Implement Widevine drm HIDL HAL service.

Modify Android mediadrm and mediacrypto glue layer to use
HIDL interface.

Test: Play Movies (streaming and offline playback)

Test: ANDROID_BUILD_TOP= ./android-gts/tools/gts-tradefed
run gts -m GtsMediaTestCases

Test:
adb shell /system/bin/libwvdrmengine_hidl_test

Test:
adb shell /system/bin/libwvdrmmediacrypto_hidl_test

Test:
adb shell /system/bin/libwvdrmdrmplugin_hidl_test

bug: 34628973
Change-Id: Icd5f2dd556acb9874697963b4d7d62cb7c943e74
This commit is contained in:
Edwin Wong
2017-01-23 15:48:45 -08:00
committed by John W. Bruce
parent a4506542df
commit 2dc53442e7
33 changed files with 6853 additions and 684 deletions

View File

@@ -1,4 +1,8 @@
LOCAL_PATH := $(call my-dir)
# -----------------------------------------------------------------------------
# Builds libwvdrmdrmplugin
#
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
@@ -20,3 +24,34 @@ LOCAL_MODULE := libwvdrmdrmplugin
LOCAL_MODULE_TAGS := optional
include $(BUILD_STATIC_LIBRARY)
# -----------------------------------------------------------------------------
# Builds libwvdrmdrmplugin_hidl
#
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
src/WVGenericCryptoInterface.cpp \
src_hidl/WVDrmPlugin.cpp \
LOCAL_C_INCLUDES := \
frameworks/av/include \
frameworks/native/include \
vendor/widevine/libwvdrmengine/cdm/core/include \
vendor/widevine/libwvdrmengine/cdm/include \
vendor/widevine/libwvdrmengine/cdm/metrics/include \
vendor/widevine/libwvdrmengine/include_hidl \
vendor/widevine/libwvdrmengine/include \
vendor/widevine/libwvdrmengine/mediadrm/include_hidl \
vendor/widevine/libwvdrmengine/mediadrm/include \
vendor/widevine/libwvdrmengine/oemcrypto/include \
LOCAL_SHARED_LIBRARIES := \
android.hardware.drm@1.0 \
android.hidl.memory@1.0 \
LOCAL_MODULE := libwvdrmdrmplugin_hidl
LOCAL_MODULE_TAGS := optional
include $(BUILD_STATIC_LIBRARY)

View File

@@ -0,0 +1,355 @@
//
// Copyright 2017 Google Inc. All Rights Reserved.
//
#ifndef WV_DRM_PLUGIN_H_
#define WV_DRM_PLUGIN_H_
#include <map>
#include <android/hardware/drm/1.0/IDrmPlugin.h>
#include <android/hardware/drm/1.0/IDrmPluginListener.h>
#include "cdm_client_property_set.h"
#include "cdm_identifier.h"
#include "OEMCryptoCENC.h"
#include "utils/String8.h"
#include "utils/Vector.h"
#include "wv_cdm_event_listener.h"
#include "wv_content_decryption_module.h"
#include "WVGenericCryptoInterface.h"
#include "WVTypes.h"
namespace wvdrm {
namespace hardware {
namespace drm {
namespace V1_0 {
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::Status;
using ::android::hardware::hidl_array;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::sp;
using android::status_t;
using android::String8;
using android::Vector;
using std::map;
using wvcdm::CdmIdentifier;
using wvcdm::CdmKeyStatusMap;
using wvcdm::CdmSessionId;
using wvcdm::CdmResponseType;
using wvcdm::WvContentDecryptionModule;
const OEMCrypto_Algorithm kInvalidCryptoAlgorithm =
static_cast<OEMCrypto_Algorithm>(-1);
struct WVDrmPlugin : public IDrmPlugin, IDrmPluginListener,
wvcdm::WvCdmEventListener {
WVDrmPlugin(const sp<WvContentDecryptionModule>& cdm,
const std::string& appPackageName,
WVGenericCryptoInterface* crypto);
virtual ~WVDrmPlugin();
Return<void> openSession(openSession_cb _hidl_cb) override;
Return<Status> closeSession(const hidl_vec<uint8_t>& sessionId) override;
Return<void> getKeyRequest(
const hidl_vec<uint8_t>& scope,
const hidl_vec<uint8_t>& initData,
const hidl_string& mimeType,
KeyType keyType,
const hidl_vec<KeyValue>& optionalParameters,
getKeyRequest_cb _hidl_cb) override;
Return<void> provideKeyResponse(
const hidl_vec<uint8_t>& scope,
const hidl_vec<uint8_t>& response,
provideKeyResponse_cb _hidl_cb) override;
Return<Status> removeKeys(const hidl_vec<uint8_t>& sessionId) override;
Return<Status> restoreKeys(
const hidl_vec<uint8_t>& sessionId,
const hidl_vec<uint8_t>& keySetId) override;
Return<void> queryKeyStatus(
const hidl_vec<uint8_t>& sessionId,
queryKeyStatus_cb _hidl_cb) override;
Return<void> getProvisionRequest(
const hidl_string& certificateType,
const hidl_string& certificateAuthority,
getProvisionRequest_cb _hidl_cb) override;
Return<void> provideProvisionResponse(
const hidl_vec<uint8_t>& response,
provideProvisionResponse_cb _hidl_cb) override;
Return<void> getSecureStops(getSecureStops_cb _hidl_cb) override;
Return<void> getSecureStop(
const hidl_vec<uint8_t>& secureStopId,
getSecureStop_cb _hidl_cb) override;
Return<Status> releaseAllSecureStops() override;
Return<Status> releaseSecureStop(
const hidl_vec<uint8_t>& secureStopId) override;
Return<void> getPropertyString(
const hidl_string& propertyName,
getPropertyString_cb _hidl_cb) override;
Return<void> getPropertyByteArray(
const hidl_string& propertyName,
getPropertyByteArray_cb _hidl_cb) override;
Return<Status> setPropertyString(
const hidl_string& propertyName,
const hidl_string& value) override;
Return<Status> setPropertyByteArray(
const hidl_string& propertyName,
const hidl_vec<uint8_t>& value) override;
Return<Status> setCipherAlgorithm(
const hidl_vec<uint8_t>& sessionId,
const hidl_string& algorithm) override;
Return<Status> setMacAlgorithm(
const hidl_vec<uint8_t>& sessionId,
const hidl_string& algorithm) override;
Return<void> encrypt(
const hidl_vec<uint8_t>& sessionId,
const hidl_vec<uint8_t>& keyId,
const hidl_vec<uint8_t>& input,
const hidl_vec<uint8_t>& iv,
encrypt_cb _hidl_cb) override;
Return<void> decrypt(
const hidl_vec<uint8_t>& sessionId,
const hidl_vec<uint8_t>& keyId,
const hidl_vec<uint8_t>& input,
const hidl_vec<uint8_t>& iv,
decrypt_cb _hidl_cb) override;
Return<void> sign(const hidl_vec<uint8_t>& sessionId,
const hidl_vec<uint8_t>& keyId, const hidl_vec<uint8_t>& message,
sign_cb _hidl_cb) override;
Return<void> verify(
const hidl_vec<uint8_t>& sessionId,
const hidl_vec<uint8_t>& keyId,
const hidl_vec<uint8_t>& message,
const hidl_vec<uint8_t>& signature,
verify_cb _hidl_cb) override;
Return<void> signRSA(
const hidl_vec<uint8_t>& sessionId,
const hidl_string& algorithm,
const hidl_vec<uint8_t>& message,
const hidl_vec<uint8_t>& wrappedkey,
signRSA_cb _hidl_cb) override;
Return<void> setListener(const sp<IDrmPluginListener>& listener) override;
Return<void> sendEvent(
EventType eventType,
const hidl_vec<uint8_t>& sessionId,
const hidl_vec<uint8_t>& data) override;
Return<void> sendExpirationUpdate(
const hidl_vec<uint8_t>& sessionId,
int64_t expiryTimeInMS) override;
Return<void> sendKeysChange(
const hidl_vec<uint8_t>& sessionId,
const hidl_vec<KeyStatus>& keyStatusList,
bool hasNewUsableKey) override;
// The following methods do not use hidl interface, it is used internally.
virtual status_t unprovisionDevice();
virtual void OnSessionRenewalNeeded(const CdmSessionId& cdmSessionId);
virtual void OnSessionKeysChange(
const CdmSessionId& cdmSessionId,
const CdmKeyStatusMap& cdmKeysStatus,
bool hasNewUsableKey);
virtual void OnExpirationUpdate(
const CdmSessionId& cdmSessionId,
int64_t newExpiryTimeSeconds);
private:
WVDRM_DISALLOW_COPY_AND_ASSIGN_AND_NEW(WVDrmPlugin);
struct CryptoSession {
public:
CryptoSession()
: mOecSessionId(-1),
mCipherAlgorithm(kInvalidCryptoAlgorithm),
mMacAlgorithm(kInvalidCryptoAlgorithm) {}
CryptoSession(OEMCrypto_SESSION sessionId)
: mOecSessionId(sessionId),
mCipherAlgorithm(kInvalidCryptoAlgorithm),
mMacAlgorithm(kInvalidCryptoAlgorithm) {}
OEMCrypto_SESSION oecSessionId() const { return mOecSessionId; }
OEMCrypto_Algorithm cipherAlgorithm() const { return mCipherAlgorithm; }
void setCipherAlgorithm(OEMCrypto_Algorithm newAlgorithm) {
mCipherAlgorithm = newAlgorithm;
}
OEMCrypto_Algorithm macAlgorithm() const { return mMacAlgorithm; }
void setMacAlgorithm(OEMCrypto_Algorithm newAlgorithm) {
mMacAlgorithm = newAlgorithm;
}
private:
OEMCrypto_SESSION mOecSessionId;
OEMCrypto_Algorithm mCipherAlgorithm;
OEMCrypto_Algorithm mMacAlgorithm;
};
class WVClientPropertySet : public wvcdm::CdmClientPropertySet {
public:
WVClientPropertySet()
: mUsePrivacyMode(false), mShareKeys(false), mSessionSharingId(0) {}
virtual ~WVClientPropertySet() {}
virtual const std::string& security_level() const {
return mSecurityLevel;
}
void set_security_level(const std::string& securityLevel) {
mSecurityLevel = securityLevel;
}
virtual bool use_privacy_mode() const {
return mUsePrivacyMode;
}
void set_use_privacy_mode(bool usePrivacyMode) {
mUsePrivacyMode = usePrivacyMode;
}
virtual const std::string& service_certificate() const {
return mServiceCertificate;
}
virtual void set_service_certificate(
const std::string& serviceCertificate) {
mServiceCertificate = serviceCertificate;
}
virtual const std::string& device_provisioning_service_certificate() const {
// Android does not support service certificates for provisioning.
return mEmptyString;
}
virtual void set_device_provisioning_service_certificate(
const std::string& ) {
// Ignore. Android does not support service certificates for provisioning
}
virtual bool is_session_sharing_enabled() const {
return mShareKeys;
}
void set_is_session_sharing_enabled(bool shareKeys) {
mShareKeys = shareKeys;
}
virtual uint32_t session_sharing_id() const {
return mSessionSharingId;
}
virtual void set_session_sharing_id(uint32_t id) {
mSessionSharingId = id;
}
virtual const std::string& app_id() const {
return mAppId;
}
void set_app_id(const std::string& appId) {
mAppId = appId;
}
private:
DISALLOW_EVIL_CONSTRUCTORS(WVClientPropertySet);
std::string mSecurityLevel;
bool mUsePrivacyMode;
std::string mServiceCertificate;
bool mShareKeys;
uint32_t mSessionSharingId;
std::string mAppId;
const std::string mEmptyString;
} mPropertySet;
std::string mAppPackageName;
sp<wvcdm::WvContentDecryptionModule> const mCDM;
CdmIdentifier mCdmIdentifier;
WVGenericCryptoInterface* mCrypto;
map<CdmSessionId, CryptoSession> mCryptoSessions;
sp<IDrmPluginListener> mListener;
const std::string& appPackageName() const {
return mAppPackageName;
}
status_t queryProperty(const std::string& property,
std::string& stringValue) const;
status_t queryProperty(wvcdm::SecurityLevel securityLevel,
const std::string& property,
std::string& stringValue) const;
status_t queryProperty(const std::string& property,
String8& string8_value) const;
status_t queryProperty(const std::string& property,
Vector<uint8_t>& vector_value) const;
status_t mapAndNotifyOfCdmResponseType(const Vector<uint8_t>& sessionId,
CdmResponseType res);
status_t mapAndNotifyOfOEMCryptoResult(const Vector<uint8_t>& sessionId,
OEMCryptoResult res);
status_t mapOEMCryptoResult(OEMCryptoResult res);
bool initDataResemblesPSSH(const Vector<uint8_t>& initData);
status_t unprovision(const CdmIdentifier& identifier);
};
} // namespace widevine
} // namespace V1_0
} // namespace drm
} // namespace hardware
} // namespace wvdrm
#endif // WV_DRM_PLUGIN_H_

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,12 @@
LOCAL_PATH := $(call my-dir)
# -----------------------------------------------------------------------------
# Builds libwvdrmdrmplugin_test
#
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
WVDrmPlugin_test.cpp \
legacy_src/WVDrmPlugin_test.cpp \
LOCAL_C_INCLUDES := \
frameworks/av/include \
@@ -38,10 +42,68 @@ LOCAL_SHARED_LIBRARIES := \
LOCAL_C_INCLUDES += \
external/protobuf/src \
# End protobuf section
LOCAL_MODULE := libwvdrmdrmplugin_test
LOCAL_MODULE_TAGS := tests
include $(BUILD_EXECUTABLE)
# -----------------------------------------------------------------------------
# Builds libwvdrmdrmplugin_hidl_test
#
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
WVDrmPlugin_test.cpp \
LOCAL_C_INCLUDES := \
frameworks/av/include \
frameworks/native/include \
vendor/widevine/libwvdrmengine/cdm/core/include \
vendor/widevine/libwvdrmengine/cdm/include \
vendor/widevine/libwvdrmengine/cdm/metrics/include \
vendor/widevine/libwvdrmengine/include_hidl \
vendor/widevine/libwvdrmengine/include \
vendor/widevine/libwvdrmengine/mediadrm/include_hidl \
vendor/widevine/libwvdrmengine/mediadrm/include \
vendor/widevine/libwvdrmengine/oemcrypto/include \
LOCAL_STATIC_LIBRARIES := \
libcdm \
libcdm_protos \
libcdm_utils \
libcrypto_static \
libjsmn \
libgmock \
libgmock_main \
libgtest \
libwvlevel3 \
libwvdrmdrmplugin_hidl \
# When the GNU linker sees a library, it discards all symbols that it doesn't
# need. libhidl_utils must come after libwvdrmdrmplugin.
LOCAL_STATIC_LIBRARIES += libhidl_utils
LOCAL_SHARED_LIBRARIES := \
android.hardware.drm@1.0 \
android.hidl.base@1.0 \
android.hidl.memory@1.0 \
libbinder \
libcutils \
libdl \
libhidlbase \
libhidlmemory \
liblog \
libmedia \
libprotobuf-cpp-lite \
libstagefright_foundation \
libutils \
LOCAL_C_INCLUDES += \
external/protobuf/src \
LOCAL_MODULE := libwvdrmdrmplugin_hidl_test
LOCAL_MODULE_TAGS := tests
include $(BUILD_EXECUTABLE)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff