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

Commit 34737365 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Added hysteresis check to screen brightness."

parents c698e729 ed958e98
Loading
Loading
Loading
Loading
+62 −28
Original line number Diff line number Diff line
@@ -1437,26 +1437,6 @@
    <integer-array name="config_autoBrightnessKeyboardBacklightValues">
    </integer-array>

    <!-- Array of hysteresis constraint values for brightening, represented as tenths of a
         percent. The length of this array is assumed to be one greater than
         config_dynamicHysteresisLuxLevels. The brightening threshold is calculated as
         lux * (1.0f + CONSTRAINT_VALUE). When the current lux is higher than this threshold,
         the screen brightness is recalculated. See the config_dynamicHysteresisLuxLevels
         description for how the constraint value is chosen. -->
    <integer-array name="config_dynamicHysteresisBrightLevels">
        <item>100</item>
    </integer-array>

    <!-- Array of hysteresis constraint values for darkening, represented as tenths of a
         percent. The length of this array is assumed to be one greater than
         config_dynamicHysteresisLuxLevels. The darkening threshold is calculated as
         lux * (1.0f - CONSTRAINT_VALUE). When the current lux is lower than this threshold,
         the screen brightness is recalculated. See the config_dynamicHysteresisLuxLevels
         description for how the constraint value is chosen. -->
    <integer-array name="config_dynamicHysteresisDarkLevels">
        <item>200</item>
    </integer-array>

    <!-- An array describing the screen's backlight values corresponding to the brightness
         values in the config_screenBrightnessNits array.

@@ -1474,19 +1454,73 @@
    <array name="config_screenBrightnessNits">
    </array>


    <!-- Array of ambient lux threshold values. This is used for determining hysteresis constraint
         values by calculating the index to use for lookup and then setting the constraint value
         to the corresponding value of the array. The new brightening hysteresis constraint value
         is the n-th element of config_dynamicHysteresisBrightLevels, and the new darkening
         hysteresis constraint value is the n-th element of config_dynamicHysteresisDarkLevels.
         is the n-th element of config_ambientBrighteningThresholds, and the new darkening
         hysteresis constraint value is the n-th element of config_ambientDarkeningThresholds.

         The (zero-based) index is calculated as follows: (MAX is the largest index of the array)
         condition                       calculated index
         value < level[0]                0
         level[n] <= value < level[n+1]  n+1
         level[MAX] <= value             MAX+1 -->
    <integer-array name="config_ambientThresholdLevels">
    </integer-array>

    <!-- Array of hysteresis constraint values for brightening, represented as tenths of a
         percent. The length of this array is assumed to be one greater than
         config_ambientThresholdLevels. The brightening threshold is calculated as
         lux * (1.0f + CONSTRAINT_VALUE). When the current lux is higher than this threshold,
         the screen brightness is recalculated. See the config_ambientThresholdLevels
         description for how the constraint value is chosen. -->
    <integer-array name="config_ambientBrighteningThresholds">
        <item>100</item>
    </integer-array>

    <!-- Array of hysteresis constraint values for darkening, represented as tenths of a
         percent. The length of this array is assumed to be one greater than
         config_ambientThresholdLevels. The darkening threshold is calculated as
         lux * (1.0f - CONSTRAINT_VALUE). When the current lux is lower than this threshold,
         the screen brightness is recalculated. See the config_ambientThresholdLevels
         description for how the constraint value is chosen. -->
    <integer-array name="config_ambientDarkeningThresholds">
        <item>200</item>
    </integer-array>

    <!-- Array of screen brightness threshold values. This is used for determining hysteresis
         constraint values by calculating the index to use for lookup and then setting the
         constraint value to the corresponding value of the array. The new brightening hysteresis
         constraint value is the n-th element of config_screenBrighteningThresholds, and the new
         darkening hysteresis constraint value is the n-th element of
         config_screenDarkeningThresholds.

         The (zero-based) index is calculated as follows: (MAX is the largest index of the array)
         condition                       calculated index
         value < lux[0]                 0
         lux[n] <= value < lux[n+1]     n+1
         lux[MAX] <= value              MAX+1 -->
    <integer-array name="config_dynamicHysteresisLuxLevels">
         value < level[0]                0
         level[n] <= value < level[n+1]  n+1
         level[MAX] <= value             MAX+1 -->
    <integer-array name="config_screenThresholdLevels">
    </integer-array>

    <!-- Array of hysteresis constraint values for brightening, represented as tenths of a
         percent. The length of this array is assumed to be one greater than
         config_screenThresholdLevels. The brightening threshold is calculated as
         screenBrightness * (1.0f + CONSTRAINT_VALUE). When the new screen brightness is higher
         than this threshold, it is applied. See the config_screenThresholdLevels description for
         how the constraint value is chosen. -->
    <integer-array name="config_screenBrighteningThresholds">
        <item>100</item>
    </integer-array>
 
    <!-- Array of hysteresis constraint values for darkening, represented as tenths of a
         percent. The length of this array is assumed to be one greater than
         config_screenThresholdLevels. The darkening threshold is calculated as
         screenBrightness * (1.0f - CONSTRAINT_VALUE). When the new screen brightness is lower than
         this threshold, it is applied. See the config_screenThresholdLevels description for how
         the constraint value is chosen. -->
    <integer-array name="config_screenDarkeningThresholds">
        <item>200</item>
    </integer-array>

    <!-- Amount of time it takes for the light sensor to warm up in milliseconds.
+6 −3
Original line number Diff line number Diff line
@@ -1829,9 +1829,12 @@
  <java-symbol type="array" name="config_autoBrightnessKeyboardBacklightValues" />
  <java-symbol type="array" name="config_autoBrightnessLcdBacklightValues" />
  <java-symbol type="array" name="config_autoBrightnessLevels" />
  <java-symbol type="array" name="config_dynamicHysteresisBrightLevels" />
  <java-symbol type="array" name="config_dynamicHysteresisDarkLevels" />
  <java-symbol type="array" name="config_dynamicHysteresisLuxLevels" />
  <java-symbol type="array" name="config_ambientThresholdLevels" />
  <java-symbol type="array" name="config_ambientBrighteningThresholds" />
  <java-symbol type="array" name="config_ambientDarkeningThresholds" />
  <java-symbol type="array" name="config_screenThresholdLevels" />
  <java-symbol type="array" name="config_screenBrighteningThresholds" />
  <java-symbol type="array" name="config_screenDarkeningThresholds" />
  <java-symbol type="array" name="config_minimumBrightnessCurveLux" />
  <java-symbol type="array" name="config_minimumBrightnessCurveNits" />
  <java-symbol type="array" name="config_protectedNetworks" />
+55 −30
Original line number Diff line number Diff line
@@ -16,30 +16,26 @@

package com.android.server.display;

import com.android.server.EventLogTags;
import com.android.server.LocalServices;

import android.annotation.Nullable;
import android.app.ActivityManager;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.hardware.display.BrightnessConfiguration;
import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.os.SystemClock;
import android.os.Trace;
import android.text.format.DateUtils;
import android.util.EventLog;
import android.util.MathUtils;
import android.util.Slog;
import android.util.TimeUtils;

import com.android.server.EventLogTags;

import java.io.PrintWriter;

class AutomaticBrightnessController {
@@ -127,7 +123,8 @@ class AutomaticBrightnessController {
    private final int mWeightingIntercept;

    // Configuration object for determining thresholds to change brightness dynamically
    private final HysteresisLevels mHysteresisLevels;
    private final HysteresisLevels mAmbientBrightnessThresholds;
    private final HysteresisLevels mScreenBrightnessThresholds;

    // Amount of time to delay auto-brightness after screen on while waiting for
    // the light sensor to warm-up in milliseconds.
@@ -147,8 +144,12 @@ class AutomaticBrightnessController {
    private boolean mAmbientLuxValid;

    // The ambient light level threshold at which to brighten or darken the screen.
    private float mBrighteningLuxThreshold;
    private float mDarkeningLuxThreshold;
    private float mAmbientBrighteningThreshold;
    private float mAmbientDarkeningThreshold;

    // The screen brightness threshold at which to brighten or darken the screen.
    private float mScreenBrighteningThreshold;
    private float mScreenDarkeningThreshold;

    // The most recent light sample.
    private float mLastObservedLux;
@@ -196,7 +197,8 @@ class AutomaticBrightnessController {
            int lightSensorWarmUpTime, int brightnessMin, int brightnessMax, float dozeScaleFactor,
            int lightSensorRate, int initialLightSensorRate, long brighteningLightDebounceConfig,
            long darkeningLightDebounceConfig, boolean resetAmbientLuxAfterWarmUpConfig,
            HysteresisLevels hysteresisLevels) {
            HysteresisLevels ambientBrightnessThresholds,
            HysteresisLevels screenBrightnessThresholds) {
        mCallbacks = callbacks;
        mSensorManager = sensorManager;
        mBrightnessMapper = mapper;
@@ -212,7 +214,8 @@ class AutomaticBrightnessController {
        mResetAmbientLuxAfterWarmUpConfig = resetAmbientLuxAfterWarmUpConfig;
        mAmbientLightHorizon = AMBIENT_LIGHT_LONG_HORIZON_MILLIS;
        mWeightingIntercept = AMBIENT_LIGHT_LONG_HORIZON_MILLIS;
        mHysteresisLevels = hysteresisLevels;
        mAmbientBrightnessThresholds = ambientBrightnessThresholds;
        mScreenBrightnessThresholds = screenBrightnessThresholds;
        mShortTermModelValid = true;
        mShortTermModelAnchor = -1;

@@ -364,8 +367,10 @@ class AutomaticBrightnessController {
        pw.println("  mCurrentLightSensorRate=" + mCurrentLightSensorRate);
        pw.println("  mAmbientLux=" + mAmbientLux);
        pw.println("  mAmbientLuxValid=" + mAmbientLuxValid);
        pw.println("  mBrighteningLuxThreshold=" + mBrighteningLuxThreshold);
        pw.println("  mDarkeningLuxThreshold=" + mDarkeningLuxThreshold);
        pw.println("  mAmbientBrighteningThreshold=" + mAmbientBrighteningThreshold);
        pw.println("  mAmbientDarkeningThreshold=" + mAmbientDarkeningThreshold);
        pw.println("  mScreenBrighteningThreshold=" + mScreenBrighteningThreshold);
        pw.println("  mScreenDarkeningThreshold=" + mScreenDarkeningThreshold);
        pw.println("  mLastObservedLux=" + mLastObservedLux);
        pw.println("  mLastObservedLuxTime=" + TimeUtils.formatUptime(mLastObservedLuxTime));
        pw.println("  mRecentLightSamples=" + mRecentLightSamples);
@@ -384,7 +389,8 @@ class AutomaticBrightnessController {
        mBrightnessMapper.dump(pw);

        pw.println();
        mHysteresisLevels.dump(pw);
        mAmbientBrightnessThresholds.dump(pw);
        mScreenBrightnessThresholds.dump(pw);
    }

    private boolean setLightSensorEnabled(boolean enable) {
@@ -460,8 +466,8 @@ class AutomaticBrightnessController {
            lux = 0;
        }
        mAmbientLux = lux;
        mBrighteningLuxThreshold = mHysteresisLevels.getBrighteningThreshold(lux);
        mDarkeningLuxThreshold = mHysteresisLevels.getDarkeningThreshold(lux);
        mAmbientBrighteningThreshold = mAmbientBrightnessThresholds.getBrighteningThreshold(lux);
        mAmbientDarkeningThreshold = mAmbientBrightnessThresholds.getDarkeningThreshold(lux);

        // If the short term model was invalidated and the change is drastic enough, reset it.
        if (!mShortTermModelValid && mShortTermModelAnchor != -1) {
@@ -552,7 +558,7 @@ class AutomaticBrightnessController {
        final int N = mAmbientLightRingBuffer.size();
        long earliestValidTime = time;
        for (int i = N - 1; i >= 0; i--) {
            if (mAmbientLightRingBuffer.getLux(i) <= mBrighteningLuxThreshold) {
            if (mAmbientLightRingBuffer.getLux(i) <= mAmbientBrighteningThreshold) {
                break;
            }
            earliestValidTime = mAmbientLightRingBuffer.getTime(i);
@@ -564,7 +570,7 @@ class AutomaticBrightnessController {
        final int N = mAmbientLightRingBuffer.size();
        long earliestValidTime = time;
        for (int i = N - 1; i >= 0; i--) {
            if (mAmbientLightRingBuffer.getLux(i) >= mDarkeningLuxThreshold) {
            if (mAmbientLightRingBuffer.getLux(i) >= mAmbientDarkeningThreshold) {
                break;
            }
            earliestValidTime = mAmbientLightRingBuffer.getTime(i);
@@ -617,20 +623,19 @@ class AutomaticBrightnessController {
        float slowAmbientLux = calculateAmbientLux(time, AMBIENT_LIGHT_LONG_HORIZON_MILLIS);
        float fastAmbientLux = calculateAmbientLux(time, AMBIENT_LIGHT_SHORT_HORIZON_MILLIS);

        if ((slowAmbientLux >= mBrighteningLuxThreshold &&
             fastAmbientLux >= mBrighteningLuxThreshold &&
             nextBrightenTransition <= time)
             ||
            (slowAmbientLux <= mDarkeningLuxThreshold &&
             fastAmbientLux <= mDarkeningLuxThreshold &&
             nextDarkenTransition <= time)) {
        if ((slowAmbientLux >= mAmbientBrighteningThreshold
                && fastAmbientLux >= mAmbientBrighteningThreshold
                && nextBrightenTransition <= time)
                || (slowAmbientLux <= mAmbientDarkeningThreshold
                        && fastAmbientLux <= mAmbientDarkeningThreshold
                        && nextDarkenTransition <= time)) {
            setAmbientLux(fastAmbientLux);
            if (DEBUG) {
                Slog.d(TAG, "updateAmbientLux: " +
                        ((fastAmbientLux > mAmbientLux) ? "Brightened" : "Darkened") + ": " +
                        "mBrighteningLuxThreshold=" + mBrighteningLuxThreshold + ", " +
                        "mAmbientLightRingBuffer=" + mAmbientLightRingBuffer + ", " +
                        "mAmbientLux=" + mAmbientLux);
                Slog.d(TAG, "updateAmbientLux: "
                        + ((fastAmbientLux > mAmbientLux) ? "Brightened" : "Darkened") + ": "
                        + "mAmbientBrighteningThreshold=" + mAmbientBrighteningThreshold + ", "
                        + "mAmbientLightRingBuffer=" + mAmbientLightRingBuffer + ", "
                        + "mAmbientLux=" + mAmbientLux);
            }
            updateAutoBrightness(true);
            nextBrightenTransition = nextAmbientLightBrighteningTransition(time);
@@ -661,7 +666,22 @@ class AutomaticBrightnessController {

        int newScreenAutoBrightness =
                clampScreenBrightness(Math.round(value * PowerManager.BRIGHTNESS_ON));

        // If screenAutoBrightness is set, we should have screen{Brightening,Darkening}Threshold,
        // in which case we ignore the new screen brightness if it doesn't differ enough from the
        // previous one.
        if (mScreenAutoBrightness != -1
                && newScreenAutoBrightness > mScreenDarkeningThreshold
                && newScreenAutoBrightness < mScreenBrighteningThreshold) {
            if (DEBUG) {
                Slog.d(TAG, "ignoring newScreenAutoBrightness: " + mScreenDarkeningThreshold
                        + " < " + newScreenAutoBrightness + " < " + mScreenBrighteningThreshold);
            }
            return;
        }

        if (mScreenAutoBrightness != newScreenAutoBrightness) {

            if (DEBUG) {
                Slog.d(TAG, "updateAutoBrightness: " +
                        "mScreenAutoBrightness=" + mScreenAutoBrightness + ", " +
@@ -669,6 +689,11 @@ class AutomaticBrightnessController {
            }

            mScreenAutoBrightness = newScreenAutoBrightness;
            mScreenBrighteningThreshold =
                    mScreenBrightnessThresholds.getBrighteningThreshold(newScreenAutoBrightness);
            mScreenDarkeningThreshold =
                    mScreenBrightnessThresholds.getDarkeningThreshold(newScreenAutoBrightness);

            if (sendUpdate) {
                mCallbacks.updateBrightness();
            }
+26 −15
Original line number Diff line number Diff line
@@ -16,16 +16,11 @@

package com.android.server.display;

import android.app.ActivityManager;
import com.android.internal.app.IBatteryStats;
import com.android.server.LocalServices;
import com.android.server.am.BatteryStatsService;
import com.android.server.policy.WindowManagerPolicy;

import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.ParceledListSlice;
import android.content.res.Resources;
@@ -54,6 +49,11 @@ import android.util.Slog;
import android.util.TimeUtils;
import android.view.Display;

import com.android.internal.app.IBatteryStats;
import com.android.server.LocalServices;
import com.android.server.am.BatteryStatsService;
import com.android.server.policy.WindowManagerPolicy;

import java.io.PrintWriter;

/**
@@ -422,14 +422,24 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
                    com.android.internal.R.fraction.config_screenAutoBrightnessDozeScaleFactor,
                    1, 1);

            int[] brightLevels = resources.getIntArray(
                    com.android.internal.R.array.config_dynamicHysteresisBrightLevels);
            int[] darkLevels = resources.getIntArray(
                    com.android.internal.R.array.config_dynamicHysteresisDarkLevels);
            int[] luxHysteresisLevels = resources.getIntArray(
                    com.android.internal.R.array.config_dynamicHysteresisLuxLevels);
            HysteresisLevels hysteresisLevels = new HysteresisLevels(
                    brightLevels, darkLevels, luxHysteresisLevels);
            int[] ambientBrighteningThresholds = resources.getIntArray(
                    com.android.internal.R.array.config_ambientBrighteningThresholds);
            int[] ambientDarkeningThresholds = resources.getIntArray(
                    com.android.internal.R.array.config_ambientDarkeningThresholds);
            int[] ambientThresholdLevels = resources.getIntArray(
                    com.android.internal.R.array.config_ambientThresholdLevels);
            HysteresisLevels ambientBrightnessThresholds = new HysteresisLevels(
                    ambientBrighteningThresholds, ambientDarkeningThresholds,
                    ambientThresholdLevels);

            int[] screenBrighteningThresholds = resources.getIntArray(
                    com.android.internal.R.array.config_screenBrighteningThresholds);
            int[] screenDarkeningThresholds = resources.getIntArray(
                    com.android.internal.R.array.config_screenDarkeningThresholds);
            int[] screenThresholdLevels = resources.getIntArray(
                    com.android.internal.R.array.config_screenThresholdLevels);
            HysteresisLevels screenBrightnessThresholds = new HysteresisLevels(
                    screenBrighteningThresholds, screenDarkeningThresholds, screenThresholdLevels);

            long brighteningLightDebounce = resources.getInteger(
                    com.android.internal.R.integer.config_autoBrightnessBrighteningLightDebounce);
@@ -459,7 +469,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
                        lightSensorWarmUpTimeConfig, mScreenBrightnessRangeMinimum,
                        mScreenBrightnessRangeMaximum, dozeScaleFactor, lightSensorRate,
                        initialLightSensorRate, brighteningLightDebounce, darkeningLightDebounce,
                        autoBrightnessResetAmbientLuxAfterWarmUp, hysteresisLevels);
                        autoBrightnessResetAmbientLuxAfterWarmUp, ambientBrightnessThresholds,
                        screenBrightnessThresholds);
            } else {
                mUseSoftwareAutoBrightnessConfig = false;
            }
+37 −37
Original line number Diff line number Diff line
@@ -28,67 +28,67 @@ final class HysteresisLevels {
    private static final String TAG = "HysteresisLevels";

    // Default hysteresis constraints for brightening or darkening.
    // The recent lux must have changed by at least this fraction relative to the
    // current ambient lux before a change will be considered.
    // The recent value must have changed by at least this fraction relative to the
    // current value before a change will be considered.
    private static final float DEFAULT_BRIGHTENING_HYSTERESIS = 0.10f;
    private static final float DEFAULT_DARKENING_HYSTERESIS = 0.20f;

    private static final boolean DEBUG = false;

    private final float[] mBrightLevels;
    private final float[] mDarkLevels;
    private final float[] mLuxLevels;
    private final float[] mBrighteningThresholds;
    private final float[] mDarkeningThresholds;
    private final float[] mThresholdLevels;

    /**
     * Creates a {@code HysteresisLevels} object with the given equal-length
     * integer arrays.
   * @param brightLevels an array of brightening hysteresis constraint constants
   * @param darkLevels an array of darkening hysteresis constraint constants
   * @param luxLevels a monotonically increasing array of illuminance
   *                  thresholds in units of lux
     * @param brighteningThresholds an array of brightening hysteresis constraint constants.
     * @param darkeningThresholds an array of darkening hysteresis constraint constants.
     * @param thresholdLevels a monotonically increasing array of threshold levels.
    */
    public HysteresisLevels(int[] brightLevels, int[] darkLevels, int[] luxLevels) {
        if (brightLevels.length != darkLevels.length || darkLevels.length != luxLevels.length + 1) {
    HysteresisLevels(int[] brighteningThresholds, int[] darkeningThresholds,
            int[] thresholdLevels) {
        if (brighteningThresholds.length != darkeningThresholds.length
                || darkeningThresholds.length != thresholdLevels.length + 1) {
            throw new IllegalArgumentException("Mismatch between hysteresis array lengths.");
        }
        mBrightLevels = setArrayFormat(brightLevels, 1000.0f);
        mDarkLevels = setArrayFormat(darkLevels, 1000.0f);
        mLuxLevels = setArrayFormat(luxLevels, 1.0f);
        mBrighteningThresholds = setArrayFormat(brighteningThresholds, 1000.0f);
        mDarkeningThresholds = setArrayFormat(darkeningThresholds, 1000.0f);
        mThresholdLevels = setArrayFormat(thresholdLevels, 1.0f);
    }

    /**
     * Return the brightening hysteresis threshold for the given lux level.
     * Return the brightening hysteresis threshold for the given value level.
     */
    public float getBrighteningThreshold(float lux) {
        float brightConstant = getReferenceLevel(lux, mBrightLevels);
        float brightThreshold = lux * (1.0f + brightConstant);
    float getBrighteningThreshold(float value) {
        float brightConstant = getReferenceLevel(value, mBrighteningThresholds);
        float brightThreshold = value * (1.0f + brightConstant);
        if (DEBUG) {
            Slog.d(TAG, "bright hysteresis constant=: " + brightConstant + ", threshold="
                + brightThreshold + ", lux=" + lux);
            Slog.d(TAG, "bright hysteresis constant=" + brightConstant + ", threshold="
                    + brightThreshold + ", value=" + value);
        }
        return brightThreshold;
    }

    /**
     * Return the darkening hysteresis threshold for the given lux level.
     * Return the darkening hysteresis threshold for the given value level.
     */
    public float getDarkeningThreshold(float lux) {
        float darkConstant = getReferenceLevel(lux, mDarkLevels);
        float darkThreshold = lux * (1.0f - darkConstant);
    float getDarkeningThreshold(float value) {
        float darkConstant = getReferenceLevel(value, mDarkeningThresholds);
        float darkThreshold = value * (1.0f - darkConstant);
        if (DEBUG) {
            Slog.d(TAG, "dark hysteresis constant=: " + darkConstant + ", threshold="
                + darkThreshold + ", lux=" + lux);
                    + darkThreshold + ", value=" + value);
        }
        return darkThreshold;
    }

    /**
     * Return the hysteresis constant for the closest lux threshold value to the
     * current illuminance from the given array.
     * Return the hysteresis constant for the closest threshold value from the given array.
     */
    private float getReferenceLevel(float lux, float[] referenceLevels) {
    private float getReferenceLevel(float value, float[] referenceLevels) {
        int index = 0;
        while (mLuxLevels.length > index && lux >= mLuxLevels[index]) {
        while (mThresholdLevels.length > index && value >= mThresholdLevels[index]) {
            ++index;
        }
        return referenceLevels[index];
@@ -105,10 +105,10 @@ final class HysteresisLevels {
        return levelArray;
    }

    public void dump(PrintWriter pw) {
    void dump(PrintWriter pw) {
        pw.println("HysteresisLevels");
        pw.println("  mBrightLevels=" + Arrays.toString(mBrightLevels));
        pw.println("  mDarkLevels=" + Arrays.toString(mDarkLevels));
        pw.println("  mLuxLevels=" + Arrays.toString(mLuxLevels));
        pw.println("  mBrighteningThresholds=" + Arrays.toString(mBrighteningThresholds));
        pw.println("  mDarkeningThresholds=" + Arrays.toString(mDarkeningThresholds));
        pw.println("  mThresholdLevels=" + Arrays.toString(mThresholdLevels));
    }
}