Upgrade widevine HIDL service to v1.1.

Merged from http://go/wvgerrit/44803.

Upgrade HIDL service to v1.1 and implements new 1.1 media API.

Test: Netflix and Play Movies & TV
  streaming and offline playback

Test: GTS WidevineH264PlaybackTests test
  e.g. ANDROID_BUILD_TOP= ./android-gts/tools/gts-tradefed run gts -m GtsMediaTestCases
  --test com.google.android.media.gts.WidevineH264PlaybackTests#testL1With480P30

Test: GTS MediaDrmTest tests
  e.g. ANDROID_BUILD_TOP= ./android-gts/tools/gts-tradefed run gts -m GtsMediaTestCases
  --test com.google.android.media.gts.MediaDrmTest#testWidevineApi28

Test: unit tests

bug: 69674645
Change-Id: I91e7e43f9178b61a531e846beffb5f5c17050a3c
This commit is contained in:
Edwin Wong
2018-02-06 10:53:10 -08:00
parent efc008c5a1
commit bc66aebfe2
24 changed files with 447 additions and 89 deletions

View File

@@ -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 \

View File

@@ -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 <vector>
@@ -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<typename T, size_t SIZE> std::vector<T> toVector(
}
} // namespace widevine
} // namespace V1_0
} // namespace V1_1
} // namespace drm
} // namespace hardware
} // namespace android

View File

@@ -5,17 +5,17 @@
#ifndef WV_CREATE_PLUGIN_FACTORIES_H_
#define WV_CREATE_PLUGIN_FACTORIES_H_
#include <android/hardware/drm/1.0/ICryptoFactory.h>
#include <android/hardware/drm/1.0/IDrmFactory.h>
#include <android/hardware/drm/1.1/ICryptoFactory.h>
#include <android/hardware/drm/1.1/IDrmFactory.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_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

View File

@@ -5,17 +5,17 @@
#ifndef WV_CRYPTO_FACTORY_H_
#define WV_CRYPTO_FACTORY_H_
#include <android/hardware/drm/1.0/ICryptoFactory.h>
#include <android/hardware/drm/1.1/ICryptoFactory.h>
#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

View File

@@ -5,7 +5,8 @@
#ifndef WV_DRM_FACTORY_H_
#define WV_DRM_FACTORY_H_
#include <android/hardware/drm/1.0/IDrmFactory.h>
#include <android/hardware/drm/1.1/IDrmFactory.h>
#include <android/hardware/drm/1.1/IDrmPlugin.h>
#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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 \

View File

@@ -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

View File

@@ -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

View File

@@ -7,8 +7,9 @@
#include <map>
#include <android/hardware/drm/1.0/IDrmPlugin.h>
#include <android/hardware/drm/1.1/IDrmPlugin.h>
#include <android/hardware/drm/1.0/IDrmPluginListener.h>
#include <android/hardware/drm/1.1/types.h>
#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<void> openSession(openSession_cb _hidl_cb) override;
Return<void> openSession_1_1(SecurityLevel securityLevel, openSession_1_1_cb _hidl_cb) override;
Return<Status> closeSession(const hidl_vec<uint8_t>& sessionId) override;
Return<void> getKeyRequest(
@@ -71,6 +80,14 @@ struct WVDrmPlugin : public IDrmPlugin, IDrmPluginListener,
const hidl_vec<KeyValue>& optionalParameters,
getKeyRequest_cb _hidl_cb) override;
Return<void> getKeyRequest_1_1(
const hidl_vec<uint8_t>& scope,
const hidl_vec<uint8_t>& initData,
const hidl_string& mimeType,
KeyType keyType,
const hidl_vec<KeyValue>& optionalParameters,
getKeyRequest_1_1_cb _hidl_cb) override;
Return<void> provideKeyResponse(
const hidl_vec<uint8_t>& scope,
const hidl_vec<uint8_t>& response,
@@ -106,6 +123,26 @@ struct WVDrmPlugin : public IDrmPlugin, IDrmPluginListener,
Return<Status> releaseSecureStop(
const hidl_vec<uint8_t>& secureStopId) override;
Return<void> getMetrics(getMetrics_cb _hidl_cb) {
_hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, hidl_vec<DrmMetricGroup>());
return Void();
}
Return<void> getSecureStopIds(getSecureStopIds_cb _hidl_cb) override;
Return<Status> releaseSecureStops(const SecureStopRelease& ssRelease) override;
Return<Status> removeSecureStop(const hidl_vec<uint8_t>& secureStopId) override;
Return<Status> removeAllSecureStops() override;
Return<void> getHdcpLevels(getHdcpLevels_cb _hidl_cb) override;
Return<void> getNumberOfSessions(getNumberOfSessions_cb _hidl_cb) override;
Return<void> getSecurityLevel(const hidl_vec<uint8_t>& sessionId,
getSecurityLevel_cb _hidl_cb) override;
Return<void> 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<uint8_t>& sessionId);
bool initDataResemblesPSSH(const std::vector<uint8_t>& initData);
Status unprovision(const CdmIdentifier& identifier);
};
} // namespace widevine
} // namespace V1_0
} // namespace V1_1
} // namespace drm
} // namespace hardware
} // namespace wvdrm

View File

@@ -7,6 +7,7 @@
#include <utils/Log.h>
#include <list>
#include <stdlib.h>
#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<WvContentDecryptionModule>& cdm,
@@ -122,15 +141,13 @@ WVDrmPlugin::~WVDrmPlugin() {
mCryptoSessions.clear();
}
Return<void> WVDrmPlugin::openSession(openSession_cb _hidl_cb) {
Status WVDrmPlugin::openSessionCommon(std::vector<uint8_t>& sessionId) {
Status status = Status::OK;
std::vector<uint8_t> 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<void> 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<void> 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<void> WVDrmPlugin::openSession(openSession_cb _hidl_cb) {
status = Status::ERROR_DRM_UNKNOWN;
}
}
return status;
}
Return<void> WVDrmPlugin::openSession(openSession_cb _hidl_cb) {
std::vector<uint8_t> 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<void> WVDrmPlugin::openSession_1_1(
SecurityLevel requestedLevel,
openSession_1_1_cb _hidl_cb) {
std::vector<uint8_t> 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<uint8_t> hSessionId = toHidlVec(sessionId);
if (Status::OK == status) {
Return<void> 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<void> WVDrmPlugin::getKeyRequest(
return Void();
}
Return<void> WVDrmPlugin::getKeyRequest_1_1(
const hidl_vec<uint8_t>& scope,
const hidl_vec<uint8_t>& initData,
const hidl_string& mimeType,
KeyType keyType,
const hidl_vec<KeyValue>& optionalParameters,
getKeyRequest_1_1_cb _hidl_cb) {
hidl_string defaultUrl;
hidl_vec<uint8_t> 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<void> hResult = getKeyRequest(scope, initData, mimeType, keyType, optionalParameters,
[&](Status statusCode, const hidl_vec<uint8_t>& 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<void> WVDrmPlugin::provideKeyResponse(
const hidl_vec<uint8_t>& scope,
const hidl_vec<uint8_t>& response,
@@ -602,16 +722,7 @@ Return<void> WVDrmPlugin::getSecureStops(getSecureStops_cb _hidl_cb) {
}
Return<Status> 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<Status> WVDrmPlugin::releaseSecureStop(
@@ -633,6 +744,158 @@ Return<Status> WVDrmPlugin::releaseSecureStop(
return mapCdmResponseType(res);
}
Return<void> WVDrmPlugin::getSecureStopIds(getSecureStopIds_cb _hidl_cb) {
std::vector<SecureStopId> secureStopIds;
CdmIdentifier identifier;
Status status = mCdmIdentifierBuilder.getCdmIdentifier(&identifier);
if (status != Status::OK) {
_hidl_cb(status, toHidlVec(secureStopIds));
return Void();
}
std::vector<CdmSecureStopId> 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<Status> 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<uint8_t> data = toVector(ssRelease.opaqueData);
CdmUsageInfoReleaseMessage cdmMessage(data.begin(), data.end());
CdmResponseType res = mCDM->ReleaseUsageInfo(cdmMessage, identifier);
return mapCdmResponseType(res);
}
Return<Status> WVDrmPlugin::removeSecureStop(const hidl_vec<uint8_t>& secureStopId) {
if (!secureStopId.size()) {
return Status::BAD_VALUE;
}
CdmIdentifier identifier;
Status status = mCdmIdentifierBuilder.getCdmIdentifier(&identifier);
if (status != Status::OK) {
return status;
}
const std::vector<uint8_t> idVec = toVector(secureStopId);
CdmSecureStopId id(idVec.begin(), idVec.end());
CdmResponseType res = mCDM->RemoveUsageInfo(mPropertySet.app_id(), identifier, id);
return mapCdmResponseType(res);
}
Return<Status> 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<void> 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<void> 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<void> WVDrmPlugin::getSecurityLevel(
const hidl_vec<uint8_t>& sessionId,
getSecurityLevel_cb _hidl_cb) {
if (sessionId.size() == 0) {
_hidl_cb(Status::BAD_VALUE, SecurityLevel::UNKNOWN);
return Void();
}
std::vector<uint8_t> 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<void> WVDrmPlugin::getPropertyString(const hidl_string& propertyName,
getPropertyString_cb _hidl_cb) {
Status status = Status::OK;
@@ -757,7 +1020,8 @@ Return<Status> 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

View File

@@ -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 \

View File

@@ -5,9 +5,9 @@
#define LOG_TAG "WVDrmPluginTest"
#include <utils/Log.h>
#include <android/hardware/drm/1.0/types.h>
#include <android/hardware/drm/1.0/IDrmPlugin.h>
#include <android/hardware/drm/1.0/IDrmPluginListener.h>
#include <android/hardware/drm/1.1/IDrmPlugin.h>
#include <android/hardware/drm/1.1/types.h>
#include <stdio.h>
#include <ostream>
@@ -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<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
StrictMock<MockCrypto> 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<uint8_t> 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

View File

@@ -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

View File

@@ -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<void> WVCryptoFactory::createPlugin(
}
} // namespace widevine
} // namespace V1_0
} // namespace V1_1
} // namespace drm
} // namespace hardware
} // namespace wvdrm

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -70,6 +70,7 @@ LOCAL_STATIC_LIBRARIES := \
LOCAL_SHARED_LIBRARIES := \
android.hardware.drm@1.0 \
android.hardware.drm@1.1 \
libcutils \
libdl \
libhidlbase \

View File

@@ -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

View File

@@ -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

View File

@@ -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