Introduce anti flicker mode in LiveDisplay

Change-Id: Iba7387ff16d463d087c9a38bced90b6c1bd503b1
diff --git a/Android.bp b/Android.bp
index fb29abc..41394bf 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,5 +1,5 @@
 //
-// Copyright (C) 2018-2020 The LineageOS Project
+// Copyright (C) 2018-2021 The LineageOS Project
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -59,6 +59,7 @@
 
 lineage_sdk_LOCAL_STATIC_JAVA_LIBRARIES = [
     "vendor.lineage.livedisplay-V2.0-java",
+    "vendor.lineage.livedisplay-V2.1-java",
     "vendor.lineage.touch-V1.0-java",
     "vendor.lineage.trust-V1.0-java",
 ]
diff --git a/api/lineage_current.txt b/api/lineage_current.txt
index 4570052..60a9274 100644
--- a/api/lineage_current.txt
+++ b/api/lineage_current.txt
@@ -196,6 +196,7 @@
     method public boolean setTouchscreenGestureEnabled(lineageos.hardware.TouchscreenGesture, boolean);
     method public boolean setVibratorIntensity(int);
     field public static final int FEATURE_ADAPTIVE_BACKLIGHT = 1; // 0x1
+    field public static final int FEATURE_ANTI_FLICKER = 2097152; // 0x200000
     field public static final int FEATURE_AUTO_CONTRAST = 4096; // 0x1000
     field public static final int FEATURE_COLOR_BALANCE = 131072; // 0x20000
     field public static final int FEATURE_COLOR_ENHANCEMENT = 2; // 0x2
@@ -245,6 +246,7 @@
     method public int getMode();
     method public int getNightColorTemperature();
     method public lineageos.hardware.HSIC getPictureAdjustment();
+    method public boolean isAntiFlickerEnabled();
     method public boolean isAutoContrastEnabled();
     method public boolean isAutomaticOutdoorModeEnabled();
     method public boolean isCABCEnabled();
@@ -263,6 +265,7 @@
     field public static final int ADJUSTMENT_HUE = 0; // 0x0
     field public static final int ADJUSTMENT_INTENSITY = 2; // 0x2
     field public static final int ADJUSTMENT_SATURATION = 1; // 0x1
+    field public static final int FEATURE_ANTI_FLICKER = 19; // 0x13
     field public static final int FEATURE_AUTO_CONTRAST = 11; // 0xb
     field public static final int FEATURE_CABC = 10; // 0xa
     field public static final int FEATURE_COLOR_ADJUSTMENT = 13; // 0xd
@@ -806,6 +809,7 @@
     field public static final android.net.Uri CONTENT_URI;
     field public static final java.lang.String DIALER_OPENCNAM_ACCOUNT_SID = "dialer_opencnam_account_sid";
     field public static final java.lang.String DIALER_OPENCNAM_AUTH_TOKEN = "dialer_opencnam_auth_token";
+    field public static final java.lang.String DISPLAY_ANTI_FLICKER = "display_anti_flicker";
     field public static final java.lang.String DISPLAY_AUTO_CONTRAST = "display_auto_contrast";
     field public static final java.lang.String DISPLAY_AUTO_OUTDOOR_MODE = "display_auto_outdoor_mode";
     field public static final java.lang.String DISPLAY_CABC = "display_low_power";
diff --git a/lineage/lib/main/java/org/lineageos/platform/internal/display/DisplayHardwareController.java b/lineage/lib/main/java/org/lineageos/platform/internal/display/DisplayHardwareController.java
index 3f4bd45..c0136e0 100644
--- a/lineage/lib/main/java/org/lineageos/platform/internal/display/DisplayHardwareController.java
+++ b/lineage/lib/main/java/org/lineageos/platform/internal/display/DisplayHardwareController.java
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2016 The CyanogenMod Project
- *               2018 The LineageOS Project
+ *               2018-2021 The LineageOS Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -50,11 +50,13 @@
     private final boolean mUseCABC;
     private final boolean mUseReaderMode;
     private final boolean mUseDisplayModes;
+    private final boolean mUseAntiFlicker;
 
     // default values
     private final boolean mDefaultAutoContrast;
     private final boolean mDefaultColorEnhancement;
     private final boolean mDefaultCABC;
+    private final boolean mDefaultAntiFlicker;
 
     // color adjustment holders
     private final float[] mAdditionalAdjustment = getDefaultAdjustment();
@@ -75,6 +77,8 @@
             LineageSettings.System.getUriFor(LineageSettings.System.DISPLAY_CABC);
     private static final Uri DISPLAY_READING_MODE =
             LineageSettings.System.getUriFor(LineageSettings.System.DISPLAY_READING_MODE);
+    private static final Uri DISPLAY_ANTI_FLICKER =
+            LineageSettings.System.getUriFor(LineageSettings.System.DISPLAY_ANTI_FLICKER);
 
     public DisplayHardwareController(Context context, Handler handler) {
         super(context, handler);
@@ -104,6 +108,11 @@
         mUseReaderMode = mHardware
                 .isSupported(LineageHardwareManager.FEATURE_READING_ENHANCEMENT);
 
+        mUseAntiFlicker = mHardware
+                .isSupported(LineageHardwareManager.FEATURE_ANTI_FLICKER);
+        mDefaultAntiFlicker = mContext.getResources().getBoolean(
+                org.lineageos.platform.internal.R.bool.config_defaultAntiFlicker);
+
         if (mUseColorAdjustment) {
             mMaxColor = mHardware.getDisplayColorCalibrationMax();
             copyColors(getColorAdjustment(), mColorAdjustment);
@@ -131,6 +140,9 @@
         if (mUseReaderMode) {
             settings.add(DISPLAY_READING_MODE);
         }
+        if (mUseAntiFlicker) {
+            settings.add(DISPLAY_ANTI_FLICKER);
+        }
 
         if (settings.size() == 0) {
             return;
@@ -159,8 +171,11 @@
         if (mUseReaderMode) {
             caps.set(LiveDisplayManager.FEATURE_READING_ENHANCEMENT);
         }
+        if (mUseAntiFlicker) {
+            caps.set(LiveDisplayManager.FEATURE_ANTI_FLICKER);
+        }
         return mUseAutoContrast || mUseColorEnhancement || mUseCABC || mUseColorAdjustment ||
-            mUseDisplayModes || mUseReaderMode;
+            mUseDisplayModes || mUseReaderMode || mUseAntiFlicker;
     }
 
     @Override
@@ -178,6 +193,9 @@
             copyColors(getColorAdjustment(), mColorAdjustment);
             updateColorAdjustment();
         }
+        if (uri == null || uri.equals(DISPLAY_ANTI_FLICKER)) {
+            updateAntiFlicker();
+        }
     }
 
     private synchronized void updateHardware() {
@@ -185,6 +203,7 @@
             updateCABCMode();
             updateAutoContrast();
             updateColorEnhancement();
+            updateAntiFlicker();
         }
     }
 
@@ -214,6 +233,7 @@
         pw.println("  mUseCABC=" + mUseCABC);
         pw.println("  mUseDisplayModes=" + mUseDisplayModes);
         pw.println("  mUseReaderMode=" + mUseReaderMode);
+        pw.println("  mUseAntiFlicker=" + mUseAntiFlicker);
         pw.println();
         pw.println("  DisplayHardwareController State:");
         pw.println("    mAutoContrast=" + isAutoContrastEnabled());
@@ -277,6 +297,16 @@
     }
 
     /**
+     * Anti flicker mode
+     */
+    private void updateAntiFlicker() {
+        if (!mUseAntiFlicker) {
+            return;
+        }
+        mHardware.set(LineageHardwareManager.FEATURE_ANTI_FLICKER, isAntiFlickerEnabled());
+    }
+
+    /**
      * Smoothly animate the current display colors to the new value.
      */
     private synchronized void animateDisplayColor(float[] targetColors) {
@@ -509,4 +539,17 @@
             dst[2] = src[2];
         }
     }
+
+    boolean isAntiFlickerEnabled() {
+        return mUseAntiFlicker &&
+                getBoolean(LineageSettings.System.DISPLAY_ANTI_FLICKER, mDefaultAntiFlicker);
+    }
+
+    boolean setAntiFlickerEnabled(boolean enabled) {
+        if (!mUseAntiFlicker) {
+            return false;
+        }
+        putBoolean(LineageSettings.System.DISPLAY_ANTI_FLICKER, enabled);
+        return true;
+    }
 }
diff --git a/lineage/lib/main/java/org/lineageos/platform/internal/display/LiveDisplayService.java b/lineage/lib/main/java/org/lineageos/platform/internal/display/LiveDisplayService.java
index 5ca9485..9561f91 100644
--- a/lineage/lib/main/java/org/lineageos/platform/internal/display/LiveDisplayService.java
+++ b/lineage/lib/main/java/org/lineageos/platform/internal/display/LiveDisplayService.java
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2016 The CyanogenMod Project
- *               2019 The LineageOS Project
+ *               2019-2021 The LineageOS Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -377,6 +377,18 @@
             final TwilightState twilight = mTwilightTracker.getCurrentState();
             return twilight != null && twilight.isNight();
         }
+
+        @Override
+        public boolean isAntiFlickerEnabled() {
+            return mDHC.isAntiFlickerEnabled();
+        }
+
+        @Override
+        public boolean setAntiFlickerEnabled(boolean enabled) {
+            mContext.enforceCallingOrSelfPermission(
+                    lineageos.platform.Manifest.permission.MANAGE_LIVEDISPLAY, null);
+            return mDHC.setAntiFlickerEnabled(enabled);
+        }
     };
 
     // Listener for screen on/off events
diff --git a/lineage/res/res/values/config.xml b/lineage/res/res/values/config.xml
index 4721f71..e43f83b 100644
--- a/lineage/res/res/values/config.xml
+++ b/lineage/res/res/values/config.xml
@@ -42,6 +42,7 @@
     <bool name="config_defaultAutoOutdoorMode">true</bool>
     <bool name="config_defaultColorEnhancement">true</bool>
     <bool name="config_defaultCABC">true</bool>
+    <bool name="config_defaultAntiFlicker">false</bool>
 
     <!-- Display mode remapping table.
          If the mode names returned by the backend do not match
diff --git a/lineage/res/res/values/symbols.xml b/lineage/res/res/values/symbols.xml
index 6bae7c2..c3a7d85 100644
--- a/lineage/res/res/values/symbols.xml
+++ b/lineage/res/res/values/symbols.xml
@@ -81,6 +81,7 @@
     <java-symbol type="bool" name="config_defaultAutoOutdoorMode" />
     <java-symbol type="bool" name="config_defaultColorEnhancement" />
     <java-symbol type="bool" name="config_defaultCABC" />
+    <java-symbol type="bool" name="config_defaultAntiFlicker" />
 
     <java-symbol type="bool" name="config_filterDisplayModes" />
     <java-symbol type="array" name="config_displayModeMappings" />
diff --git a/sdk/src/java/lineageos/hardware/ILiveDisplayService.aidl b/sdk/src/java/lineageos/hardware/ILiveDisplayService.aidl
index f864ea8..11d70c8 100644
--- a/sdk/src/java/lineageos/hardware/ILiveDisplayService.aidl
+++ b/sdk/src/java/lineageos/hardware/ILiveDisplayService.aidl
@@ -1,5 +1,6 @@
 /**
  * Copyright (c) 2016, The CyanogenMod Project
+ *               2021 The LineageOS Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -53,4 +54,7 @@
     HSIC getDefaultPictureAdjustment();
     boolean setPictureAdjustment(in HSIC adj);
     boolean isNight();
+
+    boolean isAntiFlickerEnabled();
+    boolean setAntiFlickerEnabled(boolean enabled);
 }
diff --git a/sdk/src/java/lineageos/hardware/LineageHardwareManager.java b/sdk/src/java/lineageos/hardware/LineageHardwareManager.java
index c912b80..f60291b 100644
--- a/sdk/src/java/lineageos/hardware/LineageHardwareManager.java
+++ b/sdk/src/java/lineageos/hardware/LineageHardwareManager.java
@@ -39,6 +39,7 @@
 import vendor.lineage.livedisplay.V2_0.IPictureAdjustment;
 import vendor.lineage.livedisplay.V2_0.IReadingEnhancement;
 import vendor.lineage.livedisplay.V2_0.ISunlightEnhancement;
+import vendor.lineage.livedisplay.V2_1.IAntiFlicker;
 import vendor.lineage.touch.V1_0.IGloveMode;
 import vendor.lineage.touch.V1_0.IKeyDisabler;
 import vendor.lineage.touch.V1_0.IKeySwapper;
@@ -158,8 +159,15 @@
     @VisibleForTesting
     public static final int FEATURE_TOUCHSCREEN_GESTURES = 0x80000;
 
+    /**
+     * Anti flicker mode
+     */
+    @VisibleForTesting
+    public static final int FEATURE_ANTI_FLICKER = 0x200000;
+
     private static final List<Integer> BOOLEAN_FEATURES = Arrays.asList(
         FEATURE_ADAPTIVE_BACKLIGHT,
+        FEATURE_ANTI_FLICKER,
         FEATURE_AUTO_CONTRAST,
         FEATURE_COLOR_ENHANCEMENT,
         FEATURE_HIGH_TOUCH_SENSITIVITY,
@@ -272,6 +280,8 @@
             switch (feature) {
                 case FEATURE_ADAPTIVE_BACKLIGHT:
                     return IAdaptiveBacklight.getService(true);
+                case FEATURE_ANTI_FLICKER:
+                    return IAntiFlicker.getService(true);
                 case FEATURE_AUTO_CONTRAST:
                     return IAutoContrast.getService(true);
                 case FEATURE_COLOR_BALANCE:
@@ -345,6 +355,9 @@
                     case FEATURE_ADAPTIVE_BACKLIGHT:
                         IAdaptiveBacklight adaptiveBacklight = (IAdaptiveBacklight) obj;
                         return adaptiveBacklight.isEnabled();
+                    case FEATURE_ANTI_FLICKER:
+                        IAntiFlicker antiFlicker = (IAntiFlicker) obj;
+                        return antiFlicker.isEnabled();
                     case FEATURE_AUTO_CONTRAST:
                         IAutoContrast autoContrast = (IAutoContrast) obj;
                         return autoContrast.isEnabled();
@@ -400,6 +413,9 @@
                     case FEATURE_ADAPTIVE_BACKLIGHT:
                         IAdaptiveBacklight adaptiveBacklight = (IAdaptiveBacklight) obj;
                         return adaptiveBacklight.setEnabled(enable);
+                    case FEATURE_ANTI_FLICKER:
+                        IAntiFlicker antiFlicker = (IAntiFlicker) obj;
+                        return antiFlicker.setEnabled(enable);
                     case FEATURE_AUTO_CONTRAST:
                         IAutoContrast autoContrast = (IAutoContrast) obj;
                         return autoContrast.setEnabled(enable);
diff --git a/sdk/src/java/lineageos/hardware/LiveDisplayManager.java b/sdk/src/java/lineageos/hardware/LiveDisplayManager.java
index 6535f76..5646797 100644
--- a/sdk/src/java/lineageos/hardware/LiveDisplayManager.java
+++ b/sdk/src/java/lineageos/hardware/LiveDisplayManager.java
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2016 The CyanogenMod Project
- *               2018-2019 The LineageOS Project
+ *               2018-2021 The LineageOS Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -121,6 +121,11 @@
      */
     public static final int FEATURE_READING_ENHANCEMENT = 18;
 
+    /**
+     * System supports anti flicker mode
+     */
+    public static final int FEATURE_ANTI_FLICKER = 19;
+
     public static final int ADJUSTMENT_HUE = 0;
     public static final int ADJUSTMENT_SATURATION = 1;
     public static final int ADJUSTMENT_INTENSITY = 2;
@@ -129,7 +134,7 @@
     /** @hide */
     public static final int FEATURE_FIRST = FEATURE_CABC;
     /** @hide */
-    public static final int FEATURE_LAST = FEATURE_PICTURE_ADJUSTMENT;
+    public static final int FEATURE_LAST = FEATURE_ANTI_FLICKER;
 
     private static final String TAG = "LiveDisplay";
 
@@ -496,4 +501,31 @@
         }
         return false;
     }
+
+    /**
+     * Checks if the anti flicker feature is enabled
+     *
+     * @return true if enabled
+     */
+    public boolean isAntiFlickerEnabled() {
+        try {
+            return checkService() && sService.isAntiFlickerEnabled();
+        } catch (RemoteException e) {
+            return false;
+        }
+    }
+
+    /**
+     * Sets the state of anti flicker
+     *
+     * @param enabled
+     * @return true if state was changed
+     */
+    public boolean setAntiFlickerEnabled(boolean enabled) {
+        try {
+            return checkService() && sService.setAntiFlickerEnabled(enabled);
+        } catch (RemoteException e) {
+            return false;
+        }
+    }
 }
diff --git a/sdk/src/java/lineageos/providers/LineageSettings.java b/sdk/src/java/lineageos/providers/LineageSettings.java
index b6105b2..3ebd92c 100644
--- a/sdk/src/java/lineageos/providers/LineageSettings.java
+++ b/sdk/src/java/lineageos/providers/LineageSettings.java
@@ -1541,6 +1541,16 @@
                 sBooleanValidator;
 
         /**
+         * Anti flicker
+         * 0 = 0ff, 1 = on
+         */
+        public static final String DISPLAY_ANTI_FLICKER = "display_anti_flicker";
+
+        /** @hide */
+        public static final Validator DISPLAY_ANTI_FLICKER_VALIDATOR =
+                sBooleanValidator;
+
+        /**
          * Reader mode
          * 0 = 0ff, 1 = on
          */
@@ -2168,6 +2178,7 @@
                 LineageSettings.System.DISPLAY_TEMPERATURE_NIGHT,
                 LineageSettings.System.DISPLAY_TEMPERATURE_MODE,
                 LineageSettings.System.DISPLAY_AUTO_OUTDOOR_MODE,
+                LineageSettings.System.DISPLAY_ANTI_FLICKER,
                 LineageSettings.System.DISPLAY_READING_MODE,
                 LineageSettings.System.DISPLAY_CABC,
                 LineageSettings.System.DISPLAY_COLOR_ENHANCE,
@@ -2312,6 +2323,7 @@
             VALIDATORS.put(DISPLAY_TEMPERATURE_MODE, DISPLAY_TEMPERATURE_MODE_VALIDATOR);
             VALIDATORS.put(DISPLAY_AUTO_CONTRAST, DISPLAY_AUTO_CONTRAST_VALIDATOR);
             VALIDATORS.put(DISPLAY_AUTO_OUTDOOR_MODE, DISPLAY_AUTO_OUTDOOR_MODE_VALIDATOR);
+            VALIDATORS.put(DISPLAY_ANTI_FLICKER, DISPLAY_ANTI_FLICKER_VALIDATOR);
             VALIDATORS.put(DISPLAY_READING_MODE, DISPLAY_READING_MODE_VALIDATOR);
             VALIDATORS.put(DISPLAY_CABC, DISPLAY_CABC_VALIDATOR);
             VALIDATORS.put(DISPLAY_COLOR_ENHANCE, DISPLAY_COLOR_ENHANCE_VALIDATOR);
diff --git a/sdk/src/java/org/lineageos/internal/logging/LineageMetricsLogger.java b/sdk/src/java/org/lineageos/internal/logging/LineageMetricsLogger.java
index 52181af..31c75e4 100644
--- a/sdk/src/java/org/lineageos/internal/logging/LineageMetricsLogger.java
+++ b/sdk/src/java/org/lineageos/internal/logging/LineageMetricsLogger.java
@@ -73,4 +73,5 @@
     public static final int TILE_READING_MODE = BASE + 45;
     public static final int TILE_AOD = BASE + 46;
     public static final int TILE_POWERSHARE = BASE + 47;
+    public static final int TILE_ANTI_FLICKER = BASE + 48;
 }