summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author petsjonkin <petsjonkin@google.com> 2024-01-10 13:16:54 +0000
committer petsjonkin <petsjonkin@google.com> 2024-01-10 13:16:54 +0000
commit745c45bfaa545ecfbebff7ac878cbf2ffd83a478 (patch)
treece5978168675bdac3e72df0e0bd8c6b56cbbbe71
parent27f540e35a19713ba8511e4528bdf8b7b0e92073 (diff)
Removing DisplayPowerController
Bug: b/295948590 Test: presubmit Change-Id: I03f34c62cfc169e32fb10387bc5829c2282a44e0
-rw-r--r--core/java/android/hardware/display/DisplayManager.java9
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java15
-rw-r--r--services/core/java/com/android/server/display/DisplayPowerController.java3751
-rw-r--r--services/core/java/com/android/server/display/feature/DeviceConfigParameterProvider.java7
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java1718
5 files changed, 4 insertions, 5496 deletions
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index 134a510df5f3..8f0e0c911f56 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -1831,15 +1831,6 @@ public final class DisplayManager {
String KEY_POWER_THROTTLING_DATA = "power_throttling_data";
/**
- * Key for new power controller feature flag. If enabled new DisplayPowerController will
- * be used.
- * Read value via {@link android.provider.DeviceConfig#getBoolean(String, String, boolean)}
- * with {@link android.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER} as the namespace.
- * @hide
- */
- String KEY_NEW_POWER_CONTROLLER = "use_newly_structured_display_power_controller";
-
- /**
* Key for normal brightness mode controller feature flag.
* It enables NormalBrightnessModeController.
* Read value via {@link android.provider.DeviceConfig#getBoolean(String, String, boolean)}
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index fbac924be283..14ce152767ad 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -3390,17 +3390,10 @@ public final class DisplayManagerService extends SystemService {
// with the corresponding displaydevice.
HighBrightnessModeMetadata hbmMetadata =
mHighBrightnessModeMetadataMapper.getHighBrightnessModeMetadataLocked(display);
- if (mConfigParameterProvider.isNewPowerControllerFeatureEnabled()) {
- displayPowerController = new DisplayPowerController2(
- mContext, /* injector= */ null, mDisplayPowerCallbacks, mPowerHandler,
- mSensorManager, mDisplayBlanker, display, mBrightnessTracker, brightnessSetting,
- () -> handleBrightnessChange(display), hbmMetadata, mBootCompleted, mFlags);
- } else {
- displayPowerController = new DisplayPowerController(
- mContext, /* injector= */ null, mDisplayPowerCallbacks, mPowerHandler,
- mSensorManager, mDisplayBlanker, display, mBrightnessTracker, brightnessSetting,
- () -> handleBrightnessChange(display), hbmMetadata, mBootCompleted, mFlags);
- }
+ displayPowerController = new DisplayPowerController2(
+ mContext, /* injector= */ null, mDisplayPowerCallbacks, mPowerHandler,
+ mSensorManager, mDisplayBlanker, display, mBrightnessTracker, brightnessSetting,
+ () -> handleBrightnessChange(display), hbmMetadata, mBootCompleted, mFlags);
mDisplayPowerControllers.append(display.getDisplayIdLocked(), displayPowerController);
return displayPowerController;
}
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
deleted file mode 100644
index 734381b1ddb0..000000000000
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ /dev/null
@@ -1,3751 +0,0 @@
-/*
- * Copyright (C) 2012 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;
-
-import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_DEFAULT;
-import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_IDLE;
-
-import android.animation.Animator;
-import android.animation.ObjectAnimator;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SuppressLint;
-import android.annotation.UserIdInt;
-import android.app.ActivityManager;
-import android.content.Context;
-import android.content.pm.ParceledListSlice;
-import android.content.res.Resources;
-import android.database.ContentObserver;
-import android.hardware.Sensor;
-import android.hardware.SensorEvent;
-import android.hardware.SensorEventListener;
-import android.hardware.SensorManager;
-import android.hardware.display.AmbientBrightnessDayStats;
-import android.hardware.display.BrightnessChangeEvent;
-import android.hardware.display.BrightnessConfiguration;
-import android.hardware.display.BrightnessInfo;
-import android.hardware.display.DisplayManagerInternal;
-import android.hardware.display.DisplayManagerInternal.DisplayOffloadSession;
-import android.hardware.display.DisplayManagerInternal.DisplayPowerCallbacks;
-import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
-import android.metrics.LogMaker;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.os.Trace;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.util.FloatProperty;
-import android.util.MathUtils;
-import android.util.MutableFloat;
-import android.util.MutableInt;
-import android.util.Slog;
-import android.util.SparseArray;
-import android.util.TimeUtils;
-import android.view.Display;
-
-import com.android.internal.R;
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.app.IBatteryStats;
-import com.android.internal.display.BrightnessSynchronizer;
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.internal.util.FrameworkStatsLog;
-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.feature.DisplayManagerFlags;
-import com.android.server.display.layout.Layout;
-import com.android.server.display.utils.DebugUtils;
-import com.android.server.display.utils.SensorUtils;
-import com.android.server.display.whitebalance.DisplayWhiteBalanceController;
-import com.android.server.display.whitebalance.DisplayWhiteBalanceFactory;
-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.
- *
- * Handles the proximity sensor, light sensor, and animations between states
- * including the screen off animation.
- *
- * This component acts independently of the rest of the power manager service.
- * In particular, it does not share any state and it only communicates
- * via asynchronous callbacks to inform the power manager that something has
- * changed.
- *
- * Everything this class does internally is serialized on its handler although
- * it may be accessed by other threads from the outside.
- *
- * Note that the power manager service guarantees that it will hold a suspend
- * blocker as long as the display is not ready. So most of the work done here
- * does not need to worry about holding a suspend blocker unless it happens
- * independently of the display ready signal.
- *
- * For debugging, you can make the color fade and brightness animations run
- * slower by changing the "animator duration scale" option in Development Settings.
- */
-final class DisplayPowerController implements AutomaticBrightnessController.Callbacks,
- DisplayWhiteBalanceController.Callbacks, DisplayPowerControllerInterface {
- private static final String SCREEN_ON_BLOCKED_TRACE_NAME = "Screen on blocked";
- private static final String SCREEN_OFF_BLOCKED_TRACE_NAME = "Screen off blocked";
-
- private static final String TAG = "DisplayPowerController";
- // To enable these logs, run:
- // 'adb shell setprop persist.log.tag.DisplayPowerController DEBUG && adb reboot'
- private static final boolean DEBUG = DebugUtils.isDebuggable(TAG);
-
- private static final boolean DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT = false;
-
- // If true, uses the color fade on animation.
- // We might want to turn this off if we cannot get a guarantee that the screen
- // actually turns on and starts showing new content after the call to set the
- // screen state returns. Playing the animation can also be somewhat slow.
- private static final boolean USE_COLOR_FADE_ON_ANIMATION = false;
-
- private static final float SCREEN_ANIMATION_RATE_MINIMUM = 0.0f;
-
- private static final int COLOR_FADE_ON_ANIMATION_DURATION_MILLIS = 250;
- private static final int COLOR_FADE_OFF_ANIMATION_DURATION_MILLIS = 400;
-
- private static final int MSG_UPDATE_POWER_STATE = 1;
- private static final int MSG_PROXIMITY_SENSOR_DEBOUNCED = 2;
- private static final int MSG_SCREEN_ON_UNBLOCKED = 3;
- private static final int MSG_SCREEN_OFF_UNBLOCKED = 4;
- private static final int MSG_CONFIGURE_BRIGHTNESS = 5;
- private static final int MSG_SET_TEMPORARY_BRIGHTNESS = 6;
- private static final int MSG_SET_TEMPORARY_AUTO_BRIGHTNESS_ADJUSTMENT = 7;
- private static final int MSG_IGNORE_PROXIMITY = 8;
- private static final int MSG_STOP = 9;
- private static final int MSG_UPDATE_BRIGHTNESS = 10;
- private static final int MSG_UPDATE_RBC = 11;
- private static final int MSG_BRIGHTNESS_RAMP_DONE = 12;
- private static final int MSG_STATSD_HBM_BRIGHTNESS = 13;
- private static final int MSG_SWITCH_USER = 14;
- private static final int MSG_BOOT_COMPLETED = 15;
- private static final int MSG_SET_DWBC_STRONG_MODE = 16;
- private static final int MSG_SET_DWBC_COLOR_OVERRIDE = 17;
- private static final int MSG_SET_DWBC_LOGGING_ENABLED = 18;
-
- private static final int PROXIMITY_UNKNOWN = -1;
- private static final int PROXIMITY_NEGATIVE = 0;
- private static final int PROXIMITY_POSITIVE = 1;
-
- // Proximity sensor debounce delay in milliseconds for positive or negative transitions.
- private static final int PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY = 0;
- private static final int PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY = 250;
-
- private static final int BRIGHTNESS_CHANGE_STATSD_REPORT_INTERVAL_MS = 500;
-
- // Trigger proximity if distance is less than 5 cm.
- private static final float TYPICAL_PROXIMITY_THRESHOLD = 5.0f;
-
- // State machine constants for tracking initial brightness ramp skipping when enabled.
- private static final int RAMP_STATE_SKIP_NONE = 0;
- private static final int RAMP_STATE_SKIP_INITIAL = 1;
- private static final int RAMP_STATE_SKIP_AUTOBRIGHT = 2;
-
- private static final int REPORTED_TO_POLICY_UNREPORTED = -1;
- private static final int REPORTED_TO_POLICY_SCREEN_OFF = 0;
- private static final int REPORTED_TO_POLICY_SCREEN_TURNING_ON = 1;
- private static final int REPORTED_TO_POLICY_SCREEN_ON = 2;
- private static final int REPORTED_TO_POLICY_SCREEN_TURNING_OFF = 3;
-
- private static final int RINGBUFFER_MAX = 100;
-
- private static final float[] BRIGHTNESS_RANGE_BOUNDARIES = {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50, 60, 70, 80,
- 90, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1200,
- 1400, 1600, 1800, 2000, 2250, 2500, 2750, 3000};
- private static final int[] BRIGHTNESS_RANGE_INDEX = {
- FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_UNKNOWN,
- FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_0_1,
- FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_1_2,
- FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_2_3,
- FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_3_4,
- FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_4_5,
- FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_5_6,
- FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_6_7,
- FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_7_8,
- FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_8_9,
- FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_9_10,
- FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_10_20,
- FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_20_30,
- FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_30_40,
- FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_40_50,
- FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_50_60,
- FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_60_70,
- FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_70_80,
- FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_80_90,
- FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_90_100,
- FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_100_200,
- FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_200_300,
- FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_300_400,
- FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_400_500,
- FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_500_600,
- FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_600_700,
- FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_700_800,
- FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_800_900,
- FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_900_1000,
- FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_1000_1200,
- FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_1200_1400,
- FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_1400_1600,
- FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_1600_1800,
- FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_1800_2000,
- FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_2000_2250,
- FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_2250_2500,
- FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_2500_2750,
- FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_2750_3000,
- };
-
- private final String mTag;
-
- private final Object mLock = new Object();
-
- private final Context mContext;
-
- // Our handler.
- private final DisplayControllerHandler mHandler;
-
- // Asynchronous callbacks into the power manager service.
- // Only invoked from the handler thread while no locks are held.
- private final DisplayPowerCallbacks mCallbacks;
-
- // Battery stats.
- @Nullable
- private final IBatteryStats mBatteryStats;
-
- // The sensor manager.
- private final SensorManager mSensorManager;
-
- // The window manager policy.
- private final WindowManagerPolicy mWindowManagerPolicy;
-
- // The display blanker.
- private final DisplayBlanker mBlanker;
-
- // The LogicalDisplay tied to this DisplayPowerController.
- private final LogicalDisplay mLogicalDisplay;
-
- // The ID of the LogicalDisplay tied to this DisplayPowerController.
- private final int mDisplayId;
-
- // The ID of the display which this display follows for brightness purposes.
- private int mLeadDisplayId = Layout.NO_LEAD_DISPLAY;
-
- // The unique ID of the primary display device currently tied to this logical display
- private String mUniqueDisplayId;
-
- // Tracker for brightness changes.
- @Nullable
- private final BrightnessTracker mBrightnessTracker;
-
- // Tracker for brightness settings changes.
- private final SettingsObserver mSettingsObserver;
-
- // The proximity sensor, or null if not available or needed.
- private Sensor mProximitySensor;
-
- // The doze screen brightness.
- private final float mScreenBrightnessDozeConfig;
-
- // The dim screen brightness.
- private final float mScreenBrightnessDimConfig;
-
- // The minimum dim amount to use if the screen brightness is already below
- // mScreenBrightnessDimConfig.
- private final float mScreenBrightnessMinimumDimAmount;
-
- private final float mScreenBrightnessDefault;
-
- // True if auto-brightness should be used.
- private boolean mUseSoftwareAutoBrightnessConfig;
-
- // True if should use light sensor to automatically determine doze screen brightness.
- private final boolean mAllowAutoBrightnessWhileDozingConfig;
-
- // True if we want to persist the brightness value in nits even if the underlying display
- // device changes.
- private final boolean mPersistBrightnessNitsForDefaultDisplay;
-
- // True if the brightness config has changed and the short-term model needs to be reset
- private boolean mShouldResetShortTermModel;
-
- // Whether or not the color fade on screen on / off is enabled.
- private final boolean mColorFadeEnabled;
-
- @GuardedBy("mCachedBrightnessInfo")
- private final CachedBrightnessInfo mCachedBrightnessInfo = new CachedBrightnessInfo();
-
- private DisplayDevice mDisplayDevice;
-
- // True if we should fade the screen while turning it off, false if we should play
- // a stylish color fade animation instead.
- private final boolean mColorFadeFadesConfig;
-
- // True if we need to fake a transition to off when coming out of a doze state.
- // Some display hardware will blank itself when coming out of doze in order to hide
- // artifacts. For these displays we fake a transition into OFF so that policy can appropriately
- // blank itself and begin an appropriate power on animation.
- private final boolean mDisplayBlanksAfterDozeConfig;
-
- // True if there are only buckets of brightness values when the display is in the doze state,
- // rather than a full range of values. If this is true, then we'll avoid animating the screen
- // brightness since it'd likely be multiple jarring brightness transitions instead of just one
- // to reach the final state.
- private final boolean mBrightnessBucketsInDozeConfig;
-
- private final Clock mClock;
- private final Injector mInjector;
-
- // Maximum time a ramp animation can take.
- private long mBrightnessRampIncreaseMaxTimeMillis;
- private long mBrightnessRampDecreaseMaxTimeMillis;
-
- // Maximum time a ramp animation can take in idle mode.
- private long mBrightnessRampIncreaseMaxTimeIdleMillis;
- private long mBrightnessRampDecreaseMaxTimeIdleMillis;
-
- // The pending power request.
- // Initially null until the first call to requestPowerState.
- @GuardedBy("mLock")
- private DisplayPowerRequest mPendingRequestLocked;
-
- // True if a request has been made to wait for the proximity sensor to go negative.
- @GuardedBy("mLock")
- private boolean mPendingWaitForNegativeProximityLocked;
-
- // True if the pending power request or wait for negative proximity flag
- // has been changed since the last update occurred.
- @GuardedBy("mLock")
- private boolean mPendingRequestChangedLocked;
-
- // Set to true when the important parts of the pending power request have been applied.
- // The important parts are mainly the screen state. Brightness changes may occur
- // concurrently.
- @GuardedBy("mLock")
- private boolean mDisplayReadyLocked;
-
- // Set to true if a power state update is required.
- @GuardedBy("mLock")
- private boolean mPendingUpdatePowerStateLocked;
-
- /* The following state must only be accessed by the handler thread. */
-
- // The currently requested power state.
- // The power controller will progressively update its internal state to match
- // the requested power state. Initially null until the first update.
- private DisplayPowerRequest mPowerRequest;
-
- // The current power state.
- // Must only be accessed on the handler thread.
- private DisplayPowerState mPowerState;
-
- // True if the device should wait for negative proximity sensor before
- // waking up the screen. This is set to false as soon as a negative
- // proximity sensor measurement is observed or when the device is forced to
- // go to sleep by the user. While true, the screen remains off.
- private boolean mWaitingForNegativeProximity;
-
- // True if the device should not take into account the proximity sensor
- // until either the proximity sensor state changes, or there is no longer a
- // request to listen to proximity sensor.
- private boolean mIgnoreProximityUntilChanged;
-
- // The actual proximity sensor threshold value.
- private float mProximityThreshold;
-
- // Set to true if the proximity sensor listener has been registered
- // with the sensor manager.
- private boolean mProximitySensorEnabled;
-
- // The debounced proximity sensor state.
- private int mProximity = PROXIMITY_UNKNOWN;
-
- // The raw non-debounced proximity sensor state.
- private int mPendingProximity = PROXIMITY_UNKNOWN;
- private long mPendingProximityDebounceTime = -1; // -1 if fully debounced
-
- // True if the screen was turned off because of the proximity sensor.
- // When the screen turns on again, we report user activity to the power manager.
- private boolean mScreenOffBecauseOfProximity;
-
- // The currently active screen on unblocker. This field is non-null whenever
- // we are waiting for a callback to release it and unblock the screen.
- private ScreenOnUnblocker mPendingScreenOnUnblocker;
- private ScreenOffUnblocker mPendingScreenOffUnblocker;
-
- // True if we were in the process of turning off the screen.
- // This allows us to recover more gracefully from situations where we abort
- // turning off the screen.
- private boolean mPendingScreenOff;
-
- // True if we have unfinished business and are holding a suspend blocker.
- private boolean mUnfinishedBusiness;
-
- // The elapsed real time when the screen on was blocked.
- private long mScreenOnBlockStartRealTime;
- private long mScreenOffBlockStartRealTime;
-
- // Screen state we reported to policy. Must be one of REPORTED_TO_POLICY_* fields.
- private int mReportedScreenStateToPolicy = REPORTED_TO_POLICY_UNREPORTED;
-
- // If the last recorded screen state was dozing or not.
- private boolean mDozing;
-
- // Remembers whether certain kinds of brightness adjustments
- // were recently applied so that we can decide how to transition.
- private boolean mAppliedAutoBrightness;
- private boolean mAppliedDimming;
- private boolean mAppliedLowPower;
- private boolean mAppliedScreenBrightnessOverride;
- private boolean mAppliedTemporaryBrightness;
- private boolean mAppliedTemporaryAutoBrightnessAdjustment;
- private boolean mAppliedBrightnessBoost;
- private boolean mAppliedThrottling;
-
- // Reason for which the brightness was last changed. See {@link BrightnessReason} for more
- // information.
- // At the time of this writing, this value is changed within updatePowerState() only, which is
- // limited to the thread used by DisplayControllerHandler.
- private final BrightnessReason mBrightnessReason = new BrightnessReason();
- private final BrightnessReason mBrightnessReasonTemp = new BrightnessReason();
-
- // Brightness animation ramp rates in brightness units per second
- private float mBrightnessRampRateFastDecrease;
- private float mBrightnessRampRateFastIncrease;
- private float mBrightnessRampRateSlowDecrease;
- private float mBrightnessRampRateSlowIncrease;
- private float mBrightnessRampRateSlowDecreaseIdle;
- private float mBrightnessRampRateSlowIncreaseIdle;
-
- // Report HBM brightness change to StatsD
- private int mDisplayStatsId;
- private float mLastStatsBrightness = PowerManager.BRIGHTNESS_MIN;
-
- // Whether or not to skip the initial brightness ramps into STATE_ON.
- private final boolean mSkipScreenOnBrightnessRamp;
-
- // Display white balance components.
- // Critical methods must be called on DPC handler thread.
- @Nullable
- private final DisplayWhiteBalanceSettings mDisplayWhiteBalanceSettings;
- @Nullable
- private final DisplayWhiteBalanceController mDisplayWhiteBalanceController;
-
- @Nullable
- private final ColorDisplayServiceInternal mCdsi;
- private float[] mNitsRange;
-
- private final BrightnessRangeController mBrightnessRangeController;
-
- @Nullable
- private final HighBrightnessModeMetadata mHighBrightnessModeMetadata;
-
- private final BrightnessThrottler mBrightnessThrottler;
-
- private final BrightnessSetting mBrightnessSetting;
-
- private final Runnable mOnBrightnessChangeRunnable;
-
- private final BrightnessEvent mLastBrightnessEvent;
- private final BrightnessEvent mTempBrightnessEvent;
-
- // Keeps a record of brightness changes for dumpsys.
- private RingBuffer<BrightnessEvent> mBrightnessEventRingBuffer;
-
- // A record of state for skipping brightness ramps.
- private int mSkipRampState = RAMP_STATE_SKIP_NONE;
-
- // The first autobrightness value set when entering RAMP_STATE_SKIP_INITIAL.
- private float mInitialAutoBrightness;
-
- // The controller for the automatic brightness level.
- @Nullable
- private AutomaticBrightnessController mAutomaticBrightnessController;
-
- // The controller for the sensor used to estimate ambient lux while the display is off.
- @Nullable
- private ScreenOffBrightnessSensorController mScreenOffBrightnessSensorController;
-
- private Sensor mLightSensor;
- private Sensor mScreenOffBrightnessSensor;
-
- // The current brightness configuration.
- @Nullable
- private BrightnessConfiguration mBrightnessConfiguration;
-
- // The last brightness that was set by the user and not temporary. Set to
- // PowerManager.BRIGHTNESS_INVALID_FLOAT when a brightness has yet to be recorded.
- private float mLastUserSetScreenBrightness = Float.NaN;
-
- // The screen brightness setting has changed but not taken effect yet. If this is different
- // from the current screen brightness setting then this is coming from something other than us
- // and should be considered a user interaction.
- private float mPendingScreenBrightnessSetting;
-
- // The last observed screen brightness setting, either set by us or by the settings app on
- // behalf of the user.
- private float mCurrentScreenBrightnessSetting;
-
- // The temporary screen brightness. Typically set when a user is interacting with the
- // brightness slider but hasn't settled on a choice yet. Set to
- // PowerManager.BRIGHTNESS_INVALID_FLOAT when there's no temporary brightness set.
- private float mTemporaryScreenBrightness;
-
- // This brightness value is set in concurrent displays mode. It is the brightness value
- // of the lead display that this DPC should follow.
- private float mBrightnessToFollow;
-
- // Indicates whether we should ramp slowly to the brightness value to follow.
- private boolean mBrightnessToFollowSlowChange;
-
- // The last auto brightness adjustment that was set by the user and not temporary. Set to
- // Float.NaN when an auto-brightness adjustment hasn't been recorded yet.
- private float mAutoBrightnessAdjustment;
-
- // The pending auto brightness adjustment that will take effect on the next power state update.
- private float mPendingAutoBrightnessAdjustment;
-
- // The temporary auto brightness adjustment. Typically set when a user is interacting with the
- // adjustment slider but hasn't settled on a choice yet. Set to
- // PowerManager.BRIGHTNESS_INVALID_FLOAT when there's no temporary adjustment set.
- private float mTemporaryAutoBrightnessAdjustment;
-
- private boolean mUseAutoBrightness;
-
- private boolean mIsRbcActive;
-
- // Whether there's a callback to tell listeners the display has changed scheduled to run. When
- // true it implies a wakelock is being held to guarantee the update happens before we collapse
- // into suspend and so needs to be cleaned up if the thread is exiting.
- // Should only be accessed on the Handler thread.
- private boolean mOnStateChangedPending;
-
- // Count of proximity messages currently on this DPC's Handler. Used to keep track of how many
- // suspend blocker acquisitions are pending when shutting down this DPC.
- // Should only be accessed on the Handler thread.
- private int mOnProximityPositiveMessages;
- private int mOnProximityNegativeMessages;
-
- // Animators.
- private ObjectAnimator mColorFadeOnAnimator;
- private ObjectAnimator mColorFadeOffAnimator;
- private DualRampAnimator<DisplayPowerState> mScreenBrightnessRampAnimator;
- private BrightnessSetting.BrightnessSettingListener mBrightnessSettingListener;
-
- // True if this DisplayPowerController has been stopped and should no longer be running.
- private boolean mStopped;
-
- private DisplayDeviceConfig mDisplayDeviceConfig;
-
- // Identifiers for suspend blocker acquisition requests
- private final String mSuspendBlockerIdUnfinishedBusiness;
- private final String mSuspendBlockerIdOnStateChanged;
- private final String mSuspendBlockerIdProxPositive;
- private final String mSuspendBlockerIdProxNegative;
- private final String mSuspendBlockerIdProxDebounce;
-
- private boolean mIsEnabled;
- private boolean mIsInTransition;
- private boolean mIsDisplayInternal;
-
- // The id of the thermal brightness throttling policy that should be used.
- private String mThermalBrightnessThrottlingDataId;
-
- // DPCs following the brightness of this DPC. This is used in concurrent displays mode - there
- // is one lead display, the additional displays follow the brightness value of the lead display.
- @GuardedBy("mLock")
- private final SparseArray<DisplayPowerControllerInterface> mDisplayBrightnessFollowers =
- new SparseArray<>();
-
- private boolean mBootCompleted;
- private final DisplayManagerFlags mFlags;
- private int mDozeStateOverride = Display.STATE_UNKNOWN;
- private DisplayManagerInternal.DisplayOffloadSession mDisplayOffloadSession;
-
- /**
- * Creates the display power controller.
- */
- DisplayPowerController(Context context, Injector injector,
- DisplayPowerCallbacks callbacks, Handler handler,
- SensorManager sensorManager, DisplayBlanker blanker, LogicalDisplay logicalDisplay,
- BrightnessTracker brightnessTracker, BrightnessSetting brightnessSetting,
- Runnable onBrightnessChangeRunnable, HighBrightnessModeMetadata hbmMetadata,
- boolean bootCompleted, DisplayManagerFlags flags) {
- mFlags = flags;
- mInjector = injector != null ? injector : new Injector();
- mClock = mInjector.getClock();
- mLogicalDisplay = logicalDisplay;
- mDisplayId = mLogicalDisplay.getDisplayIdLocked();
- mTag = TAG + "[" + mDisplayId + "]";
- mHighBrightnessModeMetadata = hbmMetadata;
- mSuspendBlockerIdUnfinishedBusiness = getSuspendBlockerUnfinishedBusinessId(mDisplayId);
- mSuspendBlockerIdOnStateChanged = getSuspendBlockerOnStateChangedId(mDisplayId);
- mSuspendBlockerIdProxPositive = getSuspendBlockerProxPositiveId(mDisplayId);
- mSuspendBlockerIdProxNegative = getSuspendBlockerProxNegativeId(mDisplayId);
- mSuspendBlockerIdProxDebounce = getSuspendBlockerProxDebounceId(mDisplayId);
-
- mDisplayDevice = mLogicalDisplay.getPrimaryDisplayDeviceLocked();
- mUniqueDisplayId = logicalDisplay.getPrimaryDisplayDeviceLocked().getUniqueId();
- mDisplayStatsId = mUniqueDisplayId.hashCode();
- mIsEnabled = logicalDisplay.isEnabledLocked();
- mIsInTransition = logicalDisplay.isInTransitionLocked();
- mIsDisplayInternal = logicalDisplay.getPrimaryDisplayDeviceLocked()
- .getDisplayDeviceInfoLocked().type == Display.TYPE_INTERNAL;
- mHandler = new DisplayControllerHandler(handler.getLooper());
- mLastBrightnessEvent = new BrightnessEvent(mDisplayId);
- mTempBrightnessEvent = new BrightnessEvent(mDisplayId);
- mThermalBrightnessThrottlingDataId =
- logicalDisplay.getDisplayInfoLocked().thermalBrightnessThrottlingDataId;
-
- if (mDisplayId == Display.DEFAULT_DISPLAY) {
- mBatteryStats = BatteryStatsService.getService();
- } else {
- mBatteryStats = null;
- }
-
- mSettingsObserver = new SettingsObserver(mHandler);
- mCallbacks = callbacks;
- mSensorManager = sensorManager;
- mWindowManagerPolicy = LocalServices.getService(WindowManagerPolicy.class);
- mBlanker = blanker;
- mContext = context;
- mBrightnessTracker = brightnessTracker;
- // TODO: b/186428377 update brightness setting when display changes
- mBrightnessSetting = brightnessSetting;
- mOnBrightnessChangeRunnable = onBrightnessChangeRunnable;
-
- PowerManager pm = context.getSystemService(PowerManager.class);
-
- final Resources resources = context.getResources();
-
- // DOZE AND DIM SETTINGS
- mScreenBrightnessDozeConfig = clampAbsoluteBrightness(
- pm.getBrightnessConstraint(PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DOZE));
- mScreenBrightnessDimConfig = clampAbsoluteBrightness(
- pm.getBrightnessConstraint(PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DIM));
- mScreenBrightnessMinimumDimAmount = resources.getFloat(
- com.android.internal.R.dimen.config_screenBrightnessMinimumDimAmountFloat);
-
-
- // NORMAL SCREEN SETTINGS
- mScreenBrightnessDefault = clampAbsoluteBrightness(
- mLogicalDisplay.getDisplayInfoLocked().brightnessDefault);
-
- mAllowAutoBrightnessWhileDozingConfig = resources.getBoolean(
- com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing);
-
- mPersistBrightnessNitsForDefaultDisplay = resources.getBoolean(
- com.android.internal.R.bool.config_persistBrightnessNitsForDefaultDisplay);
-
- mDisplayDeviceConfig = logicalDisplay.getPrimaryDisplayDeviceLocked()
- .getDisplayDeviceConfig();
-
- loadBrightnessRampRates();
- mSkipScreenOnBrightnessRamp = resources.getBoolean(
- com.android.internal.R.bool.config_skipScreenOnBrightnessRamp);
- Runnable modeChangeCallback = () -> {
- sendUpdatePowerState();
- postBrightnessChangeRunnable();
- // TODO(b/192258832): Switch the HBMChangeCallback to a listener pattern.
- if (mAutomaticBrightnessController != null) {
- mAutomaticBrightnessController.update();
- }
- };
-
- HighBrightnessModeController hbmController = createHbmControllerLocked(modeChangeCallback);
-
- mBrightnessRangeController = new BrightnessRangeController(hbmController,
- modeChangeCallback, mDisplayDeviceConfig, mHandler, flags,
- mDisplayDevice.getDisplayTokenLocked(),
- mDisplayDevice.getDisplayDeviceInfoLocked());
-
- mBrightnessThrottler = createBrightnessThrottlerLocked();
-
- // Seed the cached brightness
- saveBrightnessInfo(getScreenBrightnessSetting());
-
- DisplayWhiteBalanceSettings displayWhiteBalanceSettings = null;
- DisplayWhiteBalanceController displayWhiteBalanceController = null;
- if (mDisplayId == Display.DEFAULT_DISPLAY) {
- try {
- displayWhiteBalanceController = injector.getDisplayWhiteBalanceController(
- mHandler, mSensorManager, resources);
- displayWhiteBalanceSettings = new DisplayWhiteBalanceSettings(mContext, mHandler);
- displayWhiteBalanceSettings.setCallbacks(this);
- displayWhiteBalanceController.setCallbacks(this);
- } catch (Exception e) {
- Slog.e(mTag, "failed to set up display white-balance: " + e);
- }
- }
- mDisplayWhiteBalanceSettings = displayWhiteBalanceSettings;
- mDisplayWhiteBalanceController = displayWhiteBalanceController;
-
- loadNitsRange(resources);
-
- if (mDisplayId == Display.DEFAULT_DISPLAY) {
- mCdsi = LocalServices.getService(ColorDisplayServiceInternal.class);
- boolean active = mCdsi.setReduceBrightColorsListener(new ReduceBrightColorsListener() {
- @Override
- public void onReduceBrightColorsActivationChanged(boolean activated,
- boolean userInitiated) {
- applyReduceBrightColorsSplineAdjustment();
-
- }
-
- @Override
- public void onReduceBrightColorsStrengthChanged(int strength) {
- applyReduceBrightColorsSplineAdjustment();
- }
- });
- if (active) {
- applyReduceBrightColorsSplineAdjustment();
- }
- } else {
- mCdsi = null;
- }
-
- setUpAutoBrightness(context, handler);
-
- mColorFadeEnabled = !ActivityManager.isLowRamDeviceStatic()
- && !resources.getBoolean(
- com.android.internal.R.bool.config_displayColorFadeDisabled);
- mColorFadeFadesConfig = resources.getBoolean(
- com.android.internal.R.bool.config_animateScreenLights);
-
- mDisplayBlanksAfterDozeConfig = resources.getBoolean(
- com.android.internal.R.bool.config_displayBlanksAfterDoze);
-
- mBrightnessBucketsInDozeConfig = resources.getBoolean(
- com.android.internal.R.bool.config_displayBrightnessBucketsInDoze);
-
- loadProximitySensor();
-
- loadNitBasedBrightnessSetting();
- mBrightnessToFollow = PowerManager.BRIGHTNESS_INVALID_FLOAT;
- mAutoBrightnessAdjustment = getAutoBrightnessAdjustmentSetting();
- mTemporaryScreenBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
- mPendingScreenBrightnessSetting = PowerManager.BRIGHTNESS_INVALID_FLOAT;
- mTemporaryAutoBrightnessAdjustment = PowerManager.BRIGHTNESS_INVALID_FLOAT;
- mPendingAutoBrightnessAdjustment = PowerManager.BRIGHTNESS_INVALID_FLOAT;
-
- mBootCompleted = bootCompleted;
- }
-
- private void applyReduceBrightColorsSplineAdjustment() {
- mHandler.obtainMessage(MSG_UPDATE_RBC).sendToTarget();
- sendUpdatePowerState();
- }
-
- private void handleRbcChanged() {
- if (mAutomaticBrightnessController == null) {
- return;
- }
-
- float[] adjustedNits = new float[mNitsRange.length];
- for (int i = 0; i < mNitsRange.length; i++) {
- adjustedNits[i] = mCdsi.getReduceBrightColorsAdjustedBrightnessNits(mNitsRange[i]);
- }
- mIsRbcActive = mCdsi.isReduceBrightColorsActivated();
- mAutomaticBrightnessController.recalculateSplines(mIsRbcActive, adjustedNits);
- }
-
- /**
- * Returns true if the proximity sensor screen-off function is available.
- */
- @Override
- public boolean isProximitySensorAvailable() {
- return mProximitySensor != null;
- }
-
- /**
- * Get the {@link BrightnessChangeEvent}s for the specified user.
- *
- * @param userId userId to fetch data for
- * @param includePackage if false will null out the package name in events
- */
- @Nullable
- @Override
- public ParceledListSlice<BrightnessChangeEvent> getBrightnessEvents(
- @UserIdInt int userId, boolean includePackage) {
- if (mBrightnessTracker == null) {
- return null;
- }
- return mBrightnessTracker.getEvents(userId, includePackage);
- }
-
- @Override
- public void onSwitchUser(@UserIdInt int newUserId) {
- Message msg = mHandler.obtainMessage(MSG_SWITCH_USER, newUserId);
- mHandler.sendMessage(msg);
- }
-
- private void handleOnSwitchUser(@UserIdInt int newUserId) {
- handleSettingsChange(true /* userSwitch */);
- handleBrightnessModeChange();
- if (mBrightnessTracker != null) {
- mBrightnessTracker.onSwitchUser(newUserId);
- }
- }
-
- @Override
- public int getDisplayId() {
- return mDisplayId;
- }
-
- @Override
- public int getLeadDisplayId() {
- return mLeadDisplayId;
- }
-
- @Override
- public void setBrightnessToFollow(float leadDisplayBrightness, float nits, float ambientLux,
- boolean slowChange) {
- mBrightnessRangeController.onAmbientLuxChange(ambientLux);
- if (nits == BrightnessMappingStrategy.INVALID_NITS) {
- mBrightnessToFollow = leadDisplayBrightness;
- } else {
- float brightness = getBrightnessFromNits(nits);
- if (isValidBrightnessValue(brightness)) {
- mBrightnessToFollow = brightness;
- } else {
- // The device does not support nits
- mBrightnessToFollow = leadDisplayBrightness;
- }
- }
- mBrightnessToFollowSlowChange = slowChange;
- sendUpdatePowerState();
- }
-
- @Override
- public void addDisplayBrightnessFollower(@NonNull DisplayPowerControllerInterface follower) {
- synchronized (mLock) {
- mDisplayBrightnessFollowers.append(follower.getDisplayId(), follower);
- sendUpdatePowerStateLocked();
- }
- }
-
- @Override
- public void removeDisplayBrightnessFollower(@NonNull DisplayPowerControllerInterface follower) {
- synchronized (mLock) {
- mDisplayBrightnessFollowers.remove(follower.getDisplayId());
- mHandler.postAtTime(() -> follower.setBrightnessToFollow(
- PowerManager.BRIGHTNESS_INVALID_FLOAT, BrightnessMappingStrategy.INVALID_NITS,
- /* ambientLux= */ 0, /* slowChange= */ false), mClock.uptimeMillis());
- }
- }
-
- @GuardedBy("mLock")
- private void clearDisplayBrightnessFollowersLocked() {
- for (int i = 0; i < mDisplayBrightnessFollowers.size(); i++) {
- DisplayPowerControllerInterface follower = mDisplayBrightnessFollowers.valueAt(i);
- mHandler.postAtTime(() -> follower.setBrightnessToFollow(
- PowerManager.BRIGHTNESS_INVALID_FLOAT, BrightnessMappingStrategy.INVALID_NITS,
- /* ambientLux= */ 0, /* slowChange= */ false), mClock.uptimeMillis());
- }
- mDisplayBrightnessFollowers.clear();
- }
-
- @Nullable
- @Override
- public ParceledListSlice<AmbientBrightnessDayStats> getAmbientBrightnessStats(
- @UserIdInt int userId) {
- if (mBrightnessTracker == null) {
- return null;
- }
- return mBrightnessTracker.getAmbientBrightnessStats(userId);
- }
-
- /**
- * Persist the brightness slider events and ambient brightness stats to disk.
- */
- @Override
- public void persistBrightnessTrackerState() {
- if (mBrightnessTracker != null) {
- mBrightnessTracker.persistBrightnessTrackerState();
- }
- }
-
- /**
- * Requests a new power state.
- * The controller makes a copy of the provided object and then
- * begins adjusting the power state to match what was requested.
- *
- * @param request The requested power state.
- * @param waitForNegativeProximity If true, issues a request to wait for
- * negative proximity before turning the screen back on,
- * assuming the screen
- * was turned off by the proximity sensor.
- * @return True if display is ready, false if there are important changes that must
- * be made asynchronously (such as turning the screen on), in which case the caller
- * should grab a wake lock, watch for {@link DisplayPowerCallbacks#onStateChanged()}
- * then try the request again later until the state converges.
- */
- public boolean requestPowerState(DisplayPowerRequest request,
- boolean waitForNegativeProximity) {
- if (DEBUG) {
- Slog.d(mTag, "requestPowerState: "
- + request + ", waitForNegativeProximity=" + waitForNegativeProximity);
- }
-
- synchronized (mLock) {
- if (mStopped) {
- return true;
- }
-
- boolean changed = false;
-
- if (waitForNegativeProximity
- && !mPendingWaitForNegativeProximityLocked) {
- mPendingWaitForNegativeProximityLocked = true;
- changed = true;
- }
-
- if (mPendingRequestLocked == null) {
- mPendingRequestLocked = new DisplayPowerRequest(request);
- changed = true;
- } else if (!mPendingRequestLocked.equals(request)) {
- mPendingRequestLocked.copyFrom(request);
- changed = true;
- }
-
- if (changed) {
- mDisplayReadyLocked = false;
- if (!mPendingRequestChangedLocked) {
- mPendingRequestChangedLocked = true;
- sendUpdatePowerStateLocked();
- }
- }
-
- return mDisplayReadyLocked;
- }
- }
-
- @Override
- public void overrideDozeScreenState(int displayState) {
- synchronized (mLock) {
- if (mDisplayOffloadSession == null ||
- !DisplayOffloadSession.isSupportedOffloadState(displayState)) {
- return;
- }
- mDozeStateOverride = displayState;
- sendUpdatePowerState();
- }
- }
-
- @Override
- public void setDisplayOffloadSession(DisplayOffloadSession session) {
- mDisplayOffloadSession = session;
- }
-
- @Override
- public BrightnessConfiguration getDefaultBrightnessConfiguration() {
- if (mAutomaticBrightnessController == null) {
- return null;
- }
- return mAutomaticBrightnessController.getDefaultConfig();
- }
-
- /**
- * Notified when the display is changed. We use this to apply any changes that might be needed
- * when displays get swapped on foldable devices. For example, different brightness properties
- * of each display need to be properly reflected in AutomaticBrightnessController.
- *
- * Make sure DisplayManagerService.mSyncRoot is held when this is called
- */
- @Override
- public void onDisplayChanged(HighBrightnessModeMetadata hbmMetadata, int leadDisplayId) {
- mLeadDisplayId = leadDisplayId;
- final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked();
- if (device == null) {
- Slog.wtf(mTag, "Display Device is null in DisplayPowerController for display: "
- + mLogicalDisplay.getDisplayIdLocked());
- return;
- }
-
- final String uniqueId = device.getUniqueId();
- final DisplayDeviceConfig config = device.getDisplayDeviceConfig();
- final IBinder token = device.getDisplayTokenLocked();
- final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
- final boolean isEnabled = mLogicalDisplay.isEnabledLocked();
- final boolean isInTransition = mLogicalDisplay.isInTransitionLocked();
- final boolean isDisplayInternal = mLogicalDisplay.getPrimaryDisplayDeviceLocked() != null
- && mLogicalDisplay.getPrimaryDisplayDeviceLocked()
- .getDisplayDeviceInfoLocked().type == Display.TYPE_INTERNAL;
- final String thermalBrightnessThrottlingDataId =
- mLogicalDisplay.getDisplayInfoLocked().thermalBrightnessThrottlingDataId;
- mHandler.postAtTime(() -> {
- boolean changed = false;
- if (mDisplayDevice != device) {
- changed = true;
- mDisplayDevice = device;
- mUniqueDisplayId = uniqueId;
- mDisplayStatsId = mUniqueDisplayId.hashCode();
- mDisplayDeviceConfig = config;
- mThermalBrightnessThrottlingDataId = thermalBrightnessThrottlingDataId;
- loadFromDisplayDeviceConfig(token, info, hbmMetadata);
- loadNitBasedBrightnessSetting();
-
- /// Since the underlying display-device changed, we really don't know the
- // last command that was sent to change it's state. Let's assume it is unknown so
- // that we trigger a change immediately.
- mPowerState.resetScreenState();
- } else if (!Objects.equals(mThermalBrightnessThrottlingDataId,
- thermalBrightnessThrottlingDataId)) {
- changed = true;
- mThermalBrightnessThrottlingDataId = thermalBrightnessThrottlingDataId;
- mBrightnessThrottler.loadThermalBrightnessThrottlingDataFromDisplayDeviceConfig(
- config.getThermalBrightnessThrottlingDataMapByThrottlingId(),
- mThermalBrightnessThrottlingDataId,
- mUniqueDisplayId);
- }
- if (mIsEnabled != isEnabled || mIsInTransition != isInTransition) {
- changed = true;
- mIsEnabled = isEnabled;
- mIsInTransition = isInTransition;
- }
- mIsDisplayInternal = isDisplayInternal;
- if (changed) {
- updatePowerState();
- }
- }, mClock.uptimeMillis());
- }
-
- /**
- * Unregisters all listeners and interrupts all running threads; halting future work.
- *
- * This method should be called when the DisplayPowerController is no longer in use; i.e. when
- * the {@link #mDisplayId display} has been removed.
- */
- @Override
- public void stop() {
- synchronized (mLock) {
- clearDisplayBrightnessFollowersLocked();
-
- mStopped = true;
- Message msg = mHandler.obtainMessage(MSG_STOP);
- mHandler.sendMessageAtTime(msg, mClock.uptimeMillis());
-
- if (mAutomaticBrightnessController != null) {
- mAutomaticBrightnessController.stop();
- }
-
- if (mBrightnessSetting != null) {
- mBrightnessSetting.unregisterListener(mBrightnessSettingListener);
- }
-
- mContext.getContentResolver().unregisterContentObserver(mSettingsObserver);
- }
- }
-
- private void loadFromDisplayDeviceConfig(IBinder token, DisplayDeviceInfo info,
- HighBrightnessModeMetadata hbmMetadata) {
- // All properties that depend on the associated DisplayDevice and the DDC must be
- // updated here.
- loadBrightnessRampRates();
- loadProximitySensor();
- loadNitsRange(mContext.getResources());
- setUpAutoBrightness(mContext, mHandler);
- reloadReduceBrightColours();
- setAnimatorRampSpeeds(/* isIdleMode= */ false);
- mBrightnessRangeController.loadFromConfig(hbmMetadata, token, info, mDisplayDeviceConfig);
- mBrightnessThrottler.loadThermalBrightnessThrottlingDataFromDisplayDeviceConfig(
- mDisplayDeviceConfig.getThermalBrightnessThrottlingDataMapByThrottlingId(),
- mThermalBrightnessThrottlingDataId, mUniqueDisplayId);
- }
-
- private void sendUpdatePowerState() {
- synchronized (mLock) {
- sendUpdatePowerStateLocked();
- }
- }
-
- @GuardedBy("mLock")
- private void sendUpdatePowerStateLocked() {
- if (!mStopped && !mPendingUpdatePowerStateLocked) {
- mPendingUpdatePowerStateLocked = true;
- Message msg = mHandler.obtainMessage(MSG_UPDATE_POWER_STATE);
- mHandler.sendMessageAtTime(msg, mClock.uptimeMillis());
- }
- }
-
- private void initialize(int displayState) {
- mPowerState = mInjector.getDisplayPowerState(mBlanker,
- mColorFadeEnabled ? new ColorFade(mDisplayId) : null, mDisplayId, displayState);
-
- if (mColorFadeEnabled) {
- mColorFadeOnAnimator = ObjectAnimator.ofFloat(
- mPowerState, DisplayPowerState.COLOR_FADE_LEVEL, 0.0f, 1.0f);
- mColorFadeOnAnimator.setDuration(COLOR_FADE_ON_ANIMATION_DURATION_MILLIS);
- mColorFadeOnAnimator.addListener(mAnimatorListener);
-
- mColorFadeOffAnimator = ObjectAnimator.ofFloat(
- mPowerState, DisplayPowerState.COLOR_FADE_LEVEL, 1.0f, 0.0f);
- mColorFadeOffAnimator.setDuration(COLOR_FADE_OFF_ANIMATION_DURATION_MILLIS);
- mColorFadeOffAnimator.addListener(mAnimatorListener);
- }
-
- mScreenBrightnessRampAnimator = mInjector.getDualRampAnimator(mPowerState,
- DisplayPowerState.SCREEN_BRIGHTNESS_FLOAT,
- DisplayPowerState.SCREEN_SDR_BRIGHTNESS_FLOAT);
- setAnimatorRampSpeeds(mAutomaticBrightnessController != null
- && mAutomaticBrightnessController.isInIdleMode());
- mScreenBrightnessRampAnimator.setListener(mRampAnimatorListener);
-
- noteScreenState(mPowerState.getScreenState());
- noteScreenBrightness(mPowerState.getScreenBrightness());
-
- // Initialize all of the brightness tracking state
- final float brightness = convertToAdjustedNits(mPowerState.getScreenBrightness());
- if (mBrightnessTracker != null && brightness >= PowerManager.BRIGHTNESS_MIN) {
- mBrightnessTracker.start(brightness);
- }
- mBrightnessSettingListener = brightnessValue -> {
- Message msg = mHandler.obtainMessage(MSG_UPDATE_BRIGHTNESS, brightnessValue);
- mHandler.sendMessageAtTime(msg, mClock.uptimeMillis());
- };
-
- mBrightnessSetting.registerListener(mBrightnessSettingListener);
- mContext.getContentResolver().registerContentObserver(
- Settings.System.getUriFor(Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ),
- false /*notifyForDescendants*/, mSettingsObserver, UserHandle.USER_ALL);
- mContext.getContentResolver().registerContentObserver(
- Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_MODE),
- false /*notifyForDescendants*/, mSettingsObserver, UserHandle.USER_ALL);
- handleBrightnessModeChange();
- }
-
- private void setUpAutoBrightness(Context context, Handler handler) {
- mUseSoftwareAutoBrightnessConfig = mDisplayDeviceConfig.isAutoBrightnessAvailable();
-
- if (!mUseSoftwareAutoBrightnessConfig) {
- return;
- }
-
- SparseArray<BrightnessMappingStrategy> brightnessMappers = new SparseArray<>();
-
- BrightnessMappingStrategy defaultModeBrightnessMapper =
- mInjector.getDefaultModeBrightnessMapper(context, mDisplayDeviceConfig,
- mDisplayWhiteBalanceController);
- brightnessMappers.append(AUTO_BRIGHTNESS_MODE_DEFAULT,
- defaultModeBrightnessMapper);
-
- final boolean isIdleScreenBrightnessEnabled = context.getResources().getBoolean(
- R.bool.config_enableIdleScreenBrightnessMode);
- if (isIdleScreenBrightnessEnabled) {
- BrightnessMappingStrategy idleModeBrightnessMapper =
- BrightnessMappingStrategy.create(context, mDisplayDeviceConfig,
- AUTO_BRIGHTNESS_MODE_IDLE, mDisplayWhiteBalanceController);
- if (idleModeBrightnessMapper != null) {
- brightnessMappers.append(AUTO_BRIGHTNESS_MODE_IDLE, idleModeBrightnessMapper);
- }
- }
-
- float userLux = BrightnessMappingStrategy.INVALID_LUX;
- float userNits = BrightnessMappingStrategy.INVALID_NITS;
- if (mAutomaticBrightnessController != null) {
- userLux = mAutomaticBrightnessController.getUserLux();
- userNits = mAutomaticBrightnessController.getUserNits();
- }
-
- if (defaultModeBrightnessMapper != null) {
- final float dozeScaleFactor = context.getResources().getFraction(
- com.android.internal.R.fraction.config_screenAutoBrightnessDozeScaleFactor,
- 1, 1);
-
- // Ambient Lux - Active Mode Brightness Thresholds
- float[] ambientBrighteningThresholds =
- mDisplayDeviceConfig.getAmbientBrighteningPercentages();
- float[] ambientDarkeningThresholds =
- mDisplayDeviceConfig.getAmbientDarkeningPercentages();
- float[] ambientBrighteningLevels =
- mDisplayDeviceConfig.getAmbientBrighteningLevels();
- float[] ambientDarkeningLevels =
- mDisplayDeviceConfig.getAmbientDarkeningLevels();
- float ambientDarkeningMinThreshold =
- mDisplayDeviceConfig.getAmbientLuxDarkeningMinThreshold();
- float ambientBrighteningMinThreshold =
- mDisplayDeviceConfig.getAmbientLuxBrighteningMinThreshold();
- HysteresisLevels ambientBrightnessThresholds = mInjector.getHysteresisLevels(
- ambientBrighteningThresholds, ambientDarkeningThresholds,
- ambientBrighteningLevels, ambientDarkeningLevels, ambientDarkeningMinThreshold,
- ambientBrighteningMinThreshold);
-
- // Display - Active Mode Brightness Thresholds
- float[] screenBrighteningThresholds =
- mDisplayDeviceConfig.getScreenBrighteningPercentages();
- float[] screenDarkeningThresholds =
- mDisplayDeviceConfig.getScreenDarkeningPercentages();
- float[] screenBrighteningLevels =
- mDisplayDeviceConfig.getScreenBrighteningLevels();
- float[] screenDarkeningLevels =
- mDisplayDeviceConfig.getScreenDarkeningLevels();
- float screenDarkeningMinThreshold =
- mDisplayDeviceConfig.getScreenDarkeningMinThreshold();
- float screenBrighteningMinThreshold =
- mDisplayDeviceConfig.getScreenBrighteningMinThreshold();
- HysteresisLevels screenBrightnessThresholds = mInjector.getHysteresisLevels(
- screenBrighteningThresholds, screenDarkeningThresholds,
- screenBrighteningLevels, screenDarkeningLevels, screenDarkeningMinThreshold,
- screenBrighteningMinThreshold, true);
-
- // Ambient Lux - Idle Screen Brightness Thresholds
- float ambientDarkeningMinThresholdIdle =
- mDisplayDeviceConfig.getAmbientLuxDarkeningMinThresholdIdle();
- float ambientBrighteningMinThresholdIdle =
- mDisplayDeviceConfig.getAmbientLuxBrighteningMinThresholdIdle();
- float[] ambientBrighteningThresholdsIdle =
- mDisplayDeviceConfig.getAmbientBrighteningPercentagesIdle();
- float[] ambientDarkeningThresholdsIdle =
- mDisplayDeviceConfig.getAmbientDarkeningPercentagesIdle();
- float[] ambientBrighteningLevelsIdle =
- mDisplayDeviceConfig.getAmbientBrighteningLevelsIdle();
- float[] ambientDarkeningLevelsIdle =
- mDisplayDeviceConfig.getAmbientDarkeningLevelsIdle();
- HysteresisLevels ambientBrightnessThresholdsIdle = mInjector.getHysteresisLevels(
- ambientBrighteningThresholdsIdle, ambientDarkeningThresholdsIdle,
- ambientBrighteningLevelsIdle, ambientDarkeningLevelsIdle,
- ambientDarkeningMinThresholdIdle, ambientBrighteningMinThresholdIdle);
-
- // Display - Idle Screen Brightness Thresholds
- float screenDarkeningMinThresholdIdle =
- mDisplayDeviceConfig.getScreenDarkeningMinThresholdIdle();
- float screenBrighteningMinThresholdIdle =
- mDisplayDeviceConfig.getScreenBrighteningMinThresholdIdle();
- float[] screenBrighteningThresholdsIdle =
- mDisplayDeviceConfig.getScreenBrighteningPercentagesIdle();
- float[] screenDarkeningThresholdsIdle =
- mDisplayDeviceConfig.getScreenDarkeningPercentagesIdle();
- float[] screenBrighteningLevelsIdle =
- mDisplayDeviceConfig.getScreenBrighteningLevelsIdle();
- float[] screenDarkeningLevelsIdle =
- mDisplayDeviceConfig.getScreenDarkeningLevelsIdle();
- HysteresisLevels screenBrightnessThresholdsIdle = mInjector.getHysteresisLevels(
- screenBrighteningThresholdsIdle, screenDarkeningThresholdsIdle,
- screenBrighteningLevelsIdle, screenDarkeningLevelsIdle,
- screenDarkeningMinThresholdIdle, screenBrighteningMinThresholdIdle);
-
- long brighteningLightDebounce = mDisplayDeviceConfig
- .getAutoBrightnessBrighteningLightDebounce();
- long darkeningLightDebounce = mDisplayDeviceConfig
- .getAutoBrightnessDarkeningLightDebounce();
- long brighteningLightDebounceIdle = mDisplayDeviceConfig
- .getAutoBrightnessBrighteningLightDebounceIdle();
- long darkeningLightDebounceIdle = mDisplayDeviceConfig
- .getAutoBrightnessDarkeningLightDebounceIdle();
- boolean autoBrightnessResetAmbientLuxAfterWarmUp = context.getResources().getBoolean(
- com.android.internal.R.bool.config_autoBrightnessResetAmbientLuxAfterWarmUp);
-
- int lightSensorWarmUpTimeConfig = context.getResources().getInteger(
- com.android.internal.R.integer.config_lightSensorWarmupTime);
- int lightSensorRate = context.getResources().getInteger(
- com.android.internal.R.integer.config_autoBrightnessLightSensorRate);
- int initialLightSensorRate = context.getResources().getInteger(
- com.android.internal.R.integer.config_autoBrightnessInitialLightSensorRate);
- if (initialLightSensorRate == -1) {
- initialLightSensorRate = lightSensorRate;
- } else if (initialLightSensorRate > lightSensorRate) {
- Slog.w(mTag, "Expected config_autoBrightnessInitialLightSensorRate ("
- + initialLightSensorRate + ") to be less than or equal to "
- + "config_autoBrightnessLightSensorRate (" + lightSensorRate + ").");
- }
-
- loadAmbientLightSensor();
- // BrightnessTracker should only use one light sensor, we want to use the light sensor
- // from the default display and not e.g. temporary displays when switching layouts.
- if (mBrightnessTracker != null && mDisplayId == Display.DEFAULT_DISPLAY) {
- mBrightnessTracker.setLightSensor(mLightSensor);
- }
-
- if (mAutomaticBrightnessController != null) {
- mAutomaticBrightnessController.stop();
- }
- mAutomaticBrightnessController = mInjector.getAutomaticBrightnessController(
- this, handler.getLooper(), mSensorManager, mLightSensor,
- brightnessMappers, lightSensorWarmUpTimeConfig, PowerManager.BRIGHTNESS_MIN,
- PowerManager.BRIGHTNESS_MAX, dozeScaleFactor, lightSensorRate,
- initialLightSensorRate, brighteningLightDebounce, darkeningLightDebounce,
- brighteningLightDebounceIdle, darkeningLightDebounceIdle,
- autoBrightnessResetAmbientLuxAfterWarmUp, ambientBrightnessThresholds,
- screenBrightnessThresholds, ambientBrightnessThresholdsIdle,
- screenBrightnessThresholdsIdle, mContext, mBrightnessRangeController,
- mBrightnessThrottler, mDisplayDeviceConfig.getAmbientHorizonShort(),
- mDisplayDeviceConfig.getAmbientHorizonLong(), userLux, userNits);
-
- mBrightnessEventRingBuffer =
- new RingBuffer<>(BrightnessEvent.class, RINGBUFFER_MAX);
-
- if (mScreenOffBrightnessSensorController != null) {
- mScreenOffBrightnessSensorController.stop();
- mScreenOffBrightnessSensorController = null;
- }
- loadScreenOffBrightnessSensor();
- int[] sensorValueToLux = mDisplayDeviceConfig.getScreenOffBrightnessSensorValueToLux();
- if (mScreenOffBrightnessSensor != null && sensorValueToLux != null) {
- mScreenOffBrightnessSensorController =
- mInjector.getScreenOffBrightnessSensorController(
- mSensorManager,
- mScreenOffBrightnessSensor,
- mHandler,
- SystemClock::uptimeMillis,
- sensorValueToLux,
- defaultModeBrightnessMapper);
- }
- } else {
- mUseSoftwareAutoBrightnessConfig = false;
- }
- }
-
- private void loadBrightnessRampRates() {
- mBrightnessRampRateFastDecrease = mDisplayDeviceConfig.getBrightnessRampFastDecrease();
- mBrightnessRampRateFastIncrease = mDisplayDeviceConfig.getBrightnessRampFastIncrease();
- mBrightnessRampRateSlowDecrease = mDisplayDeviceConfig.getBrightnessRampSlowDecrease();
- mBrightnessRampRateSlowIncrease = mDisplayDeviceConfig.getBrightnessRampSlowIncrease();
- mBrightnessRampRateSlowDecreaseIdle =
- mDisplayDeviceConfig.getBrightnessRampSlowDecreaseIdle();
- mBrightnessRampRateSlowIncreaseIdle =
- mDisplayDeviceConfig.getBrightnessRampSlowIncreaseIdle();
- mBrightnessRampDecreaseMaxTimeMillis =
- mDisplayDeviceConfig.getBrightnessRampDecreaseMaxMillis();
- mBrightnessRampIncreaseMaxTimeMillis =
- mDisplayDeviceConfig.getBrightnessRampIncreaseMaxMillis();
- mBrightnessRampDecreaseMaxTimeIdleMillis =
- mDisplayDeviceConfig.getBrightnessRampDecreaseMaxIdleMillis();
- mBrightnessRampIncreaseMaxTimeIdleMillis =
- mDisplayDeviceConfig.getBrightnessRampIncreaseMaxIdleMillis();
- }
-
- private void loadNitsRange(Resources resources) {
- if (mDisplayDeviceConfig != null && mDisplayDeviceConfig.getNits() != null) {
- mNitsRange = mDisplayDeviceConfig.getNits();
- } else {
- Slog.w(mTag, "Screen brightness nits configuration is unavailable; falling back");
- mNitsRange = BrightnessMappingStrategy.getFloatArray(resources
- .obtainTypedArray(com.android.internal.R.array.config_screenBrightnessNits));
- }
- }
-
- private void reloadReduceBrightColours() {
- if (mCdsi != null && mCdsi.isReduceBrightColorsActivated()) {
- applyReduceBrightColorsSplineAdjustment();
- }
- }
-
- @Override
- public void setAutomaticScreenBrightnessMode(
- @AutomaticBrightnessController.AutomaticBrightnessMode int mode) {
- boolean isIdle = mode == AUTO_BRIGHTNESS_MODE_IDLE;
- if (mAutomaticBrightnessController != null) {
- mAutomaticBrightnessController.switchMode(mode);
- setAnimatorRampSpeeds(isIdle);
- }
-
- Message msg = mHandler.obtainMessage();
- msg.what = MSG_SET_DWBC_STRONG_MODE;
- msg.arg1 = isIdle ? 1 : 0;
- mHandler.sendMessageAtTime(msg, mClock.uptimeMillis());
- }
-
- private void setAnimatorRampSpeeds(boolean isIdle) {
- if (mScreenBrightnessRampAnimator == null) {
- return;
- }
- if (mFlags.isAdaptiveTone1Enabled() && isIdle) {
- mScreenBrightnessRampAnimator.setAnimationTimeLimits(
- mBrightnessRampIncreaseMaxTimeIdleMillis,
- mBrightnessRampDecreaseMaxTimeIdleMillis);
- } else {
- mScreenBrightnessRampAnimator.setAnimationTimeLimits(
- mBrightnessRampIncreaseMaxTimeMillis,
- mBrightnessRampDecreaseMaxTimeMillis);
- }
- }
-
- private final Animator.AnimatorListener mAnimatorListener = new Animator.AnimatorListener() {
- @Override
- public void onAnimationStart(Animator animation) {
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- sendUpdatePowerState();
- }
-
- @Override
- public void onAnimationRepeat(Animator animation) {
- }
-
- @Override
- public void onAnimationCancel(Animator animation) {
- }
- };
-
- private final RampAnimator.Listener mRampAnimatorListener = new RampAnimator.Listener() {
- @Override
- public void onAnimationEnd() {
- sendUpdatePowerState();
- Message msg = mHandler.obtainMessage(MSG_BRIGHTNESS_RAMP_DONE);
- mHandler.sendMessageAtTime(msg, mClock.uptimeMillis());
- }
- };
-
- /** Clean up all resources that are accessed via the {@link #mHandler} thread. */
- private void cleanupHandlerThreadAfterStop() {
- setProximitySensorEnabled(false);
- mBrightnessRangeController.stop();
- mBrightnessThrottler.stop();
- mHandler.removeCallbacksAndMessages(null);
-
- // Release any outstanding wakelocks we're still holding because of pending messages.
- if (mUnfinishedBusiness) {
- mCallbacks.releaseSuspendBlocker(mSuspendBlockerIdUnfinishedBusiness);
- mUnfinishedBusiness = false;
- }
- if (mOnStateChangedPending) {
- mCallbacks.releaseSuspendBlocker(mSuspendBlockerIdOnStateChanged);
- mOnStateChangedPending = false;
- }
- for (int i = 0; i < mOnProximityPositiveMessages; i++) {
- mCallbacks.releaseSuspendBlocker(mSuspendBlockerIdProxPositive);
- }
- mOnProximityPositiveMessages = 0;
- for (int i = 0; i < mOnProximityNegativeMessages; i++) {
- mCallbacks.releaseSuspendBlocker(mSuspendBlockerIdProxNegative);
- }
- mOnProximityNegativeMessages = 0;
-
- final float brightness = mPowerState != null
- ? mPowerState.getScreenBrightness()
- : PowerManager.BRIGHTNESS_MIN;
- reportStats(brightness);
-
- if (mPowerState != null) {
- mPowerState.stop();
- mPowerState = null;
- }
-
- if (mScreenOffBrightnessSensorController != null) {
- mScreenOffBrightnessSensorController.stop();
- }
- if (mDisplayWhiteBalanceController != null) {
- mDisplayWhiteBalanceController.setEnabled(false);
- }
-
- }
-
- // Call from handler thread
- private void updatePowerState() {
- Trace.traceBegin(Trace.TRACE_TAG_POWER,
- "DisplayPowerController#updatePowerState");
- updatePowerStateInternal();
- Trace.traceEnd(Trace.TRACE_TAG_POWER);
- }
-
- private void updatePowerStateInternal() {
- // Update the power state request.
- final boolean mustNotify;
- final int previousPolicy;
- boolean mustInitialize = false;
- int brightnessAdjustmentFlags = 0;
- mBrightnessReasonTemp.set(null);
- mTempBrightnessEvent.reset();
- SparseArray<DisplayPowerControllerInterface> displayBrightnessFollowers;
- synchronized (mLock) {
- if (mStopped) {
- return;
- }
- mPendingUpdatePowerStateLocked = false;
- if (mPendingRequestLocked == null) {
- return; // wait until first actual power request
- }
-
- if (mPowerRequest == null) {
- mPowerRequest = new DisplayPowerRequest(mPendingRequestLocked);
- updatePendingProximityRequestsLocked();
- mPendingRequestChangedLocked = false;
- mustInitialize = true;
- // Assume we're on and bright until told otherwise, since that's the state we turn
- // on in.
- previousPolicy = DisplayPowerRequest.POLICY_BRIGHT;
- } else if (mPendingRequestChangedLocked) {
- previousPolicy = mPowerRequest.policy;
- mPowerRequest.copyFrom(mPendingRequestLocked);
- updatePendingProximityRequestsLocked();
- mPendingRequestChangedLocked = false;
- mDisplayReadyLocked = false;
- } else {
- previousPolicy = mPowerRequest.policy;
- }
-
- mustNotify = !mDisplayReadyLocked;
-
- displayBrightnessFollowers = mDisplayBrightnessFollowers.clone();
- }
-
- // Compute the basic display state using the policy.
- // We might override this below based on other factors.
- // Initialise brightness as invalid.
- int state;
- float brightnessState = PowerManager.BRIGHTNESS_INVALID_FLOAT;
- boolean performScreenOffTransition = false;
- switch (mPowerRequest.policy) {
- case DisplayPowerRequest.POLICY_OFF:
- state = Display.STATE_OFF;
- performScreenOffTransition = true;
- break;
- case DisplayPowerRequest.POLICY_DOZE:
- if (mDozeStateOverride != Display.STATE_UNKNOWN) {
- state = mDozeStateOverride;
- } else if (mPowerRequest.dozeScreenState != Display.STATE_UNKNOWN) {
- state = mPowerRequest.dozeScreenState;
- } else {
- state = Display.STATE_DOZE;
- }
- if (!mAllowAutoBrightnessWhileDozingConfig) {
- brightnessState = mPowerRequest.dozeScreenBrightness;
- mBrightnessReasonTemp.setReason(BrightnessReason.REASON_DOZE);
- }
- break;
- case DisplayPowerRequest.POLICY_DIM:
- case DisplayPowerRequest.POLICY_BRIGHT:
- default:
- state = Display.STATE_ON;
- break;
- }
- assert (state != Display.STATE_UNKNOWN);
-
- if (mScreenOffBrightnessSensorController != null) {
- mScreenOffBrightnessSensorController.setLightSensorEnabled(mUseAutoBrightness
- && mIsEnabled && (state == Display.STATE_OFF || (state == Display.STATE_DOZE
- && !mAllowAutoBrightnessWhileDozingConfig))
- && mLeadDisplayId == Layout.NO_LEAD_DISPLAY);
- }
-
- boolean skipRampBecauseOfProximityChangeToNegative = false;
- // Apply the proximity sensor.
- if (mProximitySensor != null) {
- if (mPowerRequest.useProximitySensor && state != Display.STATE_OFF) {
- // At this point the policy says that the screen should be on, but we've been
- // asked to listen to the prox sensor to adjust the display state, so lets make
- // sure the sensor is on.
- setProximitySensorEnabled(true);
- if (!mScreenOffBecauseOfProximity
- && mProximity == PROXIMITY_POSITIVE
- && !mIgnoreProximityUntilChanged) {
- // Prox sensor already reporting "near" so we should turn off the screen.
- // Also checked that we aren't currently set to ignore the proximity sensor
- // temporarily.
- mScreenOffBecauseOfProximity = true;
- sendOnProximityPositiveWithWakelock();
- }
- } else if (mWaitingForNegativeProximity
- && mScreenOffBecauseOfProximity
- && mProximity == PROXIMITY_POSITIVE
- && state != Display.STATE_OFF) {
- // The policy says that we should have the screen on, but it's off due to the prox
- // and we've been asked to wait until the screen is far from the user to turn it
- // back on. Let keep the prox sensor on so we can tell when it's far again.
- setProximitySensorEnabled(true);
- } else {
- // We haven't been asked to use the prox sensor and we're not waiting on the screen
- // to turn back on...so lets shut down the prox sensor.
- setProximitySensorEnabled(false);
- mWaitingForNegativeProximity = false;
- }
-
- if (mScreenOffBecauseOfProximity
- && (mProximity != PROXIMITY_POSITIVE || mIgnoreProximityUntilChanged)) {
- // The screen *was* off due to prox being near, but now it's "far" so lets turn
- // the screen back on. Also turn it back on if we've been asked to ignore the
- // prox sensor temporarily.
- mScreenOffBecauseOfProximity = false;
- skipRampBecauseOfProximityChangeToNegative = true;
- sendOnProximityNegativeWithWakelock();
- }
- } else {
- setProximitySensorEnabled(false);
- mWaitingForNegativeProximity = false;
- mIgnoreProximityUntilChanged = false;
-
- if (mScreenOffBecauseOfProximity) {
- // The screen *was* off due to prox being near, but now there's no prox sensor, so
- // let's turn the screen back on.
- mScreenOffBecauseOfProximity = false;
- skipRampBecauseOfProximityChangeToNegative = true;
- sendOnProximityNegativeWithWakelock();
- }
- }
-
- if (!mIsEnabled
- || mIsInTransition
- || mScreenOffBecauseOfProximity) {
- state = Display.STATE_OFF;
- }
-
- // Initialize things the first time the power state is changed.
- if (mustInitialize) {
- initialize(readyToUpdateDisplayState() ? state : Display.STATE_UNKNOWN);
- }
-
- // Animate the screen state change unless already animating.
- // The transition may be deferred, so after this point we will use the
- // actual state instead of the desired one.
- final int oldState = mPowerState.getScreenState();
- animateScreenStateChange(state, performScreenOffTransition);
- state = mPowerState.getScreenState();
- boolean slowChange = false;
-
- if (state == Display.STATE_OFF) {
- brightnessState = PowerManager.BRIGHTNESS_OFF_FLOAT;
- mBrightnessReasonTemp.setReason(BrightnessReason.REASON_SCREEN_OFF);
- }
-
- if (Float.isNaN(brightnessState) && isValidBrightnessValue(mBrightnessToFollow)) {
- brightnessState = mBrightnessToFollow;
- slowChange = mBrightnessToFollowSlowChange;
- mBrightnessReasonTemp.setReason(BrightnessReason.REASON_FOLLOWER);
- }
-
- if ((Float.isNaN(brightnessState))
- && isValidBrightnessValue(mPowerRequest.screenBrightnessOverride)) {
- brightnessState = mPowerRequest.screenBrightnessOverride;
- mBrightnessReasonTemp.setReason(BrightnessReason.REASON_OVERRIDE);
- mAppliedScreenBrightnessOverride = true;
- } else {
- mAppliedScreenBrightnessOverride = false;
- }
-
- final boolean autoBrightnessEnabledInDoze =
- mAllowAutoBrightnessWhileDozingConfig && Display.isDozeState(state);
- final boolean autoBrightnessEnabled = mUseAutoBrightness
- && (state == Display.STATE_ON || autoBrightnessEnabledInDoze)
- && mBrightnessReasonTemp.getReason() != BrightnessReason.REASON_OVERRIDE
- && mAutomaticBrightnessController != null;
- final boolean autoBrightnessDisabledDueToDisplayOff = mUseAutoBrightness
- && !(state == Display.STATE_ON || autoBrightnessEnabledInDoze);
- final int autoBrightnessState = autoBrightnessEnabled
- && mBrightnessReasonTemp.getReason() != BrightnessReason.REASON_FOLLOWER
- ? AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED
- : autoBrightnessDisabledDueToDisplayOff
- ? AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE
- : AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED;
-
- final boolean userSetBrightnessChanged = updateUserSetScreenBrightness();
-
- // Use the temporary screen brightness if there isn't an override, either from
- // WindowManager or based on the display state.
- if (isValidBrightnessValue(mTemporaryScreenBrightness)) {
- brightnessState = mTemporaryScreenBrightness;
- mAppliedTemporaryBrightness = true;
- mBrightnessReasonTemp.setReason(BrightnessReason.REASON_TEMPORARY);
- } else {
- mAppliedTemporaryBrightness = false;
- }
-
- final boolean autoBrightnessAdjustmentChanged = updateAutoBrightnessAdjustment();
-
- // Use the autobrightness adjustment override if set.
- final float autoBrightnessAdjustment;
- if (!Float.isNaN(mTemporaryAutoBrightnessAdjustment)) {
- autoBrightnessAdjustment = mTemporaryAutoBrightnessAdjustment;
- brightnessAdjustmentFlags = BrightnessReason.ADJUSTMENT_AUTO_TEMP;
- mAppliedTemporaryAutoBrightnessAdjustment = true;
- } else {
- autoBrightnessAdjustment = mAutoBrightnessAdjustment;
- brightnessAdjustmentFlags = BrightnessReason.ADJUSTMENT_AUTO;
- mAppliedTemporaryAutoBrightnessAdjustment = false;
- }
- // Apply brightness boost.
- // We do this here after deciding whether auto-brightness is enabled so that we don't
- // disable the light sensor during this temporary state. That way when boost ends we will
- // be able to resume normal auto-brightness behavior without any delay.
- if (mPowerRequest.boostScreenBrightness
- && brightnessState != PowerManager.BRIGHTNESS_OFF_FLOAT) {
- brightnessState = PowerManager.BRIGHTNESS_MAX;
- mBrightnessReasonTemp.setReason(BrightnessReason.REASON_BOOST);
- mAppliedBrightnessBoost = true;
- } else {
- mAppliedBrightnessBoost = false;
- }
-
- // If the brightness is already set then it's been overridden by something other than the
- // user, or is a temporary adjustment.
- boolean userInitiatedChange = (Float.isNaN(brightnessState))
- && (autoBrightnessAdjustmentChanged || userSetBrightnessChanged);
- boolean wasShortTermModelActive = false;
- // Configure auto-brightness.
- if (mAutomaticBrightnessController != null) {
- wasShortTermModelActive = mAutomaticBrightnessController.hasUserDataPoints();
- mAutomaticBrightnessController.configure(autoBrightnessState,
- mBrightnessConfiguration,
- mLastUserSetScreenBrightness,
- userSetBrightnessChanged, autoBrightnessAdjustment,
- autoBrightnessAdjustmentChanged, mPowerRequest.policy,
- mShouldResetShortTermModel);
- mShouldResetShortTermModel = false;
- }
- mBrightnessRangeController.setAutoBrightnessEnabled(autoBrightnessEnabled
- ? AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED
- : autoBrightnessDisabledDueToDisplayOff
- ? AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE
- : AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED);
-
- if (mBrightnessTracker != null) {
- mBrightnessTracker.setShouldCollectColorSample(mBrightnessConfiguration != null
- && mBrightnessConfiguration.shouldCollectColorSamples());
- }
-
- boolean updateScreenBrightnessSetting = false;
- float rawBrightnessState = brightnessState;
-
- // Apply auto-brightness.
- if (Float.isNaN(brightnessState)) {
- float newAutoBrightnessAdjustment = autoBrightnessAdjustment;
- if (autoBrightnessEnabled) {
- rawBrightnessState = mAutomaticBrightnessController
- .getRawAutomaticScreenBrightness();
- brightnessState = mAutomaticBrightnessController.getAutomaticScreenBrightness(
- mTempBrightnessEvent);
- newAutoBrightnessAdjustment =
- mAutomaticBrightnessController.getAutomaticScreenBrightnessAdjustment();
- }
- if (isValidBrightnessValue(brightnessState)
- || brightnessState == PowerManager.BRIGHTNESS_OFF_FLOAT) {
- // Use current auto-brightness value and slowly adjust to changes.
- brightnessState = clampScreenBrightness(brightnessState);
- if (mAppliedAutoBrightness && !autoBrightnessAdjustmentChanged) {
- slowChange = true; // slowly adapt to auto-brightness
- }
- updateScreenBrightnessSetting = mCurrentScreenBrightnessSetting != brightnessState;
- mAppliedAutoBrightness = true;
- mBrightnessReasonTemp.setReason(BrightnessReason.REASON_AUTOMATIC);
- if (mScreenOffBrightnessSensorController != null) {
- mScreenOffBrightnessSensorController.setLightSensorEnabled(false);
- }
- } else {
- mAppliedAutoBrightness = false;
- }
- if (autoBrightnessAdjustment != newAutoBrightnessAdjustment) {
- // If the autobrightness controller has decided to change the adjustment value
- // used, make sure that's reflected in settings.
- putAutoBrightnessAdjustmentSetting(newAutoBrightnessAdjustment);
- } else {
- // Adjustment values resulted in no change
- brightnessAdjustmentFlags = 0;
- }
- } else {
- // Any non-auto-brightness values such as override or temporary should still be subject
- // to clamping so that they don't go beyond the current max as specified by HBM
- // Controller.
- brightnessState = clampScreenBrightness(brightnessState);
- mAppliedAutoBrightness = false;
- brightnessAdjustmentFlags = 0;
- }
- // Use default brightness when dozing unless overridden.
- if ((Float.isNaN(brightnessState))
- && Display.isDozeState(state)) {
- rawBrightnessState = mScreenBrightnessDozeConfig;
- brightnessState = clampScreenBrightness(rawBrightnessState);
- mBrightnessReasonTemp.setReason(BrightnessReason.REASON_DOZE_DEFAULT);
- }
-
- // The ALS is not available yet - use the screen off sensor to determine the initial
- // brightness
- if (Float.isNaN(brightnessState) && autoBrightnessEnabled
- && mScreenOffBrightnessSensorController != null) {
- rawBrightnessState =
- mScreenOffBrightnessSensorController.getAutomaticScreenBrightness();
- brightnessState = rawBrightnessState;
- if (isValidBrightnessValue(brightnessState)) {
- brightnessState = clampScreenBrightness(brightnessState);
- updateScreenBrightnessSetting = mCurrentScreenBrightnessSetting != brightnessState;
- mBrightnessReasonTemp.setReason(
- BrightnessReason.REASON_SCREEN_OFF_BRIGHTNESS_SENSOR);
- }
- }
-
- // Apply manual brightness.
- if (Float.isNaN(brightnessState)) {
- rawBrightnessState = mCurrentScreenBrightnessSetting;
- brightnessState = clampScreenBrightness(rawBrightnessState);
- if (brightnessState != mCurrentScreenBrightnessSetting) {
- // The manually chosen screen brightness is outside of the currently allowed
- // range (i.e., high-brightness-mode), make sure we tell the rest of the system
- // by updating the setting.
- updateScreenBrightnessSetting = true;
- }
- mBrightnessReasonTemp.setReason(BrightnessReason.REASON_MANUAL);
- }
-
- float ambientLux = mAutomaticBrightnessController == null ? 0
- : mAutomaticBrightnessController.getAmbientLux();
- for (int i = 0; i < displayBrightnessFollowers.size(); i++) {
- DisplayPowerControllerInterface follower = displayBrightnessFollowers.valueAt(i);
- follower.setBrightnessToFollow(rawBrightnessState, convertToNits(rawBrightnessState),
- ambientLux, slowChange);
- }
-
- // Now that a desired brightness has been calculated, apply brightness throttling. The
- // dimming and low power transformations that follow can only dim brightness further.
- //
- // We didn't do this earlier through brightness clamping because we need to know both
- // unthrottled (unclamped/ideal) and throttled brightness levels for subsequent operations.
- // Note throttling effectively changes the allowed brightness range, so, similarly to HBM,
- // we broadcast this change through setting.
- final float unthrottledBrightnessState = brightnessState;
- if (mBrightnessThrottler.isThrottled()) {
- mTempBrightnessEvent.setThermalMax(mBrightnessThrottler.getBrightnessCap());
- brightnessState = Math.min(brightnessState, mBrightnessThrottler.getBrightnessCap());
- mBrightnessReasonTemp.addModifier(BrightnessReason.MODIFIER_THROTTLED);
- if (!mAppliedThrottling) {
- // Brightness throttling is needed, so do so quickly.
- // Later, when throttling is removed, we let other mechanisms decide on speed.
- slowChange = false;
- }
- mAppliedThrottling = true;
- } else if (mAppliedThrottling) {
- mAppliedThrottling = false;
- }
-
- if (updateScreenBrightnessSetting) {
- // Tell the rest of the system about the new brightness in case we had to change it
- // for things like auto-brightness or high-brightness-mode. Note that we do this
- // before applying the low power or dim transformations so that the slider
- // accurately represents the full possible range, even if they range changes what
- // it means in absolute terms.
- updateScreenBrightnessSetting(brightnessState);
- }
-
- // Apply dimming by at least some minimum amount when user activity
- // timeout is about to expire.
- if (mPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) {
- if (brightnessState > PowerManager.BRIGHTNESS_MIN) {
- brightnessState = Math.max(
- Math.min(brightnessState - mScreenBrightnessMinimumDimAmount,
- mScreenBrightnessDimConfig),
- PowerManager.BRIGHTNESS_MIN);
- mBrightnessReasonTemp.addModifier(BrightnessReason.MODIFIER_DIMMED);
- }
- if (!mAppliedDimming) {
- slowChange = false;
- }
- mAppliedDimming = true;
- } else if (mAppliedDimming) {
- slowChange = false;
- mAppliedDimming = false;
- }
- // If low power mode is enabled, scale brightness by screenLowPowerBrightnessFactor
- // as long as it is above the minimum threshold.
- if (mPowerRequest.lowPowerMode) {
- if (brightnessState > PowerManager.BRIGHTNESS_MIN) {
- final float brightnessFactor =
- Math.min(mPowerRequest.screenLowPowerBrightnessFactor, 1);
- final float lowPowerBrightnessFloat = (brightnessState * brightnessFactor);
- brightnessState = Math.max(lowPowerBrightnessFloat, PowerManager.BRIGHTNESS_MIN);
- mBrightnessReasonTemp.addModifier(BrightnessReason.MODIFIER_LOW_POWER);
- }
- if (!mAppliedLowPower) {
- slowChange = false;
- }
- mAppliedLowPower = true;
- } else if (mAppliedLowPower) {
- slowChange = false;
- mAppliedLowPower = false;
- }
-
- // The current brightness to use has been calculated at this point, and HbmController should
- // be notified so that it can accurately calculate HDR or HBM levels. We specifically do it
- // here instead of having HbmController listen to the brightness setting because certain
- // brightness sources (such as an app override) are not saved to the setting, but should be
- // reflected in HBM calculations.
- mBrightnessRangeController.onBrightnessChanged(brightnessState, unthrottledBrightnessState,
- mBrightnessThrottler.getBrightnessMaxReason());
-
- // Animate the screen brightness when the screen is on or dozing.
- // Skip the animation when the screen is off.
- boolean brightnessAdjusted = false;
- final boolean brightnessIsTemporary =
- mAppliedTemporaryBrightness || mAppliedTemporaryAutoBrightnessAdjustment;
- if (!mPendingScreenOff) {
- if (mSkipScreenOnBrightnessRamp) {
- if (state == Display.STATE_ON) {
- if (mSkipRampState == RAMP_STATE_SKIP_NONE && mDozing) {
- mInitialAutoBrightness = brightnessState;
- mSkipRampState = RAMP_STATE_SKIP_INITIAL;
- } else if (mSkipRampState == RAMP_STATE_SKIP_INITIAL
- && mUseSoftwareAutoBrightnessConfig
- && !BrightnessSynchronizer.floatEquals(brightnessState,
- mInitialAutoBrightness)) {
- mSkipRampState = RAMP_STATE_SKIP_AUTOBRIGHT;
- } else if (mSkipRampState == RAMP_STATE_SKIP_AUTOBRIGHT) {
- mSkipRampState = RAMP_STATE_SKIP_NONE;
- }
- } else {
- mSkipRampState = RAMP_STATE_SKIP_NONE;
- }
- }
-
- final boolean initialRampSkip = (state == Display.STATE_ON && mSkipRampState
- != RAMP_STATE_SKIP_NONE) || skipRampBecauseOfProximityChangeToNegative;
- // While dozing, sometimes the brightness is split into buckets. Rather than animating
- // through the buckets, which is unlikely to be smooth in the first place, just jump
- // right to the suggested brightness.
- final boolean hasBrightnessBuckets =
- Display.isDozeState(state) && mBrightnessBucketsInDozeConfig;
- // If the color fade is totally covering the screen then we can change the backlight
- // level without it being a noticeable jump since any actual content isn't yet visible.
- final boolean isDisplayContentVisible =
- mColorFadeEnabled && mPowerState.getColorFadeLevel() == 1.0f;
- // We only want to animate the brightness if it is between 0.0f and 1.0f.
- // brightnessState can contain the values -1.0f and NaN, which we do not want to
- // animate to. To avoid this, we check the value first.
- // If the brightnessState is off (-1.0f) we still want to animate to the minimum
- // brightness (0.0f) to accommodate for LED displays, which can appear bright to the
- // user even when the display is all black. We also clamp here in case some
- // transformations to the brightness have pushed it outside of the currently
- // allowed range.
- float animateValue = clampScreenBrightness(brightnessState);
-
- // If there are any HDR layers on the screen, we have a special brightness value that we
- // use instead. We still preserve the calculated brightness for Standard Dynamic Range
- // (SDR) layers, but the main brightness value will be the one for HDR.
- float sdrAnimateValue = animateValue;
- // TODO(b/216365040): The decision to prevent HBM for HDR in low power mode should be
- // done in HighBrightnessModeController.
- if (mBrightnessRangeController.getHighBrightnessMode()
- == BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR
- && (mBrightnessReasonTemp.getModifier() & BrightnessReason.MODIFIER_DIMMED) == 0
- && (mBrightnessReasonTemp.getModifier() & BrightnessReason.MODIFIER_LOW_POWER)
- == 0) {
- // We want to scale HDR brightness level with the SDR level, we also need to restore
- // SDR brightness immediately when entering dim or low power mode.
- animateValue = mBrightnessRangeController.getHdrBrightnessValue();
- mBrightnessReasonTemp.addModifier(BrightnessReason.MODIFIER_HDR);
- }
-
- final float currentBrightness = mPowerState.getScreenBrightness();
- final float currentSdrBrightness = mPowerState.getSdrScreenBrightness();
-
- if (isValidBrightnessValue(animateValue)
- && (animateValue != currentBrightness
- || sdrAnimateValue != currentSdrBrightness)) {
- boolean skipAnimation = initialRampSkip || hasBrightnessBuckets
- || !isDisplayContentVisible || brightnessIsTemporary;
- final boolean isHdrOnlyChange = BrightnessSynchronizer.floatEquals(
- sdrAnimateValue, currentSdrBrightness);
- if (mFlags.isFastHdrTransitionsEnabled() && !skipAnimation && isHdrOnlyChange) {
- // SDR brightness is unchanged, so animate quickly as this is only impacting
- // a likely minority amount of display content
- // ie, the highlights of an HDR video or UltraHDR image
- slowChange = false;
-
- // Going from HDR to no HDR; visually this should be a "no-op" anyway
- // as the remaining SDR content's brightness should be holding steady
- // due to the sdr brightness not shifting
- if (BrightnessSynchronizer.floatEquals(sdrAnimateValue, animateValue)) {
- skipAnimation = true;
- }
-
- // Going from no HDR to HDR; visually this is a significant scene change
- // and the animation just prevents advanced clients from doing their own
- // handling of enter/exit animations if they would like to do such a thing
- if (BrightnessSynchronizer.floatEquals(sdrAnimateValue, currentBrightness)) {
- skipAnimation = true;
- }
- }
- if (skipAnimation) {
- animateScreenBrightness(animateValue, sdrAnimateValue,
- SCREEN_ANIMATION_RATE_MINIMUM);
- } else {
- boolean isIncreasing = animateValue > currentBrightness;
- final float rampSpeed;
- final boolean idle = mAutomaticBrightnessController != null
- && mAutomaticBrightnessController.isInIdleMode();
- if (isIncreasing && slowChange) {
- rampSpeed = idle ? mBrightnessRampRateSlowIncreaseIdle
- : mBrightnessRampRateSlowIncrease;
- } else if (isIncreasing && !slowChange) {
- rampSpeed = mBrightnessRampRateFastIncrease;
- } else if (!isIncreasing && slowChange) {
- rampSpeed = idle ? mBrightnessRampRateSlowDecreaseIdle
- : mBrightnessRampRateSlowDecrease;
- } else {
- rampSpeed = mBrightnessRampRateFastDecrease;
- }
- animateScreenBrightness(animateValue, sdrAnimateValue, rampSpeed);
- }
- }
-
- notifyBrightnessTrackerChanged(brightnessState, userInitiatedChange,
- wasShortTermModelActive, autoBrightnessEnabled, brightnessIsTemporary);
-
- // We save the brightness info *after* the brightness setting has been changed and
- // adjustments made so that the brightness info reflects the latest value.
- brightnessAdjusted = saveBrightnessInfo(getScreenBrightnessSetting(), animateValue);
- } else {
- brightnessAdjusted = saveBrightnessInfo(getScreenBrightnessSetting());
- }
-
- // Only notify if the brightness adjustment is not temporary (i.e. slider has been released)
- if (brightnessAdjusted && !brightnessIsTemporary) {
- postBrightnessChangeRunnable();
- }
-
- // Log any changes to what is currently driving the brightness setting.
- if (!mBrightnessReasonTemp.equals(mBrightnessReason) || brightnessAdjustmentFlags != 0) {
- Slog.v(mTag, "Brightness [" + brightnessState + "] reason changing to: '"
- + mBrightnessReasonTemp.toString(brightnessAdjustmentFlags)
- + "', previous reason: '" + mBrightnessReason + "'.");
- mBrightnessReason.set(mBrightnessReasonTemp);
- } else if (mBrightnessReasonTemp.getReason() == BrightnessReason.REASON_MANUAL
- && userSetBrightnessChanged) {
- Slog.v(mTag, "Brightness [" + brightnessState + "] manual adjustment.");
- }
-
-
- // 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.setTime(System.currentTimeMillis());
- mTempBrightnessEvent.setBrightness(brightnessState);
- mTempBrightnessEvent.setPhysicalDisplayId(mUniqueDisplayId);
- mTempBrightnessEvent.setReason(mBrightnessReason);
- mTempBrightnessEvent.setHbmMax(mBrightnessRangeController.getCurrentBrightnessMax());
- mTempBrightnessEvent.setHbmMode(mBrightnessRangeController.getHighBrightnessMode());
- mTempBrightnessEvent.setFlags(mTempBrightnessEvent.getFlags()
- | (mIsRbcActive ? BrightnessEvent.FLAG_RBC : 0)
- | (mPowerRequest.lowPowerMode ? BrightnessEvent.FLAG_LOW_POWER_MODE : 0));
- mTempBrightnessEvent.setRbcStrength(mCdsi != null
- ? mCdsi.getReduceBrightColorsStrength() : -1);
- mTempBrightnessEvent.setPowerFactor(mPowerRequest.screenLowPowerBrightnessFactor);
- mTempBrightnessEvent.setWasShortTermModelActive(wasShortTermModelActive);
- mTempBrightnessEvent.setAutomaticBrightnessEnabled(mUseAutoBrightness);
- // 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.getReason().getReason() == BrightnessReason.REASON_TEMPORARY
- && mLastBrightnessEvent.getReason().getReason()
- == BrightnessReason.REASON_TEMPORARY;
- if ((!mTempBrightnessEvent.equalsMainData(mLastBrightnessEvent) && !tempToTempTransition)
- || brightnessAdjustmentFlags != 0) {
- mTempBrightnessEvent.setInitialBrightness(mLastBrightnessEvent.getBrightness());
- mLastBrightnessEvent.copyFrom(mTempBrightnessEvent);
- BrightnessEvent newEvent = new BrightnessEvent(mTempBrightnessEvent);
- // Adjustment flags (and user-set flag) only get added after the equality checks since
- // they are transient.
- newEvent.setAdjustmentFlags(brightnessAdjustmentFlags);
- newEvent.setFlags(newEvent.getFlags() | (userSetBrightnessChanged
- ? BrightnessEvent.FLAG_USER_SET : 0));
- Slog.i(mTag, newEvent.toString(/* includeTime= */ false));
-
- if (userSetBrightnessChanged
- || newEvent.getReason().getReason() != BrightnessReason.REASON_TEMPORARY) {
- logBrightnessEvent(newEvent, unthrottledBrightnessState);
- }
- if (mBrightnessEventRingBuffer != null) {
- mBrightnessEventRingBuffer.append(newEvent);
- }
- }
-
- // Update display white-balance.
- if (mDisplayWhiteBalanceController != null) {
- if (state == Display.STATE_ON && mDisplayWhiteBalanceSettings.isEnabled()) {
- mDisplayWhiteBalanceController.setEnabled(true);
- mDisplayWhiteBalanceController.updateDisplayColorTemperature();
- } else {
- mDisplayWhiteBalanceController.setEnabled(false);
- }
- }
-
- // Determine whether the display is ready for use in the newly requested state.
- // Note that we do not wait for the brightness ramp animation to complete before
- // reporting the display is ready because we only need to ensure the screen is in the
- // right power state even as it continues to converge on the desired brightness.
- final boolean ready = mPendingScreenOnUnblocker == null
- && (!mColorFadeEnabled || (!mColorFadeOnAnimator.isStarted()
- && !mColorFadeOffAnimator.isStarted()))
- && mPowerState.waitUntilClean(mCleanListener);
- final boolean finished = ready
- && !mScreenBrightnessRampAnimator.isAnimating();
-
- // Notify policy about screen turned on.
- if (ready && state != Display.STATE_OFF
- && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_ON) {
- setReportedScreenState(REPORTED_TO_POLICY_SCREEN_ON);
- mWindowManagerPolicy.screenTurnedOn(mDisplayId);
- }
-
- // Grab a wake lock if we have unfinished business.
- if (!finished && !mUnfinishedBusiness) {
- if (DEBUG) {
- Slog.d(mTag, "Unfinished business...");
- }
- mCallbacks.acquireSuspendBlocker(mSuspendBlockerIdUnfinishedBusiness);
- mUnfinishedBusiness = true;
- }
-
- // Notify the power manager when ready.
- if (ready && mustNotify) {
- // Send state change.
- synchronized (mLock) {
- if (!mPendingRequestChangedLocked) {
- mDisplayReadyLocked = true;
-
- if (DEBUG) {
- Slog.d(mTag, "Display ready!");
- }
- }
- }
- sendOnStateChangedWithWakelock();
- }
-
- // Release the wake lock when we have no unfinished business.
- if (finished && mUnfinishedBusiness) {
- if (DEBUG) {
- Slog.d(mTag, "Finished business...");
- }
- mUnfinishedBusiness = false;
- mCallbacks.releaseSuspendBlocker(mSuspendBlockerIdUnfinishedBusiness);
- }
-
- // Record if dozing for future comparison.
- mDozing = state != Display.STATE_ON;
-
- if (previousPolicy != mPowerRequest.policy) {
- logDisplayPolicyChanged(mPowerRequest.policy);
- }
- }
-
- private void setDwbcOverride(float cct) {
- if (mDisplayWhiteBalanceController != null) {
- mDisplayWhiteBalanceController.setAmbientColorTemperatureOverride(cct);
- // The ambient color temperature override is only applied when the ambient color
- // temperature changes or is updated, so it doesn't necessarily change the screen color
- // temperature immediately. So, let's make it!
- // We can call this directly, since we're already on the handler thread.
- updatePowerState();
- }
- }
-
- private void setDwbcStrongMode(int arg) {
- if (mDisplayWhiteBalanceController != null) {
- final boolean isIdle = (arg == 1);
- mDisplayWhiteBalanceController.setStrongModeEnabled(isIdle);
- }
- }
-
- private void setDwbcLoggingEnabled(int arg) {
- if (mDisplayWhiteBalanceController != null) {
- final boolean shouldEnable = (arg == 1);
- mDisplayWhiteBalanceController.setLoggingEnabled(shouldEnable);
- mDisplayWhiteBalanceSettings.setLoggingEnabled(shouldEnable);
- }
- }
-
- @Override
- public void updateBrightness() {
- sendUpdatePowerState();
- }
-
- /**
- * Ignores the proximity sensor until the sensor state changes, but only if the sensor is
- * currently enabled and forcing the screen to be dark.
- */
- @Override
- public void ignoreProximitySensorUntilChanged() {
- mHandler.sendEmptyMessage(MSG_IGNORE_PROXIMITY);
- }
-
- @Override
- public void setBrightnessConfiguration(BrightnessConfiguration c,
- boolean shouldResetShortTermModel) {
- Message msg = mHandler.obtainMessage(MSG_CONFIGURE_BRIGHTNESS,
- shouldResetShortTermModel ? 1 : 0, /* unused */ 0, c);
- msg.sendToTarget();
- }
-
- @Override
- public void setTemporaryBrightness(float brightness) {
- Message msg = mHandler.obtainMessage(MSG_SET_TEMPORARY_BRIGHTNESS,
- Float.floatToIntBits(brightness), 0 /*unused*/);
- msg.sendToTarget();
- }
-
- @Override
- public void setTemporaryAutoBrightnessAdjustment(float adjustment) {
- Message msg = mHandler.obtainMessage(MSG_SET_TEMPORARY_AUTO_BRIGHTNESS_ADJUSTMENT,
- Float.floatToIntBits(adjustment), 0 /*unused*/);
- msg.sendToTarget();
- }
-
- @Override
- public void setBrightnessFromOffload(float brightness) {
- // The old DPC is no longer supported
- }
-
- @Override
- public float[] getAutoBrightnessLevels(
- @AutomaticBrightnessController.AutomaticBrightnessMode int mode) {
- // The old DPC is no longer supported
- return null;
- }
-
- @Override
- public float[] getAutoBrightnessLuxLevels(
- @AutomaticBrightnessController.AutomaticBrightnessMode int mode) {
- // The old DPC is no longer supported
- return null;
- }
-
- @Override
- public BrightnessInfo getBrightnessInfo() {
- synchronized (mCachedBrightnessInfo) {
- return new BrightnessInfo(
- mCachedBrightnessInfo.brightness.value,
- mCachedBrightnessInfo.adjustedBrightness.value,
- mCachedBrightnessInfo.brightnessMin.value,
- mCachedBrightnessInfo.brightnessMax.value,
- mCachedBrightnessInfo.hbmMode.value,
- mCachedBrightnessInfo.hbmTransitionPoint.value,
- mCachedBrightnessInfo.brightnessMaxReason.value);
- }
- }
-
- private boolean saveBrightnessInfo(float brightness) {
- return saveBrightnessInfo(brightness, brightness);
- }
-
- private boolean saveBrightnessInfo(float brightness, float adjustedBrightness) {
- synchronized (mCachedBrightnessInfo) {
- final float minBrightness = Math.min(
- mBrightnessRangeController.getCurrentBrightnessMin(),
- mBrightnessThrottler.getBrightnessCap());
- final float maxBrightness = Math.min(
- mBrightnessRangeController.getCurrentBrightnessMax(),
- mBrightnessThrottler.getBrightnessCap());
- boolean changed = false;
-
- changed |=
- mCachedBrightnessInfo.checkAndSetFloat(mCachedBrightnessInfo.brightness,
- brightness);
- changed |=
- mCachedBrightnessInfo.checkAndSetFloat(mCachedBrightnessInfo.adjustedBrightness,
- adjustedBrightness);
- changed |=
- mCachedBrightnessInfo.checkAndSetFloat(mCachedBrightnessInfo.brightnessMin,
- minBrightness);
- changed |=
- mCachedBrightnessInfo.checkAndSetFloat(mCachedBrightnessInfo.brightnessMax,
- maxBrightness);
- changed |=
- mCachedBrightnessInfo.checkAndSetInt(mCachedBrightnessInfo.hbmMode,
- mBrightnessRangeController.getHighBrightnessMode());
- changed |=
- mCachedBrightnessInfo.checkAndSetFloat(mCachedBrightnessInfo.hbmTransitionPoint,
- mBrightnessRangeController.getTransitionPoint());
- changed |=
- mCachedBrightnessInfo.checkAndSetInt(mCachedBrightnessInfo.brightnessMaxReason,
- mBrightnessThrottler.getBrightnessMaxReason());
-
- return changed;
- }
- }
-
- void postBrightnessChangeRunnable() {
- if (!mHandler.hasCallbacks(mOnBrightnessChangeRunnable)) {
- mHandler.post(mOnBrightnessChangeRunnable);
- }
- }
-
- private HighBrightnessModeController createHbmControllerLocked(
- Runnable modeChangeCallback) {
- final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked();
- final DisplayDeviceConfig ddConfig = device.getDisplayDeviceConfig();
- final IBinder displayToken =
- mLogicalDisplay.getPrimaryDisplayDeviceLocked().getDisplayTokenLocked();
- final String displayUniqueId =
- mLogicalDisplay.getPrimaryDisplayDeviceLocked().getUniqueId();
- final DisplayDeviceConfig.HighBrightnessModeData hbmData =
- ddConfig != null ? ddConfig.getHighBrightnessModeData() : null;
- final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
- return mInjector.getHighBrightnessModeController(mHandler, info.width, info.height,
- displayToken, displayUniqueId, PowerManager.BRIGHTNESS_MIN,
- PowerManager.BRIGHTNESS_MAX, hbmData,
- new HighBrightnessModeController.HdrBrightnessDeviceConfig() {
- @Override
- public float getHdrBrightnessFromSdr(
- float sdrBrightness, float maxDesiredHdrSdrRatio) {
- return mDisplayDeviceConfig.getHdrBrightnessFromSdr(
- sdrBrightness, maxDesiredHdrSdrRatio);
- }
- }, modeChangeCallback, mHighBrightnessModeMetadata, mContext);
- }
-
- private BrightnessThrottler createBrightnessThrottlerLocked() {
- final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked();
- final DisplayDeviceConfig ddConfig = device.getDisplayDeviceConfig();
- return new BrightnessThrottler(mHandler,
- () -> {
- sendUpdatePowerState();
- postBrightnessChangeRunnable();
- }, mUniqueDisplayId,
- mLogicalDisplay.getDisplayInfoLocked().thermalBrightnessThrottlingDataId,
- ddConfig.getThermalBrightnessThrottlingDataMapByThrottlingId());
- }
-
- private void blockScreenOn() {
- if (mPendingScreenOnUnblocker == null) {
- Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, SCREEN_ON_BLOCKED_TRACE_NAME, 0);
- mPendingScreenOnUnblocker = new ScreenOnUnblocker();
- mScreenOnBlockStartRealTime = SystemClock.elapsedRealtime();
- Slog.i(mTag, "Blocking screen on until initial contents have been drawn.");
- }
- }
-
- private void unblockScreenOn() {
- if (mPendingScreenOnUnblocker != null) {
- mPendingScreenOnUnblocker = null;
- long delay = SystemClock.elapsedRealtime() - mScreenOnBlockStartRealTime;
- Slog.i(mTag, "Unblocked screen on after " + delay + " ms");
- Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, SCREEN_ON_BLOCKED_TRACE_NAME, 0);
- }
- }
-
- private void blockScreenOff() {
- if (mPendingScreenOffUnblocker == null) {
- Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, SCREEN_OFF_BLOCKED_TRACE_NAME, 0);
- mPendingScreenOffUnblocker = new ScreenOffUnblocker();
- mScreenOffBlockStartRealTime = SystemClock.elapsedRealtime();
- Slog.i(mTag, "Blocking screen off");
- }
- }
-
- private void unblockScreenOff() {
- if (mPendingScreenOffUnblocker != null) {
- mPendingScreenOffUnblocker = null;
- long delay = SystemClock.elapsedRealtime() - mScreenOffBlockStartRealTime;
- Slog.i(mTag, "Unblocked screen off after " + delay + " ms");
- Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, SCREEN_OFF_BLOCKED_TRACE_NAME, 0);
- }
- }
-
- private boolean setScreenState(int state) {
- return setScreenState(state, false /*reportOnly*/);
- }
-
- private boolean setScreenState(int state, boolean reportOnly) {
- final boolean isOff = (state == Display.STATE_OFF);
-
- if (mPowerState.getScreenState() != state
- || mReportedScreenStateToPolicy == REPORTED_TO_POLICY_UNREPORTED) {
- // If we are trying to turn screen off, give policy a chance to do something before we
- // actually turn the screen off.
- if (isOff && !mScreenOffBecauseOfProximity) {
- if (mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_ON
- || mReportedScreenStateToPolicy == REPORTED_TO_POLICY_UNREPORTED) {
- setReportedScreenState(REPORTED_TO_POLICY_SCREEN_TURNING_OFF);
- blockScreenOff();
- mWindowManagerPolicy.screenTurningOff(mDisplayId, mPendingScreenOffUnblocker);
- unblockScreenOff();
- } else if (mPendingScreenOffUnblocker != null) {
- // Abort doing the state change until screen off is unblocked.
- return false;
- }
- }
-
- if (!reportOnly && mPowerState.getScreenState() != state
- && readyToUpdateDisplayState()) {
- Trace.traceCounter(Trace.TRACE_TAG_POWER, "ScreenState", state);
-
- String propertyKey = "debug.tracing.screen_state";
- String propertyValue = String.valueOf(state);
- try {
- // TODO(b/153319140) remove when we can get this from the above trace invocation
- SystemProperties.set(propertyKey, propertyValue);
- } catch (RuntimeException e) {
- Slog.e(mTag, "Failed to set a system property: key=" + propertyKey
- + " value=" + propertyValue + " " + e.getMessage());
- }
-
- mPowerState.setScreenState(state);
- // Tell battery stats about the transition.
- noteScreenState(state);
- }
- }
-
- // Tell the window manager policy when the screen is turned off or on unless it's due
- // to the proximity sensor. We temporarily block turning the screen on until the
- // window manager is ready by leaving a black surface covering the screen.
- // This surface is essentially the final state of the color fade animation and
- // it is only removed once the window manager tells us that the activity has
- // finished drawing underneath.
- if (isOff && mReportedScreenStateToPolicy != REPORTED_TO_POLICY_SCREEN_OFF
- && !mScreenOffBecauseOfProximity) {
- setReportedScreenState(REPORTED_TO_POLICY_SCREEN_OFF);
- unblockScreenOn();
- mWindowManagerPolicy.screenTurnedOff(mDisplayId, mIsInTransition);
- } else if (!isOff
- && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_OFF) {
-
- // We told policy already that screen was turning off, but now we changed our minds.
- // Complete the full state transition on -> turningOff -> off.
- unblockScreenOff();
- mWindowManagerPolicy.screenTurnedOff(mDisplayId, mIsInTransition);
- setReportedScreenState(REPORTED_TO_POLICY_SCREEN_OFF);
- }
- if (!isOff
- && (mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_OFF
- || mReportedScreenStateToPolicy == REPORTED_TO_POLICY_UNREPORTED)) {
- setReportedScreenState(REPORTED_TO_POLICY_SCREEN_TURNING_ON);
- if (mPowerState.getColorFadeLevel() == 0.0f) {
- blockScreenOn();
- } else {
- unblockScreenOn();
- }
- mWindowManagerPolicy.screenTurningOn(mDisplayId, mPendingScreenOnUnblocker);
- }
-
- // Return true if the screen isn't blocked.
- return mPendingScreenOnUnblocker == null;
- }
-
- private void setReportedScreenState(int state) {
- Trace.traceCounter(Trace.TRACE_TAG_POWER, "ReportedScreenStateToPolicy", state);
- mReportedScreenStateToPolicy = state;
- }
-
- private void loadAmbientLightSensor() {
- final int fallbackType = mDisplayId == Display.DEFAULT_DISPLAY
- ? Sensor.TYPE_LIGHT : SensorUtils.NO_FALLBACK;
- mLightSensor = SensorUtils.findSensor(mSensorManager,
- mDisplayDeviceConfig.getAmbientLightSensor(), fallbackType);
- }
-
- private void loadScreenOffBrightnessSensor() {
- mScreenOffBrightnessSensor = SensorUtils.findSensor(mSensorManager,
- mDisplayDeviceConfig.getScreenOffBrightnessSensor(), SensorUtils.NO_FALLBACK);
- }
-
- private void loadProximitySensor() {
- if (DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT || mDisplayId != Display.DEFAULT_DISPLAY) {
- return;
- }
- mProximitySensor = SensorUtils.findSensor(mSensorManager,
- mDisplayDeviceConfig.getProximitySensor(), Sensor.TYPE_PROXIMITY);
- if (mProximitySensor != null) {
- mProximityThreshold = Math.min(mProximitySensor.getMaximumRange(),
- TYPICAL_PROXIMITY_THRESHOLD);
- }
- }
-
- private float clampScreenBrightness(float value) {
- if (Float.isNaN(value)) {
- value = PowerManager.BRIGHTNESS_MIN;
- }
- return MathUtils.constrain(value, mBrightnessRangeController.getCurrentBrightnessMin(),
- mBrightnessRangeController.getCurrentBrightnessMax());
- }
-
- // Checks whether the brightness is within the valid brightness range, not including off.
- private boolean isValidBrightnessValue(float brightness) {
- return brightness >= PowerManager.BRIGHTNESS_MIN
- && brightness <= PowerManager.BRIGHTNESS_MAX;
- }
-
- private void animateScreenBrightness(float target, float sdrTarget, float rate) {
- if (DEBUG) {
- Slog.d(mTag, "Animating brightness: target=" + target + ", sdrTarget=" + sdrTarget
- + ", rate=" + rate);
- }
- if (mScreenBrightnessRampAnimator.animateTo(target, sdrTarget, rate, false)) {
- Trace.traceCounter(Trace.TRACE_TAG_POWER, "TargetScreenBrightness", (int) target);
-
- String propertyKey = "debug.tracing.screen_brightness";
- String propertyValue = String.valueOf(target);
- try {
- // TODO(b/153319140) remove when we can get this from the above trace invocation
- SystemProperties.set(propertyKey, propertyValue);
- } catch (RuntimeException e) {
- Slog.e(mTag, "Failed to set a system property: key=" + propertyKey
- + " value=" + propertyValue + " " + e.getMessage());
- }
-
- noteScreenBrightness(target);
- }
- }
-
- private void animateScreenStateChange(int target, boolean performScreenOffTransition) {
- // If there is already an animation in progress, don't interfere with it.
- if (mColorFadeEnabled
- && (mColorFadeOnAnimator.isStarted() || mColorFadeOffAnimator.isStarted())) {
- if (target != Display.STATE_ON) {
- return;
- }
- // If display state changed to on, proceed and stop the color fade and turn screen on.
- mPendingScreenOff = false;
- }
-
- if (mDisplayBlanksAfterDozeConfig
- && Display.isDozeState(mPowerState.getScreenState())
- && !Display.isDozeState(target)) {
- // Skip the screen off animation and add a black surface to hide the
- // contents of the screen.
- mPowerState.prepareColorFade(mContext,
- mColorFadeFadesConfig ? ColorFade.MODE_FADE : ColorFade.MODE_WARM_UP);
- if (mColorFadeOffAnimator != null) {
- mColorFadeOffAnimator.end();
- }
- // Some display hardware will blank itself on the transition between doze and non-doze
- // but still on display states. In this case we want to report to policy that the
- // display has turned off so it can prepare the appropriate power on animation, but we
- // don't want to actually transition to the fully off state since that takes
- // significantly longer to transition from.
- setScreenState(Display.STATE_OFF, target != Display.STATE_OFF /*reportOnly*/);
- }
-
- // If we were in the process of turning off the screen but didn't quite
- // finish. Then finish up now to prevent a jarring transition back
- // to screen on if we skipped blocking screen on as usual.
- if (mPendingScreenOff && target != Display.STATE_OFF) {
- setScreenState(Display.STATE_OFF);
- mPendingScreenOff = false;
- mPowerState.dismissColorFadeResources();
- }
-
- if (target == Display.STATE_ON) {
- // Want screen on. The contents of the screen may not yet
- // be visible if the color fade has not been dismissed because
- // its last frame of animation is solid black.
- if (!setScreenState(Display.STATE_ON)) {
- return; // screen on blocked
- }
- if (USE_COLOR_FADE_ON_ANIMATION && mColorFadeEnabled && mPowerRequest.isBrightOrDim()) {
- // Perform screen on animation.
- if (mPowerState.getColorFadeLevel() == 1.0f) {
- mPowerState.dismissColorFade();
- } else if (mPowerState.prepareColorFade(mContext,
- mColorFadeFadesConfig
- ? ColorFade.MODE_FADE : ColorFade.MODE_WARM_UP)) {
- mColorFadeOnAnimator.start();
- } else {
- mColorFadeOnAnimator.end();
- }
- } else {
- // Skip screen on animation.
- mPowerState.setColorFadeLevel(1.0f);
- mPowerState.dismissColorFade();
- }
- } else if (target == Display.STATE_DOZE) {
- // Want screen dozing.
- // Wait for brightness animation to complete beforehand when entering doze
- // from screen on to prevent a perceptible jump because brightness may operate
- // differently when the display is configured for dozing.
- if (mScreenBrightnessRampAnimator.isAnimating()
- && mPowerState.getScreenState() == Display.STATE_ON) {
- return;
- }
-
- // Set screen state.
- if (!setScreenState(Display.STATE_DOZE)) {
- return; // screen on blocked
- }
-
- // Dismiss the black surface without fanfare.
- mPowerState.setColorFadeLevel(1.0f);
- mPowerState.dismissColorFade();
- } else if (target == Display.STATE_DOZE_SUSPEND) {
- // Want screen dozing and suspended.
- // Wait for brightness animation to complete beforehand unless already
- // suspended because we may not be able to change it after suspension.
- if (mScreenBrightnessRampAnimator.isAnimating()
- && mPowerState.getScreenState() != Display.STATE_DOZE_SUSPEND) {
- return;
- }
-
- // If not already suspending, temporarily set the state to doze until the
- // screen on is unblocked, then suspend.
- if (mPowerState.getScreenState() != Display.STATE_DOZE_SUSPEND) {
- if (!setScreenState(Display.STATE_DOZE)) {
- return; // screen on blocked
- }
- setScreenState(Display.STATE_DOZE_SUSPEND); // already on so can't block
- }
-
- // Dismiss the black surface without fanfare.
- mPowerState.setColorFadeLevel(1.0f);
- mPowerState.dismissColorFade();
- } else if (target == Display.STATE_ON_SUSPEND) {
- // Want screen full-power and suspended.
- // Wait for brightness animation to complete beforehand unless already
- // suspended because we may not be able to change it after suspension.
- if (mScreenBrightnessRampAnimator.isAnimating()
- && mPowerState.getScreenState() != Display.STATE_ON_SUSPEND) {
- return;
- }
-
- // If not already suspending, temporarily set the state to on until the
- // screen on is unblocked, then suspend.
- if (mPowerState.getScreenState() != Display.STATE_ON_SUSPEND) {
- if (!setScreenState(Display.STATE_ON)) {
- return;
- }
- setScreenState(Display.STATE_ON_SUSPEND);
- }
-
- // Dismiss the black surface without fanfare.
- mPowerState.setColorFadeLevel(1.0f);
- mPowerState.dismissColorFade();
- } else {
- // Want screen off.
- mPendingScreenOff = true;
- if (!mColorFadeEnabled) {
- mPowerState.setColorFadeLevel(0.0f);
- }
-
- if (mPowerState.getColorFadeLevel() == 0.0f) {
- // Turn the screen off.
- // A black surface is already hiding the contents of the screen.
- setScreenState(Display.STATE_OFF);
- mPendingScreenOff = false;
- mPowerState.dismissColorFadeResources();
- } else if (performScreenOffTransition
- && mPowerState.prepareColorFade(mContext,
- mColorFadeFadesConfig
- ? ColorFade.MODE_FADE : ColorFade.MODE_COOL_DOWN)
- && mPowerState.getScreenState() != Display.STATE_OFF) {
- // Perform the screen off animation.
- mColorFadeOffAnimator.start();
- } else {
- // Skip the screen off animation and add a black surface to hide the
- // contents of the screen.
- mColorFadeOffAnimator.end();
- }
- }
- }
-
- private final Runnable mCleanListener = this::sendUpdatePowerState;
-
- private void setProximitySensorEnabled(boolean enable) {
- if (enable) {
- if (!mProximitySensorEnabled) {
- // Register the listener.
- // Proximity sensor state already cleared initially.
- mProximitySensorEnabled = true;
- mIgnoreProximityUntilChanged = false;
- mSensorManager.registerListener(mProximitySensorListener, mProximitySensor,
- SensorManager.SENSOR_DELAY_NORMAL, mHandler);
- }
- } else {
- if (mProximitySensorEnabled) {
- // Unregister the listener.
- // Clear the proximity sensor state for next time.
- mProximitySensorEnabled = false;
- mProximity = PROXIMITY_UNKNOWN;
- mIgnoreProximityUntilChanged = false;
- mPendingProximity = PROXIMITY_UNKNOWN;
- mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
- mSensorManager.unregisterListener(mProximitySensorListener);
- clearPendingProximityDebounceTime(); // release wake lock (must be last)
- }
- }
- }
-
- private void handleProximitySensorEvent(long time, boolean positive) {
- if (mProximitySensorEnabled) {
- if (mPendingProximity == PROXIMITY_NEGATIVE && !positive) {
- return; // no change
- }
- if (mPendingProximity == PROXIMITY_POSITIVE && positive) {
- return; // no change
- }
-
- // Only accept a proximity sensor reading if it remains
- // stable for the entire debounce delay. We hold a wake lock while
- // debouncing the sensor.
- mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
- if (positive) {
- mPendingProximity = PROXIMITY_POSITIVE;
- setPendingProximityDebounceTime(
- time + PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY); // acquire wake lock
- } else {
- mPendingProximity = PROXIMITY_NEGATIVE;
- setPendingProximityDebounceTime(
- time + PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY); // acquire wake lock
- }
-
- // Debounce the new sensor reading.
- debounceProximitySensor();
- }
- }
-
- private void debounceProximitySensor() {
- if (mProximitySensorEnabled
- && mPendingProximity != PROXIMITY_UNKNOWN
- && mPendingProximityDebounceTime >= 0) {
- final long now = mClock.uptimeMillis();
- if (mPendingProximityDebounceTime <= now) {
- if (mProximity != mPendingProximity) {
- // if the status of the sensor changed, stop ignoring.
- mIgnoreProximityUntilChanged = false;
- Slog.i(mTag, "No longer ignoring proximity [" + mPendingProximity + "]");
- }
- // Sensor reading accepted. Apply the change then release the wake lock.
- mProximity = mPendingProximity;
- updatePowerState();
- clearPendingProximityDebounceTime(); // release wake lock (must be last)
- } else {
- // Need to wait a little longer.
- // Debounce again later. We continue holding a wake lock while waiting.
- Message msg = mHandler.obtainMessage(MSG_PROXIMITY_SENSOR_DEBOUNCED);
- mHandler.sendMessageAtTime(msg, mPendingProximityDebounceTime);
- }
- }
- }
-
- private void clearPendingProximityDebounceTime() {
- if (mPendingProximityDebounceTime >= 0) {
- mPendingProximityDebounceTime = -1;
- mCallbacks.releaseSuspendBlocker(mSuspendBlockerIdProxDebounce);
- }
- }
-
- private void setPendingProximityDebounceTime(long debounceTime) {
- if (mPendingProximityDebounceTime < 0) {
- mCallbacks.acquireSuspendBlocker(mSuspendBlockerIdProxDebounce);
- }
- mPendingProximityDebounceTime = debounceTime;
- }
-
- private void sendOnStateChangedWithWakelock() {
- if (!mOnStateChangedPending) {
- mOnStateChangedPending = true;
- mCallbacks.acquireSuspendBlocker(mSuspendBlockerIdOnStateChanged);
- mHandler.post(mOnStateChangedRunnable);
- }
- }
-
- private void logDisplayPolicyChanged(int newPolicy) {
- LogMaker log = new LogMaker(MetricsEvent.DISPLAY_POLICY);
- log.setType(MetricsEvent.TYPE_UPDATE);
- log.setSubtype(newPolicy);
- MetricsLogger.action(log);
- }
-
- private void handleSettingsChange(boolean userSwitch) {
- mPendingScreenBrightnessSetting = getScreenBrightnessSetting();
- mPendingAutoBrightnessAdjustment = getAutoBrightnessAdjustmentSetting();
- if (userSwitch) {
- // Don't treat user switches as user initiated change.
- setCurrentScreenBrightness(mPendingScreenBrightnessSetting);
- updateAutoBrightnessAdjustment();
- if (mAutomaticBrightnessController != null) {
- mAutomaticBrightnessController.resetShortTermModel();
- }
- }
- sendUpdatePowerState();
- }
-
- private void handleBrightnessModeChange() {
- final int screenBrightnessModeSetting = Settings.System.getIntForUser(
- mContext.getContentResolver(),
- Settings.System.SCREEN_BRIGHTNESS_MODE,
- Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL, UserHandle.USER_CURRENT);
- mHandler.postAtTime(() -> {
- mUseAutoBrightness = screenBrightnessModeSetting
- == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;
- updatePowerState();
- }, mClock.uptimeMillis());
- }
-
- private float getAutoBrightnessAdjustmentSetting() {
- final float adj = Settings.System.getFloatForUser(mContext.getContentResolver(),
- Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0.0f, UserHandle.USER_CURRENT);
- return Float.isNaN(adj) ? 0.0f : clampAutoBrightnessAdjustment(adj);
- }
-
- @Override
- public float getScreenBrightnessSetting() {
- float brightness = mBrightnessSetting.getBrightness();
- if (Float.isNaN(brightness)) {
- brightness = mScreenBrightnessDefault;
- }
- return clampAbsoluteBrightness(brightness);
- }
-
- private void loadNitBasedBrightnessSetting() {
- if (mDisplayId == Display.DEFAULT_DISPLAY && mPersistBrightnessNitsForDefaultDisplay) {
- float brightnessNitsForDefaultDisplay =
- mBrightnessSetting.getBrightnessNitsForDefaultDisplay();
- if (brightnessNitsForDefaultDisplay >= 0) {
- float brightnessForDefaultDisplay = getBrightnessFromNits(
- brightnessNitsForDefaultDisplay);
- if (isValidBrightnessValue(brightnessForDefaultDisplay)) {
- mBrightnessSetting.setBrightness(brightnessForDefaultDisplay);
- mCurrentScreenBrightnessSetting = brightnessForDefaultDisplay;
- return;
- }
- }
- }
- mCurrentScreenBrightnessSetting = getScreenBrightnessSetting();
- }
-
- @Override
- public void setBrightness(float brightnessValue, int userSerial) {
- // Update the setting, which will eventually call back into DPC to have us actually update
- // the display with the new value.
- float clampedBrightnessValue = clampScreenBrightness(brightnessValue);
- mBrightnessSetting.setUserSerial(userSerial);
- mBrightnessSetting.setBrightness(clampedBrightnessValue);
- if (mDisplayId == Display.DEFAULT_DISPLAY && mPersistBrightnessNitsForDefaultDisplay) {
- float nits = convertToNits(clampedBrightnessValue);
- if (nits >= 0) {
- mBrightnessSetting.setBrightnessNitsForDefaultDisplay(nits);
- }
- }
- }
-
- @Override
- public void onBootCompleted() {
- Message msg = mHandler.obtainMessage(MSG_BOOT_COMPLETED);
- mHandler.sendMessageAtTime(msg, mClock.uptimeMillis());
- }
-
- private void updateScreenBrightnessSetting(float brightnessValue) {
- if (!isValidBrightnessValue(brightnessValue)
- || brightnessValue == mCurrentScreenBrightnessSetting) {
- return;
- }
- setCurrentScreenBrightness(brightnessValue);
- setBrightness(brightnessValue);
- }
-
- private void setCurrentScreenBrightness(float brightnessValue) {
- if (brightnessValue != mCurrentScreenBrightnessSetting) {
- mCurrentScreenBrightnessSetting = brightnessValue;
- postBrightnessChangeRunnable();
- }
- }
-
- private void putAutoBrightnessAdjustmentSetting(float adjustment) {
- if (mDisplayId == Display.DEFAULT_DISPLAY) {
- mAutoBrightnessAdjustment = adjustment;
- Settings.System.putFloatForUser(mContext.getContentResolver(),
- Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, adjustment,
- UserHandle.USER_CURRENT);
- }
- }
-
- private boolean updateAutoBrightnessAdjustment() {
- if (Float.isNaN(mPendingAutoBrightnessAdjustment)) {
- return false;
- }
- if (mAutoBrightnessAdjustment == mPendingAutoBrightnessAdjustment) {
- mPendingAutoBrightnessAdjustment = Float.NaN;
- return false;
- }
- mAutoBrightnessAdjustment = mPendingAutoBrightnessAdjustment;
- mPendingAutoBrightnessAdjustment = Float.NaN;
- mTemporaryAutoBrightnessAdjustment = Float.NaN;
- return true;
- }
-
- // We want to return true if the user has set the screen brightness.
- // RBC on, off, and intensity changes will return false.
- // Slider interactions whilst in RBC will return true, just as when in non-rbc.
- private boolean updateUserSetScreenBrightness() {
- if ((Float.isNaN(mPendingScreenBrightnessSetting)
- || mPendingScreenBrightnessSetting < 0.0f)) {
- return false;
- }
- if (mCurrentScreenBrightnessSetting == mPendingScreenBrightnessSetting) {
- mPendingScreenBrightnessSetting = PowerManager.BRIGHTNESS_INVALID_FLOAT;
- mTemporaryScreenBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
- return false;
- }
- setCurrentScreenBrightness(mPendingScreenBrightnessSetting);
- mLastUserSetScreenBrightness = mPendingScreenBrightnessSetting;
- mPendingScreenBrightnessSetting = PowerManager.BRIGHTNESS_INVALID_FLOAT;
- mTemporaryScreenBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
- return true;
- }
-
- private void notifyBrightnessTrackerChanged(float brightness, boolean userInitiated,
- boolean wasShortTermModelActive, boolean autobrightnessEnabled,
- boolean brightnessIsTemporary) {
- final float brightnessInNits = convertToAdjustedNits(brightness);
-
- // Don't report brightness to brightnessTracker:
- // If brightness is temporary (ie the slider has not been released)
- // or if we are in idle screen brightness mode.
- // or display is not on
- // or we shouldn't be using autobrightness
- // or the nits is invalid.
- if (brightnessIsTemporary
- || mAutomaticBrightnessController == null
- || mAutomaticBrightnessController.isInIdleMode()
- || !autobrightnessEnabled
- || mBrightnessTracker == null
- || !mUseAutoBrightness
- || brightnessInNits < 0.0f) {
- return;
- }
-
- if (userInitiated && !mAutomaticBrightnessController.hasValidAmbientLux()) {
- // If we don't have a valid lux reading we can't report a valid
- // slider event so notify as if the system changed the brightness.
- userInitiated = false;
- }
-
- // We only want to track changes on devices that can actually map the display backlight
- // values into a physical brightness unit since the value provided by the API is in
- // nits and not using the arbitrary backlight units.
- final float powerFactor = mPowerRequest.lowPowerMode
- ? mPowerRequest.screenLowPowerBrightnessFactor
- : 1.0f;
- mBrightnessTracker.notifyBrightnessChanged(brightnessInNits, userInitiated,
- powerFactor, wasShortTermModelActive,
- mAutomaticBrightnessController.isDefaultConfig(), mUniqueDisplayId,
- mAutomaticBrightnessController.getLastSensorValues(),
- mAutomaticBrightnessController.getLastSensorTimestamps());
- }
-
- private float convertToNits(float brightness) {
- if (mAutomaticBrightnessController == null) {
- return BrightnessMappingStrategy.INVALID_NITS;
- }
- return mAutomaticBrightnessController.convertToNits(brightness);
- }
-
- private float convertToAdjustedNits(float brightness) {
- if (mAutomaticBrightnessController == null) {
- return BrightnessMappingStrategy.INVALID_NITS;
- }
- return mAutomaticBrightnessController.convertToAdjustedNits(brightness);
- }
-
- private float getBrightnessFromNits(float nits) {
- if (mAutomaticBrightnessController == null) {
- return PowerManager.BRIGHTNESS_INVALID_FLOAT;
- }
- return mAutomaticBrightnessController.getBrightnessFromNits(nits);
- }
-
- @GuardedBy("mLock")
- private void updatePendingProximityRequestsLocked() {
- mWaitingForNegativeProximity |= mPendingWaitForNegativeProximityLocked;
- mPendingWaitForNegativeProximityLocked = false;
-
- if (mIgnoreProximityUntilChanged) {
- // Also, lets stop waiting for negative proximity if we're ignoring it.
- mWaitingForNegativeProximity = false;
- }
- }
-
- private void ignoreProximitySensorUntilChangedInternal() {
- if (!mIgnoreProximityUntilChanged
- && mProximity == PROXIMITY_POSITIVE) {
- // Only ignore if it is still reporting positive (near)
- mIgnoreProximityUntilChanged = true;
- Slog.i(mTag, "Ignoring proximity");
- updatePowerState();
- }
- }
-
- private final Runnable mOnStateChangedRunnable = new Runnable() {
- @Override
- public void run() {
- mOnStateChangedPending = false;
- mCallbacks.onStateChanged();
- mCallbacks.releaseSuspendBlocker(mSuspendBlockerIdOnStateChanged);
- }
- };
-
- private void sendOnProximityPositiveWithWakelock() {
- mCallbacks.acquireSuspendBlocker(mSuspendBlockerIdProxPositive);
- mHandler.post(mOnProximityPositiveRunnable);
- mOnProximityPositiveMessages++;
- }
-
- private final Runnable mOnProximityPositiveRunnable = new Runnable() {
- @Override
- public void run() {
- mOnProximityPositiveMessages--;
- mCallbacks.onProximityPositive();
- mCallbacks.releaseSuspendBlocker(mSuspendBlockerIdProxPositive);
- }
- };
-
- private void sendOnProximityNegativeWithWakelock() {
- mOnProximityNegativeMessages++;
- mCallbacks.acquireSuspendBlocker(mSuspendBlockerIdProxNegative);
- mHandler.post(mOnProximityNegativeRunnable);
- }
-
- private final Runnable mOnProximityNegativeRunnable = new Runnable() {
- @Override
- public void run() {
- mOnProximityNegativeMessages--;
- mCallbacks.onProximityNegative();
- mCallbacks.releaseSuspendBlocker(mSuspendBlockerIdProxNegative);
- }
- };
-
- /**
- * Indicates whether the display state is ready to update. If this is the default display, we
- * want to update it right away so that we can draw the boot animation on it. If it is not
- * the default display, drawing the boot animation on it would look incorrect, so we need
- * to wait until boot is completed.
- * @return True if the display state is ready to update
- */
- private boolean readyToUpdateDisplayState() {
- return mDisplayId == Display.DEFAULT_DISPLAY || mBootCompleted;
- }
-
- @Override
- public void dump(final PrintWriter pw) {
- synchronized (mLock) {
- pw.println();
- pw.println("Display Power Controller:");
- pw.println(" mDisplayId=" + mDisplayId);
- pw.println(" mLeadDisplayId=" + mLeadDisplayId);
- pw.println(" mLightSensor=" + mLightSensor);
- pw.println(" mDisplayBrightnessFollowers=" + mDisplayBrightnessFollowers);
- pw.println(" mDozeStateOverride=" + mDozeStateOverride);
-
- pw.println();
- pw.println("Display Power Controller Locked State:");
- pw.println(" mDisplayReadyLocked=" + mDisplayReadyLocked);
- pw.println(" mPendingRequestLocked=" + mPendingRequestLocked);
- pw.println(" mPendingRequestChangedLocked=" + mPendingRequestChangedLocked);
- pw.println(" mPendingWaitForNegativeProximityLocked="
- + mPendingWaitForNegativeProximityLocked);
- pw.println(" mPendingUpdatePowerStateLocked=" + mPendingUpdatePowerStateLocked);
- }
-
- pw.println();
- pw.println("Display Power Controller Configuration:");
- pw.println(" mScreenBrightnessRangeDefault=" + mScreenBrightnessDefault);
- pw.println(" mScreenBrightnessDozeConfig=" + mScreenBrightnessDozeConfig);
- pw.println(" mScreenBrightnessDimConfig=" + mScreenBrightnessDimConfig);
- pw.println(" mUseSoftwareAutoBrightnessConfig=" + mUseSoftwareAutoBrightnessConfig);
- pw.println(" mAllowAutoBrightnessWhileDozingConfig="
- + mAllowAutoBrightnessWhileDozingConfig);
- pw.println(" mPersistBrightnessNitsForDefaultDisplay="
- + mPersistBrightnessNitsForDefaultDisplay);
- pw.println(" mSkipScreenOnBrightnessRamp=" + mSkipScreenOnBrightnessRamp);
- pw.println(" mColorFadeFadesConfig=" + mColorFadeFadesConfig);
- pw.println(" mColorFadeEnabled=" + mColorFadeEnabled);
- synchronized (mCachedBrightnessInfo) {
- pw.println(" mCachedBrightnessInfo.brightness="
- + mCachedBrightnessInfo.brightness.value);
- pw.println(" mCachedBrightnessInfo.adjustedBrightness="
- + mCachedBrightnessInfo.adjustedBrightness.value);
- pw.println(" mCachedBrightnessInfo.brightnessMin="
- + mCachedBrightnessInfo.brightnessMin.value);
- pw.println(" mCachedBrightnessInfo.brightnessMax="
- + mCachedBrightnessInfo.brightnessMax.value);
- pw.println(" mCachedBrightnessInfo.hbmMode=" + mCachedBrightnessInfo.hbmMode.value);
- pw.println(" mCachedBrightnessInfo.hbmTransitionPoint="
- + mCachedBrightnessInfo.hbmTransitionPoint.value);
- pw.println(" mCachedBrightnessInfo.brightnessMaxReason ="
- + mCachedBrightnessInfo.brightnessMaxReason.value);
- }
- pw.println(" mDisplayBlanksAfterDozeConfig=" + mDisplayBlanksAfterDozeConfig);
- pw.println(" mBrightnessBucketsInDozeConfig=" + mBrightnessBucketsInDozeConfig);
-
- mHandler.runWithScissors(() -> dumpLocal(pw), 1000);
- }
-
- private void dumpLocal(PrintWriter pw) {
- pw.println();
- pw.println("Display Power Controller Thread State:");
- pw.println(" mPowerRequest=" + mPowerRequest);
- pw.println(" mUnfinishedBusiness=" + mUnfinishedBusiness);
- pw.println(" mWaitingForNegativeProximity=" + mWaitingForNegativeProximity);
- pw.println(" mProximitySensor=" + mProximitySensor);
- pw.println(" mProximitySensorEnabled=" + mProximitySensorEnabled);
- pw.println(" mProximityThreshold=" + mProximityThreshold);
- pw.println(" mProximity=" + proximityToString(mProximity));
- pw.println(" mPendingProximity=" + proximityToString(mPendingProximity));
- pw.println(" mPendingProximityDebounceTime="
- + TimeUtils.formatUptime(mPendingProximityDebounceTime));
- pw.println(" mScreenOffBecauseOfProximity=" + mScreenOffBecauseOfProximity);
- pw.println(" mLastUserSetScreenBrightness=" + mLastUserSetScreenBrightness);
- pw.println(" mPendingScreenBrightnessSetting="
- + mPendingScreenBrightnessSetting);
- pw.println(" mTemporaryScreenBrightness=" + mTemporaryScreenBrightness);
- pw.println(" mBrightnessToFollow=" + mBrightnessToFollow);
- pw.println(" mBrightnessToFollowSlowChange=" + mBrightnessToFollowSlowChange);
- pw.println(" mAutoBrightnessAdjustment=" + mAutoBrightnessAdjustment);
- pw.println(" mBrightnessReason=" + mBrightnessReason);
- pw.println(" mTemporaryAutoBrightnessAdjustment=" + mTemporaryAutoBrightnessAdjustment);
- pw.println(" mPendingAutoBrightnessAdjustment=" + mPendingAutoBrightnessAdjustment);
- pw.println(" mAppliedAutoBrightness=" + mAppliedAutoBrightness);
- pw.println(" mAppliedDimming=" + mAppliedDimming);
- pw.println(" mAppliedLowPower=" + mAppliedLowPower);
- pw.println(" mAppliedThrottling=" + mAppliedThrottling);
- pw.println(" mAppliedScreenBrightnessOverride=" + mAppliedScreenBrightnessOverride);
- pw.println(" mAppliedTemporaryBrightness=" + mAppliedTemporaryBrightness);
- pw.println(" mAppliedTemporaryAutoBrightnessAdjustment="
- + mAppliedTemporaryAutoBrightnessAdjustment);
- pw.println(" mAppliedBrightnessBoost=" + mAppliedBrightnessBoost);
- pw.println(" mDozing=" + mDozing);
- pw.println(" mSkipRampState=" + skipRampStateToString(mSkipRampState));
- pw.println(" mScreenOnBlockStartRealTime=" + mScreenOnBlockStartRealTime);
- pw.println(" mScreenOffBlockStartRealTime=" + mScreenOffBlockStartRealTime);
- pw.println(" mPendingScreenOnUnblocker=" + mPendingScreenOnUnblocker);
- pw.println(" mPendingScreenOffUnblocker=" + mPendingScreenOffUnblocker);
- pw.println(" mPendingScreenOff=" + mPendingScreenOff);
- pw.println(" mReportedToPolicy="
- + reportedToPolicyToString(mReportedScreenStateToPolicy));
- pw.println(" mIsRbcActive=" + mIsRbcActive);
- pw.println(" mOnStateChangePending=" + mOnStateChangedPending);
- pw.println(" mOnProximityPositiveMessages=" + mOnProximityPositiveMessages);
- pw.println(" mOnProximityNegativeMessages=" + mOnProximityNegativeMessages);
-
- if (mScreenBrightnessRampAnimator != null) {
- pw.println(" mScreenBrightnessRampAnimator.isAnimating()="
- + mScreenBrightnessRampAnimator.isAnimating());
- }
-
- if (mColorFadeOnAnimator != null) {
- pw.println(" mColorFadeOnAnimator.isStarted()="
- + mColorFadeOnAnimator.isStarted());
- }
- if (mColorFadeOffAnimator != null) {
- pw.println(" mColorFadeOffAnimator.isStarted()="
- + mColorFadeOffAnimator.isStarted());
- }
-
- if (mPowerState != null) {
- mPowerState.dump(pw);
- }
-
- if (mAutomaticBrightnessController != null) {
- mAutomaticBrightnessController.dump(pw);
- dumpBrightnessEvents(pw);
- }
-
- if (mScreenOffBrightnessSensorController != null) {
- mScreenOffBrightnessSensorController.dump(pw);
- }
-
- if (mBrightnessRangeController != null) {
- mBrightnessRangeController.dump(pw);
- }
-
- if (mBrightnessThrottler != null) {
- mBrightnessThrottler.dump(pw);
- }
-
- pw.println();
- if (mDisplayWhiteBalanceController != null) {
- mDisplayWhiteBalanceController.dump(pw);
- mDisplayWhiteBalanceSettings.dump(pw);
- }
- }
-
- private static String proximityToString(int state) {
- switch (state) {
- case PROXIMITY_UNKNOWN:
- return "Unknown";
- case PROXIMITY_NEGATIVE:
- return "Negative";
- case PROXIMITY_POSITIVE:
- return "Positive";
- default:
- return Integer.toString(state);
- }
- }
-
- private static String reportedToPolicyToString(int state) {
- switch (state) {
- case REPORTED_TO_POLICY_SCREEN_OFF:
- return "REPORTED_TO_POLICY_SCREEN_OFF";
- case REPORTED_TO_POLICY_SCREEN_TURNING_ON:
- return "REPORTED_TO_POLICY_SCREEN_TURNING_ON";
- case REPORTED_TO_POLICY_SCREEN_ON:
- return "REPORTED_TO_POLICY_SCREEN_ON";
- default:
- return Integer.toString(state);
- }
- }
-
- private static String skipRampStateToString(int state) {
- switch (state) {
- case RAMP_STATE_SKIP_NONE:
- return "RAMP_STATE_SKIP_NONE";
- case RAMP_STATE_SKIP_INITIAL:
- return "RAMP_STATE_SKIP_INITIAL";
- case RAMP_STATE_SKIP_AUTOBRIGHT:
- return "RAMP_STATE_SKIP_AUTOBRIGHT";
- default:
- return Integer.toString(state);
- }
- }
-
- private void dumpBrightnessEvents(PrintWriter pw) {
- int size = mBrightnessEventRingBuffer.size();
- if (size < 1) {
- pw.println("No Automatic Brightness Adjustments");
- return;
- }
-
- pw.println("Automatic Brightness Adjustments Last " + size + " Events: ");
- BrightnessEvent[] eventArray = mBrightnessEventRingBuffer.toArray();
- for (int i = 0; i < mBrightnessEventRingBuffer.size(); i++) {
- pw.println(" " + eventArray[i].toString());
- }
- }
-
- private static float clampAbsoluteBrightness(float value) {
- return MathUtils.constrain(value, PowerManager.BRIGHTNESS_MIN,
- PowerManager.BRIGHTNESS_MAX);
- }
-
- private static float clampAutoBrightnessAdjustment(float value) {
- return MathUtils.constrain(value, -1.0f, 1.0f);
- }
-
- private void noteScreenState(int screenState) {
- // Log screen state change with display id
- FrameworkStatsLog.write(FrameworkStatsLog.SCREEN_STATE_CHANGED_V2,
- screenState, mDisplayStatsId);
- if (mBatteryStats != null) {
- try {
- // TODO(multi-display): make this multi-display
- mBatteryStats.noteScreenState(screenState);
- } catch (RemoteException e) {
- // same process
- }
- }
- }
-
- @SuppressLint("AndroidFrameworkRequiresPermission")
- private void noteScreenBrightness(float brightness) {
- if (mBatteryStats != null) {
- try {
- // TODO(brightnessfloat): change BatteryStats to use float
- int brightnessInt = mFlags.isBrightnessIntRangeUserPerceptionEnabled()
- ? BrightnessSynchronizer.brightnessFloatToIntSetting(mContext, brightness)
- : BrightnessSynchronizer.brightnessFloatToInt(brightness);
- mBatteryStats.noteScreenBrightness(brightnessInt);
- } catch (RemoteException e) {
- // same process
- }
- }
- }
-
- private void reportStats(float brightness) {
- if (mLastStatsBrightness == brightness) {
- return;
- }
-
- float hbmTransitionPoint = PowerManager.BRIGHTNESS_MAX;
- synchronized (mCachedBrightnessInfo) {
- if (mCachedBrightnessInfo.hbmTransitionPoint == null) {
- return;
- }
- hbmTransitionPoint = mCachedBrightnessInfo.hbmTransitionPoint.value;
- }
-
- final boolean aboveTransition = brightness > hbmTransitionPoint;
- final boolean oldAboveTransition = mLastStatsBrightness > hbmTransitionPoint;
-
- if (aboveTransition || oldAboveTransition) {
- mLastStatsBrightness = brightness;
- mHandler.removeMessages(MSG_STATSD_HBM_BRIGHTNESS);
- if (aboveTransition != oldAboveTransition) {
- // report immediately
- logHbmBrightnessStats(brightness, mDisplayStatsId);
- } else {
- // delay for rate limiting
- Message msg = mHandler.obtainMessage();
- msg.what = MSG_STATSD_HBM_BRIGHTNESS;
- msg.arg1 = Float.floatToIntBits(brightness);
- msg.arg2 = mDisplayStatsId;
- mHandler.sendMessageAtTime(msg, mClock.uptimeMillis()
- + BRIGHTNESS_CHANGE_STATSD_REPORT_INTERVAL_MS);
- }
- }
- }
-
- private void logHbmBrightnessStats(float brightness, int displayStatsId) {
- synchronized (mHandler) {
- FrameworkStatsLog.write(
- FrameworkStatsLog.DISPLAY_HBM_BRIGHTNESS_CHANGED, displayStatsId, brightness);
- }
- }
-
- // Return bucket index of range_[left]_[right] where
- // left <= nits < right
- private int nitsToRangeIndex(float nits) {
- for (int i = 0; i < BRIGHTNESS_RANGE_BOUNDARIES.length; i++) {
- if (nits < BRIGHTNESS_RANGE_BOUNDARIES[i]) {
- return BRIGHTNESS_RANGE_INDEX[i];
- }
- }
- return FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_3000_INF;
- }
-
- private int convertBrightnessReasonToStatsEnum(int brightnessReason) {
- switch(brightnessReason) {
- case BrightnessReason.REASON_UNKNOWN:
- return FrameworkStatsLog
- .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_UNKNOWN;
- case BrightnessReason.REASON_MANUAL:
- return FrameworkStatsLog
- .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_MANUAL;
- case BrightnessReason.REASON_DOZE:
- return FrameworkStatsLog
- .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_DOZE;
- case BrightnessReason.REASON_DOZE_DEFAULT:
- return FrameworkStatsLog
- .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_DOZE_DEFAULT;
- case BrightnessReason.REASON_AUTOMATIC:
- return FrameworkStatsLog
- .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_AUTOMATIC;
- case BrightnessReason.REASON_SCREEN_OFF:
- return FrameworkStatsLog
- .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_SCREEN_OFF;
- case BrightnessReason.REASON_OVERRIDE:
- return FrameworkStatsLog
- .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_OVERRIDE;
- case BrightnessReason.REASON_TEMPORARY:
- return FrameworkStatsLog
- .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_TEMPORARY;
- case BrightnessReason.REASON_BOOST:
- return FrameworkStatsLog
- .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_BOOST;
- case BrightnessReason.REASON_SCREEN_OFF_BRIGHTNESS_SENSOR:
- return FrameworkStatsLog
- .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_SCREEN_OFF_BRIGHTNESS_SENSOR;
- case BrightnessReason.REASON_FOLLOWER:
- return FrameworkStatsLog
- .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_FOLLOWER;
- }
- return FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_UNKNOWN;
- }
-
- private void logBrightnessEvent(BrightnessEvent event, float unmodifiedBrightness) {
- int modifier = event.getReason().getModifier();
- int flags = event.getFlags();
- // It's easier to check if the brightness is at maximum level using the brightness
- // value untouched by any modifiers
- boolean brightnessIsMax = unmodifiedBrightness == event.getHbmMax();
- float brightnessInNits = convertToAdjustedNits(event.getBrightness());
- float appliedLowPowerMode = event.isLowPowerModeSet() ? event.getPowerFactor() : -1f;
- int appliedRbcStrength = event.isRbcEnabled() ? event.getRbcStrength() : -1;
- float appliedHbmMaxNits =
- event.getHbmMode() == BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF
- ? -1f : convertToAdjustedNits(event.getHbmMax());
- // thermalCapNits set to -1 if not currently capping max brightness
- float appliedThermalCapNits =
- event.getThermalMax() == PowerManager.BRIGHTNESS_MAX
- ? -1f : convertToAdjustedNits(event.getThermalMax());
-
- if (mIsDisplayInternal) {
- FrameworkStatsLog.write(FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED,
- convertToAdjustedNits(event.getInitialBrightness()),
- brightnessInNits,
- event.getLux(),
- event.getPhysicalDisplayId(),
- event.wasShortTermModelActive(),
- appliedLowPowerMode,
- appliedRbcStrength,
- appliedHbmMaxNits,
- appliedThermalCapNits,
- event.isAutomaticBrightnessEnabled(),
- FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__REASON__REASON_MANUAL,
- convertBrightnessReasonToStatsEnum(event.getReason().getReason()),
- nitsToRangeIndex(brightnessInNits),
- brightnessIsMax,
- event.getHbmMode() == BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLIGHT,
- event.getHbmMode() == BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR,
- (modifier & BrightnessReason.MODIFIER_LOW_POWER) > 0,
- mBrightnessThrottler.getBrightnessMaxReason(),
- (modifier & BrightnessReason.MODIFIER_DIMMED) > 0,
- event.isRbcEnabled(),
- (flags & BrightnessEvent.FLAG_INVALID_LUX) > 0,
- (flags & BrightnessEvent.FLAG_DOZE_SCALE) > 0,
- (flags & BrightnessEvent.FLAG_USER_SET) > 0,
- (flags & BrightnessEvent.FLAG_IDLE_CURVE) > 0,
- (flags & BrightnessEvent.FLAG_LOW_POWER_MODE) > 0);
- }
- }
-
- private final class DisplayControllerHandler extends Handler {
- DisplayControllerHandler(Looper looper) {
- super(looper, null, true /*async*/);
- }
-
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_UPDATE_POWER_STATE:
- updatePowerState();
- break;
-
- case MSG_PROXIMITY_SENSOR_DEBOUNCED:
- debounceProximitySensor();
- break;
-
- case MSG_SCREEN_ON_UNBLOCKED:
- if (mPendingScreenOnUnblocker == msg.obj) {
- unblockScreenOn();
- updatePowerState();
- }
- break;
- case MSG_SCREEN_OFF_UNBLOCKED:
- if (mPendingScreenOffUnblocker == msg.obj) {
- unblockScreenOff();
- updatePowerState();
- }
- break;
- case MSG_CONFIGURE_BRIGHTNESS:
- mBrightnessConfiguration = (BrightnessConfiguration) msg.obj;
- mShouldResetShortTermModel = msg.arg1 == 1;
- updatePowerState();
- break;
-
- case MSG_SET_TEMPORARY_BRIGHTNESS:
- // TODO: Should we have a a timeout for the temporary brightness?
- mTemporaryScreenBrightness = Float.intBitsToFloat(msg.arg1);
- updatePowerState();
- break;
-
- case MSG_SET_TEMPORARY_AUTO_BRIGHTNESS_ADJUSTMENT:
- mTemporaryAutoBrightnessAdjustment = Float.intBitsToFloat(msg.arg1);
- updatePowerState();
- break;
-
- case MSG_IGNORE_PROXIMITY:
- ignoreProximitySensorUntilChangedInternal();
- break;
-
- case MSG_STOP:
- cleanupHandlerThreadAfterStop();
- break;
-
- case MSG_UPDATE_BRIGHTNESS:
- if (mStopped) {
- return;
- }
- handleSettingsChange(false /*userSwitch*/);
- break;
-
- case MSG_UPDATE_RBC:
- handleRbcChanged();
- break;
-
- case MSG_BRIGHTNESS_RAMP_DONE:
- if (mPowerState != null) {
- final float brightness = mPowerState.getScreenBrightness();
- reportStats(brightness);
- }
- break;
-
- case MSG_STATSD_HBM_BRIGHTNESS:
- logHbmBrightnessStats(Float.intBitsToFloat(msg.arg1), msg.arg2);
- break;
-
- case MSG_SWITCH_USER:
- handleOnSwitchUser(msg.arg1);
- break;
-
- case MSG_BOOT_COMPLETED:
- mBootCompleted = true;
- updatePowerState();
- break;
-
- case MSG_SET_DWBC_STRONG_MODE:
- setDwbcStrongMode(msg.arg1);
- break;
-
- case MSG_SET_DWBC_COLOR_OVERRIDE:
- final float cct = Float.intBitsToFloat(msg.arg1);
- setDwbcOverride(cct);
- break;
-
- case MSG_SET_DWBC_LOGGING_ENABLED:
- setDwbcLoggingEnabled(msg.arg1);
- break;
- }
- }
- }
-
- private final SensorEventListener mProximitySensorListener = new SensorEventListener() {
- @Override
- public void onSensorChanged(SensorEvent event) {
- if (mProximitySensorEnabled) {
- final long time = mClock.uptimeMillis();
- final float distance = event.values[0];
- boolean positive = distance >= 0.0f && distance < mProximityThreshold;
- handleProximitySensorEvent(time, positive);
- }
- }
-
- @Override
- public void onAccuracyChanged(Sensor sensor, int accuracy) {
- // Not used.
- }
- };
-
-
- private final class SettingsObserver extends ContentObserver {
- SettingsObserver(Handler handler) {
- super(handler);
- }
-
- @Override
- public void onChange(boolean selfChange, Uri uri) {
- if (uri.equals(Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_MODE))) {
- handleBrightnessModeChange();
- } else {
- handleSettingsChange(false /* userSwitch */);
- }
- }
- }
-
- private final class ScreenOnUnblocker implements WindowManagerPolicy.ScreenOnListener {
- @Override
- public void onScreenOn() {
- Message msg = mHandler.obtainMessage(MSG_SCREEN_ON_UNBLOCKED, this);
- mHandler.sendMessageAtTime(msg, mClock.uptimeMillis());
- }
- }
-
- private final class ScreenOffUnblocker implements WindowManagerPolicy.ScreenOffListener {
- @Override
- public void onScreenOff() {
- Message msg = mHandler.obtainMessage(MSG_SCREEN_OFF_UNBLOCKED, this);
- mHandler.sendMessageAtTime(msg, mClock.uptimeMillis());
- }
- }
-
- @Override
- public void setAutoBrightnessLoggingEnabled(boolean enabled) {
- if (mAutomaticBrightnessController != null) {
- mAutomaticBrightnessController.setLoggingEnabled(enabled);
- }
- }
-
- @Override // DisplayWhiteBalanceController.Callbacks
- public void updateWhiteBalance() {
- sendUpdatePowerState();
- }
-
- @Override
- public void setDisplayWhiteBalanceLoggingEnabled(boolean enabled) {
- Message msg = mHandler.obtainMessage();
- msg.what = MSG_SET_DWBC_LOGGING_ENABLED;
- msg.arg1 = enabled ? 1 : 0;
- msg.sendToTarget();
- }
-
- @Override
- public void setAmbientColorTemperatureOverride(float cct) {
- Message msg = mHandler.obtainMessage();
- msg.what = MSG_SET_DWBC_COLOR_OVERRIDE;
- msg.arg1 = Float.floatToIntBits(cct);
- msg.sendToTarget();
- }
-
- @VisibleForTesting
- String getSuspendBlockerUnfinishedBusinessId(int displayId) {
- return "[" + displayId + "]unfinished business";
- }
-
- String getSuspendBlockerOnStateChangedId(int displayId) {
- return "[" + displayId + "]on state changed";
- }
-
- String getSuspendBlockerProxPositiveId(int displayId) {
- return "[" + displayId + "]prox positive";
- }
-
- String getSuspendBlockerProxNegativeId(int displayId) {
- return "[" + displayId + "]prox negative";
- }
-
- @VisibleForTesting
- String getSuspendBlockerProxDebounceId(int displayId) {
- return "[" + displayId + "]prox debounce";
- }
-
- /** Functional interface for providing time. */
- @VisibleForTesting
- interface Clock {
- /**
- * Returns current time in milliseconds since boot, not counting time spent in deep sleep.
- */
- long uptimeMillis();
- }
-
- @VisibleForTesting
- static class Injector {
- Clock getClock() {
- return SystemClock::uptimeMillis;
- }
-
- DisplayPowerState getDisplayPowerState(DisplayBlanker blanker, ColorFade colorFade,
- int displayId, int displayState) {
- return new DisplayPowerState(blanker, colorFade, displayId, displayState);
- }
-
- DualRampAnimator<DisplayPowerState> getDualRampAnimator(DisplayPowerState dps,
- FloatProperty<DisplayPowerState> firstProperty,
- FloatProperty<DisplayPowerState> secondProperty) {
- return new DualRampAnimator(dps, firstProperty, secondProperty);
- }
-
- AutomaticBrightnessController getAutomaticBrightnessController(
- AutomaticBrightnessController.Callbacks callbacks, Looper looper,
- SensorManager sensorManager, Sensor lightSensor,
- SparseArray<BrightnessMappingStrategy> brightnessMappingStrategyMap,
- int lightSensorWarmUpTime, float brightnessMin, float brightnessMax,
- float dozeScaleFactor, int lightSensorRate, int initialLightSensorRate,
- long brighteningLightDebounceConfig, long darkeningLightDebounceConfig,
- long brighteningLightDebounceConfigIdle, long darkeningLightDebounceConfigIdle,
- boolean resetAmbientLuxAfterWarmUpConfig,
- HysteresisLevels ambientBrightnessThresholds,
- HysteresisLevels screenBrightnessThresholds,
- HysteresisLevels ambientBrightnessThresholdsIdle,
- HysteresisLevels screenBrightnessThresholdsIdle, Context context,
- BrightnessRangeController brightnessModeController,
- BrightnessThrottler brightnessThrottler, int ambientLightHorizonShort,
- int ambientLightHorizonLong, float userLux, float userNits) {
- return new AutomaticBrightnessController(callbacks, looper, sensorManager, lightSensor,
- brightnessMappingStrategyMap, lightSensorWarmUpTime, brightnessMin,
- brightnessMax, dozeScaleFactor, lightSensorRate, initialLightSensorRate,
- brighteningLightDebounceConfig, darkeningLightDebounceConfig,
- brighteningLightDebounceConfigIdle, darkeningLightDebounceConfigIdle,
- resetAmbientLuxAfterWarmUpConfig, ambientBrightnessThresholds,
- screenBrightnessThresholds, ambientBrightnessThresholdsIdle,
- screenBrightnessThresholdsIdle, context, brightnessModeController,
- brightnessThrottler, ambientLightHorizonShort, ambientLightHorizonLong, userLux,
- userNits);
- }
-
- BrightnessMappingStrategy getDefaultModeBrightnessMapper(Context context,
- DisplayDeviceConfig displayDeviceConfig,
- DisplayWhiteBalanceController displayWhiteBalanceController) {
- return BrightnessMappingStrategy.create(context, displayDeviceConfig,
- AUTO_BRIGHTNESS_MODE_DEFAULT, displayWhiteBalanceController);
- }
-
- HysteresisLevels getHysteresisLevels(float[] brighteningThresholdsPercentages,
- float[] darkeningThresholdsPercentages, float[] brighteningThresholdLevels,
- float[] darkeningThresholdLevels, float minDarkeningThreshold,
- float minBrighteningThreshold) {
- return new HysteresisLevels(brighteningThresholdsPercentages,
- darkeningThresholdsPercentages, brighteningThresholdLevels,
- darkeningThresholdLevels, minDarkeningThreshold, minBrighteningThreshold);
- }
-
- HysteresisLevels getHysteresisLevels(float[] brighteningThresholdsPercentages,
- float[] darkeningThresholdsPercentages, float[] brighteningThresholdLevels,
- float[] darkeningThresholdLevels, float minDarkeningThreshold,
- float minBrighteningThreshold, boolean potentialOldBrightnessRange) {
- return new HysteresisLevels(brighteningThresholdsPercentages,
- darkeningThresholdsPercentages, brighteningThresholdLevels,
- darkeningThresholdLevels, minDarkeningThreshold, minBrighteningThreshold,
- potentialOldBrightnessRange);
- }
-
- ScreenOffBrightnessSensorController getScreenOffBrightnessSensorController(
- SensorManager sensorManager,
- Sensor lightSensor,
- Handler handler,
- ScreenOffBrightnessSensorController.Clock clock,
- int[] sensorValueToLux,
- BrightnessMappingStrategy brightnessMapper) {
- return new ScreenOffBrightnessSensorController(
- sensorManager,
- lightSensor,
- handler,
- clock,
- sensorValueToLux,
- brightnessMapper
- );
- }
-
- HighBrightnessModeController getHighBrightnessModeController(Handler handler, int width,
- int height, IBinder displayToken, String displayUniqueId, float brightnessMin,
- float brightnessMax, DisplayDeviceConfig.HighBrightnessModeData hbmData,
- HighBrightnessModeController.HdrBrightnessDeviceConfig hdrBrightnessCfg,
- Runnable hbmChangeCallback, HighBrightnessModeMetadata hbmMetadata,
- Context context) {
- return new HighBrightnessModeController(handler, width, height, displayToken,
- displayUniqueId, brightnessMin, brightnessMax, hbmData, hdrBrightnessCfg,
- hbmChangeCallback, hbmMetadata, context);
- }
-
- DisplayWhiteBalanceController getDisplayWhiteBalanceController(Handler handler,
- SensorManager sensorManager, Resources resources) {
- return DisplayWhiteBalanceFactory.create(handler,
- sensorManager, resources);
- }
- }
-
- static class CachedBrightnessInfo {
- public MutableFloat brightness = new MutableFloat(PowerManager.BRIGHTNESS_INVALID_FLOAT);
- public MutableFloat adjustedBrightness =
- new MutableFloat(PowerManager.BRIGHTNESS_INVALID_FLOAT);
- public MutableFloat brightnessMin =
- new MutableFloat(PowerManager.BRIGHTNESS_INVALID_FLOAT);
- public MutableFloat brightnessMax =
- new MutableFloat(PowerManager.BRIGHTNESS_INVALID_FLOAT);
- public MutableInt hbmMode = new MutableInt(BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF);
- public MutableFloat hbmTransitionPoint =
- new MutableFloat(HighBrightnessModeController.HBM_TRANSITION_POINT_INVALID);
- public MutableInt brightnessMaxReason =
- new MutableInt(BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE);
-
- public boolean checkAndSetFloat(MutableFloat mf, float f) {
- if (mf.value != f) {
- mf.value = f;
- return true;
- }
- return false;
- }
-
- public boolean checkAndSetInt(MutableInt mi, int i) {
- if (mi.value != i) {
- mi.value = i;
- return true;
- }
- return false;
- }
- }
-}
diff --git a/services/core/java/com/android/server/display/feature/DeviceConfigParameterProvider.java b/services/core/java/com/android/server/display/feature/DeviceConfigParameterProvider.java
index 465584c3d90c..403dfbe920ee 100644
--- a/services/core/java/com/android/server/display/feature/DeviceConfigParameterProvider.java
+++ b/services/core/java/com/android/server/display/feature/DeviceConfigParameterProvider.java
@@ -41,13 +41,6 @@ public class DeviceConfigParameterProvider {
mDeviceConfig = deviceConfig;
}
- // feature: revamping_display_power_controller_feature
- // parameter: use_newly_structured_display_power_controller
- public boolean isNewPowerControllerFeatureEnabled() {
- return mDeviceConfig.getBoolean(DeviceConfig.NAMESPACE_DISPLAY_MANAGER,
- DisplayManager.DeviceConfig.KEY_NEW_POWER_CONTROLLER, true);
- }
-
// feature: hdr_output_control
// parameter: enable_hdr_output_control
public boolean isHdrOutputControlFeatureEnabled() {
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
deleted file mode 100644
index 943862f918bc..000000000000
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
+++ /dev/null
@@ -1,1718 +0,0 @@
-/*
- * 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;
-
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
-import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_IDLE;
-
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.anyFloat;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.ArgumentMatchers.isA;
-import static org.mockito.Mockito.atLeastOnce;
-import static org.mockito.Mockito.clearInvocations;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.when;
-
-import android.app.ActivityManager;
-import android.content.Context;
-import android.content.res.Resources;
-import android.hardware.Sensor;
-import android.hardware.SensorEventListener;
-import android.hardware.SensorManager;
-import android.hardware.display.BrightnessInfo;
-import android.hardware.display.DisplayManagerInternal;
-import android.hardware.display.DisplayManagerInternal.DisplayPowerCallbacks;
-import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.PowerManager;
-import android.os.SystemProperties;
-import android.os.UserHandle;
-import android.os.test.TestLooper;
-import android.platform.test.annotations.RequiresFlagsDisabled;
-import android.platform.test.annotations.RequiresFlagsEnabled;
-import android.platform.test.flag.junit.CheckFlagsRule;
-import android.platform.test.flag.junit.DeviceFlagsValueProvider;
-import android.provider.Settings;
-import android.testing.TestableContext;
-import android.util.FloatProperty;
-import android.util.SparseArray;
-import android.view.Display;
-import android.view.DisplayInfo;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.FlakyTest;
-import androidx.test.filters.SmallTest;
-import androidx.test.platform.app.InstrumentationRegistry;
-
-import com.android.internal.util.test.LocalServiceKeeperRule;
-import com.android.modules.utils.testing.ExtendedMockitoRule;
-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.color.ColorDisplayService;
-import com.android.server.display.config.SensorData;
-import com.android.server.display.feature.DisplayManagerFlags;
-import com.android.server.display.feature.flags.Flags;
-import com.android.server.display.layout.Layout;
-import com.android.server.display.whitebalance.DisplayWhiteBalanceController;
-import com.android.server.policy.WindowManagerPolicy;
-import com.android.server.testutils.OffsettableClock;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.quality.Strictness;
-import org.mockito.stubbing.Answer;
-
-import java.util.List;
-
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public final class DisplayPowerControllerTest {
- private static final int DISPLAY_ID = Display.DEFAULT_DISPLAY;
- private static final String UNIQUE_ID = "unique_id_test123";
- private static final int FOLLOWER_DISPLAY_ID = DISPLAY_ID + 1;
- private static final String FOLLOWER_UNIQUE_ID = "unique_id_456";
- private static final int SECOND_FOLLOWER_DISPLAY_ID = FOLLOWER_DISPLAY_ID + 1;
- private static final String SECOND_FOLLOWER_UNIQUE_DISPLAY_ID = "unique_id_789";
- private static final float PROX_SENSOR_MAX_RANGE = 5;
- private static final float BRIGHTNESS_RAMP_RATE_MINIMUM = 0.0f;
- private static final float BRIGHTNESS_RAMP_RATE_FAST_DECREASE = 0.3f;
- private static final float BRIGHTNESS_RAMP_RATE_FAST_INCREASE = 0.4f;
- private static final float BRIGHTNESS_RAMP_RATE_SLOW_DECREASE = 0.1f;
- private static final float BRIGHTNESS_RAMP_RATE_SLOW_INCREASE = 0.2f;
- private static final float BRIGHTNESS_RAMP_RATE_SLOW_INCREASE_IDLE = 0.5f;
- private static final float BRIGHTNESS_RAMP_RATE_SLOW_DECREASE_IDLE = 0.6f;
-
- private static final long BRIGHTNESS_RAMP_INCREASE_MAX = 1000;
- private static final long BRIGHTNESS_RAMP_DECREASE_MAX = 2000;
- private static final long BRIGHTNESS_RAMP_INCREASE_MAX_IDLE = 3000;
- private static final long BRIGHTNESS_RAMP_DECREASE_MAX_IDLE = 4000;
-
- private OffsettableClock mClock;
- private TestLooper mTestLooper;
- private Handler mHandler;
- private DisplayPowerControllerHolder mHolder;
- private Sensor mProxSensor;
-
- @Mock
- private DisplayPowerCallbacks mDisplayPowerCallbacksMock;
- @Mock
- private SensorManager mSensorManagerMock;
- @Mock
- private DisplayBlanker mDisplayBlankerMock;
- @Mock
- private BrightnessTracker mBrightnessTrackerMock;
- @Mock
- private WindowManagerPolicy mWindowManagerPolicyMock;
- @Mock
- private PowerManager mPowerManagerMock;
- @Mock
- private ColorDisplayService.ColorDisplayServiceInternal mCdsiMock;
- @Mock
- private DisplayWhiteBalanceController mDisplayWhiteBalanceControllerMock;
- @Mock
- private DisplayManagerFlags mDisplayManagerFlagsMock;
- @Mock
- private DisplayManagerInternal.DisplayOffloadSession mDisplayOffloadSession;
-
- @Captor
- private ArgumentCaptor<SensorEventListener> mSensorEventListenerCaptor;
-
- @Rule
- public final TestableContext mContext = new TestableContext(
- InstrumentationRegistry.getInstrumentation().getContext());
-
- @Rule
- public final ExtendedMockitoRule mExtendedMockitoRule =
- new ExtendedMockitoRule.Builder(this)
- .setStrictness(Strictness.LENIENT)
- .spyStatic(SystemProperties.class)
- .spyStatic(BatteryStatsService.class)
- .spyStatic(ActivityManager.class)
- .build();
-
- @Rule
- public LocalServiceKeeperRule mLocalServiceKeeperRule = new LocalServiceKeeperRule();
-
- @Rule
- public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
-
- @Before
- public void setUp() throws Exception {
- mClock = new OffsettableClock.Stopped();
- mTestLooper = new TestLooper(mClock::now);
- mHandler = new Handler(mTestLooper.getLooper());
-
- // Set some settings to minimize unexpected events and have a consistent starting state
- Settings.System.putInt(mContext.getContentResolver(),
- Settings.System.SCREEN_BRIGHTNESS_MODE,
- Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
- Settings.System.putFloatForUser(mContext.getContentResolver(),
- Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0, UserHandle.USER_CURRENT);
-
- mLocalServiceKeeperRule.overrideLocalService(
- WindowManagerPolicy.class, mWindowManagerPolicyMock);
- mLocalServiceKeeperRule.overrideLocalService(
- ColorDisplayService.ColorDisplayServiceInternal.class, mCdsiMock);
-
- mContext.addMockSystemService(PowerManager.class, mPowerManagerMock);
-
- mContext.getOrCreateTestableResources().addOverride(
- com.android.internal.R.bool.config_displayColorFadeDisabled, false);
-
- doAnswer((Answer<Void>) invocationOnMock -> null).when(() ->
- SystemProperties.set(anyString(), any()));
- doAnswer((Answer<Void>) invocationOnMock -> null).when(BatteryStatsService::getService);
- doAnswer((Answer<Boolean>) invocationOnMock -> false)
- .when(ActivityManager::isLowRamDeviceStatic);
-
- setUpSensors();
- mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID);
- }
-
- @Test
- public void testReleaseProxSuspendBlockersOnExit() throws Exception {
- when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON);
- // Send a display power request
- DisplayPowerRequest dpr = new DisplayPowerRequest();
- dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
- dpr.useProximitySensor = true;
- mHolder.dpc.requestPowerState(dpr, false /* waitForNegativeProximity */);
-
- // Run updatePowerState to start listener for the prox sensor
- advanceTime(1);
-
- SensorEventListener listener = getSensorEventListener(mProxSensor);
- assertNotNull(listener);
-
- listener.onSensorChanged(TestUtils.createSensorEvent(mProxSensor, /* value= */ 5));
- advanceTime(1);
-
- // two times, one for unfinished business and one for proximity
- verify(mDisplayPowerCallbacksMock).acquireSuspendBlocker(
- mHolder.dpc.getSuspendBlockerUnfinishedBusinessId(DISPLAY_ID));
- verify(mDisplayPowerCallbacksMock).acquireSuspendBlocker(
- mHolder.dpc.getSuspendBlockerProxDebounceId(DISPLAY_ID));
-
- mHolder.dpc.stop();
- advanceTime(1);
-
- // two times, one for unfinished business and one for proximity
- verify(mDisplayPowerCallbacksMock).releaseSuspendBlocker(
- mHolder.dpc.getSuspendBlockerUnfinishedBusinessId(DISPLAY_ID));
- verify(mDisplayPowerCallbacksMock).releaseSuspendBlocker(
- mHolder.dpc.getSuspendBlockerProxDebounceId(DISPLAY_ID));
- }
-
- @Test
- public void testScreenOffBecauseOfProximity() throws Exception {
- when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON);
- // Send a display power request
- DisplayPowerRequest dpr = new DisplayPowerRequest();
- dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
- dpr.useProximitySensor = true;
- mHolder.dpc.requestPowerState(dpr, false /* waitForNegativeProximity */);
-
- // Run updatePowerState to start listener for the prox sensor
- advanceTime(1);
-
- SensorEventListener listener = getSensorEventListener(mProxSensor);
- assertNotNull(listener);
-
- // Send a positive proximity event
- listener.onSensorChanged(TestUtils.createSensorEvent(mProxSensor, /* value= */ 1));
- advanceTime(1);
-
- // The display should have been turned off
- verify(mHolder.displayPowerState).setScreenState(Display.STATE_OFF);
-
- clearInvocations(mHolder.displayPowerState);
- when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_OFF);
- // Send a negative proximity event
- listener.onSensorChanged(TestUtils.createSensorEvent(mProxSensor,
- (int) PROX_SENSOR_MAX_RANGE + 1));
- // Advance time by less than PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY
- advanceTime(1);
-
- // The prox sensor is debounced so the display should not have been turned back on yet
- verify(mHolder.displayPowerState, never()).setScreenState(Display.STATE_ON);
-
- // Advance time by more than PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY
- advanceTime(1000);
-
- // The display should have been turned back on
- verify(mHolder.displayPowerState).setScreenState(Display.STATE_ON);
- }
-
- @Test
- public void testScreenOffBecauseOfProximity_ProxSensorGone() throws Exception {
- when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON);
- // Send a display power request
- DisplayPowerRequest dpr = new DisplayPowerRequest();
- dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
- dpr.useProximitySensor = true;
- mHolder.dpc.requestPowerState(dpr, false /* waitForNegativeProximity */);
-
- // Run updatePowerState to start listener for the prox sensor
- advanceTime(1);
-
- SensorEventListener listener = getSensorEventListener(mProxSensor);
- assertNotNull(listener);
-
- // Send a positive proximity event
- listener.onSensorChanged(TestUtils.createSensorEvent(mProxSensor, /* value= */ 1));
- advanceTime(1);
-
- // The display should have been turned off
- verify(mHolder.displayPowerState).setScreenState(Display.STATE_OFF);
-
- when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_OFF);
- // The display device changes and we no longer have a prox sensor
- reset(mSensorManagerMock);
- setUpDisplay(DISPLAY_ID, "new_unique_id", mHolder.display, mock(DisplayDevice.class),
- mock(DisplayDeviceConfig.class), /* isEnabled= */ true);
- mHolder.dpc.onDisplayChanged(mHolder.hbmMetadata, Layout.NO_LEAD_DISPLAY);
-
- advanceTime(1); // Run updatePowerState
-
- // The display should have been turned back on and the listener should have been
- // unregistered
- verify(mHolder.displayPowerState).setScreenState(Display.STATE_ON);
- verify(mSensorManagerMock).unregisterListener(listener);
- }
-
- @Test
- public void testProximitySensorListenerNotRegisteredForNonDefaultDisplay() {
- DisplayPowerControllerHolder followerDpc =
- createDisplayPowerController(FOLLOWER_DISPLAY_ID, FOLLOWER_UNIQUE_ID);
-
- when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON);
- // send a display power request
- DisplayPowerRequest dpr = new DisplayPowerRequest();
- dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
- dpr.useProximitySensor = true;
- followerDpc.dpc.requestPowerState(dpr, false /* waitForNegativeProximity */);
-
- // Run updatePowerState
- advanceTime(1);
-
- verify(mSensorManagerMock, never()).registerListener(any(SensorEventListener.class),
- eq(mProxSensor), anyInt(), any(Handler.class));
- }
-
- @Test
- @FlakyTest(bugId = 294107062)
- public void testDisplayBrightnessFollowers_BothDpcsSupportNits() {
- DisplayPowerControllerHolder followerDpc =
- createDisplayPowerController(FOLLOWER_DISPLAY_ID, FOLLOWER_UNIQUE_ID);
- when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
- when(followerDpc.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
-
- DisplayPowerRequest dpr = new DisplayPowerRequest();
- mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- followerDpc.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- advanceTime(1); // Run updatePowerState
-
- ArgumentCaptor<BrightnessSetting.BrightnessSettingListener> listenerCaptor =
- ArgumentCaptor.forClass(BrightnessSetting.BrightnessSettingListener.class);
- verify(mHolder.brightnessSetting).registerListener(listenerCaptor.capture());
- BrightnessSetting.BrightnessSettingListener listener = listenerCaptor.getValue();
-
- mHolder.dpc.addDisplayBrightnessFollower(followerDpc.dpc);
-
- // Test different float scale values
- float leadBrightness = 0.3f;
- float followerBrightness = 0.4f;
- float nits = 300;
- when(mHolder.automaticBrightnessController.convertToNits(leadBrightness)).thenReturn(nits);
- when(followerDpc.automaticBrightnessController.getBrightnessFromNits(nits))
- .thenReturn(followerBrightness);
- when(mHolder.brightnessSetting.getBrightness()).thenReturn(leadBrightness);
- listener.onBrightnessChanged(leadBrightness);
- advanceTime(1); // Send messages, run updatePowerState
- verify(mHolder.animator).animateTo(eq(leadBrightness), anyFloat(),
- eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
- verify(followerDpc.animator).animateTo(eq(followerBrightness), anyFloat(),
- eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
-
- when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(leadBrightness);
- when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(followerBrightness);
- clearInvocations(mHolder.animator, followerDpc.animator);
-
- // Test the same float scale value
- float brightness = 0.6f;
- nits = 600;
- when(mHolder.automaticBrightnessController.convertToNits(brightness)).thenReturn(nits);
- when(followerDpc.automaticBrightnessController.getBrightnessFromNits(nits))
- .thenReturn(brightness);
- when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness);
- listener.onBrightnessChanged(brightness);
- advanceTime(1); // Send messages, run updatePowerState
- verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
- eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
- verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(),
- eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
- }
-
- @Test
- @FlakyTest(bugId = 294107062)
- public void testDisplayBrightnessFollowers_FollowerDoesNotSupportNits() {
- DisplayPowerControllerHolder followerDpc =
- createDisplayPowerController(FOLLOWER_DISPLAY_ID, FOLLOWER_UNIQUE_ID);
- when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
- when(followerDpc.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
-
- DisplayPowerRequest dpr = new DisplayPowerRequest();
- mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- followerDpc.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- advanceTime(1); // Run updatePowerState
-
- ArgumentCaptor<BrightnessSetting.BrightnessSettingListener> listenerCaptor =
- ArgumentCaptor.forClass(BrightnessSetting.BrightnessSettingListener.class);
- verify(mHolder.brightnessSetting).registerListener(listenerCaptor.capture());
- BrightnessSetting.BrightnessSettingListener listener = listenerCaptor.getValue();
-
- mHolder.dpc.addDisplayBrightnessFollower(followerDpc.dpc);
-
- float brightness = 0.3f;
- when(mHolder.automaticBrightnessController.convertToNits(brightness)).thenReturn(300f);
- when(followerDpc.automaticBrightnessController.getBrightnessFromNits(anyFloat()))
- .thenReturn(PowerManager.BRIGHTNESS_INVALID_FLOAT);
- when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness);
- listener.onBrightnessChanged(brightness);
- advanceTime(1); // Send messages, run updatePowerState
- verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
- eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
- verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(),
- eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
- }
-
- @Test
- @FlakyTest(bugId = 294107062)
- public void testDisplayBrightnessFollowers_LeadDpcDoesNotSupportNits() {
- DisplayPowerControllerHolder followerDpc =
- createDisplayPowerController(FOLLOWER_DISPLAY_ID, FOLLOWER_UNIQUE_ID);
- when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
- when(followerDpc.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
-
- DisplayPowerRequest dpr = new DisplayPowerRequest();
- mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- followerDpc.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- advanceTime(1); // Run updatePowerState
-
- ArgumentCaptor<BrightnessSetting.BrightnessSettingListener> listenerCaptor =
- ArgumentCaptor.forClass(BrightnessSetting.BrightnessSettingListener.class);
- verify(mHolder.brightnessSetting).registerListener(listenerCaptor.capture());
- BrightnessSetting.BrightnessSettingListener listener = listenerCaptor.getValue();
-
- mHolder.dpc.addDisplayBrightnessFollower(followerDpc.dpc);
-
- float brightness = 0.3f;
- when(mHolder.automaticBrightnessController.convertToNits(anyFloat())).thenReturn(-1f);
- when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness);
- listener.onBrightnessChanged(brightness);
- advanceTime(1); // Send messages, run updatePowerState
- verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
- eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
- verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(),
- eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
- }
-
- @Test
- @FlakyTest(bugId = 294107062)
- public void testDisplayBrightnessFollowers_NeitherDpcSupportsNits() {
- DisplayPowerControllerHolder followerDpc =
- createDisplayPowerController(FOLLOWER_DISPLAY_ID, FOLLOWER_UNIQUE_ID);
- when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
- when(followerDpc.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
-
- DisplayPowerRequest dpr = new DisplayPowerRequest();
- mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- followerDpc.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- advanceTime(1); // Run updatePowerState
-
- ArgumentCaptor<BrightnessSetting.BrightnessSettingListener> listenerCaptor =
- ArgumentCaptor.forClass(BrightnessSetting.BrightnessSettingListener.class);
- verify(mHolder.brightnessSetting).registerListener(listenerCaptor.capture());
- BrightnessSetting.BrightnessSettingListener listener = listenerCaptor.getValue();
-
- mHolder.dpc.addDisplayBrightnessFollower(followerDpc.dpc);
-
- float brightness = 0.3f;
- when(mHolder.automaticBrightnessController.convertToNits(anyFloat())).thenReturn(-1f);
- when(followerDpc.automaticBrightnessController.getBrightnessFromNits(anyFloat()))
- .thenReturn(PowerManager.BRIGHTNESS_INVALID_FLOAT);
- when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness);
- listener.onBrightnessChanged(brightness);
- advanceTime(1); // Send messages, run updatePowerState
- verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
- eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
- verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(),
- eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
- }
-
- @Test
- @FlakyTest(bugId = 294107062)
- public void testDisplayBrightnessFollowers_AutomaticBrightness() {
- Settings.System.putInt(mContext.getContentResolver(),
- Settings.System.SCREEN_BRIGHTNESS_MODE,
- Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
- DisplayPowerControllerHolder followerDpc =
- createDisplayPowerController(FOLLOWER_DISPLAY_ID, FOLLOWER_UNIQUE_ID);
- when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON);
- when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
- when(followerDpc.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
- float leadBrightness = 0.1f;
- float rawLeadBrightness = 0.3f;
- float followerBrightness = 0.4f;
- float nits = 300;
- float ambientLux = 3000;
- when(mHolder.automaticBrightnessController.getRawAutomaticScreenBrightness())
- .thenReturn(rawLeadBrightness);
- when(mHolder.automaticBrightnessController
- .getAutomaticScreenBrightness(any(BrightnessEvent.class)))
- .thenReturn(leadBrightness);
- when(mHolder.automaticBrightnessController.convertToNits(rawLeadBrightness))
- .thenReturn(nits);
- when(mHolder.automaticBrightnessController.getAmbientLux()).thenReturn(ambientLux);
- when(followerDpc.automaticBrightnessController.getBrightnessFromNits(nits))
- .thenReturn(followerBrightness);
-
- mHolder.dpc.addDisplayBrightnessFollower(followerDpc.dpc);
-
- DisplayPowerRequest dpr = new DisplayPowerRequest();
- mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- followerDpc.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- advanceTime(1); // Run updatePowerState
-
- verify(mHolder.animator).animateTo(eq(leadBrightness), anyFloat(),
- eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
- // One triggered by handleBrightnessModeChange, another triggered by setBrightnessToFollow
- verify(followerDpc.hbmController, times(2)).onAmbientLuxChange(ambientLux);
- verify(followerDpc.animator, times(2)).animateTo(eq(followerBrightness), anyFloat(),
- eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
-
- when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(leadBrightness);
- when(followerDpc.displayPowerState.getScreenBrightness()).thenReturn(followerBrightness);
- clearInvocations(mHolder.animator, followerDpc.animator);
-
- leadBrightness = 0.05f;
- rawLeadBrightness = 0.2f;
- followerBrightness = 0.3f;
- nits = 200;
- ambientLux = 2000;
- when(mHolder.automaticBrightnessController.getRawAutomaticScreenBrightness())
- .thenReturn(rawLeadBrightness);
- when(mHolder.automaticBrightnessController
- .getAutomaticScreenBrightness(any(BrightnessEvent.class)))
- .thenReturn(leadBrightness);
- when(mHolder.automaticBrightnessController.convertToNits(rawLeadBrightness))
- .thenReturn(nits);
- when(mHolder.automaticBrightnessController.getAmbientLux()).thenReturn(ambientLux);
- when(followerDpc.automaticBrightnessController.getBrightnessFromNits(nits))
- .thenReturn(followerBrightness);
-
- mHolder.dpc.updateBrightness();
- advanceTime(1); // Run updatePowerState
-
- // The second time, the animation rate should be slow
- verify(mHolder.animator).animateTo(eq(leadBrightness), anyFloat(),
- eq(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE), eq(false));
- verify(followerDpc.hbmController).onAmbientLuxChange(ambientLux);
- verify(followerDpc.animator).animateTo(eq(followerBrightness), anyFloat(),
- eq(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE), eq(false));
- }
-
- @Test
- @FlakyTest(bugId = 294107062)
- public void testDisplayBrightnessFollowersRemoval_RemoveSingleFollower() {
- DisplayPowerControllerHolder followerDpc = createDisplayPowerController(FOLLOWER_DISPLAY_ID,
- FOLLOWER_UNIQUE_ID);
- DisplayPowerControllerHolder secondFollowerDpc = createDisplayPowerController(
- SECOND_FOLLOWER_DISPLAY_ID, SECOND_FOLLOWER_UNIQUE_DISPLAY_ID);
- when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
- when(followerDpc.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
- when(secondFollowerDpc.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
-
- DisplayPowerRequest dpr = new DisplayPowerRequest();
- mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- followerDpc.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- secondFollowerDpc.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- advanceTime(1); // Run updatePowerState
-
- ArgumentCaptor<BrightnessSetting.BrightnessSettingListener> listenerCaptor =
- ArgumentCaptor.forClass(BrightnessSetting.BrightnessSettingListener.class);
- verify(mHolder.brightnessSetting).registerListener(listenerCaptor.capture());
- BrightnessSetting.BrightnessSettingListener listener = listenerCaptor.getValue();
-
- // Set the initial brightness on the DPC we're going to remove so we have a fixed value for
- // it to return to.
- listenerCaptor = ArgumentCaptor.forClass(BrightnessSetting.BrightnessSettingListener.class);
- verify(followerDpc.brightnessSetting).registerListener(listenerCaptor.capture());
- BrightnessSetting.BrightnessSettingListener followerListener = listenerCaptor.getValue();
- final float initialFollowerBrightness = 0.3f;
- when(followerDpc.brightnessSetting.getBrightness()).thenReturn(initialFollowerBrightness);
- followerListener.onBrightnessChanged(initialFollowerBrightness);
- advanceTime(1);
- verify(followerDpc.animator).animateTo(eq(initialFollowerBrightness), anyFloat(),
- eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
-
- when(followerDpc.displayPowerState.getScreenBrightness())
- .thenReturn(initialFollowerBrightness);
-
- mHolder.dpc.addDisplayBrightnessFollower(followerDpc.dpc);
- mHolder.dpc.addDisplayBrightnessFollower(secondFollowerDpc.dpc);
- clearInvocations(followerDpc.animator);
-
- // Validate both followers are correctly registered and receiving brightness updates
- float brightness = 0.6f;
- float nits = 600;
- when(mHolder.automaticBrightnessController.convertToNits(brightness)).thenReturn(nits);
- when(followerDpc.automaticBrightnessController.getBrightnessFromNits(nits))
- .thenReturn(brightness);
- when(secondFollowerDpc.automaticBrightnessController.getBrightnessFromNits(nits))
- .thenReturn(brightness);
- when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness);
- listener.onBrightnessChanged(brightness);
- advanceTime(1); // Send messages, run updatePowerState
- verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
- eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
- verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(),
- eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
- verify(secondFollowerDpc.animator).animateTo(eq(brightness), anyFloat(),
- eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
-
- when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(brightness);
- when(followerDpc.displayPowerState.getScreenBrightness()).thenReturn(brightness);
- when(secondFollowerDpc.displayPowerState.getScreenBrightness()).thenReturn(brightness);
- clearInvocations(mHolder.animator, followerDpc.animator, secondFollowerDpc.animator);
-
- // Remove the first follower and validate it goes back to its original brightness.
- mHolder.dpc.removeDisplayBrightnessFollower(followerDpc.dpc);
- advanceTime(1);
- verify(followerDpc.animator).animateTo(eq(initialFollowerBrightness), anyFloat(),
- eq(BRIGHTNESS_RAMP_RATE_FAST_DECREASE), eq(false));
-
- when(followerDpc.displayPowerState.getScreenBrightness())
- .thenReturn(initialFollowerBrightness);
- clearInvocations(followerDpc.animator);
-
- // Change the brightness of the lead display and validate only the second follower responds
- brightness = 0.7f;
- nits = 700;
- when(mHolder.automaticBrightnessController.convertToNits(brightness)).thenReturn(nits);
- when(followerDpc.automaticBrightnessController.getBrightnessFromNits(nits))
- .thenReturn(brightness);
- when(secondFollowerDpc.automaticBrightnessController.getBrightnessFromNits(nits))
- .thenReturn(brightness);
- when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness);
- listener.onBrightnessChanged(brightness);
- advanceTime(1); // Send messages, run updatePowerState
- verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
- eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
- verify(followerDpc.animator, never()).animateTo(anyFloat(), anyFloat(), anyFloat(),
- anyBoolean());
- verify(secondFollowerDpc.animator).animateTo(eq(brightness), anyFloat(),
- eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
- }
-
- @Test
- @FlakyTest(bugId = 294107062)
- public void testDisplayBrightnessFollowersRemoval_RemoveAllFollowers() {
- DisplayPowerControllerHolder followerHolder =
- createDisplayPowerController(FOLLOWER_DISPLAY_ID, FOLLOWER_UNIQUE_ID);
- DisplayPowerControllerHolder secondFollowerHolder =
- createDisplayPowerController(SECOND_FOLLOWER_DISPLAY_ID,
- SECOND_FOLLOWER_UNIQUE_DISPLAY_ID);
- when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
- when(followerHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
- when(secondFollowerHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
-
- DisplayPowerRequest dpr = new DisplayPowerRequest();
- mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- followerHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- secondFollowerHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- advanceTime(1); // Run updatePowerState
-
- ArgumentCaptor<BrightnessSetting.BrightnessSettingListener> listenerCaptor =
- ArgumentCaptor.forClass(BrightnessSetting.BrightnessSettingListener.class);
- verify(mHolder.brightnessSetting).registerListener(listenerCaptor.capture());
- BrightnessSetting.BrightnessSettingListener listener = listenerCaptor.getValue();
-
- // Set the initial brightness on the DPCs we're going to remove so we have a fixed value for
- // it to return to.
- listenerCaptor = ArgumentCaptor.forClass(BrightnessSetting.BrightnessSettingListener.class);
- verify(followerHolder.brightnessSetting).registerListener(listenerCaptor.capture());
- BrightnessSetting.BrightnessSettingListener followerListener = listenerCaptor.getValue();
- listenerCaptor = ArgumentCaptor.forClass(BrightnessSetting.BrightnessSettingListener.class);
- verify(secondFollowerHolder.brightnessSetting).registerListener(listenerCaptor.capture());
- BrightnessSetting.BrightnessSettingListener secondFollowerListener =
- listenerCaptor.getValue();
- final float initialFollowerBrightness = 0.3f;
- when(followerHolder.brightnessSetting.getBrightness()).thenReturn(
- initialFollowerBrightness);
- when(secondFollowerHolder.brightnessSetting.getBrightness()).thenReturn(
- initialFollowerBrightness);
- followerListener.onBrightnessChanged(initialFollowerBrightness);
- secondFollowerListener.onBrightnessChanged(initialFollowerBrightness);
- advanceTime(1);
- verify(followerHolder.animator).animateTo(eq(initialFollowerBrightness), anyFloat(),
- eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
- verify(secondFollowerHolder.animator).animateTo(eq(initialFollowerBrightness), anyFloat(),
- eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
-
- when(followerHolder.displayPowerState.getScreenBrightness())
- .thenReturn(initialFollowerBrightness);
- when(secondFollowerHolder.displayPowerState.getScreenBrightness())
- .thenReturn(initialFollowerBrightness);
-
- mHolder.dpc.addDisplayBrightnessFollower(followerHolder.dpc);
- mHolder.dpc.addDisplayBrightnessFollower(secondFollowerHolder.dpc);
- clearInvocations(followerHolder.animator, secondFollowerHolder.animator);
-
- // Validate both followers are correctly registered and receiving brightness updates
- float brightness = 0.6f;
- float nits = 600;
- when(mHolder.automaticBrightnessController.convertToNits(brightness)).thenReturn(nits);
- when(followerHolder.automaticBrightnessController.getBrightnessFromNits(nits))
- .thenReturn(brightness);
- when(secondFollowerHolder.automaticBrightnessController.getBrightnessFromNits(nits))
- .thenReturn(brightness);
- when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness);
- listener.onBrightnessChanged(brightness);
- advanceTime(1); // Send messages, run updatePowerState
- verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
- eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
- verify(followerHolder.animator).animateTo(eq(brightness), anyFloat(),
- eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
- verify(secondFollowerHolder.animator).animateTo(eq(brightness), anyFloat(),
- eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
-
- when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(brightness);
- when(followerHolder.displayPowerState.getScreenBrightness()).thenReturn(brightness);
- when(secondFollowerHolder.displayPowerState.getScreenBrightness()).thenReturn(brightness);
- clearInvocations(mHolder.animator, followerHolder.animator, secondFollowerHolder.animator);
-
- // Stop the lead DPC and validate that the followers go back to their original brightness.
- mHolder.dpc.stop();
- advanceTime(1);
- verify(followerHolder.animator).animateTo(eq(initialFollowerBrightness), anyFloat(),
- eq(BRIGHTNESS_RAMP_RATE_FAST_DECREASE), eq(false));
- verify(secondFollowerHolder.animator).animateTo(eq(initialFollowerBrightness), anyFloat(),
- eq(BRIGHTNESS_RAMP_RATE_FAST_DECREASE), eq(false));
- clearInvocations(followerHolder.animator, secondFollowerHolder.animator);
- }
-
- @Test
- public void testDoesNotSetScreenStateForNonDefaultDisplayUntilBootCompleted() {
- // We should still set screen state for the default display
- DisplayPowerRequest dpr = new DisplayPowerRequest();
- mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- advanceTime(1); // Run updatePowerState
- verify(mHolder.displayPowerState, times(2)).setScreenState(anyInt());
-
- mHolder = createDisplayPowerController(42, UNIQUE_ID);
-
- mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- advanceTime(1); // Run updatePowerState
- verify(mHolder.displayPowerState, never()).setScreenState(anyInt());
-
- mHolder.dpc.onBootCompleted();
- advanceTime(1); // Run updatePowerState
- verify(mHolder.displayPowerState).setScreenState(anyInt());
- }
-
- @Test
- public void testSetScreenOffBrightnessSensorEnabled_DisplayIsOff() {
- Settings.System.putInt(mContext.getContentResolver(),
- Settings.System.SCREEN_BRIGHTNESS_MODE,
- Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
-
- DisplayPowerRequest dpr = new DisplayPowerRequest();
- dpr.policy = DisplayPowerRequest.POLICY_OFF;
- mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- advanceTime(1); // Run updatePowerState
-
- verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
- .setLightSensorEnabled(true);
-
- // The display turns on and we use the brightness value recommended by
- // ScreenOffBrightnessSensorController
- clearInvocations(mHolder.screenOffBrightnessSensorController);
- float brightness = 0.14f;
- when(mHolder.screenOffBrightnessSensorController.getAutomaticScreenBrightness())
- .thenReturn(brightness);
- dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
- when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON);
- when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness(
- any(BrightnessEvent.class))).thenReturn(PowerManager.BRIGHTNESS_INVALID_FLOAT);
-
- mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- advanceTime(1); // Run updatePowerState
-
- verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
- .getAutomaticScreenBrightness();
- verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat(), eq(false));
- }
-
- @Test
- public void testSetScreenOffBrightnessSensorEnabled_DisplayIsInDoze() {
- mContext.getOrCreateTestableResources().addOverride(
- com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing, false);
- mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID);
-
- Settings.System.putInt(mContext.getContentResolver(),
- Settings.System.SCREEN_BRIGHTNESS_MODE,
- Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
-
- DisplayPowerRequest dpr = new DisplayPowerRequest();
- dpr.policy = DisplayPowerRequest.POLICY_DOZE;
- mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- advanceTime(1); // Run updatePowerState
-
- verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
- .setLightSensorEnabled(true);
-
- // The display turns on and we use the brightness value recommended by
- // ScreenOffBrightnessSensorController
- clearInvocations(mHolder.screenOffBrightnessSensorController);
- float brightness = 0.14f;
- when(mHolder.screenOffBrightnessSensorController.getAutomaticScreenBrightness())
- .thenReturn(brightness);
- dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
- when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON);
- when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness(
- any(BrightnessEvent.class))).thenReturn(PowerManager.BRIGHTNESS_INVALID_FLOAT);
-
- mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- advanceTime(1); // Run updatePowerState
-
- verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
- .getAutomaticScreenBrightness();
- verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat(), eq(false));
- }
-
- @Test
- public void testSetScreenOffBrightnessSensorDisabled_AutoBrightnessIsDisabled() {
- // Tests are set up with manual brightness by default, so no need to set it here.
- DisplayPowerRequest dpr = new DisplayPowerRequest();
- dpr.policy = DisplayPowerRequest.POLICY_OFF;
- mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- advanceTime(1); // Run updatePowerState
-
- verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
- .setLightSensorEnabled(false);
- }
-
- @Test
- public void testSetScreenOffBrightnessSensorDisabled_DisplayIsDisabled() {
- Settings.System.putInt(mContext.getContentResolver(),
- Settings.System.SCREEN_BRIGHTNESS_MODE,
- Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
-
- mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID, /* isEnabled= */ false);
-
- DisplayPowerRequest dpr = new DisplayPowerRequest();
- mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- advanceTime(1); // Run updatePowerState
-
- verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
- .setLightSensorEnabled(false);
- }
-
- @Test
- public void testSetScreenOffBrightnessSensorDisabled_DisplayIsOn() {
- DisplayPowerRequest dpr = new DisplayPowerRequest();
- dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
-
- mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- advanceTime(1); // Run updatePowerState
-
- verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
- .setLightSensorEnabled(false);
- }
-
- @Test
- public void testSetScreenOffBrightnessSensorDisabled_DisplayIsAFollower() {
- DisplayPowerRequest dpr = new DisplayPowerRequest();
- dpr.policy = DisplayPowerRequest.POLICY_OFF;
-
- mHolder.dpc.onDisplayChanged(mHolder.hbmMetadata, /* leadDisplayId= */ 42);
- mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- advanceTime(1); // Run updatePowerState
-
- verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
- .setLightSensorEnabled(false);
- }
-
- @Test
- public void testStopScreenOffBrightnessSensorControllerWhenDisplayDeviceChanges() {
- // New display device
- setUpDisplay(DISPLAY_ID, "new_unique_id", mHolder.display, mock(DisplayDevice.class),
- mock(DisplayDeviceConfig.class), /* isEnabled= */ true);
-
- mHolder.dpc.onDisplayChanged(mHolder.hbmMetadata, Layout.NO_LEAD_DISPLAY);
- DisplayPowerRequest dpr = new DisplayPowerRequest();
- mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- advanceTime(1); // Run updatePowerState
-
- verify(mHolder.screenOffBrightnessSensorController).stop();
- }
-
- @Test
- public void testAutoBrightnessEnabled_DisplayIsOn() {
- Settings.System.putInt(mContext.getContentResolver(),
- Settings.System.SCREEN_BRIGHTNESS_MODE,
- Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
-
- DisplayPowerRequest dpr = new DisplayPowerRequest();
- dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
- when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON);
- mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- advanceTime(1); // Run updatePowerState
-
- verify(mHolder.automaticBrightnessController).configure(
- AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED,
- /* configuration= */ null, PowerManager.BRIGHTNESS_INVALID_FLOAT,
- /* userChangedBrightness= */ false, /* adjustment= */ 0,
- /* userChangedAutoBrightnessAdjustment= */ false, DisplayPowerRequest.POLICY_BRIGHT,
- /* shouldResetShortTermModel= */ false
- );
- verify(mHolder.hbmController)
- .setAutoBrightnessEnabled(AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED);
- }
-
- @Test
- public void testAutoBrightnessEnabled_DisplayIsInDoze() {
- Settings.System.putInt(mContext.getContentResolver(),
- Settings.System.SCREEN_BRIGHTNESS_MODE,
- Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
- mContext.getOrCreateTestableResources().addOverride(
- com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing, true);
- mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID);
-
- DisplayPowerRequest dpr = new DisplayPowerRequest();
- dpr.policy = DisplayPowerRequest.POLICY_DOZE;
- when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_DOZE);
- mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- advanceTime(1); // Run updatePowerState
-
- verify(mHolder.automaticBrightnessController).configure(
- AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED,
- /* configuration= */ null, PowerManager.BRIGHTNESS_INVALID_FLOAT,
- /* userChangedBrightness= */ false, /* adjustment= */ 0,
- /* userChangedAutoBrightnessAdjustment= */ false, DisplayPowerRequest.POLICY_DOZE,
- /* shouldResetShortTermModel= */ false
- );
- verify(mHolder.hbmController)
- .setAutoBrightnessEnabled(AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED);
- }
-
- @Test
- public void testAutoBrightnessDisabled_ManualBrightnessMode() {
- Settings.System.putInt(mContext.getContentResolver(),
- Settings.System.SCREEN_BRIGHTNESS_MODE,
- Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
-
- DisplayPowerRequest dpr = new DisplayPowerRequest();
- dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
- when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON);
- mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- advanceTime(1); // Run updatePowerState
-
- // One triggered by the test, the other by handleBrightnessModeChange
- verify(mHolder.automaticBrightnessController, times(2)).configure(
- AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED,
- /* configuration= */ null, PowerManager.BRIGHTNESS_INVALID_FLOAT,
- /* userChangedBrightness= */ false, /* adjustment= */ 0,
- /* userChangedAutoBrightnessAdjustment= */ false, DisplayPowerRequest.POLICY_BRIGHT,
- /* shouldResetShortTermModel= */ false
- );
- verify(mHolder.hbmController, times(2))
- .setAutoBrightnessEnabled(AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED);
- }
-
- @Test
- public void testAutoBrightnessDisabled_DisplayIsOff() {
- Settings.System.putInt(mContext.getContentResolver(),
- Settings.System.SCREEN_BRIGHTNESS_MODE,
- Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
-
- DisplayPowerRequest dpr = new DisplayPowerRequest();
- dpr.policy = DisplayPowerRequest.POLICY_OFF;
- when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_OFF);
- mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- advanceTime(1); // Run updatePowerState
-
- verify(mHolder.automaticBrightnessController).configure(
- AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE,
- /* configuration= */ null, PowerManager.BRIGHTNESS_INVALID_FLOAT,
- /* userChangedBrightness= */ false, /* adjustment= */ 0,
- /* userChangedAutoBrightnessAdjustment= */ false, DisplayPowerRequest.POLICY_OFF,
- /* shouldResetShortTermModel= */ false
- );
- verify(mHolder.hbmController).setAutoBrightnessEnabled(
- AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE);
- }
-
- @Test
- public void testAutoBrightnessDisabled_DisplayIsInDoze() {
- Settings.System.putInt(mContext.getContentResolver(),
- Settings.System.SCREEN_BRIGHTNESS_MODE,
- Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
- mContext.getOrCreateTestableResources().addOverride(
- com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing, false);
- mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID);
-
- DisplayPowerRequest dpr = new DisplayPowerRequest();
- dpr.policy = DisplayPowerRequest.POLICY_DOZE;
- when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_DOZE);
- mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- advanceTime(1); // Run updatePowerState
-
- verify(mHolder.automaticBrightnessController).configure(
- AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE,
- /* configuration= */ null, PowerManager.BRIGHTNESS_INVALID_FLOAT,
- /* userChangedBrightness= */ false, /* adjustment= */ 0,
- /* userChangedAutoBrightnessAdjustment= */ false, DisplayPowerRequest.POLICY_DOZE,
- /* shouldResetShortTermModel= */ false
- );
- verify(mHolder.hbmController).setAutoBrightnessEnabled(
- AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE);
- }
-
- @Test
- public void testAutoBrightnessDisabled_FollowerDisplay() {
- Settings.System.putInt(mContext.getContentResolver(),
- Settings.System.SCREEN_BRIGHTNESS_MODE,
- Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
- mHolder.dpc.setBrightnessToFollow(0.3f, -1, 0, /* slowChange= */ false);
-
- DisplayPowerRequest dpr = new DisplayPowerRequest();
- dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
- when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON);
- mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- advanceTime(1); // Run updatePowerState
-
- // One triggered by the test, the other by handleBrightnessModeChange
- verify(mHolder.automaticBrightnessController, times(2)).configure(
- AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED,
- /* configuration= */ null, PowerManager.BRIGHTNESS_INVALID_FLOAT,
- /* userChangedBrightness= */ false, /* adjustment= */ 0,
- /* userChangedAutoBrightnessAdjustment= */ false, DisplayPowerRequest.POLICY_BRIGHT,
- /* shouldResetShortTermModel= */ false
- );
-
- // HBM should be allowed for the follower display
- verify(mHolder.hbmController)
- .setAutoBrightnessEnabled(AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED);
- }
-
- @Test
- public void testBrightnessNitsPersistWhenDisplayDeviceChanges() {
- float brightness = 0.3f;
- float nits = 500;
- mContext.getOrCreateTestableResources().addOverride(
- com.android.internal.R.bool.config_persistBrightnessNitsForDefaultDisplay,
- true);
-
- mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID);
- when(mHolder.automaticBrightnessController.convertToNits(brightness)).thenReturn(nits);
-
- mHolder.dpc.setBrightness(brightness);
- verify(mHolder.brightnessSetting).setBrightnessNitsForDefaultDisplay(nits);
-
- float newBrightness = 0.4f;
- when(mHolder.brightnessSetting.getBrightnessNitsForDefaultDisplay()).thenReturn(nits);
- when(mHolder.automaticBrightnessController.getBrightnessFromNits(nits))
- .thenReturn(newBrightness);
- // New display device
- setUpDisplay(DISPLAY_ID, "new_unique_id", mHolder.display, mock(DisplayDevice.class),
- mock(DisplayDeviceConfig.class), /* isEnabled= */ true);
- mHolder.dpc.onDisplayChanged(mHolder.hbmMetadata, Layout.NO_LEAD_DISPLAY);
- DisplayPowerRequest dpr = new DisplayPowerRequest();
- mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- advanceTime(1); // Run updatePowerState
- // One triggered by handleBrightnessModeChange, another triggered by onDisplayChanged
- verify(mHolder.animator, times(2)).animateTo(eq(newBrightness), anyFloat(), anyFloat(),
- eq(false));
- }
-
- @Test
- public void testShortTermModelPersistsWhenDisplayDeviceChanges() {
- float lux = 2000;
- float nits = 500;
- when(mHolder.automaticBrightnessController.getUserLux()).thenReturn(lux);
- when(mHolder.automaticBrightnessController.getUserNits()).thenReturn(nits);
- DisplayPowerRequest dpr = new DisplayPowerRequest();
- mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- advanceTime(1);
- clearInvocations(mHolder.injector);
-
- // New display device
- setUpDisplay(DISPLAY_ID, "new_unique_id", mHolder.display, mock(DisplayDevice.class),
- mock(DisplayDeviceConfig.class), /* isEnabled= */ true);
- mHolder.dpc.onDisplayChanged(mHolder.hbmMetadata, Layout.NO_LEAD_DISPLAY);
- advanceTime(1);
-
- verify(mHolder.injector).getAutomaticBrightnessController(
- any(AutomaticBrightnessController.Callbacks.class),
- any(Looper.class),
- eq(mSensorManagerMock),
- /* lightSensor= */ any(),
- /* brightnessMappingStrategyMap= */ any(SparseArray.class),
- /* lightSensorWarmUpTime= */ anyInt(),
- /* brightnessMin= */ anyFloat(),
- /* brightnessMax= */ anyFloat(),
- /* dozeScaleFactor */ anyFloat(),
- /* lightSensorRate= */ anyInt(),
- /* initialLightSensorRate= */ anyInt(),
- /* brighteningLightDebounceConfig */ anyLong(),
- /* darkeningLightDebounceConfig */ anyLong(),
- /* brighteningLightDebounceConfigIdle= */ anyLong(),
- /* darkeningLightDebounceConfigIdle= */ anyLong(),
- /* resetAmbientLuxAfterWarmUpConfig= */ anyBoolean(),
- any(HysteresisLevels.class),
- any(HysteresisLevels.class),
- any(HysteresisLevels.class),
- any(HysteresisLevels.class),
- eq(mContext),
- any(BrightnessRangeController.class),
- any(BrightnessThrottler.class),
- /* ambientLightHorizonShort= */ anyInt(),
- /* ambientLightHorizonLong= */ anyInt(),
- eq(lux),
- eq(nits)
- );
- }
-
- @Test
- public void testUpdateBrightnessThrottlingDataId() {
- mHolder.display.getDisplayInfoLocked().thermalBrightnessThrottlingDataId =
- "throttling-data-id";
- clearInvocations(mHolder.display.getPrimaryDisplayDeviceLocked().getDisplayDeviceConfig());
-
- mHolder.dpc.onDisplayChanged(mHolder.hbmMetadata, Layout.NO_LEAD_DISPLAY);
- DisplayPowerRequest dpr = new DisplayPowerRequest();
- mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- advanceTime(1); // Run updatePowerState
-
- verify(mHolder.display.getPrimaryDisplayDeviceLocked().getDisplayDeviceConfig())
- .getThermalBrightnessThrottlingDataMapByThrottlingId();
- }
-
- @Test
- public void testSetBrightness_BrightnessShouldBeClamped() {
- float clampedBrightness = 0.6f;
- when(mHolder.hbmController.getCurrentBrightnessMax()).thenReturn(clampedBrightness);
-
- mHolder.dpc.setBrightness(PowerManager.BRIGHTNESS_MAX);
-
- verify(mHolder.brightnessSetting).setBrightness(clampedBrightness);
- }
-
- @Test
- public void testDwbcCallsHappenOnHandler() {
- mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID);
-
- mHolder.dpc.setAutomaticScreenBrightnessMode(AUTO_BRIGHTNESS_MODE_IDLE);
- verify(mDisplayWhiteBalanceControllerMock, never()).setStrongModeEnabled(true);
-
- // dispatch handler looper
- advanceTime(1);
- verify(mDisplayWhiteBalanceControllerMock, times(1)).setStrongModeEnabled(true);
- }
-
- @Test
- public void testRampRatesIdle() {
- Settings.System.putInt(mContext.getContentResolver(),
- Settings.System.SCREEN_BRIGHTNESS_MODE,
- Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
- float brightness = 0.6f;
- when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON);
- when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
- when(mHolder.automaticBrightnessController.isInIdleMode()).thenReturn(true);
- when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness(
- any(BrightnessEvent.class))).thenReturn(brightness);
-
- DisplayPowerRequest dpr = new DisplayPowerRequest();
- mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- advanceTime(1); // Run updatePowerState
-
- verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
- eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
-
- when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(brightness);
- brightness = 0.05f;
- when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness(
- any(BrightnessEvent.class))).thenReturn(brightness);
-
- mHolder.dpc.updateBrightness();
- advanceTime(1); // Run updatePowerState
-
- // The second time, the animation rate should be slow
- verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
- eq(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE_IDLE), eq(false));
-
- brightness = 0.9f;
- when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness(
- any(BrightnessEvent.class))).thenReturn(brightness);
-
- mHolder.dpc.updateBrightness();
- advanceTime(1); // Run updatePowerState
- // The third time, the animation rate should be slow
- verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
- eq(BRIGHTNESS_RAMP_RATE_SLOW_INCREASE_IDLE), eq(false));
- }
-
- @Test
- @RequiresFlagsEnabled(Flags.FLAG_FAST_HDR_TRANSITIONS)
- public void testDisplayBrightnessHdr_SkipAnimationOnHdrAppearance() {
- Settings.System.putInt(mContext.getContentResolver(),
- Settings.System.SCREEN_BRIGHTNESS_MODE,
- Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
- final float sdrBrightness = 0.1f;
- final float hdrBrightness = 0.3f;
- when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON);
- when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
- when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness(
- any(BrightnessEvent.class))).thenReturn(sdrBrightness);
-
- DisplayPowerRequest dpr = new DisplayPowerRequest();
- mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- advanceTime(1); // Run updatePowerState
-
- verify(mHolder.animator).animateTo(eq(sdrBrightness), eq(sdrBrightness),
- eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
-
- when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(sdrBrightness);
- when(mHolder.displayPowerState.getSdrScreenBrightness()).thenReturn(sdrBrightness);
-
- when(mHolder.hbmController.getHighBrightnessMode()).thenReturn(
- BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR);
- when(mHolder.hbmController.getHdrBrightnessValue()).thenReturn(hdrBrightness);
- clearInvocations(mHolder.animator);
-
- mHolder.dpc.updateBrightness();
- advanceTime(1); // Run updatePowerState
-
- verify(mHolder.animator).animateTo(eq(hdrBrightness), eq(sdrBrightness),
- eq(BRIGHTNESS_RAMP_RATE_MINIMUM), eq(false));
- }
-
- @Test
- @RequiresFlagsEnabled(Flags.FLAG_FAST_HDR_TRANSITIONS)
- public void testDisplayBrightnessHdr_SkipAnimationOnHdrRemoval() {
- Settings.System.putInt(mContext.getContentResolver(),
- Settings.System.SCREEN_BRIGHTNESS_MODE,
- Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
- final float sdrBrightness = 0.1f;
- final float hdrBrightness = 0.3f;
- when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON);
- when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
- when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness(
- any(BrightnessEvent.class))).thenReturn(sdrBrightness);
-
- when(mHolder.hbmController.getHighBrightnessMode()).thenReturn(
- BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR);
- when(mHolder.hbmController.getHdrBrightnessValue()).thenReturn(hdrBrightness);
-
- DisplayPowerRequest dpr = new DisplayPowerRequest();
- mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- advanceTime(1); // Run updatePowerState
-
- verify(mHolder.animator).animateTo(eq(hdrBrightness), eq(sdrBrightness),
- eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
-
- when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(hdrBrightness);
- when(mHolder.displayPowerState.getSdrScreenBrightness()).thenReturn(sdrBrightness);
- when(mHolder.hbmController.getHighBrightnessMode()).thenReturn(
- BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF);
-
- clearInvocations(mHolder.animator);
-
- mHolder.dpc.updateBrightness();
- advanceTime(1); // Run updatePowerState
-
- verify(mHolder.animator).animateTo(eq(sdrBrightness), eq(sdrBrightness),
- eq(BRIGHTNESS_RAMP_RATE_MINIMUM), eq(false));
- }
-
- @Test
- @RequiresFlagsDisabled(Flags.FLAG_ENABLE_ADAPTIVE_TONE_IMPROVEMENTS_1)
- public void testRampMaxTimeInteractiveThenIdle() {
- // Send a display power request
- DisplayPowerRequest dpr = new DisplayPowerRequest();
- dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
- dpr.useProximitySensor = true;
- mHolder.dpc.requestPowerState(dpr, false /* waitForNegativeProximity */);
-
- // Run updatePowerState
- advanceTime(1);
-
- setUpDisplay(DISPLAY_ID, "new_unique_id", mHolder.display, mock(DisplayDevice.class),
- mHolder.config, /* isEnabled= */ true);
-
- verify(mHolder.animator).setAnimationTimeLimits(BRIGHTNESS_RAMP_INCREASE_MAX,
- BRIGHTNESS_RAMP_DECREASE_MAX);
-
- // switch to idle
- mHolder.dpc.setAutomaticScreenBrightnessMode(AUTO_BRIGHTNESS_MODE_IDLE);
- advanceTime(1);
-
- verify(mHolder.animator, times(2)).setAnimationTimeLimits(BRIGHTNESS_RAMP_INCREASE_MAX,
- BRIGHTNESS_RAMP_DECREASE_MAX);
- }
-
- @Test
- @RequiresFlagsEnabled(Flags.FLAG_ENABLE_ADAPTIVE_TONE_IMPROVEMENTS_1)
- public void testRampMaxTimeInteractiveThenIdle_DifferentValues() {
- when(mDisplayManagerFlagsMock.isAdaptiveTone1Enabled()).thenReturn(true);
- // Send a display power request
- DisplayPowerRequest dpr = new DisplayPowerRequest();
- dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
- dpr.useProximitySensor = true;
- mHolder.dpc.requestPowerState(dpr, false /* waitForNegativeProximity */);
-
- // Run updatePowerState
- advanceTime(1);
-
- setUpDisplay(DISPLAY_ID, "new_unique_id", mHolder.display, mock(DisplayDevice.class),
- mHolder.config, /* isEnabled= */ true);
-
- verify(mHolder.animator).setAnimationTimeLimits(BRIGHTNESS_RAMP_INCREASE_MAX,
- BRIGHTNESS_RAMP_DECREASE_MAX);
-
- // switch to idle
- mHolder.dpc.setAutomaticScreenBrightnessMode(AUTO_BRIGHTNESS_MODE_IDLE);
- advanceTime(1);
-
- verify(mHolder.animator).setAnimationTimeLimits(BRIGHTNESS_RAMP_INCREASE_MAX_IDLE,
- BRIGHTNESS_RAMP_DECREASE_MAX_IDLE);
- }
-
- @Test
- @RequiresFlagsDisabled(Flags.FLAG_ENABLE_ADAPTIVE_TONE_IMPROVEMENTS_1)
- public void testRampMaxTimeIdle() {
- // Send a display power request
- DisplayPowerRequest dpr = new DisplayPowerRequest();
- dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
- dpr.useProximitySensor = true;
- mHolder.dpc.requestPowerState(dpr, false /* waitForNegativeProximity */);
-
- // Run updatePowerState
- advanceTime(1);
-
- // once on setup
- verify(mHolder.animator).setAnimationTimeLimits(BRIGHTNESS_RAMP_INCREASE_MAX,
- BRIGHTNESS_RAMP_DECREASE_MAX);
-
- setUpDisplay(DISPLAY_ID, "new_unique_id", mHolder.display, mock(DisplayDevice.class),
- mHolder.config, /* isEnabled= */ true);
-
- // switch to idle mode
- mHolder.dpc.setAutomaticScreenBrightnessMode(AUTO_BRIGHTNESS_MODE_IDLE);
-
- // second time when switching to idle screen brightness mode
- verify(mHolder.animator, times(2)).setAnimationTimeLimits(BRIGHTNESS_RAMP_INCREASE_MAX,
- BRIGHTNESS_RAMP_DECREASE_MAX);
- }
-
- @Test
- @RequiresFlagsEnabled(Flags.FLAG_ENABLE_ADAPTIVE_TONE_IMPROVEMENTS_1)
- public void testRampMaxTimeIdle_DifferentValues() {
- when(mDisplayManagerFlagsMock.isAdaptiveTone1Enabled()).thenReturn(true);
-
- // Send a display power request
- DisplayPowerRequest dpr = new DisplayPowerRequest();
- dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
- dpr.useProximitySensor = true;
- mHolder.dpc.requestPowerState(dpr, false /* waitForNegativeProximity */);
-
- // Run updatePowerState
- advanceTime(1);
-
- setUpDisplay(DISPLAY_ID, "new_unique_id", mHolder.display, mock(DisplayDevice.class),
- mHolder.config, /* isEnabled= */ true);
-
- // switch to idle mode
- mHolder.dpc.setAutomaticScreenBrightnessMode(AUTO_BRIGHTNESS_MODE_IDLE);
-
- verify(mHolder.animator).setAnimationTimeLimits(BRIGHTNESS_RAMP_INCREASE_MAX_IDLE,
- BRIGHTNESS_RAMP_DECREASE_MAX_IDLE);
- }
- @Test
- public void testDozeScreenStateOverride_toSupportedOffloadStateFromDoze_DisplayStateChanges() {
- // set up.
- int initState = Display.STATE_DOZE;
- int supportedTargetState = Display.STATE_DOZE_SUSPEND;
- mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID);
- when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
- doAnswer(invocation -> {
- when(mHolder.displayPowerState.getScreenState()).thenReturn(invocation.getArgument(0));
- return null;
- }).when(mHolder.displayPowerState).setScreenState(anyInt());
- mHolder.dpc.setDisplayOffloadSession(mDisplayOffloadSession);
-
- // start with DOZE.
- when(mHolder.displayPowerState.getScreenState()).thenReturn(initState);
- DisplayPowerRequest dpr = new DisplayPowerRequest();
- dpr.policy = DisplayPowerRequest.POLICY_DOZE;
- mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- advanceTime(1); // Run updatePowerState
-
- mHolder.dpc.overrideDozeScreenState(supportedTargetState);
- advanceTime(1); // Run updatePowerState
-
- verify(mHolder.displayPowerState).setScreenState(supportedTargetState);
- }
-
- @Test
- public void testDozeScreenStateOverride_toUnSupportedOffloadStateFromDoze_stateRemains() {
- // set up.
- int initState = Display.STATE_DOZE;
- int unSupportedTargetState = Display.STATE_ON;
- mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID);
- when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
- doAnswer(invocation -> {
- when(mHolder.displayPowerState.getScreenState()).thenReturn(invocation.getArgument(0));
- return null;
- }).when(mHolder.displayPowerState).setScreenState(anyInt());
- mHolder.dpc.setDisplayOffloadSession(mDisplayOffloadSession);
-
- // start with DOZE.
- when(mHolder.displayPowerState.getScreenState()).thenReturn(initState);
- DisplayPowerRequest dpr = new DisplayPowerRequest();
- dpr.policy = DisplayPowerRequest.POLICY_DOZE;
- mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- advanceTime(1); // Run updatePowerState
-
- mHolder.dpc.overrideDozeScreenState(unSupportedTargetState);
- advanceTime(1); // Run updatePowerState
-
- verify(mHolder.displayPowerState, never()).setScreenState(anyInt());
- }
-
- @Test
- public void testDozeScreenStateOverride_toSupportedOffloadStateFromOFF_stateRemains() {
- // set up.
- int initState = Display.STATE_OFF;
- int supportedTargetState = Display.STATE_DOZE_SUSPEND;
- mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID);
- doAnswer(invocation -> {
- when(mHolder.displayPowerState.getScreenState()).thenReturn(invocation.getArgument(0));
- return null;
- }).when(mHolder.displayPowerState).setScreenState(anyInt());
- mHolder.dpc.setDisplayOffloadSession(mDisplayOffloadSession);
-
- // start with OFF.
- when(mHolder.displayPowerState.getScreenState()).thenReturn(initState);
- DisplayPowerRequest dpr = new DisplayPowerRequest();
- dpr.policy = DisplayPowerRequest.POLICY_OFF;
- mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- advanceTime(1); // Run updatePowerState
-
- mHolder.dpc.overrideDozeScreenState(supportedTargetState);
- advanceTime(1); // Run updatePowerState
-
- verify(mHolder.displayPowerState, never()).setScreenState(anyInt());
- }
-
- private void advanceTime(long timeMs) {
- mClock.fastForward(timeMs);
- mTestLooper.dispatchAll();
- }
-
- private void setUpSensors() throws Exception {
- mProxSensor = TestUtils.createSensor(Sensor.TYPE_PROXIMITY, Sensor.STRING_TYPE_PROXIMITY,
- PROX_SENSOR_MAX_RANGE);
- Sensor screenOffBrightnessSensor = TestUtils.createSensor(
- Sensor.TYPE_LIGHT, Sensor.STRING_TYPE_LIGHT);
- when(mSensorManagerMock.getSensorList(eq(Sensor.TYPE_ALL)))
- .thenReturn(List.of(mProxSensor, screenOffBrightnessSensor));
- }
-
- private SensorEventListener getSensorEventListener(Sensor sensor) {
- verify(mSensorManagerMock).registerListener(mSensorEventListenerCaptor.capture(),
- eq(sensor), eq(SensorManager.SENSOR_DELAY_NORMAL), isA(Handler.class));
- return mSensorEventListenerCaptor.getValue();
- }
-
- private void setUpDisplay(int displayId, String uniqueId, LogicalDisplay logicalDisplayMock,
- DisplayDevice displayDeviceMock, DisplayDeviceConfig displayDeviceConfigMock,
- boolean isEnabled) {
- DisplayInfo info = new DisplayInfo();
- DisplayDeviceInfo deviceInfo = new DisplayDeviceInfo();
- deviceInfo.uniqueId = uniqueId;
-
- when(logicalDisplayMock.getDisplayIdLocked()).thenReturn(displayId);
- when(logicalDisplayMock.getPrimaryDisplayDeviceLocked()).thenReturn(displayDeviceMock);
- when(logicalDisplayMock.getDisplayInfoLocked()).thenReturn(info);
- when(logicalDisplayMock.isEnabledLocked()).thenReturn(isEnabled);
- when(logicalDisplayMock.isInTransitionLocked()).thenReturn(false);
- when(displayDeviceMock.getDisplayDeviceInfoLocked()).thenReturn(deviceInfo);
- when(displayDeviceMock.getUniqueId()).thenReturn(uniqueId);
- when(displayDeviceMock.getDisplayDeviceConfig()).thenReturn(displayDeviceConfigMock);
- when(displayDeviceConfigMock.getProximitySensor()).thenReturn(
- new SensorData(Sensor.STRING_TYPE_PROXIMITY, null));
- when(displayDeviceConfigMock.getNits()).thenReturn(new float[]{2, 500});
- when(displayDeviceConfigMock.isAutoBrightnessAvailable()).thenReturn(true);
- when(displayDeviceConfigMock.getAmbientLightSensor()).thenReturn(
- new SensorData());
- when(displayDeviceConfigMock.getScreenOffBrightnessSensor()).thenReturn(
- new SensorData(Sensor.STRING_TYPE_LIGHT, null));
- when(displayDeviceConfigMock.getScreenOffBrightnessSensorValueToLux())
- .thenReturn(new int[0]);
-
- when(displayDeviceConfigMock.getBrightnessRampFastDecrease())
- .thenReturn(BRIGHTNESS_RAMP_RATE_FAST_DECREASE);
- when(displayDeviceConfigMock.getBrightnessRampFastIncrease())
- .thenReturn(BRIGHTNESS_RAMP_RATE_FAST_INCREASE);
- when(displayDeviceConfigMock.getBrightnessRampSlowDecrease())
- .thenReturn(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE);
- when(displayDeviceConfigMock.getBrightnessRampSlowIncrease())
- .thenReturn(BRIGHTNESS_RAMP_RATE_SLOW_INCREASE);
- when(displayDeviceConfigMock.getBrightnessRampSlowDecreaseIdle())
- .thenReturn(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE_IDLE);
- when(displayDeviceConfigMock.getBrightnessRampSlowIncreaseIdle())
- .thenReturn(BRIGHTNESS_RAMP_RATE_SLOW_INCREASE_IDLE);
-
- when(displayDeviceConfigMock.getBrightnessRampIncreaseMaxMillis())
- .thenReturn(BRIGHTNESS_RAMP_INCREASE_MAX);
- when(displayDeviceConfigMock.getBrightnessRampDecreaseMaxMillis())
- .thenReturn(BRIGHTNESS_RAMP_DECREASE_MAX);
- when(displayDeviceConfigMock.getBrightnessRampIncreaseMaxIdleMillis())
- .thenReturn(BRIGHTNESS_RAMP_INCREASE_MAX_IDLE);
- when(displayDeviceConfigMock.getBrightnessRampDecreaseMaxIdleMillis())
- .thenReturn(BRIGHTNESS_RAMP_DECREASE_MAX_IDLE);
- }
-
- private DisplayPowerControllerHolder createDisplayPowerController(int displayId,
- String uniqueId) {
- return createDisplayPowerController(displayId, uniqueId, /* isEnabled= */ true);
- }
-
- private DisplayPowerControllerHolder createDisplayPowerController(int displayId,
- String uniqueId, boolean isEnabled) {
- final DisplayPowerState displayPowerState = mock(DisplayPowerState.class);
- final DualRampAnimator<DisplayPowerState> animator = mock(DualRampAnimator.class);
- final AutomaticBrightnessController automaticBrightnessController =
- mock(AutomaticBrightnessController.class);
- final BrightnessMappingStrategy brightnessMappingStrategy =
- mock(BrightnessMappingStrategy.class);
- final HysteresisLevels hysteresisLevels = mock(HysteresisLevels.class);
- final ScreenOffBrightnessSensorController screenOffBrightnessSensorController =
- mock(ScreenOffBrightnessSensorController.class);
- final HighBrightnessModeController hbmController = mock(HighBrightnessModeController.class);
-
- when(hbmController.getCurrentBrightnessMax()).thenReturn(PowerManager.BRIGHTNESS_MAX);
-
- DisplayPowerController.Injector injector = spy(new TestInjector(displayPowerState, animator,
- automaticBrightnessController, brightnessMappingStrategy, hysteresisLevels,
- screenOffBrightnessSensorController, hbmController));
-
- final LogicalDisplay display = mock(LogicalDisplay.class);
- final DisplayDevice device = mock(DisplayDevice.class);
- final HighBrightnessModeMetadata hbmMetadata = mock(HighBrightnessModeMetadata.class);
- final BrightnessSetting brightnessSetting = mock(BrightnessSetting.class);
- final DisplayDeviceConfig config = mock(DisplayDeviceConfig.class);
-
- setUpDisplay(displayId, uniqueId, display, device, config, isEnabled);
-
- final DisplayPowerController dpc = new DisplayPowerController(
- mContext, injector, mDisplayPowerCallbacksMock, mHandler,
- mSensorManagerMock, mDisplayBlankerMock, display,
- mBrightnessTrackerMock, brightnessSetting, () -> {},
- hbmMetadata, /* bootCompleted= */ false, mDisplayManagerFlagsMock);
-
- return new DisplayPowerControllerHolder(dpc, display, displayPowerState, brightnessSetting,
- animator, automaticBrightnessController, screenOffBrightnessSensorController,
- hbmController, hbmMetadata, brightnessMappingStrategy, injector, config);
- }
-
- /**
- * A class for holding a DisplayPowerController under test and all the mocks specifically
- * related to it.
- */
- private static class DisplayPowerControllerHolder {
- public final DisplayPowerController dpc;
- public final LogicalDisplay display;
- public final DisplayPowerState displayPowerState;
- public final BrightnessSetting brightnessSetting;
- public final DualRampAnimator<DisplayPowerState> animator;
- public final AutomaticBrightnessController automaticBrightnessController;
- public final ScreenOffBrightnessSensorController screenOffBrightnessSensorController;
- public final HighBrightnessModeController hbmController;
- public final HighBrightnessModeMetadata hbmMetadata;
- public final BrightnessMappingStrategy brightnessMappingStrategy;
- public final DisplayPowerController.Injector injector;
- public final DisplayDeviceConfig config;
-
- DisplayPowerControllerHolder(DisplayPowerController dpc, LogicalDisplay display,
- DisplayPowerState displayPowerState, BrightnessSetting brightnessSetting,
- DualRampAnimator<DisplayPowerState> animator,
- AutomaticBrightnessController automaticBrightnessController,
- ScreenOffBrightnessSensorController screenOffBrightnessSensorController,
- HighBrightnessModeController hbmController,
- HighBrightnessModeMetadata hbmMetadata,
- BrightnessMappingStrategy brightnessMappingStrategy,
- DisplayPowerController.Injector injector,
- DisplayDeviceConfig config) {
- this.dpc = dpc;
- this.display = display;
- this.displayPowerState = displayPowerState;
- this.brightnessSetting = brightnessSetting;
- this.animator = animator;
- this.automaticBrightnessController = automaticBrightnessController;
- this.screenOffBrightnessSensorController = screenOffBrightnessSensorController;
- this.hbmController = hbmController;
- this.hbmMetadata = hbmMetadata;
- this.brightnessMappingStrategy = brightnessMappingStrategy;
- this.injector = injector;
- this.config = config;
- }
- }
-
- private class TestInjector extends DisplayPowerController.Injector {
- private final DisplayPowerState mDisplayPowerState;
- private final DualRampAnimator<DisplayPowerState> mAnimator;
- private final AutomaticBrightnessController mAutomaticBrightnessController;
- private final BrightnessMappingStrategy mBrightnessMappingStrategy;
- private final HysteresisLevels mHysteresisLevels;
- private final ScreenOffBrightnessSensorController mScreenOffBrightnessSensorController;
- private final HighBrightnessModeController mHighBrightnessModeController;
-
- TestInjector(DisplayPowerState dps, DualRampAnimator<DisplayPowerState> animator,
- AutomaticBrightnessController automaticBrightnessController,
- BrightnessMappingStrategy brightnessMappingStrategy,
- HysteresisLevels hysteresisLevels,
- ScreenOffBrightnessSensorController screenOffBrightnessSensorController,
- HighBrightnessModeController highBrightnessModeController) {
- mDisplayPowerState = dps;
- mAnimator = animator;
- mAutomaticBrightnessController = automaticBrightnessController;
- mBrightnessMappingStrategy = brightnessMappingStrategy;
- mHysteresisLevels = hysteresisLevels;
- mScreenOffBrightnessSensorController = screenOffBrightnessSensorController;
- mHighBrightnessModeController = highBrightnessModeController;
- }
-
- @Override
- DisplayPowerController.Clock getClock() {
- return mClock::now;
- }
-
- @Override
- DisplayPowerState getDisplayPowerState(DisplayBlanker blanker, ColorFade colorFade,
- int displayId, int displayState) {
- return mDisplayPowerState;
- }
-
- @Override
- DualRampAnimator<DisplayPowerState> getDualRampAnimator(DisplayPowerState dps,
- FloatProperty<DisplayPowerState> firstProperty,
- FloatProperty<DisplayPowerState> secondProperty) {
- return mAnimator;
- }
-
- @Override
- AutomaticBrightnessController getAutomaticBrightnessController(
- AutomaticBrightnessController.Callbacks callbacks, Looper looper,
- SensorManager sensorManager, Sensor lightSensor,
- SparseArray<BrightnessMappingStrategy> brightnessMappingStrategyMap,
- int lightSensorWarmUpTime, float brightnessMin, float brightnessMax,
- float dozeScaleFactor, int lightSensorRate, int initialLightSensorRate,
- long brighteningLightDebounceConfig, long darkeningLightDebounceConfig,
- long brighteningLightDebounceConfigIdle, long darkeningLightDebounceConfigIdle,
- boolean resetAmbientLuxAfterWarmUpConfig,
- HysteresisLevels ambientBrightnessThresholds,
- HysteresisLevels screenBrightnessThresholds,
- HysteresisLevels ambientBrightnessThresholdsIdle,
- HysteresisLevels screenBrightnessThresholdsIdle, Context context,
- BrightnessRangeController brightnessRangeController,
- BrightnessThrottler brightnessThrottler, int ambientLightHorizonShort,
- int ambientLightHorizonLong, float userLux, float userNits) {
- return mAutomaticBrightnessController;
- }
-
- @Override
- BrightnessMappingStrategy getDefaultModeBrightnessMapper(Context context,
- DisplayDeviceConfig displayDeviceConfig,
- DisplayWhiteBalanceController displayWhiteBalanceController) {
- return mBrightnessMappingStrategy;
- }
-
- @Override
- HysteresisLevels getHysteresisLevels(float[] brighteningThresholdsPercentages,
- float[] darkeningThresholdsPercentages, float[] brighteningThresholdLevels,
- float[] darkeningThresholdLevels, float minDarkeningThreshold,
- float minBrighteningThreshold) {
- return mHysteresisLevels;
- }
-
- @Override
- HysteresisLevels getHysteresisLevels(float[] brighteningThresholdsPercentages,
- float[] darkeningThresholdsPercentages, float[] brighteningThresholdLevels,
- float[] darkeningThresholdLevels, float minDarkeningThreshold,
- float minBrighteningThreshold, boolean potentialOldBrightnessRange) {
- return mHysteresisLevels;
- }
-
- @Override
- ScreenOffBrightnessSensorController getScreenOffBrightnessSensorController(
- SensorManager sensorManager, Sensor lightSensor, Handler handler,
- ScreenOffBrightnessSensorController.Clock clock, int[] sensorValueToLux,
- BrightnessMappingStrategy brightnessMapper) {
- return mScreenOffBrightnessSensorController;
- }
-
- @Override
- HighBrightnessModeController getHighBrightnessModeController(Handler handler, int width,
- int height, IBinder displayToken, String displayUniqueId, float brightnessMin,
- float brightnessMax, DisplayDeviceConfig.HighBrightnessModeData hbmData,
- HighBrightnessModeController.HdrBrightnessDeviceConfig hdrBrightnessCfg,
- Runnable hbmChangeCallback, HighBrightnessModeMetadata hbmMetadata,
- Context context) {
- return mHighBrightnessModeController;
- }
-
- @Override
- DisplayWhiteBalanceController getDisplayWhiteBalanceController(Handler handler,
- SensorManager sensorManager, Resources resources) {
- return mDisplayWhiteBalanceControllerMock;
- }
- }
-}