Merge "Add support for disabling autobrightness when stylus under use" into main
diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java
index e598097..36e816a 100644
--- a/core/java/android/hardware/display/DisplayManagerInternal.java
+++ b/core/java/android/hardware/display/DisplayManagerInternal.java
@@ -455,6 +455,11 @@
public abstract void onPresentation(int displayId, boolean isShown);
/**
+ * Called upon the usage of stylus.
+ */
+ public abstract void stylusGestureStarted(long eventTime);
+
+ /**
* Describes the requested power state of the display.
*
* This object is intended to describe the general characteristics of the
diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
index af9c9ac..8d96ba9 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
@@ -377,6 +377,7 @@
* </point>
* </map>
* </luxToBrightnessMapping>
+ * <idleStylusTimeoutMillis>10000</idleStylusTimeoutMillis>
* </autoBrightness>
*
* <screenBrightnessRampFastDecrease>0.01</screenBrightnessRampFastDecrease>
@@ -708,6 +709,10 @@
private static final int KEEP_CURRENT_BRIGHTNESS = -1;
+ // The default value to 0 which will signify that the stylus usage immediately stopped
+ // after it was started. This will make the system behave as if the stylus was never used
+ private static final int DEFAULT_IDLE_STYLUS_TIMEOUT_MILLIS = 0;
+
private final Context mContext;
// The details of the ambient light sensor associated with this display.
@@ -754,6 +759,9 @@
@Nullable
private DisplayBrightnessMappingConfig mDisplayBrightnessMapping;
+ private int mIdleStylusTimeoutMillis =
+ DEFAULT_IDLE_STYLUS_TIMEOUT_MILLIS;
+
private float mBacklightMinimum = Float.NaN;
private float mBacklightMaximum = Float.NaN;
private float mBrightnessDefault = Float.NaN;
@@ -1730,6 +1738,7 @@
+ ", mDisplayBrightnessMapping= " + mDisplayBrightnessMapping
+ ", mDdcAutoBrightnessAvailable= " + mDdcAutoBrightnessAvailable
+ ", mAutoBrightnessAvailable= " + mAutoBrightnessAvailable
+ + ", mIdleStylusTimeoutMillis= " + mIdleStylusTimeoutMillis
+ "\n"
+ "mDefaultLowBlockingZoneRefreshRate= " + mDefaultLowBlockingZoneRefreshRate
+ ", mDefaultHighBlockingZoneRefreshRate= " + mDefaultHighBlockingZoneRefreshRate
@@ -2389,10 +2398,19 @@
loadAutoBrightnessDarkeningLightDebounceIdle(autoBrightness);
mDisplayBrightnessMapping = new DisplayBrightnessMappingConfig(mContext, mFlags,
autoBrightness, getBacklightToBrightnessSpline());
+ loadIdleStylusTimeoutMillis(autoBrightness);
loadEnableAutoBrightness(autoBrightness);
}
/**
+ * Gets the timeout post the stylus usage after which the automatic brightness will be enabled
+ * again
+ */
+ public int getIdleStylusTimeoutMillis() {
+ return mIdleStylusTimeoutMillis;
+ }
+
+ /**
* Loads the auto-brightness brightening light debounce. Internally, this takes care of loading
* the value from the display config, and if not present, falls back to config.xml.
*/
@@ -2923,6 +2941,16 @@
return levels;
}
+ private void loadIdleStylusTimeoutMillis(AutoBrightness autoBrightness) {
+ if (autoBrightness == null) {
+ return;
+ }
+ BigInteger idleStylusTimeoutMillis = autoBrightness.getIdleStylusTimeoutMillis();
+ if (idleStylusTimeoutMillis != null) {
+ mIdleStylusTimeoutMillis = idleStylusTimeoutMillis.intValue();
+ }
+ }
+
private void loadEnableAutoBrightness(AutoBrightness autobrightness) {
// mDdcAutoBrightnessAvailable is initialised to true, so that we fallback to using the
// config.xml values if the autobrightness tag is not defined in the ddc file.
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 99a7743..bb503aa 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -5646,6 +5646,21 @@
public void onPresentation(int displayId, boolean isShown) {
mExternalDisplayPolicy.onPresentation(displayId, isShown);
}
+
+ @Override
+ public void stylusGestureStarted(long eventTime) {
+ if (mFlags.isBlockAutobrightnessChangesOnStylusUsage()) {
+ DisplayPowerController displayPowerController;
+ synchronized (mSyncRoot) {
+ displayPowerController = mDisplayPowerControllers.get(
+ Display.DEFAULT_DISPLAY);
+ }
+ // We assume that the stylus is being used on the default display. This should
+ // be changed to the displayId on which it is being used once we start getting this
+ // information from the input manager service
+ displayPowerController.stylusGestureStarted(eventTime);
+ }
+ }
}
class DesiredDisplayModeSpecsObserver
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 03fec011..8f07bb3 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -167,12 +167,11 @@
private static final int MSG_SET_DWBC_LOGGING_ENABLED = 16;
private static final int MSG_SET_BRIGHTNESS_FROM_OFFLOAD = 17;
private static final int MSG_OFFLOADING_SCREEN_ON_UNBLOCKED = 18;
-
-
+ private static final int MSG_SET_STYLUS_BEING_USED = 19;
+ private static final int MSG_SET_STYLUS_USE_ENDED = 20;
private static final int BRIGHTNESS_CHANGE_STATSD_REPORT_INTERVAL_MS = 500;
-
// State machine constants for tracking initial brightness ramp skipping when enabled.
private static final int RAMP_STATE_SKIP_NONE = 0;
private static final int RAMP_STATE_SKIP_INITIAL = 1;
@@ -191,6 +190,10 @@
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50, 60, 70, 80,
90, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1200,
1400, 1600, 1800, 2000, 2250, 2500, 2750, 3000};
+
+ private static final int STYLUS_USAGE_DEBOUNCE_TIME = 1000;
+ private static final int NANO_SECONDS_TO_MILLI_SECONDS_RATIO = 1_000_000;
+
private static final int[] BRIGHTNESS_RANGE_INDEX = {
FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_UNKNOWN,
FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_0_1,
@@ -498,6 +501,11 @@
@GuardedBy("mLock")
private int mPendingOverrideDozeScreenStateLocked;
+ private long mLastStylusUsageEventTime = -1;
+
+ // The time of inactivity after which the stylus can be assumed to be no longer in use.
+ private long mIdleStylusTimeoutMillisConfig = 0;
+
/**
* Creates the display power controller.
*/
@@ -518,6 +526,7 @@
mSensorManager = sensorManager;
mHandler = new DisplayControllerHandler(handler.getLooper());
mDisplayDeviceConfig = mDisplayDevice.getDisplayDeviceConfig();
+ mIdleStylusTimeoutMillisConfig = mDisplayDeviceConfig.getIdleStylusTimeoutMillis();
mIsEnabled = logicalDisplay.isEnabledLocked();
mIsInTransition = logicalDisplay.isInTransitionLocked();
mIsDisplayInternal = displayDeviceInfo.type == Display.TYPE_INTERNAL;
@@ -893,6 +902,7 @@
mPhysicalDisplayName = displayName;
mDisplayStatsId = mUniqueDisplayId.hashCode();
mDisplayDeviceConfig = config;
+ mIdleStylusTimeoutMillisConfig = mDisplayDeviceConfig.getIdleStylusTimeoutMillis();
mThermalBrightnessThrottlingDataId = thermalBrightnessThrottlingDataId;
loadFromDisplayDeviceConfig(token, info, hbmMetadata);
mDisplayPowerProximityStateController.notifyDisplayDeviceChanged(config);
@@ -2971,6 +2981,18 @@
return mDisplayId == Display.DEFAULT_DISPLAY || mBootCompleted;
}
+ public void stylusGestureStarted(long eventTimeNanoSeconds) {
+ long eventTimeMs = eventTimeNanoSeconds / NANO_SECONDS_TO_MILLI_SECONDS_RATIO;
+ if (mLastStylusUsageEventTime == -1
+ || eventTimeMs > mLastStylusUsageEventTime + STYLUS_USAGE_DEBOUNCE_TIME) {
+ synchronized (mLock) {
+ // Add a message to notify the stylus usage has started
+ mHandler.sendEmptyMessageAtTime(MSG_SET_STYLUS_BEING_USED, mClock.uptimeMillis());
+ }
+ mLastStylusUsageEventTime = eventTimeMs;
+ }
+ }
+
private final class DisplayControllerHandler extends Handler {
DisplayControllerHandler(Looper looper) {
super(looper, null, true /*async*/);
@@ -3087,6 +3109,20 @@
updatePowerState();
}
break;
+ case MSG_SET_STYLUS_BEING_USED:
+ // Remove any MSG_SET_STYLUS_USE_ENDED message from the handler queue and
+ // post a delayed MSG_SET_STYLUS_USE_ENDED message to delay the stylus
+ // usage ended event processing
+ mHandler.removeMessages(MSG_SET_STYLUS_USE_ENDED);
+ Message message = mHandler.obtainMessage(MSG_SET_STYLUS_USE_ENDED);
+ mHandler.sendMessageAtTime(message,
+ mClock.uptimeMillis() + mIdleStylusTimeoutMillisConfig);
+ mDisplayBrightnessController.setStylusBeingUsed(true);
+ break;
+ case MSG_SET_STYLUS_USE_ENDED:
+ mDisplayBrightnessController.setStylusBeingUsed(false);
+ updatePowerState();
+ break;
}
}
}
diff --git a/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java b/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java
index 72a91d5..71fdaf3 100644
--- a/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java
+++ b/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java
@@ -501,6 +501,13 @@
return true;
}
+ /**
+ * Notifies if the stylus is currently being used or not.
+ */
+ public void setStylusBeingUsed(boolean isEnabled) {
+ // Todo(b/369977976) - Disable the auto-brightness strategy
+ }
+
@VisibleForTesting
static class Injector {
DisplayBrightnessStrategySelector getDisplayBrightnessStrategySelector(Context context,
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 df66893..5284d1c 100644
--- a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
+++ b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
@@ -203,6 +203,10 @@
Flags.FLAG_NORMAL_BRIGHTNESS_FOR_DOZE_PARAMETER,
Flags::normalBrightnessForDozeParameter
);
+ private final FlagState mBlockAutobrightnessChangesOnStylusUsage = new FlagState(
+ Flags.FLAG_BLOCK_AUTOBRIGHTNESS_CHANGES_ON_STYLUS_USAGE,
+ Flags::blockAutobrightnessChangesOnStylusUsage
+ );
private final FlagState mEnableBatteryStatsForAllDisplays = new FlagState(
Flags.FLAG_ENABLE_BATTERY_STATS_FOR_ALL_DISPLAYS,
@@ -436,6 +440,13 @@
}
/**
+ * @return {@code true} if autobrightness is to be blocked when stylus is being used
+ */
+ public boolean isBlockAutobrightnessChangesOnStylusUsage() {
+ return mBlockAutobrightnessChangesOnStylusUsage.isEnabled();
+ }
+
+ /**
* dumps all flagstates
* @param pw printWriter
*/
@@ -479,6 +490,7 @@
pw.println(" " + mNormalBrightnessForDozeParameter);
pw.println(" " + mIdleScreenConfigInSubscribingLightSensor);
pw.println(" " + mEnableBatteryStatsForAllDisplays);
+ pw.println(" " + mBlockAutobrightnessChangesOnStylusUsage);
}
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 e3ebe5b..252ed09 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
@@ -364,4 +364,12 @@
description: "Flag to enable battery stats for all displays."
bug: "366112793"
is_fixed_read_only: true
-}
\ No newline at end of file
+}
+
+flag {
+ name: "block_autobrightness_changes_on_stylus_usage"
+ namespace: "display_manager"
+ description: "Block the usage of ALS to control the display brightness when stylus is being used"
+ bug: "352411468"
+ is_fixed_read_only: true
+}
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index f045576..8acf583 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -2694,6 +2694,9 @@
@SuppressWarnings("unused")
private void notifyStylusGestureStarted(int deviceId, long eventTime) {
mBatteryController.notifyStylusGestureStarted(deviceId, eventTime);
+ if (mDisplayManagerInternal != null) {
+ mDisplayManagerInternal.stylusGestureStarted(eventTime);
+ }
}
/**
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 a07facf..776de2e 100644
--- a/services/core/xsd/display-device-config/display-device-config.xsd
+++ b/services/core/xsd/display-device-config/display-device-config.xsd
@@ -712,6 +712,12 @@
minOccurs="0" maxOccurs="unbounded">
<xs:annotation name="final"/>
</xs:element>
+ <!-- The time after which the stylus is to be assumed to be not under use. This will
+ enable the logic of changing the brightness with ambient light changes -->
+ <xs:element name="idleStylusTimeoutMillis" type="xs:nonNegativeInteger"
+ minOccurs="0" maxOccurs="1">
+ <xs:annotation name="final"/>
+ </xs:element>
</xs:sequence>
</xs:complexType>
diff --git a/services/core/xsd/display-device-config/schema/current.txt b/services/core/xsd/display-device-config/schema/current.txt
index 5309263..110a5a2 100644
--- a/services/core/xsd/display-device-config/schema/current.txt
+++ b/services/core/xsd/display-device-config/schema/current.txt
@@ -8,12 +8,14 @@
method public final java.math.BigInteger getDarkeningLightDebounceIdleMillis();
method public final java.math.BigInteger getDarkeningLightDebounceMillis();
method public boolean getEnabled();
+ method public final java.math.BigInteger getIdleStylusTimeoutMillis();
method public final java.util.List<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 void setEnabled(boolean);
+ method public final void setIdleStylusTimeoutMillis(java.math.BigInteger);
}
public enum AutoBrightnessModeName {
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 8e1be9a..3976ea4 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java
@@ -157,6 +157,7 @@
.getIdleScreenRefreshRateTimeoutLuxThresholdPoint());
assertNull(mDisplayDeviceConfig.getTempSensor().name);
assertTrue(mDisplayDeviceConfig.isAutoBrightnessAvailable());
+ assertEquals(0, mDisplayDeviceConfig.getIdleStylusTimeoutMillis());
}
@Test
@@ -253,6 +254,7 @@
.getLux().intValue());
assertEquals(800, idleScreenRefreshRateTimeoutLuxThresholdPoints.get(1)
.getTimeout().intValue());
+ assertEquals(1000, mDisplayDeviceConfig.getIdleStylusTimeoutMillis());
}
@Test
@@ -1479,6 +1481,7 @@
+ "</point>\n"
+ "</map>\n"
+ "</luxToBrightnessMapping>\n"
+ + "<idleStylusTimeoutMillis>1000</idleStylusTimeoutMillis>\n"
+ "</autoBrightness>\n"
+ getPowerThrottlingConfig()
+ "<highBrightnessMode enabled=\"true\">\n"