cmsdk: Refactoring LiveDisplay
* Moving LiveDisplay to CMSDK! * Completely redesigned the feature for future expansion. * No new features in this patch, but a proper API is being designed. Change-Id: Ic8f55678f9141bf3386b2a1cf2fd1e8b3916c278
This commit is contained in:
parent
620b1eb908
commit
1dab5a0ca9
|
@ -529,6 +529,53 @@ package cyanogenmod.hardware {
|
|||
method public boolean onTransact(int, android.os.Parcel, android.os.Parcel, int) throws android.os.RemoteException;
|
||||
}
|
||||
|
||||
public class LiveDisplayConfig implements android.os.Parcelable {
|
||||
ctor public LiveDisplayConfig(java.util.BitSet, int, int, int, boolean, boolean, boolean, boolean);
|
||||
method public int describeContents();
|
||||
method public boolean getDefaultAutoContrast();
|
||||
method public boolean getDefaultAutoOutdoorMode();
|
||||
method public boolean getDefaultCABC();
|
||||
method public boolean getDefaultColorEnhancement();
|
||||
method public int getDefaultDayTemperature();
|
||||
method public int getDefaultMode();
|
||||
method public int getDefaultNightTemperature();
|
||||
method public boolean hasFeature(int);
|
||||
method public boolean isAvailable();
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
}
|
||||
|
||||
public class LiveDisplayManager {
|
||||
method public float[] getColorAdjustment();
|
||||
method public cyanogenmod.hardware.LiveDisplayConfig getConfig();
|
||||
method public int getDayColorTemperature();
|
||||
method public static synchronized cyanogenmod.hardware.LiveDisplayManager getInstance(android.content.Context);
|
||||
method public int getMode();
|
||||
method public int getNightColorTemperature();
|
||||
method public boolean isAutoContrastEnabled();
|
||||
method public boolean isAutomaticOutdoorModeEnabled();
|
||||
method public boolean isCABCEnabled();
|
||||
method public boolean isColorEnhancementEnabled();
|
||||
method public boolean setAutoContrastEnabled(boolean);
|
||||
method public boolean setAutomaticOutdoorModeEnabled(boolean);
|
||||
method public boolean setCABCEnabled(boolean);
|
||||
method public boolean setColorAdjustment(float[]);
|
||||
method public boolean setColorEnhancementEnabled(boolean);
|
||||
method public boolean setDayColorTemperature(int);
|
||||
method public boolean setMode(int);
|
||||
method public boolean setNightColorTemperature(int);
|
||||
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_ENHANCEMENT = 12; // 0xc
|
||||
field public static final int FEATURE_DISPLAY_MODES = 15; // 0xf
|
||||
field public static final int FEATURE_MANAGED_OUTDOOR_MODE = 14; // 0xe
|
||||
field public static final int MODE_AUTO = 2; // 0x2
|
||||
field public static final int MODE_DAY = 4; // 0x4
|
||||
field public static final int MODE_NIGHT = 1; // 0x1
|
||||
field public static final int MODE_OFF = 0; // 0x0
|
||||
field public static final int MODE_OUTDOOR = 3; // 0x3
|
||||
}
|
||||
|
||||
public abstract class ThermalListenerCallback extends cyanogenmod.hardware.IThermalListenerCallback.Stub {
|
||||
ctor public ThermalListenerCallback();
|
||||
}
|
||||
|
@ -613,6 +660,7 @@ package cyanogenmod.platform {
|
|||
field public static final java.lang.String HARDWARE_ABSTRACTION_ACCESS = "cyanogenmod.permission.HARDWARE_ABSTRACTION_ACCESS";
|
||||
field public static final java.lang.String LIVE_LOCK_SCREEN_MANAGER_ACCESS = "cyanogenmod.permission.LIVE_LOCK_SCREEN_MANAGER_ACCESS";
|
||||
field public static final java.lang.String MANAGE_ALARMS = "cyanogenmod.permission.MANAGE_ALARMS";
|
||||
field public static final java.lang.String MANAGE_LIVEDISPLAY = "cyanogenmod.permission.MANAGE_LIVEDISPLAY";
|
||||
field public static final java.lang.String MANAGE_PERSISTENT_STORAGE = "cyanogenmod.permission.MANAGE_PERSISTENT_STORAGE";
|
||||
field public static final java.lang.String MODIFY_MSIM_PHONE_STATE = "cyanogenmod.permission.MODIFY_MSIM_PHONE_STATE";
|
||||
field public static final java.lang.String MODIFY_NETWORK_SETTINGS = "cyanogenmod.permission.MODIFY_NETWORK_SETTINGS";
|
||||
|
@ -795,6 +843,7 @@ package cyanogenmod.providers {
|
|||
public final class CMSettings {
|
||||
ctor public CMSettings();
|
||||
field public static final java.lang.String ACTION_DATA_USAGE = "cyanogenmod.settings.ACTION_DATA_USAGE";
|
||||
field public static final java.lang.String ACTION_LIVEDISPLAY_SETTINGS = "cyanogenmod.settings.LIVEDISPLAY_SETTINGS";
|
||||
field public static final java.lang.String AUTHORITY = "cmsettings";
|
||||
}
|
||||
|
||||
|
@ -868,10 +917,12 @@ package cyanogenmod.providers {
|
|||
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_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";
|
||||
field public static final java.lang.String DISPLAY_COLOR_ADJUSTMENT = "display_color_adjustment";
|
||||
field public static final java.lang.String DISPLAY_COLOR_ENHANCE = "display_color_enhance";
|
||||
field public static final java.lang.String DISPLAY_LOW_POWER = "display_low_power";
|
||||
field public static final deprecated java.lang.String DISPLAY_LOW_POWER = "display_low_power";
|
||||
field public static final java.lang.String DISPLAY_TEMPERATURE_DAY = "display_temperature_day";
|
||||
field public static final java.lang.String DISPLAY_TEMPERATURE_MODE = "display_temperature_mode";
|
||||
field public static final java.lang.String DISPLAY_TEMPERATURE_NIGHT = "display_temperature_night";
|
||||
|
|
|
@ -0,0 +1,254 @@
|
|||
/*
|
||||
* 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.platform.internal.display;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.Sensor;
|
||||
import android.hardware.SensorEvent;
|
||||
import android.hardware.SensorEventListener;
|
||||
import android.hardware.SensorManager;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
|
||||
public class AmbientLuxObserver {
|
||||
|
||||
private static final String TAG = "AmbientLuxObserver";
|
||||
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
||||
|
||||
private final Sensor mLightSensor;
|
||||
private final SensorManager mSensorManager;
|
||||
|
||||
private final float mThresholdLux;
|
||||
private final int mThresholdDuration;
|
||||
|
||||
private boolean mLightSensorEnabled = false;
|
||||
private int mLightSensorRate;
|
||||
|
||||
private float mAmbientLux = 0.0f;
|
||||
|
||||
private static final int LOW = 0;
|
||||
private static final int HIGH = 1;
|
||||
|
||||
private int mState = LOW;
|
||||
|
||||
private final AmbientLuxHandler mLuxHandler;
|
||||
|
||||
private TransitionListener mCallback;
|
||||
|
||||
private final TimedMovingAverageRingBuffer mRingBuffer;
|
||||
|
||||
public interface TransitionListener {
|
||||
public void onTransition(int state, float ambientLux);
|
||||
}
|
||||
|
||||
public AmbientLuxObserver(Context context, Looper looper,
|
||||
float thresholdLux, int thresholdDuration) {
|
||||
mLuxHandler = new AmbientLuxHandler(looper);
|
||||
mThresholdLux = thresholdLux;
|
||||
mThresholdDuration = thresholdDuration;
|
||||
mRingBuffer = new TimedMovingAverageRingBuffer(thresholdDuration);
|
||||
|
||||
mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
|
||||
mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
|
||||
mLightSensorRate = context.getResources().getInteger(
|
||||
com.android.internal.R.integer.config_autoBrightnessLightSensorRate);
|
||||
}
|
||||
|
||||
private class AmbientLuxHandler extends Handler {
|
||||
|
||||
private static final int MSG_UPDATE_LUX = 0;
|
||||
private static final int MSG_TRANSITION = 1;
|
||||
|
||||
AmbientLuxHandler(Looper looper) {
|
||||
super(looper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
int direction = 0;
|
||||
float lux = 0.0f;
|
||||
|
||||
synchronized (AmbientLuxObserver.this) {
|
||||
switch (msg.what) {
|
||||
case MSG_UPDATE_LUX:
|
||||
lux = (Float) msg.obj;
|
||||
mRingBuffer.add(lux);
|
||||
|
||||
// FALL THRU
|
||||
|
||||
case MSG_TRANSITION:
|
||||
mAmbientLux = mRingBuffer.getAverage();
|
||||
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "lux= " + lux + " mState=" + mState +
|
||||
" mAmbientLux=" + mAmbientLux);
|
||||
}
|
||||
|
||||
direction = mAmbientLux >= mThresholdLux ? HIGH : LOW;
|
||||
if (mState != direction) {
|
||||
mState = direction;
|
||||
if (mCallback != null) {
|
||||
mCallback.onTransition(mState, mAmbientLux);
|
||||
}
|
||||
}
|
||||
|
||||
// check again in case we didn't get any
|
||||
// more readings because the sensor settled
|
||||
if (mRingBuffer.size() > 1) {
|
||||
sendEmptyMessageDelayed(MSG_TRANSITION, mThresholdDuration / 2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void clear() {
|
||||
removeCallbacksAndMessages(null);
|
||||
}
|
||||
};
|
||||
|
||||
private final SensorEventListener mListener = new SensorEventListener() {
|
||||
@Override
|
||||
public void onSensorChanged(SensorEvent event) {
|
||||
if (mLightSensorEnabled) {
|
||||
Message.obtain(mLuxHandler, AmbientLuxHandler.MSG_UPDATE_LUX,
|
||||
event.values[0]).sendToTarget();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccuracyChanged(Sensor sensor, int accuracy) {
|
||||
// Not used.
|
||||
}
|
||||
};
|
||||
|
||||
public synchronized int getState() {
|
||||
return mState;
|
||||
}
|
||||
|
||||
public synchronized void setTransitionListener(TransitionListener callback) {
|
||||
mCallback = callback;
|
||||
enableLightSensor(callback != null);
|
||||
}
|
||||
|
||||
private void enableLightSensor(boolean enable) {
|
||||
if (enable && !mLightSensorEnabled) {
|
||||
mAmbientLux = 0.0f;
|
||||
mState = LOW;
|
||||
mLightSensorEnabled = true;
|
||||
mRingBuffer.clear();
|
||||
mSensorManager.registerListener(mListener, mLightSensor,
|
||||
mLightSensorRate * 1000, mLuxHandler);
|
||||
} else if (!enable && mLightSensorEnabled) {
|
||||
mLightSensorEnabled = false;
|
||||
mSensorManager.unregisterListener(mListener);
|
||||
mLuxHandler.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void dump(PrintWriter pw) {
|
||||
pw.println();
|
||||
pw.println(" AmbientLuxObserver State:");
|
||||
pw.println(" mLightSensorEnabled=" + mLightSensorEnabled);
|
||||
pw.println(" mState=" + mState);
|
||||
pw.println(" mAmbientLux=" + mAmbientLux);
|
||||
pw.println(" mRingBuffer=" + mRingBuffer.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates a simple moving average based on a fixed
|
||||
* duration sliding window. This is useful for dampening
|
||||
* erratic sensors and rolling thru transitional periods
|
||||
* smoothly.
|
||||
*/
|
||||
private static class TimedMovingAverageRingBuffer {
|
||||
|
||||
private final LinkedList<Sample> mRing = new LinkedList<Sample>();
|
||||
|
||||
private final int mPeriod;
|
||||
|
||||
private float mTotal = 0.0f;
|
||||
|
||||
private static class Sample {
|
||||
public final long mTimestamp;
|
||||
public final float mValue;
|
||||
public Sample (long timestamp, float value) {
|
||||
mTimestamp = timestamp;
|
||||
mValue = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "(" + mValue + ", " + mTimestamp + ")";
|
||||
}
|
||||
}
|
||||
|
||||
public TimedMovingAverageRingBuffer(int period) {
|
||||
mPeriod = period;
|
||||
}
|
||||
|
||||
public synchronized void add(float sample) {
|
||||
expire();
|
||||
if (sample == 0.0f && mRing.size() == 0) {
|
||||
return;
|
||||
}
|
||||
mRing.offer(new Sample(System.currentTimeMillis(), sample));
|
||||
mTotal += sample;
|
||||
}
|
||||
|
||||
public synchronized int size() {
|
||||
return mRing.size();
|
||||
}
|
||||
|
||||
public synchronized float getAverage() {
|
||||
expire();
|
||||
return mRing.size() == 0 ? 0.0f : (mTotal / mRing.size());
|
||||
}
|
||||
|
||||
public synchronized void clear() {
|
||||
mRing.clear();
|
||||
mTotal = 0.0f;
|
||||
}
|
||||
|
||||
private void expire() {
|
||||
long now = System.currentTimeMillis();
|
||||
while (mRing.size() > 1 &&
|
||||
((now - mRing.peek().mTimestamp) > mPeriod)) {
|
||||
mTotal -= mRing.pop().mValue;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized String toString() {
|
||||
expire();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Iterator<Sample> i = mRing.iterator(); i.hasNext();) {
|
||||
if (sb.length() > 0) {
|
||||
sb.append(", ");
|
||||
}
|
||||
sb.append(i.next());
|
||||
}
|
||||
return "average=" + getAverage() + " length=" + mRing.size() +
|
||||
" mRing=[" + sb.toString() + "]";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,272 @@
|
|||
/*
|
||||
* 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.platform.internal.display;
|
||||
|
||||
import static cyanogenmod.hardware.LiveDisplayManager.MODE_AUTO;
|
||||
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.os.UserHandle;
|
||||
import android.text.format.DateUtils;
|
||||
import android.util.MathUtils;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.server.twilight.TwilightState;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.BitSet;
|
||||
|
||||
import cyanogenmod.providers.CMSettings;
|
||||
import cyanogenmod.util.ColorUtils;
|
||||
|
||||
public class ColorTemperatureController extends LiveDisplayFeature {
|
||||
|
||||
private ValueAnimator mAnimator;
|
||||
private DisplayHardwareController mDisplayHardware;
|
||||
|
||||
private boolean mUseTemperatureAdjustment;
|
||||
|
||||
private int mDefaultDayTemperature;
|
||||
private int mDefaultNightTemperature;
|
||||
|
||||
private int mDayTemperature;
|
||||
private int mNightTemperature;
|
||||
|
||||
private static final long TWILIGHT_ADJUSTMENT_TIME = DateUtils.HOUR_IN_MILLIS * 1;
|
||||
|
||||
private static final int OFF_TEMPERATURE = 6500;
|
||||
|
||||
private int mColorTemperature = OFF_TEMPERATURE;
|
||||
|
||||
public ColorTemperatureController(Context context, Handler handler,
|
||||
DisplayHardwareController displayHardware) {
|
||||
super(context, handler);
|
||||
mDisplayHardware = displayHardware;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onStart() {
|
||||
if (!mDisplayHardware.hasColorAdjustment()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mUseTemperatureAdjustment = true;
|
||||
|
||||
mDefaultDayTemperature = mContext.getResources().getInteger(
|
||||
org.cyanogenmod.platform.internal.R.integer.config_dayColorTemperature);
|
||||
mDefaultNightTemperature = mContext.getResources().getInteger(
|
||||
org.cyanogenmod.platform.internal.R.integer.config_nightColorTemperature);
|
||||
|
||||
registerSettings(
|
||||
CMSettings.System.getUriFor(CMSettings.System.DISPLAY_TEMPERATURE_DAY),
|
||||
CMSettings.System.getUriFor(CMSettings.System.DISPLAY_TEMPERATURE_NIGHT));
|
||||
return true;
|
||||
}
|
||||
|
||||
void getCapabilities(final BitSet caps) {
|
||||
if (mUseTemperatureAdjustment) {
|
||||
caps.set(MODE_AUTO);
|
||||
caps.set(MODE_DAY);
|
||||
caps.set(MODE_NIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
int getDefaultDayTemperature() {
|
||||
return mDefaultDayTemperature;
|
||||
}
|
||||
|
||||
int getDefaultNightTemperature() {
|
||||
return mDefaultNightTemperature;
|
||||
}
|
||||
|
||||
int getColorTemperature() {
|
||||
return mColorTemperature;
|
||||
}
|
||||
|
||||
int getDayColorTemperature() {
|
||||
return getInt(CMSettings.System.DISPLAY_TEMPERATURE_DAY,
|
||||
mDefaultDayTemperature);
|
||||
}
|
||||
|
||||
void setDayColorTemperature(int temperature) {
|
||||
putInt(CMSettings.System.DISPLAY_TEMPERATURE_DAY, temperature);
|
||||
}
|
||||
|
||||
int getNightColorTemperature() {
|
||||
return getInt(CMSettings.System.DISPLAY_TEMPERATURE_NIGHT,
|
||||
mDefaultNightTemperature);
|
||||
}
|
||||
|
||||
void setNightColorTemperature(int temperature) {
|
||||
putInt(CMSettings.System.DISPLAY_TEMPERATURE_NIGHT, temperature);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onModeChanged(int mode) {
|
||||
super.onModeChanged(mode);
|
||||
updateColorTemperature();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void onSettingsChanged(Uri uri) {
|
||||
mDayTemperature = getDayColorTemperature();
|
||||
mNightTemperature = getNightColorTemperature();
|
||||
updateColorTemperature();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTwilightUpdated(TwilightState twilight) {
|
||||
super.onTwilightUpdated(twilight);
|
||||
mHandler.post(mTransitionRunnable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dump(PrintWriter pw) {
|
||||
pw.println();
|
||||
pw.println("ColorTemperatureController Configuration:");
|
||||
pw.println(" mDayTemperature=" + mDayTemperature);
|
||||
pw.println(" mNightTemperature=" + mNightTemperature);
|
||||
pw.println();
|
||||
pw.println(" ColorTemperatureController State:");
|
||||
pw.println(" mColorTemperature=" + mColorTemperature);
|
||||
if (getTwilight() != null) {
|
||||
pw.println(" mTwilight=" + getTwilight().toString());
|
||||
}
|
||||
pw.println(" transitioning=" + mHandler.hasCallbacks(mTransitionRunnable));
|
||||
}
|
||||
|
||||
private final Runnable mTransitionRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
synchronized (ColorTemperatureController.this) {
|
||||
updateColorTemperature();
|
||||
|
||||
boolean transition = getMode() == MODE_AUTO &&
|
||||
mColorTemperature != mDayTemperature &&
|
||||
mColorTemperature != mNightTemperature;
|
||||
|
||||
if (transition) {
|
||||
// fire again in a minute
|
||||
mHandler.postDelayed(mTransitionRunnable, DateUtils.MINUTE_IN_MILLIS);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private void updateColorTemperature() {
|
||||
mHandler.removeCallbacks(mTransitionRunnable);
|
||||
|
||||
int temperature = mDayTemperature;
|
||||
int mode = getMode();
|
||||
|
||||
if (mode == MODE_OFF || isLowPowerMode()) {
|
||||
temperature = OFF_TEMPERATURE;
|
||||
} else if (mode == MODE_NIGHT) {
|
||||
temperature = mNightTemperature;
|
||||
} else if (mode == MODE_AUTO) {
|
||||
temperature = getTwilightK();
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "updateColorTemperatureLocked mode=" + mode +
|
||||
" temperature=" + temperature + " mColorTemperature=" + mColorTemperature);
|
||||
}
|
||||
|
||||
if (mAnimator != null) {
|
||||
mAnimator.cancel();
|
||||
mAnimator.removeAllUpdateListeners();
|
||||
}
|
||||
mAnimator = ValueAnimator.ofInt(mColorTemperature, temperature);
|
||||
mAnimator.setDuration(Math.abs(mColorTemperature - temperature) / 2);
|
||||
mAnimator.addUpdateListener(new AnimatorUpdateListener() {
|
||||
@Override
|
||||
public void onAnimationUpdate(final ValueAnimator animation) {
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
setDisplayTemperature((Integer)animation.getAnimatedValue());
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
mAnimator.start();
|
||||
}
|
||||
|
||||
|
||||
private synchronized void setDisplayTemperature(int temperature) {
|
||||
mColorTemperature = temperature;
|
||||
|
||||
final float[] rgb = ColorUtils.temperatureToRGB(temperature);
|
||||
mDisplayHardware.setAdditionalAdjustment(rgb);
|
||||
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Adjust display temperature to " + temperature + "K");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Where is the sun anyway? This calculation determines day or night, and scales
|
||||
* the value around sunset/sunrise for a smooth transition.
|
||||
*
|
||||
* @param now
|
||||
* @param sunset
|
||||
* @param sunrise
|
||||
* @return float between 0 and 1
|
||||
*/
|
||||
private static float adj(long now, long sunset, long sunrise) {
|
||||
if (sunset < 0 || sunrise < 0
|
||||
|| now < sunset || now > sunrise) {
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
if (now < sunset + TWILIGHT_ADJUSTMENT_TIME) {
|
||||
return MathUtils.lerp(1.0f, 0.0f,
|
||||
(float)(now - sunset) / TWILIGHT_ADJUSTMENT_TIME);
|
||||
}
|
||||
|
||||
if (now > sunrise - TWILIGHT_ADJUSTMENT_TIME) {
|
||||
return MathUtils.lerp(1.0f, 0.0f,
|
||||
(float)(sunrise - now) / TWILIGHT_ADJUSTMENT_TIME);
|
||||
}
|
||||
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the color temperature we should use for the display based on
|
||||
* the position of the sun.
|
||||
*
|
||||
* @return color temperature in Kelvin
|
||||
*/
|
||||
private int getTwilightK() {
|
||||
float adjustment = 1.0f;
|
||||
final TwilightState twilight = getTwilight();
|
||||
|
||||
if (twilight != null) {
|
||||
final long now = System.currentTimeMillis();
|
||||
adjustment = adj(now, twilight.getYesterdaySunset(), twilight.getTodaySunrise()) *
|
||||
adj(now, twilight.getTodaySunset(), twilight.getTomorrowSunrise());
|
||||
}
|
||||
|
||||
return (int)MathUtils.lerp(mNightTemperature, mDayTemperature, adjustment);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,435 @@
|
|||
/*
|
||||
* 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.platform.internal.display;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Parcel;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.util.Slog;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.BitSet;
|
||||
|
||||
import cyanogenmod.hardware.CMHardwareManager;
|
||||
import cyanogenmod.hardware.LiveDisplayManager;
|
||||
import cyanogenmod.providers.CMSettings;
|
||||
|
||||
public class DisplayHardwareController extends LiveDisplayFeature {
|
||||
|
||||
private CMHardwareManager mHardware;
|
||||
|
||||
// hardware capabilities
|
||||
private boolean mUseAutoContrast;
|
||||
private boolean mUseColorAdjustment;
|
||||
private boolean mUseColorEnhancement;
|
||||
private boolean mUseCABC;
|
||||
|
||||
// default values
|
||||
private boolean mDefaultAutoContrast;
|
||||
private boolean mDefaultColorEnhancement;
|
||||
private boolean mDefaultCABC;
|
||||
|
||||
// current values
|
||||
private boolean mAutoContrast;
|
||||
private boolean mColorEnhancement;
|
||||
private boolean mCABC;
|
||||
|
||||
// color adjustment holders
|
||||
private final float[] mColorAdjustment = new float[] { 1.0f, 1.0f, 1.0f };
|
||||
private final float[] mAdditionalAdjustment = new float[] { 1.0f, 1.0f, 1.0f };
|
||||
private final float[] mRGB = new float[] { 1.0f, 1.0f, 1.0f };
|
||||
|
||||
// settings uris
|
||||
private static final Uri DISPLAY_AUTO_CONTRAST =
|
||||
CMSettings.System.getUriFor(CMSettings.System.DISPLAY_AUTO_CONTRAST);
|
||||
private static final Uri DISPLAY_COLOR_ADJUSTMENT =
|
||||
CMSettings.System.getUriFor(CMSettings.System.DISPLAY_COLOR_ADJUSTMENT);
|
||||
private static final Uri DISPLAY_COLOR_ENHANCE =
|
||||
CMSettings.System.getUriFor(CMSettings.System.DISPLAY_COLOR_ENHANCE);
|
||||
private static final Uri DISPLAY_CABC =
|
||||
CMSettings.System.getUriFor(CMSettings.System.DISPLAY_CABC);
|
||||
|
||||
public DisplayHardwareController(Context context, Handler handler) {
|
||||
super(context, handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onStart() {
|
||||
final ArrayList<Uri> settings = new ArrayList<Uri>();
|
||||
|
||||
mHardware = CMHardwareManager.getInstance(mContext);
|
||||
mUseCABC = mHardware
|
||||
.isSupported(CMHardwareManager.FEATURE_ADAPTIVE_BACKLIGHT);
|
||||
if (mUseCABC) {
|
||||
mDefaultCABC = mContext.getResources().getBoolean(
|
||||
org.cyanogenmod.platform.internal.R.bool.config_defaultCABC);
|
||||
mCABC = mHardware.get(CMHardwareManager.FEATURE_ADAPTIVE_BACKLIGHT);
|
||||
settings.add(DISPLAY_CABC);
|
||||
}
|
||||
|
||||
mUseColorEnhancement = mHardware
|
||||
.isSupported(CMHardwareManager.FEATURE_COLOR_ENHANCEMENT);
|
||||
if (mUseColorEnhancement) {
|
||||
mDefaultColorEnhancement = mContext.getResources().getBoolean(
|
||||
org.cyanogenmod.platform.internal.R.bool.config_defaultColorEnhancement);
|
||||
mColorEnhancement = mHardware.get(CMHardwareManager.FEATURE_COLOR_ENHANCEMENT);
|
||||
settings.add(DISPLAY_COLOR_ENHANCE);
|
||||
}
|
||||
|
||||
mUseAutoContrast = mHardware
|
||||
.isSupported(CMHardwareManager.FEATURE_AUTO_CONTRAST);
|
||||
if (mUseAutoContrast) {
|
||||
mDefaultAutoContrast = mContext.getResources().getBoolean(
|
||||
org.cyanogenmod.platform.internal.R.bool.config_defaultAutoContrast);
|
||||
mAutoContrast = mHardware.get(CMHardwareManager.FEATURE_AUTO_CONTRAST);
|
||||
settings.add(DISPLAY_AUTO_CONTRAST);
|
||||
}
|
||||
|
||||
mUseColorAdjustment = mHardware
|
||||
.isSupported(CMHardwareManager.FEATURE_DISPLAY_COLOR_CALIBRATION);
|
||||
if (mUseColorAdjustment) {
|
||||
settings.add(DISPLAY_COLOR_ADJUSTMENT);
|
||||
}
|
||||
|
||||
if (settings.size() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
registerSettings(settings.toArray(new Uri[settings.size()]));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
void getCapabilities(final BitSet caps) {
|
||||
if (mUseAutoContrast) {
|
||||
caps.set(LiveDisplayManager.FEATURE_AUTO_CONTRAST);
|
||||
}
|
||||
if (mUseColorEnhancement) {
|
||||
caps.set(LiveDisplayManager.FEATURE_COLOR_ENHANCEMENT);
|
||||
}
|
||||
if (mUseCABC) {
|
||||
caps.set(LiveDisplayManager.FEATURE_CABC);
|
||||
}
|
||||
if (mUseColorAdjustment) {
|
||||
caps.set(LiveDisplayManager.FEATURE_COLOR_ADJUSTMENT);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void onSettingsChanged(Uri uri) {
|
||||
if (uri == null || uri.equals(DISPLAY_CABC)) {
|
||||
updateCABCMode();
|
||||
}
|
||||
if (uri == null || uri.equals(DISPLAY_AUTO_CONTRAST)) {
|
||||
updateAutoContrast();
|
||||
}
|
||||
if (uri == null || uri.equals(DISPLAY_COLOR_ENHANCE)) {
|
||||
updateColorEnhancement();
|
||||
}
|
||||
if (uri == null || uri.equals(DISPLAY_COLOR_ADJUSTMENT)) {
|
||||
System.arraycopy(
|
||||
parseColorAdjustment(getString(CMSettings.System.DISPLAY_COLOR_ADJUSTMENT)),
|
||||
0, mColorAdjustment, 0, 3);
|
||||
updateColorAdjustment();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void onLowPowerModeChanged(boolean lowPowerMode) {
|
||||
updateCABCMode();
|
||||
updateAutoContrast();
|
||||
updateColorEnhancement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dump(PrintWriter pw) {
|
||||
pw.println();
|
||||
pw.println("DisplayHardwareController Configuration:");
|
||||
pw.println(" mUseAutoContrast=" + mUseAutoContrast);
|
||||
pw.println(" mUseColorAdjustment=" + mUseColorAdjustment);
|
||||
pw.println(" mUseColorEnhancement=" + mUseColorEnhancement);
|
||||
pw.println(" mUseCABC=" + mUseCABC);
|
||||
pw.println();
|
||||
pw.println(" DisplayHardwareController State:");
|
||||
pw.println(" mAutoContrast=" + mAutoContrast);
|
||||
pw.println(" mColorEnhancement=" + mColorEnhancement);
|
||||
pw.println(" mCABC=" + mCABC);
|
||||
pw.println(" mColorAdjustment=" + Arrays.toString(mColorAdjustment));
|
||||
pw.println(" mAdditionalAdjustment=" + Arrays.toString(mAdditionalAdjustment));
|
||||
pw.println(" mRGB=" + Arrays.toString(mRGB));
|
||||
}
|
||||
|
||||
boolean hasColorAdjustment() {
|
||||
return mUseColorAdjustment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Additional adjustments provided by night mode
|
||||
*
|
||||
* @param adj
|
||||
*/
|
||||
synchronized void setAdditionalAdjustment(float[] adj) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "setAdditionalAdjustment: " + Arrays.toString(adj));
|
||||
}
|
||||
// Sanity check this so we don't mangle the display
|
||||
if (adj != null && adj.length == 3 &&
|
||||
!(adj[0] <= 0.0f && adj[1] <= 0.0f && adj[2] <= 0.0f)) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (adj[i] > 1.0f) {
|
||||
adj[i] = 1.0f;
|
||||
}
|
||||
}
|
||||
System.arraycopy(adj, 0, mAdditionalAdjustment, 0, 3);
|
||||
updateColorAdjustment();
|
||||
} else {
|
||||
mAdditionalAdjustment[0] = 1.0f;
|
||||
mAdditionalAdjustment[1] = 1.0f;
|
||||
mAdditionalAdjustment[2] = 1.0f;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Automatic contrast optimization
|
||||
*/
|
||||
private synchronized void updateAutoContrast() {
|
||||
if (!mUseAutoContrast) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean value = getInt(CMSettings.System.DISPLAY_AUTO_CONTRAST,
|
||||
(mDefaultAutoContrast ? 1 : 0)) == 1;
|
||||
|
||||
boolean enabled = !isLowPowerMode() && value;
|
||||
|
||||
if (enabled == mAutoContrast) {
|
||||
return;
|
||||
}
|
||||
|
||||
mHardware.set(CMHardwareManager.FEATURE_AUTO_CONTRAST, enabled);
|
||||
mAutoContrast = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Color enhancement is optional
|
||||
*/
|
||||
private synchronized void updateColorEnhancement() {
|
||||
if (!mUseColorEnhancement) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean value = getInt(CMSettings.System.DISPLAY_COLOR_ENHANCE,
|
||||
(mDefaultColorEnhancement ? 1 : 0)) == 1;
|
||||
|
||||
boolean enabled = !isLowPowerMode() && value;
|
||||
|
||||
if (enabled == mColorEnhancement) {
|
||||
return;
|
||||
}
|
||||
|
||||
mHardware.set(CMHardwareManager.FEATURE_COLOR_ENHANCEMENT, enabled);
|
||||
mColorEnhancement = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adaptive backlight / low power mode. Turn it off when under very bright light.
|
||||
*/
|
||||
private synchronized void updateCABCMode() {
|
||||
if (!mUseCABC) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean value = getInt(CMSettings.System.DISPLAY_CABC,
|
||||
(mDefaultCABC ? 1 : 0)) == 1;
|
||||
|
||||
boolean enabled = !isLowPowerMode() && value;
|
||||
|
||||
if (enabled == mCABC) {
|
||||
return;
|
||||
}
|
||||
|
||||
mHardware.set(CMHardwareManager.FEATURE_ADAPTIVE_BACKLIGHT, value);
|
||||
mCABC = value;
|
||||
}
|
||||
|
||||
private synchronized void updateColorAdjustment() {
|
||||
if (!mUseColorAdjustment) {
|
||||
return;
|
||||
}
|
||||
|
||||
final float[] rgb = new float[] { 1.0f, 1.0f, 1.0f };
|
||||
|
||||
if (!isLowPowerMode()) {
|
||||
|
||||
System.arraycopy(mAdditionalAdjustment, 0, rgb, 0, 3);
|
||||
rgb[0] *= mColorAdjustment[0];
|
||||
rgb[1] *= mColorAdjustment[1];
|
||||
rgb[2] *= mColorAdjustment[2];
|
||||
}
|
||||
|
||||
if (rgb[0] == mRGB[0] && rgb[1] == mRGB[1] && rgb[2] == mRGB[2]) {
|
||||
// no changes
|
||||
return;
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "updateColorAdjustment: " + Arrays.toString(rgb));
|
||||
}
|
||||
|
||||
int max = mHardware.getDisplayColorCalibrationMax();
|
||||
mHardware.setDisplayColorCalibration(new int[] {
|
||||
(int) Math.ceil(rgb[0] * max),
|
||||
(int) Math.ceil(rgb[1] * max),
|
||||
(int) Math.ceil(rgb[2] * max)
|
||||
});
|
||||
System.arraycopy(rgb, 0, mRGB, 0, 3);
|
||||
|
||||
screenRefresh();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell SurfaceFlinger to repaint the screen. This is called after updating
|
||||
* hardware registers for display calibration to have an immediate effect.
|
||||
*/
|
||||
private void screenRefresh() {
|
||||
try {
|
||||
final IBinder flinger = ServiceManager.getService("SurfaceFlinger");
|
||||
if (flinger != null) {
|
||||
final Parcel data = Parcel.obtain();
|
||||
data.writeInterfaceToken("android.ui.ISurfaceComposer");
|
||||
flinger.transact(1004, data, null, 0);
|
||||
data.recycle();
|
||||
}
|
||||
} catch (RemoteException ex) {
|
||||
Slog.e(TAG, "Failed to refresh screen", ex);
|
||||
}
|
||||
}
|
||||
|
||||
boolean getDefaultCABC() {
|
||||
return mDefaultCABC;
|
||||
}
|
||||
|
||||
boolean getDefaultAutoContrast() {
|
||||
return mDefaultAutoContrast;
|
||||
}
|
||||
|
||||
boolean getDefaultColorEnhancement() {
|
||||
return mDefaultColorEnhancement;
|
||||
}
|
||||
|
||||
boolean isAutoContrastEnabled() {
|
||||
return mUseAutoContrast &&
|
||||
getInt(CMSettings.System.DISPLAY_AUTO_CONTRAST,
|
||||
(mDefaultAutoContrast ? 1 : 0)) == 1;
|
||||
}
|
||||
|
||||
boolean setAutoContrastEnabled(boolean enabled) {
|
||||
if (!mUseAutoContrast) {
|
||||
return false;
|
||||
}
|
||||
putInt(CMSettings.System.DISPLAY_AUTO_CONTRAST, enabled ? 1 : 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean isCABCEnabled() {
|
||||
return mUseCABC &&
|
||||
getInt(CMSettings.System.DISPLAY_CABC,
|
||||
(mDefaultCABC ? 1 : 0)) == 1;
|
||||
}
|
||||
|
||||
boolean setCABCEnabled(boolean enabled) {
|
||||
if (!mUseCABC) {
|
||||
return false;
|
||||
}
|
||||
putInt(CMSettings.System.DISPLAY_CABC, enabled ? 1 : 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean isColorEnhancementEnabled() {
|
||||
return mUseColorEnhancement &&
|
||||
getInt(CMSettings.System.DISPLAY_COLOR_ENHANCE,
|
||||
(mDefaultColorEnhancement ? 1 : 0)) == 1;
|
||||
}
|
||||
|
||||
boolean setColorEnhancementEnabled(boolean enabled) {
|
||||
if (!mUseColorEnhancement) {
|
||||
return false;
|
||||
}
|
||||
putInt(CMSettings.System.DISPLAY_COLOR_ENHANCE, enabled ? 1 : 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
float[] getColorAdjustment() {
|
||||
if (!mUseColorAdjustment) {
|
||||
return new float[] { 1.0f, 1.0f, 1.0f };
|
||||
}
|
||||
return parseColorAdjustment(getString(CMSettings.System.DISPLAY_COLOR_ADJUSTMENT));
|
||||
}
|
||||
|
||||
boolean setColorAdjustment(float[] adj) {
|
||||
// sanity check
|
||||
if (!mUseColorAdjustment || adj.length != 3 ||
|
||||
adj[0] < 0 || adj[0] > 1.0f ||
|
||||
adj[1] < 0 || adj[1] > 1.0f ||
|
||||
adj[2] < 0 || adj[2] > 1.0f) {
|
||||
return false;
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(adj[0]).append(" ").append(adj[1]).append(" ").append(adj[2]);
|
||||
|
||||
putString(CMSettings.System.DISPLAY_COLOR_ADJUSTMENT, sb.toString());
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse and sanity check an RGB triplet from a string.
|
||||
*/
|
||||
private float[] parseColorAdjustment(String rgbString) {
|
||||
String[] adj = rgbString == null ? null : rgbString.split(" ");
|
||||
float[] parsed = new float[3];
|
||||
|
||||
if (adj == null || adj.length != 3) {
|
||||
adj = new String[] { "1.0", "1.0", "1.0" };
|
||||
}
|
||||
|
||||
try {
|
||||
parsed[0] = Float.parseFloat(adj[0]);
|
||||
parsed[1] = Float.parseFloat(adj[1]);
|
||||
parsed[2] = Float.parseFloat(adj[2]);
|
||||
} catch (NumberFormatException e) {
|
||||
Slog.e(TAG, e.getMessage(), e);
|
||||
parsed[0] = 1.0f;
|
||||
parsed[1] = 1.0f;
|
||||
parsed[2] = 1.0f;
|
||||
}
|
||||
|
||||
// sanity check
|
||||
for (int i = 0; i < parsed.length; i++) {
|
||||
if (parsed[i] <= 0.0f || parsed[i] > 1.0f) {
|
||||
parsed[i] = 1.0f;
|
||||
}
|
||||
}
|
||||
return parsed;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,158 @@
|
|||
/*
|
||||
* 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.platform.internal.display;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.server.pm.UserContentObserver;
|
||||
import com.android.server.twilight.TwilightState;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.BitSet;
|
||||
|
||||
import cyanogenmod.providers.CMSettings;
|
||||
|
||||
public abstract class LiveDisplayFeature {
|
||||
|
||||
protected static final String TAG = "LiveDisplay";
|
||||
protected static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
||||
|
||||
protected final Context mContext;
|
||||
protected final Handler mHandler;
|
||||
|
||||
private TwilightState mTwilight;
|
||||
private boolean mLowPowerMode = false;
|
||||
private boolean mScreenOn = false;
|
||||
private int mMode = 0;
|
||||
|
||||
private final SettingsObserver mSettingsObserver;
|
||||
|
||||
public LiveDisplayFeature(Context context, Handler handler) {
|
||||
mContext = context;
|
||||
mHandler = handler;
|
||||
mSettingsObserver = new SettingsObserver(handler);
|
||||
}
|
||||
|
||||
public abstract boolean onStart();
|
||||
|
||||
public abstract void onSettingsChanged(Uri uri);
|
||||
|
||||
public void onModeChanged(int mode) {
|
||||
mMode = mode;
|
||||
}
|
||||
|
||||
public void onDisplayStateChanged(boolean screenOn) {
|
||||
mScreenOn = screenOn;
|
||||
}
|
||||
|
||||
public void onLowPowerModeChanged(boolean lowPowerMode) {
|
||||
mLowPowerMode = lowPowerMode;
|
||||
}
|
||||
|
||||
public void onTwilightUpdated(TwilightState twilight) {
|
||||
mTwilight = twilight;
|
||||
}
|
||||
|
||||
public void onDestroy() {
|
||||
mSettingsObserver.unregister();
|
||||
}
|
||||
|
||||
public abstract void dump(PrintWriter pw);
|
||||
|
||||
abstract void getCapabilities(final BitSet caps);
|
||||
|
||||
protected final void registerSettings(Uri... settings) {
|
||||
mSettingsObserver.register(settings);
|
||||
onSettingsChanged(null);
|
||||
}
|
||||
|
||||
protected final int getInt(String setting, int defaultValue) {
|
||||
return CMSettings.System.getIntForUser(mContext.getContentResolver(),
|
||||
setting, defaultValue, UserHandle.USER_CURRENT);
|
||||
}
|
||||
|
||||
protected final void putInt(String setting, int value) {
|
||||
CMSettings.System.putIntForUser(mContext.getContentResolver(),
|
||||
setting, value, UserHandle.USER_CURRENT);
|
||||
}
|
||||
|
||||
protected final String getString(String setting) {
|
||||
return CMSettings.System.getStringForUser(mContext.getContentResolver(),
|
||||
setting, UserHandle.USER_CURRENT);
|
||||
}
|
||||
|
||||
protected final void putString(String setting, String value) {
|
||||
CMSettings.System.putStringForUser(mContext.getContentResolver(),
|
||||
setting, value, UserHandle.USER_CURRENT);
|
||||
}
|
||||
|
||||
protected final boolean isLowPowerMode() {
|
||||
return mLowPowerMode;
|
||||
}
|
||||
|
||||
protected final int getMode() {
|
||||
return mMode;
|
||||
}
|
||||
|
||||
protected final boolean isScreenOn() {
|
||||
return mScreenOn;
|
||||
}
|
||||
|
||||
protected final TwilightState getTwilight() {
|
||||
return mTwilight;
|
||||
}
|
||||
|
||||
protected final boolean isNight() {
|
||||
return mTwilight != null && mTwilight.isNight();
|
||||
}
|
||||
|
||||
final class SettingsObserver extends UserContentObserver {
|
||||
|
||||
public SettingsObserver(Handler handler) {
|
||||
super(handler);
|
||||
}
|
||||
|
||||
public void register(Uri... uris) {
|
||||
final ContentResolver cr = mContext.getContentResolver();
|
||||
for (Uri uri : uris) {
|
||||
cr.registerContentObserver(uri, false, this, UserHandle.USER_ALL);
|
||||
}
|
||||
|
||||
observe();
|
||||
}
|
||||
|
||||
public void unregister() {
|
||||
mContext.getContentResolver().unregisterContentObserver(this);
|
||||
unobserve();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void update() {
|
||||
onSettingsChanged(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChange(boolean selfChange, Uri uri) {
|
||||
onSettingsChanged(uri);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,523 @@
|
|||
/*
|
||||
* 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.platform.internal.display;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.hardware.display.DisplayManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.PowerManagerInternal;
|
||||
import android.os.Process;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
import android.view.Display;
|
||||
|
||||
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;
|
||||
import com.android.server.twilight.TwilightState;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.BitSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import cyanogenmod.app.CMContextConstants;
|
||||
import cyanogenmod.hardware.ILiveDisplayService;
|
||||
import cyanogenmod.hardware.LiveDisplayConfig;
|
||||
import cyanogenmod.providers.CMSettings;
|
||||
|
||||
import static cyanogenmod.hardware.LiveDisplayManager.*;
|
||||
|
||||
/**
|
||||
* LiveDisplay is an advanced set of features for improving
|
||||
* display quality under various ambient conditions.
|
||||
*
|
||||
* The service is constructed with a set of LiveDisplayFeatures
|
||||
* which provide capabilities such as outdoor mode, night mode,
|
||||
* and calibration. It interacts with CMHardwareService to relay
|
||||
* changes down to the lower layers.
|
||||
*/
|
||||
public class LiveDisplayService extends SystemService {
|
||||
|
||||
private static final String TAG = "LiveDisplay";
|
||||
|
||||
private static final int MSG_MODE_CHANGED = 1;
|
||||
private static final int MSG_DISPLAY_CHANGED = 2;
|
||||
private static final int MSG_LOW_POWER_MODE_CHANGED = 3;
|
||||
private static final int MSG_TWILIGHT_UPDATE = 4;
|
||||
|
||||
private final Context mContext;
|
||||
private final Handler mHandler;
|
||||
private final ServiceThread mHandlerThread;
|
||||
|
||||
private DisplayManager mDisplayManager;
|
||||
private ModeObserver mModeObserver;
|
||||
private TwilightManager mTwilightManager;
|
||||
|
||||
private boolean mInitialized = false;
|
||||
private boolean mAwaitingNudge = true;
|
||||
private boolean mSunset = false;
|
||||
|
||||
private boolean mLowPowerMode;
|
||||
private int mDisplayState = -1;
|
||||
|
||||
private final List<LiveDisplayFeature> mFeatures = new ArrayList<LiveDisplayFeature>();
|
||||
|
||||
private ColorTemperatureController mCTC;
|
||||
private DisplayHardwareController mDHC;
|
||||
private OutdoorModeController mOMC;
|
||||
|
||||
private LiveDisplayConfig mConfig;
|
||||
|
||||
public LiveDisplayService(Context context) {
|
||||
super(context);
|
||||
|
||||
mContext = context;
|
||||
|
||||
// We want a slightly higher priority thread to handle these requests
|
||||
mHandlerThread = new ServiceThread(TAG,
|
||||
Process.THREAD_PRIORITY_DISPLAY + 1, false /*allowIo*/);
|
||||
mHandlerThread.start();
|
||||
mHandler = new LiveDisplayHandler(mHandlerThread.getLooper());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
if (mContext.getPackageManager().hasSystemFeature(
|
||||
CMContextConstants.Features.LIVEDISPLAY)) {
|
||||
publishBinderService(CMContextConstants.CM_LIVEDISPLAY_SERVICE, mBinder);
|
||||
} else {
|
||||
Log.wtf(TAG, "CM LiveDisplay service started by system server but feature xml not" +
|
||||
" declared. Not publishing binder service!");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBootPhase(int phase) {
|
||||
if (phase == PHASE_BOOT_COMPLETED) {
|
||||
|
||||
mAwaitingNudge = getSunsetCounter() < 1;
|
||||
|
||||
mDHC = new DisplayHardwareController(mContext, mHandler);
|
||||
mFeatures.add(mDHC);
|
||||
|
||||
mCTC = new ColorTemperatureController(mContext, mHandler, mDHC);
|
||||
mFeatures.add(mCTC);
|
||||
|
||||
mOMC = new OutdoorModeController(mContext, mHandler);
|
||||
mFeatures.add(mOMC);
|
||||
|
||||
// Call onStart of each feature and get it's capabilities
|
||||
final BitSet capabilities = new BitSet();
|
||||
for (Iterator<LiveDisplayFeature> it = mFeatures.iterator(); it.hasNext();) {
|
||||
final LiveDisplayFeature feature = it.next();
|
||||
if (feature.onStart()) {
|
||||
feature.getCapabilities(capabilities);
|
||||
} else {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
|
||||
int defaultMode = mContext.getResources().getInteger(
|
||||
org.cyanogenmod.platform.internal.R.integer.config_defaultLiveDisplayMode);
|
||||
|
||||
mConfig = new LiveDisplayConfig(capabilities, defaultMode,
|
||||
mCTC.getDefaultDayTemperature(), mCTC.getDefaultNightTemperature(),
|
||||
mOMC.getDefaultAutoOutdoorMode(), mDHC.getDefaultAutoContrast(),
|
||||
mDHC.getDefaultCABC(), mDHC.getDefaultColorEnhancement());
|
||||
|
||||
mDisplayManager = (DisplayManager) getContext().getSystemService(
|
||||
Context.DISPLAY_SERVICE);
|
||||
mDisplayManager.registerDisplayListener(mDisplayListener, null);
|
||||
|
||||
PowerManagerInternal pmi = LocalServices.getService(PowerManagerInternal.class);
|
||||
pmi.registerLowPowerModeObserver(mLowPowerModeListener);
|
||||
|
||||
mTwilightManager = LocalServices.getService(TwilightManager.class);
|
||||
mTwilightManager.registerListener(mTwilightListener, mHandler);
|
||||
updateTwilight();
|
||||
|
||||
updateDisplayState(mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY).getState());
|
||||
|
||||
mModeObserver = new ModeObserver(mHandler);
|
||||
mModeObserver.update();
|
||||
|
||||
mInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
private final IBinder mBinder = new ILiveDisplayService.Stub() {
|
||||
|
||||
@Override
|
||||
public LiveDisplayConfig getConfig() {
|
||||
return mConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMode() {
|
||||
return mModeObserver.getMode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setMode(int mode) {
|
||||
mContext.enforceCallingOrSelfPermission(
|
||||
cyanogenmod.platform.Manifest.permission.MANAGE_LIVEDISPLAY, null);
|
||||
if (mConfig.hasFeature(mode) && mode >= MODE_FIRST && mode <= MODE_LAST) {
|
||||
putInt(CMSettings.System.DISPLAY_TEMPERATURE_MODE, mode);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float[] getColorAdjustment() {
|
||||
return mDHC.getColorAdjustment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setColorAdjustment(float[] adj) {
|
||||
mContext.enforceCallingOrSelfPermission(
|
||||
cyanogenmod.platform.Manifest.permission.MANAGE_LIVEDISPLAY, null);
|
||||
return mDHC.setColorAdjustment(adj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAutoContrastEnabled() {
|
||||
return mDHC.isAutoContrastEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setAutoContrastEnabled(boolean enabled) {
|
||||
mContext.enforceCallingOrSelfPermission(
|
||||
cyanogenmod.platform.Manifest.permission.MANAGE_LIVEDISPLAY, null);
|
||||
return mDHC.setAutoContrastEnabled(enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCABCEnabled() {
|
||||
return mDHC.isCABCEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setCABCEnabled(boolean enabled) {
|
||||
mContext.enforceCallingOrSelfPermission(
|
||||
cyanogenmod.platform.Manifest.permission.MANAGE_LIVEDISPLAY, null);
|
||||
return mDHC.setCABCEnabled(enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isColorEnhancementEnabled() {
|
||||
return mDHC.isColorEnhancementEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setColorEnhancementEnabled(boolean enabled) {
|
||||
mContext.enforceCallingOrSelfPermission(
|
||||
cyanogenmod.platform.Manifest.permission.MANAGE_LIVEDISPLAY, null);
|
||||
return mDHC.setColorEnhancementEnabled(enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAutomaticOutdoorModeEnabled() {
|
||||
return mOMC.isAutomaticOutdoorModeEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setAutomaticOutdoorModeEnabled(boolean enabled) {
|
||||
mContext.enforceCallingOrSelfPermission(
|
||||
cyanogenmod.platform.Manifest.permission.MANAGE_LIVEDISPLAY, null);
|
||||
return mOMC.setAutomaticOutdoorModeEnabled(enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDayColorTemperature() {
|
||||
return mCTC.getDayColorTemperature();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setDayColorTemperature(int temperature) {
|
||||
mContext.enforceCallingOrSelfPermission(
|
||||
cyanogenmod.platform.Manifest.permission.MANAGE_LIVEDISPLAY, null);
|
||||
mCTC.setDayColorTemperature(temperature);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNightColorTemperature() {
|
||||
return mCTC.getNightColorTemperature();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setNightColorTemperature(int temperature) {
|
||||
mContext.enforceCallingOrSelfPermission(
|
||||
cyanogenmod.platform.Manifest.permission.MANAGE_LIVEDISPLAY, null);
|
||||
mCTC.setNightColorTemperature(temperature);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColorTemperature() {
|
||||
return mCTC.getColorTemperature();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
||||
pw.println();
|
||||
pw.println("LiveDisplay Service State:");
|
||||
pw.println(" mMode=" + mModeObserver.getMode());
|
||||
pw.println(" mDisplayState=" + mDisplayState);
|
||||
pw.println(" mAwaitingNudge=" + mAwaitingNudge);
|
||||
pw.println(" mConfig=" + mConfig.toString());
|
||||
|
||||
for (int i = 0; i < mFeatures.size(); i++) {
|
||||
mFeatures.get(i).dump(pw);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Listener for screen on/off events
|
||||
private final DisplayManager.DisplayListener mDisplayListener =
|
||||
new DisplayManager.DisplayListener() {
|
||||
@Override
|
||||
public void onDisplayAdded(int displayId) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisplayRemoved(int displayId) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisplayChanged(int displayId) {
|
||||
if (displayId == Display.DEFAULT_DISPLAY) {
|
||||
mHandler.obtainMessage(MSG_DISPLAY_CHANGED,
|
||||
mDisplayManager.getDisplay(displayId).getState(), 0).sendToTarget();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Display postprocessing can have power impact.
|
||||
private PowerManagerInternal.LowPowerModeListener mLowPowerModeListener =
|
||||
new PowerManagerInternal.LowPowerModeListener() {
|
||||
@Override
|
||||
public void onLowPowerModeChanged(boolean lowPowerMode) {
|
||||
if (lowPowerMode != mLowPowerMode) {
|
||||
mLowPowerMode = lowPowerMode;
|
||||
mHandler.obtainMessage(MSG_LOW_POWER_MODE_CHANGED,
|
||||
(lowPowerMode ? 1 : 0), 0).sendToTarget();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Watch for mode changes
|
||||
private final class ModeObserver extends UserContentObserver {
|
||||
|
||||
private final Uri MODE_SETTING =
|
||||
CMSettings.System.getUriFor(CMSettings.System.DISPLAY_TEMPERATURE_MODE);
|
||||
|
||||
ModeObserver(Handler handler) {
|
||||
super(handler);
|
||||
|
||||
final ContentResolver cr = mContext.getContentResolver();
|
||||
cr.registerContentObserver(MODE_SETTING, false, this, UserHandle.USER_ALL);
|
||||
|
||||
observe();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void update() {
|
||||
mHandler.obtainMessage(MSG_MODE_CHANGED, getMode(), 0).sendToTarget();
|
||||
}
|
||||
|
||||
int getMode() {
|
||||
return getInt(CMSettings.System.DISPLAY_TEMPERATURE_MODE,
|
||||
mConfig.getDefaultMode());
|
||||
}
|
||||
}
|
||||
|
||||
// Night watchman
|
||||
private final TwilightListener mTwilightListener = new TwilightListener() {
|
||||
@Override
|
||||
public void onTwilightStateChanged() {
|
||||
mHandler.obtainMessage(MSG_TWILIGHT_UPDATE,
|
||||
mTwilightManager.getCurrentState()).sendToTarget();
|
||||
}
|
||||
};
|
||||
|
||||
private int getSunsetCounter() {
|
||||
// Counter used to determine when we should tell the user about this feature.
|
||||
// If it's not used after 3 sunsets, we'll show the hint once.
|
||||
return CMSettings.System.getIntForUser(mContext.getContentResolver(),
|
||||
CMSettings.System.LIVE_DISPLAY_HINTED,
|
||||
-3,
|
||||
UserHandle.USER_CURRENT);
|
||||
}
|
||||
|
||||
|
||||
private void updateSunsetCounter(int count) {
|
||||
CMSettings.System.putIntForUser(mContext.getContentResolver(),
|
||||
CMSettings.System.LIVE_DISPLAY_HINTED,
|
||||
count,
|
||||
UserHandle.USER_CURRENT);
|
||||
mAwaitingNudge = count > 0;
|
||||
}
|
||||
|
||||
private void stopNudgingMe() {
|
||||
if (mAwaitingNudge) {
|
||||
updateSunsetCounter(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a friendly notification to the user about the potential benefits of decreasing
|
||||
* blue light at night. Do this only once if the feature has not been used after
|
||||
* three sunsets. It would be great to enable this by default, but we don't want
|
||||
* the change of screen color to be considered a "bug" by a user who doesn't
|
||||
* understand what's happening.
|
||||
*
|
||||
* @param state
|
||||
*/
|
||||
private void nudge() {
|
||||
final TwilightState twilight = mTwilightManager.getCurrentState();
|
||||
if (!mAwaitingNudge || twilight == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
int counter = getSunsetCounter();
|
||||
|
||||
// check if we should send the hint only once after sunset
|
||||
boolean transition = twilight.isNight() && !mSunset;
|
||||
mSunset = twilight.isNight();
|
||||
if (!transition) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (counter <= 0) {
|
||||
counter++;
|
||||
updateSunsetCounter(counter);
|
||||
}
|
||||
if (counter == 0) {
|
||||
//show the notification and don't come back here
|
||||
final Intent intent = new Intent(CMSettings.ACTION_LIVEDISPLAY_SETTINGS);
|
||||
PendingIntent result = PendingIntent.getActivity(
|
||||
mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
Notification.Builder builder = new Notification.Builder(mContext)
|
||||
.setContentTitle(mContext.getResources().getString(
|
||||
org.cyanogenmod.platform.internal.R.string.live_display_title))
|
||||
.setContentText(mContext.getResources().getString(
|
||||
org.cyanogenmod.platform.internal.R.string.live_display_hint))
|
||||
.setSmallIcon(org.cyanogenmod.platform.internal.R.drawable.ic_livedisplay_notif)
|
||||
.setStyle(new Notification.BigTextStyle().bigText(mContext.getResources()
|
||||
.getString(
|
||||
org.cyanogenmod.platform.internal.R.string.live_display_hint)))
|
||||
.setContentIntent(result)
|
||||
.setAutoCancel(true);
|
||||
|
||||
NotificationManager nm =
|
||||
(NotificationManager)mContext.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
nm.notifyAsUser(null, 1, builder.build(), UserHandle.CURRENT);
|
||||
|
||||
updateSunsetCounter(1);
|
||||
}
|
||||
}
|
||||
|
||||
private int getInt(String setting, int defValue) {
|
||||
return CMSettings.System.getIntForUser(mContext.getContentResolver(),
|
||||
setting, defValue, UserHandle.USER_CURRENT);
|
||||
}
|
||||
|
||||
private void putInt(String setting, int value) {
|
||||
CMSettings.System.putIntForUser(mContext.getContentResolver(),
|
||||
setting, value, UserHandle.USER_CURRENT);
|
||||
}
|
||||
|
||||
private synchronized void updateTwilight() {
|
||||
final TwilightState twilight = mTwilightManager.getCurrentState();
|
||||
for (int i = 0; i < mFeatures.size(); i++) {
|
||||
mFeatures.get(i).onTwilightUpdated(twilight);
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void updateDisplayState(int displayState) {
|
||||
if (mDisplayState != displayState) {
|
||||
mDisplayState = displayState;
|
||||
|
||||
for (int i = 0; i < mFeatures.size(); i++) {
|
||||
mFeatures.get(i).onDisplayStateChanged(displayState == Display.STATE_ON);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void updateMode(int mode) {
|
||||
for (int i = 0; i < mFeatures.size(); i++) {
|
||||
mFeatures.get(i).onModeChanged(mode);
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void updateLowPowerMode(boolean lowPowerMode) {
|
||||
if (mLowPowerMode != lowPowerMode) {
|
||||
mLowPowerMode = lowPowerMode;
|
||||
|
||||
for (int i = 0; i < mFeatures.size(); i++) {
|
||||
mFeatures.get(i).onLowPowerModeChanged(mLowPowerMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final class LiveDisplayHandler extends Handler {
|
||||
public LiveDisplayHandler(Looper looper) {
|
||||
super(looper, null, true /*async*/);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
if (!mInitialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (msg.what) {
|
||||
case MSG_DISPLAY_CHANGED:
|
||||
updateDisplayState(msg.arg1);
|
||||
break;
|
||||
case MSG_LOW_POWER_MODE_CHANGED:
|
||||
updateLowPowerMode(msg.arg1 == 1);
|
||||
break;
|
||||
case MSG_TWILIGHT_UPDATE:
|
||||
updateTwilight();
|
||||
nudge();
|
||||
break;
|
||||
case MSG_MODE_CHANGED:
|
||||
stopNudgingMe();
|
||||
updateMode(msg.arg1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,217 @@
|
|||
/*
|
||||
* 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.platform.internal.display;
|
||||
|
||||
import static cyanogenmod.hardware.LiveDisplayManager.MODE_AUTO;
|
||||
import static cyanogenmod.hardware.LiveDisplayManager.MODE_DAY;
|
||||
import static cyanogenmod.hardware.LiveDisplayManager.MODE_OUTDOOR;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
|
||||
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;
|
||||
|
||||
public class OutdoorModeController extends LiveDisplayFeature {
|
||||
|
||||
private CMHardwareManager mHardware;
|
||||
private AmbientLuxObserver mLuxObserver;
|
||||
|
||||
// hardware capabilities
|
||||
private boolean mUseOutdoorMode;
|
||||
private boolean mSelfManaged;
|
||||
|
||||
// default values
|
||||
private int mDefaultOutdoorLux;
|
||||
private boolean mDefaultAutoOutdoorMode;
|
||||
|
||||
// current values
|
||||
private boolean mAutoOutdoorMode;
|
||||
|
||||
// internal state
|
||||
private boolean mIsOutdoor;
|
||||
private boolean mIsSensorEnabled;
|
||||
|
||||
// sliding window for sensor event smoothing
|
||||
private static final int SENSOR_WINDOW_MS = 3000;
|
||||
|
||||
public OutdoorModeController(Context context, Handler handler) {
|
||||
super(context, handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onStart() {
|
||||
mHardware = CMHardwareManager.getInstance(mContext);
|
||||
if (!mHardware.isSupported(CMHardwareManager.FEATURE_SUNLIGHT_ENHANCEMENT)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mUseOutdoorMode = true;
|
||||
|
||||
mDefaultOutdoorLux = mContext.getResources().getInteger(
|
||||
org.cyanogenmod.platform.internal.R.integer.config_outdoorAmbientLux);
|
||||
mDefaultAutoOutdoorMode = mContext.getResources().getBoolean(
|
||||
org.cyanogenmod.platform.internal.R.bool.config_defaultAutoOutdoorMode);
|
||||
|
||||
mSelfManaged = mHardware.isSunlightEnhancementSelfManaged();
|
||||
if (!mSelfManaged) {
|
||||
mLuxObserver = new AmbientLuxObserver(mContext, mHandler.getLooper(),
|
||||
mDefaultOutdoorLux, SENSOR_WINDOW_MS);
|
||||
}
|
||||
|
||||
registerSettings(
|
||||
CMSettings.System.getUriFor(CMSettings.System.DISPLAY_AUTO_OUTDOOR_MODE));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
void getCapabilities(final BitSet caps) {
|
||||
if (mUseOutdoorMode) {
|
||||
caps.set(LiveDisplayManager.MODE_OUTDOOR);
|
||||
if (mSelfManaged) {
|
||||
caps.set(LiveDisplayManager.FEATURE_MANAGED_OUTDOOR_MODE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onModeChanged(int mode) {
|
||||
super.onModeChanged(mode);
|
||||
updateOutdoorMode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisplayStateChanged(boolean screenOn) {
|
||||
super.onDisplayStateChanged(screenOn);
|
||||
if (mSelfManaged) {
|
||||
return;
|
||||
}
|
||||
updateOutdoorMode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowPowerModeChanged(boolean lowPowerMode) {
|
||||
super.onLowPowerModeChanged(lowPowerMode);
|
||||
updateOutdoorMode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void onSettingsChanged(Uri uri) {
|
||||
mAutoOutdoorMode = getInt(CMSettings.System.DISPLAY_AUTO_OUTDOOR_MODE,
|
||||
(mDefaultAutoOutdoorMode ? 1 : 0)) == 1;
|
||||
updateOutdoorMode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTwilightUpdated(TwilightState twilight) {
|
||||
super.onTwilightUpdated(twilight);
|
||||
updateOutdoorMode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dump(PrintWriter pw) {
|
||||
pw.println();
|
||||
pw.println("OutdoorModeController Configuration:");
|
||||
pw.println(" mSelfManaged=" + mSelfManaged);
|
||||
if (!mSelfManaged) {
|
||||
pw.println(" mDefaultOutdoorLux=" + mDefaultOutdoorLux);
|
||||
pw.println();
|
||||
pw.println(" OutdoorModeController State:");
|
||||
pw.println(" mAutoOutdoorMode=" + mAutoOutdoorMode);
|
||||
pw.println(" mIsOutdoor=" + mIsOutdoor);
|
||||
pw.println(" mIsNight=" + isNight());
|
||||
}
|
||||
mLuxObserver.dump(pw);
|
||||
}
|
||||
|
||||
boolean setAutomaticOutdoorModeEnabled(boolean enabled) {
|
||||
if (!mUseOutdoorMode) {
|
||||
return false;
|
||||
}
|
||||
putInt(CMSettings.System.DISPLAY_AUTO_OUTDOOR_MODE, (enabled ? 1 : 0));
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean isAutomaticOutdoorModeEnabled() {
|
||||
return mUseOutdoorMode;
|
||||
}
|
||||
|
||||
boolean getDefaultAutoOutdoorMode() {
|
||||
return mDefaultAutoOutdoorMode;
|
||||
}
|
||||
|
||||
private void observeAmbientLuxLocked(boolean observe) {
|
||||
mLuxObserver.setTransitionListener(observe ? mListener : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Outdoor mode is optionally enabled when ambient lux > 10000 and it's daytime
|
||||
* Melt faces!
|
||||
*
|
||||
* TODO: Use the camera or RGB sensor to determine if it's really sunlight
|
||||
*/
|
||||
private synchronized void updateOutdoorMode() {
|
||||
/*
|
||||
* Hardware toggle:
|
||||
* Enabled if outdoor mode explictly selected
|
||||
* Enabled if outdoor lux exceeded and day mode or auto mode (if not night)
|
||||
*/
|
||||
boolean enabled = !isLowPowerMode() &&
|
||||
(getMode() == MODE_OUTDOOR ||
|
||||
(mAutoOutdoorMode && (mSelfManaged || mIsOutdoor) &&
|
||||
((getMode() == MODE_AUTO && !isNight()) || getMode() == MODE_DAY)));
|
||||
mHardware.set(CMHardwareManager.FEATURE_SUNLIGHT_ENHANCEMENT, enabled);
|
||||
|
||||
/* Sensor:
|
||||
* Enabled in day mode
|
||||
* Enabled in auto mode if it's not night
|
||||
* Disabled if outdoor mode explicitly selected
|
||||
* Disabled in low power mode
|
||||
* Disabled if screen is off
|
||||
*/
|
||||
boolean sensorEnabled = !isLowPowerMode() && isScreenOn() &&
|
||||
getMode() != MODE_OUTDOOR && mAutoOutdoorMode &&
|
||||
((getMode() == MODE_AUTO && !isNight()) || getMode() == MODE_DAY);
|
||||
if (mIsSensorEnabled != sensorEnabled) {
|
||||
mIsSensorEnabled = sensorEnabled;
|
||||
observeAmbientLuxLocked(sensorEnabled);
|
||||
}
|
||||
}
|
||||
|
||||
private final AmbientLuxObserver.TransitionListener mListener =
|
||||
new AmbientLuxObserver.TransitionListener() {
|
||||
@Override
|
||||
public void onTransition(final int state, float ambientLux) {
|
||||
final boolean outdoor = state == 1;
|
||||
synchronized (OutdoorModeController.this) {
|
||||
if (mIsOutdoor == outdoor) {
|
||||
return;
|
||||
}
|
||||
|
||||
mIsOutdoor = outdoor;
|
||||
updateOutdoorMode();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
|
@ -219,6 +219,13 @@
|
|||
android:description="@string/permdesc_weather_access_mgr"
|
||||
android:protectionLevel="normal"/>
|
||||
|
||||
<!-- Allows an application to manage LiveDisplay -->
|
||||
<permission android:name="cyanogenmod.permission.MANAGE_LIVEDISPLAY"
|
||||
android:label="@string/permlab_manageLiveDisplay"
|
||||
android:description="@string/permdesc_manageLiveDisplay"
|
||||
android:icon="@drawable/ic_launcher_cyanogenmod"
|
||||
android:protectionLevel="normal" />
|
||||
|
||||
<application android:process="system"
|
||||
android:persistent="true"
|
||||
android:hasCode="false"
|
||||
|
|
|
@ -51,10 +51,16 @@
|
|||
<integer name="config_proximityCheckTimeout">250</integer>
|
||||
<bool name="config_proximityCheckOnWakeEnabledByDefault">false</bool>
|
||||
|
||||
<!-- Default values for display color temperature -->
|
||||
<!-- Default values for LiveDisplay -->
|
||||
<integer name="config_dayColorTemperature">6500</integer>
|
||||
<integer name="config_nightColorTemperature">4500</integer>
|
||||
<integer name="config_outdoorAmbientLux">9000</integer>
|
||||
<integer name="config_defaultLiveDisplayMode">0</integer>
|
||||
|
||||
<bool name="config_defaultAutoContrast">false</bool>
|
||||
<bool name="config_defaultAutoOutdoorMode">true</bool>
|
||||
<bool name="config_defaultColorEnhancement">true</bool>
|
||||
<bool name="config_defaultCABC">true</bool>
|
||||
|
||||
<!-- Is the notification LED brightness adjustable ?
|
||||
Used to decide if the user can set LED brightness -->
|
||||
|
@ -91,5 +97,6 @@
|
|||
<item>org.cyanogenmod.platform.internal.IconCacheManagerService</item>
|
||||
<item>org.cyanogenmod.platform.internal.LiveLockScreenServiceBroker</item>
|
||||
<item>org.cyanogenmod.platform.internal.CMWeatherManagerService</item>
|
||||
<item>org.cyanogenmod.platform.internal.display.LiveDisplayService</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
|
|
|
@ -198,4 +198,9 @@
|
|||
<string name="permlab_dataUsageRead">read data usage database</string>
|
||||
<!-- DataUsageProvider read permission description -->
|
||||
<string name="permdesc_dataUsageRead">Allows an app to read content from the data usage database.</string>
|
||||
|
||||
<!-- LiveDisplay manager permission -->
|
||||
<string name="permlab_manageLiveDisplay">manage livedisplay settings</string>
|
||||
<string name="permdesc_manageLiveDisplay">Allows an app to configure advanced display settings.</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -69,6 +69,11 @@
|
|||
<java-symbol type="integer" name="config_dayColorTemperature" />
|
||||
<java-symbol type="integer" name="config_nightColorTemperature" />
|
||||
<java-symbol type="integer" name="config_outdoorAmbientLux" />
|
||||
<java-symbol type="integer" name="config_defaultLiveDisplayMode" />
|
||||
<java-symbol type="bool" name="config_defaultAutoContrast" />
|
||||
<java-symbol type="bool" name="config_defaultAutoOutdoorMode" />
|
||||
<java-symbol type="bool" name="config_defaultColorEnhancement" />
|
||||
<java-symbol type="bool" name="config_defaultCABC" />
|
||||
|
||||
<!-- Notification and battery light -->
|
||||
<java-symbol type="bool" name="config_adjustableNotificationLedBrightness" />
|
||||
|
|
|
@ -131,6 +131,13 @@ public final class CMContextConstants {
|
|||
*/
|
||||
public static final String CM_WEATHER_SERVICE = "cmweather";
|
||||
|
||||
/**
|
||||
* Manages display color adjustments
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final String CM_LIVEDISPLAY_SERVICE = "cmlivedisplay";
|
||||
|
||||
/**
|
||||
* Features supported by the CMSDK.
|
||||
*/
|
||||
|
@ -214,5 +221,13 @@ public final class CMContextConstants {
|
|||
*/
|
||||
@SdkConstant(SdkConstant.SdkConstantType.FEATURE)
|
||||
public static final String WEATHER_SERVICES = "org.cyanogenmod.weather";
|
||||
|
||||
/**
|
||||
* Feature for {@link PackageManager#getSystemAvailableFeatures} and
|
||||
* {@link PackageManager#hasSystemFeature}: The device includes the LiveDisplay service
|
||||
* utilized by the cmsdk.
|
||||
*/
|
||||
@SdkConstant(SdkConstant.SdkConstantType.FEATURE)
|
||||
public static final String LIVEDISPLAY = "org.cyanogenmod.livedisplay";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
* 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 cyanogenmod.hardware;
|
||||
|
||||
import cyanogenmod.hardware.LiveDisplayConfig;
|
||||
|
||||
/** @hide */
|
||||
interface ILiveDisplayService {
|
||||
LiveDisplayConfig getConfig();
|
||||
|
||||
int getMode();
|
||||
boolean setMode(int mode);
|
||||
|
||||
float[] getColorAdjustment();
|
||||
boolean setColorAdjustment(in float[] adj);
|
||||
|
||||
boolean isAutoContrastEnabled();
|
||||
boolean setAutoContrastEnabled(boolean enabled);
|
||||
|
||||
boolean isCABCEnabled();
|
||||
boolean setCABCEnabled(boolean enabled);
|
||||
|
||||
boolean isColorEnhancementEnabled();
|
||||
boolean setColorEnhancementEnabled(boolean enabled);
|
||||
|
||||
int getDayColorTemperature();
|
||||
boolean setDayColorTemperature(int temperature);
|
||||
|
||||
int getNightColorTemperature();
|
||||
boolean setNightColorTemperature(int temperature);
|
||||
|
||||
int getColorTemperature();
|
||||
|
||||
boolean isAutomaticOutdoorModeEnabled();
|
||||
boolean setAutomaticOutdoorModeEnabled(boolean enabled);
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* 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 cyanogenmod.hardware;
|
||||
|
||||
parcelable LiveDisplayConfig;
|
|
@ -0,0 +1,244 @@
|
|||
/*
|
||||
* 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 cyanogenmod.hardware;
|
||||
|
||||
import static cyanogenmod.hardware.LiveDisplayManager.FEATURE_FIRST;
|
||||
import static cyanogenmod.hardware.LiveDisplayManager.FEATURE_LAST;
|
||||
import static cyanogenmod.hardware.LiveDisplayManager.MODE_FIRST;
|
||||
import static cyanogenmod.hardware.LiveDisplayManager.MODE_LAST;
|
||||
import static cyanogenmod.hardware.LiveDisplayManager.MODE_OFF;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.util.BitSet;
|
||||
|
||||
import cyanogenmod.os.Build;
|
||||
import cyanogenmod.os.Concierge;
|
||||
import cyanogenmod.os.Concierge.ParcelInfo;
|
||||
|
||||
/**
|
||||
* Holder class for LiveDisplay static configuration.
|
||||
*
|
||||
* This class holds various defaults and hardware capabilities
|
||||
* which are involved with LiveDisplay.
|
||||
*/
|
||||
public class LiveDisplayConfig implements Parcelable {
|
||||
|
||||
private final BitSet mCapabilities;
|
||||
private final int mDefaultDayTemperature;
|
||||
private final int mDefaultNightTemperature;
|
||||
private final int mDefaultMode;
|
||||
|
||||
private final boolean mDefaultAutoContrast;
|
||||
private final boolean mDefaultAutoOutdoorMode;
|
||||
private final boolean mDefaultCABC;
|
||||
private final boolean mDefaultColorEnhancement;
|
||||
|
||||
public LiveDisplayConfig(BitSet capabilities, int defaultMode,
|
||||
int defaultDayTemperature, int defaultNightTemperature,
|
||||
boolean defaultAutoOutdoorMode, boolean defaultAutoContrast,
|
||||
boolean defaultCABC, boolean defaultColorEnhancement) {
|
||||
super();
|
||||
mCapabilities = (BitSet) capabilities.clone();
|
||||
mDefaultMode = defaultMode;
|
||||
mDefaultDayTemperature = defaultDayTemperature;
|
||||
mDefaultNightTemperature = defaultNightTemperature;
|
||||
mDefaultAutoContrast = defaultAutoContrast;
|
||||
mDefaultAutoOutdoorMode = defaultAutoOutdoorMode;
|
||||
mDefaultCABC = defaultCABC;
|
||||
mDefaultColorEnhancement = defaultColorEnhancement;
|
||||
}
|
||||
|
||||
private LiveDisplayConfig(Parcel parcel) {
|
||||
// Read parcelable version via the Concierge
|
||||
ParcelInfo parcelInfo = Concierge.receiveParcel(parcel);
|
||||
int parcelableVersion = parcelInfo.getParcelVersion();
|
||||
|
||||
// temp vars
|
||||
long capabilities = 0;
|
||||
int defaultMode = 0;
|
||||
int defaultDayTemperature = -1;
|
||||
int defaultNightTemperature = -1;
|
||||
boolean defaultAutoContrast = false;
|
||||
boolean defaultAutoOutdoorMode = false;
|
||||
boolean defaultCABC = false;
|
||||
boolean defaultColorEnhancement = false;
|
||||
|
||||
if (parcelableVersion >= Build.CM_VERSION_CODES.FIG) {
|
||||
capabilities = parcel.readLong();
|
||||
defaultMode = parcel.readInt();
|
||||
defaultDayTemperature = parcel.readInt();
|
||||
defaultNightTemperature = parcel.readInt();
|
||||
defaultAutoContrast = parcel.readInt() == 1;
|
||||
defaultAutoOutdoorMode = parcel.readInt() == 1;
|
||||
defaultCABC = parcel.readInt() == 1;
|
||||
defaultColorEnhancement = parcel.readInt() == 1;
|
||||
}
|
||||
|
||||
// set temps
|
||||
mCapabilities = BitSet.valueOf(new long[] { capabilities });
|
||||
mDefaultMode = defaultMode;
|
||||
mDefaultDayTemperature = defaultDayTemperature;
|
||||
mDefaultNightTemperature = defaultNightTemperature;
|
||||
mDefaultAutoContrast = defaultAutoContrast;
|
||||
mDefaultAutoOutdoorMode = defaultAutoOutdoorMode;
|
||||
mDefaultCABC = defaultCABC;
|
||||
mDefaultColorEnhancement = defaultColorEnhancement;
|
||||
|
||||
// Complete parcel info for the concierge
|
||||
parcelInfo.complete();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("capabilities=").append(mCapabilities.toString());
|
||||
sb.append(" defaultMode=").append(mDefaultMode);
|
||||
sb.append(" defaultDayTemperature=").append(mDefaultDayTemperature);
|
||||
sb.append(" defaultNightTemperature=").append(mDefaultNightTemperature);
|
||||
sb.append(" defaultAutoOutdoorMode=").append(mDefaultAutoOutdoorMode);
|
||||
sb.append(" defaultAutoContrast=").append(mDefaultAutoContrast);
|
||||
sb.append(" defaultCABC=").append(mDefaultCABC);
|
||||
sb.append(" defaultColorEnhancement=").append(mDefaultColorEnhancement);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
// Tell the concierge to prepare the parcel
|
||||
ParcelInfo parcelInfo = Concierge.prepareParcel(out);
|
||||
|
||||
// ==== FIG =====
|
||||
out.writeLong(mCapabilities.toLongArray()[0]);
|
||||
out.writeInt(mDefaultMode);
|
||||
out.writeInt(mDefaultDayTemperature);
|
||||
out.writeInt(mDefaultNightTemperature);
|
||||
out.writeInt(mDefaultAutoContrast ? 1 : 0);
|
||||
out.writeInt(mDefaultAutoOutdoorMode ? 1 : 0);
|
||||
out.writeInt(mDefaultCABC ? 1 : 0);
|
||||
out.writeInt(mDefaultColorEnhancement ? 1 : 0);
|
||||
|
||||
// Complete the parcel info for the concierge
|
||||
parcelInfo.complete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a particular feature or mode is supported by the system.
|
||||
*
|
||||
* @param feature
|
||||
* @return true if capable
|
||||
*/
|
||||
public boolean hasFeature(int feature) {
|
||||
return ((feature >= MODE_FIRST && feature <= MODE_LAST) ||
|
||||
(feature >= FEATURE_FIRST && feature <= FEATURE_LAST)) &&
|
||||
(feature == MODE_OFF || mCapabilities.get(feature));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if LiveDisplay is available for use on this device.
|
||||
*
|
||||
* @return true if any feature is enabled
|
||||
*/
|
||||
public boolean isAvailable() {
|
||||
return !mCapabilities.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the default color temperature to use in the daytime. This is typically
|
||||
* set to 6500K, however this may not be entirely accurate. Use this value for
|
||||
* resetting controls to the default.
|
||||
*
|
||||
* @return the default day temperature in K
|
||||
*/
|
||||
public int getDefaultDayTemperature() {
|
||||
return mDefaultDayTemperature;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the default color temperature to use at night. This is typically set
|
||||
* to 4500K, but this may not be entirely accurate. Use this value for resetting
|
||||
* controls to defaults.
|
||||
*
|
||||
* @return the default night color temperature
|
||||
*/
|
||||
public int getDefaultNightTemperature() {
|
||||
return mDefaultNightTemperature;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default adaptive mode.
|
||||
*
|
||||
* @return the default mode
|
||||
*/
|
||||
public int getDefaultMode() {
|
||||
return mDefaultMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default value for auto contrast
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
public boolean getDefaultAutoContrast() {
|
||||
return mDefaultAutoContrast;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default value for automatic outdoor mode
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
public boolean getDefaultAutoOutdoorMode() {
|
||||
return mDefaultAutoOutdoorMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default value for CABC
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
public boolean getDefaultCABC() {
|
||||
return mDefaultCABC;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default value for color enhancement
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
public boolean getDefaultColorEnhancement() {
|
||||
return mDefaultColorEnhancement;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public static final Parcelable.Creator<LiveDisplayConfig> CREATOR =
|
||||
new Parcelable.Creator<LiveDisplayConfig>() {
|
||||
public LiveDisplayConfig createFromParcel(Parcel in) {
|
||||
return new LiveDisplayConfig(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LiveDisplayConfig[] newArray(int size) {
|
||||
return new LiveDisplayConfig[size];
|
||||
}
|
||||
};
|
||||
}
|
|
@ -0,0 +1,415 @@
|
|||
/*
|
||||
* 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 cyanogenmod.hardware;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.util.Log;
|
||||
|
||||
import cyanogenmod.app.CMContextConstants;
|
||||
|
||||
/**
|
||||
* LiveDisplay is an advanced set of features for improving
|
||||
* display quality under various ambient conditions.
|
||||
*
|
||||
* The backend service is constructed with a set of LiveDisplayFeatures
|
||||
* which provide capabilities such as outdoor mode, night mode,
|
||||
* and calibration. It interacts with CMHardwareService to relay
|
||||
* changes down to the lower layers.
|
||||
*
|
||||
* Multiple adaptive modes are supported, and various hardware
|
||||
* features such as CABC, ACO and color enhancement are also
|
||||
* managed by LiveDisplay.
|
||||
*/
|
||||
public class LiveDisplayManager {
|
||||
|
||||
/**
|
||||
* Disable all LiveDisplay adaptive features
|
||||
*/
|
||||
public static final int MODE_OFF = 0;
|
||||
|
||||
/**
|
||||
* Change color temperature to night mode
|
||||
*/
|
||||
public static final int MODE_NIGHT = 1;
|
||||
|
||||
/**
|
||||
* Enable automatic detection of appropriate mode
|
||||
*/
|
||||
public static final int MODE_AUTO = 2;
|
||||
|
||||
/**
|
||||
* Increase brightness/contrast/saturation for sunlight
|
||||
*/
|
||||
public static final int MODE_OUTDOOR = 3;
|
||||
|
||||
/**
|
||||
* Change color temperature to day mode, and allow
|
||||
* detection of outdoor conditions
|
||||
*/
|
||||
public static final int MODE_DAY = 4;
|
||||
|
||||
/** @hide */
|
||||
public static final int MODE_FIRST = MODE_OFF;
|
||||
/** @hide */
|
||||
public static final int MODE_LAST = MODE_DAY;
|
||||
|
||||
/**
|
||||
* Content adaptive backlight control, adjust images to
|
||||
* increase brightness in order to reduce backlight level
|
||||
*/
|
||||
public static final int FEATURE_CABC = 10;
|
||||
|
||||
/**
|
||||
* Adjust images to increase contrast
|
||||
*/
|
||||
public static final int FEATURE_AUTO_CONTRAST = 11;
|
||||
|
||||
/**
|
||||
* Adjust image to improve saturation and color
|
||||
*/
|
||||
public static final int FEATURE_COLOR_ENHANCEMENT = 12;
|
||||
|
||||
/**
|
||||
* Capable of adjusting RGB levels
|
||||
*/
|
||||
public static final int FEATURE_COLOR_ADJUSTMENT = 13;
|
||||
|
||||
/**
|
||||
* System supports outdoor mode, but environmental sensing
|
||||
* is done by an external application.
|
||||
*/
|
||||
public static final int FEATURE_MANAGED_OUTDOOR_MODE = 14;
|
||||
|
||||
/**
|
||||
* System supports multiple display calibrations
|
||||
* for different viewing intents.
|
||||
*/
|
||||
public static final int FEATURE_DISPLAY_MODES = 15;
|
||||
|
||||
/** @hide */
|
||||
public static final int FEATURE_FIRST = FEATURE_CABC;
|
||||
/** @hide */
|
||||
public static final int FEATURE_LAST = FEATURE_DISPLAY_MODES;
|
||||
|
||||
private static final String TAG = "LiveDisplay";
|
||||
|
||||
private final Context mContext;
|
||||
private final LiveDisplayConfig mConfig;
|
||||
|
||||
private static LiveDisplayManager sInstance;
|
||||
private static ILiveDisplayService sService;
|
||||
|
||||
/**
|
||||
* @hide to prevent subclassing from outside of the framework
|
||||
*/
|
||||
private LiveDisplayManager(Context context) {
|
||||
Context appContext = context.getApplicationContext();
|
||||
if (appContext != null) {
|
||||
mContext = appContext;
|
||||
} else {
|
||||
mContext = context;
|
||||
}
|
||||
sService = getService();
|
||||
|
||||
if (context.getPackageManager().hasSystemFeature(
|
||||
CMContextConstants.Features.LIVEDISPLAY) && !checkService()) {
|
||||
throw new RuntimeException("Unable to get LiveDisplayService. The service either" +
|
||||
" crashed, was not started, or the interface has been called to early in" +
|
||||
" SystemServer init");
|
||||
}
|
||||
|
||||
try {
|
||||
mConfig = sService.getConfig();
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException("Unable to fetch LiveDisplay configuration!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get or create an instance of the {@link cyanogenmod.hardware.LiveDisplayManager}
|
||||
* @param context
|
||||
* @return {@link LiveDisplayManager}
|
||||
*/
|
||||
public synchronized static LiveDisplayManager getInstance(Context context) {
|
||||
if (sInstance == null) {
|
||||
sInstance = new LiveDisplayManager(context);
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public static ILiveDisplayService getService() {
|
||||
if (sService != null) {
|
||||
return sService;
|
||||
}
|
||||
IBinder b = ServiceManager.getService(CMContextConstants.CM_LIVEDISPLAY_SERVICE);
|
||||
if (b != null) {
|
||||
sService = ILiveDisplayService.Stub.asInterface(b);
|
||||
return sService;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if service is valid
|
||||
*/
|
||||
private boolean checkService() {
|
||||
if (sService == null) {
|
||||
Log.w(TAG, "not connected to CMHardwareManagerService");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the static configuration and settings.
|
||||
*
|
||||
* @return the configuration
|
||||
*/
|
||||
public LiveDisplayConfig getConfig() {
|
||||
return mConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current adaptive mode.
|
||||
*
|
||||
* @return id of the selected mode
|
||||
*/
|
||||
public int getMode() {
|
||||
try {
|
||||
return checkService() ? sService.getMode() : MODE_OFF;
|
||||
} catch (RemoteException e) {
|
||||
return MODE_OFF;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Selects a new adaptive mode.
|
||||
*
|
||||
* @param mode
|
||||
* @return true if the mode was selected
|
||||
*/
|
||||
public boolean setMode(int mode) {
|
||||
try {
|
||||
return checkService() && sService.setMode(mode);
|
||||
} catch (RemoteException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the auto contrast optimization feature is enabled.
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
public boolean isAutoContrastEnabled() {
|
||||
try {
|
||||
return checkService() && sService.isAutoContrastEnabled();
|
||||
} catch (RemoteException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the state of auto contrast optimization
|
||||
*
|
||||
* @param enabled
|
||||
* @return true if state was changed
|
||||
*/
|
||||
public boolean setAutoContrastEnabled(boolean enabled) {
|
||||
try {
|
||||
return checkService() && sService.setAutoContrastEnabled(enabled);
|
||||
} catch (RemoteException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the CABC feature is enabled
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
public boolean isCABCEnabled() {
|
||||
try {
|
||||
return checkService() && sService.isCABCEnabled();
|
||||
} catch (RemoteException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the state of CABC
|
||||
*
|
||||
* @param enabled
|
||||
* @return true if state was changed
|
||||
*/
|
||||
public boolean setCABCEnabled(boolean enabled) {
|
||||
try {
|
||||
return checkService() && sService.setCABCEnabled(enabled);
|
||||
} catch (RemoteException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the color enhancement feature is enabled
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
public boolean isColorEnhancementEnabled() {
|
||||
try {
|
||||
return checkService() && sService.isColorEnhancementEnabled();
|
||||
} catch (RemoteException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the state of color enhancement
|
||||
*
|
||||
* @param enabled
|
||||
* @return true if state was changed
|
||||
*/
|
||||
public boolean setColorEnhancementEnabled(boolean enabled) {
|
||||
try {
|
||||
return checkService() && sService.setColorEnhancementEnabled(enabled);
|
||||
} catch (RemoteException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the user-specified color temperature to use in the daytime.
|
||||
*
|
||||
* @return the day color temperature
|
||||
*/
|
||||
public int getDayColorTemperature() {
|
||||
try {
|
||||
return checkService() ? sService.getDayColorTemperature() : -1;
|
||||
} catch (RemoteException e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the color temperature to use in the daytime.
|
||||
*
|
||||
* @param temperature
|
||||
* @return true if state was changed
|
||||
*/
|
||||
public boolean setDayColorTemperature(int temperature) {
|
||||
try {
|
||||
return checkService() && sService.setDayColorTemperature(temperature);
|
||||
} catch (RemoteException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the user-specified color temperature to use at night.
|
||||
*
|
||||
* @return the night color temperature
|
||||
*/
|
||||
public int getNightColorTemperature() {
|
||||
try {
|
||||
return checkService() ? sService.getNightColorTemperature() : -1;
|
||||
} catch (RemoteException e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the color temperature to use at night.
|
||||
*
|
||||
* @param temperature
|
||||
* @return true if state was changed
|
||||
*/
|
||||
public boolean setNightColorTemperature(int temperature) {
|
||||
try {
|
||||
return checkService() && sService.setNightColorTemperature(temperature);
|
||||
} catch (RemoteException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if outdoor mode should be enabled automatically when under extremely high
|
||||
* ambient light. This is typically around 12000 lux.
|
||||
*
|
||||
* @return if outdoor conditions should be detected
|
||||
*/
|
||||
public boolean isAutomaticOutdoorModeEnabled() {
|
||||
try {
|
||||
return checkService() && sService.isAutomaticOutdoorModeEnabled();
|
||||
} catch (RemoteException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables automatic detection of outdoor conditions. Outdoor mode is triggered
|
||||
* when high ambient light is detected and it's not night.
|
||||
*
|
||||
* @param enabled
|
||||
* @return true if state was changed
|
||||
*/
|
||||
public boolean setAutomaticOutdoorModeEnabled(boolean enabled) {
|
||||
try {
|
||||
return checkService() && sService.setAutomaticOutdoorModeEnabled(enabled);
|
||||
} catch (RemoteException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current RGB triplet which is applied as a color adjustment.
|
||||
* The values are floats between 0 and 1. A setting of { 1.0, 1.0, 1.0 }
|
||||
* means that no adjustment is made.
|
||||
*
|
||||
* @return array of { R, G, B } offsets
|
||||
*/
|
||||
public float[] getColorAdjustment() {
|
||||
try {
|
||||
if (checkService()) {
|
||||
return sService.getColorAdjustment();
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
return new float[] { 1.0f, 1.0f, 1.0f };
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the color adjustment to use. This can be set by the user to calibrate
|
||||
* their screen. This should be sent in the format { R, G, B } as floats from
|
||||
* 0 to 1. A setting of { 1.0, 1.0, 1.0 } means that no adjustment is made.
|
||||
* The hardware implementation may refuse certain values which make the display
|
||||
* unreadable, such as { 0, 0, 0 }. This calibration will be combined with other
|
||||
* internal adjustments, such as night mode, if necessary.
|
||||
*
|
||||
* @param array of { R, G, B } offsets
|
||||
* @return true if state was changed
|
||||
*/
|
||||
public boolean setColorAdjustment(float[] adj) {
|
||||
try {
|
||||
return checkService() && sService.setColorAdjustment(adj);
|
||||
} catch (RemoteException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -68,6 +68,16 @@ public final class CMSettings {
|
|||
*/
|
||||
public static final String ACTION_DATA_USAGE = "cyanogenmod.settings.ACTION_DATA_USAGE";
|
||||
|
||||
/**
|
||||
* Activity Action: Show LiveDisplay settings
|
||||
* <p>
|
||||
* Input: Nothing.
|
||||
* <p>
|
||||
* Output: Nothing.
|
||||
*/
|
||||
public static final String ACTION_LIVEDISPLAY_SETTINGS =
|
||||
"cyanogenmod.settings.LIVEDISPLAY_SETTINGS";
|
||||
|
||||
// region Call Methods
|
||||
|
||||
/**
|
||||
|
@ -1318,10 +1328,15 @@ public final class CMSettings {
|
|||
* Use display power saving features such as CABC or CABL
|
||||
* 0 = 0ff, 1 = on
|
||||
*/
|
||||
public static final String DISPLAY_LOW_POWER = "display_low_power";
|
||||
public static final String DISPLAY_CABC = "display_low_power";
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
public static final String DISPLAY_LOW_POWER = DISPLAY_CABC;
|
||||
|
||||
/** @hide */
|
||||
public static final Validator DISPLAY_LOW_POWER_VALIDATOR =
|
||||
public static final Validator DISPLAY_CABC_VALIDATOR =
|
||||
sBooleanValidator;
|
||||
|
||||
/**
|
||||
|
@ -1334,6 +1349,16 @@ public final class CMSettings {
|
|||
public static final Validator DISPLAY_COLOR_ENHANCE_VALIDATOR =
|
||||
sBooleanValidator;
|
||||
|
||||
/**
|
||||
* Use auto contrast optimization feature of display
|
||||
* 0 = 0ff, 1 = on
|
||||
*/
|
||||
public static final String DISPLAY_AUTO_CONTRAST = "display_auto_contrast";
|
||||
|
||||
/** @hide */
|
||||
public static final Validator DISPLAY_AUTO_CONTRAST_VALIDATOR =
|
||||
sBooleanValidator;
|
||||
|
||||
/**
|
||||
* Manual display color adjustments (RGB values as floats, separated by spaces)
|
||||
*/
|
||||
|
@ -1827,7 +1852,7 @@ public final class CMSettings {
|
|||
CMSettings.System.DISPLAY_TEMPERATURE_NIGHT,
|
||||
CMSettings.System.DISPLAY_TEMPERATURE_MODE,
|
||||
CMSettings.System.DISPLAY_AUTO_OUTDOOR_MODE,
|
||||
CMSettings.System.DISPLAY_LOW_POWER,
|
||||
CMSettings.System.DISPLAY_CABC,
|
||||
CMSettings.System.DISPLAY_COLOR_ENHANCE,
|
||||
CMSettings.System.DISPLAY_COLOR_ADJUSTMENT,
|
||||
CMSettings.System.LIVE_DISPLAY_HINTED,
|
||||
|
@ -1965,8 +1990,9 @@ public final class CMSettings {
|
|||
VALIDATORS.put(DISPLAY_TEMPERATURE_DAY, DISPLAY_TEMPERATURE_DAY_VALIDATOR);
|
||||
VALIDATORS.put(DISPLAY_TEMPERATURE_NIGHT, DISPLAY_TEMPERATURE_NIGHT_VALIDATOR);
|
||||
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_LOW_POWER, DISPLAY_LOW_POWER_VALIDATOR);
|
||||
VALIDATORS.put(DISPLAY_CABC, DISPLAY_CABC_VALIDATOR);
|
||||
VALIDATORS.put(DISPLAY_COLOR_ENHANCE, DISPLAY_COLOR_ENHANCE_VALIDATOR);
|
||||
VALIDATORS.put(DISPLAY_COLOR_ADJUSTMENT, DISPLAY_COLOR_ADJUSTMENT_VALIDATOR);
|
||||
VALIDATORS.put(LIVE_DISPLAY_HINTED, LIVE_DISPLAY_HINTED_VALIDATOR);
|
||||
|
|
|
@ -529,6 +529,53 @@ package cyanogenmod.hardware {
|
|||
method public boolean onTransact(int, android.os.Parcel, android.os.Parcel, int) throws android.os.RemoteException;
|
||||
}
|
||||
|
||||
public class LiveDisplayConfig implements android.os.Parcelable {
|
||||
ctor public LiveDisplayConfig(java.util.BitSet, int, int, int, boolean, boolean, boolean, boolean);
|
||||
method public int describeContents();
|
||||
method public boolean getDefaultAutoContrast();
|
||||
method public boolean getDefaultAutoOutdoorMode();
|
||||
method public boolean getDefaultCABC();
|
||||
method public boolean getDefaultColorEnhancement();
|
||||
method public int getDefaultDayTemperature();
|
||||
method public int getDefaultMode();
|
||||
method public int getDefaultNightTemperature();
|
||||
method public boolean hasFeature(int);
|
||||
method public boolean isAvailable();
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
}
|
||||
|
||||
public class LiveDisplayManager {
|
||||
method public float[] getColorAdjustment();
|
||||
method public cyanogenmod.hardware.LiveDisplayConfig getConfig();
|
||||
method public int getDayColorTemperature();
|
||||
method public static synchronized cyanogenmod.hardware.LiveDisplayManager getInstance(android.content.Context);
|
||||
method public int getMode();
|
||||
method public int getNightColorTemperature();
|
||||
method public boolean isAutoContrastEnabled();
|
||||
method public boolean isAutomaticOutdoorModeEnabled();
|
||||
method public boolean isCABCEnabled();
|
||||
method public boolean isColorEnhancementEnabled();
|
||||
method public boolean setAutoContrastEnabled(boolean);
|
||||
method public boolean setAutomaticOutdoorModeEnabled(boolean);
|
||||
method public boolean setCABCEnabled(boolean);
|
||||
method public boolean setColorAdjustment(float[]);
|
||||
method public boolean setColorEnhancementEnabled(boolean);
|
||||
method public boolean setDayColorTemperature(int);
|
||||
method public boolean setMode(int);
|
||||
method public boolean setNightColorTemperature(int);
|
||||
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_ENHANCEMENT = 12; // 0xc
|
||||
field public static final int FEATURE_DISPLAY_MODES = 15; // 0xf
|
||||
field public static final int FEATURE_MANAGED_OUTDOOR_MODE = 14; // 0xe
|
||||
field public static final int MODE_AUTO = 2; // 0x2
|
||||
field public static final int MODE_DAY = 4; // 0x4
|
||||
field public static final int MODE_NIGHT = 1; // 0x1
|
||||
field public static final int MODE_OFF = 0; // 0x0
|
||||
field public static final int MODE_OUTDOOR = 3; // 0x3
|
||||
}
|
||||
|
||||
public abstract class ThermalListenerCallback extends cyanogenmod.hardware.IThermalListenerCallback.Stub {
|
||||
ctor public ThermalListenerCallback();
|
||||
}
|
||||
|
@ -613,6 +660,7 @@ package cyanogenmod.platform {
|
|||
field public static final java.lang.String HARDWARE_ABSTRACTION_ACCESS = "cyanogenmod.permission.HARDWARE_ABSTRACTION_ACCESS";
|
||||
field public static final java.lang.String LIVE_LOCK_SCREEN_MANAGER_ACCESS = "cyanogenmod.permission.LIVE_LOCK_SCREEN_MANAGER_ACCESS";
|
||||
field public static final java.lang.String MANAGE_ALARMS = "cyanogenmod.permission.MANAGE_ALARMS";
|
||||
field public static final java.lang.String MANAGE_LIVEDISPLAY = "cyanogenmod.permission.MANAGE_LIVEDISPLAY";
|
||||
field public static final java.lang.String MANAGE_PERSISTENT_STORAGE = "cyanogenmod.permission.MANAGE_PERSISTENT_STORAGE";
|
||||
field public static final java.lang.String MODIFY_MSIM_PHONE_STATE = "cyanogenmod.permission.MODIFY_MSIM_PHONE_STATE";
|
||||
field public static final java.lang.String MODIFY_NETWORK_SETTINGS = "cyanogenmod.permission.MODIFY_NETWORK_SETTINGS";
|
||||
|
@ -795,6 +843,7 @@ package cyanogenmod.providers {
|
|||
public final class CMSettings {
|
||||
ctor public CMSettings();
|
||||
field public static final java.lang.String ACTION_DATA_USAGE = "cyanogenmod.settings.ACTION_DATA_USAGE";
|
||||
field public static final java.lang.String ACTION_LIVEDISPLAY_SETTINGS = "cyanogenmod.settings.LIVEDISPLAY_SETTINGS";
|
||||
field public static final java.lang.String AUTHORITY = "cmsettings";
|
||||
}
|
||||
|
||||
|
@ -868,10 +917,12 @@ package cyanogenmod.providers {
|
|||
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_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";
|
||||
field public static final java.lang.String DISPLAY_COLOR_ADJUSTMENT = "display_color_adjustment";
|
||||
field public static final java.lang.String DISPLAY_COLOR_ENHANCE = "display_color_enhance";
|
||||
field public static final java.lang.String DISPLAY_LOW_POWER = "display_low_power";
|
||||
field public static final deprecated java.lang.String DISPLAY_LOW_POWER = "display_low_power";
|
||||
field public static final java.lang.String DISPLAY_TEMPERATURE_DAY = "display_temperature_day";
|
||||
field public static final java.lang.String DISPLAY_TEMPERATURE_MODE = "display_temperature_mode";
|
||||
field public static final java.lang.String DISPLAY_TEMPERATURE_NIGHT = "display_temperature_night";
|
||||
|
|
Loading…
Reference in New Issue