Merge "Runtime resolution changes"
This commit is contained in:
@@ -1147,15 +1147,15 @@ package android.hardware.display {
|
||||
|
||||
public final class DisplayManager {
|
||||
method public boolean areUserDisabledHdrTypesAllowed();
|
||||
method @RequiresPermission(android.Manifest.permission.MODIFY_USER_PREFERRED_DISPLAY_MODE) public void clearUserPreferredDisplayMode();
|
||||
method @RequiresPermission(android.Manifest.permission.MODIFY_USER_PREFERRED_DISPLAY_MODE) public void clearGlobalUserPreferredDisplayMode();
|
||||
method @Nullable public android.view.Display.Mode getGlobalUserPreferredDisplayMode();
|
||||
method @NonNull public int[] getUserDisabledHdrTypes();
|
||||
method @Nullable public android.view.Display.Mode getUserPreferredDisplayMode();
|
||||
method public boolean isMinimalPostProcessingRequested(int);
|
||||
method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setAreUserDisabledHdrTypesAllowed(boolean);
|
||||
method @RequiresPermission(android.Manifest.permission.MODIFY_USER_PREFERRED_DISPLAY_MODE) public void setGlobalUserPreferredDisplayMode(@NonNull android.view.Display.Mode);
|
||||
method @RequiresPermission(android.Manifest.permission.MODIFY_REFRESH_RATE_SWITCHING_TYPE) public void setRefreshRateSwitchingType(int);
|
||||
method @RequiresPermission(android.Manifest.permission.OVERRIDE_DISPLAY_MODE_REQUESTS) public void setShouldAlwaysRespectAppRequestedMode(boolean);
|
||||
method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setUserDisabledHdrTypes(@NonNull int[]);
|
||||
method @RequiresPermission(android.Manifest.permission.MODIFY_USER_PREFERRED_DISPLAY_MODE) public void setUserPreferredDisplayMode(@NonNull android.view.Display.Mode);
|
||||
method @RequiresPermission(android.Manifest.permission.OVERRIDE_DISPLAY_MODE_REQUESTS) public boolean shouldAlwaysRespectAppRequestedMode();
|
||||
field public static final int SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS = 2; // 0x2
|
||||
field public static final int SWITCHING_TYPE_NONE = 0; // 0x0
|
||||
@@ -2714,11 +2714,14 @@ package android.view {
|
||||
}
|
||||
|
||||
public final class Display {
|
||||
method @RequiresPermission(android.Manifest.permission.MODIFY_USER_PREFERRED_DISPLAY_MODE) public void clearUserPreferredDisplayMode();
|
||||
method @NonNull public android.view.Display.Mode getDefaultMode();
|
||||
method @NonNull public int[] getReportedHdrTypes();
|
||||
method @NonNull public android.graphics.ColorSpace[] getSupportedWideColorGamut();
|
||||
method public int getType();
|
||||
method @Nullable public android.view.Display.Mode getUserPreferredDisplayMode();
|
||||
method public boolean hasAccess(int);
|
||||
method @RequiresPermission(android.Manifest.permission.MODIFY_USER_PREFERRED_DISPLAY_MODE) public void setUserPreferredDisplayMode(@NonNull android.view.Display.Mode);
|
||||
field public static final int FLAG_TRUSTED = 128; // 0x80
|
||||
field public static final int TYPE_EXTERNAL = 2; // 0x2
|
||||
field public static final int TYPE_INTERNAL = 1; // 0x1
|
||||
@@ -2733,6 +2736,13 @@ package android.view {
|
||||
method public boolean matches(int, int, float);
|
||||
}
|
||||
|
||||
public static final class Display.Mode.Builder {
|
||||
ctor public Display.Mode.Builder();
|
||||
method @NonNull public android.view.Display.Mode build();
|
||||
method @NonNull public android.view.Display.Mode.Builder setRefreshRate(float);
|
||||
method @NonNull public android.view.Display.Mode.Builder setResolution(int, int);
|
||||
}
|
||||
|
||||
public class FocusFinder {
|
||||
method public static void sort(android.view.View[], int, int, android.view.ViewGroup, boolean);
|
||||
}
|
||||
|
||||
@@ -737,6 +737,8 @@ MissingGetterMatchingBuilder: android.telephony.ims.stub.ImsFeatureConfiguration
|
||||
|
||||
MissingGetterMatchingBuilder: android.telephony.mbms.DownloadRequest.Builder#setServiceId(String):
|
||||
|
||||
MissingGetterMatchingBuilder: android.view.Display.Mode.Builder#setResolution(int, int):
|
||||
android.view.Display.Mode does not declare a `getResolution()` method matching method android.view.Display.Mode.Builder.setResolution(int,int)
|
||||
|
||||
|
||||
MissingNullability: android.app.Activity#onMovedToDisplay(int, android.content.res.Configuration) parameter #1:
|
||||
|
||||
@@ -1132,41 +1132,48 @@ public final class DisplayManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the default display mode, according to the refresh rate and the resolution chosen by the
|
||||
* user.
|
||||
* Sets the global default {@link Display.Mode}. The display mode includes preference for
|
||||
* resolution and refresh rate. The mode change is applied globally, i.e. to all the connected
|
||||
* displays. If the mode specified is not supported by a connected display, then no mode change
|
||||
* occurs for that display.
|
||||
*
|
||||
* @param mode The {@link Display.Mode} to set, which can include resolution and/or
|
||||
* refresh-rate. It is created using {@link Display.Mode.Builder}.
|
||||
*`
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
@RequiresPermission(Manifest.permission.MODIFY_USER_PREFERRED_DISPLAY_MODE)
|
||||
public void setUserPreferredDisplayMode(@NonNull Display.Mode mode) {
|
||||
public void setGlobalUserPreferredDisplayMode(@NonNull Display.Mode mode) {
|
||||
// Create a new object containing default values for the unused fields like mode ID and
|
||||
// alternative refresh rates.
|
||||
Display.Mode preferredMode = new Display.Mode(mode.getPhysicalWidth(),
|
||||
mode.getPhysicalHeight(), mode.getRefreshRate());
|
||||
mGlobal.setUserPreferredDisplayMode(preferredMode);
|
||||
mGlobal.setUserPreferredDisplayMode(Display.INVALID_DISPLAY, preferredMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the user preferred display mode.
|
||||
* Removes the global user preferred display mode.
|
||||
* User preferred display mode is cleared for all the connected displays.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
@RequiresPermission(Manifest.permission.MODIFY_USER_PREFERRED_DISPLAY_MODE)
|
||||
public void clearUserPreferredDisplayMode() {
|
||||
mGlobal.setUserPreferredDisplayMode(null);
|
||||
public void clearGlobalUserPreferredDisplayMode() {
|
||||
mGlobal.setUserPreferredDisplayMode(Display.INVALID_DISPLAY, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the user preferred display mode.
|
||||
* Returns the global user preferred display mode.
|
||||
* If no user preferred mode has been set, or it has been cleared, this method returns null.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
@Nullable
|
||||
public Display.Mode getUserPreferredDisplayMode() {
|
||||
return mGlobal.getUserPreferredDisplayMode();
|
||||
public Display.Mode getGlobalUserPreferredDisplayMode() {
|
||||
return mGlobal.getUserPreferredDisplayMode(Display.INVALID_DISPLAY);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -896,9 +896,9 @@ public final class DisplayManagerGlobal {
|
||||
* Sets the default display mode, according to the refresh rate and the resolution chosen by the
|
||||
* user.
|
||||
*/
|
||||
public void setUserPreferredDisplayMode(Display.Mode mode) {
|
||||
public void setUserPreferredDisplayMode(int displayId, Display.Mode mode) {
|
||||
try {
|
||||
mDm.setUserPreferredDisplayMode(mode);
|
||||
mDm.setUserPreferredDisplayMode(displayId, mode);
|
||||
} catch (RemoteException ex) {
|
||||
throw ex.rethrowFromSystemServer();
|
||||
}
|
||||
@@ -907,9 +907,9 @@ public final class DisplayManagerGlobal {
|
||||
/**
|
||||
* Returns the user preferred display mode.
|
||||
*/
|
||||
public Display.Mode getUserPreferredDisplayMode() {
|
||||
public Display.Mode getUserPreferredDisplayMode(int displayId) {
|
||||
try {
|
||||
return mDm.getUserPreferredDisplayMode();
|
||||
return mDm.getUserPreferredDisplayMode(displayId);
|
||||
} catch (RemoteException ex) {
|
||||
throw ex.rethrowFromSystemServer();
|
||||
}
|
||||
|
||||
@@ -166,8 +166,8 @@ interface IDisplayManager {
|
||||
|
||||
// Sets the user preferred display mode.
|
||||
// Requires MODIFY_USER_PREFERRED_DISPLAY_MODE permission.
|
||||
void setUserPreferredDisplayMode(in Mode mode);
|
||||
Mode getUserPreferredDisplayMode();
|
||||
void setUserPreferredDisplayMode(int displayId, in Mode mode);
|
||||
Mode getUserPreferredDisplayMode(int displayId);
|
||||
|
||||
// When enabled the app requested display resolution and refresh rate is always selected
|
||||
// in DisplayModeDirector regardless of user settings and policies for low brightness, low
|
||||
|
||||
@@ -19,6 +19,7 @@ package android.view;
|
||||
import static android.Manifest.permission.CONFIGURE_DISPLAY_COLOR_MODE;
|
||||
import static android.Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
@@ -137,6 +138,24 @@ public final class Display {
|
||||
*/
|
||||
public static final int INVALID_DISPLAY = -1;
|
||||
|
||||
/**
|
||||
* Invalid resolution width.
|
||||
* @hide
|
||||
*/
|
||||
public static final int INVALID_DISPLAY_WIDTH = -1;
|
||||
|
||||
/**
|
||||
* Invalid resolution height.
|
||||
* @hide
|
||||
*/
|
||||
public static final int INVALID_DISPLAY_HEIGHT = -1;
|
||||
|
||||
/**
|
||||
* Invalid refresh rate.
|
||||
* @hide
|
||||
*/
|
||||
public static final float INVALID_DISPLAY_REFRESH_RATE = 0.0f;
|
||||
|
||||
/**
|
||||
* The default display group id, which is the display group id of the primary display assuming
|
||||
* there is one.
|
||||
@@ -1169,6 +1188,49 @@ public final class Display {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the default {@link Display.Mode} to use for the display. The display mode includes
|
||||
* preference for resolution and refresh rate.
|
||||
* If the mode specified is not supported by the display, then no mode change occurs.
|
||||
*
|
||||
* @param mode The {@link Display.Mode} to set, which can include resolution and/or
|
||||
* refresh-rate. It is created using {@link Display.Mode.Builder}.
|
||||
*`
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
@RequiresPermission(Manifest.permission.MODIFY_USER_PREFERRED_DISPLAY_MODE)
|
||||
public void setUserPreferredDisplayMode(@NonNull Display.Mode mode) {
|
||||
// Create a new object containing default values for the unused fields like mode ID and
|
||||
// alternative refresh rates.
|
||||
Display.Mode preferredMode = new Display.Mode(mode.getPhysicalWidth(),
|
||||
mode.getPhysicalHeight(), mode.getRefreshRate());
|
||||
mGlobal.setUserPreferredDisplayMode(mDisplayId, preferredMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the display's user preferred display mode.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
@RequiresPermission(Manifest.permission.MODIFY_USER_PREFERRED_DISPLAY_MODE)
|
||||
public void clearUserPreferredDisplayMode() {
|
||||
mGlobal.setUserPreferredDisplayMode(mDisplayId, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the display's user preferred display mode.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
@Nullable
|
||||
public Display.Mode getUserPreferredDisplayMode() {
|
||||
return mGlobal.getUserPreferredDisplayMode(mDisplayId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether this display can be used to display wide color gamut content.
|
||||
* This does not necessarily mean the device itself can render wide color gamut
|
||||
@@ -1709,6 +1771,30 @@ public final class Display {
|
||||
return state == STATE_ON || state == STATE_VR || state == STATE_ON_SUSPEND;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the specified width is valid.
|
||||
* @hide
|
||||
*/
|
||||
public static boolean isWidthValid(int width) {
|
||||
return width > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the specified height is valid.
|
||||
* @hide
|
||||
*/
|
||||
public static boolean isHeightValid(int height) {
|
||||
return height > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the specified refresh-rate is valid.
|
||||
* @hide
|
||||
*/
|
||||
public static boolean isRefreshRateValid(float refreshRate) {
|
||||
return refreshRate > 0.0f;
|
||||
}
|
||||
|
||||
/**
|
||||
* A mode supported by a given display.
|
||||
*
|
||||
@@ -1845,6 +1931,30 @@ public final class Display {
|
||||
Float.floatToIntBits(mRefreshRate) == Float.floatToIntBits(refreshRate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if this mode matches the given parameters, if those parameters are
|
||||
* valid.<p>
|
||||
* If resolution (width and height) is valid and refresh-rate is not, the method matches
|
||||
* only resolution.
|
||||
* If refresh-rate is valid and resolution (width and height) is not, the method matches
|
||||
* only refresh-rate.</p>
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public boolean matchesIfValid(int width, int height, float refreshRate) {
|
||||
if (!isWidthValid(width) && !isHeightValid(height)
|
||||
&& !isRefreshRateValid(refreshRate)) {
|
||||
return false;
|
||||
}
|
||||
if (isWidthValid(width) != isHeightValid(height)) {
|
||||
return false;
|
||||
}
|
||||
return (!isWidthValid(width) || mWidth == width)
|
||||
&& (!isHeightValid(height) || mHeight == height)
|
||||
&& (!isRefreshRateValid(refreshRate)
|
||||
|| Float.floatToIntBits(mRefreshRate) == Float.floatToIntBits(refreshRate));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if this mode equals to the other mode in all parameters except
|
||||
* the refresh rate.
|
||||
@@ -1855,6 +1965,24 @@ public final class Display {
|
||||
return mWidth == other.mWidth && mHeight == other.mHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if refresh-rate is set for a display mode
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public boolean isRefreshRateSet() {
|
||||
return mRefreshRate != INVALID_DISPLAY_REFRESH_RATE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if refresh-rate is set for a display mode
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public boolean isResolutionSet() {
|
||||
return mWidth != INVALID_DISPLAY_WIDTH && mHeight != INVALID_DISPLAY_HEIGHT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object other) {
|
||||
if (this == other) {
|
||||
@@ -1923,6 +2051,80 @@ public final class Display {
|
||||
return new Mode[size];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Builder is used to create {@link Display.Mode} objects
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
public static final class Builder {
|
||||
private int mWidth;
|
||||
private int mHeight;
|
||||
private float mRefreshRate;
|
||||
|
||||
public Builder() {
|
||||
mWidth = Display.INVALID_DISPLAY_WIDTH;
|
||||
mHeight = Display.INVALID_DISPLAY_HEIGHT;
|
||||
mRefreshRate = Display.INVALID_DISPLAY_REFRESH_RATE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the resolution (width and height) of a {@link Display.Mode}
|
||||
*
|
||||
* @return Instance of {@link Builder}
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setResolution(int width, int height) {
|
||||
if (width > 0 && height > 0) {
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the refresh rate of a {@link Display.Mode}
|
||||
*
|
||||
* @return Instance of {@link Builder}
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setRefreshRate(float refreshRate) {
|
||||
if (refreshRate > 0.0f) {
|
||||
mRefreshRate = refreshRate;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the {@link Display.Mode} object.
|
||||
*
|
||||
* <p>
|
||||
* If resolution needs to be set, but refresh-rate doesn't matter, create a mode with
|
||||
* Builder and call setResolution.
|
||||
* {@code
|
||||
* Display.Mode mode =
|
||||
* new Display.Mode.Builder()
|
||||
* .setResolution(width, height)
|
||||
* .build();
|
||||
* }
|
||||
* </p><p>
|
||||
* If refresh-rate needs to be set, but resolution doesn't matter, create a mode with
|
||||
* Builder and call setRefreshRate.
|
||||
* {@code
|
||||
* Display.Mode mode =
|
||||
* new Display.Mode.Builder()
|
||||
* .setRefreshRate(refreshRate)
|
||||
* .build();
|
||||
* }
|
||||
* </p>
|
||||
*/
|
||||
@NonNull
|
||||
public Mode build() {
|
||||
Display.Mode mode = new Mode(mWidth, mHeight, mRefreshRate);
|
||||
return mode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -37,6 +37,8 @@ import java.io.PrintWriter;
|
||||
* </p>
|
||||
*/
|
||||
abstract class DisplayDevice {
|
||||
private static final Display.Mode EMPTY_DISPLAY_MODE = new Display.Mode.Builder().build();
|
||||
|
||||
private final DisplayAdapter mDisplayAdapter;
|
||||
private final IBinder mDisplayToken;
|
||||
private final String mUniqueId;
|
||||
@@ -212,6 +214,13 @@ abstract class DisplayDevice {
|
||||
*/
|
||||
public void setUserPreferredDisplayModeLocked(Display.Mode mode) { }
|
||||
|
||||
/**
|
||||
* Returns the user preferred display mode.
|
||||
*/
|
||||
public Display.Mode getUserPreferredDisplayModeLocked() {
|
||||
return EMPTY_DISPLAY_MODE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested color mode.
|
||||
*/
|
||||
|
||||
@@ -873,11 +873,11 @@ public final class DisplayManagerService extends SystemService {
|
||||
|
||||
private void updateUserPreferredDisplayModeSettingsLocked() {
|
||||
final float refreshRate = Settings.Global.getFloat(mContext.getContentResolver(),
|
||||
Settings.Global.USER_PREFERRED_REFRESH_RATE, 0.0f);
|
||||
Settings.Global.USER_PREFERRED_REFRESH_RATE, Display.INVALID_DISPLAY_REFRESH_RATE);
|
||||
final int height = Settings.Global.getInt(mContext.getContentResolver(),
|
||||
Settings.Global.USER_PREFERRED_RESOLUTION_HEIGHT, -1);
|
||||
Settings.Global.USER_PREFERRED_RESOLUTION_HEIGHT, Display.INVALID_DISPLAY_HEIGHT);
|
||||
final int width = Settings.Global.getInt(mContext.getContentResolver(),
|
||||
Settings.Global.USER_PREFERRED_RESOLUTION_WIDTH, -1);
|
||||
Settings.Global.USER_PREFERRED_RESOLUTION_WIDTH, Display.INVALID_DISPLAY_WIDTH);
|
||||
Display.Mode mode = new Display.Mode(width, height, refreshRate);
|
||||
mUserPreferredMode = isResolutionAndRefreshRateValid(mode) ? mode : null;
|
||||
}
|
||||
@@ -1560,8 +1560,11 @@ public final class DisplayManagerService extends SystemService {
|
||||
}
|
||||
if (mUserPreferredMode != null) {
|
||||
device.setUserPreferredDisplayModeLocked(mUserPreferredMode);
|
||||
} else {
|
||||
configurePreferredDisplayModeLocked(display);
|
||||
}
|
||||
addDisplayPowerControllerLocked(display);
|
||||
|
||||
mDisplayStates.append(displayId, Display.STATE_UNKNOWN);
|
||||
|
||||
final float brightnessDefault = display.getDisplayInfoLocked().brightnessDefault;
|
||||
@@ -1688,6 +1691,24 @@ public final class DisplayManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
private void configurePreferredDisplayModeLocked(LogicalDisplay display) {
|
||||
final DisplayDevice device = display.getPrimaryDisplayDeviceLocked();
|
||||
final Point userPreferredResolution =
|
||||
mPersistentDataStore.getUserPreferredResolution(device);
|
||||
final float refreshRate = mPersistentDataStore.getUserPreferredRefreshRate(device);
|
||||
if (userPreferredResolution == null && Float.isNaN(refreshRate)) {
|
||||
return;
|
||||
}
|
||||
Display.Mode.Builder modeBuilder = new Display.Mode.Builder();
|
||||
if (userPreferredResolution != null) {
|
||||
modeBuilder.setResolution(userPreferredResolution.x, userPreferredResolution.y);
|
||||
}
|
||||
if (!Float.isNaN(refreshRate)) {
|
||||
modeBuilder.setRefreshRate(refreshRate);
|
||||
}
|
||||
device.setUserPreferredDisplayModeLocked(modeBuilder.build());
|
||||
}
|
||||
|
||||
// If we've never recorded stable device stats for this device before and they aren't
|
||||
// explicitly configured, go ahead and record the stable device stats now based on the status
|
||||
// of the default display at first boot.
|
||||
@@ -1731,36 +1752,79 @@ public final class DisplayManagerService extends SystemService {
|
||||
return mWideColorSpace.getId();
|
||||
}
|
||||
|
||||
void setUserPreferredDisplayModeInternal(Display.Mode mode) {
|
||||
void setUserPreferredDisplayModeInternal(int displayId, Display.Mode mode) {
|
||||
synchronized (mSyncRoot) {
|
||||
if (Objects.equals(mUserPreferredMode, mode)) {
|
||||
if (Objects.equals(mUserPreferredMode, mode) && displayId == Display.INVALID_DISPLAY) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mode != null && !isResolutionAndRefreshRateValid(mode)) {
|
||||
if (mode != null && !isResolutionAndRefreshRateValid(mode)
|
||||
&& displayId == Display.INVALID_DISPLAY) {
|
||||
throw new IllegalArgumentException("width, height and refresh rate of mode should "
|
||||
+ "be greater than 0");
|
||||
+ "be greater than 0 when setting the global user preferred display mode.");
|
||||
}
|
||||
mUserPreferredMode = mode;
|
||||
|
||||
final int resolutionHeight = mode == null ? -1 : mode.getPhysicalHeight();
|
||||
final int resolutionWidth = mode == null ? -1 : mode.getPhysicalWidth();
|
||||
final float refreshRate = mode == null ? 0.0f : mode.getRefreshRate();
|
||||
Settings.Global.putFloat(mContext.getContentResolver(),
|
||||
Settings.Global.USER_PREFERRED_REFRESH_RATE, refreshRate);
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.USER_PREFERRED_RESOLUTION_HEIGHT, resolutionHeight);
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.USER_PREFERRED_RESOLUTION_WIDTH, resolutionWidth);
|
||||
mDisplayDeviceRepo.forEachLocked((DisplayDevice device) -> {
|
||||
device.setUserPreferredDisplayModeLocked(mode);
|
||||
});
|
||||
final int resolutionHeight = mode == null ? Display.INVALID_DISPLAY_HEIGHT
|
||||
: mode.getPhysicalHeight();
|
||||
final int resolutionWidth = mode == null ? Display.INVALID_DISPLAY_WIDTH
|
||||
: mode.getPhysicalWidth();
|
||||
final float refreshRate = mode == null ? Display.INVALID_DISPLAY_REFRESH_RATE
|
||||
: mode.getRefreshRate();
|
||||
|
||||
storeModeInPersistentDataStoreLocked(
|
||||
displayId, resolutionWidth, resolutionHeight, refreshRate);
|
||||
if (displayId != Display.INVALID_DISPLAY) {
|
||||
setUserPreferredModeForDisplayLocked(displayId, mode);
|
||||
} else {
|
||||
mUserPreferredMode = mode;
|
||||
storeModeInGlobalSettingsLocked(
|
||||
resolutionWidth, resolutionHeight, refreshRate, mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Display.Mode getUserPreferredDisplayModeInternal() {
|
||||
private void storeModeInPersistentDataStoreLocked(int displayId, int resolutionWidth,
|
||||
int resolutionHeight, float refreshRate) {
|
||||
DisplayDevice displayDevice = getDeviceForDisplayLocked(displayId);
|
||||
if (displayDevice == null) {
|
||||
return;
|
||||
}
|
||||
mPersistentDataStore.setUserPreferredResolution(
|
||||
displayDevice, resolutionWidth, resolutionHeight);
|
||||
mPersistentDataStore.setUserPreferredRefreshRate(displayDevice, refreshRate);
|
||||
}
|
||||
|
||||
private void setUserPreferredModeForDisplayLocked(int displayId, Display.Mode mode) {
|
||||
DisplayDevice displayDevice = getDeviceForDisplayLocked(displayId);
|
||||
if (displayDevice == null) {
|
||||
return;
|
||||
}
|
||||
displayDevice.setUserPreferredDisplayModeLocked(mode);
|
||||
}
|
||||
|
||||
private void storeModeInGlobalSettingsLocked(
|
||||
int resolutionWidth, int resolutionHeight, float refreshRate, Display.Mode mode) {
|
||||
Settings.Global.putFloat(mContext.getContentResolver(),
|
||||
Settings.Global.USER_PREFERRED_REFRESH_RATE, refreshRate);
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.USER_PREFERRED_RESOLUTION_HEIGHT, resolutionHeight);
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.USER_PREFERRED_RESOLUTION_WIDTH, resolutionWidth);
|
||||
mDisplayDeviceRepo.forEachLocked((DisplayDevice device) -> {
|
||||
device.setUserPreferredDisplayModeLocked(mode);
|
||||
});
|
||||
}
|
||||
|
||||
Display.Mode getUserPreferredDisplayModeInternal(int displayId) {
|
||||
synchronized (mSyncRoot) {
|
||||
return mUserPreferredMode;
|
||||
if (displayId == Display.INVALID_DISPLAY) {
|
||||
return mUserPreferredMode;
|
||||
}
|
||||
DisplayDevice displayDevice = getDeviceForDisplayLocked(displayId);
|
||||
if (displayDevice == null) {
|
||||
return null;
|
||||
}
|
||||
return displayDevice.getUserPreferredDisplayModeLocked();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2373,7 +2437,7 @@ public final class DisplayManagerService extends SystemService {
|
||||
pw.println(" mMinimumBrightnessCurve=" + mMinimumBrightnessCurve);
|
||||
|
||||
if (mUserPreferredMode != null) {
|
||||
pw.println(mUserPreferredMode.toString());
|
||||
pw.println(mUserPreferredMode);
|
||||
}
|
||||
|
||||
pw.println();
|
||||
@@ -3379,23 +3443,23 @@ public final class DisplayManagerService extends SystemService {
|
||||
}
|
||||
|
||||
@Override // Binder call
|
||||
public void setUserPreferredDisplayMode(Display.Mode mode) {
|
||||
public void setUserPreferredDisplayMode(int displayId, Display.Mode mode) {
|
||||
mContext.enforceCallingOrSelfPermission(
|
||||
Manifest.permission.MODIFY_USER_PREFERRED_DISPLAY_MODE,
|
||||
"Permission required to set the user preferred display mode.");
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
setUserPreferredDisplayModeInternal(mode);
|
||||
setUserPreferredDisplayModeInternal(displayId, mode);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
}
|
||||
|
||||
@Override // Binder call
|
||||
public Display.Mode getUserPreferredDisplayMode() {
|
||||
public Display.Mode getUserPreferredDisplayMode(int displayId) {
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
return getUserPreferredDisplayModeInternal();
|
||||
return getUserPreferredDisplayModeInternal(displayId);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
|
||||
@@ -113,13 +113,18 @@ class DisplayManagerShellCommand extends ShellCommand {
|
||||
pw.println(" constrain-launcher-metrics [true|false]");
|
||||
pw.println(" Sets if Display#getRealSize and getRealMetrics should be constrained for ");
|
||||
pw.println(" Launcher.");
|
||||
pw.println(" set-user-preferred-display-mode WIDTH HEIGHT REFRESH-RATE");
|
||||
pw.println(" set-user-preferred-display-mode WIDTH HEIGHT REFRESH-RATE "
|
||||
+ "DISPLAY_ID (optional)");
|
||||
pw.println(" Sets the user preferred display mode which has fields WIDTH, HEIGHT and "
|
||||
+ "REFRESH-RATE");
|
||||
pw.println(" clear-user-preferred-display-mode");
|
||||
pw.println(" Clears the user preferred display mode");
|
||||
pw.println(" get-user-preferred-display-mode");
|
||||
pw.println(" Returns the user preferred display mode or null id no mode is set by user");
|
||||
+ "REFRESH-RATE. If DISPLAY_ID is passed, the mode change is applied to display"
|
||||
+ "with id = DISPLAY_ID, else mode change is applied globally.");
|
||||
pw.println(" clear-user-preferred-display-mode DISPLAY_ID (optional)");
|
||||
pw.println(" Clears the user preferred display mode. If DISPLAY_ID is passed, the mode"
|
||||
+ " is cleared for display with id = DISPLAY_ID, else mode is cleared globally.");
|
||||
pw.println(" get-user-preferred-display-mode DISPLAY_ID (optional)");
|
||||
pw.println(" Returns the user preferred display mode or null if no mode is set by user."
|
||||
+ "If DISPLAY_ID is passed, the mode for display with id = DISPLAY_ID is "
|
||||
+ "returned, else global display mode is returned.");
|
||||
pw.println(" set-match-content-frame-rate-pref PREFERENCE");
|
||||
pw.println(" Sets the match content frame rate preference as PREFERENCE ");
|
||||
pw.println(" get-match-content-frame-rate-pref");
|
||||
@@ -235,28 +240,54 @@ class DisplayManagerShellCommand extends ShellCommand {
|
||||
getErrPrintWriter().println("Error: invalid format of width, height or refresh rate");
|
||||
return 1;
|
||||
}
|
||||
if (width < 0 || height < 0 || refreshRate <= 0.0f) {
|
||||
getErrPrintWriter().println("Error: invalid value of width, height or refresh rate");
|
||||
if ((width < 0 || height < 0) && refreshRate <= 0.0f) {
|
||||
getErrPrintWriter().println("Error: invalid value of resolution (width, height)"
|
||||
+ " and refresh rate");
|
||||
return 1;
|
||||
}
|
||||
|
||||
final Context context = mService.getContext();
|
||||
final DisplayManager dm = context.getSystemService(DisplayManager.class);
|
||||
dm.setUserPreferredDisplayMode(new Display.Mode(width, height, refreshRate));
|
||||
final String displayIdText = getNextArg();
|
||||
int displayId = Display.INVALID_DISPLAY;
|
||||
if (displayIdText != null) {
|
||||
try {
|
||||
displayId = Integer.parseInt(displayIdText);
|
||||
} catch (NumberFormatException e) {
|
||||
getErrPrintWriter().println("Error: invalid format of display ID");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
mService.setUserPreferredDisplayModeInternal(
|
||||
displayId, new Display.Mode(width, height, refreshRate));
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int clearUserPreferredDisplayMode() {
|
||||
final Context context = mService.getContext();
|
||||
final DisplayManager dm = context.getSystemService(DisplayManager.class);
|
||||
dm.clearUserPreferredDisplayMode();
|
||||
final String displayIdText = getNextArg();
|
||||
int displayId = Display.INVALID_DISPLAY;
|
||||
if (displayIdText != null) {
|
||||
try {
|
||||
displayId = Integer.parseInt(displayIdText);
|
||||
} catch (NumberFormatException e) {
|
||||
getErrPrintWriter().println("Error: invalid format of display ID");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
mService.setUserPreferredDisplayModeInternal(displayId, null);
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int getUserPreferredDisplayMode() {
|
||||
final Context context = mService.getContext();
|
||||
final DisplayManager dm = context.getSystemService(DisplayManager.class);
|
||||
final Display.Mode mode = dm.getUserPreferredDisplayMode();
|
||||
final String displayIdText = getNextArg();
|
||||
int displayId = Display.INVALID_DISPLAY;
|
||||
if (displayIdText != null) {
|
||||
try {
|
||||
displayId = Integer.parseInt(displayIdText);
|
||||
} catch (NumberFormatException e) {
|
||||
getErrPrintWriter().println("Error: invalid format of display ID");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
final Display.Mode mode = mService.getUserPreferredDisplayModeInternal(displayId);
|
||||
if (mode == null) {
|
||||
getOutPrintWriter().println("User preferred display mode: null");
|
||||
return 0;
|
||||
|
||||
@@ -847,6 +847,10 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
public void setUserPreferredDisplayModeLocked(Display.Mode mode) {
|
||||
final int oldModeId = getPreferredModeId();
|
||||
mUserPreferredMode = mode;
|
||||
if (mode != null && (mode.isRefreshRateSet() ^ mode.isResolutionSet())) {
|
||||
mUserPreferredMode = findMode(mode.getPhysicalWidth(),
|
||||
mode.getPhysicalHeight(), mode.getRefreshRate());
|
||||
}
|
||||
mUserPreferredModeId = findUserPreferredModeIdLocked(mode);
|
||||
|
||||
if (oldModeId != getPreferredModeId()) {
|
||||
@@ -854,6 +858,11 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Display.Mode getUserPreferredDisplayModeLocked() {
|
||||
return mUserPreferredMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRequestedColorModeLocked(int colorMode) {
|
||||
requestColorModeLocked(colorMode);
|
||||
@@ -1062,6 +1071,18 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
return matchingModeId;
|
||||
}
|
||||
|
||||
// Returns a mode with resolution (width, height) and/or refreshRate. If any one of the
|
||||
// resolution or refresh-rate is valid, a mode having the valid parameters is returned.
|
||||
private Display.Mode findMode(int width, int height, float refreshRate) {
|
||||
for (int i = 0; i < mSupportedModes.size(); i++) {
|
||||
Display.Mode supportedMode = mSupportedModes.valueAt(i).mMode;
|
||||
if (supportedMode.matchesIfValid(width, height, refreshRate)) {
|
||||
return supportedMode;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private int findUserPreferredModeIdLocked(Display.Mode userPreferredMode) {
|
||||
if (userPreferredMode != null) {
|
||||
for (int i = 0; i < mSupportedModes.size(); i++) {
|
||||
|
||||
@@ -291,6 +291,54 @@ final class PersistentDataStore {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean setUserPreferredRefreshRate(DisplayDevice displayDevice, float refreshRate) {
|
||||
final String displayDeviceUniqueId = displayDevice.getUniqueId();
|
||||
if (!displayDevice.hasStableUniqueId() || displayDeviceUniqueId == null) {
|
||||
return false;
|
||||
}
|
||||
DisplayState state = getDisplayState(displayDevice.getUniqueId(), true);
|
||||
if (state.setRefreshRate(refreshRate)) {
|
||||
setDirty();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public float getUserPreferredRefreshRate(DisplayDevice device) {
|
||||
if (device == null || !device.hasStableUniqueId()) {
|
||||
return Float.NaN;
|
||||
}
|
||||
final DisplayState state = getDisplayState(device.getUniqueId(), false);
|
||||
if (state == null) {
|
||||
return Float.NaN;
|
||||
}
|
||||
return state.getRefreshRate();
|
||||
}
|
||||
|
||||
public boolean setUserPreferredResolution(DisplayDevice displayDevice, int width, int height) {
|
||||
final String displayDeviceUniqueId = displayDevice.getUniqueId();
|
||||
if (!displayDevice.hasStableUniqueId() || displayDeviceUniqueId == null) {
|
||||
return false;
|
||||
}
|
||||
DisplayState state = getDisplayState(displayDevice.getUniqueId(), true);
|
||||
if (state.setResolution(width, height)) {
|
||||
setDirty();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Point getUserPreferredResolution(DisplayDevice displayDevice) {
|
||||
if (displayDevice == null || !displayDevice.hasStableUniqueId()) {
|
||||
return null;
|
||||
}
|
||||
final DisplayState state = getDisplayState(displayDevice.getUniqueId(), false);
|
||||
if (state == null) {
|
||||
return null;
|
||||
}
|
||||
return state.getResolution();
|
||||
}
|
||||
|
||||
public Point getStableDisplaySize() {
|
||||
loadIfNeeded();
|
||||
return mStableDeviceValues.getDisplaySize();
|
||||
@@ -536,6 +584,9 @@ final class PersistentDataStore {
|
||||
private static final class DisplayState {
|
||||
private int mColorMode;
|
||||
private float mBrightness;
|
||||
private int mWidth;
|
||||
private int mHeight;
|
||||
private float mRefreshRate;
|
||||
|
||||
// Brightness configuration by user
|
||||
private BrightnessConfigurations mDisplayBrightnessConfigurations =
|
||||
@@ -576,6 +627,31 @@ final class PersistentDataStore {
|
||||
return mDisplayBrightnessConfigurations.mConfigurations.get(userSerial);
|
||||
}
|
||||
|
||||
public boolean setResolution(int width, int height) {
|
||||
if (width == mWidth && height == mHeight) {
|
||||
return false;
|
||||
}
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
return true;
|
||||
}
|
||||
|
||||
public Point getResolution() {
|
||||
return new Point(mWidth, mHeight);
|
||||
}
|
||||
|
||||
public boolean setRefreshRate(float refreshRate) {
|
||||
if (refreshRate == mRefreshRate) {
|
||||
return false;
|
||||
}
|
||||
mRefreshRate = refreshRate;
|
||||
return true;
|
||||
}
|
||||
|
||||
public float getRefreshRate() {
|
||||
return mRefreshRate;
|
||||
}
|
||||
|
||||
public void loadFromXml(TypedXmlPullParser parser)
|
||||
throws IOException, XmlPullParserException {
|
||||
final int outerDepth = parser.getDepth();
|
||||
|
||||
@@ -4588,7 +4588,8 @@ public class StatsPullAtomService extends SystemService {
|
||||
int matchContentFrameRateUserPreference =
|
||||
displayManager.getMatchContentFrameRateUserPreference();
|
||||
byte[] userDisabledHdrTypes = toBytes(displayManager.getUserDisabledHdrTypes());
|
||||
Display.Mode userPreferredDisplayMode = displayManager.getUserPreferredDisplayMode();
|
||||
Display.Mode userPreferredDisplayMode =
|
||||
displayManager.getGlobalUserPreferredDisplayMode();
|
||||
int userPreferredWidth = userPreferredDisplayMode != null
|
||||
? userPreferredDisplayMode.getPhysicalWidth() : -1;
|
||||
int userPreferredHeight = userPreferredDisplayMode != null
|
||||
|
||||
Reference in New Issue
Block a user