Skip to content

Commit 9b2db4b

Browse files
author
Huihong Luo
committed
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
1 parent 73416e1 commit 9b2db4b

File tree

22 files changed

+157
-13
lines changed

22 files changed

+157
-13
lines changed

services/surfaceflinger/CompositionEngine/include/compositionengine/Display.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ class Display : public virtual Output {
3737
// Gets the DisplayId for the display
3838
virtual DisplayId getId() const = 0;
3939

40+
// True if the display has a secure layer
41+
virtual bool hasSecureLayers() const = 0;
42+
4043
// True if the display is secure
4144
virtual bool isSecure() const = 0;
4245

services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,15 +68,16 @@ class Display : public compositionengine::impl::Output, public virtual compositi
6868

6969
// compositionengine::Display overrides
7070
DisplayId getId() const override;
71+
bool hasSecureLayers() const override;
7172
bool isSecure() const override;
73+
void setSecure(bool secure) override;
7274
bool isVirtual() const override;
7375
void disconnect() override;
7476
void createDisplayColorProfile(
7577
const compositionengine::DisplayColorProfileCreationArgs&) override;
7678
void createRenderSurface(const compositionengine::RenderSurfaceCreationArgs&) override;
7779
void createClientCompositionCache(uint32_t cacheSize) override;
7880
void applyDisplayBrightness(bool applyImmediately) override;
79-
void setSecure(bool secure) override;
8081

8182
// Internal helpers used by chooseCompositionStrategy()
8283
using ChangedTypes = android::HWComposer::DeviceRequestedChanges::ChangedTypes;

services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Display.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class Display : public compositionengine::mock::Output, public compositionengine
3232
virtual ~Display();
3333

3434
MOCK_CONST_METHOD0(getId, DisplayId());
35+
MOCK_CONST_METHOD0(hasSecureLayers, bool());
3536
MOCK_CONST_METHOD0(isSecure, bool());
3637
MOCK_METHOD1(setSecure, void(bool));
3738
MOCK_CONST_METHOD0(isVirtual, bool());

services/surfaceflinger/CompositionEngine/src/Display.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,14 @@ DisplayId Display::getId() const {
7070
return asDisplayId(mIdVariant);
7171
}
7272

73+
bool Display::hasSecureLayers() const {
74+
const auto layers = getOutputLayersOrderedByZ();
75+
return std::any_of(layers.begin(), layers.end(), [](const auto& layer) {
76+
const auto* state = layer->getLayerFE().getCompositionState();
77+
return state && state->isSecure;
78+
});
79+
}
80+
7381
bool Display::isSecure() const {
7482
return getState().isSecure;
7583
}

services/surfaceflinger/Display/DisplayModeController.cpp

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,23 +46,36 @@ DisplayModeController::Display::Display(DisplaySnapshotRef snapshot,
4646
renderRateFpsTrace(concatId("RenderRateFps")),
4747
hasDesiredModeTrace(concatId("HasDesiredMode"), false) {}
4848

49+
DisplayModeController::DisplayModeController() {
50+
using namespace std::string_literals;
51+
mSupportsHdcp = base::GetBoolProperty("debug.sf.hdcp_support"s, false);
52+
}
53+
4954
void DisplayModeController::registerDisplay(PhysicalDisplayId displayId,
5055
DisplaySnapshotRef snapshotRef,
5156
RefreshRateSelectorPtr selectorPtr) {
57+
DisplayPtr displayPtr = std::make_unique<Display>(snapshotRef, selectorPtr);
58+
// TODO: b/349703362 - Remove first condition when HDCP aidl APIs are enforced
59+
displayPtr->setSecure(!supportsHdcp() ||
60+
snapshotRef.get().connectionType() ==
61+
ui::DisplayConnectionType::Internal);
5262
std::lock_guard lock(mDisplayLock);
53-
mDisplays.emplace_or_replace(displayId, std::make_unique<Display>(snapshotRef, selectorPtr));
63+
mDisplays.emplace_or_replace(displayId, std::move(displayPtr));
5464
}
5565

5666
void DisplayModeController::registerDisplay(DisplaySnapshotRef snapshotRef,
5767
DisplayModeId activeModeId,
5868
scheduler::RefreshRateSelector::Config config) {
5969
const auto& snapshot = snapshotRef.get();
6070
const auto displayId = snapshot.displayId();
61-
71+
DisplayPtr displayPtr =
72+
std::make_unique<Display>(snapshotRef, snapshot.displayModes(), activeModeId, config);
73+
// TODO: b/349703362 - Remove first condition when HDCP aidl APIs are enforced
74+
displayPtr->setSecure(!supportsHdcp() ||
75+
snapshotRef.get().connectionType() ==
76+
ui::DisplayConnectionType::Internal);
6277
std::lock_guard lock(mDisplayLock);
63-
mDisplays.emplace_or_replace(displayId,
64-
std::make_unique<Display>(snapshotRef, snapshot.displayModes(),
65-
activeModeId, config));
78+
mDisplays.emplace_or_replace(displayId, std::move(displayPtr));
6679
}
6780

6881
void DisplayModeController::unregisterDisplay(PhysicalDisplayId displayId) {
@@ -304,5 +317,30 @@ auto DisplayModeController::getKernelIdleTimerState(PhysicalDisplayId displayId)
304317
return {desiredModeIdOpt, displayPtr->isKernelIdleTimerEnabled};
305318
}
306319

320+
bool DisplayModeController::supportsHdcp() const {
321+
return mSupportsHdcp && FlagManager::getInstance().hdcp_level_hal() &&
322+
FlagManager::getInstance().hdcp_negotiation();
323+
}
324+
325+
void DisplayModeController::startHdcpNegotiation(PhysicalDisplayId displayId) {
326+
using aidl::android::hardware::drm::HdcpLevel;
327+
using aidl::android::hardware::drm::HdcpLevels;
328+
constexpr HdcpLevels kLevels = {.connectedLevel = HdcpLevel::HDCP_V2_1,
329+
.maxLevel = HdcpLevel::HDCP_V2_3};
330+
331+
std::lock_guard lock(mDisplayLock);
332+
const auto& displayPtr = FTL_TRY(mDisplays.get(displayId).ok_or(ftl::Unit())).get();
333+
if (displayPtr->hdcpState == HdcpState::Desired) {
334+
const auto status = mComposerPtr->startHdcpNegotiation(displayId, kLevels);
335+
displayPtr->hdcpState = (status == NO_ERROR) ? HdcpState::Enabled : HdcpState::Undesired;
336+
}
337+
}
338+
339+
void DisplayModeController::setSecure(PhysicalDisplayId displayId, bool secure) {
340+
std::lock_guard lock(mDisplayLock);
341+
const auto& displayPtr = FTL_TRY(mDisplays.get(displayId).ok_or(ftl::Unit())).get();
342+
displayPtr->setSecure(secure);
343+
}
344+
307345
#pragma clang diagnostic pop
308346
} // namespace android::display

services/surfaceflinger/Display/DisplayModeController.h

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class DisplayModeController {
4646
public:
4747
using ActiveModeListener = ftl::Function<void(PhysicalDisplayId, Fps vsyncRate, Fps renderFps)>;
4848

49-
DisplayModeController() = default;
49+
DisplayModeController();
5050

5151
void setHwComposer(HWComposer* composerPtr) { mComposerPtr = composerPtr; }
5252
void setActiveModeListener(const ActiveModeListener& listener) {
@@ -109,7 +109,16 @@ class DisplayModeController {
109109
KernelIdleTimerState getKernelIdleTimerState(PhysicalDisplayId) const
110110
REQUIRES(kMainThreadContext) EXCLUDES(mDisplayLock);
111111

112+
void setSecure(PhysicalDisplayId displayId, bool secure) REQUIRES(kMainThreadContext)
113+
EXCLUDES(mDisplayLock);
114+
115+
bool supportsHdcp() const;
116+
117+
void startHdcpNegotiation(PhysicalDisplayId displayId) REQUIRES(kMainThreadContext);
118+
112119
private:
120+
enum class HdcpState { Undesired, Desired, Enabled };
121+
113122
struct Display {
114123
template <size_t N>
115124
std::string concatId(const char (&)[N]) const;
@@ -120,6 +129,11 @@ class DisplayModeController {
120129
: Display(snapshot,
121130
std::make_shared<scheduler::RefreshRateSelector>(std::move(modes),
122131
activeModeId, config)) {}
132+
133+
void setSecure(bool secure) {
134+
hdcpState = secure ? HdcpState::Undesired : HdcpState::Desired;
135+
}
136+
123137
const DisplaySnapshotRef snapshot;
124138
const RefreshRateSelectorPtr selectorPtr;
125139

@@ -135,6 +149,8 @@ class DisplayModeController {
135149
bool isModeSetPending GUARDED_BY(kMainThreadContext) = false;
136150

137151
bool isKernelIdleTimerEnabled GUARDED_BY(kMainThreadContext) = false;
152+
153+
HdcpState hdcpState = HdcpState::Desired;
138154
};
139155

140156
using DisplayPtr = std::unique_ptr<Display>;
@@ -153,6 +169,8 @@ class DisplayModeController {
153169

154170
mutable std::mutex mDisplayLock;
155171
ui::PhysicalDisplayMap<PhysicalDisplayId, DisplayPtr> mDisplays GUARDED_BY(mDisplayLock);
172+
173+
bool mSupportsHdcp = false;
156174
};
157175

158176
} // namespace android::display

services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1718,6 +1718,18 @@ Error AidlComposer::setLayerPictureProfileId(Display display, Layer layer, Pictu
17181718
return error;
17191719
}
17201720

1721+
Error AidlComposer::startHdcpNegotiation(Display display,
1722+
const aidl::android::hardware::drm::HdcpLevels& levels) {
1723+
const auto status =
1724+
mAidlComposerClient->startHdcpNegotiation(translate<int64_t>(display), levels);
1725+
if (!status.isOk()) {
1726+
ALOGE("startHdcpNegotiation failed %s", status.getDescription().c_str());
1727+
return static_cast<Error>(status.getServiceSpecificError());
1728+
}
1729+
1730+
return Error::NONE;
1731+
}
1732+
17211733
Error AidlComposer::getLuts(Display display, const std::vector<sp<GraphicBuffer>>& buffers,
17221734
std::vector<aidl::android::hardware::graphics::composer3::Luts>* luts) {
17231735
std::vector<aidl::android::hardware::graphics::composer3::Buffer> aidlBuffers;

services/surfaceflinger/DisplayHardware/AidlComposerHal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ class AidlComposer final : public Hwc2::Composer {
250250
Error getMaxLayerPictureProfiles(Display, int32_t* outMaxProfiles) override;
251251
Error setDisplayPictureProfileId(Display, PictureProfileId id) override;
252252
Error setLayerPictureProfileId(Display, Layer, PictureProfileId id) override;
253+
Error startHdcpNegotiation(Display, const aidl::android::hardware::drm::HdcpLevels&) override;
253254
Error getLuts(Display, const std::vector<sp<GraphicBuffer>>&,
254255
std::vector<aidl::android::hardware::graphics::composer3::Luts>*) override;
255256

services/surfaceflinger/DisplayHardware/ComposerHal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,8 @@ class Composer {
317317
virtual Error getMaxLayerPictureProfiles(Display display, int32_t* outMaxProfiles) = 0;
318318
virtual Error setDisplayPictureProfileId(Display display, PictureProfileId id) = 0;
319319
virtual Error setLayerPictureProfileId(Display display, Layer layer, PictureProfileId id) = 0;
320+
virtual Error startHdcpNegotiation(Display display,
321+
const aidl::android::hardware::drm::HdcpLevels& levels) = 0;
320322
virtual Error getLuts(Display display, const std::vector<sp<GraphicBuffer>>&,
321323
std::vector<V3_0::Luts>*) = 0;
322324
};

services/surfaceflinger/DisplayHardware/HWC2.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,11 @@ Error Display::setPictureProfileHandle(const PictureProfileHandle& handle) {
674674
return static_cast<Error>(error);
675675
}
676676

677+
Error Display::startHdcpNegotiation(const aidl::android::hardware::drm::HdcpLevels& levels) {
678+
const auto error = mComposer.startHdcpNegotiation(mId, levels);
679+
return static_cast<Error>(error);
680+
}
681+
677682
Error Display::getLuts(const std::vector<sp<GraphicBuffer>>& buffers,
678683
std::vector<aidl::android::hardware::graphics::composer3::Luts>* outLuts) {
679684
const auto error = mComposer.getLuts(mId, buffers, outLuts);

0 commit comments

Comments
 (0)