cmsdk: Add initial DisplayMode and AutoContrast support to CMHW

Change-Id: I71f3599c64c03efc4b090ea71e583c942d0c03c2
diff --git a/cm/lib/main/java/org/cyanogenmod/platform/internal/CMHardwareService.java b/cm/lib/main/java/org/cyanogenmod/platform/internal/CMHardwareService.java
index 9b880ef..512449d 100644
--- a/cm/lib/main/java/org/cyanogenmod/platform/internal/CMHardwareService.java
+++ b/cm/lib/main/java/org/cyanogenmod/platform/internal/CMHardwareService.java
@@ -25,13 +25,16 @@
 import cyanogenmod.app.CMContextConstants;
 import cyanogenmod.hardware.ICMHardwareService;
 import cyanogenmod.hardware.CMHardwareManager;
+import cyanogenmod.hardware.DisplayMode;
 
 import java.io.File;
 
 import org.cyanogenmod.hardware.AdaptiveBacklight;
+import org.cyanogenmod.hardware.AutoContrast;
 import org.cyanogenmod.hardware.ColorEnhancement;
 import org.cyanogenmod.hardware.DisplayColorCalibration;
 import org.cyanogenmod.hardware.DisplayGammaCalibration;
+import org.cyanogenmod.hardware.DisplayModeControl;
 import org.cyanogenmod.hardware.HighTouchSensitivity;
 import org.cyanogenmod.hardware.KeyDisabler;
 import org.cyanogenmod.hardware.LongTermOrbits;
@@ -71,6 +74,11 @@
         public String getSerialNumber();
 
         public boolean requireAdaptiveBacklightForSunlightEnhancement();
+
+        public DisplayMode[] getDisplayModes();
+        public DisplayMode getCurrentDisplayMode();
+        public DisplayMode getDefaultDisplayMode();
+        public boolean setDisplayMode(DisplayMode mode);
     }
 
     private class LegacyCMHardware implements CMHardwareInterface {
@@ -102,6 +110,10 @@
                 mSupportedFeatures |= CMHardwareManager.FEATURE_VIBRATOR;
             if (TouchscreenHovering.isSupported())
                 mSupportedFeatures |= CMHardwareManager.FEATURE_TOUCH_HOVERING;
+            if (AutoContrast.isSupported())
+                mSupportedFeatures |= CMHardwareManager.FEATURE_AUTO_CONTRAST;
+            if (DisplayModeControl.isSupported())
+                mSupportedFeatures |= CMHardwareManager.FEATURE_DISPLAY_MODES;
         }
 
         public int getSupportedFeatures() {
@@ -124,6 +136,8 @@
                     return TapToWake.isEnabled();
                 case CMHardwareManager.FEATURE_TOUCH_HOVERING:
                     return TouchscreenHovering.isEnabled();
+                case CMHardwareManager.FEATURE_AUTO_CONTRAST:
+                    return AutoContrast.isEnabled();
                 default:
                     Log.e(TAG, "feature " + feature + " is not a boolean feature");
                     return false;
@@ -146,6 +160,8 @@
                     return TapToWake.setEnabled(enable);
                 case CMHardwareManager.FEATURE_TOUCH_HOVERING:
                     return TouchscreenHovering.setEnabled(enable);
+                case CMHardwareManager.FEATURE_AUTO_CONTRAST:
+                    return AutoContrast.setEnabled(enable);
                 default:
                     Log.e(TAG, "feature " + feature + " is not a boolean feature");
                     return false;
@@ -261,6 +277,22 @@
         public boolean requireAdaptiveBacklightForSunlightEnhancement() {
             return SunlightEnhancement.isAdaptiveBacklightRequired();
         }
+
+        public DisplayMode[] getDisplayModes() {
+            return DisplayModeControl.getAvailableModes();
+        }
+
+        public DisplayMode getCurrentDisplayMode() {
+            return DisplayModeControl.getCurrentMode();
+        }
+
+        public DisplayMode getDefaultDisplayMode() {
+            return DisplayModeControl.getDefaultMode();
+        }
+
+        public boolean setDisplayMode(DisplayMode mode) {
+            return DisplayModeControl.setMode(mode, true);
+        }
     }
 
     private CMHardwareInterface getImpl(Context context) {
@@ -448,5 +480,49 @@
             }
             return mCmHwImpl.requireAdaptiveBacklightForSunlightEnhancement();
         }
+
+        @Override
+        public DisplayMode[] getDisplayModes() {
+            mContext.enforceCallingOrSelfPermission(
+                    cyanogenmod.platform.Manifest.permission.HARDWARE_ABSTRACTION_ACCESS, null);
+            if (!isSupported(CMHardwareManager.FEATURE_DISPLAY_MODES)) {
+                Log.e(TAG, "Display modes are not supported");
+                return null;
+            }
+            return mCmHwImpl.getDisplayModes();
+        }
+
+        @Override
+        public DisplayMode getCurrentDisplayMode() {
+            mContext.enforceCallingOrSelfPermission(
+                    cyanogenmod.platform.Manifest.permission.HARDWARE_ABSTRACTION_ACCESS, null);
+            if (!isSupported(CMHardwareManager.FEATURE_DISPLAY_MODES)) {
+                Log.e(TAG, "Display modes are not supported");
+                return null;
+            }
+            return mCmHwImpl.getCurrentDisplayMode();
+        }
+
+        @Override
+        public DisplayMode getDefaultDisplayMode() {
+            mContext.enforceCallingOrSelfPermission(
+                    cyanogenmod.platform.Manifest.permission.HARDWARE_ABSTRACTION_ACCESS, null);
+            if (!isSupported(CMHardwareManager.FEATURE_DISPLAY_MODES)) {
+                Log.e(TAG, "Display modes are not supported");
+                return null;
+            }
+            return mCmHwImpl.getDefaultDisplayMode();
+        }
+
+        @Override
+        public boolean setDisplayMode(DisplayMode mode) {
+            mContext.enforceCallingOrSelfPermission(
+                    cyanogenmod.platform.Manifest.permission.HARDWARE_ABSTRACTION_ACCESS, null);
+            if (!isSupported(CMHardwareManager.FEATURE_DISPLAY_MODES)) {
+                Log.e(TAG, "Display modes are not supported");
+                return false;
+            }
+            return mCmHwImpl.setDisplayMode(mode);
+        }
     };
 }
diff --git a/src/java/cyanogenmod/hardware/CMHardwareManager.java b/src/java/cyanogenmod/hardware/CMHardwareManager.java
index 62e5c66..7c95767 100644
--- a/src/java/cyanogenmod/hardware/CMHardwareManager.java
+++ b/src/java/cyanogenmod/hardware/CMHardwareManager.java
@@ -100,6 +100,16 @@
      */
     public static final int FEATURE_TOUCH_HOVERING = 0x800;
 
+    /**
+     * Auto contrast
+     */
+    public static final int FEATURE_AUTO_CONTRAST = 0x1000;
+
+    /**
+     * Display modes
+     */
+    public static final int FEATURE_DISPLAY_MODES = 0x2000;
+
     private static final List<Integer> BOOLEAN_FEATURES = Arrays.asList(
         FEATURE_ADAPTIVE_BACKLIGHT,
         FEATURE_COLOR_ENHANCEMENT,
@@ -108,6 +118,7 @@
         FEATURE_SUNLIGHT_ENHANCEMENT,
         FEATURE_TAP_TO_WAKE,
         FEATURE_TOUCH_HOVERING,
+        FEATURE_AUTO_CONTRAST
     );
 
     private static CMHardwareManager sCMHardwareManagerInstance;
@@ -417,6 +428,7 @@
     /**
      * @return the number of RGB controls the device supports
      */
+    @Deprecated
     public int getNumGammaControls() {
         try {
             return getService().getNumGammaControls();
@@ -430,6 +442,7 @@
      *
      * @return the current RGB gamma calibration for the given control
      */
+    @Deprecated
     public int[] getDisplayGammaCalibration(int idx) {
         int[] arr = getDisplayGammaCalibrationArray(idx);
         if (arr == null || arr.length < 3) {
@@ -441,6 +454,7 @@
     /**
      * @return the minimum value for all colors
      */
+    @Deprecated
     public int getDisplayGammaCalibrationMin() {
         return getArrayValue(getDisplayGammaCalibrationArray(0), GAMMA_CALIBRATION_MIN_INDEX, 0);
     }
@@ -448,6 +462,7 @@
     /**
      * @return the maximum value for all colors
      */
+    @Deprecated
     public int getDisplayGammaCalibrationMax() {
         return getArrayValue(getDisplayGammaCalibrationArray(0), GAMMA_CALIBRATION_MAX_INDEX, 0);
     }
@@ -462,6 +477,7 @@
      *
      * @return true on success, false otherwise.
      */
+    @Deprecated
     public boolean setDisplayGammaCalibration(int idx, int[] rgb) {
         try {
             return getService().setDisplayGammaCalibration(idx, rgb);
@@ -525,4 +541,48 @@
         }
         return false;
     }
+
+    /**
+     * @return a list of available display modes on the devices
+     */
+    public DisplayMode[] getDisplayModes() {
+        try {
+            return getService().getDisplayModes();
+        } catch (RemoteException e) {
+        }
+        return null;
+    }
+
+    /**
+     * @return the currently active display mode
+     */
+    public DisplayMode getCurrentDisplayMode() {
+        try {
+            return getService().getCurrentDisplayMode();
+        } catch (RemoteException e) {
+        }
+        return null;
+    }
+
+    /**
+     * @return the default display mode to be set on boot
+     */
+    public DisplayMode getDefaultDisplayMode() {
+        try {
+            return getService().getDefaultDisplayMode();
+        } catch (RemoteException e) {
+        }
+        return null;
+    }
+
+    /**
+     * @return true if setting the mode was successful
+     */
+    public boolean setDisplayMode(DisplayMode mode) {
+        try {
+            return getService().setDisplayMode(mode);
+        } catch (RemoteException e) {
+        }
+        return false;
+    }
 }
diff --git a/src/java/cyanogenmod/hardware/DisplayMode.aidl b/src/java/cyanogenmod/hardware/DisplayMode.aidl
new file mode 100644
index 0000000..a4f9163
--- /dev/null
+++ b/src/java/cyanogenmod/hardware/DisplayMode.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2015 The CyanogenMod Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package cyanogenmod.hardware;
+
+parcelable DisplayMode;
diff --git a/src/java/cyanogenmod/hardware/DisplayMode.java b/src/java/cyanogenmod/hardware/DisplayMode.java
new file mode 100644
index 0000000..1384595
--- /dev/null
+++ b/src/java/cyanogenmod/hardware/DisplayMode.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2015 The CyanogenMod Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package cyanogenmod.hardware;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/* 
+ * Display Modes API
+ *
+ * A device may implement a list of preset display modes for different
+ * viewing intents, such as movies, photos, or extra vibrance. These
+ * modes may have multiple components such as gamma correction, white
+ * point adjustment, etc, but are activated by a single control point.
+ *
+ * This API provides support for enumerating and selecting the
+ * modes supported by the hardware.
+ *
+ * A DisplayMode is referenced by it's identifier and carries an
+ * associated name (up to the user to translate this value).
+ */
+public class DisplayMode implements Parcelable {
+    public final int id;
+    public final String name;
+       
+    public DisplayMode(int id, String name) {
+        this.id = id;
+        this.name = name;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }   
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(id);
+        out.writeString(name);
+    }
+    
+    /** @hide */
+    public static final Parcelable.Creator<DisplayMode> CREATOR = new Parcelable.Creator<DisplayMode>() {
+        public DisplayMode createFromParcel(Parcel in) {
+            return new DisplayMode(in.readInt(), in.readString());
+        }
+
+        @Override
+        public DisplayMode[] newArray(int size) {
+            return new DisplayMode[size];
+        }
+    };
+
+}
diff --git a/src/java/cyanogenmod/hardware/ICMHardwareService.aidl b/src/java/cyanogenmod/hardware/ICMHardwareService.aidl
index ef85d94..87d6de8 100644
--- a/src/java/cyanogenmod/hardware/ICMHardwareService.aidl
+++ b/src/java/cyanogenmod/hardware/ICMHardwareService.aidl
@@ -16,6 +16,8 @@
 
 package cyanogenmod.hardware;
 
+import cyanogenmod.hardware.DisplayMode;
+
 /** @hide */
 interface ICMHardwareService {
 
@@ -40,4 +42,9 @@
     String getSerialNumber();
 
     boolean requireAdaptiveBacklightForSunlightEnhancement();
+
+    DisplayMode[] getDisplayModes();
+    DisplayMode getCurrentDisplayMode();
+    DisplayMode getDefaultDisplayMode();
+    boolean setDisplayMode(in DisplayMode mode);
 }