Merge "Each Display Mode now has an array of supported HDR types"
diff --git a/core/api/current.txt b/core/api/current.txt
index 614c4c3..e6c0d45 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -48751,7 +48751,7 @@
method public float getDesiredMaxAverageLuminance();
method public float getDesiredMaxLuminance();
method public float getDesiredMinLuminance();
- method public int[] getSupportedHdrTypes();
+ method @Deprecated public int[] getSupportedHdrTypes();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.view.Display.HdrCapabilities> CREATOR;
field public static final int HDR_TYPE_DOLBY_VISION = 1; // 0x1
@@ -48768,6 +48768,7 @@
method public int getPhysicalHeight();
method public int getPhysicalWidth();
method public float getRefreshRate();
+ method @NonNull public int[] getSupportedHdrTypes();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.view.Display.Mode> CREATOR;
}
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 2745858..a42d3eb 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -1942,13 +1942,16 @@
private final float mRefreshRate;
@NonNull
private final float[] mAlternativeRefreshRates;
+ @NonNull
+ @HdrCapabilities.HdrType
+ private final int[] mSupportedHdrTypes;
/**
* @hide
*/
@TestApi
public Mode(int width, int height, float refreshRate) {
- this(INVALID_MODE_ID, width, height, refreshRate, new float[0]);
+ this(INVALID_MODE_ID, width, height, refreshRate, new float[0], new int[0]);
}
/**
@@ -1956,14 +1959,14 @@
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public Mode(int modeId, int width, int height, float refreshRate) {
- this(modeId, width, height, refreshRate, new float[0]);
+ this(modeId, width, height, refreshRate, new float[0], new int[0]);
}
/**
* @hide
*/
public Mode(int modeId, int width, int height, float refreshRate,
- float[] alternativeRefreshRates) {
+ float[] alternativeRefreshRates, @HdrCapabilities.HdrType int[] supportedHdrTypes) {
mModeId = modeId;
mWidth = width;
mHeight = height;
@@ -1971,6 +1974,8 @@
mAlternativeRefreshRates =
Arrays.copyOf(alternativeRefreshRates, alternativeRefreshRates.length);
Arrays.sort(mAlternativeRefreshRates);
+ mSupportedHdrTypes = Arrays.copyOf(supportedHdrTypes, supportedHdrTypes.length);
+ Arrays.sort(mSupportedHdrTypes);
}
/**
@@ -2045,6 +2050,15 @@
}
/**
+ * Returns the supported {@link HdrCapabilities} HDR_TYPE_* for this specific mode
+ */
+ @NonNull
+ @HdrCapabilities.HdrType
+ public int[] getSupportedHdrTypes() {
+ return mSupportedHdrTypes;
+ }
+
+ /**
* Returns {@code true} if this mode matches the given parameters.
*
* @hide
@@ -2118,7 +2132,8 @@
}
Mode that = (Mode) other;
return mModeId == that.mModeId && matches(that.mWidth, that.mHeight, that.mRefreshRate)
- && Arrays.equals(mAlternativeRefreshRates, that.mAlternativeRefreshRates);
+ && Arrays.equals(mAlternativeRefreshRates, that.mAlternativeRefreshRates)
+ && Arrays.equals(mSupportedHdrTypes, that.mSupportedHdrTypes);
}
@Override
@@ -2129,6 +2144,7 @@
hash = hash * 17 + mHeight;
hash = hash * 17 + Float.floatToIntBits(mRefreshRate);
hash = hash * 17 + Arrays.hashCode(mAlternativeRefreshRates);
+ hash = hash * 17 + Arrays.hashCode(mSupportedHdrTypes);
return hash;
}
@@ -2141,6 +2157,8 @@
.append(", fps=").append(mRefreshRate)
.append(", alternativeRefreshRates=")
.append(Arrays.toString(mAlternativeRefreshRates))
+ .append(", supportedHdrTypes=")
+ .append(Arrays.toString(mSupportedHdrTypes))
.append("}")
.toString();
}
@@ -2151,7 +2169,8 @@
}
private Mode(Parcel in) {
- this(in.readInt(), in.readInt(), in.readInt(), in.readFloat(), in.createFloatArray());
+ this(in.readInt(), in.readInt(), in.readInt(), in.readFloat(), in.createFloatArray(),
+ in.createIntArray());
}
@Override
@@ -2161,6 +2180,7 @@
out.writeInt(mHeight);
out.writeFloat(mRefreshRate);
out.writeFloatArray(mAlternativeRefreshRates);
+ out.writeIntArray(mSupportedHdrTypes);
}
@SuppressWarnings("hiding")
@@ -2326,6 +2346,9 @@
/**
* Gets the supported HDR types of this display.
* Returns empty array if HDR is not supported by the display.
+ *
+ * @deprecated use {@link Display#getMode()}
+ * and {@link Mode#getSupportedHdrTypes()} instead
*/
public @HdrType int[] getSupportedHdrTypes() {
return mSupportedHdrTypes;
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index e1ca0f1..30e7a7a 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -1563,6 +1563,7 @@
public float refreshRate;
public long appVsyncOffsetNanos;
public long presentationDeadlineNanos;
+ public int[] supportedHdrTypes;
/**
* The config group ID this config is associated to.
@@ -1582,6 +1583,7 @@
+ ", refreshRate=" + refreshRate
+ ", appVsyncOffsetNanos=" + appVsyncOffsetNanos
+ ", presentationDeadlineNanos=" + presentationDeadlineNanos
+ + ", supportedHdrTypes=" + Arrays.toString(supportedHdrTypes)
+ ", group=" + group + "}";
}
@@ -1598,13 +1600,14 @@
&& Float.compare(that.refreshRate, refreshRate) == 0
&& appVsyncOffsetNanos == that.appVsyncOffsetNanos
&& presentationDeadlineNanos == that.presentationDeadlineNanos
+ && Arrays.equals(supportedHdrTypes, that.supportedHdrTypes)
&& group == that.group;
}
@Override
public int hashCode() {
return Objects.hash(id, width, height, xDpi, yDpi, refreshRate, appVsyncOffsetNanos,
- presentationDeadlineNanos, group);
+ presentationDeadlineNanos, group, Arrays.hashCode(supportedHdrTypes));
}
}
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 5a0a84b..2c5386d 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -129,6 +129,7 @@
jfieldID appVsyncOffsetNanos;
jfieldID presentationDeadlineNanos;
jfieldID group;
+ jfieldID supportedHdrTypes;
} gDisplayModeClassInfo;
// Implements SkMallocPixelRef::ReleaseProc, to delete the screenshot on unref.
@@ -1130,6 +1131,16 @@
env->SetLongField(object, gDisplayModeClassInfo.presentationDeadlineNanos,
config.presentationDeadline);
env->SetIntField(object, gDisplayModeClassInfo.group, config.group);
+
+ const auto& types = config.supportedHdrTypes;
+ std::vector<jint> intTypes;
+ for (auto type : types) {
+ intTypes.push_back(static_cast<jint>(type));
+ }
+ auto typesArray = env->NewIntArray(types.size());
+ env->SetIntArrayRegion(typesArray, 0, intTypes.size(), intTypes.data());
+ env->SetObjectField(object, gDisplayModeClassInfo.supportedHdrTypes, typesArray);
+
return object;
}
@@ -2191,6 +2202,8 @@
gDisplayModeClassInfo.presentationDeadlineNanos =
GetFieldIDOrDie(env, modeClazz, "presentationDeadlineNanos", "J");
gDisplayModeClassInfo.group = GetFieldIDOrDie(env, modeClazz, "group", "I");
+ gDisplayModeClassInfo.supportedHdrTypes =
+ GetFieldIDOrDie(env, modeClazz, "supportedHdrTypes", "[I");
jclass frameStatsClazz = FindClassOrDie(env, "android/view/FrameStats");
jfieldID undefined_time_nano_field = GetStaticFieldIDOrDie(env,
diff --git a/core/tests/mockingcoretests/src/android/view/DisplayTest.java b/core/tests/mockingcoretests/src/android/view/DisplayTest.java
index 0c939ec..9ccf3b3 100644
--- a/core/tests/mockingcoretests/src/android/view/DisplayTest.java
+++ b/core/tests/mockingcoretests/src/android/view/DisplayTest.java
@@ -27,6 +27,8 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertArrayEquals;
+
import android.app.WindowConfiguration;
import android.content.Context;
import android.content.res.Resources;
@@ -399,6 +401,15 @@
verifyRealMetricsMatchesBounds(display, sDeviceBoundsLandscape);
}
+ @Test
+ public void testSupportedHdrTypesForDisplayModeAreSorted() {
+ int[] nonSortedHdrTypes = new int[]{3, 2, 1};
+ Display.Mode displayMode = new Display.Mode(0, 0, 0, 0, new float[0], nonSortedHdrTypes);
+
+ int[] sortedHdrTypes = new int[]{1, 2, 3};
+ assertArrayEquals(sortedHdrTypes, displayMode.getSupportedHdrTypes());
+ }
+
// Given rotated display dimensions, calculate the letterboxed app bounds.
private static Rect buildAppBounds(int displayWidth, int displayHeight) {
final int midWidth = displayWidth / 2;
diff --git a/services/core/java/com/android/server/display/DisplayAdapter.java b/services/core/java/com/android/server/display/DisplayAdapter.java
index 1fc15122..4f1df3f 100644
--- a/services/core/java/com/android/server/display/DisplayAdapter.java
+++ b/services/core/java/com/android/server/display/DisplayAdapter.java
@@ -120,13 +120,14 @@
}
public static Display.Mode createMode(int width, int height, float refreshRate) {
- return createMode(width, height, refreshRate, new float[0]);
+ return createMode(width, height, refreshRate, new float[0], new int[0]);
}
public static Display.Mode createMode(int width, int height, float refreshRate,
- float[] alternativeRefreshRates) {
+ float[] alternativeRefreshRates,
+ @Display.HdrCapabilities.HdrType int[] supportedHdrTypes) {
return new Display.Mode(NEXT_DISPLAY_MODE_ID.getAndIncrement(), width, height, refreshRate,
- alternativeRefreshRates);
+ alternativeRefreshRates, supportedHdrTypes);
}
public interface Listener {
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 1d04f2e..a7e6b7f 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -934,7 +934,8 @@
overriddenInfo.supportedModes[overriddenInfo.supportedModes.length - 1] =
new Display.Mode(Display.DISPLAY_MODE_ID_FOR_FRAME_RATE_OVERRIDE,
currentMode.getPhysicalWidth(), currentMode.getPhysicalHeight(),
- overriddenInfo.refreshRateOverride);
+ overriddenInfo.refreshRateOverride,
+ new float[0], currentMode.getSupportedHdrTypes());
overriddenInfo.modeId =
overriddenInfo.supportedModes[overriddenInfo.supportedModes.length - 1]
.getModeId();
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index f85b990..dc5c80f2 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -584,7 +584,9 @@
DisplayModeRecord record = mSupportedModes.valueAt(i);
if (record.hasMatchingMode(mode)
&& refreshRatesEquals(alternativeRefreshRates,
- record.mMode.getAlternativeRefreshRates())) {
+ record.mMode.getAlternativeRefreshRates())
+ && hdrTypesEqual(mode.supportedHdrTypes,
+ record.mMode.getSupportedHdrTypes())) {
return record;
}
}
@@ -1226,6 +1228,13 @@
}
}
+ private boolean hdrTypesEqual(int[] modeHdrTypes, int[] recordHdrTypes) {
+ int[] modeHdrTypesCopy = Arrays.copyOf(modeHdrTypes, modeHdrTypes.length);
+ Arrays.sort(modeHdrTypesCopy);
+ // Record HDR types are already sorted when we create the DisplayModeRecord
+ return Arrays.equals(modeHdrTypesCopy, recordHdrTypes);
+ }
+
/** Supplies a context whose Resources apply runtime-overlays */
Context getOverlayContext() {
if (mOverlayContext == null) {
@@ -1243,7 +1252,7 @@
DisplayModeRecord(SurfaceControl.DisplayMode mode,
float[] alternativeRefreshRates) {
mMode = createMode(mode.width, mode.height, mode.refreshRate,
- alternativeRefreshRates);
+ alternativeRefreshRates, mode.supportedHdrTypes);
}
/**
@@ -1257,7 +1266,7 @@
return mMode.getPhysicalWidth() == mode.width
&& mMode.getPhysicalHeight() == mode.height
&& Float.floatToIntBits(mMode.getRefreshRate())
- == Float.floatToIntBits(mode.refreshRate);
+ == Float.floatToIntBits(mode.refreshRate);
}
public String toString() {
diff --git a/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java b/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java
index 395e6ac..be32b79 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java
@@ -23,6 +23,7 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@@ -58,6 +59,7 @@
import com.google.common.truth.Truth;
import org.junit.After;
+import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -84,6 +86,8 @@
private static final long HANDLER_WAIT_MS = 100;
+ private static final int[] HDR_TYPES = new int[]{1, 2};
+
private StaticMockitoSession mMockitoSession;
private LocalDisplayAdapter mAdapter;
@@ -202,6 +206,38 @@
PORT_C, false);
}
+ @Test
+ public void testSupportedDisplayModesGetOverriddenWhenDisplayIsUpdated()
+ throws InterruptedException {
+ SurfaceControl.DisplayMode displayMode = createFakeDisplayMode(0, 1920, 1080, 0);
+ displayMode.supportedHdrTypes = new int[0];
+ FakeDisplay display = new FakeDisplay(PORT_A, new SurfaceControl.DisplayMode[]{displayMode},
+ 0);
+ setUpDisplay(display);
+ updateAvailableDisplays();
+ mAdapter.registerLocked();
+ waitForHandlerToComplete(mHandler, HANDLER_WAIT_MS);
+
+ DisplayDevice displayDevice = mListener.addedDisplays.get(0);
+ displayDevice.applyPendingDisplayDeviceInfoChangesLocked();
+ Display.Mode[] supportedModes = displayDevice.getDisplayDeviceInfoLocked().supportedModes;
+ Assert.assertEquals(1, supportedModes.length);
+ Assert.assertEquals(0, supportedModes[0].getSupportedHdrTypes().length);
+
+ displayMode.supportedHdrTypes = new int[]{3, 2};
+ display.dynamicInfo.supportedDisplayModes = new SurfaceControl.DisplayMode[]{displayMode};
+ setUpDisplay(display);
+ mInjector.getTransmitter().sendHotplug(display, true);
+ waitForHandlerToComplete(mHandler, HANDLER_WAIT_MS);
+
+ displayDevice = mListener.changedDisplays.get(0);
+ displayDevice.applyPendingDisplayDeviceInfoChangesLocked();
+ supportedModes = displayDevice.getDisplayDeviceInfoLocked().supportedModes;
+
+ Assert.assertEquals(1, supportedModes.length);
+ assertArrayEquals(new int[]{2, 3}, supportedModes[0].getSupportedHdrTypes());
+ }
+
/**
* Confirm that all local displays are public when config_localPrivateDisplayPorts is empty.
*/
@@ -1008,6 +1044,7 @@
mode.xDpi = 100;
mode.yDpi = 100;
mode.group = group;
+ mode.supportedHdrTypes = HDR_TYPES;
return mode;
}
diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
index 109abd0..5af0558 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -219,6 +219,7 @@
SurfaceControl.DisplayMode displayMode = new SurfaceControl.DisplayMode();
displayMode.width = 100;
displayMode.height = 200;
+ displayMode.supportedHdrTypes = new int[]{1, 2};
dynamicDisplayMode.supportedDisplayModes = new SurfaceControl.DisplayMode[] {displayMode};
when(mSurfaceControlProxy.getDynamicDisplayInfo(mMockDisplayToken))
.thenReturn(dynamicDisplayMode);