Merge "Add additional error conditions to MediaDrm"

This commit is contained in:
Jeff Tinker
2019-01-15 01:22:14 +00:00
committed by Android (Google) Code Review
16 changed files with 390 additions and 217 deletions

View File

@@ -0,0 +1,62 @@
//
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
//
#ifndef HIDL_TYPES_H_
#define HIDL_TYPES_H_
#include <android/hardware/drm/1.1/types.h>
#include <android/hardware/drm/1.2/ICryptoFactory.h>
#include <android/hardware/drm/1.2/ICryptoPlugin.h>
#include <android/hardware/drm/1.2/types.h>
#include <android/hardware/drm/1.2/IDrmFactory.h>
#include <android/hardware/drm/1.2/IDrmPlugin.h>
#include <android/hardware/drm/1.2/IDrmPluginListener.h>
#include <hidl/HidlTransportSupport.h>
using ::android::hardware::configureRpcThreadpool;
using ::android::hardware::hidl_array;
using ::android::hardware::hidl_handle;
using ::android::hardware::hidl_memory;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hardware::joinRpcThreadpool;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::sp;
namespace drm = ::android::hardware::drm;
using drm::V1_0::BufferType;
using drm::V1_0::DestinationBuffer;
using drm::V1_0::EventType;
using drm::V1_0::IDrmPluginListener;
using drm::V1_0::KeyRequestType;
using drm::V1_0::KeyStatus;
using drm::V1_0::KeyStatusType;
using drm::V1_0::KeyType;
using drm::V1_0::KeyValue;
using drm::V1_0::Mode;
using drm::V1_0::Pattern;
using drm::V1_0::SecureStop;
using drm::V1_0::SecureStopId;
using drm::V1_0::SharedBuffer;
using drm::V1_0::Status;
using drm::V1_0::SubSample;
using drm::V1_1::DrmMetricGroup;
using drm::V1_1::HdcpLevel;
using drm::V1_1::SecureStopRelease;
using drm::V1_1::SecurityLevel;
using drm::V1_2::ICryptoFactory;
using drm::V1_2::ICryptoPlugin;
using drm::V1_2::IDrmFactory;
using drm::V1_2::IDrmPlugin;
using drm::V1_2::KeySetId;
using drm::V1_2::OfflineLicenseState;
typedef drm::V1_1::KeyRequestType KeyRequestType_V1_1;
typedef drm::V1_2::IDrmPluginListener IDrmPluginListener_V1_2;
typedef drm::V1_2::Status Status_V1_2;
#endif

View File

@@ -16,12 +16,12 @@
#ifndef WVDRM_ANDROID_HARDWARE_DRM_V1_1_TYPECONVERT
#define WVDRM_ANDROID_HARDWARE_DRM_V1_1_TYPECONVERT
#include "utils/Errors.h"
#include <vector>
#include <android/hardware/drm/1.0/types.h>
#include <media/stagefright/MediaErrors.h>
#include "media/stagefright/MediaErrors.h"
#include "HidlTypes.h"
#include "utils/Errors.h"
namespace android {
namespace hardware {
@@ -29,9 +29,6 @@ namespace drm {
namespace V1_2 {
namespace widevine {
using ::android::hardware::hidl_array;
using ::android::hardware::hidl_vec;
template<typename T> const hidl_vec<T> toHidlVec(const std::vector<T> &vec) {
hidl_vec<T> hVec;
hVec.setToExternal(const_cast<T *>(vec.data()), vec.size());

View File

@@ -7,8 +7,7 @@
#ifndef WV_CREATE_PLUGIN_FACTORIES_H_
#define WV_CREATE_PLUGIN_FACTORIES_H_
#include <android/hardware/drm/1.1/ICryptoFactory.h>
#include <android/hardware/drm/1.1/IDrmFactory.h>
#include "HidlTypes.h"
namespace wvdrm {
namespace hardware {
@@ -16,9 +15,6 @@ namespace drm {
namespace V1_2 {
namespace widevine {
using ::android::hardware::drm::V1_1::ICryptoFactory;
using ::android::hardware::drm::V1_1::IDrmFactory;
extern "C" {
IDrmFactory* createDrmFactory();
ICryptoFactory* createCryptoFactory();

View File

@@ -7,8 +7,7 @@
#ifndef WV_CRYPTO_FACTORY_H_
#define WV_CRYPTO_FACTORY_H_
#include <android/hardware/drm/1.1/ICryptoFactory.h>
#include "HidlTypes.h"
#include "WVTypes.h"
namespace wvdrm {
@@ -17,12 +16,6 @@ namespace drm {
namespace V1_2 {
namespace widevine {
using ::android::hardware::drm::V1_1::ICryptoFactory;
using ::android::hardware::drm::V1_0::ICryptoPlugin;
using ::android::hardware::hidl_array;
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
struct WVCryptoFactory : public ICryptoFactory {
public:
WVCryptoFactory() {}

View File

@@ -7,9 +7,7 @@
#ifndef WV_DRM_FACTORY_H_
#define WV_DRM_FACTORY_H_
#include <android/hardware/drm/1.1/IDrmFactory.h>
#include <android/hardware/drm/1.2/IDrmPlugin.h>
#include "HidlTypes.h"
#include "WVGenericCryptoInterface.h"
#include "WVTypes.h"
@@ -19,12 +17,6 @@ namespace drm {
namespace V1_2 {
namespace widevine {
using ::android::hardware::drm::V1_1::IDrmFactory;
using ::android::hardware::drm::V1_2::IDrmPlugin;
using ::android::hardware::hidl_array;
using ::android::hardware::hidl_string;
using ::android::hardware::Return;
struct WVDrmFactory : public IDrmFactory {
WVDrmFactory() {}
virtual ~WVDrmFactory() {}

View File

@@ -10,12 +10,11 @@
#include "media/stagefright/MediaErrors.h"
#include "utils/Errors.h"
#include "wv_cdm_types.h"
#include "HidlTypes.h"
#include "WVErrors.h"
namespace wvdrm {
using ::android::hardware::drm::V1_0::Status;
static Status mapCdmResponseType(wvcdm::CdmResponseType res) {
switch (res) {
case wvcdm::KEY_ADDED:
@@ -321,6 +320,26 @@ static Status mapCdmResponseType(wvcdm::CdmResponseType res) {
return Status::ERROR_DRM_UNKNOWN;
}
static Status_V1_2 mapCdmResponseType_1_2(
wvcdm::CdmResponseType res) {
switch(res) {
case wvcdm::KEY_PROHIBITED_FOR_SECURITY_LEVEL:
return Status_V1_2::ERROR_DRM_INSUFFICIENT_SECURITY;
// TODO(b/120572706): define in CDM
// case wvcdm::xxx:
// return Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE;
// case wvcdm::xxx:
// return Status_V1_2::ERROR_DRM_SESSION_LOST_STATE;
// case wvcdm::xxx:
// return Status_V1_2::ERROR_DRM_RESOURCE_CONTENTION;
default:
return static_cast<Status_V1_2>(mapCdmResponseType(res));
}
}
static inline bool isCdmResponseTypeSuccess(wvcdm::CdmResponseType res) {
return mapCdmResponseType(res) == Status::OK;
}

View File

@@ -7,9 +7,9 @@
#ifndef WV_CRYPTO_PLUGIN_H_
#define WV_CRYPTO_PLUGIN_H_
#include <android/hardware/drm/1.0/ICryptoPlugin.h>
#include <android/hidl/memory/1.0/IMemory.h>
#include "HidlTypes.h"
#include "wv_content_decryption_module.h"
#include "WVTypes.h"
@@ -19,20 +19,7 @@ namespace drm {
namespace V1_2 {
namespace widevine {
using ::android::hardware::drm::V1_0::DestinationBuffer;
using ::android::hardware::drm::V1_0::ICryptoPlugin;
using ::android::hardware::drm::V1_0::Mode;
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::hidl_array;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::hidl_memory;
using ::android::hidl::memory::V1_0::IMemory;
using ::android::sp;
struct WVCryptoPlugin : public ICryptoPlugin {
WVCryptoPlugin(const void* data, size_t size,
@@ -62,6 +49,18 @@ struct WVCryptoPlugin : public ICryptoPlugin {
const DestinationBuffer& destination,
decrypt_cb _hidl_cb) override;
Return<void> decrypt_1_2(
bool secure,
const hidl_array<uint8_t, 16>& keyId,
const hidl_array<uint8_t, 16>& iv,
Mode mode,
const Pattern& pattern,
const hidl_vec<SubSample>& subSamples,
const SharedBuffer& source,
uint64_t offset,
const DestinationBuffer& destination,
decrypt_1_2_cb _hidl_cb) override;
private:
WVDRM_DISALLOW_COPY_AND_ASSIGN_AND_NEW(WVCryptoPlugin);
@@ -70,7 +69,7 @@ struct WVCryptoPlugin : public ICryptoPlugin {
sp<wvcdm::WvContentDecryptionModule> const mCDM;
Status attemptDecrypt(
Status_V1_2 attemptDecrypt(
const wvcdm::CdmDecryptionParameters& params,
bool haveEncryptedSubsamples, std::string* errorDetailMsg);
static wvcdm::CdmResponseType countEncryptedBlocksInPatternedRange(

View File

@@ -9,13 +9,14 @@
#include <utils/Log.h>
#include "WVCryptoPlugin.h"
#include "TypeConvert.h"
#include <hidlmemory/mapping.h>
#include "HidlTypes.h"
#include "mapErrors-inl.h"
#include "OEMCryptoCENC.h"
#include "openssl/sha.h"
#include "TypeConvert.h"
#include "wv_cdm_constants.h"
#include "WVErrors.h"
@@ -23,6 +24,17 @@ namespace {
static const size_t kAESBlockSize = 16;
inline Status toStatus_1_0(Status_V1_2 status) {
switch (status) {
case Status_V1_2::ERROR_DRM_INSUFFICIENT_SECURITY:
case Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE:
case Status_V1_2::ERROR_DRM_SESSION_LOST_STATE:
return Status::ERROR_DRM_UNKNOWN;
default:
return static_cast<Status>(status);
}
}
} // namespace
namespace wvdrm {
@@ -31,10 +43,7 @@ namespace drm {
namespace V1_2 {
namespace widevine {
using ::android::hardware::drm::V1_0::BufferType;
using ::android::hardware::drm::V1_2::widevine::toVector;
using ::android::hardware::Void;
using android::hardware::drm::V1_2::widevine::toVector;
using wvcdm::CdmDecryptionParameters;
using wvcdm::CdmQueryMap;
using wvcdm::CdmResponseType;
@@ -116,8 +125,40 @@ Return<void> WVCryptoPlugin::decrypt(
const DestinationBuffer& destination,
decrypt_cb _hidl_cb) {
Status status = Status::ERROR_DRM_UNKNOWN;
hidl_string detailedError;
uint32_t bytesWritten = 0;
Return<void> hResult = decrypt_1_2(
secure, keyId, iv, mode, pattern, subSamples, source, offset, destination,
[&](Status_V1_2 hStatus, uint32_t hBytesWritten, hidl_string hDetailedError) {
status = toStatus_1_0(hStatus);
if (status == Status::OK) {
bytesWritten = hBytesWritten;
detailedError = hDetailedError;
}
}
);
status = hResult.isOk() ? status : Status::ERROR_DRM_CANNOT_HANDLE;
_hidl_cb(status, bytesWritten, detailedError);
return Void();
}
Return<void> WVCryptoPlugin::decrypt_1_2(
bool secure,
const hidl_array<uint8_t, 16>& keyId,
const hidl_array<uint8_t, 16>& iv,
Mode mode,
const Pattern& pattern,
const hidl_vec<SubSample>& subSamples,
const SharedBuffer& source,
uint64_t offset,
const DestinationBuffer& destination,
decrypt_1_2_cb _hidl_cb) {
if (mSharedBufferMap.find(source.bufferId) == mSharedBufferMap.end()) {
_hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0,
_hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0,
"source decrypt buffer base not set");
return Void();
}
@@ -125,7 +166,7 @@ Return<void> WVCryptoPlugin::decrypt(
if (destination.type == BufferType::SHARED_MEMORY) {
const SharedBuffer& dest = destination.nonsecureMemory;
if (mSharedBufferMap.find(dest.bufferId) == mSharedBufferMap.end()) {
_hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0,
_hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0,
"destination decrypt buffer base not set");
return Void();
}
@@ -134,7 +175,7 @@ Return<void> WVCryptoPlugin::decrypt(
if (mode != Mode::UNENCRYPTED &&
mode != Mode::AES_CTR &&
mode != Mode::AES_CBC) {
_hidl_cb(Status::BAD_VALUE,
_hidl_cb(Status_V1_2::BAD_VALUE,
0, "Encryption mode is not supported by Widevine CDM.");
return Void();
}
@@ -147,12 +188,12 @@ Return<void> WVCryptoPlugin::decrypt(
std::string errorDetailMsg;
sp<IMemory> sourceBase = mSharedBufferMap[source.bufferId];
if (sourceBase == nullptr) {
_hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "source is a nullptr");
_hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0, "source is a nullptr");
return Void();
}
if (source.offset + offset + source.size > sourceBase->getSize()) {
_hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
_hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
return Void();
}
@@ -164,12 +205,12 @@ Return<void> WVCryptoPlugin::decrypt(
const SharedBuffer& destBuffer = destination.nonsecureMemory;
sp<IMemory> destBase = mSharedBufferMap[destBuffer.bufferId];
if (destBase == nullptr) {
_hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "destination is a nullptr");
_hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0, "destination is a nullptr");
return Void();
}
if (destBuffer.offset + destBuffer.size > destBase->getSize()) {
_hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
_hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
return Void();
}
destPtr = static_cast<void *>(base + destination.nonsecureMemory.offset);
@@ -218,7 +259,7 @@ Return<void> WVCryptoPlugin::decrypt(
const SubSample& subSample = subSamples[i];
if (mode == Mode::UNENCRYPTED && subSample.numBytesOfEncryptedData != 0) {
_hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0,
_hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0,
"Encrypted subsamples found in allegedly unencrypted data.");
return Void();
}
@@ -256,9 +297,9 @@ Return<void> WVCryptoPlugin::decrypt(
params.decrypt_buffer_offset = bufferOffset;
params.subsample_flags = clearFlags;
Status res = attemptDecrypt(params, haveEncryptedSubsamples,
&errorDetailMsg);
if (res != Status::OK) {
Status_V1_2 res = attemptDecrypt(params, haveEncryptedSubsamples,
&errorDetailMsg);
if (res != Status_V1_2::OK) {
_hidl_cb(res, 0, errorDetailMsg.c_str());
return Void();
}
@@ -275,9 +316,9 @@ Return<void> WVCryptoPlugin::decrypt(
params.decrypt_buffer_offset = bufferOffset;
params.subsample_flags = encryptedFlags;
Status res = attemptDecrypt(params, haveEncryptedSubsamples,
&errorDetailMsg);
if (res != Status::OK) {
Status_V1_2 res = attemptDecrypt(params, haveEncryptedSubsamples,
&errorDetailMsg);
if (res != Status_V1_2::OK) {
_hidl_cb(res, 0, errorDetailMsg.c_str());
return Void();
}
@@ -301,7 +342,7 @@ Return<void> WVCryptoPlugin::decrypt(
subSample.numBytesOfEncryptedData, pattern, &increment);
if (!isCdmResponseTypeSuccess(countRes)) {
// Swallow the specifics of the error to obscure decrypt internals.
_hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0,
_hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0,
"Error decrypting data: unknown error");
return Void();
}
@@ -325,18 +366,17 @@ Return<void> WVCryptoPlugin::decrypt(
}
}
_hidl_cb(Status::OK, bufferOffset, errorDetailMsg.c_str());
_hidl_cb(Status_V1_2::OK, bufferOffset, errorDetailMsg.c_str());
return Void();
}
Status WVCryptoPlugin::attemptDecrypt(const CdmDecryptionParameters& params,
bool haveEncryptedSubsamples,
std::string* errorDetailMsg) {
Status_V1_2 WVCryptoPlugin::attemptDecrypt(const CdmDecryptionParameters& params,
bool haveEncryptedSubsamples, std::string* errorDetailMsg) {
CdmResponseType res = mCDM->Decrypt(mSessionId, haveEncryptedSubsamples,
params);
if (isCdmResponseTypeSuccess(res)) {
return Status::OK;
return Status_V1_2::OK;
} else {
ALOGE("Decrypt error result in session %s during %s block: %d",
mSessionId.c_str(),
@@ -381,10 +421,10 @@ Status WVCryptoPlugin::attemptDecrypt(const CdmDecryptionParameters& params,
if (actionableError) {
// This error is actionable by the app and should be passed up.
return mapCdmResponseType(res);
return mapCdmResponseType_1_2(res);
} else {
// Swallow the specifics of other errors to obscure decrypt internals.
return Status::ERROR_DRM_UNKNOWN;
return Status_V1_2::ERROR_DRM_UNKNOWN;
}
}
}

View File

@@ -22,6 +22,7 @@
#include "wv_cdm_constants.h"
#include "wv_cdm_types.h"
#include "wv_content_decryption_module.h"
#include "HidlTypes.h"
#include "OEMCryptoCENC.h"
#include "TypeConvert.h"
#include "WVCryptoPlugin.h"
@@ -32,22 +33,7 @@ namespace drm {
namespace V1_2 {
namespace widevine {
using ::android::hardware::drm::V1_0::BufferType;
using ::android::hardware::drm::V1_0::DestinationBuffer;
using ::android::hardware::drm::V1_0::Mode;
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_2::widevine::toHidlVec;
using ::android::hardware::hidl_array;
using ::android::hardware::hidl_handle;
using ::android::hardware::hidl_memory;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hardware::Void;
using ::android::MemoryDealer;
using ::android::sp;
using ::testing::_;
using ::testing::DefaultValue;

View File

@@ -9,15 +9,12 @@
#include <map>
#include <android/hardware/drm/1.0/IDrmPluginListener.h>
#include <android/hardware/drm/1.1/types.h>
#include <android/hardware/drm/1.2/IDrmPlugin.h>
#include "cdm_client_property_set.h"
#include "cdm_identifier.h"
#include "OEMCryptoCENC.h"
#include "wv_cdm_event_listener.h"
#include "wv_content_decryption_module.h"
#include "OEMCryptoCENC.h"
#include "HidlTypes.h"
#include "WVGenericCryptoInterface.h"
#include "WVTypes.h"
@@ -27,29 +24,6 @@ namespace drm {
namespace V1_2 {
namespace widevine {
using ::android::hardware::drm::V1_0::EventType;
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::SecureStopRelease;
using ::android::hardware::drm::V1_1::SecurityLevel;
using ::android::hardware::drm::V1_2::IDrmPlugin;
using ::android::hardware::drm::V1_2::KeySetId;
using ::android::hardware::drm::V1_2::OfflineLicenseState;
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;
using wvcdm::CdmIdentifier;
using wvcdm::CdmKeyStatusMap;
@@ -92,6 +66,14 @@ struct WVDrmPlugin : public IDrmPlugin, IDrmPluginListener,
const hidl_vec<KeyValue>& optionalParameters,
getKeyRequest_1_1_cb _hidl_cb) override;
Return<void> getKeyRequest_1_2(
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_2_cb _hidl_cb) override;
Return<void> provideKeyResponse(
const hidl_vec<uint8_t>& scope,
const hidl_vec<uint8_t>& response,
@@ -112,6 +94,11 @@ struct WVDrmPlugin : public IDrmPlugin, IDrmPluginListener,
const hidl_string& certificateAuthority,
getProvisionRequest_cb _hidl_cb) override;
Return<void> getProvisionRequest_1_2(
const hidl_string& certificateType,
const hidl_string& certificateAuthority,
getProvisionRequest_1_2_cb _hidl_cb) override;
Return<void> provideProvisionResponse(
const hidl_vec<uint8_t>& response,
provideProvisionResponse_cb _hidl_cb) override;
@@ -224,6 +211,9 @@ struct WVDrmPlugin : public IDrmPlugin, IDrmPluginListener,
const hidl_vec<KeyStatus>& keyStatusList,
bool hasNewUsableKey) override;
Return<void> sendSessionLostState(
const hidl_vec<uint8_t>& sessionId) override;
// The following methods do not use hidl interface, it is used internally.
virtual Status unprovisionDevice();
@@ -238,6 +228,9 @@ struct WVDrmPlugin : public IDrmPlugin, IDrmPluginListener,
const CdmSessionId& cdmSessionId,
int64_t newExpiryTimeSeconds);
virtual void OnSessionLostState(
const CdmSessionId& cdmSessionId);
private:
WVDRM_DISALLOW_COPY_AND_ASSIGN_AND_NEW(WVDrmPlugin);
@@ -408,6 +401,7 @@ struct WVDrmPlugin : public IDrmPlugin, IDrmPluginListener,
WVGenericCryptoInterface* mCrypto;
map<CdmSessionId, CryptoSession> mCryptoSessions;
sp<IDrmPluginListener> mListener;
sp<IDrmPluginListener_V1_2> mListenerV1_2;
std::string mProvisioningServiceCertificate;
@@ -426,6 +420,12 @@ struct WVDrmPlugin : public IDrmPlugin, IDrmPluginListener,
Status mapAndNotifyOfCdmResponseType(const std::vector<uint8_t>& sessionId,
CdmResponseType res);
Status_V1_2 mapAndNotifyOfCdmResponseType_1_2(const std::vector<uint8_t>& sessionId,
CdmResponseType res);
void notifyOfCdmResponseType(const std::vector<uint8_t>& sessionId,
CdmResponseType res);
Status mapAndNotifyOfOEMCryptoResult(const std::vector<uint8_t>& sessionId,
OEMCryptoResult res);

View File

@@ -12,7 +12,6 @@
#include <stdlib.h>
#include "WVDrmPlugin.h"
#include "TypeConvert.h"
#include "android-base/macros.h"
#include "hidl_metrics_adapter.h"
@@ -21,6 +20,8 @@
#include "metrics.pb.h"
#include "openssl/sha.h"
#include "wv_cdm_constants.h"
#include "TypeConvert.h"
#include "HidlTypes.h"
namespace {
@@ -38,17 +39,8 @@ namespace drm {
namespace V1_2 {
namespace widevine {
using ::android::hardware::drm::V1_0::EventType;
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_1::DrmMetricGroup;
using ::android::hardware::drm::V1_1::SecurityLevel;
using ::android::hardware::drm::V1_2::widevine::toHidlVec;
using ::android::hardware::drm::V1_2::widevine::toVector;
using ::android::hardware::Void;
using android::hardware::drm::V1_2::widevine::toHidlVec;
using android::hardware::drm::V1_2::widevine::toVector;
using wvcdm::kDefaultCdmIdentifier;
using wvcdm::CdmAppParameterMap;
using wvcdm::CdmCertificateType;
@@ -88,6 +80,42 @@ KeyRequestType ConvertFromCdmKeyRequestType(
}
}
KeyRequestType_V1_1 ConvertFromCdmKeyRequestType_1_1(
CdmKeyRequestType keyRequestType) {
/* TODO - What happened to these?
switch (keyRequestType) {
case wvcdm::kKeyRequestTypeNone:
return KeyRequestType_V1_1::NONE;
case wvcdm::kKeyRequestTypeUpdate:
return KeyRequestType_V1_1::UPDATE;
default:
*/
return static_cast<KeyRequestType_V1_1>(
ConvertFromCdmKeyRequestType(keyRequestType));
}
KeyRequestType toKeyRequestType_V1_0(KeyRequestType_V1_1 keyRequestType) {
switch (keyRequestType) {
case KeyRequestType_V1_1::NONE:
case KeyRequestType_V1_1::UPDATE:
return KeyRequestType::UNKNOWN;
default:
return static_cast<KeyRequestType>(keyRequestType);
}
}
Status toStatus_1_0(Status_V1_2 status) {
switch (status) {
case Status_V1_2::ERROR_DRM_INSUFFICIENT_SECURITY:
case Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE:
case Status_V1_2::ERROR_DRM_SESSION_LOST_STATE:
case Status_V1_2::ERROR_DRM_RESOURCE_CONTENTION:
return Status::ERROR_DRM_UNKNOWN;
default:
return static_cast<Status>(status);
}
}
KeyStatusType ConvertFromCdmKeyStatus(CdmKeyStatus keyStatus) {
switch (keyStatus) {
case wvcdm::kKeyStatusUsable:
@@ -281,10 +309,8 @@ Return<void> WVDrmPlugin::openSession_1_1(
});
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();
}
@@ -310,21 +336,80 @@ Return<void> WVDrmPlugin::getKeyRequest(
KeyType keyType,
const hidl_vec<KeyValue>& optionalParameters,
getKeyRequest_cb _hidl_cb) {
hidl_string defaultUrl;
hidl_vec<uint8_t> request;
KeyRequestType requestType = KeyRequestType::UNKNOWN;
Status status = Status::ERROR_DRM_UNKNOWN;
defaultUrl.clear();
Return<void> hResult = getKeyRequest_1_1(
scope, initData, mimeType, keyType, optionalParameters,
[&](Status statusCode, const hidl_vec<uint8_t>& hRequest,
KeyRequestType_V1_1 hKeyRequestType, const hidl_string& hDefaultUrl) {
defaultUrl = hDefaultUrl;
request = hRequest;
requestType = toKeyRequestType_V1_0(hKeyRequestType);
status = statusCode;
});
if (!hResult.isOk()) {
status = Status::ERROR_DRM_INVALID_STATE;
}
_hidl_cb(status, request, requestType, defaultUrl);
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;
KeyRequestType_V1_1 requestType = KeyRequestType_V1_1::UNKNOWN;
Status status = Status::ERROR_DRM_UNKNOWN;
defaultUrl.clear();
Return<void> hResult = getKeyRequest_1_2(
scope, initData, mimeType, keyType, optionalParameters,
[&](Status_V1_2 statusCode, const hidl_vec<uint8_t>& hRequest,
KeyRequestType_V1_1 hKeyRequestType, const hidl_string& hDefaultUrl) {
defaultUrl = hDefaultUrl;
request = hRequest;
requestType = hKeyRequestType;
status = toStatus_1_0(statusCode);
});
if (!hResult.isOk()) {
status = Status::ERROR_DRM_INVALID_STATE;
}
_hidl_cb(status, request, requestType, defaultUrl);
return Void();
}
Return<void> WVDrmPlugin::getKeyRequest_1_2(
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_2_cb _hidl_cb) {
if (!scope.size()) {
_hidl_cb(Status::BAD_VALUE, hidl_vec<uint8_t>(),
KeyRequestType::UNKNOWN, "");
_hidl_cb(Status_V1_2::BAD_VALUE, hidl_vec<uint8_t>(),
KeyRequestType_V1_1::UNKNOWN, "");
return Void();
}
KeyRequestType requestType = KeyRequestType::UNKNOWN;
Status status = Status::OK;
KeyRequestType_V1_1 requestType = KeyRequestType_V1_1::UNKNOWN;
Status_V1_2 status = Status_V1_2::OK;
std::string defaultUrl;
std::vector<uint8_t> request;
const std::vector<uint8_t> scopeId = toVector(scope);
CdmIdentifier identifier;
status = mCdmIdentifierBuilder.getCdmIdentifier(&identifier);
if (status != Status::OK) {
status = static_cast<Status_V1_2>(
mCdmIdentifierBuilder.getCdmIdentifier(&identifier));
if (status != Status_V1_2::OK) {
_hidl_cb(status, toHidlVec(request), requestType,
defaultUrl.c_str());
return Void();
@@ -343,7 +428,7 @@ Return<void> WVDrmPlugin::getKeyRequest(
cdmLicenseType = wvcdm::kLicenseTypeRelease;
cdmKeySetId.assign(scopeId.begin(), scopeId.end());
} else {
_hidl_cb(Status::BAD_VALUE, toHidlVec(request), KeyRequestType::UNKNOWN,
_hidl_cb(Status_V1_2::BAD_VALUE, toHidlVec(request), KeyRequestType_V1_1::UNKNOWN,
defaultUrl.c_str());
return Void();
}
@@ -404,7 +489,7 @@ Return<void> WVDrmPlugin::getKeyRequest(
cdmSessionId, cdmKeySetId, cdmInitDataType, processedInitData,
cdmLicenseType, cdmParameters, &mPropertySet, identifier, &keyRequest);
requestType = ConvertFromCdmKeyRequestType(keyRequest.type);
requestType = ConvertFromCdmKeyRequestType_1_1(keyRequest.type);
if (isCdmResponseTypeSuccess(res)) {
defaultUrl.clear();
@@ -415,48 +500,16 @@ Return<void> WVDrmPlugin::getKeyRequest(
if (keyType == KeyType::RELEASE) {
// When releasing keys, we do not have a session ID.
status = mapCdmResponseType(res);
status = mapCdmResponseType_1_2(res);
} else {
// For all other requests, we have a session ID.
status = mapAndNotifyOfCdmResponseType(scopeId, res);
status = mapAndNotifyOfCdmResponseType_1_2(scopeId, res);
}
_hidl_cb(status, toHidlVec(request), requestType,
defaultUrl.c_str());
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,
@@ -575,7 +628,7 @@ Return<Status> WVDrmPlugin::restoreKeys(const hidl_vec<uint8_t>& sessionId,
return Void();
}
Return<void> WVDrmPlugin::getProvisionRequest(
Return<void> WVDrmPlugin::getProvisionRequest(
const hidl_string& certificateType,
const hidl_string& certificateAuthority,
getProvisionRequest_cb _hidl_cb) {
@@ -583,9 +636,33 @@ Return<Status> WVDrmPlugin::restoreKeys(const hidl_vec<uint8_t>& sessionId,
std::string defaultUrl;
std::vector<uint8_t> request;
Return<void> hResult = getProvisionRequest_1_2(
certificateType, certificateAuthority,
[&](Status_V1_2 statusCode, const hidl_vec<uint8_t>& hRequest,
const hidl_string& hDefaultUrl) {
request = hRequest;
status = toStatus_1_0(statusCode);
defaultUrl = hDefaultUrl;
});
if (!hResult.isOk()) {
status = Status::ERROR_DRM_INVALID_STATE;
}
_hidl_cb(status, toHidlVec(request), hidl_string(defaultUrl));
return Void();
}
Return<void> WVDrmPlugin::getProvisionRequest_1_2(
const hidl_string& certificateType,
const hidl_string& certificateAuthority,
getProvisionRequest_1_2_cb _hidl_cb) {
Status_V1_2 status = Status_V1_2::OK;
std::string defaultUrl;
std::vector<uint8_t> request;
CdmIdentifier identifier;
status = mCdmIdentifierBuilder.getCdmIdentifier(&identifier);
if (status != Status::OK) {
status = static_cast<Status_V1_2>(mCdmIdentifierBuilder.getCdmIdentifier(&identifier));
if (status != Status_V1_2::OK) {
_hidl_cb(status, toHidlVec(request), hidl_string(defaultUrl));
return Void();
}
@@ -609,7 +686,7 @@ Return<Status> WVDrmPlugin::restoreKeys(const hidl_vec<uint8_t>& sessionId,
defaultUrl.assign(cdmDefaultUrl.data(), cdmDefaultUrl.size());
}
_hidl_cb(mapCdmResponseType(res), toHidlVec(request),
_hidl_cb(mapCdmResponseType_1_2(res), toHidlVec(request),
hidl_string(defaultUrl));
return Void();
}
@@ -1542,13 +1619,17 @@ Return<void> WVDrmPlugin::signRSA(
Return<void> WVDrmPlugin::setListener(const sp<IDrmPluginListener>& listener) {
mListener = listener;
mListenerV1_2 = IDrmPluginListener_V1_2::castFrom(listener);
return Void();
}
Return<void> WVDrmPlugin::sendEvent(
EventType eventType,
const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
if (mListener != NULL) {
const hidl_vec<uint8_t>& sessionId,
const hidl_vec<uint8_t>& data) {
if (mListenerV1_2 != NULL) {
mListenerV1_2->sendEvent(eventType, sessionId, data);
} else if (mListener != NULL) {
mListener->sendEvent(eventType, sessionId, data);
} else {
ALOGE("Null event listener, event not sent");
@@ -1557,10 +1638,12 @@ Return<void> WVDrmPlugin::sendEvent(
}
Return<void> WVDrmPlugin::sendExpirationUpdate(
const hidl_vec<uint8_t>& sessionId,
int64_t expiryTimeInMS) {
if (mListener != NULL) {
mListener->sendExpirationUpdate(sessionId, expiryTimeInMS);
const hidl_vec<uint8_t>& sessionId,
int64_t expiryTimeInMS) {
if (mListenerV1_2 != NULL) {
mListenerV1_2->sendExpirationUpdate(sessionId, expiryTimeInMS);
} else if (mListener != NULL) {
mListener->sendExpirationUpdate(sessionId, expiryTimeInMS);
} else {
ALOGE("Null event listener, event not sent");
}
@@ -1570,8 +1653,20 @@ Return<void> WVDrmPlugin::sendExpirationUpdate(
Return<void> WVDrmPlugin::sendKeysChange(
const hidl_vec<uint8_t>& sessionId,
const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
if (mListener != NULL) {
mListener->sendKeysChange(sessionId, keyStatusList, hasNewUsableKey);
if (mListenerV1_2 != NULL) {
mListenerV1_2->sendKeysChange(sessionId, keyStatusList, hasNewUsableKey);
} else if (mListener != NULL) {
mListener->sendKeysChange(sessionId, keyStatusList, hasNewUsableKey);
} else {
ALOGE("Null event listener, event not sent");
}
return Void();
}
Return<void> WVDrmPlugin::sendSessionLostState(
const hidl_vec<uint8_t>& sessionId) {
if (mListenerV1_2 != NULL) {
mListenerV1_2->sendSessionLostState(sessionId);
} else {
ALOGE("Null event listener, event not sent");
}
@@ -1622,6 +1717,11 @@ void WVDrmPlugin::OnExpirationUpdate(const CdmSessionId& cdmSessionId,
sendExpirationUpdate(toHidlVec(sessionId), newExpiryTimeMilliseconds);
}
void WVDrmPlugin::OnSessionLostState(const CdmSessionId& cdmSessionId) {
const std::vector<uint8_t> sessionId = StrToVector(cdmSessionId);
sendSessionLostState(toHidlVec(sessionId));
}
Status WVDrmPlugin::queryProperty(const std::string& property,
std::string& stringValue) const {
wvcdm::SecurityLevel securityLevel =
@@ -1654,6 +1754,18 @@ Status WVDrmPlugin::queryProperty(const std::string& property,
}
Status WVDrmPlugin::mapAndNotifyOfCdmResponseType(
const std::vector<uint8_t>& sessionId, CdmResponseType res) {
notifyOfCdmResponseType(sessionId, res);
return mapCdmResponseType(res);
}
Status_V1_2 WVDrmPlugin::mapAndNotifyOfCdmResponseType_1_2(
const std::vector<uint8_t>& sessionId, CdmResponseType res) {
notifyOfCdmResponseType(sessionId, res);
return mapCdmResponseType_1_2(res);
}
void WVDrmPlugin::notifyOfCdmResponseType(
const std::vector<uint8_t>& sessionId,
CdmResponseType res) {
@@ -1663,8 +1775,6 @@ Status WVDrmPlugin::mapAndNotifyOfCdmResponseType(
} else if (res == wvcdm::NEED_KEY) {
sendEvent(EventType::KEY_NEEDED, toHidlVec(sessionId), data);
}
return mapCdmResponseType(res);
}
Status WVDrmPlugin::mapAndNotifyOfOEMCryptoResult(

View File

@@ -7,10 +7,6 @@
#define LOG_TAG "WVDrmPluginTest"
#include <utils/Log.h>
#include <android/hardware/drm/1.0/IDrmPluginListener.h>
#include <android/hardware/drm/1.1/types.h>
#include <android/hardware/drm/1.2/IDrmPlugin.h>
#include <stdio.h>
#include <ostream>
#include <string>
@@ -26,6 +22,7 @@
#include "wv_cdm_constants.h"
#include "wv_cdm_types.h"
#include "wv_content_decryption_module.h"
#include "HidlTypes.h"
#include "TypeConvert.h"
#include "WVDrmPlugin.h"
#include "WVErrors.h"
@@ -36,13 +33,7 @@ namespace drm {
namespace V1_2 {
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_2::widevine::toHidlVec;
using ::android::hardware::hidl_vec;
using android::hardware::drm::V1_2::widevine::toHidlVec;
using ::testing::_;
using ::testing::AllOf;
using ::testing::Args;

View File

@@ -9,6 +9,8 @@
#include <utils/Log.h>
#include "WVCryptoFactory.h"
#include "HidlTypes.h"
#include "WVCDMSingleton.h"
#include "WVCryptoPlugin.h"
#include "WVUUID.h"
@@ -19,9 +21,6 @@ namespace drm {
namespace V1_2 {
namespace widevine {
using ::android::hardware::drm::V1_0::Status;
using ::android::hardware::Void;
Return<bool> WVCryptoFactory::isCryptoSchemeSupported(
const hidl_array<uint8_t, 16>& uuid) {
return isWidevineUUID(uuid.data());

View File

@@ -12,8 +12,9 @@
#include "cutils/properties.h"
#include "wv_cdm_constants.h"
#include "WVCDMSingleton.h"
#include "wv_content_decryption_module.h"
#include "HidlTypes.h"
#include "WVCDMSingleton.h"
#include "WVDrmPlugin.h"
#include "WVUUID.h"
@@ -23,9 +24,6 @@ namespace drm {
namespace V1_2 {
namespace widevine {
using ::android::hardware::drm::V1_0::Status;
using ::android::hardware::Void;
WVGenericCryptoInterface WVDrmFactory::sOemCryptoInterface;
Return<bool> WVDrmFactory::isCryptoSchemeSupported(

View File

@@ -14,20 +14,14 @@
* limitations under the License.
*/
#define LOG_TAG "WidevineHidlService"
#include <WVCryptoFactory.h>
#include <WVDrmFactory.h>
#include <android-base/logging.h>
#include <binder/ProcessState.h>
#include <hidl/HidlTransportSupport.h>
#include <binder/ProcessState.h>
#include "WVCryptoFactory.h"
#include "WVDrmFactory.h"
using ::android::hardware::configureRpcThreadpool;
using ::android::hardware::joinRpcThreadpool;
using ::android::sp;
using android::hardware::drm::V1_1::ICryptoFactory;
using android::hardware::drm::V1_1::IDrmFactory;
using wvdrm::hardware::drm::V1_2::widevine::WVCryptoFactory;
using wvdrm::hardware::drm::V1_2::widevine::WVDrmFactory;

View File

@@ -4,10 +4,10 @@
* License Agreement.
*/
#include "cutils/properties.h"
#include "gtest/gtest.h"
#include "WVDrmFactory.h"
#include "cutils/properties.h"
#include "HidlTypes.h"
namespace wvdrm {
namespace hardware {
@@ -15,9 +15,6 @@ namespace drm {
namespace V1_2 {
namespace widevine {
using ::android::hardware::hidl_string;
using wvdrm::hardware::drm::V1_2::widevine::WVDrmFactory;
using namespace android;
const uint8_t kWidevineUUID[16] = {