diff options
| author | 2023-11-28 18:37:25 +0000 | |
|---|---|---|
| committer | 2023-11-28 18:37:25 +0000 | |
| commit | 4dadb089bc13c975c52ca2a8bf4d06fd8b6af8a6 (patch) | |
| tree | 46dbee08b872f71343494d8b609eac6f15c9e6ba | |
| parent | 7a473d4fb58f59bd3c1bebb54a1c3cef38ce72b9 (diff) | |
| parent | 6dbbddc21ea4817b21a6f941727279a8348d7435 (diff) | |
Merge "Define brightness curve in backlight in DDC" into main
21 files changed, 364 insertions, 194 deletions
diff --git a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java index debf828abf0a..d848f4b6cce5 100644 --- a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java +++ b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java @@ -121,6 +121,7 @@ public abstract class BrightnessMappingStrategy { // Display independent, mode dependent values float[] brightnessLevelsNits; + float[] brightnessLevels = null; float[] luxLevels; if (isForIdleMode) { brightnessLevelsNits = getFloatArray(resources.obtainTypedArray( @@ -130,11 +131,21 @@ public abstract class BrightnessMappingStrategy { } else { brightnessLevelsNits = displayDeviceConfig.getAutoBrightnessBrighteningLevelsNits(); luxLevels = displayDeviceConfig.getAutoBrightnessBrighteningLevelsLux(); + + brightnessLevels = displayDeviceConfig.getAutoBrightnessBrighteningLevels(); + if (brightnessLevels == null || brightnessLevels.length == 0) { + // Load the old configuration in the range [0, 255]. The values need to be + // normalized to the range [0, 1]. + int[] brightnessLevelsInt = resources.getIntArray( + com.android.internal.R.array.config_autoBrightnessLcdBacklightValues); + brightnessLevels = new float[brightnessLevelsInt.length]; + for (int i = 0; i < brightnessLevels.length; i++) { + brightnessLevels[i] = normalizeAbsoluteBrightness(brightnessLevelsInt[i]); + } + } } // Display independent, mode independent values - int[] brightnessLevelsBacklight = resources.getIntArray( - com.android.internal.R.array.config_autoBrightnessLcdBacklightValues); float autoBrightnessAdjustmentMaxGamma = resources.getFraction( com.android.internal.R.fraction.config_autoBrightnessAdjustmentMaxGamma, 1, 1); @@ -155,8 +166,8 @@ public abstract class BrightnessMappingStrategy { builder.setShortTermModelUpperLuxMultiplier(SHORT_TERM_MODEL_THRESHOLD_RATIO); return new PhysicalMappingStrategy(builder.build(), nitsRange, brightnessRange, autoBrightnessAdjustmentMaxGamma, isForIdleMode, displayWhiteBalanceController); - } else if (isValidMapping(luxLevels, brightnessLevelsBacklight) && !isForIdleMode) { - return new SimpleMappingStrategy(luxLevels, brightnessLevelsBacklight, + } else if (isValidMapping(luxLevels, brightnessLevels)) { + return new SimpleMappingStrategy(luxLevels, brightnessLevels, autoBrightnessAdjustmentMaxGamma, shortTermModelTimeout); } else { return null; @@ -620,7 +631,7 @@ public abstract class BrightnessMappingStrategy { private float mUserBrightness; private long mShortTermModelTimeout; - private SimpleMappingStrategy(float[] lux, int[] brightness, float maxGamma, + private SimpleMappingStrategy(float[] lux, float[] brightness, float maxGamma, long timeout) { Preconditions.checkArgument(lux.length != 0 && brightness.length != 0, "Lux and brightness arrays must not be empty!"); @@ -635,7 +646,7 @@ public abstract class BrightnessMappingStrategy { mBrightness = new float[N]; for (int i = 0; i < N; i++) { mLux[i] = lux[i]; - mBrightness[i] = normalizeAbsoluteBrightness(brightness[i]); + mBrightness[i] = brightness[i]; } mMaxGamma = maxGamma; diff --git a/services/core/java/com/android/server/display/DisplayAdapter.java b/services/core/java/com/android/server/display/DisplayAdapter.java index 70d4ad2c6e1f..c26118eac7a2 100644 --- a/services/core/java/com/android/server/display/DisplayAdapter.java +++ b/services/core/java/com/android/server/display/DisplayAdapter.java @@ -20,6 +20,8 @@ import android.content.Context; import android.os.Handler; import android.view.Display; +import com.android.server.display.feature.DisplayManagerFlags; + import java.io.PrintWriter; import java.util.concurrent.atomic.AtomicInteger; @@ -39,6 +41,7 @@ abstract class DisplayAdapter { private final Handler mHandler; private final Listener mListener; private final String mName; + private final DisplayManagerFlags mFeatureFlags; public static final int DISPLAY_DEVICE_EVENT_ADDED = 1; public static final int DISPLAY_DEVICE_EVENT_CHANGED = 2; @@ -50,13 +53,14 @@ abstract class DisplayAdapter { private static final AtomicInteger NEXT_DISPLAY_MODE_ID = new AtomicInteger(1); // 0 = no mode. // Called with SyncRoot lock held. - public DisplayAdapter(DisplayManagerService.SyncRoot syncRoot, - Context context, Handler handler, Listener listener, String name) { + DisplayAdapter(DisplayManagerService.SyncRoot syncRoot, Context context, Handler handler, + Listener listener, String name, DisplayManagerFlags featureFlags) { mSyncRoot = syncRoot; mContext = context; mHandler = handler; mListener = listener; mName = name; + mFeatureFlags = featureFlags; } /** @@ -88,6 +92,10 @@ abstract class DisplayAdapter { return mName; } + public final DisplayManagerFlags getFeatureFlags() { + return mFeatureFlags; + } + /** * Registers the display adapter with the display manager. * diff --git a/services/core/java/com/android/server/display/DisplayDevice.java b/services/core/java/com/android/server/display/DisplayDevice.java index 2fdf90d7d286..3b05b47eb542 100644 --- a/services/core/java/com/android/server/display/DisplayDevice.java +++ b/services/core/java/com/android/server/display/DisplayDevice.java @@ -400,6 +400,7 @@ abstract class DisplayDevice { } private DisplayDeviceConfig loadDisplayDeviceConfig() { - return DisplayDeviceConfig.create(mContext, false); + return DisplayDeviceConfig.create(mContext, /* useConfigXml= */ false, + mDisplayAdapter.getFeatureFlags()); } } diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java index e6aa8258041a..d97127c91fbf 100644 --- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java +++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java @@ -57,6 +57,7 @@ import com.android.server.display.config.HdrBrightnessData; import com.android.server.display.config.HighBrightnessMode; import com.android.server.display.config.IntegerArray; import com.android.server.display.config.LuxThrottling; +import com.android.server.display.config.LuxToBrightnessMapping; import com.android.server.display.config.NitsMap; import com.android.server.display.config.NonNegativeFloatToFloatPoint; import com.android.server.display.config.Point; @@ -77,6 +78,7 @@ import com.android.server.display.config.ThermalThrottling; import com.android.server.display.config.ThresholdPoint; import com.android.server.display.config.UsiVersion; import com.android.server.display.config.XmlParser; +import com.android.server.display.feature.DisplayManagerFlags; import com.android.server.display.utils.DebugUtils; import org.xmlpull.v1.XmlPullParserException; @@ -310,16 +312,18 @@ import javax.xml.datatype.DatatypeConfigurationException; * <darkeningLightDebounceIdleMillis> * 1000 * </darkeningLightDebounceIdleMillis> - * <displayBrightnessMapping> - * <displayBrightnessPoint> - * <lux>50</lux> - * <nits>45.32</nits> - * </displayBrightnessPoint> - * <displayBrightnessPoint> - * <lux>80</lux> - * <nits>75.43</nits> - * </displayBrightnessPoint> - * </displayBrightnessMapping> + * <luxToBrightnessMapping> + * <map> + * <point> + * <first>0</first> + * <second>0.2</second> + * </point> + * <point> + * <first>80</first> + * <second>0.3</second> + * </point> + * </map> + * </luxToBrightnessMapping> * </autoBrightness> * * <screenBrightnessRampFastDecrease>0.01</screenBrightnessRampFastDecrease> @@ -630,7 +634,6 @@ public class DisplayDeviceConfig { // for the corresponding values above private float[] mBrightness; - /** * Array of desired screen brightness in nits corresponding to the lux values * in the mBrightnessLevelsLux array. The display brightness is defined as the @@ -640,20 +643,25 @@ public class DisplayDeviceConfig { private float[] mBrightnessLevelsNits; /** - * Array of light sensor lux values to define our levels for auto backlight - * brightness support. + * Array of desired screen brightness corresponding to the lux values + * in the mBrightnessLevelsLux array. The brightness values must be non-negative and + * non-decreasing. They must be between {@link PowerManager.BRIGHTNESS_MIN} and + * {@link PowerManager.BRIGHTNESS_MAX}. This must be overridden in platform specific overlays + */ + private float[] mBrightnessLevels; + + /** + * Array of light sensor lux values to define our levels for auto-brightness support. * - * The N + 1 entries of this array define N control points defined in mBrightnessLevelsNits, - * with first value always being 0 lux + * The first lux value is always 0. * - * The control points must be strictly increasing. Each control point - * corresponds to an entry in the brightness backlight values arrays. - * For example, if lux == level[1] (second element of the levels array) - * then the brightness will be determined by value[0] (first element - * of the brightness values array). + * The control points must be strictly increasing. Each control point corresponds to an entry + * in the brightness values arrays. For example, if lux == luxLevels[1] (second element + * of the levels array) then the brightness will be determined by brightnessLevels[1] (second + * element of the brightness values array). * - * Spline interpolation is used to determine the auto-brightness - * backlight values for lux levels between these control points. + * Spline interpolation is used to determine the auto-brightness values for lux levels between + * these control points. */ private float[] mBrightnessLevelsLux; @@ -849,9 +857,12 @@ public class DisplayDeviceConfig { */ private float mBrightnessCapForWearBedtimeMode; + private final DisplayManagerFlags mFlags; + @VisibleForTesting - DisplayDeviceConfig(Context context) { + DisplayDeviceConfig(Context context, DisplayManagerFlags flags) { mContext = context; + mFlags = flags; } /** @@ -867,9 +878,9 @@ public class DisplayDeviceConfig { * @return A configuration instance for the specified display. */ public static DisplayDeviceConfig create(Context context, long physicalDisplayId, - boolean isFirstDisplay) { + boolean isFirstDisplay, DisplayManagerFlags flags) { final DisplayDeviceConfig config = createWithoutDefaultValues(context, physicalDisplayId, - isFirstDisplay); + isFirstDisplay, flags); config.copyUninitializedValuesFromSecondaryConfig(loadDefaultConfigurationXml(context)); return config; @@ -884,28 +895,29 @@ public class DisplayDeviceConfig { * or the default values. * @return A configuration instance. */ - public static DisplayDeviceConfig create(Context context, boolean useConfigXml) { + public static DisplayDeviceConfig create(Context context, boolean useConfigXml, + DisplayManagerFlags flags) { final DisplayDeviceConfig config; if (useConfigXml) { - config = getConfigFromGlobalXml(context); + config = getConfigFromGlobalXml(context, flags); } else { - config = getConfigFromPmValues(context); + config = getConfigFromPmValues(context, flags); } return config; } private static DisplayDeviceConfig createWithoutDefaultValues(Context context, - long physicalDisplayId, boolean isFirstDisplay) { + long physicalDisplayId, boolean isFirstDisplay, DisplayManagerFlags flags) { DisplayDeviceConfig config; config = loadConfigFromDirectory(context, Environment.getProductDirectory(), - physicalDisplayId); + physicalDisplayId, flags); if (config != null) { return config; } config = loadConfigFromDirectory(context, Environment.getVendorDirectory(), - physicalDisplayId); + physicalDisplayId, flags); if (config != null) { return config; } @@ -913,7 +925,7 @@ public class DisplayDeviceConfig { // If no config can be loaded from any ddc xml at all, // prepare a whole config using the global config.xml. // Guaranteed not null - return create(context, isFirstDisplay); + return create(context, isFirstDisplay, flags); } private static DisplayConfiguration loadDefaultConfigurationXml(Context context) { @@ -966,18 +978,19 @@ public class DisplayDeviceConfig { } private static DisplayDeviceConfig loadConfigFromDirectory(Context context, - File baseDirectory, long physicalDisplayId) { + File baseDirectory, long physicalDisplayId, DisplayManagerFlags flags) { DisplayDeviceConfig config; // Create config using filename from physical ID (including "stable" bit). config = getConfigFromSuffix(context, baseDirectory, STABLE_ID_SUFFIX_FORMAT, - physicalDisplayId); + physicalDisplayId, flags); if (config != null) { return config; } // Create config using filename from physical ID (excluding "stable" bit). final long withoutStableFlag = physicalDisplayId & ~STABLE_FLAG; - config = getConfigFromSuffix(context, baseDirectory, NO_SUFFIX_FORMAT, withoutStableFlag); + config = getConfigFromSuffix(context, baseDirectory, NO_SUFFIX_FORMAT, withoutStableFlag, + flags); if (config != null) { return config; } @@ -986,7 +999,7 @@ public class DisplayDeviceConfig { final DisplayAddress.Physical physicalAddress = DisplayAddress.fromPhysicalDisplayId(physicalDisplayId); int port = physicalAddress.getPort(); - config = getConfigFromSuffix(context, baseDirectory, PORT_SUFFIX_FORMAT, port); + config = getConfigFromSuffix(context, baseDirectory, PORT_SUFFIX_FORMAT, port, flags); return config; } @@ -1605,6 +1618,13 @@ public class DisplayDeviceConfig { } /** + * @return Auto brightness brightening levels + */ + public float[] getAutoBrightnessBrighteningLevels() { + return mBrightnessLevels; + } + + /** * @return Default peak refresh rate of the associated display */ public int getDefaultPeakRefreshRate() { @@ -1857,6 +1877,7 @@ public class DisplayDeviceConfig { + mAutoBrightnessDarkeningLightDebounceIdle + ", mBrightnessLevelsLux= " + Arrays.toString(mBrightnessLevelsLux) + ", mBrightnessLevelsNits= " + Arrays.toString(mBrightnessLevelsNits) + + ", mBrightnessLevels= " + Arrays.toString(mBrightnessLevels) + ", mDdcAutoBrightnessAvailable= " + mDdcAutoBrightnessAvailable + ", mAutoBrightnessAvailable= " + mAutoBrightnessAvailable + "\n" @@ -1890,27 +1911,29 @@ public class DisplayDeviceConfig { } private static DisplayDeviceConfig getConfigFromSuffix(Context context, File baseDirectory, - String suffixFormat, long idNumber) { + String suffixFormat, long idNumber, DisplayManagerFlags flags) { final String suffix = String.format(Locale.ROOT, suffixFormat, idNumber); final String filename = String.format(Locale.ROOT, CONFIG_FILE_FORMAT, suffix); final File filePath = Environment.buildPath( baseDirectory, ETC_DIR, DISPLAY_CONFIG_DIR, filename); - final DisplayDeviceConfig config = new DisplayDeviceConfig(context); + final DisplayDeviceConfig config = new DisplayDeviceConfig(context, flags); if (config.initFromFile(filePath)) { return config; } return null; } - private static DisplayDeviceConfig getConfigFromGlobalXml(Context context) { - DisplayDeviceConfig config = new DisplayDeviceConfig(context); + private static DisplayDeviceConfig getConfigFromGlobalXml(Context context, + DisplayManagerFlags flags) { + DisplayDeviceConfig config = new DisplayDeviceConfig(context, flags); config.initFromGlobalXml(); return config; } - private static DisplayDeviceConfig getConfigFromPmValues(Context context) { - DisplayDeviceConfig config = new DisplayDeviceConfig(context); + private static DisplayDeviceConfig getConfigFromPmValues(Context context, + DisplayManagerFlags flags) { + DisplayDeviceConfig config = new DisplayDeviceConfig(context, flags); config.initFromDefaultValues(); return config; } @@ -2615,8 +2638,23 @@ public class DisplayDeviceConfig { * loading the value from the display config, and if not present, falls back to config.xml. */ private void loadAutoBrightnessDisplayBrightnessMapping(AutoBrightness autoBrightnessConfig) { - if (autoBrightnessConfig == null - || autoBrightnessConfig.getDisplayBrightnessMapping() == null) { + if (mFlags.areAutoBrightnessModesEnabled() && autoBrightnessConfig != null + && autoBrightnessConfig.getLuxToBrightnessMapping() != null) { + LuxToBrightnessMapping mapping = autoBrightnessConfig.getLuxToBrightnessMapping(); + final int size = mapping.getMap().getPoint().size(); + mBrightnessLevels = new float[size]; + mBrightnessLevelsLux = new float[size]; + for (int i = 0; i < size; i++) { + float backlight = mapping.getMap().getPoint().get(i).getSecond().floatValue(); + mBrightnessLevels[i] = mBacklightToBrightnessSpline.interpolate(backlight); + mBrightnessLevelsLux[i] = mapping.getMap().getPoint().get(i).getFirst() + .floatValue(); + } + if (size > 0 && mBrightnessLevelsLux[0] != 0) { + throw new IllegalArgumentException( + "The first lux value in the display brightness mapping must be 0"); + } + } else { mBrightnessLevelsNits = getFloatArray(mContext.getResources() .obtainTypedArray(com.android.internal.R.array .config_autoBrightnessDisplayValuesNits), PowerManager @@ -2624,18 +2662,6 @@ public class DisplayDeviceConfig { mBrightnessLevelsLux = getLuxLevels(mContext.getResources() .getIntArray(com.android.internal.R.array .config_autoBrightnessLevels)); - } else { - final int size = autoBrightnessConfig.getDisplayBrightnessMapping() - .getDisplayBrightnessPoint().size(); - mBrightnessLevelsNits = new float[size]; - // The first control point is implicit and always at 0 lux. - mBrightnessLevelsLux = new float[size + 1]; - for (int i = 0; i < size; i++) { - mBrightnessLevelsNits[i] = autoBrightnessConfig.getDisplayBrightnessMapping() - .getDisplayBrightnessPoint().get(i).getNits().floatValue(); - mBrightnessLevelsLux[i + 1] = autoBrightnessConfig.getDisplayBrightnessMapping() - .getDisplayBrightnessPoint().get(i).getLux().floatValue(); - } } } diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index 6a7c17d54980..2ab15e639d68 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -1853,7 +1853,7 @@ public final class DisplayManagerService extends SystemService { // early apps like SetupWizard/Launcher. In particular, SUW is displayed using // the virtual display inside VR before any VR-specific apps even run. mVirtualDisplayAdapter = mInjector.getVirtualDisplayAdapter(mSyncRoot, mContext, - mHandler, mDisplayDeviceRepo); + mHandler, mDisplayDeviceRepo, mFlags); if (mVirtualDisplayAdapter != null) { registerDisplayAdapterLocked(mVirtualDisplayAdapter); } @@ -1871,7 +1871,7 @@ public final class DisplayManagerService extends SystemService { private void registerOverlayDisplayAdapterLocked() { registerDisplayAdapterLocked(new OverlayDisplayAdapter( - mSyncRoot, mContext, mHandler, mDisplayDeviceRepo, mUiHandler)); + mSyncRoot, mContext, mHandler, mDisplayDeviceRepo, mUiHandler, mFlags)); } private void registerWifiDisplayAdapterLocked() { @@ -1880,7 +1880,7 @@ public final class DisplayManagerService extends SystemService { || SystemProperties.getInt(FORCE_WIFI_DISPLAY_ENABLE, -1) == 1) { mWifiDisplayAdapter = new WifiDisplayAdapter( mSyncRoot, mContext, mHandler, mDisplayDeviceRepo, - mPersistentDataStore); + mPersistentDataStore, mFlags); registerDisplayAdapterLocked(mWifiDisplayAdapter); } } @@ -3288,8 +3288,10 @@ public final class DisplayManagerService extends SystemService { @VisibleForTesting static class Injector { VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, Context context, - Handler handler, DisplayAdapter.Listener displayAdapterListener) { - return new VirtualDisplayAdapter(syncRoot, context, handler, displayAdapterListener); + Handler handler, DisplayAdapter.Listener displayAdapterListener, + DisplayManagerFlags flags) { + return new VirtualDisplayAdapter(syncRoot, context, handler, displayAdapterListener, + flags); } LocalDisplayAdapter getLocalDisplayAdapter(SyncRoot syncRoot, Context context, diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java index ff9a1ab61b13..22898a65c5de 100644 --- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java +++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java @@ -84,8 +84,6 @@ final class LocalDisplayAdapter extends DisplayAdapter { private final boolean mIsBootDisplayModeSupported; - private final DisplayManagerFlags mFlags; - private final DisplayNotificationManager mDisplayNotificationManager; private Context mOverlayContext; @@ -103,12 +101,11 @@ final class LocalDisplayAdapter extends DisplayAdapter { Listener listener, DisplayManagerFlags flags, DisplayNotificationManager displayNotificationManager, Injector injector) { - super(syncRoot, context, handler, listener, TAG); + super(syncRoot, context, handler, listener, TAG, flags); mDisplayNotificationManager = displayNotificationManager; mInjector = injector; mSurfaceControlProxy = mInjector.getSurfaceControlProxy(); mIsBootDisplayModeSupported = mSurfaceControlProxy.getBootDisplayModeSupport(); - mFlags = flags; } @Override @@ -510,7 +507,7 @@ final class LocalDisplayAdapter extends DisplayAdapter { // Load display device config final Context context = getOverlayContext(); mDisplayDeviceConfig = mInjector.createDisplayDeviceConfig(context, mPhysicalDisplayId, - mIsFirstDisplay); + mIsFirstDisplay, getFeatureFlags()); // Load brightness HWC quirk mBacklightAdapter.setForceSurfaceControl(mDisplayDeviceConfig.hasQuirk( @@ -831,7 +828,8 @@ final class LocalDisplayAdapter extends DisplayAdapter { + ", state=" + Display.stateToString(state) + ")"); } - boolean isDisplayOffloadEnabled = mFlags.isDisplayOffloadEnabled(); + boolean isDisplayOffloadEnabled = + getFeatureFlags().isDisplayOffloadEnabled(); // We must tell sidekick/displayoffload to stop controlling the display // before we can change its power mode, so do that first. @@ -1377,8 +1375,8 @@ final class LocalDisplayAdapter extends DisplayAdapter { } public DisplayDeviceConfig createDisplayDeviceConfig(Context context, - long physicalDisplayId, boolean isFirstDisplay) { - return DisplayDeviceConfig.create(context, physicalDisplayId, isFirstDisplay); + long physicalDisplayId, boolean isFirstDisplay, DisplayManagerFlags flags) { + return DisplayDeviceConfig.create(context, physicalDisplayId, isFirstDisplay, flags); } } diff --git a/services/core/java/com/android/server/display/OverlayDisplayAdapter.java b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java index 2ce7690ecc3f..22ff2d0eeffd 100644 --- a/services/core/java/com/android/server/display/OverlayDisplayAdapter.java +++ b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java @@ -36,6 +36,7 @@ import android.view.SurfaceControl; import com.android.internal.util.DumpUtils; import com.android.internal.util.IndentingPrintWriter; +import com.android.server.display.feature.DisplayManagerFlags; import com.android.server.display.mode.DisplayModeDirector; import java.io.PrintWriter; @@ -134,8 +135,9 @@ final class OverlayDisplayAdapter extends DisplayAdapter { // Called with SyncRoot lock held. public OverlayDisplayAdapter(DisplayManagerService.SyncRoot syncRoot, - Context context, Handler handler, Listener listener, Handler uiHandler) { - super(syncRoot, context, handler, listener, TAG); + Context context, Handler handler, Listener listener, Handler uiHandler, + DisplayManagerFlags featureFlags) { + super(syncRoot, context, handler, listener, TAG, featureFlags); mUiHandler = uiHandler; } diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java index edbd42465534..ec5ad7de11b3 100644 --- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java +++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java @@ -61,6 +61,7 @@ import android.view.Surface; import android.view.SurfaceControl; import com.android.internal.annotations.VisibleForTesting; +import com.android.server.display.feature.DisplayManagerFlags; import java.io.PrintWriter; import java.util.concurrent.atomic.AtomicInteger; @@ -88,7 +89,7 @@ public class VirtualDisplayAdapter extends DisplayAdapter { // Called with SyncRoot lock held. public VirtualDisplayAdapter(DisplayManagerService.SyncRoot syncRoot, - Context context, Handler handler, Listener listener) { + Context context, Handler handler, Listener listener, DisplayManagerFlags featureFlags) { this(syncRoot, context, handler, listener, new SurfaceControlDisplayFactory() { @Override public IBinder createDisplay(String name, boolean secure, float requestedRefreshRate) { @@ -99,14 +100,15 @@ public class VirtualDisplayAdapter extends DisplayAdapter { public void destroyDisplay(IBinder displayToken) { DisplayControl.destroyDisplay(displayToken); } - }); + }, featureFlags); } @VisibleForTesting VirtualDisplayAdapter(DisplayManagerService.SyncRoot syncRoot, Context context, Handler handler, Listener listener, - SurfaceControlDisplayFactory surfaceControlDisplayFactory) { - super(syncRoot, context, handler, listener, TAG); + SurfaceControlDisplayFactory surfaceControlDisplayFactory, + DisplayManagerFlags featureFlags) { + super(syncRoot, context, handler, listener, TAG, featureFlags); mHandler = handler; mSurfaceControlDisplayFactory = surfaceControlDisplayFactory; } diff --git a/services/core/java/com/android/server/display/WifiDisplayAdapter.java b/services/core/java/com/android/server/display/WifiDisplayAdapter.java index 7660cf8a1c3a..aa98cd85d38e 100644 --- a/services/core/java/com/android/server/display/WifiDisplayAdapter.java +++ b/services/core/java/com/android/server/display/WifiDisplayAdapter.java @@ -41,6 +41,7 @@ import android.view.SurfaceControl; import com.android.internal.util.DumpUtils; import com.android.internal.util.IndentingPrintWriter; +import com.android.server.display.feature.DisplayManagerFlags; import com.android.server.display.utils.DebugUtils; import java.io.PrintWriter; @@ -99,8 +100,8 @@ final class WifiDisplayAdapter extends DisplayAdapter { // Called with SyncRoot lock held. public WifiDisplayAdapter(DisplayManagerService.SyncRoot syncRoot, Context context, Handler handler, Listener listener, - PersistentDataStore persistentDataStore) { - super(syncRoot, context, handler, listener, TAG); + PersistentDataStore persistentDataStore, DisplayManagerFlags featureFlags) { + super(syncRoot, context, handler, listener, TAG, featureFlags); if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT)) { throw new RuntimeException("WiFi display was requested, " diff --git a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java index eb8798406152..c71f0cf2dd91 100644 --- a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java +++ b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java @@ -94,6 +94,10 @@ public class DisplayManagerFlags { Flags.FLAG_BRIGHTNESS_WEAR_BEDTIME_MODE_CLAMPER, Flags::brightnessWearBedtimeModeClamper); + private final FlagState mAutoBrightnessModesFlagState = new FlagState( + Flags.FLAG_AUTO_BRIGHTNESS_MODES, + Flags::autoBrightnessModes); + /** Returns whether connected display management is enabled or not. */ public boolean isConnectedDisplayManagementEnabled() { return mConnectedDisplayManagementFlagState.isEnabled(); @@ -187,6 +191,13 @@ public class DisplayManagerFlags { } /** + * @return Whether generic auto-brightness modes are enabled + */ + public boolean areAutoBrightnessModesEnabled() { + return mAutoBrightnessModesFlagState.isEnabled(); + } + + /** * dumps all flagstates * @param pw printWriter */ @@ -206,6 +217,7 @@ public class DisplayManagerFlags { pw.println(" " + mBrightnessIntRangeUserPerceptionFlagState); pw.println(" " + mVsyncProximityVote); pw.println(" " + mBrightnessWearBedtimeModeClamperFlagState); + pw.println(" " + mAutoBrightnessModesFlagState); } private static class FlagState { diff --git a/services/core/java/com/android/server/display/feature/display_flags.aconfig b/services/core/java/com/android/server/display/feature/display_flags.aconfig index 9dab76152dad..9dfa1ee41ad6 100644 --- a/services/core/java/com/android/server/display/feature/display_flags.aconfig +++ b/services/core/java/com/android/server/display/feature/display_flags.aconfig @@ -128,3 +128,11 @@ flag { bug: "293613040" is_fixed_read_only: true } + +flag { + name: "auto_brightness_modes" + namespace: "display_manager" + description: "Feature flag for generic auto-brightness modes" + bug: "293613040" + is_fixed_read_only: true +} diff --git a/services/core/xsd/display-device-config/display-device-config.xsd b/services/core/xsd/display-device-config/display-device-config.xsd index 8473532754e4..c625b1e1eef7 100644 --- a/services/core/xsd/display-device-config/display-device-config.xsd +++ b/services/core/xsd/display-device-config/display-device-config.xsd @@ -592,42 +592,39 @@ minOccurs="0" maxOccurs="1"> <xs:annotation name="final"/> </xs:element> - <!-- Sets the brightness mapping of the desired screen brightness in nits to the - corresponding lux for the current display --> - <xs:element name="displayBrightnessMapping" type="displayBrightnessMapping" + <!-- Sets the brightness mapping of the desired screen brightness to the corresponding + lux for the current display --> + <xs:element name="luxToBrightnessMapping" type="luxToBrightnessMapping" minOccurs="0" maxOccurs="1"> <xs:annotation name="final"/> </xs:element> </xs:sequence> </xs:complexType> - <!-- Represents the brightness mapping of the desired screen brightness in nits to the - corresponding lux for the current display --> - <xs:complexType name="displayBrightnessMapping"> - <xs:sequence> - <!-- Sets the list of display brightness points, each representing the desired screen - brightness in nits to the corresponding lux for the current display - - The N entries of this array define N + 1 control points as follows: - (1-based arrays) - - Point 1: (0, nits[1]): currentLux <= 0 - Point 2: (lux[1], nits[2]): 0 < currentLux <= lux[1] - Point 3: (lux[2], nits[3]): lux[2] < currentLux <= lux[3] - ... - Point N+1: (lux[N], nits[N+1]): lux[N] < currentLux - - The control points must be strictly increasing. Each control point - corresponds to an entry in the brightness backlight values arrays. - For example, if currentLux == lux[1] (first element of the levels array) - then the brightness will be determined by nits[2] (second element - of the brightness values array). - --> - <xs:element name="displayBrightnessPoint" type="displayBrightnessPoint" - minOccurs="1" maxOccurs="unbounded"> - <xs:annotation name="final"/> - </xs:element> - </xs:sequence> + <!-- Sets the list of display brightness points, each representing the desired screen brightness + in a certain lux environment. + + The first value of each point is the lux value and the second value is the brightness value. + + The first lux value must be 0. + + The control points must be strictly increasing. + + Example: if currentLux == the second lux value in the mapping then the brightness will be + determined by the second brightness value in the mapping. Spline interpolation is used + to determine the auto-brightness values for lux levels between these control points. + + The brightness values must be non-negative decimals within the range between the first and + the last brightness values in screenBrightnessMap. + + This is used in place of config_autoBrightnessLevels and config_autoBrightnessLcdBacklightValues + defined in the config XML resource. + --> + <xs:complexType name="luxToBrightnessMapping"> + <xs:element name="map" type="nonNegativeFloatToFloatMap"> + <xs:annotation name="nonnull"/> + <xs:annotation name="final"/> + </xs:element> </xs:complexType> <!-- Represents a point in the display brightness mapping, representing the lux level from the diff --git a/services/core/xsd/display-device-config/schema/current.txt b/services/core/xsd/display-device-config/schema/current.txt index 2437261e3a54..8c8c1230f944 100644 --- a/services/core/xsd/display-device-config/schema/current.txt +++ b/services/core/xsd/display-device-config/schema/current.txt @@ -7,14 +7,14 @@ package com.android.server.display.config { method public final java.math.BigInteger getBrighteningLightDebounceMillis(); method public final java.math.BigInteger getDarkeningLightDebounceIdleMillis(); method public final java.math.BigInteger getDarkeningLightDebounceMillis(); - method public final com.android.server.display.config.DisplayBrightnessMapping getDisplayBrightnessMapping(); method public boolean getEnabled(); + method public final com.android.server.display.config.LuxToBrightnessMapping getLuxToBrightnessMapping(); method public final void setBrighteningLightDebounceIdleMillis(java.math.BigInteger); method public final void setBrighteningLightDebounceMillis(java.math.BigInteger); method public final void setDarkeningLightDebounceIdleMillis(java.math.BigInteger); method public final void setDarkeningLightDebounceMillis(java.math.BigInteger); - method public final void setDisplayBrightnessMapping(com.android.server.display.config.DisplayBrightnessMapping); method public void setEnabled(boolean); + method public final void setLuxToBrightnessMapping(com.android.server.display.config.LuxToBrightnessMapping); } public class BlockingZoneConfig { @@ -78,11 +78,6 @@ package com.android.server.display.config { method public java.util.List<com.android.server.display.config.Density> getDensity(); } - public class DisplayBrightnessMapping { - ctor public DisplayBrightnessMapping(); - method public final java.util.List<com.android.server.display.config.DisplayBrightnessPoint> getDisplayBrightnessPoint(); - } - public class DisplayBrightnessPoint { ctor public DisplayBrightnessPoint(); method public final java.math.BigInteger getLux(); @@ -222,6 +217,12 @@ package com.android.server.display.config { method @NonNull public final java.util.List<com.android.server.display.config.BrightnessLimitMap> getBrightnessLimitMap(); } + public class LuxToBrightnessMapping { + ctor public LuxToBrightnessMapping(); + method @NonNull public final com.android.server.display.config.NonNegativeFloatToFloatMap getMap(); + method public final void setMap(@NonNull com.android.server.display.config.NonNegativeFloatToFloatMap); + } + public class NitsMap { ctor public NitsMap(); method public String getInterpolation(); diff --git a/services/tests/displayservicetests/src/com/android/server/display/BrightnessMappingStrategyTest.java b/services/tests/displayservicetests/src/com/android/server/display/BrightnessMappingStrategyTest.java index 97e582607133..a2e80f0d9b9b 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/BrightnessMappingStrategyTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/BrightnessMappingStrategyTest.java @@ -104,7 +104,7 @@ public class BrightnessMappingStrategyTest { 468.5f, }; - private static final int[] DISPLAY_LEVELS_BACKLIGHT = { + private static final int[] DISPLAY_LEVELS_INT = { 9, 30, 45, @@ -118,6 +118,20 @@ public class BrightnessMappingStrategyTest { 255 }; + private static final float[] DISPLAY_LEVELS = { + 0.03f, + 0.11f, + 0.17f, + 0.24f, + 0.3f, + 0.37f, + 0.46f, + 0.57f, + 0.7f, + 0.87f, + 1 + }; + private static final float[] DISPLAY_RANGE_NITS = { 2.685f, 478.5f }; private static final float[] BACKLIGHT_RANGE_ZERO_TO_ONE = { 0.0f, 1.0f }; private static final float[] DISPLAY_LEVELS_RANGE_BACKLIGHT_FLOAT = { 0.03149606299f, 1.0f }; @@ -155,23 +169,23 @@ public class BrightnessMappingStrategyTest { DisplayWhiteBalanceController mMockDwbc; @Test - public void testSimpleStrategyMappingAtControlPoints() { - Resources res = createResources(DISPLAY_LEVELS_BACKLIGHT); + public void testSimpleStrategyMappingAtControlPoints_IntConfig() { + Resources res = createResources(DISPLAY_LEVELS_INT); DisplayDeviceConfig ddc = createDdc(); BrightnessMappingStrategy simple = BrightnessMappingStrategy.create(res, ddc, mMockDwbc); assertNotNull("BrightnessMappingStrategy should not be null", simple); for (int i = 0; i < LUX_LEVELS.length; i++) { final float expectedLevel = MathUtils.map(PowerManager.BRIGHTNESS_OFF + 1, PowerManager.BRIGHTNESS_ON, PowerManager.BRIGHTNESS_MIN, - PowerManager.BRIGHTNESS_MAX, DISPLAY_LEVELS_BACKLIGHT[i]); + PowerManager.BRIGHTNESS_MAX, DISPLAY_LEVELS_INT[i]); assertEquals(expectedLevel, simple.getBrightness(LUX_LEVELS[i]), 0.0001f /*tolerance*/); } } @Test - public void testSimpleStrategyMappingBetweenControlPoints() { - Resources res = createResources(DISPLAY_LEVELS_BACKLIGHT); + public void testSimpleStrategyMappingBetweenControlPoints_IntConfig() { + Resources res = createResources(DISPLAY_LEVELS_INT); DisplayDeviceConfig ddc = createDdc(); BrightnessMappingStrategy simple = BrightnessMappingStrategy.create(res, ddc, mMockDwbc); assertNotNull("BrightnessMappingStrategy should not be null", simple); @@ -179,14 +193,42 @@ public class BrightnessMappingStrategyTest { final float lux = (LUX_LEVELS[i - 1] + LUX_LEVELS[i]) / 2; final float backlight = simple.getBrightness(lux) * PowerManager.BRIGHTNESS_ON; assertTrue("Desired brightness should be between adjacent control points.", - backlight > DISPLAY_LEVELS_BACKLIGHT[i - 1] - && backlight < DISPLAY_LEVELS_BACKLIGHT[i]); + backlight > DISPLAY_LEVELS_INT[i - 1] + && backlight < DISPLAY_LEVELS_INT[i]); + } + } + + @Test + public void testSimpleStrategyMappingAtControlPoints_FloatConfig() { + Resources res = createResources(EMPTY_INT_ARRAY); + DisplayDeviceConfig ddc = createDdc(EMPTY_FLOAT_ARRAY, EMPTY_FLOAT_ARRAY, LUX_LEVELS, + EMPTY_FLOAT_ARRAY, DISPLAY_LEVELS); + BrightnessMappingStrategy simple = BrightnessMappingStrategy.create(res, ddc, mMockDwbc); + assertNotNull("BrightnessMappingStrategy should not be null", simple); + for (int i = 0; i < LUX_LEVELS.length; i++) { + assertEquals(DISPLAY_LEVELS[i], simple.getBrightness(LUX_LEVELS[i]), + /* tolerance= */ 0.0001f); + } + } + + @Test + public void testSimpleStrategyMappingBetweenControlPoints_FloatConfig() { + Resources res = createResources(EMPTY_INT_ARRAY); + DisplayDeviceConfig ddc = createDdc(EMPTY_FLOAT_ARRAY, EMPTY_FLOAT_ARRAY, LUX_LEVELS, + EMPTY_FLOAT_ARRAY, DISPLAY_LEVELS); + BrightnessMappingStrategy simple = BrightnessMappingStrategy.create(res, ddc, mMockDwbc); + assertNotNull("BrightnessMappingStrategy should not be null", simple); + for (int i = 1; i < LUX_LEVELS.length; i++) { + final float lux = (LUX_LEVELS[i - 1] + LUX_LEVELS[i]) / 2; + final float brightness = simple.getBrightness(lux); + assertTrue("Desired brightness should be between adjacent control points.", + brightness > DISPLAY_LEVELS[i - 1] && brightness < DISPLAY_LEVELS[i]); } } @Test public void testSimpleStrategyIgnoresNewConfiguration() { - Resources res = createResources(DISPLAY_LEVELS_BACKLIGHT); + Resources res = createResources(DISPLAY_LEVELS_INT); DisplayDeviceConfig ddc = createDdc(); BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(res, ddc, mMockDwbc); @@ -201,14 +243,14 @@ public class BrightnessMappingStrategyTest { @Test public void testSimpleStrategyIgnoresNullConfiguration() { - Resources res = createResources(DISPLAY_LEVELS_BACKLIGHT); + Resources res = createResources(DISPLAY_LEVELS_INT); DisplayDeviceConfig ddc = createDdc(); BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(res, ddc, mMockDwbc); strategy.setBrightnessConfiguration(null); - final int n = DISPLAY_LEVELS_BACKLIGHT.length; + final int n = DISPLAY_LEVELS_INT.length; final float expectedBrightness = - (float) DISPLAY_LEVELS_BACKLIGHT[n - 1] / PowerManager.BRIGHTNESS_ON; + (float) DISPLAY_LEVELS_INT[n - 1] / PowerManager.BRIGHTNESS_ON; assertEquals(expectedBrightness, strategy.getBrightness(LUX_LEVELS[n - 1]), 0.0001f /*tolerance*/); } @@ -322,7 +364,7 @@ public class BrightnessMappingStrategyTest { @Test public void testDefaultStrategyIsPhysical() { - Resources res = createResources(DISPLAY_LEVELS_BACKLIGHT); + Resources res = createResources(DISPLAY_LEVELS_INT); DisplayDeviceConfig ddc = createDdc(DISPLAY_RANGE_NITS, DISPLAY_LEVELS_RANGE_BACKLIGHT_FLOAT, LUX_LEVELS, DISPLAY_LEVELS_NITS); BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(res, ddc, mMockDwbc); @@ -363,13 +405,13 @@ public class BrightnessMappingStrategyTest { BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(res, ddc, mMockDwbc); assertNull(strategy); - res = createResources(DISPLAY_LEVELS_BACKLIGHT); + res = createResources(DISPLAY_LEVELS_INT); strategy = BrightnessMappingStrategy.create(res, ddc, mMockDwbc); assertNull(strategy); // Extra backlight level final int[] backlight = Arrays.copyOf( - DISPLAY_LEVELS_BACKLIGHT, DISPLAY_LEVELS_BACKLIGHT.length + 1); + DISPLAY_LEVELS_INT, DISPLAY_LEVELS_INT.length + 1); backlight[backlight.length - 1] = backlight[backlight.length - 2] + 1; res = createResources(backlight); ddc = createDdc(DISPLAY_RANGE_NITS, @@ -410,7 +452,7 @@ public class BrightnessMappingStrategyTest { LUX_LEVELS, DISPLAY_LEVELS_NITS); assertStrategyAdaptsToUserDataPoints(BrightnessMappingStrategy.create(res, ddc, mMockDwbc)); ddc = createDdc(DISPLAY_RANGE_NITS, BACKLIGHT_RANGE_ZERO_TO_ONE); - res = createResources(DISPLAY_LEVELS_BACKLIGHT); + res = createResources(DISPLAY_LEVELS_INT); assertStrategyAdaptsToUserDataPoints(BrightnessMappingStrategy.create(res, ddc, mMockDwbc)); } @@ -546,16 +588,24 @@ public class BrightnessMappingStrategyTest { when(mockDdc.getBrightness()).thenReturn(backlightArray); when(mockDdc.getAutoBrightnessBrighteningLevelsLux()).thenReturn(LUX_LEVELS); when(mockDdc.getAutoBrightnessBrighteningLevelsNits()).thenReturn(EMPTY_FLOAT_ARRAY); + when(mockDdc.getAutoBrightnessBrighteningLevels()).thenReturn(EMPTY_FLOAT_ARRAY); return mockDdc; } private DisplayDeviceConfig createDdc(float[] nitsArray, float[] backlightArray, float[] luxLevelsFloat, float[] brightnessLevelsNits) { + return createDdc(nitsArray, backlightArray, luxLevelsFloat, brightnessLevelsNits, + EMPTY_FLOAT_ARRAY); + } + + private DisplayDeviceConfig createDdc(float[] nitsArray, float[] backlightArray, + float[] luxLevelsFloat, float[] brightnessLevelsNits, float[] brightnessLevels) { DisplayDeviceConfig mockDdc = mock(DisplayDeviceConfig.class); when(mockDdc.getNits()).thenReturn(nitsArray); when(mockDdc.getBrightness()).thenReturn(backlightArray); when(mockDdc.getAutoBrightnessBrighteningLevelsLux()).thenReturn(luxLevelsFloat); when(mockDdc.getAutoBrightnessBrighteningLevelsNits()).thenReturn(brightnessLevelsNits); + when(mockDdc.getAutoBrightnessBrighteningLevels()).thenReturn(brightnessLevels); return mockDdc; } diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java index e80e9e805369..31d7e88e671b 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java @@ -50,6 +50,7 @@ import com.android.internal.R; import com.android.internal.display.BrightnessSynchronizer; import com.android.server.display.config.HdrBrightnessData; import com.android.server.display.config.ThermalStatus; +import com.android.server.display.feature.DisplayManagerFlags; import org.junit.Before; import org.junit.Test; @@ -93,10 +94,14 @@ public final class DisplayDeviceConfigTest { @Mock private Resources mResources; + @Mock + private DisplayManagerFlags mFlags; + @Before public void setUp() { MockitoAnnotations.initMocks(this); when(mContext.getResources()).thenReturn(mResources); + when(mFlags.areAutoBrightnessModesEnabled()).thenReturn(true); mockDeviceConfigs(); } @@ -111,10 +116,6 @@ public final class DisplayDeviceConfigTest { assertArrayEquals(mDisplayDeviceConfig.getBrightness(), BRIGHTNESS, ZERO_DELTA); assertArrayEquals(mDisplayDeviceConfig.getNits(), NITS, ZERO_DELTA); assertArrayEquals(mDisplayDeviceConfig.getBacklight(), BRIGHTNESS, ZERO_DELTA); - assertArrayEquals(mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsLux(), new - float[]{0.0f, 50.0f, 80.0f}, ZERO_DELTA); - assertArrayEquals(mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsNits(), new - float[]{45.32f, 75.43f}, ZERO_DELTA); // Test thresholds assertEquals(10, mDisplayDeviceConfig.getAmbientLuxBrighteningMinThreshold(), @@ -607,7 +608,7 @@ public final class DisplayDeviceConfigTest { assertArrayEquals(mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsNits(), new float[]{2.0f, 200.0f, 600.0f}, ZERO_DELTA); assertArrayEquals(mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsLux(), new - float[]{0.0f, 0.0f, 110.0f, 500.0f}, ZERO_DELTA); + float[]{0.0f, 110.0f, 500.0f}, ZERO_DELTA); // Test thresholds assertEquals(0, mDisplayDeviceConfig.getAmbientLuxBrighteningMinThreshold(), ZERO_DELTA); @@ -727,6 +728,31 @@ public final class DisplayDeviceConfigTest { assertEquals(0.1f, mDisplayDeviceConfig.getBrightnessCapForWearBedtimeMode(), ZERO_DELTA); } + @Test + public void testAutoBrightnessBrighteningLevels() throws IOException { + setupDisplayDeviceConfigFromDisplayConfigFile(getContent(getValidLuxThrottling(), + getValidProxSensor(), /* includeIdleMode= */ false)); + + assertArrayEquals(new float[]{0.0f, 80}, + mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsLux(), ZERO_DELTA); + assertArrayEquals(new float[]{0.2f, 0.3f}, + mDisplayDeviceConfig.getAutoBrightnessBrighteningLevels(), SMALL_DELTA); + } + + @Test + public void testAutoBrightnessBrighteningLevels_FeatureFlagOff() throws IOException { + when(mFlags.areAutoBrightnessModesEnabled()).thenReturn(false); + setupDisplayDeviceConfigFromConfigResourceFile(); + setupDisplayDeviceConfigFromDisplayConfigFile(getContent(getValidLuxThrottling(), + getValidProxSensor(), /* includeIdleMode= */ false)); + + assertNull(mDisplayDeviceConfig.getAutoBrightnessBrighteningLevels()); + assertArrayEquals(new float[]{0, 110, 500}, + mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsLux(), ZERO_DELTA); + assertArrayEquals(new float[]{2, 200, 600}, + mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsNits(), SMALL_DELTA); + } + private String getValidLuxThrottling() { return "<luxThrottling>\n" + " <brightnessLimitMap>\n" @@ -1048,8 +1074,8 @@ public final class DisplayDeviceConfigTest { + "<screenBrightnessRampDecreaseMaxIdleMillis>" + "5000" + "</screenBrightnessRampDecreaseMaxIdleMillis>\n"; - } + private String getContent() { return getContent(getValidLuxThrottling(), getValidProxSensor(), /* includeIdleMode= */ true); @@ -1100,16 +1126,18 @@ public final class DisplayDeviceConfigTest { + "<brighteningLightDebounceMillis>2000</brighteningLightDebounceMillis>\n" + "<darkeningLightDebounceMillis>1000</darkeningLightDebounceMillis>\n" + (includeIdleMode ? getRampSpeedsIdle() : "") - + "<displayBrightnessMapping>\n" - + "<displayBrightnessPoint>\n" - + "<lux>50</lux>\n" - + "<nits>45.32</nits>\n" - + "</displayBrightnessPoint>\n" - + "<displayBrightnessPoint>\n" - + "<lux>80</lux>\n" - + "<nits>75.43</nits>\n" - + "</displayBrightnessPoint>\n" - + "</displayBrightnessMapping>\n" + + "<luxToBrightnessMapping>\n" + + "<map>\n" + + "<point>\n" + + "<first>0</first>\n" + + "<second>0.2</second>\n" + + "</point>\n" + + "<point>\n" + + "<first>80</first>\n" + + "<second>0.3</second>\n" + + "</point>\n" + + "</map>\n" + + "</luxToBrightnessMapping>\n" + "</autoBrightness>\n" + getPowerThrottlingConfig() + "<highBrightnessMode enabled=\"true\">\n" @@ -1386,7 +1414,7 @@ public final class DisplayDeviceConfigTest { private void setupDisplayDeviceConfigFromDisplayConfigFile(String content) throws IOException { Path tempFile = Files.createTempFile("display_config", ".tmp"); Files.write(tempFile, content.getBytes(StandardCharsets.UTF_8)); - mDisplayDeviceConfig = new DisplayDeviceConfig(mContext); + mDisplayDeviceConfig = new DisplayDeviceConfig(mContext, mFlags); mDisplayDeviceConfig.initFromFile(tempFile.toFile()); } @@ -1395,25 +1423,15 @@ public final class DisplayDeviceConfigTest { when(mResources.obtainTypedArray( com.android.internal.R.array.config_screenBrightnessNits)) .thenReturn(screenBrightnessNits); - TypedArray screenBrightnessBacklight = createFloatTypedArray(new - float[]{0.0f, 120.0f, 255.0f}); - when(mResources.obtainTypedArray( - com.android.internal.R.array.config_screenBrightnessBacklight)) - .thenReturn(screenBrightnessBacklight); when(mResources.getIntArray(com.android.internal.R.array .config_screenBrightnessBacklight)).thenReturn(new int[]{0, 120, 255}); - when(mResources.getIntArray(com.android.internal.R.array - .config_autoBrightnessLevels)).thenReturn(new int[]{30, 80}); - when(mResources.getIntArray(com.android.internal.R.array - .config_autoBrightnessDisplayValuesNits)).thenReturn(new int[]{25, 55}); - TypedArray screenBrightnessLevelNits = createFloatTypedArray(new float[]{2.0f, 200.0f, 600.0f}); when(mResources.obtainTypedArray( com.android.internal.R.array.config_autoBrightnessDisplayValuesNits)) .thenReturn(screenBrightnessLevelNits); - int[] screenBrightnessLevelLux = new int[]{0, 110, 500}; + int[] screenBrightnessLevelLux = new int[]{110, 500}; when(mResources.getIntArray( com.android.internal.R.array.config_autoBrightnessLevels)) .thenReturn(screenBrightnessLevelLux); @@ -1475,7 +1493,8 @@ public final class DisplayDeviceConfigTest { R.integer.config_screenBrightnessCapForWearBedtimeMode)) .thenReturn(35); - mDisplayDeviceConfig = DisplayDeviceConfig.create(mContext, true); + mDisplayDeviceConfig = DisplayDeviceConfig.create(mContext, /* useConfigXml= */ true, + mFlags); } private TypedArray createFloatTypedArray(float[] vals) { diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceTest.java index 4fd8f26d91a8..dc6abf1981c0 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceTest.java @@ -57,6 +57,9 @@ public class DisplayDeviceTest { @Mock private SurfaceControl.Transaction mMockTransaction; + @Mock + private DisplayAdapter mMockDisplayAdapter; + @Before public void setup() { MockitoAnnotations.initMocks(this); @@ -67,34 +70,39 @@ public class DisplayDeviceTest { @Test public void testGetDisplaySurfaceDefaultSizeLocked_notRotated() { - DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo); + DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo, + mMockDisplayAdapter); assertThat(displayDevice.getDisplaySurfaceDefaultSizeLocked()).isEqualTo(PORTRAIT_SIZE); } @Test public void testGetDisplaySurfaceDefaultSizeLocked_rotation0() { - DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo); + DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo, + mMockDisplayAdapter); displayDevice.setProjectionLocked(mMockTransaction, ROTATION_0, new Rect(), new Rect()); assertThat(displayDevice.getDisplaySurfaceDefaultSizeLocked()).isEqualTo(PORTRAIT_SIZE); } @Test public void testGetDisplaySurfaceDefaultSizeLocked_rotation90() { - DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo); + DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo, + mMockDisplayAdapter); displayDevice.setProjectionLocked(mMockTransaction, ROTATION_90, new Rect(), new Rect()); assertThat(displayDevice.getDisplaySurfaceDefaultSizeLocked()).isEqualTo(LANDSCAPE_SIZE); } @Test public void testGetDisplaySurfaceDefaultSizeLocked_rotation180() { - DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo); + DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo, + mMockDisplayAdapter); displayDevice.setProjectionLocked(mMockTransaction, ROTATION_180, new Rect(), new Rect()); assertThat(displayDevice.getDisplaySurfaceDefaultSizeLocked()).isEqualTo(PORTRAIT_SIZE); } @Test public void testGetDisplaySurfaceDefaultSizeLocked_rotation270() { - DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo); + DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo, + mMockDisplayAdapter); displayDevice.setProjectionLocked(mMockTransaction, ROTATION_270, new Rect(), new Rect()); assertThat(displayDevice.getDisplaySurfaceDefaultSizeLocked()).isEqualTo(LANDSCAPE_SIZE); } @@ -102,8 +110,9 @@ public class DisplayDeviceTest { private static class FakeDisplayDevice extends DisplayDevice { private final DisplayDeviceInfo mDisplayDeviceInfo; - FakeDisplayDevice(DisplayDeviceInfo displayDeviceInfo) { - super(null, null, "", InstrumentationRegistry.getInstrumentation().getContext()); + FakeDisplayDevice(DisplayDeviceInfo displayDeviceInfo, DisplayAdapter displayAdapter) { + super(displayAdapter, /* displayToken= */ null, /* uniqueId= */ "", + InstrumentationRegistry.getInstrumentation().getContext()); mDisplayDeviceInfo = displayDeviceInfo; } diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java index 55f56e93fea5..02e3ef4d5f0b 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java @@ -212,7 +212,8 @@ public class DisplayManagerServiceTest { new DisplayManagerService.Injector() { @Override VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, - Context context, Handler handler, DisplayAdapter.Listener listener) { + Context context, Handler handler, DisplayAdapter.Listener listener, + DisplayManagerFlags flags) { return mMockVirtualDisplayAdapter; } @@ -251,7 +252,8 @@ public class DisplayManagerServiceTest { @Override VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, Context context, - Handler handler, DisplayAdapter.Listener displayAdapterListener) { + Handler handler, DisplayAdapter.Listener displayAdapterListener, + DisplayManagerFlags flags) { return new VirtualDisplayAdapter(syncRoot, context, handler, displayAdapterListener, new VirtualDisplayAdapter.SurfaceControlDisplayFactory() { @Override @@ -263,7 +265,7 @@ public class DisplayManagerServiceTest { @Override public void destroyDisplay(IBinder displayToken) { } - }); + }, flags); } @Override @@ -329,6 +331,7 @@ public class DisplayManagerServiceTest { @Mock SensorManager mSensorManager; @Mock DisplayDeviceConfig mMockDisplayDeviceConfig; @Mock PackageManagerInternal mMockPackageManagerInternal; + @Mock DisplayAdapter mMockDisplayAdapter; @Captor ArgumentCaptor<ContentRecordingSession> mContentRecordingSessionCaptor; @Mock DisplayManagerFlags mMockFlags; @@ -788,7 +791,8 @@ public class DisplayManagerServiceTest { new DisplayManagerService.Injector() { @Override VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, - Context context, Handler handler, DisplayAdapter.Listener listener) { + Context context, Handler handler, DisplayAdapter.Listener listener, + DisplayManagerFlags flags) { return null; // return null for the adapter. This should cause a failure. } @@ -3194,7 +3198,7 @@ public class DisplayManagerServiceTest { private DisplayDeviceInfo mDisplayDeviceInfo; FakeDisplayDevice() { - super(null, null, "", mContext); + super(mMockDisplayAdapter, /* displayToken= */ null, /* uniqueId= */ "", mContext); } public void setDisplayDeviceInfo(DisplayDeviceInfo displayDeviceInfo) { diff --git a/services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java b/services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java index 8270845657c6..f36854b1ea78 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java @@ -1455,8 +1455,8 @@ public class LocalDisplayAdapterTest { // mMockContext and values will be loaded from mMockResources. @Override public DisplayDeviceConfig createDisplayDeviceConfig(Context context, - long physicalDisplayId, boolean isFirstDisplay) { - return DisplayDeviceConfig.create(context, isFirstDisplay); + long physicalDisplayId, boolean isFirstDisplay, DisplayManagerFlags flags) { + return DisplayDeviceConfig.create(context, isFirstDisplay, flags); } } diff --git a/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java b/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java index 43d2b8f741ae..28ec89629df0 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java @@ -119,8 +119,8 @@ public class LogicalDisplayMapperTest { @Mock IThermalService mIThermalServiceMock; @Spy DeviceStateToLayoutMap mDeviceStateToLayoutMapSpy = new DeviceStateToLayoutMap(mIdProducer, NON_EXISTING_FILE); - @Mock - DisplayManagerFlags mFlagsMock; + @Mock DisplayManagerFlags mFlagsMock; + @Mock DisplayAdapter mDisplayAdapterMock; @Captor ArgumentCaptor<LogicalDisplay> mDisplayCaptor; @Captor ArgumentCaptor<Integer> mDisplayEventCaptor; @@ -1075,7 +1075,8 @@ public class LogicalDisplayMapperTest { private int mState; TestDisplayDevice() { - super(null, null, "test_display_" + sUniqueTestDisplayId++, mContextMock); + super(mDisplayAdapterMock, /* displayToken= */ null, + "test_display_" + sUniqueTestDisplayId++, mContextMock); mInfo = new DisplayDeviceInfo(); } diff --git a/services/tests/displayservicetests/src/com/android/server/display/PersistentDataStoreTest.java b/services/tests/displayservicetests/src/com/android/server/display/PersistentDataStoreTest.java index 9f91916a4046..5676a388acff 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/PersistentDataStoreTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/PersistentDataStoreTest.java @@ -32,9 +32,12 @@ import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -51,8 +54,12 @@ public class PersistentDataStoreTest { private TestInjector mInjector; private TestLooper mTestLooper; + @Mock + private DisplayAdapter mDisplayAdapter; + @Before public void setUp() { + MockitoAnnotations.initMocks(this); mInjector = new TestInjector(); mTestLooper = new TestLooper(); Handler handler = new Handler(mTestLooper.getLooper()); @@ -62,8 +69,8 @@ public class PersistentDataStoreTest { @Test public void testLoadBrightness() { final String uniqueDisplayId = "test:123"; - final DisplayDevice testDisplayDevice = new DisplayDevice( - null, null, uniqueDisplayId, null) { + final DisplayDevice testDisplayDevice = new DisplayDevice(mDisplayAdapter, + /* displayToken= */ null, uniqueDisplayId, /* context= */ null) { @Override public boolean hasStableUniqueId() { return true; @@ -100,7 +107,8 @@ public class PersistentDataStoreTest { public void testSetBrightness_brightnessTagWithNoUserId_updatesToBrightnessTagWithUserId() { final String uniqueDisplayId = "test:123"; final DisplayDevice testDisplayDevice = - new DisplayDevice(null, null, uniqueDisplayId, null) { + new DisplayDevice(mDisplayAdapter, /* displayToken= */ null, uniqueDisplayId, + /* context= */ null) { @Override public boolean hasStableUniqueId() { return true; @@ -273,7 +281,8 @@ public class PersistentDataStoreTest { assertNull(mDataStore.getBrightnessConfigurationForDisplayLocked(uniqueDisplayId, userSerial)); - DisplayDevice testDisplayDevice = new DisplayDevice(null, null, uniqueDisplayId, null) { + DisplayDevice testDisplayDevice = new DisplayDevice(mDisplayAdapter, + /* displayToken= */ null, uniqueDisplayId, /* context= */ null) { @Override public boolean hasStableUniqueId() { return true; @@ -319,7 +328,8 @@ public class PersistentDataStoreTest { assertNull(mDataStore.getBrightnessConfigurationForDisplayLocked(uniqueDisplayId, userSerial)); - DisplayDevice testDisplayDevice = new DisplayDevice(null, null, uniqueDisplayId, null) { + DisplayDevice testDisplayDevice = new DisplayDevice(mDisplayAdapter, + /* displayToken= */ null, uniqueDisplayId, /* context= */ null) { @Override public boolean hasStableUniqueId() { return false; @@ -386,7 +396,8 @@ public class PersistentDataStoreTest { @Test public void testStoreAndRestoreResolution() { final String uniqueDisplayId = "test:123"; - DisplayDevice testDisplayDevice = new DisplayDevice(null, null, uniqueDisplayId, null) { + DisplayDevice testDisplayDevice = new DisplayDevice(mDisplayAdapter, + /* displayToken= */ null, uniqueDisplayId, /* context= */ null) { @Override public boolean hasStableUniqueId() { return true; @@ -422,7 +433,8 @@ public class PersistentDataStoreTest { @Test public void testStoreAndRestoreRefreshRate() { final String uniqueDisplayId = "test:123"; - DisplayDevice testDisplayDevice = new DisplayDevice(null, null, uniqueDisplayId, null) { + DisplayDevice testDisplayDevice = new DisplayDevice(mDisplayAdapter, + /* displayToken= */ null, uniqueDisplayId, /* context= */ null) { @Override public boolean hasStableUniqueId() { return true; @@ -455,7 +467,8 @@ public class PersistentDataStoreTest { @Test public void testBrightnessInitialisesWithInvalidFloat() { final String uniqueDisplayId = "test:123"; - DisplayDevice testDisplayDevice = new DisplayDevice(null, null, uniqueDisplayId, null) { + DisplayDevice testDisplayDevice = new DisplayDevice(mDisplayAdapter, + /* displayToken= */ null, uniqueDisplayId, /* context= */ null) { @Override public boolean hasStableUniqueId() { return true; diff --git a/services/tests/displayservicetests/src/com/android/server/display/VirtualDisplayAdapterTest.java b/services/tests/displayservicetests/src/com/android/server/display/VirtualDisplayAdapterTest.java index 73e7ba0750e0..c01b15c17483 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/VirtualDisplayAdapterTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/VirtualDisplayAdapterTest.java @@ -28,6 +28,7 @@ import android.os.IBinder; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; +import com.android.server.display.feature.DisplayManagerFlags; import com.android.server.testutils.TestHandler; import org.junit.Before; @@ -59,13 +60,17 @@ public class VirtualDisplayAdapterTest { private VirtualDisplayAdapter mVirtualDisplayAdapter; + @Mock + private DisplayManagerFlags mFeatureFlags; + @Before public void setUp() { MockitoAnnotations.initMocks(this); mHandler = new TestHandler(null); mVirtualDisplayAdapter = new VirtualDisplayAdapter(new DisplayManagerService.SyncRoot(), - mContextMock, mHandler, mMockListener, mMockSufaceControlDisplayFactory); + mContextMock, mHandler, mMockListener, mMockSufaceControlDisplayFactory, + mFeatureFlags); when(mMockCallback.asBinder()).thenReturn(mMockBinder); } |