Boot time resolution changes in framework

Adding API and changes to incorporate boot-time resolution HAL APIs

Bug: 209598222
Test: atest CtsBootDisplayModeTestCases

Change-Id: I7081af903d8259cf7c0009238e7968d458ff3325
This commit is contained in:
Kriti Dang
2021-11-15 10:45:35 +01:00
parent bce8d161c4
commit aef5aa78b5
10 changed files with 237 additions and 7 deletions

View File

@@ -2705,6 +2705,7 @@ package android.view {
method @NonNull public android.view.Display.Mode getDefaultMode();
method @NonNull public int[] getReportedHdrTypes();
method @NonNull public android.graphics.ColorSpace[] getSupportedWideColorGamut();
method @Nullable public android.view.Display.Mode getSystemPreferredDisplayMode();
method public int getType();
method @Nullable public android.view.Display.Mode getUserPreferredDisplayMode();
method public boolean hasAccess(int);

View File

@@ -915,6 +915,17 @@ public final class DisplayManagerGlobal {
}
}
/**
* Returns the system preferred display mode.
*/
public Display.Mode getSystemPreferredDisplayMode(int displayId) {
try {
return mDm.getSystemPreferredDisplayMode(displayId);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
/**
* 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

View File

@@ -168,6 +168,7 @@ interface IDisplayManager {
// Requires MODIFY_USER_PREFERRED_DISPLAY_MODE permission.
void setUserPreferredDisplayMode(int displayId, in Mode mode);
Mode getUserPreferredDisplayMode(int displayId);
Mode getSystemPreferredDisplayMode(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

View File

@@ -1110,6 +1110,19 @@ public final class Display {
return mDisplayInfo.removeMode;
}
/**
* Returns the system's preferred display mode. This mode will be used when the user has not
* specified a display-mode preference. This returns null if the boot display mode feature is
* not supported by system.
*
* @hide
*/
@TestApi
@Nullable
public Display.Mode getSystemPreferredDisplayMode() {
return mGlobal.getSystemPreferredDisplayMode(getDisplayId());
}
/**
* Returns the display's HDR capabilities.
*

View File

@@ -197,6 +197,9 @@ public final class SurfaceControl implements Parcelable {
private static native int[] nativeGetCompositionDataspaces();
private static native boolean nativeSetActiveColorMode(IBinder displayToken,
int colorMode);
private static native boolean nativeGetBootDisplayModeSupport();
private static native void nativeSetBootDisplayMode(IBinder displayToken, int displayMode);
private static native void nativeClearBootDisplayMode(IBinder displayToken);
private static native void nativeSetAutoLowLatencyMode(IBinder displayToken, boolean on);
private static native void nativeSetGameContentType(IBinder displayToken, boolean on);
private static native void nativeSetDisplayPowerMode(
@@ -1874,6 +1877,8 @@ public final class SurfaceControl implements Parcelable {
public boolean autoLowLatencyModeSupported;
public boolean gameContentTypeSupported;
public int preferredBootDisplayMode;
@Override
public String toString() {
return "DynamicDisplayInfo{"
@@ -1883,7 +1888,8 @@ public final class SurfaceControl implements Parcelable {
+ ", activeColorMode=" + activeColorMode
+ ", hdrCapabilities=" + hdrCapabilities
+ ", autoLowLatencyModeSupported=" + autoLowLatencyModeSupported
+ ", gameContentTypeSupported" + gameContentTypeSupported + "}";
+ ", gameContentTypeSupported" + gameContentTypeSupported
+ ", preferredBootDisplayMode" + preferredBootDisplayMode + "}";
}
@Override
@@ -1895,7 +1901,8 @@ public final class SurfaceControl implements Parcelable {
&& activeDisplayModeId == that.activeDisplayModeId
&& Arrays.equals(supportedColorModes, that.supportedColorModes)
&& activeColorMode == that.activeColorMode
&& Objects.equals(hdrCapabilities, that.hdrCapabilities);
&& Objects.equals(hdrCapabilities, that.hdrCapabilities)
&& preferredBootDisplayMode == that.preferredBootDisplayMode;
}
@Override
@@ -2259,6 +2266,36 @@ public final class SurfaceControl implements Parcelable {
return colorSpaces;
}
/**
* @hide
*/
public static boolean getBootDisplayModeSupport() {
return nativeGetBootDisplayModeSupport();
}
/** There is no associated getter for this method. When this is set, the display is expected
* to start up in this mode next time the device reboots.
* @hide
*/
public static void setBootDisplayMode(IBinder displayToken, int displayModeId) {
if (displayToken == null) {
throw new IllegalArgumentException("displayToken must not be null");
}
nativeSetBootDisplayMode(displayToken, displayModeId);
}
/**
* @hide
*/
public static void clearBootDisplayMode(IBinder displayToken) {
if (displayToken == null) {
throw new IllegalArgumentException("displayToken must not be null");
}
nativeClearBootDisplayMode(displayToken);
}
/**
* @hide
*/

View File

@@ -1630,6 +1630,27 @@ static void nativeOverrideHdrTypes(JNIEnv* env, jclass clazz, jobject tokenObjec
}
}
static jboolean nativeGetBootDisplayModeSupport(JNIEnv* env, jclass clazz) {
bool isBootDisplayModeSupported = false;
SurfaceComposerClient::getBootDisplayModeSupport(&isBootDisplayModeSupported);
return static_cast<jboolean>(isBootDisplayModeSupported);
}
static void nativeSetBootDisplayMode(JNIEnv* env, jclass clazz, jobject tokenObject,
jint displayModId) {
sp<IBinder> token(ibinderForJavaObject(env, tokenObject));
if (token == NULL) return;
SurfaceComposerClient::setBootDisplayMode(token, displayModId);
}
static void nativeClearBootDisplayMode(JNIEnv* env, jclass clazz, jobject tokenObject) {
sp<IBinder> token(ibinderForJavaObject(env, tokenObject));
if (token == NULL) return;
SurfaceComposerClient::clearBootDisplayMode(token);
}
static void nativeSetAutoLowLatencyMode(JNIEnv* env, jclass clazz, jobject tokenObject, jboolean on) {
sp<IBinder> token(ibinderForJavaObject(env, tokenObject));
if (token == NULL) return;
@@ -2038,6 +2059,12 @@ static const JNINativeMethod sSurfaceControlMethods[] = {
(void*)nativeGetDisplayNativePrimaries },
{"nativeSetActiveColorMode", "(Landroid/os/IBinder;I)Z",
(void*)nativeSetActiveColorMode},
{"nativeGetBootDisplayModeSupport", "()Z",
(void*)nativeGetBootDisplayModeSupport },
{"nativeSetBootDisplayMode", "(Landroid/os/IBinder;I)V",
(void*)nativeSetBootDisplayMode },
{"nativeClearBootDisplayMode", "(Landroid/os/IBinder;)V",
(void*)nativeClearBootDisplayMode },
{"nativeSetAutoLowLatencyMode", "(Landroid/os/IBinder;Z)V",
(void*)nativeSetAutoLowLatencyMode },
{"nativeSetGameContentType", "(Landroid/os/IBinder;Z)V",

View File

@@ -221,6 +221,22 @@ abstract class DisplayDevice {
return EMPTY_DISPLAY_MODE;
}
/**
* Returns the system preferred display mode.
*/
public Display.Mode getSystemPreferredDisplayModeLocked() {
return EMPTY_DISPLAY_MODE;
}
/**
* Returns the display mode that was being used when this display was first found by
* display manager.
* @hide
*/
public Display.Mode getActiveDisplayModeAtStartLocked() {
return EMPTY_DISPLAY_MODE;
}
/**
* Sets the requested color mode.
*/

View File

@@ -1828,6 +1828,16 @@ public final class DisplayManagerService extends SystemService {
}
}
Display.Mode getSystemPreferredDisplayModeInternal(int displayId) {
synchronized (mSyncRoot) {
final DisplayDevice device = getDeviceForDisplayLocked(displayId);
if (device == null) {
return null;
}
return device.getSystemPreferredDisplayModeLocked();
}
}
void setShouldAlwaysRespectAppRequestedModeInternal(boolean enabled) {
mDisplayModeDirector.setShouldAlwaysRespectAppRequestedMode(enabled);
}
@@ -2178,6 +2188,16 @@ public final class DisplayManagerService extends SystemService {
}
}
Display.Mode getActiveDisplayModeAtStart(int displayId) {
synchronized (mSyncRoot) {
final DisplayDevice device = getDeviceForDisplayLocked(displayId);
if (device == null) {
return null;
}
return device.getActiveDisplayModeAtStartLocked();
}
}
void setAmbientColorTemperatureOverride(float cct) {
synchronized (mSyncRoot) {
final DisplayPowerController displayPowerController = mDisplayPowerControllers.get(
@@ -3465,6 +3485,16 @@ public final class DisplayManagerService extends SystemService {
}
}
@Override // Binder call
public Display.Mode getSystemPreferredDisplayMode(int displayId) {
final long token = Binder.clearCallingIdentity();
try {
return getSystemPreferredDisplayModeInternal(displayId);
} finally {
Binder.restoreCallingIdentity(token);
}
}
@Override // Binder call
public void setShouldAlwaysRespectAppRequestedMode(boolean enabled) {
mContext.enforceCallingOrSelfPermission(

View File

@@ -68,6 +68,8 @@ class DisplayManagerShellCommand extends ShellCommand {
return clearUserPreferredDisplayMode();
case "get-user-preferred-display-mode":
return getUserPreferredDisplayMode();
case "get-active-display-mode-at-start":
return getActiveDisplayModeAtStart();
case "set-match-content-frame-rate-pref":
return setMatchContentFrameRateUserPreference();
case "get-match-content-frame-rate-pref":
@@ -125,6 +127,9 @@ class DisplayManagerShellCommand extends ShellCommand {
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(" get-active-display-mode-at-start DISPLAY_ID");
pw.println(" Returns the display mode which was found at boot time of display with "
+ "id = DISPLAY_ID");
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");
@@ -298,6 +303,30 @@ class DisplayManagerShellCommand extends ShellCommand {
return 0;
}
private int getActiveDisplayModeAtStart() {
final String displayIdText = getNextArg();
if (displayIdText == null) {
getErrPrintWriter().println("Error: no displayId specified");
return 1;
}
final int displayId;
try {
displayId = Integer.parseInt(displayIdText);
} catch (NumberFormatException e) {
getErrPrintWriter().println("Error: invalid displayId");
return 1;
}
Display.Mode mode = mService.getActiveDisplayModeAtStart(displayId);
if (mode == null) {
getOutPrintWriter().println("Boot display mode: null");
return 0;
}
getOutPrintWriter().println("Boot display mode: " + mode.getPhysicalWidth() + " "
+ mode.getPhysicalHeight() + " " + mode.getRefreshRate());
return 0;
}
private int setMatchContentFrameRateUserPreference() {
final String matchContentFrameRatePrefText = getNextArg();
if (matchContentFrameRatePrefText == null) {

View File

@@ -192,8 +192,12 @@ final class LocalDisplayAdapter extends DisplayAdapter {
private float mBrightnessState = PowerManager.BRIGHTNESS_INVALID_FLOAT;
private float mSdrBrightnessState = PowerManager.BRIGHTNESS_INVALID_FLOAT;
private int mDefaultModeId = INVALID_MODE_ID;
private int mSystemPreferredModeId = INVALID_MODE_ID;
private int mDefaultModeGroup;
private int mUserPreferredModeId = INVALID_MODE_ID;
// This is used only for the purpose of testing, to verify if the mode was correct when the
// device started or booted.
private int mActiveDisplayModeAtStartId = INVALID_MODE_ID;
private Display.Mode mUserPreferredMode;
private int mActiveModeId = INVALID_MODE_ID;
private DisplayModeDirector.DesiredDisplayModeSpecs mDisplayModeSpecs =
@@ -208,7 +212,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
private boolean mSidekickActive;
private SidekickInternal mSidekickInternal;
private SurfaceControl.StaticDisplayInfo mStaticDisplayInfo;
// The supported display modes according in SurfaceFlinger
// The supported display modes according to SurfaceFlinger
private SurfaceControl.DisplayMode[] mSfDisplayModes;
// The active display mode in SurfaceFlinger
private SurfaceControl.DisplayMode mActiveSfDisplayMode;
@@ -230,6 +234,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
mBacklightAdapter = new BacklightAdapter(displayToken, isDefaultDisplay,
mSurfaceControlProxy);
mDisplayDeviceConfig = null;
mActiveDisplayModeAtStartId = dynamicInfo.activeDisplayModeId;
}
@Override
@@ -237,13 +242,24 @@ final class LocalDisplayAdapter extends DisplayAdapter {
return true;
}
/**
* Returns the boot display mode of this display.
* @hide
*/
@Override
public Display.Mode getActiveDisplayModeAtStartLocked() {
return findMode(mActiveDisplayModeAtStartId);
}
/**
* Returns true if there is a change.
**/
public boolean updateDisplayPropertiesLocked(SurfaceControl.StaticDisplayInfo staticInfo,
SurfaceControl.DynamicDisplayInfo dynamicInfo,
SurfaceControl.DesiredDisplayModeSpecs modeSpecs) {
boolean changed = updateDisplayModesLocked(
boolean changed =
updateSystemPreferredDisplayMode(dynamicInfo.preferredBootDisplayMode);
changed |= updateDisplayModesLocked(
dynamicInfo.supportedDisplayModes, dynamicInfo.activeDisplayModeId, modeSpecs);
changed |= updateStaticInfo(staticInfo);
changed |= updateColorModesLocked(dynamicInfo.supportedColorModes,
@@ -369,8 +385,11 @@ final class LocalDisplayAdapter extends DisplayAdapter {
// For a new display, we need to initialize the default mode ID.
if (mDefaultModeId == INVALID_MODE_ID) {
mDefaultModeId = activeRecord.mMode.getModeId();
mDefaultModeGroup = mActiveSfDisplayMode.group;
mDefaultModeId = mSystemPreferredModeId != INVALID_MODE_ID
? mSystemPreferredModeId : activeRecord.mMode.getModeId();
mDefaultModeGroup = mSystemPreferredModeId != INVALID_MODE_ID
? getModeById(mSfDisplayModes, mSystemPreferredModeId).group
: mActiveSfDisplayMode.group;
} else if (modesAdded && activeModeChanged) {
Slog.d(TAG, "New display modes are added and the active mode has changed, "
+ "use active mode as default mode.");
@@ -531,6 +550,15 @@ final class LocalDisplayAdapter extends DisplayAdapter {
return true;
}
private boolean updateSystemPreferredDisplayMode(int modeId) {
if (!mSurfaceControlProxy.getBootDisplayModeSupport()
|| mSystemPreferredModeId == modeId) {
return false;
}
mSystemPreferredModeId = modeId;
return true;
}
private SurfaceControl.DisplayMode getModeById(SurfaceControl.DisplayMode[] supportedModes,
int modeId) {
for (SurfaceControl.DisplayMode mode : supportedModes) {
@@ -856,6 +884,16 @@ final class LocalDisplayAdapter extends DisplayAdapter {
if (oldModeId != getPreferredModeId()) {
updateDeviceInfoLocked();
}
if (!mSurfaceControlProxy.getBootDisplayModeSupport()) {
return;
}
if (mUserPreferredMode == null) {
mSurfaceControlProxy.clearBootDisplayMode(getDisplayTokenLocked());
} else {
mSurfaceControlProxy.setBootDisplayMode(getDisplayTokenLocked(),
mUserPreferredMode.getModeId());
}
}
@Override
@@ -863,6 +901,11 @@ final class LocalDisplayAdapter extends DisplayAdapter {
return mUserPreferredMode;
}
@Override
public Display.Mode getSystemPreferredDisplayModeLocked() {
return findMode(mSystemPreferredModeId);
}
@Override
public void setRequestedColorModeLocked(int colorMode) {
requestColorModeLocked(colorMode);
@@ -1071,6 +1114,17 @@ final class LocalDisplayAdapter extends DisplayAdapter {
return matchingModeId;
}
// Returns a mode with id = modeId.
private Display.Mode findMode(int modeId) {
for (int i = 0; i < mSupportedModes.size(); i++) {
Display.Mode supportedMode = mSupportedModes.valueAt(i).mMode;
if (supportedMode.getModeId() == modeId) {
return supportedMode;
}
}
return null;
}
// 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) {
@@ -1317,6 +1371,18 @@ final class LocalDisplayAdapter extends DisplayAdapter {
return SurfaceControl.setActiveColorMode(displayToken, colorMode);
}
public boolean getBootDisplayModeSupport() {
return SurfaceControl.getBootDisplayModeSupport();
}
public void setBootDisplayMode(IBinder displayToken, int modeId) {
SurfaceControl.setBootDisplayMode(displayToken, modeId);
}
public void clearBootDisplayMode(IBinder displayToken) {
SurfaceControl.clearBootDisplayMode(displayToken);
}
public void setAutoLowLatencyMode(IBinder displayToken, boolean on) {
SurfaceControl.setAutoLowLatencyMode(displayToken, on);
@@ -1339,7 +1405,6 @@ final class LocalDisplayAdapter extends DisplayAdapter {
return SurfaceControl.setDisplayBrightness(displayToken, sdrBacklight, sdrNits,
displayBacklight, displayNits);
}
}
static class BacklightAdapter {