aboutsummaryrefslogtreecommitdiffstats
path: root/cm/lib/main/java/org/cyanogenmod/platform
diff options
context:
space:
mode:
Diffstat (limited to 'cm/lib/main/java/org/cyanogenmod/platform')
-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
3 files changed, 178 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(