Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5273932d authored by Sameer's avatar Sameer
Browse files

Fix Framework code for HDR bugs

- Refreshes Conversion Mode when Conversion Mode is set to System Conversion and areUserDisabled types are modified. This allows the system to have accurate array of HDR types it is allowed to use.
- Display returns null for HDR capabilities when system is set to Force SDR conversion.
- Simplifies app-requested disabling of HDR conversion (per mOverrideHdrConversionMode).

Bug: 330927371
Flag: EXEMPT bugfix
Test: manual test
Change-Id: Id7c6863bb66b5ba0789de6bed45cd508d1b54b04
parent 79675a50
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -1331,7 +1331,7 @@ public final class Display {
    public HdrCapabilities getHdrCapabilities() {
        synchronized (mLock) {
            updateDisplayInfoLocked();
            if (mDisplayInfo.hdrCapabilities == null) {
            if (mDisplayInfo.hdrCapabilities == null || mDisplayInfo.isForceSdr) {
                return null;
            }
            int[] supportedHdrTypes;
@@ -1353,6 +1353,7 @@ public final class Display {
                    supportedHdrTypes[index++] = enabledType;
                }
            }

            return new HdrCapabilities(supportedHdrTypes,
                    mDisplayInfo.hdrCapabilities.mMaxLuminance,
                    mDisplayInfo.hdrCapabilities.mMaxAverageLuminance,
+9 −0
Original line number Diff line number Diff line
@@ -230,6 +230,9 @@ public final class DisplayInfo implements Parcelable {
    /** The formats disabled by user **/
    public int[] userDisabledHdrTypes = {};

    /** When true, all HDR capabilities are disabled **/
    public boolean isForceSdr;

    /**
     * Indicates whether the display can be switched into a mode with minimal post
     * processing.
@@ -440,6 +443,7 @@ public final class DisplayInfo implements Parcelable {
                && colorMode == other.colorMode
                && Arrays.equals(supportedColorModes, other.supportedColorModes)
                && Objects.equals(hdrCapabilities, other.hdrCapabilities)
                && isForceSdr == other.isForceSdr
                && Arrays.equals(userDisabledHdrTypes, other.userDisabledHdrTypes)
                && minimalPostProcessingSupported == other.minimalPostProcessingSupported
                && logicalDensityDpi == other.logicalDensityDpi
@@ -502,6 +506,7 @@ public final class DisplayInfo implements Parcelable {
        supportedColorModes = Arrays.copyOf(
                other.supportedColorModes, other.supportedColorModes.length);
        hdrCapabilities = other.hdrCapabilities;
        isForceSdr = other.isForceSdr;
        userDisabledHdrTypes = other.userDisabledHdrTypes;
        minimalPostProcessingSupported = other.minimalPostProcessingSupported;
        logicalDensityDpi = other.logicalDensityDpi;
@@ -567,6 +572,7 @@ public final class DisplayInfo implements Parcelable {
            supportedColorModes[i] = source.readInt();
        }
        hdrCapabilities = source.readParcelable(null, android.view.Display.HdrCapabilities.class);
        isForceSdr = source.readBoolean();
        minimalPostProcessingSupported = source.readBoolean();
        logicalDensityDpi = source.readInt();
        physicalXDpi = source.readFloat();
@@ -636,6 +642,7 @@ public final class DisplayInfo implements Parcelable {
            dest.writeInt(supportedColorModes[i]);
        }
        dest.writeParcelable(hdrCapabilities, flags);
        dest.writeBoolean(isForceSdr);
        dest.writeBoolean(minimalPostProcessingSupported);
        dest.writeInt(logicalDensityDpi);
        dest.writeFloat(physicalXDpi);
@@ -874,6 +881,8 @@ public final class DisplayInfo implements Parcelable {
        sb.append(Arrays.toString(appsSupportedModes));
        sb.append(", hdrCapabilities ");
        sb.append(hdrCapabilities);
        sb.append(", isForceSdr ");
        sb.append(isForceSdr);
        sb.append(", userDisabledHdrTypes ");
        sb.append(Arrays.toString(userDisabledHdrTypes));
        sb.append(", minimalPostProcessingSupported ");
+1 −1
Original line number Diff line number Diff line
@@ -109,7 +109,7 @@ public class DisplayControl {
    /**
     * Sets the HDR conversion mode for the device.
     *
     * Returns the system preferred Hdr output type nn case when HDR conversion mode is
     * Returns the system preferred HDR output type in case when HDR conversion mode is
     * {@link android.hardware.display.HdrConversionMode#HDR_CONVERSION_SYSTEM}.
     * Returns Hdr::INVALID in other cases.
     * @hide
+7 −1
Original line number Diff line number Diff line
@@ -318,13 +318,16 @@ final class DisplayDeviceInfo {
     */
    public Display.HdrCapabilities hdrCapabilities;

    /** When true, all HDR capabilities are hidden from public APIs */
    public boolean isForceSdr;

    /**
     * Indicates whether this display supports Auto Low Latency Mode.
     */
    public boolean allmSupported;

    /**
     * Indicates whether this display suppors Game content type.
     * Indicates whether this display supports Game content type.
     */
    public boolean gameContentTypeSupported;

@@ -516,6 +519,7 @@ final class DisplayDeviceInfo {
                || !Arrays.equals(supportedModes, other.supportedModes)
                || !Arrays.equals(supportedColorModes, other.supportedColorModes)
                || !Objects.equals(hdrCapabilities, other.hdrCapabilities)
                || isForceSdr != other.isForceSdr
                || allmSupported != other.allmSupported
                || gameContentTypeSupported != other.gameContentTypeSupported
                || densityDpi != other.densityDpi
@@ -560,6 +564,7 @@ final class DisplayDeviceInfo {
        colorMode = other.colorMode;
        supportedColorModes = other.supportedColorModes;
        hdrCapabilities = other.hdrCapabilities;
        isForceSdr = other.isForceSdr;
        allmSupported = other.allmSupported;
        gameContentTypeSupported = other.gameContentTypeSupported;
        densityDpi = other.densityDpi;
@@ -603,6 +608,7 @@ final class DisplayDeviceInfo {
        sb.append(", colorMode ").append(colorMode);
        sb.append(", supportedColorModes ").append(Arrays.toString(supportedColorModes));
        sb.append(", hdrCapabilities ").append(hdrCapabilities);
        sb.append(", isForceSdr ").append(isForceSdr);
        sb.append(", allmSupported ").append(allmSupported);
        sb.append(", gameContentTypeSupported ").append(gameContentTypeSupported);
        sb.append(", density ").append(densityDpi);
+95 −50
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ import static android.os.Process.ROOT_UID;
import static android.provider.Settings.Secure.RESOLUTION_MODE_FULL;
import static android.provider.Settings.Secure.RESOLUTION_MODE_HIGH;
import static android.provider.Settings.Secure.RESOLUTION_MODE_UNKNOWN;
import static android.view.Display.HdrCapabilities.HDR_TYPE_INVALID;

import static com.android.server.display.layout.Layout.Display.POSITION_REAR;

@@ -282,7 +283,7 @@ public final class DisplayManagerService extends SystemService {
    @GuardedBy("mSyncRoot")
    private int[] mUserDisabledHdrTypes = {};
    @Display.HdrCapabilities.HdrType
    private int[] mSupportedHdrOutputType;
    private int[] mSupportedHdrOutputTypes;
    @GuardedBy("mSyncRoot")
    private boolean mAreUserDisabledHdrTypesAllowed = true;

@@ -297,10 +298,10 @@ public final class DisplayManagerService extends SystemService {
    // HDR conversion mode chosen by user
    @GuardedBy("mSyncRoot")
    private HdrConversionMode mHdrConversionMode = null;
    // Actual HDR conversion mode, which takes app overrides into account.
    private HdrConversionMode mOverrideHdrConversionMode = null;
    // Whether app has disabled HDR conversion
    private boolean mShouldDisableHdrConversion = false;
    @GuardedBy("mSyncRoot")
    private int mSystemPreferredHdrOutputType = Display.HdrCapabilities.HDR_TYPE_INVALID;
    private int mSystemPreferredHdrOutputType = HDR_TYPE_INVALID;


    // The synchronization root for the display manager.
@@ -1407,7 +1408,8 @@ public final class DisplayManagerService extends SystemService {
        }
    }

    private void setUserDisabledHdrTypesInternal(int[] userDisabledHdrTypes) {
    @VisibleForTesting
    void setUserDisabledHdrTypesInternal(int[] userDisabledHdrTypes) {
        synchronized (mSyncRoot) {
            if (userDisabledHdrTypes == null) {
                Slog.e(TAG, "Null is not an expected argument to "
@@ -1425,6 +1427,7 @@ public final class DisplayManagerService extends SystemService {
            if (Arrays.equals(mUserDisabledHdrTypes, userDisabledHdrTypes)) {
                return;
            }

            String userDisabledFormatsString = "";
            if (userDisabledHdrTypes.length != 0) {
                userDisabledFormatsString = TextUtils.join(",",
@@ -1440,6 +1443,15 @@ public final class DisplayManagerService extends SystemService {
                            handleLogicalDisplayChangedLocked(display);
                        });
            }
            /** Note: it may be expected to reset the Conversion Mode when an HDR type is enabled
             and the Conversion Mode is set to System Preferred. This is handled in the Settings
             code because in the special case where HDR is indirectly disabled by Force SDR
             Conversion, manually enabling HDR is not recognized as an action that reduces the
             disabled HDR count. Thus, this case needs to be checked in the Settings code when we
             know we're enabling an HDR mode. If we split checking for SystemConversion and
             isForceSdr in two places, we may have duplicate calls to resetting to System Conversion
             and get two black screens.
             */
        }
    }

@@ -1452,19 +1464,20 @@ public final class DisplayManagerService extends SystemService {
        return true;
    }

    private void setAreUserDisabledHdrTypesAllowedInternal(
    @VisibleForTesting
    void setAreUserDisabledHdrTypesAllowedInternal(
            boolean areUserDisabledHdrTypesAllowed) {
        synchronized (mSyncRoot) {
            if (mAreUserDisabledHdrTypesAllowed == areUserDisabledHdrTypesAllowed) {
                return;
            }
            mAreUserDisabledHdrTypesAllowed = areUserDisabledHdrTypesAllowed;
            if (mUserDisabledHdrTypes.length == 0) {
                return;
            }
            Settings.Global.putInt(mContext.getContentResolver(),
                    Settings.Global.ARE_USER_DISABLED_HDR_FORMATS_ALLOWED,
                    areUserDisabledHdrTypesAllowed ? 1 : 0);
            if (mUserDisabledHdrTypes.length == 0) {
                return;
            }
            int userDisabledHdrTypes[] = {};
            if (!mAreUserDisabledHdrTypesAllowed) {
                userDisabledHdrTypes = mUserDisabledHdrTypes;
@@ -1475,6 +1488,14 @@ public final class DisplayManagerService extends SystemService {
                        display.setUserDisabledHdrTypes(finalUserDisabledHdrTypes);
                        handleLogicalDisplayChangedLocked(display);
                    });
            // When HDR conversion mode is set to SYSTEM, modification to
            // areUserDisabledHdrTypesAllowed requires refreshing the HDR conversion mode to tell
            // the system which HDR types it is not allowed to use.
            if (getHdrConversionModeInternal().getConversionMode()
                    == HdrConversionMode.HDR_CONVERSION_SYSTEM) {
                setHdrConversionModeInternal(
                        new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_SYSTEM));
            }
        }
    }

@@ -2348,7 +2369,7 @@ public final class DisplayManagerService extends SystemService {
        final int preferredHdrOutputType =
                hdrConversionMode.getConversionMode() == HdrConversionMode.HDR_CONVERSION_FORCE
                        ? hdrConversionMode.getPreferredHdrOutputType()
                        : Display.HdrCapabilities.HDR_TYPE_INVALID;
                        : HDR_TYPE_INVALID;
        Settings.Global.putInt(mContext.getContentResolver(),
                Settings.Global.HDR_FORCE_CONVERSION_TYPE, preferredHdrOutputType);
    }
@@ -2361,7 +2382,7 @@ public final class DisplayManagerService extends SystemService {
                ? Settings.Global.getInt(mContext.getContentResolver(),
                Settings.Global.HDR_FORCE_CONVERSION_TYPE,
                        Display.HdrCapabilities.HDR_TYPE_DOLBY_VISION)
                : Display.HdrCapabilities.HDR_TYPE_INVALID;
                : HDR_TYPE_INVALID;
        mHdrConversionMode = new HdrConversionMode(conversionMode, preferredHdrOutputType);
        setHdrConversionModeInternal(mHdrConversionMode);
    }
@@ -2498,22 +2519,38 @@ public final class DisplayManagerService extends SystemService {
        });
    }

    /**
     * Returns the HDR output types that are supported by the device's HDR conversion capabilities,
     * stripping out any user-disabled HDR types if mAreUserDisabledHdrTypesAllowed is false.
     */
    @GuardedBy("mSyncRoot")
    private int[] getEnabledAutoHdrTypesLocked() {
        IntArray autoHdrOutputTypesArray = new IntArray();
    @VisibleForTesting
    int[] getEnabledHdrOutputTypesLocked() {
        if (mAreUserDisabledHdrTypesAllowed) {
            return getSupportedHdrOutputTypesInternal();
        }
        // Strip out all HDR formats that are currently user-disabled
        IntArray enabledHdrOutputTypesArray = new IntArray();
        for (int type : getSupportedHdrOutputTypesInternal()) {
            boolean isDisabled = false;
            boolean isEnabled = true;
            for (int disabledType : mUserDisabledHdrTypes) {
                if (type == disabledType) {
                    isDisabled = true;
                    isEnabled = false;
                    break;
                }
            }
            if (!isDisabled) {
                autoHdrOutputTypesArray.add(type);
            if (isEnabled) {
                enabledHdrOutputTypesArray.add(type);
            }
        }
        return autoHdrOutputTypesArray.toArray();
        return enabledHdrOutputTypesArray.toArray();
    }

    @VisibleForTesting
    int[] getEnabledHdrOutputTypes() {
        synchronized (mSyncRoot) {
            return getEnabledHdrOutputTypesLocked();
        }
    }

    @GuardedBy("mSyncRoot")
@@ -2522,7 +2559,7 @@ public final class DisplayManagerService extends SystemService {
        final int preferredHdrOutputType =
                mode.getConversionMode() == HdrConversionMode.HDR_CONVERSION_SYSTEM
                        ? mSystemPreferredHdrOutputType : mode.getPreferredHdrOutputType();
        if (preferredHdrOutputType != Display.HdrCapabilities.HDR_TYPE_INVALID) {
        if (preferredHdrOutputType != HDR_TYPE_INVALID) {
            int[] hdrTypesWithLatency = mInjector.getHdrOutputTypesWithLatency();
            return ArrayUtils.contains(hdrTypesWithLatency, preferredHdrOutputType);
        }
@@ -2556,41 +2593,57 @@ public final class DisplayManagerService extends SystemService {
        if (!mInjector.getHdrOutputConversionSupport()) {
            return;
        }
        int[] autoHdrOutputTypes = null;

        synchronized (mSyncRoot) {
            if (hdrConversionMode.getConversionMode() == HdrConversionMode.HDR_CONVERSION_SYSTEM
                    && hdrConversionMode.getPreferredHdrOutputType()
                    != Display.HdrCapabilities.HDR_TYPE_INVALID) {
                    != HDR_TYPE_INVALID) {
                throw new IllegalArgumentException("preferredHdrOutputType must not be set if"
                        + " the conversion mode is HDR_CONVERSION_SYSTEM");
            }
            mHdrConversionMode = hdrConversionMode;
            storeHdrConversionModeLocked(mHdrConversionMode);

            // For auto mode, all supported HDR types are allowed except the ones specifically
            // disabled by the user.
            // If the HDR conversion is HDR_CONVERSION_SYSTEM, all supported HDR types are allowed
            // except the ones specifically disabled by the user.
            int[] enabledHdrOutputTypes = null;
            if (hdrConversionMode.getConversionMode() == HdrConversionMode.HDR_CONVERSION_SYSTEM) {
                autoHdrOutputTypes = getEnabledAutoHdrTypesLocked();
                enabledHdrOutputTypes = getEnabledHdrOutputTypesLocked();
            }

            int conversionMode = hdrConversionMode.getConversionMode();
            int preferredHdrType = hdrConversionMode.getPreferredHdrOutputType();

            // If the HDR conversion is disabled by an app through WindowManager.LayoutParams, then
            // set HDR conversion mode to HDR_CONVERSION_PASSTHROUGH.
            if (mOverrideHdrConversionMode == null) {
            if (mShouldDisableHdrConversion) {
                conversionMode = HdrConversionMode.HDR_CONVERSION_PASSTHROUGH;
                preferredHdrType = -1;
                enabledHdrOutputTypes = null;
            } else {
                // HDR_CONVERSION_FORCE with HDR_TYPE_INVALID is used to represent forcing SDR type.
                // But, internally SDR is selected by using passthrough mode.
                // But, internally SDR is forced by using passthrough mode and not reporting any
                // HDR capabilities to apps.
                if (conversionMode == HdrConversionMode.HDR_CONVERSION_FORCE
                        && preferredHdrType == Display.HdrCapabilities.HDR_TYPE_INVALID) {
                        && preferredHdrType == HDR_TYPE_INVALID) {
                    conversionMode = HdrConversionMode.HDR_CONVERSION_PASSTHROUGH;
                    mLogicalDisplayMapper.forEachLocked(
                            logicalDisplay -> {
                                if (logicalDisplay.setIsForceSdr(true)) {
                                    handleLogicalDisplayChangedLocked(logicalDisplay);
                                }
                            });
                } else {
                conversionMode = mOverrideHdrConversionMode.getConversionMode();
                preferredHdrType = mOverrideHdrConversionMode.getPreferredHdrOutputType();
                autoHdrOutputTypes = null;
                    mLogicalDisplayMapper.forEachLocked(
                            logicalDisplay -> {
                                if (logicalDisplay.setIsForceSdr(false)) {
                                    handleLogicalDisplayChangedLocked(logicalDisplay);
                                }
                            });
                }
            }
            mSystemPreferredHdrOutputType = mInjector.setHdrConversionMode(
                    conversionMode, preferredHdrType, autoHdrOutputTypes);
                    conversionMode, preferredHdrType, enabledHdrOutputTypes);
        }
    }

@@ -2612,8 +2665,8 @@ public final class DisplayManagerService extends SystemService {
        }
        HdrConversionMode mode;
        synchronized (mSyncRoot) {
            mode = mOverrideHdrConversionMode != null
                    ? mOverrideHdrConversionMode
            mode = mShouldDisableHdrConversion
                    ? new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_PASSTHROUGH)
                    : mHdrConversionMode;
            // Handle default: PASSTHROUGH. Don't include the system-preferred type.
            if (mode == null
@@ -2621,8 +2674,6 @@ public final class DisplayManagerService extends SystemService {
                return new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_PASSTHROUGH);
            }
            // Handle default or current mode: SYSTEM. Include the system preferred type.
            // mOverrideHdrConversionMode and mHdrConversionMode do not include the system
            // preferred type, it is kept separately in mSystemPreferredHdrOutputType.
            if (mode == null
                    || mode.getConversionMode() == HdrConversionMode.HDR_CONVERSION_SYSTEM) {
                return new HdrConversionMode(
@@ -2633,10 +2684,10 @@ public final class DisplayManagerService extends SystemService {
    }

    private @Display.HdrCapabilities.HdrType int[] getSupportedHdrOutputTypesInternal() {
        if (mSupportedHdrOutputType == null) {
            mSupportedHdrOutputType = mInjector.getSupportedHdrOutputTypes();
        if (mSupportedHdrOutputTypes == null) {
            mSupportedHdrOutputTypes = mInjector.getSupportedHdrOutputTypes();
        }
        return mSupportedHdrOutputType;
        return mSupportedHdrOutputTypes;
    }

    void setShouldAlwaysRespectAppRequestedModeInternal(boolean enabled) {
@@ -2822,15 +2873,9 @@ public final class DisplayManagerService extends SystemService {
            // HDR conversion is disabled in two cases:
            // - HDR conversion introduces latency and minimal post-processing is requested
            // - app requests to disable HDR conversion
            if (mOverrideHdrConversionMode == null && (disableHdrConversion
                    || disableHdrConversionForLatency)) {
                mOverrideHdrConversionMode =
                            new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_PASSTHROUGH);
                setHdrConversionModeInternal(mHdrConversionMode);
                handleLogicalDisplayChangedLocked(display);
            } else if (mOverrideHdrConversionMode != null && !disableHdrConversion
                    && !disableHdrConversionForLatency) {
                mOverrideHdrConversionMode = null;
            boolean previousShouldDisableHdrConversion = mShouldDisableHdrConversion;
            mShouldDisableHdrConversion = disableHdrConversion || disableHdrConversionForLatency;
            if (previousShouldDisableHdrConversion != mShouldDisableHdrConversion) {
                setHdrConversionModeInternal(mHdrConversionMode);
                handleLogicalDisplayChangedLocked(display);
            }
@@ -3509,9 +3554,9 @@ public final class DisplayManagerService extends SystemService {
        }

        int setHdrConversionMode(int conversionMode, int preferredHdrOutputType,
                int[] autoHdrTypes) {
                int[] allowedHdrOutputTypes) {
            return DisplayControl.setHdrConversionMode(conversionMode, preferredHdrOutputType,
                    autoHdrTypes);
                    allowedHdrOutputTypes);
        }

        @Display.HdrCapabilities.HdrType
Loading