From 84829d74a60f0f4a5d365ac65fda52037a05d969 Mon Sep 17 00:00:00 2001 From: peak3d Date: Thu, 22 Aug 2019 23:03:56 +0200 Subject: [PATCH] [Android] Add some SDK 28 diagnostic features --- wvdecrypter/jni/src/HashMap.cpp | 6 ++++ wvdecrypter/jni/src/HashMap.h | 3 +- wvdecrypter/jni/src/JNIBase.h | 2 +- wvdecrypter/jni/src/MediaDrm.cpp | 47 +++++++++++++++++++++++-- wvdecrypter/jni/src/MediaDrm.h | 5 +++ wvdecrypter/wvdecrypter_android_jni.cpp | 19 ++++++++-- 6 files changed, 76 insertions(+), 6 deletions(-) diff --git a/wvdecrypter/jni/src/HashMap.cpp b/wvdecrypter/jni/src/HashMap.cpp index 8ed8792e4..3ad791bd0 100644 --- a/wvdecrypter/jni/src/HashMap.cpp +++ b/wvdecrypter/jni/src/HashMap.cpp @@ -36,3 +36,9 @@ jhstring CJNIHashMap::put(const jhstring key, const jhstring value) "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", key, value); } + +jhobject CJNIHashMap::entrySet() +{ + return call_method(m_object, + "entrySet", "()Ljava/util/Set;"); +} diff --git a/wvdecrypter/jni/src/HashMap.h b/wvdecrypter/jni/src/HashMap.h index 8b7102573..ba85844e7 100644 --- a/wvdecrypter/jni/src/HashMap.h +++ b/wvdecrypter/jni/src/HashMap.h @@ -31,7 +31,8 @@ class CJNIHashMap : public CJNIBase CJNIHashMap(); virtual ~CJNIHashMap() {} - virtual jhstring put(const jhstring key, const jhstring value); + jhstring put(const jhstring key, const jhstring value); + jhobject entrySet(); }; } diff --git a/wvdecrypter/jni/src/JNIBase.h b/wvdecrypter/jni/src/JNIBase.h index 75e874f3c..f876add7c 100644 --- a/wvdecrypter/jni/src/JNIBase.h +++ b/wvdecrypter/jni/src/JNIBase.h @@ -46,7 +46,7 @@ class CJNIBase CJNIBase(std::string classname); virtual ~CJNIBase(); - const std::string & GetClassName() {return m_className;} + const std::string & GetClassName() const {return m_className;} static const std::string GetDotClassName(const std::string & classname); jni::jhobject m_object; diff --git a/wvdecrypter/jni/src/MediaDrm.cpp b/wvdecrypter/jni/src/MediaDrm.cpp index d6e04e2b1..41dc96a55 100644 --- a/wvdecrypter/jni/src/MediaDrm.cpp +++ b/wvdecrypter/jni/src/MediaDrm.cpp @@ -147,14 +147,12 @@ CJNIMediaDrmProvisionRequest CJNIMediaDrm::getProvisionRequest() const void CJNIMediaDrm::provideProvisionResponse(const std::vector &response) const { - JNIEnv *env = xbmc_jnienv(); call_method(m_object, "provideProvisionResponse", "([B)V", jcast >(response)); } void CJNIMediaDrm::removeKeys(const std::vector &sessionId) const { - JNIEnv *env = xbmc_jnienv(); call_method(m_object, "removeKeys", "([B)V", jcast >(sessionId)); } @@ -165,3 +163,48 @@ void CJNIMediaDrm::setOnEventListener(const CJNIMediaDrmOnEventListener &listene "(Landroid/media/MediaDrm$OnEventListener;)V", listener.get_raw()); } + +std::map CJNIMediaDrm::queryKeyStatus(const std::vector &sessionId) const +{ + if (CJNIBase::GetSDKVersion() >= 23) + { + std::map result; + + CJNIHashMap hashMap = call_method(m_object, + "queryKeyStatus", "([B)Ljava/util/HashMap;", jcast >(sessionId)); + // Get a set with Map.entry from hashmap + jhobject entrySet = hashMap.entrySet(); + // Get the Iterator + jhobject iterator = call_method(entrySet, "iterator", "()Ljava/util/Iterator;"); + while (call_method(iterator, "hasNext", "()Z")) + { + jhobject next = call_method(iterator, "next", "()Ljava/util/Map$Entry;"); + std::string key = jcast(call_method(next, "getKey", "()Ljava/lang/Object;")); + std::string value = jcast(call_method(next, "getValue", "()Ljava/lang/Object;")); + result[key] = value; + } + return result; + } + return std::map(); +} + +int CJNIMediaDrm::getSecurityLevel(const std::vector &sessionId) const +{ + if (CJNIBase::GetSDKVersion() >= 28) + { + return call_method(m_object, + "getSecurityLevel", "([B)I", jcast >(sessionId)); + } + return -1; +} + + +int CJNIMediaDrm::getMaxSecurityLevel() const +{ + if (CJNIBase::GetSDKVersion() >= 28) + { + return call_static_method(GetClassName().c_str(), + "getMaxSecurityLevel", "()I"); + } + return -1; +} diff --git a/wvdecrypter/jni/src/MediaDrm.h b/wvdecrypter/jni/src/MediaDrm.h index 452b02d8c..a322a42db 100644 --- a/wvdecrypter/jni/src/MediaDrm.h +++ b/wvdecrypter/jni/src/MediaDrm.h @@ -68,6 +68,11 @@ class CJNIMediaDrm : public CJNIBase void removeKeys(const std::vector &sessionId) const; void setOnEventListener(const CJNIMediaDrmOnEventListener &listener) const; + + std::map queryKeyStatus(const std::vector &sessionId) const; + + int getSecurityLevel(const std::vector &sessionId) const; + int getMaxSecurityLevel() const; }; } diff --git a/wvdecrypter/wvdecrypter_android_jni.cpp b/wvdecrypter/wvdecrypter_android_jni.cpp index 4ea9e2f6c..058ef2af3 100755 --- a/wvdecrypter/wvdecrypter_android_jni.cpp +++ b/wvdecrypter/wvdecrypter_android_jni.cpp @@ -146,7 +146,7 @@ WV_DRM::WV_DRM(WV_KEYSYSTEM ks, const char* licenseURL, const AP4_DataBuffer &se return; } - std::string strDeviceId = media_drm_->getPropertyString("deviceUniqueId"); + std::vector strDeviceId = media_drm_->getPropertyByteArray("deviceUniqueId"); xbmc_jnienv()->ExceptionClear(); std::string strSecurityLevel = media_drm_->getPropertyString("securityLevel"); xbmc_jnienv()->ExceptionClear(); @@ -172,7 +172,7 @@ WV_DRM::WV_DRM(WV_KEYSYSTEM ks, const char* licenseURL, const AP4_DataBuffer &se } } - Log(SSD_HOST::LL_DEBUG, "Successful instanciated media_drm: %p, deviceid: %s, systemId: %s security-level: %s", media_drm_, strDeviceId.c_str(), strSystemId.c_str(), strSecurityLevel.c_str()); + Log(SSD_HOST::LL_DEBUG, "Successful instanciated deviceUniqueIdSize: %ld,systemId: %s security-level: %s", strDeviceId.size(), strSystemId.c_str(), strSecurityLevel.c_str()); if (license_url_.find('|') == std::string::npos) { @@ -385,6 +385,15 @@ WV_CencSingleSampleDecrypter::WV_CencSingleSampleDecrypter(WV_DRM &drm, AP4_Data if (optionalKeyParameter) optParams_["PRCustomData"] = optionalKeyParameter; + /* + std::vector pui = media_drm_.GetMediaDrm()->getPropertyByteArray("provisioningUniqueId"); + if (pui.size() > 0) + { + std::string encoded = b64_encode(reinterpret_cast(pui.data()), pui.size(), false); + optParams_["CDMID"] = encoded;; + } + */ + RETRY_OPEN: session_id_ = media_drm_.GetMediaDrm()->openSession(); if (xbmc_jnienv()->ExceptionCheck()) @@ -413,6 +422,8 @@ WV_CencSingleSampleDecrypter::WV_CencSingleSampleDecrypter(WV_DRM &drm, AP4_Data memcpy(session_id_char_, session_id_.data(), session_id_.size()); session_id_char_[session_id_.size()] = 0; + + Log(SSD_HOST::LL_DEBUG, "SessionId: %s, SecurityLevel: %d, MaxSecurityLevel: %d", session_id_char_, media_drm_.GetMediaDrm()->getSecurityLevel(session_id_), media_drm_.GetMediaDrm()->getMaxSecurityLevel()); } WV_CencSingleSampleDecrypter::~WV_CencSingleSampleDecrypter() @@ -556,6 +567,10 @@ bool WV_CencSingleSampleDecrypter::KeyUpdateRequest(bool waitKeys) } } Log(SSD_HOST::LL_DEBUG, "License update successful"); + std::map keyStatus = media_drm_.GetMediaDrm()->queryKeyStatus(session_id_); + Log(SSD_HOST::LL_DEBUG, "Key Status (%ld):", keyStatus.size()); + for (auto const& ks : keyStatus) + Log(SSD_HOST::LL_DEBUG, "-> %s -> %s", ks.first.c_str(), ks.second.c_str()); return true; }