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

Commit 9b2db4b7 authored by Huihong Luo's avatar Huihong Luo
Browse files

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
parent 73416e16
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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;

+2 −1
Original line number Diff line number Diff line
@@ -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;
+1 −0
Original line number Diff line number Diff line
@@ -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());
+8 −0
Original line number Diff line number Diff line
@@ -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;
}
+43 −5
Original line number Diff line number Diff line
@@ -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
Loading