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

Commit 37379498 authored by Rupesh Bansal's avatar Rupesh Bansal
Browse files

Moving BrightnessInfo and BrightnessReason outside of

DisplayPowerController to have the support of declaring the brightness
relevant states in DisplayPowerController agnostic fashion.

We primarily need this because currently DisplayPowerController is
tightly coupled with these classes, even though it is not really in the
realm of DisplayPowerController to evaluate it. In future, the vision
is to have a different class which keeps track of all the changes
happening to the brightness and store them in a RingBuffer(Like we do
today). This is taking it one step closer to that, with more verbose
tests
Bug: 233051797
Test: atest BrightnessEventTest && atest BrightnessReasonTest

Change-Id: I15d47cc669bda1c160f02e205168c7aeee9d6658
parent 0facbc98
Loading
Loading
Loading
Loading
+9 −8
Original line number Diff line number Diff line
@@ -46,7 +46,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.display.BrightnessSynchronizer;
import com.android.internal.os.BackgroundThread;
import com.android.server.EventLogTags;
import com.android.server.display.DisplayPowerController.BrightnessEvent;
import com.android.server.display.brightness.BrightnessEvent;

import java.io.PrintWriter;

@@ -337,14 +337,15 @@ class AutomaticBrightnessController {

    float getAutomaticScreenBrightness(BrightnessEvent brightnessEvent) {
        if (brightnessEvent != null) {
            brightnessEvent.lux =
                    mAmbientLuxValid ? mAmbientLux : PowerManager.BRIGHTNESS_INVALID_FLOAT;
            brightnessEvent.preThresholdLux = mPreThresholdLux;
            brightnessEvent.preThresholdBrightness = mPreThresholdBrightness;
            brightnessEvent.recommendedBrightness = mScreenAutoBrightness;
            brightnessEvent.flags |= (!mAmbientLuxValid ? BrightnessEvent.FLAG_INVALID_LUX : 0)
            brightnessEvent.setLux(
                    mAmbientLuxValid ? mAmbientLux : PowerManager.BRIGHTNESS_INVALID_FLOAT);
            brightnessEvent.setPreThresholdLux(mPreThresholdLux);
            brightnessEvent.setPreThresholdBrightness(mPreThresholdBrightness);
            brightnessEvent.setRecommendedBrightness(mScreenAutoBrightness);
            brightnessEvent.setFlags(brightnessEvent.getFlags()
                    | (!mAmbientLuxValid ? BrightnessEvent.FLAG_INVALID_LUX : 0)
                    | (mDisplayPolicy == DisplayPowerRequest.POLICY_DOZE
                        ? BrightnessEvent.FLAG_DOZE_SCALE : 0);
                        ? BrightnessEvent.FLAG_DOZE_SCALE : 0));
        }

        if (!mAmbientLuxValid) {
+20 −256
Original line number Diff line number Diff line
@@ -67,6 +67,8 @@ import com.android.internal.util.RingBuffer;
import com.android.server.LocalServices;
import com.android.server.am.BatteryStatsService;
import com.android.server.display.RampAnimator.DualRampAnimator;
import com.android.server.display.brightness.BrightnessEvent;
import com.android.server.display.brightness.BrightnessReason;
import com.android.server.display.color.ColorDisplayService.ColorDisplayServiceInternal;
import com.android.server.display.color.ColorDisplayService.ReduceBrightColorsListener;
import com.android.server.display.utils.SensorUtils;
@@ -76,7 +78,6 @@ import com.android.server.display.whitebalance.DisplayWhiteBalanceSettings;
import com.android.server.policy.WindowManagerPolicy;

import java.io.PrintWriter;
import java.util.Objects;

/**
 * Controls the power state of the display.
@@ -1430,7 +1431,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
        // we broadcast this change through setting.
        final float unthrottledBrightnessState = brightnessState;
        if (mBrightnessThrottler.isThrottled()) {
            mTempBrightnessEvent.thermalMax = mBrightnessThrottler.getBrightnessCap();
            mTempBrightnessEvent.setThermalMax(mBrightnessThrottler.getBrightnessCap());
            brightnessState = Math.min(brightnessState, mBrightnessThrottler.getBrightnessCap());
            mBrightnessReasonTemp.addModifier(BrightnessReason.MODIFIER_THROTTLED);
            if (!mAppliedThrottling) {
@@ -1551,8 +1552,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
            // TODO(b/216365040): The decision to prevent HBM for HDR in low power mode should be
            // done in HighBrightnessModeController.
            if (mHbmController.getHighBrightnessMode() == BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR
                    && ((mBrightnessReason.modifier & BrightnessReason.MODIFIER_DIMMED) == 0
                    || (mBrightnessReason.modifier & BrightnessReason.MODIFIER_LOW_POWER) == 0)) {
                    && ((mBrightnessReason.getModifier() & BrightnessReason.MODIFIER_DIMMED) == 0
                    || (mBrightnessReason.getModifier() & BrightnessReason.MODIFIER_LOW_POWER)
                    == 0)) {
                // We want to scale HDR brightness level with the SDR level
                animateValue = mHbmController.getHdrBrightnessValue();
            }
@@ -1615,7 +1617,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
                    + mBrightnessReasonTemp.toString(brightnessAdjustmentFlags)
                    + "', previous reason: '" + mBrightnessReason + "'.");
            mBrightnessReason.set(mBrightnessReasonTemp);
        } else if (mBrightnessReasonTemp.reason == BrightnessReason.REASON_MANUAL
        } else if (mBrightnessReasonTemp.getReason() == BrightnessReason.REASON_MANUAL
                && userSetBrightnessChanged) {
            Slog.v(TAG, "Brightness [" + brightnessState + "] manual adjustment.");
        }
@@ -1624,17 +1626,19 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
        // Log brightness events when a detail of significance has changed. Generally this is the
        // brightness itself changing, but also includes data like HBM cap, thermal throttling
        // brightness cap, RBC state, etc.
        mTempBrightnessEvent.time = System.currentTimeMillis();
        mTempBrightnessEvent.brightness = brightnessState;
        mTempBrightnessEvent.reason.set(mBrightnessReason);
        mTempBrightnessEvent.hbmMax = mHbmController.getCurrentBrightnessMax();
        mTempBrightnessEvent.hbmMode = mHbmController.getHighBrightnessMode();
        mTempBrightnessEvent.flags |= (mIsRbcActive ? BrightnessEvent.FLAG_RBC : 0);
        mTempBrightnessEvent.setTime(System.currentTimeMillis());
        mTempBrightnessEvent.setBrightness(brightnessState);
        mTempBrightnessEvent.setReason(mBrightnessReason);
        mTempBrightnessEvent.setHbmMax(mHbmController.getCurrentBrightnessMax());
        mTempBrightnessEvent.setHbmMode(mHbmController.getHighBrightnessMode());
        mTempBrightnessEvent.setFlags(mTempBrightnessEvent.getFlags()
                | (mIsRbcActive ? BrightnessEvent.FLAG_RBC : 0));
        // Temporary is what we use during slider interactions. We avoid logging those so that
        // we don't spam logcat when the slider is being used.
        boolean tempToTempTransition =
                mTempBrightnessEvent.reason.reason == BrightnessReason.REASON_TEMPORARY
                && mLastBrightnessEvent.reason.reason == BrightnessReason.REASON_TEMPORARY;
                mTempBrightnessEvent.getReason().getReason() == BrightnessReason.REASON_TEMPORARY
                && mLastBrightnessEvent.getReason().getReason()
                        == BrightnessReason.REASON_TEMPORARY;
        if ((!mTempBrightnessEvent.equalsMainData(mLastBrightnessEvent) && !tempToTempTransition)
                || brightnessAdjustmentFlags != 0) {
            mLastBrightnessEvent.copyFrom(mTempBrightnessEvent);
@@ -1642,8 +1646,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call

            // Adjustment flags (and user-set flag) only get added after the equality checks since
            // they are transient.
            newEvent.adjustmentFlags = brightnessAdjustmentFlags;
            newEvent.flags |= (userSetBrightnessChanged ? BrightnessEvent.FLAG_USER_SET : 0);
            newEvent.setAdjustmentFlags(brightnessAdjustmentFlags);
            newEvent.setFlags(newEvent.getFlags() | (userSetBrightnessChanged
                    ? BrightnessEvent.FLAG_USER_SET : 0));
            Slog.i(TAG, newEvent.toString(/* includeTime= */ false));

            if (mBrightnessEventRingBuffer != null) {
@@ -2734,117 +2739,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
        }
    }

    class BrightnessEvent {
        static final int FLAG_RBC = 0x1;
        static final int FLAG_INVALID_LUX = 0x2;
        static final int FLAG_DOZE_SCALE = 0x3;
        static final int FLAG_USER_SET = 0x4;

        public final BrightnessReason reason = new BrightnessReason();

        public int displayId;
        public float lux;
        public float preThresholdLux;
        public long time;
        public float brightness;
        public float recommendedBrightness;
        public float preThresholdBrightness;
        public float hbmMax;
        public float thermalMax;
        public int hbmMode;
        public int flags;
        public int adjustmentFlags;

        BrightnessEvent(BrightnessEvent that) {
            copyFrom(that);
        }

        BrightnessEvent(int displayId) {
            this.displayId = displayId;
            reset();
        }

        void copyFrom(BrightnessEvent that) {
            displayId = that.displayId;
            time = that.time;
            lux = that.lux;
            preThresholdLux = that.preThresholdLux;
            brightness = that.brightness;
            recommendedBrightness = that.recommendedBrightness;
            preThresholdBrightness = that.preThresholdBrightness;
            hbmMax = that.hbmMax;
            thermalMax = that.thermalMax;
            flags = that.flags;
            hbmMode = that.hbmMode;
            reason.set(that.reason);
            adjustmentFlags = that.adjustmentFlags;
        }

        void reset() {
            time = SystemClock.uptimeMillis();
            brightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
            recommendedBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
            lux = 0;
            preThresholdLux = 0;
            preThresholdBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
            hbmMax = PowerManager.BRIGHTNESS_MAX;
            thermalMax = PowerManager.BRIGHTNESS_MAX;
            flags = 0;
            hbmMode = BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF;
            reason.set(null);
            adjustmentFlags = 0;
        }

        boolean equalsMainData(BrightnessEvent that) {
            // This equals comparison purposefully ignores time since it is regularly changing and
            // we don't want to log a brightness event just because the time changed.
            return displayId == that.displayId
                    && Float.floatToRawIntBits(brightness)
                        == Float.floatToRawIntBits(that.brightness)
                    && Float.floatToRawIntBits(recommendedBrightness)
                        == Float.floatToRawIntBits(that.recommendedBrightness)
                    && Float.floatToRawIntBits(preThresholdBrightness)
                        == Float.floatToRawIntBits(that.preThresholdBrightness)
                    && Float.floatToRawIntBits(lux) == Float.floatToRawIntBits(that.lux)
                    && Float.floatToRawIntBits(preThresholdLux)
                        == Float.floatToRawIntBits(that.preThresholdLux)
                    && Float.floatToRawIntBits(hbmMax) == Float.floatToRawIntBits(that.hbmMax)
                    && hbmMode == that.hbmMode
                    && Float.floatToRawIntBits(thermalMax)
                        == Float.floatToRawIntBits(that.thermalMax)
                    && flags == that.flags
                    && adjustmentFlags == that.adjustmentFlags
                    && reason.equals(that.reason);
        }

        public String toString(boolean includeTime) {
            return (includeTime ? TimeUtils.formatForLogging(time) + " - " : "")
                    + "BrightnessEvent: "
                    + "disp=" + displayId
                    + ", brt=" + brightness + ((flags & FLAG_USER_SET) != 0 ? "(user_set)" : "")
                    + ", rcmdBrt=" + recommendedBrightness
                    + ", preBrt=" + preThresholdBrightness
                    + ", lux=" + lux
                    + ", preLux=" + preThresholdLux
                    + ", hbmMax=" + hbmMax
                    + ", hbmMode=" + BrightnessInfo.hbmToString(hbmMode)
                    + ", thrmMax=" + thermalMax
                    + ", flags=" + flagsToString()
                    + ", reason=" + reason.toString(adjustmentFlags);
        }

        @Override
        public String toString() {
            return toString(/* includeTime */ true);
        }

        private String flagsToString() {
            return ((flags & FLAG_USER_SET) != 0 ? "user_set " : "")
                    + ((flags & FLAG_RBC) != 0 ? "rbc " : "")
                    + ((flags & FLAG_INVALID_LUX) != 0 ? "invalid_lux " : "")
                    + ((flags & FLAG_DOZE_SCALE) != 0 ? "doze_scale " : "");
        }
    }

    private final class DisplayControllerHandler extends Handler {
        public DisplayControllerHandler(Looper looper) {
@@ -2996,137 +2891,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
        }
    }

    /**
     * Stores data about why the brightness was changed.  Made up of one main
     * {@code BrightnessReason.REASON_*} reason and various {@code BrightnessReason.MODIFIER_*}
     * modifiers.
     */
    private final class BrightnessReason {
        static final int REASON_UNKNOWN = 0;
        static final int REASON_MANUAL = 1;
        static final int REASON_DOZE = 2;
        static final int REASON_DOZE_DEFAULT = 3;
        static final int REASON_AUTOMATIC = 4;
        static final int REASON_SCREEN_OFF = 5;
        static final int REASON_VR = 6;
        static final int REASON_OVERRIDE = 7;
        static final int REASON_TEMPORARY = 8;
        static final int REASON_BOOST = 9;
        static final int REASON_MAX = REASON_BOOST;

        static final int MODIFIER_DIMMED = 0x1;
        static final int MODIFIER_LOW_POWER = 0x2;
        static final int MODIFIER_HDR = 0x4;
        static final int MODIFIER_THROTTLED = 0x8;
        static final int MODIFIER_MASK = MODIFIER_DIMMED | MODIFIER_LOW_POWER | MODIFIER_HDR
            | MODIFIER_THROTTLED;

        // ADJUSTMENT_*
        // These things can happen at any point, even if the main brightness reason doesn't
        // fundamentally change, so they're not stored.

        // Auto-brightness adjustment factor changed
        static final int ADJUSTMENT_AUTO_TEMP = 0x1;
        // Temporary adjustment to the auto-brightness adjustment factor.
        static final int ADJUSTMENT_AUTO = 0x2;

        // One of REASON_*
        public int reason;
        // Any number of MODIFIER_*
        public int modifier;

        public void set(BrightnessReason other) {
            setReason(other == null ? REASON_UNKNOWN : other.reason);
            setModifier(other == null ? 0 : other.modifier);
        }

        public void setReason(int reason) {
            if (reason < REASON_UNKNOWN || reason > REASON_MAX) {
                Slog.w(TAG, "brightness reason out of bounds: " + reason);
            } else {
                this.reason = reason;
            }
        }

        public void setModifier(int modifier) {
            if ((modifier & ~MODIFIER_MASK) != 0) {
                Slog.w(TAG, "brightness modifier out of bounds: 0x"
                        + Integer.toHexString(modifier));
            } else {
                this.modifier = modifier;
            }
        }

        public void addModifier(int modifier) {
            setModifier(modifier | this.modifier);
        }

        @Override
        public boolean equals(Object obj) {
            if (!(obj instanceof BrightnessReason)) {
                return false;
            }
            BrightnessReason other = (BrightnessReason) obj;
            return other.reason == reason && other.modifier == modifier;
        }

        @Override
        public int hashCode() {
            return Objects.hash(reason, modifier);
        }

        @Override
        public String toString() {
            return toString(0);
        }

        public String toString(int adjustments) {
            final StringBuilder sb = new StringBuilder();
            sb.append(reasonToString(reason));
            sb.append(" [");
            if ((adjustments & ADJUSTMENT_AUTO_TEMP) != 0) {
                sb.append(" temp_adj");
            }
            if ((adjustments & ADJUSTMENT_AUTO) != 0) {
                sb.append(" auto_adj");
            }
            if ((modifier & MODIFIER_LOW_POWER) != 0) {
                sb.append(" low_pwr");
            }
            if ((modifier & MODIFIER_DIMMED) != 0) {
                sb.append(" dim");
            }
            if ((modifier & MODIFIER_HDR) != 0) {
                sb.append(" hdr");
            }
            if ((modifier & MODIFIER_THROTTLED) != 0) {
                sb.append(" throttled");
            }
            int strlen = sb.length();
            if (sb.charAt(strlen - 1) == '[') {
                sb.setLength(strlen - 2);
            } else {
                sb.append(" ]");
            }
            return sb.toString();
        }

        private String reasonToString(int reason) {
            switch (reason) {
                case REASON_MANUAL: return "manual";
                case REASON_DOZE: return "doze";
                case REASON_DOZE_DEFAULT: return "doze_default";
                case REASON_AUTOMATIC: return "automatic";
                case REASON_SCREEN_OFF: return "screen_off";
                case REASON_VR: return "vr";
                case REASON_OVERRIDE: return "override";
                case REASON_TEMPORARY: return "temporary";
                case REASON_BOOST: return "boost";
                default: return Integer.toString(reason);
            }
        }
    }

    static class CachedBrightnessInfo {
        public MutableFloat brightness = new MutableFloat(PowerManager.BRIGHTNESS_INVALID_FLOAT);
        public MutableFloat adjustedBrightness =
+262 −0

File added.

Preview size limit exceeded, changes collapsed.

+200 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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.brightness;

import android.util.Slog;

import java.util.Objects;

/**
 * Stores data about why the brightness was changed. Made up of one main
 * {@code BrightnessReason.REASON_*} reason and various {@code BrightnessReason.MODIFIER_*}
 * modifiers.
 */
public final class BrightnessReason {
    private static final String TAG = "BrightnessReason";

    public static final int REASON_UNKNOWN = 0;
    public static final int REASON_MANUAL = 1;
    public static final int REASON_DOZE = 2;
    public static final int REASON_DOZE_DEFAULT = 3;
    public static final int REASON_AUTOMATIC = 4;
    public static final int REASON_SCREEN_OFF = 5;
    public static final int REASON_VR = 6;
    public static final int REASON_OVERRIDE = 7;
    public static final int REASON_TEMPORARY = 8;
    public static final int REASON_BOOST = 9;
    public static final int REASON_MAX = REASON_BOOST;

    public static final int MODIFIER_DIMMED = 0x1;
    public static final int MODIFIER_LOW_POWER = 0x2;
    public static final int MODIFIER_HDR = 0x4;
    public static final int MODIFIER_THROTTLED = 0x8;
    public static final int MODIFIER_MASK = MODIFIER_DIMMED | MODIFIER_LOW_POWER | MODIFIER_HDR
            | MODIFIER_THROTTLED;

    // ADJUSTMENT_*
    // These things can happen at any point, even if the main brightness reason doesn't
    // fundamentally change, so they're not stored.

    // Auto-brightness adjustment factor changed
    public static final int ADJUSTMENT_AUTO_TEMP = 0x1;
    // Temporary adjustment to the auto-brightness adjustment factor.
    public static final int ADJUSTMENT_AUTO = 0x2;

    // One of REASON_*
    private int mReason;
    // Any number of MODIFIER_*
    private int mModifier;

    /**
     * A utility to clone a BrightnessReason from another BrightnessReason event
     *
     * @param other The BrightnessReason object which is to be cloned
     */
    public void set(BrightnessReason other) {
        setReason(other == null ? REASON_UNKNOWN : other.mReason);
        setModifier(other == null ? 0 : other.mModifier);
    }

    /**
     * A utility to add a modifier to the BrightnessReason object
     *
     * @param modifier The modifier which is to be added
     */
    public void addModifier(int modifier) {
        setModifier(modifier | this.mModifier);
    }


    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof BrightnessReason)) {
            return false;
        }
        BrightnessReason other = (BrightnessReason) obj;
        return other.mReason == mReason && other.mModifier == mModifier;
    }

    @Override
    public int hashCode() {
        return Objects.hash(mReason, mModifier);
    }

    @Override
    public String toString() {
        return toString(0);
    }

    /**
     * A utility to stringify a BrightnessReason
     *
     * @param adjustments Indicates if the adjustments field is to be added in the stringify version
     *                    of the BrightnessReason
     * @return A stringified BrightnessReason
     */
    public String toString(int adjustments) {
        final StringBuilder sb = new StringBuilder();
        sb.append(reasonToString(mReason));
        sb.append(" [");
        if ((adjustments & ADJUSTMENT_AUTO_TEMP) != 0) {
            sb.append(" temp_adj");
        }
        if ((adjustments & ADJUSTMENT_AUTO) != 0) {
            sb.append(" auto_adj");
        }
        if ((mModifier & MODIFIER_LOW_POWER) != 0) {
            sb.append(" low_pwr");
        }
        if ((mModifier & MODIFIER_DIMMED) != 0) {
            sb.append(" dim");
        }
        if ((mModifier & MODIFIER_HDR) != 0) {
            sb.append(" hdr");
        }
        if ((mModifier & MODIFIER_THROTTLED) != 0) {
            sb.append(" throttled");
        }
        int strlen = sb.length();
        if (sb.charAt(strlen - 1) == '[') {
            sb.setLength(strlen - 2);
        } else {
            sb.append(" ]");
        }
        return sb.toString();
    }

    /**
     * A utility to set the reason of the BrightnessReason object
     *
     * @param reason The value to which the reason is to be updated.
     */
    public void setReason(int reason) {
        if (reason < REASON_UNKNOWN || reason > REASON_MAX) {
            Slog.w(TAG, "brightness reason out of bounds: " + reason);
        } else {
            this.mReason = reason;
        }
    }

    public int getReason() {
        return mReason;
    }

    public int getModifier() {
        return mModifier;
    }

    /**
     * A utility to set the modified of the current BrightnessReason object
     *
     * @param modifier The value to which the modifier is to be updated
     */
    public void setModifier(int modifier) {
        if ((modifier & ~MODIFIER_MASK) != 0) {
            Slog.w(TAG, "brightness modifier out of bounds: 0x"
                    + Integer.toHexString(modifier));
        } else {
            this.mModifier = modifier;
        }
    }

    private String reasonToString(int reason) {
        switch (reason) {
            case REASON_MANUAL:
                return "manual";
            case REASON_DOZE:
                return "doze";
            case REASON_DOZE_DEFAULT:
                return "doze_default";
            case REASON_AUTOMATIC:
                return "automatic";
            case REASON_SCREEN_OFF:
                return "screen_off";
            case REASON_VR:
                return "vr";
            case REASON_OVERRIDE:
                return "override";
            case REASON_TEMPORARY:
                return "temporary";
            case REASON_BOOST:
                return "boost";
            default:
                return Integer.toString(reason);
        }
    }
}
+78 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading