aboutsummaryrefslogtreecommitdiffstats
path: root/cm
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 /cm
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
Diffstat (limited to 'cm')
-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
5 files changed, 189 insertions, 6 deletions
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" />