blob: f0a505d4d8183b8c4091d833d6f32712bd2b9b0f [file] [log] [blame]
Julius D'souza428aed02016-08-07 19:08:30 -07001/*
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
17package com.android.server.display;
18
19import android.util.Slog;
20
Santos Cordon64a86272019-11-28 11:24:21 +000021import com.android.internal.annotations.VisibleForTesting;
22
Michael Wright2155bc22018-05-01 00:38:32 +010023import java.io.PrintWriter;
24import java.util.Arrays;
25
Julius D'souza428aed02016-08-07 19:08:30 -070026/**
27 * A helper class for handling access to illuminance hysteresis level values.
28 */
Santos Cordon64a86272019-11-28 11:24:21 +000029@VisibleForTesting
30public class HysteresisLevels {
Julius D'souza428aed02016-08-07 19:08:30 -070031 private static final String TAG = "HysteresisLevels";
32
33 // Default hysteresis constraints for brightening or darkening.
Dan Gittiked958e92018-11-13 14:58:20 +000034 // The recent value must have changed by at least this fraction relative to the
35 // current value before a change will be considered.
Julius D'souza428aed02016-08-07 19:08:30 -070036 private static final float DEFAULT_BRIGHTENING_HYSTERESIS = 0.10f;
37 private static final float DEFAULT_DARKENING_HYSTERESIS = 0.20f;
38
39 private static final boolean DEBUG = false;
40
Dan Gittiked958e92018-11-13 14:58:20 +000041 private final float[] mBrighteningThresholds;
42 private final float[] mDarkeningThresholds;
43 private final float[] mThresholdLevels;
Julius D'souza428aed02016-08-07 19:08:30 -070044
Dan Gittiked958e92018-11-13 14:58:20 +000045 /**
46 * Creates a {@code HysteresisLevels} object with the given equal-length
47 * integer arrays.
48 * @param brighteningThresholds an array of brightening hysteresis constraint constants.
49 * @param darkeningThresholds an array of darkening hysteresis constraint constants.
50 * @param thresholdLevels a monotonically increasing array of threshold levels.
51 */
52 HysteresisLevels(int[] brighteningThresholds, int[] darkeningThresholds,
53 int[] thresholdLevels) {
54 if (brighteningThresholds.length != darkeningThresholds.length
55 || darkeningThresholds.length != thresholdLevels.length + 1) {
Julius D'souza428aed02016-08-07 19:08:30 -070056 throw new IllegalArgumentException("Mismatch between hysteresis array lengths.");
57 }
Dan Gittiked958e92018-11-13 14:58:20 +000058 mBrighteningThresholds = setArrayFormat(brighteningThresholds, 1000.0f);
59 mDarkeningThresholds = setArrayFormat(darkeningThresholds, 1000.0f);
60 mThresholdLevels = setArrayFormat(thresholdLevels, 1.0f);
Julius D'souza428aed02016-08-07 19:08:30 -070061 }
62
63 /**
Dan Gittiked958e92018-11-13 14:58:20 +000064 * Return the brightening hysteresis threshold for the given value level.
Julius D'souza428aed02016-08-07 19:08:30 -070065 */
Santos Cordon64a86272019-11-28 11:24:21 +000066 public float getBrighteningThreshold(float value) {
Dan Gittiked958e92018-11-13 14:58:20 +000067 float brightConstant = getReferenceLevel(value, mBrighteningThresholds);
68 float brightThreshold = value * (1.0f + brightConstant);
Julius D'souza428aed02016-08-07 19:08:30 -070069 if (DEBUG) {
Dan Gittiked958e92018-11-13 14:58:20 +000070 Slog.d(TAG, "bright hysteresis constant=" + brightConstant + ", threshold="
71 + brightThreshold + ", value=" + value);
Julius D'souza428aed02016-08-07 19:08:30 -070072 }
73 return brightThreshold;
74 }
75
76 /**
Dan Gittiked958e92018-11-13 14:58:20 +000077 * Return the darkening hysteresis threshold for the given value level.
Julius D'souza428aed02016-08-07 19:08:30 -070078 */
Santos Cordon64a86272019-11-28 11:24:21 +000079 public float getDarkeningThreshold(float value) {
Dan Gittiked958e92018-11-13 14:58:20 +000080 float darkConstant = getReferenceLevel(value, mDarkeningThresholds);
81 float darkThreshold = value * (1.0f - darkConstant);
Julius D'souza428aed02016-08-07 19:08:30 -070082 if (DEBUG) {
83 Slog.d(TAG, "dark hysteresis constant=: " + darkConstant + ", threshold="
Dan Gittiked958e92018-11-13 14:58:20 +000084 + darkThreshold + ", value=" + value);
Julius D'souza428aed02016-08-07 19:08:30 -070085 }
86 return darkThreshold;
87 }
88
89 /**
Dan Gittiked958e92018-11-13 14:58:20 +000090 * Return the hysteresis constant for the closest threshold value from the given array.
Julius D'souza428aed02016-08-07 19:08:30 -070091 */
Dan Gittiked958e92018-11-13 14:58:20 +000092 private float getReferenceLevel(float value, float[] referenceLevels) {
Julius D'souza428aed02016-08-07 19:08:30 -070093 int index = 0;
Dan Gittiked958e92018-11-13 14:58:20 +000094 while (mThresholdLevels.length > index && value >= mThresholdLevels[index]) {
Julius D'souza428aed02016-08-07 19:08:30 -070095 ++index;
96 }
97 return referenceLevels[index];
98 }
99
100 /**
101 * Return a float array where each i-th element equals {@code configArray[i]/divideFactor}.
102 */
103 private float[] setArrayFormat(int[] configArray, float divideFactor) {
104 float[] levelArray = new float[configArray.length];
105 for (int index = 0; levelArray.length > index; ++index) {
106 levelArray[index] = (float)configArray[index] / divideFactor;
107 }
108 return levelArray;
109 }
Michael Wright2155bc22018-05-01 00:38:32 +0100110
Dan Gittiked958e92018-11-13 14:58:20 +0000111 void dump(PrintWriter pw) {
Michael Wright2155bc22018-05-01 00:38:32 +0100112 pw.println("HysteresisLevels");
Dan Gittiked958e92018-11-13 14:58:20 +0000113 pw.println(" mBrighteningThresholds=" + Arrays.toString(mBrighteningThresholds));
114 pw.println(" mDarkeningThresholds=" + Arrays.toString(mDarkeningThresholds));
115 pw.println(" mThresholdLevels=" + Arrays.toString(mThresholdLevels));
Michael Wright2155bc22018-05-01 00:38:32 +0100116 }
Julius D'souza428aed02016-08-07 19:08:30 -0700117}