Merge "Add display specific brightness configurations" into sc-v2-dev

This commit is contained in:
Fiona Campbell
2021-08-17 10:08:57 +00:00
committed by Android (Google) Code Review
12 changed files with 432 additions and 55 deletions

View File

@@ -3262,11 +3262,13 @@ package android.hardware.display {
public final class DisplayManager { public final class DisplayManager {
method @RequiresPermission(android.Manifest.permission.ACCESS_AMBIENT_LIGHT_STATS) public java.util.List<android.hardware.display.AmbientBrightnessDayStats> getAmbientBrightnessStats(); method @RequiresPermission(android.Manifest.permission.ACCESS_AMBIENT_LIGHT_STATS) public java.util.List<android.hardware.display.AmbientBrightnessDayStats> getAmbientBrightnessStats();
method @RequiresPermission(android.Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS) public android.hardware.display.BrightnessConfiguration getBrightnessConfiguration(); method @RequiresPermission(android.Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS) public android.hardware.display.BrightnessConfiguration getBrightnessConfiguration();
method @Nullable @RequiresPermission(android.Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS) public android.hardware.display.BrightnessConfiguration getBrightnessConfigurationForDisplay(@NonNull String);
method @RequiresPermission(android.Manifest.permission.BRIGHTNESS_SLIDER_USAGE) public java.util.List<android.hardware.display.BrightnessChangeEvent> getBrightnessEvents(); method @RequiresPermission(android.Manifest.permission.BRIGHTNESS_SLIDER_USAGE) public java.util.List<android.hardware.display.BrightnessChangeEvent> getBrightnessEvents();
method @Nullable @RequiresPermission(android.Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS) public android.hardware.display.BrightnessConfiguration getDefaultBrightnessConfiguration(); method @Nullable @RequiresPermission(android.Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS) public android.hardware.display.BrightnessConfiguration getDefaultBrightnessConfiguration();
method public android.util.Pair<float[],float[]> getMinimumBrightnessCurve(); method public android.util.Pair<float[],float[]> getMinimumBrightnessCurve();
method public android.graphics.Point getStableDisplaySize(); method public android.graphics.Point getStableDisplaySize();
method @RequiresPermission(android.Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS) public void setBrightnessConfiguration(android.hardware.display.BrightnessConfiguration); method @RequiresPermission(android.Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS) public void setBrightnessConfiguration(android.hardware.display.BrightnessConfiguration);
method @RequiresPermission(android.Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS) public void setBrightnessConfigurationForDisplay(@NonNull android.hardware.display.BrightnessConfiguration, @NonNull String);
method @Deprecated @RequiresPermission(android.Manifest.permission.CONTROL_DISPLAY_SATURATION) public void setSaturationLevel(float); method @Deprecated @RequiresPermission(android.Manifest.permission.CONTROL_DISPLAY_SATURATION) public void setSaturationLevel(float);
} }

View File

@@ -939,6 +939,34 @@ public final class DisplayManager {
setBrightnessConfigurationForUser(c, mContext.getUserId(), mContext.getPackageName()); setBrightnessConfigurationForUser(c, mContext.getUserId(), mContext.getPackageName());
} }
/**
* Sets the brightness configuration for the specified display.
* If the specified display doesn't exist, then this will return and do nothing.
*
* @hide
*/
@SystemApi
@RequiresPermission(Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS)
public void setBrightnessConfigurationForDisplay(@NonNull BrightnessConfiguration c,
@NonNull String uniqueId) {
mGlobal.setBrightnessConfigurationForDisplay(c, uniqueId, mContext.getUserId(),
mContext.getPackageName());
}
/**
* Gets the brightness configuration for the specified display and default user.
* Returns the default configuration if unset or display is invalid.
*
* @hide
*/
@Nullable
@SystemApi
@RequiresPermission(Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS)
public BrightnessConfiguration getBrightnessConfigurationForDisplay(
@NonNull String uniqueId) {
return mGlobal.getBrightnessConfigurationForDisplay(uniqueId, mContext.getUserId());
}
/** /**
* Sets the global display brightness configuration for a specific user. * Sets the global display brightness configuration for a specific user.
* *

View File

@@ -704,6 +704,34 @@ public final class DisplayManagerGlobal {
} }
} }
/**
* Sets the brightness configuration for a given display.
*
* @hide
*/
public void setBrightnessConfigurationForDisplay(BrightnessConfiguration c,
String uniqueDisplayId, int userId, String packageName) {
try {
mDm.setBrightnessConfigurationForDisplay(c, uniqueDisplayId, userId, packageName);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
/**
* Gets the brightness configuration for a given display or null if one hasn't been set.
*
* @hide
*/
public BrightnessConfiguration getBrightnessConfigurationForDisplay(String uniqueDisplayId,
int userId) {
try {
return mDm.getBrightnessConfigurationForDisplay(uniqueDisplayId, userId);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
/** /**
* Gets the global brightness configuration for a given user or null if one hasn't been set. * Gets the global brightness configuration for a given user or null if one hasn't been set.
* *

View File

@@ -118,6 +118,16 @@ interface IDisplayManager {
void setBrightnessConfigurationForUser(in BrightnessConfiguration c, int userId, void setBrightnessConfigurationForUser(in BrightnessConfiguration c, int userId,
String packageName); String packageName);
// Sets the global brightness configuration for a given display. Requires
// CONFIGURE_DISPLAY_BRIGHTNESS.
void setBrightnessConfigurationForDisplay(in BrightnessConfiguration c, String uniqueDisplayId,
int userId, String packageName);
// Gets the brightness configuration for a given display. Requires
// CONFIGURE_DISPLAY_BRIGHTNESS.
BrightnessConfiguration getBrightnessConfigurationForDisplay(String uniqueDisplayId,
int userId);
// Gets the global brightness configuration for a given user. Requires // Gets the global brightness configuration for a given user. Requires
// CONFIGURE_DISPLAY_BRIGHTNESS, and INTERACT_ACROSS_USER if the user is not // CONFIGURE_DISPLAY_BRIGHTNESS, and INTERACT_ACROSS_USER if the user is not
// the same as the calling user. // the same as the calling user.

View File

@@ -123,6 +123,17 @@ class DisplayDeviceRepository implements DisplayAdapter.Listener {
return null; return null;
} }
// String uniqueId -> DisplayDevice object with that given uniqueId
public DisplayDevice getByUniqueIdLocked(@NonNull String uniqueId) {
for (int i = mDisplayDevices.size() - 1; i >= 0; i--) {
final DisplayDevice displayDevice = mDisplayDevices.get(i);
if (displayDevice.getUniqueId().equals(uniqueId)) {
return displayDevice;
}
}
return null;
}
private void handleDisplayDeviceAdded(DisplayDevice device) { private void handleDisplayDeviceAdded(DisplayDevice device) {
synchronized (mSyncRoot) { synchronized (mSyncRoot) {
DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();

View File

@@ -197,7 +197,7 @@ public final class DisplayManagerService extends SystemService {
private static final int MSG_DELIVER_DISPLAY_EVENT = 3; private static final int MSG_DELIVER_DISPLAY_EVENT = 3;
private static final int MSG_REQUEST_TRAVERSAL = 4; private static final int MSG_REQUEST_TRAVERSAL = 4;
private static final int MSG_UPDATE_VIEWPORT = 5; private static final int MSG_UPDATE_VIEWPORT = 5;
private static final int MSG_LOAD_BRIGHTNESS_CONFIGURATION = 6; private static final int MSG_LOAD_BRIGHTNESS_CONFIGURATIONS = 6;
private static final int MSG_DELIVER_DISPLAY_EVENT_FRAME_RATE_OVERRIDE = 7; private static final int MSG_DELIVER_DISPLAY_EVENT_FRAME_RATE_OVERRIDE = 7;
private static final int MSG_DELIVER_DISPLAY_GROUP_EVENT = 8; private static final int MSG_DELIVER_DISPLAY_GROUP_EVENT = 8;
@@ -523,16 +523,29 @@ public final class DisplayManagerService extends SystemService {
final int newUserId = to.getUserIdentifier(); final int newUserId = to.getUserIdentifier();
final int userSerial = getUserManager().getUserSerialNumber(newUserId); final int userSerial = getUserManager().getUserSerialNumber(newUserId);
synchronized (mSyncRoot) { synchronized (mSyncRoot) {
final DisplayPowerController displayPowerController = mDisplayPowerControllers.get( boolean userSwitching = mCurrentUserId != newUserId;
Display.DEFAULT_DISPLAY); if (userSwitching) {
if (mCurrentUserId != newUserId) {
mCurrentUserId = newUserId; mCurrentUserId = newUserId;
BrightnessConfiguration config =
mPersistentDataStore.getBrightnessConfiguration(userSerial);
displayPowerController.setBrightnessConfiguration(config);
handleSettingsChange();
} }
displayPowerController.onSwitchUser(newUserId); mLogicalDisplayMapper.forEachLocked(logicalDisplay -> {
if (logicalDisplay.getDisplayInfoLocked().type != Display.TYPE_INTERNAL) {
return;
}
final DisplayPowerController dpc = mDisplayPowerControllers.get(
logicalDisplay.getDisplayIdLocked());
if (dpc == null) {
return;
}
if (userSwitching) {
BrightnessConfiguration config =
getBrightnessConfigForDisplayWithPdsFallbackLocked(
logicalDisplay.getPrimaryDisplayDeviceLocked().getUniqueId(),
userSerial);
dpc.setBrightnessConfiguration(config);
}
dpc.onSwitchUser(newUserId);
});
handleSettingsChange();
} }
} }
@@ -1316,6 +1329,13 @@ public final class DisplayManagerService extends SystemService {
if (work != null) { if (work != null) {
mHandler.post(work); mHandler.post(work);
} }
final int displayId = display.getDisplayIdLocked();
DisplayPowerController dpc = mDisplayPowerControllers.get(displayId);
if (dpc != null) {
dpc.onDisplayChanged();
}
mPersistentDataStore.saveIfNeeded();
mHandler.sendEmptyMessage(MSG_LOAD_BRIGHTNESS_CONFIGURATIONS);
handleLogicalDisplayChangedLocked(display); handleLogicalDisplayChangedLocked(display);
} }
@@ -1424,24 +1444,42 @@ public final class DisplayManagerService extends SystemService {
return mDisplayModeDirector.getModeSwitchingType(); return mDisplayModeDirector.getModeSwitchingType();
} }
private void setBrightnessConfigurationForUserInternal( private void setBrightnessConfigurationForDisplayInternal(
@Nullable BrightnessConfiguration c, @UserIdInt int userId, @Nullable BrightnessConfiguration c, String uniqueId, @UserIdInt int userId,
@Nullable String packageName) { String packageName) {
validateBrightnessConfiguration(c); validateBrightnessConfiguration(c);
final int userSerial = getUserManager().getUserSerialNumber(userId); final int userSerial = getUserManager().getUserSerialNumber(userId);
synchronized (mSyncRoot) { synchronized (mSyncRoot) {
try { try {
mPersistentDataStore.setBrightnessConfigurationForUser(c, userSerial, DisplayDevice displayDevice = mDisplayDeviceRepo.getByUniqueIdLocked(uniqueId);
packageName); if (displayDevice == null) {
return;
}
mPersistentDataStore.setBrightnessConfigurationForDisplayLocked(c, displayDevice,
userSerial, packageName);
} finally { } finally {
mPersistentDataStore.saveIfNeeded(); mPersistentDataStore.saveIfNeeded();
} }
if (userId == mCurrentUserId) { if (userId != mCurrentUserId) {
mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY).setBrightnessConfiguration(c); return;
}
DisplayPowerController dpc = getDpcFromUniqueIdLocked(uniqueId);
if (dpc != null) {
dpc.setBrightnessConfiguration(c);
} }
} }
} }
private DisplayPowerController getDpcFromUniqueIdLocked(String uniqueId) {
final DisplayDevice displayDevice = mDisplayDeviceRepo.getByUniqueIdLocked(uniqueId);
final LogicalDisplay logicalDisplay = mLogicalDisplayMapper.getDisplayLocked(displayDevice);
if (logicalDisplay != null) {
final int displayId = logicalDisplay.getDisplayIdLocked();
return mDisplayPowerControllers.get(displayId);
}
return null;
}
@VisibleForTesting @VisibleForTesting
void validateBrightnessConfiguration(BrightnessConfiguration config) { void validateBrightnessConfiguration(BrightnessConfiguration config) {
if (config == null) { if (config == null) {
@@ -1464,13 +1502,22 @@ public final class DisplayManagerService extends SystemService {
return false; return false;
} }
private void loadBrightnessConfiguration() { private void loadBrightnessConfigurations() {
int userSerial = getUserManager().getUserSerialNumber(mContext.getUserId());
synchronized (mSyncRoot) { synchronized (mSyncRoot) {
final int userSerial = getUserManager().getUserSerialNumber(mCurrentUserId); mLogicalDisplayMapper.forEachLocked((logicalDisplay) -> {
BrightnessConfiguration config = final String uniqueId =
mPersistentDataStore.getBrightnessConfiguration(userSerial); logicalDisplay.getPrimaryDisplayDeviceLocked().getUniqueId();
mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY).setBrightnessConfiguration( final BrightnessConfiguration config =
config); getBrightnessConfigForDisplayWithPdsFallbackLocked(uniqueId, userSerial);
if (config != null) {
final DisplayPowerController dpc = mDisplayPowerControllers.get(
logicalDisplay.getDisplayIdLocked());
if (dpc != null) {
dpc.setBrightnessConfiguration(config);
}
}
});
} }
} }
@@ -1681,9 +1728,17 @@ public final class DisplayManagerService extends SystemService {
return SurfaceControl.getDisplayedContentSample(token, maxFrames, timestamp); return SurfaceControl.getDisplayedContentSample(token, maxFrames, timestamp);
} }
void resetBrightnessConfiguration() { void resetBrightnessConfigurations() {
setBrightnessConfigurationForUserInternal(null, mContext.getUserId(), mPersistentDataStore.setBrightnessConfigurationForUser(null, mContext.getUserId(),
mContext.getPackageName()); mContext.getPackageName());
mLogicalDisplayMapper.forEachLocked((logicalDisplay -> {
if (logicalDisplay.getDisplayInfoLocked().type != Display.TYPE_INTERNAL) {
return;
}
final String uniqueId = logicalDisplay.getPrimaryDisplayDeviceLocked().getUniqueId();
setBrightnessConfigurationForDisplayInternal(null, uniqueId, mContext.getUserId(),
mContext.getPackageName());
}));
} }
void setAutoBrightnessLoggingEnabled(boolean enabled) { void setAutoBrightnessLoggingEnabled(boolean enabled) {
@@ -2132,6 +2187,18 @@ public final class DisplayManagerService extends SystemService {
return display == null ? null : display.getPrimaryDisplayDeviceLocked(); return display == null ? null : display.getPrimaryDisplayDeviceLocked();
} }
private BrightnessConfiguration getBrightnessConfigForDisplayWithPdsFallbackLocked(
String uniqueId, int userSerial) {
BrightnessConfiguration config =
mPersistentDataStore.getBrightnessConfigurationForDisplayLocked(
uniqueId, userSerial);
if (config == null) {
// Get from global configurations
config = mPersistentDataStore.getBrightnessConfiguration(userSerial);
}
return config;
}
private final class DisplayManagerHandler extends Handler { private final class DisplayManagerHandler extends Handler {
public DisplayManagerHandler(Looper looper) { public DisplayManagerHandler(Looper looper) {
super(looper, null, true /*async*/); super(looper, null, true /*async*/);
@@ -2173,8 +2240,8 @@ public final class DisplayManagerService extends SystemService {
break; break;
} }
case MSG_LOAD_BRIGHTNESS_CONFIGURATION: case MSG_LOAD_BRIGHTNESS_CONFIGURATIONS:
loadBrightnessConfiguration(); loadBrightnessConfigurations();
break; break;
case MSG_DELIVER_DISPLAY_EVENT_FRAME_RATE_OVERRIDE: case MSG_DELIVER_DISPLAY_EVENT_FRAME_RATE_OVERRIDE:
@@ -2789,6 +2856,19 @@ public final class DisplayManagerService extends SystemService {
@Override // Binder call @Override // Binder call
public void setBrightnessConfigurationForUser( public void setBrightnessConfigurationForUser(
BrightnessConfiguration c, @UserIdInt int userId, String packageName) { BrightnessConfiguration c, @UserIdInt int userId, String packageName) {
mLogicalDisplayMapper.forEachLocked(logicalDisplay -> {
if (logicalDisplay.getDisplayInfoLocked().type != Display.TYPE_INTERNAL) {
return;
}
final DisplayDevice displayDevice = logicalDisplay.getPrimaryDisplayDeviceLocked();
setBrightnessConfigurationForDisplay(c, displayDevice.getUniqueId(), userId,
packageName);
});
}
@Override // Binder call
public void setBrightnessConfigurationForDisplay(BrightnessConfiguration c,
String uniqueId, int userId, String packageName) {
mContext.enforceCallingOrSelfPermission( mContext.enforceCallingOrSelfPermission(
Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS, Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS,
"Permission required to change the display's brightness configuration"); "Permission required to change the display's brightness configuration");
@@ -2796,21 +2876,19 @@ public final class DisplayManagerService extends SystemService {
mContext.enforceCallingOrSelfPermission( mContext.enforceCallingOrSelfPermission(
Manifest.permission.INTERACT_ACROSS_USERS, Manifest.permission.INTERACT_ACROSS_USERS,
"Permission required to change the display brightness" "Permission required to change the display brightness"
+ " configuration of another user"); + " configuration of another user");
}
if (packageName != null && !validatePackageName(getCallingUid(), packageName)) {
packageName = null;
} }
final long token = Binder.clearCallingIdentity(); final long token = Binder.clearCallingIdentity();
try { try {
setBrightnessConfigurationForUserInternal(c, userId, packageName); setBrightnessConfigurationForDisplayInternal(c, uniqueId, userId, packageName);
} finally { } finally {
Binder.restoreCallingIdentity(token); Binder.restoreCallingIdentity(token);
} }
} }
@Override // Binder call @Override // Binder call
public BrightnessConfiguration getBrightnessConfigurationForUser(int userId) { public BrightnessConfiguration getBrightnessConfigurationForDisplay(String uniqueId,
int userId) {
mContext.enforceCallingOrSelfPermission( mContext.enforceCallingOrSelfPermission(
Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS, Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS,
"Permission required to read the display's brightness configuration"); "Permission required to read the display's brightness configuration");
@@ -2821,14 +2899,19 @@ public final class DisplayManagerService extends SystemService {
+ " configuration of another user"); + " configuration of another user");
} }
final long token = Binder.clearCallingIdentity(); final long token = Binder.clearCallingIdentity();
final int userSerial = getUserManager().getUserSerialNumber(userId);
try { try {
final int userSerial = getUserManager().getUserSerialNumber(userId);
synchronized (mSyncRoot) { synchronized (mSyncRoot) {
// Get from per-display configurations
BrightnessConfiguration config = BrightnessConfiguration config =
mPersistentDataStore.getBrightnessConfiguration(userSerial); getBrightnessConfigForDisplayWithPdsFallbackLocked(
uniqueId, userSerial);
if (config == null) { if (config == null) {
config = mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY) // Get default configuration
.getDefaultBrightnessConfiguration(); DisplayPowerController dpc = getDpcFromUniqueIdLocked(uniqueId);
if (dpc != null) {
config = dpc.getDefaultBrightnessConfiguration();
}
} }
return config; return config;
} }
@@ -2837,6 +2920,21 @@ public final class DisplayManagerService extends SystemService {
} }
} }
@Override // Binder call
public BrightnessConfiguration getBrightnessConfigurationForUser(int userId) {
final String uniqueId;
synchronized (mSyncRoot) {
DisplayDevice displayDevice = mLogicalDisplayMapper.getDisplayLocked(
Display.DEFAULT_DISPLAY).getPrimaryDisplayDeviceLocked();
uniqueId = displayDevice.getUniqueId();
}
return getBrightnessConfigurationForDisplay(uniqueId, userId);
}
@Override // Binder call @Override // Binder call
public BrightnessConfiguration getDefaultBrightnessConfiguration() { public BrightnessConfiguration getDefaultBrightnessConfiguration() {
mContext.enforceCallingOrSelfPermission( mContext.enforceCallingOrSelfPermission(
@@ -3105,7 +3203,7 @@ public final class DisplayManagerService extends SystemService {
initializeDisplayPowerControllersLocked(); initializeDisplayPowerControllersLocked();
} }
mHandler.sendEmptyMessage(MSG_LOAD_BRIGHTNESS_CONFIGURATION); mHandler.sendEmptyMessage(MSG_LOAD_BRIGHTNESS_CONFIGURATIONS);
} }
@Override @Override

View File

@@ -120,7 +120,7 @@ class DisplayManagerShellCommand extends ShellCommand {
} }
private int resetBrightnessConfiguration() { private int resetBrightnessConfiguration() {
mService.resetBrightnessConfiguration(); mService.resetBrightnessConfigurations();
return 0; return 0;
} }

View File

@@ -195,6 +195,9 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
} }
public LogicalDisplay getDisplayLocked(DisplayDevice device) { public LogicalDisplay getDisplayLocked(DisplayDevice device) {
if (device == null) {
return null;
}
final int count = mLogicalDisplays.size(); final int count = mLogicalDisplays.size();
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
final LogicalDisplay display = mLogicalDisplays.valueAt(i); final LogicalDisplay display = mLogicalDisplays.valueAt(i);

View File

@@ -63,6 +63,15 @@ import java.util.Objects;
* &lt;display unique-id="XXXXXXX"> * &lt;display unique-id="XXXXXXX">
* &lt;color-mode>0&lt;/color-mode> * &lt;color-mode>0&lt;/color-mode>
* &lt;brightness-value>0&lt;/brightness-value> * &lt;brightness-value>0&lt;/brightness-value>
* &lt;brightness-configurations>
* &lt;brightness-configuration user-serial="0" package-name="com.example"
* timestamp="1234">
* &lt;brightness-curve description="some text">
* &lt;brightness-point lux="0" nits="13.25"/>
* &lt;brightness-point lux="20" nits="35.94"/>
* &lt;/brightness-curve>
* &lt;/brightness-configuration>
* &lt;/brightness-configurations>
* &lt;/display> * &lt;/display>
* &lt;/display-states> * &lt;/display-states>
* &lt;stable-device-values> * &lt;stable-device-values>
@@ -120,7 +129,8 @@ final class PersistentDataStore {
private final StableDeviceValues mStableDeviceValues = new StableDeviceValues(); private final StableDeviceValues mStableDeviceValues = new StableDeviceValues();
// Brightness configuration by user // Brightness configuration by user
private BrightnessConfigurations mBrightnessConfigurations = new BrightnessConfigurations(); private BrightnessConfigurations mGlobalBrightnessConfigurations =
new BrightnessConfigurations();
// True if the data has been loaded. // True if the data has been loaded.
private boolean mLoaded; private boolean mLoaded;
@@ -293,18 +303,44 @@ final class PersistentDataStore {
} }
} }
// Used for testing & reset
public void setBrightnessConfigurationForUser(BrightnessConfiguration c, int userSerial, public void setBrightnessConfigurationForUser(BrightnessConfiguration c, int userSerial,
@Nullable String packageName) { @Nullable String packageName) {
loadIfNeeded(); loadIfNeeded();
if (mBrightnessConfigurations.setBrightnessConfigurationForUser(c, userSerial, if (mGlobalBrightnessConfigurations.setBrightnessConfigurationForUser(c, userSerial,
packageName)) { packageName)) {
setDirty(); setDirty();
} }
} }
public boolean setBrightnessConfigurationForDisplayLocked(BrightnessConfiguration configuration,
DisplayDevice device, int userSerial, String packageName) {
if (device == null || !device.hasStableUniqueId()) {
return false;
}
DisplayState state = getDisplayState(device.getUniqueId(), /*createIfAbsent*/ true);
if (state.setBrightnessConfiguration(configuration, userSerial, packageName)) {
setDirty();
return true;
}
return false;
}
public BrightnessConfiguration getBrightnessConfigurationForDisplayLocked(
String uniqueDisplayId, int userSerial) {
loadIfNeeded();
DisplayState state = mDisplayStates.get(uniqueDisplayId);
if (state != null) {
return state.getBrightnessConfiguration(userSerial);
}
return null;
}
public BrightnessConfiguration getBrightnessConfiguration(int userSerial) { public BrightnessConfiguration getBrightnessConfiguration(int userSerial) {
loadIfNeeded(); loadIfNeeded();
return mBrightnessConfigurations.getBrightnessConfiguration(userSerial); return mGlobalBrightnessConfigurations.getBrightnessConfiguration(userSerial);
} }
private DisplayState getDisplayState(String uniqueId, boolean createIfAbsent) { private DisplayState getDisplayState(String uniqueId, boolean createIfAbsent) {
@@ -391,7 +427,7 @@ final class PersistentDataStore {
mStableDeviceValues.loadFromXml(parser); mStableDeviceValues.loadFromXml(parser);
} }
if (parser.getName().equals(TAG_BRIGHTNESS_CONFIGURATIONS)) { if (parser.getName().equals(TAG_BRIGHTNESS_CONFIGURATIONS)) {
mBrightnessConfigurations.loadFromXml(parser); mGlobalBrightnessConfigurations.loadFromXml(parser);
} }
} }
} }
@@ -470,7 +506,7 @@ final class PersistentDataStore {
mStableDeviceValues.saveToXml(serializer); mStableDeviceValues.saveToXml(serializer);
serializer.endTag(null, TAG_STABLE_DEVICE_VALUES); serializer.endTag(null, TAG_STABLE_DEVICE_VALUES);
serializer.startTag(null, TAG_BRIGHTNESS_CONFIGURATIONS); serializer.startTag(null, TAG_BRIGHTNESS_CONFIGURATIONS);
mBrightnessConfigurations.saveToXml(serializer); mGlobalBrightnessConfigurations.saveToXml(serializer);
serializer.endTag(null, TAG_BRIGHTNESS_CONFIGURATIONS); serializer.endTag(null, TAG_BRIGHTNESS_CONFIGURATIONS);
serializer.endTag(null, TAG_DISPLAY_MANAGER_STATE); serializer.endTag(null, TAG_DISPLAY_MANAGER_STATE);
serializer.endDocument(); serializer.endDocument();
@@ -493,14 +529,18 @@ final class PersistentDataStore {
} }
pw.println(" StableDeviceValues:"); pw.println(" StableDeviceValues:");
mStableDeviceValues.dump(pw, " "); mStableDeviceValues.dump(pw, " ");
pw.println(" BrightnessConfigurations:"); pw.println(" GlobalBrightnessConfigurations:");
mBrightnessConfigurations.dump(pw, " "); mGlobalBrightnessConfigurations.dump(pw, " ");
} }
private static final class DisplayState { private static final class DisplayState {
private int mColorMode; private int mColorMode;
private float mBrightness; private float mBrightness;
// Brightness configuration by user
private BrightnessConfigurations mDisplayBrightnessConfigurations =
new BrightnessConfigurations();
public boolean setColorMode(int colorMode) { public boolean setColorMode(int colorMode) {
if (colorMode == mColorMode) { if (colorMode == mColorMode) {
return false; return false;
@@ -525,6 +565,16 @@ final class PersistentDataStore {
return mBrightness; return mBrightness;
} }
public boolean setBrightnessConfiguration(BrightnessConfiguration configuration,
int userSerial, String packageName) {
mDisplayBrightnessConfigurations.setBrightnessConfigurationForUser(
configuration, userSerial, packageName);
return true;
}
public BrightnessConfiguration getBrightnessConfiguration(int userSerial) {
return mDisplayBrightnessConfigurations.mConfigurations.get(userSerial);
}
public void loadFromXml(TypedXmlPullParser parser) public void loadFromXml(TypedXmlPullParser parser)
throws IOException, XmlPullParserException { throws IOException, XmlPullParserException {
@@ -540,6 +590,9 @@ final class PersistentDataStore {
String brightness = parser.nextText(); String brightness = parser.nextText();
mBrightness = Float.parseFloat(brightness); mBrightness = Float.parseFloat(brightness);
break; break;
case TAG_BRIGHTNESS_CONFIGURATIONS:
mDisplayBrightnessConfigurations.loadFromXml(parser);
break;
} }
} }
} }
@@ -548,15 +601,21 @@ final class PersistentDataStore {
serializer.startTag(null, TAG_COLOR_MODE); serializer.startTag(null, TAG_COLOR_MODE);
serializer.text(Integer.toString(mColorMode)); serializer.text(Integer.toString(mColorMode));
serializer.endTag(null, TAG_COLOR_MODE); serializer.endTag(null, TAG_COLOR_MODE);
serializer.startTag(null, TAG_BRIGHTNESS_VALUE); serializer.startTag(null, TAG_BRIGHTNESS_VALUE);
serializer.text(Float.toString(mBrightness)); serializer.text(Float.toString(mBrightness));
serializer.endTag(null, TAG_BRIGHTNESS_VALUE); serializer.endTag(null, TAG_BRIGHTNESS_VALUE);
serializer.startTag(null, TAG_BRIGHTNESS_CONFIGURATIONS);
mDisplayBrightnessConfigurations.saveToXml(serializer);
serializer.endTag(null, TAG_BRIGHTNESS_CONFIGURATIONS);
} }
public void dump(final PrintWriter pw, final String prefix) { public void dump(final PrintWriter pw, final String prefix) {
pw.println(prefix + "ColorMode=" + mColorMode); pw.println(prefix + "ColorMode=" + mColorMode);
pw.println(prefix + "BrightnessValue=" + mBrightness); pw.println(prefix + "BrightnessValue=" + mBrightness);
pw.println(prefix + "DisplayBrightnessConfigurations: ");
mDisplayBrightnessConfigurations.dump(pw, prefix);
} }
} }
@@ -621,11 +680,11 @@ final class PersistentDataStore {
private static final class BrightnessConfigurations { private static final class BrightnessConfigurations {
// Maps from a user ID to the users' given brightness configuration // Maps from a user ID to the users' given brightness configuration
private SparseArray<BrightnessConfiguration> mConfigurations; private final SparseArray<BrightnessConfiguration> mConfigurations;
// Timestamp of time the configuration was set. // Timestamp of time the configuration was set.
private SparseLongArray mTimeStamps; private final SparseLongArray mTimeStamps;
// Package that set the configuration. // Package that set the configuration.
private SparseArray<String> mPackageNames; private final SparseArray<String> mPackageNames;
public BrightnessConfigurations() { public BrightnessConfigurations() {
mConfigurations = new SparseArray<>(); mConfigurations = new SparseArray<>();

View File

@@ -71,6 +71,7 @@
<uses-permission android:name="android.permission.MANAGE_BIND_INSTANT_SERVICE"/> <uses-permission android:name="android.permission.MANAGE_BIND_INSTANT_SERVICE"/>
<uses-permission android:name="android.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS"/> <uses-permission android:name="android.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS"/>
<uses-permission android:name="android.permission.CONTROL_DISPLAY_BRIGHTNESS"/> <uses-permission android:name="android.permission.CONTROL_DISPLAY_BRIGHTNESS"/>
<uses-permission android:name="android.permission.CONFIGURE_DISPLAY_BRIGHTNESS"/>
<uses-permission android:name="android.permission.READ_DEVICE_CONFIG"/> <uses-permission android:name="android.permission.READ_DEVICE_CONFIG"/>
<uses-permission android:name="android.permission.WRITE_DEVICE_CONFIG"/> <uses-permission android:name="android.permission.WRITE_DEVICE_CONFIG"/>
<uses-permission android:name="android.permission.HARDWARE_TEST"/> <uses-permission android:name="android.permission.HARDWARE_TEST"/>

View File

@@ -885,6 +885,61 @@ public class DisplayManagerServiceTest {
assertFalse(callback.mDisplayAddedCalled); assertFalse(callback.mDisplayAddedCalled);
} }
@Test
public void testSettingTwoBrightnessConfigurationsOnMultiDisplay() {
Context mContext = InstrumentationRegistry.getInstrumentation().getContext();
DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
// get the first two internal displays
Display[] displays = displayManager.getDisplays();
Display internalDisplayOne = null;
Display internalDisplayTwo = null;
for (Display display : displays) {
if (display.getType() == Display.TYPE_INTERNAL) {
if (internalDisplayOne == null) {
internalDisplayOne = display;
} else {
internalDisplayTwo = display;
break;
}
}
}
// return if there are fewer than 2 displays on this device
if (internalDisplayOne == null || internalDisplayTwo == null) {
return;
}
final String uniqueDisplayIdOne = internalDisplayOne.getUniqueId();
final String uniqueDisplayIdTwo = internalDisplayTwo.getUniqueId();
BrightnessConfiguration configOne =
new BrightnessConfiguration.Builder(
new float[]{0.0f, 12345.0f}, new float[]{15.0f, 400.0f})
.setDescription("model:1").build();
BrightnessConfiguration configTwo =
new BrightnessConfiguration.Builder(
new float[]{0.0f, 6789.0f}, new float[]{12.0f, 300.0f})
.setDescription("model:2").build();
displayManager.setBrightnessConfigurationForDisplay(configOne,
uniqueDisplayIdOne);
displayManager.setBrightnessConfigurationForDisplay(configTwo,
uniqueDisplayIdTwo);
BrightnessConfiguration configFromOne =
displayManager.getBrightnessConfigurationForDisplay(uniqueDisplayIdOne);
BrightnessConfiguration configFromTwo =
displayManager.getBrightnessConfigurationForDisplay(uniqueDisplayIdTwo);
assertNotNull(configFromOne);
assertEquals(configOne, configFromOne);
assertEquals(configTwo, configFromTwo);
}
private void testDisplayInfoFrameRateOverrideModeCompat(boolean compatChangeEnabled) private void testDisplayInfoFrameRateOverrideModeCompat(boolean compatChangeEnabled)
throws Exception { throws Exception {
DisplayManagerService displayManager = DisplayManagerService displayManager =

View File

@@ -17,13 +17,16 @@
package com.android.server.display; package com.android.server.display;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import android.content.Context;
import android.hardware.display.BrightnessConfiguration; import android.hardware.display.BrightnessConfiguration;
import android.util.Pair; import android.util.Pair;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4; import androidx.test.runner.AndroidJUnit4;
@@ -144,15 +147,93 @@ public class PersistentDataStoreTest {
} }
@Test @Test
public void testStoreAndReloadOfBrightnessConfigurations() { public void testStoreAndReloadOfDisplayBrightnessConfigurations() {
final String uniqueDisplayId = "test:123";
int userSerial = 0;
String packageName = "pdsTestPackage";
final float[] lux = { 0f, 10f }; final float[] lux = { 0f, 10f };
final float[] nits = {1f, 100f }; final float[] nits = {1f, 100f };
final BrightnessConfiguration config = new BrightnessConfiguration.Builder(lux, nits) final BrightnessConfiguration config = new BrightnessConfiguration.Builder(lux, nits)
.setDescription("a description") .setDescription("a description")
.build(); .build();
mDataStore.loadIfNeeded();
assertNull(mDataStore.getBrightnessConfigurationForDisplayLocked(uniqueDisplayId,
userSerial));
DisplayDevice testDisplayDevice = new DisplayDevice(null, null, uniqueDisplayId, null) {
@Override
public boolean hasStableUniqueId() {
return true;
}
@Override
public DisplayDeviceInfo getDisplayDeviceInfoLocked() {
return null;
}
};
mDataStore.setBrightnessConfigurationForDisplayLocked(config, testDisplayDevice, userSerial,
packageName);
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
mInjector.setWriteStream(baos);
mDataStore.saveIfNeeded();
assertTrue(mInjector.wasWriteSuccessful());
TestInjector newInjector = new TestInjector();
PersistentDataStore newDataStore = new PersistentDataStore(newInjector);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
newInjector.setReadStream(bais);
newDataStore.loadIfNeeded();
assertNotNull(newDataStore.getBrightnessConfigurationForDisplayLocked(uniqueDisplayId,
userSerial));
assertEquals(mDataStore.getBrightnessConfigurationForDisplayLocked(uniqueDisplayId,
userSerial), newDataStore.getBrightnessConfigurationForDisplayLocked(
uniqueDisplayId, userSerial));
}
@Test
public void testSetBrightnessConfigurationFailsWithUnstableId() {
final String uniqueDisplayId = "test:123";
int userSerial = 0;
String packageName = "pdsTestPackage";
final float[] lux = { 0f, 10f };
final float[] nits = {1f, 100f };
final BrightnessConfiguration config = new BrightnessConfiguration.Builder(lux, nits)
.setDescription("a description")
.build();
mDataStore.loadIfNeeded();
assertNull(mDataStore.getBrightnessConfigurationForDisplayLocked(uniqueDisplayId,
userSerial));
DisplayDevice testDisplayDevice = new DisplayDevice(null, null, uniqueDisplayId, null) {
@Override
public boolean hasStableUniqueId() {
return false;
}
@Override
public DisplayDeviceInfo getDisplayDeviceInfoLocked() {
return null;
}
};
assertFalse(mDataStore.setBrightnessConfigurationForDisplayLocked(
config, testDisplayDevice, userSerial, packageName));
}
@Test
public void testStoreAndReloadOfBrightnessConfigurations() {
final float[] lux = { 0f, 10f };
final float[] nits = {1f, 100f };
final BrightnessConfiguration config = new BrightnessConfiguration.Builder(lux, nits)
.setDescription("a description")
.build();
Context context = InstrumentationRegistry.getInstrumentation().getContext();
String packageName = context.getPackageName();
mDataStore.loadIfNeeded(); mDataStore.loadIfNeeded();
assertNull(mDataStore.getBrightnessConfiguration(0 /*userSerial*/)); assertNull(mDataStore.getBrightnessConfiguration(0 /*userSerial*/));
mDataStore.setBrightnessConfigurationForUser(config, 0, "packagename"); mDataStore.setBrightnessConfigurationForUser(config, 0, packageName);
final ByteArrayOutputStream baos = new ByteArrayOutputStream(); final ByteArrayOutputStream baos = new ByteArrayOutputStream();
mInjector.setWriteStream(baos); mInjector.setWriteStream(baos);
@@ -173,17 +254,18 @@ public class PersistentDataStoreTest {
public void testNullBrightnessConfiguration() { public void testNullBrightnessConfiguration() {
final float[] lux = { 0f, 10f }; final float[] lux = { 0f, 10f };
final float[] nits = {1f, 100f }; final float[] nits = {1f, 100f };
int userSerial = 0;
final BrightnessConfiguration config = new BrightnessConfiguration.Builder(lux, nits) final BrightnessConfiguration config = new BrightnessConfiguration.Builder(lux, nits)
.setDescription("a description") .setDescription("a description")
.build(); .build();
mDataStore.loadIfNeeded(); mDataStore.loadIfNeeded();
assertNull(mDataStore.getBrightnessConfiguration(0 /*userSerial*/)); assertNull(mDataStore.getBrightnessConfiguration(userSerial));
mDataStore.setBrightnessConfigurationForUser(config, 0, "packagename"); mDataStore.setBrightnessConfigurationForUser(config, userSerial, "packagename");
assertNotNull(mDataStore.getBrightnessConfiguration(0 /*userSerial*/)); assertNotNull(mDataStore.getBrightnessConfiguration(userSerial));
mDataStore.setBrightnessConfigurationForUser(null, 0, "packagename"); mDataStore.setBrightnessConfigurationForUser(null, userSerial, "packagename");
assertNull(mDataStore.getBrightnessConfiguration(0 /*userSerial*/)); assertNull(mDataStore.getBrightnessConfiguration(userSerial));
} }
public class TestInjector extends PersistentDataStore.Injector { public class TestInjector extends PersistentDataStore.Injector {