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 /** 22 * A helper class for handling access to illuminance hysteresis level values. 23 */ 24 final class HysteresisLevels { 25 private static final String TAG = "HysteresisLevels"; 26 27 // Default hysteresis constraints for brightening or darkening. 28 // The recent lux must have changed by at least this fraction relative to the 29 // current ambient lux before a change will be considered. 30 private static final float DEFAULT_BRIGHTENING_HYSTERESIS = 0.10f; 31 private static final float DEFAULT_DARKENING_HYSTERESIS = 0.20f; 32 33 private static final boolean DEBUG = false; 34 35 private final float[] mBrightLevels; 36 private final float[] mDarkLevels; 37 private final float[] mLuxLevels; 38 39 /** 40 * Creates a {@code HysteresisLevels} object with the given equal-length 41 * integer arrays. 42 * @param brightLevels an array of brightening hysteresis constraint constants 43 * @param darkLevels an array of darkening hysteresis constraint constants 44 * @param luxLevels a monotonically increasing array of illuminance 45 * thresholds in units of lux 46 */ 47 public HysteresisLevels(int[] brightLevels, int[] darkLevels, int[] luxLevels) { 48 if (brightLevels.length != darkLevels.length || darkLevels.length != luxLevels.length + 1) { 49 throw new IllegalArgumentException("Mismatch between hysteresis array lengths."); 50 } 51 mBrightLevels = setArrayFormat(brightLevels, 1000.0f); 52 mDarkLevels = setArrayFormat(darkLevels, 1000.0f); 53 mLuxLevels = setArrayFormat(luxLevels, 1.0f); 54 } 55 56 /** 57 * Return the brightening hysteresis threshold for the given lux level. 58 */ 59 public float getBrighteningThreshold(float lux) { 60 float brightConstant = getReferenceLevel(lux, mBrightLevels); 61 float brightThreshold = lux * (1.0f + brightConstant); 62 if (DEBUG) { 63 Slog.d(TAG, "bright hysteresis constant=: " + brightConstant + ", threshold=" 64 + brightThreshold + ", lux=" + lux); 65 } 66 return brightThreshold; 67 } 68 69 /** 70 * Return the darkening hysteresis threshold for the given lux level. 71 */ 72 public float getDarkeningThreshold(float lux) { 73 float darkConstant = getReferenceLevel(lux, mDarkLevels); 74 float darkThreshold = lux * (1.0f - darkConstant); 75 if (DEBUG) { 76 Slog.d(TAG, "dark hysteresis constant=: " + darkConstant + ", threshold=" 77 + darkThreshold + ", lux=" + lux); 78 } 79 return darkThreshold; 80 } 81 82 /** 83 * Return the hysteresis constant for the closest lux threshold value to the 84 * current illuminance from the given array. 85 */ 86 private float getReferenceLevel(float lux, float[] referenceLevels) { 87 int index = 0; 88 while (mLuxLevels.length > index && lux >= mLuxLevels[index]) { 89 ++index; 90 } 91 return referenceLevels[index]; 92 } 93 94 /** 95 * Return a float array where each i-th element equals {@code configArray[i]/divideFactor}. 96 */ 97 private float[] setArrayFormat(int[] configArray, float divideFactor) { 98 float[] levelArray = new float[configArray.length]; 99 for (int index = 0; levelArray.length > index; ++index) { 100 levelArray[index] = (float)configArray[index] / divideFactor; 101 } 102 return levelArray; 103 } 104 } 105