Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Skip to content
Snippets Groups Projects
Commit 7119e99d authored by Christine Franks's avatar Christine Franks
Browse files

Split global saturation into a dedicated helper

Bug: 124474236
Test: atest FrameworksServicesTests:GlobalSaturationTintControllerTest

Change-Id: Ib70f84a917b3ce370b146f40cebbaa570574da47
parent 9ba5e8e4
Branches
No related tags found
No related merge requests found
...@@ -26,7 +26,6 @@ import static android.hardware.display.ColorDisplayManager.COLOR_MODE_SATURATED; ...@@ -26,7 +26,6 @@ import static android.hardware.display.ColorDisplayManager.COLOR_MODE_SATURATED;
import static com.android.server.display.color.DisplayTransformManager.LEVEL_COLOR_MATRIX_DISPLAY_WHITE_BALANCE; import static com.android.server.display.color.DisplayTransformManager.LEVEL_COLOR_MATRIX_DISPLAY_WHITE_BALANCE;
import static com.android.server.display.color.DisplayTransformManager.LEVEL_COLOR_MATRIX_NIGHT_DISPLAY; import static com.android.server.display.color.DisplayTransformManager.LEVEL_COLOR_MATRIX_NIGHT_DISPLAY;
import static com.android.server.display.color.DisplayTransformManager.LEVEL_COLOR_MATRIX_SATURATION;
import android.Manifest; import android.Manifest;
import android.animation.Animator; import android.animation.Animator;
...@@ -88,19 +87,13 @@ import java.time.LocalDateTime; ...@@ -88,19 +87,13 @@ import java.time.LocalDateTime;
import java.time.LocalTime; import java.time.LocalTime;
import java.time.ZoneId; import java.time.ZoneId;
import java.time.format.DateTimeParseException; import java.time.format.DateTimeParseException;
import java.util.Arrays;
/** /**
* Controls the display's color transforms. * Controls the display's color transforms.
*/ */
public final class ColorDisplayService extends SystemService { public final class ColorDisplayService extends SystemService {
private static final String TAG = "ColorDisplayService"; static final String TAG = "ColorDisplayService";
/**
* The transition time, in milliseconds, for Night Display to turn on/off.
*/
private static final long TRANSITION_DURATION = 3000L;
/** /**
* The identity matrix, used if one of the given matrices is {@code null}. * The identity matrix, used if one of the given matrices is {@code null}.
...@@ -111,6 +104,11 @@ public final class ColorDisplayService extends SystemService { ...@@ -111,6 +104,11 @@ public final class ColorDisplayService extends SystemService {
Matrix.setIdentityM(MATRIX_IDENTITY, 0); Matrix.setIdentityM(MATRIX_IDENTITY, 0);
} }
/**
* The transition time, in milliseconds, for Night Display to turn on/off.
*/
private static final long TRANSITION_DURATION = 3000L;
private static final int MSG_APPLY_NIGHT_DISPLAY_IMMEDIATE = 0; private static final int MSG_APPLY_NIGHT_DISPLAY_IMMEDIATE = 0;
private static final int MSG_APPLY_NIGHT_DISPLAY_ANIMATED = 1; private static final int MSG_APPLY_NIGHT_DISPLAY_ANIMATED = 1;
private static final int MSG_APPLY_GLOBAL_SATURATION = 2; private static final int MSG_APPLY_GLOBAL_SATURATION = 2;
...@@ -133,59 +131,8 @@ public final class ColorDisplayService extends SystemService { ...@@ -133,59 +131,8 @@ public final class ColorDisplayService extends SystemService {
final DisplayWhiteBalanceTintController mDisplayWhiteBalanceTintController = final DisplayWhiteBalanceTintController mDisplayWhiteBalanceTintController =
new DisplayWhiteBalanceTintController(); new DisplayWhiteBalanceTintController();
private final TintController mGlobalSaturationTintController = new TintController() { private final TintController mGlobalSaturationTintController =
new GlobalSaturationTintController();
private float[] mMatrixGlobalSaturation = new float[16];
@Override
public void setUp(Context context, boolean needsLinear) {
}
@Override
public float[] getMatrix() {
return Arrays.copyOf(mMatrixGlobalSaturation, mMatrixGlobalSaturation.length);
}
@Override
public void setMatrix(int saturationLevel) {
if (saturationLevel < 0) {
saturationLevel = 0;
} else if (saturationLevel > 100) {
saturationLevel = 100;
}
Slog.d(TAG, "Setting saturation level: " + saturationLevel);
if (saturationLevel == 100) {
setActivated(false);
Matrix.setIdentityM(mMatrixGlobalSaturation, 0);
} else {
setActivated(true);
float saturation = saturationLevel * 0.1f;
float desaturation = 1.0f - saturation;
float[] luminance = {0.231f * desaturation, 0.715f * desaturation,
0.072f * desaturation};
mMatrixGlobalSaturation[0] = luminance[0] + saturation;
mMatrixGlobalSaturation[1] = luminance[0];
mMatrixGlobalSaturation[2] = luminance[0];
mMatrixGlobalSaturation[4] = luminance[1];
mMatrixGlobalSaturation[5] = luminance[1] + saturation;
mMatrixGlobalSaturation[6] = luminance[1];
mMatrixGlobalSaturation[8] = luminance[2];
mMatrixGlobalSaturation[9] = luminance[2];
mMatrixGlobalSaturation[10] = luminance[2] + saturation;
}
}
@Override
public int getLevel() {
return LEVEL_COLOR_MATRIX_SATURATION;
}
@Override
public boolean isAvailable(Context context) {
return ColorDisplayManager.isColorTransformAccelerated(context);
}
};
/** /**
* Matrix and offset used for converting color to grayscale. * Matrix and offset used for converting color to grayscale.
...@@ -1084,82 +1031,6 @@ public final class ColorDisplayService extends SystemService { ...@@ -1084,82 +1031,6 @@ public final class ColorDisplayService extends SystemService {
} }
} }
private abstract static class TintController {
private ValueAnimator mAnimator;
private Boolean mIsActivated;
public ValueAnimator getAnimator() {
return mAnimator;
}
public void setAnimator(ValueAnimator animator) {
mAnimator = animator;
}
/**
* Cancel the animator if it's still running.
*/
public void cancelAnimator() {
if (mAnimator != null) {
mAnimator.cancel();
}
}
/**
* End the animator if it's still running, jumping to the end state.
*/
public void endAnimator() {
if (mAnimator != null) {
mAnimator.end();
mAnimator = null;
}
}
public void setActivated(Boolean isActivated) {
mIsActivated = isActivated;
}
public boolean isActivated() {
return mIsActivated != null && mIsActivated;
}
public boolean isActivatedStateNotSet() {
return mIsActivated == null;
}
/**
* Dump debug information.
*/
public void dump(PrintWriter pw) {
}
/**
* Set up any constants needed for computing the matrix.
*/
public abstract void setUp(Context context, boolean needsLinear);
/**
* Sets the 4x4 matrix to apply.
*/
public abstract void setMatrix(int value);
/**
* Get the 4x4 matrix to apply.
*/
public abstract float[] getMatrix();
/**
* Get the color transform level to apply the matrix.
*/
public abstract int getLevel();
/**
* Returns whether or not this transform type is available on this device.
*/
public abstract boolean isAvailable(Context context);
}
private final class NightDisplayTintController extends TintController { private final class NightDisplayTintController extends TintController {
private final float[] mMatrix = new float[16]; private final float[] mMatrix = new float[16];
......
/*
* Copyright (C) 2019 The Android Open Source 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 com.android.server.display.color;
import static com.android.server.display.color.DisplayTransformManager.LEVEL_COLOR_MATRIX_SATURATION;
import android.content.Context;
import android.hardware.display.ColorDisplayManager;
import android.opengl.Matrix;
import android.util.Slog;
import java.util.Arrays;
/** Control the color transform for global device saturation. */
public class GlobalSaturationTintController extends TintController {
private final float[] mMatrixGlobalSaturation = new float[16];
@Override
public void setUp(Context context, boolean needsLinear) {
}
@Override
public float[] getMatrix() {
return Arrays.copyOf(mMatrixGlobalSaturation, mMatrixGlobalSaturation.length);
}
@Override
public void setMatrix(int saturationLevel) {
if (saturationLevel < 0) {
saturationLevel = 0;
} else if (saturationLevel > 100) {
saturationLevel = 100;
}
Slog.d(ColorDisplayService.TAG, "Setting saturation level: " + saturationLevel);
if (saturationLevel == 100) {
setActivated(false);
Matrix.setIdentityM(mMatrixGlobalSaturation, 0);
} else {
setActivated(true);
float saturation = saturationLevel * 0.01f;
float desaturation = 1.0f - saturation;
float[] luminance = {0.231f * desaturation, 0.715f * desaturation,
0.072f * desaturation};
mMatrixGlobalSaturation[0] = luminance[0] + saturation;
mMatrixGlobalSaturation[1] = luminance[0];
mMatrixGlobalSaturation[2] = luminance[0];
mMatrixGlobalSaturation[4] = luminance[1];
mMatrixGlobalSaturation[5] = luminance[1] + saturation;
mMatrixGlobalSaturation[6] = luminance[1];
mMatrixGlobalSaturation[8] = luminance[2];
mMatrixGlobalSaturation[9] = luminance[2];
mMatrixGlobalSaturation[10] = luminance[2] + saturation;
}
}
@Override
public int getLevel() {
return LEVEL_COLOR_MATRIX_SATURATION;
}
@Override
public boolean isAvailable(Context context) {
return ColorDisplayManager.isColorTransformAccelerated(context);
}
}
/*
* Copyright (C) 2019 The Android Open Source 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 com.android.server.display.color;
import android.animation.ValueAnimator;
import android.content.Context;
import java.io.PrintWriter;
abstract class TintController {
private ValueAnimator mAnimator;
private Boolean mIsActivated;
public ValueAnimator getAnimator() {
return mAnimator;
}
public void setAnimator(ValueAnimator animator) {
mAnimator = animator;
}
/**
* Cancel the animator if it's still running.
*/
public void cancelAnimator() {
if (mAnimator != null) {
mAnimator.cancel();
}
}
/**
* End the animator if it's still running, jumping to the end state.
*/
public void endAnimator() {
if (mAnimator != null) {
mAnimator.end();
mAnimator = null;
}
}
public void setActivated(Boolean isActivated) {
mIsActivated = isActivated;
}
public boolean isActivated() {
return mIsActivated != null && mIsActivated;
}
public boolean isActivatedStateNotSet() {
return mIsActivated == null;
}
/**
* Dump debug information.
*/
public void dump(PrintWriter pw) {
}
/**
* Set up any constants needed for computing the matrix.
*/
public abstract void setUp(Context context, boolean needsLinear);
/**
* Sets the 4x4 matrix to apply.
*/
public abstract void setMatrix(int value);
/**
* Get the 4x4 matrix to apply.
*/
public abstract float[] getMatrix();
/**
* Get the color transform level to apply the matrix.
*/
public abstract int getLevel();
/**
* Returns whether or not this transform type is available on this device.
*/
public abstract boolean isAvailable(Context context);
}
/*
* Copyright (C) 2019 The Android Open Source 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 com.android.server.display.color;
import static com.google.common.truth.Truth.assertThat;
import android.opengl.Matrix;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class GlobalSaturationTintControllerTest {
@Test
public void setAndGetMatrix() {
final GlobalSaturationTintController tintController = new GlobalSaturationTintController();
tintController.setMatrix(50);
assertThat(tintController.getMatrix()).hasValuesWithin(0.00001f)
.of(new float[]{0.6155f, 0.1155f, 0.1155f, 0.0f, 0.3575f, 0.85749996f, 0.3575f,
0.0f, 0.036f, 0.036f, 0.536f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f});
}
@Test
public void resetMatrix() {
final GlobalSaturationTintController tintController = new GlobalSaturationTintController();
tintController.setMatrix(100);
final float[] matrix = new float[16];
Matrix.setIdentityM(matrix, 0);
assertThat(tintController.getMatrix()).hasValuesWithin(0.00001f).of(matrix);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment