Merge "camera2 ndk: Check for nullptr before assigning captureSequenceId."
diff --git a/cmds/stagefright/Android.mk b/cmds/stagefright/Android.mk
index 7a10302..6eb2e9f 100644
--- a/cmds/stagefright/Android.mk
+++ b/cmds/stagefright/Android.mk
@@ -8,7 +8,7 @@
SineSource.cpp
LOCAL_SHARED_LIBRARIES := \
- libstagefright libmedia libmedia_omx libmediaextractor libutils libbinder \
+ libstagefright libmedia libmedia_omx libutils libbinder \
libstagefright_foundation libjpeg libui libgui libcutils liblog \
libhidlbase \
android.hardware.media.omx@1.0 \
@@ -36,7 +36,7 @@
record.cpp
LOCAL_SHARED_LIBRARIES := \
- libstagefright libmedia libmediaextractor liblog libutils libbinder \
+ libstagefright libmedia liblog libutils libbinder \
libstagefright_foundation
LOCAL_C_INCLUDES:= \
@@ -61,7 +61,7 @@
recordvideo.cpp
LOCAL_SHARED_LIBRARIES := \
- libstagefright libmedia libmediaextractor liblog libutils libbinder \
+ libstagefright libmedia liblog libutils libbinder \
libstagefright_foundation
LOCAL_C_INCLUDES:= \
@@ -87,7 +87,7 @@
audioloop.cpp
LOCAL_SHARED_LIBRARIES := \
- libstagefright libmedia libmediaextractor liblog libutils libbinder \
+ libstagefright libmedia liblog libutils libbinder \
libstagefright_foundation
LOCAL_C_INCLUDES:= \
@@ -111,7 +111,7 @@
LOCAL_SHARED_LIBRARIES := \
libstagefright liblog libutils libbinder libui libgui \
- libstagefright_foundation libmedia libcutils libmediaextractor
+ libstagefright_foundation libmedia libcutils
LOCAL_C_INCLUDES:= \
frameworks/av/media/libstagefright \
@@ -203,7 +203,7 @@
LOCAL_SHARED_LIBRARIES := \
libstagefright liblog libutils libbinder libstagefright_foundation \
- libcutils libc libmediaextractor
+ libcutils libc
LOCAL_C_INCLUDES:= \
frameworks/av/media/libstagefright \
diff --git a/drm/libmediadrm/CryptoHal.cpp b/drm/libmediadrm/CryptoHal.cpp
index 3035c5a..4dda5d7 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::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_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 @@
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 @@
}
mPlugin.clear();
+ mPluginV1_2.clear();
return OK;
}
@@ -389,21 +406,33 @@
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 66c509f..fc847ff 100644
--- a/drm/libmediadrm/DrmHal.cpp
+++ b/drm/libmediadrm/DrmHal.cpp
@@ -41,6 +41,7 @@
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_0::SecureStop;
@@ -60,6 +61,9 @@
using ::android::os::PersistableBundle;
using ::android::sp;
+typedef drm::V1_1::KeyRequestType KeyRequestType_V1_1;
+typedef drm::V1_2::Status Status_V1_2;
+
namespace {
// This constant corresponds to the PROPERTY_DEVICE_UNIQUE_ID constant
@@ -239,7 +243,7 @@
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;
@@ -260,6 +264,19 @@
}
}
+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;
@@ -319,8 +336,11 @@
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;
}
@@ -532,6 +552,22 @@
return Void();
}
+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();
+}
+
bool DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
Mutex::Autolock autoLock(mLock);
@@ -568,16 +604,22 @@
if (mPlugin == NULL) {
mInitCheck = ERROR_UNSUPPORTED;
} else {
- if (!mPlugin->setListener(this).isOk()) {
- mPlugin = NULL;
- mPluginV1_1 = NULL;
- mPluginV1_2 = NULL;
+ 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;
}
@@ -694,6 +736,39 @@
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,
@@ -720,73 +795,51 @@
::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);
@@ -868,18 +921,33 @@
INIT_CHECK();
status_t err = UNKNOWN_ERROR;
+ Return<void> hResult;
- 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);
+ 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);
diff --git a/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp b/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp
index a488f86..fc0cceb 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp
@@ -42,10 +42,42 @@
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);
+ if (status == Status::OK) {
+ 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 +87,17 @@
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,7 +105,7 @@
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();
}
@@ -81,12 +113,12 @@
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();
}
@@ -98,12 +130,12 @@
const SharedBuffer& destBuffer = destination.nonsecureMemory;
sp<IMemory> destBase = mSharedBufferMap[destBuffer.bufferId];
if (destBase == nullptr) {
- _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "destination is a nullptr");
+ _hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0, "destination is a nullptr");
return Void();
}
if (destBuffer.offset + destBuffer.size > destBase->getSize()) {
- _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
+ _hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
return Void();
}
destPtr = static_cast<void *>(base + destination.nonsecureMemory.offset);
@@ -128,7 +160,7 @@
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();
}
@@ -144,22 +176,21 @@
}
}
- _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();
}
diff --git a/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp b/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
index 7184b53..badb99e 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
@@ -61,15 +61,23 @@
namespace V1_2 {
namespace clearkey {
-using ::android::hardware::drm::V1_2::KeySetId;
-using ::android::hardware::drm::V1_2::OfflineLicenseState;
+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();
@@ -84,6 +92,7 @@
mStringProperties[kPluginDescriptionKey] = kPluginDescriptionValue;
mStringProperties[kAlgorithmsKey] = kAlgorithmsValue;
mStringProperties[kListenerTestSupportKey] = kListenerTestSupportValue;
+ mStringProperties[kDrmErrorTestKey] = kDrmErrorTestValue;
std::vector<uint8_t> valueVector;
valueVector.clear();
@@ -112,6 +121,7 @@
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);
@@ -123,6 +133,7 @@
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);
@@ -138,6 +149,10 @@
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;
@@ -146,13 +161,13 @@
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);
@@ -161,18 +176,18 @@
// 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::ERROR_DRM_CANNOT_HANDLE;
+ 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 ||
(keyType != KeyType::STREAMING &&
keyType != KeyType::OFFLINE &&
keyType != KeyType::RELEASE)) {
- return Status::BAD_VALUE;
+ return Status_V1_2::BAD_VALUE;
}
const std::vector<uint8_t> scopeId = toVector(scope);
@@ -181,12 +196,16 @@
std::vector<uint8_t> sessionId(scopeId.begin(), scopeId.end());
session = mSessionLibrary->findSession(sessionId);
if (!session.get()) {
- return Status::ERROR_DRM_SESSION_NOT_OPENED;
+ return Status_V1_2::ERROR_DRM_SESSION_NOT_OPENED;
+ } else if (session->getMockError() != Status_V1_2::OK) {
+ return session->getMockError();
}
- *keyRequestType = KeyRequestType::INITIAL;
+
+ *keyRequestType = KeyRequestType_V1_1::INITIAL;
}
- Status status = session->getKeyRequest(initData, mimeType, keyType, request);
+ 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());
@@ -198,7 +217,7 @@
DeviceFiles::kLicenseStateReleasing,
emptyResponse)) {
ALOGE("Problem releasing offline license");
- return Status::ERROR_DRM_UNKNOWN;
+ return Status_V1_2::ERROR_DRM_UNKNOWN;
}
if (mReleaseKeysMap.find(keySetIdString) == mReleaseKeysMap.end()) {
sp<Session> session = mSessionLibrary->createSession();
@@ -209,7 +228,7 @@
} else {
ALOGE("Offline license not found, nothing to release");
}
- *keyRequestType = KeyRequestType::RELEASE;
+ *keyRequestType = KeyRequestType_V1_1::RELEASE;
}
return status;
}
@@ -223,15 +242,15 @@
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();
}
@@ -245,10 +264,31 @@
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 status = getKeyRequestCommon(
+ 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_V1_2 status = getKeyRequestCommon(
scope, initData, mimeType, keyType, optionalParameters,
&request, &keyRequestType, &defaultUrl);
@@ -434,6 +474,8 @@
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, "");
@@ -478,6 +520,16 @@
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;
+ }
+ }
+
mStringProperties[key] = std::string(value.c_str());
return Status::OK;
}
diff --git a/drm/mediadrm/plugins/clearkey/hidl/Session.cpp b/drm/mediadrm/plugins/clearkey/hidl/Session.cpp
index f4c49b9..a9d7016 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/Session.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/Session.cpp
@@ -68,25 +68,30 @@
}
}
-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
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyDrmProperties.h b/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyDrmProperties.h
index f83903c..1bbc822 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyDrmProperties.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyDrmProperties.h
@@ -35,6 +35,11 @@
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 kDeviceIdKey("deviceId");
static const uint8_t kTestDeviceIdData[] =
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyTypes.h b/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyTypes.h
index 7e9b6bd..2dafa36 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyTypes.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyTypes.h
@@ -17,7 +17,7 @@
#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>
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/CryptoPlugin.h b/drm/mediadrm/plugins/clearkey/hidl/include/CryptoPlugin.h
index 480dc7e..8680f0c 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"
@@ -35,13 +35,14 @@
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::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 @@
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);
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h b/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h
index 256c5d6..a9b897b 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h
@@ -18,6 +18,7 @@
#define CLEARKEY_DRM_PLUGIN_H_
#include <android/hardware/drm/1.2/IDrmPlugin.h>
+#include <android/hardware/drm/1.2/IDrmPluginListener.h>
#include <map>
#include <stdio.h>
@@ -34,22 +35,24 @@
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::HdcpLevel;
-using ::android::hardware::drm::V1_1::KeyRequestType;
-using ::android::hardware::drm::V1_1::SecureStopRelease;
-using ::android::hardware::drm::V1_1::SecurityLevel;
-using ::android::hardware::drm::V1_2::IDrmPlugin;
-using ::android::hardware::drm::V1_2::OfflineLicenseState;
+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;
@@ -57,6 +60,10 @@
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::Status Status_V1_2;
+
struct DrmPlugin : public IDrmPlugin {
explicit DrmPlugin(SessionLibrary* sessionLibrary);
@@ -84,6 +91,14 @@
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,
@@ -116,6 +131,18 @@
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) {
@@ -256,12 +283,17 @@
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");
@@ -269,8 +301,12 @@
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");
@@ -278,9 +314,12 @@
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");
@@ -288,6 +327,14 @@
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,
@@ -314,13 +361,13 @@
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 {
@@ -335,12 +382,21 @@
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);
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/Session.h b/drm/mediadrm/plugins/clearkey/hidl/include/Session.h
index f35560d..a159e5a 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/Session.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/Session.h
@@ -30,13 +30,16 @@
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; }
@@ -50,17 +53,23 @@
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
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/TypeConvert.h b/drm/mediadrm/plugins/clearkey/hidl/include/TypeConvert.h
index f6d30c9..b0f8607 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/TypeConvert.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/TypeConvert.h
@@ -68,6 +68,17 @@
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_2
} // namespace drm
diff --git a/include/media/DataSource.h b/include/media/DataSource.h
index 905bec1..198b27e 120000
--- a/include/media/DataSource.h
+++ b/include/media/DataSource.h
@@ -1 +1 @@
-../../media/libmediaextractor/include/media/DataSource.h
\ No newline at end of file
+stagefright/DataSource.h
\ No newline at end of file
diff --git a/include/media/DataSourceBase.h b/include/media/DataSourceBase.h
index 54c8047..d2ab2f1 120000
--- a/include/media/DataSourceBase.h
+++ b/include/media/DataSourceBase.h
@@ -1 +1 @@
-../../media/libmediaextractor/include/media/DataSourceBase.h
\ No newline at end of file
+stagefright/DataSourceBase.h
\ No newline at end of file
diff --git a/include/media/ExtractorUtils.h b/include/media/ExtractorUtils.h
deleted file mode 120000
index e2dd082..0000000
--- a/include/media/ExtractorUtils.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmediaextractor/include/media/ExtractorUtils.h
\ No newline at end of file
diff --git a/media/libmediaextractor/include/media/ExtractorUtils.h b/include/media/ExtractorUtils.h
similarity index 100%
rename from media/libmediaextractor/include/media/ExtractorUtils.h
rename to include/media/ExtractorUtils.h
diff --git a/include/media/MediaSource.h b/include/media/MediaSource.h
index 2e147c4..34bf65d 120000
--- a/include/media/MediaSource.h
+++ b/include/media/MediaSource.h
@@ -1 +1 @@
-../../media/libmediaextractor/include/media/MediaSource.h
\ No newline at end of file
+../../media/libstagefright/include/media/stagefright/MediaSource.h
\ No newline at end of file
diff --git a/media/codec2/components/cmds/Android.bp b/media/codec2/components/cmds/Android.bp
index 6b0977b..35f689e 100644
--- a/media/codec2/components/cmds/Android.bp
+++ b/media/codec2/components/cmds/Android.bp
@@ -15,7 +15,6 @@
"libcutils",
"libgui",
"liblog",
- "libmediaextractor",
"libstagefright",
"libstagefright_foundation",
"libui",
diff --git a/media/extractors/mpeg2/Android.bp b/media/extractors/mpeg2/Android.bp
index b816093..2a94671 100644
--- a/media/extractors/mpeg2/Android.bp
+++ b/media/extractors/mpeg2/Android.bp
@@ -28,9 +28,8 @@
static_libs: [
"libcrypto",
- "libstagefright_foundation",
+ "libstagefright_foundation_without_imemory",
"libstagefright_mpeg2support",
- "libmediaextractor",
"libutils",
"libstagefright",
"libstagefright_esds",
diff --git a/media/extractors/ogg/OggExtractor.cpp b/media/extractors/ogg/OggExtractor.cpp
index 6efbfee..590358c 100644
--- a/media/extractors/ogg/OggExtractor.cpp
+++ b/media/extractors/ogg/OggExtractor.cpp
@@ -872,7 +872,7 @@
ALOGV("readPage returned %zd", n);
- return n == ERROR_END_OF_STREAM ? AMEDIA_ERROR_END_OF_STREAM : AMEDIA_ERROR_UNKNOWN;
+ return n < 0 ? (media_status_t) n : AMEDIA_ERROR_END_OF_STREAM;
}
// Prevent a harmless unsigned integer overflow by clamping to 0
diff --git a/media/libaudioclient/AudioPolicy.cpp b/media/libaudioclient/AudioPolicy.cpp
index 9601d6d..3ab38cd 100644
--- a/media/libaudioclient/AudioPolicy.cpp
+++ b/media/libaudioclient/AudioPolicy.cpp
@@ -143,11 +143,18 @@
return NO_ERROR;
}
-void AudioMix::excludeUid(uid_t uid) const {
+void AudioMix::setExcludeUid(uid_t uid) const {
AudioMixMatchCriterion crit;
crit.mRule = RULE_EXCLUDE_UID;
crit.mValue.mUid = uid;
mCriteria.add(crit);
}
+void AudioMix::setMatchUid(uid_t uid) const {
+ AudioMixMatchCriterion crit;
+ crit.mRule = RULE_MATCH_UID;
+ crit.mValue.mUid = uid;
+ mCriteria.add(crit);
+}
+
} // namespace android
diff --git a/media/libaudioclient/include/media/AudioPolicy.h b/media/libaudioclient/include/media/AudioPolicy.h
index 96e1235..786fb9a 100644
--- a/media/libaudioclient/include/media/AudioPolicy.h
+++ b/media/libaudioclient/include/media/AudioPolicy.h
@@ -100,7 +100,8 @@
status_t readFromParcel(Parcel *parcel);
status_t writeToParcel(Parcel *parcel) const;
- void excludeUid(uid_t uid) const;
+ void setExcludeUid(uid_t uid) const;
+ void setMatchUid(uid_t uid) const;
mutable Vector<AudioMixMatchCriterion> mCriteria;
uint32_t mMixType;
diff --git a/media/libmedia/Android.bp b/media/libmedia/Android.bp
index 7d759e0..3efb5de 100644
--- a/media/libmedia/Android.bp
+++ b/media/libmedia/Android.bp
@@ -220,7 +220,6 @@
"libexpat",
"libcamera_client",
"libstagefright_foundation",
- "libmediaextractor",
"libgui",
"libdl",
"libaudioutils",
@@ -277,7 +276,6 @@
"libbinder",
"libcutils",
"liblog",
- "libmediaextractor",
"libmediandk",
"libnativewindow",
"libmediandk_utils",
diff --git a/media/libmedia/include/media/CryptoHal.h b/media/libmedia/include/media/CryptoHal.h
index ff8789d..73c029f 100644
--- a/media/libmedia/include/media/CryptoHal.h
+++ b/media/libmedia/include/media/CryptoHal.h
@@ -21,6 +21,7 @@
#include <android/hardware/drm/1.0/ICryptoFactory.h>
#include <android/hardware/drm/1.0/ICryptoPlugin.h>
#include <android/hardware/drm/1.1/ICryptoFactory.h>
+#include <android/hardware/drm/1.2/ICryptoPlugin.h>
#include <mediadrm/ICrypto.h>
#include <utils/KeyedVector.h>
@@ -72,6 +73,7 @@
const Vector<sp<ICryptoFactory>> mFactories;
sp<ICryptoPlugin> mPlugin;
+ sp<drm::V1_2::ICryptoPlugin> mPluginV1_2;
/**
* mInitCheck is:
diff --git a/media/libmedia/include/media/DrmHal.h b/media/libmedia/include/media/DrmHal.h
index 3302982..de0f3c7 100644
--- a/media/libmedia/include/media/DrmHal.h
+++ b/media/libmedia/include/media/DrmHal.h
@@ -20,11 +20,11 @@
#include <android/hardware/drm/1.0/IDrmFactory.h>
#include <android/hardware/drm/1.0/IDrmPlugin.h>
-#include <android/hardware/drm/1.0/IDrmPluginListener.h>
#include <android/hardware/drm/1.1/IDrmFactory.h>
#include <android/hardware/drm/1.1/IDrmPlugin.h>
#include <android/hardware/drm/1.2/IDrmFactory.h>
#include <android/hardware/drm/1.2/IDrmPlugin.h>
+#include <android/hardware/drm/1.2/IDrmPluginListener.h>
#include <media/MediaAnalyticsItem.h>
#include <mediadrm/DrmMetrics.h>
@@ -43,6 +43,8 @@
using ::android::hardware::Return;
using ::android::hardware::Void;
+typedef drm::V1_2::IDrmPluginListener IDrmPluginListener_V1_2;
+
namespace android {
struct DrmSessionClientInterface;
@@ -54,7 +56,7 @@
struct DrmHal : public BnDrm,
public IBinder::DeathRecipient,
- public IDrmPluginListener {
+ public IDrmPluginListener_V1_2 {
DrmHal();
virtual ~DrmHal();
@@ -176,6 +178,8 @@
Return<void> sendKeysChange(const hidl_vec<uint8_t>& sessionId,
const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey);
+ Return<void> sendSessionLostState(const hidl_vec<uint8_t>& sessionId);
+
virtual void binderDied(const wp<IBinder> &the_late_who);
private:
diff --git a/media/libmediaextractor/Android.bp b/media/libmediaextractor/Android.bp
deleted file mode 100644
index 4758cd6..0000000
--- a/media/libmediaextractor/Android.bp
+++ /dev/null
@@ -1,60 +0,0 @@
-cc_library {
- name: "libmediaextractor",
-
- include_dirs: [
- "frameworks/av/include",
- "frameworks/av/media/libmediaextractor/include",
- ],
-
- export_include_dirs: ["include"],
-
- cflags: [
- "-Wno-multichar",
- "-Werror",
- "-Wall",
- ],
-
- static: {
- cflags: [
- "-Wno-multichar",
- "-Werror",
- "-Wall",
- "-DNO_IMEMORY",
- ],
- },
-
- shared_libs: [
- "libbinder",
- "libstagefright_foundation",
- "libutils",
- "liblog",
- ],
-
- header_libs: [
- "media_ndk_headers",
- ],
-
- export_header_lib_headers: [
- "media_ndk_headers",
- ],
-
- srcs: [
- "DataSourceBase.cpp",
- "MediaBuffer.cpp",
- "MediaBufferBase.cpp",
- "MediaBufferGroup.cpp",
- "MediaSource.cpp",
- "MetaData.cpp",
- "MetaDataBase.cpp",
- ],
-
- clang: true,
-
- sanitize: {
- misc_undefined: [
- "unsigned-integer-overflow",
- "signed-integer-overflow",
- ],
- cfi: true,
- },
-}
diff --git a/media/libmediaplayer2/Android.bp b/media/libmediaplayer2/Android.bp
index 38f42dc..b3f7404 100644
--- a/media/libmediaplayer2/Android.bp
+++ b/media/libmediaplayer2/Android.bp
@@ -21,7 +21,6 @@
"libgui",
"liblog",
"libmedia_omx",
- "libmediaextractor",
"libstagefright_foundation",
"libui",
"libutils",
diff --git a/media/libmediaplayerservice/Android.bp b/media/libmediaplayerservice/Android.bp
index 51879fd..55867a5 100644
--- a/media/libmediaplayerservice/Android.bp
+++ b/media/libmediaplayerservice/Android.bp
@@ -24,7 +24,6 @@
"liblog",
"libmedia",
"libmedia_omx",
- "libmediaextractor",
"libmediadrm",
"libmediametrics",
"libmediautils",
diff --git a/media/libstagefright/Android.bp b/media/libstagefright/Android.bp
index 249f2a4..f45cc58 100644
--- a/media/libstagefright/Android.bp
+++ b/media/libstagefright/Android.bp
@@ -94,6 +94,7 @@
"CameraSource.cpp",
"CameraSourceTimeLapse.cpp",
"DataConverter.cpp",
+ "DataSourceBase.cpp",
"DataSourceFactory.cpp",
"DataURISource.cpp",
"ClearFileSource.cpp",
@@ -113,6 +114,7 @@
"MediaCodecSource.cpp",
"MediaExtractor.cpp",
"MediaExtractorFactory.cpp",
+ "MediaSource.cpp",
"MediaSync.cpp",
"MediaTrack.cpp",
"http/ClearMediaHTTP.cpp",
@@ -150,7 +152,6 @@
"libmedia",
"libmedia_omx",
"libaudioclient",
- "libmediaextractor",
"libmediametrics",
"libmediautils",
"libui",
diff --git a/media/libmediaextractor/DataSourceBase.cpp b/media/libstagefright/DataSourceBase.cpp
similarity index 100%
rename from media/libmediaextractor/DataSourceBase.cpp
rename to media/libstagefright/DataSourceBase.cpp
diff --git a/media/libmediaextractor/MediaSource.cpp b/media/libstagefright/MediaSource.cpp
similarity index 100%
rename from media/libmediaextractor/MediaSource.cpp
rename to media/libstagefright/MediaSource.cpp
diff --git a/media/libstagefright/StagefrightMediaScanner.cpp b/media/libstagefright/StagefrightMediaScanner.cpp
index 74b7340..cf4edae 100644
--- a/media/libstagefright/StagefrightMediaScanner.cpp
+++ b/media/libstagefright/StagefrightMediaScanner.cpp
@@ -127,6 +127,8 @@
{ "colorstandard", METADATA_KEY_COLOR_STANDARD },
{ "colortransfer", METADATA_KEY_COLOR_TRANSFER },
{ "colorrange", METADATA_KEY_COLOR_RANGE },
+ { "samplerate", METADATA_KEY_SAMPLERATE },
+ { "bitspersample", METADATA_KEY_BITS_PER_SAMPLE },
};
static const size_t kNumEntries = sizeof(kKeyMap) / sizeof(kKeyMap[0]);
diff --git a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
index fda7028..a8fcdd1 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
@@ -382,6 +382,7 @@
if (portIndex == 0 && mInitialized) {
CHECK_EQ((int)PVResetVideoDecoder(mHandle), (int)PV_TRUE);
}
+ mFramesConfigured = false;
}
void SoftMPEG4::onReset() {
diff --git a/media/libstagefright/foundation/Android.bp b/media/libstagefright/foundation/Android.bp
index dcf1ab8..027e593 100644
--- a/media/libstagefright/foundation/Android.bp
+++ b/media/libstagefright/foundation/Android.bp
@@ -25,6 +25,7 @@
header_libs: [
"libhardware_headers",
"libstagefright_foundation_headers",
+ "media_ndk_headers",
"media_plugin_headers",
],
@@ -64,8 +65,98 @@
"AudioPresentationInfo.cpp",
"ByteUtils.cpp",
"ColorUtils.cpp",
+ "MediaBuffer.cpp",
+ "MediaBufferBase.cpp",
+ "MediaBufferGroup.cpp",
"MediaDefs.cpp",
"MediaKeys.cpp",
+ "MetaData.cpp",
+ "MetaDataBase.cpp",
+ "avc_utils.cpp",
+ "base64.cpp",
+ "hexdump.cpp",
+ ],
+
+ clang: true,
+
+ sanitize: {
+ misc_undefined: [
+ "unsigned-integer-overflow",
+ "signed-integer-overflow",
+ ],
+ cfi: true,
+ },
+}
+
+cc_library_static {
+ name: "libstagefright_foundation_without_imemory",
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ },
+ double_loadable: true,
+ include_dirs: [
+ "frameworks/av/include",
+ "frameworks/native/include",
+ "frameworks/native/libs/arect/include",
+ "frameworks/native/libs/nativebase/include",
+ ],
+
+ local_include_dirs: [
+ "include/media/stagefright/foundation",
+ ],
+
+ header_libs: [
+ "libhardware_headers",
+ "libstagefright_foundation_headers",
+ "media_ndk_headers",
+ "media_plugin_headers",
+ ],
+
+ export_header_lib_headers: [
+ "libstagefright_foundation_headers",
+ "media_plugin_headers",
+ ],
+
+ export_shared_lib_headers: [
+ "libbinder",
+ ],
+
+ cflags: [
+ "-Wno-multichar",
+ "-Werror",
+ "-Wall",
+ "-DNO_IMEMORY",
+ ],
+
+ shared_libs: [
+ "libbinder",
+ "libutils",
+ "libcutils",
+ "liblog",
+ ],
+
+ srcs: [
+ "AAtomizer.cpp",
+ "ABitReader.cpp",
+ "ABuffer.cpp",
+ "ADebug.cpp",
+ "AHandler.cpp",
+ "ALooper.cpp",
+ "ALooperRoster.cpp",
+ "AMessage.cpp",
+ "AString.cpp",
+ "AStringUtils.cpp",
+ "AudioPresentationInfo.cpp",
+ "ByteUtils.cpp",
+ "ColorUtils.cpp",
+ "MediaBuffer.cpp",
+ "MediaBufferBase.cpp",
+ "MediaBufferGroup.cpp",
+ "MediaDefs.cpp",
+ "MediaKeys.cpp",
+ "MetaData.cpp",
+ "MetaDataBase.cpp",
"avc_utils.cpp",
"base64.cpp",
"hexdump.cpp",
diff --git a/media/libmediaextractor/MediaBuffer.cpp b/media/libstagefright/foundation/MediaBuffer.cpp
similarity index 100%
rename from media/libmediaextractor/MediaBuffer.cpp
rename to media/libstagefright/foundation/MediaBuffer.cpp
diff --git a/media/libmediaextractor/MediaBufferBase.cpp b/media/libstagefright/foundation/MediaBufferBase.cpp
similarity index 100%
rename from media/libmediaextractor/MediaBufferBase.cpp
rename to media/libstagefright/foundation/MediaBufferBase.cpp
diff --git a/media/libmediaextractor/MediaBufferGroup.cpp b/media/libstagefright/foundation/MediaBufferGroup.cpp
similarity index 100%
rename from media/libmediaextractor/MediaBufferGroup.cpp
rename to media/libstagefright/foundation/MediaBufferGroup.cpp
diff --git a/media/libmediaextractor/MetaData.cpp b/media/libstagefright/foundation/MetaData.cpp
similarity index 100%
rename from media/libmediaextractor/MetaData.cpp
rename to media/libstagefright/foundation/MetaData.cpp
diff --git a/media/libmediaextractor/MetaDataBase.cpp b/media/libstagefright/foundation/MetaDataBase.cpp
similarity index 100%
rename from media/libmediaextractor/MetaDataBase.cpp
rename to media/libstagefright/foundation/MetaDataBase.cpp
diff --git a/media/libstagefright/httplive/Android.bp b/media/libstagefright/httplive/Android.bp
index c4a072b..c0ee14e 100644
--- a/media/libstagefright/httplive/Android.bp
+++ b/media/libstagefright/httplive/Android.bp
@@ -32,7 +32,6 @@
"libcrypto",
"libcutils",
"libmedia",
- "libmediaextractor",
"libmediandk",
"libstagefright",
"libstagefright_foundation",
diff --git a/media/libmediaextractor/include/media/DataSource.h b/media/libstagefright/include/media/stagefright/DataSource.h
similarity index 100%
rename from media/libmediaextractor/include/media/DataSource.h
rename to media/libstagefright/include/media/stagefright/DataSource.h
diff --git a/media/libmediaextractor/include/media/DataSourceBase.h b/media/libstagefright/include/media/stagefright/DataSourceBase.h
similarity index 100%
rename from media/libmediaextractor/include/media/DataSourceBase.h
rename to media/libstagefright/include/media/stagefright/DataSourceBase.h
diff --git a/media/libstagefright/include/media/stagefright/MediaBuffer.h b/media/libstagefright/include/media/stagefright/MediaBuffer.h
deleted file mode 120000
index 1d49c1a..0000000
--- a/media/libstagefright/include/media/stagefright/MediaBuffer.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../../libmediaextractor/include/media/stagefright/MediaBuffer.h
\ No newline at end of file
diff --git a/media/libmediaextractor/include/media/stagefright/MediaBuffer.h b/media/libstagefright/include/media/stagefright/MediaBuffer.h
similarity index 100%
rename from media/libmediaextractor/include/media/stagefright/MediaBuffer.h
rename to media/libstagefright/include/media/stagefright/MediaBuffer.h
diff --git a/media/libstagefright/include/media/stagefright/MediaBufferBase.h b/media/libstagefright/include/media/stagefright/MediaBufferBase.h
deleted file mode 120000
index 80e49b0..0000000
--- a/media/libstagefright/include/media/stagefright/MediaBufferBase.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../../libmediaextractor/include/media/stagefright/MediaBufferBase.h
\ No newline at end of file
diff --git a/media/libmediaextractor/include/media/stagefright/MediaBufferBase.h b/media/libstagefright/include/media/stagefright/MediaBufferBase.h
similarity index 100%
rename from media/libmediaextractor/include/media/stagefright/MediaBufferBase.h
rename to media/libstagefright/include/media/stagefright/MediaBufferBase.h
diff --git a/media/libstagefright/include/media/stagefright/MediaBufferGroup.h b/media/libstagefright/include/media/stagefright/MediaBufferGroup.h
deleted file mode 120000
index 009b3d9..0000000
--- a/media/libstagefright/include/media/stagefright/MediaBufferGroup.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../../libmediaextractor/include/media/stagefright/MediaBufferGroup.h
\ No newline at end of file
diff --git a/media/libmediaextractor/include/media/stagefright/MediaBufferGroup.h b/media/libstagefright/include/media/stagefright/MediaBufferGroup.h
similarity index 100%
rename from media/libmediaextractor/include/media/stagefright/MediaBufferGroup.h
rename to media/libstagefright/include/media/stagefright/MediaBufferGroup.h
diff --git a/media/libstagefright/include/media/stagefright/MediaErrors.h b/media/libstagefright/include/media/stagefright/MediaErrors.h
index 6a5c6b6..09639e2 100644
--- a/media/libstagefright/include/media/stagefright/MediaErrors.h
+++ b/media/libstagefright/include/media/stagefright/MediaErrors.h
@@ -70,7 +70,12 @@
ERROR_DRM_DEVICE_REVOKED = DRM_ERROR_BASE - 9,
ERROR_DRM_RESOURCE_BUSY = DRM_ERROR_BASE - 10,
ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION = DRM_ERROR_BASE - 11,
- ERROR_DRM_LAST_USED_ERRORCODE = DRM_ERROR_BASE - 11,
+ ERROR_DRM_INSUFFICIENT_SECURITY = DRM_ERROR_BASE - 12,
+ ERROR_DRM_FRAME_TOO_LARGE = DRM_ERROR_BASE - 13,
+ ERROR_DRM_RESOURCE_CONTENTION = DRM_ERROR_BASE - 14,
+ ERROR_DRM_SESSION_LOST_STATE = DRM_ERROR_BASE - 15,
+ ERROR_DRM_INVALID_STATE = DRM_ERROR_BASE - 16,
+ ERROR_DRM_LAST_USED_ERRORCODE = DRM_ERROR_BASE - 16,
ERROR_DRM_VENDOR_MAX = DRM_ERROR_BASE - 500,
ERROR_DRM_VENDOR_MIN = DRM_ERROR_BASE - 999,
diff --git a/media/libmediaextractor/include/media/MediaSource.h b/media/libstagefright/include/media/stagefright/MediaSource.h
similarity index 100%
rename from media/libmediaextractor/include/media/MediaSource.h
rename to media/libstagefright/include/media/stagefright/MediaSource.h
diff --git a/media/libstagefright/include/media/stagefright/MetaData.h b/media/libstagefright/include/media/stagefright/MetaData.h
deleted file mode 120000
index 160f8d3..0000000
--- a/media/libstagefright/include/media/stagefright/MetaData.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../../libmediaextractor/include/media/stagefright/MetaData.h
\ No newline at end of file
diff --git a/media/libmediaextractor/include/media/stagefright/MetaData.h b/media/libstagefright/include/media/stagefright/MetaData.h
similarity index 100%
rename from media/libmediaextractor/include/media/stagefright/MetaData.h
rename to media/libstagefright/include/media/stagefright/MetaData.h
diff --git a/media/libstagefright/include/media/stagefright/MetaDataBase.h b/media/libstagefright/include/media/stagefright/MetaDataBase.h
deleted file mode 120000
index 1e12193..0000000
--- a/media/libstagefright/include/media/stagefright/MetaDataBase.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../../libmediaextractor/include/media/stagefright/MetaDataBase.h
\ No newline at end of file
diff --git a/media/libmediaextractor/include/media/stagefright/MetaDataBase.h b/media/libstagefright/include/media/stagefright/MetaDataBase.h
similarity index 100%
rename from media/libmediaextractor/include/media/stagefright/MetaDataBase.h
rename to media/libstagefright/include/media/stagefright/MetaDataBase.h
diff --git a/media/libstagefright/omx/tests/Android.bp b/media/libstagefright/omx/tests/Android.bp
index 31bc837..fb03229 100644
--- a/media/libstagefright/omx/tests/Android.bp
+++ b/media/libstagefright/omx/tests/Android.bp
@@ -9,7 +9,6 @@
"libbinder",
"libmedia",
"libmedia_omx",
- "libmediaextractor",
"libutils",
"liblog",
"libstagefright_foundation",
diff --git a/media/ndk/Android.bp b/media/ndk/Android.bp
index 73bd2ca..74754ea 100644
--- a/media/ndk/Android.bp
+++ b/media/ndk/Android.bp
@@ -78,7 +78,6 @@
"libmedia_omx",
"libmedia_jni",
"libmediadrm",
- "libmediaextractor",
"libstagefright",
"libstagefright_foundation",
"libstagefright_bufferqueue_helper",
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h
index 5099ebb..d52eb3d 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h
@@ -133,18 +133,14 @@
mDefaultOutputDevice->attach(module);
defaultInputDevice->attach(module);
- sp<OutputProfile> outProfile;
- outProfile = new OutputProfile(String8("primary"));
- outProfile->attach(module);
+ sp<OutputProfile> outProfile = new OutputProfile(String8("primary"));
outProfile->addAudioProfile(
new AudioProfile(AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO, 44100));
outProfile->addSupportedDevice(mDefaultOutputDevice);
outProfile->setFlags(AUDIO_OUTPUT_FLAG_PRIMARY);
module->addOutputProfile(outProfile);
- sp<InputProfile> inProfile;
- inProfile = new InputProfile(String8("primary"));
- inProfile->attach(module);
+ sp<InputProfile> inProfile = new InputProfile(String8("primary"));
inProfile->addAudioProfile(micProfile);
inProfile->addSupportedDevice(defaultInputDevice);
module->addInputProfile(inProfile);
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
index 776d98f..4d0916e 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
@@ -360,10 +360,12 @@
break;
}
}
- if (!deviceMatch) {
+ if (deviceMatch) {
+ mix->setMatchUid(uid);
+ } else {
// this mix doesn't go to one of the listed devices for the given uid,
// modify its rules to exclude the uid
- mix->excludeUid(uid);
+ mix->setExcludeUid(uid);
}
}
@@ -382,7 +384,7 @@
for (size_t j = 0; j < mix->mCriteria.size(); j++) {
const uint32_t rule = mix->mCriteria[j].mRule;
// is this rule affecting the uid?
- if (rule == RULE_EXCLUDE_UID
+ if ((rule == RULE_EXCLUDE_UID || rule == RULE_MATCH_UID)
&& uid == mix->mCriteria[j].mValue.mUid) {
foundUidRule = true;
criteriaToRemove.push_back(j);
diff --git a/services/audiopolicy/tests/audiopolicymanager_tests.cpp b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
index 56af152..24326bb 100644
--- a/services/audiopolicy/tests/audiopolicymanager_tests.cpp
+++ b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
@@ -112,10 +112,34 @@
std::set<audio_patch_handle_t> mActivePatches;
};
+class PatchCountCheck {
+ public:
+ explicit PatchCountCheck(AudioPolicyManagerTestClient *client)
+ : mClient{client},
+ mInitialCount{mClient->getActivePatchesCount()} {}
+ void assertDelta(int delta) const {
+ ASSERT_EQ(mInitialCount + delta, mClient->getActivePatchesCount()); }
+ void assertNoChange() const { assertDelta(0); }
+ private:
+ const AudioPolicyManagerTestClient *mClient;
+ const size_t mInitialCount;
+};
+
class AudioPolicyManagerTest : public testing::Test {
protected:
- virtual void SetUp();
- virtual void TearDown();
+ void SetUp() override;
+ void TearDown() override;
+ virtual void SetUpConfig(AudioPolicyConfig *config) { (void)config; }
+
+ void dumpToLog();
+ void getOutputForAttr(
+ audio_port_handle_t *selectedDeviceId,
+ audio_format_t format,
+ int channelMask,
+ int sampleRate,
+ audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
+ audio_port_handle_t *portId = nullptr);
+ PatchCountCheck snapPatchCount() { return PatchCountCheck(mClient.get()); }
std::unique_ptr<AudioPolicyManagerTestClient> mClient;
std::unique_ptr<AudioPolicyTestManager> mManager;
@@ -125,6 +149,7 @@
mClient.reset(new AudioPolicyManagerTestClient);
mManager.reset(new AudioPolicyTestManager(mClient.get()));
mManager->getConfig().setDefault();
+ SetUpConfig(&mManager->getConfig()); // Subclasses may want to customize the config.
ASSERT_EQ(NO_ERROR, mManager->initialize());
ASSERT_EQ(NO_ERROR, mManager->initCheck());
}
@@ -134,11 +159,7 @@
mClient.reset();
}
-TEST_F(AudioPolicyManagerTest, InitSuccess) {
- // SetUp must finish with no assertions.
-}
-
-TEST_F(AudioPolicyManagerTest, Dump) {
+void AudioPolicyManagerTest::dumpToLog() {
int pipefd[2];
ASSERT_NE(-1, pipe(pipefd));
pid_t cpid = fork();
@@ -168,10 +189,43 @@
}
}
+void AudioPolicyManagerTest::getOutputForAttr(
+ audio_port_handle_t *selectedDeviceId,
+ audio_format_t format,
+ int channelMask,
+ int sampleRate,
+ audio_output_flags_t flags,
+ audio_port_handle_t *portId) {
+ audio_attributes_t attr = {};
+ audio_io_handle_t output = AUDIO_PORT_HANDLE_NONE;
+ audio_stream_type_t stream = AUDIO_STREAM_DEFAULT;
+ audio_config_t config = AUDIO_CONFIG_INITIALIZER;
+ config.sample_rate = sampleRate;
+ config.channel_mask = channelMask;
+ config.format = format;
+ *selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ audio_port_handle_t localPortId;
+ if (!portId) portId = &localPortId;
+ *portId = AUDIO_PORT_HANDLE_NONE;
+ ASSERT_EQ(OK, mManager->getOutputForAttr(
+ &attr, &output, AUDIO_SESSION_NONE, &stream, 0 /*uid*/, &config, &flags,
+ selectedDeviceId, portId));
+ ASSERT_NE(AUDIO_PORT_HANDLE_NONE, *portId);
+}
+
+
+TEST_F(AudioPolicyManagerTest, InitSuccess) {
+ // SetUp must finish with no assertions.
+}
+
+TEST_F(AudioPolicyManagerTest, Dump) {
+ dumpToLog();
+}
+
TEST_F(AudioPolicyManagerTest, CreateAudioPatchFailure) {
audio_patch patch{};
audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE;
- const size_t patchCountBefore = mClient->getActivePatchesCount();
+ const PatchCountCheck patchCount = snapPatchCount();
ASSERT_EQ(BAD_VALUE, mManager->createAudioPatch(nullptr, &handle, 0));
ASSERT_EQ(BAD_VALUE, mManager->createAudioPatch(&patch, nullptr, 0));
ASSERT_EQ(BAD_VALUE, mManager->createAudioPatch(&patch, &handle, 0));
@@ -198,20 +252,182 @@
ASSERT_EQ(INVALID_OPERATION, mManager->createAudioPatch(&patch, &handle, 0));
// Verify that the handle is left unchanged.
ASSERT_EQ(AUDIO_PATCH_HANDLE_NONE, handle);
- ASSERT_EQ(patchCountBefore, mClient->getActivePatchesCount());
+ patchCount.assertNoChange();
}
TEST_F(AudioPolicyManagerTest, CreateAudioPatchFromMix) {
audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE;
uid_t uid = 42;
- const size_t patchCountBefore = mClient->getActivePatchesCount();
+ const PatchCountCheck patchCount = snapPatchCount();
ASSERT_FALSE(mManager->getConfig().getAvailableInputDevices().isEmpty());
PatchBuilder patchBuilder;
patchBuilder.addSource(mManager->getConfig().getAvailableInputDevices()[0]).
addSink(mManager->getConfig().getDefaultOutputDevice());
ASSERT_EQ(NO_ERROR, mManager->createAudioPatch(patchBuilder.patch(), &handle, uid));
ASSERT_NE(AUDIO_PATCH_HANDLE_NONE, handle);
- ASSERT_EQ(patchCountBefore + 1, mClient->getActivePatchesCount());
+ patchCount.assertDelta(1);
}
// TODO: Add patch creation tests that involve already existing patch
+
+class AudioPolicyManagerTestMsd : public AudioPolicyManagerTest {
+ protected:
+ void SetUpConfig(AudioPolicyConfig *config) override;
+ void TearDown() override;
+
+ sp<DeviceDescriptor> mMsdOutputDevice;
+ sp<DeviceDescriptor> mMsdInputDevice;
+};
+
+void AudioPolicyManagerTestMsd::SetUpConfig(AudioPolicyConfig *config) {
+ // TODO: Consider using Serializer to load part of the config from a string.
+ mMsdOutputDevice = new DeviceDescriptor(AUDIO_DEVICE_OUT_BUS);
+ sp<AudioProfile> pcmOutputProfile = new AudioProfile(
+ AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO, 48000);
+ sp<AudioProfile> ac3OutputProfile = new AudioProfile(
+ AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1, 48000);
+ mMsdOutputDevice->addAudioProfile(pcmOutputProfile);
+ mMsdOutputDevice->addAudioProfile(ac3OutputProfile);
+ mMsdInputDevice = new DeviceDescriptor(AUDIO_DEVICE_IN_BUS);
+ // Match output profile from AudioPolicyConfig::setDefault.
+ sp<AudioProfile> pcmInputProfile = new AudioProfile(
+ AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO, 44100);
+ mMsdInputDevice->addAudioProfile(pcmInputProfile);
+ config->addAvailableDevice(mMsdOutputDevice);
+ config->addAvailableDevice(mMsdInputDevice);
+
+ sp<HwModule> msdModule = new HwModule(AUDIO_HARDWARE_MODULE_ID_MSD, 2 /*halVersionMajor*/);
+ HwModuleCollection modules = config->getHwModules();
+ modules.add(msdModule);
+ config->setHwModules(modules);
+ mMsdOutputDevice->attach(msdModule);
+ mMsdInputDevice->attach(msdModule);
+
+ sp<OutputProfile> msdOutputProfile = new OutputProfile(String8("msd input"));
+ msdOutputProfile->addAudioProfile(pcmOutputProfile);
+ msdOutputProfile->addSupportedDevice(mMsdOutputDevice);
+ msdModule->addOutputProfile(msdOutputProfile);
+ sp<OutputProfile> msdCompressedOutputProfile =
+ new OutputProfile(String8("msd compressed input"));
+ msdCompressedOutputProfile->addAudioProfile(ac3OutputProfile);
+ msdCompressedOutputProfile->setFlags(
+ AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD |
+ AUDIO_OUTPUT_FLAG_NON_BLOCKING);
+ msdCompressedOutputProfile->addSupportedDevice(mMsdOutputDevice);
+ msdModule->addOutputProfile(msdCompressedOutputProfile);
+
+ sp<InputProfile> msdInputProfile = new InputProfile(String8("msd output"));
+ msdInputProfile->addAudioProfile(pcmInputProfile);
+ msdInputProfile->addSupportedDevice(mMsdInputDevice);
+ msdModule->addInputProfile(msdInputProfile);
+
+ // Add a profile with another encoding to the default device to test routing
+ // of streams that are not supported by MSD.
+ sp<AudioProfile> dtsOutputProfile = new AudioProfile(
+ AUDIO_FORMAT_DTS, AUDIO_CHANNEL_OUT_5POINT1, 48000);
+ config->getDefaultOutputDevice()->addAudioProfile(dtsOutputProfile);
+ sp<OutputProfile> primaryEncodedOutputProfile = new OutputProfile(String8("encoded"));
+ primaryEncodedOutputProfile->addAudioProfile(dtsOutputProfile);
+ primaryEncodedOutputProfile->setFlags(AUDIO_OUTPUT_FLAG_DIRECT);
+ primaryEncodedOutputProfile->addSupportedDevice(config->getDefaultOutputDevice());
+ config->getHwModules().getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY)->
+ addOutputProfile(primaryEncodedOutputProfile);
+}
+
+void AudioPolicyManagerTestMsd::TearDown() {
+ mMsdOutputDevice.clear();
+ mMsdInputDevice.clear();
+ AudioPolicyManagerTest::TearDown();
+}
+
+TEST_F(AudioPolicyManagerTestMsd, InitSuccess) {
+ ASSERT_TRUE(mMsdOutputDevice);
+ ASSERT_TRUE(mMsdInputDevice);
+}
+
+TEST_F(AudioPolicyManagerTestMsd, Dump) {
+ dumpToLog();
+}
+
+TEST_F(AudioPolicyManagerTestMsd, PatchCreationOnSetForceUse) {
+ const PatchCountCheck patchCount = snapPatchCount();
+ mManager->setForceUse(AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND,
+ AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS);
+ patchCount.assertDelta(1);
+}
+
+TEST_F(AudioPolicyManagerTestMsd, GetOutputForAttrEncodedRoutesToMsd) {
+ const PatchCountCheck patchCount = snapPatchCount();
+ audio_port_handle_t selectedDeviceId;
+ getOutputForAttr(&selectedDeviceId,
+ AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1, 48000, AUDIO_OUTPUT_FLAG_DIRECT);
+ ASSERT_EQ(selectedDeviceId, mMsdOutputDevice->getId());
+ patchCount.assertDelta(1);
+}
+
+TEST_F(AudioPolicyManagerTestMsd, GetOutputForAttrPcmRoutesToMsd) {
+ const PatchCountCheck patchCount = snapPatchCount();
+ audio_port_handle_t selectedDeviceId;
+ getOutputForAttr(&selectedDeviceId,
+ AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO, 48000);
+ ASSERT_EQ(selectedDeviceId, mMsdOutputDevice->getId());
+ patchCount.assertDelta(1);
+}
+
+TEST_F(AudioPolicyManagerTestMsd, GetOutputForAttrEncodedPlusPcmRoutesToMsd) {
+ const PatchCountCheck patchCount = snapPatchCount();
+ audio_port_handle_t selectedDeviceId;
+ getOutputForAttr(&selectedDeviceId,
+ AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1, 48000, AUDIO_OUTPUT_FLAG_DIRECT);
+ ASSERT_EQ(selectedDeviceId, mMsdOutputDevice->getId());
+ patchCount.assertDelta(1);
+ getOutputForAttr(&selectedDeviceId,
+ AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO, 48000);
+ ASSERT_EQ(selectedDeviceId, mMsdOutputDevice->getId());
+ patchCount.assertDelta(1);
+}
+
+TEST_F(AudioPolicyManagerTestMsd, GetOutputForAttrUnsupportedFormatBypassesMsd) {
+ const PatchCountCheck patchCount = snapPatchCount();
+ audio_port_handle_t selectedDeviceId;
+ getOutputForAttr(&selectedDeviceId,
+ AUDIO_FORMAT_DTS, AUDIO_CHANNEL_OUT_5POINT1, 48000, AUDIO_OUTPUT_FLAG_DIRECT);
+ ASSERT_NE(selectedDeviceId, mMsdOutputDevice->getId());
+ patchCount.assertNoChange();
+}
+
+TEST_F(AudioPolicyManagerTestMsd, GetOutputForAttrFormatSwitching) {
+ // Switch between formats that are supported and not supported by MSD.
+ {
+ const PatchCountCheck patchCount = snapPatchCount();
+ audio_port_handle_t selectedDeviceId, portId;
+ getOutputForAttr(&selectedDeviceId,
+ AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1, 48000, AUDIO_OUTPUT_FLAG_DIRECT,
+ &portId);
+ ASSERT_EQ(selectedDeviceId, mMsdOutputDevice->getId());
+ patchCount.assertDelta(1);
+ mManager->releaseOutput(portId);
+ patchCount.assertDelta(1); // compared to the state at the block entry
+ // TODO: make PatchCountCheck asserts more obvious. It's easy to
+ // miss the fact that it is immutable.
+ }
+ {
+ const PatchCountCheck patchCount = snapPatchCount();
+ audio_port_handle_t selectedDeviceId, portId;
+ getOutputForAttr(&selectedDeviceId,
+ AUDIO_FORMAT_DTS, AUDIO_CHANNEL_OUT_5POINT1, 48000, AUDIO_OUTPUT_FLAG_DIRECT,
+ &portId);
+ ASSERT_NE(selectedDeviceId, mMsdOutputDevice->getId());
+ patchCount.assertDelta(-1);
+ mManager->releaseOutput(portId);
+ patchCount.assertNoChange();
+ }
+ {
+ const PatchCountCheck patchCount = snapPatchCount();
+ audio_port_handle_t selectedDeviceId;
+ getOutputForAttr(&selectedDeviceId,
+ AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1, 48000, AUDIO_OUTPUT_FLAG_DIRECT);
+ ASSERT_EQ(selectedDeviceId, mMsdOutputDevice->getId());
+ patchCount.assertNoChange();
+ }
+}
diff --git a/services/mediaextractor/Android.mk b/services/mediaextractor/Android.mk
index 6101c8a..dd64881 100644
--- a/services/mediaextractor/Android.mk
+++ b/services/mediaextractor/Android.mk
@@ -46,6 +46,7 @@
LOCAL_INIT_RC := mediaextractor.rc
LOCAL_C_INCLUDES := frameworks/av/media/libmedia
LOCAL_CFLAGS := -Wall -Werror
+LOCAL_SANITIZE := scudo
include $(BUILD_EXECUTABLE)
# service seccomp filter
diff --git a/services/mediaextractor/main_extractorservice.cpp b/services/mediaextractor/main_extractorservice.cpp
index 8d3359a..5f42711 100644
--- a/services/mediaextractor/main_extractorservice.cpp
+++ b/services/mediaextractor/main_extractorservice.cpp
@@ -42,6 +42,12 @@
static const char kVendorSeccompPolicyPath[] =
"/vendor/etc/seccomp_policy/mediaextractor.policy";
+// Disable Scudo's mismatch allocation check, as it is being triggered
+// by some third party code.
+extern "C" const char *__scudo_default_options() {
+ return "DeallocationTypeMismatch=false";
+}
+
int main(int argc __unused, char** argv)
{
limitProcessMemory(