summaryrefslogtreecommitdiffstats
path: root/drm
diff options
context:
space:
mode:
Diffstat (limited to 'drm')
-rw-r--r--drm/common/Android.bp2
-rw-r--r--drm/common/DrmEngineBase.cpp20
-rw-r--r--drm/common/IDrmManagerService.cpp107
-rw-r--r--drm/common/include/DrmEngineBase.h47
-rw-r--r--drm/common/include/IDrmEngine.h20
-rw-r--r--drm/common/include/IDrmManagerService.h41
-rw-r--r--drm/drmserver/DrmManager.cpp42
-rw-r--r--drm/drmserver/DrmManager.h22
-rw-r--r--drm/drmserver/DrmManagerService.cpp45
-rw-r--r--drm/drmserver/DrmManagerService.h24
-rw-r--r--drm/libdrmframework/Android.bp1
-rw-r--r--drm/libdrmframework/DrmManagerClientImpl.cpp16
-rw-r--r--drm/libdrmframework/plugins/common/Android.bp1
-rw-r--r--drm/libdrmframework/plugins/forward-lock/Android.bp4
-rw-r--r--drm/libdrmframework/plugins/forward-lock/FwdLockEngine/Android.bp3
-rw-r--r--drm/libdrmframework/plugins/forward-lock/FwdLockEngine/include/FwdLockEngine.h32
-rw-r--r--drm/libdrmframework/plugins/forward-lock/FwdLockEngine/src/FwdLockEngine.cpp56
-rw-r--r--drm/libdrmframework/plugins/forward-lock/internal-format/Android.bp5
-rw-r--r--drm/libdrmframework/plugins/passthru/include/DrmPassthruPlugIn.h24
-rw-r--r--drm/libdrmframework/plugins/passthru/src/DrmPassthruPlugIn.cpp31
-rw-r--r--drm/libmediadrm/Android.bp8
-rw-r--r--drm/libmediadrm/CryptoHal.cpp73
-rw-r--r--drm/libmediadrm/DrmHal.cpp533
-rw-r--r--drm/libmediadrm/DrmMetrics.cpp2
-rw-r--r--drm/libmediadrm/IDrm.cpp111
-rw-r--r--drm/libmediadrm/PluginMetricsReporting.cpp12
-rw-r--r--drm/libmediadrm/tests/Android.bp2
-rw-r--r--drm/libmediadrm/tests/DrmMetrics_test.cpp2
-rw-r--r--drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp44
-rw-r--r--drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h11
-rw-r--r--drm/mediacas/plugins/mock/MockCasPlugin.cpp23
-rw-r--r--drm/mediacas/plugins/mock/MockCasPlugin.h11
-rw-r--r--drm/mediadrm/Android.bp1
-rw-r--r--drm/mediadrm/plugins/clearkey/common/Utils.cpp14
-rw-r--r--drm/mediadrm/plugins/clearkey/common/include/Utils.h6
-rw-r--r--drm/mediadrm/plugins/clearkey/default/Android.bp4
-rw-r--r--drm/mediadrm/plugins/clearkey/hidl/AesCtrDecryptor.cpp4
-rw-r--r--drm/mediadrm/plugins/clearkey/hidl/Android.bp33
-rw-r--r--drm/mediadrm/plugins/clearkey/hidl/Base64.cpp4
-rw-r--r--drm/mediadrm/plugins/clearkey/hidl/Buffer.cpp4
-rw-r--r--drm/mediadrm/plugins/clearkey/hidl/CreatePluginFactories.cpp4
-rw-r--r--drm/mediadrm/plugins/clearkey/hidl/CryptoFactory.cpp4
-rw-r--r--drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp76
-rw-r--r--drm/mediadrm/plugins/clearkey/hidl/DeviceFiles.cpp252
-rw-r--r--drm/mediadrm/plugins/clearkey/hidl/DrmFactory.cpp12
-rw-r--r--drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp346
-rw-r--r--drm/mediadrm/plugins/clearkey/hidl/InitDataParser.cpp38
-rw-r--r--drm/mediadrm/plugins/clearkey/hidl/JsonWebKey.cpp11
-rw-r--r--drm/mediadrm/plugins/clearkey/hidl/MemoryFileSystem.cpp92
-rw-r--r--drm/mediadrm/plugins/clearkey/hidl/Session.cpp18
-rw-r--r--drm/mediadrm/plugins/clearkey/hidl/SessionLibrary.cpp10
-rw-r--r--drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.1-service.clearkey.rc6
-rw-r--r--drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.2-service-lazy.clearkey.rc14
-rw-r--r--drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.2-service.clearkey.rc12
-rw-r--r--drm/mediadrm/plugins/clearkey/hidl/include/AesCtrDecryptor.h4
-rw-r--r--drm/mediadrm/plugins/clearkey/hidl/include/Base64.h4
-rw-r--r--drm/mediadrm/plugins/clearkey/hidl/include/Buffer.h4
-rw-r--r--drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyDrmProperties.h16
-rw-r--r--drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyTypes.h7
-rw-r--r--drm/mediadrm/plugins/clearkey/hidl/include/CreatePluginFactories.h12
-rw-r--r--drm/mediadrm/plugins/clearkey/hidl/include/CryptoFactory.h8
-rw-r--r--drm/mediadrm/plugins/clearkey/hidl/include/CryptoPlugin.h37
-rw-r--r--drm/mediadrm/plugins/clearkey/hidl/include/DeviceFiles.h71
-rw-r--r--drm/mediadrm/plugins/clearkey/hidl/include/DrmFactory.h12
-rw-r--r--drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h150
-rw-r--r--drm/mediadrm/plugins/clearkey/hidl/include/InitDataParser.h9
-rw-r--r--drm/mediadrm/plugins/clearkey/hidl/include/JsonWebKey.h4
-rw-r--r--drm/mediadrm/plugins/clearkey/hidl/include/MemoryFileSystem.h68
-rw-r--r--drm/mediadrm/plugins/clearkey/hidl/include/Session.h26
-rw-r--r--drm/mediadrm/plugins/clearkey/hidl/include/SessionLibrary.h4
-rw-r--r--drm/mediadrm/plugins/clearkey/hidl/include/TypeConvert.h15
-rw-r--r--drm/mediadrm/plugins/clearkey/hidl/protos/DeviceFiles.proto47
-rw-r--r--drm/mediadrm/plugins/clearkey/hidl/service.cpp18
-rw-r--r--drm/mediadrm/plugins/clearkey/hidl/serviceLazy.cpp50
74 files changed, 2224 insertions, 682 deletions
diff --git a/drm/common/Android.bp b/drm/common/Android.bp
index 1552c3f340..272684c29d 100644
--- a/drm/common/Android.bp
+++ b/drm/common/Android.bp
@@ -35,7 +35,7 @@ cc_library_static {
cflags: ["-Wall", "-Werror"],
- static_libs: ["libbinder"],
+ shared_libs: ["libbinder"],
export_include_dirs: ["include"],
}
diff --git a/drm/common/DrmEngineBase.cpp b/drm/common/DrmEngineBase.cpp
index f734905b78..aec5959d82 100644
--- a/drm/common/DrmEngineBase.cpp
+++ b/drm/common/DrmEngineBase.cpp
@@ -79,12 +79,12 @@ int DrmEngineBase::checkRightsStatus(int uniqueId, const String8& path, int acti
}
status_t DrmEngineBase::consumeRights(
- int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) {
+ int uniqueId, sp<DecryptHandle>& decryptHandle, int action, bool reserve) {
return onConsumeRights(uniqueId, decryptHandle, action, reserve);
}
status_t DrmEngineBase::setPlaybackStatus(
- int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position) {
+ int uniqueId, sp<DecryptHandle>& decryptHandle, int playbackStatus, int64_t position) {
return onSetPlaybackStatus(uniqueId, decryptHandle, playbackStatus, position);
}
@@ -120,7 +120,7 @@ DrmSupportInfo* DrmEngineBase::getSupportInfo(int uniqueId) {
}
status_t DrmEngineBase::openDecryptSession(
- int uniqueId, DecryptHandle* decryptHandle,
+ int uniqueId, sp<DecryptHandle>& decryptHandle,
int fd, off64_t offset, off64_t length, const char* mime) {
if (!mime || mime[0] == '\0') {
@@ -131,7 +131,7 @@ status_t DrmEngineBase::openDecryptSession(
}
status_t DrmEngineBase::openDecryptSession(
- int uniqueId, DecryptHandle* decryptHandle,
+ int uniqueId, sp<DecryptHandle>& decryptHandle,
const char* uri, const char* mime) {
if (!mime || mime[0] == '\0') {
return onOpenDecryptSession(uniqueId, decryptHandle, uri);
@@ -139,33 +139,33 @@ status_t DrmEngineBase::openDecryptSession(
return onOpenDecryptSession(uniqueId, decryptHandle, uri, mime);
}
-status_t DrmEngineBase::openDecryptSession(int uniqueId, DecryptHandle* decryptHandle,
+status_t DrmEngineBase::openDecryptSession(int uniqueId, sp<DecryptHandle>& decryptHandle,
const DrmBuffer& buf, const String8& mimeType) {
return onOpenDecryptSession(uniqueId, decryptHandle, buf, mimeType);
}
-status_t DrmEngineBase::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
+status_t DrmEngineBase::closeDecryptSession(int uniqueId, sp<DecryptHandle>& decryptHandle) {
return onCloseDecryptSession(uniqueId, decryptHandle);
}
status_t DrmEngineBase::initializeDecryptUnit(
- int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId, const DrmBuffer* headerInfo) {
+ int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId, const DrmBuffer* headerInfo) {
return onInitializeDecryptUnit(uniqueId, decryptHandle, decryptUnitId, headerInfo);
}
status_t DrmEngineBase::decrypt(
- int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+ int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId,
const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
return onDecrypt(uniqueId, decryptHandle, decryptUnitId, encBuffer, decBuffer, IV);
}
status_t DrmEngineBase::finalizeDecryptUnit(
- int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) {
+ int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId) {
return onFinalizeDecryptUnit(uniqueId, decryptHandle, decryptUnitId);
}
ssize_t DrmEngineBase::pread(
- int uniqueId, DecryptHandle* decryptHandle, void* buffer, ssize_t numBytes, off64_t offset) {
+ int uniqueId, sp<DecryptHandle>& decryptHandle, void* buffer, ssize_t numBytes, off64_t offset) {
return onPread(uniqueId, decryptHandle, buffer, numBytes, offset);
}
diff --git a/drm/common/IDrmManagerService.cpp b/drm/common/IDrmManagerService.cpp
index 44f98dd3ce..a6d33b0fa4 100644
--- a/drm/common/IDrmManagerService.cpp
+++ b/drm/common/IDrmManagerService.cpp
@@ -39,7 +39,7 @@
using namespace android;
static void writeDecryptHandleToParcelData(
- const DecryptHandle* handle, Parcel* data) {
+ const sp<DecryptHandle>& handle, Parcel* data) {
data->writeInt32(handle->decryptId);
data->writeString8(handle->mimeType);
data->writeInt32(handle->decryptApiType);
@@ -67,7 +67,7 @@ static void writeDecryptHandleToParcelData(
}
static void readDecryptHandleFromParcelData(
- DecryptHandle* handle, const Parcel& data) {
+ sp<DecryptHandle>& handle, const Parcel& data) {
if (0 == data.dataAvail()) {
return;
}
@@ -99,7 +99,7 @@ static void readDecryptHandleFromParcelData(
}
}
-static void clearDecryptHandle(DecryptHandle* handle) {
+static void clearDecryptHandle(sp<DecryptHandle> &handle) {
if (handle == NULL) {
return;
}
@@ -414,7 +414,7 @@ int BpDrmManagerService::checkRightsStatus(int uniqueId, const String8& path, in
}
status_t BpDrmManagerService::consumeRights(
- int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) {
+ int uniqueId, sp<DecryptHandle>& decryptHandle, int action, bool reserve) {
ALOGV("consumeRights");
Parcel data, reply;
@@ -431,7 +431,7 @@ status_t BpDrmManagerService::consumeRights(
}
status_t BpDrmManagerService::setPlaybackStatus(
- int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position) {
+ int uniqueId, sp<DecryptHandle>& decryptHandle, int playbackStatus, int64_t position) {
ALOGV("setPlaybackStatus");
Parcel data, reply;
@@ -603,7 +603,7 @@ status_t BpDrmManagerService::getAllSupportInfo(
return reply.readInt32();
}
-DecryptHandle* BpDrmManagerService::openDecryptSession(
+sp<DecryptHandle> BpDrmManagerService::openDecryptSession(
int uniqueId, int fd, off64_t offset, off64_t length, const char* mime) {
ALOGV("Entering BpDrmManagerService::openDecryptSession");
Parcel data, reply;
@@ -621,7 +621,7 @@ DecryptHandle* BpDrmManagerService::openDecryptSession(
remote()->transact(OPEN_DECRYPT_SESSION, data, &reply);
- DecryptHandle* handle = NULL;
+ sp<DecryptHandle> handle;
if (0 != reply.dataAvail()) {
handle = new DecryptHandle();
readDecryptHandleFromParcelData(handle, reply);
@@ -629,7 +629,7 @@ DecryptHandle* BpDrmManagerService::openDecryptSession(
return handle;
}
-DecryptHandle* BpDrmManagerService::openDecryptSession(
+sp<DecryptHandle> BpDrmManagerService::openDecryptSession(
int uniqueId, const char* uri, const char* mime) {
ALOGV("Entering BpDrmManagerService::openDecryptSession: mime=%s", mime? mime: "NULL");
@@ -646,7 +646,7 @@ DecryptHandle* BpDrmManagerService::openDecryptSession(
remote()->transact(OPEN_DECRYPT_SESSION_FROM_URI, data, &reply);
- DecryptHandle* handle = NULL;
+ sp<DecryptHandle> handle;
if (0 != reply.dataAvail()) {
handle = new DecryptHandle();
readDecryptHandleFromParcelData(handle, reply);
@@ -656,7 +656,7 @@ DecryptHandle* BpDrmManagerService::openDecryptSession(
return handle;
}
-DecryptHandle* BpDrmManagerService::openDecryptSession(
+sp<DecryptHandle> BpDrmManagerService::openDecryptSession(
int uniqueId, const DrmBuffer& buf, const String8& mimeType) {
ALOGV("Entering BpDrmManagerService::openDecryptSession");
Parcel data, reply;
@@ -673,7 +673,7 @@ DecryptHandle* BpDrmManagerService::openDecryptSession(
remote()->transact(OPEN_DECRYPT_SESSION_FOR_STREAMING, data, &reply);
- DecryptHandle* handle = NULL;
+ sp<DecryptHandle> handle;
if (0 != reply.dataAvail()) {
handle = new DecryptHandle();
readDecryptHandleFromParcelData(handle, reply);
@@ -683,7 +683,7 @@ DecryptHandle* BpDrmManagerService::openDecryptSession(
return handle;
}
-status_t BpDrmManagerService::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
+status_t BpDrmManagerService::closeDecryptSession(int uniqueId, sp<DecryptHandle>& decryptHandle) {
ALOGV("closeDecryptSession");
Parcel data, reply;
@@ -698,7 +698,7 @@ status_t BpDrmManagerService::closeDecryptSession(int uniqueId, DecryptHandle* d
}
status_t BpDrmManagerService::initializeDecryptUnit(
- int uniqueId, DecryptHandle* decryptHandle,
+ int uniqueId, sp<DecryptHandle>& decryptHandle,
int decryptUnitId, const DrmBuffer* headerInfo) {
ALOGV("initializeDecryptUnit");
Parcel data, reply;
@@ -718,7 +718,7 @@ status_t BpDrmManagerService::initializeDecryptUnit(
}
status_t BpDrmManagerService::decrypt(
- int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+ int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId,
const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
ALOGV("decrypt");
Parcel data, reply;
@@ -754,7 +754,7 @@ status_t BpDrmManagerService::decrypt(
}
status_t BpDrmManagerService::finalizeDecryptUnit(
- int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) {
+ int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId) {
ALOGV("finalizeDecryptUnit");
Parcel data, reply;
@@ -770,7 +770,7 @@ status_t BpDrmManagerService::finalizeDecryptUnit(
}
ssize_t BpDrmManagerService::pread(
- int uniqueId, DecryptHandle* decryptHandle, void* buffer,
+ int uniqueId, sp<DecryptHandle>& decryptHandle, void* buffer,
ssize_t numBytes, off64_t offset) {
ALOGV("read");
Parcel data, reply;
@@ -1128,16 +1128,16 @@ status_t BnDrmManagerService::onTransact(
const int uniqueId = data.readInt32();
- DecryptHandle handle;
- readDecryptHandleFromParcelData(&handle, data);
+ sp<DecryptHandle> handle = new DecryptHandle();
+ readDecryptHandleFromParcelData(handle, data);
const int action = data.readInt32();
const bool reserve = static_cast<bool>(data.readInt32());
const status_t status
- = consumeRights(uniqueId, &handle, action, reserve);
+ = consumeRights(uniqueId, handle, action, reserve);
reply->writeInt32(status);
- clearDecryptHandle(&handle);
+ clearDecryptHandle(handle);
return DRM_NO_ERROR;
}
@@ -1148,16 +1148,16 @@ status_t BnDrmManagerService::onTransact(
const int uniqueId = data.readInt32();
- DecryptHandle handle;
- readDecryptHandleFromParcelData(&handle, data);
+ sp<DecryptHandle> handle = new DecryptHandle();
+ readDecryptHandleFromParcelData(handle, data);
const int playbackStatus = data.readInt32();
const int64_t position = data.readInt64();
const status_t status
- = setPlaybackStatus(uniqueId, &handle, playbackStatus, position);
+ = setPlaybackStatus(uniqueId, handle, playbackStatus, position);
reply->writeInt32(status);
- clearDecryptHandle(&handle);
+ clearDecryptHandle(handle);
return DRM_NO_ERROR;
}
@@ -1329,13 +1329,13 @@ status_t BnDrmManagerService::onTransact(
const off64_t length = data.readInt64();
const String8 mime = data.readString8();
- DecryptHandle* handle
+ sp<DecryptHandle> handle
= openDecryptSession(uniqueId, fd, offset, length, mime.string());
- if (NULL != handle) {
- writeDecryptHandleToParcelData(handle, reply);
+ if (NULL != handle.get()) {
+ writeDecryptHandleToParcelData(handle.get(), reply);
clearDecryptHandle(handle);
- delete handle; handle = NULL;
+ handle.clear();
}
return DRM_NO_ERROR;
}
@@ -1349,13 +1349,13 @@ status_t BnDrmManagerService::onTransact(
const String8 uri = data.readString8();
const String8 mime = data.readString8();
- DecryptHandle* handle = openDecryptSession(uniqueId, uri.string(), mime.string());
+ sp<DecryptHandle> handle = openDecryptSession(uniqueId, uri.string(), mime.string());
- if (NULL != handle) {
- writeDecryptHandleToParcelData(handle, reply);
+ if (NULL != handle.get()) {
+ writeDecryptHandleToParcelData(handle.get(), reply);
clearDecryptHandle(handle);
- delete handle; handle = NULL;
+ handle.clear();
} else {
ALOGV("NULL decryptHandle is returned");
}
@@ -1373,13 +1373,12 @@ status_t BnDrmManagerService::onTransact(
bufferSize);
const String8 mimeType(data.readString8());
- DecryptHandle* handle = openDecryptSession(uniqueId, buf, mimeType);
+ sp<DecryptHandle> handle = openDecryptSession(uniqueId, buf, mimeType);
if (handle != NULL) {
writeDecryptHandleToParcelData(handle, reply);
clearDecryptHandle(handle);
- delete handle;
- handle = NULL;
+ handle.clear();
} else {
ALOGV("NULL decryptHandle is returned");
}
@@ -1393,7 +1392,7 @@ status_t BnDrmManagerService::onTransact(
const int uniqueId = data.readInt32();
- DecryptHandle* handle = new DecryptHandle();
+ sp<DecryptHandle> handle = new DecryptHandle();
readDecryptHandleFromParcelData(handle, data);
const status_t status = closeDecryptSession(uniqueId, handle);
@@ -1408,8 +1407,8 @@ status_t BnDrmManagerService::onTransact(
const int uniqueId = data.readInt32();
- DecryptHandle handle;
- readDecryptHandleFromParcelData(&handle, data);
+ sp<DecryptHandle> handle = new DecryptHandle();
+ readDecryptHandleFromParcelData(handle, data);
const int decryptUnitId = data.readInt32();
@@ -1417,17 +1416,17 @@ status_t BnDrmManagerService::onTransact(
const uint32_t bufferSize = data.readInt32();
if (bufferSize > data.dataAvail()) {
reply->writeInt32(BAD_VALUE);
- clearDecryptHandle(&handle);
+ clearDecryptHandle(handle);
return DRM_NO_ERROR;
}
DrmBuffer* headerInfo = NULL;
headerInfo = new DrmBuffer((char *)data.readInplace(bufferSize), bufferSize);
const status_t status
- = initializeDecryptUnit(uniqueId, &handle, decryptUnitId, headerInfo);
+ = initializeDecryptUnit(uniqueId, handle, decryptUnitId, headerInfo);
reply->writeInt32(status);
- clearDecryptHandle(&handle);
+ clearDecryptHandle(handle);
delete headerInfo; headerInfo = NULL;
return DRM_NO_ERROR;
}
@@ -1439,8 +1438,8 @@ status_t BnDrmManagerService::onTransact(
const int uniqueId = data.readInt32();
- DecryptHandle handle;
- readDecryptHandleFromParcelData(&handle, data);
+ sp<DecryptHandle> handle = new DecryptHandle;
+ readDecryptHandleFromParcelData(handle, data);
const int decryptUnitId = data.readInt32();
const uint32_t decBufferSize = data.readInt32();
@@ -1450,7 +1449,7 @@ status_t BnDrmManagerService::onTransact(
decBufferSize > MAX_BINDER_TRANSACTION_SIZE) {
reply->writeInt32(BAD_VALUE);
reply->writeInt32(0);
- clearDecryptHandle(&handle);
+ clearDecryptHandle(handle);
return DRM_NO_ERROR;
}
@@ -1470,7 +1469,7 @@ status_t BnDrmManagerService::onTransact(
}
const status_t status
- = decrypt(uniqueId, &handle, decryptUnitId, encBuffer, &decBuffer, IV);
+ = decrypt(uniqueId, handle, decryptUnitId, encBuffer, &decBuffer, IV);
reply->writeInt32(status);
@@ -1480,7 +1479,7 @@ status_t BnDrmManagerService::onTransact(
reply->write(decBuffer->data, size);
}
- clearDecryptHandle(&handle);
+ clearDecryptHandle(handle);
delete encBuffer; encBuffer = NULL;
delete decBuffer; decBuffer = NULL;
delete [] buffer; buffer = NULL;
@@ -1495,13 +1494,13 @@ status_t BnDrmManagerService::onTransact(
const int uniqueId = data.readInt32();
- DecryptHandle handle;
- readDecryptHandleFromParcelData(&handle, data);
+ sp<DecryptHandle> handle = new DecryptHandle();
+ readDecryptHandleFromParcelData(handle, data);
- const status_t status = finalizeDecryptUnit(uniqueId, &handle, data.readInt32());
+ const status_t status = finalizeDecryptUnit(uniqueId, handle, data.readInt32());
reply->writeInt32(status);
- clearDecryptHandle(&handle);
+ clearDecryptHandle(handle);
return DRM_NO_ERROR;
}
@@ -1512,8 +1511,8 @@ status_t BnDrmManagerService::onTransact(
const int uniqueId = data.readInt32();
- DecryptHandle handle;
- readDecryptHandleFromParcelData(&handle, data);
+ sp<DecryptHandle> handle = new DecryptHandle();
+ readDecryptHandleFromParcelData(handle, data);
const uint32_t numBytes = data.readInt32();
if (numBytes > MAX_BINDER_TRANSACTION_SIZE) {
@@ -1524,13 +1523,13 @@ status_t BnDrmManagerService::onTransact(
const off64_t offset = data.readInt64();
- ssize_t result = pread(uniqueId, &handle, buffer, numBytes, offset);
+ ssize_t result = pread(uniqueId, handle, buffer, numBytes, offset);
reply->writeInt32(result);
if (0 < result) {
reply->write(buffer, result);
}
- clearDecryptHandle(&handle);
+ clearDecryptHandle(handle);
delete [] buffer, buffer = NULL;
return DRM_NO_ERROR;
}
diff --git a/drm/common/include/DrmEngineBase.h b/drm/common/include/DrmEngineBase.h
index 417107f1bd..73f11a4d2b 100644
--- a/drm/common/include/DrmEngineBase.h
+++ b/drm/common/include/DrmEngineBase.h
@@ -59,10 +59,11 @@ public:
int checkRightsStatus(int uniqueId, const String8& path, int action);
- status_t consumeRights(int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve);
+ status_t consumeRights(int uniqueId, sp<DecryptHandle>& decryptHandle, int action,
+ bool reserve);
status_t setPlaybackStatus(
- int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position);
+ int uniqueId, sp<DecryptHandle>& decryptHandle, int playbackStatus, int64_t position);
bool validateAction(
int uniqueId, const String8& path, int action, const ActionDescription& description);
@@ -80,27 +81,28 @@ public:
DrmSupportInfo* getSupportInfo(int uniqueId);
status_t openDecryptSession(
- int uniqueId, DecryptHandle* decryptHandle,
+ int uniqueId, sp<DecryptHandle>& decryptHandle,
int fd, off64_t offset, off64_t length, const char* mime);
status_t openDecryptSession(
- int uniqueId, DecryptHandle* decryptHandle,
+ int uniqueId, sp<DecryptHandle>& decryptHandle,
const char* uri, const char* mime);
- status_t openDecryptSession(int uniqueId, DecryptHandle* decryptHandle,
+ status_t openDecryptSession(int uniqueId, sp<DecryptHandle>& decryptHandle,
const DrmBuffer& buf, const String8& mimeType);
- status_t closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
+ status_t closeDecryptSession(int uniqueId, sp<DecryptHandle>& decryptHandle);
- status_t initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+ status_t initializeDecryptUnit(int uniqueId, sp<DecryptHandle>& decryptHandle,
int decryptUnitId, const DrmBuffer* headerInfo);
- status_t decrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+ status_t decrypt(int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId,
const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV);
- status_t finalizeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId);
+ status_t finalizeDecryptUnit(int uniqueId, sp<DecryptHandle>& decryptHandle,
+ int decryptUnitId);
- ssize_t pread(int uniqueId, DecryptHandle* decryptHandle,
+ ssize_t pread(int uniqueId, sp<DecryptHandle>& decryptHandle,
void* buffer, ssize_t numBytes, off64_t offset);
protected:
@@ -265,7 +267,7 @@ protected:
* @return status_t
* Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
*/
- virtual status_t onConsumeRights(int uniqueId, DecryptHandle* decryptHandle,
+ virtual status_t onConsumeRights(int uniqueId, sp<DecryptHandle>& decryptHandle,
int action, bool reserve) = 0;
/**
@@ -280,7 +282,8 @@ protected:
* Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
*/
virtual status_t onSetPlaybackStatus(
- int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position) = 0;
+ int uniqueId, sp<DecryptHandle>& decryptHandle, int playbackStatus,
+ int64_t position) = 0;
/**
* Validates whether an action on the DRM content is allowed or not.
@@ -381,7 +384,7 @@ protected:
* DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
*/
virtual status_t onOpenDecryptSession(
- int uniqueId, DecryptHandle* decryptHandle,
+ int uniqueId, sp<DecryptHandle>& decryptHandle,
int fd, off64_t offset, off64_t length) = 0;
/**
@@ -398,7 +401,7 @@ protected:
* DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
*/
virtual status_t onOpenDecryptSession(
- int /* uniqueId */, DecryptHandle* /* decryptHandle */,
+ int /* uniqueId */, sp<DecryptHandle>& /* decryptHandle */,
int /* fd */, off64_t /* offset */, off64_t /* length */,
const char* /* mime */) {
@@ -415,7 +418,7 @@ protected:
* DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
*/
virtual status_t onOpenDecryptSession(
- int uniqueId, DecryptHandle* decryptHandle,
+ int uniqueId, sp<DecryptHandle>& decryptHandle,
const char* uri) = 0;
/**
@@ -430,7 +433,7 @@ protected:
* DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
*/
virtual status_t onOpenDecryptSession(
- int /* uniqueId */, DecryptHandle* /* decryptHandle */,
+ int /* uniqueId */, sp<DecryptHandle>& /* decryptHandle */,
const char* /* uri */, const char* /* mime */) {
return DRM_ERROR_CANNOT_HANDLE;
@@ -447,7 +450,7 @@ protected:
* DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
*/
virtual status_t onOpenDecryptSession(int /* uniqueId */,
- DecryptHandle* /* decryptHandle */,
+ sp<DecryptHandle>& /* decryptHandle */,
const DrmBuffer& /* buf */,
const String8& /* mimeType */) {
return DRM_ERROR_CANNOT_HANDLE;
@@ -461,7 +464,7 @@ protected:
* @return status_t
* Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
*/
- virtual status_t onCloseDecryptSession(int uniqueId, DecryptHandle* decryptHandle) = 0;
+ virtual status_t onCloseDecryptSession(int uniqueId, sp<DecryptHandle>& decryptHandle) = 0;
/**
* Initialize decryption for the given unit of the protected content
@@ -473,7 +476,7 @@ protected:
* @return status_t
* Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
*/
- virtual status_t onInitializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+ virtual status_t onInitializeDecryptUnit(int uniqueId, sp<DecryptHandle>& decryptHandle,
int decryptUnitId, const DrmBuffer* headerInfo) = 0;
/**
@@ -493,7 +496,7 @@ protected:
* DRM_ERROR_SESSION_NOT_OPENED, DRM_ERROR_DECRYPT_UNIT_NOT_INITIALIZED,
* DRM_ERROR_DECRYPT for failure.
*/
- virtual status_t onDecrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+ virtual status_t onDecrypt(int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId,
const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) = 0;
/**
@@ -506,7 +509,7 @@ protected:
* Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
*/
virtual status_t onFinalizeDecryptUnit(
- int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) = 0;
+ int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId) = 0;
/**
* Reads the specified number of bytes from an open DRM file.
@@ -519,7 +522,7 @@ protected:
*
* @return Number of bytes read. Returns -1 for Failure.
*/
- virtual ssize_t onPread(int uniqueId, DecryptHandle* decryptHandle,
+ virtual ssize_t onPread(int uniqueId, sp<DecryptHandle>& decryptHandle,
void* buffer, ssize_t numBytes, off64_t offset) = 0;
};
diff --git a/drm/common/include/IDrmEngine.h b/drm/common/include/IDrmEngine.h
index acc8ed9433..1837a116d2 100644
--- a/drm/common/include/IDrmEngine.h
+++ b/drm/common/include/IDrmEngine.h
@@ -210,7 +210,7 @@ public:
* Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
*/
virtual status_t consumeRights(
- int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) = 0;
+ int uniqueId, sp<DecryptHandle>& decryptHandle, int action, bool reserve) = 0;
/**
* Informs the DRM Engine about the playback actions performed on the DRM files.
@@ -223,7 +223,7 @@ public:
* @return status_t
* Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
*/
- virtual status_t setPlaybackStatus(int uniqueId, DecryptHandle* decryptHandle,
+ virtual status_t setPlaybackStatus(int uniqueId, sp<DecryptHandle>& decryptHandle,
int playbackStatus, int64_t position) = 0;
/**
@@ -327,7 +327,7 @@ public:
* DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
*/
virtual status_t openDecryptSession(
- int uniqueId, DecryptHandle* decryptHandle,
+ int uniqueId, sp<DecryptHandle>& decryptHandle,
int fd, off64_t offset, off64_t length, const char* mime) = 0;
/**
@@ -342,7 +342,7 @@ public:
* DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
*/
virtual status_t openDecryptSession(
- int uniqueId, DecryptHandle* decryptHandle,
+ int uniqueId, sp<DecryptHandle>& decryptHandle,
const char* uri, const char* mime) = 0;
/**
@@ -355,7 +355,7 @@ public:
* @return
* DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
*/
- virtual status_t openDecryptSession(int uniqueId, DecryptHandle* decryptHandle,
+ virtual status_t openDecryptSession(int uniqueId, sp<DecryptHandle>& decryptHandle,
const DrmBuffer& buf, const String8& mimeType) = 0;
/**
@@ -366,7 +366,7 @@ public:
* @return status_t
* Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
*/
- virtual status_t closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) = 0;
+ virtual status_t closeDecryptSession(int uniqueId, sp<DecryptHandle>& decryptHandle) = 0;
/**
* Initialize decryption for the given unit of the protected content
@@ -378,7 +378,7 @@ public:
* @return status_t
* Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
*/
- virtual status_t initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+ virtual status_t initializeDecryptUnit(int uniqueId, sp<DecryptHandle>& decryptHandle,
int decryptUnitId, const DrmBuffer* headerInfo) = 0;
/**
@@ -398,7 +398,7 @@ public:
* DRM_ERROR_SESSION_NOT_OPENED, DRM_ERROR_DECRYPT_UNIT_NOT_INITIALIZED,
* DRM_ERROR_DECRYPT for failure.
*/
- virtual status_t decrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+ virtual status_t decrypt(int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId,
const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) = 0;
/**
@@ -411,7 +411,7 @@ public:
* Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
*/
virtual status_t finalizeDecryptUnit(
- int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) = 0;
+ int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId) = 0;
/**
* Reads the specified number of bytes from an open DRM file.
@@ -424,7 +424,7 @@ public:
*
* @return Number of bytes read. Returns -1 for Failure.
*/
- virtual ssize_t pread(int uniqueId, DecryptHandle* decryptHandle,
+ virtual ssize_t pread(int uniqueId, sp<DecryptHandle>& decryptHandle,
void* buffer, ssize_t numBytes, off64_t offset) = 0;
};
diff --git a/drm/common/include/IDrmManagerService.h b/drm/common/include/IDrmManagerService.h
index 0376b492d8..836ae0a428 100644
--- a/drm/common/include/IDrmManagerService.h
+++ b/drm/common/include/IDrmManagerService.h
@@ -115,10 +115,11 @@ public:
virtual int checkRightsStatus(int uniqueId, const String8& path, int action) = 0;
virtual status_t consumeRights(
- int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) = 0;
+ int uniqueId, sp<DecryptHandle>& decryptHandle, int action, bool reserve) = 0;
virtual status_t setPlaybackStatus(
- int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position) = 0;
+ int uniqueId, sp<DecryptHandle>& decryptHandle, int playbackStatus,
+ int64_t position) = 0;
virtual bool validateAction(
int uniqueId, const String8& path,
@@ -138,28 +139,28 @@ public:
virtual status_t getAllSupportInfo(
int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray) = 0;
- virtual DecryptHandle* openDecryptSession(
+ virtual sp<DecryptHandle> openDecryptSession(
int uniqueId, int fd, off64_t offset,
off64_t length, const char* mime) = 0;
- virtual DecryptHandle* openDecryptSession(
+ virtual sp<DecryptHandle> openDecryptSession(
int uniqueId, const char* uri, const char* mime) = 0;
- virtual DecryptHandle* openDecryptSession(
+ virtual sp<DecryptHandle> openDecryptSession(
int uniqueId, const DrmBuffer& buf, const String8& mimeType) = 0;
- virtual status_t closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) = 0;
+ virtual status_t closeDecryptSession(int uniqueId, sp<DecryptHandle>& decryptHandle) = 0;
- virtual status_t initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+ virtual status_t initializeDecryptUnit(int uniqueId, sp<DecryptHandle>& decryptHandle,
int decryptUnitId, const DrmBuffer* headerInfo) = 0;
- virtual status_t decrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+ virtual status_t decrypt(int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId,
const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) = 0;
virtual status_t finalizeDecryptUnit(
- int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) = 0;
+ int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId) = 0;
- virtual ssize_t pread(int uniqueId, DecryptHandle* decryptHandle,
+ virtual ssize_t pread(int uniqueId, sp<DecryptHandle>& decryptHandle,
void* buffer, ssize_t numBytes,off64_t offset) = 0;
};
@@ -203,10 +204,10 @@ public:
virtual int checkRightsStatus(int uniqueId, const String8& path, int action);
virtual status_t consumeRights(
- int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve);
+ int uniqueId, sp<DecryptHandle>& decryptHandle, int action, bool reserve);
virtual status_t setPlaybackStatus(
- int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position);
+ int uniqueId, sp<DecryptHandle>& decryptHandle, int playbackStatus, int64_t position);
virtual bool validateAction(
int uniqueId, const String8& path, int action, const ActionDescription& description);
@@ -225,28 +226,28 @@ public:
virtual status_t getAllSupportInfo(
int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray);
- virtual DecryptHandle* openDecryptSession(
+ virtual sp<DecryptHandle> openDecryptSession(
int uniqueId, int fd, off64_t offset, off64_t length,
const char* mime);
- virtual DecryptHandle* openDecryptSession(
+ virtual sp<DecryptHandle> openDecryptSession(
int uniqueId, const char* uri, const char* mime);
- virtual DecryptHandle* openDecryptSession(
+ virtual sp<DecryptHandle> openDecryptSession(
int uniqueId, const DrmBuffer& buf, const String8& mimeType);
- virtual status_t closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
+ virtual status_t closeDecryptSession(int uniqueId, sp<DecryptHandle>& decryptHandle);
- virtual status_t initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+ virtual status_t initializeDecryptUnit(int uniqueId, sp<DecryptHandle>& decryptHandle,
int decryptUnitId, const DrmBuffer* headerInfo);
- virtual status_t decrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+ virtual status_t decrypt(int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId,
const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV);
virtual status_t finalizeDecryptUnit(
- int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId);
+ int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId);
- virtual ssize_t pread(int uniqueId, DecryptHandle* decryptHandle,
+ virtual ssize_t pread(int uniqueId, sp<DecryptHandle>& decryptHandle,
void* buffer, ssize_t numBytes, off64_t offset);
};
diff --git a/drm/drmserver/DrmManager.cpp b/drm/drmserver/DrmManager.cpp
index bf04a893a6..afbcb3940e 100644
--- a/drm/drmserver/DrmManager.cpp
+++ b/drm/drmserver/DrmManager.cpp
@@ -267,7 +267,7 @@ int DrmManager::checkRightsStatus(int uniqueId, const String8& path, int action)
}
status_t DrmManager::consumeRights(
- int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) {
+ int uniqueId, sp<DecryptHandle>& decryptHandle, int action, bool reserve) {
status_t result = DRM_ERROR_UNKNOWN;
Mutex::Autolock _l(mDecryptLock);
if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
@@ -278,7 +278,7 @@ status_t DrmManager::consumeRights(
}
status_t DrmManager::setPlaybackStatus(
- int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position) {
+ int uniqueId, sp<DecryptHandle>& decryptHandle, int playbackStatus, int64_t position) {
status_t result = DRM_ERROR_UNKNOWN;
Mutex::Autolock _l(mDecryptLock);
if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
@@ -396,15 +396,15 @@ status_t DrmManager::getAllSupportInfo(
return DRM_NO_ERROR;
}
-DecryptHandle* DrmManager::openDecryptSession(
+sp<DecryptHandle> DrmManager::openDecryptSession(
int uniqueId, int fd, off64_t offset, off64_t length, const char* mime) {
Mutex::Autolock _l(mDecryptLock);
status_t result = DRM_ERROR_CANNOT_HANDLE;
Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
- DecryptHandle* handle = new DecryptHandle();
- if (NULL != handle) {
+ sp<DecryptHandle> handle = new DecryptHandle();
+ if (NULL != handle.get()) {
handle->decryptId = mDecryptSessionId + 1;
for (size_t index = 0; index < plugInIdList.size(); index++) {
@@ -420,19 +420,19 @@ DecryptHandle* DrmManager::openDecryptSession(
}
}
if (DRM_NO_ERROR != result) {
- delete handle; handle = NULL;
+ handle.clear();
}
return handle;
}
-DecryptHandle* DrmManager::openDecryptSession(
+sp<DecryptHandle> DrmManager::openDecryptSession(
int uniqueId, const char* uri, const char* mime) {
Mutex::Autolock _l(mDecryptLock);
status_t result = DRM_ERROR_CANNOT_HANDLE;
Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
- DecryptHandle* handle = new DecryptHandle();
- if (NULL != handle) {
+ sp<DecryptHandle> handle = new DecryptHandle();
+ if (NULL != handle.get()) {
handle->decryptId = mDecryptSessionId + 1;
for (size_t index = 0; index < plugInIdList.size(); index++) {
@@ -448,20 +448,20 @@ DecryptHandle* DrmManager::openDecryptSession(
}
}
if (DRM_NO_ERROR != result) {
- delete handle; handle = NULL;
+ handle.clear();
ALOGV("DrmManager::openDecryptSession: no capable plug-in found");
}
return handle;
}
-DecryptHandle* DrmManager::openDecryptSession(
+sp<DecryptHandle> DrmManager::openDecryptSession(
int uniqueId, const DrmBuffer& buf, const String8& mimeType) {
Mutex::Autolock _l(mDecryptLock);
status_t result = DRM_ERROR_CANNOT_HANDLE;
Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
- DecryptHandle* handle = new DecryptHandle();
- if (NULL != handle) {
+ sp<DecryptHandle> handle = new DecryptHandle();
+ if (NULL != handle.get()) {
handle->decryptId = mDecryptSessionId + 1;
for (size_t index = 0; index < plugInIdList.size(); index++) {
@@ -477,20 +477,19 @@ DecryptHandle* DrmManager::openDecryptSession(
}
}
if (DRM_NO_ERROR != result) {
- delete handle;
- handle = NULL;
+ handle.clear();
ALOGV("DrmManager::openDecryptSession: no capable plug-in found");
}
return handle;
}
-status_t DrmManager::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
+status_t DrmManager::closeDecryptSession(int uniqueId, sp<DecryptHandle>& decryptHandle) {
Mutex::Autolock _l(mDecryptLock);
status_t result = DRM_ERROR_UNKNOWN;
if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
result = drmEngine->closeDecryptSession(uniqueId, decryptHandle);
- if (DRM_NO_ERROR == result) {
+ if (DRM_NO_ERROR == result && NULL != decryptHandle.get()) {
mDecryptSessionMap.removeItem(decryptHandle->decryptId);
}
}
@@ -498,7 +497,8 @@ status_t DrmManager::closeDecryptSession(int uniqueId, DecryptHandle* decryptHan
}
status_t DrmManager::initializeDecryptUnit(
- int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId, const DrmBuffer* headerInfo) {
+ int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId,
+ const DrmBuffer* headerInfo) {
status_t result = DRM_ERROR_UNKNOWN;
Mutex::Autolock _l(mDecryptLock);
if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
@@ -508,7 +508,7 @@ status_t DrmManager::initializeDecryptUnit(
return result;
}
-status_t DrmManager::decrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+status_t DrmManager::decrypt(int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId,
const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
status_t result = DRM_ERROR_UNKNOWN;
@@ -522,7 +522,7 @@ status_t DrmManager::decrypt(int uniqueId, DecryptHandle* decryptHandle, int dec
}
status_t DrmManager::finalizeDecryptUnit(
- int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) {
+ int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId) {
status_t result = DRM_ERROR_UNKNOWN;
Mutex::Autolock _l(mDecryptLock);
if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
@@ -532,7 +532,7 @@ status_t DrmManager::finalizeDecryptUnit(
return result;
}
-ssize_t DrmManager::pread(int uniqueId, DecryptHandle* decryptHandle,
+ssize_t DrmManager::pread(int uniqueId, sp<DecryptHandle>& decryptHandle,
void* buffer, ssize_t numBytes, off64_t offset) {
ssize_t result = DECRYPT_FILE_ERROR;
diff --git a/drm/drmserver/DrmManager.h b/drm/drmserver/DrmManager.h
index e7cdd36b76..26222bca3f 100644
--- a/drm/drmserver/DrmManager.h
+++ b/drm/drmserver/DrmManager.h
@@ -89,10 +89,11 @@ public:
int checkRightsStatus(int uniqueId, const String8& path, int action);
- status_t consumeRights(int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve);
+ status_t consumeRights(int uniqueId, sp<DecryptHandle>& decryptHandle, int action,
+ bool reserve);
status_t setPlaybackStatus(
- int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position);
+ int uniqueId, sp<DecryptHandle>& decryptHandle, int playbackStatus, int64_t position);
bool validateAction(
int uniqueId, const String8& path, int action, const ActionDescription& description);
@@ -109,25 +110,26 @@ public:
status_t getAllSupportInfo(int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray);
- DecryptHandle* openDecryptSession(
+ sp<DecryptHandle> openDecryptSession(
int uniqueId, int fd, off64_t offset, off64_t length, const char* mime);
- DecryptHandle* openDecryptSession(int uniqueId, const char* uri, const char* mime);
+ sp<DecryptHandle> openDecryptSession(int uniqueId, const char* uri, const char* mime);
- DecryptHandle* openDecryptSession(int uniqueId, const DrmBuffer& buf,
+ sp<DecryptHandle> openDecryptSession(int uniqueId, const DrmBuffer& buf,
const String8& mimeType);
- status_t closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
+ status_t closeDecryptSession(int uniqueId, sp<DecryptHandle>& decryptHandle);
- status_t initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+ status_t initializeDecryptUnit(int uniqueId, sp<DecryptHandle>& decryptHandle,
int decryptUnitId, const DrmBuffer* headerInfo);
- status_t decrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+ status_t decrypt(int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId,
const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV);
- status_t finalizeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId);
+ status_t finalizeDecryptUnit(int uniqueId, sp<DecryptHandle>& decryptHandle,
+ int decryptUnitId);
- ssize_t pread(int uniqueId, DecryptHandle* decryptHandle,
+ ssize_t pread(int uniqueId, sp<DecryptHandle>& decryptHandle,
void* buffer, ssize_t numBytes, off64_t offset);
void onInfo(const DrmInfoEvent& event);
diff --git a/drm/drmserver/DrmManagerService.cpp b/drm/drmserver/DrmManagerService.cpp
index dad599b42e..2600a2c23e 100644
--- a/drm/drmserver/DrmManagerService.cpp
+++ b/drm/drmserver/DrmManagerService.cpp
@@ -58,22 +58,26 @@ const char *DrmManagerService::get_perm_label(drm_perm_t perm) {
return drm_perm_labels[index];
}
-bool DrmManagerService::selinuxIsProtectedCallAllowed(pid_t spid, drm_perm_t perm) {
+bool DrmManagerService::selinuxIsProtectedCallAllowed(pid_t spid, const char* ssid, drm_perm_t perm) {
if (selinux_enabled <= 0) {
return true;
}
- char *sctx;
+ char *sctx = NULL;
const char *selinux_class = "drmservice";
const char *str_perm = get_perm_label(perm);
- if (getpidcon(spid, &sctx) != 0) {
- ALOGE("SELinux: getpidcon(pid=%d) failed.\n", spid);
- return false;
+ if (ssid == NULL) {
+ android_errorWriteLog(0x534e4554, "121035042");
+
+ if (getpidcon(spid, &sctx) != 0) {
+ ALOGE("SELinux: getpidcon(pid=%d) failed.\n", spid);
+ return false;
+ }
}
- bool allowed = (selinux_check_access(sctx, drmserver_context, selinux_class,
- str_perm, NULL) == 0);
+ bool allowed = (selinux_check_access(ssid ? ssid : sctx, drmserver_context,
+ selinux_class, str_perm, NULL) == 0);
freecon(sctx);
return allowed;
@@ -86,10 +90,11 @@ bool DrmManagerService::isProtectedCallAllowed(drm_perm_t perm) {
IPCThreadState* ipcState = IPCThreadState::self();
uid_t uid = ipcState->getCallingUid();
pid_t spid = ipcState->getCallingPid();
+ const char* ssid = ipcState->getCallingSid();
for (unsigned int i = 0; i < trustedUids.size(); ++i) {
if (trustedUids[i] == uid) {
- return selinuxIsProtectedCallAllowed(spid, perm);
+ return selinuxIsProtectedCallAllowed(spid, ssid, perm);
}
}
return false;
@@ -97,7 +102,9 @@ bool DrmManagerService::isProtectedCallAllowed(drm_perm_t perm) {
void DrmManagerService::instantiate() {
ALOGV("instantiate");
- defaultServiceManager()->addService(String16("drm.drmManager"), new DrmManagerService());
+ sp<DrmManagerService> service = new DrmManagerService();
+ service->setRequestingSid(true);
+ defaultServiceManager()->addService(String16("drm.drmManager"), service);
if (0 >= trustedUids.size()) {
// TODO
@@ -206,7 +213,7 @@ int DrmManagerService::checkRightsStatus(
}
status_t DrmManagerService::consumeRights(
- int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) {
+ int uniqueId, sp<DecryptHandle>& decryptHandle, int action, bool reserve) {
ALOGV("Entering consumeRights");
if (!isProtectedCallAllowed(CONSUME_RIGHTS)) {
return DRM_ERROR_NO_PERMISSION;
@@ -215,7 +222,7 @@ status_t DrmManagerService::consumeRights(
}
status_t DrmManagerService::setPlaybackStatus(
- int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position) {
+ int uniqueId, sp<DecryptHandle>& decryptHandle, int playbackStatus, int64_t position) {
ALOGV("Entering setPlaybackStatus");
if (!isProtectedCallAllowed(SET_PLAYBACK_STATUS)) {
return DRM_ERROR_NO_PERMISSION;
@@ -262,7 +269,7 @@ status_t DrmManagerService::getAllSupportInfo(
return mDrmManager->getAllSupportInfo(uniqueId, length, drmSupportInfoArray);
}
-DecryptHandle* DrmManagerService::openDecryptSession(
+sp<DecryptHandle> DrmManagerService::openDecryptSession(
int uniqueId, int fd, off64_t offset, off64_t length, const char* mime) {
ALOGV("Entering DrmManagerService::openDecryptSession");
if (isProtectedCallAllowed(OPEN_DECRYPT_SESSION)) {
@@ -272,7 +279,7 @@ DecryptHandle* DrmManagerService::openDecryptSession(
return NULL;
}
-DecryptHandle* DrmManagerService::openDecryptSession(
+sp<DecryptHandle> DrmManagerService::openDecryptSession(
int uniqueId, const char* uri, const char* mime) {
ALOGV("Entering DrmManagerService::openDecryptSession with uri");
if (isProtectedCallAllowed(OPEN_DECRYPT_SESSION)) {
@@ -282,7 +289,7 @@ DecryptHandle* DrmManagerService::openDecryptSession(
return NULL;
}
-DecryptHandle* DrmManagerService::openDecryptSession(
+sp<DecryptHandle> DrmManagerService::openDecryptSession(
int uniqueId, const DrmBuffer& buf, const String8& mimeType) {
ALOGV("Entering DrmManagerService::openDecryptSession for streaming");
if (isProtectedCallAllowed(OPEN_DECRYPT_SESSION)) {
@@ -292,7 +299,7 @@ DecryptHandle* DrmManagerService::openDecryptSession(
return NULL;
}
-status_t DrmManagerService::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
+status_t DrmManagerService::closeDecryptSession(int uniqueId, sp<DecryptHandle>& decryptHandle) {
ALOGV("Entering closeDecryptSession");
if (!isProtectedCallAllowed(CLOSE_DECRYPT_SESSION)) {
return DRM_ERROR_NO_PERMISSION;
@@ -300,7 +307,7 @@ status_t DrmManagerService::closeDecryptSession(int uniqueId, DecryptHandle* dec
return mDrmManager->closeDecryptSession(uniqueId, decryptHandle);
}
-status_t DrmManagerService::initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+status_t DrmManagerService::initializeDecryptUnit(int uniqueId, sp<DecryptHandle>& decryptHandle,
int decryptUnitId, const DrmBuffer* headerInfo) {
ALOGV("Entering initializeDecryptUnit");
if (!isProtectedCallAllowed(INITIALIZE_DECRYPT_UNIT)) {
@@ -310,7 +317,7 @@ status_t DrmManagerService::initializeDecryptUnit(int uniqueId, DecryptHandle* d
}
status_t DrmManagerService::decrypt(
- int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+ int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId,
const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
ALOGV("Entering decrypt");
if (!isProtectedCallAllowed(DECRYPT)) {
@@ -320,7 +327,7 @@ status_t DrmManagerService::decrypt(
}
status_t DrmManagerService::finalizeDecryptUnit(
- int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) {
+ int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId) {
ALOGV("Entering finalizeDecryptUnit");
if (!isProtectedCallAllowed(FINALIZE_DECRYPT_UNIT)) {
return DRM_ERROR_NO_PERMISSION;
@@ -328,7 +335,7 @@ status_t DrmManagerService::finalizeDecryptUnit(
return mDrmManager->finalizeDecryptUnit(uniqueId, decryptHandle, decryptUnitId);
}
-ssize_t DrmManagerService::pread(int uniqueId, DecryptHandle* decryptHandle,
+ssize_t DrmManagerService::pread(int uniqueId, sp<DecryptHandle>& decryptHandle,
void* buffer, ssize_t numBytes, off64_t offset) {
ALOGV("Entering pread");
if (!isProtectedCallAllowed(PREAD)) {
diff --git a/drm/drmserver/DrmManagerService.h b/drm/drmserver/DrmManagerService.h
index 45cee2e203..2e27a3c393 100644
--- a/drm/drmserver/DrmManagerService.h
+++ b/drm/drmserver/DrmManagerService.h
@@ -60,7 +60,7 @@ private:
static const char *get_perm_label(drm_perm_t perm);
- static bool selinuxIsProtectedCallAllowed(pid_t spid, drm_perm_t perm);
+ static bool selinuxIsProtectedCallAllowed(pid_t spid, const char* ssid, drm_perm_t perm);
static bool isProtectedCallAllowed(drm_perm_t perm);
@@ -95,10 +95,11 @@ public:
int checkRightsStatus(int uniqueId, const String8& path,int action);
- status_t consumeRights(int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve);
+ status_t consumeRights(int uniqueId, sp<DecryptHandle>& decryptHandle, int action,
+ bool reserve);
status_t setPlaybackStatus(
- int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position);
+ int uniqueId, sp<DecryptHandle>& decryptHandle, int playbackStatus, int64_t position);
bool validateAction(int uniqueId, const String8& path,
int action, const ActionDescription& description);
@@ -115,26 +116,27 @@ public:
status_t getAllSupportInfo(int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray);
- DecryptHandle* openDecryptSession(
+ sp<DecryptHandle> openDecryptSession(
int uniqueId, int fd, off64_t offset, off64_t length, const char *mime);
- DecryptHandle* openDecryptSession(
+ sp<DecryptHandle> openDecryptSession(
int uniqueId, const char* uri, const char* mime);
- DecryptHandle* openDecryptSession(int uniqueId, const DrmBuffer& buf,
+ sp<DecryptHandle> openDecryptSession(int uniqueId, const DrmBuffer& buf,
const String8& mimeType);
- status_t closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
+ status_t closeDecryptSession(int uniqueId, sp<DecryptHandle>& decryptHandle);
- status_t initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+ status_t initializeDecryptUnit(int uniqueId, sp<DecryptHandle>& decryptHandle,
int decryptUnitId, const DrmBuffer* headerInfo);
- status_t decrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+ status_t decrypt(int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId,
const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV);
- status_t finalizeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId);
+ status_t finalizeDecryptUnit(int uniqueId, sp<DecryptHandle>& decryptHandle,
+ int decryptUnitId);
- ssize_t pread(int uniqueId, DecryptHandle* decryptHandle,
+ ssize_t pread(int uniqueId, sp<DecryptHandle>& decryptHandle,
void* buffer, ssize_t numBytes, off64_t offset);
virtual status_t dump(int fd, const Vector<String16>& args);
diff --git a/drm/libdrmframework/Android.bp b/drm/libdrmframework/Android.bp
index 43ba72bcb3..940c17d2b8 100644
--- a/drm/libdrmframework/Android.bp
+++ b/drm/libdrmframework/Android.bp
@@ -39,4 +39,3 @@ cc_library_shared {
cflags: ["-Werror"],
}
-subdirs = ["plugins/*"]
diff --git a/drm/libdrmframework/DrmManagerClientImpl.cpp b/drm/libdrmframework/DrmManagerClientImpl.cpp
index c047eb13b1..b0a441b556 100644
--- a/drm/libdrmframework/DrmManagerClientImpl.cpp
+++ b/drm/libdrmframework/DrmManagerClientImpl.cpp
@@ -183,7 +183,7 @@ status_t DrmManagerClientImpl::consumeRights(
status_t status = DRM_ERROR_UNKNOWN;
if (NULL != decryptHandle.get()) {
status = getDrmManagerService()->consumeRights(
- uniqueId, decryptHandle.get(), action, reserve);
+ uniqueId, decryptHandle, action, reserve);
}
return status;
}
@@ -194,7 +194,7 @@ status_t DrmManagerClientImpl::setPlaybackStatus(
status_t status = DRM_ERROR_UNKNOWN;
if (NULL != decryptHandle.get()) {
status = getDrmManagerService()->setPlaybackStatus(
- uniqueId, decryptHandle.get(), playbackStatus, position);
+ uniqueId, decryptHandle, playbackStatus, position);
}
return status;
}
@@ -267,7 +267,7 @@ sp<DecryptHandle> DrmManagerClientImpl::openDecryptSession(
sp<DecryptHandle> DrmManagerClientImpl::openDecryptSession(
int uniqueId, const char* uri, const char* mime) {
- DecryptHandle* handle = NULL;
+ sp<DecryptHandle> handle;
if (NULL != uri) {
handle = getDrmManagerService()->openDecryptSession(uniqueId, uri, mime);
}
@@ -284,7 +284,7 @@ status_t DrmManagerClientImpl::closeDecryptSession(
status_t status = DRM_ERROR_UNKNOWN;
if (NULL != decryptHandle.get()) {
status = getDrmManagerService()->closeDecryptSession(
- uniqueId, decryptHandle.get());
+ uniqueId, decryptHandle);
}
return status;
}
@@ -295,7 +295,7 @@ status_t DrmManagerClientImpl::initializeDecryptUnit(
status_t status = DRM_ERROR_UNKNOWN;
if ((NULL != decryptHandle.get()) && (NULL != headerInfo)) {
status = getDrmManagerService()->initializeDecryptUnit(
- uniqueId, decryptHandle.get(), decryptUnitId, headerInfo);
+ uniqueId, decryptHandle, decryptUnitId, headerInfo);
}
return status;
}
@@ -308,7 +308,7 @@ status_t DrmManagerClientImpl::decrypt(
if ((NULL != decryptHandle.get()) && (NULL != encBuffer)
&& (NULL != decBuffer) && (NULL != *decBuffer)) {
status = getDrmManagerService()->decrypt(
- uniqueId, decryptHandle.get(), decryptUnitId,
+ uniqueId, decryptHandle, decryptUnitId,
encBuffer, decBuffer, IV);
}
return status;
@@ -319,7 +319,7 @@ status_t DrmManagerClientImpl::finalizeDecryptUnit(
status_t status = DRM_ERROR_UNKNOWN;
if (NULL != decryptHandle.get()) {
status = getDrmManagerService()->finalizeDecryptUnit(
- uniqueId, decryptHandle.get(), decryptUnitId);
+ uniqueId, decryptHandle, decryptUnitId);
}
return status;
}
@@ -329,7 +329,7 @@ ssize_t DrmManagerClientImpl::pread(int uniqueId, sp<DecryptHandle> &decryptHand
ssize_t retCode = INVALID_VALUE;
if ((NULL != decryptHandle.get()) && (NULL != buffer) && (0 < numBytes)) {
retCode = getDrmManagerService()->pread(
- uniqueId, decryptHandle.get(), buffer, numBytes, offset);
+ uniqueId, decryptHandle, buffer, numBytes, offset);
}
return retCode;
}
diff --git a/drm/libdrmframework/plugins/common/Android.bp b/drm/libdrmframework/plugins/common/Android.bp
deleted file mode 100644
index 213e57f859..0000000000
--- a/drm/libdrmframework/plugins/common/Android.bp
+++ /dev/null
@@ -1 +0,0 @@
-subdirs = ["util"]
diff --git a/drm/libdrmframework/plugins/forward-lock/Android.bp b/drm/libdrmframework/plugins/forward-lock/Android.bp
deleted file mode 100644
index f884c14986..0000000000
--- a/drm/libdrmframework/plugins/forward-lock/Android.bp
+++ /dev/null
@@ -1,4 +0,0 @@
-subdirs = [
- "FwdLockEngine",
- "internal-format",
-]
diff --git a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/Android.bp b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/Android.bp
index 28a78aa21a..bb9d7ec791 100644
--- a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/Android.bp
+++ b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/Android.bp
@@ -29,8 +29,7 @@ cc_library_shared {
srcs: ["src/FwdLockEngine.cpp"],
shared_libs: [
- "libicui18n",
- "libicuuc",
+ "libandroidicu",
"libutils",
"liblog",
"libdl",
diff --git a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/include/FwdLockEngine.h b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/include/FwdLockEngine.h
index a571b3aa1f..b62ddb9296 100644
--- a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/include/FwdLockEngine.h
+++ b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/include/FwdLockEngine.h
@@ -198,7 +198,7 @@ int onCheckRightsStatus(int uniqueId,
* Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
*/
status_t onConsumeRights(int uniqueId,
- DecryptHandle* decryptHandle,
+ sp<DecryptHandle>& decryptHandle,
int action,
bool reserve);
@@ -215,12 +215,12 @@ status_t onConsumeRights(int uniqueId,
*/
#ifdef USE_64BIT_DRM_API
status_t onSetPlaybackStatus(int uniqueId,
- DecryptHandle* decryptHandle,
+ sp<DecryptHandle>& decryptHandle,
int playbackStatus,
int64_t position);
#else
status_t onSetPlaybackStatus(int uniqueId,
- DecryptHandle* decryptHandle,
+ sp<DecryptHandle>& decryptHandle,
int playbackStatus,
int position);
#endif
@@ -330,11 +330,11 @@ DrmSupportInfo* onGetSupportInfo(int uniqueId);
*/
#ifdef USE_64BIT_DRM_API
status_t onOpenDecryptSession(int uniqueId,
- DecryptHandle* decryptHandle,
+ sp<DecryptHandle>& decryptHandle,
int fd, off64_t offset, off64_t length);
#else
status_t onOpenDecryptSession(int uniqueId,
- DecryptHandle* decryptHandle,
+ sp<DecryptHandle>& decryptHandle,
int fd, int offset, int length);
#endif
@@ -348,7 +348,7 @@ status_t onOpenDecryptSession(int uniqueId,
* DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
*/
status_t onOpenDecryptSession(int uniqueId,
- DecryptHandle* decryptHandle,
+ sp<DecryptHandle>& decryptHandle,
const char* uri);
/**
@@ -360,7 +360,7 @@ status_t onOpenDecryptSession(int uniqueId,
* Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
*/
status_t onCloseDecryptSession(int uniqueId,
- DecryptHandle* decryptHandle);
+ sp<DecryptHandle>& decryptHandle);
/**
* Initialize decryption for the given unit of the protected content.
@@ -373,7 +373,7 @@ status_t onCloseDecryptSession(int uniqueId,
* DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
*/
status_t onInitializeDecryptUnit(int uniqueId,
- DecryptHandle* decryptHandle,
+ sp<DecryptHandle>& decryptHandle,
int decryptUnitId,
const DrmBuffer* headerInfo);
@@ -394,7 +394,7 @@ status_t onInitializeDecryptUnit(int uniqueId,
* DRM_ERROR_DECRYPT for failure.
*/
status_t onDecrypt(int uniqueId,
- DecryptHandle* decryptHandle,
+ sp<DecryptHandle>& decryptHandle,
int decryptUnitId,
const DrmBuffer* encBuffer,
DrmBuffer** decBuffer);
@@ -416,7 +416,7 @@ status_t onDecrypt(int uniqueId,
* DRM_ERROR_SESSION_NOT_OPENED, DRM_ERROR_DECRYPT_UNIT_NOT_INITIALIZED,
* DRM_ERROR_DECRYPT for failure.
*/
-status_t onDecrypt(int uniqueId, DecryptHandle* decryptHandle,
+status_t onDecrypt(int uniqueId, sp<DecryptHandle>& decryptHandle,
int decryptUnitId, const DrmBuffer* encBuffer,
DrmBuffer** decBuffer, DrmBuffer* IV);
@@ -430,7 +430,7 @@ status_t onDecrypt(int uniqueId, DecryptHandle* decryptHandle,
* DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
*/
status_t onFinalizeDecryptUnit(int uniqueId,
- DecryptHandle* decryptHandle,
+ sp<DecryptHandle>& decryptHandle,
int decryptUnitId);
/**
@@ -445,7 +445,7 @@ status_t onFinalizeDecryptUnit(int uniqueId,
* @retval -1 Failure.
*/
ssize_t onRead(int uniqueId,
- DecryptHandle* decryptHandle,
+ sp<DecryptHandle>& decryptHandle,
void* pBuffer,
int numBytes);
@@ -463,12 +463,12 @@ ssize_t onRead(int uniqueId,
*/
#ifdef USE_64BIT_DRM_API
off64_t onLseek(int uniqueId,
- DecryptHandle* decryptHandle,
+ sp<DecryptHandle>& decryptHandle,
off64_t offset,
int whence);
#else
off_t onLseek(int uniqueId,
- DecryptHandle* decryptHandle,
+ sp<DecryptHandle>& decryptHandle,
off_t offset,
int whence);
#endif
@@ -486,13 +486,13 @@ off_t onLseek(int uniqueId,
*/
#ifdef USE_64BIT_DRM_API
ssize_t onPread(int uniqueId,
- DecryptHandle* decryptHandle,
+ sp<DecryptHandle>& decryptHandle,
void* buffer,
ssize_t numBytes,
off64_t offset);
#else
ssize_t onPread(int uniqueId,
- DecryptHandle* decryptHandle,
+ sp<DecryptHandle>& decryptHandle,
void* buffer,
ssize_t numBytes,
off_t offset);
diff --git a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/src/FwdLockEngine.cpp b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/src/FwdLockEngine.cpp
index 73eea89249..769de0c801 100644
--- a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/src/FwdLockEngine.cpp
+++ b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/src/FwdLockEngine.cpp
@@ -294,7 +294,7 @@ int FwdLockEngine::onCheckRightsStatus(int uniqueId,
}
status_t FwdLockEngine::onConsumeRights(int /* uniqueId */,
- DecryptHandle* /* decryptHandle */,
+ sp<DecryptHandle>& /* decryptHandle */,
int /* action */,
bool /* reserve */) {
// No rights consumption
@@ -372,11 +372,13 @@ status_t FwdLockEngine::onRemoveAllRights(int /* uniqueId */) {
}
#ifdef USE_64BIT_DRM_API
-status_t FwdLockEngine::onSetPlaybackStatus(int /* uniqueId */, DecryptHandle* /* decryptHandle */,
- int /* playbackStatus */, int64_t /* position */) {
+status_t FwdLockEngine::onSetPlaybackStatus(int /* uniqueId */,
+ sp<DecryptHandle>& /* decryptHandle */, int /* playbackStatus */,
+ int64_t /* position */) {
#else
-status_t FwdLockEngine::onSetPlaybackStatus(int /* uniqueId */, DecryptHandle* /* decryptHandle */,
- int /* playbackStatus */, int /* position */) {
+status_t FwdLockEngine::onSetPlaybackStatus(int /* uniqueId */,
+ sp<DecryptHandle>& /* decryptHandle */,
+ int /* playbackStatus */, int /* position */) {
#endif
// Not used
LOG_VERBOSE("FwdLockEngine::onSetPlaybackStatus");
@@ -470,13 +472,13 @@ DrmConvertedStatus* FwdLockEngine::onCloseConvertSession(int /* uniqueId */,
#ifdef USE_64BIT_DRM_API
status_t FwdLockEngine::onOpenDecryptSession(int /* uniqueId */,
- DecryptHandle* decryptHandle,
+ sp<DecryptHandle>& decryptHandle,
int fd,
off64_t offset,
off64_t /* length */) {
#else
status_t FwdLockEngine::onOpenDecryptSession(int /* uniqueId */,
- DecryptHandle* decryptHandle,
+ sp<DecryptHandle>& decryptHandle,
int fd,
int offset,
int /* length */) {
@@ -487,7 +489,7 @@ status_t FwdLockEngine::onOpenDecryptSession(int /* uniqueId */,
LOG_VERBOSE("FwdLockEngine::onOpenDecryptSession");
if ((-1 < fd) &&
- (NULL != decryptHandle) &&
+ (NULL != decryptHandle.get()) &&
(!decodeSessionMap.isCreated(decryptHandle->decryptId))) {
fileDesc = dup(fd);
} else {
@@ -533,12 +535,12 @@ status_t FwdLockEngine::onOpenDecryptSession(int /* uniqueId */,
}
status_t FwdLockEngine::onOpenDecryptSession(int uniqueId,
- DecryptHandle* decryptHandle,
+ sp<DecryptHandle>& decryptHandle,
const char* uri) {
status_t result = DRM_ERROR_CANNOT_HANDLE;
const char fileTag [] = "file://";
- if (NULL != decryptHandle && NULL != uri && strlen(uri) > sizeof(fileTag)) {
+ if (NULL != decryptHandle.get() && NULL != uri && strlen(uri) > sizeof(fileTag)) {
String8 uriTag = String8(uri);
uriTag.toLower();
@@ -562,11 +564,11 @@ status_t FwdLockEngine::onOpenDecryptSession(int uniqueId,
}
status_t FwdLockEngine::onCloseDecryptSession(int /* uniqueId */,
- DecryptHandle* decryptHandle) {
+ sp<DecryptHandle>& decryptHandle) {
status_t result = DRM_ERROR_UNKNOWN;
LOG_VERBOSE("FwdLockEngine::onCloseDecryptSession");
- if (NULL != decryptHandle && decodeSessionMap.isCreated(decryptHandle->decryptId)) {
+ if (NULL != decryptHandle.get() && decodeSessionMap.isCreated(decryptHandle->decryptId)) {
DecodeSession* session = decodeSessionMap.getValue(decryptHandle->decryptId);
if (NULL != session && session->fileDesc > -1) {
FwdLockFile_detach(session->fileDesc);
@@ -576,7 +578,7 @@ status_t FwdLockEngine::onCloseDecryptSession(int /* uniqueId */,
}
}
- if (NULL != decryptHandle) {
+ if (NULL != decryptHandle.get()) {
if (NULL != decryptHandle->decryptInfo) {
delete decryptHandle->decryptInfo;
decryptHandle->decryptInfo = NULL;
@@ -584,9 +586,7 @@ status_t FwdLockEngine::onCloseDecryptSession(int /* uniqueId */,
decryptHandle->copyControlVector.clear();
decryptHandle->extendedData.clear();
-
- delete decryptHandle;
- decryptHandle = NULL;
+ decryptHandle.clear();
}
LOG_VERBOSE("FwdLockEngine::onCloseDecryptSession Exit");
@@ -594,7 +594,7 @@ status_t FwdLockEngine::onCloseDecryptSession(int /* uniqueId */,
}
status_t FwdLockEngine::onInitializeDecryptUnit(int /* uniqueId */,
- DecryptHandle* /* decryptHandle */,
+ sp<DecryptHandle>& /* decryptHandle */,
int /* decryptUnitId */,
const DrmBuffer* /* headerInfo */) {
ALOGE("FwdLockEngine::onInitializeDecryptUnit is not supported for this DRM scheme");
@@ -603,7 +603,7 @@ status_t FwdLockEngine::onInitializeDecryptUnit(int /* uniqueId */,
status_t FwdLockEngine::onDecrypt(
int /* uniqueId */,
- DecryptHandle* /* decryptHandle */,
+ sp<DecryptHandle>& /* decryptHandle */,
int /* decryptUnitId */,
const DrmBuffer* /* encBuffer */,
DrmBuffer** /* decBuffer */,
@@ -613,7 +613,7 @@ status_t FwdLockEngine::onDecrypt(
}
status_t FwdLockEngine::onDecrypt(int /* uniqueId */,
- DecryptHandle* /* decryptHandle */,
+ sp<DecryptHandle>& /* decryptHandle */,
int /* decryptUnitId */,
const DrmBuffer* /* encBuffer */,
DrmBuffer** /* decBuffer */) {
@@ -622,19 +622,19 @@ status_t FwdLockEngine::onDecrypt(int /* uniqueId */,
}
status_t FwdLockEngine::onFinalizeDecryptUnit(int /* uniqueId */,
- DecryptHandle* /* decryptHandle */,
+ sp<DecryptHandle>& /* decryptHandle */,
int /* decryptUnitId */) {
ALOGE("FwdLockEngine::onFinalizeDecryptUnit is not supported for this DRM scheme");
return DRM_ERROR_UNKNOWN;
}
ssize_t FwdLockEngine::onRead(int /* uniqueId */,
- DecryptHandle* decryptHandle,
+ sp<DecryptHandle>& decryptHandle,
void* buffer,
int numBytes) {
ssize_t size = -1;
- if (NULL != decryptHandle &&
+ if (NULL != decryptHandle.get() &&
decodeSessionMap.isCreated(decryptHandle->decryptId) &&
NULL != buffer &&
numBytes > -1) {
@@ -654,15 +654,15 @@ ssize_t FwdLockEngine::onRead(int /* uniqueId */,
}
#ifdef USE_64BIT_DRM_API
-off64_t FwdLockEngine::onLseek(int /* uniqueId */, DecryptHandle* decryptHandle,
+off64_t FwdLockEngine::onLseek(int /* uniqueId */, sp<DecryptHandle>& decryptHandle,
off64_t offset, int whence) {
#else
-off_t FwdLockEngine::onLseek(int /* uniqueId */, DecryptHandle* decryptHandle,
+off_t FwdLockEngine::onLseek(int /* uniqueId */, sp<DecryptHandle>& decryptHandle,
off_t offset, int whence) {
#endif
off_t offval = -1;
- if (NULL != decryptHandle && decodeSessionMap.isCreated(decryptHandle->decryptId)) {
+ if (NULL != decryptHandle.get() && decodeSessionMap.isCreated(decryptHandle->decryptId)) {
DecodeSession* session = decodeSessionMap.getValue(decryptHandle->decryptId);
if (NULL != session && session->fileDesc > -1) {
offval = FwdLockFile_lseek(session->fileDesc, offset, whence);
@@ -675,13 +675,13 @@ off_t FwdLockEngine::onLseek(int /* uniqueId */, DecryptHandle* decryptHandle,
#ifdef USE_64BIT_DRM_API
ssize_t FwdLockEngine::onPread(int uniqueId,
- DecryptHandle* decryptHandle,
+ sp<DecryptHandle>& decryptHandle,
void* buffer,
ssize_t numBytes,
off64_t offset) {
#else
ssize_t FwdLockEngine::onPread(int uniqueId,
- DecryptHandle* decryptHandle,
+ sp<DecryptHandle>& decryptHandle,
void* buffer,
ssize_t numBytes,
off_t offset) {
@@ -690,7 +690,7 @@ ssize_t FwdLockEngine::onPread(int uniqueId,
DecodeSession* decoderSession = NULL;
- if ((NULL != decryptHandle) &&
+ if ((NULL != decryptHandle.get()) &&
(NULL != (decoderSession = decodeSessionMap.getValue(decryptHandle->decryptId))) &&
(NULL != buffer) &&
(numBytes > -1) &&
diff --git a/drm/libdrmframework/plugins/forward-lock/internal-format/Android.bp b/drm/libdrmframework/plugins/forward-lock/internal-format/Android.bp
deleted file mode 100644
index 9f58e264fd..0000000000
--- a/drm/libdrmframework/plugins/forward-lock/internal-format/Android.bp
+++ /dev/null
@@ -1,5 +0,0 @@
-subdirs = [
- "common",
- "converter",
- "decoder",
-]
diff --git a/drm/libdrmframework/plugins/passthru/include/DrmPassthruPlugIn.h b/drm/libdrmframework/plugins/passthru/include/DrmPassthruPlugIn.h
index 7b66dc7dbd..4ab52729a3 100644
--- a/drm/libdrmframework/plugins/passthru/include/DrmPassthruPlugIn.h
+++ b/drm/libdrmframework/plugins/passthru/include/DrmPassthruPlugIn.h
@@ -53,10 +53,11 @@ protected:
int onCheckRightsStatus(int uniqueId, const String8& path, int action);
- status_t onConsumeRights(int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve);
+ status_t onConsumeRights(int uniqueId, sp<DecryptHandle>& decryptHandle,
+ int action, bool reserve);
status_t onSetPlaybackStatus(
- int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position);
+ int uniqueId, sp<DecryptHandle>& decryptHandle, int playbackStatus, int64_t position);
bool onValidateAction(
int uniqueId, const String8& path, int action, const ActionDescription& description);
@@ -74,26 +75,25 @@ protected:
DrmSupportInfo* onGetSupportInfo(int uniqueId);
status_t onOpenDecryptSession(
- int uniqueId, DecryptHandle* decryptHandle, int fd, off64_t offset, off64_t length);
+ int uniqueId, sp<DecryptHandle>& decryptHandle, int fd, off64_t offset,
+ off64_t length);
status_t onOpenDecryptSession(
- int uniqueId, DecryptHandle* decryptHandle, const char* uri);
+ int uniqueId, sp<DecryptHandle>& decryptHandle, const char* uri);
- status_t onCloseDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
+ status_t onCloseDecryptSession(int uniqueId, sp<DecryptHandle>& decryptHandle);
- status_t onInitializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+ status_t onInitializeDecryptUnit(int uniqueId, sp<DecryptHandle>& decryptHandle,
int decryptUnitId, const DrmBuffer* headerInfo);
- status_t onDecrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+ status_t onDecrypt(int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId,
const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV);
- status_t onFinalizeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId);
+ status_t onFinalizeDecryptUnit(int uniqueId, sp<DecryptHandle>& decryptHandle,
+ int decryptUnitId);
- ssize_t onPread(int uniqueId, DecryptHandle* decryptHandle,
+ ssize_t onPread(int uniqueId, sp<DecryptHandle>& decryptHandle,
void* buffer, ssize_t numBytes, off64_t offset);
-
-private:
- DecryptHandle* openDecryptSessionImpl();
};
};
diff --git a/drm/libdrmframework/plugins/passthru/src/DrmPassthruPlugIn.cpp b/drm/libdrmframework/plugins/passthru/src/DrmPassthruPlugIn.cpp
index d7f2d287c0..0fa34786db 100644
--- a/drm/libdrmframework/plugins/passthru/src/DrmPassthruPlugIn.cpp
+++ b/drm/libdrmframework/plugins/passthru/src/DrmPassthruPlugIn.cpp
@@ -183,13 +183,13 @@ int DrmPassthruPlugIn::onCheckRightsStatus(int uniqueId, const String8& /*path*/
}
status_t DrmPassthruPlugIn::onConsumeRights(int uniqueId,
- DecryptHandle* /*decryptHandle*/, int /*action*/, bool /*reserve*/) {
+ sp<DecryptHandle>& /*decryptHandle*/, int /*action*/, bool /*reserve*/) {
ALOGV("DrmPassthruPlugIn::onConsumeRights() : %d", uniqueId);
return DRM_NO_ERROR;
}
status_t DrmPassthruPlugIn::onSetPlaybackStatus(int uniqueId,
- DecryptHandle* /*decryptHandle*/, int /*playbackStatus*/, int64_t /*position*/) {
+ sp<DecryptHandle>& /*decryptHandle*/, int /*playbackStatus*/, int64_t /*position*/) {
ALOGV("DrmPassthruPlugIn::onSetPlaybackStatus() : %d", uniqueId);
return DRM_NO_ERROR;
}
@@ -236,7 +236,8 @@ DrmConvertedStatus* DrmPassthruPlugIn::onCloseConvertSession(int uniqueId, int /
}
status_t DrmPassthruPlugIn::onOpenDecryptSession(
- int uniqueId, DecryptHandle* decryptHandle, int /*fd*/, off64_t /*offset*/, off64_t /*length*/) {
+ int uniqueId, sp<DecryptHandle>& decryptHandle, int /*fd*/, off64_t /*offset*/,
+ off64_t /*length*/) {
ALOGV("DrmPassthruPlugIn::onOpenDecryptSession() : %d", uniqueId);
#ifdef ENABLE_PASSTHRU_DECRYPTION
@@ -246,36 +247,38 @@ status_t DrmPassthruPlugIn::onOpenDecryptSession(
decryptHandle->decryptInfo = NULL;
return DRM_NO_ERROR;
#else
- (void)(decryptHandle); // unused
+ (void)(decryptHandle.get()); // unused
#endif
return DRM_ERROR_CANNOT_HANDLE;
}
status_t DrmPassthruPlugIn::onOpenDecryptSession(
- int /*uniqueId*/, DecryptHandle* /*decryptHandle*/, const char* /*uri*/) {
+ int /*uniqueId*/, sp<DecryptHandle>& /*decryptHandle*/, const char* /*uri*/) {
return DRM_ERROR_CANNOT_HANDLE;
}
-status_t DrmPassthruPlugIn::onCloseDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
+status_t DrmPassthruPlugIn::onCloseDecryptSession(int uniqueId, sp<DecryptHandle>& decryptHandle) {
ALOGV("DrmPassthruPlugIn::onCloseDecryptSession() : %d", uniqueId);
- if (NULL != decryptHandle) {
+ if (NULL != decryptHandle.get()) {
if (NULL != decryptHandle->decryptInfo) {
delete decryptHandle->decryptInfo; decryptHandle->decryptInfo = NULL;
}
- delete decryptHandle; decryptHandle = NULL;
+ decryptHandle.clear();
}
return DRM_NO_ERROR;
}
-status_t DrmPassthruPlugIn::onInitializeDecryptUnit(int uniqueId, DecryptHandle* /*decryptHandle*/,
- int /*decryptUnitId*/, const DrmBuffer* /*headerInfo*/) {
+status_t DrmPassthruPlugIn::onInitializeDecryptUnit(int uniqueId,
+ sp<DecryptHandle>& /*decryptHandle*/,
+ int /*decryptUnitId*/, const DrmBuffer* /*headerInfo*/) {
ALOGV("DrmPassthruPlugIn::onInitializeDecryptUnit() : %d", uniqueId);
return DRM_NO_ERROR;
}
-status_t DrmPassthruPlugIn::onDecrypt(int uniqueId, DecryptHandle* /*decryptHandle*/,
- int /*decryptUnitId*/, const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* /*IV*/) {
+status_t DrmPassthruPlugIn::onDecrypt(int uniqueId, sp<DecryptHandle>& /*decryptHandle*/,
+ int /*decryptUnitId*/, const DrmBuffer* encBuffer, DrmBuffer** decBuffer,
+ DrmBuffer* /*IV*/) {
ALOGV("DrmPassthruPlugIn::onDecrypt() : %d", uniqueId);
/**
* As a workaround implementation passthru would copy the given
@@ -296,12 +299,12 @@ status_t DrmPassthruPlugIn::onDecrypt(int uniqueId, DecryptHandle* /*decryptHand
}
status_t DrmPassthruPlugIn::onFinalizeDecryptUnit(
- int uniqueId, DecryptHandle* /*decryptHandle*/, int /*decryptUnitId*/) {
+ int uniqueId, sp<DecryptHandle>& /*decryptHandle*/, int /*decryptUnitId*/) {
ALOGV("DrmPassthruPlugIn::onFinalizeDecryptUnit() : %d", uniqueId);
return DRM_NO_ERROR;
}
-ssize_t DrmPassthruPlugIn::onPread(int uniqueId, DecryptHandle* /*decryptHandle*/,
+ssize_t DrmPassthruPlugIn::onPread(int uniqueId, sp<DecryptHandle>& /*decryptHandle*/,
void* /*buffer*/, ssize_t /*numBytes*/, off64_t /*offset*/) {
ALOGV("DrmPassthruPlugIn::onPread() : %d", uniqueId);
return 0;
diff --git a/drm/libmediadrm/Android.bp b/drm/libmediadrm/Android.bp
index 4991e50e8e..d6db1d4e2b 100644
--- a/drm/libmediadrm/Android.bp
+++ b/drm/libmediadrm/Android.bp
@@ -27,11 +27,11 @@ cc_library {
"libmediadrmmetrics_lite",
"libmediametrics",
"libmediautils",
- "libprotobuf-cpp-lite",
"libstagefright_foundation",
"libutils",
"android.hardware.drm@1.0",
"android.hardware.drm@1.1",
+ "android.hardware.drm@1.2",
"libhidlallocatorutils",
"libhidlbase",
"libhidltransport",
@@ -59,20 +59,18 @@ cc_library_shared {
shared_libs: [
"android.hardware.drm@1.0",
"android.hardware.drm@1.1",
- "libbase",
+ "android.hardware.drm@1.2",
"libbinder",
"libhidlbase",
"liblog",
"libmediametrics",
"libprotobuf-cpp-lite",
- "libstagefright_foundation",
"libutils",
],
cflags: [
// Suppress unused parameter and no error options. These cause problems
// with the when using the map type in a proto definition.
"-Wno-unused-parameter",
- "-Wno-error",
],
}
@@ -92,6 +90,7 @@ cc_library_shared {
shared_libs: [
"android.hardware.drm@1.0",
"android.hardware.drm@1.1",
+ "android.hardware.drm@1.2",
"libbase",
"libbinder",
"libhidlbase",
@@ -105,7 +104,6 @@ cc_library_shared {
// Suppress unused parameter and no error options. These cause problems
// when using the map type in a proto definition.
"-Wno-unused-parameter",
- "-Wno-error",
],
}
diff --git a/drm/libmediadrm/CryptoHal.cpp b/drm/libmediadrm/CryptoHal.cpp
index 3035c5a250..d62ccd6be1 100644
--- a/drm/libmediadrm/CryptoHal.cpp
+++ b/drm/libmediadrm/CryptoHal.cpp
@@ -30,16 +30,16 @@
#include <media/stagefright/MediaErrors.h>
#include <mediadrm/CryptoHal.h>
+using drm::V1_0::BufferType;
+using drm::V1_0::DestinationBuffer;
+using drm::V1_0::ICryptoFactory;
+using drm::V1_0::ICryptoPlugin;
+using drm::V1_0::Mode;
+using drm::V1_0::Pattern;
+using drm::V1_0::SharedBuffer;
+using drm::V1_0::Status;
+using drm::V1_0::SubSample;
-using ::android::hardware::drm::V1_0::BufferType;
-using ::android::hardware::drm::V1_0::DestinationBuffer;
-using ::android::hardware::drm::V1_0::ICryptoFactory;
-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_handle;
using ::android::hardware::hidl_memory;
@@ -50,6 +50,7 @@ using ::android::hardware::Void;
using ::android::hidl::manager::V1_0::IServiceManager;
using ::android::sp;
+typedef drm::V1_2::Status Status_V1_2;
namespace android {
@@ -76,6 +77,18 @@ static status_t toStatusT(Status status) {
}
}
+static status_t toStatusT_1_2(Status_V1_2 status) {
+ switch (status) {
+ case Status_V1_2::ERROR_DRM_SESSION_LOST_STATE:
+ return ERROR_DRM_SESSION_LOST_STATE;;
+ case Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE:
+ return ERROR_DRM_FRAME_TOO_LARGE;
+ case Status_V1_2::ERROR_DRM_INSUFFICIENT_SECURITY:
+ return ERROR_DRM_INSUFFICIENT_SECURITY;
+ default:
+ return toStatusT(static_cast<Status>(status));
+ }
+}
static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) {
hidl_vec<uint8_t> vec;
@@ -196,6 +209,9 @@ status_t CryptoHal::createPlugin(const uint8_t uuid[16], const void *data,
for (size_t i = 0; i < mFactories.size(); i++) {
if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
mPlugin = makeCryptoPlugin(mFactories[i], uuid, data, size);
+ if (mPlugin != NULL) {
+ mPluginV1_2 = drm::V1_2::ICryptoPlugin::castFrom(mPlugin);
+ }
}
}
@@ -216,6 +232,7 @@ status_t CryptoHal::destroyPlugin() {
}
mPlugin.clear();
+ mPluginV1_2.clear();
return OK;
}
@@ -284,7 +301,7 @@ status_t CryptoHal::toSharedBuffer(const sp<IMemory>& memory, int32_t seqNum, ::
ssize_t offset;
size_t size;
- if (memory == NULL && buffer == NULL) {
+ if (memory == NULL || buffer == NULL) {
return UNEXPECTED_NULL;
}
@@ -389,21 +406,33 @@ ssize_t CryptoHal::decrypt(const uint8_t keyId[16], const uint8_t iv[16],
status_t err = UNKNOWN_ERROR;
uint32_t bytesWritten = 0;
- Return<void> hResult = mPlugin->decrypt(secure, toHidlArray16(keyId), toHidlArray16(iv), hMode,
- hPattern, hSubSamples, hSource, offset, hDestination,
- [&](Status status, uint32_t hBytesWritten, hidl_string hDetailedError) {
- if (status == Status::OK) {
- bytesWritten = hBytesWritten;
- *errorDetailMsg = toString8(hDetailedError);
- }
- err = toStatusT(status);
- }
- );
+ Return<void> hResult;
- if (!hResult.isOk()) {
- err = DEAD_OBJECT;
+ if (mPluginV1_2 != NULL) {
+ hResult = mPluginV1_2->decrypt_1_2(secure, toHidlArray16(keyId), toHidlArray16(iv),
+ hMode, hPattern, hSubSamples, hSource, offset, hDestination,
+ [&](Status_V1_2 status, uint32_t hBytesWritten, hidl_string hDetailedError) {
+ if (status == Status_V1_2::OK) {
+ bytesWritten = hBytesWritten;
+ *errorDetailMsg = toString8(hDetailedError);
+ }
+ err = toStatusT_1_2(status);
+ }
+ );
+ } else {
+ hResult = mPlugin->decrypt(secure, toHidlArray16(keyId), toHidlArray16(iv),
+ hMode, hPattern, hSubSamples, hSource, offset, hDestination,
+ [&](Status status, uint32_t hBytesWritten, hidl_string hDetailedError) {
+ if (status == Status::OK) {
+ bytesWritten = hBytesWritten;
+ *errorDetailMsg = toString8(hDetailedError);
+ }
+ err = toStatusT(status);
+ }
+ );
}
+ err = hResult.isOk() ? err : DEAD_OBJECT;
if (err == OK) {
return bytesWritten;
}
diff --git a/drm/libmediadrm/DrmHal.cpp b/drm/libmediadrm/DrmHal.cpp
index cf08610173..919f4ee1df 100644
--- a/drm/libmediadrm/DrmHal.cpp
+++ b/drm/libmediadrm/DrmHal.cpp
@@ -23,8 +23,8 @@
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
-#include <android/hardware/drm/1.0/types.h>
-#include <android/hidl/manager/1.0/IServiceManager.h>
+#include <android/hardware/drm/1.2/types.h>
+#include <android/hidl/manager/1.2/IServiceManager.h>
#include <hidl/ServiceManagement.h>
#include <media/EventMetric.h>
@@ -40,15 +40,17 @@
#include <mediadrm/DrmSessionManager.h>
using drm::V1_0::KeyedVector;
-using drm::V1_0::KeyStatusType;
+using drm::V1_0::KeyRequestType;
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 drm::V1_2::KeyStatusType;
using ::android::hardware::drm::V1_1::DrmMetricGroup;
using ::android::hardware::hidl_array;
using ::android::hardware::hidl_string;
@@ -59,6 +61,10 @@ using ::android::hidl::manager::V1_0::IServiceManager;
using ::android::os::PersistableBundle;
using ::android::sp;
+typedef drm::V1_1::KeyRequestType KeyRequestType_V1_1;
+typedef drm::V1_2::Status Status_V1_2;
+typedef drm::V1_2::HdcpLevel HdcpLevel_V1_2;
+
namespace {
// This constant corresponds to the PROPERTY_DEVICE_UNIQUE_ID constant
@@ -139,26 +145,55 @@ static DrmPlugin::SecurityLevel toSecurityLevel(SecurityLevel level) {
}
}
-static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel level) {
+static SecurityLevel toHidlSecurityLevel(DrmPlugin::SecurityLevel level) {
switch(level) {
- case HdcpLevel::HDCP_NONE:
+ case DrmPlugin::kSecurityLevelSwSecureCrypto:
+ return SecurityLevel::SW_SECURE_CRYPTO;
+ case DrmPlugin::kSecurityLevelSwSecureDecode:
+ return SecurityLevel::SW_SECURE_DECODE;
+ case DrmPlugin::kSecurityLevelHwSecureCrypto:
+ return SecurityLevel::HW_SECURE_CRYPTO;
+ case DrmPlugin::kSecurityLevelHwSecureDecode:
+ return SecurityLevel::HW_SECURE_DECODE;
+ case DrmPlugin::kSecurityLevelHwSecureAll:
+ return SecurityLevel::HW_SECURE_ALL;
+ default:
+ return SecurityLevel::UNKNOWN;
+ }
+}
+
+static DrmPlugin::OfflineLicenseState toOfflineLicenseState(
+ OfflineLicenseState licenseState) {
+ switch(licenseState) {
+ case OfflineLicenseState::USABLE:
+ return DrmPlugin::kOfflineLicenseStateUsable;
+ case OfflineLicenseState::INACTIVE:
+ return DrmPlugin::kOfflineLicenseStateReleased;
+ default:
+ return DrmPlugin::kOfflineLicenseStateUnknown;
+ }
+}
+
+static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel_V1_2 level) {
+ switch(level) {
+ case HdcpLevel_V1_2::HDCP_NONE:
return DrmPlugin::kHdcpNone;
- case HdcpLevel::HDCP_V1:
+ case HdcpLevel_V1_2::HDCP_V1:
return DrmPlugin::kHdcpV1;
- case HdcpLevel::HDCP_V2:
+ case HdcpLevel_V1_2::HDCP_V2:
return DrmPlugin::kHdcpV2;
- case HdcpLevel::HDCP_V2_1:
+ case HdcpLevel_V1_2::HDCP_V2_1:
return DrmPlugin::kHdcpV2_1;
- case HdcpLevel::HDCP_V2_2:
+ case HdcpLevel_V1_2::HDCP_V2_2:
return DrmPlugin::kHdcpV2_2;
- case HdcpLevel::HDCP_NO_OUTPUT:
+ case HdcpLevel_V1_2::HDCP_V2_3:
+ return DrmPlugin::kHdcpV2_3;
+ case HdcpLevel_V1_2::HDCP_NO_OUTPUT:
return DrmPlugin::kHdcpNoOutput;
default:
return DrmPlugin::kHdcpLevelUnknown;
}
}
-
-
static ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>&
keyedVector) {
std::vector<KeyValue> stdKeyedVector;
@@ -199,6 +234,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:
@@ -217,7 +261,7 @@ static status_t toStatusT(Status status) {
return ERROR_DRM_CANNOT_HANDLE;
break;
case Status::ERROR_DRM_INVALID_STATE:
- return ERROR_DRM_TAMPER_DETECTED;
+ return ERROR_DRM_INVALID_STATE;
break;
case Status::BAD_VALUE:
return BAD_VALUE;
@@ -238,6 +282,19 @@ static status_t toStatusT(Status status) {
}
}
+static status_t toStatusT_1_2(Status_V1_2 status) {
+ switch (status) {
+ case Status_V1_2::ERROR_DRM_RESOURCE_CONTENTION:
+ return ERROR_DRM_RESOURCE_CONTENTION;
+ case Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE:
+ return ERROR_DRM_FRAME_TOO_LARGE;
+ case Status_V1_2::ERROR_DRM_INSUFFICIENT_SECURITY:
+ return ERROR_DRM_INSUFFICIENT_SECURITY;
+ default:
+ return toStatusT(static_cast<Status>(status));
+ }
+}
+
Mutex DrmHal::mLock;
@@ -297,39 +354,51 @@ void DrmHal::cleanup() {
setListener(NULL);
mInitCheck = NO_INIT;
-
- if (mPlugin != NULL) {
+ if (mPluginV1_2 != NULL) {
+ if (!mPluginV1_2->setListener(NULL).isOk()) {
+ mInitCheck = DEAD_OBJECT;
+ }
+ } else if (mPlugin != NULL) {
if (!mPlugin->setListener(NULL).isOk()) {
mInitCheck = DEAD_OBJECT;
}
}
mPlugin.clear();
mPluginV1_1.clear();
+ mPluginV1_2.clear();
}
Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
Vector<sp<IDrmFactory>> factories;
- auto manager = hardware::defaultServiceManager();
+ auto manager = hardware::defaultServiceManager1_2();
if (manager != NULL) {
- manager->listByInterface(drm::V1_0::IDrmFactory::descriptor,
+ manager->listManifestByInterface(drm::V1_0::IDrmFactory::descriptor,
[&factories](const hidl_vec<hidl_string> &registered) {
for (const auto &instance : registered) {
auto factory = drm::V1_0::IDrmFactory::getService(instance);
if (factory != NULL) {
- ALOGD("found drm@1.0 IDrmFactory %s", instance.c_str());
factories.push_back(factory);
}
}
}
);
- manager->listByInterface(drm::V1_1::IDrmFactory::descriptor,
+ manager->listManifestByInterface(drm::V1_1::IDrmFactory::descriptor,
[&factories](const hidl_vec<hidl_string> &registered) {
for (const auto &instance : registered) {
auto factory = drm::V1_1::IDrmFactory::getService(instance);
if (factory != NULL) {
- ALOGD("found drm@1.1 IDrmFactory %s", instance.c_str());
+ factories.push_back(factory);
+ }
+ }
+ }
+ );
+ 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);
}
}
@@ -448,6 +517,17 @@ Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
}
Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
+ const hidl_vec<KeyStatus_V1_0>& keyStatusList_V1_0, bool hasNewUsableKey) {
+ std::vector<KeyStatus> keyStatusVec;
+ for (const auto &keyStatus_V1_0 : keyStatusList_V1_0) {
+ keyStatusVec.push_back({keyStatus_V1_0.keyId,
+ static_cast<KeyStatusType>(keyStatus_V1_0.type)});
+ }
+ hidl_vec<KeyStatus> keyStatusList_V1_2(keyStatusVec);
+ return sendKeysChange_1_2(sessionId, keyStatusList_V1_2, hasNewUsableKey);
+}
+
+Return<void> DrmHal::sendKeysChange_1_2(const hidl_vec<uint8_t>& sessionId,
const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
mEventLock.lock();
@@ -477,6 +557,9 @@ Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
case KeyStatusType::STATUSPENDING:
type = DrmPlugin::kKeyStatusType_StatusPending;
break;
+ case KeyStatusType::USABLEINFUTURE:
+ type = DrmPlugin::kKeyStatusType_UsableInFuture;
+ break;
case KeyStatusType::INTERNALERROR:
default:
type = DrmPlugin::kKeyStatusType_InternalError;
@@ -501,32 +584,80 @@ Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
return Void();
}
-bool DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
- Mutex::Autolock autoLock(mLock);
+Return<void> DrmHal::sendSessionLostState(
+ const hidl_vec<uint8_t>& sessionId) {
+
+ mEventLock.lock();
+ sp<IDrmClient> listener = mListener;
+ mEventLock.unlock();
+
+ if (listener != NULL) {
+ Parcel obj;
+ writeByteArray(obj, sessionId);
+ Mutex::Autolock lock(mNotifyLock);
+ listener->notify(DrmPlugin::kDrmPluginEventSessionLostState, 0, &obj);
+ }
+ return Void();
+}
+
+status_t DrmHal::matchMimeTypeAndSecurityLevel(const sp<IDrmFactory> &factory,
+ const uint8_t uuid[16],
+ const String8 &mimeType,
+ DrmPlugin::SecurityLevel level,
+ bool *isSupported) {
+ *isSupported = false;
+
+ // handle default value cases
+ if (level == DrmPlugin::kSecurityLevelUnknown) {
+ if (mimeType == "") {
+ // isCryptoSchemeSupported(uuid)
+ *isSupported = true;
+ } else {
+ // isCryptoSchemeSupported(uuid, mimeType)
+ *isSupported = factory->isContentTypeSupported(mimeType.string());
+ }
+ return OK;
+ } else if (mimeType == "") {
+ return BAD_VALUE;
+ }
- for (size_t i = 0; i < mFactories.size(); i++) {
+ sp<drm::V1_2::IDrmFactory> factoryV1_2 = drm::V1_2::IDrmFactory::castFrom(factory);
+ if (factoryV1_2 == NULL) {
+ return ERROR_UNSUPPORTED;
+ } else {
+ *isSupported = factoryV1_2->isCryptoSchemeSupported_1_2(uuid,
+ mimeType.string(), toHidlSecurityLevel(level));
+ return OK;
+ }
+}
+
+status_t DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16],
+ const String8 &mimeType,
+ DrmPlugin::SecurityLevel level,
+ bool *isSupported) {
+ Mutex::Autolock autoLock(mLock);
+ *isSupported = false;
+ for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
- if (mimeType != "") {
- if (mFactories[i]->isContentTypeSupported(mimeType.string())) {
- return true;
- }
- } else {
- return true;
- }
+ return matchMimeTypeAndSecurityLevel(mFactories[i],
+ uuid, mimeType, level, isSupported);
}
}
- return false;
+ return OK;
}
status_t DrmHal::createPlugin(const uint8_t uuid[16],
const String8& appPackageName) {
Mutex::Autolock autoLock(mLock);
- for (size_t i = 0; i < mFactories.size(); i++) {
+ for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
- mPlugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
- if (mPlugin != NULL) {
+ auto plugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
+ if (plugin != NULL) {
+ mPlugin = plugin;
mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
+ mPluginV1_2 = drm::V1_2::IDrmPlugin::castFrom(mPlugin);
+ break;
}
}
}
@@ -534,13 +665,22 @@ status_t DrmHal::createPlugin(const uint8_t uuid[16],
if (mPlugin == NULL) {
mInitCheck = ERROR_UNSUPPORTED;
} else {
- if (!mPlugin->setListener(this).isOk()) {
+ mInitCheck = OK;
+ if (mPluginV1_2 != NULL) {
+ if (!mPluginV1_2->setListener(this).isOk()) {
+ mInitCheck = DEAD_OBJECT;
+ }
+ } else if (!mPlugin->setListener(this).isOk()) {
mInitCheck = DEAD_OBJECT;
- } else {
- mInitCheck = OK;
+ }
+ if (mInitCheck != OK) {
+ mPlugin.clear();
+ mPluginV1_1.clear();
+ mPluginV1_2.clear();
}
}
+
return mInitCheck;
}
@@ -554,30 +694,15 @@ status_t DrmHal::openSession(DrmPlugin::SecurityLevel level,
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
- SecurityLevel hSecurityLevel;
+ SecurityLevel hSecurityLevel = toHidlSecurityLevel(level);
bool setSecurityLevel = true;
- switch(level) {
- case DrmPlugin::kSecurityLevelSwSecureCrypto:
- hSecurityLevel = SecurityLevel::SW_SECURE_CRYPTO;
- break;
- case DrmPlugin::kSecurityLevelSwSecureDecode:
- hSecurityLevel = SecurityLevel::SW_SECURE_DECODE;
- break;
- case DrmPlugin::kSecurityLevelHwSecureCrypto:
- hSecurityLevel = SecurityLevel::HW_SECURE_CRYPTO;
- break;
- case DrmPlugin::kSecurityLevelHwSecureDecode:
- hSecurityLevel = SecurityLevel::HW_SECURE_DECODE;
- break;
- case DrmPlugin::kSecurityLevelHwSecureAll:
- hSecurityLevel = SecurityLevel::HW_SECURE_ALL;
- break;
- case DrmPlugin::kSecurityLevelMax:
+ if (level == DrmPlugin::kSecurityLevelMax) {
setSecurityLevel = false;
- break;
- default:
- return ERROR_DRM_CANNOT_HANDLE;
+ } else {
+ if (hSecurityLevel == SecurityLevel::UNKNOWN) {
+ return ERROR_DRM_CANNOT_HANDLE;
+ }
}
status_t err = UNKNOWN_ERROR;
@@ -657,6 +782,39 @@ status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
return DEAD_OBJECT;
}
+static DrmPlugin::KeyRequestType toKeyRequestType(
+ KeyRequestType keyRequestType) {
+ switch (keyRequestType) {
+ case KeyRequestType::INITIAL:
+ return DrmPlugin::kKeyRequestType_Initial;
+ break;
+ case KeyRequestType::RENEWAL:
+ return DrmPlugin::kKeyRequestType_Renewal;
+ break;
+ case KeyRequestType::RELEASE:
+ return DrmPlugin::kKeyRequestType_Release;
+ break;
+ default:
+ return DrmPlugin::kKeyRequestType_Unknown;
+ break;
+ }
+}
+
+static DrmPlugin::KeyRequestType toKeyRequestType_1_1(
+ KeyRequestType_V1_1 keyRequestType) {
+ switch (keyRequestType) {
+ case KeyRequestType_V1_1::NONE:
+ return DrmPlugin::kKeyRequestType_None;
+ break;
+ case KeyRequestType_V1_1::UPDATE:
+ return DrmPlugin::kKeyRequestType_Update;
+ break;
+ default:
+ return toKeyRequestType(static_cast<KeyRequestType>(keyRequestType));
+ break;
+ }
+}
+
status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
Vector<uint8_t> const &initData, String8 const &mimeType,
DrmPlugin::KeyType keyType, KeyedVector<String8,
@@ -683,73 +841,51 @@ status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
status_t err = UNKNOWN_ERROR;
+ Return<void> hResult;
- if (mPluginV1_1 != NULL) {
- Return<void> hResult =
- mPluginV1_1->getKeyRequest_1_1(
+ if (mPluginV1_2 != NULL) {
+ hResult = mPluginV1_2->getKeyRequest_1_2(
+ toHidlVec(sessionId), toHidlVec(initData),
+ toHidlString(mimeType), hKeyType, hOptionalParameters,
+ [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
+ KeyRequestType_V1_1 hKeyRequestType,
+ const hidl_string& hDefaultUrl) {
+ if (status == Status_V1_2::OK) {
+ request = toVector(hRequest);
+ defaultUrl = toString8(hDefaultUrl);
+ *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
+ }
+ err = toStatusT_1_2(status);
+ });
+ } else if (mPluginV1_1 != NULL) {
+ hResult = mPluginV1_1->getKeyRequest_1_1(
toHidlVec(sessionId), toHidlVec(initData),
toHidlString(mimeType), hKeyType, hOptionalParameters,
[&](Status status, const hidl_vec<uint8_t>& hRequest,
- drm::V1_1::KeyRequestType hKeyRequestType,
- const hidl_string& hDefaultUrl) {
-
- if (status == Status::OK) {
- request = toVector(hRequest);
- defaultUrl = toString8(hDefaultUrl);
-
- switch (hKeyRequestType) {
- case drm::V1_1::KeyRequestType::INITIAL:
- *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
- break;
- case drm::V1_1::KeyRequestType::RENEWAL:
- *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
- break;
- case drm::V1_1::KeyRequestType::RELEASE:
- *keyRequestType = DrmPlugin::kKeyRequestType_Release;
- break;
- case drm::V1_1::KeyRequestType::NONE:
- *keyRequestType = DrmPlugin::kKeyRequestType_None;
- break;
- case drm::V1_1::KeyRequestType::UPDATE:
- *keyRequestType = DrmPlugin::kKeyRequestType_Update;
- break;
- default:
- *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
- break;
- }
- err = toStatusT(status);
- }
- });
- return hResult.isOk() ? err : DEAD_OBJECT;
- }
-
- Return<void> hResult = mPlugin->getKeyRequest(toHidlVec(sessionId),
- toHidlVec(initData), toHidlString(mimeType), hKeyType, hOptionalParameters,
- [&](Status status, const hidl_vec<uint8_t>& hRequest,
- drm::V1_0::KeyRequestType hKeyRequestType,
- const hidl_string& hDefaultUrl) {
-
- if (status == Status::OK) {
- request = toVector(hRequest);
- defaultUrl = toString8(hDefaultUrl);
-
- switch (hKeyRequestType) {
- case drm::V1_0::KeyRequestType::INITIAL:
- *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
- break;
- case drm::V1_0::KeyRequestType::RENEWAL:
- *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
- break;
- case drm::V1_0::KeyRequestType::RELEASE:
- *keyRequestType = DrmPlugin::kKeyRequestType_Release;
- break;
- default:
- *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
- break;
+ KeyRequestType_V1_1 hKeyRequestType,
+ const hidl_string& hDefaultUrl) {
+ if (status == Status::OK) {
+ request = toVector(hRequest);
+ defaultUrl = toString8(hDefaultUrl);
+ *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
}
err = toStatusT(status);
- }
- });
+ });
+ } else {
+ hResult = mPlugin->getKeyRequest(
+ toHidlVec(sessionId), toHidlVec(initData),
+ toHidlString(mimeType), hKeyType, hOptionalParameters,
+ [&](Status status, const hidl_vec<uint8_t>& hRequest,
+ KeyRequestType hKeyRequestType,
+ const hidl_string& hDefaultUrl) {
+ if (status == Status::OK) {
+ request = toVector(hRequest);
+ defaultUrl = toString8(hDefaultUrl);
+ *keyRequestType = toKeyRequestType(hKeyRequestType);
+ }
+ err = toStatusT(status);
+ });
+ }
err = hResult.isOk() ? err : DEAD_OBJECT;
keyRequestTimer.SetAttribute(err);
@@ -831,18 +967,33 @@ status_t DrmHal::getProvisionRequest(String8 const &certType,
INIT_CHECK();
status_t err = UNKNOWN_ERROR;
-
- Return<void> hResult = mPlugin->getProvisionRequest(
- toHidlString(certType), toHidlString(certAuthority),
- [&](Status status, const hidl_vec<uint8_t>& hRequest,
- const hidl_string& hDefaultUrl) {
- if (status == Status::OK) {
- request = toVector(hRequest);
- defaultUrl = toString8(hDefaultUrl);
+ Return<void> hResult;
+
+ if (mPluginV1_2 != NULL) {
+ Return<void> hResult = mPluginV1_2->getProvisionRequest_1_2(
+ toHidlString(certType), toHidlString(certAuthority),
+ [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
+ const hidl_string& hDefaultUrl) {
+ if (status == Status_V1_2::OK) {
+ request = toVector(hRequest);
+ defaultUrl = toString8(hDefaultUrl);
+ }
+ err = toStatusT_1_2(status);
}
- err = toStatusT(status);
- }
- );
+ );
+ } else {
+ Return<void> hResult = mPlugin->getProvisionRequest(
+ toHidlString(certType), toHidlString(certAuthority),
+ [&](Status status, const hidl_vec<uint8_t>& hRequest,
+ const hidl_string& hDefaultUrl) {
+ if (status == Status::OK) {
+ request = toVector(hRequest);
+ defaultUrl = toString8(hDefaultUrl);
+ }
+ err = toStatusT(status);
+ }
+ );
+ }
err = hResult.isOk() ? err : DEAD_OBJECT;
mMetrics.mGetProvisionRequestCounter.Increment(err);
@@ -988,22 +1139,31 @@ status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
}
status_t err = UNKNOWN_ERROR;
- if (mPluginV1_1 == NULL) {
- return ERROR_DRM_CANNOT_HANDLE;
- }
-
*connected = DrmPlugin::kHdcpLevelUnknown;
*max = DrmPlugin::kHdcpLevelUnknown;
- Return<void> hResult = mPluginV1_1->getHdcpLevels(
- [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
- if (status == Status::OK) {
- *connected = toHdcpLevel(hConnected);
- *max = toHdcpLevel(hMax);
- }
- err = toStatusT(status);
- }
- );
+ Return<void> hResult;
+ if (mPluginV1_2 != NULL) {
+ hResult = mPluginV1_2->getHdcpLevels_1_2(
+ [&](Status_V1_2 status, const HdcpLevel_V1_2& hConnected, const HdcpLevel_V1_2& hMax) {
+ if (status == Status_V1_2::OK) {
+ *connected = toHdcpLevel(hConnected);
+ *max = toHdcpLevel(hMax);
+ }
+ err = toStatusT_1_2(status);
+ });
+ } else if (mPluginV1_1 != NULL) {
+ hResult = mPluginV1_1->getHdcpLevels(
+ [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
+ if (status == Status::OK) {
+ *connected = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hConnected));
+ *max = toHdcpLevel(static_cast<HdcpLevel_V1_2>(hMax));
+ }
+ err = toStatusT(status);
+ });
+ } else {
+ return ERROR_DRM_CANNOT_HANDLE;
+ }
return hResult.isOk() ? err : DEAD_OBJECT;
}
@@ -1065,6 +1225,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_UNSUPPORTED;
+ }
+
+ 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_UNSUPPORTED;
+ }
+
+ 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_UNSUPPORTED;
+ }
+ *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);
@@ -1343,22 +1570,22 @@ void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
void DrmHal::reportFrameworkMetrics() const
{
- MediaAnalyticsItem item("mediadrm");
- item.generateSessionID();
- item.setPkgName(mMetrics.GetAppPackageName().c_str());
+ std::unique_ptr<MediaAnalyticsItem> item(MediaAnalyticsItem::create("mediadrm"));
+ item->generateSessionID();
+ item->setPkgName(mMetrics.GetAppPackageName().c_str());
String8 vendor;
String8 description;
status_t result = getPropertyStringInternal(String8("vendor"), vendor);
if (result != OK) {
ALOGE("Failed to get vendor from drm plugin: %d", result);
} else {
- item.setCString("vendor", vendor.c_str());
+ item->setCString("vendor", vendor.c_str());
}
result = getPropertyStringInternal(String8("description"), description);
if (result != OK) {
ALOGE("Failed to get description from drm plugin: %d", result);
} else {
- item.setCString("description", description.c_str());
+ item->setCString("description", description.c_str());
}
std::string serializedMetrics;
@@ -1369,9 +1596,9 @@ void DrmHal::reportFrameworkMetrics() const
std::string b64EncodedMetrics = toBase64StringNoPad(serializedMetrics.data(),
serializedMetrics.size());
if (!b64EncodedMetrics.empty()) {
- item.setCString("serialized_metrics", b64EncodedMetrics.c_str());
+ item->setCString("serialized_metrics", b64EncodedMetrics.c_str());
}
- if (!item.selfrecord()) {
+ if (!item->selfrecord()) {
ALOGE("Failed to self record framework metrics");
}
}
diff --git a/drm/libmediadrm/DrmMetrics.cpp b/drm/libmediadrm/DrmMetrics.cpp
index 4fed707017..308080275b 100644
--- a/drm/libmediadrm/DrmMetrics.cpp
+++ b/drm/libmediadrm/DrmMetrics.cpp
@@ -32,7 +32,7 @@ using ::android::drm_metrics::DrmFrameworkMetrics;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hardware::drm::V1_0::EventType;
-using ::android::hardware::drm::V1_0::KeyStatusType;
+using ::android::hardware::drm::V1_2::KeyStatusType;
using ::android::hardware::drm::V1_1::DrmMetricGroup;
using ::android::os::PersistableBundle;
diff --git a/drm/libmediadrm/IDrm.cpp b/drm/libmediadrm/IDrm.cpp
index 509961fb10..51274d16c1 100644
--- a/drm/libmediadrm/IDrm.cpp
+++ b/drm/libmediadrm/IDrm.cpp
@@ -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> {
@@ -80,18 +83,22 @@ struct BpDrm : public BpInterface<IDrm> {
return reply.readInt32();
}
- virtual bool isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
+ virtual status_t isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType,
+ DrmPlugin::SecurityLevel level, bool *isSupported) {
Parcel data, reply;
data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
data.write(uuid, 16);
data.writeString8(mimeType);
+ data.writeInt32(level);
+
status_t status = remote()->transact(IS_CRYPTO_SUPPORTED, data, &reply);
if (status != OK) {
ALOGE("isCryptoSchemeSupported: binder call failed: %d", status);
- return false;
+ return status;
}
+ *isSupported = static_cast<bool>(reply.readInt32());
- return reply.readInt32() != 0;
+ return reply.readInt32();
}
virtual status_t createPlugin(const uint8_t uuid[16],
@@ -120,11 +127,11 @@ struct BpDrm : public BpInterface<IDrm> {
return reply.readInt32();
}
- virtual status_t openSession(DrmPlugin::SecurityLevel securityLevel,
+ virtual status_t openSession(DrmPlugin::SecurityLevel level,
Vector<uint8_t> &sessionId) {
Parcel data, reply;
data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
- data.writeInt32(securityLevel);
+ data.writeInt32(level);
status_t status = remote()->transact(OPEN_SESSION, data, &reply);
if (status != OK) {
@@ -376,6 +383,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());
@@ -719,7 +772,12 @@ status_t BnDrm::onTransact(
uint8_t uuid[16];
data.read(uuid, sizeof(uuid));
String8 mimeType = data.readString8();
- reply->writeInt32(isCryptoSchemeSupported(uuid, mimeType));
+ DrmPlugin::SecurityLevel level =
+ static_cast<DrmPlugin::SecurityLevel>(data.readInt32());
+ bool isSupported = false;
+ status_t result = isCryptoSchemeSupported(uuid, mimeType, level, &isSupported);
+ reply->writeInt32(isSupported);
+ reply->writeInt32(result);
return OK;
}
@@ -980,6 +1038,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);
diff --git a/drm/libmediadrm/PluginMetricsReporting.cpp b/drm/libmediadrm/PluginMetricsReporting.cpp
index 5cb48bf678..8cd6f969cc 100644
--- a/drm/libmediadrm/PluginMetricsReporting.cpp
+++ b/drm/libmediadrm/PluginMetricsReporting.cpp
@@ -34,17 +34,17 @@ constexpr char kSerializedMetricsField[] = "serialized_metrics";
status_t reportVendorMetrics(const std::string& metrics,
const String8& name,
const String8& appPackageName) {
- MediaAnalyticsItem analyticsItem(name.c_str());
- analyticsItem.generateSessionID();
+ std::unique_ptr<MediaAnalyticsItem> analyticsItem(MediaAnalyticsItem::create(name.c_str()));
+ analyticsItem->generateSessionID();
std::string app_package_name(appPackageName.c_str(), appPackageName.size());
- analyticsItem.setPkgName(app_package_name);
+ analyticsItem->setPkgName(app_package_name);
if (metrics.size() > 0) {
- analyticsItem.setCString(kSerializedMetricsField, metrics.c_str());
+ analyticsItem->setCString(kSerializedMetricsField, metrics.c_str());
}
- if (!analyticsItem.selfrecord()) {
- ALOGE("selfrecord() returned false. sessioId %" PRId64, analyticsItem.getSessionID());
+ if (!analyticsItem->selfrecord()) {
+ ALOGE("selfrecord() returned false. sessioId %" PRId64, analyticsItem->getSessionID());
}
return OK;
diff --git a/drm/libmediadrm/tests/Android.bp b/drm/libmediadrm/tests/Android.bp
index 66c906f2e9..9e0115e635 100644
--- a/drm/libmediadrm/tests/Android.bp
+++ b/drm/libmediadrm/tests/Android.bp
@@ -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",
@@ -33,7 +34,6 @@ cc_test {
// Suppress unused parameter and no error options. These cause problems
// when using the map type in a proto definition.
"-Wno-unused-parameter",
- "-Wno-error",
]
}
diff --git a/drm/libmediadrm/tests/DrmMetrics_test.cpp b/drm/libmediadrm/tests/DrmMetrics_test.cpp
index 64aa9d0c99..5c8a1b0064 100644
--- a/drm/libmediadrm/tests/DrmMetrics_test.cpp
+++ b/drm/libmediadrm/tests/DrmMetrics_test.cpp
@@ -30,7 +30,7 @@
using ::android::drm_metrics::DrmFrameworkMetrics;
using ::android::hardware::hidl_vec;
using ::android::hardware::drm::V1_0::EventType;
-using ::android::hardware::drm::V1_0::KeyStatusType;
+using ::android::hardware::drm::V1_2::KeyStatusType;
using ::android::hardware::drm::V1_0::Status;
using ::android::hardware::drm::V1_1::DrmMetricGroup;
using ::android::os::PersistableBundle;
diff --git a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp
index 1558e8b8da..bf352243ca 100644
--- a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp
+++ b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp
@@ -65,7 +65,20 @@ status_t ClearKeyCasFactory::createPlugin(
*plugin = new ClearKeyCasPlugin(appData, callback);
return OK;
}
-///////////////////////////////////////////////////////////////////////////////
+
+status_t ClearKeyCasFactory::createPlugin(
+ int32_t CA_system_id,
+ void *appData,
+ CasPluginCallbackExt callback,
+ CasPlugin **plugin) {
+ if (!isSystemIdSupported(CA_system_id)) {
+ return BAD_VALUE;
+ }
+
+ *plugin = new ClearKeyCasPlugin(appData, callback);
+ return OK;
+}
+////////////////////////////////////////////////////////////////////////////////
bool ClearKeyDescramblerFactory::isSystemIdSupported(
int32_t CA_system_id) const {
return CA_system_id == sClearKeySystemId;
@@ -84,7 +97,13 @@ status_t ClearKeyDescramblerFactory::createPlugin(
///////////////////////////////////////////////////////////////////////////////
ClearKeyCasPlugin::ClearKeyCasPlugin(
void *appData, CasPluginCallback callback)
- : mCallback(callback), mAppData(appData) {
+ : mCallback(callback), mCallbackExt(NULL), mAppData(appData) {
+ ALOGV("CTOR");
+}
+
+ClearKeyCasPlugin::ClearKeyCasPlugin(
+ void *appData, CasPluginCallbackExt callback)
+ : mCallback(NULL), mCallbackExt(callback), mAppData(appData) {
ALOGV("CTOR");
}
@@ -167,8 +186,27 @@ status_t ClearKeyCasPlugin::sendEvent(
// Echo the received event to the callback.
// Clear key plugin doesn't use any event, echo'ing for testing only.
if (mCallback != NULL) {
- mCallback((void*)mAppData, event, arg, (uint8_t*)eventData.data(), eventData.size());
+ mCallback((void*)mAppData, event, arg, (uint8_t*)eventData.data(),
+ eventData.size());
+ } else if (mCallbackExt != NULL) {
+ mCallbackExt((void*)mAppData, event, arg, (uint8_t*)eventData.data(),
+ eventData.size(), NULL);
+ }
+ return OK;
+}
+
+status_t ClearKeyCasPlugin::sendSessionEvent(
+ const CasSessionId &sessionId, int32_t event,
+ int arg, const CasData &eventData) {
+ ALOGV("sendSessionEvent: sessionId=%s, event=%d, arg=%d",
+ sessionIdToString(sessionId).string(), event, arg);
+ // Echo the received event to the callback.
+ // Clear key plugin doesn't use any event, echo'ing for testing only.
+ if (mCallbackExt != NULL) {
+ mCallbackExt((void*)mAppData, event, arg, (uint8_t*)eventData.data(),
+ eventData.size(), &sessionId);
}
+
return OK;
}
diff --git a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h
index 389e1728d7..f48d5b1d13 100644
--- a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h
+++ b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h
@@ -47,6 +47,11 @@ public:
void *appData,
CasPluginCallback callback,
CasPlugin **plugin) override;
+ virtual status_t createPlugin(
+ int32_t CA_system_id,
+ void *appData,
+ CasPluginCallbackExt callback,
+ CasPlugin **plugin) override;
};
class ClearKeyDescramblerFactory : public DescramblerFactory {
@@ -63,6 +68,7 @@ public:
class ClearKeyCasPlugin : public CasPlugin {
public:
ClearKeyCasPlugin(void *appData, CasPluginCallback callback);
+ ClearKeyCasPlugin(void *appData, CasPluginCallbackExt callback);
virtual ~ClearKeyCasPlugin();
virtual status_t setPrivateData(
@@ -85,6 +91,10 @@ public:
virtual status_t sendEvent(
int32_t event, int32_t arg, const CasData &eventData) override;
+ virtual status_t sendSessionEvent(
+ const CasSessionId &sessionId,
+ int32_t event, int32_t arg, const CasData &eventData) override;
+
virtual status_t provision(const String8 &str) override;
virtual status_t refreshEntitlements(
@@ -94,6 +104,7 @@ private:
Mutex mKeyFetcherLock;
std::unique_ptr<KeyFetcher> mKeyFetcher;
CasPluginCallback mCallback;
+ CasPluginCallbackExt mCallbackExt;
void* mAppData;
};
diff --git a/drm/mediacas/plugins/mock/MockCasPlugin.cpp b/drm/mediacas/plugins/mock/MockCasPlugin.cpp
index 8404a83935..2964791413 100644
--- a/drm/mediacas/plugins/mock/MockCasPlugin.cpp
+++ b/drm/mediacas/plugins/mock/MockCasPlugin.cpp
@@ -60,6 +60,19 @@ status_t MockCasFactory::createPlugin(
return OK;
}
+status_t MockCasFactory::createPlugin(
+ int32_t CA_system_id,
+ void* /*appData*/,
+ CasPluginCallbackExt /*callback*/,
+ CasPlugin **plugin) {
+ if (!isSystemIdSupported(CA_system_id)) {
+ return BAD_VALUE;
+ }
+
+ *plugin = new MockCasPlugin();
+ return OK;
+}
+
///////////////////////////////////////////////////////////////////////////////
bool MockDescramblerFactory::isSystemIdSupported(int32_t CA_system_id) const {
@@ -170,6 +183,16 @@ status_t MockCasPlugin::sendEvent(
return OK;
}
+status_t MockCasPlugin::sendSessionEvent(
+ const CasSessionId &sessionId, int32_t event,
+ int /*arg*/, const CasData& /*eventData*/) {
+ ALOGV("sendSessionEvent: sessionId=%s, event=%d",
+ arrayToString(sessionId).string(), event);
+ Mutex::Autolock lock(mLock);
+
+ return OK;
+}
+
status_t MockCasPlugin::provision(const String8 &str) {
ALOGV("provision: provisionString=%s", str.string());
Mutex::Autolock lock(mLock);
diff --git a/drm/mediacas/plugins/mock/MockCasPlugin.h b/drm/mediacas/plugins/mock/MockCasPlugin.h
index 81069906ed..74b540cc82 100644
--- a/drm/mediacas/plugins/mock/MockCasPlugin.h
+++ b/drm/mediacas/plugins/mock/MockCasPlugin.h
@@ -42,6 +42,11 @@ public:
void *appData,
CasPluginCallback callback,
CasPlugin **plugin) override;
+ virtual status_t createPlugin(
+ int32_t CA_system_id,
+ void *appData,
+ CasPluginCallbackExt callback,
+ CasPlugin **plugin) override;
};
class MockDescramblerFactory : public DescramblerFactory {
@@ -80,7 +85,11 @@ public:
virtual status_t sendEvent(
int32_t event, int32_t arg, const CasData &eventData) override;
- virtual status_t provision(const String8 &str) override;
+ virtual status_t sendSessionEvent(
+ const CasSessionId &sessionId,
+ int32_t event, int32_t arg, const CasData &eventData) override;
+
+ virtual status_t provision(const String8 &str) override;
virtual status_t refreshEntitlements(
int32_t refreshType, const CasData &refreshData) override;
diff --git a/drm/mediadrm/Android.bp b/drm/mediadrm/Android.bp
deleted file mode 100644
index b9f07f1ecd..0000000000
--- a/drm/mediadrm/Android.bp
+++ /dev/null
@@ -1 +0,0 @@
-subdirs = ["plugins/*"]
diff --git a/drm/mediadrm/plugins/clearkey/common/Utils.cpp b/drm/mediadrm/plugins/clearkey/common/Utils.cpp
index 93c643b636..d48b0a8c91 100644
--- a/drm/mediadrm/plugins/clearkey/common/Utils.cpp
+++ b/drm/mediadrm/plugins/clearkey/common/Utils.cpp
@@ -27,4 +27,18 @@ bool operator<(const Vector<uint8_t> &lhs, const Vector<uint8_t> &rhs) {
return memcmp((void *)lhs.array(), (void *)rhs.array(), rhs.size()) < 0;
}
+std::string ByteArrayToHexString(const uint8_t* in_buffer, size_t length) {
+ static const char kHexChars[] = "0123456789ABCDEF";
+
+ // Each input byte creates two output hex characters.
+ std::string out_buffer(length * 2, '\0');
+
+ for (size_t i = 0; i < length; ++i) {
+ char byte = in_buffer[i];
+ out_buffer[(i * 2)] = kHexChars[(byte >> 4) & 0xf];
+ out_buffer[(i * 2) + 1] = kHexChars[byte & 0xf];
+ }
+ return out_buffer;
+}
+
} // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/common/include/Utils.h b/drm/mediadrm/plugins/clearkey/common/include/Utils.h
index 25431247e0..aa571c0874 100644
--- a/drm/mediadrm/plugins/clearkey/common/include/Utils.h
+++ b/drm/mediadrm/plugins/clearkey/common/include/Utils.h
@@ -17,14 +17,16 @@
#ifndef CLEARKEY_UTILS_H_
#define CLEARKEY_UTILS_H_
+#include <string>
#include <utils/Vector.h>
+namespace android {
// Add a comparison operator for this Vector specialization so that it can be
// used as a key in a KeyedVector.
-namespace android {
-
bool operator<(const Vector<uint8_t> &lhs, const Vector<uint8_t> &rhs);
+std::string ByteArrayToHexString(const uint8_t* in_buffer, size_t length);
+
} // namespace android
#define UNUSED(x) (void)(x);
diff --git a/drm/mediadrm/plugins/clearkey/default/Android.bp b/drm/mediadrm/plugins/clearkey/default/Android.bp
index 7ba57088cc..9803d32d96 100644
--- a/drm/mediadrm/plugins/clearkey/default/Android.bp
+++ b/drm/mediadrm/plugins/clearkey/default/Android.bp
@@ -61,7 +61,3 @@ cc_library_shared {
},
}
-//########################################################################
-// Build unit tests
-
-subdirs = ["tests"]
diff --git a/drm/mediadrm/plugins/clearkey/hidl/AesCtrDecryptor.cpp b/drm/mediadrm/plugins/clearkey/hidl/AesCtrDecryptor.cpp
index 2fce07902e..0ac879c239 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/AesCtrDecryptor.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/AesCtrDecryptor.cpp
@@ -26,7 +26,7 @@
namespace android {
namespace hardware {
namespace drm {
-namespace V1_1 {
+namespace V1_2 {
namespace clearkey {
using ::android::hardware::drm::V1_0::SubSample;
@@ -79,7 +79,7 @@ Status AesCtrDecryptor::decrypt(
}
} // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
} // namespace drm
} // namespace hardware
} // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/Android.bp b/drm/mediadrm/plugins/clearkey/hidl/Android.bp
index 341d4f645d..e91e918b1d 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/Android.bp
+++ b/drm/mediadrm/plugins/clearkey/hidl/Android.bp
@@ -14,8 +14,8 @@
// limitations under the License.
//
-cc_binary {
- name: "android.hardware.drm@1.1-service.clearkey",
+cc_defaults {
+ name: "clearkey_service_defaults",
vendor: true,
srcs: [
@@ -25,23 +25,24 @@ cc_binary {
"CreatePluginFactories.cpp",
"CryptoFactory.cpp",
"CryptoPlugin.cpp",
+ "DeviceFiles.cpp",
"DrmFactory.cpp",
"DrmPlugin.cpp",
"InitDataParser.cpp",
"JsonWebKey.cpp",
+ "MemoryFileSystem.cpp",
"Session.cpp",
"SessionLibrary.cpp",
- "service.cpp",
],
relative_install_path: "hw",
cflags: ["-Wall", "-Werror"],
- init_rc: ["android.hardware.drm@1.1-service.clearkey.rc"],
shared_libs: [
"android.hardware.drm@1.0",
"android.hardware.drm@1.1",
+ "android.hardware.drm@1.2",
"libbase",
"libbinder",
"libcrypto",
@@ -49,11 +50,13 @@ cc_binary {
"libhidlmemory",
"libhidltransport",
"liblog",
+ "libprotobuf-cpp-lite",
"libutils",
],
static_libs: [
"libclearkeycommon",
+ "libclearkeydevicefiles-protos",
"libjsmn",
],
@@ -65,4 +68,26 @@ cc_binary {
integer_overflow: true,
},
}
+cc_library_static {
+ name: "libclearkeydevicefiles-protos",
+ vendor: true,
+ proto: {
+ export_proto_headers: true,
+ type: "lite",
+ },
+ srcs: ["protos/DeviceFiles.proto"],
+}
+cc_binary {
+ name: "android.hardware.drm@1.2-service.clearkey",
+ defaults: ["clearkey_service_defaults"],
+ srcs: ["service.cpp"],
+ init_rc: ["android.hardware.drm@1.2-service.clearkey.rc"],
+}
+cc_binary {
+ name: "android.hardware.drm@1.2-service-lazy.clearkey",
+ overrides: ["android.hardware.drm@1.2-service.clearkey"],
+ defaults: ["clearkey_service_defaults"],
+ srcs: ["serviceLazy.cpp"],
+ init_rc: ["android.hardware.drm@1.2-service-lazy.clearkey.rc"],
+}
diff --git a/drm/mediadrm/plugins/clearkey/hidl/Base64.cpp b/drm/mediadrm/plugins/clearkey/hidl/Base64.cpp
index c2ed7513f4..657a42f2e3 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/Base64.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/Base64.cpp
@@ -21,7 +21,7 @@
namespace android {
namespace hardware {
namespace drm {
-namespace V1_1 {
+namespace V1_2 {
namespace clearkey {
sp<Buffer> decodeBase64(const std::string &s) {
@@ -169,7 +169,7 @@ void encodeBase64Url(const void *_data, size_t size, std::string *out) {
}
} // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
} // namespace drm
} // namespace hardware
} // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/Buffer.cpp b/drm/mediadrm/plugins/clearkey/hidl/Buffer.cpp
index e58f58a379..75f8395a16 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/Buffer.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/Buffer.cpp
@@ -21,7 +21,7 @@
namespace android {
namespace hardware {
namespace drm {
-namespace V1_1 {
+namespace V1_2 {
namespace clearkey {
Buffer::Buffer(size_t capacity)
@@ -47,7 +47,7 @@ Buffer::~Buffer() {
}
} // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
} // namespace drm
} // namespace hardware
} // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/CreatePluginFactories.cpp b/drm/mediadrm/plugins/clearkey/hidl/CreatePluginFactories.cpp
index 1ba5c6a9ec..1410d77319 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/CreatePluginFactories.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/CreatePluginFactories.cpp
@@ -22,7 +22,7 @@
namespace android {
namespace hardware {
namespace drm {
-namespace V1_1 {
+namespace V1_2 {
namespace clearkey {
extern "C" {
@@ -38,7 +38,7 @@ ICryptoFactory* createCryptoFactory() {
} // extern "C"
} // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
} // namespace drm
} // namespace hardware
} // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/CryptoFactory.cpp b/drm/mediadrm/plugins/clearkey/hidl/CryptoFactory.cpp
index 0848cef1f2..2a48db6ca9 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/CryptoFactory.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/CryptoFactory.cpp
@@ -27,7 +27,7 @@
namespace android {
namespace hardware {
namespace drm {
-namespace V1_1 {
+namespace V1_2 {
namespace clearkey {
Return<bool> CryptoFactory::isCryptoSchemeSupported(
@@ -60,7 +60,7 @@ Return<void> CryptoFactory::createPlugin(
}
} // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
} // namespace drm
} // namespace hardware
} // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp b/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp
index cd2224db97..3ecf6d5acd 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp
@@ -27,7 +27,7 @@
namespace android {
namespace hardware {
namespace drm {
-namespace V1_1 {
+namespace V1_2 {
namespace clearkey {
using ::android::hardware::drm::V1_0::BufferType;
@@ -42,10 +42,40 @@ Return<void> CryptoPlugin::setSharedBufferBase(
return Void();
}
+Return<void> CryptoPlugin::decrypt(
+ 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_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);
+ bytesWritten = hBytesWritten;
+ detailedError = hDetailedError;
+ }
+ );
+
+ status = hResult.isOk() ? status : Status::ERROR_DRM_CANNOT_HANDLE;
+ _hidl_cb(status, bytesWritten, detailedError);
+ return Void();
+}
+
// Returns negative values for error code and positive values for the size of
// decrypted data. In theory, the output size can be larger than the input
// size, but in practice this will never happen for AES-CTR.
-Return<void> CryptoPlugin::decrypt(
+Return<void> CryptoPlugin::decrypt_1_2(
bool secure,
const hidl_array<uint8_t, KEY_ID_SIZE>& keyId,
const hidl_array<uint8_t, KEY_IV_SIZE>& iv,
@@ -55,17 +85,17 @@ Return<void> CryptoPlugin::decrypt(
const SharedBuffer& source,
uint64_t offset,
const DestinationBuffer& destination,
- decrypt_cb _hidl_cb) {
+ decrypt_1_2_cb _hidl_cb) {
UNUSED(pattern);
if (secure) {
- _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0,
+ _hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0,
"Secure decryption is not supported with ClearKey.");
return Void();
}
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();
}
@@ -73,24 +103,24 @@ Return<void> CryptoPlugin::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();
}
} else {
- _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0,
+ _hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0,
"destination type not supported");
return Void();
}
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();
}
@@ -102,18 +132,19 @@ Return<void> CryptoPlugin::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();
}
base = static_cast<uint8_t *>(static_cast<void *>(destBase->getPointer()));
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_FRAME_TOO_LARGE, 0, "invalid buffer size");
return Void();
}
destPtr = static_cast<void *>(base + destination.nonsecureMemory.offset);
+
// Calculate the output buffer size and determine if any subsamples are
// encrypted.
size_t destSize = 0;
@@ -121,11 +152,11 @@ Return<void> CryptoPlugin::decrypt(
for (size_t i = 0; i < subSamples.size(); i++) {
const SubSample &subSample = subSamples[i];
if (__builtin_add_overflow(destSize, subSample.numBytesOfClearData, &destSize)) {
- _hidl_cb(Status::BAD_VALUE, 0, "subsample clear size overflow");
+ _hidl_cb(Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE, 0, "subsample clear size overflow");
return Void();
}
if (__builtin_add_overflow(destSize, subSample.numBytesOfEncryptedData, &destSize)) {
- _hidl_cb(Status::BAD_VALUE, 0, "subsample encrypted size overflow");
+ _hidl_cb(Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE, 0, "subsample encrypted size overflow");
return Void();
}
if (subSample.numBytesOfEncryptedData > 0) {
@@ -134,13 +165,13 @@ Return<void> CryptoPlugin::decrypt(
}
if (destSize > destBuffer.size) {
- _hidl_cb(Status::BAD_VALUE, 0, "subsample sum too large");
+ _hidl_cb(Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE, 0, "subsample sum too large");
return Void();
}
if (mode == Mode::UNENCRYPTED) {
if (haveEncryptedSubsamples) {
- _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();
}
@@ -156,22 +187,21 @@ Return<void> CryptoPlugin::decrypt(
}
}
- _hidl_cb(Status::OK, static_cast<ssize_t>(offset), "");
+ _hidl_cb(Status_V1_2::OK, static_cast<ssize_t>(offset), "");
return Void();
} else if (mode == Mode::AES_CTR) {
size_t bytesDecrypted;
- Status res = mSession->decrypt(keyId.data(), iv.data(), srcPtr,
+ Status_V1_2 res = mSession->decrypt(keyId.data(), iv.data(), srcPtr,
static_cast<uint8_t*>(destPtr), toVector(subSamples), &bytesDecrypted);
- if (res == Status::OK) {
- _hidl_cb(Status::OK, static_cast<ssize_t>(bytesDecrypted), "");
+ if (res == Status_V1_2::OK) {
+ _hidl_cb(Status_V1_2::OK, static_cast<ssize_t>(bytesDecrypted), "");
return Void();
} else {
- _hidl_cb(Status::ERROR_DRM_DECRYPT, static_cast<ssize_t>(res),
- "Decryption Error");
+ _hidl_cb(res, 0, "Decryption Error");
return Void();
}
} else {
- _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0,
+ _hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0,
"Selected encryption mode is not supported by the ClearKey DRM Plugin.");
return Void();
}
@@ -191,7 +221,7 @@ Return<Status> CryptoPlugin::setMediaDrmSession(
}
} // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
} // namespace drm
} // namespace hardware
} // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/DeviceFiles.cpp b/drm/mediadrm/plugins/clearkey/hidl/DeviceFiles.cpp
new file mode 100644
index 0000000000..2415b6fe5e
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/DeviceFiles.cpp
@@ -0,0 +1,252 @@
+// 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.
+
+#include <utils/Log.h>
+
+#include <string>
+#include <sys/stat.h>
+
+#include "DeviceFiles.h"
+#include "Utils.h"
+
+#include <openssl/sha.h>
+
+// Protobuf generated classes.
+using android::hardware::drm::V1_2::clearkey::OfflineFile;
+using android::hardware::drm::V1_2::clearkey::HashedFile;
+using android::hardware::drm::V1_2::clearkey::License;
+using android::hardware::drm::V1_2::clearkey::License_LicenseState_ACTIVE;
+using android::hardware::drm::V1_2::clearkey::License_LicenseState_RELEASING;
+
+namespace {
+const char kLicenseFileNameExt[] = ".lic";
+
+bool Hash(const std::string& data, std::string* hash) {
+ if (!hash) return false;
+
+ hash->resize(SHA256_DIGEST_LENGTH);
+
+ const unsigned char* input = reinterpret_cast<const unsigned char*>(data.data());
+ unsigned char* output = reinterpret_cast<unsigned char*>(&(*hash)[0]);
+ SHA256(input, data.size(), output);
+ return true;
+}
+
+} // namespace
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace V1_2 {
+namespace clearkey {
+
+bool DeviceFiles::StoreLicense(
+ const std::string& keySetId, LicenseState state,
+ const std::string& licenseResponse) {
+
+ OfflineFile file;
+ file.set_type(OfflineFile::LICENSE);
+ file.set_version(OfflineFile::VERSION_1);
+
+ License* license = file.mutable_license();
+ switch (state) {
+ case kLicenseStateActive:
+ license->set_state(License_LicenseState_ACTIVE);
+ license->set_license(licenseResponse);
+ break;
+ case kLicenseStateReleasing:
+ license->set_state(License_LicenseState_RELEASING);
+ license->set_license(licenseResponse);
+ break;
+ default:
+ ALOGW("StoreLicense: Unknown license state: %u", state);
+ return false;
+ }
+
+ std::string serializedFile;
+ file.SerializeToString(&serializedFile);
+
+ return StoreFileWithHash(keySetId + kLicenseFileNameExt, serializedFile);
+}
+
+bool DeviceFiles::StoreFileWithHash(const std::string& fileName,
+ const std::string& serializedFile) {
+ std::string hash;
+ if (!Hash(serializedFile, &hash)) {
+ ALOGE("StoreFileWithHash: Failed to compute hash");
+ return false;
+ }
+
+ HashedFile hashFile;
+ hashFile.set_file(serializedFile);
+ hashFile.set_hash(hash);
+
+ std::string serializedHashFile;
+ hashFile.SerializeToString(&serializedHashFile);
+
+ return StoreFileRaw(fileName, serializedHashFile);
+}
+
+bool DeviceFiles::StoreFileRaw(const std::string& fileName, const std::string& serializedHashFile) {
+ MemoryFileSystem::MemoryFile memFile;
+ memFile.setFileName(fileName);
+ memFile.setContent(serializedHashFile);
+ memFile.setFileSize(serializedHashFile.size());
+ size_t len = mFileHandle.Write(fileName, memFile);
+
+ if (len != static_cast<size_t>(serializedHashFile.size())) {
+ ALOGE("StoreFileRaw: Failed to write %s", fileName.c_str());
+ ALOGD("StoreFileRaw: expected=%zd, actual=%zu", serializedHashFile.size(), len);
+ return false;
+ }
+
+ ALOGD("StoreFileRaw: wrote %zu bytes to %s", serializedHashFile.size(), fileName.c_str());
+ return true;
+}
+
+bool DeviceFiles::RetrieveLicense(
+ const std::string& keySetId, LicenseState* state, std::string* offlineLicense) {
+
+ OfflineFile file;
+ if (!RetrieveHashedFile(keySetId + kLicenseFileNameExt, &file)) {
+ return false;
+ }
+
+ if (file.type() != OfflineFile::LICENSE) {
+ ALOGE("RetrieveLicense: Invalid file type");
+ return false;
+ }
+
+ if (file.version() != OfflineFile::VERSION_1) {
+ ALOGE("RetrieveLicense: Invalid file version");
+ return false;
+ }
+
+ if (!file.has_license()) {
+ ALOGE("RetrieveLicense: License not present");
+ return false;
+ }
+
+ License license = file.license();
+ switch (license.state()) {
+ case License_LicenseState_ACTIVE:
+ *state = kLicenseStateActive;
+ break;
+ case License_LicenseState_RELEASING:
+ *state = kLicenseStateReleasing;
+ break;
+ default:
+ ALOGW("RetrieveLicense: Unrecognized license state: %u",
+ kLicenseStateUnknown);
+ *state = kLicenseStateUnknown;
+ break;
+ }
+ *offlineLicense = license.license();
+ return true;
+}
+
+bool DeviceFiles::DeleteLicense(const std::string& keySetId) {
+ return mFileHandle.RemoveFile(keySetId + kLicenseFileNameExt);
+}
+
+bool DeviceFiles::DeleteAllLicenses() {
+ return mFileHandle.RemoveAllFiles();
+}
+
+bool DeviceFiles::LicenseExists(const std::string& keySetId) {
+ return mFileHandle.FileExists(keySetId + kLicenseFileNameExt);
+}
+
+std::vector<std::string> DeviceFiles::ListLicenses() const {
+ std::vector<std::string> licenses = mFileHandle.ListFiles();
+ for (size_t i = 0; i < licenses.size(); i++) {
+ std::string& license = licenses[i];
+ license = license.substr(0, license.size() - strlen(kLicenseFileNameExt));
+ }
+ return licenses;
+}
+
+bool DeviceFiles::RetrieveHashedFile(const std::string& fileName, OfflineFile* deSerializedFile) {
+ if (!deSerializedFile) {
+ ALOGE("RetrieveHashedFile: invalid file parameter");
+ return false;
+ }
+
+ if (!FileExists(fileName)) {
+ ALOGE("RetrieveHashedFile: %s does not exist", fileName.c_str());
+ return false;
+ }
+
+ ssize_t bytes = GetFileSize(fileName);
+ if (bytes <= 0) {
+ ALOGE("RetrieveHashedFile: invalid file size: %s", fileName.c_str());
+ // Remove the corrupted file so the caller will not get the same error
+ // when trying to access the file repeatedly, causing the system to stall.
+ RemoveFile(fileName);
+ return false;
+ }
+
+ std::string serializedHashFile;
+ serializedHashFile.resize(bytes);
+ bytes = mFileHandle.Read(fileName, &serializedHashFile);
+
+ if (bytes != static_cast<ssize_t>(serializedHashFile.size())) {
+ ALOGE("RetrieveHashedFile: Failed to read from %s", fileName.c_str());
+ ALOGV("RetrieveHashedFile: expected: %zd, actual: %zd", serializedHashFile.size(), bytes);
+ // Remove the corrupted file so the caller will not get the same error
+ // when trying to access the file repeatedly, causing the system to stall.
+ RemoveFile(fileName);
+ return false;
+ }
+
+ ALOGV("RetrieveHashedFile: read %zd from %s", bytes, fileName.c_str());
+
+ HashedFile hashFile;
+ if (!hashFile.ParseFromString(serializedHashFile)) {
+ ALOGE("RetrieveHashedFile: Unable to parse hash file");
+ // Remove corrupt file.
+ RemoveFile(fileName);
+ return false;
+ }
+
+ std::string hash;
+ if (!Hash(hashFile.file(), &hash)) {
+ ALOGE("RetrieveHashedFile: Hash computation failed");
+ return false;
+ }
+
+ if (hash != hashFile.hash()) {
+ ALOGE("RetrieveHashedFile: Hash mismatch");
+ // Remove corrupt file.
+ RemoveFile(fileName);
+ return false;
+ }
+
+ if (!deSerializedFile->ParseFromString(hashFile.file())) {
+ ALOGE("RetrieveHashedFile: Unable to parse file");
+ // Remove corrupt file.
+ RemoveFile(fileName);
+ return false;
+ }
+
+ return true;
+}
+
+bool DeviceFiles::FileExists(const std::string& fileName) const {
+ return mFileHandle.FileExists(fileName);
+}
+
+bool DeviceFiles::RemoveFile(const std::string& fileName) {
+ return mFileHandle.RemoveFile(fileName);
+}
+
+ssize_t DeviceFiles::GetFileSize(const std::string& fileName) const {
+ return mFileHandle.GetFileSize(fileName);
+}
+
+} // namespace clearkey
+} // namespace V1_2
+} // namespace drm
+} // namespace hardware
+} // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/DrmFactory.cpp b/drm/mediadrm/plugins/clearkey/hidl/DrmFactory.cpp
index 77557f9da9..9fb5bbefa5 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/DrmFactory.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/DrmFactory.cpp
@@ -30,10 +30,11 @@
namespace android {
namespace hardware {
namespace drm {
-namespace V1_1 {
+namespace V1_2 {
namespace clearkey {
using ::android::hardware::drm::V1_0::Status;
+using ::android::hardware::drm::V1_1::SecurityLevel;
using ::android::hardware::Void;
Return<bool> DrmFactory::isCryptoSchemeSupported(
@@ -41,6 +42,13 @@ Return<bool> DrmFactory::isCryptoSchemeSupported(
return clearkeydrm::isClearKeyUUID(uuid.data());
}
+Return<bool> DrmFactory::isCryptoSchemeSupported_1_2(const hidl_array<uint8_t, 16>& uuid,
+ const hidl_string &mimeType,
+ SecurityLevel level) {
+ return isCryptoSchemeSupported(uuid) && isContentTypeSupported(mimeType) &&
+ level == SecurityLevel::SW_SECURE_CRYPTO;
+}
+
Return<bool> DrmFactory::isContentTypeSupported(const hidl_string &mimeType) {
// This should match the mimeTypes handed by InitDataParser.
return mimeType == kIsoBmffVideoMimeType ||
@@ -71,7 +79,7 @@ Return<void> DrmFactory::createPlugin(
}
} // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
} // namespace drm
} // namespace hardware
} // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp b/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
index 30f745913a..7cb5a38f35 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
@@ -25,11 +25,15 @@
#include "ClearKeyDrmProperties.h"
#include "Session.h"
#include "TypeConvert.h"
+#include "Utils.h"
namespace {
+const std::string kKeySetIdPrefix("ckid");
+const int kKeySetIdLength = 16;
const int kSecureStopIdStart = 100;
+const std::string kOfflineLicense("\"type\":\"persistent-license\"");
const std::string kStreaming("Streaming");
-const std::string kOffline("Offline");
+const std::string kTemporaryLicense("\"type\":\"temporary\"");
const std::string kTrue("True");
const std::string kQueryKeyLicenseType("LicenseType");
@@ -54,18 +58,31 @@ std::vector<uint8_t> uint32ToVector(uint32_t value) {
namespace android {
namespace hardware {
namespace drm {
-namespace V1_1 {
+namespace V1_2 {
namespace clearkey {
+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);
+ }
+}
+
DrmPlugin::DrmPlugin(SessionLibrary* sessionLibrary)
: mSessionLibrary(sessionLibrary),
mOpenSessionOkCount(0),
mCloseSessionOkCount(0),
mCloseSessionNotOpenedCount(0),
- mNextSecureStopId(kSecureStopIdStart) {
+ mNextSecureStopId(kSecureStopIdStart),
+ mMockError(Status_V1_2::OK) {
mPlayPolicy.clear();
initProperties();
mSecureStops.clear();
+ mReleaseKeysMap.clear();
+ std::srand(std::time(nullptr));
}
void DrmPlugin::initProperties() {
@@ -75,6 +92,7 @@ void DrmPlugin::initProperties() {
mStringProperties[kPluginDescriptionKey] = kPluginDescriptionValue;
mStringProperties[kAlgorithmsKey] = kAlgorithmsValue;
mStringProperties[kListenerTestSupportKey] = kListenerTestSupportValue;
+ mStringProperties[kDrmErrorTestKey] = kDrmErrorTestValue;
std::vector<uint8_t> valueVector;
valueVector.clear();
@@ -103,6 +121,7 @@ void DrmPlugin::installSecureStop(const hidl_vec<uint8_t>& sessionId) {
Return<void> DrmPlugin::openSession(openSession_cb _hidl_cb) {
sp<Session> session = mSessionLibrary->createSession();
+ processMockError(session);
std::vector<uint8_t> sessionId = session->sessionId();
Status status = setSecurityLevel(sessionId, SecurityLevel::SW_SECURE_CRYPTO);
@@ -114,6 +133,7 @@ Return<void> DrmPlugin::openSession(openSession_cb _hidl_cb) {
Return<void> DrmPlugin::openSession_1_1(SecurityLevel securityLevel,
openSession_1_1_cb _hidl_cb) {
sp<Session> session = mSessionLibrary->createSession();
+ processMockError(session);
std::vector<uint8_t> sessionId = session->sessionId();
Status status = setSecurityLevel(sessionId, securityLevel);
@@ -129,6 +149,10 @@ Return<Status> DrmPlugin::closeSession(const hidl_vec<uint8_t>& sessionId) {
sp<Session> session = mSessionLibrary->findSession(toVector(sessionId));
if (session.get()) {
+ if (session->getMockError() != Status_V1_2::OK) {
+ sendSessionLostState(sessionId);
+ return Status::ERROR_DRM_INVALID_STATE;
+ }
mCloseSessionOkCount++;
mSessionLibrary->destroySession(session);
return Status::OK;
@@ -137,35 +161,75 @@ Return<Status> DrmPlugin::closeSession(const hidl_vec<uint8_t>& sessionId) {
return Status::ERROR_DRM_SESSION_NOT_OPENED;
}
-Status DrmPlugin::getKeyRequestCommon(const hidl_vec<uint8_t>& scope,
+Status_V1_2 DrmPlugin::getKeyRequestCommon(const hidl_vec<uint8_t>& scope,
const hidl_vec<uint8_t>& initData,
const hidl_string& mimeType,
KeyType keyType,
const hidl_vec<KeyValue>& optionalParameters,
std::vector<uint8_t> *request,
- KeyRequestType *keyRequestType,
+ KeyRequestType_V1_1 *keyRequestType,
std::string *defaultUrl) {
UNUSED(optionalParameters);
+ // GetKeyRequestOfflineKeyTypeNotSupported() in vts 1.0 and 1.1 expects
+ // KeyType::OFFLINE to return ERROR_DRM_CANNOT_HANDLE in clearkey plugin.
+ // Those tests pass in an empty initData, we use the empty initData to
+ // signal such specific use case.
+ if (keyType == KeyType::OFFLINE && 0 == initData.size()) {
+ return Status_V1_2::ERROR_DRM_CANNOT_HANDLE;
+ }
+
*defaultUrl = "";
- *keyRequestType = KeyRequestType::UNKNOWN;
+ *keyRequestType = KeyRequestType_V1_1::UNKNOWN;
*request = std::vector<uint8_t>();
- if (scope.size() == 0) {
- return Status::BAD_VALUE;
+ if (scope.size() == 0 ||
+ (keyType != KeyType::STREAMING &&
+ keyType != KeyType::OFFLINE &&
+ keyType != KeyType::RELEASE)) {
+ return Status_V1_2::BAD_VALUE;
}
- if (keyType != KeyType::STREAMING) {
- return Status::ERROR_DRM_CANNOT_HANDLE;
- }
+ const std::vector<uint8_t> scopeId = toVector(scope);
+ sp<Session> session;
+ if (keyType == KeyType::STREAMING || keyType == KeyType::OFFLINE) {
+ std::vector<uint8_t> sessionId(scopeId.begin(), scopeId.end());
+ session = mSessionLibrary->findSession(sessionId);
+ if (!session.get()) {
+ return Status_V1_2::ERROR_DRM_SESSION_NOT_OPENED;
+ } else if (session->getMockError() != Status_V1_2::OK) {
+ return session->getMockError();
+ }
- sp<Session> session = mSessionLibrary->findSession(toVector(scope));
- if (!session.get()) {
- return Status::ERROR_DRM_SESSION_NOT_OPENED;
+ *keyRequestType = KeyRequestType_V1_1::INITIAL;
}
- Status status = session->getKeyRequest(initData, mimeType, request);
- *keyRequestType = KeyRequestType::INITIAL;
+ Status_V1_2 status = static_cast<Status_V1_2>(
+ session->getKeyRequest(initData, mimeType, keyType, request));
+
+ if (keyType == KeyType::RELEASE) {
+ std::vector<uint8_t> keySetId(scopeId.begin(), scopeId.end());
+ std::string requestString(request->begin(), request->end());
+ if (requestString.find(kOfflineLicense) != std::string::npos) {
+ std::string emptyResponse;
+ std::string keySetIdString(keySetId.begin(), keySetId.end());
+ if (!mFileHandle.StoreLicense(keySetIdString,
+ DeviceFiles::kLicenseStateReleasing,
+ emptyResponse)) {
+ ALOGE("Problem releasing offline license");
+ return Status_V1_2::ERROR_DRM_UNKNOWN;
+ }
+ if (mReleaseKeysMap.find(keySetIdString) == mReleaseKeysMap.end()) {
+ sp<Session> session = mSessionLibrary->createSession();
+ mReleaseKeysMap[keySetIdString] = session->sessionId();
+ } else {
+ ALOGI("key is in use, ignore release request");
+ }
+ } else {
+ ALOGE("Offline license not found, nothing to release");
+ }
+ *keyRequestType = KeyRequestType_V1_1::RELEASE;
+ }
return status;
}
@@ -178,15 +242,15 @@ Return<void> DrmPlugin::getKeyRequest(
getKeyRequest_cb _hidl_cb) {
UNUSED(optionalParameters);
- KeyRequestType keyRequestType = KeyRequestType::UNKNOWN;
+ KeyRequestType_V1_1 keyRequestType = KeyRequestType_V1_1::UNKNOWN;
std::string defaultUrl("");
std::vector<uint8_t> request;
- Status status = getKeyRequestCommon(
+ Status_V1_2 status = getKeyRequestCommon(
scope, initData, mimeType, keyType, optionalParameters,
&request, &keyRequestType, &defaultUrl);
- _hidl_cb(status, toHidlVec(request),
- static_cast<drm::V1_0::KeyRequestType>(keyRequestType),
+ _hidl_cb(toStatus_1_0(status), toHidlVec(request),
+ toKeyRequestType_V1_0(keyRequestType),
hidl_string(defaultUrl));
return Void();
}
@@ -200,10 +264,31 @@ Return<void> DrmPlugin::getKeyRequest_1_1(
getKeyRequest_1_1_cb _hidl_cb) {
UNUSED(optionalParameters);
- KeyRequestType keyRequestType = KeyRequestType::UNKNOWN;
+ KeyRequestType_V1_1 keyRequestType = KeyRequestType_V1_1::UNKNOWN;
+ std::string defaultUrl("");
+ std::vector<uint8_t> request;
+ Status_V1_2 status = getKeyRequestCommon(
+ scope, initData, mimeType, keyType, optionalParameters,
+ &request, &keyRequestType, &defaultUrl);
+
+ _hidl_cb(toStatus_1_0(status), toHidlVec(request),
+ keyRequestType, hidl_string(defaultUrl));
+ return Void();
+}
+
+Return<void> DrmPlugin::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) {
+ UNUSED(optionalParameters);
+
+ KeyRequestType_V1_1 keyRequestType = KeyRequestType_V1_1::UNKNOWN;
std::string defaultUrl("");
std::vector<uint8_t> request;
- Status status = getKeyRequestCommon(
+ Status_V1_2 status = getKeyRequestCommon(
scope, initData, mimeType, keyType, optionalParameters,
&request, &keyRequestType, &defaultUrl);
@@ -227,6 +312,30 @@ void DrmPlugin::setPlayPolicy() {
mPlayPolicy.push_back(policy);
}
+bool DrmPlugin::makeKeySetId(std::string* keySetId) {
+ if (!keySetId) {
+ ALOGE("keySetId destination not provided");
+ return false;
+ }
+ std::vector<uint8_t> ksid(kKeySetIdPrefix.begin(), kKeySetIdPrefix.end());
+ ksid.resize(kKeySetIdLength);
+ std::vector<uint8_t> randomData((kKeySetIdLength - kKeySetIdPrefix.size()) / 2, 0);
+
+ while (keySetId->empty()) {
+ for (auto itr = randomData.begin(); itr != randomData.end(); ++itr) {
+ *itr = std::rand() % 0xff;
+ }
+ *keySetId = kKeySetIdPrefix + ByteArrayToHexString(
+ reinterpret_cast<const uint8_t*>(randomData.data()), randomData.size());
+ if (mFileHandle.LicenseExists(*keySetId)) {
+ // collision, regenerate
+ ALOGV("Retry generating KeySetId");
+ keySetId->clear();
+ }
+ }
+ return true;
+}
+
Return<void> DrmPlugin::provideKeyResponse(
const hidl_vec<uint8_t>& scope,
const hidl_vec<uint8_t>& response,
@@ -237,28 +346,124 @@ Return<void> DrmPlugin::provideKeyResponse(
return Void();
}
- sp<Session> session = mSessionLibrary->findSession(toVector(scope));
+ std::string responseString(
+ reinterpret_cast<const char*>(response.data()), response.size());
+ const std::vector<uint8_t> scopeId = toVector(scope);
+ std::vector<uint8_t> sessionId;
+ std::string keySetId;
+
+ Status status = Status::OK;
+ bool isOfflineLicense = responseString.find(kOfflineLicense) != std::string::npos;
+ bool isRelease = (memcmp(scopeId.data(), kKeySetIdPrefix.data(), kKeySetIdPrefix.size()) == 0);
+ if (isRelease) {
+ keySetId.assign(scopeId.begin(), scopeId.end());
+
+ auto iter = mReleaseKeysMap.find(std::string(keySetId.begin(), keySetId.end()));
+ if (iter != mReleaseKeysMap.end()) {
+ sessionId.assign(iter->second.begin(), iter->second.end());
+ }
+ } else {
+ sessionId.assign(scopeId.begin(), scopeId.end());
+ // non offline license returns empty keySetId
+ keySetId.clear();
+ }
+
+ sp<Session> session = mSessionLibrary->findSession(sessionId);
if (!session.get()) {
_hidl_cb(Status::ERROR_DRM_SESSION_NOT_OPENED, hidl_vec<uint8_t>());
return Void();
}
-
setPlayPolicy();
- std::vector<uint8_t> keySetId;
- Status status = session->provideKeyResponse(response);
+
+ status = session->provideKeyResponse(response);
if (status == Status::OK) {
- // This is for testing AMediaDrm_setOnEventListener only.
- sendEvent(EventType::VENDOR_DEFINED, 0, scope);
- keySetId.clear();
- }
+ if (isOfflineLicense) {
+ if (isRelease) {
+ mFileHandle.DeleteLicense(keySetId);
+ } else {
+ if (!makeKeySetId(&keySetId)) {
+ _hidl_cb(Status::ERROR_DRM_UNKNOWN, hidl_vec<uint8_t>());
+ return Void();
+ }
+
+ bool ok = mFileHandle.StoreLicense(
+ keySetId,
+ DeviceFiles::kLicenseStateActive,
+ std::string(response.begin(), response.end()));
+ if (!ok) {
+ ALOGE("Failed to store offline license");
+ }
+ }
+ }
+
+ // Test calling AMediaDrm listeners.
+ sendEvent(EventType::VENDOR_DEFINED, sessionId, sessionId);
+
+ sendExpirationUpdate(sessionId, 100);
+
+ std::vector<KeyStatus_V1_2> keysStatus;
+ KeyStatus_V1_2 keyStatus;
+
+ std::vector<uint8_t> keyId1 = { 0xA, 0xB, 0xC };
+ keyStatus.keyId = keyId1;
+ keyStatus.type = V1_2::KeyStatusType::USABLE;
+ keysStatus.push_back(keyStatus);
+
+ std::vector<uint8_t> keyId2 = { 0xD, 0xE, 0xF };
+ keyStatus.keyId = keyId2;
+ keyStatus.type = V1_2::KeyStatusType::EXPIRED;
+ keysStatus.push_back(keyStatus);
+
+ std::vector<uint8_t> keyId3 = { 0x0, 0x1, 0x2 };
+ keyStatus.keyId = keyId3;
+ keyStatus.type = V1_2::KeyStatusType::USABLEINFUTURE;
+ keysStatus.push_back(keyStatus);
+
+ sendKeysChange_1_2(sessionId, keysStatus, true);
- installSecureStop(scope);
+ installSecureStop(sessionId);
+ } else {
+ ALOGE("provideKeyResponse returns error=%d", status);
+ }
- // Returns status and empty keySetId
- _hidl_cb(status, toHidlVec(keySetId));
+ std::vector<uint8_t> keySetIdVec(keySetId.begin(), keySetId.end());
+ _hidl_cb(status, toHidlVec(keySetIdVec));
return Void();
}
+Return<Status> DrmPlugin::restoreKeys(
+ const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& keySetId) {
+ if (sessionId.size() == 0 || keySetId.size() == 0) {
+ return Status::BAD_VALUE;
+ }
+
+ DeviceFiles::LicenseState licenseState;
+ std::string offlineLicense;
+ Status status = Status::OK;
+ if (!mFileHandle.RetrieveLicense(std::string(keySetId.begin(), keySetId.end()),
+ &licenseState, &offlineLicense)) {
+ ALOGE("Failed to restore offline license");
+ return Status::ERROR_DRM_NO_LICENSE;
+ }
+
+ if (DeviceFiles::kLicenseStateUnknown == licenseState ||
+ DeviceFiles::kLicenseStateReleasing == licenseState) {
+ ALOGE("Invalid license state=%d", licenseState);
+ return Status::ERROR_DRM_NO_LICENSE;
+ }
+
+ sp<Session> session = mSessionLibrary->findSession(toVector(sessionId));
+ if (!session.get()) {
+ return Status::ERROR_DRM_SESSION_NOT_OPENED;
+ }
+ status = session->provideKeyResponse(std::vector<uint8_t>(offlineLicense.begin(),
+ offlineLicense.end()));
+ if (status != Status::OK) {
+ ALOGE("Failed to restore keys");
+ }
+ return status;
+}
+
Return<void> DrmPlugin::getPropertyString(
const hidl_string& propertyName, getPropertyString_cb _hidl_cb) {
std::string name(propertyName.c_str());
@@ -274,6 +479,8 @@ Return<void> DrmPlugin::getPropertyString(
value = mStringProperties[kAlgorithmsKey];
} else if (name == kListenerTestSupportKey) {
value = mStringProperties[kListenerTestSupportKey];
+ } else if (name == kDrmErrorTestKey) {
+ value = mStringProperties[kDrmErrorTestKey];
} else {
ALOGE("App requested unknown string property %s", name.c_str());
_hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, "");
@@ -318,6 +525,20 @@ Return<Status> DrmPlugin::setPropertyString(
return Status::BAD_VALUE;
}
+ if (name == kDrmErrorTestKey) {
+ if (value == kResourceContentionValue) {
+ mMockError = Status_V1_2::ERROR_DRM_RESOURCE_CONTENTION;
+ } else if (value == kLostStateValue) {
+ mMockError = Status_V1_2::ERROR_DRM_SESSION_LOST_STATE;
+ } else if (value == kFrameTooLargeValue) {
+ mMockError = Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE;
+ } else if (value == kInvalidStateValue) {
+ mMockError = Status_V1_2::ERROR_DRM_INVALID_STATE;
+ } else {
+ mMockError = Status_V1_2::ERROR_DRM_UNKNOWN;
+ }
+ }
+
mStringProperties[key] = std::string(value.c_str());
return Status::OK;
}
@@ -328,6 +549,9 @@ Return<Status> DrmPlugin::setPropertyByteArray(
if (name == kDeviceIdKey) {
ALOGD("Cannot set immutable property: %s", name.c_str());
return Status::BAD_VALUE;
+ } else if (name == kClientIdKey) {
+ mByteArrayProperties[kClientIdKey] = toVector(value);
+ return Status::OK;
}
// Setting of undefined properties is not supported
@@ -465,6 +689,60 @@ Return<void> DrmPlugin::getMetrics(getMetrics_cb _hidl_cb) {
return Void();
}
+Return<void> DrmPlugin::getOfflineLicenseKeySetIds(getOfflineLicenseKeySetIds_cb _hidl_cb) {
+ std::vector<std::string> licenseNames = mFileHandle.ListLicenses();
+ std::vector<KeySetId> keySetIds;
+ if (mMockError != Status_V1_2::OK) {
+ _hidl_cb(toStatus_1_0(mMockError), keySetIds);
+ return Void();
+ }
+ for (const auto& name : licenseNames) {
+ std::vector<uint8_t> keySetId(name.begin(), name.end());
+ keySetIds.push_back(keySetId);
+ }
+ _hidl_cb(Status::OK, keySetIds);
+ return Void();
+}
+
+
+Return<Status> DrmPlugin::removeOfflineLicense(const KeySetId& keySetId) {
+ if (mMockError != Status_V1_2::OK) {
+ return toStatus_1_0(mMockError);
+ }
+ std::string licenseName(keySetId.begin(), keySetId.end());
+ if (mFileHandle.DeleteLicense(licenseName)) {
+ return Status::OK;
+ }
+ return Status::BAD_VALUE;
+}
+
+Return<void> DrmPlugin::getOfflineLicenseState(const KeySetId& keySetId,
+ getOfflineLicenseState_cb _hidl_cb) {
+ std::string licenseName(keySetId.begin(), keySetId.end());
+ DeviceFiles::LicenseState state;
+ std::string license;
+ OfflineLicenseState hLicenseState;
+ if (mMockError != Status_V1_2::OK) {
+ _hidl_cb(toStatus_1_0(mMockError), OfflineLicenseState::UNKNOWN);
+ } else if (mFileHandle.RetrieveLicense(licenseName, &state, &license)) {
+ switch (state) {
+ case DeviceFiles::kLicenseStateActive:
+ hLicenseState = OfflineLicenseState::USABLE;
+ break;
+ case DeviceFiles::kLicenseStateReleasing:
+ hLicenseState = OfflineLicenseState::INACTIVE;
+ break;
+ case DeviceFiles::kLicenseStateUnknown:
+ hLicenseState = OfflineLicenseState::UNKNOWN;
+ break;
+ }
+ _hidl_cb(Status::OK, hLicenseState);
+ } else {
+ _hidl_cb(Status::BAD_VALUE, OfflineLicenseState::UNKNOWN);
+ }
+ return Void();
+}
+
Return<void> DrmPlugin::getSecureStops(getSecureStops_cb _hidl_cb) {
std::vector<SecureStop> stops;
for (auto itr = mSecureStops.begin(); itr != mSecureStops.end(); ++itr) {
@@ -572,7 +850,7 @@ Return<Status> DrmPlugin::removeAllSecureStops() {
}
} // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
} // namespace drm
} // namespace hardware
} // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/InitDataParser.cpp b/drm/mediadrm/plugins/clearkey/hidl/InitDataParser.cpp
index e2bb6517ea..b988ce03ca 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/InitDataParser.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/InitDataParser.cpp
@@ -31,7 +31,7 @@
namespace android {
namespace hardware {
namespace drm {
-namespace V1_1 {
+namespace V1_2 {
namespace clearkey {
namespace {
@@ -45,21 +45,22 @@ std::vector<uint8_t> StrToVector(const std::string& str) {
}
Status InitDataParser::parse(const std::vector<uint8_t>& initData,
- const std::string& type,
+ const std::string& mimeType,
+ V1_0::KeyType keyType,
std::vector<uint8_t>* licenseRequest) {
// Build a list of the key IDs
std::vector<const uint8_t*> keyIds;
- if (type == kIsoBmffVideoMimeType ||
- type == kIsoBmffAudioMimeType ||
- type == kCencInitDataFormat) {
+ if (mimeType == kIsoBmffVideoMimeType.c_str() ||
+ mimeType == kIsoBmffAudioMimeType.c_str() ||
+ mimeType == kCencInitDataFormat.c_str()) {
Status res = parsePssh(initData, &keyIds);
if (res != Status::OK) {
return res;
}
- } else if (type == kWebmVideoMimeType ||
- type == kWebmAudioMimeType ||
- type == kWebmInitDataFormat) {
+ } else if (mimeType == kWebmVideoMimeType.c_str() ||
+ mimeType == kWebmAudioMimeType.c_str() ||
+ mimeType == kWebmInitDataFormat.c_str()) {
// WebM "init data" is just a single key ID
if (initData.size() != kKeyIdSize) {
return Status::ERROR_DRM_CANNOT_HANDLE;
@@ -69,8 +70,12 @@ Status InitDataParser::parse(const std::vector<uint8_t>& initData,
return Status::ERROR_DRM_CANNOT_HANDLE;
}
+ if (keyType == V1_0::KeyType::RELEASE) {
+ // restore key
+ }
+
// Build the request
- std::string requestJson = generateRequest(keyIds);
+ std::string requestJson = generateRequest(keyType, keyIds);
std::vector<uint8_t> requestJsonVec = StrToVector(requestJson);
licenseRequest->clear();
@@ -131,9 +136,11 @@ Status InitDataParser::parsePssh(const std::vector<uint8_t>& initData,
return Status::OK;
}
-std::string InitDataParser::generateRequest(const std::vector<const uint8_t*>& keyIds) {
+std::string InitDataParser::generateRequest(V1_0::KeyType keyType,
+ const std::vector<const uint8_t*>& keyIds) {
const std::string kRequestPrefix("{\"kids\":[");
- const std::string kRequestSuffix("],\"type\":\"temporary\"}");
+ const std::string kTemporarySession("],\"type\":\"temporary\"}");
+ const std::string kPersistentSession("],\"type\":\"persistent-license\"}");
std::string request(kRequestPrefix);
std::string encodedId;
@@ -147,7 +154,12 @@ std::string InitDataParser::generateRequest(const std::vector<const uint8_t*>& k
request.append(encodedId);
request.push_back('\"');
}
- request.append(kRequestSuffix);
+ if (keyType == V1_0::KeyType::STREAMING) {
+ request.append(kTemporarySession);
+ } else if (keyType == V1_0::KeyType::OFFLINE ||
+ keyType == V1_0::KeyType::RELEASE) {
+ request.append(kPersistentSession);
+ }
// Android's Base64 encoder produces padding. EME forbids padding.
const char kBase64Padding = '=';
@@ -157,7 +169,7 @@ std::string InitDataParser::generateRequest(const std::vector<const uint8_t*>& k
}
} // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
} // namespace drm
} // namespace hardware
} // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/JsonWebKey.cpp b/drm/mediadrm/plugins/clearkey/hidl/JsonWebKey.cpp
index cccb41ecc4..d93777d9d9 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/JsonWebKey.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/JsonWebKey.cpp
@@ -22,18 +22,21 @@
#include "Base64.h"
namespace {
+const std::string kBase64Padding("=");
const std::string kKeysTag("keys");
const std::string kKeyTypeTag("kty");
-const std::string kSymmetricKeyValue("oct");
const std::string kKeyTag("k");
const std::string kKeyIdTag("kid");
-const std::string kBase64Padding("=");
+const std::string kMediaSessionType("type");
+const std::string kPersistentLicenseSession("persistent-license");
+const std::string kSymmetricKeyValue("oct");
+const std::string kTemporaryLicenseSession("temporary");
}
namespace android {
namespace hardware {
namespace drm {
-namespace V1_1 {
+namespace V1_2 {
namespace clearkey {
JsonWebKey::JsonWebKey() {
@@ -268,7 +271,7 @@ bool JsonWebKey::parseJsonWebKeySet(const std::string& jsonWebKeySet,
}
} // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
} // namespace drm
} // namespace hardware
} // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/MemoryFileSystem.cpp b/drm/mediadrm/plugins/clearkey/hidl/MemoryFileSystem.cpp
new file mode 100644
index 0000000000..2dcd00fb27
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/MemoryFileSystem.cpp
@@ -0,0 +1,92 @@
+// 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.
+
+#include <utils/Log.h>
+#include <string>
+
+#include "MemoryFileSystem.h"
+#include "Utils.h"
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace V1_2 {
+namespace clearkey {
+
+std::string MemoryFileSystem::GetFileName(const std::string& path) {
+ size_t index = path.find_last_of("/");
+ if (index != std::string::npos) {
+ return path.substr(index+1);
+ } else {
+ return path;
+ }
+}
+
+bool MemoryFileSystem::FileExists(const std::string& fileName) const {
+ auto result = mMemoryFileSystem.find(fileName);
+ return result != mMemoryFileSystem.end();
+}
+
+ssize_t MemoryFileSystem::GetFileSize(const std::string& fileName) const {
+ auto result = mMemoryFileSystem.find(fileName);
+ if (result != mMemoryFileSystem.end()) {
+ return static_cast<ssize_t>(result->second.getFileSize());
+ } else {
+ ALOGE("Failed to get size for %s", fileName.c_str());
+ return -1;
+ }
+}
+
+std::vector<std::string> MemoryFileSystem::ListFiles() const {
+ std::vector<std::string> list;
+ for (const auto& filename : mMemoryFileSystem) {
+ list.push_back(filename.first);
+ }
+ return list;
+}
+
+size_t MemoryFileSystem::Read(const std::string& path, std::string* buffer) {
+ std::string key = GetFileName(path);
+ auto result = mMemoryFileSystem.find(key);
+ if (result != mMemoryFileSystem.end()) {
+ std::string serializedHashFile = result->second.getContent();
+ buffer->assign(serializedHashFile);
+ return buffer->size();
+ } else {
+ ALOGE("Failed to read from %s", path.c_str());
+ return -1;
+ }
+}
+
+size_t MemoryFileSystem::Write(const std::string& path, const MemoryFile& memoryFile) {
+ std::string key = GetFileName(path);
+ auto result = mMemoryFileSystem.find(key);
+ if (result != mMemoryFileSystem.end()) {
+ mMemoryFileSystem.erase(key);
+ }
+ mMemoryFileSystem.insert(std::pair<std::string, MemoryFile>(key, memoryFile));
+ return memoryFile.getFileSize();
+}
+
+bool MemoryFileSystem::RemoveFile(const std::string& fileName) {
+ auto result = mMemoryFileSystem.find(fileName);
+ if (result != mMemoryFileSystem.end()) {
+ mMemoryFileSystem.erase(result);
+ return true;
+ } else {
+ ALOGE("Cannot find license to remove: %s", fileName.c_str());
+ return false;
+ }
+}
+
+bool MemoryFileSystem::RemoveAllFiles() {
+ mMemoryFileSystem.clear();
+ return mMemoryFileSystem.empty();
+}
+
+} // namespace clearkey
+} // namespace V1_2
+} // namespace drm
+} // namespace hardware
+} // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/Session.cpp b/drm/mediadrm/plugins/clearkey/hidl/Session.cpp
index 07c9269c68..a9d7016075 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/Session.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/Session.cpp
@@ -28,7 +28,7 @@
namespace android {
namespace hardware {
namespace drm {
-namespace V1_1 {
+namespace V1_2 {
namespace clearkey {
using ::android::hardware::drm::V1_0::KeyValue;
@@ -42,9 +42,10 @@ using android::Mutex;
Status Session::getKeyRequest(
const std::vector<uint8_t>& initData,
const std::string& mimeType,
+ V1_0::KeyType keyType,
std::vector<uint8_t>* keyRequest) const {
InitDataParser parser;
- return parser.parse(initData, mimeType, keyRequest);
+ return parser.parse(initData, mimeType, keyType, keyRequest);
}
Status Session::provideKeyResponse(const std::vector<uint8_t>& response) {
@@ -67,29 +68,34 @@ Status Session::provideKeyResponse(const std::vector<uint8_t>& response) {
}
}
-Status Session::decrypt(
+Status_V1_2 Session::decrypt(
const KeyId keyId, const Iv iv, const uint8_t* srcPtr,
uint8_t* destPtr, const std::vector<SubSample> subSamples,
size_t* bytesDecryptedOut) {
Mutex::Autolock lock(mMapLock);
+ if (getMockError() != Status_V1_2::OK) {
+ return getMockError();
+ }
+
std::vector<uint8_t> keyIdVector;
keyIdVector.clear();
keyIdVector.insert(keyIdVector.end(), keyId, keyId + kBlockSize);
std::map<std::vector<uint8_t>, std::vector<uint8_t> >::iterator itr;
itr = mKeyMap.find(keyIdVector);
if (itr == mKeyMap.end()) {
- return Status::ERROR_DRM_NO_LICENSE;
+ return Status_V1_2::ERROR_DRM_NO_LICENSE;
}
AesCtrDecryptor decryptor;
- return decryptor.decrypt(
+ Status status = decryptor.decrypt(
itr->second /*key*/, iv, srcPtr, destPtr, subSamples,
subSamples.size(), bytesDecryptedOut);
+ return static_cast<Status_V1_2>(status);
}
} // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
} // namespace drm
} // namespace hardware
} // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/SessionLibrary.cpp b/drm/mediadrm/plugins/clearkey/hidl/SessionLibrary.cpp
index b4319e6a45..99fb30fd28 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/SessionLibrary.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/SessionLibrary.cpp
@@ -24,7 +24,7 @@
namespace android {
namespace hardware {
namespace drm {
-namespace V1_1 {
+namespace V1_2 {
namespace clearkey {
using ::android::hardware::hidl_string;
@@ -59,7 +59,8 @@ sp<Session> SessionLibrary::createSession() {
mSessions.insert(std::pair<std::vector<uint8_t>,
sp<Session> >(sessionId, new Session(sessionId)));
- std::map<std::vector<uint8_t>, sp<Session> >::iterator itr = mSessions.find(sessionId);
+ std::map<std::vector<uint8_t>, sp<Session> >::iterator itr =
+ mSessions.find(sessionId);
if (itr != mSessions.end()) {
return itr->second;
} else {
@@ -70,7 +71,8 @@ sp<Session> SessionLibrary::createSession() {
sp<Session> SessionLibrary::findSession(
const std::vector<uint8_t>& sessionId) {
Mutex::Autolock lock(mSessionsLock);
- std::map<std::vector<uint8_t>, sp<Session> >::iterator itr = mSessions.find(sessionId);
+ std::map<std::vector<uint8_t>, sp<Session> >::iterator itr =
+ mSessions.find(sessionId);
if (itr != mSessions.end()) {
return itr->second;
} else {
@@ -84,7 +86,7 @@ void SessionLibrary::destroySession(const sp<Session>& session) {
}
} // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
} // namespace drm
} // namespace hardware
} // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.1-service.clearkey.rc b/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.1-service.clearkey.rc
deleted file mode 100644
index ffe856a55d..0000000000
--- a/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.1-service.clearkey.rc
+++ /dev/null
@@ -1,6 +0,0 @@
-service vendor.drm-clearkey-hal-1-1 /vendor/bin/hw/android.hardware.drm@1.1-service.clearkey
- class hal
- user media
- group media mediadrm
- ioprio rt 4
- writepid /dev/cpuset/foreground/tasks
diff --git a/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.2-service-lazy.clearkey.rc b/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.2-service-lazy.clearkey.rc
new file mode 100644
index 0000000000..9afd3d7979
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.2-service-lazy.clearkey.rc
@@ -0,0 +1,14 @@
+service vendor.drm-clearkey-hal-1-2 /vendor/bin/hw/android.hardware.drm@1.2-service-lazy.clearkey
+ interface android.hardware.drm@1.0::ICryptoFactory clearkey
+ interface android.hardware.drm@1.0::IDrmFactory clearkey
+ interface android.hardware.drm@1.1::ICryptoFactory clearkey
+ interface android.hardware.drm@1.1::IDrmFactory clearkey
+ interface android.hardware.drm@1.2::ICryptoFactory clearkey
+ interface android.hardware.drm@1.2::IDrmFactory clearkey
+ disabled
+ oneshot
+ class hal
+ user media
+ group media mediadrm
+ ioprio rt 4
+ writepid /dev/cpuset/foreground/tasks
diff --git a/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.2-service.clearkey.rc b/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.2-service.clearkey.rc
new file mode 100644
index 0000000000..5ba669dc50
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.2-service.clearkey.rc
@@ -0,0 +1,12 @@
+service vendor.drm-clearkey-hal-1-2 /vendor/bin/hw/android.hardware.drm@1.2-service.clearkey
+ interface android.hardware.drm@1.0::ICryptoFactory clearkey
+ interface android.hardware.drm@1.0::IDrmFactory clearkey
+ interface android.hardware.drm@1.1::ICryptoFactory clearkey
+ interface android.hardware.drm@1.1::IDrmFactory clearkey
+ interface android.hardware.drm@1.2::ICryptoFactory clearkey
+ interface android.hardware.drm@1.2::IDrmFactory clearkey
+ class hal
+ user media
+ group media mediadrm
+ ioprio rt 4
+ writepid /dev/cpuset/foreground/tasks
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/AesCtrDecryptor.h b/drm/mediadrm/plugins/clearkey/hidl/include/AesCtrDecryptor.h
index 0c7ef20fdf..721f4c015c 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/AesCtrDecryptor.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/AesCtrDecryptor.h
@@ -22,7 +22,7 @@
namespace android {
namespace hardware {
namespace drm {
-namespace V1_1 {
+namespace V1_2 {
namespace clearkey {
using ::android::hardware::drm::V1_0::Status;
@@ -42,7 +42,7 @@ private:
};
} // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
} // namespace drm
} // namespace hardware
} // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/Base64.h b/drm/mediadrm/plugins/clearkey/hidl/include/Base64.h
index 4a385bdb6e..ec30cc1024 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/Base64.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/Base64.h
@@ -25,7 +25,7 @@
namespace android {
namespace hardware {
namespace drm {
-namespace V1_1 {
+namespace V1_2 {
namespace clearkey {
using ::android::sp;
@@ -38,7 +38,7 @@ void encodeBase64(const void *data, size_t size, std::string *out);
void encodeBase64Url(const void *data, size_t size, std::string *out);
} // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
} // namespace drm
} // namespace hardware
} // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/Buffer.h b/drm/mediadrm/plugins/clearkey/hidl/include/Buffer.h
index 5bbb28aa14..c497e379be 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/Buffer.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/Buffer.h
@@ -25,7 +25,7 @@
namespace android {
namespace hardware {
namespace drm {
-namespace V1_1 {
+namespace V1_2 {
namespace clearkey {
using ::android::sp;
@@ -54,7 +54,7 @@ private:
};
} // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
} // namespace drm
} // namespace hardware
} // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyDrmProperties.h b/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyDrmProperties.h
index d65b25c37f..b83ce69d4e 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyDrmProperties.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyDrmProperties.h
@@ -22,30 +22,40 @@
namespace android {
namespace hardware {
namespace drm {
-namespace V1_1 {
+namespace V1_2 {
namespace clearkey {
static const std::string kVendorKey("vendor");
static const std::string kVendorValue("Google");
static const std::string kVersionKey("version");
-static const std::string kVersionValue("1.1");
+static const std::string kVersionValue("1.2");
static const std::string kPluginDescriptionKey("description");
static const std::string kPluginDescriptionValue("ClearKey CDM");
static const std::string kAlgorithmsKey("algorithms");
static const std::string kAlgorithmsValue("");
static const std::string kListenerTestSupportKey("listenerTestSupport");
static const std::string kListenerTestSupportValue("true");
+static const std::string kDrmErrorTestKey("drmErrorTest");
+static const std::string kDrmErrorTestValue("");
+static const std::string kResourceContentionValue("resourceContention");
+static const std::string kLostStateValue("lostState");
+static const std::string kFrameTooLargeValue("frameTooLarge");
+static const std::string kInvalidStateValue("invalidState");
static const std::string kDeviceIdKey("deviceId");
static const uint8_t kTestDeviceIdData[] =
{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf};
+
+// settable byte array property
+static const std::string kClientIdKey("clientId");
+
// TODO stub out metrics for nw
static const std::string kMetricsKey("metrics");
static const uint8_t kMetricsData[] = { 0 };
} // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
} // namespace drm
} // namespace hardware
} // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyTypes.h b/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyTypes.h
index 46cb5e4dd5..03c434eaa3 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyTypes.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyTypes.h
@@ -17,17 +17,18 @@
#ifndef CLEARKEY_MACROS_H_
#define CLEARKEY_MACROS_H_
-#include <android/hardware/drm/1.0/types.h>
+#include <android/hardware/drm/1.2/types.h>
#include <map>
namespace android {
namespace hardware {
namespace drm {
-namespace V1_1 {
+namespace V1_2 {
namespace clearkey {
using ::android::hardware::drm::V1_0::KeyValue;
+using ::android::hardware::drm::V1_1::SecurityLevel;
using ::android::hardware::hidl_vec;
const uint8_t kBlockSize = 16; //AES_BLOCK_SIZE;
@@ -47,7 +48,7 @@ typedef std::map<std::vector<uint8_t>, std::vector<uint8_t> > KeyMap;
void operator=(const TypeName&) = delete;
} // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
} // namespace drm
} // namespace hardware
} // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/CreatePluginFactories.h b/drm/mediadrm/plugins/clearkey/hidl/include/CreatePluginFactories.h
index 99520277f2..6368f3dabb 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/CreatePluginFactories.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/CreatePluginFactories.h
@@ -17,17 +17,17 @@
#ifndef CLEARKEY_CREATE_PLUGIN_FACTORIES_H_
#define CLEARKEY_CREATE_PLUGIN_FACTORIES_H_
-#include <android/hardware/drm/1.1/ICryptoFactory.h>
-#include <android/hardware/drm/1.1/IDrmFactory.h>
+#include <android/hardware/drm/1.2/ICryptoFactory.h>
+#include <android/hardware/drm/1.2/IDrmFactory.h>
namespace android {
namespace hardware {
namespace drm {
-namespace V1_1 {
+namespace V1_2 {
namespace clearkey {
-using ::android::hardware::drm::V1_1::ICryptoFactory;
-using ::android::hardware::drm::V1_1::IDrmFactory;
+using ::android::hardware::drm::V1_2::ICryptoFactory;
+using ::android::hardware::drm::V1_2::IDrmFactory;
extern "C" {
IDrmFactory* createDrmFactory();
@@ -35,7 +35,7 @@ extern "C" {
}
} // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
} // namespace drm
} // namespace hardware
} // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/CryptoFactory.h b/drm/mediadrm/plugins/clearkey/hidl/include/CryptoFactory.h
index 175ab761fa..203bb2d316 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/CryptoFactory.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/CryptoFactory.h
@@ -18,17 +18,17 @@
#define CLEARKEY_CRYPTO_FACTORY_H_
#include <android/hardware/drm/1.0/ICryptoPlugin.h>
-#include <android/hardware/drm/1.1/ICryptoFactory.h>
+#include <android/hardware/drm/1.2/ICryptoFactory.h>
#include "ClearKeyTypes.h"
namespace android {
namespace hardware {
namespace drm {
-namespace V1_1 {
+namespace V1_2 {
namespace clearkey {
-using ::android::hardware::drm::V1_1::ICryptoFactory;
+using ::android::hardware::drm::V1_2::ICryptoFactory;
using ::android::hardware::drm::V1_0::ICryptoPlugin;
using ::android::hardware::hidl_array;
using ::android::hardware::hidl_string;
@@ -52,7 +52,7 @@ private:
};
} // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
} // namespace drm
} // namespace hardware
} // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/CryptoPlugin.h b/drm/mediadrm/plugins/clearkey/hidl/include/CryptoPlugin.h
index 6a738066d0..8680f0ca54 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/CryptoPlugin.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/CryptoPlugin.h
@@ -17,7 +17,7 @@
#ifndef CLEARKEY_CRYPTO_PLUGIN_H_
#define CLEARKEY_CRYPTO_PLUGIN_H_
-#include <android/hardware/drm/1.0/ICryptoPlugin.h>
+#include <android/hardware/drm/1.2/ICryptoPlugin.h>
#include <android/hidl/memory/1.0/IMemory.h>
#include "ClearKeyTypes.h"
@@ -32,16 +32,17 @@ namespace {
namespace android {
namespace hardware {
namespace drm {
-namespace V1_1 {
+namespace V1_2 {
namespace clearkey {
-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;
+namespace drm = ::android::hardware::drm;
+using drm::V1_0::DestinationBuffer;
+using drm::V1_0::Mode;
+using drm::V1_0::Pattern;
+using drm::V1_0::SharedBuffer;
+using drm::V1_0::Status;
+using drm::V1_0::SubSample;
+
using ::android::hardware::hidl_array;
using ::android::hardware::hidl_memory;
using ::android::hardware::hidl_string;
@@ -51,7 +52,9 @@ using ::android::hardware::Void;
using ::android::hidl::memory::V1_0::IMemory;
using ::android::sp;
-struct CryptoPlugin : public ICryptoPlugin {
+typedef drm::V1_2::Status Status_V1_2;
+
+struct CryptoPlugin : public drm::V1_2::ICryptoPlugin {
explicit CryptoPlugin(const hidl_vec<uint8_t>& sessionId) {
mInitStatus = setMediaDrmSession(sessionId);
}
@@ -80,6 +83,18 @@ struct CryptoPlugin : public ICryptoPlugin {
const DestinationBuffer& destination,
decrypt_cb _hidl_cb);
+ Return<void> decrypt_1_2(
+ bool secure,
+ const hidl_array<uint8_t, KEY_ID_SIZE>& keyId,
+ const hidl_array<uint8_t, KEY_IV_SIZE>& 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);
+
Return<void> setSharedBufferBase(const hidl_memory& base,
uint32_t bufferId);
@@ -96,7 +111,7 @@ private:
};
} // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
} // namespace drm
} // namespace hardware
} // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/DeviceFiles.h b/drm/mediadrm/plugins/clearkey/hidl/include/DeviceFiles.h
new file mode 100644
index 0000000000..554ae598fe
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/DeviceFiles.h
@@ -0,0 +1,71 @@
+// 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 CLEARKEY_DEVICE_FILES_H_
+#define CLEARKEY_DEVICE_FILES_H_
+
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <set>
+#include <string>
+#include <vector>
+
+#include "protos/DeviceFiles.pb.h"
+#include "ClearKeyTypes.h"
+#include "MemoryFileSystem.h"
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace V1_2 {
+namespace clearkey {
+
+class DeviceFiles {
+ public:
+ typedef enum {
+ kLicenseStateUnknown,
+ kLicenseStateActive,
+ kLicenseStateReleasing,
+ } LicenseState;
+
+ DeviceFiles() {};
+ virtual ~DeviceFiles() {};
+
+ virtual bool StoreLicense(const std::string& keySetId, LicenseState state,
+ const std::string& keyResponse);
+
+ virtual bool RetrieveLicense(
+ const std::string& key_set_id, LicenseState* state, std::string* offlineLicense);
+
+ virtual bool LicenseExists(const std::string& keySetId);
+
+ virtual std::vector<std::string> ListLicenses() const;
+
+ virtual bool DeleteLicense(const std::string& keySetId);
+
+ virtual bool DeleteAllLicenses();
+
+ private:
+ bool FileExists(const std::string& path) const;
+ ssize_t GetFileSize(const std::string& fileName) const;
+ bool RemoveFile(const std::string& fileName);
+
+ bool RetrieveHashedFile(const std::string& fileName, OfflineFile* deSerializedFile);
+ bool StoreFileRaw(const std::string& fileName, const std::string& serializedFile);
+ bool StoreFileWithHash(const std::string& fileName, const std::string& serializedFile);
+
+ MemoryFileSystem mFileHandle;
+
+ CLEARKEY_DISALLOW_COPY_AND_ASSIGN(DeviceFiles);
+};
+
+} // namespace clearkey
+} // namespace V1_2
+} // namespace drm
+} // namespace hardware
+} // namespace android
+
+#endif // CLEARKEY_DEVICE_FILES_H_
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/DrmFactory.h b/drm/mediadrm/plugins/clearkey/hidl/include/DrmFactory.h
index 6f581955b5..4ca856d63e 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/DrmFactory.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/DrmFactory.h
@@ -17,15 +17,15 @@
#ifndef CLEARKEY_DRM_FACTORY_H_
#define CLEARKEY_DRM_FACTORY_H_
-#include <android/hardware/drm/1.1/IDrmPlugin.h>
-#include <android/hardware/drm/1.1/IDrmFactory.h>
+#include <android/hardware/drm/1.2/IDrmPlugin.h>
+#include <android/hardware/drm/1.2/IDrmFactory.h>
#include "ClearKeyTypes.h"
namespace android {
namespace hardware {
namespace drm {
-namespace V1_1 {
+namespace V1_2 {
namespace clearkey {
using ::android::hardware::hidl_array;
@@ -39,6 +39,10 @@ struct DrmFactory : public IDrmFactory {
Return<bool> isCryptoSchemeSupported(const hidl_array<uint8_t, 16>& uuid)
override;
+ Return<bool> isCryptoSchemeSupported_1_2(const hidl_array<uint8_t, 16>& uuid,
+ const hidl_string& mimeType,
+ SecurityLevel level) override;
+
Return<bool> isContentTypeSupported(const hidl_string &mimeType)
override;
@@ -52,7 +56,7 @@ private:
};
} // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
} // namespace drm
} // namespace hardware
} // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h b/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h
index fb0695aaef..f294d4d736 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h
@@ -17,32 +17,42 @@
#ifndef CLEARKEY_DRM_PLUGIN_H_
#define CLEARKEY_DRM_PLUGIN_H_
-#include <android/hardware/drm/1.1/IDrmPlugin.h>
+#include <android/hardware/drm/1.2/IDrmPlugin.h>
+#include <android/hardware/drm/1.2/IDrmPluginListener.h>
-#include <stdio.h>
#include <map>
+#include <stdio.h>
+
+#include <utils/List.h>
+#include "DeviceFiles.h"
#include "SessionLibrary.h"
#include "Utils.h"
namespace android {
namespace hardware {
namespace drm {
-namespace V1_1 {
+namespace V1_2 {
namespace clearkey {
-using ::android::hardware::drm::V1_0::EventType;
-using ::android::hardware::drm::V1_0::IDrmPluginListener;
-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::SessionId;
-using ::android::hardware::drm::V1_0::Status;
-using ::android::hardware::drm::V1_1::DrmMetricGroup;
-using ::android::hardware::drm::V1_1::IDrmPlugin;
-using ::android::hardware::drm::V1_1::KeyRequestType;
+namespace drm = ::android::hardware::drm;
+using drm::V1_0::EventType;
+using drm::V1_0::IDrmPluginListener;
+using drm::V1_0::KeyRequestType;
+using drm::V1_0::KeyStatus;
+using drm::V1_0::KeyType;
+using drm::V1_0::KeyValue;
+using drm::V1_0::SecureStop;
+using drm::V1_0::SecureStopId;
+using drm::V1_0::SessionId;
+using drm::V1_0::Status;
+using drm::V1_1::DrmMetricGroup;
+using drm::V1_1::HdcpLevel;
+using drm::V1_1::SecureStopRelease;
+using drm::V1_1::SecurityLevel;
+using drm::V1_2::IDrmPlugin;
+using drm::V1_2::KeySetId;
+using drm::V1_2::OfflineLicenseState;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
@@ -50,10 +60,16 @@ using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::sp;
+typedef drm::V1_1::KeyRequestType KeyRequestType_V1_1;
+typedef drm::V1_2::IDrmPluginListener IDrmPluginListener_V1_2;
+typedef drm::V1_2::KeyStatus KeyStatus_V1_2;
+typedef drm::V1_2::Status Status_V1_2;
+typedef drm::V1_2::HdcpLevel HdcpLevel_V1_2;
+
struct DrmPlugin : public IDrmPlugin {
explicit DrmPlugin(SessionLibrary* sessionLibrary);
- virtual ~DrmPlugin() {}
+ virtual ~DrmPlugin() { mFileHandle.DeleteAllLicenses(); }
Return<void> openSession(openSession_cb _hidl_cb) override;
Return<void> openSession_1_1(SecurityLevel securityLevel,
@@ -77,6 +93,14 @@ struct DrmPlugin : public IDrmPlugin {
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,
@@ -91,13 +115,7 @@ struct DrmPlugin : public IDrmPlugin {
Return<Status> restoreKeys(
const hidl_vec<uint8_t>& sessionId,
- const hidl_vec<uint8_t>& keySetId) {
-
- if (sessionId.size() == 0 || keySetId.size() == 0) {
- return Status::BAD_VALUE;
- }
- return Status::ERROR_DRM_CANNOT_HANDLE;
- }
+ const hidl_vec<uint8_t>& keySetId) override;
Return<void> queryKeyStatus(
const hidl_vec<uint8_t>& sessionId,
@@ -115,6 +133,18 @@ struct DrmPlugin : public IDrmPlugin {
return Void();
}
+ Return<void> getProvisionRequest_1_2(
+ const hidl_string& certificateType,
+ const hidl_string& certificateAuthority,
+ getProvisionRequest_1_2_cb _hidl_cb) {
+ UNUSED(certificateType);
+ UNUSED(certificateAuthority);
+
+ hidl_string defaultUrl;
+ _hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, hidl_vec<uint8_t>(), defaultUrl);
+ return Void();
+ }
+
Return<void> provideProvisionResponse(
const hidl_vec<uint8_t>& response,
provideProvisionResponse_cb _hidl_cb) {
@@ -134,6 +164,13 @@ struct DrmPlugin : public IDrmPlugin {
return Void();
}
+ Return<void> getHdcpLevels_1_2(getHdcpLevels_1_2_cb _hidl_cb) {
+ HdcpLevel_V1_2 connectedLevel = HdcpLevel_V1_2::HDCP_NONE;
+ HdcpLevel_V1_2 maxLevel = HdcpLevel_V1_2::HDCP_NO_OUTPUT;
+ _hidl_cb(Status_V1_2::OK, connectedLevel, maxLevel);
+ return Void();
+ }
+
Return<void> getNumberOfSessions(getNumberOfSessions_cb _hidl_cb) override;
Return<void> getSecurityLevel(const hidl_vec<uint8_t>& sessionId,
@@ -141,6 +178,13 @@ struct DrmPlugin : public IDrmPlugin {
Return<void> getMetrics(getMetrics_cb _hidl_cb) override;
+ Return<void> getOfflineLicenseKeySetIds(getOfflineLicenseKeySetIds_cb _hidl_cb) override;
+
+ Return<Status> removeOfflineLicense(const KeySetId &keySetId) override;
+
+ Return<void> getOfflineLicenseState(const KeySetId &keySetId,
+ getOfflineLicenseState_cb _hidl_cb) override;
+
Return<void> getPropertyString(
const hidl_string& name,
getPropertyString_cb _hidl_cb) override;
@@ -248,12 +292,17 @@ struct DrmPlugin : public IDrmPlugin {
Return<void> setListener(const sp<IDrmPluginListener>& listener) {
mListener = listener;
+ mListenerV1_2 = IDrmPluginListener_V1_2::castFrom(listener);
return Void();
};
- Return<void> sendEvent(EventType eventType, const hidl_vec<uint8_t>& sessionId,
+ Return<void> sendEvent(
+ EventType eventType,
+ const hidl_vec<uint8_t>& sessionId,
const hidl_vec<uint8_t>& data) {
- if (mListener != NULL) {
+ 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");
@@ -261,8 +310,12 @@ struct DrmPlugin : public IDrmPlugin {
return Void();
}
- Return<void> sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId, int64_t expiryTimeInMS) {
- if (mListener != NULL) {
+ Return<void> sendExpirationUpdate(
+ 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");
@@ -270,9 +323,12 @@ struct DrmPlugin : public IDrmPlugin {
return Void();
}
- Return<void> sendKeysChange(const hidl_vec<uint8_t>& sessionId,
+ Return<void> sendKeysChange(
+ const hidl_vec<uint8_t>& sessionId,
const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
- if (mListener != NULL) {
+ 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");
@@ -280,6 +336,23 @@ struct DrmPlugin : public IDrmPlugin {
return Void();
}
+ Return<void> sendKeysChange_1_2(
+ const hidl_vec<uint8_t>& sessionId,
+ const hidl_vec<KeyStatus_V1_2>& keyStatusList, bool hasNewUsableKey) {
+ if (mListenerV1_2 != NULL) {
+ mListenerV1_2->sendKeysChange_1_2(sessionId, keyStatusList, hasNewUsableKey);
+ }
+ return Void();
+ }
+
+ Return<void> sendSessionLostState(
+ const hidl_vec<uint8_t>& sessionId) {
+ if (mListenerV1_2 != NULL) {
+ mListenerV1_2->sendSessionLostState(sessionId);
+ }
+ return Void();
+ }
+
Return<void> getSecureStops(getSecureStops_cb _hidl_cb);
Return<void> getSecureStop(const hidl_vec<uint8_t>& secureStopId,
@@ -300,18 +373,19 @@ struct DrmPlugin : public IDrmPlugin {
private:
void initProperties();
void installSecureStop(const hidl_vec<uint8_t>& sessionId);
+ bool makeKeySetId(std::string* keySetId);
void setPlayPolicy();
Return<Status> setSecurityLevel(const hidl_vec<uint8_t>& sessionId,
SecurityLevel level);
- Status getKeyRequestCommon(const hidl_vec<uint8_t>& scope,
+ Status_V1_2 getKeyRequestCommon(const hidl_vec<uint8_t>& scope,
const hidl_vec<uint8_t>& initData,
const hidl_string& mimeType,
KeyType keyType,
const hidl_vec<KeyValue>& optionalParameters,
std::vector<uint8_t> *request,
- KeyRequestType *getKeyRequestType,
+ KeyRequestType_V1_1 *getKeyRequestType,
std::string *defaultUrl);
struct ClearkeySecureStop {
@@ -323,19 +397,31 @@ private:
std::vector<KeyValue> mPlayPolicy;
std::map<std::string, std::string> mStringProperties;
std::map<std::string, std::vector<uint8_t> > mByteArrayProperties;
+ std::map<std::string, std::vector<uint8_t> > mReleaseKeysMap;
std::map<std::vector<uint8_t>, SecurityLevel> mSecurityLevel;
sp<IDrmPluginListener> mListener;
+ sp<IDrmPluginListener_V1_2> mListenerV1_2;
SessionLibrary *mSessionLibrary;
int64_t mOpenSessionOkCount;
int64_t mCloseSessionOkCount;
int64_t mCloseSessionNotOpenedCount;
uint32_t mNextSecureStopId;
+ // set by property to mock error scenarios
+ Status_V1_2 mMockError;
+
+ void processMockError(const sp<Session> &session) {
+ session->setMockError(mMockError);
+ mMockError = Status_V1_2::OK;
+ }
+
+ DeviceFiles mFileHandle;
+
CLEARKEY_DISALLOW_COPY_AND_ASSIGN_AND_NEW(DrmPlugin);
};
} // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
} // namespace drm
} // namespace hardware
} // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/InitDataParser.h b/drm/mediadrm/plugins/clearkey/hidl/include/InitDataParser.h
index 3189c4aeb2..889f51164b 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/InitDataParser.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/InitDataParser.h
@@ -24,7 +24,7 @@
namespace android {
namespace hardware {
namespace drm {
-namespace V1_1 {
+namespace V1_2 {
namespace clearkey {
using ::android::hardware::drm::V1_0::Status;
@@ -34,7 +34,8 @@ public:
InitDataParser() {}
Status parse(const std::vector<uint8_t>& initData,
- const std::string& type,
+ const std::string& mimeType,
+ V1_0::KeyType keyType,
std::vector<uint8_t>* licenseRequest);
private:
@@ -43,12 +44,12 @@ private:
Status parsePssh(const std::vector<uint8_t>& initData,
std::vector<const uint8_t*>* keyIds);
- std::string generateRequest(
+ std::string generateRequest(V1_0::KeyType keyType,
const std::vector<const uint8_t*>& keyIds);
};
} // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
} // namespace drm
} // namespace hardware
} // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/JsonWebKey.h b/drm/mediadrm/plugins/clearkey/hidl/include/JsonWebKey.h
index 4ab034cd74..e57470cd0d 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/JsonWebKey.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/JsonWebKey.h
@@ -23,7 +23,7 @@
namespace android {
namespace hardware {
namespace drm {
-namespace V1_1 {
+namespace V1_2 {
namespace clearkey {
class JsonWebKey {
@@ -54,7 +54,7 @@ class JsonWebKey {
};
} // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
} // namespace drm
} // namespace hardware
} // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/MemoryFileSystem.h b/drm/mediadrm/plugins/clearkey/hidl/include/MemoryFileSystem.h
new file mode 100644
index 0000000000..bcd9fd631a
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/MemoryFileSystem.h
@@ -0,0 +1,68 @@
+// 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 CLEARKEY_MEMORY_FILE_SYSTEM_H_
+#define CLEARKEY_MEMORY_FILE_SYSTEM_H_
+
+#include <map>
+#include <string>
+
+#include "ClearKeyTypes.h"
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace V1_2 {
+namespace clearkey {
+
+// Using android file system requires clearkey plugin to update
+// its sepolicy. However, we are unable to update sepolicy for
+// older vendor partitions. To provide backward compatibility,
+// clearkey plugin implements a very simple file system in memory.
+// This memory file system does not support directory structure.
+class MemoryFileSystem {
+ public:
+ struct MemoryFile {
+ std::string fileName; // excludes path
+ std::string content;
+ size_t fileSize;
+
+ std::string getContent() const { return content; }
+ size_t getFileSize() const { return fileSize; }
+ void setContent(const std::string& file) { content = file; }
+ void setFileName(const std::string& name) { fileName = name; }
+ void setFileSize(size_t size) {
+ content.resize(size); fileSize = size;
+ }
+ };
+
+ MemoryFileSystem() {};
+ virtual ~MemoryFileSystem() {};
+
+ bool FileExists(const std::string& fileName) const;
+ ssize_t GetFileSize(const std::string& fileName) const;
+ std::vector<std::string> ListFiles() const;
+ size_t Read(const std::string& pathName, std::string* buffer);
+ bool RemoveAllFiles();
+ bool RemoveFile(const std::string& fileName);
+ size_t Write(const std::string& pathName, const MemoryFile& memoryFile);
+
+ private:
+ // License file name is made up of a unique keySetId, therefore,
+ // the filename can be used as the key to locate licenses in the
+ // memory file system.
+ std::map<std::string, MemoryFile> mMemoryFileSystem;
+
+ std::string GetFileName(const std::string& path);
+
+ CLEARKEY_DISALLOW_COPY_AND_ASSIGN(MemoryFileSystem);
+};
+
+} // namespace clearkey
+} // namespace V1_2
+} // namespace drm
+} // namespace hardware
+} // namespace android
+
+#endif // CLEARKEY_MEMORY_FILE_SYSTEM_H_
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/Session.h b/drm/mediadrm/plugins/clearkey/hidl/include/Session.h
index cddfca5eba..a159e5ae76 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/Session.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/Session.h
@@ -27,43 +27,53 @@
namespace android {
namespace hardware {
namespace drm {
-namespace V1_1 {
+namespace V1_2 {
namespace clearkey {
-using ::android::hardware::drm::V1_0::Status;
-using ::android::hardware::drm::V1_0::SubSample;
+namespace drm = ::android::hardware::drm;
+using drm::V1_0::Status;
+using drm::V1_0::SubSample;
+
+typedef drm::V1_2::Status Status_V1_2;
class Session : public RefBase {
public:
explicit Session(const std::vector<uint8_t>& sessionId)
- : mSessionId(sessionId) {}
+ : mSessionId(sessionId), mMockError(Status_V1_2::OK) {}
virtual ~Session() {}
const std::vector<uint8_t>& sessionId() const { return mSessionId; }
Status getKeyRequest(
- const std::vector<uint8_t>& mimeType,
- const std::string& initDataType,
+ const std::vector<uint8_t>& initDataType,
+ const std::string& mimeType,
+ V1_0::KeyType keyType,
std::vector<uint8_t>* keyRequest) const;
Status provideKeyResponse(
const std::vector<uint8_t>& response);
- Status decrypt(
+ Status_V1_2 decrypt(
const KeyId keyId, const Iv iv, const uint8_t* srcPtr,
uint8_t* dstPtr, const std::vector<SubSample> subSamples,
size_t* bytesDecryptedOut);
+ void setMockError(Status_V1_2 error) {mMockError = error;}
+ Status_V1_2 getMockError() const {return mMockError;}
+
private:
CLEARKEY_DISALLOW_COPY_AND_ASSIGN(Session);
const std::vector<uint8_t> mSessionId;
KeyMap mKeyMap;
Mutex mMapLock;
+
+ // For mocking error return scenarios
+ Status_V1_2 mMockError;
};
} // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
} // namespace drm
} // namespace hardware
} // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/SessionLibrary.h b/drm/mediadrm/plugins/clearkey/hidl/include/SessionLibrary.h
index 326a0c100d..1e567b8d09 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/SessionLibrary.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/SessionLibrary.h
@@ -26,7 +26,7 @@
namespace android {
namespace hardware {
namespace drm {
-namespace V1_1 {
+namespace V1_2 {
namespace clearkey {
using ::android::sp;
@@ -58,7 +58,7 @@ private:
};
} // namespace clearkey
-} // namespace V1_1
+} // namespace V1_2
} // namespace drm
} // namespace hardware
} // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/TypeConvert.h b/drm/mediadrm/plugins/clearkey/hidl/include/TypeConvert.h
index cc06329b84..b0f8607729 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/TypeConvert.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/TypeConvert.h
@@ -24,7 +24,7 @@
namespace android {
namespace hardware {
namespace drm {
-namespace V1_1 {
+namespace V1_2 {
namespace clearkey {
using ::android::hardware::hidl_array;
@@ -68,8 +68,19 @@ template<typename T, size_t SIZE> std::vector<T> toVector(
return vec;
}
+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 clearkey
-} // namespace V1_1
+} // namespace V1_2
} // namespace drm
} // namespace hardware
} // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/protos/DeviceFiles.proto b/drm/mediadrm/plugins/clearkey/hidl/protos/DeviceFiles.proto
new file mode 100644
index 0000000000..3e11f0b3fa
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/protos/DeviceFiles.proto
@@ -0,0 +1,47 @@
+// ----------------------------------------------------------------------------
+// device_files.proto
+// ----------------------------------------------------------------------------
+// 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.
+//
+// Description:
+// Format of various files stored at the device.
+//
+syntax = "proto2";
+
+package android.hardware.drm.V1_2.clearkey;
+
+// need this if we are using libprotobuf-cpp-2.3.0-lite
+option optimize_for = LITE_RUNTIME;
+
+message License {
+ enum LicenseState {
+ ACTIVE = 1;
+ RELEASING = 2;
+ }
+
+ optional LicenseState state = 1;
+ optional bytes license = 2;
+}
+
+message OfflineFile {
+ enum FileType {
+ LICENSE = 1;
+ }
+
+ enum FileVersion {
+ VERSION_1 = 1;
+ }
+
+ optional FileType type = 1;
+ optional FileVersion version = 2 [default = VERSION_1];
+ optional License license = 3;
+
+}
+
+message HashedFile {
+ optional bytes file = 1;
+ // A raw (not hex-encoded) SHA256, taken over the bytes of 'file'.
+ optional bytes hash = 2;
+}
diff --git a/drm/mediadrm/plugins/clearkey/hidl/service.cpp b/drm/mediadrm/plugins/clearkey/hidl/service.cpp
index 6a97b720d2..b39ea018e4 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/service.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/service.cpp
@@ -13,32 +13,24 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#define LOG_TAG "android.hardware.drm@1.1-service.clearkey"
-
#include <CryptoFactory.h>
#include <DrmFactory.h>
#include <android-base/logging.h>
#include <binder/ProcessState.h>
+#include <hidl/HidlLazyUtils.h>
#include <hidl/HidlTransportSupport.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 android::hardware::drm::V1_1::clearkey::CryptoFactory;
-using android::hardware::drm::V1_1::clearkey::DrmFactory;
-
+using android::hardware::drm::V1_2::ICryptoFactory;
+using android::hardware::drm::V1_2::IDrmFactory;
+using android::hardware::drm::V1_2::clearkey::CryptoFactory;
+using android::hardware::drm::V1_2::clearkey::DrmFactory;
int main(int /* argc */, char** /* argv */) {
- ALOGD("android.hardware.drm@1.1-service.clearkey starting...");
-
- // The DRM HAL may communicate to other vendor components via
- // /dev/vndbinder
- android::ProcessState::initWithDriver("/dev/vndbinder");
-
sp<IDrmFactory> drmFactory = new DrmFactory;
sp<ICryptoFactory> cryptoFactory = new CryptoFactory;
diff --git a/drm/mediadrm/plugins/clearkey/hidl/serviceLazy.cpp b/drm/mediadrm/plugins/clearkey/hidl/serviceLazy.cpp
new file mode 100644
index 0000000000..99fd883b16
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/serviceLazy.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <CryptoFactory.h>
+#include <DrmFactory.h>
+
+#include <android-base/logging.h>
+#include <binder/ProcessState.h>
+#include <hidl/HidlLazyUtils.h>
+#include <hidl/HidlTransportSupport.h>
+
+using ::android::hardware::configureRpcThreadpool;
+using ::android::hardware::joinRpcThreadpool;
+using ::android::sp;
+
+using android::hardware::drm::V1_2::ICryptoFactory;
+using android::hardware::drm::V1_2::IDrmFactory;
+using android::hardware::drm::V1_2::clearkey::CryptoFactory;
+using android::hardware::drm::V1_2::clearkey::DrmFactory;
+using android::hardware::LazyServiceRegistrar;
+
+int main(int /* argc */, char** /* argv */) {
+ sp<IDrmFactory> drmFactory = new DrmFactory;
+ sp<ICryptoFactory> cryptoFactory = new CryptoFactory;
+
+ configureRpcThreadpool(8, true /* callerWillJoin */);
+
+ // Setup hwbinder service
+ LazyServiceRegistrar serviceRegistrar;
+
+ // Setup hwbinder service
+ CHECK_EQ(serviceRegistrar.registerService(drmFactory, "clearkey"), android::NO_ERROR)
+ << "Failed to register Clearkey Factory HAL";
+ CHECK_EQ(serviceRegistrar.registerService(cryptoFactory, "clearkey"), android::NO_ERROR)
+ << "Failed to register Clearkey Crypto HAL";
+
+ joinRpcThreadpool();
+}