Loading core/res/res/values/config.xml +38 −3 Original line number Diff line number Diff line Loading @@ -929,9 +929,6 @@ in hardware. --> <bool name="config_setColorTransformAccelerated">false</bool> <!-- Boolean indicating whether display white balance is supported. --> <bool name="config_displayWhiteBalanceAvailable">false</bool> <!-- Control whether Night display is available. This should only be enabled on devices that have a HWC implementation that can apply the matrix passed to setColorTransform without impacting power, performance, and app compatibility (e.g. protected content). --> Loading Loading @@ -987,6 +984,44 @@ <!-- B y-intercept --> <item>-0.198650895</item> </string-array> <!-- Boolean indicating whether display white balance is supported. --> <bool name="config_displayWhiteBalanceAvailable">false</bool> <!-- Minimum color temperature, in Kelvin, supported by display white balance. --> <integer name="config_displayWhiteBalanceColorTemperatureMin">4000</integer> <!-- Maximum color temperature, in Kelvin, supported by display white balance. --> <integer name="config_displayWhiteBalanceColorTemperatureMax">8000</integer> <!-- Default color temperature, in Kelvin, used by display white balance. --> <integer name="config_displayWhiteBalanceColorTemperatureDefault">6500</integer> <!-- The display primaries, in CIE1931 XYZ color space, for display white balance to use in its calculations. --> <string-array name="config_displayWhiteBalanceDisplayPrimaries"> <!-- Red X --> <item>0.412315</item> <!-- Red Y --> <item>0.212600</item> <!-- Red Z --> <item>0.019327</item> <!-- Green X --> <item>0.357600</item> <!-- Green Y --> <item>0.715200</item> <!-- Green Z --> <item>0.119200</item> <!-- Blue X --> <item>0.180500</item> <!-- Blue Y --> <item>0.072200</item> <!-- Blue Z --> <item>0.950633</item> <!-- White X --> <item>0.950456</item> <!-- White Y --> <item>1.000000</item> <!-- White Z --> <item>1.089058</item> </string-array> <!-- The nominal white coordinates, in CIE1931 XYZ color space, for Display White Balance to use in its calculations. AWB will adapt this white point to the target ambient white point. --> <string-array name="config_displayWhiteBalanceDisplayNominalWhite"> <!-- Nominal White X --> <item>0.950456</item> <!-- Nominal White Y --> <item>1.000000</item> <!-- Nominal White Z --> <item>1.089058</item> </string-array> <!-- Indicate available ColorDisplayController.COLOR_MODE_xxx. --> <integer-array name="config_availableColorModes"> Loading core/res/res/values/symbols.xml +7 −0 Original line number Diff line number Diff line Loading @@ -3042,6 +3042,13 @@ <java-symbol type="array" name="config_nightDisplayColorTemperatureCoefficientsNative" /> <java-symbol type="array" name="config_availableColorModes" /> <java-symbol type="bool" name="config_displayWhiteBalanceAvailable" /> <java-symbol type="integer" name="config_displayWhiteBalanceColorTemperatureMin" /> <java-symbol type="integer" name="config_displayWhiteBalanceColorTemperatureMax" /> <java-symbol type="integer" name="config_displayWhiteBalanceColorTemperatureDefault" /> <java-symbol type="array" name="config_displayWhiteBalanceDisplayPrimaries" /> <java-symbol type="array" name="config_displayWhiteBalanceDisplayNominalWhite" /> <!-- Default first user restrictions --> <java-symbol type="array" name="config_defaultFirstUserRestrictions" /> Loading graphics/java/android/graphics/ColorSpace.java +3 −1 Original line number Diff line number Diff line Loading @@ -1661,10 +1661,12 @@ public abstract class ColorSpace { * @param rhs 3x3 matrix, as a non-null array of 9 floats * @return A new array of 9 floats containing the result of the multiplication * of rhs by lhs * * @hide */ @NonNull @Size(9) private static float[] mul3x3(@NonNull @Size(9) float[] lhs, @NonNull @Size(9) float[] rhs) { public static float[] mul3x3(@NonNull @Size(9) float[] lhs, @NonNull @Size(9) float[] rhs) { float[] r = new float[9]; r[0] = lhs[0] * rhs[0] + lhs[3] * rhs[1] + lhs[6] * rhs[2]; r[1] = lhs[1] * rhs[0] + lhs[4] * rhs[1] + lhs[7] * rhs[2]; Loading services/core/java/com/android/server/display/ColorDisplayService.java +209 −23 Original line number Diff line number Diff line Loading @@ -34,8 +34,10 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.content.res.Resources; import android.database.ContentObserver; import android.hardware.display.ColorDisplayManager; import android.graphics.ColorSpace; import android.hardware.display.IColorDisplayManager; import android.net.Uri; import android.opengl.Matrix; Loading @@ -59,6 +61,7 @@ import com.android.server.twilight.TwilightListener; import com.android.server.twilight.TwilightManager; import com.android.server.twilight.TwilightState; import java.io.PrintWriter; import java.time.DateTimeException; import java.time.Instant; import java.time.LocalDateTime; Loading Loading @@ -148,26 +151,204 @@ public final class ColorDisplayService extends SystemService { }; private final TintController mDisplayWhiteBalanceTintController = new TintController() { // Three chromaticity coordinates per color: X, Y, and Z private final int NUM_VALUES_PER_PRIMARY = 3; // Four colors: red, green, blue, and white private final int NUM_DISPLAY_PRIMARIES_VALS = 4 * NUM_VALUES_PER_PRIMARY; private final Object mLock = new Object(); private int mTemperatureMin; private int mTemperatureMax; private int mTemperatureDefault; private float[] mDisplayNominalWhiteXYZ = new float[NUM_VALUES_PER_PRIMARY]; private ColorSpace.Rgb mDisplayColorSpaceRGB; private float[] mChromaticAdaptationMatrix; private int mCurrentColorTemperature; private float[] mCurrentColorTemperatureXYZ; private boolean mSetUp = false; private float[] mMatrixDisplayWhiteBalance = new float[16]; @Override public void setUp(Context context, boolean needsLinear) { mSetUp = false; final Resources res = getContext().getResources(); final String[] displayPrimariesValues = res.getStringArray( R.array.config_displayWhiteBalanceDisplayPrimaries); final String[] nominalWhiteValues = res.getStringArray( R.array.config_displayWhiteBalanceDisplayNominalWhite); if (displayPrimariesValues.length != NUM_DISPLAY_PRIMARIES_VALS) { Slog.e(TAG, "Unexpected display white balance primaries resource length " + displayPrimariesValues.length); return; } if (nominalWhiteValues.length != NUM_VALUES_PER_PRIMARY) { Slog.e(TAG, "Unexpected display white balance nominal white resource length " + nominalWhiteValues.length); return; } float[] displayRedGreenBlueXYZ = new float[NUM_DISPLAY_PRIMARIES_VALS - NUM_VALUES_PER_PRIMARY]; float[] displayWhiteXYZ = new float[NUM_VALUES_PER_PRIMARY]; for (int i = 0; i < displayRedGreenBlueXYZ.length; i++) { displayRedGreenBlueXYZ[i] = Float.parseFloat(displayPrimariesValues[i]); } for (int i = 0; i < displayWhiteXYZ.length; i++) { displayWhiteXYZ[i] = Float.parseFloat( displayPrimariesValues[displayRedGreenBlueXYZ.length + i]); } final ColorSpace.Rgb displayColorSpaceRGB = new ColorSpace.Rgb( "Display Color Space", displayRedGreenBlueXYZ, displayWhiteXYZ, 2.2f // gamma, unused for display white balance ); float[] displayNominalWhiteXYZ = new float[NUM_VALUES_PER_PRIMARY]; for (int i = 0; i < nominalWhiteValues.length; i++) { displayNominalWhiteXYZ[i] = Float.parseFloat(nominalWhiteValues[i]); } final int colorTemperatureMin = res.getInteger( R.integer.config_displayWhiteBalanceColorTemperatureMin); if (colorTemperatureMin <= 0) { Slog.e(TAG, "display white balance minimum temperature must be greater than 0"); return; } final int colorTemperatureMax = res.getInteger( R.integer.config_displayWhiteBalanceColorTemperatureMax); if (colorTemperatureMax < colorTemperatureMin) { Slog.e(TAG, "display white balance max temp must be greater or equal to min"); return; } final int colorTemperature = res.getInteger( R.integer.config_displayWhiteBalanceColorTemperatureDefault); synchronized (mLock) { mDisplayColorSpaceRGB = displayColorSpaceRGB; mDisplayNominalWhiteXYZ = displayNominalWhiteXYZ; mTemperatureMin = colorTemperatureMin; mTemperatureMax = colorTemperatureMax; mTemperatureDefault = colorTemperature; mSetUp = true; } setMatrix(mTemperatureDefault); } @Override public float[] getMatrix() { return isActivated() ? mMatrixDisplayWhiteBalance : MATRIX_IDENTITY; return mSetUp && isActivated() ? mMatrixDisplayWhiteBalance : MATRIX_IDENTITY; } @Override public void setMatrix(int cct) { if (!mSetUp) { Slog.w(TAG, "Can't set display white balance temperature: uninitialized"); return; } if (cct < mTemperatureMin) { Slog.w(TAG, "Requested display color temperature is below allowed minimum"); cct = mTemperatureMin; } else if (cct > mTemperatureMax) { Slog.w(TAG, "Requested display color temperature is above allowed maximum"); cct = mTemperatureMax; } Slog.d(TAG, "setDisplayWhiteBalanceTemperatureMatrix: cct = " + cct); synchronized (mLock) { mCurrentColorTemperature = cct; // Adapt the display's nominal white point to match the requested CCT value mCurrentColorTemperatureXYZ = ColorSpace.cctToIlluminantdXyz(cct); mChromaticAdaptationMatrix = ColorSpace.chromaticAdaptation(ColorSpace.Adaptation.BRADFORD, mDisplayNominalWhiteXYZ, mCurrentColorTemperatureXYZ); // Convert the adaptation matrix to RGB space float[] result = ColorSpace.mul3x3(mChromaticAdaptationMatrix, mDisplayColorSpaceRGB.getTransform()); result = ColorSpace.mul3x3(mDisplayColorSpaceRGB.getInverseTransform(), result); // Normalize the transform matrix to peak white value in RGB space final float adaptedMaxR = result[0] + result[3] + result[6]; final float adaptedMaxG = result[1] + result[4] + result[7]; final float adaptedMaxB = result[2] + result[5] + result[8]; final float denum = Math.max(Math.max(adaptedMaxR, adaptedMaxG), adaptedMaxB); for (int i = 0; i < result.length; i++) { result[i] /= denum; } Matrix.setIdentityM(mMatrixDisplayWhiteBalance, 0); java.lang.System.arraycopy(result, 0, mMatrixDisplayWhiteBalance, 0, 3); java.lang.System.arraycopy(result, 3, mMatrixDisplayWhiteBalance, 4, 3); java.lang.System.arraycopy(result, 6, mMatrixDisplayWhiteBalance, 8, 3); } } @Override public int getLevel() { return LEVEL_COLOR_MATRIX_DISPLAY_WHITE_BALANCE; } /** * Format a given matrix into a string. * * @param matrix the matrix to format * @param cols number of columns in the matrix */ private String matrixToString(float[] matrix, int cols) { if (matrix == null || cols <= 0) { Slog.e(TAG, "Invalid arguments when formatting matrix to string"); return ""; } StringBuilder sb = new StringBuilder(""); for (int i = 0; i < matrix.length; i++) { if (i % cols == 0) { sb.append("\n "); } sb.append(String.format("%9.6f ", matrix[i])); } return sb.toString(); } @Override public void dump(PrintWriter pw) { synchronized (mLock) { pw.println("ColorDisplayService"); pw.println(" mSetUp = " + mSetUp); if (!mSetUp) { return; } pw.println(" isActivated = " + isActivated()); pw.println(" mTemperatureMin = " + mTemperatureMin); pw.println(" mTemperatureMax = " + mTemperatureMax); pw.println(" mTemperatureDefault = " + mTemperatureDefault); pw.println(" mCurrentColorTemperature = " + mCurrentColorTemperature); pw.println(" mCurrentColorTemperatureXYZ = " + matrixToString(mCurrentColorTemperatureXYZ, 3)); pw.println(" mDisplayColorSpaceRGB RGB-to-XYZ = " + matrixToString(mDisplayColorSpaceRGB.getTransform(), 3)); pw.println(" mChromaticAdaptationMatrix = " + matrixToString(mChromaticAdaptationMatrix, 3)); pw.println(" mDisplayColorSpaceRGB XYZ-to-RGB = " + matrixToString(mDisplayColorSpaceRGB.getInverseTransform(), 3)); pw.println(" mMatrixDisplayWhiteBalance = " + matrixToString(mMatrixDisplayWhiteBalance, 4)); } } }; private final TintController mGlobalSaturationTintController = new TintController() { Loading Loading @@ -230,8 +411,6 @@ public final class ColorDisplayService extends SystemService { private NightDisplayAutoMode mNightDisplayAutoMode; private Integer mDisplayWhiteBalanceColorTemperature; public ColorDisplayService(Context context) { super(context); mHandler = new TintHandler(Looper.getMainLooper()); Loading Loading @@ -363,7 +542,7 @@ public final class ColorDisplayService extends SystemService { onAccessibilityTransformChanged(); break; case Secure.DISPLAY_WHITE_BALANCE_ENABLED: onDisplayWhiteBalanceEnabled(isDisplayWhiteBalanceSettingEnabled()); updateDisplayWhiteBalanceStatus(); break; } } Loading Loading @@ -416,14 +595,9 @@ public final class ColorDisplayService extends SystemService { if (ColorDisplayManager.isDisplayWhiteBalanceAvailable(getContext())) { // Prepare the display white balance transform matrix. mDisplayWhiteBalanceTintController .setUp(getContext(), DisplayTransformManager.needsLinearColorMatrix()); if (mDisplayWhiteBalanceColorTemperature != null) { mDisplayWhiteBalanceTintController .setMatrix(mDisplayWhiteBalanceColorTemperature); } mDisplayWhiteBalanceTintController.setUp(getContext(), true /* needsLinear */); onDisplayWhiteBalanceEnabled(isDisplayWhiteBalanceSettingEnabled()); updateDisplayWhiteBalanceStatus(); } } Loading Loading @@ -460,6 +634,8 @@ public final class ColorDisplayService extends SystemService { mNightDisplayAutoMode.onActivated(activated); } updateDisplayWhiteBalanceStatus(); applyTint(mNightDisplayTintController, false); } } Loading Loading @@ -516,11 +692,7 @@ public final class ColorDisplayService extends SystemService { .setUp(getContext(), DisplayTransformManager.needsLinearColorMatrix(mode)); mNightDisplayTintController.setMatrix(mNightDisplayController.getColorTemperature()); mDisplayWhiteBalanceTintController .setUp(getContext(), DisplayTransformManager.needsLinearColorMatrix(mode)); if (mDisplayWhiteBalanceColorTemperature != null) { mDisplayWhiteBalanceTintController.setMatrix(mDisplayWhiteBalanceColorTemperature); } updateDisplayWhiteBalanceStatus(); final DisplayTransformManager dtm = getLocalService(DisplayTransformManager.class); dtm.setColorMode(mode, mNightDisplayTintController.getMatrix()); Loading Loading @@ -611,10 +783,15 @@ public final class ColorDisplayService extends SystemService { return ldt.isBefore(compareTime) ? ldt.plusDays(1) : ldt; } private void onDisplayWhiteBalanceEnabled(boolean enabled) { mDisplayWhiteBalanceTintController.setActivated(enabled); if (mDisplayWhiteBalanceListener != null) { mDisplayWhiteBalanceListener.onDisplayWhiteBalanceStatusChanged(enabled); private void updateDisplayWhiteBalanceStatus() { boolean oldActivated = mDisplayWhiteBalanceTintController.isActivated(); mDisplayWhiteBalanceTintController.setActivated(isDisplayWhiteBalanceSettingEnabled() && !mNightDisplayTintController.isActivated() && DisplayTransformManager.needsLinearColorMatrix()); boolean activated = mDisplayWhiteBalanceTintController.isActivated(); if (mDisplayWhiteBalanceListener != null && oldActivated != activated) { mDisplayWhiteBalanceListener.onDisplayWhiteBalanceStatusChanged(activated); } } Loading Loading @@ -895,6 +1072,12 @@ public final class ColorDisplayService extends SystemService { return mIsActivated == null; } /** * Dump debug information. */ public void dump(PrintWriter pw) { } /** * Set up any constants needed for computing the matrix. */ Loading Loading @@ -929,11 +1112,10 @@ public final class ColorDisplayService extends SystemService { */ public boolean setDisplayWhiteBalanceColorTemperature(int cct) { // Update the transform matrix even if it can't be applied. mDisplayWhiteBalanceColorTemperature = cct; mDisplayWhiteBalanceTintController.setMatrix(cct); if (mDisplayWhiteBalanceTintController.isActivated()) { applyTint(mDisplayWhiteBalanceTintController, true); applyTint(mDisplayWhiteBalanceTintController, false); return true; } return false; Loading @@ -946,6 +1128,10 @@ public final class ColorDisplayService extends SystemService { mDisplayWhiteBalanceListener = listener; return mDisplayWhiteBalanceTintController.isActivated(); } public void dump(PrintWriter pw) { mDisplayWhiteBalanceTintController.dump(pw); } } /** Loading services/core/java/com/android/server/display/DisplayManagerService.java +8 −0 Original line number Diff line number Diff line Loading @@ -95,6 +95,7 @@ import com.android.server.SystemService; import com.android.server.UiThread; import com.android.server.wm.SurfaceAnimationThread; import com.android.server.wm.WindowManagerInternal; import com.android.server.display.ColorDisplayService.ColorDisplayServiceInternal; import java.io.FileDescriptor; import java.io.PrintWriter; Loading Loading @@ -1459,6 +1460,13 @@ public final class DisplayManagerService extends SystemService { pw.println(); mPersistentDataStore.dump(pw); final ColorDisplayServiceInternal cds = LocalServices.getService( ColorDisplayServiceInternal.class); if (cds != null) { pw.println(); cds.dump(pw); } } } Loading Loading
core/res/res/values/config.xml +38 −3 Original line number Diff line number Diff line Loading @@ -929,9 +929,6 @@ in hardware. --> <bool name="config_setColorTransformAccelerated">false</bool> <!-- Boolean indicating whether display white balance is supported. --> <bool name="config_displayWhiteBalanceAvailable">false</bool> <!-- Control whether Night display is available. This should only be enabled on devices that have a HWC implementation that can apply the matrix passed to setColorTransform without impacting power, performance, and app compatibility (e.g. protected content). --> Loading Loading @@ -987,6 +984,44 @@ <!-- B y-intercept --> <item>-0.198650895</item> </string-array> <!-- Boolean indicating whether display white balance is supported. --> <bool name="config_displayWhiteBalanceAvailable">false</bool> <!-- Minimum color temperature, in Kelvin, supported by display white balance. --> <integer name="config_displayWhiteBalanceColorTemperatureMin">4000</integer> <!-- Maximum color temperature, in Kelvin, supported by display white balance. --> <integer name="config_displayWhiteBalanceColorTemperatureMax">8000</integer> <!-- Default color temperature, in Kelvin, used by display white balance. --> <integer name="config_displayWhiteBalanceColorTemperatureDefault">6500</integer> <!-- The display primaries, in CIE1931 XYZ color space, for display white balance to use in its calculations. --> <string-array name="config_displayWhiteBalanceDisplayPrimaries"> <!-- Red X --> <item>0.412315</item> <!-- Red Y --> <item>0.212600</item> <!-- Red Z --> <item>0.019327</item> <!-- Green X --> <item>0.357600</item> <!-- Green Y --> <item>0.715200</item> <!-- Green Z --> <item>0.119200</item> <!-- Blue X --> <item>0.180500</item> <!-- Blue Y --> <item>0.072200</item> <!-- Blue Z --> <item>0.950633</item> <!-- White X --> <item>0.950456</item> <!-- White Y --> <item>1.000000</item> <!-- White Z --> <item>1.089058</item> </string-array> <!-- The nominal white coordinates, in CIE1931 XYZ color space, for Display White Balance to use in its calculations. AWB will adapt this white point to the target ambient white point. --> <string-array name="config_displayWhiteBalanceDisplayNominalWhite"> <!-- Nominal White X --> <item>0.950456</item> <!-- Nominal White Y --> <item>1.000000</item> <!-- Nominal White Z --> <item>1.089058</item> </string-array> <!-- Indicate available ColorDisplayController.COLOR_MODE_xxx. --> <integer-array name="config_availableColorModes"> Loading
core/res/res/values/symbols.xml +7 −0 Original line number Diff line number Diff line Loading @@ -3042,6 +3042,13 @@ <java-symbol type="array" name="config_nightDisplayColorTemperatureCoefficientsNative" /> <java-symbol type="array" name="config_availableColorModes" /> <java-symbol type="bool" name="config_displayWhiteBalanceAvailable" /> <java-symbol type="integer" name="config_displayWhiteBalanceColorTemperatureMin" /> <java-symbol type="integer" name="config_displayWhiteBalanceColorTemperatureMax" /> <java-symbol type="integer" name="config_displayWhiteBalanceColorTemperatureDefault" /> <java-symbol type="array" name="config_displayWhiteBalanceDisplayPrimaries" /> <java-symbol type="array" name="config_displayWhiteBalanceDisplayNominalWhite" /> <!-- Default first user restrictions --> <java-symbol type="array" name="config_defaultFirstUserRestrictions" /> Loading
graphics/java/android/graphics/ColorSpace.java +3 −1 Original line number Diff line number Diff line Loading @@ -1661,10 +1661,12 @@ public abstract class ColorSpace { * @param rhs 3x3 matrix, as a non-null array of 9 floats * @return A new array of 9 floats containing the result of the multiplication * of rhs by lhs * * @hide */ @NonNull @Size(9) private static float[] mul3x3(@NonNull @Size(9) float[] lhs, @NonNull @Size(9) float[] rhs) { public static float[] mul3x3(@NonNull @Size(9) float[] lhs, @NonNull @Size(9) float[] rhs) { float[] r = new float[9]; r[0] = lhs[0] * rhs[0] + lhs[3] * rhs[1] + lhs[6] * rhs[2]; r[1] = lhs[1] * rhs[0] + lhs[4] * rhs[1] + lhs[7] * rhs[2]; Loading
services/core/java/com/android/server/display/ColorDisplayService.java +209 −23 Original line number Diff line number Diff line Loading @@ -34,8 +34,10 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.content.res.Resources; import android.database.ContentObserver; import android.hardware.display.ColorDisplayManager; import android.graphics.ColorSpace; import android.hardware.display.IColorDisplayManager; import android.net.Uri; import android.opengl.Matrix; Loading @@ -59,6 +61,7 @@ import com.android.server.twilight.TwilightListener; import com.android.server.twilight.TwilightManager; import com.android.server.twilight.TwilightState; import java.io.PrintWriter; import java.time.DateTimeException; import java.time.Instant; import java.time.LocalDateTime; Loading Loading @@ -148,26 +151,204 @@ public final class ColorDisplayService extends SystemService { }; private final TintController mDisplayWhiteBalanceTintController = new TintController() { // Three chromaticity coordinates per color: X, Y, and Z private final int NUM_VALUES_PER_PRIMARY = 3; // Four colors: red, green, blue, and white private final int NUM_DISPLAY_PRIMARIES_VALS = 4 * NUM_VALUES_PER_PRIMARY; private final Object mLock = new Object(); private int mTemperatureMin; private int mTemperatureMax; private int mTemperatureDefault; private float[] mDisplayNominalWhiteXYZ = new float[NUM_VALUES_PER_PRIMARY]; private ColorSpace.Rgb mDisplayColorSpaceRGB; private float[] mChromaticAdaptationMatrix; private int mCurrentColorTemperature; private float[] mCurrentColorTemperatureXYZ; private boolean mSetUp = false; private float[] mMatrixDisplayWhiteBalance = new float[16]; @Override public void setUp(Context context, boolean needsLinear) { mSetUp = false; final Resources res = getContext().getResources(); final String[] displayPrimariesValues = res.getStringArray( R.array.config_displayWhiteBalanceDisplayPrimaries); final String[] nominalWhiteValues = res.getStringArray( R.array.config_displayWhiteBalanceDisplayNominalWhite); if (displayPrimariesValues.length != NUM_DISPLAY_PRIMARIES_VALS) { Slog.e(TAG, "Unexpected display white balance primaries resource length " + displayPrimariesValues.length); return; } if (nominalWhiteValues.length != NUM_VALUES_PER_PRIMARY) { Slog.e(TAG, "Unexpected display white balance nominal white resource length " + nominalWhiteValues.length); return; } float[] displayRedGreenBlueXYZ = new float[NUM_DISPLAY_PRIMARIES_VALS - NUM_VALUES_PER_PRIMARY]; float[] displayWhiteXYZ = new float[NUM_VALUES_PER_PRIMARY]; for (int i = 0; i < displayRedGreenBlueXYZ.length; i++) { displayRedGreenBlueXYZ[i] = Float.parseFloat(displayPrimariesValues[i]); } for (int i = 0; i < displayWhiteXYZ.length; i++) { displayWhiteXYZ[i] = Float.parseFloat( displayPrimariesValues[displayRedGreenBlueXYZ.length + i]); } final ColorSpace.Rgb displayColorSpaceRGB = new ColorSpace.Rgb( "Display Color Space", displayRedGreenBlueXYZ, displayWhiteXYZ, 2.2f // gamma, unused for display white balance ); float[] displayNominalWhiteXYZ = new float[NUM_VALUES_PER_PRIMARY]; for (int i = 0; i < nominalWhiteValues.length; i++) { displayNominalWhiteXYZ[i] = Float.parseFloat(nominalWhiteValues[i]); } final int colorTemperatureMin = res.getInteger( R.integer.config_displayWhiteBalanceColorTemperatureMin); if (colorTemperatureMin <= 0) { Slog.e(TAG, "display white balance minimum temperature must be greater than 0"); return; } final int colorTemperatureMax = res.getInteger( R.integer.config_displayWhiteBalanceColorTemperatureMax); if (colorTemperatureMax < colorTemperatureMin) { Slog.e(TAG, "display white balance max temp must be greater or equal to min"); return; } final int colorTemperature = res.getInteger( R.integer.config_displayWhiteBalanceColorTemperatureDefault); synchronized (mLock) { mDisplayColorSpaceRGB = displayColorSpaceRGB; mDisplayNominalWhiteXYZ = displayNominalWhiteXYZ; mTemperatureMin = colorTemperatureMin; mTemperatureMax = colorTemperatureMax; mTemperatureDefault = colorTemperature; mSetUp = true; } setMatrix(mTemperatureDefault); } @Override public float[] getMatrix() { return isActivated() ? mMatrixDisplayWhiteBalance : MATRIX_IDENTITY; return mSetUp && isActivated() ? mMatrixDisplayWhiteBalance : MATRIX_IDENTITY; } @Override public void setMatrix(int cct) { if (!mSetUp) { Slog.w(TAG, "Can't set display white balance temperature: uninitialized"); return; } if (cct < mTemperatureMin) { Slog.w(TAG, "Requested display color temperature is below allowed minimum"); cct = mTemperatureMin; } else if (cct > mTemperatureMax) { Slog.w(TAG, "Requested display color temperature is above allowed maximum"); cct = mTemperatureMax; } Slog.d(TAG, "setDisplayWhiteBalanceTemperatureMatrix: cct = " + cct); synchronized (mLock) { mCurrentColorTemperature = cct; // Adapt the display's nominal white point to match the requested CCT value mCurrentColorTemperatureXYZ = ColorSpace.cctToIlluminantdXyz(cct); mChromaticAdaptationMatrix = ColorSpace.chromaticAdaptation(ColorSpace.Adaptation.BRADFORD, mDisplayNominalWhiteXYZ, mCurrentColorTemperatureXYZ); // Convert the adaptation matrix to RGB space float[] result = ColorSpace.mul3x3(mChromaticAdaptationMatrix, mDisplayColorSpaceRGB.getTransform()); result = ColorSpace.mul3x3(mDisplayColorSpaceRGB.getInverseTransform(), result); // Normalize the transform matrix to peak white value in RGB space final float adaptedMaxR = result[0] + result[3] + result[6]; final float adaptedMaxG = result[1] + result[4] + result[7]; final float adaptedMaxB = result[2] + result[5] + result[8]; final float denum = Math.max(Math.max(adaptedMaxR, adaptedMaxG), adaptedMaxB); for (int i = 0; i < result.length; i++) { result[i] /= denum; } Matrix.setIdentityM(mMatrixDisplayWhiteBalance, 0); java.lang.System.arraycopy(result, 0, mMatrixDisplayWhiteBalance, 0, 3); java.lang.System.arraycopy(result, 3, mMatrixDisplayWhiteBalance, 4, 3); java.lang.System.arraycopy(result, 6, mMatrixDisplayWhiteBalance, 8, 3); } } @Override public int getLevel() { return LEVEL_COLOR_MATRIX_DISPLAY_WHITE_BALANCE; } /** * Format a given matrix into a string. * * @param matrix the matrix to format * @param cols number of columns in the matrix */ private String matrixToString(float[] matrix, int cols) { if (matrix == null || cols <= 0) { Slog.e(TAG, "Invalid arguments when formatting matrix to string"); return ""; } StringBuilder sb = new StringBuilder(""); for (int i = 0; i < matrix.length; i++) { if (i % cols == 0) { sb.append("\n "); } sb.append(String.format("%9.6f ", matrix[i])); } return sb.toString(); } @Override public void dump(PrintWriter pw) { synchronized (mLock) { pw.println("ColorDisplayService"); pw.println(" mSetUp = " + mSetUp); if (!mSetUp) { return; } pw.println(" isActivated = " + isActivated()); pw.println(" mTemperatureMin = " + mTemperatureMin); pw.println(" mTemperatureMax = " + mTemperatureMax); pw.println(" mTemperatureDefault = " + mTemperatureDefault); pw.println(" mCurrentColorTemperature = " + mCurrentColorTemperature); pw.println(" mCurrentColorTemperatureXYZ = " + matrixToString(mCurrentColorTemperatureXYZ, 3)); pw.println(" mDisplayColorSpaceRGB RGB-to-XYZ = " + matrixToString(mDisplayColorSpaceRGB.getTransform(), 3)); pw.println(" mChromaticAdaptationMatrix = " + matrixToString(mChromaticAdaptationMatrix, 3)); pw.println(" mDisplayColorSpaceRGB XYZ-to-RGB = " + matrixToString(mDisplayColorSpaceRGB.getInverseTransform(), 3)); pw.println(" mMatrixDisplayWhiteBalance = " + matrixToString(mMatrixDisplayWhiteBalance, 4)); } } }; private final TintController mGlobalSaturationTintController = new TintController() { Loading Loading @@ -230,8 +411,6 @@ public final class ColorDisplayService extends SystemService { private NightDisplayAutoMode mNightDisplayAutoMode; private Integer mDisplayWhiteBalanceColorTemperature; public ColorDisplayService(Context context) { super(context); mHandler = new TintHandler(Looper.getMainLooper()); Loading Loading @@ -363,7 +542,7 @@ public final class ColorDisplayService extends SystemService { onAccessibilityTransformChanged(); break; case Secure.DISPLAY_WHITE_BALANCE_ENABLED: onDisplayWhiteBalanceEnabled(isDisplayWhiteBalanceSettingEnabled()); updateDisplayWhiteBalanceStatus(); break; } } Loading Loading @@ -416,14 +595,9 @@ public final class ColorDisplayService extends SystemService { if (ColorDisplayManager.isDisplayWhiteBalanceAvailable(getContext())) { // Prepare the display white balance transform matrix. mDisplayWhiteBalanceTintController .setUp(getContext(), DisplayTransformManager.needsLinearColorMatrix()); if (mDisplayWhiteBalanceColorTemperature != null) { mDisplayWhiteBalanceTintController .setMatrix(mDisplayWhiteBalanceColorTemperature); } mDisplayWhiteBalanceTintController.setUp(getContext(), true /* needsLinear */); onDisplayWhiteBalanceEnabled(isDisplayWhiteBalanceSettingEnabled()); updateDisplayWhiteBalanceStatus(); } } Loading Loading @@ -460,6 +634,8 @@ public final class ColorDisplayService extends SystemService { mNightDisplayAutoMode.onActivated(activated); } updateDisplayWhiteBalanceStatus(); applyTint(mNightDisplayTintController, false); } } Loading Loading @@ -516,11 +692,7 @@ public final class ColorDisplayService extends SystemService { .setUp(getContext(), DisplayTransformManager.needsLinearColorMatrix(mode)); mNightDisplayTintController.setMatrix(mNightDisplayController.getColorTemperature()); mDisplayWhiteBalanceTintController .setUp(getContext(), DisplayTransformManager.needsLinearColorMatrix(mode)); if (mDisplayWhiteBalanceColorTemperature != null) { mDisplayWhiteBalanceTintController.setMatrix(mDisplayWhiteBalanceColorTemperature); } updateDisplayWhiteBalanceStatus(); final DisplayTransformManager dtm = getLocalService(DisplayTransformManager.class); dtm.setColorMode(mode, mNightDisplayTintController.getMatrix()); Loading Loading @@ -611,10 +783,15 @@ public final class ColorDisplayService extends SystemService { return ldt.isBefore(compareTime) ? ldt.plusDays(1) : ldt; } private void onDisplayWhiteBalanceEnabled(boolean enabled) { mDisplayWhiteBalanceTintController.setActivated(enabled); if (mDisplayWhiteBalanceListener != null) { mDisplayWhiteBalanceListener.onDisplayWhiteBalanceStatusChanged(enabled); private void updateDisplayWhiteBalanceStatus() { boolean oldActivated = mDisplayWhiteBalanceTintController.isActivated(); mDisplayWhiteBalanceTintController.setActivated(isDisplayWhiteBalanceSettingEnabled() && !mNightDisplayTintController.isActivated() && DisplayTransformManager.needsLinearColorMatrix()); boolean activated = mDisplayWhiteBalanceTintController.isActivated(); if (mDisplayWhiteBalanceListener != null && oldActivated != activated) { mDisplayWhiteBalanceListener.onDisplayWhiteBalanceStatusChanged(activated); } } Loading Loading @@ -895,6 +1072,12 @@ public final class ColorDisplayService extends SystemService { return mIsActivated == null; } /** * Dump debug information. */ public void dump(PrintWriter pw) { } /** * Set up any constants needed for computing the matrix. */ Loading Loading @@ -929,11 +1112,10 @@ public final class ColorDisplayService extends SystemService { */ public boolean setDisplayWhiteBalanceColorTemperature(int cct) { // Update the transform matrix even if it can't be applied. mDisplayWhiteBalanceColorTemperature = cct; mDisplayWhiteBalanceTintController.setMatrix(cct); if (mDisplayWhiteBalanceTintController.isActivated()) { applyTint(mDisplayWhiteBalanceTintController, true); applyTint(mDisplayWhiteBalanceTintController, false); return true; } return false; Loading @@ -946,6 +1128,10 @@ public final class ColorDisplayService extends SystemService { mDisplayWhiteBalanceListener = listener; return mDisplayWhiteBalanceTintController.isActivated(); } public void dump(PrintWriter pw) { mDisplayWhiteBalanceTintController.dump(pw); } } /** Loading
services/core/java/com/android/server/display/DisplayManagerService.java +8 −0 Original line number Diff line number Diff line Loading @@ -95,6 +95,7 @@ import com.android.server.SystemService; import com.android.server.UiThread; import com.android.server.wm.SurfaceAnimationThread; import com.android.server.wm.WindowManagerInternal; import com.android.server.display.ColorDisplayService.ColorDisplayServiceInternal; import java.io.FileDescriptor; import java.io.PrintWriter; Loading Loading @@ -1459,6 +1460,13 @@ public final class DisplayManagerService extends SystemService { pw.println(); mPersistentDataStore.dump(pw); final ColorDisplayServiceInternal cds = LocalServices.getService( ColorDisplayServiceInternal.class); if (cds != null) { pw.println(); cds.dump(pw); } } } Loading