diff options
author | Steve Kondik <steve@cyngn.com> | 2016-07-20 11:20:02 -0700 |
---|---|---|
committer | Steve Kondik <steve@cyngn.com> | 2016-08-08 12:41:27 -0700 |
commit | 87590f0b1ea85f6ec6364ed996c95f69bb3f28c2 (patch) | |
tree | 66dadbed3c2ecdb864b50566333edef0f6a96453 /cm | |
parent | 3e7dac120a1468ade555975e6267d3db7c1b231c (diff) | |
download | vendor_cmsdk-87590f0b1ea85f6ec6364ed996c95f69bb3f28c2.zip vendor_cmsdk-87590f0b1ea85f6ec6364ed996c95f69bb3f28c2.tar.gz vendor_cmsdk-87590f0b1ea85f6ec6364ed996c95f69bb3f28c2.tar.bz2 |
cmsdk/livedisplay: Add support for picture adjustment
* Allows adjustment of hue, saturation, intensity, and contrast.
Change-Id: Icf8ff6200a07b68e09dcd7f140a82e57b53944f7
Diffstat (limited to 'cm')
3 files changed, 332 insertions, 1 deletions
diff --git a/cm/lib/main/java/org/cyanogenmod/platform/internal/CMHardwareService.java b/cm/lib/main/java/org/cyanogenmod/platform/internal/CMHardwareService.java index 9fa1269..bd9071b 100644 --- a/cm/lib/main/java/org/cyanogenmod/platform/internal/CMHardwareService.java +++ b/cm/lib/main/java/org/cyanogenmod/platform/internal/CMHardwareService.java @@ -22,6 +22,7 @@ import android.os.RemoteCallbackList; import android.os.RemoteException; import android.util.ArrayMap; import android.util.Log; +import android.util.Range; import com.android.server.SystemService; @@ -31,10 +32,12 @@ import cyanogenmod.hardware.CMHardwareManager; import cyanogenmod.hardware.DisplayMode; import cyanogenmod.hardware.IThermalListenerCallback; import cyanogenmod.hardware.ThermalListenerCallback; +import cyanogenmod.hardware.HSIC; import java.io.File; import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import org.cyanogenmod.hardware.AdaptiveBacklight; import org.cyanogenmod.hardware.AutoContrast; @@ -47,6 +50,7 @@ import org.cyanogenmod.hardware.HighTouchSensitivity; import org.cyanogenmod.hardware.KeyDisabler; import org.cyanogenmod.hardware.LongTermOrbits; import org.cyanogenmod.hardware.PersistentStorage; +import org.cyanogenmod.hardware.PictureAdjustment; import org.cyanogenmod.hardware.SerialNumber; import org.cyanogenmod.hardware.SunlightEnhancement; import org.cyanogenmod.hardware.TapToWake; @@ -108,6 +112,11 @@ public class CMHardwareService extends CMSystemService implements ThermalUpdateC public int getColorBalanceMax(); public int getColorBalance(); public boolean setColorBalance(int value); + + public HSIC getPictureAdjustment(); + public HSIC getDefaultPictureAdjustment(); + public boolean setPictureAdjustment(HSIC hsic); + public List<Range<Float>> getPictureAdjustmentRanges(); } private class LegacyCMHardware implements CMHardwareInterface { @@ -151,6 +160,8 @@ public class CMHardwareService extends CMSystemService implements ThermalUpdateC mSupportedFeatures |= CMHardwareManager.FEATURE_UNIQUE_DEVICE_ID; if (ColorBalance.isSupported()) mSupportedFeatures |= CMHardwareManager.FEATURE_COLOR_BALANCE; + if (PictureAdjustment.isSupported()) + mSupportedFeatures |= CMHardwareManager.FEATURE_PICTURE_ADJUSTMENT; } public int getSupportedFeatures() { @@ -364,6 +375,21 @@ public class CMHardwareService extends CMSystemService implements ThermalUpdateC public boolean setColorBalance(int value) { return ColorBalance.setValue(value); } + + public HSIC getPictureAdjustment() { return PictureAdjustment.getHSIC(); } + + public HSIC getDefaultPictureAdjustment() { return PictureAdjustment.getDefaultHSIC(); } + + public boolean setPictureAdjustment(HSIC hsic) { return PictureAdjustment.setHSIC(hsic); } + + public List<Range<Float>> getPictureAdjustmentRanges() { + return Arrays.asList( + PictureAdjustment.getHueRange(), + PictureAdjustment.getSaturationRange(), + PictureAdjustment.getIntensityRange(), + PictureAdjustment.getContrastRange(), + PictureAdjustment.getSaturationThresholdRange()); + } } private CMHardwareInterface getImpl(Context context) { @@ -794,5 +820,51 @@ public class CMHardwareService extends CMSystemService implements ThermalUpdateC } return false; } + + @Override + public HSIC getPictureAdjustment() { + mContext.enforceCallingOrSelfPermission( + cyanogenmod.platform.Manifest.permission.HARDWARE_ABSTRACTION_ACCESS, null); + if (isSupported(CMHardwareManager.FEATURE_PICTURE_ADJUSTMENT)) { + return mCmHwImpl.getPictureAdjustment(); + } + return new HSIC(0.0f, 0.0f, 0.0f, 0.0f, 0.0f); + } + + @Override + public HSIC getDefaultPictureAdjustment() { + mContext.enforceCallingOrSelfPermission( + cyanogenmod.platform.Manifest.permission.HARDWARE_ABSTRACTION_ACCESS, null); + if (isSupported(CMHardwareManager.FEATURE_PICTURE_ADJUSTMENT)) { + return mCmHwImpl.getDefaultPictureAdjustment(); + } + return new HSIC(0.0f, 0.0f, 0.0f, 0.0f, 0.0f); + } + + @Override + public boolean setPictureAdjustment(HSIC hsic) { + mContext.enforceCallingOrSelfPermission( + cyanogenmod.platform.Manifest.permission.HARDWARE_ABSTRACTION_ACCESS, null); + if (isSupported(CMHardwareManager.FEATURE_PICTURE_ADJUSTMENT) && hsic != null) { + return mCmHwImpl.setPictureAdjustment(hsic); + } + return false; + } + + @Override + public float[] getPictureAdjustmentRanges() { + mContext.enforceCallingOrSelfPermission( + cyanogenmod.platform.Manifest.permission.HARDWARE_ABSTRACTION_ACCESS, null); + if (isSupported(CMHardwareManager.FEATURE_COLOR_BALANCE)) { + final List<Range<Float>> r = mCmHwImpl.getPictureAdjustmentRanges(); + return new float[] { + r.get(0).getLower(), r.get(0).getUpper(), + r.get(1).getLower(), r.get(1).getUpper(), + r.get(2).getLower(), r.get(2).getUpper(), + r.get(3).getLower(), r.get(3).getUpper(), + r.get(4).getUpper(), r.get(4).getUpper() }; + } + return new float[10]; + } }; } diff --git a/cm/lib/main/java/org/cyanogenmod/platform/internal/display/LiveDisplayService.java b/cm/lib/main/java/org/cyanogenmod/platform/internal/display/LiveDisplayService.java index 7fe5656..6b82120 100644 --- a/cm/lib/main/java/org/cyanogenmod/platform/internal/display/LiveDisplayService.java +++ b/cm/lib/main/java/org/cyanogenmod/platform/internal/display/LiveDisplayService.java @@ -65,6 +65,7 @@ import java.util.List; import cyanogenmod.app.CMContextConstants; import cyanogenmod.app.CMStatusBarManager; import cyanogenmod.app.CustomTile; +import cyanogenmod.hardware.HSIC; import cyanogenmod.hardware.ILiveDisplayService; import cyanogenmod.hardware.LiveDisplayConfig; import cyanogenmod.providers.CMSettings; @@ -98,6 +99,7 @@ public class LiveDisplayService extends CMSystemService { private ColorTemperatureController mCTC; private DisplayHardwareController mDHC; private OutdoorModeController mOMC; + private PictureAdjustmentController mPAC; private LiveDisplayConfig mConfig; @@ -175,6 +177,9 @@ public class LiveDisplayService extends CMSystemService { mOMC = new OutdoorModeController(mContext, mHandler); mFeatures.add(mOMC); + mPAC = new PictureAdjustmentController(mContext, mHandler); + mFeatures.add(mPAC); + // Get capabilities, throw out any unused features final BitSet capabilities = new BitSet(); for (Iterator<LiveDisplayFeature> it = mFeatures.iterator(); it.hasNext();) { @@ -192,7 +197,10 @@ public class LiveDisplayService extends CMSystemService { mCTC.getDefaultDayTemperature(), mCTC.getDefaultNightTemperature(), mOMC.getDefaultAutoOutdoorMode(), mDHC.getDefaultAutoContrast(), mDHC.getDefaultCABC(), mDHC.getDefaultColorEnhancement(), - mCTC.getColorTemperatureRange(), mCTC.getColorBalanceRange()); + mCTC.getColorTemperatureRange(), mCTC.getColorBalanceRange(), + mPAC.getHueRange(), mPAC.getSaturationRange(), + mPAC.getIntensityRange(), mPAC.getContrastRange(), + mPAC.getSaturationThresholdRange()); // listeners mDisplayManager = (DisplayManager) getContext().getSystemService( @@ -471,6 +479,15 @@ public class LiveDisplayService extends CMSystemService { } @Override + public HSIC getPictureAdjustment() { return mPAC.getPictureAdjustment(); } + + @Override + public boolean setPictureAdjustment(final HSIC hsic) { return mPAC.setPictureAdjustment(hsic); } + + @Override + public HSIC getDefaultPictureAdjustment() { return mPAC.getDefaultPictureAdjustment(); } + + @Override public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG); diff --git a/cm/lib/main/java/org/cyanogenmod/platform/internal/display/PictureAdjustmentController.java b/cm/lib/main/java/org/cyanogenmod/platform/internal/display/PictureAdjustmentController.java new file mode 100644 index 0000000..5cb08b2 --- /dev/null +++ b/cm/lib/main/java/org/cyanogenmod/platform/internal/display/PictureAdjustmentController.java @@ -0,0 +1,242 @@ +/* + * 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.text.TextUtils; +import android.util.Range; +import android.util.Slog; +import android.util.SparseArray; +import android.view.Display; + +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.BitSet; +import java.util.List; + +import cyanogenmod.hardware.CMHardwareManager; +import cyanogenmod.hardware.DisplayMode; +import cyanogenmod.hardware.HSIC; +import cyanogenmod.hardware.LiveDisplayManager; +import cyanogenmod.providers.CMSettings; + +public class PictureAdjustmentController extends LiveDisplayFeature { + + private static final String TAG = "LiveDisplay-PAC"; + + private final CMHardwareManager mHardware; + private final boolean mUsePictureAdjustment; + private final boolean mHasDisplayModes; + + private List<Range<Float>> mRanges = new ArrayList<Range<Float>>(); + + public PictureAdjustmentController(Context context, Handler handler) { + super(context, handler); + mHardware = CMHardwareManager.getInstance(context); + mHasDisplayModes = mHardware.isSupported(CMHardwareManager.FEATURE_DISPLAY_MODES); + + boolean usePA = mHardware.isSupported(CMHardwareManager.FEATURE_PICTURE_ADJUSTMENT); + if (usePA) { + mRanges.addAll(mHardware.getPictureAdjustmentRanges()); + if (mRanges.size() < 4) { + usePA = false; + } else { + for (Range<Float> range : mRanges) { + if (range.getLower() == 0.0f && range.getUpper() == 0.0f) { + usePA = false; + break; + } + } + } + } + if (!usePA) { + mRanges.clear(); + } + mUsePictureAdjustment = usePA; + } + + @Override + public void onStart() { + if (!mUsePictureAdjustment) { + return; + } + + registerSettings( + CMSettings.System.getUriFor(CMSettings.System.DISPLAY_PICTURE_ADJUSTMENT)); + } + + @Override + protected void onSettingsChanged(Uri uri) {// nothing to do for mode switch + updatePictureAdjustment(); + } + + @Override + protected void onUpdate() { + updatePictureAdjustment(); + } + + private void updatePictureAdjustment() { + if (mUsePictureAdjustment && isScreenOn()) { + final HSIC hsic = getPictureAdjustment(); + if (hsic != null) { + if (!mHardware.setPictureAdjustment(hsic)) { + Slog.e(TAG, "Failed to set picture adjustment! " + hsic.toString()); + } + } + } + } + + @Override + public void dump(PrintWriter pw) { + if (mUsePictureAdjustment) { + pw.println(); + pw.println("PictureAdjustmentController Configuration:"); + pw.println(" adjustment=" + getPictureAdjustment()); + pw.println(" hueRange=" + getHueRange()); + pw.println(" saturationRange=" + getSaturationRange()); + pw.println(" intensityRange=" + getIntensityRange()); + pw.println(" contrastRange=" + getContrastRange()); + pw.println(" saturationThresholdRange=" + getSaturationThresholdRange()); + pw.println(" defaultAdjustment=" + getDefaultPictureAdjustment()); + } + } + + + @Override + public boolean getCapabilities(BitSet caps) { + if (mUsePictureAdjustment) { + caps.set(LiveDisplayManager.FEATURE_PICTURE_ADJUSTMENT); + } + return mUsePictureAdjustment; + } + + Range<Float> getHueRange() { + return mUsePictureAdjustment && mRanges.size() > 0 + ? mRanges.get(0) : Range.create(0.0f, 0.0f); + } + + Range<Float> getSaturationRange() { + return mUsePictureAdjustment && mRanges.size() > 1 + ? mRanges.get(1) : Range.create(0.0f, 0.0f); + } + + Range<Float> getIntensityRange() { + return mUsePictureAdjustment && mRanges.size() > 2 + ? mRanges.get(2) : Range.create(0.0f, 0.0f); + } + + Range<Float> getContrastRange() { + return mUsePictureAdjustment && mRanges.size() > 3 ? + mRanges.get(3) : Range.create(0.0f, 0.0f); + } + + Range<Float> getSaturationThresholdRange() { + return mUsePictureAdjustment && mRanges.size() > 4 ? + mRanges.get(4) : Range.create(0.0f, 0.0f); + } + + HSIC getDefaultPictureAdjustment() { + HSIC hsic = null; + if (mUsePictureAdjustment) { + hsic = mHardware.getDefaultPictureAdjustment(); + } + if (hsic == null) { + hsic = new HSIC(0.0f, 0.0f, 0.0f, 0.0f, 0.0f); + } + return hsic; + } + + HSIC getPictureAdjustment() { + HSIC hsic = null; + if (mUsePictureAdjustment) { + int modeID = 0; + if (mHasDisplayModes) { + DisplayMode mode = mHardware.getCurrentDisplayMode(); + if (mode != null) { + modeID = mode.id; + } + } + hsic = getPAForMode(modeID); + } + if (hsic == null) { + hsic = new HSIC(0.0f, 0.0f, 0.0f, 0.0f, 0.0f); + } + return hsic; + } + + boolean setPictureAdjustment(HSIC hsic) { + if (mUsePictureAdjustment && hsic != null) { + int modeID = 0; + if (mHasDisplayModes) { + DisplayMode mode = mHardware.getCurrentDisplayMode(); + if (mode != null) { + modeID = mode.id; + } + } + setPAForMode(modeID, hsic); + return true; + } + return false; + } + + // TODO: Expose mode-based settings to upper layers + + private HSIC getPAForMode(int mode) { + final SparseArray<HSIC> prefs = unpackPreference(); + if (prefs.indexOfKey(mode) >= 0) { + return prefs.get(mode); + } + return getDefaultPictureAdjustment(); + } + + private void setPAForMode(int mode, HSIC hsic) { + final SparseArray<HSIC> prefs = unpackPreference(); + prefs.put(mode, hsic); + packPreference(prefs); + } + + private SparseArray<HSIC> unpackPreference() { + final SparseArray<HSIC> ret = new SparseArray<HSIC>(); + + String pref = getString(CMSettings.System.DISPLAY_PICTURE_ADJUSTMENT); + if (pref != null) { + String[] byMode = TextUtils.split(pref, ","); + for (String mode : byMode) { + String[] modePA = TextUtils.split(mode, ":"); + if (modePA.length == 2) { + ret.put(Integer.valueOf(modePA[0]), HSIC.unflattenFrom(modePA[1])); + } + } + } + return ret; + } + + private void packPreference(final SparseArray<HSIC> modes) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < modes.size(); i++) { + int id = modes.keyAt(i); + HSIC m = modes.get(id); + if (i > 0) { + sb.append(","); + } + sb.append(id).append(":").append(m.flatten()); + } + putString(CMSettings.System.DISPLAY_PICTURE_ADJUSTMENT, sb.toString()); + } + +} |