summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/provider/Settings.java18
-rw-r--r--core/proto/android/providers/settings/secure.proto9
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java4
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java3
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java9
-rw-r--r--services/core/java/com/android/server/display/brightness/clamper/BrightnessClamper.java5
-rw-r--r--services/core/java/com/android/server/display/brightness/clamper/BrightnessClamperController.java12
-rw-r--r--services/core/java/com/android/server/display/brightness/clamper/BrightnessMinClamper.java137
-rw-r--r--services/core/java/com/android/server/display/feature/DisplayManagerFlags.java8
-rw-r--r--services/core/java/com/android/server/display/feature/display_flags.aconfig8
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/BrightnessClamperControllerTest.java3
11 files changed, 206 insertions, 10 deletions
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 7f64400a1cce..1a33b768a039 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -8846,6 +8846,24 @@ public final class Settings {
"reduce_bright_colors_persist_across_reboots";
/**
+ * Setting that specifies whether Even Dimmer - a feature that allows the brightness
+ * slider to go below what the display can conventionally do, should be enabled.
+ *
+ * @hide
+ */
+ public static final String EVEN_DIMMER_ACTIVATED =
+ "even_dimmer_activated";
+
+ /**
+ * Setting that specifies which nits level Even Dimmer should allow the screen brightness
+ * to go down to.
+ *
+ * @hide
+ */
+ public static final String EVEN_DIMMER_MIN_NITS =
+ "even_dimmer_min_nits";
+
+ /**
* List of the enabled print services.
*
* N and beyond uses {@link #DISABLED_PRINT_SERVICES}. But this might be used in an upgrade
diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto
index 4d6ed80aa763..3887dd7a753f 100644
--- a/core/proto/android/providers/settings/secure.proto
+++ b/core/proto/android/providers/settings/secure.proto
@@ -268,6 +268,13 @@ message SecureSettingsProto {
optional SettingProto enhanced_voice_privacy_enabled = 23 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ message EvenDimmer {
+ optional SettingProto even_dimmer_activated = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto even_dimmer_min_nits = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+
+ optional EvenDimmer even_dimmer = 98;
+
optional SettingProto font_weight_adjustment = 85 [ (android.privacy).dest = DEST_AUTOMATIC ];
message Gesture {
@@ -712,5 +719,5 @@ message SecureSettingsProto {
// Please insert fields in alphabetical order and group them into messages
// if possible (to avoid reaching the method limit).
- // Next tag = 98;
+ // Next tag = 99;
}
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index 8412cbaaea36..5c09b1692453 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -251,6 +251,8 @@ public class SecureSettings {
Settings.Secure.STYLUS_HANDWRITING_ENABLED,
Settings.Secure.DEFAULT_NOTE_TASK_PROFILE,
Settings.Secure.CREDENTIAL_SERVICE,
- Settings.Secure.CREDENTIAL_SERVICE_PRIMARY
+ Settings.Secure.CREDENTIAL_SERVICE_PRIMARY,
+ Settings.Secure.EVEN_DIMMER_ACTIVATED,
+ Settings.Secure.EVEN_DIMMER_MIN_NITS
};
}
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index 9197554662d3..b0169a115ec5 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -110,6 +110,9 @@ public class SecureSettingsValidators {
VALIDATORS.put(Secure.FONT_WEIGHT_ADJUSTMENT, ANY_INTEGER_VALIDATOR);
VALIDATORS.put(Secure.REDUCE_BRIGHT_COLORS_LEVEL, PERCENTAGE_INTEGER_VALIDATOR);
VALIDATORS.put(Secure.REDUCE_BRIGHT_COLORS_PERSIST_ACROSS_REBOOTS, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.EVEN_DIMMER_ACTIVATED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.EVEN_DIMMER_MIN_NITS,
+ new InclusiveFloatRangeValidator(0.0f, Float.MAX_VALUE));
VALIDATORS.put(Secure.TTS_DEFAULT_RATE, NON_NEGATIVE_INTEGER_VALIDATOR);
VALIDATORS.put(Secure.TTS_DEFAULT_PITCH, NON_NEGATIVE_INTEGER_VALIDATOR);
VALIDATORS.put(Secure.TTS_DEFAULT_SYNTH, PACKAGE_NAME_VALIDATOR);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index a509ba33bad2..a97888949446 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -2135,6 +2135,15 @@ class SettingsProtoDumpUtil {
Settings.Secure.ENHANCED_VOICE_PRIVACY_ENABLED,
SecureSettingsProto.ENHANCED_VOICE_PRIVACY_ENABLED);
+ final long evenDimmerToken = p.start(SecureSettingsProto.EVEN_DIMMER);
+ dumpSetting(s, p,
+ Settings.Secure.EVEN_DIMMER_ACTIVATED,
+ SecureSettingsProto.EvenDimmer.EVEN_DIMMER_ACTIVATED);
+ dumpSetting(s, p,
+ Settings.Secure.EVEN_DIMMER_MIN_NITS,
+ SecureSettingsProto.EvenDimmer.EVEN_DIMMER_MIN_NITS);
+ p.end(evenDimmerToken);
+
final long gestureToken = p.start(SecureSettingsProto.GESTURE);
dumpSetting(s, p,
Settings.Secure.AWARE_ENABLED,
diff --git a/services/core/java/com/android/server/display/brightness/clamper/BrightnessClamper.java b/services/core/java/com/android/server/display/brightness/clamper/BrightnessClamper.java
index 8a884b6221a2..42ebc401335e 100644
--- a/services/core/java/com/android/server/display/brightness/clamper/BrightnessClamper.java
+++ b/services/core/java/com/android/server/display/brightness/clamper/BrightnessClamper.java
@@ -25,7 +25,7 @@ import com.android.server.display.DisplayBrightnessState;
import java.io.PrintWriter;
/**
- * Provides max allowed brightness
+ * Provides brightness range constraints
*/
abstract class BrightnessClamper<T> {
@@ -74,6 +74,7 @@ abstract class BrightnessClamper<T> {
protected enum Type {
THERMAL,
POWER,
- BEDTIME_MODE
+ BEDTIME_MODE,
+ LUX,
}
}
diff --git a/services/core/java/com/android/server/display/brightness/clamper/BrightnessClamperController.java b/services/core/java/com/android/server/display/brightness/clamper/BrightnessClamperController.java
index 765608e88356..01694ddee06a 100644
--- a/services/core/java/com/android/server/display/brightness/clamper/BrightnessClamperController.java
+++ b/services/core/java/com/android/server/display/brightness/clamper/BrightnessClamperController.java
@@ -68,14 +68,14 @@ public class BrightnessClamperController {
private boolean mClamperApplied = false;
public BrightnessClamperController(Handler handler,
- ClamperChangeListener clamperChangeListener, DisplayDeviceData data, Context context,
+ ClamperChangeListener clamperChangeListener, DisplayDeviceData data, Context context,
DisplayManagerFlags flags) {
this(new Injector(), handler, clamperChangeListener, data, context, flags);
}
@VisibleForTesting
BrightnessClamperController(Injector injector, Handler handler,
- ClamperChangeListener clamperChangeListener, DisplayDeviceData data, Context context,
+ ClamperChangeListener clamperChangeListener, DisplayDeviceData data, Context context,
DisplayManagerFlags flags) {
mDeviceConfigParameterProvider = injector.getDeviceConfigParameterProvider();
mHandler = handler;
@@ -147,7 +147,8 @@ public class BrightnessClamperController {
* Should be moved to DisplayBrightnessState OR derived from DisplayBrightnessState
* TODO: b/263362199
*/
- @BrightnessInfo.BrightnessMaxReason public int getBrightnessMaxReason() {
+ @BrightnessInfo.BrightnessMaxReason
+ public int getBrightnessMaxReason() {
if (mClamperType == null) {
return BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE;
} else if (mClamperType == Type.THERMAL) {
@@ -241,12 +242,15 @@ public class BrightnessClamperController {
new BrightnessThermalClamper(handler, clamperChangeListener, data));
if (flags.isPowerThrottlingClamperEnabled()) {
clampers.add(new BrightnessPowerClamper(handler, clamperChangeListener,
- data));
+ data));
}
if (flags.isBrightnessWearBedtimeModeClamperEnabled()) {
clampers.add(new BrightnessWearBedtimeModeClamper(handler, context,
clamperChangeListener, data));
}
+ if (flags.isEvenDimmerEnabled()) {
+ clampers.add(new BrightnessMinClamper(handler, clamperChangeListener, context));
+ }
return clampers;
}
diff --git a/services/core/java/com/android/server/display/brightness/clamper/BrightnessMinClamper.java b/services/core/java/com/android/server/display/brightness/clamper/BrightnessMinClamper.java
new file mode 100644
index 000000000000..71efca12f91c
--- /dev/null
+++ b/services/core/java/com/android/server/display/brightness/clamper/BrightnessMinClamper.java
@@ -0,0 +1,137 @@
+/*
+ * 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.brightness.clamper;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.PowerManager;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.display.utils.DebugUtils;
+
+import java.io.PrintWriter;
+
+/**
+ * Class used to prevent the screen brightness dipping below a certain value, based on current
+ * lux conditions.
+ */
+public class BrightnessMinClamper extends BrightnessClamper {
+
+ // To enable these logs, run:
+ // 'adb shell setprop persist.log.tag.BrightnessMinClamper DEBUG && adb reboot'
+ private static final String TAG = "BrightnessMinClamper";
+ private static final boolean DEBUG = DebugUtils.isDebuggable(TAG);
+
+ private final SettingsObserver mSettingsObserver;
+
+ ContentResolver mContentResolver;
+ private float mNitsLowerBound;
+
+ @VisibleForTesting
+ BrightnessMinClamper(Handler handler,
+ BrightnessClamperController.ClamperChangeListener listener, Context context) {
+ super(handler, listener);
+
+ mContentResolver = context.getContentResolver();
+ mSettingsObserver = new SettingsObserver(mHandler);
+ mHandler.post(() -> {
+ start();
+ });
+ }
+
+ private void recalculateLowerBound() {
+ final int userId = UserHandle.USER_CURRENT;
+ float settingNitsLowerBound = Settings.Secure.getFloatForUser(
+ mContentResolver, Settings.Secure.EVEN_DIMMER_MIN_NITS,
+ /* def= */ PowerManager.BRIGHTNESS_MIN, userId);
+
+ boolean isActive = Settings.Secure.getIntForUser(mContentResolver,
+ Settings.Secure.EVEN_DIMMER_ACTIVATED,
+ /* def= */ 0, userId) == 1;
+
+ // TODO: luxBasedNitsLowerBound = mMinNitsToLuxSpline(currentLux);
+ float luxBasedNitsLowerBound = PowerManager.BRIGHTNESS_MIN;
+ final float nitsLowerBound = Math.max(settingNitsLowerBound, luxBasedNitsLowerBound);
+
+ if (mNitsLowerBound != nitsLowerBound || mIsActive != isActive) {
+ mIsActive = isActive;
+ mNitsLowerBound = nitsLowerBound;
+ if (DEBUG) {
+ Slog.i(TAG, "mIsActive: " + mIsActive);
+ }
+ // TODO: mBrightnessCap = nitsToBrightnessSpline(mNitsLowerBound);
+ mChangeListener.onChanged();
+ }
+ }
+
+ void start() {
+ recalculateLowerBound();
+ }
+
+
+ @Override
+ Type getType() {
+ return Type.LUX;
+ }
+
+ @Override
+ void onDeviceConfigChanged() {
+ // TODO
+ }
+
+ @Override
+ void onDisplayChanged(Object displayData) {
+
+ }
+
+ @Override
+ void stop() {
+ mContentResolver.unregisterContentObserver(mSettingsObserver);
+ }
+
+ @Override
+ void dump(PrintWriter pw) {
+ pw.println("BrightnessMinClamper:");
+ pw.println(" mBrightnessCap=" + mBrightnessCap);
+ pw.println(" mIsActive=" + mIsActive);
+ pw.println(" mNitsLowerBound=" + mNitsLowerBound);
+ super.dump(pw);
+ }
+
+ private final class SettingsObserver extends ContentObserver {
+ SettingsObserver(Handler handler) {
+ super(handler);
+ mContentResolver.registerContentObserver(
+ Settings.Secure.getUriFor(Settings.Secure.EVEN_DIMMER_MIN_NITS),
+ false, this);
+ mContentResolver.registerContentObserver(
+ Settings.Secure.getUriFor(Settings.Secure.EVEN_DIMMER_ACTIVATED),
+ false, this);
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ recalculateLowerBound();
+ }
+ }
+}
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 c71f0cf2dd91..2d5da715b585 100644
--- a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
+++ b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
@@ -78,6 +78,9 @@ public class DisplayManagerFlags {
Flags.FLAG_ENABLE_POWER_THROTTLING_CLAMPER,
Flags::enablePowerThrottlingClamper);
+ private final FlagState mEvenDimmerFlagState = new FlagState(
+ Flags.FLAG_EVEN_DIMMER,
+ Flags::evenDimmer);
private final FlagState mSmallAreaDetectionFlagState = new FlagState(
com.android.graphics.surfaceflinger.flags.Flags.FLAG_ENABLE_SMALL_AREA_DETECTION,
com.android.graphics.surfaceflinger.flags.Flags::enableSmallAreaDetection);
@@ -174,6 +177,11 @@ public class DisplayManagerFlags {
return mBackUpSmoothDisplayAndForcePeakRefreshRateFlagState.isEnabled();
}
+ /** Returns whether brightness range is allowed to extend below traditional range. */
+ public boolean isEvenDimmerEnabled() {
+ return mEvenDimmerFlagState.isEnabled();
+ }
+
public boolean isSmallAreaDetectionEnabled() {
return mSmallAreaDetectionFlagState.isEnabled();
}
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 9dfa1ee41ad6..1b4d74cdff1f 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
@@ -106,6 +106,14 @@ flag {
}
flag {
+ name: "even_dimmer"
+ namespace: "display_manager"
+ description: "Feature flag for extending the brightness below traditional range"
+ bug: "179428400"
+ is_fixed_read_only: true
+}
+
+flag {
name: "brightness_int_range_user_perception"
namespace: "display_manager"
description: "Feature flag for converting the brightness integer range to the user perception scale"
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/BrightnessClamperControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/BrightnessClamperControllerTest.java
index 9aa6136348b4..6ba7368f8f26 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/BrightnessClamperControllerTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/BrightnessClamperControllerTest.java
@@ -262,8 +262,7 @@ public class BrightnessClamperControllerTest {
Handler handler,
BrightnessClamperController.ClamperChangeListener clamperChangeListener,
BrightnessClamperController.DisplayDeviceData data,
- DisplayManagerFlags flags,
- Context context) {
+ DisplayManagerFlags flags, Context context) {
mCapturedChangeListener = clamperChangeListener;
return mClampers;
}