diff options
| author | 2016-07-20 17:21:33 +0000 | |
|---|---|---|
| committer | 2016-07-20 17:21:35 +0000 | |
| commit | f8bc27d9683e4089cdfd778dcb61ae67f44665b7 (patch) | |
| tree | d9601e641544206c9e08f9ce605bca0578bf7f52 | |
| parent | 39abe33b501a3763c966cc946cfcef8458c68ae4 (diff) | |
| parent | 1c9977b762b4bac46b4470f04c898bfd17da5d90 (diff) | |
Merge "Rename color transform to color mode and persist the value." into nyc-mr1-dev
21 files changed, 492 insertions, 382 deletions
diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java index 93da3e5af4e9..826eb74aef65 100644 --- a/core/java/android/hardware/display/DisplayManagerGlobal.java +++ b/core/java/android/hardware/display/DisplayManagerGlobal.java @@ -354,9 +354,9 @@ public final class DisplayManagerGlobal { } } - public void requestColorTransform(int displayId, int colorTransformId) { + public void requestColorMode(int displayId, int colorMode) { try { - mDm.requestColorTransform(displayId, colorTransformId); + mDm.requestColorMode(displayId, colorMode); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } diff --git a/core/java/android/hardware/display/IDisplayManager.aidl b/core/java/android/hardware/display/IDisplayManager.aidl index 8a1abf18602a..f696c8d15446 100644 --- a/core/java/android/hardware/display/IDisplayManager.aidl +++ b/core/java/android/hardware/display/IDisplayManager.aidl @@ -59,8 +59,8 @@ interface IDisplayManager { // No permissions required. WifiDisplayStatus getWifiDisplayStatus(); - // Requires CONFIGURE_DISPLAY_COLOR_TRANSFORM - void requestColorTransform(int displayId, int colorTransformId); + // Requires CONFIGURE_DISPLAY_COLOR_MODE + void requestColorMode(int displayId, int colorMode); // Requires CAPTURE_VIDEO_OUTPUT, CAPTURE_SECURE_VIDEO_OUTPUT, or an appropriate // MediaProjection token for certain combinations of flags. diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java index 8c49009ebf44..899ae49f31a8 100644 --- a/core/java/android/view/Display.java +++ b/core/java/android/view/Display.java @@ -36,7 +36,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Arrays; -import static android.Manifest.permission.CONFIGURE_DISPLAY_COLOR_TRANSFORM; +import static android.Manifest.permission.CONFIGURE_DISPLAY_COLOR_MODE; /** * Provides information about the size and density of a logical display. @@ -284,6 +284,27 @@ public final class Display { */ public static final int STATE_DOZE_SUSPEND = 4; + /* The color mode constants defined below must be kept in sync with the ones in + * system/graphics.h */ + + /** + * Display color mode: The current color mode is unknown or invalid. + * @hide + */ + public static final int COLOR_MODE_INVALID = -1; + + /** + * Display color mode: The default or native gamut of the display. + * @hide + */ + public static final int COLOR_MODE_DEFAULT = 0; + + /** + * Display color mode: SRGB + * @hide + */ + public static final int COLOR_MODE_SRGB = 7; + /** * Internal method to create a display. * Applications should use {@link android.view.WindowManager#getDefaultDisplay()} @@ -696,33 +717,22 @@ public final class Display { } /** - * Request the display applies a color transform. + * Request the display applies a color mode. * @hide */ - @RequiresPermission(CONFIGURE_DISPLAY_COLOR_TRANSFORM) - public void requestColorTransform(ColorTransform colorTransform) { - mGlobal.requestColorTransform(mDisplayId, colorTransform.getId()); - } - - /** - * Returns the active color transform of this display - * @hide - */ - public ColorTransform getColorTransform() { - synchronized (this) { - updateDisplayInfoLocked(); - return mDisplayInfo.getColorTransform(); - } + @RequiresPermission(CONFIGURE_DISPLAY_COLOR_MODE) + public void requestColorMode(int colorMode) { + mGlobal.requestColorMode(mDisplayId, colorMode); } /** - * Returns the default color transform of this display + * Returns the active color mode of this display * @hide */ - public ColorTransform getDefaultColorTransform() { + public int getColorMode() { synchronized (this) { updateDisplayInfoLocked(); - return mDisplayInfo.getDefaultColorTransform(); + return mDisplayInfo.colorMode; } } @@ -737,14 +747,14 @@ public final class Display { } /** - * Gets the supported color transforms of this device. + * Gets the supported color modes of this device. * @hide */ - public ColorTransform[] getSupportedColorTransforms() { + public int[] getSupportedColorModes() { synchronized (this) { updateDisplayInfoLocked(); - ColorTransform[] transforms = mDisplayInfo.supportedColorTransforms; - return Arrays.copyOf(transforms, transforms.length); + int[] colorModes = mDisplayInfo.supportedColorModes; + return Arrays.copyOf(colorModes, colorModes.length); } } @@ -1263,89 +1273,4 @@ public final class Display { return 0; } } - - /** - * A color transform supported by a given display. - * - * @see Display#getSupportedColorTransforms() - * @hide - */ - public static final class ColorTransform implements Parcelable { - public static final ColorTransform[] EMPTY_ARRAY = new ColorTransform[0]; - - private final int mId; - private final int mColorTransform; - - public ColorTransform(int id, int colorTransform) { - mId = id; - mColorTransform = colorTransform; - } - - public int getId() { - return mId; - } - - public int getColorTransform() { - return mColorTransform; - } - - @Override - public boolean equals(Object other) { - if (this == other) { - return true; - } - if (!(other instanceof ColorTransform)) { - return false; - } - ColorTransform that = (ColorTransform) other; - return mId == that.mId - && mColorTransform == that.mColorTransform; - } - - @Override - public int hashCode() { - int hash = 1; - hash = hash * 17 + mId; - hash = hash * 17 + mColorTransform; - return hash; - } - - @Override - public String toString() { - return new StringBuilder("{") - .append("id=").append(mId) - .append(", colorTransform=").append(mColorTransform) - .append("}") - .toString(); - } - - @Override - public int describeContents() { - return 0; - } - - private ColorTransform(Parcel in) { - this(in.readInt(), in.readInt()); - } - - @Override - public void writeToParcel(Parcel out, int parcelableFlags) { - out.writeInt(mId); - out.writeInt(mColorTransform); - } - - @SuppressWarnings("hiding") - public static final Parcelable.Creator<ColorTransform> CREATOR - = new Parcelable.Creator<ColorTransform>() { - @Override - public ColorTransform createFromParcel(Parcel in) { - return new ColorTransform(in); - } - - @Override - public ColorTransform[] newArray(int size) { - return new ColorTransform[size]; - } - }; - } } diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java index 8aeeffd90643..49c3c46c86fc 100644 --- a/core/java/android/view/DisplayInfo.java +++ b/core/java/android/view/DisplayInfo.java @@ -169,14 +169,11 @@ public final class DisplayInfo implements Parcelable { */ public Display.Mode[] supportedModes = Display.Mode.EMPTY_ARRAY; - /** The active color transform. */ - public int colorTransformId; + /** The active color mode. */ + public int colorMode; - /** The default color transform. */ - public int defaultColorTransformId; - - /** The list of supported color transforms */ - public Display.ColorTransform[] supportedColorTransforms = Display.ColorTransform.EMPTY_ARRAY; + /** The list of supported color modes */ + public int[] supportedColorModes = { Display.COLOR_MODE_DEFAULT }; /** The display's HDR capabilities */ public Display.HdrCapabilities hdrCapabilities; @@ -291,8 +288,8 @@ public final class DisplayInfo implements Parcelable { && rotation == other.rotation && modeId == other.modeId && defaultModeId == other.defaultModeId - && colorTransformId == other.colorTransformId - && defaultColorTransformId == other.defaultColorTransformId + && colorMode == other.colorMode + && Objects.equal(supportedColorModes, other.supportedColorModes) && Objects.equal(hdrCapabilities, other.hdrCapabilities) && logicalDensityDpi == other.logicalDensityDpi && physicalXDpi == other.physicalXDpi @@ -332,10 +329,9 @@ public final class DisplayInfo implements Parcelable { modeId = other.modeId; defaultModeId = other.defaultModeId; supportedModes = Arrays.copyOf(other.supportedModes, other.supportedModes.length); - colorTransformId = other.colorTransformId; - defaultColorTransformId = other.defaultColorTransformId; - supportedColorTransforms = Arrays.copyOf( - other.supportedColorTransforms, other.supportedColorTransforms.length); + colorMode = other.colorMode; + supportedColorModes = Arrays.copyOf( + other.supportedColorModes, other.supportedColorModes.length); hdrCapabilities = other.hdrCapabilities; logicalDensityDpi = other.logicalDensityDpi; physicalXDpi = other.physicalXDpi; @@ -373,12 +369,11 @@ public final class DisplayInfo implements Parcelable { for (int i = 0; i < nModes; i++) { supportedModes[i] = Display.Mode.CREATOR.createFromParcel(source); } - colorTransformId = source.readInt(); - defaultColorTransformId = source.readInt(); - int nColorTransforms = source.readInt(); - supportedColorTransforms = new Display.ColorTransform[nColorTransforms]; - for (int i = 0; i < nColorTransforms; i++) { - supportedColorTransforms[i] = Display.ColorTransform.CREATOR.createFromParcel(source); + colorMode = source.readInt(); + int nColorModes = source.readInt(); + supportedColorModes = new int[nColorModes]; + for (int i = 0; i < nColorModes; i++) { + supportedColorModes[i] = source.readInt(); } hdrCapabilities = source.readParcelable(null); logicalDensityDpi = source.readInt(); @@ -418,11 +413,10 @@ public final class DisplayInfo implements Parcelable { for (int i = 0; i < supportedModes.length; i++) { supportedModes[i].writeToParcel(dest, flags); } - dest.writeInt(colorTransformId); - dest.writeInt(defaultColorTransformId); - dest.writeInt(supportedColorTransforms.length); - for (int i = 0; i < supportedColorTransforms.length; i++) { - supportedColorTransforms[i].writeToParcel(dest, flags); + dest.writeInt(colorMode); + dest.writeInt(supportedColorModes.length); + for (int i = 0; i < supportedColorModes.length; i++) { + dest.writeInt(supportedColorModes[i]); } dest.writeParcelable(hdrCapabilities, flags); dest.writeInt(logicalDensityDpi); @@ -496,24 +490,6 @@ public final class DisplayInfo implements Parcelable { return result; } - public Display.ColorTransform getColorTransform() { - return findColorTransform(colorTransformId); - } - - public Display.ColorTransform getDefaultColorTransform() { - return findColorTransform(defaultColorTransformId); - } - - private Display.ColorTransform findColorTransform(int colorTransformId) { - for (int i = 0; i < supportedColorTransforms.length; i++) { - Display.ColorTransform colorTransform = supportedColorTransforms[i]; - if (colorTransform.getId() == colorTransformId) { - return colorTransform; - } - } - throw new IllegalStateException("Unable to locate color transform: " + colorTransformId); - } - public void getAppMetrics(DisplayMetrics outMetrics) { getAppMetrics(outMetrics, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null); } @@ -615,12 +591,10 @@ public final class DisplayInfo implements Parcelable { sb.append(defaultModeId); sb.append(", modes "); sb.append(Arrays.toString(supportedModes)); - sb.append(", colorTransformId "); - sb.append(colorTransformId); - sb.append(", defaultColorTransformId "); - sb.append(defaultColorTransformId); - sb.append(", supportedColorTransforms "); - sb.append(Arrays.toString(supportedColorTransforms)); + sb.append(", colorMode "); + sb.append(colorMode); + sb.append(", supportedColorModes "); + sb.append(Arrays.toString(supportedColorModes)); sb.append(", hdrCapabilities "); sb.append(hdrCapabilities); sb.append(", rotation "); diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index f1abca8e2a0d..e778a7f16f25 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -82,6 +82,10 @@ public class SurfaceControl { IBinder displayToken); private static native int nativeGetActiveConfig(IBinder displayToken); private static native boolean nativeSetActiveConfig(IBinder displayToken, int id); + private static native int[] nativeGetDisplayColorModes(IBinder displayToken); + private static native int nativeGetActiveColorMode(IBinder displayToken); + private static native boolean nativeSetActiveColorMode(IBinder displayToken, + int colorMode); private static native void nativeSetDisplayPowerMode( IBinder displayToken, int mode); private static native void nativeDeferTransactionUntil(long nativeObject, @@ -547,7 +551,6 @@ public class SurfaceControl { public boolean secure; public long appVsyncOffsetNanos; public long presentationDeadlineNanos; - public int colorTransform; public PhysicalDisplayInfo() { } @@ -571,8 +574,7 @@ public class SurfaceControl { && yDpi == other.yDpi && secure == other.secure && appVsyncOffsetNanos == other.appVsyncOffsetNanos - && presentationDeadlineNanos == other.presentationDeadlineNanos - && colorTransform == other.colorTransform; + && presentationDeadlineNanos == other.presentationDeadlineNanos; } @Override @@ -590,7 +592,6 @@ public class SurfaceControl { secure = other.secure; appVsyncOffsetNanos = other.appVsyncOffsetNanos; presentationDeadlineNanos = other.presentationDeadlineNanos; - colorTransform = other.colorTransform; } // For debugging purposes @@ -599,8 +600,7 @@ public class SurfaceControl { return "PhysicalDisplayInfo{" + width + " x " + height + ", " + refreshRate + " fps, " + "density " + density + ", " + xDpi + " x " + yDpi + " dpi, secure " + secure + ", appVsyncOffset " + appVsyncOffsetNanos - + ", bufferDeadline " + presentationDeadlineNanos - + ", colorTransform " + colorTransform + "}"; + + ", bufferDeadline " + presentationDeadlineNanos + "}"; } } @@ -632,6 +632,27 @@ public class SurfaceControl { return nativeSetActiveConfig(displayToken, id); } + public static int[] getDisplayColorModes(IBinder displayToken) { + if (displayToken == null) { + throw new IllegalArgumentException("displayToken must not be null"); + } + return nativeGetDisplayColorModes(displayToken); + } + + public static int getActiveColorMode(IBinder displayToken) { + if (displayToken == null) { + throw new IllegalArgumentException("displayToken must not be null"); + } + return nativeGetActiveColorMode(displayToken); + } + + public static boolean setActiveColorMode(IBinder displayToken, int colorMode) { + if (displayToken == null) { + throw new IllegalArgumentException("displayToken must not be null"); + } + return nativeSetActiveColorMode(displayToken, colorMode); + } + public static void setDisplayProjection(IBinder displayToken, int orientation, Rect layerStackRect, Rect displayRect) { if (displayToken == null) { diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index fa1313bfd79d..0d8a95c9bcd3 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -32,6 +32,7 @@ #include <jni.h> #include <memory> #include <stdio.h> +#include <system/graphics.h> #include <ui/DisplayInfo.h> #include <ui/HdrCapabilities.h> #include <ui/FrameStats.h> @@ -58,7 +59,6 @@ static struct { jfieldID secure; jfieldID appVsyncOffsetNanos; jfieldID presentationDeadlineNanos; - jfieldID colorTransform; } gPhysicalDisplayInfoClassInfo; static struct { @@ -429,8 +429,6 @@ static jobjectArray nativeGetDisplayConfigs(JNIEnv* env, jclass clazz, info.appVsyncOffset); env->SetLongField(infoObj, gPhysicalDisplayInfoClassInfo.presentationDeadlineNanos, info.presentationDeadline); - env->SetIntField(infoObj, gPhysicalDisplayInfoClassInfo.colorTransform, - info.colorTransform); env->SetObjectArrayElement(configArray, static_cast<jsize>(c), infoObj); env->DeleteLocalRef(infoObj); } @@ -451,6 +449,43 @@ static jboolean nativeSetActiveConfig(JNIEnv* env, jclass clazz, jobject tokenOb return err == NO_ERROR ? JNI_TRUE : JNI_FALSE; } +static jintArray nativeGetDisplayColorModes(JNIEnv* env, jclass, jobject tokenObj) { + sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); + if (token == NULL) return NULL; + Vector<android_color_mode_t> colorModes; + if (SurfaceComposerClient::getDisplayColorModes(token, &colorModes) != NO_ERROR || + colorModes.isEmpty()) { + return NULL; + } + + jintArray colorModesArray = env->NewIntArray(colorModes.size()); + if (colorModesArray == NULL) { + jniThrowException(env, "java/lang/OutOfMemoryError", NULL); + return NULL; + } + jint* colorModesArrayValues = env->GetIntArrayElements(colorModesArray, 0); + for (size_t i = 0; i < colorModes.size(); i++) { + colorModesArrayValues[i] = static_cast<jint>(colorModes[i]); + } + env->ReleaseIntArrayElements(colorModesArray, colorModesArrayValues, 0); + return colorModesArray; +} + +static jint nativeGetActiveColorMode(JNIEnv* env, jclass, jobject tokenObj) { + sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); + if (token == NULL) return -1; + return static_cast<jint>(SurfaceComposerClient::getActiveColorMode(token)); +} + +static jboolean nativeSetActiveColorMode(JNIEnv* env, jclass, + jobject tokenObj, jint colorMode) { + sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); + if (token == NULL) return JNI_FALSE; + status_t err = SurfaceComposerClient::setActiveColorMode(token, + static_cast<android_color_mode_t>(colorMode)); + return err == NO_ERROR ? JNI_TRUE : JNI_FALSE; +} + static void nativeSetDisplayPowerMode(JNIEnv* env, jclass clazz, jobject tokenObj, jint mode) { sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); if (token == NULL) return; @@ -715,6 +750,12 @@ static const JNINativeMethod sSurfaceControlMethods[] = { (void*)nativeGetActiveConfig }, {"nativeSetActiveConfig", "(Landroid/os/IBinder;I)Z", (void*)nativeSetActiveConfig }, + {"nativeGetDisplayColorModes", "(Landroid/os/IBinder;)[I", + (void*)nativeGetDisplayColorModes}, + {"nativeGetActiveColorMode", "(Landroid/os/IBinder;)I", + (void*)nativeGetActiveColorMode}, + {"nativeSetActiveColorMode", "(Landroid/os/IBinder;I)Z", + (void*)nativeSetActiveColorMode}, {"nativeGetHdrCapabilities", "(Landroid/os/IBinder;)Landroid/view/Display$HdrCapabilities;", (void*)nativeGetHdrCapabilities }, {"nativeClearContentFrameStats", "(J)Z", @@ -757,8 +798,6 @@ int register_android_view_SurfaceControl(JNIEnv* env) clazz, "appVsyncOffsetNanos", "J"); gPhysicalDisplayInfoClassInfo.presentationDeadlineNanos = GetFieldIDOrDie(env, clazz, "presentationDeadlineNanos", "J"); - gPhysicalDisplayInfoClassInfo.colorTransform = GetFieldIDOrDie(env, clazz, - "colorTransform", "I"); jclass rectClazz = FindClassOrDie(env, "android/graphics/Rect"); gRectClassInfo.bottom = GetFieldIDOrDie(env, rectClazz, "bottom", "I"); diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 4b66f70dfd20..48dfdff4fd72 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -2508,11 +2508,10 @@ <permission android:name="android.permission.CONTROL_WIFI_DISPLAY" android:protectionLevel="signature" /> - <!-- Allows an application to control the color transforms applied to - displays system-wide. + <!-- Allows an application to control the color modes set for displays system-wide. <p>Not for use by third-party applications.</p> @hide --> - <permission android:name="android.permission.CONFIGURE_DISPLAY_COLOR_TRANSFORM" + <permission android:name="android.permission.CONFIGURE_DISPLAY_COLOR_MODE" android:protectionLevel="signature" /> <!-- @SystemApi Allows an application to control VPN. diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 674a0d7f61eb..2835c6f5fa0a 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -1825,28 +1825,6 @@ --> <bool name="config_enableWifiDisplay">false</bool> - <!-- The color transform values that correspond to each respective configuration mode for the - built-in display, or -1 if the mode is unsupported by the device. The possible - configuration modes are: - 1. Wide-gamut ("Vibrant") - 2. Adobe RGB ("Natural") - 3. sRGB ("Standard") - - For example, if a device had Wide-gamut as color transform mode 1, sRGB mode as color - transform mode 7, and did not support Adobe RGB at all this would look like: - - <integer-array name="config_colorTransforms"> - <item>1</item> - <item>-1</item> - <item>7</item> - </integer-array> - --> - <integer-array name="config_colorTransforms"> - <item>-1</item> - <item>-1</item> - <item>-1</item> - </integer-array> - <!-- When true, local displays that do not contain any of their own content will automatically mirror the content of the default display. --> <bool name="config_localDisplaysMirrorContent">true</bool> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 3590ac86afd0..38749f6e2cfa 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -1142,7 +1142,6 @@ <java-symbol type="array" name="config_telephonyHardware" /> <java-symbol type="array" name="config_keySystemUuidMapping" /> <java-symbol type="array" name="config_gpsParameters" /> - <java-symbol type="array" name="config_colorTransforms" /> <java-symbol type="drawable" name="default_wallpaper" /> <java-symbol type="drawable" name="default_lock_wallpaper" /> diff --git a/libs/hwui/tests/common/TestContext.cpp b/libs/hwui/tests/common/TestContext.cpp index 146e735839d1..99569755205f 100644 --- a/libs/hwui/tests/common/TestContext.cpp +++ b/libs/hwui/tests/common/TestContext.cpp @@ -33,7 +33,6 @@ static android::DisplayInfo DUMMY_DISPLAY { false, // secure? 0, // appVsyncOffset 0, // presentationDeadline - 0, // colorTransform }; DisplayInfo getBuiltInDisplay() { diff --git a/packages/SettingsLib/res/values/arrays.xml b/packages/SettingsLib/res/values/arrays.xml index 525d6f421d71..b8e6d20cc0e2 100644 --- a/packages/SettingsLib/res/values/arrays.xml +++ b/packages/SettingsLib/res/values/arrays.xml @@ -362,4 +362,12 @@ <item>3</item> </string-array> + <!-- IDs for each color mode. The values must match the corresponding constants in + android.view.Display --> + <integer-array name="color_mode_ids"> + <item>0</item> + <item>-1</item> + <item>7</item> + </integer-array> + </resources> diff --git a/services/core/java/com/android/server/display/DisplayAdapter.java b/services/core/java/com/android/server/display/DisplayAdapter.java index 701b9f179f9c..6ba25a53248d 100644 --- a/services/core/java/com/android/server/display/DisplayAdapter.java +++ b/services/core/java/com/android/server/display/DisplayAdapter.java @@ -49,13 +49,6 @@ abstract class DisplayAdapter { */ private static final AtomicInteger NEXT_DISPLAY_MODE_ID = new AtomicInteger(1); // 0 = no mode. - /** - * Used to generate globally unique color transform ids. - * - * Valid IDs start at 1 with 0 as the sentinel value for the default mode. - */ - private static final AtomicInteger NEXT_COLOR_TRANSFORM_ID = new AtomicInteger(1); - // Called with SyncRoot lock held. public DisplayAdapter(DisplayManagerService.SyncRoot syncRoot, Context context, Handler handler, Listener listener, String name) { @@ -141,11 +134,6 @@ abstract class DisplayAdapter { NEXT_DISPLAY_MODE_ID.getAndIncrement(), width, height, refreshRate); } - public static Display.ColorTransform createColorTransform(int colorTransform) { - return new Display.ColorTransform( - NEXT_COLOR_TRANSFORM_ID.getAndIncrement(), colorTransform); - } - public interface Listener { public void onDisplayDeviceEvent(DisplayDevice device, int event); public void onTraversalRequested(); diff --git a/services/core/java/com/android/server/display/DisplayDevice.java b/services/core/java/com/android/server/display/DisplayDevice.java index 7af0bdbdc357..839ab4d4867d 100644 --- a/services/core/java/com/android/server/display/DisplayDevice.java +++ b/services/core/java/com/android/server/display/DisplayDevice.java @@ -94,6 +94,11 @@ abstract class DisplayDevice { } /** + * Returns whether the unique id of the device is stable across reboots. + */ + public abstract boolean hasStableUniqueId(); + + /** * Gets information about the display device. * * The information returned should not change between calls unless the display @@ -135,7 +140,7 @@ abstract class DisplayDevice { /** * Sets the mode, if supported. */ - public void requestColorTransformAndModeInTransactionLocked(int colorTransformId, int modeId) { + public void requestDisplayModesInTransactionLocked(int colorMode, int modeId) { } /** diff --git a/services/core/java/com/android/server/display/DisplayDeviceInfo.java b/services/core/java/com/android/server/display/DisplayDeviceInfo.java index 5ce66fae3429..671918209b25 100644 --- a/services/core/java/com/android/server/display/DisplayDeviceInfo.java +++ b/services/core/java/com/android/server/display/DisplayDeviceInfo.java @@ -118,6 +118,11 @@ final class DisplayDeviceInfo { public static final int DIFF_OTHER = 1 << 1; /** + * Diff result: The color mode fields differ. + */ + public static final int DIFF_COLOR_MODE = 1 << 2; + + /** * Gets the name of the display device, which may be derived from EDID or * other sources. The name may be localized and displayed to the user. */ @@ -155,14 +160,11 @@ final class DisplayDeviceInfo { */ public Display.Mode[] supportedModes = Display.Mode.EMPTY_ARRAY; - /** The active color transform of the display */ - public int colorTransformId; + /** The active color mode of the display */ + public int colorMode; - /** The default color transform of the display */ - public int defaultColorTransformId; - - /** The supported color transforms of the display */ - public Display.ColorTransform[] supportedColorTransforms = Display.ColorTransform.EMPTY_ARRAY; + /** The supported color modes of the display */ + public int[] supportedColorModes = { Display.COLOR_MODE_DEFAULT }; /** * The HDR capabilities this display claims to support. @@ -283,6 +285,9 @@ final class DisplayDeviceInfo { if (state != other.state) { diff |= DIFF_STATE; } + if (colorMode != other.colorMode) { + diff |= DIFF_COLOR_MODE; + } if (!Objects.equal(name, other.name) || !Objects.equal(uniqueId, other.uniqueId) || width != other.width @@ -290,9 +295,7 @@ final class DisplayDeviceInfo { || modeId != other.modeId || defaultModeId != other.defaultModeId || !Arrays.equals(supportedModes, other.supportedModes) - || colorTransformId != other.colorTransformId - || defaultColorTransformId != other.defaultColorTransformId - || !Arrays.equals(supportedColorTransforms, other.supportedColorTransforms) + || !Arrays.equals(supportedColorModes, other.supportedColorModes) || !Objects.equal(hdrCapabilities, other.hdrCapabilities) || densityDpi != other.densityDpi || xDpi != other.xDpi @@ -324,9 +327,8 @@ final class DisplayDeviceInfo { modeId = other.modeId; defaultModeId = other.defaultModeId; supportedModes = other.supportedModes; - colorTransformId = other.colorTransformId; - defaultColorTransformId = other.defaultColorTransformId; - supportedColorTransforms = other.supportedColorTransforms; + colorMode = other.colorMode; + supportedColorModes = other.supportedColorModes; hdrCapabilities = other.hdrCapabilities; densityDpi = other.densityDpi; xDpi = other.xDpi; @@ -353,9 +355,8 @@ final class DisplayDeviceInfo { sb.append(", modeId ").append(modeId); sb.append(", defaultModeId ").append(defaultModeId); sb.append(", supportedModes ").append(Arrays.toString(supportedModes)); - sb.append(", colorTransformId ").append(colorTransformId); - sb.append(", defaultColorTransformId ").append(defaultColorTransformId); - sb.append(", supportedColorTransforms ").append(Arrays.toString(supportedColorTransforms)); + sb.append(", colorMode ").append(colorMode); + sb.append(", supportedColorModes ").append(Arrays.toString(supportedColorModes)); sb.append(", HdrCapabilities ").append(hdrCapabilities); sb.append(", density ").append(densityDpi); sb.append(", ").append(xDpi).append(" x ").append(yDpi).append(" dpi"); diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index fec7ed1ff998..0abd2e79b45f 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -239,6 +239,11 @@ public final class DisplayManagerService extends SystemService { @Override public void onStart() { + // We need to pre-load the persistent data store so it's ready before the default display + // adapter is up so that we have it's configuration. We could load it lazily, but since + // we're going to have to read it in eventually we may as well do it here rather than after + // we've waited for the diplay to register itself with us. + mPersistentDataStore.loadIfNeeded(); mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER); publishBinderService(Context.DISPLAY_SERVICE, new BinderService(), @@ -541,12 +546,12 @@ public final class DisplayManagerService extends SystemService { } } - private void requestColorTransformInternal(int displayId, int colorTransformId) { + private void requestColorModeInternal(int displayId, int colorMode) { synchronized (mSyncRoot) { LogicalDisplay display = mLogicalDisplays.get(displayId); if (display != null && - display.getRequestedColorTransformIdLocked() != colorTransformId) { - display.setRequestedColorTransformIdLocked(colorTransformId); + display.getRequestedColorModeLocked() != colorMode) { + display.setRequestedColorModeLocked(colorMode); scheduleTraversalLocked(false); } } @@ -691,11 +696,15 @@ public final class DisplayManagerService extends SystemService { device.mDebugLastLoggedDeviceInfo = info; mDisplayDevices.add(device); - addLogicalDisplayLocked(device); + LogicalDisplay display = addLogicalDisplayLocked(device); Runnable work = updateDisplayStateLocked(device); if (work != null) { work.run(); } + if (display != null && display.getPrimaryDisplayDeviceLocked() == device) { + int colorMode = mPersistentDataStore.getColorMode(device); + display.setRequestedColorModeLocked(colorMode); + } scheduleTraversalLocked(false); } @@ -714,6 +723,13 @@ public final class DisplayManagerService extends SystemService { } else if (diff != 0) { Slog.i(TAG, "Display device changed: " + info); } + if ((diff & DisplayDeviceInfo.DIFF_COLOR_MODE) != 0) { + try { + mPersistentDataStore.setColorMode(device, info.colorMode); + } finally { + mPersistentDataStore.saveIfNeeded(); + } + } device.mDebugLastLoggedDeviceInfo = info; device.applyPendingDisplayDeviceInfoChangesLocked(); @@ -766,7 +782,7 @@ public final class DisplayManagerService extends SystemService { // Adds a new logical display based on the given display device. // Sends notifications if needed. - private void addLogicalDisplayLocked(DisplayDevice device) { + private LogicalDisplay addLogicalDisplayLocked(DisplayDevice device) { DisplayDeviceInfo deviceInfo = device.getDisplayDeviceInfoLocked(); boolean isDefault = (deviceInfo.flags & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0; @@ -778,7 +794,7 @@ public final class DisplayManagerService extends SystemService { if (!isDefault && mSingleDisplayDemoMode) { Slog.i(TAG, "Not creating a logical display for a secondary display " + " because single display demo mode is enabled: " + deviceInfo); - return; + return null; } final int displayId = assignDisplayIdLocked(isDefault); @@ -790,7 +806,7 @@ public final class DisplayManagerService extends SystemService { // This should never happen currently. Slog.w(TAG, "Ignoring display device because the logical display " + "created from it was not considered valid: " + deviceInfo); - return; + return null; } mLogicalDisplays.put(displayId, display); @@ -801,6 +817,7 @@ public final class DisplayManagerService extends SystemService { } sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_ADDED); + return display; } private int assignDisplayIdLocked(boolean isDefault) { @@ -1068,6 +1085,9 @@ public final class DisplayManagerService extends SystemService { if (mDisplayPowerController != null) { mDisplayPowerController.dump(pw); } + + pw.println(); + mPersistentDataStore.dump(pw); } } @@ -1352,13 +1372,13 @@ public final class DisplayManagerService extends SystemService { } @Override // Binder call - public void requestColorTransform(int displayId, int colorTransformId) { + public void requestColorMode(int displayId, int colorMode) { mContext.enforceCallingOrSelfPermission( - Manifest.permission.CONFIGURE_DISPLAY_COLOR_TRANSFORM, - "Permission required to change the display color transform"); + Manifest.permission.CONFIGURE_DISPLAY_COLOR_MODE, + "Permission required to change the display color mode"); final long token = Binder.clearCallingIdentity(); try { - requestColorTransformInternal(displayId, colorTransformId); + requestColorModeInternal(displayId, colorMode); } finally { Binder.restoreCallingIdentity(token); } diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java index 7b16ea61eb74..61c2eacaa8f9 100644 --- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java +++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java @@ -39,6 +39,8 @@ import android.view.SurfaceControl; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; +import java.util.List; /** * A display adapter for the local displays managed by Surface Flinger. @@ -100,14 +102,25 @@ final class LocalDisplayAdapter extends DisplayAdapter { builtInDisplayId); return; } + int activeColorMode = SurfaceControl.getActiveColorMode(displayToken); + if (activeColorMode < 0) { + // We failed to get the active color mode. We don't bail out here since on the next + // configuration pass we'll go ahead and set it to whatever it was set to last (or + // COLOR_MODE_NATIVE if this is the first configuration). + Slog.w(TAG, "Unable to get active color mode for display device " + + builtInDisplayId); + activeColorMode = Display.COLOR_MODE_INVALID; + } + int[] colorModes = SurfaceControl.getDisplayColorModes(displayToken); LocalDisplayDevice device = mDevices.get(builtInDisplayId); if (device == null) { // Display was added. device = new LocalDisplayDevice(displayToken, builtInDisplayId, - configs, activeConfig); + configs, activeConfig, colorModes, activeColorMode); mDevices.put(builtInDisplayId, device); sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_ADDED); - } else if (device.updatePhysicalDisplayInfoLocked(configs, activeConfig)) { + } else if (device.updatePhysicalDisplayInfoLocked(configs, activeConfig, + colorModes, activeColorMode)) { // Display properties changed. sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_CHANGED); } @@ -144,8 +157,7 @@ final class LocalDisplayAdapter extends DisplayAdapter { private final int mBuiltInDisplayId; private final Light mBacklight; private final SparseArray<DisplayModeRecord> mSupportedModes = new SparseArray<>(); - private final SparseArray<Display.ColorTransform> mSupportedColorTransforms = - new SparseArray<>(); + private final ArrayList<Integer> mSupportedColorModes = new ArrayList<>(); private DisplayDeviceInfo mInfo; private boolean mHavePendingChanges; @@ -155,18 +167,20 @@ final class LocalDisplayAdapter extends DisplayAdapter { private int mDefaultModeId; private int mActiveModeId; private boolean mActiveModeInvalid; - private int mDefaultColorTransformId; - private int mActiveColorTransformId; - private boolean mActiveColorTransformInvalid; + private int mActiveColorMode; + private boolean mActiveColorModeInvalid; private Display.HdrCapabilities mHdrCapabilities; private SurfaceControl.PhysicalDisplayInfo mDisplayInfos[]; public LocalDisplayDevice(IBinder displayToken, int builtInDisplayId, - SurfaceControl.PhysicalDisplayInfo[] physicalDisplayInfos, int activeDisplayInfo) { + SurfaceControl.PhysicalDisplayInfo[] physicalDisplayInfos, int activeDisplayInfo, + int[] colorModes, int activeColorMode) { super(LocalDisplayAdapter.this, displayToken, UNIQUE_ID_PREFIX + builtInDisplayId); mBuiltInDisplayId = builtInDisplayId; - updatePhysicalDisplayInfoLocked(physicalDisplayInfos, activeDisplayInfo); + updatePhysicalDisplayInfoLocked(physicalDisplayInfos, activeDisplayInfo, + colorModes, activeColorMode); + updateColorModesLocked(colorModes, activeColorMode); if (mBuiltInDisplayId == SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN) { LightsManager lights = LocalServices.getService(LightsManager.class); mBacklight = lights.getLight(LightsManager.LIGHT_ID_BACKLIGHT); @@ -176,39 +190,16 @@ final class LocalDisplayAdapter extends DisplayAdapter { mHdrCapabilities = SurfaceControl.getHdrCapabilities(displayToken); } + @Override + public boolean hasStableUniqueId() { + return true; + } + public boolean updatePhysicalDisplayInfoLocked( - SurfaceControl.PhysicalDisplayInfo[] physicalDisplayInfos, int activeDisplayInfo) { + SurfaceControl.PhysicalDisplayInfo[] physicalDisplayInfos, int activeDisplayInfo, + int[] colorModes, int activeColorMode) { mDisplayInfos = Arrays.copyOf(physicalDisplayInfos, physicalDisplayInfos.length); mActivePhysIndex = activeDisplayInfo; - ArrayList<Display.ColorTransform> colorTransforms = new ArrayList<>(); - - // Build an updated list of all existing color transforms. - boolean colorTransformsAdded = false; - Display.ColorTransform activeColorTransform = null; - for (int i = 0; i < physicalDisplayInfos.length; i++) { - SurfaceControl.PhysicalDisplayInfo info = physicalDisplayInfos[i]; - // First check to see if we've already added this color transform - boolean existingMode = false; - for (int j = 0; j < colorTransforms.size(); j++) { - if (colorTransforms.get(j).getColorTransform() == info.colorTransform) { - existingMode = true; - break; - } - } - if (existingMode) { - continue; - } - Display.ColorTransform colorTransform = findColorTransform(info); - if (colorTransform == null) { - colorTransform = createColorTransform(info.colorTransform); - colorTransformsAdded = true; - } - colorTransforms.add(colorTransform); - if (i == activeDisplayInfo) { - activeColorTransform = colorTransform; - } - } - // Build an updated list of all existing modes. ArrayList<DisplayModeRecord> records = new ArrayList<DisplayModeRecord>(); boolean modesAdded = false; @@ -254,21 +245,10 @@ final class LocalDisplayAdapter extends DisplayAdapter { mActiveModeInvalid = true; sendTraversalRequestLocked(); } - // Check whether surface flinger spontaneously changed color transforms out from under - // us. - if (mActiveColorTransformId != 0 - && mActiveColorTransformId != activeColorTransform.getId()) { - mActiveColorTransformInvalid = true; - sendTraversalRequestLocked(); - } - boolean colorTransformsChanged = - colorTransforms.size() != mSupportedColorTransforms.size() - || colorTransformsAdded; boolean recordsChanged = records.size() != mSupportedModes.size() || modesAdded; - // If neither the records nor the supported color transforms have changed then we're - // done here. - if (!recordsChanged && !colorTransformsChanged) { + // If the records haven't changed then we're done here. + if (!recordsChanged) { return false; } // Update the index of modes. @@ -278,24 +258,13 @@ final class LocalDisplayAdapter extends DisplayAdapter { for (DisplayModeRecord record : records) { mSupportedModes.put(record.mMode.getModeId(), record); } - mSupportedColorTransforms.clear(); - for (Display.ColorTransform colorTransform : colorTransforms) { - mSupportedColorTransforms.put(colorTransform.getId(), colorTransform); - } - - // Update the default mode and color transform if needed. This needs to be done in - // tandem so we always have a default state to fall back to. - if (findDisplayInfoIndexLocked(mDefaultColorTransformId, mDefaultModeId) < 0) { + // Update the default mode, if needed. + if (findDisplayInfoIndexLocked(mDefaultModeId) < 0) { if (mDefaultModeId != 0) { Slog.w(TAG, "Default display mode no longer available, using currently" + " active mode as default."); } mDefaultModeId = activeRecord.mMode.getModeId(); - if (mDefaultColorTransformId != 0) { - Slog.w(TAG, "Default color transform no longer available, using currently" - + " active color transform as default"); - } - mDefaultColorTransformId = activeColorTransform.getId(); } // Determine whether the active mode is still there. if (mSupportedModes.indexOfKey(mActiveModeId) < 0) { @@ -307,20 +276,62 @@ final class LocalDisplayAdapter extends DisplayAdapter { mActiveModeInvalid = true; } - // Determine whether the active color transform is still there. - if (mSupportedColorTransforms.indexOfKey(mActiveColorTransformId) < 0) { - if (mActiveColorTransformId != 0) { - Slog.w(TAG, "Active color transform no longer available, reverting" - + " to default transform."); - } - mActiveColorTransformId = mDefaultColorTransformId; - mActiveColorTransformInvalid = true; - } // Schedule traversals so that we apply pending changes. sendTraversalRequestLocked(); return true; } + private boolean updateColorModesLocked(int[] colorModes, + int activeColorMode) { + List<Integer> pendingColorModes = new ArrayList<>(); + + // Build an updated list of all existing color modes. + boolean colorModesAdded = false; + for (int colorMode: colorModes) { + if (!mSupportedColorModes.contains(colorMode)) { + colorModesAdded = true; + } + pendingColorModes.add(colorMode); + } + + boolean colorModesChanged = + pendingColorModes.size() != mSupportedColorModes.size() + || colorModesAdded; + + // If the supported color modes haven't changed then we're done here. + if (!colorModesChanged) { + return false; + } + + mHavePendingChanges = true; + + mSupportedColorModes.clear(); + mSupportedColorModes.addAll(pendingColorModes); + Collections.sort(mSupportedColorModes); + + // Determine whether the active color mode is still there. + if (!mSupportedColorModes.contains(mActiveColorMode)) { + if (mActiveColorMode != 0) { + Slog.w(TAG, "Active color mode no longer available, reverting" + + " to default mode."); + mActiveColorMode = Display.COLOR_MODE_DEFAULT; + mActiveColorModeInvalid = true; + } else { + if (!mSupportedColorModes.isEmpty()) { + // This should never happen. + Slog.e(TAG, "Default and active color mode is no longer available!" + + " Reverting to first available mode."); + mActiveColorMode = mSupportedColorModes.get(0); + mActiveColorModeInvalid = true; + } else { + // This should really never happen. + Slog.e(TAG, "No color modes available!"); + } + } + } + return true; + } + private DisplayModeRecord findDisplayModeRecord(SurfaceControl.PhysicalDisplayInfo info) { for (int i = 0; i < mSupportedModes.size(); i++) { DisplayModeRecord record = mSupportedModes.valueAt(i); @@ -331,16 +342,6 @@ final class LocalDisplayAdapter extends DisplayAdapter { return null; } - private Display.ColorTransform findColorTransform(SurfaceControl.PhysicalDisplayInfo info) { - for (int i = 0; i < mSupportedColorTransforms.size(); i++) { - Display.ColorTransform transform = mSupportedColorTransforms.valueAt(i); - if (transform.getColorTransform() == info.colorTransform) { - return transform; - } - } - return null; - } - @Override public void applyPendingDisplayDeviceInfoChangesLocked() { if (mHavePendingChanges) { @@ -363,12 +364,11 @@ final class LocalDisplayAdapter extends DisplayAdapter { DisplayModeRecord record = mSupportedModes.valueAt(i); mInfo.supportedModes[i] = record.mMode; } - mInfo.colorTransformId = mActiveColorTransformId; - mInfo.defaultColorTransformId = mDefaultColorTransformId; - mInfo.supportedColorTransforms = - new Display.ColorTransform[mSupportedColorTransforms.size()]; - for (int i = 0; i < mSupportedColorTransforms.size(); i++) { - mInfo.supportedColorTransforms[i] = mSupportedColorTransforms.valueAt(i); + mInfo.colorMode = mActiveColorMode; + mInfo.supportedColorModes = + new int[mSupportedColorModes.size()]; + for (int i = 0; i < mSupportedColorModes.size(); i++) { + mInfo.supportedColorModes[i] = mSupportedColorModes.get(i); } mInfo.hdrCapabilities = mHdrCapabilities; mInfo.appVsyncOffsetNanos = phys.appVsyncOffsetNanos; @@ -520,8 +520,15 @@ final class LocalDisplayAdapter extends DisplayAdapter { } @Override - public void requestColorTransformAndModeInTransactionLocked( - int colorTransformId, int modeId) { + public void requestDisplayModesInTransactionLocked( + int colorMode, int modeId) { + if (requestModeInTransactionLocked(modeId) || + requestColorModeInTransactionLocked(colorMode)) { + updateDeviceInfoLocked(); + } + } + + public boolean requestModeInTransactionLocked(int modeId) { if (modeId == 0) { modeId = mDefaultModeId; } else if (mSupportedModes.indexOfKey(modeId) < 0) { @@ -530,37 +537,36 @@ final class LocalDisplayAdapter extends DisplayAdapter { modeId = mDefaultModeId; } - if (colorTransformId == 0) { - colorTransformId = mDefaultColorTransformId; - } else if (mSupportedColorTransforms.indexOfKey(colorTransformId) < 0) { - Slog.w(TAG, "Requested color transform " + colorTransformId + " is not supported" - + " by this display, reverting to the default color transform"); - colorTransformId = mDefaultColorTransformId; - } - int physIndex = findDisplayInfoIndexLocked(colorTransformId, modeId); + int physIndex = findDisplayInfoIndexLocked(modeId); if (physIndex < 0) { - Slog.w(TAG, "Requested color transform, mode ID pair (" + colorTransformId + ", " - + modeId + ") not available, trying color transform with default mode ID"); + Slog.w(TAG, "Requested mode ID " + modeId + " not available," + + " trying with default mode ID"); modeId = mDefaultModeId; - physIndex = findDisplayInfoIndexLocked(colorTransformId, modeId); - if (physIndex < 0) { - Slog.w(TAG, "Requested color transform with default mode ID still not" - + " available, falling back to default color transform with default" - + " mode."); - colorTransformId = mDefaultColorTransformId; - physIndex = findDisplayInfoIndexLocked(colorTransformId, modeId); - } + physIndex = findDisplayInfoIndexLocked(modeId); } if (mActivePhysIndex == physIndex) { - return; + return false; } SurfaceControl.setActiveConfig(getDisplayTokenLocked(), physIndex); mActivePhysIndex = physIndex; mActiveModeId = modeId; mActiveModeInvalid = false; - mActiveColorTransformId = colorTransformId; - mActiveColorTransformInvalid = false; - updateDeviceInfoLocked(); + return true; + } + + public boolean requestColorModeInTransactionLocked(int colorMode) { + if (mActiveColorMode == colorMode) { + return false; + } + if (!mSupportedColorModes.contains(colorMode)) { + Slog.w(TAG, "Unable to find color mode " + colorMode + + ", ignoring request."); + return false; + } + SurfaceControl.setActiveColorMode(getDisplayTokenLocked(), colorMode); + mActiveColorMode = colorMode; + mActiveColorModeInvalid = false; + return true; } @Override @@ -569,7 +575,7 @@ final class LocalDisplayAdapter extends DisplayAdapter { pw.println("mBuiltInDisplayId=" + mBuiltInDisplayId); pw.println("mActivePhysIndex=" + mActivePhysIndex); pw.println("mActiveModeId=" + mActiveModeId); - pw.println("mActiveColorTransformId=" + mActiveColorTransformId); + pw.println("mActiveColorMode=" + mActiveColorMode); pw.println("mState=" + Display.stateToString(mState)); pw.println("mBrightness=" + mBrightness); pw.println("mBacklight=" + mBacklight); @@ -581,24 +587,22 @@ final class LocalDisplayAdapter extends DisplayAdapter { for (int i = 0; i < mSupportedModes.size(); i++) { pw.println(" " + mSupportedModes.valueAt(i)); } - pw.println("mSupportedColorTransforms=["); - for (int i = 0; i < mSupportedColorTransforms.size(); i++) { + pw.print("mSupportedColorModes=["); + for (int i = 0; i < mSupportedColorModes.size(); i++) { if (i != 0) { pw.print(", "); } - pw.print(mSupportedColorTransforms.valueAt(i)); + pw.print(mSupportedColorModes.get(i)); } pw.println("]"); } - private int findDisplayInfoIndexLocked(int colorTransformId, int modeId) { + private int findDisplayInfoIndexLocked(int modeId) { DisplayModeRecord record = mSupportedModes.get(modeId); - Display.ColorTransform transform = mSupportedColorTransforms.get(colorTransformId); - if (record != null && transform != null) { + if (record != null) { for (int i = 0; i < mDisplayInfos.length; i++) { SurfaceControl.PhysicalDisplayInfo info = mDisplayInfos[i]; - if (info.colorTransform == transform.getColorTransform() - && record.hasMatchingMode(info)){ + if (record.hasMatchingMode(info)){ return i; } } diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java index 973f04ccc6a9..287a25aa9b3e 100644 --- a/services/core/java/com/android/server/display/LogicalDisplay.java +++ b/services/core/java/com/android/server/display/LogicalDisplay.java @@ -74,7 +74,7 @@ final class LogicalDisplay { private boolean mHasContent; private int mRequestedModeId; - private int mRequestedColorTransformId; + private int mRequestedColorMode; // The display offsets to apply to the display projection. private int mDisplayOffsetX; @@ -236,11 +236,10 @@ final class LogicalDisplay { mBaseDisplayInfo.defaultModeId = deviceInfo.defaultModeId; mBaseDisplayInfo.supportedModes = Arrays.copyOf( deviceInfo.supportedModes, deviceInfo.supportedModes.length); - mBaseDisplayInfo.colorTransformId = deviceInfo.colorTransformId; - mBaseDisplayInfo.defaultColorTransformId = deviceInfo.defaultColorTransformId; - mBaseDisplayInfo.supportedColorTransforms = Arrays.copyOf( - deviceInfo.supportedColorTransforms, - deviceInfo.supportedColorTransforms.length); + mBaseDisplayInfo.colorMode = deviceInfo.colorMode; + mBaseDisplayInfo.supportedColorModes = Arrays.copyOf( + deviceInfo.supportedColorModes, + deviceInfo.supportedColorModes.length); mBaseDisplayInfo.hdrCapabilities = deviceInfo.hdrCapabilities; mBaseDisplayInfo.logicalDensityDpi = deviceInfo.densityDpi; mBaseDisplayInfo.physicalXDpi = deviceInfo.xDpi; @@ -282,12 +281,12 @@ final class LogicalDisplay { // Set the layer stack. device.setLayerStackInTransactionLocked(isBlanked ? BLANK_LAYER_STACK : mLayerStack); - // Set the color transform and mode. + // Set the color mode and mode. if (device == mPrimaryDisplayDevice) { - device.requestColorTransformAndModeInTransactionLocked( - mRequestedColorTransformId, mRequestedModeId); + device.requestDisplayModesInTransactionLocked( + mRequestedColorMode, mRequestedModeId); } else { - device.requestColorTransformAndModeInTransactionLocked(0, 0); // Revert to default. + device.requestDisplayModesInTransactionLocked(0, 0); // Revert to default. } // Only grab the display info now as it may have been changed based on the requests above. @@ -391,15 +390,15 @@ final class LogicalDisplay { } /** - * Requests the given color transform. + * Requests the given color mode. */ - public void setRequestedColorTransformIdLocked(int colorTransformId) { - mRequestedColorTransformId = colorTransformId; + public void setRequestedColorModeLocked(int colorMode) { + mRequestedColorMode = colorMode; } - /** Returns the pending requested color transform. */ - public int getRequestedColorTransformIdLocked() { - return mRequestedColorTransformId; + /** Returns the pending requested color mode. */ + public int getRequestedColorModeLocked() { + return mRequestedColorMode; } /** @@ -429,7 +428,7 @@ final class LogicalDisplay { pw.println("mLayerStack=" + mLayerStack); pw.println("mHasContent=" + mHasContent); pw.println("mRequestedMode=" + mRequestedModeId); - pw.println("mRequestedColorTransformId=" + mRequestedColorTransformId); + pw.println("mRequestedColorMode=" + mRequestedColorMode); pw.println("mDisplayOffset=(" + mDisplayOffsetX + ", " + mDisplayOffsetY + ")"); pw.println("mPrimaryDisplayDevice=" + (mPrimaryDisplayDevice != null ? mPrimaryDisplayDevice.getNameLocked() : "null")); diff --git a/services/core/java/com/android/server/display/OverlayDisplayAdapter.java b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java index cf6264ace34f..27327d4eb100 100644 --- a/services/core/java/com/android/server/display/OverlayDisplayAdapter.java +++ b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java @@ -266,6 +266,11 @@ final class OverlayDisplayAdapter extends DisplayAdapter { } @Override + public boolean hasStableUniqueId() { + return false; + } + + @Override public void performTraversalInTransactionLocked() { if (mSurfaceTexture != null) { if (mSurface == null) { @@ -310,7 +315,7 @@ final class OverlayDisplayAdapter extends DisplayAdapter { } @Override - public void requestColorTransformAndModeInTransactionLocked(int color, int id) { + public void requestDisplayModesInTransactionLocked(int color, int id) { int index = -1; if (id == 0) { // Use the default. diff --git a/services/core/java/com/android/server/display/PersistentDataStore.java b/services/core/java/com/android/server/display/PersistentDataStore.java index d676b35998d2..5616fb97bad7 100644 --- a/services/core/java/com/android/server/display/PersistentDataStore.java +++ b/services/core/java/com/android/server/display/PersistentDataStore.java @@ -27,6 +27,7 @@ import android.hardware.display.WifiDisplay; import android.util.AtomicFile; import android.util.Slog; import android.util.Xml; +import android.view.Display; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; @@ -35,8 +36,11 @@ import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.io.PrintWriter; import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; import libcore.io.IoUtils; import libcore.util.Objects; @@ -50,8 +54,13 @@ import libcore.util.Objects; * <display-manager-state> * <remembered-wifi-displays> * <wifi-display deviceAddress="00:00:00:00:00:00" deviceName="XXXX" deviceAlias="YYYY" /> - * >remembered-wifi-displays> - * >/display-manager-state> + * <remembered-wifi-displays> + * <display-states> + * <display> + * <color-mode>0</color-mode> + * </display> + * </display-states> + * </display-manager-state> * </code> * * TODO: refactor this to extract common code shared with the input manager's data store @@ -62,6 +71,10 @@ final class PersistentDataStore { // Remembered Wifi display devices. private ArrayList<WifiDisplay> mRememberedWifiDisplays = new ArrayList<WifiDisplay>(); + // Display state by unique id. + private final HashMap<String, DisplayState> mDisplayStates = + new HashMap<String, DisplayState>(); + // The atomic file used to safely read or write the file. private final AtomicFile mAtomicFile; @@ -168,7 +181,41 @@ final class PersistentDataStore { return -1; } - private void loadIfNeeded() { + public int getColorMode(DisplayDevice device) { + if (!device.hasStableUniqueId()) { + return Display.COLOR_MODE_DEFAULT; + } + DisplayState state = getDisplayState(device.getUniqueId(), false); + if (state == null) { + return Display.COLOR_MODE_DEFAULT; + } + return state.getColorMode(); + } + + public boolean setColorMode(DisplayDevice device, int colorMode) { + if (!device.hasStableUniqueId()) { + return false; + } + DisplayState state = getDisplayState(device.getUniqueId(), true); + if (state.setColorMode(colorMode)) { + setDirty(); + return true; + } + return false; + } + + private DisplayState getDisplayState(String uniqueId, boolean createIfAbsent) { + loadIfNeeded(); + DisplayState state = mDisplayStates.get(uniqueId); + if (state == null && createIfAbsent) { + state = new DisplayState(); + mDisplayStates.put(uniqueId, state); + setDirty(); + } + return state; + } + + public void loadIfNeeded() { if (!mLoaded) { load(); mLoaded = true; @@ -240,6 +287,9 @@ final class PersistentDataStore { if (parser.getName().equals("remembered-wifi-displays")) { loadRememberedWifiDisplaysFromXml(parser); } + if (parser.getName().equals("display-states")) { + loadDisplaysFromXml(parser); + } } } @@ -267,6 +317,27 @@ final class PersistentDataStore { } } + private void loadDisplaysFromXml(XmlPullParser parser) + throws IOException, XmlPullParserException { + final int outerDepth = parser.getDepth(); + while (XmlUtils.nextElementWithin(parser, outerDepth)) { + if (parser.getName().equals("display")) { + String uniqueId = parser.getAttributeValue(null, "unique-id"); + if (uniqueId == null) { + throw new XmlPullParserException( + "Missing unique-id attribute on display."); + } + if (mDisplayStates.containsKey(uniqueId)) { + throw new XmlPullParserException("Found duplicate display."); + } + + DisplayState state = new DisplayState(); + state.loadFromXml(parser); + mDisplayStates.put(uniqueId, state); + } + } + } + private void saveToXml(XmlSerializer serializer) throws IOException { serializer.startDocument(null, true); serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); @@ -282,7 +353,72 @@ final class PersistentDataStore { serializer.endTag(null, "wifi-display"); } serializer.endTag(null, "remembered-wifi-displays"); + serializer.startTag(null, "display-states"); + for (Map.Entry<String, DisplayState> entry : mDisplayStates.entrySet()) { + final String uniqueId = entry.getKey(); + final DisplayState state = entry.getValue(); + serializer.startTag(null, "display"); + serializer.attribute(null, "unique-id", uniqueId); + state.saveToXml(serializer); + serializer.endTag(null, "display"); + } + serializer.endTag(null, "display-states"); serializer.endTag(null, "display-manager-state"); serializer.endDocument(); } + + public void dump(PrintWriter pw) { + pw.println("PersistentDataStore"); + pw.println(" mLoaded=" + mLoaded); + pw.println(" mDirty=" + mDirty); + pw.println(" RememberedWifiDisplays:"); + int i = 0; + for (WifiDisplay display : mRememberedWifiDisplays) { + pw.println(" " + i++ + ": " + display); + } + pw.println(" DisplayStates:"); + i = 0; + for (Map.Entry<String, DisplayState> entry : mDisplayStates.entrySet()) { + pw.println(" " + i++ + ": " + entry.getKey()); + entry.getValue().dump(pw, " "); + } + } + + private static final class DisplayState { + private int mColorMode; + + public boolean setColorMode(int colorMode) { + if (colorMode == mColorMode) { + return false; + } + mColorMode = colorMode; + return true; + } + + public int getColorMode() { + return mColorMode; + } + + public void loadFromXml(XmlPullParser parser) + throws IOException, XmlPullParserException { + final int outerDepth = parser.getDepth(); + + while (XmlUtils.nextElementWithin(parser, outerDepth)) { + if (parser.getName().equals("color-mode")) { + String value = parser.nextText(); + mColorMode = Integer.parseInt(value); + } + } + } + + public void saveToXml(XmlSerializer serializer) throws IOException { + serializer.startTag(null, "color-mode"); + serializer.text(Integer.toString(mColorMode)); + serializer.endTag(null, "color-mode"); + } + + private void dump(final PrintWriter pw, final String prefix) { + pw.println(prefix + "ColorMode=" + mColorMode); + } + } } diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java index 986efd6918b1..9d0fde5f2027 100644 --- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java +++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java @@ -225,6 +225,11 @@ final class VirtualDisplayAdapter extends DisplayAdapter { } @Override + public boolean hasStableUniqueId() { + return false; + } + + @Override public Runnable requestDisplayStateLocked(int state, int brightness) { if (state != mDisplayState) { mDisplayState = state; diff --git a/services/core/java/com/android/server/display/WifiDisplayAdapter.java b/services/core/java/com/android/server/display/WifiDisplayAdapter.java index 64bc7291114b..08c0a1ad8219 100644 --- a/services/core/java/com/android/server/display/WifiDisplayAdapter.java +++ b/services/core/java/com/android/server/display/WifiDisplayAdapter.java @@ -602,6 +602,11 @@ final class WifiDisplayAdapter extends DisplayAdapter { mMode = createMode(width, height, refreshRate); } + @Override + public boolean hasStableUniqueId() { + return true; + } + public void destroyLocked() { if (mSurface != null) { mSurface.release(); |