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
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index fd4bd11..86aa887 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -3660,7 +3660,12 @@
state.physical = {.id = displayId,
.hwcDisplayId = hwcDisplayId,
.activeMode = std::move(activeMode)};
- state.isSecure = connectionType == ui::DisplayConnectionType::Internal;
+ 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);
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h b/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h
index f26336a..db3c0a1 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h
@@ -498,9 +498,7 @@
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 @@
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 @@
: 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 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>;
+ 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, 1600, 1200>;
+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 @@
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>,
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayTransactionCommitTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayTransactionCommitTest.cpp
index b620830..9bf344c 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayTransactionCommitTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayTransactionCommitTest.cpp
@@ -265,6 +265,13 @@
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 @@
// 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 @@
processesHotplugDisconnectCommon<SimpleExternalDisplayCase>();
}
+TEST_F(DisplayTransactionCommitTest, processesHotplugDisconnectNonSecureExternalDisplay) {
+ processesHotplugDisconnectCommon<SimpleExternalDisplayNonSecureCase>();
+}
+
TEST_F(DisplayTransactionCommitTest, processesHotplugConnectThenDisconnectPrimary) {
EXPECT_EXIT(
[this] {