summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Huihong Luo <huisinro@google.com> 2025-01-21 12:00:15 -0800
committer Huihong Luo <huisinro@google.com> 2025-03-21 13:02:29 -0700
commit9b2db4b7f20aff5de2c2454678010d3e0dafa163 (patch)
treef758df85f6659be7dea0745926600872d5de1c99
parent73416e163b7611c2880add437d139129bd0cf79d (diff)
Detect secure layers and start lazy HDCP activation
Layer snapshots are traversed to check for secure layers, then trigger HWC to start HDCP activation when a secure layer is detected. Flag: com.android.graphics.surfaceflinger.flags.hdcp_negotiation Bug: 372902990 Bug: 375340594 Test: manual Change-Id: Ie52159043f94d7cdb079d7c48c47764017a979f5
-rw-r--r--services/surfaceflinger/CompositionEngine/include/compositionengine/Display.h3
-rw-r--r--services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h3
-rw-r--r--services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Display.h1
-rw-r--r--services/surfaceflinger/CompositionEngine/src/Display.cpp8
-rw-r--r--services/surfaceflinger/Display/DisplayModeController.cpp48
-rw-r--r--services/surfaceflinger/Display/DisplayModeController.h20
-rw-r--r--services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp12
-rw-r--r--services/surfaceflinger/DisplayHardware/AidlComposerHal.h1
-rw-r--r--services/surfaceflinger/DisplayHardware/ComposerHal.h2
-rw-r--r--services/surfaceflinger/DisplayHardware/HWC2.cpp5
-rw-r--r--services/surfaceflinger/DisplayHardware/HWC2.h4
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.cpp9
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.h4
-rw-r--r--services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp4
-rw-r--r--services/surfaceflinger/DisplayHardware/HidlComposerHal.h1
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp26
-rw-r--r--services/surfaceflinger/common/FlagManager.cpp2
-rw-r--r--services/surfaceflinger/common/include/common/FlagManager.h1
-rw-r--r--services/surfaceflinger/surfaceflinger_flags_new.aconfig10
-rw-r--r--services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h2
-rw-r--r--services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWC2.h2
-rw-r--r--services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWComposer.h2
22 files changed, 157 insertions, 13 deletions
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/Display.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/Display.h
index 39748b8417..acd915464e 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/Display.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/Display.h
@@ -37,6 +37,9 @@ public:
// Gets the DisplayId for the display
virtual DisplayId getId() const = 0;
+ // True if the display has a secure layer
+ virtual bool hasSecureLayers() const = 0;
+
// True if the display is secure
virtual bool isSecure() const = 0;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
index ec87acc372..6ec7be885a 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
@@ -68,7 +68,9 @@ public:
// compositionengine::Display overrides
DisplayId getId() const override;
+ bool hasSecureLayers() const override;
bool isSecure() const override;
+ void setSecure(bool secure) override;
bool isVirtual() const override;
void disconnect() override;
void createDisplayColorProfile(
@@ -76,7 +78,6 @@ public:
void createRenderSurface(const compositionengine::RenderSurfaceCreationArgs&) override;
void createClientCompositionCache(uint32_t cacheSize) override;
void applyDisplayBrightness(bool applyImmediately) override;
- void setSecure(bool secure) override;
// Internal helpers used by chooseCompositionStrategy()
using ChangedTypes = android::HWComposer::DeviceRequestedChanges::ChangedTypes;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Display.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Display.h
index 46cb95ef25..2d51b71b09 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Display.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Display.h
@@ -32,6 +32,7 @@ public:
virtual ~Display();
MOCK_CONST_METHOD0(getId, DisplayId());
+ MOCK_CONST_METHOD0(hasSecureLayers, bool());
MOCK_CONST_METHOD0(isSecure, bool());
MOCK_METHOD1(setSecure, void(bool));
MOCK_CONST_METHOD0(isVirtual, bool());
diff --git a/services/surfaceflinger/CompositionEngine/src/Display.cpp b/services/surfaceflinger/CompositionEngine/src/Display.cpp
index 5a546777f4..531cab6938 100644
--- a/services/surfaceflinger/CompositionEngine/src/Display.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Display.cpp
@@ -70,6 +70,14 @@ DisplayId Display::getId() const {
return asDisplayId(mIdVariant);
}
+bool Display::hasSecureLayers() const {
+ const auto layers = getOutputLayersOrderedByZ();
+ return std::any_of(layers.begin(), layers.end(), [](const auto& layer) {
+ const auto* state = layer->getLayerFE().getCompositionState();
+ return state && state->isSecure;
+ });
+}
+
bool Display::isSecure() const {
return getState().isSecure;
}
diff --git a/services/surfaceflinger/Display/DisplayModeController.cpp b/services/surfaceflinger/Display/DisplayModeController.cpp
index 87a677cd58..7c19885231 100644
--- a/services/surfaceflinger/Display/DisplayModeController.cpp
+++ b/services/surfaceflinger/Display/DisplayModeController.cpp
@@ -46,11 +46,21 @@ DisplayModeController::Display::Display(DisplaySnapshotRef snapshot,
renderRateFpsTrace(concatId("RenderRateFps")),
hasDesiredModeTrace(concatId("HasDesiredMode"), false) {}
+DisplayModeController::DisplayModeController() {
+ using namespace std::string_literals;
+ mSupportsHdcp = base::GetBoolProperty("debug.sf.hdcp_support"s, false);
+}
+
void DisplayModeController::registerDisplay(PhysicalDisplayId displayId,
DisplaySnapshotRef snapshotRef,
RefreshRateSelectorPtr selectorPtr) {
+ DisplayPtr displayPtr = std::make_unique<Display>(snapshotRef, selectorPtr);
+ // TODO: b/349703362 - Remove first condition when HDCP aidl APIs are enforced
+ displayPtr->setSecure(!supportsHdcp() ||
+ snapshotRef.get().connectionType() ==
+ ui::DisplayConnectionType::Internal);
std::lock_guard lock(mDisplayLock);
- mDisplays.emplace_or_replace(displayId, std::make_unique<Display>(snapshotRef, selectorPtr));
+ mDisplays.emplace_or_replace(displayId, std::move(displayPtr));
}
void DisplayModeController::registerDisplay(DisplaySnapshotRef snapshotRef,
@@ -58,11 +68,14 @@ void DisplayModeController::registerDisplay(DisplaySnapshotRef snapshotRef,
scheduler::RefreshRateSelector::Config config) {
const auto& snapshot = snapshotRef.get();
const auto displayId = snapshot.displayId();
-
+ DisplayPtr displayPtr =
+ std::make_unique<Display>(snapshotRef, snapshot.displayModes(), activeModeId, config);
+ // TODO: b/349703362 - Remove first condition when HDCP aidl APIs are enforced
+ displayPtr->setSecure(!supportsHdcp() ||
+ snapshotRef.get().connectionType() ==
+ ui::DisplayConnectionType::Internal);
std::lock_guard lock(mDisplayLock);
- mDisplays.emplace_or_replace(displayId,
- std::make_unique<Display>(snapshotRef, snapshot.displayModes(),
- activeModeId, config));
+ mDisplays.emplace_or_replace(displayId, std::move(displayPtr));
}
void DisplayModeController::unregisterDisplay(PhysicalDisplayId displayId) {
@@ -304,5 +317,30 @@ auto DisplayModeController::getKernelIdleTimerState(PhysicalDisplayId displayId)
return {desiredModeIdOpt, displayPtr->isKernelIdleTimerEnabled};
}
+bool DisplayModeController::supportsHdcp() const {
+ return mSupportsHdcp && FlagManager::getInstance().hdcp_level_hal() &&
+ FlagManager::getInstance().hdcp_negotiation();
+}
+
+void DisplayModeController::startHdcpNegotiation(PhysicalDisplayId displayId) {
+ using aidl::android::hardware::drm::HdcpLevel;
+ using aidl::android::hardware::drm::HdcpLevels;
+ constexpr HdcpLevels kLevels = {.connectedLevel = HdcpLevel::HDCP_V2_1,
+ .maxLevel = HdcpLevel::HDCP_V2_3};
+
+ std::lock_guard lock(mDisplayLock);
+ const auto& displayPtr = FTL_TRY(mDisplays.get(displayId).ok_or(ftl::Unit())).get();
+ if (displayPtr->hdcpState == HdcpState::Desired) {
+ const auto status = mComposerPtr->startHdcpNegotiation(displayId, kLevels);
+ displayPtr->hdcpState = (status == NO_ERROR) ? HdcpState::Enabled : HdcpState::Undesired;
+ }
+}
+
+void DisplayModeController::setSecure(PhysicalDisplayId displayId, bool secure) {
+ std::lock_guard lock(mDisplayLock);
+ const auto& displayPtr = FTL_TRY(mDisplays.get(displayId).ok_or(ftl::Unit())).get();
+ displayPtr->setSecure(secure);
+}
+
#pragma clang diagnostic pop
} // namespace android::display
diff --git a/services/surfaceflinger/Display/DisplayModeController.h b/services/surfaceflinger/Display/DisplayModeController.h
index af3e909bcf..f20434857a 100644
--- a/services/surfaceflinger/Display/DisplayModeController.h
+++ b/services/surfaceflinger/Display/DisplayModeController.h
@@ -46,7 +46,7 @@ class DisplayModeController {
public:
using ActiveModeListener = ftl::Function<void(PhysicalDisplayId, Fps vsyncRate, Fps renderFps)>;
- DisplayModeController() = default;
+ DisplayModeController();
void setHwComposer(HWComposer* composerPtr) { mComposerPtr = composerPtr; }
void setActiveModeListener(const ActiveModeListener& listener) {
@@ -109,7 +109,16 @@ public:
KernelIdleTimerState getKernelIdleTimerState(PhysicalDisplayId) const
REQUIRES(kMainThreadContext) EXCLUDES(mDisplayLock);
+ void setSecure(PhysicalDisplayId displayId, bool secure) REQUIRES(kMainThreadContext)
+ EXCLUDES(mDisplayLock);
+
+ bool supportsHdcp() const;
+
+ void startHdcpNegotiation(PhysicalDisplayId displayId) REQUIRES(kMainThreadContext);
+
private:
+ enum class HdcpState { Undesired, Desired, Enabled };
+
struct Display {
template <size_t N>
std::string concatId(const char (&)[N]) const;
@@ -120,6 +129,11 @@ private:
: Display(snapshot,
std::make_shared<scheduler::RefreshRateSelector>(std::move(modes),
activeModeId, config)) {}
+
+ void setSecure(bool secure) {
+ hdcpState = secure ? HdcpState::Undesired : HdcpState::Desired;
+ }
+
const DisplaySnapshotRef snapshot;
const RefreshRateSelectorPtr selectorPtr;
@@ -135,6 +149,8 @@ private:
bool isModeSetPending GUARDED_BY(kMainThreadContext) = false;
bool isKernelIdleTimerEnabled GUARDED_BY(kMainThreadContext) = false;
+
+ HdcpState hdcpState = HdcpState::Desired;
};
using DisplayPtr = std::unique_ptr<Display>;
@@ -153,6 +169,8 @@ private:
mutable std::mutex mDisplayLock;
ui::PhysicalDisplayMap<PhysicalDisplayId, DisplayPtr> mDisplays GUARDED_BY(mDisplayLock);
+
+ bool mSupportsHdcp = false;
};
} // namespace android::display
diff --git a/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp b/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
index 27ae18fac9..8ead09ca19 100644
--- a/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
@@ -1718,6 +1718,18 @@ Error AidlComposer::setLayerPictureProfileId(Display display, Layer layer, Pictu
return error;
}
+Error AidlComposer::startHdcpNegotiation(Display display,
+ const aidl::android::hardware::drm::HdcpLevels& levels) {
+ const auto status =
+ mAidlComposerClient->startHdcpNegotiation(translate<int64_t>(display), levels);
+ if (!status.isOk()) {
+ ALOGE("startHdcpNegotiation failed %s", status.getDescription().c_str());
+ return static_cast<Error>(status.getServiceSpecificError());
+ }
+
+ return Error::NONE;
+}
+
Error AidlComposer::getLuts(Display display, const std::vector<sp<GraphicBuffer>>& buffers,
std::vector<aidl::android::hardware::graphics::composer3::Luts>* luts) {
std::vector<aidl::android::hardware::graphics::composer3::Buffer> aidlBuffers;
diff --git a/services/surfaceflinger/DisplayHardware/AidlComposerHal.h b/services/surfaceflinger/DisplayHardware/AidlComposerHal.h
index 5fcc8b00ba..b84d39a2c3 100644
--- a/services/surfaceflinger/DisplayHardware/AidlComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/AidlComposerHal.h
@@ -250,6 +250,7 @@ public:
Error getMaxLayerPictureProfiles(Display, int32_t* outMaxProfiles) override;
Error setDisplayPictureProfileId(Display, PictureProfileId id) override;
Error setLayerPictureProfileId(Display, Layer, PictureProfileId id) override;
+ Error startHdcpNegotiation(Display, const aidl::android::hardware::drm::HdcpLevels&) override;
Error getLuts(Display, const std::vector<sp<GraphicBuffer>>&,
std::vector<aidl::android::hardware::graphics::composer3::Luts>*) override;
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.h b/services/surfaceflinger/DisplayHardware/ComposerHal.h
index ab086e4b55..c55893106f 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h
@@ -317,6 +317,8 @@ public:
virtual Error getMaxLayerPictureProfiles(Display display, int32_t* outMaxProfiles) = 0;
virtual Error setDisplayPictureProfileId(Display display, PictureProfileId id) = 0;
virtual Error setLayerPictureProfileId(Display display, Layer layer, PictureProfileId id) = 0;
+ virtual Error startHdcpNegotiation(Display display,
+ const aidl::android::hardware::drm::HdcpLevels& levels) = 0;
virtual Error getLuts(Display display, const std::vector<sp<GraphicBuffer>>&,
std::vector<V3_0::Luts>*) = 0;
};
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index 8d16a6bbb3..fd0bf7386b 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -674,6 +674,11 @@ Error Display::setPictureProfileHandle(const PictureProfileHandle& handle) {
return static_cast<Error>(error);
}
+Error Display::startHdcpNegotiation(const aidl::android::hardware::drm::HdcpLevels& levels) {
+ const auto error = mComposer.startHdcpNegotiation(mId, levels);
+ return static_cast<Error>(error);
+}
+
Error Display::getLuts(const std::vector<sp<GraphicBuffer>>& buffers,
std::vector<aidl::android::hardware::graphics::composer3::Luts>* outLuts) {
const auto error = mComposer.getLuts(mId, buffers, outLuts);
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index 7c1f8e3da0..3f518211c4 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -203,6 +203,8 @@ public:
[[nodiscard]] virtual hal::Error getMaxLayerPictureProfiles(int32_t* maxProfiles) = 0;
[[nodiscard]] virtual hal::Error setPictureProfileHandle(
const PictureProfileHandle& handle) = 0;
+ [[nodiscard]] virtual hal::Error startHdcpNegotiation(
+ const aidl::android::hardware::drm::HdcpLevels& levels) = 0;
[[nodiscard]] virtual hal::Error getLuts(
const std::vector<android::sp<android::GraphicBuffer>>&,
std::vector<aidl::android::hardware::graphics::composer3::Luts>*) = 0;
@@ -291,6 +293,8 @@ public:
hal::Error setIdleTimerEnabled(std::chrono::milliseconds timeout) override;
hal::Error getMaxLayerPictureProfiles(int32_t* maxProfiles) override;
hal::Error setPictureProfileHandle(const android::PictureProfileHandle& handle) override;
+ hal::Error startHdcpNegotiation(
+ const aidl::android::hardware::drm::HdcpLevels& levels) override;
hal::Error getLuts(const std::vector<android::sp<android::GraphicBuffer>>&,
std::vector<aidl::android::hardware::graphics::composer3::Luts>*) override;
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 787a64b089..758d924a53 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -1054,6 +1054,15 @@ status_t HWComposer::setDisplayPictureProfileHandle(PhysicalDisplayId displayId,
return NO_ERROR;
}
+status_t HWComposer::startHdcpNegotiation(PhysicalDisplayId displayId,
+ const aidl::android::hardware::drm::HdcpLevels& levels) {
+ RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
+ auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
+ auto error = hwcDisplay->startHdcpNegotiation(levels);
+ RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
+ return NO_ERROR;
+}
+
status_t HWComposer::getLuts(
PhysicalDisplayId displayId, const std::vector<sp<GraphicBuffer>>& buffers,
std::vector<aidl::android::hardware::graphics::composer3::Luts>* luts) {
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 472411cf99..fcecd23bca 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -327,6 +327,8 @@ public:
virtual int32_t getMaxLayerPictureProfiles(PhysicalDisplayId) = 0;
virtual status_t setDisplayPictureProfileHandle(PhysicalDisplayId,
const PictureProfileHandle& handle) = 0;
+ virtual status_t startHdcpNegotiation(PhysicalDisplayId,
+ const aidl::android::hardware::drm::HdcpLevels&) = 0;
virtual status_t getLuts(PhysicalDisplayId, const std::vector<sp<GraphicBuffer>>&,
std::vector<aidl::android::hardware::graphics::composer3::Luts>*) = 0;
};
@@ -494,6 +496,8 @@ public:
int32_t getMaxLayerPictureProfiles(PhysicalDisplayId) override;
status_t setDisplayPictureProfileHandle(PhysicalDisplayId,
const android::PictureProfileHandle& profile) override;
+ status_t startHdcpNegotiation(PhysicalDisplayId,
+ const aidl::android::hardware::drm::HdcpLevels&) override;
status_t getLuts(PhysicalDisplayId, const std::vector<sp<GraphicBuffer>>&,
std::vector<aidl::android::hardware::graphics::composer3::Luts>*) override;
diff --git a/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp b/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp
index 3321f51026..5e03f30304 100644
--- a/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp
@@ -1461,6 +1461,10 @@ Error HidlComposer::getMaxLayerPictureProfiles(Display, int32_t*) {
return Error::UNSUPPORTED;
}
+Error HidlComposer::startHdcpNegotiation(Display, const aidl::android::hardware::drm::HdcpLevels&) {
+ return Error::UNSUPPORTED;
+}
+
Error HidlComposer::getLuts(Display, const std::vector<sp<GraphicBuffer>>&,
std::vector<aidl::android::hardware::graphics::composer3::Luts>*) {
return Error::UNSUPPORTED;
diff --git a/services/surfaceflinger/DisplayHardware/HidlComposerHal.h b/services/surfaceflinger/DisplayHardware/HidlComposerHal.h
index 86ca4b1782..d3874e4889 100644
--- a/services/surfaceflinger/DisplayHardware/HidlComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/HidlComposerHal.h
@@ -363,6 +363,7 @@ public:
Error getMaxLayerPictureProfiles(Display, int32_t* outMaxProfiles) override;
Error setDisplayPictureProfileId(Display, PictureProfileId) override;
Error setLayerPictureProfileId(Display, Layer, PictureProfileId) override;
+ Error startHdcpNegotiation(Display, const aidl::android::hardware::drm::HdcpLevels&) override;
Error getLuts(Display, const std::vector<sp<GraphicBuffer>>&,
std::vector<aidl::android::hardware::graphics::composer3::Luts>*) override;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index e89ef1874d..ffe70f547e 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2958,7 +2958,7 @@ CompositeResultsPerDisplay SurfaceFlinger::composite(
for (const auto& [token, display] : FTL_FAKE_GUARD(mStateLock, mDisplays)) {
auto compositionDisplay = display->getCompositionDisplay();
if (!compositionDisplay->getState().isEnabled) continue;
- for (auto outputLayer : compositionDisplay->getOutputLayersOrderedByZ()) {
+ for (const auto* outputLayer : compositionDisplay->getOutputLayersOrderedByZ()) {
if (outputLayer->getLayerFE().getCompositionState() == nullptr) {
// This is unexpected but instead of crashing, capture traces to disk
// and recover gracefully by forcing CE to rebuild layer stack.
@@ -3084,11 +3084,23 @@ CompositeResultsPerDisplay SurfaceFlinger::composite(
.c_str());
mPowerAdvisor->setCompositedWorkload(compositedWorkload);
- moveSnapshotsFromCompositionArgs(refreshArgs, layers);
SFTRACE_ASYNC_FOR_TRACK_END(WorkloadTracer::TRACK_NAME,
WorkloadTracer::COMPOSITION_TRACE_COOKIE);
SFTRACE_NAME_FOR_TRACK(WorkloadTracer::TRACK_NAME, "Post Composition");
SFTRACE_NAME("postComposition");
+
+ if (mDisplayModeController.supportsHdcp()) {
+ for (const auto& [id, _] : frameTargeters) {
+ ftl::FakeGuard guard(mStateLock);
+ if (const auto display = getCompositionDisplayLocked(id)) {
+ if (!display->isSecure() && display->hasSecureLayers()) {
+ mDisplayModeController.startHdcpNegotiation(id);
+ }
+ }
+ }
+ }
+
+ moveSnapshotsFromCompositionArgs(refreshArgs, layers);
mTimeStats->recordFrameDuration(pacesetterTarget.frameBeginTime().ns(), systemTime());
// Send a power hint after presentation is finished.
@@ -3793,9 +3805,9 @@ std::optional<DisplayModeId> SurfaceFlinger::processHotplugConnect(PhysicalDispl
.hwcDisplayId = hwcDisplayId,
.port = info.port,
.activeMode = std::move(activeMode)};
-
- // TODO: b/349703362 - Remove this when HDCP aidl APIs are enforced
- state.isSecure = true; // All physical displays are currently considered secure.
+ // TODO: b/349703362 - Remove first condition when HDCP aidl APIs are enforced
+ state.isSecure = !mDisplayModeController.supportsHdcp() ||
+ connectionType == ui::DisplayConnectionType::Internal;
state.isProtected = true;
state.displayName = std::move(info.name);
state.maxLayerPictureProfiles = getHwComposer().getMaxLayerPictureProfiles(displayId);
@@ -8481,10 +8493,12 @@ void SurfaceFlinger::updateHdcpLevels(hal::HWDisplayId hwcDisplayId, int32_t con
}
static_cast<void>(mScheduler->schedule([this, displayId = *idOpt, connectedLevel, maxLevel]() {
+ const bool secure = connectedLevel >= 2 /* HDCP_V1 */;
if (const auto display = FTL_FAKE_GUARD(mStateLock, getDisplayDeviceLocked(displayId))) {
Mutex::Autolock lock(mStateLock);
- display->setSecure(connectedLevel >= 2 /* HDCP_V1 */);
+ display->setSecure(secure);
}
+ FTL_FAKE_GUARD(kMainThreadContext, mDisplayModeController.setSecure(displayId, secure));
mScheduler->onHdcpLevelsChanged(scheduler::Cycle::Render, displayId, connectedLevel,
maxLevel);
}));
diff --git a/services/surfaceflinger/common/FlagManager.cpp b/services/surfaceflinger/common/FlagManager.cpp
index bf1035149b..ebf451501d 100644
--- a/services/surfaceflinger/common/FlagManager.cpp
+++ b/services/surfaceflinger/common/FlagManager.cpp
@@ -161,6 +161,7 @@ void FlagManager::dump(std::string& result) const {
DUMP_ACONFIG_FLAG(game_default_frame_rate);
DUMP_ACONFIG_FLAG(graphite_renderengine);
DUMP_ACONFIG_FLAG(hdcp_level_hal);
+ DUMP_ACONFIG_FLAG(hdcp_negotiation);
DUMP_ACONFIG_FLAG(idle_screen_refresh_rate_timeout);
DUMP_ACONFIG_FLAG(latch_unsignaled_with_auto_refresh_changed);
DUMP_ACONFIG_FLAG(local_tonemap_screenshots);
@@ -259,6 +260,7 @@ FLAG_MANAGER_ACONFIG_FLAG(frame_rate_category_mrr, "debug.sf.frame_rate_category
FLAG_MANAGER_ACONFIG_FLAG(misc1, "")
FLAG_MANAGER_ACONFIG_FLAG(vrr_config, "debug.sf.enable_vrr_config")
FLAG_MANAGER_ACONFIG_FLAG(hdcp_level_hal, "")
+FLAG_MANAGER_ACONFIG_FLAG(hdcp_negotiation, "debug.sf.hdcp_negotiation");
FLAG_MANAGER_ACONFIG_FLAG(add_sf_skipped_frames_to_trace, "")
FLAG_MANAGER_ACONFIG_FLAG(use_known_refresh_rate_for_fps_consistency, "")
FLAG_MANAGER_ACONFIG_FLAG(cache_when_source_crop_layer_only_moved,
diff --git a/services/surfaceflinger/common/include/common/FlagManager.h b/services/surfaceflinger/common/include/common/FlagManager.h
index 8f361ac610..72b3bc302a 100644
--- a/services/surfaceflinger/common/include/common/FlagManager.h
+++ b/services/surfaceflinger/common/include/common/FlagManager.h
@@ -95,6 +95,7 @@ public:
bool game_default_frame_rate() const;
bool graphite_renderengine() const;
bool hdcp_level_hal() const;
+ bool hdcp_negotiation() const;
bool idle_screen_refresh_rate_timeout() const;
bool latch_unsignaled_with_auto_refresh_changed() const;
bool local_tonemap_screenshots() const;
diff --git a/services/surfaceflinger/surfaceflinger_flags_new.aconfig b/services/surfaceflinger/surfaceflinger_flags_new.aconfig
index d412a19f3c..e8b75cfa6d 100644
--- a/services/surfaceflinger/surfaceflinger_flags_new.aconfig
+++ b/services/surfaceflinger/surfaceflinger_flags_new.aconfig
@@ -190,6 +190,16 @@ flag {
} # graphite_renderengine_preview_rollout
flag {
+ name: "hdcp_negotiation"
+ namespace: "core_graphics"
+ description: "detect secure layers to start HDCP negotiation"
+ bug: "375340594"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+} # hdcp_negotiation
+
+flag {
name: "increase_missed_frame_jank_threshold"
namespace: "core_graphics"
description: "Increase the jank threshold to 4 milliseconds"
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
index 7319f1ee22..00e4cc6818 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
@@ -190,6 +190,8 @@ public:
MOCK_METHOD(Error, getMaxLayerPictureProfiles, (Display, int32_t*));
MOCK_METHOD(Error, setDisplayPictureProfileId, (Display, PictureProfileId id));
MOCK_METHOD(Error, setLayerPictureProfileId, (Display, Layer, PictureProfileId id));
+ MOCK_METHOD(Error, startHdcpNegotiation,
+ (Display, const aidl::android::hardware::drm::HdcpLevels& levels));
MOCK_METHOD(Error, getLuts,
(Display, const std::vector<sp<GraphicBuffer>>&,
std::vector<aidl::android::hardware::graphics::composer3::Luts>*));
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWC2.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWC2.h
index 4ca6fe073b..a20b9e1f0d 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWC2.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWC2.h
@@ -116,6 +116,8 @@ public:
MOCK_METHOD(hal::Error, getMaxLayerPictureProfiles, (int32_t*), (override));
MOCK_METHOD(hal::Error, setPictureProfileHandle, (const android::PictureProfileHandle&),
(override));
+ MOCK_METHOD(hal::Error, startHdcpNegotiation,
+ (const aidl::android::hardware::drm::HdcpLevels& levels), (override));
MOCK_METHOD(hal::Error, getLuts,
(const std::vector<android::sp<android::GraphicBuffer>>&,
std::vector<aidl::android::hardware::graphics::composer3::Luts>*),
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWComposer.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWComposer.h
index 01d078bbf1..449c45bc0a 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWComposer.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWComposer.h
@@ -152,6 +152,8 @@ public:
MOCK_METHOD(int32_t, getMaxLayerPictureProfiles, (PhysicalDisplayId));
MOCK_METHOD(status_t, setDisplayPictureProfileHandle,
(PhysicalDisplayId, const PictureProfileHandle&));
+ MOCK_METHOD(status_t, startHdcpNegotiation,
+ (PhysicalDisplayId, const aidl::android::hardware::drm::HdcpLevels&));
MOCK_METHOD(status_t, getLuts,
(PhysicalDisplayId, const std::vector<sp<GraphicBuffer>>&,
std::vector<aidl::android::hardware::graphics::composer3::Luts>*));