Skip to content

Commit

Permalink
com.microsoft.playready EME support added. (#49)
Browse files Browse the repository at this point in the history
Summary: com.microsoft.playready EME support added.
Type: Feature
Test Plan: Unittests, Component Tests, YT Conformance Tests, NPLB
Jira: RIALTO-499
  • Loading branch information
skywojciechowskim authored Mar 25, 2024
1 parent e084188 commit 0f369a3
Show file tree
Hide file tree
Showing 16 changed files with 157 additions and 8 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@
/clang-format_errors.log
/clang-format_errors.xml
/cppcheck_report.txt
/.vscode/*
1 change: 1 addition & 0 deletions library/include/CdmBackend.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class CdmBackend : public ICdmBackend, public firebolt::rialto::IControlClient
bool getLastDrmError(int32_t keySessionId, uint32_t &errorCode) override;
bool getDrmTime(uint64_t &drmTime) override;
bool getCdmKeySessionId(int32_t keySessionId, std::string &cdmKeySessionId) override;
bool releaseKeySession(int32_t keySessionId) override;

private:
bool createMediaKeys();
Expand Down
1 change: 1 addition & 0 deletions library/include/ICdmBackend.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class ICdmBackend
virtual bool getLastDrmError(int32_t keySessionId, uint32_t &errorCode) = 0;
virtual bool getDrmTime(uint64_t &drmTime) = 0;
virtual bool getCdmKeySessionId(int32_t keySessionId, std::string &cdmKeySessionId) = 0;
virtual bool releaseKeySession(int32_t keySessionId) = 0;
};

#endif // I_CDM_BACKEND_H_
1 change: 1 addition & 0 deletions library/include/MediaKeysCapabilitiesBackend.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class MediaKeysCapabilitiesBackend
std::vector<std::string> getSupportedKeySystems();
OpenCDMError supportsKeySystem(const std::string &keySystem);
bool getSupportedKeySystemVersion(const std::string &keySystem, std::string &version);
bool isServerCertificateSupported(const std::string &keySystem);

private:
MediaKeysCapabilitiesBackend();
Expand Down
1 change: 1 addition & 0 deletions library/include/OpenCDMSessionPrivate.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ class OpenCDMSessionPrivate : public OpenCDMSession, public firebolt::rialto::IM
private:
void initializeCdmKeySessionId();
void updateChallenge(const std::vector<unsigned char> &challenge);
void releaseSession();

private:
Logger m_log;
Expand Down
10 changes: 10 additions & 0 deletions library/source/CdmBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,16 @@ bool CdmBackend::getCdmKeySessionId(int32_t keySessionId, std::string &cdmKeySes
return firebolt::rialto::MediaKeyErrorStatus::OK == m_mediaKeys->getCdmKeySessionId(keySessionId, cdmKeySessionId);
}

bool CdmBackend::releaseKeySession(int32_t keySessionId)
{
std::unique_lock<std::mutex> lock{m_mutex};
if (!m_mediaKeys)
{
return false;
}
return firebolt::rialto::MediaKeyErrorStatus::OK == m_mediaKeys->releaseKeySession(keySessionId);
}

bool CdmBackend::createMediaKeys()
{
if (!m_mediaKeysFactory)
Expand Down
10 changes: 10 additions & 0 deletions library/source/MediaKeysCapabilitiesBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,16 @@ bool MediaKeysCapabilitiesBackend::getSupportedKeySystemVersion(const std::strin
return result;
}

bool MediaKeysCapabilitiesBackend::isServerCertificateSupported(const std::string &keySystem)
{
bool result{false};
if (m_mediaKeysCapabilities)
{
result = m_mediaKeysCapabilities->isServerCertificateSupported(keySystem);
}
return result;
}

MediaKeysCapabilitiesBackend::MediaKeysCapabilitiesBackend()
{
std::shared_ptr<firebolt::rialto::IMediaKeysCapabilitiesFactory> factory =
Expand Down
19 changes: 19 additions & 0 deletions library/source/OpenCDMSessionPrivate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ OpenCDMSessionPrivate::OpenCDMSessionPrivate(const std::shared_ptr<ICdmBackend>
OpenCDMSessionPrivate::~OpenCDMSessionPrivate()
{
m_log << debug << "destructed: " << static_cast<void *>(this);
if (m_isInitialized)
{
releaseSession();
}
}

bool OpenCDMSessionPrivate::initialize()
Expand Down Expand Up @@ -361,6 +365,21 @@ bool OpenCDMSessionPrivate::removeSession()
return false;
}

void OpenCDMSessionPrivate::releaseSession()
{
if (-1 != m_rialtoSessionId)
{
if (m_cdmBackend->releaseKeySession(m_rialtoSessionId))
{
m_log << info << "Successfully released the session";
}
else
{
m_log << warn << "Failed to release the session.";
}
}
}

bool OpenCDMSessionPrivate::containsKey(const std::vector<uint8_t> &keyId)
{
if (!m_cdmBackend)
Expand Down
27 changes: 20 additions & 7 deletions library/source/open_cdm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ namespace
{
const Logger kLog{"open_cdm"};

bool isPlayreadyKeysystem(const std::string &keySystem)
bool isNetflixPlayreadyKeysystem(const std::string &keySystem)
{
return keySystem.find("playready") != std::string::npos;
return keySystem.find("netflix") != std::string::npos;
}
} // namespace

Expand Down Expand Up @@ -185,7 +185,7 @@ OpenCDMError opencdm_construct_session(struct OpenCDMSystem *system, const Licen
return ERROR_INVALID_SESSION;
}

if (!isPlayreadyKeysystem(system->keySystem()))
if (!isNetflixPlayreadyKeysystem(system->keySystem()))
{
if (!newSession->initialize())
{
Expand All @@ -200,7 +200,7 @@ OpenCDMError opencdm_construct_session(struct OpenCDMSystem *system, const Licen
kLog << error << "Failed to generate request";

opencdm_session_close(newSession);
ActiveSessions::instance().remove(newSession);
opencdm_destruct_session(newSession);
return ERROR_FAIL;
}
}
Expand All @@ -213,9 +213,12 @@ OpenCDMError opencdm_construct_session(struct OpenCDMSystem *system, const Licen
OpenCDMError opencdm_destruct_session(struct OpenCDMSession *session)
{
kLog << debug << __func__;
// MKS is destructed in opencdm_session_close or in opencdm_session_clean_decrypt_context
ActiveSessions::instance().remove(session);
return ERROR_NONE;
if (session)
{
ActiveSessions::instance().remove(session);
return ERROR_NONE;
}
return ERROR_INVALID_SESSION;
}

OpenCDMError opencdm_session_load(struct OpenCDMSession *session)
Expand Down Expand Up @@ -388,3 +391,13 @@ OpenCDMError opencdm_session_close(struct OpenCDMSession *session)

return result;
}

OpenCDMBool opencdm_system_supports_server_certificate(struct OpenCDMSystem *system)
{
kLog << debug << __func__;
if (MediaKeysCapabilitiesBackend::instance().isServerCertificateSupported(system->keySystem()))
{
return OpenCDMBool::OPENCDM_BOOL_TRUE;
}
return OpenCDMBool::OPENCDM_BOOL_FALSE;
}
1 change: 1 addition & 0 deletions tests/mocks/CdmBackendMock.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class CdmBackendMock : public ICdmBackend
MOCK_METHOD(bool, getLastDrmError, (int32_t keySessionId, uint32_t &errorCode), (override));
MOCK_METHOD(bool, getDrmTime, (uint64_t & drmTime), (override));
MOCK_METHOD(bool, getCdmKeySessionId, (int32_t keySessionId, std::string &cdmKeySessionId), (override));
MOCK_METHOD(bool, releaseKeySession, (int32_t keySessionId), (override));
};

#endif // CDM_BACKEND_MOCK_H_
1 change: 1 addition & 0 deletions tests/mocks/MediaKeysCapabilitiesMock.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class MediaKeysCapabilitiesMock : public IMediaKeysCapabilities
MOCK_METHOD(std::vector<std::string>, getSupportedKeySystems, (), (override));
MOCK_METHOD(bool, supportsKeySystem, (const std::string &keySystem), (override));
MOCK_METHOD(bool, getSupportedKeySystemVersion, (const std::string &keySystem, std::string &version), (override));
MOCK_METHOD(bool, isServerCertificateSupported, (const std::string &keySystem), (override));
};
} // namespace firebolt::rialto

Expand Down
1 change: 1 addition & 0 deletions tests/mocks/MediaKeysMock.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class MediaKeysMock : public IMediaKeys
MOCK_METHOD(MediaKeyErrorStatus, getDrmTime, (uint64_t & drmTime), (override));
MOCK_METHOD(MediaKeyErrorStatus, getCdmKeySessionId, (int32_t keySessionId, std::string &cdmKeySessionId),
(override));
MOCK_METHOD(MediaKeyErrorStatus, releaseKeySession, (int32_t keySessionId), (override));
};

class MediaKeysFactoryMock : public IMediaKeysFactory
Expand Down
21 changes: 21 additions & 0 deletions tests/ut/CdmBackendTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -480,3 +480,24 @@ TEST_F(CdmBackendTests, ShouldGetCdmKeySessionId)
changeStateToRunning();
EXPECT_TRUE(m_sut.getCdmKeySessionId(kKeySessionId, cdmKeySessionId));
}

TEST_F(CdmBackendTests, ShouldFailToReleaseKeySessionWhenMediaKeysIsNotPresent)
{
EXPECT_FALSE(m_sut.releaseKeySession(kKeySessionId));
}

TEST_F(CdmBackendTests, ShouldFailToReleaseKeySession)
{
EXPECT_CALL(*m_mediaKeysMock, releaseKeySession(kKeySessionId))
.WillOnce(Return(firebolt::rialto::MediaKeyErrorStatus::FAIL));
changeStateToRunning();
EXPECT_FALSE(m_sut.releaseKeySession(kKeySessionId));
}

TEST_F(CdmBackendTests, ShouldReleaseKeySession)
{
EXPECT_CALL(*m_mediaKeysMock, releaseKeySession(kKeySessionId))
.WillOnce(Return(firebolt::rialto::MediaKeyErrorStatus::OK));
changeStateToRunning();
EXPECT_TRUE(m_sut.releaseKeySession(kKeySessionId));
}
6 changes: 6 additions & 0 deletions tests/ut/MediaKeysCapabilitiesBackendTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,9 @@ TEST_F(MediaKeysCapabilitiesBackendTests, shouldGetSupportedKeySystemVersion)
EXPECT_CALL(*m_mediaKeysCapabilitiesMock, getSupportedKeySystemVersion(kKeySystem, _)).WillOnce(Return(true));
EXPECT_TRUE(MediaKeysCapabilitiesBackend::instance().getSupportedKeySystemVersion(kKeySystem, version));
}

TEST_F(MediaKeysCapabilitiesBackendTests, shouldGetSupportedServerCertificate)
{
EXPECT_CALL(*m_mediaKeysCapabilitiesMock, isServerCertificateSupported(kKeySystem)).WillOnce(Return(true));
EXPECT_TRUE(MediaKeysCapabilitiesBackend::instance().isServerCertificateSupported(kKeySystem));
}
Loading

0 comments on commit 0f369a3

Please sign in to comment.