1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.display; 18 19 import android.util.Slog; 20 21 import java.io.PrintWriter; 22 import java.util.Arrays; 23 24 /** 25 * A helper class for handling access to illuminance hysteresis level values. 26 */ 27 public class HysteresisLevels { 28 private static final String TAG = "HysteresisLevels"; 29 30 private static final boolean DEBUG = false; 31 32 private final float[] mBrighteningThresholdsPercentages; 33 private final float[] mDarkeningThresholdsPercentages; 34 private final float[] mBrighteningThresholdLevels; 35 private final float[] mDarkeningThresholdLevels; 36 private final float mMinDarkening; 37 private final float mMinBrightening; 38 39 /** 40 * Creates a {@code HysteresisLevels} object with the given equal-length 41 * float arrays. 42 * @param brighteningThresholdsPercentages 0-100 of thresholds 43 * @param darkeningThresholdsPercentages 0-100 of thresholds 44 * @param brighteningThresholdLevels float array of brightness values in the relevant units 45 * @param minBrighteningThreshold the minimum value for which the brightening value needs to 46 * return. 47 * @param minDarkeningThreshold the minimum value for which the darkening value needs to return. 48 * @param potentialOldBrightnessRange whether or not the values used could be from the old 49 * screen brightness range ie, between 1-255. 50 */ HysteresisLevels(float[] brighteningThresholdsPercentages, float[] darkeningThresholdsPercentages, float[] brighteningThresholdLevels, float[] darkeningThresholdLevels, float minDarkeningThreshold, float minBrighteningThreshold, boolean potentialOldBrightnessRange)51 HysteresisLevels(float[] brighteningThresholdsPercentages, 52 float[] darkeningThresholdsPercentages, 53 float[] brighteningThresholdLevels, float[] darkeningThresholdLevels, 54 float minDarkeningThreshold, float minBrighteningThreshold, 55 boolean potentialOldBrightnessRange) { 56 if (brighteningThresholdsPercentages.length != brighteningThresholdLevels.length 57 || darkeningThresholdsPercentages.length != darkeningThresholdLevels.length) { 58 throw new IllegalArgumentException("Mismatch between hysteresis array lengths."); 59 } 60 mBrighteningThresholdsPercentages = 61 setArrayFormat(brighteningThresholdsPercentages, 100.0f); 62 mDarkeningThresholdsPercentages = 63 setArrayFormat(darkeningThresholdsPercentages, 100.0f); 64 mBrighteningThresholdLevels = setArrayFormat(brighteningThresholdLevels, 1.0f); 65 mDarkeningThresholdLevels = setArrayFormat(darkeningThresholdLevels, 1.0f); 66 mMinDarkening = minDarkeningThreshold; 67 mMinBrightening = minBrighteningThreshold; 68 } 69 HysteresisLevels(float[] brighteningThresholdsPercentages, float[] darkeningThresholdsPercentages, float[] brighteningThresholdLevels, float[] darkeningThresholdLevels, float minDarkeningThreshold, float minBrighteningThreshold)70 HysteresisLevels(float[] brighteningThresholdsPercentages, 71 float[] darkeningThresholdsPercentages, 72 float[] brighteningThresholdLevels, float[] darkeningThresholdLevels, 73 float minDarkeningThreshold, float minBrighteningThreshold) { 74 this(brighteningThresholdsPercentages, darkeningThresholdsPercentages, 75 brighteningThresholdLevels, darkeningThresholdLevels, minDarkeningThreshold, 76 minBrighteningThreshold, false); 77 } 78 79 /** 80 * Return the brightening hysteresis threshold for the given value level. 81 */ getBrighteningThreshold(float value)82 public float getBrighteningThreshold(float value) { 83 final float brightConstant = getReferenceLevel(value, 84 mBrighteningThresholdLevels, mBrighteningThresholdsPercentages); 85 86 float brightThreshold = value * (1.0f + brightConstant); 87 if (DEBUG) { 88 Slog.d(TAG, "bright hysteresis constant=" + brightConstant + ", threshold=" 89 + brightThreshold + ", value=" + value); 90 } 91 92 brightThreshold = Math.max(brightThreshold, value + mMinBrightening); 93 return brightThreshold; 94 } 95 96 /** 97 * Return the darkening hysteresis threshold for the given value level. 98 */ getDarkeningThreshold(float value)99 public float getDarkeningThreshold(float value) { 100 final float darkConstant = getReferenceLevel(value, 101 mDarkeningThresholdLevels, mDarkeningThresholdsPercentages); 102 float darkThreshold = value * (1.0f - darkConstant); 103 if (DEBUG) { 104 Slog.d(TAG, "dark hysteresis constant=: " + darkConstant + ", threshold=" 105 + darkThreshold + ", value=" + value); 106 } 107 darkThreshold = Math.min(darkThreshold, value - mMinDarkening); 108 return Math.max(darkThreshold, 0.0f); 109 } 110 111 /** 112 * Return the hysteresis constant for the closest threshold value from the given array. 113 */ getReferenceLevel(float value, float[] thresholdLevels, float[] thresholdPercentages)114 private float getReferenceLevel(float value, float[] thresholdLevels, 115 float[] thresholdPercentages) { 116 if (thresholdLevels == null || thresholdLevels.length == 0 || value < thresholdLevels[0]) { 117 return 0.0f; 118 } 119 int index = 0; 120 while (index < thresholdLevels.length - 1 && value >= thresholdLevels[index + 1]) { 121 index++; 122 } 123 return thresholdPercentages[index]; 124 } 125 126 /** 127 * Return a float array where each i-th element equals {@code configArray[i]/divideFactor}. 128 */ setArrayFormat(float[] configArray, float divideFactor)129 private float[] setArrayFormat(float[] configArray, float divideFactor) { 130 float[] levelArray = new float[configArray.length]; 131 for (int index = 0; levelArray.length > index; ++index) { 132 levelArray[index] = configArray[index] / divideFactor; 133 } 134 return levelArray; 135 } 136 dump(PrintWriter pw)137 void dump(PrintWriter pw) { 138 pw.println("HysteresisLevels"); 139 pw.println(" mBrighteningThresholdLevels=" + Arrays.toString(mBrighteningThresholdLevels)); 140 pw.println(" mBrighteningThresholdsPercentages=" 141 + Arrays.toString(mBrighteningThresholdsPercentages)); 142 pw.println(" mMinBrightening=" + mMinBrightening); 143 pw.println(" mDarkeningThresholdLevels=" + Arrays.toString(mDarkeningThresholdLevels)); 144 pw.println(" mDarkeningThresholdsPercentages=" 145 + Arrays.toString(mDarkeningThresholdsPercentages)); 146 pw.println(" mMinDarkening=" + mMinDarkening); 147 } 148 } 149