Skip to content

Commit

Permalink
[Decrypters] Reworked to use smartpointers, new wv interfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
CastagnaIT committed Sep 2, 2024
1 parent e2a9dd4 commit f414ddf
Show file tree
Hide file tree
Showing 29 changed files with 756 additions and 567 deletions.
4 changes: 2 additions & 2 deletions lib/jni/jni/src/ClassLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

using namespace jni;

CJNIClassLoader::CJNIClassLoader(const std::string &dexPath)
jni::CJNIClassLoader::CJNIClassLoader(const std::string &dexPath)
: CJNIBase("dalvik/system/PathClassLoader")
{
jhobject systemLoader = call_static_method<jhobject>("java/lang/ClassLoader", "getSystemClassLoader", "()Ljava/lang/ClassLoader;");
Expand All @@ -21,7 +21,7 @@ CJNIClassLoader::CJNIClassLoader(const std::string &dexPath)
m_object.setGlobal();
}

jhclass CJNIClassLoader::loadClass(std::string className) const
jhclass jni::CJNIClassLoader::loadClass(std::string className) const
{
return call_method<jhclass>(m_object,
"loadClass", "(Ljava/lang/String;)Ljava/lang/Class;",
Expand Down
3 changes: 3 additions & 0 deletions lib/jni/jni/src/ClassLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

#include "JNIBase.h"

namespace jni
{
class CJNIClassLoader : public CJNIBase
{
public:
Expand All @@ -22,3 +24,4 @@ class CJNIClassLoader : public CJNIBase
private:
CJNIClassLoader();
};
}
5 changes: 1 addition & 4 deletions lib/jni/jni/src/MediaDrmOnEventListener.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,9 @@

#include "JNIBase.h"


class CJNIClassLoader;

namespace jni
{

class CJNIClassLoader;
class CJNIMediaDrm;

class CJNIMediaDrmOnEventListener : public CJNIBase, public CJNIInterfaceImplem<CJNIMediaDrmOnEventListener>
Expand Down
17 changes: 3 additions & 14 deletions src/Session.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,16 +115,7 @@ void CSession::DisposeSampleDecrypter()
for (auto& cdmSession : m_cdmSessions)
{
cdmSession.m_cdmSessionStr = nullptr;
if (!cdmSession.m_sharedCencSsd)
{
m_decrypter->DestroySingleSampleDecrypter(cdmSession.m_cencSingleSampleDecrypter);
cdmSession.m_cencSingleSampleDecrypter = nullptr;
}
else
{
cdmSession.m_cencSingleSampleDecrypter = nullptr;
cdmSession.m_sharedCencSsd = false;
}
cdmSession.m_cencSingleSampleDecrypter = nullptr;
}
}
}
Expand Down Expand Up @@ -485,16 +476,15 @@ bool CSession::InitializeDRM(bool addDefaultKID /* = false */)
{
LOG::Log(LOGDEBUG, "Initializing stream with KID: %s", defaultKidStr.c_str());

// If a decrypter has the default KID, re-use the same decrypter for also this session
for (size_t i{1}; i < ses; ++i)
{
if (m_decrypter->HasLicenseKey(m_cdmSessions[i].m_cencSingleSampleDecrypter, defaultKid))
{
session.m_cencSingleSampleDecrypter = m_cdmSessions[i].m_cencSingleSampleDecrypter;
session.m_sharedCencSsd = true;
break;
}
}

}
else if (defaultKid.empty())
{
Expand All @@ -503,7 +493,6 @@ bool CSession::InitializeDRM(bool addDefaultKID /* = false */)
if (sessionPsshset.pssh_ == m_adaptiveTree->m_currentPeriod->GetPSSHSets()[i].pssh_)
{
session.m_cencSingleSampleDecrypter = m_cdmSessions[i].m_cencSingleSampleDecrypter;
session.m_sharedCencSsd = true;
break;
}
}
Expand Down Expand Up @@ -1312,7 +1301,7 @@ void CSession::OnStreamChange(adaptive::AdaptiveStream* adStream)
}
}

Adaptive_CencSingleSampleDecrypter* CSession::GetSingleSampleDecrypter(std::string sessionId)
std::shared_ptr<Adaptive_CencSingleSampleDecrypter> CSession::GetSingleSampleDecrypter(std::string sessionId)
{
for (std::vector<CCdmSession>::iterator b(m_cdmSessions.begin() + 1), e(m_cdmSessions.end());
b != e; ++b)
Expand Down
9 changes: 5 additions & 4 deletions src/Session.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#include <kodi/platform/android/System.h>
#endif

#include <memory>

class Adaptive_CencSingleSampleDecrypter;

namespace SESSION
Expand Down Expand Up @@ -136,7 +138,7 @@ class ATTR_DLL_LOCAL CSession : public adaptive::AdaptiveStreamObserver
* \param index The index (psshSet number) of the cdm session
* \return The single sample decrypter
*/
Adaptive_CencSingleSampleDecrypter* GetSingleSampleDecryptor(unsigned int index) const
std::shared_ptr<Adaptive_CencSingleSampleDecrypter> GetSingleSampleDecryptor(unsigned int index) const
{
return m_cdmSessions[index].m_cencSingleSampleDecrypter;
}
Expand All @@ -150,7 +152,7 @@ class ATTR_DLL_LOCAL CSession : public adaptive::AdaptiveStreamObserver
* \param sessionId The session id string to match
* \return The single sample decrypter
*/
Adaptive_CencSingleSampleDecrypter* GetSingleSampleDecrypter(std::string sessionId);
std::shared_ptr<Adaptive_CencSingleSampleDecrypter> GetSingleSampleDecrypter(std::string sessionId);

/*! \brief Get decrypter capabilities for a single sample decrypter
* \param index The index (psshSet number) of the cdm session
Expand Down Expand Up @@ -348,9 +350,8 @@ class ATTR_DLL_LOCAL CSession : public adaptive::AdaptiveStreamObserver
struct CCdmSession
{
DRM::DecrypterCapabilites m_decrypterCaps;
Adaptive_CencSingleSampleDecrypter* m_cencSingleSampleDecrypter{nullptr};
std::shared_ptr<Adaptive_CencSingleSampleDecrypter> m_cencSingleSampleDecrypter;
const char* m_cdmSessionStr{nullptr};
bool m_sharedCencSsd{false};
};
std::vector<CCdmSession> m_cdmSessions;

Expand Down
4 changes: 2 additions & 2 deletions src/common/AdaptiveCencSampleDecrypter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
#include "AdaptiveCencSampleDecrypter.h"

CAdaptiveCencSampleDecrypter::CAdaptiveCencSampleDecrypter(
Adaptive_CencSingleSampleDecrypter* singleSampleDecrypter,
std::shared_ptr<Adaptive_CencSingleSampleDecrypter> singleSampleDecrypter,
AP4_CencSampleInfoTable* sampleInfoTable)
: AP4_CencSampleDecrypter(singleSampleDecrypter, sampleInfoTable)
: AP4_CencSampleDecrypter(singleSampleDecrypter.get(), sampleInfoTable)
{
m_decrypter = singleSampleDecrypter;
}
Expand Down
6 changes: 4 additions & 2 deletions src/common/AdaptiveCencSampleDecrypter.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@

#include "AdaptiveDecrypter.h"

#include <memory>

#include <bento4/Ap4.h>

class CAdaptiveCencSampleDecrypter : public AP4_CencSampleDecrypter
{
public:
CAdaptiveCencSampleDecrypter(Adaptive_CencSingleSampleDecrypter* singleSampleDecrypter,
CAdaptiveCencSampleDecrypter(std::shared_ptr<Adaptive_CencSingleSampleDecrypter> singleSampleDecrypter,
AP4_CencSampleInfoTable* sampleInfoTable);
~CAdaptiveCencSampleDecrypter() override {};

Expand All @@ -23,5 +25,5 @@ class CAdaptiveCencSampleDecrypter : public AP4_CencSampleDecrypter
const AP4_UI08* iv);

protected:
Adaptive_CencSingleSampleDecrypter* m_decrypter;
std::shared_ptr<Adaptive_CencSingleSampleDecrypter> m_decrypter;
};
60 changes: 60 additions & 0 deletions src/decrypters/HelperWv.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,69 @@

#pragma once

#ifdef INPUTSTREAM_TEST_BUILD
#include "test/KodiStubs.h"
#else
#include <kodi/AddonBase.h>
#endif

#include <cstdint>
#include <memory>
#include <vector>

enum class CdmMessageType
{
UNKNOWN,
SESSION_MESSAGE,
SESSION_KEY_CHANGE,
EVENT_KEY_REQUIRED,
};

struct CdmMessage
{
std::string sessionId;
CdmMessageType type{CdmMessageType::UNKNOWN};
std::vector<uint8_t> data;
uint32_t status{0};
};

class ATTR_DLL_LOCAL IWVObserver // Observer called by IWVSubject interface
{
public:
virtual ~IWVObserver() = default;
virtual void OnNotify(const CdmMessage& message) = 0;
};

class ATTR_DLL_LOCAL IWVSubject // Subject to make callbacks to IWVObserver interfaces
{
public:
virtual ~IWVSubject() = default;
virtual void AttachObserver(IWVObserver* observer) = 0;
virtual void DetachObserver(IWVObserver* observer) = 0;
virtual void NotifyObservers(const CdmMessage& message) = 0;
};

template<class T>
class ATTR_DLL_LOCAL IWVCdmAdapter : public IWVSubject
{
public:
virtual ~IWVCdmAdapter() = default;

virtual std::shared_ptr<T> GetCDM() = 0;

virtual const std::string& GetLicenseUrl() = 0;

virtual void SetCodecInstance(void* instance) {}
virtual void ResetCodecInstance() {}

virtual std::string_view GetKeySystem() = 0;

virtual std::string_view GetLibraryPath() const { return ""; }
//! @todo: add here this method for convenience needed investigate better to better cleanup,
//! also Load/Save certificate methods need a full code cleanup
virtual void SaveServiceCertificate() {}
};

namespace DRM
{

Expand Down
28 changes: 28 additions & 0 deletions src/decrypters/Helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,34 @@ std::vector<std::string> DRM::UrnsToSystemIds(const std::vector<std::string_view
return sids;
}

std::string DRM::KeySystemToDrmName(std::string_view ks)
{
if (ks == KS_WIDEVINE)
return "widevine";
else if (ks == KS_PLAYREADY)
return "playready";
else if (ks == KS_WISEPLAY)
return "wiseplay";
else if (ks == KS_CLEARKEY)
return "clearkey";
else
return "unknown";
}

const uint8_t* DRM::KeySystemToUUID(std::string_view ks)
{
if (ks == KS_WIDEVINE)
return ID_WIDEVINE;
else if (ks == KS_PLAYREADY)
return ID_PLAYREADY;
else if (ks == KS_WISEPLAY)
return ID_WISEPLAY;
else if (ks == KS_CLEARKEY)
return ID_CLEARKEY;
else
return nullptr;
}

bool DRM::IsKeySystemSupported(std::string_view keySystem)
{
return keySystem == DRM::KS_NONE || keySystem == DRM::KS_WIDEVINE ||
Expand Down
8 changes: 8 additions & 0 deletions src/decrypters/Helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@ constexpr uint8_t ID_WIDEVINE[16] = {0xed, 0xef, 0x8b, 0xa9, 0x79, 0xd6, 0x4a, 0
0xa3, 0xc8, 0x27, 0xdc, 0xd5, 0x1d, 0x21, 0xed};
constexpr uint8_t ID_PLAYREADY[16] = {0x9a, 0x04, 0xf0, 0x79, 0x98, 0x40, 0x42, 0x86,
0xab, 0x92, 0xe6, 0x5b, 0xe0, 0x88, 0x5f, 0x95};
constexpr uint8_t ID_WISEPLAY[16] = {0x3d, 0x5e, 0x6d, 0x35, 0x9b, 0x9a, 0x41, 0xe8,
0xb8, 0x43, 0xdd, 0x3c, 0x6e, 0x72, 0xc4, 0x2c};
constexpr uint8_t ID_CLEARKEY[16] = {0xe2, 0x71, 0x9d, 0x58, 0xa9, 0x85, 0xb3, 0xc9,
0x78, 0x1a, 0xb0, 0x30, 0xaf, 0x78, 0xd3, 0x0e};

std::string KeySystemToDrmName(std::string_view ks);

const uint8_t* KeySystemToUUID(std::string_view ks);

bool IsKeySystemSupported(std::string_view keySystem);

Expand Down
18 changes: 6 additions & 12 deletions src/decrypters/IDecrypter.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
#pragma once

#include <cstdint>
#include <memory>
#include <string_view>

#include <kodi/addon-instance/VideoCodec.h>

class Adaptive_CencSingleSampleDecrypter;
class AP4_DataBuffer;
enum class CryptoMode;

namespace DRM
Expand Down Expand Up @@ -85,28 +85,22 @@ class IDecrypter
* \param cryptoMode The crypto/cypher mode to initialise with
* \return The single sample decrypter if successfully created
*/
virtual Adaptive_CencSingleSampleDecrypter* CreateSingleSampleDecrypter(
virtual std::shared_ptr<Adaptive_CencSingleSampleDecrypter> CreateSingleSampleDecrypter(
std::vector<uint8_t>& initData,
std::string_view optionalKeyParameter,
const std::vector<uint8_t>& defaultKeyId,
std::string_view licenseUrl,
bool skipSessionMessage,
CryptoMode cryptoMode) = 0;

/**
* \brief Destroy the decrypter
* \param decrypter The single sample decrypter instance to destroy
*/
virtual void DestroySingleSampleDecrypter(Adaptive_CencSingleSampleDecrypter* decrypter) = 0;

/**
* \brief Determine the capabilities of the decrypter against the supplied media type and KeyID
* \param decrypter The single sample decrypter to use for this check
* \param keyid The KeyID that will be used for this check
* \param media The type of media being decrypted (audio/video)
* \param caps The capabilities object to be populated
*/
virtual void GetCapabilities(Adaptive_CencSingleSampleDecrypter* decrypter,
virtual void GetCapabilities(std::shared_ptr<Adaptive_CencSingleSampleDecrypter> decrypter,
const std::vector<uint8_t>& keyId,
uint32_t media,
DecrypterCapabilites& caps) = 0;
Expand All @@ -117,7 +111,7 @@ class IDecrypter
* \param keyid The KeyID to check for a valid license
* \return True if the KeyID has a license otherwise false
*/
virtual bool HasLicenseKey(Adaptive_CencSingleSampleDecrypter* decrypter,
virtual bool HasLicenseKey(std::shared_ptr<Adaptive_CencSingleSampleDecrypter> decrypter,
const std::vector<uint8_t>& keyId) = 0;

/**
Expand All @@ -131,15 +125,15 @@ class IDecrypter
* \param decrypter The single sample decrypter to use for license challenge
* \return The license data in Base64 format
*/
virtual std::string GetChallengeB64Data(Adaptive_CencSingleSampleDecrypter* decrypter) = 0;
virtual std::string GetChallengeB64Data(std::shared_ptr<Adaptive_CencSingleSampleDecrypter> decrypter) = 0;

/**
* \brief Open VideoCodec for decoding video in a secure pathway to Kodi
* \param decrypter The single sample decrypter to use
* \param initData The data for initialising the codec
* \return True if the decoder was opened successfully otherwise false
*/
virtual bool OpenVideoDecoder(Adaptive_CencSingleSampleDecrypter* decrypter,
virtual bool OpenVideoDecoder(std::shared_ptr<Adaptive_CencSingleSampleDecrypter> decrypter,
const VIDEOCODEC_INITDATA* initData) = 0;

/**
Expand Down
Loading

0 comments on commit f414ddf

Please sign in to comment.