summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Kondik <steve@cyngn.com>2016-07-18 02:36:42 -0700
committerSteve Kondik <steve@cyngn.com>2016-07-20 10:07:31 -0700
commit86cae92291f728d0eca637573ecbe6e0a53ccf1a (patch)
tree577cc188e1b9fc69b006135fbb480b1848a29e1d
parent25d708141814289067587e504a0bb33a76c28a78 (diff)
downloadvendor_cmsdk-86cae92291f728d0eca637573ecbe6e0a53ccf1a.zip
vendor_cmsdk-86cae92291f728d0eca637573ecbe6e0a53ccf1a.tar.gz
vendor_cmsdk-86cae92291f728d0eca637573ecbe6e0a53ccf1a.tar.bz2
livedisplay: Add support for direct color balance control
* We currently use the DisplayColorCalibration API for setting display temperature which makes a lot of guesses about what temperature the display really is. Some devices will support the new ColorBalance API (via QDCM or other mechanism), which offers a calibrated alternative. Add support for this, which will supercede DCC if available. * Additionally, define the available color temperature range as a set of overlayable values so this can be specified per-device. This range will be mapped to balance values using the power curve calculations in the new MathUtils class. Change-Id: I99608c09807b747d962680293c7b0cee8d669003
-rw-r--r--api/cm_current.txt13
-rw-r--r--cm/lib/main/java/org/cyanogenmod/platform/internal/CMHardwareService.java64
-rw-r--r--cm/lib/main/java/org/cyanogenmod/platform/internal/display/ColorTemperatureController.java115
-rw-r--r--cm/lib/main/java/org/cyanogenmod/platform/internal/display/LiveDisplayService.java5
-rw-r--r--cm/res/res/values/config.xml8
-rw-r--r--cm/res/res/values/symbols.xml3
-rw-r--r--sdk/src/java/cyanogenmod/hardware/CMHardwareManager.java39
-rw-r--r--sdk/src/java/cyanogenmod/hardware/ICMHardwareService.aidl5
-rw-r--r--sdk/src/java/cyanogenmod/hardware/LiveDisplayConfig.java44
-rw-r--r--sdk/src/java/cyanogenmod/hardware/LiveDisplayManager.java9
-rw-r--r--sdk/src/java/cyanogenmod/providers/CMSettings.java4
-rw-r--r--sdk/src/java/org/cyanogenmod/internal/util/MathUtils.java67
-rw-r--r--system-api/cm_system-current.txt13
13 files changed, 373 insertions, 16 deletions
diff --git a/api/cm_current.txt b/api/cm_current.txt
index 87ba2c5..73de8ed 100644
--- a/api/cm_current.txt
+++ b/api/cm_current.txt
@@ -244,7 +244,7 @@ package cyanogenmod.app {
field public static final int ZEN_MODE_OFF = 0; // 0x0
}
- public final class Profile implements android.os.Parcelable {
+ public final class Profile implements java.lang.Comparable android.os.Parcelable {
ctor public Profile(java.lang.String);
method public void addSecondaryUuid(java.util.UUID);
method public int compareTo(java.lang.Object);
@@ -451,6 +451,8 @@ package cyanogenmod.hardware {
public final class CMHardwareManager {
method public boolean deletePersistentObject(java.lang.String);
method public boolean get(int);
+ method public int getColorBalance();
+ method public android.util.Range<java.lang.Integer> getColorBalanceRange();
method public cyanogenmod.hardware.DisplayMode getCurrentDisplayMode();
method public cyanogenmod.hardware.DisplayMode getDefaultDisplayMode();
method public int[] getDisplayColorCalibration();
@@ -483,6 +485,7 @@ package cyanogenmod.hardware {
method public boolean registerThermalListener(cyanogenmod.hardware.ThermalListenerCallback);
method public boolean requireAdaptiveBacklightForSunlightEnhancement();
method public boolean set(int, boolean);
+ method public boolean setColorBalance(int);
method public boolean setDisplayColorCalibration(int[]);
method public deprecated boolean setDisplayGammaCalibration(int, int[]);
method public boolean setDisplayMode(cyanogenmod.hardware.DisplayMode, boolean);
@@ -493,6 +496,7 @@ package cyanogenmod.hardware {
method public boolean writePersistentString(java.lang.String, java.lang.String);
field public static final int FEATURE_ADAPTIVE_BACKLIGHT = 1; // 0x1
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
field public static final int FEATURE_DISPLAY_COLOR_CALIBRATION = 4; // 0x4
field public static final int FEATURE_DISPLAY_GAMMA_CALIBRATION = 8; // 0x8
@@ -530,8 +534,10 @@ package cyanogenmod.hardware {
}
public class LiveDisplayConfig implements android.os.Parcelable {
- ctor public LiveDisplayConfig(java.util.BitSet, int, int, int, boolean, boolean, boolean, boolean);
+ ctor public LiveDisplayConfig(java.util.BitSet, int, int, int, boolean, boolean, boolean, boolean, android.util.Range<java.lang.Integer>, android.util.Range<java.lang.Integer>);
method public int describeContents();
+ method public android.util.Range<java.lang.Integer> getColorBalanceRange();
+ method public android.util.Range<java.lang.Integer> getColorTemperatureRange();
method public boolean getDefaultAutoContrast();
method public boolean getDefaultAutoOutdoorMode();
method public boolean getDefaultCABC();
@@ -567,6 +573,7 @@ package cyanogenmod.hardware {
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
+ field public static final int FEATURE_COLOR_BALANCE = 16; // 0x10
field public static final int FEATURE_COLOR_ENHANCEMENT = 12; // 0xc
field public static final int FEATURE_DISPLAY_MODES = 15; // 0xf
field public static final int FEATURE_MANAGED_OUTDOOR_MODE = 14; // 0xe
@@ -948,6 +955,7 @@ package cyanogenmod.providers {
field public static final java.lang.String KEY_MENU_ACTION = "key_menu_action";
field public static final java.lang.String KEY_MENU_LONG_PRESS_ACTION = "key_menu_long_press_action";
field public static final java.lang.String LOCKSCREEN_PIN_SCRAMBLE_LAYOUT = "lockscreen_scramble_pin_layout";
+ field public static final java.lang.String LOCKSCREEN_ROTATION = "lockscreen_rotation";
field public static final java.lang.String MENU_WAKE_SCREEN = "menu_wake_screen";
field public static final java.lang.String NAVBAR_LEFT_IN_LANDSCAPE = "navigation_bar_left";
field public static final java.lang.String NAVIGATION_BAR_MENU_ARROW_KEYS = "navigation_bar_menu_arrow_keys";
@@ -972,7 +980,6 @@ package cyanogenmod.providers {
field public static final java.lang.String QS_SHOW_BRIGHTNESS_SLIDER = "qs_show_brightness_slider";
field public static final java.lang.String RECENTS_SHOW_SEARCH_BAR = "recents_show_search_bar";
field public static final java.lang.String REVERSE_LOOKUP_PROVIDER = "reverse_lookup_provider";
- field public static final java.lang.String LOCKSCREEN_ROTATION = "lockscreen_rotation";
field public static final java.lang.String SHOW_ALARM_ICON = "show_alarm_icon";
field public static final java.lang.String STATUS_BAR_AM_PM = "status_bar_am_pm";
field public static final java.lang.String STATUS_BAR_BATTERY_STYLE = "status_bar_battery_style";
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 7e79de4..6052383 100644
--- a/cm/lib/main/java/org/cyanogenmod/platform/internal/CMHardwareService.java
+++ b/cm/lib/main/java/org/cyanogenmod/platform/internal/CMHardwareService.java
@@ -36,6 +36,7 @@ import java.util.Arrays;
import org.cyanogenmod.hardware.AdaptiveBacklight;
import org.cyanogenmod.hardware.AutoContrast;
+import org.cyanogenmod.hardware.ColorBalance;
import org.cyanogenmod.hardware.ColorEnhancement;
import org.cyanogenmod.hardware.DisplayColorCalibration;
import org.cyanogenmod.hardware.DisplayGammaCalibration;
@@ -96,6 +97,11 @@ public class CMHardwareService extends CMSystemService implements ThermalUpdateC
public boolean writePersistentBytes(String key, byte[] value);
public byte[] readPersistentBytes(String key);
+
+ public int getColorBalanceMin();
+ public int getColorBalanceMax();
+ public int getColorBalance();
+ public boolean setColorBalance(int value);
}
private class LegacyCMHardware implements CMHardwareInterface {
@@ -137,6 +143,8 @@ public class CMHardwareService extends CMSystemService implements ThermalUpdateC
mSupportedFeatures |= CMHardwareManager.FEATURE_THERMAL_MONITOR;
if (UniqueDeviceId.isSupported())
mSupportedFeatures |= CMHardwareManager.FEATURE_UNIQUE_DEVICE_ID;
+ if (ColorBalance.isSupported())
+ mSupportedFeatures |= CMHardwareManager.FEATURE_COLOR_BALANCE;
}
public int getSupportedFeatures() {
@@ -334,6 +342,22 @@ public class CMHardwareService extends CMSystemService implements ThermalUpdateC
public byte[] readPersistentBytes(String key) {
return PersistentStorage.get(key);
}
+
+ public int getColorBalanceMin() {
+ return ColorBalance.getMinValue();
+ }
+
+ public int getColorBalanceMax() {
+ return ColorBalance.getMaxValue();
+ }
+
+ public int getColorBalance() {
+ return ColorBalance.getValue();
+ }
+
+ public boolean setColorBalance(int value) {
+ return ColorBalance.setValue(value);
+ }
}
private CMHardwareInterface getImpl(Context context) {
@@ -687,5 +711,45 @@ public class CMHardwareService extends CMSystemService implements ThermalUpdateC
}
return false;
}
+
+ @Override
+ public int getColorBalanceMin() {
+ mContext.enforceCallingOrSelfPermission(
+ cyanogenmod.platform.Manifest.permission.HARDWARE_ABSTRACTION_ACCESS, null);
+ if (isSupported(CMHardwareManager.FEATURE_COLOR_BALANCE)) {
+ return mCmHwImpl.getColorBalanceMin();
+ }
+ return 0;
+ }
+
+ @Override
+ public int getColorBalanceMax() {
+ mContext.enforceCallingOrSelfPermission(
+ cyanogenmod.platform.Manifest.permission.HARDWARE_ABSTRACTION_ACCESS, null);
+ if (isSupported(CMHardwareManager.FEATURE_COLOR_BALANCE)) {
+ return mCmHwImpl.getColorBalanceMax();
+ }
+ return 0;
+ }
+
+ @Override
+ public int getColorBalance() {
+ mContext.enforceCallingOrSelfPermission(
+ cyanogenmod.platform.Manifest.permission.HARDWARE_ABSTRACTION_ACCESS, null);
+ if (isSupported(CMHardwareManager.FEATURE_COLOR_BALANCE)) {
+ return mCmHwImpl.getColorBalance();
+ }
+ return 0;
+ }
+
+ @Override
+ public boolean setColorBalance(int value) {
+ mContext.enforceCallingOrSelfPermission(
+ cyanogenmod.platform.Manifest.permission.HARDWARE_ABSTRACTION_ACCESS, null);
+ if (isSupported(CMHardwareManager.FEATURE_COLOR_BALANCE)) {
+ return mCmHwImpl.setColorBalance(value);
+ }
+ return false;
+ }
};
}
diff --git a/cm/lib/main/java/org/cyanogenmod/platform/internal/display/ColorTemperatureController.java b/cm/lib/main/java/org/cyanogenmod/platform/internal/display/ColorTemperatureController.java
index 3184d71..a72c3a2 100644
--- a/cm/lib/main/java/org/cyanogenmod/platform/internal/display/ColorTemperatureController.java
+++ b/cm/lib/main/java/org/cyanogenmod/platform/internal/display/ColorTemperatureController.java
@@ -20,18 +20,24 @@ import static cyanogenmod.hardware.LiveDisplayManager.MODE_DAY;
import static cyanogenmod.hardware.LiveDisplayManager.MODE_NIGHT;
import static cyanogenmod.hardware.LiveDisplayManager.MODE_OFF;
+import android.animation.ValueAnimator;
+import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.content.Context;
import android.net.Uri;
import android.os.Handler;
import android.text.format.DateUtils;
import android.util.MathUtils;
+import android.util.Range;
import android.util.Slog;
+import android.view.animation.LinearInterpolator;
import com.android.server.twilight.TwilightState;
import java.io.PrintWriter;
import java.util.BitSet;
+import cyanogenmod.hardware.CMHardwareManager;
+import cyanogenmod.hardware.LiveDisplayManager;
import cyanogenmod.providers.CMSettings;
import cyanogenmod.util.ColorUtils;
@@ -40,6 +46,10 @@ public class ColorTemperatureController extends LiveDisplayFeature {
private final DisplayHardwareController mDisplayHardware;
private final boolean mUseTemperatureAdjustment;
+ private final boolean mUseColorBalance;
+ private final Range<Integer> mColorBalanceRange;
+ private final Range<Integer> mColorTemperatureRange;
+ private final double[] mColorBalanceCurve;
private final int mDefaultDayTemperature;
private final int mDefaultNightTemperature;
@@ -48,6 +58,10 @@ public class ColorTemperatureController extends LiveDisplayFeature {
private int mDayTemperature;
private int mNightTemperature;
+ private ValueAnimator mAnimator;
+
+ private final CMHardwareManager mHardware;
+
private static final long TWILIGHT_ADJUSTMENT_TIME = DateUtils.HOUR_IN_MILLIS * 1;
private static final Uri DISPLAY_TEMPERATURE_DAY =
@@ -59,12 +73,30 @@ public class ColorTemperatureController extends LiveDisplayFeature {
Handler handler, DisplayHardwareController displayHardware) {
super(context, handler);
mDisplayHardware = displayHardware;
- mUseTemperatureAdjustment = mDisplayHardware.hasColorAdjustment();
+ mHardware = CMHardwareManager.getInstance(mContext);
+
+ mUseColorBalance = mHardware
+ .isSupported(CMHardwareManager.FEATURE_COLOR_BALANCE);
+ mColorBalanceRange = mHardware.getColorBalanceRange();
+
+ mUseTemperatureAdjustment = mUseColorBalance ||
+ mDisplayHardware.hasColorAdjustment();
mDefaultDayTemperature = mContext.getResources().getInteger(
org.cyanogenmod.platform.internal.R.integer.config_dayColorTemperature);
mDefaultNightTemperature = mContext.getResources().getInteger(
org.cyanogenmod.platform.internal.R.integer.config_nightColorTemperature);
+
+ mColorTemperatureRange = Range.create(
+ mContext.getResources().getInteger(
+ org.cyanogenmod.platform.internal.R.integer.config_minColorTemperature),
+ mContext.getResources().getInteger(
+ org.cyanogenmod.platform.internal.R.integer.config_maxColorTemperature));
+
+ mColorBalanceCurve = org.cyanogenmod.internal.util.MathUtils.powerCurve(
+ mColorTemperatureRange.getLower(),
+ mDefaultDayTemperature,
+ mColorTemperatureRange.getUpper());
}
@Override
@@ -85,6 +117,9 @@ public class ColorTemperatureController extends LiveDisplayFeature {
caps.set(MODE_AUTO);
caps.set(MODE_DAY);
caps.set(MODE_NIGHT);
+ if (mUseColorBalance) {
+ caps.set(LiveDisplayManager.FEATURE_COLOR_BALANCE);
+ }
}
return mUseTemperatureAdjustment;
}
@@ -96,7 +131,11 @@ public class ColorTemperatureController extends LiveDisplayFeature {
@Override
protected void onScreenStateChanged() {
- updateColorTemperature();
+ if (mAnimator != null && mAnimator.isRunning() && !isScreenOn()) {
+ mAnimator.cancel();
+ } else {
+ updateColorTemperature();
+ }
}
@Override
@@ -168,17 +207,79 @@ public class ColorTemperatureController extends LiveDisplayFeature {
}
}
+ /**
+ * Smoothly animate the current display color balance
+ */
+ private synchronized void animateColorBalance(int balance) {
+
+ // always start with the current values in the hardware
+ int current = mHardware.getColorBalance();
+
+ if (current == balance) {
+ return;
+ }
+
+ long duration = (long)(5 * Math.abs(current - balance));
+
+
+ if (DEBUG) {
+ Slog.d(TAG, "animateDisplayColor current=" + current +
+ " target=" + balance + " duration=" + duration);
+ }
+
+ if (mAnimator != null) {
+ mAnimator.cancel();
+ mAnimator.removeAllUpdateListeners();
+ }
+
+ mAnimator = ValueAnimator.ofInt(current, balance);
+ mAnimator.setDuration(duration);
+ mAnimator.setInterpolator(new LinearInterpolator());
+ mAnimator.addUpdateListener(new AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(final ValueAnimator animation) {
+ synchronized (ColorTemperatureController.this) {
+ if (isScreenOn()) {
+ int value = (int) animation.getAnimatedValue();
+ mHardware.setColorBalance(value);
+ }
+ }
+ }
+ });
+ mAnimator.start();
+ }
+
+ /*
+ * Map the color temperature to a color balance value using a power curve. This assumes the
+ * correct configuration at the device level!
+ */
+ private int mapColorTemperatureToBalance(int temperature) {
+ double z = org.cyanogenmod.internal.util.MathUtils.powerCurveToLinear(mColorBalanceCurve, temperature);
+ return Math.round(MathUtils.lerp((float)mColorBalanceRange.getLower(),
+ (float)mColorBalanceRange.getUpper(), (float)z));
+ }
private synchronized void setDisplayTemperature(int temperature) {
+ if (!mColorTemperatureRange.contains(temperature)) {
+ Slog.e(TAG, "Color temperature out of range: " + temperature);
+ return;
+ }
+
mColorTemperature = temperature;
+ if (mUseColorBalance) {
+ int balance = mapColorTemperatureToBalance(temperature);
+ Slog.d(TAG, "Set color balance = " + balance + " (temperature=" + temperature + ")");
+ animateColorBalance(balance);
+ return;
+ }
+
final float[] rgb = ColorUtils.temperatureToRGB(temperature);
if (mDisplayHardware.setAdditionalAdjustment(rgb)) {
if (DEBUG) {
Slog.d(TAG, "Adjust display temperature to " + temperature + "K");
}
}
-
}
/**
@@ -257,4 +358,12 @@ public class ColorTemperatureController extends LiveDisplayFeature {
void setNightColorTemperature(int temperature) {
putInt(CMSettings.System.DISPLAY_TEMPERATURE_NIGHT, temperature);
}
+
+ Range<Integer> getColorTemperatureRange() {
+ return mColorTemperatureRange;
+ }
+
+ Range<Integer> getColorBalanceRange() {
+ return mColorBalanceRange;
+ }
}
diff --git a/cm/lib/main/java/org/cyanogenmod/platform/internal/display/LiveDisplayService.java b/cm/lib/main/java/org/cyanogenmod/platform/internal/display/LiveDisplayService.java
index db2b1a6..129983b 100644
--- a/cm/lib/main/java/org/cyanogenmod/platform/internal/display/LiveDisplayService.java
+++ b/cm/lib/main/java/org/cyanogenmod/platform/internal/display/LiveDisplayService.java
@@ -40,13 +40,11 @@ import android.os.IBinder;
import android.os.PowerManagerInternal;
import android.os.Process;
import android.os.UserHandle;
-import android.util.Log;
import android.view.Display;
import com.android.internal.util.ArrayUtils;
import com.android.server.LocalServices;
import com.android.server.ServiceThread;
-import com.android.server.SystemService;
import com.android.server.pm.UserContentObserver;
import com.android.server.twilight.TwilightListener;
import com.android.server.twilight.TwilightManager;
@@ -188,7 +186,8 @@ public class LiveDisplayService extends CMSystemService {
mConfig = new LiveDisplayConfig(capabilities, defaultMode,
mCTC.getDefaultDayTemperature(), mCTC.getDefaultNightTemperature(),
mOMC.getDefaultAutoOutdoorMode(), mDHC.getDefaultAutoContrast(),
- mDHC.getDefaultCABC(), mDHC.getDefaultColorEnhancement());
+ mDHC.getDefaultCABC(), mDHC.getDefaultColorEnhancement(),
+ mCTC.getColorTemperatureRange(), mCTC.getColorBalanceRange());
// listeners
mDisplayManager = (DisplayManager) getContext().getSystemService(
diff --git a/cm/res/res/values/config.xml b/cm/res/res/values/config.xml
index f08a75f..9592bf1 100644
--- a/cm/res/res/values/config.xml
+++ b/cm/res/res/values/config.xml
@@ -57,6 +57,14 @@
<integer name="config_outdoorAmbientLux">9000</integer>
<integer name="config_defaultLiveDisplayMode">0</integer>
+ <!-- These values should map to the true min and max
+ that the backend is capable of adjusting to. This
+ is more important when using the ColorBalance mode,
+ as the discrete adjustment is interpolated between
+ this range (with config_dayColorTemperature at zero) -->
+ <integer name="config_minColorTemperature">1000</integer>
+ <integer name="config_maxColorTemperature">10000</integer>
+
<bool name="config_defaultAutoContrast">false</bool>
<bool name="config_defaultAutoOutdoorMode">true</bool>
<bool name="config_defaultColorEnhancement">true</bool>
diff --git a/cm/res/res/values/symbols.xml b/cm/res/res/values/symbols.xml
index 0e7143c..e79570b 100644
--- a/cm/res/res/values/symbols.xml
+++ b/cm/res/res/values/symbols.xml
@@ -73,6 +73,9 @@
<java-symbol type="integer" name="config_nightColorTemperature" />
<java-symbol type="integer" name="config_outdoorAmbientLux" />
<java-symbol type="integer" name="config_defaultLiveDisplayMode" />
+ <java-symbol type="integer" name="config_minColorTemperature" />
+ <java-symbol type="integer" name="config_maxColorTemperature" />
+
<java-symbol type="bool" name="config_defaultAutoContrast" />
<java-symbol type="bool" name="config_defaultAutoOutdoorMode" />
<java-symbol type="bool" name="config_defaultColorEnhancement" />
diff --git a/sdk/src/java/cyanogenmod/hardware/CMHardwareManager.java b/sdk/src/java/cyanogenmod/hardware/CMHardwareManager.java
index 7765b94..d31ce9b 100644
--- a/sdk/src/java/cyanogenmod/hardware/CMHardwareManager.java
+++ b/sdk/src/java/cyanogenmod/hardware/CMHardwareManager.java
@@ -20,6 +20,7 @@ import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;
+import android.util.Range;
import cyanogenmod.app.CMContextConstants;
@@ -129,6 +130,11 @@ public final class CMHardwareManager {
*/
public static final int FEATURE_UNIQUE_DEVICE_ID = 0x10000;
+ /**
+ * Color balance
+ */
+ public static final int FEATURE_COLOR_BALANCE = 0x20000;
+
private static final List<Integer> BOOLEAN_FEATURES = Arrays.asList(
FEATURE_ADAPTIVE_BACKLIGHT,
FEATURE_COLOR_ENHANCEMENT,
@@ -803,6 +809,39 @@ public final class CMHardwareManager {
return false;
}
+ public Range<Integer> getColorBalanceRange() {
+ int min = 0;
+ int max = 0;
+ try {
+ if (checkService()) {
+ min = sService.getColorBalanceMin();
+ max = sService.getColorBalanceMax();
+ }
+ } catch (RemoteException e) {
+ }
+ return new Range<Integer>(min, max);
+ }
+
+ public int getColorBalance() {
+ try {
+ if (checkService()) {
+ return sService.getColorBalance();
+ }
+ } catch (RemoteException e) {
+ }
+ return 0;
+ }
+
+ public boolean setColorBalance(int value) {
+ try {
+ if (checkService()) {
+ return sService.setColorBalance(value);
+ }
+ } catch (RemoteException e) {
+ }
+ return false;
+ }
+
/**
* @return true if service is valid
*/
diff --git a/sdk/src/java/cyanogenmod/hardware/ICMHardwareService.aidl b/sdk/src/java/cyanogenmod/hardware/ICMHardwareService.aidl
index a1ae65b..6fbaf66 100644
--- a/sdk/src/java/cyanogenmod/hardware/ICMHardwareService.aidl
+++ b/sdk/src/java/cyanogenmod/hardware/ICMHardwareService.aidl
@@ -58,4 +58,9 @@ interface ICMHardwareService {
boolean isSunlightEnhancementSelfManaged();
String getUniqueDeviceId();
+
+ int getColorBalanceMin();
+ int getColorBalanceMax();
+ int getColorBalance();
+ boolean setColorBalance(int value);
}
diff --git a/sdk/src/java/cyanogenmod/hardware/LiveDisplayConfig.java b/sdk/src/java/cyanogenmod/hardware/LiveDisplayConfig.java
index 81945f7..81cdca3 100644
--- a/sdk/src/java/cyanogenmod/hardware/LiveDisplayConfig.java
+++ b/sdk/src/java/cyanogenmod/hardware/LiveDisplayConfig.java
@@ -23,6 +23,7 @@ import static cyanogenmod.hardware.LiveDisplayManager.MODE_OFF;
import android.os.Parcel;
import android.os.Parcelable;
+import android.util.Range;
import java.util.BitSet;
@@ -50,10 +51,15 @@ public class LiveDisplayConfig implements Parcelable {
private final boolean mDefaultCABC;
private final boolean mDefaultColorEnhancement;
+ private final Range<Integer> mColorTemperatureRange;
+ private final Range<Integer> mColorBalanceRange;
+
public LiveDisplayConfig(BitSet capabilities, int defaultMode,
int defaultDayTemperature, int defaultNightTemperature,
boolean defaultAutoOutdoorMode, boolean defaultAutoContrast,
- boolean defaultCABC, boolean defaultColorEnhancement) {
+ boolean defaultCABC, boolean defaultColorEnhancement,
+ Range<Integer> colorTemperatureRange,
+ Range<Integer> colorBalanceRange) {
super();
mCapabilities = (BitSet) capabilities.clone();
mAllModes.set(MODE_FIRST, MODE_LAST);
@@ -64,6 +70,8 @@ public class LiveDisplayConfig implements Parcelable {
mDefaultAutoOutdoorMode = defaultAutoOutdoorMode;
mDefaultCABC = defaultCABC;
mDefaultColorEnhancement = defaultColorEnhancement;
+ mColorTemperatureRange = colorTemperatureRange;
+ mColorBalanceRange = colorBalanceRange;
}
private LiveDisplayConfig(Parcel parcel) {
@@ -80,6 +88,10 @@ public class LiveDisplayConfig implements Parcelable {
boolean defaultAutoOutdoorMode = false;
boolean defaultCABC = false;
boolean defaultColorEnhancement = false;
+ int minColorTemperature = 0;
+ int maxColorTemperature = 0;
+ int minColorBalance = 0;
+ int maxColorBalance = 0;
if (parcelableVersion >= Build.CM_VERSION_CODES.FIG) {
capabilities = parcel.readLong();
@@ -90,6 +102,10 @@ public class LiveDisplayConfig implements Parcelable {
defaultAutoOutdoorMode = parcel.readInt() == 1;
defaultCABC = parcel.readInt() == 1;
defaultColorEnhancement = parcel.readInt() == 1;
+ minColorTemperature = parcel.readInt();
+ maxColorTemperature = parcel.readInt();
+ minColorBalance = parcel.readInt();
+ maxColorBalance = parcel.readInt();
}
// set temps
@@ -102,6 +118,8 @@ public class LiveDisplayConfig implements Parcelable {
mDefaultAutoOutdoorMode = defaultAutoOutdoorMode;
mDefaultCABC = defaultCABC;
mDefaultColorEnhancement = defaultColorEnhancement;
+ mColorTemperatureRange = Range.create(minColorTemperature, maxColorTemperature);
+ mColorBalanceRange = Range.create(minColorBalance, maxColorBalance);
// Complete parcel info for the concierge
parcelInfo.complete();
@@ -118,6 +136,8 @@ public class LiveDisplayConfig implements Parcelable {
sb.append(" defaultAutoContrast=").append(mDefaultAutoContrast);
sb.append(" defaultCABC=").append(mDefaultCABC);
sb.append(" defaultColorEnhancement=").append(mDefaultColorEnhancement);
+ sb.append(" colorTemperatureRange=").append(mColorTemperatureRange);
+ sb.append(" colorBalanceRange=").append(mColorBalanceRange);
return sb.toString();
}
@@ -141,6 +161,10 @@ public class LiveDisplayConfig implements Parcelable {
out.writeInt(mDefaultAutoOutdoorMode ? 1 : 0);
out.writeInt(mDefaultCABC ? 1 : 0);
out.writeInt(mDefaultColorEnhancement ? 1 : 0);
+ out.writeInt(mColorTemperatureRange.getLower());
+ out.writeInt(mColorTemperatureRange.getUpper());
+ out.writeInt(mColorBalanceRange.getLower());
+ out.writeInt(mColorBalanceRange.getUpper());
// Complete the parcel info for the concierge
parcelInfo.complete();
@@ -243,6 +267,24 @@ public class LiveDisplayConfig implements Parcelable {
return mDefaultColorEnhancement;
}
+ /**
+ * Get the range of supported color temperatures
+ *
+ * @return range in Kelvin
+ */
+ public Range<Integer> getColorTemperatureRange() {
+ return mColorTemperatureRange;
+ }
+
+ /**
+ * Get the range of supported color balance
+ *
+ * @return linear range which maps into the temperature range curve
+ */
+ public Range<Integer> getColorBalanceRange() {
+ return mColorBalanceRange;
+ }
+
/** @hide */
public static final Parcelable.Creator<LiveDisplayConfig> CREATOR =
new Parcelable.Creator<LiveDisplayConfig>() {
diff --git a/sdk/src/java/cyanogenmod/hardware/LiveDisplayManager.java b/sdk/src/java/cyanogenmod/hardware/LiveDisplayManager.java
index abfd158..5a39a98 100644
--- a/sdk/src/java/cyanogenmod/hardware/LiveDisplayManager.java
+++ b/sdk/src/java/cyanogenmod/hardware/LiveDisplayManager.java
@@ -102,10 +102,17 @@ public class LiveDisplayManager {
*/
public static final int FEATURE_DISPLAY_MODES = 15;
+ /**
+ * System supports direct range-based control of display
+ * color balance (temperature). This is preferred over
+ * simple RGB adjustment.
+ */
+ public static final int FEATURE_COLOR_BALANCE = 16;
+
/** @hide */
public static final int FEATURE_FIRST = FEATURE_CABC;
/** @hide */
- public static final int FEATURE_LAST = FEATURE_DISPLAY_MODES;
+ public static final int FEATURE_LAST = FEATURE_COLOR_BALANCE;
private static final String TAG = "LiveDisplay";
diff --git a/sdk/src/java/cyanogenmod/providers/CMSettings.java b/sdk/src/java/cyanogenmod/providers/CMSettings.java
index 38c8b67..528518f 100644
--- a/sdk/src/java/cyanogenmod/providers/CMSettings.java
+++ b/sdk/src/java/cyanogenmod/providers/CMSettings.java
@@ -1311,7 +1311,7 @@ public final class CMSettings {
/** @hide */
public static final Validator DISPLAY_TEMPERATURE_DAY_VALIDATOR =
- new InclusiveIntegerRangeValidator(1000, 10000);
+ new InclusiveIntegerRangeValidator(0, 100000);
/**
* Color temperature of the display at night
@@ -1320,7 +1320,7 @@ public final class CMSettings {
/** @hide */
public static final Validator DISPLAY_TEMPERATURE_NIGHT_VALIDATOR =
- new InclusiveIntegerRangeValidator(1000, 10000);
+ new InclusiveIntegerRangeValidator(0, 100000);
/**
* Display color temperature adjustment mode, one of DAY (default), NIGHT, or AUTO.
diff --git a/sdk/src/java/org/cyanogenmod/internal/util/MathUtils.java b/sdk/src/java/org/cyanogenmod/internal/util/MathUtils.java
new file mode 100644
index 0000000..3a2ddf0
--- /dev/null
+++ b/sdk/src/java/org/cyanogenmod/internal/util/MathUtils.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2016 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 org.cyanogenmod.internal.util;
+
+public final class MathUtils {
+
+ /**
+ * Given a range of values which change continuously in a non-linear way,
+ * we can map back and forth to a linear scale using some quadratic equations.
+ *
+ * The linear scale ranges from 0 -> 1. This method will calculate the
+ * coefficients needed to solve the conversion functions in the next two methods.
+ *
+ * lower = actual value when linear value = 0
+ * mid = actual value when linear value = .5
+ * upper actual value when linear value = 1
+ *
+ * @param lower
+ * @param mid
+ * @param upper
+ * @return array of coefficients
+ */
+ public static double[] powerCurve(double lower, double mid, double upper) {
+ final double[] curve = new double[3];
+ curve[0] = ((lower * upper) - (mid * mid)) / (lower - (2 * mid) + upper);
+ curve[1] = Math.pow((mid - lower), 2) / (lower - (2 * mid) + upper);
+ curve[2] = 2 * Math.log((upper - mid) / (mid - lower));
+ return curve;
+ }
+
+ /**
+ * Map a value on a power curve to a linear value
+ *
+ * @param curve obtained from powerCurve()
+ * @param value to convert to linear scale
+ * @return linear value from 0 -> 1
+ */
+ public static double powerCurveToLinear(final double[] curve, double value) {
+ return Math.log((value - curve[0]) / curve[1]) / curve[2];
+ }
+
+ /**
+ * Map a value on a linear scale to a value on a power curve
+ *
+ * @param curve obtained from powerCurve()
+ * @param value from 0 -> 1 to map onto power curve
+ * @return actual value on the given curve
+ */
+ public static double linearToPowerCurve(final double[] curve, double value) {
+ return curve[0] + curve[1] * Math.exp(curve[2] * value);
+ }
+
+
+}
diff --git a/system-api/cm_system-current.txt b/system-api/cm_system-current.txt
index 87ba2c5..73de8ed 100644
--- a/system-api/cm_system-current.txt
+++ b/system-api/cm_system-current.txt
@@ -244,7 +244,7 @@ package cyanogenmod.app {
field public static final int ZEN_MODE_OFF = 0; // 0x0
}
- public final class Profile implements android.os.Parcelable {
+ public final class Profile implements java.lang.Comparable android.os.Parcelable {
ctor public Profile(java.lang.String);
method public void addSecondaryUuid(java.util.UUID);
method public int compareTo(java.lang.Object);
@@ -451,6 +451,8 @@ package cyanogenmod.hardware {
public final class CMHardwareManager {
method public boolean deletePersistentObject(java.lang.String);
method public boolean get(int);
+ method public int getColorBalance();
+ method public android.util.Range<java.lang.Integer> getColorBalanceRange();
method public cyanogenmod.hardware.DisplayMode getCurrentDisplayMode();
method public cyanogenmod.hardware.DisplayMode getDefaultDisplayMode();
method public int[] getDisplayColorCalibration();
@@ -483,6 +485,7 @@ package cyanogenmod.hardware {
method public boolean registerThermalListener(cyanogenmod.hardware.ThermalListenerCallback);
method public boolean requireAdaptiveBacklightForSunlightEnhancement();
method public boolean set(int, boolean);
+ method public boolean setColorBalance(int);
method public boolean setDisplayColorCalibration(int[]);
method public deprecated boolean setDisplayGammaCalibration(int, int[]);
method public boolean setDisplayMode(cyanogenmod.hardware.DisplayMode, boolean);
@@ -493,6 +496,7 @@ package cyanogenmod.hardware {
method public boolean writePersistentString(java.lang.String, java.lang.String);
field public static final int FEATURE_ADAPTIVE_BACKLIGHT = 1; // 0x1
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
field public static final int FEATURE_DISPLAY_COLOR_CALIBRATION = 4; // 0x4
field public static final int FEATURE_DISPLAY_GAMMA_CALIBRATION = 8; // 0x8
@@ -530,8 +534,10 @@ package cyanogenmod.hardware {
}
public class LiveDisplayConfig implements android.os.Parcelable {
- ctor public LiveDisplayConfig(java.util.BitSet, int, int, int, boolean, boolean, boolean, boolean);
+ ctor public LiveDisplayConfig(java.util.BitSet, int, int, int, boolean, boolean, boolean, boolean, android.util.Range<java.lang.Integer>, android.util.Range<java.lang.Integer>);
method public int describeContents();
+ method public android.util.Range<java.lang.Integer> getColorBalanceRange();
+ method public android.util.Range<java.lang.Integer> getColorTemperatureRange();
method public boolean getDefaultAutoContrast();
method public boolean getDefaultAutoOutdoorMode();
method public boolean getDefaultCABC();
@@ -567,6 +573,7 @@ package cyanogenmod.hardware {
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
+ field public static final int FEATURE_COLOR_BALANCE = 16; // 0x10
field public static final int FEATURE_COLOR_ENHANCEMENT = 12; // 0xc
field public static final int FEATURE_DISPLAY_MODES = 15; // 0xf
field public static final int FEATURE_MANAGED_OUTDOOR_MODE = 14; // 0xe
@@ -948,6 +955,7 @@ package cyanogenmod.providers {
field public static final java.lang.String KEY_MENU_ACTION = "key_menu_action";
field public static final java.lang.String KEY_MENU_LONG_PRESS_ACTION = "key_menu_long_press_action";
field public static final java.lang.String LOCKSCREEN_PIN_SCRAMBLE_LAYOUT = "lockscreen_scramble_pin_layout";
+ field public static final java.lang.String LOCKSCREEN_ROTATION = "lockscreen_rotation";
field public static final java.lang.String MENU_WAKE_SCREEN = "menu_wake_screen";
field public static final java.lang.String NAVBAR_LEFT_IN_LANDSCAPE = "navigation_bar_left";
field public static final java.lang.String NAVIGATION_BAR_MENU_ARROW_KEYS = "navigation_bar_menu_arrow_keys";
@@ -972,7 +980,6 @@ package cyanogenmod.providers {
field public static final java.lang.String QS_SHOW_BRIGHTNESS_SLIDER = "qs_show_brightness_slider";
field public static final java.lang.String RECENTS_SHOW_SEARCH_BAR = "recents_show_search_bar";
field public static final java.lang.String REVERSE_LOOKUP_PROVIDER = "reverse_lookup_provider";
- field public static final java.lang.String LOCKSCREEN_ROTATION = "lockscreen_rotation";
field public static final java.lang.String SHOW_ALARM_ICON = "show_alarm_icon";
field public static final java.lang.String STATUS_BAR_AM_PM = "status_bar_am_pm";
field public static final java.lang.String STATUS_BAR_BATTERY_STYLE = "status_bar_battery_style";