Add new offline management APIs to MediaDrm
bug:110838441
bug:117570956
bug:116252891
test:cts android.media.cts.MediaDrmClearkeyTest#testOfflineKeyManagement
Change-Id: I2ee86afbd1a0ae793454c2e81f3267aaf10bade7
diff --git a/drm/libmediadrm/Android.bp b/drm/libmediadrm/Android.bp
index 4991e50..94f9e02 100644
--- a/drm/libmediadrm/Android.bp
+++ b/drm/libmediadrm/Android.bp
@@ -32,6 +32,7 @@
"libutils",
"android.hardware.drm@1.0",
"android.hardware.drm@1.1",
+ "android.hardware.drm@1.2",
"libhidlallocatorutils",
"libhidlbase",
"libhidltransport",
diff --git a/drm/libmediadrm/DrmHal.cpp b/drm/libmediadrm/DrmHal.cpp
index ce9dc38..14ff493 100644
--- a/drm/libmediadrm/DrmHal.cpp
+++ b/drm/libmediadrm/DrmHal.cpp
@@ -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::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::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 @@
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 @@
}
mPlugin.clear();
mPluginV1_1.clear();
+ mPluginV1_2.clear();
}
Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
@@ -333,6 +356,16 @@
}
}
);
+ manager->listByInterface(drm::V1_2::IDrmFactory::descriptor,
+ [&factories](const hidl_vec<hidl_string> ®istered) {
+ 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 @@
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 @@
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);
diff --git a/drm/libmediadrm/IDrm.cpp b/drm/libmediadrm/IDrm.cpp
index 509961f..8c26317 100644
--- a/drm/libmediadrm/IDrm.cpp
+++ b/drm/libmediadrm/IDrm.cpp
@@ -61,7 +61,10 @@
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 @@
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 @@
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);
diff --git a/drm/libmediadrm/tests/Android.bp b/drm/libmediadrm/tests/Android.bp
index 66c906f..dcd59b7 100644
--- a/drm/libmediadrm/tests/Android.bp
+++ b/drm/libmediadrm/tests/Android.bp
@@ -17,6 +17,7 @@
shared_libs: [
"android.hardware.drm@1.0",
"android.hardware.drm@1.1",
+ "android.hardware.drm@1.2",
"libbinder",
"libhidlbase",
"liblog",
diff --git a/media/libmedia/include/media/DrmHal.h b/media/libmedia/include/media/DrmHal.h
index f267f76..3302982 100644
--- a/media/libmedia/include/media/DrmHal.h
+++ b/media/libmedia/include/media/DrmHal.h
@@ -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::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 @@
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 @@
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.
diff --git a/media/libmedia/include/media/IDrm.h b/media/libmedia/include/media/IDrm.h
index 8e9eb3a..49166c6 100644
--- a/media/libmedia/include/media/IDrm.h
+++ b/media/libmedia/include/media/IDrm.h
@@ -75,8 +75,8 @@
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 @@
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;
diff --git a/media/libmediaplayerservice/tests/Android.bp b/media/libmediaplayerservice/tests/Android.bp
index e86b68a..4749a8b 100644
--- a/media/libmediaplayerservice/tests/Android.bp
+++ b/media/libmediaplayerservice/tests/Android.bp
@@ -11,6 +11,7 @@
"libutils",
"android.hardware.drm@1.0",
"android.hardware.drm@1.1",
+ "android.hardware.drm@1.2",
],
compile_multilib: "32",
diff --git a/services/mediadrm/Android.mk b/services/mediadrm/Android.mk
index e870965..227a29d 100644
--- a/services/mediadrm/Android.mk
+++ b/services/mediadrm/Android.mk
@@ -29,7 +29,8 @@
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