Loading services/core/java/com/android/server/display/DisplayManagerService.java +60 −4 Original line number Original line Diff line number Diff line Loading @@ -108,6 +108,7 @@ import android.os.UserManager; import android.provider.DeviceConfig; import android.provider.DeviceConfig; import android.provider.Settings; import android.provider.Settings; import android.text.TextUtils; import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; import android.util.ArraySet; import android.util.EventLog; import android.util.EventLog; import android.util.IntArray; import android.util.IntArray; Loading Loading @@ -259,6 +260,13 @@ public final class DisplayManagerService extends SystemService { final SparseArray<Pair<IVirtualDevice, DisplayWindowPolicyController>> final SparseArray<Pair<IVirtualDevice, DisplayWindowPolicyController>> mDisplayWindowPolicyControllers = new SparseArray<>(); mDisplayWindowPolicyControllers = new SparseArray<>(); /** * Map of every internal primary display device {@link HighBrightnessModeMetadata}s indexed by * {@link DisplayDevice#mUniqueId}. */ public final ArrayMap<String, HighBrightnessModeMetadata> mHighBrightnessModeMetadataMap = new ArrayMap<>(); // List of all currently registered display adapters. // List of all currently registered display adapters. private final ArrayList<DisplayAdapter> mDisplayAdapters = new ArrayList<DisplayAdapter>(); private final ArrayList<DisplayAdapter> mDisplayAdapters = new ArrayList<DisplayAdapter>(); Loading Loading @@ -1634,7 +1642,16 @@ public final class DisplayManagerService extends SystemService { DisplayPowerControllerInterface dpc = mDisplayPowerControllers.get(displayId); DisplayPowerControllerInterface dpc = mDisplayPowerControllers.get(displayId); if (dpc != null) { if (dpc != null) { dpc.onDisplayChanged(); final DisplayDevice device = display.getPrimaryDisplayDeviceLocked(); if (device == null) { Slog.wtf(TAG, "Display Device is null in DisplayManagerService for display: " + display.getDisplayIdLocked()); return; } final String uniqueId = device.getUniqueId(); HighBrightnessModeMetadata hbmMetadata = mHighBrightnessModeMetadataMap.get(uniqueId); dpc.onDisplayChanged(hbmMetadata); } } } } Loading Loading @@ -1692,7 +1709,15 @@ public final class DisplayManagerService extends SystemService { final int displayId = display.getDisplayIdLocked(); final int displayId = display.getDisplayIdLocked(); final DisplayPowerControllerInterface dpc = mDisplayPowerControllers.get(displayId); final DisplayPowerControllerInterface dpc = mDisplayPowerControllers.get(displayId); if (dpc != null) { if (dpc != null) { dpc.onDisplayChanged(); final DisplayDevice device = display.getPrimaryDisplayDeviceLocked(); if (device == null) { Slog.wtf(TAG, "Display Device is null in DisplayManagerService for display: " + display.getDisplayIdLocked()); return; } final String uniqueId = device.getUniqueId(); HighBrightnessModeMetadata hbmMetadata = mHighBrightnessModeMetadataMap.get(uniqueId); dpc.onDisplayChanged(hbmMetadata); } } } } Loading Loading @@ -2645,6 +2670,31 @@ public final class DisplayManagerService extends SystemService { mLogicalDisplayMapper.forEachLocked(this::addDisplayPowerControllerLocked); mLogicalDisplayMapper.forEachLocked(this::addDisplayPowerControllerLocked); } } private HighBrightnessModeMetadata getHighBrightnessModeMetadata(LogicalDisplay display) { final DisplayDevice device = display.getPrimaryDisplayDeviceLocked(); if (device == null) { Slog.wtf(TAG, "Display Device is null in DisplayPowerController for display: " + display.getDisplayIdLocked()); return null; } // HBM brightness mode is only applicable to internal physical displays. if (display.getDisplayInfoLocked().type != Display.TYPE_INTERNAL) { return null; } final String uniqueId = device.getUniqueId(); if (mHighBrightnessModeMetadataMap.containsKey(uniqueId)) { return mHighBrightnessModeMetadataMap.get(uniqueId); } // HBM Time info not present. Create a new one for this physical display. HighBrightnessModeMetadata hbmInfo = new HighBrightnessModeMetadata(); mHighBrightnessModeMetadataMap.put(uniqueId, hbmInfo); return hbmInfo; } @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG) @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG) private void addDisplayPowerControllerLocked(LogicalDisplay display) { private void addDisplayPowerControllerLocked(LogicalDisplay display) { if (mPowerHandler == null) { if (mPowerHandler == null) { Loading @@ -2660,17 +2710,23 @@ public final class DisplayManagerService extends SystemService { display, mSyncRoot); display, mSyncRoot); final DisplayPowerControllerInterface displayPowerController; final DisplayPowerControllerInterface displayPowerController; // If display is internal and has a HighBrightnessModeMetadata mapping, use that. // Or create a new one and use that. // We also need to pass a mapping of the HighBrightnessModeTimeInfoMap to // displayPowerController, so the hbm info can be correctly associated // with the corresponding displaydevice. HighBrightnessModeMetadata hbmMetadata = getHighBrightnessModeMetadata(display); if (DeviceConfig.getBoolean("display_manager", if (DeviceConfig.getBoolean("display_manager", "use_newly_structured_display_power_controller", true)) { "use_newly_structured_display_power_controller", true)) { displayPowerController = new DisplayPowerController2( displayPowerController = new DisplayPowerController2( mContext, /* injector= */ null, mDisplayPowerCallbacks, mPowerHandler, mContext, /* injector= */ null, mDisplayPowerCallbacks, mPowerHandler, mSensorManager, mDisplayBlanker, display, mBrightnessTracker, brightnessSetting, mSensorManager, mDisplayBlanker, display, mBrightnessTracker, brightnessSetting, () -> handleBrightnessChange(display)); () -> handleBrightnessChange(display), hbmMetadata); } else { } else { displayPowerController = new DisplayPowerController( displayPowerController = new DisplayPowerController( mContext, /* injector= */ null, mDisplayPowerCallbacks, mPowerHandler, mContext, /* injector= */ null, mDisplayPowerCallbacks, mPowerHandler, mSensorManager, mDisplayBlanker, display, mBrightnessTracker, brightnessSetting, mSensorManager, mDisplayBlanker, display, mBrightnessTracker, brightnessSetting, () -> handleBrightnessChange(display)); () -> handleBrightnessChange(display), hbmMetadata); } } mDisplayPowerControllers.append(display.getDisplayIdLocked(), displayPowerController); mDisplayPowerControllers.append(display.getDisplayIdLocked(), displayPowerController); } } Loading services/core/java/com/android/server/display/DisplayPowerController.java +9 −5 Original line number Original line Diff line number Diff line Loading @@ -388,6 +388,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call private float[] mNitsRange; private float[] mNitsRange; private final HighBrightnessModeController mHbmController; private final HighBrightnessModeController mHbmController; private final HighBrightnessModeMetadata mHighBrightnessModeMetadata; private final BrightnessThrottler mBrightnessThrottler; private final BrightnessThrottler mBrightnessThrottler; Loading Loading @@ -505,13 +506,14 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call DisplayPowerCallbacks callbacks, Handler handler, DisplayPowerCallbacks callbacks, Handler handler, SensorManager sensorManager, DisplayBlanker blanker, LogicalDisplay logicalDisplay, SensorManager sensorManager, DisplayBlanker blanker, LogicalDisplay logicalDisplay, BrightnessTracker brightnessTracker, BrightnessSetting brightnessSetting, BrightnessTracker brightnessTracker, BrightnessSetting brightnessSetting, Runnable onBrightnessChangeRunnable) { Runnable onBrightnessChangeRunnable, HighBrightnessModeMetadata hbmMetadata) { mInjector = injector != null ? injector : new Injector(); mInjector = injector != null ? injector : new Injector(); mClock = mInjector.getClock(); mClock = mInjector.getClock(); mLogicalDisplay = logicalDisplay; mLogicalDisplay = logicalDisplay; mDisplayId = mLogicalDisplay.getDisplayIdLocked(); mDisplayId = mLogicalDisplay.getDisplayIdLocked(); mTag = "DisplayPowerController[" + mDisplayId + "]"; mTag = "DisplayPowerController[" + mDisplayId + "]"; mHighBrightnessModeMetadata = hbmMetadata; mSuspendBlockerIdUnfinishedBusiness = getSuspendBlockerUnfinishedBusinessId(mDisplayId); mSuspendBlockerIdUnfinishedBusiness = getSuspendBlockerUnfinishedBusinessId(mDisplayId); mSuspendBlockerIdOnStateChanged = getSuspendBlockerOnStateChangedId(mDisplayId); mSuspendBlockerIdOnStateChanged = getSuspendBlockerOnStateChangedId(mDisplayId); mSuspendBlockerIdProxPositive = getSuspendBlockerProxPositiveId(mDisplayId); mSuspendBlockerIdProxPositive = getSuspendBlockerProxPositiveId(mDisplayId); Loading Loading @@ -790,7 +792,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call * Make sure DisplayManagerService.mSyncRoot is held when this is called * Make sure DisplayManagerService.mSyncRoot is held when this is called */ */ @Override @Override public void onDisplayChanged() { public void onDisplayChanged(HighBrightnessModeMetadata hbmMetadata) { final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked(); final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked(); if (device == null) { if (device == null) { Slog.wtf(mTag, "Display Device is null in DisplayPowerController for display: " Slog.wtf(mTag, "Display Device is null in DisplayPowerController for display: " Loading @@ -812,7 +814,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mUniqueDisplayId = uniqueId; mUniqueDisplayId = uniqueId; mDisplayStatsId = mUniqueDisplayId.hashCode(); mDisplayStatsId = mUniqueDisplayId.hashCode(); mDisplayDeviceConfig = config; mDisplayDeviceConfig = config; loadFromDisplayDeviceConfig(token, info); loadFromDisplayDeviceConfig(token, info, hbmMetadata); // Since the underlying display-device changed, we really don't know the // Since the underlying display-device changed, we really don't know the // last command that was sent to change it's state. Lets assume it is off and we // last command that was sent to change it's state. Lets assume it is off and we Loading Loading @@ -864,7 +866,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } } } } private void loadFromDisplayDeviceConfig(IBinder token, DisplayDeviceInfo info) { private void loadFromDisplayDeviceConfig(IBinder token, DisplayDeviceInfo info, HighBrightnessModeMetadata hbmMetadata) { // All properties that depend on the associated DisplayDevice and the DDC must be // All properties that depend on the associated DisplayDevice and the DDC must be // updated here. // updated here. loadBrightnessRampRates(); loadBrightnessRampRates(); Loading @@ -877,6 +880,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mBrightnessRampIncreaseMaxTimeMillis, mBrightnessRampIncreaseMaxTimeMillis, mBrightnessRampDecreaseMaxTimeMillis); mBrightnessRampDecreaseMaxTimeMillis); } } mHbmController.setHighBrightnessModeMetadata(hbmMetadata); mHbmController.resetHbmData(info.width, info.height, token, info.uniqueId, mHbmController.resetHbmData(info.width, info.height, token, info.uniqueId, mDisplayDeviceConfig.getHighBrightnessModeData(), mDisplayDeviceConfig.getHighBrightnessModeData(), new HighBrightnessModeController.HdrBrightnessDeviceConfig() { new HighBrightnessModeController.HdrBrightnessDeviceConfig() { Loading Loading @@ -1961,7 +1965,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call if (mAutomaticBrightnessController != null) { if (mAutomaticBrightnessController != null) { mAutomaticBrightnessController.update(); mAutomaticBrightnessController.update(); } } }, mContext); }, mHighBrightnessModeMetadata, mContext); } } private BrightnessThrottler createBrightnessThrottlerLocked() { private BrightnessThrottler createBrightnessThrottlerLocked() { Loading services/core/java/com/android/server/display/DisplayPowerController2.java +10 −5 Original line number Original line Diff line number Diff line Loading @@ -328,6 +328,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal private float[] mNitsRange; private float[] mNitsRange; private final HighBrightnessModeController mHbmController; private final HighBrightnessModeController mHbmController; private final HighBrightnessModeMetadata mHighBrightnessModeMetadata; private final BrightnessThrottler mBrightnessThrottler; private final BrightnessThrottler mBrightnessThrottler; Loading Loading @@ -432,7 +433,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal DisplayPowerCallbacks callbacks, Handler handler, DisplayPowerCallbacks callbacks, Handler handler, SensorManager sensorManager, DisplayBlanker blanker, LogicalDisplay logicalDisplay, SensorManager sensorManager, DisplayBlanker blanker, LogicalDisplay logicalDisplay, BrightnessTracker brightnessTracker, BrightnessSetting brightnessSetting, BrightnessTracker brightnessTracker, BrightnessSetting brightnessSetting, Runnable onBrightnessChangeRunnable) { Runnable onBrightnessChangeRunnable, HighBrightnessModeMetadata hbmMetadata) { mInjector = injector != null ? injector : new Injector(); mInjector = injector != null ? injector : new Injector(); mClock = mInjector.getClock(); mClock = mInjector.getClock(); Loading @@ -448,6 +449,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal mDisplayPowerProximityStateController = mInjector.getDisplayPowerProximityStateController( mDisplayPowerProximityStateController = mInjector.getDisplayPowerProximityStateController( mWakelockController, mDisplayDeviceConfig, mHandler.getLooper(), mWakelockController, mDisplayDeviceConfig, mHandler.getLooper(), () -> updatePowerState(), mDisplayId, mSensorManager); () -> updatePowerState(), mDisplayId, mSensorManager); mHighBrightnessModeMetadata = hbmMetadata; mDisplayStateController = new DisplayStateController(mDisplayPowerProximityStateController); mDisplayStateController = new DisplayStateController(mDisplayPowerProximityStateController); mTag = "DisplayPowerController2[" + mDisplayId + "]"; mTag = "DisplayPowerController2[" + mDisplayId + "]"; Loading Loading @@ -707,7 +709,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal * Make sure DisplayManagerService.mSyncRoot lock is held when this is called * Make sure DisplayManagerService.mSyncRoot lock is held when this is called */ */ @Override @Override public void onDisplayChanged() { public void onDisplayChanged(HighBrightnessModeMetadata hbmMetadata) { final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked(); final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked(); if (device == null) { if (device == null) { Slog.wtf(mTag, "Display Device is null in DisplayPowerController2 for display: " Slog.wtf(mTag, "Display Device is null in DisplayPowerController2 for display: " Loading @@ -721,6 +723,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); final boolean isEnabled = mLogicalDisplay.isEnabledLocked(); final boolean isEnabled = mLogicalDisplay.isEnabledLocked(); final boolean isInTransition = mLogicalDisplay.isInTransitionLocked(); final boolean isInTransition = mLogicalDisplay.isInTransitionLocked(); mHandler.post(() -> { mHandler.post(() -> { boolean changed = false; boolean changed = false; if (mDisplayDevice != device) { if (mDisplayDevice != device) { Loading @@ -729,7 +732,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal mUniqueDisplayId = uniqueId; mUniqueDisplayId = uniqueId; mDisplayStatsId = mUniqueDisplayId.hashCode(); mDisplayStatsId = mUniqueDisplayId.hashCode(); mDisplayDeviceConfig = config; mDisplayDeviceConfig = config; loadFromDisplayDeviceConfig(token, info); loadFromDisplayDeviceConfig(token, info, hbmMetadata); mDisplayPowerProximityStateController.notifyDisplayDeviceChanged(config); mDisplayPowerProximityStateController.notifyDisplayDeviceChanged(config); // Since the underlying display-device changed, we really don't know the // Since the underlying display-device changed, we really don't know the Loading Loading @@ -778,7 +781,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal } } } } private void loadFromDisplayDeviceConfig(IBinder token, DisplayDeviceInfo info) { private void loadFromDisplayDeviceConfig(IBinder token, DisplayDeviceInfo info, HighBrightnessModeMetadata hbmMetadata) { // All properties that depend on the associated DisplayDevice and the DDC must be // All properties that depend on the associated DisplayDevice and the DDC must be // updated here. // updated here. loadBrightnessRampRates(); loadBrightnessRampRates(); Loading @@ -790,6 +794,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal mBrightnessRampIncreaseMaxTimeMillis, mBrightnessRampIncreaseMaxTimeMillis, mBrightnessRampDecreaseMaxTimeMillis); mBrightnessRampDecreaseMaxTimeMillis); } } mHbmController.setHighBrightnessModeMetadata(hbmMetadata); mHbmController.resetHbmData(info.width, info.height, token, info.uniqueId, mHbmController.resetHbmData(info.width, info.height, token, info.uniqueId, mDisplayDeviceConfig.getHighBrightnessModeData(), mDisplayDeviceConfig.getHighBrightnessModeData(), new HighBrightnessModeController.HdrBrightnessDeviceConfig() { new HighBrightnessModeController.HdrBrightnessDeviceConfig() { Loading Loading @@ -1740,7 +1745,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal if (mAutomaticBrightnessController != null) { if (mAutomaticBrightnessController != null) { mAutomaticBrightnessController.update(); mAutomaticBrightnessController.update(); } } }, mContext); }, mHighBrightnessModeMetadata, mContext); } } private BrightnessThrottler createBrightnessThrottlerLocked() { private BrightnessThrottler createBrightnessThrottlerLocked() { Loading services/core/java/com/android/server/display/DisplayPowerControllerInterface.java +6 −2 Original line number Original line Diff line number Diff line Loading @@ -31,10 +31,14 @@ import java.io.PrintWriter; public interface DisplayPowerControllerInterface { public interface DisplayPowerControllerInterface { /** /** * Notified when the display is changed. We use this to apply any changes that might be needed * Notified when the display is changed. * We use this to apply any changes that might be needed * when displays get swapped on foldable devices. * when displays get swapped on foldable devices. * We also pass the High brightness mode metadata like * remaining time and hbm events for the corresponding * physical display, to update the values correctly. */ */ void onDisplayChanged(); void onDisplayChanged(HighBrightnessModeMetadata hbmInfo); /** /** * Unregisters all listeners and interrupts all running threads; halting future work. * Unregisters all listeners and interrupts all running threads; halting future work. Loading services/core/java/com/android/server/display/HbmEvent.java 0 → 100644 +46 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2023 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; /** * Represents an event in which High Brightness Mode was enabled. */ class HbmEvent { private long mStartTimeMillis; private long mEndTimeMillis; HbmEvent(long startTimeMillis, long endTimeMillis) { this.mStartTimeMillis = startTimeMillis; this.mEndTimeMillis = endTimeMillis; } public long getStartTimeMillis() { return mStartTimeMillis; } public long getEndTimeMillis() { return mEndTimeMillis; } @Override public String toString() { return "HbmEvent: {startTimeMillis:" + mStartTimeMillis + ", endTimeMillis: " + mEndTimeMillis + "}, total: " + ((mEndTimeMillis - mStartTimeMillis) / 1000) + "]"; } } Loading
services/core/java/com/android/server/display/DisplayManagerService.java +60 −4 Original line number Original line Diff line number Diff line Loading @@ -108,6 +108,7 @@ import android.os.UserManager; import android.provider.DeviceConfig; import android.provider.DeviceConfig; import android.provider.Settings; import android.provider.Settings; import android.text.TextUtils; import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; import android.util.ArraySet; import android.util.EventLog; import android.util.EventLog; import android.util.IntArray; import android.util.IntArray; Loading Loading @@ -259,6 +260,13 @@ public final class DisplayManagerService extends SystemService { final SparseArray<Pair<IVirtualDevice, DisplayWindowPolicyController>> final SparseArray<Pair<IVirtualDevice, DisplayWindowPolicyController>> mDisplayWindowPolicyControllers = new SparseArray<>(); mDisplayWindowPolicyControllers = new SparseArray<>(); /** * Map of every internal primary display device {@link HighBrightnessModeMetadata}s indexed by * {@link DisplayDevice#mUniqueId}. */ public final ArrayMap<String, HighBrightnessModeMetadata> mHighBrightnessModeMetadataMap = new ArrayMap<>(); // List of all currently registered display adapters. // List of all currently registered display adapters. private final ArrayList<DisplayAdapter> mDisplayAdapters = new ArrayList<DisplayAdapter>(); private final ArrayList<DisplayAdapter> mDisplayAdapters = new ArrayList<DisplayAdapter>(); Loading Loading @@ -1634,7 +1642,16 @@ public final class DisplayManagerService extends SystemService { DisplayPowerControllerInterface dpc = mDisplayPowerControllers.get(displayId); DisplayPowerControllerInterface dpc = mDisplayPowerControllers.get(displayId); if (dpc != null) { if (dpc != null) { dpc.onDisplayChanged(); final DisplayDevice device = display.getPrimaryDisplayDeviceLocked(); if (device == null) { Slog.wtf(TAG, "Display Device is null in DisplayManagerService for display: " + display.getDisplayIdLocked()); return; } final String uniqueId = device.getUniqueId(); HighBrightnessModeMetadata hbmMetadata = mHighBrightnessModeMetadataMap.get(uniqueId); dpc.onDisplayChanged(hbmMetadata); } } } } Loading Loading @@ -1692,7 +1709,15 @@ public final class DisplayManagerService extends SystemService { final int displayId = display.getDisplayIdLocked(); final int displayId = display.getDisplayIdLocked(); final DisplayPowerControllerInterface dpc = mDisplayPowerControllers.get(displayId); final DisplayPowerControllerInterface dpc = mDisplayPowerControllers.get(displayId); if (dpc != null) { if (dpc != null) { dpc.onDisplayChanged(); final DisplayDevice device = display.getPrimaryDisplayDeviceLocked(); if (device == null) { Slog.wtf(TAG, "Display Device is null in DisplayManagerService for display: " + display.getDisplayIdLocked()); return; } final String uniqueId = device.getUniqueId(); HighBrightnessModeMetadata hbmMetadata = mHighBrightnessModeMetadataMap.get(uniqueId); dpc.onDisplayChanged(hbmMetadata); } } } } Loading Loading @@ -2645,6 +2670,31 @@ public final class DisplayManagerService extends SystemService { mLogicalDisplayMapper.forEachLocked(this::addDisplayPowerControllerLocked); mLogicalDisplayMapper.forEachLocked(this::addDisplayPowerControllerLocked); } } private HighBrightnessModeMetadata getHighBrightnessModeMetadata(LogicalDisplay display) { final DisplayDevice device = display.getPrimaryDisplayDeviceLocked(); if (device == null) { Slog.wtf(TAG, "Display Device is null in DisplayPowerController for display: " + display.getDisplayIdLocked()); return null; } // HBM brightness mode is only applicable to internal physical displays. if (display.getDisplayInfoLocked().type != Display.TYPE_INTERNAL) { return null; } final String uniqueId = device.getUniqueId(); if (mHighBrightnessModeMetadataMap.containsKey(uniqueId)) { return mHighBrightnessModeMetadataMap.get(uniqueId); } // HBM Time info not present. Create a new one for this physical display. HighBrightnessModeMetadata hbmInfo = new HighBrightnessModeMetadata(); mHighBrightnessModeMetadataMap.put(uniqueId, hbmInfo); return hbmInfo; } @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG) @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG) private void addDisplayPowerControllerLocked(LogicalDisplay display) { private void addDisplayPowerControllerLocked(LogicalDisplay display) { if (mPowerHandler == null) { if (mPowerHandler == null) { Loading @@ -2660,17 +2710,23 @@ public final class DisplayManagerService extends SystemService { display, mSyncRoot); display, mSyncRoot); final DisplayPowerControllerInterface displayPowerController; final DisplayPowerControllerInterface displayPowerController; // If display is internal and has a HighBrightnessModeMetadata mapping, use that. // Or create a new one and use that. // We also need to pass a mapping of the HighBrightnessModeTimeInfoMap to // displayPowerController, so the hbm info can be correctly associated // with the corresponding displaydevice. HighBrightnessModeMetadata hbmMetadata = getHighBrightnessModeMetadata(display); if (DeviceConfig.getBoolean("display_manager", if (DeviceConfig.getBoolean("display_manager", "use_newly_structured_display_power_controller", true)) { "use_newly_structured_display_power_controller", true)) { displayPowerController = new DisplayPowerController2( displayPowerController = new DisplayPowerController2( mContext, /* injector= */ null, mDisplayPowerCallbacks, mPowerHandler, mContext, /* injector= */ null, mDisplayPowerCallbacks, mPowerHandler, mSensorManager, mDisplayBlanker, display, mBrightnessTracker, brightnessSetting, mSensorManager, mDisplayBlanker, display, mBrightnessTracker, brightnessSetting, () -> handleBrightnessChange(display)); () -> handleBrightnessChange(display), hbmMetadata); } else { } else { displayPowerController = new DisplayPowerController( displayPowerController = new DisplayPowerController( mContext, /* injector= */ null, mDisplayPowerCallbacks, mPowerHandler, mContext, /* injector= */ null, mDisplayPowerCallbacks, mPowerHandler, mSensorManager, mDisplayBlanker, display, mBrightnessTracker, brightnessSetting, mSensorManager, mDisplayBlanker, display, mBrightnessTracker, brightnessSetting, () -> handleBrightnessChange(display)); () -> handleBrightnessChange(display), hbmMetadata); } } mDisplayPowerControllers.append(display.getDisplayIdLocked(), displayPowerController); mDisplayPowerControllers.append(display.getDisplayIdLocked(), displayPowerController); } } Loading
services/core/java/com/android/server/display/DisplayPowerController.java +9 −5 Original line number Original line Diff line number Diff line Loading @@ -388,6 +388,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call private float[] mNitsRange; private float[] mNitsRange; private final HighBrightnessModeController mHbmController; private final HighBrightnessModeController mHbmController; private final HighBrightnessModeMetadata mHighBrightnessModeMetadata; private final BrightnessThrottler mBrightnessThrottler; private final BrightnessThrottler mBrightnessThrottler; Loading Loading @@ -505,13 +506,14 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call DisplayPowerCallbacks callbacks, Handler handler, DisplayPowerCallbacks callbacks, Handler handler, SensorManager sensorManager, DisplayBlanker blanker, LogicalDisplay logicalDisplay, SensorManager sensorManager, DisplayBlanker blanker, LogicalDisplay logicalDisplay, BrightnessTracker brightnessTracker, BrightnessSetting brightnessSetting, BrightnessTracker brightnessTracker, BrightnessSetting brightnessSetting, Runnable onBrightnessChangeRunnable) { Runnable onBrightnessChangeRunnable, HighBrightnessModeMetadata hbmMetadata) { mInjector = injector != null ? injector : new Injector(); mInjector = injector != null ? injector : new Injector(); mClock = mInjector.getClock(); mClock = mInjector.getClock(); mLogicalDisplay = logicalDisplay; mLogicalDisplay = logicalDisplay; mDisplayId = mLogicalDisplay.getDisplayIdLocked(); mDisplayId = mLogicalDisplay.getDisplayIdLocked(); mTag = "DisplayPowerController[" + mDisplayId + "]"; mTag = "DisplayPowerController[" + mDisplayId + "]"; mHighBrightnessModeMetadata = hbmMetadata; mSuspendBlockerIdUnfinishedBusiness = getSuspendBlockerUnfinishedBusinessId(mDisplayId); mSuspendBlockerIdUnfinishedBusiness = getSuspendBlockerUnfinishedBusinessId(mDisplayId); mSuspendBlockerIdOnStateChanged = getSuspendBlockerOnStateChangedId(mDisplayId); mSuspendBlockerIdOnStateChanged = getSuspendBlockerOnStateChangedId(mDisplayId); mSuspendBlockerIdProxPositive = getSuspendBlockerProxPositiveId(mDisplayId); mSuspendBlockerIdProxPositive = getSuspendBlockerProxPositiveId(mDisplayId); Loading Loading @@ -790,7 +792,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call * Make sure DisplayManagerService.mSyncRoot is held when this is called * Make sure DisplayManagerService.mSyncRoot is held when this is called */ */ @Override @Override public void onDisplayChanged() { public void onDisplayChanged(HighBrightnessModeMetadata hbmMetadata) { final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked(); final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked(); if (device == null) { if (device == null) { Slog.wtf(mTag, "Display Device is null in DisplayPowerController for display: " Slog.wtf(mTag, "Display Device is null in DisplayPowerController for display: " Loading @@ -812,7 +814,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mUniqueDisplayId = uniqueId; mUniqueDisplayId = uniqueId; mDisplayStatsId = mUniqueDisplayId.hashCode(); mDisplayStatsId = mUniqueDisplayId.hashCode(); mDisplayDeviceConfig = config; mDisplayDeviceConfig = config; loadFromDisplayDeviceConfig(token, info); loadFromDisplayDeviceConfig(token, info, hbmMetadata); // Since the underlying display-device changed, we really don't know the // Since the underlying display-device changed, we really don't know the // last command that was sent to change it's state. Lets assume it is off and we // last command that was sent to change it's state. Lets assume it is off and we Loading Loading @@ -864,7 +866,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } } } } private void loadFromDisplayDeviceConfig(IBinder token, DisplayDeviceInfo info) { private void loadFromDisplayDeviceConfig(IBinder token, DisplayDeviceInfo info, HighBrightnessModeMetadata hbmMetadata) { // All properties that depend on the associated DisplayDevice and the DDC must be // All properties that depend on the associated DisplayDevice and the DDC must be // updated here. // updated here. loadBrightnessRampRates(); loadBrightnessRampRates(); Loading @@ -877,6 +880,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mBrightnessRampIncreaseMaxTimeMillis, mBrightnessRampIncreaseMaxTimeMillis, mBrightnessRampDecreaseMaxTimeMillis); mBrightnessRampDecreaseMaxTimeMillis); } } mHbmController.setHighBrightnessModeMetadata(hbmMetadata); mHbmController.resetHbmData(info.width, info.height, token, info.uniqueId, mHbmController.resetHbmData(info.width, info.height, token, info.uniqueId, mDisplayDeviceConfig.getHighBrightnessModeData(), mDisplayDeviceConfig.getHighBrightnessModeData(), new HighBrightnessModeController.HdrBrightnessDeviceConfig() { new HighBrightnessModeController.HdrBrightnessDeviceConfig() { Loading Loading @@ -1961,7 +1965,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call if (mAutomaticBrightnessController != null) { if (mAutomaticBrightnessController != null) { mAutomaticBrightnessController.update(); mAutomaticBrightnessController.update(); } } }, mContext); }, mHighBrightnessModeMetadata, mContext); } } private BrightnessThrottler createBrightnessThrottlerLocked() { private BrightnessThrottler createBrightnessThrottlerLocked() { Loading
services/core/java/com/android/server/display/DisplayPowerController2.java +10 −5 Original line number Original line Diff line number Diff line Loading @@ -328,6 +328,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal private float[] mNitsRange; private float[] mNitsRange; private final HighBrightnessModeController mHbmController; private final HighBrightnessModeController mHbmController; private final HighBrightnessModeMetadata mHighBrightnessModeMetadata; private final BrightnessThrottler mBrightnessThrottler; private final BrightnessThrottler mBrightnessThrottler; Loading Loading @@ -432,7 +433,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal DisplayPowerCallbacks callbacks, Handler handler, DisplayPowerCallbacks callbacks, Handler handler, SensorManager sensorManager, DisplayBlanker blanker, LogicalDisplay logicalDisplay, SensorManager sensorManager, DisplayBlanker blanker, LogicalDisplay logicalDisplay, BrightnessTracker brightnessTracker, BrightnessSetting brightnessSetting, BrightnessTracker brightnessTracker, BrightnessSetting brightnessSetting, Runnable onBrightnessChangeRunnable) { Runnable onBrightnessChangeRunnable, HighBrightnessModeMetadata hbmMetadata) { mInjector = injector != null ? injector : new Injector(); mInjector = injector != null ? injector : new Injector(); mClock = mInjector.getClock(); mClock = mInjector.getClock(); Loading @@ -448,6 +449,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal mDisplayPowerProximityStateController = mInjector.getDisplayPowerProximityStateController( mDisplayPowerProximityStateController = mInjector.getDisplayPowerProximityStateController( mWakelockController, mDisplayDeviceConfig, mHandler.getLooper(), mWakelockController, mDisplayDeviceConfig, mHandler.getLooper(), () -> updatePowerState(), mDisplayId, mSensorManager); () -> updatePowerState(), mDisplayId, mSensorManager); mHighBrightnessModeMetadata = hbmMetadata; mDisplayStateController = new DisplayStateController(mDisplayPowerProximityStateController); mDisplayStateController = new DisplayStateController(mDisplayPowerProximityStateController); mTag = "DisplayPowerController2[" + mDisplayId + "]"; mTag = "DisplayPowerController2[" + mDisplayId + "]"; Loading Loading @@ -707,7 +709,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal * Make sure DisplayManagerService.mSyncRoot lock is held when this is called * Make sure DisplayManagerService.mSyncRoot lock is held when this is called */ */ @Override @Override public void onDisplayChanged() { public void onDisplayChanged(HighBrightnessModeMetadata hbmMetadata) { final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked(); final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked(); if (device == null) { if (device == null) { Slog.wtf(mTag, "Display Device is null in DisplayPowerController2 for display: " Slog.wtf(mTag, "Display Device is null in DisplayPowerController2 for display: " Loading @@ -721,6 +723,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); final boolean isEnabled = mLogicalDisplay.isEnabledLocked(); final boolean isEnabled = mLogicalDisplay.isEnabledLocked(); final boolean isInTransition = mLogicalDisplay.isInTransitionLocked(); final boolean isInTransition = mLogicalDisplay.isInTransitionLocked(); mHandler.post(() -> { mHandler.post(() -> { boolean changed = false; boolean changed = false; if (mDisplayDevice != device) { if (mDisplayDevice != device) { Loading @@ -729,7 +732,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal mUniqueDisplayId = uniqueId; mUniqueDisplayId = uniqueId; mDisplayStatsId = mUniqueDisplayId.hashCode(); mDisplayStatsId = mUniqueDisplayId.hashCode(); mDisplayDeviceConfig = config; mDisplayDeviceConfig = config; loadFromDisplayDeviceConfig(token, info); loadFromDisplayDeviceConfig(token, info, hbmMetadata); mDisplayPowerProximityStateController.notifyDisplayDeviceChanged(config); mDisplayPowerProximityStateController.notifyDisplayDeviceChanged(config); // Since the underlying display-device changed, we really don't know the // Since the underlying display-device changed, we really don't know the Loading Loading @@ -778,7 +781,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal } } } } private void loadFromDisplayDeviceConfig(IBinder token, DisplayDeviceInfo info) { private void loadFromDisplayDeviceConfig(IBinder token, DisplayDeviceInfo info, HighBrightnessModeMetadata hbmMetadata) { // All properties that depend on the associated DisplayDevice and the DDC must be // All properties that depend on the associated DisplayDevice and the DDC must be // updated here. // updated here. loadBrightnessRampRates(); loadBrightnessRampRates(); Loading @@ -790,6 +794,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal mBrightnessRampIncreaseMaxTimeMillis, mBrightnessRampIncreaseMaxTimeMillis, mBrightnessRampDecreaseMaxTimeMillis); mBrightnessRampDecreaseMaxTimeMillis); } } mHbmController.setHighBrightnessModeMetadata(hbmMetadata); mHbmController.resetHbmData(info.width, info.height, token, info.uniqueId, mHbmController.resetHbmData(info.width, info.height, token, info.uniqueId, mDisplayDeviceConfig.getHighBrightnessModeData(), mDisplayDeviceConfig.getHighBrightnessModeData(), new HighBrightnessModeController.HdrBrightnessDeviceConfig() { new HighBrightnessModeController.HdrBrightnessDeviceConfig() { Loading Loading @@ -1740,7 +1745,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal if (mAutomaticBrightnessController != null) { if (mAutomaticBrightnessController != null) { mAutomaticBrightnessController.update(); mAutomaticBrightnessController.update(); } } }, mContext); }, mHighBrightnessModeMetadata, mContext); } } private BrightnessThrottler createBrightnessThrottlerLocked() { private BrightnessThrottler createBrightnessThrottlerLocked() { Loading
services/core/java/com/android/server/display/DisplayPowerControllerInterface.java +6 −2 Original line number Original line Diff line number Diff line Loading @@ -31,10 +31,14 @@ import java.io.PrintWriter; public interface DisplayPowerControllerInterface { public interface DisplayPowerControllerInterface { /** /** * Notified when the display is changed. We use this to apply any changes that might be needed * Notified when the display is changed. * We use this to apply any changes that might be needed * when displays get swapped on foldable devices. * when displays get swapped on foldable devices. * We also pass the High brightness mode metadata like * remaining time and hbm events for the corresponding * physical display, to update the values correctly. */ */ void onDisplayChanged(); void onDisplayChanged(HighBrightnessModeMetadata hbmInfo); /** /** * Unregisters all listeners and interrupts all running threads; halting future work. * Unregisters all listeners and interrupts all running threads; halting future work. Loading
services/core/java/com/android/server/display/HbmEvent.java 0 → 100644 +46 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2023 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; /** * Represents an event in which High Brightness Mode was enabled. */ class HbmEvent { private long mStartTimeMillis; private long mEndTimeMillis; HbmEvent(long startTimeMillis, long endTimeMillis) { this.mStartTimeMillis = startTimeMillis; this.mEndTimeMillis = endTimeMillis; } public long getStartTimeMillis() { return mStartTimeMillis; } public long getEndTimeMillis() { return mEndTimeMillis; } @Override public String toString() { return "HbmEvent: {startTimeMillis:" + mStartTimeMillis + ", endTimeMillis: " + mEndTimeMillis + "}, total: " + ((mEndTimeMillis - mStartTimeMillis) / 1000) + "]"; } }