Merge "hdr10+: profile level report"
diff --git a/apex/Android.bp b/apex/Android.bp
index 604b268..51e4c23 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -27,6 +27,8 @@
"libmpeg2extractor",
"liboggextractor",
"libwavextractor",
+ // MediaPlayer2
+ "libmediaplayer2_jni",
],
key: "com.android.media.key",
}
diff --git a/camera/ndk/Android.bp b/camera/ndk/Android.bp
index 60c9f85..d96f403 100644
--- a/camera/ndk/Android.bp
+++ b/camera/ndk/Android.bp
@@ -137,6 +137,7 @@
shared_libs: [
"libhwbinder",
"libcamera2ndk_vendor",
+ "libcamera_metadata",
"libmediandk",
"libnativewindow",
"libutils",
@@ -144,6 +145,9 @@
"libcutils",
"liblog",
],
+ static_libs: [
+ "android.hardware.camera.common@1.0-helper",
+ ],
cflags: [
"-D__ANDROID_VNDK__",
],
diff --git a/camera/ndk/NdkCameraCaptureSession.cpp b/camera/ndk/NdkCameraCaptureSession.cpp
index 540d84e..ab796fb 100644
--- a/camera/ndk/NdkCameraCaptureSession.cpp
+++ b/camera/ndk/NdkCameraCaptureSession.cpp
@@ -80,7 +80,9 @@
if (session->isClosed()) {
ALOGE("%s: session %p is already closed", __FUNCTION__, session);
- *captureSequenceId = CAPTURE_SEQUENCE_ID_NONE;
+ if (captureSequenceId != nullptr) {
+ *captureSequenceId = CAPTURE_SEQUENCE_ID_NONE;
+ }
return ACAMERA_ERROR_SESSION_CLOSED;
}
diff --git a/camera/ndk/ndk_vendor/impl/ACameraManager.cpp b/camera/ndk/ndk_vendor/impl/ACameraManager.cpp
index f395b44..575ee9d 100644
--- a/camera/ndk/ndk_vendor/impl/ACameraManager.cpp
+++ b/camera/ndk/ndk_vendor/impl/ACameraManager.cpp
@@ -34,7 +34,10 @@
namespace android {
namespace acam {
-using CameraStatusAndId = frameworks::cameraservice::service::V2_0::CameraStatusAndId;
+using frameworks::cameraservice::service::V2_0::CameraStatusAndId;
+using frameworks::cameraservice::common::V2_0::ProviderIdAndVendorTagSections;
+using android::hardware::camera::common::V1_0::helper::VendorTagDescriptor;
+using android::hardware::camera::common::V1_0::helper::VendorTagDescriptorCache;
// Static member definitions
const char* CameraManagerGlobal::kCameraIdKey = "CameraId";
@@ -43,6 +46,104 @@
Mutex CameraManagerGlobal::sLock;
CameraManagerGlobal* CameraManagerGlobal::sInstance = nullptr;
+/**
+ * The vendor tag descriptor class that takes HIDL vendor tag information as
+ * input. Not part of vendor available VendorTagDescriptor class because that class is used by
+ * default HAL implementation code as well.
+ */
+class HidlVendorTagDescriptor : public VendorTagDescriptor {
+public:
+ /**
+ * Create a VendorTagDescriptor object from the HIDL VendorTagSection
+ * vector.
+ *
+ * Returns OK on success, or a negative error code.
+ */
+ static status_t createDescriptorFromHidl(const hidl_vec<VendorTagSection>& vts,
+ /*out*/ sp<VendorTagDescriptor> *descriptor);
+};
+
+status_t HidlVendorTagDescriptor::createDescriptorFromHidl(const hidl_vec<VendorTagSection> &vts,
+ sp<VendorTagDescriptor> *descriptor) {
+ int tagCount = 0;
+
+ for (size_t s = 0; s < vts.size(); s++) {
+ tagCount += vts[s].tags.size();
+ }
+
+ if (tagCount < 0 || tagCount > INT32_MAX) {
+ ALOGE("%s: tag count %d from vendor tag sections is invalid.", __FUNCTION__, tagCount);
+ return BAD_VALUE;
+ }
+
+ Vector<uint32_t> tagArray;
+ LOG_ALWAYS_FATAL_IF(tagArray.resize(tagCount) != tagCount,
+ "%s: too many (%u) vendor tags defined.", __FUNCTION__, tagCount);
+
+ sp<HidlVendorTagDescriptor> desc = new HidlVendorTagDescriptor();
+ desc->mTagCount = tagCount;
+
+ KeyedVector<uint32_t, String8> tagToSectionMap;
+
+ int idx = 0;
+ for (size_t s = 0; s < vts.size(); s++) {
+ const VendorTagSection& section = vts[s];
+ const char *sectionName = section.sectionName.c_str();
+ if (sectionName == NULL) {
+ ALOGE("%s: no section name defined for vendor tag section %zu.", __FUNCTION__, s);
+ return BAD_VALUE;
+ }
+ String8 sectionString(sectionName);
+ desc->mSections.add(sectionString);
+
+ for (size_t j = 0; j < section.tags.size(); j++) {
+ uint32_t tag = section.tags[j].tagId;
+ if (tag < CAMERA_METADATA_VENDOR_TAG_BOUNDARY) {
+ ALOGE("%s: vendor tag %d not in vendor tag section.", __FUNCTION__, tag);
+ return BAD_VALUE;
+ }
+
+ tagArray.editItemAt(idx++) = section.tags[j].tagId;
+
+ const char *tagName = section.tags[j].tagName.c_str();
+ if (tagName == NULL) {
+ ALOGE("%s: no tag name defined for vendor tag %d.", __FUNCTION__, tag);
+ return BAD_VALUE;
+ }
+ desc->mTagToNameMap.add(tag, String8(tagName));
+ tagToSectionMap.add(tag, sectionString);
+
+ int tagType = (int) section.tags[j].tagType;
+ if (tagType < 0 || tagType >= NUM_TYPES) {
+ ALOGE("%s: tag type %d from vendor ops does not exist.", __FUNCTION__, tagType);
+ return BAD_VALUE;
+ }
+ desc->mTagToTypeMap.emplace(tag, tagType);
+ }
+ }
+
+ for (size_t i = 0; i < tagArray.size(); ++i) {
+ uint32_t tag = tagArray[i];
+ String8 sectionString = tagToSectionMap.valueFor(tag);
+
+ // Set up tag to section index map
+ ssize_t index = desc->mSections.indexOf(sectionString);
+ LOG_ALWAYS_FATAL_IF(index < 0, "index %zd must be non-negative", index);
+ desc->mTagToSectionMap.add(tag, static_cast<uint32_t>(index));
+
+ // Set up reverse mapping
+ ssize_t reverseIndex = -1;
+ if ((reverseIndex = desc->mReverseMapping.indexOfKey(sectionString)) < 0) {
+ KeyedVector<String8, uint32_t>* nameMapper = new KeyedVector<String8, uint32_t>();
+ reverseIndex = desc->mReverseMapping.add(sectionString, nameMapper);
+ }
+ desc->mReverseMapping[reverseIndex]->add(desc->mTagToNameMap.valueFor(tag), tag);
+ }
+
+ *descriptor = std::move(desc);
+ return OK;
+}
+
CameraManagerGlobal&
CameraManagerGlobal::getInstance() {
Mutex::Autolock _l(sLock);
@@ -80,8 +181,34 @@
return (strncmp(value, "0", 2) != 0 && strncasecmp(value, "false", 6) != 0);
}
-// TODO: Add back when vendor tags are supported for libcamera2ndk_vendor when
-// the HIDL interface supports querying by vendor id.
+bool CameraManagerGlobal::setupVendorTags() {
+ sp<VendorTagDescriptorCache> tagCache = new VendorTagDescriptorCache();
+ Status status = Status::NO_ERROR;
+ std::vector<ProviderIdAndVendorTagSections> providerIdsAndVts;
+ auto remoteRet = mCameraService->getCameraVendorTagSections([&status, &providerIdsAndVts]
+ (Status s,
+ auto &IdsAndVts) {
+ status = s;
+ providerIdsAndVts = IdsAndVts; });
+
+ if (!remoteRet.isOk() || status != Status::NO_ERROR) {
+ ALOGE("Failed to retrieve VendorTagSections %s", remoteRet.description().c_str());
+ return false;
+ }
+ // Convert each providers VendorTagSections into a VendorTagDescriptor and
+ // add it to the cache
+ for (auto &providerIdAndVts : providerIdsAndVts) {
+ sp<VendorTagDescriptor> vendorTagDescriptor;
+ if (HidlVendorTagDescriptor::createDescriptorFromHidl(providerIdAndVts.vendorTagSections,
+ &vendorTagDescriptor) != OK) {
+ ALOGE("Failed to convert from Hidl: VendorTagDescriptor");
+ return false;
+ }
+ tagCache->addVendorDescriptor(providerIdAndVts.providerId, vendorTagDescriptor);
+ }
+ VendorTagDescriptorCache::setAsGlobalVendorTagCache(tagCache);
+ return true;
+}
sp<ICameraService> CameraManagerGlobal::getCameraService() {
Mutex::Autolock _l(mLock);
@@ -140,6 +267,13 @@
if (!remoteRet.isOk() || status != Status::NO_ERROR) {
ALOGE("Failed to add listener to camera service %s", remoteRet.description().c_str());
}
+
+ // Setup vendor tags
+ if (!setupVendorTags()) {
+ ALOGE("Unable to set up vendor tags");
+ return nullptr;
+ }
+
for (auto& c : cameraStatuses) {
onStatusChangedLocked(c);
}
diff --git a/camera/ndk/ndk_vendor/impl/ACameraManager.h b/camera/ndk/ndk_vendor/impl/ACameraManager.h
index c8d640f..6b1365a 100644
--- a/camera/ndk/ndk_vendor/impl/ACameraManager.h
+++ b/camera/ndk/ndk_vendor/impl/ACameraManager.h
@@ -142,6 +142,8 @@
void onStatusChanged(const CameraStatusAndId &statusAndId);
void onStatusChangedLocked(const CameraStatusAndId &statusAndId);
+ bool setupVendorTags();
+
// Utils for status
static bool validStatus(CameraDeviceStatus status);
static bool isStatusAvailable(CameraDeviceStatus status);
diff --git a/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp b/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp
index f9bb3ac..93108b0 100644
--- a/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp
+++ b/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp
@@ -37,12 +37,7 @@
#include <media/NdkImage.h>
#include <media/NdkImageReader.h>
#include <cutils/native_handle.h>
-
-//#define ALOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)
-//#define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
-#define ALOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
-#define ALOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
-#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
+#include <VendorTagDescriptor.h>
namespace {
@@ -53,6 +48,8 @@
static constexpr int kTestImageHeight = 480;
static constexpr int kTestImageFormat = AIMAGE_FORMAT_YUV_420_888;
+using android::hardware::camera::common::V1_0::helper::VendorTagDescriptorCache;
+
class CameraHelper {
public:
CameraHelper(const char* id, ACameraManager *manager) :
@@ -527,6 +524,8 @@
ALOGE("Failed to get cameraIdList: ret=%d", ret);
return;
}
+ // TODO: Add more rigorous tests for vendor tags
+ ASSERT_NE(VendorTagDescriptorCache::getGlobalVendorTagCache(), nullptr);
if (mCameraIdList->numCameras < 1) {
ALOGW("Device has no camera on board.");
return;
diff --git a/cmds/stagefright/Android.mk b/cmds/stagefright/Android.mk
index 7a10302..6eb2e9f 100644
--- a/cmds/stagefright/Android.mk
+++ b/cmds/stagefright/Android.mk
@@ -8,7 +8,7 @@
SineSource.cpp
LOCAL_SHARED_LIBRARIES := \
- libstagefright libmedia libmedia_omx libmediaextractor libutils libbinder \
+ libstagefright libmedia libmedia_omx libutils libbinder \
libstagefright_foundation libjpeg libui libgui libcutils liblog \
libhidlbase \
android.hardware.media.omx@1.0 \
@@ -36,7 +36,7 @@
record.cpp
LOCAL_SHARED_LIBRARIES := \
- libstagefright libmedia libmediaextractor liblog libutils libbinder \
+ libstagefright libmedia liblog libutils libbinder \
libstagefright_foundation
LOCAL_C_INCLUDES:= \
@@ -61,7 +61,7 @@
recordvideo.cpp
LOCAL_SHARED_LIBRARIES := \
- libstagefright libmedia libmediaextractor liblog libutils libbinder \
+ libstagefright libmedia liblog libutils libbinder \
libstagefright_foundation
LOCAL_C_INCLUDES:= \
@@ -87,7 +87,7 @@
audioloop.cpp
LOCAL_SHARED_LIBRARIES := \
- libstagefright libmedia libmediaextractor liblog libutils libbinder \
+ libstagefright libmedia liblog libutils libbinder \
libstagefright_foundation
LOCAL_C_INCLUDES:= \
@@ -111,7 +111,7 @@
LOCAL_SHARED_LIBRARIES := \
libstagefright liblog libutils libbinder libui libgui \
- libstagefright_foundation libmedia libcutils libmediaextractor
+ libstagefright_foundation libmedia libcutils
LOCAL_C_INCLUDES:= \
frameworks/av/media/libstagefright \
@@ -203,7 +203,7 @@
LOCAL_SHARED_LIBRARIES := \
libstagefright liblog libutils libbinder libstagefright_foundation \
- libcutils libc libmediaextractor
+ libcutils libc
LOCAL_C_INCLUDES:= \
frameworks/av/media/libstagefright \
diff --git a/drm/drmserver/DrmManagerService.cpp b/drm/drmserver/DrmManagerService.cpp
index 2532275..2600a2c 100644
--- a/drm/drmserver/DrmManagerService.cpp
+++ b/drm/drmserver/DrmManagerService.cpp
@@ -58,22 +58,26 @@
return drm_perm_labels[index];
}
-bool DrmManagerService::selinuxIsProtectedCallAllowed(pid_t spid, drm_perm_t perm) {
+bool DrmManagerService::selinuxIsProtectedCallAllowed(pid_t spid, const char* ssid, drm_perm_t perm) {
if (selinux_enabled <= 0) {
return true;
}
- char *sctx;
+ char *sctx = NULL;
const char *selinux_class = "drmservice";
const char *str_perm = get_perm_label(perm);
- if (getpidcon(spid, &sctx) != 0) {
- ALOGE("SELinux: getpidcon(pid=%d) failed.\n", spid);
- return false;
+ if (ssid == NULL) {
+ android_errorWriteLog(0x534e4554, "121035042");
+
+ if (getpidcon(spid, &sctx) != 0) {
+ ALOGE("SELinux: getpidcon(pid=%d) failed.\n", spid);
+ return false;
+ }
}
- bool allowed = (selinux_check_access(sctx, drmserver_context, selinux_class,
- str_perm, NULL) == 0);
+ bool allowed = (selinux_check_access(ssid ? ssid : sctx, drmserver_context,
+ selinux_class, str_perm, NULL) == 0);
freecon(sctx);
return allowed;
@@ -86,10 +90,11 @@
IPCThreadState* ipcState = IPCThreadState::self();
uid_t uid = ipcState->getCallingUid();
pid_t spid = ipcState->getCallingPid();
+ const char* ssid = ipcState->getCallingSid();
for (unsigned int i = 0; i < trustedUids.size(); ++i) {
if (trustedUids[i] == uid) {
- return selinuxIsProtectedCallAllowed(spid, perm);
+ return selinuxIsProtectedCallAllowed(spid, ssid, perm);
}
}
return false;
@@ -97,7 +102,9 @@
void DrmManagerService::instantiate() {
ALOGV("instantiate");
- defaultServiceManager()->addService(String16("drm.drmManager"), new DrmManagerService());
+ sp<DrmManagerService> service = new DrmManagerService();
+ service->setRequestingSid(true);
+ defaultServiceManager()->addService(String16("drm.drmManager"), service);
if (0 >= trustedUids.size()) {
// TODO
diff --git a/drm/drmserver/DrmManagerService.h b/drm/drmserver/DrmManagerService.h
index 7aaeab5..2e27a3c 100644
--- a/drm/drmserver/DrmManagerService.h
+++ b/drm/drmserver/DrmManagerService.h
@@ -60,7 +60,7 @@
static const char *get_perm_label(drm_perm_t perm);
- static bool selinuxIsProtectedCallAllowed(pid_t spid, drm_perm_t perm);
+ static bool selinuxIsProtectedCallAllowed(pid_t spid, const char* ssid, drm_perm_t perm);
static bool isProtectedCallAllowed(drm_perm_t perm);
diff --git a/drm/libmediadrm/CryptoHal.cpp b/drm/libmediadrm/CryptoHal.cpp
index 3035c5a..4dda5d7 100644
--- a/drm/libmediadrm/CryptoHal.cpp
+++ b/drm/libmediadrm/CryptoHal.cpp
@@ -30,16 +30,16 @@
#include <media/stagefright/MediaErrors.h>
#include <mediadrm/CryptoHal.h>
+using drm::V1_0::BufferType;
+using drm::V1_0::DestinationBuffer;
+using drm::V1_0::ICryptoFactory;
+using drm::V1_0::ICryptoPlugin;
+using drm::V1_0::Mode;
+using drm::V1_0::Pattern;
+using drm::V1_0::SharedBuffer;
+using drm::V1_0::Status;
+using drm::V1_0::SubSample;
-using ::android::hardware::drm::V1_0::BufferType;
-using ::android::hardware::drm::V1_0::DestinationBuffer;
-using ::android::hardware::drm::V1_0::ICryptoFactory;
-using ::android::hardware::drm::V1_0::ICryptoPlugin;
-using ::android::hardware::drm::V1_0::Mode;
-using ::android::hardware::drm::V1_0::Pattern;
-using ::android::hardware::drm::V1_0::SharedBuffer;
-using ::android::hardware::drm::V1_0::Status;
-using ::android::hardware::drm::V1_0::SubSample;
using ::android::hardware::hidl_array;
using ::android::hardware::hidl_handle;
using ::android::hardware::hidl_memory;
@@ -50,6 +50,7 @@
using ::android::hidl::manager::V1_0::IServiceManager;
using ::android::sp;
+typedef drm::V1_2::Status Status_V1_2;
namespace android {
@@ -76,6 +77,18 @@
}
}
+static status_t toStatusT_1_2(Status_V1_2 status) {
+ switch (status) {
+ case Status_V1_2::ERROR_DRM_SESSION_LOST_STATE:
+ return ERROR_DRM_SESSION_LOST_STATE;;
+ case Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE:
+ return ERROR_DRM_FRAME_TOO_LARGE;
+ case Status_V1_2::ERROR_DRM_INSUFFICIENT_SECURITY:
+ return ERROR_DRM_INSUFFICIENT_SECURITY;
+ default:
+ return toStatusT(static_cast<Status>(status));
+ }
+}
static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) {
hidl_vec<uint8_t> vec;
@@ -196,6 +209,9 @@
for (size_t i = 0; i < mFactories.size(); i++) {
if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
mPlugin = makeCryptoPlugin(mFactories[i], uuid, data, size);
+ if (mPlugin != NULL) {
+ mPluginV1_2 = drm::V1_2::ICryptoPlugin::castFrom(mPlugin);
+ }
}
}
@@ -216,6 +232,7 @@
}
mPlugin.clear();
+ mPluginV1_2.clear();
return OK;
}
@@ -389,21 +406,33 @@
status_t err = UNKNOWN_ERROR;
uint32_t bytesWritten = 0;
- Return<void> hResult = mPlugin->decrypt(secure, toHidlArray16(keyId), toHidlArray16(iv), hMode,
- hPattern, hSubSamples, hSource, offset, hDestination,
- [&](Status status, uint32_t hBytesWritten, hidl_string hDetailedError) {
- if (status == Status::OK) {
- bytesWritten = hBytesWritten;
- *errorDetailMsg = toString8(hDetailedError);
- }
- err = toStatusT(status);
- }
- );
+ Return<void> hResult;
- if (!hResult.isOk()) {
- err = DEAD_OBJECT;
+ if (mPluginV1_2 != NULL) {
+ hResult = mPluginV1_2->decrypt_1_2(secure, toHidlArray16(keyId), toHidlArray16(iv),
+ hMode, hPattern, hSubSamples, hSource, offset, hDestination,
+ [&](Status_V1_2 status, uint32_t hBytesWritten, hidl_string hDetailedError) {
+ if (status == Status_V1_2::OK) {
+ bytesWritten = hBytesWritten;
+ *errorDetailMsg = toString8(hDetailedError);
+ }
+ err = toStatusT_1_2(status);
+ }
+ );
+ } else {
+ hResult = mPlugin->decrypt(secure, toHidlArray16(keyId), toHidlArray16(iv),
+ hMode, hPattern, hSubSamples, hSource, offset, hDestination,
+ [&](Status status, uint32_t hBytesWritten, hidl_string hDetailedError) {
+ if (status == Status::OK) {
+ bytesWritten = hBytesWritten;
+ *errorDetailMsg = toString8(hDetailedError);
+ }
+ err = toStatusT(status);
+ }
+ );
}
+ err = hResult.isOk() ? err : DEAD_OBJECT;
if (err == OK) {
return bytesWritten;
}
diff --git a/drm/libmediadrm/DrmHal.cpp b/drm/libmediadrm/DrmHal.cpp
index 66c509f..f4c0341 100644
--- a/drm/libmediadrm/DrmHal.cpp
+++ b/drm/libmediadrm/DrmHal.cpp
@@ -24,7 +24,7 @@
#include <binder/IServiceManager.h>
#include <android/hardware/drm/1.2/types.h>
-#include <android/hidl/manager/1.0/IServiceManager.h>
+#include <android/hidl/manager/1.2/IServiceManager.h>
#include <hidl/ServiceManagement.h>
#include <media/EventMetric.h>
@@ -41,6 +41,7 @@
using drm::V1_0::KeyedVector;
using drm::V1_0::KeyStatusType;
+using drm::V1_0::KeyRequestType;
using drm::V1_0::KeyType;
using drm::V1_0::KeyValue;
using drm::V1_0::SecureStop;
@@ -60,6 +61,9 @@
using ::android::os::PersistableBundle;
using ::android::sp;
+typedef drm::V1_1::KeyRequestType KeyRequestType_V1_1;
+typedef drm::V1_2::Status Status_V1_2;
+
namespace {
// This constant corresponds to the PROPERTY_DEVICE_UNIQUE_ID constant
@@ -239,7 +243,7 @@
return ERROR_DRM_CANNOT_HANDLE;
break;
case Status::ERROR_DRM_INVALID_STATE:
- return ERROR_DRM_TAMPER_DETECTED;
+ return ERROR_DRM_INVALID_STATE;
break;
case Status::BAD_VALUE:
return BAD_VALUE;
@@ -260,6 +264,19 @@
}
}
+static status_t toStatusT_1_2(Status_V1_2 status) {
+ switch (status) {
+ case Status_V1_2::ERROR_DRM_RESOURCE_CONTENTION:
+ return ERROR_DRM_RESOURCE_CONTENTION;
+ case Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE:
+ return ERROR_DRM_FRAME_TOO_LARGE;
+ case Status_V1_2::ERROR_DRM_INSUFFICIENT_SECURITY:
+ return ERROR_DRM_INSUFFICIENT_SECURITY;
+ default:
+ return toStatusT(static_cast<Status>(status));
+ }
+}
+
Mutex DrmHal::mLock;
@@ -319,8 +336,11 @@
setListener(NULL);
mInitCheck = NO_INIT;
-
- if (mPlugin != NULL) {
+ if (mPluginV1_2 != NULL) {
+ if (!mPluginV1_2->setListener(NULL).isOk()) {
+ mInitCheck = DEAD_OBJECT;
+ }
+ } else if (mPlugin != NULL) {
if (!mPlugin->setListener(NULL).isOk()) {
mInitCheck = DEAD_OBJECT;
}
@@ -333,10 +353,10 @@
Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
Vector<sp<IDrmFactory>> factories;
- auto manager = hardware::defaultServiceManager();
+ auto manager = hardware::defaultServiceManager1_2();
if (manager != NULL) {
- manager->listByInterface(drm::V1_0::IDrmFactory::descriptor,
+ manager->listManifestByInterface(drm::V1_0::IDrmFactory::descriptor,
[&factories](const hidl_vec<hidl_string> ®istered) {
for (const auto &instance : registered) {
auto factory = drm::V1_0::IDrmFactory::getService(instance);
@@ -346,7 +366,7 @@
}
}
);
- manager->listByInterface(drm::V1_1::IDrmFactory::descriptor,
+ manager->listManifestByInterface(drm::V1_1::IDrmFactory::descriptor,
[&factories](const hidl_vec<hidl_string> ®istered) {
for (const auto &instance : registered) {
auto factory = drm::V1_1::IDrmFactory::getService(instance);
@@ -532,6 +552,22 @@
return Void();
}
+Return<void> DrmHal::sendSessionLostState(
+ const hidl_vec<uint8_t>& sessionId) {
+
+ mEventLock.lock();
+ sp<IDrmClient> listener = mListener;
+ mEventLock.unlock();
+
+ if (listener != NULL) {
+ Parcel obj;
+ writeByteArray(obj, sessionId);
+ Mutex::Autolock lock(mNotifyLock);
+ listener->notify(DrmPlugin::kDrmPluginEventSessionLostState, 0, &obj);
+ }
+ return Void();
+}
+
bool DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
Mutex::Autolock autoLock(mLock);
@@ -568,16 +604,22 @@
if (mPlugin == NULL) {
mInitCheck = ERROR_UNSUPPORTED;
} else {
- if (!mPlugin->setListener(this).isOk()) {
- mPlugin = NULL;
- mPluginV1_1 = NULL;
- mPluginV1_2 = NULL;
+ mInitCheck = OK;
+ if (mPluginV1_2 != NULL) {
+ if (!mPluginV1_2->setListener(this).isOk()) {
+ mInitCheck = DEAD_OBJECT;
+ }
+ } else if (!mPlugin->setListener(this).isOk()) {
mInitCheck = DEAD_OBJECT;
- } else {
- mInitCheck = OK;
+ }
+ if (mInitCheck != OK) {
+ mPlugin.clear();
+ mPluginV1_1.clear();
+ mPluginV1_2.clear();
}
}
+
return mInitCheck;
}
@@ -694,6 +736,39 @@
return DEAD_OBJECT;
}
+static DrmPlugin::KeyRequestType toKeyRequestType(
+ KeyRequestType keyRequestType) {
+ switch (keyRequestType) {
+ case KeyRequestType::INITIAL:
+ return DrmPlugin::kKeyRequestType_Initial;
+ break;
+ case KeyRequestType::RENEWAL:
+ return DrmPlugin::kKeyRequestType_Renewal;
+ break;
+ case KeyRequestType::RELEASE:
+ return DrmPlugin::kKeyRequestType_Release;
+ break;
+ default:
+ return DrmPlugin::kKeyRequestType_Unknown;
+ break;
+ }
+}
+
+static DrmPlugin::KeyRequestType toKeyRequestType_1_1(
+ KeyRequestType_V1_1 keyRequestType) {
+ switch (keyRequestType) {
+ case KeyRequestType_V1_1::NONE:
+ return DrmPlugin::kKeyRequestType_None;
+ break;
+ case KeyRequestType_V1_1::UPDATE:
+ return DrmPlugin::kKeyRequestType_Update;
+ break;
+ default:
+ return toKeyRequestType(static_cast<KeyRequestType>(keyRequestType));
+ break;
+ }
+}
+
status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
Vector<uint8_t> const &initData, String8 const &mimeType,
DrmPlugin::KeyType keyType, KeyedVector<String8,
@@ -720,73 +795,51 @@
::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
status_t err = UNKNOWN_ERROR;
+ Return<void> hResult;
- if (mPluginV1_1 != NULL) {
- Return<void> hResult =
- mPluginV1_1->getKeyRequest_1_1(
+ if (mPluginV1_2 != NULL) {
+ hResult = mPluginV1_2->getKeyRequest_1_2(
+ toHidlVec(sessionId), toHidlVec(initData),
+ toHidlString(mimeType), hKeyType, hOptionalParameters,
+ [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
+ KeyRequestType_V1_1 hKeyRequestType,
+ const hidl_string& hDefaultUrl) {
+ if (status == Status_V1_2::OK) {
+ request = toVector(hRequest);
+ defaultUrl = toString8(hDefaultUrl);
+ *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
+ }
+ err = toStatusT_1_2(status);
+ });
+ } else if (mPluginV1_1 != NULL) {
+ hResult = mPluginV1_1->getKeyRequest_1_1(
toHidlVec(sessionId), toHidlVec(initData),
toHidlString(mimeType), hKeyType, hOptionalParameters,
[&](Status status, const hidl_vec<uint8_t>& hRequest,
- drm::V1_1::KeyRequestType hKeyRequestType,
- const hidl_string& hDefaultUrl) {
-
- if (status == Status::OK) {
- request = toVector(hRequest);
- defaultUrl = toString8(hDefaultUrl);
-
- switch (hKeyRequestType) {
- case drm::V1_1::KeyRequestType::INITIAL:
- *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
- break;
- case drm::V1_1::KeyRequestType::RENEWAL:
- *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
- break;
- case drm::V1_1::KeyRequestType::RELEASE:
- *keyRequestType = DrmPlugin::kKeyRequestType_Release;
- break;
- case drm::V1_1::KeyRequestType::NONE:
- *keyRequestType = DrmPlugin::kKeyRequestType_None;
- break;
- case drm::V1_1::KeyRequestType::UPDATE:
- *keyRequestType = DrmPlugin::kKeyRequestType_Update;
- break;
- default:
- *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
- break;
- }
- err = toStatusT(status);
- }
- });
- return hResult.isOk() ? err : DEAD_OBJECT;
- }
-
- Return<void> hResult = mPlugin->getKeyRequest(toHidlVec(sessionId),
- toHidlVec(initData), toHidlString(mimeType), hKeyType, hOptionalParameters,
- [&](Status status, const hidl_vec<uint8_t>& hRequest,
- drm::V1_0::KeyRequestType hKeyRequestType,
- const hidl_string& hDefaultUrl) {
-
- if (status == Status::OK) {
- request = toVector(hRequest);
- defaultUrl = toString8(hDefaultUrl);
-
- switch (hKeyRequestType) {
- case drm::V1_0::KeyRequestType::INITIAL:
- *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
- break;
- case drm::V1_0::KeyRequestType::RENEWAL:
- *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
- break;
- case drm::V1_0::KeyRequestType::RELEASE:
- *keyRequestType = DrmPlugin::kKeyRequestType_Release;
- break;
- default:
- *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
- break;
+ KeyRequestType_V1_1 hKeyRequestType,
+ const hidl_string& hDefaultUrl) {
+ if (status == Status::OK) {
+ request = toVector(hRequest);
+ defaultUrl = toString8(hDefaultUrl);
+ *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
}
err = toStatusT(status);
- }
- });
+ });
+ } else {
+ hResult = mPlugin->getKeyRequest(
+ toHidlVec(sessionId), toHidlVec(initData),
+ toHidlString(mimeType), hKeyType, hOptionalParameters,
+ [&](Status status, const hidl_vec<uint8_t>& hRequest,
+ KeyRequestType hKeyRequestType,
+ const hidl_string& hDefaultUrl) {
+ if (status == Status::OK) {
+ request = toVector(hRequest);
+ defaultUrl = toString8(hDefaultUrl);
+ *keyRequestType = toKeyRequestType(hKeyRequestType);
+ }
+ err = toStatusT(status);
+ });
+ }
err = hResult.isOk() ? err : DEAD_OBJECT;
keyRequestTimer.SetAttribute(err);
@@ -868,18 +921,33 @@
INIT_CHECK();
status_t err = UNKNOWN_ERROR;
+ Return<void> hResult;
- Return<void> hResult = mPlugin->getProvisionRequest(
- toHidlString(certType), toHidlString(certAuthority),
- [&](Status status, const hidl_vec<uint8_t>& hRequest,
- const hidl_string& hDefaultUrl) {
- if (status == Status::OK) {
- request = toVector(hRequest);
- defaultUrl = toString8(hDefaultUrl);
+ if (mPluginV1_2 != NULL) {
+ Return<void> hResult = mPluginV1_2->getProvisionRequest_1_2(
+ toHidlString(certType), toHidlString(certAuthority),
+ [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
+ const hidl_string& hDefaultUrl) {
+ if (status == Status_V1_2::OK) {
+ request = toVector(hRequest);
+ defaultUrl = toString8(hDefaultUrl);
+ }
+ err = toStatusT_1_2(status);
}
- err = toStatusT(status);
- }
- );
+ );
+ } else {
+ Return<void> hResult = mPlugin->getProvisionRequest(
+ toHidlString(certType), toHidlString(certAuthority),
+ [&](Status status, const hidl_vec<uint8_t>& hRequest,
+ const hidl_string& hDefaultUrl) {
+ if (status == Status::OK) {
+ request = toVector(hRequest);
+ defaultUrl = toString8(hDefaultUrl);
+ }
+ err = toStatusT(status);
+ }
+ );
+ }
err = hResult.isOk() ? err : DEAD_OBJECT;
mMetrics.mGetProvisionRequestCounter.Increment(err);
diff --git a/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp b/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp
index a488f86..fc0cceb 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp
@@ -42,10 +42,42 @@
return Void();
}
+Return<void> CryptoPlugin::decrypt(
+ bool secure,
+ const hidl_array<uint8_t, 16>& keyId,
+ const hidl_array<uint8_t, 16>& iv,
+ Mode mode,
+ const Pattern& pattern,
+ const hidl_vec<SubSample>& subSamples,
+ const SharedBuffer& source,
+ uint64_t offset,
+ const DestinationBuffer& destination,
+ decrypt_cb _hidl_cb) {
+
+ Status status = Status::ERROR_DRM_UNKNOWN;
+ hidl_string detailedError;
+ uint32_t bytesWritten = 0;
+
+ Return<void> hResult = decrypt_1_2(
+ secure, keyId, iv, mode, pattern, subSamples, source, offset, destination,
+ [&](Status_V1_2 hStatus, uint32_t hBytesWritten, hidl_string hDetailedError) {
+ status = toStatus_1_0(hStatus);
+ if (status == Status::OK) {
+ bytesWritten = hBytesWritten;
+ detailedError = hDetailedError;
+ }
+ }
+ );
+
+ status = hResult.isOk() ? status : Status::ERROR_DRM_CANNOT_HANDLE;
+ _hidl_cb(status, bytesWritten, detailedError);
+ return Void();
+}
+
// Returns negative values for error code and positive values for the size of
// decrypted data. In theory, the output size can be larger than the input
// size, but in practice this will never happen for AES-CTR.
-Return<void> CryptoPlugin::decrypt(
+Return<void> CryptoPlugin::decrypt_1_2(
bool secure,
const hidl_array<uint8_t, KEY_ID_SIZE>& keyId,
const hidl_array<uint8_t, KEY_IV_SIZE>& iv,
@@ -55,17 +87,17 @@
const SharedBuffer& source,
uint64_t offset,
const DestinationBuffer& destination,
- decrypt_cb _hidl_cb) {
+ decrypt_1_2_cb _hidl_cb) {
UNUSED(pattern);
if (secure) {
- _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0,
+ _hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0,
"Secure decryption is not supported with ClearKey.");
return Void();
}
if (mSharedBufferMap.find(source.bufferId) == mSharedBufferMap.end()) {
- _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0,
+ _hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0,
"source decrypt buffer base not set");
return Void();
}
@@ -73,7 +105,7 @@
if (destination.type == BufferType::SHARED_MEMORY) {
const SharedBuffer& dest = destination.nonsecureMemory;
if (mSharedBufferMap.find(dest.bufferId) == mSharedBufferMap.end()) {
- _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0,
+ _hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0,
"destination decrypt buffer base not set");
return Void();
}
@@ -81,12 +113,12 @@
sp<IMemory> sourceBase = mSharedBufferMap[source.bufferId];
if (sourceBase == nullptr) {
- _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "source is a nullptr");
+ _hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0, "source is a nullptr");
return Void();
}
if (source.offset + offset + source.size > sourceBase->getSize()) {
- _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
+ _hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
return Void();
}
@@ -98,12 +130,12 @@
const SharedBuffer& destBuffer = destination.nonsecureMemory;
sp<IMemory> destBase = mSharedBufferMap[destBuffer.bufferId];
if (destBase == nullptr) {
- _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "destination is a nullptr");
+ _hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0, "destination is a nullptr");
return Void();
}
if (destBuffer.offset + destBuffer.size > destBase->getSize()) {
- _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
+ _hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
return Void();
}
destPtr = static_cast<void *>(base + destination.nonsecureMemory.offset);
@@ -128,7 +160,7 @@
if (mode == Mode::UNENCRYPTED) {
if (haveEncryptedSubsamples) {
- _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0,
+ _hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0,
"Encrypted subsamples found in allegedly unencrypted data.");
return Void();
}
@@ -144,22 +176,21 @@
}
}
- _hidl_cb(Status::OK, static_cast<ssize_t>(offset), "");
+ _hidl_cb(Status_V1_2::OK, static_cast<ssize_t>(offset), "");
return Void();
} else if (mode == Mode::AES_CTR) {
size_t bytesDecrypted;
- Status res = mSession->decrypt(keyId.data(), iv.data(), srcPtr,
+ Status_V1_2 res = mSession->decrypt(keyId.data(), iv.data(), srcPtr,
static_cast<uint8_t*>(destPtr), toVector(subSamples), &bytesDecrypted);
- if (res == Status::OK) {
- _hidl_cb(Status::OK, static_cast<ssize_t>(bytesDecrypted), "");
+ if (res == Status_V1_2::OK) {
+ _hidl_cb(Status_V1_2::OK, static_cast<ssize_t>(bytesDecrypted), "");
return Void();
} else {
- _hidl_cb(Status::ERROR_DRM_DECRYPT, static_cast<ssize_t>(res),
- "Decryption Error");
+ _hidl_cb(res, 0, "Decryption Error");
return Void();
}
} else {
- _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0,
+ _hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0,
"Selected encryption mode is not supported by the ClearKey DRM Plugin.");
return Void();
}
diff --git a/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp b/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
index 7184b53..badb99e 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
@@ -61,15 +61,23 @@
namespace V1_2 {
namespace clearkey {
-using ::android::hardware::drm::V1_2::KeySetId;
-using ::android::hardware::drm::V1_2::OfflineLicenseState;
+KeyRequestType toKeyRequestType_V1_0(KeyRequestType_V1_1 keyRequestType) {
+ switch (keyRequestType) {
+ case KeyRequestType_V1_1::NONE:
+ case KeyRequestType_V1_1::UPDATE:
+ return KeyRequestType::UNKNOWN;
+ default:
+ return static_cast<KeyRequestType>(keyRequestType);
+ }
+}
DrmPlugin::DrmPlugin(SessionLibrary* sessionLibrary)
: mSessionLibrary(sessionLibrary),
mOpenSessionOkCount(0),
mCloseSessionOkCount(0),
mCloseSessionNotOpenedCount(0),
- mNextSecureStopId(kSecureStopIdStart) {
+ mNextSecureStopId(kSecureStopIdStart),
+ mMockError(Status_V1_2::OK) {
mPlayPolicy.clear();
initProperties();
mSecureStops.clear();
@@ -84,6 +92,7 @@
mStringProperties[kPluginDescriptionKey] = kPluginDescriptionValue;
mStringProperties[kAlgorithmsKey] = kAlgorithmsValue;
mStringProperties[kListenerTestSupportKey] = kListenerTestSupportValue;
+ mStringProperties[kDrmErrorTestKey] = kDrmErrorTestValue;
std::vector<uint8_t> valueVector;
valueVector.clear();
@@ -112,6 +121,7 @@
Return<void> DrmPlugin::openSession(openSession_cb _hidl_cb) {
sp<Session> session = mSessionLibrary->createSession();
+ processMockError(session);
std::vector<uint8_t> sessionId = session->sessionId();
Status status = setSecurityLevel(sessionId, SecurityLevel::SW_SECURE_CRYPTO);
@@ -123,6 +133,7 @@
Return<void> DrmPlugin::openSession_1_1(SecurityLevel securityLevel,
openSession_1_1_cb _hidl_cb) {
sp<Session> session = mSessionLibrary->createSession();
+ processMockError(session);
std::vector<uint8_t> sessionId = session->sessionId();
Status status = setSecurityLevel(sessionId, securityLevel);
@@ -138,6 +149,10 @@
sp<Session> session = mSessionLibrary->findSession(toVector(sessionId));
if (session.get()) {
+ if (session->getMockError() != Status_V1_2::OK) {
+ sendSessionLostState(sessionId);
+ return Status::ERROR_DRM_INVALID_STATE;
+ }
mCloseSessionOkCount++;
mSessionLibrary->destroySession(session);
return Status::OK;
@@ -146,13 +161,13 @@
return Status::ERROR_DRM_SESSION_NOT_OPENED;
}
-Status DrmPlugin::getKeyRequestCommon(const hidl_vec<uint8_t>& scope,
+Status_V1_2 DrmPlugin::getKeyRequestCommon(const hidl_vec<uint8_t>& scope,
const hidl_vec<uint8_t>& initData,
const hidl_string& mimeType,
KeyType keyType,
const hidl_vec<KeyValue>& optionalParameters,
std::vector<uint8_t> *request,
- KeyRequestType *keyRequestType,
+ KeyRequestType_V1_1 *keyRequestType,
std::string *defaultUrl) {
UNUSED(optionalParameters);
@@ -161,18 +176,18 @@
// Those tests pass in an empty initData, we use the empty initData to
// signal such specific use case.
if (keyType == KeyType::OFFLINE && 0 == initData.size()) {
- return Status::ERROR_DRM_CANNOT_HANDLE;
+ return Status_V1_2::ERROR_DRM_CANNOT_HANDLE;
}
*defaultUrl = "";
- *keyRequestType = KeyRequestType::UNKNOWN;
+ *keyRequestType = KeyRequestType_V1_1::UNKNOWN;
*request = std::vector<uint8_t>();
if (scope.size() == 0 ||
(keyType != KeyType::STREAMING &&
keyType != KeyType::OFFLINE &&
keyType != KeyType::RELEASE)) {
- return Status::BAD_VALUE;
+ return Status_V1_2::BAD_VALUE;
}
const std::vector<uint8_t> scopeId = toVector(scope);
@@ -181,12 +196,16 @@
std::vector<uint8_t> sessionId(scopeId.begin(), scopeId.end());
session = mSessionLibrary->findSession(sessionId);
if (!session.get()) {
- return Status::ERROR_DRM_SESSION_NOT_OPENED;
+ return Status_V1_2::ERROR_DRM_SESSION_NOT_OPENED;
+ } else if (session->getMockError() != Status_V1_2::OK) {
+ return session->getMockError();
}
- *keyRequestType = KeyRequestType::INITIAL;
+
+ *keyRequestType = KeyRequestType_V1_1::INITIAL;
}
- Status status = session->getKeyRequest(initData, mimeType, keyType, request);
+ Status_V1_2 status = static_cast<Status_V1_2>(
+ session->getKeyRequest(initData, mimeType, keyType, request));
if (keyType == KeyType::RELEASE) {
std::vector<uint8_t> keySetId(scopeId.begin(), scopeId.end());
@@ -198,7 +217,7 @@
DeviceFiles::kLicenseStateReleasing,
emptyResponse)) {
ALOGE("Problem releasing offline license");
- return Status::ERROR_DRM_UNKNOWN;
+ return Status_V1_2::ERROR_DRM_UNKNOWN;
}
if (mReleaseKeysMap.find(keySetIdString) == mReleaseKeysMap.end()) {
sp<Session> session = mSessionLibrary->createSession();
@@ -209,7 +228,7 @@
} else {
ALOGE("Offline license not found, nothing to release");
}
- *keyRequestType = KeyRequestType::RELEASE;
+ *keyRequestType = KeyRequestType_V1_1::RELEASE;
}
return status;
}
@@ -223,15 +242,15 @@
getKeyRequest_cb _hidl_cb) {
UNUSED(optionalParameters);
- KeyRequestType keyRequestType = KeyRequestType::UNKNOWN;
+ KeyRequestType_V1_1 keyRequestType = KeyRequestType_V1_1::UNKNOWN;
std::string defaultUrl("");
std::vector<uint8_t> request;
- Status status = getKeyRequestCommon(
+ Status_V1_2 status = getKeyRequestCommon(
scope, initData, mimeType, keyType, optionalParameters,
&request, &keyRequestType, &defaultUrl);
- _hidl_cb(status, toHidlVec(request),
- static_cast<drm::V1_0::KeyRequestType>(keyRequestType),
+ _hidl_cb(toStatus_1_0(status), toHidlVec(request),
+ toKeyRequestType_V1_0(keyRequestType),
hidl_string(defaultUrl));
return Void();
}
@@ -245,10 +264,31 @@
getKeyRequest_1_1_cb _hidl_cb) {
UNUSED(optionalParameters);
- KeyRequestType keyRequestType = KeyRequestType::UNKNOWN;
+ KeyRequestType_V1_1 keyRequestType = KeyRequestType_V1_1::UNKNOWN;
std::string defaultUrl("");
std::vector<uint8_t> request;
- Status status = getKeyRequestCommon(
+ Status_V1_2 status = getKeyRequestCommon(
+ scope, initData, mimeType, keyType, optionalParameters,
+ &request, &keyRequestType, &defaultUrl);
+
+ _hidl_cb(toStatus_1_0(status), toHidlVec(request),
+ keyRequestType, hidl_string(defaultUrl));
+ return Void();
+}
+
+Return<void> DrmPlugin::getKeyRequest_1_2(
+ const hidl_vec<uint8_t>& scope,
+ const hidl_vec<uint8_t>& initData,
+ const hidl_string& mimeType,
+ KeyType keyType,
+ const hidl_vec<KeyValue>& optionalParameters,
+ getKeyRequest_1_2_cb _hidl_cb) {
+ UNUSED(optionalParameters);
+
+ KeyRequestType_V1_1 keyRequestType = KeyRequestType_V1_1::UNKNOWN;
+ std::string defaultUrl("");
+ std::vector<uint8_t> request;
+ Status_V1_2 status = getKeyRequestCommon(
scope, initData, mimeType, keyType, optionalParameters,
&request, &keyRequestType, &defaultUrl);
@@ -434,6 +474,8 @@
value = mStringProperties[kAlgorithmsKey];
} else if (name == kListenerTestSupportKey) {
value = mStringProperties[kListenerTestSupportKey];
+ } else if (name == kDrmErrorTestKey) {
+ value = mStringProperties[kDrmErrorTestKey];
} else {
ALOGE("App requested unknown string property %s", name.c_str());
_hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, "");
@@ -478,6 +520,16 @@
return Status::BAD_VALUE;
}
+ if (name == kDrmErrorTestKey) {
+ if (value == kResourceContentionValue) {
+ mMockError = Status_V1_2::ERROR_DRM_RESOURCE_CONTENTION;
+ } else if (value == kLostStateValue) {
+ mMockError = Status_V1_2::ERROR_DRM_SESSION_LOST_STATE;
+ } else if (value == kFrameTooLargeValue) {
+ mMockError = Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE;
+ }
+ }
+
mStringProperties[key] = std::string(value.c_str());
return Status::OK;
}
diff --git a/drm/mediadrm/plugins/clearkey/hidl/Session.cpp b/drm/mediadrm/plugins/clearkey/hidl/Session.cpp
index f4c49b9..a9d7016 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/Session.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/Session.cpp
@@ -68,25 +68,30 @@
}
}
-Status Session::decrypt(
+Status_V1_2 Session::decrypt(
const KeyId keyId, const Iv iv, const uint8_t* srcPtr,
uint8_t* destPtr, const std::vector<SubSample> subSamples,
size_t* bytesDecryptedOut) {
Mutex::Autolock lock(mMapLock);
+ if (getMockError() != Status_V1_2::OK) {
+ return getMockError();
+ }
+
std::vector<uint8_t> keyIdVector;
keyIdVector.clear();
keyIdVector.insert(keyIdVector.end(), keyId, keyId + kBlockSize);
std::map<std::vector<uint8_t>, std::vector<uint8_t> >::iterator itr;
itr = mKeyMap.find(keyIdVector);
if (itr == mKeyMap.end()) {
- return Status::ERROR_DRM_NO_LICENSE;
+ return Status_V1_2::ERROR_DRM_NO_LICENSE;
}
AesCtrDecryptor decryptor;
- return decryptor.decrypt(
+ Status status = decryptor.decrypt(
itr->second /*key*/, iv, srcPtr, destPtr, subSamples,
subSamples.size(), bytesDecryptedOut);
+ return static_cast<Status_V1_2>(status);
}
} // namespace clearkey
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyDrmProperties.h b/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyDrmProperties.h
index f83903c..1bbc822 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyDrmProperties.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyDrmProperties.h
@@ -35,6 +35,11 @@
static const std::string kAlgorithmsValue("");
static const std::string kListenerTestSupportKey("listenerTestSupport");
static const std::string kListenerTestSupportValue("true");
+static const std::string kDrmErrorTestKey("drmErrorTest");
+static const std::string kDrmErrorTestValue("");
+static const std::string kResourceContentionValue("resourceContention");
+static const std::string kLostStateValue("lostState");
+static const std::string kFrameTooLargeValue("frameTooLarge");
static const std::string kDeviceIdKey("deviceId");
static const uint8_t kTestDeviceIdData[] =
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyTypes.h b/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyTypes.h
index 7e9b6bd..2dafa36 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyTypes.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyTypes.h
@@ -17,7 +17,7 @@
#ifndef CLEARKEY_MACROS_H_
#define CLEARKEY_MACROS_H_
-#include <android/hardware/drm/1.0/types.h>
+#include <android/hardware/drm/1.2/types.h>
#include <map>
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/CryptoPlugin.h b/drm/mediadrm/plugins/clearkey/hidl/include/CryptoPlugin.h
index 480dc7e..8680f0c 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/CryptoPlugin.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/CryptoPlugin.h
@@ -17,7 +17,7 @@
#ifndef CLEARKEY_CRYPTO_PLUGIN_H_
#define CLEARKEY_CRYPTO_PLUGIN_H_
-#include <android/hardware/drm/1.0/ICryptoPlugin.h>
+#include <android/hardware/drm/1.2/ICryptoPlugin.h>
#include <android/hidl/memory/1.0/IMemory.h>
#include "ClearKeyTypes.h"
@@ -35,13 +35,14 @@
namespace V1_2 {
namespace clearkey {
-using ::android::hardware::drm::V1_0::DestinationBuffer;
-using ::android::hardware::drm::V1_0::ICryptoPlugin;
-using ::android::hardware::drm::V1_0::Mode;
-using ::android::hardware::drm::V1_0::Pattern;
-using ::android::hardware::drm::V1_0::SharedBuffer;
-using ::android::hardware::drm::V1_0::Status;
-using ::android::hardware::drm::V1_0::SubSample;
+namespace drm = ::android::hardware::drm;
+using drm::V1_0::DestinationBuffer;
+using drm::V1_0::Mode;
+using drm::V1_0::Pattern;
+using drm::V1_0::SharedBuffer;
+using drm::V1_0::Status;
+using drm::V1_0::SubSample;
+
using ::android::hardware::hidl_array;
using ::android::hardware::hidl_memory;
using ::android::hardware::hidl_string;
@@ -51,7 +52,9 @@
using ::android::hidl::memory::V1_0::IMemory;
using ::android::sp;
-struct CryptoPlugin : public ICryptoPlugin {
+typedef drm::V1_2::Status Status_V1_2;
+
+struct CryptoPlugin : public drm::V1_2::ICryptoPlugin {
explicit CryptoPlugin(const hidl_vec<uint8_t>& sessionId) {
mInitStatus = setMediaDrmSession(sessionId);
}
@@ -80,6 +83,18 @@
const DestinationBuffer& destination,
decrypt_cb _hidl_cb);
+ Return<void> decrypt_1_2(
+ bool secure,
+ const hidl_array<uint8_t, KEY_ID_SIZE>& keyId,
+ const hidl_array<uint8_t, KEY_IV_SIZE>& iv,
+ Mode mode,
+ const Pattern& pattern,
+ const hidl_vec<SubSample>& subSamples,
+ const SharedBuffer& source,
+ uint64_t offset,
+ const DestinationBuffer& destination,
+ decrypt_1_2_cb _hidl_cb);
+
Return<void> setSharedBufferBase(const hidl_memory& base,
uint32_t bufferId);
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h b/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h
index 256c5d6..a9b897b 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h
@@ -18,6 +18,7 @@
#define CLEARKEY_DRM_PLUGIN_H_
#include <android/hardware/drm/1.2/IDrmPlugin.h>
+#include <android/hardware/drm/1.2/IDrmPluginListener.h>
#include <map>
#include <stdio.h>
@@ -34,22 +35,24 @@
namespace V1_2 {
namespace clearkey {
-using ::android::hardware::drm::V1_0::EventType;
-using ::android::hardware::drm::V1_0::IDrmPluginListener;
-using ::android::hardware::drm::V1_0::KeyStatus;
-using ::android::hardware::drm::V1_0::KeyType;
-using ::android::hardware::drm::V1_0::KeyValue;
-using ::android::hardware::drm::V1_0::SecureStop;
-using ::android::hardware::drm::V1_0::SecureStopId;
-using ::android::hardware::drm::V1_0::SessionId;
-using ::android::hardware::drm::V1_0::Status;
-using ::android::hardware::drm::V1_1::DrmMetricGroup;
-using ::android::hardware::drm::V1_1::HdcpLevel;
-using ::android::hardware::drm::V1_1::KeyRequestType;
-using ::android::hardware::drm::V1_1::SecureStopRelease;
-using ::android::hardware::drm::V1_1::SecurityLevel;
-using ::android::hardware::drm::V1_2::IDrmPlugin;
-using ::android::hardware::drm::V1_2::OfflineLicenseState;
+namespace drm = ::android::hardware::drm;
+using drm::V1_0::EventType;
+using drm::V1_0::IDrmPluginListener;
+using drm::V1_0::KeyRequestType;
+using drm::V1_0::KeyStatus;
+using drm::V1_0::KeyType;
+using drm::V1_0::KeyValue;
+using drm::V1_0::SecureStop;
+using drm::V1_0::SecureStopId;
+using drm::V1_0::SessionId;
+using drm::V1_0::Status;
+using drm::V1_1::DrmMetricGroup;
+using drm::V1_1::HdcpLevel;
+using drm::V1_1::SecureStopRelease;
+using drm::V1_1::SecurityLevel;
+using drm::V1_2::IDrmPlugin;
+using drm::V1_2::KeySetId;
+using drm::V1_2::OfflineLicenseState;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
@@ -57,6 +60,10 @@
using ::android::hardware::Void;
using ::android::sp;
+typedef drm::V1_1::KeyRequestType KeyRequestType_V1_1;
+typedef drm::V1_2::IDrmPluginListener IDrmPluginListener_V1_2;
+typedef drm::V1_2::Status Status_V1_2;
+
struct DrmPlugin : public IDrmPlugin {
explicit DrmPlugin(SessionLibrary* sessionLibrary);
@@ -84,6 +91,14 @@
const hidl_vec<KeyValue>& optionalParameters,
getKeyRequest_1_1_cb _hidl_cb) override;
+ Return<void> getKeyRequest_1_2(
+ const hidl_vec<uint8_t>& scope,
+ const hidl_vec<uint8_t>& initData,
+ const hidl_string& mimeType,
+ KeyType keyType,
+ const hidl_vec<KeyValue>& optionalParameters,
+ getKeyRequest_1_2_cb _hidl_cb) override;
+
Return<void> provideKeyResponse(
const hidl_vec<uint8_t>& scope,
const hidl_vec<uint8_t>& response,
@@ -116,6 +131,18 @@
return Void();
}
+ Return<void> getProvisionRequest_1_2(
+ const hidl_string& certificateType,
+ const hidl_string& certificateAuthority,
+ getProvisionRequest_1_2_cb _hidl_cb) {
+ UNUSED(certificateType);
+ UNUSED(certificateAuthority);
+
+ hidl_string defaultUrl;
+ _hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, hidl_vec<uint8_t>(), defaultUrl);
+ return Void();
+ }
+
Return<void> provideProvisionResponse(
const hidl_vec<uint8_t>& response,
provideProvisionResponse_cb _hidl_cb) {
@@ -256,12 +283,17 @@
Return<void> setListener(const sp<IDrmPluginListener>& listener) {
mListener = listener;
+ mListenerV1_2 = IDrmPluginListener_V1_2::castFrom(listener);
return Void();
};
- Return<void> sendEvent(EventType eventType, const hidl_vec<uint8_t>& sessionId,
+ Return<void> sendEvent(
+ EventType eventType,
+ const hidl_vec<uint8_t>& sessionId,
const hidl_vec<uint8_t>& data) {
- if (mListener != NULL) {
+ if (mListenerV1_2 != NULL) {
+ mListenerV1_2->sendEvent(eventType, sessionId, data);
+ } else if (mListener != NULL) {
mListener->sendEvent(eventType, sessionId, data);
} else {
ALOGE("Null event listener, event not sent");
@@ -269,8 +301,12 @@
return Void();
}
- Return<void> sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId, int64_t expiryTimeInMS) {
- if (mListener != NULL) {
+ Return<void> sendExpirationUpdate(
+ const hidl_vec<uint8_t>& sessionId,
+ int64_t expiryTimeInMS) {
+ if (mListenerV1_2 != NULL) {
+ mListenerV1_2->sendExpirationUpdate(sessionId, expiryTimeInMS);
+ } else if (mListener != NULL) {
mListener->sendExpirationUpdate(sessionId, expiryTimeInMS);
} else {
ALOGE("Null event listener, event not sent");
@@ -278,9 +314,12 @@
return Void();
}
- Return<void> sendKeysChange(const hidl_vec<uint8_t>& sessionId,
+ Return<void> sendKeysChange(
+ const hidl_vec<uint8_t>& sessionId,
const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
- if (mListener != NULL) {
+ if (mListenerV1_2 != NULL) {
+ mListenerV1_2->sendKeysChange(sessionId, keyStatusList, hasNewUsableKey);
+ } else if (mListener != NULL) {
mListener->sendKeysChange(sessionId, keyStatusList, hasNewUsableKey);
} else {
ALOGE("Null event listener, event not sent");
@@ -288,6 +327,14 @@
return Void();
}
+ Return<void> sendSessionLostState(
+ const hidl_vec<uint8_t>& sessionId) {
+ if (mListenerV1_2 != NULL) {
+ mListenerV1_2->sendSessionLostState(sessionId);
+ }
+ return Void();
+ }
+
Return<void> getSecureStops(getSecureStops_cb _hidl_cb);
Return<void> getSecureStop(const hidl_vec<uint8_t>& secureStopId,
@@ -314,13 +361,13 @@
Return<Status> setSecurityLevel(const hidl_vec<uint8_t>& sessionId,
SecurityLevel level);
- Status getKeyRequestCommon(const hidl_vec<uint8_t>& scope,
+ Status_V1_2 getKeyRequestCommon(const hidl_vec<uint8_t>& scope,
const hidl_vec<uint8_t>& initData,
const hidl_string& mimeType,
KeyType keyType,
const hidl_vec<KeyValue>& optionalParameters,
std::vector<uint8_t> *request,
- KeyRequestType *getKeyRequestType,
+ KeyRequestType_V1_1 *getKeyRequestType,
std::string *defaultUrl);
struct ClearkeySecureStop {
@@ -335,12 +382,21 @@
std::map<std::string, std::vector<uint8_t> > mReleaseKeysMap;
std::map<std::vector<uint8_t>, SecurityLevel> mSecurityLevel;
sp<IDrmPluginListener> mListener;
+ sp<IDrmPluginListener_V1_2> mListenerV1_2;
SessionLibrary *mSessionLibrary;
int64_t mOpenSessionOkCount;
int64_t mCloseSessionOkCount;
int64_t mCloseSessionNotOpenedCount;
uint32_t mNextSecureStopId;
+ // set by property to mock error scenarios
+ Status_V1_2 mMockError;
+
+ void processMockError(const sp<Session> &session) {
+ session->setMockError(mMockError);
+ mMockError = Status_V1_2::OK;
+ }
+
DeviceFiles mFileHandle;
CLEARKEY_DISALLOW_COPY_AND_ASSIGN_AND_NEW(DrmPlugin);
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/Session.h b/drm/mediadrm/plugins/clearkey/hidl/include/Session.h
index f35560d..a159e5a 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/Session.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/Session.h
@@ -30,13 +30,16 @@
namespace V1_2 {
namespace clearkey {
-using ::android::hardware::drm::V1_0::Status;
-using ::android::hardware::drm::V1_0::SubSample;
+namespace drm = ::android::hardware::drm;
+using drm::V1_0::Status;
+using drm::V1_0::SubSample;
+
+typedef drm::V1_2::Status Status_V1_2;
class Session : public RefBase {
public:
explicit Session(const std::vector<uint8_t>& sessionId)
- : mSessionId(sessionId) {}
+ : mSessionId(sessionId), mMockError(Status_V1_2::OK) {}
virtual ~Session() {}
const std::vector<uint8_t>& sessionId() const { return mSessionId; }
@@ -50,17 +53,23 @@
Status provideKeyResponse(
const std::vector<uint8_t>& response);
- Status decrypt(
+ Status_V1_2 decrypt(
const KeyId keyId, const Iv iv, const uint8_t* srcPtr,
uint8_t* dstPtr, const std::vector<SubSample> subSamples,
size_t* bytesDecryptedOut);
+ void setMockError(Status_V1_2 error) {mMockError = error;}
+ Status_V1_2 getMockError() const {return mMockError;}
+
private:
CLEARKEY_DISALLOW_COPY_AND_ASSIGN(Session);
const std::vector<uint8_t> mSessionId;
KeyMap mKeyMap;
Mutex mMapLock;
+
+ // For mocking error return scenarios
+ Status_V1_2 mMockError;
};
} // namespace clearkey
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/TypeConvert.h b/drm/mediadrm/plugins/clearkey/hidl/include/TypeConvert.h
index f6d30c9..b0f8607 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/TypeConvert.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/TypeConvert.h
@@ -68,6 +68,17 @@
return vec;
}
+inline Status toStatus_1_0(Status_V1_2 status) {
+ switch (status) {
+ case Status_V1_2::ERROR_DRM_INSUFFICIENT_SECURITY:
+ case Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE:
+ case Status_V1_2::ERROR_DRM_SESSION_LOST_STATE:
+ return Status::ERROR_DRM_UNKNOWN;
+ default:
+ return static_cast<Status>(status);
+ }
+}
+
} // namespace clearkey
} // namespace V1_2
} // namespace drm
diff --git a/include/media/DataSource.h b/include/media/DataSource.h
index 905bec1..198b27e 120000
--- a/include/media/DataSource.h
+++ b/include/media/DataSource.h
@@ -1 +1 @@
-../../media/libmediaextractor/include/media/DataSource.h
\ No newline at end of file
+stagefright/DataSource.h
\ No newline at end of file
diff --git a/include/media/DataSourceBase.h b/include/media/DataSourceBase.h
index 54c8047..d2ab2f1 120000
--- a/include/media/DataSourceBase.h
+++ b/include/media/DataSourceBase.h
@@ -1 +1 @@
-../../media/libmediaextractor/include/media/DataSourceBase.h
\ No newline at end of file
+stagefright/DataSourceBase.h
\ No newline at end of file
diff --git a/include/media/ExtractorUtils.h b/include/media/ExtractorUtils.h
deleted file mode 120000
index e2dd082..0000000
--- a/include/media/ExtractorUtils.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmediaextractor/include/media/ExtractorUtils.h
\ No newline at end of file
diff --git a/media/libmediaextractor/include/media/ExtractorUtils.h b/include/media/ExtractorUtils.h
similarity index 100%
rename from media/libmediaextractor/include/media/ExtractorUtils.h
rename to include/media/ExtractorUtils.h
diff --git a/include/media/MediaSource.h b/include/media/MediaSource.h
index 2e147c4..34bf65d 120000
--- a/include/media/MediaSource.h
+++ b/include/media/MediaSource.h
@@ -1 +1 @@
-../../media/libmediaextractor/include/media/MediaSource.h
\ No newline at end of file
+../../media/libstagefright/include/media/stagefright/MediaSource.h
\ No newline at end of file
diff --git a/media/audioserver/audioserver.rc b/media/audioserver/audioserver.rc
index f1e815b..dfb1a3f 100644
--- a/media/audioserver/audioserver.rc
+++ b/media/audioserver/audioserver.rc
@@ -16,3 +16,6 @@
stop audioserver
on property:vts.native_server.on=0
start audioserver
+
+on init
+ mkdir /dev/socket/audioserver 0775 audioserver audioserver
diff --git a/media/codec2/components/cmds/Android.bp b/media/codec2/components/cmds/Android.bp
index 6b0977b..35f689e 100644
--- a/media/codec2/components/cmds/Android.bp
+++ b/media/codec2/components/cmds/Android.bp
@@ -15,7 +15,6 @@
"libcutils",
"libgui",
"liblog",
- "libmediaextractor",
"libstagefright",
"libstagefright_foundation",
"libui",
diff --git a/media/codec2/core/include/C2Component.h b/media/codec2/core/include/C2Component.h
index 8810725..ecf8d2e 100644
--- a/media/codec2/core/include/C2Component.h
+++ b/media/codec2/core/include/C2Component.h
@@ -409,12 +409,13 @@
kind_t kind; ///< component kind
rank_t rank; ///< component rank
C2String mediaType; ///< media type supported by the component
+ C2String owner; ///< name of the component store owning this component
/**
* name alias(es) for backward compatibility.
* \note Multiple components can have the same alias as long as their media-type differs.
*/
- std::vector<C2StringLiteral> aliases; ///< name aliases for backward compatibility
+ std::vector<C2String> aliases; ///< name aliases for backward compatibility
};
// METHODS AVAILABLE WHEN RUNNING
diff --git a/media/codec2/core/include/C2Param.h b/media/codec2/core/include/C2Param.h
index 40be3b3..efc5c89 100644
--- a/media/codec2/core/include/C2Param.h
+++ b/media/codec2/core/include/C2Param.h
@@ -988,7 +988,10 @@
/** specialization for easy enums */
template<typename E>
inline static NamedValuesType namedValuesFor(const C2EasyEnum<E> &) {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wnull-dereference"
return namedValuesFor(*(E*)nullptr);
+#pragma GCC diagnostic pop
}
private:
@@ -1104,7 +1107,10 @@
template<typename B>
struct C2FieldDescriptor::_NamedValuesGetter<B, true> {
inline static C2FieldDescriptor::NamedValuesType getNamedValues() {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wnull-dereference"
return C2FieldDescriptor::namedValuesFor(*(B*)nullptr);
+#pragma GCC diagnostic pop
}
};
@@ -1599,11 +1605,13 @@
/// \internal
/// \todo: create separate values vs. flags initializer as for flags we want
/// to list both allowed and required flags
- template<typename T, typename E=decltype(C2FieldDescriptor::namedValuesFor(*(T*)0))>
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wnull-dereference"
+ template<typename T, typename E=decltype(C2FieldDescriptor::namedValuesFor(*(T*)nullptr))>
C2FieldSupportedValues(bool flags, const T*)
: type(flags ? FLAGS : VALUES),
range{(T)0, (T)0, (T)0, (T)0, (T)0} {
- C2FieldDescriptor::NamedValuesType named = C2FieldDescriptor::namedValuesFor(*(T*)0);
+ C2FieldDescriptor::NamedValuesType named = C2FieldDescriptor::namedValuesFor(*(T*)nullptr);
if (flags) {
values.emplace_back(0); // min-mask defaults to 0
}
@@ -1612,6 +1620,7 @@
}
}
};
+#pragma GCC diagnostic pop
/**
* Supported values for a specific field.
diff --git a/media/codec2/hidl/client/client.cpp b/media/codec2/hidl/client/client.cpp
index ff3e534..f5cc9ff 100644
--- a/media/codec2/hidl/client/client.cpp
+++ b/media/codec2/hidl/client/client.cpp
@@ -557,6 +557,7 @@
for (size_t i = 0; i < t.size(); ++i) {
c2_status_t status = objcpy(
&mTraitsList[i], &mAliasesBuffer[i], t[i]);
+ mTraitsList[i].owner = mInstanceName;
if (status != C2_OK) {
ALOGE("listComponents -- corrupted output.");
return;
diff --git a/media/codec2/sfplugin/Codec2InfoBuilder.cpp b/media/codec2/sfplugin/Codec2InfoBuilder.cpp
index 184f215..a8cc62d 100644
--- a/media/codec2/sfplugin/Codec2InfoBuilder.cpp
+++ b/media/codec2/sfplugin/Codec2InfoBuilder.cpp
@@ -73,10 +73,10 @@
constexpr OMX_U32 kMaxIndicesToCheck = 32;
status_t queryOmxCapabilities(
- const char* name, const char* mime, bool isEncoder,
+ const char* name, const char* mediaType, bool isEncoder,
MediaCodecInfo::CapabilitiesWriter* caps) {
- const char *role = GetComponentRole(isEncoder, mime);
+ const char *role = GetComponentRole(isEncoder, mediaType);
if (role == nullptr) {
return BAD_VALUE;
}
@@ -128,8 +128,8 @@
return err;
}
- bool isVideo = hasPrefix(mime, "video/") == 0;
- bool isImage = hasPrefix(mime, "image/") == 0;
+ bool isVideo = hasPrefix(mediaType, "video/") == 0;
+ bool isImage = hasPrefix(mediaType, "image/") == 0;
if (isVideo || isImage) {
OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
@@ -149,7 +149,7 @@
// AVC components may not list the constrained profiles explicitly, but
// decoders that support a profile also support its constrained version.
// Encoders must explicitly support constrained profiles.
- if (!isEncoder && strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC) == 0) {
+ if (!isEncoder && strcasecmp(mediaType, MEDIA_MIMETYPE_VIDEO_AVC) == 0) {
if (param.eProfile == OMX_VIDEO_AVCProfileHigh) {
caps->addProfileLevel(OMX_VIDEO_AVCProfileConstrainedHigh, param.eLevel);
} else if (param.eProfile == OMX_VIDEO_AVCProfileBaseline) {
@@ -193,7 +193,7 @@
asString(portFormat.eColorFormat), portFormat.eColorFormat);
}
}
- } else if (strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC) == 0) {
+ } else if (strcasecmp(mediaType, MEDIA_MIMETYPE_AUDIO_AAC) == 0) {
// More audio codecs if they have profiles.
OMX_AUDIO_PARAM_ANDROID_PROFILETYPE param;
InitOMXParams(¶m);
@@ -228,14 +228,17 @@
if (omxNode->configureVideoTunnelMode(
kPortIndexOutput, OMX_TRUE, 0, &sidebandHandle) == OK) {
// tunneled playback includes adaptive playback
- caps->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback
- | MediaCodecInfo::Capabilities::kFlagSupportsTunneledPlayback);
- } else if (omxNode->setPortMode(
- kPortIndexOutput, IOMX::kPortModeDynamicANWBuffer) == OK ||
- omxNode->prepareForAdaptivePlayback(
- kPortIndexOutput, OMX_TRUE,
- 1280 /* width */, 720 /* height */) == OK) {
- caps->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback);
+ } else {
+ // tunneled playback is not supported
+ caps->removeDetail(MediaCodecInfo::Capabilities::FEATURE_TUNNELED_PLAYBACK);
+ if (omxNode->setPortMode(
+ kPortIndexOutput, IOMX::kPortModeDynamicANWBuffer) == OK ||
+ omxNode->prepareForAdaptivePlayback(
+ kPortIndexOutput, OMX_TRUE,
+ 1280 /* width */, 720 /* height */) != OK) {
+ // adaptive playback is not supported
+ caps->removeDetail(MediaCodecInfo::Capabilities::FEATURE_ADAPTIVE_PLAYBACK);
+ }
}
}
@@ -243,11 +246,20 @@
OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
InitOMXParams(¶ms);
params.nPortIndex = kPortIndexOutput;
- // TODO: should we verify if fallback is supported?
+
+ OMX_VIDEO_PARAM_INTRAREFRESHTYPE fallbackParams;
+ InitOMXParams(&fallbackParams);
+ fallbackParams.nPortIndex = kPortIndexOutput;
+ fallbackParams.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic;
+
if (omxNode->getConfig(
(OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh,
- ¶ms, sizeof(params)) == OK) {
- caps->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsIntraRefresh);
+ ¶ms, sizeof(params)) != OK &&
+ omxNode->getParameter(
+ OMX_IndexParamVideoIntraRefresh, &fallbackParams,
+ sizeof(fallbackParams)) != OK) {
+ // intra refresh is not supported
+ caps->removeDetail(MediaCodecInfo::Capabilities::FEATURE_INTRA_REFRESH);
}
}
@@ -270,12 +282,26 @@
writer->addMediaCodecInfo();
info->setName(name.c_str());
info->setOwner("default");
- info->setEncoder(encoder);
+ typename std::underlying_type<MediaCodecInfo::Attributes>::type attrs = 0;
+ if (encoder) {
+ attrs |= MediaCodecInfo::kFlagIsEncoder;
+ }
+ // NOTE: we don't support software-only codecs in OMX
+ if (!hasPrefix(name, "OMX.google.")) {
+ attrs |= MediaCodecInfo::kFlagIsVendor;
+ if (properties.quirkSet.find("attribute::software-codec")
+ == properties.quirkSet.end()) {
+ attrs |= MediaCodecInfo::kFlagIsHardwareAccelerated;
+ }
+ }
+ info->setAttributes(attrs);
info->setRank(omxRank);
- for (const MediaCodecsXmlParser::Type& type : properties.typeMap) {
- const std::string &mime = type.first;
+ // OMX components don't have aliases
+ for (const MediaCodecsXmlParser::Type &type : properties.typeMap) {
+ const std::string &mediaType = type.first;
+
std::unique_ptr<MediaCodecInfo::CapabilitiesWriter> caps =
- info->addMime(mime.c_str());
+ info->addMediaType(mediaType.c_str());
const MediaCodecsXmlParser::AttributeMap &attrMap = type.second;
for (const MediaCodecsXmlParser::Attribute& attr : attrMap) {
const std::string &key = attr.first;
@@ -289,13 +315,13 @@
}
status_t err = queryOmxCapabilities(
name.c_str(),
- mime.c_str(),
+ mediaType.c_str(),
encoder,
caps.get());
if (err != OK) {
- ALOGE("Failed to query capabilities for %s (mime: %s). Error: %d",
+ ALOGI("Failed to query capabilities for %s (media type: %s). Error: %d",
name.c_str(),
- mime.c_str(),
+ mediaType.c_str(),
static_cast<int>(err));
}
}
@@ -407,20 +433,40 @@
break;
}
+ ALOGV("canonName = %s", canonName.c_str());
std::unique_ptr<MediaCodecInfoWriter> codecInfo = writer->addMediaCodecInfo();
codecInfo->setName(trait.name.c_str());
- codecInfo->setOwner("codec2");
+ codecInfo->setOwner(("codec2::" + trait.owner).c_str());
+ const MediaCodecsXmlParser::CodecProperties &codec = parser.getCodecMap().at(canonName);
+
bool encoder = trait.kind == C2Component::KIND_ENCODER;
- codecInfo->setEncoder(encoder);
+ typename std::underlying_type<MediaCodecInfo::Attributes>::type attrs = 0;
+
+ if (encoder) {
+ attrs |= MediaCodecInfo::kFlagIsEncoder;
+ }
+ if (trait.owner == "software") {
+ attrs |= MediaCodecInfo::kFlagIsSoftwareOnly;
+ } else {
+ attrs |= MediaCodecInfo::kFlagIsVendor;
+ if (trait.owner == "vendor-software") {
+ attrs |= MediaCodecInfo::kFlagIsSoftwareOnly;
+ } else if (codec.quirkSet.find("attribute::software-codec") == codec.quirkSet.end()) {
+ attrs |= MediaCodecInfo::kFlagIsHardwareAccelerated;
+ }
+ }
+ codecInfo->setAttributes(attrs);
codecInfo->setRank(rank);
- const MediaCodecsXmlParser::CodecProperties &codec =
- parser.getCodecMap().at(canonName);
+
+ for (const std::string &alias : codec.aliases) {
+ codecInfo->addAlias(alias.c_str());
+ }
for (auto typeIt = codec.typeMap.begin(); typeIt != codec.typeMap.end(); ++typeIt) {
const std::string &mediaType = typeIt->first;
const MediaCodecsXmlParser::AttributeMap &attrMap = typeIt->second;
std::unique_ptr<MediaCodecInfo::CapabilitiesWriter> caps =
- codecInfo->addMime(mediaType.c_str());
+ codecInfo->addMediaType(mediaType.c_str());
for (auto attrIt = attrMap.begin(); attrIt != attrMap.end(); ++attrIt) {
std::string key, value;
std::tie(key, value) = *attrIt;
diff --git a/media/extractors/amr/AMRExtractor.cpp b/media/extractors/amr/AMRExtractor.cpp
index df8de9b..ffeff42 100644
--- a/media/extractors/amr/AMRExtractor.cpp
+++ b/media/extractors/amr/AMRExtractor.cpp
@@ -280,8 +280,8 @@
ReadOptions::SeekMode mode;
if (mOffsetTableLength > 0 && options && options->getSeekTo(&seekTimeUs, &mode)) {
size_t size;
- int64_t seekFrame = seekTimeUs / 20000ll; // 20ms per frame.
- mCurrentTimeUs = seekFrame * 20000ll;
+ int64_t seekFrame = seekTimeUs / 20000LL; // 20ms per frame.
+ mCurrentTimeUs = seekFrame * 20000LL;
size_t index = seekFrame < 0 ? 0 : seekFrame / 50;
if (index >= mOffsetTableLength) {
diff --git a/media/extractors/flac/FLACExtractor.cpp b/media/extractors/flac/FLACExtractor.cpp
index e4bbc07..84fbcee 100644
--- a/media/extractors/flac/FLACExtractor.cpp
+++ b/media/extractors/flac/FLACExtractor.cpp
@@ -806,14 +806,42 @@
bool SniffFLAC(DataSourceHelper *source, float *confidence)
{
- // first 4 is the signature word
- // second 4 is the sizeof STREAMINFO
- // 042 is the mandatory STREAMINFO
- // no need to read rest of the header, as a premature EOF will be caught later
- uint8_t header[4+4];
- if (source->readAt(0, header, sizeof(header)) != sizeof(header)
- || memcmp("fLaC\0\0\0\042", header, 4+4))
- {
+ // Skip ID3 tags
+ off64_t pos = 0;
+ uint8_t header[10];
+ for (;;) {
+ if (source->readAt(pos, header, sizeof(header)) != sizeof(header)) {
+ return false; // no more file to read.
+ }
+
+ // check for ID3 tag
+ if (memcmp("ID3", header, 3) != 0) {
+ break; // not an ID3 tag.
+ }
+
+ // skip the ID3v2 data and check again
+ const unsigned id3Len = 10 +
+ (((header[6] & 0x7f) << 21)
+ | ((header[7] & 0x7f) << 14)
+ | ((header[8] & 0x7f) << 7)
+ | (header[9] & 0x7f));
+ pos += id3Len;
+
+ ALOGV("skipped ID3 tag of len %u new starting offset is %#016llx",
+ id3Len, (long long)pos);
+ }
+
+ // Check FLAC header.
+ // https://xiph.org/flac/format.html#stream
+ //
+ // Note: content stored big endian.
+ // byte offset bit size content
+ // 0 32 fLaC
+ // 4 8 metadata type STREAMINFO (0) (note: OR with 0x80 if last metadata)
+ // 5 24 size of metadata, for STREAMINFO (0x22).
+
+ if (memcmp("fLaC\x00\x00\x00\x22", header, 8) != 0 &&
+ memcmp("fLaC\x80\x00\x00\x22", header, 8) != 0) {
return false;
}
diff --git a/media/extractors/mp3/VBRISeeker.cpp b/media/extractors/mp3/VBRISeeker.cpp
index 9eb72a7..ca51b88 100644
--- a/media/extractors/mp3/VBRISeeker.cpp
+++ b/media/extractors/mp3/VBRISeeker.cpp
@@ -71,7 +71,7 @@
size_t numFrames = U32_AT(&vbriHeader[14]);
int64_t durationUs =
- numFrames * 1000000ll * (sampleRate >= 32000 ? 1152 : 576) / sampleRate;
+ numFrames * 1000000LL * (sampleRate >= 32000 ? 1152 : 576) / sampleRate;
ALOGV("duration = %.2f secs", durationUs / 1E6);
diff --git a/media/extractors/mpeg2/Android.bp b/media/extractors/mpeg2/Android.bp
index b816093..2a94671 100644
--- a/media/extractors/mpeg2/Android.bp
+++ b/media/extractors/mpeg2/Android.bp
@@ -28,9 +28,8 @@
static_libs: [
"libcrypto",
- "libstagefright_foundation",
+ "libstagefright_foundation_without_imemory",
"libstagefright_mpeg2support",
- "libmediaextractor",
"libutils",
"libstagefright",
"libstagefright_esds",
diff --git a/media/extractors/mpeg2/MPEG2PSExtractor.cpp b/media/extractors/mpeg2/MPEG2PSExtractor.cpp
index 554d252..731584d 100644
--- a/media/extractors/mpeg2/MPEG2PSExtractor.cpp
+++ b/media/extractors/mpeg2/MPEG2PSExtractor.cpp
@@ -734,6 +734,9 @@
if (inMeta.findData(kKeySEI, &bufType, &bufData, &bufSize)) {
AMediaFormat_setBuffer(outMeta, AMEDIAFORMAT_KEY_SEI, bufData, bufSize);
}
+ if (inMeta.findData(kKeyAudioPresentationInfo, &bufType, &bufData, &bufSize)) {
+ AMediaFormat_setBuffer(outMeta, AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_INFO, bufData, bufSize);
+ }
mbuf->release();
return AMEDIA_OK;
}
@@ -790,6 +793,7 @@
}
media_status_t MPEG2PSExtractor::WrappedTrack::start() {
+ mTrack->mBufferGroup = mBufferGroup;
return mTrack->start();
}
diff --git a/media/extractors/mpeg2/MPEG2TSExtractor.cpp b/media/extractors/mpeg2/MPEG2TSExtractor.cpp
index 3bb2af7..e1509ee 100644
--- a/media/extractors/mpeg2/MPEG2TSExtractor.cpp
+++ b/media/extractors/mpeg2/MPEG2TSExtractor.cpp
@@ -224,6 +224,9 @@
if (inMeta.findData(kKeySEI, &bufType, &bufData, &bufSize)) {
AMediaFormat_setBuffer(outMeta, AMEDIAFORMAT_KEY_SEI, bufData, bufSize);
}
+ if (inMeta.findData(kKeyAudioPresentationInfo, &bufType, &bufData, &bufSize)) {
+ AMediaFormat_setBuffer(outMeta, AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_INFO, bufData, bufSize);
+ }
mbuf->release();
return AMEDIA_OK;
}
@@ -373,7 +376,7 @@
}
// Wait only for 2 seconds to detect audio/video streams.
- if (ALooper::GetNowUs() - startTime > 2000000ll) {
+ if (ALooper::GetNowUs() - startTime > 2000000LL) {
break;
}
}
@@ -385,7 +388,7 @@
List<int64_t> durations;
// Estimate duration --- stabilize until you get <500ms deviation.
while (feedMore() == OK
- && ALooper::GetNowUs() - startTime <= 2000000ll) {
+ && ALooper::GetNowUs() - startTime <= 2000000LL) {
if (mSeekSyncPoints->size() > prevSyncSize) {
prevSyncSize = mSeekSyncPoints->size();
int64_t diffUs = mSeekSyncPoints->keyAt(prevSyncSize - 1)
diff --git a/media/extractors/ogg/OggExtractor.cpp b/media/extractors/ogg/OggExtractor.cpp
index 6efbfee..596c1c8 100644
--- a/media/extractors/ogg/OggExtractor.cpp
+++ b/media/extractors/ogg/OggExtractor.cpp
@@ -515,10 +515,10 @@
ALOGV("failed to read %zu bytes at offset %#016llx, got %zd bytes",
sizeof(header), (long long)offset, n);
- if (n < 0) {
- return n;
- } else if (n == 0) {
+ if (n == 0 || n == ERROR_END_OF_STREAM) {
return AMEDIA_ERROR_END_OF_STREAM;
+ } else if (n < 0) {
+ return AMEDIA_ERROR_UNKNOWN;
} else {
return AMEDIA_ERROR_IO;
}
@@ -872,7 +872,7 @@
ALOGV("readPage returned %zd", n);
- return n == ERROR_END_OF_STREAM ? AMEDIA_ERROR_END_OF_STREAM : AMEDIA_ERROR_UNKNOWN;
+ return (media_status_t) n;
}
// Prevent a harmless unsigned integer overflow by clamping to 0
diff --git a/media/libaaudio/include/aaudio/AAudio.h b/media/libaaudio/include/aaudio/AAudio.h
index 1493b26..8e36c77 100644
--- a/media/libaaudio/include/aaudio/AAudio.h
+++ b/media/libaaudio/include/aaudio/AAudio.h
@@ -373,6 +373,13 @@
* so the recorded volume may be very low.
*/
AAUDIO_INPUT_PRESET_UNPROCESSED = 9,
+
+ /**
+ * Use this preset for capturing audio meant to be processed in real time
+ * and played back for live performance (e.g karaoke).
+ * The capture path will minimize latency and coupling with playback path.
+ */
+ AAUDIO_INPUT_PRESET_VOICE_PERFORMANCE = 10,
};
typedef int32_t aaudio_input_preset_t;
diff --git a/media/libaaudio/src/core/AAudioStreamParameters.cpp b/media/libaaudio/src/core/AAudioStreamParameters.cpp
index bd42697..88da53a 100644
--- a/media/libaaudio/src/core/AAudioStreamParameters.cpp
+++ b/media/libaaudio/src/core/AAudioStreamParameters.cpp
@@ -158,6 +158,7 @@
case AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION:
case AAUDIO_INPUT_PRESET_VOICE_RECOGNITION:
case AAUDIO_INPUT_PRESET_UNPROCESSED:
+ case AAUDIO_INPUT_PRESET_VOICE_PERFORMANCE:
break; // valid
default:
ALOGE("input preset not valid = %d", mInputPreset);
diff --git a/media/libaaudio/src/utility/AAudioUtilities.cpp b/media/libaaudio/src/utility/AAudioUtilities.cpp
index f5b3ad4..723cbf1 100644
--- a/media/libaaudio/src/utility/AAudioUtilities.cpp
+++ b/media/libaaudio/src/utility/AAudioUtilities.cpp
@@ -210,6 +210,7 @@
STATIC_ASSERT(AAUDIO_INPUT_PRESET_VOICE_RECOGNITION == AUDIO_SOURCE_VOICE_RECOGNITION);
STATIC_ASSERT(AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION == AUDIO_SOURCE_VOICE_COMMUNICATION);
STATIC_ASSERT(AAUDIO_INPUT_PRESET_UNPROCESSED == AUDIO_SOURCE_UNPROCESSED);
+ STATIC_ASSERT(AAUDIO_INPUT_PRESET_VOICE_PERFORMANCE == AUDIO_SOURCE_VOICE_PERFORMANCE);
if (preset == AAUDIO_UNSPECIFIED) {
preset = AAUDIO_INPUT_PRESET_VOICE_RECOGNITION;
}
diff --git a/media/libaaudio/tests/test_attributes.cpp b/media/libaaudio/tests/test_attributes.cpp
index b01af25..dbf8712 100644
--- a/media/libaaudio/tests/test_attributes.cpp
+++ b/media/libaaudio/tests/test_attributes.cpp
@@ -130,6 +130,7 @@
AAUDIO_INPUT_PRESET_VOICE_RECOGNITION,
AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION,
AAUDIO_INPUT_PRESET_UNPROCESSED,
+ AAUDIO_INPUT_PRESET_VOICE_PERFORMANCE,
};
static void checkAttributesUsage(aaudio_performance_mode_t perfMode) {
diff --git a/media/libaudioclient/AudioPolicy.cpp b/media/libaudioclient/AudioPolicy.cpp
index 9601d6d..3ab38cd 100644
--- a/media/libaudioclient/AudioPolicy.cpp
+++ b/media/libaudioclient/AudioPolicy.cpp
@@ -143,11 +143,18 @@
return NO_ERROR;
}
-void AudioMix::excludeUid(uid_t uid) const {
+void AudioMix::setExcludeUid(uid_t uid) const {
AudioMixMatchCriterion crit;
crit.mRule = RULE_EXCLUDE_UID;
crit.mValue.mUid = uid;
mCriteria.add(crit);
}
+void AudioMix::setMatchUid(uid_t uid) const {
+ AudioMixMatchCriterion crit;
+ crit.mRule = RULE_MATCH_UID;
+ crit.mValue.mUid = uid;
+ mCriteria.add(crit);
+}
+
} // namespace android
diff --git a/media/libaudioclient/include/media/AudioPolicy.h b/media/libaudioclient/include/media/AudioPolicy.h
index 96e1235..786fb9a 100644
--- a/media/libaudioclient/include/media/AudioPolicy.h
+++ b/media/libaudioclient/include/media/AudioPolicy.h
@@ -100,7 +100,8 @@
status_t readFromParcel(Parcel *parcel);
status_t writeToParcel(Parcel *parcel) const;
- void excludeUid(uid_t uid) const;
+ void setExcludeUid(uid_t uid) const;
+ void setMatchUid(uid_t uid) const;
mutable Vector<AudioMixMatchCriterion> mCriteria;
uint32_t mMixType;
diff --git a/media/libeffects/config/src/EffectsConfig.cpp b/media/libeffects/config/src/EffectsConfig.cpp
index 76b4adc..f39eb0c 100644
--- a/media/libeffects/config/src/EffectsConfig.cpp
+++ b/media/libeffects/config/src/EffectsConfig.cpp
@@ -115,6 +115,7 @@
{AUDIO_SOURCE_VOICE_RECOGNITION, "voice_recognition"},
{AUDIO_SOURCE_VOICE_COMMUNICATION, "voice_communication"},
{AUDIO_SOURCE_UNPROCESSED, "unprocessed"},
+ {AUDIO_SOURCE_VOICE_PERFORMANCE, "voice_performance"},
};
/** Find the stream type enum corresponding to the stream type name or return false */
diff --git a/media/libmedia/Android.bp b/media/libmedia/Android.bp
index 7d759e0..3efb5de 100644
--- a/media/libmedia/Android.bp
+++ b/media/libmedia/Android.bp
@@ -220,7 +220,6 @@
"libexpat",
"libcamera_client",
"libstagefright_foundation",
- "libmediaextractor",
"libgui",
"libdl",
"libaudioutils",
@@ -277,7 +276,6 @@
"libbinder",
"libcutils",
"liblog",
- "libmediaextractor",
"libmediandk",
"libnativewindow",
"libmediandk_utils",
diff --git a/media/libmedia/MediaCodecInfo.cpp b/media/libmedia/MediaCodecInfo.cpp
index 5308e1c..86ad997 100644
--- a/media/libmedia/MediaCodecInfo.cpp
+++ b/media/libmedia/MediaCodecInfo.cpp
@@ -28,6 +28,15 @@
namespace android {
+/** This redundant redeclaration is needed for C++ pre 14 */
+constexpr char MediaCodecInfo::Capabilities::FEATURE_ADAPTIVE_PLAYBACK[];
+constexpr char MediaCodecInfo::Capabilities::FEATURE_DYNAMIC_TIMESTAMP[];
+constexpr char MediaCodecInfo::Capabilities::FEATURE_FRAME_PARSING[];
+constexpr char MediaCodecInfo::Capabilities::FEATURE_INTRA_REFRESH[];
+constexpr char MediaCodecInfo::Capabilities::FEATURE_MULTIPLE_FRAMES[];
+constexpr char MediaCodecInfo::Capabilities::FEATURE_SECURE_PLAYBACK[];
+constexpr char MediaCodecInfo::Capabilities::FEATURE_TUNNELED_PLAYBACK[];
+
void MediaCodecInfo::Capabilities::getSupportedProfileLevels(
Vector<ProfileLevel> *profileLevels) const {
profileLevels->clear();
@@ -40,16 +49,11 @@
colorFormats->appendVector(mColorFormats);
}
-uint32_t MediaCodecInfo::Capabilities::getFlags() const {
- return mFlags;
-}
-
const sp<AMessage> MediaCodecInfo::Capabilities::getDetails() const {
return mDetails;
}
-MediaCodecInfo::Capabilities::Capabilities()
- : mFlags(0) {
+MediaCodecInfo::Capabilities::Capabilities() {
mDetails = new AMessage;
}
@@ -73,12 +77,10 @@
caps->mColorFormats.push_back(color);
}
}
- uint32_t flags = static_cast<uint32_t>(parcel.readInt32());
sp<AMessage> details = AMessage::FromParcel(parcel);
if (details == NULL)
return NULL;
if (caps != NULL) {
- caps->mFlags = flags;
caps->mDetails = details;
}
return caps;
@@ -96,7 +98,6 @@
for (size_t i = 0; i < mColorFormats.size(); i++) {
parcel->writeInt32(mColorFormats.itemAt(i));
}
- parcel->writeInt32(mFlags);
mDetails->writeToParcel(parcel);
return OK;
}
@@ -111,6 +112,14 @@
mCap->mDetails->setInt32(key, value);
}
+void MediaCodecInfo::CapabilitiesWriter::removeDetail(const char* key) {
+ if (mCap->mDetails->removeEntryAt(mCap->mDetails->findEntryByName(key)) == OK) {
+ ALOGD("successfully removed detail %s", key);
+ } else {
+ ALOGD("detail %s wasn't present to remove", key);
+ }
+}
+
void MediaCodecInfo::CapabilitiesWriter::addProfileLevel(
uint32_t profile, uint32_t level) {
ProfileLevel profileLevel;
@@ -129,32 +138,32 @@
}
}
-void MediaCodecInfo::CapabilitiesWriter::addFlags(uint32_t flags) {
- mCap->mFlags |= flags;
-}
-
MediaCodecInfo::CapabilitiesWriter::CapabilitiesWriter(
MediaCodecInfo::Capabilities* cap) : mCap(cap) {
}
-bool MediaCodecInfo::isEncoder() const {
- return mIsEncoder;
+MediaCodecInfo::Attributes MediaCodecInfo::getAttributes() const {
+ return mAttributes;
}
-uint32_t MediaCodecInfo::rank() const {
+uint32_t MediaCodecInfo::getRank() const {
return mRank;
}
-void MediaCodecInfo::getSupportedMimes(Vector<AString> *mimes) const {
- mimes->clear();
+void MediaCodecInfo::getAliases(Vector<AString> *aliases) const {
+ *aliases = mAliases;
+}
+
+void MediaCodecInfo::getSupportedMediaTypes(Vector<AString> *mediaTypes) const {
+ mediaTypes->clear();
for (size_t ix = 0; ix < mCaps.size(); ix++) {
- mimes->push_back(mCaps.keyAt(ix));
+ mediaTypes->push_back(mCaps.keyAt(ix));
}
}
const sp<MediaCodecInfo::Capabilities>
-MediaCodecInfo::getCapabilitiesFor(const char *mime) const {
- ssize_t ix = getCapabilityIndex(mime);
+MediaCodecInfo::getCapabilitiesFor(const char *mediaType) const {
+ ssize_t ix = getCapabilityIndex(mediaType);
if (ix >= 0) {
return mCaps.valueAt(ix);
}
@@ -173,21 +182,26 @@
sp<MediaCodecInfo> MediaCodecInfo::FromParcel(const Parcel &parcel) {
AString name = AString::FromParcel(parcel);
AString owner = AString::FromParcel(parcel);
- bool isEncoder = static_cast<bool>(parcel.readInt32());
+ Attributes attributes = static_cast<Attributes>(parcel.readInt32());
uint32_t rank = parcel.readUint32();
sp<MediaCodecInfo> info = new MediaCodecInfo;
info->mName = name;
info->mOwner = owner;
- info->mIsEncoder = isEncoder;
+ info->mAttributes = attributes;
info->mRank = rank;
+ size_t numAliases = static_cast<size_t>(parcel.readInt32());
+ for (size_t i = 0; i < numAliases; i++) {
+ AString alias = AString::FromParcel(parcel);
+ info->mAliases.add(alias);
+ }
size_t size = static_cast<size_t>(parcel.readInt32());
for (size_t i = 0; i < size; i++) {
- AString mime = AString::FromParcel(parcel);
+ AString mediaType = AString::FromParcel(parcel);
sp<Capabilities> caps = Capabilities::FromParcel(parcel);
if (caps == NULL)
return NULL;
if (info != NULL) {
- info->mCaps.add(mime, caps);
+ info->mCaps.add(mediaType, caps);
}
}
return info;
@@ -196,8 +210,12 @@
status_t MediaCodecInfo::writeToParcel(Parcel *parcel) const {
mName.writeToParcel(parcel);
mOwner.writeToParcel(parcel);
- parcel->writeInt32(mIsEncoder);
+ parcel->writeInt32(mAttributes);
parcel->writeUint32(mRank);
+ parcel->writeInt32(mAliases.size());
+ for (const AString &alias : mAliases) {
+ alias.writeToParcel(parcel);
+ }
parcel->writeInt32(mCaps.size());
for (size_t i = 0; i < mCaps.size(); i++) {
mCaps.keyAt(i).writeToParcel(parcel);
@@ -206,10 +224,10 @@
return OK;
}
-ssize_t MediaCodecInfo::getCapabilityIndex(const char *mime) const {
- if (mime) {
+ssize_t MediaCodecInfo::getCapabilityIndex(const char *mediaType) const {
+ if (mediaType) {
for (size_t ix = 0; ix < mCaps.size(); ix++) {
- if (mCaps.keyAt(ix).equalsIgnoreCase(mime)) {
+ if (mCaps.keyAt(ix).equalsIgnoreCase(mediaType)) {
return ix;
}
}
@@ -217,19 +235,26 @@
return -1;
}
-MediaCodecInfo::MediaCodecInfo() : mRank(0x100) {
+MediaCodecInfo::MediaCodecInfo()
+ : mAttributes((MediaCodecInfo::Attributes)0),
+ mRank(0x100) {
}
void MediaCodecInfoWriter::setName(const char* name) {
mInfo->mName = name;
}
+void MediaCodecInfoWriter::addAlias(const char* name) {
+ mInfo->mAliases.add(name);
+}
+
void MediaCodecInfoWriter::setOwner(const char* owner) {
mInfo->mOwner = owner;
}
-void MediaCodecInfoWriter::setEncoder(bool isEncoder) {
- mInfo->mIsEncoder = isEncoder;
+void MediaCodecInfoWriter::setAttributes(
+ typename std::underlying_type<MediaCodecInfo::Attributes>::type attributes) {
+ mInfo->mAttributes = (MediaCodecInfo::Attributes)attributes;
}
void MediaCodecInfoWriter::setRank(uint32_t rank) {
@@ -237,21 +262,21 @@
}
std::unique_ptr<MediaCodecInfo::CapabilitiesWriter>
- MediaCodecInfoWriter::addMime(const char *mime) {
- ssize_t ix = mInfo->getCapabilityIndex(mime);
+ MediaCodecInfoWriter::addMediaType(const char *mediaType) {
+ ssize_t ix = mInfo->getCapabilityIndex(mediaType);
if (ix >= 0) {
return std::unique_ptr<MediaCodecInfo::CapabilitiesWriter>(
new MediaCodecInfo::CapabilitiesWriter(
mInfo->mCaps.valueAt(ix).get()));
}
sp<MediaCodecInfo::Capabilities> caps = new MediaCodecInfo::Capabilities();
- mInfo->mCaps.add(AString(mime), caps);
+ mInfo->mCaps.add(AString(mediaType), caps);
return std::unique_ptr<MediaCodecInfo::CapabilitiesWriter>(
new MediaCodecInfo::CapabilitiesWriter(caps.get()));
}
-bool MediaCodecInfoWriter::removeMime(const char *mime) {
- ssize_t ix = mInfo->getCapabilityIndex(mime);
+bool MediaCodecInfoWriter::removeMediaType(const char *mediaType) {
+ ssize_t ix = mInfo->getCapabilityIndex(mediaType);
if (ix >= 0) {
mInfo->mCaps.removeItemsAt(ix);
return true;
diff --git a/media/libmedia/TypeConverter.cpp b/media/libmedia/TypeConverter.cpp
index b5a7172..0ab0e9b 100644
--- a/media/libmedia/TypeConverter.cpp
+++ b/media/libmedia/TypeConverter.cpp
@@ -93,6 +93,8 @@
MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BUS),
MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_PROXY),
MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_USB_HEADSET),
+ MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_BLE),
+ MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_ECHO_REFERENCE),
MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_DEFAULT),
// STUB must be after DEFAULT, so the latter is picked up by toString first.
MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_STUB),
@@ -357,6 +359,8 @@
MAKE_STRING_FROM_ENUM(AUDIO_SOURCE_VOICE_COMMUNICATION),
MAKE_STRING_FROM_ENUM(AUDIO_SOURCE_REMOTE_SUBMIX),
MAKE_STRING_FROM_ENUM(AUDIO_SOURCE_UNPROCESSED),
+ MAKE_STRING_FROM_ENUM(AUDIO_SOURCE_VOICE_PERFORMANCE),
+ MAKE_STRING_FROM_ENUM(AUDIO_SOURCE_ECHO_REFERENCE),
MAKE_STRING_FROM_ENUM(AUDIO_SOURCE_FM_TUNER),
MAKE_STRING_FROM_ENUM(AUDIO_SOURCE_HOTWORD),
TERMINATOR
diff --git a/media/libmedia/include/media/CryptoHal.h b/media/libmedia/include/media/CryptoHal.h
index ff8789d..73c029f 100644
--- a/media/libmedia/include/media/CryptoHal.h
+++ b/media/libmedia/include/media/CryptoHal.h
@@ -21,6 +21,7 @@
#include <android/hardware/drm/1.0/ICryptoFactory.h>
#include <android/hardware/drm/1.0/ICryptoPlugin.h>
#include <android/hardware/drm/1.1/ICryptoFactory.h>
+#include <android/hardware/drm/1.2/ICryptoPlugin.h>
#include <mediadrm/ICrypto.h>
#include <utils/KeyedVector.h>
@@ -72,6 +73,7 @@
const Vector<sp<ICryptoFactory>> mFactories;
sp<ICryptoPlugin> mPlugin;
+ sp<drm::V1_2::ICryptoPlugin> mPluginV1_2;
/**
* mInitCheck is:
diff --git a/media/libmedia/include/media/DrmHal.h b/media/libmedia/include/media/DrmHal.h
index 3302982..de0f3c7 100644
--- a/media/libmedia/include/media/DrmHal.h
+++ b/media/libmedia/include/media/DrmHal.h
@@ -20,11 +20,11 @@
#include <android/hardware/drm/1.0/IDrmFactory.h>
#include <android/hardware/drm/1.0/IDrmPlugin.h>
-#include <android/hardware/drm/1.0/IDrmPluginListener.h>
#include <android/hardware/drm/1.1/IDrmFactory.h>
#include <android/hardware/drm/1.1/IDrmPlugin.h>
#include <android/hardware/drm/1.2/IDrmFactory.h>
#include <android/hardware/drm/1.2/IDrmPlugin.h>
+#include <android/hardware/drm/1.2/IDrmPluginListener.h>
#include <media/MediaAnalyticsItem.h>
#include <mediadrm/DrmMetrics.h>
@@ -43,6 +43,8 @@
using ::android::hardware::Return;
using ::android::hardware::Void;
+typedef drm::V1_2::IDrmPluginListener IDrmPluginListener_V1_2;
+
namespace android {
struct DrmSessionClientInterface;
@@ -54,7 +56,7 @@
struct DrmHal : public BnDrm,
public IBinder::DeathRecipient,
- public IDrmPluginListener {
+ public IDrmPluginListener_V1_2 {
DrmHal();
virtual ~DrmHal();
@@ -176,6 +178,8 @@
Return<void> sendKeysChange(const hidl_vec<uint8_t>& sessionId,
const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey);
+ Return<void> sendSessionLostState(const hidl_vec<uint8_t>& sessionId);
+
virtual void binderDied(const wp<IBinder> &the_late_who);
private:
diff --git a/media/libmedia/include/media/MediaCodecInfo.h b/media/libmedia/include/media/MediaCodecInfo.h
index b3777d3..54f565a 100644
--- a/media/libmedia/include/media/MediaCodecInfo.h
+++ b/media/libmedia/include/media/MediaCodecInfo.h
@@ -30,6 +30,8 @@
#include <utils/Vector.h>
#include <utils/StrongPointer.h>
+#include <type_traits>
+
namespace android {
struct AMessage;
@@ -51,21 +53,47 @@
struct CapabilitiesWriter;
+ enum Attributes : int32_t {
+ // attribute flags
+ kFlagIsEncoder = 1 << 0,
+ kFlagIsVendor = 1 << 1,
+ kFlagIsSoftwareOnly = 1 << 2,
+ kFlagIsHardwareAccelerated = 1 << 3,
+ };
+
struct Capabilities : public RefBase {
- enum {
- // decoder flags
- kFlagSupportsAdaptivePlayback = 1 << 0,
- kFlagSupportsSecurePlayback = 1 << 1,
- kFlagSupportsTunneledPlayback = 1 << 2,
+ constexpr static char FEATURE_ADAPTIVE_PLAYBACK[] = "feature-adaptive-playback";
+ constexpr static char FEATURE_DYNAMIC_TIMESTAMP[] = "feature-dynamic-timestamp";
+ constexpr static char FEATURE_FRAME_PARSING[] = "feature-frame-parsing";
+ constexpr static char FEATURE_INTRA_REFRESH[] = "feature-frame-parsing";
+ constexpr static char FEATURE_MULTIPLE_FRAMES[] = "feature-multiple-frames";
+ constexpr static char FEATURE_SECURE_PLAYBACK[] = "feature-secure-playback";
+ constexpr static char FEATURE_TUNNELED_PLAYBACK[] = "feature-tunneled-playback";
- // encoder flags
- kFlagSupportsIntraRefresh = 1 << 0,
-
- };
-
+ /**
+ * Returns the supported levels for each supported profile in a target array.
+ *
+ * @param profileLevels target array for the profile levels.
+ */
void getSupportedProfileLevels(Vector<ProfileLevel> *profileLevels) const;
+
+ /**
+ * Returns the supported color formats in a target array. Only used for video/image
+ * components.
+ *
+ * @param colorFormats target array for the color formats.
+ */
void getSupportedColorFormats(Vector<uint32_t> *colorFormats) const;
- uint32_t getFlags() const;
+
+ /**
+ * Returns metadata associated with this codec capability.
+ *
+ * This contains:
+ * - features,
+ * - performance data.
+ *
+ * TODO: expose this as separate API-s and wrap here.
+ */
const sp<AMessage> getDetails() const;
protected:
@@ -73,7 +101,6 @@
SortedVector<ProfileLevel> mProfileLevelsSorted;
Vector<uint32_t> mColorFormats;
SortedVector<uint32_t> mColorFormatsSorted;
- uint32_t mFlags;
sp<AMessage> mDetails;
Capabilities();
@@ -93,8 +120,7 @@
/**
* This class is used for modifying information inside a `Capabilities`
* object. An object of type `CapabilitiesWriter` can be obtained by calling
- * `MediaCodecInfoWriter::addMime()` or
- * `MediaCodecInfoWriter::updateMime()`.
+ * `MediaCodecInfoWriter::addMediaType()`.
*/
struct CapabilitiesWriter {
/**
@@ -122,6 +148,13 @@
*/
void addDetail(const char* key, int32_t value);
/**
+ * Removes a key-value pair from the list of details. If the key is not
+ * present, this call does nothing.
+ *
+ * @param key The key.
+ */
+ void removeDetail(const char* key);
+ /**
* Add a profile-level pair. If this profile-level pair already exists,
* it will be ignored.
*
@@ -136,13 +169,7 @@
* @param format The color format.
*/
void addColorFormat(uint32_t format);
- /**
- * Add flags. The underlying operation is bitwise-or. In other words,
- * bits that have already been set will be ignored.
- *
- * @param flags The additional flags.
- */
- void addFlags(uint32_t flags);
+
private:
/**
* The associated `Capabilities` object.
@@ -158,19 +185,42 @@
friend MediaCodecInfoWriter;
};
- bool isEncoder() const;
- void getSupportedMimes(Vector<AString> *mimes) const;
- const sp<Capabilities> getCapabilitiesFor(const char *mime) const;
+ inline bool isEncoder() const {
+ return getAttributes() & kFlagIsEncoder;
+ }
+
+ Attributes getAttributes() const;
+ void getSupportedMediaTypes(Vector<AString> *mediaTypes) const;
+ const sp<Capabilities> getCapabilitiesFor(const char *mediaType) const;
const char *getCodecName() const;
/**
+ * Returns a vector containing alternate names for the codec.
+ *
+ * \param aliases the destination array for the aliases. This is cleared.
+ *
+ * Multiple codecs may share alternate names as long as their supported media types are
+ * distinct; however, these will result in different aliases for the MediaCodec user as
+ * the canonical codec has to be resolved without knowing the media type in
+ * MediaCodec::CreateByComponentName.
+ */
+ void getAliases(Vector<AString> *aliases) const;
+
+ /**
* Return the name of the service that hosts the codec. This value is not
* visible at the Java level.
*
* Currently, this is the "instance name" of the IOmx service.
*/
const char *getOwnerName() const;
- uint32_t rank() const;
+
+ /**
+ * Returns the rank of the component.
+ *
+ * Technically this is defined to be per media type, but that makes ordering the MediaCodecList
+ * impossible as MediaCodecList is ordered by codec name.
+ */
+ uint32_t getRank() const;
/**
* Serialization over Binder
@@ -181,11 +231,12 @@
private:
AString mName;
AString mOwner;
- bool mIsEncoder;
+ Attributes mAttributes;
KeyedVector<AString, sp<Capabilities> > mCaps;
+ Vector<AString> mAliases;
uint32_t mRank;
- ssize_t getCapabilityIndex(const char *mime) const;
+ ssize_t getCapabilityIndex(const char *mediaType) const;
/**
* Construct an `MediaCodecInfo` object. After the construction, its
@@ -219,6 +270,13 @@
*/
void setName(const char* name);
/**
+ * Adds an alias (alternate name) for the codec. Multiple codecs can share an alternate name
+ * as long as their supported media types are distinct.
+ *
+ * @param name an alternate name.
+ */
+ void addAlias(const char* name);
+ /**
* Set the owner name of the codec.
*
* This "owner name" is the name of the `IOmx` instance that supports this
@@ -228,32 +286,32 @@
*/
void setOwner(const char* owner);
/**
- * Set whether this codec is an encoder or a decoder.
+ * Sets codec attributes.
*
- * @param isEncoder Whether this codec is an encoder or a decoder.
+ * @param attributes Codec attributes.
*/
- void setEncoder(bool isEncoder = true);
+ void setAttributes(typename std::underlying_type<MediaCodecInfo::Attributes>::type attributes);
/**
- * Add a mime to an indexed list and return a `CapabilitiesWriter` object
+ * Add a media type to an indexed list and return a `CapabilitiesWriter` object
* that can be used for modifying the associated `Capabilities`.
*
- * If the mime already exists, this function will return the
- * `CapabilitiesWriter` associated with the mime.
+ * If the media type already exists, this function will return the
+ * `CapabilitiesWriter` associated with the media type.
*
- * @param[in] mime The name of a new mime to add.
+ * @param[in] mediaType The name of a new media type to add.
* @return writer The `CapabilitiesWriter` object for modifying the
- * `Capabilities` associated with the mime. `writer` will be valid
- * regardless of whether `mime` already exists or not.
+ * `Capabilities` associated with the media type. `writer` will be valid
+ * regardless of whether `mediaType` already exists or not.
*/
- std::unique_ptr<MediaCodecInfo::CapabilitiesWriter> addMime(
- const char* mime);
+ std::unique_ptr<MediaCodecInfo::CapabilitiesWriter> addMediaType(
+ const char* mediaType);
/**
- * Remove a mime.
+ * Remove a media type.
*
- * @param mime The name of the mime to remove.
- * @return `true` if `mime` is removed; `false` if `mime` is not found.
+ * @param mediaType The name of the media type to remove.
+ * @return `true` if `mediaType` is removed; `false` if `mediaType` is not found.
*/
- bool removeMime(const char* mime);
+ bool removeMediaType(const char* mediaType);
/**
* Set rank of the codec. MediaCodecList will stable-sort the list according
* to rank in non-descending order.
diff --git a/media/libmediaextractor/Android.bp b/media/libmediaextractor/Android.bp
deleted file mode 100644
index 4758cd6..0000000
--- a/media/libmediaextractor/Android.bp
+++ /dev/null
@@ -1,60 +0,0 @@
-cc_library {
- name: "libmediaextractor",
-
- include_dirs: [
- "frameworks/av/include",
- "frameworks/av/media/libmediaextractor/include",
- ],
-
- export_include_dirs: ["include"],
-
- cflags: [
- "-Wno-multichar",
- "-Werror",
- "-Wall",
- ],
-
- static: {
- cflags: [
- "-Wno-multichar",
- "-Werror",
- "-Wall",
- "-DNO_IMEMORY",
- ],
- },
-
- shared_libs: [
- "libbinder",
- "libstagefright_foundation",
- "libutils",
- "liblog",
- ],
-
- header_libs: [
- "media_ndk_headers",
- ],
-
- export_header_lib_headers: [
- "media_ndk_headers",
- ],
-
- srcs: [
- "DataSourceBase.cpp",
- "MediaBuffer.cpp",
- "MediaBufferBase.cpp",
- "MediaBufferGroup.cpp",
- "MediaSource.cpp",
- "MetaData.cpp",
- "MetaDataBase.cpp",
- ],
-
- clang: true,
-
- sanitize: {
- misc_undefined: [
- "unsigned-integer-overflow",
- "signed-integer-overflow",
- ],
- cfi: true,
- },
-}
diff --git a/media/libmediaplayer2/Android.bp b/media/libmediaplayer2/Android.bp
index 38f42dc..b3f7404 100644
--- a/media/libmediaplayer2/Android.bp
+++ b/media/libmediaplayer2/Android.bp
@@ -21,7 +21,6 @@
"libgui",
"liblog",
"libmedia_omx",
- "libmediaextractor",
"libstagefright_foundation",
"libui",
"libutils",
diff --git a/media/libmediaplayer2/JavaVMHelper.cpp b/media/libmediaplayer2/JavaVMHelper.cpp
index 90aaa7f..8d03ed0 100644
--- a/media/libmediaplayer2/JavaVMHelper.cpp
+++ b/media/libmediaplayer2/JavaVMHelper.cpp
@@ -19,6 +19,7 @@
#include "mediaplayer2/JavaVMHelper.h"
#include <media/stagefright/foundation/ADebug.h>
+#include <utils/threads.h>
#include <stdlib.h>
@@ -27,6 +28,109 @@
// static
std::atomic<JavaVM *> JavaVMHelper::sJavaVM(NULL);
+/*
+ * Makes the current thread visible to the VM.
+ *
+ * The JNIEnv pointer returned is only valid for the current thread, and
+ * thus must be tucked into thread-local storage.
+ */
+static int javaAttachThread(const char* threadName, JNIEnv** pEnv) {
+ JavaVMAttachArgs args;
+ JavaVM* vm;
+ jint result;
+
+ vm = JavaVMHelper::getJavaVM();
+ if (vm == NULL) {
+ return JNI_ERR;
+ }
+
+ args.version = JNI_VERSION_1_4;
+ args.name = (char*) threadName;
+ args.group = NULL;
+
+ result = vm->AttachCurrentThread(pEnv, (void*) &args);
+ if (result != JNI_OK) {
+ ALOGI("NOTE: attach of thread '%s' failed\n", threadName);
+ }
+
+ return result;
+}
+
+/*
+ * Detach the current thread from the set visible to the VM.
+ */
+static int javaDetachThread(void) {
+ JavaVM* vm;
+ jint result;
+
+ vm = JavaVMHelper::getJavaVM();
+ if (vm == NULL) {
+ return JNI_ERR;
+ }
+
+ result = vm->DetachCurrentThread();
+ if (result != JNI_OK) {
+ ALOGE("ERROR: thread detach failed\n");
+ }
+ return result;
+}
+
+/*
+ * When starting a native thread that will be visible from the VM, we
+ * bounce through this to get the right attach/detach action.
+ * Note that this function calls free(args)
+ */
+static int javaThreadShell(void* args) {
+ void* start = ((void**)args)[0];
+ void* userData = ((void **)args)[1];
+ char* name = (char*) ((void **)args)[2]; // we own this storage
+ free(args);
+ JNIEnv* env;
+ int result;
+
+ /* hook us into the VM */
+ if (javaAttachThread(name, &env) != JNI_OK) {
+ return -1;
+ }
+
+ /* start the thread running */
+ result = (*(android_thread_func_t)start)(userData);
+
+ /* unhook us */
+ javaDetachThread();
+ free(name);
+
+ return result;
+}
+
+/*
+ * This is invoked from androidCreateThreadEtc() via the callback
+ * set with androidSetCreateThreadFunc().
+ *
+ * We need to create the new thread in such a way that it gets hooked
+ * into the VM before it really starts executing.
+ */
+static int javaCreateThreadEtc(
+ android_thread_func_t entryFunction,
+ void* userData,
+ const char* threadName,
+ int32_t threadPriority,
+ size_t threadStackSize,
+ android_thread_id_t* threadId) {
+ void** args = (void**) malloc(3 * sizeof(void*)); // javaThreadShell must free
+ int result;
+
+ LOG_ALWAYS_FATAL_IF(threadName == nullptr, "threadName not provided to javaCreateThreadEtc");
+
+ args[0] = (void*) entryFunction;
+ args[1] = userData;
+ args[2] = (void*) strdup(threadName); // javaThreadShell must free
+
+ result = androidCreateRawThreadEtc(javaThreadShell, args,
+ threadName, threadPriority, threadStackSize, threadId);
+ return result;
+}
+
// static
JNIEnv *JavaVMHelper::getJNIEnv() {
JNIEnv *env;
@@ -40,9 +144,19 @@
return env;
}
+//static
+JavaVM *JavaVMHelper::getJavaVM() {
+ return sJavaVM.load();
+}
+
// static
void JavaVMHelper::setJavaVM(JavaVM *vm) {
sJavaVM.store(vm);
+
+ // Ensure that Thread(/*canCallJava*/ true) in libutils is attached to the VM.
+ // This is supposed to be done by runtime, but when libutils is used with linker
+ // namespace, CreateThreadFunc should be initialized separately within the namespace.
+ androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);
}
} // namespace android
diff --git a/media/libmediaplayer2/include/mediaplayer2/JavaVMHelper.h b/media/libmediaplayer2/include/mediaplayer2/JavaVMHelper.h
index 35091b7..4b56aca 100644
--- a/media/libmediaplayer2/include/mediaplayer2/JavaVMHelper.h
+++ b/media/libmediaplayer2/include/mediaplayer2/JavaVMHelper.h
@@ -26,6 +26,7 @@
struct JavaVMHelper {
static JNIEnv *getJNIEnv();
+ static JavaVM *getJavaVM();
static void setJavaVM(JavaVM *vm);
private:
diff --git a/media/libmediaplayerservice/Android.bp b/media/libmediaplayerservice/Android.bp
index 51879fd..55867a5 100644
--- a/media/libmediaplayerservice/Android.bp
+++ b/media/libmediaplayerservice/Android.bp
@@ -24,7 +24,6 @@
"liblog",
"libmedia",
"libmedia_omx",
- "libmediaextractor",
"libmediadrm",
"libmediametrics",
"libmediautils",
diff --git a/media/libnblog/Reader.cpp b/media/libnblog/Reader.cpp
index fd53090..f556e37 100644
--- a/media/libnblog/Reader.cpp
+++ b/media/libnblog/Reader.cpp
@@ -284,6 +284,15 @@
EntryIterator DumpReader::handleFormat(const FormatEntry &fmtEntry,
String8 *timestamp, String8 *body)
{
+ String8 timestampLocal;
+ String8 bodyLocal;
+ if (timestamp == nullptr) {
+ timestamp = ×tampLocal;
+ }
+ if (body == nullptr) {
+ body = &bodyLocal;
+ }
+
// log timestamp
const int64_t ts = fmtEntry.timestamp();
timestamp->clear();
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 2ea5286..a1a2660 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -566,8 +566,8 @@
mDequeueCounter(0),
mMetadataBuffersToSubmit(0),
mNumUndequeuedBuffers(0),
- mRepeatFrameDelayUs(-1ll),
- mMaxPtsGapUs(0ll),
+ mRepeatFrameDelayUs(-1LL),
+ mMaxPtsGapUs(0LL),
mMaxFps(-1),
mFps(-1.0),
mCaptureFps(-1.0),
@@ -1822,15 +1822,15 @@
if (!msg->findInt64(
"repeat-previous-frame-after",
&mRepeatFrameDelayUs)) {
- mRepeatFrameDelayUs = -1ll;
+ mRepeatFrameDelayUs = -1LL;
}
// only allow 32-bit value, since we pass it as U32 to OMX.
if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
- mMaxPtsGapUs = 0ll;
+ mMaxPtsGapUs = 0LL;
} else if (mMaxPtsGapUs > INT32_MAX || mMaxPtsGapUs < INT32_MIN) {
ALOGW("Unsupported value for max pts gap %lld", (long long) mMaxPtsGapUs);
- mMaxPtsGapUs = 0ll;
+ mMaxPtsGapUs = 0LL;
}
if (!msg->findFloat("max-fps-to-encoder", &mMaxFps)) {
@@ -1838,7 +1838,7 @@
}
// notify GraphicBufferSource to allow backward frames
- if (mMaxPtsGapUs < 0ll) {
+ if (mMaxPtsGapUs < 0LL) {
mMaxFps = -1;
}
@@ -6707,7 +6707,7 @@
mCodec->mDequeueCounter = 0;
mCodec->mMetadataBuffersToSubmit = 0;
- mCodec->mRepeatFrameDelayUs = -1ll;
+ mCodec->mRepeatFrameDelayUs = -1LL;
mCodec->mInputFormat.clear();
mCodec->mOutputFormat.clear();
mCodec->mBaseOutputFormat.clear();
@@ -6849,7 +6849,7 @@
return err;
}
- if (mCodec->mRepeatFrameDelayUs > 0ll) {
+ if (mCodec->mRepeatFrameDelayUs > 0LL) {
err = statusFromBinderStatus(
mCodec->mGraphicBufferSource->setRepeatPreviousFrameDelayUs(
mCodec->mRepeatFrameDelayUs));
@@ -6862,7 +6862,7 @@
}
}
- if (mCodec->mMaxPtsGapUs != 0ll) {
+ if (mCodec->mMaxPtsGapUs != 0LL) {
OMX_PARAM_U32TYPE maxPtsGapParams;
InitOMXParams(&maxPtsGapParams);
maxPtsGapParams.nPortIndex = kPortIndexInput;
@@ -8682,14 +8682,17 @@
if (omxNode->configureVideoTunnelMode(
kPortIndexOutput, OMX_TRUE, 0, &sidebandHandle) == OK) {
// tunneled playback includes adaptive playback
- caps->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback
- | MediaCodecInfo::Capabilities::kFlagSupportsTunneledPlayback);
- } else if (omxNode->setPortMode(
- kPortIndexOutput, IOMX::kPortModeDynamicANWBuffer) == OK ||
- omxNode->prepareForAdaptivePlayback(
- kPortIndexOutput, OMX_TRUE,
- 1280 /* width */, 720 /* height */) == OK) {
- caps->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback);
+ } else {
+ // tunneled playback is not supported
+ caps->removeDetail(MediaCodecInfo::Capabilities::FEATURE_TUNNELED_PLAYBACK);
+ if (omxNode->setPortMode(
+ kPortIndexOutput, IOMX::kPortModeDynamicANWBuffer) != OK &&
+ omxNode->prepareForAdaptivePlayback(
+ kPortIndexOutput, OMX_TRUE,
+ 1280 /* width */, 720 /* height */) != OK) {
+ // adaptive playback is not supported
+ caps->removeDetail(MediaCodecInfo::Capabilities::FEATURE_ADAPTIVE_PLAYBACK);
+ }
}
}
@@ -8697,11 +8700,20 @@
OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
InitOMXParams(¶ms);
params.nPortIndex = kPortIndexOutput;
- // TODO: should we verify if fallback is supported?
+
+ OMX_VIDEO_PARAM_INTRAREFRESHTYPE fallbackParams;
+ InitOMXParams(&fallbackParams);
+ fallbackParams.nPortIndex = kPortIndexOutput;
+ fallbackParams.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic;
+
if (omxNode->getConfig(
(OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh,
- ¶ms, sizeof(params)) == OK) {
- caps->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsIntraRefresh);
+ ¶ms, sizeof(params)) != OK &&
+ omxNode->getParameter(
+ OMX_IndexParamVideoIntraRefresh, &fallbackParams,
+ sizeof(fallbackParams)) != OK) {
+ // intra refresh is not supported
+ caps->removeDetail(MediaCodecInfo::Capabilities::FEATURE_INTRA_REFRESH);
}
}
diff --git a/media/libstagefright/Android.bp b/media/libstagefright/Android.bp
index 249f2a4..f45cc58 100644
--- a/media/libstagefright/Android.bp
+++ b/media/libstagefright/Android.bp
@@ -94,6 +94,7 @@
"CameraSource.cpp",
"CameraSourceTimeLapse.cpp",
"DataConverter.cpp",
+ "DataSourceBase.cpp",
"DataSourceFactory.cpp",
"DataURISource.cpp",
"ClearFileSource.cpp",
@@ -113,6 +114,7 @@
"MediaCodecSource.cpp",
"MediaExtractor.cpp",
"MediaExtractorFactory.cpp",
+ "MediaSource.cpp",
"MediaSync.cpp",
"MediaTrack.cpp",
"http/ClearMediaHTTP.cpp",
@@ -150,7 +152,6 @@
"libmedia",
"libmedia_omx",
"libaudioclient",
- "libmediaextractor",
"libmediametrics",
"libmediautils",
"libui",
diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp
index 9de1e22..5027303 100644
--- a/media/libstagefright/AudioSource.cpp
+++ b/media/libstagefright/AudioSource.cpp
@@ -337,7 +337,7 @@
} else {
// This should not happen in normal case.
ALOGW("Failed to get audio timestamp, fallback to use systemclock");
- timeUs = systemTime() / 1000ll;
+ timeUs = systemTime() / 1000LL;
// Estimate the real sampling time of the 1st sample in this buffer
// from AudioRecord's latency. (Apply this adjustment first so that
// the start time logic is not affected.)
diff --git a/media/libmediaextractor/DataSourceBase.cpp b/media/libstagefright/DataSourceBase.cpp
similarity index 100%
rename from media/libmediaextractor/DataSourceBase.cpp
rename to media/libstagefright/DataSourceBase.cpp
diff --git a/media/libstagefright/FrameDecoder.cpp b/media/libstagefright/FrameDecoder.cpp
index c62c05a..42b98b1 100644
--- a/media/libstagefright/FrameDecoder.cpp
+++ b/media/libstagefright/FrameDecoder.cpp
@@ -39,7 +39,7 @@
namespace android {
-static const int64_t kBufferTimeOutUs = 10000ll; // 10 msec
+static const int64_t kBufferTimeOutUs = 10000LL; // 10 msec
static const size_t kRetryCount = 50; // must be >0
sp<IMemory> allocVideoFrame(const sp<MetaData>& trackMeta,
@@ -274,7 +274,7 @@
size_t retriesLeft = kRetryCount;
do {
size_t index;
- int64_t ptsUs = 0ll;
+ int64_t ptsUs = 0LL;
uint32_t flags = 0;
// Queue as many inputs as we possibly can, then block on dequeuing
@@ -406,7 +406,7 @@
: FrameDecoder(componentName, trackMeta, source),
mIsAvcOrHevc(false),
mSeekMode(MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC),
- mTargetTimeUs(-1ll),
+ mTargetTimeUs(-1LL),
mNumFrames(0),
mNumFramesDecoded(0) {
}
@@ -487,7 +487,7 @@
const sp<MediaCodecBuffer> &videoFrameBuffer,
const sp<AMessage> &outputFormat,
int64_t timeUs, bool *done) {
- bool shouldOutput = (mTargetTimeUs < 0ll) || (timeUs >= mTargetTimeUs);
+ bool shouldOutput = (mTargetTimeUs < 0LL) || (timeUs >= mTargetTimeUs);
// If this is not the target frame, skip color convert.
if (!shouldOutput) {
diff --git a/media/libstagefright/MPEG2TSWriter.cpp b/media/libstagefright/MPEG2TSWriter.cpp
index 770535c..a9715c9 100644
--- a/media/libstagefright/MPEG2TSWriter.cpp
+++ b/media/libstagefright/MPEG2TSWriter.cpp
@@ -240,7 +240,7 @@
size -= length;
}
- out->meta()->setInt64("timeUs", 0ll);
+ out->meta()->setInt64("timeUs", 0LL);
sp<AMessage> notify = mNotify->dup();
notify->setInt32("what", kNotifyBuffer);
@@ -842,7 +842,7 @@
int64_t timeUs;
CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs));
- uint32_t PTS = (timeUs * 9ll) / 100ll;
+ uint32_t PTS = (timeUs * 9LL) / 100LL;
size_t PES_packet_length = accessUnit->size() + 8;
bool padding = (accessUnit->size() < (188 - 18));
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index b45eb03..7df1a2d 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -487,7 +487,7 @@
mInterleaveDurationUs = 1000000;
- mStartTimestampUs = -1ll;
+ mStartTimestampUs = -1LL;
mStartTimeOffsetMs = -1;
mStartTimeOffsetBFramesUs = 0;
mPaused = false;
@@ -1745,7 +1745,7 @@
void MPEG4Writer::setStartTimestampUs(int64_t timeUs) {
ALOGI("setStartTimestampUs: %" PRId64, timeUs);
- CHECK_GE(timeUs, 0ll);
+ CHECK_GE(timeUs, 0LL);
Mutex::Autolock autoLock(mLock);
if (mStartTimestampUs < 0 || mStartTimestampUs > timeUs) {
mStartTimestampUs = timeUs;
@@ -3099,7 +3099,7 @@
if (mResumed) {
int64_t durExcludingEarlierPausesUs = timestampUs - previousPausedDurationUs;
- if (WARN_UNLESS(durExcludingEarlierPausesUs >= 0ll, "for %s track", trackName)) {
+ if (WARN_UNLESS(durExcludingEarlierPausesUs >= 0LL, "for %s track", trackName)) {
copy->release();
mSource->stop();
mIsMalformed = true;
@@ -3120,7 +3120,7 @@
TimestampDebugHelperEntry timestampDebugEntry;
timestampUs -= previousPausedDurationUs;
timestampDebugEntry.pts = timestampUs;
- if (WARN_UNLESS(timestampUs >= 0ll, "for %s track", trackName)) {
+ if (WARN_UNLESS(timestampUs >= 0LL, "for %s track", trackName)) {
copy->release();
mSource->stop();
mIsMalformed = true;
@@ -3159,7 +3159,7 @@
cttsOffsetTimeUs =
timestampUs + kMaxCttsOffsetTimeUs - decodingTimeUs;
- if (WARN_UNLESS(cttsOffsetTimeUs >= 0ll, "for %s track", trackName)) {
+ if (WARN_UNLESS(cttsOffsetTimeUs >= 0LL, "for %s track", trackName)) {
copy->release();
mSource->stop();
mIsMalformed = true;
@@ -3217,7 +3217,7 @@
}
}
- if (WARN_UNLESS(timestampUs >= 0ll, "for %s track", trackName)) {
+ if (WARN_UNLESS(timestampUs >= 0LL, "for %s track", trackName)) {
copy->release();
mSource->stop();
mIsMalformed = true;
@@ -3238,7 +3238,7 @@
currDurationTicks =
((timestampUs * mTimeScale + 500000LL) / 1000000LL -
(lastTimestampUs * mTimeScale + 500000LL) / 1000000LL);
- if (currDurationTicks < 0ll) {
+ if (currDurationTicks < 0LL) {
ALOGE("do not support out of order frames (timestamp: %lld < last: %lld for %s track",
(long long)timestampUs, (long long)lastTimestampUs, trackName);
copy->release();
diff --git a/media/libstagefright/MediaClock.cpp b/media/libstagefright/MediaClock.cpp
index 41dbfd4..4f9bc6d 100644
--- a/media/libstagefright/MediaClock.cpp
+++ b/media/libstagefright/MediaClock.cpp
@@ -28,7 +28,7 @@
// Maximum allowed time backwards from anchor change.
// If larger than this threshold, it's treated as discontinuity.
-static const int64_t kAnchorFluctuationAllowedUs = 10000ll;
+static const int64_t kAnchorFluctuationAllowedUs = 10000LL;
MediaClock::Timer::Timer(const sp<AMessage> ¬ify, int64_t mediaTimeUs, int64_t adjustRealUs)
: mNotify(notify),
@@ -110,7 +110,7 @@
if (mAnchorTimeRealUs != -1) {
int64_t oldNowMediaUs =
mAnchorTimeMediaUs + (nowUs - mAnchorTimeRealUs) * (double)mPlaybackRate;
- if (nowMediaUs < oldNowMediaUs
+ if (nowMediaUs < oldNowMediaUs + kAnchorFluctuationAllowedUs
&& nowMediaUs > oldNowMediaUs - kAnchorFluctuationAllowedUs) {
return;
}
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index bd9e2bb..2547888 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -911,10 +911,10 @@
continue;
}
mCodecInfo = mcl->getCodecInfo(codecIdx);
- Vector<AString> mimes;
- mCodecInfo->getSupportedMimes(&mimes);
- for (size_t i = 0; i < mimes.size(); i++) {
- if (mimes[i].startsWith("video/")) {
+ Vector<AString> mediaTypes;
+ mCodecInfo->getSupportedMediaTypes(&mediaTypes);
+ for (size_t i = 0; i < mediaTypes.size(); i++) {
+ if (mediaTypes[i].startsWith("video/")) {
mIsVideo = true;
break;
}
@@ -2699,7 +2699,7 @@
int64_t timeoutUs;
CHECK(msg->findInt64("timeoutUs", &timeoutUs));
- if (timeoutUs == 0ll) {
+ if (timeoutUs == 0LL) {
PostReplyWithError(replyID, -EAGAIN);
break;
}
@@ -2707,7 +2707,7 @@
mFlags |= kFlagDequeueInputPending;
mDequeueInputReplyID = replyID;
- if (timeoutUs > 0ll) {
+ if (timeoutUs > 0LL) {
sp<AMessage> timeoutMsg =
new AMessage(kWhatDequeueInputTimedOut, this);
timeoutMsg->setInt32(
@@ -2773,7 +2773,7 @@
int64_t timeoutUs;
CHECK(msg->findInt64("timeoutUs", &timeoutUs));
- if (timeoutUs == 0ll) {
+ if (timeoutUs == 0LL) {
PostReplyWithError(replyID, -EAGAIN);
break;
}
@@ -2781,7 +2781,7 @@
mFlags |= kFlagDequeueOutputPending;
mDequeueOutputReplyID = replyID;
- if (timeoutUs > 0ll) {
+ if (timeoutUs > 0LL) {
sp<AMessage> timeoutMsg =
new AMessage(kWhatDequeueOutputTimedOut, this);
timeoutMsg->setInt32(
@@ -3042,7 +3042,7 @@
msg->setSize("index", bufferIndex);
msg->setSize("offset", 0);
msg->setSize("size", csd->size());
- msg->setInt64("timeUs", 0ll);
+ msg->setInt64("timeUs", 0LL);
msg->setInt32("flags", BUFFER_FLAG_CODECCONFIG);
msg->setPointer("errorDetailMsg", &errorDetailMsg);
diff --git a/media/libstagefright/MediaCodecList.cpp b/media/libstagefright/MediaCodecList.cpp
index eaff283..93478e9 100644
--- a/media/libstagefright/MediaCodecList.cpp
+++ b/media/libstagefright/MediaCodecList.cpp
@@ -215,13 +215,9 @@
mCodecInfos.begin(),
mCodecInfos.end(),
[](const sp<MediaCodecInfo> &info1, const sp<MediaCodecInfo> &info2) {
- if (info2 == nullptr) {
- return false;
- } else if (info1 == nullptr) {
- return true;
- } else {
- return info1->rank() < info2->rank();
- }
+ // null is lowest
+ return info1 == nullptr
+ || (info2 != nullptr && info1->getRank() < info2->getRank());
});
}
diff --git a/media/libstagefright/MediaCodecListOverrides.cpp b/media/libstagefright/MediaCodecListOverrides.cpp
index cac53f4..dd7c3e6 100644
--- a/media/libstagefright/MediaCodecListOverrides.cpp
+++ b/media/libstagefright/MediaCodecListOverrides.cpp
@@ -228,18 +228,18 @@
continue;
}
- Vector<AString> mimes;
- info->getSupportedMimes(&mimes);
- for (size_t i = 0; i < mimes.size(); ++i) {
+ Vector<AString> mediaTypes;
+ info->getSupportedMediaTypes(&mediaTypes);
+ for (size_t i = 0; i < mediaTypes.size(); ++i) {
const sp<MediaCodecInfo::Capabilities> &caps =
- info->getCapabilitiesFor(mimes[i].c_str());
+ info->getCapabilitiesFor(mediaTypes[i].c_str());
if (!forceToMeasure &&
(caps->getDetails()->contains("max-supported-instances") ||
caps->getDetails()->contains("max-concurrent-instances"))) {
continue;
}
- size_t max = doProfileCodecs(info->isEncoder(), name, mimes[i], caps);
+ size_t max = doProfileCodecs(info->isEncoder(), name, mediaTypes[i], caps);
if (max > 0) {
CodecSettings settings;
char maxStr[32];
@@ -248,7 +248,7 @@
AString key = name;
key.append(" ");
- key.append(mimes[i]);
+ key.append(mediaTypes[i]);
if (info->isEncoder()) {
encoder_results->add(key, settings);
diff --git a/media/libstagefright/MediaCodecSource.cpp b/media/libstagefright/MediaCodecSource.cpp
index 20881a4..0f75822 100644
--- a/media/libstagefright/MediaCodecSource.cpp
+++ b/media/libstagefright/MediaCodecSource.cpp
@@ -372,7 +372,7 @@
msg->postAndAwaitResponse(&response);
int64_t timeUs;
if (!response->findInt64("time-us", &timeUs)) {
- timeUs = -1ll;
+ timeUs = -1LL;
}
return timeUs;
}
@@ -452,9 +452,9 @@
mEncoderDataSpace(0),
mPersistentSurface(persistentSurface),
mInputBufferTimeOffsetUs(0),
- mFirstSampleSystemTimeUs(-1ll),
+ mFirstSampleSystemTimeUs(-1LL),
mPausePending(false),
- mFirstSampleTimeUs(-1ll),
+ mFirstSampleTimeUs(-1LL),
mGeneration(0) {
CHECK(mLooper != NULL);
@@ -687,13 +687,13 @@
size_t bufferIndex = *mAvailEncoderInputIndices.begin();
mAvailEncoderInputIndices.erase(mAvailEncoderInputIndices.begin());
- int64_t timeUs = 0ll;
+ int64_t timeUs = 0LL;
uint32_t flags = 0;
size_t size = 0;
if (mbuf != NULL) {
CHECK(mbuf->meta_data().findInt64(kKeyTime, &timeUs));
- if (mFirstSampleSystemTimeUs < 0ll) {
+ if (mFirstSampleSystemTimeUs < 0LL) {
mFirstSampleSystemTimeUs = systemTime() / 1000;
if (mPausePending) {
mPausePending = false;
@@ -767,7 +767,7 @@
}
int64_t startTimeUs;
if (params == NULL || !params->findInt64(kKeyTime, &startTimeUs)) {
- startTimeUs = -1ll;
+ startTimeUs = -1LL;
}
if (mStarted) {
@@ -914,7 +914,7 @@
if (mIsVideo) {
int64_t decodingTimeUs;
if (mFlags & FLAG_USE_SURFACE_INPUT) {
- if (mFirstSampleSystemTimeUs < 0ll) {
+ if (mFirstSampleSystemTimeUs < 0LL) {
mFirstSampleSystemTimeUs = systemTime() / 1000;
if (mPausePending) {
mPausePending = false;
@@ -926,7 +926,7 @@
// Timestamp offset is already adjusted in GraphicBufferSource.
// GraphicBufferSource is supposed to discard samples
// queued before start, and offset timeUs by start time
- CHECK_GE(timeUs, 0ll);
+ CHECK_GE(timeUs, 0LL);
// TODO:
// Decoding time for surface source is unavailable,
// use presentation time for now. May need to move
@@ -954,7 +954,7 @@
}
mbuf->meta_data().setInt64(kKeyTime, timeUs);
} else {
- mbuf->meta_data().setInt64(kKeyTime, 0ll);
+ mbuf->meta_data().setInt64(kKeyTime, 0LL);
mbuf->meta_data().setInt32(kKeyIsCodecConfig, true);
}
if (flags & MediaCodec::BUFFER_FLAG_SYNCFRAME) {
@@ -1081,7 +1081,7 @@
MetaData *params = static_cast<MetaData *>(obj.get());
int64_t pauseStartTimeUs = -1;
if (params == NULL || !params->findInt64(kKeyTime, &pauseStartTimeUs)) {
- pauseStartTimeUs = -1ll;
+ pauseStartTimeUs = -1LL;
}
onPause(pauseStartTimeUs);
}
diff --git a/media/libmediaextractor/MediaSource.cpp b/media/libstagefright/MediaSource.cpp
similarity index 100%
rename from media/libmediaextractor/MediaSource.cpp
rename to media/libstagefright/MediaSource.cpp
diff --git a/media/libstagefright/MediaSync.cpp b/media/libstagefright/MediaSync.cpp
index ba14e5d..a3f55da 100644
--- a/media/libstagefright/MediaSync.cpp
+++ b/media/libstagefright/MediaSync.cpp
@@ -36,7 +36,7 @@
// Maximum late time allowed for a video frame to be rendered. When a video
// frame arrives later than this number, it will be discarded without rendering.
-static const int64_t kMaxAllowedVideoLateTimeUs = 40000ll;
+static const int64_t kMaxAllowedVideoLateTimeUs = 40000LL;
namespace android {
diff --git a/media/libstagefright/MediaTrack.cpp b/media/libstagefright/MediaTrack.cpp
index f158491..036e79d 100644
--- a/media/libstagefright/MediaTrack.cpp
+++ b/media/libstagefright/MediaTrack.cpp
@@ -172,6 +172,10 @@
meta.setData(kKeySEI,
MetaDataBase::Type::TYPE_NONE, valbuf->data(), valbuf->size());
}
+ if (format->mFormat->findBuffer("audio-presentation-info", &valbuf)) {
+ meta.setData(kKeyAudioPresentationInfo,
+ MetaDataBase::Type::TYPE_NONE, valbuf->data(), valbuf->size());
+ }
} else {
*buffer = nullptr;
}
diff --git a/media/libstagefright/NuCachedSource2.cpp b/media/libstagefright/NuCachedSource2.cpp
index 7025af7..522c81d 100644
--- a/media/libstagefright/NuCachedSource2.cpp
+++ b/media/libstagefright/NuCachedSource2.cpp
@@ -440,12 +440,12 @@
if (mFetching) {
if (mFinalStatus != OK && mNumRetriesLeft > 0) {
// We failed this time and will try again in 3 seconds.
- delayUs = 3000000ll;
+ delayUs = 3000000LL;
} else {
delayUs = 0;
}
} else {
- delayUs = 100000ll;
+ delayUs = 100000LL;
}
(new AMessage(kWhatFetchMore, mReflector))->post(delayUs);
@@ -740,7 +740,7 @@
}
if (keepAliveSecs >= 0) {
- mKeepAliveIntervalUs = keepAliveSecs * 1000000ll;
+ mKeepAliveIntervalUs = keepAliveSecs * 1000000LL;
} else {
mKeepAliveIntervalUs = kDefaultKeepAliveIntervalUs;
}
diff --git a/media/libstagefright/NuMediaExtractor.cpp b/media/libstagefright/NuMediaExtractor.cpp
index f5178dd..83b87d9 100644
--- a/media/libstagefright/NuMediaExtractor.cpp
+++ b/media/libstagefright/NuMediaExtractor.cpp
@@ -41,7 +41,7 @@
NuMediaExtractor::Sample::Sample()
: mBuffer(NULL),
- mSampleTimeUs(-1ll) {
+ mSampleTimeUs(-1LL) {
}
NuMediaExtractor::Sample::Sample(MediaBufferBase *buffer, int64_t timeUs)
@@ -50,8 +50,8 @@
}
NuMediaExtractor::NuMediaExtractor()
- : mTotalBitrate(-1ll),
- mDurationUs(-1ll) {
+ : mTotalBitrate(-1LL),
+ mDurationUs(-1LL) {
}
NuMediaExtractor::~NuMediaExtractor() {
@@ -209,8 +209,8 @@
return ERROR_UNSUPPORTED;
}
- mTotalBitrate = 0ll;
- mDurationUs = -1ll;
+ mTotalBitrate = 0LL;
+ mDurationUs = -1LL;
for (size_t i = 0; i < mImpl->countTracks(); ++i) {
sp<MetaData> meta = mImpl->getTrackMetaData(i);
@@ -225,8 +225,8 @@
CHECK(meta->findCString(kKeyMIMEType, &mime));
ALOGV("track of type '%s' does not publish bitrate", mime);
- mTotalBitrate = -1ll;
- } else if (mTotalBitrate >= 0ll) {
+ mTotalBitrate = -1LL;
+ } else if (mTotalBitrate >= 0LL) {
mTotalBitrate += bitrate;
}
@@ -503,7 +503,7 @@
}
MediaSource::ReadOptions options;
- if (seekTimeUs >= 0ll) {
+ if (seekTimeUs >= 0LL) {
options.setSeekTo(seekTimeUs, mode);
info->mFinalResult = OK;
releaseTrackSamples(info);
@@ -768,7 +768,7 @@
off64_t size;
if (mDurationUs > 0 && mDataSource->getSize(&size) == OK) {
- *bitrate = size * 8000000ll / mDurationUs; // in bits/sec
+ *bitrate = size * 8000000LL / mDurationUs; // in bits/sec
return true;
}
@@ -795,30 +795,34 @@
}
// Return OK if we have received an audio presentation info.
+// Return ERROR_END_OF_STREAM if no tracks are available.
// Return ERROR_UNSUPPORTED if the track has no audio presentation.
// Return INVALID_OPERATION if audio presentation metadata version does not match.
status_t NuMediaExtractor::getAudioPresentations(
- size_t trackIndex, AudioPresentationCollection *presentations) const {
+ size_t trackIndex, AudioPresentationCollection *presentations) {
Mutex::Autolock autoLock(mLock);
-
- if (mImpl == NULL) {
- return -EINVAL;
+ ssize_t minIndex = fetchAllTrackSamples();
+ if (minIndex < 0) {
+ return ERROR_END_OF_STREAM;
}
+ for (size_t i = 0; i < mSelectedTracks.size(); ++i) {
+ TrackInfo *info = &mSelectedTracks.editItemAt(i);
- if (trackIndex >= mImpl->countTracks()) {
- return -ERANGE;
+ if (info->mTrackIndex == trackIndex) {
+ sp<MetaData> meta = new MetaData(info->mSamples.begin()->mBuffer->meta_data());
+
+ uint32_t type;
+ const void *data;
+ size_t size;
+ if (meta != NULL && meta->findData(kKeyAudioPresentationInfo, &type, &data, &size)) {
+ std::istringstream inStream(std::string(static_cast<const char*>(data), size));
+ return deserializeAudioPresentations(&inStream, presentations);
+ }
+ ALOGV("Track %zu does not contain any audio presentation", trackIndex);
+ return ERROR_UNSUPPORTED;
+ }
}
-
- sp<MetaData> meta = mImpl->getTrackMetaData(trackIndex);
-
- uint32_t type;
- const void *data;
- size_t size;
- if (meta != NULL && meta->findData(kKeyAudioPresentationInfo, &type, &data, &size)) {
- std::istringstream inStream(std::string(static_cast<const char*>(data), size));
- return deserializeAudioPresentations(&inStream, presentations);
- }
- ALOGE("Source does not contain any audio presentation");
+ ALOGV("Source does not contain any audio presentation");
return ERROR_UNSUPPORTED;
}
diff --git a/media/libstagefright/OmxInfoBuilder.cpp b/media/libstagefright/OmxInfoBuilder.cpp
index 96b896b..382c947 100644
--- a/media/libstagefright/OmxInfoBuilder.cpp
+++ b/media/libstagefright/OmxInfoBuilder.cpp
@@ -57,14 +57,9 @@
}
status_t queryCapabilities(
- const IOmxStore::NodeInfo& node, const char* mime, bool isEncoder,
+ const IOmxStore::NodeInfo& node, const char* mediaType, bool isEncoder,
MediaCodecInfo::CapabilitiesWriter* caps) {
sp<ACodec> codec = new ACodec();
- status_t err = codec->queryCapabilities(
- node.owner.c_str(), node.name.c_str(), mime, isEncoder, caps);
- if (err != OK) {
- return err;
- }
for (const auto& attribute : node.attributes) {
// All features have an int32 value except
// "feature-bitrate-modes", which has a string value.
@@ -81,6 +76,12 @@
attribute.key.c_str(), attribute.value.c_str());
}
}
+ // query capabilities may remove capabilities that are not actually supported by the codec
+ status_t err = codec->queryCapabilities(
+ node.owner.c_str(), node.name.c_str(), mediaType, isEncoder, caps);
+ if (err != OK) {
+ return err;
+ }
return OK;
}
@@ -163,7 +164,10 @@
info = c2i->second.get();
info->setName(nodeName.c_str());
info->setOwner(node.owner.c_str());
- info->setEncoder(isEncoder);
+ info->setAttributes(
+ // all OMX codecs are vendor codecs (in the vendor partition), but
+ // treat OMX.google codecs as non-hardware-accelerated and non-vendor
+ (isEncoder ? MediaCodecInfo::kFlagIsEncoder : 0));
info->setRank(defaultRank);
} else {
// The node has been seen before. Simply retrieve the
@@ -180,7 +184,19 @@
info = c2i->second.get();
info->setName(nodeName.c_str());
info->setOwner(node.owner.c_str());
- info->setEncoder(isEncoder);
+ typename std::underlying_type<MediaCodecInfo::Attributes>::type attrs =
+ MediaCodecInfo::kFlagIsVendor;
+ if (isEncoder) {
+ attrs |= MediaCodecInfo::kFlagIsEncoder;
+ }
+ if (std::count_if(
+ node.attributes.begin(), node.attributes.end(),
+ [](const IOmxStore::Attribute &i) -> bool {
+ return i.key == "attribute::software-codec";
+ })) {
+ attrs |= MediaCodecInfo::kFlagIsHardwareAccelerated;
+ }
+ info->setAttributes(attrs);
info->setRank(defaultRank);
} else {
// If preferPlatformNodes is true, this node must be
@@ -195,12 +211,12 @@
}
}
std::unique_ptr<MediaCodecInfo::CapabilitiesWriter> caps =
- info->addMime(typeName.c_str());
+ info->addMediaType(typeName.c_str());
if (queryCapabilities(
node, typeName.c_str(), isEncoder, caps.get()) != OK) {
- ALOGW("Fail to add mime %s to codec %s",
+ ALOGW("Fail to add media type %s to codec %s",
typeName.c_str(), nodeName.c_str());
- info->removeMime(typeName.c_str());
+ info->removeMediaType(typeName.c_str());
}
}
@@ -219,7 +235,18 @@
info = c2i->second.get();
info->setName(nodeName.c_str());
info->setOwner(node->owner.c_str());
- info->setEncoder(isEncoder);
+ typename std::underlying_type<MediaCodecInfo::Attributes>::type attrs =
+ MediaCodecInfo::kFlagIsVendor;
+ if (isEncoder) {
+ attrs |= MediaCodecInfo::kFlagIsEncoder;
+ }
+ if (std::count_if(
+ node->attributes.begin(), node->attributes.end(),
+ [](const IOmxStore::Attribute &i) -> bool {
+ return i.key == "attribute::software-codec";
+ })) {
+ attrs |= MediaCodecInfo::kFlagIsHardwareAccelerated;
+ }
info->setRank(defaultRank);
} else {
// The node has been seen before. Simply retrieve the
@@ -227,13 +254,13 @@
info = c2i->second.get();
}
std::unique_ptr<MediaCodecInfo::CapabilitiesWriter> caps =
- info->addMime(typeName.c_str());
+ info->addMediaType(typeName.c_str());
if (queryCapabilities(
*node, typeName.c_str(), isEncoder, caps.get()) != OK) {
- ALOGW("Fail to add mime %s to codec %s "
+ ALOGW("Fail to add media type %s to codec %s "
"after software codecs",
typeName.c_str(), nodeName.c_str());
- info->removeMime(typeName.c_str());
+ info->removeMediaType(typeName.c_str());
}
}
}
diff --git a/media/libstagefright/StagefrightMediaScanner.cpp b/media/libstagefright/StagefrightMediaScanner.cpp
index 74b7340..cf4edae 100644
--- a/media/libstagefright/StagefrightMediaScanner.cpp
+++ b/media/libstagefright/StagefrightMediaScanner.cpp
@@ -127,6 +127,8 @@
{ "colorstandard", METADATA_KEY_COLOR_STANDARD },
{ "colortransfer", METADATA_KEY_COLOR_TRANSFER },
{ "colorrange", METADATA_KEY_COLOR_RANGE },
+ { "samplerate", METADATA_KEY_SAMPLERATE },
+ { "bitspersample", METADATA_KEY_BITS_PER_SAMPLE },
};
static const size_t kNumEntries = sizeof(kKeyMap) / sizeof(kKeyMap[0]);
diff --git a/media/libstagefright/ThrottledSource.cpp b/media/libstagefright/ThrottledSource.cpp
index 7496752..49cea9e 100644
--- a/media/libstagefright/ThrottledSource.cpp
+++ b/media/libstagefright/ThrottledSource.cpp
@@ -51,7 +51,7 @@
// How long would it have taken to transfer everything we ever
// transferred given the limited bandwidth.
int64_t durationUs =
- mTotalTransferred * 1000000ll / mBandwidthLimitBytesPerSecond;
+ mTotalTransferred * 1000000LL / mBandwidthLimitBytesPerSecond;
int64_t whenUs = mStartTimeUs + durationUs;
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index 163cd05..49e485a 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -2020,7 +2020,7 @@
HLSTime::HLSTime(const sp<AMessage>& meta) :
mSeq(-1),
- mTimeUs(-1ll),
+ mTimeUs(-1LL),
mMeta(meta) {
if (meta != NULL) {
CHECK(meta->findInt32("discontinuitySeq", &mSeq));
@@ -2029,7 +2029,7 @@
}
int64_t HLSTime::getSegmentTimeUs() const {
- int64_t segmentStartTimeUs = -1ll;
+ int64_t segmentStartTimeUs = -1LL;
if (mMeta != NULL) {
CHECK(mMeta->findInt64("segmentStartTimeUs", &segmentStartTimeUs));
diff --git a/media/libstagefright/VideoFrameScheduler2.cpp b/media/libstagefright/VideoFrameScheduler2.cpp
index e02ae7d..fc76904 100644
--- a/media/libstagefright/VideoFrameScheduler2.cpp
+++ b/media/libstagefright/VideoFrameScheduler2.cpp
@@ -36,7 +36,7 @@
namespace android {
-static void getVsyncOffset(long* appVsyncOffsetPtr, long* sfVsyncOffsetPtr);
+static void getVsyncOffset(nsecs_t* appVsyncOffsetPtr, nsecs_t* sfVsyncOffsetPtr);
/* ======================================================================= */
/* VsyncTracker */
@@ -46,19 +46,19 @@
public:
VsyncTracker();
~VsyncTracker() {}
- long getVsyncPeriod();
- long getVsyncTime(long periodOffset);
- void addSample(long timestamp);
+ nsecs_t getVsyncPeriod();
+ nsecs_t getVsyncTime(nsecs_t periodOffset);
+ void addSample(nsecs_t timestamp);
private:
static const int kMaxSamples = 32;
static const int kMinSamplesForUpdate = 6;
int mNumSamples;
int mFirstSample;
- long mReferenceTime;
- long mPhase;
- long mPeriod;
- long mTimestampSamples[kMaxSamples];
+ nsecs_t mReferenceTime;
+ nsecs_t mPhase;
+ nsecs_t mPeriod;
+ nsecs_t mTimestampSamples[kMaxSamples];
Mutex mLock;
void updateModelLocked();
@@ -75,19 +75,39 @@
}
}
-long VsyncTracker::getVsyncPeriod() {
+nsecs_t VsyncTracker::getVsyncPeriod() {
Mutex::Autolock dataLock(mLock);
return mPeriod;
}
-long VsyncTracker::getVsyncTime(long periodOffset) {
+nsecs_t VsyncTracker::getVsyncTime(nsecs_t periodOffset) {
Mutex::Autolock dataLock(mLock);
- const long now = systemTime();
- long phase = mReferenceTime + mPhase;
- return (((now - phase) / mPeriod) + periodOffset + 1) * mPeriod + phase;
+ const nsecs_t now = systemTime();
+ nsecs_t phase = mReferenceTime + mPhase;
+
+ // result = (((now - phase) / mPeriod) + periodOffset + 1) * mPeriod + phase
+ // prevent overflow
+ nsecs_t result = (now - phase) / mPeriod;
+ if (result > LONG_LONG_MAX - periodOffset - 1) {
+ return LONG_LONG_MAX;
+ } else {
+ result += periodOffset + 1;
+ }
+ if (result > LONG_LONG_MAX / mPeriod) {
+ return LONG_LONG_MAX;
+ } else {
+ result *= mPeriod;
+ }
+ if (result > LONG_LONG_MAX - phase) {
+ return LONG_LONG_MAX;
+ } else {
+ result += phase;
+ }
+
+ return result;
}
-void VsyncTracker::addSample(long timestamp) {
+void VsyncTracker::addSample(nsecs_t timestamp) {
Mutex::Autolock dataLock(mLock);
if (mNumSamples == 0) {
mPhase = 0;
@@ -107,17 +127,17 @@
if (mNumSamples < kMinSamplesForUpdate) {
return;
}
- long durationSum = 0;
- long minDuration = LONG_MAX;
- long maxDuration = 0;
+ nsecs_t durationSum = 0;
+ nsecs_t minDuration = LONG_MAX;
+ nsecs_t maxDuration = 0;
for (int i = 1; i < mNumSamples; i++) {
int idx = (mFirstSample + i) % kMaxSamples;
int prev = (idx + kMaxSamples - 1) % kMaxSamples;
long duration = mTimestampSamples[idx] - mTimestampSamples[prev];
durationSum += duration;
- minDuration = min(minDuration, duration);
- maxDuration = max(maxDuration, duration);
+ if (minDuration > duration) { minDuration = duration; }
+ if (maxDuration < duration) { maxDuration = duration; }
}
durationSum -= (minDuration + maxDuration);
@@ -154,9 +174,9 @@
/* JNI */
/* ======================================================================= */
-static void getVsyncOffset(long* appVsyncOffsetPtr, long* sfVsyncOffsetPtr) {
- static const long kOneMillisecInNanosec = 1000000;
- static const long kOneSecInNanosec = kOneMillisecInNanosec * 1000;
+static void getVsyncOffset(nsecs_t* appVsyncOffsetPtr, nsecs_t* sfVsyncOffsetPtr) {
+ static const nsecs_t kOneMillisecInNanosec = 1000000;
+ static const nsecs_t kOneSecInNanosec = kOneMillisecInNanosec * 1000;
JNIEnv *env = JavaVMHelper::getJNIEnv();
jclass jDisplayManagerGlobalCls = env->FindClass(
@@ -178,19 +198,19 @@
jmethodID jGetRefreshRate = env->GetMethodID(jDisplayCls, "getRefreshRate", "()F");
jfloat javaRefreshRate = env->CallFloatMethod(javaDisplayObj, jGetRefreshRate);
- long vsyncPeriod = (long) (kOneSecInNanosec / (float) javaRefreshRate);
+ nsecs_t vsyncPeriod = (nsecs_t) (kOneSecInNanosec / (float) javaRefreshRate);
jmethodID jGetAppVsyncOffsetNanos = env->GetMethodID(
jDisplayCls, "getAppVsyncOffsetNanos", "()J");
jlong javaAppVsyncOffset = env->CallLongMethod(javaDisplayObj, jGetAppVsyncOffsetNanos);
- *appVsyncOffsetPtr = (long) javaAppVsyncOffset;
+ *appVsyncOffsetPtr = (nsecs_t) javaAppVsyncOffset;
jmethodID jGetPresentationDeadlineNanos = env->GetMethodID(
jDisplayCls, "getPresentationDeadlineNanos", "()J");
jlong javaPresentationDeadline = env->CallLongMethod(
javaDisplayObj, jGetPresentationDeadlineNanos);
- *sfVsyncOffsetPtr = vsyncPeriod - ((long) javaPresentationDeadline - kOneMillisecInNanosec);
+ *sfVsyncOffsetPtr = vsyncPeriod - ((nsecs_t) javaPresentationDeadline - kOneMillisecInNanosec);
}
/* ======================================================================= */
diff --git a/media/libstagefright/bqhelper/FrameDropper.cpp b/media/libstagefright/bqhelper/FrameDropper.cpp
index d2a2473..387ac5a 100644
--- a/media/libstagefright/bqhelper/FrameDropper.cpp
+++ b/media/libstagefright/bqhelper/FrameDropper.cpp
@@ -35,7 +35,7 @@
status_t FrameDropper::setMaxFrameRate(float maxFrameRate) {
if (maxFrameRate < 0) {
- mMinIntervalUs = -1ll;
+ mMinIntervalUs = -1LL;
return OK;
}
diff --git a/media/libstagefright/bqhelper/GraphicBufferSource.cpp b/media/libstagefright/bqhelper/GraphicBufferSource.cpp
index 8c1da76..a4374c9 100644
--- a/media/libstagefright/bqhelper/GraphicBufferSource.cpp
+++ b/media/libstagefright/bqhelper/GraphicBufferSource.cpp
@@ -292,20 +292,20 @@
mSuspended(false),
mLastFrameTimestampUs(-1),
mStopTimeUs(-1),
- mLastActionTimeUs(-1ll),
- mSkipFramesBeforeNs(-1ll),
- mFrameRepeatIntervalUs(-1ll),
+ mLastActionTimeUs(-1LL),
+ mSkipFramesBeforeNs(-1LL),
+ mFrameRepeatIntervalUs(-1LL),
mRepeatLastFrameGeneration(0),
mOutstandingFrameRepeatCount(0),
mFrameRepeatBlockedOnCodecBuffer(false),
mFps(-1.0),
mCaptureFps(-1.0),
- mBaseCaptureUs(-1ll),
- mBaseFrameUs(-1ll),
+ mBaseCaptureUs(-1LL),
+ mBaseFrameUs(-1LL),
mFrameCount(0),
- mPrevCaptureUs(-1ll),
- mPrevFrameUs(-1ll),
- mInputBufferTimeOffsetUs(0ll) {
+ mPrevCaptureUs(-1LL),
+ mPrevFrameUs(-1LL),
+ mInputBufferTimeOffsetUs(0LL) {
ALOGV("GraphicBufferSource");
String8 name("GraphicBufferSource");
@@ -392,7 +392,7 @@
submitEndOfInputStream_l();
}
- if (mFrameRepeatIntervalUs > 0ll && mLooper == NULL) {
+ if (mFrameRepeatIntervalUs > 0LL && mLooper == NULL) {
mReflector = new AHandlerReflector<GraphicBufferSource>(this);
mLooper = new ALooper;
@@ -655,7 +655,7 @@
// only submit sample if start time is unspecified, or sample
// is queued after the specified start time
- if (mSkipFramesBeforeNs < 0ll || item.mTimestampNs >= mSkipFramesBeforeNs) {
+ if (mSkipFramesBeforeNs < 0LL || item.mTimestampNs >= mSkipFramesBeforeNs) {
// if start time is set, offset time stamp by start time
if (mSkipFramesBeforeNs > 0) {
item.mTimestampNs -= mSkipFramesBeforeNs;
@@ -677,7 +677,7 @@
} else {
// Don't set the last buffer id if we're not repeating,
// we'll be holding on to the last buffer for nothing.
- if (mFrameRepeatIntervalUs > 0ll) {
+ if (mFrameRepeatIntervalUs > 0LL) {
setLatestBuffer_l(item);
}
ALOGV("buffer submitted [slot=%d, useCount=%ld] acquired=%d",
@@ -755,7 +755,7 @@
&& (mFps > 2 * mCaptureFps
|| mCaptureFps > 2 * mFps)) {
// Time lapse or slow motion mode
- if (mPrevCaptureUs < 0ll) {
+ if (mPrevCaptureUs < 0LL) {
// first capture
mPrevCaptureUs = mBaseCaptureUs = timeUs;
// adjust the first sample timestamp.
@@ -1123,19 +1123,19 @@
mSuspended = false;
mEndOfStream = false;
mEndOfStreamSent = false;
- mSkipFramesBeforeNs = -1ll;
+ mSkipFramesBeforeNs = -1LL;
mFrameDropper.clear();
- mFrameRepeatIntervalUs = -1ll;
+ mFrameRepeatIntervalUs = -1LL;
mRepeatLastFrameGeneration = 0;
mOutstandingFrameRepeatCount = 0;
mLatestBuffer.mBuffer.reset();
mFrameRepeatBlockedOnCodecBuffer = false;
mFps = -1.0;
mCaptureFps = -1.0;
- mBaseCaptureUs = -1ll;
- mBaseFrameUs = -1ll;
- mPrevCaptureUs = -1ll;
- mPrevFrameUs = -1ll;
+ mBaseCaptureUs = -1LL;
+ mBaseFrameUs = -1LL;
+ mPrevCaptureUs = -1LL;
+ mPrevFrameUs = -1LL;
mFrameCount = 0;
mInputBufferTimeOffsetUs = 0;
mStopTimeUs = -1;
@@ -1201,7 +1201,7 @@
Mutex::Autolock autoLock(mMutex);
- if (mExecuting || repeatAfterUs <= 0ll) {
+ if (mExecuting || repeatAfterUs <= 0LL) {
return INVALID_OPERATION;
}
@@ -1213,7 +1213,7 @@
Mutex::Autolock autoLock(mMutex);
// timeOffsetUs must be negative for adjustment.
- if (timeOffsetUs >= 0ll) {
+ if (timeOffsetUs >= 0LL) {
return INVALID_OPERATION;
}
@@ -1247,7 +1247,7 @@
mSkipFramesBeforeNs =
(skipFramesBeforeUs > 0 && skipFramesBeforeUs <= INT64_MAX / 1000) ?
- (skipFramesBeforeUs * 1000) : -1ll;
+ (skipFramesBeforeUs * 1000) : -1LL;
return OK;
}
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
index d393c7a..41bc16c 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
+++ b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
@@ -738,7 +738,7 @@
} else {
int64_t currentTime = mBufferTimestamps.top();
currentTime += mStreamInfo->aacSamplesPerFrame *
- 1000000ll / mStreamInfo->aacSampleRate;
+ 1000000LL / mStreamInfo->aacSampleRate;
mBufferTimestamps.add(currentTime);
}
} else {
@@ -989,7 +989,7 @@
// adjust/interpolate next time stamp
*currentBufLeft -= decodedSize;
*nextTimeStamp += mStreamInfo->aacSamplesPerFrame *
- 1000000ll / mStreamInfo->aacSampleRate;
+ 1000000LL / mStreamInfo->aacSampleRate;
ALOGV("adjusted nextTimeStamp/size to %lld/%d",
(long long) *nextTimeStamp, *currentBufLeft);
} else {
diff --git a/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp b/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp
index 96e668e..6e437cf 100644
--- a/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp
+++ b/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp
@@ -63,7 +63,7 @@
mInputSize(0),
mInputFrame(NULL),
mAllocatedFrameSize(0),
- mInputTimeUs(-1ll),
+ mInputTimeUs(-1LL),
mSawInputEOS(false),
mSignalledError(false) {
initPorts();
@@ -587,7 +587,7 @@
// "Time" on the input buffer has in effect advanced by the
// number of audio frames we just advanced nOffset by.
inHeader->nTimeStamp +=
- (copy * 1000000ll / mSampleRate)
+ (copy * 1000000LL / mSampleRate)
/ (mNumChannels * sizeof(int16_t));
if (inHeader->nFilledLen == 0) {
@@ -725,7 +725,7 @@
mAllocatedFrameSize = 0;
mSentCodecSpecificData = false;
- mInputTimeUs = -1ll;
+ mInputTimeUs = -1LL;
mSawInputEOS = false;
mSignalledError = false;
}
diff --git a/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp b/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp
index b7e84ec..34dd011 100644
--- a/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp
+++ b/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp
@@ -505,7 +505,7 @@
outHeader->nTimeStamp =
mAnchorTimeUs
- + (mNumSamplesOutput * 1000000ll) / kSampleRateNB;
+ + (mNumSamplesOutput * 1000000LL) / kSampleRateNB;
mNumSamplesOutput += kNumSamplesPerFrameNB;
} else {
@@ -513,7 +513,7 @@
outHeader->nTimeStamp =
mAnchorTimeUs
- + (mNumSamplesOutput * 1000000ll) / kSampleRateWB;
+ + (mNumSamplesOutput * 1000000LL) / kSampleRateWB;
mNumSamplesOutput += kNumSamplesPerFrameWB;
}
diff --git a/media/libstagefright/codecs/amrnb/enc/SoftAMRNBEncoder.cpp b/media/libstagefright/codecs/amrnb/enc/SoftAMRNBEncoder.cpp
index f97c44f..85ab64e 100644
--- a/media/libstagefright/codecs/amrnb/enc/SoftAMRNBEncoder.cpp
+++ b/media/libstagefright/codecs/amrnb/enc/SoftAMRNBEncoder.cpp
@@ -49,7 +49,7 @@
mBitRate(0),
mMode(MR475),
mInputSize(0),
- mInputTimeUs(-1ll),
+ mInputTimeUs(-1LL),
mSawInputEOS(false),
mSignalledError(false) {
initPorts();
@@ -340,7 +340,7 @@
// "Time" on the input buffer has in effect advanced by the
// number of audio frames we just advanced nOffset by.
inHeader->nTimeStamp +=
- (copy * 1000000ll / kSampleRate) / sizeof(int16_t);
+ (copy * 1000000LL / kSampleRate) / sizeof(int16_t);
if (inHeader->nFilledLen == 0) {
if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
diff --git a/media/libstagefright/codecs/amrwbenc/SoftAMRWBEncoder.cpp b/media/libstagefright/codecs/amrwbenc/SoftAMRWBEncoder.cpp
index a644b66..7fb8a4c 100644
--- a/media/libstagefright/codecs/amrwbenc/SoftAMRWBEncoder.cpp
+++ b/media/libstagefright/codecs/amrwbenc/SoftAMRWBEncoder.cpp
@@ -50,7 +50,7 @@
mBitRate(0),
mMode(VOAMRWB_MD66),
mInputSize(0),
- mInputTimeUs(-1ll),
+ mInputTimeUs(-1LL),
mSawInputEOS(false),
mSignalledError(false) {
initPorts();
@@ -387,7 +387,7 @@
// "Time" on the input buffer has in effect advanced by the
// number of audio frames we just advanced nOffset by.
inHeader->nTimeStamp +=
- (copy * 1000000ll / kSampleRate) / sizeof(int16_t);
+ (copy * 1000000LL / kSampleRate) / sizeof(int16_t);
if (inHeader->nFilledLen == 0) {
if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
diff --git a/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp b/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp
index 3924fc2..bf5e243 100644
--- a/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp
+++ b/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp
@@ -607,7 +607,7 @@
timeTaken = mTimeEnd - mTimeStart;
ALOGV("timeTaken=%6lldus delay=%6lldus numBytes=%6d",
- (long long) (timeTaken / 1000ll), (long long) (timeDelay / 1000ll),
+ (long long) (timeTaken / 1000LL), (long long) (timeDelay / 1000LL),
s_dec_op.u4_num_bytes_consumed);
if (s_dec_op.u4_frame_decoded_flag && !mFlushNeeded) {
mFlushNeeded = true;
diff --git a/media/libstagefright/codecs/g711/dec/SoftG711.cpp b/media/libstagefright/codecs/g711/dec/SoftG711.cpp
index 7a4cca9..c14983a 100644
--- a/media/libstagefright/codecs/g711/dec/SoftG711.cpp
+++ b/media/libstagefright/codecs/g711/dec/SoftG711.cpp
@@ -372,7 +372,7 @@
int32_t step = 4 << segment;
- int32_t abs = (0x80l << exponent) + step * mantissa + step / 2 - 4 * 33;
+ int32_t abs = (0x80L << exponent) + step * mantissa + step / 2 - 4 * 33;
*out++ = (x < 0x80) ? -abs : abs;
}
diff --git a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
index fda7028..a8fcdd1 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
@@ -382,6 +382,7 @@
if (portIndex == 0 && mInitialized) {
CHECK_EQ((int)PVResetVideoDecoder(mHandle), (int)PV_TRUE);
}
+ mFramesConfigured = false;
}
void SoftMPEG4::onReset() {
diff --git a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
index cd984f0..80083f7 100644
--- a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
+++ b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
@@ -407,7 +407,7 @@
}
outHeader->nTimeStamp =
- mAnchorTimeUs + (mNumFramesOutput * 1000000ll) / mSamplingRate;
+ mAnchorTimeUs + (mNumFramesOutput * 1000000LL) / mSamplingRate;
if (inHeader) {
CHECK_GE((int32_t)inHeader->nFilledLen, mConfig->inputBufferUsedLength);
diff --git a/media/libstagefright/codecs/opus/dec/SoftOpus.cpp b/media/libstagefright/codecs/opus/dec/SoftOpus.cpp
index c6dc326..4f61aa8 100644
--- a/media/libstagefright/codecs/opus/dec/SoftOpus.cpp
+++ b/media/libstagefright/codecs/opus/dec/SoftOpus.cpp
@@ -582,7 +582,7 @@
outHeader->nFilledLen = numFrames * sizeof(int16_t) * mHeader->channels;
outHeader->nTimeStamp = mAnchorTimeUs +
- (mNumFramesOutput * 1000000ll) /
+ (mNumFramesOutput * 1000000LL) /
kRate;
mNumFramesOutput += numFrames;
diff --git a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
index ce8d458..76a400c 100644
--- a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
+++ b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
@@ -554,7 +554,7 @@
outHeader->nTimeStamp =
mAnchorTimeUs
- + (mNumFramesOutput * 1000000ll) / mVi->rate;
+ + (mNumFramesOutput * 1000000LL) / mVi->rate;
mNumFramesOutput += numFrames;
diff --git a/media/libstagefright/codecs/xaacdec/SoftXAAC.cpp b/media/libstagefright/codecs/xaacdec/SoftXAAC.cpp
index 1d792fd..8a86a0d 100644
--- a/media/libstagefright/codecs/xaacdec/SoftXAAC.cpp
+++ b/media/libstagefright/codecs/xaacdec/SoftXAAC.cpp
@@ -649,7 +649,7 @@
mCurrentTimestamp = inHeader->nTimeStamp;
mLastInHeader = inHeader;
} else {
- mCurrentTimestamp = mPrevTimestamp + mOutputFrameLength * 1000000ll / mSampFreq;
+ mCurrentTimestamp = mPrevTimestamp + mOutputFrameLength * 1000000LL / mSampFreq;
}
} else {
inBuffer = inHeader->pBuffer + inHeader->nOffset;
diff --git a/media/libstagefright/foundation/ALooper.cpp b/media/libstagefright/foundation/ALooper.cpp
index 768cbd6..a276722 100644
--- a/media/libstagefright/foundation/ALooper.cpp
+++ b/media/libstagefright/foundation/ALooper.cpp
@@ -66,7 +66,7 @@
// static
int64_t ALooper::GetNowUs() {
- return systemTime(SYSTEM_TIME_MONOTONIC) / 1000ll;
+ return systemTime(SYSTEM_TIME_MONOTONIC) / 1000LL;
}
ALooper::ALooper()
diff --git a/media/libstagefright/foundation/Android.bp b/media/libstagefright/foundation/Android.bp
index dcf1ab8..dd1d904 100644
--- a/media/libstagefright/foundation/Android.bp
+++ b/media/libstagefright/foundation/Android.bp
@@ -4,8 +4,8 @@
vendor_available: true,
}
-cc_library {
- name: "libstagefright_foundation",
+cc_defaults {
+ name: "libstagefright_foundation_defaults",
vendor_available: true,
vndk: {
enabled: true,
@@ -25,6 +25,7 @@
header_libs: [
"libhardware_headers",
"libstagefright_foundation_headers",
+ "media_ndk_headers",
"media_plugin_headers",
],
@@ -64,8 +65,13 @@
"AudioPresentationInfo.cpp",
"ByteUtils.cpp",
"ColorUtils.cpp",
+ "MediaBuffer.cpp",
+ "MediaBufferBase.cpp",
+ "MediaBufferGroup.cpp",
"MediaDefs.cpp",
"MediaKeys.cpp",
+ "MetaData.cpp",
+ "MetaDataBase.cpp",
"avc_utils.cpp",
"base64.cpp",
"hexdump.cpp",
@@ -81,3 +87,20 @@
cfi: true,
},
}
+
+cc_library {
+ name: "libstagefright_foundation",
+ defaults: ["libstagefright_foundation_defaults"],
+}
+
+cc_library_static {
+ name: "libstagefright_foundation_without_imemory",
+ defaults: ["libstagefright_foundation_defaults"],
+
+ cflags: [
+ "-Wno-multichar",
+ "-Werror",
+ "-Wall",
+ "-DNO_IMEMORY",
+ ],
+}
diff --git a/media/libmediaextractor/MediaBuffer.cpp b/media/libstagefright/foundation/MediaBuffer.cpp
similarity index 93%
rename from media/libmediaextractor/MediaBuffer.cpp
rename to media/libstagefright/foundation/MediaBuffer.cpp
index bab3a03..9beac05 100644
--- a/media/libmediaextractor/MediaBuffer.cpp
+++ b/media/libstagefright/foundation/MediaBuffer.cpp
@@ -59,9 +59,11 @@
#ifndef NO_IMEMORY
} else {
ALOGV("creating memoryDealer");
- sp<MemoryDealer> memoryDealer =
- new MemoryDealer(size + sizeof(SharedControl), "MediaBuffer");
- mMemory = memoryDealer->allocate(size + sizeof(SharedControl));
+ size_t newSize = 0;
+ if (!__builtin_add_overflow(size, sizeof(SharedControl), &newSize)) {
+ sp<MemoryDealer> memoryDealer = new MemoryDealer(newSize, "MediaBuffer");
+ mMemory = memoryDealer->allocate(newSize);
+ }
if (mMemory == NULL) {
ALOGW("Failed to allocate shared memory, trying regular allocation!");
mData = malloc(size);
diff --git a/media/libmediaextractor/MediaBufferBase.cpp b/media/libstagefright/foundation/MediaBufferBase.cpp
similarity index 100%
rename from media/libmediaextractor/MediaBufferBase.cpp
rename to media/libstagefright/foundation/MediaBufferBase.cpp
diff --git a/media/libmediaextractor/MediaBufferGroup.cpp b/media/libstagefright/foundation/MediaBufferGroup.cpp
similarity index 100%
rename from media/libmediaextractor/MediaBufferGroup.cpp
rename to media/libstagefright/foundation/MediaBufferGroup.cpp
diff --git a/media/libmediaextractor/MetaData.cpp b/media/libstagefright/foundation/MetaData.cpp
similarity index 100%
rename from media/libmediaextractor/MetaData.cpp
rename to media/libstagefright/foundation/MetaData.cpp
diff --git a/media/libmediaextractor/MetaDataBase.cpp b/media/libstagefright/foundation/MetaDataBase.cpp
similarity index 100%
rename from media/libmediaextractor/MetaDataBase.cpp
rename to media/libstagefright/foundation/MetaDataBase.cpp
diff --git a/media/libstagefright/httplive/Android.bp b/media/libstagefright/httplive/Android.bp
index c4a072b..c0ee14e 100644
--- a/media/libstagefright/httplive/Android.bp
+++ b/media/libstagefright/httplive/Android.bp
@@ -32,7 +32,6 @@
"libcrypto",
"libcutils",
"libmedia",
- "libmediaextractor",
"libmediandk",
"libstagefright",
"libstagefright_foundation",
diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp
index 86872c5..2ecfa43 100644
--- a/media/libstagefright/httplive/LiveSession.cpp
+++ b/media/libstagefright/httplive/LiveSession.cpp
@@ -44,10 +44,10 @@
// static
// Bandwidth Switch Mark Defaults
-const int64_t LiveSession::kUpSwitchMarkUs = 15000000ll;
-const int64_t LiveSession::kDownSwitchMarkUs = 20000000ll;
-const int64_t LiveSession::kUpSwitchMarginUs = 5000000ll;
-const int64_t LiveSession::kResumeThresholdUs = 100000ll;
+const int64_t LiveSession::kUpSwitchMarkUs = 15000000LL;
+const int64_t LiveSession::kDownSwitchMarkUs = 20000000LL;
+const int64_t LiveSession::kUpSwitchMarginUs = 5000000LL;
+const int64_t LiveSession::kResumeThresholdUs = 100000LL;
//TODO: redefine this mark to a fair value
// default buffer underflow mark
@@ -66,9 +66,9 @@
// Bandwidth estimation parameters
static const int32_t kShortTermBandwidthItems = 3;
static const int32_t kMinBandwidthHistoryItems = 20;
- static const int64_t kMinBandwidthHistoryWindowUs = 5000000ll; // 5 sec
- static const int64_t kMaxBandwidthHistoryWindowUs = 30000000ll; // 30 sec
- static const int64_t kMaxBandwidthHistoryAgeUs = 60000000ll; // 60 sec
+ static const int64_t kMinBandwidthHistoryWindowUs = 5000000LL; // 5 sec
+ static const int64_t kMaxBandwidthHistoryWindowUs = 30000000LL; // 30 sec
+ static const int64_t kMaxBandwidthHistoryAgeUs = 60000000LL; // 60 sec
struct BandwidthEntry {
int64_t mTimestampUs;
@@ -284,7 +284,7 @@
mPrevBufferPercentage(-1),
mCurBandwidthIndex(-1),
mOrigBandwidthIndex(-1),
- mLastBandwidthBps(-1ll),
+ mLastBandwidthBps(-1LL),
mLastBandwidthStable(false),
mBandwidthEstimator(new BandwidthEstimator()),
mMaxWidth(720),
@@ -294,8 +294,8 @@
mSwapMask(0),
mSwitchGeneration(0),
mSubtitleGeneration(0),
- mLastDequeuedTimeUs(0ll),
- mRealTimeBaseUs(0ll),
+ mLastDequeuedTimeUs(0LL),
+ mRealTimeBaseUs(0LL),
mReconfigurationInProgress(false),
mSwitchInProgress(false),
mUpSwitchMark(kUpSwitchMarkUs),
@@ -844,7 +844,7 @@
// (If we don't have that cushion we'd rather cancel and try again.)
int64_t delayUs =
switchUp ?
- (kUnderflowMarkMs * 1000ll + 1000000ll)
+ (kUnderflowMarkMs * 1000LL + 1000000LL)
: 0;
bool needResumeUntil = false;
sp<AMessage> stopParams = msg;
@@ -954,7 +954,7 @@
// static
bool LiveSession::isBandwidthValid(const BandwidthItem &item) {
- static const int64_t kBlacklistWindowUs = 300 * 1000000ll;
+ static const int64_t kBlacklistWindowUs = 300 * 1000000LL;
return item.mLastFailureUs < 0
|| ALooper::GetNowUs() - item.mLastFailureUs > kBlacklistWindowUs;
}
@@ -1060,7 +1060,7 @@
BandwidthItem item;
item.mPlaylistIndex = i;
- item.mLastFailureUs = -1ll;
+ item.mLastFailureUs = -1LL;
sp<AMessage> meta;
AString uri;
@@ -1114,7 +1114,7 @@
mPlaylist->pickRandomMediaItems();
changeConfiguration(
- 0ll /* timeUs */, initialBandwidthIndex, false /* pickTrack */);
+ 0LL /* timeUs */, initialBandwidthIndex, false /* pickTrack */);
}
void LiveSession::finishDisconnect() {
@@ -1175,7 +1175,7 @@
FetcherInfo info;
info.mFetcher = new PlaylistFetcher(
notify, this, uri, mCurBandwidthIndex, mSubtitleGeneration);
- info.mDurationUs = -1ll;
+ info.mDurationUs = -1LL;
info.mToBeRemoved = false;
info.mToBeResumed = false;
mFetcherLooper->registerHandler(info.mFetcher);
@@ -1466,7 +1466,7 @@
}
status_t LiveSession::getDuration(int64_t *durationUs) const {
- int64_t maxDurationUs = -1ll;
+ int64_t maxDurationUs = -1LL;
for (size_t i = 0; i < mFetcherInfos.size(); ++i) {
int64_t fetcherDurationUs = mFetcherInfos.valueAt(i).mDurationUs;
@@ -1592,7 +1592,7 @@
// Delay fetcher removal if not picking tracks, AND old fetcher
// has stream mask that overlaps new variant. (Okay to discard
// old fetcher now, if completely no overlap.)
- if (discardFetcher && timeUs < 0ll && !pickTrack
+ if (discardFetcher && timeUs < 0LL && !pickTrack
&& (fetcher->getStreamTypeMask() & streamMask)) {
discardFetcher = false;
delayRemoval = true;
@@ -1604,7 +1604,7 @@
} else {
float threshold = 0.0f; // default to pause after current block (47Kbytes)
bool disconnect = false;
- if (timeUs >= 0ll) {
+ if (timeUs >= 0LL) {
// seeking, no need to finish fetching
disconnect = true;
} else if (delayRemoval) {
@@ -1620,7 +1620,7 @@
}
sp<AMessage> msg;
- if (timeUs < 0ll) {
+ if (timeUs < 0LL) {
// skip onChangeConfiguration2 (decoder destruction) if not seeking.
msg = new AMessage(kWhatChangeConfiguration3, this);
} else {
@@ -1654,9 +1654,9 @@
if (!mReconfigurationInProgress) {
int32_t pickTrack = 0;
msg->findInt32("pickTrack", &pickTrack);
- changeConfiguration(-1ll /* timeUs */, -1, pickTrack);
+ changeConfiguration(-1LL /* timeUs */, -1, pickTrack);
} else {
- msg->post(1000000ll); // retry in 1 sec
+ msg->post(1000000LL); // retry in 1 sec
}
}
@@ -1788,7 +1788,7 @@
CHECK(msg->findInt64("timeUs", &timeUs));
CHECK(msg->findInt32("pickTrack", &pickTrack));
- if (timeUs < 0ll) {
+ if (timeUs < 0LL) {
if (!pickTrack) {
// mSwapMask contains streams that are in both old and new variant,
// (in mNewStreamMask & mStreamMask) but with different URIs
@@ -2062,7 +2062,7 @@
void LiveSession::schedulePollBuffering() {
sp<AMessage> msg = new AMessage(kWhatPollBuffering, this);
msg->setInt32("generation", mPollBufferingGeneration);
- msg->post(1000000ll);
+ msg->post(1000000LL);
}
void LiveSession::cancelPollBuffering() {
@@ -2208,13 +2208,13 @@
int64_t readyMarkUs =
(mInPreparationPhase ?
mBufferingSettings.mInitialMarkMs :
- mBufferingSettings.mResumePlaybackMarkMs) * 1000ll;
+ mBufferingSettings.mResumePlaybackMarkMs) * 1000LL;
if (bufferedDurationUs > readyMarkUs
|| mPacketSources[i]->isFinished(0)) {
++readyCount;
}
if (!mPacketSources[i]->isFinished(0)) {
- if (bufferedDurationUs < kUnderflowMarkMs * 1000ll) {
+ if (bufferedDurationUs < kUnderflowMarkMs * 1000LL) {
++underflowCount;
}
if (bufferedDurationUs > mUpSwitchMark) {
@@ -2300,7 +2300,7 @@
ssize_t lowestValid = getLowestValidBandwidthIndex();
if (mCurBandwidthIndex > lowestValid) {
cancelBandwidthSwitch();
- changeConfiguration(-1ll, lowestValid);
+ changeConfiguration(-1LL, lowestValid);
return true;
}
}
@@ -2370,7 +2370,7 @@
// if not yet prepared, just restart again with new bw index.
// this is faster and playback experience is cleaner.
changeConfiguration(
- mInPreparationPhase ? 0 : -1ll, bandwidthIndex);
+ mInPreparationPhase ? 0 : -1LL, bandwidthIndex);
return true;
}
}
diff --git a/media/libstagefright/httplive/M3UParser.cpp b/media/libstagefright/httplive/M3UParser.cpp
index d06d9f2..16179d3 100644
--- a/media/libstagefright/httplive/M3UParser.cpp
+++ b/media/libstagefright/httplive/M3UParser.cpp
@@ -258,7 +258,7 @@
mIsEvent(false),
mFirstSeqNumber(-1),
mLastSeqNumber(-1),
- mTargetDurationUs(-1ll),
+ mTargetDurationUs(-1LL),
mDiscontinuitySeq(0),
mDiscontinuityCount(0),
mSelectedIndex(-1) {
@@ -716,7 +716,7 @@
ALOGE("Media playlist missing #EXT-X-TARGETDURATION");
return ERROR_MALFORMED;
}
- mTargetDurationUs = targetDurationSecs * 1000000ll;
+ mTargetDurationUs = targetDurationSecs * 1000000LL;
mFirstSeqNumber = 0;
if (mMeta != NULL) {
diff --git a/media/libstagefright/httplive/PlaylistFetcher.cpp b/media/libstagefright/httplive/PlaylistFetcher.cpp
index 823f90e..562c625 100644
--- a/media/libstagefright/httplive/PlaylistFetcher.cpp
+++ b/media/libstagefright/httplive/PlaylistFetcher.cpp
@@ -50,8 +50,8 @@
namespace android {
// static
-const int64_t PlaylistFetcher::kMinBufferedDurationUs = 30000000ll;
-const int64_t PlaylistFetcher::kMaxMonitorDelayUs = 3000000ll;
+const int64_t PlaylistFetcher::kMinBufferedDurationUs = 30000000LL;
+const int64_t PlaylistFetcher::kMaxMonitorDelayUs = 3000000LL;
// LCM of 188 (size of a TS packet) & 1k works well
const int32_t PlaylistFetcher::kDownloadBlockSize = 47 * 1024;
@@ -152,25 +152,25 @@
mURI(uri),
mFetcherID(id),
mStreamTypeMask(0),
- mStartTimeUs(-1ll),
- mSegmentStartTimeUs(-1ll),
- mDiscontinuitySeq(-1ll),
+ mStartTimeUs(-1LL),
+ mSegmentStartTimeUs(-1LL),
+ mDiscontinuitySeq(-1LL),
mStartTimeUsRelative(false),
- mLastPlaylistFetchTimeUs(-1ll),
- mPlaylistTimeUs(-1ll),
+ mLastPlaylistFetchTimeUs(-1LL),
+ mPlaylistTimeUs(-1LL),
mSeqNumber(-1),
mNumRetries(0),
mStartup(true),
mIDRFound(false),
mSeekMode(LiveSession::kSeekModeExactPosition),
mTimeChangeSignaled(false),
- mNextPTSTimeUs(-1ll),
+ mNextPTSTimeUs(-1LL),
mMonitorQueueGeneration(0),
mSubtitleGeneration(subtitleGeneration),
- mLastDiscontinuitySeq(-1ll),
+ mLastDiscontinuitySeq(-1LL),
mRefreshState(INITIAL_MINIMUM_RELOAD_DELAY),
mFirstPTSValid(false),
- mFirstTimeUs(-1ll),
+ mFirstTimeUs(-1LL),
mVideoBuffer(new AnotherPacketSource(NULL)),
mSampleAesKeyItemChanged(false),
mThresholdRatio(-1.0f),
@@ -200,7 +200,7 @@
CHECK_GE(seqNumber, firstSeqNumberInPlaylist);
CHECK_LE(seqNumber, lastSeqNumberInPlaylist);
- int64_t segmentStartUs = 0ll;
+ int64_t segmentStartUs = 0LL;
for (int32_t index = 0;
index < seqNumber - firstSeqNumberInPlaylist; ++index) {
sp<AMessage> itemMeta;
@@ -240,13 +240,13 @@
int64_t PlaylistFetcher::delayUsToRefreshPlaylist() const {
int64_t nowUs = ALooper::GetNowUs();
- if (mPlaylist == NULL || mLastPlaylistFetchTimeUs < 0ll) {
+ if (mPlaylist == NULL || mLastPlaylistFetchTimeUs < 0LL) {
CHECK_EQ((int)mRefreshState, (int)INITIAL_MINIMUM_RELOAD_DELAY);
- return 0ll;
+ return 0LL;
}
if (mPlaylist->isComplete()) {
- return (~0llu >> 1);
+ return (~0LLU >> 1);
}
int64_t targetDurationUs = mPlaylist->getTargetDuration();
@@ -295,7 +295,7 @@
}
int64_t delayUs = mLastPlaylistFetchTimeUs + minPlaylistAgeUs - nowUs;
- return delayUs > 0ll ? delayUs : 0ll;
+ return delayUs > 0LL ? delayUs : 0LL;
}
status_t PlaylistFetcher::decryptBuffer(
@@ -857,7 +857,7 @@
targetDurationUs = mPlaylist->getTargetDuration();
}
- int64_t bufferedDurationUs = 0ll;
+ int64_t bufferedDurationUs = 0LL;
status_t finalResult = OK;
if (mStreamTypeMask == LiveSession::STREAMTYPE_SUBTITLES) {
sp<AnotherPacketSource> packetSource =
@@ -870,7 +870,7 @@
// enqueued to prevent us from waiting on a non-existent stream;
// when we cannot make out from the manifest what streams are included in
// a playlist we might assume extra streams.
- bufferedDurationUs = -1ll;
+ bufferedDurationUs = -1LL;
for (size_t i = 0; i < mPacketSources.size(); ++i) {
if ((mStreamTypeMask & mPacketSources.keyAt(i)) == 0
|| mPacketSources[i]->getLatestEnqueuedMeta() == NULL) {
@@ -882,13 +882,13 @@
FSLOGV(mPacketSources.keyAt(i), "buffered %lld", (long long)bufferedStreamDurationUs);
- if (bufferedDurationUs == -1ll
+ if (bufferedDurationUs == -1LL
|| bufferedStreamDurationUs < bufferedDurationUs) {
bufferedDurationUs = bufferedStreamDurationUs;
}
}
- if (bufferedDurationUs == -1ll) {
- bufferedDurationUs = 0ll;
+ if (bufferedDurationUs == -1LL) {
+ bufferedDurationUs = 0LL;
}
}
@@ -901,12 +901,12 @@
// onDownloadNext();
sp<AMessage> msg = new AMessage(kWhatDownloadNext, this);
msg->setInt32("generation", mMonitorQueueGeneration);
- msg->post(1000l);
+ msg->post(1000L);
} else {
// We'd like to maintain buffering above durationToBufferUs, so try
// again when buffer just about to go below durationToBufferUs
// (or after targetDurationUs / 2, whichever is smaller).
- int64_t delayUs = bufferedDurationUs - kMinBufferedDurationUs + 1000000ll;
+ int64_t delayUs = bufferedDurationUs - kMinBufferedDurationUs + 1000000LL;
if (delayUs > targetDurationUs / 2) {
delayUs = targetDurationUs / 2;
}
@@ -1073,10 +1073,10 @@
}
}
- mSegmentFirstPTS = -1ll;
+ mSegmentFirstPTS = -1LL;
if (mPlaylist != NULL && mSeqNumber < 0) {
- CHECK_GE(mStartTimeUs, 0ll);
+ CHECK_GE(mStartTimeUs, 0LL);
if (mSegmentStartTimeUs < 0) {
if (!mPlaylist->isComplete() && !mPlaylist->isEvent()) {
@@ -1379,7 +1379,7 @@
& (LiveSession::STREAMTYPE_AUDIO
| LiveSession::STREAMTYPE_VIDEO))) {
mSession->addBandwidthMeasurement(bytesRead, delayUs);
- if (delayUs > 2000000ll) {
+ if (delayUs > 2000000LL) {
FLOGV("bytesRead %zd took %.2f seconds - abnormal bandwidth dip",
bytesRead, (double)delayUs / 1.0e6);
}
@@ -1553,7 +1553,7 @@
// if the previous fetcher paused in the middle of a segment, we
// want to start at a segment that overlaps the last sample
minDiffUs = -mPlaylist->getTargetDuration();
- maxDiffUs = 0ll;
+ maxDiffUs = 0LL;
} else {
// if the previous fetcher paused at the end of a segment, ideally
// we want to start at the segment that's roughly aligned with its
@@ -1704,7 +1704,7 @@
mTSParser = new ATSParser(ATSParser::TS_TIMESTAMPS_ARE_ABSOLUTE);
}
- if (mNextPTSTimeUs >= 0ll) {
+ if (mNextPTSTimeUs >= 0LL) {
sp<AMessage> extra = new AMessage;
// Since we are using absolute timestamps, signal an offset of 0 to prevent
// ATSParser from skewing the timestamps of access units.
@@ -1719,7 +1719,7 @@
mTSParser->signalDiscontinuity(
ATSParser::DISCONTINUITY_TIME, extra);
- mNextPTSTimeUs = -1ll;
+ mNextPTSTimeUs = -1LL;
}
if (mSampleAesKeyItemChanged) {
@@ -1740,7 +1740,7 @@
// setRange to indicate consumed bytes.
buffer->setRange(buffer->offset() + offset, buffer->size() - offset);
- if (mSegmentFirstPTS < 0ll) {
+ if (mSegmentFirstPTS < 0LL) {
// get the smallest first PTS from all streams present in this parser
for (size_t i = mPacketSources.size(); i > 0;) {
i--;
@@ -1764,12 +1764,12 @@
if (meta != NULL) {
int64_t timeUs;
CHECK(meta->findInt64("timeUs", &timeUs));
- if (mSegmentFirstPTS < 0ll || timeUs < mSegmentFirstPTS) {
+ if (mSegmentFirstPTS < 0LL || timeUs < mSegmentFirstPTS) {
mSegmentFirstPTS = timeUs;
}
}
}
- if (mSegmentFirstPTS < 0ll) {
+ if (mSegmentFirstPTS < 0LL) {
// didn't find any TS packet, can return early
return OK;
}
@@ -1988,8 +1988,8 @@
return OK;
}
- if (mNextPTSTimeUs >= 0ll) {
- mNextPTSTimeUs = -1ll;
+ if (mNextPTSTimeUs >= 0LL) {
+ mNextPTSTimeUs = -1LL;
}
// This better be an ISO 13818-7 (AAC) or ISO 13818-1 (MPEG) audio
@@ -2088,17 +2088,17 @@
packetSource->setFormat(meta);
}
- int64_t numSamples = 0ll;
+ int64_t numSamples = 0LL;
int32_t sampleRate;
CHECK(packetSource->getFormat()->findInt32(kKeySampleRate, &sampleRate));
- int64_t timeUs = (PTS * 100ll) / 9ll;
+ int64_t timeUs = (PTS * 100LL) / 9LL;
if (mStartup && !mFirstPTSValid) {
mFirstPTSValid = true;
mFirstTimeUs = timeUs;
}
- if (mSegmentFirstPTS < 0ll) {
+ if (mSegmentFirstPTS < 0LL) {
mSegmentFirstPTS = timeUs;
if (!mStartTimeUsRelative) {
// Duplicated logic from how we handle .ts playlists.
@@ -2148,7 +2148,7 @@
CHECK_LE(offset + aac_frame_length, buffer->size());
- int64_t unitTimeUs = timeUs + numSamples * 1000000ll / sampleRate;
+ int64_t unitTimeUs = timeUs + numSamples * 1000000LL / sampleRate;
offset += aac_frame_length;
// Each AAC frame encodes 1024 samples.
@@ -2209,7 +2209,7 @@
}
void PlaylistFetcher::updateDuration() {
- int64_t durationUs = 0ll;
+ int64_t durationUs = 0LL;
for (size_t index = 0; index < mPlaylist->size(); ++index) {
sp<AMessage> itemMeta;
CHECK(mPlaylist->itemAt(
diff --git a/media/libstagefright/id3/ID3.cpp b/media/libstagefright/id3/ID3.cpp
index b489183..792a68a 100644
--- a/media/libstagefright/id3/ID3.cpp
+++ b/media/libstagefright/id3/ID3.cpp
@@ -43,7 +43,7 @@
}
virtual ssize_t readAt(off64_t offset, void *data, size_t size) {
- off64_t available = (offset >= (off64_t)mSize) ? 0ll : mSize - offset;
+ off64_t available = (offset >= (off64_t)mSize) ? 0LL : mSize - offset;
size_t copy = (available > (off64_t)size) ? size : available;
memcpy(data, mData + offset, copy);
diff --git a/media/libmediaextractor/include/media/DataSource.h b/media/libstagefright/include/media/stagefright/DataSource.h
similarity index 100%
rename from media/libmediaextractor/include/media/DataSource.h
rename to media/libstagefright/include/media/stagefright/DataSource.h
diff --git a/media/libmediaextractor/include/media/DataSourceBase.h b/media/libstagefright/include/media/stagefright/DataSourceBase.h
similarity index 100%
rename from media/libmediaextractor/include/media/DataSourceBase.h
rename to media/libstagefright/include/media/stagefright/DataSourceBase.h
diff --git a/media/libstagefright/include/media/stagefright/MediaBuffer.h b/media/libstagefright/include/media/stagefright/MediaBuffer.h
deleted file mode 120000
index 1d49c1a..0000000
--- a/media/libstagefright/include/media/stagefright/MediaBuffer.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../../libmediaextractor/include/media/stagefright/MediaBuffer.h
\ No newline at end of file
diff --git a/media/libmediaextractor/include/media/stagefright/MediaBuffer.h b/media/libstagefright/include/media/stagefright/MediaBuffer.h
similarity index 100%
rename from media/libmediaextractor/include/media/stagefright/MediaBuffer.h
rename to media/libstagefright/include/media/stagefright/MediaBuffer.h
diff --git a/media/libstagefright/include/media/stagefright/MediaBufferBase.h b/media/libstagefright/include/media/stagefright/MediaBufferBase.h
deleted file mode 120000
index 80e49b0..0000000
--- a/media/libstagefright/include/media/stagefright/MediaBufferBase.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../../libmediaextractor/include/media/stagefright/MediaBufferBase.h
\ No newline at end of file
diff --git a/media/libmediaextractor/include/media/stagefright/MediaBufferBase.h b/media/libstagefright/include/media/stagefright/MediaBufferBase.h
similarity index 100%
rename from media/libmediaextractor/include/media/stagefright/MediaBufferBase.h
rename to media/libstagefright/include/media/stagefright/MediaBufferBase.h
diff --git a/media/libstagefright/include/media/stagefright/MediaBufferGroup.h b/media/libstagefright/include/media/stagefright/MediaBufferGroup.h
deleted file mode 120000
index 009b3d9..0000000
--- a/media/libstagefright/include/media/stagefright/MediaBufferGroup.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../../libmediaextractor/include/media/stagefright/MediaBufferGroup.h
\ No newline at end of file
diff --git a/media/libmediaextractor/include/media/stagefright/MediaBufferGroup.h b/media/libstagefright/include/media/stagefright/MediaBufferGroup.h
similarity index 100%
rename from media/libmediaextractor/include/media/stagefright/MediaBufferGroup.h
rename to media/libstagefright/include/media/stagefright/MediaBufferGroup.h
diff --git a/media/libstagefright/include/media/stagefright/MediaCodecConstants.h b/media/libstagefright/include/media/stagefright/MediaCodecConstants.h
index 984c23d..c06c288 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodecConstants.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodecConstants.h
@@ -31,6 +31,21 @@
constexpr int32_t AVCProfileConstrainedBaseline = 0x10000;
constexpr int32_t AVCProfileConstrainedHigh = 0x80000;
+inline static const char *asString_AVCProfile(int32_t i, const char *def = "??") {
+ switch (i) {
+ case AVCProfileBaseline: return "Baseline";
+ case AVCProfileMain: return "Main";
+ case AVCProfileExtended: return "Extended";
+ case AVCProfileHigh: return "High";
+ case AVCProfileHigh10: return "High10";
+ case AVCProfileHigh422: return "High422";
+ case AVCProfileHigh444: return "High444";
+ case AVCProfileConstrainedBaseline: return "ConstrainedBaseline";
+ case AVCProfileConstrainedHigh: return "ConstrainedHigh";
+ default: return def;
+ }
+}
+
constexpr int32_t AVCLevel1 = 0x01;
constexpr int32_t AVCLevel1b = 0x02;
constexpr int32_t AVCLevel11 = 0x04;
@@ -48,6 +63,35 @@
constexpr int32_t AVCLevel5 = 0x4000;
constexpr int32_t AVCLevel51 = 0x8000;
constexpr int32_t AVCLevel52 = 0x10000;
+constexpr int32_t AVCLevel6 = 0x20000;
+constexpr int32_t AVCLevel61 = 0x40000;
+constexpr int32_t AVCLevel62 = 0x80000;
+
+inline static const char *asString_AVCLevel(int32_t i, const char *def = "??") {
+ switch (i) {
+ case AVCLevel1: return "1";
+ case AVCLevel1b: return "1b";
+ case AVCLevel11: return "1.1";
+ case AVCLevel12: return "1.2";
+ case AVCLevel13: return "1.3";
+ case AVCLevel2: return "2";
+ case AVCLevel21: return "2.1";
+ case AVCLevel22: return "2.2";
+ case AVCLevel3: return "3";
+ case AVCLevel31: return "3.1";
+ case AVCLevel32: return "3.2";
+ case AVCLevel4: return "4";
+ case AVCLevel41: return "4.1";
+ case AVCLevel42: return "4.2";
+ case AVCLevel5: return "5";
+ case AVCLevel51: return "5.1";
+ case AVCLevel52: return "5.2";
+ case AVCLevel6: return "6";
+ case AVCLevel61: return "6.1";
+ case AVCLevel62: return "6.2";
+ default: return def;
+ }
+}
constexpr int32_t H263ProfileBaseline = 0x01;
constexpr int32_t H263ProfileH320Coding = 0x02;
@@ -59,6 +103,21 @@
constexpr int32_t H263ProfileInterlace = 0x80;
constexpr int32_t H263ProfileHighLatency = 0x100;
+inline static const char *asString_H263Profile(int32_t i, const char *def = "??") {
+ switch (i) {
+ case H263ProfileBaseline: return "Baseline";
+ case H263ProfileH320Coding: return "H320Coding";
+ case H263ProfileBackwardCompatible: return "BackwardCompatible";
+ case H263ProfileISWV2: return "ISWV2";
+ case H263ProfileISWV3: return "ISWV3";
+ case H263ProfileHighCompression: return "HighCompression";
+ case H263ProfileInternet: return "Internet";
+ case H263ProfileInterlace: return "Interlace";
+ case H263ProfileHighLatency: return "HighLatency";
+ default: return def;
+ }
+}
+
constexpr int32_t H263Level10 = 0x01;
constexpr int32_t H263Level20 = 0x02;
constexpr int32_t H263Level30 = 0x04;
@@ -68,6 +127,20 @@
constexpr int32_t H263Level60 = 0x40;
constexpr int32_t H263Level70 = 0x80;
+inline static const char *asString_H263Level(int32_t i, const char *def = "??") {
+ switch (i) {
+ case H263Level10: return "10";
+ case H263Level20: return "20";
+ case H263Level30: return "30";
+ case H263Level40: return "40";
+ case H263Level45: return "45";
+ case H263Level50: return "50";
+ case H263Level60: return "60";
+ case H263Level70: return "70";
+ default: return def;
+ }
+}
+
constexpr int32_t MPEG4ProfileSimple = 0x01;
constexpr int32_t MPEG4ProfileSimpleScalable = 0x02;
constexpr int32_t MPEG4ProfileCore = 0x04;
@@ -85,6 +158,28 @@
constexpr int32_t MPEG4ProfileAdvancedScalable = 0x4000;
constexpr int32_t MPEG4ProfileAdvancedSimple = 0x8000;
+inline static const char *asString_MPEG4Profile(int32_t i, const char *def = "??") {
+ switch (i) {
+ case MPEG4ProfileSimple: return "Simple";
+ case MPEG4ProfileSimpleScalable: return "SimpleScalable";
+ case MPEG4ProfileCore: return "Core";
+ case MPEG4ProfileMain: return "Main";
+ case MPEG4ProfileNbit: return "Nbit";
+ case MPEG4ProfileScalableTexture: return "ScalableTexture";
+ case MPEG4ProfileSimpleFace: return "SimpleFace";
+ case MPEG4ProfileSimpleFBA: return "SimpleFBA";
+ case MPEG4ProfileBasicAnimated: return "BasicAnimated";
+ case MPEG4ProfileHybrid: return "Hybrid";
+ case MPEG4ProfileAdvancedRealTime: return "AdvancedRealTime";
+ case MPEG4ProfileCoreScalable: return "CoreScalable";
+ case MPEG4ProfileAdvancedCoding: return "AdvancedCoding";
+ case MPEG4ProfileAdvancedCore: return "AdvancedCore";
+ case MPEG4ProfileAdvancedScalable: return "AdvancedScalable";
+ case MPEG4ProfileAdvancedSimple: return "AdvancedSimple";
+ default: return def;
+ }
+}
+
constexpr int32_t MPEG4Level0 = 0x01;
constexpr int32_t MPEG4Level0b = 0x02;
constexpr int32_t MPEG4Level1 = 0x04;
@@ -96,6 +191,22 @@
constexpr int32_t MPEG4Level5 = 0x80;
constexpr int32_t MPEG4Level6 = 0x100;
+inline static const char *asString_MPEG4Level(int32_t i, const char *def = "??") {
+ switch (i) {
+ case MPEG4Level0: return "0";
+ case MPEG4Level0b: return "0b";
+ case MPEG4Level1: return "1";
+ case MPEG4Level2: return "2";
+ case MPEG4Level3: return "3";
+ case MPEG4Level3b: return "3b";
+ case MPEG4Level4: return "4";
+ case MPEG4Level4a: return "4a";
+ case MPEG4Level5: return "5";
+ case MPEG4Level6: return "6";
+ default: return def;
+ }
+}
+
constexpr int32_t MPEG2ProfileSimple = 0x00;
constexpr int32_t MPEG2ProfileMain = 0x01;
constexpr int32_t MPEG2Profile422 = 0x02;
@@ -103,12 +214,35 @@
constexpr int32_t MPEG2ProfileSpatial = 0x04;
constexpr int32_t MPEG2ProfileHigh = 0x05;
+inline static const char *asString_MPEG2Profile(int32_t i, const char *def = "??") {
+ switch (i) {
+ case MPEG2ProfileSimple: return "Simple";
+ case MPEG2ProfileMain: return "Main";
+ case MPEG2Profile422: return "422";
+ case MPEG2ProfileSNR: return "SNR";
+ case MPEG2ProfileSpatial: return "Spatial";
+ case MPEG2ProfileHigh: return "High";
+ default: return def;
+ }
+}
+
constexpr int32_t MPEG2LevelLL = 0x00;
constexpr int32_t MPEG2LevelML = 0x01;
constexpr int32_t MPEG2LevelH14 = 0x02;
constexpr int32_t MPEG2LevelHL = 0x03;
constexpr int32_t MPEG2LevelHP = 0x04;
+inline static const char *asString_MPEG2Level(int32_t i, const char *def = "??") {
+ switch (i) {
+ case MPEG2LevelLL: return "LL";
+ case MPEG2LevelML: return "ML";
+ case MPEG2LevelH14: return "H14";
+ case MPEG2LevelHL: return "HL";
+ case MPEG2LevelHP: return "HP";
+ default: return def;
+ }
+}
+
constexpr int32_t AACObjectMain = 1;
constexpr int32_t AACObjectLC = 2;
constexpr int32_t AACObjectSSR = 3;
@@ -122,13 +256,48 @@
constexpr int32_t AACObjectELD = 39;
constexpr int32_t AACObjectXHE = 42;
+inline static const char *asString_AACObject(int32_t i, const char *def = "??") {
+ switch (i) {
+ case AACObjectMain: return "Main";
+ case AACObjectLC: return "LC";
+ case AACObjectSSR: return "SSR";
+ case AACObjectLTP: return "LTP";
+ case AACObjectHE: return "HE";
+ case AACObjectScalable: return "Scalable";
+ case AACObjectERLC: return "ERLC";
+ case AACObjectERScalable: return "ERScalable";
+ case AACObjectLD: return "LD";
+ case AACObjectHE_PS: return "HE_PS";
+ case AACObjectELD: return "ELD";
+ case AACObjectXHE: return "XHE";
+ default: return def;
+ }
+}
+
constexpr int32_t VP8Level_Version0 = 0x01;
constexpr int32_t VP8Level_Version1 = 0x02;
constexpr int32_t VP8Level_Version2 = 0x04;
constexpr int32_t VP8Level_Version3 = 0x08;
+inline static const char *asString_VP8Level(int32_t i, const char *def = "??") {
+ switch (i) {
+ case VP8Level_Version0: return "V0";
+ case VP8Level_Version1: return "V1";
+ case VP8Level_Version2: return "V2";
+ case VP8Level_Version3: return "V3";
+ default: return def;
+ }
+}
+
constexpr int32_t VP8ProfileMain = 0x01;
+inline static const char *asString_VP8Profile(int32_t i, const char *def = "??") {
+ switch (i) {
+ case VP8ProfileMain: return "Main";
+ default: return def;
+ }
+}
+
constexpr int32_t VP9Profile0 = 0x01;
constexpr int32_t VP9Profile1 = 0x02;
constexpr int32_t VP9Profile2 = 0x04;
@@ -138,6 +307,20 @@
constexpr int32_t VP9Profile2HDR10Plus = 0x4000;
constexpr int32_t VP9Profile3HDR10Plus = 0x8000;
+inline static const char *asString_VP9Profile(int32_t i, const char *def = "??") {
+ switch (i) {
+ case VP9Profile0: return "0";
+ case VP9Profile1: return "1";
+ case VP9Profile2: return "2";
+ case VP9Profile3: return "3";
+ case VP9Profile2HDR: return "2HDR";
+ case VP9Profile3HDR: return "3HDR";
+ case VP9Profile2HDR10Plus: return "2HDRPlus";
+ case VP9Profile3HDR10Plus: return "3HDRPlus";
+ default: return def;
+ }
+}
+
constexpr int32_t VP9Level1 = 0x1;
constexpr int32_t VP9Level11 = 0x2;
constexpr int32_t VP9Level2 = 0x4;
@@ -153,10 +336,39 @@
constexpr int32_t VP9Level61 = 0x1000;
constexpr int32_t VP9Level62 = 0x2000;
+inline static const char *asString_VP9Level(int32_t i, const char *def = "??") {
+ switch (i) {
+ case VP9Level1: return "1";
+ case VP9Level11: return "1.1";
+ case VP9Level2: return "2";
+ case VP9Level21: return "2.1";
+ case VP9Level3: return "3";
+ case VP9Level31: return "3.1";
+ case VP9Level4: return "4";
+ case VP9Level41: return "4.1";
+ case VP9Level5: return "5";
+ case VP9Level51: return "5.1";
+ case VP9Level52: return "5.2";
+ case VP9Level6: return "6";
+ case VP9Level61: return "6.1";
+ case VP9Level62: return "6.2";
+ default: return def;
+ }
+}
+
constexpr int32_t AV1Profile0 = 0x01;
constexpr int32_t AV1Profile1 = 0x02;
constexpr int32_t AV1Profile2 = 0x04;
+inline static const char *asString_AV1Profile(int32_t i, const char *def = "??") {
+ switch (i) {
+ case AV1Profile0: return "0";
+ case AV1Profile1: return "1";
+ case AV1Profile2: return "2";
+ default: return def;
+ }
+}
+
constexpr int32_t AV1Level2 = 0x1;
constexpr int32_t AV1Level21 = 0x2;
constexpr int32_t AV1Level22 = 0x4;
@@ -182,12 +394,53 @@
constexpr int32_t AV1Level72 = 0x400000;
constexpr int32_t AV1Level73 = 0x800000;
+inline static const char *asString_AV1Level(int32_t i, const char *def = "??") {
+ switch (i) {
+ case AV1Level2: return "2";
+ case AV1Level21: return "2.1";
+ case AV1Level22: return "2.2";
+ case AV1Level23: return "2.3";
+ case AV1Level3: return "3";
+ case AV1Level31: return "3.1";
+ case AV1Level32: return "3.2";
+ case AV1Level33: return "3.3";
+ case AV1Level4: return "4";
+ case AV1Level41: return "4.1";
+ case AV1Level42: return "4.2";
+ case AV1Level43: return "4.3";
+ case AV1Level5: return "5";
+ case AV1Level51: return "5.1";
+ case AV1Level52: return "5.2";
+ case AV1Level53: return "5.3";
+ case AV1Level6: return "6";
+ case AV1Level61: return "6.1";
+ case AV1Level62: return "6.2";
+ case AV1Level63: return "6.3";
+ case AV1Level7: return "7";
+ case AV1Level71: return "7.1";
+ case AV1Level72: return "7.2";
+ case AV1Level73: return "7.3";
+ default: return def;
+ }
+}
+
constexpr int32_t HEVCProfileMain = 0x01;
constexpr int32_t HEVCProfileMain10 = 0x02;
constexpr int32_t HEVCProfileMainStill = 0x04;
constexpr int32_t HEVCProfileMain10HDR10 = 0x1000;
constexpr int32_t HEVCProfileMain10HDR10Plus = 0x2000;
+inline static const char *asString_HEVCProfile(int32_t i, const char *def = "??") {
+ switch (i) {
+ case HEVCProfileMain: return "Main";
+ case HEVCProfileMain10: return "Main10";
+ case HEVCProfileMainStill: return "MainStill";
+ case HEVCProfileMain10HDR10: return "Main10HDR10";
+ case HEVCProfileMain10HDR10Plus: return "Main10HDR10Plus";
+ default: return def;
+ }
+}
+
constexpr int32_t HEVCMainTierLevel1 = 0x1;
constexpr int32_t HEVCHighTierLevel1 = 0x2;
constexpr int32_t HEVCMainTierLevel2 = 0x4;
@@ -215,6 +468,38 @@
constexpr int32_t HEVCMainTierLevel62 = 0x1000000;
constexpr int32_t HEVCHighTierLevel62 = 0x2000000;
+inline static const char *asString_HEVCTierLevel(int32_t i, const char *def = "??") {
+ switch (i) {
+ case HEVCMainTierLevel1: return "Main 1";
+ case HEVCHighTierLevel1: return "High 1";
+ case HEVCMainTierLevel2: return "Main 2";
+ case HEVCHighTierLevel2: return "High 2";
+ case HEVCMainTierLevel21: return "Main 2.1";
+ case HEVCHighTierLevel21: return "High 2.1";
+ case HEVCMainTierLevel3: return "Main 3";
+ case HEVCHighTierLevel3: return "High 3";
+ case HEVCMainTierLevel31: return "Main 3.1";
+ case HEVCHighTierLevel31: return "High 3.1";
+ case HEVCMainTierLevel4: return "Main 4";
+ case HEVCHighTierLevel4: return "High 4";
+ case HEVCMainTierLevel41: return "Main 4.1";
+ case HEVCHighTierLevel41: return "High 4.1";
+ case HEVCMainTierLevel5: return "Main 5";
+ case HEVCHighTierLevel5: return "High 5";
+ case HEVCMainTierLevel51: return "Main 5.1";
+ case HEVCHighTierLevel51: return "High 5.1";
+ case HEVCMainTierLevel52: return "Main 5.2";
+ case HEVCHighTierLevel52: return "High 5.2";
+ case HEVCMainTierLevel6: return "Main 6";
+ case HEVCHighTierLevel6: return "High 6";
+ case HEVCMainTierLevel61: return "Main 6.1";
+ case HEVCHighTierLevel61: return "High 6.1";
+ case HEVCMainTierLevel62: return "Main 6.2";
+ case HEVCHighTierLevel62: return "High 6.2";
+ default: return def;
+ }
+}
+
constexpr int32_t DolbyVisionProfileDvavPer = 0x1;
constexpr int32_t DolbyVisionProfileDvavPen = 0x2;
constexpr int32_t DolbyVisionProfileDvheDer = 0x4;
@@ -226,6 +511,22 @@
constexpr int32_t DolbyVisionProfileDvheSt = 0x100;
constexpr int32_t DolbyVisionProfileDvavSe = 0x200;
+inline static const char *asString_DolbyVisionProfile(int32_t i, const char *def = "??") {
+ switch (i) {
+ case DolbyVisionProfileDvavPer: return "DvavPer";
+ case DolbyVisionProfileDvavPen: return "DvavPen";
+ case DolbyVisionProfileDvheDer: return "DvheDer";
+ case DolbyVisionProfileDvheDen: return "DvheDen";
+ case DolbyVisionProfileDvheDtr: return "DvheDtr";
+ case DolbyVisionProfileDvheStn: return "DvheStn";
+ case DolbyVisionProfileDvheDth: return "DvheDth";
+ case DolbyVisionProfileDvheDtb: return "DvheDtb";
+ case DolbyVisionProfileDvheSt: return "DvheSt";
+ case DolbyVisionProfileDvavSe: return "DvavSe";
+ default: return def;
+ }
+}
+
constexpr int32_t DolbyVisionLevelHd24 = 0x1;
constexpr int32_t DolbyVisionLevelHd30 = 0x2;
constexpr int32_t DolbyVisionLevelFhd24 = 0x4;
@@ -236,10 +537,34 @@
constexpr int32_t DolbyVisionLevelUhd48 = 0x80;
constexpr int32_t DolbyVisionLevelUhd60 = 0x100;
+inline static const char *asString_DolbyVisionLevel(int32_t i, const char *def = "??") {
+ switch (i) {
+ case DolbyVisionLevelHd24: return "Hd24";
+ case DolbyVisionLevelHd30: return "Hd30";
+ case DolbyVisionLevelFhd24: return "Fhd24";
+ case DolbyVisionLevelFhd30: return "Fhd30";
+ case DolbyVisionLevelFhd60: return "Fhd60";
+ case DolbyVisionLevelUhd24: return "Uhd24";
+ case DolbyVisionLevelUhd30: return "Uhd30";
+ case DolbyVisionLevelUhd48: return "Uhd48";
+ case DolbyVisionLevelUhd60: return "Uhd60";
+ default: return def;
+ }
+}
+
constexpr int32_t BITRATE_MODE_CBR = 2;
constexpr int32_t BITRATE_MODE_CQ = 0;
constexpr int32_t BITRATE_MODE_VBR = 1;
+inline static const char *asString_BitrateMode(int32_t i, const char *def = "??") {
+ switch (i) {
+ case BITRATE_MODE_CBR: return "CBR";
+ case BITRATE_MODE_CQ: return "CQ";
+ case BITRATE_MODE_VBR: return "VBR";
+ default: return def;
+ }
+}
+
constexpr int32_t COLOR_Format12bitRGB444 = 3;
constexpr int32_t COLOR_Format16bitARGB1555 = 5;
constexpr int32_t COLOR_Format16bitARGB4444 = 4;
@@ -293,6 +618,64 @@
constexpr int32_t COLOR_QCOM_FormatYUV420SemiPlanar = 0x7fa30c00;
constexpr int32_t COLOR_TI_FormatYUV420PackedSemiPlanar = 0x7f000100;
+inline static const char *asString_ColorFormat(int32_t i, const char *def = "??") {
+ switch (i) {
+ case COLOR_Format12bitRGB444: return "12bitRGB444";
+ case COLOR_Format16bitARGB1555: return "16bitARGB1555";
+ case COLOR_Format16bitARGB4444: return "16bitARGB4444";
+ case COLOR_Format16bitBGR565: return "16bitBGR565";
+ case COLOR_Format16bitRGB565: return "16bitRGB565";
+ case COLOR_Format18bitARGB1665: return "18bitARGB1665";
+ case COLOR_Format18BitBGR666: return "18BitBGR666";
+ case COLOR_Format18bitRGB666: return "18bitRGB666";
+ case COLOR_Format19bitARGB1666: return "19bitARGB1666";
+ case COLOR_Format24BitABGR6666: return "24BitABGR6666";
+ case COLOR_Format24bitARGB1887: return "24bitARGB1887";
+ case COLOR_Format24BitARGB6666: return "24BitARGB6666";
+ case COLOR_Format24bitBGR888: return "24bitBGR888";
+ case COLOR_Format24bitRGB888: return "24bitRGB888";
+ case COLOR_Format25bitARGB1888: return "25bitARGB1888";
+ case COLOR_Format32bitABGR8888: return "32bitABGR8888";
+ case COLOR_Format32bitARGB8888: return "32bitARGB8888";
+ case COLOR_Format32bitBGRA8888: return "32bitBGRA8888";
+ case COLOR_Format8bitRGB332: return "8bitRGB332";
+ case COLOR_FormatCbYCrY: return "CbYCrY";
+ case COLOR_FormatCrYCbY: return "CrYCbY";
+ case COLOR_FormatL16: return "L16";
+ case COLOR_FormatL2: return "L2";
+ case COLOR_FormatL24: return "L24";
+ case COLOR_FormatL32: return "L32";
+ case COLOR_FormatL4: return "L4";
+ case COLOR_FormatL8: return "L8";
+ case COLOR_FormatMonochrome: return "Monochrome";
+ case COLOR_FormatRawBayer10bit: return "RawBayer10bit";
+ case COLOR_FormatRawBayer8bit: return "RawBayer8bit";
+ case COLOR_FormatRawBayer8bitcompressed: return "RawBayer8bitcompressed";
+ case COLOR_FormatRGBAFlexible: return "RGBAFlexible";
+ case COLOR_FormatRGBFlexible: return "RGBFlexible";
+ case COLOR_FormatSurface: return "Surface";
+ case COLOR_FormatYCbYCr: return "YCbYCr";
+ case COLOR_FormatYCrYCb: return "YCrYCb";
+ case COLOR_FormatYUV411PackedPlanar: return "YUV411PackedPlanar";
+ case COLOR_FormatYUV411Planar: return "YUV411Planar";
+ case COLOR_FormatYUV420Flexible: return "YUV420Flexible";
+ case COLOR_FormatYUV420PackedPlanar: return "YUV420PackedPlanar";
+ case COLOR_FormatYUV420PackedSemiPlanar: return "YUV420PackedSemiPlanar";
+ case COLOR_FormatYUV420Planar: return "YUV420Planar";
+ case COLOR_FormatYUV420SemiPlanar: return "YUV420SemiPlanar";
+ case COLOR_FormatYUV422Flexible: return "YUV422Flexible";
+ case COLOR_FormatYUV422PackedPlanar: return "YUV422PackedPlanar";
+ case COLOR_FormatYUV422PackedSemiPlanar: return "YUV422PackedSemiPlanar";
+ case COLOR_FormatYUV422Planar: return "YUV422Planar";
+ case COLOR_FormatYUV422SemiPlanar: return "YUV422SemiPlanar";
+ case COLOR_FormatYUV444Flexible: return "YUV444Flexible";
+ case COLOR_FormatYUV444Interleaved: return "YUV444Interleaved";
+ case COLOR_QCOM_FormatYUV420SemiPlanar: return "QCOM_YUV420SemiPlanar";
+ case COLOR_TI_FormatYUV420PackedSemiPlanar: return "TI_YUV420PackedSemiPlanar";
+ default: return def;
+ }
+}
+
constexpr char FEATURE_AdaptivePlayback[] = "adaptive-playback";
constexpr char FEATURE_IntraRefresh[] = "intra-refresh";
constexpr char FEATURE_PartialFrame[] = "partial-frame";
diff --git a/media/libstagefright/include/media/stagefright/MediaErrors.h b/media/libstagefright/include/media/stagefright/MediaErrors.h
index 6a5c6b6..09639e2 100644
--- a/media/libstagefright/include/media/stagefright/MediaErrors.h
+++ b/media/libstagefright/include/media/stagefright/MediaErrors.h
@@ -70,7 +70,12 @@
ERROR_DRM_DEVICE_REVOKED = DRM_ERROR_BASE - 9,
ERROR_DRM_RESOURCE_BUSY = DRM_ERROR_BASE - 10,
ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION = DRM_ERROR_BASE - 11,
- ERROR_DRM_LAST_USED_ERRORCODE = DRM_ERROR_BASE - 11,
+ ERROR_DRM_INSUFFICIENT_SECURITY = DRM_ERROR_BASE - 12,
+ ERROR_DRM_FRAME_TOO_LARGE = DRM_ERROR_BASE - 13,
+ ERROR_DRM_RESOURCE_CONTENTION = DRM_ERROR_BASE - 14,
+ ERROR_DRM_SESSION_LOST_STATE = DRM_ERROR_BASE - 15,
+ ERROR_DRM_INVALID_STATE = DRM_ERROR_BASE - 16,
+ ERROR_DRM_LAST_USED_ERRORCODE = DRM_ERROR_BASE - 16,
ERROR_DRM_VENDOR_MAX = DRM_ERROR_BASE - 500,
ERROR_DRM_VENDOR_MIN = DRM_ERROR_BASE - 999,
diff --git a/media/libmediaextractor/include/media/MediaSource.h b/media/libstagefright/include/media/stagefright/MediaSource.h
similarity index 100%
rename from media/libmediaextractor/include/media/MediaSource.h
rename to media/libstagefright/include/media/stagefright/MediaSource.h
diff --git a/media/libstagefright/include/media/stagefright/MetaData.h b/media/libstagefright/include/media/stagefright/MetaData.h
deleted file mode 120000
index 160f8d3..0000000
--- a/media/libstagefright/include/media/stagefright/MetaData.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../../libmediaextractor/include/media/stagefright/MetaData.h
\ No newline at end of file
diff --git a/media/libmediaextractor/include/media/stagefright/MetaData.h b/media/libstagefright/include/media/stagefright/MetaData.h
similarity index 100%
rename from media/libmediaextractor/include/media/stagefright/MetaData.h
rename to media/libstagefright/include/media/stagefright/MetaData.h
diff --git a/media/libstagefright/include/media/stagefright/MetaDataBase.h b/media/libstagefright/include/media/stagefright/MetaDataBase.h
deleted file mode 120000
index 1e12193..0000000
--- a/media/libstagefright/include/media/stagefright/MetaDataBase.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../../libmediaextractor/include/media/stagefright/MetaDataBase.h
\ No newline at end of file
diff --git a/media/libmediaextractor/include/media/stagefright/MetaDataBase.h b/media/libstagefright/include/media/stagefright/MetaDataBase.h
similarity index 100%
rename from media/libmediaextractor/include/media/stagefright/MetaDataBase.h
rename to media/libstagefright/include/media/stagefright/MetaDataBase.h
diff --git a/media/libstagefright/include/media/stagefright/NuMediaExtractor.h b/media/libstagefright/include/media/stagefright/NuMediaExtractor.h
index 8dc8d38..f34f9b6 100644
--- a/media/libstagefright/include/media/stagefright/NuMediaExtractor.h
+++ b/media/libstagefright/include/media/stagefright/NuMediaExtractor.h
@@ -96,8 +96,7 @@
bool getCachedDuration(int64_t *durationUs, bool *eos) const;
- status_t getAudioPresentations(size_t trackIdx,
- AudioPresentationCollection *presentations) const;
+ status_t getAudioPresentations(size_t trackIdx, AudioPresentationCollection *presentations);
protected:
virtual ~NuMediaExtractor();
diff --git a/media/libstagefright/include/media/stagefright/VideoFrameScheduler2.h b/media/libstagefright/include/media/stagefright/VideoFrameScheduler2.h
index be911cc..891b9a0 100644
--- a/media/libstagefright/include/media/stagefright/VideoFrameScheduler2.h
+++ b/media/libstagefright/include/media/stagefright/VideoFrameScheduler2.h
@@ -34,8 +34,8 @@
private:
void updateVsync() override;
- long mAppVsyncOffset;
- long mSfVsyncOffset;
+ nsecs_t mAppVsyncOffset;
+ nsecs_t mSfVsyncOffset;
sp<VsyncTracker> mVsyncTracker;
sp<ChoreographerThread> mChoreographerThread;
Mutex mLock;
diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp
index 345f85d..1482072 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.cpp
+++ b/media/libstagefright/mpeg2ts/ATSParser.cpp
@@ -217,6 +217,9 @@
sp<IDescrambler> mDescrambler;
AudioPresentationCollection mAudioPresentations;
+ // Send audio presentations along with access units.
+ void addAudioPresentations(const sp<ABuffer> &buffer);
+
// Flush accumulated payload if necessary --- i.e. at EOS or at the start of
// another payload. event is set if the flushed payload is PES with a sync
// frame.
@@ -758,21 +761,21 @@
// reasonable amount of time. To handle the wrap-around, use fancy math
// to get an extended PTS that is within [-0xffffffff, 0xffffffff]
// of the latest recovered PTS.
- if (mLastRecoveredPTS < 0ll) {
+ if (mLastRecoveredPTS < 0LL) {
// Use the original 33bit number for 1st frame, the reason is that
// if 1st frame wraps to negative that's far away from 0, we could
// never start. Only start wrapping around from 2nd frame.
mLastRecoveredPTS = static_cast<int64_t>(PTS_33bit);
} else {
mLastRecoveredPTS = static_cast<int64_t>(
- ((mLastRecoveredPTS - static_cast<int64_t>(PTS_33bit) + 0x100000000ll)
+ ((mLastRecoveredPTS - static_cast<int64_t>(PTS_33bit) + 0x100000000LL)
& 0xfffffffe00000000ull) | PTS_33bit);
// We start from 0, but recovered PTS could be slightly below 0.
// Clamp it to 0 as rest of the pipeline doesn't take negative pts.
// (eg. video is read first and starts at 0, but audio starts at 0xfffffff0)
- if (mLastRecoveredPTS < 0ll) {
+ if (mLastRecoveredPTS < 0LL) {
ALOGI("Clamping negative recovered PTS (%" PRId64 ") to 0", mLastRecoveredPTS);
- mLastRecoveredPTS = 0ll;
+ mLastRecoveredPTS = 0LL;
}
}
@@ -822,7 +825,7 @@
int64_t timeUs = (PTS * 100) / 9;
- if (mParser->mAbsoluteTimeAnchorUs >= 0ll) {
+ if (mParser->mAbsoluteTimeAnchorUs >= 0LL) {
timeUs += mParser->mAbsoluteTimeAnchorUs;
}
@@ -1708,6 +1711,13 @@
return err;
}
+void ATSParser::Stream::addAudioPresentations(const sp<ABuffer> &buffer) {
+ std::ostringstream outStream(std::ios::out);
+ serializeAudioPresentations(mAudioPresentations, &outStream);
+ sp<ABuffer> ap = ABuffer::CreateAsCopy(outStream.str().data(), outStream.str().size());
+ buffer->meta()->setBuffer("audio-presentation-info", ap);
+}
+
void ATSParser::Stream::onPayloadData(
unsigned PTS_DTS_flags, uint64_t PTS, uint64_t /* DTS */,
unsigned PES_scrambling_control,
@@ -1723,7 +1733,7 @@
ALOGV("onPayloadData mStreamType=0x%02x size: %zu", mStreamType, size);
- int64_t timeUs = 0ll; // no presentation timestamp available.
+ int64_t timeUs = 0LL; // no presentation timestamp available.
if (PTS_DTS_flags == 2 || PTS_DTS_flags == 3) {
timeUs = mProgram->convertPTSToTimestamp(PTS);
}
@@ -1758,8 +1768,10 @@
}
}
mSource = new AnotherPacketSource(meta);
+ if (mAudioPresentations.size() > 0) {
+ addAudioPresentations(accessUnit);
+ }
mSource->queueAccessUnit(accessUnit);
- mSource->convertAudioPresentationInfoToMetadata(mAudioPresentations);
ALOGV("onPayloadData: created AnotherPacketSource PID 0x%08x of type 0x%02x",
mElementaryPID, mStreamType);
}
@@ -1771,8 +1783,10 @@
if (mSource->getFormat() == NULL) {
mSource->setFormat(mQueue->getFormat());
}
+ if (mAudioPresentations.size() > 0) {
+ addAudioPresentations(accessUnit);
+ }
mSource->queueAccessUnit(accessUnit);
- mSource->convertAudioPresentationInfoToMetadata(mAudioPresentations);
}
// Every access unit has a pesStartOffset queued in |mPesStartOffsets|.
@@ -1855,10 +1869,10 @@
ATSParser::ATSParser(uint32_t flags)
: mFlags(flags),
- mAbsoluteTimeAnchorUs(-1ll),
+ mAbsoluteTimeAnchorUs(-1LL),
mTimeOffsetValid(false),
- mTimeOffsetUs(0ll),
- mLastRecoveredPTS(-1ll),
+ mTimeOffsetUs(0LL),
+ mLastRecoveredPTS(-1LL),
mNumTSPacketsParsed(0),
mNumPCRs(0) {
mPSISections.add(0 /* PID */, new PSISection);
@@ -1900,7 +1914,7 @@
if ((mFlags & TS_TIMESTAMPS_ARE_ABSOLUTE)
&& extra->findInt64(
kATSParserKeyRecentMediaTimeUs, &mediaTimeUs)) {
- if (mAbsoluteTimeAnchorUs >= 0ll) {
+ if (mAbsoluteTimeAnchorUs >= 0LL) {
mediaTimeUs -= mAbsoluteTimeAnchorUs;
}
if (mTimeOffsetValid) {
diff --git a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
index e2c5031..62e3a4b 100644
--- a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
+++ b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
@@ -35,7 +35,7 @@
namespace android {
-const int64_t kNearEOSMarkUs = 2000000ll; // 2 secs
+const int64_t kNearEOSMarkUs = 2000000LL; // 2 secs
AnotherPacketSource::AnotherPacketSource(const sp<MetaData> &meta)
: mIsAudio(false),
@@ -223,6 +223,12 @@
kKeyMpegUserData, 0, mpegUserData->data(), mpegUserData->size());
}
+ sp<ABuffer> ap;
+ if (buffer->meta()->findBuffer("audio-presentation-info", &ap) && ap != NULL) {
+ bufmeta.setData(
+ kKeyAudioPresentationInfo, 0, ap->data(), ap->size());
+ }
+
int32_t cryptoMode;
if (buffer->meta()->findInt32("cryptoMode", &cryptoMode)) {
int32_t cryptoKey;
@@ -293,7 +299,7 @@
if (buffer->meta()->findInt32("discontinuity", &discontinuity)){
ALOGV("queueing a discontinuity with queueAccessUnit");
- mLastQueuedTimeUs = 0ll;
+ mLastQueuedTimeUs = 0LL;
mEOSResult = OK;
mLatestEnqueuedMeta = NULL;
@@ -697,23 +703,4 @@
return firstMeta;
}
-void AnotherPacketSource::convertAudioPresentationInfoToMetadata(
- const AudioPresentationCollection& presentations) {
- sp<MetaData> meta = getFormat();
- if (meta == NULL) {
- return;
- }
- if (presentations.empty()) {
- // Clear audio presentation info in metadata.
- Mutex::Autolock autoLock(mLock);
- meta->remove(kKeyAudioPresentationInfo);
- } else {
- std::ostringstream outStream(std::ios::out);
- serializeAudioPresentations(presentations, &outStream);
- Mutex::Autolock autoLock(mLock);
- meta->setData(kKeyAudioPresentationInfo, MetaData::TYPE_NONE,
- outStream.str().data(), outStream.str().size());
- }
-}
-
} // namespace android
diff --git a/media/libstagefright/mpeg2ts/AnotherPacketSource.h b/media/libstagefright/mpeg2ts/AnotherPacketSource.h
index 57a6c33..f4a6acb 100644
--- a/media/libstagefright/mpeg2ts/AnotherPacketSource.h
+++ b/media/libstagefright/mpeg2ts/AnotherPacketSource.h
@@ -85,8 +85,6 @@
void trimBuffersAfterMeta(const sp<AMessage> &meta);
sp<AMessage> trimBuffersBeforeMeta(const sp<AMessage> &meta);
- void convertAudioPresentationInfoToMetadata(const AudioPresentationCollection &presentations);
-
protected:
virtual ~AnotherPacketSource();
diff --git a/media/libstagefright/mpeg2ts/ESQueue.cpp b/media/libstagefright/mpeg2ts/ESQueue.cpp
index fb8b9fd..b91edcd 100644
--- a/media/libstagefright/mpeg2ts/ESQueue.cpp
+++ b/media/libstagefright/mpeg2ts/ESQueue.cpp
@@ -1111,7 +1111,7 @@
memcpy(accessUnit->data(), mBuffer->data() + 4, payloadSize);
int64_t timeUs = fetchTimestamp(payloadSize + 4);
- if (timeUs < 0ll) {
+ if (timeUs < 0LL) {
ALOGE("Negative timeUs");
return NULL;
}
@@ -1147,7 +1147,7 @@
return NULL;
}
- if (info.mTimestampUs < 0ll) {
+ if (info.mTimestampUs < 0LL) {
ALOGE("Negative info.mTimestampUs");
return NULL;
}
@@ -1317,7 +1317,7 @@
}
- if (timeUs == 0ll) {
+ if (timeUs == 0LL) {
ALOGV("Returning 0 timestamp");
}
@@ -1460,7 +1460,7 @@
mBuffer->setRange(0, mBuffer->size() - nextScan);
int64_t timeUs = fetchTimestamp(nextScan);
- if (timeUs < 0ll) {
+ if (timeUs < 0LL) {
ALOGE("Negative timeUs");
return NULL;
}
@@ -1545,7 +1545,7 @@
mBuffer->setRange(0, mBuffer->size() - frameSize);
int64_t timeUs = fetchTimestamp(frameSize);
- if (timeUs < 0ll) {
+ if (timeUs < 0LL) {
ALOGE("Negative timeUs");
return NULL;
}
@@ -1732,7 +1732,7 @@
mBuffer->setRange(0, mBuffer->size() - offset);
int64_t timeUs = fetchTimestamp(offset);
- if (timeUs < 0ll) {
+ if (timeUs < 0LL) {
ALOGE("Negative timeUs");
return NULL;
}
@@ -1929,7 +1929,7 @@
mBuffer->setRange(0, size);
int64_t timeUs = fetchTimestamp(offset);
- if (timeUs < 0ll) {
+ if (timeUs < 0LL) {
ALOGE("Negative timeus");
return NULL;
}
diff --git a/media/libstagefright/omx/1.0/Omx.cpp b/media/libstagefright/omx/1.0/Omx.cpp
index 4e2d398..121bb1a 100644
--- a/media/libstagefright/omx/1.0/Omx.cpp
+++ b/media/libstagefright/omx/1.0/Omx.cpp
@@ -124,11 +124,11 @@
} else {
uint32_t quirks = 0;
for (const auto& quirk : codec->second.quirkSet) {
- if (quirk == "requires-allocate-on-input-ports") {
+ if (quirk == "quirk::requires-allocate-on-input-ports") {
quirks |= OMXNodeInstance::
kRequiresAllocateBufferOnInputPorts;
}
- if (quirk == "requires-allocate-on-output-ports") {
+ if (quirk == "quirk::requires-allocate-on-output-ports") {
quirks |= OMXNodeInstance::
kRequiresAllocateBufferOnOutputPorts;
}
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index 68b375a..d7aacff 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -355,9 +355,9 @@
mQuirks(0),
mBufferIDCount(0),
mRestorePtsFailed(false),
- mMaxTimestampGapUs(0ll),
- mPrevOriginalTimeUs(-1ll),
- mPrevModifiedTimeUs(-1ll)
+ mMaxTimestampGapUs(0LL),
+ mPrevOriginalTimeUs(-1LL),
+ mPrevModifiedTimeUs(-1LL)
{
mName = ADebug::GetDebugName(name);
DEBUG = ADebug::GetDebugLevelFromProperty(name, "debug.stagefright.omx-debug");
@@ -1948,7 +1948,7 @@
int64_t OMXNodeInstance::getCodecTimestamp(OMX_TICKS timestamp) {
int64_t originalTimeUs = timestamp;
- if (mMaxTimestampGapUs > 0ll) {
+ if (mMaxTimestampGapUs > 0LL) {
/* Cap timestamp gap between adjacent frames to specified max
*
* In the scenario of cast mirroring, encoding could be suspended for
@@ -1956,7 +1956,7 @@
* where encoder's rate control logic produces huge frames after a
* long period of suspension.
*/
- if (mPrevOriginalTimeUs >= 0ll) {
+ if (mPrevOriginalTimeUs >= 0LL) {
int64_t timestampGapUs = originalTimeUs - mPrevOriginalTimeUs;
timestamp = (timestampGapUs < mMaxTimestampGapUs ?
timestampGapUs : mMaxTimestampGapUs) + mPrevModifiedTimeUs;
@@ -1964,7 +1964,7 @@
ALOGV("IN timestamp: %lld -> %lld",
static_cast<long long>(originalTimeUs),
static_cast<long long>(timestamp));
- } else if (mMaxTimestampGapUs < 0ll) {
+ } else if (mMaxTimestampGapUs < 0LL) {
/*
* Apply a fixed timestamp gap between adjacent frames.
*
@@ -1972,7 +1972,7 @@
* on frames could go forward or backward. Some encoders may silently
* drop frames when it goes backward (or even stay unchanged).
*/
- if (mPrevOriginalTimeUs >= 0ll) {
+ if (mPrevOriginalTimeUs >= 0LL) {
timestamp = mPrevModifiedTimeUs - mMaxTimestampGapUs;
}
ALOGV("IN timestamp: %lld -> %lld",
@@ -1983,7 +1983,7 @@
mPrevOriginalTimeUs = originalTimeUs;
mPrevModifiedTimeUs = timestamp;
- if (mMaxTimestampGapUs != 0ll && !mRestorePtsFailed) {
+ if (mMaxTimestampGapUs != 0LL && !mRestorePtsFailed) {
mOriginalTimeUs.add(timestamp, originalTimeUs);
}
@@ -2016,7 +2016,7 @@
void OMXNodeInstance::codecBufferFilled(omx_message &msg) {
Mutex::Autolock autoLock(mLock);
- if (mMaxTimestampGapUs == 0ll || mRestorePtsFailed) {
+ if (mMaxTimestampGapUs == 0LL || mRestorePtsFailed) {
return;
}
diff --git a/media/libstagefright/omx/tests/Android.bp b/media/libstagefright/omx/tests/Android.bp
index 31bc837..fb03229 100644
--- a/media/libstagefright/omx/tests/Android.bp
+++ b/media/libstagefright/omx/tests/Android.bp
@@ -9,7 +9,6 @@
"libbinder",
"libmedia",
"libmedia_omx",
- "libmediaextractor",
"libutils",
"liblog",
"libstagefright_foundation",
diff --git a/media/libstagefright/rtsp/APacketSource.cpp b/media/libstagefright/rtsp/APacketSource.cpp
index 201a5df..b964bc0 100644
--- a/media/libstagefright/rtsp/APacketSource.cpp
+++ b/media/libstagefright/rtsp/APacketSource.cpp
@@ -417,7 +417,7 @@
if (sessionDesc->getDurationUs(&durationUs)) {
mFormat->setInt64(kKeyDuration, durationUs);
} else {
- mFormat->setInt64(kKeyDuration, -1ll);
+ mFormat->setInt64(kKeyDuration, -1LL);
}
mInitCheck = OK;
diff --git a/media/libstagefright/rtsp/ARTPAssembler.cpp b/media/libstagefright/rtsp/ARTPAssembler.cpp
index c7a65c2..befc226 100644
--- a/media/libstagefright/rtsp/ARTPAssembler.cpp
+++ b/media/libstagefright/rtsp/ARTPAssembler.cpp
@@ -36,7 +36,7 @@
if (status == WRONG_SEQUENCE_NUMBER) {
if (mFirstFailureTimeUs >= 0) {
- if (ALooper::GetNowUs() - mFirstFailureTimeUs > 10000ll) {
+ if (ALooper::GetNowUs() - mFirstFailureTimeUs > 10000LL) {
mFirstFailureTimeUs = -1;
// LOG(VERBOSE) << "waited too long for packet.";
diff --git a/media/libstagefright/rtsp/ARTPConnection.cpp b/media/libstagefright/rtsp/ARTPConnection.cpp
index a86ab74..6a4706d 100644
--- a/media/libstagefright/rtsp/ARTPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTPConnection.cpp
@@ -50,7 +50,7 @@
}
// static
-const int64_t ARTPConnection::kSelectTimeoutUs = 1000ll;
+const int64_t ARTPConnection::kSelectTimeoutUs = 1000LL;
struct ARTPConnection::StreamInfo {
int mRTPSocket;
@@ -118,7 +118,7 @@
bumpSocketBufferSize(*rtcpSocket);
/* rand() * 1000 may overflow int type, use long long */
- unsigned start = (unsigned)((rand()* 1000ll)/RAND_MAX) + 15550;
+ unsigned start = (unsigned)((rand()* 1000LL)/RAND_MAX) + 15550;
start &= ~1;
for (unsigned port = start; port < 65536; port += 2) {
@@ -307,7 +307,7 @@
int64_t nowUs = ALooper::GetNowUs();
if (mLastReceiverReportTimeUs <= 0
- || mLastReceiverReportTimeUs + 5000000ll <= nowUs) {
+ || mLastReceiverReportTimeUs + 5000000LL <= nowUs) {
sp<ABuffer> buffer = new ABuffer(kMaxUDPSize);
List<StreamInfo>::iterator it = mStreams.begin();
while (it != mStreams.end()) {
diff --git a/media/libstagefright/rtsp/ARTPSource.cpp b/media/libstagefright/rtsp/ARTPSource.cpp
index 4827cd2..4afa6f4 100644
--- a/media/libstagefright/rtsp/ARTPSource.cpp
+++ b/media/libstagefright/rtsp/ARTPSource.cpp
@@ -180,7 +180,7 @@
}
int64_t nowUs = ALooper::GetNowUs();
- if (mLastFIRRequestUs >= 0 && mLastFIRRequestUs + 5000000ll > nowUs) {
+ if (mLastFIRRequestUs >= 0 && mLastFIRRequestUs + 5000000LL > nowUs) {
// Send FIR requests at most every 5 secs.
return;
}
diff --git a/media/libstagefright/rtsp/ARTPWriter.cpp b/media/libstagefright/rtsp/ARTPWriter.cpp
index 49e01c0..4f86773 100644
--- a/media/libstagefright/rtsp/ARTPWriter.cpp
+++ b/media/libstagefright/rtsp/ARTPWriter.cpp
@@ -420,10 +420,10 @@
uint64_t ARTPWriter::GetNowNTP() {
uint64_t nowUs = ALooper::GetNowUs();
- nowUs += ((70ll * 365 + 17) * 24) * 60 * 60 * 1000000ll;
+ nowUs += ((70LL * 365 + 17) * 24) * 60 * 60 * 1000000LL;
- uint64_t hi = nowUs / 1000000ll;
- uint64_t lo = ((1ll << 32) * (nowUs % 1000000ll)) / 1000000ll;
+ uint64_t hi = nowUs / 1000000LL;
+ uint64_t lo = ((1LL << 32) * (nowUs % 1000000LL)) / 1000000LL;
return (hi << 32) | lo;
}
@@ -576,7 +576,7 @@
int64_t timeUs;
CHECK(mediaBuf->meta_data().findInt64(kKeyTime, &timeUs));
- uint32_t rtpTime = mRTPTimeBase + (timeUs * 9 / 100ll);
+ uint32_t rtpTime = mRTPTimeBase + (timeUs * 9 / 100LL);
const uint8_t *mediaData =
(const uint8_t *)mediaBuf->data() + mediaBuf->range_offset();
@@ -671,7 +671,7 @@
int64_t timeUs;
CHECK(mediaBuf->meta_data().findInt64(kKeyTime, &timeUs));
- uint32_t rtpTime = mRTPTimeBase + (timeUs * 9 / 100ll);
+ uint32_t rtpTime = mRTPTimeBase + (timeUs * 9 / 100LL);
const uint8_t *mediaData =
(const uint8_t *)mediaBuf->data() + mediaBuf->range_offset();
diff --git a/media/libstagefright/rtsp/ARTSPConnection.cpp b/media/libstagefright/rtsp/ARTSPConnection.cpp
index 33c1c18..20cb415 100644
--- a/media/libstagefright/rtsp/ARTSPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTSPConnection.cpp
@@ -39,7 +39,7 @@
namespace android {
// static
-const int64_t ARTSPConnection::kSelectTimeoutUs = 1000ll;
+const int64_t ARTSPConnection::kSelectTimeoutUs = 1000LL;
// static
const AString ARTSPConnection::sUserAgent =
diff --git a/media/libstagefright/webm/WebmFrameThread.cpp b/media/libstagefright/webm/WebmFrameThread.cpp
index 23269af..4b6f928 100644
--- a/media/libstagefright/webm/WebmFrameThread.cpp
+++ b/media/libstagefright/webm/WebmFrameThread.cpp
@@ -364,14 +364,14 @@
// adjust time-stamps after pause/resume
if (mResumed) {
int64_t durExcludingEarlierPausesUs = timestampUs - previousPausedDurationUs;
- CHECK_GE(durExcludingEarlierPausesUs, 0ll);
+ CHECK_GE(durExcludingEarlierPausesUs, 0LL);
int64_t pausedDurationUs = durExcludingEarlierPausesUs - mTrackDurationUs;
CHECK_GE(pausedDurationUs, lastDurationUs);
previousPausedDurationUs += pausedDurationUs - lastDurationUs;
mResumed = false;
}
timestampUs -= previousPausedDurationUs;
- CHECK_GE(timestampUs, 0ll);
+ CHECK_GE(timestampUs, 0LL);
int32_t isSync = false;
md.findInt32(kKeyIsSyncFrame, &isSync);
diff --git a/media/libstagefright/xmlparser/MediaCodecsXmlParser.cpp b/media/libstagefright/xmlparser/MediaCodecsXmlParser.cpp
index 2dec9fa..6e541ba 100644
--- a/media/libstagefright/xmlparser/MediaCodecsXmlParser.cpp
+++ b/media/libstagefright/xmlparser/MediaCodecsXmlParser.cpp
@@ -26,8 +26,9 @@
#include <sys/stat.h>
#include <expat.h>
-#include <cctype>
#include <algorithm>
+#include <cctype>
+#include <string>
namespace android {
@@ -326,8 +327,8 @@
case SECTION_DECODER:
case SECTION_ENCODER:
{
- if (strEq(name, "Quirk")) {
- (void)addQuirk(attrs);
+ if (strEq(name, "Quirk") || strEq(name, "Attribute")) {
+ (void)addQuirk(attrs, name);
} else if (strEq(name, "Type")) {
(void)addTypeFromAttributes(attrs,
(mCurrentSection == SECTION_ENCODER));
@@ -348,6 +349,8 @@
if (outside &&
(strEq(name, "Limit") || strEq(name, "Feature"))) {
ALOGW("ignoring %s specified outside of a Type", name);
+ } else if (strEq(name, "Alias")) {
+ (void)addAlias(attrs);
} else if (strEq(name, "Limit")) {
(void)addLimit(attrs);
} else if (strEq(name, "Feature")) {
@@ -579,7 +582,7 @@
return OK;
}
-status_t MediaCodecsXmlParser::addQuirk(const char **attrs) {
+status_t MediaCodecsXmlParser::addQuirk(const char **attrs, const char *tag) {
if (mCurrentCodec == mCodecMap.end()) {
return BAD_VALUE;
}
@@ -606,7 +609,12 @@
return BAD_VALUE;
}
- mCurrentCodec->second.quirkSet.emplace(name);
+ std::string tagString = tag;
+ std::transform(tagString.begin(), tagString.end(), tagString.begin(), ::tolower);
+ tagString.append("::");
+ tagString.append(name);
+ mCurrentCodec->second.quirkSet.emplace(tagString.c_str());
+ ALOGI("adding %s to %s", tagString.c_str(), mCurrentCodec->first.c_str());
return OK;
}
@@ -760,6 +768,7 @@
strEq(a_name, "quality") ||
strEq(a_name, "size") ||
strEq(a_name, "measured-blocks-per-second") ||
+ strHasPrefix(a_name, "performance-point-") ||
strHasPrefix(a_name, "measured-frame-rate-")) {
// "range" is specified in exactly one of the following forms:
// 1) min-max
@@ -964,6 +973,34 @@
return OK;
}
+status_t MediaCodecsXmlParser::addAlias(const char **attrs) {
+ size_t i = 0;
+ const char *name = nullptr;
+
+ while (attrs[i] != nullptr) {
+ if (strEq(attrs[i], "name")) {
+ if (attrs[++i] == nullptr) {
+ ALOGE("addAlias: name is null");
+ return BAD_VALUE;
+ }
+ name = attrs[i];
+ } else {
+ ALOGE("addAlias: unrecognized attribute: %s", attrs[i]);
+ return BAD_VALUE;
+ }
+ ++i;
+ }
+
+ // Every feature must have a name.
+ if (name == nullptr) {
+ ALOGE("alias with no 'name' attribute");
+ return BAD_VALUE;
+ }
+
+ mCurrentCodec->second.aliases.emplace_back(name);
+ return OK;
+}
+
const MediaCodecsXmlParser::AttributeMap&
MediaCodecsXmlParser::getServiceAttributeMap() const {
return mServiceAttributeMap;
@@ -1041,11 +1078,18 @@
NodeInfo nodeInfo;
nodeInfo.name = codecName;
+ // NOTE: no aliases are exposed in role info
+ // attribute quirks are exposed as node attributes
nodeInfo.attributeList.reserve(typeAttributeMap.size());
for (const auto& attribute : typeAttributeMap) {
nodeInfo.attributeList.push_back(
Attribute{attribute.first, attribute.second});
}
+ for (const std::string &quirk : codec.second.quirkSet) {
+ if (strHasPrefix(quirk.c_str(), "attribute::")) {
+ nodeInfo.attributeList.push_back(Attribute{quirk, "present"});
+ }
+ }
nodeList->insert(std::make_pair(
std::move(order), std::move(nodeInfo)));
}
diff --git a/media/libstagefright/xmlparser/include/media/stagefright/xmlparser/MediaCodecsXmlParser.h b/media/libstagefright/xmlparser/include/media/stagefright/xmlparser/MediaCodecsXmlParser.h
index cc69e52..fd949da 100644
--- a/media/libstagefright/xmlparser/include/media/stagefright/xmlparser/MediaCodecsXmlParser.h
+++ b/media/libstagefright/xmlparser/include/media/stagefright/xmlparser/MediaCodecsXmlParser.h
@@ -65,6 +65,7 @@
size_t order; ///< Order of appearance in the file (starting from 0)
QuirkSet quirkSet; ///< Set of quirks requested by this codec
TypeMap typeMap; ///< Map of types supported by this codec
+ std::vector<std::string> aliases; ///< Name aliases for this codec
};
typedef std::pair<std::string, CodecProperties> Codec;
@@ -76,6 +77,7 @@
struct NodeInfo {
std::string name;
std::vector<Attribute> attributeList;
+ // note: aliases are not exposed here as they are not part of the role map
};
/**
@@ -171,8 +173,9 @@
void addMediaCodec(bool encoder, const char *name,
const char *type = nullptr);
- status_t addQuirk(const char **attrs);
+ status_t addQuirk(const char **attrs, const char *tag);
status_t addTypeFromAttributes(const char **attrs, bool encoder);
+ status_t addAlias(const char **attrs);
status_t addLimit(const char **attrs);
status_t addFeature(const char **attrs);
void addType(const char *name);
diff --git a/media/ndk/Android.bp b/media/ndk/Android.bp
index 73bd2ca..74754ea 100644
--- a/media/ndk/Android.bp
+++ b/media/ndk/Android.bp
@@ -78,7 +78,6 @@
"libmedia_omx",
"libmedia_jni",
"libmediadrm",
- "libmediaextractor",
"libstagefright",
"libstagefright_foundation",
"libstagefright_bufferqueue_helper",
diff --git a/media/ndk/NdkMediaExtractor.cpp b/media/ndk/NdkMediaExtractor.cpp
index f697bd1..8296598 100644
--- a/media/ndk/NdkMediaExtractor.cpp
+++ b/media/ndk/NdkMediaExtractor.cpp
@@ -448,6 +448,16 @@
meta->setBuffer(AMEDIAFORMAT_KEY_MPEG_USER_DATA, mpegUserData);
}
+ const void *audioPresentationsPointer;
+ size_t audioPresentationsLength;
+ if (sampleMeta->findData(
+ kKeyAudioPresentationInfo, &dataType,
+ &audioPresentationsPointer, &audioPresentationsLength)) {
+ sp<ABuffer> audioPresentationsData = ABuffer::CreateAsCopy(
+ audioPresentationsPointer, audioPresentationsLength);
+ meta->setBuffer(AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_INFO, audioPresentationsData);
+ }
+
return AMEDIA_OK;
}
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index 538a0eb..63a9ec4 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -322,6 +322,13 @@
}
}
status = thread->sendCreateAudioPatchConfigEvent(patch, &halHandle);
+ // remove stale audio patch with same input as sink if any
+ for (auto& iter : mPatches) {
+ if (iter.second.mAudioPatch.sinks[0].ext.mix.handle == thread->id()) {
+ mPatches.erase(iter.first);
+ break;
+ }
+ }
} else {
sp<DeviceHalInterface> hwDevice = audioHwDevice->hwDevice();
status = hwDevice->createAudioPatch(patch->num_sources,
@@ -376,6 +383,14 @@
}
status = thread->sendCreateAudioPatchConfigEvent(patch, &halHandle);
+
+ // remove stale audio patch with same output as source if any
+ for (auto& iter : mPatches) {
+ if (iter.second.mAudioPatch.sources[0].ext.mix.handle == thread->id()) {
+ mPatches.erase(iter.first);
+ break;
+ }
+ }
} break;
default:
status = BAD_VALUE;
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index c6941c0..607d2d1 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -494,6 +494,8 @@
case AUDIO_SOURCE_VOICE_COMMUNICATION: return "voice communication";
case AUDIO_SOURCE_REMOTE_SUBMIX: return "remote submix";
case AUDIO_SOURCE_UNPROCESSED: return "unprocessed";
+ case AUDIO_SOURCE_VOICE_PERFORMANCE: return "voice performance";
+ case AUDIO_SOURCE_ECHO_REFERENCE: return "echo reference";
case AUDIO_SOURCE_FM_TUNER: return "FM tuner";
case AUDIO_SOURCE_HOTWORD: return "hotword";
default: return "unknown";
@@ -3850,6 +3852,7 @@
type |= patch->sinks[i].ext.device.type;
}
+ audio_port_handle_t sinkPortId = patch->sinks[0].id;
#ifdef ADD_BATTERY_DATA
// when changing the audio output device, call addBatteryData to notify
// the change
@@ -3879,7 +3882,7 @@
// mPrevOutDevice is the latest device set by createAudioPatch_l(). It is not set when
// the thread is created so that the first patch creation triggers an ioConfigChanged callback
- bool configChanged = mPrevOutDevice != type;
+ bool configChanged = (mPrevOutDevice != type) || (mDeviceId != sinkPortId);
mOutDevice = type;
mPatch = *patch;
@@ -3908,6 +3911,7 @@
}
if (configChanged) {
mPrevOutDevice = type;
+ mDeviceId = sinkPortId;
sendIoConfigEvent_l(AUDIO_OUTPUT_CONFIG_CHANGED);
}
return status;
@@ -8145,6 +8149,7 @@
// store new device and send to effects
mInDevice = patch->sources[0].ext.device.type;
+ audio_port_handle_t deviceId = patch->sources[0].id;
mPatch = *patch;
for (size_t i = 0; i < mEffectChains.size(); i++) {
mEffectChains[i]->setDevice_l(mInDevice);
@@ -8186,9 +8191,10 @@
*handle = AUDIO_PATCH_HANDLE_NONE;
}
- if (mInDevice != mPrevInDevice) {
+ if ((mInDevice != mPrevInDevice) || (mDeviceId != deviceId)) {
sendIoConfigEvent_l(AUDIO_INPUT_CONFIG_CHANGED);
mPrevInDevice = mInDevice;
+ mDeviceId = deviceId;
}
return status;
@@ -8285,7 +8291,7 @@
audio_devices_t outDevice, audio_devices_t inDevice, bool systemReady)
: ThreadBase(audioFlinger, id, outDevice, inDevice, MMAP, systemReady),
mSessionId(AUDIO_SESSION_NONE),
- mDeviceId(AUDIO_PORT_HANDLE_NONE), mPortId(AUDIO_PORT_HANDLE_NONE),
+ mPortId(AUDIO_PORT_HANDLE_NONE),
mHalStream(stream), mHalDevice(hwDev->hwDevice()), mAudioHwDev(hwDev),
mActiveTracks(&this->mLocalLog),
mHalVolFloat(-1.0f), // Initialize to illegal value so it always gets set properly later.
@@ -8769,7 +8775,7 @@
*handle = AUDIO_PATCH_HANDLE_NONE;
}
- if (isOutput() && mPrevOutDevice != mOutDevice) {
+ if (isOutput() && (mPrevOutDevice != mOutDevice || mDeviceId != deviceId)) {
mPrevOutDevice = type;
sendIoConfigEvent_l(AUDIO_OUTPUT_CONFIG_CHANGED);
sp<MmapStreamCallback> callback = mCallback.promote();
@@ -8780,7 +8786,7 @@
}
mDeviceId = deviceId;
}
- if (!isOutput() && mPrevInDevice != mInDevice) {
+ if (!isOutput() && (mPrevInDevice != mInDevice || mDeviceId != deviceId)) {
mPrevInDevice = type;
sendIoConfigEvent_l(AUDIO_INPUT_CONFIG_CHANGED);
sp<MmapStreamCallback> callback = mCallback.promote();
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index e8b2158..5d06773 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -485,6 +485,10 @@
audio_devices_t mPrevOutDevice; // previous output device
audio_devices_t mPrevInDevice; // previous input device
struct audio_patch mPatch;
+ /**
+ * @brief mDeviceId current device port unique identifier
+ */
+ audio_port_handle_t mDeviceId = AUDIO_PORT_HANDLE_NONE;
audio_source_t mAudioSource;
const audio_io_handle_t mId;
@@ -1704,7 +1708,6 @@
audio_attributes_t mAttr;
audio_session_t mSessionId;
- audio_port_handle_t mDeviceId;
audio_port_handle_t mPortId;
wp<MmapStreamCallback> mCallback;
diff --git a/services/audiopolicy/TEST_MAPPING b/services/audiopolicy/TEST_MAPPING
new file mode 100644
index 0000000..a94fd87
--- /dev/null
+++ b/services/audiopolicy/TEST_MAPPING
@@ -0,0 +1,10 @@
+{
+ "presubmit": [
+ {
+ "name": "audiopolicy_tests"
+ },
+ {
+ "name": "systemaudio_tests"
+ }
+ ]
+}
diff --git a/services/audiopolicy/common/include/policy.h b/services/audiopolicy/common/include/policy.h
index 30b0044..46a2a40 100644
--- a/services/audiopolicy/common/include/policy.h
+++ b/services/audiopolicy/common/include/policy.h
@@ -83,7 +83,10 @@
* @param[in] inputSource to consider. Valid sources are:
* - AUDIO_SOURCE_VOICE_COMMUNICATION
* - AUDIO_SOURCE_CAMCORDER
+ * - AUDIO_SOURCE_VOICE_PERFORMANCE
+ * - AUDIO_SOURCE_UNPROCESSED
* - AUDIO_SOURCE_MIC
+ * - AUDIO_SOURCE_ECHO_REFERENCE
* - AUDIO_SOURCE_FM_TUNER
* - AUDIO_SOURCE_VOICE_RECOGNITION
* - AUDIO_SOURCE_HOTWORD
@@ -96,10 +99,16 @@
{
switch (inputSource) {
case AUDIO_SOURCE_VOICE_COMMUNICATION:
- return 6;
+ return 9;
case AUDIO_SOURCE_CAMCORDER:
- return 5;
+ return 8;
+ case AUDIO_SOURCE_VOICE_PERFORMANCE:
+ return 7;
+ case AUDIO_SOURCE_UNPROCESSED:
+ return 6;
case AUDIO_SOURCE_MIC:
+ return 5;
+ case AUDIO_SOURCE_ECHO_REFERENCE:
return 4;
case AUDIO_SOURCE_FM_TUNER:
return 3;
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h
index 5099ebb..d52eb3d 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h
@@ -133,18 +133,14 @@
mDefaultOutputDevice->attach(module);
defaultInputDevice->attach(module);
- sp<OutputProfile> outProfile;
- outProfile = new OutputProfile(String8("primary"));
- outProfile->attach(module);
+ sp<OutputProfile> outProfile = new OutputProfile(String8("primary"));
outProfile->addAudioProfile(
new AudioProfile(AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO, 44100));
outProfile->addSupportedDevice(mDefaultOutputDevice);
outProfile->setFlags(AUDIO_OUTPUT_FLAG_PRIMARY);
module->addOutputProfile(outProfile);
- sp<InputProfile> inProfile;
- inProfile = new InputProfile(String8("primary"));
- inProfile->attach(module);
+ sp<InputProfile> inProfile = new InputProfile(String8("primary"));
inProfile->addAudioProfile(micProfile);
inProfile->addSupportedDevice(defaultInputDevice);
module->addInputProfile(inProfile);
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
index 776d98f..4d0916e 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
@@ -360,10 +360,12 @@
break;
}
}
- if (!deviceMatch) {
+ if (deviceMatch) {
+ mix->setMatchUid(uid);
+ } else {
// this mix doesn't go to one of the listed devices for the given uid,
// modify its rules to exclude the uid
- mix->excludeUid(uid);
+ mix->setExcludeUid(uid);
}
}
@@ -382,7 +384,7 @@
for (size_t j = 0; j < mix->mCriteria.size(); j++) {
const uint32_t rule = mix->mCriteria[j].mRule;
// is this rule affecting the uid?
- if (rule == RULE_EXCLUDE_UID
+ if ((rule == RULE_EXCLUDE_UID || rule == RULE_MATCH_UID)
&& uid == mix->mCriteria[j].mValue.mUid) {
foundUidRule = true;
criteriaToRemove.push_back(j);
diff --git a/services/audiopolicy/engineconfigurable/include/AudioPolicyEngineInstance.h b/services/audiopolicy/engineconfigurable/include/AudioPolicyEngineInstance.h
index a597e87..efc69da 100644
--- a/services/audiopolicy/engineconfigurable/include/AudioPolicyEngineInstance.h
+++ b/services/audiopolicy/engineconfigurable/include/AudioPolicyEngineInstance.h
@@ -19,10 +19,8 @@
class AudioPolicyManagerInterface;
class AudioPolicyPluginInterface;
-namespace android
-{
-namespace audio_policy
-{
+namespace android {
+namespace audio_policy {
class Engine;
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Android.mk b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Android.mk
index baaefd2..7631976 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Android.mk
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Android.mk
@@ -7,15 +7,19 @@
#
################################################################################################
-ifeq (1, 0)
-
LOCAL_PATH := $(call my-dir)
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), 1)
+
PFW_CORE := external/parameter-framework
-BUILD_PFW_SETTINGS := $(PFW_CORE)/support/android/build_pfw_settings.mk
+#@TODO: upstream new domain generator
+#BUILD_PFW_SETTINGS := $(PFW_CORE)/support/android/build_pfw_settings.mk
PFW_DEFAULT_SCHEMAS_DIR := $(PFW_CORE)/upstream/schemas
PFW_SCHEMAS_DIR := $(PFW_DEFAULT_SCHEMAS_DIR)
+TOOLS := frameworks/av/services/audiopolicy/engineconfigurable/tools
+BUILD_PFW_SETTINGS := $(TOOLS)/build_audio_pfw_settings.mk
+
##################################################################
# CONFIGURATION FILES
##################################################################
@@ -25,7 +29,8 @@
LOCAL_MODULE := ParameterFrameworkConfigurationPolicy.xml
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/parameter-framework
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_ETC)/parameter-framework
LOCAL_SRC_FILES := $(LOCAL_MODULE).in
AUDIO_PATTERN = @TUNING_ALLOWED@
@@ -46,7 +51,8 @@
LOCAL_MODULE := PolicyClass.xml
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/parameter-framework/Structure/Policy
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/Structure/Policy
LOCAL_SRC_FILES := Structure/$(LOCAL_MODULE)
include $(BUILD_PREBUILT)
@@ -54,12 +60,12 @@
LOCAL_MODULE := PolicySubsystem.xml
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
LOCAL_REQUIRED_MODULES := \
PolicySubsystem-CommonTypes.xml \
- PolicySubsystem-Volume.xml \
- libpolicy-subsystem \
+ libpolicy-subsystem
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/parameter-framework/Structure/Policy
+LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/Structure/Policy
LOCAL_SRC_FILES := Structure/$(LOCAL_MODULE)
include $(BUILD_PREBUILT)
@@ -67,7 +73,8 @@
LOCAL_MODULE := PolicySubsystem-CommonTypes.xml
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/parameter-framework/Structure/Policy
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/Structure/Policy
LOCAL_SRC_FILES := Structure/$(LOCAL_MODULE)
include $(BUILD_PREBUILT)
@@ -76,15 +83,16 @@
LOCAL_MODULE := parameter-framework.policy
LOCAL_MODULE_STEM := PolicyConfigurableDomains.xml
LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Settings/Policy
-LOCAL_ADDITIONAL_DEPENDENCIES := \
- PolicyClass.xml \
- PolicySubsystem.xml \
- ParameterFrameworkConfigurationPolicy.xml
+LOCAL_REQUIRED_MODULES := \
+ policy_criteria.xml \
+ policy_criterion_types.xml \
+ PolicySubsystem.xml \
+ PolicyClass.xml \
+ ParameterFrameworkConfigurationPolicy.xml
ifeq ($(pfw_rebuild_settings),true)
-PFW_TOPLEVEL_FILE := $(TARGET_OUT_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
-PFW_CRITERIA_FILE := $(LOCAL_PATH)/policy_criteria.txt
PFW_EDD_FILES := \
$(LOCAL_PATH)/Settings/device_for_strategy_media.pfw \
$(LOCAL_PATH)/Settings/device_for_strategy_phone.pfw \
@@ -100,6 +108,17 @@
$(LOCAL_PATH)/Settings/device_for_input_source.pfw \
$(LOCAL_PATH)/Settings/volumes.pfw
+LOCAL_ADDITIONAL_DEPENDENCIES := \
+ $(PFW_EDD_FILES)
+
+
+PFW_CRITERION_TYPES_FILE := $(TARGET_OUT_VENDOR_ETC)/policy_criterion_types.xml
+PFW_CRITERIA_FILE := $(TARGET_OUT_VENDOR_ETC)/policy_criteria.xml
+
+PFW_TOPLEVEL_FILE := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
+
+PFW_SCHEMAS_DIR := $(PFW_DEFAULT_SCHEMAS_DIR)
+
include $(BUILD_PFW_SETTINGS)
else
# Use the existing file
@@ -107,19 +126,27 @@
include $(BUILD_PREBUILT)
endif # pfw_rebuild_settings
+endif # ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), 0)
+
######### Policy PFW Settings - No Output #########
+ifeq (0, 1)
+
include $(CLEAR_VARS)
LOCAL_MODULE := parameter-framework.policy.no-output
LOCAL_MODULE_STEM := PolicyConfigurableDomains-NoOutputDevice.xml
LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Settings/Policy
-LOCAL_ADDITIONAL_DEPENDENCIES := \
- PolicyClass.xml \
- PolicySubsystem.xml \
- ParameterFrameworkConfigurationPolicy.xml
+LOCAL_REQUIRED_MODULES := \
+ policy_criteria.xml \
+ policy_criterion_types.xml \
+ PolicySubsystem.xml \
+ PolicyClass.xml \
+ ParameterFrameworkConfigurationPolicy.xml
-PFW_TOPLEVEL_FILE := $(TARGET_OUT_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
-PFW_CRITERIA_FILE := $(LOCAL_PATH)/policy_criteria.txt
+PFW_TOPLEVEL_FILE := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
+PFW_CRITERION_TYPES_FILE := $(TARGET_OUT_VENDOR_ETC)/policy_criterion_types.xml
+PFW_CRITERIA_FILE := $(TARGET_OUT_VENDOR_ETC)/policy_criteria.xml
PFW_EDD_FILES := \
$(LOCAL_PATH)/SettingsNoOutput/device_for_strategies.pfw \
$(LOCAL_PATH)/Settings/strategy_for_stream.pfw \
@@ -128,20 +155,26 @@
$(LOCAL_PATH)/Settings/volumes.pfw
include $(BUILD_PFW_SETTINGS)
-
+endif # ifeq (0, 1)
######### Policy PFW Settings - No Input #########
+ifeq (0, 1)
+
include $(CLEAR_VARS)
LOCAL_MODULE := parameter-framework.policy.no-input
LOCAL_MODULE_STEM := PolicyConfigurableDomains-NoInputDevice.xml
LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Settings/Policy
-LOCAL_ADDITIONAL_DEPENDENCIES := \
- PolicyClass.xml \
- PolicySubsystem.xml \
- ParameterFrameworkConfigurationPolicy.xml
+LOCAL_REQUIRED_MODULES := \
+ policy_criteria.xml \
+ policy_criterion_types.xml \
+ PolicySubsystem.xml \
+ PolicyClass.xml \
+ ParameterFrameworkConfigurationPolicy.xml
-PFW_TOPLEVEL_FILE := $(TARGET_OUT_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
-PFW_CRITERIA_FILE := $(LOCAL_PATH)/policy_criteria.txt
+PFW_TOPLEVEL_FILE := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
+PFW_CRITERION_TYPES_FILE := $(TARGET_OUT_VENDOR_ETC)/policy_criterion_types.xml
+PFW_CRITERIA_FILE := $(TARGET_OUT_VENDOR_ETC)/policy_criteria.xml
PFW_EDD_FILES := \
$(LOCAL_PATH)/Settings/device_for_strategy_media.pfw \
$(LOCAL_PATH)/Settings/device_for_strategy_phone.pfw \
@@ -160,3 +193,9 @@
include $(BUILD_PFW_SETTINGS)
endif # ifeq (1, 0)
+
+#######################################################################
+# Recursive call sub-folder Android.mk
+#######################################################################
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/ParameterFrameworkConfigurationPolicy.xml.in b/services/audiopolicy/engineconfigurable/parameter-framework/examples/ParameterFrameworkConfigurationPolicy.xml.in
index f5615cd..f80a07f 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/ParameterFrameworkConfigurationPolicy.xml.in
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/ParameterFrameworkConfigurationPolicy.xml.in
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ParameterFrameworkConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- SystemClassName="Policy" ServerPort="5019" TuningAllowed="@TUNING_ALLOWED@">
+ SystemClassName="Policy" ServerPort="/dev/socket/audioserver/policy_debug"
+ TuningAllowed="@TUNING_ALLOWED@">
<SubsystemPlugins>
<Location Folder="">
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/PolicyConfigurableDomains.xml b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/PolicyConfigurableDomains.xml
index b43f83b..0710441 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/PolicyConfigurableDomains.xml
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/PolicyConfigurableDomains.xml
@@ -8472,7 +8472,7 @@
<Configurations>
<Configuration Name="Sonification">
<CompoundRule Type="All">
- <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="Is" Value="RingTone"/>
+ <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="Is" Value="Ringtone"/>
</CompoundRule>
</Configuration>
<Configuration Name="Phone">
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/strategy_for_usage.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/strategy_for_usage.pfw
index b3115e7..fbea9e2 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/strategy_for_usage.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/strategy_for_usage.pfw
@@ -24,7 +24,7 @@
# In case of Ring or Alarm stream type active, switching to sonification
# @todo: handle this dynamic case. As a WA, using Ringtone mode...
#
- TelephonyMode Is RingTone
+ TelephonyMode Is Ringtone
/Policy/policy/usages/assistance_accessibility/applicable_strategy/strategy = sonification
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/SettingsNoOutput/device_for_strategies.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/SettingsNoOutput/device_for_strategies.pfw
index 917d4a7..f923610 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/SettingsNoOutput/device_for_strategies.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/SettingsNoOutput/device_for_strategies.pfw
@@ -9,7 +9,7 @@
bluetooth_sco = 0
bluetooth_sco_headset = 0
bluetooth_sco_carkit = 0
- bluetooth_a2dp = 0>
+ bluetooth_a2dp = 0
bluetooth_a2dp_headphones = 0
bluetooth_a2dp_speaker = 0
hdmi = 0
@@ -37,7 +37,7 @@
bluetooth_sco = 0
bluetooth_sco_headset = 0
bluetooth_sco_carkit = 0
- bluetooth_a2dp = 0>
+ bluetooth_a2dp = 0
bluetooth_a2dp_headphones = 0
bluetooth_a2dp_speaker = 0
hdmi = 0
@@ -65,7 +65,7 @@
bluetooth_sco = 0
bluetooth_sco_headset = 0
bluetooth_sco_carkit = 0
- bluetooth_a2dp = 0>
+ bluetooth_a2dp = 0
bluetooth_a2dp_headphones = 0
bluetooth_a2dp_speaker = 0
hdmi = 0
@@ -93,7 +93,7 @@
bluetooth_sco = 0
bluetooth_sco_headset = 0
bluetooth_sco_carkit = 0
- bluetooth_a2dp = 0>
+ bluetooth_a2dp = 0
bluetooth_a2dp_headphones = 0
bluetooth_a2dp_speaker = 0
hdmi = 0
@@ -121,7 +121,7 @@
bluetooth_sco = 0
bluetooth_sco_headset = 0
bluetooth_sco_carkit = 0
- bluetooth_a2dp = 0>
+ bluetooth_a2dp = 0
bluetooth_a2dp_headphones = 0
bluetooth_a2dp_speaker = 0
hdmi = 0
@@ -149,7 +149,7 @@
bluetooth_sco = 0
bluetooth_sco_headset = 0
bluetooth_sco_carkit = 0
- bluetooth_a2dp = 0>
+ bluetooth_a2dp = 0
bluetooth_a2dp_headphones = 0
bluetooth_a2dp_speaker = 0
hdmi = 0
@@ -177,7 +177,7 @@
bluetooth_sco = 0
bluetooth_sco_headset = 0
bluetooth_sco_carkit = 0
- bluetooth_a2dp = 0>
+ bluetooth_a2dp = 0
bluetooth_a2dp_headphones = 0
bluetooth_a2dp_speaker = 0
hdmi = 0
@@ -205,7 +205,7 @@
bluetooth_sco = 0
bluetooth_sco_headset = 0
bluetooth_sco_carkit = 0
- bluetooth_a2dp = 0>
+ bluetooth_a2dp = 0
bluetooth_a2dp_headphones = 0
bluetooth_a2dp_speaker = 0
hdmi = 0
@@ -233,7 +233,7 @@
bluetooth_sco = 0
bluetooth_sco_headset = 0
bluetooth_sco_carkit = 0
- bluetooth_a2dp = 0>
+ bluetooth_a2dp = 0
bluetooth_a2dp_headphones = 0
bluetooth_a2dp_speaker = 0
hdmi = 0
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicySubsystem-CommonTypes.xml b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicySubsystem-CommonTypes.xml
index 461e44a..daa7f68 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicySubsystem-CommonTypes.xml
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicySubsystem-CommonTypes.xml
@@ -37,6 +37,10 @@
<BitParameter Name="speaker_safe" Size="1" Pos="22"/>
<BitParameter Name="ip" Size="1" Pos="23"/>
<BitParameter Name="bus" Size="1" Pos="24"/>
+ <BitParameter Name="proxy" Size="1" Pos="25"/>
+ <BitParameter Name="usb_headset" Size="1" Pos="26"/>
+ <BitParameter Name="hearing_aid" Size="1" Pos="27"/>
+ <BitParameter Name="echo_canceller" Size="1" Pos="28"/>
<BitParameter Name="stub" Size="1" Pos="30"/>
</BitParameterBlock>
</ComponentType>
@@ -67,6 +71,9 @@
<BitParameter Name="loopback" Size="1" Pos="18"/>
<BitParameter Name="ip" Size="1" Pos="19"/>
<BitParameter Name="bus" Size="1" Pos="20"/>
+ <BitParameter Name="proxy" Size="1" Pos="21"/>
+ <BitParameter Name="usb_headset" Size="1" Pos="22"/>
+ <BitParameter Name="bluetooth_ble" Size="1" Pos="23"/>
<BitParameter Name="stub" Size="1" Pos="30"/>
</BitParameterBlock>
</ComponentType>
@@ -144,7 +151,7 @@
<!--#################### STRATEGY COMMON TYPES BEGIN ####################-->
- <ComponentType Name="StrategyConfig" Mapping="Strategy:'%1'">
+ <ComponentType Name="StrategyConfig" Mapping="Strategy">
<Component Name="selected_output_devices" Type="OutputDevicesMask"/>
</ComponentType>
@@ -170,7 +177,7 @@
</EnumParameter>
</ComponentType>
- <ComponentType Name="Stream">
+ <ComponentType Name="Stream" Mapping="Stream">
<Component Name="applicable_strategy" Type="Strategy"/>
<Component Name="applicable_volume_profile" Type="VolumeProfileType"
Description="Volume profile followed by a given stream type."/>
@@ -181,7 +188,7 @@
<!--#################### USAGE COMMON TYPES BEGIN ####################-->
<ComponentType Name="Usage">
- <Component Name="applicable_strategy" Type="Strategy" Mapping="Usage:'%1'"/>
+ <Component Name="applicable_strategy" Type="Strategy" Mapping="Usage"/>
</ComponentType>
<!--#################### USAGE COMMON TYPES END ####################-->
@@ -190,7 +197,7 @@
<ComponentType Name="InputSource">
<Component Name="applicable_input_device" Type="InputDevicesMask"
- Mapping="InputSource:'%1'" Description="Selected Input device"/>
+ Mapping="InputSource" Description="Selected Input device"/>
</ComponentType>
<!--#################### INPUT SOURCE COMMON TYPES END ####################-->
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicySubsystem.xml b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicySubsystem.xml
index ad9c356..45d1e8a 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicySubsystem.xml
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicySubsystem.xml
@@ -13,54 +13,40 @@
<!--#################### STRATEGY BEGIN ####################-->
- <ComponentType Name="Strategies" Description="Identifier must match the enum value to make
- the link between the PolicyManager and PFW">
- <Component Name="media" Type="StrategyConfig" Mapping="Amend1:Media,Identifier:0"/>
- <Component Name="phone" Type="StrategyConfig" Mapping="Amend1:Phone,Identifier:1"/>
- <Component Name="sonification" Type="StrategyConfig"
- Mapping="Amend1:Sonification,Identifier:2"/>
- <Component Name="sonification_respectful" Type="StrategyConfig"
- Mapping="Amend1:SonificationRespectful,Identifier:3"/>
- <Component Name="dtmf" Type="StrategyConfig" Mapping="Amend1:Dtmf,Identifier:4"/>
- <Component Name="enforced_audible" Type="StrategyConfig"
- Mapping="Amend1:EnforcedAudible,Identifier:5"/>
- <Component Name="transmitted_through_speaker" Type="StrategyConfig"
- Mapping="Amend1:TransmittedThroughSpeaker,Identifier:6"/>
- <Component Name="accessibility" Type="StrategyConfig"
- Mapping="Amend1:Accessibility,Identifier:7"/>
- <Component Name="rerouting" Type="StrategyConfig"
- Mapping="Amend1:Rerouting,Identifier:8"/>
+ <ComponentType Name="Strategies">
+ <Component Name="media" Type="StrategyConfig" Mapping="Name:STRATEGY_MEDIA"/>
+ <Component Name="phone" Type="StrategyConfig" Mapping="Name:STRATEGY_PHONE"/>
+ <Component Name="sonification" Type="StrategyConfig" Mapping="Name:STRATEGY_SONIFICATION"/>
+ <Component Name="sonification_respectful" Type="StrategyConfig" Mapping="Name:STRATEGY_SONIFICATION_RESPECTFUL"/>
+ <Component Name="dtmf" Type="StrategyConfig" Mapping="Name:STRATEGY_DTMF"/>
+ <Component Name="enforced_audible" Type="StrategyConfig" Mapping="Name:STRATEGY_ENFORCED_AUDIBLE"/>
+ <Component Name="transmitted_through_speaker" Type="StrategyConfig" Mapping="Name:STRATEGY_TRANSMITTED_THROUGH_SPEAKER"/>
+ <Component Name="accessibility" Type="StrategyConfig" Mapping="Name:STRATEGY_ACCESSIBILITY"/>
+ <Component Name="rerouting" Type="StrategyConfig" Mapping=",Name:STRATEGY_REROUTING"/>
</ComponentType>
<!--#################### STRATEGY END ####################-->
<!--#################### STREAM BEGIN ####################-->
- <ComponentType Name="Streams" Description="associated to audio_stream_type_t definition,
- identifier mapping must match the value of the enum">
- <Component Name="voice_call" Type="Stream" Mapping="Stream:VoiceCall,Identifier:0"/>
- <Component Name="system" Type="Stream" Mapping="Stream:System,Identifier:1"/>
- <Component Name="ring" Type="Stream" Mapping="Stream:Ring,Identifier:2"/>
- <Component Name="music" Type="Stream" Mapping="Stream:Music,Identifier:3"/>
- <Component Name="alarm" Type="Stream" Mapping="Stream:Alarm,Identifier:4"/>
- <Component Name="notification" Type="Stream"
- Mapping="Stream:Notification,Identifier:5"/>
- <Component Name="bluetooth_sco" Type="Stream"
- Mapping="Stream:BluetoothSco,Identifier:6"/>
- <Component Name="enforced_audible" Type="Stream"
- Mapping="Stream:EnforceAudible,Identifier:7"
- Description="Sounds that cannot be muted by user and must
- be routed to speaker"/>
- <Component Name="dtmf" Type="Stream" Mapping="Stream:Dtmf,Identifier:8"/>
- <Component Name="tts" Type="Stream" Mapping="Stream:Tts,Identifier:9"
- Description="Transmitted Through Speaker.
- Plays over speaker only, silent on other devices"/>
- <Component Name="accessibility" Type="Stream"
- Mapping="Stream:Accessibility,Identifier:10"
+ <ComponentType Name="Streams" Description="associated to audio_stream_type_t definition">
+ <Component Name="voice_call" Type="Stream" Mapping="Name:AUDIO_STREAM_VOICE_CALL"/>
+ <Component Name="system" Type="Stream" Mapping="Name:AUDIO_STREAM_SYSTEM"/>
+ <Component Name="ring" Type="Stream" Mapping="Name:AUDIO_STREAM_RING"/>
+ <Component Name="music" Type="Stream" Mapping="Name:AUDIO_STREAM_MUSIC"/>
+ <Component Name="alarm" Type="Stream" Mapping="Name:AUDIO_STREAM_ALARM"/>
+ <Component Name="notification" Type="Stream" Mapping="Name:AUDIO_STREAM_NOTIFICATION"/>
+ <Component Name="bluetooth_sco" Type="Stream" Mapping="Name:AUDIO_STREAM_BLUETOOTH_SCO"/>
+ <Component Name="enforced_audible" Type="Stream" Mapping="Name:AUDIO_STREAM_ENFORCED_AUDIBLE"
+ Description="Sounds that cannot be muted by user and must be routed to speaker"/>
+ <Component Name="dtmf" Type="Stream" Mapping="Name:AUDIO_STREAM_DTMF"/>
+ <Component Name="tts" Type="Stream" Mapping="Name:AUDIO_STREAM_TTS"
+ Description="Transmitted Through Speaker. Plays over speaker only, silent on other devices"/>
+ <Component Name="accessibility" Type="Stream" Mapping="Name:AUDIO_STREAM_ACCESSIBILITY"
Description="For accessibility talk back prompts"/>
- <Component Name="rerouting" Type="Stream" Mapping="Stream:Rerouting,Identifier:11"
+ <Component Name="rerouting" Type="Stream" Mapping="Name:AUDIO_STREAM_REROUTING"
Description="For dynamic policy output mixes"/>
- <Component Name="patch" Type="Stream" Mapping="Stream:Patch,Identifier:12"
+ <Component Name="patch" Type="Stream" Mapping="Name:AUDIO_STREAM_PATCH"
Description="For internal audio flinger tracks. Fixed volume"/>
</ComponentType>
@@ -68,36 +54,34 @@
<!--#################### USAGE BEGIN ####################-->
- <ComponentType Name="Usages" Description="associated to audio_usage_t definition,
- identifier mapping must match the value of the enum">
- <Component Name="unknown" Type="Usage" Mapping="Amend1:Unknown,Identifier:0"/>
- <Component Name="media" Type="Usage" Mapping="Amend1:Media,Identifier:1"/>
+ <ComponentType Name="Usages" Description="associated to audio_usage_t definition">
+ <Component Name="unknown" Type="Usage" Mapping="Name:AUDIO_USAGE_UNKNOWN"/>
+ <Component Name="media" Type="Usage" Mapping="Name:AUDIO_USAGE_MEDIA"/>
<Component Name="voice_communication" Type="Usage"
- Mapping="Amend1:VoiceCommunication,Identifier:2"/>
+ Mapping="Name:AUDIO_USAGE_VOICE_COMMUNICATION"/>
<Component Name="voice_communication_signalling" Type="Usage"
- Mapping="Amend1:VoiceCommunicationSignalling,Identifier:3"/>
- <Component Name="alarm" Type="Usage" Mapping="Amend1:Alarm,Identifier:4"/>
- <Component Name="notification" Type="Usage" Mapping="Amend1:Notification,Identifier:5"/>
+ Mapping="Name:AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING"/>
+ <Component Name="alarm" Type="Usage" Mapping="Name:AUDIO_USAGE_ALARM"/>
+ <Component Name="notification" Type="Usage" Mapping="Name:AUDIO_USAGE_NOTIFICATION"/>
<Component Name="notification_telephony_ringtone" Type="Usage"
- Mapping="Amend1:NotificationTelephonyRingtone,Identifier:6"/>
+ Mapping="Name:AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE"/>
<Component Name="notification_communication_request" Type="Usage"
- Mapping="Amend1:NotificationCommunicationRequest,Identifier:7"/>
+ Mapping="Name:AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST"/>
<Component Name="notification_communication_instant" Type="Usage"
- Mapping="Amend1:NotificationCommunicationInstant,Identifier:8"/>
+ Mapping="Name:AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT"/>
<Component Name="notification_communication_delayed" Type="Usage"
- Mapping="Amend1:NotificationCommunicationDelated,Identifier:9"/>
+ Mapping="Name:AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED"/>
<Component Name="notification_event" Type="Usage"
- Mapping="Amend1:NotificationEvent,Identifier:10"/>
+ Mapping="Name:AUDIO_USAGE_NOTIFICATION_EVENT"/>
<Component Name="assistance_accessibility" Type="Usage"
- Mapping="Amend1:AssistanceAccessibility,Identifier:11"/>
+ Mapping="Name:AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY"/>
<Component Name="assistance_navigation_guidance" Type="Usage"
- Mapping="Amend1:AssistanceNavigationGuidance,Identifier:12"/>
+ Mapping="Name:AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/>
<Component Name="assistance_sonification" Type="Usage"
- Mapping="Amend1:AssistanceSonification,Identifier:13"/>
- <Component Name="game" Type="Usage" Mapping="Amend1:BluetoothSco,Identifier:14"/>
- <Component Name="virtual_source" Type="Usage"
- Mapping="Amend1:VirtualSource,Identifier:15"/>
- <Component Name="assistant" Type="Usage" Mapping="Amend1:Assistant,Identifier:16"/>
+ Mapping="Name:AUDIO_USAGE_ASSISTANCE_SONIFICATION"/>
+ <Component Name="game" Type="Usage" Mapping="Name:AUDIO_USAGE_GAME"/>
+ <Component Name="virtual_source" Type="Usage" Mapping="Name:AUDIO_USAGE_VIRTUAL_SOURCE"/>
+ <Component Name="assistant" Type="Usage" Mapping="Name:AUDIO_USAGE_ASSISTANT"/>
</ComponentType>
<!--#################### USAGE END ####################-->
@@ -106,25 +90,25 @@
<ComponentType Name="InputSources" Description="associated to audio_source_t definition,
identifier mapping must match the value of the enum">
- <Component Name="default" Type="InputSource" Mapping="Amend1:Default,Identifier:0"/>
- <Component Name="mic" Type="InputSource" Mapping="Amend1:Mic,Identifier:1"/>
+ <Component Name="default" Type="InputSource" Mapping="Name:AUDIO_SOURCE_DEFAULT"/>
+ <Component Name="mic" Type="InputSource" Mapping="Name:AUDIO_SOURCE_MIC"/>
<Component Name="voice_uplink" Type="InputSource"
- Mapping="Amend1:VoiceUplink,Identifier:2"/>
+ Mapping="Name:AUDIO_SOURCE_VOICE_UPLINK"/>
<Component Name="voice_downlink" Type="InputSource"
- Mapping="Amend1:VoiceDownlink,Identifier:3"/>
+ Mapping="Name:AUDIO_SOURCE_VOICE_DOWNLINK"/>
<Component Name="voice_call" Type="InputSource"
- Mapping="Amend1:VoiceCall,Identifier:4"/>
- <Component Name="camcorder" Type="InputSource" Mapping="Amend1:Camcorder,Identifier:5"/>
+ Mapping="Name:AUDIO_SOURCE_VOICE_CALL"/>
+ <Component Name="camcorder" Type="InputSource" Mapping="Name:AUDIO_SOURCE_CAMCORDER"/>
<Component Name="voice_recognition" Type="InputSource"
- Mapping="Amend1:VoiceRecognition,Identifier:6"/>
+ Mapping="Name:AUDIO_SOURCE_VOICE_RECOGNITION"/>
<Component Name="voice_communication" Type="InputSource"
- Mapping="Amend1:VoiceCommunication,Identifier:7"/>
+ Mapping="Name:AUDIO_SOURCE_VOICE_COMMUNICATION"/>
<Component Name="remote_submix" Type="InputSource"
- Mapping="Amend1:RemoteSubmix,Identifier:8"/>
+ Mapping="Name:AUDIO_SOURCE_REMOTE_SUBMIX"/>
<Component Name="unprocessed" Type="InputSource"
- Mapping="Amend1:Unprocessed,Identifier:9"/>
- <Component Name="fm_tuner" Type="InputSource" Mapping="Amend1:FmTuner,Identifier:1998"/>
- <Component Name="hotword" Type="InputSource" Mapping="Amend1:Hotword,Identifier:1999"/>
+ Mapping="Name:AUDIO_SOURCE_UNPROCESSED"/>
+ <Component Name="fm_tuner" Type="InputSource" Mapping="Name:AUDIO_SOURCE_FM_TUNER"/>
+ <Component Name="hotword" Type="InputSource" Mapping="Name:AUDIO_SOURCE_HOTWORD"/>
</ComponentType>
<!--#################### INPUT SOURCE END ####################-->
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/policy_criteria.txt b/services/audiopolicy/engineconfigurable/parameter-framework/examples/policy_criteria.txt
deleted file mode 100644
index 480cbe1..0000000
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/policy_criteria.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-ExclusiveCriterion TelephonyMode : Normal RingTone InCall InCommunication
-InclusiveCriterion AvailableInputDevices : Communication Ambient BuiltinMic BluetoothScoHeadset WiredHeadset Hdmi TelephonyRx BackMic RemoteSubmix AnlgDockHeadset DgtlDockHeadset UsbAccessory UsbDevice FmTuner TvTuner Line Spdif BluetoothA2dp Loopback Ip Bus Stub
-InclusiveCriterion AvailableOutputDevices : Earpiece Speaker WiredSpeaker WiredHeadset WiredHeadphone BluetoothSco BluetoothScoHeadset BluetoothScoCarkit BluetoothA2dp BluetoothA2dpHeadphones BluetoothA2dpSpeaker Hdmi AnlgDockHeadset DgtlDockHeadset UsbAccessory UsbDevice RemoteSubmix TelephonyTx Line HdmiArc Spdif Fm AuxLine SpeakerSafe Ip Bus Stub
-ExclusiveCriterion ForceUseForCommunication : ForceNone ForceSpeaker ForceBtSco
-ExclusiveCriterion ForceUseForMedia : ForceNone ForceSpeaker ForceHeadphones ForceBtA2dp ForceWiredAccessory ForceAnalogDock ForceDigitalDock ForceNoBtA2dp ForceSystemEnforced
-ExclusiveCriterion ForceUseForRecord : ForceNone ForceBtSco ForceWiredAccessory
-ExclusiveCriterion ForceUseForDock : ForceNone ForceWiredAccessory ForceBtCarDock ForceBtDeskDock ForceAnalogDock ForceDigitalDock
-ExclusiveCriterion ForceUseForSystem : ForceNone ForceSystemEnforced
-ExclusiveCriterion ForceUseForHdmiSystemAudio : ForceNone ForceHdmiSystemEnforced
-ExclusiveCriterion ForceUseForEncodedSurround : ForceNone ForceEncodedSurroundNever ForceEncodedSurroundAlways
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Android.mk b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Android.mk
index 3559cf1..db1f038 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Android.mk
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Android.mk
@@ -28,6 +28,7 @@
LOCAL_SHARED_LIBRARIES := \
libaudiopolicyengineconfigurable \
libparameter \
+ libmedia_helper \
liblog \
LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/InputSource.cpp b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/InputSource.cpp
index eac4efe..f91f8d7 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/InputSource.cpp
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/InputSource.cpp
@@ -17,6 +17,7 @@
#include "InputSource.h"
#include "PolicyMappingKeys.h"
#include "PolicySubsystem.h"
+#include <media/TypeConverter.h>
using std::string;
@@ -33,9 +34,13 @@
instanceConfigurableElement->getBelongingSubsystem())),
mPolicyPluginInterface(mPolicySubsystem->getPolicyPluginInterface())
{
- mId = static_cast<audio_source_t>(context.getItemAsInteger(MappingKeyIdentifier));
+ std::string name(context.getItem(MappingKeyName));
+
+ if(not android::SourceTypeConverter::fromString(name, mId)) {
+ LOG_ALWAYS_FATAL("Invalid Input Source name: %s, invalid XML structure file", name.c_str());
+ }
// Declares the strategy to audio policy engine
- mPolicyPluginInterface->addInputSource(getFormattedMappingValue(), mId);
+ mPolicyPluginInterface->addInputSource(name, mId);
}
bool InputSource::sendToHW(string & /*error*/)
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystem.cpp b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystem.cpp
index 98d10a9..7374fc3 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystem.cpp
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystem.cpp
@@ -65,22 +65,22 @@
addSubsystemObjectFactory(
new TSubsystemObjectFactory<Stream>(
mStreamComponentName,
- (1 << MappingKeyIdentifier))
+ (1 << MappingKeyName))
);
addSubsystemObjectFactory(
new TSubsystemObjectFactory<Strategy>(
mStrategyComponentName,
- (1 << MappingKeyAmend1) | (1 << MappingKeyIdentifier))
+ 0)
);
addSubsystemObjectFactory(
new TSubsystemObjectFactory<Usage>(
mUsageComponentName,
- (1 << MappingKeyAmend1) | (1 << MappingKeyIdentifier))
+ (1 << MappingKeyName))
);
addSubsystemObjectFactory(
new TSubsystemObjectFactory<InputSource>(
mInputSourceComponentName,
- (1 << MappingKeyAmend1) | (1 << MappingKeyIdentifier))
+ (1 << MappingKeyName))
);
}
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Strategy.cpp b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Strategy.cpp
index 746c3a8..876bcb0 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Strategy.cpp
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Strategy.cpp
@@ -17,10 +17,38 @@
#include "Strategy.h"
#include "PolicyMappingKeys.h"
#include "PolicySubsystem.h"
+#include <RoutingStrategy.h>
using std::string;
using android::routing_strategy;
+namespace detail {
+
+constexpr std::pair<routing_strategy, const char*> routingStrategyMap[] = {
+ {android::STRATEGY_MEDIA, "STRATEGY_MEDIA"},
+ {android::STRATEGY_PHONE, "STRATEGY_PHONE"},
+ {android::STRATEGY_SONIFICATION, "STRATEGY_SONIFICATION"},
+ {android::STRATEGY_SONIFICATION_RESPECTFUL, "STRATEGY_SONIFICATION_RESPECTFUL"},
+ {android::STRATEGY_DTMF, "STRATEGY_DTMF"},
+ {android::STRATEGY_ENFORCED_AUDIBLE, "STRATEGY_ENFORCED_AUDIBLE"},
+ {android::STRATEGY_TRANSMITTED_THROUGH_SPEAKER, "STRATEGY_TRANSMITTED_THROUGH_SPEAKER"},
+ {android::STRATEGY_ACCESSIBILITY, "STRATEGY_ACCESSIBILITY"},
+ {android::STRATEGY_REROUTING, "STRATEGY_REROUTING"},
+};
+
+bool fromString(const char *literalName, routing_strategy &type)
+{
+ for (auto& pair : routingStrategyMap) {
+ if (strcmp(pair.second, literalName) == 0) {
+ type = pair.first;
+ return true;
+ }
+ }
+ return false;
+}
+
+}
+
Strategy::Strategy(const string &mappingValue,
CInstanceConfigurableElement *instanceConfigurableElement,
const CMappingContext &context,
@@ -35,10 +63,12 @@
instanceConfigurableElement->getBelongingSubsystem())),
mPolicyPluginInterface(mPolicySubsystem->getPolicyPluginInterface())
{
- mId = static_cast<routing_strategy>(context.getItemAsInteger(MappingKeyIdentifier));
-
+ std::string name(context.getItem(MappingKeyName));
+ if (not detail::fromString(name.c_str(), mId)) {
+ LOG_ALWAYS_FATAL("Invalid Strategy %s, invalid XML structure file", name.c_str());
+ }
// Declares the strategy to audio policy engine
- mPolicyPluginInterface->addStrategy(getFormattedMappingValue(), mId);
+ mPolicyPluginInterface->addStrategy(instanceConfigurableElement->getName(), mId);
}
bool Strategy::sendToHW(string & /*error*/)
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Stream.cpp b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Stream.cpp
index c642a23..46c9e1c 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Stream.cpp
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Stream.cpp
@@ -17,6 +17,7 @@
#include "Stream.h"
#include "PolicyMappingKeys.h"
#include "PolicySubsystem.h"
+#include <media/TypeConverter.h>
using std::string;
using android::routing_strategy;
@@ -29,10 +30,14 @@
instanceConfigurableElement->getBelongingSubsystem())),
mPolicyPluginInterface(mPolicySubsystem->getPolicyPluginInterface())
{
- mId = static_cast<audio_stream_type_t>(context.getItemAsInteger(MappingKeyIdentifier));
+ std::string name(context.getItem(MappingKeyName));
+
+ if (not android::StreamTypeConverter::fromString(name, mId)) {
+ LOG_ALWAYS_FATAL("Invalid Stream type name: %s, invalid XML structure file", name.c_str());
+ }
// Declares the strategy to audio policy engine
- mPolicyPluginInterface->addStream(getFormattedMappingValue(), mId);
+ mPolicyPluginInterface->addStream(name, mId);
}
bool Stream::sendToHW(string & /*error*/)
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Usage.cpp b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Usage.cpp
index 78199f8..925d631 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Usage.cpp
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Usage.cpp
@@ -17,6 +17,7 @@
#include "Usage.h"
#include "PolicyMappingKeys.h"
#include "PolicySubsystem.h"
+#include <media/TypeConverter.h>
using std::string;
using android::routing_strategy;
@@ -34,10 +35,13 @@
instanceConfigurableElement->getBelongingSubsystem())),
mPolicyPluginInterface(mPolicySubsystem->getPolicyPluginInterface())
{
- mId = static_cast<audio_usage_t>(context.getItemAsInteger(MappingKeyIdentifier));
+ std::string name(context.getItem(MappingKeyName));
+ if (not android::UsageTypeConverter::fromString(name, mId)) {
+ LOG_ALWAYS_FATAL("Invalid Usage name: %s, invalid XML structure file", name.c_str());
+ }
// Declares the strategy to audio policy engine
- mPolicyPluginInterface->addUsage(getFormattedMappingValue(), mId);
+ mPolicyPluginInterface->addUsage(name, mId);
}
bool Usage::sendToHW(string & /*error*/)
diff --git a/services/audiopolicy/engineconfigurable/sepolicy/audioserver.te b/services/audiopolicy/engineconfigurable/sepolicy/audioserver.te
new file mode 100644
index 0000000..4d41d42
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/sepolicy/audioserver.te
@@ -0,0 +1,4 @@
+userdebug_or_eng(`
+ allow audioserver audioserver_socket:dir rw_dir_perms;
+ allow audioserver audioserver_socket:sock_file create_file_perms;
+')
diff --git a/services/audiopolicy/engineconfigurable/sepolicy/file.te b/services/audiopolicy/engineconfigurable/sepolicy/file.te
new file mode 100644
index 0000000..7db1937
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/sepolicy/file.te
@@ -0,0 +1,2 @@
+# Policy Engine remote connection for runtime debug of parameter framework
+type audioserver_socket, file_type, coredomain_socket;
diff --git a/services/audiopolicy/engineconfigurable/sepolicy/file_contexts b/services/audiopolicy/engineconfigurable/sepolicy/file_contexts
new file mode 100644
index 0000000..950fcce
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/sepolicy/file_contexts
@@ -0,0 +1 @@
+/dev/socket/audioserver(/.*)? u:object_r:audioserver_socket:s0
diff --git a/services/audiopolicy/engineconfigurable/src/Collection.h b/services/audiopolicy/engineconfigurable/src/Collection.h
index b72ded8..1f8ed8d 100644
--- a/services/audiopolicy/engineconfigurable/src/Collection.h
+++ b/services/audiopolicy/engineconfigurable/src/Collection.h
@@ -28,10 +28,8 @@
#include <stdint.h>
#include <string>
-namespace android
-{
-namespace audio_policy
-{
+namespace android {
+namespace audio_policy {
/**
* Collection of policy element as a map indexed with a their UID type.
diff --git a/services/audiopolicy/engineconfigurable/src/Element.h b/services/audiopolicy/engineconfigurable/src/Element.h
index 52e77e5..1b55c8c 100644
--- a/services/audiopolicy/engineconfigurable/src/Element.h
+++ b/services/audiopolicy/engineconfigurable/src/Element.h
@@ -22,10 +22,8 @@
#include <system/audio.h>
#include <utils/Log.h>
-namespace android
-{
-namespace audio_policy
-{
+namespace android {
+namespace audio_policy {
template <typename Key>
class Element
diff --git a/services/audiopolicy/engineconfigurable/src/Engine.cpp b/services/audiopolicy/engineconfigurable/src/Engine.cpp
index 0d18ffa..009cf90 100644
--- a/services/audiopolicy/engineconfigurable/src/Engine.cpp
+++ b/services/audiopolicy/engineconfigurable/src/Engine.cpp
@@ -35,10 +35,9 @@
using std::string;
using std::map;
-namespace android
-{
-namespace audio_policy
-{
+namespace android {
+namespace audio_policy {
+
template <>
StrategyCollection &Engine::getCollection<routing_strategy>()
{
@@ -220,8 +219,10 @@
}
status_t Engine::setDeviceConnectionState(const sp<DeviceDescriptor> devDesc,
- audio_policy_dev_state_t /*state*/)
+ audio_policy_dev_state_t state)
{
+ mPolicyParameterMgr->setDeviceConnectionState(devDesc, state);
+
if (audio_is_output_device(devDesc->type())) {
return mPolicyParameterMgr->setAvailableOutputDevices(
mApmObserver->getAvailableOutputDevices().types());
diff --git a/services/audiopolicy/engineconfigurable/src/Engine.h b/services/audiopolicy/engineconfigurable/src/Engine.h
index 328d23d..ba4f889 100644
--- a/services/audiopolicy/engineconfigurable/src/Engine.h
+++ b/services/audiopolicy/engineconfigurable/src/Engine.h
@@ -21,12 +21,10 @@
#include <AudioPolicyPluginInterface.h>
#include "Collection.h"
-namespace android
-{
+namespace android {
class AudioPolicyManagerObserver;
-namespace audio_policy
-{
+namespace audio_policy {
class ParameterManagerWrapper;
class VolumeProfile;
diff --git a/services/audiopolicy/engineconfigurable/src/EngineInstance.cpp b/services/audiopolicy/engineconfigurable/src/EngineInstance.cpp
index 9aa89b2..2442590 100644
--- a/services/audiopolicy/engineconfigurable/src/EngineInstance.cpp
+++ b/services/audiopolicy/engineconfigurable/src/EngineInstance.cpp
@@ -21,10 +21,8 @@
using std::string;
-namespace android
-{
-namespace audio_policy
-{
+namespace android {
+namespace audio_policy {
EngineInstance::EngineInstance()
{
diff --git a/services/audiopolicy/engineconfigurable/src/InputSource.cpp b/services/audiopolicy/engineconfigurable/src/InputSource.cpp
index ae39fef..d252d3f 100644
--- a/services/audiopolicy/engineconfigurable/src/InputSource.cpp
+++ b/services/audiopolicy/engineconfigurable/src/InputSource.cpp
@@ -20,13 +20,13 @@
using std::string;
-namespace android
-{
-namespace audio_policy
-{
+namespace android {
+namespace audio_policy {
+
status_t Element<audio_source_t>::setIdentifier(audio_source_t identifier)
{
- if (identifier > AUDIO_SOURCE_MAX && identifier != AUDIO_SOURCE_HOTWORD) {
+ if (identifier > AUDIO_SOURCE_MAX && identifier != AUDIO_SOURCE_HOTWORD
+ && identifier != AUDIO_SOURCE_FM_TUNER && identifier != AUDIO_SOURCE_ECHO_REFERENCE) {
return BAD_VALUE;
}
mIdentifier = identifier;
diff --git a/services/audiopolicy/engineconfigurable/src/InputSource.h b/services/audiopolicy/engineconfigurable/src/InputSource.h
index 6c498dc..64b390e 100644
--- a/services/audiopolicy/engineconfigurable/src/InputSource.h
+++ b/services/audiopolicy/engineconfigurable/src/InputSource.h
@@ -18,10 +18,8 @@
#include "Element.h"
-namespace android
-{
-namespace audio_policy
-{
+namespace android {
+namespace audio_policy {
/**
* Specialization of policy base class element for audio_source_t
diff --git a/services/audiopolicy/engineconfigurable/src/Strategy.cpp b/services/audiopolicy/engineconfigurable/src/Strategy.cpp
index a539914..310b35e 100644
--- a/services/audiopolicy/engineconfigurable/src/Strategy.cpp
+++ b/services/audiopolicy/engineconfigurable/src/Strategy.cpp
@@ -20,10 +20,8 @@
using std::string;
-namespace android
-{
-namespace audio_policy
-{
+namespace android {
+namespace audio_policy {
status_t Element<routing_strategy>::setIdentifier(routing_strategy identifier)
{
diff --git a/services/audiopolicy/engineconfigurable/src/Strategy.h b/services/audiopolicy/engineconfigurable/src/Strategy.h
index 1157d55..f2487fd 100644
--- a/services/audiopolicy/engineconfigurable/src/Strategy.h
+++ b/services/audiopolicy/engineconfigurable/src/Strategy.h
@@ -19,10 +19,8 @@
#include "Element.h"
#include <RoutingStrategy.h>
-namespace android
-{
-namespace audio_policy
-{
+namespace android {
+namespace audio_policy {
/**
* @tparam audio_devices_t: Applicable output device(s) for this strategy.
diff --git a/services/audiopolicy/engineconfigurable/src/Stream.cpp b/services/audiopolicy/engineconfigurable/src/Stream.cpp
index 0ed364f..73fb94d 100644
--- a/services/audiopolicy/engineconfigurable/src/Stream.cpp
+++ b/services/audiopolicy/engineconfigurable/src/Stream.cpp
@@ -21,10 +21,8 @@
using std::string;
-namespace android
-{
-namespace audio_policy
-{
+namespace android {
+namespace audio_policy {
status_t Element<audio_stream_type_t>::setIdentifier(audio_stream_type_t identifier)
{
diff --git a/services/audiopolicy/engineconfigurable/src/Stream.h b/services/audiopolicy/engineconfigurable/src/Stream.h
index 6902003..2bf70b3 100644
--- a/services/audiopolicy/engineconfigurable/src/Stream.h
+++ b/services/audiopolicy/engineconfigurable/src/Stream.h
@@ -21,10 +21,9 @@
#include <RoutingStrategy.h>
#include <map>
-namespace android
-{
-namespace audio_policy
-{
+namespace android {
+namespace audio_policy {
+
/**
* @tparam routing_strategy: Applicable strategy for this stream.
*/
diff --git a/services/audiopolicy/engineconfigurable/src/Usage.cpp b/services/audiopolicy/engineconfigurable/src/Usage.cpp
index 5d20828..8c0dfba 100644
--- a/services/audiopolicy/engineconfigurable/src/Usage.cpp
+++ b/services/audiopolicy/engineconfigurable/src/Usage.cpp
@@ -18,10 +18,8 @@
#include "Usage.h"
-namespace android
-{
-namespace audio_policy
-{
+namespace android {
+namespace audio_policy {
status_t Element<audio_usage_t>::setIdentifier(audio_usage_t identifier)
{
diff --git a/services/audiopolicy/engineconfigurable/src/Usage.h b/services/audiopolicy/engineconfigurable/src/Usage.h
index d69e0e0..72a452f 100644
--- a/services/audiopolicy/engineconfigurable/src/Usage.h
+++ b/services/audiopolicy/engineconfigurable/src/Usage.h
@@ -19,10 +19,8 @@
#include "Element.h"
#include <RoutingStrategy.h>
-namespace android
-{
-namespace audio_policy
-{
+namespace android {
+namespace audio_policy {
/**
* @tparam routing_strategy: Applicable strategy for this usage.
diff --git a/services/audiopolicy/engineconfigurable/tools/Android.bp b/services/audiopolicy/engineconfigurable/tools/Android.bp
new file mode 100644
index 0000000..d8f29dc
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/tools/Android.bp
@@ -0,0 +1,31 @@
+// 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.
+
+python_binary_host {
+ name: "buildPolicyCriterionTypes.py",
+ owner: "renault",
+ main: "buildPolicyCriterionTypes.py",
+ srcs: [
+ "buildPolicyCriterionTypes.py",
+ ],
+ version: {
+ py2: {
+ enabled: true,
+ },
+ py3: {
+ enabled: false,
+ },
+ },
+}
+
diff --git a/services/audiopolicy/engineconfigurable/tools/buildPolicyCriterionTypes.py b/services/audiopolicy/engineconfigurable/tools/buildPolicyCriterionTypes.py
new file mode 100755
index 0000000..0fb70a6
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/tools/buildPolicyCriterionTypes.py
@@ -0,0 +1,243 @@
+#!/usr/bin/python
+
+#
+# Copyright 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.
+#
+
+import argparse
+import re
+import sys
+import tempfile
+import os
+import logging
+import subprocess
+import xml.etree.ElementTree as ET
+import xml.etree.ElementInclude as EI
+import xml.dom.minidom as MINIDOM
+from collections import OrderedDict
+
+#
+# Helper script that helps to feed at build time the XML criterion types file used by
+# the engineconfigurable to start the parameter-framework.
+# It prevents to fill them manually and avoid divergences with android.
+#
+# The Device Types criterion types are fed from audio-base.h file with the option
+# --androidaudiobaseheader <path/to/android/audio/base/file/audio-base.h>
+#
+# The Device Addresses criterion types are fed from the audio policy configuration file
+# in order to discover all the devices for which the address matter.
+# --audiopolicyconfigurationfile <path/to/audio_policy_configuration.xml>
+#
+# The reference file of criterion types must also be set as an input of the script:
+# --criteriontypes <path/to/criterion/file/audio_criterion_types.xml.in>
+#
+# At last, the output of the script shall be set also:
+# --outputfile <path/to/out/vendor/etc/audio_criterion_types.xml>
+#
+
+def parseArgs():
+ argparser = argparse.ArgumentParser(description="Parameter-Framework XML \
+ audio criterion type file generator.\n\
+ Exit with the number of (recoverable or not) error that occured.")
+ argparser.add_argument('--androidaudiobaseheader',
+ help="Android Audio Base C header file, Mandatory.",
+ metavar="ANDROID_AUDIO_BASE_HEADER",
+ type=argparse.FileType('r'),
+ required=True)
+ argparser.add_argument('--audiopolicyconfigurationfile',
+ help="Android Audio Policy Configuration file, Mandatory.",
+ metavar="(AUDIO_POLICY_CONFIGURATION_FILE)",
+ type=argparse.FileType('r'),
+ required=True)
+ argparser.add_argument('--criteriontypes',
+ help="Criterion types XML base file, in \
+ '<criterion_types> \
+ <criterion_type name="" type=<inclusive|exclusive> values=<value1,value2,...>/>' \
+ format. Mandatory.",
+ metavar="CRITERION_TYPE_FILE",
+ type=argparse.FileType('r'),
+ required=True)
+ argparser.add_argument('--outputfile',
+ help="Criterion types outputfile file. Mandatory.",
+ metavar="CRITERION_TYPE_OUTPUT_FILE",
+ type=argparse.FileType('w'),
+ required=True)
+ argparser.add_argument('--verbose',
+ action='store_true')
+
+ return argparser.parse_args()
+
+
+def generateXmlCriterionTypesFile(criterionTypes, addressCriteria, criterionTypesFile, outputFile):
+
+ logging.info("Importing criterionTypesFile {}".format(criterionTypesFile))
+ criterion_types_in_tree = ET.parse(criterionTypesFile)
+
+ criterion_types_root = criterion_types_in_tree.getroot()
+
+ for criterion_name, values_dict in criterionTypes.items():
+ for criterion_type in criterion_types_root.findall('criterion_type'):
+ if criterion_type.get('name') == criterion_name:
+ values_node = ET.SubElement(criterion_type, "values")
+ ordered_values = OrderedDict(sorted(values_dict.items(), key=lambda x: x[1]))
+ for key, value in ordered_values.items():
+ value_node = ET.SubElement(values_node, "value")
+ value_node.set('numerical', str(value))
+ value_node.set('literal', key)
+
+ if addressCriteria:
+ for criterion_name, values_list in addressCriteria.items():
+ for criterion_type in criterion_types_root.findall('criterion_type'):
+ if criterion_type.get('name') == criterion_name:
+ values_node = ET.SubElement(criterion_type, "values")
+ index = 0
+ for value in values_list:
+ value_node = ET.SubElement(values_node, "value", literal=value)
+ value_node.set('numerical', str(1 << index))
+ index += 1
+
+ xmlstr = ET.tostring(criterion_types_root, encoding='utf8', method='xml')
+ reparsed = MINIDOM.parseString(xmlstr)
+ prettyXmlStr = reparsed.toprettyxml(newl='\r\n')
+ prettyXmlStr = os.linesep.join([s for s in prettyXmlStr.splitlines() if s.strip()])
+ outputFile.write(prettyXmlStr.encode('utf-8'))
+
+def capitalizeLine(line):
+ return ' '.join((w.capitalize() for w in line.split(' ')))
+
+
+#
+# Parse the audio policy configuration file and output a dictionary of device criteria addresses
+#
+def parseAndroidAudioPolicyConfigurationFile(audiopolicyconfigurationfile):
+
+ logging.info("Checking Audio Policy Configuration file {}".format(audiopolicyconfigurationfile))
+ #
+ # extract all devices addresses from audio policy configuration file
+ #
+ address_criteria_mapping_table = {
+ 'sink' : "OutputDevicesAddressesType",
+ 'source' : "InputDevicesAddressesType" }
+
+ address_criteria = {
+ 'OutputDevicesAddressesType' : [],
+ 'InputDevicesAddressesType' : [] }
+
+ oldWorkingDir = os.getcwd()
+ print "Current working directory %s" % oldWorkingDir
+
+ newDir = os.path.join(oldWorkingDir , audiopolicyconfigurationfile.name)
+
+ policy_in_tree = ET.parse(audiopolicyconfigurationfile)
+ os.chdir(os.path.dirname(os.path.normpath(newDir)))
+
+ print "new working directory %s" % os.getcwd()
+
+ policy_root = policy_in_tree.getroot()
+ EI.include(policy_root)
+
+ os.chdir(oldWorkingDir)
+
+ for device in policy_root.iter('devicePort'):
+ for key in address_criteria_mapping_table.keys():
+ if device.get('role') == key and device.get('address') :
+ logging.info("{}: <{}>".format(key, device.get('address')))
+ address_criteria[address_criteria_mapping_table[key]].append(device.get('address'))
+
+ for criteria in address_criteria:
+ values = ','.join(address_criteria[criteria])
+ logging.info("{}: <{}>".format(criteria, values))
+
+ return address_criteria
+
+#
+# Parse the audio-base.h file and output a dictionary of android dependent criterion types:
+# -Android Mode
+# -Output devices type
+# -Input devices type
+#
+def parseAndroidAudioFile(androidaudiobaseheaderFile):
+ #
+ # Adaptation table between Android Enumeration prefix and Audio PFW Criterion type names
+ #
+ criterion_mapping_table = {
+ 'AUDIO_MODE' : "AndroidModeType",
+ 'AUDIO_DEVICE_OUT' : "OutputDevicesMaskType",
+ 'AUDIO_DEVICE_IN' : "InputDevicesMaskType"}
+
+ all_criteria = {
+ 'AndroidModeType' : {},
+ 'OutputDevicesMaskType' : {},
+ 'InputDevicesMaskType' : {} }
+
+ #
+ # _CNT, _MAX, _ALL and _NONE are prohibited values as ther are just helpers for enum users.
+ #
+ ignored_values = [ 'CNT', 'MAX', 'ALL', 'NONE' ]
+
+ criteria_pattern = re.compile(
+ r"\s*(?P<type>(?:"+'|'.join(criterion_mapping_table.keys()) + "))\_" \
+ r"(?P<literal>(?!" + '|'.join(ignored_values) + ")\w*)\s*=\s*" \
+ r"(?P<values>(?:0[xX])?[0-9a-fA-F]+)")
+
+ logging.info("Checking Android Header file {}".format(androidaudiobaseheaderFile))
+
+ for line_number, line in enumerate(androidaudiobaseheaderFile):
+ match = criteria_pattern.match(line)
+ if match:
+ logging.debug("The following line is VALID: {}:{}\n{}".format(
+ androidaudiobaseheaderFile.name, line_number, line))
+
+ criterion_name = criterion_mapping_table[match.groupdict()['type']]
+ literal = ''.join((w.capitalize() for w in match.groupdict()['literal'].split('_')))
+ numerical_value = match.groupdict()['values']
+
+ # for AUDIO_DEVICE_IN: need to remove sign bit
+ if criterion_name == "InputDevicesMaskType":
+ numerical_value = str(int(numerical_value, 0) & ~2147483648)
+
+ # Remove duplicated numerical values
+ if int(numerical_value, 0) in all_criteria[criterion_name].values():
+ logging.info("criterion {} duplicated values:".format(criterion_name))
+ logging.info("{}:{}".format(numerical_value, literal))
+ logging.info("KEEPING LATEST")
+ for key in all_criteria[criterion_name].keys():
+ if all_criteria[criterion_name][key] == int(numerical_value, 0):
+ del all_criteria[criterion_name][key]
+
+ all_criteria[criterion_name][literal] = int(numerical_value, 0)
+
+ logging.debug("type:{},".format(criterion_name))
+ logging.debug("iteral:{},".format(literal))
+ logging.debug("values:{}.".format(numerical_value))
+
+ return all_criteria
+
+
+def main():
+ logging.root.setLevel(logging.INFO)
+ args = parseArgs()
+
+ all_criteria = parseAndroidAudioFile(args.androidaudiobaseheader)
+
+ address_criteria = parseAndroidAudioPolicyConfigurationFile(args.audiopolicyconfigurationfile)
+
+ criterion_types = args.criteriontypes
+
+ generateXmlCriterionTypesFile(all_criteria, address_criteria, criterion_types, args.outputfile)
+
+# If this file is directly executed
+if __name__ == "__main__":
+ exit(main())
diff --git a/services/audiopolicy/engineconfigurable/tools/build_audio_pfw_settings.mk b/services/audiopolicy/engineconfigurable/tools/build_audio_pfw_settings.mk
new file mode 100644
index 0000000..2b86469
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/tools/build_audio_pfw_settings.mk
@@ -0,0 +1,35 @@
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): MY_CRITERION_TYPES_FILE := $(PFW_CRITERION_TYPES_FILE)
+$(LOCAL_BUILT_MODULE): MY_TOOL := domainGeneratorPolicy.py
+$(LOCAL_BUILT_MODULE): MY_TOPLEVEL_FILE := $(PFW_TOPLEVEL_FILE)
+$(LOCAL_BUILT_MODULE): MY_CRITERIA_FILE := $(PFW_CRITERIA_FILE)
+$(LOCAL_BUILT_MODULE): MY_TUNING_FILE := $(PFW_TUNING_FILE)
+$(LOCAL_BUILT_MODULE): MY_EDD_FILES := $(PFW_EDD_FILES)
+$(LOCAL_BUILT_MODULE): MY_DOMAIN_FILES := $(PFW_DOMAIN_FILES)
+$(LOCAL_BUILT_MODULE): MY_SCHEMAS_DIR := $(PFW_SCHEMAS_DIR)
+$(LOCAL_BUILT_MODULE): MY_CRITERION_TYPES_FILE := $(PFW_CRITERION_TYPES_FILE)
+$(LOCAL_BUILT_MODULE): $(LOCAL_REQUIRED_MODULES) $(LOCAL_ADDITIONAL_DEPENDENCIES) domainGeneratorPolicy.py
+
+ "$(MY_TOOL)" --validate \
+ --toplevel-config "$(MY_TOPLEVEL_FILE)" \
+ --criteria "$(MY_CRITERIA_FILE)" \
+ --criteriontypes "$(MY_CRITERION_TYPES_FILE)" \
+ --initial-settings $(MY_TUNING_FILE) \
+ --add-edds $(MY_EDD_FILES) \
+ --add-domains $(MY_DOMAIN_FILES) \
+ --schemas-dir $(MY_SCHEMAS_DIR) > "$@"
+
+
+# Clear variables for further use
+PFW_TOPLEVEL_FILE :=
+PFW_STRUCTURE_FILES :=
+PFW_CRITERIA_FILE :=
+PFW_CRITERION_TYPES_FILE :=
+PFW_TUNING_FILE :=
+PFW_EDD_FILES :=
+PFW_DOMAIN_FILES :=
+PFW_SCHEMAS_DIR := $(PFW_DEFAULT_SCHEMAS_DIR)
diff --git a/services/audiopolicy/engineconfigurable/tools/domainGeneratorPolicy.py b/services/audiopolicy/engineconfigurable/tools/domainGeneratorPolicy.py
new file mode 100755
index 0000000..7929402
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/tools/domainGeneratorPolicy.py
@@ -0,0 +1,268 @@
+#!/usr/bin/python
+
+#
+# Copyright 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.
+#
+
+import EddParser
+from PFWScriptGenerator import PfwScriptTranslator
+import hostConfig
+
+import argparse
+import re
+import sys
+import tempfile
+import os
+import logging
+import subprocess
+import xml.etree.ElementTree as ET
+
+#
+# In order to build the XML Settings file at build time, an instance of the parameter-framework
+# shall be started and fed with all the criterion types/criteria that will be used by
+# the engineconfigurable.
+# This scripts allows generates the settings from the same audio_criterion_types.xml /
+# audio_criteria.xml files used at run time by the engineconfigurable
+#
+
+def parseArgs():
+ argparser = argparse.ArgumentParser(description="Parameter-Framework XML \
+ Settings file generator.\n\
+ Exit with the number of (recoverable or not) error that occured.")
+ argparser.add_argument('--toplevel-config',
+ help="Top-level parameter-framework configuration file. Mandatory.",
+ metavar="TOPLEVEL_CONFIG_FILE",
+ required=True)
+ argparser.add_argument('--criteria',
+ help="Criteria file, in XML format: \
+ in '<criteria> \
+ <criterion name="" type=""/> \
+ </criteria>' \
+ format. Mandatory.",
+ metavar="CRITERIA_FILE",
+ type=argparse.FileType('r'),
+ required=True)
+ argparser.add_argument('--criteriontypes',
+ help="Criterion types XML file, in \
+ '<criterion_types> \
+ <criterion_type name="" type=<inclusive|exclusive> values=<value1,value2,...>/> \
+ </criterion_types>' \
+ format. Mandatory.",
+ metavar="CRITERION_TYPE_FILE",
+ type=argparse.FileType('r'),
+ required=False)
+ argparser.add_argument('--initial-settings',
+ help="Initial XML settings file (containing a \
+ <ConfigurableDomains> tag",
+ nargs='?',
+ default=None,
+ metavar="XML_SETTINGS_FILE")
+ argparser.add_argument('--add-domains',
+ help="List of single domain files (each containing a single \
+ <ConfigurableDomain> tag",
+ metavar="XML_DOMAIN_FILE",
+ nargs='*',
+ dest='xml_domain_files',
+ default=[])
+ argparser.add_argument('--add-edds',
+ help="List of files in EDD syntax (aka \".pfw\" files)",
+ metavar="EDD_FILE",
+ type=argparse.FileType('r'),
+ nargs='*',
+ default=[],
+ dest='edd_files')
+ argparser.add_argument('--schemas-dir',
+ help="Directory of parameter-framework XML Schemas for generation \
+ validation",
+ default=None)
+ argparser.add_argument('--target-schemas-dir',
+ help="Ignored. Kept for retro-compatibility")
+ argparser.add_argument('--validate',
+ help="Validate the settings against XML schemas",
+ action='store_true')
+ argparser.add_argument('--verbose',
+ action='store_true')
+
+ return argparser.parse_args()
+
+#
+# Parses audio_criterion_types.xml / audio_criteria.xml files used at run time by the
+# engineconfigurable and outputs a dictionnary of criteria.
+# For each criteria, the name, type (aka inclusive (bitfield) or exclusive (enum), the values
+# are provided.
+#
+def parseCriteriaAndCriterionTypes(criteriaFile, criterionTypesFile):
+ # Parse criteria and criterion types XML files
+ #
+ criteria_tree = ET.parse(criteriaFile)
+ logging.info("Importing criteriaFile {}".format(criteriaFile))
+ criterion_types_tree = ET.parse(criterionTypesFile)
+ logging.info("Importing criterionTypesFile {}".format(criterionTypesFile))
+
+ criteria_root = criteria_tree.getroot()
+ criterion_types_root = criterion_types_tree.getroot()
+
+ all_criteria = []
+ for criterion in criteria_root.findall('criterion'):
+ criterion_name = criterion.get('name')
+ type_name = criterion.get('type')
+ logging.info("Importing criterion_name {}".format(criterion_name))
+ logging.info("Importing type_name {}".format(type_name))
+
+ for criterion_types in criterion_types_tree.findall('criterion_type'):
+ criterion_type_name = criterion_types.get('name')
+ if criterion_type_name == type_name:
+ criterion_inclusiveness = criterion_types.get('type')
+
+ criterion_values = []
+
+ values_node = criterion_types.find('values')
+ if values_node:
+ for value in values_node.findall('value'):
+ criterion_values.append(value.get('literal'))
+
+ if len(criterion_values) == 0:
+ criterion_values.append('')
+
+ logging.info("Importing criterion_type_name {}".format(criterion_type_name))
+ logging.info("Importing criterion_inclusiveness {}".format(criterion_inclusiveness))
+ logging.info("Importing criterion_values {}".format(criterion_values))
+
+ all_criteria.append({
+ "name" : criterion_name,
+ "inclusive" : criterion_inclusiveness,
+ "values" : criterion_values})
+ break
+
+ return all_criteria
+
+#
+# Parses the Edd files (aka .pfw extension file), which is a simplified language to write the
+# parameter framework settings.
+#
+def parseEdd(EDDFiles):
+ parsed_edds = []
+
+ for edd_file in EDDFiles:
+ try:
+ root = EddParser.Parser().parse(edd_file)
+ except EddParser.MySyntaxError as ex:
+ logging.critical(str(ex))
+ logging.info("EXIT ON FAILURE")
+ exit(2)
+
+ try:
+ root.propagate()
+ except EddParser.MyPropagationError, ex :
+ logging.critical(str(ex))
+ logging.info("EXIT ON FAILURE")
+ exit(1)
+
+ parsed_edds.append((edd_file.name, root))
+ return parsed_edds
+
+#
+# Generates all the required commands to be sent to the instance of parameter-framework launched
+# at runtime to generate the XML Settings file.
+# It takes as input the collection of criteria, the domains and the simplified settings read from
+# pfw.
+#
+def generateDomainCommands(logging, all_criteria, initial_settings, xml_domain_files, parsed_edds):
+ # create and inject all the criteria
+ logging.info("Creating all criteria")
+ for criterion in all_criteria:
+ yield ["createSelectionCriterion", criterion['inclusive'],
+ criterion['name']] + criterion['values']
+
+ yield ["start"]
+
+ # Import initial settings file
+ if initial_settings:
+ logging.info("Importing initial settings file {}".format(initial_settings))
+ yield ["importDomainsWithSettingsXML", initial_settings]
+
+ # Import each standalone domain files
+ for domain_file in xml_domain_files:
+ logging.info("Importing single domain file {}".format(domain_file))
+ yield ["importDomainWithSettingsXML", domain_file]
+
+ # Generate the script for each EDD file
+ for filename, parsed_edd in parsed_edds:
+ logging.info("Translating and injecting EDD file {}".format(filename))
+ translator = PfwScriptTranslator()
+ parsed_edd.translate(translator)
+ for command in translator.getScript():
+ yield command
+
+#
+# Entry point of the domain generator.
+# -Parses Criterion types and criteria files
+# -Parses settings written in simplified pfw language.
+# -Launches a parameter-framework
+# -Translates the settings into command that can be interpreted by parameter-framework.
+# -Use the exports command and output them in XML Settings file.
+#
+def main():
+ logging.root.setLevel(logging.INFO)
+ args = parseArgs()
+
+ all_criteria = parseCriteriaAndCriterionTypes(args.criteria, args.criteriontypes)
+
+ #
+ # EDD files (aka ".pfw" files)
+ #
+ parsed_edds = parseEdd(args.edd_files)
+
+ # We need to modify the toplevel configuration file to account for differences
+ # between development setup and target (installation) setup, in particular, the
+ # TuningMwith ode must be enforced, regardless of what will be allowed on the target
+ fake_toplevel_config = tempfile.NamedTemporaryFile(mode='w', delete=False, suffix=".xml",
+ prefix="TMPdomainGeneratorPFConfig_")
+
+ install_path = os.path.dirname(os.path.realpath(args.toplevel_config))
+ hostConfig.configure(
+ infile=args.toplevel_config,
+ outfile=fake_toplevel_config,
+ structPath=install_path)
+ fake_toplevel_config.close()
+
+ # Create the connector. Pipe its input to us in order to write commands;
+ # connect its output to stdout in order to have it dump the domains
+ # there; connect its error output to stderr.
+ connector = subprocess.Popen(["domainGeneratorConnector",
+ fake_toplevel_config.name,
+ 'verbose' if args.verbose else 'no-verbose',
+ 'validate' if args.validate else 'no-validate',
+ args.schemas_dir],
+ stdout=sys.stdout, stdin=subprocess.PIPE, stderr=sys.stderr)
+
+ initial_settings = None
+ if args.initial_settings:
+ initial_settings = os.path.realpath(args.initial_settings)
+
+ for command in generateDomainCommands(logging, all_criteria, initial_settings,
+ args.xml_domain_files, parsed_edds):
+ connector.stdin.write('\0'.join(command))
+ connector.stdin.write("\n")
+
+ # Closing the connector's input triggers the domain generation
+ connector.stdin.close()
+ connector.wait()
+ os.remove(fake_toplevel_config.name)
+ return connector.returncode
+
+# If this file is directly executed
+if __name__ == "__main__":
+ exit(main())
diff --git a/services/audiopolicy/engineconfigurable/tools/provision_criterion_types_from_android_headers.mk b/services/audiopolicy/engineconfigurable/tools/provision_criterion_types_from_android_headers.mk
new file mode 100644
index 0000000..4814376
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/tools/provision_criterion_types_from_android_headers.mk
@@ -0,0 +1,24 @@
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): MY_CRITERION_TYPES_FILE := $(CRITERION_TYPES_FILE)
+$(LOCAL_BUILT_MODULE): MY_ANDROID_AUDIO_BASE_HEADER_FILE := $(ANDROID_AUDIO_BASE_HEADER_FILE)
+$(LOCAL_BUILT_MODULE): MY_AUDIO_POLICY_CONFIGURATION_FILE := $(AUDIO_POLICY_CONFIGURATION_FILE)
+$(LOCAL_BUILT_MODULE): MY_CRITERION_TOOL := $(HOST_OUT)/bin/buildPolicyCriterionTypes.py
+$(LOCAL_BUILT_MODULE): $(LOCAL_REQUIRED_MODULES) $(LOCAL_ADDITIONAL_DEPENDENCIES) \
+ buildPolicyCriterionTypes.py \
+ $(CRITERION_TYPES_FILE) \
+ $(ANDROID_AUDIO_BASE_HEADER_FILE)
+
+ "$(MY_CRITERION_TOOL)" \
+ --androidaudiobaseheader "$(MY_ANDROID_AUDIO_BASE_HEADER_FILE)" \
+ --audiopolicyconfigurationfile "$(MY_AUDIO_POLICY_CONFIGURATION_FILE)" \
+ --criteriontypes "$(MY_CRITERION_TYPES_FILE)" \
+ --outputfile "$(@)"
+
+# Clear variables for further use
+CRITERION_TYPES_FILE :=
+ANDROID_AUDIO_BASE_HEADER_FILE :=
+AUDIO_POLICY_CONFIGURATION_FILE :=
diff --git a/services/audiopolicy/engineconfigurable/wrapper/Android.mk b/services/audiopolicy/engineconfigurable/wrapper/Android.mk
index b128a38..d19a364 100644
--- a/services/audiopolicy/engineconfigurable/wrapper/Android.mk
+++ b/services/audiopolicy/engineconfigurable/wrapper/Android.mk
@@ -1,5 +1,8 @@
LOCAL_PATH:= $(call my-dir)
+TOOLS := frameworks/av/services/audiopolicy/engineconfigurable/tools
+PROVISION_CRITERION_TYPES := $(TOOLS)/provision_criterion_types_from_android_headers.mk
+
##################################################################
# WRAPPER LIBRARY
##################################################################
@@ -10,12 +13,22 @@
$(LOCAL_PATH)/include \
frameworks/av/services/audiopolicy/engineconfigurable/include \
frameworks/av/services/audiopolicy/engineconfigurable/interface \
+ frameworks/av/services/audiopolicy/common/include \
+ external/libxml2/include \
+ external/icu/icu4c/source/common
-LOCAL_SRC_FILES:= ParameterManagerWrapper.cpp
+LOCAL_SRC_FILES:= \
+ ParameterManagerWrapper.cpp \
+ ParameterManagerWrapperConfig.cpp
LOCAL_SHARED_LIBRARIES := \
libparameter \
- libmedia_helper
+ libmedia_helper \
+ libicuuc \
+ libxml2
+
+LOCAL_STATIC_LIBRARIES := \
+ libaudiopolicycomponents
LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
@@ -31,11 +44,35 @@
# CONFIGURATION FILE
##################################################################
-# specific management of audio_policy_criteria.conf
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), 1)
+
include $(CLEAR_VARS)
-LOCAL_MODULE := audio_policy_criteria.conf
+LOCAL_MODULE := policy_wrapper_configuration.xml
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
+LOCAL_VENDOR_MODULE := true
LOCAL_SRC_FILES := config/$(LOCAL_MODULE)
include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := policy_criteria.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_SRC_FILES := config/$(LOCAL_MODULE)
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := policy_criterion_types.xml
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_ADDITIONAL_DEPENDENCIES := \
+ $(TARGET_OUT_VENDOR_ETC)/audio_policy_configuration.xml
+
+AUDIO_POLICY_CONFIGURATION_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_configuration.xml
+ANDROID_AUDIO_BASE_HEADER_FILE := system/media/audio/include/system/audio-base.h
+CRITERION_TYPES_FILE := $(LOCAL_PATH)/config/policy_criterion_types.xml.in
+
+include $(PROVISION_CRITERION_TYPES)
+
+endif #ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), 1)
diff --git a/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp b/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp
index 9b0442e..fc6c1e4 100644
--- a/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp
+++ b/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp
@@ -18,7 +18,7 @@
//#define LOG_NDEBUG 0
#include "ParameterManagerWrapper.h"
-#include "audio_policy_criteria_conf.h"
+#include "ParameterManagerWrapperConfig.h"
#include <ParameterMgrPlatformConnector.h>
#include <SelectionCriterionTypeInterface.h>
#include <SelectionCriterionInterface.h>
@@ -38,6 +38,7 @@
using std::string;
using std::map;
using std::vector;
+using CriterionTypes = std::map<std::string, ISelectionCriterionTypeInterface *>;
/// PFW related definitions
// Logger
@@ -56,16 +57,36 @@
}
};
-namespace android
-{
+namespace android {
using utilities::convertTo;
-namespace audio_policy
-{
+namespace audio_policy {
+
const char *const ParameterManagerWrapper::mPolicyPfwDefaultConfFileName =
"/etc/parameter-framework/ParameterFrameworkConfigurationPolicy.xml";
+static const char *const gInputDeviceCriterionName = "AvailableInputDevices";
+static const char *const gOutputDeviceCriterionName = "AvailableOutputDevices";
+static const char *const gPhoneStateCriterionName = "TelephonyMode";
+static const char *const gOutputDeviceAddressCriterionName = "AvailableOutputDevicesAddresses";
+static const char *const gInputDeviceAddressCriterionName = "AvailableInputDevicesAddresses";
+
+/**
+ * Order MUST be align with defintiion of audio_policy_force_use_t within audio_policy.h
+ */
+static const char *const gForceUseCriterionTag[AUDIO_POLICY_FORCE_USE_CNT] =
+{
+ [AUDIO_POLICY_FORCE_FOR_COMMUNICATION] = "ForceUseForCommunication",
+ [AUDIO_POLICY_FORCE_FOR_MEDIA] = "ForceUseForMedia",
+ [AUDIO_POLICY_FORCE_FOR_RECORD] = "ForceUseForRecord",
+ [AUDIO_POLICY_FORCE_FOR_DOCK] = "ForceUseForDock",
+ [AUDIO_POLICY_FORCE_FOR_SYSTEM] = "ForceUseForSystem",
+ [AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO] = "ForceUseForHdmiSystemAudio",
+ [AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND] = "ForceUseForEncodedSurround",
+ [AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING] = "ForceUseForVibrateRinging"
+};
+
template <>
struct ParameterManagerWrapper::parameterManagerElementSupported<ISelectionCriterionInterface> {};
template <>
@@ -80,15 +101,64 @@
// Logger
mPfwConnector->setLogger(mPfwConnectorLogger);
- // Load criteria file
- if ((loadAudioPolicyCriteriaConfig(gAudioPolicyCriteriaVendorConfFilePath) != NO_ERROR) &&
- (loadAudioPolicyCriteriaConfig(gAudioPolicyCriteriaConfFilePath) != NO_ERROR)) {
- ALOGE("%s: Neither vendor conf file (%s) nor system conf file (%s) could be found",
- __FUNCTION__, gAudioPolicyCriteriaVendorConfFilePath,
- gAudioPolicyCriteriaConfFilePath);
+ status_t loadResult = loadConfig();
+ if (loadResult < 0) {
+ ALOGE("Policy Wrapper configuration is partially invalid.");
}
}
+status_t ParameterManagerWrapper::loadConfig()
+{
+ auto result = wrapper_config::parse();
+ if (result.parsedConfig == nullptr) {
+ return -ENOENT;
+ }
+ ALOGE_IF(result.nbSkippedElement != 0, "skipped %zu elements", result.nbSkippedElement);
+
+ CriterionTypes criterionTypes;
+ for (auto criterionType : result.parsedConfig->criterionTypes) {
+ ALOG_ASSERT(criterionTypes.find(criterionType.name) == criterionTypes.end(),
+ "CriterionType %s already added", criterionType.name.c_str());
+ ALOGV("%s: Adding new criterionType %s", __FUNCTION__, criterionType.name.c_str());
+
+ auto criterionTypePfw =
+ mPfwConnector->createSelectionCriterionType(criterionType.isInclusive);
+
+ for (auto pair : criterionType.valuePairs) {
+ std::string error;
+ ALOGV("%s: Adding pair %d,%s for criterionType %s", __FUNCTION__, pair.first,
+ pair.second.c_str(), criterionType.name.c_str());
+ criterionTypePfw->addValuePair(pair.first, pair.second, error);
+ }
+ criterionTypes[criterionType.name] = criterionTypePfw;
+ }
+
+ for (auto criterion : result.parsedConfig->criteria) {
+ ALOG_ASSERT(mPolicyCriteria.find(criterion.name) == mPolicyCriteria.end(),
+ "%s: Criterion %s already added", __FUNCTION__, criterion.name.c_str());
+
+ auto criterionType =
+ getElement<ISelectionCriterionTypeInterface>(criterion.typeName, criterionTypes);
+ ALOG_ASSERT(criterionType != nullptr, "No %s Criterion type found for criterion %s",
+ criterion.typeName.c_str(), criterion.name.c_str());
+
+ auto criterionPfw = mPfwConnector->createSelectionCriterion(criterion.name, criterionType);
+ mPolicyCriteria[criterion.name] = criterionPfw;
+
+ if (not criterion.defaultLiteralValue.empty()) {
+ int numericalValue = 0;
+ if (not criterionType->getNumericalValue(criterion.defaultLiteralValue.c_str(),
+ numericalValue)) {
+ ALOGE("%s; trying to apply invalid default literal value (%s)", __FUNCTION__,
+ criterion.defaultLiteralValue.c_str());
+ continue;
+ }
+ criterionPfw->setCriterionState(numericalValue);
+ }
+ }
+ return result.nbSkippedElement == 0? NO_ERROR : BAD_VALUE;
+}
+
ParameterManagerWrapper::~ParameterManagerWrapper()
{
// Unset logger
@@ -112,112 +182,6 @@
return NO_ERROR;
}
-
-void ParameterManagerWrapper::addCriterionType(const string &typeName, bool isInclusive)
-{
- ALOG_ASSERT(mPolicyCriterionTypes.find(typeName) == mPolicyCriterionTypes.end(),
- "CriterionType %s already added", typeName.c_str());
- ALOGD("%s: Adding new criterionType %s", __FUNCTION__, typeName.c_str());
-
- mPolicyCriterionTypes[typeName] = mPfwConnector->createSelectionCriterionType(isInclusive);
-}
-
-void ParameterManagerWrapper::addCriterionTypeValuePair(
- const string &typeName,
- uint32_t numericValue,
- const string &literalValue)
-{
- ALOG_ASSERT(mPolicyCriterionTypes.find(typeName) != mPolicyCriterionTypes.end(),
- "CriterionType %s not found", typeName.c_str());
- ALOGV("%s: Adding new value pair (%d,%s) for criterionType %s", __FUNCTION__,
- numericValue, literalValue.c_str(), typeName.c_str());
- ISelectionCriterionTypeInterface *criterionType = mPolicyCriterionTypes[typeName];
- std::string error;
- criterionType->addValuePair(numericValue, literalValue, error);
-}
-
-void ParameterManagerWrapper::loadCriterionType(cnode *root, bool isInclusive)
-{
- ALOG_ASSERT(root != NULL, "error in parsing file");
- cnode *node;
- for (node = root->first_child; node != NULL; node = node->next) {
-
- ALOG_ASSERT(node != NULL, "error in parsing file");
- const char *typeName = node->name;
- char *valueNames = strndup(node->value, strlen(node->value));
-
- addCriterionType(typeName, isInclusive);
-
- uint32_t index = 0;
- char *ctx;
- char *valueName = strtok_r(valueNames, ",", &ctx);
- while (valueName != NULL) {
- if (strlen(valueName) != 0) {
-
- // Conf file may use or not pair, if no pair, use incremental index, else
- // use provided index.
- if (strchr(valueName, ':') != NULL) {
-
- char *first = strtok(valueName, ":");
- char *second = strtok(NULL, ":");
- ALOG_ASSERT((first != NULL) && (strlen(first) != 0) &&
- (second != NULL) && (strlen(second) != 0),
- "invalid value pair");
-
- if (!convertTo<string, uint32_t>(first, index)) {
- ALOGE("%s: Invalid index(%s) found", __FUNCTION__, first);
- }
- addCriterionTypeValuePair(typeName, index, second);
- } else {
-
- uint32_t pfwIndex = isInclusive ? 1 << index : index;
- addCriterionTypeValuePair(typeName, pfwIndex, valueName);
- index += 1;
- }
- }
- valueName = strtok_r(NULL, ",", &ctx);
- }
- free(valueNames);
- }
-}
-
-void ParameterManagerWrapper::loadInclusiveCriterionType(cnode *root)
-{
- ALOG_ASSERT(root != NULL, "error in parsing file");
- cnode *node = config_find(root, gInclusiveCriterionTypeTag.c_str());
- if (node == NULL) {
- return;
- }
- loadCriterionType(node, true);
-}
-
-void ParameterManagerWrapper::loadExclusiveCriterionType(cnode *root)
-{
- ALOG_ASSERT(root != NULL, "error in parsing file");
- cnode *node = config_find(root, gExclusiveCriterionTypeTag.c_str());
- if (node == NULL) {
- return;
- }
- loadCriterionType(node, false);
-}
-
-void ParameterManagerWrapper::parseChildren(cnode *root, string &defaultValue, string &type)
-{
- ALOG_ASSERT(root != NULL, "error in parsing file");
- cnode *node;
- for (node = root->first_child; node != NULL; node = node->next) {
- ALOG_ASSERT(node != NULL, "error in parsing file");
-
- if (string(node->name) == gDefaultTag) {
- defaultValue = node->value;
- } else if (string(node->name) == gTypeTag) {
- type = node->value;
- } else {
- ALOGE("%s: Unrecognized %s %s node", __FUNCTION__, node->name, node->value);
- }
- }
-}
-
template <typename T>
T *ParameterManagerWrapper::getElement(const string &name, std::map<string, T *> &elementsMap)
{
@@ -236,97 +200,6 @@
return it != elementsMap.end() ? it->second : NULL;
}
-void ParameterManagerWrapper::loadCriteria(cnode *root)
-{
- ALOG_ASSERT(root != NULL, "error in parsing file");
- cnode *node = config_find(root, gCriterionTag.c_str());
-
- if (node == NULL) {
- ALOGW("%s: no inclusive criteria found", __FUNCTION__);
- return;
- }
- for (node = node->first_child; node != NULL; node = node->next) {
- loadCriterion(node);
- }
-}
-
-void ParameterManagerWrapper::addCriterion(const string &name, const string &typeName,
- const string &defaultLiteralValue)
-{
- ALOG_ASSERT(mPolicyCriteria.find(name) == mPolicyCriteria.end(),
- "Route Criterion %s already added", name.c_str());
-
- ISelectionCriterionTypeInterface *criterionType =
- getElement<ISelectionCriterionTypeInterface>(typeName, mPolicyCriterionTypes);
-
- ISelectionCriterionInterface *criterion =
- mPfwConnector->createSelectionCriterion(name, criterionType);
-
- mPolicyCriteria[name] = criterion;
- int numericalValue = 0;
- if (!criterionType->getNumericalValue(defaultLiteralValue.c_str(), numericalValue)) {
- ALOGE("%s; trying to apply invalid default literal value (%s)", __FUNCTION__,
- defaultLiteralValue.c_str());
- }
- criterion->setCriterionState(numericalValue);
-}
-
-void ParameterManagerWrapper::loadCriterion(cnode *root)
-{
- ALOG_ASSERT(root != NULL, "error in parsing file");
- const char *criterionName = root->name;
-
- ALOG_ASSERT(mPolicyCriteria.find(criterionName) == mPolicyCriteria.end(),
- "Criterion %s already added", criterionName);
-
- string paramKeyName = "";
- string path = "";
- string typeName = "";
- string defaultValue = "";
-
- parseChildren(root, defaultValue, typeName);
-
- addCriterion(criterionName, typeName, defaultValue);
-}
-
-void ParameterManagerWrapper::loadConfig(cnode *root)
-{
- ALOG_ASSERT(root != NULL, "error in parsing file");
- cnode *node = config_find(root, gPolicyConfTag.c_str());
- if (node == NULL) {
- ALOGW("%s: Could not find node for pfw", __FUNCTION__);
- return;
- }
- ALOGD("%s: Loading conf for pfw", __FUNCTION__);
- loadInclusiveCriterionType(node);
- loadExclusiveCriterionType(node);
- loadCriteria(node);
-}
-
-
-status_t ParameterManagerWrapper::loadAudioPolicyCriteriaConfig(const char *path)
-{
- ALOG_ASSERT(path != NULL, "error in parsing file: empty path");
- cnode *root;
- char *data;
- ALOGD("%s", __FUNCTION__);
- data = (char *)load_file(path, NULL);
- if (data == NULL) {
- return -ENODEV;
- }
- root = config_node("", "");
- ALOG_ASSERT(root != NULL, "Unable to allocate a configuration node");
- config_load(root, data);
-
- loadConfig(root);
-
- config_free(root);
- free(root);
- free(data);
- ALOGD("%s: loaded", __FUNCTION__);
- return NO_ERROR;
-}
-
bool ParameterManagerWrapper::isStarted()
{
return mPfwConnector && mPfwConnector->isStarted();
@@ -335,9 +208,9 @@
status_t ParameterManagerWrapper::setPhoneState(audio_mode_t mode)
{
ISelectionCriterionInterface *criterion =
- getElement<ISelectionCriterionInterface>(gPhoneStateCriterionTag, mPolicyCriteria);
+ getElement<ISelectionCriterionInterface>(gPhoneStateCriterionName, mPolicyCriteria);
if (criterion == NULL) {
- ALOGE("%s: no criterion found for %s", __FUNCTION__, gPhoneStateCriterionTag.c_str());
+ ALOGE("%s: no criterion found for %s", __FUNCTION__, gPhoneStateCriterionName);
return BAD_VALUE;
}
if (!isValueValidForCriterion(criterion, static_cast<int>(mode))) {
@@ -351,9 +224,9 @@
audio_mode_t ParameterManagerWrapper::getPhoneState() const
{
const ISelectionCriterionInterface *criterion =
- getElement<ISelectionCriterionInterface>(gPhoneStateCriterionTag, mPolicyCriteria);
+ getElement<ISelectionCriterionInterface>(gPhoneStateCriterionName, mPolicyCriteria);
if (criterion == NULL) {
- ALOGE("%s: no criterion found for %s", __FUNCTION__, gPhoneStateCriterionTag.c_str());
+ ALOGE("%s: no criterion found for %s", __FUNCTION__, gPhoneStateCriterionName);
return AUDIO_MODE_NORMAL;
}
return static_cast<audio_mode_t>(criterion->getCriterionState());
@@ -370,7 +243,7 @@
ISelectionCriterionInterface *criterion =
getElement<ISelectionCriterionInterface>(gForceUseCriterionTag[usage], mPolicyCriteria);
if (criterion == NULL) {
- ALOGE("%s: no criterion found for %s", __FUNCTION__, gForceUseCriterionTag[usage].c_str());
+ ALOGE("%s: no criterion found for %s", __FUNCTION__, gForceUseCriterionTag[usage]);
return BAD_VALUE;
}
if (!isValueValidForCriterion(criterion, static_cast<int>(config))) {
@@ -390,7 +263,7 @@
const ISelectionCriterionInterface *criterion =
getElement<ISelectionCriterionInterface>(gForceUseCriterionTag[usage], mPolicyCriteria);
if (criterion == NULL) {
- ALOGE("%s: no criterion found for %s", __FUNCTION__, gForceUseCriterionTag[usage].c_str());
+ ALOGE("%s: no criterion found for %s", __FUNCTION__, gForceUseCriterionTag[usage]);
return AUDIO_POLICY_FORCE_NONE;
}
return static_cast<audio_policy_forced_cfg_t>(criterion->getCriterionState());
@@ -404,12 +277,45 @@
return interface->getLiteralValue(valueToCheck, literalValue);
}
+status_t ParameterManagerWrapper::setDeviceConnectionState(const sp<DeviceDescriptor> devDesc,
+ audio_policy_dev_state_t state)
+{
+ std::string criterionName = audio_is_output_device(devDesc->type()) ?
+ gOutputDeviceAddressCriterionName : gInputDeviceAddressCriterionName;
+
+ ALOGV("%s: device with address %s %s", __FUNCTION__, devDesc->mAddress.string(),
+ state != AUDIO_POLICY_DEVICE_STATE_AVAILABLE? "disconnected" : "connected");
+ ISelectionCriterionInterface *criterion =
+ getElement<ISelectionCriterionInterface>(criterionName, mPolicyCriteria);
+
+ if (criterion == NULL) {
+ ALOGE("%s: no criterion found for %s", __FUNCTION__, criterionName.c_str());
+ return DEAD_OBJECT;
+ }
+
+ auto criterionType = criterion->getCriterionType();
+ int deviceAddressId;
+ if (not criterionType->getNumericalValue(devDesc->mAddress.string(), deviceAddressId)) {
+ ALOGE("%s: unknown device address reported (%s)", __FUNCTION__, devDesc->mAddress.c_str());
+ return BAD_TYPE;
+ }
+ int currentValueMask = criterion->getCriterionState();
+ if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
+ currentValueMask |= deviceAddressId;
+ }
+ else {
+ currentValueMask &= ~deviceAddressId;
+ }
+ criterion->setCriterionState(currentValueMask);
+ return NO_ERROR;
+}
+
status_t ParameterManagerWrapper::setAvailableInputDevices(audio_devices_t inputDevices)
{
ISelectionCriterionInterface *criterion =
- getElement<ISelectionCriterionInterface>(gInputDeviceCriterionTag, mPolicyCriteria);
+ getElement<ISelectionCriterionInterface>(gInputDeviceCriterionName, mPolicyCriteria);
if (criterion == NULL) {
- ALOGE("%s: no criterion found for %s", __FUNCTION__, gInputDeviceCriterionTag.c_str());
+ ALOGE("%s: no criterion found for %s", __FUNCTION__, gInputDeviceCriterionName);
return DEAD_OBJECT;
}
criterion->setCriterionState(inputDevices & ~AUDIO_DEVICE_BIT_IN);
@@ -420,9 +326,9 @@
status_t ParameterManagerWrapper::setAvailableOutputDevices(audio_devices_t outputDevices)
{
ISelectionCriterionInterface *criterion =
- getElement<ISelectionCriterionInterface>(gOutputDeviceCriterionTag, mPolicyCriteria);
+ getElement<ISelectionCriterionInterface>(gOutputDeviceCriterionName, mPolicyCriteria);
if (criterion == NULL) {
- ALOGE("%s: no criterion found for %s", __FUNCTION__, gOutputDeviceCriterionTag.c_str());
+ ALOGE("%s: no criterion found for %s", __FUNCTION__, gOutputDeviceCriterionName);
return DEAD_OBJECT;
}
criterion->setCriterionState(outputDevices);
diff --git a/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapperConfig.cpp b/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapperConfig.cpp
new file mode 100644
index 0000000..bc6d046
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapperConfig.cpp
@@ -0,0 +1,208 @@
+/*
+ * 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 "APM::AudioPolicyEngine/PFWWrapperConfig"
+#define LOG_NDEBUG 0
+
+#include "ParameterManagerWrapperConfig.h"
+
+#include <media/convert.h>
+#include <utils/Log.h>
+#include <libxml/parser.h>
+#include <libxml/xinclude.h>
+#include <string>
+#include <vector>
+#include <sstream>
+#include <istream>
+
+
+namespace android {
+
+using utilities::convertTo;
+
+namespace audio_policy {
+namespace wrapper_config {
+namespace detail {
+
+std::string getXmlAttribute(const xmlNode *cur, const char *attribute)
+{
+ xmlChar *xmlValue = xmlGetProp(cur, (const xmlChar *)attribute);
+ if (xmlValue == NULL) {
+ return "";
+ }
+ std::string value((const char *)xmlValue);
+ xmlFree(xmlValue);
+ return value;
+}
+
+template <class Trait>
+static status_t deserializeCollection(_xmlDoc *doc, const _xmlNode *cur,
+ typename Trait::Collection &collection,
+ size_t &nbSkippedElement)
+{
+ const xmlNode *root = cur->xmlChildrenNode;
+ while (root != NULL) {
+ if (xmlStrcmp(root->name, (const xmlChar *)Trait::collectionTag) &&
+ xmlStrcmp(root->name, (const xmlChar *)Trait::tag)) {
+ root = root->next;
+ continue;
+ }
+ const xmlNode *child = root;
+ if (!xmlStrcmp(child->name, (const xmlChar *)Trait::collectionTag)) {
+ child = child->xmlChildrenNode;
+ }
+ while (child != NULL) {
+ if (!xmlStrcmp(child->name, (const xmlChar *)Trait::tag)) {
+ status_t status = Trait::deserialize(doc, child, collection);
+ if (status == NO_ERROR) {
+ nbSkippedElement += 1;
+ }
+ }
+ child = child->next;
+ }
+ if (!xmlStrcmp(root->name, (const xmlChar *)Trait::tag)) {
+ return NO_ERROR;
+ }
+ root = root->next;
+ }
+ return NO_ERROR;
+}
+
+const char *const ValueTraits::tag = "value";
+const char *const ValueTraits::collectionTag = "values";
+
+const char ValueTraits::Attributes::literal[] = "literal";
+const char ValueTraits::Attributes::numerical[] = "numerical";
+
+status_t ValueTraits::deserialize(_xmlDoc */*doc*/, const _xmlNode *child, Collection &values)
+{
+ std::string literal = getXmlAttribute(child, Attributes::literal);
+ if (literal.empty()) {
+ ALOGE("%s: No attribute %s found", __FUNCTION__, Attributes::literal);
+ return BAD_VALUE;
+ }
+ uint32_t numerical = 0;
+ std::string numericalTag = getXmlAttribute(child, Attributes::numerical);
+ if (numericalTag.empty()) {
+ ALOGE("%s: No attribute %s found", __FUNCTION__, Attributes::literal);
+ return BAD_VALUE;
+ }
+ if (!convertTo(numericalTag, numerical)) {
+ ALOGE("%s: : Invalid value(%s)", __FUNCTION__, numericalTag.c_str());
+ return BAD_VALUE;
+ }
+ values.push_back({numerical, literal});
+ return NO_ERROR;
+}
+
+const char *const CriterionTypeTraits::tag = "criterion_type";
+const char *const CriterionTypeTraits::collectionTag = "criterion_types";
+
+const char CriterionTypeTraits::Attributes::name[] = "name";
+const char CriterionTypeTraits::Attributes::type[] = "type";
+
+status_t CriterionTypeTraits::deserialize(_xmlDoc *doc, const _xmlNode *child,
+ Collection &criterionTypes)
+{
+ std::string name = getXmlAttribute(child, Attributes::name);
+ if (name.empty()) {
+ ALOGE("%s: No attribute %s found", __FUNCTION__, Attributes::name);
+ return BAD_VALUE;
+ }
+ ALOGV("%s: %s %s = %s", __FUNCTION__, tag, Attributes::name, name.c_str());
+
+ std::string type = getXmlAttribute(child, Attributes::type);
+ if (type.empty()) {
+ ALOGE("%s: No attribute %s found", __FUNCTION__, Attributes::type);
+ return BAD_VALUE;
+ }
+ ALOGV("%s: %s %s = %s", __FUNCTION__, tag, Attributes::type, type.c_str());
+ bool isInclusive(type == "inclusive");
+
+ ValuePairs pairs;
+ size_t nbSkippedElements = 0;
+ detail::deserializeCollection<detail::ValueTraits>(doc, child, pairs, nbSkippedElements);
+
+ criterionTypes.push_back({name, isInclusive, pairs});
+ return NO_ERROR;
+}
+
+const char *const CriterionTraits::tag = "criterion";
+const char *const CriterionTraits::collectionTag = "criteria";
+
+const char CriterionTraits::Attributes::name[] = "name";
+const char CriterionTraits::Attributes::type[] = "type";
+const char CriterionTraits::Attributes::defaultVal[] = "default";
+
+status_t CriterionTraits::deserialize(_xmlDoc */*doc*/, const _xmlNode *child, Collection &criteria)
+{
+ std::string name = getXmlAttribute(child, Attributes::name);
+ if (name.empty()) {
+ ALOGE("%s: No attribute %s found", __FUNCTION__, Attributes::name);
+ return BAD_VALUE;
+ }
+ ALOGV("%s: %s = %s", __FUNCTION__, Attributes::name, name.c_str());
+
+ std::string defaultValue = getXmlAttribute(child, Attributes::defaultVal);
+ if (defaultValue.empty()) {
+ // Not mandatory to provide a default value for a criterion, even it is recommanded...
+ ALOGV("%s: No attribute %s found", __FUNCTION__, Attributes::defaultVal);
+ }
+ ALOGV("%s: %s = %s", __FUNCTION__, Attributes::defaultVal, defaultValue.c_str());
+
+ std::string typeName = getXmlAttribute(child, Attributes::type);
+ if (typeName.empty()) {
+ ALOGE("%s: No attribute %s found", __FUNCTION__, Attributes::name);
+ return BAD_VALUE;
+ }
+ ALOGV("%s: %s = %s", __FUNCTION__, Attributes::type, typeName.c_str());
+
+ criteria.push_back({name, typeName, defaultValue});
+ return NO_ERROR;
+}
+} // namespace detail
+
+ParsingResult parse(const char* path) {
+ xmlDocPtr doc;
+ doc = xmlParseFile(path);
+ if (doc == NULL) {
+ ALOGE("%s: Could not parse document %s", __FUNCTION__, path);
+ return {nullptr, 0};
+ }
+ xmlNodePtr cur = xmlDocGetRootElement(doc);
+ if (cur == NULL) {
+ ALOGE("%s: Could not parse: empty document %s", __FUNCTION__, path);
+ xmlFreeDoc(doc);
+ return {nullptr, 0};
+ }
+ if (xmlXIncludeProcess(doc) < 0) {
+ ALOGE("%s: libxml failed to resolve XIncludes on document %s", __FUNCTION__, path);
+ return {nullptr, 0};
+ }
+ size_t nbSkippedElements = 0;
+ auto config = std::make_unique<Config>();
+
+ detail::deserializeCollection<detail::CriterionTraits>(
+ doc, cur, config->criteria, nbSkippedElements);
+ detail::deserializeCollection<detail::CriterionTypeTraits>(
+ doc, cur, config->criterionTypes, nbSkippedElements);
+
+ return {std::move(config), nbSkippedElements};
+}
+
+} // namespace wrapper_config
+} // namespace audio_policy
+} // namespace android
diff --git a/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapperConfig.h b/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapperConfig.h
new file mode 100644
index 0000000..467d0e1
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapperConfig.h
@@ -0,0 +1,139 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <string>
+#include <vector>
+#include <utils/Errors.h>
+
+struct _xmlNode;
+struct _xmlDoc;
+
+namespace android {
+namespace audio_policy {
+namespace wrapper_config {
+
+/** Default path of audio policy usages configuration file. */
+constexpr char DEFAULT_PATH[] = "/vendor/etc/policy_wrapper_configuration.xml";
+
+/** Directories where the effect libraries will be search for. */
+constexpr const char* POLICY_USAGE_LIBRARY_PATH[] = {"/odm/etc/", "/vendor/etc/", "/system/etc/"};
+
+using ValuePair = std::pair<uint32_t, std::string>;
+using ValuePairs = std::vector<ValuePair>;
+
+struct CriterionType
+{
+ std::string name;
+ bool isInclusive;
+ ValuePairs valuePairs;
+};
+
+using CriterionTypes = std::vector<CriterionType>;
+
+struct Criterion
+{
+ std::string name;
+ std::string typeName;
+ std::string defaultLiteralValue;
+};
+
+using Criteria = std::vector<Criterion>;
+
+struct Config {
+ float version;
+ Criteria criteria;
+ CriterionTypes criterionTypes;
+};
+
+namespace detail
+{
+struct ValueTraits
+{
+ static const char *const tag;
+ static const char *const collectionTag;
+
+ struct Attributes
+ {
+ static const char literal[];
+ static const char numerical[];
+ };
+
+ typedef ValuePair Element;
+ typedef ValuePair *PtrElement;
+ typedef ValuePairs Collection;
+
+ static android::status_t deserialize(_xmlDoc *doc, const _xmlNode *root,
+ Collection &collection);
+};
+
+struct CriterionTypeTraits
+{
+ static const char *const tag;
+ static const char *const collectionTag;
+
+ struct Attributes
+ {
+ static const char name[];
+ static const char type[];
+ };
+
+ typedef CriterionType Element;
+ typedef CriterionType *PtrElement;
+ typedef CriterionTypes Collection;
+
+ static android::status_t deserialize(_xmlDoc *doc, const _xmlNode *root,
+ Collection &collection);
+};
+
+struct CriterionTraits
+{
+ static const char *const tag;
+ static const char *const collectionTag;
+
+ struct Attributes
+ {
+ static const char name[];
+ static const char type[];
+ static const char defaultVal[];
+ };
+
+ typedef Criterion Element;
+ typedef Criterion *PtrElement;
+ typedef Criteria Collection;
+
+ static android::status_t deserialize(_xmlDoc *doc, const _xmlNode *root,
+ Collection &collection);
+};
+} // namespace detail
+
+/** Result of `parse(const char*)` */
+struct ParsingResult {
+ /** Parsed config, nullptr if the xml lib could not load the file */
+ std::unique_ptr<Config> parsedConfig;
+ size_t nbSkippedElement; //< Number of skipped invalid product strategies
+};
+
+/** Parses the provided audio policy usage configuration.
+ * @return audio policy usage @see Config
+ */
+ParsingResult parse(const char* path = DEFAULT_PATH);
+
+} // namespace wrapper_config
+} // namespace audio_policy
+} // android
diff --git a/services/audiopolicy/engineconfigurable/wrapper/audio_policy_criteria_conf.h b/services/audiopolicy/engineconfigurable/wrapper/audio_policy_criteria_conf.h
deleted file mode 100644
index e4fd176..0000000
--- a/services/audiopolicy/engineconfigurable/wrapper/audio_policy_criteria_conf.h
+++ /dev/null
@@ -1,73 +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.
- */
-
-#pragma once
-
-#include <string>
-#include <system/audio_policy.h>
-
-//////////////////////////////////////////////////////////////////////////////////////////////////
-// Definitions for audio policy criteria configuration file (audio_policy_criteria.conf) //
-// //
-// @TODO: scripted from audio.h & audio_policy,h //
-//////////////////////////////////////////////////////////////////////////////////////////////////
-
-static const char *const gAudioPolicyCriteriaConfFilePath =
- "/system/etc/audio_policy_criteria.conf";
-static const char *const gAudioPolicyCriteriaVendorConfFilePath =
- "/vendor/etc/audio_policy_criteria.conf";
-
-/**
- * PFW instances tags
- */
-static const std::string &gPolicyConfTag = "Policy";
-static const std::string &gDefaultTag = "Default";
-static const std::string &gTypeTag = "Type";
-
-/**
- * PFW elements tags
- */
-static const std::string &gInclusiveCriterionTypeTag = "InclusiveCriterionType";
-static const std::string &gExclusiveCriterionTypeTag = "ExclusiveCriterionType";
-static const std::string &gCriterionTag = "Criterion";
-
-/**
- * PFW known criterion tags
- */
-static const std::string &gInputDeviceCriterionTag = "AvailableInputDevices";
-static const std::string &gOutputDeviceCriterionTag = "AvailableOutputDevices";
-static const std::string &gPhoneStateCriterionTag = "TelephonyMode";
-
-/**
- * Order MUST be align with defintiion of audio_policy_force_use_t within audio_policy.h
- */
-static const std::string gForceUseCriterionTag[AUDIO_POLICY_FORCE_USE_CNT] =
-{
- [AUDIO_POLICY_FORCE_FOR_COMMUNICATION] = "ForceUseForCommunication",
- [AUDIO_POLICY_FORCE_FOR_MEDIA] = "ForceUseForMedia",
- [AUDIO_POLICY_FORCE_FOR_RECORD] = "ForceUseForRecord",
- [AUDIO_POLICY_FORCE_FOR_DOCK] = "ForceUseForDock",
- [AUDIO_POLICY_FORCE_FOR_SYSTEM] = "ForceUseForSystem",
- [AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO] = "ForceUseForHdmiSystemAudio",
- [AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND] = "ForceUseForEncodedSurround",
- [AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING] = "ForceUseForVibrateRinging"
-};
-
-
-
-
-
-
diff --git a/services/audiopolicy/engineconfigurable/wrapper/config/audio_policy_criteria.conf b/services/audiopolicy/engineconfigurable/wrapper/config/audio_policy_criteria.conf
deleted file mode 100644
index 043d5a6..0000000
--- a/services/audiopolicy/engineconfigurable/wrapper/config/audio_policy_criteria.conf
+++ /dev/null
@@ -1,146 +0,0 @@
-################################################################################################
-#
-# @NOTE:
-# Audio Policy Criteria file example for generic device build
-#
-# Any vendor shall have its own configuration within the corresponding device folder
-#
-################################################################################################
-
-#########################################################
-# Criterion type Example:
-# For each criterion, a couple of numerical, literal values must be provided to the PFW.
-# The numerical part is not mandatory. If not filled by the user, a default numerical value will be
-# automatically provided by audio HAL using the following logic:
-# - Exclusive criterion:
-# * 0 -> first literal value,
-# * 1 -> second literal value,
-# ...
-# * N -> (N+1)th literal value.
-# - Inclusive criterion:
-# * 1 << 0 -> first literal value,
-# * 1 << 1 -> second literal value,
-# ...
-# * 1 << N -> (N+1)th literal value,
-#
-#########################################################
-# Policy {
-# InclusiveCriterionType|ExclusiveCriterionType {
-# <Criterion Name> [numerical value 1:]<literal value 1>,[numerical value 2:]<literal value 2>,<literal value 3>,...
-# }
-# }
-
-#########################################################
-# Criterion:
-#########################################################
-# Policy {
-# Criterion {
-# <Criterion Name> {
-# Type <Criterion type name>
-# Default <default value of the criterion>
-# }
-# }
-# }
-
-Policy {
- InclusiveCriterionType {
- #
- # DO NOT CHANGE ORDER. This definition must be aligned with the definition of
- # AUDIO_DEVICE_OUT_* within <system/audio.h> file of android.
- #
- OutputDevicesMaskType Earpiece,Speaker,WiredHeadset,WiredHeadphone,BluetoothSco,BluetoothScoHeadset,BluetoothScoCarkit,BluetoothA2dp,BluetoothA2dpHeadphones,BluetoothA2dpSpeaker,Hdmi,AnlgDockHeadset,DgtlDockHeadset,UsbAccessory,UsbDevice,RemoteSubmix,TelephonyTx,Line,HdmiArc,Spdif,Fm,AuxLine,SpeakerSafe
- #
- # DO NOT CHANGE ORDER. This definition must be aligned with the definition of
- # AUDIO_DEVICE_IN_* within <system/audio.h> file of android.
- # Note also that direction bit will be decimated by AudioHAL in order to allow using a mask
- # with the cardinality of 1 between a bit and an input device.
- #
- InputDevicesMaskType Communication,Ambient,BuiltinMic,BluetoothScoHeadset,WiredHeadset,Hdmi,TelephonyRx,BackMic,RemoteSubmix,AnlgDockHeadset,DgtlDockHeadset,UsbAccessory,UsbDevice,FmTuner,TvTune,Line,Spdif,BluetoothA2dp,Loopback
- }
- ExclusiveCriterionType {
- #
- # The values of the mode MUST be aligned with the definition of the audio_mode_t
- # from system/audio.h
- #
- AndroidModeType 0:Normal,1:RingTone,2:InCall,3:InCommunication
- #
- # The values of the mode MUST be aligned with the definition of the
- # audio_policy_forced_config_t from system/audio.h
- #
- ForceUseForCommunicationType 0:ForceNone,1:ForceSpeaker,3:ForceBtSco
- #
- # The values of the mode MUST be aligned with the definition of the
- # audio_policy_forced_config_t from system/audio.h
- #
- ForceUseForMediaType 0:ForceNone,1:ForceSpeaker,2:ForceHeadphones,4:ForceBtA2dp,5:ForceWiredAccessory,8:ForceAnalogDock,9:ForceDigitalDock,10:ForceNoBtA2dp
- #
- # The values of the mode MUST be aligned with the definition of the
- # audio_policy_forced_config_t from system/audio.h
- #
- ForceUseForRecordType 0:ForceNone,3:ForceBtSco,5:ForceWiredAccessory
- #
- # The values of the mode MUST be aligned with the definition of the
- # audio_policy_forced_config_t from system/audio.h
- #
- ForceUseForDockType 0:ForceNone,5:ForceWiredAccessory,6:ForceBtCarDock,7:ForceBtDeskDock,8:ForceAnalogDock,9:ForceDigitalDock
- #
- # The values of the mode MUST be aligned with the definition of the
- # audio_policy_forced_config_t from system/audio.h
- #
- ForceUseForSystemType 0:ForceNone,11:ForceSystemEnforced
- #
- # The values of the mode MUST be aligned with the definition of the
- # audio_policy_forced_config_t from system/audio.h
- #
- ForceUseForHdmiSystemAudioType 0:ForceNone,12:ForceHdmiSystemEnforced
- #
- # The values of the mode MUST be aligned with the definition of the
- # audio_policy_forced_config_t from system/audio_policy.h
- #
- ForceUseForEncodedSurroundType 0:ForceNone,13:ForceEncodedSurroundNever,14:ForceEncodedSurroundAlways
- }
-
- Criterion {
- AvailableInputDevices {
- Type InputDevicesMaskType
- Default none
- }
- AvailableOutputDevices {
- Type OutputDevicesMaskType
- Default none
- }
- TelephonyMode {
- Type AndroidModeType
- Default Normal
- }
- ForceUseForCommunication {
- Type ForceUseForCommunicationType
- Default ForceNone
- }
- ForceUseForMedia {
- Type ForceUseForMediaType
- Default ForceNone
- }
- ForceUseForRecord {
- Type ForceUseForRecordType
- Default ForceNone
- }
- ForceUseForDock {
- Type ForceUseForDockType
- Default ForceNone
- }
- ForceUseForSystem {
- Type ForceUseForSystemType
- Default ForceNone
- }
- ForceUseForHdmiSystemAudio {
- Type ForceUseForHdmiSystemAudioType
- Default ForceNone
- }
- ForceUseForEncodedSurround {
- Type ForceUseForEncodedSurroundType
- Default ForceNone
- }
- }
-}
-
diff --git a/services/audiopolicy/engineconfigurable/wrapper/config/policy_criteria.xml b/services/audiopolicy/engineconfigurable/wrapper/config/policy_criteria.xml
new file mode 100644
index 0000000..ec82b2e
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/wrapper/config/policy_criteria.xml
@@ -0,0 +1,30 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- 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.
+-->
+<criteria>
+ <criterion name="AvailableInputDevices" type="InputDevicesMaskType" default="none"/>
+ <criterion name="AvailableOutputDevices" type="OutputDevicesMaskType" default="none"/>
+ <criterion name="AvailableOutputDevicesAddresses" type="OutputDevicesAddressesType" default="none"/>
+ <criterion name="AvailableInputDevicesAddresses" type="InputDevicesAddressesType" default="none"/>
+ <criterion name="TelephonyMode" type="AndroidModeType" default="Normal"/>
+ <criterion name="ForceUseForCommunication" type="ForceUseForCommunicationType" default="ForceNone"/>
+ <criterion name="ForceUseForMedia" type="ForceUseForMediaType" default="ForceNone"/>
+ <criterion name="ForceUseForRecord" type="ForceUseForRecordType" default="ForceNone"/>
+ <criterion name="ForceUseForDock" type="ForceUseForDockType" default="ForceNone"/>
+ <criterion name="ForceUseForSystem" type="ForceUseForSystemType" default="ForceNone"/>
+ <criterion name="ForceUseForHdmiSystemAudio" type="ForceUseForHdmiSystemAudioType" default="ForceNone"/>
+ <criterion name="ForceUseForEncodedSurround" type="ForceUseForEncodedSurroundType" default="ForceNone"/>
+ <criterion name="ForceUseForVibrateRinging" type="ForceUseForVibrateRingingType" default="ForceNone"/>
+</criteria>
diff --git a/services/audiopolicy/engineconfigurable/wrapper/config/policy_criterion_types.xml.in b/services/audiopolicy/engineconfigurable/wrapper/config/policy_criterion_types.xml.in
new file mode 100644
index 0000000..6cb799f
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/wrapper/config/policy_criterion_types.xml.in
@@ -0,0 +1,91 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- 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.
+-->
+<criterion_types>
+ <criterion_type name="OutputDevicesMaskType" type="inclusive"/>
+ <criterion_type name="InputDevicesMaskType" type="inclusive"/>
+ <criterion_type name="OutputDevicesAddressesType" type="inclusive"/>
+ <criterion_type name="InputDevicesAddressesType" type="inclusive"/>
+ <criterion_type name="AndroidModeType" type="exclusive"/>
+ <criterion_type name="BooleanType" type="exclusive">
+ <values>
+ <value literal="False" numerical="0"/>
+ <value literal="True" numerical="1"/>
+ </values>
+ </criterion_type>
+ <criterion_type name="ForceUseForCommunicationType" type="exclusive">
+ <values>
+ <value literal="ForceNone" numerical="0"/>
+ <value literal="ForceSpeaker" numerical="1"/>
+ <value literal="ForceBtSco" numerical="3"/>
+ </values>
+ </criterion_type>
+ <criterion_type name="ForceUseForMediaType" type="exclusive">
+ <values>
+ <value literal="ForceNone" numerical="0"/>
+ <value literal="ForceSpeaker" numerical="1"/>
+ <value literal="ForceHeadphones" numerical="2"/>
+ <value literal="ForceBtA2dp" numerical="4"/>
+ <value literal="ForceWiredAccessory" numerical="5"/>
+ <value literal="ForceAnalogDock" numerical="8"/>
+ <value literal="ForceDigitalDock" numerical="9"/>
+ <value literal="ForceNoBtA2dp" numerical="10"/>
+ </values>
+ </criterion_type>
+ <criterion_type name="ForceUseForRecordType" type="exclusive">
+ <values>
+ <value literal="ForceNone" numerical="0"/>
+ <value literal="ForceBtSco" numerical="3"/>
+ <value literal="ForceWiredAccessory" numerical="5"/>
+ </values>
+ </criterion_type>
+ <criterion_type name="ForceUseForDockType" type="exclusive">
+ <values>
+ <value literal="ForceNone" numerical="0"/>
+ <value literal="ForceWiredAccessory" numerical="5"/>
+ <value literal="ForceBtCarDock" numerical="6"/>
+ <value literal="ForceBtDeskDock" numerical="7"/>
+ <value literal="ForceAnalogDock" numerical="8"/>
+ <value literal="ForceDigitalDock" numerical="9"/>
+ </values>
+ </criterion_type>
+ <criterion_type name="ForceUseForSystemType" type="exclusive" >
+ <values>
+ <value literal="ForceNone" numerical="0"/>
+ <value literal="ForceSystemEnforced" numerical="11"/>
+ </values>
+ </criterion_type>
+ <criterion_type name="ForceUseForHdmiSystemAudioType" type="exclusive">
+ <values>
+ <value literal="ForceNone" numerical="0"/>
+ <value literal="ForceHdmiSystemEnforced" numerical="12"/>
+ </values>
+ </criterion_type>
+ <criterion_type name="ForceUseForEncodedSurroundType" type="exclusive">
+ <values>
+ <value literal="ForceNone" numerical="0"/>
+ <value literal="ForceEncodedSurroundNever" numerical="13"/>
+ <value literal="ForceEncodedSurroundAlways" numerical="14"/>
+ </values>
+ </criterion_type>
+ <criterion_type name="ForceUseForVibrateRingingType" type="exclusive">
+ <values>
+ <value literal="ForceNone" numerical="0"/>
+ <value literal="ForceBtSco" numerical="3"/>
+ </values>
+ </criterion_type>
+</criterion_types>
+
+
diff --git a/services/audiopolicy/engineconfigurable/wrapper/config/policy_wrapper_configuration.xml b/services/audiopolicy/engineconfigurable/wrapper/config/policy_wrapper_configuration.xml
new file mode 100644
index 0000000..5d9193b
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/wrapper/config/policy_wrapper_configuration.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!-- 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.
+-->
+<!--
+ These are the minimum required criteria to be used by Audio HAL to ensure a basic
+ user experience on an Android device
+-->
+<configuration name="audio_policy_wrapper_configuration" xmlns:xi="http://www.w3.org/2001/XInclude">
+
+ <xi:include href="policy_criterion_types.xml"/>
+ <xi:include href="policy_criteria.xml"/>
+
+</configuration>
diff --git a/services/audiopolicy/engineconfigurable/wrapper/include/ParameterManagerWrapper.h b/services/audiopolicy/engineconfigurable/wrapper/include/ParameterManagerWrapper.h
index 4c1acfe..1a634a1 100644
--- a/services/audiopolicy/engineconfigurable/wrapper/include/ParameterManagerWrapper.h
+++ b/services/audiopolicy/engineconfigurable/wrapper/include/ParameterManagerWrapper.h
@@ -16,10 +16,15 @@
#pragma once
+#include <AudioGain.h>
+#include <AudioPort.h>
+#include <HwModule.h>
+#include <DeviceDescriptor.h>
#include <system/audio.h>
#include <system/audio_policy.h>
#include <utils/Errors.h>
#include <utils/RWLock.h>
+#include <utils/RefBase.h>
#include <list>
#include <map>
#include <string>
@@ -27,27 +32,17 @@
class CParameterMgrPlatformConnector;
class ISelectionCriterionInterface;
-class ISelectionCriterionTypeInterface;
struct cnode;
class ParameterMgrPlatformConnectorLogger;
-namespace android
-{
-namespace audio_policy
-{
+namespace android {
+namespace audio_policy {
class ParameterManagerWrapper
{
private:
- typedef std::pair<int, const char *> CriterionTypeValuePair;
-
- typedef std::map<std::string, ISelectionCriterionInterface *> CriterionCollection;
- typedef std::map<std::string, ISelectionCriterionTypeInterface *> CriterionTypeCollection;
- typedef CriterionCollection::iterator CriterionMapIterator;
- typedef CriterionCollection::const_iterator CriterionMapConstIterator;
- typedef CriterionTypeCollection::iterator CriterionTypeMapIterator;
- typedef CriterionTypeCollection::const_iterator CriteriaTypeMapConstIterator;
+ using Criteria = std::map<std::string, ISelectionCriterionInterface *>;
public:
ParameterManagerWrapper();
@@ -120,6 +115,9 @@
*/
status_t setAvailableOutputDevices(audio_devices_t outputDevices);
+ status_t setDeviceConnectionState(const sp<DeviceDescriptor> devDesc,
+ audio_policy_dev_state_t state);
+
private:
/**
* Apply the configuration of the platform on the policy parameter manager.
@@ -136,93 +134,11 @@
/**
* Load the criterion configuration file.
*
- * @param[in] path Criterion conf file path.
- *
* @return NO_ERROR is parsing successful, error code otherwise.
*/
- status_t loadAudioPolicyCriteriaConfig(const char *path);
+ status_t loadConfig();
- /**
- * Add a criterion type to AudioPolicyPfw.
- *
- * @param[in] typeName of the PFW criterion type.
- * @param[in] isInclusive attribute of the criterion type.
- */
- void addCriterionType(const std::string &typeName, bool isInclusive);
-
- /**
- * Add a criterion type value pair to AudioPolicyPfw.
- *
- * @param[in] typeName criterion type name to which this value pair is added to.
- * @param[in] numeric part of the value pair.
- * @param[in] literal part of the value pair.
- */
- void addCriterionTypeValuePair(const std::string &typeName, uint32_t numeric,
- const std::string &literal);
-
- /**
- * Add a criterion to AudioPolicyPfw.
- *
- * @param[in] name of the PFW criterion.
- * @param[in] typeName criterion type name to which this criterion is associated to.
- * @param[in] defaultLiteralValue of the PFW criterion.
- */
- void addCriterion(const std::string &name,
- const std::string &typeName,
- const std::string &defaultLiteralValue);
- /**
- * Parse and load the inclusive criterion type from configuration file.
- *
- * @param[in] root node of the configuration file.
- */
- void loadInclusiveCriterionType(cnode *root);
-
- /**
- * Parse and load the exclusive criterion type from configuration file.
- *
- * @param[in] root node of the configuration file.
- */
- void loadExclusiveCriterionType(cnode *root);
-
- /**
- * Parse and load the criteria from configuration file.
- *
- * @param[in] root node of the configuration file.
- */
- void loadCriteria(cnode *root);
-
- /**
- * Parse and load a criterion from configuration file.
- *
- * @param[in] root node of the configuration file.
- */
- void loadCriterion(cnode *root);
-
- /**
- * Parse and load the criterion types from configuration file.
- *
- * @param[in] root node of the configuration file
- * @param[in] isInclusive true if inclusive, false is exclusive.
- */
- void loadCriterionType(cnode *root, bool isInclusive);
-
- /**
- * Load the configuration file.
- *
- * @param[in] root node of the configuration file.
- */
- void loadConfig(cnode *root);
-
- /**
- * Parse and load the chidren node from a given root node.
- *
- * @param[in] root node of the configuration file
- * @param[out] defaultValue of the parameter manager element to retrieve.
- * @param[out] type of the parameter manager element to retrieve.
- */
- void parseChildren(cnode *root, std::string &defaultValue, std::string &type);
-
- /**
+ /**
* Retrieve an element from a map by its name.
*
* @tparam T type of element to search.
@@ -266,8 +182,7 @@
bool isValueValidForCriterion(ISelectionCriterionInterface *criterion, int valueToCheck);
- CriterionTypeCollection mPolicyCriterionTypes; /**< Policy Criterion Type map. */
- CriterionCollection mPolicyCriteria; /**< Policy Criterion Map. */
+ Criteria mPolicyCriteria; /**< Policy Criterion Map. */
CParameterMgrPlatformConnector *mPfwConnector; /**< Policy Parameter Manager connector. */
ParameterMgrPlatformConnectorLogger *mPfwConnectorLogger; /**< Policy PFW logger. */
diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
index 69395f3..0ef6f52 100644
--- a/services/audiopolicy/enginedefault/src/Engine.cpp
+++ b/services/audiopolicy/enginedefault/src/Engine.cpp
@@ -631,6 +631,7 @@
case AUDIO_SOURCE_UNPROCESSED:
case AUDIO_SOURCE_HOTWORD:
case AUDIO_SOURCE_CAMCORDER:
+ case AUDIO_SOURCE_VOICE_PERFORMANCE:
inputSource = AUDIO_SOURCE_VOICE_COMMUNICATION;
break;
default:
@@ -737,16 +738,32 @@
device = AUDIO_DEVICE_IN_VOICE_CALL;
}
break;
+ case AUDIO_SOURCE_VOICE_PERFORMANCE:
+ if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
+ device = AUDIO_DEVICE_IN_WIRED_HEADSET;
+ } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_HEADSET) {
+ device = AUDIO_DEVICE_IN_USB_HEADSET;
+ } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
+ device = AUDIO_DEVICE_IN_USB_DEVICE;
+ } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
+ device = AUDIO_DEVICE_IN_BUILTIN_MIC;
+ }
+ break;
case AUDIO_SOURCE_REMOTE_SUBMIX:
if (availableDeviceTypes & AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
device = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
}
break;
- case AUDIO_SOURCE_FM_TUNER:
+ case AUDIO_SOURCE_FM_TUNER:
if (availableDeviceTypes & AUDIO_DEVICE_IN_FM_TUNER) {
device = AUDIO_DEVICE_IN_FM_TUNER;
}
break;
+ case AUDIO_SOURCE_ECHO_REFERENCE:
+ if (availableDeviceTypes & AUDIO_DEVICE_IN_ECHO_REFERENCE) {
+ device = AUDIO_DEVICE_IN_ECHO_REFERENCE;
+ }
+ break;
default:
ALOGW("getDeviceForInputSource() invalid input source %d", inputSource);
break;
diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp
index 29b0561..919a90d 100644
--- a/services/audiopolicy/service/AudioPolicyEffects.cpp
+++ b/services/audiopolicy/service/AudioPolicyEffects.cpp
@@ -330,11 +330,12 @@
return BAD_VALUE;
}
- // HOTWORD and FM_TUNER are two special case sources > MAX.
+ // HOTWORD, FM_TUNER and ECHO_REFERENCE are special case sources > MAX.
if (source < AUDIO_SOURCE_DEFAULT ||
(source > AUDIO_SOURCE_MAX &&
source != AUDIO_SOURCE_HOTWORD &&
- source != AUDIO_SOURCE_FM_TUNER)) {
+ source != AUDIO_SOURCE_FM_TUNER &&
+ source != AUDIO_SOURCE_ECHO_REFERENCE)) {
ALOGE("addSourceDefaultEffect(): Unsupported source type %d", source);
return BAD_VALUE;
}
@@ -534,7 +535,8 @@
CAMCORDER_SRC_TAG,
VOICE_REC_SRC_TAG,
VOICE_COMM_SRC_TAG,
- UNPROCESSED_SRC_TAG
+ UNPROCESSED_SRC_TAG,
+ VOICE_PERFORMANCE_SRC_TAG
};
// returns the audio_source_t enum corresponding to the input source name or
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 80503fd..2c904d9 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -336,8 +336,11 @@
}
// already checked by client, but double-check in case the client wrapper is bypassed
- if (attr->source < AUDIO_SOURCE_DEFAULT && attr->source >= AUDIO_SOURCE_CNT &&
- attr->source != AUDIO_SOURCE_HOTWORD && attr->source != AUDIO_SOURCE_FM_TUNER) {
+ if ((attr->source < AUDIO_SOURCE_DEFAULT)
+ || (attr->source >= AUDIO_SOURCE_CNT
+ && attr->source != AUDIO_SOURCE_HOTWORD
+ && attr->source != AUDIO_SOURCE_FM_TUNER
+ && attr->source != AUDIO_SOURCE_ECHO_REFERENCE)) {
return BAD_VALUE;
}
@@ -367,7 +370,8 @@
if ((attr->source == AUDIO_SOURCE_VOICE_UPLINK ||
attr->source == AUDIO_SOURCE_VOICE_DOWNLINK ||
- attr->source == AUDIO_SOURCE_VOICE_CALL) &&
+ attr->source == AUDIO_SOURCE_VOICE_CALL ||
+ attr->source == AUDIO_SOURCE_ECHO_REFERENCE) &&
!captureAudioOutputAllowed(pid, uid)) {
return PERMISSION_DENIED;
}
diff --git a/services/audiopolicy/tests/audiopolicymanager_tests.cpp b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
index 56af152..24326bb 100644
--- a/services/audiopolicy/tests/audiopolicymanager_tests.cpp
+++ b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
@@ -112,10 +112,34 @@
std::set<audio_patch_handle_t> mActivePatches;
};
+class PatchCountCheck {
+ public:
+ explicit PatchCountCheck(AudioPolicyManagerTestClient *client)
+ : mClient{client},
+ mInitialCount{mClient->getActivePatchesCount()} {}
+ void assertDelta(int delta) const {
+ ASSERT_EQ(mInitialCount + delta, mClient->getActivePatchesCount()); }
+ void assertNoChange() const { assertDelta(0); }
+ private:
+ const AudioPolicyManagerTestClient *mClient;
+ const size_t mInitialCount;
+};
+
class AudioPolicyManagerTest : public testing::Test {
protected:
- virtual void SetUp();
- virtual void TearDown();
+ void SetUp() override;
+ void TearDown() override;
+ virtual void SetUpConfig(AudioPolicyConfig *config) { (void)config; }
+
+ void dumpToLog();
+ void getOutputForAttr(
+ audio_port_handle_t *selectedDeviceId,
+ audio_format_t format,
+ int channelMask,
+ int sampleRate,
+ audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
+ audio_port_handle_t *portId = nullptr);
+ PatchCountCheck snapPatchCount() { return PatchCountCheck(mClient.get()); }
std::unique_ptr<AudioPolicyManagerTestClient> mClient;
std::unique_ptr<AudioPolicyTestManager> mManager;
@@ -125,6 +149,7 @@
mClient.reset(new AudioPolicyManagerTestClient);
mManager.reset(new AudioPolicyTestManager(mClient.get()));
mManager->getConfig().setDefault();
+ SetUpConfig(&mManager->getConfig()); // Subclasses may want to customize the config.
ASSERT_EQ(NO_ERROR, mManager->initialize());
ASSERT_EQ(NO_ERROR, mManager->initCheck());
}
@@ -134,11 +159,7 @@
mClient.reset();
}
-TEST_F(AudioPolicyManagerTest, InitSuccess) {
- // SetUp must finish with no assertions.
-}
-
-TEST_F(AudioPolicyManagerTest, Dump) {
+void AudioPolicyManagerTest::dumpToLog() {
int pipefd[2];
ASSERT_NE(-1, pipe(pipefd));
pid_t cpid = fork();
@@ -168,10 +189,43 @@
}
}
+void AudioPolicyManagerTest::getOutputForAttr(
+ audio_port_handle_t *selectedDeviceId,
+ audio_format_t format,
+ int channelMask,
+ int sampleRate,
+ audio_output_flags_t flags,
+ audio_port_handle_t *portId) {
+ audio_attributes_t attr = {};
+ audio_io_handle_t output = AUDIO_PORT_HANDLE_NONE;
+ audio_stream_type_t stream = AUDIO_STREAM_DEFAULT;
+ audio_config_t config = AUDIO_CONFIG_INITIALIZER;
+ config.sample_rate = sampleRate;
+ config.channel_mask = channelMask;
+ config.format = format;
+ *selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ audio_port_handle_t localPortId;
+ if (!portId) portId = &localPortId;
+ *portId = AUDIO_PORT_HANDLE_NONE;
+ ASSERT_EQ(OK, mManager->getOutputForAttr(
+ &attr, &output, AUDIO_SESSION_NONE, &stream, 0 /*uid*/, &config, &flags,
+ selectedDeviceId, portId));
+ ASSERT_NE(AUDIO_PORT_HANDLE_NONE, *portId);
+}
+
+
+TEST_F(AudioPolicyManagerTest, InitSuccess) {
+ // SetUp must finish with no assertions.
+}
+
+TEST_F(AudioPolicyManagerTest, Dump) {
+ dumpToLog();
+}
+
TEST_F(AudioPolicyManagerTest, CreateAudioPatchFailure) {
audio_patch patch{};
audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE;
- const size_t patchCountBefore = mClient->getActivePatchesCount();
+ const PatchCountCheck patchCount = snapPatchCount();
ASSERT_EQ(BAD_VALUE, mManager->createAudioPatch(nullptr, &handle, 0));
ASSERT_EQ(BAD_VALUE, mManager->createAudioPatch(&patch, nullptr, 0));
ASSERT_EQ(BAD_VALUE, mManager->createAudioPatch(&patch, &handle, 0));
@@ -198,20 +252,182 @@
ASSERT_EQ(INVALID_OPERATION, mManager->createAudioPatch(&patch, &handle, 0));
// Verify that the handle is left unchanged.
ASSERT_EQ(AUDIO_PATCH_HANDLE_NONE, handle);
- ASSERT_EQ(patchCountBefore, mClient->getActivePatchesCount());
+ patchCount.assertNoChange();
}
TEST_F(AudioPolicyManagerTest, CreateAudioPatchFromMix) {
audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE;
uid_t uid = 42;
- const size_t patchCountBefore = mClient->getActivePatchesCount();
+ const PatchCountCheck patchCount = snapPatchCount();
ASSERT_FALSE(mManager->getConfig().getAvailableInputDevices().isEmpty());
PatchBuilder patchBuilder;
patchBuilder.addSource(mManager->getConfig().getAvailableInputDevices()[0]).
addSink(mManager->getConfig().getDefaultOutputDevice());
ASSERT_EQ(NO_ERROR, mManager->createAudioPatch(patchBuilder.patch(), &handle, uid));
ASSERT_NE(AUDIO_PATCH_HANDLE_NONE, handle);
- ASSERT_EQ(patchCountBefore + 1, mClient->getActivePatchesCount());
+ patchCount.assertDelta(1);
}
// TODO: Add patch creation tests that involve already existing patch
+
+class AudioPolicyManagerTestMsd : public AudioPolicyManagerTest {
+ protected:
+ void SetUpConfig(AudioPolicyConfig *config) override;
+ void TearDown() override;
+
+ sp<DeviceDescriptor> mMsdOutputDevice;
+ sp<DeviceDescriptor> mMsdInputDevice;
+};
+
+void AudioPolicyManagerTestMsd::SetUpConfig(AudioPolicyConfig *config) {
+ // TODO: Consider using Serializer to load part of the config from a string.
+ mMsdOutputDevice = new DeviceDescriptor(AUDIO_DEVICE_OUT_BUS);
+ sp<AudioProfile> pcmOutputProfile = new AudioProfile(
+ AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO, 48000);
+ sp<AudioProfile> ac3OutputProfile = new AudioProfile(
+ AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1, 48000);
+ mMsdOutputDevice->addAudioProfile(pcmOutputProfile);
+ mMsdOutputDevice->addAudioProfile(ac3OutputProfile);
+ mMsdInputDevice = new DeviceDescriptor(AUDIO_DEVICE_IN_BUS);
+ // Match output profile from AudioPolicyConfig::setDefault.
+ sp<AudioProfile> pcmInputProfile = new AudioProfile(
+ AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO, 44100);
+ mMsdInputDevice->addAudioProfile(pcmInputProfile);
+ config->addAvailableDevice(mMsdOutputDevice);
+ config->addAvailableDevice(mMsdInputDevice);
+
+ sp<HwModule> msdModule = new HwModule(AUDIO_HARDWARE_MODULE_ID_MSD, 2 /*halVersionMajor*/);
+ HwModuleCollection modules = config->getHwModules();
+ modules.add(msdModule);
+ config->setHwModules(modules);
+ mMsdOutputDevice->attach(msdModule);
+ mMsdInputDevice->attach(msdModule);
+
+ sp<OutputProfile> msdOutputProfile = new OutputProfile(String8("msd input"));
+ msdOutputProfile->addAudioProfile(pcmOutputProfile);
+ msdOutputProfile->addSupportedDevice(mMsdOutputDevice);
+ msdModule->addOutputProfile(msdOutputProfile);
+ sp<OutputProfile> msdCompressedOutputProfile =
+ new OutputProfile(String8("msd compressed input"));
+ msdCompressedOutputProfile->addAudioProfile(ac3OutputProfile);
+ msdCompressedOutputProfile->setFlags(
+ AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD |
+ AUDIO_OUTPUT_FLAG_NON_BLOCKING);
+ msdCompressedOutputProfile->addSupportedDevice(mMsdOutputDevice);
+ msdModule->addOutputProfile(msdCompressedOutputProfile);
+
+ sp<InputProfile> msdInputProfile = new InputProfile(String8("msd output"));
+ msdInputProfile->addAudioProfile(pcmInputProfile);
+ msdInputProfile->addSupportedDevice(mMsdInputDevice);
+ msdModule->addInputProfile(msdInputProfile);
+
+ // Add a profile with another encoding to the default device to test routing
+ // of streams that are not supported by MSD.
+ sp<AudioProfile> dtsOutputProfile = new AudioProfile(
+ AUDIO_FORMAT_DTS, AUDIO_CHANNEL_OUT_5POINT1, 48000);
+ config->getDefaultOutputDevice()->addAudioProfile(dtsOutputProfile);
+ sp<OutputProfile> primaryEncodedOutputProfile = new OutputProfile(String8("encoded"));
+ primaryEncodedOutputProfile->addAudioProfile(dtsOutputProfile);
+ primaryEncodedOutputProfile->setFlags(AUDIO_OUTPUT_FLAG_DIRECT);
+ primaryEncodedOutputProfile->addSupportedDevice(config->getDefaultOutputDevice());
+ config->getHwModules().getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY)->
+ addOutputProfile(primaryEncodedOutputProfile);
+}
+
+void AudioPolicyManagerTestMsd::TearDown() {
+ mMsdOutputDevice.clear();
+ mMsdInputDevice.clear();
+ AudioPolicyManagerTest::TearDown();
+}
+
+TEST_F(AudioPolicyManagerTestMsd, InitSuccess) {
+ ASSERT_TRUE(mMsdOutputDevice);
+ ASSERT_TRUE(mMsdInputDevice);
+}
+
+TEST_F(AudioPolicyManagerTestMsd, Dump) {
+ dumpToLog();
+}
+
+TEST_F(AudioPolicyManagerTestMsd, PatchCreationOnSetForceUse) {
+ const PatchCountCheck patchCount = snapPatchCount();
+ mManager->setForceUse(AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND,
+ AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS);
+ patchCount.assertDelta(1);
+}
+
+TEST_F(AudioPolicyManagerTestMsd, GetOutputForAttrEncodedRoutesToMsd) {
+ const PatchCountCheck patchCount = snapPatchCount();
+ audio_port_handle_t selectedDeviceId;
+ getOutputForAttr(&selectedDeviceId,
+ AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1, 48000, AUDIO_OUTPUT_FLAG_DIRECT);
+ ASSERT_EQ(selectedDeviceId, mMsdOutputDevice->getId());
+ patchCount.assertDelta(1);
+}
+
+TEST_F(AudioPolicyManagerTestMsd, GetOutputForAttrPcmRoutesToMsd) {
+ const PatchCountCheck patchCount = snapPatchCount();
+ audio_port_handle_t selectedDeviceId;
+ getOutputForAttr(&selectedDeviceId,
+ AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO, 48000);
+ ASSERT_EQ(selectedDeviceId, mMsdOutputDevice->getId());
+ patchCount.assertDelta(1);
+}
+
+TEST_F(AudioPolicyManagerTestMsd, GetOutputForAttrEncodedPlusPcmRoutesToMsd) {
+ const PatchCountCheck patchCount = snapPatchCount();
+ audio_port_handle_t selectedDeviceId;
+ getOutputForAttr(&selectedDeviceId,
+ AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1, 48000, AUDIO_OUTPUT_FLAG_DIRECT);
+ ASSERT_EQ(selectedDeviceId, mMsdOutputDevice->getId());
+ patchCount.assertDelta(1);
+ getOutputForAttr(&selectedDeviceId,
+ AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO, 48000);
+ ASSERT_EQ(selectedDeviceId, mMsdOutputDevice->getId());
+ patchCount.assertDelta(1);
+}
+
+TEST_F(AudioPolicyManagerTestMsd, GetOutputForAttrUnsupportedFormatBypassesMsd) {
+ const PatchCountCheck patchCount = snapPatchCount();
+ audio_port_handle_t selectedDeviceId;
+ getOutputForAttr(&selectedDeviceId,
+ AUDIO_FORMAT_DTS, AUDIO_CHANNEL_OUT_5POINT1, 48000, AUDIO_OUTPUT_FLAG_DIRECT);
+ ASSERT_NE(selectedDeviceId, mMsdOutputDevice->getId());
+ patchCount.assertNoChange();
+}
+
+TEST_F(AudioPolicyManagerTestMsd, GetOutputForAttrFormatSwitching) {
+ // Switch between formats that are supported and not supported by MSD.
+ {
+ const PatchCountCheck patchCount = snapPatchCount();
+ audio_port_handle_t selectedDeviceId, portId;
+ getOutputForAttr(&selectedDeviceId,
+ AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1, 48000, AUDIO_OUTPUT_FLAG_DIRECT,
+ &portId);
+ ASSERT_EQ(selectedDeviceId, mMsdOutputDevice->getId());
+ patchCount.assertDelta(1);
+ mManager->releaseOutput(portId);
+ patchCount.assertDelta(1); // compared to the state at the block entry
+ // TODO: make PatchCountCheck asserts more obvious. It's easy to
+ // miss the fact that it is immutable.
+ }
+ {
+ const PatchCountCheck patchCount = snapPatchCount();
+ audio_port_handle_t selectedDeviceId, portId;
+ getOutputForAttr(&selectedDeviceId,
+ AUDIO_FORMAT_DTS, AUDIO_CHANNEL_OUT_5POINT1, 48000, AUDIO_OUTPUT_FLAG_DIRECT,
+ &portId);
+ ASSERT_NE(selectedDeviceId, mMsdOutputDevice->getId());
+ patchCount.assertDelta(-1);
+ mManager->releaseOutput(portId);
+ patchCount.assertNoChange();
+ }
+ {
+ const PatchCountCheck patchCount = snapPatchCount();
+ audio_port_handle_t selectedDeviceId;
+ getOutputForAttr(&selectedDeviceId,
+ AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1, 48000, AUDIO_OUTPUT_FLAG_DIRECT);
+ ASSERT_EQ(selectedDeviceId, mMsdOutputDevice->getId());
+ patchCount.assertNoChange();
+ }
+}
diff --git a/services/mediacodec/MediaCodecUpdateService.cpp b/services/mediacodec/MediaCodecUpdateService.cpp
index aee890d..0e6892d 100644
--- a/services/mediacodec/MediaCodecUpdateService.cpp
+++ b/services/mediacodec/MediaCodecUpdateService.cpp
@@ -18,14 +18,10 @@
//#define LOG_NDEBUG 0
#include <android/dlext.h>
-#include <android-base/logging.h>
-#include <android-base/strings.h>
-#include <dirent.h>
#include <dlfcn.h>
#include <media/CodecServiceRegistrant.h>
#include <utils/Log.h>
-#include <ziparchive/zip_archive.h>
-#include <cutils/properties.h>
+#include <utils/String8.h>
#include "MediaCodecUpdateService.h"
@@ -47,90 +43,53 @@
}
namespace android {
-namespace media {
-binder::Status MediaCodecUpdateService::loadPlugins(const ::std::string& apkPath) {
- ALOGV("loadPlugins %s", apkPath.c_str());
+void loadFromApex(const char *libDirPath) {
+ ALOGV("loadFromApex: path=%s", libDirPath);
- ZipArchiveHandle zipHandle;
- void *registrantLib = NULL;
- int32_t ret = OpenArchive(apkPath.c_str(), &zipHandle);
+ String8 libPath = String8(libDirPath) + "/libmedia_codecserviceregistrant.so";
- if (ret == 0) {
- char abilist32[PROPERTY_VALUE_MAX];
- property_get("ro.product.cpu.abilist32", abilist32, "armeabi-v7a");
+ android_namespace_t *codecNs = android_create_namespace("codecs",
+ nullptr, // ld_library_path
+ libDirPath,
+ ANDROID_NAMESPACE_TYPE_ISOLATED,
+ nullptr, // permitted_when_isolated_path
+ nullptr); // parent
- auto abis = base::Split(abilist32, ",");
- if (abis.empty()) {
- ALOGW("abilist is empty, trying armeabi-v7a ...");
- abis.push_back("armeabi-v7a");
- }
-
- // TODO: Only try the first entry in abilist32 for now.
- // We probably should try the next if it fails.
- String8 libPathInApk = String8("lib/") + String8(abis[0].c_str());
- String8 defaultLibPath = String8(apkPath.c_str()) + "!/" + libPathInApk;
- String8 libPath = defaultLibPath + "/libmedia_codecserviceregistrant.so";
- String8 zipEntryPath = libPathInApk + "/libmedia_codecserviceregistrant.so";
-
- ZipEntry entry;
- ret = FindEntry(zipHandle, ZipString(zipEntryPath), &entry);
-
- if (ret == 0) {
- android_namespace_t *codecNs = android_create_namespace("codecs",
- nullptr, // ld_library_path
- defaultLibPath.c_str(),
- ANDROID_NAMESPACE_TYPE_ISOLATED,
- nullptr, // permitted_when_isolated_path
- nullptr); // parent
-
- if (codecNs != nullptr) {
- String8 linked_libraries(LINKED_LIBRARIES);
- if (android_link_namespaces(
- codecNs, nullptr, linked_libraries.c_str())) {
- const android_dlextinfo dlextinfo = {
- .flags = ANDROID_DLEXT_USE_NAMESPACE,
- .library_namespace = codecNs,
- };
-
- registrantLib = android_dlopen_ext(
- libPath.string(),
- RTLD_NOW | RTLD_LOCAL, &dlextinfo);
-
- if (registrantLib == NULL) {
- ALOGE("Failed to load lib from archive: %s", dlerror());
- }
- } else {
- ALOGE("Failed to link namespace");
- }
- } else {
- ALOGE("Failed to create codec namespace");
- }
- } else {
- ALOGE("Failed to find entry (ret=%d)", ret);
- }
-
- CloseArchive(zipHandle);
- } else {
- ALOGE("Failed to open archive (ret=%d)", ret);
+ if (codecNs == nullptr) {
+ ALOGE("Failed to create codec namespace");
+ return;
}
- if (registrantLib) {
- RegisterCodecServicesFunc registerCodecServices =
- reinterpret_cast<RegisterCodecServicesFunc>(
- dlsym(registrantLib, "RegisterCodecServices"));
- if (registerCodecServices) {
- registerCodecServices();
- } else {
- LOG(WARNING) << "Cannot register codec services "
- "-- corrupted library.";
- }
- } else {
- LOG(ERROR) << "Cannot find codec service registrant.";
+ String8 linked_libraries(LINKED_LIBRARIES);
+ if (!android_link_namespaces(codecNs, nullptr, linked_libraries.c_str())) {
+ ALOGE("Failed to link namespace");
+ return;
}
- return binder::Status::ok();
+ const android_dlextinfo dlextinfo = {
+ .flags = ANDROID_DLEXT_USE_NAMESPACE,
+ .library_namespace = codecNs,
+ };
+
+ void *registrantLib = android_dlopen_ext(
+ libPath.string(),
+ RTLD_NOW | RTLD_LOCAL, &dlextinfo);
+
+ if (registrantLib == nullptr) {
+ ALOGE("Failed to load lib from archive: %s", dlerror());
+ }
+
+ RegisterCodecServicesFunc registerCodecServices =
+ reinterpret_cast<RegisterCodecServicesFunc>(
+ dlsym(registrantLib, "RegisterCodecServices"));
+
+ if (registerCodecServices == nullptr) {
+ ALOGE("Cannot register codec services -- corrupted library.");
+ return;
+ }
+
+ registerCodecServices();
}
-} // namespace media
} // namespace android
diff --git a/services/mediacodec/MediaCodecUpdateService.h b/services/mediacodec/MediaCodecUpdateService.h
index 7b7cee9..09d6dbe 100644
--- a/services/mediacodec/MediaCodecUpdateService.h
+++ b/services/mediacodec/MediaCodecUpdateService.h
@@ -17,24 +17,10 @@
#ifndef ANDROID_MEDIA_CODEC_UPDATE_SERVICE_H
#define ANDROID_MEDIA_CODEC_UPDATE_SERVICE_H
-#include <binder/BinderService.h>
-#include <android/media/BnMediaUpdateService.h>
-
namespace android {
-namespace media {
-class MediaCodecUpdateService
- : public BinderService<MediaCodecUpdateService>, public BnMediaUpdateService
-{
- friend class BinderService<MediaCodecUpdateService>;
-public:
- MediaCodecUpdateService() : BnMediaUpdateService() { }
- virtual ~MediaCodecUpdateService() { }
- static const char* getServiceName() { return "media.codec.update"; }
- binder::Status loadPlugins(const ::std::string& apkPath);
-};
+void loadFromApex(const char *libDirPath);
-} // namespace media
} // namespace android
#endif // ANDROID_MEDIA_CODEC_UPDATE_SERVICE_H
diff --git a/services/mediacodec/main_swcodecservice.cpp b/services/mediacodec/main_swcodecservice.cpp
index 79fea25..1168825 100644
--- a/services/mediacodec/main_swcodecservice.cpp
+++ b/services/mediacodec/main_swcodecservice.cpp
@@ -20,11 +20,7 @@
// from LOCAL_C_INCLUDES
#include "minijail.h"
-#include <android-base/properties.h>
-#include <binder/ProcessState.h>
-#include <dlfcn.h>
#include <hidl/HidlTransportSupport.h>
-#include <media/CodecServiceRegistrant.h>
#include "MediaCodecUpdateService.h"
@@ -49,32 +45,10 @@
signal(SIGPIPE, SIG_IGN);
SetUpMinijail(kSystemSeccompPolicyPath, kVendorSeccompPolicyPath);
- std::string value = base::GetProperty("ro.build.type", "unknown");
- if (value == "userdebug" || value == "eng") {
- media::MediaCodecUpdateService::instantiate();
- }
-
- android::ProcessState::self()->startThreadPool();
-
::android::hardware::configureRpcThreadpool(64, false);
- // Registration of customized codec services
- void *registrantLib = dlopen(
- "libmedia_codecserviceregistrant.so",
- RTLD_NOW | RTLD_LOCAL);
- if (registrantLib) {
- RegisterCodecServicesFunc registerCodecServices =
- reinterpret_cast<RegisterCodecServicesFunc>(
- dlsym(registrantLib, "RegisterCodecServices"));
- if (registerCodecServices) {
- registerCodecServices();
- } else {
- LOG(WARNING) << "Cannot register codec services "
- "-- corrupted library.";
- }
- } else {
- LOG(ERROR) << "Cannot find codec service registrant.";
- }
+ // codec libs are currently 32-bit only
+ loadFromApex("/apex/com.android.media.swcodec/lib");
::android::hardware::joinRpcThreadpool();
}
diff --git a/services/mediaextractor/Android.mk b/services/mediaextractor/Android.mk
index 6101c8a..dd64881 100644
--- a/services/mediaextractor/Android.mk
+++ b/services/mediaextractor/Android.mk
@@ -46,6 +46,7 @@
LOCAL_INIT_RC := mediaextractor.rc
LOCAL_C_INCLUDES := frameworks/av/media/libmedia
LOCAL_CFLAGS := -Wall -Werror
+LOCAL_SANITIZE := scudo
include $(BUILD_EXECUTABLE)
# service seccomp filter
diff --git a/services/mediaextractor/main_extractorservice.cpp b/services/mediaextractor/main_extractorservice.cpp
index 8d3359a..5f42711 100644
--- a/services/mediaextractor/main_extractorservice.cpp
+++ b/services/mediaextractor/main_extractorservice.cpp
@@ -42,6 +42,12 @@
static const char kVendorSeccompPolicyPath[] =
"/vendor/etc/seccomp_policy/mediaextractor.policy";
+// Disable Scudo's mismatch allocation check, as it is being triggered
+// by some third party code.
+extern "C" const char *__scudo_default_options() {
+ return "DeallocationTypeMismatch=false";
+}
+
int main(int argc __unused, char** argv)
{
limitProcessMemory(
diff --git a/services/mediaextractor/seccomp_policy/mediaextractor-x86_64.policy b/services/mediaextractor/seccomp_policy/mediaextractor-x86_64.policy
index 35ac458..607a03e 100644
--- a/services/mediaextractor/seccomp_policy/mediaextractor-x86_64.policy
+++ b/services/mediaextractor/seccomp_policy/mediaextractor-x86_64.policy
@@ -11,6 +11,7 @@
mmap: 1
madvise: 1
openat: 1
+open: 1
clock_gettime: 1
writev: 1
brk: 1