diff --git a/libwvdrmengine/Android.mk b/libwvdrmengine/Android.mk index 2b4bb7a8..e7930bfa 100644 --- a/libwvdrmengine/Android.mk +++ b/libwvdrmengine/Android.mk @@ -40,7 +40,7 @@ LOCAL_MODULE_OWNER := widevine include $(BUILD_PREBUILT) # ----------------------------------------------------------------------------- -# Builds android.hardware.drm@1.0-service.widevine +# Builds android.hardware.drm@1.1-service.widevine # include $(CLEAR_VARS) @@ -53,6 +53,7 @@ LOCAL_C_INCLUDES := \ LOCAL_SHARED_LIBRARIES := \ android.hardware.drm@1.0 \ + android.hardware.drm@1.1 \ libbase \ libhidltransport \ libhwbinder \ @@ -64,8 +65,8 @@ LOCAL_SHARED_LIBRARIES := \ LOCAL_HEADER_LIBRARIES := \ libstagefright_foundation_headers -LOCAL_MODULE := android.hardware.drm@1.0-service.widevine -LOCAL_INIT_RC := src_hidl/android.hardware.drm@1.0-service.widevine.rc +LOCAL_MODULE := android.hardware.drm@1.1-service.widevine +LOCAL_INIT_RC := src_hidl/android.hardware.drm@1.1-service.widevine.rc LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/bin/hw LOCAL_PROPRIETARY_MODULE := true LOCAL_MODULE_OWNER := widevine @@ -237,6 +238,7 @@ LOCAL_STATIC_LIBRARIES := \ LOCAL_SHARED_LIBRARIES := \ android.hardware.drm@1.0 \ + android.hardware.drm@1.1 \ android.hidl.memory@1.0 \ libcutils \ libdl \ diff --git a/libwvdrmengine/include_hidl/TypeConvert.h b/libwvdrmengine/include_hidl/TypeConvert.h index dada0b26..7962a900 100644 --- a/libwvdrmengine/include_hidl/TypeConvert.h +++ b/libwvdrmengine/include_hidl/TypeConvert.h @@ -14,8 +14,8 @@ * limitations under the License. */ -#ifndef WVDRM_ANDROID_HARDWARE_DRM_V1_0_TYPECONVERT -#define WVDRM_ANDROID_HARDWARE_DRM_V1_0_TYPECONVERT +#ifndef WVDRM_ANDROID_HARDWARE_DRM_V1_1_TYPECONVERT +#define WVDRM_ANDROID_HARDWARE_DRM_V1_1_TYPECONVERT #include "utils/Errors.h" #include @@ -26,7 +26,7 @@ namespace android { namespace hardware { namespace drm { -namespace V1_0 { +namespace V1_1 { namespace widevine { using ::android::hardware::hidl_array; @@ -71,7 +71,7 @@ template std::vector toVector( } } // namespace widevine -} // namespace V1_0 +} // namespace V1_1 } // namespace drm } // namespace hardware } // namespace android diff --git a/libwvdrmengine/include_hidl/WVCreatePluginFactories.h b/libwvdrmengine/include_hidl/WVCreatePluginFactories.h index 40707074..30e31f9f 100644 --- a/libwvdrmengine/include_hidl/WVCreatePluginFactories.h +++ b/libwvdrmengine/include_hidl/WVCreatePluginFactories.h @@ -5,17 +5,17 @@ #ifndef WV_CREATE_PLUGIN_FACTORIES_H_ #define WV_CREATE_PLUGIN_FACTORIES_H_ -#include -#include +#include +#include namespace wvdrm { namespace hardware { namespace drm { -namespace V1_0 { +namespace V1_1 { namespace widevine { -using ::android::hardware::drm::V1_0::ICryptoFactory; -using ::android::hardware::drm::V1_0::IDrmFactory; +using ::android::hardware::drm::V1_1::ICryptoFactory; +using ::android::hardware::drm::V1_1::IDrmFactory; extern "C" { IDrmFactory* createDrmFactory(); @@ -23,7 +23,7 @@ extern "C" { } } // namespace widevine -} // namespace V1_0 +} // namespace V1_1 } // namespace drm } // namespace hardware } // namespace wvdrm diff --git a/libwvdrmengine/include_hidl/WVCryptoFactory.h b/libwvdrmengine/include_hidl/WVCryptoFactory.h index 73cbae4a..cde6e528 100644 --- a/libwvdrmengine/include_hidl/WVCryptoFactory.h +++ b/libwvdrmengine/include_hidl/WVCryptoFactory.h @@ -5,17 +5,17 @@ #ifndef WV_CRYPTO_FACTORY_H_ #define WV_CRYPTO_FACTORY_H_ -#include +#include #include "WVTypes.h" namespace wvdrm { namespace hardware { namespace drm { -namespace V1_0 { +namespace V1_1 { namespace widevine { -using ::android::hardware::drm::V1_0::ICryptoFactory; +using ::android::hardware::drm::V1_1::ICryptoFactory; using ::android::hardware::drm::V1_0::ICryptoPlugin; using ::android::hardware::hidl_array; using ::android::hardware::hidl_vec; @@ -39,7 +39,7 @@ struct WVCryptoFactory : public ICryptoFactory { }; } // namespace widevine -} // namespace V1_0 +} // namespace V1_1 } // namespace drm } // namespace hardware } // namespace wvdrm diff --git a/libwvdrmengine/include_hidl/WVDrmFactory.h b/libwvdrmengine/include_hidl/WVDrmFactory.h index ddb5530f..5ab7dd3a 100644 --- a/libwvdrmengine/include_hidl/WVDrmFactory.h +++ b/libwvdrmengine/include_hidl/WVDrmFactory.h @@ -5,7 +5,8 @@ #ifndef WV_DRM_FACTORY_H_ #define WV_DRM_FACTORY_H_ -#include +#include +#include #include "WVGenericCryptoInterface.h" #include "WVTypes.h" @@ -13,11 +14,11 @@ namespace wvdrm { namespace hardware { namespace drm { -namespace V1_0 { +namespace V1_1 { namespace widevine { -using ::android::hardware::drm::V1_0::IDrmFactory; -using ::android::hardware::drm::V1_0::IDrmPlugin; +using ::android::hardware::drm::V1_1::IDrmFactory; +using ::android::hardware::drm::V1_1::IDrmPlugin; using ::android::hardware::hidl_array; using ::android::hardware::hidl_string; using ::android::hardware::Return; @@ -50,7 +51,7 @@ struct WVDrmFactory : public IDrmFactory { extern "C" IDrmFactory* HIDL_FETCH_IDrmFactory(const char* name); } // namespace widevine -} // namespace V1_0 +} // namespace V1_1 } // namespace drm } // namespace hardware } // namespace wvdrm diff --git a/libwvdrmengine/mediacrypto/Android.mk b/libwvdrmengine/mediacrypto/Android.mk index eaf6646c..5855cbf1 100644 --- a/libwvdrmengine/mediacrypto/Android.mk +++ b/libwvdrmengine/mediacrypto/Android.mk @@ -64,6 +64,7 @@ LOCAL_STATIC_LIBRARIES := \ LOCAL_SHARED_LIBRARIES := \ android.hardware.drm@1.0 \ + android.hardware.drm@1.1 \ android.hidl.memory@1.0 \ libhidlmemory \ liblog diff --git a/libwvdrmengine/mediacrypto/include_hidl/WVCryptoPlugin.h b/libwvdrmengine/mediacrypto/include_hidl/WVCryptoPlugin.h index 1ea1fd4a..45641e92 100644 --- a/libwvdrmengine/mediacrypto/include_hidl/WVCryptoPlugin.h +++ b/libwvdrmengine/mediacrypto/include_hidl/WVCryptoPlugin.h @@ -14,7 +14,7 @@ namespace wvdrm { namespace hardware { namespace drm { -namespace V1_0 { +namespace V1_1 { namespace widevine { using ::android::hardware::drm::V1_0::DestinationBuffer; @@ -77,7 +77,7 @@ struct WVCryptoPlugin : public ICryptoPlugin { }; } // namespace widevine -} // namespace V1_0 +} // namespace V1_1 } // namespace drm } // namespace hardware } // namespace wvdrm diff --git a/libwvdrmengine/mediacrypto/src_hidl/WVCryptoPlugin.cpp b/libwvdrmengine/mediacrypto/src_hidl/WVCryptoPlugin.cpp index 0ab8795e..0f9efb6e 100644 --- a/libwvdrmengine/mediacrypto/src_hidl/WVCryptoPlugin.cpp +++ b/libwvdrmengine/mediacrypto/src_hidl/WVCryptoPlugin.cpp @@ -26,11 +26,11 @@ static const size_t kAESBlockSize = 16; namespace wvdrm { namespace hardware { namespace drm { -namespace V1_0 { +namespace V1_1 { namespace widevine { using ::android::hardware::drm::V1_0::BufferType; -using ::android::hardware::drm::V1_0::widevine::toVector; +using ::android::hardware::drm::V1_1::widevine::toVector; using ::android::hardware::Void; using wvcdm::CdmDecryptionParameters; @@ -416,7 +416,7 @@ void WVCryptoPlugin::incrementIV(uint64_t increaseBy, } } // namespace widevine -} // namespace V1_0 +} // namespace V1_1 } // namespace drm } // namespace hardware } // namespace wvdrm diff --git a/libwvdrmengine/mediacrypto/test/Android.mk b/libwvdrmengine/mediacrypto/test/Android.mk index 1fba8755..01ea90ea 100644 --- a/libwvdrmengine/mediacrypto/test/Android.mk +++ b/libwvdrmengine/mediacrypto/test/Android.mk @@ -89,6 +89,7 @@ LOCAL_STATIC_LIBRARIES := \ LOCAL_SHARED_LIBRARIES := \ android.hardware.drm@1.0 \ + android.hardware.drm@1.1 \ android.hidl.memory@1.0 \ libbinder \ libcutils \ diff --git a/libwvdrmengine/mediacrypto/test/WVCryptoPlugin_test.cpp b/libwvdrmengine/mediacrypto/test/WVCryptoPlugin_test.cpp index 811e98b5..eea8845e 100644 --- a/libwvdrmengine/mediacrypto/test/WVCryptoPlugin_test.cpp +++ b/libwvdrmengine/mediacrypto/test/WVCryptoPlugin_test.cpp @@ -27,7 +27,7 @@ namespace wvdrm { namespace hardware { namespace drm { -namespace V1_0 { +namespace V1_1 { namespace widevine { using ::android::hardware::drm::V1_0::BufferType; @@ -37,7 +37,7 @@ using ::android::hardware::drm::V1_0::Pattern; using ::android::hardware::drm::V1_0::SharedBuffer; using ::android::hardware::drm::V1_0::Status; using ::android::hardware::drm::V1_0::SubSample; -using ::android::hardware::drm::V1_0::widevine::toHidlVec; +using ::android::hardware::drm::V1_1::widevine::toHidlVec; using ::android::hardware::hidl_array; using ::android::hardware::hidl_handle; using ::android::hardware::hidl_memory; @@ -773,7 +773,7 @@ TEST_F(WVCryptoPluginTest, DisallowsUnopenedSessionIdChanges) { } } // namespace widevine -} // namespace V1_0 +} // namespace V1_1 } // namespace drm } // namespace hardware } // namespace wvdrm diff --git a/libwvdrmengine/mediadrm/Android.mk b/libwvdrmengine/mediadrm/Android.mk index 30141745..e6b40a23 100644 --- a/libwvdrmengine/mediadrm/Android.mk +++ b/libwvdrmengine/mediadrm/Android.mk @@ -65,6 +65,7 @@ LOCAL_STATIC_LIBRARIES := \ LOCAL_SHARED_LIBRARIES := \ android.hardware.drm@1.0 \ + android.hardware.drm@1.1 \ android.hidl.memory@1.0 \ liblog diff --git a/libwvdrmengine/mediadrm/include_hidl/WVDrmPlugin.h b/libwvdrmengine/mediadrm/include_hidl/WVDrmPlugin.h index 057a581c..34f68cad 100644 --- a/libwvdrmengine/mediadrm/include_hidl/WVDrmPlugin.h +++ b/libwvdrmengine/mediadrm/include_hidl/WVDrmPlugin.h @@ -7,8 +7,9 @@ #include -#include +#include #include +#include #include "cdm_client_property_set.h" #include "cdm_identifier.h" @@ -21,22 +22,28 @@ namespace wvdrm { namespace hardware { namespace drm { -namespace V1_0 { +namespace V1_1 { namespace widevine { using ::android::hardware::drm::V1_0::EventType; -using ::android::hardware::drm::V1_0::IDrmPlugin; using ::android::hardware::drm::V1_0::IDrmPluginListener; using ::android::hardware::drm::V1_0::KeyRequestType; using ::android::hardware::drm::V1_0::KeyStatus; using ::android::hardware::drm::V1_0::KeyType; using ::android::hardware::drm::V1_0::KeyValue; using ::android::hardware::drm::V1_0::SecureStop; +using ::android::hardware::drm::V1_0::SecureStopId; using ::android::hardware::drm::V1_0::Status; +using ::android::hardware::drm::V1_1::DrmMetricGroup; +using ::android::hardware::drm::V1_1::HdcpLevel; +using ::android::hardware::drm::V1_1::IDrmPlugin; +using ::android::hardware::drm::V1_1::SecureStopRelease; +using ::android::hardware::drm::V1_1::SecurityLevel; using ::android::hardware::hidl_array; using ::android::hardware::hidl_string; using ::android::hardware::hidl_vec; using ::android::hardware::Return; +using ::android::hardware::Void; using ::android::sp; using std::map; @@ -61,6 +68,8 @@ struct WVDrmPlugin : public IDrmPlugin, IDrmPluginListener, Return openSession(openSession_cb _hidl_cb) override; + Return openSession_1_1(SecurityLevel securityLevel, openSession_1_1_cb _hidl_cb) override; + Return closeSession(const hidl_vec& sessionId) override; Return getKeyRequest( @@ -71,6 +80,14 @@ struct WVDrmPlugin : public IDrmPlugin, IDrmPluginListener, const hidl_vec& optionalParameters, getKeyRequest_cb _hidl_cb) override; + Return getKeyRequest_1_1( + const hidl_vec& scope, + const hidl_vec& initData, + const hidl_string& mimeType, + KeyType keyType, + const hidl_vec& optionalParameters, + getKeyRequest_1_1_cb _hidl_cb) override; + Return provideKeyResponse( const hidl_vec& scope, const hidl_vec& response, @@ -106,6 +123,26 @@ struct WVDrmPlugin : public IDrmPlugin, IDrmPluginListener, Return releaseSecureStop( const hidl_vec& secureStopId) override; + Return getMetrics(getMetrics_cb _hidl_cb) { + _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, hidl_vec()); + return Void(); + } + + Return getSecureStopIds(getSecureStopIds_cb _hidl_cb) override; + + Return releaseSecureStops(const SecureStopRelease& ssRelease) override; + + Return removeSecureStop(const hidl_vec& secureStopId) override; + + Return removeAllSecureStops() override; + + Return getHdcpLevels(getHdcpLevels_cb _hidl_cb) override; + + Return getNumberOfSessions(getNumberOfSessions_cb _hidl_cb) override; + + Return getSecurityLevel(const hidl_vec& sessionId, + getSecurityLevel_cb _hidl_cb) override; + Return getPropertyString( const hidl_string& propertyName, getPropertyString_cb _hidl_cb) override; @@ -370,13 +407,17 @@ struct WVDrmPlugin : public IDrmPlugin, IDrmPluginListener, Status mapOEMCryptoResult(OEMCryptoResult res); + SecurityLevel mapSecurityLevel(const std::string& level); + + Status openSessionCommon(std::vector& sessionId); + bool initDataResemblesPSSH(const std::vector& initData); Status unprovision(const CdmIdentifier& identifier); }; } // namespace widevine -} // namespace V1_0 +} // namespace V1_1 } // namespace drm } // namespace hardware } // namespace wvdrm diff --git a/libwvdrmengine/mediadrm/src_hidl/WVDrmPlugin.cpp b/libwvdrmengine/mediadrm/src_hidl/WVDrmPlugin.cpp index 58d08b7c..2d909850 100644 --- a/libwvdrmengine/mediadrm/src_hidl/WVDrmPlugin.cpp +++ b/libwvdrmengine/mediadrm/src_hidl/WVDrmPlugin.cpp @@ -7,6 +7,7 @@ #include #include +#include #include "WVDrmPlugin.h" #include "TypeConvert.h" @@ -29,7 +30,7 @@ static const char* const kSpecialUnprovisionResponse = "unprovision"; namespace wvdrm { namespace hardware { namespace drm { -namespace V1_0 { +namespace V1_1 { namespace widevine { using ::android::hardware::drm::V1_0::EventType; @@ -37,9 +38,9 @@ using ::android::hardware::drm::V1_0::KeyRequestType; using ::android::hardware::drm::V1_0::KeyStatusType; using ::android::hardware::drm::V1_0::KeyType; using ::android::hardware::drm::V1_0::Status; -using ::android::hardware::drm::V1_0::widevine::toHidlVec; - -using ::android::hardware::drm::V1_0::widevine::toVector; +using ::android::hardware::drm::V1_1::SecurityLevel; +using ::android::hardware::drm::V1_1::widevine::toHidlVec; +using ::android::hardware::drm::V1_1::widevine::toVector; using ::android::hardware::Void; using wvcdm::kDefaultCdmIdentifier; @@ -59,7 +60,6 @@ using wvcdm::CdmSecureStopId; using wvcdm::CdmUsageInfo; using wvcdm::CdmUsageInfoReleaseMessage; using wvcdm::KeyId; -using wvcdm::SecurityLevel; namespace { @@ -98,6 +98,25 @@ KeyStatusType ConvertFromCdmKeyStatus(CdmKeyStatus keyStatus) { } } +HdcpLevel mapHdcpLevel(const std::string level) { + if (level == wvcdm::QUERY_VALUE_HDCP_V1) + return HdcpLevel::HDCP_V1; + else if (level == wvcdm::QUERY_VALUE_HDCP_V2_0) + return HdcpLevel::HDCP_V2; + else if (level == wvcdm::QUERY_VALUE_HDCP_V2_1) + return HdcpLevel::HDCP_V2_1; + else if (level == wvcdm::QUERY_VALUE_HDCP_V2_2) + return HdcpLevel::HDCP_V2_2; + else if (level == wvcdm::QUERY_VALUE_HDCP_NONE) + return HdcpLevel::HDCP_NONE; + else if (level == wvcdm::QUERY_VALUE_HDCP_NO_DIGITAL_OUTPUT) + return HdcpLevel::HDCP_NO_OUTPUT; + else { + ALOGE("Invalid HDCP level=%s", level.c_str()); + return HdcpLevel::HDCP_NONE; + } +} + } // namespace WVDrmPlugin::WVDrmPlugin(const sp& cdm, @@ -122,15 +141,13 @@ WVDrmPlugin::~WVDrmPlugin() { mCryptoSessions.clear(); } -Return WVDrmPlugin::openSession(openSession_cb _hidl_cb) { +Status WVDrmPlugin::openSessionCommon(std::vector& sessionId) { Status status = Status::OK; - std::vector sessionId; CdmIdentifier identifier; status = mCdmIdentifierBuilder.getCdmIdentifier(&identifier); if (status != Status::OK) { - _hidl_cb(status, toHidlVec(sessionId)); - return Void(); + return status; } CdmSessionId cdmSessionId; @@ -140,8 +157,7 @@ Return WVDrmPlugin::openSession(openSession_cb _hidl_cb) { if (!isCdmResponseTypeSuccess(res)) { status = mapAndNotifyOfCdmResponseType(sessionId, res); - _hidl_cb(status, toHidlVec(sessionId)); - return Void(); + return status; } bool success = false; @@ -164,8 +180,7 @@ Return WVDrmPlugin::openSession(openSession_cb _hidl_cb) { if (success) { // Marshal Session ID sessionId = StrToVector(cdmSessionId); - _hidl_cb(Status::OK, toHidlVec(sessionId)); - return Void(); + return Status::OK; } else { mCDM->CloseSession(cdmSessionId); @@ -179,6 +194,79 @@ Return WVDrmPlugin::openSession(openSession_cb _hidl_cb) { status = Status::ERROR_DRM_UNKNOWN; } } + + return status; +} + +Return WVDrmPlugin::openSession(openSession_cb _hidl_cb) { + std::vector sessionId; + Status status = openSessionCommon(sessionId); + + _hidl_cb(status, toHidlVec(sessionId)); + return Void(); +} + +SecurityLevel WVDrmPlugin::mapSecurityLevel(const std::string& level) { + SecurityLevel hSecurityLevel = SecurityLevel::UNKNOWN; + + if (wvcdm::QUERY_VALUE_SECURITY_LEVEL_L1 == level) { + hSecurityLevel = SecurityLevel::HW_SECURE_ALL; + } else if (wvcdm::QUERY_VALUE_SECURITY_LEVEL_L2 == level) { + hSecurityLevel = SecurityLevel::HW_SECURE_CRYPTO; + } else if (wvcdm::QUERY_VALUE_SECURITY_LEVEL_L3 == level) { + hSecurityLevel = SecurityLevel::SW_SECURE_CRYPTO; + } // else QUERY_VALUE_SECURITY_LEVEL_UNKNOWN returns Security::UNKNOWN + + return hSecurityLevel; +} + +Return WVDrmPlugin::openSession_1_1( + SecurityLevel requestedLevel, + openSession_1_1_cb _hidl_cb) { + std::vector sessionId; + sessionId.clear(); + + if (SecurityLevel::UNKNOWN == requestedLevel) { + _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, toHidlVec(sessionId)); + return Void(); + } + + std::string native_security_level; + Status status = queryProperty(wvcdm::kLevelDefault, + wvcdm::QUERY_KEY_SECURITY_LEVEL, native_security_level); + if (Status::OK != status) { + _hidl_cb(status, toHidlVec(sessionId)); + return Void(); + } + + if (wvcdm::QUERY_VALUE_SECURITY_LEVEL_L3 == native_security_level && + requestedLevel >= SecurityLevel::SW_SECURE_DECODE) { + _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, toHidlVec(sessionId)); + return Void(); + } + + std::string wvcdm_security_level = + (SecurityLevel::SW_SECURE_CRYPTO == requestedLevel) ? + wvcdm::QUERY_VALUE_SECURITY_LEVEL_L3 : wvcdm::QUERY_VALUE_SECURITY_LEVEL_DEFAULT; + + setPropertyString(hidl_string(wvcdm::QUERY_KEY_SECURITY_LEVEL), + hidl_string(wvcdm_security_level)); + + status = openSessionCommon(sessionId); + hidl_vec hSessionId = toHidlVec(sessionId); + if (Status::OK == status) { + Return hResult = getSecurityLevel(hSessionId, [&](Status status, SecurityLevel hSecurityLevel) { + if (Status::OK != status || requestedLevel != hSecurityLevel) { + ALOGE("Failed to open session with the requested security level=%d", requestedLevel); + if (Status::OK != closeSession(hSessionId)) sessionId.clear(); + } + }); + if (!hResult.isOk()) { + status = Status::ERROR_DRM_INVALID_STATE; + ALOGE("openSession_1_1 fails communication with the remote HAL"); + } + } + _hidl_cb(status, toHidlVec(sessionId)); return Void(); } @@ -319,6 +407,38 @@ Return WVDrmPlugin::getKeyRequest( return Void(); } +Return WVDrmPlugin::getKeyRequest_1_1( + const hidl_vec& scope, + const hidl_vec& initData, + const hidl_string& mimeType, + KeyType keyType, + const hidl_vec& optionalParameters, + getKeyRequest_1_1_cb _hidl_cb) { + hidl_string defaultUrl; + hidl_vec request; + ::android::hardware::drm::V1_1::KeyRequestType requestType = + static_cast<::android::hardware::drm::V1_1::KeyRequestType>(KeyRequestType::UNKNOWN); + Status status = Status::ERROR_DRM_UNKNOWN; + + defaultUrl.clear(); + Return hResult = getKeyRequest(scope, initData, mimeType, keyType, optionalParameters, + [&](Status statusCode, const hidl_vec& hRequest, + KeyRequestType hKeyRequestType, + const hidl_string& hDefaultUrl) { + defaultUrl = hDefaultUrl; + request = hRequest; + requestType = static_cast<::android::hardware::drm::V1_1::KeyRequestType>(hKeyRequestType); + status = statusCode; + }); + if (!hResult.isOk()) { + status = Status::ERROR_DRM_INVALID_STATE; + ALOGE("getKeyRequest_1_1 fails communication with the remote HAL"); + } + + _hidl_cb(status, request, requestType, defaultUrl); + return Void(); +} + Return WVDrmPlugin::provideKeyResponse( const hidl_vec& scope, const hidl_vec& response, @@ -602,16 +722,7 @@ Return WVDrmPlugin::getSecureStops(getSecureStops_cb _hidl_cb) { } Return WVDrmPlugin::releaseAllSecureStops() { - - CdmIdentifier identifier; - Status status = mCdmIdentifierBuilder.getCdmIdentifier(&identifier); - if (status != Status::OK) { - return status; - } - - CdmResponseType res = mCDM->RemoveAllUsageInfo(mPropertySet.app_id(), - identifier); - return mapCdmResponseType(res); + return removeAllSecureStops(); } Return WVDrmPlugin::releaseSecureStop( @@ -633,6 +744,158 @@ Return WVDrmPlugin::releaseSecureStop( return mapCdmResponseType(res); } +Return WVDrmPlugin::getSecureStopIds(getSecureStopIds_cb _hidl_cb) { + + std::vector secureStopIds; + + CdmIdentifier identifier; + Status status = mCdmIdentifierBuilder.getCdmIdentifier(&identifier); + if (status != Status::OK) { + _hidl_cb(status, toHidlVec(secureStopIds)); + return Void(); + } + + std::vector ssids; + CdmResponseType res = + mCDM->GetSecureStopIds(mPropertySet.app_id(), identifier, &ssids); + + if (isCdmResponseTypeSuccess(res)) { + for (auto itr = ssids.begin(); itr != ssids.end(); ++itr) { + const CdmSecureStopId& ssid = *itr; + secureStopIds.push_back(StrToVector(ssid)); + } + } + + _hidl_cb(mapCdmResponseType(res), toHidlVec(secureStopIds)); + return Void(); +} + +Return WVDrmPlugin::releaseSecureStops(const SecureStopRelease& ssRelease) { + + if (ssRelease.opaqueData.size() == 0) { + return Status::BAD_VALUE; + } + + CdmIdentifier identifier; + Status status = mCdmIdentifierBuilder.getCdmIdentifier(&identifier); + if (status != Status::OK) { + return status; + } + + const std::vector data = toVector(ssRelease.opaqueData); + CdmUsageInfoReleaseMessage cdmMessage(data.begin(), data.end()); + CdmResponseType res = mCDM->ReleaseUsageInfo(cdmMessage, identifier); + return mapCdmResponseType(res); +} + +Return WVDrmPlugin::removeSecureStop(const hidl_vec& secureStopId) { + if (!secureStopId.size()) { + return Status::BAD_VALUE; + } + + CdmIdentifier identifier; + Status status = mCdmIdentifierBuilder.getCdmIdentifier(&identifier); + if (status != Status::OK) { + return status; + } + + const std::vector idVec = toVector(secureStopId); + CdmSecureStopId id(idVec.begin(), idVec.end()); + CdmResponseType res = mCDM->RemoveUsageInfo(mPropertySet.app_id(), identifier, id); + return mapCdmResponseType(res); +} + +Return WVDrmPlugin::removeAllSecureStops() { + CdmIdentifier identifier; + Status status = mCdmIdentifierBuilder.getCdmIdentifier(&identifier); + if (status != Status::OK) { + return status; + } + + CdmResponseType res = mCDM->RemoveAllUsageInfo(mPropertySet.app_id(), + identifier); + return mapCdmResponseType(res); +} + +Return WVDrmPlugin::getHdcpLevels(getHdcpLevels_cb _hidl_cb) { + HdcpLevel connectedLevel = HdcpLevel::HDCP_NONE; + HdcpLevel maxLevel = HdcpLevel::HDCP_NO_OUTPUT; + + std::string level; + Status status = queryProperty(wvcdm::QUERY_KEY_CURRENT_HDCP_LEVEL, level); + if (status == Status::OK) { + connectedLevel = mapHdcpLevel(level); + } else { + ALOGE("Failed to query current hdcp level."); + _hidl_cb(Status::ERROR_DRM_INVALID_STATE, connectedLevel, maxLevel); + return Void(); + } + + status = queryProperty(wvcdm::QUERY_KEY_MAX_HDCP_LEVEL, level); + if (status == Status::OK) { + maxLevel = mapHdcpLevel(level); + } else { + ALOGE("Failed to query maximum hdcp level."); + _hidl_cb(Status::ERROR_DRM_INVALID_STATE, connectedLevel, maxLevel); + return Void(); + } + + _hidl_cb(Status::OK, connectedLevel, maxLevel); + return Void(); +} + +Return WVDrmPlugin::getNumberOfSessions(getNumberOfSessions_cb _hidl_cb) { + uint32_t currentSessions = 0; + uint32_t maxSessions = 1; + + std::string value; + Status status = queryProperty(wvcdm::QUERY_KEY_NUMBER_OF_OPEN_SESSIONS, value); + if (status == Status::OK) { + currentSessions = std::strtoul(value.c_str(), nullptr, 10); + } else { + ALOGE("Failed to query currently opened sessions."); + _hidl_cb(Status::ERROR_DRM_INVALID_STATE, currentSessions, maxSessions); + return Void(); + } + + status = queryProperty(wvcdm::QUERY_KEY_MAX_NUMBER_OF_SESSIONS, value); + if (status == Status::OK) { + maxSessions = std::strtoul(value.c_str(), nullptr, 10); + } else { + ALOGE("Failed to query maximum number of sessions that the device can support."); + _hidl_cb(Status::ERROR_DRM_INVALID_STATE, currentSessions, maxSessions); + return Void(); + } + + _hidl_cb(Status::OK, currentSessions, maxSessions); + return Void(); +} + +Return WVDrmPlugin::getSecurityLevel( + const hidl_vec& sessionId, + getSecurityLevel_cb _hidl_cb) { + if (sessionId.size() == 0) { + _hidl_cb(Status::BAD_VALUE, SecurityLevel::UNKNOWN); + return Void(); + } + + std::vector sid = toVector(sessionId); + CdmQueryMap info; + SecurityLevel hSecurityLevel = SecurityLevel::UNKNOWN; + + CdmResponseType status = mCDM->QuerySessionStatus( + std::string(sid.begin(), sid.end()), &info); + if (wvcdm::NO_ERROR == status) { + std::string level = info[wvcdm::QUERY_KEY_SECURITY_LEVEL]; + hSecurityLevel = mapSecurityLevel(level); + } else { + ALOGE("Failed to query security level, status=%d", status); + } + + _hidl_cb(mapCdmResponseType(status), hSecurityLevel); + return Void(); +} + Return WVDrmPlugin::getPropertyString(const hidl_string& propertyName, getPropertyString_cb _hidl_cb) { Status status = Status::OK; @@ -757,7 +1020,8 @@ Return WVDrmPlugin::setPropertyString(const hidl_string& propertyName, } else { mPropertySet.set_security_level(kResetSecurityLevel); } - } else if (_value == kResetSecurityLevel) { + } else if (_value == kResetSecurityLevel || + _value == wvcdm::QUERY_VALUE_SECURITY_LEVEL_DEFAULT) { mPropertySet.set_security_level(kResetSecurityLevel); } else { ALOGE("App requested invalid security level %s", _value.c_str()); @@ -1245,7 +1509,7 @@ void WVDrmPlugin::OnExpirationUpdate(const CdmSessionId& cdmSessionId, Status WVDrmPlugin::queryProperty(const std::string& property, std::string& stringValue) const { - SecurityLevel securityLevel = + wvcdm::SecurityLevel securityLevel = mPropertySet.security_level().compare( wvcdm::QUERY_VALUE_SECURITY_LEVEL_L3) == 0 ? wvcdm::kLevel3 @@ -1253,7 +1517,7 @@ Status WVDrmPlugin::queryProperty(const std::string& property, return queryProperty(securityLevel, property, stringValue); } -Status WVDrmPlugin::queryProperty(SecurityLevel securityLevel, +Status WVDrmPlugin::queryProperty(wvcdm::SecurityLevel securityLevel, const std::string& property, std::string& stringValue) const { CdmResponseType res = @@ -1454,7 +1718,7 @@ Status WVDrmPlugin::CdmIdentifierBuilder::getOemcryptoDeviceId( } } // namespace widevine -} // namespace V1_0 +} // namespace V1_1 } // namespace drm } // namespace hardware } // namespace wvdrm diff --git a/libwvdrmengine/mediadrm/test/Android.mk b/libwvdrmengine/mediadrm/test/Android.mk index 874698d9..c5bc46b0 100644 --- a/libwvdrmengine/mediadrm/test/Android.mk +++ b/libwvdrmengine/mediadrm/test/Android.mk @@ -90,6 +90,7 @@ LOCAL_STATIC_LIBRARIES := \ LOCAL_SHARED_LIBRARIES := \ android.hardware.drm@1.0 \ + android.hardware.drm@1.1 \ android.hidl.memory@1.0 \ libbinder \ libcutils \ diff --git a/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp b/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp index b20edf2d..3876f1f0 100644 --- a/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp +++ b/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp @@ -5,9 +5,9 @@ #define LOG_TAG "WVDrmPluginTest" #include -#include -#include #include +#include +#include #include #include @@ -30,14 +30,14 @@ namespace wvdrm { namespace hardware { namespace drm { -namespace V1_0 { +namespace V1_1 { namespace widevine { using ::android::hardware::drm::V1_0::EventType; using ::android::hardware::drm::V1_0::KeyStatus; using ::android::hardware::drm::V1_0::KeyStatusType; using ::android::hardware::drm::V1_0::Status; -using ::android::hardware::drm::V1_0::widevine::toHidlVec; +using ::android::hardware::drm::V1_1::widevine::toHidlVec; using ::android::hardware::hidl_vec; using ::testing::_; @@ -55,6 +55,7 @@ using ::testing::NotNull; using ::testing::Pointee; using ::testing::SaveArg; using ::testing::SetArgPointee; +using ::testing::SetArrayArgument; using ::testing::StrictMock; using ::testing::StrEq; using ::testing::Test; @@ -107,7 +108,6 @@ using wvcdm::QUERY_KEY_SYSTEM_ID; using wvcdm::QUERY_KEY_WVCDM_VERSION; using wvcdm::QUERY_VALUE_SECURITY_LEVEL_L1; using wvcdm::QUERY_VALUE_SECURITY_LEVEL_L3; -using wvcdm::SecurityLevel; using wvcdm::SESSION_ID_PREFIX; using wvcdm::WvCdmEventListener; @@ -159,7 +159,7 @@ class MockCDM : public WvContentDecryptionModule { MOCK_METHOD2(RestoreKey, CdmResponseType(const CdmSessionId&, const CdmKeySetId&)); - MOCK_METHOD3(QueryStatus, CdmResponseType(SecurityLevel, const std::string&, + MOCK_METHOD3(QueryStatus, CdmResponseType(wvcdm::SecurityLevel, const std::string&, std::string*)); MOCK_METHOD2(QueryKeyStatus, CdmResponseType(const CdmSessionId&, @@ -309,7 +309,7 @@ TEST_F(WVDrmPluginTest, OpensSessions) { .WillOnce(DoAll(SetArgPointee<4>(cdmSessionId), testing::Return(wvcdm::NO_ERROR))); - // Provide expected behavior when plugin requests session control info + // Provide expected mock behavior EXPECT_CALL(*cdm, QueryOemCryptoSessionId(cdmSessionId, _)) .Times(AtLeast(1)) .WillRepeatedly(Invoke(setSessionIdOnMap<4>)); @@ -326,6 +326,51 @@ TEST_F(WVDrmPluginTest, OpensSessions) { }); EXPECT_THAT(sessionId, ElementsAreArray(sessionIdRaw, kSessionIdSize)); + Status status = plugin.closeSession(toHidlVec(sessionId)); + ASSERT_EQ(Status::OK, status); +} + +TEST_F(WVDrmPluginTest, OpensSessions_1_1) { + android::sp> cdm = new StrictMock(); + StrictMock crypto; + std::string appPackageName; + + const CdmClientPropertySet* propertySet = NULL; + + // Provide expected mock behavior + EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_SECURITY_LEVEL, _)) + .WillOnce(DoAll(SetArgPointee<2>(QUERY_VALUE_SECURITY_LEVEL_L1), + testing::Return(wvcdm::NO_ERROR))) + .WillOnce(DoAll(SetArgPointee<2>(QUERY_VALUE_SECURITY_LEVEL_L3), + testing::Return(wvcdm::NO_ERROR))); + + EXPECT_CALL(*cdm, OpenSession(_, _, _, _, _)) + .WillRepeatedly(DoAll(SetArgPointee<4>(cdmSessionId), + SaveArg<1>(&propertySet), + testing::Return(wvcdm::NO_ERROR))); + + EXPECT_CALL(*cdm, QueryOemCryptoSessionId(cdmSessionId, _)) + .WillRepeatedly(Invoke(setSessionIdOnMap<4>)); + + EXPECT_CALL(*cdm, CloseSession(_)) + .Times(AtLeast(0)); + + WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); + + Status status = plugin.setPropertyString(hidl_string("securityLevel"), hidl_string("L1")); + ASSERT_EQ(Status::OK, status); + + plugin.openSession_1_1(android::hardware::drm::V1_1::SecurityLevel::SW_SECURE_CRYPTO, + [&](Status status, hidl_vec hSessionId) { + ASSERT_EQ(Status::OK, status); + sessionId.clear(); + sessionId.assign(hSessionId.data(), hSessionId.data() + hSessionId.size()); + }); + + ASSERT_THAT(propertySet, NotNull()); + EXPECT_THAT(sessionId, ElementsAreArray(sessionIdRaw, kSessionIdSize)); + status = plugin.closeSession(toHidlVec(sessionId)); + ASSERT_EQ(Status::OK, status); } TEST_F(WVDrmPluginTest, ClosesSessions) { @@ -2453,7 +2498,7 @@ TEST_F(WVDrmPluginTest, AllowsStoringOfSessionSharingId) { } } // namespace widevine -} // namespace V1_0 +} // namespace V1_1 } // namespace drm } // namespace hardware } // namespace wvdrm diff --git a/libwvdrmengine/src_hidl/WVCreatePluginFactories.cpp b/libwvdrmengine/src_hidl/WVCreatePluginFactories.cpp index 9bfd6be6..a4da8d7b 100644 --- a/libwvdrmengine/src_hidl/WVCreatePluginFactories.cpp +++ b/libwvdrmengine/src_hidl/WVCreatePluginFactories.cpp @@ -10,7 +10,7 @@ namespace wvdrm { namespace hardware { namespace drm { -namespace V1_0 { +namespace V1_1 { namespace widevine { extern "C" { @@ -25,7 +25,7 @@ ICryptoFactory* createCryptoFactory() { } // extern "C" } // namespace widevine -} // namespace V1_0 +} // namespace V1_1 } // namespace drm } // namespace hardware } // namespace wvdrm diff --git a/libwvdrmengine/src_hidl/WVCryptoFactory.cpp b/libwvdrmengine/src_hidl/WVCryptoFactory.cpp index f042ecf8..a98bd3e2 100644 --- a/libwvdrmengine/src_hidl/WVCryptoFactory.cpp +++ b/libwvdrmengine/src_hidl/WVCryptoFactory.cpp @@ -14,7 +14,7 @@ namespace wvdrm { namespace hardware { namespace drm { -namespace V1_0 { +namespace V1_1 { namespace widevine { using ::android::hardware::drm::V1_0::Status; @@ -44,7 +44,7 @@ Return WVCryptoFactory::createPlugin( } } // namespace widevine -} // namespace V1_0 +} // namespace V1_1 } // namespace drm } // namespace hardware } // namespace wvdrm diff --git a/libwvdrmengine/src_hidl/WVDrmFactory.cpp b/libwvdrmengine/src_hidl/WVDrmFactory.cpp index 533e0d90..a93d294d 100644 --- a/libwvdrmengine/src_hidl/WVDrmFactory.cpp +++ b/libwvdrmengine/src_hidl/WVDrmFactory.cpp @@ -18,7 +18,7 @@ namespace wvdrm { namespace hardware { namespace drm { -namespace V1_0 { +namespace V1_1 { namespace widevine { using ::android::hardware::drm::V1_0::Status; @@ -68,7 +68,7 @@ bool WVDrmFactory::areSpoidsEnabled() { } // namespace widevine -} // namespace V1_0 +} // namespace V1_1 } // namespace drm } // namespace hardware } // namespace wvdrm diff --git a/libwvdrmengine/src_hidl/android.hardware.drm@1.0-service.widevine.rc b/libwvdrmengine/src_hidl/android.hardware.drm@1.1-service.widevine.rc similarity index 80% rename from libwvdrmengine/src_hidl/android.hardware.drm@1.0-service.widevine.rc rename to libwvdrmengine/src_hidl/android.hardware.drm@1.1-service.widevine.rc index f4328932..eb31f5c4 100644 --- a/libwvdrmengine/src_hidl/android.hardware.drm@1.0-service.widevine.rc +++ b/libwvdrmengine/src_hidl/android.hardware.drm@1.1-service.widevine.rc @@ -9,7 +9,7 @@ service vendor.move_data_sh /system/bin/move_widevine_data.sh disabled oneshot -service vendor.drm-widevine-hal-1-0 /vendor/bin/hw/android.hardware.drm@1.0-service.widevine +service vendor.drm-widevine-hal-1-1 /vendor/bin/hw/android.hardware.drm@1.1-service.widevine class hal user media group media mediadrm drmrpc diff --git a/libwvdrmengine/src_hidl/service.cpp b/libwvdrmengine/src_hidl/service.cpp index 276914fc..431aeec0 100644 --- a/libwvdrmengine/src_hidl/service.cpp +++ b/libwvdrmengine/src_hidl/service.cpp @@ -27,13 +27,13 @@ using ::android::hardware::configureRpcThreadpool; using ::android::hardware::joinRpcThreadpool; using ::android::sp; -using android::hardware::drm::V1_0::ICryptoFactory; -using android::hardware::drm::V1_0::IDrmFactory; -using wvdrm::hardware::drm::V1_0::widevine::WVCryptoFactory; -using wvdrm::hardware::drm::V1_0::widevine::WVDrmFactory; +using android::hardware::drm::V1_1::ICryptoFactory; +using android::hardware::drm::V1_1::IDrmFactory; +using wvdrm::hardware::drm::V1_1::widevine::WVCryptoFactory; +using wvdrm::hardware::drm::V1_1::widevine::WVDrmFactory; int main(int /* argc */, char** /* argv */) { - ALOGD("android.hardware.drm@1.0-service.widevine starting..."); + ALOGD("android.hardware.drm@1.1-service.widevine starting..."); // The DRM HAL may communicate to other vendor components via // /dev/vndbinder diff --git a/libwvdrmengine/test/unit/Android.mk b/libwvdrmengine/test/unit/Android.mk index fced9690..1dee6514 100644 --- a/libwvdrmengine/test/unit/Android.mk +++ b/libwvdrmengine/test/unit/Android.mk @@ -70,6 +70,7 @@ LOCAL_STATIC_LIBRARIES := \ LOCAL_SHARED_LIBRARIES := \ android.hardware.drm@1.0 \ + android.hardware.drm@1.1 \ libcutils \ libdl \ libhidlbase \ diff --git a/libwvdrmengine/test/unit/WVCreatePluginFactories_test.cpp b/libwvdrmengine/test/unit/WVCreatePluginFactories_test.cpp index 09d13570..2bcc6cdb 100644 --- a/libwvdrmengine/test/unit/WVCreatePluginFactories_test.cpp +++ b/libwvdrmengine/test/unit/WVCreatePluginFactories_test.cpp @@ -8,7 +8,7 @@ namespace wvdrm { namespace hardware { namespace drm { -namespace V1_0 { +namespace V1_1 { namespace widevine { using ::android::sp; @@ -30,7 +30,7 @@ TEST(CreatePluginFactoriesTest, CreatesCryptoFactory) { } } // namespace widevine -} // namespace V1_0 +} // namespace V1_1 } // namespace drm } // namespace hardware } // namespace wvdrm diff --git a/libwvdrmengine/test/unit/WVCryptoFactory_test.cpp b/libwvdrmengine/test/unit/WVCryptoFactory_test.cpp index a91c1751..ebee4c13 100644 --- a/libwvdrmengine/test/unit/WVCryptoFactory_test.cpp +++ b/libwvdrmengine/test/unit/WVCryptoFactory_test.cpp @@ -8,10 +8,10 @@ namespace wvdrm { namespace hardware { namespace drm { -namespace V1_0 { +namespace V1_1 { namespace widevine { -using wvdrm::hardware::drm::V1_0::widevine::WVCryptoFactory; +using wvdrm::hardware::drm::V1_1::widevine::WVCryptoFactory; using ::android::sp; const uint8_t kWidevineUUID[16] = { @@ -47,7 +47,7 @@ TEST(WVCryptoFactoryTest, DoesNotSupportUnsupportedCryptoSchemes) { } } // namespace widevine -} // namespace V1_0 +} // namespace V1_1 } // namespace drm } // namespace hardware } // namespace wvdrm diff --git a/libwvdrmengine/test/unit/WVDrmFactory_test.cpp b/libwvdrmengine/test/unit/WVDrmFactory_test.cpp index 52fa2bad..eaf65f74 100644 --- a/libwvdrmengine/test/unit/WVDrmFactory_test.cpp +++ b/libwvdrmengine/test/unit/WVDrmFactory_test.cpp @@ -10,11 +10,11 @@ namespace wvdrm { namespace hardware { namespace drm { -namespace V1_0 { +namespace V1_1 { namespace widevine { using ::android::hardware::hidl_string; -using wvdrm::hardware::drm::V1_0::widevine::WVDrmFactory; +using wvdrm::hardware::drm::V1_1::widevine::WVDrmFactory; using namespace android; @@ -111,7 +111,7 @@ TEST(WVDrmFactoryTest, CalculatesSpoidUseCorrectly) { } } // namespace widevine -} // namespace V1_0 +} // namespace V1_1 } // namespace drm } // namespace hardware } // namespace wvdrm