Add new offline management APIs to MediaDrm

bug:110838441
bug:117570956
bug:116252891

test:cts android.media.cts.MediaDrmClearkeyTest#testOfflineKeyManagement

Change-Id: I2ee86afbd1a0ae793454c2e81f3267aaf10bade7
gugelfrei
Jeff Tinker 6 years ago
parent 71fb1a8ce5
commit c8baaba1ee

@ -32,6 +32,7 @@ cc_library {
"libutils",
"android.hardware.drm@1.0",
"android.hardware.drm@1.1",
"android.hardware.drm@1.2",
"libhidlallocatorutils",
"libhidlbase",
"libhidltransport",

@ -23,7 +23,7 @@
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <android/hardware/drm/1.0/types.h>
#include <android/hardware/drm/1.2/types.h>
#include <android/hidl/manager/1.0/IServiceManager.h>
#include <hidl/ServiceManagement.h>
@ -43,12 +43,13 @@ using drm::V1_0::KeyedVector;
using drm::V1_0::KeyStatusType;
using drm::V1_0::KeyType;
using drm::V1_0::KeyValue;
using drm::V1_1::HdcpLevel;;
using drm::V1_0::SecureStop;
using drm::V1_1::SecureStopRelease;
using drm::V1_0::SecureStopId;
using drm::V1_1::SecurityLevel;
using drm::V1_0::Status;
using drm::V1_1::HdcpLevel;
using drm::V1_1::SecureStopRelease;
using drm::V1_1::SecurityLevel;
using drm::V1_2::KeySetId;
using ::android::hardware::drm::V1_1::DrmMetricGroup;
using ::android::hardware::hidl_array;
using ::android::hardware::hidl_string;
@ -139,6 +140,18 @@ static DrmPlugin::SecurityLevel toSecurityLevel(SecurityLevel level) {
}
}
static DrmPlugin::OfflineLicenseState toOfflineLicenseState(
OfflineLicenseState licenseState) {
switch(licenseState) {
case OfflineLicenseState::USABLE:
return DrmPlugin::kOfflineLicenseStateUsable;
case OfflineLicenseState::INACTIVE:
return DrmPlugin::kOfflineLicenseStateInactive;
default:
return DrmPlugin::kOfflineLicenseStateUnknown;
}
}
static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel level) {
switch(level) {
case HdcpLevel::HDCP_NONE:
@ -199,6 +212,15 @@ static List<Vector<uint8_t>> toSecureStopIds(const hidl_vec<SecureStopId>&
return secureStopIds;
}
static List<Vector<uint8_t>> toKeySetIds(const hidl_vec<KeySetId>&
hKeySetIds) {
List<Vector<uint8_t>> keySetIds;
for (size_t i = 0; i < hKeySetIds.size(); i++) {
keySetIds.push_back(toVector(hKeySetIds[i]));
}
return keySetIds;
}
static status_t toStatusT(Status status) {
switch (status) {
case Status::OK:
@ -305,6 +327,7 @@ void DrmHal::cleanup() {
}
mPlugin.clear();
mPluginV1_1.clear();
mPluginV1_2.clear();
}
Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
@ -333,6 +356,16 @@ Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
}
}
);
manager->listByInterface(drm::V1_2::IDrmFactory::descriptor,
[&factories](const hidl_vec<hidl_string> &registered) {
for (const auto &instance : registered) {
auto factory = drm::V1_2::IDrmFactory::getService(instance);
if (factory != NULL) {
factories.push_back(factory);
}
}
}
);
}
if (factories.size() == 0) {
@ -525,6 +558,7 @@ status_t DrmHal::createPlugin(const uint8_t uuid[16],
mPlugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
if (mPlugin != NULL) {
mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
mPluginV1_2 = drm::V1_2::IDrmPlugin::castFrom(mPlugin);
}
}
}
@ -1063,6 +1097,73 @@ status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
return hResult.isOk() ? err : DEAD_OBJECT;
}
status_t DrmHal::getOfflineLicenseKeySetIds(List<Vector<uint8_t>> &keySetIds) const {
Mutex::Autolock autoLock(mLock);
if (mInitCheck != OK) {
return mInitCheck;
}
if (mPluginV1_2 == NULL) {
return ERROR_DRM_CANNOT_HANDLE;
}
status_t err = UNKNOWN_ERROR;
Return<void> hResult = mPluginV1_2->getOfflineLicenseKeySetIds(
[&](Status status, const hidl_vec<KeySetId>& hKeySetIds) {
if (status == Status::OK) {
keySetIds = toKeySetIds(hKeySetIds);
}
err = toStatusT(status);
}
);
return hResult.isOk() ? err : DEAD_OBJECT;
}
status_t DrmHal::removeOfflineLicense(Vector<uint8_t> const &keySetId) {
Mutex::Autolock autoLock(mLock);
if (mInitCheck != OK) {
return mInitCheck;
}
if (mPluginV1_2 == NULL) {
return ERROR_DRM_CANNOT_HANDLE;
}
Return<Status> status = mPluginV1_2->removeOfflineLicense(toHidlVec(keySetId));
return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
}
status_t DrmHal::getOfflineLicenseState(Vector<uint8_t> const &keySetId,
DrmPlugin::OfflineLicenseState *licenseState) const {
Mutex::Autolock autoLock(mLock);
if (mInitCheck != OK) {
return mInitCheck;
}
if (mPluginV1_2 == NULL) {
return ERROR_DRM_CANNOT_HANDLE;
}
*licenseState = DrmPlugin::kOfflineLicenseStateUnknown;
status_t err = UNKNOWN_ERROR;
Return<void> hResult = mPluginV1_2->getOfflineLicenseState(toHidlVec(keySetId),
[&](Status status, OfflineLicenseState hLicenseState) {
if (status == Status::OK) {
*licenseState = toOfflineLicenseState(hLicenseState);
}
err = toStatusT(status);
}
);
return hResult.isOk() ? err : DEAD_OBJECT;
}
status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
Mutex::Autolock autoLock(mLock);
return getPropertyStringInternal(name, value);

@ -61,7 +61,10 @@ enum {
GET_NUMBER_OF_SESSIONS,
GET_SECURITY_LEVEL,
REMOVE_SECURE_STOP,
GET_SECURE_STOP_IDS
GET_SECURE_STOP_IDS,
GET_OFFLINE_LICENSE_KEYSET_IDS,
REMOVE_OFFLINE_LICENSE,
GET_OFFLINE_LICENSE_STATE
};
struct BpDrm : public BpInterface<IDrm> {
@ -376,6 +379,52 @@ struct BpDrm : public BpInterface<IDrm> {
return reply.readInt32();
}
virtual status_t getOfflineLicenseKeySetIds(List<Vector<uint8_t> > &keySetIds) const {
Parcel data, reply;
data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
status_t status = remote()->transact(GET_OFFLINE_LICENSE_KEYSET_IDS, data, &reply);
if (status != OK) {
return status;
}
keySetIds.clear();
uint32_t count = reply.readInt32();
for (size_t i = 0; i < count; i++) {
Vector<uint8_t> keySetId;
readVector(reply, keySetId);
keySetIds.push_back(keySetId);
}
return reply.readInt32();
}
virtual status_t removeOfflineLicense(Vector<uint8_t> const &keySetId) {
Parcel data, reply;
data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
writeVector(data, keySetId);
status_t status = remote()->transact(REMOVE_OFFLINE_LICENSE, data, &reply);
if (status != OK) {
return status;
}
return reply.readInt32();
}
virtual status_t getOfflineLicenseState(Vector<uint8_t> const &keySetId,
DrmPlugin::OfflineLicenseState *licenseState) const {
Parcel data, reply;
data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
writeVector(data, keySetId);
status_t status = remote()->transact(GET_OFFLINE_LICENSE_STATE, data, &reply);
if (status != OK) {
*licenseState = DrmPlugin::OfflineLicenseState::kOfflineLicenseStateUnknown;
return status;
}
*licenseState = static_cast<DrmPlugin::OfflineLicenseState>(reply.readInt32());
return reply.readInt32();
}
virtual status_t getPropertyString(String8 const &name, String8 &value) const {
Parcel data, reply;
data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
@ -980,6 +1029,45 @@ status_t BnDrm::onTransact(
return OK;
}
case GET_OFFLINE_LICENSE_KEYSET_IDS:
{
CHECK_INTERFACE(IDrm, data, reply);
List<Vector<uint8_t> > keySetIds;
status_t result = getOfflineLicenseKeySetIds(keySetIds);
size_t count = keySetIds.size();
reply->writeInt32(count);
List<Vector<uint8_t> >::iterator iter = keySetIds.begin();
while(iter != keySetIds.end()) {
size_t size = iter->size();
reply->writeInt32(size);
reply->write(iter->array(), iter->size());
iter++;
}
reply->writeInt32(result);
return OK;
}
case REMOVE_OFFLINE_LICENSE:
{
CHECK_INTERFACE(IDrm, data, reply);
Vector<uint8_t> keySetId;
readVector(data, keySetId);
reply->writeInt32(removeOfflineLicense(keySetId));
return OK;
}
case GET_OFFLINE_LICENSE_STATE:
{
CHECK_INTERFACE(IDrm, data, reply);
Vector<uint8_t> keySetId;
readVector(data, keySetId);
DrmPlugin::OfflineLicenseState state;
status_t result = getOfflineLicenseState(keySetId, &state);
reply->writeInt32(static_cast<DrmPlugin::OfflineLicenseState>(state));
reply->writeInt32(result);
return OK;
}
case GET_PROPERTY_STRING:
{
CHECK_INTERFACE(IDrm, data, reply);

@ -17,6 +17,7 @@ cc_test {
shared_libs: [
"android.hardware.drm@1.0",
"android.hardware.drm@1.1",
"android.hardware.drm@1.2",
"libbinder",
"libhidlbase",
"liblog",

@ -23,6 +23,8 @@
#include <android/hardware/drm/1.0/IDrmPluginListener.h>
#include <android/hardware/drm/1.1/IDrmFactory.h>
#include <android/hardware/drm/1.1/IDrmPlugin.h>
#include <android/hardware/drm/1.2/IDrmFactory.h>
#include <android/hardware/drm/1.2/IDrmPlugin.h>
#include <media/MediaAnalyticsItem.h>
#include <mediadrm/DrmMetrics.h>
@ -36,6 +38,7 @@ using drm::V1_0::IDrmFactory;
using drm::V1_0::IDrmPlugin;
using drm::V1_0::IDrmPluginListener;
using drm::V1_0::KeyStatus;
using drm::V1_2::OfflineLicenseState;
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
@ -113,6 +116,11 @@ struct DrmHal : public BnDrm,
virtual status_t getSecurityLevel(Vector<uint8_t> const &sessionId,
DrmPlugin::SecurityLevel *level) const;
virtual status_t getOfflineLicenseKeySetIds(List<Vector<uint8_t>> &keySetIds) const;
virtual status_t removeOfflineLicense(Vector<uint8_t> const &keySetId);
virtual status_t getOfflineLicenseState(Vector<uint8_t> const &keySetId,
DrmPlugin::OfflineLicenseState *licenseState) const;
virtual status_t getPropertyString(String8 const &name, String8 &value ) const;
virtual status_t getPropertyByteArray(String8 const &name,
Vector<uint8_t> &value ) const;
@ -182,6 +190,7 @@ private:
const Vector<sp<IDrmFactory>> mFactories;
sp<IDrmPlugin> mPlugin;
sp<drm::V1_1::IDrmPlugin> mPluginV1_1;
sp<drm::V1_2::IDrmPlugin> mPluginV1_2;
String8 mAppPackageName;
// Mutable to allow modification within GetPropertyByteArray.

@ -75,8 +75,8 @@ struct IDrm : public IInterface {
Vector<uint8_t> &certificate,
Vector<uint8_t> &wrappedKey) = 0;
virtual status_t getSecureStops(List<Vector<uint8_t> > &secureStops) = 0;
virtual status_t getSecureStopIds(List<Vector<uint8_t> > &secureStopIds) = 0;
virtual status_t getSecureStops(List<Vector<uint8_t>> &secureStops) = 0;
virtual status_t getSecureStopIds(List<Vector<uint8_t>> &secureStopIds) = 0;
virtual status_t getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) = 0;
virtual status_t releaseSecureStops(Vector<uint8_t> const &ssRelease) = 0;
@ -91,6 +91,11 @@ struct IDrm : public IInterface {
virtual status_t getSecurityLevel(Vector<uint8_t> const &sessionId,
DrmPlugin::SecurityLevel *level) const = 0;
virtual status_t getOfflineLicenseKeySetIds(List<Vector<uint8_t>> &keySetIds) const = 0;
virtual status_t removeOfflineLicense(Vector<uint8_t> const &keySetId) = 0;
virtual status_t getOfflineLicenseState(Vector<uint8_t> const &keySetId,
DrmPlugin::OfflineLicenseState *licenseState) const = 0;
virtual status_t getPropertyString(String8 const &name, String8 &value) const = 0;
virtual status_t getPropertyByteArray(String8 const &name,
Vector<uint8_t> &value) const = 0;

@ -11,6 +11,7 @@ cc_test {
"libutils",
"android.hardware.drm@1.0",
"android.hardware.drm@1.1",
"android.hardware.drm@1.2",
],
compile_multilib: "32",

@ -29,7 +29,8 @@ LOCAL_SHARED_LIBRARIES:= \
libhidlmemory \
libhidltransport \
android.hardware.drm@1.0 \
android.hardware.drm@1.1
android.hardware.drm@1.1 \
android.hardware.drm@1.2
LOCAL_CFLAGS += -Wall -Wextra -Werror

Loading…
Cancel
Save