Update HDCP for external displays
So the secure flag of Display object in Display Manager (DM) can
be set correctly. HWC calls the onSync method as a workaround,
to notify SurfaceFlinger (SF) about hdcp changes, SF in turn sends
an event to DM, DM will then fetch and update display info.
Bug: 280818362
Test: manual
Change-Id: I29ce0337865b51c0fc7bf7c2d7fdd4cd6d66ef46
diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp
index 693a357..56be1b1 100644
--- a/services/surfaceflinger/Scheduler/EventThread.cpp
+++ b/services/surfaceflinger/Scheduler/EventThread.cpp
@@ -100,6 +100,11 @@
case DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE:
return StringPrintf("ModeChanged{displayId=%s, modeId=%u}",
to_string(event.header.displayId).c_str(), event.modeChange.modeId);
+ case DisplayEventReceiver::DISPLAY_EVENT_HDCP_LEVELS_CHANGE:
+ return StringPrintf("HdcpLevelsChange{displayId=%s, connectedLevel=%d, maxLevel=%d}",
+ to_string(event.header.displayId).c_str(),
+ event.hdcpLevelsChange.connectedLevel,
+ event.hdcpLevelsChange.maxLevel);
default:
return "Event{}";
}
@@ -170,6 +175,20 @@
}};
}
+DisplayEventReceiver::Event makeHdcpLevelsChange(PhysicalDisplayId displayId,
+ int32_t connectedLevel, int32_t maxLevel) {
+ return DisplayEventReceiver::Event{
+ .header =
+ DisplayEventReceiver::Event::Header{
+ .type = DisplayEventReceiver::DISPLAY_EVENT_HDCP_LEVELS_CHANGE,
+ .displayId = displayId,
+ .timestamp = systemTime(),
+ },
+ .hdcpLevelsChange.connectedLevel = connectedLevel,
+ .hdcpLevelsChange.maxLevel = maxLevel,
+ };
+}
+
} // namespace
EventThreadConnection::EventThreadConnection(EventThread* eventThread, uid_t callingUid,
@@ -442,6 +461,14 @@
mCondition.notify_all();
}
+void EventThread::onHdcpLevelsChanged(PhysicalDisplayId displayId, int32_t connectedLevel,
+ int32_t maxLevel) {
+ std::lock_guard<std::mutex> lock(mMutex);
+
+ mPendingEvents.push_back(makeHdcpLevelsChange(displayId, connectedLevel, maxLevel));
+ mCondition.notify_all();
+}
+
void EventThread::threadMain(std::unique_lock<std::mutex>& lock) {
DisplayEventConsumers consumers;
diff --git a/services/surfaceflinger/Scheduler/EventThread.h b/services/surfaceflinger/Scheduler/EventThread.h
index 7842318..8970103 100644
--- a/services/surfaceflinger/Scheduler/EventThread.h
+++ b/services/surfaceflinger/Scheduler/EventThread.h
@@ -131,6 +131,9 @@
const sp<EventThreadConnection>& connection) const = 0;
virtual void onNewVsyncSchedule(std::shared_ptr<scheduler::VsyncSchedule>) = 0;
+
+ virtual void onHdcpLevelsChanged(PhysicalDisplayId displayId, int32_t connectedLevel,
+ int32_t maxLevel) = 0;
};
struct IEventThreadCallback {
@@ -177,6 +180,9 @@
void onNewVsyncSchedule(std::shared_ptr<scheduler::VsyncSchedule>) override EXCLUDES(mMutex);
+ void onHdcpLevelsChanged(PhysicalDisplayId displayId, int32_t connectedLevel,
+ int32_t maxLevel) override;
+
private:
friend EventThreadTest;
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index ce59a04..1b72071 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -412,6 +412,17 @@
thread->onFrameRateOverridesChanged(displayId, std::move(overrides));
}
+void Scheduler::onHdcpLevelsChanged(ConnectionHandle handle, PhysicalDisplayId displayId,
+ int32_t connectedLevel, int32_t maxLevel) {
+ android::EventThread* thread;
+ {
+ std::lock_guard<std::mutex> lock(mConnectionsLock);
+ RETURN_IF_INVALID_HANDLE(handle);
+ thread = mConnections[handle].thread.get();
+ }
+ thread->onHdcpLevelsChanged(displayId, connectedLevel, maxLevel);
+}
+
void Scheduler::onPrimaryDisplayModeChanged(ConnectionHandle handle, const FrameRateMode& mode) {
{
std::lock_guard<std::mutex> lock(mPolicyLock);
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index ce585c6..a29d153 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -173,6 +173,8 @@
void onFrameRateOverridesChanged(ConnectionHandle, PhysicalDisplayId)
EXCLUDES(mConnectionsLock);
+ void onHdcpLevelsChanged(ConnectionHandle, PhysicalDisplayId, int32_t, int32_t);
+
// Modifies work duration in the event thread.
void setDuration(ConnectionHandle, std::chrono::nanoseconds workDuration,
std::chrono::nanoseconds readyDuration);