Merge "NdkMediaDrm: get app name from /proc/self/cmdline"
diff --git a/apex/testing/Android.bp b/apex/testing/Android.bp
index 701ced7..477c371 100644
--- a/apex/testing/Android.bp
+++ b/apex/testing/Android.bp
@@ -15,7 +15,7 @@
apex {
name: "test_com.android.media",
manifest: "test_manifest.json",
- file_contexts: "com.android.media",
+ file_contexts: ":com.android.media-file_contexts",
defaults: ["com.android.media-defaults"],
installable: false,
}
@@ -23,7 +23,7 @@
apex {
name: "test_com.android.media.swcodec",
manifest: "test_manifest_codec.json",
- file_contexts: "com.android.media.swcodec",
+ file_contexts: ":com.android.media.swcodec-file_contexts",
defaults: ["com.android.media.swcodec-defaults"],
installable: false,
}
diff --git a/camera/ndk/impl/ACameraManager.cpp b/camera/ndk/impl/ACameraManager.cpp
index 8eb030a..7a0f63b 100644
--- a/camera/ndk/impl/ACameraManager.cpp
+++ b/camera/ndk/impl/ACameraManager.cpp
@@ -76,6 +76,10 @@
sp<hardware::ICameraService> CameraManagerGlobal::getCameraService() {
Mutex::Autolock _l(mLock);
+ return getCameraServiceLocked();
+}
+
+sp<hardware::ICameraService> CameraManagerGlobal::getCameraServiceLocked() {
if (mCameraService.get() == nullptr) {
if (isCameraServiceDisabled()) {
return mCameraService;
@@ -216,8 +220,12 @@
if (pair.second) {
for (auto& pair : mDeviceStatusMap) {
const String8& cameraId = pair.first;
- int32_t status = pair.second;
-
+ int32_t status = pair.second.status;
+ // Don't send initial callbacks for camera ids which don't support
+ // camera2
+ if (!pair.second.supportsHAL3) {
+ continue;
+ }
sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
ACameraManager_AvailabilityCallback cb = isStatusAvailable(status) ?
callback->onCameraAvailable : callback->onCameraUnavailable;
@@ -236,20 +244,32 @@
mCallbacks.erase(cb);
}
+bool CameraManagerGlobal::supportsCamera2ApiLocked(const String8 &cameraId) {
+ bool camera2Support = false;
+ auto cs = getCameraServiceLocked();
+ binder::Status serviceRet =
+ cs->supportsCameraApi(String16(cameraId),
+ hardware::ICameraService::API_VERSION_2, &camera2Support);
+ if (!serviceRet.isOk()) {
+ ALOGE("%s: supportsCameraApi2Locked() call failed for cameraId %s",
+ __FUNCTION__, cameraId.c_str());
+ return false;
+ }
+ return camera2Support;
+}
+
void CameraManagerGlobal::getCameraIdList(std::vector<String8>* cameraIds) {
// Ensure that we have initialized/refreshed the list of available devices
- auto cs = getCameraService();
Mutex::Autolock _l(mLock);
-
+ // Needed to make sure we're connected to cameraservice
+ getCameraServiceLocked();
for(auto& deviceStatus : mDeviceStatusMap) {
- if (deviceStatus.second == hardware::ICameraServiceListener::STATUS_NOT_PRESENT ||
- deviceStatus.second == hardware::ICameraServiceListener::STATUS_ENUMERATING) {
+ if (deviceStatus.second.status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT ||
+ deviceStatus.second.status ==
+ hardware::ICameraServiceListener::STATUS_ENUMERATING) {
continue;
}
- bool camera2Support = false;
- binder::Status serviceRet = cs->supportsCameraApi(String16(deviceStatus.first),
- hardware::ICameraService::API_VERSION_2, &camera2Support);
- if (!serviceRet.isOk() || !camera2Support) {
+ if (!deviceStatus.second.supportsHAL3) {
continue;
}
cameraIds->push_back(deviceStatus.first);
@@ -377,7 +397,7 @@
bool firstStatus = (mDeviceStatusMap.count(cameraId) == 0);
int32_t oldStatus = firstStatus ?
status : // first status
- mDeviceStatusMap[cameraId];
+ mDeviceStatusMap[cameraId].status;
if (!firstStatus &&
isStatusAvailable(status) == isStatusAvailable(oldStatus)) {
@@ -385,16 +405,19 @@
return;
}
+ bool supportsHAL3 = supportsCamera2ApiLocked(cameraId);
// Iterate through all registered callbacks
- mDeviceStatusMap[cameraId] = status;
- for (auto cb : mCallbacks) {
- sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
- ACameraManager_AvailabilityCallback cbFp = isStatusAvailable(status) ?
- cb.mAvailable : cb.mUnavailable;
- msg->setPointer(kCallbackFpKey, (void *) cbFp);
- msg->setPointer(kContextKey, cb.mContext);
- msg->setString(kCameraIdKey, AString(cameraId));
- msg->post();
+ mDeviceStatusMap[cameraId] = StatusAndHAL3Support(status, supportsHAL3);
+ if (supportsHAL3) {
+ for (auto cb : mCallbacks) {
+ sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
+ ACameraManager_AvailabilityCallback cbFp = isStatusAvailable(status) ?
+ cb.mAvailable : cb.mUnavailable;
+ msg->setPointer(kCallbackFpKey, (void *) cbFp);
+ msg->setPointer(kContextKey, cb.mContext);
+ msg->setString(kCameraIdKey, AString(cameraId));
+ msg->post();
+ }
}
if (status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT) {
mDeviceStatusMap.erase(cameraId);
diff --git a/camera/ndk/impl/ACameraManager.h b/camera/ndk/impl/ACameraManager.h
index 8c1da36..e945ba0 100644
--- a/camera/ndk/impl/ACameraManager.h
+++ b/camera/ndk/impl/ACameraManager.h
@@ -66,9 +66,9 @@
private:
sp<hardware::ICameraService> mCameraService;
- const int kCameraServicePollDelay = 500000; // 0.5s
- const char* kCameraServiceName = "media.camera";
- Mutex mLock;
+ const int kCameraServicePollDelay = 500000; // 0.5s
+ const char* kCameraServiceName = "media.camera";
+ Mutex mLock;
class DeathNotifier : public IBinder::DeathRecipient {
public:
@@ -156,12 +156,14 @@
sp<CallbackHandler> mHandler;
sp<ALooper> mCbLooper; // Looper thread where callbacks actually happen on
+ sp<hardware::ICameraService> getCameraServiceLocked();
void onCameraAccessPrioritiesChanged();
void onStatusChanged(int32_t status, const String8& cameraId);
void onStatusChangedLocked(int32_t status, const String8& cameraId);
// Utils for status
static bool validStatus(int32_t status);
static bool isStatusAvailable(int32_t status);
+ bool supportsCamera2ApiLocked(const String8 &cameraId);
// The sort logic must match the logic in
// libcameraservice/common/CameraProviderManager.cpp::getAPI1CompatibleCameraDeviceIds
@@ -184,8 +186,16 @@
}
};
+ struct StatusAndHAL3Support {
+ int32_t status = hardware::ICameraServiceListener::STATUS_NOT_PRESENT;
+ bool supportsHAL3 = false;
+ StatusAndHAL3Support(int32_t st, bool HAL3support):
+ status(st), supportsHAL3(HAL3support) { };
+ StatusAndHAL3Support() = default;
+ };
+
// Map camera_id -> status
- std::map<String8, int32_t, CameraIdComparator> mDeviceStatusMap;
+ std::map<String8, StatusAndHAL3Support, CameraIdComparator> mDeviceStatusMap;
// For the singleton instance
static Mutex sLock;
diff --git a/drm/libmediadrm/Android.bp b/drm/libmediadrm/Android.bp
index 26e147b..4c411be 100644
--- a/drm/libmediadrm/Android.bp
+++ b/drm/libmediadrm/Android.bp
@@ -17,7 +17,6 @@
srcs: [
"DrmPluginPath.cpp",
"DrmSessionManager.cpp",
- "IMediaDrmService.cpp",
"SharedLibrary.cpp",
"DrmHal.cpp",
"CryptoHal.cpp",
@@ -39,14 +38,14 @@
shared_libs: [
"libbinder",
+ "libbinder_ndk",
"libcutils",
"libdl",
"liblog",
"libmedia",
"libmediadrmmetrics_lite",
- "libmediametrics",
+ "libmediametrics#1",
"libmediautils",
- "libresourcemanagerservice",
"libstagefright_foundation",
"libutils",
"android.hardware.drm@1.0",
@@ -56,6 +55,10 @@
"libhidlbase",
],
+ static_libs: [
+ "resourcemanager_aidl_interface-ndk_platform",
+ ],
+
export_shared_lib_headers: [
"android.hardware.drm@1.0",
"android.hardware.drm@1.1",
@@ -92,8 +95,6 @@
"android.hardware.drm@1.0",
"android.hardware.drm@1.1",
"android.hardware.drm@1.2",
- "libbinder",
- "libhidlbase",
"liblog",
"libmediametrics",
"libprotobuf-cpp-lite",
@@ -131,8 +132,6 @@
"android.hardware.drm@1.1",
"android.hardware.drm@1.2",
"libbase",
- "libbinder",
- "libhidlbase",
"liblog",
"libmediametrics",
"libprotobuf-cpp-full",
@@ -146,3 +145,25 @@
],
}
+cc_library_shared {
+ name: "libmediadrmmetrics_consumer",
+ srcs: [
+ "DrmMetricsConsumer.cpp",
+ ],
+
+ include_dirs: [
+ "frameworks/av/media/libmedia/include"
+ ],
+
+ shared_libs: [
+ "android.hardware.drm@1.0",
+ "android.hardware.drm@1.1",
+ "android.hardware.drm@1.2",
+ "libbinder",
+ "libhidlbase",
+ "liblog",
+ "libmediadrm",
+ "libmediadrmmetrics_full",
+ "libutils",
+ ],
+}
diff --git a/drm/libmediadrm/CryptoHal.cpp b/drm/libmediadrm/CryptoHal.cpp
index 6a0e75e..55b9bb8 100644
--- a/drm/libmediadrm/CryptoHal.cpp
+++ b/drm/libmediadrm/CryptoHal.cpp
@@ -45,6 +45,7 @@
using ::android::hardware::hidl_memory;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
+using ::android::hardware::HidlMemory;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::sp;
@@ -255,10 +256,7 @@
* size. Once the heap base is established, shared memory buffers
* are sent by providing an offset into the heap and a buffer size.
*/
-int32_t CryptoHal::setHeapBase(const sp<IMemoryHeap>& heap) {
- using ::android::hardware::fromHeap;
- using ::android::hardware::HidlMemory;
-
+int32_t CryptoHal::setHeapBase(const sp<HidlMemory>& heap) {
if (heap == NULL || mHeapSeqNum < 0) {
ALOGE("setHeapBase(): heap %p mHeapSeqNum %d", heap.get(), mHeapSeqNum);
return -1;
@@ -268,9 +266,8 @@
int32_t seqNum = mHeapSeqNum++;
uint32_t bufferId = static_cast<uint32_t>(seqNum);
- sp<HidlMemory> hidlMemory = fromHeap(heap);
- mHeapBases.add(seqNum, HeapBase(bufferId, heap->getSize()));
- Return<void> hResult = mPlugin->setSharedBufferBase(*hidlMemory, bufferId);
+ mHeapSizes.add(seqNum, heap->size());
+ Return<void> hResult = mPlugin->setSharedBufferBase(*heap, bufferId);
ALOGE_IF(!hResult.isOk(), "setSharedBufferBase(): remote call failed");
return seqNum;
}
@@ -285,64 +282,40 @@
* TODO: Add a releaseSharedBuffer method in a future DRM HAL
* API version to make this explicit.
*/
- ssize_t index = mHeapBases.indexOfKey(seqNum);
+ ssize_t index = mHeapSizes.indexOfKey(seqNum);
if (index >= 0) {
if (mPlugin != NULL) {
- uint32_t bufferId = mHeapBases[index].getBufferId();
+ uint32_t bufferId = static_cast<uint32_t>(seqNum);
Return<void> hResult = mPlugin->setSharedBufferBase(hidl_memory(), bufferId);
ALOGE_IF(!hResult.isOk(), "setSharedBufferBase(): remote call failed");
}
- mHeapBases.removeItem(seqNum);
+ mHeapSizes.removeItem(seqNum);
}
}
-status_t CryptoHal::toSharedBuffer(const sp<IMemory>& memory, int32_t seqNum, ::SharedBuffer* buffer) {
- ssize_t offset;
- size_t size;
-
- if (memory == NULL || buffer == NULL) {
- return UNEXPECTED_NULL;
- }
-
- sp<IMemoryHeap> heap = memory->getMemory(&offset, &size);
- if (heap == NULL) {
- return UNEXPECTED_NULL;
- }
-
+status_t CryptoHal::checkSharedBuffer(const ::SharedBuffer &buffer) {
+ int32_t seqNum = static_cast<int32_t>(buffer.bufferId);
// memory must be in one of the heaps that have been set
- if (mHeapBases.indexOfKey(seqNum) < 0) {
+ if (mHeapSizes.indexOfKey(seqNum) < 0) {
return UNKNOWN_ERROR;
}
- // heap must be the same size as the one that was set in setHeapBase
- if (mHeapBases.valueFor(seqNum).getSize() != heap->getSize()) {
- android_errorWriteLog(0x534e4554, "76221123");
- return UNKNOWN_ERROR;
- }
-
// memory must be within the address space of the heap
- // TODO: Using unsecurePointer() has some associated security pitfalls
- // (see declaration for details).
- // Either document why it is safe in this case or address the
- // issue (e.g. by copying).
- if (memory->unsecurePointer() != static_cast<uint8_t *>(heap->getBase()) + memory->offset() ||
- heap->getSize() < memory->offset() + memory->size() ||
- SIZE_MAX - memory->offset() < memory->size()) {
+ size_t heapSize = mHeapSizes.valueFor(seqNum);
+ if (heapSize < buffer.offset + buffer.size ||
+ SIZE_MAX - buffer.offset < buffer.size) {
android_errorWriteLog(0x534e4554, "76221123");
return UNKNOWN_ERROR;
}
- buffer->bufferId = mHeapBases.valueFor(seqNum).getBufferId();
- buffer->offset = offset >= 0 ? offset : 0;
- buffer->size = size;
return OK;
}
ssize_t CryptoHal::decrypt(const uint8_t keyId[16], const uint8_t iv[16],
CryptoPlugin::Mode mode, const CryptoPlugin::Pattern &pattern,
- const ICrypto::SourceBuffer &source, size_t offset,
+ const ::SharedBuffer &hSource, size_t offset,
const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
- const ICrypto::DestinationBuffer &destination, AString *errorDetailMsg) {
+ const ::DestinationBuffer &hDestination, AString *errorDetailMsg) {
Mutex::Autolock autoLock(mLock);
if (mInitCheck != OK) {
@@ -380,28 +353,21 @@
}
auto hSubSamples = hidl_vec<SubSample>(stdSubSamples);
- int32_t heapSeqNum = source.mHeapSeqNum;
bool secure;
- ::DestinationBuffer hDestination;
- if (destination.mType == kDestinationTypeSharedMemory) {
- hDestination.type = BufferType::SHARED_MEMORY;
- status_t status = toSharedBuffer(destination.mSharedMemory, heapSeqNum,
- &hDestination.nonsecureMemory);
+ if (hDestination.type == BufferType::SHARED_MEMORY) {
+ status_t status = checkSharedBuffer(hDestination.nonsecureMemory);
if (status != OK) {
return status;
}
secure = false;
- } else if (destination.mType == kDestinationTypeNativeHandle) {
- hDestination.type = BufferType::NATIVE_HANDLE;
- hDestination.secureMemory = hidl_handle(destination.mHandle);
+ } else if (hDestination.type == BufferType::NATIVE_HANDLE) {
secure = true;
} else {
android_errorWriteLog(0x534e4554, "70526702");
return UNKNOWN_ERROR;
}
- ::SharedBuffer hSource;
- status_t status = toSharedBuffer(source.mSharedMemory, heapSeqNum, &hSource);
+ status_t status = checkSharedBuffer(hSource);
if (status != OK) {
return status;
}
diff --git a/drm/libmediadrm/DrmHal.cpp b/drm/libmediadrm/DrmHal.cpp
index 53a7446..757ccda 100644
--- a/drm/libmediadrm/DrmHal.cpp
+++ b/drm/libmediadrm/DrmHal.cpp
@@ -20,14 +20,14 @@
#include <utils/Log.h>
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
+#include <android/binder_manager.h>
+#include <aidl/android/media/BnResourceManagerClient.h>
#include <android/hardware/drm/1.2/types.h>
#include <android/hidl/manager/1.2/IServiceManager.h>
-#include <android/media/BnResourceManagerClient.h>
#include <hidl/ServiceManagement.h>
#include <media/EventMetric.h>
+#include <media/MediaMetrics.h>
#include <media/PluginMetricsReporting.h>
#include <media/drm/DrmAPI.h>
#include <media/stagefright/foundation/ADebug.h>
@@ -38,6 +38,7 @@
#include <mediadrm/DrmHal.h>
#include <mediadrm/DrmSessionClientInterface.h>
#include <mediadrm/DrmSessionManager.h>
+#include <mediadrm/IDrmMetricsConsumer.h>
#include <vector>
@@ -98,17 +99,6 @@
#define INIT_CHECK() {if (mInitCheck != OK) return mInitCheck;}
-static inline int getCallingPid() {
- return IPCThreadState::self()->getCallingPid();
-}
-
-static bool checkPermission(const char* permissionString) {
- if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
- bool ok = checkCallingPermission(String16(permissionString));
- if (!ok) ALOGE("Request requires %s", permissionString);
- return ok;
-}
-
static const Vector<uint8_t> toVector(const hidl_vec<uint8_t> &vec) {
Vector<uint8_t> vector;
vector.appendArray(vec.data(), vec.size());
@@ -298,17 +288,16 @@
Mutex DrmHal::mLock;
-struct DrmHal::DrmSessionClient : public android::media::BnResourceManagerClient {
+struct DrmHal::DrmSessionClient : public aidl::android::media::BnResourceManagerClient {
explicit DrmSessionClient(DrmHal* drm, const Vector<uint8_t>& sessionId)
: mSessionId(sessionId),
mDrm(drm) {}
- ::android::binder::Status reclaimResource(bool* _aidl_return) override;
- ::android::binder::Status getName(::std::string* _aidl_return) override;
+ ::ndk::ScopedAStatus reclaimResource(bool* _aidl_return) override;
+ ::ndk::ScopedAStatus getName(::std::string* _aidl_return) override;
const Vector<uint8_t> mSessionId;
-protected:
virtual ~DrmSessionClient();
private:
@@ -317,24 +306,25 @@
DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
};
-::android::binder::Status DrmHal::DrmSessionClient::reclaimResource(bool* _aidl_return) {
+::ndk::ScopedAStatus DrmHal::DrmSessionClient::reclaimResource(bool* _aidl_return) {
+ auto sessionId = mSessionId;
sp<DrmHal> drm = mDrm.promote();
if (drm == NULL) {
*_aidl_return = true;
- return ::android::binder::Status::ok();
+ return ::ndk::ScopedAStatus::ok();
}
- status_t err = drm->closeSession(mSessionId);
+ status_t err = drm->closeSession(sessionId);
if (err != OK) {
*_aidl_return = false;
- return ::android::binder::Status::ok();
+ return ::ndk::ScopedAStatus::ok();
}
drm->sendEvent(EventType::SESSION_RECLAIMED,
- toHidlVec(mSessionId), hidl_vec<uint8_t>());
+ toHidlVec(sessionId), hidl_vec<uint8_t>());
*_aidl_return = true;
- return ::android::binder::Status::ok();
+ return ::ndk::ScopedAStatus::ok();
}
-::android::binder::Status DrmHal::DrmSessionClient::getName(::std::string* _aidl_return) {
+::ndk::ScopedAStatus DrmHal::DrmSessionClient::getName(::std::string* _aidl_return) {
String8 name;
sp<DrmHal> drm = mDrm.promote();
if (drm == NULL) {
@@ -349,7 +339,7 @@
}
name.append("]");
*_aidl_return = name;
- return ::android::binder::Status::ok();
+ return ::ndk::ScopedAStatus::ok();
}
DrmHal::DrmSessionClient::~DrmSessionClient() {
@@ -453,6 +443,7 @@
const uint8_t uuid[16], const String8& appPackageName) {
mAppPackageName = appPackageName;
mMetrics.SetAppPackageName(appPackageName);
+ mMetrics.SetAppUid(AIBinder_getCallingUid());
sp<IDrmPlugin> plugin;
Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
@@ -749,7 +740,7 @@
// reclaimSession may call back to closeSession, since mLock is
// shared between Drm instances, we should unlock here to avoid
// deadlock.
- retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
+ retry = DrmSessionManager::Instance()->reclaimSession(AIBinder_getCallingPid());
mLock.lock();
} else {
retry = false;
@@ -757,9 +748,10 @@
} while (retry);
if (err == OK) {
- sp<DrmSessionClient> client(new DrmSessionClient(this, sessionId));
- DrmSessionManager::Instance()->addSession(getCallingPid(), client, sessionId);
- mOpenSessions.push(client);
+ std::shared_ptr<DrmSessionClient> client(new DrmSessionClient(this, sessionId));
+ DrmSessionManager::Instance()->addSession(AIBinder_getCallingPid(),
+ std::static_pointer_cast<IResourceManagerClient>(client), sessionId);
+ mOpenSessions.push_back(client);
mMetrics.SetSessionStart(sessionId);
}
@@ -775,9 +767,9 @@
if (status.isOk()) {
if (status == Status::OK) {
DrmSessionManager::Instance()->removeSession(sessionId);
- for (size_t i = 0; i < mOpenSessions.size(); i++) {
- if (isEqualSessionId(mOpenSessions[i]->mSessionId, sessionId)) {
- mOpenSessions.removeAt(i);
+ for (auto i = mOpenSessions.begin(); i != mOpenSessions.end(); i++) {
+ if (isEqualSessionId((*i)->mSessionId, sessionId)) {
+ mOpenSessions.erase(i);
break;
}
}
@@ -1371,11 +1363,11 @@
return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
}
-status_t DrmHal::getMetrics(PersistableBundle* metrics) {
- if (metrics == nullptr) {
+status_t DrmHal::getMetrics(const sp<IDrmMetricsConsumer> &consumer) {
+ if (consumer == nullptr) {
return UNEXPECTED_NULL;
}
- mMetrics.Export(metrics);
+ consumer->consumeFrameworkMetrics(mMetrics);
// Append vendor metrics if they are supported.
if (mPluginV1_1 != NULL) {
@@ -1402,11 +1394,7 @@
if (status != Status::OK) {
ALOGV("Error getting plugin metrics: %d", status);
} else {
- PersistableBundle pluginBundle;
- if (MediaDrmMetrics::HidlMetricsToBundle(
- pluginMetrics, &pluginBundle) == OK) {
- metrics->putPersistableBundle(String16(vendor), pluginBundle);
- }
+ consumer->consumeHidlMetrics(vendor, pluginMetrics);
}
err = toStatusT(status);
});
@@ -1540,10 +1528,6 @@
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
- if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
- return -EPERM;
- }
-
DrmSessionManager::Instance()->useSession(sessionId);
status_t err = UNKNOWN_ERROR;
@@ -1563,21 +1547,21 @@
void DrmHal::reportFrameworkMetrics() const
{
- std::unique_ptr<MediaAnalyticsItem> item(MediaAnalyticsItem::create("mediadrm"));
- item->setPkgName(mMetrics.GetAppPackageName().c_str());
+ mediametrics_handle_t item(mediametrics_create("mediadrm"));
+ mediametrics_setUid(item, mMetrics.GetAppUid());
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());
+ mediametrics_setCString(item, "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());
+ mediametrics_setCString(item, "description", description.c_str());
}
std::string serializedMetrics;
@@ -1588,11 +1572,12 @@
std::string b64EncodedMetrics = toBase64StringNoPad(serializedMetrics.data(),
serializedMetrics.size());
if (!b64EncodedMetrics.empty()) {
- item->setCString("serialized_metrics", b64EncodedMetrics.c_str());
+ mediametrics_setCString(item, "serialized_metrics", b64EncodedMetrics.c_str());
}
- if (!item->selfrecord()) {
+ if (!mediametrics_selfRecord(item)) {
ALOGE("Failed to self record framework metrics");
}
+ mediametrics_delete(item);
}
void DrmHal::reportPluginMetrics() const
@@ -1606,7 +1591,7 @@
std::string metricsString = toBase64StringNoPad(metricsVector.array(),
metricsVector.size());
status_t res = android::reportDrmPluginMetrics(metricsString, vendor,
- description, mAppPackageName);
+ description, mMetrics.GetAppUid());
if (res != OK) {
ALOGE("Metrics were retrieved but could not be reported: %d", res);
}
diff --git a/drm/libmediadrm/DrmMetrics.cpp b/drm/libmediadrm/DrmMetrics.cpp
index 3080802..996fd19 100644
--- a/drm/libmediadrm/DrmMetrics.cpp
+++ b/drm/libmediadrm/DrmMetrics.cpp
@@ -29,143 +29,12 @@
using ::android::String16;
using ::android::String8;
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_2::KeyStatusType;
using ::android::hardware::drm::V1_1::DrmMetricGroup;
-using ::android::os::PersistableBundle;
namespace {
-template <typename T> std::string GetAttributeName(T type);
-
-template <> std::string GetAttributeName<KeyStatusType>(KeyStatusType type) {
- static const char *type_names[] = {"USABLE", "EXPIRED",
- "OUTPUT_NOT_ALLOWED", "STATUS_PENDING",
- "INTERNAL_ERROR"};
- if (((size_t)type) > arraysize(type_names)) {
- return "UNKNOWN_TYPE";
- }
- return type_names[(size_t)type];
-}
-
-template <> std::string GetAttributeName<EventType>(EventType type) {
- static const char *type_names[] = {"PROVISION_REQUIRED", "KEY_NEEDED",
- "KEY_EXPIRED", "VENDOR_DEFINED",
- "SESSION_RECLAIMED"};
- if (((size_t)type) > arraysize(type_names)) {
- return "UNKNOWN_TYPE";
- }
- return type_names[(size_t)type];
-}
-
-template <typename T>
-void ExportCounterMetric(const android::CounterMetric<T> &counter,
- PersistableBundle *metrics) {
- if (!metrics) {
- ALOGE("metrics was unexpectedly null.");
- return;
- }
- std::string success_count_name = counter.metric_name() + ".ok.count";
- std::string error_count_name = counter.metric_name() + ".error.count";
- std::vector<int64_t> status_values;
- counter.ExportValues(
- [&](const android::status_t status, const int64_t value) {
- if (status == android::OK) {
- metrics->putLong(android::String16(success_count_name.c_str()),
- value);
- } else {
- int64_t total_errors(0);
- metrics->getLong(android::String16(error_count_name.c_str()),
- &total_errors);
- metrics->putLong(android::String16(error_count_name.c_str()),
- total_errors + value);
- status_values.push_back(status);
- }
- });
- if (!status_values.empty()) {
- std::string error_list_name = counter.metric_name() + ".error.list";
- metrics->putLongVector(android::String16(error_list_name.c_str()),
- status_values);
- }
-}
-
-template <typename T>
-void ExportCounterMetricWithAttributeNames(
- const android::CounterMetric<T> &counter, PersistableBundle *metrics) {
- if (!metrics) {
- ALOGE("metrics was unexpectedly null.");
- return;
- }
- counter.ExportValues([&](const T &attribute, const int64_t value) {
- std::string name = counter.metric_name() + "." +
- GetAttributeName(attribute) + ".count";
- metrics->putLong(android::String16(name.c_str()), value);
- });
-}
-
-template <typename T>
-void ExportEventMetric(const android::EventMetric<T> &event,
- PersistableBundle *metrics) {
- if (!metrics) {
- ALOGE("metrics was unexpectedly null.");
- return;
- }
- std::string success_count_name = event.metric_name() + ".ok.count";
- std::string error_count_name = event.metric_name() + ".error.count";
- std::string timing_name = event.metric_name() + ".ok.average_time_micros";
- std::vector<int64_t> status_values;
- event.ExportValues([&](const android::status_t &status,
- const android::EventStatistics &value) {
- if (status == android::OK) {
- metrics->putLong(android::String16(success_count_name.c_str()),
- value.count);
- metrics->putLong(android::String16(timing_name.c_str()),
- value.mean);
- } else {
- int64_t total_errors(0);
- metrics->getLong(android::String16(error_count_name.c_str()),
- &total_errors);
- metrics->putLong(android::String16(error_count_name.c_str()),
- total_errors + value.count);
- status_values.push_back(status);
- }
- });
- if (!status_values.empty()) {
- std::string error_list_name = event.metric_name() + ".error.list";
- metrics->putLongVector(android::String16(error_list_name.c_str()),
- status_values);
- }
-}
-
-void ExportSessionLifespans(
- const std::map<std::string, std::pair<int64_t, int64_t>> &mSessionLifespans,
- PersistableBundle *metrics) {
- if (!metrics) {
- ALOGE("metrics was unexpectedly null.");
- return;
- }
-
- if (mSessionLifespans.empty()) {
- return;
- }
-
- PersistableBundle startTimesBundle;
- PersistableBundle endTimesBundle;
- for (auto it = mSessionLifespans.begin(); it != mSessionLifespans.end();
- it++) {
- String16 key(it->first.c_str(), it->first.size());
- startTimesBundle.putLong(key, it->second.first);
- endTimesBundle.putLong(key, it->second.second);
- }
- metrics->putPersistableBundle(
- android::String16("drm.mediadrm.session_start_times_ms"),
- startTimesBundle);
- metrics->putPersistableBundle(
- android::String16("drm.mediadrm.session_end_times_ms"), endTimesBundle);
-}
-
std::string ToHexString(const android::Vector<uint8_t> &sessionId) {
std::ostringstream out;
out << std::hex << std::setfill('0');
@@ -175,31 +44,6 @@
return out.str();
}
-template <typename CT>
-void SetValue(const String16 &name, DrmMetricGroup::ValueType type,
- const CT &value, PersistableBundle *bundle) {
- switch (type) {
- case DrmMetricGroup::ValueType::INT64_TYPE:
- bundle->putLong(name, value.int64Value);
- break;
- case DrmMetricGroup::ValueType::DOUBLE_TYPE:
- bundle->putDouble(name, value.doubleValue);
- break;
- case DrmMetricGroup::ValueType::STRING_TYPE:
- bundle->putString(name, String16(value.stringValue.c_str()));
- break;
- default:
- ALOGE("Unexpected value type: %hhu", type);
- }
-}
-
-inline String16 MakeIndexString(unsigned int index) {
- std::string str("[");
- str.append(std::to_string(index));
- str.append("]");
- return String16(str.c_str());
-}
-
} // namespace
namespace android {
@@ -237,23 +81,6 @@
}
}
-void MediaDrmMetrics::Export(PersistableBundle *metrics) {
- if (!metrics) {
- ALOGE("metrics was unexpectedly null.");
- return;
- }
- ExportCounterMetric(mOpenSessionCounter, metrics);
- ExportCounterMetric(mCloseSessionCounter, metrics);
- ExportEventMetric(mGetKeyRequestTimeUs, metrics);
- ExportEventMetric(mProvideKeyResponseTimeUs, metrics);
- ExportCounterMetric(mGetProvisionRequestCounter, metrics);
- ExportCounterMetric(mProvideProvisionResponseCounter, metrics);
- ExportCounterMetricWithAttributeNames(mKeyStatusChangeCounter, metrics);
- ExportCounterMetricWithAttributeNames(mEventCounter, metrics);
- ExportCounterMetric(mGetDeviceUniqueIdCounter, metrics);
- ExportSessionLifespans(mSessionLifespans, metrics);
-}
-
status_t MediaDrmMetrics::GetSerializedMetrics(std::string *serializedMetrics) {
if (!serializedMetrics) {
@@ -361,62 +188,14 @@
return OK;
}
+std::map<std::string, std::pair<int64_t, int64_t>> MediaDrmMetrics::GetSessionLifespans() const {
+ return mSessionLifespans;
+}
+
int64_t MediaDrmMetrics::GetCurrentTimeMs() {
struct timeval tv;
gettimeofday(&tv, NULL);
return ((int64_t)tv.tv_sec * 1000) + ((int64_t)tv.tv_usec / 1000);
}
-status_t MediaDrmMetrics::HidlMetricsToBundle(
- const hidl_vec<DrmMetricGroup> &hidlMetricGroups,
- PersistableBundle *bundleMetricGroups) {
- if (bundleMetricGroups == nullptr) {
- return UNEXPECTED_NULL;
- }
- if (hidlMetricGroups.size() == 0) {
- return OK;
- }
-
- int groupIndex = 0;
- std::map<String16, int> indexMap;
- for (const auto &hidlMetricGroup : hidlMetricGroups) {
- PersistableBundle bundleMetricGroup;
- for (const auto &hidlMetric : hidlMetricGroup.metrics) {
- String16 metricName(hidlMetric.name.c_str());
- PersistableBundle bundleMetric;
- // Add metric component values.
- for (const auto &value : hidlMetric.values) {
- SetValue(String16(value.componentName.c_str()), value.type,
- value, &bundleMetric);
- }
- // Set metric attributes.
- PersistableBundle bundleMetricAttributes;
- for (const auto &attribute : hidlMetric.attributes) {
- SetValue(String16(attribute.name.c_str()), attribute.type,
- attribute, &bundleMetricAttributes);
- }
- // Add attributes to the bundle metric.
- bundleMetric.putPersistableBundle(String16("attributes"),
- bundleMetricAttributes);
- // Add one layer of indirection, allowing for repeated metric names.
- PersistableBundle repeatedMetrics;
- bundleMetricGroup.getPersistableBundle(metricName,
- &repeatedMetrics);
- int index = indexMap[metricName];
- repeatedMetrics.putPersistableBundle(MakeIndexString(index),
- bundleMetric);
- indexMap[metricName] = ++index;
-
- // Add the bundle metric to the group of metrics.
- bundleMetricGroup.putPersistableBundle(metricName,
- repeatedMetrics);
- }
- // Add the bundle metric group to the collection of groups.
- bundleMetricGroups->putPersistableBundle(MakeIndexString(groupIndex++),
- bundleMetricGroup);
- }
-
- return OK;
-}
-
} // namespace android
diff --git a/drm/libmediadrm/DrmMetricsConsumer.cpp b/drm/libmediadrm/DrmMetricsConsumer.cpp
new file mode 100644
index 0000000..b47b4ff
--- /dev/null
+++ b/drm/libmediadrm/DrmMetricsConsumer.cpp
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+#define LOG_TAG "DrmMetricsConsumer"
+
+#include <android-base/macros.h>
+#include <mediadrm/DrmMetricsConsumer.h>
+#include <mediadrm/DrmMetrics.h>
+#include <utils/String8.h>
+#include <utils/String16.h>
+
+using ::android::String16;
+using ::android::String8;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::drm::V1_0::EventType;
+using ::android::hardware::drm::V1_2::KeyStatusType;
+using ::android::hardware::drm::V1_1::DrmMetricGroup;
+using ::android::os::PersistableBundle;
+
+namespace {
+
+template <typename T> std::string GetAttributeName(T type);
+
+template <> std::string GetAttributeName<KeyStatusType>(KeyStatusType type) {
+ static const char *type_names[] = {"USABLE", "EXPIRED",
+ "OUTPUT_NOT_ALLOWED", "STATUS_PENDING",
+ "INTERNAL_ERROR"};
+ if (((size_t)type) > arraysize(type_names)) {
+ return "UNKNOWN_TYPE";
+ }
+ return type_names[(size_t)type];
+}
+
+template <> std::string GetAttributeName<EventType>(EventType type) {
+ static const char *type_names[] = {"PROVISION_REQUIRED", "KEY_NEEDED",
+ "KEY_EXPIRED", "VENDOR_DEFINED",
+ "SESSION_RECLAIMED"};
+ if (((size_t)type) > arraysize(type_names)) {
+ return "UNKNOWN_TYPE";
+ }
+ return type_names[(size_t)type];
+}
+
+template <typename T>
+void ExportCounterMetric(const android::CounterMetric<T> &counter,
+ PersistableBundle *metrics) {
+ if (!metrics) {
+ ALOGE("metrics was unexpectedly null.");
+ return;
+ }
+ std::string success_count_name = counter.metric_name() + ".ok.count";
+ std::string error_count_name = counter.metric_name() + ".error.count";
+ std::vector<int64_t> status_values;
+ counter.ExportValues(
+ [&](const android::status_t status, const int64_t value) {
+ if (status == android::OK) {
+ metrics->putLong(android::String16(success_count_name.c_str()),
+ value);
+ } else {
+ int64_t total_errors(0);
+ metrics->getLong(android::String16(error_count_name.c_str()),
+ &total_errors);
+ metrics->putLong(android::String16(error_count_name.c_str()),
+ total_errors + value);
+ status_values.push_back(status);
+ }
+ });
+ if (!status_values.empty()) {
+ std::string error_list_name = counter.metric_name() + ".error.list";
+ metrics->putLongVector(android::String16(error_list_name.c_str()),
+ status_values);
+ }
+}
+
+template <typename T>
+void ExportCounterMetricWithAttributeNames(
+ const android::CounterMetric<T> &counter, PersistableBundle *metrics) {
+ if (!metrics) {
+ ALOGE("metrics was unexpectedly null.");
+ return;
+ }
+ counter.ExportValues([&](const T &attribute, const int64_t value) {
+ std::string name = counter.metric_name() + "." +
+ GetAttributeName(attribute) + ".count";
+ metrics->putLong(android::String16(name.c_str()), value);
+ });
+}
+
+template <typename T>
+void ExportEventMetric(const android::EventMetric<T> &event,
+ PersistableBundle *metrics) {
+ if (!metrics) {
+ ALOGE("metrics was unexpectedly null.");
+ return;
+ }
+ std::string success_count_name = event.metric_name() + ".ok.count";
+ std::string error_count_name = event.metric_name() + ".error.count";
+ std::string timing_name = event.metric_name() + ".ok.average_time_micros";
+ std::vector<int64_t> status_values;
+ event.ExportValues([&](const android::status_t &status,
+ const android::EventStatistics &value) {
+ if (status == android::OK) {
+ metrics->putLong(android::String16(success_count_name.c_str()),
+ value.count);
+ metrics->putLong(android::String16(timing_name.c_str()),
+ value.mean);
+ } else {
+ int64_t total_errors(0);
+ metrics->getLong(android::String16(error_count_name.c_str()),
+ &total_errors);
+ metrics->putLong(android::String16(error_count_name.c_str()),
+ total_errors + value.count);
+ status_values.push_back(status);
+ }
+ });
+ if (!status_values.empty()) {
+ std::string error_list_name = event.metric_name() + ".error.list";
+ metrics->putLongVector(android::String16(error_list_name.c_str()),
+ status_values);
+ }
+}
+
+void ExportSessionLifespans(
+ const std::map<std::string, std::pair<int64_t, int64_t>> &sessionLifespans,
+ PersistableBundle *metrics) {
+ if (!metrics) {
+ ALOGE("metrics was unexpectedly null.");
+ return;
+ }
+
+ if (sessionLifespans.empty()) {
+ return;
+ }
+
+ PersistableBundle startTimesBundle;
+ PersistableBundle endTimesBundle;
+ for (auto it = sessionLifespans.begin(); it != sessionLifespans.end();
+ it++) {
+ String16 key(it->first.c_str(), it->first.size());
+ startTimesBundle.putLong(key, it->second.first);
+ endTimesBundle.putLong(key, it->second.second);
+ }
+ metrics->putPersistableBundle(
+ android::String16("drm.mediadrm.session_start_times_ms"),
+ startTimesBundle);
+ metrics->putPersistableBundle(
+ android::String16("drm.mediadrm.session_end_times_ms"), endTimesBundle);
+}
+
+template <typename CT>
+void SetValue(const String16 &name, DrmMetricGroup::ValueType type,
+ const CT &value, PersistableBundle *bundle) {
+ switch (type) {
+ case DrmMetricGroup::ValueType::INT64_TYPE:
+ bundle->putLong(name, value.int64Value);
+ break;
+ case DrmMetricGroup::ValueType::DOUBLE_TYPE:
+ bundle->putDouble(name, value.doubleValue);
+ break;
+ case DrmMetricGroup::ValueType::STRING_TYPE:
+ bundle->putString(name, String16(value.stringValue.c_str()));
+ break;
+ default:
+ ALOGE("Unexpected value type: %hhu", type);
+ }
+}
+
+inline String16 MakeIndexString(unsigned int index) {
+ std::string str("[");
+ str.append(std::to_string(index));
+ str.append("]");
+ return String16(str.c_str());
+}
+
+} // namespace
+
+namespace android {
+
+status_t DrmMetricsConsumer::consumeFrameworkMetrics(const MediaDrmMetrics &metrics) {
+ ExportCounterMetric(metrics.mOpenSessionCounter, mBundle);
+ ExportCounterMetric(metrics.mCloseSessionCounter, mBundle);
+ ExportEventMetric(metrics.mGetKeyRequestTimeUs, mBundle);
+ ExportEventMetric(metrics.mProvideKeyResponseTimeUs, mBundle);
+ ExportCounterMetric(metrics.mGetProvisionRequestCounter, mBundle);
+ ExportCounterMetric(metrics.mProvideProvisionResponseCounter, mBundle);
+ ExportCounterMetricWithAttributeNames(metrics.mKeyStatusChangeCounter, mBundle);
+ ExportCounterMetricWithAttributeNames(metrics.mEventCounter, mBundle);
+ ExportCounterMetric(metrics.mGetDeviceUniqueIdCounter, mBundle);
+ ExportSessionLifespans(metrics.GetSessionLifespans(), mBundle);
+ return android::OK;
+}
+
+status_t DrmMetricsConsumer::consumeHidlMetrics(
+ const String8 &vendor,
+ const hidl_vec<DrmMetricGroup> &pluginMetrics) {
+ PersistableBundle pluginBundle;
+ if (DrmMetricsConsumer::HidlMetricsToBundle(
+ pluginMetrics, &pluginBundle) == OK) {
+ mBundle->putPersistableBundle(String16(vendor), pluginBundle);
+ }
+ return android::OK;
+}
+
+status_t DrmMetricsConsumer::HidlMetricsToBundle(
+ const hidl_vec<DrmMetricGroup> &hidlMetricGroups,
+ PersistableBundle *bundleMetricGroups) {
+ if (bundleMetricGroups == nullptr) {
+ return UNEXPECTED_NULL;
+ }
+ if (hidlMetricGroups.size() == 0) {
+ return OK;
+ }
+
+ int groupIndex = 0;
+ std::map<String16, int> indexMap;
+ for (const auto &hidlMetricGroup : hidlMetricGroups) {
+ PersistableBundle bundleMetricGroup;
+ for (const auto &hidlMetric : hidlMetricGroup.metrics) {
+ String16 metricName(hidlMetric.name.c_str());
+ PersistableBundle bundleMetric;
+ // Add metric component values.
+ for (const auto &value : hidlMetric.values) {
+ SetValue(String16(value.componentName.c_str()), value.type,
+ value, &bundleMetric);
+ }
+ // Set metric attributes.
+ PersistableBundle bundleMetricAttributes;
+ for (const auto &attribute : hidlMetric.attributes) {
+ SetValue(String16(attribute.name.c_str()), attribute.type,
+ attribute, &bundleMetricAttributes);
+ }
+ // Add attributes to the bundle metric.
+ bundleMetric.putPersistableBundle(String16("attributes"),
+ bundleMetricAttributes);
+ // Add one layer of indirection, allowing for repeated metric names.
+ PersistableBundle repeatedMetrics;
+ bundleMetricGroup.getPersistableBundle(metricName,
+ &repeatedMetrics);
+ int index = indexMap[metricName];
+ repeatedMetrics.putPersistableBundle(MakeIndexString(index),
+ bundleMetric);
+ indexMap[metricName] = ++index;
+
+ // Add the bundle metric to the group of metrics.
+ bundleMetricGroup.putPersistableBundle(metricName,
+ repeatedMetrics);
+ }
+ // Add the bundle metric group to the collection of groups.
+ bundleMetricGroups->putPersistableBundle(MakeIndexString(groupIndex++),
+ bundleMetricGroup);
+ }
+
+ return OK;
+}
+
+} // namespace android
+
diff --git a/drm/libmediadrm/DrmSessionManager.cpp b/drm/libmediadrm/DrmSessionManager.cpp
index 165a4d6..7a4e1ae 100644
--- a/drm/libmediadrm/DrmSessionManager.cpp
+++ b/drm/libmediadrm/DrmSessionManager.cpp
@@ -18,13 +18,12 @@
#define LOG_TAG "DrmSessionManager"
#include <utils/Log.h>
-#include <android/media/IResourceManagerClient.h>
-#include <android/media/IResourceManagerService.h>
-#include <binder/IPCThreadState.h>
-#include <binder/IProcessInfoService.h>
-#include <binder/IServiceManager.h>
+#include <aidl/android/media/IResourceManagerClient.h>
+#include <aidl/android/media/IResourceManagerService.h>
+#include <aidl/android/media/MediaResourceParcel.h>
+#include <android/binder_ibinder.h>
+#include <android/binder_manager.h>
#include <cutils/properties.h>
-#include <media/MediaResource.h>
#include <mediadrm/DrmUtils.h>
#include <mediadrm/DrmSessionManager.h>
#include <unistd.h>
@@ -32,10 +31,18 @@
#include <vector>
-#include "ResourceManagerService.h"
-
namespace android {
-using android::binder::Status;
+
+using aidl::android::media::MediaResourceParcel;
+
+namespace {
+void ResourceManagerServiceDied(void* cookie) {
+ auto thiz = static_cast<DrmSessionManager*>(cookie);
+ thiz->binderDied();
+}
+}
+
+using ::ndk::ScopedAStatus;
static String8 GetSessionIdString(const Vector<uint8_t> &sessionId) {
String8 sessionIdStr;
@@ -45,34 +52,28 @@
return sessionIdStr;
}
-static std::vector<uint8_t> toStdVec(const Vector<uint8_t> &vector) {
- const uint8_t *v = vector.array();
- std::vector<uint8_t> vec(v, v + vector.size());
+template <typename Byte = uint8_t>
+static std::vector<Byte> toStdVec(const Vector<uint8_t> &vector) {
+ auto v = reinterpret_cast<const Byte *>(vector.array());
+ std::vector<Byte> vec(v, v + vector.size());
return vec;
}
-static uint64_t toClientId(const sp<IResourceManagerClient>& drm) {
- return reinterpret_cast<int64_t>(drm.get());
-}
-
static std::vector<MediaResourceParcel> toResourceVec(
const Vector<uint8_t> &sessionId, int64_t value) {
+ using Type = aidl::android::media::MediaResourceType;
+ using SubType = aidl::android::media::MediaResourceSubType;
std::vector<MediaResourceParcel> resources;
- resources.push_back(MediaResource::DrmSessionResource(toStdVec(sessionId), value));
+ MediaResourceParcel resource{
+ Type::kDrmSession, SubType::kUnspecifiedSubType,
+ toStdVec<int8_t>(sessionId), value};
+ resources.push_back(resource);
return resources;
}
-static sp<IResourceManagerService> getResourceManagerService() {
- if (DrmUtils::UseDrmService()) {
- // Create ResourceManagerService object in mediadrmserver process
- return new android::media::ResourceManagerService();
- }
- sp<IServiceManager> sm = defaultServiceManager();
- if (sm == NULL) {
- return NULL;
- }
- sp<IBinder> binder = sm->getService(String16("media.resource_manager"));
- return interface_cast<IResourceManagerService>(binder);
+static std::shared_ptr<IResourceManagerService> getResourceManagerService() {
+ ::ndk::SpAIBinder binder(AServiceManager_getService("media.resource_manager"));
+ return IResourceManagerService::fromBinder(binder);
}
bool isEqualSessionId(const Vector<uint8_t> &sessionId1, const Vector<uint8_t> &sessionId2) {
@@ -88,7 +89,7 @@
}
sp<DrmSessionManager> DrmSessionManager::Instance() {
- static sp<DrmSessionManager> drmSessionManager = new DrmSessionManager();
+ auto drmSessionManager = new DrmSessionManager();
drmSessionManager->init();
return drmSessionManager;
}
@@ -97,9 +98,10 @@
: DrmSessionManager(getResourceManagerService()) {
}
-DrmSessionManager::DrmSessionManager(const sp<IResourceManagerService> &service)
+DrmSessionManager::DrmSessionManager(const std::shared_ptr<IResourceManagerService> &service)
: mService(service),
- mInitialized(false) {
+ mInitialized(false),
+ mDeathRecipient(AIBinder_DeathRecipient_new(ResourceManagerServiceDied)) {
if (mService == NULL) {
ALOGE("Failed to init ResourceManagerService");
}
@@ -107,7 +109,7 @@
DrmSessionManager::~DrmSessionManager() {
if (mService != NULL) {
- IInterface::asBinder(mService)->unlinkToDeath(this);
+ AIBinder_unlinkToDeath(mService->asBinder().get(), mDeathRecipient.get(), this);
}
}
@@ -118,13 +120,13 @@
}
mInitialized = true;
if (mService != NULL) {
- IInterface::asBinder(mService)->linkToDeath(this);
+ AIBinder_linkToDeath(mService->asBinder().get(), mDeathRecipient.get(), this);
}
}
void DrmSessionManager::addSession(int pid,
- const sp<IResourceManagerClient>& drm, const Vector<uint8_t> &sessionId) {
- uid_t uid = IPCThreadState::self()->getCallingUid();
+ const std::shared_ptr<IResourceManagerClient>& drm, const Vector<uint8_t> &sessionId) {
+ uid_t uid = AIBinder_getCallingUid();
ALOGV("addSession(pid %d, uid %d, drm %p, sessionId %s)", pid, uid, drm.get(),
GetSessionIdString(sessionId).string());
@@ -133,9 +135,9 @@
return;
}
- int64_t clientId = toClientId(drm);
+ static int64_t clientId = 0;
mSessionMap[toStdVec(sessionId)] = (SessionInfo){pid, uid, clientId};
- mService->addResource(pid, uid, clientId, drm, toResourceVec(sessionId, INT64_MAX));
+ mService->addResource(pid, uid, clientId++, drm, toResourceVec(sessionId, INT64_MAX));
}
void DrmSessionManager::useSession(const Vector<uint8_t> &sessionId) {
@@ -170,7 +172,7 @@
// unlock early because reclaimResource might callback into removeSession
mLock.lock();
- sp<IResourceManagerService> service(mService);
+ std::shared_ptr<IResourceManagerService> service(mService);
mLock.unlock();
if (service == NULL) {
@@ -181,7 +183,7 @@
// we rely on IResourceManagerClient to removeSession in reclaimResource
Vector<uint8_t> dummy;
bool success;
- Status status = service->reclaimResource(callingPid, toResourceVec(dummy, INT64_MAX), &success);
+ ScopedAStatus status = service->reclaimResource(callingPid, toResourceVec(dummy, INT64_MAX), &success);
return status.isOk() && success;
}
@@ -195,10 +197,10 @@
return mSessionMap.count(toStdVec(sessionId));
}
-void DrmSessionManager::binderDied(const wp<IBinder>& /*who*/) {
+void DrmSessionManager::binderDied() {
ALOGW("ResourceManagerService died.");
Mutex::Autolock lock(mLock);
- mService.clear();
+ mService.reset();
}
} // namespace android
diff --git a/drm/libmediadrm/IMediaDrmService.cpp b/drm/libmediadrm/IMediaDrmService.cpp
deleted file mode 100644
index db67c23..0000000
--- a/drm/libmediadrm/IMediaDrmService.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
-**
-** Copyright 2015, 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 <stdint.h>
-#include <sys/types.h>
-
-#include <binder/Parcel.h>
-#include <binder/IMemory.h>
-#include <mediadrm/ICrypto.h>
-#include <mediadrm/IDrm.h>
-#include <mediadrm/IMediaDrmService.h>
-
-#include <utils/Errors.h> // for status_t
-#include <utils/String8.h>
-
-namespace android {
-
-class BpMediaDrmService: public BpInterface<IMediaDrmService>
-{
-public:
- explicit BpMediaDrmService(const sp<IBinder>& impl)
- : BpInterface<IMediaDrmService>(impl)
- {
- }
-
-};
-
-IMPLEMENT_META_INTERFACE(MediaDrmService, "android.media.IMediaDrmService");
-
-// ----------------------------------------------------------------------
-
-status_t BnMediaDrmService::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- switch (code) {
- default:
- return BBinder::onTransact(code, data, reply, flags);
- }
-}
-
-// ----------------------------------------------------------------------------
-
-} // namespace android
diff --git a/drm/libmediadrm/PluginMetricsReporting.cpp b/drm/libmediadrm/PluginMetricsReporting.cpp
index 098f07b..b0abf83 100644
--- a/drm/libmediadrm/PluginMetricsReporting.cpp
+++ b/drm/libmediadrm/PluginMetricsReporting.cpp
@@ -21,7 +21,7 @@
#include <inttypes.h>
-#include <media/MediaAnalyticsItem.h>
+#include <media/MediaMetrics.h>
#include <utils/Log.h>
@@ -33,18 +33,18 @@
status_t reportVendorMetrics(const std::string& metrics,
const String8& name,
- const String8& appPackageName) {
- std::unique_ptr<MediaAnalyticsItem> analyticsItem(MediaAnalyticsItem::create(name.c_str()));
- std::string app_package_name(appPackageName.c_str(), appPackageName.size());
- analyticsItem->setPkgName(app_package_name);
+ uid_t appUid) {
+ mediametrics_handle_t analyticsItem(mediametrics_create(name.c_str()));
+ mediametrics_setUid(analyticsItem, appUid);
if (metrics.size() > 0) {
- analyticsItem->setCString(kSerializedMetricsField, metrics.c_str());
+ mediametrics_setCString(analyticsItem, kSerializedMetricsField, metrics.c_str());
}
- if (!analyticsItem->selfrecord()) {
+ if (!mediametrics_selfRecord(analyticsItem)) {
ALOGE("%s: selfrecord() returned false", __func__);
}
+ mediametrics_delete(analyticsItem);
return OK;
}
@@ -67,13 +67,13 @@
status_t reportDrmPluginMetrics(const std::string& b64EncodedMetrics,
const String8& vendor,
const String8& description,
- const String8& appPackageName) {
+ uid_t appUid) {
String8 name = String8::format("drm.vendor.%s.%s",
sanitize(vendor).c_str(),
sanitize(description).c_str());
- return reportVendorMetrics(b64EncodedMetrics, name, appPackageName);
+ return reportVendorMetrics(b64EncodedMetrics, name, appUid);
}
} // namespace android
diff --git a/drm/libmediadrm/include/mediadrm/CryptoHal.h b/drm/libmediadrm/include/mediadrm/CryptoHal.h
index 865ca38..c9fda67 100644
--- a/drm/libmediadrm/include/mediadrm/CryptoHal.h
+++ b/drm/libmediadrm/include/mediadrm/CryptoHal.h
@@ -31,6 +31,9 @@
using drm::V1_0::ICryptoFactory;
using drm::V1_0::ICryptoPlugin;
using drm::V1_0::SharedBuffer;
+using drm::V1_0::DestinationBuffer;
+
+using ::android::hardware::HidlMemory;
class IMemoryHeap;
@@ -58,12 +61,12 @@
virtual ssize_t decrypt(const uint8_t key[16], const uint8_t iv[16],
CryptoPlugin::Mode mode, const CryptoPlugin::Pattern &pattern,
- const ICrypto::SourceBuffer &source, size_t offset,
+ const ::SharedBuffer &source, size_t offset,
const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
- const ICrypto::DestinationBuffer &destination,
+ const ::DestinationBuffer &destination,
AString *errorDetailMsg);
- virtual int32_t setHeap(const sp<IMemoryHeap>& heap) {
+ virtual int32_t setHeap(const sp<HidlMemory>& heap) {
return setHeapBase(heap);
}
virtual void unsetHeap(int32_t seqNum) { clearHeapBase(seqNum); }
@@ -83,30 +86,17 @@
*/
status_t mInitCheck;
- struct HeapBase {
- HeapBase() : mBufferId(0), mSize(0) {}
- HeapBase(uint32_t bufferId, size_t size) :
- mBufferId(bufferId), mSize(size) {}
-
- uint32_t getBufferId() const {return mBufferId;}
- size_t getSize() const {return mSize;}
-
- private:
- uint32_t mBufferId;
- size_t mSize;
- };
-
- KeyedVector<int32_t, HeapBase> mHeapBases;
+ KeyedVector<int32_t, size_t> mHeapSizes;
int32_t mHeapSeqNum;
Vector<sp<ICryptoFactory>> makeCryptoFactories();
sp<ICryptoPlugin> makeCryptoPlugin(const sp<ICryptoFactory>& factory,
const uint8_t uuid[16], const void *initData, size_t size);
- int32_t setHeapBase(const sp<IMemoryHeap>& heap);
+ int32_t setHeapBase(const sp<HidlMemory>& heap);
void clearHeapBase(int32_t seqNum);
- status_t toSharedBuffer(const sp<IMemory>& memory, int32_t seqNum, ::SharedBuffer* buffer);
+ status_t checkSharedBuffer(const ::SharedBuffer& buffer);
DISALLOW_EVIL_CONSTRUCTORS(CryptoHal);
};
diff --git a/drm/libmediadrm/include/mediadrm/DrmHal.h b/drm/libmediadrm/include/mediadrm/DrmHal.h
index 97dd920..6818dd7 100644
--- a/drm/libmediadrm/include/mediadrm/DrmHal.h
+++ b/drm/libmediadrm/include/mediadrm/DrmHal.h
@@ -26,11 +26,11 @@
#include <android/hardware/drm/1.2/IDrmPlugin.h>
#include <android/hardware/drm/1.2/IDrmPluginListener.h>
-#include <media/MediaAnalyticsItem.h>
#include <mediadrm/DrmMetrics.h>
#include <mediadrm/DrmSessionManager.h>
#include <mediadrm/IDrm.h>
#include <mediadrm/IDrmClient.h>
+#include <mediadrm/IDrmMetricsConsumer.h>
#include <utils/threads.h>
namespace drm = ::android::hardware::drm;
@@ -137,7 +137,7 @@
virtual status_t setPropertyString(String8 const &name, String8 const &value ) const;
virtual status_t setPropertyByteArray(String8 const &name,
Vector<uint8_t> const &value ) const;
- virtual status_t getMetrics(os::PersistableBundle *metrics);
+ virtual status_t getMetrics(const sp<IDrmMetricsConsumer> &consumer);
virtual status_t setCipherAlgorithm(Vector<uint8_t> const &sessionId,
String8 const &algorithm);
@@ -207,7 +207,7 @@
// Mutable to allow modification within GetPropertyByteArray.
mutable MediaDrmMetrics mMetrics;
- Vector<sp<DrmSessionClient>> mOpenSessions;
+ std::vector<std::shared_ptr<DrmSessionClient>> mOpenSessions;
void closeOpenSessions();
void cleanup();
diff --git a/drm/libmediadrm/include/mediadrm/DrmMetrics.h b/drm/libmediadrm/include/mediadrm/DrmMetrics.h
index 6f132bf..100b8f7 100644
--- a/drm/libmediadrm/include/mediadrm/DrmMetrics.h
+++ b/drm/libmediadrm/include/mediadrm/DrmMetrics.h
@@ -25,6 +25,7 @@
#include <binder/PersistableBundle.h>
#include <media/CounterMetric.h>
#include <media/EventMetric.h>
+#include <sys/types.h>
namespace android {
@@ -71,8 +72,8 @@
void SetAppPackageName(const String8& appPackageName) { mAppPackageName = appPackageName; }
const String8& GetAppPackageName() { return mAppPackageName; }
- // Export the metrics to a PersistableBundle.
- void Export(os::PersistableBundle* metricsBundle);
+ void SetAppUid(uid_t appUid) { mAppUid = appUid; }
+ uid_t GetAppUid() const { return mAppUid; }
// Get the serialized metrics. Metrics are formatted as a serialized
// DrmFrameworkMetrics proto. If there is a failure serializing the metrics,
@@ -80,46 +81,8 @@
// caller and must not be null.
status_t GetSerializedMetrics(std::string* serializedMetrics);
- // Converts the DRM plugin metrics to a PersistableBundle. All of the metrics
- // found in |pluginMetrics| are added to the |metricsBundle| parameter.
- // |pluginBundle| is owned by the caller and must not be null.
- //
- // Each item in the pluginMetrics vector is added as a new PersistableBundle. E.g.
- // DrmMetricGroup {
- // metrics[0] {
- // name: "buf_copy"
- // attributes[0] {
- // name: "size"
- // type: INT64_TYPE
- // int64Value: 1024
- // }
- // values[0] {
- // componentName: "operation_count"
- // type: INT64_TYPE
- // int64Value: 75
- // }
- // values[1] {
- // component_name: "average_time_seconds"
- // type: DOUBLE_TYPE
- // doubleValue: 0.00000042
- // }
- // }
- // }
- //
- // becomes
- //
- // metricsBundle {
- // "0": (PersistableBundle) {
- // "attributes" : (PersistableBundle) {
- // "size" : (int64) 1024
- // }
- // "operation_count" : (int64) 75
- // "average_time_seconds" : (double) 0.00000042
- // }
- //
- static status_t HidlMetricsToBundle(
- const hardware::hidl_vec<hardware::drm::V1_1::DrmMetricGroup>& pluginMetrics,
- os::PersistableBundle* metricsBundle);
+ // Get copy of session lifetimes.
+ std::map<std::string, std::pair<int64_t, int64_t>> GetSessionLifespans() const;
protected:
// This is visible for testing only.
@@ -131,6 +94,7 @@
std::map<std::string, std::pair<int64_t, int64_t>> mSessionLifespans;
String8 mAppPackageName;
+ uid_t mAppUid{~0u};
};
} // namespace android
diff --git a/drm/libmediadrm/include/mediadrm/DrmMetricsConsumer.h b/drm/libmediadrm/include/mediadrm/DrmMetricsConsumer.h
new file mode 100644
index 0000000..bbbf4b5
--- /dev/null
+++ b/drm/libmediadrm/include/mediadrm/DrmMetricsConsumer.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 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 <binder/PersistableBundle.h>
+#include <mediadrm/IDrmMetricsConsumer.h>
+#include <utils/Errors.h>
+
+#ifndef ANDROID_METRICSCONSUMER_H_
+
+#define ANDROID_METRICSCONSUMER_H_
+
+namespace android {
+
+/**
+ * IDrmMetricsConsumer which saves IDrm/ICrypto metrics into a PersistableBundle.
+ *
+ * Example usage:
+ *
+ * PersistableBundle bundle;
+ * DrmMetricsConsumer consumer(&bundle);
+ * drm->exportMetrics(&consumer);
+ * crypto->exportMetrics(&consumer);
+ * // bundle now contains metrics from drm/crypto.
+ *
+ */
+struct DrmMetricsConsumer : public IDrmMetricsConsumer {
+ DrmMetricsConsumer(os::PersistableBundle *bundle) : mBundle(bundle) {}
+
+ status_t consumeFrameworkMetrics(const MediaDrmMetrics &) override;
+
+ status_t consumeHidlMetrics(
+ const String8 &/*vendor*/,
+ const hidl_vec<DrmMetricGroup> &/*pluginMetrics*/) override;
+
+ // Converts the DRM plugin metrics to a PersistableBundle. All of the metrics
+ // found in |pluginMetrics| are added to the |metricsBundle| parameter.
+ // |pluginBundle| is owned by the caller and must not be null.
+ //
+ // Each item in the pluginMetrics vector is added as a new PersistableBundle. E.g.
+ // DrmMetricGroup {
+ // metrics[0] {
+ // name: "buf_copy"
+ // attributes[0] {
+ // name: "size"
+ // type: INT64_TYPE
+ // int64Value: 1024
+ // }
+ // values[0] {
+ // componentName: "operation_count"
+ // type: INT64_TYPE
+ // int64Value: 75
+ // }
+ // values[1] {
+ // component_name: "average_time_seconds"
+ // type: DOUBLE_TYPE
+ // doubleValue: 0.00000042
+ // }
+ // }
+ // }
+ //
+ // becomes
+ //
+ // metricsBundle {
+ // "0": (PersistableBundle) {
+ // "attributes" : (PersistableBundle) {
+ // "size" : (int64) 1024
+ // }
+ // "operation_count" : (int64) 75
+ // "average_time_seconds" : (double) 0.00000042
+ // }
+ //
+ static status_t HidlMetricsToBundle(
+ const hardware::hidl_vec<hardware::drm::V1_1::DrmMetricGroup>& pluginMetrics,
+ os::PersistableBundle* metricsBundle);
+
+private:
+ os::PersistableBundle *mBundle;
+ DISALLOW_EVIL_CONSTRUCTORS(DrmMetricsConsumer);
+};
+
+} // namespace android
+
+#endif // ANDROID_METRICSCONSUMER_H_
diff --git a/drm/libmediadrm/include/mediadrm/DrmSessionManager.h b/drm/libmediadrm/include/mediadrm/DrmSessionManager.h
index 3258f7a..9e43504 100644
--- a/drm/libmediadrm/include/mediadrm/DrmSessionManager.h
+++ b/drm/libmediadrm/include/mediadrm/DrmSessionManager.h
@@ -18,7 +18,9 @@
#define DRM_SESSION_MANAGER_H_
-#include <binder/IBinder.h>
+#include <aidl/android/media/IResourceManagerClient.h>
+#include <aidl/android/media/IResourceManagerService.h>
+#include <android/binder_auto_utils.h>
#include <media/stagefright/foundation/ABase.h>
#include <utils/RefBase.h>
#include <utils/KeyedVector.h>
@@ -26,6 +28,7 @@
#include <utils/Vector.h>
#include <map>
+#include <memory>
#include <utility>
#include <vector>
@@ -33,12 +36,8 @@
class DrmSessionManagerTest;
-namespace media {
-class IResourceManagerClient;
-class IResourceManagerService;
-}
-using android::media::IResourceManagerClient;
-using android::media::IResourceManagerService;
+using aidl::android::media::IResourceManagerClient;
+using aidl::android::media::IResourceManagerService;
bool isEqualSessionId(const Vector<uint8_t> &sessionId1, const Vector<uint8_t> &sessionId2);
@@ -50,13 +49,15 @@
typedef std::map<std::vector<uint8_t>, SessionInfo> SessionInfoMap;
-struct DrmSessionManager : public IBinder::DeathRecipient {
+struct DrmSessionManager : public RefBase {
static sp<DrmSessionManager> Instance();
DrmSessionManager();
- explicit DrmSessionManager(const sp<IResourceManagerService> &service);
+ explicit DrmSessionManager(const std::shared_ptr<IResourceManagerService> &service);
- void addSession(int pid, const sp<IResourceManagerClient>& drm, const Vector<uint8_t>& sessionId);
+ void addSession(int pid,
+ const std::shared_ptr<IResourceManagerClient>& drm,
+ const Vector<uint8_t>& sessionId);
void useSession(const Vector<uint8_t>& sessionId);
void removeSession(const Vector<uint8_t>& sessionId);
bool reclaimSession(int callingPid);
@@ -66,7 +67,7 @@
bool containsSession(const Vector<uint8_t>& sessionId) const;
// implements DeathRecipient
- virtual void binderDied(const wp<IBinder>& /*who*/);
+ void binderDied();
protected:
virtual ~DrmSessionManager();
@@ -74,10 +75,11 @@
private:
void init();
- sp<IResourceManagerService> mService;
+ std::shared_ptr<IResourceManagerService> mService;
mutable Mutex mLock;
SessionInfoMap mSessionMap;
bool mInitialized;
+ ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
DISALLOW_EVIL_CONSTRUCTORS(DrmSessionManager);
};
diff --git a/drm/libmediadrm/include/mediadrm/IDrm.h b/drm/libmediadrm/include/mediadrm/IDrm.h
index db79008..48a7170 100644
--- a/drm/libmediadrm/include/mediadrm/IDrm.h
+++ b/drm/libmediadrm/include/mediadrm/IDrm.h
@@ -18,8 +18,8 @@
#include <binder/PersistableBundle.h>
#include <media/stagefright/foundation/ABase.h>
#include <media/drm/DrmAPI.h>
-#include <media/MediaAnalyticsItem.h>
#include <mediadrm/IDrmClient.h>
+#include <mediadrm/IDrmMetricsConsumer.h>
#ifndef ANDROID_IDRM_H_
@@ -108,7 +108,7 @@
virtual status_t setPropertyByteArray(String8 const &name,
Vector<uint8_t> const &value) const = 0;
- virtual status_t getMetrics(os::PersistableBundle *metrics) = 0;
+ virtual status_t getMetrics(const sp<IDrmMetricsConsumer> &consumer) = 0;
virtual status_t setCipherAlgorithm(Vector<uint8_t> const &sessionId,
String8 const &algorithm) = 0;
diff --git a/drm/libmediadrm/include/mediadrm/IDrmMetricsConsumer.h b/drm/libmediadrm/include/mediadrm/IDrmMetricsConsumer.h
new file mode 100644
index 0000000..aef35c3
--- /dev/null
+++ b/drm/libmediadrm/include/mediadrm/IDrmMetricsConsumer.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 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 <android/hardware/drm/1.1/types.h>
+#include <hidl/HidlSupport.h>
+#include <media/stagefright/foundation/ABase.h>
+
+#ifndef ANDROID_IDRMMETRICSCONSUMER_H_
+
+#define ANDROID_IDRMMETRICSCONSUMER_H_
+
+using ::android::hardware::hidl_vec;
+using ::android::hardware::drm::V1_1::DrmMetricGroup;
+
+namespace android {
+
+class MediaDrmMetrics;
+class String8;
+
+/**
+ * Interface to consume metrics produced by the IDrm/ICrypto
+ *
+ * To use with IDrm:
+ * drm->exportMetrics(&consumer);
+ *
+ * IDrmMetricsConsumer::consumeFrameworkMetrics &
+ * IDrmMetricsConsumer::consumeHidlMetrics implementations
+ * would each be invoked once per call to IDrm::exportMetrics.
+ * |consumeFrameworkMetrics| would be called for plugin-agnostic
+ * framework metrics; |consumeHidlMetrics| would be called for
+ * plugin specific metrics.
+ *
+ * ----------------------------------------
+ *
+ * To use with ICrypto:
+ * crypto->exportMetrics(&consumer);
+ *
+ * IDrmMetricsConsumer::consumeHidlMetrics implementation
+ * would each be invoked once per call to ICrypto::exportMetrics.
+ * ICrypto metrics are plugin agnostic.
+ *
+ * ----------------------------------------
+ *
+ * For an example implementation of IDrmMetricsConsumer, please
+ * see DrmMetricsConsumer. DrmMetricsConsumer consumes IDrm/ICrypto
+ * metrics and saves the metrics to a PersistableBundle.
+ *
+ */
+struct IDrmMetricsConsumer : public RefBase {
+
+ virtual ~IDrmMetricsConsumer() {}
+
+ /**
+ * Consume framework (plugin agnostic) MediaDrmMetrics
+ */
+ virtual status_t consumeFrameworkMetrics(const MediaDrmMetrics &) = 0;
+
+ /**
+ * Consume list of DrmMetricGroup with optional Drm vendor name
+ */
+ virtual status_t consumeHidlMetrics(
+ const String8 &vendor,
+ const hidl_vec<DrmMetricGroup> &pluginMetrics) = 0;
+
+protected:
+ IDrmMetricsConsumer() {}
+
+private:
+ DISALLOW_EVIL_CONSTRUCTORS(IDrmMetricsConsumer);
+};
+
+} // namespace android
+
+#endif // ANDROID_IDRMMETRICSCONSUMER_H_
diff --git a/drm/libmediadrm/include/mediadrm/IMediaDrmService.h b/drm/libmediadrm/include/mediadrm/IMediaDrmService.h
deleted file mode 100644
index 715e0e4..0000000
--- a/drm/libmediadrm/include/mediadrm/IMediaDrmService.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2015 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.
- */
-
-#ifndef ANDROID_IMEDIADRMSERVICE_H
-#define ANDROID_IMEDIADRMSERVICE_H
-
-#include <utils/Errors.h> // for status_t
-#include <utils/RefBase.h>
-#include <utils/String8.h>
-#include <binder/IInterface.h>
-#include <binder/Parcel.h>
-
-namespace android {
-
-struct IDrm;
-
-class IMediaDrmService: public IInterface
-{
-public:
- DECLARE_META_INTERFACE(MediaDrmService);
-
-};
-
-// ----------------------------------------------------------------------------
-
-class BnMediaDrmService: public BnInterface<IMediaDrmService>
-{
-public:
- virtual status_t onTransact( uint32_t code,
- const Parcel& data,
- Parcel* reply,
- uint32_t flags = 0);
-};
-
-}; // namespace android
-
-#endif // ANDROID_IMEDIADRMSERVICE_H
diff --git a/drm/libmediadrm/interface/mediadrm/ICrypto.h b/drm/libmediadrm/interface/mediadrm/ICrypto.h
index 48a0c44..df980ae 100644
--- a/drm/libmediadrm/interface/mediadrm/ICrypto.h
+++ b/drm/libmediadrm/interface/mediadrm/ICrypto.h
@@ -25,10 +25,23 @@
#define ANDROID_ICRYPTO_H_
namespace android {
+namespace hardware {
+class HidlMemory;
+namespace drm {
+namespace V1_0 {
+struct SharedBuffer;
+struct DestinationBuffer;
+} // namespace V1_0
+} // namespace drm
+} // namespace hardware
+} // namespace android
+
+namespace drm = ::android::hardware::drm;
+using drm::V1_0::SharedBuffer;
+
+namespace android {
struct AString;
-class IMemory;
-class IMemoryHeap;
struct ICrypto : public RefBase {
@@ -50,27 +63,16 @@
virtual status_t setMediaDrmSession(const Vector<uint8_t> &sessionId) = 0;
- struct SourceBuffer {
- sp<IMemory> mSharedMemory;
- int32_t mHeapSeqNum;
- };
-
enum DestinationType {
kDestinationTypeSharedMemory, // non-secure
kDestinationTypeNativeHandle // secure
};
- struct DestinationBuffer {
- DestinationType mType;
- native_handle_t *mHandle;
- sp<IMemory> mSharedMemory;
- };
-
- virtual ssize_t decrypt(const uint8_t key[16], const uint8_t iv[16],
- CryptoPlugin::Mode mode, const CryptoPlugin::Pattern &pattern,
- const SourceBuffer &source, size_t offset,
- const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
- const DestinationBuffer &destination, AString *errorDetailMsg) = 0;
+ virtual ssize_t decrypt(const uint8_t /*key*/[16], const uint8_t /*iv*/[16],
+ CryptoPlugin::Mode /*mode*/, const CryptoPlugin::Pattern &/*pattern*/,
+ const drm::V1_0::SharedBuffer &/*source*/, size_t /*offset*/,
+ const CryptoPlugin::SubSample * /*subSamples*/, size_t /*numSubSamples*/,
+ const drm::V1_0::DestinationBuffer &/*destination*/, AString * /*errorDetailMsg*/) = 0;
/**
* Declare the heap that the shared memory source buffers passed
@@ -78,7 +80,7 @@
* that subsequent decrypt calls can use to refer to the heap,
* with -1 indicating failure.
*/
- virtual int32_t setHeap(const sp<IMemoryHeap>& heap) = 0;
+ virtual int32_t setHeap(const sp<hardware::HidlMemory>& heap) = 0;
virtual void unsetHeap(int32_t seqNum) = 0;
protected:
diff --git a/drm/libmediadrm/tests/Android.bp b/drm/libmediadrm/tests/Android.bp
index 2e39943..7471e05 100644
--- a/drm/libmediadrm/tests/Android.bp
+++ b/drm/libmediadrm/tests/Android.bp
@@ -24,6 +24,8 @@
"libbinder",
"libhidlbase",
"liblog",
+ "libmediadrm",
+ "libmediadrmmetrics_consumer",
"libmediadrmmetrics_full",
"libmediametrics",
"libprotobuf-cpp-full",
diff --git a/drm/libmediadrm/tests/DrmMetrics_test.cpp b/drm/libmediadrm/tests/DrmMetrics_test.cpp
index 5c8a1b0..f362d60 100644
--- a/drm/libmediadrm/tests/DrmMetrics_test.cpp
+++ b/drm/libmediadrm/tests/DrmMetrics_test.cpp
@@ -16,6 +16,7 @@
#define LOG_TAG "DrmMetricsTest"
#include "mediadrm/DrmMetrics.h"
+#include "mediadrm/DrmMetricsConsumer.h"
#include <android/hardware/drm/1.0/types.h>
#include <android/hardware/drm/1.1/types.h>
@@ -58,8 +59,9 @@
TEST_F(MediaDrmMetricsTest, EmptySuccess) {
MediaDrmMetrics metrics;
PersistableBundle bundle;
+ DrmMetricsConsumer consumer(&bundle);
- metrics.Export(&bundle);
+ consumer.consumeFrameworkMetrics(metrics);
EXPECT_TRUE(bundle.empty());
}
@@ -85,8 +87,9 @@
metrics.mEventCounter.Increment(EventType::PROVISION_REQUIRED);
PersistableBundle bundle;
+ DrmMetricsConsumer consumer(&bundle);
- metrics.Export(&bundle);
+ consumer.consumeFrameworkMetrics(metrics);
EXPECT_EQ(11U, bundle.size());
// Verify the list of pairs of int64 metrics.
@@ -174,7 +177,8 @@
metrics.SetSessionEnd(sessionId1);
PersistableBundle bundle;
- metrics.Export(&bundle);
+ DrmMetricsConsumer consumer(&bundle);
+ consumer.consumeFrameworkMetrics(metrics);
EXPECT_EQ(35U, bundle.size());
// Verify the list of pairs of int64 metrics.
@@ -421,7 +425,7 @@
hidl_vec<DrmMetricGroup> hidlMetricGroups;
PersistableBundle bundleMetricGroups;
- ASSERT_EQ(OK, MediaDrmMetrics::HidlMetricsToBundle(hidlMetricGroups, &bundleMetricGroups));
+ ASSERT_EQ(OK, DrmMetricsConsumer::HidlMetricsToBundle(hidlMetricGroups, &bundleMetricGroups));
ASSERT_EQ(0U, bundleMetricGroups.size());
}
@@ -441,7 +445,7 @@
} } };
PersistableBundle bundleMetricGroups;
- ASSERT_EQ(OK, MediaDrmMetrics::HidlMetricsToBundle(hidl_vec<DrmMetricGroup>({hidlMetricGroup}),
+ ASSERT_EQ(OK, DrmMetricsConsumer::HidlMetricsToBundle(hidl_vec<DrmMetricGroup>({hidlMetricGroup}),
&bundleMetricGroups));
ASSERT_EQ(1U, bundleMetricGroups.size());
PersistableBundle bundleMetricGroup;
diff --git a/media/codec2/components/avc/C2SoftAvcEnc.cpp b/media/codec2/components/avc/C2SoftAvcEnc.cpp
index b41c271..e3d419c 100644
--- a/media/codec2/components/avc/C2SoftAvcEnc.cpp
+++ b/media/codec2/components/avc/C2SoftAvcEnc.cpp
@@ -40,7 +40,7 @@
namespace {
constexpr char COMPONENT_NAME[] = "c2.android.avc.encoder";
-
+constexpr uint32_t kMinOutBufferSize = 524288;
void ParseGop(
const C2StreamGopTuning::output &gop,
uint32_t *syncInterval, uint32_t *iInterval, uint32_t *maxBframes) {
@@ -440,8 +440,7 @@
mSignalledError(false),
mCodecCtx(nullptr),
mOutBlock(nullptr),
- // TODO: output buffer size
- mOutBufferSize(524288) {
+ mOutBufferSize(kMinOutBufferSize) {
// If dump is enabled, then open create an empty file
GENERATE_FILE_NAMES();
@@ -951,6 +950,9 @@
mStride = width;
+ // Assume worst case output buffer size to be equal to number of bytes in input
+ mOutBufferSize = std::max(width * height * 3 / 2, kMinOutBufferSize);
+
// TODO
mIvVideoColorFormat = IV_YUV_420P;
diff --git a/media/codec2/hidl/services/vendor.cpp b/media/codec2/hidl/services/vendor.cpp
index 65bb6f7..81bffeb 100644
--- a/media/codec2/hidl/services/vendor.cpp
+++ b/media/codec2/hidl/services/vendor.cpp
@@ -23,7 +23,9 @@
#include <hidl/HidlTransportSupport.h>
#include <minijail.h>
+#include <util/C2InterfaceHelper.h>
#include <C2Component.h>
+#include <C2Config.h>
// This is the absolute on-device path of the prebuild_etc module
// "android.hardware.media.c2@1.1-default-seccomp_policy" in Android.bp.
@@ -37,11 +39,14 @@
"/vendor/etc/seccomp_policy/"
"android.hardware.media.c2@1.1-extended-seccomp-policy";
-class DummyC2Store : public C2ComponentStore {
+class StoreImpl : public C2ComponentStore {
public:
- DummyC2Store() = default;
+ StoreImpl()
+ : mReflectorHelper(std::make_shared<C2ReflectorHelper>()),
+ mInterface(mReflectorHelper) {
+ }
- virtual ~DummyC2Store() override = default;
+ virtual ~StoreImpl() override = default;
virtual C2String getName() const override {
return "default";
@@ -71,31 +76,69 @@
}
virtual c2_status_t query_sm(
- const std::vector<C2Param*>& /* stackParams */,
- const std::vector<C2Param::Index>& /* heapParamIndices */,
- std::vector<std::unique_ptr<C2Param>>* const /* heapParams */) const override {
- return C2_OMITTED;
+ const std::vector<C2Param*>& stackParams,
+ const std::vector<C2Param::Index>& heapParamIndices,
+ std::vector<std::unique_ptr<C2Param>>* const heapParams) const override {
+ return mInterface.query(stackParams, heapParamIndices, C2_MAY_BLOCK, heapParams);
}
virtual c2_status_t config_sm(
- const std::vector<C2Param*>& /* params */,
- std::vector<std::unique_ptr<C2SettingResult>>* const /* failures */) override {
- return C2_OMITTED;
+ const std::vector<C2Param*>& params,
+ std::vector<std::unique_ptr<C2SettingResult>>* const failures) override {
+ return mInterface.config(params, C2_MAY_BLOCK, failures);
}
virtual std::shared_ptr<C2ParamReflector> getParamReflector() const override {
- return nullptr;
+ return mReflectorHelper;
}
virtual c2_status_t querySupportedParams_nb(
- std::vector<std::shared_ptr<C2ParamDescriptor>>* const /* params */) const override {
- return C2_OMITTED;
+ std::vector<std::shared_ptr<C2ParamDescriptor>>* const params) const override {
+ return mInterface.querySupportedParams(params);
}
virtual c2_status_t querySupportedValues_sm(
- std::vector<C2FieldSupportedValuesQuery>& /* fields */) const override {
- return C2_OMITTED;
+ std::vector<C2FieldSupportedValuesQuery>& fields) const override {
+ return mInterface.querySupportedValues(fields, C2_MAY_BLOCK);
}
+
+private:
+ class Interface : public C2InterfaceHelper {
+ public:
+ Interface(const std::shared_ptr<C2ReflectorHelper> &helper)
+ : C2InterfaceHelper(helper) {
+ setDerivedInstance(this);
+
+ addParameter(
+ DefineParam(mIonUsageInfo, "ion-usage")
+ .withDefault(new C2StoreIonUsageInfo())
+ .withFields({
+ C2F(mIonUsageInfo, usage).flags(
+ {C2MemoryUsage::CPU_READ | C2MemoryUsage::CPU_WRITE}),
+ C2F(mIonUsageInfo, capacity).inRange(0, UINT32_MAX, 1024),
+ C2F(mIonUsageInfo, heapMask).any(),
+ C2F(mIonUsageInfo, allocFlags).flags({}),
+ C2F(mIonUsageInfo, minAlignment).equalTo(0)
+ })
+ .withSetter(SetIonUsage)
+ .build());
+ }
+
+ virtual ~Interface() = default;
+
+ private:
+ static C2R SetIonUsage(bool /* mayBlock */, C2P<C2StoreIonUsageInfo> &me) {
+ // Vendor's TODO: put appropriate mapping logic
+ me.set().heapMask = ~0;
+ me.set().allocFlags = 0;
+ me.set().minAlignment = 0;
+ return C2R::Ok();
+ }
+
+ std::shared_ptr<C2StoreIonUsageInfo> mIonUsageInfo;
+ };
+ std::shared_ptr<C2ReflectorHelper> mReflectorHelper;
+ Interface mInterface;
};
int main(int /* argc */, char** /* argv */) {
@@ -124,7 +167,7 @@
// /* implementation of C2ComponentStore */);
LOG(DEBUG) << "Instantiating Codec2's IComponentStore service...";
store = new utils::ComponentStore(
- std::make_shared<DummyC2Store>());
+ std::make_shared<StoreImpl>());
if (store == nullptr) {
LOG(ERROR) << "Cannot create Codec2's IComponentStore service.";
diff --git a/media/codec2/sfplugin/Android.bp b/media/codec2/sfplugin/Android.bp
index e174751..59ac94b 100644
--- a/media/codec2/sfplugin/Android.bp
+++ b/media/codec2/sfplugin/Android.bp
@@ -27,6 +27,7 @@
shared_libs: [
"android.hardware.cas.native@1.0",
+ "android.hardware.drm@1.0",
"android.hardware.media.c2@1.0",
"android.hardware.media.omx@1.0",
"libbase",
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp
index c78cdc1..31e5406 100644
--- a/media/codec2/sfplugin/CCodec.cpp
+++ b/media/codec2/sfplugin/CCodec.cpp
@@ -1524,7 +1524,9 @@
{
Mutexed<State>::Locked state(mState);
- state->set(FLUSHED);
+ if (state->get() == FLUSHING) {
+ state->set(FLUSHED);
+ }
}
mCallback->onFlushCompleted();
}
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.cpp b/media/codec2/sfplugin/CCodecBufferChannel.cpp
index d61b751..7b8dac5 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.cpp
+++ b/media/codec2/sfplugin/CCodecBufferChannel.cpp
@@ -27,10 +27,12 @@
#include <C2Debug.h>
#include <android/hardware/cas/native/1.0/IDescrambler.h>
+#include <android/hardware/drm/1.0/types.h>
#include <android-base/stringprintf.h>
#include <binder/MemoryDealer.h>
#include <cutils/properties.h>
#include <gui/Surface.h>
+#include <hidlmemory/FrameworkUtils.h>
#include <media/openmax/OMX_Core.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ALookup.h>
@@ -52,10 +54,14 @@
using hardware::hidl_handle;
using hardware::hidl_string;
using hardware::hidl_vec;
+using hardware::fromHeap;
+using hardware::HidlMemory;
+
using namespace hardware::cas::V1_0;
using namespace hardware::cas::native::V1_0;
using CasStatus = hardware::cas::V1_0::Status;
+using DrmBufferType = hardware::drm::V1_0::BufferType;
namespace {
@@ -431,15 +437,16 @@
ssize_t result = -1;
ssize_t codecDataOffset = 0;
if (mCrypto != nullptr) {
- ICrypto::DestinationBuffer destination;
+ hardware::drm::V1_0::DestinationBuffer destination;
if (secure) {
- destination.mType = ICrypto::kDestinationTypeNativeHandle;
- destination.mHandle = encryptedBuffer->handle();
+ destination.type = DrmBufferType::NATIVE_HANDLE;
+ destination.secureMemory = hidl_handle(encryptedBuffer->handle());
} else {
- destination.mType = ICrypto::kDestinationTypeSharedMemory;
- destination.mSharedMemory = mDecryptDestination;
+ destination.type = DrmBufferType::SHARED_MEMORY;
+ IMemoryToSharedBuffer(
+ mDecryptDestination, mHeapSeqNum, &destination.nonsecureMemory);
}
- ICrypto::SourceBuffer source;
+ hardware::drm::V1_0::SharedBuffer source;
encryptedBuffer->fillSourceBuffer(&source);
result = mCrypto->decrypt(
key, iv, mode, pattern, source, buffer->offset(),
@@ -447,7 +454,7 @@
if (result < 0) {
return result;
}
- if (destination.mType == ICrypto::kDestinationTypeSharedMemory) {
+ if (destination.type == DrmBufferType::SHARED_MEMORY) {
encryptedBuffer->copyDecryptedContent(mDecryptDestination, result);
}
} else {
@@ -919,7 +926,8 @@
mDecryptDestination = mDealer->allocate((size_t)capacity);
}
if (mCrypto != nullptr && mHeapSeqNum < 0) {
- mHeapSeqNum = mCrypto->setHeap(mDealer->getMemoryHeap());
+ sp<HidlMemory> heap = fromHeap(mDealer->getMemoryHeap());
+ mHeapSeqNum = mCrypto->setHeap(heap);
} else {
mHeapSeqNum = -1;
}
@@ -1662,6 +1670,14 @@
mMetaMode = mode;
}
+void CCodecBufferChannel::setCrypto(const sp<ICrypto> &crypto) {
+ mCrypto = crypto;
+}
+
+void CCodecBufferChannel::setDescrambler(const sp<IDescrambler> &descrambler) {
+ mDescrambler = descrambler;
+}
+
status_t toStatusT(c2_status_t c2s, c2_operation_t c2op) {
// C2_OK is always translated to OK.
if (c2s == C2_OK) {
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.h b/media/codec2/sfplugin/CCodecBufferChannel.h
index c0fa138..82fec18 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.h
+++ b/media/codec2/sfplugin/CCodecBufferChannel.h
@@ -56,6 +56,9 @@
virtual ~CCodecBufferChannel();
// BufferChannelBase interface
+ void setCrypto(const sp<ICrypto> &crypto) override;
+ void setDescrambler(const sp<IDescrambler> &descrambler) override;
+
virtual status_t queueInputBuffer(const sp<MediaCodecBuffer> &buffer) override;
virtual status_t queueSecureInputBuffer(
const sp<MediaCodecBuffer> &buffer,
@@ -318,6 +321,9 @@
std::atomic_bool mInputMetEos;
std::once_flag mRenderWarningFlag;
+ sp<ICrypto> mCrypto;
+ sp<IDescrambler> mDescrambler;
+
inline bool hasCryptoOrDescrambler() {
return mCrypto != nullptr || mDescrambler != nullptr;
}
diff --git a/media/codec2/sfplugin/Codec2Buffer.cpp b/media/codec2/sfplugin/Codec2Buffer.cpp
index b339a92..b6d18e2 100644
--- a/media/codec2/sfplugin/Codec2Buffer.cpp
+++ b/media/codec2/sfplugin/Codec2Buffer.cpp
@@ -20,6 +20,7 @@
#include <hidlmemory/FrameworkUtils.h>
#include <media/hardware/HardwareAPI.h>
+#include <media/stagefright/CodecBase.h>
#include <media/stagefright/MediaCodecConstants.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/AMessage.h>
@@ -779,9 +780,8 @@
}
void EncryptedLinearBlockBuffer::fillSourceBuffer(
- ICrypto::SourceBuffer *source) {
- source->mSharedMemory = mMemory;
- source->mHeapSeqNum = mHeapSeqNum;
+ hardware::drm::V1_0::SharedBuffer *source) {
+ BufferChannelBase::IMemoryToSharedBuffer(mMemory, mHeapSeqNum, source);
}
void EncryptedLinearBlockBuffer::fillSourceBuffer(
diff --git a/media/codec2/sfplugin/Codec2Buffer.h b/media/codec2/sfplugin/Codec2Buffer.h
index 6f87101..9291c52 100644
--- a/media/codec2/sfplugin/Codec2Buffer.h
+++ b/media/codec2/sfplugin/Codec2Buffer.h
@@ -21,6 +21,7 @@
#include <C2Buffer.h>
#include <android/hardware/cas/native/1.0/types.h>
+#include <android/hardware/drm/1.0/types.h>
#include <binder/IMemory.h>
#include <media/hardware/VideoAPI.h>
#include <media/stagefright/foundation/ABuffer.h>
@@ -361,7 +362,8 @@
*
* \param source source buffer structure to fill.
*/
- void fillSourceBuffer(ICrypto::SourceBuffer *source);
+ void fillSourceBuffer(
+ hardware::drm::V1_0::SharedBuffer *source);
void fillSourceBuffer(
hardware::cas::native::V1_0::SharedBuffer *source);
diff --git a/media/codec2/vndk/Android.bp b/media/codec2/vndk/Android.bp
index 4c529a6..e0b3939 100644
--- a/media/codec2/vndk/Android.bp
+++ b/media/codec2/vndk/Android.bp
@@ -16,6 +16,7 @@
vendor_available: true,
srcs: [
+ "C2AllocatorBlob.cpp",
"C2AllocatorIon.cpp",
"C2AllocatorGralloc.cpp",
"C2Buffer.cpp",
diff --git a/media/codec2/vndk/C2AllocatorBlob.cpp b/media/codec2/vndk/C2AllocatorBlob.cpp
new file mode 100644
index 0000000..50c9e59
--- /dev/null
+++ b/media/codec2/vndk/C2AllocatorBlob.cpp
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 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.
+ */
+
+// #define LOG_NDEBUG 0
+#define LOG_TAG "C2AllocatorBlob"
+
+#include <C2AllocatorBlob.h>
+#include <C2PlatformSupport.h>
+
+#include <android/hardware/graphics/common/1.2/types.h>
+#include <utils/Log.h>
+
+namespace android {
+
+using ::android::hardware::graphics::common::V1_2::PixelFormat;
+
+constexpr uint32_t kLinearBufferHeight = 1u;
+constexpr uint32_t kLinearBufferFormat = static_cast<uint32_t>(PixelFormat::BLOB);
+
+namespace {
+
+c2_status_t GetCapacityFromHandle(const C2Handle* const grallocHandle, size_t* capacity) {
+ uint32_t width, height, format, stride, generation, igbp_slot;
+ uint64_t usage, igbp_id;
+ _UnwrapNativeCodec2GrallocMetadata(grallocHandle, &width, &height, &format, &usage, &stride,
+ &generation, &igbp_id, &igbp_slot);
+
+ if (height != kLinearBufferHeight || format != kLinearBufferFormat) {
+ return C2_BAD_VALUE;
+ }
+ *capacity = width;
+ return C2_OK;
+}
+
+} // namespace
+
+// C2AllocationBlob is a wrapper for C2AllocationGralloc allocated by C2AllocatorGralloc.
+// C2AllocationBlob::handle() delegates to the backed C2AllocationGralloc::handle().
+class C2AllocationBlob : public C2LinearAllocation {
+public:
+ C2AllocationBlob(std::shared_ptr<C2GraphicAllocation> graphicAllocation, size_t capacity,
+ C2Allocator::id_t allocatorId);
+ ~C2AllocationBlob() override;
+ c2_status_t map(size_t offset, size_t size, C2MemoryUsage usage, C2Fence* fence,
+ void** addr /* nonnull */) override;
+ c2_status_t unmap(void* addr, size_t size, C2Fence* fenceFd) override;
+
+ id_t getAllocatorId() const override { return mAllocatorId; }
+ const C2Handle* handle() const override { return mGraphicAllocation->handle(); }
+ bool equals(const std::shared_ptr<C2LinearAllocation>& other) const override {
+ return other && other->handle() == handle();
+ }
+
+private:
+ const std::shared_ptr<C2GraphicAllocation> mGraphicAllocation;
+ const C2Allocator::id_t mAllocatorId;
+};
+
+C2AllocationBlob::C2AllocationBlob(
+ std::shared_ptr<C2GraphicAllocation> graphicAllocation, size_t capacity,
+ C2Allocator::id_t allocatorId)
+ : C2LinearAllocation(capacity),
+ mGraphicAllocation(std::move(graphicAllocation)),
+ mAllocatorId(allocatorId) {}
+
+C2AllocationBlob::~C2AllocationBlob() {}
+
+c2_status_t C2AllocationBlob::map(size_t offset, size_t size, C2MemoryUsage usage,
+ C2Fence* fence, void** addr /* nonnull */) {
+ C2PlanarLayout layout;
+ C2Rect rect = C2Rect(size, kLinearBufferHeight).at(offset, 0u);
+ return mGraphicAllocation->map(rect, usage, fence, &layout, reinterpret_cast<uint8_t**>(addr));
+}
+
+c2_status_t C2AllocationBlob::unmap(void* addr, size_t size, C2Fence* fenceFd) {
+ C2Rect rect(size, kLinearBufferHeight);
+ return mGraphicAllocation->unmap(reinterpret_cast<uint8_t**>(&addr), rect, fenceFd);
+}
+
+/* ====================================== BLOB ALLOCATOR ====================================== */
+C2AllocatorBlob::C2AllocatorBlob(id_t id) {
+ C2MemoryUsage minUsage = {0, 0};
+ C2MemoryUsage maxUsage = {C2MemoryUsage::CPU_READ | C2MemoryUsage::READ_PROTECTED,
+ C2MemoryUsage::CPU_WRITE};
+ Traits traits = {"android.allocator.blob", id, LINEAR, minUsage, maxUsage};
+ mTraits = std::make_shared<C2Allocator::Traits>(traits);
+ auto allocatorStore = GetCodec2PlatformAllocatorStore();
+ allocatorStore->fetchAllocator(C2PlatformAllocatorStore::GRALLOC, &mC2AllocatorGralloc);
+ if (!mC2AllocatorGralloc) {
+ ALOGE("Failed to obtain C2AllocatorGralloc as backed allocator");
+ }
+}
+
+C2AllocatorBlob::~C2AllocatorBlob() {}
+
+c2_status_t C2AllocatorBlob::newLinearAllocation(
+ uint32_t capacity, C2MemoryUsage usage, std::shared_ptr<C2LinearAllocation>* allocation) {
+ if (allocation == nullptr) {
+ return C2_BAD_VALUE;
+ }
+
+ allocation->reset();
+
+ if (!mC2AllocatorGralloc) {
+ return C2_CORRUPTED;
+ }
+
+ std::shared_ptr<C2GraphicAllocation> graphicAllocation;
+ c2_status_t status = mC2AllocatorGralloc->newGraphicAllocation(
+ capacity, kLinearBufferHeight, kLinearBufferFormat, usage, &graphicAllocation);
+ if (status != C2_OK) {
+ ALOGE("Failed newGraphicAllocation");
+ return status;
+ }
+
+ allocation->reset(new C2AllocationBlob(std::move(graphicAllocation),
+ static_cast<size_t>(capacity), mTraits->id));
+ return C2_OK;
+}
+
+c2_status_t C2AllocatorBlob::priorLinearAllocation(
+ const C2Handle* handle, std::shared_ptr<C2LinearAllocation>* allocation) {
+ if (allocation == nullptr) {
+ return C2_BAD_VALUE;
+ }
+
+ allocation->reset();
+
+ if (!mC2AllocatorGralloc) {
+ return C2_CORRUPTED;
+ }
+
+ std::shared_ptr<C2GraphicAllocation> graphicAllocation;
+ c2_status_t status = mC2AllocatorGralloc->priorGraphicAllocation(handle, &graphicAllocation);
+ if (status != C2_OK) {
+ ALOGE("Failed priorGraphicAllocation");
+ return status;
+ }
+
+ const C2Handle* const grallocHandle = graphicAllocation->handle();
+ size_t capacity = 0;
+ status = GetCapacityFromHandle(grallocHandle, &capacity);
+ if (status != C2_OK) {
+ ALOGE("Failed to extract capacity from Handle");
+ return status;
+ }
+
+ allocation->reset(new C2AllocationBlob(std::move(graphicAllocation), capacity, mTraits->id));
+ return C2_OK;
+}
+
+id_t C2AllocatorBlob::getId() const {
+ return mTraits->id;
+}
+
+C2String C2AllocatorBlob::getName() const {
+ return mTraits->name;
+}
+
+std::shared_ptr<const C2Allocator::Traits> C2AllocatorBlob::getTraits() const {
+ return mTraits;
+}
+
+// static
+bool C2AllocatorBlob::isValid(const C2Handle* const o) {
+ size_t capacity;
+ // Distinguish C2Handle purely allocated by C2AllocatorGralloc, or one allocated through
+ // C2AllocatorBlob, by checking the handle's height is 1, and its format is
+ // PixelFormat::BLOB by GetCapacityFromHandle().
+ return C2AllocatorGralloc::isValid(o) && GetCapacityFromHandle(o, &capacity) == C2_OK;
+}
+
+} // namespace android
diff --git a/media/codec2/vndk/C2AllocatorGralloc.cpp b/media/codec2/vndk/C2AllocatorGralloc.cpp
index cd179be..78ac355 100644
--- a/media/codec2/vndk/C2AllocatorGralloc.cpp
+++ b/media/codec2/vndk/C2AllocatorGralloc.cpp
@@ -605,14 +605,11 @@
(int32_t)rect.width, (int32_t)rect.height },
// TODO: fence
hidl_handle(),
- [&err, &pointer](const auto &maperr, const auto &mapPointer,
- int32_t bytesPerPixel, int32_t bytesPerStride) {
+ [&err, &pointer](const auto &maperr, const auto &mapPointer) {
err = maperr2error(maperr);
if (err == C2_OK) {
pointer = mapPointer;
}
- (void)bytesPerPixel;
- (void)bytesPerStride;
}).isOk()) {
ALOGE("failed transaction: lock(RGBA_1010102) (@4.0)");
return C2_CORRUPTED;
@@ -743,14 +740,11 @@
(int32_t)rect.width, (int32_t)rect.height },
// TODO: fence
hidl_handle(),
- [&err, &pointer](const auto &maperr, const auto &mapPointer,
- int32_t bytesPerPixel, int32_t bytesPerStride) {
+ [&err, &pointer](const auto &maperr, const auto &mapPointer) {
err = maperr2error(maperr);
if (err == C2_OK) {
pointer = mapPointer;
}
- (void)bytesPerPixel;
- (void)bytesPerStride;
}).isOk()) {
ALOGE("failed transaction: lock(RGBA_8888) (@4.0)");
return C2_CORRUPTED;
@@ -816,6 +810,70 @@
break;
}
+ case PixelFormat4::BLOB: {
+ void* pointer = nullptr;
+ if (mMapper2) {
+ if (!mMapper2->lock(const_cast<native_handle_t*>(mBuffer), grallocUsage,
+ {(int32_t)rect.left, (int32_t)rect.top, (int32_t)rect.width,
+ (int32_t)rect.height},
+ // TODO: fence
+ hidl_handle(),
+ [&err, &pointer](const auto& maperr, const auto& mapPointer) {
+ err = maperr2error(maperr);
+ if (err == C2_OK) {
+ pointer = mapPointer;
+ }
+ }).isOk()) {
+ ALOGE("failed transaction: lock(BLOB)");
+ return C2_CORRUPTED;
+ }
+ } else if (mMapper3) {
+ if (!mMapper3->lock(
+ const_cast<native_handle_t*>(mBuffer),
+ grallocUsage,
+ { (int32_t)rect.left, (int32_t)rect.top,
+ (int32_t)rect.width, (int32_t)rect.height },
+ // TODO: fence
+ hidl_handle(),
+ [&err, &pointer](const auto &maperr, const auto &mapPointer,
+ int32_t bytesPerPixel, int32_t bytesPerStride) {
+ err = maperr2error(maperr);
+ if (err == C2_OK) {
+ pointer = mapPointer;
+ }
+ (void)bytesPerPixel;
+ (void)bytesPerStride;
+ }).isOk()) {
+ ALOGE("failed transaction: lock(BLOB) (@3.0)");
+ return C2_CORRUPTED;
+ }
+ } else {
+ if (!mMapper4->lock(
+ const_cast<native_handle_t *>(mBuffer),
+ grallocUsage,
+ { (int32_t)rect.left, (int32_t)rect.top,
+ (int32_t)rect.width, (int32_t)rect.height },
+ // TODO: fence
+ hidl_handle(),
+ [&err, &pointer](const auto &maperr, const auto &mapPointer) {
+ err = maperr2error(maperr);
+ if (err == C2_OK) {
+ pointer = mapPointer;
+ }
+ }).isOk()) {
+ ALOGE("failed transaction: lock(BLOB) (@4.0)");
+ return C2_CORRUPTED;
+ }
+ }
+ if (err != C2_OK) {
+ ALOGD("lock failed: %d", err);
+ return err;
+ }
+
+ *addr = static_cast<uint8_t*>(pointer);
+ break;
+ }
+
case PixelFormat4::YCBCR_420_888:
// fall-through
case PixelFormat4::YV12:
@@ -875,27 +933,14 @@
return C2_CORRUPTED;
}
} else {
- if (!mMapper4->lockYCbCr(
- const_cast<native_handle_t *>(mBuffer), grallocUsage,
- { (int32_t)rect.left, (int32_t)rect.top,
- (int32_t)rect.width, (int32_t)rect.height },
- // TODO: fence
- hidl_handle(),
- [&err, &ycbcrLayout](const auto &maperr, const auto &mapLayout) {
- err = maperr2error(maperr);
- if (err == C2_OK) {
- ycbcrLayout = YCbCrLayout{
- mapLayout.y,
- mapLayout.cb,
- mapLayout.cr,
- mapLayout.yStride,
- mapLayout.cStride,
- mapLayout.chromaStep};
- }
- }).isOk()) {
- ALOGE("failed transaction: lockYCbCr (@4.0)");
- return C2_CORRUPTED;
- }
+ // No device currently supports IMapper 4.0 so it is safe to just return an error
+ // code here.
+ //
+ // This will be supported by a combination of lock and BufferMetadata getters.
+ // We are going to refactor all the IAllocator/IMapper versioning code into a
+ // shared library. We will then add the IMapper 4.0 lockYCbCr support then.
+ ALOGE("failed transaction: lockYCbCr (@4.0)");
+ return C2_CORRUPTED;
}
if (err != C2_OK) {
ALOGD("lockYCbCr failed: %d", err);
diff --git a/media/codec2/vndk/include/C2AllocatorBlob.h b/media/codec2/vndk/include/C2AllocatorBlob.h
new file mode 100644
index 0000000..89ce949
--- /dev/null
+++ b/media/codec2/vndk/include/C2AllocatorBlob.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 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.
+ */
+
+#ifndef STAGEFRIGHT_CODEC2_ALLOCATOR_BLOB_H_
+#define STAGEFRIGHT_CODEC2_ALLOCATOR_BLOB_H_
+
+#include <functional>
+
+#include <C2AllocatorGralloc.h>
+#include <C2Buffer.h>
+
+namespace android {
+
+class C2AllocatorBlob : public C2Allocator {
+public:
+ virtual id_t getId() const override;
+
+ virtual C2String getName() const override;
+
+ virtual std::shared_ptr<const Traits> getTraits() const override;
+
+ virtual c2_status_t newLinearAllocation(
+ uint32_t capacity, C2MemoryUsage usage,
+ std::shared_ptr<C2LinearAllocation> *allocation) override;
+
+ virtual c2_status_t priorLinearAllocation(
+ const C2Handle *handle,
+ std::shared_ptr<C2LinearAllocation> *allocation) override;
+
+ C2AllocatorBlob(id_t id);
+
+ virtual ~C2AllocatorBlob() override;
+
+ static bool isValid(const C2Handle* const o);
+
+private:
+ std::shared_ptr<const Traits> mTraits;
+ // Design as C2AllocatorGralloc-backed to unify Gralloc implementations.
+ std::shared_ptr<C2Allocator> mC2AllocatorGralloc;
+};
+
+} // namespace android
+
+#endif // STAGEFRIGHT_CODEC2_ALLOCATOR_BLOB_H_
diff --git a/media/libaaudio/src/Android.bp b/media/libaaudio/src/Android.bp
index 850b1d0..463f606 100644
--- a/media/libaaudio/src/Android.bp
+++ b/media/libaaudio/src/Android.bp
@@ -40,6 +40,20 @@
"libutils",
"libbinder",
],
+
+ sanitize: {
+ integer_overflow: true,
+ misc_undefined: ["bounds"],
+ diag: {
+ integer_overflow: true,
+ misc_undefined: ["bounds"],
+ no_recover: [
+ "bounds",
+ "integer",
+ ],
+ },
+ },
+
}
cc_library {
@@ -57,7 +71,7 @@
export_include_dirs: ["."],
header_libs: [
"libaaudio_headers",
- "libmedia_headers"
+ "libmedia_headers",
],
export_header_lib_headers: ["libaaudio_headers"],
@@ -116,4 +130,17 @@
"flowgraph/SourceI16.cpp",
"flowgraph/SourceI24.cpp",
],
+ sanitize: {
+ integer_overflow: true,
+ misc_undefined: ["bounds"],
+ diag: {
+ integer_overflow: true,
+ misc_undefined: ["bounds"],
+ no_recover: [
+ "bounds",
+ "integer",
+ ],
+ },
+ },
+
}
diff --git a/media/libaaudio/src/fifo/FifoControllerBase.cpp b/media/libaaudio/src/fifo/FifoControllerBase.cpp
index 66e247f..1dece0e 100644
--- a/media/libaaudio/src/fifo/FifoControllerBase.cpp
+++ b/media/libaaudio/src/fifo/FifoControllerBase.cpp
@@ -33,7 +33,9 @@
}
fifo_frames_t FifoControllerBase::getFullFramesAvailable() {
- return (fifo_frames_t) (getWriteCounter() - getReadCounter());
+ fifo_frames_t temp = 0;
+ __builtin_sub_overflow(getWriteCounter(), getReadCounter(), &temp);
+ return temp;
}
fifo_frames_t FifoControllerBase::getReadIndex() {
@@ -42,7 +44,9 @@
}
void FifoControllerBase::advanceReadIndex(fifo_frames_t numFrames) {
- setReadCounter(getReadCounter() + numFrames);
+ fifo_counter_t temp = 0;
+ __builtin_add_overflow(getReadCounter(), numFrames, &temp);
+ setReadCounter(temp);
}
fifo_frames_t FifoControllerBase::getEmptyFramesAvailable() {
@@ -55,7 +59,9 @@
}
void FifoControllerBase::advanceWriteIndex(fifo_frames_t numFrames) {
- setWriteCounter(getWriteCounter() + numFrames);
+ fifo_counter_t temp = 0;
+ __builtin_add_overflow(getWriteCounter(), numFrames, &temp);
+ setWriteCounter(temp);
}
void FifoControllerBase::setThreshold(fifo_frames_t threshold) {
diff --git a/media/libaudiofoundation/AudioContainers.cpp b/media/libaudiofoundation/AudioContainers.cpp
index 1bfe3f9..31257d5 100644
--- a/media/libaudiofoundation/AudioContainers.cpp
+++ b/media/libaudiofoundation/AudioContainers.cpp
@@ -42,6 +42,13 @@
return audioDeviceOutAllScoSet;
}
+const DeviceTypeSet& getAudioDeviceOutAllUsbSet() {
+ static const DeviceTypeSet audioDeviceOutAllUsbSet = DeviceTypeSet(
+ std::begin(AUDIO_DEVICE_OUT_ALL_USB_ARRAY),
+ std::end(AUDIO_DEVICE_OUT_ALL_USB_ARRAY));
+ return audioDeviceOutAllUsbSet;
+}
+
const DeviceTypeSet& getAudioDeviceInAllSet() {
static const DeviceTypeSet audioDeviceInAllSet = DeviceTypeSet(
std::begin(AUDIO_DEVICE_IN_ALL_ARRAY),
@@ -49,6 +56,13 @@
return audioDeviceInAllSet;
}
+const DeviceTypeSet& getAudioDeviceInAllUsbSet() {
+ static const DeviceTypeSet audioDeviceInAllUsbSet = DeviceTypeSet(
+ std::begin(AUDIO_DEVICE_IN_ALL_USB_ARRAY),
+ std::end(AUDIO_DEVICE_IN_ALL_USB_ARRAY));
+ return audioDeviceInAllUsbSet;
+}
+
bool deviceTypesToString(const DeviceTypeSet &deviceTypes, std::string &str) {
if (deviceTypes.empty()) {
str = "Empty device types";
diff --git a/media/libaudiofoundation/include/media/AudioContainers.h b/media/libaudiofoundation/include/media/AudioContainers.h
index 2a3385b..72fda49 100644
--- a/media/libaudiofoundation/include/media/AudioContainers.h
+++ b/media/libaudiofoundation/include/media/AudioContainers.h
@@ -37,7 +37,9 @@
const DeviceTypeSet& getAudioDeviceOutAllSet();
const DeviceTypeSet& getAudioDeviceOutAllA2dpSet();
const DeviceTypeSet& getAudioDeviceOutAllScoSet();
+const DeviceTypeSet& getAudioDeviceOutAllUsbSet();
const DeviceTypeSet& getAudioDeviceInAllSet();
+const DeviceTypeSet& getAudioDeviceInAllUsbSet();
template<typename T>
static std::vector<T> Intersection(const std::set<T>& a, const std::set<T>& b) {
diff --git a/media/libaudiohal/impl/Android.bp b/media/libaudiohal/impl/Android.bp
index 8669e2a..e96a68c 100644
--- a/media/libaudiohal/impl/Android.bp
+++ b/media/libaudiohal/impl/Android.bp
@@ -27,6 +27,7 @@
"android.hardware.audio.common-util",
"android.hidl.allocator@1.0",
"android.hidl.memory@1.0",
+ "libaudiofoundation",
"libaudiohal_deathhandler",
"libaudioutils",
"libbase",
diff --git a/media/libaudiohal/impl/ConversionHelperHidl.cpp b/media/libaudiohal/impl/ConversionHelperHidl.cpp
index 9f8a520..f29b0f3 100644
--- a/media/libaudiohal/impl/ConversionHelperHidl.cpp
+++ b/media/libaudiohal/impl/ConversionHelperHidl.cpp
@@ -17,6 +17,7 @@
#include <string.h>
#define LOG_TAG "HalHidl"
+#include <media/AudioContainers.h>
#include <media/AudioParameter.h>
#include <utils/Log.h>
@@ -109,26 +110,22 @@
char halAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN];
memset(halAddress, 0, sizeof(halAddress));
audio_devices_t halDevice = static_cast<audio_devices_t>(address.device);
- const bool isInput = (halDevice & AUDIO_DEVICE_BIT_IN) != 0;
- if (isInput) halDevice &= ~AUDIO_DEVICE_BIT_IN;
- if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_ALL_A2DP) != 0) ||
- (isInput && (halDevice & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) != 0)) {
+ if (getAudioDeviceOutAllA2dpSet().count(halDevice) > 0 ||
+ halDevice == AUDIO_DEVICE_IN_BLUETOOTH_A2DP) {
snprintf(halAddress, sizeof(halAddress), "%02X:%02X:%02X:%02X:%02X:%02X",
address.address.mac[0], address.address.mac[1], address.address.mac[2],
address.address.mac[3], address.address.mac[4], address.address.mac[5]);
- } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_IP) != 0) ||
- (isInput && (halDevice & AUDIO_DEVICE_IN_IP) != 0)) {
+ } else if (halDevice == AUDIO_DEVICE_OUT_IP || halDevice == AUDIO_DEVICE_IN_IP) {
snprintf(halAddress, sizeof(halAddress), "%d.%d.%d.%d", address.address.ipv4[0],
address.address.ipv4[1], address.address.ipv4[2], address.address.ipv4[3]);
- } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_ALL_USB) != 0) ||
- (isInput && (halDevice & AUDIO_DEVICE_IN_ALL_USB) != 0)) {
+ } else if (getAudioDeviceOutAllUsbSet().count(halDevice) > 0 ||
+ getAudioDeviceInAllUsbSet().count(halDevice) > 0) {
snprintf(halAddress, sizeof(halAddress), "card=%d;device=%d", address.address.alsa.card,
address.address.alsa.device);
- } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_BUS) != 0) ||
- (isInput && (halDevice & AUDIO_DEVICE_IN_BUS) != 0)) {
+ } else if (halDevice == AUDIO_DEVICE_OUT_BUS || halDevice == AUDIO_DEVICE_IN_BUS) {
snprintf(halAddress, sizeof(halAddress), "%s", address.busAddress.c_str());
- } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_REMOTE_SUBMIX)) != 0 ||
- (isInput && (halDevice & AUDIO_DEVICE_IN_REMOTE_SUBMIX) != 0)) {
+ } else if (halDevice == AUDIO_DEVICE_OUT_REMOTE_SUBMIX ||
+ halDevice == AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
snprintf(halAddress, sizeof(halAddress), "%s", address.rSubmixAddress.c_str());
} else {
snprintf(halAddress, sizeof(halAddress), "%s", address.busAddress.c_str());
diff --git a/media/libaudiohal/impl/DeviceHalHidl.cpp b/media/libaudiohal/impl/DeviceHalHidl.cpp
index 3d3a5eb..d52416c 100644
--- a/media/libaudiohal/impl/DeviceHalHidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalHidl.cpp
@@ -22,6 +22,7 @@
#include PATH(android/hardware/audio/FILE_VERSION/IPrimaryDevice.h)
#include <cutils/native_handle.h>
#include <hwbinder/IPCThreadState.h>
+#include <media/AudioContainers.h>
#include <utils/Log.h>
#include <common/all-versions/VersionUtils.h>
@@ -51,42 +52,32 @@
if (halAddress == nullptr || strnlen(halAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0) {
return OK;
}
- const bool isInput = (device & AUDIO_DEVICE_BIT_IN) != 0;
- if (isInput) device &= ~AUDIO_DEVICE_BIT_IN;
- if ((!isInput && (device & AUDIO_DEVICE_OUT_ALL_A2DP) != 0)
- || (isInput && (device & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) != 0)) {
+ if (getAudioDeviceOutAllA2dpSet().count(device) > 0
+ || device == AUDIO_DEVICE_IN_BLUETOOTH_A2DP) {
int status = sscanf(halAddress,
"%hhX:%hhX:%hhX:%hhX:%hhX:%hhX",
&address->address.mac[0], &address->address.mac[1], &address->address.mac[2],
&address->address.mac[3], &address->address.mac[4], &address->address.mac[5]);
return status == 6 ? OK : BAD_VALUE;
- } else if ((!isInput && (device & AUDIO_DEVICE_OUT_IP) != 0)
- || (isInput && (device & AUDIO_DEVICE_IN_IP) != 0)) {
+ } else if (device == AUDIO_DEVICE_OUT_IP || device == AUDIO_DEVICE_IN_IP) {
int status = sscanf(halAddress,
"%hhu.%hhu.%hhu.%hhu",
&address->address.ipv4[0], &address->address.ipv4[1],
&address->address.ipv4[2], &address->address.ipv4[3]);
return status == 4 ? OK : BAD_VALUE;
- } else if ((!isInput && (device & AUDIO_DEVICE_OUT_ALL_USB)) != 0
- || (isInput && (device & AUDIO_DEVICE_IN_ALL_USB)) != 0) {
+ } else if (getAudioDeviceOutAllUsbSet().count(device) > 0
+ || getAudioDeviceInAllUsbSet().count(device) > 0) {
int status = sscanf(halAddress,
"card=%d;device=%d",
&address->address.alsa.card, &address->address.alsa.device);
return status == 2 ? OK : BAD_VALUE;
- } else if ((!isInput && (device & AUDIO_DEVICE_OUT_BUS) != 0)
- || (isInput && (device & AUDIO_DEVICE_IN_BUS) != 0)) {
- if (halAddress != NULL) {
- address->busAddress = halAddress;
- return OK;
- }
- return BAD_VALUE;
- } else if ((!isInput && (device & AUDIO_DEVICE_OUT_REMOTE_SUBMIX)) != 0
- || (isInput && (device & AUDIO_DEVICE_IN_REMOTE_SUBMIX) != 0)) {
- if (halAddress != NULL) {
- address->rSubmixAddress = halAddress;
- return OK;
- }
- return BAD_VALUE;
+ } else if (device == AUDIO_DEVICE_OUT_BUS || device == AUDIO_DEVICE_IN_BUS) {
+ address->busAddress = halAddress;
+ return OK;
+ } else if (device == AUDIO_DEVICE_OUT_REMOTE_SUBMIX
+ || device == AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
+ address->rSubmixAddress = halAddress;
+ return OK;
}
return OK;
}
@@ -100,8 +91,12 @@
DeviceHalHidl::~DeviceHalHidl() {
if (mDevice != 0) {
+#if MAJOR_VERSION <= 5
mDevice.clear();
hardware::IPCThreadState::self()->flushCommands();
+#elif MAJOR_VERSION >= 6
+ mDevice->close();
+#endif
}
}
diff --git a/media/libmedia/Android.bp b/media/libmedia/Android.bp
index ac88448..b064f08 100644
--- a/media/libmedia/Android.bp
+++ b/media/libmedia/Android.bp
@@ -34,7 +34,6 @@
"aidl/android/media/MediaResourceParcel.aidl",
"aidl/android/media/MediaResourcePolicyParcel.aidl",
],
- api_dir: "api/resourcemanager",
versions: ["1"],
}
diff --git a/media/libmedia/api/resourcemanager/1/.hash b/media/libmedia/aidl_api/resourcemanager_aidl_interface/.hash
similarity index 100%
rename from media/libmedia/api/resourcemanager/1/.hash
rename to media/libmedia/aidl_api/resourcemanager_aidl_interface/.hash
diff --git a/media/libmedia/api/resourcemanager/1/android/media/IResourceManagerClient.aidl b/media/libmedia/aidl_api/resourcemanager_aidl_interface/1/android/media/IResourceManagerClient.aidl
similarity index 100%
rename from media/libmedia/api/resourcemanager/1/android/media/IResourceManagerClient.aidl
rename to media/libmedia/aidl_api/resourcemanager_aidl_interface/1/android/media/IResourceManagerClient.aidl
diff --git a/media/libmedia/api/resourcemanager/1/android/media/IResourceManagerService.aidl b/media/libmedia/aidl_api/resourcemanager_aidl_interface/1/android/media/IResourceManagerService.aidl
similarity index 100%
rename from media/libmedia/api/resourcemanager/1/android/media/IResourceManagerService.aidl
rename to media/libmedia/aidl_api/resourcemanager_aidl_interface/1/android/media/IResourceManagerService.aidl
diff --git a/media/libmedia/api/resourcemanager/1/android/media/MediaResourceParcel.aidl b/media/libmedia/aidl_api/resourcemanager_aidl_interface/1/android/media/MediaResourceParcel.aidl
similarity index 100%
rename from media/libmedia/api/resourcemanager/1/android/media/MediaResourceParcel.aidl
rename to media/libmedia/aidl_api/resourcemanager_aidl_interface/1/android/media/MediaResourceParcel.aidl
diff --git a/media/libmedia/api/resourcemanager/1/android/media/MediaResourcePolicyParcel.aidl b/media/libmedia/aidl_api/resourcemanager_aidl_interface/1/android/media/MediaResourcePolicyParcel.aidl
similarity index 100%
rename from media/libmedia/api/resourcemanager/1/android/media/MediaResourcePolicyParcel.aidl
rename to media/libmedia/aidl_api/resourcemanager_aidl_interface/1/android/media/MediaResourcePolicyParcel.aidl
diff --git a/media/libmedia/api/resourcemanager/1/android/media/MediaResourceSubType.aidl b/media/libmedia/aidl_api/resourcemanager_aidl_interface/1/android/media/MediaResourceSubType.aidl
similarity index 100%
rename from media/libmedia/api/resourcemanager/1/android/media/MediaResourceSubType.aidl
rename to media/libmedia/aidl_api/resourcemanager_aidl_interface/1/android/media/MediaResourceSubType.aidl
diff --git a/media/libmedia/api/resourcemanager/1/android/media/MediaResourceType.aidl b/media/libmedia/aidl_api/resourcemanager_aidl_interface/1/android/media/MediaResourceType.aidl
similarity index 100%
rename from media/libmedia/api/resourcemanager/1/android/media/MediaResourceType.aidl
rename to media/libmedia/aidl_api/resourcemanager_aidl_interface/1/android/media/MediaResourceType.aidl
diff --git a/media/libmedia/include/media/PluginMetricsReporting.h b/media/libmedia/include/media/PluginMetricsReporting.h
index e00bd43..f71c52d 100644
--- a/media/libmedia/include/media/PluginMetricsReporting.h
+++ b/media/libmedia/include/media/PluginMetricsReporting.h
@@ -18,6 +18,7 @@
#define PLUGIN_METRICS_REPORTING_H_
+#include <sys/types.h>
#include <utils/Errors.h>
#include <utils/String8.h>
@@ -26,7 +27,7 @@
status_t reportDrmPluginMetrics(const std::string& b64EncodedMetrics,
const String8& vendorName,
const String8& description,
- const String8& appPackageName);
+ uid_t appUid);
} // namespace android
diff --git a/media/libmediaplayerservice/tests/Android.bp b/media/libmediaplayerservice/tests/Android.bp
index 8357925..e845c33 100644
--- a/media/libmediaplayerservice/tests/Android.bp
+++ b/media/libmediaplayerservice/tests/Android.bp
@@ -7,6 +7,7 @@
shared_libs: [
"liblog",
"libbinder",
+ "libbinder_ndk",
"libmedia",
"libmediaplayerservice",
"libmediadrm",
@@ -17,6 +18,10 @@
"android.hardware.drm@1.2",
],
+ static_libs: [
+ "resourcemanager_aidl_interface-ndk_platform",
+ ],
+
include_dirs: [
"frameworks/av/include",
"frameworks/av/services/mediaresourcemanager",
diff --git a/media/libmediaplayerservice/tests/DrmSessionManager_test.cpp b/media/libmediaplayerservice/tests/DrmSessionManager_test.cpp
index 262fe32..9a8ed8d 100644
--- a/media/libmediaplayerservice/tests/DrmSessionManager_test.cpp
+++ b/media/libmediaplayerservice/tests/DrmSessionManager_test.cpp
@@ -16,19 +16,21 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "DrmSessionManager_test"
+#include <android/binder_auto_utils.h>
#include <utils/Log.h>
#include <gtest/gtest.h>
+#include <aidl/android/media/BnResourceManagerClient.h>
+#include <aidl/android/media/BnResourceManagerService.h>
#include <android/media/BnResourceManagerClient.h>
-#include <android/media/IResourceManagerService.h>
+
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/ProcessInfoInterface.h>
-#include <mediadrm/DrmHal.h>
-#include <mediadrm/DrmSessionClientInterface.h>
#include <mediadrm/DrmSessionManager.h>
#include <algorithm>
+#include <iostream>
#include <vector>
#include "ResourceManagerService.h"
@@ -36,8 +38,109 @@
namespace android {
using ::android::binder::Status;
-using ::android::media::BnResourceManagerClient;
using ::android::media::ResourceManagerService;
+using ::ndk::ScopedAStatus;
+
+using NdkBnResourceManagerClient = ::aidl::android::media::BnResourceManagerClient;
+using NdkBnResourceManagerService = ::aidl::android::media::BnResourceManagerService;
+using NdkMediaResource = ::aidl::android::media::MediaResourceParcel;
+using NdkResourceManagerClient = ::aidl::android::media::IResourceManagerClient;
+
+using FwkBnResourceManagerClient = ::android::media::BnResourceManagerClient;
+using FwkMediaResource = ::android::media::MediaResourceParcel;
+
+namespace {
+
+struct FwkResourceManagerClientImpl : public FwkBnResourceManagerClient {
+ FwkResourceManagerClientImpl(const std::shared_ptr<NdkResourceManagerClient> &client)
+ : mClient(client) {
+ }
+
+ Status reclaimResource(bool* _aidl_return) override {
+ mClient->reclaimResource(_aidl_return);
+ return Status::ok();
+ }
+
+ Status getName(std::string* _aidl_return) override {
+ mClient->getName(_aidl_return);
+ return Status::ok();
+ }
+
+private:
+ std::shared_ptr<NdkResourceManagerClient> mClient;
+};
+
+FwkMediaResource NdkToFwkMediaResource(const NdkMediaResource &in) {
+ FwkMediaResource out{};
+ out.type = static_cast<decltype(out.type)>(in.type);
+ out.subType = static_cast<decltype(out.subType)>(in.subType);
+ auto v(reinterpret_cast<const uint8_t *>(in.id.data()));
+ out.id.assign(v, v + in.id.size());
+ out.value = in.value;
+ return out;
+}
+
+std::vector<FwkMediaResource> NdkToFwkMediaResourceVec(const std::vector<NdkMediaResource> &in) {
+ std::vector<FwkMediaResource> out;
+ for (auto e : in) {
+ out.push_back(NdkToFwkMediaResource(e));
+ }
+ return out;
+}
+
+ScopedAStatus FwkToNdkStatus(Status err) {
+ return ScopedAStatus(AStatus_fromExceptionCode(err.serviceSpecificErrorCode()));
+}
+
+struct NdkResourceManagerServiceImpl : public NdkBnResourceManagerService {
+ using NdkMediaResourcePolicy = ::aidl::android::media::MediaResourcePolicyParcel;
+
+ NdkResourceManagerServiceImpl(const sp<ResourceManagerService> &service)
+ : mService(service) {}
+
+ ScopedAStatus config(const std::vector<NdkMediaResourcePolicy>& in_policies) override {
+ (void)in_policies;
+ return ScopedAStatus::ok();
+ }
+
+ ScopedAStatus addResource(int32_t in_pid, int32_t in_uid, int64_t in_clientId,
+ const std::shared_ptr<NdkResourceManagerClient>& in_client,
+ const std::vector<NdkMediaResource>& in_resources) override {
+ sp<FwkBnResourceManagerClient> client(new FwkResourceManagerClientImpl(in_client));
+ std::vector<FwkMediaResource> resources(NdkToFwkMediaResourceVec(in_resources));
+ auto err = mService->addResource(in_pid, in_uid, in_clientId, client, resources);
+ return FwkToNdkStatus(err);
+ }
+
+ ScopedAStatus removeResource(int32_t in_pid, int64_t in_clientId,
+ const std::vector<NdkMediaResource>& in_resources) override {
+ std::vector<FwkMediaResource> resources(NdkToFwkMediaResourceVec(in_resources));
+ auto err = mService->removeResource(in_pid, in_clientId, resources);
+ return FwkToNdkStatus(err);
+ }
+
+ ScopedAStatus removeClient(int32_t in_pid, int64_t in_clientId) override{
+ auto err = mService->removeClient(in_pid, in_clientId);
+ return FwkToNdkStatus(err);
+ }
+
+ ScopedAStatus reclaimResource(int32_t in_callingPid,
+ const std::vector<NdkMediaResource>& in_resources, bool* _aidl_return) override {
+ std::vector<FwkMediaResource> resources(NdkToFwkMediaResourceVec(in_resources));
+ auto err = mService->reclaimResource(in_callingPid, resources, _aidl_return);
+ return FwkToNdkStatus(err);
+ }
+
+private:
+ sp<ResourceManagerService> mService;
+};
+
+template <typename Impl>
+std::shared_ptr<NdkResourceManagerClient> NdkImplToIface(const Impl &impl) {
+ return std::static_pointer_cast<NdkResourceManagerClient>(impl);
+}
+
+}
static Vector<uint8_t> toAndroidVector(const std::vector<uint8_t> &vec) {
Vector<uint8_t> aVec;
@@ -66,29 +169,27 @@
DISALLOW_EVIL_CONSTRUCTORS(FakeProcessInfo);
};
-struct FakeDrm : public BnResourceManagerClient {
+struct FakeDrm : public NdkBnResourceManagerClient {
FakeDrm(const std::vector<uint8_t>& sessionId, const sp<DrmSessionManager>& manager)
: mSessionId(toAndroidVector(sessionId)),
mReclaimed(false),
mDrmSessionManager(manager) {}
- virtual ~FakeDrm() {}
-
- Status reclaimResource(bool* _aidl_return) {
+ ScopedAStatus reclaimResource(bool* _aidl_return) {
mReclaimed = true;
mDrmSessionManager->removeSession(mSessionId);
*_aidl_return = true;
- return Status::ok();
+ return ScopedAStatus::ok();
}
- Status getName(::std::string* _aidl_return) {
+ ScopedAStatus getName(::std::string* _aidl_return) {
String8 name("FakeDrm[");
for (size_t i = 0; i < mSessionId.size(); ++i) {
name.appendFormat("%02x", mSessionId[i]);
}
name.append("]");
*_aidl_return = name;
- return Status::ok();
+ return ScopedAStatus::ok();
}
bool isReclaimed() const {
@@ -137,27 +238,24 @@
public:
DrmSessionManagerTest()
: mService(new ResourceManagerService(new FakeProcessInfo(), new FakeSystemCallback())),
- mDrmSessionManager(new DrmSessionManager(mService)),
+ mDrmSessionManager(new DrmSessionManager(std::shared_ptr<NdkBnResourceManagerService>(new NdkResourceManagerServiceImpl(mService)))),
mTestDrm1(new FakeDrm(kTestSessionId1, mDrmSessionManager)),
mTestDrm2(new FakeDrm(kTestSessionId2, mDrmSessionManager)),
mTestDrm3(new FakeDrm(kTestSessionId3, mDrmSessionManager)) {
- DrmSessionManager *ptr = new DrmSessionManager(mService);
- EXPECT_NE(ptr, nullptr);
- /* mDrmSessionManager = ptr; */
}
protected:
void addSession() {
- mDrmSessionManager->addSession(kTestPid1, mTestDrm1, mTestDrm1->mSessionId);
- mDrmSessionManager->addSession(kTestPid2, mTestDrm2, mTestDrm2->mSessionId);
- mDrmSessionManager->addSession(kTestPid2, mTestDrm3, mTestDrm3->mSessionId);
+ mDrmSessionManager->addSession(kTestPid1, NdkImplToIface(mTestDrm1), mTestDrm1->mSessionId);
+ mDrmSessionManager->addSession(kTestPid2, NdkImplToIface(mTestDrm2), mTestDrm2->mSessionId);
+ mDrmSessionManager->addSession(kTestPid2, NdkImplToIface(mTestDrm3), mTestDrm3->mSessionId);
}
- sp<IResourceManagerService> mService;
+ sp<ResourceManagerService> mService;
sp<DrmSessionManager> mDrmSessionManager;
- sp<FakeDrm> mTestDrm1;
- sp<FakeDrm> mTestDrm2;
- sp<FakeDrm> mTestDrm3;
+ std::shared_ptr<FakeDrm> mTestDrm1;
+ std::shared_ptr<FakeDrm> mTestDrm2;
+ std::shared_ptr<FakeDrm> mTestDrm3;
};
TEST_F(DrmSessionManagerTest, addSession) {
@@ -204,8 +302,8 @@
// add a session from a higher priority process.
const std::vector<uint8_t> sid{1, 3, 5};
- sp<FakeDrm> drm = new FakeDrm(sid, mDrmSessionManager);
- mDrmSessionManager->addSession(15, drm, drm->mSessionId);
+ std::shared_ptr<FakeDrm> drm(new FakeDrm(sid, mDrmSessionManager));
+ mDrmSessionManager->addSession(15, NdkImplToIface(drm), drm->mSessionId);
// make sure mTestDrm2 is reclaimed next instead of mTestDrm3
mDrmSessionManager->useSession(mTestDrm3->mSessionId);
@@ -225,9 +323,9 @@
EXPECT_FALSE(mDrmSessionManager->reclaimSession(kTestPid2));
// add sessions from same pid
- mDrmSessionManager->addSession(kTestPid2, mTestDrm1, mTestDrm1->mSessionId);
- mDrmSessionManager->addSession(kTestPid2, mTestDrm2, mTestDrm2->mSessionId);
- mDrmSessionManager->addSession(kTestPid2, mTestDrm3, mTestDrm3->mSessionId);
+ mDrmSessionManager->addSession(kTestPid2, NdkImplToIface(mTestDrm1), mTestDrm1->mSessionId);
+ mDrmSessionManager->addSession(kTestPid2, NdkImplToIface(mTestDrm2), mTestDrm2->mSessionId);
+ mDrmSessionManager->addSession(kTestPid2, NdkImplToIface(mTestDrm3), mTestDrm3->mSessionId);
// use some but not all sessions
mDrmSessionManager->useSession(mTestDrm1->mSessionId);
diff --git a/media/libstagefright/ACodecBufferChannel.cpp b/media/libstagefright/ACodecBufferChannel.cpp
index dd6f7b4..bf8f09c 100644
--- a/media/libstagefright/ACodecBufferChannel.cpp
+++ b/media/libstagefright/ACodecBufferChannel.cpp
@@ -21,6 +21,7 @@
#include <numeric>
#include <android/hardware/cas/native/1.0/IDescrambler.h>
+#include <android/hardware/drm/1.0/types.h>
#include <binder/MemoryDealer.h>
#include <hidlmemory/FrameworkUtils.h>
#include <media/openmax/OMX_Core.h>
@@ -41,6 +42,7 @@
using hardware::hidl_vec;
using namespace hardware::cas::V1_0;
using namespace hardware::cas::native::V1_0;
+using DrmBufferType = hardware::drm::V1_0::BufferType;
using BufferInfo = ACodecBufferChannel::BufferInfo;
using BufferInfoIterator = std::vector<const BufferInfo>::const_iterator;
@@ -131,18 +133,18 @@
ssize_t result = -1;
ssize_t codecDataOffset = 0;
if (mCrypto != NULL) {
- ICrypto::DestinationBuffer destination;
+ hardware::drm::V1_0::DestinationBuffer destination;
if (secure) {
- destination.mType = ICrypto::kDestinationTypeNativeHandle;
- destination.mHandle = secureHandle;
+ destination.type = DrmBufferType::NATIVE_HANDLE;
+ destination.secureMemory = hidl_handle(secureHandle);
} else {
- destination.mType = ICrypto::kDestinationTypeSharedMemory;
- destination.mSharedMemory = mDecryptDestination;
+ destination.type = DrmBufferType::SHARED_MEMORY;
+ IMemoryToSharedBuffer(
+ mDecryptDestination, mHeapSeqNum, &destination.nonsecureMemory);
}
- ICrypto::SourceBuffer source;
- source.mSharedMemory = it->mSharedEncryptedBuffer;
- source.mHeapSeqNum = mHeapSeqNum;
+ hardware::drm::V1_0::SharedBuffer source;
+ IMemoryToSharedBuffer(it->mSharedEncryptedBuffer, mHeapSeqNum, &source);
result = mCrypto->decrypt(key, iv, mode, pattern,
source, it->mClientBuffer->offset(),
@@ -152,9 +154,8 @@
return result;
}
- if (destination.mType == ICrypto::kDestinationTypeSharedMemory) {
- memcpy(it->mCodecBuffer->base(),
- destination.mSharedMemory->unsecurePointer(), result);
+ if (destination.type == DrmBufferType::SHARED_MEMORY) {
+ memcpy(it->mCodecBuffer->base(), mDecryptDestination->unsecurePointer(), result);
}
} else {
// Here we cast CryptoPlugin::SubSample to hardware::cas::native::V1_0::SubSample
@@ -315,7 +316,8 @@
}
dealer = new MemoryDealer(heapSize, "ACodecBufferChannel");
if (mCrypto != nullptr) {
- int32_t seqNum = mCrypto->setHeap(dealer->getMemoryHeap());
+ sp<HidlMemory> hHeap = fromHeap(dealer->getMemoryHeap());
+ int32_t seqNum = mCrypto->setHeap(hHeap);
if (seqNum >= 0) {
mHeapSeqNum = seqNum;
ALOGV("setHeap returned mHeapSeqNum=%d", mHeapSeqNum);
@@ -431,4 +433,12 @@
it->mClientBuffer);
}
+void ACodecBufferChannel::setCrypto(const sp<ICrypto> &crypto) {
+ mCrypto = crypto;
+}
+
+void ACodecBufferChannel::setDescrambler(const sp<IDescrambler> &descrambler) {
+ mDescrambler = descrambler;
+}
+
} // namespace android
diff --git a/media/libstagefright/Android.bp b/media/libstagefright/Android.bp
index afd5017..76eadf7 100644
--- a/media/libstagefright/Android.bp
+++ b/media/libstagefright/Android.bp
@@ -252,6 +252,7 @@
"libhidlmemory",
"android.hidl.allocator@1.0",
"android.hardware.cas.native@1.0",
+ "android.hardware.drm@1.0",
"android.hardware.media.omx@1.0",
],
diff --git a/media/libstagefright/CodecBase.cpp b/media/libstagefright/CodecBase.cpp
index 5765883..5b724aa 100644
--- a/media/libstagefright/CodecBase.cpp
+++ b/media/libstagefright/CodecBase.cpp
@@ -26,14 +26,6 @@
namespace android {
-void BufferChannelBase::setCrypto(const sp<ICrypto> &crypto) {
- mCrypto = crypto;
-}
-
-void BufferChannelBase::setDescrambler(const sp<IDescrambler> &descrambler) {
- mDescrambler = descrambler;
-}
-
void BufferChannelBase::IMemoryToSharedBuffer(
const sp<IMemory> &memory,
int32_t heapSeqNum,
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 14564c9..b043e31 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -955,37 +955,41 @@
mCodecInfo.clear();
bool secureCodec = false;
- AString tmp = name;
- if (tmp.endsWith(".secure")) {
- secureCodec = true;
- tmp.erase(tmp.size() - 7, 7);
- }
- const sp<IMediaCodecList> mcl = MediaCodecList::getInstance();
- if (mcl == NULL) {
- mCodec = NULL; // remove the codec.
- return NO_INIT; // if called from Java should raise IOException
- }
- for (const AString &codecName : { name, tmp }) {
- ssize_t codecIdx = mcl->findCodecByName(codecName.c_str());
- if (codecIdx < 0) {
- continue;
+ const char *owner = "";
+ if (!name.startsWith("android.filter.")) {
+ AString tmp = name;
+ if (tmp.endsWith(".secure")) {
+ secureCodec = true;
+ tmp.erase(tmp.size() - 7, 7);
}
- mCodecInfo = mcl->getCodecInfo(codecIdx);
- Vector<AString> mediaTypes;
- mCodecInfo->getSupportedMediaTypes(&mediaTypes);
- for (size_t i = 0; i < mediaTypes.size(); i++) {
- if (mediaTypes[i].startsWith("video/")) {
- mIsVideo = true;
- break;
+ const sp<IMediaCodecList> mcl = MediaCodecList::getInstance();
+ if (mcl == NULL) {
+ mCodec = NULL; // remove the codec.
+ return NO_INIT; // if called from Java should raise IOException
+ }
+ for (const AString &codecName : { name, tmp }) {
+ ssize_t codecIdx = mcl->findCodecByName(codecName.c_str());
+ if (codecIdx < 0) {
+ continue;
}
+ mCodecInfo = mcl->getCodecInfo(codecIdx);
+ Vector<AString> mediaTypes;
+ mCodecInfo->getSupportedMediaTypes(&mediaTypes);
+ for (size_t i = 0; i < mediaTypes.size(); i++) {
+ if (mediaTypes[i].startsWith("video/")) {
+ mIsVideo = true;
+ break;
+ }
+ }
+ break;
}
- break;
- }
- if (mCodecInfo == nullptr) {
- return NAME_NOT_FOUND;
+ if (mCodecInfo == nullptr) {
+ return NAME_NOT_FOUND;
+ }
+ owner = mCodecInfo->getOwnerName();
}
- mCodec = GetCodecBase(name, mCodecInfo->getOwnerName());
+ mCodec = GetCodecBase(name, owner);
if (mCodec == NULL) {
return NAME_NOT_FOUND;
}
@@ -1014,9 +1018,11 @@
new BufferCallback(new AMessage(kWhatCodecNotify, this))));
sp<AMessage> msg = new AMessage(kWhatInit, this);
- msg->setObject("codecInfo", mCodecInfo);
- // name may be different from mCodecInfo->getCodecName() if we stripped
- // ".secure"
+ if (mCodecInfo) {
+ msg->setObject("codecInfo", mCodecInfo);
+ // name may be different from mCodecInfo->getCodecName() if we stripped
+ // ".secure"
+ }
msg->setString("name", name);
if (mMetricsHandle != 0) {
@@ -2070,9 +2076,9 @@
mComponentName.c_str());
}
- const char *owner = mCodecInfo->getOwnerName();
+ const char *owner = mCodecInfo ? mCodecInfo->getOwnerName() : "";
if (mComponentName.startsWith("OMX.google.")
- && (owner == nullptr || strncmp(owner, "default", 8) == 0)) {
+ && strncmp(owner, "default", 8) == 0) {
mFlags |= kFlagUsesSoftwareRenderer;
} else {
mFlags &= ~kFlagUsesSoftwareRenderer;
@@ -2480,12 +2486,14 @@
setState(INITIALIZING);
sp<RefBase> codecInfo;
- CHECK(msg->findObject("codecInfo", &codecInfo));
+ (void)msg->findObject("codecInfo", &codecInfo);
AString name;
CHECK(msg->findString("name", &name));
sp<AMessage> format = new AMessage;
- format->setObject("codecInfo", codecInfo);
+ if (codecInfo) {
+ format->setObject("codecInfo", codecInfo);
+ }
format->setString("componentName", name);
mCodec->initiateAllocateComponent(format);
diff --git a/media/libstagefright/filters/MediaFilter.cpp b/media/libstagefright/filters/MediaFilter.cpp
index 777ab5b..c7baa73 100644
--- a/media/libstagefright/filters/MediaFilter.cpp
+++ b/media/libstagefright/filters/MediaFilter.cpp
@@ -20,13 +20,12 @@
#include <inttypes.h>
#include <utils/Trace.h>
-#include <binder/MemoryDealer.h>
-
-#include <media/stagefright/BufferProducerWrapper.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/BufferProducerWrapper.h>
+#include <media/stagefright/MediaCodecConstants.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MediaFilter.h>
@@ -42,11 +41,121 @@
#include "SaturationFilter.h"
#include "ZeroFilter.h"
-#include "../include/ACodecBufferChannel.h"
-#include "../include/SharedMemoryBuffer.h"
-
namespace android {
+class MediaFilter::BufferChannel : public BufferChannelBase {
+public:
+ BufferChannel(const sp<AMessage> &in, const sp<AMessage> &out)
+ : mInputBufferFilled(in), mOutputBufferDrained(out) {
+ }
+
+ ~BufferChannel() override = default;
+
+ // BufferChannelBase
+
+ status_t queueInputBuffer(const sp<MediaCodecBuffer> &buffer) override {
+ sp<AMessage> msg = mInputBufferFilled->dup();
+ msg->setObject("buffer", buffer);
+ msg->post();
+ return OK;
+ }
+
+ status_t queueSecureInputBuffer(
+ const sp<MediaCodecBuffer> &,
+ bool,
+ const uint8_t *,
+ const uint8_t *,
+ CryptoPlugin::Mode,
+ CryptoPlugin::Pattern,
+ const CryptoPlugin::SubSample *,
+ size_t,
+ AString *) override {
+ return INVALID_OPERATION;
+ }
+
+ status_t renderOutputBuffer(
+ const sp<MediaCodecBuffer> &buffer, int64_t /* timestampNs */) override {
+ sp<AMessage> msg = mOutputBufferDrained->dup();
+ msg->setObject("buffer", buffer);
+ msg->post();
+ return OK;
+ }
+
+ status_t discardBuffer(const sp<MediaCodecBuffer> &buffer) override {
+ if (FindBufferIndex(&mInputBuffers, buffer) >= 0) {
+ sp<AMessage> msg = mInputBufferFilled->dup();
+ msg->setObject("buffer", buffer);
+ msg->post();
+ return OK;
+ }
+ sp<AMessage> msg = mOutputBufferDrained->dup();
+ msg->setObject("buffer", buffer);
+ msg->post();
+ return OK;
+ }
+
+ void getInputBufferArray(Vector<sp<MediaCodecBuffer>> *array) {
+ if (!array) {
+ return;
+ }
+ array->clear();
+ array->appendVector(mInputBuffers);
+ }
+
+ void getOutputBufferArray(Vector<sp<MediaCodecBuffer>> *array) {
+ if (!array) {
+ return;
+ }
+ array->clear();
+ array->appendVector(mOutputBuffers);
+ }
+
+ // For MediaFilter
+
+ void fillThisBuffer(const sp<MediaCodecBuffer> &buffer) {
+ ssize_t index = FindBufferIndex(&mInputBuffers, buffer);
+ mCallback->onInputBufferAvailable(index, buffer);
+ }
+
+ void drainThisBuffer(const sp<MediaCodecBuffer> &buffer, int flags) {
+ ssize_t index = FindBufferIndex(&mOutputBuffers, buffer);
+ buffer->meta()->setInt32("flags", flags);
+ mCallback->onOutputBufferAvailable(index, buffer);
+ }
+
+ template <class T>
+ void setInputBuffers(T begin, T end) {
+ mInputBuffers.clear();
+ for (T it = begin; it != end; ++it) {
+ mInputBuffers.push_back(it->mData);
+ }
+ }
+
+ template <class T>
+ void setOutputBuffers(T begin, T end) {
+ mOutputBuffers.clear();
+ for (T it = begin; it != end; ++it) {
+ mOutputBuffers.push_back(it->mData);
+ }
+ }
+
+private:
+ sp<AMessage> mInputBufferFilled;
+ sp<AMessage> mOutputBufferDrained;
+ Vector<sp<MediaCodecBuffer>> mInputBuffers;
+ Vector<sp<MediaCodecBuffer>> mOutputBuffers;
+
+ static ssize_t FindBufferIndex(
+ Vector<sp<MediaCodecBuffer>> *array, const sp<MediaCodecBuffer> &buffer) {
+ for (size_t i = 0; i < array->size(); ++i) {
+ if (array->itemAt(i) == buffer) {
+ return i;
+ }
+ }
+ return -1;
+ }
+};
+
// parameter: number of input and output buffers
static const size_t kBufferCountActual = 4;
@@ -54,9 +163,6 @@
: mState(UNINITIALIZED),
mGeneration(0),
mGraphicBufferListener(NULL) {
- mBufferChannel = std::make_shared<ACodecBufferChannel>(
- new AMessage(kWhatInputBufferFilled, this),
- new AMessage(kWhatOutputBufferDrained, this));
}
MediaFilter::~MediaFilter() {
@@ -65,6 +171,11 @@
//////////////////// PUBLIC FUNCTIONS //////////////////////////////////////////
std::shared_ptr<BufferChannelBase> MediaFilter::getBufferChannel() {
+ if (!mBufferChannel) {
+ mBufferChannel = std::make_shared<BufferChannel>(
+ new AMessage(kWhatInputBufferFilled, this),
+ new AMessage(kWhatOutputBufferDrained, this));
+ }
return mBufferChannel;
}
@@ -212,28 +323,23 @@
const bool isInput = portIndex == kPortIndexInput;
const size_t bufferSize = isInput ? mMaxInputSize : mMaxOutputSize;
- CHECK(mDealer[portIndex] == NULL);
CHECK(mBuffers[portIndex].isEmpty());
ALOGV("Allocating %zu buffers of size %zu on %s port",
kBufferCountActual, bufferSize,
isInput ? "input" : "output");
- size_t totalSize = kBufferCountActual * bufferSize;
-
- mDealer[portIndex] = new MemoryDealer(totalSize, "MediaFilter");
-
+ // trigger output format change
+ sp<AMessage> outputFormat = mOutputFormat->dup();
for (size_t i = 0; i < kBufferCountActual; ++i) {
- sp<IMemory> mem = mDealer[portIndex]->allocate(bufferSize);
- CHECK(mem.get() != NULL);
-
BufferInfo info;
info.mStatus = BufferInfo::OWNED_BY_US;
info.mBufferID = i;
info.mGeneration = mGeneration;
info.mOutputFlags = 0;
- info.mData = new SharedMemoryBuffer(
- isInput ? mInputFormat : mOutputFormat, mem);
+ info.mData = new MediaCodecBuffer(
+ isInput ? mInputFormat : outputFormat,
+ new ABuffer(bufferSize));
info.mData->meta()->setInt64("timeUs", 0);
mBuffers[portIndex].push_back(info);
@@ -243,27 +349,24 @@
&mBuffers[portIndex].editItemAt(i));
}
}
-
- std::vector<ACodecBufferChannel::BufferAndId> array(mBuffers[portIndex].size());
- for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
- array[i] = {mBuffers[portIndex][i].mData, mBuffers[portIndex][i].mBufferID};
- }
- if (portIndex == kPortIndexInput) {
- mBufferChannel->setInputBufferArray(array);
+ if (isInput) {
+ mBufferChannel->setInputBuffers(
+ mBuffers[portIndex].begin(), mBuffers[portIndex].end());
} else {
- mBufferChannel->setOutputBufferArray(array);
+ mBufferChannel->setOutputBuffers(
+ mBuffers[portIndex].begin(), mBuffers[portIndex].end());
}
return OK;
}
-MediaFilter::BufferInfo* MediaFilter::findBufferByID(
- uint32_t portIndex, IOMX::buffer_id bufferID,
+MediaFilter::BufferInfo* MediaFilter::findBuffer(
+ uint32_t portIndex, const sp<MediaCodecBuffer> &buffer,
ssize_t *index) {
for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
- if (info->mBufferID == bufferID) {
+ if (info->mData == buffer) {
if (index != NULL) {
*index = i;
}
@@ -293,7 +396,7 @@
info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
- mBufferChannel->fillThisBuffer(info->mBufferID);
+ mBufferChannel->fillThisBuffer(info->mData);
}
void MediaFilter::postDrainThisBuffer(BufferInfo *info) {
@@ -304,7 +407,7 @@
sp<AMessage> reply = new AMessage(kWhatOutputBufferDrained, this);
reply->setInt32("buffer-id", info->mBufferID);
- mBufferChannel->drainThisBuffer(info->mBufferID, info->mOutputFlags);
+ mBufferChannel->drainThisBuffer(info->mData, info->mOutputFlags);
info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
}
@@ -359,7 +462,7 @@
outputInfo->mOutputFlags = 0;
int32_t eos = 0;
if (inputInfo->mData->meta()->findInt32("eos", &eos) && eos != 0) {
- outputInfo->mOutputFlags |= OMX_BUFFERFLAG_EOS;
+ outputInfo->mOutputFlags |= BUFFER_FLAG_END_OF_STREAM;
mPortEOS[kPortIndexOutput] = true;
outputInfo->mData->meta()->setInt32("eos", eos);
postEOS();
@@ -400,8 +503,7 @@
return;
}
- // HACK - need "OMX.google" to use MediaCodec's software renderer
- mCallback->onComponentAllocated("OMX.google.MediaFilter");
+ mCallback->onComponentAllocated(mComponentName.c_str());
mState = INITIALIZED;
ALOGV("Handled kWhatAllocateComponent.");
}
@@ -477,6 +579,7 @@
mOutputFormat->setRect("crop", 0, 0, mStride, mSliceHeight);
mOutputFormat->setInt32("width", mWidth);
mOutputFormat->setInt32("height", mHeight);
+ mOutputFormat->setInt32("using-sw-renderer", 1);
mCallback->onComponentConfigured(mInputFormat, mOutputFormat);
mState = CONFIGURED;
@@ -509,9 +612,11 @@
}
void MediaFilter::onInputBufferFilled(const sp<AMessage> &msg) {
- IOMX::buffer_id bufferID;
- CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
- BufferInfo *info = findBufferByID(kPortIndexInput, bufferID);
+ sp<RefBase> obj;
+ CHECK(msg->findObject("buffer", &obj));
+ sp<MediaCodecBuffer> buffer = static_cast<MediaCodecBuffer *>(obj.get());
+ ssize_t index = -1;
+ BufferInfo *info = findBuffer(kPortIndexInput, buffer, &index);
if (mState != STARTED) {
// we're not running, so we'll just keep that buffer...
@@ -520,7 +625,7 @@
}
if (info->mGeneration != mGeneration) {
- ALOGV("Caught a stale input buffer [ID %d]", bufferID);
+ ALOGV("Caught a stale input buffer [index %zd]", index);
// buffer is stale (taken before a flush/shutdown) - repost it
CHECK_EQ(info->mStatus, BufferInfo::OWNED_BY_US);
postFillThisBuffer(info);
@@ -530,30 +635,9 @@
CHECK_EQ(info->mStatus, BufferInfo::OWNED_BY_UPSTREAM);
info->mStatus = BufferInfo::OWNED_BY_US;
- sp<MediaCodecBuffer> buffer;
int32_t err = OK;
bool eos = false;
- sp<RefBase> obj;
- if (!msg->findObject("buffer", &obj)) {
- // these are unfilled buffers returned by client
- CHECK(msg->findInt32("err", &err));
-
- if (err == OK) {
- // buffers with no errors are returned on MediaCodec.flush
- ALOGV("saw unfilled buffer (MediaCodec.flush)");
- postFillThisBuffer(info);
- return;
- } else {
- ALOGV("saw error %d instead of an input buffer", err);
- eos = true;
- }
-
- buffer.clear();
- } else {
- buffer = static_cast<MediaCodecBuffer *>(obj.get());
- }
-
int32_t isCSD;
if (buffer != NULL && buffer->meta()->findInt32("csd", &isCSD)
&& isCSD != 0) {
@@ -577,13 +661,15 @@
mInputEOSResult = err;
}
- ALOGV("Handled kWhatInputBufferFilled. [ID %u]", bufferID);
+ ALOGV("Handled kWhatInputBufferFilled. [index %zd]", index);
}
void MediaFilter::onOutputBufferDrained(const sp<AMessage> &msg) {
- IOMX::buffer_id bufferID;
- CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
- BufferInfo *info = findBufferByID(kPortIndexOutput, bufferID);
+ sp<RefBase> obj;
+ CHECK(msg->findObject("buffer", &obj));
+ sp<MediaCodecBuffer> buffer = static_cast<MediaCodecBuffer *>(obj.get());
+ ssize_t index = -1;
+ BufferInfo *info = findBuffer(kPortIndexOutput, buffer, &index);
if (mState != STARTED) {
// we're not running, so we'll just keep that buffer...
@@ -592,7 +678,7 @@
}
if (info->mGeneration != mGeneration) {
- ALOGV("Caught a stale output buffer [ID %d]", bufferID);
+ ALOGV("Caught a stale output buffer [index %zd]", index);
// buffer is stale (taken before a flush/shutdown) - keep it
CHECK_EQ(info->mStatus, BufferInfo::OWNED_BY_US);
return;
@@ -605,8 +691,7 @@
processBuffers();
- ALOGV("Handled kWhatOutputBufferDrained. [ID %u]",
- bufferID);
+ ALOGV("Handled kWhatOutputBufferDrained. [index %zd]", index);
}
void MediaFilter::onShutdown(const sp<AMessage> &msg) {
@@ -739,7 +824,7 @@
return;
}
- eosBuf->mOutputFlags = OMX_BUFFERFLAG_EOS;
+ eosBuf->mOutputFlags = BUFFER_FLAG_END_OF_STREAM;
eosBuf->mGeneration = mGeneration;
eosBuf->mData->setRange(0, 0);
postDrainThisBuffer(eosBuf);
diff --git a/media/libstagefright/foundation/TEST_MAPPING b/media/libstagefright/foundation/TEST_MAPPING
new file mode 100644
index 0000000..3301c4b
--- /dev/null
+++ b/media/libstagefright/foundation/TEST_MAPPING
@@ -0,0 +1,5 @@
+{
+ "presubmit": [
+ { "name": "sf_foundation_test" }
+ ]
+}
diff --git a/media/libstagefright/foundation/tests/Android.bp b/media/libstagefright/foundation/tests/Android.bp
new file mode 100644
index 0000000..f2157c9
--- /dev/null
+++ b/media/libstagefright/foundation/tests/Android.bp
@@ -0,0 +1,27 @@
+cc_test {
+ name: "sf_foundation_test",
+ test_suites: ["device-tests"],
+
+ cflags: [
+ "-Werror",
+ "-Wall",
+ ],
+
+ include_dirs: [
+ "frameworks/av/include",
+ ],
+
+ shared_libs: [
+ "liblog",
+ "libstagefright_foundation",
+ "libutils",
+ ],
+
+ srcs: [
+ "AData_test.cpp",
+ "Base64_test.cpp",
+ "Flagged_test.cpp",
+ "TypeTraits_test.cpp",
+ "Utils_test.cpp",
+ ],
+}
diff --git a/media/libstagefright/foundation/tests/Android.mk b/media/libstagefright/foundation/tests/Android.mk
deleted file mode 100644
index a9e3c76..0000000
--- a/media/libstagefright/foundation/tests/Android.mk
+++ /dev/null
@@ -1,37 +0,0 @@
-# Build the unit tests.
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
-
-LOCAL_MODULE := sf_foundation_test
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_SRC_FILES := \
- AData_test.cpp \
- Base64_test.cpp \
- Flagged_test.cpp \
- TypeTraits_test.cpp \
- Utils_test.cpp \
-
-LOCAL_SHARED_LIBRARIES := \
- liblog \
- libstagefright_foundation \
- libutils \
-
-LOCAL_C_INCLUDES := \
- frameworks/av/include \
-
-LOCAL_CFLAGS += -Werror -Wall
-LOCAL_CLANG := true
-
-include $(BUILD_NATIVE_TEST)
-
-# Include subdirectory makefiles
-# ============================================================
-
-# If we're building with ONE_SHOT_MAKEFILE (mm, mmm), then what the framework
-# team really wants is to build the stuff defined by this makefile.
-ifeq (,$(ONE_SHOT_MAKEFILE))
-include $(call first-makefiles-under,$(LOCAL_PATH))
-endif
diff --git a/media/libstagefright/include/ACodecBufferChannel.h b/media/libstagefright/include/ACodecBufferChannel.h
index 3a087d1..5f65575 100644
--- a/media/libstagefright/include/ACodecBufferChannel.h
+++ b/media/libstagefright/include/ACodecBufferChannel.h
@@ -67,6 +67,9 @@
virtual ~ACodecBufferChannel();
// BufferChannelBase interface
+ void setCrypto(const sp<ICrypto> &crypto) override;
+ void setDescrambler(const sp<IDescrambler> &descrambler) override;
+
virtual status_t queueInputBuffer(const sp<MediaCodecBuffer> &buffer) override;
virtual status_t queueSecureInputBuffer(
const sp<MediaCodecBuffer> &buffer,
@@ -135,6 +138,9 @@
sp<MemoryDealer> makeMemoryDealer(size_t heapSize);
+ sp<ICrypto> mCrypto;
+ sp<IDescrambler> mDescrambler;
+
bool hasCryptoOrDescrambler() {
return mCrypto != NULL || mDescrambler != NULL;
}
diff --git a/media/libstagefright/include/media/stagefright/CodecBase.h b/media/libstagefright/include/media/stagefright/CodecBase.h
index e728c00..bc7881c 100644
--- a/media/libstagefright/include/media/stagefright/CodecBase.h
+++ b/media/libstagefright/include/media/stagefright/CodecBase.h
@@ -257,15 +257,15 @@
*/
class BufferChannelBase {
public:
+ BufferChannelBase() = default;
virtual ~BufferChannelBase() = default;
inline void setCallback(std::unique_ptr<CodecBase::BufferCallback> &&callback) {
mCallback = std::move(callback);
}
- void setCrypto(const sp<ICrypto> &crypto);
-
- void setDescrambler(const sp<IDescrambler> &descrambler);
+ virtual void setCrypto(const sp<ICrypto> &) {}
+ virtual void setDescrambler(const sp<IDescrambler> &) {}
/**
* Queue an input buffer into the buffer channel.
@@ -336,8 +336,6 @@
protected:
std::unique_ptr<CodecBase::BufferCallback> mCallback;
- sp<ICrypto> mCrypto;
- sp<IDescrambler> mDescrambler;
};
} // namespace android
diff --git a/media/libstagefright/include/media/stagefright/MediaFilter.h b/media/libstagefright/include/media/stagefright/MediaFilter.h
index a28c49d..1255e0f 100644
--- a/media/libstagefright/include/media/stagefright/MediaFilter.h
+++ b/media/libstagefright/include/media/stagefright/MediaFilter.h
@@ -21,9 +21,7 @@
namespace android {
-class ACodecBufferChannel;
struct GraphicBufferListener;
-class MemoryDealer;
struct SimpleFilter;
struct MediaFilter : public CodecBase {
@@ -65,6 +63,8 @@
sp<MediaCodecBuffer> mData;
};
+ class BufferChannel;
+
enum State {
UNINITIALIZED,
INITIALIZED,
@@ -104,7 +104,6 @@
sp<AMessage> mInputFormat;
sp<AMessage> mOutputFormat;
- sp<MemoryDealer> mDealer[2];
Vector<BufferInfo> mBuffers[2];
Vector<BufferInfo*> mAvailableInputBuffers;
Vector<BufferInfo*> mAvailableOutputBuffers;
@@ -113,15 +112,15 @@
sp<SimpleFilter> mFilter;
sp<GraphicBufferListener> mGraphicBufferListener;
- std::shared_ptr<ACodecBufferChannel> mBufferChannel;
+ std::shared_ptr<BufferChannel> mBufferChannel;
// helper functions
void signalProcessBuffers();
void signalError(status_t error);
status_t allocateBuffersOnPort(OMX_U32 portIndex);
- BufferInfo *findBufferByID(
- uint32_t portIndex, uint32_t bufferID,
+ BufferInfo *findBuffer(
+ uint32_t portIndex, const sp<MediaCodecBuffer> &buffer,
ssize_t *index = NULL);
void postFillThisBuffer(BufferInfo *info);
void postDrainThisBuffer(BufferInfo *info);
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index cb1ef7f..53e2dd5 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -168,6 +168,7 @@
if (hwDevice != 0) {
hwDevice->releaseAudioPatch(removedPatch.mHalHandle);
}
+ halHandle = removedPatch.mHalHandle;
}
mPatches.erase(iter);
removeSoftwarePatchFromInsertedModules(*handle);
diff --git a/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp b/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
index 80df7db..5c6c518 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
+++ b/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
@@ -139,7 +139,9 @@
mOutputSlots.clear();
mConsumerBufferCount.clear();
- mConsumer->consumerDisconnect();
+ if (mConsumer.get() != nullptr) {
+ mConsumer->consumerDisconnect();
+ }
if (mBuffers.size() > 0) {
SP_LOGW("%zu buffers still being tracked", mBuffers.size());
diff --git a/services/mediadrm/Android.mk b/services/mediadrm/Android.mk
deleted file mode 100644
index 72d42ae..0000000
--- a/services/mediadrm/Android.mk
+++ /dev/null
@@ -1,53 +0,0 @@
-# Copyright 2014 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.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- MediaDrmService.cpp \
- main_mediadrmserver.cpp
-
-LOCAL_HEADER_LIBRARIES:= \
- libmedia_headers \
- libmediadrm_headers
-
-LOCAL_SHARED_LIBRARIES:= \
- libbinder \
- liblog \
- libmedia \
- libmediadrm \
- libutils \
- libhidlbase \
- libhidlmemory \
- android.hardware.drm@1.0 \
- android.hardware.drm@1.1 \
- android.hardware.drm@1.2
-
-LOCAL_CFLAGS += -Wall -Wextra -Werror
-
-LOCAL_MODULE:= mediadrmserver
-
-# TODO: Some legacy DRM plugins only support 32-bit. They need to be migrated to
-# 64-bit. (b/18948909) Once all of a device's legacy DRM plugins support 64-bit,
-# that device can turn on TARGET_ENABLE_MEDIADRM_64 to build this service as
-# 64-bit.
-ifneq ($(TARGET_ENABLE_MEDIADRM_64), true)
-LOCAL_32_BIT_ONLY := true
-endif
-
-LOCAL_INIT_RC := mediadrmserver.rc
-
-include $(BUILD_EXECUTABLE)
diff --git a/services/mediadrm/MediaDrmService.cpp b/services/mediadrm/MediaDrmService.cpp
deleted file mode 100644
index 3cee88b..0000000
--- a/services/mediadrm/MediaDrmService.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
-**
-** Copyright 2008, 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.
-*/
-
-// Proxy for media player implementations
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "MediaDrmService"
-
-#include "MediaDrmService.h"
-#include <binder/IServiceManager.h>
-#include <utils/Log.h>
-
-#include <mediadrm/CryptoHal.h>
-#include <mediadrm/DrmHal.h>
-
-namespace android {
-
-void MediaDrmService::instantiate() {
- defaultServiceManager()->addService(
- String16("media.drm"), new MediaDrmService());
-}
-
-} // namespace android
diff --git a/services/mediadrm/MediaDrmService.h b/services/mediadrm/MediaDrmService.h
deleted file mode 100644
index 8a11e36..0000000
--- a/services/mediadrm/MediaDrmService.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
-**
-** Copyright 2008, 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.
-*/
-
-#ifndef ANDROID_MEDIADRMSERVICE_H
-#define ANDROID_MEDIADRMSERVICE_H
-
-#include <arpa/inet.h>
-
-#include <utils/threads.h>
-
-#include <media/Metadata.h>
-#include <media/stagefright/foundation/ABase.h>
-#include <mediadrm/IMediaDrmService.h>
-
-namespace android {
-
-class MediaDrmService : public BnMediaDrmService
-{
-public:
- static void instantiate();
-
-private:
- MediaDrmService() {}
- virtual ~MediaDrmService() {}
-};
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_MEDIADRMSERVICE_H
diff --git a/services/mediadrm/OWNERS b/services/mediadrm/OWNERS
deleted file mode 100644
index 6d3b533..0000000
--- a/services/mediadrm/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-jtinker@google.com
-marcone@google.com
diff --git a/services/mediadrm/main_mediadrmserver.cpp b/services/mediadrm/main_mediadrmserver.cpp
deleted file mode 100644
index b767b8c..0000000
--- a/services/mediadrm/main_mediadrmserver.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
-**
-** Copyright 2008, 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.
-*/
-
-#define LOG_TAG "mediaserver"
-//#define LOG_NDEBUG 0
-
-#include <fcntl.h>
-#include <sys/prctl.h>
-#include <sys/wait.h>
-#include <binder/IPCThreadState.h>
-#include <binder/ProcessState.h>
-#include <binder/IServiceManager.h>
-#include <cutils/properties.h>
-#include <utils/Log.h>
-#include "MediaDrmService.h"
-
-using namespace android;
-
-int main()
-{
- signal(SIGPIPE, SIG_IGN);
-
- sp<ProcessState> proc(ProcessState::self());
- sp<IServiceManager> sm = defaultServiceManager();
- ALOGI("ServiceManager: %p", sm.get());
- MediaDrmService::instantiate();
- ProcessState::self()->startThreadPool();
- IPCThreadState::self()->joinThreadPool();
-}
diff --git a/services/mediadrm/mediadrmserver.rc b/services/mediadrm/mediadrmserver.rc
deleted file mode 100644
index 359c2cf..0000000
--- a/services/mediadrm/mediadrmserver.rc
+++ /dev/null
@@ -1,6 +0,0 @@
-service mediadrm /system/bin/mediadrmserver
- class main
- user media
- group mediadrm drmrpc
- ioprio rt 4
- writepid /dev/cpuset/foreground/tasks
diff --git a/tools/OWNERS b/tools/OWNERS
deleted file mode 100644
index f9cb567..0000000
--- a/tools/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-gkasten@google.com
diff --git a/tools/resampler_tools/Android.bp b/tools/resampler_tools/Android.bp
deleted file mode 100644
index 7549359..0000000
--- a/tools/resampler_tools/Android.bp
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2005 The Android Open Source Project
-//
-// Android.mk for resampler_tools
-//
-
-cc_binary_host {
- name: "fir",
-
- srcs: ["fir.cpp"],
-
- cflags: [
- "-Werror",
- "-Wall",
- ],
-}
diff --git a/tools/resampler_tools/OWNERS b/tools/resampler_tools/OWNERS
deleted file mode 100644
index b4a6798..0000000
--- a/tools/resampler_tools/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-hunga@google.com
diff --git a/tools/resampler_tools/fir.cpp b/tools/resampler_tools/fir.cpp
deleted file mode 100644
index fe4d212..0000000
--- a/tools/resampler_tools/fir.cpp
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * Copyright (C) 2007 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 <math.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-
-static inline double sinc(double x) {
- if (fabs(x) == 0.0f) return 1.0f;
- return sin(x) / x;
-}
-
-static inline double sqr(double x) {
- return x*x;
-}
-
-static inline int64_t toint(double x, int64_t maxval) {
- int64_t v;
-
- v = static_cast<int64_t>(floor(x * maxval + 0.5));
- if (v >= maxval) {
- return maxval - 1; // error!
- }
- return v;
-}
-
-static double I0(double x) {
- // from the Numerical Recipes in C p. 237
- double ax,ans,y;
- ax=fabs(x);
- if (ax < 3.75) {
- y=x/3.75;
- y*=y;
- ans=1.0+y*(3.5156229+y*(3.0899424+y*(1.2067492
- +y*(0.2659732+y*(0.360768e-1+y*0.45813e-2)))));
- } else {
- y=3.75/ax;
- ans=(exp(ax)/sqrt(ax))*(0.39894228+y*(0.1328592e-1
- +y*(0.225319e-2+y*(-0.157565e-2+y*(0.916281e-2
- +y*(-0.2057706e-1+y*(0.2635537e-1+y*(-0.1647633e-1
- +y*0.392377e-2))))))));
- }
- return ans;
-}
-
-static double kaiser(int k, int N, double beta) {
- if (k < 0 || k > N)
- return 0;
- return I0(beta * sqrt(1.0 - sqr((2.0*k)/N - 1.0))) / I0(beta);
-}
-
-static void usage(char* name) {
- fprintf(stderr,
- "usage: %s [-h] [-d] [-D] [-s sample_rate] [-c cut-off_frequency] [-n half_zero_crossings]"
- " [-f {float|fixed|fixed16}] [-b beta] [-v dBFS] [-l lerp]\n"
- " %s [-h] [-d] [-D] [-s sample_rate] [-c cut-off_frequency] [-n half_zero_crossings]"
- " [-f {float|fixed|fixed16}] [-b beta] [-v dBFS] -p M/N\n"
- " -h this help message\n"
- " -d debug, print comma-separated coefficient table\n"
- " -D generate extra declarations\n"
- " -p generate poly-phase filter coefficients, with sample increment M/N\n"
- " -s sample rate (48000)\n"
- " -c cut-off frequency (20478)\n"
- " -n number of zero-crossings on one side (8)\n"
- " -l number of lerping bits (4)\n"
- " -m number of polyphases (related to -l, default 16)\n"
- " -f output format, can be fixed, fixed16, or float (fixed)\n"
- " -b kaiser window parameter beta (7.865 [-80dB])\n"
- " -v attenuation in dBFS (0)\n",
- name, name
- );
- exit(0);
-}
-
-int main(int argc, char** argv)
-{
- // nc is the number of bits to store the coefficients
- int nc = 32;
- bool polyphase = false;
- unsigned int polyM = 160;
- unsigned int polyN = 147;
- bool debug = false;
- double Fs = 48000;
- double Fc = 20478;
- double atten = 1;
- int format = 0; // 0=fixed, 1=float
- bool declarations = false;
-
- // in order to keep the errors associated with the linear
- // interpolation of the coefficients below the quantization error
- // we must satisfy:
- // 2^nz >= 2^(nc/2)
- //
- // for 16 bit coefficients that would be 256
- //
- // note that increasing nz only increases memory requirements,
- // but doesn't increase the amount of computation to do.
- //
- //
- // see:
- // Smith, J.O. Digital Audio Resampling Home Page
- // https://ccrma.stanford.edu/~jos/resample/, 2011-03-29
- //
-
- // | 0.1102*(A - 8.7) A > 50
- // beta = | 0.5842*(A - 21)^0.4 + 0.07886*(A - 21) 21 <= A <= 50
- // | 0 A < 21
- // with A is the desired stop-band attenuation in dBFS
- //
- // for eg:
- //
- // 30 dB 2.210
- // 40 dB 3.384
- // 50 dB 4.538
- // 60 dB 5.658
- // 70 dB 6.764
- // 80 dB 7.865
- // 90 dB 8.960
- // 100 dB 10.056
- double beta = 7.865;
-
- // 2*nzc = (A - 8) / (2.285 * dw)
- // with dw the transition width = 2*pi*dF/Fs
- //
- int nzc = 8;
-
- /*
- * Example:
- * 44.1 KHz to 48 KHz resampling
- * 100 dB rejection above 28 KHz
- * (the spectrum will fold around 24 KHz and we want 100 dB rejection
- * at the point where the folding reaches 20 KHz)
- * ...___|_____
- * | \|
- * | ____/|\____
- * |/alias| \
- * ------/------+------\---------> KHz
- * 20 24 28
- *
- * Transition band 8 KHz, or dw = 1.0472
- *
- * beta = 10.056
- * nzc = 20
- */
-
- int M = 1 << 4; // number of phases for interpolation
- int ch;
- while ((ch = getopt(argc, argv, ":hds:c:n:f:l:m:b:p:v:z:D")) != -1) {
- switch (ch) {
- case 'd':
- debug = true;
- break;
- case 'D':
- declarations = true;
- break;
- case 'p':
- if (sscanf(optarg, "%u/%u", &polyM, &polyN) != 2) {
- usage(argv[0]);
- }
- polyphase = true;
- break;
- case 's':
- Fs = atof(optarg);
- break;
- case 'c':
- Fc = atof(optarg);
- break;
- case 'n':
- nzc = atoi(optarg);
- break;
- case 'm':
- M = atoi(optarg);
- break;
- case 'l':
- M = 1 << atoi(optarg);
- break;
- case 'f':
- if (!strcmp(optarg, "fixed")) {
- format = 0;
- }
- else if (!strcmp(optarg, "fixed16")) {
- format = 0;
- nc = 16;
- }
- else if (!strcmp(optarg, "float")) {
- format = 1;
- }
- else {
- usage(argv[0]);
- }
- break;
- case 'b':
- beta = atof(optarg);
- break;
- case 'v':
- atten = pow(10, -fabs(atof(optarg))*0.05 );
- break;
- case 'h':
- default:
- usage(argv[0]);
- break;
- }
- }
-
- // cut off frequency ratio Fc/Fs
- double Fcr = Fc / Fs;
-
- // total number of coefficients (one side)
-
- const int N = M * nzc;
-
- // lerp (which is most useful if M is a power of 2)
-
- int nz = 0; // recalculate nz as the bits needed to represent M
- for (int i = M-1 ; i; i>>=1, nz++);
- // generate the right half of the filter
- if (!debug) {
- printf("// cmd-line:");
- for (int i=0 ; i<argc ; i++) {
- printf(" %s", argv[i]);
- }
- printf("\n");
- if (declarations) {
- if (!polyphase) {
- printf("const int32_t RESAMPLE_FIR_SIZE = %d;\n", N);
- printf("const int32_t RESAMPLE_FIR_INT_PHASES = %d;\n", M);
- printf("const int32_t RESAMPLE_FIR_NUM_COEF = %d;\n", nzc);
- } else {
- printf("const int32_t RESAMPLE_FIR_SIZE = %d;\n", 2*nzc*polyN);
- printf("const int32_t RESAMPLE_FIR_NUM_COEF = %d;\n", 2*nzc);
- }
- if (!format) {
- printf("const int32_t RESAMPLE_FIR_COEF_BITS = %d;\n", nc);
- }
- printf("\n");
- printf("static %s resampleFIR[] = {", !format ? "int32_t" : "float");
- }
- }
-
- if (!polyphase) {
- for (int i=0 ; i<=M ; i++) { // an extra set of coefs for interpolation
- for (int j=0 ; j<nzc ; j++) {
- int ix = j*M + i;
- double x = (2.0 * M_PI * ix * Fcr) / M;
- double y = kaiser(ix+N, 2*N, beta) * sinc(x) * 2.0 * Fcr;
- y *= atten;
-
- if (!debug) {
- if (j == 0)
- printf("\n ");
- }
- if (!format) {
- int64_t yi = toint(y, 1ULL<<(nc-1));
- if (nc > 16) {
- printf("0x%08x,", int32_t(yi));
- } else {
- printf("0x%04x,", int32_t(yi)&0xffff);
- }
- } else {
- printf("%.9g%s", y, debug ? "," : "f,");
- }
- if (j != nzc-1) {
- printf(" ");
- }
- }
- }
- } else {
- for (unsigned int j=0 ; j<polyN ; j++) {
- // calculate the phase
- double p = ((polyM*j) % polyN) / double(polyN);
- if (!debug) printf("\n ");
- else printf("\n");
- // generate a FIR per phase
- for (int i=-nzc ; i<nzc ; i++) {
- double x = 2.0 * M_PI * Fcr * (i + p);
- double y = kaiser(i+N, 2*N, beta) * sinc(x) * 2.0 * Fcr;;
- y *= atten;
- if (!format) {
- int64_t yi = toint(y, 1ULL<<(nc-1));
- if (nc > 16) {
- printf("0x%08x,", int32_t(yi));
- } else {
- printf("0x%04x,", int32_t(yi)&0xffff);
- }
- } else {
- printf("%.9g%s", y, debug ? "," : "f,");
- }
-
- if (i != nzc-1) {
- printf(" ");
- }
- }
- }
- }
-
- if (!debug && declarations) {
- printf("\n};");
- }
- printf("\n");
- return 0;
-}
-
-// http://www.csee.umbc.edu/help/sound/AFsp-V2R1/html/audio/ResampAudio.html