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

Commit 82e15631 authored by Huihong Luo's avatar Huihong Luo
Browse files

Remove HDCP check on external displays

Pixel devices are still enforced, but the check for other devices
is removed to maintain backward compatibility. This needs to be
reverted when HDCP aidl API becomes ready.

This is safe (and unflagged) because it simply restores the
long-tested Android U behavior for non-Pixel devices, while
leaving the Pixel behavior (where mIsHdcpViaNegVsync is already
set to true) unchanged. This also needs to be cherry-picked to
Android 15, where it cannot be flagged.

Flag: EXEMPT bugfix
Bug: 347825589
Test: play DRM protected video with external display connected
Change-Id: Iec423d9b0d127474c734beb8a0d73f9ce780a4e2
parent 8b426bf4
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -3660,7 +3660,12 @@ std::optional<DisplayModeId> SurfaceFlinger::processHotplugConnect(PhysicalDispl
    state.physical = {.id = displayId,
                      .hwcDisplayId = hwcDisplayId,
                      .activeMode = std::move(activeMode)};
    if (mIsHdcpViaNegVsync) {
        state.isSecure = connectionType == ui::DisplayConnectionType::Internal;
    } else {
        // TODO(b/349703362): Remove this when HDCP aidl API becomes ready
        state.isSecure = true; // All physical displays are currently considered secure.
    }
    state.isProtected = true;
    state.displayName = std::move(info.name);

+35 −10
Original line number Diff line number Diff line
@@ -498,9 +498,7 @@ constexpr uint32_t GRALLOC_USAGE_PHYSICAL_DISPLAY =
constexpr int PHYSICAL_DISPLAY_FLAGS = 0x1;

template <typename PhysicalDisplay, int width, int height,
          Secure secure = (PhysicalDisplay::CONNECTION_TYPE == ui::DisplayConnectionType::Internal)
                  ? Secure::TRUE
                  : Secure::FALSE>
          Secure secure = (PhysicalDisplay::SECURE) ? Secure::TRUE : Secure::FALSE>
struct PhysicalDisplayVariant
      : DisplayVariant<PhysicalDisplayIdType<PhysicalDisplay>, width, height, Async::FALSE, secure,
                       PhysicalDisplay::PRIMARY, GRALLOC_USAGE_PHYSICAL_DISPLAY,
@@ -515,16 +513,18 @@ template <bool hasIdentificationData>
struct PrimaryDisplay {
    static constexpr auto CONNECTION_TYPE = ui::DisplayConnectionType::Internal;
    static constexpr Primary PRIMARY = Primary::TRUE;
    static constexpr bool SECURE = true;
    static constexpr uint8_t PORT = 255;
    static constexpr HWDisplayId HWC_DISPLAY_ID = 1001;
    static constexpr bool HAS_IDENTIFICATION_DATA = hasIdentificationData;
    static constexpr auto GET_IDENTIFICATION_DATA = getInternalEdid;
};

template <ui::DisplayConnectionType connectionType, bool hasIdentificationData>
template <ui::DisplayConnectionType connectionType, bool hasIdentificationData, bool secure>
struct SecondaryDisplay {
    static constexpr auto CONNECTION_TYPE = connectionType;
    static constexpr Primary PRIMARY = Primary::FALSE;
    static constexpr bool SECURE = secure;
    static constexpr uint8_t PORT = 254;
    static constexpr HWDisplayId HWC_DISPLAY_ID = 1002;
    static constexpr bool HAS_IDENTIFICATION_DATA = hasIdentificationData;
@@ -533,9 +533,14 @@ struct SecondaryDisplay {
                                                                  : getExternalEdid;
};

constexpr bool kSecure = true;
constexpr bool kNonSecure = false;

template <bool secure>
struct TertiaryDisplay {
    static constexpr auto CONNECTION_TYPE = ui::DisplayConnectionType::External;
    static constexpr Primary PRIMARY = Primary::FALSE;
    static constexpr bool SECURE = secure;
    static constexpr uint8_t PORT = 253;
    static constexpr HWDisplayId HWC_DISPLAY_ID = 1003;
    static constexpr auto GET_IDENTIFICATION_DATA = getExternalEdid;
@@ -545,14 +550,26 @@ using PrimaryDisplayVariant = PhysicalDisplayVariant<PrimaryDisplay<false>, 3840

using InnerDisplayVariant = PhysicalDisplayVariant<PrimaryDisplay<true>, 1840, 2208>;
using OuterDisplayVariant =
        PhysicalDisplayVariant<SecondaryDisplay<ui::DisplayConnectionType::Internal, true>, 1080,
                               2092>;
        PhysicalDisplayVariant<SecondaryDisplay<ui::DisplayConnectionType::Internal,
                                                /*hasIdentificationData=*/true, kSecure>,
                               1080, 2092>;
using OuterDisplayNonSecureVariant =
        PhysicalDisplayVariant<SecondaryDisplay<ui::DisplayConnectionType::Internal,
                                                /*hasIdentificationData=*/true, kNonSecure>,
                               1080, 2092>;

using ExternalDisplayVariant =
        PhysicalDisplayVariant<SecondaryDisplay<ui::DisplayConnectionType::External, false>, 1920,
                               1280>;

using TertiaryDisplayVariant = PhysicalDisplayVariant<TertiaryDisplay, 1600, 1200>;
        PhysicalDisplayVariant<SecondaryDisplay<ui::DisplayConnectionType::External,
                                                /*hasIdentificationData=*/false, kSecure>,
                               1920, 1280>;
using ExternalDisplayNonSecureVariant =
        PhysicalDisplayVariant<SecondaryDisplay<ui::DisplayConnectionType::External,
                                                /*hasIdentificationData=*/false, kNonSecure>,
                               1920, 1280>;

using TertiaryDisplayVariant = PhysicalDisplayVariant<TertiaryDisplay<kSecure>, 1600, 1200>;
using TertiaryDisplayNonSecureVariant =
        PhysicalDisplayVariant<TertiaryDisplay<kNonSecure>, 1600, 1200>;

// A virtual display not supported by the HWC.
constexpr uint32_t GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY = 0;
@@ -750,10 +767,18 @@ using SimpleExternalDisplayCase =
        Case<ExternalDisplayVariant, WideColorNotSupportedVariant<ExternalDisplayVariant>,
             HdrNotSupportedVariant<ExternalDisplayVariant>,
             NoPerFrameMetadataSupportVariant<ExternalDisplayVariant>>;
using SimpleExternalDisplayNonSecureCase =
        Case<ExternalDisplayVariant, WideColorNotSupportedVariant<ExternalDisplayNonSecureVariant>,
             HdrNotSupportedVariant<ExternalDisplayNonSecureVariant>,
             NoPerFrameMetadataSupportVariant<ExternalDisplayNonSecureVariant>>;
using SimpleTertiaryDisplayCase =
        Case<TertiaryDisplayVariant, WideColorNotSupportedVariant<TertiaryDisplayVariant>,
             HdrNotSupportedVariant<TertiaryDisplayVariant>,
             NoPerFrameMetadataSupportVariant<TertiaryDisplayVariant>>;
using SimpleTertiaryDisplayNonSecureCase =
        Case<TertiaryDisplayVariant, WideColorNotSupportedVariant<TertiaryDisplayNonSecureVariant>,
             HdrNotSupportedVariant<TertiaryDisplayNonSecureVariant>,
             NoPerFrameMetadataSupportVariant<TertiaryDisplayNonSecureVariant>>;

using NonHwcVirtualDisplayCase =
        Case<NonHwcVirtualDisplayVariant<1024, 768, Secure::FALSE>,
+29 −2
Original line number Diff line number Diff line
@@ -265,6 +265,13 @@ TEST_F(DisplayTransactionCommitTest, processesHotplugConnectExternalDisplay) {
    processesHotplugConnectCommon<SimpleExternalDisplayCase>();
}

TEST_F(DisplayTransactionCommitTest, processesHotplugConnectNonSecureExternalDisplay) {
    // Inject a primary display.
    PrimaryDisplayVariant::injectHwcDisplay(this);

    processesHotplugConnectCommon<SimpleExternalDisplayNonSecureCase>();
}

TEST_F(DisplayTransactionCommitTest, ignoresHotplugConnectIfPrimaryAndExternalAlreadyConnected) {
    // Inject both a primary and external display.
    PrimaryDisplayVariant::injectHwcDisplay(this);
@@ -273,13 +280,29 @@ TEST_F(DisplayTransactionCommitTest, ignoresHotplugConnectIfPrimaryAndExternalAl
    // TODO: This is an unnecessary call.
    EXPECT_CALL(*mComposer,
                getDisplayIdentificationData(TertiaryDisplayVariant::HWC_DISPLAY_ID, _, _))
            .WillOnce(DoAll(SetArgPointee<1>(TertiaryDisplay::PORT),
                            SetArgPointee<2>(TertiaryDisplay::GET_IDENTIFICATION_DATA()),
            .WillOnce(DoAll(SetArgPointee<1>(TertiaryDisplay<kSecure>::PORT),
                            SetArgPointee<2>(TertiaryDisplay<kSecure>::GET_IDENTIFICATION_DATA()),
                            Return(Error::NONE)));

    ignoresHotplugConnectCommon<SimpleTertiaryDisplayCase>();
}

TEST_F(DisplayTransactionCommitTest,
       ignoresHotplugConnectNonSecureIfPrimaryAndExternalAlreadyConnected) {
    // Inject both a primary and external display.
    PrimaryDisplayVariant::injectHwcDisplay(this);
    ExternalDisplayVariant::injectHwcDisplay(this);

    // TODO: This is an unnecessary call.
    EXPECT_CALL(*mComposer,
                getDisplayIdentificationData(TertiaryDisplayVariant::HWC_DISPLAY_ID, _, _))
            .WillOnce(DoAll(SetArgPointee<1>(TertiaryDisplay<kSecure>::PORT),
                            SetArgPointee<2>(TertiaryDisplay<kSecure>::GET_IDENTIFICATION_DATA()),
                            Return(Error::NONE)));

    ignoresHotplugConnectCommon<SimpleTertiaryDisplayNonSecureCase>();
}

TEST_F(DisplayTransactionCommitTest, processesHotplugDisconnectPrimaryDisplay) {
    EXPECT_EXIT(processesHotplugDisconnectCommon<SimplePrimaryDisplayCase>(),
                testing::KilledBySignal(SIGABRT), "Primary display cannot be disconnected.");
@@ -289,6 +312,10 @@ TEST_F(DisplayTransactionCommitTest, processesHotplugDisconnectExternalDisplay)
    processesHotplugDisconnectCommon<SimpleExternalDisplayCase>();
}

TEST_F(DisplayTransactionCommitTest, processesHotplugDisconnectNonSecureExternalDisplay) {
    processesHotplugDisconnectCommon<SimpleExternalDisplayNonSecureCase>();
}

TEST_F(DisplayTransactionCommitTest, processesHotplugConnectThenDisconnectPrimary) {
    EXPECT_EXIT(
            [this] {