Merge "Initialize mRowBytes and mSize with overflow check." into tm-qpr-dev am: ea44678be2
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/av/+/20132241
Change-Id: I8c838dfd1b87a0179babdf5409d9deb6a650a91f
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/Android.bp b/Android.bp
index ee609e1..5aa2029 100644
--- a/Android.bp
+++ b/Android.bp
@@ -57,7 +57,7 @@
min_sdk_version: "29",
apex_available: [
"//apex_available:platform",
- "com.android.bluetooth",
+ "com.android.btservices",
"com.android.media",
"com.android.media.swcodec",
],
@@ -75,10 +75,10 @@
"av-types-aidl-cpp",
],
header_libs: [
- "libaudioclient_aidl_conversion_util",
+ "libaudio_aidl_conversion_common_util_cpp",
],
export_header_lib_headers: [
- "libaudioclient_aidl_conversion_util",
+ "libaudio_aidl_conversion_common_util_cpp",
],
host_supported: true,
vendor_available: true,
@@ -86,7 +86,7 @@
min_sdk_version: "29",
apex_available: [
"//apex_available:platform",
- "com.android.bluetooth",
+ "com.android.btservices",
"com.android.media",
"com.android.media.swcodec",
],
diff --git a/MainlineFiles.cfg b/MainlineFiles.cfg
index 490bbbf..bf39c1a 100644
--- a/MainlineFiles.cfg
+++ b/MainlineFiles.cfg
@@ -21,11 +21,20 @@
#
# matching is purely prefix
# so 'foo' will match 'foo', 'foo.c', 'foo/bar/baz'
-# if you want to exclude a directory, best to use a pattern like "foo/"
+# if you want to specify a directory, best to use a pattern like "foo/"
#
+apex/
media/codec2/components/
-media/codecs/
-media/extractors/
-media/libstagefright/mpeg2ts/
-media/libstagefright/flac/
+media/codec2/core/
+media/codec2/hidl/
+media/codec2/sfplugin/utils/
+media/codec2/vndk/
+media/libstagefright/data/media_codecs_sw.xml
+media/module/
+services/mediacodec/
+
+# source code used in both framework and mainline libraries
+media/libstagefright/HevcUtils.cpp
+media/libstagefright/MediaSource.cpp
+media/libstagefright/Utils.cpp
diff --git a/OWNERS b/OWNERS
index 40c65e7..3c7a3ab 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,7 +1,16 @@
-# Bug component: 1344
+## Media team top-level OWNERS, bug component: 1344
+## Only contact for camera changes as a fallback
elaurent@google.com
-etalvala@google.com
lajos@google.com
# go/android-fwk-media-solutions for info on areas of ownership.
include platform/frameworks/av:/media/janitors/media_solutions_OWNERS
+
+## Camera team top-level OWNERS, bug component: 41727
+## Only contact for media changes as a fallback
+etalvala@google.com
+shuzhenwang@google.com
+
+# mainline related
+per-file MainlineFiles.cfg=essick@google.com
+per-file MainlineFiles.cfg=file:/media/janitors/reliability_mainline_OWNERS
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index 716b550..1f7083b 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -11,3 +11,4 @@
clang_format = --commit ${PREUPLOAD_COMMIT} --style file --extensions c,h,cc,cpp
media/libmediatranscoding/
services/mediatranscoding/
+ media/libaudioclient/tests/
diff --git a/apex/Android.bp b/apex/Android.bp
index 570ca01..b0d7c02 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -67,13 +67,15 @@
// Use a custom AndroidManifest.xml used for API targeting.
androidManifest: ":com.android.media-androidManifest",
- // IMPORTANT: q-launched-apex-module enables the build system to make
- // sure the package compatible to Android 10 in two ways:
+ // IMPORTANT: q-launched-dcla-enabled-apex-module enables the build system to make
+ // sure the package compatible to Android 10 in two ways(if flag APEX_BUILD_FOR_PRE_S_DEVICES=1
+ // is set):
// - build the APEX package compatible to Android 10
// so that the package can be installed.
// - build artifacts (lib/javalib/bin) against Android 10 SDK
// so that the artifacts can run.
- defaults: ["q-launched-apex-module"],
+ // If the flag is not set, the package is built to be compatible with Android 12.
+ defaults: ["q-launched-dcla-enabled-apex-module"],
// Indicates that pre-installed version of this apex can be compressed.
// Whether it actually will be compressed is controlled on per-device basis.
compressible: true,
@@ -191,13 +193,15 @@
// Use a custom AndroidManifest.xml used for API targeting.
androidManifest: ":com.android.media.swcodec-androidManifest",
- // IMPORTANT: q-launched-apex-module enables the build system to make
- // sure the package compatible to Android 10 in two ways:
+ // IMPORTANT: q-launched-dcla-enabled-apex-module enables the build system to make
+ // sure the package compatible to Android 10 in two ways(if flag APEX_BUILD_FOR_PRE_S_DEVICES=1
+ // is set):
// - build the APEX package compatible to Android 10
// so that the package can be installed.
// - build artifacts (lib/javalib/bin) against Android 10 SDK
// so that the artifacts can run.
- defaults: ["q-launched-apex-module"],
+ // If the flag is not set, the package is built to be compatible with Android 12.
+ defaults: ["q-launched-dcla-enabled-apex-module"],
// Indicates that pre-installed version of this apex can be compressed.
// Whether it actually will be compressed is controlled on per-device basis.
compressible: true,
diff --git a/apex/manifest.json b/apex/manifest.json
index 1a26bff..5b235cd 100644
--- a/apex/manifest.json
+++ b/apex/manifest.json
@@ -1,6 +1,10 @@
{
"name": "com.android.media",
- "version": 330400000,
+
+ // Placeholder module version to be replaced during build.
+ // Do not change!
+ "version": 0,
+
"requireNativeLibs": [
"libandroid.so",
"libbinder_ndk.so",
diff --git a/apex/manifest_codec.json b/apex/manifest_codec.json
index 9426e59..f2b8b36 100644
--- a/apex/manifest_codec.json
+++ b/apex/manifest_codec.json
@@ -1,6 +1,10 @@
{
"name": "com.android.media.swcodec",
- "version": 330400000,
+
+ // Placeholder module version to be replaced during build.
+ // Do not change!
+ "version": 0,
+
"requireNativeLibs": [
":sphal"
]
diff --git a/camera/OWNERS b/camera/OWNERS
index 385c163..b705548 100644
--- a/camera/OWNERS
+++ b/camera/OWNERS
@@ -1,7 +1,11 @@
# Bug component: 41727
etalvala@google.com
arakesh@google.com
+borgera@google.com
+bkukreja@google.com
epeev@google.com
jchowdhary@google.com
-shuzhenwang@google.com
+rdhanjal@google.com
ruchamk@google.com
+shuzhenwang@google.com
+
diff --git a/camera/ndk/ndk_vendor/impl/ACameraManager.cpp b/camera/ndk/ndk_vendor/impl/ACameraManager.cpp
index 77c934a..bb4ef56 100644
--- a/camera/ndk/ndk_vendor/impl/ACameraManager.cpp
+++ b/camera/ndk/ndk_vendor/impl/ACameraManager.cpp
@@ -165,7 +165,10 @@
Mutex::Autolock _l(mLock);
if (mCameraService != nullptr) {
mCameraService->unlinkToDeath(mDeathNotifier);
- mCameraService->removeListener(mCameraServiceListener);
+ auto stat = mCameraService->removeListener(mCameraServiceListener);
+ if (!stat.isOk()) {
+ ALOGE("Failed to remove listener to camera service %s", stat.description().c_str());
+ }
}
mDeathNotifier.clear();
if (mCbLooper != nullptr) {
@@ -475,6 +478,10 @@
ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
return;
}
+ if (cb == nullptr) {
+ // Physical camera callback is null
+ return;
+ }
found = msg->findPointer(kContextKey, &context);
if (!found) {
ALOGE("%s: Cannot find callback context!", __FUNCTION__);
diff --git a/cmds/stagefright/SineSource.cpp b/cmds/stagefright/SineSource.cpp
index 0ecc16c..0656030 100644
--- a/cmds/stagefright/SineSource.cpp
+++ b/cmds/stagefright/SineSource.cpp
@@ -63,12 +63,15 @@
MediaBufferBase **out, const ReadOptions * /* options */) {
*out = NULL;
- MediaBufferBase *buffer;
+ MediaBufferBase *buffer = nullptr;
status_t err = mGroup->acquire_buffer(&buffer);
if (err != OK) {
return err;
}
+ if (buffer == nullptr) {
+ return AMEDIA_ERROR_UNKNOWN;
+ }
size_t frameSize = mNumChannels * sizeof(int16_t);
size_t numFramesPerBuffer = buffer->size() / frameSize;
diff --git a/cmds/stagefright/muxer.cpp b/cmds/stagefright/muxer.cpp
index bc7e41e..185491f 100644
--- a/cmds/stagefright/muxer.cpp
+++ b/cmds/stagefright/muxer.cpp
@@ -78,10 +78,14 @@
int fd = open(outputFileName, O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
if (fd < 0) {
- ALOGE("couldn't open file");
- return fd;
+ ALOGE("couldn't open output file %s", outputFileName);
+ return 1;
}
- sp<MediaMuxer> muxer = new MediaMuxer(fd, container);
+ sp<MediaMuxer> muxer = MediaMuxer::create(fd, container);
+ if (muxer == nullptr) {
+ fprintf(stderr, "unable to instantiate muxer for format %d\n", container);
+ return 1;
+ }
close(fd);
size_t trackCount = extractor->countTracks();
diff --git a/cmds/stagefright/record.cpp b/cmds/stagefright/record.cpp
index 5743ad6..87e8832 100644
--- a/cmds/stagefright/record.cpp
+++ b/cmds/stagefright/record.cpp
@@ -89,6 +89,9 @@
if (err != OK) {
return err;
}
+ if (buffer == nullptr) {
+ return AMEDIA_ERROR_UNKNOWN;
+ }
char x = (char)((double)rand() / RAND_MAX * 255);
memset((*buffer)->data(), x, mSize);
diff --git a/drm/libmediadrm/Android.bp b/drm/libmediadrm/Android.bp
index 408d216..7d68c5b 100644
--- a/drm/libmediadrm/Android.bp
+++ b/drm/libmediadrm/Android.bp
@@ -35,6 +35,8 @@
"CryptoHalAidl.cpp",
"DrmUtils.cpp",
"DrmHalListener.cpp",
+ "DrmStatus.cpp",
+ "DrmMetricsLogger.cpp",
],
local_include_dirs: [
@@ -74,6 +76,7 @@
static_libs: [
"resourcemanager_aidl_interface-ndk",
"libaidlcommonsupport",
+ "libjsoncpp",
],
export_shared_lib_headers: [
diff --git a/drm/libmediadrm/CryptoHal.cpp b/drm/libmediadrm/CryptoHal.cpp
index f95d527..fc1780d 100644
--- a/drm/libmediadrm/CryptoHal.cpp
+++ b/drm/libmediadrm/CryptoHal.cpp
@@ -71,7 +71,7 @@
mCryptoHalHidl->notifyResolution(width, height);
}
-status_t CryptoHal::setMediaDrmSession(const Vector<uint8_t>& sessionId) {
+DrmStatus CryptoHal::setMediaDrmSession(const Vector<uint8_t>& sessionId) {
// This requires plugin to be created.
if (mCryptoHalAidl->initCheck() == OK) return mCryptoHalAidl->setMediaDrmSession(sessionId);
return mCryptoHalHidl->setMediaDrmSession(sessionId);
diff --git a/drm/libmediadrm/CryptoHalAidl.cpp b/drm/libmediadrm/CryptoHalAidl.cpp
index 8b9d1de..c1fd797 100644
--- a/drm/libmediadrm/CryptoHalAidl.cpp
+++ b/drm/libmediadrm/CryptoHalAidl.cpp
@@ -41,7 +41,7 @@
using ::aidl::android::hardware::drm::DecryptArgs;
using ::android::sp;
-using ::android::DrmUtils::statusAidlToStatusT;
+using ::android::DrmUtils::statusAidlToDrmStatus;
using ::android::hardware::hidl_array;
using ::android::hardware::hidl_handle;
using ::android::hardware::hidl_memory;
@@ -260,7 +260,7 @@
}
}
-status_t CryptoHalAidl::setMediaDrmSession(const Vector<uint8_t>& sessionId) {
+DrmStatus CryptoHalAidl::setMediaDrmSession(const Vector<uint8_t>& sessionId) {
Mutex::Autolock autoLock(mLock);
if (mInitCheck != OK) {
@@ -268,7 +268,7 @@
}
auto err = mPlugin->setMediaDrmSession(toStdVec(sessionId));
- return statusAidlToStatusT(err);
+ return statusAidlToDrmStatus(err);
}
ssize_t CryptoHalAidl::decrypt(const uint8_t keyId[16], const uint8_t iv[16],
@@ -352,7 +352,7 @@
int32_t result = 0;
::ndk::ScopedAStatus statusAidl = mPlugin->decrypt(args, &result);
- err = statusAidlToStatusT(statusAidl);
+ err = statusAidlToDrmStatus(statusAidl);
std::string msgStr(statusAidl.getMessage());
if (errorDetailMsg != nullptr) {
*errorDetailMsg = toString8(msgStr);
diff --git a/drm/libmediadrm/CryptoHalHidl.cpp b/drm/libmediadrm/CryptoHalHidl.cpp
index 55364b5..458a1ae 100644
--- a/drm/libmediadrm/CryptoHalHidl.cpp
+++ b/drm/libmediadrm/CryptoHalHidl.cpp
@@ -386,7 +386,7 @@
ALOGE_IF(!hResult.isOk(), "notifyResolution txn failed %s", hResult.description().c_str());
}
-status_t CryptoHalHidl::setMediaDrmSession(const Vector<uint8_t>& sessionId) {
+DrmStatus CryptoHalHidl::setMediaDrmSession(const Vector<uint8_t>& sessionId) {
Mutex::Autolock autoLock(mLock);
if (mInitCheck != OK) {
diff --git a/drm/libmediadrm/DrmHal.cpp b/drm/libmediadrm/DrmHal.cpp
index c394d5a..754f066 100644
--- a/drm/libmediadrm/DrmHal.cpp
+++ b/drm/libmediadrm/DrmHal.cpp
@@ -20,6 +20,7 @@
#include <mediadrm/DrmHal.h>
#include <mediadrm/DrmHalAidl.h>
#include <mediadrm/DrmHalHidl.h>
+#include <mediadrm/DrmStatus.h>
#include <mediadrm/DrmUtils.h>
namespace android {
@@ -31,49 +32,49 @@
DrmHal::~DrmHal() {}
-status_t DrmHal::initCheck() const {
- if (mDrmHalAidl->initCheck() == OK || mDrmHalHidl->initCheck() == OK) return OK;
- if (mDrmHalAidl->initCheck() == NO_INIT || mDrmHalHidl->initCheck() == NO_INIT) return NO_INIT;
+DrmStatus DrmHal::initCheck() const {
+ if (mDrmHalAidl->initCheck() == OK || mDrmHalHidl->initCheck() == OK) return DrmStatus(OK);
+ if (mDrmHalAidl->initCheck() == NO_INIT || mDrmHalHidl->initCheck() == NO_INIT)
+ return DrmStatus(NO_INIT);
return mDrmHalHidl->initCheck();
}
-status_t DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16], const String8& mimeType,
- DrmPlugin::SecurityLevel securityLevel, bool* result) {
- status_t statusResult;
- statusResult = mDrmHalAidl->isCryptoSchemeSupported(uuid, mimeType, securityLevel, result);
+DrmStatus DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16], const String8& mimeType,
+ DrmPlugin::SecurityLevel securityLevel, bool* result) {
+ DrmStatus statusResult =
+ mDrmHalAidl->isCryptoSchemeSupported(uuid, mimeType, securityLevel, result);
if (*result) return statusResult;
return mDrmHalHidl->isCryptoSchemeSupported(uuid, mimeType, securityLevel, result);
}
-status_t DrmHal::createPlugin(const uint8_t uuid[16], const String8& appPackageName) {
- status_t statusResult;
- statusResult = mDrmHalAidl->createPlugin(uuid, appPackageName);
- if (statusResult != OK) return mDrmHalHidl->createPlugin(uuid, appPackageName);
- return statusResult;
+DrmStatus DrmHal::createPlugin(const uint8_t uuid[16], const String8& appPackageName) {
+ return mDrmHalAidl->createPlugin(uuid, appPackageName) == OK
+ ? DrmStatus(OK)
+ : mDrmHalHidl->createPlugin(uuid, appPackageName);
}
-status_t DrmHal::destroyPlugin() {
- status_t statusResult = mDrmHalAidl->destroyPlugin();
- status_t statusResultHidl = mDrmHalHidl->destroyPlugin();
+DrmStatus DrmHal::destroyPlugin() {
+ DrmStatus statusResult = mDrmHalAidl->destroyPlugin();
+ DrmStatus statusResultHidl = mDrmHalHidl->destroyPlugin();
if (statusResult != OK) return statusResult;
return statusResultHidl;
}
-status_t DrmHal::openSession(DrmPlugin::SecurityLevel securityLevel, Vector<uint8_t>& sessionId) {
+DrmStatus DrmHal::openSession(DrmPlugin::SecurityLevel securityLevel, Vector<uint8_t>& sessionId) {
if (mDrmHalAidl->initCheck() == OK) return mDrmHalAidl->openSession(securityLevel, sessionId);
return mDrmHalHidl->openSession(securityLevel, sessionId);
}
-status_t DrmHal::closeSession(Vector<uint8_t> const& sessionId) {
+DrmStatus DrmHal::closeSession(Vector<uint8_t> const& sessionId) {
if (mDrmHalAidl->initCheck() == OK) return mDrmHalAidl->closeSession(sessionId);
return mDrmHalHidl->closeSession(sessionId);
}
-status_t DrmHal::getKeyRequest(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& initData,
- String8 const& mimeType, DrmPlugin::KeyType keyType,
- KeyedVector<String8, String8> const& optionalParameters,
- Vector<uint8_t>& request, String8& defaultUrl,
- DrmPlugin::KeyRequestType* keyRequestType) {
+DrmStatus DrmHal::getKeyRequest(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& initData,
+ String8 const& mimeType, DrmPlugin::KeyType keyType,
+ KeyedVector<String8, String8> const& optionalParameters,
+ Vector<uint8_t>& request, String8& defaultUrl,
+ DrmPlugin::KeyRequestType* keyRequestType) {
if (mDrmHalAidl->initCheck() == OK)
return mDrmHalAidl->getKeyRequest(sessionId, initData, mimeType, keyType,
optionalParameters, request, defaultUrl, keyRequestType);
@@ -81,212 +82,212 @@
request, defaultUrl, keyRequestType);
}
-status_t DrmHal::provideKeyResponse(Vector<uint8_t> const& sessionId,
- Vector<uint8_t> const& response, Vector<uint8_t>& keySetId) {
+DrmStatus DrmHal::provideKeyResponse(Vector<uint8_t> const& sessionId,
+ Vector<uint8_t> const& response, Vector<uint8_t>& keySetId) {
if (mDrmHalAidl->initCheck() == OK)
return mDrmHalAidl->provideKeyResponse(sessionId, response, keySetId);
return mDrmHalHidl->provideKeyResponse(sessionId, response, keySetId);
}
-status_t DrmHal::removeKeys(Vector<uint8_t> const& keySetId) {
+DrmStatus DrmHal::removeKeys(Vector<uint8_t> const& keySetId) {
if (mDrmHalAidl->initCheck() == OK) return mDrmHalAidl->removeKeys(keySetId);
return mDrmHalHidl->removeKeys(keySetId);
}
-status_t DrmHal::restoreKeys(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keySetId) {
+DrmStatus DrmHal::restoreKeys(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keySetId) {
if (mDrmHalAidl->initCheck() == OK) return mDrmHalAidl->restoreKeys(sessionId, keySetId);
return mDrmHalHidl->restoreKeys(sessionId, keySetId);
}
-status_t DrmHal::queryKeyStatus(Vector<uint8_t> const& sessionId,
- KeyedVector<String8, String8>& infoMap) const {
+DrmStatus DrmHal::queryKeyStatus(Vector<uint8_t> const& sessionId,
+ KeyedVector<String8, String8>& infoMap) const {
if (mDrmHalAidl->initCheck() == OK) return mDrmHalAidl->queryKeyStatus(sessionId, infoMap);
return mDrmHalHidl->queryKeyStatus(sessionId, infoMap);
}
-status_t DrmHal::getProvisionRequest(String8 const& certType, String8 const& certAuthority,
- Vector<uint8_t>& request, String8& defaultUrl) {
+DrmStatus DrmHal::getProvisionRequest(String8 const& certType, String8 const& certAuthority,
+ Vector<uint8_t>& request, String8& defaultUrl) {
if (mDrmHalAidl->initCheck() == OK)
return mDrmHalAidl->getProvisionRequest(certType, certAuthority, request, defaultUrl);
return mDrmHalHidl->getProvisionRequest(certType, certAuthority, request, defaultUrl);
}
-status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const& response,
- Vector<uint8_t>& certificate,
- Vector<uint8_t>& wrappedKey) {
+DrmStatus DrmHal::provideProvisionResponse(Vector<uint8_t> const& response,
+ Vector<uint8_t>& certificate,
+ Vector<uint8_t>& wrappedKey) {
if (mDrmHalAidl->initCheck() == OK)
return mDrmHalAidl->provideProvisionResponse(response, certificate, wrappedKey);
return mDrmHalHidl->provideProvisionResponse(response, certificate, wrappedKey);
}
-status_t DrmHal::getSecureStops(List<Vector<uint8_t>>& secureStops) {
+DrmStatus DrmHal::getSecureStops(List<Vector<uint8_t>>& secureStops) {
if (mDrmHalAidl->initCheck() == OK) return mDrmHalAidl->getSecureStops(secureStops);
return mDrmHalHidl->getSecureStops(secureStops);
}
-status_t DrmHal::getSecureStopIds(List<Vector<uint8_t>>& secureStopIds) {
+DrmStatus DrmHal::getSecureStopIds(List<Vector<uint8_t>>& secureStopIds) {
if (mDrmHalAidl->initCheck() == OK) return mDrmHalAidl->getSecureStopIds(secureStopIds);
return mDrmHalHidl->getSecureStopIds(secureStopIds);
}
-status_t DrmHal::getSecureStop(Vector<uint8_t> const& ssid, Vector<uint8_t>& secureStop) {
+DrmStatus DrmHal::getSecureStop(Vector<uint8_t> const& ssid, Vector<uint8_t>& secureStop) {
if (mDrmHalAidl->initCheck() == OK) return mDrmHalAidl->getSecureStop(ssid, secureStop);
return mDrmHalHidl->getSecureStop(ssid, secureStop);
}
-status_t DrmHal::releaseSecureStops(Vector<uint8_t> const& ssRelease) {
+DrmStatus DrmHal::releaseSecureStops(Vector<uint8_t> const& ssRelease) {
if (mDrmHalAidl->initCheck() == OK) return mDrmHalAidl->releaseSecureStops(ssRelease);
return mDrmHalHidl->releaseSecureStops(ssRelease);
}
-status_t DrmHal::removeSecureStop(Vector<uint8_t> const& ssid) {
+DrmStatus DrmHal::removeSecureStop(Vector<uint8_t> const& ssid) {
if (mDrmHalAidl->initCheck() == OK) return mDrmHalAidl->removeSecureStop(ssid);
return mDrmHalHidl->removeSecureStop(ssid);
}
-status_t DrmHal::removeAllSecureStops() {
+DrmStatus DrmHal::removeAllSecureStops() {
if (mDrmHalAidl->initCheck() == OK) return mDrmHalAidl->removeAllSecureStops();
return mDrmHalHidl->removeAllSecureStops();
}
-status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel* connectedLevel,
- DrmPlugin::HdcpLevel* maxLevel) const {
+DrmStatus DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel* connectedLevel,
+ DrmPlugin::HdcpLevel* maxLevel) const {
if (mDrmHalAidl->initCheck() == OK) return mDrmHalAidl->getHdcpLevels(connectedLevel, maxLevel);
return mDrmHalHidl->getHdcpLevels(connectedLevel, maxLevel);
}
-status_t DrmHal::getNumberOfSessions(uint32_t* currentSessions, uint32_t* maxSessions) const {
+DrmStatus DrmHal::getNumberOfSessions(uint32_t* currentSessions, uint32_t* maxSessions) const {
if (mDrmHalAidl->initCheck() == OK)
return mDrmHalAidl->getNumberOfSessions(currentSessions, maxSessions);
return mDrmHalHidl->getNumberOfSessions(currentSessions, maxSessions);
}
-status_t DrmHal::getSecurityLevel(Vector<uint8_t> const& sessionId,
- DrmPlugin::SecurityLevel* level) const {
+DrmStatus DrmHal::getSecurityLevel(Vector<uint8_t> const& sessionId,
+ DrmPlugin::SecurityLevel* level) const {
if (mDrmHalAidl->initCheck() == OK) return mDrmHalAidl->getSecurityLevel(sessionId, level);
return mDrmHalHidl->getSecurityLevel(sessionId, level);
}
-status_t DrmHal::getOfflineLicenseKeySetIds(List<Vector<uint8_t>>& keySetIds) const {
+DrmStatus DrmHal::getOfflineLicenseKeySetIds(List<Vector<uint8_t>>& keySetIds) const {
if (mDrmHalAidl->initCheck() == OK) return mDrmHalAidl->getOfflineLicenseKeySetIds(keySetIds);
return mDrmHalHidl->getOfflineLicenseKeySetIds(keySetIds);
}
-status_t DrmHal::removeOfflineLicense(Vector<uint8_t> const& keySetId) {
+DrmStatus DrmHal::removeOfflineLicense(Vector<uint8_t> const& keySetId) {
if (mDrmHalAidl->initCheck() == OK) return mDrmHalAidl->removeOfflineLicense(keySetId);
return mDrmHalHidl->removeOfflineLicense(keySetId);
}
-status_t DrmHal::getOfflineLicenseState(Vector<uint8_t> const& keySetId,
- DrmPlugin::OfflineLicenseState* licenseState) const {
+DrmStatus DrmHal::getOfflineLicenseState(Vector<uint8_t> const& keySetId,
+ DrmPlugin::OfflineLicenseState* licenseState) const {
if (mDrmHalAidl->initCheck() == OK)
return mDrmHalAidl->getOfflineLicenseState(keySetId, licenseState);
return mDrmHalHidl->getOfflineLicenseState(keySetId, licenseState);
}
-status_t DrmHal::getPropertyString(String8 const& name, String8& value) const {
+DrmStatus DrmHal::getPropertyString(String8 const& name, String8& value) const {
if (mDrmHalAidl->initCheck() == OK) return mDrmHalAidl->getPropertyString(name, value);
return mDrmHalHidl->getPropertyString(name, value);
}
-status_t DrmHal::getPropertyByteArray(String8 const& name, Vector<uint8_t>& value) const {
+DrmStatus DrmHal::getPropertyByteArray(String8 const& name, Vector<uint8_t>& value) const {
if (mDrmHalAidl->initCheck() == OK) return mDrmHalAidl->getPropertyByteArray(name, value);
return mDrmHalHidl->getPropertyByteArray(name, value);
}
-status_t DrmHal::setPropertyString(String8 const& name, String8 const& value) const {
+DrmStatus DrmHal::setPropertyString(String8 const& name, String8 const& value) const {
if (mDrmHalAidl->initCheck() == OK) return mDrmHalAidl->setPropertyString(name, value);
return mDrmHalHidl->setPropertyString(name, value);
}
-status_t DrmHal::setPropertyByteArray(String8 const& name, Vector<uint8_t> const& value) const {
+DrmStatus DrmHal::setPropertyByteArray(String8 const& name, Vector<uint8_t> const& value) const {
if (mDrmHalAidl->initCheck() == OK) return mDrmHalAidl->setPropertyByteArray(name, value);
return mDrmHalHidl->setPropertyByteArray(name, value);
}
-status_t DrmHal::getMetrics(const sp<IDrmMetricsConsumer>& consumer) {
+DrmStatus DrmHal::getMetrics(const sp<IDrmMetricsConsumer>& consumer) {
if (mDrmHalAidl->initCheck() == OK) return mDrmHalAidl->getMetrics(consumer);
return mDrmHalHidl->getMetrics(consumer);
}
-status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const& sessionId, String8 const& algorithm) {
+DrmStatus DrmHal::setCipherAlgorithm(Vector<uint8_t> const& sessionId, String8 const& algorithm) {
if (mDrmHalAidl->initCheck() == OK)
return mDrmHalAidl->setCipherAlgorithm(sessionId, algorithm);
return mDrmHalHidl->setCipherAlgorithm(sessionId, algorithm);
}
-status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const& sessionId, String8 const& algorithm) {
+DrmStatus DrmHal::setMacAlgorithm(Vector<uint8_t> const& sessionId, String8 const& algorithm) {
if (mDrmHalAidl->initCheck() == OK) return mDrmHalAidl->setMacAlgorithm(sessionId, algorithm);
return mDrmHalHidl->setMacAlgorithm(sessionId, algorithm);
}
-status_t DrmHal::encrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
- Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
- Vector<uint8_t>& output) {
+DrmStatus DrmHal::encrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
+ Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
+ Vector<uint8_t>& output) {
if (mDrmHalAidl->initCheck() == OK)
return mDrmHalAidl->encrypt(sessionId, keyId, input, iv, output);
return mDrmHalHidl->encrypt(sessionId, keyId, input, iv, output);
}
-status_t DrmHal::decrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
- Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
- Vector<uint8_t>& output) {
+DrmStatus DrmHal::decrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
+ Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
+ Vector<uint8_t>& output) {
if (mDrmHalAidl->initCheck() == OK)
return mDrmHalAidl->decrypt(sessionId, keyId, input, iv, output);
return mDrmHalHidl->decrypt(sessionId, keyId, input, iv, output);
}
-status_t DrmHal::sign(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
- Vector<uint8_t> const& message, Vector<uint8_t>& signature) {
+DrmStatus DrmHal::sign(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
+ Vector<uint8_t> const& message, Vector<uint8_t>& signature) {
if (mDrmHalAidl->initCheck() == OK)
return mDrmHalAidl->sign(sessionId, keyId, message, signature);
return mDrmHalHidl->sign(sessionId, keyId, message, signature);
}
-status_t DrmHal::verify(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
- Vector<uint8_t> const& message, Vector<uint8_t> const& signature,
- bool& match) {
+DrmStatus DrmHal::verify(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
+ Vector<uint8_t> const& message, Vector<uint8_t> const& signature,
+ bool& match) {
if (mDrmHalAidl->initCheck() == OK)
return mDrmHalAidl->verify(sessionId, keyId, message, signature, match);
return mDrmHalHidl->verify(sessionId, keyId, message, signature, match);
}
-status_t DrmHal::signRSA(Vector<uint8_t> const& sessionId, String8 const& algorithm,
- Vector<uint8_t> const& message, Vector<uint8_t> const& wrappedKey,
- Vector<uint8_t>& signature) {
+DrmStatus DrmHal::signRSA(Vector<uint8_t> const& sessionId, String8 const& algorithm,
+ Vector<uint8_t> const& message, Vector<uint8_t> const& wrappedKey,
+ Vector<uint8_t>& signature) {
if (mDrmHalAidl->initCheck() == OK)
return mDrmHalAidl->signRSA(sessionId, algorithm, message, wrappedKey, signature);
return mDrmHalHidl->signRSA(sessionId, algorithm, message, wrappedKey, signature);
}
-status_t DrmHal::setListener(const sp<IDrmClient>& listener) {
+DrmStatus DrmHal::setListener(const sp<IDrmClient>& listener) {
if (mDrmHalAidl->initCheck() == OK) return mDrmHalAidl->setListener(listener);
return mDrmHalHidl->setListener(listener);
}
-status_t DrmHal::requiresSecureDecoder(const char* mime, bool* required) const {
+DrmStatus DrmHal::requiresSecureDecoder(const char* mime, bool* required) const {
if (mDrmHalAidl->initCheck() == OK) return mDrmHalAidl->requiresSecureDecoder(mime, required);
return mDrmHalHidl->requiresSecureDecoder(mime, required);
}
-status_t DrmHal::requiresSecureDecoder(const char* mime, DrmPlugin::SecurityLevel securityLevel,
- bool* required) const {
+DrmStatus DrmHal::requiresSecureDecoder(const char* mime, DrmPlugin::SecurityLevel securityLevel,
+ bool* required) const {
if (mDrmHalAidl->initCheck() == OK)
return mDrmHalAidl->requiresSecureDecoder(mime, securityLevel, required);
return mDrmHalHidl->requiresSecureDecoder(mime, securityLevel, required);
}
-status_t DrmHal::setPlaybackId(Vector<uint8_t> const& sessionId, const char* playbackId) {
+DrmStatus DrmHal::setPlaybackId(Vector<uint8_t> const& sessionId, const char* playbackId) {
if (mDrmHalAidl->initCheck() == OK) return mDrmHalAidl->setPlaybackId(sessionId, playbackId);
return mDrmHalHidl->setPlaybackId(sessionId, playbackId);
}
-status_t DrmHal::getLogMessages(Vector<drm::V1_4::LogMessage>& logs) const {
+DrmStatus DrmHal::getLogMessages(Vector<drm::V1_4::LogMessage>& logs) const {
if (mDrmHalAidl->initCheck() == OK) return mDrmHalAidl->getLogMessages(logs);
return mDrmHalHidl->getLogMessages(logs);
}
-status_t DrmHal::getSupportedSchemes(std::vector<uint8_t> &schemes) const {
+DrmStatus DrmHal::getSupportedSchemes(std::vector<uint8_t>& schemes) const {
status_t statusResult;
statusResult = mDrmHalAidl->getSupportedSchemes(schemes);
if (statusResult == OK) return statusResult;
diff --git a/drm/libmediadrm/DrmHalAidl.cpp b/drm/libmediadrm/DrmHalAidl.cpp
index bdd83e9..c369529 100644
--- a/drm/libmediadrm/DrmHalAidl.cpp
+++ b/drm/libmediadrm/DrmHalAidl.cpp
@@ -29,9 +29,9 @@
#include <media/stagefright/foundation/hexdump.h>
#include <mediadrm/DrmHalAidl.h>
#include <mediadrm/DrmSessionManager.h>
+#include <mediadrm/DrmStatus.h>
#include <mediadrm/DrmUtils.h>
-using ::android::DrmUtils::statusAidlToStatusT;
using ::aidl::android::hardware::drm::CryptoSchemes;
using ::aidl::android::hardware::drm::DrmMetricNamedValue;
using ::aidl::android::hardware::drm::DrmMetricValue;
@@ -55,6 +55,7 @@
using ::aidl::android::hardware::drm::Status;
using ::aidl::android::hardware::drm::SupportedContentType;
using ::aidl::android::hardware::drm::Uuid;
+using ::android::DrmUtils::statusAidlToDrmStatus;
using DrmMetricGroupAidl = ::aidl::android::hardware::drm::DrmMetricGroup;
using DrmMetricGroupHidl = ::android::hardware::drm::V1_1::DrmMetricGroup;
using DrmMetricAidl = ::aidl::android::hardware::drm::DrmMetric;
@@ -396,19 +397,19 @@
mFactories(DrmUtils::makeDrmFactoriesAidl()),
mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {}
-status_t DrmHalAidl::initCheck() const {
- return mInitCheck;
+DrmStatus DrmHalAidl::initCheck() const {
+ return DrmStatus(mInitCheck);
}
DrmHalAidl::~DrmHalAidl() {}
-status_t DrmHalAidl::setListener(const sp<IDrmClient>& listener) {
+DrmStatus DrmHalAidl::setListener(const sp<IDrmClient>& listener) {
mListener->setListener(listener);
- return NO_ERROR;
+ return DrmStatus(NO_ERROR);
}
-status_t DrmHalAidl::isCryptoSchemeSupported(const uint8_t uuid[16], const String8& mimeType,
- DrmPlugin::SecurityLevel level, bool* isSupported) {
+DrmStatus DrmHalAidl::isCryptoSchemeSupported(const uint8_t uuid[16], const String8& mimeType,
+ DrmPlugin::SecurityLevel level, bool* isSupported) {
Mutex::Autolock autoLock(mLock);
*isSupported = false;
Uuid uuidAidl = DrmUtils::toAidlUuid(uuid);
@@ -438,9 +439,9 @@
// isCryptoSchemeSupported(uuid, mimeType)
*isSupported = contentTypes.count(mimeTypeStr);
}
- return OK;
+ return DrmStatus(OK);
} else if (mimeType == "") {
- return BAD_VALUE;
+ return DrmStatus(BAD_VALUE);
}
auto ct = contentTypes[mimeTypeStr];
@@ -452,10 +453,10 @@
break;
}
- return OK;
+ return DrmStatus(OK);
}
-status_t DrmHalAidl::createPlugin(const uint8_t uuid[16], const String8& appPackageName) {
+DrmStatus DrmHalAidl::createPlugin(const uint8_t uuid[16], const String8& appPackageName) {
Mutex::Autolock autoLock(mLock);
Uuid uuidAidl = DrmUtils::toAidlUuid(uuid);
@@ -497,10 +498,10 @@
}
}
- return mInitCheck;
+ return DrmStatus(mInitCheck);
}
-status_t DrmHalAidl::openSession(DrmPlugin::SecurityLevel level, Vector<uint8_t>& sessionId) {
+DrmStatus DrmHalAidl::openSession(DrmPlugin::SecurityLevel level, Vector<uint8_t>& sessionId) {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
@@ -510,14 +511,14 @@
return ERROR_DRM_CANNOT_HANDLE;
}
- status_t err = UNKNOWN_ERROR;
+ DrmStatus err = UNKNOWN_ERROR;
bool retry = true;
do {
std::vector<uint8_t> aSessionId;
::ndk::ScopedAStatus status = mPlugin->openSession(aSecurityLevel, &aSessionId);
if (status.isOk()) sessionId = toVector(aSessionId);
- err = statusAidlToStatusT(status);
+ err = statusAidlToDrmStatus(status);
if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
mLock.unlock();
@@ -545,13 +546,13 @@
return err;
}
-status_t DrmHalAidl::closeSession(Vector<uint8_t> const& sessionId) {
+DrmStatus DrmHalAidl::closeSession(Vector<uint8_t> const& sessionId) {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
std::vector<uint8_t> sessionIdAidl = toStdVec(sessionId);
::ndk::ScopedAStatus status = mPlugin->closeSession(sessionIdAidl);
- status_t response = statusAidlToStatusT(status);
+ DrmStatus response = statusAidlToDrmStatus(status);
if (status.isOk()) {
DrmSessionManager::Instance()->removeSession(sessionId);
for (auto i = mOpenSessions.begin(); i != mOpenSessions.end(); i++) {
@@ -568,12 +569,12 @@
return response;
}
-status_t DrmHalAidl::getKeyRequest(Vector<uint8_t> const& sessionId,
- Vector<uint8_t> const& initData, String8 const& mimeType,
- DrmPlugin::KeyType keyType,
- KeyedVector<String8, String8> const& optionalParameters,
- Vector<uint8_t>& request, String8& defaultUrl,
- DrmPlugin::KeyRequestType* keyRequestType) {
+DrmStatus DrmHalAidl::getKeyRequest(Vector<uint8_t> const& sessionId,
+ Vector<uint8_t> const& initData, String8 const& mimeType,
+ DrmPlugin::KeyType keyType,
+ KeyedVector<String8, String8> const& optionalParameters,
+ Vector<uint8_t>& request, String8& defaultUrl,
+ DrmPlugin::KeyRequestType* keyRequestType) {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTimeUs);
@@ -592,7 +593,7 @@
return BAD_VALUE;
}
- status_t err = UNKNOWN_ERROR;
+ DrmStatus err = UNKNOWN_ERROR;
std::vector<uint8_t> sessionIdAidl = toStdVec(sessionId);
std::vector<uint8_t> initDataAidl = toStdVec(initData);
@@ -607,21 +608,21 @@
*keyRequestType = toKeyRequestType(keyRequest.requestType);
}
- err = statusAidlToStatusT(status);
+ err = statusAidlToDrmStatus(status);
keyRequestTimer.SetAttribute(err);
return err;
}
-status_t DrmHalAidl::provideKeyResponse(Vector<uint8_t> const& sessionId,
- Vector<uint8_t> const& response,
- Vector<uint8_t>& keySetId) {
+DrmStatus DrmHalAidl::provideKeyResponse(Vector<uint8_t> const& sessionId,
+ Vector<uint8_t> const& response,
+ Vector<uint8_t>& keySetId) {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTimeUs);
DrmSessionManager::Instance()->useSession(sessionId);
- status_t err = UNKNOWN_ERROR;
+ DrmStatus err = UNKNOWN_ERROR;
std::vector<uint8_t> sessionIdAidl = toStdVec(sessionId);
std::vector<uint8_t> responseAidl = toStdVec(response);
@@ -630,21 +631,21 @@
mPlugin->provideKeyResponse(sessionIdAidl, responseAidl, &keySetIdsAidl);
if (status.isOk()) keySetId = toVector(keySetIdsAidl.keySetId);
- err = statusAidlToStatusT(status);
+ err = statusAidlToDrmStatus(status);
keyResponseTimer.SetAttribute(err);
return err;
}
-status_t DrmHalAidl::removeKeys(Vector<uint8_t> const& keySetId) {
+DrmStatus DrmHalAidl::removeKeys(Vector<uint8_t> const& keySetId) {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
::ndk::ScopedAStatus status = mPlugin->removeKeys(toStdVec(keySetId));
- return statusAidlToStatusT(status);
+ return statusAidlToDrmStatus(status);
}
-status_t DrmHalAidl::restoreKeys(Vector<uint8_t> const& sessionId,
- Vector<uint8_t> const& keySetId) {
+DrmStatus DrmHalAidl::restoreKeys(Vector<uint8_t> const& sessionId,
+ Vector<uint8_t> const& keySetId) {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
@@ -653,11 +654,11 @@
KeySetId keySetIdsAidl;
keySetIdsAidl.keySetId = toStdVec(keySetId);
::ndk::ScopedAStatus status = mPlugin->restoreKeys(toStdVec(sessionId), keySetIdsAidl);
- return statusAidlToStatusT(status);
+ return statusAidlToDrmStatus(status);
}
-status_t DrmHalAidl::queryKeyStatus(Vector<uint8_t> const& sessionId,
- KeyedVector<String8, String8>& infoMap) const {
+DrmStatus DrmHalAidl::queryKeyStatus(Vector<uint8_t> const& sessionId,
+ KeyedVector<String8, String8>& infoMap) const {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
@@ -668,15 +669,15 @@
infoMap = toKeyedVector(infoMapAidl);
- return statusAidlToStatusT(status);
+ return statusAidlToDrmStatus(status);
}
-status_t DrmHalAidl::getProvisionRequest(String8 const& certType, String8 const& certAuthority,
- Vector<uint8_t>& request, String8& defaultUrl) {
+DrmStatus DrmHalAidl::getProvisionRequest(String8 const& certType, String8 const& certAuthority,
+ Vector<uint8_t>& request, String8& defaultUrl) {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
- status_t err = UNKNOWN_ERROR;
+ DrmStatus err = UNKNOWN_ERROR;
ProvisionRequest requestAidl;
::ndk::ScopedAStatus status = mPlugin->getProvisionRequest(
@@ -685,29 +686,29 @@
request = toVector(requestAidl.request);
defaultUrl = toString8(requestAidl.defaultUrl);
- err = statusAidlToStatusT(status);
+ err = statusAidlToDrmStatus(status);
mMetrics.mGetProvisionRequestCounter.Increment(err);
return err;
}
-status_t DrmHalAidl::provideProvisionResponse(Vector<uint8_t> const& response,
- Vector<uint8_t>& certificate,
- Vector<uint8_t>& wrappedKey) {
+DrmStatus DrmHalAidl::provideProvisionResponse(Vector<uint8_t> const& response,
+ Vector<uint8_t>& certificate,
+ Vector<uint8_t>& wrappedKey) {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
- status_t err = UNKNOWN_ERROR;
+ DrmStatus err = UNKNOWN_ERROR;
ProvideProvisionResponseResult result;
::ndk::ScopedAStatus status = mPlugin->provideProvisionResponse(toStdVec(response), &result);
certificate = toVector(result.certificate);
wrappedKey = toVector(result.wrappedKey);
- err = statusAidlToStatusT(status);
+ err = statusAidlToDrmStatus(status);
mMetrics.mProvideProvisionResponseCounter.Increment(err);
return err;
}
-status_t DrmHalAidl::getSecureStops(List<Vector<uint8_t>>& secureStops) {
+DrmStatus DrmHalAidl::getSecureStops(List<Vector<uint8_t>>& secureStops) {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
@@ -716,10 +717,10 @@
secureStops = toSecureStops(result);
- return statusAidlToStatusT(status);
+ return statusAidlToDrmStatus(status);
}
-status_t DrmHalAidl::getSecureStopIds(List<Vector<uint8_t>>& secureStopIds) {
+DrmStatus DrmHalAidl::getSecureStopIds(List<Vector<uint8_t>>& secureStopIds) {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
@@ -728,10 +729,10 @@
secureStopIds = toSecureStopIds(result);
- return statusAidlToStatusT(status);
+ return statusAidlToDrmStatus(status);
}
-status_t DrmHalAidl::getSecureStop(Vector<uint8_t> const& ssid, Vector<uint8_t>& secureStop) {
+DrmStatus DrmHalAidl::getSecureStop(Vector<uint8_t> const& ssid, Vector<uint8_t>& secureStop) {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
@@ -743,10 +744,10 @@
secureStop = toVector(result.opaqueData);
- return statusAidlToStatusT(status);
+ return statusAidlToDrmStatus(status);
}
-status_t DrmHalAidl::releaseSecureStops(Vector<uint8_t> const& ssRelease) {
+DrmStatus DrmHalAidl::releaseSecureStops(Vector<uint8_t> const& ssRelease) {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
@@ -754,10 +755,10 @@
ssId.opaqueData = toStdVec(ssRelease);
::ndk::ScopedAStatus status = mPlugin->releaseSecureStops(ssId);
- return statusAidlToStatusT(status);
+ return statusAidlToDrmStatus(status);
}
-status_t DrmHalAidl::removeSecureStop(Vector<uint8_t> const& ssid) {
+DrmStatus DrmHalAidl::removeSecureStop(Vector<uint8_t> const& ssid) {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
@@ -765,19 +766,19 @@
SecureStopId ssidAidl;
ssidAidl.secureStopId = toStdVec(ssid);
::ndk::ScopedAStatus status = mPlugin->removeSecureStop(ssidAidl);
- return statusAidlToStatusT(status);
+ return statusAidlToDrmStatus(status);
}
-status_t DrmHalAidl::removeAllSecureStops() {
+DrmStatus DrmHalAidl::removeAllSecureStops() {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
::ndk::ScopedAStatus status = mPlugin->releaseAllSecureStops();
- return statusAidlToStatusT(status);
+ return statusAidlToDrmStatus(status);
}
-status_t DrmHalAidl::getHdcpLevels(DrmPlugin::HdcpLevel* connected,
- DrmPlugin::HdcpLevel* max) const {
+DrmStatus DrmHalAidl::getHdcpLevels(DrmPlugin::HdcpLevel* connected,
+ DrmPlugin::HdcpLevel* max) const {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
@@ -794,10 +795,10 @@
*connected = toHdcpLevel(lvlsAidl.connectedLevel);
*max = toHdcpLevel(lvlsAidl.maxLevel);
- return statusAidlToStatusT(status);
+ return statusAidlToDrmStatus(status);
}
-status_t DrmHalAidl::getNumberOfSessions(uint32_t* open, uint32_t* max) const {
+DrmStatus DrmHalAidl::getNumberOfSessions(uint32_t* open, uint32_t* max) const {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
@@ -814,11 +815,11 @@
*open = result.currentSessions;
*max = result.maxSessions;
- return statusAidlToStatusT(status);
+ return statusAidlToDrmStatus(status);
}
-status_t DrmHalAidl::getSecurityLevel(Vector<uint8_t> const& sessionId,
- DrmPlugin::SecurityLevel* level) const {
+DrmStatus DrmHalAidl::getSecurityLevel(Vector<uint8_t> const& sessionId,
+ DrmPlugin::SecurityLevel* level) const {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
@@ -833,10 +834,10 @@
*level = toSecurityLevel(result);
- return statusAidlToStatusT(status);
+ return statusAidlToDrmStatus(status);
}
-status_t DrmHalAidl::getOfflineLicenseKeySetIds(List<Vector<uint8_t>>& keySetIds) const {
+DrmStatus DrmHalAidl::getOfflineLicenseKeySetIds(List<Vector<uint8_t>>& keySetIds) const {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
@@ -845,21 +846,21 @@
keySetIds = toKeySetIds(result);
- return statusAidlToStatusT(status);
+ return statusAidlToDrmStatus(status);
}
-status_t DrmHalAidl::removeOfflineLicense(Vector<uint8_t> const& keySetId) {
+DrmStatus DrmHalAidl::removeOfflineLicense(Vector<uint8_t> const& keySetId) {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
KeySetId keySetIdAidl;
keySetIdAidl.keySetId = toStdVec(keySetId);
::ndk::ScopedAStatus status = mPlugin->removeOfflineLicense(keySetIdAidl);
- return statusAidlToStatusT(status);
+ return statusAidlToDrmStatus(status);
}
-status_t DrmHalAidl::getOfflineLicenseState(Vector<uint8_t> const& keySetId,
- DrmPlugin::OfflineLicenseState* licenseState) const {
+DrmStatus DrmHalAidl::getOfflineLicenseState(Vector<uint8_t> const& keySetId,
+ DrmPlugin::OfflineLicenseState* licenseState) const {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
@@ -873,15 +874,15 @@
*licenseState = toOfflineLicenseState(result);
- return statusAidlToStatusT(status);
+ return statusAidlToDrmStatus(status);
}
-status_t DrmHalAidl::getPropertyString(String8 const& name, String8& value) const {
+DrmStatus DrmHalAidl::getPropertyString(String8 const& name, String8& value) const {
Mutex::Autolock autoLock(mLock);
- return getPropertyStringInternal(name, value);
+ return DrmStatus(getPropertyStringInternal(name, value));
}
-status_t DrmHalAidl::getPropertyStringInternal(String8 const& name, String8& value) const {
+DrmStatus DrmHalAidl::getPropertyStringInternal(String8 const& name, String8& value) const {
// This function is internal to the class and should only be called while
// mLock is already held.
INIT_CHECK();
@@ -891,52 +892,53 @@
value = toString8(result);
- return statusAidlToStatusT(status);
+ return statusAidlToDrmStatus(status);
}
-status_t DrmHalAidl::getPropertyByteArray(String8 const& name, Vector<uint8_t>& value) const {
+DrmStatus DrmHalAidl::getPropertyByteArray(String8 const& name, Vector<uint8_t>& value) const {
Mutex::Autolock autoLock(mLock);
- return getPropertyByteArrayInternal(name, value);
+ return DrmStatus(getPropertyByteArrayInternal(name, value));
}
-status_t DrmHalAidl::getPropertyByteArrayInternal(String8 const& name,
- Vector<uint8_t>& value) const {
+DrmStatus DrmHalAidl::getPropertyByteArrayInternal(String8 const& name,
+ Vector<uint8_t>& value) const {
// This function is internal to the class and should only be called while
// mLock is already held.
INIT_CHECK();
- status_t err = UNKNOWN_ERROR;
+ DrmStatus err = UNKNOWN_ERROR;
std::vector<uint8_t> result;
::ndk::ScopedAStatus status = mPlugin->getPropertyByteArray(toStdString(name), &result);
value = toVector(result);
- err = statusAidlToStatusT(status);
+ err = statusAidlToDrmStatus(status);
if (name == kPropertyDeviceUniqueId) {
mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
}
return err;
}
-status_t DrmHalAidl::setPropertyString(String8 const& name, String8 const& value) const {
+DrmStatus DrmHalAidl::setPropertyString(String8 const& name, String8 const& value) const {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
::ndk::ScopedAStatus status = mPlugin->setPropertyString(toStdString(name), toStdString(value));
- return statusAidlToStatusT(status);
+ return statusAidlToDrmStatus(status);
}
-status_t DrmHalAidl::setPropertyByteArray(String8 const& name, Vector<uint8_t> const& value) const {
+DrmStatus DrmHalAidl::setPropertyByteArray(String8 const& name,
+ Vector<uint8_t> const& value) const {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
::ndk::ScopedAStatus status = mPlugin->setPropertyByteArray(toStdString(name), toStdVec(value));
- return statusAidlToStatusT(status);
+ return statusAidlToDrmStatus(status);
}
-status_t DrmHalAidl::getMetrics(const sp<IDrmMetricsConsumer>& consumer) {
+DrmStatus DrmHalAidl::getMetrics(const sp<IDrmMetricsConsumer>& consumer) {
if (consumer == nullptr) {
- return UNEXPECTED_NULL;
+ return DrmStatus(UNEXPECTED_NULL);
}
consumer->consumeFrameworkMetrics(mMetrics);
@@ -957,7 +959,7 @@
vendor += description;
hidl_vec<DrmMetricGroupHidl> pluginMetrics;
- status_t err = UNKNOWN_ERROR;
+ DrmStatus err = UNKNOWN_ERROR;
std::vector<DrmMetricGroupAidl> result;
::ndk::ScopedAStatus status = mPlugin->getMetrics(&result);
@@ -967,13 +969,13 @@
consumer->consumeHidlMetrics(vendor, pluginMetrics);
}
- err = statusAidlToStatusT(status);
+ err = statusAidlToDrmStatus(status);
return err;
}
-status_t DrmHalAidl::setCipherAlgorithm(Vector<uint8_t> const& sessionId,
- String8 const& algorithm) {
+DrmStatus DrmHalAidl::setCipherAlgorithm(Vector<uint8_t> const& sessionId,
+ String8 const& algorithm) {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
@@ -981,10 +983,10 @@
::ndk::ScopedAStatus status =
mPlugin->setCipherAlgorithm(toStdVec(sessionId), toStdString(algorithm));
- return statusAidlToStatusT(status);
+ return statusAidlToDrmStatus(status);
}
-status_t DrmHalAidl::setMacAlgorithm(Vector<uint8_t> const& sessionId, String8 const& algorithm) {
+DrmStatus DrmHalAidl::setMacAlgorithm(Vector<uint8_t> const& sessionId, String8 const& algorithm) {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
@@ -992,12 +994,12 @@
::ndk::ScopedAStatus status =
mPlugin->setMacAlgorithm(toStdVec(sessionId), toStdString(algorithm));
- return statusAidlToStatusT(status);
+ return statusAidlToDrmStatus(status);
}
-status_t DrmHalAidl::encrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
- Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
- Vector<uint8_t>& output) {
+DrmStatus DrmHalAidl::encrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
+ Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
+ Vector<uint8_t>& output) {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
@@ -1009,12 +1011,12 @@
output = toVector(result);
- return statusAidlToStatusT(status);
+ return statusAidlToDrmStatus(status);
}
-status_t DrmHalAidl::decrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
- Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
- Vector<uint8_t>& output) {
+DrmStatus DrmHalAidl::decrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
+ Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
+ Vector<uint8_t>& output) {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
@@ -1026,11 +1028,11 @@
output = toVector(result);
- return statusAidlToStatusT(status);
+ return statusAidlToDrmStatus(status);
}
-status_t DrmHalAidl::sign(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
- Vector<uint8_t> const& message, Vector<uint8_t>& signature) {
+DrmStatus DrmHalAidl::sign(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
+ Vector<uint8_t> const& message, Vector<uint8_t>& signature) {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
@@ -1042,12 +1044,12 @@
signature = toVector(result);
- return statusAidlToStatusT(status);
+ return statusAidlToDrmStatus(status);
}
-status_t DrmHalAidl::verify(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
- Vector<uint8_t> const& message, Vector<uint8_t> const& signature,
- bool& match) {
+DrmStatus DrmHalAidl::verify(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
+ Vector<uint8_t> const& message, Vector<uint8_t> const& signature,
+ bool& match) {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
@@ -1056,12 +1058,12 @@
::ndk::ScopedAStatus status = mPlugin->verify(toStdVec(sessionId), toStdVec(keyId),
toStdVec(message), toStdVec(signature), &match);
- return statusAidlToStatusT(status);
+ return statusAidlToDrmStatus(status);
}
-status_t DrmHalAidl::signRSA(Vector<uint8_t> const& sessionId, String8 const& algorithm,
- Vector<uint8_t> const& message, Vector<uint8_t> const& wrappedKey,
- Vector<uint8_t>& signature) {
+DrmStatus DrmHalAidl::signRSA(Vector<uint8_t> const& sessionId, String8 const& algorithm,
+ Vector<uint8_t> const& message, Vector<uint8_t> const& wrappedKey,
+ Vector<uint8_t>& signature) {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
@@ -1074,10 +1076,10 @@
signature = toVector(result);
- return statusAidlToStatusT(status);
+ return statusAidlToDrmStatus(status);
}
-status_t DrmHalAidl::requiresSecureDecoder(const char* mime, bool* required) const {
+DrmStatus DrmHalAidl::requiresSecureDecoder(const char* mime, bool* required) const {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
@@ -1086,14 +1088,15 @@
mPlugin->requiresSecureDecoder(mimeAidl, SecurityLevel::DEFAULT, required);
if (!status.isOk()) {
DrmUtils::LOG2BE("requiresSecureDecoder txn failed: %d", status.getServiceSpecificError());
- return DEAD_OBJECT;
+ return DrmStatus(DEAD_OBJECT);
}
- return OK;
+ return DrmStatus(OK);
}
-status_t DrmHalAidl::requiresSecureDecoder(const char* mime, DrmPlugin::SecurityLevel securityLevel,
- bool* required) const {
+DrmStatus DrmHalAidl::requiresSecureDecoder(const char* mime,
+ DrmPlugin::SecurityLevel securityLevel,
+ bool* required) const {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
@@ -1101,7 +1104,7 @@
std::string mimeAidl(mime);
::ndk::ScopedAStatus status = mPlugin->requiresSecureDecoder(mimeAidl, aLevel, required);
- status_t err = statusAidlToStatusT(status);
+ DrmStatus err = statusAidlToDrmStatus(status);
if (!status.isOk()) {
DrmUtils::LOG2BE("requiresSecureDecoder txn failed: %d", status.getServiceSpecificError());
}
@@ -1109,17 +1112,17 @@
return err;
}
-status_t DrmHalAidl::setPlaybackId(Vector<uint8_t> const& sessionId, const char* playbackId) {
+DrmStatus DrmHalAidl::setPlaybackId(Vector<uint8_t> const& sessionId, const char* playbackId) {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
std::string playbackIdAidl(playbackId);
::ndk::ScopedAStatus status = mPlugin->setPlaybackId(toStdVec(sessionId), playbackIdAidl);
- return statusAidlToStatusT(status);
+ return statusAidlToDrmStatus(status);
}
-status_t DrmHalAidl::getLogMessages(Vector<drm::V1_4::LogMessage>& logs) const {
+DrmStatus DrmHalAidl::getLogMessages(Vector<drm::V1_4::LogMessage>& logs) const {
Mutex::Autolock autoLock(mLock);
- return DrmUtils::GetLogMessagesAidl<IDrmPluginAidl>(mPlugin, logs);
+ return DrmStatus(DrmUtils::GetLogMessagesAidl<IDrmPluginAidl>(mPlugin, logs));
}
void DrmHalAidl::closeOpenSessions() {
@@ -1189,7 +1192,7 @@
return serializedMetrics;
}
-status_t DrmHalAidl::getSupportedSchemes(std::vector<uint8_t> &schemes) const {
+DrmStatus DrmHalAidl::getSupportedSchemes(std::vector<uint8_t>& schemes) const {
Mutex::Autolock autoLock(mLock);
if (mFactories.empty()) return UNKNOWN_ERROR;
@@ -1205,7 +1208,7 @@
}
}
- return OK;
+ return DrmStatus(OK);
}
void DrmHalAidl::cleanup() {
@@ -1225,9 +1228,9 @@
mPlugin.reset();
}
-status_t DrmHalAidl::destroyPlugin() {
+DrmStatus DrmHalAidl::destroyPlugin() {
cleanup();
- return OK;
+ return DrmStatus(OK);
}
::ndk::ScopedAStatus DrmHalAidl::onEvent(EventTypeAidl eventTypeAidl,
diff --git a/drm/libmediadrm/DrmHalHidl.cpp b/drm/libmediadrm/DrmHalHidl.cpp
index c38dbef..7d045ac 100644
--- a/drm/libmediadrm/DrmHalHidl.cpp
+++ b/drm/libmediadrm/DrmHalHidl.cpp
@@ -35,6 +35,7 @@
#include <mediadrm/DrmHalHidl.h>
#include <mediadrm/DrmSessionClientInterface.h>
#include <mediadrm/DrmSessionManager.h>
+#include <mediadrm/DrmStatus.h>
#include <mediadrm/DrmUtils.h>
#include <mediadrm/IDrmMetricsConsumer.h>
#include <utils/Log.h>
@@ -368,14 +369,14 @@
return plugin;
}
-status_t DrmHalHidl::initCheck() const {
- return mInitCheck;
+DrmStatus DrmHalHidl::initCheck() const {
+ return DrmStatus(mInitCheck);
}
-status_t DrmHalHidl::setListener(const sp<IDrmClient>& listener) {
+DrmStatus DrmHalHidl::setListener(const sp<IDrmClient>& listener) {
Mutex::Autolock lock(mEventLock);
mListener = listener;
- return NO_ERROR;
+ return DrmStatus(NO_ERROR);
}
Return<void> DrmHalHidl::sendEvent(EventType hEventType, const hidl_vec<uint8_t>& sessionId,
@@ -502,10 +503,10 @@
return Void();
}
-status_t DrmHalHidl::matchMimeTypeAndSecurityLevel(const sp<IDrmFactory>& factory,
- const uint8_t uuid[16], const String8& mimeType,
- DrmPlugin::SecurityLevel level,
- bool* isSupported) {
+DrmStatus DrmHalHidl::matchMimeTypeAndSecurityLevel(const sp<IDrmFactory>& factory,
+ const uint8_t uuid[16], const String8& mimeType,
+ DrmPlugin::SecurityLevel level,
+ bool* isSupported) {
*isSupported = false;
// handle default value cases
@@ -517,23 +518,23 @@
// isCryptoSchemeSupported(uuid, mimeType)
*isSupported = factory->isContentTypeSupported(mimeType.string());
}
- return OK;
+ return DrmStatus(OK);
} else if (mimeType == "") {
- return BAD_VALUE;
+ return DrmStatus(BAD_VALUE);
}
sp<drm::V1_2::IDrmFactory> factoryV1_2 = drm::V1_2::IDrmFactory::castFrom(factory);
if (factoryV1_2 == NULL) {
- return ERROR_UNSUPPORTED;
+ return DrmStatus(ERROR_UNSUPPORTED);
} else {
*isSupported = factoryV1_2->isCryptoSchemeSupported_1_2(uuid, mimeType.string(),
toHidlSecurityLevel(level));
- return OK;
+ return DrmStatus(OK);
}
}
-status_t DrmHalHidl::isCryptoSchemeSupported(const uint8_t uuid[16], const String8& mimeType,
- DrmPlugin::SecurityLevel level, bool* isSupported) {
+DrmStatus DrmHalHidl::isCryptoSchemeSupported(const uint8_t uuid[16], const String8& mimeType,
+ DrmPlugin::SecurityLevel level, bool* isSupported) {
Mutex::Autolock autoLock(mLock);
*isSupported = false;
for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
@@ -541,10 +542,10 @@
return matchMimeTypeAndSecurityLevel(mFactories[i], uuid, mimeType, level, isSupported);
}
}
- return OK;
+ return DrmStatus(OK);
}
-status_t DrmHalHidl::createPlugin(const uint8_t uuid[16], const String8& appPackageName) {
+DrmStatus DrmHalHidl::createPlugin(const uint8_t uuid[16], const String8& appPackageName) {
Mutex::Autolock autoLock(mLock);
for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
@@ -581,15 +582,15 @@
}
}
- return mInitCheck;
+ return DrmStatus(mInitCheck);
}
-status_t DrmHalHidl::destroyPlugin() {
+DrmStatus DrmHalHidl::destroyPlugin() {
cleanup();
- return OK;
+ return DrmStatus(OK);
}
-status_t DrmHalHidl::openSession(DrmPlugin::SecurityLevel level, Vector<uint8_t>& sessionId) {
+DrmStatus DrmHalHidl::openSession(DrmPlugin::SecurityLevel level, Vector<uint8_t>& sessionId) {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
@@ -604,7 +605,7 @@
}
}
- status_t err = UNKNOWN_ERROR;
+ DrmStatus err = UNKNOWN_ERROR;
bool retry = true;
do {
hidl_vec<uint8_t> hSessionId;
@@ -657,7 +658,7 @@
return err;
}
-status_t DrmHalHidl::closeSession(Vector<uint8_t> const& sessionId) {
+DrmStatus DrmHalHidl::closeSession(Vector<uint8_t> const& sessionId) {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
@@ -672,13 +673,13 @@
}
}
}
- status_t response = toStatusT(status);
+ DrmStatus response = toStatusT(status);
mMetrics.SetSessionEnd(sessionId);
mMetrics.mCloseSessionCounter.Increment(response);
return response;
}
mMetrics.mCloseSessionCounter.Increment(DEAD_OBJECT);
- return DEAD_OBJECT;
+ return DrmStatus(DEAD_OBJECT);
}
static DrmPlugin::KeyRequestType toKeyRequestType(KeyRequestType keyRequestType) {
@@ -712,12 +713,12 @@
}
}
-status_t DrmHalHidl::getKeyRequest(Vector<uint8_t> const& sessionId,
- Vector<uint8_t> const& initData, String8 const& mimeType,
- DrmPlugin::KeyType keyType,
- KeyedVector<String8, String8> const& optionalParameters,
- Vector<uint8_t>& request, String8& defaultUrl,
- DrmPlugin::KeyRequestType* keyRequestType) {
+DrmStatus DrmHalHidl::getKeyRequest(Vector<uint8_t> const& sessionId,
+ Vector<uint8_t> const& initData, String8 const& mimeType,
+ DrmPlugin::KeyType keyType,
+ KeyedVector<String8, String8> const& optionalParameters,
+ Vector<uint8_t>& request, String8& defaultUrl,
+ DrmPlugin::KeyRequestType* keyRequestType) {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTimeUs);
@@ -738,7 +739,7 @@
::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
- status_t err = UNKNOWN_ERROR;
+ DrmStatus err = UNKNOWN_ERROR;
Return<void> hResult;
if (mPluginV1_2 != NULL) {
@@ -787,16 +788,16 @@
return err;
}
-status_t DrmHalHidl::provideKeyResponse(Vector<uint8_t> const& sessionId,
- Vector<uint8_t> const& response,
- Vector<uint8_t>& keySetId) {
+DrmStatus DrmHalHidl::provideKeyResponse(Vector<uint8_t> const& sessionId,
+ Vector<uint8_t> const& response,
+ Vector<uint8_t>& keySetId) {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTimeUs);
DrmSessionManager::Instance()->useSession(sessionId);
- status_t err = UNKNOWN_ERROR;
+ DrmStatus err = UNKNOWN_ERROR;
Return<void> hResult =
mPlugin->provideKeyResponse(toHidlVec(sessionId), toHidlVec(response),
@@ -811,27 +812,27 @@
return err;
}
-status_t DrmHalHidl::removeKeys(Vector<uint8_t> const& keySetId) {
+DrmStatus DrmHalHidl::removeKeys(Vector<uint8_t> const& keySetId) {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
Return<Status> status = mPlugin->removeKeys(toHidlVec(keySetId));
- return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
+ return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
}
-status_t DrmHalHidl::restoreKeys(Vector<uint8_t> const& sessionId,
- Vector<uint8_t> const& keySetId) {
+DrmStatus DrmHalHidl::restoreKeys(Vector<uint8_t> const& sessionId,
+ Vector<uint8_t> const& keySetId) {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
DrmSessionManager::Instance()->useSession(sessionId);
Return<Status> status = mPlugin->restoreKeys(toHidlVec(sessionId), toHidlVec(keySetId));
- return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
+ return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
}
-status_t DrmHalHidl::queryKeyStatus(Vector<uint8_t> const& sessionId,
- KeyedVector<String8, String8>& infoMap) const {
+DrmStatus DrmHalHidl::queryKeyStatus(Vector<uint8_t> const& sessionId,
+ KeyedVector<String8, String8>& infoMap) const {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
@@ -839,7 +840,7 @@
::KeyedVector hInfoMap;
- status_t err = UNKNOWN_ERROR;
+ DrmStatus err = UNKNOWN_ERROR;
Return<void> hResult = mPlugin->queryKeyStatus(
toHidlVec(sessionId), [&](Status status, const hidl_vec<KeyValue>& map) {
@@ -849,15 +850,15 @@
err = toStatusT(status);
});
- return hResult.isOk() ? err : DEAD_OBJECT;
+ return hResult.isOk() ? DrmStatus(err) : DrmStatus(DEAD_OBJECT);
}
-status_t DrmHalHidl::getProvisionRequest(String8 const& certType, String8 const& certAuthority,
- Vector<uint8_t>& request, String8& defaultUrl) {
+DrmStatus DrmHalHidl::getProvisionRequest(String8 const& certType, String8 const& certAuthority,
+ Vector<uint8_t>& request, String8& defaultUrl) {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
- status_t err = UNKNOWN_ERROR;
+ DrmStatus err = UNKNOWN_ERROR;
Return<void> hResult;
if (mPluginV1_2 != NULL) {
@@ -888,13 +889,13 @@
return err;
}
-status_t DrmHalHidl::provideProvisionResponse(Vector<uint8_t> const& response,
- Vector<uint8_t>& certificate,
- Vector<uint8_t>& wrappedKey) {
+DrmStatus DrmHalHidl::provideProvisionResponse(Vector<uint8_t> const& response,
+ Vector<uint8_t>& certificate,
+ Vector<uint8_t>& wrappedKey) {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
- status_t err = UNKNOWN_ERROR;
+ DrmStatus err = UNKNOWN_ERROR;
Return<void> hResult = mPlugin->provideProvisionResponse(
toHidlVec(response), [&](Status status, const hidl_vec<uint8_t>& hCertificate,
@@ -911,11 +912,11 @@
return err;
}
-status_t DrmHalHidl::getSecureStops(List<Vector<uint8_t>>& secureStops) {
+DrmStatus DrmHalHidl::getSecureStops(List<Vector<uint8_t>>& secureStops) {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
- status_t err = UNKNOWN_ERROR;
+ DrmStatus err = UNKNOWN_ERROR;
Return<void> hResult =
mPlugin->getSecureStops([&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
@@ -925,10 +926,10 @@
err = toStatusT(status);
});
- return hResult.isOk() ? err : DEAD_OBJECT;
+ return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
}
-status_t DrmHalHidl::getSecureStopIds(List<Vector<uint8_t>>& secureStopIds) {
+DrmStatus DrmHalHidl::getSecureStopIds(List<Vector<uint8_t>>& secureStopIds) {
Mutex::Autolock autoLock(mLock);
if (mInitCheck != OK) {
@@ -939,7 +940,7 @@
return ERROR_DRM_CANNOT_HANDLE;
}
- status_t err = UNKNOWN_ERROR;
+ DrmStatus err = UNKNOWN_ERROR;
Return<void> hResult = mPluginV1_1->getSecureStopIds(
[&](Status status, const hidl_vec<SecureStopId>& hSecureStopIds) {
@@ -949,14 +950,14 @@
err = toStatusT(status);
});
- return hResult.isOk() ? err : DEAD_OBJECT;
+ return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
}
-status_t DrmHalHidl::getSecureStop(Vector<uint8_t> const& ssid, Vector<uint8_t>& secureStop) {
+DrmStatus DrmHalHidl::getSecureStop(Vector<uint8_t> const& ssid, Vector<uint8_t>& secureStop) {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
- status_t err = UNKNOWN_ERROR;
+ DrmStatus err = UNKNOWN_ERROR;
Return<void> hResult = mPlugin->getSecureStop(
toHidlVec(ssid), [&](Status status, const SecureStop& hSecureStop) {
@@ -966,10 +967,10 @@
err = toStatusT(status);
});
- return hResult.isOk() ? err : DEAD_OBJECT;
+ return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
}
-status_t DrmHalHidl::releaseSecureStops(Vector<uint8_t> const& ssRelease) {
+DrmStatus DrmHalHidl::releaseSecureStops(Vector<uint8_t> const& ssRelease) {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
@@ -981,10 +982,10 @@
} else {
status = mPlugin->releaseSecureStop(toHidlVec(ssRelease));
}
- return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
+ return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
}
-status_t DrmHalHidl::removeSecureStop(Vector<uint8_t> const& ssid) {
+DrmStatus DrmHalHidl::removeSecureStop(Vector<uint8_t> const& ssid) {
Mutex::Autolock autoLock(mLock);
if (mInitCheck != OK) {
@@ -996,10 +997,10 @@
}
Return<Status> status = mPluginV1_1->removeSecureStop(toHidlVec(ssid));
- return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
+ return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
}
-status_t DrmHalHidl::removeAllSecureStops() {
+DrmStatus DrmHalHidl::removeAllSecureStops() {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
@@ -1009,18 +1010,18 @@
} else {
status = mPlugin->releaseAllSecureStops();
}
- return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
+ return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
}
-status_t DrmHalHidl::getHdcpLevels(DrmPlugin::HdcpLevel* connected,
- DrmPlugin::HdcpLevel* max) const {
+DrmStatus DrmHalHidl::getHdcpLevels(DrmPlugin::HdcpLevel* connected,
+ DrmPlugin::HdcpLevel* max) const {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
if (connected == NULL || max == NULL) {
return BAD_VALUE;
}
- status_t err = UNKNOWN_ERROR;
+ DrmStatus err = UNKNOWN_ERROR;
*connected = DrmPlugin::kHdcpLevelUnknown;
*max = DrmPlugin::kHdcpLevelUnknown;
@@ -1046,26 +1047,26 @@
err = toStatusT(status);
});
} else {
- return ERROR_DRM_CANNOT_HANDLE;
+ return DrmStatus(ERROR_DRM_CANNOT_HANDLE);
}
- return hResult.isOk() ? err : DEAD_OBJECT;
+ return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
}
-status_t DrmHalHidl::getNumberOfSessions(uint32_t* open, uint32_t* max) const {
+DrmStatus DrmHalHidl::getNumberOfSessions(uint32_t* open, uint32_t* max) const {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
if (open == NULL || max == NULL) {
return BAD_VALUE;
}
- status_t err = UNKNOWN_ERROR;
+ DrmStatus err = UNKNOWN_ERROR;
*open = 0;
*max = 0;
if (mPluginV1_1 == NULL) {
- return ERROR_DRM_CANNOT_HANDLE;
+ return DrmStatus(ERROR_DRM_CANNOT_HANDLE);
}
Return<void> hResult =
@@ -1077,21 +1078,21 @@
err = toStatusT(status);
});
- return hResult.isOk() ? err : DEAD_OBJECT;
+ return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
}
-status_t DrmHalHidl::getSecurityLevel(Vector<uint8_t> const& sessionId,
- DrmPlugin::SecurityLevel* level) const {
+DrmStatus DrmHalHidl::getSecurityLevel(Vector<uint8_t> const& sessionId,
+ DrmPlugin::SecurityLevel* level) const {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
if (level == NULL) {
- return BAD_VALUE;
+ return DrmStatus(BAD_VALUE);
}
- status_t err = UNKNOWN_ERROR;
+ DrmStatus err = UNKNOWN_ERROR;
if (mPluginV1_1 == NULL) {
- return ERROR_DRM_CANNOT_HANDLE;
+ return DrmStatus(ERROR_DRM_CANNOT_HANDLE);
}
*level = DrmPlugin::kSecurityLevelUnknown;
@@ -1104,21 +1105,21 @@
err = toStatusT(status);
});
- return hResult.isOk() ? err : DEAD_OBJECT;
+ return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
}
-status_t DrmHalHidl::getOfflineLicenseKeySetIds(List<Vector<uint8_t>>& keySetIds) const {
+DrmStatus DrmHalHidl::getOfflineLicenseKeySetIds(List<Vector<uint8_t>>& keySetIds) const {
Mutex::Autolock autoLock(mLock);
if (mInitCheck != OK) {
- return mInitCheck;
+ return DrmStatus(mInitCheck);
}
if (mPluginV1_2 == NULL) {
- return ERROR_UNSUPPORTED;
+ return DrmStatus(ERROR_UNSUPPORTED);
}
- status_t err = UNKNOWN_ERROR;
+ DrmStatus err = UNKNOWN_ERROR;
Return<void> hResult = mPluginV1_2->getOfflineLicenseKeySetIds(
[&](Status status, const hidl_vec<KeySetId>& hKeySetIds) {
@@ -1128,38 +1129,38 @@
err = toStatusT(status);
});
- return hResult.isOk() ? err : DEAD_OBJECT;
+ return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
}
-status_t DrmHalHidl::removeOfflineLicense(Vector<uint8_t> const& keySetId) {
+DrmStatus DrmHalHidl::removeOfflineLicense(Vector<uint8_t> const& keySetId) {
Mutex::Autolock autoLock(mLock);
if (mInitCheck != OK) {
- return mInitCheck;
+ return DrmStatus(mInitCheck);
}
if (mPluginV1_2 == NULL) {
- return ERROR_UNSUPPORTED;
+ return DrmStatus(ERROR_UNSUPPORTED);
}
Return<Status> status = mPluginV1_2->removeOfflineLicense(toHidlVec(keySetId));
- return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
+ return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
}
-status_t DrmHalHidl::getOfflineLicenseState(Vector<uint8_t> const& keySetId,
- DrmPlugin::OfflineLicenseState* licenseState) const {
+DrmStatus DrmHalHidl::getOfflineLicenseState(Vector<uint8_t> const& keySetId,
+ DrmPlugin::OfflineLicenseState* licenseState) const {
Mutex::Autolock autoLock(mLock);
if (mInitCheck != OK) {
- return mInitCheck;
+ return DrmStatus(mInitCheck);
}
if (mPluginV1_2 == NULL) {
- return ERROR_UNSUPPORTED;
+ return DrmStatus(ERROR_UNSUPPORTED);
}
*licenseState = DrmPlugin::kOfflineLicenseStateUnknown;
- status_t err = UNKNOWN_ERROR;
+ DrmStatus err = UNKNOWN_ERROR;
Return<void> hResult = mPluginV1_2->getOfflineLicenseState(
toHidlVec(keySetId), [&](Status status, OfflineLicenseState hLicenseState) {
@@ -1169,20 +1170,20 @@
err = toStatusT(status);
});
- return hResult.isOk() ? err : DEAD_OBJECT;
+ return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
}
-status_t DrmHalHidl::getPropertyString(String8 const& name, String8& value) const {
+DrmStatus DrmHalHidl::getPropertyString(String8 const& name, String8& value) const {
Mutex::Autolock autoLock(mLock);
return getPropertyStringInternal(name, value);
}
-status_t DrmHalHidl::getPropertyStringInternal(String8 const& name, String8& value) const {
+DrmStatus DrmHalHidl::getPropertyStringInternal(String8 const& name, String8& value) const {
// This function is internal to the class and should only be called while
// mLock is already held.
INIT_CHECK();
- status_t err = UNKNOWN_ERROR;
+ DrmStatus err = UNKNOWN_ERROR;
Return<void> hResult = mPlugin->getPropertyString(
toHidlString(name), [&](Status status, const hidl_string& hValue) {
@@ -1192,21 +1193,21 @@
err = toStatusT(status);
});
- return hResult.isOk() ? err : DEAD_OBJECT;
+ return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
}
-status_t DrmHalHidl::getPropertyByteArray(String8 const& name, Vector<uint8_t>& value) const {
+DrmStatus DrmHalHidl::getPropertyByteArray(String8 const& name, Vector<uint8_t>& value) const {
Mutex::Autolock autoLock(mLock);
return getPropertyByteArrayInternal(name, value);
}
-status_t DrmHalHidl::getPropertyByteArrayInternal(String8 const& name,
- Vector<uint8_t>& value) const {
+DrmStatus DrmHalHidl::getPropertyByteArrayInternal(String8 const& name,
+ Vector<uint8_t>& value) const {
// This function is internal to the class and should only be called while
// mLock is already held.
INIT_CHECK();
- status_t err = UNKNOWN_ERROR;
+ DrmStatus err = UNKNOWN_ERROR;
Return<void> hResult = mPlugin->getPropertyByteArray(
toHidlString(name), [&](Status status, const hidl_vec<uint8_t>& hValue) {
@@ -1223,25 +1224,26 @@
return err;
}
-status_t DrmHalHidl::setPropertyString(String8 const& name, String8 const& value) const {
+DrmStatus DrmHalHidl::setPropertyString(String8 const& name, String8 const& value) const {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
Return<Status> status = mPlugin->setPropertyString(toHidlString(name), toHidlString(value));
- return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
+ return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
}
-status_t DrmHalHidl::setPropertyByteArray(String8 const& name, Vector<uint8_t> const& value) const {
+DrmStatus DrmHalHidl::setPropertyByteArray(String8 const& name,
+ Vector<uint8_t> const& value) const {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
Return<Status> status = mPlugin->setPropertyByteArray(toHidlString(name), toHidlVec(value));
- return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
+ return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
}
-status_t DrmHalHidl::getMetrics(const sp<IDrmMetricsConsumer>& consumer) {
+DrmStatus DrmHalHidl::getMetrics(const sp<IDrmMetricsConsumer>& consumer) {
if (consumer == nullptr) {
- return UNEXPECTED_NULL;
+ return DrmStatus(UNEXPECTED_NULL);
}
consumer->consumeFrameworkMetrics(mMetrics);
@@ -1262,7 +1264,7 @@
vendor += description;
hidl_vec<DrmMetricGroup> pluginMetrics;
- status_t err = UNKNOWN_ERROR;
+ DrmStatus err = UNKNOWN_ERROR;
Return<void> status =
mPluginV1_1->getMetrics([&](Status status, hidl_vec<DrmMetricGroup> pluginMetrics) {
@@ -1273,14 +1275,14 @@
}
err = toStatusT(status);
});
- return status.isOk() ? err : DEAD_OBJECT;
+ return status.isOk() ? err : DrmStatus(DEAD_OBJECT);
}
- return OK;
+ return DrmStatus(OK);
}
-status_t DrmHalHidl::setCipherAlgorithm(Vector<uint8_t> const& sessionId,
- String8 const& algorithm) {
+DrmStatus DrmHalHidl::setCipherAlgorithm(Vector<uint8_t> const& sessionId,
+ String8 const& algorithm) {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
@@ -1288,28 +1290,28 @@
Return<Status> status =
mPlugin->setCipherAlgorithm(toHidlVec(sessionId), toHidlString(algorithm));
- return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
+ return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
}
-status_t DrmHalHidl::setMacAlgorithm(Vector<uint8_t> const& sessionId, String8 const& algorithm) {
+DrmStatus DrmHalHidl::setMacAlgorithm(Vector<uint8_t> const& sessionId, String8 const& algorithm) {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
DrmSessionManager::Instance()->useSession(sessionId);
Return<Status> status = mPlugin->setMacAlgorithm(toHidlVec(sessionId), toHidlString(algorithm));
- return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
+ return status.isOk() ? DrmStatus(toStatusT(status)) : DrmStatus(DEAD_OBJECT);
}
-status_t DrmHalHidl::encrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
- Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
- Vector<uint8_t>& output) {
+DrmStatus DrmHalHidl::encrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
+ Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
+ Vector<uint8_t>& output) {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
DrmSessionManager::Instance()->useSession(sessionId);
- status_t err = UNKNOWN_ERROR;
+ DrmStatus err = UNKNOWN_ERROR;
Return<void> hResult =
mPlugin->encrypt(toHidlVec(sessionId), toHidlVec(keyId), toHidlVec(input),
@@ -1320,18 +1322,18 @@
err = toStatusT(status);
});
- return hResult.isOk() ? err : DEAD_OBJECT;
+ return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
}
-status_t DrmHalHidl::decrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
- Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
- Vector<uint8_t>& output) {
+DrmStatus DrmHalHidl::decrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
+ Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
+ Vector<uint8_t>& output) {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
DrmSessionManager::Instance()->useSession(sessionId);
- status_t err = UNKNOWN_ERROR;
+ DrmStatus err = UNKNOWN_ERROR;
Return<void> hResult =
mPlugin->decrypt(toHidlVec(sessionId), toHidlVec(keyId), toHidlVec(input),
@@ -1342,17 +1344,17 @@
err = toStatusT(status);
});
- return hResult.isOk() ? err : DEAD_OBJECT;
+ return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
}
-status_t DrmHalHidl::sign(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
- Vector<uint8_t> const& message, Vector<uint8_t>& signature) {
+DrmStatus DrmHalHidl::sign(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
+ Vector<uint8_t> const& message, Vector<uint8_t>& signature) {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
DrmSessionManager::Instance()->useSession(sessionId);
- status_t err = UNKNOWN_ERROR;
+ DrmStatus err = UNKNOWN_ERROR;
Return<void> hResult = mPlugin->sign(toHidlVec(sessionId), toHidlVec(keyId), toHidlVec(message),
[&](Status status, const hidl_vec<uint8_t>& hSignature) {
@@ -1362,18 +1364,18 @@
err = toStatusT(status);
});
- return hResult.isOk() ? err : DEAD_OBJECT;
+ return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
}
-status_t DrmHalHidl::verify(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
- Vector<uint8_t> const& message, Vector<uint8_t> const& signature,
- bool& match) {
+DrmStatus DrmHalHidl::verify(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
+ Vector<uint8_t> const& message, Vector<uint8_t> const& signature,
+ bool& match) {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
DrmSessionManager::Instance()->useSession(sessionId);
- status_t err = UNKNOWN_ERROR;
+ DrmStatus err = UNKNOWN_ERROR;
Return<void> hResult =
mPlugin->verify(toHidlVec(sessionId), toHidlVec(keyId), toHidlVec(message),
@@ -1386,18 +1388,18 @@
err = toStatusT(status);
});
- return hResult.isOk() ? err : DEAD_OBJECT;
+ return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
}
-status_t DrmHalHidl::signRSA(Vector<uint8_t> const& sessionId, String8 const& algorithm,
- Vector<uint8_t> const& message, Vector<uint8_t> const& wrappedKey,
- Vector<uint8_t>& signature) {
+DrmStatus DrmHalHidl::signRSA(Vector<uint8_t> const& sessionId, String8 const& algorithm,
+ Vector<uint8_t> const& message, Vector<uint8_t> const& wrappedKey,
+ Vector<uint8_t>& signature) {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
DrmSessionManager::Instance()->useSession(sessionId);
- status_t err = UNKNOWN_ERROR;
+ DrmStatus err = UNKNOWN_ERROR;
Return<void> hResult = mPlugin->signRSA(
toHidlVec(sessionId), toHidlString(algorithm), toHidlVec(message),
@@ -1408,7 +1410,7 @@
err = toStatusT(status);
});
- return hResult.isOk() ? err : DEAD_OBJECT;
+ return hResult.isOk() ? err : DrmStatus(DEAD_OBJECT);
}
std::string DrmHalHidl::reportFrameworkMetrics(const std::string& pluginMetrics) const {
@@ -1467,55 +1469,56 @@
return metricsString;
}
-status_t DrmHalHidl::requiresSecureDecoder(const char* mime, bool* required) const {
+DrmStatus DrmHalHidl::requiresSecureDecoder(const char* mime, bool* required) const {
Mutex::Autolock autoLock(mLock);
if (mPluginV1_4 == NULL) {
- return false;
+ return DrmStatus(false);
}
auto hResult = mPluginV1_4->requiresSecureDecoderDefault(hidl_string(mime));
if (!hResult.isOk()) {
DrmUtils::LOG2BE("requiresSecureDecoder txn failed: %s", hResult.description().c_str());
- return DEAD_OBJECT;
+ return DrmStatus(DEAD_OBJECT);
}
if (required) {
*required = hResult;
}
- return OK;
+ return DrmStatus(OK);
}
-status_t DrmHalHidl::requiresSecureDecoder(const char* mime, DrmPlugin::SecurityLevel securityLevel,
- bool* required) const {
+DrmStatus DrmHalHidl::requiresSecureDecoder(const char* mime,
+ DrmPlugin::SecurityLevel securityLevel,
+ bool* required) const {
Mutex::Autolock autoLock(mLock);
if (mPluginV1_4 == NULL) {
- return false;
+ return DrmStatus(false);
}
auto hLevel = toHidlSecurityLevel(securityLevel);
auto hResult = mPluginV1_4->requiresSecureDecoder(hidl_string(mime), hLevel);
if (!hResult.isOk()) {
DrmUtils::LOG2BE("requiresSecureDecoder txn failed: %s", hResult.description().c_str());
- return DEAD_OBJECT;
+ return DrmStatus(DEAD_OBJECT);
}
if (required) {
*required = hResult;
}
- return OK;
+ return DrmStatus(OK);
}
-status_t DrmHalHidl::setPlaybackId(Vector<uint8_t> const& sessionId, const char* playbackId) {
+DrmStatus DrmHalHidl::setPlaybackId(Vector<uint8_t> const& sessionId, const char* playbackId) {
Mutex::Autolock autoLock(mLock);
if (mPluginV1_4 == NULL) {
- return ERROR_UNSUPPORTED;
+ return DrmStatus(ERROR_UNSUPPORTED);
}
auto err = mPluginV1_4->setPlaybackId(toHidlVec(sessionId), hidl_string(playbackId));
- return err.isOk() ? toStatusT(err) : DEAD_OBJECT;
+ return err.isOk() ? DrmStatus(toStatusT(err)) : DrmStatus(DEAD_OBJECT);
}
-status_t DrmHalHidl::getLogMessages(Vector<drm::V1_4::LogMessage>& logs) const {
+DrmStatus DrmHalHidl::getLogMessages(Vector<drm::V1_4::LogMessage>& logs) const {
Mutex::Autolock autoLock(mLock);
- return DrmUtils::GetLogMessages<drm::V1_4::IDrmPlugin>(mPlugin, logs);
+ return DrmStatus(DrmUtils::GetLogMessages<drm::V1_4::IDrmPlugin>(mPlugin, logs));
}
-status_t DrmHalHidl::getSupportedSchemes(std::vector<uint8_t> &schemes) const {
+DrmStatus DrmHalHidl::getSupportedSchemes(std::vector<uint8_t>& schemes) const {
Mutex::Autolock autoLock(mLock);
for (auto &factory : mFactories) {
sp<drm::V1_3::IDrmFactory> factoryV1_3 = drm::V1_3::IDrmFactory::castFrom(factory);
@@ -1531,7 +1534,7 @@
});
}
- return OK;
+ return DrmStatus(OK);
}
} // namespace android
diff --git a/drm/libmediadrm/DrmMetricsLogger.cpp b/drm/libmediadrm/DrmMetricsLogger.cpp
new file mode 100644
index 0000000..9c737a0
--- /dev/null
+++ b/drm/libmediadrm/DrmMetricsLogger.cpp
@@ -0,0 +1,513 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// #define LOG_NDEBUG 0
+#define LOG_TAG "DrmMetricsLogger"
+
+#include <media/MediaMetrics.h>
+#include <mediadrm/DrmHal.h>
+#include <mediadrm/DrmMetricsLogger.h>
+#include <mediadrm/DrmUtils.h>
+
+namespace android {
+
+namespace {
+
+std::vector<uint8_t> toStdVec(Vector<uint8_t> const& sessionId) {
+ auto sessionKey = sessionId.array();
+ std::vector<uint8_t> vec(sessionKey, sessionKey + sessionId.size());
+ return vec;
+}
+} // namespace
+
+DrmMetricsLogger::DrmMetricsLogger(IDrmFrontend frontend)
+ : mImpl(sp<DrmHal>::make()), mUuid(), mObjNonceMsb(0), mObjNonceLsb(0), mFrontend(frontend) {}
+
+DrmMetricsLogger::~DrmMetricsLogger() {}
+
+DrmStatus DrmMetricsLogger::initCheck() const {
+ DrmStatus status = mImpl->initCheck();
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::isCryptoSchemeSupported(const uint8_t uuid[16], const String8& mimeType,
+ DrmPlugin::SecurityLevel securityLevel,
+ bool* result) {
+ DrmStatus status = mImpl->isCryptoSchemeSupported(uuid, mimeType, securityLevel, result);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::createPlugin(const uint8_t uuid[16], const String8& appPackageName) {
+ std::memcpy(mUuid, uuid, sizeof(mUuid));
+ if (checkGetRandom(&mObjNonceMsb, __func__) == OK &&
+ checkGetRandom(&mObjNonceLsb, __func__) == OK) {
+ DrmStatus status = mImpl->createPlugin(uuid, appPackageName);
+ if (status == OK) {
+ reportMediaDrmCreated();
+ } else {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+ }
+ return ERROR_DRM_RESOURCE_BUSY;
+}
+
+DrmStatus DrmMetricsLogger::destroyPlugin() {
+ DrmStatus status = mImpl->destroyPlugin();
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::openSession(DrmPlugin::SecurityLevel securityLevel,
+ Vector<uint8_t>& sessionId) {
+ SessionContext ctx{};
+ if (checkGetRandom(&ctx.mNonceMsb, __func__) == OK &&
+ checkGetRandom(&ctx.mNonceLsb, __func__) == OK) {
+ DrmStatus status = mImpl->openSession(securityLevel, sessionId);
+ if (status == OK) {
+ std::vector<uint8_t> sessionKey = toStdVec(sessionId);
+ ctx.mTargetSecurityLevel = securityLevel;
+ if (getSecurityLevel(sessionId, &ctx.mActualSecurityLevel) != OK) {
+ ctx.mActualSecurityLevel = DrmPlugin::kSecurityLevelUnknown;
+ }
+ {
+ const std::lock_guard<std::mutex> lock(mSessionMapMutex);
+ mSessionMap.insert({sessionKey, ctx});
+ }
+ reportMediaDrmSessionOpened(sessionKey);
+ } else {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+ }
+ return ERROR_DRM_RESOURCE_BUSY;
+}
+
+DrmStatus DrmMetricsLogger::closeSession(Vector<uint8_t> const& sessionId) {
+ std::vector<uint8_t> sid = toStdVec(sessionId);
+ {
+ const std::lock_guard<std::mutex> lock(mSessionMapMutex);
+ mSessionMap.erase(sid);
+ }
+ DrmStatus status = mImpl->closeSession(sessionId);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__, sid);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::getKeyRequest(Vector<uint8_t> const& sessionId,
+ Vector<uint8_t> const& initData, String8 const& mimeType,
+ DrmPlugin::KeyType keyType,
+ KeyedVector<String8, String8> const& optionalParameters,
+ Vector<uint8_t>& request, String8& defaultUrl,
+ DrmPlugin::KeyRequestType* keyRequestType) {
+ DrmStatus status =
+ mImpl->getKeyRequest(sessionId, initData, mimeType, keyType, optionalParameters,
+ request, defaultUrl, keyRequestType);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::provideKeyResponse(Vector<uint8_t> const& sessionId,
+ Vector<uint8_t> const& response,
+ Vector<uint8_t>& keySetId) {
+ DrmStatus status = mImpl->provideKeyResponse(sessionId, response, keySetId);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::removeKeys(Vector<uint8_t> const& keySetId) {
+ DrmStatus status = mImpl->removeKeys(keySetId);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::restoreKeys(Vector<uint8_t> const& sessionId,
+ Vector<uint8_t> const& keySetId) {
+ DrmStatus status = mImpl->restoreKeys(sessionId, keySetId);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::queryKeyStatus(Vector<uint8_t> const& sessionId,
+ KeyedVector<String8, String8>& infoMap) const {
+ DrmStatus status = mImpl->queryKeyStatus(sessionId, infoMap);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::getProvisionRequest(String8 const& certType,
+ String8 const& certAuthority,
+ Vector<uint8_t>& request, String8& defaultUrl) {
+ DrmStatus status = mImpl->getProvisionRequest(certType, certAuthority, request, defaultUrl);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::provideProvisionResponse(Vector<uint8_t> const& response,
+ Vector<uint8_t>& certificate,
+ Vector<uint8_t>& wrappedKey) {
+ DrmStatus status = mImpl->provideProvisionResponse(response, certificate, wrappedKey);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::getSecureStops(List<Vector<uint8_t>>& secureStops) {
+ DrmStatus status = mImpl->getSecureStops(secureStops);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::getSecureStopIds(List<Vector<uint8_t>>& secureStopIds) {
+ DrmStatus status = mImpl->getSecureStopIds(secureStopIds);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::getSecureStop(Vector<uint8_t> const& ssid,
+ Vector<uint8_t>& secureStop) {
+ DrmStatus status = mImpl->getSecureStop(ssid, secureStop);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::releaseSecureStops(Vector<uint8_t> const& ssRelease) {
+ DrmStatus status = mImpl->releaseSecureStops(ssRelease);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::removeSecureStop(Vector<uint8_t> const& ssid) {
+ DrmStatus status = mImpl->removeSecureStop(ssid);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::removeAllSecureStops() {
+ DrmStatus status = mImpl->removeAllSecureStops();
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::getHdcpLevels(DrmPlugin::HdcpLevel* connectedLevel,
+ DrmPlugin::HdcpLevel* maxLevel) const {
+ DrmStatus status = mImpl->getHdcpLevels(connectedLevel, maxLevel);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::getNumberOfSessions(uint32_t* currentSessions,
+ uint32_t* maxSessions) const {
+ DrmStatus status = mImpl->getNumberOfSessions(currentSessions, maxSessions);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::getSecurityLevel(Vector<uint8_t> const& sessionId,
+ DrmPlugin::SecurityLevel* level) const {
+ DrmStatus status = mImpl->getSecurityLevel(sessionId, level);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::getOfflineLicenseKeySetIds(List<Vector<uint8_t>>& keySetIds) const {
+ DrmStatus status = mImpl->getOfflineLicenseKeySetIds(keySetIds);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::removeOfflineLicense(Vector<uint8_t> const& keySetId) {
+ DrmStatus status = mImpl->removeOfflineLicense(keySetId);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::getOfflineLicenseState(
+ Vector<uint8_t> const& keySetId, DrmPlugin::OfflineLicenseState* licenseState) const {
+ DrmStatus status = mImpl->getOfflineLicenseState(keySetId, licenseState);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::getPropertyString(String8 const& name, String8& value) const {
+ DrmStatus status = mImpl->getPropertyString(name, value);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::getPropertyByteArray(String8 const& name,
+ Vector<uint8_t>& value) const {
+ DrmStatus status = mImpl->getPropertyByteArray(name, value);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::setPropertyString(String8 const& name, String8 const& value) const {
+ DrmStatus status = mImpl->setPropertyString(name, value);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::setPropertyByteArray(String8 const& name,
+ Vector<uint8_t> const& value) const {
+ DrmStatus status = mImpl->setPropertyByteArray(name, value);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::getMetrics(const sp<IDrmMetricsConsumer>& consumer) {
+ DrmStatus status = mImpl->getMetrics(consumer);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::setCipherAlgorithm(Vector<uint8_t> const& sessionId,
+ String8 const& algorithm) {
+ DrmStatus status = mImpl->setCipherAlgorithm(sessionId, algorithm);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::setMacAlgorithm(Vector<uint8_t> const& sessionId,
+ String8 const& algorithm) {
+ DrmStatus status = mImpl->setMacAlgorithm(sessionId, algorithm);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::encrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
+ Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
+ Vector<uint8_t>& output) {
+ DrmStatus status = mImpl->encrypt(sessionId, keyId, input, iv, output);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::decrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
+ Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
+ Vector<uint8_t>& output) {
+ DrmStatus status = mImpl->decrypt(sessionId, keyId, input, iv, output);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::sign(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
+ Vector<uint8_t> const& message, Vector<uint8_t>& signature) {
+ DrmStatus status = mImpl->sign(sessionId, keyId, message, signature);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::verify(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
+ Vector<uint8_t> const& message, Vector<uint8_t> const& signature,
+ bool& match) {
+ DrmStatus status = mImpl->verify(sessionId, keyId, message, signature, match);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::signRSA(Vector<uint8_t> const& sessionId, String8 const& algorithm,
+ Vector<uint8_t> const& message,
+ Vector<uint8_t> const& wrappedKey, Vector<uint8_t>& signature) {
+ DrmStatus status = mImpl->signRSA(sessionId, algorithm, message, wrappedKey, signature);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::setListener(const sp<IDrmClient>& listener) {
+ DrmStatus status = mImpl->setListener(listener);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::requiresSecureDecoder(const char* mime, bool* required) const {
+ DrmStatus status = mImpl->requiresSecureDecoder(mime, required);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::requiresSecureDecoder(const char* mime,
+ DrmPlugin::SecurityLevel securityLevel,
+ bool* required) const {
+ DrmStatus status = mImpl->requiresSecureDecoder(mime, securityLevel, required);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::setPlaybackId(Vector<uint8_t> const& sessionId,
+ const char* playbackId) {
+ DrmStatus status = mImpl->setPlaybackId(sessionId, playbackId);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::getLogMessages(Vector<drm::V1_4::LogMessage>& logs) const {
+ DrmStatus status = mImpl->getLogMessages(logs);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::getSupportedSchemes(std::vector<uint8_t>& schemes) const {
+ DrmStatus status = mImpl->getSupportedSchemes(schemes);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+void DrmMetricsLogger::reportMediaDrmCreated() const {
+ mediametrics_handle_t handle(mediametrics_create("mediadrm.created"));
+ mediametrics_setInt64(handle, "uuid_msb", be64toh(mUuid[0]));
+ mediametrics_setInt64(handle, "uuid_lsb", be64toh(mUuid[1]));
+ mediametrics_setInt32(handle, "frontend", mFrontend);
+ mediametrics_selfRecord(handle);
+ mediametrics_delete(handle);
+}
+
+void DrmMetricsLogger::reportMediaDrmSessionOpened(const std::vector<uint8_t>& sessionId) const {
+ mediametrics_handle_t handle(mediametrics_create("mediadrm.session_opened"));
+ mediametrics_setInt64(handle, "obj_nonce_msb", mObjNonceMsb);
+ mediametrics_setInt64(handle, "obj_nonce_lsb", mObjNonceLsb);
+ const std::lock_guard<std::mutex> lock(mSessionMapMutex);
+ auto it = mSessionMap.find(sessionId);
+ if (it != mSessionMap.end()) {
+ mediametrics_setInt64(handle, "session_nonce_msb", it->second.mNonceMsb);
+ mediametrics_setInt64(handle, "session_nonce_lsb", it->second.mNonceLsb);
+ mediametrics_setInt64(handle, "target_seucrity_level", it->second.mTargetSecurityLevel);
+ mediametrics_setInt64(handle, "actual_seucrity_level", it->second.mActualSecurityLevel);
+ }
+ mediametrics_setInt32(handle, "frontend", mFrontend);
+ mediametrics_selfRecord(handle);
+ mediametrics_delete(handle);
+}
+
+void DrmMetricsLogger::reportMediaDrmErrored(const DrmStatus& error_code, const char* api,
+ const std::vector<uint8_t>& sessionId) const {
+ mediametrics_handle_t handle(mediametrics_create("mediadrm.errored"));
+ mediametrics_setInt64(handle, "obj_nonce_msb", mObjNonceMsb);
+ mediametrics_setInt64(handle, "obj_nonce_lsb", mObjNonceLsb);
+ if (!sessionId.empty()) {
+ const std::lock_guard<std::mutex> lock(mSessionMapMutex);
+ auto it = mSessionMap.find(sessionId);
+ if (it != mSessionMap.end()) {
+ mediametrics_setInt64(handle, "session_nonce_msb", it->second.mNonceMsb);
+ mediametrics_setInt64(handle, "session_nonce_lsb", it->second.mNonceLsb);
+ }
+ }
+ mediametrics_setInt64(handle, "uuid_msb", be64toh(mUuid[0]));
+ mediametrics_setInt64(handle, "uuid_lsb", be64toh(mUuid[1]));
+ mediametrics_setInt32(handle, "error_code", error_code);
+ mediametrics_setInt32(handle, "cdm_err", error_code.getCdmErr());
+ mediametrics_setInt32(handle, "oem_err", error_code.getOemErr());
+ mediametrics_setInt32(handle, "error_context", error_code.getContext());
+ mediametrics_setCString(handle, "api", api);
+ mediametrics_setInt32(handle, "frontend", mFrontend);
+ mediametrics_selfRecord(handle);
+ mediametrics_delete(handle);
+}
+
+DrmStatus DrmMetricsLogger::checkGetRandom(int64_t* nonce, const char* api) {
+ ssize_t bytes = getrandom(nonce, sizeof(int64_t), GRND_NONBLOCK);
+ if (bytes < sizeof(int64_t)) {
+ ALOGE("getrandom failed: %d", errno);
+ reportMediaDrmErrored(ERROR_DRM_RESOURCE_BUSY, api);
+ return ERROR_DRM_RESOURCE_BUSY;
+ }
+ return OK;
+}
+
+} // namespace android
\ No newline at end of file
diff --git a/drm/libmediadrm/DrmStatus.cpp b/drm/libmediadrm/DrmStatus.cpp
new file mode 100644
index 0000000..0258801
--- /dev/null
+++ b/drm/libmediadrm/DrmStatus.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <mediadrm/DrmStatus.h>
+#include <json/json.h>
+
+namespace android {
+
+DrmStatus::DrmStatus(status_t err, const char *msg) : mStatus(err) {
+ Json::Value errorDetails;
+ Json::Reader reader;
+ if (!reader.parse(msg, errorDetails)) {
+ mErrMsg = msg;
+ return;
+ }
+
+ std::string errMsg;
+ auto val = errorDetails["cdmError"];
+ if (!val.isNull()) {
+ mCdmErr = val.asInt();
+ }
+ val = errorDetails["oemError"];
+ if (!val.isNull()) {
+ mOemErr = val.asInt();
+ }
+ val = errorDetails["context"];
+ if (!val.isNull()) {
+ mCtx = val.asInt();
+ }
+ val = errorDetails["errorMessage"];
+ if (!val.isNull()) {
+ mErrMsg = val.asString();
+ } else {
+ mErrMsg = msg;
+ }
+}
+
+} // namespace android
diff --git a/drm/libmediadrm/DrmUtils.cpp b/drm/libmediadrm/DrmUtils.cpp
index be0cd4b..a99b1d1 100644
--- a/drm/libmediadrm/DrmUtils.cpp
+++ b/drm/libmediadrm/DrmUtils.cpp
@@ -32,6 +32,7 @@
#include <android/hardware/drm/1.4/IDrmFactory.h>
#include <android/hidl/manager/1.2/IServiceManager.h>
#include <hidl/HidlSupport.h>
+#include <json/json.h>
#include <cutils/properties.h>
#include <utils/Errors.h>
@@ -58,11 +59,11 @@
namespace {
-template <typename Hal>
-Hal* MakeObject(status_t* pstatus) {
+template <typename Hal, typename... Ts>
+Hal* MakeObject(status_t* pstatus, Ts... args) {
status_t err = OK;
status_t& status = pstatus ? *pstatus : err;
- auto obj = new Hal();
+ auto obj = new Hal(args...);
status = obj->initCheck();
if (status != OK && status != NO_INIT) {
return NULL;
@@ -191,8 +192,8 @@
return factories;
}
-sp<IDrm> MakeDrm(status_t* pstatus) {
- return MakeObject<DrmHal>(pstatus);
+sp<IDrm> MakeDrm(IDrmFrontend frontend, status_t* pstatus) {
+ return MakeObject<DrmMetricsLogger>(pstatus, frontend);
}
sp<ICrypto> MakeCrypto(status_t* pstatus) {
@@ -362,18 +363,23 @@
}
} // namespace
-std::string GetExceptionMessage(status_t err, const char* msg,
+std::string GetExceptionMessage(const DrmStatus &err, const char* defaultMsg,
const Vector<::V1_4::LogMessage>& logs) {
std::string ruler("==============================");
std::string header("Beginning of DRM Plugin Log");
std::string footer("End of DRM Plugin Log");
+ std::string msg(err.getErrorMessage());
String8 msg8;
- if (msg) {
- msg8 += msg;
+ if (!msg.empty()) {
+ msg8 += msg.c_str();
+ msg8 += ": ";
+ } else if (defaultMsg) {
+ msg8 += defaultMsg;
msg8 += ": ";
}
- auto errStr = StrCryptoError(err);
- msg8 += errStr.c_str();
+ msg8 += StrCryptoError(err).c_str();
+ msg8 += String8::format("\ncdm err: %d, oem err: %d, ctx: %d",
+ err.getCdmErr(), err.getOemErr(), err.getContext());
msg8 += String8::format("\n%s %s %s", ruler.c_str(), header.c_str(), ruler.c_str());
for (auto log : logs) {
@@ -410,6 +416,141 @@
return logs;
}
+DrmStatus statusAidlToDrmStatus(::ndk::ScopedAStatus& statusAidl) {
+ if (statusAidl.isOk()) return OK;
+ if (statusAidl.getExceptionCode() != EX_SERVICE_SPECIFIC) return DEAD_OBJECT;
+ auto astatus = static_cast<StatusAidl>(statusAidl.getServiceSpecificError());
+ status_t status{};
+ switch (astatus) {
+ case StatusAidl::OK:
+ status = OK;
+ break;
+ case StatusAidl::BAD_VALUE:
+ status = BAD_VALUE;
+ break;
+ case StatusAidl::ERROR_DRM_CANNOT_HANDLE:
+ status = ERROR_DRM_CANNOT_HANDLE;
+ break;
+ case StatusAidl::ERROR_DRM_DECRYPT:
+ status = ERROR_DRM_DECRYPT;
+ break;
+ case StatusAidl::ERROR_DRM_DEVICE_REVOKED:
+ status = ERROR_DRM_DEVICE_REVOKED;
+ break;
+ case StatusAidl::ERROR_DRM_FRAME_TOO_LARGE:
+ status = ERROR_DRM_FRAME_TOO_LARGE;
+ break;
+ case StatusAidl::ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION:
+ status = ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION;
+ break;
+ case StatusAidl::ERROR_DRM_INSUFFICIENT_SECURITY:
+ status = ERROR_DRM_INSUFFICIENT_SECURITY;
+ break;
+ case StatusAidl::ERROR_DRM_INVALID_STATE:
+ status = ERROR_DRM_INVALID_STATE;
+ break;
+ case StatusAidl::ERROR_DRM_LICENSE_EXPIRED:
+ status = ERROR_DRM_LICENSE_EXPIRED;
+ break;
+ case StatusAidl::ERROR_DRM_NO_LICENSE:
+ status = ERROR_DRM_NO_LICENSE;
+ break;
+ case StatusAidl::ERROR_DRM_NOT_PROVISIONED:
+ status = ERROR_DRM_NOT_PROVISIONED;
+ break;
+ case StatusAidl::ERROR_DRM_RESOURCE_BUSY:
+ status = ERROR_DRM_RESOURCE_BUSY;
+ break;
+ case StatusAidl::ERROR_DRM_RESOURCE_CONTENTION:
+ status = ERROR_DRM_RESOURCE_CONTENTION;
+ break;
+ case StatusAidl::ERROR_DRM_SESSION_LOST_STATE:
+ status = ERROR_DRM_SESSION_LOST_STATE;
+ break;
+ case StatusAidl::ERROR_DRM_SESSION_NOT_OPENED:
+ status = ERROR_DRM_SESSION_NOT_OPENED;
+ break;
+
+ // New in S / drm@1.4:
+ case StatusAidl::CANNOT_DECRYPT_ZERO_SUBSAMPLES:
+ status = ERROR_DRM_ZERO_SUBSAMPLES;
+ break;
+ case StatusAidl::CRYPTO_LIBRARY_ERROR:
+ status = ERROR_DRM_CRYPTO_LIBRARY;
+ break;
+ case StatusAidl::GENERAL_OEM_ERROR:
+ status = ERROR_DRM_GENERIC_OEM;
+ break;
+ case StatusAidl::GENERAL_PLUGIN_ERROR:
+ status = ERROR_DRM_GENERIC_PLUGIN;
+ break;
+ case StatusAidl::INIT_DATA_INVALID:
+ status = ERROR_DRM_INIT_DATA;
+ break;
+ case StatusAidl::KEY_NOT_LOADED:
+ status = ERROR_DRM_KEY_NOT_LOADED;
+ break;
+ case StatusAidl::LICENSE_PARSE_ERROR:
+ status = ERROR_DRM_LICENSE_PARSE;
+ break;
+ case StatusAidl::LICENSE_POLICY_ERROR:
+ status = ERROR_DRM_LICENSE_POLICY;
+ break;
+ case StatusAidl::LICENSE_RELEASE_ERROR:
+ status = ERROR_DRM_LICENSE_RELEASE;
+ break;
+ case StatusAidl::LICENSE_REQUEST_REJECTED:
+ status = ERROR_DRM_LICENSE_REQUEST_REJECTED;
+ break;
+ case StatusAidl::LICENSE_RESTORE_ERROR:
+ status = ERROR_DRM_LICENSE_RESTORE;
+ break;
+ case StatusAidl::LICENSE_STATE_ERROR:
+ status = ERROR_DRM_LICENSE_STATE;
+ break;
+ case StatusAidl::MALFORMED_CERTIFICATE:
+ status = ERROR_DRM_CERTIFICATE_MALFORMED;
+ break;
+ case StatusAidl::MEDIA_FRAMEWORK_ERROR:
+ status = ERROR_DRM_MEDIA_FRAMEWORK;
+ break;
+ case StatusAidl::MISSING_CERTIFICATE:
+ status = ERROR_DRM_CERTIFICATE_MISSING;
+ break;
+ case StatusAidl::PROVISIONING_CERTIFICATE_ERROR:
+ status = ERROR_DRM_PROVISIONING_CERTIFICATE;
+ break;
+ case StatusAidl::PROVISIONING_CONFIGURATION_ERROR:
+ status = ERROR_DRM_PROVISIONING_CONFIG;
+ break;
+ case StatusAidl::PROVISIONING_PARSE_ERROR:
+ status = ERROR_DRM_PROVISIONING_PARSE;
+ break;
+ case StatusAidl::PROVISIONING_REQUEST_REJECTED:
+ status = ERROR_DRM_PROVISIONING_REQUEST_REJECTED;
+ break;
+ case StatusAidl::RETRYABLE_PROVISIONING_ERROR:
+ status = ERROR_DRM_PROVISIONING_RETRY;
+ break;
+ case StatusAidl::SECURE_STOP_RELEASE_ERROR:
+ status = ERROR_DRM_SECURE_STOP_RELEASE;
+ break;
+ case StatusAidl::STORAGE_READ_FAILURE:
+ status = ERROR_DRM_STORAGE_READ;
+ break;
+ case StatusAidl::STORAGE_WRITE_FAILURE:
+ status = ERROR_DRM_STORAGE_WRITE;
+ break;
+
+ case StatusAidl::ERROR_DRM_UNKNOWN:
+ default:
+ status = ERROR_DRM_UNKNOWN;
+ break;
+ }
+
+ return DrmStatus(status, statusAidl.getMessage());
+}
+
LogBuffer gLogBuf;
} // namespace DrmUtils
} // namespace android
diff --git a/drm/libmediadrm/fuzzer/Android.bp b/drm/libmediadrm/fuzzer/Android.bp
index a85e3cf..deda9ef 100644
--- a/drm/libmediadrm/fuzzer/Android.bp
+++ b/drm/libmediadrm/fuzzer/Android.bp
@@ -37,6 +37,7 @@
"liblog",
"resourcemanager_aidl_interface-ndk",
"libaidlcommonsupport",
+ "libjsoncpp",
],
header_libs: [
"libmedia_headers",
diff --git a/drm/libmediadrm/include/mediadrm/CryptoHal.h b/drm/libmediadrm/include/mediadrm/CryptoHal.h
index 32a6741..60cbbf8 100644
--- a/drm/libmediadrm/include/mediadrm/CryptoHal.h
+++ b/drm/libmediadrm/include/mediadrm/CryptoHal.h
@@ -38,7 +38,7 @@
virtual bool requiresSecureDecoderComponent(
const char *mime) const;
virtual void notifyResolution(uint32_t width, uint32_t height);
- virtual status_t setMediaDrmSession(const Vector<uint8_t> &sessionId);
+ virtual DrmStatus setMediaDrmSession(const Vector<uint8_t> &sessionId);
virtual ssize_t decrypt(const uint8_t key[16], const uint8_t iv[16],
CryptoPlugin::Mode mode, const CryptoPlugin::Pattern &pattern,
const drm::V1_0::SharedBuffer &source, size_t offset,
diff --git a/drm/libmediadrm/include/mediadrm/CryptoHalAidl.h b/drm/libmediadrm/include/mediadrm/CryptoHalAidl.h
index 50878a6..eec4585 100644
--- a/drm/libmediadrm/include/mediadrm/CryptoHalAidl.h
+++ b/drm/libmediadrm/include/mediadrm/CryptoHalAidl.h
@@ -49,7 +49,7 @@
virtual status_t destroyPlugin();
virtual bool requiresSecureDecoderComponent(const char* mime) const;
virtual void notifyResolution(uint32_t width, uint32_t height);
- virtual status_t setMediaDrmSession(const Vector<uint8_t>& sessionId);
+ virtual DrmStatus setMediaDrmSession(const Vector<uint8_t>& sessionId);
virtual ssize_t decrypt(const uint8_t key[16], const uint8_t iv[16], CryptoPlugin::Mode mode,
const CryptoPlugin::Pattern& pattern, const ::SharedBuffer& source,
size_t offset, const CryptoPlugin::SubSample* subSamples,
diff --git a/drm/libmediadrm/include/mediadrm/CryptoHalHidl.h b/drm/libmediadrm/include/mediadrm/CryptoHalHidl.h
index 6db1e89..0150d7c 100644
--- a/drm/libmediadrm/include/mediadrm/CryptoHalHidl.h
+++ b/drm/libmediadrm/include/mediadrm/CryptoHalHidl.h
@@ -57,7 +57,7 @@
virtual void notifyResolution(uint32_t width, uint32_t height);
- virtual status_t setMediaDrmSession(const Vector<uint8_t> &sessionId);
+ virtual DrmStatus setMediaDrmSession(const Vector<uint8_t> &sessionId);
virtual ssize_t decrypt(const uint8_t key[16], const uint8_t iv[16],
CryptoPlugin::Mode mode, const CryptoPlugin::Pattern &pattern,
diff --git a/drm/libmediadrm/include/mediadrm/DrmHal.h b/drm/libmediadrm/include/mediadrm/DrmHal.h
index eab597b..16e5fe1 100644
--- a/drm/libmediadrm/include/mediadrm/DrmHal.h
+++ b/drm/libmediadrm/include/mediadrm/DrmHal.h
@@ -15,6 +15,7 @@
*/
#include <mediadrm/IDrm.h>
+#include <mediadrm/DrmStatus.h>
#ifndef DRM_HAL_H_
#define DRM_HAL_H_
@@ -24,100 +25,99 @@
struct DrmHal : public IDrm {
DrmHal();
virtual ~DrmHal();
- virtual status_t initCheck() const;
- virtual status_t isCryptoSchemeSupported(const uint8_t uuid[16],
- const String8 &mimeType,
- DrmPlugin::SecurityLevel securityLevel,
- bool *result);
- virtual status_t createPlugin(const uint8_t uuid[16],
- const String8 &appPackageName);
- virtual status_t destroyPlugin();
- virtual status_t openSession(DrmPlugin::SecurityLevel securityLevel,
+ virtual DrmStatus initCheck() const;
+ virtual DrmStatus isCryptoSchemeSupported(const uint8_t uuid[16], const String8& mimeType,
+ DrmPlugin::SecurityLevel securityLevel, bool* result);
+ virtual DrmStatus createPlugin(const uint8_t uuid[16],
+ const String8 &appPackageName);
+ virtual DrmStatus destroyPlugin();
+ virtual DrmStatus openSession(DrmPlugin::SecurityLevel securityLevel,
Vector<uint8_t> &sessionId);
- virtual status_t closeSession(Vector<uint8_t> const &sessionId);
- virtual status_t
+ virtual DrmStatus closeSession(Vector<uint8_t> const &sessionId);
+ virtual DrmStatus
getKeyRequest(Vector<uint8_t> const &sessionId,
Vector<uint8_t> const &initData,
String8 const &mimeType, DrmPlugin::KeyType keyType,
KeyedVector<String8, String8> const &optionalParameters,
Vector<uint8_t> &request, String8 &defaultUrl,
DrmPlugin::KeyRequestType *keyRequestType);
- virtual status_t provideKeyResponse(Vector<uint8_t> const &sessionId,
- Vector<uint8_t> const &response,
- Vector<uint8_t> &keySetId);
- virtual status_t removeKeys(Vector<uint8_t> const &keySetId);
- virtual status_t restoreKeys(Vector<uint8_t> const &sessionId,
- Vector<uint8_t> const &keySetId);
- virtual status_t queryKeyStatus(Vector<uint8_t> const &sessionId,
- KeyedVector<String8, String8> &infoMap) const;
- virtual status_t getProvisionRequest(String8 const &certType,
- String8 const &certAuthority,
- Vector<uint8_t> &request,
- String8 &defaultUrl);
- virtual status_t provideProvisionResponse(Vector<uint8_t> const &response,
- Vector<uint8_t> &certificate,
- Vector<uint8_t> &wrappedKey);
- virtual status_t getSecureStops(List<Vector<uint8_t>> &secureStops);
- virtual status_t getSecureStopIds(List<Vector<uint8_t>> &secureStopIds);
- virtual status_t getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop);
- virtual status_t releaseSecureStops(Vector<uint8_t> const &ssRelease);
- virtual status_t removeSecureStop(Vector<uint8_t> const &ssid);
- virtual status_t removeAllSecureStops();
- virtual status_t getHdcpLevels(DrmPlugin::HdcpLevel *connectedLevel,
+ virtual DrmStatus provideKeyResponse(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &response,
+ Vector<uint8_t> &keySetId);
+ virtual DrmStatus removeKeys(Vector<uint8_t> const &keySetId);
+ virtual DrmStatus restoreKeys(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &keySetId);
+ virtual DrmStatus queryKeyStatus(Vector<uint8_t> const &sessionId,
+ KeyedVector<String8, String8> &infoMap) const;
+ virtual DrmStatus getProvisionRequest(String8 const &certType,
+ String8 const &certAuthority,
+ Vector<uint8_t> &request,
+ String8 &defaultUrl);
+ virtual DrmStatus provideProvisionResponse(Vector<uint8_t> const &response,
+ Vector<uint8_t> &certificate,
+ Vector<uint8_t> &wrappedKey);
+ virtual DrmStatus getSecureStops(List<Vector<uint8_t>> &secureStops);
+ virtual DrmStatus getSecureStopIds(List<Vector<uint8_t>> &secureStopIds);
+ virtual DrmStatus getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop);
+ virtual DrmStatus releaseSecureStops(Vector<uint8_t> const &ssRelease);
+ virtual DrmStatus removeSecureStop(Vector<uint8_t> const &ssid);
+ virtual DrmStatus removeAllSecureStops();
+ virtual DrmStatus getHdcpLevels(DrmPlugin::HdcpLevel *connectedLevel,
DrmPlugin::HdcpLevel *maxLevel) const;
- virtual status_t getNumberOfSessions(uint32_t *currentSessions,
+ virtual DrmStatus getNumberOfSessions(uint32_t *currentSessions,
uint32_t *maxSessions) const;
- virtual status_t getSecurityLevel(Vector<uint8_t> const &sessionId,
+ virtual DrmStatus getSecurityLevel(Vector<uint8_t> const &sessionId,
DrmPlugin::SecurityLevel *level) const;
- virtual status_t getOfflineLicenseKeySetIds(List<Vector<uint8_t>> &keySetIds) const;
- virtual status_t removeOfflineLicense(Vector<uint8_t> const &keySetId);
- virtual status_t getOfflineLicenseState(Vector<uint8_t> const &keySetId,
+ virtual DrmStatus getOfflineLicenseKeySetIds(List<Vector<uint8_t>> &keySetIds) const;
+ virtual DrmStatus removeOfflineLicense(Vector<uint8_t> const &keySetId);
+ virtual DrmStatus getOfflineLicenseState(Vector<uint8_t> const &keySetId,
DrmPlugin::OfflineLicenseState *licenseState) const;
- virtual status_t getPropertyString(String8 const &name, String8 &value) const;
- virtual status_t getPropertyByteArray(String8 const &name,
- Vector<uint8_t> &value) const;
- virtual status_t setPropertyString(String8 const &name,
- String8 const &value ) const;
- virtual status_t setPropertyByteArray(String8 const &name,
- Vector<uint8_t> const &value) const;
- virtual status_t getMetrics(const sp<IDrmMetricsConsumer> &consumer);
- virtual status_t setCipherAlgorithm(Vector<uint8_t> const &sessionId,
- String8 const &algorithm);
- virtual status_t setMacAlgorithm(Vector<uint8_t> const &sessionId,
- String8 const &algorithm);
- virtual status_t encrypt(Vector<uint8_t> const &sessionId,
+ virtual DrmStatus getPropertyString(String8 const &name, String8 &value) const;
+ virtual DrmStatus getPropertyByteArray(String8 const &name,
+ Vector<uint8_t> &value) const;
+ virtual DrmStatus setPropertyString(String8 const &name,
+ String8 const &value ) const;
+ virtual DrmStatus setPropertyByteArray(String8 const &name,
+ Vector<uint8_t> const &value) const;
+ virtual DrmStatus getMetrics(const sp<IDrmMetricsConsumer> &consumer);
+ virtual DrmStatus setCipherAlgorithm(Vector<uint8_t> const &sessionId,
+ String8 const &algorithm);
+ virtual DrmStatus setMacAlgorithm(Vector<uint8_t> const &sessionId,
+ String8 const &algorithm);
+ virtual DrmStatus encrypt(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &keyId,
+ Vector<uint8_t> const &input,
+ Vector<uint8_t> const &iv,
+ Vector<uint8_t> &output);
+ virtual DrmStatus decrypt(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &keyId,
+ Vector<uint8_t> const &input,
+ Vector<uint8_t> const &iv,
+ Vector<uint8_t> &output);
+ virtual DrmStatus sign(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &keyId,
+ Vector<uint8_t> const &message,
+ Vector<uint8_t> &signature);
+ virtual DrmStatus verify(Vector<uint8_t> const &sessionId,
Vector<uint8_t> const &keyId,
- Vector<uint8_t> const &input,
- Vector<uint8_t> const &iv,
- Vector<uint8_t> &output);
- virtual status_t decrypt(Vector<uint8_t> const &sessionId,
- Vector<uint8_t> const &keyId,
- Vector<uint8_t> const &input,
- Vector<uint8_t> const &iv,
- Vector<uint8_t> &output);
- virtual status_t sign(Vector<uint8_t> const &sessionId,
- Vector<uint8_t> const &keyId,
- Vector<uint8_t> const &message,
- Vector<uint8_t> &signature);
- virtual status_t verify(Vector<uint8_t> const &sessionId,
- Vector<uint8_t> const &keyId,
- Vector<uint8_t> const &message,
- Vector<uint8_t> const &signature,
- bool &match);
- virtual status_t signRSA(Vector<uint8_t> const &sessionId,
- String8 const &algorithm,
Vector<uint8_t> const &message,
- Vector<uint8_t> const &wrappedKey,
- Vector<uint8_t> &signature);
- virtual status_t setListener(const sp<IDrmClient>& listener);
- virtual status_t requiresSecureDecoder(const char *mime, bool *required) const;
- virtual status_t requiresSecureDecoder(const char *mime, DrmPlugin::SecurityLevel securityLevel,
- bool *required) const;
- virtual status_t setPlaybackId(
+ Vector<uint8_t> const &signature,
+ bool &match);
+ virtual DrmStatus signRSA(Vector<uint8_t> const &sessionId,
+ String8 const &algorithm,
+ Vector<uint8_t> const &message,
+ Vector<uint8_t> const &wrappedKey,
+ Vector<uint8_t> &signature);
+ virtual DrmStatus setListener(const sp<IDrmClient>& listener);
+ virtual DrmStatus requiresSecureDecoder(const char *mime, bool *required) const;
+ virtual DrmStatus requiresSecureDecoder(const char *mime,
+ DrmPlugin::SecurityLevel securityLevel,
+ bool *required) const;
+ virtual DrmStatus setPlaybackId(
Vector<uint8_t> const &sessionId,
const char *playbackId);
- virtual status_t getLogMessages(Vector<drm::V1_4::LogMessage> &logs) const;
- virtual status_t getSupportedSchemes(std::vector<uint8_t> &schemes) const;
+ virtual DrmStatus getLogMessages(Vector<drm::V1_4::LogMessage> &logs) const;
+ virtual DrmStatus getSupportedSchemes(std::vector<uint8_t> &schemes) const;
private:
sp<IDrm> mDrmHalHidl;
diff --git a/drm/libmediadrm/include/mediadrm/DrmHalAidl.h b/drm/libmediadrm/include/mediadrm/DrmHalAidl.h
index 0f51ce9..e0b8341 100644
--- a/drm/libmediadrm/include/mediadrm/DrmHalAidl.h
+++ b/drm/libmediadrm/include/mediadrm/DrmHalAidl.h
@@ -25,6 +25,7 @@
#include <mediadrm/DrmMetrics.h>
#include <mediadrm/DrmSessionManager.h>
#include <mediadrm/DrmHalListener.h>
+#include <mediadrm/DrmStatus.h>
#include <mediadrm/IDrm.h>
using IDrmPluginAidl = ::aidl::android::hardware::drm::IDrmPlugin;
@@ -38,74 +39,78 @@
struct DrmSessionClient;
DrmHalAidl();
virtual ~DrmHalAidl();
- virtual status_t initCheck() const;
- virtual status_t isCryptoSchemeSupported(const uint8_t uuid[16], const String8& mimeType,
- DrmPlugin::SecurityLevel securityLevel, bool* result);
- virtual status_t createPlugin(const uint8_t uuid[16], const String8& appPackageName);
- virtual status_t destroyPlugin();
- virtual status_t openSession(DrmPlugin::SecurityLevel securityLevel,
- Vector<uint8_t>& sessionId);
- virtual status_t closeSession(Vector<uint8_t> const& sessionId);
- virtual status_t getKeyRequest(Vector<uint8_t> const& sessionId,
- Vector<uint8_t> const& initData, String8 const& mimeType,
- DrmPlugin::KeyType keyType,
- KeyedVector<String8, String8> const& optionalParameters,
- Vector<uint8_t>& request, String8& defaultUrl,
- DrmPlugin::KeyRequestType* keyRequestType);
- virtual status_t provideKeyResponse(Vector<uint8_t> const& sessionId,
- Vector<uint8_t> const& response, Vector<uint8_t>& keySetId);
- virtual status_t removeKeys(Vector<uint8_t> const& keySetId);
- virtual status_t restoreKeys(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keySetId);
- virtual status_t queryKeyStatus(Vector<uint8_t> const& sessionId,
- KeyedVector<String8, String8>& infoMap) const;
- virtual status_t getProvisionRequest(String8 const& certType, String8 const& certAuthority,
- Vector<uint8_t>& request, String8& defaultUrl);
- virtual status_t provideProvisionResponse(Vector<uint8_t> const& response,
- Vector<uint8_t>& certificate,
- Vector<uint8_t>& wrappedKey);
- virtual status_t getSecureStops(List<Vector<uint8_t>>& secureStops);
- virtual status_t getSecureStopIds(List<Vector<uint8_t>>& secureStopIds);
- virtual status_t getSecureStop(Vector<uint8_t> const& ssid, Vector<uint8_t>& secureStop);
- virtual status_t releaseSecureStops(Vector<uint8_t> const& ssRelease);
- virtual status_t removeSecureStop(Vector<uint8_t> const& ssid);
- virtual status_t removeAllSecureStops();
- virtual status_t getHdcpLevels(DrmPlugin::HdcpLevel* connectedLevel,
- DrmPlugin::HdcpLevel* maxLevel) const;
- virtual status_t getNumberOfSessions(uint32_t* currentSessions, uint32_t* maxSessions) const;
- virtual status_t getSecurityLevel(Vector<uint8_t> const& sessionId,
- DrmPlugin::SecurityLevel* level) const;
- virtual status_t getOfflineLicenseKeySetIds(List<Vector<uint8_t>>& keySetIds) const;
- virtual status_t removeOfflineLicense(Vector<uint8_t> const& keySetId);
- virtual status_t getOfflineLicenseState(Vector<uint8_t> const& keySetId,
- DrmPlugin::OfflineLicenseState* licenseState) const;
- virtual status_t getPropertyString(String8 const& name, String8& value) const;
- virtual status_t getPropertyByteArray(String8 const& name, Vector<uint8_t>& value) const;
- virtual status_t setPropertyString(String8 const& name, String8 const& value) const;
- virtual status_t setPropertyByteArray(String8 const& name, Vector<uint8_t> const& value) const;
- virtual status_t getMetrics(const sp<IDrmMetricsConsumer>& consumer);
- virtual status_t setCipherAlgorithm(Vector<uint8_t> const& sessionId, String8 const& algorithm);
- virtual status_t setMacAlgorithm(Vector<uint8_t> const& sessionId, String8 const& algorithm);
- virtual status_t encrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
- Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
- Vector<uint8_t>& output);
- virtual status_t decrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
- Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
- Vector<uint8_t>& output);
- virtual status_t sign(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
- Vector<uint8_t> const& message, Vector<uint8_t>& signature);
- virtual status_t verify(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
- Vector<uint8_t> const& message, Vector<uint8_t> const& signature,
- bool& match);
- virtual status_t signRSA(Vector<uint8_t> const& sessionId, String8 const& algorithm,
- Vector<uint8_t> const& message, Vector<uint8_t> const& wrappedKey,
- Vector<uint8_t>& signature);
- virtual status_t setListener(const sp<IDrmClient>& listener);
- virtual status_t requiresSecureDecoder(const char* mime, bool* required) const;
- virtual status_t requiresSecureDecoder(const char* mime, DrmPlugin::SecurityLevel securityLevel,
- bool* required) const;
- virtual status_t setPlaybackId(Vector<uint8_t> const& sessionId, const char* playbackId);
- virtual status_t getLogMessages(Vector<drm::V1_4::LogMessage>& logs) const;
- virtual status_t getSupportedSchemes(std::vector<uint8_t> &schemes) const;
+ virtual DrmStatus initCheck() const;
+ virtual DrmStatus isCryptoSchemeSupported(const uint8_t uuid[16], const String8& mimeType,
+ DrmPlugin::SecurityLevel securityLevel, bool* result);
+ virtual DrmStatus createPlugin(const uint8_t uuid[16], const String8& appPackageName);
+ virtual DrmStatus destroyPlugin();
+ virtual DrmStatus openSession(DrmPlugin::SecurityLevel securityLevel,
+ Vector<uint8_t>& sessionId);
+ virtual DrmStatus closeSession(Vector<uint8_t> const& sessionId);
+ virtual DrmStatus getKeyRequest(Vector<uint8_t> const& sessionId,
+ Vector<uint8_t> const& initData, String8 const& mimeType,
+ DrmPlugin::KeyType keyType,
+ KeyedVector<String8, String8> const& optionalParameters,
+ Vector<uint8_t>& request, String8& defaultUrl,
+ DrmPlugin::KeyRequestType* keyRequestType);
+ virtual DrmStatus provideKeyResponse(Vector<uint8_t> const& sessionId,
+ Vector<uint8_t> const& response,
+ Vector<uint8_t>& keySetId);
+ virtual DrmStatus removeKeys(Vector<uint8_t> const& keySetId);
+ virtual DrmStatus restoreKeys(Vector<uint8_t> const& sessionId,
+ Vector<uint8_t> const& keySetId);
+ virtual DrmStatus queryKeyStatus(Vector<uint8_t> const& sessionId,
+ KeyedVector<String8, String8>& infoMap) const;
+ virtual DrmStatus getProvisionRequest(String8 const& certType, String8 const& certAuthority,
+ Vector<uint8_t>& request, String8& defaultUrl);
+ virtual DrmStatus provideProvisionResponse(Vector<uint8_t> const& response,
+ Vector<uint8_t>& certificate,
+ Vector<uint8_t>& wrappedKey);
+ virtual DrmStatus getSecureStops(List<Vector<uint8_t>>& secureStops);
+ virtual DrmStatus getSecureStopIds(List<Vector<uint8_t>>& secureStopIds);
+ virtual DrmStatus getSecureStop(Vector<uint8_t> const& ssid, Vector<uint8_t>& secureStop);
+ virtual DrmStatus releaseSecureStops(Vector<uint8_t> const& ssRelease);
+ virtual DrmStatus removeSecureStop(Vector<uint8_t> const& ssid);
+ virtual DrmStatus removeAllSecureStops();
+ virtual DrmStatus getHdcpLevels(DrmPlugin::HdcpLevel* connectedLevel,
+ DrmPlugin::HdcpLevel* maxLevel) const;
+ virtual DrmStatus getNumberOfSessions(uint32_t* currentSessions, uint32_t* maxSessions) const;
+ virtual DrmStatus getSecurityLevel(Vector<uint8_t> const& sessionId,
+ DrmPlugin::SecurityLevel* level) const;
+ virtual DrmStatus getOfflineLicenseKeySetIds(List<Vector<uint8_t>>& keySetIds) const;
+ virtual DrmStatus removeOfflineLicense(Vector<uint8_t> const& keySetId);
+ virtual DrmStatus getOfflineLicenseState(Vector<uint8_t> const& keySetId,
+ DrmPlugin::OfflineLicenseState* licenseState) const;
+ virtual DrmStatus getPropertyString(String8 const& name, String8& value) const;
+ virtual DrmStatus getPropertyByteArray(String8 const& name, Vector<uint8_t>& value) const;
+ virtual DrmStatus setPropertyString(String8 const& name, String8 const& value) const;
+ virtual DrmStatus setPropertyByteArray(String8 const& name, Vector<uint8_t> const& value) const;
+ virtual DrmStatus getMetrics(const sp<IDrmMetricsConsumer>& consumer);
+ virtual DrmStatus setCipherAlgorithm(Vector<uint8_t> const& sessionId,
+ String8 const& algorithm);
+ virtual DrmStatus setMacAlgorithm(Vector<uint8_t> const& sessionId, String8 const& algorithm);
+ virtual DrmStatus encrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
+ Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
+ Vector<uint8_t>& output);
+ virtual DrmStatus decrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
+ Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
+ Vector<uint8_t>& output);
+ virtual DrmStatus sign(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
+ Vector<uint8_t> const& message, Vector<uint8_t>& signature);
+ virtual DrmStatus verify(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
+ Vector<uint8_t> const& message, Vector<uint8_t> const& signature,
+ bool& match);
+ virtual DrmStatus signRSA(Vector<uint8_t> const& sessionId, String8 const& algorithm,
+ Vector<uint8_t> const& message, Vector<uint8_t> const& wrappedKey,
+ Vector<uint8_t>& signature);
+ virtual DrmStatus setListener(const sp<IDrmClient>& listener);
+ virtual DrmStatus requiresSecureDecoder(const char* mime, bool* required) const;
+ virtual DrmStatus requiresSecureDecoder(const char* mime,
+ DrmPlugin::SecurityLevel securityLevel,
+ bool* required) const;
+ virtual DrmStatus setPlaybackId(Vector<uint8_t> const& sessionId, const char* playbackId);
+ virtual DrmStatus getLogMessages(Vector<drm::V1_4::LogMessage>& logs) const;
+ virtual DrmStatus getSupportedSchemes(std::vector<uint8_t>& schemes) const;
::ndk::ScopedAStatus onEvent(EventTypeAidl in_eventType,
const std::vector<uint8_t>& in_sessionId,
@@ -128,8 +133,8 @@
void closeOpenSessions();
std::string reportPluginMetrics() const;
std::string reportFrameworkMetrics(const std::string& pluginMetrics) const;
- status_t getPropertyStringInternal(String8 const& name, String8& value) const;
- status_t getPropertyByteArrayInternal(String8 const& name, Vector<uint8_t>& value) const;
+ DrmStatus getPropertyStringInternal(String8 const& name, String8& value) const;
+ DrmStatus getPropertyByteArrayInternal(String8 const& name, Vector<uint8_t>& value) const;
DISALLOW_EVIL_CONSTRUCTORS(DrmHalAidl);
};
diff --git a/drm/libmediadrm/include/mediadrm/DrmHalHidl.h b/drm/libmediadrm/include/mediadrm/DrmHalHidl.h
index 11f0608..73a9e1d 100644
--- a/drm/libmediadrm/include/mediadrm/DrmHalHidl.h
+++ b/drm/libmediadrm/include/mediadrm/DrmHalHidl.h
@@ -26,6 +26,7 @@
#include <media/drm/DrmAPI.h>
#include <mediadrm/DrmMetrics.h>
#include <mediadrm/DrmSessionManager.h>
+#include <mediadrm/DrmStatus.h>
#include <mediadrm/IDrm.h>
#include <mediadrm/IDrmClient.h>
#include <mediadrm/IDrmMetricsConsumer.h>
@@ -63,24 +64,22 @@
DrmHalHidl();
virtual ~DrmHalHidl();
- virtual status_t initCheck() const;
+ virtual DrmStatus initCheck() const;
- virtual status_t isCryptoSchemeSupported(const uint8_t uuid[16],
- const String8& mimeType,
- DrmPlugin::SecurityLevel level,
- bool *isSupported);
+ virtual DrmStatus isCryptoSchemeSupported(const uint8_t uuid[16], const String8& mimeType,
+ DrmPlugin::SecurityLevel level, bool* isSupported);
- virtual status_t createPlugin(const uint8_t uuid[16],
- const String8 &appPackageName);
+ virtual DrmStatus createPlugin(const uint8_t uuid[16],
+ const String8 &appPackageName);
- virtual status_t destroyPlugin();
+ virtual DrmStatus destroyPlugin();
- virtual status_t openSession(DrmPlugin::SecurityLevel level,
+ virtual DrmStatus openSession(DrmPlugin::SecurityLevel level,
Vector<uint8_t> &sessionId);
- virtual status_t closeSession(Vector<uint8_t> const &sessionId);
+ virtual DrmStatus closeSession(Vector<uint8_t> const &sessionId);
- virtual status_t
+ virtual DrmStatus
getKeyRequest(Vector<uint8_t> const &sessionId,
Vector<uint8_t> const &initData,
String8 const &mimeType, DrmPlugin::KeyType keyType,
@@ -88,103 +87,104 @@
Vector<uint8_t> &request, String8 &defaultUrl,
DrmPlugin::KeyRequestType *keyRequestType);
- virtual status_t provideKeyResponse(Vector<uint8_t> const &sessionId,
- Vector<uint8_t> const &response,
- Vector<uint8_t> &keySetId);
+ virtual DrmStatus provideKeyResponse(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &response,
+ Vector<uint8_t> &keySetId);
- virtual status_t removeKeys(Vector<uint8_t> const &keySetId);
+ virtual DrmStatus removeKeys(Vector<uint8_t> const &keySetId);
- virtual status_t restoreKeys(Vector<uint8_t> const &sessionId,
- Vector<uint8_t> const &keySetId);
+ virtual DrmStatus restoreKeys(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &keySetId);
- virtual status_t queryKeyStatus(Vector<uint8_t> const &sessionId,
- KeyedVector<String8, String8> &infoMap) const;
+ virtual DrmStatus queryKeyStatus(Vector<uint8_t> const &sessionId,
+ KeyedVector<String8, String8> &infoMap) const;
- virtual status_t getProvisionRequest(String8 const &certType,
- String8 const &certAuthority,
- Vector<uint8_t> &request,
- String8 &defaultUrl);
+ virtual DrmStatus getProvisionRequest(String8 const &certType,
+ String8 const &certAuthority,
+ Vector<uint8_t> &request,
+ String8 &defaultUrl);
- virtual status_t provideProvisionResponse(Vector<uint8_t> const &response,
- Vector<uint8_t> &certificate,
- Vector<uint8_t> &wrappedKey);
+ virtual DrmStatus provideProvisionResponse(Vector<uint8_t> const &response,
+ Vector<uint8_t> &certificate,
+ Vector<uint8_t> &wrappedKey);
- virtual status_t getSecureStops(List<Vector<uint8_t>> &secureStops);
- virtual status_t getSecureStopIds(List<Vector<uint8_t>> &secureStopIds);
- virtual status_t getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop);
+ virtual DrmStatus getSecureStops(List<Vector<uint8_t>> &secureStops);
+ virtual DrmStatus getSecureStopIds(List<Vector<uint8_t>> &secureStopIds);
+ virtual DrmStatus getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop);
- virtual status_t releaseSecureStops(Vector<uint8_t> const &ssRelease);
- virtual status_t removeSecureStop(Vector<uint8_t> const &ssid);
- virtual status_t removeAllSecureStops();
+ virtual DrmStatus releaseSecureStops(Vector<uint8_t> const &ssRelease);
+ virtual DrmStatus removeSecureStop(Vector<uint8_t> const &ssid);
+ virtual DrmStatus removeAllSecureStops();
- virtual status_t getHdcpLevels(DrmPlugin::HdcpLevel *connectedLevel,
+ virtual DrmStatus getHdcpLevels(DrmPlugin::HdcpLevel *connectedLevel,
DrmPlugin::HdcpLevel *maxLevel) const;
- virtual status_t getNumberOfSessions(uint32_t *currentSessions,
+ virtual DrmStatus getNumberOfSessions(uint32_t *currentSessions,
uint32_t *maxSessions) const;
- virtual status_t getSecurityLevel(Vector<uint8_t> const &sessionId,
+ virtual DrmStatus getSecurityLevel(Vector<uint8_t> const &sessionId,
DrmPlugin::SecurityLevel *level) const;
- virtual status_t getOfflineLicenseKeySetIds(List<Vector<uint8_t>> &keySetIds) const;
- virtual status_t removeOfflineLicense(Vector<uint8_t> const &keySetId);
- virtual status_t getOfflineLicenseState(Vector<uint8_t> const &keySetId,
+ virtual DrmStatus getOfflineLicenseKeySetIds(List<Vector<uint8_t>> &keySetIds) const;
+ virtual DrmStatus removeOfflineLicense(Vector<uint8_t> const &keySetId);
+ virtual DrmStatus getOfflineLicenseState(Vector<uint8_t> const &keySetId,
DrmPlugin::OfflineLicenseState *licenseState) const;
- virtual status_t getPropertyString(String8 const &name, String8 &value ) const;
- virtual status_t getPropertyByteArray(String8 const &name,
- Vector<uint8_t> &value ) const;
- virtual status_t setPropertyString(String8 const &name, String8 const &value ) const;
- virtual status_t setPropertyByteArray(String8 const &name,
- Vector<uint8_t> const &value ) const;
- virtual status_t getMetrics(const sp<IDrmMetricsConsumer> &consumer);
+ virtual DrmStatus getPropertyString(String8 const &name, String8 &value ) const;
+ virtual DrmStatus getPropertyByteArray(String8 const &name,
+ Vector<uint8_t> &value ) const;
+ virtual DrmStatus setPropertyString(String8 const &name, String8 const &value ) const;
+ virtual DrmStatus setPropertyByteArray(String8 const &name,
+ Vector<uint8_t> const &value ) const;
+ virtual DrmStatus getMetrics(const sp<IDrmMetricsConsumer> &consumer);
- virtual status_t setCipherAlgorithm(Vector<uint8_t> const &sessionId,
- String8 const &algorithm);
+ virtual DrmStatus setCipherAlgorithm(Vector<uint8_t> const &sessionId,
+ String8 const &algorithm);
- virtual status_t setMacAlgorithm(Vector<uint8_t> const &sessionId,
- String8 const &algorithm);
+ virtual DrmStatus setMacAlgorithm(Vector<uint8_t> const &sessionId,
+ String8 const &algorithm);
- virtual status_t encrypt(Vector<uint8_t> const &sessionId,
+ virtual DrmStatus encrypt(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &keyId,
+ Vector<uint8_t> const &input,
+ Vector<uint8_t> const &iv,
+ Vector<uint8_t> &output);
+
+ virtual DrmStatus decrypt(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &keyId,
+ Vector<uint8_t> const &input,
+ Vector<uint8_t> const &iv,
+ Vector<uint8_t> &output);
+
+ virtual DrmStatus sign(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &keyId,
+ Vector<uint8_t> const &message,
+ Vector<uint8_t> &signature);
+
+ virtual DrmStatus verify(Vector<uint8_t> const &sessionId,
Vector<uint8_t> const &keyId,
- Vector<uint8_t> const &input,
- Vector<uint8_t> const &iv,
- Vector<uint8_t> &output);
-
- virtual status_t decrypt(Vector<uint8_t> const &sessionId,
- Vector<uint8_t> const &keyId,
- Vector<uint8_t> const &input,
- Vector<uint8_t> const &iv,
- Vector<uint8_t> &output);
-
- virtual status_t sign(Vector<uint8_t> const &sessionId,
- Vector<uint8_t> const &keyId,
- Vector<uint8_t> const &message,
- Vector<uint8_t> &signature);
-
- virtual status_t verify(Vector<uint8_t> const &sessionId,
- Vector<uint8_t> const &keyId,
- Vector<uint8_t> const &message,
- Vector<uint8_t> const &signature,
- bool &match);
-
- virtual status_t signRSA(Vector<uint8_t> const &sessionId,
- String8 const &algorithm,
Vector<uint8_t> const &message,
- Vector<uint8_t> const &wrappedKey,
- Vector<uint8_t> &signature);
+ Vector<uint8_t> const &signature,
+ bool &match);
- virtual status_t setListener(const sp<IDrmClient>& listener);
+ virtual DrmStatus signRSA(Vector<uint8_t> const &sessionId,
+ String8 const &algorithm,
+ Vector<uint8_t> const &message,
+ Vector<uint8_t> const &wrappedKey,
+ Vector<uint8_t> &signature);
- virtual status_t requiresSecureDecoder(const char *mime, bool *required) const;
+ virtual DrmStatus setListener(const sp<IDrmClient>& listener);
- virtual status_t requiresSecureDecoder(const char *mime, DrmPlugin::SecurityLevel securityLevel,
- bool *required) const;
+ virtual DrmStatus requiresSecureDecoder(const char *mime, bool *required) const;
- virtual status_t setPlaybackId(
+ virtual DrmStatus requiresSecureDecoder(const char *mime,
+ DrmPlugin::SecurityLevel securityLevel,
+ bool *required) const;
+
+ virtual DrmStatus setPlaybackId(
Vector<uint8_t> const &sessionId,
const char *playbackId);
- virtual status_t getLogMessages(Vector<drm::V1_4::LogMessage> &logs) const;
- virtual status_t getSupportedSchemes(std::vector<uint8_t> &schemes) const;
+ virtual DrmStatus getLogMessages(Vector<drm::V1_4::LogMessage> &logs) const;
+ virtual DrmStatus getSupportedSchemes(std::vector<uint8_t> &schemes) const;
// Methods of IDrmPluginListener
Return<void> sendEvent(EventType eventType,
@@ -238,10 +238,10 @@
std::string reportPluginMetrics() const;
std::string reportFrameworkMetrics(const std::string& pluginMetrics) const;
- status_t getPropertyStringInternal(String8 const &name, String8 &value) const;
- status_t getPropertyByteArrayInternal(String8 const &name,
+ DrmStatus getPropertyStringInternal(String8 const &name, String8 &value) const;
+ DrmStatus getPropertyByteArrayInternal(String8 const &name,
Vector<uint8_t> &value) const;
- status_t matchMimeTypeAndSecurityLevel(const sp<IDrmFactory> &factory,
+ DrmStatus matchMimeTypeAndSecurityLevel(const sp<IDrmFactory> &factory,
const uint8_t uuid[16],
const String8 &mimeType,
DrmPlugin::SecurityLevel level,
diff --git a/drm/libmediadrm/include/mediadrm/DrmMetricsLogger.h b/drm/libmediadrm/include/mediadrm/DrmMetricsLogger.h
new file mode 100644
index 0000000..b618314
--- /dev/null
+++ b/drm/libmediadrm/include/mediadrm/DrmMetricsLogger.h
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <mediadrm/DrmStatus.h>
+#include <mediadrm/IDrm.h>
+#include <sys/random.h>
+#include <map>
+#include <mutex>
+
+#ifndef DRM_METRICS_LOGGER_H
+#define DRM_METRICS_LOGGER_H
+
+namespace android {
+
+struct SessionContext {
+ int64_t mNonceMsb;
+ int64_t mNonceLsb;
+ int64_t mTargetSecurityLevel;
+ DrmPlugin::SecurityLevel mActualSecurityLevel;
+};
+
+class DrmMetricsLogger : public IDrm {
+ public:
+ DrmMetricsLogger(IDrmFrontend);
+
+ virtual ~DrmMetricsLogger();
+
+ virtual DrmStatus initCheck() const;
+
+ virtual DrmStatus isCryptoSchemeSupported(const uint8_t uuid[16], const String8& mimeType,
+ DrmPlugin::SecurityLevel securityLevel, bool* result);
+
+ virtual DrmStatus createPlugin(const uint8_t uuid[16], const String8& appPackageName);
+
+ virtual DrmStatus destroyPlugin();
+
+ virtual DrmStatus openSession(DrmPlugin::SecurityLevel securityLevel,
+ Vector<uint8_t>& sessionId);
+
+ virtual DrmStatus closeSession(Vector<uint8_t> const& sessionId);
+
+ virtual DrmStatus getKeyRequest(Vector<uint8_t> const& sessionId,
+ Vector<uint8_t> const& initData, String8 const& mimeType,
+ DrmPlugin::KeyType keyType,
+ KeyedVector<String8, String8> const& optionalParameters,
+ Vector<uint8_t>& request, String8& defaultUrl,
+ DrmPlugin::KeyRequestType* keyRequestType);
+
+ virtual DrmStatus provideKeyResponse(Vector<uint8_t> const& sessionId,
+ Vector<uint8_t> const& response,
+ Vector<uint8_t>& keySetId);
+
+ virtual DrmStatus removeKeys(Vector<uint8_t> const& keySetId);
+
+ virtual DrmStatus restoreKeys(Vector<uint8_t> const& sessionId,
+ Vector<uint8_t> const& keySetId);
+
+ virtual DrmStatus queryKeyStatus(Vector<uint8_t> const& sessionId,
+ KeyedVector<String8, String8>& infoMap) const;
+
+ virtual DrmStatus getProvisionRequest(String8 const& certType, String8 const& certAuthority,
+ Vector<uint8_t>& request, String8& defaultUrl);
+
+ virtual DrmStatus provideProvisionResponse(Vector<uint8_t> const& response,
+ Vector<uint8_t>& certificate,
+ Vector<uint8_t>& wrappedKey);
+
+ virtual DrmStatus getSecureStops(List<Vector<uint8_t>>& secureStops);
+ virtual DrmStatus getSecureStopIds(List<Vector<uint8_t>>& secureStopIds);
+ virtual DrmStatus getSecureStop(Vector<uint8_t> const& ssid, Vector<uint8_t>& secureStop);
+
+ virtual DrmStatus releaseSecureStops(Vector<uint8_t> const& ssRelease);
+ virtual DrmStatus removeSecureStop(Vector<uint8_t> const& ssid);
+ virtual DrmStatus removeAllSecureStops();
+
+ virtual DrmStatus getHdcpLevels(DrmPlugin::HdcpLevel* connectedLevel,
+ DrmPlugin::HdcpLevel* maxLevel) const;
+ virtual DrmStatus getNumberOfSessions(uint32_t* currentSessions, uint32_t* maxSessions) const;
+ virtual DrmStatus getSecurityLevel(Vector<uint8_t> const& sessionId,
+ DrmPlugin::SecurityLevel* level) const;
+
+ virtual DrmStatus getOfflineLicenseKeySetIds(List<Vector<uint8_t>>& keySetIds) const;
+ virtual DrmStatus removeOfflineLicense(Vector<uint8_t> const& keySetId);
+ virtual DrmStatus getOfflineLicenseState(Vector<uint8_t> const& keySetId,
+ DrmPlugin::OfflineLicenseState* licenseState) const;
+
+ virtual DrmStatus getPropertyString(String8 const& name, String8& value) const;
+ virtual DrmStatus getPropertyByteArray(String8 const& name, Vector<uint8_t>& value) const;
+ virtual DrmStatus setPropertyString(String8 const& name, String8 const& value) const;
+ virtual DrmStatus setPropertyByteArray(String8 const& name, Vector<uint8_t> const& value) const;
+
+ virtual DrmStatus getMetrics(const sp<IDrmMetricsConsumer>& consumer);
+
+ virtual DrmStatus setCipherAlgorithm(Vector<uint8_t> const& sessionId,
+ String8 const& algorithm);
+
+ virtual DrmStatus setMacAlgorithm(Vector<uint8_t> const& sessionId, String8 const& algorithm);
+
+ virtual DrmStatus encrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
+ Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
+ Vector<uint8_t>& output);
+
+ virtual DrmStatus decrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
+ Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
+ Vector<uint8_t>& output);
+
+ virtual DrmStatus sign(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
+ Vector<uint8_t> const& message, Vector<uint8_t>& signature);
+
+ virtual DrmStatus verify(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
+ Vector<uint8_t> const& message, Vector<uint8_t> const& signature,
+ bool& match);
+
+ virtual DrmStatus signRSA(Vector<uint8_t> const& sessionId, String8 const& algorithm,
+ Vector<uint8_t> const& message, Vector<uint8_t> const& wrappedKey,
+ Vector<uint8_t>& signature);
+
+ virtual DrmStatus setListener(const sp<IDrmClient>& listener);
+
+ virtual DrmStatus requiresSecureDecoder(const char* mime, bool* required) const;
+
+ virtual DrmStatus requiresSecureDecoder(const char* mime,
+ DrmPlugin::SecurityLevel securityLevel,
+ bool* required) const;
+
+ virtual DrmStatus setPlaybackId(Vector<uint8_t> const& sessionId, const char* playbackId);
+
+ virtual DrmStatus getLogMessages(Vector<drm::V1_4::LogMessage>& logs) const;
+
+ virtual DrmStatus getSupportedSchemes(std::vector<uint8_t>& schemes) const;
+
+ void reportMediaDrmCreated() const;
+
+ void reportMediaDrmSessionOpened(const std::vector<uint8_t>& sessionId) const;
+
+ void reportMediaDrmErrored(
+ const DrmStatus& error_code, const char* api,
+ const std::vector<uint8_t>& sessionId = std::vector<uint8_t>()) const;
+
+ DrmStatus checkGetRandom(int64_t* nonce, const char* api);
+
+ private:
+ sp<IDrm> mImpl;
+ int64_t mUuid[2] = {};
+ int64_t mObjNonceMsb, mObjNonceLsb;
+ std::map<std::vector<uint8_t>, SessionContext> mSessionMap;
+ mutable std::mutex mSessionMapMutex;
+ IDrmFrontend mFrontend;
+ DISALLOW_EVIL_CONSTRUCTORS(DrmMetricsLogger);
+};
+
+} // namespace android
+
+#endif // DRM_METRICS_LOGGER_H
\ No newline at end of file
diff --git a/drm/libmediadrm/include/mediadrm/IDrm.h b/drm/libmediadrm/include/mediadrm/IDrm.h
index ee2be6a..f37d1d1 100644
--- a/drm/libmediadrm/include/mediadrm/IDrm.h
+++ b/drm/libmediadrm/include/mediadrm/IDrm.h
@@ -16,6 +16,7 @@
#include <media/stagefright/foundation/ABase.h>
#include <media/drm/DrmAPI.h>
+#include <mediadrm/DrmStatus.h>
#include <mediadrm/IDrmClient.h>
#include <mediadrm/IDrmMetricsConsumer.h>
@@ -32,6 +33,13 @@
} // namespace drm
} // namespace hardware
+enum IDrmFrontend : int32_t {
+ IDRM_UNKNOWN = 0,
+ IDRM_JNI = 1,
+ IDRM_NDK = 2,
+ IDRM_NUPLAYER = 3,
+};
+
namespace drm = ::android::hardware::drm;
struct AString;
@@ -40,24 +48,23 @@
virtual ~IDrm() {}
- virtual status_t initCheck() const = 0;
+ virtual DrmStatus initCheck() const = 0;
- virtual status_t isCryptoSchemeSupported(const uint8_t uuid[16],
- const String8 &mimeType,
- DrmPlugin::SecurityLevel securityLevel,
- bool *result) = 0;
+ virtual DrmStatus isCryptoSchemeSupported(const uint8_t uuid[16], const String8& mimeType,
+ DrmPlugin::SecurityLevel securityLevel,
+ bool* result) = 0;
- virtual status_t createPlugin(const uint8_t uuid[16],
- const String8 &appPackageName) = 0;
+ virtual DrmStatus createPlugin(const uint8_t uuid[16],
+ const String8 &appPackageName) = 0;
- virtual status_t destroyPlugin() = 0;
+ virtual DrmStatus destroyPlugin() = 0;
- virtual status_t openSession(DrmPlugin::SecurityLevel securityLevel,
+ virtual DrmStatus openSession(DrmPlugin::SecurityLevel securityLevel,
Vector<uint8_t> &sessionId) = 0;
- virtual status_t closeSession(Vector<uint8_t> const &sessionId) = 0;
+ virtual DrmStatus closeSession(Vector<uint8_t> const &sessionId) = 0;
- virtual status_t
+ virtual DrmStatus
getKeyRequest(Vector<uint8_t> const &sessionId,
Vector<uint8_t> const &initData,
String8 const &mimeType, DrmPlugin::KeyType keyType,
@@ -65,107 +72,108 @@
Vector<uint8_t> &request, String8 &defaultUrl,
DrmPlugin::KeyRequestType *keyRequestType) = 0;
- virtual status_t provideKeyResponse(Vector<uint8_t> const &sessionId,
- Vector<uint8_t> const &response,
- Vector<uint8_t> &keySetId) = 0;
+ virtual DrmStatus provideKeyResponse(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &response,
+ Vector<uint8_t> &keySetId) = 0;
- virtual status_t removeKeys(Vector<uint8_t> const &keySetId) = 0;
+ virtual DrmStatus removeKeys(Vector<uint8_t> const &keySetId) = 0;
- virtual status_t restoreKeys(Vector<uint8_t> const &sessionId,
- Vector<uint8_t> const &keySetId) = 0;
+ virtual DrmStatus restoreKeys(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &keySetId) = 0;
- virtual status_t queryKeyStatus(Vector<uint8_t> const &sessionId,
- KeyedVector<String8, String8> &infoMap) const = 0;
+ virtual DrmStatus queryKeyStatus(Vector<uint8_t> const &sessionId,
+ KeyedVector<String8, String8> &infoMap) const = 0;
- virtual status_t getProvisionRequest(String8 const &certType,
- String8 const &certAuthority,
- Vector<uint8_t> &request,
- String8 &defaulUrl) = 0;
+ virtual DrmStatus getProvisionRequest(String8 const &certType,
+ String8 const &certAuthority,
+ Vector<uint8_t> &request,
+ String8 &defaultUrl) = 0;
- virtual status_t provideProvisionResponse(Vector<uint8_t> const &response,
- Vector<uint8_t> &certificate,
- Vector<uint8_t> &wrappedKey) = 0;
+ virtual DrmStatus provideProvisionResponse(Vector<uint8_t> const &response,
+ Vector<uint8_t> &certificate,
+ Vector<uint8_t> &wrappedKey) = 0;
- virtual status_t getSecureStops(List<Vector<uint8_t>> &secureStops) = 0;
- virtual status_t getSecureStopIds(List<Vector<uint8_t>> &secureStopIds) = 0;
- virtual status_t getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) = 0;
+ virtual DrmStatus getSecureStops(List<Vector<uint8_t>> &secureStops) = 0;
+ virtual DrmStatus getSecureStopIds(List<Vector<uint8_t>> &secureStopIds) = 0;
+ virtual DrmStatus getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) = 0;
- virtual status_t releaseSecureStops(Vector<uint8_t> const &ssRelease) = 0;
- virtual status_t removeSecureStop(Vector<uint8_t> const &ssid) = 0;
- virtual status_t removeAllSecureStops() = 0;
+ virtual DrmStatus releaseSecureStops(Vector<uint8_t> const &ssRelease) = 0;
+ virtual DrmStatus removeSecureStop(Vector<uint8_t> const &ssid) = 0;
+ virtual DrmStatus removeAllSecureStops() = 0;
- virtual status_t getHdcpLevels(DrmPlugin::HdcpLevel *connectedLevel,
+ virtual DrmStatus getHdcpLevels(DrmPlugin::HdcpLevel *connectedLevel,
DrmPlugin::HdcpLevel *maxLevel)
const = 0;
- virtual status_t getNumberOfSessions(uint32_t *currentSessions,
+ virtual DrmStatus getNumberOfSessions(uint32_t *currentSessions,
uint32_t *maxSessions) const = 0;
- virtual status_t getSecurityLevel(Vector<uint8_t> const &sessionId,
+ virtual DrmStatus getSecurityLevel(Vector<uint8_t> const &sessionId,
DrmPlugin::SecurityLevel *level) const = 0;
- virtual status_t getOfflineLicenseKeySetIds(List<Vector<uint8_t>> &keySetIds) const = 0;
- virtual status_t removeOfflineLicense(Vector<uint8_t> const &keySetId) = 0;
- virtual status_t getOfflineLicenseState(Vector<uint8_t> const &keySetId,
+ virtual DrmStatus getOfflineLicenseKeySetIds(List<Vector<uint8_t>> &keySetIds) const = 0;
+ virtual DrmStatus removeOfflineLicense(Vector<uint8_t> const &keySetId) = 0;
+ virtual DrmStatus getOfflineLicenseState(Vector<uint8_t> const &keySetId,
DrmPlugin::OfflineLicenseState *licenseState) const = 0;
- virtual status_t getPropertyString(String8 const &name, String8 &value) const = 0;
- virtual status_t getPropertyByteArray(String8 const &name,
- Vector<uint8_t> &value) const = 0;
- virtual status_t setPropertyString(String8 const &name,
- String8 const &value ) const = 0;
- virtual status_t setPropertyByteArray(String8 const &name,
- Vector<uint8_t> const &value) const = 0;
+ virtual DrmStatus getPropertyString(String8 const &name, String8 &value) const = 0;
+ virtual DrmStatus getPropertyByteArray(String8 const &name,
+ Vector<uint8_t> &value) const = 0;
+ virtual DrmStatus setPropertyString(String8 const &name,
+ String8 const &value ) const = 0;
+ virtual DrmStatus setPropertyByteArray(String8 const &name,
+ Vector<uint8_t> const &value) const = 0;
- virtual status_t getMetrics(const sp<IDrmMetricsConsumer> &consumer) = 0;
+ virtual DrmStatus getMetrics(const sp<IDrmMetricsConsumer> &consumer) = 0;
- virtual status_t setCipherAlgorithm(Vector<uint8_t> const &sessionId,
- String8 const &algorithm) = 0;
+ virtual DrmStatus setCipherAlgorithm(Vector<uint8_t> const &sessionId,
+ String8 const &algorithm) = 0;
- virtual status_t setMacAlgorithm(Vector<uint8_t> const &sessionId,
- String8 const &algorithm) = 0;
+ virtual DrmStatus setMacAlgorithm(Vector<uint8_t> const &sessionId,
+ String8 const &algorithm) = 0;
- virtual status_t encrypt(Vector<uint8_t> const &sessionId,
+ virtual DrmStatus encrypt(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &keyId,
+ Vector<uint8_t> const &input,
+ Vector<uint8_t> const &iv,
+ Vector<uint8_t> &output) = 0;
+
+ virtual DrmStatus decrypt(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &keyId,
+ Vector<uint8_t> const &input,
+ Vector<uint8_t> const &iv,
+ Vector<uint8_t> &output) = 0;
+
+ virtual DrmStatus sign(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &keyId,
+ Vector<uint8_t> const &message,
+ Vector<uint8_t> &signature) = 0;
+
+ virtual DrmStatus verify(Vector<uint8_t> const &sessionId,
Vector<uint8_t> const &keyId,
- Vector<uint8_t> const &input,
- Vector<uint8_t> const &iv,
- Vector<uint8_t> &output) = 0;
-
- virtual status_t decrypt(Vector<uint8_t> const &sessionId,
- Vector<uint8_t> const &keyId,
- Vector<uint8_t> const &input,
- Vector<uint8_t> const &iv,
- Vector<uint8_t> &output) = 0;
-
- virtual status_t sign(Vector<uint8_t> const &sessionId,
- Vector<uint8_t> const &keyId,
- Vector<uint8_t> const &message,
- Vector<uint8_t> &signature) = 0;
-
- virtual status_t verify(Vector<uint8_t> const &sessionId,
- Vector<uint8_t> const &keyId,
- Vector<uint8_t> const &message,
- Vector<uint8_t> const &signature,
- bool &match) = 0;
-
- virtual status_t signRSA(Vector<uint8_t> const &sessionId,
- String8 const &algorithm,
Vector<uint8_t> const &message,
- Vector<uint8_t> const &wrappedKey,
- Vector<uint8_t> &signature) = 0;
+ Vector<uint8_t> const &signature,
+ bool &match) = 0;
- virtual status_t setListener(const sp<IDrmClient>& listener) = 0;
+ virtual DrmStatus signRSA(Vector<uint8_t> const &sessionId,
+ String8 const &algorithm,
+ Vector<uint8_t> const &message,
+ Vector<uint8_t> const &wrappedKey,
+ Vector<uint8_t> &signature) = 0;
- virtual status_t requiresSecureDecoder(const char *mime, bool *required) const = 0;
+ virtual DrmStatus setListener(const sp<IDrmClient>& listener) = 0;
- virtual status_t requiresSecureDecoder(const char *mime, DrmPlugin::SecurityLevel securityLevel,
- bool *required) const = 0;
+ virtual DrmStatus requiresSecureDecoder(const char *mime, bool *required) const = 0;
- virtual status_t setPlaybackId(
+ virtual DrmStatus requiresSecureDecoder(const char *mime,
+ DrmPlugin::SecurityLevel securityLevel,
+ bool *required) const = 0;
+
+ virtual DrmStatus setPlaybackId(
Vector<uint8_t> const &sessionId,
const char *playbackId) = 0;
- virtual status_t getLogMessages(Vector<drm::V1_4::LogMessage> &logs) const = 0;
+ virtual DrmStatus getLogMessages(Vector<drm::V1_4::LogMessage> &logs) const = 0;
- virtual status_t getSupportedSchemes(std::vector<uint8_t> &schemes) const = 0;
+ virtual DrmStatus getSupportedSchemes(std::vector<uint8_t> &schemes) const = 0;
protected:
IDrm() {}
diff --git a/drm/libmediadrm/interface/mediadrm/DrmStatus.h b/drm/libmediadrm/interface/mediadrm/DrmStatus.h
new file mode 100644
index 0000000..15826ca
--- /dev/null
+++ b/drm/libmediadrm/interface/mediadrm/DrmStatus.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef DRM_STATUS_
+#define DRM_STATUS_
+
+#include <media/stagefright/foundation/ABase.h>
+#include <media/stagefright/MediaErrors.h>
+#include <utils/Errors.h>
+
+#include <stdint.h>
+#include <string>
+
+namespace android {
+
+struct DrmStatus {
+ public:
+ DrmStatus(status_t status, int32_t cdmErr = 0, int32_t oemErr = 0,
+ int32_t ctx = 0, std::string errMsg = "")
+ : mStatus(status), mCdmErr(cdmErr), mOemErr(oemErr),
+ mCtx(ctx), mErrMsg(errMsg) {}
+ DrmStatus(status_t err, const char *msg);
+ operator status_t() const { return mStatus; }
+ int32_t getCdmErr() const { return mCdmErr; }
+ int32_t getOemErr() const { return mOemErr; }
+ int32_t getContext() const { return mCtx; }
+ std::string getErrorMessage() const { return mErrMsg; }
+ bool operator==(status_t other) const { return mStatus == other; }
+ bool operator!=(status_t other) const { return mStatus != other; }
+
+ private:
+ status_t mStatus{};
+ int32_t mCdmErr{}, mOemErr{}, mCtx{};
+ std::string mErrMsg;
+};
+
+} // namespace android
+
+#endif // DRM_STATUS_
diff --git a/drm/libmediadrm/interface/mediadrm/DrmUtils.h b/drm/libmediadrm/interface/mediadrm/DrmUtils.h
index 980ce55..94cf743 100644
--- a/drm/libmediadrm/interface/mediadrm/DrmUtils.h
+++ b/drm/libmediadrm/interface/mediadrm/DrmUtils.h
@@ -22,6 +22,8 @@
#include <android/hardware/drm/1.4/IDrmPlugin.h>
#include <android/hardware/drm/1.4/types.h>
#include <media/stagefright/MediaErrors.h>
+#include <mediadrm/DrmMetricsLogger.h>
+#include <mediadrm/DrmStatus.h>
#include <utils/Errors.h> // for status_t
#include <utils/Log.h>
#include <utils/String8.h>
@@ -118,7 +120,7 @@
bool UseDrmService();
-sp<IDrm> MakeDrm(status_t *pstatus = nullptr);
+sp<IDrm> MakeDrm(IDrmFrontend frontend = IDRM_JNI, status_t* pstatus = nullptr);
sp<ICrypto> MakeCrypto(status_t *pstatus = nullptr);
@@ -198,98 +200,7 @@
return toStatusT_1_4(err);
}
-inline status_t statusAidlToStatusT(::ndk::ScopedAStatus &statusAidl) {
- if (statusAidl.isOk()) return OK;
- if (statusAidl.getExceptionCode() != EX_SERVICE_SPECIFIC) return DEAD_OBJECT;
- auto status = static_cast<StatusAidl>(statusAidl.getServiceSpecificError());
- switch (status) {
- case StatusAidl::OK:
- return OK;
- case StatusAidl::BAD_VALUE:
- return BAD_VALUE;
- case StatusAidl::ERROR_DRM_CANNOT_HANDLE:
- return ERROR_DRM_CANNOT_HANDLE;
- case StatusAidl::ERROR_DRM_DECRYPT:
- return ERROR_DRM_DECRYPT;
- case StatusAidl::ERROR_DRM_DEVICE_REVOKED:
- return ERROR_DRM_DEVICE_REVOKED;
- case StatusAidl::ERROR_DRM_FRAME_TOO_LARGE:
- return ERROR_DRM_FRAME_TOO_LARGE;
- case StatusAidl::ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION:
- return ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION;
- case StatusAidl::ERROR_DRM_INSUFFICIENT_SECURITY:
- return ERROR_DRM_INSUFFICIENT_SECURITY;
- case StatusAidl::ERROR_DRM_INVALID_STATE:
- return ERROR_DRM_INVALID_STATE;
- case StatusAidl::ERROR_DRM_LICENSE_EXPIRED:
- return ERROR_DRM_LICENSE_EXPIRED;
- case StatusAidl::ERROR_DRM_NO_LICENSE:
- return ERROR_DRM_NO_LICENSE;
- case StatusAidl::ERROR_DRM_NOT_PROVISIONED:
- return ERROR_DRM_NOT_PROVISIONED;
- case StatusAidl::ERROR_DRM_RESOURCE_BUSY:
- return ERROR_DRM_RESOURCE_BUSY;
- case StatusAidl::ERROR_DRM_RESOURCE_CONTENTION:
- return ERROR_DRM_RESOURCE_CONTENTION;
- case StatusAidl::ERROR_DRM_SESSION_LOST_STATE:
- return ERROR_DRM_SESSION_LOST_STATE;
- case StatusAidl::ERROR_DRM_SESSION_NOT_OPENED:
- return ERROR_DRM_SESSION_NOT_OPENED;
-
- // New in S / drm@1.4:
- case StatusAidl::CANNOT_DECRYPT_ZERO_SUBSAMPLES:
- return ERROR_DRM_ZERO_SUBSAMPLES;
- case StatusAidl::CRYPTO_LIBRARY_ERROR:
- return ERROR_DRM_CRYPTO_LIBRARY;
- case StatusAidl::GENERAL_OEM_ERROR:
- return ERROR_DRM_GENERIC_OEM;
- case StatusAidl::GENERAL_PLUGIN_ERROR:
- return ERROR_DRM_GENERIC_PLUGIN;
- case StatusAidl::INIT_DATA_INVALID:
- return ERROR_DRM_INIT_DATA;
- case StatusAidl::KEY_NOT_LOADED:
- return ERROR_DRM_KEY_NOT_LOADED;
- case StatusAidl::LICENSE_PARSE_ERROR:
- return ERROR_DRM_LICENSE_PARSE;
- case StatusAidl::LICENSE_POLICY_ERROR:
- return ERROR_DRM_LICENSE_POLICY;
- case StatusAidl::LICENSE_RELEASE_ERROR:
- return ERROR_DRM_LICENSE_RELEASE;
- case StatusAidl::LICENSE_REQUEST_REJECTED:
- return ERROR_DRM_LICENSE_REQUEST_REJECTED;
- case StatusAidl::LICENSE_RESTORE_ERROR:
- return ERROR_DRM_LICENSE_RESTORE;
- case StatusAidl::LICENSE_STATE_ERROR:
- return ERROR_DRM_LICENSE_STATE;
- case StatusAidl::MALFORMED_CERTIFICATE:
- return ERROR_DRM_CERTIFICATE_MALFORMED;
- case StatusAidl::MEDIA_FRAMEWORK_ERROR:
- return ERROR_DRM_MEDIA_FRAMEWORK;
- case StatusAidl::MISSING_CERTIFICATE:
- return ERROR_DRM_CERTIFICATE_MISSING;
- case StatusAidl::PROVISIONING_CERTIFICATE_ERROR:
- return ERROR_DRM_PROVISIONING_CERTIFICATE;
- case StatusAidl::PROVISIONING_CONFIGURATION_ERROR:
- return ERROR_DRM_PROVISIONING_CONFIG;
- case StatusAidl::PROVISIONING_PARSE_ERROR:
- return ERROR_DRM_PROVISIONING_PARSE;
- case StatusAidl::PROVISIONING_REQUEST_REJECTED:
- return ERROR_DRM_PROVISIONING_REQUEST_REJECTED;
- case StatusAidl::RETRYABLE_PROVISIONING_ERROR:
- return ERROR_DRM_PROVISIONING_RETRY;
- case StatusAidl::SECURE_STOP_RELEASE_ERROR:
- return ERROR_DRM_SECURE_STOP_RELEASE;
- case StatusAidl::STORAGE_READ_FAILURE:
- return ERROR_DRM_STORAGE_READ;
- case StatusAidl::STORAGE_WRITE_FAILURE:
- return ERROR_DRM_STORAGE_WRITE;
-
- case StatusAidl::ERROR_DRM_UNKNOWN:
- default:
- return ERROR_DRM_UNKNOWN;
- }
- return ERROR_DRM_UNKNOWN;
-}
+DrmStatus statusAidlToDrmStatus(::ndk::ScopedAStatus& statusAidl);
template<typename T, typename U>
status_t GetLogMessagesAidl(const std::shared_ptr<U> &obj, Vector<::V1_4::LogMessage> &logs) {
@@ -373,14 +284,16 @@
return OK;
}
-std::string GetExceptionMessage(status_t err, const char *msg,
+std::string GetExceptionMessage(const DrmStatus & err, const char *defaultMsg,
const Vector<::V1_4::LogMessage> &logs);
template<typename T>
-std::string GetExceptionMessage(status_t err, const char *msg, const sp<T> &iface) {
+std::string GetExceptionMessage(const DrmStatus &err, const char *defaultMsg, const sp<T> &iface) {
Vector<::V1_4::LogMessage> logs;
- iface->getLogMessages(logs);
- return GetExceptionMessage(err, msg, logs);
+ if (iface != NULL) {
+ iface->getLogMessages(logs);
+ }
+ return GetExceptionMessage(err, defaultMsg, logs);
}
} // namespace DrmUtils
diff --git a/drm/libmediadrm/interface/mediadrm/ICrypto.h b/drm/libmediadrm/interface/mediadrm/ICrypto.h
index 2c4df60..4087186 100644
--- a/drm/libmediadrm/interface/mediadrm/ICrypto.h
+++ b/drm/libmediadrm/interface/mediadrm/ICrypto.h
@@ -17,6 +17,7 @@
#include <cutils/native_handle.h>
#include <media/hardware/CryptoAPI.h>
#include <media/stagefright/foundation/ABase.h>
+#include <mediadrm/DrmStatus.h>
#include <utils/RefBase.h>
#include <utils/StrongPointer.h>
@@ -65,7 +66,7 @@
virtual void notifyResolution(uint32_t width, uint32_t height) = 0;
- virtual status_t setMediaDrmSession(const Vector<uint8_t> &sessionId) = 0;
+ virtual DrmStatus setMediaDrmSession(const Vector<uint8_t> &sessionId) = 0;
enum DestinationType {
kDestinationTypeSharedMemory, // non-secure
diff --git a/include/media/MicrophoneInfo.h b/include/media/MicrophoneInfo.h
index a5045b9..6d6c594 100644
--- a/include/media/MicrophoneInfo.h
+++ b/include/media/MicrophoneInfo.h
@@ -70,6 +70,9 @@
}
virtual status_t writeToParcelable(MicrophoneInfoData* parcelable) const {
+#if defined(BACKEND_NDK)
+ using ::aidl::android::convertReinterpret;
+#endif
parcelable->deviceId = mDeviceId;
parcelable->portId = mPortId;
parcelable->type = VALUE_OR_RETURN_STATUS(convertReinterpret<int32_t>(mType));
@@ -98,6 +101,9 @@
}
virtual status_t readFromParcelable(const MicrophoneInfoData& parcelable) {
+#if defined(BACKEND_NDK)
+ using ::aidl::android::convertReinterpret;
+#endif
mDeviceId = parcelable.deviceId;
mPortId = parcelable.portId;
mType = VALUE_OR_RETURN_STATUS(convertReinterpret<uint32_t>(parcelable.type));
@@ -208,6 +214,10 @@
int32_t mDirectionality;
};
+#if defined(BACKEND_NDK)
+using ::aidl::ConversionResult;
+#endif
+
// Conversion routines, according to AidlConversion.h conventions.
inline ConversionResult<MicrophoneInfo>
aidl2legacy_MicrophoneInfo(const media::MicrophoneInfoData& aidl) {
diff --git a/media/TEST_MAPPING b/media/TEST_MAPPING
index 048301f..a22ec19 100644
--- a/media/TEST_MAPPING
+++ b/media/TEST_MAPPING
@@ -1,7 +1,24 @@
// for frameworks/av/media
{
- // TODO (b/229286407) Add EncodeDecodeTest and DecodeEditEncodeTest to
- // presubmit-large once issues in cuttlefish are fixed
+ "presubmit-large": [
+ // runs whenever we change something in this tree
+ {
+ "name": "CtsMediaCodecTestCases",
+ "options": [
+ {
+ "include-filter": "android.media.codec.cts.EncodeDecodeTest"
+ }
+ ]
+ },
+ {
+ "name": "CtsMediaCodecTestCases",
+ "options": [
+ {
+ "include-filter": "android.media.codec.cts.DecodeEditEncodeTest"
+ }
+ ]
+ }
+ ],
"presubmit": [
{
"name": "GtsMediaTestCases",
@@ -15,7 +32,8 @@
{
"include-filter": "com.google.android.media.gts.WidevineH264PlaybackTests"
}
- ]
+ ],
+ "file_patterns": ["(?i)drm|crypto"]
}
],
diff --git a/media/audioaidlconversion/AidlConversionCppNdk.cpp b/media/audioaidlconversion/AidlConversionCppNdk.cpp
new file mode 100644
index 0000000..37887f6
--- /dev/null
+++ b/media/audioaidlconversion/AidlConversionCppNdk.cpp
@@ -0,0 +1,2266 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+#include <map>
+#include <utility>
+#include <vector>
+
+#define LOG_TAG "AidlConversionCppNdk"
+//#define LOG_NDEBUG 0
+#include <utils/Log.h>
+
+#include "media/AidlConversionCppNdk.h"
+
+#include <media/ShmemCompat.h>
+#include <media/stagefright/foundation/MediaDefs.h>
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// AIDL CPP/NDK backend to legacy audio data structure conversion utilities.
+
+#if defined(BACKEND_NDK)
+/* AIDL String generated in NDK is different than CPP */
+#define GET_DEVICE_DESC_CONNECTION(x) AudioDeviceDescription::CONNECTION_##x
+namespace aidl {
+#else
+#define GET_DEVICE_DESC_CONNECTION(x) AudioDeviceDescription::CONNECTION_##x()
+#endif
+
+namespace android {
+
+using ::android::BAD_VALUE;
+using ::android::OK;
+using ::android::base::unexpected;
+
+using media::audio::common::AudioChannelLayout;
+using media::audio::common::AudioConfig;
+using media::audio::common::AudioConfigBase;
+using media::audio::common::AudioContentType;
+using media::audio::common::AudioDevice;
+using media::audio::common::AudioDeviceAddress;
+using media::audio::common::AudioDeviceDescription;
+using media::audio::common::AudioDeviceType;
+using media::audio::common::AudioDualMonoMode;
+using media::audio::common::AudioEncapsulationMetadataType;
+using media::audio::common::AudioEncapsulationMode;
+using media::audio::common::AudioEncapsulationType;
+using media::audio::common::AudioFormatDescription;
+using media::audio::common::AudioFormatType;
+using media::audio::common::AudioGain;
+using media::audio::common::AudioGainConfig;
+using media::audio::common::AudioGainMode;
+using media::audio::common::AudioInputFlags;
+using media::audio::common::AudioIoFlags;
+using media::audio::common::AudioLatencyMode;
+using media::audio::common::AudioMode;
+using media::audio::common::AudioOffloadInfo;
+using media::audio::common::AudioOutputFlags;
+using media::audio::common::AudioPlaybackRate;
+using media::audio::common::AudioPortDeviceExt;
+using media::audio::common::AudioPortExt;
+using media::audio::common::AudioPortMixExt;
+using media::audio::common::AudioPortMixExtUseCase;
+using media::audio::common::AudioProfile;
+using media::audio::common::AudioSource;
+using media::audio::common::AudioStandard;
+using media::audio::common::AudioStreamType;
+using media::audio::common::AudioUsage;
+using media::audio::common::AudioUuid;
+using media::audio::common::ExtraAudioDescriptor;
+using media::audio::common::Int;
+using media::audio::common::PcmType;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Converters
+
+::android::status_t aidl2legacy_string(std::string_view aidl, char* dest, size_t maxSize) {
+ if (aidl.size() > maxSize - 1) {
+ return BAD_VALUE;
+ }
+ aidl.copy(dest, aidl.size());
+ dest[aidl.size()] = '\0';
+ return OK;
+}
+
+ConversionResult<std::string> legacy2aidl_string(const char* legacy, size_t maxSize) {
+ if (legacy == nullptr) {
+ return unexpected(BAD_VALUE);
+ }
+ if (strnlen(legacy, maxSize) == maxSize) {
+ // No null-terminator.
+ return unexpected(BAD_VALUE);
+ }
+ return std::string(legacy);
+}
+
+ConversionResult<audio_module_handle_t> aidl2legacy_int32_t_audio_module_handle_t(int32_t aidl) {
+ return convertReinterpret<audio_module_handle_t>(aidl);
+}
+
+ConversionResult<int32_t> legacy2aidl_audio_module_handle_t_int32_t(audio_module_handle_t legacy) {
+ return convertReinterpret<int32_t>(legacy);
+}
+
+ConversionResult<audio_io_handle_t> aidl2legacy_int32_t_audio_io_handle_t(int32_t aidl) {
+ return convertReinterpret<audio_io_handle_t>(aidl);
+}
+
+ConversionResult<int32_t> legacy2aidl_audio_io_handle_t_int32_t(audio_io_handle_t legacy) {
+ return convertReinterpret<int32_t>(legacy);
+}
+
+ConversionResult<audio_port_handle_t> aidl2legacy_int32_t_audio_port_handle_t(int32_t aidl) {
+ return convertReinterpret<audio_port_handle_t>(aidl);
+}
+
+ConversionResult<int32_t> legacy2aidl_audio_port_handle_t_int32_t(audio_port_handle_t legacy) {
+ return convertReinterpret<int32_t>(legacy);
+}
+
+ConversionResult<audio_patch_handle_t> aidl2legacy_int32_t_audio_patch_handle_t(int32_t aidl) {
+ return convertReinterpret<audio_patch_handle_t>(aidl);
+}
+
+ConversionResult<int32_t> legacy2aidl_audio_patch_handle_t_int32_t(audio_patch_handle_t legacy) {
+ return convertReinterpret<int32_t>(legacy);
+}
+
+ConversionResult<audio_unique_id_t> aidl2legacy_int32_t_audio_unique_id_t(int32_t aidl) {
+ return convertReinterpret<audio_unique_id_t>(aidl);
+}
+
+ConversionResult<int32_t> legacy2aidl_audio_unique_id_t_int32_t(audio_unique_id_t legacy) {
+ return convertReinterpret<int32_t>(legacy);
+}
+
+ConversionResult<audio_hw_sync_t> aidl2legacy_int32_t_audio_hw_sync_t(int32_t aidl) {
+ return convertReinterpret<audio_hw_sync_t>(aidl);
+}
+
+ConversionResult<int32_t> legacy2aidl_audio_hw_sync_t_int32_t(audio_hw_sync_t legacy) {
+ return convertReinterpret<int32_t>(legacy);
+}
+
+ConversionResult<pid_t> aidl2legacy_int32_t_pid_t(int32_t aidl) {
+ return convertReinterpret<pid_t>(aidl);
+}
+
+ConversionResult<int32_t> legacy2aidl_pid_t_int32_t(pid_t legacy) {
+ return convertReinterpret<int32_t>(legacy);
+}
+
+ConversionResult<uid_t> aidl2legacy_int32_t_uid_t(int32_t aidl) {
+ return convertReinterpret<uid_t>(aidl);
+}
+
+ConversionResult<int32_t> legacy2aidl_uid_t_int32_t(uid_t legacy) {
+ return convertReinterpret<int32_t>(legacy);
+}
+
+ConversionResult<String16> aidl2legacy_string_view_String16(std::string_view aidl) {
+ return String16(aidl.data(), aidl.size());
+}
+
+ConversionResult<std::string> legacy2aidl_String16_string(const String16& legacy) {
+ return std::string(String8(legacy).c_str());
+}
+
+// TODO b/182392769: create an optional -> optional util
+ConversionResult<std::optional<String16>>
+aidl2legacy_optional_string_view_optional_String16(std::optional<std::string_view> aidl) {
+ if (!aidl.has_value()) {
+ return std::nullopt;
+ }
+ ConversionResult<String16> conversion =
+ VALUE_OR_RETURN(aidl2legacy_string_view_String16(aidl.value()));
+ return conversion.value();
+}
+
+ConversionResult<std::optional<std::string_view>>
+legacy2aidl_optional_String16_optional_string(std::optional<String16> legacy) {
+ if (!legacy.has_value()) {
+ return std::nullopt;
+ }
+ ConversionResult<std::string> conversion =
+ VALUE_OR_RETURN(legacy2aidl_String16_string(legacy.value()));
+ return conversion.value();
+}
+
+ConversionResult<String8> aidl2legacy_string_view_String8(std::string_view aidl) {
+ return String8(aidl.data(), aidl.size());
+}
+
+ConversionResult<std::string> legacy2aidl_String8_string(const String8& legacy) {
+ return std::string(legacy.c_str());
+}
+
+namespace {
+
+namespace detail {
+using AudioChannelBitPair = std::pair<audio_channel_mask_t, int>;
+using AudioChannelBitPairs = std::vector<AudioChannelBitPair>;
+using AudioChannelPair = std::pair<audio_channel_mask_t, AudioChannelLayout>;
+using AudioChannelPairs = std::vector<AudioChannelPair>;
+using AudioDevicePair = std::pair<audio_devices_t, AudioDeviceDescription>;
+using AudioDevicePairs = std::vector<AudioDevicePair>;
+using AudioFormatPair = std::pair<audio_format_t, AudioFormatDescription>;
+using AudioFormatPairs = std::vector<AudioFormatPair>;
+}
+
+const detail::AudioChannelBitPairs& getInAudioChannelBits() {
+ static const detail::AudioChannelBitPairs pairs = {
+ { AUDIO_CHANNEL_IN_LEFT, AudioChannelLayout::CHANNEL_FRONT_LEFT },
+ { AUDIO_CHANNEL_IN_RIGHT, AudioChannelLayout::CHANNEL_FRONT_RIGHT },
+ // AUDIO_CHANNEL_IN_FRONT is at the end
+ { AUDIO_CHANNEL_IN_BACK, AudioChannelLayout::CHANNEL_BACK_CENTER },
+ // AUDIO_CHANNEL_IN_*_PROCESSED not supported
+ // AUDIO_CHANNEL_IN_PRESSURE not supported
+ // AUDIO_CHANNEL_IN_*_AXIS not supported
+ // AUDIO_CHANNEL_IN_VOICE_* not supported
+ { AUDIO_CHANNEL_IN_BACK_LEFT, AudioChannelLayout::CHANNEL_BACK_LEFT },
+ { AUDIO_CHANNEL_IN_BACK_RIGHT, AudioChannelLayout::CHANNEL_BACK_RIGHT },
+ { AUDIO_CHANNEL_IN_CENTER, AudioChannelLayout::CHANNEL_FRONT_CENTER },
+ { AUDIO_CHANNEL_IN_LOW_FREQUENCY, AudioChannelLayout::CHANNEL_LOW_FREQUENCY },
+ { AUDIO_CHANNEL_IN_TOP_LEFT, AudioChannelLayout::CHANNEL_TOP_SIDE_LEFT },
+ { AUDIO_CHANNEL_IN_TOP_RIGHT, AudioChannelLayout::CHANNEL_TOP_SIDE_RIGHT },
+ // When going from aidl to legacy, IN_CENTER is used
+ { AUDIO_CHANNEL_IN_FRONT, AudioChannelLayout::CHANNEL_FRONT_CENTER }
+ };
+ return pairs;
+}
+
+const detail::AudioChannelPairs& getInAudioChannelPairs() {
+ static const detail::AudioChannelPairs pairs = {
+#define DEFINE_INPUT_LAYOUT(n) \
+ { \
+ AUDIO_CHANNEL_IN_##n, \
+ AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>( \
+ AudioChannelLayout::LAYOUT_##n) \
+ }
+
+ DEFINE_INPUT_LAYOUT(MONO),
+ DEFINE_INPUT_LAYOUT(STEREO),
+ DEFINE_INPUT_LAYOUT(FRONT_BACK),
+ // AUDIO_CHANNEL_IN_6 not supported
+ DEFINE_INPUT_LAYOUT(2POINT0POINT2),
+ DEFINE_INPUT_LAYOUT(2POINT1POINT2),
+ DEFINE_INPUT_LAYOUT(3POINT0POINT2),
+ DEFINE_INPUT_LAYOUT(3POINT1POINT2),
+ DEFINE_INPUT_LAYOUT(5POINT1)
+#undef DEFINE_INPUT_LAYOUT
+ };
+ return pairs;
+}
+
+const detail::AudioChannelBitPairs& getOutAudioChannelBits() {
+ static const detail::AudioChannelBitPairs pairs = {
+#define DEFINE_OUTPUT_BITS(n) \
+ { AUDIO_CHANNEL_OUT_##n, AudioChannelLayout::CHANNEL_##n }
+
+ DEFINE_OUTPUT_BITS(FRONT_LEFT),
+ DEFINE_OUTPUT_BITS(FRONT_RIGHT),
+ DEFINE_OUTPUT_BITS(FRONT_CENTER),
+ DEFINE_OUTPUT_BITS(LOW_FREQUENCY),
+ DEFINE_OUTPUT_BITS(BACK_LEFT),
+ DEFINE_OUTPUT_BITS(BACK_RIGHT),
+ DEFINE_OUTPUT_BITS(FRONT_LEFT_OF_CENTER),
+ DEFINE_OUTPUT_BITS(FRONT_RIGHT_OF_CENTER),
+ DEFINE_OUTPUT_BITS(BACK_CENTER),
+ DEFINE_OUTPUT_BITS(SIDE_LEFT),
+ DEFINE_OUTPUT_BITS(SIDE_RIGHT),
+ DEFINE_OUTPUT_BITS(TOP_CENTER),
+ DEFINE_OUTPUT_BITS(TOP_FRONT_LEFT),
+ DEFINE_OUTPUT_BITS(TOP_FRONT_CENTER),
+ DEFINE_OUTPUT_BITS(TOP_FRONT_RIGHT),
+ DEFINE_OUTPUT_BITS(TOP_BACK_LEFT),
+ DEFINE_OUTPUT_BITS(TOP_BACK_CENTER),
+ DEFINE_OUTPUT_BITS(TOP_BACK_RIGHT),
+ DEFINE_OUTPUT_BITS(TOP_SIDE_LEFT),
+ DEFINE_OUTPUT_BITS(TOP_SIDE_RIGHT),
+ DEFINE_OUTPUT_BITS(BOTTOM_FRONT_LEFT),
+ DEFINE_OUTPUT_BITS(BOTTOM_FRONT_CENTER),
+ DEFINE_OUTPUT_BITS(BOTTOM_FRONT_RIGHT),
+ DEFINE_OUTPUT_BITS(LOW_FREQUENCY_2),
+ DEFINE_OUTPUT_BITS(FRONT_WIDE_LEFT),
+ DEFINE_OUTPUT_BITS(FRONT_WIDE_RIGHT),
+#undef DEFINE_OUTPUT_BITS
+ { AUDIO_CHANNEL_OUT_HAPTIC_A, AudioChannelLayout::CHANNEL_HAPTIC_A },
+ { AUDIO_CHANNEL_OUT_HAPTIC_B, AudioChannelLayout::CHANNEL_HAPTIC_B }
+ };
+ return pairs;
+}
+
+const detail::AudioChannelPairs& getOutAudioChannelPairs() {
+ static const detail::AudioChannelPairs pairs = {
+#define DEFINE_OUTPUT_LAYOUT(n) \
+ { \
+ AUDIO_CHANNEL_OUT_##n, \
+ AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>( \
+ AudioChannelLayout::LAYOUT_##n) \
+ }
+
+ DEFINE_OUTPUT_LAYOUT(MONO),
+ DEFINE_OUTPUT_LAYOUT(STEREO),
+ DEFINE_OUTPUT_LAYOUT(2POINT1),
+ DEFINE_OUTPUT_LAYOUT(TRI),
+ DEFINE_OUTPUT_LAYOUT(TRI_BACK),
+ DEFINE_OUTPUT_LAYOUT(3POINT1),
+ DEFINE_OUTPUT_LAYOUT(2POINT0POINT2),
+ DEFINE_OUTPUT_LAYOUT(2POINT1POINT2),
+ DEFINE_OUTPUT_LAYOUT(3POINT0POINT2),
+ DEFINE_OUTPUT_LAYOUT(3POINT1POINT2),
+ DEFINE_OUTPUT_LAYOUT(QUAD),
+ DEFINE_OUTPUT_LAYOUT(QUAD_SIDE),
+ DEFINE_OUTPUT_LAYOUT(SURROUND),
+ DEFINE_OUTPUT_LAYOUT(PENTA),
+ DEFINE_OUTPUT_LAYOUT(5POINT1),
+ DEFINE_OUTPUT_LAYOUT(5POINT1_SIDE),
+ DEFINE_OUTPUT_LAYOUT(5POINT1POINT2),
+ DEFINE_OUTPUT_LAYOUT(5POINT1POINT4),
+ DEFINE_OUTPUT_LAYOUT(6POINT1),
+ DEFINE_OUTPUT_LAYOUT(7POINT1),
+ DEFINE_OUTPUT_LAYOUT(7POINT1POINT2),
+ DEFINE_OUTPUT_LAYOUT(7POINT1POINT4),
+ DEFINE_OUTPUT_LAYOUT(13POINT_360RA),
+ DEFINE_OUTPUT_LAYOUT(22POINT2),
+ DEFINE_OUTPUT_LAYOUT(MONO_HAPTIC_A),
+ DEFINE_OUTPUT_LAYOUT(STEREO_HAPTIC_A),
+ DEFINE_OUTPUT_LAYOUT(HAPTIC_AB),
+ DEFINE_OUTPUT_LAYOUT(MONO_HAPTIC_AB),
+ DEFINE_OUTPUT_LAYOUT(STEREO_HAPTIC_AB)
+#undef DEFINE_OUTPUT_LAYOUT
+ };
+ return pairs;
+}
+
+const detail::AudioChannelPairs& getVoiceAudioChannelPairs() {
+ static const detail::AudioChannelPairs pairs = {
+#define DEFINE_VOICE_LAYOUT(n) \
+ { \
+ AUDIO_CHANNEL_IN_VOICE_##n, \
+ AudioChannelLayout::make<AudioChannelLayout::Tag::voiceMask>( \
+ AudioChannelLayout::VOICE_##n) \
+ }
+ DEFINE_VOICE_LAYOUT(UPLINK_MONO),
+ DEFINE_VOICE_LAYOUT(DNLINK_MONO),
+ DEFINE_VOICE_LAYOUT(CALL_MONO)
+#undef DEFINE_VOICE_LAYOUT
+ };
+ return pairs;
+}
+
+AudioDeviceDescription make_AudioDeviceDescription(AudioDeviceType type,
+ const std::string& connection = "") {
+ AudioDeviceDescription result;
+ result.type = type;
+ result.connection = connection;
+ return result;
+}
+
+void append_AudioDeviceDescription(detail::AudioDevicePairs& pairs,
+ audio_devices_t inputType, audio_devices_t outputType,
+ AudioDeviceType inType, AudioDeviceType outType,
+ const std::string& connection = "") {
+ pairs.push_back(std::make_pair(inputType, make_AudioDeviceDescription(inType, connection)));
+ pairs.push_back(std::make_pair(outputType, make_AudioDeviceDescription(outType, connection)));
+}
+
+const detail::AudioDevicePairs& getAudioDevicePairs() {
+ static const detail::AudioDevicePairs pairs = []() {
+ detail::AudioDevicePairs pairs = {{
+ {
+ AUDIO_DEVICE_NONE, AudioDeviceDescription{}
+ },
+ {
+ AUDIO_DEVICE_OUT_EARPIECE, make_AudioDeviceDescription(
+ AudioDeviceType::OUT_SPEAKER_EARPIECE)
+ },
+ {
+ AUDIO_DEVICE_OUT_SPEAKER, make_AudioDeviceDescription(
+ AudioDeviceType::OUT_SPEAKER)
+ },
+ {
+ AUDIO_DEVICE_OUT_WIRED_HEADPHONE, make_AudioDeviceDescription(
+ AudioDeviceType::OUT_HEADPHONE,
+ GET_DEVICE_DESC_CONNECTION(ANALOG))
+ },
+ {
+ AUDIO_DEVICE_OUT_BLUETOOTH_SCO, make_AudioDeviceDescription(
+ AudioDeviceType::OUT_DEVICE,
+ GET_DEVICE_DESC_CONNECTION(BT_SCO))
+ },
+ {
+ AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT, make_AudioDeviceDescription(
+ AudioDeviceType::OUT_CARKIT,
+ GET_DEVICE_DESC_CONNECTION(BT_SCO))
+ },
+ {
+ AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES, make_AudioDeviceDescription(
+ AudioDeviceType::OUT_HEADPHONE,
+ GET_DEVICE_DESC_CONNECTION(BT_A2DP))
+ },
+ {
+ AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER, make_AudioDeviceDescription(
+ AudioDeviceType::OUT_SPEAKER,
+ GET_DEVICE_DESC_CONNECTION(BT_A2DP))
+ },
+ {
+ AUDIO_DEVICE_OUT_TELEPHONY_TX, make_AudioDeviceDescription(
+ AudioDeviceType::OUT_TELEPHONY_TX)
+ },
+ {
+ AUDIO_DEVICE_OUT_AUX_LINE, make_AudioDeviceDescription(
+ AudioDeviceType::OUT_LINE_AUX)
+ },
+ {
+ AUDIO_DEVICE_OUT_SPEAKER_SAFE, make_AudioDeviceDescription(
+ AudioDeviceType::OUT_SPEAKER_SAFE)
+ },
+ {
+ AUDIO_DEVICE_OUT_HEARING_AID, make_AudioDeviceDescription(
+ AudioDeviceType::OUT_HEARING_AID,
+ GET_DEVICE_DESC_CONNECTION(WIRELESS))
+ },
+ {
+ AUDIO_DEVICE_OUT_ECHO_CANCELLER, make_AudioDeviceDescription(
+ AudioDeviceType::OUT_ECHO_CANCELLER)
+ },
+ {
+ AUDIO_DEVICE_OUT_BLE_SPEAKER, make_AudioDeviceDescription(
+ AudioDeviceType::OUT_SPEAKER,
+ GET_DEVICE_DESC_CONNECTION(BT_LE))
+ },
+ {
+ AUDIO_DEVICE_OUT_BLE_BROADCAST, make_AudioDeviceDescription(
+ AudioDeviceType::OUT_BROADCAST,
+ GET_DEVICE_DESC_CONNECTION(BT_LE))
+ },
+ // AUDIO_DEVICE_IN_AMBIENT and IN_COMMUNICATION are removed since they were deprecated.
+ {
+ AUDIO_DEVICE_IN_BUILTIN_MIC, make_AudioDeviceDescription(
+ AudioDeviceType::IN_MICROPHONE)
+ },
+ {
+ AUDIO_DEVICE_IN_BACK_MIC, make_AudioDeviceDescription(
+ AudioDeviceType::IN_MICROPHONE_BACK)
+ },
+ {
+ AUDIO_DEVICE_IN_TELEPHONY_RX, make_AudioDeviceDescription(
+ AudioDeviceType::IN_TELEPHONY_RX)
+ },
+ {
+ AUDIO_DEVICE_IN_TV_TUNER, make_AudioDeviceDescription(
+ AudioDeviceType::IN_TV_TUNER)
+ },
+ {
+ AUDIO_DEVICE_IN_LOOPBACK, make_AudioDeviceDescription(
+ AudioDeviceType::IN_LOOPBACK)
+ },
+ {
+ AUDIO_DEVICE_IN_BLUETOOTH_BLE, make_AudioDeviceDescription(
+ AudioDeviceType::IN_DEVICE,
+ GET_DEVICE_DESC_CONNECTION(BT_LE))
+ },
+ {
+ AUDIO_DEVICE_IN_ECHO_REFERENCE, make_AudioDeviceDescription(
+ AudioDeviceType::IN_ECHO_REFERENCE)
+ }
+ }};
+ append_AudioDeviceDescription(pairs,
+ AUDIO_DEVICE_IN_DEFAULT, AUDIO_DEVICE_OUT_DEFAULT,
+ AudioDeviceType::IN_DEFAULT, AudioDeviceType::OUT_DEFAULT);
+ append_AudioDeviceDescription(pairs,
+ AUDIO_DEVICE_IN_WIRED_HEADSET, AUDIO_DEVICE_OUT_WIRED_HEADSET,
+ AudioDeviceType::IN_HEADSET, AudioDeviceType::OUT_HEADSET,
+ GET_DEVICE_DESC_CONNECTION(ANALOG));
+ append_AudioDeviceDescription(pairs,
+ AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET, AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET,
+ AudioDeviceType::IN_HEADSET, AudioDeviceType::OUT_HEADSET,
+ GET_DEVICE_DESC_CONNECTION(BT_SCO));
+ append_AudioDeviceDescription(pairs,
+ AUDIO_DEVICE_IN_HDMI, AUDIO_DEVICE_OUT_HDMI,
+ AudioDeviceType::IN_DEVICE, AudioDeviceType::OUT_DEVICE,
+ GET_DEVICE_DESC_CONNECTION(HDMI));
+ append_AudioDeviceDescription(pairs,
+ AUDIO_DEVICE_IN_REMOTE_SUBMIX, AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
+ AudioDeviceType::IN_SUBMIX, AudioDeviceType::OUT_SUBMIX);
+ append_AudioDeviceDescription(pairs,
+ AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET, AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET,
+ AudioDeviceType::IN_DOCK, AudioDeviceType::OUT_DOCK,
+ GET_DEVICE_DESC_CONNECTION(ANALOG));
+ append_AudioDeviceDescription(pairs,
+ AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET, AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET,
+ AudioDeviceType::IN_DOCK, AudioDeviceType::OUT_DOCK,
+ GET_DEVICE_DESC_CONNECTION(USB));
+ append_AudioDeviceDescription(pairs,
+ AUDIO_DEVICE_IN_USB_ACCESSORY, AUDIO_DEVICE_OUT_USB_ACCESSORY,
+ AudioDeviceType::IN_ACCESSORY, AudioDeviceType::OUT_ACCESSORY,
+ GET_DEVICE_DESC_CONNECTION(USB));
+ append_AudioDeviceDescription(pairs,
+ AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_DEVICE_OUT_USB_DEVICE,
+ AudioDeviceType::IN_DEVICE, AudioDeviceType::OUT_DEVICE,
+ GET_DEVICE_DESC_CONNECTION(USB));
+ append_AudioDeviceDescription(pairs,
+ AUDIO_DEVICE_IN_FM_TUNER, AUDIO_DEVICE_OUT_FM,
+ AudioDeviceType::IN_FM_TUNER, AudioDeviceType::OUT_FM);
+ append_AudioDeviceDescription(pairs,
+ AUDIO_DEVICE_IN_LINE, AUDIO_DEVICE_OUT_LINE,
+ AudioDeviceType::IN_DEVICE, AudioDeviceType::OUT_DEVICE,
+ GET_DEVICE_DESC_CONNECTION(ANALOG));
+ append_AudioDeviceDescription(pairs,
+ AUDIO_DEVICE_IN_SPDIF, AUDIO_DEVICE_OUT_SPDIF,
+ AudioDeviceType::IN_DEVICE, AudioDeviceType::OUT_DEVICE,
+ GET_DEVICE_DESC_CONNECTION(SPDIF));
+ append_AudioDeviceDescription(pairs,
+ AUDIO_DEVICE_IN_BLUETOOTH_A2DP, AUDIO_DEVICE_OUT_BLUETOOTH_A2DP,
+ AudioDeviceType::IN_DEVICE, AudioDeviceType::OUT_DEVICE,
+ GET_DEVICE_DESC_CONNECTION(BT_A2DP));
+ append_AudioDeviceDescription(pairs,
+ AUDIO_DEVICE_IN_IP, AUDIO_DEVICE_OUT_IP,
+ AudioDeviceType::IN_DEVICE, AudioDeviceType::OUT_DEVICE,
+ GET_DEVICE_DESC_CONNECTION(IP_V4));
+ append_AudioDeviceDescription(pairs,
+ AUDIO_DEVICE_IN_BUS, AUDIO_DEVICE_OUT_BUS,
+ AudioDeviceType::IN_DEVICE, AudioDeviceType::OUT_DEVICE,
+ GET_DEVICE_DESC_CONNECTION(BUS));
+ append_AudioDeviceDescription(pairs,
+ AUDIO_DEVICE_IN_PROXY, AUDIO_DEVICE_OUT_PROXY,
+ AudioDeviceType::IN_AFE_PROXY, AudioDeviceType::OUT_AFE_PROXY);
+ append_AudioDeviceDescription(pairs,
+ AUDIO_DEVICE_IN_USB_HEADSET, AUDIO_DEVICE_OUT_USB_HEADSET,
+ AudioDeviceType::IN_HEADSET, AudioDeviceType::OUT_HEADSET,
+ GET_DEVICE_DESC_CONNECTION(USB));
+ append_AudioDeviceDescription(pairs,
+ AUDIO_DEVICE_IN_HDMI_ARC, AUDIO_DEVICE_OUT_HDMI_ARC,
+ AudioDeviceType::IN_DEVICE, AudioDeviceType::OUT_DEVICE,
+ GET_DEVICE_DESC_CONNECTION(HDMI_ARC));
+ append_AudioDeviceDescription(pairs,
+ AUDIO_DEVICE_IN_HDMI_EARC, AUDIO_DEVICE_OUT_HDMI_EARC,
+ AudioDeviceType::IN_DEVICE, AudioDeviceType::OUT_DEVICE,
+ GET_DEVICE_DESC_CONNECTION(HDMI_EARC));
+ append_AudioDeviceDescription(pairs,
+ AUDIO_DEVICE_IN_BLE_HEADSET, AUDIO_DEVICE_OUT_BLE_HEADSET,
+ AudioDeviceType::IN_HEADSET, AudioDeviceType::OUT_HEADSET,
+ GET_DEVICE_DESC_CONNECTION(BT_LE));
+ return pairs;
+ }();
+#undef GET_DEVICE_DESC_CONNECTION
+ return pairs;
+}
+
+AudioFormatDescription make_AudioFormatDescription(AudioFormatType type) {
+ AudioFormatDescription result;
+ result.type = type;
+ return result;
+}
+
+AudioFormatDescription make_AudioFormatDescription(PcmType pcm) {
+ auto result = make_AudioFormatDescription(AudioFormatType::PCM);
+ result.pcm = pcm;
+ return result;
+}
+
+AudioFormatDescription make_AudioFormatDescription(const std::string& encoding) {
+ AudioFormatDescription result;
+ result.encoding = encoding;
+ return result;
+}
+
+AudioFormatDescription make_AudioFormatDescription(PcmType transport,
+ const std::string& encoding) {
+ auto result = make_AudioFormatDescription(encoding);
+ result.pcm = transport;
+ return result;
+}
+
+const detail::AudioFormatPairs& getAudioFormatPairs() {
+ static const detail::AudioFormatPairs pairs = {{
+ {AUDIO_FORMAT_INVALID,
+ make_AudioFormatDescription(AudioFormatType::SYS_RESERVED_INVALID)},
+ {AUDIO_FORMAT_DEFAULT, AudioFormatDescription{}},
+ {AUDIO_FORMAT_PCM_16_BIT, make_AudioFormatDescription(PcmType::INT_16_BIT)},
+ {AUDIO_FORMAT_PCM_8_BIT, make_AudioFormatDescription(PcmType::UINT_8_BIT)},
+ {AUDIO_FORMAT_PCM_32_BIT, make_AudioFormatDescription(PcmType::INT_32_BIT)},
+ {AUDIO_FORMAT_PCM_8_24_BIT, make_AudioFormatDescription(PcmType::FIXED_Q_8_24)},
+ {AUDIO_FORMAT_PCM_FLOAT, make_AudioFormatDescription(PcmType::FLOAT_32_BIT)},
+ {AUDIO_FORMAT_PCM_24_BIT_PACKED, make_AudioFormatDescription(PcmType::INT_24_BIT)},
+ {AUDIO_FORMAT_MP3, make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_MPEG)},
+ {AUDIO_FORMAT_AMR_NB,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_AMR_NB)},
+ {AUDIO_FORMAT_AMR_WB,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_AMR_WB)},
+ {AUDIO_FORMAT_AAC,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_AAC_MP4)},
+ {AUDIO_FORMAT_AAC_MAIN,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_AAC_MAIN)},
+ {AUDIO_FORMAT_AAC_LC,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_AAC_LC)},
+ {AUDIO_FORMAT_AAC_SSR,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_AAC_SSR)},
+ {AUDIO_FORMAT_AAC_LTP,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_AAC_LTP)},
+ {AUDIO_FORMAT_AAC_HE_V1,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_AAC_HE_V1)},
+ {AUDIO_FORMAT_AAC_SCALABLE,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_AAC_SCALABLE)},
+ {AUDIO_FORMAT_AAC_ERLC,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_AAC_ERLC)},
+ {AUDIO_FORMAT_AAC_LD,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_AAC_LD)},
+ {AUDIO_FORMAT_AAC_HE_V2,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_AAC_HE_V2)},
+ {AUDIO_FORMAT_AAC_ELD,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_AAC_ELD)},
+ {AUDIO_FORMAT_AAC_XHE,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_AAC_XHE)
+
+ },
+ // AUDIO_FORMAT_HE_AAC_V1 and HE_AAC_V2 are removed since they were deprecated long time
+ // ago.
+ {AUDIO_FORMAT_VORBIS,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_VORBIS)},
+ {AUDIO_FORMAT_OPUS, make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_OPUS)},
+ {AUDIO_FORMAT_AC3, make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_AC3)},
+ {AUDIO_FORMAT_E_AC3, make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_EAC3)},
+ {AUDIO_FORMAT_E_AC3_JOC,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_EAC3_JOC)},
+ {AUDIO_FORMAT_DTS, make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_DTS)},
+ {AUDIO_FORMAT_DTS_HD,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_DTS_HD)},
+ {AUDIO_FORMAT_DTS_HD_MA,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_DTS_HD_MA)},
+ {AUDIO_FORMAT_DTS_UHD,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_DTS_UHD_P1)},
+ {AUDIO_FORMAT_DTS_UHD_P2,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_DTS_UHD_P2)},
+ // In the future, we would like to represent encapsulated bitstreams as
+ // nested AudioFormatDescriptions. The legacy 'AUDIO_FORMAT_IEC61937' type doesn't
+ // specify the format of the encapsulated bitstream.
+ {AUDIO_FORMAT_IEC61937,
+ make_AudioFormatDescription(PcmType::INT_16_BIT,
+ ::android::MEDIA_MIMETYPE_AUDIO_IEC61937)},
+ {AUDIO_FORMAT_DOLBY_TRUEHD,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_DOLBY_TRUEHD)},
+ {AUDIO_FORMAT_EVRC, make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_EVRC)},
+ {AUDIO_FORMAT_EVRCB,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_EVRCB)},
+ {AUDIO_FORMAT_EVRCWB,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_EVRCWB)},
+ {AUDIO_FORMAT_EVRCNW,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_EVRCNW)},
+ {AUDIO_FORMAT_AAC_ADIF,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_AAC_ADIF)},
+ {AUDIO_FORMAT_WMA, make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_WMA)},
+ {// Note: not in the IANA registry.
+ AUDIO_FORMAT_WMA_PRO, make_AudioFormatDescription("audio/x-ms-wma.pro")},
+ {AUDIO_FORMAT_AMR_WB_PLUS,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_AMR_WB_PLUS)},
+ {AUDIO_FORMAT_MP2,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II)},
+ {AUDIO_FORMAT_QCELP,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_QCELP)},
+ {// Note: not in the IANA registry.
+ AUDIO_FORMAT_DSD, make_AudioFormatDescription("audio/vnd.sony.dsd")},
+ {AUDIO_FORMAT_FLAC, make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_FLAC)},
+ {AUDIO_FORMAT_ALAC, make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_ALAC)},
+ {// Note: not in the IANA registry.
+ AUDIO_FORMAT_APE, make_AudioFormatDescription("audio/x-ape")},
+ {AUDIO_FORMAT_AAC_ADTS,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_AAC_ADTS)},
+ {AUDIO_FORMAT_AAC_ADTS_MAIN,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_AAC_ADTS_MAIN)},
+ {AUDIO_FORMAT_AAC_ADTS_LC,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_AAC_ADTS_LC)},
+ {AUDIO_FORMAT_AAC_ADTS_SSR,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_AAC_ADTS_SSR)},
+ {AUDIO_FORMAT_AAC_ADTS_LTP,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_AAC_ADTS_LTP)},
+ {AUDIO_FORMAT_AAC_ADTS_HE_V1,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_AAC_ADTS_HE_V1)},
+ {AUDIO_FORMAT_AAC_ADTS_SCALABLE,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_AAC_ADTS_SCALABLE)},
+ {AUDIO_FORMAT_AAC_ADTS_ERLC,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_AAC_ADTS_ERLC)},
+ {AUDIO_FORMAT_AAC_ADTS_LD,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_AAC_ADTS_LD)},
+ {AUDIO_FORMAT_AAC_ADTS_HE_V2,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_AAC_ADTS_HE_V2)},
+ {AUDIO_FORMAT_AAC_ADTS_ELD,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_AAC_ADTS_ELD)},
+ {AUDIO_FORMAT_AAC_ADTS_XHE,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_AAC_ADTS_XHE)},
+ {// Note: not in the IANA registry. "vnd.octel.sbc" is not BT SBC.
+ AUDIO_FORMAT_SBC, make_AudioFormatDescription("audio/x-sbc")},
+ {AUDIO_FORMAT_APTX, make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_APTX)},
+ {// Note: not in the IANA registry.
+ AUDIO_FORMAT_APTX_HD, make_AudioFormatDescription("audio/vnd.qcom.aptx.hd")},
+ {AUDIO_FORMAT_AC4, make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_AC4)},
+ {// Note: not in the IANA registry.
+ AUDIO_FORMAT_LDAC, make_AudioFormatDescription("audio/vnd.sony.ldac")},
+ {AUDIO_FORMAT_MAT,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_DOLBY_MAT)},
+ {// Note: not in the IANA registry.
+ AUDIO_FORMAT_MAT_1_0,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_DOLBY_MAT +
+ std::string(".1.0"))},
+ {// Note: not in the IANA registry.
+ AUDIO_FORMAT_MAT_2_0,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_DOLBY_MAT +
+ std::string(".2.0"))},
+ {// Note: not in the IANA registry.
+ AUDIO_FORMAT_MAT_2_1,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_DOLBY_MAT +
+ std::string(".2.1"))},
+ {AUDIO_FORMAT_AAC_LATM,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_AAC)},
+ {AUDIO_FORMAT_AAC_LATM_LC,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_AAC_LATM_LC)},
+ {AUDIO_FORMAT_AAC_LATM_HE_V1,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_AAC_LATM_HE_V1)},
+ {AUDIO_FORMAT_AAC_LATM_HE_V2,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_AAC_LATM_HE_V2)},
+ {// Note: not in the IANA registry.
+ AUDIO_FORMAT_CELT, make_AudioFormatDescription("audio/x-celt")},
+ {// Note: not in the IANA registry.
+ AUDIO_FORMAT_APTX_ADAPTIVE,
+ make_AudioFormatDescription("audio/vnd.qcom.aptx.adaptive")},
+ {// Note: not in the IANA registry.
+ AUDIO_FORMAT_LHDC, make_AudioFormatDescription("audio/vnd.savitech.lhdc")},
+ {// Note: not in the IANA registry.
+ AUDIO_FORMAT_LHDC_LL, make_AudioFormatDescription("audio/vnd.savitech.lhdc.ll")},
+ {// Note: not in the IANA registry.
+ AUDIO_FORMAT_APTX_TWSP, make_AudioFormatDescription("audio/vnd.qcom.aptx.twsp")},
+ {// Note: not in the IANA registry.
+ AUDIO_FORMAT_LC3, make_AudioFormatDescription("audio/x-lc3")},
+ {AUDIO_FORMAT_MPEGH,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_MPEGH_MHM1)},
+ {AUDIO_FORMAT_MPEGH_BL_L3,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_MPEGH_BL_L3)},
+ {AUDIO_FORMAT_MPEGH_BL_L4,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_MPEGH_BL_L4)},
+ {AUDIO_FORMAT_MPEGH_LC_L3,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_MPEGH_LC_L3)},
+ {AUDIO_FORMAT_MPEGH_LC_L4,
+ make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_MPEGH_LC_L4)},
+ {AUDIO_FORMAT_IEC60958,
+ make_AudioFormatDescription(PcmType::INT_24_BIT,
+ ::android::MEDIA_MIMETYPE_AUDIO_IEC60958)},
+ {AUDIO_FORMAT_DRA, make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_DRA)},
+ {// Note: not in the IANA registry.
+ AUDIO_FORMAT_APTX_ADAPTIVE_QLEA,
+ make_AudioFormatDescription("audio/vnd.qcom.aptx.adaptive.r3")},
+ {// Note: not in the IANA registry.
+ AUDIO_FORMAT_APTX_ADAPTIVE_R4,
+ make_AudioFormatDescription("audio/vnd.qcom.aptx.adaptive.r4")},
+ }};
+ return pairs;
+}
+
+template<typename S, typename T>
+std::map<S, T> make_DirectMap(const std::vector<std::pair<S, T>>& v) {
+ std::map<S, T> result(v.begin(), v.end());
+ LOG_ALWAYS_FATAL_IF(result.size() != v.size(), "Duplicate key elements detected");
+ return result;
+}
+
+template<typename S, typename T>
+std::map<S, T> make_DirectMap(
+ const std::vector<std::pair<S, T>>& v1, const std::vector<std::pair<S, T>>& v2) {
+ std::map<S, T> result(v1.begin(), v1.end());
+ LOG_ALWAYS_FATAL_IF(result.size() != v1.size(), "Duplicate key elements detected in v1");
+ result.insert(v2.begin(), v2.end());
+ LOG_ALWAYS_FATAL_IF(result.size() != v1.size() + v2.size(),
+ "Duplicate key elements detected in v1+v2");
+ return result;
+}
+
+template<typename S, typename T>
+std::map<T, S> make_ReverseMap(const std::vector<std::pair<S, T>>& v) {
+ std::map<T, S> result;
+ std::transform(v.begin(), v.end(), std::inserter(result, result.begin()),
+ [](const std::pair<S, T>& p) {
+ return std::make_pair(p.second, p.first);
+ });
+ LOG_ALWAYS_FATAL_IF(result.size() != v.size(), "Duplicate key elements detected");
+ return result;
+}
+
+} // namespace
+
+audio_channel_mask_t aidl2legacy_AudioChannelLayout_layout_audio_channel_mask_t_bits(
+ int aidlLayout, bool isInput) {
+ auto& bitMapping = isInput ? getInAudioChannelBits() : getOutAudioChannelBits();
+ const int aidlLayoutInitial = aidlLayout; // for error message
+ audio_channel_mask_t legacy = AUDIO_CHANNEL_NONE;
+ for (const auto& bitPair : bitMapping) {
+ if ((aidlLayout & bitPair.second) == bitPair.second) {
+ legacy = static_cast<audio_channel_mask_t>(legacy | bitPair.first);
+ aidlLayout &= ~bitPair.second;
+ if (aidlLayout == 0) {
+ return legacy;
+ }
+ }
+ }
+ ALOGE("%s: aidl layout 0x%x contains bits 0x%x that have no match to legacy %s bits",
+ __func__, aidlLayoutInitial, aidlLayout, isInput ? "input" : "output");
+ return AUDIO_CHANNEL_NONE;
+}
+
+ConversionResult<audio_channel_mask_t> aidl2legacy_AudioChannelLayout_audio_channel_mask_t(
+ const AudioChannelLayout& aidl, bool isInput) {
+ using ReverseMap = std::map<AudioChannelLayout, audio_channel_mask_t>;
+ using Tag = AudioChannelLayout::Tag;
+ static const ReverseMap mIn = make_ReverseMap(getInAudioChannelPairs());
+ static const ReverseMap mOut = make_ReverseMap(getOutAudioChannelPairs());
+ static const ReverseMap mVoice = make_ReverseMap(getVoiceAudioChannelPairs());
+
+ auto convert = [](const AudioChannelLayout& aidl, const ReverseMap& m,
+ const char* func, const char* type) -> ConversionResult<audio_channel_mask_t> {
+ if (auto it = m.find(aidl); it != m.end()) {
+ return it->second;
+ } else {
+ ALOGW("%s: no legacy %s audio_channel_mask_t found for %s", func, type,
+ aidl.toString().c_str());
+ return unexpected(BAD_VALUE);
+ }
+ };
+
+ switch (aidl.getTag()) {
+ case Tag::none:
+ return AUDIO_CHANNEL_NONE;
+ case Tag::invalid:
+ return AUDIO_CHANNEL_INVALID;
+ case Tag::indexMask:
+ // Index masks do not have pre-defined values.
+ if (const int bits = aidl.get<Tag::indexMask>();
+ __builtin_popcount(bits) != 0 &&
+ __builtin_popcount(bits) <= (int)AUDIO_CHANNEL_COUNT_MAX) {
+ return audio_channel_mask_from_representation_and_bits(
+ AUDIO_CHANNEL_REPRESENTATION_INDEX, bits);
+ } else {
+ ALOGE("%s: invalid indexMask value 0x%x in %s",
+ __func__, bits, aidl.toString().c_str());
+ return unexpected(BAD_VALUE);
+ }
+ case Tag::layoutMask:
+ // The fast path is to find a direct match for some known layout mask.
+ if (const auto layoutMatch = convert(aidl, isInput ? mIn : mOut, __func__,
+ isInput ? "input" : "output");
+ layoutMatch.ok()) {
+ return layoutMatch;
+ }
+ // If a match for a predefined layout wasn't found, make a custom one from bits.
+ if (audio_channel_mask_t bitMask =
+ aidl2legacy_AudioChannelLayout_layout_audio_channel_mask_t_bits(
+ aidl.get<Tag::layoutMask>(), isInput);
+ bitMask != AUDIO_CHANNEL_NONE) {
+ return bitMask;
+ }
+ return unexpected(BAD_VALUE);
+ case Tag::voiceMask:
+ return convert(aidl, mVoice, __func__, "voice");
+ }
+ ALOGE("%s: unexpected tag value %d", __func__, aidl.getTag());
+ return unexpected(BAD_VALUE);
+}
+
+int legacy2aidl_audio_channel_mask_t_bits_AudioChannelLayout_layout(
+ audio_channel_mask_t legacy, bool isInput) {
+ auto& bitMapping = isInput ? getInAudioChannelBits() : getOutAudioChannelBits();
+ const int legacyInitial = legacy; // for error message
+ int aidlLayout = 0;
+ for (const auto& bitPair : bitMapping) {
+ if ((legacy & bitPair.first) == bitPair.first) {
+ aidlLayout |= bitPair.second;
+ legacy = static_cast<audio_channel_mask_t>(legacy & ~bitPair.first);
+ if (legacy == 0) {
+ return aidlLayout;
+ }
+ }
+ }
+ ALOGE("%s: legacy %s audio_channel_mask_t 0x%x contains unrecognized bits 0x%x",
+ __func__, isInput ? "input" : "output", legacyInitial, legacy);
+ return 0;
+}
+
+ConversionResult<AudioChannelLayout> legacy2aidl_audio_channel_mask_t_AudioChannelLayout(
+ audio_channel_mask_t legacy, bool isInput) {
+ using DirectMap = std::map<audio_channel_mask_t, AudioChannelLayout>;
+ using Tag = AudioChannelLayout::Tag;
+ static const DirectMap mInAndVoice = make_DirectMap(
+ getInAudioChannelPairs(), getVoiceAudioChannelPairs());
+ static const DirectMap mOut = make_DirectMap(getOutAudioChannelPairs());
+
+ auto convert = [](const audio_channel_mask_t legacy, const DirectMap& m,
+ const char* func, const char* type) -> ConversionResult<AudioChannelLayout> {
+ if (auto it = m.find(legacy); it != m.end()) {
+ return it->second;
+ } else {
+ ALOGW("%s: no AudioChannelLayout found for legacy %s audio_channel_mask_t value 0x%x",
+ func, type, legacy);
+ return unexpected(BAD_VALUE);
+ }
+ };
+
+ if (legacy == AUDIO_CHANNEL_NONE) {
+ return AudioChannelLayout{};
+ } else if (legacy == AUDIO_CHANNEL_INVALID) {
+ return AudioChannelLayout::make<Tag::invalid>(0);
+ }
+
+ const audio_channel_representation_t repr = audio_channel_mask_get_representation(legacy);
+ if (repr == AUDIO_CHANNEL_REPRESENTATION_INDEX) {
+ if (audio_channel_mask_is_valid(legacy)) {
+ const int indexMask = VALUE_OR_RETURN(
+ convertIntegral<int>(audio_channel_mask_get_bits(legacy)));
+ return AudioChannelLayout::make<Tag::indexMask>(indexMask);
+ } else {
+ ALOGE("%s: legacy audio_channel_mask_t value 0x%x is invalid", __func__, legacy);
+ return unexpected(BAD_VALUE);
+ }
+ } else if (repr == AUDIO_CHANNEL_REPRESENTATION_POSITION) {
+ // The fast path is to find a direct match for some known layout mask.
+ if (const auto layoutMatch = convert(legacy, isInput ? mInAndVoice : mOut, __func__,
+ isInput ? "input / voice" : "output");
+ layoutMatch.ok()) {
+ return layoutMatch;
+ }
+ // If a match for a predefined layout wasn't found, make a custom one from bits,
+ // rejecting those with voice channel bits.
+ if (!isInput ||
+ (legacy & (AUDIO_CHANNEL_IN_VOICE_UPLINK | AUDIO_CHANNEL_IN_VOICE_DNLINK)) == 0) {
+ if (int bitMaskLayout =
+ legacy2aidl_audio_channel_mask_t_bits_AudioChannelLayout_layout(
+ legacy, isInput);
+ bitMaskLayout != 0) {
+ return AudioChannelLayout::make<Tag::layoutMask>(bitMaskLayout);
+ }
+ } else {
+ ALOGE("%s: legacy audio_channel_mask_t value 0x%x contains voice bits",
+ __func__, legacy);
+ }
+ return unexpected(BAD_VALUE);
+ }
+
+ ALOGE("%s: unknown representation %d in audio_channel_mask_t value 0x%x",
+ __func__, repr, legacy);
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<audio_devices_t> aidl2legacy_AudioDeviceDescription_audio_devices_t(
+ const AudioDeviceDescription& aidl) {
+ static const std::map<AudioDeviceDescription, audio_devices_t> m =
+ make_ReverseMap(getAudioDevicePairs());
+ if (auto it = m.find(aidl); it != m.end()) {
+ return it->second;
+ } else {
+ ALOGE("%s: no legacy audio_devices_t found for %s", __func__, aidl.toString().c_str());
+ return unexpected(BAD_VALUE);
+ }
+}
+
+ConversionResult<AudioDeviceDescription> legacy2aidl_audio_devices_t_AudioDeviceDescription(
+ audio_devices_t legacy) {
+ static const std::map<audio_devices_t, AudioDeviceDescription> m =
+ make_DirectMap(getAudioDevicePairs());
+ if (auto it = m.find(legacy); it != m.end()) {
+ return it->second;
+ } else {
+ ALOGE("%s: no AudioDeviceDescription found for legacy audio_devices_t value 0x%x",
+ __func__, legacy);
+ return unexpected(BAD_VALUE);
+ }
+}
+
+::android::status_t aidl2legacy_AudioDevice_audio_device(
+ const AudioDevice& aidl,
+ audio_devices_t* legacyType, char* legacyAddress) {
+ *legacyType = VALUE_OR_RETURN_STATUS(
+ aidl2legacy_AudioDeviceDescription_audio_devices_t(aidl.type));
+ return aidl2legacy_string(
+ aidl.address.get<AudioDeviceAddress::id>(),
+ legacyAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN);
+}
+
+::android::status_t aidl2legacy_AudioDevice_audio_device(
+ const AudioDevice& aidl,
+ audio_devices_t* legacyType, String8* legacyAddress) {
+ *legacyType = VALUE_OR_RETURN_STATUS(
+ aidl2legacy_AudioDeviceDescription_audio_devices_t(aidl.type));
+ *legacyAddress = VALUE_OR_RETURN_STATUS(aidl2legacy_string_view_String8(
+ aidl.address.get<AudioDeviceAddress::id>()));
+ return OK;
+}
+
+::android::status_t aidl2legacy_AudioDevice_audio_device(
+ const AudioDevice& aidl,
+ audio_devices_t* legacyType, std::string* legacyAddress) {
+ *legacyType = VALUE_OR_RETURN_STATUS(
+ aidl2legacy_AudioDeviceDescription_audio_devices_t(aidl.type));
+ *legacyAddress = aidl.address.get<AudioDeviceAddress::id>();
+ return OK;
+}
+
+ConversionResult<AudioDevice> legacy2aidl_audio_device_AudioDevice(
+ audio_devices_t legacyType, const char* legacyAddress) {
+ AudioDevice aidl;
+ aidl.type = VALUE_OR_RETURN(
+ legacy2aidl_audio_devices_t_AudioDeviceDescription(legacyType));
+ const std::string aidl_id = VALUE_OR_RETURN(
+ legacy2aidl_string(legacyAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN));
+ aidl.address = AudioDeviceAddress::make<AudioDeviceAddress::id>(aidl_id);
+ return aidl;
+}
+
+ConversionResult<AudioDevice>
+legacy2aidl_audio_device_AudioDevice(
+ audio_devices_t legacyType, const String8& legacyAddress) {
+ AudioDevice aidl;
+ aidl.type = VALUE_OR_RETURN(
+ legacy2aidl_audio_devices_t_AudioDeviceDescription(legacyType));
+ const std::string aidl_id = VALUE_OR_RETURN(
+ legacy2aidl_String8_string(legacyAddress));
+ aidl.address = AudioDeviceAddress::make<AudioDeviceAddress::id>(aidl_id);
+ return aidl;
+}
+
+ConversionResult<audio_format_t> aidl2legacy_AudioFormatDescription_audio_format_t(
+ const AudioFormatDescription& aidl) {
+ static const std::map<AudioFormatDescription, audio_format_t> m =
+ make_ReverseMap(getAudioFormatPairs());
+ if (auto it = m.find(aidl); it != m.end()) {
+ return it->second;
+ } else {
+ ALOGE("%s: no legacy audio_format_t found for %s", __func__, aidl.toString().c_str());
+ return unexpected(BAD_VALUE);
+ }
+}
+
+ConversionResult<AudioFormatDescription> legacy2aidl_audio_format_t_AudioFormatDescription(
+ audio_format_t legacy) {
+ static const std::map<audio_format_t, AudioFormatDescription> m =
+ make_DirectMap(getAudioFormatPairs());
+ if (auto it = m.find(legacy); it != m.end()) {
+ return it->second;
+ } else {
+ ALOGE("%s: no AudioFormatDescription found for legacy audio_format_t value 0x%x",
+ __func__, legacy);
+ return unexpected(BAD_VALUE);
+ }
+}
+
+ConversionResult<audio_gain_mode_t> aidl2legacy_AudioGainMode_audio_gain_mode_t(
+ AudioGainMode aidl) {
+ switch (aidl) {
+ case AudioGainMode::JOINT:
+ return AUDIO_GAIN_MODE_JOINT;
+ case AudioGainMode::CHANNELS:
+ return AUDIO_GAIN_MODE_CHANNELS;
+ case AudioGainMode::RAMP:
+ return AUDIO_GAIN_MODE_RAMP;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<AudioGainMode> legacy2aidl_audio_gain_mode_t_AudioGainMode(
+ audio_gain_mode_t legacy) {
+ switch (legacy) {
+ case AUDIO_GAIN_MODE_JOINT:
+ return AudioGainMode::JOINT;
+ case AUDIO_GAIN_MODE_CHANNELS:
+ return AudioGainMode::CHANNELS;
+ case AUDIO_GAIN_MODE_RAMP:
+ return AudioGainMode::RAMP;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<audio_gain_mode_t> aidl2legacy_int32_t_audio_gain_mode_t_mask(int32_t aidl) {
+ return convertBitmask<audio_gain_mode_t, int32_t, audio_gain_mode_t, AudioGainMode>(
+ aidl, aidl2legacy_AudioGainMode_audio_gain_mode_t,
+ // AudioGainMode is index-based.
+ indexToEnum_index<AudioGainMode>,
+ // AUDIO_GAIN_MODE_* constants are mask-based.
+ enumToMask_bitmask<audio_gain_mode_t, audio_gain_mode_t>);
+}
+
+ConversionResult<int32_t> legacy2aidl_audio_gain_mode_t_int32_t_mask(audio_gain_mode_t legacy) {
+ return convertBitmask<int32_t, audio_gain_mode_t, AudioGainMode, audio_gain_mode_t>(
+ legacy, legacy2aidl_audio_gain_mode_t_AudioGainMode,
+ // AUDIO_GAIN_MODE_* constants are mask-based.
+ indexToEnum_bitmask<audio_gain_mode_t>,
+ // AudioGainMode is index-based.
+ enumToMask_index<int32_t, AudioGainMode>);
+}
+
+ConversionResult<audio_gain_config> aidl2legacy_AudioGainConfig_audio_gain_config(
+ const AudioGainConfig& aidl, bool isInput) {
+ audio_gain_config legacy;
+ legacy.index = VALUE_OR_RETURN(convertIntegral<int>(aidl.index));
+ legacy.mode = VALUE_OR_RETURN(aidl2legacy_int32_t_audio_gain_mode_t_mask(aidl.mode));
+ legacy.channel_mask = VALUE_OR_RETURN(
+ aidl2legacy_AudioChannelLayout_audio_channel_mask_t(aidl.channelMask, isInput));
+ const bool isJoint = bitmaskIsSet(aidl.mode, AudioGainMode::JOINT);
+ size_t numValues = isJoint ? 1
+ : isInput ? audio_channel_count_from_in_mask(legacy.channel_mask)
+ : audio_channel_count_from_out_mask(legacy.channel_mask);
+ if (aidl.values.size() != numValues || aidl.values.size() > std::size(legacy.values)) {
+ return unexpected(BAD_VALUE);
+ }
+ for (size_t i = 0; i < numValues; ++i) {
+ legacy.values[i] = VALUE_OR_RETURN(convertIntegral<int>(aidl.values[i]));
+ }
+ legacy.ramp_duration_ms = VALUE_OR_RETURN(convertIntegral<int>(aidl.rampDurationMs));
+ return legacy;
+}
+
+ConversionResult<AudioGainConfig> legacy2aidl_audio_gain_config_AudioGainConfig(
+ const audio_gain_config& legacy, bool isInput) {
+ AudioGainConfig aidl;
+ aidl.index = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.index));
+ aidl.mode = VALUE_OR_RETURN(legacy2aidl_audio_gain_mode_t_int32_t_mask(legacy.mode));
+ aidl.channelMask = VALUE_OR_RETURN(
+ legacy2aidl_audio_channel_mask_t_AudioChannelLayout(legacy.channel_mask, isInput));
+ const bool isJoint = (legacy.mode & AUDIO_GAIN_MODE_JOINT) != 0;
+ size_t numValues = isJoint ? 1
+ : isInput ? audio_channel_count_from_in_mask(legacy.channel_mask)
+ : audio_channel_count_from_out_mask(legacy.channel_mask);
+ aidl.values.resize(numValues);
+ for (size_t i = 0; i < numValues; ++i) {
+ aidl.values[i] = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.values[i]));
+ }
+ aidl.rampDurationMs = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.ramp_duration_ms));
+ return aidl;
+}
+
+ConversionResult<audio_input_flags_t> aidl2legacy_AudioInputFlags_audio_input_flags_t(
+ AudioInputFlags aidl) {
+ switch (aidl) {
+ case AudioInputFlags::FAST:
+ return AUDIO_INPUT_FLAG_FAST;
+ case AudioInputFlags::HW_HOTWORD:
+ return AUDIO_INPUT_FLAG_HW_HOTWORD;
+ case AudioInputFlags::RAW:
+ return AUDIO_INPUT_FLAG_RAW;
+ case AudioInputFlags::SYNC:
+ return AUDIO_INPUT_FLAG_SYNC;
+ case AudioInputFlags::MMAP_NOIRQ:
+ return AUDIO_INPUT_FLAG_MMAP_NOIRQ;
+ case AudioInputFlags::VOIP_TX:
+ return AUDIO_INPUT_FLAG_VOIP_TX;
+ case AudioInputFlags::HW_AV_SYNC:
+ return AUDIO_INPUT_FLAG_HW_AV_SYNC;
+ case AudioInputFlags::DIRECT:
+ return AUDIO_INPUT_FLAG_DIRECT;
+ case AudioInputFlags::ULTRASOUND:
+ return AUDIO_INPUT_FLAG_ULTRASOUND;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<AudioInputFlags> legacy2aidl_audio_input_flags_t_AudioInputFlags(
+ audio_input_flags_t legacy) {
+ switch (legacy) {
+ case AUDIO_INPUT_FLAG_NONE:
+ break; // shouldn't get here. must be listed -Werror,-Wswitch
+ case AUDIO_INPUT_FLAG_FAST:
+ return AudioInputFlags::FAST;
+ case AUDIO_INPUT_FLAG_HW_HOTWORD:
+ return AudioInputFlags::HW_HOTWORD;
+ case AUDIO_INPUT_FLAG_RAW:
+ return AudioInputFlags::RAW;
+ case AUDIO_INPUT_FLAG_SYNC:
+ return AudioInputFlags::SYNC;
+ case AUDIO_INPUT_FLAG_MMAP_NOIRQ:
+ return AudioInputFlags::MMAP_NOIRQ;
+ case AUDIO_INPUT_FLAG_VOIP_TX:
+ return AudioInputFlags::VOIP_TX;
+ case AUDIO_INPUT_FLAG_HW_AV_SYNC:
+ return AudioInputFlags::HW_AV_SYNC;
+ case AUDIO_INPUT_FLAG_DIRECT:
+ return AudioInputFlags::DIRECT;
+ case AUDIO_INPUT_FLAG_ULTRASOUND:
+ return AudioInputFlags::ULTRASOUND;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<audio_output_flags_t> aidl2legacy_AudioOutputFlags_audio_output_flags_t(
+ AudioOutputFlags aidl) {
+ switch (aidl) {
+ case AudioOutputFlags::DIRECT:
+ return AUDIO_OUTPUT_FLAG_DIRECT;
+ case AudioOutputFlags::PRIMARY:
+ return AUDIO_OUTPUT_FLAG_PRIMARY;
+ case AudioOutputFlags::FAST:
+ return AUDIO_OUTPUT_FLAG_FAST;
+ case AudioOutputFlags::DEEP_BUFFER:
+ return AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
+ case AudioOutputFlags::COMPRESS_OFFLOAD:
+ return AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
+ case AudioOutputFlags::NON_BLOCKING:
+ return AUDIO_OUTPUT_FLAG_NON_BLOCKING;
+ case AudioOutputFlags::HW_AV_SYNC:
+ return AUDIO_OUTPUT_FLAG_HW_AV_SYNC;
+ case AudioOutputFlags::TTS:
+ return AUDIO_OUTPUT_FLAG_TTS;
+ case AudioOutputFlags::RAW:
+ return AUDIO_OUTPUT_FLAG_RAW;
+ case AudioOutputFlags::SYNC:
+ return AUDIO_OUTPUT_FLAG_SYNC;
+ case AudioOutputFlags::IEC958_NONAUDIO:
+ return AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO;
+ case AudioOutputFlags::DIRECT_PCM:
+ return AUDIO_OUTPUT_FLAG_DIRECT_PCM;
+ case AudioOutputFlags::MMAP_NOIRQ:
+ return AUDIO_OUTPUT_FLAG_MMAP_NOIRQ;
+ case AudioOutputFlags::VOIP_RX:
+ return AUDIO_OUTPUT_FLAG_VOIP_RX;
+ case AudioOutputFlags::INCALL_MUSIC:
+ return AUDIO_OUTPUT_FLAG_INCALL_MUSIC;
+ case AudioOutputFlags::GAPLESS_OFFLOAD:
+ return AUDIO_OUTPUT_FLAG_GAPLESS_OFFLOAD;
+ case AudioOutputFlags::ULTRASOUND:
+ return AUDIO_OUTPUT_FLAG_ULTRASOUND;
+ case AudioOutputFlags::SPATIALIZER:
+ return AUDIO_OUTPUT_FLAG_SPATIALIZER;
+ case AudioOutputFlags::BIT_PERFECT:
+ return AUDIO_OUTPUT_FLAG_BIT_PERFECT;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<AudioOutputFlags> legacy2aidl_audio_output_flags_t_AudioOutputFlags(
+ audio_output_flags_t legacy) {
+ switch (legacy) {
+ case AUDIO_OUTPUT_FLAG_NONE:
+ break; // shouldn't get here. must be listed -Werror,-Wswitch
+ case AUDIO_OUTPUT_FLAG_DIRECT:
+ return AudioOutputFlags::DIRECT;
+ case AUDIO_OUTPUT_FLAG_PRIMARY:
+ return AudioOutputFlags::PRIMARY;
+ case AUDIO_OUTPUT_FLAG_FAST:
+ return AudioOutputFlags::FAST;
+ case AUDIO_OUTPUT_FLAG_DEEP_BUFFER:
+ return AudioOutputFlags::DEEP_BUFFER;
+ case AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD:
+ return AudioOutputFlags::COMPRESS_OFFLOAD;
+ case AUDIO_OUTPUT_FLAG_NON_BLOCKING:
+ return AudioOutputFlags::NON_BLOCKING;
+ case AUDIO_OUTPUT_FLAG_HW_AV_SYNC:
+ return AudioOutputFlags::HW_AV_SYNC;
+ case AUDIO_OUTPUT_FLAG_TTS:
+ return AudioOutputFlags::TTS;
+ case AUDIO_OUTPUT_FLAG_RAW:
+ return AudioOutputFlags::RAW;
+ case AUDIO_OUTPUT_FLAG_SYNC:
+ return AudioOutputFlags::SYNC;
+ case AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO:
+ return AudioOutputFlags::IEC958_NONAUDIO;
+ case AUDIO_OUTPUT_FLAG_DIRECT_PCM:
+ return AudioOutputFlags::DIRECT_PCM;
+ case AUDIO_OUTPUT_FLAG_MMAP_NOIRQ:
+ return AudioOutputFlags::MMAP_NOIRQ;
+ case AUDIO_OUTPUT_FLAG_VOIP_RX:
+ return AudioOutputFlags::VOIP_RX;
+ case AUDIO_OUTPUT_FLAG_INCALL_MUSIC:
+ return AudioOutputFlags::INCALL_MUSIC;
+ case AUDIO_OUTPUT_FLAG_GAPLESS_OFFLOAD:
+ return AudioOutputFlags::GAPLESS_OFFLOAD;
+ case AUDIO_OUTPUT_FLAG_ULTRASOUND:
+ return AudioOutputFlags::ULTRASOUND;
+ case AUDIO_OUTPUT_FLAG_SPATIALIZER:
+ return AudioOutputFlags::SPATIALIZER;
+ case AUDIO_OUTPUT_FLAG_BIT_PERFECT:
+ return AudioOutputFlags::BIT_PERFECT;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<audio_input_flags_t> aidl2legacy_int32_t_audio_input_flags_t_mask(
+ int32_t aidl) {
+ using LegacyMask = std::underlying_type_t<audio_input_flags_t>;
+
+ LegacyMask converted = VALUE_OR_RETURN(
+ (convertBitmask<LegacyMask, int32_t, audio_input_flags_t, AudioInputFlags>(
+ aidl, aidl2legacy_AudioInputFlags_audio_input_flags_t,
+ indexToEnum_index<AudioInputFlags>,
+ enumToMask_bitmask<LegacyMask, audio_input_flags_t>)));
+ return static_cast<audio_input_flags_t>(converted);
+}
+
+ConversionResult<int32_t> legacy2aidl_audio_input_flags_t_int32_t_mask(
+ audio_input_flags_t legacy) {
+ using LegacyMask = std::underlying_type_t<audio_input_flags_t>;
+
+ LegacyMask legacyMask = static_cast<LegacyMask>(legacy);
+ return convertBitmask<int32_t, LegacyMask, AudioInputFlags, audio_input_flags_t>(
+ legacyMask, legacy2aidl_audio_input_flags_t_AudioInputFlags,
+ indexToEnum_bitmask<audio_input_flags_t>,
+ enumToMask_index<int32_t, AudioInputFlags>);
+}
+
+ConversionResult<audio_output_flags_t> aidl2legacy_int32_t_audio_output_flags_t_mask(
+ int32_t aidl) {
+ return convertBitmask<audio_output_flags_t,
+ int32_t,
+ audio_output_flags_t,
+ AudioOutputFlags>(
+ aidl, aidl2legacy_AudioOutputFlags_audio_output_flags_t,
+ indexToEnum_index<AudioOutputFlags>,
+ enumToMask_bitmask<audio_output_flags_t, audio_output_flags_t>);
+}
+
+ConversionResult<int32_t> legacy2aidl_audio_output_flags_t_int32_t_mask(
+ audio_output_flags_t legacy) {
+ using LegacyMask = std::underlying_type_t<audio_output_flags_t>;
+
+ LegacyMask legacyMask = static_cast<LegacyMask>(legacy);
+ return convertBitmask<int32_t, LegacyMask, AudioOutputFlags, audio_output_flags_t>(
+ legacyMask, legacy2aidl_audio_output_flags_t_AudioOutputFlags,
+ indexToEnum_bitmask<audio_output_flags_t>,
+ enumToMask_index<int32_t, AudioOutputFlags>);
+}
+
+ConversionResult<audio_io_flags> aidl2legacy_AudioIoFlags_audio_io_flags(
+ const AudioIoFlags& aidl, bool isInput) {
+ audio_io_flags legacy;
+ if (isInput) {
+ legacy.input = VALUE_OR_RETURN(
+ aidl2legacy_int32_t_audio_input_flags_t_mask(
+ VALUE_OR_RETURN(UNION_GET(aidl, input))));
+ } else {
+ legacy.output = VALUE_OR_RETURN(
+ aidl2legacy_int32_t_audio_output_flags_t_mask(
+ VALUE_OR_RETURN(UNION_GET(aidl, output))));
+ }
+ return legacy;
+}
+
+ConversionResult<AudioIoFlags> legacy2aidl_audio_io_flags_AudioIoFlags(
+ const audio_io_flags& legacy, bool isInput) {
+ AudioIoFlags aidl;
+ if (isInput) {
+ UNION_SET(aidl, input,
+ VALUE_OR_RETURN(legacy2aidl_audio_input_flags_t_int32_t_mask(legacy.input)));
+ } else {
+ UNION_SET(aidl, output,
+ VALUE_OR_RETURN(legacy2aidl_audio_output_flags_t_int32_t_mask(legacy.output)));
+ }
+ return aidl;
+}
+
+ConversionResult<audio_stream_type_t> aidl2legacy_AudioStreamType_audio_stream_type_t(
+ AudioStreamType aidl) {
+ switch (aidl) {
+ case AudioStreamType::INVALID:
+ break; // return error
+ case AudioStreamType::SYS_RESERVED_DEFAULT:
+ return AUDIO_STREAM_DEFAULT;
+ case AudioStreamType::VOICE_CALL:
+ return AUDIO_STREAM_VOICE_CALL;
+ case AudioStreamType::SYSTEM:
+ return AUDIO_STREAM_SYSTEM;
+ case AudioStreamType::RING:
+ return AUDIO_STREAM_RING;
+ case AudioStreamType::MUSIC:
+ return AUDIO_STREAM_MUSIC;
+ case AudioStreamType::ALARM:
+ return AUDIO_STREAM_ALARM;
+ case AudioStreamType::NOTIFICATION:
+ return AUDIO_STREAM_NOTIFICATION;
+ case AudioStreamType::BLUETOOTH_SCO:
+ return AUDIO_STREAM_BLUETOOTH_SCO;
+ case AudioStreamType::ENFORCED_AUDIBLE:
+ return AUDIO_STREAM_ENFORCED_AUDIBLE;
+ case AudioStreamType::DTMF:
+ return AUDIO_STREAM_DTMF;
+ case AudioStreamType::TTS:
+ return AUDIO_STREAM_TTS;
+ case AudioStreamType::ACCESSIBILITY:
+ return AUDIO_STREAM_ACCESSIBILITY;
+ case AudioStreamType::ASSISTANT:
+ return AUDIO_STREAM_ASSISTANT;
+ case AudioStreamType::SYS_RESERVED_REROUTING:
+ return AUDIO_STREAM_REROUTING;
+ case AudioStreamType::SYS_RESERVED_PATCH:
+ return AUDIO_STREAM_PATCH;
+ case AudioStreamType::CALL_ASSISTANT:
+ return AUDIO_STREAM_CALL_ASSISTANT;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<AudioStreamType> legacy2aidl_audio_stream_type_t_AudioStreamType(
+ audio_stream_type_t legacy) {
+ switch (legacy) {
+ case AUDIO_STREAM_DEFAULT:
+ return AudioStreamType::SYS_RESERVED_DEFAULT;
+ case AUDIO_STREAM_VOICE_CALL:
+ return AudioStreamType::VOICE_CALL;
+ case AUDIO_STREAM_SYSTEM:
+ return AudioStreamType::SYSTEM;
+ case AUDIO_STREAM_RING:
+ return AudioStreamType::RING;
+ case AUDIO_STREAM_MUSIC:
+ return AudioStreamType::MUSIC;
+ case AUDIO_STREAM_ALARM:
+ return AudioStreamType::ALARM;
+ case AUDIO_STREAM_NOTIFICATION:
+ return AudioStreamType::NOTIFICATION;
+ case AUDIO_STREAM_BLUETOOTH_SCO:
+ return AudioStreamType::BLUETOOTH_SCO;
+ case AUDIO_STREAM_ENFORCED_AUDIBLE:
+ return AudioStreamType::ENFORCED_AUDIBLE;
+ case AUDIO_STREAM_DTMF:
+ return AudioStreamType::DTMF;
+ case AUDIO_STREAM_TTS:
+ return AudioStreamType::TTS;
+ case AUDIO_STREAM_ACCESSIBILITY:
+ return AudioStreamType::ACCESSIBILITY;
+ case AUDIO_STREAM_ASSISTANT:
+ return AudioStreamType::ASSISTANT;
+ case AUDIO_STREAM_REROUTING:
+ return AudioStreamType::SYS_RESERVED_REROUTING;
+ case AUDIO_STREAM_PATCH:
+ return AudioStreamType::SYS_RESERVED_PATCH;
+ case AUDIO_STREAM_CALL_ASSISTANT:
+ return AudioStreamType::CALL_ASSISTANT;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<audio_source_t> aidl2legacy_AudioSource_audio_source_t(
+ AudioSource aidl) {
+ switch (aidl) {
+ case AudioSource::SYS_RESERVED_INVALID:
+ return AUDIO_SOURCE_INVALID;
+ case AudioSource::DEFAULT:
+ return AUDIO_SOURCE_DEFAULT;
+ case AudioSource::MIC:
+ return AUDIO_SOURCE_MIC;
+ case AudioSource::VOICE_UPLINK:
+ return AUDIO_SOURCE_VOICE_UPLINK;
+ case AudioSource::VOICE_DOWNLINK:
+ return AUDIO_SOURCE_VOICE_DOWNLINK;
+ case AudioSource::VOICE_CALL:
+ return AUDIO_SOURCE_VOICE_CALL;
+ case AudioSource::CAMCORDER:
+ return AUDIO_SOURCE_CAMCORDER;
+ case AudioSource::VOICE_RECOGNITION:
+ return AUDIO_SOURCE_VOICE_RECOGNITION;
+ case AudioSource::VOICE_COMMUNICATION:
+ return AUDIO_SOURCE_VOICE_COMMUNICATION;
+ case AudioSource::REMOTE_SUBMIX:
+ return AUDIO_SOURCE_REMOTE_SUBMIX;
+ case AudioSource::UNPROCESSED:
+ return AUDIO_SOURCE_UNPROCESSED;
+ case AudioSource::VOICE_PERFORMANCE:
+ return AUDIO_SOURCE_VOICE_PERFORMANCE;
+ case AudioSource::ULTRASOUND:
+ return AUDIO_SOURCE_ULTRASOUND;
+ case AudioSource::ECHO_REFERENCE:
+ return AUDIO_SOURCE_ECHO_REFERENCE;
+ case AudioSource::FM_TUNER:
+ return AUDIO_SOURCE_FM_TUNER;
+ case AudioSource::HOTWORD:
+ return AUDIO_SOURCE_HOTWORD;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<AudioSource> legacy2aidl_audio_source_t_AudioSource(
+ audio_source_t legacy) {
+ switch (legacy) {
+ case AUDIO_SOURCE_INVALID:
+ return AudioSource::SYS_RESERVED_INVALID;
+ case AUDIO_SOURCE_DEFAULT:
+ return AudioSource::DEFAULT;
+ case AUDIO_SOURCE_MIC:
+ return AudioSource::MIC;
+ case AUDIO_SOURCE_VOICE_UPLINK:
+ return AudioSource::VOICE_UPLINK;
+ case AUDIO_SOURCE_VOICE_DOWNLINK:
+ return AudioSource::VOICE_DOWNLINK;
+ case AUDIO_SOURCE_VOICE_CALL:
+ return AudioSource::VOICE_CALL;
+ case AUDIO_SOURCE_CAMCORDER:
+ return AudioSource::CAMCORDER;
+ case AUDIO_SOURCE_VOICE_RECOGNITION:
+ return AudioSource::VOICE_RECOGNITION;
+ case AUDIO_SOURCE_VOICE_COMMUNICATION:
+ return AudioSource::VOICE_COMMUNICATION;
+ case AUDIO_SOURCE_REMOTE_SUBMIX:
+ return AudioSource::REMOTE_SUBMIX;
+ case AUDIO_SOURCE_UNPROCESSED:
+ return AudioSource::UNPROCESSED;
+ case AUDIO_SOURCE_VOICE_PERFORMANCE:
+ return AudioSource::VOICE_PERFORMANCE;
+ case AUDIO_SOURCE_ULTRASOUND:
+ return AudioSource::ULTRASOUND;
+ case AUDIO_SOURCE_ECHO_REFERENCE:
+ return AudioSource::ECHO_REFERENCE;
+ case AUDIO_SOURCE_FM_TUNER:
+ return AudioSource::FM_TUNER;
+ case AUDIO_SOURCE_HOTWORD:
+ return AudioSource::HOTWORD;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<audio_session_t> aidl2legacy_int32_t_audio_session_t(int32_t aidl) {
+ return convertReinterpret<audio_session_t>(aidl);
+}
+
+ConversionResult<int32_t> legacy2aidl_audio_session_t_int32_t(audio_session_t legacy) {
+ return convertReinterpret<int32_t>(legacy);
+}
+
+ConversionResult<audio_content_type_t>
+aidl2legacy_AudioContentType_audio_content_type_t(AudioContentType aidl) {
+ switch (aidl) {
+ case AudioContentType::UNKNOWN:
+ return AUDIO_CONTENT_TYPE_UNKNOWN;
+ case AudioContentType::SPEECH:
+ return AUDIO_CONTENT_TYPE_SPEECH;
+ case AudioContentType::MUSIC:
+ return AUDIO_CONTENT_TYPE_MUSIC;
+ case AudioContentType::MOVIE:
+ return AUDIO_CONTENT_TYPE_MOVIE;
+ case AudioContentType::SONIFICATION:
+ return AUDIO_CONTENT_TYPE_SONIFICATION;
+ case AudioContentType::ULTRASOUND:
+ return AUDIO_CONTENT_TYPE_ULTRASOUND;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<AudioContentType>
+legacy2aidl_audio_content_type_t_AudioContentType(audio_content_type_t legacy) {
+ switch (legacy) {
+ case AUDIO_CONTENT_TYPE_UNKNOWN:
+ return AudioContentType::UNKNOWN;
+ case AUDIO_CONTENT_TYPE_SPEECH:
+ return AudioContentType::SPEECH;
+ case AUDIO_CONTENT_TYPE_MUSIC:
+ return AudioContentType::MUSIC;
+ case AUDIO_CONTENT_TYPE_MOVIE:
+ return AudioContentType::MOVIE;
+ case AUDIO_CONTENT_TYPE_SONIFICATION:
+ return AudioContentType::SONIFICATION;
+ case AUDIO_CONTENT_TYPE_ULTRASOUND:
+ return AudioContentType::ULTRASOUND;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<audio_usage_t>
+aidl2legacy_AudioUsage_audio_usage_t(AudioUsage aidl) {
+ switch (aidl) {
+ case AudioUsage::INVALID:
+ break; // return error
+ case AudioUsage::UNKNOWN:
+ return AUDIO_USAGE_UNKNOWN;
+ case AudioUsage::MEDIA:
+ return AUDIO_USAGE_MEDIA;
+ case AudioUsage::VOICE_COMMUNICATION:
+ return AUDIO_USAGE_VOICE_COMMUNICATION;
+ case AudioUsage::VOICE_COMMUNICATION_SIGNALLING:
+ return AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING;
+ case AudioUsage::ALARM:
+ return AUDIO_USAGE_ALARM;
+ case AudioUsage::NOTIFICATION:
+ return AUDIO_USAGE_NOTIFICATION;
+ case AudioUsage::NOTIFICATION_TELEPHONY_RINGTONE:
+ return AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE;
+ case AudioUsage::SYS_RESERVED_NOTIFICATION_COMMUNICATION_REQUEST:
+ return AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST;
+ case AudioUsage::SYS_RESERVED_NOTIFICATION_COMMUNICATION_INSTANT:
+ return AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT;
+ case AudioUsage::SYS_RESERVED_NOTIFICATION_COMMUNICATION_DELAYED:
+ return AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED;
+ case AudioUsage::NOTIFICATION_EVENT:
+ return AUDIO_USAGE_NOTIFICATION_EVENT;
+ case AudioUsage::ASSISTANCE_ACCESSIBILITY:
+ return AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY;
+ case AudioUsage::ASSISTANCE_NAVIGATION_GUIDANCE:
+ return AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE;
+ case AudioUsage::ASSISTANCE_SONIFICATION:
+ return AUDIO_USAGE_ASSISTANCE_SONIFICATION;
+ case AudioUsage::GAME:
+ return AUDIO_USAGE_GAME;
+ case AudioUsage::VIRTUAL_SOURCE:
+ return AUDIO_USAGE_VIRTUAL_SOURCE;
+ case AudioUsage::ASSISTANT:
+ return AUDIO_USAGE_ASSISTANT;
+ case AudioUsage::CALL_ASSISTANT:
+ return AUDIO_USAGE_CALL_ASSISTANT;
+ case AudioUsage::EMERGENCY:
+ return AUDIO_USAGE_EMERGENCY;
+ case AudioUsage::SAFETY:
+ return AUDIO_USAGE_SAFETY;
+ case AudioUsage::VEHICLE_STATUS:
+ return AUDIO_USAGE_VEHICLE_STATUS;
+ case AudioUsage::ANNOUNCEMENT:
+ return AUDIO_USAGE_ANNOUNCEMENT;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<AudioUsage>
+legacy2aidl_audio_usage_t_AudioUsage(audio_usage_t legacy) {
+ switch (legacy) {
+ case AUDIO_USAGE_UNKNOWN:
+ return AudioUsage::UNKNOWN;
+ case AUDIO_USAGE_MEDIA:
+ return AudioUsage::MEDIA;
+ case AUDIO_USAGE_VOICE_COMMUNICATION:
+ return AudioUsage::VOICE_COMMUNICATION;
+ case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
+ return AudioUsage::VOICE_COMMUNICATION_SIGNALLING;
+ case AUDIO_USAGE_ALARM:
+ return AudioUsage::ALARM;
+ case AUDIO_USAGE_NOTIFICATION:
+ return AudioUsage::NOTIFICATION;
+ case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
+ return AudioUsage::NOTIFICATION_TELEPHONY_RINGTONE;
+ case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
+ return AudioUsage::SYS_RESERVED_NOTIFICATION_COMMUNICATION_REQUEST;
+ case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
+ return AudioUsage::SYS_RESERVED_NOTIFICATION_COMMUNICATION_INSTANT;
+ case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
+ return AudioUsage::SYS_RESERVED_NOTIFICATION_COMMUNICATION_DELAYED;
+ case AUDIO_USAGE_NOTIFICATION_EVENT:
+ return AudioUsage::NOTIFICATION_EVENT;
+ case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
+ return AudioUsage::ASSISTANCE_ACCESSIBILITY;
+ case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
+ return AudioUsage::ASSISTANCE_NAVIGATION_GUIDANCE;
+ case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
+ return AudioUsage::ASSISTANCE_SONIFICATION;
+ case AUDIO_USAGE_GAME:
+ return AudioUsage::GAME;
+ case AUDIO_USAGE_VIRTUAL_SOURCE:
+ return AudioUsage::VIRTUAL_SOURCE;
+ case AUDIO_USAGE_ASSISTANT:
+ return AudioUsage::ASSISTANT;
+ case AUDIO_USAGE_CALL_ASSISTANT:
+ return AudioUsage::CALL_ASSISTANT;
+ case AUDIO_USAGE_EMERGENCY:
+ return AudioUsage::EMERGENCY;
+ case AUDIO_USAGE_SAFETY:
+ return AudioUsage::SAFETY;
+ case AUDIO_USAGE_VEHICLE_STATUS:
+ return AudioUsage::VEHICLE_STATUS;
+ case AUDIO_USAGE_ANNOUNCEMENT:
+ return AudioUsage::ANNOUNCEMENT;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+
+ConversionResult<audio_encapsulation_mode_t>
+aidl2legacy_AudioEncapsulationMode_audio_encapsulation_mode_t(AudioEncapsulationMode aidl) {
+ switch (aidl) {
+ case AudioEncapsulationMode::INVALID:
+ break; // return error
+ case AudioEncapsulationMode::NONE:
+ return AUDIO_ENCAPSULATION_MODE_NONE;
+ case AudioEncapsulationMode::ELEMENTARY_STREAM:
+ return AUDIO_ENCAPSULATION_MODE_ELEMENTARY_STREAM;
+ case AudioEncapsulationMode::HANDLE:
+ return AUDIO_ENCAPSULATION_MODE_HANDLE;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<AudioEncapsulationMode>
+legacy2aidl_audio_encapsulation_mode_t_AudioEncapsulationMode(audio_encapsulation_mode_t legacy) {
+ switch (legacy) {
+ case AUDIO_ENCAPSULATION_MODE_NONE:
+ return AudioEncapsulationMode::NONE;
+ case AUDIO_ENCAPSULATION_MODE_ELEMENTARY_STREAM:
+ return AudioEncapsulationMode::ELEMENTARY_STREAM;
+ case AUDIO_ENCAPSULATION_MODE_HANDLE:
+ return AudioEncapsulationMode::HANDLE;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<audio_offload_info_t>
+aidl2legacy_AudioOffloadInfo_audio_offload_info_t(const AudioOffloadInfo& aidl) {
+ audio_offload_info_t legacy = AUDIO_INFO_INITIALIZER;
+ audio_config_base_t base = VALUE_OR_RETURN(
+ aidl2legacy_AudioConfigBase_audio_config_base_t(aidl.base, false /*isInput*/));
+ legacy.sample_rate = base.sample_rate;
+ legacy.channel_mask = base.channel_mask;
+ legacy.format = base.format;
+ legacy.stream_type = VALUE_OR_RETURN(
+ aidl2legacy_AudioStreamType_audio_stream_type_t(aidl.streamType));
+ legacy.bit_rate = VALUE_OR_RETURN(convertIntegral<int32_t>(aidl.bitRatePerSecond));
+ legacy.duration_us = VALUE_OR_RETURN(convertIntegral<int64_t>(aidl.durationUs));
+ legacy.has_video = aidl.hasVideo;
+ legacy.is_streaming = aidl.isStreaming;
+ legacy.bit_width = VALUE_OR_RETURN(convertIntegral<int32_t>(aidl.bitWidth));
+ legacy.offload_buffer_size = VALUE_OR_RETURN(convertIntegral<int32_t>(aidl.offloadBufferSize));
+ legacy.usage = VALUE_OR_RETURN(aidl2legacy_AudioUsage_audio_usage_t(aidl.usage));
+ legacy.encapsulation_mode = VALUE_OR_RETURN(
+ aidl2legacy_AudioEncapsulationMode_audio_encapsulation_mode_t(aidl.encapsulationMode));
+ legacy.content_id = VALUE_OR_RETURN(convertReinterpret<int32_t>(aidl.contentId));
+ legacy.sync_id = VALUE_OR_RETURN(convertReinterpret<int32_t>(aidl.syncId));
+ return legacy;
+}
+
+ConversionResult<AudioOffloadInfo>
+legacy2aidl_audio_offload_info_t_AudioOffloadInfo(const audio_offload_info_t& legacy) {
+ AudioOffloadInfo aidl;
+ // Version 0.1 fields.
+ if (legacy.size < offsetof(audio_offload_info_t, usage) + sizeof(audio_offload_info_t::usage)) {
+ return unexpected(BAD_VALUE);
+ }
+ const audio_config_base_t base = { .sample_rate = legacy.sample_rate,
+ .channel_mask = legacy.channel_mask, .format = legacy.format };
+ aidl.base = VALUE_OR_RETURN(legacy2aidl_audio_config_base_t_AudioConfigBase(
+ base, false /*isInput*/));
+ aidl.streamType = VALUE_OR_RETURN(
+ legacy2aidl_audio_stream_type_t_AudioStreamType(legacy.stream_type));
+ aidl.bitRatePerSecond = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.bit_rate));
+ aidl.durationUs = VALUE_OR_RETURN(convertIntegral<int64_t>(legacy.duration_us));
+ aidl.hasVideo = legacy.has_video;
+ aidl.isStreaming = legacy.is_streaming;
+ aidl.bitWidth = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.bit_width));
+ aidl.offloadBufferSize = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.offload_buffer_size));
+ aidl.usage = VALUE_OR_RETURN(legacy2aidl_audio_usage_t_AudioUsage(legacy.usage));
+
+ // Version 0.2 fields.
+ if (legacy.version >= AUDIO_OFFLOAD_INFO_VERSION_0_2) {
+ if (legacy.size <
+ offsetof(audio_offload_info_t, sync_id) + sizeof(audio_offload_info_t::sync_id)) {
+ return unexpected(BAD_VALUE);
+ }
+ aidl.encapsulationMode = VALUE_OR_RETURN(
+ legacy2aidl_audio_encapsulation_mode_t_AudioEncapsulationMode(
+ legacy.encapsulation_mode));
+ aidl.contentId = VALUE_OR_RETURN(convertReinterpret<int32_t>(legacy.content_id));
+ aidl.syncId = VALUE_OR_RETURN(convertReinterpret<int32_t>(legacy.sync_id));
+ }
+ return aidl;
+}
+
+ConversionResult<audio_config_t>
+aidl2legacy_AudioConfig_audio_config_t(const AudioConfig& aidl, bool isInput) {
+ const audio_config_base_t legacyBase = VALUE_OR_RETURN(
+ aidl2legacy_AudioConfigBase_audio_config_base_t(aidl.base, isInput));
+ audio_config_t legacy = AUDIO_CONFIG_INITIALIZER;
+ legacy.sample_rate = legacyBase.sample_rate;
+ legacy.channel_mask = legacyBase.channel_mask;
+ legacy.format = legacyBase.format;
+ legacy.offload_info = VALUE_OR_RETURN(
+ aidl2legacy_AudioOffloadInfo_audio_offload_info_t(aidl.offloadInfo));
+ legacy.frame_count = VALUE_OR_RETURN(convertIntegral<uint32_t>(aidl.frameCount));
+ return legacy;
+}
+
+ConversionResult<AudioConfig>
+legacy2aidl_audio_config_t_AudioConfig(const audio_config_t& legacy, bool isInput) {
+ const audio_config_base_t base = { .sample_rate = legacy.sample_rate,
+ .channel_mask = legacy.channel_mask, .format = legacy.format };
+ AudioConfig aidl;
+ aidl.base = VALUE_OR_RETURN(legacy2aidl_audio_config_base_t_AudioConfigBase(base, isInput));
+ aidl.offloadInfo = VALUE_OR_RETURN(
+ legacy2aidl_audio_offload_info_t_AudioOffloadInfo(legacy.offload_info));
+ aidl.frameCount = VALUE_OR_RETURN(convertIntegral<int64_t>(legacy.frame_count));
+ return aidl;
+}
+
+ConversionResult<audio_config_base_t>
+aidl2legacy_AudioConfigBase_audio_config_base_t(const AudioConfigBase& aidl, bool isInput) {
+ audio_config_base_t legacy;
+ legacy.sample_rate = VALUE_OR_RETURN(convertIntegral<int>(aidl.sampleRate));
+ legacy.channel_mask = VALUE_OR_RETURN(
+ aidl2legacy_AudioChannelLayout_audio_channel_mask_t(aidl.channelMask, isInput));
+ legacy.format = VALUE_OR_RETURN(aidl2legacy_AudioFormatDescription_audio_format_t(aidl.format));
+ return legacy;
+}
+
+ConversionResult<AudioConfigBase>
+legacy2aidl_audio_config_base_t_AudioConfigBase(const audio_config_base_t& legacy, bool isInput) {
+ AudioConfigBase aidl;
+ aidl.sampleRate = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.sample_rate));
+ aidl.channelMask = VALUE_OR_RETURN(
+ legacy2aidl_audio_channel_mask_t_AudioChannelLayout(legacy.channel_mask, isInput));
+ aidl.format = VALUE_OR_RETURN(legacy2aidl_audio_format_t_AudioFormatDescription(legacy.format));
+ return aidl;
+}
+
+ConversionResult<audio_uuid_t>
+aidl2legacy_AudioUuid_audio_uuid_t(const AudioUuid& aidl) {
+ audio_uuid_t legacy;
+ legacy.timeLow = VALUE_OR_RETURN(convertReinterpret<uint32_t>(aidl.timeLow));
+ legacy.timeMid = VALUE_OR_RETURN(convertIntegral<uint16_t>(aidl.timeMid));
+ legacy.timeHiAndVersion = VALUE_OR_RETURN(convertIntegral<uint16_t>(aidl.timeHiAndVersion));
+ legacy.clockSeq = VALUE_OR_RETURN(convertIntegral<uint16_t>(aidl.clockSeq));
+ if (aidl.node.size() != std::size(legacy.node)) {
+ return unexpected(BAD_VALUE);
+ }
+ std::copy(aidl.node.begin(), aidl.node.end(), legacy.node);
+ return legacy;
+}
+
+ConversionResult<AudioUuid>
+legacy2aidl_audio_uuid_t_AudioUuid(const audio_uuid_t& legacy) {
+ AudioUuid aidl;
+ aidl.timeLow = VALUE_OR_RETURN(convertReinterpret<int32_t>(legacy.timeLow));
+ aidl.timeMid = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.timeMid));
+ aidl.timeHiAndVersion = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.timeHiAndVersion));
+ aidl.clockSeq = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.clockSeq));
+ std::copy(legacy.node, legacy.node + std::size(legacy.node), std::back_inserter(aidl.node));
+ return aidl;
+}
+
+ConversionResult<audio_encapsulation_metadata_type_t>
+aidl2legacy_AudioEncapsulationMetadataType_audio_encapsulation_metadata_type_t(
+ AudioEncapsulationMetadataType aidl) {
+ switch (aidl) {
+ case AudioEncapsulationMetadataType::NONE:
+ return AUDIO_ENCAPSULATION_METADATA_TYPE_NONE;
+ case AudioEncapsulationMetadataType::FRAMEWORK_TUNER:
+ return AUDIO_ENCAPSULATION_METADATA_TYPE_FRAMEWORK_TUNER;
+ case AudioEncapsulationMetadataType::DVB_AD_DESCRIPTOR:
+ return AUDIO_ENCAPSULATION_METADATA_TYPE_DVB_AD_DESCRIPTOR;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<AudioEncapsulationMetadataType>
+legacy2aidl_audio_encapsulation_metadata_type_t_AudioEncapsulationMetadataType(
+ audio_encapsulation_metadata_type_t legacy) {
+ switch (legacy) {
+ case AUDIO_ENCAPSULATION_METADATA_TYPE_NONE:
+ return AudioEncapsulationMetadataType::NONE;
+ case AUDIO_ENCAPSULATION_METADATA_TYPE_FRAMEWORK_TUNER:
+ return AudioEncapsulationMetadataType::FRAMEWORK_TUNER;
+ case AUDIO_ENCAPSULATION_METADATA_TYPE_DVB_AD_DESCRIPTOR:
+ return AudioEncapsulationMetadataType::DVB_AD_DESCRIPTOR;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<uint32_t>
+aidl2legacy_AudioEncapsulationMode_mask(int32_t aidl) {
+ return convertBitmask<uint32_t,
+ int32_t,
+ audio_encapsulation_mode_t,
+ AudioEncapsulationMode>(
+ aidl, aidl2legacy_AudioEncapsulationMode_audio_encapsulation_mode_t,
+ indexToEnum_index<AudioEncapsulationMode>,
+ enumToMask_index<uint32_t, audio_encapsulation_mode_t>);
+}
+
+ConversionResult<int32_t>
+legacy2aidl_AudioEncapsulationMode_mask(uint32_t legacy) {
+ return convertBitmask<int32_t,
+ uint32_t,
+ AudioEncapsulationMode,
+ audio_encapsulation_mode_t>(
+ legacy, legacy2aidl_audio_encapsulation_mode_t_AudioEncapsulationMode,
+ indexToEnum_index<audio_encapsulation_mode_t>,
+ enumToMask_index<int32_t, AudioEncapsulationMode>);
+}
+
+ConversionResult<uint32_t>
+aidl2legacy_AudioEncapsulationMetadataType_mask(int32_t aidl) {
+ return convertBitmask<uint32_t,
+ int32_t,
+ audio_encapsulation_metadata_type_t,
+ AudioEncapsulationMetadataType>(
+ aidl, aidl2legacy_AudioEncapsulationMetadataType_audio_encapsulation_metadata_type_t,
+ indexToEnum_index<AudioEncapsulationMetadataType>,
+ enumToMask_index<uint32_t, audio_encapsulation_metadata_type_t>);
+}
+
+ConversionResult<int32_t>
+legacy2aidl_AudioEncapsulationMetadataType_mask(uint32_t legacy) {
+ return convertBitmask<int32_t,
+ uint32_t,
+ AudioEncapsulationMetadataType,
+ audio_encapsulation_metadata_type_t>(
+ legacy, legacy2aidl_audio_encapsulation_metadata_type_t_AudioEncapsulationMetadataType,
+ indexToEnum_index<audio_encapsulation_metadata_type_t>,
+ enumToMask_index<int32_t, AudioEncapsulationMetadataType>);
+}
+
+ConversionResult<audio_profile>
+aidl2legacy_AudioProfile_audio_profile(const AudioProfile& aidl, bool isInput) {
+ audio_profile legacy;
+ legacy.format = VALUE_OR_RETURN(aidl2legacy_AudioFormatDescription_audio_format_t(aidl.format));
+
+ if (aidl.sampleRates.size() > std::size(legacy.sample_rates)) {
+ return unexpected(BAD_VALUE);
+ }
+ RETURN_IF_ERROR(
+ convertRange(aidl.sampleRates.begin(), aidl.sampleRates.end(), legacy.sample_rates,
+ convertIntegral<int32_t, unsigned int>));
+ legacy.num_sample_rates = aidl.sampleRates.size();
+
+ if (aidl.channelMasks.size() > std::size(legacy.channel_masks)) {
+ return unexpected(BAD_VALUE);
+ }
+ RETURN_IF_ERROR(
+ convertRange(aidl.channelMasks.begin(), aidl.channelMasks.end(), legacy.channel_masks,
+ [isInput](const AudioChannelLayout& l) {
+ return aidl2legacy_AudioChannelLayout_audio_channel_mask_t(l, isInput);
+ }));
+ legacy.num_channel_masks = aidl.channelMasks.size();
+
+ legacy.encapsulation_type = VALUE_OR_RETURN(
+ aidl2legacy_AudioEncapsulationType_audio_encapsulation_type_t(aidl.encapsulationType));
+ return legacy;
+}
+
+ConversionResult<AudioProfile>
+legacy2aidl_audio_profile_AudioProfile(const audio_profile& legacy, bool isInput) {
+ AudioProfile aidl;
+ aidl.format = VALUE_OR_RETURN(legacy2aidl_audio_format_t_AudioFormatDescription(legacy.format));
+
+ if (legacy.num_sample_rates > std::size(legacy.sample_rates)) {
+ return unexpected(BAD_VALUE);
+ }
+ RETURN_IF_ERROR(
+ convertRange(legacy.sample_rates, legacy.sample_rates + legacy.num_sample_rates,
+ std::back_inserter(aidl.sampleRates),
+ convertIntegral<unsigned int, int32_t>));
+
+ if (legacy.num_channel_masks > std::size(legacy.channel_masks)) {
+ return unexpected(BAD_VALUE);
+ }
+ RETURN_IF_ERROR(
+ convertRange(legacy.channel_masks, legacy.channel_masks + legacy.num_channel_masks,
+ std::back_inserter(aidl.channelMasks),
+ [isInput](audio_channel_mask_t m) {
+ return legacy2aidl_audio_channel_mask_t_AudioChannelLayout(m, isInput);
+ }));
+
+ aidl.encapsulationType = VALUE_OR_RETURN(
+ legacy2aidl_audio_encapsulation_type_t_AudioEncapsulationType(
+ legacy.encapsulation_type));
+ return aidl;
+}
+
+ConversionResult<audio_gain>
+aidl2legacy_AudioGain_audio_gain(const AudioGain& aidl, bool isInput) {
+ audio_gain legacy;
+ legacy.mode = VALUE_OR_RETURN(aidl2legacy_int32_t_audio_gain_mode_t_mask(aidl.mode));
+ legacy.channel_mask = VALUE_OR_RETURN(aidl2legacy_AudioChannelLayout_audio_channel_mask_t(
+ aidl.channelMask, isInput));
+ legacy.min_value = VALUE_OR_RETURN(convertIntegral<int>(aidl.minValue));
+ legacy.max_value = VALUE_OR_RETURN(convertIntegral<int>(aidl.maxValue));
+ legacy.default_value = VALUE_OR_RETURN(convertIntegral<int>(aidl.defaultValue));
+ legacy.step_value = VALUE_OR_RETURN(convertIntegral<unsigned int>(aidl.stepValue));
+ legacy.min_ramp_ms = VALUE_OR_RETURN(convertIntegral<unsigned int>(aidl.minRampMs));
+ legacy.max_ramp_ms = VALUE_OR_RETURN(convertIntegral<unsigned int>(aidl.maxRampMs));
+ return legacy;
+}
+
+ConversionResult<AudioGain>
+legacy2aidl_audio_gain_AudioGain(const audio_gain& legacy, bool isInput) {
+ AudioGain aidl;
+ aidl.mode = VALUE_OR_RETURN(legacy2aidl_audio_gain_mode_t_int32_t_mask(legacy.mode));
+ aidl.channelMask = VALUE_OR_RETURN(
+ legacy2aidl_audio_channel_mask_t_AudioChannelLayout(legacy.channel_mask, isInput));
+ aidl.minValue = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.min_value));
+ aidl.maxValue = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.max_value));
+ aidl.defaultValue = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.default_value));
+ aidl.stepValue = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.step_value));
+ aidl.minRampMs = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.min_ramp_ms));
+ aidl.maxRampMs = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.max_ramp_ms));
+ return aidl;
+}
+
+ConversionResult<audio_mode_t>
+aidl2legacy_AudioMode_audio_mode_t(AudioMode aidl) {
+ switch (aidl) {
+ case AudioMode::SYS_RESERVED_INVALID:
+ return AUDIO_MODE_INVALID;
+ case AudioMode::SYS_RESERVED_CURRENT:
+ return AUDIO_MODE_CURRENT;
+ case AudioMode::NORMAL:
+ return AUDIO_MODE_NORMAL;
+ case AudioMode::RINGTONE:
+ return AUDIO_MODE_RINGTONE;
+ case AudioMode::IN_CALL:
+ return AUDIO_MODE_IN_CALL;
+ case AudioMode::IN_COMMUNICATION:
+ return AUDIO_MODE_IN_COMMUNICATION;
+ case AudioMode::CALL_SCREEN:
+ return AUDIO_MODE_CALL_SCREEN;
+ case AudioMode::SYS_RESERVED_CALL_REDIRECT:
+ return AUDIO_MODE_CALL_REDIRECT;
+ case AudioMode::SYS_RESERVED_COMMUNICATION_REDIRECT:
+ return AUDIO_MODE_COMMUNICATION_REDIRECT;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<AudioMode>
+legacy2aidl_audio_mode_t_AudioMode(audio_mode_t legacy) {
+ switch (legacy) {
+ case AUDIO_MODE_INVALID:
+ return AudioMode::SYS_RESERVED_INVALID;
+ case AUDIO_MODE_CURRENT:
+ return AudioMode::SYS_RESERVED_CURRENT;
+ case AUDIO_MODE_NORMAL:
+ return AudioMode::NORMAL;
+ case AUDIO_MODE_RINGTONE:
+ return AudioMode::RINGTONE;
+ case AUDIO_MODE_IN_CALL:
+ return AudioMode::IN_CALL;
+ case AUDIO_MODE_IN_COMMUNICATION:
+ return AudioMode::IN_COMMUNICATION;
+ case AUDIO_MODE_CALL_SCREEN:
+ return AudioMode::CALL_SCREEN;
+ case AUDIO_MODE_CALL_REDIRECT:
+ return AudioMode::SYS_RESERVED_CALL_REDIRECT;
+ case AUDIO_MODE_COMMUNICATION_REDIRECT:
+ return AudioMode::SYS_RESERVED_COMMUNICATION_REDIRECT;
+ case AUDIO_MODE_CNT:
+ break;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<audio_standard_t>
+aidl2legacy_AudioStandard_audio_standard_t(AudioStandard aidl) {
+ switch (aidl) {
+ case AudioStandard::NONE:
+ return AUDIO_STANDARD_NONE;
+ case AudioStandard::EDID:
+ return AUDIO_STANDARD_EDID;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<AudioStandard>
+legacy2aidl_audio_standard_t_AudioStandard(audio_standard_t legacy) {
+ switch (legacy) {
+ case AUDIO_STANDARD_NONE:
+ return AudioStandard::NONE;
+ case AUDIO_STANDARD_EDID:
+ return AudioStandard::EDID;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<audio_extra_audio_descriptor>
+aidl2legacy_ExtraAudioDescriptor_audio_extra_audio_descriptor(
+ const ExtraAudioDescriptor& aidl) {
+ audio_extra_audio_descriptor legacy;
+ legacy.standard = VALUE_OR_RETURN(aidl2legacy_AudioStandard_audio_standard_t(aidl.standard));
+ if (aidl.audioDescriptor.size() > EXTRA_AUDIO_DESCRIPTOR_SIZE) {
+ return unexpected(BAD_VALUE);
+ }
+ legacy.descriptor_length = aidl.audioDescriptor.size();
+ std::copy(aidl.audioDescriptor.begin(), aidl.audioDescriptor.end(),
+ std::begin(legacy.descriptor));
+ legacy.encapsulation_type =
+ VALUE_OR_RETURN(aidl2legacy_AudioEncapsulationType_audio_encapsulation_type_t(
+ aidl.encapsulationType));
+ return legacy;
+}
+
+ConversionResult<ExtraAudioDescriptor>
+legacy2aidl_audio_extra_audio_descriptor_ExtraAudioDescriptor(
+ const audio_extra_audio_descriptor& legacy) {
+ ExtraAudioDescriptor aidl;
+ aidl.standard = VALUE_OR_RETURN(legacy2aidl_audio_standard_t_AudioStandard(legacy.standard));
+ if (legacy.descriptor_length > EXTRA_AUDIO_DESCRIPTOR_SIZE) {
+ return unexpected(BAD_VALUE);
+ }
+ aidl.audioDescriptor.resize(legacy.descriptor_length);
+ std::copy(legacy.descriptor, legacy.descriptor + legacy.descriptor_length,
+ aidl.audioDescriptor.begin());
+ aidl.encapsulationType =
+ VALUE_OR_RETURN(legacy2aidl_audio_encapsulation_type_t_AudioEncapsulationType(
+ legacy.encapsulation_type));
+ return aidl;
+}
+
+ConversionResult<audio_encapsulation_type_t>
+aidl2legacy_AudioEncapsulationType_audio_encapsulation_type_t(
+ const AudioEncapsulationType& aidl) {
+ switch (aidl) {
+ case AudioEncapsulationType::NONE:
+ return AUDIO_ENCAPSULATION_TYPE_NONE;
+ case AudioEncapsulationType::IEC61937:
+ return AUDIO_ENCAPSULATION_TYPE_IEC61937;
+ case AudioEncapsulationType::PCM:
+ return AUDIO_ENCAPSULATION_TYPE_PCM;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<AudioEncapsulationType>
+legacy2aidl_audio_encapsulation_type_t_AudioEncapsulationType(
+ const audio_encapsulation_type_t & legacy) {
+ switch (legacy) {
+ case AUDIO_ENCAPSULATION_TYPE_NONE:
+ return AudioEncapsulationType::NONE;
+ case AUDIO_ENCAPSULATION_TYPE_IEC61937:
+ return AudioEncapsulationType::IEC61937;
+ case AUDIO_ENCAPSULATION_TYPE_PCM:
+ return AudioEncapsulationType::PCM;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<audio_dual_mono_mode_t>
+aidl2legacy_AudioDualMonoMode_audio_dual_mono_mode_t(AudioDualMonoMode aidl) {
+ switch (aidl) {
+ case AudioDualMonoMode::OFF:
+ return AUDIO_DUAL_MONO_MODE_OFF;
+ case AudioDualMonoMode::LR:
+ return AUDIO_DUAL_MONO_MODE_LR;
+ case AudioDualMonoMode::LL:
+ return AUDIO_DUAL_MONO_MODE_LL;
+ case AudioDualMonoMode::RR:
+ return AUDIO_DUAL_MONO_MODE_RR;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<AudioDualMonoMode>
+legacy2aidl_audio_dual_mono_mode_t_AudioDualMonoMode(audio_dual_mono_mode_t legacy) {
+ switch (legacy) {
+ case AUDIO_DUAL_MONO_MODE_OFF:
+ return AudioDualMonoMode::OFF;
+ case AUDIO_DUAL_MONO_MODE_LR:
+ return AudioDualMonoMode::LR;
+ case AUDIO_DUAL_MONO_MODE_LL:
+ return AudioDualMonoMode::LL;
+ case AUDIO_DUAL_MONO_MODE_RR:
+ return AudioDualMonoMode::RR;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<audio_timestretch_fallback_mode_t>
+aidl2legacy_TimestretchFallbackMode_audio_timestretch_fallback_mode_t(
+ AudioPlaybackRate::TimestretchFallbackMode aidl) {
+ switch (aidl) {
+ case AudioPlaybackRate::TimestretchFallbackMode::SYS_RESERVED_CUT_REPEAT:
+ return AUDIO_TIMESTRETCH_FALLBACK_CUT_REPEAT;
+ case AudioPlaybackRate::TimestretchFallbackMode::SYS_RESERVED_DEFAULT:
+ return AUDIO_TIMESTRETCH_FALLBACK_DEFAULT;
+ case AudioPlaybackRate::TimestretchFallbackMode::MUTE:
+ return AUDIO_TIMESTRETCH_FALLBACK_MUTE;
+ case AudioPlaybackRate::TimestretchFallbackMode::FAIL:
+ return AUDIO_TIMESTRETCH_FALLBACK_FAIL;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<AudioPlaybackRate::TimestretchFallbackMode>
+legacy2aidl_audio_timestretch_fallback_mode_t_TimestretchFallbackMode(
+ audio_timestretch_fallback_mode_t legacy) {
+ switch (legacy) {
+ case AUDIO_TIMESTRETCH_FALLBACK_CUT_REPEAT:
+ return AudioPlaybackRate::TimestretchFallbackMode::SYS_RESERVED_CUT_REPEAT;
+ case AUDIO_TIMESTRETCH_FALLBACK_DEFAULT:
+ return AudioPlaybackRate::TimestretchFallbackMode::SYS_RESERVED_DEFAULT;
+ case AUDIO_TIMESTRETCH_FALLBACK_MUTE:
+ return AudioPlaybackRate::TimestretchFallbackMode::MUTE;
+ case AUDIO_TIMESTRETCH_FALLBACK_FAIL:
+ return AudioPlaybackRate::TimestretchFallbackMode::FAIL;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<audio_timestretch_stretch_mode_t>
+aidl2legacy_TimestretchMode_audio_timestretch_stretch_mode_t(
+ AudioPlaybackRate::TimestretchMode aidl) {
+ switch (aidl) {
+ case AudioPlaybackRate::TimestretchMode::DEFAULT:
+ return AUDIO_TIMESTRETCH_STRETCH_DEFAULT;
+ case AudioPlaybackRate::TimestretchMode::VOICE:
+ return AUDIO_TIMESTRETCH_STRETCH_VOICE;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<AudioPlaybackRate::TimestretchMode>
+legacy2aidl_audio_timestretch_stretch_mode_t_TimestretchMode(
+ audio_timestretch_stretch_mode_t legacy) {
+ switch (legacy) {
+ case AUDIO_TIMESTRETCH_STRETCH_DEFAULT:
+ return AudioPlaybackRate::TimestretchMode::DEFAULT;
+ case AUDIO_TIMESTRETCH_STRETCH_VOICE:
+ return AudioPlaybackRate::TimestretchMode::VOICE;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<audio_playback_rate_t>
+aidl2legacy_AudioPlaybackRate_audio_playback_rate_t(const AudioPlaybackRate& aidl) {
+ audio_playback_rate_t legacy;
+ legacy.mSpeed = aidl.speed;
+ legacy.mPitch = aidl.pitch;
+ legacy.mFallbackMode = VALUE_OR_RETURN(
+ aidl2legacy_TimestretchFallbackMode_audio_timestretch_fallback_mode_t(
+ aidl.fallbackMode));
+ legacy.mStretchMode = VALUE_OR_RETURN(
+ aidl2legacy_TimestretchMode_audio_timestretch_stretch_mode_t(aidl.timestretchMode));
+ return legacy;
+}
+
+ConversionResult<AudioPlaybackRate>
+legacy2aidl_audio_playback_rate_t_AudioPlaybackRate(const audio_playback_rate_t& legacy) {
+ AudioPlaybackRate aidl;
+ aidl.speed = legacy.mSpeed;
+ aidl.pitch = legacy.mPitch;
+ aidl.fallbackMode = VALUE_OR_RETURN(
+ legacy2aidl_audio_timestretch_fallback_mode_t_TimestretchFallbackMode(
+ legacy.mFallbackMode));
+ aidl.timestretchMode = VALUE_OR_RETURN(
+ legacy2aidl_audio_timestretch_stretch_mode_t_TimestretchMode(legacy.mStretchMode));
+ return aidl;
+}
+
+ConversionResult<audio_latency_mode_t>
+aidl2legacy_AudioLatencyMode_audio_latency_mode_t(AudioLatencyMode aidl) {
+ switch (aidl) {
+ case AudioLatencyMode::FREE:
+ return AUDIO_LATENCY_MODE_FREE;
+ case AudioLatencyMode::LOW:
+ return AUDIO_LATENCY_MODE_LOW;
+ }
+ return unexpected(BAD_VALUE);
+}
+ConversionResult<AudioLatencyMode>
+legacy2aidl_audio_latency_mode_t_AudioLatencyMode(audio_latency_mode_t legacy) {
+ switch (legacy) {
+ case AUDIO_LATENCY_MODE_FREE:
+ return AudioLatencyMode::FREE;
+ case AUDIO_LATENCY_MODE_LOW:
+ return AudioLatencyMode::LOW;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+} // namespace android
+
+#if defined(BACKEND_NDK)
+} // aidl
+#endif
\ No newline at end of file
diff --git a/media/audioaidlconversion/AidlConversionNdk.cpp b/media/audioaidlconversion/AidlConversionNdk.cpp
new file mode 100644
index 0000000..9981435
--- /dev/null
+++ b/media/audioaidlconversion/AidlConversionNdk.cpp
@@ -0,0 +1,300 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <utility>
+
+#define LOG_TAG "AidlConversionNdk"
+//#define LOG_NDEBUG 0
+#include <utils/Log.h>
+
+#include <media/AidlConversionCppNdk.h>
+#include <media/AidlConversionNdk.h>
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// AIDL NDK backend to legacy audio data structure conversion utilities.
+
+namespace aidl {
+namespace android {
+
+using ::aidl::android::hardware::audio::effect::AcousticEchoCanceler;
+using ::aidl::android::hardware::audio::effect::Descriptor;
+using ::aidl::android::hardware::audio::effect::Flags;
+using ::aidl::android::hardware::audio::effect::Parameter;
+using ::aidl::android::media::audio::common::AudioDeviceDescription;
+
+using ::android::BAD_VALUE;
+using ::android::base::unexpected;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Utils
+
+ConversionResult<AcousticEchoCanceler> getParameterSpecificAec(const Parameter& aidl) {
+ const auto& specific = VALUE_OR_RETURN(UNION_GET(aidl, specific));
+ return VALUE_OR_RETURN(UNION_GET(specific, acousticEchoCanceler));
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Converters
+
+ConversionResult<uint32_t> aidl2legacy_Flags_Type_uint32(Flags::Type type) {
+ switch (type) {
+ case Flags::Type::INSERT:
+ return EFFECT_FLAG_TYPE_INSERT;
+ case Flags::Type::AUXILIARY:
+ return EFFECT_FLAG_TYPE_AUXILIARY;
+ case Flags::Type::REPLACE:
+ return EFFECT_FLAG_TYPE_REPLACE;
+ case Flags::Type::PRE_PROC:
+ return EFFECT_FLAG_TYPE_PRE_PROC;
+ case Flags::Type::POST_PROC:
+ return EFFECT_FLAG_TYPE_POST_PROC;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<uint32_t> aidl2legacy_Flags_Insert_uint32(Flags::Insert insert) {
+ switch (insert) {
+ case Flags::Insert::ANY:
+ return EFFECT_FLAG_INSERT_ANY;
+ case Flags::Insert::FIRST:
+ return EFFECT_FLAG_INSERT_FIRST;
+ case Flags::Insert::LAST:
+ return EFFECT_FLAG_INSERT_LAST;
+ case Flags::Insert::EXCLUSIVE:
+ return EFFECT_FLAG_INSERT_EXCLUSIVE;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<uint32_t> aidl2legacy_Flags_Volume_uint32(Flags::Volume volume) {
+ switch (volume) {
+ case Flags::Volume::NONE:
+ return 0;
+ case Flags::Volume::CTRL:
+ return EFFECT_FLAG_VOLUME_CTRL;
+ case Flags::Volume::IND:
+ return EFFECT_FLAG_VOLUME_IND;
+ case Flags::Volume::MONITOR:
+ return EFFECT_FLAG_VOLUME_MONITOR;
+ }
+ return unexpected(BAD_VALUE);
+}
+ConversionResult<uint32_t> aidl2legacy_Flags_HardwareAccelerator_uint32(
+ Flags::HardwareAccelerator hwAcceleratorMode) {
+ switch (hwAcceleratorMode) {
+ case Flags::HardwareAccelerator::NONE:
+ return 0;
+ case Flags::HardwareAccelerator::SIMPLE:
+ return EFFECT_FLAG_HW_ACC_SIMPLE;
+ case Flags::HardwareAccelerator::TUNNEL:
+ return EFFECT_FLAG_HW_ACC_TUNNEL;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<uint32_t> aidl2legacy_Flags_uint32(Flags aidl) {
+ uint32_t legacy = 0;
+ legacy |= VALUE_OR_RETURN(aidl2legacy_Flags_Type_uint32(aidl.type));
+ legacy |= VALUE_OR_RETURN(aidl2legacy_Flags_Insert_uint32(aidl.insert));
+ legacy |= VALUE_OR_RETURN(aidl2legacy_Flags_Volume_uint32(aidl.volume));
+ legacy |= VALUE_OR_RETURN(aidl2legacy_Flags_HardwareAccelerator_uint32(aidl.hwAcceleratorMode));
+
+ if (aidl.offloadIndication) {
+ legacy |= EFFECT_FLAG_OFFLOAD_SUPPORTED;
+ }
+ if (aidl.deviceIndication) {
+ legacy |= EFFECT_FLAG_DEVICE_IND;
+ }
+ if (aidl.audioModeIndication) {
+ legacy |= EFFECT_FLAG_AUDIO_MODE_IND;
+ }
+ if (aidl.audioSourceIndication) {
+ legacy |= EFFECT_FLAG_AUDIO_SOURCE_IND;
+ }
+ if (aidl.noProcessing) {
+ legacy |= EFFECT_FLAG_NO_PROCESS;
+ }
+ return legacy;
+}
+
+ConversionResult<Flags::Type> legacy2aidl_uint32_Flags_Type(uint32_t legacy) {
+ switch (legacy & EFFECT_FLAG_TYPE_MASK) {
+ case EFFECT_FLAG_TYPE_INSERT:
+ return Flags::Type::INSERT;
+ case EFFECT_FLAG_TYPE_AUXILIARY:
+ return Flags::Type::AUXILIARY;
+ case EFFECT_FLAG_TYPE_REPLACE:
+ return Flags::Type::REPLACE;
+ case EFFECT_FLAG_TYPE_PRE_PROC:
+ return Flags::Type::PRE_PROC;
+ case EFFECT_FLAG_TYPE_POST_PROC:
+ return Flags::Type::POST_PROC;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<Flags::Insert> legacy2aidl_uint32_Flags_Insert(uint32_t legacy) {
+ switch (legacy & EFFECT_FLAG_INSERT_MASK) {
+ case EFFECT_FLAG_INSERT_ANY:
+ return Flags::Insert::ANY;
+ case EFFECT_FLAG_INSERT_FIRST:
+ return Flags::Insert::FIRST;
+ case EFFECT_FLAG_INSERT_LAST:
+ return Flags::Insert::LAST;
+ case EFFECT_FLAG_INSERT_EXCLUSIVE:
+ return Flags::Insert::EXCLUSIVE;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<Flags::Volume> legacy2aidl_uint32_Flags_Volume(uint32_t legacy) {
+ switch (legacy & EFFECT_FLAG_VOLUME_MASK) {
+ case EFFECT_FLAG_VOLUME_IND:
+ return Flags::Volume::IND;
+ case EFFECT_FLAG_VOLUME_MONITOR:
+ return Flags::Volume::MONITOR;
+ case EFFECT_FLAG_VOLUME_NONE:
+ return Flags::Volume::NONE;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<Flags::HardwareAccelerator> legacy2aidl_uint32_Flags_HardwareAccelerator(
+ uint32_t legacy) {
+ switch (legacy & EFFECT_FLAG_HW_ACC_MASK) {
+ case EFFECT_FLAG_HW_ACC_SIMPLE:
+ return Flags::HardwareAccelerator::SIMPLE;
+ case EFFECT_FLAG_HW_ACC_TUNNEL:
+ return Flags::HardwareAccelerator::TUNNEL;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<Flags> legacy2aidl_uint32_Flags(uint32_t legacy) {
+ Flags aidl;
+
+ aidl.type = VALUE_OR_RETURN(legacy2aidl_uint32_Flags_Type(legacy));
+ aidl.insert = VALUE_OR_RETURN(legacy2aidl_uint32_Flags_Insert(legacy));
+ aidl.volume = VALUE_OR_RETURN(legacy2aidl_uint32_Flags_Volume(legacy));
+ aidl.hwAcceleratorMode = VALUE_OR_RETURN(legacy2aidl_uint32_Flags_HardwareAccelerator(legacy));
+ aidl.offloadIndication = (legacy & EFFECT_FLAG_OFFLOAD_SUPPORTED);
+ aidl.deviceIndication = (legacy & EFFECT_FLAG_DEVICE_IND);
+ aidl.audioModeIndication = (legacy & EFFECT_FLAG_AUDIO_MODE_IND);
+ aidl.audioSourceIndication = (legacy & EFFECT_FLAG_AUDIO_SOURCE_IND);
+ aidl.noProcessing = (legacy & EFFECT_FLAG_NO_PROCESS);
+ return aidl;
+}
+
+ConversionResult<effect_descriptor_t>
+aidl2legacy_Descriptor_effect_descriptor(const Descriptor& aidl) {
+ effect_descriptor_t legacy;
+ legacy.type = VALUE_OR_RETURN(aidl2legacy_AudioUuid_audio_uuid_t(aidl.common.id.type));
+ legacy.uuid = VALUE_OR_RETURN(aidl2legacy_AudioUuid_audio_uuid_t(aidl.common.id.uuid));
+ // legacy descriptor doesn't have proxy information
+ // proxy = VALUE_OR_RETURN(aidl2legacy_AudioUuid_audio_uuid_t(aidl.proxy));
+ legacy.apiVersion = EFFECT_CONTROL_API_VERSION;
+ legacy.flags = VALUE_OR_RETURN(aidl2legacy_Flags_uint32(aidl.common.flags));
+ legacy.cpuLoad = VALUE_OR_RETURN(convertIntegral<uint16_t>(aidl.common.cpuLoad));
+ legacy.memoryUsage = VALUE_OR_RETURN(convertIntegral<uint16_t>(aidl.common.memoryUsage));
+ RETURN_IF_ERROR(aidl2legacy_string(aidl.common.name, legacy.name, sizeof(legacy.name)));
+ RETURN_IF_ERROR(aidl2legacy_string(aidl.common.implementor, legacy.implementor,
+ sizeof(legacy.implementor)));
+ return legacy;
+}
+
+ConversionResult<Descriptor>
+legacy2aidl_effect_descriptor_Descriptor(const effect_descriptor_t& legacy) {
+ Descriptor aidl;
+ aidl.common.id.type = VALUE_OR_RETURN(legacy2aidl_audio_uuid_t_AudioUuid(legacy.type));
+ aidl.common.id.uuid = VALUE_OR_RETURN(legacy2aidl_audio_uuid_t_AudioUuid(legacy.uuid));
+ // legacy descriptor doesn't have proxy information
+ // aidl.common.id.proxy
+ aidl.common.flags = VALUE_OR_RETURN(legacy2aidl_uint32_Flags(legacy.flags));
+ aidl.common.cpuLoad = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.cpuLoad));
+ aidl.common.memoryUsage = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.memoryUsage));
+ aidl.common.name = VALUE_OR_RETURN(legacy2aidl_string(legacy.name, sizeof(legacy.name)));
+ aidl.common.implementor =
+ VALUE_OR_RETURN(legacy2aidl_string(legacy.implementor, sizeof(legacy.implementor)));
+ return aidl;
+}
+
+ConversionResult<buffer_config_t> aidl2legacy_AudioConfigBase_buffer_config_t(
+ const media::audio::common::AudioConfigBase& aidl, bool isInput) {
+ buffer_config_t legacy;
+
+ legacy.samplingRate = VALUE_OR_RETURN(convertIntegral<uint32_t>(aidl.sampleRate));
+ legacy.mask |= EFFECT_CONFIG_SMP_RATE;
+
+ legacy.channels = VALUE_OR_RETURN(
+ aidl2legacy_AudioChannelLayout_audio_channel_mask_t(aidl.channelMask, isInput));
+ legacy.mask |= EFFECT_CONFIG_CHANNELS;
+
+ legacy.format = VALUE_OR_RETURN(aidl2legacy_AudioFormatDescription_audio_format_t(aidl.format));
+ legacy.mask |= EFFECT_CONFIG_FORMAT;
+
+ return legacy;
+}
+
+ConversionResult<media::audio::common::AudioConfigBase>
+legacy2aidl_buffer_config_t_AudioConfigBase(const buffer_config_t& legacy, bool isInput) {
+ media::audio::common::AudioConfigBase aidl;
+
+ if (legacy.mask & EFFECT_CONFIG_SMP_RATE) {
+ aidl.sampleRate = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.samplingRate));
+ }
+ if (legacy.mask & EFFECT_CONFIG_CHANNELS) {
+ aidl.channelMask = VALUE_OR_RETURN(legacy2aidl_audio_channel_mask_t_AudioChannelLayout(
+ static_cast<audio_channel_mask_t>(legacy.channels), isInput));
+ }
+ if (legacy.mask & EFFECT_CONFIG_FORMAT) {
+ aidl.format = VALUE_OR_RETURN(legacy2aidl_audio_format_t_AudioFormatDescription(
+ static_cast<audio_format_t>(legacy.format)));
+ }
+ return aidl;
+}
+
+ConversionResult<uint32_t> aidl2legacy_Parameter_uint32_echoDelay(const Parameter& aidl) {
+ const auto& aec = VALUE_OR_RETURN(getParameterSpecificAec(aidl));
+ const auto& echoDelay = VALUE_OR_RETURN(UNION_GET(aec, echoDelayUs));
+ return VALUE_OR_RETURN(convertIntegral<uint32_t>(echoDelay));
+}
+
+ConversionResult<Parameter> legacy2aidl_uint32_echoDelay_Parameter(const uint32_t& legacy) {
+ int delay = VALUE_OR_RETURN(convertReinterpret<int32_t>(legacy));
+ AcousticEchoCanceler aec = AcousticEchoCanceler::make<AcousticEchoCanceler::echoDelayUs>(delay);
+ Parameter::Specific specific =
+ Parameter::Specific::make<Parameter::Specific::acousticEchoCanceler>(aec);
+
+ return Parameter::make<Parameter::specific>(specific);
+}
+
+ConversionResult<uint32_t> aidl2legacy_Parameter_uint32_mobileMode(const Parameter& aidl) {
+ const auto& aec = VALUE_OR_RETURN(getParameterSpecificAec(aidl));
+ const auto& mobileMode = VALUE_OR_RETURN(UNION_GET(aec, mobileMode));
+ return VALUE_OR_RETURN(convertIntegral<uint32_t>(mobileMode));
+}
+
+ConversionResult<Parameter> legacy2aidl_uint32_mobileMode_Parameter(const uint32_t& legacy) {
+ bool mode = VALUE_OR_RETURN(convertIntegral<bool>(legacy));
+ AcousticEchoCanceler aec = AcousticEchoCanceler::make<AcousticEchoCanceler::mobileMode>(mode);
+ Parameter::Specific specific =
+ Parameter::Specific::make<Parameter::Specific::acousticEchoCanceler>(aec);
+
+ return Parameter::make<Parameter::specific>(specific);
+}
+
+} // namespace android
+} // aidl
diff --git a/media/audioaidlconversion/Android.bp b/media/audioaidlconversion/Android.bp
new file mode 100644
index 0000000..86f455e
--- /dev/null
+++ b/media/audioaidlconversion/Android.bp
@@ -0,0 +1,150 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_av_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_av_license"],
+}
+
+cc_defaults {
+ name: "audio_aidl_conversion_common_util_default",
+ host_supported: true,
+ vendor_available: true,
+ double_loadable: true,
+ min_sdk_version: "29",
+ export_include_dirs: [
+ "include",
+ ],
+ header_libs: [
+ "libbase_headers",
+ "liberror_headers",
+ ],
+ export_header_lib_headers: [
+ "libbase_headers",
+ "liberror_headers",
+ ],
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.btservices",
+ "com.android.media",
+ "com.android.media.swcodec",
+ ],
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
+}
+
+// This is intended for clients needing to include AidlConversionUtil.h, without extra dependencies.
+cc_library_headers {
+ name: "libaudio_aidl_conversion_common_util_cpp",
+ defaults: [
+ "audio_aidl_conversion_common_util_default",
+ ],
+}
+
+cc_library_headers {
+ name: "libaudio_aidl_conversion_common_util_ndk",
+ defaults: [
+ "audio_aidl_conversion_common_util_default",
+ ],
+ cflags: [
+ "-DBACKEND_NDK",
+ ],
+}
+
+cc_defaults {
+ name: "audio_aidl_conversion_common_default",
+ export_include_dirs: ["include"],
+ host_supported: true,
+ vendor_available: true,
+ double_loadable: true,
+ header_libs: [
+ "libaudio_system_headers",
+ "libhardware_headers",
+ ],
+ shared_libs: [
+ "libbase",
+ "libbinder",
+ "liblog",
+ "libshmemcompat",
+ "libstagefright_foundation",
+ "libutils",
+ "shared-file-region-aidl-cpp",
+ "framework-permission-aidl-cpp",
+ ],
+ export_shared_lib_headers: [
+ "libbase",
+ "shared-file-region-aidl-cpp",
+ ],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ "-Wno-error=deprecated-declarations",
+ ],
+ sanitize: {
+ misc_undefined: [
+ "unsigned-integer-overflow",
+ "signed-integer-overflow",
+ ],
+ },
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
+}
+
+/**
+ * Only AIDL CPP backend conversion supported.
+ */
+cc_library {
+ name: "libaudio_aidl_conversion_common_cpp",
+ srcs: [
+ "AidlConversionCppNdk.cpp",
+ ],
+ header_libs: [
+ "libaudio_aidl_conversion_common_util_cpp",
+ ],
+ export_header_lib_headers: [
+ "libaudio_aidl_conversion_common_util_cpp",
+ ],
+ defaults: [
+ "audio_aidl_conversion_common_default",
+ "latest_android_media_audio_common_types_cpp_export_shared",
+ ],
+ min_sdk_version: "29",
+}
+
+/**
+ * Only AIDL NDK backend conversion supported.
+ */
+cc_library {
+ name: "libaudio_aidl_conversion_common_ndk",
+ srcs: [
+ "AidlConversionCppNdk.cpp",
+ "AidlConversionNdk.cpp",
+ ],
+ header_libs: [
+ "libaudio_aidl_conversion_common_util_ndk",
+ ],
+ export_header_lib_headers: [
+ "libaudio_aidl_conversion_common_util_ndk",
+ ],
+ defaults: [
+ "audio_aidl_conversion_common_default",
+ "latest_android_hardware_audio_common_ndk_shared",
+ "latest_android_hardware_audio_effect_ndk_shared",
+ "latest_android_media_audio_common_types_ndk_shared",
+ ],
+ shared_libs: [
+ "libbinder_ndk",
+ "libbase",
+ ],
+ cflags: [
+ "-DBACKEND_NDK",
+ ],
+ min_sdk_version: "31", //AParcelableHolder has been introduced in 31
+}
diff --git a/media/audioaidlconversion/include/media/AidlConversionCppNdk.h b/media/audioaidlconversion/include/media/AidlConversionCppNdk.h
new file mode 100644
index 0000000..c25ddb1
--- /dev/null
+++ b/media/audioaidlconversion/include/media/AidlConversionCppNdk.h
@@ -0,0 +1,327 @@
+/*
+ * Copyright (C) 2022 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 <limits>
+#include <type_traits>
+#include <system/audio.h>
+
+/**
+ * Can handle conversion between AIDL (both CPP and NDK backend) and legacy type.
+ * Controlled by the cflags preprocessor in Android.bp.
+ */
+#if defined(BACKEND_NDK)
+#define PREFIX(f) <aidl/f>
+#else
+#define PREFIX(f) <f>
+#endif
+
+#include PREFIX(android/media/audio/common/AudioChannelLayout.h)
+#include PREFIX(android/media/audio/common/AudioConfig.h)
+#include PREFIX(android/media/audio/common/AudioConfigBase.h)
+#include PREFIX(android/media/audio/common/AudioContentType.h)
+#include PREFIX(android/media/audio/common/AudioDeviceDescription.h)
+#include PREFIX(android/media/audio/common/AudioDualMonoMode.h)
+#include PREFIX(android/media/audio/common/AudioEncapsulationMetadataType.h)
+#include PREFIX(android/media/audio/common/AudioEncapsulationMode.h)
+#include PREFIX(android/media/audio/common/AudioEncapsulationType.h)
+#include PREFIX(android/media/audio/common/AudioFormatDescription.h)
+#include PREFIX(android/media/audio/common/AudioGain.h)
+#include PREFIX(android/media/audio/common/AudioGainConfig.h)
+#include PREFIX(android/media/audio/common/AudioGainMode.h)
+#include PREFIX(android/media/audio/common/AudioInputFlags.h)
+#include PREFIX(android/media/audio/common/AudioIoFlags.h)
+#include PREFIX(android/media/audio/common/AudioLatencyMode.h)
+#include PREFIX(android/media/audio/common/AudioMode.h)
+#include PREFIX(android/media/audio/common/AudioOffloadInfo.h)
+#include PREFIX(android/media/audio/common/AudioOutputFlags.h)
+#include PREFIX(android/media/audio/common/AudioPortExt.h)
+#include PREFIX(android/media/audio/common/AudioPortMixExt.h)
+#include PREFIX(android/media/audio/common/AudioPlaybackRate.h)
+#include PREFIX(android/media/audio/common/AudioProfile.h)
+#include PREFIX(android/media/audio/common/AudioSource.h)
+#include PREFIX(android/media/audio/common/AudioStandard.h)
+#include PREFIX(android/media/audio/common/AudioUsage.h)
+#include PREFIX(android/media/audio/common/AudioUuid.h)
+#include PREFIX(android/media/audio/common/ExtraAudioDescriptor.h)
+#include PREFIX(android/media/audio/common/Int.h)
+#undef PREFIX
+
+#include <media/AidlConversionUtil.h>
+#include <system/audio.h>
+#include <system/audio_effect.h>
+
+using ::android::String16;
+using ::android::String8;
+
+#if defined(BACKEND_NDK)
+namespace aidl {
+#endif
+
+namespace android {
+
+// maxSize is the size of the C-string buffer (including the 0-terminator), NOT the max length of
+// the string.
+::android::status_t aidl2legacy_string(std::string_view aidl, char* dest, size_t maxSize);
+ConversionResult<std::string> legacy2aidl_string(const char* legacy, size_t maxSize);
+
+ConversionResult<audio_module_handle_t> aidl2legacy_int32_t_audio_module_handle_t(int32_t aidl);
+ConversionResult<int32_t> legacy2aidl_audio_module_handle_t_int32_t(audio_module_handle_t legacy);
+
+ConversionResult<audio_io_handle_t> aidl2legacy_int32_t_audio_io_handle_t(int32_t aidl);
+ConversionResult<int32_t> legacy2aidl_audio_io_handle_t_int32_t(audio_io_handle_t legacy);
+
+ConversionResult<audio_port_handle_t> aidl2legacy_int32_t_audio_port_handle_t(int32_t aidl);
+ConversionResult<int32_t> legacy2aidl_audio_port_handle_t_int32_t(audio_port_handle_t legacy);
+
+ConversionResult<audio_patch_handle_t> aidl2legacy_int32_t_audio_patch_handle_t(int32_t aidl);
+ConversionResult<int32_t> legacy2aidl_audio_patch_handle_t_int32_t(audio_patch_handle_t legacy);
+
+ConversionResult<audio_unique_id_t> aidl2legacy_int32_t_audio_unique_id_t(int32_t aidl);
+ConversionResult<int32_t> legacy2aidl_audio_unique_id_t_int32_t(audio_unique_id_t legacy);
+
+ConversionResult<audio_hw_sync_t> aidl2legacy_int32_t_audio_hw_sync_t(int32_t aidl);
+ConversionResult<int32_t> legacy2aidl_audio_hw_sync_t_int32_t(audio_hw_sync_t legacy);
+
+ConversionResult<unsigned int> aidl2legacy_int32_t_config_mask(int32_t aidl);
+ConversionResult<int32_t> legacy2aidl_config_mask_int32_t(unsigned int legacy);
+
+ConversionResult<pid_t> aidl2legacy_int32_t_pid_t(int32_t aidl);
+ConversionResult<int32_t> legacy2aidl_pid_t_int32_t(pid_t legacy);
+
+ConversionResult<uid_t> aidl2legacy_int32_t_uid_t(int32_t aidl);
+ConversionResult<int32_t> legacy2aidl_uid_t_int32_t(uid_t legacy);
+
+ConversionResult<String8> aidl2legacy_string_view_String8(std::string_view aidl);
+ConversionResult<std::string> legacy2aidl_String8_string(const String8& legacy);
+
+ConversionResult<String16> aidl2legacy_string_view_String16(std::string_view aidl);
+ConversionResult<std::string> legacy2aidl_String16_string(const String16& legacy);
+
+ConversionResult<std::optional<String16>>
+aidl2legacy_optional_string_view_optional_String16(std::optional<std::string_view> aidl);
+ConversionResult<std::optional<std::string_view>>
+legacy2aidl_optional_String16_optional_string(std::optional<String16> legacy);
+
+ConversionResult<audio_channel_mask_t> aidl2legacy_AudioChannelLayout_audio_channel_mask_t(
+ const media::audio::common::AudioChannelLayout& aidl, bool isInput);
+ConversionResult<media::audio::common::AudioChannelLayout>
+legacy2aidl_audio_channel_mask_t_AudioChannelLayout(audio_channel_mask_t legacy, bool isInput);
+
+ConversionResult<audio_config_t>
+aidl2legacy_AudioConfig_audio_config_t(const media::audio::common::AudioConfig& aidl, bool isInput);
+ConversionResult<media::audio::common::AudioConfig>
+legacy2aidl_audio_config_t_AudioConfig(const audio_config_t& legacy, bool isInput);
+
+ConversionResult<audio_config_base_t>
+aidl2legacy_AudioConfigBase_audio_config_base_t(
+ const media::audio::common::AudioConfigBase& aidl, bool isInput);
+ConversionResult<media::audio::common::AudioConfigBase>
+legacy2aidl_audio_config_base_t_AudioConfigBase(const audio_config_base_t& legacy, bool isInput);
+
+ConversionResult<audio_input_flags_t>
+aidl2legacy_AudioInputFlags_audio_input_flags_t(media::audio::common::AudioInputFlags aidl);
+ConversionResult<media::audio::common::AudioInputFlags>
+legacy2aidl_audio_input_flags_t_AudioInputFlags(audio_input_flags_t legacy);
+
+ConversionResult<audio_output_flags_t>
+aidl2legacy_AudioOutputFlags_audio_output_flags_t(media::audio::common::AudioOutputFlags aidl);
+ConversionResult<media::audio::common::AudioOutputFlags>
+legacy2aidl_audio_output_flags_t_AudioOutputFlags(audio_output_flags_t legacy);
+
+ConversionResult<audio_input_flags_t> aidl2legacy_int32_t_audio_input_flags_t_mask(
+ int32_t aidl);
+ConversionResult<int32_t> legacy2aidl_audio_input_flags_t_int32_t_mask(
+ audio_input_flags_t legacy);
+
+ConversionResult<audio_output_flags_t> aidl2legacy_int32_t_audio_output_flags_t_mask(
+ int32_t aidl);
+ConversionResult<int32_t> legacy2aidl_audio_output_flags_t_int32_t_mask(
+ audio_output_flags_t legacy);
+
+ConversionResult<audio_io_flags> aidl2legacy_AudioIoFlags_audio_io_flags(
+ const media::audio::common::AudioIoFlags& aidl, bool isInput);
+ConversionResult<media::audio::common::AudioIoFlags> legacy2aidl_audio_io_flags_AudioIoFlags(
+ const audio_io_flags& legacy, bool isInput);
+
+ConversionResult<audio_session_t> aidl2legacy_int32_t_audio_session_t(int32_t aidl);
+ConversionResult<int32_t> legacy2aidl_audio_session_t_int32_t(audio_session_t legacy);
+
+ConversionResult<audio_content_type_t>
+aidl2legacy_AudioContentType_audio_content_type_t(
+ media::audio::common::AudioContentType aidl);
+ConversionResult<media::audio::common::AudioContentType>
+legacy2aidl_audio_content_type_t_AudioContentType(audio_content_type_t legacy);
+
+ConversionResult<audio_devices_t> aidl2legacy_AudioDeviceDescription_audio_devices_t(
+ const media::audio::common::AudioDeviceDescription& aidl);
+ConversionResult<media::audio::common::AudioDeviceDescription>
+legacy2aidl_audio_devices_t_AudioDeviceDescription(audio_devices_t legacy);
+
+::android::status_t aidl2legacy_AudioDevice_audio_device(
+ const media::audio::common::AudioDevice& aidl, audio_devices_t* legacyType,
+ char* legacyAddress);
+::android::status_t aidl2legacy_AudioDevice_audio_device(
+ const media::audio::common::AudioDevice& aidl, audio_devices_t* legacyType,
+ String8* legacyAddress);
+::android::status_t aidl2legacy_AudioDevice_audio_device(
+ const media::audio::common::AudioDevice& aidl, audio_devices_t* legacyType,
+ std::string* legacyAddress);
+
+ConversionResult<media::audio::common::AudioDevice> legacy2aidl_audio_device_AudioDevice(
+ audio_devices_t legacyType, const char* legacyAddress);
+ConversionResult<media::audio::common::AudioDevice> legacy2aidl_audio_device_AudioDevice(
+ audio_devices_t legacyType, const String8& legacyAddress);
+
+ConversionResult<audio_extra_audio_descriptor>
+aidl2legacy_ExtraAudioDescriptor_audio_extra_audio_descriptor(
+ const media::audio::common::ExtraAudioDescriptor& aidl);
+
+ConversionResult<media::audio::common::ExtraAudioDescriptor>
+legacy2aidl_audio_extra_audio_descriptor_ExtraAudioDescriptor(
+ const audio_extra_audio_descriptor& legacy);
+
+ConversionResult<audio_encapsulation_metadata_type_t>
+aidl2legacy_AudioEncapsulationMetadataType_audio_encapsulation_metadata_type_t(
+ media::audio::common::AudioEncapsulationMetadataType aidl);
+ConversionResult<media::audio::common::AudioEncapsulationMetadataType>
+legacy2aidl_audio_encapsulation_metadata_type_t_AudioEncapsulationMetadataType(
+ audio_encapsulation_metadata_type_t legacy);
+
+ConversionResult<uint32_t> aidl2legacy_AudioEncapsulationMetadataType_mask(int32_t aidl);
+ConversionResult<int32_t> legacy2aidl_AudioEncapsulationMetadataType_mask(uint32_t legacy);
+
+ConversionResult<audio_encapsulation_mode_t>
+aidl2legacy_AudioEncapsulationMode_audio_encapsulation_mode_t(
+ media::audio::common::AudioEncapsulationMode aidl);
+ConversionResult<media::audio::common::AudioEncapsulationMode>
+legacy2aidl_audio_encapsulation_mode_t_AudioEncapsulationMode(audio_encapsulation_mode_t legacy);
+
+ConversionResult<uint32_t> aidl2legacy_AudioEncapsulationMode_mask(int32_t aidl);
+ConversionResult<int32_t> legacy2aidl_AudioEncapsulationMode_mask(uint32_t legacy);
+
+ConversionResult<audio_encapsulation_type_t>
+aidl2legacy_AudioEncapsulationType_audio_encapsulation_type_t(
+ const media::audio::common::AudioEncapsulationType& aidl);
+ConversionResult<media::audio::common::AudioEncapsulationType>
+legacy2aidl_audio_encapsulation_type_t_AudioEncapsulationType(
+ const audio_encapsulation_type_t& legacy);
+
+ConversionResult<audio_format_t> aidl2legacy_AudioFormatDescription_audio_format_t(
+ const media::audio::common::AudioFormatDescription& aidl);
+ConversionResult<media::audio::common::AudioFormatDescription>
+legacy2aidl_audio_format_t_AudioFormatDescription(audio_format_t legacy);
+
+ConversionResult<audio_gain_mode_t>
+aidl2legacy_AudioGainMode_audio_gain_mode_t(media::audio::common::AudioGainMode aidl);
+ConversionResult<media::audio::common::AudioGainMode>
+legacy2aidl_audio_gain_mode_t_AudioGainMode(audio_gain_mode_t legacy);
+
+ConversionResult<audio_gain_mode_t> aidl2legacy_int32_t_audio_gain_mode_t_mask(int32_t aidl);
+ConversionResult<int32_t> legacy2aidl_audio_gain_mode_t_int32_t_mask(audio_gain_mode_t legacy);
+
+ConversionResult<audio_gain_config> aidl2legacy_AudioGainConfig_audio_gain_config(
+ const media::audio::common::AudioGainConfig& aidl, bool isInput);
+ConversionResult<media::audio::common::AudioGainConfig>
+legacy2aidl_audio_gain_config_AudioGainConfig(const audio_gain_config& legacy, bool isInput);
+
+ConversionResult<audio_gain>
+aidl2legacy_AudioGain_audio_gain(const media::audio::common::AudioGain& aidl, bool isInput);
+ConversionResult<media::audio::common::AudioGain>
+legacy2aidl_audio_gain_AudioGain(const audio_gain& legacy, bool isInput);
+
+ConversionResult<audio_input_flags_t>
+aidl2legacy_AudioInputFlags_audio_input_flags_t(media::audio::common::AudioInputFlags aidl);
+ConversionResult<media::audio::common::AudioInputFlags>
+legacy2aidl_audio_input_flags_t_AudioInputFlags(audio_input_flags_t legacy);
+
+ConversionResult<audio_mode_t>
+aidl2legacy_AudioMode_audio_mode_t(media::audio::common::AudioMode aidl);
+ConversionResult<media::audio::common::AudioMode>
+legacy2aidl_audio_mode_t_AudioMode(audio_mode_t legacy);
+
+ConversionResult<audio_offload_info_t>
+aidl2legacy_AudioOffloadInfo_audio_offload_info_t(
+ const media::audio::common::AudioOffloadInfo& aidl);
+ConversionResult<media::audio::common::AudioOffloadInfo>
+legacy2aidl_audio_offload_info_t_AudioOffloadInfo(const audio_offload_info_t& legacy);
+
+ConversionResult<audio_output_flags_t>
+aidl2legacy_AudioOutputFlags_audio_output_flags_t(media::audio::common::AudioOutputFlags aidl);
+ConversionResult<media::audio::common::AudioOutputFlags>
+legacy2aidl_audio_output_flags_t_AudioOutputFlags(audio_output_flags_t legacy);
+
+ConversionResult<audio_profile> aidl2legacy_AudioProfile_audio_profile(
+ const media::audio::common::AudioProfile& aidl, bool isInput);
+ConversionResult<media::audio::common::AudioProfile> legacy2aidl_audio_profile_AudioProfile(
+ const audio_profile& legacy, bool isInput);
+
+ConversionResult<audio_standard_t> aidl2legacy_AudioStandard_audio_standard_t(
+ media::audio::common::AudioStandard aidl);
+ConversionResult<media::audio::common::AudioStandard> legacy2aidl_audio_standard_t_AudioStandard(
+ audio_standard_t legacy);
+
+ConversionResult<audio_source_t> aidl2legacy_AudioSource_audio_source_t(
+ media::audio::common::AudioSource aidl);
+ConversionResult<media::audio::common::AudioSource> legacy2aidl_audio_source_t_AudioSource(
+ audio_source_t legacy);
+
+ConversionResult<audio_usage_t> aidl2legacy_AudioUsage_audio_usage_t(
+ media::audio::common::AudioUsage aidl);
+ConversionResult<media::audio::common::AudioUsage> legacy2aidl_audio_usage_t_AudioUsage(
+ audio_usage_t legacy);
+
+ConversionResult<audio_uuid_t> aidl2legacy_AudioUuid_audio_uuid_t(
+ const media::audio::common::AudioUuid &aidl);
+ConversionResult<media::audio::common::AudioUuid> legacy2aidl_audio_uuid_t_AudioUuid(
+ const audio_uuid_t& legacy);
+
+ConversionResult<audio_dual_mono_mode_t>
+aidl2legacy_AudioDualMonoMode_audio_dual_mono_mode_t(media::audio::common::AudioDualMonoMode aidl);
+ConversionResult<media::audio::common::AudioDualMonoMode>
+legacy2aidl_audio_dual_mono_mode_t_AudioDualMonoMode(audio_dual_mono_mode_t legacy);
+
+ConversionResult<audio_timestretch_fallback_mode_t>
+aidl2legacy_TimestretchFallbackMode_audio_timestretch_fallback_mode_t(
+ media::audio::common::AudioPlaybackRate::TimestretchFallbackMode aidl);
+ConversionResult<media::audio::common::AudioPlaybackRate::TimestretchFallbackMode>
+legacy2aidl_audio_timestretch_fallback_mode_t_TimestretchFallbackMode(
+ audio_timestretch_fallback_mode_t legacy);
+
+ConversionResult<audio_timestretch_stretch_mode_t>
+aidl2legacy_TimestretchMode_audio_timestretch_stretch_mode_t(
+ media::audio::common::AudioPlaybackRate::TimestretchMode aidl);
+ConversionResult<media::audio::common::AudioPlaybackRate::TimestretchMode>
+legacy2aidl_audio_timestretch_stretch_mode_t_TimestretchMode(
+ audio_timestretch_stretch_mode_t legacy);
+
+ConversionResult<audio_playback_rate_t>
+aidl2legacy_AudioPlaybackRate_audio_playback_rate_t(
+ const media::audio::common::AudioPlaybackRate& aidl);
+ConversionResult<media::audio::common::AudioPlaybackRate>
+legacy2aidl_audio_playback_rate_t_AudioPlaybackRate(const audio_playback_rate_t& legacy);
+
+ConversionResult<audio_latency_mode_t>
+aidl2legacy_AudioLatencyMode_audio_latency_mode_t(media::audio::common::AudioLatencyMode aidl);
+ConversionResult<media::audio::common::AudioLatencyMode>
+legacy2aidl_audio_latency_mode_t_AudioLatencyMode(audio_latency_mode_t legacy);
+
+} // namespace android
+
+#if defined(BACKEND_NDK)
+} // aidl
+#endif
diff --git a/media/audioaidlconversion/include/media/AidlConversionNdk.h b/media/audioaidlconversion/include/media/AidlConversionNdk.h
new file mode 100644
index 0000000..a1c0da7
--- /dev/null
+++ b/media/audioaidlconversion/include/media/AidlConversionNdk.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2022 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 <android/binder_auto_utils.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+/**
+ * Can only handle conversion between AIDL (NDK backend) and legacy type.
+ */
+#include <hardware/audio_effect.h>
+#include <media/AidlConversionUtil.h>
+#include <system/audio_effect.h>
+
+#include <aidl/android/hardware/audio/effect/IEffect.h>
+
+namespace aidl {
+namespace android {
+
+ConversionResult<::aidl::android::hardware::audio::effect::AcousticEchoCanceler>
+getParameterSpecificAec(const ::aidl::android::hardware::audio::effect::Parameter& aidl);
+
+ConversionResult<uint32_t> aidl2legacy_Flags_Type_uint32(
+ ::aidl::android::hardware::audio::effect::Flags::Type type);
+ConversionResult<uint32_t> aidl2legacy_Flags_Insert_uint32(
+ ::aidl::android::hardware::audio::effect::Flags::Insert insert);
+ConversionResult<uint32_t> aidl2legacy_Flags_Volume_uint32(
+ ::aidl::android::hardware::audio::effect::Flags::Volume volume);
+ConversionResult<uint32_t> aidl2legacy_Flags_HardwareAccelerator_uint32(
+ ::aidl::android::hardware::audio::effect::Flags::HardwareAccelerator hwAcceleratorMode);
+ConversionResult<uint32_t> aidl2legacy_Flags_uint32(
+ const ::aidl::android::hardware::audio::effect::Flags aidl);
+
+ConversionResult<::aidl::android::hardware::audio::effect::Flags::Type>
+legacy2aidl_uint32_Flags_Type(uint32_t legacy);
+ConversionResult<::aidl::android::hardware::audio::effect::Flags::Insert>
+legacy2aidl_uint32_Flags_Insert(uint32_t legacy);
+ConversionResult<::aidl::android::hardware::audio::effect::Flags::Volume>
+legacy2aidl_uint32_Flags_Volume(uint32_t legacy);
+ConversionResult<::aidl::android::hardware::audio::effect::Flags::HardwareAccelerator>
+legacy2aidl_uint32_Flags_HardwareAccelerator(uint32_t legacy);
+ConversionResult<::aidl::android::hardware::audio::effect::Flags> legacy2aidl_uint32_Flags(
+ uint32_t hal);
+
+ConversionResult<effect_descriptor_t> aidl2legacy_Descriptor_effect_descriptor(
+ const ::aidl::android::hardware::audio::effect::Descriptor& aidl);
+ConversionResult<::aidl::android::hardware::audio::effect::Descriptor>
+legacy2aidl_effect_descriptor_Descriptor(const effect_descriptor_t& hal);
+
+ConversionResult<buffer_config_t> aidl2legacy_AudioConfigBase_buffer_config_t(
+ const media::audio::common::AudioConfigBase& aidl, bool isInput);
+ConversionResult<media::audio::common::AudioConfigBase> legacy2aidl_buffer_config_t_AudioConfigBase(
+ const buffer_config_t& legacy, bool isInput);
+
+ConversionResult<uint32_t> aidl2legacy_Parameter_uint32_echoDelay(
+ const ::aidl::android::hardware::audio::effect::Parameter& aidl);
+ConversionResult<::aidl::android::hardware::audio::effect::Parameter>
+legacy2aidl_uint32_echoDelay_Parameter(const uint32_t& legacy);
+
+ConversionResult<uint32_t> aidl2legacy_Parameter_uint32_mobileMode(
+ const ::aidl::android::hardware::audio::effect::Parameter& aidl);
+ConversionResult<::aidl::android::hardware::audio::effect::Parameter>
+legacy2aidl_uint32_mobileMode_Parameter(const uint32_t& legacy);
+
+
+} // namespace android
+} // namespace aidl
diff --git a/media/libaudioclient/include/media/AidlConversionUtil.h b/media/audioaidlconversion/include/media/AidlConversionUtil.h
similarity index 75%
rename from media/libaudioclient/include/media/AidlConversionUtil.h
rename to media/audioaidlconversion/include/media/AidlConversionUtil.h
index 8817c35..a0830fc 100644
--- a/media/libaudioclient/include/media/AidlConversionUtil.h
+++ b/media/audioaidlconversion/include/media/AidlConversionUtil.h
@@ -20,15 +20,24 @@
#include <type_traits>
#include <utility>
-#include <binder/Enums.h>
+#include <android-base/expected.h>
#include <binder/Status.h>
#include <error/Result.h>
-namespace android {
+#if defined(BACKEND_NDK)
+#include <android/binder_auto_utils.h>
+#include <android/binder_enums.h>
+#include <android/binder_status.h>
+
+namespace aidl {
+#else
+#include <binder/Enums.h>
+#endif
template <typename T>
-using ConversionResult = error::Result<T>;
+using ConversionResult = ::android::error::Result<T>;
+namespace android {
/**
* A generic template to safely cast between integral types, respecting limits of the destination
* type.
@@ -39,15 +48,15 @@
// have the signed converted to unsigned and produce wrong results.
if (std::is_signed_v<From> && !std::is_signed_v<To>) {
if (from < 0 || from > std::numeric_limits<To>::max()) {
- return base::unexpected(BAD_VALUE);
+ return ::android::base::unexpected(::android::BAD_VALUE);
}
} else if (std::is_signed_v<To> && !std::is_signed_v<From>) {
if (from > std::numeric_limits<To>::max()) {
- return base::unexpected(BAD_VALUE);
+ return ::android::base::unexpected(::android::BAD_VALUE);
}
} else {
if (from < std::numeric_limits<To>::min() || from > std::numeric_limits<To>::max()) {
- return base::unexpected(BAD_VALUE);
+ return ::android::base::unexpected(::android::BAD_VALUE);
}
}
return static_cast<To>(from);
@@ -67,14 +76,14 @@
* A generic template that helps convert containers of convertible types, using iterators.
*/
template<typename InputIterator, typename OutputIterator, typename Func>
-status_t convertRange(InputIterator start,
+::android::status_t convertRange(InputIterator start,
InputIterator end,
OutputIterator out,
const Func& itemConversion) {
for (InputIterator iter = start; iter != end; ++iter, ++out) {
*out = VALUE_OR_RETURN_STATUS(itemConversion(*iter));
}
- return OK;
+ return ::android::OK;
}
/**
@@ -82,7 +91,7 @@
* Uses a limit as maximum conversion items.
*/
template<typename InputIterator, typename OutputIterator, typename Func>
-status_t convertRangeWithLimit(InputIterator start,
+::android::status_t convertRangeWithLimit(InputIterator start,
InputIterator end,
OutputIterator out,
const Func& itemConversion,
@@ -94,7 +103,7 @@
for (InputIterator iter = start; (iter != last); ++iter, ++out) {
*out = VALUE_OR_RETURN_STATUS(itemConversion(*iter));
}
- return OK;
+ return ::android::OK;
}
/**
@@ -140,7 +149,7 @@
OutputContainer output;
auto ins = std::inserter(output, output.begin());
for (const auto& item1 : input1) {
- RETURN_IF_ERROR(iter2 != input2.end() ? OK : BAD_VALUE);
+ RETURN_IF_ERROR(iter2 != input2.end() ? ::android::OK : ::android::BAD_VALUE);
*ins = VALUE_OR_RETURN(itemConversion(item1, *iter2++));
}
return output;
@@ -248,7 +257,8 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// Utilities for working with AIDL unions.
// UNION_GET(obj, fieldname) returns a ConversionResult<T> containing either the strongly-typed
-// value of the respective field, or BAD_VALUE if the union is not set to the requested field.
+// value of the respective field, or ::android::BAD_VALUE if the union is not set to the requested
+// field.
// UNION_SET(obj, fieldname, value) sets the requested field to the given value.
template<typename T, typename T::Tag tag>
@@ -257,7 +267,7 @@
template<typename T, typename T::Tag tag>
ConversionResult<UnionFieldType<T, tag>> unionGetField(const T& u) {
if (u.getTag() != tag) {
- return base::unexpected(BAD_VALUE);
+ return ::android::base::unexpected(::android::BAD_VALUE);
}
return u.template get<tag>();
}
@@ -275,7 +285,11 @@
*/
template <typename T>
bool isValidEnum(T value) {
- constexpr android::enum_range<T> er{};
+#if defined(BACKEND_NDK)
+ constexpr ndk::enum_range<T> er{};
+#else
+ constexpr ::android::enum_range<T> er{};
+#endif
return std::find(er.begin(), er.end(), value) != er.end();
}
@@ -294,7 +308,7 @@
}
/**
- * Return the equivalent Android status_t from a binder exception code.
+ * Return the equivalent Android ::android::status_t from a binder exception code.
*
* Generally one should use statusTFromBinderStatus() instead.
*
@@ -304,33 +318,33 @@
* Note: for EX_TRANSACTION_FAILED and EX_SERVICE_SPECIFIC a more detailed error code
* can be found from transactionError() or serviceSpecificErrorCode().
*/
-static inline status_t statusTFromExceptionCode(int32_t exceptionCode) {
+static inline ::android::status_t statusTFromExceptionCode(int32_t exceptionCode) {
using namespace ::android::binder;
switch (exceptionCode) {
case Status::EX_NONE:
- return OK;
- case Status::EX_SECURITY: // Java SecurityException, rethrows locally in Java
- return PERMISSION_DENIED;
- case Status::EX_BAD_PARCELABLE: // Java BadParcelableException, rethrows in Java
- case Status::EX_ILLEGAL_ARGUMENT: // Java IllegalArgumentException, rethrows in Java
- case Status::EX_NULL_POINTER: // Java NullPointerException, rethrows in Java
- return BAD_VALUE;
- case Status::EX_ILLEGAL_STATE: // Java IllegalStateException, rethrows in Java
- case Status::EX_UNSUPPORTED_OPERATION: // Java UnsupportedOperationException, rethrows
- return INVALID_OPERATION;
+ return ::android::OK;
+ case Status::EX_SECURITY: // Java SecurityException, rethrows locally in Java
+ return ::android::PERMISSION_DENIED;
+ case Status::EX_BAD_PARCELABLE: // Java BadParcelableException, rethrows in Java
+ case Status::EX_ILLEGAL_ARGUMENT: // Java IllegalArgumentException, rethrows in Java
+ case Status::EX_NULL_POINTER: // Java NullPointerException, rethrows in Java
+ return ::android::BAD_VALUE;
+ case Status::EX_ILLEGAL_STATE: // Java IllegalStateException, rethrows in Java
+ case Status::EX_UNSUPPORTED_OPERATION: // Java UnsupportedOperationException, rethrows
+ return ::android::INVALID_OPERATION;
case Status::EX_HAS_REPLY_HEADER: // Native strictmode violation
- case Status::EX_PARCELABLE: // Java bootclass loader (not standard exception), rethrows
- case Status::EX_NETWORK_MAIN_THREAD: // Java NetworkOnMainThreadException, rethrows
+ case Status::EX_PARCELABLE: // Java bootclass loader (not standard exception), rethrows
+ case Status::EX_NETWORK_MAIN_THREAD: // Java NetworkOnMainThreadException, rethrows
case Status::EX_TRANSACTION_FAILED: // Native - see error code
- case Status::EX_SERVICE_SPECIFIC: // Java ServiceSpecificException,
- // rethrows in Java with integer error code
- return UNKNOWN_ERROR;
+ case Status::EX_SERVICE_SPECIFIC: // Java ServiceSpecificException,
+ // rethrows in Java with integer error code
+ return ::android::UNKNOWN_ERROR;
}
- return UNKNOWN_ERROR;
+ return ::android::UNKNOWN_ERROR;
}
/**
- * Return the equivalent Android status_t from a binder status.
+ * Return the equivalent Android ::android::status_t from a binder status.
*
* Used to handle errors from a AIDL method declaration
*
@@ -340,8 +354,8 @@
*
* return_type method(type0 param0, ...)
*/
-static inline status_t statusTFromBinderStatus(const ::android::binder::Status &status) {
- return status.isOk() ? OK // check OK,
+static inline ::android::status_t statusTFromBinderStatus(const ::android::binder::Status &status) {
+ return status.isOk() ? ::android::OK // check ::android::OK,
: status.serviceSpecificErrorCode() // service-side error, not standard Java exception
// (fromServiceSpecificError)
?: status.transactionError() // a native binder transaction error (fromStatusT)
@@ -349,6 +363,20 @@
// standard Java exception (fromExceptionCode)
}
+#if defined(BACKEND_NDK)
+static inline ::android::status_t statusTFromBinderStatus(const ::ndk::ScopedAStatus &status) {
+ // What we want to do is to 'return statusTFromBinderStatus(status.get()->get())'
+ // However, since the definition of AStatus is not exposed, we have to do the same
+ // via methods of ScopedAStatus:
+ return status.isOk() ? ::android::OK // check ::android::OK,
+ : status.getServiceSpecificError() // service-side error, not standard Java exception
+ // (fromServiceSpecificError)
+ ?: status.getStatus() // a native binder transaction error (fromStatusT)
+ ?: statusTFromExceptionCode(status.getExceptionCode()); // a service-side error with a
+ // standard Java exception (fromExceptionCode)
+}
+#endif
+
/**
* Return a binder::Status from native service status.
*
@@ -356,23 +384,23 @@
* where Java callers expect an exception, not an integer return value.
*/
static inline ::android::binder::Status binderStatusFromStatusT(
- status_t status, const char *optionalMessage = nullptr) {
+ ::android::status_t status, const char *optionalMessage = nullptr) {
const char * const emptyIfNull = optionalMessage == nullptr ? "" : optionalMessage;
// From binder::Status instructions:
// Prefer a generic exception code when possible, then a service specific
- // code, and finally a status_t for low level failures or legacy support.
+ // code, and finally a ::android::status_t for low level failures or legacy support.
// Exception codes and service specific errors map to nicer exceptions for
// Java clients.
using namespace ::android::binder;
switch (status) {
- case OK:
+ case ::android::OK:
return Status::ok();
- case PERMISSION_DENIED: // throw SecurityException on Java side
+ case ::android::PERMISSION_DENIED: // throw SecurityException on Java side
return Status::fromExceptionCode(Status::EX_SECURITY, emptyIfNull);
- case BAD_VALUE: // throw IllegalArgumentException on Java side
+ case ::android::BAD_VALUE: // throw IllegalArgumentException on Java side
return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT, emptyIfNull);
- case INVALID_OPERATION: // throw IllegalStateException on Java side
+ case ::android::INVALID_OPERATION: // throw IllegalStateException on Java side
return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE, emptyIfNull);
}
@@ -383,7 +411,10 @@
return Status::fromServiceSpecificError(status, emptyIfNull);
}
-
} // namespace aidl_utils
} // namespace android
+
+#if defined(BACKEND_NDK)
+} // namespace aidl
+#endif
diff --git a/media/audioserver/audioserver.rc b/media/audioserver/audioserver.rc
index c4a6601..d62dd91 100644
--- a/media/audioserver/audioserver.rc
+++ b/media/audioserver/audioserver.rc
@@ -7,11 +7,10 @@
ioprio rt 4
task_profiles ProcessCapacityHigh HighPerformance
onrestart restart vendor.audio-hal
+ onrestart restart vendor.audio-hal-aidl
+ onrestart restart vendor.audio-effect-hal-aidl
onrestart restart vendor.audio-hal-4-0-msd
onrestart restart audio_proxy_service
- # Keep the original service names for backward compatibility
- onrestart restart vendor.audio-hal-2-0
- onrestart restart audio-hal-2-0
on property:vts.native_server.on=1
stop audioserver
@@ -20,42 +19,39 @@
on property:init.svc.audioserver=stopped
stop vendor.audio-hal
+ stop vendor.audio-hal-aidl
+ stop vendor.audio-effect-hal-aidl
stop vendor.audio-hal-4-0-msd
stop audio_proxy_service
- # Keep the original service names for backward compatibility
- stop vendor.audio-hal-2-0
- stop audio-hal-2-0
# See b/155364397. Need to have HAL service running for VTS.
# Can't use 'restart' because then HAL service would restart
# audioserver bringing it back into running state.
start vendor.audio-hal
+ start vendor.audio-hal-aidl
+ start vendor.audio-effect-hal-aidl
start vendor.audio-hal-4-0-msd
start audio_proxy_service
- # Keep the original service names for backward compatibility
- start vendor.audio-hal-2-0
- start audio-hal-2-0
on property:init.svc.audioserver=running
start vendor.audio-hal
+ start vendor.audio-hal-aidl
+ start vendor.audio-effect-hal-aidl
start vendor.audio-hal-4-0-msd
start audio_proxy_service
- # Keep the original service names for backward compatibility
- start vendor.audio-hal-2-0
- start audio-hal-2-0
on property:sys.audio.restart.hal=1
# See b/159966243. Avoid restart loop between audioserver and HAL.
# Keep the original service names for backward compatibility
stop vendor.audio-hal
+ stop vendor.audio-hal-aidl
+ stop vendor.audio-effect-hal-aidl
stop vendor.audio-hal-4-0-msd
stop audio_proxy_service
- stop vendor.audio-hal-2-0
- stop audio-hal-2-0
start vendor.audio-hal
+ start vendor.audio-hal-aidl
+ start vendor.audio-effect-hal-aidl
start vendor.audio-hal-4-0-msd
start audio_proxy_service
- start vendor.audio-hal-2-0
- start audio-hal-2-0
# reset the property
setprop sys.audio.restart.hal 0
diff --git a/media/codec2/components/aac/C2SoftAacDec.cpp b/media/codec2/components/aac/C2SoftAacDec.cpp
index 4e4a9a1..d1b08bd 100644
--- a/media/codec2/components/aac/C2SoftAacDec.cpp
+++ b/media/codec2/components/aac/C2SoftAacDec.cpp
@@ -275,7 +275,8 @@
mStreamInfo(nullptr),
mSignalledError(false),
mOutputPortDelay(kDefaultOutputPortDelay),
- mOutputDelayRingBuffer(nullptr) {
+ mOutputDelayRingBuffer(nullptr),
+ mDeviceApiLevel(android_get_device_api_level()) {
}
C2SoftAacDec::~C2SoftAacDec() {
@@ -891,7 +892,7 @@
work->worklets.front()->output.configUpdate.push_back(
C2Param::Copy(currentBoostFactor));
- if (android_get_device_api_level() < __ANDROID_API_S__) {
+ if (mDeviceApiLevel < __ANDROID_API_S__) {
// We used to report DRC compression mode in the output format
// in Q and R, but stopped doing that in S
C2StreamDrcCompressionModeTuning::input currentCompressMode(0u,
diff --git a/media/codec2/components/aac/C2SoftAacDec.h b/media/codec2/components/aac/C2SoftAacDec.h
index b45f148..f85d45f 100644
--- a/media/codec2/components/aac/C2SoftAacDec.h
+++ b/media/codec2/components/aac/C2SoftAacDec.h
@@ -97,6 +97,7 @@
int32_t mOutputDelayRingBufferWritePos;
int32_t mOutputDelayRingBufferReadPos;
int32_t mOutputDelayRingBufferFilled;
+ int mDeviceApiLevel;
bool outputDelayRingBufferPutSamples(INT_PCM *samples, int numSamples);
int32_t outputDelayRingBufferGetSamples(INT_PCM *samples, int numSamples);
int32_t outputDelayRingBufferSamplesAvailable();
diff --git a/media/codec2/components/avc/C2SoftAvcDec.cpp b/media/codec2/components/avc/C2SoftAvcDec.cpp
index 953afc5..96a4c4a 100644
--- a/media/codec2/components/avc/C2SoftAvcDec.cpp
+++ b/media/codec2/components/avc/C2SoftAvcDec.cpp
@@ -671,6 +671,9 @@
void C2SoftAvcDec::resetPlugin() {
mSignalledOutputEos = false;
mTimeStart = mTimeEnd = systemTime();
+ if (mOutBlock) {
+ mOutBlock.reset();
+ }
}
status_t C2SoftAvcDec::deleteDecoder() {
diff --git a/media/codec2/components/avc/C2SoftAvcEnc.cpp b/media/codec2/components/avc/C2SoftAvcEnc.cpp
index 8b46d3f..5d2856a 100644
--- a/media/codec2/components/avc/C2SoftAvcEnc.cpp
+++ b/media/codec2/components/avc/C2SoftAvcEnc.cpp
@@ -392,9 +392,9 @@
static C2R PictureQuantizationSetter(bool mayBlock,
C2P<C2StreamPictureQuantizationTuning::output> &me) {
(void)mayBlock;
- (void)me;
- // TODO: refactor with same algorithm in the SetQp()
+ // these are the ones we're going to set, so want them to default
+ // to the DEFAULT values for the codec
int32_t iMin = DEFAULT_I_QP_MIN, pMin = DEFAULT_P_QP_MIN, bMin = DEFAULT_B_QP_MIN;
int32_t iMax = DEFAULT_I_QP_MAX, pMax = DEFAULT_P_QP_MAX, bMax = DEFAULT_B_QP_MAX;
@@ -419,13 +419,14 @@
ALOGV("PictureQuantizationSetter(entry): i %d-%d p %d-%d b %d-%d",
iMin, iMax, pMin, pMax, bMin, bMax);
- // ensure we have legal values
- iMax = std::clamp(iMax, CODEC_QP_MIN, CODEC_QP_MAX);
- iMin = std::clamp(iMin, CODEC_QP_MIN, CODEC_QP_MAX);
- pMax = std::clamp(pMax, CODEC_QP_MIN, CODEC_QP_MAX);
- pMin = std::clamp(pMin, CODEC_QP_MIN, CODEC_QP_MAX);
- bMax = std::clamp(bMax, CODEC_QP_MIN, CODEC_QP_MAX);
- bMin = std::clamp(bMin, CODEC_QP_MIN, CODEC_QP_MAX);
+ // min is clamped to [AVC_QP_MIN, max] to avoid error
+ // cases where layer.min > layer.max
+ iMax = std::clamp(iMax, AVC_QP_MIN, AVC_QP_MAX);
+ iMin = std::clamp(iMin, AVC_QP_MIN, iMax);
+ pMax = std::clamp(pMax, AVC_QP_MIN, AVC_QP_MAX);
+ pMin = std::clamp(pMin, AVC_QP_MIN, pMax);
+ bMax = std::clamp(bMax, AVC_QP_MIN, AVC_QP_MAX);
+ bMin = std::clamp(bMin, AVC_QP_MIN, bMax);
// put them back into the structure
for (size_t i = 0; i < me.v.flexCount(); ++i) {
@@ -819,7 +820,8 @@
s_qp_ip.e_cmd = IVE_CMD_VIDEO_CTL;
s_qp_ip.e_sub_cmd = IVE_CMD_CTL_SET_QP;
- // TODO: refactor with same algorithm in the PictureQuantizationSetter()
+ // we resolved out-of-bound and unspecified values in PictureQuantizationSetter()
+ // so we can start with defaults that are overridden as needed.
int32_t iMin = DEFAULT_I_QP_MIN, pMin = DEFAULT_P_QP_MIN, bMin = DEFAULT_B_QP_MIN;
int32_t iMax = DEFAULT_I_QP_MAX, pMax = DEFAULT_P_QP_MAX, bMax = DEFAULT_B_QP_MAX;
@@ -1766,17 +1768,20 @@
// }
// }
// }
- std::shared_ptr<const C2GraphicView> view;
+ std::shared_ptr<C2GraphicView> view;
std::shared_ptr<C2Buffer> inputBuffer;
if (!work->input.buffers.empty()) {
inputBuffer = work->input.buffers[0];
- view = std::make_shared<const C2GraphicView>(
+ view = std::make_shared<C2GraphicView>(
inputBuffer->data().graphicBlocks().front().map().get());
if (view->error() != C2_OK) {
ALOGE("graphic view map err = %d", view->error());
work->workletsProcessed = 1u;
return;
}
+ //(b/232396154)
+ //workaround for incorrect crop size in view when using surface mode
+ view->setCrop_be(C2Rect(mSize->width, mSize->height));
}
do {
diff --git a/media/codec2/components/avc/C2SoftAvcEnc.h b/media/codec2/components/avc/C2SoftAvcEnc.h
index 293867d..cde6604 100644
--- a/media/codec2/components/avc/C2SoftAvcEnc.h
+++ b/media/codec2/components/avc/C2SoftAvcEnc.h
@@ -103,8 +103,8 @@
/** limits as specified by h264
* (QP_MIN==4 is actually a limitation of this SW codec, not the H.264 standard)
**/
-#define CODEC_QP_MIN 4
-#define CODEC_QP_MAX 51
+#define AVC_QP_MIN 4
+#define AVC_QP_MAX 51
#define MIN(a, b) ((a) < (b))? (a) : (b)
diff --git a/media/codec2/components/base/SimpleC2Component.cpp b/media/codec2/components/base/SimpleC2Component.cpp
index 9d4f049..199875d 100644
--- a/media/codec2/components/base/SimpleC2Component.cpp
+++ b/media/codec2/components/base/SimpleC2Component.cpp
@@ -190,7 +190,7 @@
// matrix conversion coefficients
// (see media/libstagefright/colorconverter/ColorConverter.cpp for more details)
struct Coeffs {
- int32_t _y, _b_u, _g_u, _g_v, _r_v, _c16;
+ int32_t _y, _r_v, _g_u, _g_v, _b_u, _c16;
};
static const struct Coeffs GetCoeffsForAspects(const C2ColorAspectsStruct &aspects) {
diff --git a/media/codec2/components/gav1/C2SoftGav1Dec.cpp b/media/codec2/components/gav1/C2SoftGav1Dec.cpp
index 4dec57f..d234f21 100644
--- a/media/codec2/components/gav1/C2SoftGav1Dec.cpp
+++ b/media/codec2/components/gav1/C2SoftGav1Dec.cpp
@@ -102,6 +102,29 @@
.withSetter(Hdr10PlusInfoOutputSetter)
.build());
+ // default static info
+ C2HdrStaticMetadataStruct defaultStaticInfo{};
+ helper->addStructDescriptors<C2MasteringDisplayColorVolumeStruct, C2ColorXyStruct>();
+ addParameter(
+ DefineParam(mHdrStaticInfo, C2_PARAMKEY_HDR_STATIC_INFO)
+ .withDefault(new C2StreamHdrStaticInfo::output(0u, defaultStaticInfo))
+ .withFields({
+ C2F(mHdrStaticInfo, mastering.red.x).inRange(0, 1),
+ C2F(mHdrStaticInfo, mastering.red.y).inRange(0, 1),
+ C2F(mHdrStaticInfo, mastering.green.x).inRange(0, 1),
+ C2F(mHdrStaticInfo, mastering.green.y).inRange(0, 1),
+ C2F(mHdrStaticInfo, mastering.blue.x).inRange(0, 1),
+ C2F(mHdrStaticInfo, mastering.blue.y).inRange(0, 1),
+ C2F(mHdrStaticInfo, mastering.white.x).inRange(0, 1),
+ C2F(mHdrStaticInfo, mastering.white.x).inRange(0, 1),
+ C2F(mHdrStaticInfo, mastering.maxLuminance).inRange(0, 65535),
+ C2F(mHdrStaticInfo, mastering.minLuminance).inRange(0, 6.5535),
+ C2F(mHdrStaticInfo, maxCll).inRange(0, 0XFFFF),
+ C2F(mHdrStaticInfo, maxFall).inRange(0, 0XFFFF)
+ })
+ .withSetter(HdrStaticInfoSetter)
+ .build());
+
addParameter(
DefineParam(mMaxSize, C2_PARAMKEY_MAX_PICTURE_SIZE)
.withDefault(new C2StreamMaxPictureSizeTuning::output(0u, 320, 240))
@@ -331,6 +354,47 @@
// unsafe getters
std::shared_ptr<C2StreamPixelFormatInfo::output> getPixelFormat_l() const { return mPixelFormat; }
+ static C2R HdrStaticInfoSetter(bool mayBlock, C2P<C2StreamHdrStaticInfo::output> &me) {
+ (void)mayBlock;
+ if (me.v.mastering.red.x > 1) {
+ me.set().mastering.red.x = 1;
+ }
+ if (me.v.mastering.red.y > 1) {
+ me.set().mastering.red.y = 1;
+ }
+ if (me.v.mastering.green.x > 1) {
+ me.set().mastering.green.x = 1;
+ }
+ if (me.v.mastering.green.y > 1) {
+ me.set().mastering.green.y = 1;
+ }
+ if (me.v.mastering.blue.x > 1) {
+ me.set().mastering.blue.x = 1;
+ }
+ if (me.v.mastering.blue.y > 1) {
+ me.set().mastering.blue.y = 1;
+ }
+ if (me.v.mastering.white.x > 1) {
+ me.set().mastering.white.x = 1;
+ }
+ if (me.v.mastering.white.y > 1) {
+ me.set().mastering.white.y = 1;
+ }
+ if (me.v.mastering.maxLuminance > 65535.0) {
+ me.set().mastering.maxLuminance = 65535.0;
+ }
+ if (me.v.mastering.minLuminance > 6.5535) {
+ me.set().mastering.minLuminance = 6.5535;
+ }
+ if (me.v.maxCll > 65535.0) {
+ me.set().maxCll = 65535.0;
+ }
+ if (me.v.maxFall > 65535.0) {
+ me.set().maxFall = 65535.0;
+ }
+ return C2R::Ok();
+ }
+
private:
std::shared_ptr<C2StreamProfileLevelInfo::input> mProfileLevel;
std::shared_ptr<C2StreamPictureSizeInfo::output> mSize;
@@ -343,6 +407,7 @@
std::shared_ptr<C2StreamColorAspectsInfo::output> mColorAspects;
std::shared_ptr<C2StreamHdr10PlusInfo::input> mHdr10PlusInfoInput;
std::shared_ptr<C2StreamHdr10PlusInfo::output> mHdr10PlusInfoOutput;
+ std::shared_ptr<C2StreamHdrStaticInfo::output> mHdrStaticInfo;
};
C2SoftGav1Dec::C2SoftGav1Dec(const char *name, c2_node_id_t id,
@@ -558,6 +623,76 @@
}
}
+void C2SoftGav1Dec::getHDRStaticParams(const libgav1::DecoderBuffer *buffer,
+ const std::unique_ptr<C2Work> &work) {
+ C2StreamHdrStaticMetadataInfo::output hdrStaticMetadataInfo{};
+ bool infoPresent = false;
+ if (buffer->has_hdr_mdcv) {
+ // hdr_mdcv.primary_chromaticity_* values are in 0.16 fixed-point format.
+ hdrStaticMetadataInfo.mastering.red.x = buffer->hdr_mdcv.primary_chromaticity_x[0] / 65536.0;
+ hdrStaticMetadataInfo.mastering.red.y = buffer->hdr_mdcv.primary_chromaticity_y[0] / 65536.0;
+
+ hdrStaticMetadataInfo.mastering.green.x = buffer->hdr_mdcv.primary_chromaticity_x[1] / 65536.0;
+ hdrStaticMetadataInfo.mastering.green.y = buffer->hdr_mdcv.primary_chromaticity_y[1] / 65536.0;
+
+ hdrStaticMetadataInfo.mastering.blue.x = buffer->hdr_mdcv.primary_chromaticity_x[2] / 65536.0;
+ hdrStaticMetadataInfo.mastering.blue.y = buffer->hdr_mdcv.primary_chromaticity_y[2] / 65536.0;
+
+ // hdr_mdcv.white_point_chromaticity_* values are in 0.16 fixed-point format.
+ hdrStaticMetadataInfo.mastering.white.x = buffer->hdr_mdcv.white_point_chromaticity_x / 65536.0;
+ hdrStaticMetadataInfo.mastering.white.y = buffer->hdr_mdcv.white_point_chromaticity_y / 65536.0;
+
+ // hdr_mdcv.luminance_max is in 24.8 fixed-point format.
+ hdrStaticMetadataInfo.mastering.maxLuminance = buffer->hdr_mdcv.luminance_max / 256.0;
+ // hdr_mdcv.luminance_min is in 18.14 format.
+ hdrStaticMetadataInfo.mastering.minLuminance = buffer->hdr_mdcv.luminance_min / 16384.0;
+ infoPresent = true;
+ }
+
+ if (buffer->has_hdr_cll) {
+ hdrStaticMetadataInfo.maxCll = buffer->hdr_cll.max_cll;
+ hdrStaticMetadataInfo.maxFall = buffer->hdr_cll.max_fall;
+ infoPresent = true;
+ }
+ // config if static info has changed
+ if (infoPresent && !(hdrStaticMetadataInfo == mHdrStaticMetadataInfo)) {
+ mHdrStaticMetadataInfo = hdrStaticMetadataInfo;
+ work->worklets.front()->output.configUpdate.push_back(C2Param::Copy(mHdrStaticMetadataInfo));
+ }
+}
+
+void C2SoftGav1Dec::getHDR10PlusInfoData(const libgav1::DecoderBuffer *buffer,
+ const std::unique_ptr<C2Work> &work) {
+ if (buffer->has_itut_t35) {
+ std::vector<uint8_t> payload;
+ size_t payloadSize = buffer->itut_t35.payload_size;
+ if (payloadSize > 0) {
+ payload.push_back(buffer->itut_t35.country_code);
+ if (buffer->itut_t35.country_code == 0xFF) {
+ payload.push_back(buffer->itut_t35.country_code_extension_byte);
+ }
+ payload.insert(payload.end(), buffer->itut_t35.payload_bytes,
+ buffer->itut_t35.payload_bytes + buffer->itut_t35.payload_size);
+ }
+
+ std::unique_ptr<C2StreamHdr10PlusInfo::output> hdr10PlusInfo =
+ C2StreamHdr10PlusInfo::output::AllocUnique(payload.size());
+ if (!hdr10PlusInfo) {
+ ALOGE("Hdr10PlusInfo allocation failed");
+ mSignalledError = true;
+ work->result = C2_NO_MEMORY;
+ return;
+ }
+ memcpy(hdr10PlusInfo->m.value, payload.data(), payload.size());
+
+ // config if hdr10Plus info has changed
+ if (nullptr == mHdr10PlusInfo || !(*hdr10PlusInfo == *mHdr10PlusInfo)) {
+ mHdr10PlusInfo = std::move(hdr10PlusInfo);
+ work->worklets.front()->output.configUpdate.push_back(std::move(mHdr10PlusInfo));
+ }
+ }
+}
+
void C2SoftGav1Dec::getVuiParams(const libgav1::DecoderBuffer *buffer) {
VuiColorAspects vuiColorAspects;
vuiColorAspects.primaries = buffer->color_primary;
@@ -633,6 +768,9 @@
}
getVuiParams(buffer);
+ getHDRStaticParams(buffer, work);
+ getHDR10PlusInfoData(buffer, work);
+
if (!(buffer->image_format == libgav1::kImageFormatYuv420 ||
buffer->image_format == libgav1::kImageFormatMonochrome400)) {
ALOGE("image_format %d not supported", buffer->image_format);
diff --git a/media/codec2/components/gav1/C2SoftGav1Dec.h b/media/codec2/components/gav1/C2SoftGav1Dec.h
index 3d4db55..f0e14d7 100644
--- a/media/codec2/components/gav1/C2SoftGav1Dec.h
+++ b/media/codec2/components/gav1/C2SoftGav1Dec.h
@@ -23,8 +23,8 @@
#include <SimpleC2Component.h>
#include <C2Config.h>
-#include "libgav1/src/gav1/decoder.h"
-#include "libgav1/src/gav1/decoder_settings.h"
+#include <gav1/decoder.h>
+#include <gav1/decoder_settings.h>
namespace android {
@@ -61,6 +61,9 @@
bool mSignalledOutputEos;
bool mSignalledError;
+ C2StreamHdrStaticMetadataInfo::output mHdrStaticMetadataInfo;
+ std::unique_ptr<C2StreamHdr10PlusInfo::output> mHdr10PlusInfo = nullptr;
+
// Color aspects. These are ISO values and are meant to detect changes in aspects to avoid
// converting them to C2 values for each frame
struct VuiColorAspects {
@@ -86,6 +89,10 @@
nsecs_t mTimeEnd = 0; // Time at the end of decode()
bool initDecoder();
+ void getHDRStaticParams(const libgav1::DecoderBuffer *buffer,
+ const std::unique_ptr<C2Work> &work);
+ void getHDR10PlusInfoData(const libgav1::DecoderBuffer *buffer,
+ const std::unique_ptr<C2Work> &work);
void getVuiParams(const libgav1::DecoderBuffer *buffer);
void destroyDecoder();
void finishWork(uint64_t index, const std::unique_ptr<C2Work>& work,
diff --git a/media/codec2/components/hevc/C2SoftHevcDec.cpp b/media/codec2/components/hevc/C2SoftHevcDec.cpp
index 5a660c5..15d6dcd 100644
--- a/media/codec2/components/hevc/C2SoftHevcDec.cpp
+++ b/media/codec2/components/hevc/C2SoftHevcDec.cpp
@@ -664,6 +664,9 @@
void C2SoftHevcDec::resetPlugin() {
mSignalledOutputEos = false;
mTimeStart = mTimeEnd = systemTime();
+ if (mOutBlock) {
+ mOutBlock.reset();
+ }
}
status_t C2SoftHevcDec::deleteDecoder() {
@@ -917,7 +920,8 @@
if (0 < ps_decode_op->u4_pic_wd && 0 < ps_decode_op->u4_pic_ht) {
if (mHeaderDecoded == false) {
mHeaderDecoded = true;
- setParams(ALIGN128(ps_decode_op->u4_pic_wd), IVD_DECODE_FRAME);
+ mStride = ALIGN128(ps_decode_op->u4_pic_wd);
+ setParams(mStride, IVD_DECODE_FRAME);
}
if (ps_decode_op->u4_pic_wd != mWidth || ps_decode_op->u4_pic_ht != mHeight) {
mWidth = ps_decode_op->u4_pic_wd;
diff --git a/media/codec2/components/hevc/C2SoftHevcEnc.cpp b/media/codec2/components/hevc/C2SoftHevcEnc.cpp
index 60d5875..9c26c02 100644
--- a/media/codec2/components/hevc/C2SoftHevcEnc.cpp
+++ b/media/codec2/components/hevc/C2SoftHevcEnc.cpp
@@ -1109,14 +1109,14 @@
}
}
- std::shared_ptr<const C2GraphicView> view;
+ std::shared_ptr<C2GraphicView> view;
std::shared_ptr<C2Buffer> inputBuffer = nullptr;
bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
if (eos) mSignalledEos = true;
if (!work->input.buffers.empty()) {
inputBuffer = work->input.buffers[0];
- view = std::make_shared<const C2GraphicView>(
+ view = std::make_shared<C2GraphicView>(
inputBuffer->data().graphicBlocks().front().map().get());
if (view->error() != C2_OK) {
ALOGE("graphic view map err = %d", view->error());
@@ -1125,6 +1125,9 @@
work->workletsProcessed = 1u;
return;
}
+ //(b/232396154)
+ //workaround for incorrect crop size in view when using surface mode
+ view->setCrop_be(C2Rect(mSize->width, mSize->height));
}
IHEVCE_PLUGIN_STATUS_T err = IHEVCE_EOK;
diff --git a/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp b/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp
index 9a41910..439323c 100644
--- a/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp
+++ b/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp
@@ -732,6 +732,9 @@
void C2SoftMpeg2Dec::resetPlugin() {
mSignalledOutputEos = false;
mTimeStart = mTimeEnd = systemTime();
+ if (mOutBlock) {
+ mOutBlock.reset();
+ }
}
status_t C2SoftMpeg2Dec::deleteDecoder() {
diff --git a/media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.cpp b/media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.cpp
index 54a1d0e..3bf9c48 100644
--- a/media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.cpp
+++ b/media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.cpp
@@ -256,7 +256,9 @@
mFramesConfigured = false;
mSignalledOutputEos = false;
mSignalledError = false;
-
+ if (mOutBlock) {
+ mOutBlock.reset();
+ }
return C2_OK;
}
diff --git a/media/codec2/components/mpeg4_h263/C2SoftMpeg4Enc.cpp b/media/codec2/components/mpeg4_h263/C2SoftMpeg4Enc.cpp
index 3bfec66..d5e8c56 100644
--- a/media/codec2/components/mpeg4_h263/C2SoftMpeg4Enc.cpp
+++ b/media/codec2/components/mpeg4_h263/C2SoftMpeg4Enc.cpp
@@ -464,18 +464,21 @@
}
}
- std::shared_ptr<const C2GraphicView> rView;
+ std::shared_ptr<C2GraphicView> rView;
std::shared_ptr<C2Buffer> inputBuffer;
bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
if (!work->input.buffers.empty()) {
inputBuffer = work->input.buffers[0];
- rView = std::make_shared<const C2GraphicView>(
+ rView = std::make_shared<C2GraphicView>(
inputBuffer->data().graphicBlocks().front().map().get());
if (rView->error() != C2_OK) {
ALOGE("graphic view map err = %d", rView->error());
work->result = rView->error();
return;
}
+ //(b/232396154)
+ //workaround for incorrect crop size in view when using surface mode
+ rView->setCrop_be(C2Rect(mSize->width, mSize->height));
} else {
fillEmptyWork(work);
if (eos) {
diff --git a/media/codec2/components/vpx/C2SoftVpxEnc.cpp b/media/codec2/components/vpx/C2SoftVpxEnc.cpp
index f99ee24..5700e5d 100644
--- a/media/codec2/components/vpx/C2SoftVpxEnc.cpp
+++ b/media/codec2/components/vpx/C2SoftVpxEnc.cpp
@@ -59,7 +59,7 @@
addParameter(
DefineParam(mSize, C2_PARAMKEY_PICTURE_SIZE)
- .withDefault(new C2StreamPictureSizeInfo::input(0u, 320, 240))
+ .withDefault(new C2StreamPictureSizeInfo::input(0u, 64, 64))
.withFields({
C2F(mSize, width).inRange(2, 2048, 2),
C2F(mSize, height).inRange(2, 2048, 2),
@@ -81,7 +81,7 @@
addParameter(
DefineParam(mFrameRate, C2_PARAMKEY_FRAME_RATE)
- .withDefault(new C2StreamFrameRateInfo::output(0u, 30.))
+ .withDefault(new C2StreamFrameRateInfo::output(0u, 1.))
// TODO: More restriction?
.withFields({C2F(mFrameRate, value).greaterThan(0.)})
.withSetter(
@@ -127,10 +127,18 @@
C2F(mProfileLevel, profile).equalTo(
PROFILE_VP9_0
),
- C2F(mProfileLevel, level).equalTo(
- LEVEL_VP9_4_1),
+ C2F(mProfileLevel, level).oneOf({
+ C2Config::LEVEL_VP9_1,
+ C2Config::LEVEL_VP9_1_1,
+ C2Config::LEVEL_VP9_2,
+ C2Config::LEVEL_VP9_2_1,
+ C2Config::LEVEL_VP9_3,
+ C2Config::LEVEL_VP9_3_1,
+ C2Config::LEVEL_VP9_4,
+ C2Config::LEVEL_VP9_4_1,
+ }),
})
- .withSetter(ProfileLevelSetter)
+ .withSetter(ProfileLevelSetter, mSize, mFrameRate, mBitrate)
.build());
#else
addParameter(
@@ -144,7 +152,7 @@
C2F(mProfileLevel, level).equalTo(
LEVEL_UNUSED),
})
- .withSetter(ProfileLevelSetter)
+ .withSetter(ProfileLevelSetter, mSize, mFrameRate, mBitrate)
.build());
#endif
addParameter(
@@ -217,14 +225,81 @@
}
C2R C2SoftVpxEnc::IntfImpl::ProfileLevelSetter(bool mayBlock,
- C2P<C2StreamProfileLevelInfo::output>& me) {
+ C2P<C2StreamProfileLevelInfo::output>& me,
+ const C2P<C2StreamPictureSizeInfo::input>& size,
+ const C2P<C2StreamFrameRateInfo::output>& frameRate,
+ const C2P<C2StreamBitrateInfo::output>& bitrate) {
(void)mayBlock;
+#ifdef VP9
if (!me.F(me.v.profile).supportsAtAll(me.v.profile)) {
me.set().profile = PROFILE_VP9_0;
}
- if (!me.F(me.v.level).supportsAtAll(me.v.level)) {
+ struct LevelLimits {
+ C2Config::level_t level;
+ float samplesPerSec;
+ uint64_t samples;
+ uint32_t bitrate;
+ size_t dimension;
+ };
+ constexpr LevelLimits kLimits[] = {
+ {LEVEL_VP9_1, 829440, 36864, 200000, 512},
+ {LEVEL_VP9_1_1, 2764800, 73728, 800000, 768},
+ {LEVEL_VP9_2, 4608000, 122880, 1800000, 960},
+ {LEVEL_VP9_2_1, 9216000, 245760, 3600000, 1344},
+ {LEVEL_VP9_3, 20736000, 552960, 7200000, 2048},
+ {LEVEL_VP9_3_1, 36864000, 983040, 12000000, 2752},
+ {LEVEL_VP9_4, 83558400, 2228224, 18000000, 4160},
+ {LEVEL_VP9_4_1, 160432128, 2228224, 30000000, 4160},
+ };
+
+ uint64_t samples = size.v.width * size.v.height;
+ float samplesPerSec = float(samples) * frameRate.v.value;
+ size_t dimension = std::max(size.v.width, size.v.height);
+
+ // Check if the supplied level meets the samples / bitrate requirements.
+ // If not, update the level with the lowest level meeting the requirements.
+ bool found = false;
+
+ // By default needsUpdate = false in case the supplied level does meet
+ // the requirements.
+ bool needsUpdate = false;
+ for (const LevelLimits& limit : kLimits) {
+ if (samples <= limit.samples && samplesPerSec <= limit.samplesPerSec &&
+ bitrate.v.value <= limit.bitrate && dimension <= limit.dimension) {
+ // This is the lowest level that meets the requirements, and if
+ // we haven't seen the supplied level yet, that means we don't
+ // need the update.
+ if (needsUpdate) {
+ ALOGD("Given level %x does not cover current configuration: "
+ "adjusting to %x",
+ me.v.level, limit.level);
+ me.set().level = limit.level;
+ }
+ found = true;
+ break;
+ }
+ if (me.v.level == limit.level) {
+ // We break out of the loop when the lowest feasible level is
+ // found. The fact that we're here means that our level doesn't
+ // meet the requirement and needs to be updated.
+ needsUpdate = true;
+ }
+ }
+ if (!found) {
+ // We set to the highest supported level.
me.set().level = LEVEL_VP9_4_1;
}
+#else
+ (void)size;
+ (void)frameRate;
+ (void)bitrate;
+ if (!me.F(me.v.profile).supportsAtAll(me.v.profile)) {
+ me.set().profile = PROFILE_VP8_0;
+ }
+ if (!me.F(me.v.level).supportsAtAll(me.v.level)) {
+ me.set().level = LEVEL_UNUSED;
+ }
+#endif
return C2R::Ok();
}
@@ -683,17 +758,20 @@
return;
}
- std::shared_ptr<const C2GraphicView> rView;
+ std::shared_ptr<C2GraphicView> rView;
std::shared_ptr<C2Buffer> inputBuffer;
if (!work->input.buffers.empty()) {
inputBuffer = work->input.buffers[0];
- rView = std::make_shared<const C2GraphicView>(
+ rView = std::make_shared<C2GraphicView>(
inputBuffer->data().graphicBlocks().front().map().get());
if (rView->error() != C2_OK) {
ALOGE("graphic view map err = %d", rView->error());
work->result = C2_CORRUPTED;
return;
}
+ //(b/232396154)
+ //workaround for incorrect crop size in view when using surface mode
+ rView->setCrop_be(C2Rect(mSize->width, mSize->height));
} else {
ALOGV("Empty input Buffer");
uint32_t flags = 0;
diff --git a/media/codec2/components/vpx/C2SoftVpxEnc.h b/media/codec2/components/vpx/C2SoftVpxEnc.h
index 714fadb..bfb4444 100644
--- a/media/codec2/components/vpx/C2SoftVpxEnc.h
+++ b/media/codec2/components/vpx/C2SoftVpxEnc.h
@@ -243,9 +243,10 @@
static C2R SizeSetter(bool mayBlock, const C2P<C2StreamPictureSizeInfo::input> &oldMe,
C2P<C2StreamPictureSizeInfo::input> &me);
- static C2R ProfileLevelSetter(
- bool mayBlock,
- C2P<C2StreamProfileLevelInfo::output> &me);
+ static C2R ProfileLevelSetter(bool mayBlock, C2P<C2StreamProfileLevelInfo::output>& me,
+ const C2P<C2StreamPictureSizeInfo::input>& size,
+ const C2P<C2StreamFrameRateInfo::output>& frameRate,
+ const C2P<C2StreamBitrateInfo::output>& bitrate);
static C2R LayeringSetter(bool mayBlock, C2P<C2StreamTemporalLayeringTuning::output>& me);
diff --git a/media/codec2/fuzzer/C2Fuzzer.cpp b/media/codec2/fuzzer/C2Fuzzer.cpp
index e469d8b..d6793e0 100644
--- a/media/codec2/fuzzer/C2Fuzzer.cpp
+++ b/media/codec2/fuzzer/C2Fuzzer.cpp
@@ -246,7 +246,8 @@
bufferSource->parse();
c2_status_t status = C2_OK;
size_t numFrames = 0;
- while (!bufferSource->isEos()) {
+ int32_t iterationCount = 0;
+ while (!bufferSource->isEos() && ++iterationCount <= kMaxIterations) {
uint8_t* frame = nullptr;
size_t frameSize = 0;
FrameData frameData = bufferSource->getFrame();
diff --git a/media/codec2/fuzzer/C2Fuzzer.h b/media/codec2/fuzzer/C2Fuzzer.h
index da76885..4e3e3ea 100644
--- a/media/codec2/fuzzer/C2Fuzzer.h
+++ b/media/codec2/fuzzer/C2Fuzzer.h
@@ -37,6 +37,7 @@
#define C2FUZZER_ALIGN(_sz, _align) (((_sz) + ((_align)-1)) & ~((_align)-1))
constexpr std::chrono::milliseconds kC2FuzzerTimeOut = 5000ms;
+constexpr int32_t kMaxIterations = 100;
constexpr int32_t kNumberOfC2WorkItems = 8;
constexpr uint32_t kWidthOfVideo = 3840;
constexpr uint32_t kHeightOfVideo = 2160;
diff --git a/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioEncTest.cpp b/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioEncTest.cpp
index bd7ec0d..327717b 100644
--- a/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioEncTest.cpp
+++ b/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioEncTest.cpp
@@ -372,9 +372,8 @@
ULock l(queueLock);
flushedIndices.emplace_back(frameID);
}
- char* data = (char*)malloc(bytesCount);
- ASSERT_NE(data, nullptr);
- eleStream.read(data, bytesCount);
+ std::vector<char> eleData(bytesCount);
+ eleStream.read(eleData.data(), bytesCount);
// if we have reached at the end of input stream, signal eos
if (eleStream.gcount() < bytesCount) {
bytesCount = eleStream.gcount();
@@ -396,12 +395,11 @@
ASSERT_EQ(0u, view.offset());
ASSERT_EQ((size_t)bytesCount, view.size());
- memcpy(view.base(), data, bytesCount);
+ memcpy(view.base(), eleData.data(), bytesCount);
work->input.buffers.clear();
work->input.buffers.emplace_back(new LinearBuffer(block));
work->worklets.clear();
work->worklets.emplace_back(new C2Worklet);
- free(data);
std::list<std::unique_ptr<C2Work>> items;
items.push_back(std::move(work));
diff --git a/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp
index 67873fa..117d9ca 100644
--- a/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp
+++ b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp
@@ -214,10 +214,8 @@
calc_md5_cksum(uPlane, uvStride, cropWidth / 2, cropHeight / 2, au1_u_chksum);
calc_md5_cksum(vPlane, uvStride, cropWidth / 2, cropHeight / 2, au1_v_chksum);
} else if (bitDepth == 8 && layoutType == C2PlanarLayout::TYPE_YUV && colInc == 2) {
- uint8_t* cbPlane = (uint8_t*)malloc(cropWidth * cropHeight / 4);
- uint8_t* crPlane = (uint8_t*)malloc(cropWidth * cropHeight / 4);
- ASSERT_NE(cbPlane, nullptr);
- ASSERT_NE(crPlane, nullptr);
+ std::vector<uint8_t> cbPlane(cropWidth * cropHeight / 4);
+ std::vector<uint8_t> crPlane(cropWidth * cropHeight / 4);
size_t count = 0;
for (size_t k = 0; k < (cropHeight / 2); k++) {
for (size_t l = 0; l < (cropWidth); l = l + 2) {
@@ -227,10 +225,10 @@
}
}
calc_md5_cksum(yPlane, yStride, cropWidth, cropHeight, au1_y_chksum);
- calc_md5_cksum(cbPlane, cropWidth / 2, cropWidth / 2, cropHeight / 2, au1_u_chksum);
- calc_md5_cksum(crPlane, cropWidth / 2, cropWidth / 2, cropHeight / 2, au1_v_chksum);
- free(cbPlane);
- free(crPlane);
+ calc_md5_cksum(cbPlane.data(), cropWidth / 2, cropWidth / 2, cropHeight / 2,
+ au1_u_chksum);
+ calc_md5_cksum(crPlane.data(), cropWidth / 2, cropWidth / 2, cropHeight / 2,
+ au1_v_chksum);
} else {
mMd5Enable = false;
ALOGV("Disabling MD5 chksm flag");
diff --git a/media/codec2/hidl/plugin/samples/Android.bp b/media/codec2/hidl/plugin/samples/Android.bp
index 32b760d..e0f8280 100644
--- a/media/codec2/hidl/plugin/samples/Android.bp
+++ b/media/codec2/hidl/plugin/samples/Android.bp
@@ -28,6 +28,7 @@
"libGLESv1_CM",
"libGLESv2",
"libGLESv3",
+ "libvulkan",
"libbase",
"libcodec2",
"libcutils",
diff --git a/media/codec2/hidl/plugin/samples/SampleFilterPlugin.cpp b/media/codec2/hidl/plugin/samples/SampleFilterPlugin.cpp
index 5c13b0e..c8997bb 100644
--- a/media/codec2/hidl/plugin/samples/SampleFilterPlugin.cpp
+++ b/media/codec2/hidl/plugin/samples/SampleFilterPlugin.cpp
@@ -417,6 +417,7 @@
}
std::unique_lock lock(mQueueMutex);
mQueue.splice(mQueue.end(), *items);
+ mQueueCondition.notify_all();
return C2_OK;
}
@@ -665,6 +666,7 @@
grallocHandle, GraphicBuffer::CLONE_HANDLE,
width, height, format, 1, usage, stride);
+ native_handle_delete(grallocHandle);
std::shared_ptr<C2GraphicBlock> dstBlock;
C2BlockPool::local_id_t poolId = mIntf->getPoolId();
std::shared_ptr<C2BlockPool> pool;
@@ -683,6 +685,7 @@
grallocHandle, GraphicBuffer::CLONE_HANDLE,
width, height, format, 1, usage, stride);
+ native_handle_delete(grallocHandle);
Rect sourceCrop(0, 0, width, height);
renderengine::DisplaySettings clientCompositionDisplay;
diff --git a/media/codec2/hidl/services/Android.bp b/media/codec2/hidl/services/Android.bp
index b36e80a..524519c 100644
--- a/media/codec2/hidl/services/Android.bp
+++ b/media/codec2/hidl/services/Android.bp
@@ -85,6 +85,9 @@
arm64: {
src: "seccomp_policy/android.hardware.media.c2@1.2-default-arm64.policy",
},
+ riscv64: {
+ src: "seccomp_policy/android.hardware.media.c2@1.2-default-riscv64.policy",
+ },
x86: {
src: "seccomp_policy/android.hardware.media.c2@1.2-default-x86.policy",
},
@@ -96,3 +99,4 @@
// This may be removed.
required: ["crash_dump.policy"],
}
+
diff --git a/media/codec2/hidl/services/seccomp_policy/android.hardware.media.c2@1.2-default-riscv64.policy b/media/codec2/hidl/services/seccomp_policy/android.hardware.media.c2@1.2-default-riscv64.policy
new file mode 100644
index 0000000..27f0b95
--- /dev/null
+++ b/media/codec2/hidl/services/seccomp_policy/android.hardware.media.c2@1.2-default-riscv64.policy
@@ -0,0 +1,75 @@
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+futex: 1
+# ioctl calls are filtered via the selinux policy.
+ioctl: 1
+sched_yield: 1
+close: 1
+dup: 1
+ppoll: 1
+mprotect: arg2 in ~PROT_EXEC || arg2 in ~PROT_WRITE
+mmap: arg2 in ~PROT_EXEC || arg2 in ~PROT_WRITE
+getuid: 1
+getrlimit: 1
+fstat: 1
+newfstatat: 1
+fstatfs: 1
+memfd_create: 1
+ftruncate: 1
+
+mremap: arg3 == 3 || arg3 == MREMAP_MAYMOVE
+munmap: 1
+prctl: 1
+writev: 1
+sigaltstack: 1
+clone: 1
+exit: 1
+lseek: 1
+rt_sigprocmask: 1
+openat: 1
+write: 1
+nanosleep: 1
+setpriority: 1
+set_tid_address: 1
+getdents64: 1
+readlinkat: 1
+read: 1
+pread64: 1
+gettimeofday: 1
+faccessat: 1
+exit_group: 1
+restart_syscall: 1
+rt_sigreturn: 1
+getrandom: 1
+madvise: 1
+
+# crash dump policy additions
+clock_gettime: 1
+getpid: 1
+gettid: 1
+pipe2: 1
+recvmsg: 1
+process_vm_readv: 1
+tgkill: 1
+rt_sigaction: 1
+rt_tgsigqueueinfo: 1
+#mprotect: arg2 in 0x1|0x2
+munmap: 1
+#mmap: arg2 in 0x1|0x2
+geteuid: 1
+getgid: 1
+getegid: 1
+getgroups: 1
+
diff --git a/media/codec2/sfplugin/Android.bp b/media/codec2/sfplugin/Android.bp
index 5a652a3..ecd5463 100644
--- a/media/codec2/sfplugin/Android.bp
+++ b/media/codec2/sfplugin/Android.bp
@@ -44,7 +44,7 @@
],
static_libs: [
- "SurfaceFlingerProperties",
+ "libSurfaceFlingerProperties",
],
shared_libs: [
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp
index 72301db..a008dc2 100644
--- a/media/codec2/sfplugin/CCodec.cpp
+++ b/media/codec2/sfplugin/CCodec.cpp
@@ -1014,7 +1014,7 @@
C2StoreFlexiblePixelFormatDescriptorsInfo *pixelFormatInfo = nullptr;
int vendorSdkVersion = base::GetIntProperty(
"ro.vendor.build.version.sdk", android_get_device_api_level());
- if (vendorSdkVersion >= __ANDROID_API_S__ && mClient->query(
+ if (mClient->query(
{},
{C2StoreFlexiblePixelFormatDescriptorsInfo::PARAM_TYPE},
C2_MAY_BLOCK,
@@ -1075,8 +1075,7 @@
} else {
if ((config->mDomain & Config::IS_ENCODER) || !surface) {
if (vendorSdkVersion < __ANDROID_API_S__ &&
- (format == COLOR_FormatYUV420Flexible ||
- format == COLOR_FormatYUV420Planar ||
+ (format == COLOR_FormatYUV420Planar ||
format == COLOR_FormatYUV420PackedPlanar ||
format == COLOR_FormatYUV420SemiPlanar ||
format == COLOR_FormatYUV420PackedSemiPlanar)) {
diff --git a/media/codec2/sfplugin/CCodecBuffers.h b/media/codec2/sfplugin/CCodecBuffers.h
index c8e9930..6335f13 100644
--- a/media/codec2/sfplugin/CCodecBuffers.h
+++ b/media/codec2/sfplugin/CCodecBuffers.h
@@ -72,7 +72,7 @@
virtual void getArray(Vector<sp<MediaCodecBuffer>> *) const {}
/**
- * Return number of buffers the client owns.
+ * Return number of buffers owned by the client or the component.
*/
virtual size_t numActiveSlots() const = 0;
@@ -595,8 +595,7 @@
void flush();
/**
- * Return the number of buffers that are sent to the client but not released
- * yet.
+ * Return the number of buffers that are sent to the client or the component.
*/
size_t numActiveSlots() const;
@@ -716,8 +715,7 @@
void grow(size_t newSize, std::function<sp<Codec2Buffer>()> alloc);
/**
- * Return the number of buffers that are sent to the client but not released
- * yet.
+ * Return the number of buffers that are sent to the client or the component.
*/
size_t numActiveSlots() const;
diff --git a/media/codec2/sfplugin/CCodecConfig.cpp b/media/codec2/sfplugin/CCodecConfig.cpp
index 5208be6..0253815 100644
--- a/media/codec2/sfplugin/CCodecConfig.cpp
+++ b/media/codec2/sfplugin/CCodecConfig.cpp
@@ -389,7 +389,7 @@
// read back always as int
float value;
if (v.get(&value)) {
- return (int32_t)value;
+ return (int32_t) (value + 0.5);
}
return C2Value();
}));
diff --git a/media/codec2/sfplugin/Codec2Buffer.cpp b/media/codec2/sfplugin/Codec2Buffer.cpp
index 55e0c45..b9270de 100644
--- a/media/codec2/sfplugin/Codec2Buffer.cpp
+++ b/media/codec2/sfplugin/Codec2Buffer.cpp
@@ -533,7 +533,7 @@
* align(mHeight, 64) / plane.rowSampling;
}
- if (minPtr == mView.data()[0] && (maxPtr - minPtr + 1) <= planeSize) {
+ if (minPtr == mView.data()[0] && (maxPtr - minPtr) <= planeSize) {
// FIXME: this is risky as reading/writing data out of bound results
// in an undefined behavior, but gralloc does assume a
// contiguous mapping
@@ -545,8 +545,7 @@
mediaImage->mPlane[i].mHorizSubsampling = plane.colSampling;
mediaImage->mPlane[i].mVertSubsampling = plane.rowSampling;
}
- mWrapped = new ABuffer(const_cast<uint8_t *>(minPtr),
- maxPtr - minPtr + 1);
+ mWrapped = new ABuffer(const_cast<uint8_t *>(minPtr), maxPtr - minPtr);
ALOGV("Converter: wrapped (capacity=%zu)", mWrapped->capacity());
}
}
@@ -843,6 +842,10 @@
}
}
sp<ABuffer> aBuffer(alloc(align(width, 16) * align(height, 16) * bpp / 8));
+ if (aBuffer == nullptr) {
+ ALOGD("%s: failed to allocate buffer", __func__);
+ return nullptr;
+ }
return new ConstGraphicBlockBuffer(
format,
aBuffer,
diff --git a/media/codec2/sfplugin/utils/Codec2CommonUtils.cpp b/media/codec2/sfplugin/utils/Codec2CommonUtils.cpp
index ef5800d..332d3ac 100644
--- a/media/codec2/sfplugin/utils/Codec2CommonUtils.cpp
+++ b/media/codec2/sfplugin/utils/Codec2CommonUtils.cpp
@@ -38,7 +38,7 @@
!strcmp(deviceCodeName, "Tiramisu");
}
-bool isVendorApiOrFirstApiAtLeastT() {
+static bool isP010Allowed() {
// The first SDK the device shipped with.
static const int32_t kProductFirstApiLevel =
base::GetIntProperty<int32_t>("ro.product.first_api_level", 0);
@@ -47,6 +47,17 @@
// to signal which VSR requirements they conform to even if the first device SDK was higher.
static const int32_t kBoardFirstApiLevel =
base::GetIntProperty<int32_t>("ro.board.first_api_level", 0);
+
+ // Some devices that launched prior to Android S may not support P010 correctly, even
+ // though they may advertise it as supported.
+ if (kProductFirstApiLevel != 0 && kProductFirstApiLevel < __ANDROID_API_S__) {
+ return false;
+ }
+
+ if (kBoardFirstApiLevel != 0 && kBoardFirstApiLevel < __ANDROID_API_S__) {
+ return false;
+ }
+
static const int32_t kBoardApiLevel =
base::GetIntProperty<int32_t>("ro.board.api_level", 0);
@@ -67,7 +78,7 @@
// API alone. For now limit P010 to devices that launched with Android T or known to conform
// to Android T VSR (as opposed to simply limiting to a T vendor image).
if (format == (AHardwareBuffer_Format)HAL_PIXEL_FORMAT_YCBCR_P010 &&
- !isVendorApiOrFirstApiAtLeastT()) {
+ !isP010Allowed()) {
return false;
}
diff --git a/media/codec2/tests/Android.bp b/media/codec2/tests/Android.bp
index 9c3ba4d..2217235 100644
--- a/media/codec2/tests/Android.bp
+++ b/media/codec2/tests/Android.bp
@@ -36,6 +36,8 @@
cc_test {
name: "codec2_vndk_test",
test_suites: ["device-tests"],
+ // This test doesn't seem to support isolated with current assumption
+ isolated: false,
srcs: [
"C2_test.cpp",
diff --git a/media/codec2/vndk/C2AllocatorGralloc.cpp b/media/codec2/vndk/C2AllocatorGralloc.cpp
index bc4053d..f272499 100644
--- a/media/codec2/vndk/C2AllocatorGralloc.cpp
+++ b/media/codec2/vndk/C2AllocatorGralloc.cpp
@@ -54,6 +54,10 @@
static_assert((~C2MemoryUsage::PLATFORM_MASK & PASSTHROUGH_USAGE_MASK) == 0, "");
} // unnamed
+static bool isAtLeastT() {
+ return android_get_device_api_level() >= __ANDROID_API_T__;
+}
+
C2MemoryUsage C2AndroidMemoryUsage::FromGrallocUsage(uint64_t usage) {
// gralloc does not support WRITE_PROTECTED
return C2MemoryUsage(
@@ -702,6 +706,14 @@
}
case static_cast<uint32_t>(PixelFormat4::YCBCR_P010): {
+ // In Android T, P010 is relaxed to allow arbitrary stride for the Y and UV planes,
+ // try locking with the gralloc4 mapper first.
+ c2_status_t status = Gralloc4Mapper_lock(
+ const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, layout, addr);
+ if (status == C2_OK) {
+ break;
+ }
+
void *pointer = nullptr;
status_t err = GraphicBufferMapper::get().lock(
const_cast<native_handle_t *>(mBuffer), grallocUsage, rect, &pointer);
@@ -760,10 +772,12 @@
default: {
// We don't know what it is, let's try to lock it with gralloc4
android_ycbcr ycbcrLayout;
- c2_status_t status = Gralloc4Mapper_lock(
- const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, layout, addr);
- if (status == C2_OK) {
- break;
+ if (isAtLeastT()) {
+ c2_status_t status = Gralloc4Mapper_lock(
+ const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, layout, addr);
+ if (status == C2_OK) {
+ break;
+ }
}
// fallback to lockYCbCr
diff --git a/media/codec2/vndk/C2Fence.cpp b/media/codec2/vndk/C2Fence.cpp
index 0b556aa..aa908a8 100644
--- a/media/codec2/vndk/C2Fence.cpp
+++ b/media/codec2/vndk/C2Fence.cpp
@@ -186,7 +186,7 @@
class _C2FenceFactory::SyncFenceImpl : public C2Fence::Impl {
public:
virtual c2_status_t wait(c2_nsecs_t timeoutNs) {
- c2_nsecs_t timeoutMs = timeoutNs / 1000;
+ int64_t timeoutMs = timeoutNs / 1000000;
if (timeoutMs > INT_MAX) {
timeoutMs = INT_MAX;
}
diff --git a/media/janitors/avic_OWNERS b/media/janitors/avic_OWNERS
new file mode 100644
index 0000000..eca9978
--- /dev/null
+++ b/media/janitors/avic_OWNERS
@@ -0,0 +1,6 @@
+# Bug component: 1344
+# gerrit owner/approvers in the AVIC team
+arifdikici@google.com
+dichenzhang@google.com
+kyslov@google.com
+richardxie@google.com
diff --git a/media/janitors/media_solutions_OWNERS b/media/janitors/media_solutions_OWNERS
index 8dc1c7b..e0c87f7 100644
--- a/media/janitors/media_solutions_OWNERS
+++ b/media/janitors/media_solutions_OWNERS
@@ -1,10 +1,21 @@
# Bug component: 1344
# go/android-fwk-media-solutions for info on areas of ownership.
-# Main owners:
+# MediaRouter and native mirroring only:
+adadukin@google.com
aquilescanta@google.com
-krocard@google.com
+bishoygendy@google.com
+ivanbuper@google.com
-# In case of emergency:
-andrewlewis@google.com #{LAST_RESORT_SUGGESTION}
-olly@google.com #{LAST_RESORT_SUGGESTION}
+# MediaMuxer, MediaRecorder, and seamless transcoding only:
+andrewlewis@google.com
+claincly@google.com
+
+# Everything in go/android-fwk-media-solutions not covered above:
+bachinger@google.com
+christosts@google.com
+ibaker@google.com
+michaelkatz@google.com
+rohks@google.com
+tianyifeng@google.com
+tonihei@google.com
diff --git a/media/libaaudio/Android.bp b/media/libaaudio/Android.bp
index add28e0..4b417a7 100644
--- a/media/libaaudio/Android.bp
+++ b/media/libaaudio/Android.bp
@@ -36,6 +36,9 @@
symbol_file: "src/libaaudio.map.txt",
first_version: "26",
unversioned_until: "current",
+ export_header_libs: [
+ "libAAudio_headers",
+ ],
}
cc_library_headers {
diff --git a/media/libaaudio/fuzzer/Android.bp b/media/libaaudio/fuzzer/Android.bp
index 2a12191..3393930 100644
--- a/media/libaaudio/fuzzer/Android.bp
+++ b/media/libaaudio/fuzzer/Android.bp
@@ -25,6 +25,9 @@
cc_fuzz {
name: "libaaudio_fuzzer",
+ defaults: [
+ "latest_android_media_audio_common_types_cpp_static",
+ ],
srcs: [
"libaaudio_fuzzer.cpp",
],
@@ -36,10 +39,10 @@
"libaudiomanager",
"libaudiopolicy",
"libaudioclient_aidl_conversion",
+ "libaudio_aidl_conversion_common_cpp",
"libutils",
],
static_libs: [
- "android.media.audio.common.types-V1-cpp",
"liblog",
"libcutils",
"libaaudio",
diff --git a/media/libaaudio/include/aaudio/AAudio.h b/media/libaaudio/include/aaudio/AAudio.h
index 2ff9f5a..0c4a8f7 100644
--- a/media/libaaudio/include/aaudio/AAudio.h
+++ b/media/libaaudio/include/aaudio/AAudio.h
@@ -40,7 +40,7 @@
/**
* This is used to represent a value that has not been specified.
* For example, an application could use {@link #AAUDIO_UNSPECIFIED} to indicate
- * that is did not not care what the specific value of a parameter was
+ * that it did not care what the specific value of a parameter was
* and would accept whatever it was given.
*/
#define AAUDIO_UNSPECIFIED 0
diff --git a/media/libaaudio/src/Android.bp b/media/libaaudio/src/Android.bp
index 363d219..4c5fc71 100644
--- a/media/libaaudio/src/Android.bp
+++ b/media/libaaudio/src/Android.bp
@@ -134,6 +134,10 @@
cc_library {
name: "libaaudio_internal",
+ defaults: [
+ "latest_android_media_audio_common_types_cpp_shared",
+ ],
+
local_include_dirs: [
"binding",
"client",
@@ -167,7 +171,6 @@
"libbinder",
"framework-permission-aidl-cpp",
"aaudio-aidl-cpp",
- "android.media.audio.common.types-V1-cpp",
"audioclient-types-aidl-cpp",
"libaudioclient_aidl_conversion",
],
@@ -260,7 +263,7 @@
"binding/aidl/aaudio/IAAudioService.aidl",
],
imports: [
- "android.media.audio.common.types-V1",
+ "android.media.audio.common.types-V2",
"audioclient-types-aidl",
"shared-file-region-aidl",
"framework-permission-aidl",
diff --git a/media/libaaudio/src/client/AudioStreamInternalCapture.cpp b/media/libaaudio/src/client/AudioStreamInternalCapture.cpp
index 1efccb1..f5cc2be 100644
--- a/media/libaaudio/src/client/AudioStreamInternalCapture.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternalCapture.cpp
@@ -25,6 +25,7 @@
#include "client/AudioStreamInternalCapture.h"
#include "utility/AudioClock.h"
+#undef ATRACE_TAG
#define ATRACE_TAG ATRACE_TAG_AUDIO
#include <utils/Trace.h>
diff --git a/media/libaaudio/src/core/AAudioAudio.cpp b/media/libaaudio/src/core/AAudioAudio.cpp
index 90ff4a5..938079b 100644
--- a/media/libaaudio/src/core/AAudioAudio.cpp
+++ b/media/libaaudio/src/core/AAudioAudio.cpp
@@ -566,9 +566,7 @@
int64_t *timeNanoseconds)
{
AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
- if (framePosition == nullptr) {
- return AAUDIO_ERROR_NULL;
- } else if (timeNanoseconds == nullptr) {
+ if (framePosition == nullptr || timeNanoseconds == nullptr) {
return AAUDIO_ERROR_NULL;
} else if (clockid != CLOCK_MONOTONIC && clockid != CLOCK_BOOTTIME) {
return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
diff --git a/media/libaaudio/src/core/AAudioStreamParameters.cpp b/media/libaaudio/src/core/AAudioStreamParameters.cpp
index 8b7b75e..31fd011 100644
--- a/media/libaaudio/src/core/AAudioStreamParameters.cpp
+++ b/media/libaaudio/src/core/AAudioStreamParameters.cpp
@@ -83,7 +83,6 @@
switch (mSessionId) {
case AAUDIO_SESSION_ID_NONE:
case AAUDIO_SESSION_ID_ALLOCATE:
- break;
default:
break;
}
diff --git a/media/libaaudio/tests/test_attributes.cpp b/media/libaaudio/tests/test_attributes.cpp
index b88d562..e5676a7 100644
--- a/media/libaaudio/tests/test_attributes.cpp
+++ b/media/libaaudio/tests/test_attributes.cpp
@@ -20,6 +20,7 @@
// "test_aaudio_attributes.cpp". That other file is more current.
// So these tests could be deleted.
+#include <memory>
#include <stdio.h>
#include <unistd.h>
@@ -40,7 +41,7 @@
int privacyMode = DONT_SET,
aaudio_direction_t direction = AAUDIO_DIRECTION_OUTPUT) {
- float *buffer = new float[kNumFrames * kChannelCount];
+ std::unique_ptr<float[]> buffer(new float[kNumFrames * kChannelCount]);
AAudioStreamBuilder *aaudioBuilder = nullptr;
AAudioStream *aaudioStream = nullptr;
@@ -109,16 +110,15 @@
if (direction == AAUDIO_DIRECTION_INPUT) {
EXPECT_EQ(kNumFrames,
- AAudioStream_read(aaudioStream, buffer, kNumFrames, kNanosPerSecond));
+ AAudioStream_read(aaudioStream, buffer.get(), kNumFrames, kNanosPerSecond));
} else {
EXPECT_EQ(kNumFrames,
- AAudioStream_write(aaudioStream, buffer, kNumFrames, kNanosPerSecond));
+ AAudioStream_write(aaudioStream, buffer.get(), kNumFrames, kNanosPerSecond));
}
EXPECT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream));
EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream));
- delete[] buffer;
}
static const aaudio_usage_t sUsages[] = {
diff --git a/media/libaaudio/tests/test_recovery.cpp b/media/libaaudio/tests/test_recovery.cpp
index 6e89f83..11331af 100644
--- a/media/libaaudio/tests/test_recovery.cpp
+++ b/media/libaaudio/tests/test_recovery.cpp
@@ -16,6 +16,7 @@
// Play silence and recover from dead servers or disconnected devices.
+#include <memory>
#include <stdio.h>
#include <aaudio/AAudio.h>
@@ -32,7 +33,6 @@
int32_t triesLeft = 3;
int32_t bufferCapacity;
int32_t framesPerBurst = 0;
- float *buffer = nullptr;
int32_t actualChannelCount = 0;
int32_t actualSampleRate = 0;
@@ -83,7 +83,7 @@
bufferCapacity, framesPerBurst);
int samplesPerBurst = framesPerBurst * actualChannelCount;
- buffer = new float[samplesPerBurst];
+ std::unique_ptr<float[]> buffer(new float[samplesPerBurst]);
result = AAudioStream_requestStart(aaudioStream);
if (result != AAUDIO_OK) {
@@ -98,7 +98,7 @@
int64_t printAt = actualSampleRate;
while (result == AAUDIO_OK && framesTotal < framesMax) {
int32_t framesWritten = AAudioStream_write(aaudioStream,
- buffer, framesPerBurst,
+ buffer.get(), framesPerBurst,
DEFAULT_TIMEOUT_NANOS);
if (framesWritten < 0) {
result = framesWritten;
@@ -134,6 +134,5 @@
AAudioStream_close(aaudioStream);
}
AAudioStreamBuilder_delete(aaudioBuilder);
- delete[] buffer;
printf(" result = %d = %s\n", result, AAudio_convertResultToText(result));
}
diff --git a/media/libaaudio/tests/test_session_id.cpp b/media/libaaudio/tests/test_session_id.cpp
index 3f7d4fc..5968b5d 100644
--- a/media/libaaudio/tests/test_session_id.cpp
+++ b/media/libaaudio/tests/test_session_id.cpp
@@ -16,6 +16,7 @@
// Test AAudio SessionId, which is used to associate Effects with a stream
+#include <memory>
#include <stdio.h>
#include <unistd.h>
@@ -29,7 +30,7 @@
// Test AAUDIO_SESSION_ID_NONE default
static void checkSessionIdNone(aaudio_performance_mode_t perfMode) {
- float *buffer = new float[kNumFrames * kChannelCount];
+ std::unique_ptr<float[]> buffer(new float[kNumFrames * kChannelCount]);
AAudioStreamBuilder *aaudioBuilder = nullptr;
@@ -51,12 +52,12 @@
ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStart(aaudioStream1));
- ASSERT_EQ(kNumFrames, AAudioStream_write(aaudioStream1, buffer, kNumFrames, kNanosPerSecond));
+ ASSERT_EQ(kNumFrames,
+ AAudioStream_write(aaudioStream1, buffer.get(), kNumFrames, kNanosPerSecond));
EXPECT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream1));
EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream1));
- delete[] buffer;
AAudioStreamBuilder_delete(aaudioBuilder);
}
@@ -72,7 +73,7 @@
static void checkSessionIdAllocate(aaudio_performance_mode_t perfMode,
aaudio_direction_t direction) {
- float *buffer = new float[kNumFrames * kChannelCount];
+ std::unique_ptr<float[]> buffer(new float[kNumFrames * kChannelCount]);
AAudioStreamBuilder *aaudioBuilder = nullptr;
@@ -106,10 +107,10 @@
if (direction == AAUDIO_DIRECTION_INPUT) {
ASSERT_EQ(kNumFrames, AAudioStream_read(aaudioStream1,
- buffer, kNumFrames, kNanosPerSecond));
+ buffer.get(), kNumFrames, kNanosPerSecond));
} else {
ASSERT_EQ(kNumFrames, AAudioStream_write(aaudioStream1,
- buffer, kNumFrames, kNanosPerSecond));
+ buffer.get(), kNumFrames, kNanosPerSecond));
}
EXPECT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream1));
@@ -135,10 +136,10 @@
if (otherDirection == AAUDIO_DIRECTION_INPUT) {
ASSERT_EQ(kNumFrames, AAudioStream_read(aaudioStream2,
- buffer, kNumFrames, kNanosPerSecond));
+ buffer.get(), kNumFrames, kNanosPerSecond));
} else {
ASSERT_EQ(kNumFrames, AAudioStream_write(aaudioStream2,
- buffer, kNumFrames, kNanosPerSecond));
+ buffer.get(), kNumFrames, kNanosPerSecond));
}
EXPECT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream2));
@@ -147,7 +148,6 @@
EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream1));
- delete[] buffer;
AAudioStreamBuilder_delete(aaudioBuilder);
}
diff --git a/media/libaudioclient/AidlConversion.cpp b/media/libaudioclient/AidlConversion.cpp
index 4133bd0..f65ff18 100644
--- a/media/libaudioclient/AidlConversion.cpp
+++ b/media/libaudioclient/AidlConversion.cpp
@@ -42,9 +42,6 @@
using media::audio::common::AudioDeviceAddress;
using media::audio::common::AudioDeviceDescription;
using media::audio::common::AudioDeviceType;
-using media::audio::common::AudioEncapsulationMetadataType;
-using media::audio::common::AudioEncapsulationMode;
-using media::audio::common::AudioEncapsulationType;
using media::audio::common::AudioFormatDescription;
using media::audio::common::AudioFormatType;
using media::audio::common::AudioGain;
@@ -138,127 +135,6 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// Converters
-status_t aidl2legacy_string(std::string_view aidl, char* dest, size_t maxSize) {
- if (aidl.size() > maxSize - 1) {
- return BAD_VALUE;
- }
- aidl.copy(dest, aidl.size());
- dest[aidl.size()] = '\0';
- return OK;
-}
-
-ConversionResult<std::string> legacy2aidl_string(const char* legacy, size_t maxSize) {
- if (legacy == nullptr) {
- return unexpected(BAD_VALUE);
- }
- if (strnlen(legacy, maxSize) == maxSize) {
- // No null-terminator.
- return unexpected(BAD_VALUE);
- }
- return std::string(legacy);
-}
-
-ConversionResult<audio_module_handle_t> aidl2legacy_int32_t_audio_module_handle_t(int32_t aidl) {
- return convertReinterpret<audio_module_handle_t>(aidl);
-}
-
-ConversionResult<int32_t> legacy2aidl_audio_module_handle_t_int32_t(audio_module_handle_t legacy) {
- return convertReinterpret<int32_t>(legacy);
-}
-
-ConversionResult<audio_io_handle_t> aidl2legacy_int32_t_audio_io_handle_t(int32_t aidl) {
- return convertReinterpret<audio_io_handle_t>(aidl);
-}
-
-ConversionResult<int32_t> legacy2aidl_audio_io_handle_t_int32_t(audio_io_handle_t legacy) {
- return convertReinterpret<int32_t>(legacy);
-}
-
-ConversionResult<audio_port_handle_t> aidl2legacy_int32_t_audio_port_handle_t(int32_t aidl) {
- return convertReinterpret<audio_port_handle_t>(aidl);
-}
-
-ConversionResult<int32_t> legacy2aidl_audio_port_handle_t_int32_t(audio_port_handle_t legacy) {
- return convertReinterpret<int32_t>(legacy);
-}
-
-ConversionResult<audio_patch_handle_t> aidl2legacy_int32_t_audio_patch_handle_t(int32_t aidl) {
- return convertReinterpret<audio_patch_handle_t>(aidl);
-}
-
-ConversionResult<int32_t> legacy2aidl_audio_patch_handle_t_int32_t(audio_patch_handle_t legacy) {
- return convertReinterpret<int32_t>(legacy);
-}
-
-ConversionResult<audio_unique_id_t> aidl2legacy_int32_t_audio_unique_id_t(int32_t aidl) {
- return convertReinterpret<audio_unique_id_t>(aidl);
-}
-
-ConversionResult<int32_t> legacy2aidl_audio_unique_id_t_int32_t(audio_unique_id_t legacy) {
- return convertReinterpret<int32_t>(legacy);
-}
-
-ConversionResult<audio_hw_sync_t> aidl2legacy_int32_t_audio_hw_sync_t(int32_t aidl) {
- return convertReinterpret<audio_hw_sync_t>(aidl);
-}
-
-ConversionResult<int32_t> legacy2aidl_audio_hw_sync_t_int32_t(audio_hw_sync_t legacy) {
- return convertReinterpret<int32_t>(legacy);
-}
-
-ConversionResult<pid_t> aidl2legacy_int32_t_pid_t(int32_t aidl) {
- return convertReinterpret<pid_t>(aidl);
-}
-
-ConversionResult<int32_t> legacy2aidl_pid_t_int32_t(pid_t legacy) {
- return convertReinterpret<int32_t>(legacy);
-}
-
-ConversionResult<uid_t> aidl2legacy_int32_t_uid_t(int32_t aidl) {
- return convertReinterpret<uid_t>(aidl);
-}
-
-ConversionResult<int32_t> legacy2aidl_uid_t_int32_t(uid_t legacy) {
- return convertReinterpret<int32_t>(legacy);
-}
-
-ConversionResult<String16> aidl2legacy_string_view_String16(std::string_view aidl) {
- return String16(aidl.data(), aidl.size());
-}
-
-ConversionResult<std::string> legacy2aidl_String16_string(const String16& legacy) {
- return std::string(String8(legacy).c_str());
-}
-
-// TODO b/182392769: create an optional -> optional util
-ConversionResult<std::optional<String16>>
-aidl2legacy_optional_string_view_optional_String16(std::optional<std::string_view> aidl) {
- if (!aidl.has_value()) {
- return std::nullopt;
- }
- ConversionResult<String16> conversion =
- VALUE_OR_RETURN(aidl2legacy_string_view_String16(aidl.value()));
- return conversion.value();
-}
-
-ConversionResult<std::optional<std::string_view>>
-legacy2aidl_optional_String16_optional_string(std::optional<String16> legacy) {
- if (!legacy.has_value()) {
- return std::nullopt;
- }
- ConversionResult<std::string> conversion =
- VALUE_OR_RETURN(legacy2aidl_String16_string(legacy.value()));
- return conversion.value();
-}
-
-ConversionResult<String8> aidl2legacy_string_view_String8(std::string_view aidl) {
- return String8(aidl.data(), aidl.size());
-}
-
-ConversionResult<std::string> legacy2aidl_String8_string(const String8& legacy) {
- return std::string(legacy.c_str());
-}
-
ConversionResult<audio_io_config_event_t> aidl2legacy_AudioIoConfigEvent_audio_io_config_event_t(
media::AudioIoConfigEvent aidl) {
switch (aidl) {
@@ -365,1461 +241,6 @@
return unexpected(BAD_VALUE);
}
-namespace {
-
-namespace detail {
-using AudioChannelBitPair = std::pair<audio_channel_mask_t, int>;
-using AudioChannelBitPairs = std::vector<AudioChannelBitPair>;
-using AudioChannelPair = std::pair<audio_channel_mask_t, AudioChannelLayout>;
-using AudioChannelPairs = std::vector<AudioChannelPair>;
-using AudioDevicePair = std::pair<audio_devices_t, AudioDeviceDescription>;
-using AudioDevicePairs = std::vector<AudioDevicePair>;
-using AudioFormatPair = std::pair<audio_format_t, AudioFormatDescription>;
-using AudioFormatPairs = std::vector<AudioFormatPair>;
-}
-
-const detail::AudioChannelBitPairs& getInAudioChannelBits() {
- static const detail::AudioChannelBitPairs pairs = {
- { AUDIO_CHANNEL_IN_LEFT, AudioChannelLayout::CHANNEL_FRONT_LEFT },
- { AUDIO_CHANNEL_IN_RIGHT, AudioChannelLayout::CHANNEL_FRONT_RIGHT },
- // AUDIO_CHANNEL_IN_FRONT is at the end
- { AUDIO_CHANNEL_IN_BACK, AudioChannelLayout::CHANNEL_BACK_CENTER },
- // AUDIO_CHANNEL_IN_*_PROCESSED not supported
- // AUDIO_CHANNEL_IN_PRESSURE not supported
- // AUDIO_CHANNEL_IN_*_AXIS not supported
- // AUDIO_CHANNEL_IN_VOICE_* not supported
- { AUDIO_CHANNEL_IN_BACK_LEFT, AudioChannelLayout::CHANNEL_BACK_LEFT },
- { AUDIO_CHANNEL_IN_BACK_RIGHT, AudioChannelLayout::CHANNEL_BACK_RIGHT },
- { AUDIO_CHANNEL_IN_CENTER, AudioChannelLayout::CHANNEL_FRONT_CENTER },
- { AUDIO_CHANNEL_IN_LOW_FREQUENCY, AudioChannelLayout::CHANNEL_LOW_FREQUENCY },
- { AUDIO_CHANNEL_IN_TOP_LEFT, AudioChannelLayout::CHANNEL_TOP_SIDE_LEFT },
- { AUDIO_CHANNEL_IN_TOP_RIGHT, AudioChannelLayout::CHANNEL_TOP_SIDE_RIGHT },
- // When going from aidl to legacy, IN_CENTER is used
- { AUDIO_CHANNEL_IN_FRONT, AudioChannelLayout::CHANNEL_FRONT_CENTER }
- };
- return pairs;
-}
-
-const detail::AudioChannelPairs& getInAudioChannelPairs() {
- static const detail::AudioChannelPairs pairs = {
-#define DEFINE_INPUT_LAYOUT(n) \
- { \
- AUDIO_CHANNEL_IN_##n, \
- AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>( \
- AudioChannelLayout::LAYOUT_##n) \
- }
-
- DEFINE_INPUT_LAYOUT(MONO),
- DEFINE_INPUT_LAYOUT(STEREO),
- DEFINE_INPUT_LAYOUT(FRONT_BACK),
- // AUDIO_CHANNEL_IN_6 not supported
- DEFINE_INPUT_LAYOUT(2POINT0POINT2),
- DEFINE_INPUT_LAYOUT(2POINT1POINT2),
- DEFINE_INPUT_LAYOUT(3POINT0POINT2),
- DEFINE_INPUT_LAYOUT(3POINT1POINT2),
- DEFINE_INPUT_LAYOUT(5POINT1)
-#undef DEFINE_INPUT_LAYOUT
- };
- return pairs;
-}
-
-const detail::AudioChannelBitPairs& getOutAudioChannelBits() {
- static const detail::AudioChannelBitPairs pairs = {
-#define DEFINE_OUTPUT_BITS(n) \
- { AUDIO_CHANNEL_OUT_##n, AudioChannelLayout::CHANNEL_##n }
-
- DEFINE_OUTPUT_BITS(FRONT_LEFT),
- DEFINE_OUTPUT_BITS(FRONT_RIGHT),
- DEFINE_OUTPUT_BITS(FRONT_CENTER),
- DEFINE_OUTPUT_BITS(LOW_FREQUENCY),
- DEFINE_OUTPUT_BITS(BACK_LEFT),
- DEFINE_OUTPUT_BITS(BACK_RIGHT),
- DEFINE_OUTPUT_BITS(FRONT_LEFT_OF_CENTER),
- DEFINE_OUTPUT_BITS(FRONT_RIGHT_OF_CENTER),
- DEFINE_OUTPUT_BITS(BACK_CENTER),
- DEFINE_OUTPUT_BITS(SIDE_LEFT),
- DEFINE_OUTPUT_BITS(SIDE_RIGHT),
- DEFINE_OUTPUT_BITS(TOP_CENTER),
- DEFINE_OUTPUT_BITS(TOP_FRONT_LEFT),
- DEFINE_OUTPUT_BITS(TOP_FRONT_CENTER),
- DEFINE_OUTPUT_BITS(TOP_FRONT_RIGHT),
- DEFINE_OUTPUT_BITS(TOP_BACK_LEFT),
- DEFINE_OUTPUT_BITS(TOP_BACK_CENTER),
- DEFINE_OUTPUT_BITS(TOP_BACK_RIGHT),
- DEFINE_OUTPUT_BITS(TOP_SIDE_LEFT),
- DEFINE_OUTPUT_BITS(TOP_SIDE_RIGHT),
- DEFINE_OUTPUT_BITS(BOTTOM_FRONT_LEFT),
- DEFINE_OUTPUT_BITS(BOTTOM_FRONT_CENTER),
- DEFINE_OUTPUT_BITS(BOTTOM_FRONT_RIGHT),
- DEFINE_OUTPUT_BITS(LOW_FREQUENCY_2),
- DEFINE_OUTPUT_BITS(FRONT_WIDE_LEFT),
- DEFINE_OUTPUT_BITS(FRONT_WIDE_RIGHT),
-#undef DEFINE_OUTPUT_BITS
- { AUDIO_CHANNEL_OUT_HAPTIC_A, AudioChannelLayout::CHANNEL_HAPTIC_A },
- { AUDIO_CHANNEL_OUT_HAPTIC_B, AudioChannelLayout::CHANNEL_HAPTIC_B }
- };
- return pairs;
-}
-
-const detail::AudioChannelPairs& getOutAudioChannelPairs() {
- static const detail::AudioChannelPairs pairs = {
-#define DEFINE_OUTPUT_LAYOUT(n) \
- { \
- AUDIO_CHANNEL_OUT_##n, \
- AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>( \
- AudioChannelLayout::LAYOUT_##n) \
- }
-
- DEFINE_OUTPUT_LAYOUT(MONO),
- DEFINE_OUTPUT_LAYOUT(STEREO),
- DEFINE_OUTPUT_LAYOUT(2POINT1),
- DEFINE_OUTPUT_LAYOUT(TRI),
- DEFINE_OUTPUT_LAYOUT(TRI_BACK),
- DEFINE_OUTPUT_LAYOUT(3POINT1),
- DEFINE_OUTPUT_LAYOUT(2POINT0POINT2),
- DEFINE_OUTPUT_LAYOUT(2POINT1POINT2),
- DEFINE_OUTPUT_LAYOUT(3POINT0POINT2),
- DEFINE_OUTPUT_LAYOUT(3POINT1POINT2),
- DEFINE_OUTPUT_LAYOUT(QUAD),
- DEFINE_OUTPUT_LAYOUT(QUAD_SIDE),
- DEFINE_OUTPUT_LAYOUT(SURROUND),
- DEFINE_OUTPUT_LAYOUT(PENTA),
- DEFINE_OUTPUT_LAYOUT(5POINT1),
- DEFINE_OUTPUT_LAYOUT(5POINT1_SIDE),
- DEFINE_OUTPUT_LAYOUT(5POINT1POINT2),
- DEFINE_OUTPUT_LAYOUT(5POINT1POINT4),
- DEFINE_OUTPUT_LAYOUT(6POINT1),
- DEFINE_OUTPUT_LAYOUT(7POINT1),
- DEFINE_OUTPUT_LAYOUT(7POINT1POINT2),
- DEFINE_OUTPUT_LAYOUT(7POINT1POINT4),
- DEFINE_OUTPUT_LAYOUT(13POINT_360RA),
- DEFINE_OUTPUT_LAYOUT(22POINT2),
- DEFINE_OUTPUT_LAYOUT(MONO_HAPTIC_A),
- DEFINE_OUTPUT_LAYOUT(STEREO_HAPTIC_A),
- DEFINE_OUTPUT_LAYOUT(HAPTIC_AB),
- DEFINE_OUTPUT_LAYOUT(MONO_HAPTIC_AB),
- DEFINE_OUTPUT_LAYOUT(STEREO_HAPTIC_AB)
-#undef DEFINE_OUTPUT_LAYOUT
- };
- return pairs;
-}
-
-const detail::AudioChannelPairs& getVoiceAudioChannelPairs() {
- static const detail::AudioChannelPairs pairs = {
-#define DEFINE_VOICE_LAYOUT(n) \
- { \
- AUDIO_CHANNEL_IN_VOICE_##n, \
- AudioChannelLayout::make<AudioChannelLayout::Tag::voiceMask>( \
- AudioChannelLayout::VOICE_##n) \
- }
- DEFINE_VOICE_LAYOUT(UPLINK_MONO),
- DEFINE_VOICE_LAYOUT(DNLINK_MONO),
- DEFINE_VOICE_LAYOUT(CALL_MONO)
-#undef DEFINE_VOICE_LAYOUT
- };
- return pairs;
-}
-
-AudioDeviceDescription make_AudioDeviceDescription(AudioDeviceType type,
- const std::string& connection = "") {
- AudioDeviceDescription result;
- result.type = type;
- result.connection = connection;
- return result;
-}
-
-void append_AudioDeviceDescription(detail::AudioDevicePairs& pairs,
- audio_devices_t inputType, audio_devices_t outputType,
- AudioDeviceType inType, AudioDeviceType outType,
- const std::string& connection = "") {
- pairs.push_back(std::make_pair(inputType, make_AudioDeviceDescription(inType, connection)));
- pairs.push_back(std::make_pair(outputType, make_AudioDeviceDescription(outType, connection)));
-}
-
-const detail::AudioDevicePairs& getAudioDevicePairs() {
- static const detail::AudioDevicePairs pairs = []() {
- detail::AudioDevicePairs pairs = {{
- {
- AUDIO_DEVICE_NONE, AudioDeviceDescription{}
- },
- {
- AUDIO_DEVICE_OUT_EARPIECE, make_AudioDeviceDescription(
- AudioDeviceType::OUT_SPEAKER_EARPIECE)
- },
- {
- AUDIO_DEVICE_OUT_SPEAKER, make_AudioDeviceDescription(
- AudioDeviceType::OUT_SPEAKER)
- },
- {
- AUDIO_DEVICE_OUT_WIRED_HEADPHONE, make_AudioDeviceDescription(
- AudioDeviceType::OUT_HEADPHONE,
- AudioDeviceDescription::CONNECTION_ANALOG())
- },
- {
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO, make_AudioDeviceDescription(
- AudioDeviceType::OUT_DEVICE,
- AudioDeviceDescription::CONNECTION_BT_SCO())
- },
- {
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT, make_AudioDeviceDescription(
- AudioDeviceType::OUT_CARKIT,
- AudioDeviceDescription::CONNECTION_BT_SCO())
- },
- {
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES, make_AudioDeviceDescription(
- AudioDeviceType::OUT_HEADPHONE,
- AudioDeviceDescription::CONNECTION_BT_A2DP())
- },
- {
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER, make_AudioDeviceDescription(
- AudioDeviceType::OUT_SPEAKER,
- AudioDeviceDescription::CONNECTION_BT_A2DP())
- },
- {
- AUDIO_DEVICE_OUT_TELEPHONY_TX, make_AudioDeviceDescription(
- AudioDeviceType::OUT_TELEPHONY_TX)
- },
- {
- AUDIO_DEVICE_OUT_AUX_LINE, make_AudioDeviceDescription(
- AudioDeviceType::OUT_LINE_AUX)
- },
- {
- AUDIO_DEVICE_OUT_SPEAKER_SAFE, make_AudioDeviceDescription(
- AudioDeviceType::OUT_SPEAKER_SAFE)
- },
- {
- AUDIO_DEVICE_OUT_HEARING_AID, make_AudioDeviceDescription(
- AudioDeviceType::OUT_HEARING_AID,
- AudioDeviceDescription::CONNECTION_WIRELESS())
- },
- {
- AUDIO_DEVICE_OUT_ECHO_CANCELLER, make_AudioDeviceDescription(
- AudioDeviceType::OUT_ECHO_CANCELLER)
- },
- {
- AUDIO_DEVICE_OUT_BLE_SPEAKER, make_AudioDeviceDescription(
- AudioDeviceType::OUT_SPEAKER,
- AudioDeviceDescription::CONNECTION_BT_LE())
- },
- {
- AUDIO_DEVICE_OUT_BLE_BROADCAST, make_AudioDeviceDescription(
- AudioDeviceType::OUT_BROADCAST,
- AudioDeviceDescription::CONNECTION_BT_LE())
- },
- // AUDIO_DEVICE_IN_AMBIENT and IN_COMMUNICATION are removed since they were deprecated.
- {
- AUDIO_DEVICE_IN_BUILTIN_MIC, make_AudioDeviceDescription(
- AudioDeviceType::IN_MICROPHONE)
- },
- {
- AUDIO_DEVICE_IN_BACK_MIC, make_AudioDeviceDescription(
- AudioDeviceType::IN_MICROPHONE_BACK)
- },
- {
- AUDIO_DEVICE_IN_TELEPHONY_RX, make_AudioDeviceDescription(
- AudioDeviceType::IN_TELEPHONY_RX)
- },
- {
- AUDIO_DEVICE_IN_TV_TUNER, make_AudioDeviceDescription(
- AudioDeviceType::IN_TV_TUNER)
- },
- {
- AUDIO_DEVICE_IN_LOOPBACK, make_AudioDeviceDescription(
- AudioDeviceType::IN_LOOPBACK)
- },
- {
- AUDIO_DEVICE_IN_BLUETOOTH_BLE, make_AudioDeviceDescription(
- AudioDeviceType::IN_DEVICE,
- AudioDeviceDescription::CONNECTION_BT_LE())
- },
- {
- AUDIO_DEVICE_IN_ECHO_REFERENCE, make_AudioDeviceDescription(
- AudioDeviceType::IN_ECHO_REFERENCE)
- }
- }};
- append_AudioDeviceDescription(pairs,
- AUDIO_DEVICE_IN_DEFAULT, AUDIO_DEVICE_OUT_DEFAULT,
- AudioDeviceType::IN_DEFAULT, AudioDeviceType::OUT_DEFAULT);
- append_AudioDeviceDescription(pairs,
- AUDIO_DEVICE_IN_WIRED_HEADSET, AUDIO_DEVICE_OUT_WIRED_HEADSET,
- AudioDeviceType::IN_HEADSET, AudioDeviceType::OUT_HEADSET,
- AudioDeviceDescription::CONNECTION_ANALOG());
- append_AudioDeviceDescription(pairs,
- AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET, AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET,
- AudioDeviceType::IN_HEADSET, AudioDeviceType::OUT_HEADSET,
- AudioDeviceDescription::CONNECTION_BT_SCO());
- append_AudioDeviceDescription(pairs,
- AUDIO_DEVICE_IN_HDMI, AUDIO_DEVICE_OUT_HDMI,
- AudioDeviceType::IN_DEVICE, AudioDeviceType::OUT_DEVICE,
- AudioDeviceDescription::CONNECTION_HDMI());
- append_AudioDeviceDescription(pairs,
- AUDIO_DEVICE_IN_REMOTE_SUBMIX, AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
- AudioDeviceType::IN_SUBMIX, AudioDeviceType::OUT_SUBMIX);
- append_AudioDeviceDescription(pairs,
- AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET, AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET,
- AudioDeviceType::IN_DOCK, AudioDeviceType::OUT_DOCK,
- AudioDeviceDescription::CONNECTION_ANALOG());
- append_AudioDeviceDescription(pairs,
- AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET, AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET,
- AudioDeviceType::IN_DOCK, AudioDeviceType::OUT_DOCK,
- AudioDeviceDescription::CONNECTION_USB());
- append_AudioDeviceDescription(pairs,
- AUDIO_DEVICE_IN_USB_ACCESSORY, AUDIO_DEVICE_OUT_USB_ACCESSORY,
- AudioDeviceType::IN_ACCESSORY, AudioDeviceType::OUT_ACCESSORY,
- AudioDeviceDescription::CONNECTION_USB());
- append_AudioDeviceDescription(pairs,
- AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_DEVICE_OUT_USB_DEVICE,
- AudioDeviceType::IN_DEVICE, AudioDeviceType::OUT_DEVICE,
- AudioDeviceDescription::CONNECTION_USB());
- append_AudioDeviceDescription(pairs,
- AUDIO_DEVICE_IN_FM_TUNER, AUDIO_DEVICE_OUT_FM,
- AudioDeviceType::IN_FM_TUNER, AudioDeviceType::OUT_FM);
- append_AudioDeviceDescription(pairs,
- AUDIO_DEVICE_IN_LINE, AUDIO_DEVICE_OUT_LINE,
- AudioDeviceType::IN_DEVICE, AudioDeviceType::OUT_DEVICE,
- AudioDeviceDescription::CONNECTION_ANALOG());
- append_AudioDeviceDescription(pairs,
- AUDIO_DEVICE_IN_SPDIF, AUDIO_DEVICE_OUT_SPDIF,
- AudioDeviceType::IN_DEVICE, AudioDeviceType::OUT_DEVICE,
- AudioDeviceDescription::CONNECTION_SPDIF());
- append_AudioDeviceDescription(pairs,
- AUDIO_DEVICE_IN_BLUETOOTH_A2DP, AUDIO_DEVICE_OUT_BLUETOOTH_A2DP,
- AudioDeviceType::IN_DEVICE, AudioDeviceType::OUT_DEVICE,
- AudioDeviceDescription::CONNECTION_BT_A2DP());
- append_AudioDeviceDescription(pairs,
- AUDIO_DEVICE_IN_IP, AUDIO_DEVICE_OUT_IP,
- AudioDeviceType::IN_DEVICE, AudioDeviceType::OUT_DEVICE,
- AudioDeviceDescription::CONNECTION_IP_V4());
- append_AudioDeviceDescription(pairs,
- AUDIO_DEVICE_IN_BUS, AUDIO_DEVICE_OUT_BUS,
- AudioDeviceType::IN_DEVICE, AudioDeviceType::OUT_DEVICE,
- AudioDeviceDescription::CONNECTION_BUS());
- append_AudioDeviceDescription(pairs,
- AUDIO_DEVICE_IN_PROXY, AUDIO_DEVICE_OUT_PROXY,
- AudioDeviceType::IN_AFE_PROXY, AudioDeviceType::OUT_AFE_PROXY);
- append_AudioDeviceDescription(pairs,
- AUDIO_DEVICE_IN_USB_HEADSET, AUDIO_DEVICE_OUT_USB_HEADSET,
- AudioDeviceType::IN_HEADSET, AudioDeviceType::OUT_HEADSET,
- AudioDeviceDescription::CONNECTION_USB());
- append_AudioDeviceDescription(pairs,
- AUDIO_DEVICE_IN_HDMI_ARC, AUDIO_DEVICE_OUT_HDMI_ARC,
- AudioDeviceType::IN_DEVICE, AudioDeviceType::OUT_DEVICE,
- AudioDeviceDescription::CONNECTION_HDMI_ARC());
- append_AudioDeviceDescription(pairs,
- AUDIO_DEVICE_IN_HDMI_EARC, AUDIO_DEVICE_OUT_HDMI_EARC,
- AudioDeviceType::IN_DEVICE, AudioDeviceType::OUT_DEVICE,
- AudioDeviceDescription::CONNECTION_HDMI_EARC());
- append_AudioDeviceDescription(pairs,
- AUDIO_DEVICE_IN_BLE_HEADSET, AUDIO_DEVICE_OUT_BLE_HEADSET,
- AudioDeviceType::IN_HEADSET, AudioDeviceType::OUT_HEADSET,
- AudioDeviceDescription::CONNECTION_BT_LE());
- return pairs;
- }();
- return pairs;
-}
-
-AudioFormatDescription make_AudioFormatDescription(AudioFormatType type) {
- AudioFormatDescription result;
- result.type = type;
- return result;
-}
-
-AudioFormatDescription make_AudioFormatDescription(PcmType pcm) {
- auto result = make_AudioFormatDescription(AudioFormatType::PCM);
- result.pcm = pcm;
- return result;
-}
-
-AudioFormatDescription make_AudioFormatDescription(const std::string& encoding) {
- AudioFormatDescription result;
- result.encoding = encoding;
- return result;
-}
-
-AudioFormatDescription make_AudioFormatDescription(PcmType transport,
- const std::string& encoding) {
- auto result = make_AudioFormatDescription(encoding);
- result.pcm = transport;
- return result;
-}
-
-const detail::AudioFormatPairs& getAudioFormatPairs() {
- static const detail::AudioFormatPairs pairs = {{
- {
- AUDIO_FORMAT_INVALID,
- make_AudioFormatDescription(AudioFormatType::SYS_RESERVED_INVALID)
- },
- {
- AUDIO_FORMAT_DEFAULT, AudioFormatDescription{}
- },
- {
- AUDIO_FORMAT_PCM_16_BIT, make_AudioFormatDescription(PcmType::INT_16_BIT)
- },
- {
- AUDIO_FORMAT_PCM_8_BIT, make_AudioFormatDescription(PcmType::UINT_8_BIT)
- },
- {
- AUDIO_FORMAT_PCM_32_BIT, make_AudioFormatDescription(PcmType::INT_32_BIT)
- },
- {
- AUDIO_FORMAT_PCM_8_24_BIT, make_AudioFormatDescription(PcmType::FIXED_Q_8_24)
- },
- {
- AUDIO_FORMAT_PCM_FLOAT, make_AudioFormatDescription(PcmType::FLOAT_32_BIT)
- },
- {
- AUDIO_FORMAT_PCM_24_BIT_PACKED, make_AudioFormatDescription(PcmType::INT_24_BIT)
- },
- {
- AUDIO_FORMAT_MP3, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_MPEG)
- },
- {
- AUDIO_FORMAT_AMR_NB, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_AMR_NB)
- },
- {
- AUDIO_FORMAT_AMR_WB, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_AMR_WB)
- },
- {
- AUDIO_FORMAT_AAC, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_AAC_MP4)
- },
- {
- AUDIO_FORMAT_AAC_MAIN, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_AAC_MAIN)
- },
- {
- AUDIO_FORMAT_AAC_LC, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_AAC_LC)
- },
- {
- AUDIO_FORMAT_AAC_SSR, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_AAC_SSR)
- },
- {
- AUDIO_FORMAT_AAC_LTP, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_AAC_LTP)
- },
- {
- AUDIO_FORMAT_AAC_HE_V1, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_AAC_HE_V1)
- },
- {
- AUDIO_FORMAT_AAC_SCALABLE,
- make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_AAC_SCALABLE)
- },
- {
- AUDIO_FORMAT_AAC_ERLC, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_AAC_ERLC)
- },
- {
- AUDIO_FORMAT_AAC_LD, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_AAC_LD)
- },
- {
- AUDIO_FORMAT_AAC_HE_V2, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_AAC_HE_V2)
- },
- {
- AUDIO_FORMAT_AAC_ELD, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_AAC_ELD)
- },
- {
- AUDIO_FORMAT_AAC_XHE, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_AAC_XHE)
- },
- // AUDIO_FORMAT_HE_AAC_V1 and HE_AAC_V2 are removed since they were deprecated long time
- // ago.
- {
- AUDIO_FORMAT_VORBIS, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_VORBIS)
- },
- {
- AUDIO_FORMAT_OPUS, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_OPUS)
- },
- {
- AUDIO_FORMAT_AC3, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_AC3)
- },
- {
- AUDIO_FORMAT_E_AC3, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_EAC3)
- },
- {
- AUDIO_FORMAT_E_AC3_JOC, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_EAC3_JOC)
- },
- {
- AUDIO_FORMAT_DTS, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_DTS)
- },
- {
- AUDIO_FORMAT_DTS_HD, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_DTS_HD)
- },
- // In the future, we would like to represent encapsulated bitstreams as
- // nested AudioFormatDescriptions. The legacy 'AUDIO_FORMAT_IEC61937' type doesn't
- // specify the format of the encapsulated bitstream.
- {
- AUDIO_FORMAT_IEC61937,
- make_AudioFormatDescription(PcmType::INT_16_BIT, MEDIA_MIMETYPE_AUDIO_IEC61937)
- },
- {
- AUDIO_FORMAT_DOLBY_TRUEHD,
- make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_DOLBY_TRUEHD)
- },
- {
- AUDIO_FORMAT_EVRC, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_EVRC)
- },
- {
- AUDIO_FORMAT_EVRCB, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_EVRCB)
- },
- {
- AUDIO_FORMAT_EVRCWB, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_EVRCWB)
- },
- {
- AUDIO_FORMAT_EVRCNW, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_EVRCNW)
- },
- {
- AUDIO_FORMAT_AAC_ADIF, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_AAC_ADIF)
- },
- {
- AUDIO_FORMAT_WMA, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_WMA)
- },
- {
- // Note: not in the IANA registry.
- AUDIO_FORMAT_WMA_PRO, make_AudioFormatDescription("audio/x-ms-wma.pro")
- },
- {
- AUDIO_FORMAT_AMR_WB_PLUS, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_AMR_WB_PLUS)
- },
- {
- AUDIO_FORMAT_MP2, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II)
- },
- {
- AUDIO_FORMAT_QCELP, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_QCELP)
- },
- {
- // Note: not in the IANA registry.
- AUDIO_FORMAT_DSD, make_AudioFormatDescription("audio/vnd.sony.dsd")
- },
- {
- AUDIO_FORMAT_FLAC, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_FLAC)
- },
- {
- AUDIO_FORMAT_ALAC, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_ALAC)
- },
- {
- // Note: not in the IANA registry.
- AUDIO_FORMAT_APE, make_AudioFormatDescription("audio/x-ape")
- },
- {
- AUDIO_FORMAT_AAC_ADTS, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_AAC_ADTS)
- },
- {
- AUDIO_FORMAT_AAC_ADTS_MAIN,
- make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_AAC_ADTS_MAIN)
- },
- {
- AUDIO_FORMAT_AAC_ADTS_LC, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_AAC_ADTS_LC)
- },
- {
- AUDIO_FORMAT_AAC_ADTS_SSR,
- make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_AAC_ADTS_SSR)
- },
- {
- AUDIO_FORMAT_AAC_ADTS_LTP,
- make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_AAC_ADTS_LTP)
- },
- {
- AUDIO_FORMAT_AAC_ADTS_HE_V1,
- make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_AAC_ADTS_HE_V1)
- },
- {
- AUDIO_FORMAT_AAC_ADTS_SCALABLE,
- make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_AAC_ADTS_SCALABLE)
- },
- {
- AUDIO_FORMAT_AAC_ADTS_ERLC,
- make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_AAC_ADTS_ERLC)
- },
- {
- AUDIO_FORMAT_AAC_ADTS_LD, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_AAC_ADTS_LD)
- },
- {
- AUDIO_FORMAT_AAC_ADTS_HE_V2,
- make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_AAC_ADTS_HE_V2)
- },
- {
- AUDIO_FORMAT_AAC_ADTS_ELD,
- make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_AAC_ADTS_ELD)
- },
- {
- AUDIO_FORMAT_AAC_ADTS_XHE,
- make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_AAC_ADTS_XHE)
- },
- {
- // Note: not in the IANA registry. "vnd.octel.sbc" is not BT SBC.
- AUDIO_FORMAT_SBC, make_AudioFormatDescription("audio/x-sbc")
- },
- {
- AUDIO_FORMAT_APTX, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_APTX)
- },
- {
- // Note: not in the IANA registry.
- AUDIO_FORMAT_APTX_HD, make_AudioFormatDescription("audio/vnd.qcom.aptx.hd")
- },
- {
- AUDIO_FORMAT_AC4, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_AC4)
- },
- {
- // Note: not in the IANA registry.
- AUDIO_FORMAT_LDAC, make_AudioFormatDescription("audio/vnd.sony.ldac")
- },
- {
- AUDIO_FORMAT_MAT, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_DOLBY_MAT)
- },
- {
- // Note: not in the IANA registry.
- AUDIO_FORMAT_MAT_1_0,
- make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_DOLBY_MAT + std::string(".1.0"))
- },
- {
- // Note: not in the IANA registry.
- AUDIO_FORMAT_MAT_2_0,
- make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_DOLBY_MAT + std::string(".2.0"))
- },
- {
- // Note: not in the IANA registry.
- AUDIO_FORMAT_MAT_2_1,
- make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_DOLBY_MAT + std::string(".2.1"))
- },
- {
- AUDIO_FORMAT_AAC_LATM, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_AAC)
- },
- {
- AUDIO_FORMAT_AAC_LATM_LC, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_AAC_LATM_LC)
- },
- {
- AUDIO_FORMAT_AAC_LATM_HE_V1,
- make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_AAC_LATM_HE_V1)
- },
- {
- AUDIO_FORMAT_AAC_LATM_HE_V2,
- make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_AAC_LATM_HE_V2)
- },
- {
- // Note: not in the IANA registry.
- AUDIO_FORMAT_CELT, make_AudioFormatDescription("audio/x-celt")
- },
- {
- // Note: not in the IANA registry.
- AUDIO_FORMAT_APTX_ADAPTIVE, make_AudioFormatDescription("audio/vnd.qcom.aptx.adaptive")
- },
- {
- // Note: not in the IANA registry.
- AUDIO_FORMAT_LHDC, make_AudioFormatDescription("audio/vnd.savitech.lhdc")
- },
- {
- // Note: not in the IANA registry.
- AUDIO_FORMAT_LHDC_LL, make_AudioFormatDescription("audio/vnd.savitech.lhdc.ll")
- },
- {
- // Note: not in the IANA registry.
- AUDIO_FORMAT_APTX_TWSP, make_AudioFormatDescription("audio/vnd.qcom.aptx.twsp")
- },
- {
- // Note: not in the IANA registry.
- AUDIO_FORMAT_LC3, make_AudioFormatDescription("audio/x-lc3")
- },
- {
- AUDIO_FORMAT_MPEGH, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_MPEGH_MHM1)
- },
- {
- AUDIO_FORMAT_MPEGH_BL_L3, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_MPEGH_BL_L3)
- },
- {
- AUDIO_FORMAT_MPEGH_BL_L4, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_MPEGH_BL_L4)
- },
- {
- AUDIO_FORMAT_MPEGH_LC_L3, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_MPEGH_LC_L3)
- },
- {
- AUDIO_FORMAT_MPEGH_LC_L4, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_MPEGH_LC_L4)
- },
- {
- AUDIO_FORMAT_IEC60958,
- make_AudioFormatDescription(PcmType::INT_24_BIT, MEDIA_MIMETYPE_AUDIO_IEC60958)
- },
- {
- AUDIO_FORMAT_DTS_UHD, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_DTS_UHD)
- },
- {
- AUDIO_FORMAT_DRA, make_AudioFormatDescription(MEDIA_MIMETYPE_AUDIO_DRA)
- },
- }};
- return pairs;
-}
-
-template<typename S, typename T>
-std::unordered_map<S, T> make_DirectMap(const std::vector<std::pair<S, T>>& v) {
- std::unordered_map<S, T> result(v.begin(), v.end());
- LOG_ALWAYS_FATAL_IF(result.size() != v.size(), "Duplicate key elements detected");
- return result;
-}
-
-template<typename S, typename T>
-std::unordered_map<S, T> make_DirectMap(
- const std::vector<std::pair<S, T>>& v1, const std::vector<std::pair<S, T>>& v2) {
- std::unordered_map<S, T> result(v1.begin(), v1.end());
- LOG_ALWAYS_FATAL_IF(result.size() != v1.size(), "Duplicate key elements detected in v1");
- result.insert(v2.begin(), v2.end());
- LOG_ALWAYS_FATAL_IF(result.size() != v1.size() + v2.size(),
- "Duplicate key elements detected in v1+v2");
- return result;
-}
-
-template<typename S, typename T>
-std::unordered_map<T, S> make_ReverseMap(const std::vector<std::pair<S, T>>& v) {
- std::unordered_map<T, S> result;
- std::transform(v.begin(), v.end(), std::inserter(result, result.begin()),
- [](const std::pair<S, T>& p) {
- return std::make_pair(p.second, p.first);
- });
- LOG_ALWAYS_FATAL_IF(result.size() != v.size(), "Duplicate key elements detected");
- return result;
-}
-
-} // namespace
-
-audio_channel_mask_t aidl2legacy_AudioChannelLayout_layout_audio_channel_mask_t_bits(
- int aidlLayout, bool isInput) {
- auto& bitMapping = isInput ? getInAudioChannelBits() : getOutAudioChannelBits();
- const int aidlLayoutInitial = aidlLayout; // for error message
- audio_channel_mask_t legacy = AUDIO_CHANNEL_NONE;
- for (const auto& bitPair : bitMapping) {
- if ((aidlLayout & bitPair.second) == bitPair.second) {
- legacy = static_cast<audio_channel_mask_t>(legacy | bitPair.first);
- aidlLayout &= ~bitPair.second;
- if (aidlLayout == 0) {
- return legacy;
- }
- }
- }
- ALOGE("%s: aidl layout 0x%x contains bits 0x%x that have no match to legacy %s bits",
- __func__, aidlLayoutInitial, aidlLayout, isInput ? "input" : "output");
- return AUDIO_CHANNEL_NONE;
-}
-
-ConversionResult<audio_channel_mask_t> aidl2legacy_AudioChannelLayout_audio_channel_mask_t(
- const AudioChannelLayout& aidl, bool isInput) {
- using ReverseMap = std::unordered_map<AudioChannelLayout, audio_channel_mask_t>;
- using Tag = AudioChannelLayout::Tag;
- static const ReverseMap mIn = make_ReverseMap(getInAudioChannelPairs());
- static const ReverseMap mOut = make_ReverseMap(getOutAudioChannelPairs());
- static const ReverseMap mVoice = make_ReverseMap(getVoiceAudioChannelPairs());
-
- auto convert = [](const AudioChannelLayout& aidl, const ReverseMap& m,
- const char* func, const char* type) -> ConversionResult<audio_channel_mask_t> {
- if (auto it = m.find(aidl); it != m.end()) {
- return it->second;
- } else {
- ALOGW("%s: no legacy %s audio_channel_mask_t found for %s", func, type,
- aidl.toString().c_str());
- return unexpected(BAD_VALUE);
- }
- };
-
- switch (aidl.getTag()) {
- case Tag::none:
- return AUDIO_CHANNEL_NONE;
- case Tag::invalid:
- return AUDIO_CHANNEL_INVALID;
- case Tag::indexMask:
- // Index masks do not have pre-defined values.
- if (const int bits = aidl.get<Tag::indexMask>();
- __builtin_popcount(bits) != 0 &&
- __builtin_popcount(bits) <= AUDIO_CHANNEL_COUNT_MAX) {
- return audio_channel_mask_from_representation_and_bits(
- AUDIO_CHANNEL_REPRESENTATION_INDEX, bits);
- } else {
- ALOGE("%s: invalid indexMask value 0x%x in %s",
- __func__, bits, aidl.toString().c_str());
- return unexpected(BAD_VALUE);
- }
- case Tag::layoutMask:
- // The fast path is to find a direct match for some known layout mask.
- if (const auto layoutMatch = convert(aidl, isInput ? mIn : mOut, __func__,
- isInput ? "input" : "output");
- layoutMatch.ok()) {
- return layoutMatch;
- }
- // If a match for a predefined layout wasn't found, make a custom one from bits.
- if (audio_channel_mask_t bitMask =
- aidl2legacy_AudioChannelLayout_layout_audio_channel_mask_t_bits(
- aidl.get<Tag::layoutMask>(), isInput);
- bitMask != AUDIO_CHANNEL_NONE) {
- return bitMask;
- }
- return unexpected(BAD_VALUE);
- case Tag::voiceMask:
- return convert(aidl, mVoice, __func__, "voice");
- }
- ALOGE("%s: unexpected tag value %d", __func__, aidl.getTag());
- return unexpected(BAD_VALUE);
-}
-
-int legacy2aidl_audio_channel_mask_t_bits_AudioChannelLayout_layout(
- audio_channel_mask_t legacy, bool isInput) {
- auto& bitMapping = isInput ? getInAudioChannelBits() : getOutAudioChannelBits();
- const int legacyInitial = legacy; // for error message
- int aidlLayout = 0;
- for (const auto& bitPair : bitMapping) {
- if ((legacy & bitPair.first) == bitPair.first) {
- aidlLayout |= bitPair.second;
- legacy = static_cast<audio_channel_mask_t>(legacy & ~bitPair.first);
- if (legacy == 0) {
- return aidlLayout;
- }
- }
- }
- ALOGE("%s: legacy %s audio_channel_mask_t 0x%x contains unrecognized bits 0x%x",
- __func__, isInput ? "input" : "output", legacyInitial, legacy);
- return 0;
-}
-
-ConversionResult<AudioChannelLayout> legacy2aidl_audio_channel_mask_t_AudioChannelLayout(
- audio_channel_mask_t legacy, bool isInput) {
- using DirectMap = std::unordered_map<audio_channel_mask_t, AudioChannelLayout>;
- using Tag = AudioChannelLayout::Tag;
- static const DirectMap mInAndVoice = make_DirectMap(
- getInAudioChannelPairs(), getVoiceAudioChannelPairs());
- static const DirectMap mOut = make_DirectMap(getOutAudioChannelPairs());
-
- auto convert = [](const audio_channel_mask_t legacy, const DirectMap& m,
- const char* func, const char* type) -> ConversionResult<AudioChannelLayout> {
- if (auto it = m.find(legacy); it != m.end()) {
- return it->second;
- } else {
- ALOGW("%s: no AudioChannelLayout found for legacy %s audio_channel_mask_t value 0x%x",
- func, type, legacy);
- return unexpected(BAD_VALUE);
- }
- };
-
- if (legacy == AUDIO_CHANNEL_NONE) {
- return AudioChannelLayout{};
- } else if (legacy == AUDIO_CHANNEL_INVALID) {
- return AudioChannelLayout::make<Tag::invalid>(0);
- }
-
- const audio_channel_representation_t repr = audio_channel_mask_get_representation(legacy);
- if (repr == AUDIO_CHANNEL_REPRESENTATION_INDEX) {
- if (audio_channel_mask_is_valid(legacy)) {
- const int indexMask = VALUE_OR_RETURN(
- convertIntegral<int>(audio_channel_mask_get_bits(legacy)));
- return AudioChannelLayout::make<Tag::indexMask>(indexMask);
- } else {
- ALOGE("%s: legacy audio_channel_mask_t value 0x%x is invalid", __func__, legacy);
- return unexpected(BAD_VALUE);
- }
- } else if (repr == AUDIO_CHANNEL_REPRESENTATION_POSITION) {
- // The fast path is to find a direct match for some known layout mask.
- if (const auto layoutMatch = convert(legacy, isInput ? mInAndVoice : mOut, __func__,
- isInput ? "input / voice" : "output");
- layoutMatch.ok()) {
- return layoutMatch;
- }
- // If a match for a predefined layout wasn't found, make a custom one from bits,
- // rejecting those with voice channel bits.
- if (!isInput ||
- (legacy & (AUDIO_CHANNEL_IN_VOICE_UPLINK | AUDIO_CHANNEL_IN_VOICE_DNLINK)) == 0) {
- if (int bitMaskLayout =
- legacy2aidl_audio_channel_mask_t_bits_AudioChannelLayout_layout(
- legacy, isInput);
- bitMaskLayout != 0) {
- return AudioChannelLayout::make<Tag::layoutMask>(bitMaskLayout);
- }
- } else {
- ALOGE("%s: legacy audio_channel_mask_t value 0x%x contains voice bits",
- __func__, legacy);
- }
- return unexpected(BAD_VALUE);
- }
-
- ALOGE("%s: unknown representation %d in audio_channel_mask_t value 0x%x",
- __func__, repr, legacy);
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<audio_devices_t> aidl2legacy_AudioDeviceDescription_audio_devices_t(
- const AudioDeviceDescription& aidl) {
- static const std::unordered_map<AudioDeviceDescription, audio_devices_t> m =
- make_ReverseMap(getAudioDevicePairs());
- if (auto it = m.find(aidl); it != m.end()) {
- return it->second;
- } else {
- ALOGE("%s: no legacy audio_devices_t found for %s", __func__, aidl.toString().c_str());
- return unexpected(BAD_VALUE);
- }
-}
-
-ConversionResult<AudioDeviceDescription> legacy2aidl_audio_devices_t_AudioDeviceDescription(
- audio_devices_t legacy) {
- static const std::unordered_map<audio_devices_t, AudioDeviceDescription> m =
- make_DirectMap(getAudioDevicePairs());
- if (auto it = m.find(legacy); it != m.end()) {
- return it->second;
- } else {
- ALOGE("%s: no AudioDeviceDescription found for legacy audio_devices_t value 0x%x",
- __func__, legacy);
- return unexpected(BAD_VALUE);
- }
-}
-
-status_t aidl2legacy_AudioDevice_audio_device(
- const AudioDevice& aidl,
- audio_devices_t* legacyType, char* legacyAddress) {
- *legacyType = VALUE_OR_RETURN_STATUS(
- aidl2legacy_AudioDeviceDescription_audio_devices_t(aidl.type));
- return aidl2legacy_string(
- aidl.address.get<AudioDeviceAddress::id>(),
- legacyAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN);
-}
-
-status_t aidl2legacy_AudioDevice_audio_device(
- const AudioDevice& aidl,
- audio_devices_t* legacyType, String8* legacyAddress) {
- *legacyType = VALUE_OR_RETURN_STATUS(
- aidl2legacy_AudioDeviceDescription_audio_devices_t(aidl.type));
- *legacyAddress = VALUE_OR_RETURN_STATUS(aidl2legacy_string_view_String8(
- aidl.address.get<AudioDeviceAddress::id>()));
- return OK;
-}
-
-status_t aidl2legacy_AudioDevice_audio_device(
- const AudioDevice& aidl,
- audio_devices_t* legacyType, std::string* legacyAddress) {
- *legacyType = VALUE_OR_RETURN_STATUS(
- aidl2legacy_AudioDeviceDescription_audio_devices_t(aidl.type));
- *legacyAddress = aidl.address.get<AudioDeviceAddress::id>();
- return OK;
-}
-
-ConversionResult<AudioDevice> legacy2aidl_audio_device_AudioDevice(
- audio_devices_t legacyType, const char* legacyAddress) {
- AudioDevice aidl;
- aidl.type = VALUE_OR_RETURN(
- legacy2aidl_audio_devices_t_AudioDeviceDescription(legacyType));
- const std::string aidl_id = VALUE_OR_RETURN(
- legacy2aidl_string(legacyAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN));
- aidl.address = AudioDeviceAddress::make<AudioDeviceAddress::id>(aidl_id);
- return aidl;
-}
-
-ConversionResult<AudioDevice>
-legacy2aidl_audio_device_AudioDevice(
- audio_devices_t legacyType, const String8& legacyAddress) {
- AudioDevice aidl;
- aidl.type = VALUE_OR_RETURN(
- legacy2aidl_audio_devices_t_AudioDeviceDescription(legacyType));
- const std::string aidl_id = VALUE_OR_RETURN(
- legacy2aidl_String8_string(legacyAddress));
- aidl.address = AudioDeviceAddress::make<AudioDeviceAddress::id>(aidl_id);
- return aidl;
-}
-
-ConversionResult<audio_format_t> aidl2legacy_AudioFormatDescription_audio_format_t(
- const AudioFormatDescription& aidl) {
- static const std::unordered_map<AudioFormatDescription, audio_format_t> m =
- make_ReverseMap(getAudioFormatPairs());
- if (auto it = m.find(aidl); it != m.end()) {
- return it->second;
- } else {
- ALOGE("%s: no legacy audio_format_t found for %s", __func__, aidl.toString().c_str());
- return unexpected(BAD_VALUE);
- }
-}
-
-ConversionResult<AudioFormatDescription> legacy2aidl_audio_format_t_AudioFormatDescription(
- audio_format_t legacy) {
- static const std::unordered_map<audio_format_t, AudioFormatDescription> m =
- make_DirectMap(getAudioFormatPairs());
- if (auto it = m.find(legacy); it != m.end()) {
- return it->second;
- } else {
- ALOGE("%s: no AudioFormatDescription found for legacy audio_format_t value 0x%x",
- __func__, legacy);
- return unexpected(BAD_VALUE);
- }
-}
-
-ConversionResult<audio_gain_mode_t> aidl2legacy_AudioGainMode_audio_gain_mode_t(
- AudioGainMode aidl) {
- switch (aidl) {
- case AudioGainMode::JOINT:
- return AUDIO_GAIN_MODE_JOINT;
- case AudioGainMode::CHANNELS:
- return AUDIO_GAIN_MODE_CHANNELS;
- case AudioGainMode::RAMP:
- return AUDIO_GAIN_MODE_RAMP;
- }
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<AudioGainMode> legacy2aidl_audio_gain_mode_t_AudioGainMode(
- audio_gain_mode_t legacy) {
- switch (legacy) {
- case AUDIO_GAIN_MODE_JOINT:
- return AudioGainMode::JOINT;
- case AUDIO_GAIN_MODE_CHANNELS:
- return AudioGainMode::CHANNELS;
- case AUDIO_GAIN_MODE_RAMP:
- return AudioGainMode::RAMP;
- }
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<audio_gain_mode_t> aidl2legacy_int32_t_audio_gain_mode_t_mask(int32_t aidl) {
- return convertBitmask<audio_gain_mode_t, int32_t, audio_gain_mode_t, AudioGainMode>(
- aidl, aidl2legacy_AudioGainMode_audio_gain_mode_t,
- // AudioGainMode is index-based.
- indexToEnum_index<AudioGainMode>,
- // AUDIO_GAIN_MODE_* constants are mask-based.
- enumToMask_bitmask<audio_gain_mode_t, audio_gain_mode_t>);
-}
-
-ConversionResult<int32_t> legacy2aidl_audio_gain_mode_t_int32_t_mask(audio_gain_mode_t legacy) {
- return convertBitmask<int32_t, audio_gain_mode_t, AudioGainMode, audio_gain_mode_t>(
- legacy, legacy2aidl_audio_gain_mode_t_AudioGainMode,
- // AUDIO_GAIN_MODE_* constants are mask-based.
- indexToEnum_bitmask<audio_gain_mode_t>,
- // AudioGainMode is index-based.
- enumToMask_index<int32_t, AudioGainMode>);
-}
-
-ConversionResult<audio_gain_config> aidl2legacy_AudioGainConfig_audio_gain_config(
- const AudioGainConfig& aidl, bool isInput) {
- audio_gain_config legacy;
- legacy.index = VALUE_OR_RETURN(convertIntegral<int>(aidl.index));
- legacy.mode = VALUE_OR_RETURN(aidl2legacy_int32_t_audio_gain_mode_t_mask(aidl.mode));
- legacy.channel_mask = VALUE_OR_RETURN(
- aidl2legacy_AudioChannelLayout_audio_channel_mask_t(aidl.channelMask, isInput));
- const bool isJoint = bitmaskIsSet(aidl.mode, AudioGainMode::JOINT);
- size_t numValues = isJoint ? 1
- : isInput ? audio_channel_count_from_in_mask(legacy.channel_mask)
- : audio_channel_count_from_out_mask(legacy.channel_mask);
- if (aidl.values.size() != numValues || aidl.values.size() > std::size(legacy.values)) {
- return unexpected(BAD_VALUE);
- }
- for (size_t i = 0; i < numValues; ++i) {
- legacy.values[i] = VALUE_OR_RETURN(convertIntegral<int>(aidl.values[i]));
- }
- legacy.ramp_duration_ms = VALUE_OR_RETURN(convertIntegral<unsigned int>(aidl.rampDurationMs));
- return legacy;
-}
-
-ConversionResult<AudioGainConfig> legacy2aidl_audio_gain_config_AudioGainConfig(
- const audio_gain_config& legacy, bool isInput) {
- AudioGainConfig aidl;
- aidl.index = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.index));
- aidl.mode = VALUE_OR_RETURN(legacy2aidl_audio_gain_mode_t_int32_t_mask(legacy.mode));
- aidl.channelMask = VALUE_OR_RETURN(
- legacy2aidl_audio_channel_mask_t_AudioChannelLayout(legacy.channel_mask, isInput));
- const bool isJoint = (legacy.mode & AUDIO_GAIN_MODE_JOINT) != 0;
- size_t numValues = isJoint ? 1
- : isInput ? audio_channel_count_from_in_mask(legacy.channel_mask)
- : audio_channel_count_from_out_mask(legacy.channel_mask);
- aidl.values.resize(numValues);
- for (size_t i = 0; i < numValues; ++i) {
- aidl.values[i] = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.values[i]));
- }
- aidl.rampDurationMs = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.ramp_duration_ms));
- return aidl;
-}
-
-ConversionResult<audio_input_flags_t> aidl2legacy_AudioInputFlags_audio_input_flags_t(
- AudioInputFlags aidl) {
- switch (aidl) {
- case AudioInputFlags::FAST:
- return AUDIO_INPUT_FLAG_FAST;
- case AudioInputFlags::HW_HOTWORD:
- return AUDIO_INPUT_FLAG_HW_HOTWORD;
- case AudioInputFlags::RAW:
- return AUDIO_INPUT_FLAG_RAW;
- case AudioInputFlags::SYNC:
- return AUDIO_INPUT_FLAG_SYNC;
- case AudioInputFlags::MMAP_NOIRQ:
- return AUDIO_INPUT_FLAG_MMAP_NOIRQ;
- case AudioInputFlags::VOIP_TX:
- return AUDIO_INPUT_FLAG_VOIP_TX;
- case AudioInputFlags::HW_AV_SYNC:
- return AUDIO_INPUT_FLAG_HW_AV_SYNC;
- case AudioInputFlags::DIRECT:
- return AUDIO_INPUT_FLAG_DIRECT;
- case AudioInputFlags::ULTRASOUND:
- return AUDIO_INPUT_FLAG_ULTRASOUND;
- }
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<AudioInputFlags> legacy2aidl_audio_input_flags_t_AudioInputFlags(
- audio_input_flags_t legacy) {
- switch (legacy) {
- case AUDIO_INPUT_FLAG_NONE:
- break; // shouldn't get here. must be listed -Werror,-Wswitch
- case AUDIO_INPUT_FLAG_FAST:
- return AudioInputFlags::FAST;
- case AUDIO_INPUT_FLAG_HW_HOTWORD:
- return AudioInputFlags::HW_HOTWORD;
- case AUDIO_INPUT_FLAG_RAW:
- return AudioInputFlags::RAW;
- case AUDIO_INPUT_FLAG_SYNC:
- return AudioInputFlags::SYNC;
- case AUDIO_INPUT_FLAG_MMAP_NOIRQ:
- return AudioInputFlags::MMAP_NOIRQ;
- case AUDIO_INPUT_FLAG_VOIP_TX:
- return AudioInputFlags::VOIP_TX;
- case AUDIO_INPUT_FLAG_HW_AV_SYNC:
- return AudioInputFlags::HW_AV_SYNC;
- case AUDIO_INPUT_FLAG_DIRECT:
- return AudioInputFlags::DIRECT;
- case AUDIO_INPUT_FLAG_ULTRASOUND:
- return AudioInputFlags::ULTRASOUND;
- }
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<audio_output_flags_t> aidl2legacy_AudioOutputFlags_audio_output_flags_t(
- AudioOutputFlags aidl) {
- switch (aidl) {
- case AudioOutputFlags::DIRECT:
- return AUDIO_OUTPUT_FLAG_DIRECT;
- case AudioOutputFlags::PRIMARY:
- return AUDIO_OUTPUT_FLAG_PRIMARY;
- case AudioOutputFlags::FAST:
- return AUDIO_OUTPUT_FLAG_FAST;
- case AudioOutputFlags::DEEP_BUFFER:
- return AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
- case AudioOutputFlags::COMPRESS_OFFLOAD:
- return AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
- case AudioOutputFlags::NON_BLOCKING:
- return AUDIO_OUTPUT_FLAG_NON_BLOCKING;
- case AudioOutputFlags::HW_AV_SYNC:
- return AUDIO_OUTPUT_FLAG_HW_AV_SYNC;
- case AudioOutputFlags::TTS:
- return AUDIO_OUTPUT_FLAG_TTS;
- case AudioOutputFlags::RAW:
- return AUDIO_OUTPUT_FLAG_RAW;
- case AudioOutputFlags::SYNC:
- return AUDIO_OUTPUT_FLAG_SYNC;
- case AudioOutputFlags::IEC958_NONAUDIO:
- return AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO;
- case AudioOutputFlags::DIRECT_PCM:
- return AUDIO_OUTPUT_FLAG_DIRECT_PCM;
- case AudioOutputFlags::MMAP_NOIRQ:
- return AUDIO_OUTPUT_FLAG_MMAP_NOIRQ;
- case AudioOutputFlags::VOIP_RX:
- return AUDIO_OUTPUT_FLAG_VOIP_RX;
- case AudioOutputFlags::INCALL_MUSIC:
- return AUDIO_OUTPUT_FLAG_INCALL_MUSIC;
- case AudioOutputFlags::GAPLESS_OFFLOAD:
- return AUDIO_OUTPUT_FLAG_GAPLESS_OFFLOAD;
- case AudioOutputFlags::ULTRASOUND:
- return AUDIO_OUTPUT_FLAG_ULTRASOUND;
- case AudioOutputFlags::SPATIALIZER:
- return AUDIO_OUTPUT_FLAG_SPATIALIZER;
- }
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<AudioOutputFlags> legacy2aidl_audio_output_flags_t_AudioOutputFlags(
- audio_output_flags_t legacy) {
- switch (legacy) {
- case AUDIO_OUTPUT_FLAG_NONE:
- break; // shouldn't get here. must be listed -Werror,-Wswitch
- case AUDIO_OUTPUT_FLAG_DIRECT:
- return AudioOutputFlags::DIRECT;
- case AUDIO_OUTPUT_FLAG_PRIMARY:
- return AudioOutputFlags::PRIMARY;
- case AUDIO_OUTPUT_FLAG_FAST:
- return AudioOutputFlags::FAST;
- case AUDIO_OUTPUT_FLAG_DEEP_BUFFER:
- return AudioOutputFlags::DEEP_BUFFER;
- case AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD:
- return AudioOutputFlags::COMPRESS_OFFLOAD;
- case AUDIO_OUTPUT_FLAG_NON_BLOCKING:
- return AudioOutputFlags::NON_BLOCKING;
- case AUDIO_OUTPUT_FLAG_HW_AV_SYNC:
- return AudioOutputFlags::HW_AV_SYNC;
- case AUDIO_OUTPUT_FLAG_TTS:
- return AudioOutputFlags::TTS;
- case AUDIO_OUTPUT_FLAG_RAW:
- return AudioOutputFlags::RAW;
- case AUDIO_OUTPUT_FLAG_SYNC:
- return AudioOutputFlags::SYNC;
- case AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO:
- return AudioOutputFlags::IEC958_NONAUDIO;
- case AUDIO_OUTPUT_FLAG_DIRECT_PCM:
- return AudioOutputFlags::DIRECT_PCM;
- case AUDIO_OUTPUT_FLAG_MMAP_NOIRQ:
- return AudioOutputFlags::MMAP_NOIRQ;
- case AUDIO_OUTPUT_FLAG_VOIP_RX:
- return AudioOutputFlags::VOIP_RX;
- case AUDIO_OUTPUT_FLAG_INCALL_MUSIC:
- return AudioOutputFlags::INCALL_MUSIC;
- case AUDIO_OUTPUT_FLAG_GAPLESS_OFFLOAD:
- return AudioOutputFlags::GAPLESS_OFFLOAD;
- case AUDIO_OUTPUT_FLAG_ULTRASOUND:
- return AudioOutputFlags::ULTRASOUND;
- case AUDIO_OUTPUT_FLAG_SPATIALIZER:
- return AudioOutputFlags::SPATIALIZER;
- }
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<audio_input_flags_t> aidl2legacy_int32_t_audio_input_flags_t_mask(
- int32_t aidl) {
- using LegacyMask = std::underlying_type_t<audio_input_flags_t>;
-
- LegacyMask converted = VALUE_OR_RETURN(
- (convertBitmask<LegacyMask, int32_t, audio_input_flags_t, AudioInputFlags>(
- aidl, aidl2legacy_AudioInputFlags_audio_input_flags_t,
- indexToEnum_index<AudioInputFlags>,
- enumToMask_bitmask<LegacyMask, audio_input_flags_t>)));
- return static_cast<audio_input_flags_t>(converted);
-}
-
-ConversionResult<int32_t> legacy2aidl_audio_input_flags_t_int32_t_mask(
- audio_input_flags_t legacy) {
- using LegacyMask = std::underlying_type_t<audio_input_flags_t>;
-
- LegacyMask legacyMask = static_cast<LegacyMask>(legacy);
- return convertBitmask<int32_t, LegacyMask, AudioInputFlags, audio_input_flags_t>(
- legacyMask, legacy2aidl_audio_input_flags_t_AudioInputFlags,
- indexToEnum_bitmask<audio_input_flags_t>,
- enumToMask_index<int32_t, AudioInputFlags>);
-}
-
-ConversionResult<audio_output_flags_t> aidl2legacy_int32_t_audio_output_flags_t_mask(
- int32_t aidl) {
- return convertBitmask<audio_output_flags_t,
- int32_t,
- audio_output_flags_t,
- AudioOutputFlags>(
- aidl, aidl2legacy_AudioOutputFlags_audio_output_flags_t,
- indexToEnum_index<AudioOutputFlags>,
- enumToMask_bitmask<audio_output_flags_t, audio_output_flags_t>);
-}
-
-ConversionResult<int32_t> legacy2aidl_audio_output_flags_t_int32_t_mask(
- audio_output_flags_t legacy) {
- using LegacyMask = std::underlying_type_t<audio_output_flags_t>;
-
- LegacyMask legacyMask = static_cast<LegacyMask>(legacy);
- return convertBitmask<int32_t, LegacyMask, AudioOutputFlags, audio_output_flags_t>(
- legacyMask, legacy2aidl_audio_output_flags_t_AudioOutputFlags,
- indexToEnum_bitmask<audio_output_flags_t>,
- enumToMask_index<int32_t, AudioOutputFlags>);
-}
-
-ConversionResult<audio_io_flags> aidl2legacy_AudioIoFlags_audio_io_flags(
- const AudioIoFlags& aidl, bool isInput) {
- audio_io_flags legacy;
- if (isInput) {
- legacy.input = VALUE_OR_RETURN(
- aidl2legacy_int32_t_audio_input_flags_t_mask(
- VALUE_OR_RETURN(UNION_GET(aidl, input))));
- } else {
- legacy.output = VALUE_OR_RETURN(
- aidl2legacy_int32_t_audio_output_flags_t_mask(
- VALUE_OR_RETURN(UNION_GET(aidl, output))));
- }
- return legacy;
-}
-
-ConversionResult<AudioIoFlags> legacy2aidl_audio_io_flags_AudioIoFlags(
- const audio_io_flags& legacy, bool isInput) {
- AudioIoFlags aidl;
- if (isInput) {
- UNION_SET(aidl, input,
- VALUE_OR_RETURN(legacy2aidl_audio_input_flags_t_int32_t_mask(legacy.input)));
- } else {
- UNION_SET(aidl, output,
- VALUE_OR_RETURN(legacy2aidl_audio_output_flags_t_int32_t_mask(legacy.output)));
- }
- return aidl;
-}
-
-ConversionResult<audio_port_config_device_ext>
-aidl2legacy_AudioPortDeviceExt_audio_port_config_device_ext(
- const AudioPortDeviceExt& aidl, const media::AudioPortDeviceExtSys& aidlDeviceExt) {
- audio_port_config_device_ext legacy;
- legacy.hw_module = VALUE_OR_RETURN(
- aidl2legacy_int32_t_audio_module_handle_t(aidlDeviceExt.hwModule));
- RETURN_IF_ERROR(aidl2legacy_AudioDevice_audio_device(
- aidl.device, &legacy.type, legacy.address));
- return legacy;
-}
-
-status_t legacy2aidl_audio_port_config_device_ext_AudioPortDeviceExt(
- const audio_port_config_device_ext& legacy,
- AudioPortDeviceExt* aidl, media::AudioPortDeviceExtSys* aidlDeviceExt) {
- aidlDeviceExt->hwModule = VALUE_OR_RETURN_STATUS(
- legacy2aidl_audio_module_handle_t_int32_t(legacy.hw_module));
- aidl->device = VALUE_OR_RETURN_STATUS(
- legacy2aidl_audio_device_AudioDevice(legacy.type, legacy.address));
- return OK;
-}
-
-ConversionResult<audio_stream_type_t> aidl2legacy_AudioStreamType_audio_stream_type_t(
- AudioStreamType aidl) {
- switch (aidl) {
- case AudioStreamType::INVALID:
- break; // return error
- case AudioStreamType::SYS_RESERVED_DEFAULT:
- return AUDIO_STREAM_DEFAULT;
- case AudioStreamType::VOICE_CALL:
- return AUDIO_STREAM_VOICE_CALL;
- case AudioStreamType::SYSTEM:
- return AUDIO_STREAM_SYSTEM;
- case AudioStreamType::RING:
- return AUDIO_STREAM_RING;
- case AudioStreamType::MUSIC:
- return AUDIO_STREAM_MUSIC;
- case AudioStreamType::ALARM:
- return AUDIO_STREAM_ALARM;
- case AudioStreamType::NOTIFICATION:
- return AUDIO_STREAM_NOTIFICATION;
- case AudioStreamType::BLUETOOTH_SCO:
- return AUDIO_STREAM_BLUETOOTH_SCO;
- case AudioStreamType::ENFORCED_AUDIBLE:
- return AUDIO_STREAM_ENFORCED_AUDIBLE;
- case AudioStreamType::DTMF:
- return AUDIO_STREAM_DTMF;
- case AudioStreamType::TTS:
- return AUDIO_STREAM_TTS;
- case AudioStreamType::ACCESSIBILITY:
- return AUDIO_STREAM_ACCESSIBILITY;
- case AudioStreamType::ASSISTANT:
- return AUDIO_STREAM_ASSISTANT;
- case AudioStreamType::SYS_RESERVED_REROUTING:
- return AUDIO_STREAM_REROUTING;
- case AudioStreamType::SYS_RESERVED_PATCH:
- return AUDIO_STREAM_PATCH;
- case AudioStreamType::CALL_ASSISTANT:
- return AUDIO_STREAM_CALL_ASSISTANT;
- }
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<AudioStreamType> legacy2aidl_audio_stream_type_t_AudioStreamType(
- audio_stream_type_t legacy) {
- switch (legacy) {
- case AUDIO_STREAM_DEFAULT:
- return AudioStreamType::SYS_RESERVED_DEFAULT;
- case AUDIO_STREAM_VOICE_CALL:
- return AudioStreamType::VOICE_CALL;
- case AUDIO_STREAM_SYSTEM:
- return AudioStreamType::SYSTEM;
- case AUDIO_STREAM_RING:
- return AudioStreamType::RING;
- case AUDIO_STREAM_MUSIC:
- return AudioStreamType::MUSIC;
- case AUDIO_STREAM_ALARM:
- return AudioStreamType::ALARM;
- case AUDIO_STREAM_NOTIFICATION:
- return AudioStreamType::NOTIFICATION;
- case AUDIO_STREAM_BLUETOOTH_SCO:
- return AudioStreamType::BLUETOOTH_SCO;
- case AUDIO_STREAM_ENFORCED_AUDIBLE:
- return AudioStreamType::ENFORCED_AUDIBLE;
- case AUDIO_STREAM_DTMF:
- return AudioStreamType::DTMF;
- case AUDIO_STREAM_TTS:
- return AudioStreamType::TTS;
- case AUDIO_STREAM_ACCESSIBILITY:
- return AudioStreamType::ACCESSIBILITY;
- case AUDIO_STREAM_ASSISTANT:
- return AudioStreamType::ASSISTANT;
- case AUDIO_STREAM_REROUTING:
- return AudioStreamType::SYS_RESERVED_REROUTING;
- case AUDIO_STREAM_PATCH:
- return AudioStreamType::SYS_RESERVED_PATCH;
- case AUDIO_STREAM_CALL_ASSISTANT:
- return AudioStreamType::CALL_ASSISTANT;
- }
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<audio_source_t> aidl2legacy_AudioSource_audio_source_t(
- AudioSource aidl) {
- switch (aidl) {
- case AudioSource::SYS_RESERVED_INVALID:
- return AUDIO_SOURCE_INVALID;
- case AudioSource::DEFAULT:
- return AUDIO_SOURCE_DEFAULT;
- case AudioSource::MIC:
- return AUDIO_SOURCE_MIC;
- case AudioSource::VOICE_UPLINK:
- return AUDIO_SOURCE_VOICE_UPLINK;
- case AudioSource::VOICE_DOWNLINK:
- return AUDIO_SOURCE_VOICE_DOWNLINK;
- case AudioSource::VOICE_CALL:
- return AUDIO_SOURCE_VOICE_CALL;
- case AudioSource::CAMCORDER:
- return AUDIO_SOURCE_CAMCORDER;
- case AudioSource::VOICE_RECOGNITION:
- return AUDIO_SOURCE_VOICE_RECOGNITION;
- case AudioSource::VOICE_COMMUNICATION:
- return AUDIO_SOURCE_VOICE_COMMUNICATION;
- case AudioSource::REMOTE_SUBMIX:
- return AUDIO_SOURCE_REMOTE_SUBMIX;
- case AudioSource::UNPROCESSED:
- return AUDIO_SOURCE_UNPROCESSED;
- case AudioSource::VOICE_PERFORMANCE:
- return AUDIO_SOURCE_VOICE_PERFORMANCE;
- case AudioSource::ULTRASOUND:
- return AUDIO_SOURCE_ULTRASOUND;
- case AudioSource::ECHO_REFERENCE:
- return AUDIO_SOURCE_ECHO_REFERENCE;
- case AudioSource::FM_TUNER:
- return AUDIO_SOURCE_FM_TUNER;
- case AudioSource::HOTWORD:
- return AUDIO_SOURCE_HOTWORD;
- }
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<AudioSource> legacy2aidl_audio_source_t_AudioSource(
- audio_source_t legacy) {
- switch (legacy) {
- case AUDIO_SOURCE_INVALID:
- return AudioSource::SYS_RESERVED_INVALID;
- case AUDIO_SOURCE_DEFAULT:
- return AudioSource::DEFAULT;
- case AUDIO_SOURCE_MIC:
- return AudioSource::MIC;
- case AUDIO_SOURCE_VOICE_UPLINK:
- return AudioSource::VOICE_UPLINK;
- case AUDIO_SOURCE_VOICE_DOWNLINK:
- return AudioSource::VOICE_DOWNLINK;
- case AUDIO_SOURCE_VOICE_CALL:
- return AudioSource::VOICE_CALL;
- case AUDIO_SOURCE_CAMCORDER:
- return AudioSource::CAMCORDER;
- case AUDIO_SOURCE_VOICE_RECOGNITION:
- return AudioSource::VOICE_RECOGNITION;
- case AUDIO_SOURCE_VOICE_COMMUNICATION:
- return AudioSource::VOICE_COMMUNICATION;
- case AUDIO_SOURCE_REMOTE_SUBMIX:
- return AudioSource::REMOTE_SUBMIX;
- case AUDIO_SOURCE_UNPROCESSED:
- return AudioSource::UNPROCESSED;
- case AUDIO_SOURCE_VOICE_PERFORMANCE:
- return AudioSource::VOICE_PERFORMANCE;
- case AUDIO_SOURCE_ULTRASOUND:
- return AudioSource::ULTRASOUND;
- case AUDIO_SOURCE_ECHO_REFERENCE:
- return AudioSource::ECHO_REFERENCE;
- case AUDIO_SOURCE_FM_TUNER:
- return AudioSource::FM_TUNER;
- case AUDIO_SOURCE_HOTWORD:
- return AudioSource::HOTWORD;
- }
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<audio_session_t> aidl2legacy_int32_t_audio_session_t(int32_t aidl) {
- return convertReinterpret<audio_session_t>(aidl);
-}
-
-ConversionResult<int32_t> legacy2aidl_audio_session_t_int32_t(audio_session_t legacy) {
- return convertReinterpret<int32_t>(legacy);
-}
-
// This type is unnamed in the original definition, thus we name it here.
using audio_port_config_mix_ext_usecase = decltype(audio_port_config_mix_ext::usecase);
@@ -1905,6 +326,27 @@
return legacy2aidl_audio_session_t_int32_t(legacy.session);
}
+ConversionResult<audio_port_config_device_ext>
+aidl2legacy_AudioPortDeviceExt_audio_port_config_device_ext(
+ const AudioPortDeviceExt& aidl, const media::AudioPortDeviceExtSys& aidlDeviceExt) {
+ audio_port_config_device_ext legacy;
+ legacy.hw_module = VALUE_OR_RETURN(
+ aidl2legacy_int32_t_audio_module_handle_t(aidlDeviceExt.hwModule));
+ RETURN_IF_ERROR(aidl2legacy_AudioDevice_audio_device(
+ aidl.device, &legacy.type, legacy.address));
+ return legacy;
+}
+
+status_t legacy2aidl_audio_port_config_device_ext_AudioPortDeviceExt(
+ const audio_port_config_device_ext& legacy,
+ AudioPortDeviceExt* aidl, media::AudioPortDeviceExtSys* aidlDeviceExt) {
+ aidlDeviceExt->hwModule = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_module_handle_t_int32_t(legacy.hw_module));
+ aidl->device = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_device_AudioDevice(legacy.type, legacy.address));
+ return OK;
+}
+
// This type is unnamed in the original definition, thus we name it here.
using audio_port_config_ext = decltype(audio_port_config::ext);
@@ -1932,7 +374,7 @@
case media::AudioPortType::SESSION:
legacy.session = VALUE_OR_RETURN(
aidl2legacy_int32_t_audio_port_config_session_ext(
- VALUE_OR_RETURN(UNION_GET(aidl, session))));
+ VALUE_OR_RETURN(UNION_GET(aidlSys, session))));
return legacy;
}
@@ -1966,16 +408,16 @@
return OK;
}
case AUDIO_PORT_TYPE_SESSION:
- UNION_SET(*aidl, session, VALUE_OR_RETURN_STATUS(
+ UNION_SET(*aidl, unspecified, false);
+ UNION_SET(*aidlSys, session, VALUE_OR_RETURN_STATUS(
legacy2aidl_audio_port_config_session_ext_int32_t(legacy.session)));
- UNION_SET(*aidlSys, unspecified, false);
return OK;
}
LOG_ALWAYS_FATAL("Shouldn't get here"); // with -Werror,-Wswitch may compile-time fail
}
-ConversionResult<audio_port_config> aidl2legacy_AudioPortConfig_audio_port_config(
- const media::AudioPortConfig& aidl) {
+ConversionResult<audio_port_config> aidl2legacy_AudioPortConfigFw_audio_port_config(
+ const media::AudioPortConfigFw& aidl) {
audio_port_config legacy{};
legacy.id = VALUE_OR_RETURN(aidl2legacy_int32_t_audio_port_handle_t(aidl.hal.id));
legacy.role = VALUE_OR_RETURN(aidl2legacy_AudioPortRole_audio_port_role_t(aidl.sys.role));
@@ -2015,9 +457,9 @@
return legacy;
}
-ConversionResult<media::AudioPortConfig> legacy2aidl_audio_port_config_AudioPortConfig(
+ConversionResult<media::AudioPortConfigFw> legacy2aidl_audio_port_config_AudioPortConfigFw(
const audio_port_config& legacy) {
- media::AudioPortConfig aidl;
+ media::AudioPortConfigFw aidl;
aidl.hal.id = VALUE_OR_RETURN(legacy2aidl_audio_port_handle_t_int32_t(legacy.id));
aidl.sys.role = VALUE_OR_RETURN(legacy2aidl_audio_port_role_t_AudioPortRole(legacy.role));
aidl.sys.type = VALUE_OR_RETURN(legacy2aidl_audio_port_type_t_AudioPortType(legacy.type));
@@ -2049,8 +491,8 @@
return aidl;
}
-ConversionResult<struct audio_patch> aidl2legacy_AudioPatch_audio_patch(
- const media::AudioPatch& aidl) {
+ConversionResult<struct audio_patch> aidl2legacy_AudioPatchFw_audio_patch(
+ const media::AudioPatchFw& aidl) {
struct audio_patch legacy;
legacy.id = VALUE_OR_RETURN(aidl2legacy_int32_t_audio_patch_handle_t(aidl.id));
legacy.num_sinks = VALUE_OR_RETURN(convertIntegral<unsigned int>(aidl.sinks.size()));
@@ -2059,7 +501,7 @@
}
for (size_t i = 0; i < legacy.num_sinks; ++i) {
legacy.sinks[i] =
- VALUE_OR_RETURN(aidl2legacy_AudioPortConfig_audio_port_config(aidl.sinks[i]));
+ VALUE_OR_RETURN(aidl2legacy_AudioPortConfigFw_audio_port_config(aidl.sinks[i]));
}
legacy.num_sources = VALUE_OR_RETURN(convertIntegral<unsigned int>(aidl.sources.size()));
if (legacy.num_sources > AUDIO_PATCH_PORTS_MAX) {
@@ -2067,14 +509,14 @@
}
for (size_t i = 0; i < legacy.num_sources; ++i) {
legacy.sources[i] =
- VALUE_OR_RETURN(aidl2legacy_AudioPortConfig_audio_port_config(aidl.sources[i]));
+ VALUE_OR_RETURN(aidl2legacy_AudioPortConfigFw_audio_port_config(aidl.sources[i]));
}
return legacy;
}
-ConversionResult<media::AudioPatch> legacy2aidl_audio_patch_AudioPatch(
+ConversionResult<media::AudioPatchFw> legacy2aidl_audio_patch_AudioPatchFw(
const struct audio_patch& legacy) {
- media::AudioPatch aidl;
+ media::AudioPatchFw aidl;
aidl.id = VALUE_OR_RETURN(legacy2aidl_audio_patch_handle_t_int32_t(legacy.id));
if (legacy.num_sinks > AUDIO_PATCH_PORTS_MAX) {
@@ -2082,14 +524,14 @@
}
for (unsigned int i = 0; i < legacy.num_sinks; ++i) {
aidl.sinks.push_back(
- VALUE_OR_RETURN(legacy2aidl_audio_port_config_AudioPortConfig(legacy.sinks[i])));
+ VALUE_OR_RETURN(legacy2aidl_audio_port_config_AudioPortConfigFw(legacy.sinks[i])));
}
if (legacy.num_sources > AUDIO_PATCH_PORTS_MAX) {
return unexpected(BAD_VALUE);
}
for (unsigned int i = 0; i < legacy.num_sources; ++i) {
aidl.sources.push_back(
- VALUE_OR_RETURN(legacy2aidl_audio_port_config_AudioPortConfig(legacy.sources[i])));
+ VALUE_OR_RETURN(legacy2aidl_audio_port_config_AudioPortConfigFw(legacy.sources[i])));
}
return aidl;
}
@@ -2099,7 +541,7 @@
const audio_io_handle_t io_handle = VALUE_OR_RETURN(
aidl2legacy_int32_t_audio_io_handle_t(aidl.ioHandle));
const struct audio_patch patch = VALUE_OR_RETURN(
- aidl2legacy_AudioPatch_audio_patch(aidl.patch));
+ aidl2legacy_AudioPatchFw_audio_patch(aidl.patch));
const bool isInput = aidl.isInput;
const uint32_t sampling_rate = VALUE_OR_RETURN(convertIntegral<uint32_t>(aidl.samplingRate));
const audio_format_t format = VALUE_OR_RETURN(
@@ -2119,7 +561,7 @@
const sp<AudioIoDescriptor>& legacy) {
media::AudioIoDescriptor aidl;
aidl.ioHandle = VALUE_OR_RETURN(legacy2aidl_audio_io_handle_t_int32_t(legacy->getIoHandle()));
- aidl.patch = VALUE_OR_RETURN(legacy2aidl_audio_patch_AudioPatch(legacy->getPatch()));
+ aidl.patch = VALUE_OR_RETURN(legacy2aidl_audio_patch_AudioPatchFw(legacy->getPatch()));
aidl.isInput = legacy->getIsInput();
aidl.samplingRate = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy->getSamplingRate()));
aidl.format = VALUE_OR_RETURN(
@@ -2149,148 +591,6 @@
return aidl;
}
-ConversionResult<audio_content_type_t>
-aidl2legacy_AudioContentType_audio_content_type_t(AudioContentType aidl) {
- switch (aidl) {
- case AudioContentType::UNKNOWN:
- return AUDIO_CONTENT_TYPE_UNKNOWN;
- case AudioContentType::SPEECH:
- return AUDIO_CONTENT_TYPE_SPEECH;
- case AudioContentType::MUSIC:
- return AUDIO_CONTENT_TYPE_MUSIC;
- case AudioContentType::MOVIE:
- return AUDIO_CONTENT_TYPE_MOVIE;
- case AudioContentType::SONIFICATION:
- return AUDIO_CONTENT_TYPE_SONIFICATION;
- case AudioContentType::ULTRASOUND:
- return AUDIO_CONTENT_TYPE_ULTRASOUND;
- }
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<AudioContentType>
-legacy2aidl_audio_content_type_t_AudioContentType(audio_content_type_t legacy) {
- switch (legacy) {
- case AUDIO_CONTENT_TYPE_UNKNOWN:
- return AudioContentType::UNKNOWN;
- case AUDIO_CONTENT_TYPE_SPEECH:
- return AudioContentType::SPEECH;
- case AUDIO_CONTENT_TYPE_MUSIC:
- return AudioContentType::MUSIC;
- case AUDIO_CONTENT_TYPE_MOVIE:
- return AudioContentType::MOVIE;
- case AUDIO_CONTENT_TYPE_SONIFICATION:
- return AudioContentType::SONIFICATION;
- case AUDIO_CONTENT_TYPE_ULTRASOUND:
- return AudioContentType::ULTRASOUND;
- }
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<audio_usage_t>
-aidl2legacy_AudioUsage_audio_usage_t(AudioUsage aidl) {
- switch (aidl) {
- case AudioUsage::INVALID:
- break; // return error
- case AudioUsage::UNKNOWN:
- return AUDIO_USAGE_UNKNOWN;
- case AudioUsage::MEDIA:
- return AUDIO_USAGE_MEDIA;
- case AudioUsage::VOICE_COMMUNICATION:
- return AUDIO_USAGE_VOICE_COMMUNICATION;
- case AudioUsage::VOICE_COMMUNICATION_SIGNALLING:
- return AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING;
- case AudioUsage::ALARM:
- return AUDIO_USAGE_ALARM;
- case AudioUsage::NOTIFICATION:
- return AUDIO_USAGE_NOTIFICATION;
- case AudioUsage::NOTIFICATION_TELEPHONY_RINGTONE:
- return AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE;
- case AudioUsage::SYS_RESERVED_NOTIFICATION_COMMUNICATION_REQUEST:
- return AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST;
- case AudioUsage::SYS_RESERVED_NOTIFICATION_COMMUNICATION_INSTANT:
- return AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT;
- case AudioUsage::SYS_RESERVED_NOTIFICATION_COMMUNICATION_DELAYED:
- return AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED;
- case AudioUsage::NOTIFICATION_EVENT:
- return AUDIO_USAGE_NOTIFICATION_EVENT;
- case AudioUsage::ASSISTANCE_ACCESSIBILITY:
- return AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY;
- case AudioUsage::ASSISTANCE_NAVIGATION_GUIDANCE:
- return AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE;
- case AudioUsage::ASSISTANCE_SONIFICATION:
- return AUDIO_USAGE_ASSISTANCE_SONIFICATION;
- case AudioUsage::GAME:
- return AUDIO_USAGE_GAME;
- case AudioUsage::VIRTUAL_SOURCE:
- return AUDIO_USAGE_VIRTUAL_SOURCE;
- case AudioUsage::ASSISTANT:
- return AUDIO_USAGE_ASSISTANT;
- case AudioUsage::CALL_ASSISTANT:
- return AUDIO_USAGE_CALL_ASSISTANT;
- case AudioUsage::EMERGENCY:
- return AUDIO_USAGE_EMERGENCY;
- case AudioUsage::SAFETY:
- return AUDIO_USAGE_SAFETY;
- case AudioUsage::VEHICLE_STATUS:
- return AUDIO_USAGE_VEHICLE_STATUS;
- case AudioUsage::ANNOUNCEMENT:
- return AUDIO_USAGE_ANNOUNCEMENT;
- }
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<AudioUsage>
-legacy2aidl_audio_usage_t_AudioUsage(audio_usage_t legacy) {
- switch (legacy) {
- case AUDIO_USAGE_UNKNOWN:
- return AudioUsage::UNKNOWN;
- case AUDIO_USAGE_MEDIA:
- return AudioUsage::MEDIA;
- case AUDIO_USAGE_VOICE_COMMUNICATION:
- return AudioUsage::VOICE_COMMUNICATION;
- case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
- return AudioUsage::VOICE_COMMUNICATION_SIGNALLING;
- case AUDIO_USAGE_ALARM:
- return AudioUsage::ALARM;
- case AUDIO_USAGE_NOTIFICATION:
- return AudioUsage::NOTIFICATION;
- case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
- return AudioUsage::NOTIFICATION_TELEPHONY_RINGTONE;
- case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
- return AudioUsage::SYS_RESERVED_NOTIFICATION_COMMUNICATION_REQUEST;
- case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
- return AudioUsage::SYS_RESERVED_NOTIFICATION_COMMUNICATION_INSTANT;
- case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
- return AudioUsage::SYS_RESERVED_NOTIFICATION_COMMUNICATION_DELAYED;
- case AUDIO_USAGE_NOTIFICATION_EVENT:
- return AudioUsage::NOTIFICATION_EVENT;
- case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
- return AudioUsage::ASSISTANCE_ACCESSIBILITY;
- case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
- return AudioUsage::ASSISTANCE_NAVIGATION_GUIDANCE;
- case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
- return AudioUsage::ASSISTANCE_SONIFICATION;
- case AUDIO_USAGE_GAME:
- return AudioUsage::GAME;
- case AUDIO_USAGE_VIRTUAL_SOURCE:
- return AudioUsage::VIRTUAL_SOURCE;
- case AUDIO_USAGE_ASSISTANT:
- return AudioUsage::ASSISTANT;
- case AUDIO_USAGE_CALL_ASSISTANT:
- return AudioUsage::CALL_ASSISTANT;
- case AUDIO_USAGE_EMERGENCY:
- return AudioUsage::EMERGENCY;
- case AUDIO_USAGE_SAFETY:
- return AudioUsage::SAFETY;
- case AUDIO_USAGE_VEHICLE_STATUS:
- return AudioUsage::VEHICLE_STATUS;
- case AUDIO_USAGE_ANNOUNCEMENT:
- return AudioUsage::ANNOUNCEMENT;
- }
- return unexpected(BAD_VALUE);
-}
-
ConversionResult<audio_flags_mask_t>
aidl2legacy_AudioFlag_audio_flags_mask_t(media::AudioFlag aidl) {
switch (aidl) {
@@ -2414,140 +714,6 @@
return aidl;
}
-ConversionResult<audio_encapsulation_mode_t>
-aidl2legacy_AudioEncapsulationMode_audio_encapsulation_mode_t(AudioEncapsulationMode aidl) {
- switch (aidl) {
- case AudioEncapsulationMode::INVALID:
- break; // return error
- case AudioEncapsulationMode::NONE:
- return AUDIO_ENCAPSULATION_MODE_NONE;
- case AudioEncapsulationMode::ELEMENTARY_STREAM:
- return AUDIO_ENCAPSULATION_MODE_ELEMENTARY_STREAM;
- case AudioEncapsulationMode::HANDLE:
- return AUDIO_ENCAPSULATION_MODE_HANDLE;
- }
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<AudioEncapsulationMode>
-legacy2aidl_audio_encapsulation_mode_t_AudioEncapsulationMode(audio_encapsulation_mode_t legacy) {
- switch (legacy) {
- case AUDIO_ENCAPSULATION_MODE_NONE:
- return AudioEncapsulationMode::NONE;
- case AUDIO_ENCAPSULATION_MODE_ELEMENTARY_STREAM:
- return AudioEncapsulationMode::ELEMENTARY_STREAM;
- case AUDIO_ENCAPSULATION_MODE_HANDLE:
- return AudioEncapsulationMode::HANDLE;
- }
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<audio_offload_info_t>
-aidl2legacy_AudioOffloadInfo_audio_offload_info_t(const AudioOffloadInfo& aidl) {
- audio_offload_info_t legacy = AUDIO_INFO_INITIALIZER;
- audio_config_base_t base = VALUE_OR_RETURN(
- aidl2legacy_AudioConfigBase_audio_config_base_t(aidl.base, false /*isInput*/));
- legacy.sample_rate = base.sample_rate;
- legacy.channel_mask = base.channel_mask;
- legacy.format = base.format;
- legacy.stream_type = VALUE_OR_RETURN(
- aidl2legacy_AudioStreamType_audio_stream_type_t(aidl.streamType));
- legacy.bit_rate = VALUE_OR_RETURN(convertIntegral<uint32_t>(aidl.bitRatePerSecond));
- legacy.duration_us = VALUE_OR_RETURN(convertIntegral<int64_t>(aidl.durationUs));
- legacy.has_video = aidl.hasVideo;
- legacy.is_streaming = aidl.isStreaming;
- legacy.bit_width = VALUE_OR_RETURN(convertIntegral<uint32_t>(aidl.bitWidth));
- legacy.offload_buffer_size = VALUE_OR_RETURN(convertIntegral<uint32_t>(aidl.offloadBufferSize));
- legacy.usage = VALUE_OR_RETURN(aidl2legacy_AudioUsage_audio_usage_t(aidl.usage));
- legacy.encapsulation_mode = VALUE_OR_RETURN(
- aidl2legacy_AudioEncapsulationMode_audio_encapsulation_mode_t(aidl.encapsulationMode));
- legacy.content_id = VALUE_OR_RETURN(convertReinterpret<int32_t>(aidl.contentId));
- legacy.sync_id = VALUE_OR_RETURN(convertReinterpret<int32_t>(aidl.syncId));
- return legacy;
-}
-
-ConversionResult<AudioOffloadInfo>
-legacy2aidl_audio_offload_info_t_AudioOffloadInfo(const audio_offload_info_t& legacy) {
- AudioOffloadInfo aidl;
- // Version 0.1 fields.
- if (legacy.size < offsetof(audio_offload_info_t, usage) + sizeof(audio_offload_info_t::usage)) {
- return unexpected(BAD_VALUE);
- }
- const audio_config_base_t base = { .sample_rate = legacy.sample_rate,
- .channel_mask = legacy.channel_mask, .format = legacy.format };
- aidl.base = VALUE_OR_RETURN(legacy2aidl_audio_config_base_t_AudioConfigBase(
- base, false /*isInput*/));
- aidl.streamType = VALUE_OR_RETURN(
- legacy2aidl_audio_stream_type_t_AudioStreamType(legacy.stream_type));
- aidl.bitRatePerSecond = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.bit_rate));
- aidl.durationUs = VALUE_OR_RETURN(convertIntegral<int64_t>(legacy.duration_us));
- aidl.hasVideo = legacy.has_video;
- aidl.isStreaming = legacy.is_streaming;
- aidl.bitWidth = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.bit_width));
- aidl.offloadBufferSize = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.offload_buffer_size));
- aidl.usage = VALUE_OR_RETURN(legacy2aidl_audio_usage_t_AudioUsage(legacy.usage));
-
- // Version 0.2 fields.
- if (legacy.version >= AUDIO_OFFLOAD_INFO_VERSION_0_2) {
- if (legacy.size <
- offsetof(audio_offload_info_t, sync_id) + sizeof(audio_offload_info_t::sync_id)) {
- return unexpected(BAD_VALUE);
- }
- aidl.encapsulationMode = VALUE_OR_RETURN(
- legacy2aidl_audio_encapsulation_mode_t_AudioEncapsulationMode(
- legacy.encapsulation_mode));
- aidl.contentId = VALUE_OR_RETURN(convertReinterpret<int32_t>(legacy.content_id));
- aidl.syncId = VALUE_OR_RETURN(convertReinterpret<int32_t>(legacy.sync_id));
- }
- return aidl;
-}
-
-ConversionResult<audio_config_t>
-aidl2legacy_AudioConfig_audio_config_t(const AudioConfig& aidl, bool isInput) {
- const audio_config_base_t legacyBase = VALUE_OR_RETURN(
- aidl2legacy_AudioConfigBase_audio_config_base_t(aidl.base, isInput));
- audio_config_t legacy = AUDIO_CONFIG_INITIALIZER;
- legacy.sample_rate = legacyBase.sample_rate;
- legacy.channel_mask = legacyBase.channel_mask;
- legacy.format = legacyBase.format;
- legacy.offload_info = VALUE_OR_RETURN(
- aidl2legacy_AudioOffloadInfo_audio_offload_info_t(aidl.offloadInfo));
- legacy.frame_count = VALUE_OR_RETURN(convertIntegral<uint32_t>(aidl.frameCount));
- return legacy;
-}
-
-ConversionResult<AudioConfig>
-legacy2aidl_audio_config_t_AudioConfig(const audio_config_t& legacy, bool isInput) {
- const audio_config_base_t base = { .sample_rate = legacy.sample_rate,
- .channel_mask = legacy.channel_mask, .format = legacy.format };
- AudioConfig aidl;
- aidl.base = VALUE_OR_RETURN(legacy2aidl_audio_config_base_t_AudioConfigBase(base, isInput));
- aidl.offloadInfo = VALUE_OR_RETURN(
- legacy2aidl_audio_offload_info_t_AudioOffloadInfo(legacy.offload_info));
- aidl.frameCount = VALUE_OR_RETURN(convertIntegral<int64_t>(legacy.frame_count));
- return aidl;
-}
-
-ConversionResult<audio_config_base_t>
-aidl2legacy_AudioConfigBase_audio_config_base_t(const AudioConfigBase& aidl, bool isInput) {
- audio_config_base_t legacy;
- legacy.sample_rate = VALUE_OR_RETURN(convertIntegral<uint32_t>(aidl.sampleRate));
- legacy.channel_mask = VALUE_OR_RETURN(
- aidl2legacy_AudioChannelLayout_audio_channel_mask_t(aidl.channelMask, isInput));
- legacy.format = VALUE_OR_RETURN(aidl2legacy_AudioFormatDescription_audio_format_t(aidl.format));
- return legacy;
-}
-
-ConversionResult<AudioConfigBase>
-legacy2aidl_audio_config_base_t_AudioConfigBase(const audio_config_base_t& legacy, bool isInput) {
- AudioConfigBase aidl;
- aidl.sampleRate = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.sample_rate));
- aidl.channelMask = VALUE_OR_RETURN(
- legacy2aidl_audio_channel_mask_t_AudioChannelLayout(legacy.channel_mask, isInput));
- aidl.format = VALUE_OR_RETURN(legacy2aidl_audio_format_t_AudioFormatDescription(legacy.format));
- return aidl;
-}
-
ConversionResult<sp<IMemory>>
aidl2legacy_SharedFileRegion_IMemory(const media::SharedFileRegion& aidl) {
sp<IMemory> legacy;
@@ -2566,8 +732,8 @@
return aidl;
}
-ConversionResult<sp<IMemory>>
-aidl2legacy_NullableSharedFileRegion_IMemory(const std::optional<media::SharedFileRegion>& aidl) {
+ConversionResult<sp<IMemory>> aidl2legacy_NullableSharedFileRegion_IMemory(
+ const std::optional<media::SharedFileRegion>& aidl) {
sp<IMemory> legacy;
if (!convertNullableSharedFileRegionToIMemory(aidl, &legacy)) {
return unexpected(BAD_VALUE);
@@ -2602,31 +768,6 @@
return aidl;
}
-ConversionResult<audio_uuid_t>
-aidl2legacy_AudioUuid_audio_uuid_t(const AudioUuid& aidl) {
- audio_uuid_t legacy;
- legacy.timeLow = VALUE_OR_RETURN(convertReinterpret<uint32_t>(aidl.timeLow));
- legacy.timeMid = VALUE_OR_RETURN(convertIntegral<uint16_t>(aidl.timeMid));
- legacy.timeHiAndVersion = VALUE_OR_RETURN(convertIntegral<uint16_t>(aidl.timeHiAndVersion));
- legacy.clockSeq = VALUE_OR_RETURN(convertIntegral<uint16_t>(aidl.clockSeq));
- if (aidl.node.size() != std::size(legacy.node)) {
- return unexpected(BAD_VALUE);
- }
- std::copy(aidl.node.begin(), aidl.node.end(), legacy.node);
- return legacy;
-}
-
-ConversionResult<AudioUuid>
-legacy2aidl_audio_uuid_t_AudioUuid(const audio_uuid_t& legacy) {
- AudioUuid aidl;
- aidl.timeLow = VALUE_OR_RETURN(convertReinterpret<int32_t>(legacy.timeLow));
- aidl.timeMid = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.timeMid));
- aidl.timeHiAndVersion = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.timeHiAndVersion));
- aidl.clockSeq = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.clockSeq));
- std::copy(legacy.node, legacy.node + std::size(legacy.node), std::back_inserter(aidl.node));
- return aidl;
-}
-
ConversionResult<effect_descriptor_t>
aidl2legacy_EffectDescriptor_effect_descriptor_t(const media::EffectDescriptor& aidl) {
effect_descriptor_t legacy;
@@ -2657,108 +798,6 @@
return aidl;
}
-ConversionResult<audio_encapsulation_metadata_type_t>
-aidl2legacy_AudioEncapsulationMetadataType_audio_encapsulation_metadata_type_t(
- AudioEncapsulationMetadataType aidl) {
- switch (aidl) {
- case AudioEncapsulationMetadataType::NONE:
- return AUDIO_ENCAPSULATION_METADATA_TYPE_NONE;
- case AudioEncapsulationMetadataType::FRAMEWORK_TUNER:
- return AUDIO_ENCAPSULATION_METADATA_TYPE_FRAMEWORK_TUNER;
- case AudioEncapsulationMetadataType::DVB_AD_DESCRIPTOR:
- return AUDIO_ENCAPSULATION_METADATA_TYPE_DVB_AD_DESCRIPTOR;
- }
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<AudioEncapsulationMetadataType>
-legacy2aidl_audio_encapsulation_metadata_type_t_AudioEncapsulationMetadataType(
- audio_encapsulation_metadata_type_t legacy) {
- switch (legacy) {
- case AUDIO_ENCAPSULATION_METADATA_TYPE_NONE:
- return AudioEncapsulationMetadataType::NONE;
- case AUDIO_ENCAPSULATION_METADATA_TYPE_FRAMEWORK_TUNER:
- return AudioEncapsulationMetadataType::FRAMEWORK_TUNER;
- case AUDIO_ENCAPSULATION_METADATA_TYPE_DVB_AD_DESCRIPTOR:
- return AudioEncapsulationMetadataType::DVB_AD_DESCRIPTOR;
- }
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<uint32_t>
-aidl2legacy_AudioEncapsulationMode_mask(int32_t aidl) {
- return convertBitmask<uint32_t,
- int32_t,
- audio_encapsulation_mode_t,
- AudioEncapsulationMode>(
- aidl, aidl2legacy_AudioEncapsulationMode_audio_encapsulation_mode_t,
- indexToEnum_index<AudioEncapsulationMode>,
- enumToMask_index<uint32_t, audio_encapsulation_mode_t>);
-}
-
-ConversionResult<int32_t>
-legacy2aidl_AudioEncapsulationMode_mask(uint32_t legacy) {
- return convertBitmask<int32_t,
- uint32_t,
- AudioEncapsulationMode,
- audio_encapsulation_mode_t>(
- legacy, legacy2aidl_audio_encapsulation_mode_t_AudioEncapsulationMode,
- indexToEnum_index<audio_encapsulation_mode_t>,
- enumToMask_index<int32_t, AudioEncapsulationMode>);
-}
-
-ConversionResult<uint32_t>
-aidl2legacy_AudioEncapsulationMetadataType_mask(int32_t aidl) {
- return convertBitmask<uint32_t,
- int32_t,
- audio_encapsulation_metadata_type_t,
- AudioEncapsulationMetadataType>(
- aidl, aidl2legacy_AudioEncapsulationMetadataType_audio_encapsulation_metadata_type_t,
- indexToEnum_index<AudioEncapsulationMetadataType>,
- enumToMask_index<uint32_t, audio_encapsulation_metadata_type_t>);
-}
-
-ConversionResult<int32_t>
-legacy2aidl_AudioEncapsulationMetadataType_mask(uint32_t legacy) {
- return convertBitmask<int32_t,
- uint32_t,
- AudioEncapsulationMetadataType,
- audio_encapsulation_metadata_type_t>(
- legacy, legacy2aidl_audio_encapsulation_metadata_type_t_AudioEncapsulationMetadataType,
- indexToEnum_index<audio_encapsulation_metadata_type_t>,
- enumToMask_index<int32_t, AudioEncapsulationMetadataType>);
-}
-
-ConversionResult<audio_port_device_ext>
-aidl2legacy_AudioPortDeviceExt_audio_port_device_ext(
- const AudioPortDeviceExt& aidl, const media::AudioPortDeviceExtSys& aidlSys) {
- audio_port_device_ext legacy;
- legacy.hw_module = VALUE_OR_RETURN(
- aidl2legacy_int32_t_audio_module_handle_t(aidlSys.hwModule));
- RETURN_IF_ERROR(aidl2legacy_AudioDevice_audio_device(
- aidl.device, &legacy.type, legacy.address));
- legacy.encapsulation_modes = VALUE_OR_RETURN(
- aidl2legacy_AudioEncapsulationMode_mask(aidlSys.encapsulationModes));
- legacy.encapsulation_metadata_types = VALUE_OR_RETURN(
- aidl2legacy_AudioEncapsulationMetadataType_mask(
- aidlSys.encapsulationMetadataTypes));
- return legacy;
-}
-
-status_t legacy2aidl_audio_port_device_ext_AudioPortDeviceExt(
- const audio_port_device_ext& legacy,
- AudioPortDeviceExt* aidl, media::AudioPortDeviceExtSys* aidlDeviceExt) {
- aidlDeviceExt->hwModule = VALUE_OR_RETURN_STATUS(
- legacy2aidl_audio_module_handle_t_int32_t(legacy.hw_module));
- aidl->device = VALUE_OR_RETURN_STATUS(
- legacy2aidl_audio_device_AudioDevice(legacy.type, legacy.address));
- aidlDeviceExt->encapsulationModes = VALUE_OR_RETURN_STATUS(
- legacy2aidl_AudioEncapsulationMode_mask(legacy.encapsulation_modes));
- aidlDeviceExt->encapsulationMetadataTypes = VALUE_OR_RETURN_STATUS(
- legacy2aidl_AudioEncapsulationMetadataType_mask(legacy.encapsulation_metadata_types));
- return OK;
-}
-
ConversionResult<audio_port_mix_ext>
aidl2legacy_AudioPortMixExt_audio_port_mix_ext(
const AudioPortMixExt& aidl, const media::AudioPortMixExtSys& aidlSys) {
@@ -2789,6 +828,36 @@
return legacy2aidl_audio_session_t_int32_t(legacy.session);
}
+ConversionResult<audio_port_device_ext>
+aidl2legacy_AudioPortDeviceExt_audio_port_device_ext(
+ const AudioPortDeviceExt& aidl, const media::AudioPortDeviceExtSys& aidlSys) {
+ audio_port_device_ext legacy;
+ legacy.hw_module = VALUE_OR_RETURN(
+ aidl2legacy_int32_t_audio_module_handle_t(aidlSys.hwModule));
+ RETURN_IF_ERROR(aidl2legacy_AudioDevice_audio_device(
+ aidl.device, &legacy.type, legacy.address));
+ legacy.encapsulation_modes = VALUE_OR_RETURN(
+ aidl2legacy_AudioEncapsulationMode_mask(aidlSys.encapsulationModes));
+ legacy.encapsulation_metadata_types = VALUE_OR_RETURN(
+ aidl2legacy_AudioEncapsulationMetadataType_mask(
+ aidlSys.encapsulationMetadataTypes));
+ return legacy;
+}
+
+status_t legacy2aidl_audio_port_device_ext_AudioPortDeviceExt(
+ const audio_port_device_ext& legacy,
+ AudioPortDeviceExt* aidl, media::AudioPortDeviceExtSys* aidlDeviceExt) {
+ aidlDeviceExt->hwModule = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_module_handle_t_int32_t(legacy.hw_module));
+ aidl->device = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_device_AudioDevice(legacy.type, legacy.address));
+ aidlDeviceExt->encapsulationModes = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_AudioEncapsulationMode_mask(legacy.encapsulation_modes));
+ aidlDeviceExt->encapsulationMetadataTypes = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_AudioEncapsulationMetadataType_mask(legacy.encapsulation_metadata_types));
+ return OK;
+}
+
// This type is unnamed in the original definition, thus we name it here.
using audio_port_v7_ext = decltype(audio_port_v7::ext);
@@ -2816,7 +885,7 @@
case media::AudioPortType::SESSION:
legacy.session = VALUE_OR_RETURN(
aidl2legacy_int32_t_audio_port_session_ext(
- VALUE_OR_RETURN(UNION_GET(aidl, session))));
+ VALUE_OR_RETURN(UNION_GET(aidlSys, session))));
return legacy;
}
@@ -2852,103 +921,16 @@
return OK;
}
case AUDIO_PORT_TYPE_SESSION:
- UNION_SET(*aidl, session, VALUE_OR_RETURN_STATUS(
+ UNION_SET(*aidl, unspecified, false);
+ UNION_SET(*aidlSys, session, VALUE_OR_RETURN_STATUS(
legacy2aidl_audio_port_session_ext_int32_t(legacy.session)));
- UNION_SET(*aidlSys, unspecified, false);
return OK;
}
LOG_ALWAYS_FATAL("Shouldn't get here"); // with -Werror,-Wswitch may compile-time fail
}
-ConversionResult<audio_profile>
-aidl2legacy_AudioProfile_audio_profile(const AudioProfile& aidl, bool isInput) {
- audio_profile legacy;
- legacy.format = VALUE_OR_RETURN(aidl2legacy_AudioFormatDescription_audio_format_t(aidl.format));
-
- if (aidl.sampleRates.size() > std::size(legacy.sample_rates)) {
- return unexpected(BAD_VALUE);
- }
- RETURN_IF_ERROR(
- convertRange(aidl.sampleRates.begin(), aidl.sampleRates.end(), legacy.sample_rates,
- convertIntegral<int32_t, unsigned int>));
- legacy.num_sample_rates = aidl.sampleRates.size();
-
- if (aidl.channelMasks.size() > std::size(legacy.channel_masks)) {
- return unexpected(BAD_VALUE);
- }
- RETURN_IF_ERROR(
- convertRange(aidl.channelMasks.begin(), aidl.channelMasks.end(), legacy.channel_masks,
- [isInput](const AudioChannelLayout& l) {
- return aidl2legacy_AudioChannelLayout_audio_channel_mask_t(l, isInput);
- }));
- legacy.num_channel_masks = aidl.channelMasks.size();
-
- legacy.encapsulation_type = VALUE_OR_RETURN(
- aidl2legacy_AudioEncapsulationType_audio_encapsulation_type_t(aidl.encapsulationType));
- return legacy;
-}
-
-ConversionResult<AudioProfile>
-legacy2aidl_audio_profile_AudioProfile(const audio_profile& legacy, bool isInput) {
- AudioProfile aidl;
- aidl.format = VALUE_OR_RETURN(legacy2aidl_audio_format_t_AudioFormatDescription(legacy.format));
-
- if (legacy.num_sample_rates > std::size(legacy.sample_rates)) {
- return unexpected(BAD_VALUE);
- }
- RETURN_IF_ERROR(
- convertRange(legacy.sample_rates, legacy.sample_rates + legacy.num_sample_rates,
- std::back_inserter(aidl.sampleRates),
- convertIntegral<unsigned int, int32_t>));
-
- if (legacy.num_channel_masks > std::size(legacy.channel_masks)) {
- return unexpected(BAD_VALUE);
- }
- RETURN_IF_ERROR(
- convertRange(legacy.channel_masks, legacy.channel_masks + legacy.num_channel_masks,
- std::back_inserter(aidl.channelMasks),
- [isInput](audio_channel_mask_t m) {
- return legacy2aidl_audio_channel_mask_t_AudioChannelLayout(m, isInput);
- }));
-
- aidl.encapsulationType = VALUE_OR_RETURN(
- legacy2aidl_audio_encapsulation_type_t_AudioEncapsulationType(
- legacy.encapsulation_type));
- return aidl;
-}
-
-ConversionResult<audio_gain>
-aidl2legacy_AudioGain_audio_gain(const AudioGain& aidl, bool isInput) {
- audio_gain legacy;
- legacy.mode = VALUE_OR_RETURN(aidl2legacy_int32_t_audio_gain_mode_t_mask(aidl.mode));
- legacy.channel_mask = VALUE_OR_RETURN(aidl2legacy_AudioChannelLayout_audio_channel_mask_t(
- aidl.channelMask, isInput));
- legacy.min_value = VALUE_OR_RETURN(convertIntegral<int>(aidl.minValue));
- legacy.max_value = VALUE_OR_RETURN(convertIntegral<int>(aidl.maxValue));
- legacy.default_value = VALUE_OR_RETURN(convertIntegral<int>(aidl.defaultValue));
- legacy.step_value = VALUE_OR_RETURN(convertIntegral<unsigned int>(aidl.stepValue));
- legacy.min_ramp_ms = VALUE_OR_RETURN(convertIntegral<unsigned int>(aidl.minRampMs));
- legacy.max_ramp_ms = VALUE_OR_RETURN(convertIntegral<unsigned int>(aidl.maxRampMs));
- return legacy;
-}
-
-ConversionResult<AudioGain>
-legacy2aidl_audio_gain_AudioGain(const audio_gain& legacy, bool isInput) {
- AudioGain aidl;
- aidl.mode = VALUE_OR_RETURN(legacy2aidl_audio_gain_mode_t_int32_t_mask(legacy.mode));
- aidl.channelMask = VALUE_OR_RETURN(
- legacy2aidl_audio_channel_mask_t_AudioChannelLayout(legacy.channel_mask, isInput));
- aidl.minValue = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.min_value));
- aidl.maxValue = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.max_value));
- aidl.defaultValue = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.default_value));
- aidl.stepValue = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.step_value));
- aidl.minRampMs = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.min_ramp_ms));
- aidl.maxRampMs = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.max_ramp_ms));
- return aidl;
-}
-
ConversionResult<audio_port_v7>
-aidl2legacy_AudioPort_audio_port_v7(const media::AudioPort& aidl) {
+aidl2legacy_AudioPortFw_audio_port_v7(const media::AudioPortFw& aidl) {
audio_port_v7 legacy;
legacy.id = VALUE_OR_RETURN(aidl2legacy_int32_t_audio_port_handle_t(aidl.hal.id));
legacy.role = VALUE_OR_RETURN(aidl2legacy_AudioPortRole_audio_port_role_t(aidl.sys.role));
@@ -2987,15 +969,15 @@
legacy.num_gains = aidl.hal.gains.size();
legacy.active_config = VALUE_OR_RETURN(
- aidl2legacy_AudioPortConfig_audio_port_config(aidl.sys.activeConfig));
+ aidl2legacy_AudioPortConfigFw_audio_port_config(aidl.sys.activeConfig));
legacy.ext = VALUE_OR_RETURN(
aidl2legacy_AudioPortExt_audio_port_v7_ext(aidl.hal.ext, aidl.sys.type, aidl.sys.ext));
return legacy;
}
-ConversionResult<media::AudioPort>
-legacy2aidl_audio_port_v7_AudioPort(const audio_port_v7& legacy) {
- media::AudioPort aidl;
+ConversionResult<media::AudioPortFw>
+legacy2aidl_audio_port_v7_AudioPortFw(const audio_port_v7& legacy) {
+ media::AudioPortFw aidl;
aidl.hal.id = VALUE_OR_RETURN(legacy2aidl_audio_port_handle_t_int32_t(legacy.id));
aidl.sys.role = VALUE_OR_RETURN(legacy2aidl_audio_port_role_t_AudioPortRole(legacy.role));
aidl.sys.type = VALUE_OR_RETURN(legacy2aidl_audio_port_type_t_AudioPortType(legacy.type));
@@ -3034,65 +1016,13 @@
aidl.sys.gains.resize(legacy.num_gains);
aidl.sys.activeConfig = VALUE_OR_RETURN(
- legacy2aidl_audio_port_config_AudioPortConfig(legacy.active_config));
+ legacy2aidl_audio_port_config_AudioPortConfigFw(legacy.active_config));
aidl.sys.activeConfig.hal.portId = aidl.hal.id;
RETURN_IF_ERROR(
legacy2aidl_AudioPortExt(legacy.ext, legacy.type, &aidl.hal.ext, &aidl.sys.ext));
return aidl;
}
-ConversionResult<audio_mode_t>
-aidl2legacy_AudioMode_audio_mode_t(AudioMode aidl) {
- switch (aidl) {
- case AudioMode::SYS_RESERVED_INVALID:
- return AUDIO_MODE_INVALID;
- case AudioMode::SYS_RESERVED_CURRENT:
- return AUDIO_MODE_CURRENT;
- case AudioMode::NORMAL:
- return AUDIO_MODE_NORMAL;
- case AudioMode::RINGTONE:
- return AUDIO_MODE_RINGTONE;
- case AudioMode::IN_CALL:
- return AUDIO_MODE_IN_CALL;
- case AudioMode::IN_COMMUNICATION:
- return AUDIO_MODE_IN_COMMUNICATION;
- case AudioMode::CALL_SCREEN:
- return AUDIO_MODE_CALL_SCREEN;
- case AudioMode::SYS_RESERVED_CALL_REDIRECT:
- return AUDIO_MODE_CALL_REDIRECT;
- case AudioMode::SYS_RESERVED_COMMUNICATION_REDIRECT:
- return AUDIO_MODE_COMMUNICATION_REDIRECT;
- }
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<AudioMode>
-legacy2aidl_audio_mode_t_AudioMode(audio_mode_t legacy) {
- switch (legacy) {
- case AUDIO_MODE_INVALID:
- return AudioMode::SYS_RESERVED_INVALID;
- case AUDIO_MODE_CURRENT:
- return AudioMode::SYS_RESERVED_CURRENT;
- case AUDIO_MODE_NORMAL:
- return AudioMode::NORMAL;
- case AUDIO_MODE_RINGTONE:
- return AudioMode::RINGTONE;
- case AUDIO_MODE_IN_CALL:
- return AudioMode::IN_CALL;
- case AUDIO_MODE_IN_COMMUNICATION:
- return AudioMode::IN_COMMUNICATION;
- case AUDIO_MODE_CALL_SCREEN:
- return AudioMode::CALL_SCREEN;
- case AUDIO_MODE_CALL_REDIRECT:
- return AudioMode::SYS_RESERVED_CALL_REDIRECT;
- case AUDIO_MODE_COMMUNICATION_REDIRECT:
- return AudioMode::SYS_RESERVED_COMMUNICATION_REDIRECT;
- case AUDIO_MODE_CNT:
- break;
- }
- return unexpected(BAD_VALUE);
-}
-
ConversionResult<audio_unique_id_use_t>
aidl2legacy_AudioUniqueIdUse_audio_unique_id_use_t(media::AudioUniqueIdUse aidl) {
switch (aidl) {
@@ -3161,160 +1091,6 @@
return convertReinterpret<int32_t>(legacy);
}
-ConversionResult<audio_dual_mono_mode_t>
-aidl2legacy_AudioDualMonoMode_audio_dual_mono_mode_t(media::AudioDualMonoMode aidl) {
- switch (aidl) {
- case media::AudioDualMonoMode::OFF:
- return AUDIO_DUAL_MONO_MODE_OFF;
- case media::AudioDualMonoMode::LR:
- return AUDIO_DUAL_MONO_MODE_LR;
- case media::AudioDualMonoMode::LL:
- return AUDIO_DUAL_MONO_MODE_LL;
- case media::AudioDualMonoMode::RR:
- return AUDIO_DUAL_MONO_MODE_RR;
- }
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<media::AudioDualMonoMode>
-legacy2aidl_audio_dual_mono_mode_t_AudioDualMonoMode(audio_dual_mono_mode_t legacy) {
- switch (legacy) {
- case AUDIO_DUAL_MONO_MODE_OFF:
- return media::AudioDualMonoMode::OFF;
- case AUDIO_DUAL_MONO_MODE_LR:
- return media::AudioDualMonoMode::LR;
- case AUDIO_DUAL_MONO_MODE_LL:
- return media::AudioDualMonoMode::LL;
- case AUDIO_DUAL_MONO_MODE_RR:
- return media::AudioDualMonoMode::RR;
- }
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<audio_timestretch_fallback_mode_t>
-aidl2legacy_int32_t_audio_timestretch_fallback_mode_t(int32_t aidl) {
- return convertReinterpret<audio_timestretch_fallback_mode_t>(aidl);
-}
-
-ConversionResult<int32_t>
-legacy2aidl_audio_timestretch_fallback_mode_t_int32_t(audio_timestretch_fallback_mode_t legacy) {
- return convertReinterpret<int32_t>(legacy);
-}
-
-ConversionResult<audio_timestretch_stretch_mode_t>
-aidl2legacy_int32_t_audio_timestretch_stretch_mode_t(int32_t aidl) {
- return convertReinterpret<audio_timestretch_stretch_mode_t>(aidl);
-}
-
-ConversionResult<int32_t>
-legacy2aidl_audio_timestretch_stretch_mode_t_int32_t(audio_timestretch_stretch_mode_t legacy) {
- return convertReinterpret<int32_t>(legacy);
-}
-
-ConversionResult<audio_playback_rate_t>
-aidl2legacy_AudioPlaybackRate_audio_playback_rate_t(const media::AudioPlaybackRate& aidl) {
- audio_playback_rate_t legacy;
- legacy.mSpeed = aidl.speed;
- legacy.mPitch = aidl.pitch;
- legacy.mFallbackMode = VALUE_OR_RETURN(
- aidl2legacy_int32_t_audio_timestretch_fallback_mode_t(aidl.fallbackMode));
- legacy.mStretchMode = VALUE_OR_RETURN(
- aidl2legacy_int32_t_audio_timestretch_stretch_mode_t(aidl.stretchMode));
- return legacy;
-}
-
-ConversionResult<media::AudioPlaybackRate>
-legacy2aidl_audio_playback_rate_t_AudioPlaybackRate(const audio_playback_rate_t& legacy) {
- media::AudioPlaybackRate aidl;
- aidl.speed = legacy.mSpeed;
- aidl.pitch = legacy.mPitch;
- aidl.fallbackMode = VALUE_OR_RETURN(
- legacy2aidl_audio_timestretch_fallback_mode_t_int32_t(legacy.mFallbackMode));
- aidl.stretchMode = VALUE_OR_RETURN(
- legacy2aidl_audio_timestretch_stretch_mode_t_int32_t(legacy.mStretchMode));
- return aidl;
-}
-
-ConversionResult<audio_standard_t>
-aidl2legacy_AudioStandard_audio_standard_t(AudioStandard aidl) {
- switch (aidl) {
- case AudioStandard::NONE:
- return AUDIO_STANDARD_NONE;
- case AudioStandard::EDID:
- return AUDIO_STANDARD_EDID;
- }
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<AudioStandard>
-legacy2aidl_audio_standard_t_AudioStandard(audio_standard_t legacy) {
- switch (legacy) {
- case AUDIO_STANDARD_NONE:
- return AudioStandard::NONE;
- case AUDIO_STANDARD_EDID:
- return AudioStandard::EDID;
- }
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<audio_extra_audio_descriptor>
-aidl2legacy_ExtraAudioDescriptor_audio_extra_audio_descriptor(
- const ExtraAudioDescriptor& aidl) {
- audio_extra_audio_descriptor legacy;
- legacy.standard = VALUE_OR_RETURN(aidl2legacy_AudioStandard_audio_standard_t(aidl.standard));
- if (aidl.audioDescriptor.size() > EXTRA_AUDIO_DESCRIPTOR_SIZE) {
- return unexpected(BAD_VALUE);
- }
- legacy.descriptor_length = aidl.audioDescriptor.size();
- std::copy(aidl.audioDescriptor.begin(), aidl.audioDescriptor.end(),
- std::begin(legacy.descriptor));
- legacy.encapsulation_type =
- VALUE_OR_RETURN(aidl2legacy_AudioEncapsulationType_audio_encapsulation_type_t(
- aidl.encapsulationType));
- return legacy;
-}
-
-ConversionResult<ExtraAudioDescriptor>
-legacy2aidl_audio_extra_audio_descriptor_ExtraAudioDescriptor(
- const audio_extra_audio_descriptor& legacy) {
- ExtraAudioDescriptor aidl;
- aidl.standard = VALUE_OR_RETURN(legacy2aidl_audio_standard_t_AudioStandard(legacy.standard));
- if (legacy.descriptor_length > EXTRA_AUDIO_DESCRIPTOR_SIZE) {
- return unexpected(BAD_VALUE);
- }
- aidl.audioDescriptor.resize(legacy.descriptor_length);
- std::copy(legacy.descriptor, legacy.descriptor + legacy.descriptor_length,
- aidl.audioDescriptor.begin());
- aidl.encapsulationType =
- VALUE_OR_RETURN(legacy2aidl_audio_encapsulation_type_t_AudioEncapsulationType(
- legacy.encapsulation_type));
- return aidl;
-}
-
-ConversionResult<audio_encapsulation_type_t>
-aidl2legacy_AudioEncapsulationType_audio_encapsulation_type_t(
- const AudioEncapsulationType& aidl) {
- switch (aidl) {
- case AudioEncapsulationType::NONE:
- return AUDIO_ENCAPSULATION_TYPE_NONE;
- case AudioEncapsulationType::IEC61937:
- return AUDIO_ENCAPSULATION_TYPE_IEC61937;
- }
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<AudioEncapsulationType>
-legacy2aidl_audio_encapsulation_type_t_AudioEncapsulationType(
- const audio_encapsulation_type_t & legacy) {
- switch (legacy) {
- case AUDIO_ENCAPSULATION_TYPE_NONE:
- return AudioEncapsulationType::NONE;
- case AUDIO_ENCAPSULATION_TYPE_IEC61937:
- return AudioEncapsulationType::IEC61937;
- }
- return unexpected(BAD_VALUE);
-}
-
ConversionResult<TrackSecondaryOutputInfoPair>
aidl2legacy_TrackSecondaryOutputInfo_TrackSecondaryOutputInfoPair(
const media::TrackSecondaryOutputInfo& aidl) {
@@ -3387,25 +1163,4 @@
indexToEnum_bitmask<audio_direct_mode_t>,
enumToMask_index<int32_t, media::AudioDirectMode>);
}
-
-ConversionResult<audio_latency_mode_t>
-aidl2legacy_LatencyMode_audio_latency_mode_t(media::LatencyMode aidl) {
- switch (aidl) {
- case media::LatencyMode::FREE:
- return AUDIO_LATENCY_MODE_FREE;
- case media::LatencyMode::LOW:
- return AUDIO_LATENCY_MODE_LOW;
- }
- return unexpected(BAD_VALUE);
-}
-ConversionResult<media::LatencyMode>
-legacy2aidl_audio_latency_mode_t_LatencyMode(audio_latency_mode_t legacy) {
- switch (legacy) {
- case AUDIO_LATENCY_MODE_FREE:
- return media::LatencyMode::FREE;
- case AUDIO_LATENCY_MODE_LOW:
- return media::LatencyMode::LOW;
- }
- return unexpected(BAD_VALUE);
-}
} // namespace android
diff --git a/media/libaudioclient/Android.bp b/media/libaudioclient/Android.bp
index dccef0e..1c0535d 100644
--- a/media/libaudioclient/Android.bp
+++ b/media/libaudioclient/Android.bp
@@ -54,8 +54,10 @@
"AudioVolumeGroup.cpp",
"PolicyAidlConversion.cpp"
],
+ defaults: [
+ "latest_android_media_audio_common_types_cpp_export_shared",
+ ],
shared_libs: [
- "android.media.audio.common.types-V1-cpp",
"audioclient-types-aidl-cpp",
"audioflinger-aidl-cpp",
"audiopolicy-aidl-cpp",
@@ -76,7 +78,6 @@
include_dirs: ["system/media/audio_utils/include"],
export_include_dirs: ["include"],
export_shared_lib_headers: [
- "android.media.audio.common.types-V1-cpp",
"audioclient-types-aidl-cpp",
"audioflinger-aidl-cpp",
"audiopolicy-aidl-cpp",
@@ -116,8 +117,10 @@
"RecordingActivityTracker.cpp",
"TrackPlayerBase.cpp",
],
+ defaults: [
+ "latest_android_media_audio_common_types_cpp_shared",
+ ],
shared_libs: [
- "android.media.audio.common.types-V1-cpp",
"audioclient-types-aidl-cpp",
"audioflinger-aidl-cpp",
"audiopolicy-aidl-cpp",
@@ -125,6 +128,7 @@
"audiopolicy-types-aidl-cpp",
"av-types-aidl-cpp",
"capture_state_listener-aidl-cpp",
+ "libaudio_aidl_conversion_common_cpp",
"libaudioclient_aidl_conversion",
"libaudiofoundation",
"libaudioutils",
@@ -190,87 +194,29 @@
},
}
-// This is intended for clients needing to include AidlConversionUtil.h, without dragging in a lot of extra
-// dependencies.
-cc_library_headers {
- name: "libaudioclient_aidl_conversion_util",
- host_supported: true,
- vendor_available: true,
- double_loadable: true,
- min_sdk_version: "29",
- export_include_dirs: [
- "include",
- ],
- header_libs: [
- "libbase_headers",
- "liberror_headers",
- ],
- export_header_lib_headers: [
- "libbase_headers",
- "liberror_headers",
- ],
- apex_available: [
- "//apex_available:platform",
- "com.android.bluetooth",
- "com.android.media",
- "com.android.media.swcodec",
- ],
- target: {
- darwin: {
- enabled: false,
- },
- },
-}
-
cc_library {
name: "libaudioclient_aidl_conversion",
srcs: ["AidlConversion.cpp"],
+ shared_libs: [
+ "audioclient-types-aidl-cpp",
+ ],
+ static_libs: [
+ "libaudio_aidl_conversion_common_cpp",
+ ],
export_include_dirs: ["include"],
- host_supported: true,
- vendor_available: true,
- double_loadable: true,
- min_sdk_version: "29",
header_libs: [
- "libaudioclient_aidl_conversion_util",
- "libaudio_system_headers",
+ "libaudio_aidl_conversion_common_util_cpp",
],
export_header_lib_headers: [
- "libaudioclient_aidl_conversion_util",
- ],
- shared_libs: [
- "android.media.audio.common.types-V1-cpp",
- "audioclient-types-aidl-cpp",
- "libbase",
- "libbinder",
- "liblog",
- "libshmemcompat",
- "libstagefright_foundation",
- "libutils",
- "shared-file-region-aidl-cpp",
- "framework-permission-aidl-cpp",
+ "libaudio_aidl_conversion_common_util_cpp",
],
export_shared_lib_headers: [
- "android.media.audio.common.types-V1-cpp",
"audioclient-types-aidl-cpp",
- "libbase",
- "shared-file-region-aidl-cpp",
],
- cflags: [
- "-Wall",
- "-Werror",
- "-Wno-error=deprecated-declarations",
+ defaults: [
+ "audio_aidl_conversion_common_default",
+ "latest_android_media_audio_common_types_cpp_export_shared",
],
- sanitize: {
- misc_undefined: [
- "unsigned-integer-overflow",
- "signed-integer-overflow",
- ],
- },
- target: {
- darwin: {
- enabled: false,
- },
- },
}
// AIDL interface between libaudioclient and framework.jar
@@ -278,6 +224,7 @@
name: "libaudioclient_aidl",
srcs: [
"aidl/android/media/IPlayer.aidl",
+ "aidl/android/media/AudioHalVersion.aidl",
],
path: "aidl",
}
@@ -302,12 +249,26 @@
double_loadable: true,
vendor_available: true,
srcs: [
+ "aidl/android/media/EffectConfig.aidl",
"aidl/android/media/IEffect.aidl",
"aidl/android/media/IEffectClient.aidl",
],
imports: [
+ "android.media.audio.common.types-V2",
"shared-file-region-aidl",
],
+ backend: {
+ cpp: {
+ min_sdk_version: "29",
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.media",
+ ],
+ },
+ java: {
+ sdk_version: "module_current",
+ },
+ },
}
aidl_interface {
@@ -321,16 +282,15 @@
"aidl/android/media/AudioAttributesInternal.aidl",
"aidl/android/media/AudioClient.aidl",
"aidl/android/media/AudioDirectMode.aidl",
- "aidl/android/media/AudioDualMonoMode.aidl",
"aidl/android/media/AudioFlag.aidl",
"aidl/android/media/AudioGainSys.aidl",
+ "aidl/android/media/AudioHalVersion.aidl",
"aidl/android/media/AudioIoConfigEvent.aidl",
"aidl/android/media/AudioIoDescriptor.aidl",
- "aidl/android/media/AudioPatch.aidl",
- "aidl/android/media/AudioPlaybackRate.aidl",
- "aidl/android/media/AudioPort.aidl",
+ "aidl/android/media/AudioPatchFw.aidl",
+ "aidl/android/media/AudioPortFw.aidl",
"aidl/android/media/AudioPortSys.aidl",
- "aidl/android/media/AudioPortConfig.aidl",
+ "aidl/android/media/AudioPortConfigFw.aidl",
"aidl/android/media/AudioPortConfigSys.aidl",
"aidl/android/media/AudioPortDeviceExtSys.aidl",
"aidl/android/media/AudioPortExtSys.aidl",
@@ -342,11 +302,10 @@
"aidl/android/media/AudioUniqueIdUse.aidl",
"aidl/android/media/AudioVibratorInfo.aidl",
"aidl/android/media/EffectDescriptor.aidl",
- "aidl/android/media/LatencyMode.aidl",
"aidl/android/media/TrackSecondaryOutputInfo.aidl",
],
imports: [
- "android.media.audio.common.types-V1",
+ "android.media.audio.common.types-V2",
"framework-permission-aidl",
],
backend: {
@@ -390,7 +349,7 @@
"aidl/android/media/SpatializerHeadTrackingMode.aidl",
],
imports: [
- "android.media.audio.common.types-V1",
+ "android.media.audio.common.types-V2",
"audioclient-types-aidl",
],
backend: {
@@ -433,7 +392,7 @@
"aidl/android/media/IAudioTrackCallback.aidl",
],
imports: [
- "android.media.audio.common.types-V1",
+ "android.media.audio.common.types-V2",
"audioclient-types-aidl",
"av-types-aidl",
"effect-aidl",
@@ -470,7 +429,7 @@
"aidl/android/media/IAudioPolicyServiceClient.aidl",
],
imports: [
- "android.media.audio.common.types-V1",
+ "android.media.audio.common.types-V2",
"audioclient-types-aidl",
"audiopolicy-types-aidl",
"capture_state_listener-aidl",
diff --git a/media/libaudioclient/AudioEffect.cpp b/media/libaudioclient/AudioEffect.cpp
index dc21c52..2870c4c 100644
--- a/media/libaudioclient/AudioEffect.cpp
+++ b/media/libaudioclient/AudioEffect.cpp
@@ -89,7 +89,7 @@
return NO_INIT;
}
- if (type == NULL && uuid == NULL) {
+ if (type == nullptr && uuid == nullptr) {
ALOGW("Must specify at least type or uuid");
return BAD_VALUE;
}
@@ -99,8 +99,8 @@
mCallback = callback;
memset(&mDescriptor, 0, sizeof(effect_descriptor_t));
- mDescriptor.type = *(type != NULL ? type : EFFECT_UUID_NULL);
- mDescriptor.uuid = *(uuid != NULL ? uuid : EFFECT_UUID_NULL);
+ mDescriptor.type = *(type != nullptr ? type : EFFECT_UUID_NULL);
+ mDescriptor.uuid = *(uuid != nullptr ? uuid : EFFECT_UUID_NULL);
// TODO b/182392769: use attribution source util
mIEffectClient = new EffectClient(this);
@@ -292,7 +292,7 @@
AudioSystem::releaseAudioSessionId(mSessionId,
VALUE_OR_FATAL(aidl2legacy_int32_t_pid_t(mClientAttributionSource.pid)));
}
- if (mIEffect != NULL) {
+ if (mIEffect != nullptr) {
mIEffect->disconnect();
IInterface::asBinder(mIEffect)->unlinkToDeath(mIEffectClient);
}
@@ -370,7 +370,7 @@
if (mEnabled == (cmdCode == EFFECT_CMD_ENABLE)) {
return NO_ERROR;
}
- if (replySize == NULL || *replySize != sizeof(status_t) || replyData == NULL) {
+ if (replySize == nullptr || *replySize != sizeof(status_t) || replyData == nullptr) {
return BAD_VALUE;
}
mLock.lock();
@@ -413,7 +413,7 @@
return (mStatus == ALREADY_EXISTS) ? (status_t) INVALID_OPERATION : mStatus;
}
- if (param == NULL || param->psize == 0 || param->vsize == 0) {
+ if (param == nullptr || param->psize == 0 || param->vsize == 0) {
return BAD_VALUE;
}
@@ -448,8 +448,7 @@
if (mStatus != NO_ERROR) {
return (mStatus == ALREADY_EXISTS) ? (status_t) INVALID_OPERATION : mStatus;
}
-
- if (param == NULL || param->psize == 0 || param->vsize == 0) {
+ if (param == nullptr || param->psize == 0 || param->vsize == 0) {
return BAD_VALUE;
}
@@ -504,8 +503,7 @@
if (mStatus != NO_ERROR && mStatus != ALREADY_EXISTS) {
return mStatus;
}
-
- if (param == NULL || param->psize == 0 || param->vsize == 0) {
+ if (param == nullptr || param->psize == 0 || param->vsize == 0) {
return BAD_VALUE;
}
@@ -529,6 +527,36 @@
return status;
}
+status_t AudioEffect::getConfigs(
+ audio_config_base_t *inputCfg, audio_config_base_t *outputCfg)
+{
+ if (mProbe) {
+ return INVALID_OPERATION;
+ }
+ if (mStatus != NO_ERROR && mStatus != ALREADY_EXISTS) {
+ return mStatus;
+ }
+ if (inputCfg == NULL || outputCfg == NULL) {
+ return BAD_VALUE;
+ }
+ status_t status;
+ media::EffectConfig cfg;
+ Status bs = mIEffect->getConfig(&cfg, &status);
+ if (!bs.isOk()) {
+ status = statusTFromBinderStatus(bs);
+ ALOGW("%s received status %d from binder transaction", __func__, status);
+ return status;
+ }
+ if (status == NO_ERROR) {
+ *inputCfg = VALUE_OR_RETURN_STATUS(aidl2legacy_AudioConfigBase_audio_config_base_t(
+ cfg.inputCfg, cfg.isOnInputStream));
+ *outputCfg = VALUE_OR_RETURN_STATUS(aidl2legacy_AudioConfigBase_audio_config_base_t(
+ cfg.outputCfg, cfg.isOnInputStream));
+ } else {
+ ALOGW("%s received status %d from the effect", __func__, status);
+ }
+ return status;
+}
// -------------------------------------------------------------------------
@@ -602,6 +630,9 @@
status_t AudioEffect::queryNumberEffects(uint32_t *numEffects)
{
+ if (numEffects == nullptr) {
+ return BAD_VALUE;
+ }
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
return af->queryNumberEffects(numEffects);
@@ -609,6 +640,9 @@
status_t AudioEffect::queryEffect(uint32_t index, effect_descriptor_t *descriptor)
{
+ if (descriptor == nullptr) {
+ return BAD_VALUE;
+ }
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
return af->queryEffect(index, descriptor);
@@ -619,6 +653,9 @@
uint32_t preferredTypeFlag,
effect_descriptor_t *descriptor)
{
+ if (uuid == nullptr || type == nullptr || descriptor == nullptr) {
+ return BAD_VALUE;
+ }
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
return af->getEffectDescriptor(uuid, type, preferredTypeFlag, descriptor);
@@ -649,6 +686,9 @@
status_t AudioEffect::newEffectUniqueId(audio_unique_id_t* id)
{
+ if (id == nullptr) {
+ return BAD_VALUE;
+ }
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
*id = af->newAudioUniqueId(AUDIO_UNIQUE_ID_USE_EFFECT);
@@ -662,14 +702,15 @@
audio_source_t source,
audio_unique_id_t *id)
{
+ if ((typeStr == nullptr && uuidStr == nullptr) || id == nullptr) {
+ return BAD_VALUE;
+ }
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
- if (typeStr == NULL && uuidStr == NULL) return BAD_VALUE;
-
// Convert type & uuid from string to effect_uuid_t.
effect_uuid_t type;
- if (typeStr != NULL) {
+ if (typeStr != nullptr) {
status_t res = stringToGuid(typeStr, &type);
if (res != OK) return res;
} else {
@@ -677,7 +718,7 @@
}
effect_uuid_t uuid;
- if (uuidStr != NULL) {
+ if (uuidStr != nullptr) {
status_t res = stringToGuid(uuidStr, &uuid);
if (res != OK) return res;
} else {
@@ -705,14 +746,15 @@
audio_usage_t usage,
audio_unique_id_t *id)
{
+ if ((typeStr == nullptr && uuidStr == nullptr) || id == nullptr) {
+ return BAD_VALUE;
+ }
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
- if (typeStr == NULL && uuidStr == NULL) return BAD_VALUE;
-
// Convert type & uuid from string to effect_uuid_t.
effect_uuid_t type;
- if (typeStr != NULL) {
+ if (typeStr != nullptr) {
status_t res = stringToGuid(typeStr, &type);
if (res != OK) return res;
} else {
@@ -720,7 +762,7 @@
}
effect_uuid_t uuid;
- if (uuidStr != NULL) {
+ if (uuidStr != nullptr) {
status_t res = stringToGuid(uuidStr, &uuid);
if (res != OK) return res;
} else {
@@ -763,7 +805,7 @@
status_t AudioEffect::stringToGuid(const char *str, effect_uuid_t *guid)
{
- if (str == NULL || guid == NULL) {
+ if (str == nullptr || guid == nullptr) {
return BAD_VALUE;
}
@@ -789,7 +831,7 @@
status_t AudioEffect::guidToString(const effect_uuid_t *guid, char *str, size_t maxLen)
{
- if (guid == NULL || str == NULL) {
+ if (guid == nullptr || str == nullptr) {
return BAD_VALUE;
}
diff --git a/media/libaudioclient/AudioPolicy.cpp b/media/libaudioclient/AudioPolicy.cpp
index c2f7229..4d2b6b1 100644
--- a/media/libaudioclient/AudioPolicy.cpp
+++ b/media/libaudioclient/AudioPolicy.cpp
@@ -71,6 +71,10 @@
return NO_ERROR;
}
+bool AudioMixMatchCriterion::isExcludeCriterion() const {
+ return mRule & RULE_EXCLUSION_MASK;
+}
+
//
// AudioMix implementation
//
@@ -91,10 +95,11 @@
if (size > MAX_CRITERIA_PER_MIX) {
size = MAX_CRITERIA_PER_MIX;
}
+ mCriteria.reserve(size);
for (size_t i = 0; i < size; i++) {
AudioMixMatchCriterion criterion;
if (criterion.readFromParcel(parcel) == NO_ERROR) {
- mCriteria.add(criterion);
+ mCriteria.push_back(criterion);
}
}
return NO_ERROR;
@@ -135,18 +140,18 @@
return NO_ERROR;
}
-void AudioMix::setExcludeUid(uid_t uid) const {
+void AudioMix::setExcludeUid(uid_t uid) {
AudioMixMatchCriterion crit;
crit.mRule = RULE_EXCLUDE_UID;
crit.mValue.mUid = uid;
- mCriteria.add(crit);
+ mCriteria.push_back(crit);
}
-void AudioMix::setMatchUid(uid_t uid) const {
+void AudioMix::setMatchUid(uid_t uid) {
AudioMixMatchCriterion crit;
crit.mRule = RULE_MATCH_UID;
crit.mValue.mUid = uid;
- mCriteria.add(crit);
+ mCriteria.push_back(crit);
}
bool AudioMix::hasUidRule(bool match, uid_t uid) const {
@@ -169,18 +174,18 @@
return false;
}
-void AudioMix::setExcludeUserId(int userId) const {
+void AudioMix::setExcludeUserId(int userId) {
AudioMixMatchCriterion crit;
crit.mRule = RULE_EXCLUDE_USERID;
crit.mValue.mUserId = userId;
- mCriteria.add(crit);
+ mCriteria.push_back(crit);
}
-void AudioMix::setMatchUserId(int userId) const {
+void AudioMix::setMatchUserId(int userId) {
AudioMixMatchCriterion crit;
crit.mRule = RULE_MATCH_USERID;
crit.mValue.mUserId = userId;
- mCriteria.add(crit);
+ mCriteria.push_back(crit);
}
bool AudioMix::hasUserIdRule(bool match, int userId) const {
diff --git a/media/libaudioclient/AudioRecord.cpp b/media/libaudioclient/AudioRecord.cpp
index 15203d6..69d73ad 100644
--- a/media/libaudioclient/AudioRecord.cpp
+++ b/media/libaudioclient/AudioRecord.cpp
@@ -146,39 +146,6 @@
audio_channel_mask_t channelMask,
const AttributionSourceState& client,
size_t frameCount,
- legacy_callback_t callback,
- void* user,
- uint32_t notificationFrames,
- audio_session_t sessionId,
- transfer_type transferType,
- audio_input_flags_t flags,
- const audio_attributes_t* pAttributes,
- audio_port_handle_t selectedDeviceId,
- audio_microphone_direction_t selectedMicDirection,
- float microphoneFieldDimension)
- : mActive(false),
- mStatus(NO_INIT),
- mClientAttributionSource(client),
- mSessionId(AUDIO_SESSION_ALLOCATE),
- mPreviousPriority(ANDROID_PRIORITY_NORMAL),
- mPreviousSchedulingGroup(SP_DEFAULT),
- mProxy(NULL)
-{
- uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(mClientAttributionSource.uid));
- pid_t pid = VALUE_OR_FATAL(aidl2legacy_int32_t_pid_t(mClientAttributionSource.pid));
- (void)set(inputSource, sampleRate, format, channelMask, frameCount, callback, user,
- notificationFrames, false /*threadCanCallJava*/, sessionId, transferType, flags,
- uid, pid, pAttributes, selectedDeviceId, selectedMicDirection,
- microphoneFieldDimension);
-}
-
-AudioRecord::AudioRecord(
- audio_source_t inputSource,
- uint32_t sampleRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
- const AttributionSourceState& client,
- size_t frameCount,
const wp<IAudioRecordCallback>& callback,
uint32_t notificationFrames,
audio_session_t sessionId,
@@ -255,37 +222,6 @@
mDeviceCallback.clear();
}
}
-namespace {
-class LegacyCallbackWrapper : public AudioRecord::IAudioRecordCallback {
- const AudioRecord::legacy_callback_t mCallback;
- void* const mData;
-
- public:
- LegacyCallbackWrapper(AudioRecord::legacy_callback_t callback, void* user)
- : mCallback(callback), mData(user) {}
-
- size_t onMoreData(const AudioRecord::Buffer& buffer) override {
- AudioRecord::Buffer copy = buffer;
- mCallback(AudioRecord::EVENT_MORE_DATA, mData, ©);
- return copy.size();
- }
-
- void onOverrun() override { mCallback(AudioRecord::EVENT_OVERRUN, mData, nullptr); }
-
- void onMarker(uint32_t markerPosition) override {
- mCallback(AudioRecord::EVENT_MARKER, mData, &markerPosition);
- }
-
- void onNewPos(uint32_t newPos) override {
- mCallback(AudioRecord::EVENT_NEW_POS, mData, &newPos);
- }
-
- void onNewIAudioRecord() override {
- mCallback(AudioRecord::EVENT_NEW_IAUDIORECORD, mData, nullptr);
- }
-};
-} // namespace
-
status_t AudioRecord::set(
audio_source_t inputSource,
uint32_t sampleRate,
@@ -479,37 +415,6 @@
return status;
}
-status_t AudioRecord::set(
- audio_source_t inputSource,
- uint32_t sampleRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
- size_t frameCount,
- legacy_callback_t callback,
- void* user,
- uint32_t notificationFrames,
- bool threadCanCallJava,
- audio_session_t sessionId,
- transfer_type transferType,
- audio_input_flags_t flags,
- uid_t uid,
- pid_t pid,
- const audio_attributes_t* pAttributes,
- audio_port_handle_t selectedDeviceId,
- audio_microphone_direction_t selectedMicDirection,
- float microphoneFieldDimension,
- int32_t maxSharedAudioHistoryMs)
-{
- if (callback != nullptr) {
- mLegacyCallbackWrapper = sp<LegacyCallbackWrapper>::make(callback, user);
- } else if (user) {
- LOG_ALWAYS_FATAL("Callback data provided without callback pointer!");
- }
- return set(inputSource, sampleRate, format, channelMask, frameCount, mLegacyCallbackWrapper,
- notificationFrames, threadCanCallJava, sessionId, transferType, flags, uid, pid,
- pAttributes, selectedDeviceId, selectedMicDirection, microphoneFieldDimension,
- maxSharedAudioHistoryMs);
-}
// -------------------------------------------------------------------------
status_t AudioRecord::start(AudioSystem::sync_event_t event, audio_session_t triggerSession)
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index bacca3a..31d95e6 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -671,12 +671,12 @@
}
Status AudioSystem::AudioFlingerClient::onSupportedLatencyModesChanged(
- int output, const std::vector<media::LatencyMode>& latencyModes) {
+ int output, const std::vector<media::audio::common::AudioLatencyMode>& latencyModes) {
audio_io_handle_t outputLegacy = VALUE_OR_RETURN_BINDER_STATUS(
aidl2legacy_int32_t_audio_io_handle_t(output));
std::vector<audio_latency_mode_t> modesLegacy = VALUE_OR_RETURN_BINDER_STATUS(
convertContainer<std::vector<audio_latency_mode_t>>(
- latencyModes, aidl2legacy_LatencyMode_audio_latency_mode_t));
+ latencyModes, aidl2legacy_AudioLatencyMode_audio_latency_mode_t));
std::vector<sp<SupportedLatencyModesCallback>> callbacks;
{
@@ -1532,7 +1532,7 @@
legacy2aidl_audio_port_type_t_AudioPortType(type));
Int numPortsAidl;
numPortsAidl.value = VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(*num_ports));
- std::vector<media::AudioPort> portsAidl;
+ std::vector<media::AudioPortFw> portsAidl;
int32_t generationAidl;
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
@@ -1540,7 +1540,7 @@
*num_ports = VALUE_OR_RETURN_STATUS(convertIntegral<unsigned int>(numPortsAidl.value));
*generation = VALUE_OR_RETURN_STATUS(convertIntegral<unsigned int>(generationAidl));
RETURN_STATUS_IF_ERROR(convertRange(portsAidl.begin(), portsAidl.end(), ports,
- aidl2legacy_AudioPort_audio_port_v7));
+ aidl2legacy_AudioPortFw_audio_port_v7));
return OK;
}
@@ -1551,10 +1551,10 @@
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
- media::AudioPort portAidl;
+ media::AudioPortFw portAidl;
RETURN_STATUS_IF_ERROR(
statusTFromBinderStatus(aps->getAudioPort(port->id, &portAidl)));
- *port = VALUE_OR_RETURN_STATUS(aidl2legacy_AudioPort_audio_port_v7(portAidl));
+ *port = VALUE_OR_RETURN_STATUS(aidl2legacy_AudioPortFw_audio_port_v7(portAidl));
return OK;
}
@@ -1567,8 +1567,8 @@
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
- media::AudioPatch patchAidl = VALUE_OR_RETURN_STATUS(
- legacy2aidl_audio_patch_AudioPatch(*patch));
+ media::AudioPatchFw patchAidl = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_patch_AudioPatchFw(*patch));
int32_t handleAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_patch_handle_t_int32_t(*handle));
RETURN_STATUS_IF_ERROR(
statusTFromBinderStatus(aps->createAudioPatch(patchAidl, handleAidl, &handleAidl)));
@@ -1598,7 +1598,7 @@
Int numPatchesAidl;
numPatchesAidl.value = VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(*num_patches));
- std::vector<media::AudioPatch> patchesAidl;
+ std::vector<media::AudioPatchFw> patchesAidl;
int32_t generationAidl;
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
@@ -1606,7 +1606,7 @@
*num_patches = VALUE_OR_RETURN_STATUS(convertIntegral<unsigned int>(numPatchesAidl.value));
*generation = VALUE_OR_RETURN_STATUS(convertIntegral<unsigned int>(generationAidl));
RETURN_STATUS_IF_ERROR(convertRange(patchesAidl.begin(), patchesAidl.end(), patches,
- aidl2legacy_AudioPatch_audio_patch));
+ aidl2legacy_AudioPatchFw_audio_patch));
return OK;
}
@@ -1618,8 +1618,8 @@
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
- media::AudioPortConfig configAidl = VALUE_OR_RETURN_STATUS(
- legacy2aidl_audio_port_config_AudioPortConfig(*config));
+ media::AudioPortConfigFw configAidl = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_port_config_AudioPortConfigFw(*config));
return statusTFromBinderStatus(aps->setAudioPortConfig(configAidl));
}
@@ -1839,8 +1839,8 @@
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
- media::AudioPortConfig sourceAidl = VALUE_OR_RETURN_STATUS(
- legacy2aidl_audio_port_config_AudioPortConfig(*source));
+ media::AudioPortConfigFw sourceAidl = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_port_config_AudioPortConfigFw(*source));
media::AudioAttributesInternal attributesAidl = VALUE_OR_RETURN_STATUS(
legacy2aidl_audio_attributes_t_AudioAttributesInternal(*attributes));
int32_t portIdAidl;
@@ -2339,6 +2339,9 @@
const AudioDeviceTypeAddrVector &devices,
bool *canBeSpatialized) {
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ if (canBeSpatialized == nullptr) {
+ return BAD_VALUE;
+ }
if (aps == 0) {
return PERMISSION_DENIED;
}
@@ -2384,7 +2387,7 @@
status_t AudioSystem::getDirectProfilesForAttributes(const audio_attributes_t* attr,
std::vector<audio_profile>* audioProfiles) {
- if (attr == nullptr) {
+ if (attr == nullptr || audioProfiles == nullptr) {
return BAD_VALUE;
}
@@ -2423,6 +2426,32 @@
return af->getSupportedLatencyModes(output, modes);
}
+status_t AudioSystem::setBluetoothVariableLatencyEnabled(bool enabled) {
+ const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ if (af == nullptr) {
+ return PERMISSION_DENIED;
+ }
+ return af->setBluetoothVariableLatencyEnabled(enabled);
+}
+
+status_t AudioSystem::isBluetoothVariableLatencyEnabled(
+ bool *enabled) {
+ const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ if (af == nullptr) {
+ return PERMISSION_DENIED;
+ }
+ return af->isBluetoothVariableLatencyEnabled(enabled);
+}
+
+status_t AudioSystem::supportsBluetoothVariableLatency(
+ bool *support) {
+ const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ if (af == nullptr) {
+ return PERMISSION_DENIED;
+ }
+ return af->supportsBluetoothVariableLatency(support);
+}
+
class CaptureStateListenerImpl : public media::BnCaptureStateListener,
public IBinder::DeathRecipient {
public:
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index 6ab8339..ff4b071 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -325,45 +325,6 @@
}
};
}
-
-AudioTrack::AudioTrack(
- audio_stream_type_t streamType,
- uint32_t sampleRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
- size_t frameCount,
- audio_output_flags_t flags,
- legacy_callback_t callback,
- void* user,
- int32_t notificationFrames,
- audio_session_t sessionId,
- transfer_type transferType,
- const audio_offload_info_t *offloadInfo,
- const AttributionSourceState& attributionSource,
- const audio_attributes_t* pAttributes,
- bool doNotReconnect,
- float maxRequiredSpeed,
- audio_port_handle_t selectedDeviceId)
- : mStatus(NO_INIT),
- mState(STATE_STOPPED),
- mPreviousPriority(ANDROID_PRIORITY_NORMAL),
- mPreviousSchedulingGroup(SP_DEFAULT),
- mPausedPosition(0),
- mAudioTrackCallback(new AudioTrackCallback())
-{
- mAttributes = AUDIO_ATTRIBUTES_INITIALIZER;
- if (callback != nullptr) {
- mLegacyCallbackWrapper = sp<LegacyCallbackWrapper>::make(callback, user);
- } else if (user) {
- LOG_ALWAYS_FATAL("Callback data provided without callback pointer!");
- }
- mSetParams = std::unique_ptr<SetParams>{new SetParams{
- streamType, sampleRate, format, channelMask, frameCount, flags, mLegacyCallbackWrapper,
- notificationFrames, 0 /*sharedBuffer*/, false /*threadCanCallJava*/, sessionId,
- transferType, offloadInfo, attributionSource, pAttributes, doNotReconnect,
- maxRequiredSpeed, selectedDeviceId}};
-}
-
AudioTrack::AudioTrack(
audio_stream_type_t streamType,
uint32_t sampleRate,
@@ -397,44 +358,6 @@
doNotReconnect, maxRequiredSpeed, AUDIO_PORT_HANDLE_NONE}};
}
-AudioTrack::AudioTrack(
- audio_stream_type_t streamType,
- uint32_t sampleRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
- const sp<IMemory>& sharedBuffer,
- audio_output_flags_t flags,
- legacy_callback_t callback,
- void* user,
- int32_t notificationFrames,
- audio_session_t sessionId,
- transfer_type transferType,
- const audio_offload_info_t *offloadInfo,
- const AttributionSourceState& attributionSource,
- const audio_attributes_t* pAttributes,
- bool doNotReconnect,
- float maxRequiredSpeed)
- : mStatus(NO_INIT),
- mState(STATE_STOPPED),
- mPreviousPriority(ANDROID_PRIORITY_NORMAL),
- mPreviousSchedulingGroup(SP_DEFAULT),
- mPausedPosition(0),
- mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE),
- mAudioTrackCallback(new AudioTrackCallback())
-{
- mAttributes = AUDIO_ATTRIBUTES_INITIALIZER;
- if (callback) {
- mLegacyCallbackWrapper = sp<LegacyCallbackWrapper>::make(callback, user);
- } else if (user) {
- LOG_ALWAYS_FATAL("Callback data provided without callback pointer!");
- }
- mSetParams = std::unique_ptr<SetParams>{new SetParams{
- streamType, sampleRate, format, channelMask, 0 /*frameCount*/, flags,
- mLegacyCallbackWrapper, notificationFrames, sharedBuffer, false /*threadCanCallJava*/,
- sessionId, transferType, offloadInfo, attributionSource, pAttributes, doNotReconnect,
- maxRequiredSpeed, AUDIO_PORT_HANDLE_NONE}};
-}
-
void AudioTrack::onFirstRef() {
if (mSetParams) {
set(*mSetParams);
@@ -496,38 +419,6 @@
mDeviceCallback.clear();
}
}
-
-status_t AudioTrack::set(
- audio_stream_type_t streamType,
- uint32_t sampleRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
- size_t frameCount,
- audio_output_flags_t flags,
- legacy_callback_t callback,
- void * user,
- int32_t notificationFrames,
- const sp<IMemory>& sharedBuffer,
- bool threadCanCallJava,
- audio_session_t sessionId,
- transfer_type transferType,
- const audio_offload_info_t *offloadInfo,
- const AttributionSourceState& attributionSource,
- const audio_attributes_t* pAttributes,
- bool doNotReconnect,
- float maxRequiredSpeed,
- audio_port_handle_t selectedDeviceId)
-{
- if (callback) {
- mLegacyCallbackWrapper = sp<LegacyCallbackWrapper>::make(callback, user);
- } else if (user) {
- LOG_ALWAYS_FATAL("Callback data provided without callback pointer!");
- }
- return set(streamType, sampleRate,format, channelMask, frameCount, flags,
- mLegacyCallbackWrapper, notificationFrames, sharedBuffer, threadCanCallJava,
- sessionId, transferType, offloadInfo, attributionSource, pAttributes,
- doNotReconnect, maxRequiredSpeed, selectedDeviceId);
-}
status_t AudioTrack::set(
audio_stream_type_t streamType,
uint32_t sampleRate,
@@ -559,7 +450,7 @@
std::string errorMessage;
// Note mPortId is not valid until the track is created, so omit mPortId in ALOG for set.
ALOGV("%s(): streamType %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, "
- "flags #%x, notificationFrames %d, sessionId %d, transferType %d, uid %d, pid %d",
+ "flags %#x, notificationFrames %d, sessionId %d, transferType %d, uid %d, pid %d",
__func__,
streamType, sampleRate, format, channelMask, frameCount, flags, notificationFrames,
sessionId, transferType, attributionSource.uid, attributionSource.pid);
@@ -1357,7 +1248,7 @@
status_t AudioTrack::getDualMonoMode(audio_dual_mono_mode_t* mode) const
{
AutoMutex lock(mLock);
- media::AudioDualMonoMode mediaMode;
+ media::audio::common::AudioDualMonoMode mediaMode;
const status_t status = statusTFromBinderStatus(mAudioTrack->getDualMonoMode(&mediaMode));
if (status == NO_ERROR) {
*mode = VALUE_OR_RETURN_STATUS(
@@ -1398,6 +1289,10 @@
legacy2aidl_audio_playback_rate_t_AudioPlaybackRate(playbackRate))));
if (status == NO_ERROR) {
mPlaybackRate = playbackRate;
+ } else if (status == INVALID_OPERATION
+ && playbackRate.mSpeed == 1.0f && mPlaybackRate.mPitch == 1.0f) {
+ mPlaybackRate = playbackRate;
+ return NO_ERROR;
}
return status;
}
@@ -1468,7 +1363,7 @@
{
AutoMutex lock(mLock);
if (isOffloadedOrDirect_l()) {
- media::AudioPlaybackRate playbackRateTemp;
+ media::audio::common::AudioPlaybackRate playbackRateTemp;
const status_t status = statusTFromBinderStatus(
mAudioTrack->getPlaybackRateParameters(&playbackRateTemp));
if (status == NO_ERROR) { // update local version if changed.
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index f290453..255fd1e 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -666,17 +666,19 @@
}
status_t AudioFlingerClientAdapter::getAudioPort(struct audio_port_v7* port) {
- media::AudioPort portAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_port_v7_AudioPort(*port));
- media::AudioPort aidlRet;
+ media::AudioPortFw portAidl = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_port_v7_AudioPortFw(*port));
+ media::AudioPortFw aidlRet;
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
mDelegate->getAudioPort(portAidl, &aidlRet)));
- *port = VALUE_OR_RETURN_STATUS(aidl2legacy_AudioPort_audio_port_v7(aidlRet));
+ *port = VALUE_OR_RETURN_STATUS(aidl2legacy_AudioPortFw_audio_port_v7(aidlRet));
return OK;
}
status_t AudioFlingerClientAdapter::createAudioPatch(const struct audio_patch* patch,
audio_patch_handle_t* handle) {
- media::AudioPatch patchAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_patch_AudioPatch(*patch));
+ media::AudioPatchFw patchAidl = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_patch_AudioPatchFw(*patch));
int32_t aidlRet = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_patch_handle_t_int32_t(
AUDIO_PATCH_HANDLE_NONE));
if (handle != nullptr) {
@@ -697,18 +699,18 @@
status_t AudioFlingerClientAdapter::listAudioPatches(unsigned int* num_patches,
struct audio_patch* patches) {
- std::vector<media::AudioPatch> aidlRet;
+ std::vector<media::AudioPatchFw> aidlRet;
int32_t maxPatches = VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(*num_patches));
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
mDelegate->listAudioPatches(maxPatches, &aidlRet)));
*num_patches = VALUE_OR_RETURN_STATUS(convertIntegral<unsigned int>(aidlRet.size()));
return convertRange(aidlRet.begin(), aidlRet.end(), patches,
- aidl2legacy_AudioPatch_audio_patch);
+ aidl2legacy_AudioPatchFw_audio_patch);
}
status_t AudioFlingerClientAdapter::setAudioPortConfig(const struct audio_port_config* config) {
- media::AudioPortConfig configAidl = VALUE_OR_RETURN_STATUS(
- legacy2aidl_audio_port_config_AudioPortConfig(*config));
+ media::AudioPortConfigFw configAidl = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_port_config_AudioPortConfigFw(*config));
return statusTFromBinderStatus(mDelegate->setAudioPortConfig(configAidl));
}
@@ -805,16 +807,16 @@
status_t AudioFlingerClientAdapter::setDeviceConnectedState(
const struct audio_port_v7 *port, bool connected) {
- media::AudioPort aidlPort = VALUE_OR_RETURN_STATUS(
- legacy2aidl_audio_port_v7_AudioPort(*port));
+ media::AudioPortFw aidlPort = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_port_v7_AudioPortFw(*port));
return statusTFromBinderStatus(mDelegate->setDeviceConnectedState(aidlPort, connected));
}
status_t AudioFlingerClientAdapter::setRequestedLatencyMode(
audio_io_handle_t output, audio_latency_mode_t mode) {
int32_t outputAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_io_handle_t_int32_t(output));
- media::LatencyMode modeAidl = VALUE_OR_RETURN_STATUS(
- legacy2aidl_audio_latency_mode_t_LatencyMode(mode));
+ media::audio::common::AudioLatencyMode modeAidl = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_latency_mode_t_AudioLatencyMode(mode));
return statusTFromBinderStatus(mDelegate->setRequestedLatencyMode(outputAidl, modeAidl));
}
@@ -825,14 +827,40 @@
}
int32_t outputAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_io_handle_t_int32_t(output));
- std::vector<media::LatencyMode> modesAidl;
+ std::vector<media::audio::common::AudioLatencyMode> modesAidl;
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
mDelegate->getSupportedLatencyModes(outputAidl, &modesAidl)));
*modes = VALUE_OR_RETURN_STATUS(
convertContainer<std::vector<audio_latency_mode_t>>(modesAidl,
- aidl2legacy_LatencyMode_audio_latency_mode_t));
+ aidl2legacy_AudioLatencyMode_audio_latency_mode_t));
+
+ return NO_ERROR;
+}
+
+status_t AudioFlingerClientAdapter::setBluetoothVariableLatencyEnabled(bool enabled) {
+ return statusTFromBinderStatus(mDelegate->setBluetoothVariableLatencyEnabled(enabled));
+}
+
+status_t AudioFlingerClientAdapter::isBluetoothVariableLatencyEnabled(bool* enabled) {
+ if (enabled == nullptr) {
+ return BAD_VALUE;
+ }
+
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
+ mDelegate->isBluetoothVariableLatencyEnabled(enabled)));
+
+ return NO_ERROR;
+}
+
+status_t AudioFlingerClientAdapter::supportsBluetoothVariableLatency(bool* support) {
+ if (support == nullptr) {
+ return BAD_VALUE;
+ }
+
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
+ mDelegate->supportsBluetoothVariableLatency(support)));
return NO_ERROR;
}
@@ -1211,17 +1239,17 @@
return Status::fromStatusT(mDelegate->setLowRamDevice(isLowRamDevice, totalMemory));
}
-Status AudioFlingerServerAdapter::getAudioPort(const media::AudioPort& port,
- media::AudioPort* _aidl_return) {
- audio_port_v7 portLegacy = VALUE_OR_RETURN_BINDER(aidl2legacy_AudioPort_audio_port_v7(port));
+Status AudioFlingerServerAdapter::getAudioPort(const media::AudioPortFw& port,
+ media::AudioPortFw* _aidl_return) {
+ audio_port_v7 portLegacy = VALUE_OR_RETURN_BINDER(aidl2legacy_AudioPortFw_audio_port_v7(port));
RETURN_BINDER_IF_ERROR(mDelegate->getAudioPort(&portLegacy));
- *_aidl_return = VALUE_OR_RETURN_BINDER(legacy2aidl_audio_port_v7_AudioPort(portLegacy));
+ *_aidl_return = VALUE_OR_RETURN_BINDER(legacy2aidl_audio_port_v7_AudioPortFw(portLegacy));
return Status::ok();
}
-Status AudioFlingerServerAdapter::createAudioPatch(const media::AudioPatch& patch,
+Status AudioFlingerServerAdapter::createAudioPatch(const media::AudioPatchFw& patch,
int32_t* _aidl_return) {
- audio_patch patchLegacy = VALUE_OR_RETURN_BINDER(aidl2legacy_AudioPatch_audio_patch(patch));
+ audio_patch patchLegacy = VALUE_OR_RETURN_BINDER(aidl2legacy_AudioPatchFw_audio_patch(patch));
audio_patch_handle_t handleLegacy = VALUE_OR_RETURN_BINDER(
aidl2legacy_int32_t_audio_patch_handle_t(*_aidl_return));
RETURN_BINDER_IF_ERROR(mDelegate->createAudioPatch(&patchLegacy, &handleLegacy));
@@ -1236,7 +1264,7 @@
}
Status AudioFlingerServerAdapter::listAudioPatches(int32_t maxCount,
- std::vector<media::AudioPatch>* _aidl_return) {
+ std::vector<media::AudioPatchFw>* _aidl_return) {
unsigned int count = VALUE_OR_RETURN_BINDER(convertIntegral<unsigned int>(maxCount));
count = std::min(count, static_cast<unsigned int>(MAX_ITEMS_PER_LIST));
std::unique_ptr<audio_patch[]> patchesLegacy(new audio_patch[count]);
@@ -1244,13 +1272,13 @@
RETURN_BINDER_IF_ERROR(convertRange(&patchesLegacy[0],
&patchesLegacy[count],
std::back_inserter(*_aidl_return),
- legacy2aidl_audio_patch_AudioPatch));
+ legacy2aidl_audio_patch_AudioPatchFw));
return Status::ok();
}
-Status AudioFlingerServerAdapter::setAudioPortConfig(const media::AudioPortConfig& config) {
+Status AudioFlingerServerAdapter::setAudioPortConfig(const media::AudioPortConfigFw& config) {
audio_port_config configLegacy = VALUE_OR_RETURN_BINDER(
- aidl2legacy_AudioPortConfig_audio_port_config(config));
+ aidl2legacy_AudioPortConfigFw_audio_port_config(config));
return Status::fromStatusT(mDelegate->setAudioPortConfig(&configLegacy));
}
@@ -1328,23 +1356,23 @@
}
Status AudioFlingerServerAdapter::setDeviceConnectedState(
- const media::AudioPort& port, bool connected) {
- audio_port_v7 portLegacy = VALUE_OR_RETURN_BINDER(aidl2legacy_AudioPort_audio_port_v7(port));
+ const media::AudioPortFw& port, bool connected) {
+ audio_port_v7 portLegacy = VALUE_OR_RETURN_BINDER(aidl2legacy_AudioPortFw_audio_port_v7(port));
return Status::fromStatusT(mDelegate->setDeviceConnectedState(&portLegacy, connected));
}
Status AudioFlingerServerAdapter::setRequestedLatencyMode(
- int32_t output, media::LatencyMode modeAidl) {
+ int32_t output, media::audio::common::AudioLatencyMode modeAidl) {
audio_io_handle_t outputLegacy = VALUE_OR_RETURN_BINDER(
aidl2legacy_int32_t_audio_io_handle_t(output));
audio_latency_mode_t modeLegacy = VALUE_OR_RETURN_BINDER(
- aidl2legacy_LatencyMode_audio_latency_mode_t(modeAidl));
+ aidl2legacy_AudioLatencyMode_audio_latency_mode_t(modeAidl));
return Status::fromStatusT(mDelegate->setRequestedLatencyMode(
outputLegacy, modeLegacy));
}
Status AudioFlingerServerAdapter::getSupportedLatencyModes(
- int output, std::vector<media::LatencyMode>* _aidl_return) {
+ int output, std::vector<media::audio::common::AudioLatencyMode>* _aidl_return) {
audio_io_handle_t outputLegacy = VALUE_OR_RETURN_BINDER(
aidl2legacy_int32_t_audio_io_handle_t(output));
std::vector<audio_latency_mode_t> modesLegacy;
@@ -1352,9 +1380,21 @@
RETURN_BINDER_IF_ERROR(mDelegate->getSupportedLatencyModes(outputLegacy, &modesLegacy));
*_aidl_return = VALUE_OR_RETURN_BINDER(
- convertContainer<std::vector<media::LatencyMode>>(
- modesLegacy, legacy2aidl_audio_latency_mode_t_LatencyMode));
+ convertContainer<std::vector<media::audio::common::AudioLatencyMode>>(
+ modesLegacy, legacy2aidl_audio_latency_mode_t_AudioLatencyMode));
return Status::ok();
}
+Status AudioFlingerServerAdapter::setBluetoothVariableLatencyEnabled(bool enabled) {
+ return Status::fromStatusT(mDelegate->setBluetoothVariableLatencyEnabled(enabled));
+}
+
+Status AudioFlingerServerAdapter::isBluetoothVariableLatencyEnabled(bool *enabled) {
+ return Status::fromStatusT(mDelegate->isBluetoothVariableLatencyEnabled(enabled));
+}
+
+Status AudioFlingerServerAdapter::supportsBluetoothVariableLatency(bool *support) {
+ return Status::fromStatusT(mDelegate->supportsBluetoothVariableLatency(support));
+}
+
} // namespace android
diff --git a/media/libaudioclient/TEST_MAPPING b/media/libaudioclient/TEST_MAPPING
index 3751f80..10f9d9b 100644
--- a/media/libaudioclient/TEST_MAPPING
+++ b/media/libaudioclient/TEST_MAPPING
@@ -4,12 +4,38 @@
"name": "audio_aidl_conversion_tests"
},
{
+ "name": "audio_aidl_status_tests"
+ },
+ {
"name": "CtsNativeMediaAAudioTestCases",
"options" : [
{
"include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic.*"
}
]
+ },
+ {
+ "name": "audiorecord_tests"
+ },
+ {
+ "name": "audioeffect_tests"
+ },
+ {
+ "name": "audiorouting_tests"
+ },
+ {
+ "name": "audioclient_serialization_tests"
+ },
+ {
+ "name": "trackplayerbase_tests"
+ },
+ {
+ "name": "audiosystem_tests"
+ }
+ ],
+ "postsubmit": [
+ {
+ "name": "audioeffect_analysis"
}
]
}
diff --git a/media/libaudioclient/ToneGenerator.cpp b/media/libaudioclient/ToneGenerator.cpp
index f968a4b..f0b4d11 100644
--- a/media/libaudioclient/ToneGenerator.cpp
+++ b/media/libaudioclient/ToneGenerator.cpp
@@ -1027,7 +1027,7 @@
if (property_get("gsm.operator.iso-country", value, "") == 0) {
property_get("gsm.sim.operator.iso-country", value, "");
}
- // If dual sim device has two SIM cards inserted and is not registerd to any network,
+ // If dual sim device has two SIM cards inserted and is not registered to any network,
// "," is set to "gsm.operator.iso-country" prop.
// In this case, "gsm.sim.operator.iso-country" prop should be used.
if (strlen(value) == 1 && strstr(value, ",") != NULL) {
diff --git a/media/libaudioclient/aidl/android/media/AudioDualMonoMode.aidl b/media/libaudioclient/aidl/android/media/AudioDualMonoMode.aidl
deleted file mode 100644
index f6220c2..0000000
--- a/media/libaudioclient/aidl/android/media/AudioDualMonoMode.aidl
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-package android.media;
-
-// TODO(b/175167149): Reconcile AudioDualMonoMode with framework-media-sources
-
-@Backing(type="int")
-enum AudioDualMonoMode {
- OFF = 0,
- LR = 1,
- LL = 2,
- RR = 3,
-}
diff --git a/media/libaudioclient/aidl/android/media/AudioHalVersion.aidl b/media/libaudioclient/aidl/android/media/AudioHalVersion.aidl
new file mode 100644
index 0000000..49048040
--- /dev/null
+++ b/media/libaudioclient/aidl/android/media/AudioHalVersion.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+package android.media;
+
+/**
+ * The audio HAL version definition.
+ *
+ * {@hide}
+ */
+parcelable AudioHalVersion {
+
+ @Backing(type="int")
+ enum Type {
+ /**
+ * Indicate the audio HAL is implemented with HIDL (HAL interface definition language).
+ * @see <a href="https://source.android.com/docs/core/architecture/hidl/">HIDL</a>
+ */
+ HIDL = 0,
+
+ /**
+ * Indicate the audio HAL is implemented with AIDL (Android Interface Definition Language).
+ * @see <a href="https://source.android.com/docs/core/architecture/aidl/">AIDL</a>
+ */
+ AIDL
+ }
+
+ Type type = Type.HIDL;
+
+ /**
+ * Major version number.
+ */
+ int major;
+
+ /**
+ * Minor version number.
+ */
+ int minor;
+}
diff --git a/media/libaudioclient/aidl/android/media/AudioIoDescriptor.aidl b/media/libaudioclient/aidl/android/media/AudioIoDescriptor.aidl
index b01f902..5dd898c 100644
--- a/media/libaudioclient/aidl/android/media/AudioIoDescriptor.aidl
+++ b/media/libaudioclient/aidl/android/media/AudioIoDescriptor.aidl
@@ -16,7 +16,7 @@
package android.media;
-import android.media.AudioPatch;
+import android.media.AudioPatchFw;
import android.media.audio.common.AudioChannelLayout;
import android.media.audio.common.AudioFormatDescription;
@@ -26,7 +26,7 @@
parcelable AudioIoDescriptor {
/** Interpreted as audio_io_handle_t. */
int ioHandle;
- AudioPatch patch;
+ AudioPatchFw patch;
boolean isInput;
int samplingRate;
AudioFormatDescription format;
diff --git a/media/libaudioclient/aidl/android/media/AudioPatch.aidl b/media/libaudioclient/aidl/android/media/AudioPatchFw.aidl
similarity index 74%
rename from media/libaudioclient/aidl/android/media/AudioPatch.aidl
rename to media/libaudioclient/aidl/android/media/AudioPatchFw.aidl
index 8519faf..9ec3fa9 100644
--- a/media/libaudioclient/aidl/android/media/AudioPatch.aidl
+++ b/media/libaudioclient/aidl/android/media/AudioPatchFw.aidl
@@ -16,17 +16,19 @@
package android.media;
-import android.media.AudioPortConfig;
+import android.media.AudioPortConfigFw;
/**
* {@hide}
+ * The Fw suffix is used to break a namespace collision with an SDK API.
+ * It contains the framework version of AudioPortConfig.
*/
-parcelable AudioPatch {
+parcelable AudioPatchFw {
/**
* Patch unique ID.
* Interpreted as audio_patch_handle_t.
*/
int id;
- AudioPortConfig[] sources;
- AudioPortConfig[] sinks;
+ AudioPortConfigFw[] sources;
+ AudioPortConfigFw[] sinks;
}
diff --git a/media/libaudioclient/aidl/android/media/AudioPlaybackRate.aidl b/media/libaudioclient/aidl/android/media/AudioPlaybackRate.aidl
deleted file mode 100644
index e29d398..0000000
--- a/media/libaudioclient/aidl/android/media/AudioPlaybackRate.aidl
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-package android.media;
-
-/**
- * The AudioPlaybackRate.
- *
- * See https://developer.android.com/reference/android/media/PlaybackParams.
- * TODO(b/175166815): Reconcile with framework-media-sources PlaybackParams.aidl.
- * As this is used for native wire serialization, no need to define
- * audio_timestretch_stretch_mode_t and audio_timestretch_fallback_mode_t enums
- * until we attempt to unify with PlaybackParams.
- *
- * {@hide}
- */
-parcelable AudioPlaybackRate {
- /** Speed of audio playback, >= 0.f, 1.f nominal (system limits are further restrictive) */
- float speed;
- /** Pitch of audio, >= 0.f, 1.f nominal (system limits are further restrictive) */
- float pitch;
- /** Interpreted as audio_timestretch_stretch_mode_t */
- int stretchMode;
- /** Interpreted as audio_timestretch_fallback_mode_t */
- int fallbackMode;
-}
diff --git a/media/libaudioclient/aidl/android/media/AudioPortConfig.aidl b/media/libaudioclient/aidl/android/media/AudioPortConfigFw.aidl
similarity index 89%
rename from media/libaudioclient/aidl/android/media/AudioPortConfig.aidl
rename to media/libaudioclient/aidl/android/media/AudioPortConfigFw.aidl
index 3a4ca31..e7565d7 100644
--- a/media/libaudioclient/aidl/android/media/AudioPortConfig.aidl
+++ b/media/libaudioclient/aidl/android/media/AudioPortConfigFw.aidl
@@ -21,8 +21,9 @@
/**
* {@hide}
+ * Suffixed with Fw to avoid name conflict with SDK class.
*/
-parcelable AudioPortConfig {
+parcelable AudioPortConfigFw {
AudioPortConfig hal;
AudioPortConfigSys sys;
}
diff --git a/media/libaudioclient/aidl/android/media/AudioPortExtSys.aidl b/media/libaudioclient/aidl/android/media/AudioPortExtSys.aidl
index 2cdf4f6..d9c6df4 100644
--- a/media/libaudioclient/aidl/android/media/AudioPortExtSys.aidl
+++ b/media/libaudioclient/aidl/android/media/AudioPortExtSys.aidl
@@ -31,4 +31,6 @@
AudioPortDeviceExtSys device;
/** System-only parameters when the port is an audio mix. */
AudioPortMixExtSys mix;
+ /** Framework audio session identifier. */
+ int session;
}
diff --git a/media/libaudioclient/aidl/android/media/AudioPort.aidl b/media/libaudioclient/aidl/android/media/AudioPortFw.aidl
similarity index 88%
rename from media/libaudioclient/aidl/android/media/AudioPort.aidl
rename to media/libaudioclient/aidl/android/media/AudioPortFw.aidl
index ff177c0..5580e35 100644
--- a/media/libaudioclient/aidl/android/media/AudioPort.aidl
+++ b/media/libaudioclient/aidl/android/media/AudioPortFw.aidl
@@ -21,8 +21,9 @@
/**
* {@hide}
+ * The Fw suffix is used to break a namespace collision with an SDK API.
*/
-parcelable AudioPort {
+parcelable AudioPortFw {
AudioPort hal;
AudioPortSys sys;
}
diff --git a/media/libaudioclient/aidl/android/media/AudioPortSys.aidl b/media/libaudioclient/aidl/android/media/AudioPortSys.aidl
index f3b5c19..756c469 100644
--- a/media/libaudioclient/aidl/android/media/AudioPortSys.aidl
+++ b/media/libaudioclient/aidl/android/media/AudioPortSys.aidl
@@ -17,7 +17,7 @@
package android.media;
import android.media.AudioGainSys;
-import android.media.AudioPortConfig;
+import android.media.AudioPortConfigFw;
import android.media.AudioPortExtSys;
import android.media.AudioPortRole;
import android.media.AudioPortType;
@@ -36,7 +36,7 @@
/** System-only parameters for each AudioGain from 'port.gains'. */
AudioGainSys[] gains;
/** Current audio port configuration. */
- AudioPortConfig activeConfig;
+ AudioPortConfigFw activeConfig;
/** System-only extra parameters for 'port.ext'. */
AudioPortExtSys ext;
}
diff --git a/media/libaudioclient/aidl/android/media/EffectConfig.aidl b/media/libaudioclient/aidl/android/media/EffectConfig.aidl
new file mode 100644
index 0000000..5f62b73
--- /dev/null
+++ b/media/libaudioclient/aidl/android/media/EffectConfig.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+package android.media;
+
+import android.media.audio.common.AudioConfigBase;
+
+/**
+ * Describes configuration of an audio effect. Input and output
+ * audio configurations are described separately because the effect
+ * can perform transformations on channel layouts, for example.
+ *
+ * {@hide}
+ */
+parcelable EffectConfig {
+ /** Configuration of the audio input of the effect. */
+ AudioConfigBase inputCfg;
+ /** Configuration of the audio output of the effect. */
+ AudioConfigBase outputCfg;
+ /**
+ * Specifies whether the effect is instantiated on an input stream,
+ * e.g. on the input from a microphone.
+ */
+ boolean isOnInputStream;
+}
diff --git a/media/libaudioclient/aidl/android/media/IAudioFlingerClient.aidl b/media/libaudioclient/aidl/android/media/IAudioFlingerClient.aidl
index a2bb024..f055cc4 100644
--- a/media/libaudioclient/aidl/android/media/IAudioFlingerClient.aidl
+++ b/media/libaudioclient/aidl/android/media/IAudioFlingerClient.aidl
@@ -18,7 +18,7 @@
import android.media.AudioIoConfigEvent;
import android.media.AudioIoDescriptor;
-import android.media.LatencyMode;
+import android.media.audio.common.AudioLatencyMode;
/**
* A callback interface for AudioFlinger.
@@ -31,7 +31,8 @@
/**
* Called when the latency modes supported on a given output stream change.
* output is the I/O handle of the output stream for which the change is signalled.
- * latencyModes is the new list of supported latency modes (See LatencyMode.aidl).
+ * latencyModes is the new list of supported latency modes (See AudioLatencyMode.aidl).
*/
- oneway void onSupportedLatencyModesChanged(int output, in LatencyMode[] latencyModes);
+ oneway void onSupportedLatencyModesChanged(
+ int output, in AudioLatencyMode[] latencyModes);
}
diff --git a/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl b/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl
index 9b8a843..51bf05a 100644
--- a/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl
+++ b/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl
@@ -16,9 +16,9 @@
package android.media;
-import android.media.AudioPatch;
-import android.media.AudioPort;
-import android.media.AudioPortConfig;
+import android.media.AudioPatchFw;
+import android.media.AudioPortFw;
+import android.media.AudioPortConfigFw;
import android.media.AudioUniqueIdUse;
import android.media.AudioVibratorInfo;
import android.media.CreateEffectRequest;
@@ -35,12 +35,12 @@
import android.media.IAudioFlingerClient;
import android.media.IAudioRecord;
import android.media.IAudioTrack;
-import android.media.LatencyMode;
import android.media.MicrophoneInfoData;
import android.media.RenderPosition;
import android.media.TrackSecondaryOutputInfo;
import android.media.audio.common.AudioChannelLayout;
import android.media.audio.common.AudioFormatDescription;
+import android.media.audio.common.AudioLatencyMode;
import android.media.audio.common.AudioMMapPolicyInfo;
import android.media.audio.common.AudioMMapPolicyType;
import android.media.audio.common.AudioMode;
@@ -182,18 +182,18 @@
void setLowRamDevice(boolean isLowRamDevice, long totalMemory);
/* Get attributes for a given audio port */
- AudioPort getAudioPort(in AudioPort port);
+ AudioPortFw getAudioPort(in AudioPortFw port);
/* Create an audio patch between several source and sink ports */
- int /* audio_patch_handle_t */ createAudioPatch(in AudioPatch patch);
+ int /* audio_patch_handle_t */ createAudioPatch(in AudioPatchFw patch);
/* Release an audio patch */
void releaseAudioPatch(int /* audio_patch_handle_t */ handle);
/* List existing audio patches */
- AudioPatch[] listAudioPatches(int maxCount);
+ AudioPatchFw[] listAudioPatches(int maxCount);
/* Set audio port configuration */
- void setAudioPortConfig(in AudioPortConfig config);
+ void setAudioPortConfig(in AudioPortConfigFw config);
/* Get the HW synchronization source used for an audio session */
int /* audio_hw_sync_t */ getAudioHwSyncForSession(int /* audio_session_t */ sessionId);
@@ -227,24 +227,44 @@
int getAAudioHardwareBurstMinUsec();
- void setDeviceConnectedState(in AudioPort devicePort, boolean connected);
+ void setDeviceConnectedState(in AudioPortFw devicePort, boolean connected);
/**
- * Requests a given latency mode (See LatencyMode.aidl) on an output stream.
+ * Requests a given latency mode (See AudioLatencyMode.aidl) on an output stream.
* This can be used when some use case on a given mixer/stream can only be enabled
* if a specific latency mode is selected on the audio path below the HAL.
* For instance spatial audio with head tracking.
* output is the I/O handle of the output stream for which the request is made.
* latencyMode is the requested latency mode.
*/
- void setRequestedLatencyMode(int output, LatencyMode latencyMode);
+ void setRequestedLatencyMode(int output, AudioLatencyMode latencyMode);
/**
* Queries the list of latency modes (See LatencyMode.aidl) supported by an output stream.
* output is the I/O handle of the output stream to which the query applies.
* returns the list of supported latency modes.
*/
- LatencyMode[] getSupportedLatencyModes(int output);
+ AudioLatencyMode[] getSupportedLatencyModes(int output);
+
+ /**
+ * Requests if the implementation supports controlling the latency modes
+ * over the Bluetooth A2DP or LE Audio links. If it does,
+ * setRequestedLatencyMode() and getSupportedLatencyModes() APIs can also be used
+ * for streams routed to Bluetooth and not just for the spatializer output.
+ */
+ boolean supportsBluetoothVariableLatency();
+
+ /**
+ * Enables or disables the variable Bluetooth latency control mechanism in the
+ * audio framework and the audio HAL. This does not apply to the latency mode control
+ * on the spatializer output as this is a built-in feature.
+ */
+ void setBluetoothVariableLatencyEnabled(boolean enabled);
+
+ /**
+ * Indicates if the variable Bluetooth latency control mechanism is enabled or disabled.
+ */
+ boolean isBluetoothVariableLatencyEnabled();
// When adding a new method, please review and update
// IAudioFlinger.h AudioFlingerServerAdapter::Delegate::TransactionCode
diff --git a/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl b/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
index 8ac89a8..ed7e243 100644
--- a/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
+++ b/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
@@ -23,12 +23,12 @@
import android.media.AudioDirectMode;
import android.media.AudioMix;
import android.media.AudioOffloadMode;
-import android.media.AudioPatch;
+import android.media.AudioPatchFw;
import android.media.AudioPolicyDeviceState;
import android.media.AudioPolicyForcedConfig;
import android.media.AudioPolicyForceUse;
-import android.media.AudioPort;
-import android.media.AudioPortConfig;
+import android.media.AudioPortFw;
+import android.media.AudioPortConfigFw;
import android.media.AudioPortRole;
import android.media.AudioPortType;
import android.media.AudioProductStrategy;
@@ -212,16 +212,16 @@
int listAudioPorts(AudioPortRole role,
AudioPortType type,
inout Int count,
- out AudioPort[] ports);
+ out AudioPortFw[] ports);
/** Get attributes for the audio port with the given id (AudioPort.hal.id field). */
- AudioPort getAudioPort(int /* audio_port_handle_t */ portId);
+ AudioPortFw getAudioPort(int /* audio_port_handle_t */ portId);
/**
* Create an audio patch between several source and sink ports.
* The handle argument is used when updating an existing patch.
*/
- int /* audio_patch_handle_t */ createAudioPatch(in AudioPatch patch, int handle);
+ int /* audio_patch_handle_t */ createAudioPatch(in AudioPatchFw patch, int handle);
/** Release an audio patch. */
void releaseAudioPatch(int /* audio_patch_handle_t */ handle);
@@ -234,10 +234,10 @@
* Passing '0' on input and inspecting the value on output is a common way of determining the
* number of elements without actually retrieving them.
*/
- int listAudioPatches(inout Int count, out AudioPatch[] patches);
+ int listAudioPatches(inout Int count, out AudioPatchFw[] patches);
/** Set audio port configuration. */
- void setAudioPortConfig(in AudioPortConfig config);
+ void setAudioPortConfig(in AudioPortConfigFw config);
void registerClient(IAudioPolicyServiceClient client);
@@ -261,7 +261,7 @@
void removeUserIdDeviceAffinities(int userId);
- int /* audio_port_handle_t */ startAudioSource(in AudioPortConfig source,
+ int /* audio_port_handle_t */ startAudioSource(in AudioPortConfigFw source,
in AudioAttributesInternal attributes);
void stopAudioSource(int /* audio_port_handle_t */ portId);
diff --git a/media/libaudioclient/aidl/android/media/IAudioTrack.aidl b/media/libaudioclient/aidl/android/media/IAudioTrack.aidl
index ac58925..c3a2dbe 100644
--- a/media/libaudioclient/aidl/android/media/IAudioTrack.aidl
+++ b/media/libaudioclient/aidl/android/media/IAudioTrack.aidl
@@ -16,13 +16,13 @@
package android.media;
-import android.media.AudioDualMonoMode;
-import android.media.AudioPlaybackRate;
import android.media.AudioTimestampInternal;
import android.media.SharedFileRegion;
import android.media.VolumeShaperConfiguration;
import android.media.VolumeShaperOperation;
import android.media.VolumeShaperState;
+import android.media.audio.common.AudioDualMonoMode;
+import android.media.audio.common.AudioPlaybackRate;
/**
* Unless otherwise noted, methods returning int expect it to be interpreted as a status_t.
diff --git a/media/libaudioclient/aidl/android/media/IEffect.aidl b/media/libaudioclient/aidl/android/media/IEffect.aidl
index 6ec0405..b7f70a6 100644
--- a/media/libaudioclient/aidl/android/media/IEffect.aidl
+++ b/media/libaudioclient/aidl/android/media/IEffect.aidl
@@ -16,6 +16,7 @@
package android.media;
+import android.media.EffectConfig;
import android.media.SharedFileRegion;
/**
@@ -63,6 +64,14 @@
*/
SharedFileRegion getCblk();
+ /**
+ * Provides audio configurations for effect's input and output,
+ * see EffectConfig parcelable for more details.
+ *
+ * @return a status_t code.
+ */
+ int getConfig(out EffectConfig config);
+
// When adding a new method, please review and update
// Effects.cpp AudioFlinger::EffectHandle::onTransact()
// Effects.cpp IEFFECT_BINDER_METHOD_MACRO_LIST
diff --git a/media/libaudioclient/aidl/android/media/LatencyMode.aidl b/media/libaudioclient/aidl/android/media/LatencyMode.aidl
deleted file mode 100644
index 0b2a72b..0000000
--- a/media/libaudioclient/aidl/android/media/LatencyMode.aidl
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright 2021 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.
- */
-
-package android.media;
-
-/**
- * The latency mode currently used by the spatializer mixer.
- * {@hide}
- */
-@Backing(type="byte")
-enum LatencyMode {
- /** No specific constraint on the latency */
- FREE = 0,
- /** A relatively low latency compatible with head tracking operation (e.g less than 100ms) */
- LOW = 1,
-}
diff --git a/media/libaudioclient/aidl/android/media/OpenOutputRequest.aidl b/media/libaudioclient/aidl/android/media/OpenOutputRequest.aidl
index 90e7ea6..ddda8bb 100644
--- a/media/libaudioclient/aidl/android/media/OpenOutputRequest.aidl
+++ b/media/libaudioclient/aidl/android/media/OpenOutputRequest.aidl
@@ -16,7 +16,7 @@
package android.media;
-import android.media.AudioPort;
+import android.media.AudioPortFw;
import android.media.audio.common.AudioConfig;
import android.media.audio.common.AudioConfigBase;
@@ -29,7 +29,7 @@
AudioConfig halConfig;
AudioConfigBase mixerConfig;
/** Type must be DEVICE. */
- AudioPort device;
+ AudioPortFw device;
/** Bitmask, indexed by AudioOutputFlag. */
int flags;
}
diff --git a/media/libaudioclient/fuzzer/Android.bp b/media/libaudioclient/fuzzer/Android.bp
index 969e3e6..b1feb60 100644
--- a/media/libaudioclient/fuzzer/Android.bp
+++ b/media/libaudioclient/fuzzer/Android.bp
@@ -25,6 +25,9 @@
cc_fuzz {
name: "audioflinger_fuzzer",
+ defaults: [
+ "latest_android_media_audio_common_types_cpp_shared",
+ ],
srcs: [
"audioflinger_fuzzer.cpp",
],
@@ -46,7 +49,6 @@
],
shared_libs: [
"android.hardware.audio.common-util",
- "android.media.audio.common.types-V1-cpp",
"audioclient-types-aidl-cpp",
"audioflinger-aidl-cpp",
"audiopolicy-aidl-cpp",
@@ -54,6 +56,7 @@
"av-types-aidl-cpp",
"capture_state_listener-aidl-cpp",
"libaudioclient_aidl_conversion",
+ "libaudio_aidl_conversion_common_cpp",
"libaudioflinger",
"libaudiofoundation",
"libaudiomanager",
diff --git a/media/libaudioclient/include/media/AidlConversion.h b/media/libaudioclient/include/media/AidlConversion.h
index 1e66164..9a88f76 100644
--- a/media/libaudioclient/include/media/AidlConversion.h
+++ b/media/libaudioclient/include/media/AidlConversion.h
@@ -24,46 +24,20 @@
#include <android/media/AudioAttributesInternal.h>
#include <android/media/AudioClient.h>
#include <android/media/AudioDirectMode.h>
-#include <android/media/AudioDualMonoMode.h>
#include <android/media/AudioFlag.h>
#include <android/media/AudioIoConfigEvent.h>
#include <android/media/AudioIoDescriptor.h>
-#include <android/media/AudioPlaybackRate.h>
-#include <android/media/AudioPort.h>
-#include <android/media/AudioPortConfig.h>
+#include <android/media/AudioPortFw.h>
+#include <android/media/AudioPortConfigFw.h>
#include <android/media/AudioPortDeviceExtSys.h>
#include <android/media/AudioTimestampInternal.h>
#include <android/media/AudioUniqueIdUse.h>
#include <android/media/EffectDescriptor.h>
-#include <android/media/LatencyMode.h>
#include <android/media/TrackSecondaryOutputInfo.h>
-#include <android/media/audio/common/AudioChannelLayout.h>
-#include <android/media/audio/common/AudioConfig.h>
-#include <android/media/audio/common/AudioConfigBase.h>
-#include <android/media/audio/common/AudioContentType.h>
-#include <android/media/audio/common/AudioDeviceDescription.h>
-#include <android/media/audio/common/AudioEncapsulationMetadataType.h>
-#include <android/media/audio/common/AudioEncapsulationMode.h>
-#include <android/media/audio/common/AudioEncapsulationType.h>
-#include <android/media/audio/common/AudioFormatDescription.h>
-#include <android/media/audio/common/AudioGain.h>
-#include <android/media/audio/common/AudioGainConfig.h>
-#include <android/media/audio/common/AudioGainMode.h>
-#include <android/media/audio/common/AudioInputFlags.h>
-#include <android/media/audio/common/AudioMode.h>
-#include <android/media/audio/common/AudioOffloadInfo.h>
-#include <android/media/audio/common/AudioOutputFlags.h>
-#include <android/media/audio/common/AudioPortExt.h>
-#include <android/media/audio/common/AudioPortMixExt.h>
-#include <android/media/audio/common/AudioProfile.h>
-#include <android/media/audio/common/AudioSource.h>
-#include <android/media/audio/common/AudioStandard.h>
-#include <android/media/audio/common/AudioUsage.h>
-#include <android/media/audio/common/AudioUuid.h>
-#include <android/media/audio/common/ExtraAudioDescriptor.h>
#include <android/media/SharedFileRegion.h>
#include <binder/IMemory.h>
+#include <media/AidlConversionCppNdk.h>
#include <media/AidlConversionUtil.h>
#include <media/AudioClient.h>
#include <media/AudioCommonTypes.h>
@@ -73,49 +47,6 @@
namespace android {
-// maxSize is the size of the C-string buffer (including the 0-terminator), NOT the max length of
-// the string.
-status_t aidl2legacy_string(std::string_view aidl, char* dest, size_t maxSize);
-ConversionResult<std::string> legacy2aidl_string(const char* legacy, size_t maxSize);
-
-ConversionResult<audio_module_handle_t> aidl2legacy_int32_t_audio_module_handle_t(int32_t aidl);
-ConversionResult<int32_t> legacy2aidl_audio_module_handle_t_int32_t(audio_module_handle_t legacy);
-
-ConversionResult<audio_io_handle_t> aidl2legacy_int32_t_audio_io_handle_t(int32_t aidl);
-ConversionResult<int32_t> legacy2aidl_audio_io_handle_t_int32_t(audio_io_handle_t legacy);
-
-ConversionResult<audio_port_handle_t> aidl2legacy_int32_t_audio_port_handle_t(int32_t aidl);
-ConversionResult<int32_t> legacy2aidl_audio_port_handle_t_int32_t(audio_port_handle_t legacy);
-
-ConversionResult<audio_patch_handle_t> aidl2legacy_int32_t_audio_patch_handle_t(int32_t aidl);
-ConversionResult<int32_t> legacy2aidl_audio_patch_handle_t_int32_t(audio_patch_handle_t legacy);
-
-ConversionResult<audio_unique_id_t> aidl2legacy_int32_t_audio_unique_id_t(int32_t aidl);
-ConversionResult<int32_t> legacy2aidl_audio_unique_id_t_int32_t(audio_unique_id_t legacy);
-
-ConversionResult<audio_hw_sync_t> aidl2legacy_int32_t_audio_hw_sync_t(int32_t aidl);
-ConversionResult<int32_t> legacy2aidl_audio_hw_sync_t_int32_t(audio_hw_sync_t legacy);
-
-ConversionResult<unsigned int> aidl2legacy_int32_t_config_mask(int32_t aidl);
-ConversionResult<int32_t> legacy2aidl_config_mask_int32_t(unsigned int legacy);
-
-ConversionResult<pid_t> aidl2legacy_int32_t_pid_t(int32_t aidl);
-ConversionResult<int32_t> legacy2aidl_pid_t_int32_t(pid_t legacy);
-
-ConversionResult<uid_t> aidl2legacy_int32_t_uid_t(int32_t aidl);
-ConversionResult<int32_t> legacy2aidl_uid_t_int32_t(uid_t legacy);
-
-ConversionResult<String8> aidl2legacy_string_view_String8(std::string_view aidl);
-ConversionResult<std::string> legacy2aidl_String8_string(const String8& legacy);
-
-ConversionResult<String16> aidl2legacy_string_view_String16(std::string_view aidl);
-ConversionResult<std::string> legacy2aidl_String16_string(const String16& legacy);
-
-ConversionResult<std::optional<String16>>
-aidl2legacy_optional_string_view_optional_String16(std::optional<std::string_view> aidl);
-ConversionResult<std::optional<std::string_view>>
-legacy2aidl_optional_String16_optional_string(std::optional<String16> legacy);
-
ConversionResult<audio_io_config_event_t> aidl2legacy_AudioIoConfigEvent_audio_io_config_event_t(
media::AudioIoConfigEvent aidl);
ConversionResult<media::AudioIoConfigEvent> legacy2aidl_audio_io_config_event_t_AudioIoConfigEvent(
@@ -131,75 +62,6 @@
ConversionResult<media::AudioPortType> legacy2aidl_audio_port_type_t_AudioPortType(
audio_port_type_t legacy);
-ConversionResult<audio_channel_mask_t> aidl2legacy_AudioChannelLayout_audio_channel_mask_t(
- const media::audio::common::AudioChannelLayout& aidl, bool isInput);
-ConversionResult<media::audio::common::AudioChannelLayout>
-legacy2aidl_audio_channel_mask_t_AudioChannelLayout(audio_channel_mask_t legacy, bool isInput);
-
-ConversionResult<audio_devices_t> aidl2legacy_AudioDeviceDescription_audio_devices_t(
- const media::audio::common::AudioDeviceDescription& aidl);
-ConversionResult<media::audio::common::AudioDeviceDescription>
-legacy2aidl_audio_devices_t_AudioDeviceDescription(audio_devices_t legacy);
-
-status_t aidl2legacy_AudioDevice_audio_device(
- const media::audio::common::AudioDevice& aidl,
- audio_devices_t* legacyType, char* legacyAddress);
-status_t aidl2legacy_AudioDevice_audio_device(
- const media::audio::common::AudioDevice& aidl,
- audio_devices_t* legacyType, String8* legacyAddress);
-status_t aidl2legacy_AudioDevice_audio_device(
- const media::audio::common::AudioDevice& aidl,
- audio_devices_t* legacyType, std::string* legacyAddress);
-ConversionResult<media::audio::common::AudioDevice>
-legacy2aidl_audio_device_AudioDevice(
- audio_devices_t legacyType, const char* legacyAddress);
-ConversionResult<media::audio::common::AudioDevice>
-legacy2aidl_audio_device_AudioDevice(
- audio_devices_t legacyType, const String8& legacyAddress);
-
-ConversionResult<audio_format_t> aidl2legacy_AudioFormatDescription_audio_format_t(
- const media::audio::common::AudioFormatDescription& aidl);
-ConversionResult<media::audio::common::AudioFormatDescription>
-legacy2aidl_audio_format_t_AudioFormatDescription(audio_format_t legacy);
-
-ConversionResult<audio_gain_mode_t>
-aidl2legacy_AudioGainMode_audio_gain_mode_t(media::audio::common::AudioGainMode aidl);
-ConversionResult<media::audio::common::AudioGainMode>
-legacy2aidl_audio_gain_mode_t_AudioGainMode(audio_gain_mode_t legacy);
-
-ConversionResult<audio_gain_mode_t> aidl2legacy_int32_t_audio_gain_mode_t_mask(int32_t aidl);
-ConversionResult<int32_t> legacy2aidl_audio_gain_mode_t_int32_t_mask(audio_gain_mode_t legacy);
-
-ConversionResult<audio_gain_config> aidl2legacy_AudioGainConfig_audio_gain_config(
- const media::audio::common::AudioGainConfig& aidl, bool isInput);
-ConversionResult<media::audio::common::AudioGainConfig>
-legacy2aidl_audio_gain_config_AudioGainConfig(const audio_gain_config& legacy, bool isInput);
-
-ConversionResult<audio_input_flags_t>
-aidl2legacy_AudioInputFlags_audio_input_flags_t(media::audio::common::AudioInputFlags aidl);
-ConversionResult<media::audio::common::AudioInputFlags>
-legacy2aidl_audio_input_flags_t_AudioInputFlags(audio_input_flags_t legacy);
-
-ConversionResult<audio_output_flags_t>
-aidl2legacy_AudioOutputFlags_audio_output_flags_t(media::audio::common::AudioOutputFlags aidl);
-ConversionResult<media::audio::common::AudioOutputFlags>
-legacy2aidl_audio_output_flags_t_AudioOutputFlags(audio_output_flags_t legacy);
-
-ConversionResult<audio_input_flags_t> aidl2legacy_int32_t_audio_input_flags_t_mask(
- int32_t aidl);
-ConversionResult<int32_t> legacy2aidl_audio_input_flags_t_int32_t_mask(
- audio_input_flags_t legacy);
-
-ConversionResult<audio_output_flags_t> aidl2legacy_int32_t_audio_output_flags_t_mask(
- int32_t aidl);
-ConversionResult<int32_t> legacy2aidl_audio_output_flags_t_int32_t_mask(
- audio_output_flags_t legacy);
-
-ConversionResult<audio_io_flags> aidl2legacy_AudioIoFlags_audio_io_flags(
- const media::audio::common::AudioIoFlags& aidl, bool isInput);
-ConversionResult<media::audio::common::AudioIoFlags> legacy2aidl_audio_io_flags_AudioIoFlags(
- const audio_io_flags& legacy, bool isInput);
-
ConversionResult<audio_port_config_device_ext>
aidl2legacy_AudioPortDeviceExt_audio_port_config_device_ext(
const media::audio::common::AudioPortDeviceExt& aidl,
@@ -214,15 +76,6 @@
ConversionResult<media::audio::common::AudioStreamType>
legacy2aidl_audio_stream_type_t_AudioStreamType(audio_stream_type_t legacy);
-ConversionResult<audio_source_t> aidl2legacy_AudioSource_audio_source_t(
- media::audio::common::AudioSource aidl);
-ConversionResult<media::audio::common::AudioSource>
- legacy2aidl_audio_source_t_AudioSource(
- audio_source_t legacy);
-
-ConversionResult<audio_session_t> aidl2legacy_int32_t_audio_session_t(int32_t aidl);
-ConversionResult<int32_t> legacy2aidl_audio_session_t_int32_t(audio_session_t legacy);
-
ConversionResult<audio_port_config_mix_ext> aidl2legacy_AudioPortMixExt(
const media::audio::common::AudioPortMixExt& aidl, media::AudioPortRole role,
const media::AudioPortMixExtSys& aidlMixExt);
@@ -235,14 +88,14 @@
ConversionResult<int32_t> legacy2aidl_audio_port_config_session_ext_AudioPortConfigSessionExt(
const audio_port_config_session_ext& legacy);
-ConversionResult<audio_port_config> aidl2legacy_AudioPortConfig_audio_port_config(
- const media::AudioPortConfig& aidl);
-ConversionResult<media::AudioPortConfig> legacy2aidl_audio_port_config_AudioPortConfig(
+ConversionResult<audio_port_config> aidl2legacy_AudioPortConfigFw_audio_port_config(
+ const media::AudioPortConfigFw& aidl);
+ConversionResult<media::AudioPortConfigFw> legacy2aidl_audio_port_config_AudioPortConfigFw(
const audio_port_config& legacy);
-ConversionResult<struct audio_patch> aidl2legacy_AudioPatch_audio_patch(
- const media::AudioPatch& aidl);
-ConversionResult<media::AudioPatch> legacy2aidl_audio_patch_AudioPatch(
+ConversionResult<struct audio_patch> aidl2legacy_AudioPatchFw_audio_patch(
+ const media::AudioPatchFw& aidl);
+ConversionResult<media::AudioPatchFw> legacy2aidl_audio_patch_AudioPatchFw(
const struct audio_patch& legacy);
ConversionResult<sp<AudioIoDescriptor>> aidl2legacy_AudioIoDescriptor_AudioIoDescriptor(
@@ -255,17 +108,6 @@
ConversionResult<media::AudioClient> legacy2aidl_AudioClient_AudioClient(
const AudioClient& legacy);
-ConversionResult<audio_content_type_t>
-aidl2legacy_AudioContentType_audio_content_type_t(
- media::audio::common::AudioContentType aidl);
-ConversionResult<media::audio::common::AudioContentType>
-legacy2aidl_audio_content_type_t_AudioContentType(audio_content_type_t legacy);
-
-ConversionResult<audio_usage_t>
-aidl2legacy_AudioUsage_audio_usage_t(media::audio::common::AudioUsage aidl);
-ConversionResult<media::audio::common::AudioUsage>
-legacy2aidl_audio_usage_t_AudioUsage(audio_usage_t legacy);
-
ConversionResult<audio_flags_mask_t>
aidl2legacy_AudioFlag_audio_flags_mask_t(media::AudioFlag aidl);
ConversionResult<media::AudioFlag>
@@ -281,36 +123,13 @@
ConversionResult<media::AudioAttributesInternal>
legacy2aidl_audio_attributes_t_AudioAttributesInternal(const audio_attributes_t& legacy);
-ConversionResult<audio_encapsulation_mode_t>
-aidl2legacy_AudioEncapsulationMode_audio_encapsulation_mode_t(
- media::audio::common::AudioEncapsulationMode aidl);
-ConversionResult<media::audio::common::AudioEncapsulationMode>
-legacy2aidl_audio_encapsulation_mode_t_AudioEncapsulationMode(audio_encapsulation_mode_t legacy);
-
-ConversionResult<audio_offload_info_t>
-aidl2legacy_AudioOffloadInfo_audio_offload_info_t(
- const media::audio::common::AudioOffloadInfo& aidl);
-ConversionResult<media::audio::common::AudioOffloadInfo>
-legacy2aidl_audio_offload_info_t_AudioOffloadInfo(const audio_offload_info_t& legacy);
-
-ConversionResult<audio_config_t>
-aidl2legacy_AudioConfig_audio_config_t(const media::audio::common::AudioConfig& aidl, bool isInput);
-ConversionResult<media::audio::common::AudioConfig>
-legacy2aidl_audio_config_t_AudioConfig(const audio_config_t& legacy, bool isInput);
-
-ConversionResult<audio_config_base_t>
-aidl2legacy_AudioConfigBase_audio_config_base_t(
- const media::audio::common::AudioConfigBase& aidl, bool isInput);
-ConversionResult<media::audio::common::AudioConfigBase>
-legacy2aidl_audio_config_base_t_AudioConfigBase(const audio_config_base_t& legacy, bool isInput);
-
ConversionResult<sp<IMemory>>
aidl2legacy_SharedFileRegion_IMemory(const media::SharedFileRegion& aidl);
ConversionResult<media::SharedFileRegion>
legacy2aidl_IMemory_SharedFileRegion(const sp<IMemory>& legacy);
-ConversionResult<sp<IMemory>>
-aidl2legacy_NullableSharedFileRegion_IMemory(const std::optional<media::SharedFileRegion>& aidl);
+ConversionResult<sp<::android::IMemory>> aidl2legacy_NullableSharedFileRegion_IMemory(
+ const std::optional<media::SharedFileRegion>& aidl);
ConversionResult<std::optional<media::SharedFileRegion>>
legacy2aidl_NullableIMemory_SharedFileRegion(const sp<IMemory>& legacy);
@@ -319,32 +138,10 @@
ConversionResult<media::AudioTimestampInternal>
legacy2aidl_AudioTimestamp_AudioTimestampInternal(const AudioTimestamp& legacy);
-ConversionResult<audio_uuid_t>
-aidl2legacy_AudioUuid_audio_uuid_t(const media::audio::common::AudioUuid& aidl);
-ConversionResult<media::audio::common::AudioUuid>
-legacy2aidl_audio_uuid_t_AudioUuid(const audio_uuid_t& legacy);
-
ConversionResult<effect_descriptor_t>
aidl2legacy_EffectDescriptor_effect_descriptor_t(const media::EffectDescriptor& aidl);
-ConversionResult<media::EffectDescriptor>
-legacy2aidl_effect_descriptor_t_EffectDescriptor(const effect_descriptor_t& legacy);
-
-ConversionResult<audio_encapsulation_metadata_type_t>
-aidl2legacy_AudioEncapsulationMetadataType_audio_encapsulation_metadata_type_t(
- media::audio::common::AudioEncapsulationMetadataType aidl);
-ConversionResult<media::audio::common::AudioEncapsulationMetadataType>
-legacy2aidl_audio_encapsulation_metadata_type_t_AudioEncapsulationMetadataType(
- audio_encapsulation_metadata_type_t legacy);
-
-ConversionResult<uint32_t>
-aidl2legacy_AudioEncapsulationMode_mask(int32_t aidl);
-ConversionResult<int32_t>
-legacy2aidl_AudioEncapsulationMode_mask(uint32_t legacy);
-
-ConversionResult<uint32_t>
-aidl2legacy_AudioEncapsulationMetadataType_mask(int32_t aidl);
-ConversionResult<int32_t>
-legacy2aidl_AudioEncapsulationMetadataType_mask(uint32_t legacy);
+ConversionResult<media::EffectDescriptor> legacy2aidl_effect_descriptor_t_EffectDescriptor(
+ const effect_descriptor_t& legacy);
ConversionResult<audio_port_device_ext>
aidl2legacy_AudioPortDeviceExt_audio_port_device_ext(
@@ -369,26 +166,10 @@
ConversionResult<int32_t>
legacy2aidl_audio_port_session_ext_int32_t(const audio_port_session_ext& legacy);
-ConversionResult<audio_profile>
-aidl2legacy_AudioProfile_audio_profile(
- const media::audio::common::AudioProfile& aidl, bool isInput);
-ConversionResult<media::audio::common::AudioProfile>
-legacy2aidl_audio_profile_AudioProfile(const audio_profile& legacy, bool isInput);
-
-ConversionResult<audio_gain>
-aidl2legacy_AudioGain_audio_gain(const media::audio::common::AudioGain& aidl, bool isInput);
-ConversionResult<media::audio::common::AudioGain>
-legacy2aidl_audio_gain_AudioGain(const audio_gain& legacy, bool isInput);
-
ConversionResult<audio_port_v7>
-aidl2legacy_AudioPort_audio_port_v7(const media::AudioPort& aidl);
-ConversionResult<media::AudioPort>
-legacy2aidl_audio_port_v7_AudioPort(const audio_port_v7& legacy);
-
-ConversionResult<audio_mode_t>
-aidl2legacy_AudioMode_audio_mode_t(media::audio::common::AudioMode aidl);
-ConversionResult<media::audio::common::AudioMode>
-legacy2aidl_audio_mode_t_AudioMode(audio_mode_t legacy);
+aidl2legacy_AudioPortFw_audio_port_v7(const media::AudioPortFw& aidl);
+ConversionResult<media::AudioPortFw>
+legacy2aidl_audio_port_v7_AudioPortFw(const audio_port_v7& legacy);
ConversionResult<audio_unique_id_use_t>
aidl2legacy_AudioUniqueIdUse_audio_unique_id_use_t(media::AudioUniqueIdUse aidl);
@@ -400,45 +181,6 @@
ConversionResult<int32_t>
legacy2aidl_volume_group_t_int32_t(volume_group_t legacy);
-ConversionResult<audio_dual_mono_mode_t>
-aidl2legacy_AudioDualMonoMode_audio_dual_mono_mode_t(media::AudioDualMonoMode aidl);
-ConversionResult<media::AudioDualMonoMode>
-legacy2aidl_audio_dual_mono_mode_t_AudioDualMonoMode(audio_dual_mono_mode_t legacy);
-
-ConversionResult<audio_timestretch_fallback_mode_t>
-aidl2legacy_int32_t_audio_timestretch_fallback_mode_t(int32_t aidl);
-ConversionResult<int32_t>
-legacy2aidl_audio_timestretch_fallback_mode_t_int32_t(audio_timestretch_fallback_mode_t legacy);
-
-ConversionResult<audio_timestretch_stretch_mode_t>
-aidl2legacy_int32_t_audio_timestretch_stretch_mode_t(int32_t aidl);
-ConversionResult<int32_t>
-legacy2aidl_audio_timestretch_stretch_mode_t_int32_t(audio_timestretch_stretch_mode_t legacy);
-
-ConversionResult<audio_playback_rate_t>
-aidl2legacy_AudioPlaybackRate_audio_playback_rate_t(const media::AudioPlaybackRate& aidl);
-ConversionResult<media::AudioPlaybackRate>
-legacy2aidl_audio_playback_rate_t_AudioPlaybackRate(const audio_playback_rate_t& legacy);
-
-ConversionResult<audio_standard_t>
-aidl2legacy_AudioStandard_audio_standard_t(media::audio::common::AudioStandard aidl);
-ConversionResult<media::audio::common::AudioStandard>
-legacy2aidl_audio_standard_t_AudioStandard(audio_standard_t legacy);
-
-ConversionResult<audio_extra_audio_descriptor>
-aidl2legacy_ExtraAudioDescriptor_audio_extra_audio_descriptor(
- const media::audio::common::ExtraAudioDescriptor& aidl);
-ConversionResult<media::audio::common::ExtraAudioDescriptor>
-legacy2aidl_audio_extra_audio_descriptor_ExtraAudioDescriptor(
- const audio_extra_audio_descriptor& legacy);
-
-ConversionResult<audio_encapsulation_type_t>
-aidl2legacy_AudioEncapsulationType_audio_encapsulation_type_t(
- const media::audio::common::AudioEncapsulationType& aidl);
-ConversionResult<media::audio::common::AudioEncapsulationType>
-legacy2aidl_audio_encapsulation_type_t_AudioEncapsulationType(
- const audio_encapsulation_type_t & legacy);
-
using TrackSecondaryOutputInfoPair = std::pair<audio_port_handle_t, std::vector<audio_io_handle_t>>;
ConversionResult<TrackSecondaryOutputInfoPair>
aidl2legacy_TrackSecondaryOutputInfo_TrackSecondaryOutputInfoPair(
@@ -455,9 +197,4 @@
ConversionResult<audio_direct_mode_t> aidl2legacy_int32_t_audio_direct_mode_t_mask(int32_t aidl);
ConversionResult<int32_t> legacy2aidl_audio_direct_mode_t_int32_t_mask(audio_direct_mode_t legacy);
-ConversionResult<audio_latency_mode_t>
-aidl2legacy_LatencyMode_audio_latency_mode_t(media::LatencyMode aidl);
-ConversionResult<media::LatencyMode>
-legacy2aidl_audio_latency_mode_t_LatencyMode(audio_latency_mode_t legacy);
-
} // namespace android
diff --git a/media/libaudioclient/include/media/AudioEffect.h b/media/libaudioclient/include/media/AudioEffect.h
index 56884a3..291312e 100644
--- a/media/libaudioclient/include/media/AudioEffect.h
+++ b/media/libaudioclient/include/media/AudioEffect.h
@@ -136,7 +136,7 @@
* indicated by count.
* PERMISSION_DENIED could not get AudioFlinger interface
* NO_INIT effect library failed to initialize
- * BAD_VALUE invalid audio session or descriptor pointers
+ * BAD_VALUE invalid audio session, or invalid descriptor or count pointers
*
* Returned value
* *descriptor updated with descriptors of pre processings enabled by default
@@ -160,6 +160,7 @@
* NO_ERROR successful operation.
* PERMISSION_DENIED could not get AudioFlinger interface
* or caller lacks required permissions.
+ * BAD_VALUE invalid pointer to id
* Returned value
* *id: The new unique system-wide effect id.
*/
@@ -194,7 +195,7 @@
* PERMISSION_DENIED could not get AudioFlinger interface
* or caller lacks required permissions.
* NO_INIT effect library failed to initialize.
- * BAD_VALUE invalid source, type uuid or implementation uuid.
+ * BAD_VALUE invalid source, type uuid or implementation uuid, or id pointer
* NAME_NOT_FOUND no effect with this uuid or type found.
*
* Returned value
@@ -233,7 +234,7 @@
* PERMISSION_DENIED could not get AudioFlinger interface
* or caller lacks required permissions.
* NO_INIT effect library failed to initialize.
- * BAD_VALUE invalid type uuid or implementation uuid.
+ * BAD_VALUE invalid type uuid or implementation uuid, or id pointer
* NAME_NOT_FOUND no effect with this uuid or type found.
*
* Returned value
@@ -517,7 +518,7 @@
* Returned status (from utils/Errors.h) can be:
* - NO_ERROR: successful operation.
* - INVALID_OPERATION: the application does not have control of the effect engine.
- * - BAD_VALUE: invalid parameter identifier or value.
+ * - BAD_VALUE: invalid parameter structure pointer, or invalid identifier or value.
* - DEAD_OBJECT: the effect engine has been deleted.
*/
virtual status_t setParameter(effect_param_t *param);
@@ -562,7 +563,7 @@
* Returned status (from utils/Errors.h) can be:
* - NO_ERROR: successful operation.
* - INVALID_OPERATION: the AudioEffect was not successfully initialized.
- * - BAD_VALUE: invalid parameter identifier.
+ * - BAD_VALUE: invalid parameter structure pointer, or invalid parameter identifier.
* - DEAD_OBJECT: the effect engine has been deleted.
*/
virtual status_t getParameter(effect_param_t *param);
@@ -577,6 +578,25 @@
uint32_t *replySize,
void *replyData);
+ /* Retrieves the configuration of the effect.
+ *
+ * Parameters:
+ * inputCfg: pointer to audio_config_base_t structure receiving input
+ * configuration of the effect
+ * outputCfg: pointer to audio_config_base_t structure receiving output
+ * configuration of the effect
+ *
+ * Channel masks of the returned configs are "input" or "output" depending
+ * on the direction of the stream that the effect is attached to.
+ *
+ * Returned status (from utils/Errors.h) can be:
+ * - NO_ERROR: successful operation.
+ * - INVALID_OPERATION: the AudioEffect was not successfully initialized.
+ * - BAD_VALUE: null config pointers
+ * - DEAD_OBJECT: the effect engine has been deleted.
+ */
+ virtual status_t getConfigs(audio_config_base_t *inputCfg,
+ audio_config_base_t *outputCfg);
/*
* Utility functions.
@@ -628,7 +648,7 @@
{
public:
- EffectClient(AudioEffect *effect) : mEffect(effect){}
+ explicit EffectClient(const sp<AudioEffect>& effect) : mEffect(effect){}
// IEffectClient
binder::Status controlStatusChanged(bool controlGranted) override {
diff --git a/media/libaudioclient/include/media/AudioPolicy.h b/media/libaudioclient/include/media/AudioPolicy.h
index fbb1100..cab476e 100644
--- a/media/libaudioclient/include/media/AudioPolicy.h
+++ b/media/libaudioclient/include/media/AudioPolicy.h
@@ -72,6 +72,7 @@
status_t readFromParcel(Parcel *parcel);
status_t writeToParcel(Parcel *parcel) const;
+ bool isExcludeCriterion() const;
union {
audio_usage_t mUsage;
audio_source_t mSource;
@@ -88,23 +89,24 @@
static const uint32_t kCbFlagNotifyActivity = 0x1;
AudioMix() {}
- AudioMix(Vector<AudioMixMatchCriterion> criteria, uint32_t mixType, audio_config_t format,
- uint32_t routeFlags, String8 registrationId, uint32_t flags) :
+ AudioMix(const std::vector<AudioMixMatchCriterion> &criteria, uint32_t mixType,
+ audio_config_t format, uint32_t routeFlags,const String8 ®istrationId,
+ uint32_t flags) :
mCriteria(criteria), mMixType(mixType), mFormat(format),
mRouteFlags(routeFlags), mDeviceAddress(registrationId), mCbFlags(flags){}
status_t readFromParcel(Parcel *parcel);
status_t writeToParcel(Parcel *parcel) const;
- void setExcludeUid(uid_t uid) const;
- void setMatchUid(uid_t uid) const;
+ void setExcludeUid(uid_t uid);
+ void setMatchUid(uid_t uid);
/** returns true if this mix has a rule to match or exclude the given uid */
bool hasUidRule(bool match, uid_t uid) const;
/** returns true if this mix has a rule for uid match (any uid) */
bool hasMatchUidRule() const;
- void setExcludeUserId(int userId) const;
- void setMatchUserId(int userId) const;
+ void setExcludeUserId(int userId);
+ void setMatchUserId(int userId);
/** returns true if this mix has a rule to match or exclude the given userId */
bool hasUserIdRule(bool match, int userId) const;
/** returns true if this mix has a rule for userId match (any userId) */
@@ -112,7 +114,7 @@
/** returns true if this mix can be used for uid-device affinity routing */
bool isDeviceAffinityCompatible() const;
- mutable Vector<AudioMixMatchCriterion> mCriteria;
+ std::vector<AudioMixMatchCriterion> mCriteria;
uint32_t mMixType;
audio_config_t mFormat;
uint32_t mRouteFlags;
diff --git a/media/libaudioclient/include/media/AudioRecord.h b/media/libaudioclient/include/media/AudioRecord.h
index cb05dd9..5a1ff65 100644
--- a/media/libaudioclient/include/media/AudioRecord.h
+++ b/media/libaudioclient/include/media/AudioRecord.h
@@ -46,27 +46,6 @@
{
public:
- /* Events used by AudioRecord callback function (legacy_callback_t).
- * Keep in sync with frameworks/base/media/java/android/media/AudioRecord.java NATIVE_EVENT_*.
- */
- enum event_type {
- EVENT_MORE_DATA = 0, // Request to read available data from buffer.
- // If this event is delivered but the callback handler
- // does not want to read the available data, the handler must
- // explicitly ignore the event by setting frameCount to zero.
- EVENT_OVERRUN = 1, // Buffer overrun occurred.
- EVENT_MARKER = 2, // Record head is at the specified marker position
- // (See setMarkerPosition()).
- EVENT_NEW_POS = 3, // Record head is at a new position
- // (See setPositionUpdatePeriod()).
- EVENT_NEW_IAUDIORECORD = 4, // IAudioRecord was re-created, either due to re-routing and
- // voluntary invalidation by mediaserver, or mediaserver crash.
- };
-
- /* Client should declare a Buffer and pass address to obtainBuffer()
- * and releaseBuffer(). See also legacy_callback_t for EVENT_MORE_DATA.
- */
-
class Buffer
{
friend AudioRecord;
@@ -122,7 +101,6 @@
* - EVENT_NEW_IAUDIORECORD: unused.
*/
- typedef void (*legacy_callback_t)(int event, void* user, void *info);
class IAudioRecordCallback : public virtual RefBase {
friend AudioRecord;
@@ -226,24 +204,6 @@
float selectedMicFieldDimension = MIC_FIELD_DIMENSION_DEFAULT);
- AudioRecord(audio_source_t inputSource,
- uint32_t sampleRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
- const android::content::AttributionSourceState& client,
- size_t frameCount,
- legacy_callback_t callback,
- void* user,
- uint32_t notificationFrames = 0,
- audio_session_t sessionId = AUDIO_SESSION_ALLOCATE,
- transfer_type transferType = TRANSFER_DEFAULT,
- audio_input_flags_t flags = AUDIO_INPUT_FLAG_NONE,
- const audio_attributes_t* pAttributes = nullptr,
- audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE,
- audio_microphone_direction_t
- selectedMicDirection = MIC_DIRECTION_UNSPECIFIED,
- float selectedMicFieldDimension = MIC_FIELD_DIMENSION_DEFAULT);
-
/* Terminates the AudioRecord and unregisters it from AudioFlinger.
* Also destroys all resources associated with the AudioRecord.
*/
@@ -286,27 +246,6 @@
float selectedMicFieldDimension = MIC_FIELD_DIMENSION_DEFAULT,
int32_t maxSharedAudioHistoryMs = 0);
- status_t set(audio_source_t inputSource,
- uint32_t sampleRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
- size_t frameCount,
- legacy_callback_t callback,
- void* user,
- uint32_t notificationFrames = 0,
- bool threadCanCallJava = false,
- audio_session_t sessionId = AUDIO_SESSION_ALLOCATE,
- transfer_type transferType = TRANSFER_DEFAULT,
- audio_input_flags_t flags = AUDIO_INPUT_FLAG_NONE,
- uid_t uid = AUDIO_UID_INVALID,
- pid_t pid = -1,
- const audio_attributes_t* pAttributes = nullptr,
- audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE,
- audio_microphone_direction_t
- selectedMicDirection = MIC_DIRECTION_UNSPECIFIED,
- float selectedMicFieldDimension = MIC_FIELD_DIMENSION_DEFAULT,
- int32_t maxSharedAudioHistoryMs = 0);
-
/* Result of constructing the AudioRecord. This must be checked for successful initialization
* before using any AudioRecord API (except for set()), because using
* an uninitialized AudioRecord produces undefined results.
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index 9411f46..3b7cc39 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -575,6 +575,12 @@
static status_t getSupportedLatencyModes(audio_io_handle_t output,
std::vector<audio_latency_mode_t>* modes);
+ static status_t setBluetoothVariableLatencyEnabled(bool enabled);
+
+ static status_t isBluetoothVariableLatencyEnabled(bool *enabled);
+
+ static status_t supportsBluetoothVariableLatency(bool *support);
+
// A listener for capture state changes.
class CaptureStateListener : public virtual RefBase {
public:
@@ -705,7 +711,8 @@
const media::AudioIoDescriptor& ioDesc) override;
binder::Status onSupportedLatencyModesChanged(
- int output, const std::vector<media::LatencyMode>& latencyModes) override;
+ int output,
+ const std::vector<media::audio::common::AudioLatencyMode>& latencyModes) override;
status_t addAudioDeviceCallback(const wp<AudioDeviceCallback>& callback,
audio_io_handle_t audioIo,
diff --git a/media/libaudioclient/include/media/AudioTrack.h b/media/libaudioclient/include/media/AudioTrack.h
index 9f540e6..b6ee483 100644
--- a/media/libaudioclient/include/media/AudioTrack.h
+++ b/media/libaudioclient/include/media/AudioTrack.h
@@ -148,7 +148,6 @@
* - EVENT_NEW_TIMESTAMP: pointer to const AudioTimestamp.
*/
- typedef void (*legacy_callback_t)(int event, void* user, void* info);
class IAudioTrackCallback : public virtual RefBase {
friend AudioTrack;
protected:
@@ -343,26 +342,6 @@
float maxRequiredSpeed = 1.0f,
audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE);
-
- AudioTrack( audio_stream_type_t streamType,
- uint32_t sampleRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
- size_t frameCount,
- audio_output_flags_t flags,
- legacy_callback_t cbf,
- void* user = nullptr,
- int32_t notificationFrames = 0,
- audio_session_t sessionId = AUDIO_SESSION_ALLOCATE,
- transfer_type transferType = TRANSFER_DEFAULT,
- const audio_offload_info_t *offloadInfo = nullptr,
- const AttributionSourceState& attributionSource =
- AttributionSourceState(),
- const audio_attributes_t* pAttributes = nullptr,
- bool doNotReconnect = false,
- float maxRequiredSpeed = 1.0f,
- audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE);
-
/* Creates an audio track and registers it with AudioFlinger.
* With this constructor, the track is configured for static buffer mode.
* Data to be rendered is passed in a shared memory buffer
@@ -391,25 +370,6 @@
bool doNotReconnect = false,
float maxRequiredSpeed = 1.0f);
-
- AudioTrack( audio_stream_type_t streamType,
- uint32_t sampleRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
- const sp<IMemory>& sharedBuffer,
- audio_output_flags_t flags,
- legacy_callback_t cbf,
- void* user = nullptr,
- int32_t notificationFrames = 0,
- audio_session_t sessionId = AUDIO_SESSION_ALLOCATE,
- transfer_type transferType = TRANSFER_DEFAULT,
- const audio_offload_info_t *offloadInfo = nullptr,
- const AttributionSourceState& attributionSource =
- AttributionSourceState(),
- const audio_attributes_t* pAttributes = nullptr,
- bool doNotReconnect = false,
- float maxRequiredSpeed = 1.0f);
-
/* Terminates the AudioTrack and unregisters it from AudioFlinger.
* Also destroys all resources associated with the AudioTrack.
*/
@@ -490,28 +450,8 @@
}
void onFirstRef() override;
public:
- status_t set(audio_stream_type_t streamType,
- uint32_t sampleRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
- size_t frameCount,
- audio_output_flags_t flags,
- legacy_callback_t callback,
- void * user = nullptr,
- int32_t notificationFrames = 0,
- const sp<IMemory>& sharedBuffer = 0,
- bool threadCanCallJava = false,
- audio_session_t sessionId = AUDIO_SESSION_ALLOCATE,
- transfer_type transferType = TRANSFER_DEFAULT,
- const audio_offload_info_t *offloadInfo = nullptr,
- const AttributionSourceState& attributionSource =
- AttributionSourceState(),
- const audio_attributes_t* pAttributes = nullptr,
- bool doNotReconnect = false,
- float maxRequiredSpeed = 1.0f,
- audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE);
-
- // FIXME(b/169889714): Vendor code depends on the old method signature at link time
+ typedef void (*legacy_callback_t)(int event, void* user, void* info);
+ // FIXME(b/169889714): Vendor code depends on the old method signature at link time
status_t set(audio_stream_type_t streamType,
uint32_t sampleRate,
audio_format_t format,
diff --git a/media/libaudioclient/include/media/IAudioFlinger.h b/media/libaudioclient/include/media/IAudioFlinger.h
index c891ae6..1177e5a 100644
--- a/media/libaudioclient/include/media/IAudioFlinger.h
+++ b/media/libaudioclient/include/media/IAudioFlinger.h
@@ -367,6 +367,11 @@
virtual status_t getSupportedLatencyModes(audio_io_handle_t output,
std::vector<audio_latency_mode_t>* modes) = 0;
+ virtual status_t setBluetoothVariableLatencyEnabled(bool enabled) = 0;
+
+ virtual status_t isBluetoothVariableLatencyEnabled(bool* enabled) = 0;
+
+ virtual status_t supportsBluetoothVariableLatency(bool* support) = 0;
};
/**
@@ -473,6 +478,9 @@
audio_latency_mode_t mode) override;
status_t getSupportedLatencyModes(
audio_io_handle_t output, std::vector<audio_latency_mode_t>* modes) override;
+ status_t setBluetoothVariableLatencyEnabled(bool enabled) override;
+ status_t isBluetoothVariableLatencyEnabled(bool* enabled) override;
+ status_t supportsBluetoothVariableLatency(bool* support) override;
private:
const sp<media::IAudioFlingerService> mDelegate;
@@ -564,6 +572,12 @@
SET_DEVICE_CONNECTED_STATE = media::BnAudioFlingerService::TRANSACTION_setDeviceConnectedState,
SET_REQUESTED_LATENCY_MODE = media::BnAudioFlingerService::TRANSACTION_setRequestedLatencyMode,
GET_SUPPORTED_LATENCY_MODES = media::BnAudioFlingerService::TRANSACTION_getSupportedLatencyModes,
+ SET_BLUETOOTH_VARIABLE_LATENCY_ENABLED =
+ media::BnAudioFlingerService::TRANSACTION_setBluetoothVariableLatencyEnabled,
+ IS_BLUETOOTH_VARIABLE_LATENCY_ENABLED =
+ media::BnAudioFlingerService::TRANSACTION_isBluetoothVariableLatencyEnabled,
+ SUPPORTS_BLUETOOTH_VARIABLE_LATENCY =
+ media::BnAudioFlingerService::TRANSACTION_supportsBluetoothVariableLatency,
};
protected:
@@ -664,12 +678,12 @@
Status getPrimaryOutputSamplingRate(int32_t* _aidl_return) override;
Status getPrimaryOutputFrameCount(int64_t* _aidl_return) override;
Status setLowRamDevice(bool isLowRamDevice, int64_t totalMemory) override;
- Status getAudioPort(const media::AudioPort& port, media::AudioPort* _aidl_return) override;
- Status createAudioPatch(const media::AudioPatch& patch, int32_t* _aidl_return) override;
+ Status getAudioPort(const media::AudioPortFw& port, media::AudioPortFw* _aidl_return) override;
+ Status createAudioPatch(const media::AudioPatchFw& patch, int32_t* _aidl_return) override;
Status releaseAudioPatch(int32_t handle) override;
Status listAudioPatches(int32_t maxCount,
- std::vector<media::AudioPatch>* _aidl_return) override;
- Status setAudioPortConfig(const media::AudioPortConfig& config) override;
+ std::vector<media::AudioPatchFw>* _aidl_return) override;
+ Status setAudioPortConfig(const media::AudioPortConfigFw& config) override;
Status getAudioHwSyncForSession(int32_t sessionId, int32_t* _aidl_return) override;
Status systemReady() override;
Status audioPolicyReady() override;
@@ -684,10 +698,14 @@
std::vector<media::audio::common::AudioMMapPolicyInfo> *_aidl_return) override;
Status getAAudioMixerBurstCount(int32_t* _aidl_return) override;
Status getAAudioHardwareBurstMinUsec(int32_t* _aidl_return) override;
- Status setDeviceConnectedState(const media::AudioPort& port, bool connected) override;
- Status setRequestedLatencyMode(int output, media::LatencyMode mode) override;
+ Status setDeviceConnectedState(const media::AudioPortFw& port, bool connected) override;
+ Status setRequestedLatencyMode(
+ int output, media::audio::common::AudioLatencyMode mode) override;
Status getSupportedLatencyModes(int output,
- std::vector<media::LatencyMode>* _aidl_return) override;
+ std::vector<media::audio::common::AudioLatencyMode>* _aidl_return) override;
+ Status setBluetoothVariableLatencyEnabled(bool enabled) override;
+ Status isBluetoothVariableLatencyEnabled(bool* enabled) override;
+ Status supportsBluetoothVariableLatency(bool* support) override;
private:
const sp<AudioFlingerServerAdapter::Delegate> mDelegate;
};
diff --git a/media/libaudioclient/tests/Android.bp b/media/libaudioclient/tests/Android.bp
index 891293e..dcb6c25 100644
--- a/media/libaudioclient/tests/Android.bp
+++ b/media/libaudioclient/tests/Android.bp
@@ -24,7 +24,10 @@
cc_test {
name: "audio_aidl_conversion_tests",
- defaults: ["libaudioclient_tests_defaults"],
+ defaults: [
+ "libaudioclient_tests_defaults",
+ "latest_android_media_audio_common_types_cpp_static",
+ ],
srcs: ["audio_aidl_legacy_conversion_tests.cpp"],
shared_libs: [
"libbinder",
@@ -33,9 +36,9 @@
"libutils",
],
static_libs: [
- "android.media.audio.common.types-V1-cpp",
- "audioclient-types-aidl-cpp",
"libaudioclient_aidl_conversion",
+ "libaudio_aidl_conversion_common_cpp",
+ "audioclient-types-aidl-cpp",
"libstagefright_foundation",
],
}
@@ -93,3 +96,132 @@
],
data: ["record_test_input_*.txt"],
}
+
+cc_defaults {
+ name: "libaudioclient_gtests_defaults",
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+ defaults: [
+ "latest_android_media_audio_common_types_cpp_static",
+ ],
+ shared_libs: [
+ "capture_state_listener-aidl-cpp",
+ "framework-permission-aidl-cpp",
+ "libaudioclient_aidl_conversion",
+ "libaudio_aidl_conversion_common_cpp",
+ "libbase",
+ "libbinder",
+ "libcgrouprc",
+ "libcutils",
+ "libdl",
+ "liblog",
+ "libmedia",
+ "libmediametrics",
+ "libmediautils",
+ "libmedia_helper",
+ "libnblog",
+ "libprocessgroup",
+ "libshmemcompat",
+ "libstagefright_foundation",
+ "libutils",
+ "libxml2",
+ "mediametricsservice-aidl-cpp",
+ "packagemanager_aidl-cpp",
+ "shared-file-region-aidl-cpp",
+ ],
+ static_libs: [
+ "android.hardware.audio.common@7.0-enums",
+ "audioclient-types-aidl-cpp",
+ "audioflinger-aidl-cpp",
+ "audiopolicy-aidl-cpp",
+ "audiopolicy-types-aidl-cpp",
+ "av-types-aidl-cpp",
+ "effect-aidl-cpp",
+ "libaudioclient",
+ "libaudiofoundation",
+ "libaudiomanager",
+ "libaudiopolicy",
+ "libaudioutils",
+ ],
+ data: ["bbb*.raw"],
+ test_config_template: "audio_test_template.xml",
+ test_suites: ["device-tests"],
+}
+
+cc_test {
+ name: "audiorecord_tests",
+ defaults: ["libaudioclient_gtests_defaults"],
+ srcs: [
+ "audiorecord_tests.cpp",
+ "audio_test_utils.cpp",
+ ],
+}
+
+cc_test {
+ name: "audiotrack_tests",
+ defaults: ["libaudioclient_gtests_defaults"],
+ srcs: [
+ "audiotrack_tests.cpp",
+ "audio_test_utils.cpp",
+ ],
+}
+
+cc_test {
+ name: "audioeffect_tests",
+ defaults: ["libaudioclient_gtests_defaults"],
+ srcs: [
+ "audioeffect_tests.cpp",
+ "audio_test_utils.cpp",
+ ],
+}
+
+cc_test {
+ name: "audioeffect_analysis",
+ defaults: ["libaudioclient_gtests_defaults"],
+ // flag needed for pfft/pffft.hpp
+ cflags: [
+ "-Wno-error=unused-parameter",
+ ],
+ srcs: [
+ "audioeffect_analyser.cpp",
+ "audio_test_utils.cpp",
+ ],
+ static_libs: [
+ "libpffft",
+ ],
+}
+
+cc_test {
+ name: "audiorouting_tests",
+ defaults: ["libaudioclient_gtests_defaults"],
+ srcs: [
+ "audiorouting_tests.cpp",
+ "audio_test_utils.cpp",
+ ],
+}
+
+cc_test {
+ name: "audioclient_serialization_tests",
+ defaults: ["libaudioclient_gtests_defaults"],
+ srcs: [
+ "audioclient_serialization_tests.cpp",
+ "audio_test_utils.cpp",
+ ],
+}
+
+cc_test {
+ name: "trackplayerbase_tests",
+ defaults: ["libaudioclient_gtests_defaults"],
+ srcs: ["trackplayerbase_tests.cpp"],
+}
+
+cc_test {
+ name: "audiosystem_tests",
+ defaults: ["libaudioclient_gtests_defaults"],
+ srcs: [
+ "audiosystem_tests.cpp",
+ "audio_test_utils.cpp",
+ ],
+}
diff --git a/media/libaudioclient/tests/audio_aidl_legacy_conversion_tests.cpp b/media/libaudioclient/tests/audio_aidl_legacy_conversion_tests.cpp
index 997f62a..9e663bc 100644
--- a/media/libaudioclient/tests/audio_aidl_legacy_conversion_tests.cpp
+++ b/media/libaudioclient/tests/audio_aidl_legacy_conversion_tests.cpp
@@ -16,22 +16,29 @@
#include <gtest/gtest.h>
-#include <media/AudioCommonTypes.h>
#include <media/AidlConversion.h>
+#include <media/AudioCommonTypes.h>
using namespace android;
using namespace android::aidl_utils;
+using android::media::AudioDirectMode;
using media::audio::common::AudioChannelLayout;
using media::audio::common::AudioDeviceDescription;
using media::audio::common::AudioDeviceType;
+using media::audio::common::AudioEncapsulationMetadataType;
+using media::audio::common::AudioEncapsulationType;
using media::audio::common::AudioFormatDescription;
using media::audio::common::AudioFormatType;
+using media::audio::common::AudioGainMode;
+using media::audio::common::AudioStandard;
+using media::audio::common::ExtraAudioDescriptor;
using media::audio::common::PcmType;
namespace {
-template<typename T> size_t hash(const T& t) {
+template <typename T>
+size_t hash(const T& t) {
return std::hash<T>{}(t);
}
@@ -52,10 +59,8 @@
return AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
// Use channels that exist both for input and output,
// but doesn't form a known layout mask.
- AudioChannelLayout::CHANNEL_FRONT_LEFT |
- AudioChannelLayout::CHANNEL_FRONT_RIGHT |
- AudioChannelLayout::CHANNEL_TOP_SIDE_LEFT |
- AudioChannelLayout::CHANNEL_TOP_SIDE_RIGHT);
+ AudioChannelLayout::CHANNEL_FRONT_LEFT | AudioChannelLayout::CHANNEL_FRONT_RIGHT |
+ AudioChannelLayout::CHANNEL_TOP_SIDE_LEFT | AudioChannelLayout::CHANNEL_TOP_SIDE_RIGHT);
}
AudioChannelLayout make_ACL_ChannelIndex2() {
@@ -74,7 +79,7 @@
}
AudioDeviceDescription make_AudioDeviceDescription(AudioDeviceType type,
- const std::string& connection = "") {
+ const std::string& connection = "") {
AudioDeviceDescription result;
result.type = type;
result.connection = connection;
@@ -95,12 +100,12 @@
AudioDeviceDescription make_ADD_WiredHeadset() {
return make_AudioDeviceDescription(AudioDeviceType::OUT_HEADSET,
- AudioDeviceDescription::CONNECTION_ANALOG());
+ AudioDeviceDescription::CONNECTION_ANALOG());
}
AudioDeviceDescription make_ADD_BtScoHeadset() {
return make_AudioDeviceDescription(AudioDeviceType::OUT_HEADSET,
- AudioDeviceDescription::CONNECTION_BT_SCO());
+ AudioDeviceDescription::CONNECTION_BT_SCO());
}
AudioFormatDescription make_AudioFormatDescription(AudioFormatType type) {
@@ -121,8 +126,7 @@
return result;
}
-AudioFormatDescription make_AudioFormatDescription(PcmType transport,
- const std::string& encoding) {
+AudioFormatDescription make_AudioFormatDescription(PcmType transport, const std::string& encoding) {
auto result = make_AudioFormatDescription(encoding);
result.pcm = transport;
return result;
@@ -154,6 +158,22 @@
return afd;
}
+android::media::TrackSecondaryOutputInfo make_TrackSecondaryOutputInfo() {
+ android::media::TrackSecondaryOutputInfo result;
+ result.portId = 1;
+ result.secondaryOutputIds = {0, 5, 7};
+ return result;
+}
+
+ExtraAudioDescriptor make_ExtraAudioDescriptor(AudioStandard audioStandard,
+ AudioEncapsulationType audioEncapsulationType) {
+ ExtraAudioDescriptor result;
+ result.standard = audioStandard;
+ result.audioDescriptor = {0xb4, 0xaf, 0x98, 0x1a};
+ result.encapsulationType = audioEncapsulationType;
+ return result;
+}
+
} // namespace
// Verify that two independently constructed ADDs/AFDs have the same hash.
@@ -163,7 +183,8 @@
// is identical to the same format description constructed by the framework.
class HashIdentityTest : public ::testing::Test {
public:
- template<typename T> void verifyHashIdentity(const std::vector<std::function<T()>>& valueGens) {
+ template <typename T>
+ void verifyHashIdentity(const std::vector<std::function<T()>>& valueGens) {
for (size_t i = 0; i < valueGens.size(); ++i) {
for (size_t j = 0; j < valueGens.size(); ++j) {
if (i == j) {
@@ -177,27 +198,25 @@
};
TEST_F(HashIdentityTest, AudioChannelLayoutHashIdentity) {
- verifyHashIdentity<AudioChannelLayout>({
- make_ACL_None, make_ACL_Invalid, make_ACL_Stereo,
- make_ACL_LayoutArbitrary, make_ACL_ChannelIndex2,
- make_ACL_ChannelIndexArbitrary, make_ACL_VoiceCall});
+ verifyHashIdentity<AudioChannelLayout>({make_ACL_None, make_ACL_Invalid, make_ACL_Stereo,
+ make_ACL_LayoutArbitrary, make_ACL_ChannelIndex2,
+ make_ACL_ChannelIndexArbitrary, make_ACL_VoiceCall});
}
TEST_F(HashIdentityTest, AudioDeviceDescriptionHashIdentity) {
- verifyHashIdentity<AudioDeviceDescription>({
- make_ADD_None, make_ADD_DefaultIn, make_ADD_DefaultOut, make_ADD_WiredHeadset,
- make_ADD_BtScoHeadset});
+ verifyHashIdentity<AudioDeviceDescription>({make_ADD_None, make_ADD_DefaultIn,
+ make_ADD_DefaultOut, make_ADD_WiredHeadset,
+ make_ADD_BtScoHeadset});
}
TEST_F(HashIdentityTest, AudioFormatDescriptionHashIdentity) {
- verifyHashIdentity<AudioFormatDescription>({
- make_AFD_Default, make_AFD_Invalid, make_AFD_Pcm16Bit, make_AFD_Bitstream,
- make_AFD_Encap, make_AFD_Encap_with_Enc});
+ verifyHashIdentity<AudioFormatDescription>({make_AFD_Default, make_AFD_Invalid,
+ make_AFD_Pcm16Bit, make_AFD_Bitstream,
+ make_AFD_Encap, make_AFD_Encap_with_Enc});
}
using ChannelLayoutParam = std::tuple<AudioChannelLayout, bool /*isInput*/>;
-class AudioChannelLayoutRoundTripTest :
- public testing::TestWithParam<ChannelLayoutParam> {};
+class AudioChannelLayoutRoundTripTest : public testing::TestWithParam<ChannelLayoutParam> {};
TEST_P(AudioChannelLayoutRoundTripTest, Aidl2Legacy2Aidl) {
const auto initial = std::get<0>(GetParam());
const bool isInput = std::get<1>(GetParam());
@@ -207,21 +226,82 @@
ASSERT_TRUE(convBack.ok());
EXPECT_EQ(initial, convBack.value());
}
-INSTANTIATE_TEST_SUITE_P(AudioChannelLayoutRoundTrip,
- AudioChannelLayoutRoundTripTest,
+
+INSTANTIATE_TEST_SUITE_P(
+ AudioChannelLayoutRoundTrip, AudioChannelLayoutRoundTripTest,
testing::Combine(
testing::Values(AudioChannelLayout{}, make_ACL_Invalid(), make_ACL_Stereo(),
- make_ACL_LayoutArbitrary(), make_ACL_ChannelIndex2(),
- make_ACL_ChannelIndexArbitrary()),
+ make_ACL_LayoutArbitrary(), make_ACL_ChannelIndex2(),
+ make_ACL_ChannelIndexArbitrary(),
+ AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
+ AudioChannelLayout::CHANNEL_FRONT_LEFT),
+ AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
+ AudioChannelLayout::CHANNEL_FRONT_RIGHT),
+ AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
+ AudioChannelLayout::CHANNEL_BACK_CENTER),
+ AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
+ AudioChannelLayout::CHANNEL_BACK_LEFT),
+ AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
+ AudioChannelLayout::CHANNEL_BACK_RIGHT),
+ AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
+ AudioChannelLayout::CHANNEL_FRONT_CENTER),
+ AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
+ AudioChannelLayout::CHANNEL_LOW_FREQUENCY),
+ AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
+ AudioChannelLayout::CHANNEL_TOP_SIDE_LEFT),
+ AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
+ AudioChannelLayout::CHANNEL_TOP_SIDE_RIGHT)),
testing::Values(false, true)));
-INSTANTIATE_TEST_SUITE_P(AudioChannelVoiceRoundTrip,
- AudioChannelLayoutRoundTripTest,
- // In legacy constants the voice call is only defined for input.
- testing::Combine(testing::Values(make_ACL_VoiceCall()), testing::Values(true)));
+INSTANTIATE_TEST_SUITE_P(AudioChannelVoiceRoundTrip, AudioChannelLayoutRoundTripTest,
+ // In legacy constants the voice call is only defined for input.
+ testing::Combine(testing::Values(make_ACL_VoiceCall()),
+ testing::Values(true)));
+
+INSTANTIATE_TEST_SUITE_P(
+ OutAudioChannelLayoutLayoutRoundTrip, AudioChannelLayoutRoundTripTest,
+ testing::Combine(
+ testing::Values(AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
+ AudioChannelLayout::CHANNEL_FRONT_LEFT_OF_CENTER),
+ AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
+ AudioChannelLayout::CHANNEL_FRONT_RIGHT_OF_CENTER),
+ AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
+ AudioChannelLayout::CHANNEL_SIDE_LEFT),
+ AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
+ AudioChannelLayout::CHANNEL_SIDE_RIGHT),
+ AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
+ AudioChannelLayout::CHANNEL_TOP_CENTER),
+ AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
+ AudioChannelLayout::CHANNEL_TOP_FRONT_LEFT),
+ AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
+ AudioChannelLayout::CHANNEL_TOP_FRONT_CENTER),
+ AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
+ AudioChannelLayout::CHANNEL_TOP_FRONT_RIGHT),
+ AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
+ AudioChannelLayout::CHANNEL_TOP_BACK_LEFT),
+ AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
+ AudioChannelLayout::CHANNEL_TOP_BACK_CENTER),
+ AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
+ AudioChannelLayout::CHANNEL_TOP_BACK_RIGHT),
+ AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
+ AudioChannelLayout::CHANNEL_BOTTOM_FRONT_LEFT),
+ AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
+ AudioChannelLayout::CHANNEL_BOTTOM_FRONT_CENTER),
+ AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
+ AudioChannelLayout::CHANNEL_BOTTOM_FRONT_RIGHT),
+ AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
+ AudioChannelLayout::CHANNEL_LOW_FREQUENCY_2),
+ AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
+ AudioChannelLayout::CHANNEL_FRONT_WIDE_LEFT),
+ AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
+ AudioChannelLayout::CHANNEL_FRONT_WIDE_RIGHT),
+ AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
+ AudioChannelLayout::CHANNEL_HAPTIC_A),
+ AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
+ AudioChannelLayout::CHANNEL_HAPTIC_B)),
+ testing::Values(false)));
using ChannelLayoutEdgeCaseParam = std::tuple<int /*legacy*/, bool /*isInput*/, bool /*isValid*/>;
-class AudioChannelLayoutEdgeCaseTest :
- public testing::TestWithParam<ChannelLayoutEdgeCaseParam> {};
+class AudioChannelLayoutEdgeCaseTest : public testing::TestWithParam<ChannelLayoutEdgeCaseParam> {};
TEST_P(AudioChannelLayoutEdgeCaseTest, Legacy2Aidl) {
const audio_channel_mask_t legacy = static_cast<audio_channel_mask_t>(std::get<0>(GetParam()));
const bool isInput = std::get<1>(GetParam());
@@ -229,8 +309,8 @@
auto conv = legacy2aidl_audio_channel_mask_t_AudioChannelLayout(legacy, isInput);
EXPECT_EQ(isValid, conv.ok());
}
-INSTANTIATE_TEST_SUITE_P(AudioChannelLayoutEdgeCase,
- AudioChannelLayoutEdgeCaseTest,
+INSTANTIATE_TEST_SUITE_P(
+ AudioChannelLayoutEdgeCase, AudioChannelLayoutEdgeCaseTest,
testing::Values(
// Valid legacy input masks.
std::make_tuple(AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO, true, true),
@@ -240,25 +320,26 @@
std::make_tuple(
// This has the same numerical representation as Mask 'A' below
AUDIO_CHANNEL_OUT_FRONT_CENTER | AUDIO_CHANNEL_OUT_LOW_FREQUENCY |
- AUDIO_CHANNEL_OUT_TOP_FRONT_RIGHT, false, true),
+ AUDIO_CHANNEL_OUT_TOP_FRONT_RIGHT,
+ false, true),
std::make_tuple(
// This has the same numerical representation as Mask 'B' below
AUDIO_CHANNEL_OUT_FRONT_CENTER | AUDIO_CHANNEL_OUT_LOW_FREQUENCY |
- AUDIO_CHANNEL_OUT_TOP_BACK_LEFT, false, true),
+ AUDIO_CHANNEL_OUT_TOP_BACK_LEFT,
+ false, true),
// Invalid legacy input masks.
std::make_tuple(AUDIO_CHANNEL_IN_6, true, false),
- std::make_tuple(
- AUDIO_CHANNEL_IN_6 | AUDIO_CHANNEL_IN_FRONT_PROCESSED, true, false),
- std::make_tuple(
- AUDIO_CHANNEL_IN_PRESSURE | AUDIO_CHANNEL_IN_X_AXIS |
- AUDIO_CHANNEL_IN_Y_AXIS | AUDIO_CHANNEL_IN_Z_AXIS, true, false),
+ std::make_tuple(AUDIO_CHANNEL_IN_6 | AUDIO_CHANNEL_IN_FRONT_PROCESSED, true, false),
+ std::make_tuple(AUDIO_CHANNEL_IN_PRESSURE | AUDIO_CHANNEL_IN_X_AXIS |
+ AUDIO_CHANNEL_IN_Y_AXIS | AUDIO_CHANNEL_IN_Z_AXIS,
+ true, false),
std::make_tuple( // Mask 'A'
AUDIO_CHANNEL_IN_STEREO | AUDIO_CHANNEL_IN_VOICE_UPLINK, true, false),
std::make_tuple( // Mask 'B'
AUDIO_CHANNEL_IN_STEREO | AUDIO_CHANNEL_IN_VOICE_DNLINK, true, false)));
-class AudioDeviceDescriptionRoundTripTest :
- public testing::TestWithParam<AudioDeviceDescription> {};
+class AudioDeviceDescriptionRoundTripTest : public testing::TestWithParam<AudioDeviceDescription> {
+};
TEST_P(AudioDeviceDescriptionRoundTripTest, Aidl2Legacy2Aidl) {
const auto initial = GetParam();
auto conv = aidl2legacy_AudioDeviceDescription_audio_devices_t(initial);
@@ -267,13 +348,13 @@
ASSERT_TRUE(convBack.ok());
EXPECT_EQ(initial, convBack.value());
}
-INSTANTIATE_TEST_SUITE_P(AudioDeviceDescriptionRoundTrip,
- AudioDeviceDescriptionRoundTripTest,
- testing::Values(AudioDeviceDescription{}, make_ADD_DefaultIn(),
- make_ADD_DefaultOut(), make_ADD_WiredHeadset(), make_ADD_BtScoHeadset()));
+INSTANTIATE_TEST_SUITE_P(AudioDeviceDescriptionRoundTrip, AudioDeviceDescriptionRoundTripTest,
+ testing::Values(AudioDeviceDescription{}, make_ADD_DefaultIn(),
+ make_ADD_DefaultOut(), make_ADD_WiredHeadset(),
+ make_ADD_BtScoHeadset()));
-class AudioFormatDescriptionRoundTripTest :
- public testing::TestWithParam<AudioFormatDescription> {};
+class AudioFormatDescriptionRoundTripTest : public testing::TestWithParam<AudioFormatDescription> {
+};
TEST_P(AudioFormatDescriptionRoundTripTest, Aidl2Legacy2Aidl) {
const auto initial = GetParam();
auto conv = aidl2legacy_AudioFormatDescription_audio_format_t(initial);
@@ -282,6 +363,140 @@
ASSERT_TRUE(convBack.ok());
EXPECT_EQ(initial, convBack.value());
}
-INSTANTIATE_TEST_SUITE_P(AudioFormatDescriptionRoundTrip,
- AudioFormatDescriptionRoundTripTest,
- testing::Values(make_AFD_Invalid(), AudioFormatDescription{}, make_AFD_Pcm16Bit()));
+INSTANTIATE_TEST_SUITE_P(AudioFormatDescriptionRoundTrip, AudioFormatDescriptionRoundTripTest,
+ testing::Values(make_AFD_Invalid(), AudioFormatDescription{},
+ make_AFD_Pcm16Bit()));
+
+class AudioDirectModeRoundTripTest : public testing::TestWithParam<AudioDirectMode> {};
+TEST_P(AudioDirectModeRoundTripTest, Aidl2Legacy2Aidl) {
+ const auto initial = GetParam();
+ auto conv = aidl2legacy_AudioDirectMode_audio_direct_mode_t(initial);
+ ASSERT_TRUE(conv.ok());
+ auto convBack = legacy2aidl_audio_direct_mode_t_AudioDirectMode(conv.value());
+ ASSERT_TRUE(convBack.ok());
+ EXPECT_EQ(initial, convBack.value());
+}
+INSTANTIATE_TEST_SUITE_P(AudioDirectMode, AudioDirectModeRoundTripTest,
+ testing::Values(AudioDirectMode::NONE, AudioDirectMode::OFFLOAD,
+ AudioDirectMode::OFFLOAD_GAPLESS,
+ AudioDirectMode::BITSTREAM));
+
+class AudioStandardRoundTripTest : public testing::TestWithParam<AudioStandard> {};
+TEST_P(AudioStandardRoundTripTest, Aidl2Legacy2Aidl) {
+ const auto initial = GetParam();
+ auto conv = aidl2legacy_AudioStandard_audio_standard_t(initial);
+ ASSERT_TRUE(conv.ok());
+ auto convBack = legacy2aidl_audio_standard_t_AudioStandard(conv.value());
+ ASSERT_TRUE(convBack.ok());
+ EXPECT_EQ(initial, convBack.value());
+}
+INSTANTIATE_TEST_SUITE_P(AudioStandard, AudioStandardRoundTripTest,
+ testing::Values(AudioStandard::NONE, AudioStandard::EDID));
+
+class AudioEncapsulationMetadataTypeRoundTripTest
+ : public testing::TestWithParam<AudioEncapsulationMetadataType> {};
+TEST_P(AudioEncapsulationMetadataTypeRoundTripTest, Aidl2Legacy2Aidl) {
+ const auto initial = GetParam();
+ auto conv =
+ aidl2legacy_AudioEncapsulationMetadataType_audio_encapsulation_metadata_type_t(initial);
+ ASSERT_TRUE(conv.ok());
+ auto convBack = legacy2aidl_audio_encapsulation_metadata_type_t_AudioEncapsulationMetadataType(
+ conv.value());
+ ASSERT_TRUE(convBack.ok());
+ EXPECT_EQ(initial, convBack.value());
+}
+INSTANTIATE_TEST_SUITE_P(AudioEncapsulationMetadataType,
+ AudioEncapsulationMetadataTypeRoundTripTest,
+ testing::Values(AudioEncapsulationMetadataType::NONE,
+ AudioEncapsulationMetadataType::FRAMEWORK_TUNER,
+ AudioEncapsulationMetadataType::DVB_AD_DESCRIPTOR));
+
+class AudioGainModeRoundTripTest : public testing::TestWithParam<AudioGainMode> {};
+TEST_P(AudioGainModeRoundTripTest, Aidl2Legacy2Aidl) {
+ const auto initial = GetParam();
+ auto conv = aidl2legacy_AudioGainMode_audio_gain_mode_t(initial);
+ ASSERT_TRUE(conv.ok());
+ auto convBack = legacy2aidl_audio_gain_mode_t_AudioGainMode(conv.value());
+ ASSERT_TRUE(convBack.ok());
+ EXPECT_EQ(initial, convBack.value());
+}
+INSTANTIATE_TEST_SUITE_P(AudioGainMode, AudioGainModeRoundTripTest,
+ testing::Values(AudioGainMode::JOINT, AudioGainMode::CHANNELS,
+ AudioGainMode::RAMP));
+
+TEST(AudioTrackSecondaryOutputInfoRoundTripTest, Aidl2Legacy2Aidl) {
+ const auto initial = make_TrackSecondaryOutputInfo();
+ auto conv = aidl2legacy_TrackSecondaryOutputInfo_TrackSecondaryOutputInfoPair(initial);
+ ASSERT_TRUE(conv.ok());
+ auto convBack = legacy2aidl_TrackSecondaryOutputInfoPair_TrackSecondaryOutputInfo(conv.value());
+ ASSERT_TRUE(convBack.ok());
+ EXPECT_EQ(initial, convBack.value());
+}
+
+using ExtraAudioDescriptorParam = std::tuple<AudioStandard, AudioEncapsulationType>;
+class ExtraAudioDescriptorRoundTripTest : public testing::TestWithParam<ExtraAudioDescriptorParam> {
+};
+TEST_P(ExtraAudioDescriptorRoundTripTest, Aidl2Legacy2Aidl) {
+ ExtraAudioDescriptor initial =
+ make_ExtraAudioDescriptor(std::get<0>(GetParam()), std::get<1>(GetParam()));
+ auto conv = aidl2legacy_ExtraAudioDescriptor_audio_extra_audio_descriptor(initial);
+ ASSERT_TRUE(conv.ok());
+ auto convBack = legacy2aidl_audio_extra_audio_descriptor_ExtraAudioDescriptor(conv.value());
+ ASSERT_TRUE(convBack.ok());
+ EXPECT_EQ(initial, convBack.value());
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ ExtraAudioDescriptor, ExtraAudioDescriptorRoundTripTest,
+ testing::Values(std::make_tuple(AudioStandard::NONE, AudioEncapsulationType::NONE),
+ std::make_tuple(AudioStandard::EDID, AudioEncapsulationType::NONE),
+ std::make_tuple(AudioStandard::EDID, AudioEncapsulationType::IEC61937)));
+
+TEST(AudioPortSessionExtRoundTripTest, Aidl2Legacy2Aidl) {
+ const int32_t initial = 7;
+ auto conv = aidl2legacy_int32_t_audio_port_session_ext(initial);
+ ASSERT_TRUE(conv.ok());
+ auto convBack = legacy2aidl_audio_port_session_ext_int32_t(conv.value());
+ ASSERT_TRUE(convBack.ok());
+ EXPECT_EQ(initial, convBack.value());
+}
+
+class AudioGainTest : public testing::TestWithParam<bool> {};
+TEST_P(AudioGainTest, Legacy2Aidl2Legacy) {
+ audio_port_v7 port;
+ port.num_gains = 2;
+ port.gains[0] = {.mode = AUDIO_GAIN_MODE_JOINT,
+ .channel_mask = AUDIO_CHANNEL_IN_STEREO,
+ .min_value = -3200,
+ .max_value = 600,
+ .default_value = 0,
+ .step_value = 100,
+ .min_ramp_ms = 10,
+ .max_ramp_ms = 20};
+ port.gains[1] = {.mode = AUDIO_GAIN_MODE_JOINT,
+ .channel_mask = AUDIO_CHANNEL_IN_MONO,
+ .min_value = -8800,
+ .max_value = 4000,
+ .default_value = 0,
+ .step_value = 100,
+ .min_ramp_ms = 192,
+ .max_ramp_ms = 224};
+
+ const auto isInput = GetParam();
+ for (int i = 0; i < port.num_gains; i++) {
+ auto initial = port.gains[i];
+ auto conv = legacy2aidl_audio_gain_AudioGain(initial, isInput);
+ ASSERT_TRUE(conv.ok());
+ auto convBack = aidl2legacy_AudioGain_audio_gain(conv.value(), isInput);
+ ASSERT_TRUE(convBack.ok());
+ EXPECT_EQ(initial.mode, convBack.value().mode);
+ EXPECT_EQ(initial.channel_mask, convBack.value().channel_mask);
+ EXPECT_EQ(initial.min_value, convBack.value().min_value);
+ EXPECT_EQ(initial.max_value, convBack.value().max_value);
+ EXPECT_EQ(initial.default_value, convBack.value().default_value);
+ EXPECT_EQ(initial.step_value, convBack.value().step_value);
+ EXPECT_EQ(initial.min_ramp_ms, convBack.value().min_ramp_ms);
+ EXPECT_EQ(initial.max_ramp_ms, convBack.value().max_ramp_ms);
+ }
+}
+INSTANTIATE_TEST_SUITE_P(AudioGain, AudioGainTest, testing::Values(true, false));
diff --git a/media/libaudioclient/tests/audio_aidl_status_tests.cpp b/media/libaudioclient/tests/audio_aidl_status_tests.cpp
index 5517091..8a7e6c1 100644
--- a/media/libaudioclient/tests/audio_aidl_status_tests.cpp
+++ b/media/libaudioclient/tests/audio_aidl_status_tests.cpp
@@ -37,25 +37,10 @@
// Special status values are preserved on round trip.
TEST(audio_aidl_status_tests, statusRoundTripSpecialValues) {
- for (status_t status : {
- OK,
- UNKNOWN_ERROR,
- NO_MEMORY,
- INVALID_OPERATION,
- BAD_VALUE,
- BAD_TYPE,
- NAME_NOT_FOUND,
- PERMISSION_DENIED,
- NO_INIT,
- ALREADY_EXISTS,
- DEAD_OBJECT,
- FAILED_TRANSACTION,
- BAD_INDEX,
- NOT_ENOUGH_DATA,
- WOULD_BLOCK,
- TIMED_OUT,
- UNKNOWN_TRANSACTION,
- FDS_NOT_ALLOWED}) {
+ for (status_t status :
+ {OK, UNKNOWN_ERROR, NO_MEMORY, INVALID_OPERATION, BAD_VALUE, BAD_TYPE, NAME_NOT_FOUND,
+ PERMISSION_DENIED, NO_INIT, ALREADY_EXISTS, DEAD_OBJECT, FAILED_TRANSACTION, BAD_INDEX,
+ NOT_ENOUGH_DATA, WOULD_BLOCK, TIMED_OUT, UNKNOWN_TRANSACTION, FDS_NOT_ALLOWED}) {
ASSERT_EQ(status, statusTFromBinderStatus(binderStatusFromStatusT(status)));
}
}
@@ -63,47 +48,29 @@
// Binder exceptions show as an error (not fixed at this time); these come fromExceptionCode().
TEST(audio_aidl_status_tests, binderStatusExceptions) {
for (int exceptionCode : {
- //Status::EX_NONE,
- Status::EX_SECURITY,
- Status::EX_BAD_PARCELABLE,
- Status::EX_ILLEGAL_ARGUMENT,
- Status::EX_NULL_POINTER,
- Status::EX_ILLEGAL_STATE,
- Status::EX_NETWORK_MAIN_THREAD,
- Status::EX_UNSUPPORTED_OPERATION,
- //Status::EX_SERVICE_SPECIFIC, -- tested fromServiceSpecificError()
- Status::EX_PARCELABLE,
- // This is special and Java specific; see Parcel.java.
- Status::EX_HAS_REPLY_HEADER,
- // This is special, and indicates to C++ binder proxies that the
- // transaction has failed at a low level.
- //Status::EX_TRANSACTION_FAILED, -- tested fromStatusT().
- }) {
+ // Status::EX_NONE,
+ Status::EX_SECURITY, Status::EX_BAD_PARCELABLE, Status::EX_ILLEGAL_ARGUMENT,
+ Status::EX_NULL_POINTER, Status::EX_ILLEGAL_STATE, Status::EX_NETWORK_MAIN_THREAD,
+ Status::EX_UNSUPPORTED_OPERATION,
+ // Status::EX_SERVICE_SPECIFIC, -- tested fromServiceSpecificError()
+ Status::EX_PARCELABLE,
+ // This is special and Java specific; see Parcel.java.
+ Status::EX_HAS_REPLY_HEADER,
+ // This is special, and indicates to C++ binder proxies that the
+ // transaction has failed at a low level.
+ // Status::EX_TRANSACTION_FAILED, -- tested fromStatusT().
+ }) {
ASSERT_NE(OK, statusTFromBinderStatus(Status::fromExceptionCode(exceptionCode)));
}
}
// Binder transaction errors show exactly in status_t; these come fromStatusT().
TEST(audio_aidl_status_tests, binderStatusTransactionError) {
- for (status_t status : {
- OK, // Note: fromStatusT does check if this is 0, so this is no error.
- UNKNOWN_ERROR,
- NO_MEMORY,
- INVALID_OPERATION,
- BAD_VALUE,
- BAD_TYPE,
- NAME_NOT_FOUND,
- PERMISSION_DENIED,
- NO_INIT,
- ALREADY_EXISTS,
- DEAD_OBJECT,
- FAILED_TRANSACTION,
- BAD_INDEX,
- NOT_ENOUGH_DATA,
- WOULD_BLOCK,
- TIMED_OUT,
- UNKNOWN_TRANSACTION,
- FDS_NOT_ALLOWED}) {
+ for (status_t status :
+ {OK, // Note: fromStatusT does check if this is 0, so this is no error.
+ UNKNOWN_ERROR, NO_MEMORY, INVALID_OPERATION, BAD_VALUE, BAD_TYPE, NAME_NOT_FOUND,
+ PERMISSION_DENIED, NO_INIT, ALREADY_EXISTS, DEAD_OBJECT, FAILED_TRANSACTION, BAD_INDEX,
+ NOT_ENOUGH_DATA, WOULD_BLOCK, TIMED_OUT, UNKNOWN_TRANSACTION, FDS_NOT_ALLOWED}) {
ASSERT_EQ(status, statusTFromBinderStatus(Status::fromStatusT(status)));
}
}
diff --git a/media/libaudioclient/tests/audio_test_template.xml b/media/libaudioclient/tests/audio_test_template.xml
new file mode 100644
index 0000000..ed0cb21
--- /dev/null
+++ b/media/libaudioclient/tests/audio_test_template.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2022 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.
+-->
+<configuration description="Unit test configuration for {MODULE}">
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push-file" key="{MODULE}" value="/data/local/tmp/{MODULE}" />
+
+ <!-- Files used for audio testing -->
+ <option name="push-file" key="bbb_1ch_8kHz_s16le.raw" value="/data/local/tmp/bbb_1ch_8kHz_s16le.raw" />
+ <option name="push-file" key="bbb_2ch_24kHz_s16le.raw" value="/data/local/tmp/bbb_2ch_24kHz_s16le.raw" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="{MODULE}" />
+ </test>
+</configuration>
diff --git a/media/libaudioclient/tests/audio_test_utils.cpp b/media/libaudioclient/tests/audio_test_utils.cpp
new file mode 100644
index 0000000..1e26ff6
--- /dev/null
+++ b/media/libaudioclient/tests/audio_test_utils.cpp
@@ -0,0 +1,910 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "AudioTestUtils"
+
+#include <android-base/file.h>
+#include <system/audio_config.h>
+#include <utils/Log.h>
+
+#include "audio_test_utils.h"
+
+#define WAIT_PERIOD_MS 10 // from AudioTrack.cpp
+#define MAX_WAIT_TIME_MS 5000
+
+template <class T>
+constexpr void (*xmlDeleter)(T* t);
+template <>
+constexpr auto xmlDeleter<xmlDoc> = xmlFreeDoc;
+template <>
+constexpr auto xmlDeleter<xmlChar> = [](xmlChar* s) { xmlFree(s); };
+
+/** @return a unique_ptr with the correct deleter for the libxml2 object. */
+template <class T>
+constexpr auto make_xmlUnique(T* t) {
+ // Wrap deleter in lambda to enable empty base optimization
+ auto deleter = [](T* t) { xmlDeleter<T>(t); };
+ return std::unique_ptr<T, decltype(deleter)>{t, deleter};
+}
+
+void OnAudioDeviceUpdateNotifier::onAudioDeviceUpdate(audio_io_handle_t audioIo,
+ audio_port_handle_t deviceId) {
+ std::unique_lock<std::mutex> lock{mMutex};
+ ALOGD("%s audioIo=%d deviceId=%d", __func__, audioIo, deviceId);
+ mAudioIo = audioIo;
+ mDeviceId = deviceId;
+ mCondition.notify_all();
+}
+
+status_t OnAudioDeviceUpdateNotifier::waitForAudioDeviceCb(audio_port_handle_t expDeviceId) {
+ std::unique_lock<std::mutex> lock{mMutex};
+ if (mAudioIo == AUDIO_IO_HANDLE_NONE ||
+ (expDeviceId != AUDIO_PORT_HANDLE_NONE && expDeviceId != mDeviceId)) {
+ mCondition.wait_for(lock, std::chrono::milliseconds(500));
+ if (mAudioIo == AUDIO_IO_HANDLE_NONE ||
+ (expDeviceId != AUDIO_PORT_HANDLE_NONE && expDeviceId != mDeviceId))
+ return TIMED_OUT;
+ }
+ return OK;
+}
+
+AudioPlayback::AudioPlayback(uint32_t sampleRate, audio_format_t format,
+ audio_channel_mask_t channelMask, audio_output_flags_t flags,
+ audio_session_t sessionId, AudioTrack::transfer_type transferType,
+ audio_attributes_t* attributes, audio_offload_info_t* info)
+ : mSampleRate(sampleRate),
+ mFormat(format),
+ mChannelMask(channelMask),
+ mFlags(flags),
+ mSessionId(sessionId),
+ mTransferType(transferType),
+ mAttributes(attributes),
+ mOffloadInfo(info) {
+ mStopPlaying = false;
+ mBytesUsedSoFar = 0;
+ mState = PLAY_NO_INIT;
+ mMemCapacity = 0;
+ mMemoryDealer = nullptr;
+ mMemory = nullptr;
+}
+
+AudioPlayback::~AudioPlayback() {
+ stop();
+}
+
+status_t AudioPlayback::create() {
+ if (mState != PLAY_NO_INIT) return INVALID_OPERATION;
+ std::string packageName{"AudioPlayback"};
+ AttributionSourceState attributionSource;
+ attributionSource.packageName = packageName;
+ attributionSource.uid = VALUE_OR_FATAL(legacy2aidl_uid_t_int32_t(getuid()));
+ attributionSource.pid = VALUE_OR_FATAL(legacy2aidl_pid_t_int32_t(getpid()));
+ attributionSource.token = sp<BBinder>::make();
+ if (mTransferType == AudioTrack::TRANSFER_OBTAIN) {
+ mTrack = new AudioTrack(attributionSource);
+ mTrack->set(AUDIO_STREAM_MUSIC, mSampleRate, mFormat, mChannelMask, 0 /* frameCount */,
+ mFlags, nullptr /* callback */, 0 /* notificationFrames */,
+ nullptr /* sharedBuffer */, false /*canCallJava */, mSessionId, mTransferType,
+ mOffloadInfo, attributionSource, mAttributes);
+ } else if (mTransferType == AudioTrack::TRANSFER_SHARED) {
+ mTrack = new AudioTrack(AUDIO_STREAM_MUSIC, mSampleRate, mFormat, mChannelMask, mMemory,
+ mFlags, wp<AudioTrack::IAudioTrackCallback>::fromExisting(this), 0,
+ mSessionId, mTransferType, nullptr, attributionSource, mAttributes);
+ } else {
+ ALOGE("Test application is not handling transfer type %s",
+ AudioTrack::convertTransferToText(mTransferType));
+ return INVALID_OPERATION;
+ }
+ mTrack->setCallerName(packageName);
+ status_t status = mTrack->initCheck();
+ if (NO_ERROR == status) mState = PLAY_READY;
+ return status;
+}
+
+status_t AudioPlayback::loadResource(const char* name) {
+ status_t status = OK;
+ FILE* fp = fopen(name, "rbe");
+ struct stat buf {};
+ if (fp && !fstat(fileno(fp), &buf)) {
+ mMemCapacity = buf.st_size;
+ mMemoryDealer = new MemoryDealer(mMemCapacity, "AudioPlayback");
+ if (nullptr == mMemoryDealer.get()) {
+ ALOGE("couldn't get MemoryDealer!");
+ fclose(fp);
+ return NO_MEMORY;
+ }
+ mMemory = mMemoryDealer->allocate(mMemCapacity);
+ if (nullptr == mMemory.get()) {
+ ALOGE("couldn't get IMemory!");
+ fclose(fp);
+ return NO_MEMORY;
+ }
+ uint8_t* ipBuffer = static_cast<uint8_t*>(static_cast<void*>(mMemory->unsecurePointer()));
+ fread(ipBuffer, sizeof(uint8_t), mMemCapacity, fp);
+ } else {
+ ALOGE("unable to open input file %s", name);
+ status = NAME_NOT_FOUND;
+ }
+ if (fp) fclose(fp);
+ return status;
+}
+
+sp<AudioTrack> AudioPlayback::getAudioTrackHandle() {
+ return (PLAY_NO_INIT != mState) ? mTrack : nullptr;
+}
+
+status_t AudioPlayback::start() {
+ status_t status;
+ if (PLAY_READY != mState) {
+ return INVALID_OPERATION;
+ } else {
+ status = mTrack->start();
+ if (OK == status) {
+ mState = PLAY_STARTED;
+ LOG_FATAL_IF(false != mTrack->stopped());
+ }
+ }
+ return status;
+}
+
+void AudioPlayback::onBufferEnd() {
+ std::unique_lock<std::mutex> lock{mMutex};
+ mStopPlaying = true;
+ mCondition.notify_all();
+}
+
+status_t AudioPlayback::fillBuffer() {
+ if (PLAY_STARTED != mState) return INVALID_OPERATION;
+ const int maxTries = MAX_WAIT_TIME_MS / WAIT_PERIOD_MS;
+ int counter = 0;
+ uint8_t* ipBuffer = static_cast<uint8_t*>(static_cast<void*>(mMemory->unsecurePointer()));
+ size_t nonContig = 0;
+ size_t bytesAvailable = mMemCapacity - mBytesUsedSoFar;
+ while (bytesAvailable > 0) {
+ AudioTrack::Buffer trackBuffer;
+ trackBuffer.frameCount = mTrack->frameCount() * 2;
+ status_t status = mTrack->obtainBuffer(&trackBuffer, 1, &nonContig);
+ if (OK == status) {
+ size_t bytesToCopy = std::min(bytesAvailable, trackBuffer.size());
+ if (bytesToCopy > 0) {
+ memcpy(trackBuffer.data(), ipBuffer + mBytesUsedSoFar, bytesToCopy);
+ }
+ mTrack->releaseBuffer(&trackBuffer);
+ mBytesUsedSoFar += bytesToCopy;
+ bytesAvailable = mMemCapacity - mBytesUsedSoFar;
+ counter = 0;
+ } else if (WOULD_BLOCK == status) {
+ // if not received a buffer for MAX_WAIT_TIME_MS, something has gone wrong
+ if (counter == maxTries) return TIMED_OUT;
+ counter++;
+ }
+ }
+ return OK;
+}
+
+status_t AudioPlayback::waitForConsumption(bool testSeek) {
+ if (PLAY_STARTED != mState) return INVALID_OPERATION;
+
+ const int maxTries = MAX_WAIT_TIME_MS / WAIT_PERIOD_MS;
+ int counter = 0;
+ size_t totalFrameCount = mMemCapacity / mTrack->frameSize();
+ while (!mStopPlaying && counter < maxTries) {
+ uint32_t currPosition;
+ mTrack->getPosition(&currPosition);
+ if (currPosition >= totalFrameCount) counter++;
+
+ if (testSeek && (currPosition > totalFrameCount * 0.6)) {
+ testSeek = false;
+ if (!mTrack->hasStarted()) return BAD_VALUE;
+ mTrack->pauseAndWait(std::chrono::seconds(2));
+ if (mTrack->hasStarted()) return BAD_VALUE;
+ mTrack->reload();
+ mTrack->getPosition(&currPosition);
+ if (currPosition != 0) return BAD_VALUE;
+ mTrack->start();
+ while (currPosition < totalFrameCount * 0.3) {
+ mTrack->getPosition(&currPosition);
+ }
+ mTrack->pauseAndWait(std::chrono::seconds(2));
+ uint32_t setPosition = totalFrameCount * 0.9;
+ mTrack->setPosition(setPosition);
+ uint32_t bufferPosition;
+ mTrack->getBufferPosition(&bufferPosition);
+ if (bufferPosition != setPosition) return BAD_VALUE;
+ mTrack->start();
+ }
+ std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_PERIOD_MS));
+ }
+ if (!mStopPlaying && counter == maxTries) return TIMED_OUT;
+ return OK;
+}
+
+status_t AudioPlayback::onProcess(bool testSeek) {
+ if (mTransferType == AudioTrack::TRANSFER_SHARED)
+ return waitForConsumption(testSeek);
+ else if (mTransferType == AudioTrack::TRANSFER_OBTAIN)
+ return fillBuffer();
+ else
+ return INVALID_OPERATION;
+}
+
+void AudioPlayback::stop() {
+ std::unique_lock<std::mutex> lock{mMutex};
+ mStopPlaying = true;
+ if (mState != PLAY_STOPPED && mState != PLAY_NO_INIT) {
+ int32_t msec = 0;
+ (void)mTrack->pendingDuration(&msec);
+ mTrack->stopAndJoinCallbacks();
+ LOG_FATAL_IF(true != mTrack->stopped());
+ mState = PLAY_STOPPED;
+ if (msec > 0) {
+ ALOGD("deleting recycled track, waiting for data drain (%d msec)", msec);
+ usleep(msec * 1000LL);
+ }
+ }
+}
+
+// hold pcm data sent by AudioRecord
+RawBuffer::RawBuffer(int64_t ptsPipeline, int64_t ptsManual, int32_t capacity)
+ : mData(capacity > 0 ? new uint8_t[capacity] : nullptr),
+ mPtsPipeline(ptsPipeline),
+ mPtsManual(ptsManual),
+ mCapacity(capacity) {}
+
+// Simple AudioCapture
+size_t AudioCapture::onMoreData(const AudioRecord::Buffer& buffer) {
+ if (mState != REC_STARTED) {
+ ALOGE("Unexpected Callback from audiorecord, not reading data");
+ return 0;
+ }
+
+ // no more frames to read
+ if (mNumFramesReceived >= mNumFramesToRecord || mStopRecording) {
+ mStopRecording = true;
+ return 0;
+ }
+
+ int64_t timeUs = 0, position = 0, timeNs = 0;
+ ExtendedTimestamp ts;
+ ExtendedTimestamp::Location location;
+ const int32_t usPerSec = 1000000;
+
+ if (mRecord->getTimestamp(&ts) == OK &&
+ ts.getBestTimestamp(&position, &timeNs, ExtendedTimestamp::TIMEBASE_MONOTONIC, &location) ==
+ OK) {
+ // Use audio timestamp.
+ timeUs = timeNs / 1000 -
+ (position - mNumFramesReceived + mNumFramesLost) * usPerSec / mSampleRate;
+ } else {
+ // This should not happen in normal case.
+ ALOGW("Failed to get audio timestamp, fallback to use systemclock");
+ 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.)
+ timeUs -= mRecord->latency() * 1000LL;
+ }
+
+ ALOGV("dataCallbackTimestamp: %" PRId64 " us", timeUs);
+
+ const size_t frameSize = mRecord->frameSize();
+ uint64_t numLostBytes = (uint64_t)mRecord->getInputFramesLost() * frameSize;
+ if (numLostBytes > 0) {
+ ALOGW("Lost audio record data: %" PRIu64 " bytes", numLostBytes);
+ }
+ std::deque<RawBuffer> tmpQueue;
+ while (numLostBytes > 0) {
+ uint64_t bufferSize = numLostBytes;
+ if (numLostBytes > mMaxBytesPerCallback) {
+ numLostBytes -= mMaxBytesPerCallback;
+ bufferSize = mMaxBytesPerCallback;
+ } else {
+ numLostBytes = 0;
+ }
+ const int64_t timestampUs =
+ ((1000000LL * mNumFramesReceived) + (mRecord->getSampleRate() >> 1)) /
+ mRecord->getSampleRate();
+ RawBuffer emptyBuffer{timeUs, timestampUs, static_cast<int32_t>(bufferSize)};
+ memset(emptyBuffer.mData.get(), 0, bufferSize);
+ mNumFramesLost += bufferSize / frameSize;
+ mNumFramesReceived += bufferSize / frameSize;
+ tmpQueue.push_back(std::move(emptyBuffer));
+ }
+
+ if (buffer.size() == 0) {
+ ALOGW("Nothing is available from AudioRecord callback buffer");
+ } else {
+ const size_t bufferSize = buffer.size();
+ const int64_t timestampUs =
+ ((1000000LL * mNumFramesReceived) + (mRecord->getSampleRate() >> 1)) /
+ mRecord->getSampleRate();
+ RawBuffer audioBuffer{timeUs, timestampUs, static_cast<int32_t>(bufferSize)};
+ memcpy(audioBuffer.mData.get(), buffer.data(), bufferSize);
+ mNumFramesReceived += bufferSize / frameSize;
+ tmpQueue.push_back(std::move(audioBuffer));
+ }
+
+ if (tmpQueue.size() > 0) {
+ std::unique_lock<std::mutex> lock{mMutex};
+ for (auto it = tmpQueue.begin(); it != tmpQueue.end(); it++)
+ mBuffersReceived.push_back(std::move(*it));
+ mCondition.notify_all();
+ }
+ return buffer.size();
+}
+
+void AudioCapture::onOverrun() {
+ ALOGV("received event overrun");
+ mBufferOverrun = true;
+}
+
+void AudioCapture::onMarker(uint32_t markerPosition) {
+ ALOGV("received Callback at position %d", markerPosition);
+ mReceivedCbMarkerAtPosition = markerPosition;
+}
+
+void AudioCapture::onNewPos(uint32_t markerPosition) {
+ ALOGV("received Callback at position %d", markerPosition);
+ mReceivedCbMarkerCount++;
+}
+
+void AudioCapture::onNewIAudioRecord() {
+ ALOGV("IAudioRecord is re-created");
+}
+
+AudioCapture::AudioCapture(audio_source_t inputSource, uint32_t sampleRate, audio_format_t format,
+ audio_channel_mask_t channelMask, audio_input_flags_t flags,
+ audio_session_t sessionId, AudioRecord::transfer_type transferType,
+ const audio_attributes_t* attributes)
+ : mInputSource(inputSource),
+ mSampleRate(sampleRate),
+ mFormat(format),
+ mChannelMask(channelMask),
+ mFlags(flags),
+ mSessionId(sessionId),
+ mTransferType(transferType),
+ mAttributes(attributes) {
+ mFrameCount = 0;
+ mNotificationFrames = 0;
+ mNumFramesToRecord = 0;
+ mNumFramesReceived = 0;
+ mNumFramesLost = 0;
+ mBufferOverrun = false;
+ mMarkerPosition = 0;
+ mMarkerPeriod = 0;
+ mReceivedCbMarkerAtPosition = -1;
+ mReceivedCbMarkerCount = 0;
+ mState = REC_NO_INIT;
+ mStopRecording = false;
+}
+
+AudioCapture::~AudioCapture() {
+ if (mOutFileFd > 0) close(mOutFileFd);
+ stop();
+}
+
+status_t AudioCapture::create() {
+ if (mState != REC_NO_INIT) return INVALID_OPERATION;
+ // get Min Frame Count
+ size_t minFrameCount;
+ status_t status =
+ AudioRecord::getMinFrameCount(&minFrameCount, mSampleRate, mFormat, mChannelMask);
+ if (NO_ERROR != status) return status;
+ // Limit notificationFrames basing on client bufferSize
+ const int samplesPerFrame = audio_channel_count_from_in_mask(mChannelMask);
+ const int bytesPerSample = audio_bytes_per_sample(mFormat);
+ mNotificationFrames = mMaxBytesPerCallback / (samplesPerFrame * bytesPerSample);
+ // select frameCount to be at least minFrameCount
+ mFrameCount = 2 * mNotificationFrames;
+ while (mFrameCount < minFrameCount) {
+ mFrameCount += mNotificationFrames;
+ }
+ if (mFlags & AUDIO_INPUT_FLAG_FAST) {
+ ALOGW("Overriding all previous computations");
+ mFrameCount = 0;
+ mNotificationFrames = 0;
+ }
+ mNumFramesToRecord = (mSampleRate * 0.25); // record .25 sec
+ std::string packageName{"AudioCapture"};
+ AttributionSourceState attributionSource;
+ attributionSource.packageName = packageName;
+ attributionSource.uid = VALUE_OR_FATAL(legacy2aidl_uid_t_int32_t(getuid()));
+ attributionSource.pid = VALUE_OR_FATAL(legacy2aidl_pid_t_int32_t(getpid()));
+ attributionSource.token = sp<BBinder>::make();
+ if (mTransferType == AudioRecord::TRANSFER_OBTAIN) {
+ if (mSampleRate == 48000) { // test all available constructors
+ mRecord = new AudioRecord(mInputSource, mSampleRate, mFormat, mChannelMask,
+ attributionSource, mFrameCount, nullptr /* callback */,
+ mNotificationFrames, mSessionId, mTransferType, mFlags,
+ mAttributes);
+ } else {
+ mRecord = new AudioRecord(attributionSource);
+ status = mRecord->set(mInputSource, mSampleRate, mFormat, mChannelMask, mFrameCount,
+ nullptr /* callback */, 0 /* notificationFrames */,
+ false /* canCallJava */, mSessionId, mTransferType, mFlags,
+ attributionSource.uid, attributionSource.pid, mAttributes);
+ }
+ if (NO_ERROR != status) return status;
+ } else if (mTransferType == AudioRecord::TRANSFER_CALLBACK) {
+ mRecord = new AudioRecord(mInputSource, mSampleRate, mFormat, mChannelMask,
+ attributionSource, mFrameCount, this, mNotificationFrames,
+ mSessionId, mTransferType, mFlags, mAttributes);
+ } else {
+ ALOGE("Test application is not handling transfer type %s",
+ AudioRecord::convertTransferToText(mTransferType));
+ return NO_INIT;
+ }
+ mRecord->setCallerName(packageName);
+ status = mRecord->initCheck();
+ if (NO_ERROR == status) mState = REC_READY;
+ if (mFlags & AUDIO_INPUT_FLAG_FAST) {
+ mFrameCount = mRecord->frameCount();
+ mNotificationFrames = mRecord->getNotificationPeriodInFrames();
+ mMaxBytesPerCallback = mNotificationFrames * samplesPerFrame * bytesPerSample;
+ }
+ return status;
+}
+
+status_t AudioCapture::setRecordDuration(float durationInSec) {
+ if (REC_READY != mState) {
+ return INVALID_OPERATION;
+ }
+ uint32_t sampleRate = mSampleRate == 0 ? mRecord->getSampleRate() : mSampleRate;
+ mNumFramesToRecord = (sampleRate * durationInSec);
+ return OK;
+}
+
+status_t AudioCapture::enableRecordDump() {
+ if (mOutFileFd != -1) {
+ return INVALID_OPERATION;
+ }
+ TemporaryFile tf("/data/local/tmp");
+ tf.DoNotRemove();
+ mOutFileFd = tf.release();
+ mFileName = std::string{tf.path};
+ return OK;
+}
+
+sp<AudioRecord> AudioCapture::getAudioRecordHandle() {
+ return (REC_NO_INIT == mState) ? nullptr : mRecord;
+}
+
+status_t AudioCapture::start(AudioSystem::sync_event_t event, audio_session_t triggerSession) {
+ status_t status;
+ if (REC_READY != mState) {
+ return INVALID_OPERATION;
+ } else {
+ status = mRecord->start(event, triggerSession);
+ if (OK == status) {
+ mState = REC_STARTED;
+ LOG_FATAL_IF(false != mRecord->stopped());
+ }
+ }
+ return status;
+}
+
+status_t AudioCapture::stop() {
+ status_t status = OK;
+ mStopRecording = true;
+ if (mState != REC_STOPPED && mState != REC_NO_INIT) {
+ if (mInputSource != AUDIO_SOURCE_DEFAULT) {
+ bool state = false;
+ status = AudioSystem::isSourceActive(mInputSource, &state);
+ if (status == OK && !state) status = BAD_VALUE;
+ }
+ mRecord->stopAndJoinCallbacks();
+ mState = REC_STOPPED;
+ LOG_FATAL_IF(true != mRecord->stopped());
+ }
+ return status;
+}
+
+status_t AudioCapture::obtainBuffer(RawBuffer& buffer) {
+ if (REC_STARTED != mState) return INVALID_OPERATION;
+ const int maxTries = MAX_WAIT_TIME_MS / WAIT_PERIOD_MS;
+ int counter = 0;
+ size_t nonContig = 0;
+ while (mNumFramesReceived < mNumFramesToRecord) {
+ AudioRecord::Buffer recordBuffer;
+ recordBuffer.frameCount = mNotificationFrames;
+ status_t status = mRecord->obtainBuffer(&recordBuffer, 1, &nonContig);
+ if (OK == status) {
+ const int64_t timestampUs =
+ ((1000000LL * mNumFramesReceived) + (mRecord->getSampleRate() >> 1)) /
+ mRecord->getSampleRate();
+ RawBuffer buff{-1, timestampUs, static_cast<int32_t>(recordBuffer.size())};
+ memcpy(buff.mData.get(), recordBuffer.data(), recordBuffer.size());
+ buffer = std::move(buff);
+ mNumFramesReceived += recordBuffer.size() / mRecord->frameSize();
+ mRecord->releaseBuffer(&recordBuffer);
+ counter = 0;
+ } else if (WOULD_BLOCK == status) {
+ // if not received a buffer for MAX_WAIT_TIME_MS, something has gone wrong
+ if (counter == maxTries) return TIMED_OUT;
+ counter++;
+ }
+ }
+ return OK;
+}
+
+status_t AudioCapture::obtainBufferCb(RawBuffer& buffer) {
+ if (REC_STARTED != mState) return INVALID_OPERATION;
+ const int maxTries = MAX_WAIT_TIME_MS / WAIT_PERIOD_MS;
+ int counter = 0;
+ std::unique_lock<std::mutex> lock{mMutex};
+ while (mBuffersReceived.empty() && !mStopRecording && counter < maxTries) {
+ mCondition.wait_for(lock, std::chrono::milliseconds(WAIT_PERIOD_MS));
+ counter++;
+ }
+ if (!mBuffersReceived.empty()) {
+ auto it = mBuffersReceived.begin();
+ buffer = std::move(*it);
+ mBuffersReceived.erase(it);
+ } else {
+ if (!mStopRecording && counter == maxTries) return TIMED_OUT;
+ }
+ return OK;
+}
+
+status_t AudioCapture::audioProcess() {
+ RawBuffer buffer;
+ status_t status = OK;
+ while (mNumFramesReceived < mNumFramesToRecord && status == OK) {
+ if (mTransferType == AudioRecord::TRANSFER_CALLBACK)
+ status = obtainBufferCb(buffer);
+ else
+ status = obtainBuffer(buffer);
+ if (OK == status && mOutFileFd > 0) {
+ const char* ptr = static_cast<const char*>(static_cast<void*>(buffer.mData.get()));
+ write(mOutFileFd, ptr, buffer.mCapacity);
+ }
+ }
+ return OK;
+}
+
+status_t listAudioPorts(std::vector<audio_port_v7>& portsVec) {
+ int attempts = 5;
+ status_t status;
+ unsigned int generation1, generation;
+ unsigned int numPorts = 0;
+ do {
+ if (attempts-- < 0) {
+ status = TIMED_OUT;
+ break;
+ }
+ status = AudioSystem::listAudioPorts(AUDIO_PORT_ROLE_NONE, AUDIO_PORT_TYPE_NONE, &numPorts,
+ nullptr, &generation1);
+ if (status != NO_ERROR) {
+ ALOGE("AudioSystem::listAudioPorts returned error %d", status);
+ break;
+ }
+ portsVec.resize(numPorts);
+ status = AudioSystem::listAudioPorts(AUDIO_PORT_ROLE_NONE, AUDIO_PORT_TYPE_NONE, &numPorts,
+ portsVec.data(), &generation);
+ } while (generation1 != generation && status == NO_ERROR);
+ if (status != NO_ERROR) {
+ numPorts = 0;
+ portsVec.clear();
+ }
+ return status;
+}
+
+status_t getPortById(const audio_port_handle_t portId, audio_port_v7& port) {
+ std::vector<struct audio_port_v7> ports;
+ status_t status = listAudioPorts(ports);
+ if (status != OK) return status;
+ for (auto i = 0; i < ports.size(); i++) {
+ if (ports[i].id == portId) {
+ port = ports[i];
+ return OK;
+ }
+ }
+ return BAD_VALUE;
+}
+
+status_t getPortByAttributes(audio_port_role_t role, audio_port_type_t type,
+ audio_devices_t deviceType, const std::string& address,
+ audio_port_v7& port) {
+ std::vector<struct audio_port_v7> ports;
+ status_t status = listAudioPorts(ports);
+ if (status != OK) return status;
+ for (auto i = 0; i < ports.size(); i++) {
+ if (ports[i].role == role && ports[i].type == type &&
+ ports[i].ext.device.type == deviceType &&
+ !strncmp(ports[i].ext.device.address, address.c_str(), AUDIO_DEVICE_MAX_ADDRESS_LEN)) {
+ port = ports[i];
+ return OK;
+ }
+ }
+ return BAD_VALUE;
+}
+
+status_t listAudioPatches(std::vector<struct audio_patch>& patchesVec) {
+ int attempts = 5;
+ status_t status;
+ unsigned int generation1, generation;
+ unsigned int numPatches = 0;
+ do {
+ if (attempts-- < 0) {
+ status = TIMED_OUT;
+ break;
+ }
+ status = AudioSystem::listAudioPatches(&numPatches, nullptr, &generation1);
+ if (status != NO_ERROR) {
+ ALOGE("AudioSystem::listAudioPatches returned error %d", status);
+ break;
+ }
+ patchesVec.resize(numPatches);
+ status = AudioSystem::listAudioPatches(&numPatches, patchesVec.data(), &generation);
+ } while (generation1 != generation && status == NO_ERROR);
+ if (status != NO_ERROR) {
+ numPatches = 0;
+ patchesVec.clear();
+ }
+ return status;
+}
+
+status_t getPatchForOutputMix(audio_io_handle_t audioIo, audio_patch& patch) {
+ std::vector<struct audio_patch> patches;
+ status_t status = listAudioPatches(patches);
+ if (status != OK) return status;
+
+ for (auto i = 0; i < patches.size(); i++) {
+ for (auto j = 0; j < patches[i].num_sources; j++) {
+ if (patches[i].sources[j].type == AUDIO_PORT_TYPE_MIX &&
+ patches[i].sources[j].ext.mix.handle == audioIo) {
+ patch = patches[i];
+ return OK;
+ }
+ }
+ }
+ return BAD_VALUE;
+}
+
+status_t getPatchForInputMix(audio_io_handle_t audioIo, audio_patch& patch) {
+ std::vector<struct audio_patch> patches;
+ status_t status = listAudioPatches(patches);
+ if (status != OK) return status;
+
+ for (auto i = 0; i < patches.size(); i++) {
+ for (auto j = 0; j < patches[i].num_sinks; j++) {
+ if (patches[i].sinks[j].type == AUDIO_PORT_TYPE_MIX &&
+ patches[i].sinks[j].ext.mix.handle == audioIo) {
+ patch = patches[i];
+ return OK;
+ }
+ }
+ }
+ return BAD_VALUE;
+}
+
+bool patchContainsOutputDevice(audio_port_handle_t deviceId, audio_patch patch) {
+ for (auto j = 0; j < patch.num_sinks; j++) {
+ if (patch.sinks[j].type == AUDIO_PORT_TYPE_DEVICE && patch.sinks[j].id == deviceId) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool patchContainsInputDevice(audio_port_handle_t deviceId, audio_patch patch) {
+ for (auto j = 0; j < patch.num_sources; j++) {
+ if (patch.sources[j].type == AUDIO_PORT_TYPE_DEVICE && patch.sources[j].id == deviceId) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool checkPatchPlayback(audio_io_handle_t audioIo, audio_port_handle_t deviceId) {
+ struct audio_patch patch;
+ if (getPatchForOutputMix(audioIo, patch) == OK) {
+ return patchContainsOutputDevice(deviceId, patch);
+ }
+ return false;
+}
+
+bool checkPatchCapture(audio_io_handle_t audioIo, audio_port_handle_t deviceId) {
+ struct audio_patch patch;
+ if (getPatchForInputMix(audioIo, patch) == OK) {
+ return patchContainsInputDevice(deviceId, patch);
+ }
+ return false;
+}
+
+std::string dumpPortConfig(const audio_port_config& port) {
+ std::ostringstream result;
+ std::string deviceInfo;
+ if (port.type == AUDIO_PORT_TYPE_DEVICE) {
+ if (port.ext.device.type & AUDIO_DEVICE_BIT_IN) {
+ InputDeviceConverter::maskToString(port.ext.device.type, deviceInfo);
+ } else {
+ OutputDeviceConverter::maskToString(port.ext.device.type, deviceInfo);
+ }
+ deviceInfo += std::string(", address = ") + port.ext.device.address;
+ }
+ result << "audio_port_handle_t = " << port.id << ", "
+ << "Role = " << (port.role == AUDIO_PORT_ROLE_SOURCE ? "source" : "sink") << ", "
+ << "Type = " << (port.type == AUDIO_PORT_TYPE_DEVICE ? "device" : "mix") << ", "
+ << "deviceInfo = " << (port.type == AUDIO_PORT_TYPE_DEVICE ? deviceInfo : "") << ", "
+ << "config_mask = 0x" << std::hex << port.config_mask << std::dec << ", ";
+ if (port.config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) {
+ result << "sample rate = " << port.sample_rate << ", ";
+ }
+ if (port.config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) {
+ result << "channel mask = " << port.channel_mask << ", ";
+ }
+ if (port.config_mask & AUDIO_PORT_CONFIG_FORMAT) {
+ result << "format = " << port.format << ", ";
+ }
+ result << "input flags = " << port.flags.input << ", ";
+ result << "output flags = " << port.flags.output << ", ";
+ result << "mix io handle = " << (port.type == AUDIO_PORT_TYPE_DEVICE ? 0 : port.ext.mix.handle)
+ << "\n";
+ return result.str();
+}
+
+std::string dumpPatch(const audio_patch& patch) {
+ std::ostringstream result;
+ result << "----------------- Dumping Patch ------------ \n";
+ result << "Patch Handle: " << patch.id << ", sources: " << patch.num_sources
+ << ", sink: " << patch.num_sinks << "\n";
+ audio_port_v7 port;
+ for (uint32_t i = 0; i < patch.num_sources; i++) {
+ result << "----------------- Dumping Source Port Config @ index " << i
+ << " ------------ \n";
+ result << dumpPortConfig(patch.sources[i]);
+ result << "----------------- Dumping Source Port for id " << patch.sources[i].id
+ << " ------------ \n";
+ getPortById(patch.sources[i].id, port);
+ result << dumpPort(port);
+ }
+ for (uint32_t i = 0; i < patch.num_sinks; i++) {
+ result << "----------------- Dumping Sink Port Config @ index " << i << " ------------ \n";
+ result << dumpPortConfig(patch.sinks[i]);
+ result << "----------------- Dumping Sink Port for id " << patch.sinks[i].id
+ << " ------------ \n";
+ getPortById(patch.sinks[i].id, port);
+ result << dumpPort(port);
+ }
+ return result.str();
+}
+
+std::string dumpPort(const audio_port_v7& port) {
+ std::ostringstream result;
+ std::string deviceInfo;
+ if (port.type == AUDIO_PORT_TYPE_DEVICE) {
+ if (port.ext.device.type & AUDIO_DEVICE_BIT_IN) {
+ InputDeviceConverter::maskToString(port.ext.device.type, deviceInfo);
+ } else {
+ OutputDeviceConverter::maskToString(port.ext.device.type, deviceInfo);
+ }
+ deviceInfo += std::string(", address = ") + port.ext.device.address;
+ }
+ result << "audio_port_handle_t = " << port.id << ", "
+ << "Role = " << (port.role == AUDIO_PORT_ROLE_SOURCE ? "source" : "sink") << ", "
+ << "Type = " << (port.type == AUDIO_PORT_TYPE_DEVICE ? "device" : "mix") << ", "
+ << "deviceInfo = " << (port.type == AUDIO_PORT_TYPE_DEVICE ? deviceInfo : "") << ", "
+ << "Name = " << port.name << ", "
+ << "num profiles = " << port.num_audio_profiles << ", "
+ << "mix io handle = " << (port.type == AUDIO_PORT_TYPE_DEVICE ? 0 : port.ext.mix.handle)
+ << ", ";
+ for (int i = 0; i < port.num_audio_profiles; i++) {
+ result << "AudioProfile = " << i << " {";
+ result << "format = " << port.audio_profiles[i].format << ", ";
+ result << "samplerates = ";
+ for (int j = 0; j < port.audio_profiles[i].num_sample_rates; j++) {
+ result << port.audio_profiles[i].sample_rates[j] << ", ";
+ }
+ result << "channelmasks = ";
+ for (int j = 0; j < port.audio_profiles[i].num_channel_masks; j++) {
+ result << "0x" << std::hex << port.audio_profiles[i].channel_masks[j] << std::dec
+ << ", ";
+ }
+ result << "} ";
+ }
+ result << dumpPortConfig(port.active_config);
+ return result.str();
+}
+
+std::string getXmlAttribute(const xmlNode* cur, const char* attribute) {
+ auto charPtr = make_xmlUnique(xmlGetProp(cur, reinterpret_cast<const xmlChar*>(attribute)));
+ if (charPtr == NULL) {
+ return "";
+ }
+ std::string value(reinterpret_cast<const char*>(charPtr.get()));
+ return value;
+}
+
+status_t parse_audio_policy_configuration_xml(std::vector<std::string>& attachedDevices,
+ std::vector<MixPort>& mixPorts,
+ std::vector<Route>& routes) {
+ std::string path = audio_find_readable_configuration_file("audio_policy_configuration.xml");
+ if (path.length() == 0) return UNKNOWN_ERROR;
+ auto doc = make_xmlUnique(xmlParseFile(path.c_str()));
+ if (doc == nullptr) return UNKNOWN_ERROR;
+ xmlNode* root = xmlDocGetRootElement(doc.get());
+ if (root == nullptr) return UNKNOWN_ERROR;
+ if (xmlXIncludeProcess(doc.get()) < 0) return UNKNOWN_ERROR;
+ mixPorts.clear();
+ if (!xmlStrcmp(root->name, reinterpret_cast<const xmlChar*>("audioPolicyConfiguration"))) {
+ std::string raw{getXmlAttribute(root, "version")};
+ for (auto* child = root->xmlChildrenNode; child != nullptr; child = child->next) {
+ if (!xmlStrcmp(child->name, reinterpret_cast<const xmlChar*>("modules"))) {
+ xmlNode* root = child;
+ for (auto* child = root->xmlChildrenNode; child != nullptr; child = child->next) {
+ if (!xmlStrcmp(child->name, reinterpret_cast<const xmlChar*>("module"))) {
+ xmlNode* root = child;
+ for (auto* child = root->xmlChildrenNode; child != nullptr;
+ child = child->next) {
+ if (!xmlStrcmp(child->name,
+ reinterpret_cast<const xmlChar*>("mixPorts"))) {
+ xmlNode* root = child;
+ for (auto* child = root->xmlChildrenNode; child != nullptr;
+ child = child->next) {
+ if (!xmlStrcmp(child->name,
+ reinterpret_cast<const xmlChar*>("mixPort"))) {
+ MixPort mixPort;
+ xmlNode* root = child;
+ mixPort.name = getXmlAttribute(root, "name");
+ mixPort.role = getXmlAttribute(root, "role");
+ mixPort.flags = getXmlAttribute(root, "flags");
+ if (mixPort.role == "source") mixPorts.push_back(mixPort);
+ }
+ }
+ } else if (!xmlStrcmp(child->name, reinterpret_cast<const xmlChar*>(
+ "attachedDevices"))) {
+ xmlNode* root = child;
+ for (auto* child = root->xmlChildrenNode; child != nullptr;
+ child = child->next) {
+ if (!xmlStrcmp(child->name,
+ reinterpret_cast<const xmlChar*>("item"))) {
+ auto xmlValue = make_xmlUnique(xmlNodeListGetString(
+ child->doc, child->xmlChildrenNode, 1));
+ if (xmlValue == nullptr) {
+ raw = "";
+ } else {
+ raw = reinterpret_cast<const char*>(xmlValue.get());
+ }
+ std::string& value = raw;
+ attachedDevices.push_back(std::move(value));
+ }
+ }
+ } else if (!xmlStrcmp(child->name,
+ reinterpret_cast<const xmlChar*>("routes"))) {
+ xmlNode* root = child;
+ for (auto* child = root->xmlChildrenNode; child != nullptr;
+ child = child->next) {
+ if (!xmlStrcmp(child->name,
+ reinterpret_cast<const xmlChar*>("route"))) {
+ Route route;
+ xmlNode* root = child;
+ route.name = getXmlAttribute(root, "name");
+ route.sources = getXmlAttribute(root, "sources");
+ route.sink = getXmlAttribute(root, "sink");
+ routes.push_back(route);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return OK;
+}
diff --git a/media/libaudioclient/tests/audio_test_utils.h b/media/libaudioclient/tests/audio_test_utils.h
new file mode 100644
index 0000000..90c30c2
--- /dev/null
+++ b/media/libaudioclient/tests/audio_test_utils.h
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef AUDIO_TEST_UTILS_H_
+#define AUDIO_TEST_UTILS_H_
+
+#include <sys/stat.h>
+#include <unistd.h>
+#include <atomic>
+#include <chrono>
+#include <cinttypes>
+#include <deque>
+#include <memory>
+#include <mutex>
+#include <thread>
+
+#include <binder/MemoryDealer.h>
+#include <libxml/parser.h>
+#include <libxml/xinclude.h>
+#include <media/AidlConversion.h>
+#include <media/AudioRecord.h>
+#include <media/AudioTrack.h>
+
+using namespace android;
+
+struct MixPort {
+ std::string name;
+ std::string role;
+ std::string flags;
+};
+
+struct Route {
+ std::string name;
+ std::string sources;
+ std::string sink;
+};
+
+status_t parse_audio_policy_configuration_xml(std::vector<std::string>& attachedDevices,
+ std::vector<MixPort>& mixPorts,
+ std::vector<Route>& routes);
+status_t listAudioPorts(std::vector<audio_port_v7>& portsVec);
+status_t listAudioPatches(std::vector<struct audio_patch>& patchesVec);
+status_t getPortByAttributes(audio_port_role_t role, audio_port_type_t type,
+ audio_devices_t deviceType, const std::string& address,
+ audio_port_v7& port);
+status_t getPatchForOutputMix(audio_io_handle_t audioIo, audio_patch& patch);
+status_t getPatchForInputMix(audio_io_handle_t audioIo, audio_patch& patch);
+bool patchContainsOutputDevice(audio_port_handle_t deviceId, audio_patch patch);
+bool patchContainsInputDevice(audio_port_handle_t deviceId, audio_patch patch);
+bool checkPatchPlayback(audio_io_handle_t audioIo, audio_port_handle_t deviceId);
+bool checkPatchCapture(audio_io_handle_t audioIo, audio_port_handle_t deviceId);
+std::string dumpPort(const audio_port_v7& port);
+std::string dumpPortConfig(const audio_port_config& port);
+std::string dumpPatch(const audio_patch& patch);
+
+class OnAudioDeviceUpdateNotifier : public AudioSystem::AudioDeviceCallback {
+ public:
+ audio_io_handle_t mAudioIo = AUDIO_IO_HANDLE_NONE;
+ audio_port_handle_t mDeviceId = AUDIO_PORT_HANDLE_NONE;
+ std::mutex mMutex;
+ std::condition_variable mCondition;
+
+ void onAudioDeviceUpdate(audio_io_handle_t audioIo, audio_port_handle_t deviceId);
+ status_t waitForAudioDeviceCb(audio_port_handle_t expDeviceId = AUDIO_PORT_HANDLE_NONE);
+};
+
+// Simple AudioPlayback class.
+class AudioPlayback : public AudioTrack::IAudioTrackCallback {
+ friend sp<AudioPlayback>;
+ AudioPlayback(uint32_t sampleRate, audio_format_t format, audio_channel_mask_t channelMask,
+ audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
+ audio_session_t sessionId = AUDIO_SESSION_NONE,
+ AudioTrack::transfer_type transferType = AudioTrack::TRANSFER_SHARED,
+ audio_attributes_t* attributes = nullptr, audio_offload_info_t* info = nullptr);
+
+ public:
+ status_t loadResource(const char* name);
+ status_t create();
+ sp<AudioTrack> getAudioTrackHandle();
+ status_t start();
+ status_t waitForConsumption(bool testSeek = false);
+ status_t fillBuffer();
+ status_t onProcess(bool testSeek = false);
+ virtual void onBufferEnd() override;
+ void stop();
+
+ bool mStopPlaying;
+ std::mutex mMutex;
+ std::condition_variable mCondition;
+
+ enum State {
+ PLAY_NO_INIT,
+ PLAY_READY,
+ PLAY_STARTED,
+ PLAY_STOPPED,
+ };
+
+ private:
+ ~AudioPlayback();
+ const uint32_t mSampleRate;
+ const audio_format_t mFormat;
+ const audio_channel_mask_t mChannelMask;
+ const audio_output_flags_t mFlags;
+ const audio_session_t mSessionId;
+ const AudioTrack::transfer_type mTransferType;
+ const audio_attributes_t* mAttributes;
+ const audio_offload_info_t* mOffloadInfo;
+
+ size_t mBytesUsedSoFar;
+ State mState;
+ size_t mMemCapacity;
+ sp<MemoryDealer> mMemoryDealer;
+ sp<IMemory> mMemory;
+
+ sp<AudioTrack> mTrack;
+};
+
+// hold pcm data sent by AudioRecord
+class RawBuffer {
+ public:
+ RawBuffer(int64_t ptsPipeline = -1, int64_t ptsManual = -1, int32_t capacity = 0);
+
+ std::unique_ptr<uint8_t[]> mData;
+ int64_t mPtsPipeline;
+ int64_t mPtsManual;
+ int32_t mCapacity;
+};
+
+// Simple AudioCapture
+class AudioCapture : public AudioRecord::IAudioRecordCallback {
+ public:
+ AudioCapture(audio_source_t inputSource, uint32_t sampleRate, audio_format_t format,
+ audio_channel_mask_t channelMask,
+ audio_input_flags_t flags = AUDIO_INPUT_FLAG_NONE,
+ audio_session_t sessionId = AUDIO_SESSION_ALLOCATE,
+ AudioRecord::transfer_type transferType = AudioRecord::TRANSFER_CALLBACK,
+ const audio_attributes_t* attributes = nullptr);
+ ~AudioCapture();
+ size_t onMoreData(const AudioRecord::Buffer& buffer) override;
+ void onOverrun() override;
+ void onMarker(uint32_t markerPosition) override;
+ void onNewPos(uint32_t newPos) override;
+ void onNewIAudioRecord() override;
+ status_t create();
+ status_t setRecordDuration(float durationInSec);
+ status_t enableRecordDump();
+ std::string getRecordDumpFileName() const { return mFileName; }
+ sp<AudioRecord> getAudioRecordHandle();
+ status_t start(AudioSystem::sync_event_t event = AudioSystem::SYNC_EVENT_NONE,
+ audio_session_t triggerSession = AUDIO_SESSION_NONE);
+ status_t obtainBufferCb(RawBuffer& buffer);
+ status_t obtainBuffer(RawBuffer& buffer);
+ status_t audioProcess();
+ status_t stop();
+
+ uint32_t mFrameCount;
+ uint32_t mNotificationFrames;
+ int64_t mNumFramesToRecord;
+ int64_t mNumFramesReceived;
+ int64_t mNumFramesLost;
+ uint32_t mMarkerPosition;
+ uint32_t mMarkerPeriod;
+ uint32_t mReceivedCbMarkerAtPosition;
+ uint32_t mReceivedCbMarkerCount;
+ bool mBufferOverrun;
+
+ enum State {
+ REC_NO_INIT,
+ REC_READY,
+ REC_STARTED,
+ REC_STOPPED,
+ };
+
+ private:
+ const audio_source_t mInputSource;
+ const uint32_t mSampleRate;
+ const audio_format_t mFormat;
+ const audio_channel_mask_t mChannelMask;
+ const audio_input_flags_t mFlags;
+ const audio_session_t mSessionId;
+ const AudioRecord::transfer_type mTransferType;
+ const audio_attributes_t* mAttributes;
+
+ size_t mMaxBytesPerCallback = 2048;
+ sp<AudioRecord> mRecord;
+ State mState;
+ bool mStopRecording;
+ std::string mFileName;
+ int mOutFileFd = -1;
+
+ std::mutex mMutex;
+ std::condition_variable mCondition;
+ std::deque<RawBuffer> mBuffersReceived;
+};
+
+#endif // AUDIO_TEST_UTILS_H_
diff --git a/media/libaudioclient/tests/audioclient_serialization_tests.cpp b/media/libaudioclient/tests/audioclient_serialization_tests.cpp
new file mode 100644
index 0000000..ef8500b
--- /dev/null
+++ b/media/libaudioclient/tests/audioclient_serialization_tests.cpp
@@ -0,0 +1,311 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "AudioClientSerializationUnitTests"
+
+#include <cstdint>
+#include <cstdlib>
+#include <ctime>
+
+#include <gtest/gtest.h>
+
+#include <android_audio_policy_configuration_V7_0-enums.h>
+#include <xsdc/XsdcSupport.h>
+
+#include "audio_test_utils.h"
+
+using namespace android;
+namespace xsd {
+using namespace ::android::audio::policy::configuration::V7_0;
+}
+
+template <typename T, typename X, typename FUNC>
+std::vector<T> getFlags(const xsdc_enum_range<X>& range, const FUNC& func,
+ const std::string& findString = {}) {
+ std::vector<T> vec;
+ for (const auto& xsdEnumVal : range) {
+ T enumVal;
+ std::string enumString = toString(xsdEnumVal);
+ if (enumString.find(findString) != std::string::npos &&
+ func(enumString.c_str(), &enumVal)) {
+ vec.push_back(enumVal);
+ }
+ }
+ return vec;
+}
+
+static const std::vector<audio_usage_t> kUsages =
+ getFlags<audio_usage_t, xsd::AudioUsage, decltype(audio_usage_from_string)>(
+ xsdc_enum_range<xsd::AudioUsage>{}, audio_usage_from_string);
+
+static const std::vector<audio_content_type_t> kContentType =
+ getFlags<audio_content_type_t, xsd::AudioContentType,
+ decltype(audio_content_type_from_string)>(xsdc_enum_range<xsd::AudioContentType>{},
+ audio_content_type_from_string);
+
+static const std::vector<audio_source_t> kInputSources =
+ getFlags<audio_source_t, xsd::AudioSource, decltype(audio_source_from_string)>(
+ xsdc_enum_range<xsd::AudioSource>{}, audio_source_from_string);
+
+static const std::vector<audio_stream_type_t> kStreamtypes =
+ getFlags<audio_stream_type_t, xsd::AudioStreamType,
+ decltype(audio_stream_type_from_string)>(xsdc_enum_range<xsd::AudioStreamType>{},
+ audio_stream_type_from_string);
+
+static const std::vector<uint32_t> kMixMatchRules = {
+ RULE_MATCH_ATTRIBUTE_USAGE,
+ RULE_EXCLUDE_ATTRIBUTE_USAGE,
+ RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET,
+ RULE_EXCLUDE_ATTRIBUTE_CAPTURE_PRESET,
+ RULE_MATCH_UID,
+ RULE_EXCLUDE_UID,
+ RULE_MATCH_USERID,
+ RULE_EXCLUDE_USERID,
+};
+
+// Generates a random string.
+std::string CreateRandomString(size_t n) {
+ std::string data =
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "0123456789";
+ srand(static_cast<unsigned int>(time(0)));
+ std::string s(n, ' ');
+ for (size_t i = 0; i < n; ++i) {
+ s[i] = data[rand() % data.size()];
+ }
+ return s;
+}
+
+class FillAudioAttributes {
+ public:
+ void fillAudioAttributes(audio_attributes_t& attr);
+
+ unsigned int mSeed;
+};
+
+void FillAudioAttributes::fillAudioAttributes(audio_attributes_t& attr) {
+ attr.content_type = kContentType[rand() % kContentType.size()];
+ attr.usage = kUsages[rand() % kUsages.size()];
+ attr.source = kInputSources[rand() % kInputSources.size()];
+ // attr.flags -> [0, (1 << (CAPTURE_PRIVATE + 1) - 1)]
+ attr.flags = static_cast<audio_flags_mask_t>(rand() & 0x3fff);
+ sprintf(attr.tags, "%s",
+ CreateRandomString((int)rand() % (AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1)).c_str());
+}
+
+class SerializationTest : public FillAudioAttributes, public ::testing::Test {
+ void SetUp() override {
+ mSeed = static_cast<unsigned int>(time(0));
+ srand(mSeed);
+ }
+};
+
+// UNIT TESTS
+TEST_F(SerializationTest, AudioProductStrategyBinderization) {
+ for (int j = 0; j < 512; j++) {
+ const std::string name{"Test APSBinderization for seed::" + std::to_string(mSeed)};
+ std::vector<AudioAttributes> audioattributesvector;
+ for (auto i = 0; i < 16; i++) {
+ audio_attributes_t attributes;
+ fillAudioAttributes(attributes);
+ AudioAttributes audioattributes{static_cast<volume_group_t>(rand()),
+ kStreamtypes[rand() % kStreamtypes.size()], attributes};
+ audioattributesvector.push_back(audioattributes);
+ }
+ product_strategy_t psId = static_cast<product_strategy_t>(rand());
+ AudioProductStrategy aps{name, audioattributesvector, psId};
+
+ Parcel p;
+ EXPECT_EQ(NO_ERROR, aps.writeToParcel(&p)) << name;
+
+ AudioProductStrategy apsCopy;
+ p.setDataPosition(0);
+ EXPECT_EQ(NO_ERROR, apsCopy.readFromParcel(&p)) << name;
+ EXPECT_EQ(apsCopy.getName(), name) << name;
+ EXPECT_EQ(apsCopy.getId(), psId) << name;
+ auto avec = apsCopy.getAudioAttributes();
+ EXPECT_EQ(avec.size(), audioattributesvector.size()) << name;
+ for (int i = 0; i < audioattributesvector.size(); i++) {
+ EXPECT_EQ(avec[i].getGroupId(), audioattributesvector[i].getGroupId()) << name;
+ EXPECT_EQ(avec[i].getStreamType(), audioattributesvector[i].getStreamType()) << name;
+ EXPECT_TRUE(avec[i].getAttributes() == audioattributesvector[i].getAttributes())
+ << name;
+ }
+ }
+}
+
+TEST_F(SerializationTest, AudioVolumeGroupBinderization) {
+ for (int j = 0; j < 512; j++) {
+ const std::string name{"Test AVGBinderization for seed::" + std::to_string(mSeed)};
+ volume_group_t groupId = static_cast<volume_group_t>(rand());
+ std::vector<audio_attributes_t> attributesvector;
+ for (auto i = 0; i < 16; i++) {
+ audio_attributes_t attributes;
+ fillAudioAttributes(attributes);
+ attributesvector.push_back(attributes);
+ }
+ std::vector<audio_stream_type_t> streamsvector;
+ for (auto i = 0; i < 8; i++) {
+ streamsvector.push_back(kStreamtypes[rand() % kStreamtypes.size()]);
+ }
+ AudioVolumeGroup avg{name, groupId, attributesvector, streamsvector};
+
+ Parcel p;
+ EXPECT_EQ(NO_ERROR, avg.writeToParcel(&p));
+
+ AudioVolumeGroup avgCopy;
+ p.setDataPosition(0);
+ EXPECT_EQ(NO_ERROR, avgCopy.readFromParcel(&p)) << name;
+ EXPECT_EQ(avgCopy.getName(), name) << name;
+ EXPECT_EQ(avgCopy.getId(), groupId) << name;
+ auto avec = avgCopy.getAudioAttributes();
+ EXPECT_EQ(avec.size(), attributesvector.size()) << name;
+ for (int i = 0; i < avec.size(); i++) {
+ EXPECT_TRUE(avec[i] == attributesvector[i]) << name;
+ }
+ StreamTypeVector svec = avgCopy.getStreamTypes();
+ EXPECT_EQ(svec.size(), streamsvector.size()) << name;
+ for (int i = 0; i < svec.size(); i++) {
+ EXPECT_EQ(svec[i], streamsvector[i]) << name;
+ }
+ }
+}
+
+TEST_F(SerializationTest, AudioMixBinderization) {
+ for (int j = 0; j < 512; j++) {
+ const std::string msg{"Test AMBinderization for seed::" + std::to_string(mSeed)};
+ std::vector<AudioMixMatchCriterion> criteria;
+ criteria.reserve(16);
+ for (int i = 0; i < 16; i++) {
+ AudioMixMatchCriterion ammc{kUsages[rand() % kUsages.size()],
+ kInputSources[rand() % kInputSources.size()],
+ kMixMatchRules[rand() % kMixMatchRules.size()]};
+ criteria.push_back(ammc);
+ }
+ audio_config_t config{};
+ config.sample_rate = 48000;
+ config.channel_mask = AUDIO_CHANNEL_IN_MONO;
+ config.format = AUDIO_FORMAT_PCM_16_BIT;
+ config.offload_info = AUDIO_INFO_INITIALIZER;
+ config.frame_count = 4800;
+ AudioMix am{criteria,
+ static_cast<uint32_t>(rand()),
+ config,
+ static_cast<uint32_t>(rand()),
+ String8(msg.c_str()),
+ static_cast<uint32_t>(rand())};
+
+ Parcel p;
+ EXPECT_EQ(NO_ERROR, am.writeToParcel(&p)) << msg;
+
+ AudioMix amCopy;
+ p.setDataPosition(0);
+ EXPECT_EQ(NO_ERROR, amCopy.readFromParcel(&p)) << msg;
+ EXPECT_EQ(amCopy.mMixType, am.mMixType) << msg;
+ EXPECT_EQ(amCopy.mFormat.sample_rate, am.mFormat.sample_rate) << msg;
+ EXPECT_EQ(amCopy.mFormat.channel_mask, am.mFormat.channel_mask) << msg;
+ EXPECT_EQ(amCopy.mFormat.format, am.mFormat.format) << msg;
+ EXPECT_EQ(amCopy.mRouteFlags, am.mRouteFlags) << msg;
+ EXPECT_EQ(amCopy.mDeviceAddress, am.mDeviceAddress) << msg;
+ EXPECT_EQ(amCopy.mCbFlags, am.mCbFlags) << msg;
+ EXPECT_EQ(amCopy.mCriteria.size(), am.mCriteria.size()) << msg;
+ for (auto i = 0; i < amCopy.mCriteria.size(); i++) {
+ EXPECT_EQ(amCopy.mCriteria[i].mRule, am.mCriteria[i].mRule) << msg;
+ EXPECT_EQ(amCopy.mCriteria[i].mValue.mUserId, am.mCriteria[i].mValue.mUserId) << msg;
+ }
+ }
+}
+
+using MMCTestParams = std::tuple<audio_usage_t, audio_source_t, uint32_t>;
+
+class MMCParameterizedTest : public FillAudioAttributes,
+ public ::testing::TestWithParam<MMCTestParams> {
+ public:
+ MMCParameterizedTest()
+ : mAudioUsage(std::get<0>(GetParam())),
+ mAudioSource(std::get<1>(GetParam())),
+ mAudioMixMatchRules(std::get<2>(GetParam())){};
+
+ const audio_usage_t mAudioUsage;
+ const audio_source_t mAudioSource;
+ const uint32_t mAudioMixMatchRules;
+
+ void SetUp() override {
+ mSeed = static_cast<unsigned int>(time(0));
+ srand(mSeed);
+ }
+};
+
+TEST_P(MMCParameterizedTest, AudioMixMatchCriterionBinderization) {
+ const std::string msg{"Test AMMCBinderization for seed::" + std::to_string(mSeed)};
+ AudioMixMatchCriterion ammc{mAudioUsage, mAudioSource, mAudioMixMatchRules};
+
+ Parcel p;
+ EXPECT_EQ(NO_ERROR, ammc.writeToParcel(&p)) << msg;
+
+ AudioMixMatchCriterion ammcCopy;
+ p.setDataPosition(0);
+ EXPECT_EQ(NO_ERROR, ammcCopy.readFromParcel(&p)) << msg;
+ EXPECT_EQ(ammcCopy.mRule, ammc.mRule) << msg;
+ EXPECT_EQ(ammcCopy.mValue.mUserId, ammc.mValue.mUserId) << msg;
+}
+
+// audioUsage, audioSource, audioMixMatchRules
+INSTANTIATE_TEST_SUITE_P(SerializationParameterizedTests, MMCParameterizedTest,
+ ::testing::Combine(testing::ValuesIn(kUsages),
+ testing::ValuesIn(kInputSources),
+ testing::ValuesIn(kMixMatchRules)));
+
+using AudioAttributesTestParams = std::tuple<audio_stream_type_t>;
+
+class AudioAttributesParameterizedTest
+ : public FillAudioAttributes,
+ public ::testing::TestWithParam<AudioAttributesTestParams> {
+ public:
+ AudioAttributesParameterizedTest() : mAudioStream(std::get<0>(GetParam())){};
+
+ const audio_stream_type_t mAudioStream;
+
+ void SetUp() override {
+ mSeed = static_cast<unsigned int>(time(0));
+ srand(mSeed);
+ }
+};
+
+TEST_P(AudioAttributesParameterizedTest, AudioAttributesBinderization) {
+ const std::string msg{"Test AABinderization for seed::" + std::to_string(mSeed)};
+ volume_group_t groupId = static_cast<volume_group_t>(rand());
+ audio_stream_type_t stream = mAudioStream;
+ audio_attributes_t attributes;
+ fillAudioAttributes(attributes);
+ AudioAttributes audioattributes{groupId, stream, attributes};
+
+ Parcel p;
+ EXPECT_EQ(NO_ERROR, audioattributes.writeToParcel(&p)) << msg;
+
+ AudioAttributes audioattributesCopy;
+ p.setDataPosition(0);
+ EXPECT_EQ(NO_ERROR, audioattributesCopy.readFromParcel(&p)) << msg;
+ EXPECT_EQ(audioattributesCopy.getGroupId(), audioattributes.getGroupId()) << msg;
+ EXPECT_EQ(audioattributesCopy.getStreamType(), audioattributes.getStreamType()) << msg;
+ EXPECT_TRUE(audioattributesCopy.getAttributes() == attributes) << msg;
+}
+
+// audioStream
+INSTANTIATE_TEST_SUITE_P(SerializationParameterizedTests, AudioAttributesParameterizedTest,
+ ::testing::Combine(testing::ValuesIn(kStreamtypes)));
diff --git a/media/libaudioclient/tests/audioeffect_analyser.cpp b/media/libaudioclient/tests/audioeffect_analyser.cpp
new file mode 100644
index 0000000..94accae
--- /dev/null
+++ b/media/libaudioclient/tests/audioeffect_analyser.cpp
@@ -0,0 +1,419 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// #define LOG_NDEBUG 0
+#define LOG_TAG "AudioEffectAnalyser"
+
+#include <android-base/file.h>
+#include <android-base/stringprintf.h>
+#include <gtest/gtest.h>
+#include <media/AudioEffect.h>
+#include <system/audio_effects/effect_bassboost.h>
+#include <system/audio_effects/effect_equalizer.h>
+#include <fstream>
+#include <iostream>
+#include <string>
+#include <tuple>
+#include <vector>
+
+#include "audio_test_utils.h"
+#include "pffft.hpp"
+
+#define CHECK_OK(expr, msg) \
+ mStatus = (expr); \
+ if (OK != mStatus) { \
+ mMsg = (msg); \
+ return; \
+ }
+
+using namespace android;
+
+constexpr float kDefAmplitude = 0.60f;
+
+constexpr float kPlayBackDurationSec = 1.5;
+constexpr float kCaptureDurationSec = 1.0;
+constexpr float kPrimeDurationInSec = 0.5;
+
+// chosen to safely sample largest center freq of eq bands
+constexpr uint32_t kSamplingFrequency = 48000;
+
+// allows no fmt conversion before fft
+constexpr audio_format_t kFormat = AUDIO_FORMAT_PCM_FLOAT;
+
+// playback and capture are done with channel mask configured to mono.
+// effect analysis should not depend on mask, mono makes it easier.
+
+constexpr int kNPointFFT = 16384;
+constexpr float kBinWidth = (float)kSamplingFrequency / kNPointFFT;
+
+const char* gPackageName = "AudioEffectAnalyser";
+
+static_assert(kPrimeDurationInSec + 2 * kNPointFFT / kSamplingFrequency < kCaptureDurationSec,
+ "capture at least, prime, pad, nPointFft size of samples");
+static_assert(kPrimeDurationInSec + 2 * kNPointFFT / kSamplingFrequency < kPlayBackDurationSec,
+ "playback needs to be active during capture");
+
+struct CaptureEnv {
+ // input args
+ uint32_t mSampleRate{kSamplingFrequency};
+ audio_format_t mFormat{kFormat};
+ audio_channel_mask_t mChannelMask{AUDIO_CHANNEL_IN_MONO};
+ float mCaptureDuration{kCaptureDurationSec};
+ // output val
+ status_t mStatus{OK};
+ std::string mMsg;
+ std::string mDumpFileName;
+
+ ~CaptureEnv();
+ void capture();
+};
+
+CaptureEnv::~CaptureEnv() {
+ if (!mDumpFileName.empty()) {
+ std::ifstream f(mDumpFileName);
+ if (f.good()) {
+ f.close();
+ remove(mDumpFileName.c_str());
+ }
+ }
+}
+
+void CaptureEnv::capture() {
+ audio_port_v7 port;
+ CHECK_OK(getPortByAttributes(AUDIO_PORT_ROLE_SOURCE, AUDIO_PORT_TYPE_DEVICE,
+ AUDIO_DEVICE_IN_REMOTE_SUBMIX, "0", port),
+ "Could not find port")
+ const auto capture =
+ sp<AudioCapture>::make(AUDIO_SOURCE_REMOTE_SUBMIX, mSampleRate, mFormat, mChannelMask);
+ CHECK_OK(capture->create(), "record creation failed")
+ CHECK_OK(capture->setRecordDuration(mCaptureDuration), "set record duration failed")
+ CHECK_OK(capture->enableRecordDump(), "enable record dump failed")
+ auto cbCapture = sp<OnAudioDeviceUpdateNotifier>::make();
+ CHECK_OK(capture->getAudioRecordHandle()->addAudioDeviceCallback(cbCapture),
+ "addAudioDeviceCallback failed")
+ CHECK_OK(capture->start(), "start recording failed")
+ CHECK_OK(capture->audioProcess(), "recording process failed")
+ CHECK_OK(cbCapture->waitForAudioDeviceCb(), "audio device callback notification timed out");
+ if (port.id != capture->getAudioRecordHandle()->getRoutedDeviceId()) {
+ CHECK_OK(BAD_VALUE, "Capture NOT routed on expected port")
+ }
+ CHECK_OK(getPortByAttributes(AUDIO_PORT_ROLE_SINK, AUDIO_PORT_TYPE_DEVICE,
+ AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "0", port),
+ "Could not find port")
+ CHECK_OK(capture->stop(), "record stop failed")
+ mDumpFileName = capture->getRecordDumpFileName();
+}
+
+struct PlaybackEnv {
+ // input args
+ uint32_t mSampleRate{kSamplingFrequency};
+ audio_format_t mFormat{kFormat};
+ audio_channel_mask_t mChannelMask{AUDIO_CHANNEL_OUT_MONO};
+ audio_session_t mSessionId{AUDIO_SESSION_NONE};
+ std::string mRes;
+ // output val
+ status_t mStatus{OK};
+ std::string mMsg;
+
+ void play();
+};
+
+void PlaybackEnv::play() {
+ const auto ap =
+ sp<AudioPlayback>::make(mSampleRate, mFormat, mChannelMask, AUDIO_OUTPUT_FLAG_NONE,
+ mSessionId, AudioTrack::TRANSFER_OBTAIN);
+ CHECK_OK(ap->loadResource(mRes.c_str()), "Unable to open Resource")
+ const auto cbPlayback = sp<OnAudioDeviceUpdateNotifier>::make();
+ CHECK_OK(ap->create(), "track creation failed")
+ ap->getAudioTrackHandle()->setVolume(1.0f);
+ CHECK_OK(ap->getAudioTrackHandle()->addAudioDeviceCallback(cbPlayback),
+ "addAudioDeviceCallback failed")
+ CHECK_OK(ap->start(), "audio track start failed")
+ CHECK_OK(cbPlayback->waitForAudioDeviceCb(), "audio device callback notification timed out")
+ CHECK_OK(ap->onProcess(), "playback process failed")
+ ap->stop();
+}
+
+void generateMultiTone(const std::vector<int>& toneFrequencies, float samplingFrequency,
+ float duration, float amplitude, float* buffer, int numSamples) {
+ int totalFrameCount = (samplingFrequency * duration);
+ int limit = std::min(totalFrameCount, numSamples);
+
+ for (auto i = 0; i < limit; i++) {
+ buffer[i] = 0;
+ for (auto j = 0; j < toneFrequencies.size(); j++) {
+ buffer[i] += sin(2 * M_PI * toneFrequencies[j] * i / samplingFrequency);
+ }
+ buffer[i] *= (amplitude / toneFrequencies.size());
+ }
+}
+
+sp<AudioEffect> createEffect(const effect_uuid_t* type,
+ audio_session_t sessionId = AUDIO_SESSION_OUTPUT_MIX) {
+ std::string packageName{gPackageName};
+ AttributionSourceState attributionSource;
+ attributionSource.packageName = packageName;
+ attributionSource.uid = VALUE_OR_FATAL(legacy2aidl_uid_t_int32_t(getuid()));
+ attributionSource.pid = VALUE_OR_FATAL(legacy2aidl_pid_t_int32_t(getpid()));
+ attributionSource.token = sp<BBinder>::make();
+ sp<AudioEffect> effect = sp<AudioEffect>::make(attributionSource);
+ effect->set(type, nullptr, 0, nullptr, sessionId, AUDIO_IO_HANDLE_NONE, {}, false, false);
+ return effect;
+}
+
+void computeFilterGainsAtTones(float captureDuration, int nPointFft, std::vector<int>& binOffsets,
+ float* inputMag, float* gaindB, const char* res,
+ audio_session_t sessionId) {
+ int totalFrameCount = captureDuration * kSamplingFrequency;
+ auto output = pffft::AlignedVector<float>(totalFrameCount);
+ auto fftOutput = pffft::AlignedVector<float>(nPointFft);
+ PlaybackEnv argsP;
+ argsP.mRes = std::string{res};
+ argsP.mSessionId = sessionId;
+ CaptureEnv argsR;
+ argsR.mCaptureDuration = captureDuration;
+ std::thread playbackThread(&PlaybackEnv::play, &argsP);
+ std::thread captureThread(&CaptureEnv::capture, &argsR);
+ captureThread.join();
+ playbackThread.join();
+ ASSERT_EQ(OK, argsR.mStatus) << argsR.mMsg;
+ ASSERT_EQ(OK, argsP.mStatus) << argsP.mMsg;
+ ASSERT_FALSE(argsR.mDumpFileName.empty()) << "recorded not written to file";
+ std::ifstream fin(argsR.mDumpFileName, std::ios::in | std::ios::binary);
+ fin.read((char*)output.data(), totalFrameCount * sizeof(output[0]));
+ fin.close();
+ PFFFT_Setup* handle = pffft_new_setup(nPointFft, PFFFT_REAL);
+ // ignore first few samples. This is to not analyse until audio track is re-routed to remote
+ // submix source, also for the effect filter response to reach steady-state (priming / pruning
+ // samples).
+ int rerouteOffset = kPrimeDurationInSec * kSamplingFrequency;
+ pffft_transform_ordered(handle, output.data() + rerouteOffset, fftOutput.data(), nullptr,
+ PFFFT_FORWARD);
+ pffft_destroy_setup(handle);
+ for (auto i = 0; i < binOffsets.size(); i++) {
+ auto k = binOffsets[i];
+ auto outputMag = sqrt((fftOutput[k * 2] * fftOutput[k * 2]) +
+ (fftOutput[k * 2 + 1] * fftOutput[k * 2 + 1]));
+ gaindB[i] = 20 * log10(outputMag / inputMag[i]);
+ }
+}
+
+std::tuple<int, int> roundToFreqCenteredToFftBin(float binWidth, float freq) {
+ int bin_index = std::round(freq / binWidth);
+ int cfreq = std::round(bin_index * binWidth);
+ return std::make_tuple(bin_index, cfreq);
+}
+
+TEST(AudioEffectTest, CheckEqualizerEffect) {
+ audio_session_t sessionId =
+ (audio_session_t)AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
+ sp<AudioEffect> equalizer = createEffect(SL_IID_EQUALIZER, sessionId);
+ ASSERT_EQ(OK, equalizer->initCheck());
+ ASSERT_EQ(NO_ERROR, equalizer->setEnabled(true));
+ if ((equalizer->descriptor().flags & EFFECT_FLAG_HW_ACC_MASK) != 0) {
+ GTEST_SKIP() << "effect processed output inaccessible, skipping test";
+ }
+#define MAX_PARAMS 64
+ uint32_t buf32[sizeof(effect_param_t) / sizeof(uint32_t) + MAX_PARAMS];
+ effect_param_t* eqParam = (effect_param_t*)(&buf32);
+
+ // get num of presets
+ eqParam->psize = sizeof(uint32_t);
+ eqParam->vsize = sizeof(uint16_t);
+ *(int32_t*)eqParam->data = EQ_PARAM_GET_NUM_OF_PRESETS;
+ EXPECT_EQ(0, equalizer->getParameter(eqParam));
+ EXPECT_EQ(0, eqParam->status);
+ int numPresets = *((uint16_t*)((int32_t*)eqParam->data + 1));
+
+ // get num of bands
+ eqParam->psize = sizeof(uint32_t);
+ eqParam->vsize = sizeof(uint16_t);
+ *(int32_t*)eqParam->data = EQ_PARAM_NUM_BANDS;
+ EXPECT_EQ(0, equalizer->getParameter(eqParam));
+ EXPECT_EQ(0, eqParam->status);
+ int numBands = *((uint16_t*)((int32_t*)eqParam->data + 1));
+
+ const int totalFrameCount = kSamplingFrequency * kPlayBackDurationSec;
+
+ // get band center frequencies
+ std::vector<int> centerFrequencies;
+ std::vector<int> binOffsets;
+ for (auto i = 0; i < numBands; i++) {
+ eqParam->psize = sizeof(uint32_t) * 2;
+ eqParam->vsize = sizeof(uint32_t);
+ *(int32_t*)eqParam->data = EQ_PARAM_CENTER_FREQ;
+ *((uint16_t*)((int32_t*)eqParam->data + 1)) = i;
+ EXPECT_EQ(0, equalizer->getParameter(eqParam));
+ EXPECT_EQ(0, eqParam->status);
+ float cfreq = *((int32_t*)eqParam->data + 2) / 1000; // milli hz
+ // pick frequency close to bin center frequency
+ auto [bin_index, bin_freq] = roundToFreqCenteredToFftBin(kBinWidth, cfreq);
+ centerFrequencies.push_back(bin_freq);
+ binOffsets.push_back(bin_index);
+ }
+
+ // input for effect module
+ auto input = pffft::AlignedVector<float>(totalFrameCount);
+ generateMultiTone(centerFrequencies, kSamplingFrequency, kPlayBackDurationSec, kDefAmplitude,
+ input.data(), totalFrameCount);
+ auto fftInput = pffft::AlignedVector<float>(kNPointFFT);
+ PFFFT_Setup* handle = pffft_new_setup(kNPointFFT, PFFFT_REAL);
+ pffft_transform_ordered(handle, input.data(), fftInput.data(), nullptr, PFFFT_FORWARD);
+ pffft_destroy_setup(handle);
+ float inputMag[numBands];
+ for (auto i = 0; i < numBands; i++) {
+ auto k = binOffsets[i];
+ inputMag[i] = sqrt((fftInput[k * 2] * fftInput[k * 2]) +
+ (fftInput[k * 2 + 1] * fftInput[k * 2 + 1]));
+ }
+ TemporaryFile tf("/data/local/tmp");
+ close(tf.release());
+ std::ofstream fout(tf.path, std::ios::out | std::ios::binary);
+ fout.write((char*)input.data(), input.size() * sizeof(input[0]));
+ fout.close();
+
+ float expGaindB[numBands], actGaindB[numBands];
+
+ std::string msg = "";
+ int numPresetsOk = 0;
+ for (auto preset = 0; preset < numPresets; preset++) {
+ // set preset
+ eqParam->psize = sizeof(uint32_t);
+ eqParam->vsize = sizeof(uint32_t);
+ *(int32_t*)eqParam->data = EQ_PARAM_CUR_PRESET;
+ *((uint16_t*)((int32_t*)eqParam->data + 1)) = preset;
+ EXPECT_EQ(0, equalizer->setParameter(eqParam));
+ EXPECT_EQ(0, eqParam->status);
+ // get preset gains
+ eqParam->psize = sizeof(uint32_t);
+ eqParam->vsize = (numBands + 1) * sizeof(uint32_t);
+ *(int32_t*)eqParam->data = EQ_PARAM_PROPERTIES;
+ EXPECT_EQ(0, equalizer->getParameter(eqParam));
+ EXPECT_EQ(0, eqParam->status);
+ t_equalizer_settings* settings =
+ reinterpret_cast<t_equalizer_settings*>((int32_t*)eqParam->data + 1);
+ EXPECT_EQ(preset, settings->curPreset);
+ EXPECT_EQ(numBands, settings->numBands);
+ for (auto i = 0; i < numBands; i++) {
+ expGaindB[i] = ((int16_t)settings->bandLevels[i]) / 100.0f; // gain in milli bels
+ }
+ memset(actGaindB, 0, sizeof(actGaindB));
+ ASSERT_NO_FATAL_FAILURE(computeFilterGainsAtTones(kCaptureDurationSec, kNPointFFT,
+ binOffsets, inputMag, actGaindB, tf.path,
+ sessionId));
+ bool isOk = true;
+ for (auto i = 0; i < numBands - 1; i++) {
+ auto diffA = expGaindB[i] - expGaindB[i + 1];
+ auto diffB = actGaindB[i] - actGaindB[i + 1];
+ if (diffA == 0 && fabs(diffA - diffB) > 1.0f) {
+ msg += (android::base::StringPrintf(
+ "For eq preset : %d, between bands %d and %d, expected relative gain is : "
+ "%f, got relative gain is : %f, error : %f \n",
+ preset, i, i + 1, diffA, diffB, diffA - diffB));
+ isOk = false;
+ } else if (diffA * diffB < 0) {
+ msg += (android::base::StringPrintf(
+ "For eq preset : %d, between bands %d and %d, expected relative gain and "
+ "seen relative gain are of opposite signs \n. Expected relative gain is : "
+ "%f, seen relative gain is : %f \n",
+ preset, i, i + 1, diffA, diffB));
+ isOk = false;
+ }
+ }
+ if (isOk) numPresetsOk++;
+ }
+ EXPECT_EQ(numPresetsOk, numPresets) << msg;
+}
+
+TEST(AudioEffectTest, CheckBassBoostEffect) {
+ audio_session_t sessionId =
+ (audio_session_t)AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
+ sp<AudioEffect> bassboost = createEffect(SL_IID_BASSBOOST, sessionId);
+ ASSERT_EQ(OK, bassboost->initCheck());
+ ASSERT_EQ(NO_ERROR, bassboost->setEnabled(true));
+ if ((bassboost->descriptor().flags & EFFECT_FLAG_HW_ACC_MASK) != 0) {
+ GTEST_SKIP() << "effect processed output inaccessible, skipping test";
+ }
+ int32_t buf32[sizeof(effect_param_t) / sizeof(int32_t) + MAX_PARAMS];
+ effect_param_t* bbParam = (effect_param_t*)(&buf32);
+
+ bbParam->psize = sizeof(int32_t);
+ bbParam->vsize = sizeof(int32_t);
+ *(int32_t*)bbParam->data = BASSBOOST_PARAM_STRENGTH_SUPPORTED;
+ EXPECT_EQ(0, bassboost->getParameter(bbParam));
+ EXPECT_EQ(0, bbParam->status);
+ bool strengthSupported = *((int32_t*)bbParam->data + 1);
+
+ const int totalFrameCount = kSamplingFrequency * kPlayBackDurationSec;
+
+ // selecting bass frequency, speech tone (for relative gain)
+ std::vector<int> testFrequencies{100, 1200};
+ std::vector<int> binOffsets;
+ for (auto i = 0; i < testFrequencies.size(); i++) {
+ // pick frequency close to bin center frequency
+ auto [bin_index, bin_freq] = roundToFreqCenteredToFftBin(kBinWidth, testFrequencies[i]);
+ testFrequencies[i] = bin_freq;
+ binOffsets.push_back(bin_index);
+ }
+
+ // input for effect module
+ auto input = pffft::AlignedVector<float>(totalFrameCount);
+ generateMultiTone(testFrequencies, kSamplingFrequency, kPlayBackDurationSec, kDefAmplitude,
+ input.data(), totalFrameCount);
+ auto fftInput = pffft::AlignedVector<float>(kNPointFFT);
+ PFFFT_Setup* handle = pffft_new_setup(kNPointFFT, PFFFT_REAL);
+ pffft_transform_ordered(handle, input.data(), fftInput.data(), nullptr, PFFFT_FORWARD);
+ pffft_destroy_setup(handle);
+ float inputMag[testFrequencies.size()];
+ for (auto i = 0; i < testFrequencies.size(); i++) {
+ auto k = binOffsets[i];
+ inputMag[i] = sqrt((fftInput[k * 2] * fftInput[k * 2]) +
+ (fftInput[k * 2 + 1] * fftInput[k * 2 + 1]));
+ }
+ TemporaryFile tf("/data/local/tmp");
+ close(tf.release());
+ std::ofstream fout(tf.path, std::ios::out | std::ios::binary);
+ fout.write((char*)input.data(), input.size() * sizeof(input[0]));
+ fout.close();
+
+ float gainWithOutFilter[testFrequencies.size()];
+ memset(gainWithOutFilter, 0, sizeof(gainWithOutFilter));
+ ASSERT_NO_FATAL_FAILURE(computeFilterGainsAtTones(kCaptureDurationSec, kNPointFFT, binOffsets,
+ inputMag, gainWithOutFilter, tf.path,
+ AUDIO_SESSION_OUTPUT_MIX));
+ float diffA = gainWithOutFilter[0] - gainWithOutFilter[1];
+ float prevGain = -100.f;
+ for (auto strength = 150; strength < 1000; strength += strengthSupported ? 150 : 1000) {
+ // configure filter strength
+ if (strengthSupported) {
+ bbParam->psize = sizeof(int32_t);
+ bbParam->vsize = sizeof(int16_t);
+ *(int32_t*)bbParam->data = BASSBOOST_PARAM_STRENGTH;
+ *((int16_t*)((int32_t*)bbParam->data + 1)) = strength;
+ EXPECT_EQ(0, bassboost->setParameter(bbParam));
+ EXPECT_EQ(0, bbParam->status);
+ }
+ float gainWithFilter[testFrequencies.size()];
+ memset(gainWithFilter, 0, sizeof(gainWithFilter));
+ ASSERT_NO_FATAL_FAILURE(computeFilterGainsAtTones(kCaptureDurationSec, kNPointFFT,
+ binOffsets, inputMag, gainWithFilter,
+ tf.path, sessionId));
+ float diffB = gainWithFilter[0] - gainWithFilter[1];
+ EXPECT_GT(diffB, diffA) << "bassboost effect not seen";
+ EXPECT_GE(diffB, prevGain) << "increase in boost strength causing fall in gain";
+ prevGain = diffB;
+ }
+}
diff --git a/media/libaudioclient/tests/audioeffect_tests.cpp b/media/libaudioclient/tests/audioeffect_tests.cpp
new file mode 100644
index 0000000..e6149e4
--- /dev/null
+++ b/media/libaudioclient/tests/audioeffect_tests.cpp
@@ -0,0 +1,559 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "AudioEffectUnitTests"
+
+#include <gtest/gtest.h>
+#include <media/AudioEffect.h>
+#include <system/audio_effects/effect_hapticgenerator.h>
+#include <system/audio_effects/effect_spatializer.h>
+#include <system/audio_effects/effect_visualizer.h>
+
+#include "audio_test_utils.h"
+
+using namespace android;
+
+class AudioEffectCallback : public AudioEffect::IAudioEffectCallback {
+ public:
+ bool receivedFramesProcessed = false;
+
+ void onFramesProcessed(int32_t framesProcessed) override {
+ ALOGE("number of frames processed %d", framesProcessed);
+ receivedFramesProcessed = true;
+ }
+};
+
+static constexpr int kDefaultInputEffectPriority = -1;
+static constexpr int kDefaultOutputEffectPriority = 0;
+
+static const char* gPackageName = "AudioEffectTest";
+
+bool doesDeviceSupportLowLatencyMode(std::vector<struct audio_port_v7>& ports) {
+ for (const auto& port : ports) {
+ if (port.role == AUDIO_PORT_ROLE_SOURCE && port.type == AUDIO_PORT_TYPE_MIX) {
+ if ((port.active_config.flags.output & AUDIO_OUTPUT_FLAG_FAST) != 0) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+sp<AudioEffect> createEffect(const effect_uuid_t* type, const effect_uuid_t* uuid = nullptr,
+ int priority = 0, audio_session_t sessionId = AUDIO_SESSION_OUTPUT_MIX,
+ const wp<AudioEffectCallback>& callback = nullptr) {
+ std::string packageName{gPackageName};
+ AttributionSourceState attributionSource;
+ attributionSource.packageName = packageName;
+ attributionSource.uid = VALUE_OR_FATAL(legacy2aidl_uid_t_int32_t(getuid()));
+ attributionSource.pid = VALUE_OR_FATAL(legacy2aidl_pid_t_int32_t(getpid()));
+ attributionSource.token = sp<BBinder>::make();
+ sp<AudioEffect> effect = new AudioEffect(attributionSource);
+ effect->set(type, uuid, priority, callback, sessionId, AUDIO_IO_HANDLE_NONE, {}, false,
+ (callback != nullptr));
+ return effect;
+}
+
+status_t isEffectExistsOnAudioSession(const effect_uuid_t* type, const effect_uuid_t* uuid,
+ int priority, audio_session_t sessionId) {
+ sp<AudioEffect> effect = createEffect(type, uuid, priority, sessionId);
+ return effect->initCheck();
+}
+
+bool isEffectDefaultOnRecord(const effect_uuid_t* type, const effect_uuid_t* uuid,
+ const sp<AudioRecord>& audioRecord) {
+ effect_descriptor_t descriptors[AudioEffect::kMaxPreProcessing];
+ uint32_t numEffects = AudioEffect::kMaxPreProcessing;
+ status_t ret = AudioEffect::queryDefaultPreProcessing(audioRecord->getSessionId(), descriptors,
+ &numEffects);
+ if (ret != OK) {
+ return false;
+ }
+ for (int i = 0; i < numEffects; i++) {
+ if ((memcmp(&descriptors[i].type, type, sizeof(effect_uuid_t)) == 0) &&
+ (memcmp(&descriptors[i].uuid, uuid, sizeof(effect_uuid_t)) == 0)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void listEffectsAvailable(std::vector<effect_descriptor_t>& descriptors) {
+ uint32_t numEffects = 0;
+ ASSERT_EQ(NO_ERROR, AudioEffect::queryNumberEffects(&numEffects));
+ for (auto i = 0; i < numEffects; i++) {
+ effect_descriptor_t des;
+ ASSERT_EQ(NO_ERROR, AudioEffect::queryEffect(i, &des));
+ descriptors.push_back(des);
+ }
+}
+
+bool isPreprocessing(effect_descriptor_t& descriptor) {
+ return ((descriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC);
+}
+
+bool isInsert(effect_descriptor_t& descriptor) {
+ return ((descriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_INSERT);
+}
+
+bool isAux(effect_descriptor_t& descriptor) {
+ return ((descriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY);
+}
+
+bool isPostproc(effect_descriptor_t& descriptor) {
+ return ((descriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC);
+}
+
+bool isFastCompatible(effect_descriptor_t& descriptor) {
+ return !(((descriptor.flags & EFFECT_FLAG_HW_ACC_MASK) == 0) &&
+ ((descriptor.flags & EFFECT_FLAG_NO_PROCESS) == 0));
+}
+
+bool isSpatializer(effect_descriptor_t& descriptor) {
+ return (memcmp(&descriptor.type, FX_IID_SPATIALIZER, sizeof(effect_uuid_t)) == 0);
+}
+
+bool isHapticGenerator(effect_descriptor_t& descriptor) {
+ return (memcmp(&descriptor.type, FX_IID_HAPTICGENERATOR, sizeof(effect_uuid_t)) == 0);
+}
+
+std::tuple<std::string, std::string> typeAndUuidToString(const effect_descriptor_t& desc) {
+ char type[512];
+ AudioEffect::guidToString(&desc.type, type, sizeof(type));
+ char uuid[512];
+ AudioEffect::guidToString(&desc.uuid, uuid, sizeof(uuid));
+ return std::make_tuple(type, uuid);
+}
+
+// UNIT TESTS
+TEST(AudioEffectTest, getEffectDescriptor) {
+ effect_uuid_t randomType = {
+ 0x81781c08, 0x93dd, 0x11ec, 0xb909, {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
+ effect_uuid_t randomUuid = {
+ 0x653730e1, 0x1be1, 0x438e, 0xa35a, {0xfc, 0x9b, 0xa1, 0x2a, 0x5e, 0xc9}};
+ effect_uuid_t empty = EFFECT_UUID_INITIALIZER;
+
+ effect_descriptor_t descriptor;
+ EXPECT_EQ(NAME_NOT_FOUND, AudioEffect::getEffectDescriptor(&randomUuid, &randomType,
+ EFFECT_FLAG_TYPE_MASK, &descriptor));
+
+ std::vector<effect_descriptor_t> descriptors;
+ ASSERT_NO_FATAL_FAILURE(listEffectsAvailable(descriptors));
+
+ for (auto i = 0; i < descriptors.size(); i++) {
+ EXPECT_EQ(NO_ERROR,
+ AudioEffect::getEffectDescriptor(&descriptors[i].uuid, &descriptors[i].type,
+ EFFECT_FLAG_TYPE_MASK, &descriptor));
+ EXPECT_EQ(0, memcmp(&descriptor, &descriptors[i], sizeof(effect_uuid_t)));
+ }
+ // negative tests
+ if (descriptors.size() > 0) {
+ EXPECT_EQ(BAD_VALUE,
+ AudioEffect::getEffectDescriptor(&descriptors[0].uuid, &descriptors[0].type,
+ EFFECT_FLAG_TYPE_MASK, nullptr));
+ }
+ EXPECT_EQ(BAD_VALUE, AudioEffect::getEffectDescriptor(nullptr, nullptr,
+ EFFECT_FLAG_TYPE_PRE_PROC, &descriptor));
+ EXPECT_EQ(BAD_VALUE, AudioEffect::getEffectDescriptor(&empty, &randomType,
+ EFFECT_FLAG_TYPE_MASK, nullptr));
+ EXPECT_EQ(BAD_VALUE, AudioEffect::getEffectDescriptor(nullptr, &randomType,
+ EFFECT_FLAG_TYPE_POST_PROC, &descriptor));
+ EXPECT_EQ(BAD_VALUE, AudioEffect::getEffectDescriptor(&randomUuid, nullptr,
+ EFFECT_FLAG_TYPE_INSERT, &descriptor));
+}
+
+TEST(AudioEffectTest, DISABLED_GetSetParameterForEffect) {
+ sp<AudioEffect> visualizer = createEffect(SL_IID_VISUALIZATION);
+ status_t status = visualizer->initCheck();
+ ASSERT_TRUE(status == NO_ERROR || status == ALREADY_EXISTS) << "Init check error";
+ ASSERT_EQ(NO_ERROR, visualizer->setEnabled(true)) << "visualizer not enabled";
+
+ uint32_t buf32[3][sizeof(effect_param_t) / sizeof(uint32_t) + 2];
+ effect_param_t* vis_none = (effect_param_t*)(buf32[0]);
+ effect_param_t* vis_rms = (effect_param_t*)(buf32[1]);
+ effect_param_t* vis_tmp = (effect_param_t*)(buf32[2]);
+
+ // Visualizer::setMeasurementMode()
+ vis_none->psize = sizeof(uint32_t);
+ vis_none->vsize = sizeof(uint32_t);
+ *(int32_t*)vis_none->data = VISUALIZER_PARAM_MEASUREMENT_MODE;
+ *((int32_t*)vis_none->data + 1) = MEASUREMENT_MODE_NONE;
+ EXPECT_EQ(NO_ERROR, visualizer->setParameter(vis_none))
+ << "setMeasurementMode doesn't report success";
+
+ // Visualizer::getMeasurementMode()
+ vis_tmp->psize = sizeof(uint32_t);
+ vis_tmp->vsize = sizeof(uint32_t);
+ *(int32_t*)vis_tmp->data = VISUALIZER_PARAM_MEASUREMENT_MODE;
+ *((int32_t*)vis_tmp->data + 1) = 23;
+ EXPECT_EQ(NO_ERROR, visualizer->getParameter(vis_tmp))
+ << "getMeasurementMode doesn't report success";
+ EXPECT_EQ(*((int32_t*)vis_tmp->data + 1), *((int32_t*)vis_none->data + 1))
+ << "target mode does not match set mode";
+
+ // Visualizer::setMeasurementModeDeferred()
+ vis_rms->psize = sizeof(uint32_t);
+ vis_rms->vsize = sizeof(uint32_t);
+ *(int32_t*)vis_rms->data = VISUALIZER_PARAM_MEASUREMENT_MODE;
+ *((int32_t*)vis_rms->data + 1) = MEASUREMENT_MODE_PEAK_RMS;
+ EXPECT_EQ(NO_ERROR, visualizer->setParameterDeferred(vis_rms))
+ << "setMeasurementModeDeferred doesn't report success";
+
+ *((int32_t*)vis_tmp->data + 1) = 23;
+ EXPECT_EQ(NO_ERROR, visualizer->getParameter(vis_tmp))
+ << "getMeasurementMode doesn't report success";
+ EXPECT_EQ(*((int32_t*)vis_tmp->data + 1), *((int32_t*)vis_none->data + 1))
+ << "target mode does not match set mode";
+
+ // setParameterCommit
+ EXPECT_EQ(NO_ERROR, visualizer->setParameterCommit())
+ << "setMeasurementModeCommit does not report success";
+
+ // validate Params
+ *((int32_t*)vis_tmp->data + 1) = 23;
+ EXPECT_EQ(NO_ERROR, visualizer->getParameter(vis_tmp))
+ << "getMeasurementMode doesn't report success";
+ EXPECT_EQ(*((int32_t*)vis_tmp->data + 1), *((int32_t*)vis_rms->data + 1))
+ << "target mode does not match set mode";
+}
+
+TEST(AudioEffectTest, ManageSourceDefaultEffects) {
+ int32_t selectedEffect = -1;
+
+ const uint32_t sampleRate = 44100;
+ const audio_format_t format = AUDIO_FORMAT_PCM_16_BIT;
+ const audio_channel_mask_t channelMask = AUDIO_CHANNEL_IN_STEREO;
+ sp<AudioCapture> capture = nullptr;
+
+ std::vector<effect_descriptor_t> descriptors;
+ ASSERT_NO_FATAL_FAILURE(listEffectsAvailable(descriptors));
+ for (auto i = 0; i < descriptors.size(); i++) {
+ if (isPreprocessing(descriptors[i])) {
+ capture = new AudioCapture(AUDIO_SOURCE_MIC, sampleRate, format, channelMask);
+ ASSERT_NE(capture, nullptr) << "Unable to create Record Application";
+ EXPECT_EQ(NO_ERROR, capture->create());
+ EXPECT_EQ(NO_ERROR, capture->start());
+ if (!isEffectDefaultOnRecord(&descriptors[i].type, &descriptors[i].uuid,
+ capture->getAudioRecordHandle())) {
+ selectedEffect = i;
+ break;
+ }
+ }
+ }
+ if (selectedEffect == -1) GTEST_SKIP() << " expected at least one preprocessing effect";
+
+ effect_uuid_t* selectedEffectType = &descriptors[selectedEffect].type;
+ effect_uuid_t* selectedEffectUuid = &descriptors[selectedEffect].uuid;
+ auto [type, uuid] = typeAndUuidToString(descriptors[selectedEffect]);
+ capture = new AudioCapture(AUDIO_SOURCE_MIC, sampleRate, format, channelMask);
+ ASSERT_NE(capture, nullptr) << "Unable to create Record Application";
+ EXPECT_EQ(NO_ERROR, capture->create());
+ EXPECT_EQ(NO_ERROR, capture->start());
+ EXPECT_FALSE(isEffectDefaultOnRecord(selectedEffectType, selectedEffectUuid,
+ capture->getAudioRecordHandle()))
+ << "Effect should not have been default on record. " << type;
+ EXPECT_EQ(NO_ERROR,
+ isEffectExistsOnAudioSession(selectedEffectType, selectedEffectUuid,
+ kDefaultInputEffectPriority - 1,
+ capture->getAudioRecordHandle()->getSessionId()))
+ << "Effect should not have been added. " << type;
+ EXPECT_EQ(OK, capture->audioProcess());
+ EXPECT_EQ(OK, capture->stop());
+
+ String16 name{gPackageName};
+ audio_unique_id_t effectId;
+ status_t status = AudioEffect::addSourceDefaultEffect(type.c_str(), name, uuid.c_str(),
+ kDefaultInputEffectPriority,
+ AUDIO_SOURCE_MIC, &effectId);
+ EXPECT_EQ(NO_ERROR, status) << "Adding default effect failed: " << type;
+
+ capture = new AudioCapture(AUDIO_SOURCE_MIC, sampleRate, format, channelMask);
+ ASSERT_NE(capture, nullptr) << "Unable to create Record Application";
+ EXPECT_EQ(NO_ERROR, capture->create());
+ EXPECT_EQ(NO_ERROR, capture->start());
+ EXPECT_TRUE(isEffectDefaultOnRecord(selectedEffectType, selectedEffectUuid,
+ capture->getAudioRecordHandle()))
+ << "Effect should have been default on record. " << type;
+ EXPECT_EQ(ALREADY_EXISTS,
+ isEffectExistsOnAudioSession(selectedEffectType, selectedEffectUuid,
+ kDefaultInputEffectPriority - 1,
+ capture->getAudioRecordHandle()->getSessionId()))
+ << "Effect should have been added. " << type;
+ EXPECT_EQ(OK, capture->audioProcess());
+ EXPECT_EQ(OK, capture->stop());
+
+ status = AudioEffect::removeSourceDefaultEffect(effectId);
+ EXPECT_EQ(NO_ERROR, status);
+ capture = new AudioCapture(AUDIO_SOURCE_MIC, sampleRate, format, channelMask);
+ ASSERT_NE(capture, nullptr) << "Unable to create Record Application";
+ EXPECT_EQ(NO_ERROR, capture->create());
+ EXPECT_EQ(NO_ERROR, capture->start());
+ EXPECT_FALSE(isEffectDefaultOnRecord(selectedEffectType, selectedEffectUuid,
+ capture->getAudioRecordHandle()))
+ << "Effect should not have been default on record. " << type;
+ EXPECT_EQ(NO_ERROR,
+ isEffectExistsOnAudioSession(selectedEffectType, selectedEffectUuid,
+ kDefaultInputEffectPriority - 1,
+ capture->getAudioRecordHandle()->getSessionId()))
+ << "Effect should not have been added. " << type;
+ EXPECT_EQ(OK, capture->audioProcess());
+ EXPECT_EQ(OK, capture->stop());
+}
+
+TEST(AudioEffectTest, AuxEffectSanityTest) {
+ int32_t selectedEffect = -1;
+ std::vector<effect_descriptor_t> descriptors;
+ ASSERT_NO_FATAL_FAILURE(listEffectsAvailable(descriptors));
+ for (auto i = 0; i < descriptors.size(); i++) {
+ if (isAux(descriptors[i])) {
+ selectedEffect = i;
+ break;
+ }
+ }
+ if (selectedEffect == -1) GTEST_SKIP() << "expected at least one aux effect";
+ effect_uuid_t* selectedEffectType = &descriptors[selectedEffect].type;
+ effect_uuid_t* selectedEffectUuid = &descriptors[selectedEffect].uuid;
+ auto [type, uuid] = typeAndUuidToString(descriptors[selectedEffect]);
+ String16 name{gPackageName};
+ audio_session_t sessionId =
+ (audio_session_t)AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
+ sp<AudioEffect> audioEffect = createEffect(selectedEffectType, selectedEffectUuid,
+ kDefaultInputEffectPriority, sessionId);
+ EXPECT_EQ(NO_INIT, audioEffect->initCheck())
+ << "error, creating auxiliary effect (" << type << ") on session id " << (int)sessionId
+ << " successful ";
+ audio_unique_id_t id;
+ status_t status = AudioEffect::addStreamDefaultEffect(
+ type.c_str(), name, uuid.c_str(), kDefaultOutputEffectPriority, AUDIO_USAGE_MEDIA, &id);
+ if (status == NO_ERROR) {
+ EXPECT_EQ(NO_ERROR, AudioEffect::removeStreamDefaultEffect(id));
+ EXPECT_NE(NO_ERROR, status) << "error, adding auxiliary effect (" << type
+ << ") as stream default effect is successful";
+ }
+}
+
+class AudioPlaybackEffectTest : public ::testing::TestWithParam<bool> {
+ public:
+ AudioPlaybackEffectTest() : mSelectFastMode(GetParam()){};
+
+ const bool mSelectFastMode;
+
+ bool mIsFastCompatibleEffect;
+ effect_uuid_t mType;
+ effect_uuid_t mUuid;
+ std::string mTypeStr;
+ std::string mUuidStr;
+
+ void SetUp() override {
+ if (mSelectFastMode) {
+ std::vector<struct audio_port_v7> ports;
+ ASSERT_EQ(OK, listAudioPorts(ports));
+ if (!doesDeviceSupportLowLatencyMode(ports)) {
+ GTEST_SKIP() << "device does not support low latency mode";
+ }
+ }
+
+ int32_t selectedEffect = -1;
+ std::vector<effect_descriptor_t> descriptors;
+ ASSERT_NO_FATAL_FAILURE(listEffectsAvailable(descriptors));
+ for (auto i = 0; i < descriptors.size(); i++) {
+ if (isSpatializer(descriptors[i])) continue;
+ if (isHapticGenerator(descriptors[i]) && !AudioSystem::isHapticPlaybackSupported())
+ continue;
+ if (!isInsert(descriptors[i])) continue;
+ selectedEffect = i;
+ mIsFastCompatibleEffect = isFastCompatible(descriptors[i]);
+ // in fast mode, pick fast compatible effect if available
+ if (mSelectFastMode == mIsFastCompatibleEffect) break;
+ }
+ if (selectedEffect == -1) {
+ GTEST_SKIP() << "expected at least one valid effect";
+ }
+
+ mType = descriptors[selectedEffect].type;
+ mUuid = descriptors[selectedEffect].uuid;
+ std::tie(mTypeStr, mUuidStr) = typeAndUuidToString(descriptors[selectedEffect]);
+ }
+};
+
+TEST_P(AudioPlaybackEffectTest, StreamDefaultEffectTest) {
+ SCOPED_TRACE(testing::Message()
+ << "\n selected effect type is :: " << mTypeStr
+ << "\n selected effect uuid is :: " << mUuidStr
+ << "\n audiotrack output flag : " << (mSelectFastMode ? "fast" : "default")
+ << "\n audio effect is fast compatible : "
+ << (mIsFastCompatibleEffect ? "yes" : "no"));
+
+ bool compatCheck = !mSelectFastMode || (mSelectFastMode && mIsFastCompatibleEffect);
+
+ // create track
+ audio_attributes_t attributes;
+ attributes.usage = AUDIO_USAGE_MEDIA;
+ attributes.content_type = AUDIO_CONTENT_TYPE_MUSIC;
+ auto playback = sp<AudioPlayback>::make(
+ 0 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
+ mSelectFastMode ? AUDIO_OUTPUT_FLAG_FAST : AUDIO_OUTPUT_FLAG_NONE, AUDIO_SESSION_NONE,
+ AudioTrack::TRANSFER_SHARED, &attributes);
+ ASSERT_NE(nullptr, playback);
+ ASSERT_EQ(NO_ERROR, playback->loadResource("/data/local/tmp/bbb_2ch_24kHz_s16le.raw"));
+ EXPECT_EQ(NO_ERROR, playback->create());
+ EXPECT_EQ(NO_ERROR, playback->start());
+ EXPECT_EQ(compatCheck ? NO_ERROR : NO_INIT,
+ isEffectExistsOnAudioSession(&mType, &mUuid, kDefaultOutputEffectPriority - 1,
+ playback->getAudioTrackHandle()->getSessionId()))
+ << "Effect should not have been added. " << mTypeStr;
+ EXPECT_EQ(NO_ERROR, playback->waitForConsumption());
+ playback->stop();
+ playback.clear();
+
+ String16 name{gPackageName};
+ audio_unique_id_t id;
+ status_t status = AudioEffect::addStreamDefaultEffect(mTypeStr.c_str(), name, mUuidStr.c_str(),
+ kDefaultOutputEffectPriority,
+ AUDIO_USAGE_MEDIA, &id);
+ EXPECT_EQ(NO_ERROR, status) << "Adding default effect failed: " << mTypeStr;
+
+ playback = sp<AudioPlayback>::make(
+ 0 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
+ mSelectFastMode ? AUDIO_OUTPUT_FLAG_FAST : AUDIO_OUTPUT_FLAG_NONE, AUDIO_SESSION_NONE,
+ AudioTrack::TRANSFER_SHARED, &attributes);
+ ASSERT_NE(nullptr, playback);
+ ASSERT_EQ(NO_ERROR, playback->loadResource("/data/local/tmp/bbb_2ch_24kHz_s16le.raw"));
+ EXPECT_EQ(NO_ERROR, playback->create());
+ EXPECT_EQ(NO_ERROR, playback->start());
+ // If effect chosen is not compatible with the session, then effect won't be applied
+ EXPECT_EQ(compatCheck ? ALREADY_EXISTS : NO_INIT,
+ isEffectExistsOnAudioSession(&mType, &mUuid, kDefaultOutputEffectPriority - 1,
+ playback->getAudioTrackHandle()->getSessionId()))
+ << "Effect should have been added. " << mTypeStr;
+ EXPECT_EQ(NO_ERROR, playback->waitForConsumption());
+ if (mSelectFastMode) {
+ EXPECT_EQ(AUDIO_OUTPUT_FLAG_FAST,
+ playback->getAudioTrackHandle()->getFlags() & AUDIO_OUTPUT_FLAG_FAST);
+ }
+ playback->stop();
+ playback.clear();
+
+ status = AudioEffect::removeStreamDefaultEffect(id);
+ EXPECT_EQ(NO_ERROR, status);
+ playback = sp<AudioPlayback>::make(
+ 0 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
+ mSelectFastMode ? AUDIO_OUTPUT_FLAG_FAST : AUDIO_OUTPUT_FLAG_NONE, AUDIO_SESSION_NONE,
+ AudioTrack::TRANSFER_SHARED, &attributes);
+ ASSERT_NE(nullptr, playback);
+ ASSERT_EQ(NO_ERROR, playback->loadResource("/data/local/tmp/bbb_2ch_24kHz_s16le.raw"));
+ EXPECT_EQ(NO_ERROR, playback->create());
+ EXPECT_EQ(NO_ERROR, playback->start());
+ EXPECT_EQ(compatCheck ? NO_ERROR : NO_INIT,
+ isEffectExistsOnAudioSession(&mType, &mUuid, kDefaultOutputEffectPriority - 1,
+ playback->getAudioTrackHandle()->getSessionId()))
+ << "Effect should not have been added. " << mTypeStr;
+ EXPECT_EQ(NO_ERROR, playback->waitForConsumption());
+ playback->stop();
+ playback.clear();
+}
+
+TEST_P(AudioPlaybackEffectTest, CheckOutputFlagCompatibility) {
+ SCOPED_TRACE(testing::Message()
+ << "\n selected effect type is :: " << mTypeStr
+ << "\n selected effect uuid is :: " << mUuidStr
+ << "\n audiotrack output flag : " << (mSelectFastMode ? "fast" : "default")
+ << "\n audio effect is fast compatible : "
+ << (mIsFastCompatibleEffect ? "yes" : "no"));
+
+ audio_attributes_t attributes;
+ attributes.usage = AUDIO_USAGE_MEDIA;
+ attributes.content_type = AUDIO_CONTENT_TYPE_MUSIC;
+ audio_session_t sessionId =
+ (audio_session_t)AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
+ sp<AudioEffectCallback> cb = sp<AudioEffectCallback>::make();
+ sp<AudioEffect> audioEffect =
+ createEffect(&mType, &mUuid, kDefaultOutputEffectPriority, sessionId, cb);
+ ASSERT_EQ(OK, audioEffect->initCheck());
+ ASSERT_EQ(NO_ERROR, audioEffect->setEnabled(true));
+ auto playback = sp<AudioPlayback>::make(
+ 0 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_MONO,
+ mSelectFastMode ? AUDIO_OUTPUT_FLAG_FAST : AUDIO_OUTPUT_FLAG_NONE, sessionId,
+ AudioTrack::TRANSFER_SHARED, &attributes);
+ ASSERT_NE(nullptr, playback);
+ ASSERT_EQ(NO_ERROR, playback->loadResource("/data/local/tmp/bbb_1ch_8kHz_s16le.raw"));
+ EXPECT_EQ(NO_ERROR, playback->create());
+ EXPECT_EQ(NO_ERROR, playback->start());
+
+ EXPECT_EQ(ALREADY_EXISTS, isEffectExistsOnAudioSession(
+ &mType, &mUuid, kDefaultOutputEffectPriority - 1, sessionId))
+ << "Effect should have been added. " << mTypeStr;
+ if (mSelectFastMode) {
+ EXPECT_EQ(mIsFastCompatibleEffect ? AUDIO_OUTPUT_FLAG_FAST : 0,
+ playback->getAudioTrackHandle()->getFlags() & AUDIO_OUTPUT_FLAG_FAST);
+ }
+ EXPECT_EQ(NO_ERROR, playback->waitForConsumption());
+ EXPECT_EQ(NO_ERROR, playback->getAudioTrackHandle()->attachAuxEffect(0));
+ playback->stop();
+ playback.clear();
+ EXPECT_TRUE(cb->receivedFramesProcessed)
+ << "AudioEffect frames processed callback not received";
+}
+
+INSTANTIATE_TEST_SUITE_P(EffectParameterizedTests, AudioPlaybackEffectTest, ::testing::Bool());
+
+TEST(AudioEffectTest, TestHapticEffect) {
+ if (!AudioSystem::isHapticPlaybackSupported())
+ GTEST_SKIP() << "Haptic playback is not supported";
+ int32_t selectedEffect = -1;
+ std::vector<effect_descriptor_t> descriptors;
+ ASSERT_NO_FATAL_FAILURE(listEffectsAvailable(descriptors));
+ for (auto i = 0; i < descriptors.size(); i++) {
+ if (!isHapticGenerator(descriptors[i])) continue;
+ selectedEffect = i;
+ break;
+ }
+ if (selectedEffect == -1) GTEST_SKIP() << "expected at least one valid effect";
+
+ effect_uuid_t* selectedEffectType = &descriptors[selectedEffect].type;
+ effect_uuid_t* selectedEffectUuid = &descriptors[selectedEffect].uuid;
+ auto [type, uuid] = typeAndUuidToString(descriptors[selectedEffect]);
+
+ SCOPED_TRACE(testing::Message() << "\n selected effect type is :: " << type
+ << "\n selected effect uuid is :: " << uuid);
+
+ audio_attributes_t attributes;
+ attributes.usage = AUDIO_USAGE_MEDIA;
+ attributes.content_type = AUDIO_CONTENT_TYPE_MUSIC;
+ audio_session_t sessionId =
+ (audio_session_t)AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
+ sp<AudioEffectCallback> cb = sp<AudioEffectCallback>::make();
+ sp<AudioEffect> audioEffect = createEffect(selectedEffectType, selectedEffectUuid,
+ kDefaultOutputEffectPriority, sessionId, cb);
+ ASSERT_EQ(OK, audioEffect->initCheck());
+ ASSERT_EQ(NO_ERROR, audioEffect->setEnabled(true));
+ auto playback = sp<AudioPlayback>::make(0 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT,
+ AUDIO_CHANNEL_OUT_STEREO, AUDIO_OUTPUT_FLAG_NONE,
+ sessionId, AudioTrack::TRANSFER_SHARED, &attributes);
+ ASSERT_NE(nullptr, playback);
+ ASSERT_EQ(NO_ERROR, playback->loadResource("/data/local/tmp/bbb_2ch_24kHz_s16le.raw"));
+ EXPECT_EQ(NO_ERROR, playback->create());
+ EXPECT_EQ(NO_ERROR, playback->start());
+ EXPECT_TRUE(isEffectExistsOnAudioSession(selectedEffectType, selectedEffectUuid,
+ kDefaultOutputEffectPriority - 1, sessionId))
+ << "Effect should have been added. " << type;
+ EXPECT_EQ(NO_ERROR, playback->waitForConsumption());
+ playback->stop();
+ playback.clear();
+ EXPECT_TRUE(cb->receivedFramesProcessed)
+ << "AudioEffect frames processed callback not received";
+}
diff --git a/media/libaudioclient/tests/audiorecord_tests.cpp b/media/libaudioclient/tests/audiorecord_tests.cpp
new file mode 100644
index 0000000..8c63a6d
--- /dev/null
+++ b/media/libaudioclient/tests/audiorecord_tests.cpp
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "AudioRecordTest"
+
+#include <gtest/gtest.h>
+
+#include "audio_test_utils.h"
+
+using namespace android;
+
+class AudioRecordTest : public ::testing::Test {
+ public:
+ virtual void SetUp() override {
+ mAC = new AudioCapture(AUDIO_SOURCE_DEFAULT, 44100, AUDIO_FORMAT_PCM_16_BIT,
+ AUDIO_CHANNEL_IN_FRONT);
+ ASSERT_NE(nullptr, mAC);
+ ASSERT_EQ(OK, mAC->create()) << "record creation failed";
+ }
+
+ virtual void TearDown() override {
+ if (mAC) ASSERT_EQ(OK, mAC->stop());
+ }
+
+ sp<AudioCapture> mAC;
+};
+
+class AudioRecordCreateTest
+ : public ::testing::TestWithParam<
+ std::tuple<uint32_t, audio_format_t, audio_channel_mask_t, audio_input_flags_t,
+ audio_session_t, audio_source_t>> {
+ public:
+ AudioRecordCreateTest()
+ : mSampleRate(std::get<0>(GetParam())),
+ mFormat(std::get<1>(GetParam())),
+ mChannelMask(std::get<2>(GetParam())),
+ mFlags(std::get<3>(GetParam())),
+ mSessionId(std::get<4>(GetParam())),
+ mInputSource(std::get<5>(GetParam())){};
+
+ const uint32_t mSampleRate;
+ const audio_format_t mFormat;
+ const audio_channel_mask_t mChannelMask;
+ const audio_input_flags_t mFlags;
+ const audio_session_t mSessionId;
+ const audio_source_t mInputSource;
+ const AudioRecord::transfer_type mTransferType = AudioRecord::TRANSFER_OBTAIN;
+
+ sp<AudioCapture> mAC;
+
+ virtual void SetUp() override {
+ mAC = new AudioCapture(mInputSource, mSampleRate, mFormat, mChannelMask, mFlags, mSessionId,
+ mTransferType);
+ ASSERT_NE(nullptr, mAC);
+ ASSERT_EQ(OK, mAC->create()) << "record creation failed";
+ }
+
+ virtual void TearDown() override {
+ if (mAC) ASSERT_EQ(OK, mAC->stop());
+ }
+};
+
+TEST_F(AudioRecordTest, TestSimpleRecord) {
+ EXPECT_EQ(OK, mAC->start()) << "start recording failed";
+ EXPECT_EQ(OK, mAC->audioProcess()) << "audioProcess failed";
+}
+
+TEST_F(AudioRecordTest, TestAudioCbNotifier) {
+ EXPECT_EQ(BAD_VALUE, mAC->getAudioRecordHandle()->addAudioDeviceCallback(nullptr));
+ sp<OnAudioDeviceUpdateNotifier> cb = sp<OnAudioDeviceUpdateNotifier>::make();
+ sp<OnAudioDeviceUpdateNotifier> cbOld = sp<OnAudioDeviceUpdateNotifier>::make();
+ EXPECT_EQ(OK, mAC->getAudioRecordHandle()->addAudioDeviceCallback(cbOld));
+ EXPECT_EQ(INVALID_OPERATION, mAC->getAudioRecordHandle()->addAudioDeviceCallback(cbOld));
+ EXPECT_EQ(OK, mAC->getAudioRecordHandle()->addAudioDeviceCallback(cb));
+ EXPECT_EQ(OK, mAC->start()) << "record creation failed";
+ EXPECT_EQ(OK, cb->waitForAudioDeviceCb());
+ EXPECT_EQ(AUDIO_IO_HANDLE_NONE, cbOld->mAudioIo);
+ EXPECT_EQ(AUDIO_PORT_HANDLE_NONE, cbOld->mDeviceId);
+ EXPECT_NE(AUDIO_IO_HANDLE_NONE, cb->mAudioIo);
+ EXPECT_NE(AUDIO_PORT_HANDLE_NONE, cb->mDeviceId);
+ EXPECT_EQ(BAD_VALUE, mAC->getAudioRecordHandle()->removeAudioDeviceCallback(nullptr));
+ EXPECT_EQ(INVALID_OPERATION, mAC->getAudioRecordHandle()->removeAudioDeviceCallback(cbOld));
+ EXPECT_EQ(OK, mAC->getAudioRecordHandle()->removeAudioDeviceCallback(cb));
+ mAC->stop();
+}
+
+TEST_F(AudioRecordTest, TestEventRecordTrackPause) {
+ const auto playback = sp<AudioPlayback>::make(
+ 8000 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_MONO);
+ ASSERT_EQ(OK, playback->loadResource("/data/local/tmp/bbb_1ch_8kHz_s16le.raw"))
+ << "Unable to open Resource";
+ EXPECT_EQ(OK, playback->create()) << "AudioTrack Creation failed";
+ audio_session_t audioTrackSession = playback->getAudioTrackHandle()->getSessionId();
+ EXPECT_EQ(OK, mAC->start(AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE, audioTrackSession))
+ << "record creation failed";
+ EXPECT_EQ(OK, playback->start());
+ RawBuffer buffer;
+ status_t status = mAC->obtainBufferCb(buffer);
+ EXPECT_EQ(status, TIMED_OUT) << "Not expecting any callbacks until track sends Sync event";
+ playback->getAudioTrackHandle()->pause();
+ EXPECT_EQ(OK, mAC->audioProcess()) << "audioProcess failed";
+ playback->stop();
+}
+
+TEST_F(AudioRecordTest, TestEventRecordTrackStop) {
+ const auto playback = sp<AudioPlayback>::make(
+ 8000 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_MONO);
+ ASSERT_EQ(OK, playback->loadResource("/data/local/tmp/bbb_1ch_8kHz_s16le.raw"))
+ << "Unable to open Resource";
+ EXPECT_EQ(OK, playback->create()) << "AudioTrack Creation failed";
+ audio_session_t audioTrackSession = playback->getAudioTrackHandle()->getSessionId();
+ EXPECT_EQ(OK, mAC->start(AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE, audioTrackSession))
+ << "record creation failed";
+ EXPECT_EQ(OK, playback->start());
+ RawBuffer buffer;
+ status_t status = mAC->obtainBufferCb(buffer);
+ EXPECT_EQ(status, TIMED_OUT) << "Not expecting any callbacks until track sends Sync event";
+ playback->stop();
+ EXPECT_EQ(OK, mAC->audioProcess()) << "audioProcess failed";
+}
+
+TEST_F(AudioRecordTest, TestGetSetMarker) {
+ mAC->mMarkerPosition = (mAC->mNotificationFrames << 3) + (mAC->mNotificationFrames >> 1);
+ EXPECT_EQ(OK, mAC->getAudioRecordHandle()->setMarkerPosition(mAC->mMarkerPosition))
+ << "setMarkerPosition() failed";
+ uint32_t marker;
+ EXPECT_EQ(OK, mAC->getAudioRecordHandle()->getMarkerPosition(&marker))
+ << "getMarkerPosition() failed";
+ EXPECT_EQ(OK, mAC->start()) << "start recording failed";
+ EXPECT_EQ(OK, mAC->audioProcess()) << "audioProcess failed";
+ EXPECT_EQ(marker, mAC->mMarkerPosition)
+ << "configured marker and received marker are different";
+ EXPECT_EQ(mAC->mReceivedCbMarkerAtPosition, mAC->mMarkerPosition)
+ << "configured marker and received cb marker are different";
+}
+
+TEST_F(AudioRecordTest, TestGetSetMarkerPeriodical) {
+ mAC->mMarkerPeriod = (mAC->mNotificationFrames << 3) + (mAC->mNotificationFrames >> 1);
+ EXPECT_EQ(OK, mAC->getAudioRecordHandle()->setPositionUpdatePeriod(mAC->mMarkerPeriod))
+ << "setPositionUpdatePeriod() failed";
+ uint32_t marker;
+ EXPECT_EQ(OK, mAC->getAudioRecordHandle()->getPositionUpdatePeriod(&marker))
+ << "getPositionUpdatePeriod() failed";
+ EXPECT_EQ(OK, mAC->start()) << "start recording failed";
+ EXPECT_EQ(OK, mAC->audioProcess()) << "audioProcess failed";
+ EXPECT_EQ(marker, mAC->mMarkerPeriod) << "configured marker and received marker are different";
+ EXPECT_EQ(mAC->mReceivedCbMarkerCount, mAC->mNumFramesToRecord / mAC->mMarkerPeriod)
+ << "configured marker and received cb marker are different";
+}
+
+TEST_F(AudioRecordTest, TestGetPosition) {
+ uint32_t position;
+ EXPECT_EQ(OK, mAC->getAudioRecordHandle()->getPosition(&position)) << "getPosition() failed";
+ EXPECT_EQ(0, position);
+ EXPECT_EQ(OK, mAC->start()) << "start recording failed";
+ EXPECT_EQ(OK, mAC->audioProcess()) << "audioProcess failed";
+ EXPECT_EQ(OK, mAC->stop());
+ EXPECT_EQ(OK, mAC->getAudioRecordHandle()->getPosition(&position)) << "getPosition() failed";
+}
+
+// TODO: Add checkPatchCapture(), verify the information of patch via dumpPort() and dumpPatch()
+TEST_P(AudioRecordCreateTest, TestCreateRecord) {
+ EXPECT_EQ(mFormat, mAC->getAudioRecordHandle()->format());
+ EXPECT_EQ(audio_channel_count_from_in_mask(mChannelMask),
+ mAC->getAudioRecordHandle()->channelCount());
+ if (mAC->mFrameCount != 0)
+ EXPECT_LE(mAC->mFrameCount, mAC->getAudioRecordHandle()->frameCount());
+ EXPECT_EQ(mInputSource, mAC->getAudioRecordHandle()->inputSource());
+ if (mSampleRate != 0) EXPECT_EQ(mSampleRate, mAC->getAudioRecordHandle()->getSampleRate());
+ if (mSessionId != AUDIO_SESSION_NONE)
+ EXPECT_EQ(mSessionId, mAC->getAudioRecordHandle()->getSessionId());
+ if (mTransferType != AudioRecord::TRANSFER_CALLBACK) {
+ uint32_t marker;
+ mAC->mMarkerPosition = (mAC->mNotificationFrames << 3) + (mAC->mNotificationFrames >> 1);
+ EXPECT_EQ(INVALID_OPERATION,
+ mAC->getAudioRecordHandle()->setMarkerPosition(mAC->mMarkerPosition));
+ EXPECT_EQ(OK, mAC->getAudioRecordHandle()->getMarkerPosition(&marker));
+ EXPECT_EQ(INVALID_OPERATION,
+ mAC->getAudioRecordHandle()->setPositionUpdatePeriod(mAC->mMarkerPosition));
+ EXPECT_EQ(OK, mAC->getAudioRecordHandle()->getPositionUpdatePeriod(&marker));
+ }
+ EXPECT_EQ(OK, mAC->start()) << "start recording failed";
+ EXPECT_EQ(OK, mAC->audioProcess()) << "audioProcess failed";
+}
+
+// for port primary input
+INSTANTIATE_TEST_SUITE_P(AudioRecordPrimaryInput, AudioRecordCreateTest,
+ ::testing::Combine(::testing::Values(8000, 11025, 12000, 16000, 22050,
+ 24000, 32000, 44100, 48000),
+ ::testing::Values(AUDIO_FORMAT_PCM_8_24_BIT),
+ ::testing::Values(AUDIO_CHANNEL_IN_MONO,
+ AUDIO_CHANNEL_IN_STEREO,
+ AUDIO_CHANNEL_IN_FRONT_BACK),
+ ::testing::Values(AUDIO_INPUT_FLAG_NONE),
+ ::testing::Values(AUDIO_SESSION_NONE),
+ ::testing::Values(AUDIO_SOURCE_DEFAULT)));
+
+// for port fast input
+INSTANTIATE_TEST_SUITE_P(AudioRecordFastInput, AudioRecordCreateTest,
+ ::testing::Combine(::testing::Values(8000, 11025, 12000, 16000, 22050,
+ 24000, 32000, 44100, 48000),
+ ::testing::Values(AUDIO_FORMAT_PCM_8_24_BIT),
+ ::testing::Values(AUDIO_CHANNEL_IN_MONO,
+ AUDIO_CHANNEL_IN_STEREO,
+ AUDIO_CHANNEL_IN_FRONT_BACK),
+ ::testing::Values(AUDIO_INPUT_FLAG_FAST),
+ ::testing::Values(AUDIO_SESSION_NONE),
+ ::testing::Values(AUDIO_SOURCE_DEFAULT)));
+
+// misc
+INSTANTIATE_TEST_SUITE_P(AudioRecordMiscInput, AudioRecordCreateTest,
+ ::testing::Combine(::testing::Values(48000),
+ ::testing::Values(AUDIO_FORMAT_PCM_16_BIT),
+ ::testing::Values(AUDIO_CHANNEL_IN_MONO),
+ ::testing::Values(AUDIO_INPUT_FLAG_NONE),
+ ::testing::Values(AUDIO_SESSION_NONE),
+ ::testing::Values(AUDIO_SOURCE_MIC,
+ AUDIO_SOURCE_CAMCORDER,
+ AUDIO_SOURCE_VOICE_RECOGNITION,
+ AUDIO_SOURCE_VOICE_COMMUNICATION,
+ AUDIO_SOURCE_UNPROCESSED)));
diff --git a/media/libaudioclient/tests/audiorouting_tests.cpp b/media/libaudioclient/tests/audiorouting_tests.cpp
new file mode 100644
index 0000000..2c5fcd7
--- /dev/null
+++ b/media/libaudioclient/tests/audiorouting_tests.cpp
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+
+#include <cutils/properties.h>
+#include <gtest/gtest.h>
+#include <string.h>
+
+#include "audio_test_utils.h"
+
+using namespace android;
+
+// UNIT TEST
+TEST(AudioTrackTest, TestPerformanceMode) {
+ std::vector<struct audio_port_v7> ports;
+ ASSERT_EQ(OK, listAudioPorts(ports));
+ audio_output_flags_t output_flags[] = {AUDIO_OUTPUT_FLAG_FAST, AUDIO_OUTPUT_FLAG_DEEP_BUFFER};
+ audio_flags_mask_t flags[] = {AUDIO_FLAG_LOW_LATENCY, AUDIO_FLAG_DEEP_BUFFER};
+ bool hasFlag = false;
+ for (int i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
+ hasFlag = false;
+ for (const auto& port : ports) {
+ if (port.role == AUDIO_PORT_ROLE_SOURCE && port.type == AUDIO_PORT_TYPE_MIX) {
+ if ((port.active_config.flags.output & output_flags[i]) != 0) {
+ hasFlag = true;
+ break;
+ }
+ }
+ }
+ if (!hasFlag) continue;
+ audio_attributes_t attributes = AUDIO_ATTRIBUTES_INITIALIZER;
+ attributes.usage = AUDIO_USAGE_MEDIA;
+ attributes.content_type = AUDIO_CONTENT_TYPE_MUSIC;
+ attributes.flags = flags[i];
+ sp<AudioPlayback> ap = sp<AudioPlayback>::make(0 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT,
+ AUDIO_CHANNEL_OUT_STEREO,
+ AUDIO_OUTPUT_FLAG_NONE, AUDIO_SESSION_NONE,
+ AudioTrack::TRANSFER_OBTAIN, &attributes);
+ ASSERT_NE(nullptr, ap);
+ ASSERT_EQ(OK, ap->loadResource("/data/local/tmp/bbb_2ch_24kHz_s16le.raw"))
+ << "Unable to open Resource";
+ EXPECT_EQ(OK, ap->create()) << "track creation failed";
+ sp<OnAudioDeviceUpdateNotifier> cb = sp<OnAudioDeviceUpdateNotifier>::make();
+ EXPECT_EQ(OK, ap->getAudioTrackHandle()->addAudioDeviceCallback(cb));
+ EXPECT_EQ(OK, ap->start()) << "audio track start failed";
+ EXPECT_EQ(OK, ap->onProcess());
+ EXPECT_EQ(OK, cb->waitForAudioDeviceCb());
+ EXPECT_TRUE(checkPatchPlayback(cb->mAudioIo, cb->mDeviceId));
+ EXPECT_NE(0, ap->getAudioTrackHandle()->getFlags() & output_flags[i]);
+ audio_patch patch;
+ EXPECT_EQ(OK, getPatchForOutputMix(cb->mAudioIo, patch));
+ for (auto j = 0; j < patch.num_sources; j++) {
+ if (patch.sources[j].type == AUDIO_PORT_TYPE_MIX &&
+ patch.sources[j].ext.mix.handle == cb->mAudioIo) {
+ if ((patch.sources[j].flags.output & output_flags[i]) == 0) {
+ ADD_FAILURE() << "expected output flag " << output_flags[i] << " is absent";
+ std::cerr << dumpPortConfig(patch.sources[j]);
+ }
+ }
+ }
+ ap->stop();
+ ap->getAudioTrackHandle()->removeAudioDeviceCallback(cb);
+ }
+}
+
+TEST(AudioTrackTest, DefaultRoutingTest) {
+ audio_port_v7 port;
+ if (OK != getPortByAttributes(AUDIO_PORT_ROLE_SOURCE, AUDIO_PORT_TYPE_DEVICE,
+ AUDIO_DEVICE_IN_REMOTE_SUBMIX, "0", port)) {
+ GTEST_SKIP() << "remote submix in device not connected";
+ }
+
+ // create record instance
+ sp<AudioCapture> capture = sp<AudioCapture>::make(
+ AUDIO_SOURCE_REMOTE_SUBMIX, 48000, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO);
+ ASSERT_NE(nullptr, capture);
+ EXPECT_EQ(OK, capture->create()) << "record creation failed";
+ sp<OnAudioDeviceUpdateNotifier> cbCapture = sp<OnAudioDeviceUpdateNotifier>::make();
+ EXPECT_EQ(OK, capture->getAudioRecordHandle()->addAudioDeviceCallback(cbCapture));
+
+ // create playback instance
+ sp<AudioPlayback> playback = sp<AudioPlayback>::make(
+ 48000 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
+ AUDIO_OUTPUT_FLAG_NONE, AUDIO_SESSION_NONE);
+ ASSERT_NE(nullptr, playback);
+ ASSERT_EQ(OK, playback->loadResource("/data/local/tmp/bbb_2ch_24kHz_s16le.raw"))
+ << "Unable to open Resource";
+ EXPECT_EQ(OK, playback->create()) << "track creation failed";
+ sp<OnAudioDeviceUpdateNotifier> cbPlayback = sp<OnAudioDeviceUpdateNotifier>::make();
+ EXPECT_EQ(OK, playback->getAudioTrackHandle()->addAudioDeviceCallback(cbPlayback));
+
+ // capture should be routed to submix in port
+ EXPECT_EQ(OK, capture->start()) << "start recording failed";
+ EXPECT_EQ(OK, cbCapture->waitForAudioDeviceCb());
+ EXPECT_EQ(port.id, capture->getAudioRecordHandle()->getRoutedDeviceId())
+ << "Capture NOT routed on expected port";
+
+ // capture start should create submix out port
+ status_t status = getPortByAttributes(AUDIO_PORT_ROLE_SINK, AUDIO_PORT_TYPE_DEVICE,
+ AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "0", port);
+ EXPECT_EQ(OK, status) << "Could not find port";
+
+ // playback should be routed to submix out as long as capture is active
+ EXPECT_EQ(OK, playback->start()) << "audio track start failed";
+ EXPECT_EQ(OK, cbPlayback->waitForAudioDeviceCb());
+ EXPECT_EQ(port.id, playback->getAudioTrackHandle()->getRoutedDeviceId())
+ << "Playback NOT routed on expected port";
+
+ capture->stop();
+ playback->stop();
+}
+
+class AudioRoutingTest : public ::testing::Test {
+ public:
+ void SetUp() override {
+ audio_port_v7 port;
+ if (OK != getPortByAttributes(AUDIO_PORT_ROLE_SOURCE, AUDIO_PORT_TYPE_DEVICE,
+ AUDIO_DEVICE_IN_REMOTE_SUBMIX, "0", port)) {
+ GTEST_SKIP() << "remote submix in device not connected";
+ }
+ uint32_t mixType = MIX_TYPE_PLAYERS;
+ uint32_t mixFlag = MIX_ROUTE_FLAG_LOOP_BACK;
+ audio_devices_t deviceType = AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
+ AudioMixMatchCriterion criterion(AUDIO_USAGE_MEDIA, AUDIO_SOURCE_DEFAULT,
+ RULE_MATCH_ATTRIBUTE_USAGE);
+ std::vector<AudioMixMatchCriterion> criteria{criterion};
+ audio_config_t config = AUDIO_CONFIG_INITIALIZER;
+ config.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+ config.format = AUDIO_FORMAT_PCM_16_BIT;
+ config.sample_rate = 48000;
+ AudioMix mix(criteria, mixType, config, mixFlag, String8{mAddress.c_str()}, 0);
+ mix.mDeviceType = deviceType;
+ mMixes.push(mix);
+ if (OK == AudioSystem::registerPolicyMixes(mMixes, true)) {
+ mPolicyMixRegistered = true;
+ }
+ ASSERT_TRUE(mPolicyMixRegistered) << "register policy mix failed";
+ }
+
+ void TearDown() override {
+ if (mPolicyMixRegistered) {
+ EXPECT_EQ(OK, AudioSystem::registerPolicyMixes(mMixes, false));
+ }
+ }
+
+ bool mPolicyMixRegistered{false};
+ std::string mAddress{"mix_1"};
+ Vector<AudioMix> mMixes;
+};
+
+TEST_F(AudioRoutingTest, ConcurrentDynamicRoutingTest) {
+ audio_port_v7 port, port_mix;
+ // expect legacy submix in port to be connected
+ status_t status = getPortByAttributes(AUDIO_PORT_ROLE_SOURCE, AUDIO_PORT_TYPE_DEVICE,
+ AUDIO_DEVICE_IN_REMOTE_SUBMIX, "0", port);
+ EXPECT_EQ(OK, status) << "Could not find port";
+
+ // as policy mix is registered, expect submix in port with mAddress to be connected
+ status = getPortByAttributes(AUDIO_PORT_ROLE_SOURCE, AUDIO_PORT_TYPE_DEVICE,
+ AUDIO_DEVICE_IN_REMOTE_SUBMIX, mAddress, port_mix);
+ EXPECT_EQ(OK, status) << "Could not find port";
+
+ // create playback instance
+ sp<AudioPlayback> playback = sp<AudioPlayback>::make(
+ 48000 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
+ AUDIO_OUTPUT_FLAG_NONE, AUDIO_SESSION_NONE, AudioTrack::TRANSFER_OBTAIN);
+ ASSERT_NE(nullptr, playback);
+ ASSERT_EQ(OK, playback->loadResource("/data/local/tmp/bbb_2ch_24kHz_s16le.raw"))
+ << "Unable to open Resource";
+ EXPECT_EQ(OK, playback->create()) << "track creation failed";
+ sp<OnAudioDeviceUpdateNotifier> cbPlayback = sp<OnAudioDeviceUpdateNotifier>::make();
+ EXPECT_EQ(OK, playback->getAudioTrackHandle()->addAudioDeviceCallback(cbPlayback));
+
+ // create capture instances on different ports
+ sp<AudioCapture> captureA = sp<AudioCapture>::make(
+ AUDIO_SOURCE_REMOTE_SUBMIX, 48000, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO);
+ ASSERT_NE(nullptr, captureA);
+ EXPECT_EQ(OK, captureA->create()) << "record creation failed";
+ sp<OnAudioDeviceUpdateNotifier> cbCaptureA = sp<OnAudioDeviceUpdateNotifier>::make();
+ EXPECT_EQ(OK, captureA->getAudioRecordHandle()->addAudioDeviceCallback(cbCaptureA));
+
+ audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER;
+ attr.source = AUDIO_SOURCE_REMOTE_SUBMIX;
+ sprintf(attr.tags, "addr=%s", mAddress.c_str());
+ sp<AudioCapture> captureB = sp<AudioCapture>::make(
+ AUDIO_SOURCE_REMOTE_SUBMIX, 48000, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
+ AUDIO_INPUT_FLAG_NONE, AUDIO_SESSION_ALLOCATE, AudioRecord::TRANSFER_CALLBACK, &attr);
+ ASSERT_NE(nullptr, captureB);
+ EXPECT_EQ(OK, captureB->create()) << "record creation failed";
+ sp<OnAudioDeviceUpdateNotifier> cbCaptureB = sp<OnAudioDeviceUpdateNotifier>::make();
+ EXPECT_EQ(OK, captureB->getAudioRecordHandle()->addAudioDeviceCallback(cbCaptureB));
+
+ // launch
+ EXPECT_EQ(OK, captureA->start()) << "start recording failed";
+ EXPECT_EQ(OK, cbCaptureA->waitForAudioDeviceCb());
+ EXPECT_EQ(port.id, captureA->getAudioRecordHandle()->getRoutedDeviceId())
+ << "Capture NOT routed on expected port";
+
+ EXPECT_EQ(OK, captureB->start()) << "start recording failed";
+ EXPECT_EQ(OK, cbCaptureB->waitForAudioDeviceCb());
+ EXPECT_EQ(port_mix.id, captureB->getAudioRecordHandle()->getRoutedDeviceId())
+ << "Capture NOT routed on expected port";
+
+ // as record started, expect submix out ports to be connected
+ status = getPortByAttributes(AUDIO_PORT_ROLE_SINK, AUDIO_PORT_TYPE_DEVICE,
+ AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "0", port);
+ EXPECT_EQ(OK, status) << "unexpected submix out port found";
+
+ status = getPortByAttributes(AUDIO_PORT_ROLE_SINK, AUDIO_PORT_TYPE_DEVICE,
+ AUDIO_DEVICE_OUT_REMOTE_SUBMIX, mAddress, port_mix);
+ EXPECT_EQ(OK, status) << "Could not find port";
+
+ // check if playback routed to desired port
+ EXPECT_EQ(OK, playback->start());
+ EXPECT_EQ(OK, cbPlayback->waitForAudioDeviceCb());
+ EXPECT_EQ(port_mix.id, playback->getAudioTrackHandle()->getRoutedDeviceId())
+ << "Playback NOT routed on expected port";
+
+ captureB->stop();
+
+ // check if mAddress submix out is disconnected as capture session is stopped
+ status = getPortByAttributes(AUDIO_PORT_ROLE_SINK, AUDIO_PORT_TYPE_DEVICE,
+ AUDIO_DEVICE_OUT_REMOTE_SUBMIX, mAddress, port_mix);
+ EXPECT_NE(OK, status) << "unexpected submix in port found";
+
+ // check if legacy submix out is connected
+ status = getPortByAttributes(AUDIO_PORT_ROLE_SINK, AUDIO_PORT_TYPE_DEVICE,
+ AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "0", port);
+ EXPECT_EQ(OK, status) << "port not found";
+
+ // unregister policy
+ EXPECT_EQ(OK, AudioSystem::registerPolicyMixes(mMixes, false));
+ mPolicyMixRegistered = false;
+
+ // as policy mix is unregistered, expect submix in port with mAddress to be disconnected
+ status = getPortByAttributes(AUDIO_PORT_ROLE_SOURCE, AUDIO_PORT_TYPE_DEVICE,
+ AUDIO_DEVICE_IN_REMOTE_SUBMIX, mAddress, port_mix);
+ EXPECT_NE(OK, status) << "unexpected submix in port found";
+
+ playback->onProcess();
+ // as captureA is active, it should re route to legacy submix
+ EXPECT_EQ(OK, cbPlayback->waitForAudioDeviceCb(port.id));
+ EXPECT_EQ(port.id, playback->getAudioTrackHandle()->getRoutedDeviceId())
+ << "Playback NOT routed on expected port";
+
+ captureA->stop();
+ playback->stop();
+}
diff --git a/media/libaudioclient/tests/audiosystem_tests.cpp b/media/libaudioclient/tests/audiosystem_tests.cpp
new file mode 100644
index 0000000..aed847c
--- /dev/null
+++ b/media/libaudioclient/tests/audiosystem_tests.cpp
@@ -0,0 +1,573 @@
+/*
+ * Copyright (C) 2021 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 "AudioSystemTest"
+
+#include <string.h>
+
+#include <gtest/gtest.h>
+#include <media/IAudioFlinger.h>
+#include <utils/Log.h>
+
+#include "audio_test_utils.h"
+
+using namespace android;
+
+void anyPatchContainsInputDevice(audio_port_handle_t deviceId, bool& res) {
+ std::vector<struct audio_patch> patches;
+ status_t status = listAudioPatches(patches);
+ ASSERT_EQ(OK, status);
+ res = false;
+ for (const auto& patch : patches) {
+ if (patchContainsInputDevice(deviceId, patch)) {
+ res = true;
+ return;
+ }
+ }
+}
+
+class AudioSystemTest : public ::testing::Test {
+ public:
+ void SetUp() override {
+ mAF = AudioSystem::get_audio_flinger();
+ ASSERT_NE(mAF, nullptr) << "Permission denied";
+ }
+
+ void TearDown() override {
+ if (mPlayback) {
+ mPlayback->stop();
+ mPlayback->getAudioTrackHandle()->removeAudioDeviceCallback(mCbPlayback);
+ mPlayback.clear();
+ }
+ if (mCapture) {
+ mCapture->stop();
+ mCapture->getAudioRecordHandle()->removeAudioDeviceCallback(mCbRecord);
+ mCapture.clear();
+ }
+ }
+
+ void createPlaybackSession(void);
+ void createRecordSession(void);
+
+ sp<IAudioFlinger> mAF;
+ sp<AudioPlayback> mPlayback;
+ sp<OnAudioDeviceUpdateNotifier> mCbPlayback;
+ sp<AudioCapture> mCapture;
+ sp<OnAudioDeviceUpdateNotifier> mCbRecord;
+};
+
+void AudioSystemTest::createPlaybackSession(void) {
+ audio_attributes_t attributes = AUDIO_ATTRIBUTES_INITIALIZER;
+ attributes.usage = AUDIO_USAGE_MEDIA;
+ attributes.content_type = AUDIO_CONTENT_TYPE_MUSIC;
+ mPlayback = sp<AudioPlayback>::make(48000, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
+ AUDIO_OUTPUT_FLAG_FAST, AUDIO_SESSION_NONE,
+ AudioTrack::TRANSFER_SHARED, &attributes);
+ ASSERT_NE(nullptr, mPlayback);
+ ASSERT_EQ(NO_ERROR, mPlayback->loadResource("/data/local/tmp/bbb_2ch_24kHz_s16le.raw"));
+ EXPECT_EQ(NO_ERROR, mPlayback->create());
+ mCbPlayback = sp<OnAudioDeviceUpdateNotifier>::make();
+ EXPECT_EQ(OK, mPlayback->getAudioTrackHandle()->addAudioDeviceCallback(mCbPlayback));
+ EXPECT_EQ(NO_ERROR, mPlayback->start());
+ EXPECT_EQ(OK, mPlayback->onProcess());
+ EXPECT_EQ(OK, mCbPlayback->waitForAudioDeviceCb());
+}
+
+void AudioSystemTest::createRecordSession(void) {
+ mCapture = new AudioCapture(AUDIO_SOURCE_DEFAULT, 44100, AUDIO_FORMAT_PCM_8_24_BIT,
+ AUDIO_CHANNEL_IN_MONO, AUDIO_INPUT_FLAG_FAST);
+ ASSERT_NE(nullptr, mCapture);
+ ASSERT_EQ(OK, mCapture->create()) << "record creation failed";
+ mCbRecord = sp<OnAudioDeviceUpdateNotifier>::make();
+ EXPECT_EQ(OK, mCapture->getAudioRecordHandle()->addAudioDeviceCallback(mCbRecord));
+ EXPECT_EQ(OK, mCapture->start()) << "record creation failed";
+ EXPECT_EQ(OK, mCbRecord->waitForAudioDeviceCb());
+}
+
+// UNIT TESTS
+TEST_F(AudioSystemTest, CheckServerSideValues) {
+ ASSERT_NO_FATAL_FAILURE(createPlaybackSession());
+ EXPECT_GT(mAF->sampleRate(mCbPlayback->mAudioIo), 0);
+ EXPECT_NE(mAF->format(mCbPlayback->mAudioIo), AUDIO_FORMAT_INVALID);
+ EXPECT_GT(mAF->frameCount(mCbPlayback->mAudioIo), 0);
+ size_t frameCountHal, frameCountHalCache;
+ frameCountHal = mAF->frameCountHAL(mCbPlayback->mAudioIo);
+ EXPECT_GT(frameCountHal, 0);
+ EXPECT_EQ(OK, AudioSystem::getFrameCountHAL(mCbPlayback->mAudioIo, &frameCountHalCache));
+ EXPECT_EQ(frameCountHal, frameCountHalCache);
+ EXPECT_GT(mAF->latency(mCbPlayback->mAudioIo), 0);
+ // client side latency is at least server side latency
+ EXPECT_LE(mAF->latency(mCbPlayback->mAudioIo), mPlayback->getAudioTrackHandle()->latency());
+
+ ASSERT_NO_FATAL_FAILURE(createRecordSession());
+ EXPECT_GT(mAF->sampleRate(mCbRecord->mAudioIo), 0);
+ // EXPECT_NE(mAF->format(mCbRecord->mAudioIo), AUDIO_FORMAT_INVALID);
+ EXPECT_GT(mAF->frameCount(mCbRecord->mAudioIo), 0);
+ EXPECT_GT(mAF->frameCountHAL(mCbRecord->mAudioIo), 0);
+ frameCountHal = mAF->frameCountHAL(mCbRecord->mAudioIo);
+ EXPECT_GT(frameCountHal, 0);
+ EXPECT_EQ(OK, AudioSystem::getFrameCountHAL(mCbRecord->mAudioIo, &frameCountHalCache));
+ EXPECT_EQ(frameCountHal, frameCountHalCache);
+ // EXPECT_GT(mAF->latency(mCbRecord->mAudioIo), 0);
+ // client side latency is at least server side latency
+ // EXPECT_LE(mAF->latency(mCbRecord->mAudioIo), mCapture->getAudioRecordHandle()->latency());
+
+ EXPECT_GT(AudioSystem::getPrimaryOutputSamplingRate(), 0); // first fast mixer sample rate
+ EXPECT_GT(AudioSystem::getPrimaryOutputFrameCount(), 0); // fast mixer frame count
+}
+
+TEST_F(AudioSystemTest, GetSetMasterVolume) {
+ ASSERT_NO_FATAL_FAILURE(createPlaybackSession());
+ float origVol, tstVol;
+ EXPECT_EQ(NO_ERROR, AudioSystem::getMasterVolume(&origVol));
+ float newVol;
+ if (origVol + 0.2f > 1.0f) {
+ newVol = origVol - 0.2f;
+ } else {
+ newVol = origVol + 0.2f;
+ }
+ EXPECT_EQ(NO_ERROR, AudioSystem::setMasterVolume(newVol));
+ EXPECT_EQ(NO_ERROR, AudioSystem::getMasterVolume(&tstVol));
+ EXPECT_EQ(newVol, tstVol);
+ EXPECT_EQ(NO_ERROR, AudioSystem::setMasterVolume(origVol));
+ EXPECT_EQ(NO_ERROR, AudioSystem::getMasterVolume(&tstVol));
+ EXPECT_EQ(origVol, tstVol);
+}
+
+TEST_F(AudioSystemTest, GetSetMasterMute) {
+ ASSERT_NO_FATAL_FAILURE(createPlaybackSession());
+ bool origMuteState, tstMuteState;
+ EXPECT_EQ(NO_ERROR, AudioSystem::getMasterMute(&origMuteState));
+ EXPECT_EQ(NO_ERROR, AudioSystem::setMasterMute(!origMuteState));
+ EXPECT_EQ(NO_ERROR, AudioSystem::getMasterMute(&tstMuteState));
+ EXPECT_EQ(!origMuteState, tstMuteState);
+ EXPECT_EQ(NO_ERROR, AudioSystem::setMasterMute(origMuteState));
+ EXPECT_EQ(NO_ERROR, AudioSystem::getMasterMute(&tstMuteState));
+ EXPECT_EQ(origMuteState, tstMuteState);
+}
+
+TEST_F(AudioSystemTest, GetSetMicMute) {
+ ASSERT_NO_FATAL_FAILURE(createPlaybackSession());
+ bool origMuteState, tstMuteState;
+ EXPECT_EQ(NO_ERROR, AudioSystem::isMicrophoneMuted(&origMuteState));
+ EXPECT_EQ(NO_ERROR, AudioSystem::muteMicrophone(!origMuteState));
+ EXPECT_EQ(NO_ERROR, AudioSystem::isMicrophoneMuted(&tstMuteState));
+ EXPECT_EQ(!origMuteState, tstMuteState);
+ EXPECT_EQ(NO_ERROR, AudioSystem::muteMicrophone(origMuteState));
+ EXPECT_EQ(NO_ERROR, AudioSystem::isMicrophoneMuted(&tstMuteState));
+ EXPECT_EQ(origMuteState, tstMuteState);
+}
+
+TEST_F(AudioSystemTest, GetSetMasterBalance) {
+ ASSERT_NO_FATAL_FAILURE(createPlaybackSession());
+ float origBalance, tstBalance;
+ EXPECT_EQ(OK, AudioSystem::getMasterBalance(&origBalance));
+ float newBalance;
+ if (origBalance + 0.2f > 1.0f) {
+ newBalance = origBalance - 0.2f;
+ } else {
+ newBalance = origBalance + 0.2f;
+ }
+ EXPECT_EQ(OK, AudioSystem::setMasterBalance(newBalance));
+ EXPECT_EQ(OK, AudioSystem::getMasterBalance(&tstBalance));
+ EXPECT_EQ(newBalance, tstBalance);
+ EXPECT_EQ(OK, AudioSystem::setMasterBalance(origBalance));
+ EXPECT_EQ(OK, AudioSystem::getMasterBalance(&tstBalance));
+ EXPECT_EQ(origBalance, tstBalance);
+}
+
+TEST_F(AudioSystemTest, GetStreamVolume) {
+ ASSERT_NO_FATAL_FAILURE(createPlaybackSession());
+ float origStreamVol;
+ EXPECT_EQ(NO_ERROR, AudioSystem::getStreamVolume(AUDIO_STREAM_MUSIC, &origStreamVol,
+ mCbPlayback->mAudioIo));
+}
+
+TEST_F(AudioSystemTest, GetStreamMute) {
+ ASSERT_NO_FATAL_FAILURE(createPlaybackSession());
+ bool origMuteState;
+ EXPECT_EQ(NO_ERROR, AudioSystem::getStreamMute(AUDIO_STREAM_MUSIC, &origMuteState));
+}
+
+TEST_F(AudioSystemTest, StartAndStopAudioSource) {
+ std::vector<struct audio_port_v7> ports;
+ audio_port_config sourcePortConfig;
+ audio_attributes_t attributes = AudioSystem::streamTypeToAttributes(AUDIO_STREAM_MUSIC);
+ audio_port_handle_t sourcePortHandle = AUDIO_PORT_HANDLE_NONE;
+
+ status_t status = listAudioPorts(ports);
+ ASSERT_EQ(OK, status);
+ if (ports.empty()) {
+ GTEST_SKIP() << "No ports returned by the audio system";
+ }
+
+ for (const auto& port : ports) {
+ if (port.role != AUDIO_PORT_ROLE_SOURCE || port.type != AUDIO_PORT_TYPE_DEVICE) continue;
+ sourcePortConfig = port.active_config;
+
+ bool patchFound;
+
+ // start audio source.
+ status_t ret =
+ AudioSystem::startAudioSource(&sourcePortConfig, &attributes, &sourcePortHandle);
+ EXPECT_EQ(OK, ret) << "AudioSystem::startAudioSource for source " << port.ext.device.address
+ << " failed";
+
+ // verify that patch is established by the source port.
+ ASSERT_NO_FATAL_FAILURE(anyPatchContainsInputDevice(port.id, patchFound));
+ EXPECT_EQ(true, patchFound);
+ EXPECT_NE(sourcePortHandle, AUDIO_PORT_HANDLE_NONE);
+
+ if (sourcePortHandle != AUDIO_PORT_HANDLE_NONE) {
+ ret = AudioSystem::stopAudioSource(sourcePortHandle);
+ EXPECT_EQ(OK, ret) << "AudioSystem::stopAudioSource for handle failed";
+ }
+
+ // verify that no source port patch exists.
+ ASSERT_NO_FATAL_FAILURE(anyPatchContainsInputDevice(port.id, patchFound));
+ EXPECT_EQ(false, patchFound);
+ }
+}
+
+TEST_F(AudioSystemTest, CreateAndReleaseAudioPatch) {
+ status_t status;
+ struct audio_patch audioPatch;
+ std::vector<struct audio_port_v7> ports;
+ audio_patch_handle_t audioPatchHandle = AUDIO_PATCH_HANDLE_NONE;
+
+ bool patchFound = false;
+ audio_port_v7 sourcePort{};
+ audio_port_v7 sinkPort{};
+
+ audioPatch.id = 0;
+ audioPatch.num_sources = 1;
+ audioPatch.num_sinks = 1;
+
+ status = listAudioPorts(ports);
+ ASSERT_EQ(OK, status);
+ if (ports.empty()) {
+ GTEST_SKIP() << "No output devices returned by the audio system";
+ }
+
+ for (const auto& port : ports) {
+ if (port.role == AUDIO_PORT_ROLE_SOURCE && port.type == AUDIO_PORT_TYPE_DEVICE) {
+ sourcePort = port;
+ }
+ if (port.role == AUDIO_PORT_ROLE_SINK && port.type == AUDIO_PORT_TYPE_DEVICE &&
+ port.ext.device.type == AUDIO_DEVICE_OUT_SPEAKER) {
+ sinkPort = port;
+ }
+ }
+
+ audioPatch.sources[0] = sourcePort.active_config;
+ audioPatch.sinks[0] = sinkPort.active_config;
+
+ status = AudioSystem::createAudioPatch(&audioPatch, &audioPatchHandle);
+ EXPECT_EQ(OK, status) << "AudioSystem::createAudiopatch failed between source "
+ << sourcePort.ext.device.address << " and sink "
+ << sinkPort.ext.device.address;
+
+ // verify that patch is established between source and the sink.
+ ASSERT_NO_FATAL_FAILURE(anyPatchContainsInputDevice(sourcePort.id, patchFound));
+ EXPECT_EQ(true, patchFound);
+
+ EXPECT_NE(AUDIO_PORT_HANDLE_NONE, audioPatchHandle);
+ status = AudioSystem::releaseAudioPatch(audioPatchHandle);
+ EXPECT_EQ(OK, status) << "AudioSystem::releaseAudioPatch failed between source "
+ << sourcePort.ext.device.address << " and sink "
+ << sinkPort.ext.device.address;
+
+ // verify that no patch is established between source and the sink after releaseAudioPatch.
+ ASSERT_NO_FATAL_FAILURE(anyPatchContainsInputDevice(sourcePort.id, patchFound));
+ EXPECT_EQ(false, patchFound);
+}
+
+TEST_F(AudioSystemTest, GetAudioPort) {
+ std::vector<struct audio_port_v7> ports;
+ status_t status = listAudioPorts(ports);
+ ASSERT_EQ(OK, status);
+ for (const auto& port : ports) {
+ audio_port_v7 portTest{.id = port.id};
+ EXPECT_EQ(OK, AudioSystem::getAudioPort(&portTest));
+ EXPECT_TRUE(audio_ports_v7_are_equal(&portTest, &port));
+ }
+}
+
+TEST_F(AudioSystemTest, TestPhoneState) {
+ uid_t uid = getuid();
+ EXPECT_EQ(OK, AudioSystem::setPhoneState(AUDIO_MODE_RINGTONE, uid));
+ audio_mode_t state = AudioSystem::getPhoneState();
+ EXPECT_EQ(AUDIO_MODE_RINGTONE, state);
+ EXPECT_EQ(OK, AudioSystem::setPhoneState(AUDIO_MODE_IN_COMMUNICATION, uid));
+ state = AudioSystem::getPhoneState();
+ EXPECT_EQ(AUDIO_MODE_IN_COMMUNICATION, state);
+ EXPECT_EQ(OK, AudioSystem::setPhoneState(AUDIO_MODE_NORMAL, uid));
+ state = AudioSystem::getPhoneState();
+ EXPECT_EQ(AUDIO_MODE_NORMAL, state);
+}
+
+TEST_F(AudioSystemTest, GetDirectProfilesForAttributes) {
+ std::vector<audio_profile> audioProfiles;
+ audio_attributes_t attributes = AUDIO_ATTRIBUTES_INITIALIZER;
+ attributes.usage = AUDIO_USAGE_MEDIA;
+ attributes.content_type = AUDIO_CONTENT_TYPE_MUSIC;
+ EXPECT_EQ(BAD_VALUE, AudioSystem::getDirectProfilesForAttributes(nullptr, nullptr));
+ EXPECT_EQ(BAD_VALUE, AudioSystem::getDirectProfilesForAttributes(nullptr, &audioProfiles));
+ EXPECT_EQ(BAD_VALUE, AudioSystem::getDirectProfilesForAttributes(&attributes, nullptr));
+ EXPECT_EQ(NO_ERROR, AudioSystem::getDirectProfilesForAttributes(&attributes, &audioProfiles));
+}
+
+bool isPublicStrategy(const AudioProductStrategy& strategy) {
+ bool result = true;
+ for (auto& attribute : strategy.getAudioAttributes()) {
+ if (attribute.getAttributes() == AUDIO_ATTRIBUTES_INITIALIZER &&
+ (uint32_t(attribute.getStreamType()) >= AUDIO_STREAM_PUBLIC_CNT)) {
+ result = false;
+ break;
+ }
+ }
+ return result;
+}
+
+TEST_F(AudioSystemTest, DevicesForRoleAndStrategy) {
+ std::vector<struct audio_port_v7> ports;
+ status_t status = listAudioPorts(ports);
+ ASSERT_EQ(OK, status);
+
+ std::vector<struct audio_port_v7> devicePorts;
+ for (const auto& port : ports) {
+ if (port.type == AUDIO_PORT_TYPE_DEVICE && audio_is_output_device(port.ext.device.type)) {
+ devicePorts.push_back(port);
+ }
+ }
+ if (devicePorts.empty()) {
+ GTEST_SKIP() << "No output devices returned by the audio system";
+ }
+
+ AudioProductStrategyVector strategies;
+ EXPECT_EQ(OK, AudioSystem::listAudioProductStrategies(strategies));
+ if (strategies.empty()) {
+ GTEST_SKIP() << "No strategies returned by the audio system";
+ }
+
+ audio_attributes_t attributes = AUDIO_ATTRIBUTES_INITIALIZER;
+ attributes.usage = AUDIO_USAGE_MEDIA;
+
+ bool hasStrategyForMedia = false;
+ AudioProductStrategy mediaStrategy;
+ for (const auto& strategy : strategies) {
+ if (!isPublicStrategy(strategy)) continue;
+
+ for (const auto& att : strategy.getAudioAttributes()) {
+ if (strategy.attributesMatches(att.getAttributes(), attributes)) {
+ hasStrategyForMedia = true;
+ mediaStrategy = strategy;
+ break;
+ }
+ }
+ }
+
+ if (!hasStrategyForMedia) {
+ GTEST_SKIP() << "No strategies returned for music media";
+ }
+
+ AudioDeviceTypeAddrVector devices;
+ EXPECT_EQ(BAD_VALUE, AudioSystem::getDevicesForRoleAndStrategy(PRODUCT_STRATEGY_NONE,
+ DEVICE_ROLE_PREFERRED, devices));
+ EXPECT_EQ(BAD_VALUE, AudioSystem::getDevicesForRoleAndStrategy(mediaStrategy.getId(),
+ DEVICE_ROLE_NONE, devices));
+ status = AudioSystem::getDevicesForRoleAndStrategy(mediaStrategy.getId(), DEVICE_ROLE_PREFERRED,
+ devices);
+ if (status == NAME_NOT_FOUND) {
+ AudioDeviceTypeAddrVector outputDevices;
+ for (const auto& port : devicePorts) {
+ if (port.ext.device.type == AUDIO_DEVICE_OUT_SPEAKER) {
+ const AudioDeviceTypeAddr outputDevice(port.ext.device.type,
+ port.ext.device.address);
+ outputDevices.push_back(outputDevice);
+ }
+ }
+ EXPECT_EQ(OK, AudioSystem::setDevicesRoleForStrategy(mediaStrategy.getId(),
+ DEVICE_ROLE_PREFERRED, outputDevices));
+ EXPECT_EQ(OK, AudioSystem::getDevicesForRoleAndStrategy(mediaStrategy.getId(),
+ DEVICE_ROLE_PREFERRED, devices));
+ EXPECT_EQ(devices, outputDevices);
+ EXPECT_EQ(OK, AudioSystem::removeDevicesRoleForStrategy(mediaStrategy.getId(),
+ DEVICE_ROLE_PREFERRED));
+ EXPECT_EQ(NAME_NOT_FOUND, AudioSystem::getDevicesForRoleAndStrategy(
+ mediaStrategy.getId(), DEVICE_ROLE_PREFERRED, devices));
+ }
+}
+
+TEST_F(AudioSystemTest, VolumeIndexForAttributes) {
+ AudioVolumeGroupVector groups;
+ EXPECT_EQ(OK, AudioSystem::listAudioVolumeGroups(groups));
+ for (const auto& group : groups) {
+ if (group.getAudioAttributes().empty()) continue;
+ const audio_attributes_t attr = group.getAudioAttributes()[0];
+ if (attr == AUDIO_ATTRIBUTES_INITIALIZER) continue;
+ audio_stream_type_t streamType = AudioSystem::attributesToStreamType(attr);
+ if (streamType >= AUDIO_STREAM_PUBLIC_CNT) continue;
+
+ volume_group_t vg;
+ EXPECT_EQ(OK, AudioSystem::getVolumeGroupFromAudioAttributes(attr, vg));
+ EXPECT_EQ(group.getId(), vg);
+
+ int index;
+ EXPECT_EQ(OK,
+ AudioSystem::getVolumeIndexForAttributes(attr, index, AUDIO_DEVICE_OUT_SPEAKER));
+
+ int indexTest;
+ EXPECT_EQ(OK, AudioSystem::getStreamVolumeIndex(streamType, &indexTest,
+ AUDIO_DEVICE_OUT_SPEAKER));
+ EXPECT_EQ(index, indexTest);
+ }
+}
+
+TEST_F(AudioSystemTest, DevicesRoleForCapturePreset) {
+ std::vector<struct audio_port_v7> ports;
+ status_t status = listAudioPorts(ports);
+ ASSERT_EQ(OK, status);
+
+ if (ports.empty()) {
+ GTEST_SKIP() << "No ports returned by the audio system";
+ }
+
+ audio_devices_t inDeviceA = AUDIO_DEVICE_IN_BUILTIN_MIC;
+ audio_devices_t inDeviceB = AUDIO_DEVICE_IN_BUILTIN_MIC;
+ for (const auto& port : ports) {
+ if (port.role != AUDIO_PORT_ROLE_SOURCE || port.type != AUDIO_PORT_TYPE_DEVICE) continue;
+ if (port.ext.device.type == inDeviceA) continue;
+ inDeviceB = port.ext.device.type;
+ break;
+ }
+ const audio_source_t audioSource = AUDIO_SOURCE_MIC;
+ const device_role_t role = DEVICE_ROLE_PREFERRED;
+ const AudioDeviceTypeAddr inputDevice(inDeviceA, "");
+ const AudioDeviceTypeAddrVector inputDevices = {inputDevice};
+ const AudioDeviceTypeAddr outputDevice(AUDIO_DEVICE_OUT_SPEAKER, "");
+ const AudioDeviceTypeAddrVector outputDevices = {outputDevice};
+
+ // Test invalid device when setting
+ EXPECT_EQ(BAD_VALUE,
+ AudioSystem::setDevicesRoleForCapturePreset(audioSource, role, outputDevices));
+ EXPECT_EQ(BAD_VALUE,
+ AudioSystem::addDevicesRoleForCapturePreset(audioSource, role, outputDevices));
+ EXPECT_EQ(BAD_VALUE,
+ AudioSystem::removeDevicesRoleForCapturePreset(audioSource, role, outputDevices));
+
+ // Test invalid role
+ AudioDeviceTypeAddrVector devices;
+ EXPECT_EQ(BAD_VALUE, AudioSystem::getDevicesForRoleAndCapturePreset(audioSource,
+ DEVICE_ROLE_NONE, devices));
+ EXPECT_EQ(BAD_VALUE, AudioSystem::setDevicesRoleForCapturePreset(audioSource, DEVICE_ROLE_NONE,
+ inputDevices));
+ EXPECT_EQ(BAD_VALUE, AudioSystem::addDevicesRoleForCapturePreset(audioSource, DEVICE_ROLE_NONE,
+ inputDevices));
+ EXPECT_EQ(BAD_VALUE, AudioSystem::removeDevicesRoleForCapturePreset(
+ audioSource, DEVICE_ROLE_NONE, inputDevices));
+ EXPECT_EQ(BAD_VALUE,
+ AudioSystem::clearDevicesRoleForCapturePreset(audioSource, DEVICE_ROLE_NONE));
+
+ // Without setting, call get/remove/clear must fail
+ EXPECT_EQ(NAME_NOT_FOUND,
+ AudioSystem::getDevicesForRoleAndCapturePreset(audioSource, role, devices));
+ EXPECT_TRUE(devices.empty());
+ EXPECT_EQ(NAME_NOT_FOUND,
+ AudioSystem::removeDevicesRoleForCapturePreset(audioSource, role, devices));
+ EXPECT_EQ(NAME_NOT_FOUND, AudioSystem::clearDevicesRoleForCapturePreset(audioSource, role));
+
+ // Test set/get devices role
+ EXPECT_EQ(NO_ERROR,
+ AudioSystem::setDevicesRoleForCapturePreset(audioSource, role, inputDevices));
+ ASSERT_EQ(NO_ERROR, AudioSystem::getDevicesForRoleAndCapturePreset(audioSource, role, devices));
+ EXPECT_EQ(devices, inputDevices);
+
+ // Test setting will change the previously set devices
+ const AudioDeviceTypeAddr inputDevice2 = AudioDeviceTypeAddr(inDeviceB, "");
+ AudioDeviceTypeAddrVector inputDevices2 = {inputDevice2};
+ EXPECT_EQ(NO_ERROR,
+ AudioSystem::setDevicesRoleForCapturePreset(audioSource, role, inputDevices2));
+ devices.clear();
+ EXPECT_EQ(NO_ERROR, AudioSystem::getDevicesForRoleAndCapturePreset(audioSource, role, devices));
+ EXPECT_EQ(devices, inputDevices2);
+
+ // Test add devices
+ EXPECT_EQ(NO_ERROR,
+ AudioSystem::addDevicesRoleForCapturePreset(audioSource, role, inputDevices));
+ devices.clear();
+ EXPECT_EQ(NO_ERROR, AudioSystem::getDevicesForRoleAndCapturePreset(audioSource, role, devices));
+ EXPECT_EQ(2, devices.size());
+ EXPECT_TRUE(std::find(devices.begin(), devices.end(), inputDevice) != devices.end());
+ EXPECT_TRUE(std::find(devices.begin(), devices.end(), inputDevice2) != devices.end());
+
+ // Test remove devices
+ EXPECT_EQ(NO_ERROR,
+ AudioSystem::removeDevicesRoleForCapturePreset(audioSource, role, inputDevices));
+ devices.clear();
+ EXPECT_EQ(NO_ERROR, AudioSystem::getDevicesForRoleAndCapturePreset(audioSource, role, devices));
+ EXPECT_EQ(devices, inputDevices2);
+
+ // Test remove devices that are not set as the device role
+ EXPECT_EQ(BAD_VALUE,
+ AudioSystem::removeDevicesRoleForCapturePreset(audioSource, role, inputDevices));
+
+ // Test clear devices
+ EXPECT_EQ(NO_ERROR, AudioSystem::clearDevicesRoleForCapturePreset(audioSource, role));
+ devices.clear();
+ EXPECT_EQ(NAME_NOT_FOUND,
+ AudioSystem::getDevicesForRoleAndCapturePreset(audioSource, role, devices));
+
+ AudioDeviceTypeAddrVector inputDevices3 = {inputDevice, inputDevice2};
+ EXPECT_EQ(NO_ERROR,
+ AudioSystem::setDevicesRoleForCapturePreset(audioSource, role, inputDevices3));
+ devices.clear();
+ EXPECT_EQ(NO_ERROR, AudioSystem::getDevicesForRoleAndCapturePreset(audioSource, role, devices));
+ EXPECT_EQ(2, devices.size());
+ EXPECT_TRUE(std::find(devices.begin(), devices.end(), inputDevice) != devices.end());
+ EXPECT_TRUE(std::find(devices.begin(), devices.end(), inputDevice2) != devices.end());
+ EXPECT_EQ(NO_ERROR, AudioSystem::clearDevicesRoleForCapturePreset(audioSource, role));
+}
+
+TEST_F(AudioSystemTest, UidDeviceAffinities) {
+ uid_t uid = getuid();
+
+ // Test invalid device for example audio_is_input_device
+ AudioDeviceTypeAddr inputDevice(AUDIO_DEVICE_IN_BUILTIN_MIC, "");
+ AudioDeviceTypeAddrVector inputDevices = {inputDevice};
+ EXPECT_EQ(BAD_VALUE, AudioSystem::setUidDeviceAffinities(uid, inputDevices));
+
+ // Test valid device for example audio_is_output_device
+ AudioDeviceTypeAddr outputDevice(AUDIO_DEVICE_OUT_SPEAKER, "");
+ AudioDeviceTypeAddrVector outputDevices = {outputDevice};
+ EXPECT_EQ(NO_ERROR, AudioSystem::setUidDeviceAffinities(uid, outputDevices));
+ EXPECT_EQ(NO_ERROR, AudioSystem::removeUidDeviceAffinities(uid));
+}
+
+TEST_F(AudioSystemTest, UserIdDeviceAffinities) {
+ int userId = 200;
+
+ // Test invalid device for example audio_is_input_device
+ AudioDeviceTypeAddr inputDevice(AUDIO_DEVICE_IN_BUILTIN_MIC, "");
+ AudioDeviceTypeAddrVector inputDevices = {inputDevice};
+ EXPECT_EQ(BAD_VALUE, AudioSystem::setUserIdDeviceAffinities(userId, inputDevices));
+
+ // Test valid device for ezample audio_is_output_device
+ AudioDeviceTypeAddr outputDevice(AUDIO_DEVICE_OUT_SPEAKER, "");
+ AudioDeviceTypeAddrVector outputDevices = {outputDevice};
+ EXPECT_EQ(NO_ERROR, AudioSystem::setUserIdDeviceAffinities(userId, outputDevices));
+ EXPECT_EQ(NO_ERROR, AudioSystem::removeUserIdDeviceAffinities(userId));
+}
diff --git a/media/libaudioclient/tests/audiotrack_tests.cpp b/media/libaudioclient/tests/audiotrack_tests.cpp
new file mode 100644
index 0000000..8daba0a
--- /dev/null
+++ b/media/libaudioclient/tests/audiotrack_tests.cpp
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+
+#include <gtest/gtest.h>
+
+#include "audio_test_utils.h"
+
+using namespace android;
+
+TEST(AudioTrackTest, TestPlayTrack) {
+ const auto ap = sp<AudioPlayback>::make(44100 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT,
+ AUDIO_CHANNEL_OUT_STEREO, AUDIO_OUTPUT_FLAG_NONE,
+ AUDIO_SESSION_NONE, AudioTrack::TRANSFER_OBTAIN);
+ ASSERT_NE(nullptr, ap);
+ ASSERT_EQ(OK, ap->loadResource("/data/local/tmp/bbb_2ch_24kHz_s16le.raw"))
+ << "Unable to open Resource";
+ EXPECT_EQ(OK, ap->create()) << "track creation failed";
+ EXPECT_EQ(OK, ap->start()) << "audio track start failed";
+ EXPECT_EQ(OK, ap->onProcess());
+ ap->stop();
+}
+
+TEST(AudioTrackTest, TestSeek) {
+ const auto ap = sp<AudioPlayback>::make(
+ 44100 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO);
+ ASSERT_NE(nullptr, ap);
+ ASSERT_EQ(OK, ap->loadResource("/data/local/tmp/bbb_2ch_24kHz_s16le.raw"))
+ << "Unable to open Resource";
+ EXPECT_EQ(OK, ap->create()) << "track creation failed";
+ EXPECT_EQ(OK, ap->start()) << "audio track start failed";
+ EXPECT_EQ(OK, ap->onProcess(true));
+ ap->stop();
+}
+
+TEST(AudioTrackTest, OffloadOrDirectPlayback) {
+ audio_offload_info_t info = AUDIO_INFO_INITIALIZER;
+ info.sample_rate = 44100;
+ info.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+ info.format = AUDIO_FORMAT_MP3;
+ info.stream_type = AUDIO_STREAM_MUSIC;
+ info.bit_rate = 192;
+ info.duration_us = 120 * 1000000; // 120 sec
+
+ audio_config_base_t config = {/* .sample_rate = */ info.sample_rate,
+ /* .channel_mask = */ info.channel_mask,
+ /* .format = */ AUDIO_FORMAT_PCM_16_BIT};
+ audio_attributes_t attributes = AUDIO_ATTRIBUTES_INITIALIZER;
+ attributes.content_type = AUDIO_CONTENT_TYPE_MUSIC;
+ attributes.usage = AUDIO_USAGE_MEDIA;
+ attributes.flags = AUDIO_FLAG_NONE;
+
+ if (!AudioTrack::isDirectOutputSupported(config, attributes) &&
+ AUDIO_OFFLOAD_NOT_SUPPORTED == AudioSystem::getOffloadSupport(info)) {
+ GTEST_SKIP() << "offload or direct playback is not supported";
+ }
+ sp<AudioPlayback> ap = nullptr;
+ if (AUDIO_OFFLOAD_NOT_SUPPORTED != AudioSystem::getOffloadSupport(info)) {
+ ap = sp<AudioPlayback>::make(info.sample_rate, info.format, info.channel_mask,
+ AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD, AUDIO_SESSION_NONE,
+ AudioTrack::TRANSFER_OBTAIN, nullptr, &info);
+ } else {
+ ap = sp<AudioPlayback>::make(config.sample_rate, config.format, config.channel_mask,
+ AUDIO_OUTPUT_FLAG_DIRECT, AUDIO_SESSION_NONE,
+ AudioTrack::TRANSFER_OBTAIN);
+ }
+ ASSERT_NE(nullptr, ap);
+ EXPECT_EQ(OK, ap->create()) << "track creation failed";
+ audio_dual_mono_mode_t mode;
+ if (OK != ap->getAudioTrackHandle()->getDualMonoMode(&mode)) {
+ std::cerr << "no dual mono presentation is available" << std::endl;
+ }
+ if (OK != ap->getAudioTrackHandle()->setDualMonoMode(AUDIO_DUAL_MONO_MODE_LR)) {
+ std::cerr << "no dual mono presentation is available" << std::endl;
+ } else {
+ EXPECT_EQ(OK, ap->getAudioTrackHandle()->getDualMonoMode(&mode));
+ EXPECT_EQ(AUDIO_DUAL_MONO_MODE_LR, mode);
+ }
+ float leveldB;
+ if (OK != ap->getAudioTrackHandle()->getAudioDescriptionMixLevel(&leveldB)) {
+ std::cerr << "Audio Description mixing is unavailable" << std::endl;
+ }
+ if (OK != ap->getAudioTrackHandle()->setAudioDescriptionMixLevel(3.14f)) {
+ std::cerr << "Audio Description mixing is unavailable" << std::endl;
+ } else {
+ EXPECT_EQ(OK, ap->getAudioTrackHandle()->getAudioDescriptionMixLevel(&leveldB));
+ EXPECT_EQ(3.14f, leveldB);
+ }
+ AudioPlaybackRate audioRate;
+ audioRate = ap->getAudioTrackHandle()->getPlaybackRate();
+ std::cerr << "playback speed :: " << audioRate.mSpeed << std::endl
+ << "playback pitch :: " << audioRate.mPitch << std::endl;
+ audioRate.mSpeed = 2.0f;
+ audioRate.mPitch = 2.0f;
+ audioRate.mStretchMode = AUDIO_TIMESTRETCH_STRETCH_VOICE;
+ audioRate.mFallbackMode = AUDIO_TIMESTRETCH_FALLBACK_MUTE;
+ EXPECT_TRUE(isAudioPlaybackRateValid(audioRate));
+ if (OK != ap->getAudioTrackHandle()->setPlaybackRate(audioRate)) {
+ std::cerr << "unable to set playback rate parameters" << std::endl;
+ } else {
+ AudioPlaybackRate audioRateLocal;
+ audioRateLocal = ap->getAudioTrackHandle()->getPlaybackRate();
+ EXPECT_TRUE(isAudioPlaybackRateEqual(audioRate, audioRateLocal));
+ }
+ ap->stop();
+}
+
+TEST(AudioTrackTest, TestAudioCbNotifier) {
+ const auto ap = sp<AudioPlayback>::make(0 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT,
+ AUDIO_CHANNEL_OUT_STEREO, AUDIO_OUTPUT_FLAG_FAST,
+ AUDIO_SESSION_NONE, AudioTrack::TRANSFER_SHARED);
+ ASSERT_NE(nullptr, ap);
+ ASSERT_EQ(OK, ap->loadResource("/data/local/tmp/bbb_2ch_24kHz_s16le.raw"))
+ << "Unable to open Resource";
+ EXPECT_EQ(OK, ap->create()) << "track creation failed";
+ EXPECT_EQ(BAD_VALUE, ap->getAudioTrackHandle()->addAudioDeviceCallback(nullptr));
+ sp<OnAudioDeviceUpdateNotifier> cb = sp<OnAudioDeviceUpdateNotifier>::make();
+ sp<OnAudioDeviceUpdateNotifier> cbOld = sp<OnAudioDeviceUpdateNotifier>::make();
+ EXPECT_EQ(OK, ap->getAudioTrackHandle()->addAudioDeviceCallback(cbOld));
+ EXPECT_EQ(INVALID_OPERATION, ap->getAudioTrackHandle()->addAudioDeviceCallback(cbOld));
+ EXPECT_EQ(OK, ap->getAudioTrackHandle()->addAudioDeviceCallback(cb));
+ EXPECT_EQ(OK, ap->start()) << "audio track start failed";
+ EXPECT_EQ(OK, ap->onProcess());
+ EXPECT_EQ(OK, cb->waitForAudioDeviceCb());
+ EXPECT_EQ(AUDIO_IO_HANDLE_NONE, cbOld->mAudioIo);
+ EXPECT_EQ(AUDIO_PORT_HANDLE_NONE, cbOld->mDeviceId);
+ EXPECT_NE(AUDIO_IO_HANDLE_NONE, cb->mAudioIo);
+ EXPECT_NE(AUDIO_PORT_HANDLE_NONE, cb->mDeviceId);
+ EXPECT_EQ(cb->mAudioIo, ap->getAudioTrackHandle()->getOutput());
+ EXPECT_EQ(cb->mDeviceId, ap->getAudioTrackHandle()->getRoutedDeviceId());
+ String8 keys;
+ keys = ap->getAudioTrackHandle()->getParameters(keys);
+ if (!keys.isEmpty()) {
+ std::cerr << "track parameters :: " << keys << std::endl;
+ }
+ EXPECT_TRUE(checkPatchPlayback(cb->mAudioIo, cb->mDeviceId));
+ EXPECT_EQ(BAD_VALUE, ap->getAudioTrackHandle()->removeAudioDeviceCallback(nullptr));
+ EXPECT_EQ(INVALID_OPERATION, ap->getAudioTrackHandle()->removeAudioDeviceCallback(cbOld));
+ EXPECT_EQ(OK, ap->getAudioTrackHandle()->removeAudioDeviceCallback(cb));
+ ap->stop();
+}
+
+class AudioTrackCreateTest
+ : public ::testing::TestWithParam<std::tuple<uint32_t, audio_format_t, audio_channel_mask_t,
+ audio_output_flags_t, audio_session_t>> {
+ public:
+ AudioTrackCreateTest()
+ : mSampleRate(std::get<0>(GetParam())),
+ mFormat(std::get<1>(GetParam())),
+ mChannelMask(std::get<2>(GetParam())),
+ mFlags(std::get<3>(GetParam())),
+ mSessionId(std::get<4>(GetParam())){};
+
+ const uint32_t mSampleRate;
+ const audio_format_t mFormat;
+ const audio_channel_mask_t mChannelMask;
+ const audio_output_flags_t mFlags;
+ const audio_session_t mSessionId;
+
+ sp<AudioPlayback> mAP;
+
+ virtual void SetUp() override {
+ mAP = sp<AudioPlayback>::make(mSampleRate, mFormat, mChannelMask, mFlags,
+ mSessionId);
+ ASSERT_NE(nullptr, mAP);
+ ASSERT_EQ(OK, mAP->loadResource("/data/local/tmp/bbb_2ch_24kHz_s16le.raw"))
+ << "Unable to open Resource";
+ ASSERT_EQ(OK, mAP->create()) << "track creation failed";
+ }
+
+ virtual void TearDown() override {
+ if (mAP) mAP->stop();
+ }
+};
+
+TEST_P(AudioTrackCreateTest, TestCreateTrack) {
+ EXPECT_EQ(mFormat, mAP->getAudioTrackHandle()->format());
+ EXPECT_EQ(audio_channel_count_from_out_mask(mChannelMask),
+ mAP->getAudioTrackHandle()->channelCount());
+ if (mSampleRate != 0) EXPECT_EQ(mSampleRate, mAP->getAudioTrackHandle()->getSampleRate());
+ if (mSessionId != AUDIO_SESSION_NONE)
+ EXPECT_EQ(mSessionId, mAP->getAudioTrackHandle()->getSessionId());
+ EXPECT_EQ(mSampleRate, mAP->getAudioTrackHandle()->getOriginalSampleRate());
+ EXPECT_EQ(OK, mAP->start()) << "audio track start failed";
+ EXPECT_EQ(OK, mAP->onProcess());
+}
+
+// sampleRate, format, channelMask, flags, sessionId
+INSTANTIATE_TEST_SUITE_P(
+ AudioTrackParameterizedTest, AudioTrackCreateTest,
+ ::testing::Combine(::testing::Values(48000), ::testing::Values(AUDIO_FORMAT_PCM_16_BIT),
+ ::testing::Values(AUDIO_CHANNEL_OUT_STEREO),
+ ::testing::Values(AUDIO_OUTPUT_FLAG_NONE,
+ AUDIO_OUTPUT_FLAG_PRIMARY | AUDIO_OUTPUT_FLAG_FAST,
+ AUDIO_OUTPUT_FLAG_RAW | AUDIO_OUTPUT_FLAG_FAST,
+ AUDIO_OUTPUT_FLAG_DEEP_BUFFER),
+ ::testing::Values(AUDIO_SESSION_NONE)));
diff --git a/media/libaudioclient/tests/bbb_1ch_8kHz_s16le.raw b/media/libaudioclient/tests/bbb_1ch_8kHz_s16le.raw
new file mode 100644
index 0000000..2d1e4bf
--- /dev/null
+++ b/media/libaudioclient/tests/bbb_1ch_8kHz_s16le.raw
Binary files differ
diff --git a/media/libaudioclient/tests/bbb_2ch_24kHz_s16le.raw b/media/libaudioclient/tests/bbb_2ch_24kHz_s16le.raw
new file mode 100644
index 0000000..c8ac5f7
--- /dev/null
+++ b/media/libaudioclient/tests/bbb_2ch_24kHz_s16le.raw
Binary files differ
diff --git a/media/libaudioclient/tests/test_create_audiorecord.cpp b/media/libaudioclient/tests/test_create_audiorecord.cpp
index 2e0883b..277110b 100644
--- a/media/libaudioclient/tests/test_create_audiorecord.cpp
+++ b/media/libaudioclient/tests/test_create_audiorecord.cpp
@@ -29,14 +29,13 @@
#define NUM_ARGUMENTS 8
#define VERSION_VALUE "1.0"
-#define PACKAGE_NAME "AudioRecord test"
+#define PACKAGE_NAME "AudioRecord test"
namespace android {
using android::content::AttributionSourceState;
-int testRecord(FILE *inputFile, int outputFileFd)
-{
+int testRecord(FILE* inputFile, int outputFileFd) {
char line[MAX_INPUT_FILE_LINE_LENGTH];
uint32_t testCount = 0;
Vector<String16> args;
@@ -47,11 +46,9 @@
attributionSource.token = sp<BBinder>::make();
if (inputFile == nullptr) {
- sp<AudioRecord> record = new AudioRecord(AUDIO_SOURCE_DEFAULT,
- 0 /* sampleRate */,
- AUDIO_FORMAT_DEFAULT,
- AUDIO_CHANNEL_IN_MONO,
- attributionSource);
+ sp<AudioRecord> record =
+ new AudioRecord(AUDIO_SOURCE_DEFAULT, 0 /* sampleRate */, AUDIO_FORMAT_DEFAULT,
+ AUDIO_CHANNEL_IN_MONO, attributionSource);
if (record == 0 || record->initCheck() != NO_ERROR) {
write(outputFileFd, "Error creating AudioRecord\n",
sizeof("Error creating AudioRecord\n"));
@@ -80,11 +77,10 @@
char statusStr[MAX_OUTPUT_FILE_LINE_LENGTH];
bool fast = false;
- if (sscanf(line, " %u %x %x %zu %d %x %u %u",
- &sampleRate, &format, &channelMask,
- &frameCount, ¬ificationFrames,
- &flags, &sessionId, &inputSource) != NUM_ARGUMENTS) {
- fprintf(stderr, "Malformed line for test #%u in input file\n", testCount+1);
+ if (sscanf(line, " %u %x %x %zu %d %x %u %u", &sampleRate, &format, &channelMask,
+ &frameCount, ¬ificationFrames, &flags, &sessionId,
+ &inputSource) != NUM_ARGUMENTS) {
+ fprintf(stderr, "Malformed line for test #%u in input file\n", testCount + 1);
ret = 1;
continue;
}
@@ -100,21 +96,10 @@
sp<AudioRecord> record = new AudioRecord(attributionSource);
const auto emptyCallback = sp<AudioRecord::IAudioRecordCallback>::make();
- record->set(AUDIO_SOURCE_DEFAULT,
- sampleRate,
- format,
- channelMask,
- frameCount,
- fast ? emptyCallback : nullptr,
- notificationFrames,
- false,
- sessionId,
- fast ? AudioRecord::TRANSFER_CALLBACK : AudioRecord::TRANSFER_DEFAULT,
- flags,
- getuid(),
- getpid(),
- &attributes,
- AUDIO_PORT_HANDLE_NONE);
+ record->set(AUDIO_SOURCE_DEFAULT, sampleRate, format, channelMask, frameCount,
+ fast ? emptyCallback : nullptr, notificationFrames, false, sessionId,
+ fast ? AudioRecord::TRANSFER_CALLBACK : AudioRecord::TRANSFER_DEFAULT, flags,
+ getuid(), getpid(), &attributes, AUDIO_PORT_HANDLE_NONE);
status = record->initCheck();
sprintf(statusStr, "\n#### Test %u status %d\n", testCount, status);
write(outputFileFd, statusStr, strlen(statusStr));
@@ -126,11 +111,8 @@
return ret;
}
-}; // namespace android
+}; // namespace android
-
-int main(int argc, char **argv)
-{
+int main(int argc, char** argv) {
return android::main(argc, argv, android::testRecord);
}
-
diff --git a/media/libaudioclient/tests/test_create_audiotrack.cpp b/media/libaudioclient/tests/test_create_audiotrack.cpp
index e7231d3..4e09e21 100644
--- a/media/libaudioclient/tests/test_create_audiotrack.cpp
+++ b/media/libaudioclient/tests/test_create_audiotrack.cpp
@@ -32,18 +32,15 @@
namespace android {
-int testTrack(FILE *inputFile, int outputFileFd)
-{
+int testTrack(FILE* inputFile, int outputFileFd) {
char line[MAX_INPUT_FILE_LINE_LENGTH];
uint32_t testCount = 0;
Vector<String16> args;
int ret = 0;
if (inputFile == nullptr) {
- sp<AudioTrack> track = new AudioTrack(AUDIO_STREAM_DEFAULT,
- 0 /* sampleRate */,
- AUDIO_FORMAT_DEFAULT,
- AUDIO_CHANNEL_OUT_STEREO);
+ sp<AudioTrack> track = new AudioTrack(AUDIO_STREAM_DEFAULT, 0 /* sampleRate */,
+ AUDIO_FORMAT_DEFAULT, AUDIO_CHANNEL_OUT_STEREO);
if (track == 0 || track->initCheck() != NO_ERROR) {
write(outputFileFd, "Error creating AudioTrack\n",
sizeof("Error creating AudioTrack\n"));
@@ -78,11 +75,10 @@
bool offload = false;
bool fast = false;
- if (sscanf(line, " %u %x %x %zu %d %u %x %u %u %u",
- &sampleRate, &format, &channelMask,
- &frameCount, ¬ificationFrames, &useSharedBuffer,
- &flags, &sessionId, &usage, &contentType) != NUM_ARGUMENTS) {
- fprintf(stderr, "Malformed line for test #%u in input file\n", testCount+1);
+ if (sscanf(line, " %u %x %x %zu %d %u %x %u %u %u", &sampleRate, &format, &channelMask,
+ &frameCount, ¬ificationFrames, &useSharedBuffer, &flags, &sessionId, &usage,
+ &contentType) != NUM_ARGUMENTS) {
+ fprintf(stderr, "Malformed line for test #%u in input file\n", testCount + 1);
ret = 1;
continue;
}
@@ -90,7 +86,7 @@
if (useSharedBuffer != 0) {
size_t heapSize = audio_channel_count_from_out_mask(channelMask) *
- audio_bytes_per_sample(format) * frameCount;
+ audio_bytes_per_sample(format) * frameCount;
heap = new MemoryDealer(heapSize, "AudioTrack Heap Base");
sharedBuffer = heap->allocate(heapSize);
frameCount = 0;
@@ -111,25 +107,13 @@
attributes.usage = usage;
sp<AudioTrack> track = new AudioTrack();
const auto emptyCallback = sp<AudioTrack::IAudioTrackCallback>::make();
- track->set(AUDIO_STREAM_DEFAULT,
- sampleRate,
- format,
- channelMask,
- frameCount,
- flags,
- (fast || offload) ? emptyCallback : nullptr,
- notificationFrames,
- sharedBuffer,
- false,
- sessionId,
- ((fast && sharedBuffer == 0) || offload) ?
- AudioTrack::TRANSFER_CALLBACK : AudioTrack::TRANSFER_DEFAULT,
- offload ? &offloadInfo : nullptr,
- AttributionSourceState(),
- &attributes,
- false,
- 1.0f,
- AUDIO_PORT_HANDLE_NONE);
+ track->set(AUDIO_STREAM_DEFAULT, sampleRate, format, channelMask, frameCount, flags,
+ (fast || offload) ? emptyCallback : nullptr, notificationFrames, sharedBuffer,
+ false, sessionId,
+ ((fast && sharedBuffer == 0) || offload) ? AudioTrack::TRANSFER_CALLBACK
+ : AudioTrack::TRANSFER_DEFAULT,
+ offload ? &offloadInfo : nullptr, AttributionSourceState(), &attributes, false,
+ 1.0f, AUDIO_PORT_HANDLE_NONE);
status = track->initCheck();
sprintf(statusStr, "\n#### Test %u status %d\n", testCount, status);
write(outputFileFd, statusStr, strlen(statusStr));
@@ -141,11 +125,8 @@
return ret;
}
-}; // namespace android
+}; // namespace android
-
-int main(int argc, char **argv)
-{
+int main(int argc, char** argv) {
return android::main(argc, argv, android::testTrack);
}
-
diff --git a/media/libaudioclient/tests/test_create_utils.cpp b/media/libaudioclient/tests/test_create_utils.cpp
index caf5227..c2c2e8b 100644
--- a/media/libaudioclient/tests/test_create_utils.cpp
+++ b/media/libaudioclient/tests/test_create_utils.cpp
@@ -23,10 +23,10 @@
namespace android {
-int readLine(FILE *inputFile, char *line, int size) {
+int readLine(FILE* inputFile, char* line, int size) {
int ret = 0;
while (true) {
- char *str = fgets(line, size, inputFile);
+ char* str = fgets(line, size, inputFile);
if (str == nullptr) {
ret = -1;
break;
@@ -42,8 +42,7 @@
return ret;
}
-bool checkVersion(FILE *inputFile, const char *version)
-{
+bool checkVersion(FILE* inputFile, const char* version) {
char line[MAX_INPUT_FILE_LINE_LENGTH];
char versionKey[MAX_INPUT_FILE_LINE_LENGTH];
char versionValue[MAX_INPUT_FILE_LINE_LENGTH];
@@ -68,9 +67,8 @@
return true;
}
-int main(int argc, char **argv, test_func_t testFunc)
-{
- FILE *inputFile = nullptr;
+int main(int argc, char** argv, test_func_t testFunc) {
+ FILE* inputFile = nullptr;
int outputFileFd = STDOUT_FILENO;
mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
int ret = 0;
@@ -96,7 +94,7 @@
if (strcmp(*argv, "-o") == 0) {
argv++;
if (*argv) {
- outputFileFd = open(*argv, O_WRONLY|O_CREAT, mode);
+ outputFileFd = open(*argv, O_WRONLY | O_CREAT, mode);
if (outputFileFd < 0) {
ret = 1;
}
@@ -126,5 +124,4 @@
return ret;
}
-}; // namespace android
-
+}; // namespace android
diff --git a/media/libaudioclient/tests/test_create_utils.h b/media/libaudioclient/tests/test_create_utils.h
index 9a6f9fa..110baf7 100644
--- a/media/libaudioclient/tests/test_create_utils.h
+++ b/media/libaudioclient/tests/test_create_utils.h
@@ -27,13 +27,12 @@
namespace android {
-int readLine(FILE *inputFile, char *line, int size);
+int readLine(FILE* inputFile, char* line, int size);
-bool checkVersion(FILE *inputFile, const char *version);
+bool checkVersion(FILE* inputFile, const char* version);
+typedef int (*test_func_t)(FILE* inputFile, int outputFileFd);
-typedef int (*test_func_t)(FILE *inputFile, int outputFileFd);
+int main(int argc, char** argv, test_func_t testFunc);
-int main(int argc, char **argv, test_func_t testFunc);
-
-}; // namespace android
+}; // namespace android
diff --git a/media/libaudioclient/tests/trackplayerbase_tests.cpp b/media/libaudioclient/tests/trackplayerbase_tests.cpp
new file mode 100644
index 0000000..c9b704d
--- /dev/null
+++ b/media/libaudioclient/tests/trackplayerbase_tests.cpp
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2021 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 "TrackPlayerBaseTest"
+
+#include <gtest/gtest.h>
+
+#include <media/TrackPlayerBase.h>
+
+using namespace android;
+using namespace android::media;
+
+class TrackPlayer : public TrackPlayerBase, public AudioTrack::IAudioTrackCallback {
+ public:
+ // methods protected in base class
+ using TrackPlayerBase::playerPause;
+ using TrackPlayerBase::playerSetVolume;
+ using TrackPlayerBase::playerStart;
+ using TrackPlayerBase::playerStop;
+};
+
+class TrackPlayerBaseTest
+ : public ::testing::TestWithParam<std::tuple<double, double, uint32_t, uint32_t>> {
+ public:
+ TrackPlayerBaseTest()
+ : mDuration(std::get<0>(GetParam())),
+ mPulseFreq(std::get<1>(GetParam())),
+ mChannelCount(std::get<2>(GetParam())),
+ mSampleRate(std::get<3>(GetParam())){};
+
+ virtual void SetUp() override {
+ mFrameCount = mDuration * mSampleRate;
+ audio_channel_mask_t channelMask = audio_channel_out_mask_from_count(mChannelCount);
+ sp<AudioTrack> track = new AudioTrack(mStreamType, mSampleRate, mFormat, channelMask,
+ mFrameCount, mFlags, nullptr /* callback */,
+ 0 /* notificationFrames */, AUDIO_SESSION_NONE);
+ ASSERT_EQ(track->initCheck(), NO_ERROR);
+
+ mPlayer = new TrackPlayer();
+ mPlayer->init(track.get(), mPlayer, PLAYER_TYPE_AAUDIO, AUDIO_USAGE_MEDIA,
+ AUDIO_SESSION_NONE);
+ sp<AudioTrack> playerTrack = mPlayer->mAudioTrack;
+ ASSERT_EQ(playerTrack->initCheck(), NO_ERROR);
+
+ mBufferSize = mFrameCount * playerTrack->frameSize();
+ mBuffer.resize(mBufferSize, 0);
+
+ // populate buffer
+ ASSERT_NE(mPulseFreq, 0);
+ int32_t nPulseSamples = mSampleRate / mPulseFreq;
+ int32_t pulseSize = nPulseSamples * playerTrack->frameSize();
+
+ int32_t marker = 0;
+ while (marker + pulseSize <= mBufferSize) {
+ memset(mBuffer.data() + marker, 127, pulseSize / 2);
+ marker += pulseSize;
+ }
+ }
+
+ void playBuffer() {
+ bool blocking = true;
+ ssize_t nbytes = mPlayer->mAudioTrack->write(mBuffer.data(), mBufferSize, blocking);
+ EXPECT_EQ(nbytes, mBufferSize) << "Did not write all data in blocking mode";
+ }
+
+ const double mDuration; // seconds
+ sp<TrackPlayer> mPlayer;
+
+ private:
+ const double mPulseFreq;
+ const uint32_t mChannelCount;
+ const uint32_t mSampleRate;
+
+ const audio_format_t mFormat = AUDIO_FORMAT_PCM_16_BIT;
+ const audio_output_flags_t mFlags = AUDIO_OUTPUT_FLAG_NONE;
+ const audio_stream_type_t mStreamType = AUDIO_STREAM_MUSIC;
+
+ int32_t mBufferSize;
+ int32_t mFrameCount;
+ std::vector<uint8_t> mBuffer;
+};
+
+class PlaybackTestParam : public TrackPlayerBaseTest {};
+
+TEST_P(PlaybackTestParam, PlaybackTest) {
+ // no-op implementation
+ EXPECT_TRUE(mPlayer->setStartDelayMs(0).isOk());
+
+ ASSERT_EQ(mPlayer->playerStart(), NO_ERROR);
+ ASSERT_NO_FATAL_FAILURE(playBuffer());
+ EXPECT_EQ(mPlayer->playerStop(), NO_ERROR);
+}
+
+INSTANTIATE_TEST_SUITE_P(TrackPlayerTest, PlaybackTestParam,
+ ::testing::Values(std::make_tuple(2.5, 25.0, 2, 48000)));
+
+class ChangeVolumeTestParam : public TrackPlayerBaseTest {};
+
+TEST_P(ChangeVolumeTestParam, ChangeVolumeTest) {
+ float volume = 1.0f;
+ (void)mPlayer->setPlayerVolume(volume / 2, volume);
+
+ ASSERT_TRUE(mPlayer->start().isOk());
+ ASSERT_EQ(mPlayer->playerSetVolume(), NO_ERROR);
+
+ ASSERT_NO_FATAL_FAILURE(playBuffer());
+
+ EXPECT_TRUE(mPlayer->stop().isOk());
+
+ std::vector<float> setVol = {0.95f, 0.05f, 0.5f, 0.25f, -1.0f, 1.0f, 1.0f};
+ std::vector<float> setPan = {0.0f, 0.0f, 1.0f, -1.0f, -1.0f, 0.5f, -0.5f};
+
+ ASSERT_TRUE(mPlayer->start().isOk());
+
+ for (int32_t i = 0; i < setVol.size(); i++) {
+ EXPECT_TRUE(mPlayer->setVolume(setVol[i]).isOk());
+ EXPECT_TRUE(mPlayer->setPan(setPan[i]).isOk());
+ ASSERT_NO_FATAL_FAILURE(playBuffer());
+ }
+ EXPECT_TRUE(mPlayer->stop().isOk());
+}
+
+INSTANTIATE_TEST_SUITE_P(TrackPlayerTest, ChangeVolumeTestParam,
+ ::testing::Values(std::make_tuple(1.0, 100.0, 1, 24000)));
+
+class PauseTestParam : public TrackPlayerBaseTest {};
+
+TEST_P(PauseTestParam, PauseTest) {
+ ASSERT_EQ(mPlayer->playerStart(), NO_ERROR);
+ ASSERT_NO_FATAL_FAILURE(playBuffer());
+
+ ASSERT_EQ(mPlayer->playerPause(), NO_ERROR);
+ ASSERT_EQ(mPlayer->playerStart(), NO_ERROR);
+
+ ASSERT_NO_FATAL_FAILURE(playBuffer());
+
+ EXPECT_EQ(mPlayer->playerStop(), NO_ERROR);
+
+ for (int32_t i = 0; i < 5; i++) {
+ ASSERT_TRUE(mPlayer->start().isOk());
+ ASSERT_NO_FATAL_FAILURE(playBuffer());
+ ASSERT_TRUE(mPlayer->pause().isOk());
+ }
+ EXPECT_TRUE(mPlayer->stop().isOk());
+}
+
+INSTANTIATE_TEST_SUITE_P(TrackPlayerTest, PauseTestParam,
+ ::testing::Values(std::make_tuple(1.0, 75.0, 2, 24000)));
diff --git a/media/libaudiofoundation/Android.bp b/media/libaudiofoundation/Android.bp
index 159f898..c758fcd 100644
--- a/media/libaudiofoundation/Android.bp
+++ b/media/libaudiofoundation/Android.bp
@@ -18,21 +18,22 @@
export_include_dirs: ["include"],
header_libs: [
- "libaudioclient_aidl_conversion_util",
+ "libaudio_aidl_conversion_common_util_cpp",
"libaudio_system_headers",
"libmedia_helper_headers",
],
export_header_lib_headers: [
- "libaudioclient_aidl_conversion_util",
+ "libaudio_aidl_conversion_common_util_cpp",
"libaudio_system_headers",
"libmedia_helper_headers",
],
+ defaults: [
+ "latest_android_media_audio_common_types_cpp_export_static",
+ ],
static_libs: [
- "android.media.audio.common.types-V1-cpp",
"audioclient-types-aidl-cpp",
],
export_static_lib_headers: [
- "android.media.audio.common.types-V1-cpp",
"audioclient-types-aidl-cpp",
],
host_supported: true,
@@ -57,8 +58,11 @@
"DeviceDescriptorBase.cpp",
],
+ defaults: [
+ "latest_android_media_audio_common_types_cpp_export_shared",
+ ],
+
shared_libs: [
- "android.media.audio.common.types-V1-cpp",
"audioclient-types-aidl-cpp",
"libaudioclient_aidl_conversion",
"libaudioutils",
@@ -70,7 +74,6 @@
],
export_shared_lib_headers: [
- "android.media.audio.common.types-V1-cpp",
"audioclient-types-aidl-cpp",
"libaudioclient_aidl_conversion",
],
diff --git a/media/libaudiofoundation/AudioPort.cpp b/media/libaudiofoundation/AudioPort.cpp
index 4513323..6e05abc 100644
--- a/media/libaudiofoundation/AudioPort.cpp
+++ b/media/libaudiofoundation/AudioPort.cpp
@@ -222,7 +222,7 @@
mExtraAudioDescriptors == other->getExtraAudioDescriptors();
}
-status_t AudioPort::writeToParcelable(media::AudioPort* parcelable) const {
+status_t AudioPort::writeToParcelable(media::AudioPortFw* parcelable) const {
parcelable->hal.name = mName;
parcelable->sys.type = VALUE_OR_RETURN_STATUS(
legacy2aidl_audio_port_type_t_AudioPortType(mType));
@@ -249,7 +249,7 @@
return OK;
}
-status_t AudioPort::readFromParcelable(const media::AudioPort& parcelable) {
+status_t AudioPort::readFromParcelable(const media::AudioPortFw& parcelable) {
mName = parcelable.hal.name;
mType = VALUE_OR_RETURN_STATUS(
aidl2legacy_AudioPortType_audio_port_type_t(parcelable.sys.type));
diff --git a/media/libaudiofoundation/DeviceDescriptorBase.cpp b/media/libaudiofoundation/DeviceDescriptorBase.cpp
index 5ffbffc..4185b5f 100644
--- a/media/libaudiofoundation/DeviceDescriptorBase.cpp
+++ b/media/libaudiofoundation/DeviceDescriptorBase.cpp
@@ -174,7 +174,7 @@
return false;
}
-status_t DeviceDescriptorBase::writeToParcelable(media::AudioPort* parcelable) const {
+status_t DeviceDescriptorBase::writeToParcelable(media::AudioPortFw* parcelable) const {
AudioPort::writeToParcelable(parcelable);
AudioPortConfig::writeToParcelable(&parcelable->sys.activeConfig.hal, useInputChannelMask());
parcelable->hal.id = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_port_handle_t_int32_t(mId));
@@ -196,7 +196,7 @@
return OK;
}
-status_t DeviceDescriptorBase::readFromParcelable(const media::AudioPort& parcelable) {
+status_t DeviceDescriptorBase::readFromParcelable(const media::AudioPortFw& parcelable) {
if (parcelable.sys.type != media::AudioPortType::DEVICE) {
return BAD_VALUE;
}
@@ -245,7 +245,7 @@
}
ConversionResult<sp<DeviceDescriptorBase>>
-aidl2legacy_DeviceDescriptorBase(const media::AudioPort& aidl) {
+aidl2legacy_DeviceDescriptorBase(const media::AudioPortFw& aidl) {
sp<DeviceDescriptorBase> result = new DeviceDescriptorBase(AUDIO_DEVICE_NONE);
status_t status = result->readFromParcelable(aidl);
if (status != OK) {
@@ -254,9 +254,9 @@
return result;
}
-ConversionResult<media::AudioPort>
+ConversionResult<media::AudioPortFw>
legacy2aidl_DeviceDescriptorBase(const sp<DeviceDescriptorBase>& legacy) {
- media::AudioPort aidl;
+ media::AudioPortFw aidl;
status_t status = legacy->writeToParcelable(&aidl);
if (status != OK) {
return base::unexpected(status);
diff --git a/media/libaudiofoundation/include/media/AudioContainers.h b/media/libaudiofoundation/include/media/AudioContainers.h
index b6e6c84..6c01e29 100644
--- a/media/libaudiofoundation/include/media/AudioContainers.h
+++ b/media/libaudiofoundation/include/media/AudioContainers.h
@@ -66,6 +66,9 @@
for (const auto &channel : channelMasks) {
if (audio_channel_mask_out_to_in(channel) != AUDIO_CHANNEL_INVALID) {
inMaskSet.insert(audio_channel_mask_out_to_in(channel));
+ } else if (audio_channel_mask_get_representation(channel)
+ == AUDIO_CHANNEL_REPRESENTATION_INDEX) {
+ inMaskSet.insert(channel);
}
}
return inMaskSet;
@@ -76,6 +79,9 @@
for (const auto &channel : channelMasks) {
if (audio_channel_mask_in_to_out(channel) != AUDIO_CHANNEL_INVALID) {
outMaskSet.insert(audio_channel_mask_in_to_out(channel));
+ } else if (audio_channel_mask_get_representation(channel)
+ == AUDIO_CHANNEL_REPRESENTATION_INDEX) {
+ outMaskSet.insert(channel);
}
}
return outMaskSet;
diff --git a/media/libaudiofoundation/include/media/AudioPort.h b/media/libaudiofoundation/include/media/AudioPort.h
index d6a098f..77e58ed 100644
--- a/media/libaudiofoundation/include/media/AudioPort.h
+++ b/media/libaudiofoundation/include/media/AudioPort.h
@@ -19,8 +19,8 @@
#include <string>
#include <type_traits>
-#include <android/media/AudioPort.h>
-#include <android/media/AudioPortConfig.h>
+#include <android/media/AudioPortFw.h>
+#include <android/media/AudioPortConfigFw.h>
#include <android/media/audio/common/ExtraAudioDescriptor.h>
#include <binder/Parcel.h>
#include <binder/Parcelable.h>
@@ -72,7 +72,7 @@
AudioProfileVector &getAudioProfiles() { return mProfiles; }
void setExtraAudioDescriptors(
- const std::vector<media::audio::common::ExtraAudioDescriptor> extraAudioDescriptors) {
+ const std::vector<media::audio::common::ExtraAudioDescriptor>& extraAudioDescriptors) {
mExtraAudioDescriptors = extraAudioDescriptors;
}
std::vector<media::audio::common::ExtraAudioDescriptor> &getExtraAudioDescriptors() {
@@ -118,8 +118,8 @@
bool equals(const sp<AudioPort>& other) const;
- status_t writeToParcelable(media::AudioPort* parcelable) const;
- status_t readFromParcelable(const media::AudioPort& parcelable);
+ status_t writeToParcelable(media::AudioPortFw* parcelable) const;
+ status_t readFromParcelable(const media::AudioPortFw& parcelable);
AudioGains mGains; // gain controllers
// Maximum number of input or output streams that can be simultaneously
diff --git a/media/libaudiofoundation/include/media/DeviceDescriptorBase.h b/media/libaudiofoundation/include/media/DeviceDescriptorBase.h
index 1f0c768..501831d 100644
--- a/media/libaudiofoundation/include/media/DeviceDescriptorBase.h
+++ b/media/libaudiofoundation/include/media/DeviceDescriptorBase.h
@@ -18,7 +18,7 @@
#include <vector>
-#include <android/media/AudioPort.h>
+#include <android/media/AudioPortFw.h>
#include <binder/Parcel.h>
#include <binder/Parcelable.h>
#include <media/AudioContainers.h>
@@ -53,7 +53,7 @@
// AudioPortConfig
virtual sp<AudioPort> getAudioPort() const {
- return static_cast<AudioPort*>(const_cast<DeviceDescriptorBase*>(this));
+ return sp<AudioPort>::fromExisting(const_cast<DeviceDescriptorBase*>(this));
}
virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
const struct audio_port_config *srcConfig = NULL) const;
@@ -79,8 +79,8 @@
bool equals(const sp<DeviceDescriptorBase>& other) const;
- status_t writeToParcelable(media::AudioPort* parcelable) const;
- status_t readFromParcelable(const media::AudioPort& parcelable);
+ status_t writeToParcelable(media::AudioPortFw* parcelable) const;
+ status_t readFromParcelable(const media::AudioPortFw& parcelable);
protected:
AudioDeviceTypeAddr mDeviceTypeAddr;
@@ -116,8 +116,8 @@
// Conversion routines, according to AidlConversion.h conventions.
ConversionResult<sp<DeviceDescriptorBase>>
-aidl2legacy_DeviceDescriptorBase(const media::AudioPort& aidl);
-ConversionResult<media::AudioPort>
+aidl2legacy_DeviceDescriptorBase(const media::AudioPortFw& aidl);
+ConversionResult<media::AudioPortFw>
legacy2aidl_DeviceDescriptorBase(const sp<DeviceDescriptorBase>& legacy);
} // namespace android
diff --git a/media/libaudiofoundation/tests/Android.bp b/media/libaudiofoundation/tests/Android.bp
index 3f1fbea..2f4aee0 100644
--- a/media/libaudiofoundation/tests/Android.bp
+++ b/media/libaudiofoundation/tests/Android.bp
@@ -10,6 +10,9 @@
cc_test {
name: "audiofoundation_parcelable_test",
+ defaults: [
+ "latest_android_media_audio_common_types_cpp_static",
+ ],
shared_libs: [
"libbase",
"libbinder",
@@ -18,9 +21,9 @@
],
static_libs: [
- "android.media.audio.common.types-V1-cpp",
"audioclient-types-aidl-cpp",
"libaudioclient_aidl_conversion",
+ "libaudio_aidl_conversion_common_cpp",
"libaudiofoundation",
"libstagefright_foundation",
],
diff --git a/media/libaudiofoundation/tests/audiofoundation_parcelable_test.cpp b/media/libaudiofoundation/tests/audiofoundation_parcelable_test.cpp
index 50d8dc8..e315858 100644
--- a/media/libaudiofoundation/tests/audiofoundation_parcelable_test.cpp
+++ b/media/libaudiofoundation/tests/audiofoundation_parcelable_test.cpp
@@ -117,7 +117,7 @@
audioPort->setGains(getAudioGainsForTest());
audioPort->setAudioProfiles(getAudioProfileVectorForTest());
- media::AudioPort parcelable;
+ media::AudioPortFw parcelable;
ASSERT_EQ(NO_ERROR, audioPort->writeToParcelable(&parcelable));
sp<AudioPort> audioPortFromParcel = new AudioPort(
"", AUDIO_PORT_TYPE_NONE, AUDIO_PORT_ROLE_NONE);
@@ -152,7 +152,7 @@
ASSERT_EQ(desc->setEncapsulationMetadataTypes(
AUDIO_ENCAPSULATION_METADATA_TYPE_ALL_POSITION_BITS), NO_ERROR);
- media::AudioPort parcelable;
+ media::AudioPortFw parcelable;
ASSERT_EQ(NO_ERROR, desc->writeToParcelable(&parcelable));
sp<DeviceDescriptorBase> descFromParcel = new DeviceDescriptorBase(AUDIO_DEVICE_NONE);
ASSERT_EQ(NO_ERROR, descFromParcel->readFromParcelable(parcelable));
diff --git a/media/libaudiohal/Android.bp b/media/libaudiohal/Android.bp
index 5f63e8d..f47dd0b 100644
--- a/media/libaudiohal/Android.bp
+++ b/media/libaudiohal/Android.bp
@@ -13,7 +13,7 @@
srcs: [
"DevicesFactoryHalInterface.cpp",
"EffectsFactoryHalInterface.cpp",
- "FactoryHalHidl.cpp",
+ "FactoryHal.cpp",
],
cflags: [
@@ -28,10 +28,12 @@
"libaudiohal@6.0",
"libaudiohal@7.0",
"libaudiohal@7.1",
+ "libaudiohal@aidl",
],
shared_libs: [
"audioclient-types-aidl-cpp",
+ "libbinder_ndk",
"libdl",
"libhidlbase",
"liblog",
@@ -41,6 +43,7 @@
header_libs: [
"libaudiohal_headers",
"libbase_headers",
+ "liberror_headers",
"libmediautils_headers",
]
}
@@ -65,15 +68,11 @@
header_libs: [
"libaudiohal_headers"
- ]
+ ],
}
cc_library_headers {
name: "libaudiohal_headers",
export_include_dirs: ["include"],
-
- // This is needed because the stream interface includes media/MicrophoneInfo.h
- header_libs: ["av-headers"],
- export_header_lib_headers: ["av-headers"],
}
diff --git a/media/libaudiohal/DevicesFactoryHalInterface.cpp b/media/libaudiohal/DevicesFactoryHalInterface.cpp
index 5ad26fc..adce681 100644
--- a/media/libaudiohal/DevicesFactoryHalInterface.cpp
+++ b/media/libaudiohal/DevicesFactoryHalInterface.cpp
@@ -14,19 +14,14 @@
* limitations under the License.
*/
-#include <string>
-
#include <media/audiohal/DevicesFactoryHalInterface.h>
-#include <media/audiohal/FactoryHalHidl.h>
+#include <media/audiohal/FactoryHal.h>
namespace android {
// static
sp<DevicesFactoryHalInterface> DevicesFactoryHalInterface::create() {
- using namespace std::string_literals;
- return createPreferredImpl<DevicesFactoryHalInterface>(
- std::make_pair("android.hardware.audio"s, "IDevicesFactory"s),
- std::make_pair("android.hardware.audio.effect"s, "IEffectsFactory"s));
+ return createPreferredImpl<DevicesFactoryHalInterface>(true /* isCore */);
}
} // namespace android
diff --git a/media/libaudiohal/EffectsFactoryHalInterface.cpp b/media/libaudiohal/EffectsFactoryHalInterface.cpp
index 8a28f64..3a05f21 100644
--- a/media/libaudiohal/EffectsFactoryHalInterface.cpp
+++ b/media/libaudiohal/EffectsFactoryHalInterface.cpp
@@ -14,19 +14,14 @@
* limitations under the License.
*/
-#include <string>
-
#include <media/audiohal/EffectsFactoryHalInterface.h>
-#include <media/audiohal/FactoryHalHidl.h>
+#include <media/audiohal/FactoryHal.h>
namespace android {
// static
sp<EffectsFactoryHalInterface> EffectsFactoryHalInterface::create() {
- using namespace std::string_literals;
- return createPreferredImpl<EffectsFactoryHalInterface>(
- std::make_pair("android.hardware.audio.effect"s, "IEffectsFactory"s),
- std::make_pair("android.hardware.audio"s, "IDevicesFactory"s));
+ return createPreferredImpl<EffectsFactoryHalInterface>(false /* isCore */);
}
// static
diff --git a/media/libaudiohal/FactoryHal.cpp b/media/libaudiohal/FactoryHal.cpp
new file mode 100644
index 0000000..84ac64c
--- /dev/null
+++ b/media/libaudiohal/FactoryHal.cpp
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <map>
+#include <memory>
+#define LOG_TAG "FactoryHal"
+
+#include <algorithm>
+#include <array>
+#include <cstddef>
+#include <dlfcn.h>
+#include <utility>
+
+#include <android/binder_manager.h>
+#include <android/hidl/manager/1.0/IServiceManager.h>
+#include <hidl/ServiceManagement.h>
+#include <hidl/Status.h>
+#include <utils/Log.h>
+
+#include "include/media/audiohal/AudioHalVersionInfo.h"
+#include "include/media/audiohal/FactoryHal.h"
+
+namespace android::detail {
+
+namespace {
+
+using ::android::detail::AudioHalVersionInfo;
+
+// The pair of the interface's package name and the interface name,
+// e.g. <"android.hardware.audio", "IDevicesFactory"> for HIDL, <"android.hardware.audio.core",
+// "IModule"> for AIDL.
+// Splitting is used for easier construction of versioned names (FQNs).
+using InterfaceName = std::pair<std::string, std::string>;
+
+/**
+ * Supported HAL versions, from most recent to least recent.
+ * This list need to keep sync with AudioHalVersionInfo.VERSIONS in
+ * media/java/android/media/AudioHalVersionInfo.java.
+ */
+static const std::array<AudioHalVersionInfo, 5> sAudioHALVersions = {
+ // TODO: remove this comment to get AIDL
+ // AudioHalVersionInfo(AudioHalVersionInfo::Type::AIDL, 1, 0),
+ AudioHalVersionInfo(AudioHalVersionInfo::Type::HIDL, 7, 1),
+ AudioHalVersionInfo(AudioHalVersionInfo::Type::HIDL, 7, 0),
+ AudioHalVersionInfo(AudioHalVersionInfo::Type::HIDL, 6, 0),
+ AudioHalVersionInfo(AudioHalVersionInfo::Type::HIDL, 5, 0),
+ AudioHalVersionInfo(AudioHalVersionInfo::Type::HIDL, 4, 0),
+};
+
+static const std::map<AudioHalVersionInfo::Type, InterfaceName> sDevicesHALInterfaces = {
+ {AudioHalVersionInfo::Type::AIDL, std::make_pair("android.hardware.audio.core", "IModule")},
+ {AudioHalVersionInfo::Type::HIDL,
+ std::make_pair("android.hardware.audio", "IDevicesFactory")},
+};
+
+static const std::map<AudioHalVersionInfo::Type, InterfaceName> sEffectsHALInterfaces = {
+ {AudioHalVersionInfo::Type::AIDL,
+ std::make_pair("android.hardware.audio.effect", "IFactory")},
+ {AudioHalVersionInfo::Type::HIDL,
+ std::make_pair("android.hardware.audio.effect", "IEffectsFactory")},
+};
+
+bool createHalService(const AudioHalVersionInfo& version, bool isDevice, void** rawInterface) {
+ const std::string libName = "libaudiohal@" + version.toVersionString() + ".so";
+ const std::string factoryFunctionName =
+ isDevice ? "createIDevicesFactory" : "createIEffectsFactory";
+ constexpr int dlMode = RTLD_LAZY;
+ void* handle = nullptr;
+ dlerror(); // clear
+ handle = dlopen(libName.c_str(), dlMode);
+ if (handle == nullptr) {
+ const char* error = dlerror();
+ ALOGE("Failed to dlopen %s: %s", libName.c_str(),
+ error != nullptr ? error : "unknown error");
+ return false;
+ }
+ void* (*factoryFunction)();
+ *(void **)(&factoryFunction) = dlsym(handle, factoryFunctionName.c_str());
+ if (!factoryFunction) {
+ const char* error = dlerror();
+ ALOGE("Factory function %s not found in library %s: %s",
+ factoryFunctionName.c_str(), libName.c_str(),
+ error != nullptr ? error : "unknown error");
+ dlclose(handle);
+ return false;
+ }
+ *rawInterface = (*factoryFunction)();
+ ALOGW_IF(!*rawInterface, "Factory function %s from %s returned nullptr",
+ factoryFunctionName.c_str(), libName.c_str());
+ return true;
+}
+
+bool hasAidlHalService(const InterfaceName& interface, const AudioHalVersionInfo& version) {
+ const std::string name = interface.first + "." + interface.second + "/default";
+ AIBinder* binder = AServiceManager_checkService(name.c_str());
+ if (binder == nullptr) {
+ ALOGW("%s Service %s doesn't exist", __func__, name.c_str());
+ return false;
+ }
+ ALOGI("%s AIDL Service %s exist: %s", __func__, name.c_str(), version.toString().c_str());
+ return true;
+}
+
+bool hasHidlHalService(const InterfaceName& interface, const AudioHalVersionInfo& version) {
+ using ::android::hidl::manager::V1_0::IServiceManager;
+ sp<IServiceManager> sm = ::android::hardware::defaultServiceManager();
+ if (!sm) {
+ ALOGW("Failed to obtain HIDL ServiceManager");
+ return false;
+ }
+ // Since audio HAL doesn't support multiple clients, avoid instantiating
+ // the interface right away. Instead, query the transport type for it.
+ using ::android::hardware::Return;
+ using Transport = IServiceManager::Transport;
+ const std::string fqName =
+ interface.first + "@" + version.toVersionString() + "::" + interface.second;
+ const std::string instance = "default";
+ Return<Transport> transport = sm->getTransport(fqName, instance);
+ if (!transport.isOk()) {
+ ALOGW("Failed to obtain transport type for %s/%s: %s",
+ fqName.c_str(), instance.c_str(), transport.description().c_str());
+ return false;
+ }
+ return transport != Transport::EMPTY;
+}
+
+bool hasHalService(const InterfaceName& interface, const AudioHalVersionInfo& version) {
+ auto halType = version.getType();
+ if (halType == AudioHalVersionInfo::Type::AIDL) {
+ return hasAidlHalService(interface, version);
+ } else if (halType == AudioHalVersionInfo::Type::HIDL) {
+ return hasHidlHalService(interface, version);
+ } else {
+ ALOGE("HalType not supported %s", version.toString().c_str());
+ return false;
+ }
+}
+
+} // namespace
+
+void *createPreferredImpl(bool isDevice) {
+ auto findMostRecentVersion = [](const auto& iMap) {
+ return std::find_if(sAudioHALVersions.begin(), sAudioHALVersions.end(),
+ [iMap](const auto& v) {
+ auto iface = iMap.find(v.getType());
+ return hasHalService(iface->second, v);
+ });
+ };
+
+ auto interfaceMap = isDevice ? sDevicesHALInterfaces : sEffectsHALInterfaces;
+ auto siblingInterfaceMap = isDevice ? sEffectsHALInterfaces : sDevicesHALInterfaces;
+ auto ifaceVersionIt = findMostRecentVersion(interfaceMap);
+ auto siblingVersionIt = findMostRecentVersion(siblingInterfaceMap);
+ if (ifaceVersionIt != sAudioHALVersions.end() && siblingVersionIt != sAudioHALVersions.end() &&
+ // same HAL type (HIDL/AIDL) and same major version
+ ifaceVersionIt->getType() == siblingVersionIt->getType() &&
+ ifaceVersionIt->getMajorVersion() == siblingVersionIt->getMajorVersion()) {
+ void* rawInterface;
+ if (createHalService(std::max(*ifaceVersionIt, *siblingVersionIt), isDevice,
+ &rawInterface)) {
+ return rawInterface;
+ } else {
+ ALOGE("Failed to create HAL services with major %s, sibling %s!",
+ ifaceVersionIt->toString().c_str(), siblingVersionIt->toString().c_str());
+ }
+ } else {
+ ALOGE("Found no HAL version, main(%s) %s %s!", isDevice ? "Device" : "Effect",
+ (ifaceVersionIt == sAudioHALVersions.end()) ? "null"
+ : ifaceVersionIt->toString().c_str(),
+ (siblingVersionIt == sAudioHALVersions.end()) ? "null"
+ : siblingVersionIt->toString().c_str());
+ }
+ return nullptr;
+}
+
+} // namespace android::detail
diff --git a/media/libaudiohal/FactoryHalHidl.cpp b/media/libaudiohal/FactoryHalHidl.cpp
deleted file mode 100644
index 590fec5..0000000
--- a/media/libaudiohal/FactoryHalHidl.cpp
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2020 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 "FactoryHalHidl"
-
-#include <algorithm>
-#include <array>
-#include <utility>
-
-#include <media/audiohal/FactoryHalHidl.h>
-
-#include <dlfcn.h>
-
-#include <android/hidl/manager/1.0/IServiceManager.h>
-#include <hidl/ServiceManagement.h>
-#include <hidl/Status.h>
-#include <utils/Log.h>
-
-namespace android::detail {
-
-namespace {
-/** Supported HAL versions, from most recent to least recent.
- */
-#define CONC_VERSION(maj, min) #maj "." #min
-#define DECLARE_VERSION(maj, min) std::make_pair(std::make_pair(maj, min), CONC_VERSION(maj, min))
-static constexpr std::array<std::pair<std::pair<int, int>, const char*>, 5> sAudioHALVersions = {
- DECLARE_VERSION(7, 1),
- DECLARE_VERSION(7, 0),
- DECLARE_VERSION(6, 0),
- DECLARE_VERSION(5, 0),
- DECLARE_VERSION(4, 0)
-};
-
-bool createHalService(const std::string& version, const std::string& interface,
- void** rawInterface) {
- const std::string libName = "libaudiohal@" + version + ".so";
- const std::string factoryFunctionName = "create" + interface;
- constexpr int dlMode = RTLD_LAZY;
- void* handle = nullptr;
- dlerror(); // clear
- handle = dlopen(libName.c_str(), dlMode);
- if (handle == nullptr) {
- const char* error = dlerror();
- ALOGE("Failed to dlopen %s: %s", libName.c_str(),
- error != nullptr ? error : "unknown error");
- return false;
- }
- void* (*factoryFunction)();
- *(void **)(&factoryFunction) = dlsym(handle, factoryFunctionName.c_str());
- if (!factoryFunction) {
- const char* error = dlerror();
- ALOGE("Factory function %s not found in library %s: %s",
- factoryFunctionName.c_str(), libName.c_str(),
- error != nullptr ? error : "unknown error");
- dlclose(handle);
- return false;
- }
- *rawInterface = (*factoryFunction)();
- ALOGW_IF(!*rawInterface, "Factory function %s from %s returned nullptr",
- factoryFunctionName.c_str(), libName.c_str());
- return true;
-}
-
-bool hasHalService(const std::string& package, const std::string& version,
- const std::string& interface) {
- using ::android::hidl::manager::V1_0::IServiceManager;
- sp<IServiceManager> sm = ::android::hardware::defaultServiceManager();
- if (!sm) {
- ALOGE("Failed to obtain HIDL ServiceManager");
- return false;
- }
- // Since audio HAL doesn't support multiple clients, avoid instantiating
- // the interface right away. Instead, query the transport type for it.
- using ::android::hardware::Return;
- using Transport = IServiceManager::Transport;
- const std::string fqName = package + "@" + version + "::" + interface;
- const std::string instance = "default";
- Return<Transport> transport = sm->getTransport(fqName, instance);
- if (!transport.isOk()) {
- ALOGE("Failed to obtain transport type for %s/%s: %s",
- fqName.c_str(), instance.c_str(), transport.description().c_str());
- return false;
- }
- return transport != Transport::EMPTY;
-}
-
-} // namespace
-
-void* createPreferredImpl(const InterfaceName& iface, const InterfaceName& siblingIface) {
- auto findMostRecentVersion = [](const InterfaceName& iface) {
- return std::find_if(detail::sAudioHALVersions.begin(), detail::sAudioHALVersions.end(),
- [&](const auto& v) { return hasHalService(iface.first, v.second, iface.second); });
- };
- auto ifaceVersionIt = findMostRecentVersion(iface);
- auto siblingVersionIt = findMostRecentVersion(siblingIface);
- if (ifaceVersionIt != detail::sAudioHALVersions.end() &&
- siblingVersionIt != detail::sAudioHALVersions.end() &&
- // same major version
- ifaceVersionIt->first.first == siblingVersionIt->first.first) {
- std::string libraryVersion =
- ifaceVersionIt->first >= siblingVersionIt->first ?
- ifaceVersionIt->second : siblingVersionIt->second;
- void* rawInterface;
- if (createHalService(libraryVersion, iface.second, &rawInterface)) {
- return rawInterface;
- }
- }
- return nullptr;
-}
-
-} // namespace android::detail
diff --git a/media/libaudiohal/impl/Android.bp b/media/libaudiohal/impl/Android.bp
index d30883a..829a79a 100644
--- a/media/libaudiohal/impl/Android.bp
+++ b/media/libaudiohal/impl/Android.bp
@@ -12,13 +12,14 @@
srcs: [
"CoreConversionHelperHidl.cpp",
"DeviceHalHidl.cpp",
+ "DevicesFactoryHalEntry.cpp",
"DevicesFactoryHalHidl.cpp",
"StreamHalHidl.cpp",
],
}
filegroup {
- name: "audio_effect_hal_client_sources",
+ name: "audio_effect_hidl_hal_client_sources",
srcs: [
"EffectBufferHalHidl.cpp",
"EffectConversionHelperHidl.cpp",
@@ -28,6 +29,21 @@
}
cc_defaults {
+ name: "libaudiohal_hidl_default",
+ shared_libs: [
+ "android.hardware.audio.common-util",
+ "android.hidl.allocator@1.0",
+ "android.hidl.memory@1.0",
+ "libaudiohal_deathhandler",
+ "libhidlbase",
+ "libhidlmemory",
+ ],
+ header_libs: [
+ "android.hardware.audio.common.util@all-versions",
+ ]
+}
+
+cc_defaults {
name: "libaudiohal_default",
cflags: [
@@ -37,28 +53,21 @@
"-fvisibility=hidden",
],
shared_libs: [
- "android.hardware.audio.common-util",
- "android.hidl.allocator@1.0",
- "android.hidl.memory@1.0",
+ "audioclient-types-aidl-cpp",
"av-types-aidl-cpp",
"libaudiofoundation",
- "libaudiohal_deathhandler",
"libaudioutils",
"libbase",
"libbinder",
"libcutils",
"libfmq",
"libhardware",
- "libhidlbase",
- "libhidlmemory",
"liblog",
"libmedia_helper",
"libmediautils",
"libutils",
- "audioclient-types-aidl-cpp",
],
header_libs: [
- "android.hardware.audio.common.util@all-versions",
"libaudioclient_headers",
"libaudiohal_headers"
],
@@ -70,11 +79,14 @@
cc_library_shared {
name: "libaudiohal@4.0",
- defaults: ["libaudiohal_default"],
+ defaults: [
+ "libaudiohal_default",
+ "libaudiohal_hidl_default"
+ ],
srcs: [
":audio_core_hal_client_sources",
- ":audio_effect_hal_client_sources",
- "EffectsFactoryHalHidlEntry.cpp",
+ ":audio_effect_hidl_hal_client_sources",
+ "EffectsFactoryHalEntry.cpp",
],
shared_libs: [
"android.hardware.audio.common@4.0",
@@ -93,11 +105,14 @@
cc_library_shared {
name: "libaudiohal@5.0",
- defaults: ["libaudiohal_default"],
+ defaults: [
+ "libaudiohal_default",
+ "libaudiohal_hidl_default"
+ ],
srcs: [
":audio_core_hal_client_sources",
- ":audio_effect_hal_client_sources",
- "EffectsFactoryHalHidlEntry.cpp",
+ ":audio_effect_hidl_hal_client_sources",
+ "EffectsFactoryHalEntry.cpp",
],
shared_libs: [
"android.hardware.audio.common@5.0",
@@ -116,11 +131,14 @@
cc_library_shared {
name: "libaudiohal@6.0",
- defaults: ["libaudiohal_default"],
+ defaults: [
+ "libaudiohal_default",
+ "libaudiohal_hidl_default"
+ ],
srcs: [
":audio_core_hal_client_sources",
- ":audio_effect_hal_client_sources",
- "EffectsFactoryHalHidlEntry.cpp",
+ ":audio_effect_hidl_hal_client_sources",
+ "EffectsFactoryHalEntry.cpp",
],
shared_libs: [
"android.hardware.audio.common@6.0",
@@ -139,9 +157,12 @@
cc_library_static {
name: "libaudiohal.effect@7.0",
- defaults: ["libaudiohal_default"],
+ defaults: [
+ "libaudiohal_default",
+ "libaudiohal_hidl_default"
+ ],
srcs: [
- ":audio_effect_hal_client_sources",
+ ":audio_effect_hidl_hal_client_sources",
],
static_libs: [
"android.hardware.audio.common@7.0",
@@ -158,10 +179,13 @@
cc_library_shared {
name: "libaudiohal@7.0",
- defaults: ["libaudiohal_default"],
+ defaults: [
+ "libaudiohal_default",
+ "libaudiohal_hidl_default"
+ ],
srcs: [
":audio_core_hal_client_sources",
- "EffectsFactoryHalHidlEntry.cpp",
+ "EffectsFactoryHalEntry.cpp",
],
static_libs: [
"android.hardware.audio.common@7.0",
@@ -182,10 +206,13 @@
cc_library_shared {
name: "libaudiohal@7.1",
- defaults: ["libaudiohal_default"],
+ defaults: [
+ "libaudiohal_default",
+ "libaudiohal_hidl_default"
+ ],
srcs: [
":audio_core_hal_client_sources",
- "EffectsFactoryHalHidlEntry.cpp",
+ "EffectsFactoryHalEntry.cpp",
],
static_libs: [
"android.hardware.audio.common@7.0",
@@ -207,3 +234,44 @@
"-include common/all-versions/VersionMacro.h",
]
}
+
+cc_library_shared {
+ name: "libaudiohal@aidl",
+ defaults: [
+ "libaudiohal_default",
+ "latest_android_hardware_audio_common_ndk_shared",
+ "latest_android_hardware_audio_core_ndk_shared",
+ "latest_android_hardware_audio_effect_ndk_static",
+ "latest_android_media_audio_common_types_ndk_shared",
+ ],
+ srcs: [
+ "DeviceHalAidl.cpp",
+ "DevicesFactoryHalEntry.cpp",
+ "DevicesFactoryHalAidl.cpp",
+ "EffectConversionHelperAidl.cpp",
+ "EffectBufferHalAidl.cpp",
+ "EffectHalAidl.cpp",
+ "EffectsFactoryHalAidl.cpp",
+ "EffectsFactoryHalEntry.cpp",
+ "StreamHalAidl.cpp",
+ ],
+ static_libs: [
+ "android.hardware.common-V2-ndk",
+ "android.hardware.common.fmq-V1-ndk",
+ ],
+ shared_libs: [
+ "libbinder_ndk",
+ "libaudio_aidl_conversion_common_ndk",
+ ],
+ header_libs: [
+ "libaudio_aidl_conversion_common_util_ndk",
+ "libaudio_system_headers",
+ ],
+ cflags: [
+ "-Wall",
+ "-Wextra",
+ "-Werror",
+ "-Wthread-safety",
+ "-DBACKEND_NDK",
+ ],
+}
diff --git a/media/libaudiohal/impl/ConversionHelperAidl.h b/media/libaudiohal/impl/ConversionHelperAidl.h
new file mode 100644
index 0000000..db6b6cf
--- /dev/null
+++ b/media/libaudiohal/impl/ConversionHelperAidl.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2023 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 <string_view>
+#include <vector>
+
+#include <utils/String16.h>
+#include <utils/Vector.h>
+
+namespace android {
+
+class Args {
+ public:
+ explicit Args(const Vector<String16>& args)
+ : mValues(args.size()), mPtrs(args.size()) {
+ for (size_t i = 0; i < args.size(); ++i) {
+ mValues[i] = std::string(String8(args[i]));
+ mPtrs[i] = mValues[i].c_str();
+ }
+ }
+ const char** args() { return mPtrs.data(); }
+ private:
+ std::vector<std::string> mValues;
+ std::vector<const char*> mPtrs;
+};
+
+class ConversionHelperAidl {
+ protected:
+ ConversionHelperAidl(std::string_view className) : mClassName(className) {}
+
+ const std::string& getClassName() const {
+ return mClassName;
+ }
+
+ const std::string mClassName;
+};
+
+} // namespace android
diff --git a/media/libaudiohal/impl/DeviceHalAidl.cpp b/media/libaudiohal/impl/DeviceHalAidl.cpp
new file mode 100644
index 0000000..179a655
--- /dev/null
+++ b/media/libaudiohal/impl/DeviceHalAidl.cpp
@@ -0,0 +1,289 @@
+/*
+ * Copyright (C) 2022 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 "DeviceHalAidl"
+
+#include <aidl/android/hardware/audio/core/StreamDescriptor.h>
+#include <error/expected_utils.h>
+#include <media/AidlConversionCppNdk.h>
+#include <media/AidlConversionUtil.h>
+#include <mediautils/TimeCheck.h>
+#include <utils/Log.h>
+
+#include "DeviceHalAidl.h"
+#include "StreamHalAidl.h"
+
+using aidl::android::aidl_utils::statusTFromBinderStatus;
+using aidl::android::media::audio::common::AudioMode;
+using aidl::android::media::audio::common::Float;
+using aidl::android::hardware::audio::core::IModule;
+using aidl::android::hardware::audio::core::ITelephony;
+using aidl::android::hardware::audio::core::StreamDescriptor;
+
+namespace android {
+
+status_t DeviceHalAidl::getSupportedDevices(uint32_t*) {
+ // Obsolete.
+ return INVALID_OPERATION;
+}
+
+status_t DeviceHalAidl::initCheck() {
+ if (mModule == nullptr) return NO_INIT;
+ // HAL modules are already initialized by the time they are published to the SM.
+ return OK;
+}
+
+status_t DeviceHalAidl::setVoiceVolume(float volume) {
+ TIME_CHECK();
+ if (!mModule) return NO_INIT;
+ std::shared_ptr<ITelephony> telephony;
+ if (ndk::ScopedAStatus status = mModule->getTelephony(&telephony);
+ status.isOk() && telephony != nullptr) {
+ ITelephony::TelecomConfig inConfig{ .voiceVolume = Float{volume} }, outConfig;
+ RETURN_STATUS_IF_ERROR(
+ statusTFromBinderStatus(telephony->setTelecomConfig(inConfig, &outConfig)));
+ ALOGW_IF(outConfig.voiceVolume.has_value() && volume != outConfig.voiceVolume.value().value,
+ "%s: the resulting voice volume %f is not the same as requested %f",
+ __func__, outConfig.voiceVolume.value().value, volume);
+ }
+ return INVALID_OPERATION;
+}
+
+status_t DeviceHalAidl::setMasterVolume(float volume) {
+ TIME_CHECK();
+ if (!mModule) return NO_INIT;
+ return statusTFromBinderStatus(mModule->setMasterVolume(volume));
+}
+
+status_t DeviceHalAidl::getMasterVolume(float *volume) {
+ TIME_CHECK();
+ if (!mModule) return NO_INIT;
+ return statusTFromBinderStatus(mModule->getMasterVolume(volume));
+}
+
+status_t DeviceHalAidl::setMode(audio_mode_t mode) {
+ TIME_CHECK();
+ if (!mModule) return NO_INIT;
+ AudioMode audioMode = VALUE_OR_FATAL(::aidl::android::legacy2aidl_audio_mode_t_AudioMode(mode));
+ std::shared_ptr<ITelephony> telephony;
+ if (ndk::ScopedAStatus status = mModule->getTelephony(&telephony);
+ status.isOk() && telephony != nullptr) {
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(telephony->switchAudioMode(audioMode)));
+ }
+ return statusTFromBinderStatus(mModule->updateAudioMode(audioMode));
+}
+
+status_t DeviceHalAidl::setMicMute(bool state) {
+ TIME_CHECK();
+ if (!mModule) return NO_INIT;
+ return statusTFromBinderStatus(mModule->setMicMute(state));
+}
+
+status_t DeviceHalAidl::getMicMute(bool *state) {
+ TIME_CHECK();
+ if (!mModule) return NO_INIT;
+ return statusTFromBinderStatus(mModule->getMicMute(state));
+}
+
+status_t DeviceHalAidl::setMasterMute(bool state) {
+ TIME_CHECK();
+ if (!mModule) return NO_INIT;
+ return statusTFromBinderStatus(mModule->setMasterMute(state));
+}
+
+status_t DeviceHalAidl::getMasterMute(bool *state) {
+ TIME_CHECK();
+ if (!mModule) return NO_INIT;
+ return statusTFromBinderStatus(mModule->getMasterMute(state));
+}
+
+status_t DeviceHalAidl::setParameters(const String8& kvPairs __unused) {
+ TIME_CHECK();
+ if (!mModule) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t DeviceHalAidl::getParameters(const String8& keys __unused, String8 *values) {
+ TIME_CHECK();
+ values->clear();
+ if (!mModule) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t DeviceHalAidl::getInputBufferSize(
+ const struct audio_config* config __unused, size_t* size __unused) {
+ TIME_CHECK();
+ if (!mModule) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t DeviceHalAidl::openOutputStream(
+ audio_io_handle_t handle __unused, audio_devices_t devices __unused,
+ audio_output_flags_t flags __unused, struct audio_config* config,
+ const char* address __unused,
+ sp<StreamOutHalInterface>* outStream) {
+ if (!outStream || !config) {
+ return BAD_VALUE;
+ }
+ TIME_CHECK();
+ if (!mModule) return NO_INIT;
+ config->sample_rate = 48000;
+ config->format = AUDIO_FORMAT_PCM_24_BIT_PACKED;
+ config->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+ StreamDescriptor descriptor;
+ descriptor.frameSizeBytes = audio_bytes_per_sample(config->format) *
+ audio_channel_count_from_out_mask(config->channel_mask);
+ descriptor.bufferSizeFrames = 600;
+ *outStream = sp<StreamOutHalAidl>::make(descriptor, nullptr);
+ return OK;
+}
+
+status_t DeviceHalAidl::openInputStream(
+ audio_io_handle_t handle __unused, audio_devices_t devices __unused,
+ struct audio_config* config, audio_input_flags_t flags __unused,
+ const char* address __unused, audio_source_t source __unused,
+ audio_devices_t outputDevice __unused,
+ const char* outputDeviceAddress __unused,
+ sp<StreamInHalInterface>* inStream) {
+ if (!inStream || !config) {
+ return BAD_VALUE;
+ }
+ TIME_CHECK();
+ if (!mModule) return NO_INIT;
+ config->sample_rate = 48000;
+ config->format = AUDIO_FORMAT_PCM_24_BIT_PACKED;
+ config->channel_mask = AUDIO_CHANNEL_IN_STEREO;
+ StreamDescriptor descriptor;
+ descriptor.frameSizeBytes = audio_bytes_per_sample(config->format) *
+ audio_channel_count_from_out_mask(config->channel_mask);
+ descriptor.bufferSizeFrames = 600;
+ *inStream = sp<StreamInHalAidl>::make(descriptor, nullptr);
+ return OK;
+}
+
+status_t DeviceHalAidl::supportsAudioPatches(bool* supportsPatches) {
+ *supportsPatches = true;
+ return OK;
+}
+
+status_t DeviceHalAidl::createAudioPatch(unsigned int num_sources __unused,
+ const struct audio_port_config* sources __unused,
+ unsigned int num_sinks __unused,
+ const struct audio_port_config* sinks __unused,
+ audio_patch_handle_t* patch __unused) {
+ TIME_CHECK();
+ if (!mModule) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t DeviceHalAidl::releaseAudioPatch(audio_patch_handle_t patch __unused) {
+ TIME_CHECK();
+ if (!mModule) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t DeviceHalAidl::getAudioPort(struct audio_port* port __unused) {
+ TIME_CHECK();
+ ALOGE("%s not implemented yet", __func__);
+ return INVALID_OPERATION;
+}
+
+status_t DeviceHalAidl::getAudioPort(struct audio_port_v7 *port __unused) {
+ TIME_CHECK();
+ ALOGE("%s not implemented yet", __func__);
+ return INVALID_OPERATION;
+}
+
+status_t DeviceHalAidl::setAudioPortConfig(const struct audio_port_config* config __unused) {
+ TIME_CHECK();
+ if (!mModule) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t DeviceHalAidl::getMicrophones(
+ std::vector<audio_microphone_characteristic_t>* microphones __unused) {
+ TIME_CHECK();
+ if (!mModule) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t DeviceHalAidl::addDeviceEffect(audio_port_handle_t device __unused,
+ sp<EffectHalInterface> effect) {
+ if (!effect) {
+ return BAD_VALUE;
+ }
+ TIME_CHECK();
+ if (!mModule) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+status_t DeviceHalAidl::removeDeviceEffect(audio_port_handle_t device __unused,
+ sp<EffectHalInterface> effect) {
+ if (!effect) {
+ return BAD_VALUE;
+ }
+ TIME_CHECK();
+ if (!mModule) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t DeviceHalAidl::getMmapPolicyInfos(
+ media::audio::common::AudioMMapPolicyType policyType __unused,
+ std::vector<media::audio::common::AudioMMapPolicyInfo>* policyInfos __unused) {
+ TIME_CHECK();
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+int32_t DeviceHalAidl::getAAudioMixerBurstCount() {
+ TIME_CHECK();
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+int32_t DeviceHalAidl::getAAudioHardwareBurstMinUsec() {
+ TIME_CHECK();
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+error::Result<audio_hw_sync_t> DeviceHalAidl::getHwAvSync() {
+ TIME_CHECK();
+ ALOGE("%s not implemented yet", __func__);
+ return base::unexpected(INVALID_OPERATION);
+}
+
+status_t DeviceHalAidl::dump(int fd, const Vector<String16>& args) {
+ TIME_CHECK();
+ if (!mModule) return NO_INIT;
+ return mModule->dump(fd, Args(args).args(), args.size());
+};
+
+int32_t DeviceHalAidl::supportsBluetoothVariableLatency(bool* supports __unused) {
+ TIME_CHECK();
+ ALOGE("%s not implemented yet", __func__);
+ return INVALID_OPERATION;
+}
+
+} // namespace android
diff --git a/media/libaudiohal/impl/DeviceHalAidl.h b/media/libaudiohal/impl/DeviceHalAidl.h
new file mode 100644
index 0000000..99e28d8
--- /dev/null
+++ b/media/libaudiohal/impl/DeviceHalAidl.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2022 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 <aidl/android/hardware/audio/core/BpModule.h>
+#include <media/audiohal/DeviceHalInterface.h>
+#include <media/audiohal/EffectHalInterface.h>
+
+#include "ConversionHelperAidl.h"
+
+namespace android {
+
+class DeviceHalAidl : public DeviceHalInterface, public ConversionHelperAidl {
+ public:
+ // Sets the value of 'devices' to a bitmask of 1 or more values of audio_devices_t.
+ status_t getSupportedDevices(uint32_t *devices) override;
+
+ // Check to see if the audio hardware interface has been initialized.
+ status_t initCheck() override;
+
+ // Set the audio volume of a voice call. Range is between 0.0 and 1.0.
+ status_t setVoiceVolume(float volume) override;
+
+ // Set the audio volume for all audio activities other than voice call.
+ status_t setMasterVolume(float volume) override;
+
+ // Get the current master volume value for the HAL.
+ status_t getMasterVolume(float *volume) override;
+
+ // Called when the audio mode changes.
+ status_t setMode(audio_mode_t mode) override;
+
+ // Muting control.
+ status_t setMicMute(bool state) override;
+
+ status_t getMicMute(bool* state) override;
+
+ status_t setMasterMute(bool state) override;
+
+ status_t getMasterMute(bool *state) override;
+
+ // Set global audio parameters.
+ status_t setParameters(const String8& kvPairs) override;
+
+ // Get global audio parameters.
+ status_t getParameters(const String8& keys, String8 *values) override;
+
+ // Returns audio input buffer size according to parameters passed.
+ status_t getInputBufferSize(const struct audio_config* config, size_t* size) override;
+
+ // Creates and opens the audio hardware output stream. The stream is closed
+ // by releasing all references to the returned object.
+ status_t openOutputStream(audio_io_handle_t handle, audio_devices_t devices,
+ audio_output_flags_t flags, struct audio_config* config,
+ const char* address, sp<StreamOutHalInterface>* outStream) override;
+
+ // Creates and opens the audio hardware input stream. The stream is closed
+ // by releasing all references to the returned object.
+ status_t openInputStream(audio_io_handle_t handle, audio_devices_t devices,
+ struct audio_config* config, audio_input_flags_t flags,
+ const char* address, audio_source_t source,
+ audio_devices_t outputDevice, const char* outputDeviceAddress,
+ sp<StreamInHalInterface>* inStream) override;
+
+ // Returns whether createAudioPatch and releaseAudioPatch operations are supported.
+ status_t supportsAudioPatches(bool* supportsPatches) override;
+
+ // Creates an audio patch between several source and sink ports.
+ status_t createAudioPatch(unsigned int num_sources, const struct audio_port_config* sources,
+ unsigned int num_sinks, const struct audio_port_config* sinks,
+ audio_patch_handle_t* patch) override;
+
+ // Releases an audio patch.
+ status_t releaseAudioPatch(audio_patch_handle_t patch) override;
+
+ // Fills the list of supported attributes for a given audio port.
+ status_t getAudioPort(struct audio_port* port) override;
+
+ // Fills the list of supported attributes for a given audio port.
+ status_t getAudioPort(struct audio_port_v7 *port) override;
+
+ // Set audio port configuration.
+ status_t setAudioPortConfig(const struct audio_port_config* config) override;
+
+ // List microphones
+ status_t getMicrophones(std::vector<audio_microphone_characteristic_t>* microphones);
+
+ status_t addDeviceEffect(audio_port_handle_t device, sp<EffectHalInterface> effect) override;
+
+ status_t removeDeviceEffect(audio_port_handle_t device, sp<EffectHalInterface> effect) override;
+
+ status_t getMmapPolicyInfos(media::audio::common::AudioMMapPolicyType policyType __unused,
+ std::vector<media::audio::common::AudioMMapPolicyInfo>* policyInfos
+ __unused) override;
+
+ int32_t getAAudioMixerBurstCount() override;
+
+ int32_t getAAudioHardwareBurstMinUsec() override;
+
+ error::Result<audio_hw_sync_t> getHwAvSync() override;
+
+ status_t dump(int __unused, const Vector<String16>& __unused) override;
+
+ int32_t supportsBluetoothVariableLatency(bool* supports __unused) override;
+
+ private:
+ friend class sp<DeviceHalAidl>;
+
+ const std::shared_ptr<::aidl::android::hardware::audio::core::IModule> mModule;
+
+ // Can not be constructed directly by clients.
+ explicit DeviceHalAidl(
+ const std::shared_ptr<::aidl::android::hardware::audio::core::IModule>& module)
+ : ConversionHelperAidl("DeviceHalAidl"), mModule(module) {}
+
+ ~DeviceHalAidl() override = default;
+};
+
+} // namespace android
diff --git a/media/libaudiohal/impl/DeviceHalHidl.cpp b/media/libaudiohal/impl/DeviceHalHidl.cpp
index 0cdf621..12acebd 100644
--- a/media/libaudiohal/impl/DeviceHalHidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalHidl.cpp
@@ -46,9 +46,6 @@
using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION;
-#define TIME_CHECK() auto timeCheck = \
- mediautils::makeTimeCheckStatsForClassMethod(getClassName(), __func__)
-
DeviceHalHidl::DeviceHalHidl(const sp<::android::hardware::audio::CPP_VERSION::IDevice>& device)
: CoreConversionHelperHidl("DeviceHalHidl"), mDevice(device) {
}
@@ -459,12 +456,13 @@
#if MAJOR_VERSION == 2
status_t DeviceHalHidl::getMicrophones(
- std::vector<media::MicrophoneInfo> *microphonesInfo __unused) {
+ std::vector<audio_microphone_characteristic_t> *microphonesInfo __unused) {
if (mDevice == 0) return NO_INIT;
return INVALID_OPERATION;
}
#elif MAJOR_VERSION >= 4
-status_t DeviceHalHidl::getMicrophones(std::vector<media::MicrophoneInfo> *microphonesInfo) {
+status_t DeviceHalHidl::getMicrophones(
+ std::vector<audio_microphone_characteristic_t> *microphonesInfo) {
TIME_CHECK();
if (mDevice == 0) return NO_INIT;
Result retval;
@@ -475,8 +473,7 @@
audio_microphone_characteristic_t dst;
//convert
(void)CoreUtils::microphoneInfoToHal(micArrayHal[k], &dst);
- media::MicrophoneInfo microphone = media::MicrophoneInfo(dst);
- microphonesInfo->push_back(microphone);
+ microphonesInfo->push_back(dst);
}
});
return processReturn("getMicrophones", ret, retval);
diff --git a/media/libaudiohal/impl/DeviceHalHidl.h b/media/libaudiohal/impl/DeviceHalHidl.h
index f6519b6..052eb65 100644
--- a/media/libaudiohal/impl/DeviceHalHidl.h
+++ b/media/libaudiohal/impl/DeviceHalHidl.h
@@ -30,87 +30,74 @@
{
public:
// Sets the value of 'devices' to a bitmask of 1 or more values of audio_devices_t.
- virtual status_t getSupportedDevices(uint32_t *devices);
+ status_t getSupportedDevices(uint32_t *devices) override;
// Check to see if the audio hardware interface has been initialized.
- virtual status_t initCheck();
+ status_t initCheck() override;
// Set the audio volume of a voice call. Range is between 0.0 and 1.0.
- virtual status_t setVoiceVolume(float volume);
+ status_t setVoiceVolume(float volume) override;
// Set the audio volume for all audio activities other than voice call.
- virtual status_t setMasterVolume(float volume);
+ status_t setMasterVolume(float volume) override;
// Get the current master volume value for the HAL.
- virtual status_t getMasterVolume(float *volume);
+ status_t getMasterVolume(float *volume) override;
// Called when the audio mode changes.
- virtual status_t setMode(audio_mode_t mode);
+ status_t setMode(audio_mode_t mode) override;
// Muting control.
- virtual status_t setMicMute(bool state);
- virtual status_t getMicMute(bool *state);
- virtual status_t setMasterMute(bool state);
- virtual status_t getMasterMute(bool *state);
+ status_t setMicMute(bool state) override;
+ status_t getMicMute(bool *state) override;
+ status_t setMasterMute(bool state) override;
+ status_t getMasterMute(bool *state) override;
// Set global audio parameters.
- virtual status_t setParameters(const String8& kvPairs);
+ status_t setParameters(const String8& kvPairs) override;
// Get global audio parameters.
- virtual status_t getParameters(const String8& keys, String8 *values);
+ status_t getParameters(const String8& keys, String8 *values) override;
// Returns audio input buffer size according to parameters passed.
- virtual status_t getInputBufferSize(const struct audio_config *config,
- size_t *size);
+ status_t getInputBufferSize(const struct audio_config* config, size_t* size) override;
// Creates and opens the audio hardware output stream. The stream is closed
// by releasing all references to the returned object.
- virtual status_t openOutputStream(
- audio_io_handle_t handle,
- audio_devices_t devices,
- audio_output_flags_t flags,
- struct audio_config *config,
- const char *address,
- sp<StreamOutHalInterface> *outStream);
+ status_t openOutputStream(audio_io_handle_t handle, audio_devices_t devices,
+ audio_output_flags_t flags, struct audio_config* config,
+ const char* address, sp<StreamOutHalInterface>* outStream) override;
// Creates and opens the audio hardware input stream. The stream is closed
// by releasing all references to the returned object.
- virtual status_t openInputStream(
- audio_io_handle_t handle,
- audio_devices_t devices,
- struct audio_config *config,
- audio_input_flags_t flags,
- const char *address,
- audio_source_t source,
- audio_devices_t outputDevice,
- const char *outputDeviceAddress,
- sp<StreamInHalInterface> *inStream);
+ status_t openInputStream(audio_io_handle_t handle, audio_devices_t devices,
+ struct audio_config* config, audio_input_flags_t flags,
+ const char* address, audio_source_t source,
+ audio_devices_t outputDevice, const char* outputDeviceAddress,
+ sp<StreamInHalInterface>* inStream) override;
// Returns whether createAudioPatch and releaseAudioPatch operations are supported.
- virtual status_t supportsAudioPatches(bool *supportsPatches);
+ status_t supportsAudioPatches(bool* supportsPatches) override;
// Creates an audio patch between several source and sink ports.
- virtual status_t createAudioPatch(
- unsigned int num_sources,
- const struct audio_port_config *sources,
- unsigned int num_sinks,
- const struct audio_port_config *sinks,
- audio_patch_handle_t *patch);
+ status_t createAudioPatch(unsigned int num_sources, const struct audio_port_config* sources,
+ unsigned int num_sinks, const struct audio_port_config* sinks,
+ audio_patch_handle_t* patch) override;
// Releases an audio patch.
- virtual status_t releaseAudioPatch(audio_patch_handle_t patch);
+ status_t releaseAudioPatch(audio_patch_handle_t patch) override;
// Fills the list of supported attributes for a given audio port.
- virtual status_t getAudioPort(struct audio_port *port);
+ status_t getAudioPort(struct audio_port *port) override;
// Fills the list of supported attributes for a given audio port.
- virtual status_t getAudioPort(struct audio_port_v7 *port);
+ status_t getAudioPort(struct audio_port_v7 *port) override;
// Set audio port configuration.
- virtual status_t setAudioPortConfig(const struct audio_port_config *config);
+ status_t setAudioPortConfig(const struct audio_port_config *config) override;
// List microphones
- virtual status_t getMicrophones(std::vector<media::MicrophoneInfo> *microphones);
+ status_t getMicrophones(std::vector<audio_microphone_characteristic_t>* microphones) override;
status_t addDeviceEffect(audio_port_handle_t device, sp<EffectHalInterface> effect) override;
status_t removeDeviceEffect(audio_port_handle_t device, sp<EffectHalInterface> effect) override;
@@ -132,6 +119,11 @@
return INVALID_OPERATION;
}
+ int32_t supportsBluetoothVariableLatency(bool* supports __unused) override {
+ // TODO: Implement the HAL query when moving to AIDL HAL.
+ return INVALID_OPERATION;
+ }
+
status_t setConnectedState(const struct audio_port_v7 *port, bool connected) override;
error::Result<audio_hw_sync_t> getHwAvSync() override;
diff --git a/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp b/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp
new file mode 100644
index 0000000..78d03e7
--- /dev/null
+++ b/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2022 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 "DevicesFactoryHalAidl"
+//#define LOG_NDEBUG 0
+
+#include <aidl/android/hardware/audio/core/IModule.h>
+#include <android/binder_manager.h>
+#include <binder/IServiceManager.h>
+#include <memory>
+#include <utils/Log.h>
+
+#include "DeviceHalAidl.h"
+#include "DevicesFactoryHalAidl.h"
+
+using namespace ::aidl::android::hardware::audio::core;
+using ::android::detail::AudioHalVersionInfo;
+
+namespace android {
+
+DevicesFactoryHalAidl::DevicesFactoryHalAidl(std::shared_ptr<IConfig> iconfig)
+ : mIConfig(std::move(iconfig)) {
+ ALOG_ASSERT(iconfig != nullptr, "Provided default IConfig service is NULL");
+}
+
+// Opens a device with the specified name. To close the device, it is
+// necessary to release references to the returned object.
+status_t DevicesFactoryHalAidl::openDevice(const char *name, sp<DeviceHalInterface> *device) {
+ if (name == nullptr || device == nullptr) {
+ return BAD_VALUE;
+ }
+
+ std::shared_ptr<IModule> service;
+ // FIXME: Normally we will list available HAL modules and connect to them,
+ // however currently we still get the list of module names from the config.
+ // Since the example service does not have all modules, the SM will wait
+ // for the missing ones forever.
+ if (strcmp(name, "primary") == 0 || strcmp(name, "r_submix") == 0) {
+ if (strcmp(name, "primary") == 0) name = "default";
+ auto serviceName = std::string(IModule::descriptor) + "/" + name;
+ service = IModule::fromBinder(
+ ndk::SpAIBinder(AServiceManager_waitForService(serviceName.c_str())));
+ ALOGE_IF(service == nullptr, "%s fromBinder %s failed", __func__, serviceName.c_str());
+ }
+ // If the service is a nullptr, the device will not be really functional,
+ // but will not crash either.
+ *device = sp<DeviceHalAidl>::make(service);
+ return OK;
+}
+
+status_t DevicesFactoryHalAidl::getHalPids(std::vector<pid_t> *pids) {
+ if (pids == nullptr) {
+ return BAD_VALUE;
+ }
+ // The functionality for retrieving debug infos of services is not exposed via the NDK.
+ sp<IServiceManager> sm = defaultServiceManager();
+ if (sm == nullptr) {
+ return NO_INIT;
+ }
+ std::set<pid_t> pidsSet;
+ const auto moduleServiceName = std::string(IModule::descriptor) + "/";
+ auto debugInfos = sm->getServiceDebugInfo();
+ for (const auto& info : debugInfos) {
+ if (info.pid > 0 &&
+ info.name.size() > moduleServiceName.size() && // '>' as there must be instance name
+ info.name.substr(0, moduleServiceName.size()) == moduleServiceName) {
+ pidsSet.insert(info.pid);
+ }
+ }
+ *pids = {pidsSet.begin(), pidsSet.end()};
+ return NO_ERROR;
+}
+
+status_t DevicesFactoryHalAidl::setCallbackOnce(sp<DevicesFactoryHalCallback> callback) {
+ // Dynamic registration of module instances is not supported. The functionality
+ // in the audio server which is related to this callback can be removed together
+ // with HIDL support.
+ ALOG_ASSERT(callback != nullptr);
+ if (callback != nullptr) {
+ callback->onNewDevicesAvailable();
+ }
+ return NO_ERROR;
+}
+
+AudioHalVersionInfo DevicesFactoryHalAidl::getHalVersion() const {
+ int32_t versionNumber = 0;
+ if (mIConfig != 0) {
+ if (ndk::ScopedAStatus status = mIConfig->getInterfaceVersion(&versionNumber);
+ !status.isOk()) {
+ ALOGE("%s getInterfaceVersion failed: %s", __func__, status.getDescription().c_str());
+ }
+ } else {
+ ALOGW("%s no IConfig instance", __func__);
+ }
+ // AIDL does not have minor version, fill 0 for all versions
+ return AudioHalVersionInfo(AudioHalVersionInfo::Type::AIDL, versionNumber);
+}
+
+// Main entry-point to the shared library.
+extern "C" __attribute__((visibility("default"))) void* createIDevicesFactoryImpl() {
+ auto serviceName = std::string(IConfig::descriptor) + "/default";
+ auto service = IConfig::fromBinder(
+ ndk::SpAIBinder(AServiceManager_waitForService(serviceName.c_str())));
+ if (!service) {
+ ALOGE("%s binder service %s not exist", __func__, serviceName.c_str());
+ return nullptr;
+ }
+ return new DevicesFactoryHalAidl(service);
+}
+
+} // namespace android
diff --git a/media/libaudiohal/impl/DevicesFactoryHalAidl.h b/media/libaudiohal/impl/DevicesFactoryHalAidl.h
new file mode 100644
index 0000000..cb627bc
--- /dev/null
+++ b/media/libaudiohal/impl/DevicesFactoryHalAidl.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 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 <aidl/android/hardware/audio/core/IConfig.h>
+#include <media/audiohal/DevicesFactoryHalInterface.h>
+#include <utils/RefBase.h>
+
+namespace android {
+
+class DevicesFactoryHalAidl : public DevicesFactoryHalInterface
+{
+ public:
+ explicit DevicesFactoryHalAidl(
+ std::shared_ptr<::aidl::android::hardware::audio::core::IConfig> iConfig);
+
+ // Opens a device with the specified name. To close the device, it is
+ // necessary to release references to the returned object.
+ status_t openDevice(const char *name, sp<DeviceHalInterface> *device) override;
+
+ status_t getHalPids(std::vector<pid_t> *pids) override;
+
+ status_t setCallbackOnce(sp<DevicesFactoryHalCallback> callback) override;
+
+ android::detail::AudioHalVersionInfo getHalVersion() const override;
+
+ private:
+ const std::shared_ptr<::aidl::android::hardware::audio::core::IConfig> mIConfig;
+ ~DevicesFactoryHalAidl() = default;
+};
+
+} // namespace android
diff --git a/media/libaudiohal/impl/EffectsFactoryHalHidlEntry.cpp b/media/libaudiohal/impl/DevicesFactoryHalEntry.cpp
similarity index 74%
copy from media/libaudiohal/impl/EffectsFactoryHalHidlEntry.cpp
copy to media/libaudiohal/impl/DevicesFactoryHalEntry.cpp
index 2c6f2c6..5bf6d89 100644
--- a/media/libaudiohal/impl/EffectsFactoryHalHidlEntry.cpp
+++ b/media/libaudiohal/impl/DevicesFactoryHalEntry.cpp
@@ -14,8 +14,10 @@
* limitations under the License.
*/
-extern "C" void* createIEffectsFactoryImpl();
+#include "android/media/AudioHalVersion.h"
-extern "C" __attribute__((visibility("default"))) void* createIEffectsFactory() {
- return createIEffectsFactoryImpl();
+extern "C" void* createIDevicesFactoryImpl();
+
+extern "C" __attribute__((visibility("default"))) void* createIDevicesFactory() {
+ return createIDevicesFactoryImpl();
}
diff --git a/media/libaudiohal/impl/DevicesFactoryHalHidl.cpp b/media/libaudiohal/impl/DevicesFactoryHalHidl.cpp
index 4069a6b..9f06f83 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalHidl.cpp
+++ b/media/libaudiohal/impl/DevicesFactoryHalHidl.cpp
@@ -29,6 +29,7 @@
#include "DeviceHalHidl.h"
#include "DevicesFactoryHalHidl.h"
+using ::android::detail::AudioHalVersionInfo;
using ::android::hardware::audio::CPP_VERSION::IDevice;
using ::android::hardware::audio::CORE_TYPES_CPP_VERSION::Result;
using ::android::hardware::Return;
@@ -226,8 +227,13 @@
return mDeviceFactories;
}
+
+AudioHalVersionInfo DevicesFactoryHalHidl::getHalVersion() const {
+ return AudioHalVersionInfo(AudioHalVersionInfo::Type::HIDL, MAJOR_VERSION, MINOR_VERSION);
+}
+
// Main entry-point to the shared library.
-extern "C" __attribute__((visibility("default"))) void* createIDevicesFactory() {
+extern "C" __attribute__((visibility("default"))) void* createIDevicesFactoryImpl() {
auto service = hardware::audio::CPP_VERSION::IDevicesFactory::getService();
return service ? new DevicesFactoryHalHidl(service) : nullptr;
}
diff --git a/media/libaudiohal/impl/DevicesFactoryHalHidl.h b/media/libaudiohal/impl/DevicesFactoryHalHidl.h
index ffd229d..5294728 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalHidl.h
+++ b/media/libaudiohal/impl/DevicesFactoryHalHidl.h
@@ -45,7 +45,7 @@
status_t setCallbackOnce(sp<DevicesFactoryHalCallback> callback) override;
- float getHalVersion() const override { return MAJOR_VERSION + (float)MINOR_VERSION / 10; }
+ android::detail::AudioHalVersionInfo getHalVersion() const override;
private:
friend class ServiceNotificationListener;
diff --git a/media/libaudiohal/impl/EffectBufferHalAidl.cpp b/media/libaudiohal/impl/EffectBufferHalAidl.cpp
new file mode 100644
index 0000000..5af8e24
--- /dev/null
+++ b/media/libaudiohal/impl/EffectBufferHalAidl.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2022 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 "EffectBufferHalAidl"
+//#define LOG_NDEBUG 0
+
+#include <utils/Log.h>
+
+#include "EffectBufferHalAidl.h"
+
+namespace android {
+namespace effect {
+
+// static
+status_t EffectBufferHalAidl::allocate(size_t size, sp<EffectBufferHalInterface>* buffer) {
+ ALOGE("%s not implemented yet %zu %p", __func__, size, buffer);
+ return mirror(nullptr, size, buffer);
+}
+
+status_t EffectBufferHalAidl::mirror(void* external, size_t size,
+ sp<EffectBufferHalInterface>* buffer) {
+ // buffer->setExternalData(external);
+ ALOGW("%s not implemented yet %p %zu %p", __func__, external, size, buffer);
+ return OK;
+}
+
+EffectBufferHalAidl::EffectBufferHalAidl(size_t size)
+ : mBufferSize(size),
+ mFrameCountChanged(false),
+ mExternalData(nullptr),
+ mAudioBuffer{0, {nullptr}} {
+}
+
+EffectBufferHalAidl::~EffectBufferHalAidl() {
+}
+
+status_t EffectBufferHalAidl::init() {
+ ALOGW("%s not implemented yet", __func__);
+ return OK;
+}
+
+audio_buffer_t* EffectBufferHalAidl::audioBuffer() {
+ return &mAudioBuffer;
+}
+
+void* EffectBufferHalAidl::externalData() const {
+ return mExternalData;
+}
+
+void EffectBufferHalAidl::setFrameCount(size_t frameCount) {
+ mAudioBuffer.frameCount = frameCount;
+ mFrameCountChanged = true;
+}
+
+bool EffectBufferHalAidl::checkFrameCountChange() {
+ bool result = mFrameCountChanged;
+ mFrameCountChanged = false;
+ return result;
+}
+
+void EffectBufferHalAidl::setExternalData(void* external) {
+ mExternalData = external;
+}
+
+void EffectBufferHalAidl::update() {
+ ALOGW("%s not implemented yet", __func__);
+}
+
+void EffectBufferHalAidl::commit() {
+ ALOGW("%s not implemented yet", __func__);
+}
+
+} // namespace effect
+} // namespace android
diff --git a/media/libaudiohal/impl/EffectBufferHalAidl.h b/media/libaudiohal/impl/EffectBufferHalAidl.h
new file mode 100644
index 0000000..f488708
--- /dev/null
+++ b/media/libaudiohal/impl/EffectBufferHalAidl.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 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 <media/audiohal/EffectBufferHalInterface.h>
+#include <system/audio_effect.h>
+
+namespace android {
+namespace effect {
+
+class EffectBufferHalAidl : public EffectBufferHalInterface {
+ public:
+ static status_t allocate(size_t size, sp<EffectBufferHalInterface>* buffer);
+ static status_t mirror(void* external, size_t size, sp<EffectBufferHalInterface>* buffer);
+
+ audio_buffer_t* audioBuffer() override;
+ void* externalData() const override;
+
+ size_t getSize() const override { return mBufferSize; }
+
+ void setExternalData(void* external) override;
+ void setFrameCount(size_t frameCount) override;
+ bool checkFrameCountChange() override;
+
+ void update() override;
+ void commit() override;
+ void update(size_t size) override;
+ void commit(size_t size) override;
+
+ private:
+ friend class EffectBufferHalInterface;
+
+ const size_t mBufferSize;
+ bool mFrameCountChanged;
+ void* mExternalData;
+ audio_buffer_t mAudioBuffer;
+
+ // Can not be constructed directly by clients.
+ explicit EffectBufferHalAidl(size_t size);
+
+ ~EffectBufferHalAidl();
+
+ status_t init();
+};
+
+} // namespace effect
+} // namespace android
diff --git a/media/libaudiohal/impl/EffectConversionHelperAidl.cpp b/media/libaudiohal/impl/EffectConversionHelperAidl.cpp
new file mode 100644
index 0000000..493d1ee
--- /dev/null
+++ b/media/libaudiohal/impl/EffectConversionHelperAidl.cpp
@@ -0,0 +1,345 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cstdint>
+#include <cstring>
+#define LOG_TAG "EffectConversionHelperAidl"
+//#define LOG_NDEBUG 0
+
+#include <error/expected_utils.h>
+#include <media/audiohal/AudioEffectUuid.h>
+#include <system/audio_effects/audio_effects_utils.h>
+#include <utils/Log.h>
+
+#include "EffectConversionHelperAidl.h"
+
+namespace android {
+namespace effect {
+
+using ::aidl::android::aidl_utils::statusTFromBinderStatus;
+using ::aidl::android::hardware::audio::effect::AcousticEchoCanceler;
+using ::aidl::android::hardware::audio::effect::CommandId;
+using ::aidl::android::hardware::audio::effect::Parameter;
+using ::aidl::android::media::audio::common::AudioDeviceDescription;
+using ::aidl::android::media::audio::common::AudioUuid;
+
+using ::android::status_t;
+
+const std::map<uint32_t /* effect_command_e */, EffectConversionHelperAidl::CommandHandler>
+ EffectConversionHelperAidl::mCommandHandlerMap = {
+ {EFFECT_CMD_INIT, &EffectConversionHelperAidl::handleInit},
+ {EFFECT_CMD_SET_PARAM, &EffectConversionHelperAidl::handleSetParameter},
+ {EFFECT_CMD_GET_PARAM, &EffectConversionHelperAidl::handleGetParameter},
+ {EFFECT_CMD_SET_CONFIG, &EffectConversionHelperAidl::handleSetConfig},
+ {EFFECT_CMD_GET_CONFIG, &EffectConversionHelperAidl::handleGetConfig},
+ {EFFECT_CMD_RESET, &EffectConversionHelperAidl::handleReset},
+ {EFFECT_CMD_ENABLE, &EffectConversionHelperAidl::handleEnable},
+ {EFFECT_CMD_DISABLE, &EffectConversionHelperAidl::handleDisable},
+ {EFFECT_CMD_SET_DEVICE, &EffectConversionHelperAidl::handleSetDevice},
+ {EFFECT_CMD_SET_INPUT_DEVICE, &EffectConversionHelperAidl::handleSetDevice},
+ {EFFECT_CMD_SET_VOLUME, &EffectConversionHelperAidl::handleSetVolume},
+ {EFFECT_CMD_OFFLOAD, &EffectConversionHelperAidl::handleSetOffload},
+ {EFFECT_CMD_FIRST_PROPRIETARY, &EffectConversionHelperAidl::handleFirstPriority}};
+
+const std::map<AudioUuid /* TypeUUID */, std::pair<EffectConversionHelperAidl::SetParameter,
+ EffectConversionHelperAidl::GetParameter>>
+ EffectConversionHelperAidl::mParameterHandlerMap = {
+ {kAcousticEchoCancelerTypeUUID,
+ {&EffectConversionHelperAidl::setAecParameter,
+ &EffectConversionHelperAidl::getAecParameter}}};
+
+
+status_t EffectConversionHelperAidl::handleCommand(uint32_t cmdCode, uint32_t cmdSize,
+ void* pCmdData, uint32_t* replySize,
+ void* pReplyData) {
+ const auto& handler = mCommandHandlerMap.find(cmdCode);
+ if (handler == mCommandHandlerMap.end() || !handler->second) {
+ ALOGE("%s handler for command %u doesn't exist", __func__, cmdCode);
+ return BAD_VALUE;
+ }
+ return (this->*handler->second)(cmdSize, pCmdData, replySize, pReplyData);
+}
+
+status_t EffectConversionHelperAidl::handleInit(uint32_t cmdSize __unused,
+ const void* pCmdData __unused, uint32_t* replySize,
+ void* pReplyData) {
+ if (!replySize || *replySize < sizeof(int) || !pReplyData) {
+ return BAD_VALUE;
+ }
+
+ return *(status_t*)pReplyData = OK;
+}
+
+status_t EffectConversionHelperAidl::handleSetParameter(uint32_t cmdSize, const void* pCmdData,
+ uint32_t* replySize, void* pReplyData) {
+ if (cmdSize < kEffectParamSize || !pCmdData || !replySize || *replySize < sizeof(int) ||
+ !pReplyData) {
+ return BAD_VALUE;
+ }
+
+ const effect_param_t* param = (effect_param_t*)pCmdData;
+ if (!validateCommandSize(*param, cmdSize)) {
+ ALOGE("%s illegal param %s size %u", __func__, utils::toString(*param).c_str(), cmdSize);
+ return BAD_VALUE;
+ }
+
+ const auto& handler = mParameterHandlerMap.find(mTypeUuid);
+ if (handler == mParameterHandlerMap.end() || !handler->second.first) {
+ ALOGE("%s handler for uuid %s not found", __func__, mTypeUuid.toString().c_str());
+ return BAD_VALUE;
+ }
+ const SetParameter& functor = handler->second.first;
+ return *(status_t*)pReplyData = (this->*functor)(*(const effect_param_t*)param);
+}
+
+status_t EffectConversionHelperAidl::handleGetParameter(uint32_t cmdSize, const void* pCmdData,
+ uint32_t* replySize, void* pReplyData) {
+ if (cmdSize < kEffectParamSize || !pCmdData || !replySize || !pReplyData) {
+ return BAD_VALUE;
+ }
+
+ const effect_param_t* param = (effect_param_t*)pCmdData;
+ if (!validateCommandSize(*param, *replySize)) {
+ ALOGE("%s illegal param %s, replysize %u", __func__, utils::toString(*param).c_str(),
+ *replySize);
+ return BAD_VALUE;
+ }
+
+ const auto& handler = mParameterHandlerMap.find(mTypeUuid);
+ if (handler == mParameterHandlerMap.end() || !handler->second.second) {
+ ALOGE("%s handler for uuid %s not found", __func__, mTypeUuid.toString().c_str());
+ return BAD_VALUE;
+ }
+ const GetParameter& functor = handler->second.second;
+ memcpy(pReplyData, pCmdData, sizeof(effect_param_t) + param->psize);
+ effect_param_t* reply = (effect_param_t *)pReplyData;
+ (this->*functor)(*reply);
+ *replySize = kEffectParamSize + padding(reply->psize) + reply->vsize;
+ return reply->status;
+}
+
+status_t EffectConversionHelperAidl::handleSetConfig(uint32_t cmdSize, const void* pCmdData,
+ uint32_t* replySize, void* pReplyData) {
+ if (!replySize || *replySize != sizeof(int) || !pReplyData || cmdSize != kEffectConfigSize) {
+ return BAD_VALUE;
+ }
+
+ const auto& legacyConfig = static_cast<const effect_config_t*>(pCmdData);
+ // already open, apply latest settings
+ Parameter::Common common;
+ common.input.base =
+ VALUE_OR_RETURN_STATUS(::aidl::android::legacy2aidl_buffer_config_t_AudioConfigBase(
+ legacyConfig->inputCfg, true /* isInput */));
+ common.output.base =
+ VALUE_OR_RETURN_STATUS(::aidl::android::legacy2aidl_buffer_config_t_AudioConfigBase(
+ legacyConfig->outputCfg, false /* isInput */));
+ common.session = mSessionId;
+ common.ioHandle = mIoId;
+ // TODO: add access mode support
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
+ mEffect->setParameter(Parameter::make<Parameter::common>(common))));
+ return *static_cast<int32_t*>(pReplyData) = OK;
+}
+
+status_t EffectConversionHelperAidl::handleGetConfig(uint32_t cmdSize __unused,
+ const void* pCmdData __unused,
+ uint32_t* replySize, void* pReplyData) {
+ if (!replySize || *replySize != kEffectConfigSize || !pReplyData) {
+ ALOGE("%s parameter invalid %p %p", __func__, replySize, pReplyData);
+ return BAD_VALUE;
+ }
+
+ Parameter param;
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(
+ Parameter::Id::make<Parameter::Id::commonTag>(Parameter::common), ¶m)));
+
+ const auto& common = param.get<Parameter::common>();
+ effect_config_t* pConfig = (effect_config_t*)pReplyData;
+ pConfig->inputCfg = VALUE_OR_RETURN_STATUS(
+ ::aidl::android::aidl2legacy_AudioConfigBase_buffer_config_t(common.input.base, true));
+ pConfig->outputCfg =
+ VALUE_OR_RETURN_STATUS(::aidl::android::aidl2legacy_AudioConfigBase_buffer_config_t(
+ common.output.base, false));
+ return OK;
+}
+
+status_t EffectConversionHelperAidl::handleReset(uint32_t cmdSize __unused,
+ const void* pCmdData __unused, uint32_t* replySize,
+ void* pReplyData) {
+ if (!replySize || *replySize != kEffectConfigSize || !pReplyData) {
+ ALOGE("%s parameter invalid %p %p", __func__, replySize, pReplyData);
+ return BAD_VALUE;
+ }
+
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->command(CommandId::RESET)));
+ return OK;
+}
+
+status_t EffectConversionHelperAidl::handleEnable(uint32_t cmdSize __unused,
+ const void* pCmdData __unused, uint32_t* replySize,
+ void* pReplyData) {
+ if (!replySize || *replySize != kEffectConfigSize || !pReplyData) {
+ ALOGE("%s parameter invalid %p %p", __func__, replySize, pReplyData);
+ return BAD_VALUE;
+ }
+
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->command(CommandId::START)));
+ return OK;
+}
+
+status_t EffectConversionHelperAidl::handleDisable(uint32_t cmdSize __unused,
+ const void* pCmdData __unused,
+ uint32_t* replySize, void* pReplyData) {
+ if (!replySize || *replySize != kEffectConfigSize || !pReplyData) {
+ ALOGE("%s parameter invalid %p %p", __func__, replySize, pReplyData);
+ return BAD_VALUE;
+ }
+
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->command(CommandId::STOP)));
+ return OK;
+}
+
+status_t EffectConversionHelperAidl::handleSetDevice(uint32_t cmdSize, const void* pCmdData,
+ uint32_t* replySize, void* pReplyData) {
+ if (cmdSize != sizeof(uint32_t) || !pCmdData || !replySize || *replySize != kEffectConfigSize ||
+ !pReplyData) {
+ ALOGE("%s parameter invalid %u %p %p %p", __func__, cmdSize, pCmdData, replySize,
+ pReplyData);
+ return BAD_VALUE;
+ }
+ // TODO: convert from audio_devices_t to std::vector<AudioDeviceDescription>
+ // const auto& legacyDevice = *(uint32_t*)(pCmdData);
+ std::vector<AudioDeviceDescription> aidlDevices;
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
+ mEffect->setParameter(Parameter::make<Parameter::deviceDescription>(aidlDevices))));
+ return *static_cast<int32_t*>(pReplyData) = OK;
+}
+
+status_t EffectConversionHelperAidl::handleSetVolume(uint32_t cmdSize, const void* pCmdData,
+ uint32_t* replySize, void* pReplyData) {
+ if (cmdSize != 2 * sizeof(uint32_t) || !pCmdData || !replySize ||
+ *replySize != kEffectConfigSize || !pReplyData) {
+ ALOGE("%s parameter invalid %u %p %p %p", __func__, cmdSize, pCmdData, replySize,
+ pReplyData);
+ return BAD_VALUE;
+ }
+ Parameter::VolumeStereo volume = {.left = (float)(*(uint32_t*)pCmdData) / (1 << 24),
+ .right = (float)(*(uint32_t*)pCmdData + 1) / (1 << 24)};
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
+ mEffect->setParameter(Parameter::make<Parameter::volumeStereo>(volume))));
+ return *static_cast<int32_t*>(pReplyData) = OK;
+}
+
+status_t EffectConversionHelperAidl::handleSetOffload(uint32_t cmdSize, const void* pCmdData,
+ uint32_t* replySize, void* pReplyData) {
+ if (cmdSize < sizeof(effect_offload_param_t) || !pCmdData || !replySize ||
+ *replySize != kEffectConfigSize || !pReplyData) {
+ ALOGE("%s parameter invalid %u %p %p %p", __func__, cmdSize, pCmdData, replySize,
+ pReplyData);
+ return BAD_VALUE;
+ }
+ // TODO: handle this after effectproxy implemented in libaudiohal
+ return *static_cast<int32_t*>(pReplyData) = OK;
+}
+
+status_t EffectConversionHelperAidl::handleFirstPriority(uint32_t cmdSize __unused,
+ const void* pCmdData __unused,
+ uint32_t* replySize, void* pReplyData) {
+ if (!replySize || *replySize != kEffectConfigSize || !pReplyData) {
+ ALOGE("%s parameter invalid %p %p", __func__, replySize, pReplyData);
+ return BAD_VALUE;
+ }
+
+ // TODO
+ return OK;
+}
+
+status_t EffectConversionHelperAidl::setAecParameter(const effect_param_t& param) {
+ const auto psize = sizeof(uint32_t);
+ const auto vsize = sizeof(uint32_t);
+ if (!validatePVsize(param, psize, vsize)) {
+ return BAD_VALUE;
+ }
+
+ const auto& type = *(uint32_t*)param.data;
+ const auto& value = *(uint32_t*)(param.data + psize);
+ Parameter aidlParam;
+ switch (type) {
+ case AEC_PARAM_ECHO_DELAY:
+ FALLTHROUGH_INTENDED;
+ case AEC_PARAM_PROPERTIES: {
+ aidlParam = VALUE_OR_RETURN_STATUS(
+ aidl::android::legacy2aidl_uint32_echoDelay_Parameter(value));
+ break;
+ }
+ case AEC_PARAM_MOBILE_MODE: {
+ aidlParam = VALUE_OR_RETURN_STATUS(
+ aidl::android::legacy2aidl_uint32_mobileMode_Parameter(value));
+ break;
+ }
+ default: {
+ ALOGW("%s unknown param %08x value %08x", __func__, type, value);
+ return BAD_VALUE;
+ }
+ }
+
+ return mEffect->setParameter(aidlParam).getStatus();
+}
+
+status_t EffectConversionHelperAidl::getAecParameter(effect_param_t& param) {
+ const auto psize = sizeof(uint32_t);
+ const auto vsize = sizeof(uint32_t);
+ if (!validatePVsize(param, psize, vsize)) {
+ return param.status = BAD_VALUE;
+ }
+
+ uint32_t value = 0;
+ status_t status = BAD_VALUE;
+ const auto& type = *(uint32_t*)param.data;
+ switch (type) {
+ case AEC_PARAM_ECHO_DELAY:
+ FALLTHROUGH_INTENDED;
+ case AEC_PARAM_PROPERTIES: {
+ Parameter aidlParam;
+ Parameter::Id id = Parameter::Id::make<Parameter::Id::acousticEchoCancelerTag>(
+ AcousticEchoCanceler::Id::make<AcousticEchoCanceler::Id::commonTag>(
+ AcousticEchoCanceler::echoDelayUs));
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+ value = VALUE_OR_RETURN_STATUS(
+ aidl::android::aidl2legacy_Parameter_uint32_echoDelay(aidlParam));
+ break;
+ }
+ case AEC_PARAM_MOBILE_MODE: {
+ Parameter aidlParam;
+ Parameter::Id id = Parameter::Id::make<Parameter::Id::acousticEchoCancelerTag>(
+ AcousticEchoCanceler::Id::make<AcousticEchoCanceler::Id::commonTag>(
+ AcousticEchoCanceler::mobileMode));
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+ value = VALUE_OR_RETURN_STATUS(
+ aidl::android::aidl2legacy_Parameter_uint32_mobileMode(aidlParam));
+ break;
+ }
+ default:
+ ALOGW("%s unknown param %08x", __func__, type);
+ break;
+ }
+
+ *(uint32_t*)(param.data + psize) = value;
+ return param.status = status;
+}
+
+} // namespace effect
+} // namespace android
diff --git a/media/libaudiohal/impl/EffectConversionHelperAidl.h b/media/libaudiohal/impl/EffectConversionHelperAidl.h
new file mode 100644
index 0000000..5d7c1d6
--- /dev/null
+++ b/media/libaudiohal/impl/EffectConversionHelperAidl.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2023 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 <cstddef>
+#include <map>
+#include <memory>
+#include <utils/Errors.h>
+
+#include <aidl/android/hardware/audio/effect/IEffect.h>
+
+#include <media/AidlConversionNdk.h>
+#include <system/audio_effect.h>
+#include <system/audio_effects/effect_aec.h>
+#include <system/audio_effects/effect_downmix.h>
+#include <system/audio_effects/effect_dynamicsprocessing.h>
+#include <system/audio_effects/effect_hapticgenerator.h>
+#include <system/audio_effects/effect_ns.h>
+#include <system/audio_effects/effect_visualizer.h>
+
+namespace android {
+namespace effect {
+
+static const size_t kEffectParamSize = sizeof(effect_param_t);
+static const size_t kEffectConfigSize = sizeof(effect_config_t);
+
+class EffectConversionHelperAidl {
+ protected:
+ EffectConversionHelperAidl(
+ std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> effect,
+ int32_t sessionId, int32_t ioId, ::aidl::android::media::audio::common::AudioUuid uuid)
+ : mSessionId(sessionId),
+ mIoId(ioId),
+ mTypeUuid(std::move(uuid)),
+ mEffect(std::move(effect)) {}
+
+ status_t handleCommand(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData, uint32_t* replySize,
+ void* pReplyData);
+
+ private:
+ const int32_t mSessionId;
+ const int32_t mIoId;
+ ::aidl::android::media::audio::common::AudioUuid mTypeUuid;
+ const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> mEffect;
+
+ // command handler map
+ typedef status_t (EffectConversionHelperAidl::*CommandHandler)(uint32_t /* cmdSize */,
+ const void* /* pCmdData */,
+ uint32_t* /* replySize */,
+ void* /* pReplyData */);
+ static const std::map<uint32_t /* effect_command_e */, CommandHandler> mCommandHandlerMap;
+
+ // parameter set/get handler map
+ typedef status_t (EffectConversionHelperAidl::*SetParameter)(const effect_param_t& param);
+ typedef status_t (EffectConversionHelperAidl::*GetParameter)(effect_param_t& param);
+ static const std::map<::aidl::android::media::audio::common::AudioUuid /* TypeUUID */,
+ std::pair<SetParameter, GetParameter>>
+ mParameterHandlerMap;
+
+ // align to 32 bit boundary
+ static constexpr size_t padding(size_t size) {
+ return ((size - 1) / sizeof(int) + 1) * sizeof(int);
+ }
+ static constexpr bool validatePVsize(const effect_param_t& param, size_t p, size_t v) {
+ return padding(param.psize) == p && param.vsize == v;
+ }
+ static constexpr bool validateCommandSize(const effect_param_t& param, size_t size) {
+ return padding(param.psize) + param.vsize + kEffectParamSize <= size;
+ }
+
+ status_t handleInit(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
+ void* pReplyData);
+ status_t handleSetParameter(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
+ void* pReplyData);
+ status_t handleGetParameter(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
+ void* pReplyData);
+ status_t handleSetConfig(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
+ void* pReplyData);
+ status_t handleGetConfig(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
+ void* pReplyData);
+ status_t handleEnable(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
+ void* pReplyData);
+ status_t handleDisable(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
+ void* pReplyData);
+ status_t handleReset(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
+ void* pReplyData);
+ status_t handleSetDevice(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
+ void* pReplyData);
+ status_t handleSetVolume(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
+ void* pReplyData);
+ status_t handleSetOffload(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
+ void* pReplyData);
+ status_t handleFirstPriority(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
+ void* pReplyData);
+
+ // AEC parameter handler
+ status_t setAecParameter(const effect_param_t& param);
+ status_t getAecParameter(effect_param_t& param);
+};
+
+} // namespace effect
+} // namespace android
diff --git a/media/libaudiohal/impl/EffectHalAidl.cpp b/media/libaudiohal/impl/EffectHalAidl.cpp
new file mode 100644
index 0000000..3346459
--- /dev/null
+++ b/media/libaudiohal/impl/EffectHalAidl.cpp
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2022 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 "EffectHalAidl"
+//#define LOG_NDEBUG 0
+
+#include <error/expected_utils.h>
+#include <media/AidlConversionCppNdk.h>
+#include <media/AidlConversionNdk.h>
+#include <media/AidlConversionUtil.h>
+#include <media/EffectsFactoryApi.h>
+#include <mediautils/TimeCheck.h>
+#include <utils/Log.h>
+
+#include <system/audio_effects/effect_aec.h>
+#include <system/audio_effects/effect_downmix.h>
+#include <system/audio_effects/effect_dynamicsprocessing.h>
+#include <system/audio_effects/effect_hapticgenerator.h>
+#include <system/audio_effects/effect_ns.h>
+#include <system/audio_effects/effect_spatializer.h>
+#include <system/audio_effects/effect_visualizer.h>
+
+#include "EffectHalAidl.h"
+
+#include <system/audio.h>
+#include <aidl/android/hardware/audio/effect/IEffect.h>
+
+using ::aidl::android::aidl_utils::statusTFromBinderStatus;
+using ::aidl::android::hardware::audio::effect::CommandId;
+using ::aidl::android::hardware::audio::effect::Descriptor;
+using ::aidl::android::hardware::audio::effect::IEffect;
+using ::aidl::android::hardware::audio::effect::Parameter;
+
+namespace android {
+namespace effect {
+
+EffectHalAidl::EffectHalAidl(const std::shared_ptr<IEffect>& effect, uint64_t effectId,
+ int32_t sessionId, int32_t ioId, const Descriptor& desc)
+ : EffectConversionHelperAidl(effect, sessionId, ioId, desc.common.id.type),
+ mEffectId(effectId),
+ mSessionId(sessionId),
+ mIoId(ioId),
+ mEffect(effect),
+ mDesc(desc) {}
+
+EffectHalAidl::~EffectHalAidl() {}
+
+status_t EffectHalAidl::setInBuffer(const sp<EffectBufferHalInterface>& buffer) {
+ if (buffer == nullptr) {
+ return BAD_VALUE;
+ }
+ ALOGW("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t EffectHalAidl::setOutBuffer(const sp<EffectBufferHalInterface>& buffer) {
+ if (buffer == nullptr) {
+ return BAD_VALUE;
+ }
+ ALOGW("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t EffectHalAidl::process() {
+ ALOGW("%s not implemented yet", __func__);
+ // write to input FMQ here, and wait for statusMQ STATUS_OK
+ return OK;
+}
+
+// TODO: no one using, maybe deprecate this interface
+status_t EffectHalAidl::processReverse() {
+ ALOGW("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t EffectHalAidl::command(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData,
+ uint32_t* replySize, void* pReplyData) {
+ return handleCommand(cmdCode, cmdSize, pCmdData, replySize, pReplyData);
+}
+
+status_t EffectHalAidl::getDescriptor(effect_descriptor_t* pDescriptor) {
+ ALOGW("%s %p", __func__, pDescriptor);
+ if (pDescriptor == nullptr) {
+ return BAD_VALUE;
+ }
+ Descriptor aidlDesc;
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getDescriptor(&aidlDesc)));
+
+ *pDescriptor = VALUE_OR_RETURN_STATUS(
+ ::aidl::android::aidl2legacy_Descriptor_effect_descriptor(aidlDesc));
+ return OK;
+}
+
+status_t EffectHalAidl::close() {
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->close()));
+ return OK;
+}
+
+status_t EffectHalAidl::dump(int fd) {
+ ALOGW("%s not implemented yet, fd %d", __func__, fd);
+ return OK;
+}
+
+} // namespace effect
+} // namespace android
diff --git a/media/libaudiohal/impl/EffectHalAidl.h b/media/libaudiohal/impl/EffectHalAidl.h
new file mode 100644
index 0000000..1ba262c
--- /dev/null
+++ b/media/libaudiohal/impl/EffectHalAidl.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2022 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 <aidl/android/hardware/audio/effect/IEffect.h>
+#include <media/audiohal/EffectHalInterface.h>
+#include <system/audio_effect.h>
+
+#include "EffectConversionHelperAidl.h"
+
+namespace android {
+namespace effect {
+
+class EffectHalAidl : public EffectHalInterface, public EffectConversionHelperAidl {
+ public:
+ // Set the input buffer.
+ status_t setInBuffer(const sp<EffectBufferHalInterface>& buffer) override;
+
+ // Set the output buffer.
+ status_t setOutBuffer(const sp<EffectBufferHalInterface>& buffer) override;
+
+ // Effect process function.
+ status_t process() override;
+
+ // Process reverse stream function. This function is used to pass
+ // a reference stream to the effect engine.
+ status_t processReverse() override;
+
+ // Send a command and receive a response to/from effect engine.
+ status_t command(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData, uint32_t* replySize,
+ void* pReplyData) override;
+
+ // Returns the effect descriptor.
+ status_t getDescriptor(effect_descriptor_t *pDescriptor) override;
+
+ // Free resources on the remote side.
+ status_t close() override;
+
+ // Whether it's a local implementation.
+ bool isLocal() const override { return false; }
+
+ status_t dump(int fd) override;
+
+ uint64_t effectId() const override { return mEffectId; }
+
+ const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> getIEffect() const {
+ return mEffect;
+ }
+
+ private:
+ friend class sp<EffectHalAidl>;
+
+ const uint64_t mEffectId;
+ const int32_t mSessionId;
+ const int32_t mIoId;
+ const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> mEffect;
+ const ::aidl::android::hardware::audio::effect::Descriptor mDesc;
+
+ sp<EffectBufferHalInterface> mInBuffer, mOutBuffer;
+ effect_config_t mConfig;
+
+ // Can not be constructed directly by clients.
+ EffectHalAidl(const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& effect,
+ uint64_t effectId, int32_t sessionId, int32_t ioId,
+ const ::aidl::android::hardware::audio::effect::Descriptor& desc);
+ bool setEffectReverse(bool reverse);
+
+ // The destructor automatically releases the effect.
+ virtual ~EffectHalAidl();
+};
+
+} // namespace effect
+} // namespace android
diff --git a/media/libaudiohal/impl/EffectHalHidl.cpp b/media/libaudiohal/impl/EffectHalHidl.cpp
index 3956a6c..ed952a3 100644
--- a/media/libaudiohal/impl/EffectHalHidl.cpp
+++ b/media/libaudiohal/impl/EffectHalHidl.cpp
@@ -46,9 +46,6 @@
using namespace ::android::hardware::audio::common::CPP_VERSION;
using namespace ::android::hardware::audio::effect::CPP_VERSION;
-#define TIME_CHECK() auto timeCheck = \
- mediautils::makeTimeCheckStatsForClassMethod(getClassName(), __func__)
-
EffectHalHidl::EffectHalHidl(const sp<IEffect>& effect, uint64_t effectId)
: EffectConversionHelperHidl("EffectHalHidl"),
mEffect(effect), mEffectId(effectId), mBuffersChanged(true), mEfGroup(nullptr) {
diff --git a/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp b/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
new file mode 100644
index 0000000..96ea861
--- /dev/null
+++ b/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+#include <cstdint>
+#include <memory>
+#define LOG_TAG "EffectsFactoryHalAidl"
+//#define LOG_NDEBUG 0
+
+#include <aidl/android/hardware/audio/effect/IFactory.h>
+#include <error/expected_utils.h>
+#include <android/binder_manager.h>
+#include <media/AidlConversionCppNdk.h>
+#include <media/AidlConversionNdk.h>
+#include <system/audio.h>
+#include <utils/Log.h>
+
+#include "EffectBufferHalAidl.h"
+#include "EffectHalAidl.h"
+#include "EffectsFactoryHalAidl.h"
+
+using ::aidl::android::legacy2aidl_audio_uuid_t_AudioUuid;
+using aidl::android::aidl_utils::statusTFromBinderStatus;
+using aidl::android::hardware::audio::effect::IFactory;
+using aidl::android::media::audio::common::AudioUuid;
+using android::detail::AudioHalVersionInfo;
+
+namespace android {
+namespace effect {
+
+EffectsFactoryHalAidl::EffectsFactoryHalAidl(std::shared_ptr<IFactory> effectsFactory)
+ : mFactory(effectsFactory),
+ mHalVersion(AudioHalVersionInfo(AudioHalVersionInfo::Type::AIDL, [this]() {
+ int32_t majorVersion = 0;
+ return (mFactory && mFactory->getInterfaceVersion(&majorVersion).isOk()) ? majorVersion
+ : 0;
+ }())) {
+ ALOG_ASSERT(effectsFactory != nullptr, "Provided IEffectsFactory service is NULL");
+}
+
+status_t EffectsFactoryHalAidl::queryNumberEffects(uint32_t *pNumEffects) {
+ if (pNumEffects == nullptr) {
+ return BAD_VALUE;
+ }
+
+ {
+ std::lock_guard lg(mLock);
+ RETURN_STATUS_IF_ERROR(queryEffectList_l());
+ *pNumEffects = mDescList->size();
+ }
+ ALOGI("%s %d", __func__, *pNumEffects);
+ return OK;
+}
+
+status_t EffectsFactoryHalAidl::getDescriptor(uint32_t index, effect_descriptor_t* pDescriptor) {
+ if (pDescriptor == nullptr) {
+ return BAD_VALUE;
+ }
+
+ std::lock_guard lg(mLock);
+ RETURN_STATUS_IF_ERROR(queryEffectList_l());
+
+ auto listSize = mDescList->size();
+ if (index >= listSize) {
+ ALOGE("%s index %d exceed size DescList %zd", __func__, index, listSize);
+ return INVALID_OPERATION;
+ }
+
+ *pDescriptor = VALUE_OR_RETURN_STATUS(
+ ::aidl::android::aidl2legacy_Descriptor_effect_descriptor(mDescList->at(index)));
+ return OK;
+}
+
+status_t EffectsFactoryHalAidl::getDescriptor(const effect_uuid_t* halUuid,
+ effect_descriptor_t* pDescriptor) {
+ if (halUuid == nullptr || pDescriptor == nullptr) {
+ return BAD_VALUE;
+ }
+
+ AudioUuid uuid = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_uuid_t_AudioUuid(*halUuid));
+ std::lock_guard lg(mLock);
+ return getHalDescriptorWithImplUuid_l(uuid, pDescriptor);
+}
+
+status_t EffectsFactoryHalAidl::getDescriptors(const effect_uuid_t* halType,
+ std::vector<effect_descriptor_t>* descriptors) {
+ if (halType == nullptr || descriptors == nullptr) {
+ return BAD_VALUE;
+ }
+
+ AudioUuid type = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_uuid_t_AudioUuid(*halType));
+ std::lock_guard lg(mLock);
+ return getHalDescriptorWithTypeUuid_l(type, descriptors);
+}
+
+status_t EffectsFactoryHalAidl::createEffect(const effect_uuid_t* uuid, int32_t sessionId,
+ int32_t ioId, int32_t deviceId __unused,
+ sp<EffectHalInterface>* effect) {
+ if (uuid == nullptr || effect == nullptr) {
+ return BAD_VALUE;
+ }
+ if (sessionId == AUDIO_SESSION_DEVICE && ioId == AUDIO_IO_HANDLE_NONE) {
+ return INVALID_OPERATION;
+ }
+
+ ALOGI("%s session %d ioId %d", __func__, sessionId, ioId);
+
+ AudioUuid aidlUuid = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_uuid_t_AudioUuid(*uuid));
+ std::shared_ptr<IEffect> aidlEffect;
+ Descriptor desc;
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mFactory->createEffect(aidlUuid, &aidlEffect)));
+ if (aidlEffect == nullptr) {
+ ALOGE("%s IFactory::createFactory failed UUID %s", __func__, aidlUuid.toString().c_str());
+ return NAME_NOT_FOUND;
+ }
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(aidlEffect->getDescriptor(&desc)));
+
+ uint64_t effectId;
+ {
+ std::lock_guard lg(mLock);
+ effectId = ++mEffectIdCounter;
+ }
+
+ *effect = sp<EffectHalAidl>::make(aidlEffect, effectId, sessionId, ioId, desc);
+ return OK;
+}
+
+status_t EffectsFactoryHalAidl::dumpEffects(int fd) {
+ ALOGE("%s not implemented yet, fd %d", __func__, fd);
+ return INVALID_OPERATION;
+}
+
+status_t EffectsFactoryHalAidl::allocateBuffer(size_t size, sp<EffectBufferHalInterface>* buffer) {
+ ALOGI("%s size %zu buffer %p", __func__, size, buffer);
+ // Buffer doesn't allocated here for AIDL, instead each effect open will return I/O data FMQ.
+ return EffectBufferHalAidl::allocate(size, buffer);
+}
+
+status_t EffectsFactoryHalAidl::mirrorBuffer(void* external, size_t size,
+ sp<EffectBufferHalInterface>* buffer) {
+ ALOGI("%s extern %p size %zu buffer %p", __func__, external, size, buffer);
+ // TODO: implement with FMQ
+ return EffectBufferHalAidl::mirror(external, size, buffer);
+}
+
+AudioHalVersionInfo EffectsFactoryHalAidl::getHalVersion() const {
+ return mHalVersion;
+}
+
+status_t EffectsFactoryHalAidl::queryEffectList_l() {
+ if (!mDescList) {
+ std::vector<Descriptor> list;
+ auto status = mFactory->queryEffects(std::nullopt, std::nullopt, std::nullopt, &list);
+ if (!status.isOk()) {
+ ALOGE("%s IFactory::queryEffects failed %s", __func__, status.getDescription().c_str());
+ return status.getStatus();
+ }
+
+ mDescList = std::make_unique<std::vector<Descriptor>>(list);
+ }
+ return OK;
+}
+
+status_t EffectsFactoryHalAidl::getHalDescriptorWithImplUuid_l(const AudioUuid& uuid,
+ effect_descriptor_t* pDescriptor) {
+ if (pDescriptor == nullptr) {
+ return BAD_VALUE;
+ }
+ if (!mDescList) {
+ RETURN_STATUS_IF_ERROR(queryEffectList_l());
+ }
+
+ auto matchIt = std::find_if(mDescList->begin(), mDescList->end(),
+ [&](const auto& desc) { return desc.common.id.uuid == uuid; });
+ if (matchIt == mDescList->end()) {
+ ALOGE("%s UUID %s not found", __func__, uuid.toString().c_str());
+ return BAD_VALUE;
+ }
+
+ *pDescriptor = VALUE_OR_RETURN_STATUS(
+ ::aidl::android::aidl2legacy_Descriptor_effect_descriptor(*matchIt));
+ return OK;
+}
+
+status_t EffectsFactoryHalAidl::getHalDescriptorWithTypeUuid_l(
+ const AudioUuid& type, std::vector<effect_descriptor_t>* descriptors) {
+ if (descriptors == nullptr) {
+ return BAD_VALUE;
+ }
+ if (!mDescList) {
+ RETURN_STATUS_IF_ERROR(queryEffectList_l());
+ }
+ std::vector<Descriptor> result;
+ std::copy_if(mDescList->begin(), mDescList->end(), std::back_inserter(result),
+ [&](auto& desc) { return desc.common.id.type == type; });
+ if (result.size() == 0) {
+ ALOGE("%s type UUID %s not found", __func__, type.toString().c_str());
+ return BAD_VALUE;
+ }
+
+ *descriptors = VALUE_OR_RETURN_STATUS(
+ aidl::android::convertContainer<std::vector<effect_descriptor_t>>(
+ result, ::aidl::android::aidl2legacy_Descriptor_effect_descriptor));
+ return OK;
+}
+
+} // namespace effect
+
+// When a shared library is built from a static library, even explicit
+// exports from a static library are optimized out unless actually used by
+// the shared library. See EffectsFactoryHalEntry.cpp.
+extern "C" void* createIEffectsFactoryImpl() {
+ auto serviceName = std::string(IFactory::descriptor) + "/default";
+ auto service = IFactory::fromBinder(
+ ndk::SpAIBinder(AServiceManager_waitForService(serviceName.c_str())));
+ if (!service) {
+ ALOGE("%s binder service %s not exist", __func__, serviceName.c_str());
+ return nullptr;
+ }
+ return new effect::EffectsFactoryHalAidl(service);
+}
+
+} // namespace android
diff --git a/media/libaudiohal/impl/EffectsFactoryHalAidl.h b/media/libaudiohal/impl/EffectsFactoryHalAidl.h
new file mode 100644
index 0000000..1e85da9
--- /dev/null
+++ b/media/libaudiohal/impl/EffectsFactoryHalAidl.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2022 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 <cstddef>
+#include <memory>
+#include <mutex>
+
+#include <android-base/thread_annotations.h>
+#include <media/audiohal/EffectsFactoryHalInterface.h>
+#include <system/thread_defs.h>
+
+namespace android {
+namespace effect {
+
+using namespace aidl::android::hardware::audio::effect;
+
+class EffectsFactoryHalAidl final : public EffectsFactoryHalInterface {
+ public:
+ explicit EffectsFactoryHalAidl(std::shared_ptr<IFactory> effectsFactory);
+
+ // Returns the number of different effects in all loaded libraries.
+ status_t queryNumberEffects(uint32_t *pNumEffects) override;
+
+ // Returns a descriptor of the next available effect.
+ status_t getDescriptor(uint32_t index, effect_descriptor_t* pDescriptor) override;
+
+ status_t getDescriptor(const effect_uuid_t* pEffectUuid,
+ effect_descriptor_t* pDescriptor) override;
+
+ status_t getDescriptors(const effect_uuid_t* pEffectType,
+ std::vector<effect_descriptor_t>* descriptors) override;
+
+ // Creates an effect engine of the specified type.
+ // To release the effect engine, it is necessary to release references to the returned effect
+ // object.
+ status_t createEffect(const effect_uuid_t* pEffectUuid, int32_t sessionId, int32_t ioId,
+ int32_t deviceId, sp<EffectHalInterface>* effect) override;
+
+ status_t dumpEffects(int fd) override;
+
+ status_t allocateBuffer(size_t size, sp<EffectBufferHalInterface>* buffer) override;
+ status_t mirrorBuffer(void* external, size_t size,
+ sp<EffectBufferHalInterface>* buffer) override;
+
+ detail::AudioHalVersionInfo getHalVersion() const override;
+
+ private:
+ std::mutex mLock;
+ const std::shared_ptr<IFactory> mFactory;
+ uint64_t mEffectIdCounter GUARDED_BY(mLock) = 0; // Align with HIDL (0 is INVALID_ID)
+ std::unique_ptr<std::vector<Descriptor>> mDescList GUARDED_BY(mLock) = nullptr;
+ const detail::AudioHalVersionInfo mHalVersion;
+
+ virtual ~EffectsFactoryHalAidl() = default;
+ status_t queryEffectList_l() REQUIRES(mLock);
+ status_t getHalDescriptorWithImplUuid_l(
+ const aidl::android::media::audio::common::AudioUuid& uuid,
+ effect_descriptor_t* pDescriptor) REQUIRES(mLock);
+ status_t getHalDescriptorWithTypeUuid_l(
+ const aidl::android::media::audio::common::AudioUuid& type,
+ std::vector<effect_descriptor_t>* descriptors) REQUIRES(mLock);
+};
+
+} // namespace effect
+} // namespace android
diff --git a/media/libaudiohal/impl/EffectsFactoryHalHidlEntry.cpp b/media/libaudiohal/impl/EffectsFactoryHalEntry.cpp
similarity index 94%
rename from media/libaudiohal/impl/EffectsFactoryHalHidlEntry.cpp
rename to media/libaudiohal/impl/EffectsFactoryHalEntry.cpp
index 2c6f2c6..f6ad99a 100644
--- a/media/libaudiohal/impl/EffectsFactoryHalHidlEntry.cpp
+++ b/media/libaudiohal/impl/EffectsFactoryHalEntry.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include "android/media/AudioHalVersion.h"
+
extern "C" void* createIEffectsFactoryImpl();
extern "C" __attribute__((visibility("default"))) void* createIEffectsFactory() {
diff --git a/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp b/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp
index 3470380..172ebdf 100644
--- a/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp
+++ b/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp
@@ -31,6 +31,9 @@
#include "EffectHalHidl.h"
#include "EffectsFactoryHalHidl.h"
+#include "android/media/AudioHalVersion.h"
+
+using ::android::detail::AudioHalVersionInfo;
using ::android::hardware::audio::common::CPP_VERSION::implementation::UuidUtils;
using ::android::hardware::audio::effect::CPP_VERSION::implementation::EffectUtils;
using ::android::hardware::Return;
@@ -77,7 +80,7 @@
EffectsFactoryHalHidl::EffectsFactoryHalHidl(sp<IEffectsFactory> effectsFactory)
: EffectConversionHelperHidl("EffectsFactory"), mCache(new EffectDescriptorCache) {
ALOG_ASSERT(effectsFactory != nullptr, "Provided IEffectsFactory service is NULL");
- mEffectsFactory = effectsFactory;
+ mEffectsFactory = std::move(effectsFactory);
}
status_t EffectsFactoryHalHidl::queryNumberEffects(uint32_t *pNumEffects) {
@@ -221,11 +224,15 @@
return EffectBufferHalHidl::mirror(external, size, buffer);
}
+AudioHalVersionInfo EffectsFactoryHalHidl::getHalVersion() const {
+ return AudioHalVersionInfo(AudioHalVersionInfo::Type::HIDL, MAJOR_VERSION, MINOR_VERSION);
+}
+
} // namespace effect
// When a shared library is built from a static library, even explicit
// exports from a static library are optimized out unless actually used by
-// the shared library. See EffectsFactoryHalHidlEntry.cpp.
+// the shared library. See EffectsFactoryHalEntry.cpp.
extern "C" void* createIEffectsFactoryImpl() {
auto service = hardware::audio::effect::CPP_VERSION::IEffectsFactory::getService();
return service ? new effect::EffectsFactoryHalHidl(service) : nullptr;
diff --git a/media/libaudiohal/impl/EffectsFactoryHalHidl.h b/media/libaudiohal/impl/EffectsFactoryHalHidl.h
index 7ccddc6..9875154 100644
--- a/media/libaudiohal/impl/EffectsFactoryHalHidl.h
+++ b/media/libaudiohal/impl/EffectsFactoryHalHidl.h
@@ -14,8 +14,7 @@
* limitations under the License.
*/
-#ifndef ANDROID_HARDWARE_EFFECTS_FACTORY_HAL_HIDL_H
-#define ANDROID_HARDWARE_EFFECTS_FACTORY_HAL_HIDL_H
+#pragma once
#include <memory>
@@ -32,39 +31,37 @@
class EffectDescriptorCache;
-class EffectsFactoryHalHidl : public EffectsFactoryHalInterface, public EffectConversionHelperHidl
-{
+class EffectsFactoryHalHidl final : public EffectsFactoryHalInterface,
+ public EffectConversionHelperHidl {
public:
EffectsFactoryHalHidl(sp<IEffectsFactory> effectsFactory);
// Returns the number of different effects in all loaded libraries.
- virtual status_t queryNumberEffects(uint32_t *pNumEffects);
+ status_t queryNumberEffects(uint32_t *pNumEffects) override;
// Returns a descriptor of the next available effect.
- virtual status_t getDescriptor(uint32_t index,
- effect_descriptor_t *pDescriptor);
+ status_t getDescriptor(uint32_t index, effect_descriptor_t* pDescriptor) override;
- virtual status_t getDescriptor(const effect_uuid_t *pEffectUuid,
- effect_descriptor_t *pDescriptor);
+ status_t getDescriptor(const effect_uuid_t* pEffectUuid,
+ effect_descriptor_t* pDescriptor) override;
- virtual status_t getDescriptors(const effect_uuid_t *pEffectType,
- std::vector<effect_descriptor_t> *descriptors);
+ status_t getDescriptors(const effect_uuid_t* pEffectType,
+ std::vector<effect_descriptor_t>* descriptors) override;
// Creates an effect engine of the specified type.
// To release the effect engine, it is necessary to release references
// to the returned effect object.
- virtual status_t createEffect(const effect_uuid_t *pEffectUuid,
- int32_t sessionId, int32_t ioId, int32_t deviceId,
- sp<EffectHalInterface> *effect);
+ status_t createEffect(const effect_uuid_t* pEffectUuid, int32_t sessionId, int32_t ioId,
+ int32_t deviceId, sp<EffectHalInterface>* effect) override;
- virtual status_t dumpEffects(int fd);
-
- virtual float getHalVersion() { return MAJOR_VERSION + (float)MINOR_VERSION / 10; }
+ status_t dumpEffects(int fd) override;
status_t allocateBuffer(size_t size, sp<EffectBufferHalInterface>* buffer) override;
status_t mirrorBuffer(void* external, size_t size,
sp<EffectBufferHalInterface>* buffer) override;
+ android::detail::AudioHalVersionInfo getHalVersion() const override;
+
private:
sp<IEffectsFactory> mEffectsFactory;
std::unique_ptr<EffectDescriptorCache> mCache;
@@ -72,5 +69,3 @@
} // namespace effect
} // namespace android
-
-#endif // ANDROID_HARDWARE_EFFECTS_FACTORY_HAL_HIDL_H
diff --git a/media/libaudiohal/impl/StreamHalAidl.cpp b/media/libaudiohal/impl/StreamHalAidl.cpp
new file mode 100644
index 0000000..1c6a014
--- /dev/null
+++ b/media/libaudiohal/impl/StreamHalAidl.cpp
@@ -0,0 +1,517 @@
+/*
+ * Copyright (C) 2023 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 "StreamHalAidl"
+//#define LOG_NDEBUG 0
+
+#include <aidl/android/hardware/audio/core/BnStreamCallback.h>
+#include <mediautils/TimeCheck.h>
+#include <utils/Log.h>
+
+#include "DeviceHalAidl.h"
+#include "StreamHalAidl.h"
+
+using ::aidl::android::hardware::audio::core::IStreamCommon;
+using ::aidl::android::hardware::audio::core::IStreamIn;
+using ::aidl::android::hardware::audio::core::IStreamOut;
+using ::aidl::android::hardware::audio::core::StreamDescriptor;
+
+namespace android {
+
+// static
+template<class T>
+std::shared_ptr<IStreamCommon> StreamHalAidl::getStreamCommon(const std::shared_ptr<T>& stream) {
+ std::shared_ptr<::aidl::android::hardware::audio::core::IStreamCommon> streamCommon;
+ if (stream != nullptr) {
+ if (ndk::ScopedAStatus status = stream->getStreamCommon(&streamCommon);
+ !status.isOk()) {
+ ALOGE("%s: failed to retrieve IStreamCommon instance: %s", __func__,
+ status.getDescription().c_str());
+ }
+ }
+ return streamCommon;
+}
+
+StreamHalAidl::StreamHalAidl(
+ std::string_view className, bool isInput, const StreamDescriptor& descriptor,
+ const std::shared_ptr<IStreamCommon>& stream)
+ : ConversionHelperAidl(className),
+ mIsInput(isInput),
+ mFrameSizeBytes(descriptor.frameSizeBytes),
+ mBufferSizeFrames(descriptor.bufferSizeFrames),
+ mCommandMQ(new CommandMQ(descriptor.command)),
+ mReplyMQ(new ReplyMQ(descriptor.reply)),
+ mDataMQ(maybeCreateDataMQ(descriptor)),
+ mStream(stream) {
+ // Instrument audio signal power logging.
+ // Note: This assumes channel mask, format, and sample rate do not change after creation.
+ if (audio_config_base_t config = AUDIO_CONFIG_BASE_INITIALIZER;
+ /* mStreamPowerLog.isUserDebugOrEngBuild() && */
+ StreamHalAidl::getAudioProperties(&config) == NO_ERROR) {
+ mStreamPowerLog.init(config.sample_rate, config.channel_mask, config.format);
+ }
+}
+
+StreamHalAidl::~StreamHalAidl() {
+ if (mStream != nullptr) {
+ ndk::ScopedAStatus status = mStream->close();
+ ALOGE_IF(!status.isOk(), "%s: status %s", __func__, status.getDescription().c_str());
+ }
+}
+
+status_t StreamHalAidl::getBufferSize(size_t *size) {
+ if (size == nullptr) {
+ return BAD_VALUE;
+ }
+ if (mFrameSizeBytes == 0 || mBufferSizeFrames == 0) {
+ return NO_INIT;
+ }
+ *size = mFrameSizeBytes * mBufferSizeFrames;
+ return OK;
+}
+
+status_t StreamHalAidl::getAudioProperties(audio_config_base_t *configBase) {
+ if (configBase == nullptr) {
+ return BAD_VALUE;
+ }
+ TIME_CHECK();
+ *configBase = AUDIO_CONFIG_BASE_INITIALIZER;
+ configBase->sample_rate = 48000;
+ configBase->format = AUDIO_FORMAT_PCM_24_BIT_PACKED;
+ configBase->channel_mask = mIsInput ? AUDIO_CHANNEL_IN_STEREO : AUDIO_CHANNEL_OUT_STEREO;
+ // if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamHalAidl::setParameters(const String8& kvPairs __unused) {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamHalAidl::getParameters(const String8& keys __unused, String8 *values) {
+ TIME_CHECK();
+ values->clear();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamHalAidl::getFrameSize(size_t *size) {
+ if (size == nullptr) {
+ return BAD_VALUE;
+ }
+ if (mFrameSizeBytes == 0) {
+ return NO_INIT;
+ }
+ *size = mFrameSizeBytes;
+ return OK;
+}
+
+status_t StreamHalAidl::addEffect(sp<EffectHalInterface> effect __unused) {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamHalAidl::removeEffect(sp<EffectHalInterface> effect __unused) {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamHalAidl::standby() {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamHalAidl::dump(int fd, const Vector<String16>& args) {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ return mStream->dump(fd, Args(args).args(), args.size());
+}
+
+status_t StreamHalAidl::start() {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamHalAidl::stop() {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamHalAidl::createMmapBuffer(int32_t minSizeFrames __unused,
+ struct audio_mmap_buffer_info *info __unused) {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamHalAidl::getMmapPosition(struct audio_mmap_position *position __unused) {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamHalAidl::setHalThreadPriority(int priority __unused) {
+ mHalThreadPriority = priority;
+ return OK;
+}
+
+status_t StreamHalAidl::getHalPid(pid_t *pid __unused) {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+bool StreamHalAidl::requestHalThreadPriority(pid_t threadPid __unused, pid_t threadId __unused) {
+ if (mHalThreadPriority == HAL_THREAD_PRIORITY_DEFAULT) {
+ return true;
+ }
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamHalAidl::legacyCreateAudioPatch(const struct audio_port_config& port __unused,
+ std::optional<audio_source_t> source __unused,
+ audio_devices_t type __unused) {
+ // Obsolete since 'DeviceHalAidl.supportsAudioPatches' always returns 'true'.
+ return INVALID_OPERATION;
+}
+
+status_t StreamHalAidl::legacyReleaseAudioPatch() {
+ // Obsolete since 'DeviceHalAidl.supportsAudioPatches' always returns 'true'.
+ return INVALID_OPERATION;
+}
+
+namespace {
+
+/* Notes on callback ownership.
+
+This is how Binder ownership model looks like. The server implementation
+is owned by Binder framework (via sp<>). Proxies are owned by clients.
+When the last proxy disappears, Binder framework releases the server impl.
+
+Thus, it is not needed to keep any references to StreamCallback (this is
+the server impl) -- it will live as long as HAL server holds a strong ref to
+IStreamCallback proxy.
+
+The callback only keeps a weak reference to the stream. The stream is owned
+by AudioFlinger.
+
+*/
+
+class StreamCallback : public ::aidl::android::hardware::audio::core::BnStreamCallback {
+ ndk::ScopedAStatus onTransferReady() override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus onError() override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus onDrainReady() override {
+ return ndk::ScopedAStatus::ok();
+ }
+};
+
+} // namespace
+
+StreamOutHalAidl::StreamOutHalAidl(
+ const StreamDescriptor& descriptor, const std::shared_ptr<IStreamOut>& stream)
+ : StreamHalAidl("StreamOutHalAidl", false /*isInput*/, descriptor, getStreamCommon(stream)),
+ mStream(stream) {}
+
+status_t StreamOutHalAidl::getLatency(uint32_t *latency) {
+ TIME_CHECK();
+ *latency = 0;
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamOutHalAidl::setVolume(float left __unused, float right __unused) {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamOutHalAidl::selectPresentation(int presentationId __unused, int programId __unused) {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamOutHalAidl::write(
+ const void *buffer __unused, size_t bytes __unused, size_t *written __unused) {
+ // TIME_CHECK(); // TODO(b/238654698) reenable only when optimized.
+ if (!mStream) return NO_INIT;
+ *written = 0;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamOutHalAidl::getRenderPosition(uint32_t *dspFrames __unused) {
+ // TIME_CHECK(); // TODO(b/238654698) reenable only when optimized.
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamOutHalAidl::getNextWriteTimestamp(int64_t *timestamp __unused) {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamOutHalAidl::setCallback(wp<StreamOutHalInterfaceCallback> callback __unused) {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamOutHalAidl::supportsPauseAndResume(
+ bool *supportsPause __unused, bool *supportsResume __unused) {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamOutHalAidl::pause() {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamOutHalAidl::resume() {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamOutHalAidl::supportsDrain(bool *supportsDrain __unused) {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamOutHalAidl::drain(bool earlyNotify __unused) {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamOutHalAidl::flush() {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamOutHalAidl::getPresentationPosition(
+ uint64_t *frames __unused, struct timespec *timestamp __unused) {
+ // TIME_CHECK(); // TODO(b/238654698) reenable only when optimized.
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamOutHalAidl::updateSourceMetadata(
+ const StreamOutHalInterface::SourceMetadata& sourceMetadata __unused) {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamOutHalAidl::getDualMonoMode(audio_dual_mono_mode_t* mode __unused) {
+ return INVALID_OPERATION;
+}
+
+status_t StreamOutHalAidl::setDualMonoMode(audio_dual_mono_mode_t mode __unused) {
+ return INVALID_OPERATION;
+}
+
+status_t StreamOutHalAidl::getAudioDescriptionMixLevel(float* leveldB __unused) {
+ return INVALID_OPERATION;
+}
+
+status_t StreamOutHalAidl::setAudioDescriptionMixLevel(float leveldB __unused) {
+ return INVALID_OPERATION;
+}
+
+status_t StreamOutHalAidl::getPlaybackRateParameters(
+ audio_playback_rate_t* playbackRate __unused) {
+ return INVALID_OPERATION;
+}
+
+status_t StreamOutHalAidl::setPlaybackRateParameters(
+ const audio_playback_rate_t& playbackRate __unused) {
+ return INVALID_OPERATION;
+}
+
+status_t StreamOutHalAidl::setEventCallback(
+ const sp<StreamOutHalInterfaceEventCallback>& callback __unused) {
+ return INVALID_OPERATION;
+}
+
+namespace {
+
+struct StreamOutEventCallback {
+ StreamOutEventCallback(const wp<StreamOutHalAidl>& stream) : mStream(stream) {}
+ private:
+ wp<StreamOutHalAidl> mStream;
+};
+
+} // namespace
+
+status_t StreamOutHalAidl::setLatencyMode(audio_latency_mode_t mode __unused) {
+ return INVALID_OPERATION;
+};
+
+status_t StreamOutHalAidl::getRecommendedLatencyModes(
+ std::vector<audio_latency_mode_t> *modes __unused) {
+ return INVALID_OPERATION;
+};
+
+status_t StreamOutHalAidl::setLatencyModeCallback(
+ const sp<StreamOutHalInterfaceLatencyModeCallback>& callback __unused) {
+ return INVALID_OPERATION;
+};
+
+void StreamOutHalAidl::onWriteReady() {
+ sp<StreamOutHalInterfaceCallback> callback = mCallback.load().promote();
+ if (callback == 0) return;
+ ALOGV("asyncCallback onWriteReady");
+ callback->onWriteReady();
+}
+
+void StreamOutHalAidl::onDrainReady() {
+ sp<StreamOutHalInterfaceCallback> callback = mCallback.load().promote();
+ if (callback == 0) return;
+ ALOGV("asyncCallback onDrainReady");
+ callback->onDrainReady();
+}
+
+void StreamOutHalAidl::onError() {
+ sp<StreamOutHalInterfaceCallback> callback = mCallback.load().promote();
+ if (callback == 0) return;
+ ALOGV("asyncCallback onError");
+ callback->onError();
+}
+
+void StreamOutHalAidl::onCodecFormatChanged(const std::basic_string<uint8_t>& metadataBs __unused) {
+ sp<StreamOutHalInterfaceEventCallback> callback = mEventCallback.load().promote();
+ if (callback == nullptr) return;
+ ALOGV("asyncCodecFormatCallback %s", __func__);
+ callback->onCodecFormatChanged(metadataBs);
+}
+
+void StreamOutHalAidl::onRecommendedLatencyModeChanged(
+ const std::vector<audio_latency_mode_t>& modes __unused) {
+ sp<StreamOutHalInterfaceLatencyModeCallback> callback = mLatencyModeCallback.load().promote();
+ if (callback == nullptr) return;
+ callback->onRecommendedLatencyModeChanged(modes);
+}
+
+status_t StreamOutHalAidl::exit() {
+ // FIXME this is using hard-coded strings but in the future, this functionality will be
+ // converted to use audio HAL extensions required to support tunneling
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+StreamInHalAidl::StreamInHalAidl(
+ const StreamDescriptor& descriptor, const std::shared_ptr<IStreamIn>& stream)
+ : StreamHalAidl("StreamInHalAidl", true /*isInput*/, descriptor, getStreamCommon(stream)),
+ mStream(stream) {}
+
+status_t StreamInHalAidl::setGain(float gain __unused) {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamInHalAidl::read(
+ void *buffer __unused, size_t bytes __unused, size_t *read __unused) {
+ // TIME_CHECK(); // TODO(b/238654698) reenable only when optimized.
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ // FIXME: Don't forget to update mPowerLog
+ return OK;
+}
+
+status_t StreamInHalAidl::getInputFramesLost(uint32_t *framesLost __unused) {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamInHalAidl::getCapturePosition(int64_t *frames __unused, int64_t *time __unused) {
+ // TIME_CHECK(); // TODO(b/238654698) reenable only when optimized.
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamInHalAidl::getActiveMicrophones(
+ std::vector<media::MicrophoneInfo> *microphones __unused) {
+ if (mStream == 0) return NO_INIT;
+ return INVALID_OPERATION;
+}
+
+status_t StreamInHalAidl::updateSinkMetadata(
+ const StreamInHalInterface::SinkMetadata& sinkMetadata __unused) {
+ return INVALID_OPERATION;
+}
+
+status_t StreamInHalAidl::setPreferredMicrophoneDirection(
+ audio_microphone_direction_t direction __unused) {
+ if (mStream == 0) return NO_INIT;
+ return INVALID_OPERATION;
+}
+
+status_t StreamInHalAidl::setPreferredMicrophoneFieldDimension(float zoom __unused) {
+ if (mStream == 0) return NO_INIT;
+ return INVALID_OPERATION;
+}
+
+} // namespace android
diff --git a/media/libaudiohal/impl/StreamHalAidl.h b/media/libaudiohal/impl/StreamHalAidl.h
new file mode 100644
index 0000000..c56d5e3
--- /dev/null
+++ b/media/libaudiohal/impl/StreamHalAidl.h
@@ -0,0 +1,280 @@
+/*
+ * Copyright (C) 2023 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 <memory>
+#include <string_view>
+
+#include <aidl/android/hardware/audio/core/BpStreamCommon.h>
+#include <aidl/android/hardware/audio/core/BpStreamIn.h>
+#include <aidl/android/hardware/audio/core/BpStreamOut.h>
+#include <fmq/AidlMessageQueue.h>
+#include <media/audiohal/EffectHalInterface.h>
+#include <media/audiohal/StreamHalInterface.h>
+#include <mediautils/Synchronization.h>
+
+#include "ConversionHelperAidl.h"
+#include "StreamPowerLog.h"
+
+namespace android {
+
+class DeviceHalAidl;
+
+class StreamHalAidl : public virtual StreamHalInterface, public ConversionHelperAidl {
+ public:
+ // Return size of input/output buffer in bytes for this stream - eg. 4800.
+ status_t getBufferSize(size_t *size) override;
+
+ // Return the base configuration of the stream:
+ // - channel mask;
+ // - format - e.g. AUDIO_FORMAT_PCM_16_BIT;
+ // - sampling rate in Hz - eg. 44100.
+ status_t getAudioProperties(audio_config_base_t *configBase) override;
+
+ // Set audio stream parameters.
+ status_t setParameters(const String8& kvPairs) override;
+
+ // Get audio stream parameters.
+ status_t getParameters(const String8& keys, String8 *values) override;
+
+ // Return the frame size (number of bytes per sample) of a stream.
+ status_t getFrameSize(size_t *size) override;
+
+ // Add or remove the effect on the stream.
+ status_t addEffect(sp<EffectHalInterface> effect) override;
+ status_t removeEffect(sp<EffectHalInterface> effect) override;
+
+ // Put the audio hardware input/output into standby mode.
+ status_t standby() override;
+
+ status_t dump(int fd, const Vector<String16>& args) override;
+
+ // Start a stream operating in mmap mode.
+ status_t start() override;
+
+ // Stop a stream operating in mmap mode.
+ status_t stop() override;
+
+ // Retrieve information on the data buffer in mmap mode.
+ status_t createMmapBuffer(int32_t minSizeFrames,
+ struct audio_mmap_buffer_info *info) override;
+
+ // Get current read/write position in the mmap buffer
+ status_t getMmapPosition(struct audio_mmap_position *position) override;
+
+ // Set the priority of the thread that interacts with the HAL
+ // (must match the priority of the audioflinger's thread that calls 'read' / 'write')
+ status_t setHalThreadPriority(int priority) override;
+
+ status_t legacyCreateAudioPatch(const struct audio_port_config& port,
+ std::optional<audio_source_t> source,
+ audio_devices_t type) override;
+
+ status_t legacyReleaseAudioPatch() override;
+
+ protected:
+ typedef AidlMessageQueue<::aidl::android::hardware::audio::core::StreamDescriptor::Command,
+ ::aidl::android::hardware::common::fmq::SynchronizedReadWrite> CommandMQ;
+ typedef AidlMessageQueue<::aidl::android::hardware::audio::core::StreamDescriptor::Reply,
+ ::aidl::android::hardware::common::fmq::SynchronizedReadWrite> ReplyMQ;
+ typedef AidlMessageQueue<int8_t,
+ ::aidl::android::hardware::common::fmq::SynchronizedReadWrite> DataMQ;
+
+ template<class T>
+ static std::shared_ptr<::aidl::android::hardware::audio::core::IStreamCommon> getStreamCommon(
+ const std::shared_ptr<T>& stream);
+
+ // Subclasses can not be constructed directly by clients.
+ StreamHalAidl(std::string_view className,
+ bool isInput,
+ const ::aidl::android::hardware::audio::core::StreamDescriptor& descriptor,
+ const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamCommon>& stream);
+
+ ~StreamHalAidl() override;
+
+ status_t getHalPid(pid_t *pid);
+
+ bool requestHalThreadPriority(pid_t threadPid, pid_t threadId);
+
+ const bool mIsInput;
+ const size_t mFrameSizeBytes;
+ const size_t mBufferSizeFrames;
+ const std::unique_ptr<CommandMQ> mCommandMQ;
+ const std::unique_ptr<ReplyMQ> mReplyMQ;
+ const std::unique_ptr<DataMQ> mDataMQ;
+ // mStreamPowerLog is used for audio signal power logging.
+ StreamPowerLog mStreamPowerLog;
+
+ private:
+ static std::unique_ptr<DataMQ> maybeCreateDataMQ(
+ const ::aidl::android::hardware::audio::core::StreamDescriptor& descriptor) {
+ using Tag = ::aidl::android::hardware::audio::core::StreamDescriptor::AudioBuffer::Tag;
+ if (descriptor.audio.getTag() == Tag::fmq) {
+ return std::make_unique<DataMQ>(descriptor.audio.get<Tag::fmq>());
+ }
+ return nullptr;
+ }
+
+ const int HAL_THREAD_PRIORITY_DEFAULT = -1;
+ const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamCommon> mStream;
+ int mHalThreadPriority = HAL_THREAD_PRIORITY_DEFAULT;
+};
+
+class StreamOutHalAidl : public StreamOutHalInterface, public StreamHalAidl {
+ public:
+ // Return the audio hardware driver estimated latency in milliseconds.
+ status_t getLatency(uint32_t *latency) override;
+
+ // Use this method in situations where audio mixing is done in the hardware.
+ status_t setVolume(float left, float right) override;
+
+ // Selects the audio presentation (if available).
+ status_t selectPresentation(int presentationId, int programId) override;
+
+ // Write audio buffer to driver.
+ status_t write(const void *buffer, size_t bytes, size_t *written) override;
+
+ // Return the number of audio frames written by the audio dsp to DAC since
+ // the output has exited standby.
+ status_t getRenderPosition(uint32_t *dspFrames) override;
+
+ // Get the local time at which the next write to the audio driver will be presented.
+ status_t getNextWriteTimestamp(int64_t *timestamp) override;
+
+ // Set the callback for notifying completion of non-blocking write and drain.
+ status_t setCallback(wp<StreamOutHalInterfaceCallback> callback) override;
+
+ // Returns whether pause and resume operations are supported.
+ status_t supportsPauseAndResume(bool *supportsPause, bool *supportsResume) override;
+
+ // Notifies to the audio driver to resume playback following a pause.
+ status_t pause() override;
+
+ // Notifies to the audio driver to resume playback following a pause.
+ status_t resume() override;
+
+ // Returns whether drain operation is supported.
+ status_t supportsDrain(bool *supportsDrain) override;
+
+ // Requests notification when data buffered by the driver/hardware has been played.
+ status_t drain(bool earlyNotify) override;
+
+ // Notifies to the audio driver to flush the queued data.
+ status_t flush() override;
+
+ // Return a recent count of the number of audio frames presented to an external observer.
+ status_t getPresentationPosition(uint64_t *frames, struct timespec *timestamp) override;
+
+ // Called when the metadata of the stream's source has been changed.
+ status_t updateSourceMetadata(const SourceMetadata& sourceMetadata) override;
+
+ // Returns the Dual Mono mode presentation setting.
+ status_t getDualMonoMode(audio_dual_mono_mode_t* mode) override;
+
+ // Sets the Dual Mono mode presentation on the output device.
+ status_t setDualMonoMode(audio_dual_mono_mode_t mode) override;
+
+ // Returns the Audio Description Mix level in dB.
+ status_t getAudioDescriptionMixLevel(float* leveldB) override;
+
+ // Sets the Audio Description Mix level in dB.
+ status_t setAudioDescriptionMixLevel(float leveldB) override;
+
+ // Retrieves current playback rate parameters.
+ status_t getPlaybackRateParameters(audio_playback_rate_t* playbackRate) override;
+
+ // Sets the playback rate parameters that control playback behavior.
+ status_t setPlaybackRateParameters(const audio_playback_rate_t& playbackRate) override;
+
+ status_t setEventCallback(const sp<StreamOutHalInterfaceEventCallback>& callback) override;
+
+ status_t setLatencyMode(audio_latency_mode_t mode) override;
+ status_t getRecommendedLatencyModes(std::vector<audio_latency_mode_t> *modes) override;
+ status_t setLatencyModeCallback(
+ const sp<StreamOutHalInterfaceLatencyModeCallback>& callback) override;
+
+ void onRecommendedLatencyModeChanged(const std::vector<audio_latency_mode_t>& modes);
+
+ status_t exit() override;
+
+ void onCodecFormatChanged(const std::basic_string<uint8_t>& metadataBs);
+
+ // Methods used by StreamOutCallback ().
+ // FIXME: Consider the required visibility.
+ void onWriteReady();
+ void onDrainReady();
+ void onError();
+
+ private:
+ friend class sp<StreamOutHalAidl>;
+
+ mediautils::atomic_wp<StreamOutHalInterfaceCallback> mCallback;
+ mediautils::atomic_wp<StreamOutHalInterfaceEventCallback> mEventCallback;
+ mediautils::atomic_wp<StreamOutHalInterfaceLatencyModeCallback> mLatencyModeCallback;
+
+ const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamOut> mStream;
+
+ // Can not be constructed directly by clients.
+ StreamOutHalAidl(
+ const ::aidl::android::hardware::audio::core::StreamDescriptor& descriptor,
+ const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamOut>& stream);
+
+ ~StreamOutHalAidl() override = default;
+};
+
+class StreamInHalAidl : public StreamInHalInterface, public StreamHalAidl {
+ public:
+ // Set the input gain for the audio driver.
+ status_t setGain(float gain) override;
+
+ // Read audio buffer in from driver.
+ status_t read(void *buffer, size_t bytes, size_t *read) override;
+
+ // Return the amount of input frames lost in the audio driver.
+ status_t getInputFramesLost(uint32_t *framesLost) override;
+
+ // Return a recent count of the number of audio frames received and
+ // the clock time associated with that frame count.
+ status_t getCapturePosition(int64_t *frames, int64_t *time) override;
+
+ // Get active microphones
+ status_t getActiveMicrophones(std::vector<media::MicrophoneInfo> *microphones) override;
+
+ // Set microphone direction (for processing)
+ status_t setPreferredMicrophoneDirection(
+ audio_microphone_direction_t direction) override;
+
+ // Set microphone zoom (for processing)
+ status_t setPreferredMicrophoneFieldDimension(float zoom) override;
+
+ // Called when the metadata of the stream's sink has been changed.
+ status_t updateSinkMetadata(const SinkMetadata& sinkMetadata) override;
+
+ private:
+ friend class sp<StreamInHalAidl>;
+
+ const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamIn> mStream;
+
+ // Can not be constructed directly by clients.
+ StreamInHalAidl(
+ const ::aidl::android::hardware::audio::core::StreamDescriptor& descriptor,
+ const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamIn>& stream);
+
+ ~StreamInHalAidl() override = default;
+};
+
+} // namespace android
diff --git a/media/libaudiohal/impl/StreamHalHidl.cpp b/media/libaudiohal/impl/StreamHalHidl.cpp
index 76f9a60..2c289e1 100644
--- a/media/libaudiohal/impl/StreamHalHidl.cpp
+++ b/media/libaudiohal/impl/StreamHalHidl.cpp
@@ -46,9 +46,6 @@
using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION;
-#define TIME_CHECK() auto TimeCheck = \
- mediautils::makeTimeCheckStatsForClassMethod(getClassName(), __func__)
-
StreamHalHidl::StreamHalHidl(std::string_view className, IStream *stream)
: CoreConversionHelperHidl(className),
mStream(stream),
diff --git a/media/libaudiohal/include/media/audiohal/AudioEffectUuid.h b/media/libaudiohal/include/media/audiohal/AudioEffectUuid.h
new file mode 100644
index 0000000..20a10f6
--- /dev/null
+++ b/media/libaudiohal/include/media/audiohal/AudioEffectUuid.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2023 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 <aidl/android/media/audio/common/AudioUuid.h>
+
+namespace android {
+namespace effect {
+
+using ::aidl::android::media::audio::common::AudioUuid;
+
+// 7b491460-8d4d-11e0-bd61-0002a5d5c51b.
+static const AudioUuid kAcousticEchoCancelerTypeUUID = {static_cast<int32_t>(0x7b491460),
+ 0x8d4d,
+ 0x11e0,
+ 0xbd61,
+ {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
+// 0xae3c653b-be18-4ab8-8938-418f0a7f06ac
+static const AudioUuid kAutomaticGainControlTypeUUID = {static_cast<int32_t>(0xae3c653b),
+ 0xbe18,
+ 0x4ab8,
+ 0x8938,
+ {0x41, 0x8f, 0x0a, 0x7f, 0x06, 0xac}};
+// 0634f220-ddd4-11db-a0fc-0002a5d5c51b
+static const AudioUuid kBassBoostTypeUUID = {static_cast<int32_t>(0x0634f220),
+ 0xddd4,
+ 0x11db,
+ 0xa0fc,
+ {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
+// fa81862a-588b-11ed-9b6a-0242ac120002
+static const AudioUuid kDownmixTypeUUID = {static_cast<int32_t>(0xfa81862a),
+ 0x588b,
+ 0x11ed,
+ 0x9b6a,
+ {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
+// 0bed4300-ddd6-11db-8f34-0002a5d5c51b.
+static const AudioUuid kEqualizerTypeUUID = {static_cast<int32_t>(0x0bed4300),
+ 0xddd6,
+ 0x11db,
+ 0x8f34,
+ {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
+// 7261676f-6d75-7369-6364-28e2fd3ac39e
+static const AudioUuid kDynamicsProcessingTypeUUID = {static_cast<int32_t>(0x7261676f),
+ 0x6d75,
+ 0x7369,
+ 0x6364,
+ {0x28, 0xe2, 0xfd, 0x3a, 0xc3, 0x9e}};
+// 1411e6d6-aecd-4021-a1cf-a6aceb0d71e5
+static const AudioUuid kHapticGeneratorTypeUUID = {static_cast<int32_t>(0x1411e6d6),
+ 0xaecd,
+ 0x4021,
+ 0xa1cf,
+ {0xa6, 0xac, 0xeb, 0x0d, 0x71, 0xe5}};
+// fe3199be-aed0-413f-87bb-11260eb63cf1
+static const AudioUuid kLoudnessEnhancerTypeUUID = {static_cast<int32_t>(0xfe3199be),
+ 0xaed0,
+ 0x413f,
+ 0x87bb,
+ {0x11, 0x26, 0x0e, 0xb6, 0x3c, 0xf1}};
+// c2e5d5f0-94bd-4763-9cac-4e234d06839e
+static const AudioUuid kEnvReverbTypeUUID = {static_cast<int32_t>(0xc2e5d5f0),
+ 0x94bd,
+ 0x4763,
+ 0x9cac,
+ {0x4e, 0x23, 0x4d, 0x06, 0x83, 0x9e}};
+// 58b4b260-8e06-11e0-aa8e-0002a5d5c51b
+static const AudioUuid kNoiseSuppressionTypeUUID = {static_cast<int32_t>(0x58b4b260),
+ 0x8e06,
+ 0x11e0,
+ 0xaa8e,
+ {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
+// 47382d60-ddd8-11db-bf3a-0002a5d5c51b
+static const AudioUuid kPresetReverbTypeUUID = {static_cast<int32_t>(0x47382d60),
+ 0xddd8,
+ 0x11db,
+ 0xbf3a,
+ {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
+// 37cc2c00-dddd-11db-8577-0002a5d5c51b
+static const AudioUuid kVirtualizerTypeUUID = {static_cast<int32_t>(0x37cc2c00),
+ 0xdddd,
+ 0x11db,
+ 0x8577,
+ {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
+// fa819f3e-588b-11ed-9b6a-0242ac120002
+static const AudioUuid kVisualizerTypeUUID = {static_cast<int32_t>(0xfa819f3e),
+ 0x588b,
+ 0x11ed,
+ 0x9b6a,
+ {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
+// fa81a2b8-588b-11ed-9b6a-0242ac120002
+static const AudioUuid kVolumeTypeUUID = {static_cast<int32_t>(0xfa81a2b8),
+ 0x588b,
+ 0x11ed,
+ 0x9b6a,
+ {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
+
+} // namespace effect
+} // namespace android
diff --git a/media/libaudiohal/include/media/audiohal/AudioHalVersionInfo.h b/media/libaudiohal/include/media/audiohal/AudioHalVersionInfo.h
new file mode 100644
index 0000000..6e09463
--- /dev/null
+++ b/media/libaudiohal/include/media/audiohal/AudioHalVersionInfo.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 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 <utility>
+#include <android/media/AudioHalVersion.h>
+
+namespace android::detail {
+
+class AudioHalVersionInfo : public android::media::AudioHalVersion {
+ public:
+ AudioHalVersionInfo(Type halType, int halMajor, int halMinor = 0) {
+ type = halType;
+ major = halMajor;
+ minor = halMinor;
+ }
+
+ Type getType() const { return type; }
+
+ int getMajorVersion() const { return major; }
+
+ int getMinorVersion() const { return minor; }
+
+ /** Keep HIDL version format as is for backward compatibility, only add prefix for AIDL. */
+ std::string toVersionString() const {
+ std::string versionStr =
+ android::internal::ToString(major) + "." + android::internal::ToString(minor);
+ if (type == Type::AIDL) {
+ return "aidl";
+ } else {
+ return versionStr;
+ }
+ }
+};
+
+} // namespace android
diff --git a/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
index d27ad4c..094b415 100644
--- a/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
+++ b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
@@ -21,7 +21,6 @@
#include <android/media/audio/common/AudioMMapPolicyType.h>
#include <error/Result.h>
#include <media/audiohal/EffectHalInterface.h>
-#include <media/MicrophoneInfo.h>
#include <system/audio.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>
@@ -107,7 +106,7 @@
virtual status_t releaseAudioPatch(audio_patch_handle_t patch) = 0;
// Fills the list of supported attributes for a given audio port.
- virtual status_t getAudioPort(struct audio_port *port) = 0;
+ virtual status_t getAudioPort(struct audio_port* port) = 0;
// Fills the list of supported attributes for a given audio port.
virtual status_t getAudioPort(struct audio_port_v7 *port) = 0;
@@ -116,7 +115,8 @@
virtual status_t setAudioPortConfig(const struct audio_port_config *config) = 0;
// List microphones
- virtual status_t getMicrophones(std::vector<media::MicrophoneInfo> *microphones) = 0;
+ virtual status_t getMicrophones(
+ std::vector<audio_microphone_characteristic_t>* microphones) = 0;
virtual status_t addDeviceEffect(
audio_port_handle_t device, sp<EffectHalInterface> effect) = 0;
@@ -125,12 +125,16 @@
virtual status_t getMmapPolicyInfos(
media::audio::common::AudioMMapPolicyType policyType,
- std::vector<media::audio::common::AudioMMapPolicyInfo> *policyInfos) = 0;
+ std::vector<media::audio::common::AudioMMapPolicyInfo> *policyInfos) = 0;
virtual int32_t getAAudioMixerBurstCount() = 0;
virtual int32_t getAAudioHardwareBurstMinUsec() = 0;
+ virtual int32_t supportsBluetoothVariableLatency(bool* supports) = 0;
// Update the connection status of an external device.
- virtual status_t setConnectedState(const struct audio_port_v7 *port, bool connected) = 0;
+ virtual status_t setConnectedState(const struct audio_port_v7* port, bool connected) {
+ ALOGE("%s override me port %p connected %d", __func__, port, connected);
+ return OK;
+ }
virtual error::Result<audio_hw_sync_t> getHwAvSync() = 0;
diff --git a/media/libaudiohal/include/media/audiohal/DevicesFactoryHalInterface.h b/media/libaudiohal/include/media/audiohal/DevicesFactoryHalInterface.h
index 17010e6..be3a723 100644
--- a/media/libaudiohal/include/media/audiohal/DevicesFactoryHalInterface.h
+++ b/media/libaudiohal/include/media/audiohal/DevicesFactoryHalInterface.h
@@ -14,14 +14,15 @@
* limitations under the License.
*/
-#ifndef ANDROID_HARDWARE_DEVICES_FACTORY_HAL_INTERFACE_H
-#define ANDROID_HARDWARE_DEVICES_FACTORY_HAL_INTERFACE_H
+#pragma once
#include <media/audiohal/DeviceHalInterface.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>
#include <vector>
+#include "AudioHalVersionInfo.h"
+
namespace android {
class DevicesFactoryHalCallback : public RefBase
@@ -43,7 +44,7 @@
// The callback can be only set once.
virtual status_t setCallbackOnce(sp<DevicesFactoryHalCallback> callback) = 0;
- virtual float getHalVersion() const = 0;
+ virtual android::detail::AudioHalVersionInfo getHalVersion() const = 0;
static sp<DevicesFactoryHalInterface> create();
@@ -55,5 +56,3 @@
};
} // namespace android
-
-#endif // ANDROID_HARDWARE_DEVICES_FACTORY_HAL_INTERFACE_H
diff --git a/media/libaudiohal/include/media/audiohal/EffectsFactoryHalInterface.h b/media/libaudiohal/include/media/audiohal/EffectsFactoryHalInterface.h
index 3e505bd..d740fe9 100644
--- a/media/libaudiohal/include/media/audiohal/EffectsFactoryHalInterface.h
+++ b/media/libaudiohal/include/media/audiohal/EffectsFactoryHalInterface.h
@@ -14,14 +14,16 @@
* limitations under the License.
*/
-#ifndef ANDROID_HARDWARE_EFFECTS_FACTORY_HAL_INTERFACE_H
-#define ANDROID_HARDWARE_EFFECTS_FACTORY_HAL_INTERFACE_H
+#pragma once
#include <media/audiohal/EffectHalInterface.h>
#include <system/audio_effect.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>
+#include "AudioHalVersionInfo.h"
+#include "FactoryHal.h"
+
namespace android {
class EffectsFactoryHalInterface : public RefBase
@@ -49,16 +51,16 @@
virtual status_t dumpEffects(int fd) = 0;
- virtual float getHalVersion() = 0;
-
static sp<EffectsFactoryHalInterface> create();
virtual status_t allocateBuffer(size_t size, sp<EffectBufferHalInterface>* buffer) = 0;
virtual status_t mirrorBuffer(void* external, size_t size,
sp<EffectBufferHalInterface>* buffer) = 0;
+ virtual android::detail::AudioHalVersionInfo getHalVersion() const = 0;
+
// Helper function to compare effect uuid to EFFECT_UUID_NULL.
- static bool isNullUuid(const effect_uuid_t *pEffectUuid);
+ static bool isNullUuid(const effect_uuid_t* pEffectUuid);
protected:
// Subclasses can not be constructed directly by clients.
@@ -68,5 +70,3 @@
};
} // namespace android
-
-#endif // ANDROID_HARDWARE_EFFECTS_FACTORY_HAL_INTERFACE_H
diff --git a/media/libaudiohal/include/media/audiohal/FactoryHalHidl.h b/media/libaudiohal/include/media/audiohal/FactoryHal.h
similarity index 62%
rename from media/libaudiohal/include/media/audiohal/FactoryHalHidl.h
rename to media/libaudiohal/include/media/audiohal/FactoryHal.h
index 866dd3e..4776d98 100644
--- a/media/libaudiohal/include/media/audiohal/FactoryHalHidl.h
+++ b/media/libaudiohal/include/media/audiohal/FactoryHal.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -14,24 +14,19 @@
* limitations under the License.
*/
-#ifndef ANDROID_HARDWARE_FACTORY_HAL_HIDL_H
-#define ANDROID_HARDWARE_FACTORY_HAL_HIDL_H
+#pragma once
#include <string>
#include <utility>
-
#include <utils/StrongPointer.h>
+#include "AudioHalVersionInfo.h"
+
namespace android {
-// The pair of the interface's package name and the interface name,
-// e.g. <"android.hardware.audio", "IDevicesFactory">.
-// Splitting is used for easier construction of versioned names (FQNs).
-using InterfaceName = std::pair<std::string, std::string>;
-
namespace detail {
-void* createPreferredImpl(const InterfaceName& iface, const InterfaceName& siblingIface);
+void* createPreferredImpl(bool isCore);
} // namespace detail
@@ -45,17 +40,12 @@
* shared libraries the loader function considers which interface among two has the most
* recent version. Thus, a pair of interface names must be passed in.
*
- * @param iface the interface that needs to be created.
- * @param siblingIface the interface which occupies the same shared library.
+ * @param isCore Indicating if this is audio Core HAL service interface.
* @return the preferred available implementation or nullptr if none are available.
*/
+
template <class Interface>
-static sp<Interface> createPreferredImpl(
- const InterfaceName& iface, const InterfaceName& siblingIface) {
- return sp<Interface>{
- static_cast<Interface*>(detail::createPreferredImpl(iface, siblingIface))};
+static sp<Interface> createPreferredImpl(bool isCore) {
+ return sp<Interface>{static_cast<Interface*>(detail::createPreferredImpl(isCore))};
}
-
} // namespace android
-
-#endif // ANDROID_HARDWARE_FACTORY_HAL_HIDL_H
diff --git a/media/libaudiohal/tests/Android.bp b/media/libaudiohal/tests/Android.bp
new file mode 100644
index 0000000..e20f74c
--- /dev/null
+++ b/media/libaudiohal/tests/Android.bp
@@ -0,0 +1,51 @@
+// Copyright (C) 2022 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.
+
+// Headers module is in frameworks/av/Android.bp because modules are not allowed
+// to refer to headers in parent directories and the headers live in
+// frameworks/av/include.
+
+package {
+ default_applicable_licenses: ["frameworks_av_license"],
+}
+
+cc_test {
+ name: "EffectsFactoryHalInterfaceTest",
+ test_suites: ["device-tests"],
+
+ srcs: [
+ "EffectsFactoryHalInterface_test.cpp",
+ ],
+
+ defaults: [
+ "latest_android_media_audio_common_types_cpp_shared",
+ ],
+
+ cflags: [
+ "-Wall",
+ "-Wextra",
+ "-Werror",
+ "-Wthread-safety",
+ ],
+
+ shared_libs: [
+ "audioclient-types-aidl-cpp",
+ "libaudiohal",
+ "libutils",
+ ],
+
+ header_libs: [
+ "libaudiohal_headers",
+ ],
+}
diff --git a/media/libaudiohal/tests/EffectsFactoryHalInterface_test.cpp b/media/libaudiohal/tests/EffectsFactoryHalInterface_test.cpp
new file mode 100644
index 0000000..83c7809
--- /dev/null
+++ b/media/libaudiohal/tests/EffectsFactoryHalInterface_test.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#include <cstdint>
+#define LOG_TAG "EffectsFactoryHalInterfaceTest"
+
+#include <media/audiohal/EffectsFactoryHalInterface.h>
+
+#include <gtest/gtest.h>
+#include <utils/RefBase.h>
+
+namespace android {
+
+// EffectsFactoryHalInterface
+TEST(libAudioHalTest, createEffectsFactoryHalInterface) {
+ ASSERT_NE(nullptr, EffectsFactoryHalInterface::create());
+}
+
+TEST(libAudioHalTest, queryNumberEffects) {
+ auto factory = EffectsFactoryHalInterface::create();
+ ASSERT_NE(nullptr, factory);
+
+ uint32_t numEffects = 0;
+ EXPECT_EQ(OK, factory->queryNumberEffects(&numEffects));
+ EXPECT_NE(0ul, numEffects);
+}
+
+TEST(libAudioHalTest, getDescriptorByNumber) {
+ auto factory = EffectsFactoryHalInterface::create();
+ ASSERT_NE(nullptr, factory);
+
+ uint32_t numEffects = 0;
+ EXPECT_EQ(OK, factory->queryNumberEffects(&numEffects));
+ EXPECT_NE(0ul, numEffects);
+
+ effect_descriptor_t desc;
+ for (uint32_t i = 0; i < numEffects; i++) {
+ EXPECT_EQ(OK, factory->getDescriptor(i, &desc));
+ }
+}
+
+TEST(libAudioHalTest, createEffect) {
+ auto factory = EffectsFactoryHalInterface::create();
+ ASSERT_NE(nullptr, factory);
+
+ uint32_t numEffects = 0;
+ EXPECT_EQ(OK, factory->queryNumberEffects(&numEffects));
+ EXPECT_NE(0ul, numEffects);
+
+ effect_descriptor_t desc;
+ for (uint32_t i = 0; i < numEffects; i++) {
+ sp<EffectHalInterface> interface;
+ EXPECT_EQ(OK, factory->getDescriptor(i, &desc));
+ EXPECT_EQ(OK, factory->createEffect(&desc.uuid, 1 /* sessionId */, 1 /* ioId */,
+ 1 /* deviceId */, &interface));
+ }
+}
+
+TEST(libAudioHalTest, getHalVersion) {
+ auto factory = EffectsFactoryHalInterface::create();
+ ASSERT_NE(nullptr, factory);
+
+ auto version = factory->getHalVersion();
+ EXPECT_NE(0, version.getMajorVersion());
+}
+
+// TODO: b/263986405 Add multi-thread testing
+
+} // namespace android
diff --git a/media/libaudioprocessing/tests/test-resampler.cpp b/media/libaudioprocessing/tests/test-resampler.cpp
index f178bde..2166a83 100644
--- a/media/libaudioprocessing/tests/test-resampler.cpp
+++ b/media/libaudioprocessing/tests/test-resampler.cpp
@@ -18,6 +18,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
+#include <memory>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
@@ -474,7 +475,7 @@
// mono takes left channel only (out of stereo output pair)
// stereo and multichannel preserve all channels.
int32_t* out = (int32_t*) output_vaddr;
- int16_t* convert = (int16_t*) malloc(output_frames * channels * sizeof(int16_t));
+ std::unique_ptr<int16_t[]> convert(new int16_t[output_frames * channels]);
const int volumeShift = 12; // shift requirement for Q4.27 to Q.15
// round to half towards zero and saturate at int16 (non-dithered)
@@ -509,7 +510,7 @@
perror(file_out);
return EXIT_FAILURE;
}
- (void) sf_writef_short(sf, convert, output_frames);
+ (void) sf_writef_short(sf, convert.get(), output_frames);
sf_close(sf);
return EXIT_SUCCESS;
diff --git a/media/libeffects/downmix/Android.bp b/media/libeffects/downmix/Android.bp
index abe622d..742626c 100644
--- a/media/libeffects/downmix/Android.bp
+++ b/media/libeffects/downmix/Android.bp
@@ -47,3 +47,29 @@
"libhardware_headers",
],
}
+
+cc_library_shared {
+ name: "libdownmixaidl",
+ srcs: [
+ "aidl/EffectDownmix.cpp",
+ "aidl/DownmixContext.cpp",
+ ":effectCommonFile",
+ ],
+ defaults: [
+ "aidlaudioservice_defaults",
+ "latest_android_hardware_audio_effect_ndk_shared",
+ "latest_android_media_audio_common_types_ndk_shared",
+ ],
+ header_libs: [
+ "libaudioeffects",
+ "libhardware_headers"
+ ],
+ shared_libs: [
+ "libaudioutils",
+ "libcutils",
+ "liblog",
+ ],
+ visibility: [
+ "//hardware/interfaces/audio/aidl/default",
+ ],
+}
diff --git a/media/libeffects/downmix/aidl/DownmixContext.cpp b/media/libeffects/downmix/aidl/DownmixContext.cpp
new file mode 100644
index 0000000..43bfeed
--- /dev/null
+++ b/media/libeffects/downmix/aidl/DownmixContext.cpp
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2022 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 "AHAL_DownmixContext"
+
+#include <android-base/logging.h>
+
+#include "DownmixContext.h"
+
+using aidl::android::hardware::audio::effect::IEffect;
+using ::aidl::android::media::audio::common::AudioChannelLayout;
+using ::android::hardware::audio::common::getChannelCount;
+
+namespace aidl::android::hardware::audio::effect {
+
+DownmixContext::DownmixContext(int statusDepth, const Parameter::Common& common)
+ : EffectContext(statusDepth, common) {
+ LOG(DEBUG) << __func__;
+ mState = DOWNMIX_STATE_UNINITIALIZED;
+ init_params(common);
+}
+
+DownmixContext::~DownmixContext() {
+ LOG(DEBUG) << __func__;
+ mState = DOWNMIX_STATE_UNINITIALIZED;
+}
+
+RetCode DownmixContext::enable() {
+ LOG(DEBUG) << __func__;
+ if (mState != DOWNMIX_STATE_INITIALIZED) {
+ return RetCode::ERROR_EFFECT_LIB_ERROR;
+ }
+ mState = DOWNMIX_STATE_ACTIVE;
+ return RetCode::SUCCESS;
+}
+
+RetCode DownmixContext::disable() {
+ LOG(DEBUG) << __func__;
+ if (mState != DOWNMIX_STATE_ACTIVE) {
+ return RetCode::ERROR_EFFECT_LIB_ERROR;
+ }
+ mState = DOWNMIX_STATE_INITIALIZED;
+ return RetCode::SUCCESS;
+}
+
+void DownmixContext::reset() {
+ LOG(DEBUG) << __func__;
+ disable();
+ resetBuffer();
+}
+
+IEffect::Status DownmixContext::lvmProcess(float* in, float* out, int samples) {
+ LOG(DEBUG) << __func__ << " in " << in << " out " << out << " sample " << samples;
+ IEffect::Status status = {EX_ILLEGAL_ARGUMENT, 0, 0};
+
+ if (in == nullptr || out == nullptr || getInputFrameSize() != getOutputFrameSize() ||
+ getInputFrameSize() == 0) {
+ return status;
+ }
+
+ status = {EX_ILLEGAL_STATE, 0, 0};
+ if (mState == DOWNMIX_STATE_UNINITIALIZED) {
+ LOG(ERROR) << __func__ << "Trying to use an uninitialized downmixer";
+ return status;
+ } else if (mState == DOWNMIX_STATE_INITIALIZED) {
+ LOG(ERROR) << __func__ << "Trying to use a non-configured downmixer";
+ return status;
+ }
+
+ LOG(DEBUG) << __func__ << " start processing";
+ bool accumulate = false;
+ int frames = samples * sizeof(float) / getInputFrameSize();
+ if (mType == Downmix::Type::STRIP) {
+ int inputChannelCount = getChannelCount(mChMask);
+ while (frames) {
+ if (accumulate) {
+ out[0] = std::clamp(out[0] + in[0], -1.f, 1.f);
+ out[1] = std::clamp(out[1] + in[1], -1.f, 1.f);
+ } else {
+ out[0] = in[0];
+ out[1] = in[1];
+ }
+ in += inputChannelCount;
+ out += 2;
+ frames--;
+ }
+ } else {
+ int chMask = mChMask.get<AudioChannelLayout::layoutMask>();
+ if (!mChannelMix.process(in, out, frames, accumulate, (audio_channel_mask_t)chMask)) {
+ LOG(ERROR) << "Multichannel configuration " << mChMask.toString()
+ << " is not supported";
+ return status;
+ }
+ }
+ LOG(DEBUG) << __func__ << " done processing";
+ return {STATUS_OK, samples, samples};
+}
+
+void DownmixContext::init_params(const Parameter::Common& common) {
+ // when configuring the effect, do not allow a blank or unsupported channel mask
+ AudioChannelLayout channelMask = common.input.base.channelMask;
+ if (isChannelMaskValid(channelMask)) {
+ LOG(ERROR) << "Downmix_Configure error: input channel mask " << channelMask.toString()
+ << " not supported";
+ } else {
+ mType = Downmix::Type::FOLD;
+ mChMask = channelMask;
+ mState = DOWNMIX_STATE_INITIALIZED;
+ }
+}
+
+bool DownmixContext::isChannelMaskValid(AudioChannelLayout channelMask) {
+ if (channelMask.getTag() == AudioChannelLayout::layoutMask) return false;
+ int chMask = channelMask.get<AudioChannelLayout::layoutMask>();
+ // check against unsupported channels (up to FCC_26)
+ constexpr uint32_t MAXIMUM_CHANNEL_MASK = AudioChannelLayout::LAYOUT_22POINT2 |
+ AudioChannelLayout::CHANNEL_FRONT_WIDE_LEFT |
+ AudioChannelLayout::CHANNEL_FRONT_WIDE_RIGHT;
+ if (chMask & ~MAXIMUM_CHANNEL_MASK) {
+ LOG(ERROR) << "Unsupported channels in " << (chMask & ~MAXIMUM_CHANNEL_MASK);
+ return false;
+ }
+ return true;
+}
+
+} // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/downmix/aidl/DownmixContext.h b/media/libeffects/downmix/aidl/DownmixContext.h
new file mode 100644
index 0000000..9a9f2da
--- /dev/null
+++ b/media/libeffects/downmix/aidl/DownmixContext.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2022 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 "effect-impl/EffectContext.h"
+
+#include <audio_utils/ChannelMix.h>
+
+namespace aidl::android::hardware::audio::effect {
+
+enum DownmixState {
+ DOWNMIX_STATE_UNINITIALIZED,
+ DOWNMIX_STATE_INITIALIZED,
+ DOWNMIX_STATE_ACTIVE,
+};
+
+class DownmixContext final : public EffectContext {
+ public:
+ DownmixContext(int statusDepth, const Parameter::Common& common);
+ ~DownmixContext();
+ RetCode enable();
+ RetCode disable();
+ void reset();
+
+ RetCode setDmType(Downmix::Type type) {
+ mType = type;
+ return RetCode::SUCCESS;
+ }
+ Downmix::Type getDmType() const { return mType; }
+
+ RetCode setOutputDevice(
+ const std::vector<::aidl::android::media::audio::common::AudioDeviceDescription>&
+ device) override {
+ // FIXME change type if playing on headset vs speaker
+ mOutputDevice = device;
+ return RetCode::SUCCESS;
+ }
+
+ IEffect::Status lvmProcess(float* in, float* out, int samples);
+
+ private:
+ DownmixState mState;
+ Downmix::Type mType;
+ ::aidl::android::media::audio::common::AudioChannelLayout mChMask;
+ ::android::audio_utils::channels::ChannelMix mChannelMix;
+
+ // Common Params
+ void init_params(const Parameter::Common& common);
+ bool isChannelMaskValid(::aidl::android::media::audio::common::AudioChannelLayout channelMask);
+};
+
+} // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/downmix/aidl/EffectDownmix.cpp b/media/libeffects/downmix/aidl/EffectDownmix.cpp
new file mode 100644
index 0000000..17d0736
--- /dev/null
+++ b/media/libeffects/downmix/aidl/EffectDownmix.cpp
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2022 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 "AHAL_DownmixImpl"
+
+#include <android-base/logging.h>
+
+#include "EffectDownmix.h"
+
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::DownmixImpl;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::kDownmixImplUUID;
+using aidl::android::hardware::audio::effect::kDownmixTypeUUID;
+using aidl::android::media::audio::common::AudioUuid;
+
+extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
+ std::shared_ptr<IEffect>* instanceSpp) {
+ if (!in_impl_uuid || *in_impl_uuid != kDownmixImplUUID) {
+ LOG(ERROR) << __func__ << "uuid not supported";
+ return EX_ILLEGAL_ARGUMENT;
+ }
+ if (instanceSpp) {
+ *instanceSpp = ndk::SharedRefBase::make<DownmixImpl>();
+ LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
+ return EX_NONE;
+ } else {
+ LOG(ERROR) << __func__ << " invalid input parameter!";
+ return EX_ILLEGAL_ARGUMENT;
+ }
+}
+
+extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
+ if (!in_impl_uuid || *in_impl_uuid != kDownmixImplUUID) {
+ LOG(ERROR) << __func__ << "uuid not supported";
+ return EX_ILLEGAL_ARGUMENT;
+ }
+ *_aidl_return = DownmixImpl::kDescriptor;
+ return EX_NONE;
+}
+
+namespace aidl::android::hardware::audio::effect {
+
+const std::string DownmixImpl::kEffectName = "Multichannel Downmix To Stereo";
+const Descriptor DownmixImpl::kDescriptor = {
+ .common = {
+ .id = {.type = kDownmixTypeUUID, .uuid = kDownmixImplUUID, .proxy = std::nullopt},
+ .flags = {.type = Flags::Type::INSERT, .insert = Flags::Insert::FIRST},
+ .name = DownmixImpl::kEffectName,
+ .implementor = "The Android Open Source Project"}};
+
+ndk::ScopedAStatus DownmixImpl::getDescriptor(Descriptor* _aidl_return) {
+ RETURN_IF(!_aidl_return, EX_ILLEGAL_ARGUMENT, "Parameter:nullptr");
+ LOG(DEBUG) << __func__ << kDescriptor.toString();
+ *_aidl_return = kDescriptor;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus DownmixImpl::setParameterCommon(const Parameter& param) {
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+ auto tag = param.getTag();
+ switch (tag) {
+ case Parameter::common:
+ RETURN_IF(mContext->setCommon(param.get<Parameter::common>()) != RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setCommFailed");
+ break;
+ case Parameter::deviceDescription:
+ RETURN_IF(mContext->setOutputDevice(param.get<Parameter::deviceDescription>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setDeviceFailed");
+ break;
+ case Parameter::mode:
+ RETURN_IF(mContext->setAudioMode(param.get<Parameter::mode>()) != RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setModeFailed");
+ break;
+ case Parameter::source:
+ RETURN_IF(mContext->setAudioSource(param.get<Parameter::source>()) != RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setSourceFailed");
+ break;
+ case Parameter::volumeStereo:
+ RETURN_IF(mContext->setVolumeStereo(param.get<Parameter::volumeStereo>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setVolumeStereoFailed");
+ break;
+ default: {
+ LOG(ERROR) << __func__ << " unsupportedParameterTag " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "commonParamNotSupported");
+ }
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus DownmixImpl::commandImpl(CommandId command) {
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+ switch (command) {
+ case CommandId::START:
+ mContext->enable();
+ break;
+ case CommandId::STOP:
+ mContext->disable();
+ break;
+ case CommandId::RESET:
+ mContext->reset();
+ break;
+ default:
+ LOG(ERROR) << __func__ << " commandId " << toString(command) << " not supported";
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "commandIdNotSupported");
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus DownmixImpl::setParameterSpecific(const Parameter::Specific& specific) {
+ RETURN_IF(Parameter::Specific::downmix != specific.getTag(), EX_ILLEGAL_ARGUMENT,
+ "EffectNotSupported");
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+ auto& dmParam = specific.get<Parameter::Specific::downmix>();
+ auto tag = dmParam.getTag();
+
+ switch (tag) {
+ case Downmix::type: {
+ RETURN_IF(mContext->setDmType(dmParam.get<Downmix::type>()) != RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setTypeFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ default: {
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "DownmixTagNotSupported");
+ }
+ }
+}
+
+ndk::ScopedAStatus DownmixImpl::getParameterSpecific(const Parameter::Id& id,
+ Parameter::Specific* specific) {
+ RETURN_IF(!specific, EX_NULL_POINTER, "nullPtr");
+ auto tag = id.getTag();
+ RETURN_IF(Parameter::Id::downmixTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
+ auto dmId = id.get<Parameter::Id::downmixTag>();
+ auto dmIdTag = dmId.getTag();
+ switch (dmIdTag) {
+ case Downmix::Id::commonTag:
+ return getParameterDownmix(dmId.get<Downmix::Id::commonTag>(), specific);
+ default:
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(dmIdTag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "DownmixTagNotSupported");
+ }
+}
+
+ndk::ScopedAStatus DownmixImpl::getParameterDownmix(const Downmix::Tag& tag,
+ Parameter::Specific* specific) {
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+ Downmix dmParam;
+ switch (tag) {
+ case Downmix::type: {
+ dmParam.set<Downmix::type>(mContext->getDmType());
+ break;
+ }
+ default: {
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "DownmixTagNotSupported");
+ }
+ }
+
+ specific->set<Parameter::Specific::downmix>(dmParam);
+ return ndk::ScopedAStatus::ok();
+}
+
+std::shared_ptr<EffectContext> DownmixImpl::createContext(const Parameter::Common& common) {
+ if (mContext) {
+ LOG(DEBUG) << __func__ << " context already exist";
+ return mContext;
+ }
+
+ mContext = std::make_shared<DownmixContext>(1 /* statusFmqDepth */, common);
+ return mContext;
+}
+
+RetCode DownmixImpl::releaseContext() {
+ if (mContext) {
+ mContext.reset();
+ }
+ return RetCode::SUCCESS;
+}
+
+// Processing method running in EffectWorker thread.
+IEffect::Status DownmixImpl::effectProcessImpl(float* in, float* out, int sampleToProcess) {
+ if (!mContext) {
+ LOG(ERROR) << __func__ << " nullContext";
+ return {EX_NULL_POINTER, 0, 0};
+ }
+ return mContext->lvmProcess(in, out, sampleToProcess);
+}
+
+} // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/downmix/aidl/EffectDownmix.h b/media/libeffects/downmix/aidl/EffectDownmix.h
new file mode 100644
index 0000000..d590133
--- /dev/null
+++ b/media/libeffects/downmix/aidl/EffectDownmix.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2022 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 <aidl/android/hardware/audio/effect/BnEffect.h>
+#include <audio_effects/effect_downmix.h>
+
+#include "DownmixContext.h"
+#include "effect-impl/EffectImpl.h"
+#include "effect-impl/EffectUUID.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+class DownmixImpl final : public EffectImpl {
+ public:
+ static const std::string kEffectName;
+ static const Descriptor kDescriptor;
+ DownmixImpl() { LOG(DEBUG) << __func__; }
+ ~DownmixImpl() {
+ cleanUp();
+ LOG(DEBUG) << __func__;
+ }
+
+ ndk::ScopedAStatus commandImpl(CommandId command) override;
+ ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
+ ndk::ScopedAStatus setParameterCommon(const Parameter& param) override;
+ ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
+ ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
+ Parameter::Specific* specific) override;
+ IEffect::Status effectProcessImpl(float* in, float* out, int process) override;
+ std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
+ RetCode releaseContext() override;
+
+ std::shared_ptr<EffectContext> getContext() override { return mContext; }
+ std::string getEffectName() override { return kEffectName; }
+
+ private:
+ std::shared_ptr<DownmixContext> mContext;
+ ndk::ScopedAStatus getParameterDownmix(const Downmix::Tag& tag, Parameter::Specific* specific);
+};
+} // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/dynamicsproc/Android.bp b/media/libeffects/dynamicsproc/Android.bp
index 84131a4..f655c4f 100644
--- a/media/libeffects/dynamicsproc/Android.bp
+++ b/media/libeffects/dynamicsproc/Android.bp
@@ -32,34 +32,68 @@
],
}
+cc_defaults {
+ name : "dynamicsprocessingdefaults",
+ srcs: [
+ "dsp/DPBase.cpp",
+ "dsp/DPFrequency.cpp",
+ ],
+
+ shared_libs: [
+ "libaudioutils",
+ "libbase",
+ "liblog",
+ "libutils",
+ ],
+ header_libs: [
+ "libaudioeffects",
+ "libeigen",
+ ],
+ cflags: [
+ "-Wthread-safety",
+ "-Wall",
+ "-Werror",
+ ],
+}
+
cc_library_shared {
name: "libdynproc",
vendor: true,
+ defaults: [
+ "dynamicsprocessingdefaults",
+ ],
+
srcs: [
"EffectDynamicsProcessing.cpp",
- "dsp/DPBase.cpp",
- "dsp/DPFrequency.cpp",
],
cflags: [
"-O2",
"-fvisibility=hidden",
-
- "-Wall",
- "-Werror",
- ],
-
- shared_libs: [
- "libcutils",
- "liblog",
],
relative_install_path: "soundfx",
+}
- header_libs: [
- "libaudioeffects",
- "libeigen",
+cc_library_shared {
+ name: "libdynamicsprocessingaidl",
+
+ srcs: [
+ "aidl/DynamicsProcessing.cpp",
+ "aidl/DynamicsProcessingContext.cpp",
+ ":effectCommonFile",
+ ],
+
+ defaults: [
+ "aidlaudioservice_defaults",
+ "latest_android_hardware_audio_effect_ndk_shared",
+ "latest_android_media_audio_common_types_ndk_shared",
+ "dynamicsprocessingdefaults",
+ ],
+
+ visibility: [
+ "//hardware/interfaces/audio/aidl/default",
],
}
diff --git a/media/libeffects/dynamicsproc/aidl/DynamicsProcessing.cpp b/media/libeffects/dynamicsproc/aidl/DynamicsProcessing.cpp
new file mode 100644
index 0000000..203a27b
--- /dev/null
+++ b/media/libeffects/dynamicsproc/aidl/DynamicsProcessing.cpp
@@ -0,0 +1,313 @@
+/*
+ * Copyright (C) 2023 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 "AHAL_DynamicsProcessingLibEffects"
+
+#include <android-base/logging.h>
+
+#include "DynamicsProcessing.h"
+
+#include <dsp/DPBase.h>
+#include <dsp/DPFrequency.h>
+
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::DynamicsProcessingImpl;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::kDynamicsProcessingImplUUID;
+using aidl::android::hardware::audio::effect::State;
+using aidl::android::media::audio::common::AudioUuid;
+using aidl::android::media::audio::common::PcmType;
+
+extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
+ std::shared_ptr<IEffect>* instanceSpp) {
+ if (!in_impl_uuid || *in_impl_uuid != kDynamicsProcessingImplUUID) {
+ LOG(ERROR) << __func__ << "uuid not supported";
+ return EX_ILLEGAL_ARGUMENT;
+ }
+ if (instanceSpp) {
+ *instanceSpp = ndk::SharedRefBase::make<DynamicsProcessingImpl>();
+ LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
+ return EX_NONE;
+ } else {
+ LOG(ERROR) << __func__ << " invalid input parameter!";
+ return EX_ILLEGAL_ARGUMENT;
+ }
+}
+
+extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
+ if (!in_impl_uuid || *in_impl_uuid != kDynamicsProcessingImplUUID) {
+ LOG(ERROR) << __func__ << "uuid not supported";
+ return EX_ILLEGAL_ARGUMENT;
+ }
+ *_aidl_return = DynamicsProcessingImpl::kDescriptor;
+ return EX_NONE;
+}
+
+namespace aidl::android::hardware::audio::effect {
+
+const std::string DynamicsProcessingImpl::kEffectName = "DynamicsProcessing";
+const DynamicsProcessing::Capability DynamicsProcessingImpl::kCapability = {.minCutOffFreq = 220,
+ .maxCutOffFreq = 20000};
+const Descriptor DynamicsProcessingImpl::kDescriptor = {
+ .common = {.id = {.type = kDynamicsProcessingTypeUUID,
+ .uuid = kDynamicsProcessingImplUUID,
+ .proxy = std::nullopt},
+ .flags = {.type = Flags::Type::INSERT,
+ .insert = Flags::Insert::LAST,
+ .volume = Flags::Volume::CTRL},
+ .name = DynamicsProcessingImpl::kEffectName,
+ .implementor = "The Android Open Source Project"},
+ .capability = Capability::make<Capability::dynamicsProcessing>(
+ DynamicsProcessingImpl::kCapability)};
+
+ndk::ScopedAStatus DynamicsProcessingImpl::open(const Parameter::Common& common,
+ const std::optional<Parameter::Specific>& specific,
+ OpenEffectReturn* ret) {
+ LOG(DEBUG) << __func__;
+ // effect only support 32bits float
+ RETURN_IF(common.input.base.format.pcm != common.output.base.format.pcm ||
+ common.input.base.format.pcm != PcmType::FLOAT_32_BIT,
+ EX_ILLEGAL_ARGUMENT, "dataMustBe32BitsFloat");
+ RETURN_OK_IF(mState != State::INIT);
+ auto context = createContext(common);
+ RETURN_IF(!context, EX_NULL_POINTER, "createContextFailed");
+
+ RETURN_IF_ASTATUS_NOT_OK(setParameterCommon(common), "setCommParamErr");
+ if (specific.has_value()) {
+ RETURN_IF_ASTATUS_NOT_OK(setParameterSpecific(specific.value()), "setSpecParamErr");
+ } else {
+ Parameter::Specific defaultSpecific =
+ Parameter::Specific::make<Parameter::Specific::dynamicsProcessing>(
+ DynamicsProcessing::make<DynamicsProcessing::engineArchitecture>(
+ mContext->getEngineArchitecture()));
+ RETURN_IF_ASTATUS_NOT_OK(setParameterSpecific(defaultSpecific), "setDefaultEngineErr");
+ }
+
+ mState = State::IDLE;
+ context->dupeFmq(ret);
+ RETURN_IF(createThread(context, getEffectName()) != RetCode::SUCCESS, EX_UNSUPPORTED_OPERATION,
+ "FailedToCreateWorker");
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus DynamicsProcessingImpl::getDescriptor(Descriptor* _aidl_return) {
+ RETURN_IF(!_aidl_return, EX_ILLEGAL_ARGUMENT, "Parameter:nullptr");
+ LOG(DEBUG) << __func__ << kDescriptor.toString();
+ *_aidl_return = kDescriptor;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus DynamicsProcessingImpl::commandImpl(CommandId command) {
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+ switch (command) {
+ case CommandId::START:
+ mContext->enable();
+ return ndk::ScopedAStatus::ok();
+ case CommandId::STOP:
+ mContext->disable();
+ return ndk::ScopedAStatus::ok();
+ case CommandId::RESET:
+ mContext->disable();
+ mContext->resetBuffer();
+ return ndk::ScopedAStatus::ok();
+ default:
+ // Need this default handling for vendor extendable CommandId::VENDOR_COMMAND_*
+ LOG(ERROR) << __func__ << " commandId " << toString(command) << " not supported";
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "commandIdNotSupported");
+ }
+}
+
+ndk::ScopedAStatus DynamicsProcessingImpl::setParameterSpecific(
+ const Parameter::Specific& specific) {
+ RETURN_IF(Parameter::Specific::dynamicsProcessing != specific.getTag(), EX_ILLEGAL_ARGUMENT,
+ "EffectNotSupported");
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+ auto& param = specific.get<Parameter::Specific::dynamicsProcessing>();
+ auto tag = param.getTag();
+
+ switch (tag) {
+ case DynamicsProcessing::engineArchitecture: {
+ RETURN_IF(mContext->setEngineArchitecture(
+ param.get<DynamicsProcessing::engineArchitecture>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setEngineArchitectureFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ case DynamicsProcessing::preEq: {
+ RETURN_IF(
+ mContext->setPreEq(param.get<DynamicsProcessing::preEq>()) != RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setPreEqFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ case DynamicsProcessing::postEq: {
+ RETURN_IF(mContext->setPostEq(param.get<DynamicsProcessing::postEq>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setPostEqFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ case DynamicsProcessing::preEqBand: {
+ RETURN_IF(mContext->setPreEqBand(param.get<DynamicsProcessing::preEqBand>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setPreEqBandFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ case DynamicsProcessing::postEqBand: {
+ RETURN_IF(mContext->setPostEqBand(param.get<DynamicsProcessing::postEqBand>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setPostEqBandFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ case DynamicsProcessing::mbc: {
+ RETURN_IF(mContext->setMbc(param.get<DynamicsProcessing::mbc>()) != RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setMbcFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ case DynamicsProcessing::mbcBand: {
+ RETURN_IF(mContext->setMbcBand(param.get<DynamicsProcessing::mbcBand>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setMbcBandFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ case DynamicsProcessing::limiter: {
+ RETURN_IF(mContext->setLimiter(param.get<DynamicsProcessing::limiter>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setLimiterFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ case DynamicsProcessing::inputGain: {
+ RETURN_IF(mContext->setInputGain(param.get<DynamicsProcessing::inputGain>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setInputGainFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ case DynamicsProcessing::vendorExtension: {
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+ EX_ILLEGAL_ARGUMENT, "DPVendorExtensionTagNotSupported");
+ }
+ }
+}
+
+ndk::ScopedAStatus DynamicsProcessingImpl::getParameterSpecific(const Parameter::Id& id,
+ Parameter::Specific* specific) {
+ RETURN_IF(!specific, EX_NULL_POINTER, "nullPtr");
+ auto tag = id.getTag();
+ RETURN_IF(Parameter::Id::dynamicsProcessingTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
+ auto dpId = id.get<Parameter::Id::dynamicsProcessingTag>();
+ auto dpIdTag = dpId.getTag();
+ switch (dpIdTag) {
+ case DynamicsProcessing::Id::commonTag:
+ return getParameterDynamicsProcessing(dpId.get<DynamicsProcessing::Id::commonTag>(),
+ specific);
+ case DynamicsProcessing::Id::vendorExtensionTag:
+ LOG(ERROR) << __func__ << " unsupported ID: " << toString(dpIdTag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+ EX_ILLEGAL_ARGUMENT, "DPVendorExtensionIdNotSupported");
+ }
+}
+
+ndk::ScopedAStatus DynamicsProcessingImpl::getParameterDynamicsProcessing(
+ const DynamicsProcessing::Tag& tag, Parameter::Specific* specific) {
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+ switch (tag) {
+ case DynamicsProcessing::engineArchitecture: {
+ specific->set<Parameter::Specific::dynamicsProcessing>(
+ DynamicsProcessing::make<DynamicsProcessing::engineArchitecture>(
+ mContext->getEngineArchitecture()));
+ return ndk::ScopedAStatus::ok();
+ }
+ case DynamicsProcessing::preEq: {
+ specific->set<Parameter::Specific::dynamicsProcessing>(
+ DynamicsProcessing::make<DynamicsProcessing::preEq>(mContext->getPreEq()));
+ return ndk::ScopedAStatus::ok();
+ }
+ case DynamicsProcessing::postEq: {
+ specific->set<Parameter::Specific::dynamicsProcessing>(
+ DynamicsProcessing::make<DynamicsProcessing::postEq>(mContext->getPostEq()));
+ return ndk::ScopedAStatus::ok();
+ }
+ case DynamicsProcessing::preEqBand: {
+ specific->set<Parameter::Specific::dynamicsProcessing>(
+ DynamicsProcessing::make<DynamicsProcessing::preEqBand>(
+ mContext->getPreEqBand()));
+ return ndk::ScopedAStatus::ok();
+ }
+ case DynamicsProcessing::postEqBand: {
+ specific->set<Parameter::Specific::dynamicsProcessing>(
+ DynamicsProcessing::make<DynamicsProcessing::postEqBand>(
+ mContext->getPostEqBand()));
+ return ndk::ScopedAStatus::ok();
+ }
+ case DynamicsProcessing::mbc: {
+ specific->set<Parameter::Specific::dynamicsProcessing>(
+ DynamicsProcessing::make<DynamicsProcessing::mbc>(mContext->getMbc()));
+ return ndk::ScopedAStatus::ok();
+ }
+ case DynamicsProcessing::mbcBand: {
+ specific->set<Parameter::Specific::dynamicsProcessing>(
+ DynamicsProcessing::make<DynamicsProcessing::mbcBand>(mContext->getMbcBand()));
+ return ndk::ScopedAStatus::ok();
+ }
+ case DynamicsProcessing::limiter: {
+ specific->set<Parameter::Specific::dynamicsProcessing>(
+ DynamicsProcessing::make<DynamicsProcessing::limiter>(mContext->getLimiter()));
+ return ndk::ScopedAStatus::ok();
+ }
+ case DynamicsProcessing::inputGain: {
+ specific->set<Parameter::Specific::dynamicsProcessing>(
+ DynamicsProcessing::make<DynamicsProcessing::inputGain>(
+ mContext->getInputGain()));
+ return ndk::ScopedAStatus::ok();
+ }
+ case DynamicsProcessing::vendorExtension: {
+ LOG(ERROR) << __func__ << " wrong vendor tag in CommonTag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+ EX_ILLEGAL_ARGUMENT, "DPVendorExtensionTagInWrongId");
+ }
+ }
+}
+
+std::shared_ptr<EffectContext> DynamicsProcessingImpl::createContext(
+ const Parameter::Common& common) {
+ if (mContext) {
+ LOG(DEBUG) << __func__ << " context already exist";
+ return mContext;
+ }
+
+ mContext = std::make_shared<DynamicsProcessingContext>(1 /* statusFmqDepth */, common);
+ return mContext;
+}
+
+RetCode DynamicsProcessingImpl::releaseContext() {
+ if (mContext) {
+ mContext->disable();
+ mContext->resetBuffer();
+ mContext.reset();
+ }
+ return RetCode::SUCCESS;
+}
+
+// Processing method running in EffectWorker thread.
+IEffect::Status DynamicsProcessingImpl::effectProcessImpl(float* in, float* out, int samples) {
+ IEffect::Status status = {EX_NULL_POINTER, 0, 0};
+ RETURN_VALUE_IF(!mContext, status, "nullContext");
+ return mContext->lvmProcess(in, out, samples);
+}
+
+} // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/dynamicsproc/aidl/DynamicsProcessing.h b/media/libeffects/dynamicsproc/aidl/DynamicsProcessing.h
new file mode 100644
index 0000000..824ebea
--- /dev/null
+++ b/media/libeffects/dynamicsproc/aidl/DynamicsProcessing.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2023 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 <aidl/android/hardware/audio/effect/BnEffect.h>
+
+#include "effect-impl/EffectImpl.h"
+#include "effect-impl/EffectUUID.h"
+#include "DynamicsProcessingContext.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+class DynamicsProcessingImpl final : public EffectImpl {
+ public:
+ static const std::string kEffectName;
+ static const Descriptor kDescriptor;
+ static const DynamicsProcessing::Capability kCapability;
+
+ DynamicsProcessingImpl() { LOG(DEBUG) << __func__; }
+ ~DynamicsProcessingImpl() {
+ cleanUp();
+ LOG(DEBUG) << __func__;
+ }
+
+ ndk::ScopedAStatus open(const Parameter::Common& common,
+ const std::optional<Parameter::Specific>& specific,
+ OpenEffectReturn* ret) override;
+ ndk::ScopedAStatus commandImpl(CommandId command) override;
+ ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
+ ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
+ ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
+ Parameter::Specific* specific) override;
+ IEffect::Status effectProcessImpl(float* in, float* out, int process) override;
+ std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
+ RetCode releaseContext() override;
+
+ std::shared_ptr<EffectContext> getContext() override { return mContext; }
+ std::string getEffectName() override { return kEffectName; }
+
+ private:
+ std::shared_ptr<DynamicsProcessingContext> mContext;
+ ndk::ScopedAStatus getParameterDynamicsProcessing(const DynamicsProcessing::Tag& tag,
+ Parameter::Specific* specific);
+};
+
+} // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/dynamicsproc/aidl/DynamicsProcessingContext.cpp b/media/libeffects/dynamicsproc/aidl/DynamicsProcessingContext.cpp
new file mode 100644
index 0000000..57a2be9
--- /dev/null
+++ b/media/libeffects/dynamicsproc/aidl/DynamicsProcessingContext.cpp
@@ -0,0 +1,580 @@
+/*
+ * Copyright (C) 2023 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 "AHAL_DPLibEffectsContext"
+
+#include "DynamicsProcessing.h"
+#include "DynamicsProcessingContext.h"
+
+#include <functional>
+#include <sys/param.h>
+#include <unordered_set>
+
+namespace aidl::android::hardware::audio::effect {
+
+DynamicsProcessingContext::DynamicsProcessingContext(int statusDepth,
+ const Parameter::Common& common)
+ : EffectContext(statusDepth, common) {
+ LOG(DEBUG) << __func__;
+ init();
+}
+
+DynamicsProcessingContext::~DynamicsProcessingContext() {
+ LOG(DEBUG) << __func__;
+}
+
+RetCode DynamicsProcessingContext::enable() {
+ std::lock_guard lg(mMutex);
+ if (mState != DYNAMICS_PROCESSING_STATE_INITIALIZED) {
+ return RetCode::ERROR_EFFECT_LIB_ERROR;
+ }
+ mState = DYNAMICS_PROCESSING_STATE_ACTIVE;
+ return RetCode::SUCCESS;
+}
+
+RetCode DynamicsProcessingContext::disable() {
+ std::lock_guard lg(mMutex);
+ if (mState != DYNAMICS_PROCESSING_STATE_ACTIVE) {
+ return RetCode::ERROR_EFFECT_LIB_ERROR;
+ }
+ mState = DYNAMICS_PROCESSING_STATE_INITIALIZED;
+ return RetCode::SUCCESS;
+}
+
+void DynamicsProcessingContext::reset() {
+ std::lock_guard lg(mMutex);
+ if (mDpFreq != nullptr) {
+ mDpFreq.reset();
+ }
+}
+
+RetCode DynamicsProcessingContext::setCommon(const Parameter::Common& common) {
+ mCommon = common;
+ init();
+ return RetCode::SUCCESS;
+}
+
+void DynamicsProcessingContext::dpSetFreqDomainVariant_l(
+ const DynamicsProcessing::EngineArchitecture& engine) {
+ mDpFreq.reset(new dp_fx::DPFrequency());
+ mDpFreq->init(mChannelCount, engine.preEqStage.inUse, engine.preEqStage.bandCount,
+ engine.mbcStage.inUse, engine.mbcStage.bandCount, engine.postEqStage.inUse,
+ engine.postEqStage.bandCount, engine.limiterInUse);
+
+ int32_t sampleRate = mCommon.input.base.sampleRate;
+ int32_t minBlockSize = (int32_t)dp_fx::DPFrequency::getMinBockSize();
+ int32_t block = engine.preferredProcessingDurationMs * sampleRate / 1000.0f;
+ LOG(INFO) << __func__ << " sampleRate " << sampleRate << " block length "
+ << engine.preferredProcessingDurationMs << " ms (" << block << "samples)";
+ if (block < minBlockSize) {
+ block = minBlockSize;
+ } else if (!powerof2(block)) {
+ //find next highest power of 2.
+ block = 1 << (32 - __builtin_clz(block));
+ }
+ mDpFreq->configure(block, block >> 1, sampleRate);
+}
+
+RetCode DynamicsProcessingContext::setEngineArchitecture(
+ const DynamicsProcessing::EngineArchitecture& engineArchitecture) {
+ RETURN_VALUE_IF(!validateEngineConfig(engineArchitecture), RetCode::ERROR_ILLEGAL_PARAMETER,
+ "illegalEngineConfig");
+
+ std::lock_guard lg(mMutex);
+ if (!mEngineInited || mEngineArchitecture != engineArchitecture) {
+ if (engineArchitecture.resolutionPreference ==
+ DynamicsProcessing::ResolutionPreference::FAVOR_FREQUENCY_RESOLUTION) {
+ dpSetFreqDomainVariant_l(engineArchitecture);
+ } else {
+ LOG(WARNING) << __func__ << toString(engineArchitecture.resolutionPreference)
+ << " not available now";
+ }
+ mEngineInited = true;
+ mEngineArchitecture = engineArchitecture;
+ }
+ LOG(INFO) << __func__ << engineArchitecture.toString();
+ return RetCode::SUCCESS;
+}
+
+RetCode DynamicsProcessingContext::setPreEq(
+ const std::vector<DynamicsProcessing::ChannelConfig>& channels) {
+ std::lock_guard lg(mMutex);
+ return setDpChannels_l<dp_fx::DPEq>(channels, mEngineArchitecture.preEqStage.inUse,
+ StageType::PREEQ);
+}
+
+RetCode DynamicsProcessingContext::setPostEq(
+ const std::vector<DynamicsProcessing::ChannelConfig>& channels) {
+ std::lock_guard lg(mMutex);
+ return setDpChannels_l<dp_fx::DPEq>(channels, mEngineArchitecture.postEqStage.inUse,
+ StageType::POSTEQ);
+}
+
+RetCode DynamicsProcessingContext::setMbc(
+ const std::vector<DynamicsProcessing::ChannelConfig>& channels) {
+ std::lock_guard lg(mMutex);
+ return setDpChannels_l<dp_fx::DPMbc>(channels, mEngineArchitecture.mbcStage.inUse,
+ StageType::MBC);
+}
+
+RetCode DynamicsProcessingContext::setPreEqBand(
+ const std::vector<DynamicsProcessing::EqBandConfig>& bands) {
+ std::lock_guard lg(mMutex);
+ RETURN_VALUE_IF(!mEngineArchitecture.postEqStage.inUse, RetCode::ERROR_ILLEGAL_PARAMETER,
+ "postEqNotInUse");
+ return setBands_l<DynamicsProcessing::EqBandConfig>(
+ bands, mEngineArchitecture.preEqStage.bandCount, StageType::PREEQ);
+}
+
+RetCode DynamicsProcessingContext::setPostEqBand(
+ const std::vector<DynamicsProcessing::EqBandConfig>& bands) {
+ std::lock_guard lg(mMutex);
+ RETURN_VALUE_IF(!mEngineArchitecture.postEqStage.inUse, RetCode::ERROR_ILLEGAL_PARAMETER,
+ "postEqNotInUse");
+ return setBands_l<DynamicsProcessing::EqBandConfig>(
+ bands, mEngineArchitecture.postEqStage.bandCount, StageType::POSTEQ);
+}
+
+RetCode DynamicsProcessingContext::setMbcBand(
+ const std::vector<DynamicsProcessing::MbcBandConfig>& bands) {
+ std::lock_guard lg(mMutex);
+ RETURN_VALUE_IF(!mEngineArchitecture.mbcStage.inUse, RetCode::ERROR_ILLEGAL_PARAMETER,
+ "mbcNotInUse");
+ return setBands_l<DynamicsProcessing::MbcBandConfig>(
+ bands, mEngineArchitecture.preEqStage.bandCount, StageType::MBC);
+}
+
+RetCode DynamicsProcessingContext::setLimiter(
+ const std::vector<DynamicsProcessing::LimiterConfig>& limiters) {
+ std::lock_guard lg(mMutex);
+ RETURN_VALUE_IF(!mEngineArchitecture.limiterInUse, RetCode::ERROR_ILLEGAL_PARAMETER,
+ "limiterNotInUse");
+ return setBands_l<DynamicsProcessing::LimiterConfig>(limiters, -1, StageType::LIMITER);
+}
+
+RetCode DynamicsProcessingContext::setInputGain(
+ const std::vector<DynamicsProcessing::InputGain>& inputGains) {
+ std::lock_guard lg(mMutex);
+ return setBands_l<DynamicsProcessing::InputGain>(inputGains, -1, StageType::INPUTGAIN);
+}
+
+DynamicsProcessing::EngineArchitecture DynamicsProcessingContext::getEngineArchitecture() {
+ std::lock_guard lg(mMutex);
+ LOG(INFO) << __func__ << mEngineArchitecture.toString();
+ return mEngineArchitecture;
+}
+
+std::vector<DynamicsProcessing::ChannelConfig> DynamicsProcessingContext::getPreEq() {
+ return getChannelConfig(StageType::PREEQ);
+}
+
+std::vector<DynamicsProcessing::ChannelConfig> DynamicsProcessingContext::getPostEq() {
+ return getChannelConfig(StageType::POSTEQ);
+}
+
+std::vector<DynamicsProcessing::EqBandConfig> DynamicsProcessingContext::getPreEqBand() {
+ return getEqBandConfigs(StageType::PREEQ);
+}
+
+std::vector<DynamicsProcessing::EqBandConfig> DynamicsProcessingContext::getPostEqBand() {
+ return getEqBandConfigs(StageType::POSTEQ);
+}
+
+std::vector<DynamicsProcessing::ChannelConfig> DynamicsProcessingContext::getMbc() {
+ return getChannelConfig(StageType::MBC);
+}
+
+std::vector<DynamicsProcessing::MbcBandConfig> DynamicsProcessingContext::getMbcBand() {
+ std::vector<DynamicsProcessing::MbcBandConfig> bands;
+
+ std::lock_guard lg(mMutex);
+ auto maxBand = mEngineArchitecture.mbcStage.bandCount;
+ for (int32_t ch = 0; ch < mChannelCount; ch++) {
+ auto mbc = getMbc_l(ch);
+ if (!mbc) {
+ continue;
+ }
+ for (int32_t bandId = 0; bandId < maxBand; bandId++) {
+ auto band = mbc->getBand(bandId);
+ if (!band) {
+ continue;
+ }
+ bands.push_back({.channel = ch,
+ .band = bandId,
+ .enable = band->isEnabled(),
+ .cutoffFrequencyHz = band->getCutoffFrequency(),
+ .attackTimeMs = band->getAttackTime(),
+ .releaseTimeMs = band->getReleaseTime(),
+ .ratio = band->getRatio(),
+ .thresholdDb = band->getThreshold(),
+ .kneeWidthDb = band->getKneeWidth(),
+ .noiseGateThresholdDb = band->getNoiseGateThreshold(),
+ .expanderRatio = band->getExpanderRatio(),
+ .preGainDb = band->getPreGain(),
+ .postGainDb = band->getPostGain()});
+ }
+ }
+ return bands;
+}
+
+std::vector<DynamicsProcessing::LimiterConfig> DynamicsProcessingContext::getLimiter() {
+ std::vector<DynamicsProcessing::LimiterConfig> ret;
+
+ std::lock_guard lg(mMutex);
+ for (int32_t ch = 0; ch < mChannelCount; ch++) {
+ auto limiter = getLimiter_l(ch);
+ if (!limiter) {
+ continue;
+ }
+ ret.push_back({.channel = ch,
+ .enable = limiter->isEnabled(),
+ .linkGroup = static_cast<int32_t>(limiter->getLinkGroup()),
+ .attackTimeMs = limiter->getAttackTime(),
+ .releaseTimeMs = limiter->getReleaseTime(),
+ .ratio = limiter->getRatio(),
+ .thresholdDb = limiter->getThreshold(),
+ .postGainDb = limiter->getPostGain()});
+ }
+ return ret;
+}
+
+std::vector<DynamicsProcessing::InputGain> DynamicsProcessingContext::getInputGain() {
+ std::vector<DynamicsProcessing::InputGain> ret;
+
+ std::lock_guard lg(mMutex);
+ for (int32_t ch = 0; ch < mChannelCount; ch++) {
+ auto channel = getChannel_l(ch);
+ if (!channel) {
+ continue;
+ }
+ ret.push_back({.channel = ch, .gainDb = channel->getInputGain()});
+ }
+ return ret;
+}
+
+IEffect::Status DynamicsProcessingContext::lvmProcess(float* in, float* out, int samples) {
+ LOG(DEBUG) << __func__ << " in " << in << " out " << out << " sample " << samples;
+
+ IEffect::Status status = {EX_NULL_POINTER, 0, 0};
+ RETURN_VALUE_IF(!in, status, "nullInput");
+ RETURN_VALUE_IF(!out, status, "nullOutput");
+ status = {EX_ILLEGAL_STATE, 0, 0};
+
+ LOG(DEBUG) << __func__ << " start processing";
+ {
+ std::lock_guard lg(mMutex);
+ RETURN_VALUE_IF(mState != DynamicsProcessingState::DYNAMICS_PROCESSING_STATE_ACTIVE, status,
+ "notInActiveState");
+ RETURN_VALUE_IF(!mDpFreq, status, "engineNotInited");
+ mDpFreq->processSamples(in, out, samples);
+ }
+ return {STATUS_OK, samples, samples};
+}
+
+void DynamicsProcessingContext::init() {
+ std::lock_guard lg(mMutex);
+ mState = DYNAMICS_PROCESSING_STATE_INITIALIZED;
+ mChannelCount =
+ ::android::hardware::audio::common::getChannelCount(mCommon.input.base.channelMask);
+}
+
+dp_fx::DPChannel* DynamicsProcessingContext::getChannel_l(int channel) {
+ RETURN_VALUE_IF(mDpFreq == nullptr, nullptr, "DPFreqNotInited");
+
+ return mDpFreq->getChannel(channel);
+}
+
+dp_fx::DPEq* DynamicsProcessingContext::getPreEq_l(int ch) {
+ auto channel = getChannel_l(ch);
+ RETURN_VALUE_IF(channel == nullptr, nullptr, "ChannelNotExist");
+
+ return channel->getPreEq();
+}
+
+dp_fx::DPEq* DynamicsProcessingContext::getPostEq_l(int ch) {
+ auto channel = getChannel_l(ch);
+ RETURN_VALUE_IF(channel == nullptr, nullptr, "ChannelNotExist");
+
+ return channel->getPostEq();
+}
+
+dp_fx::DPMbc* DynamicsProcessingContext::getMbc_l(int ch) {
+ auto channel = getChannel_l(ch);
+ RETURN_VALUE_IF(channel == nullptr, nullptr, "ChannelNotExist");
+
+ return channel->getMbc();
+}
+
+dp_fx::DPLimiter* DynamicsProcessingContext::getLimiter_l(int ch) {
+ auto channel = getChannel_l(ch);
+ RETURN_VALUE_IF(channel == nullptr, nullptr, "ChannelNotExist");
+
+ return channel->getLimiter();
+}
+
+dp_fx::DPBandStage* DynamicsProcessingContext::getStageWithType_l(
+ DynamicsProcessingContext::StageType type, int ch) {
+ switch (type) {
+ case StageType::PREEQ: {
+ return getEqWithType_l(type, ch);
+ }
+ case StageType::POSTEQ: {
+ return getEqWithType_l(type, ch);
+ }
+ case StageType::MBC: {
+ return getMbc_l(ch);
+ }
+ case StageType::LIMITER:
+ FALLTHROUGH_INTENDED;
+ case StageType::INPUTGAIN: {
+ return nullptr;
+ }
+ }
+}
+
+dp_fx::DPEq* DynamicsProcessingContext::getEqWithType_l(DynamicsProcessingContext::StageType type,
+ int ch) {
+ switch (type) {
+ case StageType::PREEQ: {
+ return getPreEq_l(ch);
+ }
+ case StageType::POSTEQ: {
+ return getPostEq_l(ch);
+ }
+ case StageType::MBC:
+ FALLTHROUGH_INTENDED;
+ case StageType::LIMITER:
+ FALLTHROUGH_INTENDED;
+ case StageType::INPUTGAIN: {
+ return nullptr;
+ }
+ }
+}
+
+std::vector<DynamicsProcessing::ChannelConfig> DynamicsProcessingContext::getChannelConfig(
+ StageType type) {
+ std::vector<DynamicsProcessing::ChannelConfig> ret;
+
+ std::lock_guard lg(mMutex);
+ for (int32_t ch = 0; ch < mChannelCount; ch++) {
+ auto stage = getStageWithType_l(type, ch);
+ if (!stage) {
+ continue;
+ }
+ ret.push_back({.channel = ch, .enable = stage->isEnabled()});
+ }
+ return ret;
+}
+
+std::vector<DynamicsProcessing::EqBandConfig> DynamicsProcessingContext::getEqBandConfigs(
+ StageType type) {
+ std::vector<DynamicsProcessing::EqBandConfig> eqBands;
+
+ std::lock_guard lg(mMutex);
+ auto maxBand = mEngineArchitecture.preEqStage.bandCount;
+ for (int32_t ch = 0; ch < mChannelCount; ch++) {
+ auto eq = getEqWithType_l(type, ch);
+ if (!eq) {
+ continue;
+ }
+ for (int32_t bandId = 0; bandId < maxBand; bandId++) {
+ auto band = eq->getBand(bandId);
+ if (!band) {
+ continue;
+ }
+ eqBands.push_back({.channel = ch,
+ .band = bandId,
+ .enable = band->isEnabled(),
+ .cutoffFrequencyHz = band->getCutoffFrequency(),
+ .gainDb = band->getGain()});
+ }
+ }
+ return eqBands;
+}
+
+/**
+ * When StageEnablement is in use, bandCount needs to be positive.
+ */
+bool DynamicsProcessingContext::validateStageEnablement(
+ const DynamicsProcessing::StageEnablement& enablement) {
+ return !enablement.inUse || (enablement.inUse && enablement.bandCount > 0);
+}
+
+bool DynamicsProcessingContext::validateEngineConfig(
+ const DynamicsProcessing::EngineArchitecture& engine) {
+ return engine.preferredProcessingDurationMs >= 0 &&
+ validateStageEnablement(engine.preEqStage) &&
+ validateStageEnablement(engine.postEqStage) && validateStageEnablement(engine.mbcStage);
+}
+
+inline bool DynamicsProcessingContext::validateCutoffFrequency(float freq) {
+ return freq >= DynamicsProcessingImpl::kCapability.minCutOffFreq &&
+ freq <= DynamicsProcessingImpl::kCapability.maxCutOffFreq;
+}
+
+bool DynamicsProcessingContext::validateEqBandConfig(const DynamicsProcessing::EqBandConfig& band,
+ int maxChannel, int maxBand) {
+ return validateChannel(band.channel, maxChannel) && validateBand(band.band, maxBand) &&
+ validateCutoffFrequency(band.cutoffFrequencyHz);
+}
+
+bool DynamicsProcessingContext::validateMbcBandConfig(const DynamicsProcessing::MbcBandConfig& band,
+ int maxChannel, int maxBand) {
+ return validateChannel(band.channel, maxChannel) && validateBand(band.band, maxBand) &&
+ validateCutoffFrequency(band.cutoffFrequencyHz) && validateTime(band.attackTimeMs) &&
+ validateTime(band.releaseTimeMs) && validateRatio(band.ratio) &&
+ validateBandDb(band.thresholdDb) && validateBandDb(band.kneeWidthDb) &&
+ validateBandDb(band.noiseGateThresholdDb) && validateRatio(band.expanderRatio);
+}
+
+bool DynamicsProcessingContext::validateLimiterConfig(
+ const DynamicsProcessing::LimiterConfig& limiter, int maxChannel) {
+ return validateChannel(limiter.channel, maxChannel) && validateTime(limiter.attackTimeMs) &&
+ validateTime(limiter.releaseTimeMs) && validateRatio(limiter.ratio) &&
+ validateBandDb(limiter.thresholdDb);
+}
+
+bool DynamicsProcessingContext::validateInputGainConfig(const DynamicsProcessing::InputGain& gain,
+ int maxChannel) {
+ return validateChannel(gain.channel, maxChannel);
+}
+
+template <typename D>
+RetCode DynamicsProcessingContext::setDpChannels_l(
+ const std::vector<DynamicsProcessing::ChannelConfig>& channels, bool stageInUse,
+ StageType type) {
+ RetCode ret = RetCode::SUCCESS;
+ std::unordered_set<int> channelSet;
+
+ RETURN_VALUE_IF(!stageInUse, RetCode::ERROR_ILLEGAL_PARAMETER, "stageNotInUse");
+ for (auto& it : channels) {
+ if (0 != channelSet.count(it.channel)) {
+ LOG(WARNING) << __func__ << " duplicated channel " << it.channel;
+ ret = RetCode::ERROR_ILLEGAL_PARAMETER;
+ } else {
+ channelSet.insert(it.channel);
+ }
+ if (it.channel < 0 || it.channel >= mChannelCount) {
+ LOG(WARNING) << __func__ << " skip illegal ChannelConfig " << it.toString() << " max "
+ << mChannelCount;
+ ret = RetCode::ERROR_ILLEGAL_PARAMETER;
+ continue;
+ }
+ auto dp = getStageWithType_l(type, it.channel);
+ if (!dp) {
+ LOG(WARNING) << __func__ << " channel " << it.channel << " not exist";
+ ret = RetCode::ERROR_ILLEGAL_PARAMETER;
+ continue;
+ }
+ if (dp->isEnabled() != it.enable) {
+ LOG(INFO) << __func__ << it.toString();
+ dp->setEnabled(it.enable);
+ }
+ }
+ return ret;
+}
+
+RetCode DynamicsProcessingContext::setDpChannelBand_l(const std::any& anyConfig, StageType type,
+ int maxCh, int maxBand,
+ std::set<std::pair<int, int>>& chBandSet) {
+ RETURN_VALUE_IF(!anyConfig.has_value(), RetCode::ERROR_ILLEGAL_PARAMETER, "bandInvalid");
+ RetCode ret = RetCode::SUCCESS;
+ std::pair<int, int> chBandKey;
+ switch (type) {
+ case StageType::PREEQ:
+ FALLTHROUGH_INTENDED;
+ case StageType::POSTEQ: {
+ dp_fx::DPEq* dp;
+ const auto& config = std::any_cast<DynamicsProcessing::EqBandConfig>(anyConfig);
+ RETURN_VALUE_IF(!validateEqBandConfig(config, maxCh, maxBand),
+ RetCode::ERROR_ILLEGAL_PARAMETER, "eqBandNotValid");
+ RETURN_VALUE_IF(
+ nullptr == (dp = getEqWithType_l(type, config.channel)) || !dp->isEnabled(),
+ RetCode::ERROR_ILLEGAL_PARAMETER, "dpEqNotExist");
+ dp_fx::DPEqBand band;
+ band.init(config.enable, config.cutoffFrequencyHz, config.gainDb);
+ dp->setBand(config.band, band);
+ chBandKey = {config.channel, config.band};
+ break;
+ }
+ case StageType::MBC: {
+ dp_fx::DPMbc* dp;
+ const auto& config = std::any_cast<DynamicsProcessing::MbcBandConfig>(anyConfig);
+ RETURN_VALUE_IF(!validateMbcBandConfig(config, maxCh, maxBand),
+ RetCode::ERROR_ILLEGAL_PARAMETER, "mbcBandNotValid");
+ RETURN_VALUE_IF(nullptr == (dp = getMbc_l(config.channel)) || !dp->isEnabled(),
+ RetCode::ERROR_ILLEGAL_PARAMETER, "dpMbcNotExist");
+ dp_fx::DPMbcBand band;
+ band.init(config.enable, config.cutoffFrequencyHz, config.attackTimeMs,
+ config.releaseTimeMs, config.ratio, config.thresholdDb, config.kneeWidthDb,
+ config.noiseGateThresholdDb, config.expanderRatio, config.preGainDb,
+ config.postGainDb);
+ dp->setBand(config.band, band);
+ chBandKey = {config.channel, config.band};
+ break;
+ }
+ case StageType::LIMITER: {
+ dp_fx::DPChannel* dp;
+ const auto& config = std::any_cast<DynamicsProcessing::LimiterConfig>(anyConfig);
+ RETURN_VALUE_IF(!validateLimiterConfig(config, maxCh),
+ RetCode::ERROR_ILLEGAL_PARAMETER, "limiterBandNotValid");
+ RETURN_VALUE_IF(nullptr == (dp = getChannel_l(config.channel)),
+ RetCode::ERROR_ILLEGAL_PARAMETER, "dpChNotExist");
+ dp_fx::DPLimiter limiter;
+ limiter.init(mEngineArchitecture.limiterInUse, config.enable, config.linkGroup,
+ config.attackTimeMs, config.releaseTimeMs, config.ratio,
+ config.thresholdDb, config.postGainDb);
+ dp->setLimiter(limiter);
+ chBandKey = {config.channel, 0};
+ break;
+ }
+ case StageType::INPUTGAIN: {
+ dp_fx::DPChannel* dp;
+ const auto& config = std::any_cast<DynamicsProcessing::InputGain>(anyConfig);
+ RETURN_VALUE_IF(!validateInputGainConfig(config, maxCh),
+ RetCode::ERROR_ILLEGAL_PARAMETER, "inputGainNotValid");
+ RETURN_VALUE_IF(nullptr == (dp = getChannel_l(config.channel)),
+ RetCode::ERROR_ILLEGAL_PARAMETER, "dpChNotExist");
+ dp->setInputGain(config.gainDb);
+ chBandKey = {config.channel, 0};
+ break;
+ }
+ }
+ RETURN_VALUE_IF(0 != chBandSet.count(chBandKey), RetCode::ERROR_ILLEGAL_PARAMETER,
+ "duplicatedBand");
+ chBandSet.insert(chBandKey);
+ return ret;
+}
+
+template <typename T /* BandConfig */>
+RetCode DynamicsProcessingContext::setBands_l(
+ const std::vector<T>& bands, int maxBand, StageType type) {
+ RetCode ret = RetCode::SUCCESS;
+ std::set<std::pair<int /* channel */, int /* band */>> bandSet;
+
+ for (const auto& it : bands) {
+ if (RetCode::SUCCESS !=
+ setDpChannelBand_l(std::make_any<T>(it), type, mChannelCount, maxBand, bandSet)) {
+ LOG(WARNING) << __func__ << " skipping band " << it.toString();
+ ret = RetCode::ERROR_ILLEGAL_PARAMETER;
+ continue;
+ }
+ LOG(INFO) << __func__ << it.toString();
+ }
+ return ret;
+}
+
+} // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/dynamicsproc/aidl/DynamicsProcessingContext.h b/media/libeffects/dynamicsproc/aidl/DynamicsProcessingContext.h
new file mode 100644
index 0000000..8be784e
--- /dev/null
+++ b/media/libeffects/dynamicsproc/aidl/DynamicsProcessingContext.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2023 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 <android-base/thread_annotations.h>
+#include <audio_effects/effect_dynamicsprocessing.h>
+
+#include "effect-impl/EffectContext.h"
+
+#include <any>
+#include <cstddef>
+#include <dsp/DPBase.h>
+#include <dsp/DPFrequency.h>
+
+namespace aidl::android::hardware::audio::effect {
+
+enum DynamicsProcessingState {
+ DYNAMICS_PROCESSING_STATE_UNINITIALIZED,
+ DYNAMICS_PROCESSING_STATE_INITIALIZED,
+ DYNAMICS_PROCESSING_STATE_ACTIVE,
+};
+
+class DynamicsProcessingContext final : public EffectContext {
+ public:
+ DynamicsProcessingContext(int statusDepth, const Parameter::Common& common);
+ ~DynamicsProcessingContext();
+
+ RetCode enable();
+ RetCode disable();
+ void reset();
+
+ // override EffectContext::setCommon to update mChannelCount
+ RetCode setCommon(const Parameter::Common& common) override;
+
+ RetCode setEngineArchitecture(const DynamicsProcessing::EngineArchitecture& engineArchitecture);
+ RetCode setPreEq(const std::vector<DynamicsProcessing::ChannelConfig>& eqChannels);
+ RetCode setPostEq(const std::vector<DynamicsProcessing::ChannelConfig>& eqChannels);
+ RetCode setPreEqBand(const std::vector<DynamicsProcessing::EqBandConfig>& eqBands);
+ RetCode setPostEqBand(const std::vector<DynamicsProcessing::EqBandConfig>& eqBands);
+ RetCode setMbc(const std::vector<DynamicsProcessing::ChannelConfig>& mbcChannels);
+ RetCode setMbcBand(const std::vector<DynamicsProcessing::MbcBandConfig>& eqBands);
+ RetCode setLimiter(const std::vector<DynamicsProcessing::LimiterConfig>& limiters);
+ RetCode setInputGain(const std::vector<DynamicsProcessing::InputGain>& gain);
+
+ DynamicsProcessing::EngineArchitecture getEngineArchitecture();
+ std::vector<DynamicsProcessing::ChannelConfig> getPreEq();
+ std::vector<DynamicsProcessing::ChannelConfig> getPostEq();
+ std::vector<DynamicsProcessing::EqBandConfig> getPreEqBand();
+ std::vector<DynamicsProcessing::EqBandConfig> getPostEqBand();
+ std::vector<DynamicsProcessing::ChannelConfig> getMbc();
+ std::vector<DynamicsProcessing::MbcBandConfig> getMbcBand();
+ std::vector<DynamicsProcessing::LimiterConfig> getLimiter();
+ std::vector<DynamicsProcessing::InputGain> getInputGain();
+
+ IEffect::Status lvmProcess(float* in, float* out, int samples);
+
+ private:
+ static constexpr float kPreferredProcessingDurationMs = 10.0f;
+ static constexpr int kBandCount = 5;
+ std::mutex mMutex;
+ size_t mChannelCount GUARDED_BY(mMutex) = 0;
+ DynamicsProcessingState mState GUARDED_BY(mMutex) = DYNAMICS_PROCESSING_STATE_UNINITIALIZED;
+ std::unique_ptr<dp_fx::DPFrequency> mDpFreq GUARDED_BY(mMutex) = nullptr;
+ bool mEngineInited GUARDED_BY(mMutex) = false;
+ DynamicsProcessing::EngineArchitecture mEngineArchitecture GUARDED_BY(mMutex) = {
+ .resolutionPreference =
+ DynamicsProcessing::ResolutionPreference::FAVOR_FREQUENCY_RESOLUTION,
+ .preferredProcessingDurationMs = kPreferredProcessingDurationMs,
+ .preEqStage = {.inUse = true, .bandCount = kBandCount},
+ .postEqStage = {.inUse = true, .bandCount = kBandCount},
+ .mbcStage = {.inUse = true, .bandCount = kBandCount},
+ .limiterInUse = true,
+ };
+
+ enum class StageType { PREEQ, POSTEQ, MBC, LIMITER, INPUTGAIN };
+
+ void init();
+
+ void dpSetFreqDomainVariant_l(const DynamicsProcessing::EngineArchitecture& engine)
+ REQUIRES(mMutex);
+ dp_fx::DPChannel* getChannel_l(int ch) REQUIRES(mMutex);
+ dp_fx::DPEq* getPreEq_l(int ch) REQUIRES(mMutex);
+ dp_fx::DPEq* getPostEq_l(int ch) REQUIRES(mMutex);
+ dp_fx::DPMbc* getMbc_l(int ch) REQUIRES(mMutex);
+ dp_fx::DPLimiter* getLimiter_l(int ch) REQUIRES(mMutex);
+ dp_fx::DPBandStage* getStageWithType_l(StageType type, int ch) REQUIRES(mMutex);
+ dp_fx::DPEq* getEqWithType_l(StageType type, int ch) REQUIRES(mMutex);
+ template <typename D>
+ RetCode setDpChannels_l(const std::vector<DynamicsProcessing::ChannelConfig>& channels,
+ bool stageInUse, StageType type) REQUIRES(mMutex);
+ template <typename T /* BandConfig */>
+ RetCode setBands_l(const std::vector<T>& bands, int maxBand, StageType type) REQUIRES(mMutex);
+ RetCode setDpChannelBand_l(const std::any& anyConfig, StageType type, int maxCh, int maxBand,
+ std::set<std::pair<int, int>>& chBandSet) REQUIRES(mMutex);
+
+ std::vector<DynamicsProcessing::EqBandConfig> getEqBandConfigs(StageType type);
+ std::vector<DynamicsProcessing::ChannelConfig> getChannelConfig(StageType type);
+
+ bool validateStageEnablement(const DynamicsProcessing::StageEnablement& enablement);
+ bool validateEngineConfig(const DynamicsProcessing::EngineArchitecture& engine);
+ bool validateEqBandConfig(const DynamicsProcessing::EqBandConfig& band, int maxChannel,
+ int maxBand);
+ bool validateMbcBandConfig(const DynamicsProcessing::MbcBandConfig& band, int maxChannel,
+ int maxBand);
+ bool validateLimiterConfig(const DynamicsProcessing::LimiterConfig& limiter, int maxChannel);
+ bool validateInputGainConfig(const DynamicsProcessing::InputGain& gain, int maxChannel);
+
+ inline bool validateCutoffFrequency(float freq);
+ inline bool validateChannel(int ch, int maxCh) { return ch >= 0 && ch < maxCh; }
+ inline bool validateBand(int band, int maxBand) { return band >= 0 && band < maxBand; }
+ inline bool validateTime(int time) { return time >= 0; }
+ inline bool validateRatio(int ratio) { return ratio >= 0; }
+ inline bool validateBandDb(int db) { return db <= 0; }
+};
+
+} // namespace aidl::android::hardware::audio::effect
\ No newline at end of file
diff --git a/media/libeffects/hapticgenerator/Android.bp b/media/libeffects/hapticgenerator/Android.bp
index 03ce329..07ba492 100644
--- a/media/libeffects/hapticgenerator/Android.bp
+++ b/media/libeffects/hapticgenerator/Android.bp
@@ -22,6 +22,23 @@
default_applicable_licenses: ["frameworks_av_license"],
}
+cc_defaults {
+ name : "hapticgeneratordefaults",
+ srcs: [
+ "Processors.cpp",
+ ],
+ shared_libs: [
+ "libaudioutils",
+ "libbase",
+ "liblog",
+ "libutils",
+ "libvibratorutils",
+ ],
+ header_libs: [
+ "libaudioeffects",
+ ],
+}
+
cc_library_shared {
name: "libhapticgenerator",
@@ -29,7 +46,10 @@
srcs: [
"EffectHapticGenerator.cpp",
- "Processors.cpp",
+ ],
+
+ defaults: [
+ "hapticgeneratordefaults",
],
cflags: [
@@ -43,18 +63,30 @@
"-fvisibility=hidden",
],
- shared_libs: [
- "libaudioutils",
- "libbase",
- "libbinder",
- "liblog",
- "libutils",
- "libvibrator",
+ relative_install_path: "soundfx",
+}
+
+cc_library_shared {
+ name: "libhapticgeneratoraidl",
+
+ srcs: [
+ "aidl/EffectHapticGenerator.cpp",
+ "aidl/HapticGeneratorContext.cpp",
+ ":effectCommonFile",
],
- relative_install_path: "soundfx",
+ defaults: [
+ "aidlaudioservice_defaults",
+ "latest_android_hardware_audio_effect_ndk_shared",
+ "latest_android_media_audio_common_types_ndk_shared",
+ "hapticgeneratordefaults",
+ ],
- header_libs: [
- "libaudioeffects",
+ cflags: [
+ "-Wthread-safety",
+ ],
+
+ visibility: [
+ "//hardware/interfaces/audio/aidl/default",
],
}
diff --git a/media/libeffects/hapticgenerator/aidl/EffectHapticGenerator.cpp b/media/libeffects/hapticgenerator/aidl/EffectHapticGenerator.cpp
new file mode 100644
index 0000000..7e22482
--- /dev/null
+++ b/media/libeffects/hapticgenerator/aidl/EffectHapticGenerator.cpp
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2022 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 "AHAL_HapticGeneratorImpl"
+
+#include "EffectHapticGenerator.h"
+
+#include <android-base/logging.h>
+#include <audio_effects/effect_hapticgenerator.h>
+
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::HapticGeneratorImpl;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::kHapticGeneratorImplUUID;
+using aidl::android::media::audio::common::AudioUuid;
+
+extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
+ std::shared_ptr<IEffect>* instanceSpp) {
+ if (!in_impl_uuid || *in_impl_uuid != kHapticGeneratorImplUUID) {
+ LOG(ERROR) << __func__ << "uuid not supported";
+ return EX_ILLEGAL_ARGUMENT;
+ }
+ if (instanceSpp) {
+ *instanceSpp = ndk::SharedRefBase::make<HapticGeneratorImpl>();
+ LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
+ return EX_NONE;
+ } else {
+ LOG(ERROR) << __func__ << " invalid input parameter!";
+ return EX_ILLEGAL_ARGUMENT;
+ }
+}
+
+extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
+ if (!in_impl_uuid || *in_impl_uuid != kHapticGeneratorImplUUID) {
+ LOG(ERROR) << __func__ << "uuid not supported";
+ return EX_ILLEGAL_ARGUMENT;
+ }
+ *_aidl_return = HapticGeneratorImpl::kDescriptor;
+ return EX_NONE;
+}
+
+namespace aidl::android::hardware::audio::effect {
+
+const std::string HapticGeneratorImpl::kEffectName = "Haptic Generator";
+const Descriptor HapticGeneratorImpl::kDescriptor = {
+ .common = {.id = {.type = kHapticGeneratorTypeUUID,
+ .uuid = kHapticGeneratorImplUUID,
+ .proxy = std::nullopt},
+ .flags = {.type = Flags::Type::INSERT, .insert = Flags::Insert::FIRST},
+ .name = HapticGeneratorImpl::kEffectName,
+ .implementor = "The Android Open Source Project"}};
+
+ndk::ScopedAStatus HapticGeneratorImpl::getDescriptor(Descriptor* _aidl_return) {
+ RETURN_IF(!_aidl_return, EX_ILLEGAL_ARGUMENT, "Parameter:nullptr");
+ LOG(DEBUG) << __func__ << kDescriptor.toString();
+ *_aidl_return = kDescriptor;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus HapticGeneratorImpl::commandImpl(CommandId command) {
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+ switch (command) {
+ case CommandId::START:
+ mContext->enable();
+ break;
+ case CommandId::STOP:
+ mContext->disable();
+ break;
+ case CommandId::RESET:
+ mContext->reset();
+ break;
+ default:
+ LOG(ERROR) << __func__ << " commandId " << toString(command) << " not supported";
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "commandIdNotSupported");
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus HapticGeneratorImpl::setParameterSpecific(const Parameter::Specific& specific) {
+ RETURN_IF(Parameter::Specific::hapticGenerator != specific.getTag(), EX_ILLEGAL_ARGUMENT,
+ "EffectNotSupported");
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+ auto& hgParam = specific.get<Parameter::Specific::hapticGenerator>();
+ auto tag = hgParam.getTag();
+
+ switch (tag) {
+ case HapticGenerator::hapticScales: {
+ RETURN_IF(mContext->setHgHapticScales(hgParam.get<HapticGenerator::hapticScales>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setHapticScaleFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ case HapticGenerator::vibratorInfo: {
+ RETURN_IF(mContext->setHgVibratorInformation(
+ hgParam.get<HapticGenerator::vibratorInfo>()) != RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setVibratorInfoFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ default: {
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+ EX_ILLEGAL_ARGUMENT, "HapticGeneratorTagNotSupported");
+ }
+ }
+}
+
+ndk::ScopedAStatus HapticGeneratorImpl::getParameterSpecific(const Parameter::Id& id,
+ Parameter::Specific* specific) {
+ RETURN_IF(!specific, EX_NULL_POINTER, "nullPtr");
+ auto tag = id.getTag();
+ RETURN_IF(Parameter::Id::hapticGeneratorTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
+ auto hgId = id.get<Parameter::Id::hapticGeneratorTag>();
+ auto hgIdTag = hgId.getTag();
+ switch (hgIdTag) {
+ case HapticGenerator::Id::commonTag:
+ return getParameterHapticGenerator(hgId.get<HapticGenerator::Id::commonTag>(),
+ specific);
+ default:
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(hgIdTag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+ EX_ILLEGAL_ARGUMENT, "HapticGeneratorTagNotSupported");
+ }
+}
+
+ndk::ScopedAStatus HapticGeneratorImpl::getParameterHapticGenerator(const HapticGenerator::Tag& tag,
+ Parameter::Specific* specific) {
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+ HapticGenerator hgParam;
+ switch (tag) {
+ case HapticGenerator::hapticScales: {
+ hgParam.set<HapticGenerator::hapticScales>(mContext->getHgHapticScales());
+ break;
+ }
+ case HapticGenerator::vibratorInfo: {
+ hgParam.set<HapticGenerator::vibratorInfo>(mContext->getHgVibratorInformation());
+ break;
+ }
+ default: {
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+ EX_ILLEGAL_ARGUMENT, "HapticGeneratorTagNotSupported");
+ }
+ }
+
+ specific->set<Parameter::Specific::hapticGenerator>(hgParam);
+ return ndk::ScopedAStatus::ok();
+}
+
+std::shared_ptr<EffectContext> HapticGeneratorImpl::createContext(const Parameter::Common& common) {
+ if (mContext) {
+ LOG(DEBUG) << __func__ << " context already exist";
+ return mContext;
+ }
+
+ mContext = std::make_shared<HapticGeneratorContext>(1 /* statusFmqDepth */, common);
+ return mContext;
+}
+
+RetCode HapticGeneratorImpl::releaseContext() {
+ if (mContext) {
+ mContext->reset();
+ }
+ return RetCode::SUCCESS;
+}
+
+// Processing method running in EffectWorker thread.
+IEffect::Status HapticGeneratorImpl::effectProcessImpl(float* in, float* out, int samples) {
+ IEffect::Status status = {EX_NULL_POINTER, 0, 0};
+ RETURN_VALUE_IF(!mContext, status, "nullContext");
+ return mContext->lvmProcess(in, out, samples);
+}
+
+} // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/hapticgenerator/aidl/EffectHapticGenerator.h b/media/libeffects/hapticgenerator/aidl/EffectHapticGenerator.h
new file mode 100644
index 0000000..02ca392
--- /dev/null
+++ b/media/libeffects/hapticgenerator/aidl/EffectHapticGenerator.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2022 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 <aidl/android/hardware/audio/effect/BnEffect.h>
+
+#include "HapticGeneratorContext.h"
+#include "effect-impl/EffectImpl.h"
+#include "effect-impl/EffectUUID.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+class HapticGeneratorImpl final : public EffectImpl {
+ public:
+ static const std::string kEffectName;
+ static const Descriptor kDescriptor;
+ HapticGeneratorImpl() { LOG(DEBUG) << __func__; }
+ ~HapticGeneratorImpl() {
+ cleanUp();
+ LOG(DEBUG) << __func__;
+ }
+
+ ndk::ScopedAStatus commandImpl(CommandId command) override;
+ ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
+ ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
+ ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
+ Parameter::Specific* specific) override;
+ IEffect::Status effectProcessImpl(float* in, float* out, int process) override;
+ std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
+ RetCode releaseContext() override;
+
+ std::shared_ptr<EffectContext> getContext() override { return mContext; }
+ std::string getEffectName() override { return kEffectName; }
+
+ private:
+ std::shared_ptr<HapticGeneratorContext> mContext;
+ ndk::ScopedAStatus getParameterHapticGenerator(const HapticGenerator::Tag& tag,
+ Parameter::Specific* specific);
+};
+
+} // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/hapticgenerator/aidl/HapticGeneratorContext.cpp b/media/libeffects/hapticgenerator/aidl/HapticGeneratorContext.cpp
new file mode 100644
index 0000000..64f51c3
--- /dev/null
+++ b/media/libeffects/hapticgenerator/aidl/HapticGeneratorContext.cpp
@@ -0,0 +1,346 @@
+/*
+ * Copyright (C) 2022 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 "AHAL_HapticGeneratorContext"
+
+#include <Utils.h>
+#include <android-base/parsedouble.h>
+#include <android-base/properties.h>
+
+#include "HapticGeneratorContext.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+HapticGeneratorContext::HapticGeneratorContext(int statusDepth, const Parameter::Common& common)
+ : EffectContext(statusDepth, common) {
+ LOG(DEBUG) << __func__;
+ mState = HAPTIC_GENERATOR_STATE_UNINITIALIZED;
+ mSampleRate = common.input.base.sampleRate;
+ mFrameCount = common.input.frameCount;
+ init_params(common.input.base.channelMask, common.output.base.channelMask);
+}
+
+HapticGeneratorContext::~HapticGeneratorContext() {
+ LOG(DEBUG) << __func__;
+ mState = HAPTIC_GENERATOR_STATE_UNINITIALIZED;
+}
+
+RetCode HapticGeneratorContext::enable() {
+ if (mState != HAPTIC_GENERATOR_STATE_INITIALIZED) {
+ return RetCode::ERROR_EFFECT_LIB_ERROR;
+ }
+ mState = HAPTIC_GENERATOR_STATE_ACTIVE;
+ return RetCode::SUCCESS;
+}
+
+RetCode HapticGeneratorContext::disable() {
+ if (mState != HAPTIC_GENERATOR_STATE_ACTIVE) {
+ return RetCode::ERROR_EFFECT_LIB_ERROR;
+ }
+ mState = HAPTIC_GENERATOR_STATE_INITIALIZED;
+ return RetCode::SUCCESS;
+}
+
+void HapticGeneratorContext::reset() {
+ for (auto& filter : mProcessorsRecord.filters) {
+ filter->clear();
+ }
+ for (auto& slowEnv : mProcessorsRecord.slowEnvs) {
+ slowEnv->clear();
+ }
+ for (auto& distortion : mProcessorsRecord.distortions) {
+ distortion->clear();
+ }
+}
+
+RetCode HapticGeneratorContext::setHgHapticScales(
+ const std::vector<HapticGenerator::HapticScale> hapticScales) {
+ std::lock_guard lg(mMutex);
+ for (auto hapticScale : hapticScales) {
+ mParams.mHapticScales.insert_or_assign(hapticScale.id, hapticScale.scale);
+ }
+ mParams.mMaxVibratorScale = HapticGenerator::VibratorScale::MUTE;
+ for (const auto& [id, vibratorScale] : mParams.mHapticScales) {
+ mParams.mMaxVibratorScale = std::max(mParams.mMaxVibratorScale, vibratorScale);
+ }
+ return RetCode::SUCCESS;
+}
+
+HapticGenerator::VibratorInformation HapticGeneratorContext::getHgVibratorInformation() {
+ std::lock_guard lg(mMutex);
+ return mParams.mVibratorInfo;
+}
+
+std::vector<HapticGenerator::HapticScale> HapticGeneratorContext::getHgHapticScales() {
+ std::vector<HapticGenerator::HapticScale> result;
+ std::lock_guard lg(mMutex);
+ for (const auto& [id, vibratorScale] : mParams.mHapticScales) {
+ result.push_back({id, vibratorScale});
+ }
+ return result;
+}
+
+RetCode HapticGeneratorContext::setHgVibratorInformation(
+ const HapticGenerator::VibratorInformation& vibratorInfo) {
+ {
+ std::lock_guard lg(mMutex);
+ mParams.mVibratorInfo = vibratorInfo;
+
+ if (mProcessorsRecord.bpf != nullptr) {
+ mProcessorsRecord.bpf->setCoefficients(
+ ::android::audio_effect::haptic_generator::bpfCoefs(
+ mParams.mVibratorInfo.resonantFrequencyHz, DEFAULT_BPF_Q, mSampleRate));
+ }
+ if (mProcessorsRecord.bsf != nullptr) {
+ mProcessorsRecord.bsf->setCoefficients(
+ ::android::audio_effect::haptic_generator::bsfCoefs(
+ mParams.mVibratorInfo.resonantFrequencyHz,
+ mParams.mVibratorInfo.qFactor, mParams.mVibratorInfo.qFactor / 2.0f,
+ mSampleRate));
+ }
+ }
+ configure();
+ return RetCode::SUCCESS;
+}
+
+IEffect::Status HapticGeneratorContext::lvmProcess(float* in, float* out, int samples) {
+ LOG(DEBUG) << __func__ << " in " << in << " out " << out << " sample " << samples;
+
+ IEffect::Status status = {EX_NULL_POINTER, 0, 0};
+ RETURN_VALUE_IF(!in, status, "nullInput");
+ RETURN_VALUE_IF(!out, status, "nullOutput");
+ status = {EX_ILLEGAL_STATE, 0, 0};
+ RETURN_VALUE_IF(getInputFrameSize() != getOutputFrameSize(), status, "FrameSizeMismatch");
+ auto frameSize = getInputFrameSize();
+ RETURN_VALUE_IF(0 == frameSize, status, "zeroFrameSize");
+
+ LOG(DEBUG) << __func__ << " start processing";
+ // The audio data must not be modified but just written to
+ // output buffer according the access mode.
+ bool accumulate = false;
+ if (in != out) {
+ for (int i = 0; i < samples; i++) {
+ if (accumulate) {
+ out[i] += in[i];
+ } else {
+ out[i] = in[i];
+ }
+ }
+ }
+
+ if (mState != HAPTIC_GENERATOR_STATE_ACTIVE) {
+ return status;
+ }
+
+ std::lock_guard lg(mMutex);
+ if (mParams.mMaxVibratorScale == HapticGenerator::VibratorScale::MUTE) {
+ // Haptic channels are muted, not need to generate haptic data.
+ return {STATUS_OK, samples, samples};
+ }
+
+ // Resize buffer if the haptic sample count is greater than buffer size.
+ size_t hapticSampleCount = mFrameCount * mParams.mHapticChannelCount;
+ if (hapticSampleCount > mInputBuffer.size()) {
+ // The inputBuffer and outputBuffer must have the same size, which must be at least
+ // the haptic sample count.
+ mInputBuffer.resize(hapticSampleCount);
+ mOutputBuffer.resize(hapticSampleCount);
+ }
+
+ // Construct input buffer according to haptic channel source
+ for (size_t i = 0; i < mFrameCount; ++i) {
+ for (size_t j = 0; j < mParams.mHapticChannelCount; ++j) {
+ mInputBuffer[i * mParams.mHapticChannelCount + j] =
+ in[i * mParams.mAudioChannelCount + mParams.mHapticChannelSource[j]];
+ }
+ }
+
+ float* hapticOutBuffer =
+ runProcessingChain(mInputBuffer.data(), mOutputBuffer.data(), mFrameCount);
+ ::android::os::scaleHapticData(
+ hapticOutBuffer, hapticSampleCount,
+ static_cast<::android::os::HapticScale>(mParams.mMaxVibratorScale),
+ mParams.mVibratorInfo.qFactor);
+
+ // For haptic data, the haptic playback thread will copy the data from effect input
+ // buffer, which contains haptic data at the end of the buffer, directly to sink buffer.
+ // In that case, copy haptic data to input buffer instead of output buffer.
+ // Note: this may not work with rpc/binder calls
+ int offset = samples;
+ for (int i = 0; i < hapticSampleCount; ++i) {
+ in[samples + i] = hapticOutBuffer[i];
+ }
+ return {STATUS_OK, samples, static_cast<int32_t>(samples + hapticSampleCount)};
+}
+
+void HapticGeneratorContext::init_params(media::audio::common::AudioChannelLayout inputChMask,
+ media::audio::common::AudioChannelLayout outputChMask) {
+ std::lock_guard lg(mMutex);
+ mParams.mMaxVibratorScale = HapticGenerator::VibratorScale::MUTE;
+ mParams.mVibratorInfo.resonantFrequencyHz = DEFAULT_RESONANT_FREQUENCY;
+ mParams.mVibratorInfo.qFactor = DEFAULT_BSF_ZERO_Q;
+
+ mParams.mAudioChannelCount = ::android::hardware::audio::common::getChannelCount(
+ inputChMask, ~media::audio::common::AudioChannelLayout::LAYOUT_HAPTIC_AB);
+ mParams.mHapticChannelCount = ::android::hardware::audio::common::getChannelCount(
+ outputChMask, media::audio::common::AudioChannelLayout::LAYOUT_HAPTIC_AB);
+ LOG_ALWAYS_FATAL_IF(mParams.mHapticChannelCount > 2, "haptic channel count is too large");
+ for (size_t i = 0; i < mParams.mHapticChannelCount; ++i) {
+ // By default, use the first audio channel to generate haptic channels.
+ mParams.mHapticChannelSource[i] = 0;
+ }
+
+ mState = HAPTIC_GENERATOR_STATE_INITIALIZED;
+}
+
+float HapticGeneratorContext::getDistortionOutputGain() {
+ float distortionOutputGain = getFloatProperty(
+ "vendor.audio.hapticgenerator.distortion.output.gain", DEFAULT_DISTORTION_OUTPUT_GAIN);
+ LOG(DEBUG) << "Using distortion output gain as " << distortionOutputGain;
+ return distortionOutputGain;
+}
+
+float HapticGeneratorContext::getFloatProperty(const std::string& key, float defaultValue) {
+ float result;
+ std::string value = ::android::base::GetProperty(key, "");
+ if (!value.empty() && ::android::base::ParseFloat(value, &result)) {
+ return result;
+ }
+ return defaultValue;
+}
+
+void HapticGeneratorContext::addBiquadFilter(std::shared_ptr<HapticBiquadFilter> filter) {
+ // The process chain captures the shared pointer of the filter in lambda.
+ // The process record will keep a shared pointer to the filter so that it is possible to
+ // access the filter outside of the process chain.
+ mProcessorsRecord.filters.push_back(filter);
+ mProcessingChain.push_back([filter](float* out, const float* in, size_t frameCount) {
+ filter->process(out, in, frameCount);
+ });
+}
+
+/**
+ * Build haptic generator processing chain.
+ */
+void HapticGeneratorContext::buildProcessingChain() {
+ std::lock_guard lg(mMutex);
+ const size_t channelCount = mParams.mHapticChannelCount;
+ float highPassCornerFrequency = 50.0f;
+ auto hpf = ::android::audio_effect::haptic_generator::createHPF2(highPassCornerFrequency,
+ mSampleRate, channelCount);
+ addBiquadFilter(hpf);
+ float lowPassCornerFrequency = 9000.0f;
+ auto lpf = ::android::audio_effect::haptic_generator::createLPF2(lowPassCornerFrequency,
+ mSampleRate, channelCount);
+ addBiquadFilter(lpf);
+
+ auto ramp = std::make_shared<::android::audio_effect::haptic_generator::Ramp>(
+ channelCount); // ramp = half-wave rectifier.
+ // The process chain captures the shared pointer of the ramp in lambda. It will be the only
+ // reference to the ramp.
+ // The process record will keep a weak pointer to the ramp so that it is possible to access
+ // the ramp outside of the process chain.
+ mProcessorsRecord.ramps.push_back(ramp);
+ mProcessingChain.push_back([ramp](float* out, const float* in, size_t frameCount) {
+ ramp->process(out, in, frameCount);
+ });
+
+ highPassCornerFrequency = 60.0f;
+ hpf = ::android::audio_effect::haptic_generator::createHPF2(highPassCornerFrequency,
+ mSampleRate, channelCount);
+ addBiquadFilter(hpf);
+ lowPassCornerFrequency = 700.0f;
+ lpf = ::android::audio_effect::haptic_generator::createLPF2(lowPassCornerFrequency, mSampleRate,
+ channelCount);
+ addBiquadFilter(lpf);
+
+ lowPassCornerFrequency = 400.0f;
+ lpf = ::android::audio_effect::haptic_generator::createLPF2(lowPassCornerFrequency, mSampleRate,
+ channelCount);
+ addBiquadFilter(lpf);
+ lowPassCornerFrequency = 500.0f;
+ lpf = ::android::audio_effect::haptic_generator::createLPF2(lowPassCornerFrequency, mSampleRate,
+ channelCount);
+ addBiquadFilter(lpf);
+
+ auto bpf = ::android::audio_effect::haptic_generator::createBPF(
+ mParams.mVibratorInfo.resonantFrequencyHz, DEFAULT_BPF_Q, mSampleRate, channelCount);
+ mProcessorsRecord.bpf = bpf;
+ addBiquadFilter(bpf);
+
+ float normalizationPower = DEFAULT_SLOW_ENV_NORMALIZATION_POWER;
+ // The process chain captures the shared pointer of the slow envelope in lambda. It will
+ // be the only reference to the slow envelope.
+ // The process record will keep a weak pointer to the slow envelope so that it is possible
+ // to access the slow envelope outside of the process chain.
+ // SlowEnvelope = partial normalizer, or AGC.
+ auto slowEnv = std::make_shared<::android::audio_effect::haptic_generator::SlowEnvelope>(
+ 5.0f /*envCornerFrequency*/, mSampleRate, normalizationPower, 0.01f /*envOffset*/,
+ channelCount);
+ mProcessorsRecord.slowEnvs.push_back(slowEnv);
+ mProcessingChain.push_back([slowEnv](float* out, const float* in, size_t frameCount) {
+ slowEnv->process(out, in, frameCount);
+ });
+
+ auto bsf = ::android::audio_effect::haptic_generator::createBSF(
+ mParams.mVibratorInfo.resonantFrequencyHz, mParams.mVibratorInfo.qFactor,
+ mParams.mVibratorInfo.qFactor / 2.0f, mSampleRate, channelCount);
+ mProcessorsRecord.bsf = bsf;
+ addBiquadFilter(bsf);
+
+ // The process chain captures the shared pointer of the Distortion in lambda. It will
+ // be the only reference to the Distortion.
+ // The process record will keep a weak pointer to the Distortion so that it is possible
+ // to access the Distortion outside of the process chain.
+ auto distortion = std::make_shared<::android::audio_effect::haptic_generator::Distortion>(
+ DEFAULT_DISTORTION_CORNER_FREQUENCY, mSampleRate, DEFAULT_DISTORTION_INPUT_GAIN,
+ DEFAULT_DISTORTION_CUBE_THRESHOLD, getDistortionOutputGain(), channelCount);
+ mProcessorsRecord.distortions.push_back(distortion);
+ mProcessingChain.push_back([distortion](float* out, const float* in, size_t frameCount) {
+ distortion->process(out, in, frameCount);
+ });
+}
+
+void HapticGeneratorContext::configure() {
+ mProcessingChain.clear();
+ mProcessorsRecord.filters.clear();
+ mProcessorsRecord.ramps.clear();
+ mProcessorsRecord.slowEnvs.clear();
+ mProcessorsRecord.distortions.clear();
+
+ buildProcessingChain();
+}
+
+/**
+ * Run the processing chain to generate haptic data from audio data
+ *
+ * @param buf1 a buffer contains raw audio data
+ * @param buf2 a buffer that is large enough to keep all the data
+ * @param frameCount frame count of the data
+ *
+ * @return a pointer to the output buffer
+ */
+float* HapticGeneratorContext::runProcessingChain(float* buf1, float* buf2, size_t frameCount) {
+ float* in = buf1;
+ float* out = buf2;
+ for (const auto processingFunc : mProcessingChain) {
+ processingFunc(out, in, frameCount);
+ std::swap(in, out);
+ }
+ return in;
+}
+
+} // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/hapticgenerator/aidl/HapticGeneratorContext.h b/media/libeffects/hapticgenerator/aidl/HapticGeneratorContext.h
new file mode 100644
index 0000000..dc43feb
--- /dev/null
+++ b/media/libeffects/hapticgenerator/aidl/HapticGeneratorContext.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2022 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 <android-base/thread_annotations.h>
+#include <vibrator/ExternalVibrationUtils.h>
+#include <map>
+
+#include "Processors.h"
+#include "effect-impl/EffectContext.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+enum HapticGeneratorState {
+ HAPTIC_GENERATOR_STATE_UNINITIALIZED,
+ HAPTIC_GENERATOR_STATE_INITIALIZED,
+ HAPTIC_GENERATOR_STATE_ACTIVE,
+};
+
+struct HapticGeneratorParam {
+ // The audio channels used to generate haptic channels. The first channel will be used to
+ // generate HAPTIC_A, The second channel will be used to generate HAPTIC_B.
+ // The value will be offset of audio channel
+ int mHapticChannelSource[2];
+
+ int mHapticChannelCount;
+ int mAudioChannelCount;
+
+ HapticGenerator::HapticScale mHapticScale;
+ std::map<int, HapticGenerator::VibratorScale> mHapticScales;
+ // max intensity will be used to scale haptic data.
+ HapticGenerator::VibratorScale mMaxVibratorScale;
+
+ HapticGenerator::VibratorInformation mVibratorInfo;
+};
+
+// A structure to keep all shared pointers for all processors in HapticGenerator.
+struct HapticGeneratorProcessorsRecord {
+ std::vector<std::shared_ptr<HapticBiquadFilter>> filters;
+ std::vector<std::shared_ptr<::android::audio_effect::haptic_generator::Ramp>> ramps;
+ std::vector<std::shared_ptr<::android::audio_effect::haptic_generator::SlowEnvelope>> slowEnvs;
+ std::vector<std::shared_ptr<::android::audio_effect::haptic_generator::Distortion>> distortions;
+
+ // Cache band-pass filter and band-stop filter for updating parameters
+ // according to vibrator info
+ std::shared_ptr<HapticBiquadFilter> bpf;
+ std::shared_ptr<HapticBiquadFilter> bsf;
+};
+
+class HapticGeneratorContext final : public EffectContext {
+ public:
+ HapticGeneratorContext(int statusDepth, const Parameter::Common& common);
+ ~HapticGeneratorContext();
+ RetCode enable();
+ RetCode disable();
+ void reset();
+
+ RetCode setHgHapticScales(const std::vector<HapticGenerator::HapticScale> hapticScales);
+ std::vector<HapticGenerator::HapticScale> getHgHapticScales();
+
+ RetCode setHgVibratorInformation(const HapticGenerator::VibratorInformation& vibratorInfo);
+ HapticGenerator::VibratorInformation getHgVibratorInformation();
+
+ IEffect::Status lvmProcess(float* in, float* out, int samples);
+
+ private:
+ static constexpr float DEFAULT_RESONANT_FREQUENCY = 150.0f;
+ static constexpr float DEFAULT_BSF_ZERO_Q = 8.0f;
+ static constexpr float DEFAULT_BSF_POLE_Q = 4.0f;
+ static constexpr float DEFAULT_DISTORTION_OUTPUT_GAIN = 1.5f;
+ static constexpr float DEFAULT_BPF_Q = 1.0f;
+ static constexpr float DEFAULT_SLOW_ENV_NORMALIZATION_POWER = -0.8f;
+ static constexpr float DEFAULT_DISTORTION_CORNER_FREQUENCY = 300.0f;
+ static constexpr float DEFAULT_DISTORTION_INPUT_GAIN = 0.3f;
+ static constexpr float DEFAULT_DISTORTION_CUBE_THRESHOLD = 0.1f;
+
+ std::mutex mMutex;
+ HapticGeneratorState mState;
+ HapticGeneratorParam mParams GUARDED_BY(mMutex);
+ int mSampleRate;
+ int mFrameCount = 0;
+
+ // A cache for all shared pointers of the HapticGenerator
+ struct HapticGeneratorProcessorsRecord mProcessorsRecord;
+
+ // Using a vector of functions to record the processing chain for haptic-generating algorithm.
+ // The three parameters of the processing functions are pointer to output buffer, pointer to
+ // input buffer and frame count.
+ std::vector<std::function<void(float*, const float*, size_t)>> mProcessingChain;
+
+ // inputBuffer is where to keep input buffer for the generating algorithm. It will be
+ // constructed according to hapticChannelSource.
+ std::vector<float> mInputBuffer;
+
+ // outputBuffer is a buffer having the same length as inputBuffer. It can be used as
+ // intermediate buffer in the generating algorithm.
+ std::vector<float> mOutputBuffer;
+
+ void init_params(media::audio::common::AudioChannelLayout inputChMask,
+ media::audio::common::AudioChannelLayout outputChMask);
+ void configure();
+
+ float getDistortionOutputGain();
+ float getFloatProperty(const std::string& key, float defaultValue);
+ void addBiquadFilter(std::shared_ptr<HapticBiquadFilter> filter);
+ void buildProcessingChain();
+ float* runProcessingChain(float* buf1, float* buf2, size_t frameCount);
+};
+
+} // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/loudness/Android.bp b/media/libeffects/loudness/Android.bp
index bcd6947..fc0217b 100644
--- a/media/libeffects/loudness/Android.bp
+++ b/media/libeffects/loudness/Android.bp
@@ -44,3 +44,32 @@
header_libs: ["libaudioeffects"],
}
+
+cc_library_shared {
+ name: "libloudnessenhanceraidl",
+ srcs: [
+ "aidl/EffectLoudnessEnhancer.cpp",
+ "aidl/LoudnessEnhancerContext.cpp",
+ "dsp/core/dynamic_range_compression.cpp",
+ ":effectCommonFile",
+ ],
+ defaults: [
+ "aidlaudioservice_defaults",
+ "latest_android_hardware_audio_effect_ndk_shared",
+ "latest_android_media_audio_common_types_ndk_shared",
+ ],
+ header_libs: [
+ "libaudioeffects",
+ "libhardware_headers",
+ ],
+ cflags: [
+ "-Wthread-safety",
+ ],
+ shared_libs: [
+ "libcutils",
+ "liblog",
+ ],
+ visibility: [
+ "//hardware/interfaces/audio/aidl/default",
+ ],
+}
diff --git a/media/libeffects/loudness/aidl/EffectLoudnessEnhancer.cpp b/media/libeffects/loudness/aidl/EffectLoudnessEnhancer.cpp
new file mode 100644
index 0000000..9d8bc80
--- /dev/null
+++ b/media/libeffects/loudness/aidl/EffectLoudnessEnhancer.cpp
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2022 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 "AHAL_LoudnessEnhancerImpl"
+
+#include <android-base/logging.h>
+
+#include "EffectLoudnessEnhancer.h"
+
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::kLoudnessEnhancerImplUUID;
+using aidl::android::hardware::audio::effect::LoudnessEnhancerImpl;
+using aidl::android::hardware::audio::effect::State;
+using aidl::android::media::audio::common::AudioUuid;
+
+extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
+ std::shared_ptr<IEffect>* instanceSpp) {
+ if (!in_impl_uuid || *in_impl_uuid != kLoudnessEnhancerImplUUID) {
+ LOG(ERROR) << __func__ << "uuid not supported";
+ return EX_ILLEGAL_ARGUMENT;
+ }
+ if (instanceSpp) {
+ *instanceSpp = ndk::SharedRefBase::make<LoudnessEnhancerImpl>();
+ LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
+ return EX_NONE;
+ } else {
+ LOG(ERROR) << __func__ << " invalid input parameter!";
+ return EX_ILLEGAL_ARGUMENT;
+ }
+}
+
+extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
+ if (!in_impl_uuid || *in_impl_uuid != kLoudnessEnhancerImplUUID) {
+ LOG(ERROR) << __func__ << "uuid not supported";
+ return EX_ILLEGAL_ARGUMENT;
+ }
+ *_aidl_return = LoudnessEnhancerImpl::kDescriptor;
+ return EX_NONE;
+}
+
+namespace aidl::android::hardware::audio::effect {
+
+const std::string LoudnessEnhancerImpl::kEffectName = "Loudness Enhancer";
+const Descriptor LoudnessEnhancerImpl::kDescriptor = {
+ .common = {.id = {.type = kLoudnessEnhancerTypeUUID,
+ .uuid = kLoudnessEnhancerImplUUID,
+ .proxy = std::nullopt},
+ .flags = {.type = Flags::Type::INSERT, .insert = Flags::Insert::FIRST},
+ .name = LoudnessEnhancerImpl::kEffectName,
+ .implementor = "The Android Open Source Project"}};
+
+ndk::ScopedAStatus LoudnessEnhancerImpl::getDescriptor(Descriptor* _aidl_return) {
+ RETURN_IF(!_aidl_return, EX_ILLEGAL_ARGUMENT, "Parameter:nullptr");
+ LOG(DEBUG) << __func__ << kDescriptor.toString();
+ *_aidl_return = kDescriptor;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus LoudnessEnhancerImpl::commandImpl(CommandId command) {
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+ switch (command) {
+ case CommandId::START:
+ mContext->enable();
+ break;
+ case CommandId::STOP:
+ mContext->disable();
+ break;
+ case CommandId::RESET:
+ mContext->disable();
+ mContext->resetBuffer();
+ break;
+ default:
+ LOG(ERROR) << __func__ << " commandId " << toString(command) << " not supported";
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "commandIdNotSupported");
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus LoudnessEnhancerImpl::setParameterSpecific(const Parameter::Specific& specific) {
+ RETURN_IF(Parameter::Specific::loudnessEnhancer != specific.getTag(), EX_ILLEGAL_ARGUMENT,
+ "EffectNotSupported");
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+ auto& leParam = specific.get<Parameter::Specific::loudnessEnhancer>();
+ auto tag = leParam.getTag();
+
+ switch (tag) {
+ case LoudnessEnhancer::gainMb: {
+ RETURN_IF(mContext->setLeGain(leParam.get<LoudnessEnhancer::gainMb>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setGainMbFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ default: {
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+ EX_ILLEGAL_ARGUMENT, "LoudnessEnhancerTagNotSupported");
+ }
+ }
+}
+
+ndk::ScopedAStatus LoudnessEnhancerImpl::getParameterSpecific(const Parameter::Id& id,
+ Parameter::Specific* specific) {
+ RETURN_IF(!specific, EX_NULL_POINTER, "nullPtr");
+ auto tag = id.getTag();
+ RETURN_IF(Parameter::Id::loudnessEnhancerTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
+ auto leId = id.get<Parameter::Id::loudnessEnhancerTag>();
+ auto leIdTag = leId.getTag();
+ switch (leIdTag) {
+ case LoudnessEnhancer::Id::commonTag:
+ return getParameterLoudnessEnhancer(leId.get<LoudnessEnhancer::Id::commonTag>(),
+ specific);
+ default:
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(leIdTag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+ EX_ILLEGAL_ARGUMENT, "LoudnessEnhancerTagNotSupported");
+ }
+}
+
+ndk::ScopedAStatus LoudnessEnhancerImpl::getParameterLoudnessEnhancer(
+ const LoudnessEnhancer::Tag& tag, Parameter::Specific* specific) {
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+ LoudnessEnhancer leParam;
+ switch (tag) {
+ case LoudnessEnhancer::gainMb: {
+ leParam.set<LoudnessEnhancer::gainMb>(mContext->getLeGain());
+ break;
+ }
+ default: {
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+ EX_ILLEGAL_ARGUMENT, "LoudnessEnhancerTagNotSupported");
+ }
+ }
+
+ specific->set<Parameter::Specific::loudnessEnhancer>(leParam);
+ return ndk::ScopedAStatus::ok();
+}
+
+std::shared_ptr<EffectContext> LoudnessEnhancerImpl::createContext(
+ const Parameter::Common& common) {
+ if (mContext) {
+ LOG(DEBUG) << __func__ << " context already exist";
+ return mContext;
+ }
+
+ mContext = std::make_shared<LoudnessEnhancerContext>(1 /* statusFmqDepth */, common);
+ return mContext;
+}
+
+RetCode LoudnessEnhancerImpl::releaseContext() {
+ if (mContext) {
+ mContext->disable();
+ mContext->resetBuffer();
+ }
+ return RetCode::SUCCESS;
+}
+
+// Processing method running in EffectWorker thread.
+IEffect::Status LoudnessEnhancerImpl::effectProcessImpl(float* in, float* out, int samples) {
+ IEffect::Status status = {EX_NULL_POINTER, 0, 0};
+ RETURN_VALUE_IF(!mContext, status, "nullContext");
+ return mContext->lvmProcess(in, out, samples);
+}
+
+} // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/loudness/aidl/EffectLoudnessEnhancer.h b/media/libeffects/loudness/aidl/EffectLoudnessEnhancer.h
new file mode 100644
index 0000000..6402fd2
--- /dev/null
+++ b/media/libeffects/loudness/aidl/EffectLoudnessEnhancer.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2022 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 <aidl/android/hardware/audio/effect/BnEffect.h>
+
+#include "effect-impl/EffectImpl.h"
+#include "effect-impl/EffectUUID.h"
+#include "LoudnessEnhancerContext.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+class LoudnessEnhancerImpl final : public EffectImpl {
+ public:
+ static const std::string kEffectName;
+ static const Descriptor kDescriptor;
+ LoudnessEnhancerImpl() { LOG(DEBUG) << __func__; }
+ ~LoudnessEnhancerImpl() {
+ cleanUp();
+ LOG(DEBUG) << __func__;
+ }
+
+ ndk::ScopedAStatus commandImpl(CommandId command) override;
+ ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
+ ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
+ ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
+ Parameter::Specific* specific) override;
+ IEffect::Status effectProcessImpl(float* in, float* out, int process) override;
+ std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
+ RetCode releaseContext() override;
+
+ std::shared_ptr<EffectContext> getContext() override { return mContext; }
+ std::string getEffectName() override { return kEffectName; }
+
+ private:
+ std::shared_ptr<LoudnessEnhancerContext> mContext;
+ ndk::ScopedAStatus getParameterLoudnessEnhancer(const LoudnessEnhancer::Tag& tag,
+ Parameter::Specific* specific);
+};
+
+} // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/loudness/aidl/LoudnessEnhancerContext.cpp b/media/libeffects/loudness/aidl/LoudnessEnhancerContext.cpp
new file mode 100644
index 0000000..033b222
--- /dev/null
+++ b/media/libeffects/loudness/aidl/LoudnessEnhancerContext.cpp
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "LoudnessEnhancerContext.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+LoudnessEnhancerContext::LoudnessEnhancerContext(int statusDepth, const Parameter::Common& common)
+ : EffectContext(statusDepth, common) {
+ LOG(DEBUG) << __func__;
+ mState = LOUDNESS_ENHANCER_STATE_UNINITIALIZED;
+ mSampleRate = common.input.base.sampleRate;
+ init_params();
+}
+
+LoudnessEnhancerContext::~LoudnessEnhancerContext() {
+ LOG(DEBUG) << __func__;
+ mState = LOUDNESS_ENHANCER_STATE_UNINITIALIZED;
+}
+
+RetCode LoudnessEnhancerContext::enable() {
+ if (mState != LOUDNESS_ENHANCER_STATE_INITIALIZED) {
+ return RetCode::ERROR_EFFECT_LIB_ERROR;
+ }
+ mState = LOUDNESS_ENHANCER_STATE_ACTIVE;
+ return RetCode::SUCCESS;
+}
+
+RetCode LoudnessEnhancerContext::disable() {
+ if (mState != LOUDNESS_ENHANCER_STATE_ACTIVE) {
+ return RetCode::ERROR_EFFECT_LIB_ERROR;
+ }
+ mState = LOUDNESS_ENHANCER_STATE_INITIALIZED;
+ return RetCode::SUCCESS;
+}
+
+void LoudnessEnhancerContext::reset() {
+ float targetAmp = pow(10, mGain / 2000.0f); // mB to linear amplification
+ {
+ std::lock_guard lg(mMutex);
+ if (mCompressor != nullptr) {
+ // Get samplingRate from input
+ mCompressor->Initialize(targetAmp, mSampleRate);
+ }
+ }
+}
+
+RetCode LoudnessEnhancerContext::setLeGain(int gainMb) {
+ mGain = gainMb;
+ reset(); // apply parameter update
+ return RetCode::SUCCESS;
+}
+
+IEffect::Status LoudnessEnhancerContext::lvmProcess(float* in, float* out, int samples) {
+ LOG(DEBUG) << __func__ << " in " << in << " out " << out << " sample " << samples;
+
+ IEffect::Status status = {EX_NULL_POINTER, 0, 0};
+ RETURN_VALUE_IF(!in, status, "nullInput");
+ RETURN_VALUE_IF(!out, status, "nullOutput");
+ status = {EX_ILLEGAL_STATE, 0, 0};
+ RETURN_VALUE_IF(getInputFrameSize() != getOutputFrameSize(), status, "FrameSizeMismatch");
+ auto frameSize = getInputFrameSize();
+ RETURN_VALUE_IF(0 == frameSize, status, "zeroFrameSize");
+
+ LOG(DEBUG) << __func__ << " start processing";
+ {
+ std::lock_guard lg(mMutex);
+ // PcmType is always expected to be Float 32 bit.
+ constexpr float scale = 1 << 15; // power of 2 is lossless conversion to int16_t range
+ constexpr float inverseScale = 1.f / scale;
+ const float inputAmp = pow(10, mGain / 2000.0f) * scale;
+ float leftSample, rightSample;
+ if (mCompressor != nullptr) {
+ for (int inIdx = 0; inIdx < samples; inIdx += 2) {
+ // makeup gain is applied on the input of the compressor
+ leftSample = inputAmp * in[inIdx];
+ rightSample = inputAmp * in[inIdx + 1];
+ mCompressor->Compress(&leftSample, &rightSample);
+ in[inIdx] = leftSample * inverseScale;
+ in[inIdx + 1] = rightSample * inverseScale;
+ }
+ } else {
+ for (int inIdx = 0; inIdx < samples; inIdx += 2) {
+ leftSample = inputAmp * in[inIdx];
+ rightSample = inputAmp * in[inIdx + 1];
+ in[inIdx] = leftSample * inverseScale;
+ in[inIdx + 1] = rightSample * inverseScale;
+ }
+ }
+ bool accumulate = false;
+ if (in != out) {
+ for (int i = 0; i < samples; i++) {
+ if (accumulate) {
+ out[i] += in[i];
+ } else {
+ out[i] = in[i];
+ }
+ }
+ }
+ }
+ return {STATUS_OK, samples, samples};
+}
+
+void LoudnessEnhancerContext::init_params() {
+ mGain = LOUDNESS_ENHANCER_DEFAULT_TARGET_GAIN_MB;
+ float targetAmp = pow(10, mGain / 2000.0f); // mB to linear amplification
+ LOG(DEBUG) << __func__ << "Target gain = " << mGain << "mB <=> factor = " << targetAmp;
+
+ {
+ std::lock_guard lg(mMutex);
+ mCompressor = std::make_unique<le_fx::AdaptiveDynamicRangeCompression>();
+ mCompressor->Initialize(targetAmp, mSampleRate);
+ }
+ mState = LOUDNESS_ENHANCER_STATE_INITIALIZED;
+}
+
+} // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/loudness/aidl/LoudnessEnhancerContext.h b/media/libeffects/loudness/aidl/LoudnessEnhancerContext.h
new file mode 100644
index 0000000..b478b27
--- /dev/null
+++ b/media/libeffects/loudness/aidl/LoudnessEnhancerContext.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2022 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 <android-base/thread_annotations.h>
+#include <audio_effects/effect_loudnessenhancer.h>
+
+#include "dsp/core/dynamic_range_compression.h"
+#include "effect-impl/EffectContext.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+enum LoudnessEnhancerState {
+ LOUDNESS_ENHANCER_STATE_UNINITIALIZED,
+ LOUDNESS_ENHANCER_STATE_INITIALIZED,
+ LOUDNESS_ENHANCER_STATE_ACTIVE,
+};
+
+class LoudnessEnhancerContext final : public EffectContext {
+ public:
+ LoudnessEnhancerContext(int statusDepth, const Parameter::Common& common);
+ ~LoudnessEnhancerContext();
+
+ RetCode enable();
+ RetCode disable();
+ void reset();
+
+ RetCode setLeGain(int gainMb);
+ int getLeGain() const { return mGain; }
+
+ IEffect::Status lvmProcess(float* in, float* out, int samples);
+
+ private:
+ std::mutex mMutex;
+ LoudnessEnhancerState mState;
+ int mSampleRate;
+ int mGain;
+ // In this implementation, there is no coupling between the compression on the left and right
+ // channels
+ std::unique_ptr<le_fx::AdaptiveDynamicRangeCompression> mCompressor GUARDED_BY(mMutex);
+
+ void init_params();
+};
+} // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/lvm/tests/Android.bp b/media/libeffects/lvm/tests/Android.bp
index 7d7f8b9..0568fbd 100644
--- a/media/libeffects/lvm/tests/Android.bp
+++ b/media/libeffects/lvm/tests/Android.bp
@@ -11,48 +11,33 @@
cc_test {
name: "EffectReverbTest",
- vendor: true,
- gtest: true,
- host_supported: true,
+ defaults: [
+ "libeffects-test-defaults",
+ ],
srcs: [
"EffectReverbTest.cpp",
- "EffectTestHelper.cpp",
],
static_libs: [
- "libaudioutils",
"libreverb",
"libreverbwrapper",
],
- shared_libs: [
- "liblog",
- ],
header_libs: [
"libaudioeffects",
- "libhardware_headers",
],
}
cc_test {
name: "EffectBundleTest",
- vendor: true,
- gtest: true,
- host_supported: true,
- test_suites: ["device-tests"],
+ defaults: [
+ "libeffects-test-defaults",
+ ],
srcs: [
"EffectBundleTest.cpp",
- "EffectTestHelper.cpp",
],
static_libs: [
- "libaudioutils",
"libbundlewrapper",
"libmusicbundle",
],
- shared_libs: [
- "liblog",
- ],
- header_libs: [
- "libhardware_headers",
- ],
}
cc_test {
diff --git a/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp b/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp
new file mode 100644
index 0000000..c601c38
--- /dev/null
+++ b/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp
@@ -0,0 +1,808 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cstddef>
+#define LOG_TAG "BundleContext"
+#include <Utils.h>
+
+#include "BundleContext.h"
+#include "BundleTypes.h"
+#include "math.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+using aidl::android::media::audio::common::AudioDeviceDescription;
+using aidl::android::media::audio::common::AudioDeviceType;
+
+RetCode BundleContext::init() {
+ std::lock_guard lg(mMutex);
+ // init with pre-defined preset NORMAL
+ for (std::size_t i = 0; i < lvm::MAX_NUM_BANDS; i++) {
+ mBandGaindB[i] = lvm::kSoftPresets[0 /* normal */][i];
+ }
+
+ // allocate lvm instance
+ LVM_ReturnStatus_en status;
+ LVM_InstParams_t params = {.BufferMode = LVM_UNMANAGED_BUFFERS,
+ .MaxBlockSize = lvm::MAX_CALL_SIZE,
+ .EQNB_NumBands = lvm::MAX_NUM_BANDS,
+ .PSA_Included = LVM_PSA_ON};
+ status = LVM_GetInstanceHandle(&mInstance, ¶ms);
+ GOTO_IF_LVM_ERROR(status, deinit, "LVM_GetInstanceHandleFailed");
+
+ // set control
+ LVM_ControlParams_t controlParams;
+ initControlParameter(controlParams);
+ status = LVM_SetControlParameters(mInstance, &controlParams);
+ GOTO_IF_LVM_ERROR(status, deinit, "LVM_SetControlParametersFailed");
+
+ /* Set the headroom parameters */
+ LVM_HeadroomParams_t headroomParams;
+ initHeadroomParameter(headroomParams);
+ status = LVM_SetHeadroomParams(mInstance, &headroomParams);
+ GOTO_IF_LVM_ERROR(status, deinit, "LVM_SetHeadroomParamsFailed");
+
+ return RetCode::SUCCESS;
+
+deinit:
+ deInit();
+ return RetCode::ERROR_EFFECT_LIB_ERROR;
+}
+
+void BundleContext::deInit() {
+ std::lock_guard lg(mMutex);
+ if (mInstance) {
+ LVM_DelInstanceHandle(&mInstance);
+ mInstance = nullptr;
+ }
+}
+
+RetCode BundleContext::enable() {
+ if (mEnabled) return RetCode::ERROR_ILLEGAL_PARAMETER;
+ // Bass boost or Virtualizer can be temporarily disabled if playing over device speaker due to
+ // their nature.
+ bool tempDisabled = false;
+ switch (mType) {
+ case lvm::BundleEffectType::EQUALIZER:
+ LOG(DEBUG) << __func__ << " enable bundle EQ";
+ if (mSamplesToExitCountEq <= 0) mNumberEffectsEnabled++;
+ mSamplesToExitCountEq = (mSamplesPerSecond * 0.1);
+ mEffectInDrain &= ~(1 << int(lvm::BundleEffectType::EQUALIZER));
+ break;
+ case lvm::BundleEffectType::BASS_BOOST:
+ LOG(DEBUG) << __func__ << " enable bundle BB";
+ if (mSamplesToExitCountBb <= 0) mNumberEffectsEnabled++;
+ mEffectInDrain &= ~(1 << int(lvm::BundleEffectType::BASS_BOOST));
+ mSamplesToExitCountBb = (mSamplesPerSecond * 0.1);
+ tempDisabled = mBassTempDisabled;
+ break;
+ case lvm::BundleEffectType::VIRTUALIZER:
+ LOG(DEBUG) << __func__ << " enable bundle VR";
+ if (mSamplesToExitCountVirt <= 0) mNumberEffectsEnabled++;
+ mEffectInDrain &= ~(1 << int(lvm::BundleEffectType::VIRTUALIZER));
+ mSamplesToExitCountVirt = (mSamplesPerSecond * 0.1);
+ tempDisabled = mVirtualizerTempDisabled;
+ break;
+ case lvm::BundleEffectType::VOLUME:
+ LOG(DEBUG) << __func__ << " enable bundle VOL";
+ if ((mEffectInDrain & (1 << int(lvm::BundleEffectType::VOLUME))) == 0)
+ mNumberEffectsEnabled++;
+ mEffectInDrain &= ~(1 << int(lvm::BundleEffectType::VOLUME));
+ break;
+ }
+ mEnabled = true;
+ return (tempDisabled ? RetCode::SUCCESS : enableOperatingMode());
+}
+
+RetCode BundleContext::enableOperatingMode() {
+ LVM_ControlParams_t params;
+ {
+ std::lock_guard lg(mMutex);
+ RETURN_VALUE_IF(LVM_SUCCESS != LVM_GetControlParameters(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, "failGetControlParams");
+ switch (mType) {
+ case lvm::BundleEffectType::EQUALIZER:
+ LOG(DEBUG) << __func__ << " enable bundle EQ";
+ params.EQNB_OperatingMode = LVM_EQNB_ON;
+ break;
+ case lvm::BundleEffectType::BASS_BOOST:
+ LOG(DEBUG) << __func__ << " enable bundle BB";
+ params.BE_OperatingMode = LVM_BE_ON;
+ break;
+ case lvm::BundleEffectType::VIRTUALIZER:
+ LOG(DEBUG) << __func__ << " enable bundle VR";
+ params.VirtualizerOperatingMode = LVM_MODE_ON;
+ break;
+ case lvm::BundleEffectType::VOLUME:
+ LOG(DEBUG) << __func__ << " enable bundle VOL";
+ break;
+ }
+ RETURN_VALUE_IF(LVM_SUCCESS != LVM_SetControlParameters(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, "failSetControlParams");
+ }
+ return limitLevel();
+}
+
+RetCode BundleContext::disable() {
+ if (!mEnabled) return RetCode::ERROR_ILLEGAL_PARAMETER;
+ switch (mType) {
+ case lvm::BundleEffectType::EQUALIZER:
+ LOG(DEBUG) << __func__ << " disable bundle EQ";
+ mEffectInDrain |= 1 << int(lvm::BundleEffectType::EQUALIZER);
+ break;
+ case lvm::BundleEffectType::BASS_BOOST:
+ LOG(DEBUG) << __func__ << " disable bundle BB";
+ mEffectInDrain |= 1 << int(lvm::BundleEffectType::BASS_BOOST);
+ break;
+ case lvm::BundleEffectType::VIRTUALIZER:
+ LOG(DEBUG) << __func__ << " disable bundle VR";
+ mEffectInDrain |= 1 << int(lvm::BundleEffectType::VIRTUALIZER);
+ break;
+ case lvm::BundleEffectType::VOLUME:
+ LOG(DEBUG) << __func__ << " disable bundle VOL";
+ mEffectInDrain |= 1 << int(lvm::BundleEffectType::VOLUME);
+ break;
+ }
+ mEnabled = false;
+ return disableOperatingMode();
+}
+
+RetCode BundleContext::disableOperatingMode() {
+ LVM_ControlParams_t params;
+ {
+ std::lock_guard lg(mMutex);
+ RETURN_VALUE_IF(LVM_SUCCESS != LVM_GetControlParameters(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, "failGetControlParams");
+ switch (mType) {
+ case lvm::BundleEffectType::EQUALIZER:
+ LOG(DEBUG) << __func__ << " disable bundle EQ";
+ params.EQNB_OperatingMode = LVM_EQNB_OFF;
+ break;
+ case lvm::BundleEffectType::BASS_BOOST:
+ LOG(DEBUG) << __func__ << " disable bundle BB";
+ params.BE_OperatingMode = LVM_BE_OFF;
+ break;
+ case lvm::BundleEffectType::VIRTUALIZER:
+ LOG(DEBUG) << __func__ << " disable bundle VR";
+ params.VirtualizerOperatingMode = LVM_MODE_OFF;
+ break;
+ case lvm::BundleEffectType::VOLUME:
+ LOG(DEBUG) << __func__ << " disable bundle VOL";
+ break;
+ }
+ RETURN_VALUE_IF(LVM_SUCCESS != LVM_SetControlParameters(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, "failSetControlParams");
+ }
+ mEnabled = false;
+ return limitLevel();
+}
+
+RetCode BundleContext::limitLevel() {
+ int gainCorrection = 0;
+ // Count the energy contribution per band for EQ and BassBoost only if they are active.
+ float energyContribution = 0;
+ float energyCross = 0;
+ float energyBassBoost = 0;
+ float crossCorrection = 0;
+ LVM_ControlParams_t params;
+ {
+ std::lock_guard lg(mMutex);
+ RETURN_VALUE_IF(LVM_SUCCESS != LVM_GetControlParameters(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, " getControlParamFailed");
+
+ bool eqEnabled = params.EQNB_OperatingMode == LVM_EQNB_ON;
+ bool bbEnabled = params.BE_OperatingMode == LVM_BE_ON;
+ bool viEnabled = params.VirtualizerOperatingMode == LVM_MODE_ON;
+
+ if (eqEnabled) {
+ for (int i = 0; i < lvm::MAX_NUM_BANDS; i++) {
+ float bandFactor = mBandGaindB[i] / 15.0;
+ float bandCoefficient = lvm::kBandEnergyCoefficient[i];
+ float bandEnergy = bandFactor * bandCoefficient * bandCoefficient;
+ if (bandEnergy > 0) energyContribution += bandEnergy;
+ }
+
+ // cross EQ coefficients
+ float bandFactorSum = 0;
+ for (int i = 0; i < lvm::MAX_NUM_BANDS - 1; i++) {
+ float bandFactor1 = mBandGaindB[i] / 15.0;
+ float bandFactor2 = mBandGaindB[i + 1] / 15.0;
+
+ if (bandFactor1 > 0 && bandFactor2 > 0) {
+ float crossEnergy =
+ bandFactor1 * bandFactor2 * lvm::kBandEnergyCrossCoefficient[i];
+ bandFactorSum += bandFactor1 * bandFactor2;
+
+ if (crossEnergy > 0) energyCross += crossEnergy;
+ }
+ }
+ bandFactorSum -= 1.0;
+ if (bandFactorSum > 0) crossCorrection = bandFactorSum * 0.7;
+ }
+ // BassBoost contribution
+ if (bbEnabled) {
+ float boostFactor = mBassStrengthSaved / 1000.0;
+ float boostCoefficient = lvm::kBassBoostEnergyCoefficient;
+
+ energyContribution += boostFactor * boostCoefficient * boostCoefficient;
+
+ if (eqEnabled) {
+ for (int i = 0; i < lvm::MAX_NUM_BANDS; i++) {
+ float bandFactor = mBandGaindB[i] / 15.0;
+ float bandCrossCoefficient = lvm::kBassBoostEnergyCrossCoefficient[i];
+ float bandEnergy = boostFactor * bandFactor * bandCrossCoefficient;
+ if (bandEnergy > 0) energyBassBoost += bandEnergy;
+ }
+ }
+ }
+ // Virtualizer contribution
+ if (viEnabled) {
+ energyContribution += lvm::kVirtualizerContribution * lvm::kVirtualizerContribution;
+ }
+
+ double totalEnergyEstimation =
+ sqrt(energyContribution + energyCross + energyBassBoost) - crossCorrection;
+ LOG(INFO) << " TOTAL energy estimation: " << totalEnergyEstimation << " dB";
+
+ // roundoff
+ int maxLevelRound = (int)(totalEnergyEstimation + 0.99);
+ if (maxLevelRound + mVolume > 0) {
+ gainCorrection = maxLevelRound + mVolume;
+ }
+
+ params.VC_EffectLevel = mVolume - gainCorrection;
+ if (params.VC_EffectLevel < -96) {
+ params.VC_EffectLevel = -96;
+ }
+ LOG(INFO) << "\tVol: " << mVolume << ", GainCorrection: " << gainCorrection
+ << ", Actual vol: " << params.VC_EffectLevel;
+
+ /* Activate the initial settings */
+ RETURN_VALUE_IF(LVM_SUCCESS != LVM_SetControlParameters(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, " setControlParamFailed");
+
+ if (mFirstVolume) {
+ RETURN_VALUE_IF(LVM_SUCCESS != LVM_SetVolumeNoSmoothing(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, " setVolumeNoSmoothingFailed");
+ LOG(INFO) << "\tLVM_VOLUME: Disabling Smoothing for first volume change to remove "
+ "spikes/clicks";
+ mFirstVolume = false;
+ }
+ }
+
+ return RetCode::SUCCESS;
+}
+
+bool BundleContext::isDeviceSupportedBassBoost(
+ const std::vector<aidl::android::media::audio::common::AudioDeviceDescription>& devices) {
+ for (const auto& device : devices) {
+ if (device != AudioDeviceDescription{AudioDeviceType::OUT_SPEAKER, ""} &&
+ device != AudioDeviceDescription{AudioDeviceType::OUT_CARKIT,
+ AudioDeviceDescription::CONNECTION_BT_SCO} &&
+ device != AudioDeviceDescription{AudioDeviceType::OUT_SPEAKER,
+ AudioDeviceDescription::CONNECTION_BT_A2DP}) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool BundleContext::isDeviceSupportedVirtualizer(
+ const std::vector<aidl::android::media::audio::common::AudioDeviceDescription>& devices) {
+ for (const auto& device : devices) {
+ if (device != AudioDeviceDescription{AudioDeviceType::OUT_HEADSET,
+ AudioDeviceDescription::CONNECTION_ANALOG} &&
+ device != AudioDeviceDescription{AudioDeviceType::OUT_HEADPHONE,
+ AudioDeviceDescription::CONNECTION_ANALOG} &&
+ device != AudioDeviceDescription{AudioDeviceType::OUT_HEADPHONE,
+ AudioDeviceDescription::CONNECTION_BT_A2DP} &&
+ device != AudioDeviceDescription{AudioDeviceType::OUT_HEADSET,
+ AudioDeviceDescription::CONNECTION_USB}) {
+ return false;
+ }
+ }
+ return true;
+}
+
+RetCode BundleContext::setOutputDevice(
+ const std::vector<aidl::android::media::audio::common::AudioDeviceDescription>& devices) {
+ mOutputDevice = devices;
+ switch (mType) {
+ case lvm::BundleEffectType::BASS_BOOST:
+ if (!isDeviceSupportedBassBoost(devices)) {
+ // If a device doesn't support bass boost, the effect must be temporarily disabled.
+ // The effect must still report its original state as this can only be changed by
+ // the start/stop commands.
+ if (mEnabled) {
+ disableOperatingMode();
+ }
+ mBassTempDisabled = true;
+ } else {
+ // If a device supports bass boost and the effect has been temporarily disabled
+ // previously then re-enable it
+ if (!mEnabled) {
+ enableOperatingMode();
+ }
+ mBassTempDisabled = false;
+ }
+ break;
+ case lvm::BundleEffectType::VIRTUALIZER:
+ if (!isDeviceSupportedVirtualizer(devices)) {
+ if (mEnabled) {
+ disableOperatingMode();
+ }
+ mVirtualizerTempDisabled = true;
+ } else {
+ if (!mEnabled) {
+ enableOperatingMode();
+ }
+ mVirtualizerTempDisabled = false;
+ }
+ break;
+ default:
+ break;
+ }
+ return RetCode::SUCCESS;
+}
+
+LVM_INT16 BundleContext::LVC_ToDB_s32Tos16(LVM_INT32 Lin_fix) const {
+ LVM_INT16 db_fix;
+ LVM_INT16 Shift;
+ LVM_INT16 SmallRemainder;
+ LVM_UINT32 Remainder = (LVM_UINT32)Lin_fix;
+
+ /* Count leading bits, 1 cycle in assembly*/
+ for (Shift = 0; Shift < 32; Shift++) {
+ if ((Remainder & 0x80000000U) != 0) {
+ break;
+ }
+ Remainder = Remainder << 1;
+ }
+
+ /*
+ * Based on the approximation equation (for Q11.4 format):
+ *
+ * dB = -96 * Shift + 16 * (8 * Remainder - 2 * Remainder^2)
+ */
+ db_fix = (LVM_INT16)(-96 * Shift); /* Six dB steps in Q11.4 format*/
+ SmallRemainder = (LVM_INT16)((Remainder & 0x7fffffff) >> 24);
+ db_fix = (LVM_INT16)(db_fix + SmallRemainder);
+ SmallRemainder = (LVM_INT16)(SmallRemainder * SmallRemainder);
+ db_fix = (LVM_INT16)(db_fix - (LVM_INT16)((LVM_UINT16)SmallRemainder >> 9));
+
+ /* Correct for small offset */
+ db_fix = (LVM_INT16)(db_fix - 5);
+
+ return db_fix;
+}
+
+// TODO: replace with more generic approach, like: audio_utils_power_from_amplitude
+int16_t BundleContext::VolToDb(uint32_t vol) const {
+ int16_t dB;
+
+ dB = LVC_ToDB_s32Tos16(vol << 7);
+ dB = (dB + 8) >> 4;
+ dB = (dB < -96) ? -96 : dB;
+
+ return dB;
+}
+
+RetCode BundleContext::setVolumeStereo(const Parameter::VolumeStereo& volume) {
+ LVM_ControlParams_t params;
+ LVM_ReturnStatus_en status = LVM_SUCCESS;
+
+ // Convert volume to dB
+ int leftdB = VolToDb(volume.left);
+ int rightdB = VolToDb(volume.right);
+ int maxdB = std::max(leftdB, rightdB);
+ int pandB = rightdB - leftdB;
+ setVolumeLevel(maxdB * 100);
+ LOG(DEBUG) << __func__ << " pandB: " << pandB << " maxdB " << maxdB;
+
+ {
+ std::lock_guard lg(mMutex);
+ RETURN_VALUE_IF(LVM_SUCCESS != LVM_GetControlParameters(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, "");
+ params.VC_Balance = pandB;
+
+ RETURN_VALUE_IF(LVM_SUCCESS != LVM_SetControlParameters(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, "");
+ }
+ mVolumeStereo = volume;
+ return RetCode::SUCCESS;
+}
+
+RetCode BundleContext::setEqualizerPreset(const std::size_t presetIdx) {
+ if (presetIdx < 0 || presetIdx >= lvm::MAX_NUM_PRESETS) {
+ return RetCode::ERROR_ILLEGAL_PARAMETER;
+ }
+
+ std::vector<Equalizer::BandLevel> bandLevels;
+ bandLevels.reserve(lvm::MAX_NUM_BANDS);
+ for (std::size_t i = 0; i < lvm::MAX_NUM_BANDS; i++) {
+ bandLevels.emplace_back(
+ Equalizer::BandLevel{static_cast<int32_t>(i), lvm::kSoftPresets[presetIdx][i]});
+ }
+
+ RetCode ret = updateControlParameter(bandLevels);
+ if (RetCode::SUCCESS == ret) {
+ mCurPresetIdx = presetIdx;
+ LOG(INFO) << __func__ << " success with " << presetIdx;
+ } else {
+ LOG(ERROR) << __func__ << " failed to setPreset " << presetIdx;
+ }
+ return ret;
+}
+
+RetCode BundleContext::setEqualizerBandLevels(const std::vector<Equalizer::BandLevel>& bandLevels) {
+ RETURN_VALUE_IF(bandLevels.size() > lvm::MAX_NUM_BANDS || bandLevels.empty(),
+ RetCode::ERROR_ILLEGAL_PARAMETER, "sizeExceedMax");
+ RetCode ret = updateControlParameter(bandLevels);
+ if (RetCode::SUCCESS == ret) {
+ mCurPresetIdx = lvm::PRESET_CUSTOM;
+ LOG(INFO) << __func__ << " succeed with " << ::android::internal::ToString(bandLevels);
+ } else {
+ LOG(ERROR) << __func__ << " failed with " << ::android::internal::ToString(bandLevels);
+ }
+ return ret;
+}
+
+std::vector<Equalizer::BandLevel> BundleContext::getEqualizerBandLevels() const {
+ std::vector<Equalizer::BandLevel> bandLevels;
+ bandLevels.reserve(lvm::MAX_NUM_BANDS);
+ for (std::size_t i = 0; i < lvm::MAX_NUM_BANDS; i++) {
+ bandLevels.emplace_back(Equalizer::BandLevel{static_cast<int32_t>(i), mBandGaindB[i]});
+ }
+ return bandLevels;
+}
+
+bool BundleContext::isBandLevelIndexInRange(
+ const std::vector<Equalizer::BandLevel>& bandLevels) const {
+ const auto [min, max] =
+ std::minmax_element(bandLevels.begin(), bandLevels.end(),
+ [](const auto& a, const auto& b) { return a.index < b.index; });
+ return min->index >= 0 && max->index < lvm::MAX_NUM_BANDS;
+}
+
+RetCode BundleContext::updateControlParameter(const std::vector<Equalizer::BandLevel>& bandLevels) {
+ RETURN_VALUE_IF(!isBandLevelIndexInRange(bandLevels), RetCode::ERROR_ILLEGAL_PARAMETER,
+ "indexOutOfRange");
+
+ std::array<int, lvm::MAX_NUM_BANDS> tempLevel;
+ for (const auto& it : bandLevels) {
+ tempLevel[it.index] = it.levelMb;
+ }
+
+ LVM_ControlParams_t params;
+ {
+ std::lock_guard lg(mMutex);
+ RETURN_VALUE_IF(LVM_SUCCESS != LVM_GetControlParameters(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, " getControlParamFailed");
+
+ for (std::size_t i = 0; i < lvm::MAX_NUM_BANDS; i++) {
+ params.pEQNB_BandDefinition[i].Frequency = lvm::kPresetsFrequencies[i];
+ params.pEQNB_BandDefinition[i].QFactor = lvm::kPresetsQFactors[i];
+ params.pEQNB_BandDefinition[i].Gain = tempLevel[i];
+ }
+
+ RETURN_VALUE_IF(LVM_SUCCESS != LVM_SetControlParameters(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, " setControlParamFailed");
+ }
+ mBandGaindB = tempLevel;
+ LOG(INFO) << __func__ << " update bandGain to " << ::android::internal::ToString(mBandGaindB);
+
+ return RetCode::SUCCESS;
+}
+
+RetCode BundleContext::setBassBoostStrength(int strength) {
+ if (strength < 0 || strength > lvm::kBassBoostCap.maxStrengthPm) {
+ LOG(ERROR) << __func__ << " invalid strength: " << strength;
+ return RetCode::ERROR_ILLEGAL_PARAMETER;
+ }
+
+ // Update Control Parameter
+ LVM_ControlParams_t params;
+ {
+ std::lock_guard lg(mMutex);
+ RETURN_VALUE_IF(LVM_SUCCESS != LVM_GetControlParameters(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, " getControlParamFailed");
+
+ params.BE_EffectLevel = (LVM_INT16)((15 * strength) / 1000);
+ params.BE_CentreFreq = LVM_BE_CENTRE_90Hz;
+
+ RETURN_VALUE_IF(LVM_SUCCESS != LVM_SetControlParameters(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, " setControlParamFailed");
+ }
+ mBassStrengthSaved = strength;
+ LOG(INFO) << __func__ << " success with strength " << strength;
+ return limitLevel();
+}
+
+RetCode BundleContext::setVolumeLevel(int level) {
+ if (level < lvm::kVolumeCap.minLevelDb || level > lvm::kVolumeCap.maxLevelDb) {
+ return RetCode::ERROR_ILLEGAL_PARAMETER;
+ }
+
+ if (mMuteEnabled) {
+ mLevelSaved = level / 100;
+ } else {
+ mVolume = level / 100;
+ }
+ LOG(INFO) << __func__ << " success with level " << level;
+ return limitLevel();
+}
+
+int BundleContext::getVolumeLevel() const {
+ return (mMuteEnabled ? mLevelSaved * 100 : mVolume * 100);
+}
+
+RetCode BundleContext::setVolumeMute(bool mute) {
+ mMuteEnabled = mute;
+ if (mMuteEnabled) {
+ mLevelSaved = mVolume;
+ mVolume = -96;
+ } else {
+ mVolume = mLevelSaved;
+ }
+ return limitLevel();
+}
+
+RetCode BundleContext::setVirtualizerStrength(int strength) {
+ if (strength < 0 || strength > lvm::kVirtualizerCap.maxStrengthPm) {
+ return RetCode::ERROR_ILLEGAL_PARAMETER;
+ }
+
+ // Update Control Parameter
+ LVM_ControlParams_t params;
+ {
+ std::lock_guard lg(mMutex);
+ RETURN_VALUE_IF(LVM_SUCCESS != LVM_GetControlParameters(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, " getControlParamFailed");
+
+ params.CS_EffectLevel = ((strength * 32767) / 1000);
+
+ RETURN_VALUE_IF(LVM_SUCCESS != LVM_SetControlParameters(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, " setControlParamFailed");
+ }
+
+ mVirtStrengthSaved = strength;
+ LOG(INFO) << __func__ << " success with strength " << strength;
+ return limitLevel();
+}
+
+void BundleContext::initControlParameter(LVM_ControlParams_t& params) const {
+ /* General parameters */
+ params.OperatingMode = LVM_MODE_ON;
+ params.SampleRate = LVM_FS_44100;
+ params.SourceFormat = LVM_STEREO;
+ params.SpeakerType = LVM_HEADPHONES;
+
+ /* Concert Sound parameters */
+ params.VirtualizerOperatingMode = LVM_MODE_OFF;
+ params.VirtualizerType = LVM_CONCERTSOUND;
+ params.VirtualizerReverbLevel = 100;
+ params.CS_EffectLevel = LVM_CS_EFFECT_NONE;
+
+ params.EQNB_OperatingMode = LVM_EQNB_OFF;
+ params.EQNB_NBands = lvm::MAX_NUM_BANDS;
+ params.pEQNB_BandDefinition = getDefaultEqualizerBandDefs();
+
+ /* Volume Control parameters */
+ params.VC_EffectLevel = 0;
+ params.VC_Balance = 0;
+
+ /* Treble Enhancement parameters */
+ params.TE_OperatingMode = LVM_TE_OFF;
+ params.TE_EffectLevel = 0;
+
+ /* PSA Control parameters */
+ params.PSA_Enable = LVM_PSA_OFF;
+ params.PSA_PeakDecayRate = (LVM_PSA_DecaySpeed_en)0;
+
+ /* Bass Enhancement parameters */
+ params.BE_OperatingMode = LVM_BE_OFF;
+ params.BE_EffectLevel = 0;
+ params.BE_CentreFreq = LVM_BE_CENTRE_90Hz;
+ params.BE_HPF = LVM_BE_HPF_ON;
+
+ /* PSA Control parameters */
+ params.PSA_Enable = LVM_PSA_OFF;
+ params.PSA_PeakDecayRate = LVM_PSA_SPEED_MEDIUM;
+
+ /* TE Control parameters */
+ params.TE_OperatingMode = LVM_TE_OFF;
+ params.TE_EffectLevel = 0;
+
+ params.NrChannels = audio_channel_count_from_out_mask(AUDIO_CHANNEL_OUT_STEREO);
+ params.ChMask = AUDIO_CHANNEL_OUT_STEREO;
+ params.SourceFormat = LVM_STEREO;
+}
+
+void BundleContext::initHeadroomParameter(LVM_HeadroomParams_t& params) const {
+ params.pHeadroomDefinition = getDefaultEqualizerHeadroomBanDefs();
+ params.NHeadroomBands = 2;
+ params.Headroom_OperatingMode = LVM_HEADROOM_OFF;
+}
+
+LVM_EQNB_BandDef_t *BundleContext::getDefaultEqualizerBandDefs() {
+ static LVM_EQNB_BandDef_t* BandDefs = []() {
+ static LVM_EQNB_BandDef_t tempDefs[lvm::MAX_NUM_BANDS];
+ /* N-Band Equaliser parameters */
+ for (std::size_t i = 0; i < lvm::MAX_NUM_BANDS; i++) {
+ tempDefs[i].Frequency = lvm::kPresetsFrequencies[i];
+ tempDefs[i].QFactor = lvm::kPresetsQFactors[i];
+ tempDefs[i].Gain = lvm::kSoftPresets[0/* normal */][i];
+ }
+ return tempDefs;
+ }();
+
+ return BandDefs;
+}
+
+LVM_HeadroomBandDef_t *BundleContext::getDefaultEqualizerHeadroomBanDefs() {
+ static LVM_HeadroomBandDef_t HeadroomBandDef[LVM_HEADROOM_MAX_NBANDS] = {
+ {
+ .Limit_Low = 20,
+ .Limit_High = 4999,
+ .Headroom_Offset = 0,
+ },
+ {
+ .Limit_Low = 5000,
+ .Limit_High = 24000,
+ .Headroom_Offset = 0,
+ },
+ };
+ return HeadroomBandDef;
+}
+
+IEffect::Status BundleContext::lvmProcess(float* in, float* out, int samples) {
+ IEffect::Status status = {EX_NULL_POINTER, 0, 0};
+ RETURN_VALUE_IF(!in, status, "nullInput");
+ RETURN_VALUE_IF(!out, status, "nullOutput");
+ status = {EX_ILLEGAL_STATE, 0, 0};
+ int64_t inputFrameCount = getCommon().input.frameCount;
+ int64_t outputFrameCount = getCommon().output.frameCount;
+ RETURN_VALUE_IF(inputFrameCount != outputFrameCount, status, "FrameCountMismatch");
+ int isDataAvailable = true;
+
+ auto frameSize = getInputFrameSize();
+ RETURN_VALUE_IF(0 == frameSize, status, "zeroFrameSize");
+
+ LOG(DEBUG) << __func__ << " start processing";
+ if ((mEffectProcessCalled & 1 << int(mType)) != 0) {
+ const int undrainedEffects = mEffectInDrain & ~mEffectProcessCalled;
+ if ((undrainedEffects & 1 << int(lvm::BundleEffectType::EQUALIZER)) != 0) {
+ LOG(DEBUG) << "Draining EQUALIZER";
+ mSamplesToExitCountEq = 0;
+ --mNumberEffectsEnabled;
+ mEffectInDrain &= ~(1 << int(lvm::BundleEffectType::EQUALIZER));
+ }
+ if ((undrainedEffects & 1 << int(lvm::BundleEffectType::BASS_BOOST)) != 0) {
+ LOG(DEBUG) << "Draining BASS_BOOST";
+ mSamplesToExitCountBb = 0;
+ --mNumberEffectsEnabled;
+ mEffectInDrain &= ~(1 << int(lvm::BundleEffectType::BASS_BOOST));
+ }
+ if ((undrainedEffects & 1 << int(lvm::BundleEffectType::VIRTUALIZER)) != 0) {
+ LOG(DEBUG) << "Draining VIRTUALIZER";
+ mSamplesToExitCountVirt = 0;
+ --mNumberEffectsEnabled;
+ mEffectInDrain &= ~(1 << int(lvm::BundleEffectType::VIRTUALIZER));
+ }
+ if ((undrainedEffects & 1 << int(lvm::BundleEffectType::VOLUME)) != 0) {
+ LOG(DEBUG) << "Draining VOLUME";
+ --mNumberEffectsEnabled;
+ mEffectInDrain &= ~(1 << int(lvm::BundleEffectType::VOLUME));
+ }
+ }
+ mEffectProcessCalled |= 1 << int(mType);
+ if (!mEnabled) {
+ switch (mType) {
+ case lvm::BundleEffectType::EQUALIZER:
+ if (mSamplesToExitCountEq > 0) {
+ mSamplesToExitCountEq -= samples;
+ }
+ if (mSamplesToExitCountEq <= 0) {
+ isDataAvailable = false;
+ if ((mEffectInDrain & 1 << int(lvm::BundleEffectType::EQUALIZER)) != 0) {
+ mNumberEffectsEnabled--;
+ mEffectInDrain &= ~(1 << int(lvm::BundleEffectType::EQUALIZER));
+ }
+ LOG(DEBUG) << "Effect_process() this is the last frame for EQUALIZER";
+ }
+ break;
+ case lvm::BundleEffectType::BASS_BOOST:
+ if (mSamplesToExitCountBb > 0) {
+ mSamplesToExitCountBb -= samples;
+ }
+ if (mSamplesToExitCountBb <= 0) {
+ isDataAvailable = false;
+ if ((mEffectInDrain & 1 << int(lvm::BundleEffectType::BASS_BOOST)) != 0) {
+ mNumberEffectsEnabled--;
+ mEffectInDrain &= ~(1 << int(lvm::BundleEffectType::BASS_BOOST));
+ }
+ LOG(DEBUG) << "Effect_process() this is the last frame for BASS_BOOST";
+ }
+ break;
+ case lvm::BundleEffectType::VIRTUALIZER:
+ if (mSamplesToExitCountVirt > 0) {
+ mSamplesToExitCountVirt -= samples;
+ }
+ if (mSamplesToExitCountVirt <= 0) {
+ isDataAvailable = false;
+ if ((mEffectInDrain & 1 << int(lvm::BundleEffectType::VIRTUALIZER)) != 0) {
+ mNumberEffectsEnabled--;
+ mEffectInDrain &= ~(1 << int(lvm::BundleEffectType::VIRTUALIZER));
+ }
+ LOG(DEBUG) << "Effect_process() this is the last frame for VIRTUALIZER";
+ }
+ break;
+ case lvm::BundleEffectType::VOLUME:
+ isDataAvailable = false;
+ if ((mEffectInDrain & 1 << int(lvm::BundleEffectType::VOLUME)) != 0) {
+ mNumberEffectsEnabled--;
+ mEffectInDrain &= ~(1 << int(lvm::BundleEffectType::VOLUME));
+ }
+ LOG(DEBUG) << "Effect_process() LVM_VOLUME Effect is not enabled";
+ break;
+ }
+ }
+ if (isDataAvailable) {
+ mNumberEffectsCalled++;
+ }
+ bool accumulate = false;
+ if (mNumberEffectsCalled >= mNumberEffectsEnabled) {
+ // We expect the # effects called to be equal to # effects enabled in sequence (including
+ // draining effects). Warn if this is not the case due to inconsistent calls.
+ ALOGW_IF(mNumberEffectsCalled > mNumberEffectsEnabled,
+ "%s Number of effects called %d is greater than number of effects enabled %d",
+ __func__, mNumberEffectsCalled, mNumberEffectsEnabled);
+ mEffectProcessCalled = 0; // reset our consistency check.
+ if (!isDataAvailable) {
+ LOG(DEBUG) << "Effect_process() processing last frame";
+ }
+ mNumberEffectsCalled = 0;
+ LVM_UINT16 frames = samples * sizeof(float) / frameSize;
+ float* outTmp = (accumulate ? getWorkBuffer() : out);
+ /* Process the samples */
+ LVM_ReturnStatus_en lvmStatus;
+ {
+ std::lock_guard lg(mMutex);
+ lvmStatus = LVM_Process(mInstance, in, outTmp, frames, 0);
+ if (lvmStatus != LVM_SUCCESS) {
+ LOG(ERROR) << __func__ << lvmStatus;
+ return {EX_UNSUPPORTED_OPERATION, 0, 0};
+ }
+ if (accumulate) {
+ for (int i = 0; i < samples; i++) {
+ out[i] += outTmp[i];
+ }
+ }
+ }
+ } else {
+ for (int i = 0; i < samples; i++) {
+ if (accumulate) {
+ out[i] += in[i];
+ } else {
+ out[i] = in[i];
+ }
+ }
+ }
+ LOG(DEBUG) << __func__ << " done processing";
+ return {STATUS_OK, samples, samples};
+}
+
+} // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/lvm/wrapper/Aidl/BundleContext.h b/media/libeffects/lvm/wrapper/Aidl/BundleContext.h
new file mode 100644
index 0000000..1f328fc
--- /dev/null
+++ b/media/libeffects/lvm/wrapper/Aidl/BundleContext.h
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2022 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 <android-base/logging.h>
+#include <android-base/thread_annotations.h>
+#include <array>
+#include <cstddef>
+
+#include "BundleTypes.h"
+#include "effect-impl/EffectContext.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+class BundleContext final : public EffectContext {
+ public:
+ BundleContext(int statusDepth, const Parameter::Common& common,
+ const lvm::BundleEffectType& type)
+ : EffectContext(statusDepth, common), mType(type) {
+ LOG(DEBUG) << __func__ << type;
+ }
+ ~BundleContext() override {
+ LOG(DEBUG) << __func__;
+ deInit();
+ }
+
+ RetCode init();
+ void deInit();
+ lvm::BundleEffectType getBundleType() const { return mType; }
+
+ RetCode enable();
+ RetCode enableOperatingMode();
+ RetCode disable();
+ RetCode disableOperatingMode();
+
+ void setSampleRate(const int sampleRate) { mSampleRate = sampleRate; }
+ int getSampleRate() const { return mSampleRate; }
+
+ void setChannelMask(const aidl::android::media::audio::common::AudioChannelLayout& chMask) {
+ mChMask = chMask;
+ }
+ aidl::android::media::audio::common::AudioChannelLayout getChannelMask() const {
+ return mChMask;
+ }
+ bool isDeviceSupportedBassBoost(
+ const std::vector<aidl::android::media::audio::common::AudioDeviceDescription>&
+ devices);
+ bool isDeviceSupportedVirtualizer(
+ const std::vector<aidl::android::media::audio::common::AudioDeviceDescription>&
+ devices);
+ RetCode setOutputDevice(
+ const std::vector<aidl::android::media::audio::common::AudioDeviceDescription>& devices)
+ override;
+
+ RetCode setEqualizerPreset(const std::size_t presetIdx);
+ int getEqualizerPreset() const { return mCurPresetIdx; }
+ RetCode setEqualizerBandLevels(const std::vector<Equalizer::BandLevel>& bandLevels);
+ std::vector<Equalizer::BandLevel> getEqualizerBandLevels() const;
+
+ RetCode setBassBoostStrength(int strength);
+ int getBassBoostStrength() const { return mBassStrengthSaved; }
+
+ RetCode setVolumeLevel(int level);
+ int getVolumeLevel() const;
+
+ RetCode setVolumeMute(bool mute);
+ int getVolumeMute() const { return mMuteEnabled; }
+
+ RetCode setVirtualizerStrength(int strength);
+ int getVirtualizerStrength() const { return mVirtStrengthSaved; }
+
+ RetCode setVolumeStereo(const Parameter::VolumeStereo& volumeStereo) override;
+ Parameter::VolumeStereo getVolumeStereo() override { return mVolumeStereo; }
+
+ IEffect::Status lvmProcess(float* in, float* out, int samples);
+
+ IEffect::Status processEffect(float* in, float* out, int sampleToProcess);
+
+ private:
+ std::mutex mMutex;
+ const lvm::BundleEffectType mType;
+ bool mEnabled = false;
+ LVM_Handle_t mInstance GUARDED_BY(mMutex);
+
+ aidl::android::media::audio::common::AudioDeviceDescription mVirtualizerForcedDevice;
+ aidl::android::media::audio::common::AudioChannelLayout mChMask;
+
+ int mSampleRate = LVM_FS_44100;
+ int mSamplesPerSecond = 0;
+ int mSamplesToExitCountEq = 0;
+ int mSamplesToExitCountBb = 0;
+ int mSamplesToExitCountVirt = 0;
+ int mFrameCount = 0;
+
+ /* Bitmask whether drain is in progress due to disabling the effect.
+ The corresponding bit to an effect is set by 1 << lvm_effect_en. */
+ int mEffectInDrain = 0;
+
+ /* Bitmask whether process() was called for a particular effect.
+ The corresponding bit to an effect is set by 1 << lvm_effect_en. */
+ int mEffectProcessCalled = 0;
+ int mNumberEffectsEnabled = 0;
+ int mNumberEffectsCalled = 0;
+ bool mFirstVolume = true;
+ // Bass
+ bool mBassTempDisabled = false;
+ int mBassStrengthSaved = 0;
+ // Equalizer
+ int mCurPresetIdx = lvm::PRESET_CUSTOM; /* Current preset being used */
+ std::array<int, lvm::MAX_NUM_BANDS> mBandGaindB;
+ // Virtualizer
+ int mVirtStrengthSaved = 0; /* Conversion between Get/Set */
+ bool mVirtualizerTempDisabled = false;
+ // Volume
+ int mLevelSaved = 0; /* for when mute is set, level must be saved */
+ int mVolume = 0;
+ bool mMuteEnabled = false; /* Must store as mute = -96dB level */
+
+ void initControlParameter(LVM_ControlParams_t& params) const;
+ void initHeadroomParameter(LVM_HeadroomParams_t& params) const;
+ RetCode limitLevel();
+ int16_t VolToDb(uint32_t vol) const;
+ LVM_INT16 LVC_ToDB_s32Tos16(LVM_INT32 Lin_fix) const;
+ RetCode updateControlParameter(const std::vector<Equalizer::BandLevel>& bandLevels);
+ bool isBandLevelIndexInRange(const std::vector<Equalizer::BandLevel>& bandLevels) const;
+ static LVM_EQNB_BandDef_t* getDefaultEqualizerBandDefs();
+ static LVM_HeadroomBandDef_t* getDefaultEqualizerHeadroomBanDefs();
+};
+
+} // namespace aidl::android::hardware::audio::effect
+
diff --git a/media/libeffects/lvm/wrapper/Aidl/BundleTypes.h b/media/libeffects/lvm/wrapper/Aidl/BundleTypes.h
new file mode 100644
index 0000000..1996240
--- /dev/null
+++ b/media/libeffects/lvm/wrapper/Aidl/BundleTypes.h
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2022 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 <array>
+
+#include <aidl/android/hardware/audio/effect/BnEffect.h>
+#include "effect-impl/EffectUUID.h"
+#include "effect-impl/EffectTypes.h"
+#include "LVM.h"
+
+namespace aidl::android::hardware::audio::effect {
+namespace lvm {
+
+constexpr inline size_t MAX_NUM_PRESETS = 10;
+constexpr inline size_t MAX_NUM_BANDS = 5;
+constexpr inline size_t MAX_CALL_SIZE = 256;
+constexpr inline int BASS_BOOST_CUP_LOAD_ARM9E = 150; // Expressed in 0.1 MIPS
+constexpr inline int VIRTUALIZER_CUP_LOAD_ARM9E = 120; // Expressed in 0.1 MIPS
+constexpr inline int EQUALIZER_CUP_LOAD_ARM9E = 220; // Expressed in 0.1 MIPS
+constexpr inline int VOLUME_CUP_LOAD_ARM9E = 0; // Expressed in 0.1 MIPS
+constexpr inline int BUNDLE_MEM_USAGE = 25; // Expressed in kB
+constexpr inline int PRESET_CUSTOM = -1;
+
+static const std::vector<Equalizer::BandFrequency> kEqBandFrequency = {{0, 30000, 120000},
+ {1, 120001, 460000},
+ {2, 460001, 1800000},
+ {3, 1800001, 7000000},
+ {4, 7000001, 20000000}};
+
+/*
+Frequencies in Hz
+Note: If these frequencies change, please update LimitLevel values accordingly.
+*/
+constexpr inline std::array<uint16_t, MAX_NUM_BANDS> kPresetsFrequencies = {60, 230, 910, 3600,
+ 14000};
+
+/* Q factor multiplied by 100 */
+constexpr inline std::array<uint16_t, MAX_NUM_BANDS> kPresetsQFactors = {96, 96, 96, 96, 96};
+
+constexpr inline std::array<std::array<int16_t, MAX_NUM_BANDS>, MAX_NUM_PRESETS> kSoftPresets = {
+ {{3, 0, 0, 0, 3}, /* Normal Preset */
+ {5, 3, -2, 4, 4}, /* Classical Preset */
+ {6, 0, 2, 4, 1}, /* Dance Preset */
+ {0, 0, 0, 0, 0}, /* Flat Preset */
+ {3, 0, 0, 2, -1}, /* Folk Preset */
+ {4, 1, 9, 3, 0}, /* Heavy Metal Preset */
+ {5, 3, 0, 1, 3}, /* Hip Hop Preset */
+ {4, 2, -2, 2, 5}, /* Jazz Preset */
+ {-1, 2, 5, 1, -2}, /* Pop Preset */
+ {5, 3, -1, 3, 5}}}; /* Rock Preset */
+
+static const std::vector<Equalizer::Preset> kEqPresets = {
+ {0, "Normal"}, {1, "Classical"}, {2, "Dance"}, {3, "Flat"}, {4, "Folk"},
+ {5, "Heavy Metal"}, {6, "Hip Hop"}, {7, "Jazz"}, {8, "Pop"}, {9, "Rock"}};
+
+static const Equalizer::Capability kEqCap = {.bandFrequencies = kEqBandFrequency,
+ .presets = kEqPresets};
+
+static const std::string kEqualizerEffectName = "EqualizerBundle";
+
+static const Descriptor kEqualizerDesc = {
+ .common = {.id = {.type = kEqualizerTypeUUID,
+ .uuid = kEqualizerBundleImplUUID,
+ .proxy = kEqualizerProxyUUID},
+ .flags = {.type = Flags::Type::INSERT,
+ .insert = Flags::Insert::FIRST,
+ .volume = Flags::Volume::CTRL},
+ .name = kEqualizerEffectName,
+ .implementor = "NXP Software Ltd."},
+ .capability = Capability::make<Capability::equalizer>(kEqCap)};
+
+static const bool mStrengthSupported = true;
+
+static const BassBoost::Capability kBassBoostCap = {.maxStrengthPm = 1000,
+ .strengthSupported = mStrengthSupported};
+
+static const std::string kBassBoostEffectName = "Dynamic Bass Boost";
+
+static const Descriptor kBassBoostDesc = {
+ .common = {.id = {.type = kBassBoostTypeUUID,
+ .uuid = kBassBoostBundleImplUUID,
+ .proxy = kBassBoostProxyUUID},
+ .flags = {.type = Flags::Type::INSERT,
+ .insert = Flags::Insert::FIRST,
+ .volume = Flags::Volume::CTRL,
+ .deviceIndication = true},
+ .cpuLoad = BASS_BOOST_CUP_LOAD_ARM9E,
+ .memoryUsage = BUNDLE_MEM_USAGE,
+ .name = kBassBoostEffectName,
+ .implementor = "NXP Software Ltd."},
+ .capability = Capability::make<Capability::bassBoost>(kBassBoostCap)};
+
+static const Virtualizer::Capability kVirtualizerCap = {.maxStrengthPm = 1000,
+ .strengthSupported = mStrengthSupported};
+
+static const std::string kVirtualizerEffectName = "Virtualizer";
+
+static const Descriptor kVirtualizerDesc = {
+ .common = {.id = {.type = kVirtualizerTypeUUID,
+ .uuid = kVirtualizerBundleImplUUID,
+ .proxy = kVirtualizerProxyUUID},
+ .flags = {.type = Flags::Type::INSERT,
+ .insert = Flags::Insert::LAST,
+ .volume = Flags::Volume::CTRL,
+ .deviceIndication = true},
+ .cpuLoad = VIRTUALIZER_CUP_LOAD_ARM9E,
+ .memoryUsage = BUNDLE_MEM_USAGE,
+ .name = kVirtualizerEffectName,
+ .implementor = "NXP Software Ltd."},
+ .capability = Capability::make<Capability::virtualizer>(kVirtualizerCap)};
+
+static const Volume::Capability kVolumeCap = {.minLevelDb = -9600, .maxLevelDb = 0};
+
+static const std::string kVolumeEffectName = "Volume";
+
+static const Descriptor kVolumeDesc = {
+ .common = {.id = {.type = kVolumeTypeUUID,
+ .uuid = kVolumeBundleImplUUID,
+ .proxy = std::nullopt},
+ .flags = {.type = Flags::Type::INSERT,
+ .insert = Flags::Insert::LAST,
+ .volume = Flags::Volume::CTRL},
+ .cpuLoad = VOLUME_CUP_LOAD_ARM9E,
+ .memoryUsage = BUNDLE_MEM_USAGE,
+ .name = kVolumeEffectName,
+ .implementor = "NXP Software Ltd."},
+ .capability = Capability::make<Capability::volume>(kVolumeCap)};
+
+/* The following tables have been computed using the actual levels measured by the output of
+ * white noise or pink noise (IEC268-1) for the EQ and BassBoost Effects. These are estimates of
+ * the actual energy that 'could' be present in the given band.
+ * If the frequency values in EQNB_5BandPresetsFrequencies change, these values might need to be
+ * updated.
+ */
+constexpr inline std::array<float, MAX_NUM_BANDS> kBandEnergyCoefficient = {7.56, 9.69, 9.59, 7.37,
+ 2.88};
+
+constexpr inline std::array<float, MAX_NUM_BANDS - 1> kBandEnergyCrossCoefficient = {126.0, 115.0,
+ 125.0, 104.0};
+
+constexpr inline std::array<float, MAX_NUM_BANDS> kBassBoostEnergyCrossCoefficient = {
+ 221.21, 208.10, 28.16, 0.0, 0.0};
+
+constexpr inline float kBassBoostEnergyCoefficient = 9.00;
+
+constexpr inline float kVirtualizerContribution = 1.9;
+
+enum class BundleEffectType {
+ BASS_BOOST,
+ VIRTUALIZER,
+ EQUALIZER,
+ VOLUME,
+};
+
+inline std::ostream& operator<<(std::ostream& out, const BundleEffectType& type) {
+ switch (type) {
+ case BundleEffectType::BASS_BOOST:
+ return out << "BASS_BOOST";
+ case BundleEffectType::VIRTUALIZER:
+ return out << "VIRTUALIZER";
+ case BundleEffectType::EQUALIZER:
+ return out << "EQUALIZER";
+ case BundleEffectType::VOLUME:
+ return out << "VOLUME";
+ }
+ return out << "EnumBundleEffectTypeError";
+}
+
+inline std::ostream& operator<<(std::ostream& out, const LVM_ReturnStatus_en& status) {
+ switch (status) {
+ case LVM_SUCCESS:
+ return out << "LVM_SUCCESS";
+ case LVM_ALIGNMENTERROR:
+ return out << "LVM_ALIGNMENTERROR";
+ case LVM_NULLADDRESS:
+ return out << "LVM_NULLADDRESS";
+ case LVM_OUTOFRANGE:
+ return out << "LVM_OUTOFRANGE";
+ case LVM_INVALIDNUMSAMPLES:
+ return out << "LVM_INVALIDNUMSAMPLES";
+ case LVM_WRONGAUDIOTIME:
+ return out << "LVM_WRONGAUDIOTIME";
+ case LVM_ALGORITHMDISABLED:
+ return out << "LVM_ALGORITHMDISABLED";
+ case LVM_ALGORITHMPSA:
+ return out << "LVM_ALGORITHMPSA";
+ case LVM_RETURNSTATUS_DUMMY:
+ return out << "LVM_RETURNSTATUS_DUMMY";
+ }
+ return out << "EnumLvmRetStatusError";
+}
+
+#define GOTO_IF_LVM_ERROR(status, tag, log) \
+ do { \
+ LVM_ReturnStatus_en temp = (status); \
+ if (temp != LVM_SUCCESS) { \
+ LOG(ERROR) << __func__ << " return status: " << temp << " " << (log); \
+ goto tag; \
+ } \
+ } while (0)
+
+} // namespace lvm
+} // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/lvm/wrapper/Aidl/EffectBundleAidl.cpp b/media/libeffects/lvm/wrapper/Aidl/EffectBundleAidl.cpp
new file mode 100644
index 0000000..81b8aca
--- /dev/null
+++ b/media/libeffects/lvm/wrapper/Aidl/EffectBundleAidl.cpp
@@ -0,0 +1,426 @@
+/*
+ * Copyright (C) 2022 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 "EffectBundleAidl"
+#include <Utils.h>
+#include <algorithm>
+#include <unordered_set>
+
+#include <android-base/logging.h>
+#include <fmq/AidlMessageQueue.h>
+#include <audio_effects/effect_bassboost.h>
+#include <audio_effects/effect_equalizer.h>
+#include <audio_effects/effect_virtualizer.h>
+
+#include "EffectBundleAidl.h"
+#include <LVM.h>
+#include <limits.h>
+
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::EffectBundleAidl;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::kBassBoostBundleImplUUID;
+using aidl::android::hardware::audio::effect::kEqualizerBundleImplUUID;
+using aidl::android::hardware::audio::effect::kVirtualizerBundleImplUUID;
+using aidl::android::hardware::audio::effect::kVolumeBundleImplUUID;
+using aidl::android::hardware::audio::effect::State;
+using aidl::android::media::audio::common::AudioUuid;
+
+bool isUuidSupported(const AudioUuid* uuid) {
+ return (*uuid == kEqualizerBundleImplUUID || *uuid == kBassBoostBundleImplUUID ||
+ *uuid == kVirtualizerBundleImplUUID || *uuid == kVolumeBundleImplUUID);
+}
+
+extern "C" binder_exception_t createEffect(const AudioUuid* uuid,
+ std::shared_ptr<IEffect>* instanceSpp) {
+ if (uuid == nullptr || !isUuidSupported(uuid)) {
+ LOG(ERROR) << __func__ << "uuid not supported";
+ return EX_ILLEGAL_ARGUMENT;
+ }
+ if (instanceSpp) {
+ *instanceSpp = ndk::SharedRefBase::make<EffectBundleAidl>(*uuid);
+ LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
+ return EX_NONE;
+ } else {
+ LOG(ERROR) << __func__ << " invalid input parameter!";
+ return EX_ILLEGAL_ARGUMENT;
+ }
+}
+
+extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
+ if (!in_impl_uuid || !isUuidSupported(in_impl_uuid)) {
+ LOG(ERROR) << __func__ << "uuid not supported";
+ return EX_ILLEGAL_ARGUMENT;
+ }
+ if (*in_impl_uuid == kEqualizerBundleImplUUID) {
+ *_aidl_return = aidl::android::hardware::audio::effect::lvm::kEqualizerDesc;
+ } else if (*in_impl_uuid == kBassBoostBundleImplUUID) {
+ *_aidl_return = aidl::android::hardware::audio::effect::lvm:: kBassBoostDesc;
+ } else if (*in_impl_uuid == kVirtualizerBundleImplUUID) {
+ *_aidl_return = aidl::android::hardware::audio::effect::lvm::kVirtualizerDesc;
+ } else if (*in_impl_uuid == kVolumeBundleImplUUID) {
+ *_aidl_return = aidl::android::hardware::audio::effect::lvm::kVolumeDesc;
+ }
+ return EX_NONE;
+}
+
+namespace aidl::android::hardware::audio::effect {
+
+EffectBundleAidl::EffectBundleAidl(const AudioUuid& uuid) {
+ LOG(DEBUG) << __func__ << uuid.toString();
+ if (uuid == kEqualizerBundleImplUUID) {
+ mType = lvm::BundleEffectType::EQUALIZER;
+ mDescriptor = &lvm::kEqualizerDesc;
+ mEffectName = &lvm::kEqualizerEffectName;
+ } else if (uuid == kBassBoostBundleImplUUID) {
+ mType = lvm::BundleEffectType::BASS_BOOST;
+ mDescriptor = &lvm::kBassBoostDesc;
+ mEffectName = &lvm::kBassBoostEffectName;
+ } else if (uuid == kVirtualizerBundleImplUUID) {
+ mType = lvm::BundleEffectType::VIRTUALIZER;
+ mDescriptor = &lvm::kVirtualizerDesc;
+ mEffectName = &lvm::kVirtualizerEffectName;
+ } else if (uuid == kVolumeBundleImplUUID) {
+ mType = lvm::BundleEffectType::VOLUME;
+ mDescriptor = &lvm::kVolumeDesc;
+ mEffectName = &lvm::kVolumeEffectName;
+ } else {
+ LOG(ERROR) << __func__ << uuid.toString() << " not supported!";
+ }
+}
+
+EffectBundleAidl::~EffectBundleAidl() {
+ cleanUp();
+ LOG(DEBUG) << __func__;
+}
+
+ndk::ScopedAStatus EffectBundleAidl::getDescriptor(Descriptor* _aidl_return) {
+ RETURN_IF(!_aidl_return, EX_ILLEGAL_ARGUMENT, "Parameter:nullptr");
+ LOG(DEBUG) << _aidl_return->toString();
+ *_aidl_return = *mDescriptor;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus EffectBundleAidl::setParameterCommon(const Parameter& param) {
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+ auto tag = param.getTag();
+ switch (tag) {
+ case Parameter::common:
+ RETURN_IF(mContext->setCommon(param.get<Parameter::common>()) != RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setCommFailed");
+ break;
+ case Parameter::deviceDescription:
+ RETURN_IF(mContext->setOutputDevice(param.get<Parameter::deviceDescription>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setDeviceFailed");
+ break;
+ case Parameter::mode:
+ RETURN_IF(mContext->setAudioMode(param.get<Parameter::mode>()) != RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setModeFailed");
+ break;
+ case Parameter::source:
+ RETURN_IF(mContext->setAudioSource(param.get<Parameter::source>()) != RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setSourceFailed");
+ break;
+ case Parameter::volumeStereo:
+ RETURN_IF(mContext->setVolumeStereo(param.get<Parameter::volumeStereo>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setVolumeStereoFailed");
+ break;
+ default: {
+ LOG(ERROR) << __func__ << " unsupportedParameterTag " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "commonParamNotSupported");
+ }
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus EffectBundleAidl::setParameterSpecific(const Parameter::Specific& specific) {
+ LOG(DEBUG) << __func__ << " specific " << specific.toString();
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+ auto tag = specific.getTag();
+ switch (tag) {
+ case Parameter::Specific::equalizer:
+ return setParameterEqualizer(specific);
+ case Parameter::Specific::bassBoost:
+ return setParameterBassBoost(specific);
+ case Parameter::Specific::virtualizer:
+ return setParameterVirtualizer(specific);
+ case Parameter::Specific::volume:
+ return setParameterVolume(specific);
+ default:
+ LOG(ERROR) << __func__ << " unsupported tag " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "specificParamNotSupported");
+ }
+}
+
+ndk::ScopedAStatus EffectBundleAidl::setParameterEqualizer(const Parameter::Specific& specific) {
+ auto& eq = specific.get<Parameter::Specific::equalizer>();
+ auto eqTag = eq.getTag();
+ switch (eqTag) {
+ case Equalizer::preset:
+ RETURN_IF(mContext->setEqualizerPreset(eq.get<Equalizer::preset>()) != RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setBandLevelsFailed");
+ return ndk::ScopedAStatus::ok();
+ case Equalizer::bandLevels:
+ RETURN_IF(mContext->setEqualizerBandLevels(eq.get<Equalizer::bandLevels>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setBandLevelsFailed");
+ return ndk::ScopedAStatus::ok();
+ default:
+ LOG(ERROR) << __func__ << " unsupported parameter " << specific.toString();
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "eqTagNotSupported");
+ }
+}
+
+ndk::ScopedAStatus EffectBundleAidl::setParameterBassBoost(const Parameter::Specific& specific) {
+ auto& bb = specific.get<Parameter::Specific::bassBoost>();
+ auto bbTag = bb.getTag();
+ switch (bbTag) {
+ case BassBoost::strengthPm: {
+ RETURN_IF(mContext->setBassBoostStrength(bb.get<BassBoost::strengthPm>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setStrengthFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ default:
+ LOG(ERROR) << __func__ << " unsupported parameter " << specific.toString();
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "bbTagNotSupported");
+ }
+}
+
+ndk::ScopedAStatus EffectBundleAidl::setParameterVirtualizer(const Parameter::Specific& specific) {
+ auto& vr = specific.get<Parameter::Specific::virtualizer>();
+ auto vrTag = vr.getTag();
+ switch (vrTag) {
+ case Virtualizer::strengthPm: {
+ RETURN_IF(mContext->setVirtualizerStrength(vr.get<Virtualizer::strengthPm>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setStrengthFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ default:
+ LOG(ERROR) << __func__ << " unsupported parameter " << specific.toString();
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "vrTagNotSupported");
+ }
+}
+
+ndk::ScopedAStatus EffectBundleAidl::setParameterVolume(const Parameter::Specific& specific) {
+ auto& vol = specific.get<Parameter::Specific::volume>();
+ auto volTag = vol.getTag();
+ switch (volTag) {
+ case Volume::levelDb: {
+ RETURN_IF(mContext->setVolumeLevel(vol.get<Volume::levelDb>()) != RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setLevelFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ case Volume::mute:
+ RETURN_IF(mContext->setVolumeMute(vol.get<Volume::mute>()) != RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setMuteFailed");
+ return ndk::ScopedAStatus::ok();
+ default:
+ LOG(ERROR) << __func__ << " unsupported parameter " << specific.toString();
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "volTagNotSupported");
+ }
+}
+
+ndk::ScopedAStatus EffectBundleAidl::getParameterSpecific(const Parameter::Id& id,
+ Parameter::Specific* specific) {
+ RETURN_IF(!specific, EX_NULL_POINTER, "nullPtr");
+ auto tag = id.getTag();
+
+ switch (tag) {
+ case Parameter::Id::equalizerTag:
+ return getParameterEqualizer(id.get<Parameter::Id::equalizerTag>(), specific);
+ case Parameter::Id::bassBoostTag:
+ return getParameterBassBoost(id.get<Parameter::Id::bassBoostTag>(), specific);
+ case Parameter::Id::virtualizerTag:
+ return getParameterVirtualizer(id.get<Parameter::Id::virtualizerTag>(), specific);
+ case Parameter::Id::volumeTag:
+ return getParameterVolume(id.get<Parameter::Id::volumeTag>(), specific);
+ default:
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "wrongIdTag");
+ }
+}
+
+ndk::ScopedAStatus EffectBundleAidl::getParameterEqualizer(const Equalizer::Id& id,
+ Parameter::Specific* specific) {
+ RETURN_IF(id.getTag() != Equalizer::Id::commonTag, EX_ILLEGAL_ARGUMENT,
+ "EqualizerTagNotSupported");
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+ Equalizer eqParam;
+
+ auto tag = id.get<Equalizer::Id::commonTag>();
+ switch (tag) {
+ case Equalizer::bandLevels: {
+ eqParam.set<Equalizer::bandLevels>(mContext->getEqualizerBandLevels());
+ break;
+ }
+ case Equalizer::preset: {
+ eqParam.set<Equalizer::preset>(mContext->getEqualizerPreset());
+ break;
+ }
+ default: {
+ LOG(ERROR) << __func__ << " not handled tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+ EX_ILLEGAL_ARGUMENT, "unsupportedTag");
+ }
+ }
+
+ specific->set<Parameter::Specific::equalizer>(eqParam);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus EffectBundleAidl::getParameterBassBoost(const BassBoost::Id& id,
+ Parameter::Specific* specific) {
+ RETURN_IF(id.getTag() != BassBoost::Id::commonTag, EX_ILLEGAL_ARGUMENT,
+ "BassBoostTagNotSupported");
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+ BassBoost bbParam;
+
+ auto tag = id.get<BassBoost::Id::commonTag>();
+ switch (tag) {
+ case BassBoost::strengthPm: {
+ bbParam.set<BassBoost::strengthPm>(mContext->getBassBoostStrength());
+ break;
+ }
+ default: {
+ LOG(ERROR) << __func__ << " not handled tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "BassBoostTagNotSupported");
+ }
+ }
+
+ specific->set<Parameter::Specific::bassBoost>(bbParam);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus EffectBundleAidl::getParameterVolume(const Volume::Id& id,
+ Parameter::Specific* specific) {
+ RETURN_IF(id.getTag() != Volume::Id::commonTag, EX_ILLEGAL_ARGUMENT, "VolumeTagNotSupported");
+
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+ Volume volParam;
+
+ auto tag = id.get<Volume::Id::commonTag>();
+ switch (tag) {
+ case Volume::levelDb: {
+ volParam.set<Volume::levelDb>(mContext->getVolumeLevel());
+ break;
+ }
+ case Volume::mute: {
+ volParam.set<Volume::mute>(mContext->getVolumeMute());
+ break;
+ }
+ default: {
+ LOG(ERROR) << __func__ << " not handled tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "VolumeTagNotSupported");
+ }
+ }
+
+ specific->set<Parameter::Specific::volume>(volParam);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus EffectBundleAidl::getParameterVirtualizer(const Virtualizer::Id& id,
+ Parameter::Specific* specific) {
+ RETURN_IF(id.getTag() != Virtualizer::Id::commonTag, EX_ILLEGAL_ARGUMENT,
+ "VirtualizerTagNotSupported");
+
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+ Virtualizer vrParam;
+
+ auto tag = id.get<Virtualizer::Id::commonTag>();
+ switch (tag) {
+ case Virtualizer::strengthPm: {
+ vrParam.set<Virtualizer::strengthPm>(mContext->getVirtualizerStrength());
+ break;
+ }
+ default: {
+ LOG(ERROR) << __func__ << " not handled tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "VirtualizerTagNotSupported");
+ }
+ }
+
+ specific->set<Parameter::Specific::virtualizer>(vrParam);
+ return ndk::ScopedAStatus::ok();
+}
+
+std::shared_ptr<EffectContext> EffectBundleAidl::createContext(const Parameter::Common& common) {
+ if (mContext) {
+ LOG(DEBUG) << __func__ << " context already exist";
+ } else {
+ // GlobalSession is a singleton
+ mContext = GlobalSession::getGlobalSession().createSession(mType, 1 /* statusFmqDepth */,
+ common);
+ }
+
+ return mContext;
+}
+
+std::shared_ptr<EffectContext> EffectBundleAidl::getContext() {
+ return mContext;
+}
+
+RetCode EffectBundleAidl::releaseContext() {
+ if (mContext) {
+ GlobalSession::getGlobalSession().releaseSession(mType, mContext->getSessionId());
+ mContext.reset();
+ }
+ return RetCode::SUCCESS;
+}
+
+ndk::ScopedAStatus EffectBundleAidl::commandImpl(CommandId command) {
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+ switch (command) {
+ case CommandId::START:
+ mContext->enable();
+ break;
+ case CommandId::STOP:
+ mContext->disable();
+ break;
+ case CommandId::RESET:
+ mContext->disable();
+ mContext->resetBuffer();
+ break;
+ default:
+ LOG(ERROR) << __func__ << " commandId " << toString(command) << " not supported";
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "commandIdNotSupported");
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+// Processing method running in EffectWorker thread.
+IEffect::Status EffectBundleAidl::effectProcessImpl(float* in, float* out, int sampleToProcess) {
+ IEffect::Status status = {EX_NULL_POINTER, 0, 0};
+ RETURN_VALUE_IF(!mContext, status, "nullContext");
+ return mContext->lvmProcess(in, out, sampleToProcess);
+}
+
+} // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/lvm/wrapper/Aidl/EffectBundleAidl.h b/media/libeffects/lvm/wrapper/Aidl/EffectBundleAidl.h
new file mode 100644
index 0000000..0330e5a
--- /dev/null
+++ b/media/libeffects/lvm/wrapper/Aidl/EffectBundleAidl.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2022 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 <functional>
+#include <map>
+#include <memory>
+
+#include <aidl/android/hardware/audio/effect/BnEffect.h>
+#include <android-base/logging.h>
+
+#include "effect-impl/EffectImpl.h"
+#include "effect-impl/EffectUUID.h"
+
+#include "BundleContext.h"
+#include "BundleTypes.h"
+#include "GlobalSession.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+class EffectBundleAidl final : public EffectImpl {
+ public:
+ explicit EffectBundleAidl(const AudioUuid& uuid);
+ ~EffectBundleAidl() override;
+
+ ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
+ ndk::ScopedAStatus setParameterCommon(const Parameter& param) override;
+ ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
+ ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
+ Parameter::Specific* specific) override;
+
+ std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
+ std::shared_ptr<EffectContext> getContext() override;
+ RetCode releaseContext() override;
+
+ IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+
+ ndk::ScopedAStatus commandImpl(CommandId command) override;
+
+ std::string getEffectName() override { return *mEffectName; }
+
+ private:
+ std::shared_ptr<BundleContext> mContext;
+ const Descriptor* mDescriptor;
+ const std::string* mEffectName;
+ lvm::BundleEffectType mType = lvm::BundleEffectType::EQUALIZER;
+
+ IEffect::Status status(binder_status_t status, size_t consumed, size_t produced);
+
+ ndk::ScopedAStatus setParameterBassBoost(const Parameter::Specific& specific);
+ ndk::ScopedAStatus getParameterBassBoost(const BassBoost::Id& id,
+ Parameter::Specific* specific);
+
+ ndk::ScopedAStatus setParameterEqualizer(const Parameter::Specific& specific);
+ ndk::ScopedAStatus getParameterEqualizer(const Equalizer::Id& id,
+ Parameter::Specific* specific);
+ ndk::ScopedAStatus setParameterVolume(const Parameter::Specific& specific);
+ ndk::ScopedAStatus getParameterVolume(const Volume::Id& id, Parameter::Specific* specific);
+ ndk::ScopedAStatus setParameterVirtualizer(const Parameter::Specific& specific);
+ ndk::ScopedAStatus getParameterVirtualizer(const Virtualizer::Id& id,
+ Parameter::Specific* specific);
+};
+
+} // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/lvm/wrapper/Aidl/GlobalSession.h b/media/libeffects/lvm/wrapper/Aidl/GlobalSession.h
new file mode 100644
index 0000000..d31763b
--- /dev/null
+++ b/media/libeffects/lvm/wrapper/Aidl/GlobalSession.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2022 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 <algorithm>
+#include <memory>
+#include <unordered_map>
+
+#include <android-base/logging.h>
+#include <android-base/thread_annotations.h>
+
+#include "BundleContext.h"
+#include "BundleTypes.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+/**
+ * @brief Maintain all effect bundle sessions.
+ *
+ * Sessions are identified with the session ID, maximum of MAX_BUNDLE_SESSIONS is supported by the
+ * bundle implementation.
+ */
+class GlobalSession {
+ public:
+ static GlobalSession& getGlobalSession() {
+ static GlobalSession instance;
+ return instance;
+ }
+
+ bool isSessionIdExist(int sessionId) {
+ std::lock_guard lg(mMutex);
+ return mSessionMap.count(sessionId);
+ }
+
+ static bool findBundleTypeInList(std::vector<std::shared_ptr<BundleContext>>& list,
+ const lvm::BundleEffectType& type, bool remove = false) {
+ auto itor = std::find_if(list.begin(), list.end(),
+ [type](const std::shared_ptr<BundleContext>& bundle) {
+ return bundle ? bundle->getBundleType() == type : false;
+ });
+ if (itor == list.end()) {
+ return false;
+ }
+ if (remove && *itor) {
+ (*itor)->deInit();
+ list.erase(itor);
+ }
+ return true;
+ }
+
+ /**
+ * Create a certain type of BundleContext in shared_ptr container, each session must not have
+ * more than one session for each type.
+ */
+ std::shared_ptr<BundleContext> createSession(const lvm::BundleEffectType& type, int statusDepth,
+ const Parameter::Common& common) {
+ int sessionId = common.session;
+ LOG(DEBUG) << __func__ << type << " with sessionId " << sessionId;
+ std::lock_guard lg(mMutex);
+ if (mSessionMap.count(sessionId) == 0 && mSessionMap.size() >= MAX_BUNDLE_SESSIONS) {
+ LOG(ERROR) << __func__ << " exceed max bundle session";
+ return nullptr;
+ }
+
+ if (mSessionMap.count(sessionId)) {
+ if (findBundleTypeInList(mSessionMap[sessionId], type)) {
+ LOG(ERROR) << __func__ << type << " already exist in session " << sessionId;
+ return nullptr;
+ }
+ }
+
+ auto& list = mSessionMap[sessionId];
+ auto context = std::make_shared<BundleContext>(statusDepth, common, type);
+ RETURN_VALUE_IF(!context, nullptr, "failedToCreateContext");
+
+ RetCode ret = context->init();
+ if (RetCode::SUCCESS != ret) {
+ LOG(ERROR) << __func__ << " context init ret " << ret;
+ return nullptr;
+ }
+ list.push_back(context);
+ return context;
+ }
+
+ void releaseSession(const lvm::BundleEffectType& type, int sessionId) {
+ LOG(DEBUG) << __func__ << type << " sessionId " << sessionId;
+ std::lock_guard lg(mMutex);
+ if (mSessionMap.count(sessionId)) {
+ auto& list = mSessionMap[sessionId];
+ if (!findBundleTypeInList(list, type, true /* remove */)) {
+ LOG(ERROR) << __func__ << " can't find " << type << "in session " << sessionId;
+ return;
+ }
+ if (list.size() == 0) {
+ mSessionMap.erase(sessionId);
+ }
+ }
+ }
+
+ private:
+ // Lock for mSessionMap access.
+ std::mutex mMutex;
+ // Max session number supported.
+ static constexpr int MAX_BUNDLE_SESSIONS = 32;
+ std::unordered_map<int /* session ID */, std::vector<std::shared_ptr<BundleContext>>>
+ mSessionMap GUARDED_BY(mMutex);
+};
+} // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/lvm/wrapper/Android.bp b/media/libeffects/lvm/wrapper/Android.bp
index 1287514..bc19379 100644
--- a/media/libeffects/lvm/wrapper/Android.bp
+++ b/media/libeffects/lvm/wrapper/Android.bp
@@ -100,3 +100,64 @@
integer_overflow: true,
},
}
+
+cc_library_shared {
+ name: "libbundleaidl",
+ srcs: [
+ "Aidl/BundleContext.cpp",
+ "Aidl/EffectBundleAidl.cpp",
+ ":effectCommonFile",
+ ],
+ static_libs: ["libmusicbundle"],
+ defaults: [
+ "aidlaudioservice_defaults",
+ "latest_android_hardware_audio_effect_ndk_shared",
+ "latest_android_media_audio_common_types_ndk_shared",
+ ],
+ local_include_dirs: ["Aidl"],
+ header_libs: [
+ "libaudioeffects",
+ "libhardware_headers",
+ ],
+ shared_libs: [
+ "liblog",
+ ],
+ cflags: [
+ "-Wthread-safety",
+ ],
+ visibility: [
+ "//hardware/interfaces/audio/aidl/default",
+ ],
+}
+
+cc_library_shared {
+ name: "libreverbaidl",
+ srcs: [
+ "Reverb/aidl/ReverbContext.cpp",
+ "Reverb/aidl/EffectReverb.cpp",
+ ":effectCommonFile",
+ ],
+ static_libs: ["libreverb"],
+ defaults: [
+ "aidlaudioservice_defaults",
+ "latest_android_hardware_audio_effect_ndk_shared",
+ "latest_android_media_audio_common_types_ndk_shared",
+ ],
+ local_include_dirs: ["Reverb/aidl"],
+ header_libs: [
+ "libaudioeffects",
+ "libhardware_headers",
+ ],
+ shared_libs: [
+ "libbase",
+ "libaudioutils",
+ "libcutils",
+ "liblog",
+ ],
+ cflags: [
+ "-Wthread-safety",
+ ],
+ visibility: [
+ "//hardware/interfaces/audio/aidl/default",
+ ],
+}
diff --git a/media/libeffects/lvm/wrapper/Reverb/aidl/EffectReverb.cpp b/media/libeffects/lvm/wrapper/Reverb/aidl/EffectReverb.cpp
new file mode 100644
index 0000000..51825ca
--- /dev/null
+++ b/media/libeffects/lvm/wrapper/Reverb/aidl/EffectReverb.cpp
@@ -0,0 +1,373 @@
+/*
+ * Copyright (C) 2023 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 "EffectReverb"
+#include <Utils.h>
+#include <algorithm>
+#include <unordered_set>
+
+#include <android-base/logging.h>
+#include <fmq/AidlMessageQueue.h>
+#include <audio_effects/effect_bassboost.h>
+#include <audio_effects/effect_equalizer.h>
+#include <audio_effects/effect_virtualizer.h>
+
+#include "EffectReverb.h"
+#include <limits.h>
+
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::EffectReverb;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::kAuxEnvReverbImplUUID;
+using aidl::android::hardware::audio::effect::kAuxPresetReverbImplUUID;
+using aidl::android::hardware::audio::effect::kInsertEnvReverbImplUUID;
+using aidl::android::hardware::audio::effect::kInsertPresetReverbImplUUID;
+using aidl::android::hardware::audio::effect::State;
+using aidl::android::media::audio::common::AudioUuid;
+
+bool isReverbUuidSupported(const AudioUuid* uuid) {
+ return (*uuid == kAuxEnvReverbImplUUID || *uuid == kInsertEnvReverbImplUUID ||
+ *uuid == kAuxPresetReverbImplUUID || *uuid == kInsertPresetReverbImplUUID);
+}
+
+extern "C" binder_exception_t createEffect(const AudioUuid* uuid,
+ std::shared_ptr<IEffect>* instanceSpp) {
+ if (uuid == nullptr || !isReverbUuidSupported(uuid)) {
+ LOG(ERROR) << __func__ << "uuid not supported";
+ return EX_ILLEGAL_ARGUMENT;
+ }
+ if (instanceSpp) {
+ *instanceSpp = ndk::SharedRefBase::make<EffectReverb>(*uuid);
+ LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
+ return EX_NONE;
+ } else {
+ LOG(ERROR) << __func__ << " invalid input parameter!";
+ return EX_ILLEGAL_ARGUMENT;
+ }
+}
+
+extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
+ if (!in_impl_uuid || !isReverbUuidSupported(in_impl_uuid)) {
+ LOG(ERROR) << __func__ << "uuid not supported";
+ return EX_ILLEGAL_ARGUMENT;
+ }
+ if (*in_impl_uuid == kAuxEnvReverbImplUUID) {
+ *_aidl_return = aidl::android::hardware::audio::effect::lvm::kAuxEnvReverbDesc;
+ } else if (*in_impl_uuid == kInsertEnvReverbImplUUID) {
+ *_aidl_return = aidl::android::hardware::audio::effect::lvm::kInsertEnvReverbDesc;
+ } else if (*in_impl_uuid == kAuxPresetReverbImplUUID) {
+ *_aidl_return = aidl::android::hardware::audio::effect::lvm::kAuxPresetReverbDesc;
+ } else if (*in_impl_uuid == kInsertPresetReverbImplUUID) {
+ *_aidl_return = aidl::android::hardware::audio::effect::lvm::kInsertPresetReverbDesc;
+ }
+ return EX_NONE;
+}
+
+namespace aidl::android::hardware::audio::effect {
+
+EffectReverb::EffectReverb(const AudioUuid& uuid) {
+ LOG(DEBUG) << __func__ << uuid.toString();
+ if (uuid == kAuxEnvReverbImplUUID) {
+ mType = lvm::ReverbEffectType::AUX_ENV;
+ mDescriptor = &lvm::kAuxEnvReverbDesc;
+ mEffectName = &lvm::kAuxEnvReverbEffectName;
+ } else if (uuid == kInsertEnvReverbImplUUID) {
+ mType = lvm::ReverbEffectType::INSERT_ENV;
+ mDescriptor = &lvm::kInsertEnvReverbDesc;
+ mEffectName = &lvm::kInsertEnvReverbEffectName;
+ } else if (uuid == kAuxPresetReverbImplUUID) {
+ mType = lvm::ReverbEffectType::AUX_PRESET;
+ mDescriptor = &lvm::kAuxPresetReverbDesc;
+ mEffectName = &lvm::kAuxPresetReverbEffectName;
+ } else if (uuid == kInsertPresetReverbImplUUID) {
+ mType = lvm::ReverbEffectType::INSERT_PRESET;
+ mDescriptor = &lvm::kInsertPresetReverbDesc;
+ mEffectName = &lvm::kInsertPresetReverbEffectName;
+ } else {
+ LOG(ERROR) << __func__ << uuid.toString() << " not supported!";
+ }
+}
+
+EffectReverb::~EffectReverb() {
+ cleanUp();
+ LOG(DEBUG) << __func__;
+}
+
+ndk::ScopedAStatus EffectReverb::getDescriptor(Descriptor* _aidl_return) {
+ RETURN_IF(!_aidl_return, EX_ILLEGAL_ARGUMENT, "Parameter:nullptr");
+ LOG(DEBUG) << _aidl_return->toString();
+ *_aidl_return = *mDescriptor;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus EffectReverb::setParameterSpecific(const Parameter::Specific& specific) {
+ LOG(DEBUG) << __func__ << " specific " << specific.toString();
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+ auto tag = specific.getTag();
+ switch (tag) {
+ case Parameter::Specific::presetReverb:
+ return setParameterPresetReverb(specific);
+ case Parameter::Specific::environmentalReverb:
+ return setParameterEnvironmentalReverb(specific);
+ default:
+ LOG(ERROR) << __func__ << " unsupported tag " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "specificParamNotSupported");
+ }
+}
+
+ndk::ScopedAStatus EffectReverb::setParameterPresetReverb(const Parameter::Specific& specific) {
+ auto& prParam = specific.get<Parameter::Specific::presetReverb>();
+ auto tag = prParam.getTag();
+
+ switch (tag) {
+ case PresetReverb::preset: {
+ RETURN_IF(mContext->setPresetReverbPreset(prParam.get<PresetReverb::preset>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setPresetFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ default: {
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "PresetReverbTagNotSupported");
+ }
+ }
+}
+
+ndk::ScopedAStatus EffectReverb::setParameterEnvironmentalReverb(
+ const Parameter::Specific& specific) {
+ auto& erParam = specific.get<Parameter::Specific::environmentalReverb>();
+ auto tag = erParam.getTag();
+
+ switch (tag) {
+ case EnvironmentalReverb::roomLevelMb: {
+ RETURN_IF(mContext->setEnvironmentalReverbRoomLevel(
+ erParam.get<EnvironmentalReverb::roomLevelMb>()) != RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setRoomLevelFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ case EnvironmentalReverb::roomHfLevelMb: {
+ RETURN_IF(
+ mContext->setEnvironmentalReverbRoomHfLevel(
+ erParam.get<EnvironmentalReverb::roomHfLevelMb>()) != RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setRoomHfLevelFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ case EnvironmentalReverb::decayTimeMs: {
+ RETURN_IF(mContext->setEnvironmentalReverbDecayTime(
+ erParam.get<EnvironmentalReverb::decayTimeMs>()) != RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setDecayTimeFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ case EnvironmentalReverb::decayHfRatioPm: {
+ RETURN_IF(
+ mContext->setEnvironmentalReverbDecayHfRatio(
+ erParam.get<EnvironmentalReverb::decayHfRatioPm>()) != RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setDecayHfRatioFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ case EnvironmentalReverb::levelMb: {
+ RETURN_IF(mContext->setEnvironmentalReverbLevel(
+ erParam.get<EnvironmentalReverb::levelMb>()) != RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setLevelFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ case EnvironmentalReverb::delayMs: {
+ RETURN_IF(mContext->setEnvironmentalReverbDelay(
+ erParam.get<EnvironmentalReverb::delayMs>()) != RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setDelayFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ case EnvironmentalReverb::diffusionPm: {
+ RETURN_IF(mContext->setEnvironmentalReverbDiffusion(
+ erParam.get<EnvironmentalReverb::diffusionPm>()) != RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setDiffusionFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ case EnvironmentalReverb::densityPm: {
+ RETURN_IF(mContext->setEnvironmentalReverbDensity(
+ erParam.get<EnvironmentalReverb::densityPm>()) != RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setDensityFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ case EnvironmentalReverb::bypass: {
+ RETURN_IF(mContext->setEnvironmentalReverbBypass(
+ erParam.get<EnvironmentalReverb::bypass>()) != RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setBypassFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ default: {
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+ EX_ILLEGAL_ARGUMENT, "EnvironmentalReverbTagNotSupported");
+ }
+ }
+}
+
+ndk::ScopedAStatus EffectReverb::getParameterSpecific(const Parameter::Id& id,
+ Parameter::Specific* specific) {
+ RETURN_IF(!specific, EX_NULL_POINTER, "nullPtr");
+ auto tag = id.getTag();
+
+ switch (tag) {
+ case Parameter::Id::presetReverbTag:
+ return getParameterPresetReverb(id.get<Parameter::Id::presetReverbTag>(), specific);
+ case Parameter::Id::environmentalReverbTag:
+ return getParameterEnvironmentalReverb(id.get<Parameter::Id::environmentalReverbTag>(),
+ specific);
+ default:
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "wrongIdTag");
+ }
+}
+
+ndk::ScopedAStatus EffectReverb::getParameterPresetReverb(const PresetReverb::Id& id,
+ Parameter::Specific* specific) {
+ RETURN_IF(id.getTag() != PresetReverb::Id::commonTag, EX_ILLEGAL_ARGUMENT,
+ "PresetReverbTagNotSupported");
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+ PresetReverb prParam;
+ auto tag = id.get<PresetReverb::Id::commonTag>();
+ switch (tag) {
+ case PresetReverb::preset: {
+ prParam.set<PresetReverb::preset>(mContext->getPresetReverbPreset());
+ break;
+ }
+ default: {
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "PresetReverbTagNotSupported");
+ }
+ }
+
+ specific->set<Parameter::Specific::presetReverb>(prParam);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus EffectReverb::getParameterEnvironmentalReverb(const EnvironmentalReverb::Id& id,
+ Parameter::Specific* specific) {
+ RETURN_IF(id.getTag() != EnvironmentalReverb::Id::commonTag, EX_ILLEGAL_ARGUMENT,
+ "EnvironmentalReverbTagNotSupported");
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+ EnvironmentalReverb erParam;
+
+ auto tag = id.get<EnvironmentalReverb::Id::commonTag>();
+ switch (tag) {
+ case EnvironmentalReverb::roomLevelMb: {
+ erParam.set<EnvironmentalReverb::roomLevelMb>(
+ mContext->getEnvironmentalReverbRoomLevel());
+ break;
+ }
+ case EnvironmentalReverb::roomHfLevelMb: {
+ erParam.set<EnvironmentalReverb::roomHfLevelMb>(
+ mContext->getEnvironmentalReverbRoomHfLevel());
+ break;
+ }
+ case EnvironmentalReverb::decayTimeMs: {
+ erParam.set<EnvironmentalReverb::decayTimeMs>(
+ mContext->getEnvironmentalReverbDecayTime());
+ break;
+ }
+ case EnvironmentalReverb::decayHfRatioPm: {
+ erParam.set<EnvironmentalReverb::decayHfRatioPm>(
+ mContext->getEnvironmentalReverbDecayHfRatio());
+ break;
+ }
+ case EnvironmentalReverb::levelMb: {
+ erParam.set<EnvironmentalReverb::levelMb>(mContext->getEnvironmentalReverbLevel());
+ break;
+ }
+ case EnvironmentalReverb::delayMs: {
+ erParam.set<EnvironmentalReverb::delayMs>(mContext->getEnvironmentalReverbDelay());
+ break;
+ }
+ case EnvironmentalReverb::diffusionPm: {
+ erParam.set<EnvironmentalReverb::diffusionPm>(
+ mContext->getEnvironmentalReverbDiffusion());
+ break;
+ }
+ case EnvironmentalReverb::densityPm: {
+ erParam.set<EnvironmentalReverb::densityPm>(mContext->getEnvironmentalReverbDensity());
+ break;
+ }
+ case EnvironmentalReverb::bypass: {
+ erParam.set<EnvironmentalReverb::bypass>(mContext->getEnvironmentalReverbBypass());
+ break;
+ }
+ default: {
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+ EX_ILLEGAL_ARGUMENT, "EnvironmentalReverbTagNotSupported");
+ }
+ }
+
+ specific->set<Parameter::Specific::environmentalReverb>(erParam);
+ return ndk::ScopedAStatus::ok();
+}
+
+std::shared_ptr<EffectContext> EffectReverb::createContext(const Parameter::Common& common) {
+ if (mContext) {
+ LOG(DEBUG) << __func__ << " context already exist";
+ } else {
+ mContext = std::make_shared<ReverbContext>(1 /* statusFmqDepth */, common, mType);
+ }
+
+ return mContext;
+}
+
+std::shared_ptr<EffectContext> EffectReverb::getContext() {
+ return mContext;
+}
+
+RetCode EffectReverb::releaseContext() {
+ if (mContext) {
+ mContext.reset();
+ }
+ return RetCode::SUCCESS;
+}
+
+ndk::ScopedAStatus EffectReverb::commandImpl(CommandId command) {
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+ switch (command) {
+ case CommandId::START:
+ mContext->enable();
+ break;
+ case CommandId::STOP:
+ mContext->disable();
+ break;
+ case CommandId::RESET:
+ mContext->disable();
+ mContext->resetBuffer();
+ break;
+ default:
+ LOG(ERROR) << __func__ << " commandId " << toString(command) << " not supported";
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "commandIdNotSupported");
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+// Processing method running in EffectWorker thread.
+IEffect::Status EffectReverb::effectProcessImpl(float* in, float* out, int sampleToProcess) {
+ IEffect::Status status = {EX_NULL_POINTER, 0, 0};
+ RETURN_VALUE_IF(!mContext, status, "nullContext");
+ return mContext->lvmProcess(in, out, sampleToProcess);
+}
+
+} // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/lvm/wrapper/Reverb/aidl/EffectReverb.h b/media/libeffects/lvm/wrapper/Reverb/aidl/EffectReverb.h
new file mode 100644
index 0000000..d7d2bbd
--- /dev/null
+++ b/media/libeffects/lvm/wrapper/Reverb/aidl/EffectReverb.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2023 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 <aidl/android/hardware/audio/effect/BnEffect.h>
+
+#include "effect-impl/EffectImpl.h"
+#include "ReverbContext.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+class EffectReverb final : public EffectImpl {
+ public:
+ explicit EffectReverb(const AudioUuid& uuid);
+ ~EffectReverb() override;
+
+ ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
+
+ ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
+ ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
+ Parameter::Specific* specific) override;
+
+ std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
+ std::shared_ptr<EffectContext> getContext() override;
+ RetCode releaseContext() override;
+
+ IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+
+ ndk::ScopedAStatus commandImpl(CommandId command) override;
+
+ std::string getEffectName() override { return *mEffectName; }
+
+ private:
+ std::shared_ptr<ReverbContext> mContext;
+ const Descriptor* mDescriptor;
+ const std::string* mEffectName;
+ lvm::ReverbEffectType mType;
+
+ IEffect::Status status(binder_status_t status, size_t consumed, size_t produced);
+
+ ndk::ScopedAStatus setParameterPresetReverb(const Parameter::Specific& specific);
+ ndk::ScopedAStatus getParameterPresetReverb(const PresetReverb::Id& id,
+ Parameter::Specific* specific);
+
+ ndk::ScopedAStatus setParameterEnvironmentalReverb(const Parameter::Specific& specific);
+ ndk::ScopedAStatus getParameterEnvironmentalReverb(const EnvironmentalReverb::Id& id,
+ Parameter::Specific* specific);
+};
+
+} // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbContext.cpp b/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbContext.cpp
new file mode 100644
index 0000000..d35c22b
--- /dev/null
+++ b/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbContext.cpp
@@ -0,0 +1,560 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cstddef>
+#define LOG_TAG "ReverbContext"
+#include <Utils.h>
+
+#include "ReverbContext.h"
+#include "VectorArithmetic.h"
+#include "math.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+using aidl::android::media::audio::common::AudioDeviceDescription;
+using aidl::android::media::audio::common::AudioDeviceType;
+
+#define GOTO_IF_LVREV_ERROR(status, tag, log) \
+ do { \
+ LVREV_ReturnStatus_en temp = (status); \
+ if (temp != LVREV_SUCCESS) { \
+ LOG(ERROR) << __func__ << " return status: " << temp << " " << (log); \
+ goto tag; \
+ } \
+ } while (0)
+
+RetCode ReverbContext::init() {
+ if (isPreset()) {
+ // force reloading preset at first call to process()
+ mPreset = PresetReverb::Presets::NONE;
+ mNextPreset = PresetReverb::Presets::NONE;
+ }
+
+ mVolume.left = kUnitVolume;
+ mVolume.right = kUnitVolume;
+ mPrevVolume.left = kUnitVolume;
+ mPrevVolume.right = kUnitVolume;
+ volumeMode = VOLUME_FLAT;
+
+ mSamplesToExitCount = kDefaultDecayTime * mCommon.input.base.sampleRate / 1000;
+
+ /* Saved strength is used to return the exact strength that was used in the set to the get
+ * because we map the original strength range of 0:1000 to 1:15, and this will avoid
+ * quantisation like effect when returning
+ */
+ mRoomLevel = lvm::kMinLevel;
+ mRoomHfLevel = 0;
+ mEnabled = LVM_FALSE;
+ mDecayTime = kDefaultDecayTime;
+ mDecayHfRatio = kDefaultDamping * 20;
+ mDensity = kDefaultRoomSize * 10;
+ mDiffusion = kDefaultDensity * 10;
+ mLevel = lvm::kMinLevel;
+
+ // allocate lvm reverb instance
+ LVREV_ReturnStatus_en status = LVREV_SUCCESS;
+ {
+ std::lock_guard lg(mMutex);
+ LVREV_InstanceParams_st params = {
+ .MaxBlockSize = lvm::kMaxCallSize,
+ // Max format, could be mono during process
+ .SourceFormat = LVM_STEREO,
+ .NumDelays = LVREV_DELAYLINES_4,
+ };
+ /* Init sets the instance handle */
+ status = LVREV_GetInstanceHandle(&mInstance, ¶ms);
+ GOTO_IF_LVREV_ERROR(status, deinit, "LVREV_GetInstanceHandleFailed");
+
+ // set control
+ LVREV_ControlParams_st controlParams;
+ initControlParameter(controlParams);
+ status = LVREV_SetControlParameters(mInstance, &controlParams);
+ GOTO_IF_LVREV_ERROR(status, deinit, "LVREV_SetControlParametersFailed");
+ }
+
+ return RetCode::SUCCESS;
+
+deinit:
+ deInit();
+ return RetCode::ERROR_EFFECT_LIB_ERROR;
+}
+
+void ReverbContext::deInit() {
+ std::lock_guard lg(mMutex);
+ if (mInstance) {
+ LVREV_FreeInstance(mInstance);
+ mInstance = nullptr;
+ }
+}
+
+RetCode ReverbContext::enable() {
+ if (mEnabled) return RetCode::ERROR_ILLEGAL_PARAMETER;
+ mEnabled = true;
+ mSamplesToExitCount = (mDecayTime * mCommon.input.base.sampleRate) / 1000;
+ // force no volume ramp for first buffer processed after enabling the effect
+ volumeMode = VOLUME_FLAT;
+ return RetCode::SUCCESS;
+}
+
+RetCode ReverbContext::disable() {
+ if (!mEnabled) return RetCode::ERROR_ILLEGAL_PARAMETER;
+ mEnabled = false;
+ return RetCode::SUCCESS;
+}
+
+bool ReverbContext::isAuxiliary() {
+ return (mType == lvm::ReverbEffectType::AUX_ENV || mType == lvm::ReverbEffectType::AUX_PRESET);
+}
+
+bool ReverbContext::isPreset() {
+ return (mType == lvm::ReverbEffectType::AUX_PRESET ||
+ mType == lvm::ReverbEffectType::INSERT_PRESET);
+}
+
+RetCode ReverbContext::setVolumeStereo(const Parameter::VolumeStereo& volume) {
+ if (volumeMode == VOLUME_OFF) {
+ // force no volume ramp for first buffer processed after getting volume control
+ volumeMode = VOLUME_FLAT;
+ }
+ mVolumeStereo = volume;
+ return RetCode::SUCCESS;
+}
+
+RetCode ReverbContext::setPresetReverbPreset(const PresetReverb::Presets& preset) {
+ mNextPreset = preset;
+ return RetCode::SUCCESS;
+}
+
+RetCode ReverbContext::setEnvironmentalReverbRoomLevel(int roomLevel) {
+ if (roomLevel < lvm::kEnvReverbCap.minRoomLevelMb ||
+ roomLevel > lvm::kEnvReverbCap.maxRoomLevelMb) {
+ LOG(ERROR) << __func__ << " invalid roomLevel: " << roomLevel;
+ return RetCode::ERROR_ILLEGAL_PARAMETER;
+ }
+
+ // Update Control Parameter
+ LVREV_ControlParams_st params;
+ {
+ std::lock_guard lg(mMutex);
+ RETURN_VALUE_IF(LVREV_SUCCESS != LVREV_GetControlParameters(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, " getControlParamFailed");
+
+ // Sum of room and reverb level controls
+ // needs to subtract max levels for both room level and reverb level
+ int combinedLevel = (roomLevel + mLevel) - lvm::kMaxReverbLevel;
+ params.Level = convertLevel(combinedLevel);
+
+ RETURN_VALUE_IF(LVREV_SUCCESS != LVREV_SetControlParameters(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, " setControlParamFailed");
+ }
+ mRoomLevel = roomLevel;
+ return RetCode::SUCCESS;
+}
+
+RetCode ReverbContext::setEnvironmentalReverbRoomHfLevel(int roomHfLevel) {
+ if (roomHfLevel < lvm::kEnvReverbCap.minRoomHfLevelMb ||
+ roomHfLevel > lvm::kEnvReverbCap.maxRoomHfLevelMb) {
+ LOG(ERROR) << __func__ << " invalid roomHfLevel: " << roomHfLevel;
+ return RetCode::ERROR_ILLEGAL_PARAMETER;
+ }
+
+ // Update Control Parameter
+ LVREV_ControlParams_st params;
+ {
+ std::lock_guard lg(mMutex);
+ RETURN_VALUE_IF(LVREV_SUCCESS != LVREV_GetControlParameters(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, " getControlParamFailed");
+
+ params.LPF = convertHfLevel(roomHfLevel);
+
+ RETURN_VALUE_IF(LVREV_SUCCESS != LVREV_SetControlParameters(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, " setControlParamFailed");
+ }
+ mRoomHfLevel = roomHfLevel;
+ return RetCode::SUCCESS;
+}
+
+RetCode ReverbContext::setEnvironmentalReverbDecayTime(int decayTime) {
+ if (decayTime < 0 || decayTime > lvm::kEnvReverbCap.maxDecayTimeMs) {
+ LOG(ERROR) << __func__ << " invalid decayTime: " << decayTime;
+ return RetCode::ERROR_ILLEGAL_PARAMETER;
+ }
+ int time = decayTime;
+ if (time > lvm::kMaxT60) {
+ time = lvm::kMaxT60;
+ }
+
+ // Update Control Parameter
+ LVREV_ControlParams_st params;
+ {
+ std::lock_guard lg(mMutex);
+ RETURN_VALUE_IF(LVREV_SUCCESS != LVREV_GetControlParameters(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, " getControlParamFailed");
+
+ params.T60 = (LVM_UINT16)time;
+ mSamplesToExitCount = (params.T60 * mCommon.input.base.sampleRate) / 1000;
+
+ RETURN_VALUE_IF(LVREV_SUCCESS != LVREV_SetControlParameters(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, " setControlParamFailed");
+ }
+ mDecayTime = time;
+ return RetCode::SUCCESS;
+}
+
+RetCode ReverbContext::setEnvironmentalReverbDecayHfRatio(int decayHfRatio) {
+ if (decayHfRatio < lvm::kEnvReverbCap.minDecayHfRatioPm ||
+ decayHfRatio > lvm::kEnvReverbCap.maxDecayHfRatioPm) {
+ LOG(ERROR) << __func__ << " invalid decayHfRatio: " << decayHfRatio;
+ return RetCode::ERROR_ILLEGAL_PARAMETER;
+ }
+
+ // Update Control Parameter
+ LVREV_ControlParams_st params;
+ {
+ std::lock_guard lg(mMutex);
+ RETURN_VALUE_IF(LVREV_SUCCESS != LVREV_GetControlParameters(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, " getControlParamFailed");
+
+ params.Damping = (LVM_INT16)(decayHfRatio / 20);
+
+ RETURN_VALUE_IF(LVREV_SUCCESS != LVREV_SetControlParameters(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, " setControlParamFailed");
+ }
+ mDecayHfRatio = decayHfRatio;
+ return RetCode::SUCCESS;
+}
+
+RetCode ReverbContext::setEnvironmentalReverbLevel(int level) {
+ if (level < lvm::kEnvReverbCap.minLevelMb || level > lvm::kEnvReverbCap.maxLevelMb) {
+ LOG(ERROR) << __func__ << " invalid level: " << level;
+ return RetCode::ERROR_ILLEGAL_PARAMETER;
+ }
+
+ // Update Control Parameter
+ LVREV_ControlParams_st params;
+ {
+ std::lock_guard lg(mMutex);
+ RETURN_VALUE_IF(LVREV_SUCCESS != LVREV_GetControlParameters(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, " getControlParamFailed");
+
+ // Sum of room and reverb level controls
+ // needs to subtract max levels for both room level and level
+ int combinedLevel = (level + mRoomLevel) - lvm::kMaxReverbLevel;
+ params.Level = convertLevel(combinedLevel);
+
+ RETURN_VALUE_IF(LVREV_SUCCESS != LVREV_SetControlParameters(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, " setControlParamFailed");
+ }
+ mLevel = level;
+ return RetCode::SUCCESS;
+}
+
+RetCode ReverbContext::setEnvironmentalReverbDelay(int delay) {
+ if (delay < 0 || delay > lvm::kEnvReverbCap.maxDelayMs) {
+ LOG(ERROR) << __func__ << " invalid delay: " << delay;
+ return RetCode::ERROR_ILLEGAL_PARAMETER;
+ }
+ mDelay = delay;
+ return RetCode::SUCCESS;
+}
+
+RetCode ReverbContext::setEnvironmentalReverbDiffusion(int diffusion) {
+ if (diffusion < 0 || diffusion > lvm::kEnvReverbCap.maxDiffusionPm) {
+ LOG(ERROR) << __func__ << " invalid diffusion: " << diffusion;
+ return RetCode::ERROR_ILLEGAL_PARAMETER;
+ }
+
+ // Update Control Parameter
+ LVREV_ControlParams_st params;
+ {
+ std::lock_guard lg(mMutex);
+ RETURN_VALUE_IF(LVREV_SUCCESS != LVREV_GetControlParameters(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, " getControlParamFailed");
+
+ params.Density = (LVM_INT16)(diffusion / 10);
+
+ RETURN_VALUE_IF(LVREV_SUCCESS != LVREV_SetControlParameters(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, " setControlParamFailed");
+ }
+ mDiffusion = diffusion;
+ return RetCode::SUCCESS;
+}
+
+RetCode ReverbContext::setEnvironmentalReverbDensity(int density) {
+ if (density < 0 || density > lvm::kEnvReverbCap.maxDensityPm) {
+ LOG(ERROR) << __func__ << " invalid density: " << density;
+ return RetCode::ERROR_ILLEGAL_PARAMETER;
+ }
+
+ // Update Control Parameter
+ LVREV_ControlParams_st params;
+ {
+ std::lock_guard lg(mMutex);
+ RETURN_VALUE_IF(LVREV_SUCCESS != LVREV_GetControlParameters(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, " getControlParamFailed");
+
+ params.RoomSize = (LVM_INT16)(((density * 99) / 1000) + 1);
+
+ RETURN_VALUE_IF(LVREV_SUCCESS != LVREV_SetControlParameters(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, " setControlParamFailed");
+ }
+ mDensity = density;
+ return RetCode::SUCCESS;
+}
+
+RetCode ReverbContext::setEnvironmentalReverbBypass(bool bypass) {
+ mBypass = bypass;
+ return RetCode::SUCCESS;
+}
+
+void ReverbContext::loadPreset() {
+ // TODO: add delay when early reflections are implemented
+ mPreset = mNextPreset;
+
+ if (mPreset != PresetReverb::Presets::NONE) {
+ const t_reverb_settings preset = mReverbPresets[mPreset];
+ setEnvironmentalReverbRoomLevel(preset.roomLevel);
+ setEnvironmentalReverbRoomHfLevel(preset.roomHFLevel);
+ setEnvironmentalReverbDecayTime(preset.decayTime);
+ setEnvironmentalReverbDecayHfRatio(preset.decayHFRatio);
+ setEnvironmentalReverbLevel(preset.reverbLevel);
+ // reverbDelay
+ setEnvironmentalReverbDiffusion(preset.diffusion);
+ setEnvironmentalReverbDensity(preset.density);
+ }
+}
+
+void ReverbContext::initControlParameter(LVREV_ControlParams_st& params) {
+ /* Set the initial process parameters */
+ /* General parameters */
+ params.OperatingMode = LVM_MODE_ON;
+ params.SampleRate = LVM_FS_44100;
+ params.SourceFormat = (::android::hardware::audio::common::getChannelCount(
+ mCommon.input.base.channelMask) == 1
+ ? LVM_MONO
+ : LVM_STEREO);
+
+ if (!isAuxiliary() && params.SourceFormat == LVM_MONO) {
+ params.SourceFormat = LVM_STEREO;
+ }
+
+ /* Reverb parameters */
+ params.Level = kDefaultLevel;
+ params.LPF = kDefaultLPF;
+ params.HPF = kDefaultHPF;
+ params.T60 = kDefaultDecayTime;
+ params.Density = kDefaultDensity;
+ params.Damping = kDefaultDamping;
+ params.RoomSize = kDefaultRoomSize;
+}
+
+/*
+ * Convert level from OpenSL ES format to LVM format
+ *
+ * @param level : level to be applied
+ */
+
+int ReverbContext::convertLevel(int level) {
+ for (int i = 0; i < kLevelMapping.size(); i++) {
+ if (level <= kLevelMapping[i]) {
+ return i;
+ }
+ }
+ return kDefaultLevel;
+}
+
+/*
+ * Convert level HF from OpenSL ES format to LVM format
+ *
+ * @param hfLevel : level to be applied
+ */
+
+int16_t ReverbContext::convertHfLevel(int hfLevel) {
+ for (auto lpfPair : kLPFMapping) {
+ if (hfLevel <= lpfPair.roomHf) {
+ return lpfPair.lpf;
+ }
+ }
+ return kDefaultLPF;
+}
+
+IEffect::Status ReverbContext::lvmProcess(float* in, float* out, int samples) {
+ IEffect::Status status = {EX_NULL_POINTER, 0, 0};
+ RETURN_VALUE_IF(!in, status, "nullInput");
+ RETURN_VALUE_IF(!out, status, "nullOutput");
+ status = {EX_ILLEGAL_STATE, 0, 0};
+ int64_t inputFrameCount = getCommon().input.frameCount;
+ int64_t outputFrameCount = getCommon().output.frameCount;
+ RETURN_VALUE_IF(inputFrameCount != outputFrameCount, status, "FrameCountMismatch");
+ RETURN_VALUE_IF(0 == getInputFrameSize(), status, "zeroFrameSize");
+
+ LOG(DEBUG) << __func__ << " start processing";
+ std::lock_guard lg(mMutex);
+
+ int channels =
+ ::android::hardware::audio::common::getChannelCount(mCommon.input.base.channelMask);
+ int outChannels =
+ ::android::hardware::audio::common::getChannelCount(mCommon.output.base.channelMask);
+ int frameCount = mCommon.input.frameCount;
+
+ // Reverb only effects the stereo channels in multichannel source.
+ if (channels < 1 || channels > LVM_MAX_CHANNELS) {
+ LOG(ERROR) << __func__ << " process invalid PCM channels " << channels;
+ return status;
+ }
+
+ std::vector<float> inFrames(samples);
+ std::vector<float> outFrames(frameCount * FCC_2);
+
+ if (isPreset() && mNextPreset != mPreset) {
+ loadPreset();
+ }
+
+ if (isAuxiliary()) {
+ inFrames.assign(in, in + samples);
+ } else {
+ // mono input is duplicated
+ if (channels >= FCC_2) {
+ for (int i = 0; i < frameCount; i++) {
+ inFrames[FCC_2 * i] = in[channels * i] * kSendLevel;
+ inFrames[FCC_2 * i + 1] = in[channels * i + 1] * kSendLevel;
+ }
+ } else {
+ for (int i = 0; i < frameCount; i++) {
+ inFrames[FCC_2 * i] = inFrames[FCC_2 * i + 1] = in[i] * kSendLevel;
+ }
+ }
+ }
+
+ if (isPreset() && mPreset == PresetReverb::Presets::NONE) {
+ std::fill(outFrames.begin(), outFrames.end(), 0); // always stereo here
+ } else {
+ if (!mEnabled && mSamplesToExitCount > 0) {
+ std::fill(outFrames.begin(), outFrames.end(), 0);
+ LOG(VERBOSE) << "Zeroing " << channels << " samples per frame at the end of call ";
+ }
+
+ /* Process the samples, producing a stereo output */
+ LVREV_ReturnStatus_en lvrevStatus =
+ LVREV_Process(mInstance, /* Instance handle */
+ inFrames.data(), /* Input buffer */
+ outFrames.data(), /* Output buffer */
+ frameCount); /* Number of samples to read */
+ if (lvrevStatus != LVREV_SUCCESS) {
+ LOG(ERROR) << __func__ << lvrevStatus;
+ return {EX_UNSUPPORTED_OPERATION, 0, 0};
+ }
+ }
+ // Convert to 16 bits
+ if (isAuxiliary()) {
+ // nothing to do here
+ } else {
+ if (channels >= FCC_2) {
+ for (int i = 0; i < frameCount; i++) {
+ // Mix with dry input
+ outFrames[FCC_2 * i] += in[channels * i];
+ outFrames[FCC_2 * i + 1] += in[channels * i + 1];
+ }
+ } else {
+ for (int i = 0; i < frameCount; i++) {
+ // Mix with dry input
+ outFrames[FCC_2 * i] += in[i];
+ outFrames[FCC_2 * i + 1] += in[i];
+ }
+ }
+
+ // apply volume with ramp if needed
+ if (mVolume != mPrevVolume && volumeMode == VOLUME_RAMP) {
+ float vl = mPrevVolume.left;
+ float incl = (mVolume.left - vl) / frameCount;
+ float vr = mPrevVolume.right;
+ float incr = (mVolume.right - vr) / frameCount;
+
+ for (int i = 0; i < frameCount; i++) {
+ outFrames[FCC_2 * i] *= vl;
+ outFrames[FCC_2 * i + 1] *= vr;
+
+ vl += incl;
+ vr += incr;
+ }
+ mPrevVolume = mVolume;
+ } else if (volumeMode != VOLUME_OFF) {
+ if (mVolume.left != kUnitVolume || mVolume.right != kUnitVolume) {
+ for (int i = 0; i < frameCount; i++) {
+ outFrames[FCC_2 * i] *= mVolume.left;
+ outFrames[FCC_2 * i + 1] *= mVolume.right;
+ }
+ }
+ mPrevVolume = mVolume;
+ volumeMode = VOLUME_RAMP;
+ }
+ }
+
+ bool accumulate = false;
+ if (outChannels > 2) {
+ // Accumulate if required
+ if (accumulate) {
+ for (int i = 0; i < frameCount; i++) {
+ out[outChannels * i] += outFrames[FCC_2 * i];
+ out[outChannels * i + 1] += outFrames[FCC_2 * i + 1];
+ }
+ } else {
+ for (int i = 0; i < frameCount; i++) {
+ out[outChannels * i] = outFrames[FCC_2 * i];
+ out[outChannels * i + 1] = outFrames[FCC_2 * i + 1];
+ }
+ }
+ if (!isAuxiliary()) {
+ for (int i = 0; i < frameCount; i++) {
+ // channels and outChannels are expected to be same.
+ for (int j = FCC_2; j < outChannels; j++) {
+ out[outChannels * i + j] = in[outChannels * i + j];
+ }
+ }
+ }
+ } else {
+ if (accumulate) {
+ if (outChannels == FCC_1) {
+ for (int i = 0; i < frameCount; i++) {
+ out[i] += ((outFrames[i * FCC_2] + outFrames[i * FCC_2 + 1]) * 0.5f);
+ }
+ } else {
+ for (int i = 0; i < frameCount * FCC_2; i++) {
+ out[i] += outFrames[i];
+ }
+ }
+ } else {
+ if (outChannels == FCC_1) {
+ From2iToMono_Float(outFrames.data(), out, frameCount);
+ } else {
+ for (int i = 0; i < frameCount * FCC_2; i++) {
+ out[i] = outFrames[i];
+ }
+ }
+ }
+ }
+
+ LOG(DEBUG) << __func__ << " done processing";
+
+ if (!mEnabled && mSamplesToExitCount > 0) {
+ // signed - unsigned will trigger integer overflow if result becomes negative.
+ mSamplesToExitCount -= samples;
+ }
+
+ return {STATUS_OK, samples, outChannels * frameCount};
+}
+
+} // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbContext.h b/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbContext.h
new file mode 100644
index 0000000..af49a25
--- /dev/null
+++ b/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbContext.h
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2023 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 <android-base/logging.h>
+#include <android-base/thread_annotations.h>
+#include <unordered_map>
+
+#include "ReverbTypes.h"
+#include "effect-impl/EffectContext.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+enum VolumeMode {
+ VOLUME_OFF,
+ VOLUME_FLAT,
+ VOLUME_RAMP,
+};
+
+struct LPFPair {
+ int roomHf;
+ int lpf;
+};
+
+class ReverbContext final : public EffectContext {
+ public:
+ ReverbContext(int statusDepth, const Parameter::Common& common,
+ const lvm::ReverbEffectType& type)
+ : EffectContext(statusDepth, common), mType(type) {
+ LOG(DEBUG) << __func__ << type;
+ init();
+ }
+ ~ReverbContext() override {
+ LOG(DEBUG) << __func__;
+ deInit();
+ }
+
+ RetCode init();
+ void deInit();
+
+ RetCode enable();
+ RetCode disable();
+
+ bool isAuxiliary();
+ bool isPreset();
+
+ RetCode setPresetReverbPreset(const PresetReverb::Presets& preset);
+ PresetReverb::Presets getPresetReverbPreset() const { return mNextPreset; }
+
+ RetCode setEnvironmentalReverbRoomLevel(int roomLevel);
+ int getEnvironmentalReverbRoomLevel() const { return mRoomLevel; }
+ RetCode setEnvironmentalReverbRoomHfLevel(int roomHfLevel);
+ int getEnvironmentalReverbRoomHfLevel() const { return mRoomHfLevel; }
+ RetCode setEnvironmentalReverbDecayTime(int decayTime);
+ int getEnvironmentalReverbDecayTime() const { return mDecayTime; }
+ RetCode setEnvironmentalReverbDecayHfRatio(int decayHfRatio);
+ int getEnvironmentalReverbDecayHfRatio() const { return mDecayHfRatio; }
+ RetCode setEnvironmentalReverbLevel(int level);
+ int getEnvironmentalReverbLevel() const { return mLevel; }
+ RetCode setEnvironmentalReverbDelay(int delay);
+ int getEnvironmentalReverbDelay() const { return mDelay; }
+ RetCode setEnvironmentalReverbDiffusion(int diffusion);
+ int getEnvironmentalReverbDiffusion() const { return mDiffusion; }
+ RetCode setEnvironmentalReverbDensity(int density);
+ int getEnvironmentalReverbDensity() const { return mDensity; }
+ RetCode setEnvironmentalReverbBypass(bool bypass);
+ bool getEnvironmentalReverbBypass() const { return mBypass; }
+
+ RetCode setVolumeStereo(const Parameter::VolumeStereo& volumeStereo) override;
+ Parameter::VolumeStereo getVolumeStereo() override { return mVolumeStereo; }
+
+ IEffect::Status lvmProcess(float* in, float* out, int samples);
+
+ private:
+ static constexpr inline float kUnitVolume = 1;
+ static constexpr inline float kSendLevel = 0.75f;
+ static constexpr inline int kDefaultLevel = 0;
+ static constexpr inline int kDefaultLPF = 23999; /* Default low pass filter, in Hz */
+ static constexpr inline int kDefaultHPF = 50; /* Default high pass filter, in Hz */
+ static constexpr inline int kDefaultDecayTime = 1490; /* Default Decay time, in ms */
+ static constexpr inline int kDefaultDensity = 100; /* Default Echo density */
+ static constexpr inline int kDefaultDamping = 21;
+ static constexpr inline int kDefaultRoomSize = 100;
+
+ static inline const std::vector<LPFPair> kLPFMapping = {
+ // Limit range to 50 for LVREV parameter range
+ {-10000, 50}, {-5000, 50}, {-4000, 50}, {-3000, 158}, {-2000, 502}, {-1000, 1666},
+ {-900, 1897}, {-800, 2169}, {-700, 2496}, {-600, 2895}, {-500, 3400}, {-400, 4066},
+ {-300, 5011}, {-200, 6537}, {-100, 9826}, {-99, 9881}, {-98, 9937}, {-97, 9994},
+ {-96, 10052}, {-95, 10111}, {-94, 10171}, {-93, 10231}, {-92, 10293}, {-91, 10356},
+ {-90, 10419}, {-89, 10484}, {-88, 10549}, {-87, 10616}, {-86, 10684}, {-85, 10753},
+ {-84, 10823}, {-83, 10895}, {-82, 10968}, {-81, 11042}, {-80, 11117}, {-79, 11194},
+ {-78, 11272}, {-77, 11352}, {-76, 11433}, {-75, 11516}, {-74, 11600}, {-73, 11686},
+ {-72, 11774}, {-71, 11864}, {-70, 11955}, {-69, 12049}, {-68, 12144}, {-67, 12242},
+ {-66, 12341}, {-65, 12443}, {-64, 12548}, {-63, 12654}, {-62, 12763}, {-61, 12875},
+ {-60, 12990}, {-59, 13107}, {-58, 13227}, {-57, 13351}, {-56, 13477}, {-55, 13607},
+ {-54, 13741}, {-53, 13878}, {-52, 14019}, {-51, 14164}, {-50, 14313}, {-49, 14467},
+ {-48, 14626}, {-47, 14789}, {-46, 14958}, {-45, 15132}, {-44, 15312}, {-43, 15498},
+ {-42, 15691}, {-41, 15890}, {-40, 16097}, {-39, 16311}, {-38, 16534}, {-37, 16766},
+ {-36, 17007}, {-35, 17259}, {-34, 17521}, {-33, 17795}, {-32, 18081}, {-31, 18381},
+ {-30, 18696}, {-29, 19027}, {-28, 19375}, {-27, 19742}, {-26, 20129}, {-25, 20540},
+ {-24, 20976}, {-23, 21439}, {-22, 21934}, {-21, 22463}, {-20, 23031}, {-19, 23643},
+ {-18, 23999}};
+
+ static inline const std::vector<int> kLevelMapping = {
+ -12000, -4000, -3398, -3046, -2796, -2603, -2444, -2310, -2194, -2092, -2000, -1918,
+ -1842, -1773, -1708, -1648, -1592, -1540, -1490, -1443, -1398, -1356, -1316, -1277,
+ -1240, -1205, -1171, -1138, -1106, -1076, -1046, -1018, -990, -963, -938, -912,
+ -888, -864, -841, -818, -796, -775, -754, -734, -714, -694, -675, -656,
+ -638, -620, -603, -585, -568, -552, -536, -520, -504, -489, -474, -459,
+ -444, -430, -416, -402, -388, -375, -361, -348, -335, -323, -310, -298,
+ -286, -274, -262, -250, -239, -228, -216, -205, -194, -184, -173, -162,
+ -152, -142, -132, -121, -112, -102, -92, -82, -73, -64, -54, -45,
+ -36, -27, -18, -9, 0};
+
+ static inline std::unordered_map<PresetReverb::Presets, t_reverb_settings> mReverbPresets = {
+ {PresetReverb::Presets::NONE, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+ {PresetReverb::Presets::SMALLROOM,
+ {-400, -600, 1100, 830, -400, 5, 500, 10, 1000, 1000}},
+ {PresetReverb::Presets::MEDIUMROOM,
+ {-400, -600, 1300, 830, -1000, 20, -200, 20, 1000, 1000}},
+ {PresetReverb::Presets::LARGEROOM,
+ {-400, -600, 1500, 830, -1600, 5, -1000, 40, 1000, 1000}},
+ {PresetReverb::Presets::MEDIUMHALL,
+ {-400, -600, 1800, 700, -1300, 15, -800, 30, 1000, 1000}},
+ {PresetReverb::Presets::LARGEHALL,
+ {-400, -600, 1800, 700, -2000, 30, -1400, 60, 1000, 1000}},
+ {PresetReverb::Presets::PLATE, {-400, -200, 1300, 900, 0, 2, 0, 10, 1000, 750}}};
+
+ std::mutex mMutex;
+ const lvm::ReverbEffectType mType;
+ bool mEnabled = false;
+ LVREV_Handle_t mInstance GUARDED_BY(mMutex);
+
+ int mRoomLevel;
+ int mRoomHfLevel;
+ int mDecayTime;
+ int mDecayHfRatio;
+ int mLevel;
+ int mDelay;
+ int mDiffusion;
+ int mDensity;
+ bool mBypass;
+
+ PresetReverb::Presets mPreset;
+ PresetReverb::Presets mNextPreset;
+
+ int mSamplesToExitCount;
+
+ Parameter::VolumeStereo mVolume;
+ Parameter::VolumeStereo mPrevVolume;
+ VolumeMode volumeMode;
+
+ void initControlParameter(LVREV_ControlParams_st& params);
+ int16_t convertHfLevel(int hfLevel);
+ int convertLevel(int level);
+ void loadPreset();
+};
+
+} // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbTypes.h b/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbTypes.h
new file mode 100644
index 0000000..e37602c
--- /dev/null
+++ b/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbTypes.h
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2023 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 <aidl/android/hardware/audio/effect/BnEffect.h>
+#include <android/binder_enums.h>
+#include <audio_effects/effect_environmentalreverb.h>
+#include <audio_effects/effect_presetreverb.h>
+#include "effect-impl/EffectUUID.h"
+// from Reverb/lib
+#include "LVREV.h"
+
+namespace aidl::android::hardware::audio::effect {
+namespace lvm {
+
+constexpr inline int kMaxCallSize = 256;
+constexpr inline int kMinLevel = -6000;
+constexpr inline int kMaxT60 = 7000; /* Maximum decay time */
+constexpr inline int kMaxReverbLevel = 2000;
+constexpr inline int kMaxFrameSize = 2560;
+constexpr inline int kCpuLoadARM9E = 470; // Expressed in 0.1 MIPS
+constexpr inline int kMemUsage = (71 + (kMaxFrameSize >> 7)); // Expressed in kB
+
+static const EnvironmentalReverb::Capability kEnvReverbCap = {.minRoomLevelMb = lvm::kMinLevel,
+ .maxRoomLevelMb = 0,
+ .minRoomHfLevelMb = -4000,
+ .maxRoomHfLevelMb = 0,
+ .maxDecayTimeMs = lvm::kMaxT60,
+ .minDecayHfRatioPm = 100,
+ .maxDecayHfRatioPm = 2000,
+ .minLevelMb = lvm::kMinLevel,
+ .maxLevelMb = 0,
+ .maxDelayMs = 65,
+ .maxDiffusionPm = 1000,
+ .maxDensityPm = 1000};
+
+// NXP SW auxiliary environmental reverb
+static const std::string kAuxEnvReverbEffectName = "Auxiliary Environmental Reverb";
+static const Descriptor kAuxEnvReverbDesc = {
+ .common = {.id = {.type = kEnvReverbTypeUUID,
+ .uuid = kAuxEnvReverbImplUUID,
+ .proxy = std::nullopt},
+ .flags = {.type = Flags::Type::AUXILIARY},
+ .cpuLoad = kCpuLoadARM9E,
+ .memoryUsage = kMemUsage,
+ .name = kAuxEnvReverbEffectName,
+ .implementor = "NXP Software Ltd."},
+ .capability = Capability::make<Capability::environmentalReverb>(kEnvReverbCap)};
+
+// NXP SW insert environmental reverb
+static const std::string kInsertEnvReverbEffectName = "Insert Environmental Reverb";
+static const Descriptor kInsertEnvReverbDesc = {
+ .common = {.id = {.type = kEnvReverbTypeUUID,
+ .uuid = kInsertEnvReverbImplUUID,
+ .proxy = std::nullopt},
+ .flags = {.type = Flags::Type::INSERT,
+ .insert = Flags::Insert::FIRST,
+ .volume = Flags::Volume::CTRL},
+ .cpuLoad = kCpuLoadARM9E,
+ .memoryUsage = kMemUsage,
+ .name = kInsertEnvReverbEffectName,
+ .implementor = "NXP Software Ltd."},
+ .capability = Capability::make<Capability::environmentalReverb>(kEnvReverbCap)};
+
+static const std::vector<PresetReverb::Presets> kSupportedPresets{
+ ndk::enum_range<PresetReverb::Presets>().begin(),
+ ndk::enum_range<PresetReverb::Presets>().end()};
+static const PresetReverb::Capability kPresetReverbCap = {.supportedPresets = kSupportedPresets};
+
+// NXP SW auxiliary preset reverb
+static const std::string kAuxPresetReverbEffectName = "Auxiliary Preset Reverb";
+static const Descriptor kAuxPresetReverbDesc = {
+ .common = {.id = {.type = kPresetReverbTypeUUID,
+ .uuid = kAuxPresetReverbImplUUID,
+ .proxy = std::nullopt},
+ .flags = {.type = Flags::Type::AUXILIARY},
+ .cpuLoad = kCpuLoadARM9E,
+ .memoryUsage = kMemUsage,
+ .name = kAuxPresetReverbEffectName,
+ .implementor = "NXP Software Ltd."},
+ .capability = Capability::make<Capability::presetReverb>(kPresetReverbCap)};
+
+// NXP SW insert preset reverb
+static const std::string kInsertPresetReverbEffectName = "Insert Preset Reverb";
+static const Descriptor kInsertPresetReverbDesc = {
+ .common = {.id = {.type = kPresetReverbTypeUUID,
+ .uuid = kInsertPresetReverbImplUUID,
+ .proxy = std::nullopt},
+ .flags = {.type = Flags::Type::INSERT,
+ .insert = Flags::Insert::FIRST,
+ .volume = Flags::Volume::CTRL},
+ .cpuLoad = kCpuLoadARM9E,
+ .memoryUsage = kMemUsage,
+ .name = kInsertPresetReverbEffectName,
+ .implementor = "NXP Software Ltd."},
+ .capability = Capability::make<Capability::presetReverb>(kPresetReverbCap)};
+
+enum class ReverbEffectType {
+ AUX_ENV,
+ INSERT_ENV,
+ AUX_PRESET,
+ INSERT_PRESET,
+};
+
+inline std::ostream& operator<<(std::ostream& out, const ReverbEffectType& type) {
+ switch (type) {
+ case ReverbEffectType::AUX_ENV:
+ return out << kAuxEnvReverbEffectName;
+ case ReverbEffectType::INSERT_ENV:
+ return out << kInsertEnvReverbEffectName;
+ case ReverbEffectType::AUX_PRESET:
+ return out << kAuxPresetReverbEffectName;
+ case ReverbEffectType::INSERT_PRESET:
+ return out << kInsertPresetReverbEffectName;
+ }
+ return out << "EnumReverbEffectTypeError";
+}
+
+inline std::ostream& operator<<(std::ostream& out, const LVREV_ReturnStatus_en& status) {
+ switch (status) {
+ case LVREV_SUCCESS:
+ return out << "LVREV_SUCCESS";
+ case LVREV_NULLADDRESS:
+ return out << "LVREV_NULLADDRESS";
+ case LVREV_OUTOFRANGE:
+ return out << "LVREV_OUTOFRANGE";
+ case LVREV_INVALIDNUMSAMPLES:
+ return out << "LVREV_INVALIDNUMSAMPLES";
+ case LVREV_RETURNSTATUS_DUMMY:
+ return out << "LVREV_RETURNSTATUS_DUMMY";
+ }
+ return out << "EnumLvrevRetStatusError";
+}
+
+} // namespace lvm
+} // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/preprocessing/PreProcessing.cpp b/media/libeffects/preprocessing/PreProcessing.cpp
index 61a2bf5..59f1fc3 100644
--- a/media/libeffects/preprocessing/PreProcessing.cpp
+++ b/media/libeffects/preprocessing/PreProcessing.cpp
@@ -102,7 +102,8 @@
uint32_t state; // current state (enum preproc_session_state)
int id; // audio session ID
int io; // handle of input stream this session is on
- webrtc::AudioProcessing* apm; // handle on webRTC audio processing module (APM)
+ rtc::scoped_refptr<webrtc::AudioProcessing>
+ apm; // handle on webRTC audio processing module (APM)
// Audio Processing module builder
webrtc::AudioProcessingBuilder ap_builder;
// frameCount represents the size of the buffers used for processing, and must represent 10ms.
@@ -260,9 +261,6 @@
ALOGV("Agc2Init");
effect->session->config = effect->session->apm->GetConfig();
effect->session->config.gain_controller2.fixed_digital.gain_db = 0.f;
- effect->session->config.gain_controller2.adaptive_digital.level_estimator =
- effect->session->config.gain_controller2.kRms;
- effect->session->config.gain_controller2.adaptive_digital.extra_saturation_margin_db = 2.f;
effect->session->apm->ApplyConfig(effect->session->config);
return 0;
}
@@ -332,24 +330,19 @@
ALOGV("Agc2GetParameter() target level %f dB", *(float*)pValue);
break;
case AGC2_PARAM_ADAPT_DIGI_LEVEL_ESTIMATOR:
- *(uint32_t*)pValue = (uint32_t)(
- effect->session->config.gain_controller2.adaptive_digital.level_estimator);
- ALOGV("Agc2GetParameter() level estimator %d",
- *(webrtc::AudioProcessing::Config::GainController2::LevelEstimator*)pValue);
+ // WebRTC only supports RMS level estimator now
+ *(uint32_t*)pValue = (uint32_t)(0);
+ ALOGV("Agc2GetParameter() level estimator RMS");
break;
case AGC2_PARAM_ADAPT_DIGI_EXTRA_SATURATION_MARGIN:
- *(float*)pValue = (float)(effect->session->config.gain_controller2.adaptive_digital
- .extra_saturation_margin_db);
+ *(float*)pValue = (float)(2.0);
ALOGV("Agc2GetParameter() extra saturation margin %f dB", *(float*)pValue);
break;
case AGC2_PARAM_PROPERTIES:
pProperties->fixedDigitalGain =
(float)(effect->session->config.gain_controller2.fixed_digital.gain_db);
- pProperties->level_estimator = (uint32_t)(
- effect->session->config.gain_controller2.adaptive_digital.level_estimator);
- pProperties->extraSaturationMargin =
- (float)(effect->session->config.gain_controller2.adaptive_digital
- .extra_saturation_margin_db);
+ pProperties->level_estimator = 0;
+ pProperties->extraSaturationMargin = 2.0;
break;
default:
ALOGW("Agc2GetParameter() unknown param %d", param);
@@ -438,16 +431,19 @@
effect->session->config.gain_controller2.fixed_digital.gain_db = valueFloat;
break;
case AGC2_PARAM_ADAPT_DIGI_LEVEL_ESTIMATOR:
- ALOGV("Agc2SetParameter() level estimator %d",
- *(webrtc::AudioProcessing::Config::GainController2::LevelEstimator*)pValue);
- effect->session->config.gain_controller2.adaptive_digital.level_estimator =
- (*(webrtc::AudioProcessing::Config::GainController2::LevelEstimator*)pValue);
+ ALOGV("Agc2SetParameter() level estimator %d", *(uint32_t*)pValue);
+ if (*(uint32_t*)pValue != 0) {
+ // only RMS is supported
+ status = -EINVAL;
+ }
break;
case AGC2_PARAM_ADAPT_DIGI_EXTRA_SATURATION_MARGIN:
valueFloat = (float)(*(int32_t*)pValue);
ALOGV("Agc2SetParameter() extra saturation margin %f dB", valueFloat);
- effect->session->config.gain_controller2.adaptive_digital.extra_saturation_margin_db =
- valueFloat;
+ if (valueFloat != 2.0) {
+ // extra_staturation_margin_db is no longer configurable in webrtc
+ status = -EINVAL;
+ }
break;
case AGC2_PARAM_PROPERTIES:
ALOGV("Agc2SetParameter() properties gain %f, level %d margin %f",
@@ -455,11 +451,9 @@
pProperties->extraSaturationMargin);
effect->session->config.gain_controller2.fixed_digital.gain_db =
pProperties->fixedDigitalGain;
- effect->session->config.gain_controller2.adaptive_digital.level_estimator =
- (webrtc::AudioProcessing::Config::GainController2::LevelEstimator)
- pProperties->level_estimator;
- effect->session->config.gain_controller2.adaptive_digital.extra_saturation_margin_db =
- pProperties->extraSaturationMargin;
+ if (pProperties->level_estimator != 0 || pProperties->extraSaturationMargin != 2.0) {
+ status = -EINVAL;
+ }
break;
default:
ALOGW("Agc2SetParameter() unknown param %08x value %08x", param, *(uint32_t*)pValue);
@@ -879,8 +873,8 @@
error:
if (session->createdMsk == 0) {
- delete session->apm;
- session->apm = NULL;
+ // Scoped_refptr will handle reference counting here
+ session->apm = nullptr;
}
return status;
}
@@ -889,8 +883,8 @@
ALOGW_IF(Effect_Release(fx) != 0, " Effect_Release() failed for proc ID %d", fx->procId);
session->createdMsk &= ~(1 << fx->procId);
if (session->createdMsk == 0) {
- delete session->apm;
- session->apm = NULL;
+ // Scoped_refptr will handle reference counting here
+ session->apm = nullptr;
session->id = 0;
}
diff --git a/media/libeffects/preprocessing/tests/EffectPreprocessingTest.cpp b/media/libeffects/preprocessing/tests/EffectPreprocessingTest.cpp
index 07006a1..8fdb864 100644
--- a/media/libeffects/preprocessing/tests/EffectPreprocessingTest.cpp
+++ b/media/libeffects/preprocessing/tests/EffectPreprocessingTest.cpp
@@ -143,10 +143,6 @@
const AGC2Params* agc2Params = ¶ms->agc2Params;
ASSERT_NO_FATAL_FAILURE(
effect.setParam(AGC2_PARAM_FIXED_DIGITAL_GAIN, agc2Params->fixedDigitalGain));
- ASSERT_NO_FATAL_FAILURE(effect.setParam(AGC2_PARAM_ADAPT_DIGI_LEVEL_ESTIMATOR,
- agc2Params->adaptDigiLevelEstimator));
- ASSERT_NO_FATAL_FAILURE(effect.setParam(AGC2_PARAM_ADAPT_DIGI_EXTRA_SATURATION_MARGIN,
- agc2Params->extraSaturationMargin));
} else if (isAECEffect(uuid)) {
const AECParams* aecParams = ¶ms->aecParams;
ASSERT_NO_FATAL_FAILURE(effect.setParam(AEC_PARAM_ECHO_DELAY, aecParams->echoDelay));
diff --git a/media/libeffects/preprocessing/tests/PreProcessingTest.cpp b/media/libeffects/preprocessing/tests/PreProcessingTest.cpp
index 3bd93f8..03400d7 100644
--- a/media/libeffects/preprocessing/tests/PreProcessingTest.cpp
+++ b/media/libeffects/preprocessing/tests/PreProcessingTest.cpp
@@ -400,20 +400,6 @@
ALOGE("Invalid AGC2 Fixed Digital Gain. Error %d\n", status);
return EXIT_FAILURE;
}
- if (int status = preProcSetConfigParam(AGC2_PARAM_ADAPT_DIGI_LEVEL_ESTIMATOR,
- (uint32_t)preProcCfgParams.agc2Level,
- effectHandle[PREPROC_AGC2]);
- status != 0) {
- ALOGE("Invalid AGC2 Level Estimator. Error %d\n", status);
- return EXIT_FAILURE;
- }
- if (int status = preProcSetConfigParam(AGC2_PARAM_ADAPT_DIGI_EXTRA_SATURATION_MARGIN,
- (float)preProcCfgParams.agc2SaturationMargin,
- effectHandle[PREPROC_AGC2]);
- status != 0) {
- ALOGE("Invalid AGC2 Saturation Margin. Error %d\n", status);
- return EXIT_FAILURE;
- }
}
if (effectEn[PREPROC_NS]) {
if (int status = preProcSetConfigParam(NS_PARAM_LEVEL, (uint32_t)preProcCfgParams.nsLevel,
diff --git a/media/libeffects/spatializer/benchmarks/Android.bp b/media/libeffects/spatializer/benchmarks/Android.bp
new file mode 100644
index 0000000..ab7e468
--- /dev/null
+++ b/media/libeffects/spatializer/benchmarks/Android.bp
@@ -0,0 +1,21 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_av_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_av_license"],
+}
+
+cc_benchmark {
+ name: "spatializer_benchmark",
+ vendor: true,
+ srcs: ["spatializer_benchmark.cpp"],
+ shared_libs: [
+ "libaudioutils",
+ "liblog",
+ ],
+ header_libs: [
+ "libhardware_headers",
+ ],
+}
diff --git a/media/libeffects/spatializer/benchmarks/spatializer_benchmark.cpp b/media/libeffects/spatializer/benchmarks/spatializer_benchmark.cpp
new file mode 100644
index 0000000..e8ac480
--- /dev/null
+++ b/media/libeffects/spatializer/benchmarks/spatializer_benchmark.cpp
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <array>
+#include <dlfcn.h>
+#include <random>
+#include <vector>
+
+#include <benchmark/benchmark.h>
+#include <hardware/audio_effect.h>
+#include <log/log.h>
+
+audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = [] {
+ audio_effect_library_t symbol{};
+ void* effectLib = dlopen("libspatialaudio.so", RTLD_NOW);
+ if (effectLib) {
+ audio_effect_library_t* effectInterface =
+ (audio_effect_library_t*)dlsym(effectLib, AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR);
+ if (effectInterface == nullptr) {
+ ALOGE("dlsym failed: %s", dlerror());
+ exit(-1);
+ }
+ symbol = (audio_effect_library_t)(*effectInterface);
+ } else {
+ ALOGE("dlopen failed: %s", dlerror());
+ exit(-1);
+ }
+ return symbol;
+}();
+
+// channel masks
+constexpr int kInputChMask = AUDIO_CHANNEL_OUT_5POINT1;
+
+// sampleRates
+constexpr size_t kSampleRates[] = {
+ 44100,
+ 48000,
+ 96000,
+};
+constexpr size_t kNumSampleRates = std::size(kSampleRates);
+
+// duration in ms
+constexpr size_t kDurations[] = {2, 5, 10};
+constexpr size_t kNumDurations = std::size(kDurations);
+
+// effect uuids
+constexpr effect_uuid_t kEffectUuid = {
+ 0xcc4677de, 0xff72, 0x11eb, 0x9a03, {0x02, 0x42, 0xac, 0x13, 0x00, 0x03}};
+
+constexpr float kMinAmplitude = -1.0f;
+constexpr float kMaxAmplitude = 1.0f;
+
+/*******************************************************************
+ * A test result running on Pixel 5 for comparison.
+ * The first parameter indicates the sample rate.
+ * 0: 44100, 1: 48000, 2: 96000
+ * The second parameter indicates the duration in ms.
+ * 0: 2, 1: 5, 2: 10
+ * -------------------------------------------------------------
+ * Benchmark Time CPU Iterations
+ * -------------------------------------------------------------
+ * BM_SPATIALIZER/0/0 739848 ns 738497 ns 934
+ * BM_SPATIALIZER/0/1 1250503 ns 1248337 ns 480
+ * BM_SPATIALIZER/0/2 2094092 ns 2090092 ns 310
+ * BM_SPATIALIZER/1/0 783114 ns 781626 ns 683
+ * BM_SPATIALIZER/1/1 1332951 ns 1330473 ns 452
+ * BM_SPATIALIZER/1/2 2258313 ns 2254022 ns 289
+ * BM_SPATIALIZER/2/0 1210332 ns 1207957 ns 477
+ * BM_SPATIALIZER/2/1 2356259 ns 2351764 ns 269
+ * BM_SPATIALIZER/2/2 4267814 ns 4259567 ns 155
+ *******************************************************************/
+
+static void BM_SPATIALIZER(benchmark::State& state) {
+ const size_t sampleRate = kSampleRates[state.range(0)];
+ const size_t durationMs = kDurations[state.range(1)];
+ const size_t frameCount = durationMs * sampleRate / 1000;
+ const size_t inputChannelCount = audio_channel_count_from_out_mask(kInputChMask);
+ const size_t outputChannelCount = audio_channel_count_from_out_mask(AUDIO_CHANNEL_OUT_STEREO);
+
+ // Initialize input buffer with deterministic pseudo-random values
+ std::minstd_rand gen(kInputChMask);
+ std::uniform_real_distribution<> dis(kMinAmplitude, kMaxAmplitude);
+ std::vector<float> input(frameCount * inputChannelCount);
+ for (auto& in : input) {
+ in = dis(gen);
+ }
+
+ effect_handle_t effectHandle = nullptr;
+ if (int status = AUDIO_EFFECT_LIBRARY_INFO_SYM.create_effect(&kEffectUuid, 1 /* sessionId */,
+ 1 /* ioId */, &effectHandle);
+ status != 0) {
+ ALOGE("create_effect returned an error = %d\n", status);
+ return;
+ }
+
+ effect_config_t config{};
+ config.inputCfg.samplingRate = config.outputCfg.samplingRate = sampleRate;
+ config.inputCfg.channels = kInputChMask;
+ config.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
+ config.inputCfg.format = config.outputCfg.format = AUDIO_FORMAT_PCM_FLOAT;
+
+ int reply = 0;
+ uint32_t replySize = sizeof(reply);
+ if (int status = (*effectHandle)
+ ->command(effectHandle, EFFECT_CMD_SET_CONFIG, sizeof(effect_config_t),
+ &config, &replySize, &reply);
+ status != 0) {
+ ALOGE("command returned an error = %d\n", status);
+ return;
+ }
+
+ if (int status = (*effectHandle)
+ ->command(effectHandle, EFFECT_CMD_ENABLE, sizeof(effect_config_t),
+ &config, &replySize, &reply);
+ status != 0) {
+ ALOGE("command returned an error = %d\n", status);
+ return;
+ }
+
+ // Run the test
+ std::vector<float> output(frameCount * outputChannelCount);
+ for (auto _ : state) {
+ benchmark::DoNotOptimize(input.data());
+ benchmark::DoNotOptimize(output.data());
+
+ audio_buffer_t inBuffer = {.frameCount = frameCount, .f32 = input.data()};
+ audio_buffer_t outBuffer = {.frameCount = frameCount, .f32 = output.data()};
+ (*effectHandle)->process(effectHandle, &inBuffer, &outBuffer);
+
+ benchmark::ClobberMemory();
+ }
+
+ state.SetComplexityN(frameCount);
+
+ if (int status = AUDIO_EFFECT_LIBRARY_INFO_SYM.release_effect(effectHandle); status != 0) {
+ ALOGE("release_effect returned an error = %d\n", status);
+ return;
+ }
+}
+
+static void SPATIALIZERArgs(benchmark::internal::Benchmark* b) {
+ for (int i = 0; i < kNumSampleRates; i++) {
+ for (int j = 0; j < kNumDurations; ++j) {
+ b->Args({i, j});
+ }
+ }
+}
+
+BENCHMARK(BM_SPATIALIZER)->Apply(SPATIALIZERArgs);
+
+BENCHMARK_MAIN();
diff --git a/media/libeffects/spatializer/tests/Android.bp b/media/libeffects/spatializer/tests/Android.bp
new file mode 100644
index 0000000..704e873
--- /dev/null
+++ b/media/libeffects/spatializer/tests/Android.bp
@@ -0,0 +1,21 @@
+// Build the unit tests for spatializer effect
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_av_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_av_license"],
+}
+
+cc_test {
+ name: "SpatializerTest",
+ defaults: [
+ "libeffects-test-defaults",
+ ],
+ host_supported: false,
+ srcs: [
+ "SpatializerTest.cpp",
+ ],
+}
diff --git a/media/libeffects/spatializer/tests/SpatializerTest.cpp b/media/libeffects/spatializer/tests/SpatializerTest.cpp
new file mode 100644
index 0000000..110fbb1
--- /dev/null
+++ b/media/libeffects/spatializer/tests/SpatializerTest.cpp
@@ -0,0 +1,300 @@
+/*
+ * Copyright 2022 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 "SpatializerTest"
+
+#include <system/audio_effects/effect_spatializer.h>
+#include "EffectTestHelper.h"
+
+using namespace android;
+
+// relying on dlsym to fill the interface context
+audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = [] {
+ audio_effect_library_t symbol{};
+ void* effectLib = dlopen("libspatialaudio.so", RTLD_NOW);
+ if (effectLib) {
+ audio_effect_library_t* effectInterface =
+ (audio_effect_library_t*)dlsym(effectLib, AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR);
+ if (effectInterface == nullptr) {
+ ALOGE("dlsym failed: %s", dlerror());
+ exit(-1);
+ }
+ symbol = (audio_effect_library_t)(*effectInterface);
+ } else {
+ ALOGE("dlopen failed: %s", dlerror());
+ exit(-1);
+ }
+ return symbol;
+}();
+
+// channel masks
+constexpr audio_channel_mask_t kSpatializerChMasks[] = {
+ AUDIO_CHANNEL_OUT_5POINT1,
+};
+constexpr size_t kNumSpatializerChMasks = std::size(kSpatializerChMasks);
+
+// sampleRates
+// TODO(b/234170025): Add all sampling rates once they are handled by spatializer
+constexpr int kSpatializerSampleRates[] = {44100, 48000, 96000};
+constexpr size_t kNumSpatializerSampleRates = std::size(kSpatializerSampleRates);
+
+// frame counts
+// TODO(b/234620538): Add sizes smaller than 80 once they are handled by spatializer
+constexpr size_t kSpatializerFrameCounts[] = {4800, 1920, 480, 80};
+constexpr size_t kNumSpatializerFrameCounts = std::size(kSpatializerFrameCounts);
+
+// effect uuids
+constexpr effect_uuid_t kSpatializerEffectUuids[] = {
+ {0xcc4677de, 0xff72, 0x11eb, 0x9a03, {0x02, 0x42, 0xac, 0x13, 0x00, 0x03}},
+};
+const size_t kNumSpatializerEffectUuids = std::size(kSpatializerEffectUuids);
+
+constexpr float kMinAmplitude = -1.0f;
+constexpr float kMaxAmplitude = 1.0f;
+constexpr float kSNRThreshold = 100.0f;
+constexpr size_t kNumBufferSplits = 2;
+
+using SingleEffectTestParam = std::tuple<int, int, int, int, int>;
+
+class SingleEffectTest : public ::testing::TestWithParam<SingleEffectTestParam> {
+ public:
+ SingleEffectTest()
+ : mInputChMask(kSpatializerChMasks[std::get<0>(GetParam())]),
+ mInputChannelCount(audio_channel_count_from_out_mask(mInputChMask)),
+ mOutputChMask(AUDIO_CHANNEL_OUT_STEREO),
+ mOutputChannelCount(audio_channel_count_from_out_mask(mOutputChMask)),
+ mSampleRate(kSpatializerSampleRates[std::get<1>(GetParam())]),
+ mFrameCount(kSpatializerFrameCounts[std::get<2>(GetParam())]),
+ mLoopCount(EffectTestHelper::kLoopCounts[std::get<3>(GetParam())]),
+ mTotalFrameCount(mFrameCount * mLoopCount),
+ mUuid(&kSpatializerEffectUuids[std::get<4>(GetParam())]) {}
+ void SetUp() override {
+ ASSERT_EQ(AUDIO_EFFECT_LIBRARY_TAG, AUDIO_EFFECT_LIBRARY_INFO_SYM.tag)
+ << "Invalid effect tag";
+ }
+ const size_t mInputChMask;
+ const size_t mInputChannelCount;
+ const size_t mOutputChMask;
+ const size_t mOutputChannelCount;
+ const size_t mSampleRate;
+ const size_t mFrameCount;
+ const size_t mLoopCount;
+ const size_t mTotalFrameCount;
+ const effect_uuid_t* mUuid;
+};
+
+// Test basic spatializer functionality (does not crash) for various combinations of sampling
+// rates, channel masks and frame counts.
+TEST_P(SingleEffectTest, SimpleProcess) {
+ SCOPED_TRACE(testing::Message()
+ << "chMask: " << mInputChMask << " sampleRate: " << mSampleRate);
+
+ EffectTestHelper effect(mUuid, mInputChMask, mOutputChMask, mSampleRate, mFrameCount,
+ mLoopCount);
+ ASSERT_NO_FATAL_FAILURE(effect.createEffect());
+ ASSERT_NO_FATAL_FAILURE(effect.setConfig());
+
+ // Initialize input buffer with deterministic pseudo-random values
+ std::vector<float> input(mTotalFrameCount * mInputChannelCount);
+ std::vector<float> output(mTotalFrameCount * mOutputChannelCount);
+ std::minstd_rand gen(mInputChMask);
+ std::uniform_real_distribution<> dis(kMinAmplitude, kMaxAmplitude);
+ for (auto& in : input) {
+ in = dis(gen);
+ }
+ ASSERT_NO_FATAL_FAILURE(effect.process(input.data(), output.data()));
+ ASSERT_NO_FATAL_FAILURE(effect.releaseEffect());
+}
+
+INSTANTIATE_TEST_SUITE_P(SpatializerTest, SingleEffectTest,
+ ::testing::Combine(::testing::Range(0, (int)kNumSpatializerChMasks),
+ ::testing::Range(0, (int)kNumSpatializerSampleRates),
+ ::testing::Range(0, (int)kNumSpatializerFrameCounts),
+ ::testing::Range(0,
+ (int)EffectTestHelper::kNumLoopCounts),
+ ::testing::Range(0, (int)kNumSpatializerEffectUuids)));
+
+using SingleEffectComparisonTestParam = std::tuple<int, int, int>;
+
+class SingleEffectComparisonTest
+ : public ::testing::TestWithParam<SingleEffectComparisonTestParam> {
+ public:
+ SingleEffectComparisonTest()
+ : mInputChMask(kSpatializerChMasks[std::get<0>(GetParam())]),
+ mInputChannelCount(audio_channel_count_from_out_mask(mInputChMask)),
+ mOutputChMask(AUDIO_CHANNEL_OUT_STEREO),
+ mOutputChannelCount(audio_channel_count_from_out_mask(mOutputChMask)),
+ mSampleRate(kSpatializerSampleRates[std::get<1>(GetParam())]),
+ mUuid(&kSpatializerEffectUuids[std::get<2>(GetParam())]) {}
+
+ const size_t mInputChMask;
+ const size_t mInputChannelCount;
+ const size_t mOutputChMask;
+ const size_t mOutputChannelCount;
+ const size_t mSampleRate;
+ const effect_uuid_t* mUuid;
+};
+
+// Ensure that effect produces similar output when an input is fed in a single call
+// or called multiples times with buffer split into smaller parts
+
+// TODO(b/234619903): This is currently disabled as output from the spatializer has
+// an algorithm delay that varies with frame count and hence makes it tricky to
+// compare output from two cases with different frame counts.
+// Feed valid input to spatializer and dump the output to verify spatializer is being
+// correctly initialized and once that is verified, enable the following
+TEST_P(SingleEffectComparisonTest, DISABLED_SimpleProcess) {
+ SCOPED_TRACE(testing::Message()
+ << "chMask: " << mInputChMask << " sampleRate: " << mSampleRate);
+ int testDurationMs = 20; // 20 ms
+ int testFrameCount = (mSampleRate * testDurationMs) / 1000;
+ int totalFrameCount = testFrameCount * kNumBufferSplits;
+ size_t totalInSamples = totalFrameCount * mInputChannelCount;
+ size_t totalOutSamples = totalFrameCount * mOutputChannelCount;
+ std::vector<float> input(totalInSamples);
+ std::vector<float> outRef(totalOutSamples);
+ std::vector<float> outTest(totalOutSamples);
+
+ // Initialize input buffer with deterministic pseudo-random values
+ std::minstd_rand gen(mInputChMask);
+ std::uniform_real_distribution<> dis(kMinAmplitude, kMaxAmplitude);
+ for (auto& in : input) {
+ in = dis(gen);
+ }
+
+ EffectTestHelper refEffect(mUuid, mInputChMask, mOutputChMask, mSampleRate, totalFrameCount, 1);
+ ASSERT_NO_FATAL_FAILURE(refEffect.createEffect());
+ ASSERT_NO_FATAL_FAILURE(refEffect.setConfig());
+ ASSERT_NO_FATAL_FAILURE(refEffect.process(input.data(), outRef.data()));
+ ASSERT_NO_FATAL_FAILURE(refEffect.releaseEffect());
+
+ EffectTestHelper testEffect(mUuid, mInputChMask, mOutputChMask, mSampleRate,
+ totalFrameCount / kNumBufferSplits, kNumBufferSplits);
+ ASSERT_NO_FATAL_FAILURE(testEffect.createEffect());
+ ASSERT_NO_FATAL_FAILURE(testEffect.setConfig());
+ ASSERT_NO_FATAL_FAILURE(testEffect.process(input.data(), outTest.data()));
+ ASSERT_NO_FATAL_FAILURE(testEffect.releaseEffect());
+
+ float snr = computeSnr(outTest.data(), outRef.data(), totalOutSamples);
+ ASSERT_GT(snr, kSNRThreshold) << "SNR between reference and test output " << snr
+ << " is lower than required " << kSNRThreshold;
+}
+
+INSTANTIATE_TEST_SUITE_P(SpatializerTest, SingleEffectComparisonTest,
+ ::testing::Combine(::testing::Range(0, (int)kNumSpatializerChMasks),
+ ::testing::Range(0, (int)kNumSpatializerSampleRates),
+ ::testing::Range(0, (int)kNumSpatializerEffectUuids)));
+
+// This test checks if get/set Spatializer effect params are in accordance with documentation. The
+// test doesn't validate the functionality of the params configured. It only checks the return
+// status of API calls.
+TEST(ParameterTests, CheckParameterSupport) {
+ EffectTestHelper effect(&kSpatializerEffectUuids[0], kSpatializerChMasks[0],
+ AUDIO_CHANNEL_OUT_STEREO, kSpatializerSampleRates[0],
+ kSpatializerFrameCounts[0], EffectTestHelper::kLoopCounts[0]);
+ ASSERT_NO_FATAL_FAILURE(effect.createEffect());
+
+ // capture list of channel masks supported
+ std::vector<audio_channel_mask_t> channelMasks;
+ int status = effect.getParam<true>(SPATIALIZER_PARAM_SUPPORTED_CHANNEL_MASKS, channelMasks);
+ EXPECT_EQ(status, 0) << "get Param returned an error " << status;
+ if (!status) {
+ EXPECT_EQ(1, channelMasks.size());
+ EXPECT_EQ(AUDIO_CHANNEL_OUT_5POINT1, channelMasks[0]);
+ }
+
+ // capture list of spatialization levels supported
+ std::vector<int8_t> spatializationLevels;
+ status = effect.getParam<true>(SPATIALIZER_PARAM_SUPPORTED_LEVELS, spatializationLevels);
+ EXPECT_EQ(status, 0) << "get Param returned an error " << status;
+ if (!status) {
+ EXPECT_EQ(1, spatializationLevels.size());
+ EXPECT_EQ(SPATIALIZATION_LEVEL_MULTICHANNEL, spatializationLevels[0]);
+ }
+
+ // capture list of spatialization modes supported
+ std::vector<int8_t> spatializationModes;
+ status = effect.getParam<true>(SPATIALIZER_PARAM_SUPPORTED_SPATIALIZATION_MODES,
+ spatializationModes);
+ EXPECT_EQ(status, 0) << "get Param returned an error " << status;
+ if (!status) {
+ EXPECT_EQ(1, spatializationModes.size());
+ EXPECT_EQ(SPATIALIZATION_MODE_BINAURAL, spatializationModes[0]);
+ }
+
+ // check if head tracking is supported
+ std::vector<int8_t> headTracking;
+ status = effect.getParam<false>(SPATIALIZER_PARAM_HEADTRACKING_SUPPORTED, headTracking);
+ EXPECT_EQ(status, 0) << "get Param returned an error " << status;
+ if (!status) {
+ EXPECT_EQ(1, headTracking.size());
+ EXPECT_EQ(true, headTracking[0]);
+ }
+
+ // verify spatialization level setting
+ std::vector<int8_t> level;
+ status = effect.getParam<false>(SPATIALIZER_PARAM_LEVEL, level);
+ EXPECT_EQ(status, 0) << "get Param returned an error " << status;
+ if (!status) {
+ EXPECT_EQ(1, level.size());
+ EXPECT_EQ(SPATIALIZATION_LEVEL_NONE, level[0]);
+ }
+
+ ASSERT_NO_FATAL_FAILURE(effect.setConfig());
+
+ status = effect.getParam<false>(SPATIALIZER_PARAM_LEVEL, level);
+ EXPECT_EQ(status, 0) << "get Param returned an error " << status;
+ if (!status) {
+ EXPECT_EQ(1, level.size());
+ EXPECT_EQ(SPATIALIZATION_LEVEL_MULTICHANNEL, level[0]);
+ }
+
+ // try setting unsupported parameters
+ level.clear();
+ level.push_back(SPATIALIZATION_LEVEL_MCHAN_BED_PLUS_OBJECTS);
+ ASSERT_EQ(1, level.size());
+ EXPECT_NE(0, effect.setParam(SPATIALIZER_PARAM_LEVEL, level));
+
+ // Ensure that unsupported level isn't set by above setParam
+ status = effect.getParam<false>(SPATIALIZER_PARAM_LEVEL, level);
+ EXPECT_EQ(status, 0) << "get Param returned an error " << status;
+ if (!status) {
+ EXPECT_EQ(1, level.size());
+ EXPECT_EQ(SPATIALIZATION_LEVEL_MULTICHANNEL, level[0]);
+ }
+
+ std::vector<float> hingeAngle = {3.1415f};
+ ASSERT_EQ(1, hingeAngle.size());
+ EXPECT_NE(0, effect.setParam(SPATIALIZER_PARAM_HINGE_ANGLE, hingeAngle));
+
+ std::vector<int8_t> headTrackingMode = {2}; // RELATIVE_WORLD
+ ASSERT_EQ(1, headTrackingMode.size());
+ EXPECT_NE(0, effect.setParam(SPATIALIZER_PARAM_HEADTRACKING_MODE, headTrackingMode));
+
+ // try setting supported parameters
+ std::vector<float> vectorFloat = {0.1, 0.2, 0.15, 0.04, 2.23, 3.14};
+ ASSERT_EQ(6, vectorFloat.size());
+ EXPECT_EQ(0, effect.setParam(SPATIALIZER_PARAM_HEAD_TO_STAGE, vectorFloat));
+
+ ASSERT_NO_FATAL_FAILURE(effect.releaseEffect());
+}
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ int status = RUN_ALL_TESTS();
+ ALOGD("Test result = %d\n", status);
+ return status;
+}
diff --git a/media/libeffects/tests/common/Android.bp b/media/libeffects/tests/common/Android.bp
new file mode 100644
index 0000000..73179fb
--- /dev/null
+++ b/media/libeffects/tests/common/Android.bp
@@ -0,0 +1,45 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_av_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_av_license"],
+}
+
+filegroup {
+ name: "libeffects-test-helper-srcs",
+ srcs: [
+ "EffectTestHelper.cpp",
+ ],
+}
+
+cc_library_headers {
+ name: "libeffects-test-helper-headers",
+ vendor: true,
+ host_supported: true,
+ export_include_dirs: [
+ ".",
+ ],
+}
+
+cc_defaults {
+ name: "libeffects-test-defaults",
+ vendor: true,
+ gtest: true,
+ host_supported: true,
+ test_suites: ["device-tests"],
+ static_libs: [
+ "libaudioutils",
+ ],
+ srcs: [
+ ":libeffects-test-helper-srcs",
+ ],
+ header_libs: [
+ "libeffects-test-helper-headers",
+ "libhardware_headers",
+ ],
+ shared_libs: [
+ "liblog",
+ ],
+}
diff --git a/media/libeffects/lvm/tests/EffectTestHelper.cpp b/media/libeffects/tests/common/EffectTestHelper.cpp
similarity index 97%
rename from media/libeffects/lvm/tests/EffectTestHelper.cpp
rename to media/libeffects/tests/common/EffectTestHelper.cpp
index ec727c7..db085ba 100644
--- a/media/libeffects/lvm/tests/EffectTestHelper.cpp
+++ b/media/libeffects/tests/common/EffectTestHelper.cpp
@@ -15,7 +15,6 @@
*/
#include "EffectTestHelper.h"
-extern audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM;
namespace android {
diff --git a/media/libeffects/lvm/tests/EffectTestHelper.h b/media/libeffects/tests/common/EffectTestHelper.h
similarity index 69%
rename from media/libeffects/lvm/tests/EffectTestHelper.h
rename to media/libeffects/tests/common/EffectTestHelper.h
index bcee84e..c99e27a 100644
--- a/media/libeffects/lvm/tests/EffectTestHelper.h
+++ b/media/libeffects/tests/common/EffectTestHelper.h
@@ -21,6 +21,7 @@
#include <audio_utils/primitives.h>
#include <climits>
#include <cstdlib>
+#include <dlfcn.h>
#include <gtest/gtest.h>
#include <hardware/audio_effect.h>
#include <log/log.h>
@@ -29,7 +30,9 @@
#include <system/audio.h>
#include <vector>
+extern audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM;
namespace android {
+
template <typename T>
static float computeSnr(const T* ref, const T* tst, size_t count) {
double signal{};
@@ -82,6 +85,7 @@
void createEffect();
void releaseEffect();
void setConfig();
+
template <typename VALUE_DTYPE>
void setParam(uint32_t type, VALUE_DTYPE const value) {
int reply = 0;
@@ -101,6 +105,76 @@
ASSERT_EQ(status, 0) << "set_param returned an error " << status;
ASSERT_EQ(reply, 0) << "set_param reply non zero " << reply;
};
+
+ template <bool MULTI_VALUES, typename T>
+ int32_t getParam(uint32_t type, std::vector<T>& values) {
+ const int kMaxEffectParamValues = 10;
+ uint32_t cmd[sizeof(effect_param_t) / sizeof(uint32_t) + 1];
+ uint32_t reply[sizeof(effect_param_t) / sizeof(uint32_t) + 1 + 1 + kMaxEffectParamValues];
+
+ effect_param_t* p = (effect_param_t*)cmd;
+ p->psize = sizeof(uint32_t);
+ if (MULTI_VALUES) {
+ p->vsize = (kMaxEffectParamValues + 1) * sizeof(T);
+ } else {
+ p->vsize = sizeof(T);
+ }
+ *(uint32_t*)p->data = type;
+ uint32_t replySize = sizeof(effect_param_t) + p->psize + p->vsize;
+
+ int32_t status = (*mEffectHandle)
+ ->command(mEffectHandle, EFFECT_CMD_GET_PARAM,
+ sizeof(effect_param_t) + sizeof(uint32_t), cmd,
+ &replySize, reply);
+ if (status) {
+ return status;
+ }
+ if (p->status) {
+ return p->status;
+ }
+ if (replySize <
+ sizeof(effect_param_t) + sizeof(uint32_t) + (MULTI_VALUES ? 2 : 1) * sizeof(T)) {
+ return -EINVAL;
+ }
+
+ T* params = (T*)((uint8_t*)reply + sizeof(effect_param_t) + sizeof(uint32_t));
+ int numParams = 1;
+ if (MULTI_VALUES) {
+ numParams = (int)*params++;
+ }
+ if (numParams > kMaxEffectParamValues) {
+ return -EINVAL;
+ }
+ values.clear();
+ std::copy(¶ms[0], ¶ms[numParams], back_inserter(values));
+ return 0;
+ }
+
+ template <typename T>
+ int setParam(uint32_t type, const std::vector<T>& values) {
+ int reply = 0;
+ uint32_t replySize = sizeof(reply);
+
+ uint32_t cmd[sizeof(effect_param_t) / sizeof(uint32_t) + 1 + values.size()];
+ effect_param_t* p = (effect_param_t*)cmd;
+ p->psize = sizeof(uint32_t);
+ p->vsize = sizeof(T) * values.size();
+ *(uint32_t*)p->data = type;
+ memcpy((uint32_t*)p->data + 1, values.data(), sizeof(T) * values.size());
+
+ int status = (*mEffectHandle)
+ ->command(mEffectHandle, EFFECT_CMD_SET_PARAM,
+ sizeof(effect_param_t) + p->psize + p->vsize, p, &replySize,
+ &reply);
+ if (status) {
+ return status;
+ }
+ if (reply) {
+ return reply;
+ }
+ return 0;
+ }
+
void process(float* input, float* output);
// Corresponds to SNR for 1 bit difference between two int16_t signals
diff --git a/media/libeffects/visualizer/Android.bp b/media/libeffects/visualizer/Android.bp
index 8dd6789..fb9d7b7 100644
--- a/media/libeffects/visualizer/Android.bp
+++ b/media/libeffects/visualizer/Android.bp
@@ -18,34 +18,59 @@
],
}
-cc_library_shared {
- name: "libvisualizer",
-
+cc_defaults {
+ name: "visualizer_defaults",
vendor: true,
-
- srcs: [
- "EffectVisualizer.cpp",
- ],
-
cflags: [
- "-O2",
- "-fvisibility=hidden",
-
- "-DBUILD_FLOAT",
+ "-DBUILD_FLOAT", // TODO: remove BUILD_FLOAT and SUPPORT_MC in lvm libs
"-DSUPPORT_MC",
-
"-Wall",
"-Werror",
],
-
shared_libs: [
"liblog",
],
-
- relative_install_path: "soundfx",
-
header_libs: [
"libaudioeffects",
"libaudioutils_headers",
],
}
+
+cc_library_shared {
+ name: "libvisualizer",
+ defaults: [
+ "visualizer_defaults",
+ ],
+ srcs: [
+ "EffectVisualizer.cpp",
+ ],
+ relative_install_path: "soundfx",
+ cflags: [
+ "-O2",
+ "-fvisibility=hidden",
+ ],
+}
+
+cc_library_shared {
+ name: "libvisualizeraidl",
+ srcs: [
+ "aidl/Visualizer.cpp",
+ "aidl/VisualizerContext.cpp",
+ ":effectCommonFile",
+ ],
+ defaults: [
+ "aidlaudioeffectservice_defaults",
+ "latest_android_hardware_audio_effect_ndk_shared",
+ "latest_android_media_audio_common_types_ndk_shared",
+ "visualizer_defaults",
+ ],
+ cflags: [
+ "-Wthread-safety",
+ ],
+ shared_libs: [
+ "libcutils",
+ ],
+ visibility: [
+ "//hardware/interfaces/audio/aidl/default",
+ ],
+}
diff --git a/media/libeffects/visualizer/aidl/Visualizer.cpp b/media/libeffects/visualizer/aidl/Visualizer.cpp
new file mode 100644
index 0000000..28a7287
--- /dev/null
+++ b/media/libeffects/visualizer/aidl/Visualizer.cpp
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2022 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 "AHAL_VisualizerLibEffects"
+
+#include <android-base/logging.h>
+#include "Visualizer.h"
+
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::VisualizerImpl;
+using aidl::android::hardware::audio::effect::kVisualizerImplUUID;
+using aidl::android::hardware::audio::effect::State;
+using aidl::android::media::audio::common::AudioUuid;
+
+extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
+ std::shared_ptr<IEffect>* instanceSpp) {
+ if (!in_impl_uuid || *in_impl_uuid != kVisualizerImplUUID) {
+ LOG(ERROR) << __func__ << "uuid not supported";
+ return EX_ILLEGAL_ARGUMENT;
+ }
+ if (instanceSpp) {
+ *instanceSpp = ndk::SharedRefBase::make<VisualizerImpl>();
+ LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
+ return EX_NONE;
+ } else {
+ LOG(ERROR) << __func__ << " invalid input parameter!";
+ return EX_ILLEGAL_ARGUMENT;
+ }
+}
+
+extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
+ if (!in_impl_uuid || *in_impl_uuid != kVisualizerImplUUID) {
+ LOG(ERROR) << __func__ << "uuid not supported";
+ return EX_ILLEGAL_ARGUMENT;
+ }
+ *_aidl_return = VisualizerImpl::kDescriptor;
+ return EX_NONE;
+}
+
+namespace aidl::android::hardware::audio::effect {
+
+const std::string VisualizerImpl::kEffectName = "Visualizer";
+const Visualizer::Capability VisualizerImpl::kCapability = {
+ .maxLatencyMs = VisualizerContext::kMaxLatencyMs,
+ .captureSampleRange = {.min = 0, .max = VisualizerContext::kMaxCaptureBufSize}};
+const Descriptor VisualizerImpl::kDescriptor = {
+ .common = {.id = {.type = kVisualizerTypeUUID,
+ .uuid = kVisualizerImplUUID,
+ .proxy = std::nullopt},
+ .flags = {.type = Flags::Type::INSERT,
+ .insert = Flags::Insert::LAST,
+ .volume = Flags::Volume::CTRL},
+ .name = VisualizerImpl::kEffectName,
+ .implementor = "The Android Open Source Project"},
+ .capability = Capability::make<Capability::visualizer>(VisualizerImpl::kCapability)};
+
+ndk::ScopedAStatus VisualizerImpl::getDescriptor(Descriptor* _aidl_return) {
+ RETURN_IF(!_aidl_return, EX_ILLEGAL_ARGUMENT, "Parameter:nullptr");
+ LOG(DEBUG) << __func__ << kDescriptor.toString();
+ *_aidl_return = kDescriptor;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus VisualizerImpl::commandImpl(CommandId command) {
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+ switch (command) {
+ case CommandId::START:
+ mContext->enable();
+ break;
+ case CommandId::STOP:
+ mContext->disable();
+ break;
+ case CommandId::RESET:
+ mContext->disable();
+ mContext->resetBuffer();
+ break;
+ default:
+ LOG(ERROR) << __func__ << " commandId " << toString(command) << " not supported";
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "commandIdNotSupported");
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus VisualizerImpl::setOnlyParameter(
+ const Visualizer::SetOnlyParameters& param) {
+ auto tag = param.getTag();
+ switch (tag) {
+ case Visualizer::SetOnlyParameters::latencyMs: {
+ RETURN_IF(mContext->setDownstreamLatency(
+ param.get<Visualizer::SetOnlyParameters::latencyMs>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setLatencyFailed");
+ break;
+ }
+ default: {
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+ EX_ILLEGAL_ARGUMENT, "setOnlyParameterTagNotSupported");
+ }
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus VisualizerImpl::setParameterSpecific(const Parameter::Specific& specific) {
+ RETURN_IF(Parameter::Specific::visualizer != specific.getTag(), EX_ILLEGAL_ARGUMENT,
+ "EffectNotSupported");
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+ auto& param = specific.get<Parameter::Specific::visualizer>();
+ const auto tag = param.getTag();
+ switch (tag) {
+ case Visualizer::captureSamples: {
+ RETURN_IF(mContext->setCaptureSamples(param.get<Visualizer::captureSamples>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setCaptureSizeFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ case Visualizer::scalingMode: {
+ RETURN_IF(mContext->setScalingMode(param.get<Visualizer::scalingMode>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setScalingModeFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ case Visualizer::measurementMode: {
+ RETURN_IF(mContext->setMeasurementMode(param.get<Visualizer::measurementMode>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setMeasurementModeFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ case Visualizer::setOnlyParameters: {
+ return setOnlyParameter(param.get<Visualizer::setOnlyParameters>());
+ }
+ default: {
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+ EX_ILLEGAL_ARGUMENT, "VisualizerTagNotSupported");
+ }
+ }
+}
+
+ndk::ScopedAStatus VisualizerImpl::getOnlyParameter(const Visualizer::GetOnlyParameters::Tag tag,
+ Parameter::Specific* specific) {
+ Visualizer visualizer;
+ Visualizer::GetOnlyParameters param;
+ switch (tag) {
+ case Visualizer::GetOnlyParameters::measurement: {
+ param.set<Visualizer::GetOnlyParameters::measurement>(mContext->getMeasure());
+ break;
+ }
+ case Visualizer::GetOnlyParameters::captureSampleBuffer: {
+ param.set<Visualizer::GetOnlyParameters::captureSampleBuffer>(mContext->capture());
+ break;
+ }
+ default: {
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+ EX_ILLEGAL_ARGUMENT, "setOnlyParameterTagNotSupported");
+ }
+ }
+ visualizer.set<Visualizer::getOnlyParameters>(param);
+ specific->set<Parameter::Specific::visualizer>(visualizer);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus VisualizerImpl::getParameterSpecific(const Parameter::Id& id,
+ Parameter::Specific* specific) {
+ RETURN_IF(!specific, EX_NULL_POINTER, "nullPtr");
+ auto tag = id.getTag();
+ RETURN_IF(Parameter::Id::visualizerTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
+ auto specificId = id.get<Parameter::Id::visualizerTag>();
+ auto specificTag = specificId.getTag();
+ switch (specificTag) {
+ case Visualizer::Id::commonTag: {
+ return getParameterVisualizer(specificId.get<Visualizer::Id::commonTag>(), specific);
+ }
+ case Visualizer::Id::getOnlyParamTag: {
+ return getOnlyParameter(specificId.get<Visualizer::Id::getOnlyParamTag>(), specific);
+ }
+ default: {
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(specificTag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "VisualizerTagNotSupported");
+ }
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus VisualizerImpl::getParameterVisualizer(const Visualizer::Tag& tag,
+ Parameter::Specific* specific) {
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+ Visualizer param;
+ switch (tag) {
+ case Visualizer::captureSamples: {
+ param.set<Visualizer::captureSamples>(mContext->getCaptureSamples());
+ break;
+ }
+ case Visualizer::scalingMode: {
+ param.set<Visualizer::scalingMode>(mContext->getScalingMode());
+ break;
+ }
+ case Visualizer::measurementMode: {
+ param.set<Visualizer::measurementMode>(mContext->getMeasurementMode());
+ break;
+ }
+ default: {
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+ EX_ILLEGAL_ARGUMENT, "VisualizerTagNotSupported");
+ }
+ }
+
+ specific->set<Parameter::Specific::visualizer>(param);
+ return ndk::ScopedAStatus::ok();
+}
+
+std::shared_ptr<EffectContext> VisualizerImpl::createContext(const Parameter::Common& common) {
+ if (mContext) {
+ LOG(DEBUG) << __func__ << " context already exist";
+ return mContext;
+ }
+
+ mContext = std::make_shared<VisualizerContext>(1 /* statusFmqDepth */, common);
+ mContext->initParams(common);
+ return mContext;
+}
+
+RetCode VisualizerImpl::releaseContext() {
+ if (mContext) {
+ mContext->disable();
+ mContext->resetBuffer();
+ }
+ return RetCode::SUCCESS;
+}
+
+// Processing method running in EffectWorker thread.
+IEffect::Status VisualizerImpl::effectProcessImpl(float* in, float* out, int samples) {
+ IEffect::Status status = {EX_NULL_POINTER, 0, 0};
+ RETURN_VALUE_IF(!mContext, status, "nullContext");
+ return mContext->process(in, out, samples);
+}
+
+} // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/visualizer/aidl/Visualizer.h b/media/libeffects/visualizer/aidl/Visualizer.h
new file mode 100644
index 0000000..5908d9a
--- /dev/null
+++ b/media/libeffects/visualizer/aidl/Visualizer.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2022 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 <aidl/android/hardware/audio/effect/BnEffect.h>
+
+#include "effect-impl/EffectImpl.h"
+#include "effect-impl/EffectUUID.h"
+
+#include "VisualizerContext.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+class VisualizerImpl final : public EffectImpl {
+ public:
+ static const std::string kEffectName;
+ static const Visualizer::Capability kCapability;
+ static const Descriptor kDescriptor;
+ VisualizerImpl() { LOG(DEBUG) << __func__; }
+ ~VisualizerImpl() {
+ cleanUp();
+ LOG(DEBUG) << __func__;
+ }
+
+ ndk::ScopedAStatus commandImpl(CommandId command) override;
+ ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
+ ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
+ ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
+ Parameter::Specific* specific) override;
+ IEffect::Status effectProcessImpl(float* in, float* out, int process) override;
+ std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
+ RetCode releaseContext() override;
+
+ std::shared_ptr<EffectContext> getContext() override { return mContext; }
+ std::string getEffectName() override { return kEffectName; }
+
+ private:
+ std::shared_ptr<VisualizerContext> mContext;
+ ndk::ScopedAStatus getParameterVisualizer(const Visualizer::Tag& tag,
+ Parameter::Specific* specific);
+ ndk::ScopedAStatus setOnlyParameter(const Visualizer::SetOnlyParameters& param);
+ ndk::ScopedAStatus getOnlyParameter(const Visualizer::GetOnlyParameters::Tag tag,
+ Parameter::Specific* specific);
+};
+
+} // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/visualizer/aidl/VisualizerContext.cpp b/media/libeffects/visualizer/aidl/VisualizerContext.cpp
new file mode 100644
index 0000000..1965e0e
--- /dev/null
+++ b/media/libeffects/visualizer/aidl/VisualizerContext.cpp
@@ -0,0 +1,331 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "VisualizerContext.h"
+
+#include <algorithm>
+#include <android/binder_status.h>
+#include <audio_utils/primitives.h>
+#include <math.h>
+#include <system/audio.h>
+#include <time.h>
+#include <Utils.h>
+
+#ifndef BUILD_FLOAT
+ #error AIDL Visualizer only support float 32bits, make sure add cflags -DBUILD_FLOAT,
+#endif
+
+using android::hardware::audio::common::getChannelCount;
+
+namespace aidl::android::hardware::audio::effect {
+
+VisualizerContext::VisualizerContext(int statusDepth, const Parameter::Common& common)
+ : EffectContext(statusDepth, common) {
+}
+
+VisualizerContext::~VisualizerContext() {
+ std::lock_guard lg(mMutex);
+ LOG(DEBUG) << __func__;
+ mState = State::UNINITIALIZED;
+}
+
+RetCode VisualizerContext::initParams(const Parameter::Common& common) {
+ std::lock_guard lg(mMutex);
+ LOG(DEBUG) << __func__;
+ if (common.input != common.output) {
+ LOG(ERROR) << __func__ << " mismatch input: " << common.input.toString()
+ << " and output: " << common.output.toString();
+ return RetCode::ERROR_ILLEGAL_PARAMETER;
+ }
+
+ mState = State::INITIALIZED;
+ auto channelCount = getChannelCount(common.input.base.channelMask);
+#ifdef SUPPORT_MC
+ if (channelCount < 1 || channelCount > FCC_LIMIT) return RetCode::ERROR_ILLEGAL_PARAMETER;
+#else
+ if (channelCount != FCC_2) return RetCode::ERROR_ILLEGAL_PARAMETER;
+#endif
+ mChannelCount = channelCount;
+ mCommon = common;
+ return RetCode::SUCCESS;
+}
+
+RetCode VisualizerContext::enable() {
+ std::lock_guard lg(mMutex);
+ if (mState != State::INITIALIZED) {
+ return RetCode::ERROR_EFFECT_LIB_ERROR;
+ }
+ mState = State::ACTIVE;
+ return RetCode::SUCCESS;
+}
+
+RetCode VisualizerContext::disable() {
+ std::lock_guard lg(mMutex);
+ if (mState != State::ACTIVE) {
+ return RetCode::ERROR_EFFECT_LIB_ERROR;
+ }
+ mState = State::INITIALIZED;
+ return RetCode::SUCCESS;
+}
+
+void VisualizerContext::reset() {
+ std::lock_guard lg(mMutex);
+ std::fill_n(mCaptureBuf.begin(), kMaxCaptureBufSize, 0x80);
+}
+
+RetCode VisualizerContext::setCaptureSamples(int samples) {
+ std::lock_guard lg(mMutex);
+ if (samples < 0 || (unsigned)samples > kMaxCaptureBufSize) {
+ LOG(ERROR) << __func__ << " captureSamples " << samples << " exceed valid range: 0 - "
+ << kMaxCaptureBufSize;
+ return RetCode::ERROR_ILLEGAL_PARAMETER;
+ }
+ mCaptureSamples = samples;
+ return RetCode::SUCCESS;
+}
+int VisualizerContext::getCaptureSamples() {
+ std::lock_guard lg(mMutex);
+ return mCaptureSamples;
+}
+
+RetCode VisualizerContext::setMeasurementMode(Visualizer::MeasurementMode mode) {
+ std::lock_guard lg(mMutex);
+ mMeasurementMode = mode;
+ return RetCode::SUCCESS;
+}
+Visualizer::MeasurementMode VisualizerContext::getMeasurementMode() {
+ std::lock_guard lg(mMutex);
+ return mMeasurementMode;
+}
+
+RetCode VisualizerContext::setScalingMode(Visualizer::ScalingMode mode) {
+ std::lock_guard lg(mMutex);
+ mScalingMode = mode;
+ return RetCode::SUCCESS;
+}
+Visualizer::ScalingMode VisualizerContext::getScalingMode() {
+ std::lock_guard lg(mMutex);
+ return mScalingMode;
+}
+
+RetCode VisualizerContext::setDownstreamLatency(int latency) {
+ if (latency < 0 || (unsigned)latency > kMaxLatencyMs) {
+ LOG(ERROR) << __func__ << " latency " << latency << " exceed valid range: 0 - "
+ << kMaxLatencyMs;
+ return RetCode::ERROR_ILLEGAL_PARAMETER;
+ }
+ std::lock_guard lg(mMutex);
+ mDownstreamLatency = latency;
+ return RetCode::SUCCESS;
+}
+
+uint32_t VisualizerContext::getDeltaTimeMsFromUpdatedTime_l() {
+ uint32_t deltaMs = 0;
+ if (mBufferUpdateTime.tv_sec != 0) {
+ struct timespec ts;
+ if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
+ time_t secs = ts.tv_sec - mBufferUpdateTime.tv_sec;
+ long nsec = ts.tv_nsec - mBufferUpdateTime.tv_nsec;
+ if (nsec < 0) {
+ --secs;
+ nsec += 1000000000;
+ }
+ deltaMs = secs * 1000 + nsec / 1000000;
+ }
+ }
+ return deltaMs;
+}
+
+Visualizer::GetOnlyParameters::Measurement VisualizerContext::getMeasure() {
+ uint16_t peakU16 = 0;
+ float sumRmsSquared = 0.0f;
+ uint8_t nbValidMeasurements = 0;
+
+ {
+ std::lock_guard lg(mMutex);
+ // reset measurements if last measurement was too long ago (which implies stored
+ // measurements aren't relevant anymore and shouldn't bias the new one)
+ const uint32_t delayMs = getDeltaTimeMsFromUpdatedTime_l();
+ if (delayMs > kDiscardMeasurementsTimeMs) {
+ LOG(INFO) << __func__ << " Discarding " << delayMs << " ms old measurements";
+ for (uint32_t i = 0; i < mMeasurementWindowSizeInBuffers; i++) {
+ mPastMeasurements[i].mIsValid = false;
+ mPastMeasurements[i].mPeakU16 = 0;
+ mPastMeasurements[i].mRmsSquared = 0;
+ }
+ mMeasurementBufferIdx = 0;
+ } else {
+ // only use actual measurements, otherwise the first RMS measure happening before
+ // MEASUREMENT_WINDOW_MAX_SIZE_IN_BUFFERS have been played will always be artificially
+ // low
+ for (uint32_t i = 0; i < mMeasurementWindowSizeInBuffers; i++) {
+ if (mPastMeasurements[i].mIsValid) {
+ if (mPastMeasurements[i].mPeakU16 > peakU16) {
+ peakU16 = mPastMeasurements[i].mPeakU16;
+ }
+ sumRmsSquared += mPastMeasurements[i].mRmsSquared;
+ nbValidMeasurements++;
+ }
+ }
+ }
+ }
+
+ float rms = nbValidMeasurements == 0 ? 0.0f : sqrtf(sumRmsSquared / nbValidMeasurements);
+ Visualizer::GetOnlyParameters::Measurement measure;
+ // convert from I16 sample values to mB and write results
+ measure.rms = (rms < 0.000016f) ? -9600 : (int32_t)(2000 * log10(rms / 32767.0f));
+ measure.peak = (peakU16 == 0) ? -9600 : (int32_t)(2000 * log10(peakU16 / 32767.0f));
+ LOG(INFO) << __func__ << " peak " << peakU16 << " (" << measure.peak << "mB), rms " << rms
+ << " (" << measure.rms << "mB)";
+ return measure;
+}
+
+std::vector<uint8_t> VisualizerContext::capture() {
+ std::vector<uint8_t> result;
+ std::lock_guard lg(mMutex);
+ RETURN_VALUE_IF(mState != State::ACTIVE, result, "illegalState");
+ const uint32_t deltaMs = getDeltaTimeMsFromUpdatedTime_l();
+
+ // if audio framework has stopped playing audio although the effect is still active we must
+ // clear the capture buffer to return silence
+ if ((mLastCaptureIdx == mCaptureIdx) && (mBufferUpdateTime.tv_sec != 0) &&
+ (deltaMs > kMaxStallTimeMs)) {
+ LOG(INFO) << __func__ << " capture going to idle";
+ mBufferUpdateTime.tv_sec = 0;
+ return result;
+ }
+ int32_t latencyMs = mDownstreamLatency;
+ latencyMs -= deltaMs;
+ if (latencyMs < 0) {
+ latencyMs = 0;
+ }
+ uint32_t deltaSamples = mCaptureSamples + mCommon.input.base.sampleRate * latencyMs / 1000;
+
+ // large sample rate, latency, or capture size, could cause overflow.
+ // do not offset more than the size of buffer.
+ if (deltaSamples > kMaxCaptureBufSize) {
+ android_errorWriteLog(0x534e4554, "31781965");
+ deltaSamples = kMaxCaptureBufSize;
+ }
+
+ int32_t capturePoint;
+ //capturePoint = (int32_t)mCaptureIdx - deltaSamples;
+ __builtin_sub_overflow((int32_t) mCaptureIdx, deltaSamples, &capturePoint);
+ // a negative capturePoint means we wrap the buffer.
+ if (capturePoint < 0) {
+ uint32_t size = -capturePoint;
+ if (size > mCaptureSamples) {
+ size = mCaptureSamples;
+ }
+ result.insert(result.end(), &mCaptureBuf[kMaxCaptureBufSize + capturePoint],
+ &mCaptureBuf[kMaxCaptureBufSize + capturePoint + size]);
+ mCaptureSamples -= size;
+ capturePoint = 0;
+ }
+ result.insert(result.end(), &mCaptureBuf[capturePoint],
+ &mCaptureBuf[capturePoint + mCaptureSamples]);
+ mLastCaptureIdx = mCaptureIdx;
+ return result;
+}
+
+IEffect::Status VisualizerContext::process(float* in, float* out, int samples) {
+ IEffect::Status result = {STATUS_NOT_ENOUGH_DATA, 0, 0};
+ RETURN_VALUE_IF(in == nullptr || out == nullptr || samples == 0, result, "dataBufferError");
+
+ std::lock_guard lg(mMutex);
+ result.status = STATUS_INVALID_OPERATION;
+ RETURN_VALUE_IF(mState != State::ACTIVE, result, "stateNotActive");
+ LOG(DEBUG) << __func__ << " in " << in << " out " << out << " sample " << samples;
+ // perform measurements if needed
+ if (mMeasurementMode == Visualizer::MeasurementMode::PEAK_RMS) {
+ // find the peak and RMS squared for the new buffer
+ float rmsSqAcc = 0;
+ float maxSample = 0.f;
+ for (size_t inIdx = 0; inIdx < (unsigned)samples; ++inIdx) {
+ maxSample = fmax(maxSample, fabs(in[inIdx]));
+ rmsSqAcc += in[inIdx] * in[inIdx];
+ }
+ maxSample *= 1 << 15; // scale to int16_t, with exactly 1 << 15 representing positive num.
+ rmsSqAcc *= 1 << 30; // scale to int16_t * 2
+ mPastMeasurements[mMeasurementBufferIdx] = {
+ .mPeakU16 = (uint16_t)maxSample,
+ .mRmsSquared = rmsSqAcc / samples,
+ .mIsValid = true };
+ if (++mMeasurementBufferIdx >= mMeasurementWindowSizeInBuffers) {
+ mMeasurementBufferIdx = 0;
+ }
+ }
+
+ float fscale; // multiplicative scale
+ if (mScalingMode == Visualizer::ScalingMode::NORMALIZED) {
+ // derive capture scaling factor from peak value in current buffer
+ // this gives more interesting captures for display.
+ float maxSample = 0.f;
+ for (size_t inIdx = 0; inIdx < (unsigned)samples; ) {
+ // we reconstruct the actual summed value to ensure proper normalization
+ // for multichannel outputs (channels > 2 may often be 0).
+ float smp = 0.f;
+ for (int i = 0; i < mChannelCount; ++i) {
+ smp += in[inIdx++];
+ }
+ maxSample = fmax(maxSample, fabs(smp));
+ }
+ if (maxSample > 0.f) {
+ fscale = 0.99f / maxSample;
+ int exp; // unused
+ const float significand = frexp(fscale, &exp);
+ if (significand == 0.5f) {
+ fscale *= 255.f / 256.f; // avoid returning unaltered PCM signal
+ }
+ } else {
+ // scale doesn't matter, the values are all 0.
+ fscale = 1.f;
+ }
+ } else {
+ assert(mScalingMode == Visualizer::ScalingMode::AS_PLAYED);
+ // Note: if channels are uncorrelated, 1/sqrt(N) could be used at the risk of clipping.
+ fscale = 1.f / mChannelCount; // account for summing all the channels together.
+ }
+
+ uint32_t captIdx;
+ uint32_t inIdx;
+ for (inIdx = 0, captIdx = mCaptureIdx; inIdx < (unsigned)samples; captIdx++) {
+ // wrap
+ if (captIdx >= kMaxCaptureBufSize) {
+ captIdx = 0;
+ }
+
+ float smp = 0.f;
+ for (uint32_t i = 0; i < mChannelCount; ++i) {
+ smp += in[inIdx++];
+ }
+ mCaptureBuf[captIdx] = clamp8_from_float(smp * fscale);
+ }
+
+ // the following two should really be atomic, though it probably doesn't
+ // matter much for visualization purposes
+ mCaptureIdx = captIdx;
+ // update last buffer update time stamp
+ if (clock_gettime(CLOCK_MONOTONIC, &mBufferUpdateTime) < 0) {
+ mBufferUpdateTime.tv_sec = 0;
+ }
+
+ // TODO: handle access_mode
+ memcpy(out, in, samples * sizeof(float));
+ return {STATUS_OK, samples, samples};
+}
+
+} // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/visualizer/aidl/VisualizerContext.h b/media/libeffects/visualizer/aidl/VisualizerContext.h
new file mode 100644
index 0000000..bfda0b9
--- /dev/null
+++ b/media/libeffects/visualizer/aidl/VisualizerContext.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2022 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 <android-base/thread_annotations.h>
+#include <audio_effects/effect_dynamicsprocessing.h>
+
+#include "effect-impl/EffectContext.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+class VisualizerContext final : public EffectContext {
+ public:
+ static const uint32_t kMaxCaptureBufSize = 65536;
+ static const uint32_t kMaxLatencyMs = 3000; // 3 seconds of latency for audio pipeline
+
+ VisualizerContext(int statusDepth, const Parameter::Common& common);
+ ~VisualizerContext();
+
+ RetCode initParams(const Parameter::Common& common);
+
+ RetCode enable();
+ RetCode disable();
+ // keep all parameters and reset buffer.
+ void reset();
+
+ RetCode setCaptureSamples(int captureSize);
+ int getCaptureSamples();
+ RetCode setMeasurementMode(Visualizer::MeasurementMode mode);
+ Visualizer::MeasurementMode getMeasurementMode();
+ RetCode setScalingMode(Visualizer::ScalingMode mode);
+ Visualizer::ScalingMode getScalingMode();
+ RetCode setDownstreamLatency(int latency);
+
+ IEffect::Status process(float* in, float* out, int samples);
+ // Gets the current measurements, measured by process() and consumed by getParameter()
+ Visualizer::GetOnlyParameters::Measurement getMeasure();
+ // Gets the latest PCM capture, data captured by process() and consumed by getParameter()
+ std::vector<uint8_t> capture();
+
+ struct BufferStats {
+ bool mIsValid;
+ uint16_t mPeakU16; // the positive peak of the absolute value of the samples in a buffer
+ float mRmsSquared; // the average square of the samples in a buffer
+ };
+
+ enum State {
+ UNINITIALIZED,
+ INITIALIZED,
+ ACTIVE,
+ };
+
+ private:
+ // maximum time since last capture buffer update before resetting capture buffer. This means
+ // that the framework has stopped playing audio and we must start returning silence
+ static const uint32_t kMaxStallTimeMs = 1000;
+ // discard measurements older than this number of ms
+ static const uint32_t kDiscardMeasurementsTimeMs = 2000;
+ // maximum number of buffers for which we keep track of the measurements
+ // note: buffer index is stored in uint8_t
+ static const uint32_t kMeasurementWindowMaxSizeInBuffers = 25;
+
+ // serialize process() and parameter setting
+ std::mutex mMutex;
+ Parameter::Common mCommon GUARDED_BY(mMutex);
+ State mState GUARDED_BY(mMutex) = State::UNINITIALIZED;
+ uint32_t mCaptureIdx GUARDED_BY(mMutex) = 0;
+ uint32_t mLastCaptureIdx GUARDED_BY(mMutex) = 0;
+ Visualizer::ScalingMode mScalingMode GUARDED_BY(mMutex) = Visualizer::ScalingMode::NORMALIZED;
+ struct timespec mBufferUpdateTime GUARDED_BY(mMutex);
+ // capture buf with 8 bits PCM
+ std::array<uint8_t, kMaxCaptureBufSize> mCaptureBuf GUARDED_BY(mMutex);
+ uint32_t mDownstreamLatency GUARDED_BY(mMutex) = 0;
+ uint32_t mCaptureSamples GUARDED_BY(mMutex) = kMaxCaptureBufSize;
+
+ // to avoid recomputing it every time a buffer is processed
+ uint8_t mChannelCount GUARDED_BY(mMutex) = 0;
+ Visualizer::MeasurementMode mMeasurementMode GUARDED_BY(mMutex) =
+ Visualizer::MeasurementMode::NONE;
+ uint8_t mMeasurementWindowSizeInBuffers = kMeasurementWindowMaxSizeInBuffers;
+ uint8_t mMeasurementBufferIdx GUARDED_BY(mMutex) = 0;
+ std::array<BufferStats, kMeasurementWindowMaxSizeInBuffers> mPastMeasurements;
+ void init_params();
+
+ uint32_t getDeltaTimeMsFromUpdatedTime_l() REQUIRES(mMutex);
+};
+} // namespace aidl::android::hardware::audio::effect
diff --git a/media/liberror/Android.bp b/media/liberror/Android.bp
index f54d354..5e94b0a 100644
--- a/media/liberror/Android.bp
+++ b/media/liberror/Android.bp
@@ -25,7 +25,7 @@
],
apex_available: [
"//apex_available:platform",
- "com.android.bluetooth",
+ "com.android.btservices",
"com.android.media",
"com.android.media.swcodec",
],
@@ -51,7 +51,7 @@
min_sdk_version: "29",
apex_available: [
"//apex_available:platform",
- "com.android.bluetooth",
+ "com.android.btservices",
"com.android.media",
"com.android.media.swcodec",
],
diff --git a/media/libmedia/Android.bp b/media/libmedia/Android.bp
index 2dd5784..ab1cf69 100644
--- a/media/libmedia/Android.bp
+++ b/media/libmedia/Android.bp
@@ -304,6 +304,10 @@
cc_library {
name: "libmedia",
+ defaults: [
+ "latest_android_media_audio_common_types_cpp_shared",
+ ],
+
srcs: [
":mediaextractorservice_aidl",
"IDataSource.cpp",
@@ -356,7 +360,6 @@
shared_libs: [
"android.hidl.token@1.0-utils",
- "android.media.audio.common.types-V1-cpp",
"audioclient-types-aidl-cpp",
"av-types-aidl-cpp",
"liblog",
diff --git a/media/libmedia/tests/codeclist/CodecListTest.cpp b/media/libmedia/tests/codeclist/CodecListTest.cpp
index bd2adf7..75adcca 100644
--- a/media/libmedia/tests/codeclist/CodecListTest.cpp
+++ b/media/libmedia/tests/codeclist/CodecListTest.cpp
@@ -18,6 +18,8 @@
#define LOG_TAG "CodecListTest"
#include <utils/Log.h>
+#include <memory>
+
#include <gtest/gtest.h>
#include <binder/Parcel.h>
@@ -194,16 +196,15 @@
}
}
- Parcel *codecInfoParcel = new Parcel();
+ std::unique_ptr<Parcel> codecInfoParcel(new Parcel());
ASSERT_NE(codecInfoParcel, nullptr) << "Unable to create parcel";
- status_t status = info->writeToParcel(codecInfoParcel);
+ status_t status = info->writeToParcel(codecInfoParcel.get());
ASSERT_EQ(status, OK) << "Writing to parcel failed";
codecInfoParcel->setDataPosition(0);
sp<MediaCodecInfo> parcelCodecInfo = info->FromParcel(*codecInfoParcel);
ASSERT_NE(parcelCodecInfo, nullptr) << "CodecInfo from parcel is null";
- delete codecInfoParcel;
EXPECT_STREQ(info->getCodecName(), parcelCodecInfo->getCodecName())
<< "Returned codec name in info doesn't match";
diff --git a/media/libmediahelper/Android.bp b/media/libmediahelper/Android.bp
index 165a8ad..c66861b 100644
--- a/media/libmediahelper/Android.bp
+++ b/media/libmediahelper/Android.bp
@@ -20,7 +20,7 @@
},
apex_available: [
"//apex_available:platform",
- "com.android.bluetooth",
+ "com.android.btservices",
"com.android.media",
"com.android.media.swcodec",
],
diff --git a/media/libmediametrics/libmediametrics.map.txt b/media/libmediametrics/libmediametrics.map.txt
index c46281a..f37af64 100644
--- a/media/libmediametrics/libmediametrics.map.txt
+++ b/media/libmediametrics/libmediametrics.map.txt
@@ -1,29 +1,29 @@
LIBMEDIAMETRICS_1 {
global:
- mediametrics_addDouble; # apex
- mediametrics_addInt32; # apex
- mediametrics_addInt64; # apex
- mediametrics_addRate; # apex
- mediametrics_count; # apex
- mediametrics_create; # apex
- mediametrics_delete; # apex
- mediametrics_freeCString; # apex
- mediametrics_getAttributes; # apex
- mediametrics_getCString; # apex
- mediametrics_getDouble; # apex
- mediametrics_getInt32; # apex
- mediametrics_getInt64; # apex
- mediametrics_getKey; # apex
- mediametrics_getRate; # apex
- mediametrics_isEnabled; # apex
- mediametrics_readable; # apex
- mediametrics_selfRecord; # apex
- mediametrics_setCString; # apex
- mediametrics_setDouble; # apex
- mediametrics_setInt32; # apex
- mediametrics_setInt64; # apex
- mediametrics_setRate; # apex
- mediametrics_setUid; # apex
+ mediametrics_addDouble; # systemapi
+ mediametrics_addInt32; # systemapi
+ mediametrics_addInt64; # systemapi
+ mediametrics_addRate; # systemapi
+ mediametrics_count; # systemapi
+ mediametrics_create; # systemapi
+ mediametrics_delete; # systemapi
+ mediametrics_freeCString; # systemapi
+ mediametrics_getAttributes; # systemapi
+ mediametrics_getCString; # systemapi
+ mediametrics_getDouble; # systemapi
+ mediametrics_getInt32; # systemapi
+ mediametrics_getInt64; # systemapi
+ mediametrics_getKey; # systemapi
+ mediametrics_getRate; # systemapi
+ mediametrics_isEnabled; # systemapi
+ mediametrics_readable; # systemapi
+ mediametrics_selfRecord; # systemapi
+ mediametrics_setCString; # systemapi
+ mediametrics_setDouble; # systemapi
+ mediametrics_setInt32; # systemapi
+ mediametrics_setInt64; # systemapi
+ mediametrics_setRate; # systemapi
+ mediametrics_setUid; # systemapi
local:
*;
};
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 8e19d02..fdcf246 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -2683,7 +2683,7 @@
// This is a benign busy-wait, with the next data request generated 10 ms or more later;
// nevertheless for power reasons, we don't want to see too many of these.
- ALOGV_IF(actualSize == 0 && buffer->size > 0, "callbackwrapper: empty buffer returned");
+ ALOGV_IF(actualSize == 0 && buffer.size() > 0, "callbackwrapper: empty buffer returned");
unlock();
return actualSize;
}
diff --git a/media/libmediaplayerservice/nuplayer/Android.bp b/media/libmediaplayerservice/nuplayer/Android.bp
index 71a3168..911463b 100644
--- a/media/libmediaplayerservice/nuplayer/Android.bp
+++ b/media/libmediaplayerservice/nuplayer/Android.bp
@@ -17,6 +17,14 @@
],
}
+cc_library_headers {
+ name: "libstagefright_nuplayer_headers",
+
+ export_include_dirs: [
+ "include",
+ ],
+}
+
cc_library_static {
srcs: [
@@ -81,6 +89,7 @@
static_libs: [
"libplayerservice_datasource",
+ "libstagefright_esds",
"libstagefright_timedtext",
],
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 9b4fc8f..4851684 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -60,7 +60,7 @@
#include <gui/Surface.h>
-#include "ESDS.h"
+#include <media/esds/ESDS.h>
#include <media/stagefright/Utils.h>
namespace android {
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDrm.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDrm.cpp
index 5e29b3f..a964d4f 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDrm.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDrm.cpp
@@ -22,14 +22,13 @@
#include <mediadrm/DrmUtils.h>
#include <utils/Log.h>
-
namespace android {
// static helpers - internal
sp<IDrm> NuPlayerDrm::CreateDrm(status_t *pstatus)
{
- return DrmUtils::MakeDrm(pstatus);
+ return DrmUtils::MakeDrm(IDRM_NUPLAYER, pstatus);
}
sp<ICrypto> NuPlayerDrm::createCrypto(status_t *pstatus)
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 52c4c0f..d6028d9 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -785,7 +785,7 @@
// we cannot change the number of output buffers while OMX is running
// set up surface to the same count
- Vector<BufferInfo> &buffers = mBuffers[kPortIndexOutput];
+ std::vector<BufferInfo> &buffers = mBuffers[kPortIndexOutput];
ALOGV("setting up surface for %zu buffers", buffers.size());
err = native_window_set_buffer_count(nativeWindow, buffers.size());
@@ -825,7 +825,7 @@
// cancel undequeued buffers to new surface
if (!storingMetadataInDecodedBuffers()) {
for (size_t i = 0; i < buffers.size(); ++i) {
- BufferInfo &info = buffers.editItemAt(i);
+ BufferInfo &info = buffers[i];
if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
ALOGV("canceling buffer %p", info.mGraphicBuffer->getNativeBuffer());
err = nativeWindow->cancelBuffer(
@@ -872,7 +872,7 @@
CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
CHECK(mAllocator[portIndex] == NULL);
- CHECK(mBuffers[portIndex].isEmpty());
+ CHECK(mBuffers[portIndex].empty());
status_t err;
if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
@@ -951,6 +951,7 @@
const sp<AMessage> &format =
portIndex == kPortIndexInput ? mInputFormat : mOutputFormat;
+ mBuffers[portIndex].reserve(def.nBufferCountActual);
for (OMX_U32 i = 0; i < def.nBufferCountActual && err == OK; ++i) {
hidl_memory hidlMemToken;
sp<TMemory> hidlMem;
@@ -1039,7 +1040,7 @@
}
}
- mBuffers[portIndex].push(info);
+ mBuffers[portIndex].push_back(info);
}
}
}
@@ -1250,6 +1251,7 @@
mComponentName.c_str(), bufferCount, bufferSize);
// Dequeue buffers and send them to OMX
+ mBuffers[kPortIndexOutput].reserve(bufferCount);
for (OMX_U32 i = 0; i < bufferCount; i++) {
ANativeWindowBuffer *buf;
int fenceFd;
@@ -1275,7 +1277,7 @@
info.mData = new MediaCodecBuffer(mOutputFormat, new ABuffer(bufferSize));
info.mCodecData = info.mData;
- mBuffers[kPortIndexOutput].push(info);
+ mBuffers[kPortIndexOutput].push_back(info);
IOMX::buffer_id bufferId;
err = mOMXNode->useBuffer(kPortIndexOutput, graphicBuffer, &bufferId);
@@ -1285,7 +1287,7 @@
break;
}
- mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
+ mBuffers[kPortIndexOutput][i].mBufferID = bufferId;
ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)",
mComponentName.c_str(),
@@ -1307,7 +1309,7 @@
}
for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
- BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
+ BufferInfo *info = &mBuffers[kPortIndexOutput][i];
if (info->mStatus == BufferInfo::OWNED_BY_US) {
status_t error = cancelBufferToNativeWindow(info);
if (err == 0) {
@@ -1336,6 +1338,7 @@
ALOGV("[%s] Allocating %u meta buffers on output port",
mComponentName.c_str(), bufferCount);
+ mBuffers[kPortIndexOutput].reserve(bufferCount);
for (OMX_U32 i = 0; i < bufferCount; i++) {
BufferInfo info;
info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
@@ -1353,7 +1356,7 @@
info.mCodecData = info.mData;
err = mOMXNode->useBuffer(kPortIndexOutput, OMXBuffer::sPreset, &info.mBufferID);
- mBuffers[kPortIndexOutput].push(info);
+ mBuffers[kPortIndexOutput].push_back(info);
ALOGV("[%s] allocated meta buffer with ID %u",
mComponentName.c_str(), info.mBufferID);
@@ -1462,7 +1465,7 @@
it != done.cend(); ++it) {
ssize_t index = it->getIndex();
if (index >= 0 && (size_t)index < mBuffers[kPortIndexOutput].size()) {
- mBuffers[kPortIndexOutput].editItemAt(index).mRenderInfo = NULL;
+ mBuffers[kPortIndexOutput][index].mRenderInfo = NULL;
} else if (index >= 0) {
// THIS SHOULD NEVER HAPPEN
ALOGE("invalid index %zd in %zu", index, mBuffers[kPortIndexOutput].size());
@@ -1502,7 +1505,7 @@
bool stale = false;
for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
i--;
- BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
+ BufferInfo *info = &mBuffers[kPortIndexOutput][i];
if (info->mGraphicBuffer != NULL &&
info->mGraphicBuffer->handle == buf->handle) {
@@ -1550,8 +1553,7 @@
BufferInfo *oldest = NULL;
for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
i--;
- BufferInfo *info =
- &mBuffers[kPortIndexOutput].editItemAt(i);
+ BufferInfo *info = &mBuffers[kPortIndexOutput][i];
if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
(oldest == NULL ||
// avoid potential issues from counter rolling over
@@ -1608,8 +1610,7 @@
status_t err = OK;
for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
i--;
- BufferInfo *info =
- &mBuffers[kPortIndexOutput].editItemAt(i);
+ BufferInfo *info = &mBuffers[kPortIndexOutput][i];
// At this time some buffers may still be with the component
// or being drained.
@@ -1626,7 +1627,7 @@
}
status_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
- BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
+ BufferInfo *info = &mBuffers[portIndex][i];
status_t err = OK;
// there should not be any fences in the metadata
@@ -1666,14 +1667,14 @@
}
// remove buffer even if mOMXNode->freeBuffer fails
- mBuffers[portIndex].removeAt(i);
+ mBuffers[portIndex].erase(mBuffers[portIndex].begin() + i);
return err;
}
ACodec::BufferInfo *ACodec::findBufferByID(
uint32_t portIndex, IOMX::buffer_id bufferID, ssize_t *index) {
for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
- BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
+ BufferInfo *info = &mBuffers[portIndex][i];
if (info->mBufferID == bufferID) {
if (index != NULL) {
@@ -5102,7 +5103,7 @@
size_t n = 0;
for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
- const BufferInfo &info = mBuffers[portIndex].itemAt(i);
+ const BufferInfo &info = mBuffers[portIndex][i];
if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
++n;
@@ -5116,7 +5117,7 @@
size_t n = 0;
for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
- const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
+ const BufferInfo &info = mBuffers[kPortIndexOutput][i];
if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
++n;
@@ -5143,7 +5144,7 @@
bool ACodec::allYourBuffersAreBelongToUs(
OMX_U32 portIndex) {
for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
- BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
+ BufferInfo *info = &mBuffers[portIndex][i];
if (info->mStatus != BufferInfo::OWNED_BY_US
&& info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
@@ -5167,12 +5168,11 @@
}
void ACodec::processDeferredMessages() {
- List<sp<AMessage> > queue = mDeferredQueue;
+ std::list<sp<AMessage>> queue = mDeferredQueue;
mDeferredQueue.clear();
- List<sp<AMessage> >::iterator it = queue.begin();
- while (it != queue.end()) {
- onMessageReceived(*it++);
+ for(const sp<AMessage> &msg : queue) {
+ onMessageReceived(msg);
}
}
@@ -5928,19 +5928,17 @@
case ACodec::kWhatSetSurface:
{
+ sp<AReplyToken> replyID;
+ CHECK(msg->senderAwaitsResponse(&replyID));
+
sp<RefBase> obj;
CHECK(msg->findObject("surface", &obj));
status_t err = mCodec->handleSetSurface(static_cast<Surface *>(obj.get()));
- sp<AReplyToken> replyID;
- if (msg->senderAwaitsResponse(&replyID)) {
- sp<AMessage> response = new AMessage;
- response->setInt32("err", err);
- response->postReply(replyID);
- } else if (err != OK) {
- mCodec->signalError(OMX_ErrorUndefined, err);
- }
+ sp<AMessage> response = new AMessage;
+ response->setInt32("err", err);
+ response->postReply(replyID);
break;
}
@@ -6483,7 +6481,7 @@
BufferInfo *eligible = NULL;
for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
- BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
+ BufferInfo *info = &mCodec->mBuffers[kPortIndexInput][i];
#if 0
if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
@@ -7515,7 +7513,7 @@
// submit as many buffers as there are input buffers with the codec
// in case we are in port reconfiguring
for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
- BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
+ BufferInfo *info = &mCodec->mBuffers[kPortIndexInput][i];
if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
if (mCodec->submitOutputMetadataBuffer() != OK)
@@ -7533,7 +7531,7 @@
void ACodec::ExecutingState::submitRegularOutputBuffers() {
bool failed = false;
for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
- BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
+ BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput][i];
if (mCodec->mNativeWindow != NULL) {
if (info->mStatus != BufferInfo::OWNED_BY_US
@@ -7590,7 +7588,7 @@
}
for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
- BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
+ BufferInfo *info = &mCodec->mBuffers[kPortIndexInput][i];
if (info->mStatus == BufferInfo::OWNED_BY_US) {
postFillThisBuffer(info);
}
@@ -8529,17 +8527,11 @@
case kWhatSetSurface:
{
- ALOGV("[%s] Deferring setSurface", mCodec->mComponentName.c_str());
-
- sp<AReplyToken> replyID;
- CHECK(msg->senderAwaitsResponse(&replyID));
+ ALOGD("[%s] Deferring setSurface from OutputPortSettingsChangedState",
+ mCodec->mComponentName.c_str());
mCodec->deferMessage(msg);
- sp<AMessage> response = new AMessage;
- response->setInt32("err", OK);
- response->postReply(replyID);
-
handled = true;
break;
}
@@ -8594,7 +8586,7 @@
ALOGV("[%s] Output port now disabled.", mCodec->mComponentName.c_str());
status_t err = OK;
- if (!mCodec->mBuffers[kPortIndexOutput].isEmpty()) {
+ if (!mCodec->mBuffers[kPortIndexOutput].empty()) {
ALOGE("disabled port should be empty, but has %zu buffers",
mCodec->mBuffers[kPortIndexOutput].size());
err = FAILED_TRANSACTION;
diff --git a/media/libstagefright/Android.bp b/media/libstagefright/Android.bp
index 10baec4..ccd3a54 100644
--- a/media/libstagefright/Android.bp
+++ b/media/libstagefright/Android.bp
@@ -33,75 +33,6 @@
},
}
-cc_library_static {
- name: "libstagefright_esds",
- apex_available: [
- "//apex_available:platform",
- "com.android.media",
- ],
- min_sdk_version: "29",
-
- srcs: ["ESDS.cpp"],
-
- cflags: [
- "-Werror",
- "-Wall",
- ],
- sanitize: {
- misc_undefined: [
- "signed-integer-overflow",
- ],
- cfi: true,
- },
- shared_libs: [
- "libstagefright_foundation",
- "libutils"
- ],
- host_supported: true,
- target: {
- darwin: {
- enabled: false,
- },
- },
-}
-
-cc_library_static {
- name: "libstagefright_metadatautils",
- apex_available: [
- "//apex_available:platform",
- "com.android.media",
- ],
- min_sdk_version: "29",
-
- srcs: ["MetaDataUtils.cpp"],
-
- cflags: [
- "-Werror",
- "-Wall",
- ],
- sanitize: {
- misc_undefined: [
- "signed-integer-overflow",
- ],
- cfi: true,
- },
-
- header_libs: [
- "libaudioclient_headers",
- "libstagefright_foundation_headers",
- "media_ndk_headers",
- ],
-
- host_supported: true,
- target: {
- darwin: {
- enabled: false,
- },
- },
-
- export_include_dirs: ["include"],
-}
-
cc_library_shared {
name: "libstagefright_codecbase",
@@ -166,6 +97,10 @@
"liblog",
],
+ static_libs: [
+ "libstagefright_esds",
+ ],
+
export_include_dirs: [
"include",
],
@@ -220,6 +155,7 @@
"libEGL",
"libGLESv1_CM",
"libGLESv2",
+ "libvulkan",
"libgui",
"liblog",
"libprocessgroup",
@@ -386,7 +322,6 @@
"libstagefright_webm",
"libstagefright_timedtext",
"libogg",
- "libwebm",
"libstagefright_id3",
"framework-permission-aidl-cpp",
"libmediandk_format",
diff --git a/media/libstagefright/DataConverter.cpp b/media/libstagefright/DataConverter.cpp
index 52be054..b53ac77 100644
--- a/media/libstagefright/DataConverter.cpp
+++ b/media/libstagefright/DataConverter.cpp
@@ -24,6 +24,10 @@
#include <media/MediaCodecBuffer.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AUtils.h>
+#include <system/audio.h>
+#include <audio_utils/primitives.h>
+#include <audio_utils/format.h>
+
namespace android {
@@ -81,12 +85,38 @@
return numSamples * mTargetSampleSize;
}
+static audio_format_t getAudioFormat(AudioEncoding e) {
+ audio_format_t format = AUDIO_FORMAT_INVALID;
+ switch (e) {
+ case kAudioEncodingPcm16bit:
+ format = AUDIO_FORMAT_PCM_16_BIT;
+ break;
+ case kAudioEncodingPcm8bit:
+ format = AUDIO_FORMAT_PCM_8_BIT;
+ break;
+ case kAudioEncodingPcmFloat:
+ format = AUDIO_FORMAT_PCM_FLOAT;
+ break;
+ case kAudioEncodingPcm24bitPacked:
+ format = AUDIO_FORMAT_PCM_24_BIT_PACKED;
+ break;
+ case kAudioEncodingPcm32bit:
+ format = AUDIO_FORMAT_PCM_32_BIT;
+ break;
+ default:
+ ALOGE("Invalid AudioEncoding %d", e);
+ }
+ return format;
+}
static size_t getAudioSampleSize(AudioEncoding e) {
switch (e) {
- case kAudioEncodingPcm16bit: return 2;
- case kAudioEncodingPcm8bit: return 1;
- case kAudioEncodingPcmFloat: return 4;
+ case kAudioEncodingPcm16bit:
+ case kAudioEncodingPcm8bit:
+ case kAudioEncodingPcmFloat:
+ case kAudioEncodingPcm24bitPacked:
+ case kAudioEncodingPcm32bit:
+ return audio_bytes_per_sample(getAudioFormat(e));
default: return 0;
}
}
@@ -116,7 +146,15 @@
} else if (mTo == kAudioEncodingPcmFloat && mFrom == kAudioEncodingPcm16bit) {
memcpy_to_float_from_i16((float*)tgt->base(), (const int16_t*)src->data(), src->size() / 2);
} else {
- return INVALID_OPERATION;
+ audio_format_t srcFormat = getAudioFormat(mFrom);
+ audio_format_t dstFormat = getAudioFormat(mTo);
+
+ if ((srcFormat == AUDIO_FORMAT_INVALID) || (dstFormat == AUDIO_FORMAT_INVALID))
+ return INVALID_OPERATION;
+
+ size_t frames = src->size() / audio_bytes_per_sample(srcFormat);
+ memcpy_by_audio_format((void*)tgt->base(), dstFormat, (void*)src->data(),
+ srcFormat, frames);
}
return OK;
}
diff --git a/media/libstagefright/FrameDecoder.cpp b/media/libstagefright/FrameDecoder.cpp
index 344456c..42815b3 100644
--- a/media/libstagefright/FrameDecoder.cpp
+++ b/media/libstagefright/FrameDecoder.cpp
@@ -352,6 +352,10 @@
status_t err = OK;
bool done = false;
size_t retriesLeft = kRetryCount;
+ if (!mDecoder) {
+ ALOGE("decoder is not initialized");
+ return NO_INIT;
+ }
do {
size_t index;
int64_t ptsUs = 0LL;
diff --git a/media/libstagefright/MPEG2TSWriter.cpp b/media/libstagefright/MPEG2TSWriter.cpp
index 34b840e..fbc684b 100644
--- a/media/libstagefright/MPEG2TSWriter.cpp
+++ b/media/libstagefright/MPEG2TSWriter.cpp
@@ -30,7 +30,7 @@
#include <media/stagefright/MetaData.h>
#include <arpa/inet.h>
-#include "include/ESDS.h"
+#include <media/esds/ESDS.h>
namespace android {
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 63d3180..386b790 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -51,7 +51,7 @@
#include <media/mediarecorder.h>
#include <cutils/properties.h>
-#include "include/ESDS.h"
+#include <media/esds/ESDS.h>
#include "include/HevcUtils.h"
#ifndef __predict_false
diff --git a/media/libstagefright/MediaAppender.cpp b/media/libstagefright/MediaAppender.cpp
index 21dcfa1..2d9c651 100644
--- a/media/libstagefright/MediaAppender.cpp
+++ b/media/libstagefright/MediaAppender.cpp
@@ -308,7 +308,11 @@
ALOGE("MediaAppender::start() is called in invalid state %d", mState);
return INVALID_OPERATION;
}
- mMuxer = new (std::nothrow) MediaMuxer(mFd, mFormat);
+ mMuxer = MediaMuxer::create(mFd, mFormat);
+ if (mMuxer == nullptr) {
+ ALOGE("MediaMuxer::create failed");
+ return INVALID_OPERATION;
+ }
for (const auto& n : mFmtIndexMap) {
ssize_t muxIndex = mMuxer->addTrack(n.second);
if (muxIndex < 0) {
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 3044c20..f67f717 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -3481,8 +3481,8 @@
MediaCodecInfo::Attributes attr = mCodecInfo
? mCodecInfo->getAttributes()
: MediaCodecInfo::Attributes(0);
- if (!(attr & MediaCodecInfo::kFlagIsSoftwareOnly)) {
- // software codec is currently ignored.
+ if (mDomain == DOMAIN_VIDEO || !(attr & MediaCodecInfo::kFlagIsSoftwareOnly)) {
+ // software audio codecs are currently ignored.
mResourceManagerProxy->addResource(MediaResource::CodecResource(
mFlags & kFlagIsSecure, toMediaResourceSubType(mDomain)));
}
@@ -4841,7 +4841,7 @@
// rendering.
int32_t dataSpace;
if (mOutputFormat->findInt32("android._dataspace", &dataSpace)) {
- ALOGD("[%s] setting dataspace on output surface to #%x",
+ ALOGD("[%s] setting dataspace on output surface to %#x",
mComponentName.c_str(), dataSpace);
int err = native_window_set_buffers_data_space(
mSurface.get(), (android_dataspace)dataSpace);
@@ -5413,7 +5413,7 @@
MediaCodec::BufferInfo *MediaCodec::peekNextPortBuffer(int32_t portIndex) {
CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
- List<size_t> *availBuffers = &mAvailPortBuffers[portIndex];
+ std::list<size_t> *availBuffers = &mAvailPortBuffers[portIndex];
if (availBuffers->empty()) {
return nullptr;
@@ -5430,7 +5430,7 @@
return -EAGAIN;
}
- List<size_t> *availBuffers = &mAvailPortBuffers[portIndex];
+ std::list<size_t> *availBuffers = &mAvailPortBuffers[portIndex];
size_t index = *availBuffers->begin();
CHECK_EQ(info, &mPortBuffers[portIndex][index]);
availBuffers->erase(availBuffers->begin());
diff --git a/media/libstagefright/MediaMuxer.cpp b/media/libstagefright/MediaMuxer.cpp
index a946f71..9f590e5 100644
--- a/media/libstagefright/MediaMuxer.cpp
+++ b/media/libstagefright/MediaMuxer.cpp
@@ -46,6 +46,30 @@
format == MediaMuxer::OUTPUT_FORMAT_HEIF;
}
+MediaMuxer* MediaMuxer::create(int fd, OutputFormat format) {
+ bool isInputValid = true;
+ if (isMp4Format(format)) {
+ isInputValid = MPEG4Writer::isFdOpenModeValid(fd);
+ } else if (format == OUTPUT_FORMAT_WEBM) {
+ isInputValid = WebmWriter::isFdOpenModeValid(fd);
+ } else if (format == OUTPUT_FORMAT_OGG) {
+ isInputValid = OggWriter::isFdOpenModeValid(fd);
+ } else {
+ ALOGE("MediaMuxer does not support output format %d", format);
+ return nullptr;
+ }
+ if (!isInputValid) {
+ ALOGE("File descriptor is not suitable for format %d", format);
+ return nullptr;
+ }
+
+ MediaMuxer *muxer = new (std::nothrow) MediaMuxer(fd, (MediaMuxer::OutputFormat)format);
+ if (muxer == nullptr) {
+ ALOGE("Failed to create writer object");
+ }
+ return muxer;
+}
+
MediaMuxer::MediaMuxer(int fd, OutputFormat format)
: mFormat(format),
mState(UNINITIALIZED) {
diff --git a/media/libstagefright/NuMediaExtractor.cpp b/media/libstagefright/NuMediaExtractor.cpp
index 2b45f2d..0536f2a 100644
--- a/media/libstagefright/NuMediaExtractor.cpp
+++ b/media/libstagefright/NuMediaExtractor.cpp
@@ -20,7 +20,7 @@
#include <media/stagefright/NuMediaExtractor.h>
-#include "include/ESDS.h"
+#include <media/esds/ESDS.h>
#include <datasource/DataSourceFactory.h>
#include <datasource/FileSource.h>
diff --git a/media/libstagefright/OggWriter.cpp b/media/libstagefright/OggWriter.cpp
index 0f5e95e..cff37a3 100644
--- a/media/libstagefright/OggWriter.cpp
+++ b/media/libstagefright/OggWriter.cpp
@@ -96,6 +96,7 @@
return ERROR_UNSUPPORTED;
}
+ // NOLINTNEXTLINE(clang-analyzer-unix.MallocSizeof)
mOs = (OggStreamState*) malloc(sizeof(ogg_stream_state));
if (ogg_stream_init((ogg_stream_state*)mOs, rand()) == -1) {
ALOGE("ogg stream init failed");
@@ -242,13 +243,15 @@
mDone = true;
- void* dummy;
- pthread_join(mThread, &dummy);
+ status_t status = mSource->stop();
- status_t err = static_cast<status_t>(reinterpret_cast<uintptr_t>(dummy));
+ void *pthread_res;
+ pthread_join(mThread, &pthread_res);
+
+ status_t err = static_cast<status_t>(reinterpret_cast<uintptr_t>(pthread_res));
{
- status_t status = mSource->stop();
- if (err == OK && (status != OK && status != ERROR_END_OF_STREAM)) {
+ if (err == OK &&
+ (status != OK && status != ERROR_END_OF_STREAM)) {
err = status;
}
}
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index a443ed9..c5b5199 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -24,7 +24,7 @@
#include <utility>
#include <vector>
-#include "include/ESDS.h"
+#include <media/esds/ESDS.h>
#include "include/HevcUtils.h"
#include <cutils/properties.h>
@@ -794,6 +794,10 @@
{ "thumbnail-height", kKeyThumbnailHeight },
{ "track-id", kKeyTrackID },
{ "valid-samples", kKeyValidSamples },
+ { "dvb-component-tag", kKeyDvbComponentTag},
+ { "dvb-audio-description", kKeyDvbAudioDescription},
+ { "dvb-teletext-magazine-number", kKeyDvbTeletextMagazineNumber},
+ { "dvb-teletext-page-number", kKeyDvbTeletextPageNumber},
}
};
@@ -1002,6 +1006,26 @@
msg->setInt32("is-sync-frame", 1);
}
+ int32_t dvbComponentTag = 0;
+ if (meta->findInt32(kKeyDvbComponentTag, &dvbComponentTag)) {
+ msg->setInt32("dvb-component-tag", dvbComponentTag);
+ }
+
+ int32_t dvbAudioDescription = 0;
+ if (meta->findInt32(kKeyDvbAudioDescription, &dvbAudioDescription)) {
+ msg->setInt32("dvb-audio-description", dvbAudioDescription);
+ }
+
+ int32_t dvbTeletextMagazineNumber = 0;
+ if (meta->findInt32(kKeyDvbTeletextMagazineNumber, &dvbTeletextMagazineNumber)) {
+ msg->setInt32("dvb-teletext-magazine-number", dvbTeletextMagazineNumber);
+ }
+
+ int32_t dvbTeletextPageNumber = 0;
+ if (meta->findInt32(kKeyDvbTeletextPageNumber, &dvbTeletextPageNumber)) {
+ msg->setInt32("dvb-teletext-page-number", dvbTeletextPageNumber);
+ }
+
const char *lang;
if (meta->findCString(kKeyMediaLanguage, &lang)) {
msg->setString("language", lang);
@@ -1788,6 +1812,26 @@
meta->setInt32(kKeyMaxBitRate, maxBitrate);
}
+ int32_t dvbComponentTag = 0;
+ if (msg->findInt32("dvb-component-tag", &dvbComponentTag) && dvbComponentTag > 0) {
+ meta->setInt32(kKeyDvbComponentTag, dvbComponentTag);
+ }
+
+ int32_t dvbAudioDescription = 0;
+ if (msg->findInt32("dvb-audio-description", &dvbAudioDescription)) {
+ meta->setInt32(kKeyDvbAudioDescription, dvbAudioDescription);
+ }
+
+ int32_t dvbTeletextMagazineNumber = 0;
+ if (msg->findInt32("dvb-teletext-magazine-number", &dvbTeletextMagazineNumber)) {
+ meta->setInt32(kKeyDvbTeletextMagazineNumber, dvbTeletextMagazineNumber);
+ }
+
+ int32_t dvbTeletextPageNumber = 0;
+ if (msg->findInt32("dvb-teletext-page-number", &dvbTeletextPageNumber)) {
+ meta->setInt32(kKeyDvbTeletextPageNumber, dvbTeletextPageNumber);
+ }
+
AString lang;
if (msg->findString("language", &lang)) {
meta->setCString(kKeyMediaLanguage, lang.c_str());
@@ -1911,10 +1955,10 @@
if (msg->findString("ts-schema", &tsSchema)) {
unsigned int numLayers = 0;
unsigned int numBLayers = 0;
- char dummy;
+ char placeholder;
int tags = sscanf(tsSchema.c_str(), "android.generic.%u%c%u%c",
- &numLayers, &dummy, &numBLayers, &dummy);
- if ((tags == 1 || (tags == 3 && dummy == '+'))
+ &numLayers, &placeholder, &numBLayers, &placeholder);
+ if ((tags == 1 || (tags == 3 && placeholder == '+'))
&& numLayers > 0 && numLayers < UINT32_MAX - numBLayers
&& numLayers + numBLayers <= INT32_MAX) {
meta->setInt32(kKeyTemporalLayerCount, numLayers + numBLayers);
diff --git a/media/libstagefright/colorconversion/SoftwareRenderer.cpp b/media/libstagefright/colorconversion/SoftwareRenderer.cpp
index 4711315..2409315 100644
--- a/media/libstagefright/colorconversion/SoftwareRenderer.cpp
+++ b/media/libstagefright/colorconversion/SoftwareRenderer.cpp
@@ -441,7 +441,7 @@
((dataSpace & ~HAL_DATASPACE_RANGE_MASK) | HAL_DATASPACE_RANGE_FULL);
}
- ALOGD("setting dataspace on output surface to #%x", dataSpace);
+ ALOGD("setting dataspace on output surface to %#x", dataSpace);
if ((err = native_window_set_buffers_data_space(mNativeWindow.get(), dataSpace))) {
ALOGW("failed to set dataspace on surface (%d)", err);
}
diff --git a/media/libstagefright/colorconversion/fuzzer/Android.bp b/media/libstagefright/colorconversion/fuzzer/Android.bp
new file mode 100644
index 0000000..76b054a
--- /dev/null
+++ b/media/libstagefright/colorconversion/fuzzer/Android.bp
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_av_media_libstagefright_colorconversion_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: [
+ "frameworks_av_media_libstagefright_colorconversion_license",
+ ],
+}
+
+cc_defaults {
+ name: "libcolorconversion_fuzzer_defaults",
+ static_libs: [
+ "libyuv_static",
+ "libstagefright_color_conversion",
+ "libstagefright",
+ "liblog",
+ ],
+ header_libs: [
+ "libstagefright_headers",
+ "libgui_headers",
+ ],
+ shared_libs: [
+ "libui",
+ "libnativewindow",
+ "libstagefright_codecbase",
+ "libstagefright_foundation",
+ "libutils",
+ "libgui",
+ "libbinder",
+ ],
+ fuzz_config: {
+ cc: [
+ "android-media-fuzzing-reports@google.com",
+ ],
+ componentid: 155276,
+ },
+}
+
+cc_fuzz {
+ name: "color_conversion_fuzzer",
+ srcs: [
+ "color_conversion_fuzzer.cpp",
+ ],
+ defaults: [
+ "libcolorconversion_fuzzer_defaults",
+ ],
+}
diff --git a/media/libstagefright/colorconversion/fuzzer/README.md b/media/libstagefright/colorconversion/fuzzer/README.md
new file mode 100644
index 0000000..220f749
--- /dev/null
+++ b/media/libstagefright/colorconversion/fuzzer/README.md
@@ -0,0 +1,28 @@
+# Fuzzers for libstagefright_color_conversion
+
+## Table of contents
++ [color_conversion_fuzzer](#ColorConversion)
+
+
+# <a name="ColorConversion"></a> Fuzzer for Colorconversion
+
+ColorConversion supports the following parameters:
+1. SrcColorFormatType (parameter name: "kSrcFormatType")
+2. DstColorFormatType (parameter name: "kDstFormatType")
+
+| Parameter| Valid Values| Configured Value|
+|------------- |-------------| ----- |
+|`kSrcFormatType`| 0. `OMX_COLOR_FormatYUV420Planar`<br/>1. `OMX_COLOR_FormatYUV420Planar16`<br/>2. `OMX_COLOR_FormatYUV420SemiPlanar` <br/>3. `OMX_TI_COLOR_FormatYUV420PackedSemiPlanar` <br/>4.`OMX_COLOR_FormatCbYCrY`<br/>5.`OMX_QCOM_COLOR_FormatYVU420SemiPlanar`<br/>6.`COLOR_FormatYUVP010`|Value obtained from FuzzedDataProvider|
+|`kDstFormatType`| 0. `OMX_COLOR_Format16bitRGB565`<br/>1. `OMX_COLOR_Format32BitRGBA8888`<br/>2. `OMX_COLOR_Format32bitBGRA8888` <br/>3. `OMX_COLOR_Format16bitRGB565` <br/>4. `OMX_COLOR_Format32bitBGRA8888`<br/>5.`OMX_COLOR_FormatYUV444Y410`<br/>6. `COLOR_Format32bitABGR2101010`|Value obtained from FuzzedDataProvider|
+
+
+#### Steps to run
+1. Build the fuzzer
+```
+ $ mm -j$(nproc) color_conversion_fuzzer
+```
+2. Run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/color_conversion_fuzzer/color_conversion_fuzzer
+```
diff --git a/media/libstagefright/colorconversion/fuzzer/color_conversion_fuzzer.cpp b/media/libstagefright/colorconversion/fuzzer/color_conversion_fuzzer.cpp
new file mode 100644
index 0000000..7c2bfe5
--- /dev/null
+++ b/media/libstagefright/colorconversion/fuzzer/color_conversion_fuzzer.cpp
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <media/stagefright/ColorConverter.h>
+#include <media/stagefright/MediaCodecConstants.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <iostream>
+#include <vector>
+#include "fuzzer/FuzzedDataProvider.h"
+
+using namespace android;
+using ::android::sp;
+
+static constexpr int32_t kMinFrameSize = 2;
+static constexpr int32_t kMaxFrameSize = 8192;
+
+static constexpr int32_t kSrcFormatType[] = {OMX_COLOR_FormatYUV420Planar,
+ OMX_COLOR_FormatYUV420Planar16,
+ OMX_COLOR_FormatYUV420SemiPlanar,
+ OMX_TI_COLOR_FormatYUV420PackedSemiPlanar,
+ OMX_COLOR_FormatCbYCrY,
+ OMX_QCOM_COLOR_FormatYVU420SemiPlanar,
+ COLOR_FormatYUVP010};
+
+static constexpr int32_t kDstFormatType[] = {
+ OMX_COLOR_Format16bitRGB565, OMX_COLOR_Format32BitRGBA8888, OMX_COLOR_Format32bitBGRA8888,
+ OMX_COLOR_FormatYUV444Y410, COLOR_Format32bitABGR2101010};
+
+class ColorConversionFuzzer {
+ public:
+ ColorConversionFuzzer(const uint8_t* data, size_t size) : mFdp(data, size){};
+ void process();
+
+ private:
+ FuzzedDataProvider mFdp;
+ int32_t getFrameSize(OMX_COLOR_FORMATTYPE colorFormat, int32_t stride, int32_t height);
+ bool isValidFormat(OMX_COLOR_FORMATTYPE srcFormat, OMX_COLOR_FORMATTYPE dstFormat);
+};
+
+int32_t ColorConversionFuzzer::getFrameSize(OMX_COLOR_FORMATTYPE colorFormat, int32_t stride,
+ int32_t height) {
+ int32_t frameSize;
+ switch ((int32_t)colorFormat) {
+ case OMX_COLOR_Format16bitRGB565: {
+ frameSize = 2 * stride * height;
+ break;
+ }
+ case OMX_COLOR_FormatYUV420Planar16:
+ case COLOR_FormatYUVP010:
+ case OMX_COLOR_FormatYUV444Y410: {
+ frameSize = 3 * stride * height;
+ break;
+ }
+ case OMX_COLOR_Format32bitBGRA8888:
+ case OMX_COLOR_Format32BitRGBA8888:
+ case COLOR_Format32bitABGR2101010: {
+ frameSize = 4 * stride * height;
+ break;
+ }
+ case OMX_COLOR_FormatYUV420Planar:
+ case OMX_COLOR_FormatYUV420SemiPlanar:
+ case OMX_COLOR_FormatCbYCrY:
+ case OMX_QCOM_COLOR_FormatYVU420SemiPlanar:
+ case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar:
+ default: {
+ frameSize = stride * height + 2 * (((stride + 1) / 2) * ((height + 1) / 2));
+ break;
+ }
+ }
+ return frameSize;
+}
+
+void ColorConversionFuzzer::process() {
+ OMX_COLOR_FORMATTYPE srcColorFormat =
+ static_cast<OMX_COLOR_FORMATTYPE>(mFdp.PickValueInArray(kSrcFormatType));
+ OMX_COLOR_FORMATTYPE dstColorFormat =
+ static_cast<OMX_COLOR_FORMATTYPE>(mFdp.PickValueInArray(kDstFormatType));
+ std::unique_ptr<ColorConverter> converter(new ColorConverter(srcColorFormat, dstColorFormat));
+ if (converter->isValid()) {
+ int32_t srcLeft, srcTop, srcRight, srcBottom, width, height, stride;
+ width = mFdp.ConsumeIntegralInRange<int32_t>(kMinFrameSize, kMaxFrameSize);
+ height = mFdp.ConsumeIntegralInRange<int32_t>(kMinFrameSize, kMaxFrameSize);
+ stride = mFdp.ConsumeIntegralInRange<int32_t>(width, 2 * kMaxFrameSize);
+
+ srcLeft = mFdp.ConsumeIntegralInRange<int32_t>(0, width - 1);
+ srcTop = mFdp.ConsumeIntegralInRange<int32_t>(0, height - 1);
+ srcRight = mFdp.ConsumeIntegralInRange<int32_t>(srcLeft, width - 1);
+ srcBottom = mFdp.ConsumeIntegralInRange<int32_t>(srcTop, height - 1);
+
+ int32_t dstLeft, dstTop, dstRight, dstBottom;
+ dstLeft = mFdp.ConsumeIntegralInRange<int32_t>(0, width - 1);
+ dstTop = mFdp.ConsumeIntegralInRange<int32_t>(0, height - 1);
+ dstRight = mFdp.ConsumeIntegralInRange<int32_t>(dstLeft, width - 1);
+ dstBottom = mFdp.ConsumeIntegralInRange<int32_t>(dstTop, height - 1);
+
+ int32_t srcFrameSize = getFrameSize(srcColorFormat, stride, height);
+ int32_t dstFrameSize = getFrameSize(dstColorFormat, stride, height);
+ std::vector<uint8_t> srcFrame(srcFrameSize), dstFrame(dstFrameSize);
+ mFdp.ConsumeData(srcFrame.data(), srcFrameSize);
+ converter->convert(srcFrame.data(), width, height, stride, srcLeft, srcTop, srcRight,
+ srcBottom, dstFrame.data(), width, height, stride, dstLeft, dstTop,
+ dstRight, dstBottom);
+ }
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ ColorConversionFuzzer colorConversionFuzzer(data, size);
+ colorConversionFuzzer.process();
+ return 0;
+}
diff --git a/media/libstagefright/data/media_codecs_sw.xml b/media/libstagefright/data/media_codecs_sw.xml
index d7e2d18..b29c3b6 100644
--- a/media/libstagefright/data/media_codecs_sw.xml
+++ b/media/libstagefright/data/media_codecs_sw.xml
@@ -27,66 +27,77 @@
<Limit name="channel-count" max="2" />
<Limit name="sample-rate" ranges="8000,11025,12000,16000,22050,24000,32000,44100,48000" />
<Limit name="bitrate" range="8000-320000" />
+ <Attribute name="software-codec" />
</MediaCodec>
<MediaCodec name="c2.android.amrnb.decoder" type="audio/3gpp">
<Alias name="OMX.google.amrnb.decoder" />
<Limit name="channel-count" max="1" />
<Limit name="sample-rate" ranges="8000" />
<Limit name="bitrate" range="4750-12200" />
+ <Attribute name="software-codec" />
</MediaCodec>
<MediaCodec name="c2.android.amrwb.decoder" type="audio/amr-wb">
<Alias name="OMX.google.amrwb.decoder" />
<Limit name="channel-count" max="1" />
<Limit name="sample-rate" ranges="16000" />
<Limit name="bitrate" range="6600-23850" />
+ <Attribute name="software-codec" />
</MediaCodec>
<MediaCodec name="c2.android.aac.decoder" type="audio/mp4a-latm">
<Alias name="OMX.google.aac.decoder" />
<Limit name="channel-count" max="8" />
<Limit name="sample-rate" ranges="7350,8000,11025,12000,16000,22050,24000,32000,44100,48000" />
<Limit name="bitrate" range="8000-960000" />
+ <Attribute name="software-codec" />
</MediaCodec>
<MediaCodec name="c2.android.g711.alaw.decoder" type="audio/g711-alaw">
<Alias name="OMX.google.g711.alaw.decoder" />
<Limit name="channel-count" max="6" />
<Limit name="sample-rate" ranges="8000-48000" />
<Limit name="bitrate" range="64000" />
+ <Attribute name="software-codec" />
</MediaCodec>
<MediaCodec name="c2.android.g711.mlaw.decoder" type="audio/g711-mlaw">
<Alias name="OMX.google.g711.mlaw.decoder" />
<Limit name="channel-count" max="6" />
<Limit name="sample-rate" ranges="8000-48000" />
<Limit name="bitrate" range="64000" />
+ <Attribute name="software-codec" />
</MediaCodec>
<MediaCodec name="c2.android.vorbis.decoder" type="audio/vorbis">
<Alias name="OMX.google.vorbis.decoder" />
<Limit name="channel-count" max="8" />
<Limit name="sample-rate" ranges="8000-96000" />
<Limit name="bitrate" range="32000-500000" />
+ <Attribute name="software-codec" />
</MediaCodec>
<MediaCodec name="c2.android.opus.decoder" type="audio/opus">
<Alias name="OMX.google.opus.decoder" />
<Limit name="channel-count" max="8" />
<Limit name="sample-rate" ranges="8000,12000,16000,24000,48000" />
<Limit name="bitrate" range="6000-510000" />
+ <Attribute name="software-codec" />
</MediaCodec>
<MediaCodec name="c2.android.raw.decoder" type="audio/raw">
<Alias name="OMX.google.raw.decoder" />
<Limit name="channel-count" max="8" />
- <Limit name="sample-rate" ranges="8000-96000" />
+ <Limit name="sample-rate" ranges="8000-192000" />
<Limit name="bitrate" range="1-10000000" />
+ <Attribute name="software-codec" />
</MediaCodec>
<MediaCodec name="c2.android.flac.decoder" type="audio/flac">
<Alias name="OMX.google.flac.decoder" />
<Limit name="channel-count" max="8" />
<Limit name="sample-rate" ranges="1-655350" />
<Limit name="bitrate" range="1-21000000" />
+ <Attribute name="software-codec" />
</MediaCodec>
<MediaCodec name="c2.android.gsm.decoder" type="audio/gsm" domain="telephony">
<Alias name="OMX.google.gsm.decoder" />
<Limit name="channel-count" max="1" />
<Limit name="sample-rate" ranges="8000" />
<Limit name="bitrate" range="13000" />
+ <Attribute name="software-codec" />
</MediaCodec>
<MediaCodec name="c2.android.mpeg4.decoder" type="video/mp4v-es">
<Alias name="OMX.google.mpeg4.decoder" />
@@ -97,6 +108,7 @@
<Limit name="blocks-per-second" range="1-432000" />
<Limit name="bitrate" range="1-40000000" />
<Feature name="adaptive-playback" />
+ <Attribute name="software-codec" />
</MediaCodec>
<MediaCodec name="c2.android.h263.decoder" type="video/3gpp">
<Alias name="OMX.google.h263.decoder" />
@@ -106,6 +118,7 @@
<Limit name="alignment" value="2x2" />
<Limit name="bitrate" range="1-384000" />
<Feature name="adaptive-playback" />
+ <Attribute name="software-codec" />
</MediaCodec>
<MediaCodec name="c2.android.avc.decoder" type="video/avc" variant="slow-cpu,!slow-cpu">
<Alias name="OMX.google.h264.decoder" />
@@ -126,6 +139,7 @@
<Limit name="bitrate" range="1-40000000" />
</Variant>
<Feature name="adaptive-playback" />
+ <Attribute name="software-codec" />
</MediaCodec>
<MediaCodec name="c2.android.hevc.decoder" type="video/hevc" variant="slow-cpu,!slow-cpu">
<Alias name="OMX.google.hevc.decoder" />
@@ -146,6 +160,7 @@
<Limit name="bitrate" range="1-5000000" />
</Variant>
<Feature name="adaptive-playback" />
+ <Attribute name="software-codec" />
</MediaCodec>
<MediaCodec name="c2.android.vp8.decoder" type="video/x-vnd.on2.vp8" variant="slow-cpu,!slow-cpu">
<Alias name="OMX.google.vp8.decoder" />
@@ -163,6 +178,7 @@
<Limit name="bitrate" range="1-40000000" />
</Variant>
<Feature name="adaptive-playback" />
+ <Attribute name="software-codec" />
</MediaCodec>
<MediaCodec name="c2.android.vp9.decoder" type="video/x-vnd.on2.vp9" variant="slow-cpu,!slow-cpu">
<Alias name="OMX.google.vp9.decoder" />
@@ -181,6 +197,7 @@
<Limit name="bitrate" range="1-5000000" />
</Variant>
<Feature name="adaptive-playback" />
+ <Attribute name="software-codec" />
</MediaCodec>
<MediaCodec name="c2.android.av1.decoder" type="video/av01" variant="!slow-cpu">
<Limit name="size" min="2x2" max="2048x2048" />
@@ -190,6 +207,7 @@
<Limit name="blocks-per-second" range="1-2073600" />
<Limit name="bitrate" range="1-120000000" />
<Feature name="adaptive-playback" />
+ <Attribute name="software-codec" />
</MediaCodec>
<MediaCodec name="c2.android.mpeg2.decoder" type="video/mpeg2" domain="tv">
<Alias name="OMX.google.mpeg2.decoder" />
@@ -200,6 +218,7 @@
<Limit name="blocks-per-second" range="1-244800" />
<Limit name="bitrate" range="1-20000000" />
<Feature name="adaptive-playback" />
+ <Attribute name="software-codec" />
</MediaCodec>
</Decoders>
<Encoders>
@@ -209,6 +228,7 @@
<Limit name="sample-rate" ranges="8000,11025,12000,16000,22050,24000,32000,44100,48000" />
<!-- also may support 64000, 88200 and 96000 Hz -->
<Limit name="bitrate" range="8000-960000" />
+ <Attribute name="software-codec" />
</MediaCodec>
<MediaCodec name="c2.android.amrnb.encoder" type="audio/3gpp">
<Alias name="OMX.google.amrnb.encoder" />
@@ -216,6 +236,7 @@
<Limit name="sample-rate" ranges="8000" />
<Limit name="bitrate" range="4750-12200" />
<Feature name="bitrate-modes" value="CBR" />
+ <Attribute name="software-codec" />
</MediaCodec>
<MediaCodec name="c2.android.amrwb.encoder" type="audio/amr-wb">
<Alias name="OMX.google.amrwb.encoder" />
@@ -223,6 +244,7 @@
<Limit name="sample-rate" ranges="16000" />
<Limit name="bitrate" range="6600-23850" />
<Feature name="bitrate-modes" value="CBR" />
+ <Attribute name="software-codec" />
</MediaCodec>
<MediaCodec name="c2.android.flac.encoder" type="audio/flac">
<Alias name="OMX.google.flac.encoder" />
@@ -231,6 +253,7 @@
<Limit name="bitrate" range="1-21000000" />
<Limit name="complexity" range="0-8" default="5" />
<Feature name="bitrate-modes" value="CQ" />
+ <Attribute name="software-codec" />
</MediaCodec>
<MediaCodec name="c2.android.opus.encoder" type="audio/opus">
<Limit name="channel-count" max="2" />
@@ -238,6 +261,7 @@
<Limit name="bitrate" range="500-512000" />
<Limit name="complexity" range="0-10" default="5" />
<Feature name="bitrate-modes" value="CBR,VBR" />
+ <Attribute name="software-codec" />
</MediaCodec>
<MediaCodec name="c2.android.h263.encoder" type="video/3gpp">
<Alias name="OMX.google.h263.encoder" />
@@ -245,6 +269,7 @@
<Limit name="size" min="176x144" max="176x144" />
<Limit name="alignment" value="16x16" />
<Limit name="bitrate" range="1-128000" />
+ <Attribute name="software-codec" />
</MediaCodec>
<MediaCodec name="c2.android.mpeg4.encoder" type="video/mp4v-es">
<Alias name="OMX.google.mpeg4.encoder" />
@@ -254,6 +279,7 @@
<Limit name="block-size" value="16x16" />
<Limit name="blocks-per-second" range="12-1485" />
<Limit name="bitrate" range="1-64000" />
+ <Attribute name="software-codec" />
</MediaCodec>
<MediaCodec name="c2.android.avc.encoder" type="video/avc" variant="slow-cpu,!slow-cpu">
<Alias name="OMX.google.h264.encoder" />
@@ -277,6 +303,7 @@
<!-- Video Quality control -->
<!-- supports QP bounding with standard keys -->
<Feature name="qp-bounds" />
+ <Attribute name="software-codec" />
</MediaCodec>
<MediaCodec name="c2.android.vp8.encoder" type="video/x-vnd.on2.vp8" variant="slow-cpu,!slow-cpu">
<Alias name="OMX.google.vp8.encoder" />
@@ -296,6 +323,7 @@
<Limit name="bitrate" range="1-20000000" />
</Variant>
<Feature name="bitrate-modes" value="VBR,CBR" />
+ <Attribute name="software-codec" />
</MediaCodec>
<MediaCodec name="c2.android.hevc.encoder" type="video/hevc" variant="!slow-cpu">
<!-- profiles and levels: ProfileMain : MainTierLevel51 -->
@@ -309,6 +337,7 @@
<Limit name="complexity" range="0-10" default="0" />
<Limit name="quality" range="0-100" default="80" />
<Feature name="bitrate-modes" value="VBR,CBR,CQ" />
+ <Attribute name="software-codec" />
</MediaCodec>
<MediaCodec name="c2.android.vp9.encoder" type="video/x-vnd.on2.vp9" variant="!slow-cpu">
<Alias name="OMX.google.vp9.encoder" />
@@ -320,6 +349,7 @@
<Limit name="block-count" range="1-3600" /> <!-- max 1280x720 -->
<Limit name="bitrate" range="1-40000000" />
<Feature name="bitrate-modes" value="VBR,CBR" />
+ <Attribute name="software-codec" />
</MediaCodec>
</Encoders>
</MediaCodecs>
diff --git a/media/libstagefright/exports.lds b/media/libstagefright/exports.lds
index f5ddf1e..7fe6d6c 100644
--- a/media/libstagefright/exports.lds
+++ b/media/libstagefright/exports.lds
@@ -8,19 +8,19 @@
_ZNK7android14ColorConverter*;
_ZN7android16SoftwareRenderer*;
ABGRToARGB;
- ABGRToI420;
+ ABGRToI420*;
ABGRToUVRow_Any_NEON*;
ABGRToUVRow_C;
ABGRToUVRow_NEON*;
ABGRToYRow_Any_NEON*;
ABGRToYRow_C;
ABGRToYRow_NEON*;
- Android420ToI420;
+ Android420ToI420*;
ARGB1555ToARGB;
ARGB1555ToARGBRow_Any_NEON*;
ARGB1555ToARGBRow_C;
ARGB1555ToARGBRow_NEON*;
- ARGB1555ToI420;
+ ARGB1555ToI420*;
ARGB1555ToUVRow_Any_NEON*;
ARGB1555ToUVRow_C;
ARGB1555ToUVRow_NEON*;
@@ -31,7 +31,7 @@
ARGB4444ToARGBRow_Any_NEON*;
ARGB4444ToARGBRow_C;
ARGB4444ToARGBRow_NEON*;
- ARGB4444ToI420;
+ ARGB4444ToI420*;
ARGB4444ToUVRow_Any_NEON*;
ARGB4444ToUVRow_C;
ARGB4444ToUVRow_NEON*;
@@ -115,7 +115,7 @@
ARGBToARGB4444Row_C;
ARGBToARGB4444Row_NEON*;
ARGBToBGRA;
- ARGBToI420;
+ ARGBToI420*;
ARGBToRAWRow_Any_NEON*;
ARGBToRAWRow_C;
ARGBToRAWRow_NEON*;
@@ -147,7 +147,7 @@
ARGBUnattenuateRow_C;
ArmCpuCaps*;
BGRAToARGB;
- BGRAToI420;
+ BGRAToI420*;
BGRAToUVRow_Any_NEON*;
BGRAToUVRow_C;
BGRAToUVRow_NEON*;
@@ -156,9 +156,9 @@
BGRAToYRow_NEON*;
BlendPlane;
BlendPlaneRow_C;
- CanonicalFourCC;
+ CanonicalFourCC*;
ComputeCumulativeSumRow_C;
- ConvertFromI420;
+ ConvertFromI420*;
CopyPlane;
CopyPlane_16;
CopyRow_16_C;
@@ -182,40 +182,40 @@
HalfFloatRow_Any_NEON*;
HalfFloatRow_C;
HalfFloatRow_NEON*;
- I400Copy;
+ I400Copy*;
I400Mirror;
I400ToARGB;
I400ToARGBRow_Any_NEON*;
I400ToARGBRow_C;
I400ToARGBRow_NEON*;
I400ToI400;
- I400ToI420;
+ I400ToI420*;
I420AlphaToABGR;
I420AlphaToARGB;
I420Blend;
- I420Copy;
+ I420Copy*;
I420Interpolate;
I420Mirror;
I420Rect;
- I420Scale;
- I420Scale_16;
+ I420Scale*;
+ I420Scale_16*;
I420ToABGR;
I420ToARGB;
I420ToARGB1555;
I420ToARGB4444;
I420ToBGRA;
I420ToI400;
- I420ToI422;
- I420ToI444;
- I420ToNV12;
- I420ToNV21;
+ I420ToI422*;
+ I420ToI444*;
+ I420ToNV12*;
+ I420ToNV21*;
I420ToRAW;
I420ToRGB24;
I420ToRGB565;
I420ToRGB565Dither;
I420ToRGBA;
- I420ToUYVY;
- I420ToYUY2;
+ I420ToUYVY*;
+ I420ToYUY2*;
I422AlphaToARGBRow_Any_NEON*;
I422AlphaToARGBRow_C;
I422AlphaToARGBRow_NEON*;
@@ -232,7 +232,7 @@
I422ToARGBRow_C;
I422ToARGBRow_NEON*;
I422ToBGRA;
- I422ToI420;
+ I422ToI420*;
I422ToRGB24Row_Any_NEON*;
I422ToRGB24Row_C;
I422ToRGB24Row_NEON*;
@@ -244,11 +244,11 @@
I422ToRGBARow_Any_NEON*;
I422ToRGBARow_C;
I422ToRGBARow_NEON*;
- I422ToUYVY;
+ I422ToUYVY*;
I422ToUYVYRow_Any_NEON*;
I422ToUYVYRow_C;
I422ToUYVYRow_NEON*;
- I422ToYUY2;
+ I422ToYUY2*;
I422ToYUY2Row_Any_NEON*;
I422ToYUY2Row_C;
I422ToYUY2Row_NEON*;
@@ -258,7 +258,7 @@
I444ToARGBRow_Any_NEON*;
I444ToARGBRow_C;
I444ToARGBRow_NEON*;
- I444ToI420;
+ I444ToI420*;
InitCpuFlags*;
InterpolatePlane;
InterpolateRow_16_C;
@@ -280,8 +280,8 @@
kYvuH709Constants;
kYvuI601Constants;
kYvuJPEGConstants;
- M420ToARGB;
- M420ToI420;
+ M420ToARGB*;
+ M420ToI420*;
MaskCpuFlags*;
MergeUVPlane;
MergeUVRow_Any_NEON*;
@@ -297,7 +297,7 @@
NV12ToARGBRow_Any_NEON*;
NV12ToARGBRow_C;
NV12ToARGBRow_NEON*;
- NV12ToI420;
+ NV12ToI420*;
NV12ToRGB565;
NV12ToRGB565Row_Any_NEON*;
NV12ToRGB565Row_C;
@@ -306,12 +306,12 @@
NV21ToARGBRow_Any_NEON*;
NV21ToARGBRow_C;
NV21ToARGBRow_NEON*;
- NV21ToI420;
+ NV21ToI420*;
RAWToARGB;
RAWToARGBRow_Any_NEON*;
RAWToARGBRow_C;
RAWToARGBRow_NEON*;
- RAWToI420;
+ RAWToI420*;
RAWToRGB24;
RAWToRGB24Row_Any_NEON*;
RAWToRGB24Row_C;
@@ -326,7 +326,7 @@
RGB24ToARGBRow_Any_NEON*;
RGB24ToARGBRow_C;
RGB24ToARGBRow_NEON*;
- RGB24ToI420;
+ RGB24ToI420*;
RGB24ToUVRow_Any_NEON*;
RGB24ToUVRow_C;
RGB24ToUVRow_NEON*;
@@ -337,7 +337,7 @@
RGB565ToARGBRow_Any_NEON*;
RGB565ToARGBRow_C;
RGB565ToARGBRow_NEON*;
- RGB565ToI420;
+ RGB565ToI420*;
RGB565ToUVRow_Any_NEON*;
RGB565ToUVRow_C;
RGB565ToUVRow_NEON*;
@@ -345,7 +345,7 @@
RGB565ToYRow_C;
RGB565ToYRow_NEON*;
RGBAToARGB;
- RGBAToI420;
+ RGBAToI420*;
RGBAToUVRow_Any_NEON*;
RGBAToUVRow_C;
RGBAToUVRow_NEON*;
@@ -355,7 +355,7 @@
RGBColorMatrix;
RGBColorTable;
RGBColorTableRow_C;
- Scale;
+ Scale*;
ScaleAddRow_16_C;
ScaleAddRow_C;
ScaleAddRows_NEON*;
@@ -395,12 +395,12 @@
ScaleFilterCols_NEON*;
ScaleFilterReduce;
ScaleFilterRows_NEON*;
- ScalePlane;
- ScalePlane_16;
- ScalePlaneBilinearDown;
- ScalePlaneBilinearDown_16;
- ScalePlaneBilinearUp;
- ScalePlaneBilinearUp_16;
+ ScalePlane*;
+ ScalePlane_16*;
+ ScalePlaneBilinearDown*;
+ ScalePlaneBilinearDown_16*;
+ ScalePlaneBilinearUp*;
+ ScalePlaneBilinearUp_16*;
ScalePlaneVertical;
ScalePlaneVertical_16;
ScaleRowDown2_16_C;
@@ -475,7 +475,7 @@
UYVYToARGBRow_Any_NEON*;
UYVYToARGBRow_C;
UYVYToARGBRow_NEON*;
- UYVYToI420;
+ UYVYToI420*;
UYVYToI422;
UYVYToNV12;
UYVYToUV422Row_Any_NEON*;
@@ -491,7 +491,7 @@
YUY2ToARGBRow_Any_NEON*;
YUY2ToARGBRow_C;
YUY2ToARGBRow_NEON*;
- YUY2ToI420;
+ YUY2ToI420*;
YUY2ToI422;
YUY2ToNV12;
YUY2ToUV422Row_Any_NEON*;
diff --git a/media/libstagefright/include/media/stagefright/ACodec.h b/media/libstagefright/include/media/stagefright/ACodec.h
index 5a21755..38a4c1e 100644
--- a/media/libstagefright/include/media/stagefright/ACodec.h
+++ b/media/libstagefright/include/media/stagefright/ACodec.h
@@ -18,6 +18,8 @@
#define A_CODEC_H_
#include <stdint.h>
+#include <list>
+#include <vector>
#include <android/native_window.h>
#include <media/hardware/MetadataBufferType.h>
#include <media/MediaCodecInfo.h>
@@ -265,11 +267,11 @@
sp<AMessage> mBaseOutputFormat;
FrameRenderTracker mRenderTracker; // render information for buffers rendered by ACodec
- Vector<BufferInfo> mBuffers[2];
+ std::vector<BufferInfo> mBuffers[2];
bool mPortEOS[2];
status_t mInputEOSResult;
- List<sp<AMessage> > mDeferredQueue;
+ std::list<sp<AMessage>> mDeferredQueue;
sp<AMessage> mLastOutputFormat;
bool mIsVideo;
diff --git a/media/libstagefright/include/media/stagefright/MediaCodec.h b/media/libstagefright/include/media/stagefright/MediaCodec.h
index 6644e8e..edb3786 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodec.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodec.h
@@ -18,6 +18,7 @@
#define MEDIA_CODEC_H_
+#include <list>
#include <memory>
#include <vector>
@@ -494,7 +495,7 @@
// stop/flush/reset/release.
Mutex mBufferLock;
- List<size_t> mAvailPortBuffers[2];
+ std::list<size_t> mAvailPortBuffers[2];
std::vector<BufferInfo> mPortBuffers[2];
int32_t mDequeueInputTimeoutGeneration;
@@ -512,7 +513,7 @@
sp<IDescrambler> mDescrambler;
- List<sp<ABuffer> > mCSD;
+ std::list<sp<ABuffer> > mCSD;
sp<AMessage> mActivityNotify;
diff --git a/media/libstagefright/include/media/stagefright/MediaMuxer.h b/media/libstagefright/include/media/stagefright/MediaMuxer.h
index e97a65e..33aaf11 100644
--- a/media/libstagefright/include/media/stagefright/MediaMuxer.h
+++ b/media/libstagefright/include/media/stagefright/MediaMuxer.h
@@ -48,9 +48,13 @@
// deleting the output file after stop.
struct MediaMuxer : public MediaMuxerBase {
public:
- // Construct the muxer with the file descriptor. Note that the MediaMuxer
- // will close this file at stop().
- MediaMuxer(int fd, OutputFormat format);
+ /**
+ * Creates the muxer for a given output format.
+ * @param fd : file descriptor of the output file.
+ * @param format : output format of the muxer. e.g.: webm/mp4/ogg
+ * @return writer's object or nullptr if error.
+ */
+ static MediaMuxer* create(int fd, OutputFormat format);
virtual ~MediaMuxer();
@@ -127,6 +131,11 @@
sp<AMessage> getTrackFormat(size_t idx);
private:
+ // Construct the muxer with the file descriptor. Note that the MediaMuxer
+ // will close this file at stop().
+ // This constructor is made private to ensure that MediaMuxer::create() is used instead.
+ MediaMuxer(int fd, OutputFormat format);
+
const OutputFormat mFormat;
sp<MediaWriter> mWriter;
Vector< sp<MediaAdapter> > mTrackList; // Each track has its MediaAdapter.
diff --git a/media/libstagefright/include/media/stagefright/MediaWriter.h b/media/libstagefright/include/media/stagefright/MediaWriter.h
index 9f20185..2b14811 100644
--- a/media/libstagefright/include/media/stagefright/MediaWriter.h
+++ b/media/libstagefright/include/media/stagefright/MediaWriter.h
@@ -31,6 +31,29 @@
mMaxFileDurationLimitUs(0) {
}
+ // Returns true if the file descriptor is opened using a mode
+ // which meets minimum writer/muxer requirements.
+ static bool isFdOpenModeValid(int fd) {
+ // check for invalid file descriptor.
+ int flags = fcntl(fd, F_GETFL);
+ if (flags == -1) {
+ ALOGE("Invalid File Status Flags and/or mode : %d", flags);
+ return false;
+ }
+ // fd must be in read-write mode or write-only mode.
+ if ((flags & (O_RDWR | O_WRONLY)) == 0) {
+ ALOGE("File must be writable");
+ return false;
+ }
+ // Verify fd is seekable
+ off64_t off = lseek64(fd, 0, SEEK_SET);
+ if (off < 0) {
+ ALOGE("File descriptor is not seekable");
+ return false;
+ }
+ return true;
+ }
+
virtual status_t addSource(const sp<MediaSource> &source) = 0;
virtual bool reachedEOS() = 0;
virtual status_t start(MetaData *params = NULL) = 0;
diff --git a/media/libstagefright/include/media/stagefright/MetaDataBase.h b/media/libstagefright/include/media/stagefright/MetaDataBase.h
index 31faafb..2ca0e33 100644
--- a/media/libstagefright/include/media/stagefright/MetaDataBase.h
+++ b/media/libstagefright/include/media/stagefright/MetaDataBase.h
@@ -278,6 +278,18 @@
kKeyLastSampleIndexInChunk = 'lsic', //int64_t, index of last sample in a chunk.
kKeySampleTimeBeforeAppend = 'lsba', // int64_t, timestamp of last sample of a track.
+ // DVB component tag
+ kKeyDvbComponentTag = 'copt', // int32_t, component tag for DVB video/audio/subtitle
+
+ // DVB audio description
+ kKeyDvbAudioDescription = 'addt', // bool (int32_t), DVB audio description only defined for
+ // audio component
+
+ // DVB teletext magazine number
+ kKeyDvbTeletextMagazineNumber = 'ttxm', // int32_t, DVB teletext magazine number
+
+ // DVB teletext page number
+ kKeyDvbTeletextPageNumber = 'ttxp', // int32_t, DVB teletext page number
};
enum {
diff --git a/media/libstagefright/renderfright/Android.bp b/media/libstagefright/renderfright/Android.bp
index 3c00a1c..3598e8d 100644
--- a/media/libstagefright/renderfright/Android.bp
+++ b/media/libstagefright/renderfright/Android.bp
@@ -32,6 +32,7 @@
"libEGL",
"libGLESv1_CM",
"libGLESv2",
+ "libvulkan",
"liblog",
"libnativewindow",
"libprocessgroup",
diff --git a/media/libstagefright/renderfright/gl/ProgramCache.cpp b/media/libstagefright/renderfright/gl/ProgramCache.cpp
index 56d35a9..af55172 100644
--- a/media/libstagefright/renderfright/gl/ProgramCache.cpp
+++ b/media/libstagefright/renderfright/gl/ProgramCache.cpp
@@ -373,7 +373,11 @@
return color * slope;
} else if (nits < x1) {
// scale [x0, x1] to [y0, y1] linearly
- float slope = (y1 - y0) / (x1 - x0);
+ // Use highp since some compilers may do this
+ // operation as reciprocal multiplication with
+ // re-association that could exceed the range
+ // of mediump float.
+ highp float slope = (y1 - y0) / (x1 - x0);
nits = y0 + (nits - x0) * slope;
} else if (nits < x2) {
// scale [x1, x2] to [y1, y2] using Hermite interp
diff --git a/media/libstagefright/tests/HEVC/HEVCUtilsUnitTest.cpp b/media/libstagefright/tests/HEVC/HEVCUtilsUnitTest.cpp
index c43e1f8..19c8577 100644
--- a/media/libstagefright/tests/HEVC/HEVCUtilsUnitTest.cpp
+++ b/media/libstagefright/tests/HEVC/HEVCUtilsUnitTest.cpp
@@ -19,6 +19,7 @@
#include <utils/Log.h>
#include <fstream>
+#include <memory>
#include <media/stagefright/foundation/ABitReader.h>
#include <HevcUtils.h>
@@ -88,10 +89,10 @@
stringLine >> type >> chunkLength;
ASSERT_GT(chunkLength, 0) << "Length of data chunk must be greater than 0";
- char *data = (char *)malloc(chunkLength);
+ std::unique_ptr<char[]> data(new char[chunkLength]);
ASSERT_NE(data, nullptr) << "Failed to allocate data buffer of size: " << chunkLength;
- mMediaFileStream.read(data, chunkLength);
+ mMediaFileStream.read(data.get(), chunkLength);
ASSERT_EQ(mMediaFileStream.gcount(), chunkLength)
<< "Failed to read complete file, bytes read: " << mMediaFileStream.gcount();
@@ -105,7 +106,7 @@
offset += 3;
ASSERT_LE(offset, chunkLength) << "NAL unit offset must not exceed the chunk length";
- uint8_t *nalUnit = (uint8_t *)(data + offset);
+ uint8_t *nalUnit = (uint8_t *)(data.get() + offset);
size_t nalUnitLength = chunkLength - offset;
// Add NAL units only if they're of type: VPS/SPS/PPS/SEI
@@ -118,20 +119,18 @@
size_t sizeNalUnit = hevcParams.getSize(index);
ASSERT_EQ(sizeNalUnit, nalUnitLength) << "Invalid size returned for NAL: " << type;
- uint8_t *destination = (uint8_t *)malloc(nalUnitLength);
+ std::unique_ptr<uint8_t[]> destination(new uint8_t[nalUnitLength]);
ASSERT_NE(destination, nullptr)
<< "Failed to allocate buffer of size: " << nalUnitLength;
- bool status = hevcParams.write(index, destination, nalUnitLength);
+ bool status = hevcParams.write(index, destination.get(), nalUnitLength);
ASSERT_TRUE(status) << "Unable to write NAL Unit data";
- free(destination);
index++;
} else {
err = hevcParams.addNalUnit(nalUnit, nalUnitLength);
ASSERT_NE(err, (status_t)OK) << "Invalid NAL Unit added, type: " << type;
}
- free(data);
}
size_t numNalUnits = hevcParams.getNumNalUnitsOfType(kVPSCode);
@@ -166,10 +165,10 @@
<< "Expected NAL type: 34(PPS), found: " << typeNalUnit;
size_t hvccBoxSize = kHvccBoxMaxSize;
- uint8_t *hvcc = (uint8_t *)malloc(kHvccBoxMaxSize);
+ std::unique_ptr<uint8_t[]> hvcc(new uint8_t[kHvccBoxMaxSize]);
ASSERT_NE(hvcc, nullptr) << "Failed to allocate a hvcc buffer of size: " << kHvccBoxMaxSize;
- err = hevcParams.makeHvcc(hvcc, &hvccBoxSize, kNALSizeLength);
+ err = hevcParams.makeHvcc(hvcc.get(), &hvccBoxSize, kNALSizeLength);
ASSERT_EQ(err, (status_t)OK) << "Unable to create hvcc box";
ASSERT_GT(hvccBoxSize, kHvccBoxMinSize)
@@ -179,8 +178,6 @@
if (frameRate != mFrameRate)
cout << "[ WARN ] Expected frame rate: " << mFrameRate << " Found: " << frameRate
<< endl;
-
- free(hvcc);
}
// Info File contains the type and length for each chunk/frame
diff --git a/media/libstagefright/tests/fuzzers/FuzzerMediaUtility.cpp b/media/libstagefright/tests/fuzzers/FuzzerMediaUtility.cpp
index d94c8ff..9f46a74 100644
--- a/media/libstagefright/tests/fuzzers/FuzzerMediaUtility.cpp
+++ b/media/libstagefright/tests/fuzzers/FuzzerMediaUtility.cpp
@@ -66,8 +66,8 @@
for (size_t i = 0; i < extractor->countTracks(); ++i) {
sp<MetaData> meta = extractor->getTrackMetaData(i);
- const char *trackMime;
- if (!strcasecmp(mime.c_str(), trackMime)) {
+ std::string trackMime = dataProvider->PickValueInArray(kTestedMimeTypes);
+ if (!strcasecmp(mime.c_str(), trackMime.c_str())) {
sp<IMediaSource> track = extractor->getTrack(i);
if (track == NULL) {
return NULL;
diff --git a/media/libstagefright/tests/fuzzers/FuzzerMediaUtility.h b/media/libstagefright/tests/fuzzers/FuzzerMediaUtility.h
index 98bfb94..6856ac0 100644
--- a/media/libstagefright/tests/fuzzers/FuzzerMediaUtility.h
+++ b/media/libstagefright/tests/fuzzers/FuzzerMediaUtility.h
@@ -42,6 +42,51 @@
kMaxValue = MPEG2TS,
};
+static std::string kTestedMimeTypes[] = {"audio/3gpp",
+ "audio/amr-wb",
+ "audio/vorbis",
+ "audio/opus",
+ "audio/mp4a-latm",
+ "audio/mpeg",
+ "audio/mpeg-L1",
+ "audio/mpeg-L2",
+ "audio/midi",
+ "audio/qcelp",
+ "audio/g711-alaw",
+ "audio/g711-mlaw",
+ "audio/flac",
+ "audio/aac-adts",
+ "audio/gsm",
+ "audio/ac3",
+ "audio/eac3",
+ "audio/eac3-joc",
+ "audio/ac4",
+ "audio/scrambled",
+ "audio/alac",
+ "audio/x-ms-wma",
+ "audio/x-adpcm-ms",
+ "audio/x-adpcm-dvi-ima",
+ "video/avc",
+ "video/hevc",
+ "video/mp4v-es",
+ "video/3gpp",
+ "video/x-vnd.on2.vp8",
+ "video/x-vnd.on2.vp9",
+ "video/av01",
+ "video/mpeg2",
+ "video/dolby-vision",
+ "video/scrambled",
+ "video/divx",
+ "video/divx3",
+ "video/xvid",
+ "video/x-motion-jpeg",
+ "text/3gpp-tt",
+ "application/x-subrip",
+ "text/vtt",
+ "text/cea-608",
+ "text/cea-708",
+ "application/x-id3v4"};
+
std::string genMimeType(FuzzedDataProvider *dataProvider);
sp<IMediaExtractor> genMediaExtractor(FuzzedDataProvider *dataProvider, uint16_t dataAmount);
sp<MediaSource> genMediaSource(FuzzedDataProvider *dataProvider, uint16_t maxMediaBlobSize);
diff --git a/media/libstagefright/tests/fuzzers/MediaMuxerFuzzer.cpp b/media/libstagefright/tests/fuzzers/MediaMuxerFuzzer.cpp
index 5df3267..70d73c8 100644
--- a/media/libstagefright/tests/fuzzers/MediaMuxerFuzzer.cpp
+++ b/media/libstagefright/tests/fuzzers/MediaMuxerFuzzer.cpp
@@ -52,7 +52,10 @@
MediaMuxer::OutputFormat format =
(MediaMuxer::OutputFormat)fdp.ConsumeIntegralInRange<int32_t>(0, 4);
- sp<MediaMuxer> mMuxer(new MediaMuxer(fd, format));
+ sp<MediaMuxer> mMuxer = MediaMuxer::create(fd, format);
+ if (mMuxer == nullptr) {
+ return 0;
+ }
while (fdp.remaining_bytes() > 1) {
switch (fdp.ConsumeIntegralInRange<uint8_t>(0, 4)) {
diff --git a/media/libstagefright/timedtext/test/TimedTextUnitTest.cpp b/media/libstagefright/timedtext/test/TimedTextUnitTest.cpp
index f934b54..b2044d3 100644
--- a/media/libstagefright/timedtext/test/TimedTextUnitTest.cpp
+++ b/media/libstagefright/timedtext/test/TimedTextUnitTest.cpp
@@ -22,6 +22,7 @@
#include <string.h>
#include <sys/stat.h>
#include <fstream>
+#include <memory>
#include <binder/Parcel.h>
#include <media/stagefright/foundation/AString.h>
@@ -240,10 +241,10 @@
if (remaining < tempFontNameLength) break;
const uint8_t *tmpFont = tmpData;
- char *tmpFontName = strndup((const char *)tmpFont, tempFontNameLength);
+ std::unique_ptr<char[]> tmpFontName(new char[tempFontNameLength]);
+ strncpy(tmpFontName.get(), (const char *)tmpFont, tempFontNameLength);
ASSERT_NE(tmpFontName, nullptr) << "Font Name is null";
- ALOGI("FontName = %s", tmpFontName);
- free(tmpFontName);
+ ALOGI("FontName = %s", tmpFontName.get());
tmpData += tempFontNameLength;
remaining -= tempFontNameLength;
fontRecordEntries.push_back({tempFontID, tempFontNameLength, tmpFont});
diff --git a/media/libstagefright/webm/WebmWriter.cpp b/media/libstagefright/webm/WebmWriter.cpp
index 5eaadbd..3823c36 100644
--- a/media/libstagefright/webm/WebmWriter.cpp
+++ b/media/libstagefright/webm/WebmWriter.cpp
@@ -54,6 +54,19 @@
static const int64_t kMinStreamableFileSizeInBytes = 5 * 1024 * 1024;
+bool WebmWriter::isFdOpenModeValid(int fd) {
+ // check for invalid file descriptor.
+ if (!MediaWriter::isFdOpenModeValid(fd)) {
+ return false;
+ }
+ int flags = fcntl(fd, F_GETFL);
+ if ((flags & O_RDWR) == 0) {
+ ALOGE("File must be in read-write mode for webm writer");
+ return false;
+ }
+ return true;
+}
+
WebmWriter::WebmWriter(int fd)
: mFd(dup(fd)),
mInitCheck(mFd < 0 ? NO_INIT : OK),
diff --git a/media/libstagefright/webm/include/webm/WebmWriter.h b/media/libstagefright/webm/include/webm/WebmWriter.h
index ed5bc4c..e339add 100644
--- a/media/libstagefright/webm/include/webm/WebmWriter.h
+++ b/media/libstagefright/webm/include/webm/WebmWriter.h
@@ -36,6 +36,10 @@
class WebmWriter : public MediaWriter {
public:
+ // Returns true if the file descriptor is opened using a mode
+ // which is compatible with WebmWriter.
+ // Note that this overloads that method in the base class.
+ static bool isFdOpenModeValid(int fd);
explicit WebmWriter(int fd);
~WebmWriter() { reset(); }
diff --git a/media/mediaserver/Android.bp b/media/mediaserver/Android.bp
index edddaa4..19f9549 100644
--- a/media/mediaserver/Android.bp
+++ b/media/mediaserver/Android.bp
@@ -26,7 +26,33 @@
],
}
-cc_binary {
+prebuilt_etc {
+ name: "mediaserver.zygote64_32.rc",
+ src: "mediaserver.zygote64_32.rc",
+ sub_dir: "init/hw",
+}
+
+prebuilt_etc {
+ name: "mediaserver.zygote64.rc",
+ src: "mediaserver.zygote64.rc",
+ sub_dir: "init/hw",
+}
+
+soong_config_module_type {
+ name: "mediaserver_cc_binary",
+ module_type: "cc_binary",
+ config_namespace: "ANDROID",
+ bool_variables: ["TARGET_DYNAMIC_64_32_MEDIASERVER"],
+ properties: [
+ "compile_multilib",
+ "init_rc",
+ "multilib.lib32.suffix",
+ "multilib.lib64.suffix",
+ "required",
+ ],
+}
+
+mediaserver_cc_binary {
name: "mediaserver",
srcs: ["main_mediaserver.cpp"],
@@ -55,12 +81,32 @@
// ****************************************************************
compile_multilib: "prefer32",
- init_rc: ["mediaserver.rc"],
-
cflags: [
"-Werror",
"-Wall",
],
vintf_fragments: ["manifest_media_c2_software.xml"],
+
+ soong_config_variables: {
+ TARGET_DYNAMIC_64_32_MEDIASERVER: {
+ compile_multilib: "both",
+ multilib: {
+ lib32: {
+ suffix: "32",
+ },
+ lib64: {
+ suffix: "64",
+ },
+ },
+ required: [
+ "mediaserver.zygote64_32.rc",
+ "mediaserver.zygote64.rc",
+ ],
+ init_rc: ["mediaserver_dynamic.rc"],
+ conditions_default: {
+ init_rc: ["mediaserver.rc"],
+ },
+ },
+ },
}
diff --git a/media/mediaserver/mediaserver.zygote64.rc b/media/mediaserver/mediaserver.zygote64.rc
new file mode 100644
index 0000000..8842b01
--- /dev/null
+++ b/media/mediaserver/mediaserver.zygote64.rc
@@ -0,0 +1,6 @@
+service media /system/bin/mediaserver64
+ class main
+ user media
+ group audio camera inet net_bt net_bt_admin net_bw_acct drmrpc mediadrm
+ ioprio rt 4
+ task_profiles ProcessCapacityHigh HighPerformance
diff --git a/media/mediaserver/mediaserver.zygote64_32.rc b/media/mediaserver/mediaserver.zygote64_32.rc
new file mode 100644
index 0000000..4039073
--- /dev/null
+++ b/media/mediaserver/mediaserver.zygote64_32.rc
@@ -0,0 +1,6 @@
+service media /system/bin/mediaserver32
+ class main
+ user media
+ group audio camera inet net_bt net_bt_admin net_bw_acct drmrpc mediadrm
+ ioprio rt 4
+ task_profiles ProcessCapacityHigh HighPerformance
diff --git a/media/mediaserver/mediaserver_dynamic.rc b/media/mediaserver/mediaserver_dynamic.rc
new file mode 100644
index 0000000..65d5c40
--- /dev/null
+++ b/media/mediaserver/mediaserver_dynamic.rc
@@ -0,0 +1,4 @@
+on property:init.svc.media=*
+ setprop init.svc.mediadrm ${init.svc.media}
+
+import /system/etc/init/hw/mediaserver.${ro.zygote}.rc
diff --git a/media/libstagefright/bqhelper/Android.bp b/media/module/bqhelper/Android.bp
similarity index 97%
rename from media/libstagefright/bqhelper/Android.bp
rename to media/module/bqhelper/Android.bp
index 0e2b472..df658ee 100644
--- a/media/libstagefright/bqhelper/Android.bp
+++ b/media/module/bqhelper/Android.bp
@@ -4,7 +4,6 @@
// all of the 'license_kinds' from "frameworks_av_media_libstagefright_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["frameworks_av_media_libstagefright_license"],
}
cc_defaults {
diff --git a/media/libstagefright/bqhelper/FrameDropper.cpp b/media/module/bqhelper/FrameDropper.cpp
similarity index 100%
rename from media/libstagefright/bqhelper/FrameDropper.cpp
rename to media/module/bqhelper/FrameDropper.cpp
diff --git a/media/libstagefright/bqhelper/GraphicBufferSource.cpp b/media/module/bqhelper/GraphicBufferSource.cpp
similarity index 100%
rename from media/libstagefright/bqhelper/GraphicBufferSource.cpp
rename to media/module/bqhelper/GraphicBufferSource.cpp
diff --git a/media/libstagefright/bqhelper/TEST_MAPPING b/media/module/bqhelper/TEST_MAPPING
similarity index 100%
rename from media/libstagefright/bqhelper/TEST_MAPPING
rename to media/module/bqhelper/TEST_MAPPING
diff --git a/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/ComponentWrapper.h b/media/module/bqhelper/include/media/stagefright/bqhelper/ComponentWrapper.h
similarity index 100%
rename from media/libstagefright/bqhelper/include/media/stagefright/bqhelper/ComponentWrapper.h
rename to media/module/bqhelper/include/media/stagefright/bqhelper/ComponentWrapper.h
diff --git a/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/FrameDropper.h b/media/module/bqhelper/include/media/stagefright/bqhelper/FrameDropper.h
similarity index 100%
rename from media/libstagefright/bqhelper/include/media/stagefright/bqhelper/FrameDropper.h
rename to media/module/bqhelper/include/media/stagefright/bqhelper/FrameDropper.h
diff --git a/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/GraphicBufferSource.h b/media/module/bqhelper/include/media/stagefright/bqhelper/GraphicBufferSource.h
similarity index 100%
rename from media/libstagefright/bqhelper/include/media/stagefright/bqhelper/GraphicBufferSource.h
rename to media/module/bqhelper/include/media/stagefright/bqhelper/GraphicBufferSource.h
diff --git a/media/libstagefright/bqhelper/tests/Android.bp b/media/module/bqhelper/tests/Android.bp
similarity index 88%
rename from media/libstagefright/bqhelper/tests/Android.bp
rename to media/module/bqhelper/tests/Android.bp
index 95953ee..3004ec4 100644
--- a/media/libstagefright/bqhelper/tests/Android.bp
+++ b/media/module/bqhelper/tests/Android.bp
@@ -4,7 +4,6 @@
// all of the 'license_kinds' from "frameworks_av_media_libstagefright_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["frameworks_av_media_libstagefright_license"],
}
cc_test {
diff --git a/media/libstagefright/bqhelper/tests/FrameDropper_test.cpp b/media/module/bqhelper/tests/FrameDropper_test.cpp
similarity index 100%
rename from media/libstagefright/bqhelper/tests/FrameDropper_test.cpp
rename to media/module/bqhelper/tests/FrameDropper_test.cpp
diff --git a/media/bufferpool/1.0/Accessor.cpp b/media/module/bufferpool/1.0/Accessor.cpp
similarity index 100%
rename from media/bufferpool/1.0/Accessor.cpp
rename to media/module/bufferpool/1.0/Accessor.cpp
diff --git a/media/bufferpool/1.0/Accessor.h b/media/module/bufferpool/1.0/Accessor.h
similarity index 100%
rename from media/bufferpool/1.0/Accessor.h
rename to media/module/bufferpool/1.0/Accessor.h
diff --git a/media/bufferpool/1.0/AccessorImpl.cpp b/media/module/bufferpool/1.0/AccessorImpl.cpp
similarity index 100%
rename from media/bufferpool/1.0/AccessorImpl.cpp
rename to media/module/bufferpool/1.0/AccessorImpl.cpp
diff --git a/media/bufferpool/1.0/AccessorImpl.h b/media/module/bufferpool/1.0/AccessorImpl.h
similarity index 100%
rename from media/bufferpool/1.0/AccessorImpl.h
rename to media/module/bufferpool/1.0/AccessorImpl.h
diff --git a/media/bufferpool/1.0/Android.bp b/media/module/bufferpool/1.0/Android.bp
similarity index 100%
rename from media/bufferpool/1.0/Android.bp
rename to media/module/bufferpool/1.0/Android.bp
diff --git a/media/bufferpool/1.0/BufferPoolClient.cpp b/media/module/bufferpool/1.0/BufferPoolClient.cpp
similarity index 100%
rename from media/bufferpool/1.0/BufferPoolClient.cpp
rename to media/module/bufferpool/1.0/BufferPoolClient.cpp
diff --git a/media/bufferpool/1.0/BufferPoolClient.h b/media/module/bufferpool/1.0/BufferPoolClient.h
similarity index 100%
rename from media/bufferpool/1.0/BufferPoolClient.h
rename to media/module/bufferpool/1.0/BufferPoolClient.h
diff --git a/media/bufferpool/1.0/BufferStatus.cpp b/media/module/bufferpool/1.0/BufferStatus.cpp
similarity index 100%
rename from media/bufferpool/1.0/BufferStatus.cpp
rename to media/module/bufferpool/1.0/BufferStatus.cpp
diff --git a/media/bufferpool/1.0/BufferStatus.h b/media/module/bufferpool/1.0/BufferStatus.h
similarity index 100%
rename from media/bufferpool/1.0/BufferStatus.h
rename to media/module/bufferpool/1.0/BufferStatus.h
diff --git a/media/bufferpool/1.0/ClientManager.cpp b/media/module/bufferpool/1.0/ClientManager.cpp
similarity index 100%
rename from media/bufferpool/1.0/ClientManager.cpp
rename to media/module/bufferpool/1.0/ClientManager.cpp
diff --git a/media/bufferpool/1.0/Connection.cpp b/media/module/bufferpool/1.0/Connection.cpp
similarity index 100%
rename from media/bufferpool/1.0/Connection.cpp
rename to media/module/bufferpool/1.0/Connection.cpp
diff --git a/media/bufferpool/1.0/Connection.h b/media/module/bufferpool/1.0/Connection.h
similarity index 100%
rename from media/bufferpool/1.0/Connection.h
rename to media/module/bufferpool/1.0/Connection.h
diff --git a/media/bufferpool/1.0/TEST_MAPPING b/media/module/bufferpool/1.0/TEST_MAPPING
similarity index 100%
rename from media/bufferpool/1.0/TEST_MAPPING
rename to media/module/bufferpool/1.0/TEST_MAPPING
diff --git a/media/bufferpool/1.0/include/bufferpool/BufferPoolTypes.h b/media/module/bufferpool/1.0/include/bufferpool/BufferPoolTypes.h
similarity index 100%
rename from media/bufferpool/1.0/include/bufferpool/BufferPoolTypes.h
rename to media/module/bufferpool/1.0/include/bufferpool/BufferPoolTypes.h
diff --git a/media/bufferpool/1.0/include/bufferpool/ClientManager.h b/media/module/bufferpool/1.0/include/bufferpool/ClientManager.h
similarity index 100%
rename from media/bufferpool/1.0/include/bufferpool/ClientManager.h
rename to media/module/bufferpool/1.0/include/bufferpool/ClientManager.h
diff --git a/media/bufferpool/1.0/vts/Android.bp b/media/module/bufferpool/1.0/vts/Android.bp
similarity index 100%
rename from media/bufferpool/1.0/vts/Android.bp
rename to media/module/bufferpool/1.0/vts/Android.bp
diff --git a/media/bufferpool/1.0/vts/OWNERS b/media/module/bufferpool/1.0/vts/OWNERS
similarity index 100%
rename from media/bufferpool/1.0/vts/OWNERS
rename to media/module/bufferpool/1.0/vts/OWNERS
diff --git a/media/bufferpool/1.0/vts/allocator.cpp b/media/module/bufferpool/1.0/vts/allocator.cpp
similarity index 100%
rename from media/bufferpool/1.0/vts/allocator.cpp
rename to media/module/bufferpool/1.0/vts/allocator.cpp
diff --git a/media/bufferpool/1.0/vts/allocator.h b/media/module/bufferpool/1.0/vts/allocator.h
similarity index 100%
rename from media/bufferpool/1.0/vts/allocator.h
rename to media/module/bufferpool/1.0/vts/allocator.h
diff --git a/media/bufferpool/1.0/vts/multi.cpp b/media/module/bufferpool/1.0/vts/multi.cpp
similarity index 100%
rename from media/bufferpool/1.0/vts/multi.cpp
rename to media/module/bufferpool/1.0/vts/multi.cpp
diff --git a/media/bufferpool/1.0/vts/single.cpp b/media/module/bufferpool/1.0/vts/single.cpp
similarity index 100%
rename from media/bufferpool/1.0/vts/single.cpp
rename to media/module/bufferpool/1.0/vts/single.cpp
diff --git a/media/bufferpool/2.0/Accessor.cpp b/media/module/bufferpool/2.0/Accessor.cpp
similarity index 100%
rename from media/bufferpool/2.0/Accessor.cpp
rename to media/module/bufferpool/2.0/Accessor.cpp
diff --git a/media/bufferpool/2.0/Accessor.h b/media/module/bufferpool/2.0/Accessor.h
similarity index 100%
rename from media/bufferpool/2.0/Accessor.h
rename to media/module/bufferpool/2.0/Accessor.h
diff --git a/media/bufferpool/2.0/AccessorImpl.cpp b/media/module/bufferpool/2.0/AccessorImpl.cpp
similarity index 100%
rename from media/bufferpool/2.0/AccessorImpl.cpp
rename to media/module/bufferpool/2.0/AccessorImpl.cpp
diff --git a/media/bufferpool/2.0/AccessorImpl.h b/media/module/bufferpool/2.0/AccessorImpl.h
similarity index 100%
rename from media/bufferpool/2.0/AccessorImpl.h
rename to media/module/bufferpool/2.0/AccessorImpl.h
diff --git a/media/bufferpool/2.0/Android.bp b/media/module/bufferpool/2.0/Android.bp
similarity index 100%
rename from media/bufferpool/2.0/Android.bp
rename to media/module/bufferpool/2.0/Android.bp
diff --git a/media/bufferpool/2.0/BufferPoolClient.cpp b/media/module/bufferpool/2.0/BufferPoolClient.cpp
similarity index 100%
rename from media/bufferpool/2.0/BufferPoolClient.cpp
rename to media/module/bufferpool/2.0/BufferPoolClient.cpp
diff --git a/media/bufferpool/2.0/BufferPoolClient.h b/media/module/bufferpool/2.0/BufferPoolClient.h
similarity index 100%
rename from media/bufferpool/2.0/BufferPoolClient.h
rename to media/module/bufferpool/2.0/BufferPoolClient.h
diff --git a/media/bufferpool/2.0/BufferStatus.cpp b/media/module/bufferpool/2.0/BufferStatus.cpp
similarity index 100%
rename from media/bufferpool/2.0/BufferStatus.cpp
rename to media/module/bufferpool/2.0/BufferStatus.cpp
diff --git a/media/bufferpool/2.0/BufferStatus.h b/media/module/bufferpool/2.0/BufferStatus.h
similarity index 100%
rename from media/bufferpool/2.0/BufferStatus.h
rename to media/module/bufferpool/2.0/BufferStatus.h
diff --git a/media/bufferpool/2.0/ClientManager.cpp b/media/module/bufferpool/2.0/ClientManager.cpp
similarity index 100%
rename from media/bufferpool/2.0/ClientManager.cpp
rename to media/module/bufferpool/2.0/ClientManager.cpp
diff --git a/media/bufferpool/2.0/Connection.cpp b/media/module/bufferpool/2.0/Connection.cpp
similarity index 100%
rename from media/bufferpool/2.0/Connection.cpp
rename to media/module/bufferpool/2.0/Connection.cpp
diff --git a/media/bufferpool/2.0/Connection.h b/media/module/bufferpool/2.0/Connection.h
similarity index 100%
rename from media/bufferpool/2.0/Connection.h
rename to media/module/bufferpool/2.0/Connection.h
diff --git a/media/bufferpool/2.0/Observer.cpp b/media/module/bufferpool/2.0/Observer.cpp
similarity index 100%
rename from media/bufferpool/2.0/Observer.cpp
rename to media/module/bufferpool/2.0/Observer.cpp
diff --git a/media/bufferpool/2.0/Observer.h b/media/module/bufferpool/2.0/Observer.h
similarity index 100%
rename from media/bufferpool/2.0/Observer.h
rename to media/module/bufferpool/2.0/Observer.h
diff --git a/media/bufferpool/2.0/TEST_MAPPING b/media/module/bufferpool/2.0/TEST_MAPPING
similarity index 100%
rename from media/bufferpool/2.0/TEST_MAPPING
rename to media/module/bufferpool/2.0/TEST_MAPPING
diff --git a/media/bufferpool/2.0/include/bufferpool/BufferPoolTypes.h b/media/module/bufferpool/2.0/include/bufferpool/BufferPoolTypes.h
similarity index 100%
rename from media/bufferpool/2.0/include/bufferpool/BufferPoolTypes.h
rename to media/module/bufferpool/2.0/include/bufferpool/BufferPoolTypes.h
diff --git a/media/bufferpool/2.0/include/bufferpool/ClientManager.h b/media/module/bufferpool/2.0/include/bufferpool/ClientManager.h
similarity index 100%
rename from media/bufferpool/2.0/include/bufferpool/ClientManager.h
rename to media/module/bufferpool/2.0/include/bufferpool/ClientManager.h
diff --git a/media/bufferpool/2.0/tests/Android.bp b/media/module/bufferpool/2.0/tests/Android.bp
similarity index 100%
rename from media/bufferpool/2.0/tests/Android.bp
rename to media/module/bufferpool/2.0/tests/Android.bp
diff --git a/media/bufferpool/2.0/tests/AndroidTest.xml b/media/module/bufferpool/2.0/tests/AndroidTest.xml
similarity index 100%
rename from media/bufferpool/2.0/tests/AndroidTest.xml
rename to media/module/bufferpool/2.0/tests/AndroidTest.xml
diff --git a/media/bufferpool/2.0/tests/BufferpoolUnitTest.cpp b/media/module/bufferpool/2.0/tests/BufferpoolUnitTest.cpp
similarity index 100%
rename from media/bufferpool/2.0/tests/BufferpoolUnitTest.cpp
rename to media/module/bufferpool/2.0/tests/BufferpoolUnitTest.cpp
diff --git a/media/bufferpool/2.0/tests/OWNERS b/media/module/bufferpool/2.0/tests/OWNERS
similarity index 100%
rename from media/bufferpool/2.0/tests/OWNERS
rename to media/module/bufferpool/2.0/tests/OWNERS
diff --git a/media/bufferpool/2.0/tests/README.md b/media/module/bufferpool/2.0/tests/README.md
similarity index 100%
rename from media/bufferpool/2.0/tests/README.md
rename to media/module/bufferpool/2.0/tests/README.md
diff --git a/media/bufferpool/2.0/tests/allocator.cpp b/media/module/bufferpool/2.0/tests/allocator.cpp
similarity index 100%
rename from media/bufferpool/2.0/tests/allocator.cpp
rename to media/module/bufferpool/2.0/tests/allocator.cpp
diff --git a/media/bufferpool/2.0/tests/allocator.h b/media/module/bufferpool/2.0/tests/allocator.h
similarity index 100%
rename from media/bufferpool/2.0/tests/allocator.h
rename to media/module/bufferpool/2.0/tests/allocator.h
diff --git a/media/bufferpool/2.0/tests/cond.cpp b/media/module/bufferpool/2.0/tests/cond.cpp
similarity index 100%
rename from media/bufferpool/2.0/tests/cond.cpp
rename to media/module/bufferpool/2.0/tests/cond.cpp
diff --git a/media/bufferpool/2.0/tests/multi.cpp b/media/module/bufferpool/2.0/tests/multi.cpp
similarity index 100%
rename from media/bufferpool/2.0/tests/multi.cpp
rename to media/module/bufferpool/2.0/tests/multi.cpp
diff --git a/media/bufferpool/2.0/tests/single.cpp b/media/module/bufferpool/2.0/tests/single.cpp
similarity index 100%
rename from media/bufferpool/2.0/tests/single.cpp
rename to media/module/bufferpool/2.0/tests/single.cpp
diff --git a/media/codecs/amrnb/TEST_MAPPING b/media/module/codecs/amrnb/TEST_MAPPING
similarity index 100%
rename from media/codecs/amrnb/TEST_MAPPING
rename to media/module/codecs/amrnb/TEST_MAPPING
diff --git a/media/codecs/amrnb/common/Android.bp b/media/module/codecs/amrnb/common/Android.bp
similarity index 100%
rename from media/codecs/amrnb/common/Android.bp
rename to media/module/codecs/amrnb/common/Android.bp
diff --git a/media/codecs/amrnb/common/MODULE_LICENSE_APACHE2 b/media/module/codecs/amrnb/common/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/codecs/amrnb/common/MODULE_LICENSE_APACHE2
rename to media/module/codecs/amrnb/common/MODULE_LICENSE_APACHE2
diff --git a/media/codecs/amrnb/common/NOTICE b/media/module/codecs/amrnb/common/NOTICE
similarity index 100%
rename from media/codecs/amrnb/common/NOTICE
rename to media/module/codecs/amrnb/common/NOTICE
diff --git a/media/codecs/amrnb/common/include/abs_s.h b/media/module/codecs/amrnb/common/include/abs_s.h
similarity index 100%
rename from media/codecs/amrnb/common/include/abs_s.h
rename to media/module/codecs/amrnb/common/include/abs_s.h
diff --git a/media/codecs/amrnb/common/include/add.h b/media/module/codecs/amrnb/common/include/add.h
similarity index 100%
rename from media/codecs/amrnb/common/include/add.h
rename to media/module/codecs/amrnb/common/include/add.h
diff --git a/media/codecs/amrnb/common/include/az_lsp.h b/media/module/codecs/amrnb/common/include/az_lsp.h
similarity index 100%
rename from media/codecs/amrnb/common/include/az_lsp.h
rename to media/module/codecs/amrnb/common/include/az_lsp.h
diff --git a/media/codecs/amrnb/common/include/basic_op.h b/media/module/codecs/amrnb/common/include/basic_op.h
similarity index 100%
rename from media/codecs/amrnb/common/include/basic_op.h
rename to media/module/codecs/amrnb/common/include/basic_op.h
diff --git a/media/codecs/amrnb/common/include/basic_op_arm_gcc_v5.h b/media/module/codecs/amrnb/common/include/basic_op_arm_gcc_v5.h
similarity index 100%
rename from media/codecs/amrnb/common/include/basic_op_arm_gcc_v5.h
rename to media/module/codecs/amrnb/common/include/basic_op_arm_gcc_v5.h
diff --git a/media/codecs/amrnb/common/include/basic_op_arm_v5.h b/media/module/codecs/amrnb/common/include/basic_op_arm_v5.h
similarity index 100%
rename from media/codecs/amrnb/common/include/basic_op_arm_v5.h
rename to media/module/codecs/amrnb/common/include/basic_op_arm_v5.h
diff --git a/media/codecs/amrnb/common/include/basic_op_c_equivalent.h b/media/module/codecs/amrnb/common/include/basic_op_c_equivalent.h
similarity index 100%
rename from media/codecs/amrnb/common/include/basic_op_c_equivalent.h
rename to media/module/codecs/amrnb/common/include/basic_op_c_equivalent.h
diff --git a/media/codecs/amrnb/common/include/basicop_malloc.h b/media/module/codecs/amrnb/common/include/basicop_malloc.h
similarity index 100%
rename from media/codecs/amrnb/common/include/basicop_malloc.h
rename to media/module/codecs/amrnb/common/include/basicop_malloc.h
diff --git a/media/codecs/amrnb/common/include/bitno_tab.h b/media/module/codecs/amrnb/common/include/bitno_tab.h
similarity index 100%
rename from media/codecs/amrnb/common/include/bitno_tab.h
rename to media/module/codecs/amrnb/common/include/bitno_tab.h
diff --git a/media/codecs/amrnb/common/include/bitreorder_tab.h b/media/module/codecs/amrnb/common/include/bitreorder_tab.h
similarity index 100%
rename from media/codecs/amrnb/common/include/bitreorder_tab.h
rename to media/module/codecs/amrnb/common/include/bitreorder_tab.h
diff --git a/media/codecs/amrnb/common/include/bits2prm.h b/media/module/codecs/amrnb/common/include/bits2prm.h
similarity index 100%
rename from media/codecs/amrnb/common/include/bits2prm.h
rename to media/module/codecs/amrnb/common/include/bits2prm.h
diff --git a/media/codecs/amrnb/common/include/cnst.h b/media/module/codecs/amrnb/common/include/cnst.h
similarity index 100%
rename from media/codecs/amrnb/common/include/cnst.h
rename to media/module/codecs/amrnb/common/include/cnst.h
diff --git a/media/codecs/amrnb/common/include/cnst_vad.h b/media/module/codecs/amrnb/common/include/cnst_vad.h
similarity index 100%
rename from media/codecs/amrnb/common/include/cnst_vad.h
rename to media/module/codecs/amrnb/common/include/cnst_vad.h
diff --git a/media/codecs/amrnb/common/include/copy.h b/media/module/codecs/amrnb/common/include/copy.h
similarity index 100%
rename from media/codecs/amrnb/common/include/copy.h
rename to media/module/codecs/amrnb/common/include/copy.h
diff --git a/media/codecs/amrnb/common/include/d_gain_c.h b/media/module/codecs/amrnb/common/include/d_gain_c.h
similarity index 100%
rename from media/codecs/amrnb/common/include/d_gain_c.h
rename to media/module/codecs/amrnb/common/include/d_gain_c.h
diff --git a/media/codecs/amrnb/common/include/d_gain_p.h b/media/module/codecs/amrnb/common/include/d_gain_p.h
similarity index 100%
rename from media/codecs/amrnb/common/include/d_gain_p.h
rename to media/module/codecs/amrnb/common/include/d_gain_p.h
diff --git a/media/codecs/amrnb/common/include/d_plsf.h b/media/module/codecs/amrnb/common/include/d_plsf.h
similarity index 100%
rename from media/codecs/amrnb/common/include/d_plsf.h
rename to media/module/codecs/amrnb/common/include/d_plsf.h
diff --git a/media/codecs/amrnb/common/include/div_32.h b/media/module/codecs/amrnb/common/include/div_32.h
similarity index 100%
rename from media/codecs/amrnb/common/include/div_32.h
rename to media/module/codecs/amrnb/common/include/div_32.h
diff --git a/media/codecs/amrnb/common/include/div_s.h b/media/module/codecs/amrnb/common/include/div_s.h
similarity index 100%
rename from media/codecs/amrnb/common/include/div_s.h
rename to media/module/codecs/amrnb/common/include/div_s.h
diff --git a/media/codecs/amrnb/common/include/dtx_common_def.h b/media/module/codecs/amrnb/common/include/dtx_common_def.h
similarity index 100%
rename from media/codecs/amrnb/common/include/dtx_common_def.h
rename to media/module/codecs/amrnb/common/include/dtx_common_def.h
diff --git a/media/codecs/amrnb/common/include/extract_h.h b/media/module/codecs/amrnb/common/include/extract_h.h
similarity index 100%
rename from media/codecs/amrnb/common/include/extract_h.h
rename to media/module/codecs/amrnb/common/include/extract_h.h
diff --git a/media/codecs/amrnb/common/include/extract_l.h b/media/module/codecs/amrnb/common/include/extract_l.h
similarity index 100%
rename from media/codecs/amrnb/common/include/extract_l.h
rename to media/module/codecs/amrnb/common/include/extract_l.h
diff --git a/media/codecs/amrnb/common/include/frame.h b/media/module/codecs/amrnb/common/include/frame.h
similarity index 100%
rename from media/codecs/amrnb/common/include/frame.h
rename to media/module/codecs/amrnb/common/include/frame.h
diff --git a/media/codecs/amrnb/common/include/frame_type_3gpp.h b/media/module/codecs/amrnb/common/include/frame_type_3gpp.h
similarity index 100%
rename from media/codecs/amrnb/common/include/frame_type_3gpp.h
rename to media/module/codecs/amrnb/common/include/frame_type_3gpp.h
diff --git a/media/codecs/amrnb/common/include/gc_pred.h b/media/module/codecs/amrnb/common/include/gc_pred.h
similarity index 100%
rename from media/codecs/amrnb/common/include/gc_pred.h
rename to media/module/codecs/amrnb/common/include/gc_pred.h
diff --git a/media/codecs/amrnb/common/include/gmed_n.h b/media/module/codecs/amrnb/common/include/gmed_n.h
similarity index 100%
rename from media/codecs/amrnb/common/include/gmed_n.h
rename to media/module/codecs/amrnb/common/include/gmed_n.h
diff --git a/media/codecs/amrnb/common/include/gsm_amr_typedefs.h b/media/module/codecs/amrnb/common/include/gsm_amr_typedefs.h
similarity index 100%
rename from media/codecs/amrnb/common/include/gsm_amr_typedefs.h
rename to media/module/codecs/amrnb/common/include/gsm_amr_typedefs.h
diff --git a/media/codecs/amrnb/common/include/int_lpc.h b/media/module/codecs/amrnb/common/include/int_lpc.h
similarity index 100%
rename from media/codecs/amrnb/common/include/int_lpc.h
rename to media/module/codecs/amrnb/common/include/int_lpc.h
diff --git a/media/codecs/amrnb/common/include/int_lsf.h b/media/module/codecs/amrnb/common/include/int_lsf.h
similarity index 100%
rename from media/codecs/amrnb/common/include/int_lsf.h
rename to media/module/codecs/amrnb/common/include/int_lsf.h
diff --git a/media/codecs/amrnb/common/include/inv_sqrt.h b/media/module/codecs/amrnb/common/include/inv_sqrt.h
similarity index 100%
rename from media/codecs/amrnb/common/include/inv_sqrt.h
rename to media/module/codecs/amrnb/common/include/inv_sqrt.h
diff --git a/media/codecs/amrnb/common/include/l_abs.h b/media/module/codecs/amrnb/common/include/l_abs.h
similarity index 100%
rename from media/codecs/amrnb/common/include/l_abs.h
rename to media/module/codecs/amrnb/common/include/l_abs.h
diff --git a/media/codecs/amrnb/common/include/l_add.h b/media/module/codecs/amrnb/common/include/l_add.h
similarity index 100%
rename from media/codecs/amrnb/common/include/l_add.h
rename to media/module/codecs/amrnb/common/include/l_add.h
diff --git a/media/codecs/amrnb/common/include/l_add_c.h b/media/module/codecs/amrnb/common/include/l_add_c.h
similarity index 100%
rename from media/codecs/amrnb/common/include/l_add_c.h
rename to media/module/codecs/amrnb/common/include/l_add_c.h
diff --git a/media/codecs/amrnb/common/include/l_comp.h b/media/module/codecs/amrnb/common/include/l_comp.h
similarity index 100%
rename from media/codecs/amrnb/common/include/l_comp.h
rename to media/module/codecs/amrnb/common/include/l_comp.h
diff --git a/media/codecs/amrnb/common/include/l_deposit_h.h b/media/module/codecs/amrnb/common/include/l_deposit_h.h
similarity index 100%
rename from media/codecs/amrnb/common/include/l_deposit_h.h
rename to media/module/codecs/amrnb/common/include/l_deposit_h.h
diff --git a/media/codecs/amrnb/common/include/l_deposit_l.h b/media/module/codecs/amrnb/common/include/l_deposit_l.h
similarity index 100%
rename from media/codecs/amrnb/common/include/l_deposit_l.h
rename to media/module/codecs/amrnb/common/include/l_deposit_l.h
diff --git a/media/codecs/amrnb/common/include/l_extract.h b/media/module/codecs/amrnb/common/include/l_extract.h
similarity index 100%
rename from media/codecs/amrnb/common/include/l_extract.h
rename to media/module/codecs/amrnb/common/include/l_extract.h
diff --git a/media/codecs/amrnb/common/include/l_mac.h b/media/module/codecs/amrnb/common/include/l_mac.h
similarity index 100%
rename from media/codecs/amrnb/common/include/l_mac.h
rename to media/module/codecs/amrnb/common/include/l_mac.h
diff --git a/media/codecs/amrnb/common/include/l_msu.h b/media/module/codecs/amrnb/common/include/l_msu.h
similarity index 100%
rename from media/codecs/amrnb/common/include/l_msu.h
rename to media/module/codecs/amrnb/common/include/l_msu.h
diff --git a/media/codecs/amrnb/common/include/l_mult.h b/media/module/codecs/amrnb/common/include/l_mult.h
similarity index 100%
rename from media/codecs/amrnb/common/include/l_mult.h
rename to media/module/codecs/amrnb/common/include/l_mult.h
diff --git a/media/codecs/amrnb/common/include/l_negate.h b/media/module/codecs/amrnb/common/include/l_negate.h
similarity index 100%
rename from media/codecs/amrnb/common/include/l_negate.h
rename to media/module/codecs/amrnb/common/include/l_negate.h
diff --git a/media/codecs/amrnb/common/include/l_shl.h b/media/module/codecs/amrnb/common/include/l_shl.h
similarity index 100%
rename from media/codecs/amrnb/common/include/l_shl.h
rename to media/module/codecs/amrnb/common/include/l_shl.h
diff --git a/media/codecs/amrnb/common/include/l_shr.h b/media/module/codecs/amrnb/common/include/l_shr.h
similarity index 100%
rename from media/codecs/amrnb/common/include/l_shr.h
rename to media/module/codecs/amrnb/common/include/l_shr.h
diff --git a/media/codecs/amrnb/common/include/l_shr_r.h b/media/module/codecs/amrnb/common/include/l_shr_r.h
similarity index 100%
rename from media/codecs/amrnb/common/include/l_shr_r.h
rename to media/module/codecs/amrnb/common/include/l_shr_r.h
diff --git a/media/codecs/amrnb/common/include/l_sub.h b/media/module/codecs/amrnb/common/include/l_sub.h
similarity index 100%
rename from media/codecs/amrnb/common/include/l_sub.h
rename to media/module/codecs/amrnb/common/include/l_sub.h
diff --git a/media/codecs/amrnb/common/include/log2.h b/media/module/codecs/amrnb/common/include/log2.h
similarity index 100%
rename from media/codecs/amrnb/common/include/log2.h
rename to media/module/codecs/amrnb/common/include/log2.h
diff --git a/media/codecs/amrnb/common/include/log2_norm.h b/media/module/codecs/amrnb/common/include/log2_norm.h
similarity index 100%
rename from media/codecs/amrnb/common/include/log2_norm.h
rename to media/module/codecs/amrnb/common/include/log2_norm.h
diff --git a/media/codecs/amrnb/common/include/lsfwt.h b/media/module/codecs/amrnb/common/include/lsfwt.h
similarity index 100%
rename from media/codecs/amrnb/common/include/lsfwt.h
rename to media/module/codecs/amrnb/common/include/lsfwt.h
diff --git a/media/codecs/amrnb/common/include/lsp.h b/media/module/codecs/amrnb/common/include/lsp.h
similarity index 100%
rename from media/codecs/amrnb/common/include/lsp.h
rename to media/module/codecs/amrnb/common/include/lsp.h
diff --git a/media/codecs/amrnb/common/include/lsp_az.h b/media/module/codecs/amrnb/common/include/lsp_az.h
similarity index 100%
rename from media/codecs/amrnb/common/include/lsp_az.h
rename to media/module/codecs/amrnb/common/include/lsp_az.h
diff --git a/media/codecs/amrnb/common/include/lsp_lsf.h b/media/module/codecs/amrnb/common/include/lsp_lsf.h
similarity index 100%
rename from media/codecs/amrnb/common/include/lsp_lsf.h
rename to media/module/codecs/amrnb/common/include/lsp_lsf.h
diff --git a/media/codecs/amrnb/common/include/lsp_tab.h b/media/module/codecs/amrnb/common/include/lsp_tab.h
similarity index 100%
rename from media/codecs/amrnb/common/include/lsp_tab.h
rename to media/module/codecs/amrnb/common/include/lsp_tab.h
diff --git a/media/codecs/amrnb/common/include/mac_32.h b/media/module/codecs/amrnb/common/include/mac_32.h
similarity index 100%
rename from media/codecs/amrnb/common/include/mac_32.h
rename to media/module/codecs/amrnb/common/include/mac_32.h
diff --git a/media/codecs/amrnb/common/include/mode.h b/media/module/codecs/amrnb/common/include/mode.h
similarity index 100%
rename from media/codecs/amrnb/common/include/mode.h
rename to media/module/codecs/amrnb/common/include/mode.h
diff --git a/media/codecs/amrnb/common/include/mpy_32.h b/media/module/codecs/amrnb/common/include/mpy_32.h
similarity index 100%
rename from media/codecs/amrnb/common/include/mpy_32.h
rename to media/module/codecs/amrnb/common/include/mpy_32.h
diff --git a/media/codecs/amrnb/common/include/mpy_32_16.h b/media/module/codecs/amrnb/common/include/mpy_32_16.h
similarity index 100%
rename from media/codecs/amrnb/common/include/mpy_32_16.h
rename to media/module/codecs/amrnb/common/include/mpy_32_16.h
diff --git a/media/codecs/amrnb/common/include/mult.h b/media/module/codecs/amrnb/common/include/mult.h
similarity index 100%
rename from media/codecs/amrnb/common/include/mult.h
rename to media/module/codecs/amrnb/common/include/mult.h
diff --git a/media/codecs/amrnb/common/include/mult_r.h b/media/module/codecs/amrnb/common/include/mult_r.h
similarity index 100%
rename from media/codecs/amrnb/common/include/mult_r.h
rename to media/module/codecs/amrnb/common/include/mult_r.h
diff --git a/media/codecs/amrnb/common/include/n_proc.h b/media/module/codecs/amrnb/common/include/n_proc.h
similarity index 100%
rename from media/codecs/amrnb/common/include/n_proc.h
rename to media/module/codecs/amrnb/common/include/n_proc.h
diff --git a/media/codecs/amrnb/common/include/negate.h b/media/module/codecs/amrnb/common/include/negate.h
similarity index 100%
rename from media/codecs/amrnb/common/include/negate.h
rename to media/module/codecs/amrnb/common/include/negate.h
diff --git a/media/codecs/amrnb/common/include/norm_l.h b/media/module/codecs/amrnb/common/include/norm_l.h
similarity index 100%
rename from media/codecs/amrnb/common/include/norm_l.h
rename to media/module/codecs/amrnb/common/include/norm_l.h
diff --git a/media/codecs/amrnb/common/include/norm_s.h b/media/module/codecs/amrnb/common/include/norm_s.h
similarity index 100%
rename from media/codecs/amrnb/common/include/norm_s.h
rename to media/module/codecs/amrnb/common/include/norm_s.h
diff --git a/media/codecs/amrnb/common/include/oper_32b.h b/media/module/codecs/amrnb/common/include/oper_32b.h
similarity index 100%
rename from media/codecs/amrnb/common/include/oper_32b.h
rename to media/module/codecs/amrnb/common/include/oper_32b.h
diff --git a/media/codecs/amrnb/common/include/p_ol_wgh.h b/media/module/codecs/amrnb/common/include/p_ol_wgh.h
similarity index 100%
rename from media/codecs/amrnb/common/include/p_ol_wgh.h
rename to media/module/codecs/amrnb/common/include/p_ol_wgh.h
diff --git a/media/codecs/amrnb/common/include/pow2.h b/media/module/codecs/amrnb/common/include/pow2.h
similarity index 100%
rename from media/codecs/amrnb/common/include/pow2.h
rename to media/module/codecs/amrnb/common/include/pow2.h
diff --git a/media/codecs/amrnb/common/include/pred_lt.h b/media/module/codecs/amrnb/common/include/pred_lt.h
similarity index 100%
rename from media/codecs/amrnb/common/include/pred_lt.h
rename to media/module/codecs/amrnb/common/include/pred_lt.h
diff --git a/media/codecs/amrnb/common/include/q_plsf.h b/media/module/codecs/amrnb/common/include/q_plsf.h
similarity index 100%
rename from media/codecs/amrnb/common/include/q_plsf.h
rename to media/module/codecs/amrnb/common/include/q_plsf.h
diff --git a/media/codecs/amrnb/common/include/q_plsf_3_tbl.h b/media/module/codecs/amrnb/common/include/q_plsf_3_tbl.h
similarity index 100%
rename from media/codecs/amrnb/common/include/q_plsf_3_tbl.h
rename to media/module/codecs/amrnb/common/include/q_plsf_3_tbl.h
diff --git a/media/codecs/amrnb/common/include/q_plsf_5_tbl.h b/media/module/codecs/amrnb/common/include/q_plsf_5_tbl.h
similarity index 100%
rename from media/codecs/amrnb/common/include/q_plsf_5_tbl.h
rename to media/module/codecs/amrnb/common/include/q_plsf_5_tbl.h
diff --git a/media/codecs/amrnb/common/include/qgain475_tab.h b/media/module/codecs/amrnb/common/include/qgain475_tab.h
similarity index 100%
rename from media/codecs/amrnb/common/include/qgain475_tab.h
rename to media/module/codecs/amrnb/common/include/qgain475_tab.h
diff --git a/media/codecs/amrnb/common/include/qua_gain.h b/media/module/codecs/amrnb/common/include/qua_gain.h
similarity index 100%
rename from media/codecs/amrnb/common/include/qua_gain.h
rename to media/module/codecs/amrnb/common/include/qua_gain.h
diff --git a/media/codecs/amrnb/common/include/qua_gain_tbl.h b/media/module/codecs/amrnb/common/include/qua_gain_tbl.h
similarity index 100%
rename from media/codecs/amrnb/common/include/qua_gain_tbl.h
rename to media/module/codecs/amrnb/common/include/qua_gain_tbl.h
diff --git a/media/codecs/amrnb/common/include/reorder.h b/media/module/codecs/amrnb/common/include/reorder.h
similarity index 100%
rename from media/codecs/amrnb/common/include/reorder.h
rename to media/module/codecs/amrnb/common/include/reorder.h
diff --git a/media/codecs/amrnb/common/include/residu.h b/media/module/codecs/amrnb/common/include/residu.h
similarity index 100%
rename from media/codecs/amrnb/common/include/residu.h
rename to media/module/codecs/amrnb/common/include/residu.h
diff --git a/media/codecs/amrnb/common/include/reverse_bits.h b/media/module/codecs/amrnb/common/include/reverse_bits.h
similarity index 100%
rename from media/codecs/amrnb/common/include/reverse_bits.h
rename to media/module/codecs/amrnb/common/include/reverse_bits.h
diff --git a/media/codecs/amrnb/common/include/round.h b/media/module/codecs/amrnb/common/include/round.h
similarity index 100%
rename from media/codecs/amrnb/common/include/round.h
rename to media/module/codecs/amrnb/common/include/round.h
diff --git a/media/codecs/amrnb/common/include/set_zero.h b/media/module/codecs/amrnb/common/include/set_zero.h
similarity index 100%
rename from media/codecs/amrnb/common/include/set_zero.h
rename to media/module/codecs/amrnb/common/include/set_zero.h
diff --git a/media/codecs/amrnb/common/include/shl.h b/media/module/codecs/amrnb/common/include/shl.h
similarity index 100%
rename from media/codecs/amrnb/common/include/shl.h
rename to media/module/codecs/amrnb/common/include/shl.h
diff --git a/media/codecs/amrnb/common/include/shr.h b/media/module/codecs/amrnb/common/include/shr.h
similarity index 100%
rename from media/codecs/amrnb/common/include/shr.h
rename to media/module/codecs/amrnb/common/include/shr.h
diff --git a/media/codecs/amrnb/common/include/shr_r.h b/media/module/codecs/amrnb/common/include/shr_r.h
similarity index 100%
rename from media/codecs/amrnb/common/include/shr_r.h
rename to media/module/codecs/amrnb/common/include/shr_r.h
diff --git a/media/codecs/amrnb/common/include/sqrt_l.h b/media/module/codecs/amrnb/common/include/sqrt_l.h
similarity index 100%
rename from media/codecs/amrnb/common/include/sqrt_l.h
rename to media/module/codecs/amrnb/common/include/sqrt_l.h
diff --git a/media/codecs/amrnb/common/include/sub.h b/media/module/codecs/amrnb/common/include/sub.h
similarity index 100%
rename from media/codecs/amrnb/common/include/sub.h
rename to media/module/codecs/amrnb/common/include/sub.h
diff --git a/media/codecs/amrnb/common/include/syn_filt.h b/media/module/codecs/amrnb/common/include/syn_filt.h
similarity index 100%
rename from media/codecs/amrnb/common/include/syn_filt.h
rename to media/module/codecs/amrnb/common/include/syn_filt.h
diff --git a/media/codecs/amrnb/common/include/typedef.h b/media/module/codecs/amrnb/common/include/typedef.h
similarity index 100%
rename from media/codecs/amrnb/common/include/typedef.h
rename to media/module/codecs/amrnb/common/include/typedef.h
diff --git a/media/codecs/amrnb/common/include/vad.h b/media/module/codecs/amrnb/common/include/vad.h
similarity index 100%
rename from media/codecs/amrnb/common/include/vad.h
rename to media/module/codecs/amrnb/common/include/vad.h
diff --git a/media/codecs/amrnb/common/include/vad1.h b/media/module/codecs/amrnb/common/include/vad1.h
similarity index 100%
rename from media/codecs/amrnb/common/include/vad1.h
rename to media/module/codecs/amrnb/common/include/vad1.h
diff --git a/media/codecs/amrnb/common/include/vad2.h b/media/module/codecs/amrnb/common/include/vad2.h
similarity index 100%
rename from media/codecs/amrnb/common/include/vad2.h
rename to media/module/codecs/amrnb/common/include/vad2.h
diff --git a/media/codecs/amrnb/common/include/weight_a.h b/media/module/codecs/amrnb/common/include/weight_a.h
similarity index 100%
rename from media/codecs/amrnb/common/include/weight_a.h
rename to media/module/codecs/amrnb/common/include/weight_a.h
diff --git a/media/codecs/amrnb/common/include/window_tab.h b/media/module/codecs/amrnb/common/include/window_tab.h
similarity index 100%
rename from media/codecs/amrnb/common/include/window_tab.h
rename to media/module/codecs/amrnb/common/include/window_tab.h
diff --git a/media/codecs/amrnb/common/include/wmf_to_ets.h b/media/module/codecs/amrnb/common/include/wmf_to_ets.h
similarity index 100%
rename from media/codecs/amrnb/common/include/wmf_to_ets.h
rename to media/module/codecs/amrnb/common/include/wmf_to_ets.h
diff --git a/media/codecs/amrnb/common/src/add.cpp b/media/module/codecs/amrnb/common/src/add.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/add.cpp
rename to media/module/codecs/amrnb/common/src/add.cpp
diff --git a/media/codecs/amrnb/common/src/az_lsp.cpp b/media/module/codecs/amrnb/common/src/az_lsp.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/az_lsp.cpp
rename to media/module/codecs/amrnb/common/src/az_lsp.cpp
diff --git a/media/codecs/amrnb/common/src/bitno_tab.cpp b/media/module/codecs/amrnb/common/src/bitno_tab.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/bitno_tab.cpp
rename to media/module/codecs/amrnb/common/src/bitno_tab.cpp
diff --git a/media/codecs/amrnb/common/src/bitreorder_tab.cpp b/media/module/codecs/amrnb/common/src/bitreorder_tab.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/bitreorder_tab.cpp
rename to media/module/codecs/amrnb/common/src/bitreorder_tab.cpp
diff --git a/media/codecs/amrnb/common/src/bits2prm.cpp b/media/module/codecs/amrnb/common/src/bits2prm.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/bits2prm.cpp
rename to media/module/codecs/amrnb/common/src/bits2prm.cpp
diff --git a/media/codecs/amrnb/common/src/c2_9pf_tab.cpp b/media/module/codecs/amrnb/common/src/c2_9pf_tab.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/c2_9pf_tab.cpp
rename to media/module/codecs/amrnb/common/src/c2_9pf_tab.cpp
diff --git a/media/codecs/amrnb/common/src/copy.cpp b/media/module/codecs/amrnb/common/src/copy.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/copy.cpp
rename to media/module/codecs/amrnb/common/src/copy.cpp
diff --git a/media/codecs/amrnb/common/src/div_32.cpp b/media/module/codecs/amrnb/common/src/div_32.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/div_32.cpp
rename to media/module/codecs/amrnb/common/src/div_32.cpp
diff --git a/media/codecs/amrnb/common/src/div_s.cpp b/media/module/codecs/amrnb/common/src/div_s.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/div_s.cpp
rename to media/module/codecs/amrnb/common/src/div_s.cpp
diff --git a/media/codecs/amrnb/common/src/extract_h.cpp b/media/module/codecs/amrnb/common/src/extract_h.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/extract_h.cpp
rename to media/module/codecs/amrnb/common/src/extract_h.cpp
diff --git a/media/codecs/amrnb/common/src/extract_l.cpp b/media/module/codecs/amrnb/common/src/extract_l.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/extract_l.cpp
rename to media/module/codecs/amrnb/common/src/extract_l.cpp
diff --git a/media/codecs/amrnb/common/src/gains_tbl.cpp b/media/module/codecs/amrnb/common/src/gains_tbl.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/gains_tbl.cpp
rename to media/module/codecs/amrnb/common/src/gains_tbl.cpp
diff --git a/media/codecs/amrnb/common/src/gc_pred.cpp b/media/module/codecs/amrnb/common/src/gc_pred.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/gc_pred.cpp
rename to media/module/codecs/amrnb/common/src/gc_pred.cpp
diff --git a/media/codecs/amrnb/common/src/gmed_n.cpp b/media/module/codecs/amrnb/common/src/gmed_n.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/gmed_n.cpp
rename to media/module/codecs/amrnb/common/src/gmed_n.cpp
diff --git a/media/codecs/amrnb/common/src/gray_tbl.cpp b/media/module/codecs/amrnb/common/src/gray_tbl.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/gray_tbl.cpp
rename to media/module/codecs/amrnb/common/src/gray_tbl.cpp
diff --git a/media/codecs/amrnb/common/src/grid_tbl.cpp b/media/module/codecs/amrnb/common/src/grid_tbl.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/grid_tbl.cpp
rename to media/module/codecs/amrnb/common/src/grid_tbl.cpp
diff --git a/media/codecs/amrnb/common/src/int_lpc.cpp b/media/module/codecs/amrnb/common/src/int_lpc.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/int_lpc.cpp
rename to media/module/codecs/amrnb/common/src/int_lpc.cpp
diff --git a/media/codecs/amrnb/common/src/inv_sqrt.cpp b/media/module/codecs/amrnb/common/src/inv_sqrt.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/inv_sqrt.cpp
rename to media/module/codecs/amrnb/common/src/inv_sqrt.cpp
diff --git a/media/codecs/amrnb/common/src/inv_sqrt_tbl.cpp b/media/module/codecs/amrnb/common/src/inv_sqrt_tbl.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/inv_sqrt_tbl.cpp
rename to media/module/codecs/amrnb/common/src/inv_sqrt_tbl.cpp
diff --git a/media/codecs/amrnb/common/src/l_abs.cpp b/media/module/codecs/amrnb/common/src/l_abs.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/l_abs.cpp
rename to media/module/codecs/amrnb/common/src/l_abs.cpp
diff --git a/media/codecs/amrnb/common/src/l_deposit_h.cpp b/media/module/codecs/amrnb/common/src/l_deposit_h.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/l_deposit_h.cpp
rename to media/module/codecs/amrnb/common/src/l_deposit_h.cpp
diff --git a/media/codecs/amrnb/common/src/l_deposit_l.cpp b/media/module/codecs/amrnb/common/src/l_deposit_l.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/l_deposit_l.cpp
rename to media/module/codecs/amrnb/common/src/l_deposit_l.cpp
diff --git a/media/codecs/amrnb/common/src/l_shr_r.cpp b/media/module/codecs/amrnb/common/src/l_shr_r.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/l_shr_r.cpp
rename to media/module/codecs/amrnb/common/src/l_shr_r.cpp
diff --git a/media/codecs/amrnb/common/src/log2.cpp b/media/module/codecs/amrnb/common/src/log2.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/log2.cpp
rename to media/module/codecs/amrnb/common/src/log2.cpp
diff --git a/media/codecs/amrnb/common/src/log2_norm.cpp b/media/module/codecs/amrnb/common/src/log2_norm.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/log2_norm.cpp
rename to media/module/codecs/amrnb/common/src/log2_norm.cpp
diff --git a/media/codecs/amrnb/common/src/log2_tbl.cpp b/media/module/codecs/amrnb/common/src/log2_tbl.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/log2_tbl.cpp
rename to media/module/codecs/amrnb/common/src/log2_tbl.cpp
diff --git a/media/codecs/amrnb/common/src/lsfwt.cpp b/media/module/codecs/amrnb/common/src/lsfwt.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/lsfwt.cpp
rename to media/module/codecs/amrnb/common/src/lsfwt.cpp
diff --git a/media/codecs/amrnb/common/src/lsp.cpp b/media/module/codecs/amrnb/common/src/lsp.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/lsp.cpp
rename to media/module/codecs/amrnb/common/src/lsp.cpp
diff --git a/media/codecs/amrnb/common/src/lsp_az.cpp b/media/module/codecs/amrnb/common/src/lsp_az.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/lsp_az.cpp
rename to media/module/codecs/amrnb/common/src/lsp_az.cpp
diff --git a/media/codecs/amrnb/common/src/lsp_lsf.cpp b/media/module/codecs/amrnb/common/src/lsp_lsf.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/lsp_lsf.cpp
rename to media/module/codecs/amrnb/common/src/lsp_lsf.cpp
diff --git a/media/codecs/amrnb/common/src/lsp_lsf_tbl.cpp b/media/module/codecs/amrnb/common/src/lsp_lsf_tbl.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/lsp_lsf_tbl.cpp
rename to media/module/codecs/amrnb/common/src/lsp_lsf_tbl.cpp
diff --git a/media/codecs/amrnb/common/src/lsp_tab.cpp b/media/module/codecs/amrnb/common/src/lsp_tab.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/lsp_tab.cpp
rename to media/module/codecs/amrnb/common/src/lsp_tab.cpp
diff --git a/media/codecs/amrnb/common/src/mult_r.cpp b/media/module/codecs/amrnb/common/src/mult_r.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/mult_r.cpp
rename to media/module/codecs/amrnb/common/src/mult_r.cpp
diff --git a/media/codecs/amrnb/common/src/negate.cpp b/media/module/codecs/amrnb/common/src/negate.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/negate.cpp
rename to media/module/codecs/amrnb/common/src/negate.cpp
diff --git a/media/codecs/amrnb/common/src/norm_l.cpp b/media/module/codecs/amrnb/common/src/norm_l.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/norm_l.cpp
rename to media/module/codecs/amrnb/common/src/norm_l.cpp
diff --git a/media/codecs/amrnb/common/src/norm_s.cpp b/media/module/codecs/amrnb/common/src/norm_s.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/norm_s.cpp
rename to media/module/codecs/amrnb/common/src/norm_s.cpp
diff --git a/media/codecs/amrnb/common/src/ph_disp_tab.cpp b/media/module/codecs/amrnb/common/src/ph_disp_tab.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/ph_disp_tab.cpp
rename to media/module/codecs/amrnb/common/src/ph_disp_tab.cpp
diff --git a/media/codecs/amrnb/common/src/pow2.cpp b/media/module/codecs/amrnb/common/src/pow2.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/pow2.cpp
rename to media/module/codecs/amrnb/common/src/pow2.cpp
diff --git a/media/codecs/amrnb/common/src/pow2_tbl.cpp b/media/module/codecs/amrnb/common/src/pow2_tbl.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/pow2_tbl.cpp
rename to media/module/codecs/amrnb/common/src/pow2_tbl.cpp
diff --git a/media/codecs/amrnb/common/src/pred_lt.cpp b/media/module/codecs/amrnb/common/src/pred_lt.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/pred_lt.cpp
rename to media/module/codecs/amrnb/common/src/pred_lt.cpp
diff --git a/media/codecs/amrnb/common/src/q_plsf.cpp b/media/module/codecs/amrnb/common/src/q_plsf.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/q_plsf.cpp
rename to media/module/codecs/amrnb/common/src/q_plsf.cpp
diff --git a/media/codecs/amrnb/common/src/q_plsf_3.cpp b/media/module/codecs/amrnb/common/src/q_plsf_3.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/q_plsf_3.cpp
rename to media/module/codecs/amrnb/common/src/q_plsf_3.cpp
diff --git a/media/codecs/amrnb/common/src/q_plsf_3_tbl.cpp b/media/module/codecs/amrnb/common/src/q_plsf_3_tbl.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/q_plsf_3_tbl.cpp
rename to media/module/codecs/amrnb/common/src/q_plsf_3_tbl.cpp
diff --git a/media/codecs/amrnb/common/src/q_plsf_5.cpp b/media/module/codecs/amrnb/common/src/q_plsf_5.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/q_plsf_5.cpp
rename to media/module/codecs/amrnb/common/src/q_plsf_5.cpp
diff --git a/media/codecs/amrnb/common/src/q_plsf_5_tbl.cpp b/media/module/codecs/amrnb/common/src/q_plsf_5_tbl.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/q_plsf_5_tbl.cpp
rename to media/module/codecs/amrnb/common/src/q_plsf_5_tbl.cpp
diff --git a/media/codecs/amrnb/common/src/qua_gain_tbl.cpp b/media/module/codecs/amrnb/common/src/qua_gain_tbl.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/qua_gain_tbl.cpp
rename to media/module/codecs/amrnb/common/src/qua_gain_tbl.cpp
diff --git a/media/codecs/amrnb/common/src/reorder.cpp b/media/module/codecs/amrnb/common/src/reorder.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/reorder.cpp
rename to media/module/codecs/amrnb/common/src/reorder.cpp
diff --git a/media/codecs/amrnb/common/src/residu.cpp b/media/module/codecs/amrnb/common/src/residu.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/residu.cpp
rename to media/module/codecs/amrnb/common/src/residu.cpp
diff --git a/media/codecs/amrnb/common/src/round.cpp b/media/module/codecs/amrnb/common/src/round.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/round.cpp
rename to media/module/codecs/amrnb/common/src/round.cpp
diff --git a/media/codecs/amrnb/common/src/set_zero.cpp b/media/module/codecs/amrnb/common/src/set_zero.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/set_zero.cpp
rename to media/module/codecs/amrnb/common/src/set_zero.cpp
diff --git a/media/codecs/amrnb/common/src/shr.cpp b/media/module/codecs/amrnb/common/src/shr.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/shr.cpp
rename to media/module/codecs/amrnb/common/src/shr.cpp
diff --git a/media/codecs/amrnb/common/src/shr_r.cpp b/media/module/codecs/amrnb/common/src/shr_r.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/shr_r.cpp
rename to media/module/codecs/amrnb/common/src/shr_r.cpp
diff --git a/media/codecs/amrnb/common/src/sqrt_l.cpp b/media/module/codecs/amrnb/common/src/sqrt_l.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/sqrt_l.cpp
rename to media/module/codecs/amrnb/common/src/sqrt_l.cpp
diff --git a/media/codecs/amrnb/common/src/sqrt_l_tbl.cpp b/media/module/codecs/amrnb/common/src/sqrt_l_tbl.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/sqrt_l_tbl.cpp
rename to media/module/codecs/amrnb/common/src/sqrt_l_tbl.cpp
diff --git a/media/codecs/amrnb/common/src/sub.cpp b/media/module/codecs/amrnb/common/src/sub.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/sub.cpp
rename to media/module/codecs/amrnb/common/src/sub.cpp
diff --git a/media/codecs/amrnb/common/src/syn_filt.cpp b/media/module/codecs/amrnb/common/src/syn_filt.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/syn_filt.cpp
rename to media/module/codecs/amrnb/common/src/syn_filt.cpp
diff --git a/media/codecs/amrnb/common/src/vad1.cpp b/media/module/codecs/amrnb/common/src/vad1.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/vad1.cpp
rename to media/module/codecs/amrnb/common/src/vad1.cpp
diff --git a/media/codecs/amrnb/common/src/weight_a.cpp b/media/module/codecs/amrnb/common/src/weight_a.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/weight_a.cpp
rename to media/module/codecs/amrnb/common/src/weight_a.cpp
diff --git a/media/codecs/amrnb/common/src/window_tab.cpp b/media/module/codecs/amrnb/common/src/window_tab.cpp
similarity index 100%
rename from media/codecs/amrnb/common/src/window_tab.cpp
rename to media/module/codecs/amrnb/common/src/window_tab.cpp
diff --git a/media/codecs/amrnb/dec/Android.bp b/media/module/codecs/amrnb/dec/Android.bp
similarity index 100%
rename from media/codecs/amrnb/dec/Android.bp
rename to media/module/codecs/amrnb/dec/Android.bp
diff --git a/media/codecs/amrnb/dec/MODULE_LICENSE_APACHE2 b/media/module/codecs/amrnb/dec/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/codecs/amrnb/dec/MODULE_LICENSE_APACHE2
rename to media/module/codecs/amrnb/dec/MODULE_LICENSE_APACHE2
diff --git a/media/codecs/amrnb/dec/NOTICE b/media/module/codecs/amrnb/dec/NOTICE
similarity index 100%
rename from media/codecs/amrnb/dec/NOTICE
rename to media/module/codecs/amrnb/dec/NOTICE
diff --git a/media/codecs/amrnb/dec/src/a_refl.cpp b/media/module/codecs/amrnb/dec/src/a_refl.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/a_refl.cpp
rename to media/module/codecs/amrnb/dec/src/a_refl.cpp
diff --git a/media/codecs/amrnb/dec/src/a_refl.h b/media/module/codecs/amrnb/dec/src/a_refl.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/a_refl.h
rename to media/module/codecs/amrnb/dec/src/a_refl.h
diff --git a/media/codecs/amrnb/dec/src/agc.cpp b/media/module/codecs/amrnb/dec/src/agc.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/agc.cpp
rename to media/module/codecs/amrnb/dec/src/agc.cpp
diff --git a/media/codecs/amrnb/dec/src/agc.h b/media/module/codecs/amrnb/dec/src/agc.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/agc.h
rename to media/module/codecs/amrnb/dec/src/agc.h
diff --git a/media/codecs/amrnb/dec/src/amrdecode.cpp b/media/module/codecs/amrnb/dec/src/amrdecode.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/amrdecode.cpp
rename to media/module/codecs/amrnb/dec/src/amrdecode.cpp
diff --git a/media/codecs/amrnb/dec/src/amrdecode.h b/media/module/codecs/amrnb/dec/src/amrdecode.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/amrdecode.h
rename to media/module/codecs/amrnb/dec/src/amrdecode.h
diff --git a/media/codecs/amrnb/dec/src/b_cn_cod.cpp b/media/module/codecs/amrnb/dec/src/b_cn_cod.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/b_cn_cod.cpp
rename to media/module/codecs/amrnb/dec/src/b_cn_cod.cpp
diff --git a/media/codecs/amrnb/dec/src/b_cn_cod.h b/media/module/codecs/amrnb/dec/src/b_cn_cod.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/b_cn_cod.h
rename to media/module/codecs/amrnb/dec/src/b_cn_cod.h
diff --git a/media/codecs/amrnb/dec/src/bgnscd.cpp b/media/module/codecs/amrnb/dec/src/bgnscd.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/bgnscd.cpp
rename to media/module/codecs/amrnb/dec/src/bgnscd.cpp
diff --git a/media/codecs/amrnb/dec/src/bgnscd.h b/media/module/codecs/amrnb/dec/src/bgnscd.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/bgnscd.h
rename to media/module/codecs/amrnb/dec/src/bgnscd.h
diff --git a/media/codecs/amrnb/dec/src/c_g_aver.cpp b/media/module/codecs/amrnb/dec/src/c_g_aver.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/c_g_aver.cpp
rename to media/module/codecs/amrnb/dec/src/c_g_aver.cpp
diff --git a/media/codecs/amrnb/dec/src/c_g_aver.h b/media/module/codecs/amrnb/dec/src/c_g_aver.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/c_g_aver.h
rename to media/module/codecs/amrnb/dec/src/c_g_aver.h
diff --git a/media/codecs/amrnb/dec/src/d1035pf.cpp b/media/module/codecs/amrnb/dec/src/d1035pf.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/d1035pf.cpp
rename to media/module/codecs/amrnb/dec/src/d1035pf.cpp
diff --git a/media/codecs/amrnb/dec/src/d1035pf.h b/media/module/codecs/amrnb/dec/src/d1035pf.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/d1035pf.h
rename to media/module/codecs/amrnb/dec/src/d1035pf.h
diff --git a/media/codecs/amrnb/dec/src/d2_11pf.cpp b/media/module/codecs/amrnb/dec/src/d2_11pf.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/d2_11pf.cpp
rename to media/module/codecs/amrnb/dec/src/d2_11pf.cpp
diff --git a/media/codecs/amrnb/dec/src/d2_11pf.h b/media/module/codecs/amrnb/dec/src/d2_11pf.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/d2_11pf.h
rename to media/module/codecs/amrnb/dec/src/d2_11pf.h
diff --git a/media/codecs/amrnb/dec/src/d2_9pf.cpp b/media/module/codecs/amrnb/dec/src/d2_9pf.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/d2_9pf.cpp
rename to media/module/codecs/amrnb/dec/src/d2_9pf.cpp
diff --git a/media/codecs/amrnb/dec/src/d2_9pf.h b/media/module/codecs/amrnb/dec/src/d2_9pf.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/d2_9pf.h
rename to media/module/codecs/amrnb/dec/src/d2_9pf.h
diff --git a/media/codecs/amrnb/dec/src/d3_14pf.cpp b/media/module/codecs/amrnb/dec/src/d3_14pf.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/d3_14pf.cpp
rename to media/module/codecs/amrnb/dec/src/d3_14pf.cpp
diff --git a/media/codecs/amrnb/dec/src/d3_14pf.h b/media/module/codecs/amrnb/dec/src/d3_14pf.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/d3_14pf.h
rename to media/module/codecs/amrnb/dec/src/d3_14pf.h
diff --git a/media/codecs/amrnb/dec/src/d4_17pf.cpp b/media/module/codecs/amrnb/dec/src/d4_17pf.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/d4_17pf.cpp
rename to media/module/codecs/amrnb/dec/src/d4_17pf.cpp
diff --git a/media/codecs/amrnb/dec/src/d4_17pf.h b/media/module/codecs/amrnb/dec/src/d4_17pf.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/d4_17pf.h
rename to media/module/codecs/amrnb/dec/src/d4_17pf.h
diff --git a/media/codecs/amrnb/dec/src/d8_31pf.cpp b/media/module/codecs/amrnb/dec/src/d8_31pf.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/d8_31pf.cpp
rename to media/module/codecs/amrnb/dec/src/d8_31pf.cpp
diff --git a/media/codecs/amrnb/dec/src/d8_31pf.h b/media/module/codecs/amrnb/dec/src/d8_31pf.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/d8_31pf.h
rename to media/module/codecs/amrnb/dec/src/d8_31pf.h
diff --git a/media/codecs/amrnb/dec/src/d_gain_c.cpp b/media/module/codecs/amrnb/dec/src/d_gain_c.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/d_gain_c.cpp
rename to media/module/codecs/amrnb/dec/src/d_gain_c.cpp
diff --git a/media/codecs/amrnb/dec/src/d_gain_p.cpp b/media/module/codecs/amrnb/dec/src/d_gain_p.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/d_gain_p.cpp
rename to media/module/codecs/amrnb/dec/src/d_gain_p.cpp
diff --git a/media/codecs/amrnb/dec/src/d_plsf.cpp b/media/module/codecs/amrnb/dec/src/d_plsf.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/d_plsf.cpp
rename to media/module/codecs/amrnb/dec/src/d_plsf.cpp
diff --git a/media/codecs/amrnb/dec/src/d_plsf_3.cpp b/media/module/codecs/amrnb/dec/src/d_plsf_3.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/d_plsf_3.cpp
rename to media/module/codecs/amrnb/dec/src/d_plsf_3.cpp
diff --git a/media/codecs/amrnb/dec/src/d_plsf_5.cpp b/media/module/codecs/amrnb/dec/src/d_plsf_5.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/d_plsf_5.cpp
rename to media/module/codecs/amrnb/dec/src/d_plsf_5.cpp
diff --git a/media/codecs/amrnb/dec/src/dec_amr.cpp b/media/module/codecs/amrnb/dec/src/dec_amr.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/dec_amr.cpp
rename to media/module/codecs/amrnb/dec/src/dec_amr.cpp
diff --git a/media/codecs/amrnb/dec/src/dec_amr.h b/media/module/codecs/amrnb/dec/src/dec_amr.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/dec_amr.h
rename to media/module/codecs/amrnb/dec/src/dec_amr.h
diff --git a/media/codecs/amrnb/dec/src/dec_gain.cpp b/media/module/codecs/amrnb/dec/src/dec_gain.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/dec_gain.cpp
rename to media/module/codecs/amrnb/dec/src/dec_gain.cpp
diff --git a/media/codecs/amrnb/dec/src/dec_gain.h b/media/module/codecs/amrnb/dec/src/dec_gain.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/dec_gain.h
rename to media/module/codecs/amrnb/dec/src/dec_gain.h
diff --git a/media/codecs/amrnb/dec/src/dec_input_format_tab.cpp b/media/module/codecs/amrnb/dec/src/dec_input_format_tab.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/dec_input_format_tab.cpp
rename to media/module/codecs/amrnb/dec/src/dec_input_format_tab.cpp
diff --git a/media/codecs/amrnb/dec/src/dec_lag3.cpp b/media/module/codecs/amrnb/dec/src/dec_lag3.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/dec_lag3.cpp
rename to media/module/codecs/amrnb/dec/src/dec_lag3.cpp
diff --git a/media/codecs/amrnb/dec/src/dec_lag3.h b/media/module/codecs/amrnb/dec/src/dec_lag3.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/dec_lag3.h
rename to media/module/codecs/amrnb/dec/src/dec_lag3.h
diff --git a/media/codecs/amrnb/dec/src/dec_lag6.cpp b/media/module/codecs/amrnb/dec/src/dec_lag6.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/dec_lag6.cpp
rename to media/module/codecs/amrnb/dec/src/dec_lag6.cpp
diff --git a/media/codecs/amrnb/dec/src/dec_lag6.h b/media/module/codecs/amrnb/dec/src/dec_lag6.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/dec_lag6.h
rename to media/module/codecs/amrnb/dec/src/dec_lag6.h
diff --git a/media/codecs/amrnb/dec/src/dtx_dec.cpp b/media/module/codecs/amrnb/dec/src/dtx_dec.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/dtx_dec.cpp
rename to media/module/codecs/amrnb/dec/src/dtx_dec.cpp
diff --git a/media/codecs/amrnb/dec/src/dtx_dec.h b/media/module/codecs/amrnb/dec/src/dtx_dec.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/dtx_dec.h
rename to media/module/codecs/amrnb/dec/src/dtx_dec.h
diff --git a/media/codecs/amrnb/dec/src/ec_gains.cpp b/media/module/codecs/amrnb/dec/src/ec_gains.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/ec_gains.cpp
rename to media/module/codecs/amrnb/dec/src/ec_gains.cpp
diff --git a/media/codecs/amrnb/dec/src/ec_gains.h b/media/module/codecs/amrnb/dec/src/ec_gains.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/ec_gains.h
rename to media/module/codecs/amrnb/dec/src/ec_gains.h
diff --git a/media/codecs/amrnb/dec/src/ex_ctrl.cpp b/media/module/codecs/amrnb/dec/src/ex_ctrl.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/ex_ctrl.cpp
rename to media/module/codecs/amrnb/dec/src/ex_ctrl.cpp
diff --git a/media/codecs/amrnb/dec/src/ex_ctrl.h b/media/module/codecs/amrnb/dec/src/ex_ctrl.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/ex_ctrl.h
rename to media/module/codecs/amrnb/dec/src/ex_ctrl.h
diff --git a/media/codecs/amrnb/dec/src/gsmamr_dec.h b/media/module/codecs/amrnb/dec/src/gsmamr_dec.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/gsmamr_dec.h
rename to media/module/codecs/amrnb/dec/src/gsmamr_dec.h
diff --git a/media/codecs/amrnb/dec/src/if2_to_ets.cpp b/media/module/codecs/amrnb/dec/src/if2_to_ets.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/if2_to_ets.cpp
rename to media/module/codecs/amrnb/dec/src/if2_to_ets.cpp
diff --git a/media/codecs/amrnb/dec/src/if2_to_ets.h b/media/module/codecs/amrnb/dec/src/if2_to_ets.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/if2_to_ets.h
rename to media/module/codecs/amrnb/dec/src/if2_to_ets.h
diff --git a/media/codecs/amrnb/dec/src/int_lsf.cpp b/media/module/codecs/amrnb/dec/src/int_lsf.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/int_lsf.cpp
rename to media/module/codecs/amrnb/dec/src/int_lsf.cpp
diff --git a/media/codecs/amrnb/dec/src/lsp_avg.cpp b/media/module/codecs/amrnb/dec/src/lsp_avg.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/lsp_avg.cpp
rename to media/module/codecs/amrnb/dec/src/lsp_avg.cpp
diff --git a/media/codecs/amrnb/dec/src/lsp_avg.h b/media/module/codecs/amrnb/dec/src/lsp_avg.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/lsp_avg.h
rename to media/module/codecs/amrnb/dec/src/lsp_avg.h
diff --git a/media/codecs/amrnb/dec/src/ph_disp.cpp b/media/module/codecs/amrnb/dec/src/ph_disp.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/ph_disp.cpp
rename to media/module/codecs/amrnb/dec/src/ph_disp.cpp
diff --git a/media/codecs/amrnb/dec/src/ph_disp.h b/media/module/codecs/amrnb/dec/src/ph_disp.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/ph_disp.h
rename to media/module/codecs/amrnb/dec/src/ph_disp.h
diff --git a/media/codecs/amrnb/dec/src/post_pro.cpp b/media/module/codecs/amrnb/dec/src/post_pro.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/post_pro.cpp
rename to media/module/codecs/amrnb/dec/src/post_pro.cpp
diff --git a/media/codecs/amrnb/dec/src/post_pro.h b/media/module/codecs/amrnb/dec/src/post_pro.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/post_pro.h
rename to media/module/codecs/amrnb/dec/src/post_pro.h
diff --git a/media/codecs/amrnb/dec/src/preemph.cpp b/media/module/codecs/amrnb/dec/src/preemph.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/preemph.cpp
rename to media/module/codecs/amrnb/dec/src/preemph.cpp
diff --git a/media/codecs/amrnb/dec/src/preemph.h b/media/module/codecs/amrnb/dec/src/preemph.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/preemph.h
rename to media/module/codecs/amrnb/dec/src/preemph.h
diff --git a/media/codecs/amrnb/dec/src/pstfilt.cpp b/media/module/codecs/amrnb/dec/src/pstfilt.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/pstfilt.cpp
rename to media/module/codecs/amrnb/dec/src/pstfilt.cpp
diff --git a/media/codecs/amrnb/dec/src/pstfilt.h b/media/module/codecs/amrnb/dec/src/pstfilt.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/pstfilt.h
rename to media/module/codecs/amrnb/dec/src/pstfilt.h
diff --git a/media/codecs/amrnb/dec/src/qgain475_tab.cpp b/media/module/codecs/amrnb/dec/src/qgain475_tab.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/qgain475_tab.cpp
rename to media/module/codecs/amrnb/dec/src/qgain475_tab.cpp
diff --git a/media/codecs/amrnb/dec/src/sp_dec.cpp b/media/module/codecs/amrnb/dec/src/sp_dec.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/sp_dec.cpp
rename to media/module/codecs/amrnb/dec/src/sp_dec.cpp
diff --git a/media/codecs/amrnb/dec/src/sp_dec.h b/media/module/codecs/amrnb/dec/src/sp_dec.h
similarity index 100%
rename from media/codecs/amrnb/dec/src/sp_dec.h
rename to media/module/codecs/amrnb/dec/src/sp_dec.h
diff --git a/media/codecs/amrnb/dec/src/wmf_to_ets.cpp b/media/module/codecs/amrnb/dec/src/wmf_to_ets.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/src/wmf_to_ets.cpp
rename to media/module/codecs/amrnb/dec/src/wmf_to_ets.cpp
diff --git a/media/codecs/amrnb/dec/test/AmrnbDecTestEnvironment.h b/media/module/codecs/amrnb/dec/test/AmrnbDecTestEnvironment.h
similarity index 100%
rename from media/codecs/amrnb/dec/test/AmrnbDecTestEnvironment.h
rename to media/module/codecs/amrnb/dec/test/AmrnbDecTestEnvironment.h
diff --git a/media/codecs/amrnb/dec/test/AmrnbDecoderTest.cpp b/media/module/codecs/amrnb/dec/test/AmrnbDecoderTest.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/test/AmrnbDecoderTest.cpp
rename to media/module/codecs/amrnb/dec/test/AmrnbDecoderTest.cpp
diff --git a/media/codecs/amrnb/dec/test/Android.bp b/media/module/codecs/amrnb/dec/test/Android.bp
similarity index 100%
rename from media/codecs/amrnb/dec/test/Android.bp
rename to media/module/codecs/amrnb/dec/test/Android.bp
diff --git a/media/codecs/amrnb/dec/test/AndroidTest.xml b/media/module/codecs/amrnb/dec/test/AndroidTest.xml
similarity index 100%
rename from media/codecs/amrnb/dec/test/AndroidTest.xml
rename to media/module/codecs/amrnb/dec/test/AndroidTest.xml
diff --git a/media/codecs/amrnb/dec/test/README.md b/media/module/codecs/amrnb/dec/test/README.md
similarity index 100%
rename from media/codecs/amrnb/dec/test/README.md
rename to media/module/codecs/amrnb/dec/test/README.md
diff --git a/media/codecs/amrnb/dec/test/amrnbdec_test.cpp b/media/module/codecs/amrnb/dec/test/amrnbdec_test.cpp
similarity index 100%
rename from media/codecs/amrnb/dec/test/amrnbdec_test.cpp
rename to media/module/codecs/amrnb/dec/test/amrnbdec_test.cpp
diff --git a/media/codecs/amrnb/enc/Android.bp b/media/module/codecs/amrnb/enc/Android.bp
similarity index 100%
rename from media/codecs/amrnb/enc/Android.bp
rename to media/module/codecs/amrnb/enc/Android.bp
diff --git a/media/codecs/amrnb/enc/MODULE_LICENSE_APACHE2 b/media/module/codecs/amrnb/enc/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/codecs/amrnb/enc/MODULE_LICENSE_APACHE2
rename to media/module/codecs/amrnb/enc/MODULE_LICENSE_APACHE2
diff --git a/media/codecs/amrnb/enc/NOTICE b/media/module/codecs/amrnb/enc/NOTICE
similarity index 100%
rename from media/codecs/amrnb/enc/NOTICE
rename to media/module/codecs/amrnb/enc/NOTICE
diff --git a/media/codecs/amrnb/enc/fuzzer/Android.bp b/media/module/codecs/amrnb/enc/fuzzer/Android.bp
similarity index 100%
rename from media/codecs/amrnb/enc/fuzzer/Android.bp
rename to media/module/codecs/amrnb/enc/fuzzer/Android.bp
diff --git a/media/codecs/amrnb/enc/fuzzer/README.md b/media/module/codecs/amrnb/enc/fuzzer/README.md
similarity index 100%
rename from media/codecs/amrnb/enc/fuzzer/README.md
rename to media/module/codecs/amrnb/enc/fuzzer/README.md
diff --git a/media/codecs/amrnb/enc/fuzzer/amrnb_enc_fuzzer.cpp b/media/module/codecs/amrnb/enc/fuzzer/amrnb_enc_fuzzer.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/fuzzer/amrnb_enc_fuzzer.cpp
rename to media/module/codecs/amrnb/enc/fuzzer/amrnb_enc_fuzzer.cpp
diff --git a/media/codecs/amrnb/enc/src/amrencode.cpp b/media/module/codecs/amrnb/enc/src/amrencode.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/amrencode.cpp
rename to media/module/codecs/amrnb/enc/src/amrencode.cpp
diff --git a/media/codecs/amrnb/enc/src/amrencode.h b/media/module/codecs/amrnb/enc/src/amrencode.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/amrencode.h
rename to media/module/codecs/amrnb/enc/src/amrencode.h
diff --git a/media/codecs/amrnb/enc/src/autocorr.cpp b/media/module/codecs/amrnb/enc/src/autocorr.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/autocorr.cpp
rename to media/module/codecs/amrnb/enc/src/autocorr.cpp
diff --git a/media/codecs/amrnb/enc/src/autocorr.h b/media/module/codecs/amrnb/enc/src/autocorr.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/autocorr.h
rename to media/module/codecs/amrnb/enc/src/autocorr.h
diff --git a/media/codecs/amrnb/enc/src/c1035pf.cpp b/media/module/codecs/amrnb/enc/src/c1035pf.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/c1035pf.cpp
rename to media/module/codecs/amrnb/enc/src/c1035pf.cpp
diff --git a/media/codecs/amrnb/enc/src/c1035pf.h b/media/module/codecs/amrnb/enc/src/c1035pf.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/c1035pf.h
rename to media/module/codecs/amrnb/enc/src/c1035pf.h
diff --git a/media/codecs/amrnb/enc/src/c2_11pf.cpp b/media/module/codecs/amrnb/enc/src/c2_11pf.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/c2_11pf.cpp
rename to media/module/codecs/amrnb/enc/src/c2_11pf.cpp
diff --git a/media/codecs/amrnb/enc/src/c2_11pf.h b/media/module/codecs/amrnb/enc/src/c2_11pf.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/c2_11pf.h
rename to media/module/codecs/amrnb/enc/src/c2_11pf.h
diff --git a/media/codecs/amrnb/enc/src/c2_9pf.cpp b/media/module/codecs/amrnb/enc/src/c2_9pf.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/c2_9pf.cpp
rename to media/module/codecs/amrnb/enc/src/c2_9pf.cpp
diff --git a/media/codecs/amrnb/enc/src/c2_9pf.h b/media/module/codecs/amrnb/enc/src/c2_9pf.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/c2_9pf.h
rename to media/module/codecs/amrnb/enc/src/c2_9pf.h
diff --git a/media/codecs/amrnb/enc/src/c3_14pf.cpp b/media/module/codecs/amrnb/enc/src/c3_14pf.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/c3_14pf.cpp
rename to media/module/codecs/amrnb/enc/src/c3_14pf.cpp
diff --git a/media/codecs/amrnb/enc/src/c3_14pf.h b/media/module/codecs/amrnb/enc/src/c3_14pf.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/c3_14pf.h
rename to media/module/codecs/amrnb/enc/src/c3_14pf.h
diff --git a/media/codecs/amrnb/enc/src/c4_17pf.cpp b/media/module/codecs/amrnb/enc/src/c4_17pf.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/c4_17pf.cpp
rename to media/module/codecs/amrnb/enc/src/c4_17pf.cpp
diff --git a/media/codecs/amrnb/enc/src/c4_17pf.h b/media/module/codecs/amrnb/enc/src/c4_17pf.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/c4_17pf.h
rename to media/module/codecs/amrnb/enc/src/c4_17pf.h
diff --git a/media/codecs/amrnb/enc/src/c8_31pf.cpp b/media/module/codecs/amrnb/enc/src/c8_31pf.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/c8_31pf.cpp
rename to media/module/codecs/amrnb/enc/src/c8_31pf.cpp
diff --git a/media/codecs/amrnb/enc/src/c8_31pf.h b/media/module/codecs/amrnb/enc/src/c8_31pf.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/c8_31pf.h
rename to media/module/codecs/amrnb/enc/src/c8_31pf.h
diff --git a/media/codecs/amrnb/enc/src/calc_cor.cpp b/media/module/codecs/amrnb/enc/src/calc_cor.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/calc_cor.cpp
rename to media/module/codecs/amrnb/enc/src/calc_cor.cpp
diff --git a/media/codecs/amrnb/enc/src/calc_cor.h b/media/module/codecs/amrnb/enc/src/calc_cor.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/calc_cor.h
rename to media/module/codecs/amrnb/enc/src/calc_cor.h
diff --git a/media/codecs/amrnb/enc/src/calc_en.cpp b/media/module/codecs/amrnb/enc/src/calc_en.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/calc_en.cpp
rename to media/module/codecs/amrnb/enc/src/calc_en.cpp
diff --git a/media/codecs/amrnb/enc/src/calc_en.h b/media/module/codecs/amrnb/enc/src/calc_en.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/calc_en.h
rename to media/module/codecs/amrnb/enc/src/calc_en.h
diff --git a/media/codecs/amrnb/enc/src/cbsearch.cpp b/media/module/codecs/amrnb/enc/src/cbsearch.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/cbsearch.cpp
rename to media/module/codecs/amrnb/enc/src/cbsearch.cpp
diff --git a/media/codecs/amrnb/enc/src/cbsearch.h b/media/module/codecs/amrnb/enc/src/cbsearch.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/cbsearch.h
rename to media/module/codecs/amrnb/enc/src/cbsearch.h
diff --git a/media/codecs/amrnb/enc/src/cl_ltp.cpp b/media/module/codecs/amrnb/enc/src/cl_ltp.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/cl_ltp.cpp
rename to media/module/codecs/amrnb/enc/src/cl_ltp.cpp
diff --git a/media/codecs/amrnb/enc/src/cl_ltp.h b/media/module/codecs/amrnb/enc/src/cl_ltp.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/cl_ltp.h
rename to media/module/codecs/amrnb/enc/src/cl_ltp.h
diff --git a/media/codecs/amrnb/enc/src/cod_amr.cpp b/media/module/codecs/amrnb/enc/src/cod_amr.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/cod_amr.cpp
rename to media/module/codecs/amrnb/enc/src/cod_amr.cpp
diff --git a/media/codecs/amrnb/enc/src/cod_amr.h b/media/module/codecs/amrnb/enc/src/cod_amr.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/cod_amr.h
rename to media/module/codecs/amrnb/enc/src/cod_amr.h
diff --git a/media/codecs/amrnb/enc/src/convolve.cpp b/media/module/codecs/amrnb/enc/src/convolve.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/convolve.cpp
rename to media/module/codecs/amrnb/enc/src/convolve.cpp
diff --git a/media/codecs/amrnb/enc/src/convolve.h b/media/module/codecs/amrnb/enc/src/convolve.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/convolve.h
rename to media/module/codecs/amrnb/enc/src/convolve.h
diff --git a/media/codecs/amrnb/enc/src/cor_h.cpp b/media/module/codecs/amrnb/enc/src/cor_h.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/cor_h.cpp
rename to media/module/codecs/amrnb/enc/src/cor_h.cpp
diff --git a/media/codecs/amrnb/enc/src/cor_h.h b/media/module/codecs/amrnb/enc/src/cor_h.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/cor_h.h
rename to media/module/codecs/amrnb/enc/src/cor_h.h
diff --git a/media/codecs/amrnb/enc/src/cor_h_x.cpp b/media/module/codecs/amrnb/enc/src/cor_h_x.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/cor_h_x.cpp
rename to media/module/codecs/amrnb/enc/src/cor_h_x.cpp
diff --git a/media/codecs/amrnb/enc/src/cor_h_x.h b/media/module/codecs/amrnb/enc/src/cor_h_x.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/cor_h_x.h
rename to media/module/codecs/amrnb/enc/src/cor_h_x.h
diff --git a/media/codecs/amrnb/enc/src/cor_h_x2.cpp b/media/module/codecs/amrnb/enc/src/cor_h_x2.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/cor_h_x2.cpp
rename to media/module/codecs/amrnb/enc/src/cor_h_x2.cpp
diff --git a/media/codecs/amrnb/enc/src/cor_h_x2.h b/media/module/codecs/amrnb/enc/src/cor_h_x2.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/cor_h_x2.h
rename to media/module/codecs/amrnb/enc/src/cor_h_x2.h
diff --git a/media/codecs/amrnb/enc/src/corrwght_tab.cpp b/media/module/codecs/amrnb/enc/src/corrwght_tab.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/corrwght_tab.cpp
rename to media/module/codecs/amrnb/enc/src/corrwght_tab.cpp
diff --git a/media/codecs/amrnb/enc/src/dtx_enc.cpp b/media/module/codecs/amrnb/enc/src/dtx_enc.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/dtx_enc.cpp
rename to media/module/codecs/amrnb/enc/src/dtx_enc.cpp
diff --git a/media/codecs/amrnb/enc/src/dtx_enc.h b/media/module/codecs/amrnb/enc/src/dtx_enc.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/dtx_enc.h
rename to media/module/codecs/amrnb/enc/src/dtx_enc.h
diff --git a/media/codecs/amrnb/enc/src/enc_lag3.cpp b/media/module/codecs/amrnb/enc/src/enc_lag3.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/enc_lag3.cpp
rename to media/module/codecs/amrnb/enc/src/enc_lag3.cpp
diff --git a/media/codecs/amrnb/enc/src/enc_lag3.h b/media/module/codecs/amrnb/enc/src/enc_lag3.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/enc_lag3.h
rename to media/module/codecs/amrnb/enc/src/enc_lag3.h
diff --git a/media/codecs/amrnb/enc/src/enc_lag6.cpp b/media/module/codecs/amrnb/enc/src/enc_lag6.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/enc_lag6.cpp
rename to media/module/codecs/amrnb/enc/src/enc_lag6.cpp
diff --git a/media/codecs/amrnb/enc/src/enc_lag6.h b/media/module/codecs/amrnb/enc/src/enc_lag6.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/enc_lag6.h
rename to media/module/codecs/amrnb/enc/src/enc_lag6.h
diff --git a/media/codecs/amrnb/enc/src/enc_output_format_tab.cpp b/media/module/codecs/amrnb/enc/src/enc_output_format_tab.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/enc_output_format_tab.cpp
rename to media/module/codecs/amrnb/enc/src/enc_output_format_tab.cpp
diff --git a/media/codecs/amrnb/enc/src/ets_to_if2.cpp b/media/module/codecs/amrnb/enc/src/ets_to_if2.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/ets_to_if2.cpp
rename to media/module/codecs/amrnb/enc/src/ets_to_if2.cpp
diff --git a/media/codecs/amrnb/enc/src/ets_to_if2.h b/media/module/codecs/amrnb/enc/src/ets_to_if2.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/ets_to_if2.h
rename to media/module/codecs/amrnb/enc/src/ets_to_if2.h
diff --git a/media/codecs/amrnb/enc/src/ets_to_wmf.cpp b/media/module/codecs/amrnb/enc/src/ets_to_wmf.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/ets_to_wmf.cpp
rename to media/module/codecs/amrnb/enc/src/ets_to_wmf.cpp
diff --git a/media/codecs/amrnb/enc/src/ets_to_wmf.h b/media/module/codecs/amrnb/enc/src/ets_to_wmf.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/ets_to_wmf.h
rename to media/module/codecs/amrnb/enc/src/ets_to_wmf.h
diff --git a/media/codecs/amrnb/enc/src/g_adapt.cpp b/media/module/codecs/amrnb/enc/src/g_adapt.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/g_adapt.cpp
rename to media/module/codecs/amrnb/enc/src/g_adapt.cpp
diff --git a/media/codecs/amrnb/enc/src/g_adapt.h b/media/module/codecs/amrnb/enc/src/g_adapt.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/g_adapt.h
rename to media/module/codecs/amrnb/enc/src/g_adapt.h
diff --git a/media/codecs/amrnb/enc/src/g_code.cpp b/media/module/codecs/amrnb/enc/src/g_code.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/g_code.cpp
rename to media/module/codecs/amrnb/enc/src/g_code.cpp
diff --git a/media/codecs/amrnb/enc/src/g_code.h b/media/module/codecs/amrnb/enc/src/g_code.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/g_code.h
rename to media/module/codecs/amrnb/enc/src/g_code.h
diff --git a/media/codecs/amrnb/enc/src/g_pitch.cpp b/media/module/codecs/amrnb/enc/src/g_pitch.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/g_pitch.cpp
rename to media/module/codecs/amrnb/enc/src/g_pitch.cpp
diff --git a/media/codecs/amrnb/enc/src/g_pitch.h b/media/module/codecs/amrnb/enc/src/g_pitch.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/g_pitch.h
rename to media/module/codecs/amrnb/enc/src/g_pitch.h
diff --git a/media/codecs/amrnb/enc/src/gain_q.cpp b/media/module/codecs/amrnb/enc/src/gain_q.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/gain_q.cpp
rename to media/module/codecs/amrnb/enc/src/gain_q.cpp
diff --git a/media/codecs/amrnb/enc/src/gain_q.h b/media/module/codecs/amrnb/enc/src/gain_q.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/gain_q.h
rename to media/module/codecs/amrnb/enc/src/gain_q.h
diff --git a/media/codecs/amrnb/enc/src/gsmamr_enc.h b/media/module/codecs/amrnb/enc/src/gsmamr_enc.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/gsmamr_enc.h
rename to media/module/codecs/amrnb/enc/src/gsmamr_enc.h
diff --git a/media/codecs/amrnb/enc/src/hp_max.cpp b/media/module/codecs/amrnb/enc/src/hp_max.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/hp_max.cpp
rename to media/module/codecs/amrnb/enc/src/hp_max.cpp
diff --git a/media/codecs/amrnb/enc/src/hp_max.h b/media/module/codecs/amrnb/enc/src/hp_max.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/hp_max.h
rename to media/module/codecs/amrnb/enc/src/hp_max.h
diff --git a/media/codecs/amrnb/enc/src/inter_36.cpp b/media/module/codecs/amrnb/enc/src/inter_36.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/inter_36.cpp
rename to media/module/codecs/amrnb/enc/src/inter_36.cpp
diff --git a/media/codecs/amrnb/enc/src/inter_36.h b/media/module/codecs/amrnb/enc/src/inter_36.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/inter_36.h
rename to media/module/codecs/amrnb/enc/src/inter_36.h
diff --git a/media/codecs/amrnb/enc/src/inter_36_tab.cpp b/media/module/codecs/amrnb/enc/src/inter_36_tab.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/inter_36_tab.cpp
rename to media/module/codecs/amrnb/enc/src/inter_36_tab.cpp
diff --git a/media/codecs/amrnb/enc/src/inter_36_tab.h b/media/module/codecs/amrnb/enc/src/inter_36_tab.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/inter_36_tab.h
rename to media/module/codecs/amrnb/enc/src/inter_36_tab.h
diff --git a/media/codecs/amrnb/enc/src/l_comp.cpp b/media/module/codecs/amrnb/enc/src/l_comp.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/l_comp.cpp
rename to media/module/codecs/amrnb/enc/src/l_comp.cpp
diff --git a/media/codecs/amrnb/enc/src/l_extract.cpp b/media/module/codecs/amrnb/enc/src/l_extract.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/l_extract.cpp
rename to media/module/codecs/amrnb/enc/src/l_extract.cpp
diff --git a/media/codecs/amrnb/enc/src/l_negate.cpp b/media/module/codecs/amrnb/enc/src/l_negate.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/l_negate.cpp
rename to media/module/codecs/amrnb/enc/src/l_negate.cpp
diff --git a/media/codecs/amrnb/enc/src/lag_wind.cpp b/media/module/codecs/amrnb/enc/src/lag_wind.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/lag_wind.cpp
rename to media/module/codecs/amrnb/enc/src/lag_wind.cpp
diff --git a/media/codecs/amrnb/enc/src/lag_wind.h b/media/module/codecs/amrnb/enc/src/lag_wind.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/lag_wind.h
rename to media/module/codecs/amrnb/enc/src/lag_wind.h
diff --git a/media/codecs/amrnb/enc/src/lag_wind_tab.cpp b/media/module/codecs/amrnb/enc/src/lag_wind_tab.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/lag_wind_tab.cpp
rename to media/module/codecs/amrnb/enc/src/lag_wind_tab.cpp
diff --git a/media/codecs/amrnb/enc/src/lag_wind_tab.h b/media/module/codecs/amrnb/enc/src/lag_wind_tab.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/lag_wind_tab.h
rename to media/module/codecs/amrnb/enc/src/lag_wind_tab.h
diff --git a/media/codecs/amrnb/enc/src/levinson.cpp b/media/module/codecs/amrnb/enc/src/levinson.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/levinson.cpp
rename to media/module/codecs/amrnb/enc/src/levinson.cpp
diff --git a/media/codecs/amrnb/enc/src/levinson.h b/media/module/codecs/amrnb/enc/src/levinson.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/levinson.h
rename to media/module/codecs/amrnb/enc/src/levinson.h
diff --git a/media/codecs/amrnb/enc/src/lpc.cpp b/media/module/codecs/amrnb/enc/src/lpc.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/lpc.cpp
rename to media/module/codecs/amrnb/enc/src/lpc.cpp
diff --git a/media/codecs/amrnb/enc/src/lpc.h b/media/module/codecs/amrnb/enc/src/lpc.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/lpc.h
rename to media/module/codecs/amrnb/enc/src/lpc.h
diff --git a/media/codecs/amrnb/enc/src/ol_ltp.cpp b/media/module/codecs/amrnb/enc/src/ol_ltp.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/ol_ltp.cpp
rename to media/module/codecs/amrnb/enc/src/ol_ltp.cpp
diff --git a/media/codecs/amrnb/enc/src/ol_ltp.h b/media/module/codecs/amrnb/enc/src/ol_ltp.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/ol_ltp.h
rename to media/module/codecs/amrnb/enc/src/ol_ltp.h
diff --git a/media/codecs/amrnb/enc/src/p_ol_wgh.cpp b/media/module/codecs/amrnb/enc/src/p_ol_wgh.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/p_ol_wgh.cpp
rename to media/module/codecs/amrnb/enc/src/p_ol_wgh.cpp
diff --git a/media/codecs/amrnb/enc/src/pitch_fr.cpp b/media/module/codecs/amrnb/enc/src/pitch_fr.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/pitch_fr.cpp
rename to media/module/codecs/amrnb/enc/src/pitch_fr.cpp
diff --git a/media/codecs/amrnb/enc/src/pitch_fr.h b/media/module/codecs/amrnb/enc/src/pitch_fr.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/pitch_fr.h
rename to media/module/codecs/amrnb/enc/src/pitch_fr.h
diff --git a/media/codecs/amrnb/enc/src/pitch_ol.cpp b/media/module/codecs/amrnb/enc/src/pitch_ol.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/pitch_ol.cpp
rename to media/module/codecs/amrnb/enc/src/pitch_ol.cpp
diff --git a/media/codecs/amrnb/enc/src/pitch_ol.h b/media/module/codecs/amrnb/enc/src/pitch_ol.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/pitch_ol.h
rename to media/module/codecs/amrnb/enc/src/pitch_ol.h
diff --git a/media/codecs/amrnb/enc/src/pre_big.cpp b/media/module/codecs/amrnb/enc/src/pre_big.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/pre_big.cpp
rename to media/module/codecs/amrnb/enc/src/pre_big.cpp
diff --git a/media/codecs/amrnb/enc/src/pre_big.h b/media/module/codecs/amrnb/enc/src/pre_big.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/pre_big.h
rename to media/module/codecs/amrnb/enc/src/pre_big.h
diff --git a/media/codecs/amrnb/enc/src/pre_proc.cpp b/media/module/codecs/amrnb/enc/src/pre_proc.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/pre_proc.cpp
rename to media/module/codecs/amrnb/enc/src/pre_proc.cpp
diff --git a/media/codecs/amrnb/enc/src/pre_proc.h b/media/module/codecs/amrnb/enc/src/pre_proc.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/pre_proc.h
rename to media/module/codecs/amrnb/enc/src/pre_proc.h
diff --git a/media/codecs/amrnb/enc/src/prm2bits.cpp b/media/module/codecs/amrnb/enc/src/prm2bits.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/prm2bits.cpp
rename to media/module/codecs/amrnb/enc/src/prm2bits.cpp
diff --git a/media/codecs/amrnb/enc/src/prm2bits.h b/media/module/codecs/amrnb/enc/src/prm2bits.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/prm2bits.h
rename to media/module/codecs/amrnb/enc/src/prm2bits.h
diff --git a/media/codecs/amrnb/enc/src/q_gain_c.cpp b/media/module/codecs/amrnb/enc/src/q_gain_c.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/q_gain_c.cpp
rename to media/module/codecs/amrnb/enc/src/q_gain_c.cpp
diff --git a/media/codecs/amrnb/enc/src/q_gain_c.h b/media/module/codecs/amrnb/enc/src/q_gain_c.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/q_gain_c.h
rename to media/module/codecs/amrnb/enc/src/q_gain_c.h
diff --git a/media/codecs/amrnb/enc/src/q_gain_p.cpp b/media/module/codecs/amrnb/enc/src/q_gain_p.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/q_gain_p.cpp
rename to media/module/codecs/amrnb/enc/src/q_gain_p.cpp
diff --git a/media/codecs/amrnb/enc/src/q_gain_p.h b/media/module/codecs/amrnb/enc/src/q_gain_p.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/q_gain_p.h
rename to media/module/codecs/amrnb/enc/src/q_gain_p.h
diff --git a/media/codecs/amrnb/enc/src/qgain475.cpp b/media/module/codecs/amrnb/enc/src/qgain475.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/qgain475.cpp
rename to media/module/codecs/amrnb/enc/src/qgain475.cpp
diff --git a/media/codecs/amrnb/enc/src/qgain475.h b/media/module/codecs/amrnb/enc/src/qgain475.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/qgain475.h
rename to media/module/codecs/amrnb/enc/src/qgain475.h
diff --git a/media/codecs/amrnb/enc/src/qgain795.cpp b/media/module/codecs/amrnb/enc/src/qgain795.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/qgain795.cpp
rename to media/module/codecs/amrnb/enc/src/qgain795.cpp
diff --git a/media/codecs/amrnb/enc/src/qgain795.h b/media/module/codecs/amrnb/enc/src/qgain795.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/qgain795.h
rename to media/module/codecs/amrnb/enc/src/qgain795.h
diff --git a/media/codecs/amrnb/enc/src/qua_gain.cpp b/media/module/codecs/amrnb/enc/src/qua_gain.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/qua_gain.cpp
rename to media/module/codecs/amrnb/enc/src/qua_gain.cpp
diff --git a/media/codecs/amrnb/enc/src/s10_8pf.cpp b/media/module/codecs/amrnb/enc/src/s10_8pf.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/s10_8pf.cpp
rename to media/module/codecs/amrnb/enc/src/s10_8pf.cpp
diff --git a/media/codecs/amrnb/enc/src/s10_8pf.h b/media/module/codecs/amrnb/enc/src/s10_8pf.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/s10_8pf.h
rename to media/module/codecs/amrnb/enc/src/s10_8pf.h
diff --git a/media/codecs/amrnb/enc/src/set_sign.cpp b/media/module/codecs/amrnb/enc/src/set_sign.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/set_sign.cpp
rename to media/module/codecs/amrnb/enc/src/set_sign.cpp
diff --git a/media/codecs/amrnb/enc/src/set_sign.h b/media/module/codecs/amrnb/enc/src/set_sign.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/set_sign.h
rename to media/module/codecs/amrnb/enc/src/set_sign.h
diff --git a/media/codecs/amrnb/enc/src/sid_sync.cpp b/media/module/codecs/amrnb/enc/src/sid_sync.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/sid_sync.cpp
rename to media/module/codecs/amrnb/enc/src/sid_sync.cpp
diff --git a/media/codecs/amrnb/enc/src/sid_sync.h b/media/module/codecs/amrnb/enc/src/sid_sync.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/sid_sync.h
rename to media/module/codecs/amrnb/enc/src/sid_sync.h
diff --git a/media/codecs/amrnb/enc/src/sp_enc.cpp b/media/module/codecs/amrnb/enc/src/sp_enc.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/sp_enc.cpp
rename to media/module/codecs/amrnb/enc/src/sp_enc.cpp
diff --git a/media/codecs/amrnb/enc/src/sp_enc.h b/media/module/codecs/amrnb/enc/src/sp_enc.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/sp_enc.h
rename to media/module/codecs/amrnb/enc/src/sp_enc.h
diff --git a/media/codecs/amrnb/enc/src/spreproc.cpp b/media/module/codecs/amrnb/enc/src/spreproc.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/spreproc.cpp
rename to media/module/codecs/amrnb/enc/src/spreproc.cpp
diff --git a/media/codecs/amrnb/enc/src/spreproc.h b/media/module/codecs/amrnb/enc/src/spreproc.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/spreproc.h
rename to media/module/codecs/amrnb/enc/src/spreproc.h
diff --git a/media/codecs/amrnb/enc/src/spstproc.cpp b/media/module/codecs/amrnb/enc/src/spstproc.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/spstproc.cpp
rename to media/module/codecs/amrnb/enc/src/spstproc.cpp
diff --git a/media/codecs/amrnb/enc/src/spstproc.h b/media/module/codecs/amrnb/enc/src/spstproc.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/spstproc.h
rename to media/module/codecs/amrnb/enc/src/spstproc.h
diff --git a/media/codecs/amrnb/enc/src/ton_stab.cpp b/media/module/codecs/amrnb/enc/src/ton_stab.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/src/ton_stab.cpp
rename to media/module/codecs/amrnb/enc/src/ton_stab.cpp
diff --git a/media/codecs/amrnb/enc/src/ton_stab.h b/media/module/codecs/amrnb/enc/src/ton_stab.h
similarity index 100%
rename from media/codecs/amrnb/enc/src/ton_stab.h
rename to media/module/codecs/amrnb/enc/src/ton_stab.h
diff --git a/media/codecs/amrnb/enc/test/AmrnbEncTestEnvironment.h b/media/module/codecs/amrnb/enc/test/AmrnbEncTestEnvironment.h
similarity index 100%
rename from media/codecs/amrnb/enc/test/AmrnbEncTestEnvironment.h
rename to media/module/codecs/amrnb/enc/test/AmrnbEncTestEnvironment.h
diff --git a/media/codecs/amrnb/enc/test/AmrnbEncoderTest.cpp b/media/module/codecs/amrnb/enc/test/AmrnbEncoderTest.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/test/AmrnbEncoderTest.cpp
rename to media/module/codecs/amrnb/enc/test/AmrnbEncoderTest.cpp
diff --git a/media/codecs/amrnb/enc/test/Android.bp b/media/module/codecs/amrnb/enc/test/Android.bp
similarity index 100%
rename from media/codecs/amrnb/enc/test/Android.bp
rename to media/module/codecs/amrnb/enc/test/Android.bp
diff --git a/media/codecs/amrnb/enc/test/AndroidTest.xml b/media/module/codecs/amrnb/enc/test/AndroidTest.xml
similarity index 100%
rename from media/codecs/amrnb/enc/test/AndroidTest.xml
rename to media/module/codecs/amrnb/enc/test/AndroidTest.xml
diff --git a/media/codecs/amrnb/enc/test/README.md b/media/module/codecs/amrnb/enc/test/README.md
similarity index 100%
rename from media/codecs/amrnb/enc/test/README.md
rename to media/module/codecs/amrnb/enc/test/README.md
diff --git a/media/codecs/amrnb/enc/test/amrnb_enc_test.cpp b/media/module/codecs/amrnb/enc/test/amrnb_enc_test.cpp
similarity index 100%
rename from media/codecs/amrnb/enc/test/amrnb_enc_test.cpp
rename to media/module/codecs/amrnb/enc/test/amrnb_enc_test.cpp
diff --git a/media/codecs/amrnb/fuzzer/Android.bp b/media/module/codecs/amrnb/fuzzer/Android.bp
similarity index 100%
rename from media/codecs/amrnb/fuzzer/Android.bp
rename to media/module/codecs/amrnb/fuzzer/Android.bp
diff --git a/media/codecs/amrnb/fuzzer/README.md b/media/module/codecs/amrnb/fuzzer/README.md
similarity index 100%
rename from media/codecs/amrnb/fuzzer/README.md
rename to media/module/codecs/amrnb/fuzzer/README.md
diff --git a/media/codecs/amrnb/fuzzer/amrnb_dec_fuzzer.cpp b/media/module/codecs/amrnb/fuzzer/amrnb_dec_fuzzer.cpp
similarity index 100%
rename from media/codecs/amrnb/fuzzer/amrnb_dec_fuzzer.cpp
rename to media/module/codecs/amrnb/fuzzer/amrnb_dec_fuzzer.cpp
diff --git a/media/codecs/amrnb/patent_disclaimer.txt b/media/module/codecs/amrnb/patent_disclaimer.txt
similarity index 100%
rename from media/codecs/amrnb/patent_disclaimer.txt
rename to media/module/codecs/amrnb/patent_disclaimer.txt
diff --git a/media/codecs/amrwb/dec/Android.bp b/media/module/codecs/amrwb/dec/Android.bp
similarity index 100%
rename from media/codecs/amrwb/dec/Android.bp
rename to media/module/codecs/amrwb/dec/Android.bp
diff --git a/media/codecs/amrwb/dec/MODULE_LICENSE_APACHE2 b/media/module/codecs/amrwb/dec/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/codecs/amrwb/dec/MODULE_LICENSE_APACHE2
rename to media/module/codecs/amrwb/dec/MODULE_LICENSE_APACHE2
diff --git a/media/codecs/amrwb/dec/NOTICE b/media/module/codecs/amrwb/dec/NOTICE
similarity index 100%
rename from media/codecs/amrwb/dec/NOTICE
rename to media/module/codecs/amrwb/dec/NOTICE
diff --git a/media/codecs/amrwb/dec/TEST_MAPPING b/media/module/codecs/amrwb/dec/TEST_MAPPING
similarity index 100%
rename from media/codecs/amrwb/dec/TEST_MAPPING
rename to media/module/codecs/amrwb/dec/TEST_MAPPING
diff --git a/media/codecs/amrwb/dec/fuzzer/Android.bp b/media/module/codecs/amrwb/dec/fuzzer/Android.bp
similarity index 100%
rename from media/codecs/amrwb/dec/fuzzer/Android.bp
rename to media/module/codecs/amrwb/dec/fuzzer/Android.bp
diff --git a/media/codecs/amrwb/dec/fuzzer/README.md b/media/module/codecs/amrwb/dec/fuzzer/README.md
similarity index 100%
rename from media/codecs/amrwb/dec/fuzzer/README.md
rename to media/module/codecs/amrwb/dec/fuzzer/README.md
diff --git a/media/codecs/amrwb/dec/fuzzer/amrwb_dec_fuzzer.cpp b/media/module/codecs/amrwb/dec/fuzzer/amrwb_dec_fuzzer.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/fuzzer/amrwb_dec_fuzzer.cpp
rename to media/module/codecs/amrwb/dec/fuzzer/amrwb_dec_fuzzer.cpp
diff --git a/media/codecs/amrwb/dec/include/pvamrwbdecoder_api.h b/media/module/codecs/amrwb/dec/include/pvamrwbdecoder_api.h
similarity index 100%
rename from media/codecs/amrwb/dec/include/pvamrwbdecoder_api.h
rename to media/module/codecs/amrwb/dec/include/pvamrwbdecoder_api.h
diff --git a/media/codecs/amrwb/dec/patent_disclaimer.txt b/media/module/codecs/amrwb/dec/patent_disclaimer.txt
similarity index 100%
rename from media/codecs/amrwb/dec/patent_disclaimer.txt
rename to media/module/codecs/amrwb/dec/patent_disclaimer.txt
diff --git a/media/codecs/amrwb/dec/src/agc2_amr_wb.cpp b/media/module/codecs/amrwb/dec/src/agc2_amr_wb.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/agc2_amr_wb.cpp
rename to media/module/codecs/amrwb/dec/src/agc2_amr_wb.cpp
diff --git a/media/codecs/amrwb/dec/src/band_pass_6k_7k.cpp b/media/module/codecs/amrwb/dec/src/band_pass_6k_7k.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/band_pass_6k_7k.cpp
rename to media/module/codecs/amrwb/dec/src/band_pass_6k_7k.cpp
diff --git a/media/codecs/amrwb/dec/src/dec_acelp_2p_in_64.cpp b/media/module/codecs/amrwb/dec/src/dec_acelp_2p_in_64.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/dec_acelp_2p_in_64.cpp
rename to media/module/codecs/amrwb/dec/src/dec_acelp_2p_in_64.cpp
diff --git a/media/codecs/amrwb/dec/src/dec_acelp_4p_in_64.cpp b/media/module/codecs/amrwb/dec/src/dec_acelp_4p_in_64.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/dec_acelp_4p_in_64.cpp
rename to media/module/codecs/amrwb/dec/src/dec_acelp_4p_in_64.cpp
diff --git a/media/codecs/amrwb/dec/src/dec_alg_codebook.cpp b/media/module/codecs/amrwb/dec/src/dec_alg_codebook.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/dec_alg_codebook.cpp
rename to media/module/codecs/amrwb/dec/src/dec_alg_codebook.cpp
diff --git a/media/codecs/amrwb/dec/src/dec_gain2_amr_wb.cpp b/media/module/codecs/amrwb/dec/src/dec_gain2_amr_wb.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/dec_gain2_amr_wb.cpp
rename to media/module/codecs/amrwb/dec/src/dec_gain2_amr_wb.cpp
diff --git a/media/codecs/amrwb/dec/src/deemphasis_32.cpp b/media/module/codecs/amrwb/dec/src/deemphasis_32.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/deemphasis_32.cpp
rename to media/module/codecs/amrwb/dec/src/deemphasis_32.cpp
diff --git a/media/codecs/amrwb/dec/src/dtx.h b/media/module/codecs/amrwb/dec/src/dtx.h
similarity index 100%
rename from media/codecs/amrwb/dec/src/dtx.h
rename to media/module/codecs/amrwb/dec/src/dtx.h
diff --git a/media/codecs/amrwb/dec/src/dtx_decoder_amr_wb.cpp b/media/module/codecs/amrwb/dec/src/dtx_decoder_amr_wb.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/dtx_decoder_amr_wb.cpp
rename to media/module/codecs/amrwb/dec/src/dtx_decoder_amr_wb.cpp
diff --git a/media/codecs/amrwb/dec/src/e_pv_amrwbdec.h b/media/module/codecs/amrwb/dec/src/e_pv_amrwbdec.h
similarity index 100%
rename from media/codecs/amrwb/dec/src/e_pv_amrwbdec.h
rename to media/module/codecs/amrwb/dec/src/e_pv_amrwbdec.h
diff --git a/media/codecs/amrwb/dec/src/get_amr_wb_bits.cpp b/media/module/codecs/amrwb/dec/src/get_amr_wb_bits.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/get_amr_wb_bits.cpp
rename to media/module/codecs/amrwb/dec/src/get_amr_wb_bits.cpp
diff --git a/media/codecs/amrwb/dec/src/get_amr_wb_bits.h b/media/module/codecs/amrwb/dec/src/get_amr_wb_bits.h
similarity index 100%
rename from media/codecs/amrwb/dec/src/get_amr_wb_bits.h
rename to media/module/codecs/amrwb/dec/src/get_amr_wb_bits.h
diff --git a/media/codecs/amrwb/dec/src/highpass_400hz_at_12k8.cpp b/media/module/codecs/amrwb/dec/src/highpass_400hz_at_12k8.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/highpass_400hz_at_12k8.cpp
rename to media/module/codecs/amrwb/dec/src/highpass_400hz_at_12k8.cpp
diff --git a/media/codecs/amrwb/dec/src/highpass_50hz_at_12k8.cpp b/media/module/codecs/amrwb/dec/src/highpass_50hz_at_12k8.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/highpass_50hz_at_12k8.cpp
rename to media/module/codecs/amrwb/dec/src/highpass_50hz_at_12k8.cpp
diff --git a/media/codecs/amrwb/dec/src/homing_amr_wb_dec.cpp b/media/module/codecs/amrwb/dec/src/homing_amr_wb_dec.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/homing_amr_wb_dec.cpp
rename to media/module/codecs/amrwb/dec/src/homing_amr_wb_dec.cpp
diff --git a/media/codecs/amrwb/dec/src/interpolate_isp.cpp b/media/module/codecs/amrwb/dec/src/interpolate_isp.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/interpolate_isp.cpp
rename to media/module/codecs/amrwb/dec/src/interpolate_isp.cpp
diff --git a/media/codecs/amrwb/dec/src/isf_extrapolation.cpp b/media/module/codecs/amrwb/dec/src/isf_extrapolation.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/isf_extrapolation.cpp
rename to media/module/codecs/amrwb/dec/src/isf_extrapolation.cpp
diff --git a/media/codecs/amrwb/dec/src/isp_az.cpp b/media/module/codecs/amrwb/dec/src/isp_az.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/isp_az.cpp
rename to media/module/codecs/amrwb/dec/src/isp_az.cpp
diff --git a/media/codecs/amrwb/dec/src/isp_isf.cpp b/media/module/codecs/amrwb/dec/src/isp_isf.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/isp_isf.cpp
rename to media/module/codecs/amrwb/dec/src/isp_isf.cpp
diff --git a/media/codecs/amrwb/dec/src/lagconceal.cpp b/media/module/codecs/amrwb/dec/src/lagconceal.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/lagconceal.cpp
rename to media/module/codecs/amrwb/dec/src/lagconceal.cpp
diff --git a/media/codecs/amrwb/dec/src/low_pass_filt_7k.cpp b/media/module/codecs/amrwb/dec/src/low_pass_filt_7k.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/low_pass_filt_7k.cpp
rename to media/module/codecs/amrwb/dec/src/low_pass_filt_7k.cpp
diff --git a/media/codecs/amrwb/dec/src/median5.cpp b/media/module/codecs/amrwb/dec/src/median5.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/median5.cpp
rename to media/module/codecs/amrwb/dec/src/median5.cpp
diff --git a/media/codecs/amrwb/dec/src/mime_io.cpp b/media/module/codecs/amrwb/dec/src/mime_io.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/mime_io.cpp
rename to media/module/codecs/amrwb/dec/src/mime_io.cpp
diff --git a/media/codecs/amrwb/dec/src/mime_io.h b/media/module/codecs/amrwb/dec/src/mime_io.h
similarity index 100%
rename from media/codecs/amrwb/dec/src/mime_io.h
rename to media/module/codecs/amrwb/dec/src/mime_io.h
diff --git a/media/codecs/amrwb/dec/src/noise_gen_amrwb.cpp b/media/module/codecs/amrwb/dec/src/noise_gen_amrwb.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/noise_gen_amrwb.cpp
rename to media/module/codecs/amrwb/dec/src/noise_gen_amrwb.cpp
diff --git a/media/codecs/amrwb/dec/src/normalize_amr_wb.cpp b/media/module/codecs/amrwb/dec/src/normalize_amr_wb.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/normalize_amr_wb.cpp
rename to media/module/codecs/amrwb/dec/src/normalize_amr_wb.cpp
diff --git a/media/codecs/amrwb/dec/src/normalize_amr_wb.h b/media/module/codecs/amrwb/dec/src/normalize_amr_wb.h
similarity index 100%
rename from media/codecs/amrwb/dec/src/normalize_amr_wb.h
rename to media/module/codecs/amrwb/dec/src/normalize_amr_wb.h
diff --git a/media/codecs/amrwb/dec/src/oversamp_12k8_to_16k.cpp b/media/module/codecs/amrwb/dec/src/oversamp_12k8_to_16k.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/oversamp_12k8_to_16k.cpp
rename to media/module/codecs/amrwb/dec/src/oversamp_12k8_to_16k.cpp
diff --git a/media/codecs/amrwb/dec/src/phase_dispersion.cpp b/media/module/codecs/amrwb/dec/src/phase_dispersion.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/phase_dispersion.cpp
rename to media/module/codecs/amrwb/dec/src/phase_dispersion.cpp
diff --git a/media/codecs/amrwb/dec/src/pit_shrp.cpp b/media/module/codecs/amrwb/dec/src/pit_shrp.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/pit_shrp.cpp
rename to media/module/codecs/amrwb/dec/src/pit_shrp.cpp
diff --git a/media/codecs/amrwb/dec/src/pred_lt4.cpp b/media/module/codecs/amrwb/dec/src/pred_lt4.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/pred_lt4.cpp
rename to media/module/codecs/amrwb/dec/src/pred_lt4.cpp
diff --git a/media/codecs/amrwb/dec/src/preemph_amrwb_dec.cpp b/media/module/codecs/amrwb/dec/src/preemph_amrwb_dec.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/preemph_amrwb_dec.cpp
rename to media/module/codecs/amrwb/dec/src/preemph_amrwb_dec.cpp
diff --git a/media/codecs/amrwb/dec/src/pv_amr_wb_type_defs.h b/media/module/codecs/amrwb/dec/src/pv_amr_wb_type_defs.h
similarity index 100%
rename from media/codecs/amrwb/dec/src/pv_amr_wb_type_defs.h
rename to media/module/codecs/amrwb/dec/src/pv_amr_wb_type_defs.h
diff --git a/media/codecs/amrwb/dec/src/pvamrwb_math_op.cpp b/media/module/codecs/amrwb/dec/src/pvamrwb_math_op.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/pvamrwb_math_op.cpp
rename to media/module/codecs/amrwb/dec/src/pvamrwb_math_op.cpp
diff --git a/media/codecs/amrwb/dec/src/pvamrwb_math_op.h b/media/module/codecs/amrwb/dec/src/pvamrwb_math_op.h
similarity index 100%
rename from media/codecs/amrwb/dec/src/pvamrwb_math_op.h
rename to media/module/codecs/amrwb/dec/src/pvamrwb_math_op.h
diff --git a/media/codecs/amrwb/dec/src/pvamrwbdecoder.cpp b/media/module/codecs/amrwb/dec/src/pvamrwbdecoder.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/pvamrwbdecoder.cpp
rename to media/module/codecs/amrwb/dec/src/pvamrwbdecoder.cpp
diff --git a/media/codecs/amrwb/dec/src/pvamrwbdecoder.h b/media/module/codecs/amrwb/dec/src/pvamrwbdecoder.h
similarity index 100%
rename from media/codecs/amrwb/dec/src/pvamrwbdecoder.h
rename to media/module/codecs/amrwb/dec/src/pvamrwbdecoder.h
diff --git a/media/codecs/amrwb/dec/src/pvamrwbdecoder_acelp.h b/media/module/codecs/amrwb/dec/src/pvamrwbdecoder_acelp.h
similarity index 100%
rename from media/codecs/amrwb/dec/src/pvamrwbdecoder_acelp.h
rename to media/module/codecs/amrwb/dec/src/pvamrwbdecoder_acelp.h
diff --git a/media/codecs/amrwb/dec/src/pvamrwbdecoder_basic_op.h b/media/module/codecs/amrwb/dec/src/pvamrwbdecoder_basic_op.h
similarity index 100%
rename from media/codecs/amrwb/dec/src/pvamrwbdecoder_basic_op.h
rename to media/module/codecs/amrwb/dec/src/pvamrwbdecoder_basic_op.h
diff --git a/media/codecs/amrwb/dec/src/pvamrwbdecoder_basic_op_armv5.h b/media/module/codecs/amrwb/dec/src/pvamrwbdecoder_basic_op_armv5.h
similarity index 100%
rename from media/codecs/amrwb/dec/src/pvamrwbdecoder_basic_op_armv5.h
rename to media/module/codecs/amrwb/dec/src/pvamrwbdecoder_basic_op_armv5.h
diff --git a/media/codecs/amrwb/dec/src/pvamrwbdecoder_basic_op_cequivalent.h b/media/module/codecs/amrwb/dec/src/pvamrwbdecoder_basic_op_cequivalent.h
similarity index 100%
rename from media/codecs/amrwb/dec/src/pvamrwbdecoder_basic_op_cequivalent.h
rename to media/module/codecs/amrwb/dec/src/pvamrwbdecoder_basic_op_cequivalent.h
diff --git a/media/codecs/amrwb/dec/src/pvamrwbdecoder_basic_op_gcc_armv5.h b/media/module/codecs/amrwb/dec/src/pvamrwbdecoder_basic_op_gcc_armv5.h
similarity index 100%
rename from media/codecs/amrwb/dec/src/pvamrwbdecoder_basic_op_gcc_armv5.h
rename to media/module/codecs/amrwb/dec/src/pvamrwbdecoder_basic_op_gcc_armv5.h
diff --git a/media/codecs/amrwb/dec/src/pvamrwbdecoder_cnst.h b/media/module/codecs/amrwb/dec/src/pvamrwbdecoder_cnst.h
similarity index 100%
rename from media/codecs/amrwb/dec/src/pvamrwbdecoder_cnst.h
rename to media/module/codecs/amrwb/dec/src/pvamrwbdecoder_cnst.h
diff --git a/media/codecs/amrwb/dec/src/pvamrwbdecoder_mem_funcs.h b/media/module/codecs/amrwb/dec/src/pvamrwbdecoder_mem_funcs.h
similarity index 100%
rename from media/codecs/amrwb/dec/src/pvamrwbdecoder_mem_funcs.h
rename to media/module/codecs/amrwb/dec/src/pvamrwbdecoder_mem_funcs.h
diff --git a/media/codecs/amrwb/dec/src/q_gain2_tab.cpp b/media/module/codecs/amrwb/dec/src/q_gain2_tab.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/q_gain2_tab.cpp
rename to media/module/codecs/amrwb/dec/src/q_gain2_tab.cpp
diff --git a/media/codecs/amrwb/dec/src/q_pulse.h b/media/module/codecs/amrwb/dec/src/q_pulse.h
similarity index 100%
rename from media/codecs/amrwb/dec/src/q_pulse.h
rename to media/module/codecs/amrwb/dec/src/q_pulse.h
diff --git a/media/codecs/amrwb/dec/src/qisf_ns.cpp b/media/module/codecs/amrwb/dec/src/qisf_ns.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/qisf_ns.cpp
rename to media/module/codecs/amrwb/dec/src/qisf_ns.cpp
diff --git a/media/codecs/amrwb/dec/src/qisf_ns.h b/media/module/codecs/amrwb/dec/src/qisf_ns.h
similarity index 100%
rename from media/codecs/amrwb/dec/src/qisf_ns.h
rename to media/module/codecs/amrwb/dec/src/qisf_ns.h
diff --git a/media/codecs/amrwb/dec/src/qisf_ns_tab.cpp b/media/module/codecs/amrwb/dec/src/qisf_ns_tab.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/qisf_ns_tab.cpp
rename to media/module/codecs/amrwb/dec/src/qisf_ns_tab.cpp
diff --git a/media/codecs/amrwb/dec/src/qpisf_2s.cpp b/media/module/codecs/amrwb/dec/src/qpisf_2s.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/qpisf_2s.cpp
rename to media/module/codecs/amrwb/dec/src/qpisf_2s.cpp
diff --git a/media/codecs/amrwb/dec/src/qpisf_2s.h b/media/module/codecs/amrwb/dec/src/qpisf_2s.h
similarity index 100%
rename from media/codecs/amrwb/dec/src/qpisf_2s.h
rename to media/module/codecs/amrwb/dec/src/qpisf_2s.h
diff --git a/media/codecs/amrwb/dec/src/qpisf_2s_tab.cpp b/media/module/codecs/amrwb/dec/src/qpisf_2s_tab.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/qpisf_2s_tab.cpp
rename to media/module/codecs/amrwb/dec/src/qpisf_2s_tab.cpp
diff --git a/media/codecs/amrwb/dec/src/scale_signal.cpp b/media/module/codecs/amrwb/dec/src/scale_signal.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/scale_signal.cpp
rename to media/module/codecs/amrwb/dec/src/scale_signal.cpp
diff --git a/media/codecs/amrwb/dec/src/synthesis_amr_wb.cpp b/media/module/codecs/amrwb/dec/src/synthesis_amr_wb.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/synthesis_amr_wb.cpp
rename to media/module/codecs/amrwb/dec/src/synthesis_amr_wb.cpp
diff --git a/media/codecs/amrwb/dec/src/synthesis_amr_wb.h b/media/module/codecs/amrwb/dec/src/synthesis_amr_wb.h
similarity index 100%
rename from media/codecs/amrwb/dec/src/synthesis_amr_wb.h
rename to media/module/codecs/amrwb/dec/src/synthesis_amr_wb.h
diff --git a/media/codecs/amrwb/dec/src/voice_factor.cpp b/media/module/codecs/amrwb/dec/src/voice_factor.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/voice_factor.cpp
rename to media/module/codecs/amrwb/dec/src/voice_factor.cpp
diff --git a/media/codecs/amrwb/dec/src/wb_syn_filt.cpp b/media/module/codecs/amrwb/dec/src/wb_syn_filt.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/wb_syn_filt.cpp
rename to media/module/codecs/amrwb/dec/src/wb_syn_filt.cpp
diff --git a/media/codecs/amrwb/dec/src/weight_amrwb_lpc.cpp b/media/module/codecs/amrwb/dec/src/weight_amrwb_lpc.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/src/weight_amrwb_lpc.cpp
rename to media/module/codecs/amrwb/dec/src/weight_amrwb_lpc.cpp
diff --git a/media/codecs/amrwb/dec/test/AmrwbDecTestEnvironment.h b/media/module/codecs/amrwb/dec/test/AmrwbDecTestEnvironment.h
similarity index 100%
rename from media/codecs/amrwb/dec/test/AmrwbDecTestEnvironment.h
rename to media/module/codecs/amrwb/dec/test/AmrwbDecTestEnvironment.h
diff --git a/media/codecs/amrwb/dec/test/AmrwbDecoderTest.cpp b/media/module/codecs/amrwb/dec/test/AmrwbDecoderTest.cpp
similarity index 89%
rename from media/codecs/amrwb/dec/test/AmrwbDecoderTest.cpp
rename to media/module/codecs/amrwb/dec/test/AmrwbDecoderTest.cpp
index 7221b92..2cc88ce 100644
--- a/media/codecs/amrwb/dec/test/AmrwbDecoderTest.cpp
+++ b/media/module/codecs/amrwb/dec/test/AmrwbDecoderTest.cpp
@@ -21,6 +21,7 @@
#include <utils/Log.h>
#include <audio_utils/sndfile.h>
+#include <memory>
#include <stdio.h>
#include "pvamrwbdecoder.h"
@@ -121,7 +122,7 @@
TEST_F(AmrwbDecoderTest, MultiCreateAmrwbDecoderTest) {
uint32_t memRequirements = pvDecoder_AmrWbMemRequirements();
- void *decoderBuf = malloc(memRequirements);
+ std::unique_ptr<char[]> decoderBuf(new char[memRequirements]);
ASSERT_NE(decoderBuf, nullptr)
<< "Failed to allocate decoder memory of size " << memRequirements;
@@ -129,25 +130,21 @@
void *amrHandle = nullptr;
int16_t *decoderCookie;
for (int count = 0; count < kMaxCount; count++) {
- pvDecoder_AmrWb_Init(&amrHandle, decoderBuf, &decoderCookie);
+ pvDecoder_AmrWb_Init(&amrHandle, decoderBuf.get(), &decoderCookie);
ASSERT_NE(amrHandle, nullptr) << "Failed to initialize decoder";
ALOGV("Decoder created successfully");
}
- if (decoderBuf) {
- free(decoderBuf);
- decoderBuf = nullptr;
- }
}
TEST_P(AmrwbDecoderTest, DecodeTest) {
uint32_t memRequirements = pvDecoder_AmrWbMemRequirements();
- void *decoderBuf = malloc(memRequirements);
+ std::unique_ptr<char[]> decoderBuf(new char[memRequirements]);
ASSERT_NE(decoderBuf, nullptr)
<< "Failed to allocate decoder memory of size " << memRequirements;
void *amrHandle = nullptr;
int16_t *decoderCookie;
- pvDecoder_AmrWb_Init(&amrHandle, decoderBuf, &decoderCookie);
+ pvDecoder_AmrWb_Init(&amrHandle, decoderBuf.get(), &decoderCookie);
ASSERT_NE(amrHandle, nullptr) << "Failed to initialize decoder";
string inputFile = gEnv->getRes() + GetParam();
@@ -159,25 +156,21 @@
SNDFILE *outFileHandle = openOutputFile(&sfInfo);
ASSERT_NE(outFileHandle, nullptr) << "Error opening output file for writing decoded output";
- int32_t decoderErr = DecodeFrames(decoderCookie, decoderBuf, outFileHandle);
+ int32_t decoderErr = DecodeFrames(decoderCookie, decoderBuf.get(), outFileHandle);
ASSERT_EQ(decoderErr, 0) << "DecodeFrames returned error";
sf_close(outFileHandle);
- if (decoderBuf) {
- free(decoderBuf);
- decoderBuf = nullptr;
- }
}
TEST_P(AmrwbDecoderTest, ResetDecoderTest) {
uint32_t memRequirements = pvDecoder_AmrWbMemRequirements();
- void *decoderBuf = malloc(memRequirements);
+ std::unique_ptr<char[]> decoderBuf(new char[memRequirements]);
ASSERT_NE(decoderBuf, nullptr)
<< "Failed to allocate decoder memory of size " << memRequirements;
void *amrHandle = nullptr;
int16_t *decoderCookie;
- pvDecoder_AmrWb_Init(&amrHandle, decoderBuf, &decoderCookie);
+ pvDecoder_AmrWb_Init(&amrHandle, decoderBuf.get(), &decoderCookie);
ASSERT_NE(amrHandle, nullptr) << "Failed to initialize decoder";
string inputFile = gEnv->getRes() + GetParam();
@@ -190,20 +183,18 @@
ASSERT_NE(outFileHandle, nullptr) << "Error opening output file for writing decoded output";
// Decode 150 frames first
- int32_t decoderErr = DecodeFrames(decoderCookie, decoderBuf, outFileHandle, kNumFrameReset);
+ int32_t decoderErr =
+ DecodeFrames(decoderCookie, decoderBuf.get(), outFileHandle, kNumFrameReset);
ASSERT_EQ(decoderErr, 0) << "DecodeFrames returned error";
// Reset Decoder
- pvDecoder_AmrWb_Reset(decoderBuf, 1);
+ pvDecoder_AmrWb_Reset(decoderBuf.get(), 1);
// Start decoding again
- decoderErr = DecodeFrames(decoderCookie, decoderBuf, outFileHandle);
+ decoderErr = DecodeFrames(decoderCookie, decoderBuf.get(), outFileHandle);
ASSERT_EQ(decoderErr, 0) << "DecodeFrames returned error";
sf_close(outFileHandle);
- if (decoderBuf) {
- free(decoderBuf);
- }
}
INSTANTIATE_TEST_SUITE_P(AmrwbDecoderTestAll, AmrwbDecoderTest,
diff --git a/media/codecs/amrwb/dec/test/Android.bp b/media/module/codecs/amrwb/dec/test/Android.bp
similarity index 100%
rename from media/codecs/amrwb/dec/test/Android.bp
rename to media/module/codecs/amrwb/dec/test/Android.bp
diff --git a/media/codecs/amrwb/dec/test/AndroidTest.xml b/media/module/codecs/amrwb/dec/test/AndroidTest.xml
similarity index 100%
rename from media/codecs/amrwb/dec/test/AndroidTest.xml
rename to media/module/codecs/amrwb/dec/test/AndroidTest.xml
diff --git a/media/codecs/amrwb/dec/test/README.md b/media/module/codecs/amrwb/dec/test/README.md
similarity index 100%
rename from media/codecs/amrwb/dec/test/README.md
rename to media/module/codecs/amrwb/dec/test/README.md
diff --git a/media/codecs/amrwb/dec/test/amrwbdec_test.cpp b/media/module/codecs/amrwb/dec/test/amrwbdec_test.cpp
similarity index 100%
rename from media/codecs/amrwb/dec/test/amrwbdec_test.cpp
rename to media/module/codecs/amrwb/dec/test/amrwbdec_test.cpp
diff --git a/media/codecs/amrwb/enc/Android.bp b/media/module/codecs/amrwb/enc/Android.bp
similarity index 100%
rename from media/codecs/amrwb/enc/Android.bp
rename to media/module/codecs/amrwb/enc/Android.bp
diff --git a/media/codecs/amrwb/enc/MODULE_LICENSE_APACHE2 b/media/module/codecs/amrwb/enc/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/codecs/amrwb/enc/MODULE_LICENSE_APACHE2
rename to media/module/codecs/amrwb/enc/MODULE_LICENSE_APACHE2
diff --git a/media/codecs/amrwb/enc/NOTICE b/media/module/codecs/amrwb/enc/NOTICE
similarity index 100%
rename from media/codecs/amrwb/enc/NOTICE
rename to media/module/codecs/amrwb/enc/NOTICE
diff --git a/media/codecs/amrwb/enc/SampleCode/AMRWB_E_SAMPLE.c b/media/module/codecs/amrwb/enc/SampleCode/AMRWB_E_SAMPLE.c
similarity index 100%
rename from media/codecs/amrwb/enc/SampleCode/AMRWB_E_SAMPLE.c
rename to media/module/codecs/amrwb/enc/SampleCode/AMRWB_E_SAMPLE.c
diff --git a/media/codecs/amrwb/enc/SampleCode/Android.bp b/media/module/codecs/amrwb/enc/SampleCode/Android.bp
similarity index 100%
rename from media/codecs/amrwb/enc/SampleCode/Android.bp
rename to media/module/codecs/amrwb/enc/SampleCode/Android.bp
diff --git a/media/codecs/amrwb/enc/SampleCode/MODULE_LICENSE_APACHE2 b/media/module/codecs/amrwb/enc/SampleCode/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/codecs/amrwb/enc/SampleCode/MODULE_LICENSE_APACHE2
rename to media/module/codecs/amrwb/enc/SampleCode/MODULE_LICENSE_APACHE2
diff --git a/media/codecs/amrwb/enc/SampleCode/NOTICE b/media/module/codecs/amrwb/enc/SampleCode/NOTICE
similarity index 100%
rename from media/codecs/amrwb/enc/SampleCode/NOTICE
rename to media/module/codecs/amrwb/enc/SampleCode/NOTICE
diff --git a/media/codecs/amrwb/enc/TEST_MAPPING b/media/module/codecs/amrwb/enc/TEST_MAPPING
similarity index 100%
rename from media/codecs/amrwb/enc/TEST_MAPPING
rename to media/module/codecs/amrwb/enc/TEST_MAPPING
diff --git a/media/codecs/amrwb/enc/doc/voAMRWBEncoderSDK.pdf b/media/module/codecs/amrwb/enc/doc/voAMRWBEncoderSDK.pdf
similarity index 100%
rename from media/codecs/amrwb/enc/doc/voAMRWBEncoderSDK.pdf
rename to media/module/codecs/amrwb/enc/doc/voAMRWBEncoderSDK.pdf
Binary files differ
diff --git a/media/codecs/amrwb/enc/fuzzer/Android.bp b/media/module/codecs/amrwb/enc/fuzzer/Android.bp
similarity index 100%
rename from media/codecs/amrwb/enc/fuzzer/Android.bp
rename to media/module/codecs/amrwb/enc/fuzzer/Android.bp
diff --git a/media/codecs/amrwb/enc/fuzzer/README.md b/media/module/codecs/amrwb/enc/fuzzer/README.md
similarity index 100%
rename from media/codecs/amrwb/enc/fuzzer/README.md
rename to media/module/codecs/amrwb/enc/fuzzer/README.md
diff --git a/media/codecs/amrwb/enc/fuzzer/amrwb_enc_fuzzer.cpp b/media/module/codecs/amrwb/enc/fuzzer/amrwb_enc_fuzzer.cpp
similarity index 100%
rename from media/codecs/amrwb/enc/fuzzer/amrwb_enc_fuzzer.cpp
rename to media/module/codecs/amrwb/enc/fuzzer/amrwb_enc_fuzzer.cpp
diff --git a/media/codecs/amrwb/enc/inc/acelp.h b/media/module/codecs/amrwb/enc/inc/acelp.h
similarity index 100%
rename from media/codecs/amrwb/enc/inc/acelp.h
rename to media/module/codecs/amrwb/enc/inc/acelp.h
diff --git a/media/codecs/amrwb/enc/inc/basic_op.h b/media/module/codecs/amrwb/enc/inc/basic_op.h
similarity index 100%
rename from media/codecs/amrwb/enc/inc/basic_op.h
rename to media/module/codecs/amrwb/enc/inc/basic_op.h
diff --git a/media/codecs/amrwb/enc/inc/bits.h b/media/module/codecs/amrwb/enc/inc/bits.h
similarity index 100%
rename from media/codecs/amrwb/enc/inc/bits.h
rename to media/module/codecs/amrwb/enc/inc/bits.h
diff --git a/media/codecs/amrwb/enc/inc/cnst.h b/media/module/codecs/amrwb/enc/inc/cnst.h
similarity index 100%
rename from media/codecs/amrwb/enc/inc/cnst.h
rename to media/module/codecs/amrwb/enc/inc/cnst.h
diff --git a/media/codecs/amrwb/enc/inc/cod_main.h b/media/module/codecs/amrwb/enc/inc/cod_main.h
similarity index 100%
rename from media/codecs/amrwb/enc/inc/cod_main.h
rename to media/module/codecs/amrwb/enc/inc/cod_main.h
diff --git a/media/codecs/amrwb/enc/inc/dtx.h b/media/module/codecs/amrwb/enc/inc/dtx.h
similarity index 100%
rename from media/codecs/amrwb/enc/inc/dtx.h
rename to media/module/codecs/amrwb/enc/inc/dtx.h
diff --git a/media/codecs/amrwb/enc/inc/grid100.tab b/media/module/codecs/amrwb/enc/inc/grid100.tab
similarity index 100%
rename from media/codecs/amrwb/enc/inc/grid100.tab
rename to media/module/codecs/amrwb/enc/inc/grid100.tab
diff --git a/media/codecs/amrwb/enc/inc/ham_wind.tab b/media/module/codecs/amrwb/enc/inc/ham_wind.tab
similarity index 100%
rename from media/codecs/amrwb/enc/inc/ham_wind.tab
rename to media/module/codecs/amrwb/enc/inc/ham_wind.tab
diff --git a/media/codecs/amrwb/enc/inc/homing.tab b/media/module/codecs/amrwb/enc/inc/homing.tab
similarity index 100%
rename from media/codecs/amrwb/enc/inc/homing.tab
rename to media/module/codecs/amrwb/enc/inc/homing.tab
diff --git a/media/codecs/amrwb/enc/inc/isp_isf.tab b/media/module/codecs/amrwb/enc/inc/isp_isf.tab
similarity index 100%
rename from media/codecs/amrwb/enc/inc/isp_isf.tab
rename to media/module/codecs/amrwb/enc/inc/isp_isf.tab
diff --git a/media/codecs/amrwb/enc/inc/lag_wind.tab b/media/module/codecs/amrwb/enc/inc/lag_wind.tab
similarity index 100%
rename from media/codecs/amrwb/enc/inc/lag_wind.tab
rename to media/module/codecs/amrwb/enc/inc/lag_wind.tab
diff --git a/media/codecs/amrwb/enc/inc/log2.h b/media/module/codecs/amrwb/enc/inc/log2.h
similarity index 100%
rename from media/codecs/amrwb/enc/inc/log2.h
rename to media/module/codecs/amrwb/enc/inc/log2.h
diff --git a/media/codecs/amrwb/enc/inc/log2_tab.h b/media/module/codecs/amrwb/enc/inc/log2_tab.h
similarity index 100%
rename from media/codecs/amrwb/enc/inc/log2_tab.h
rename to media/module/codecs/amrwb/enc/inc/log2_tab.h
diff --git a/media/codecs/amrwb/enc/inc/main.h b/media/module/codecs/amrwb/enc/inc/main.h
similarity index 100%
rename from media/codecs/amrwb/enc/inc/main.h
rename to media/module/codecs/amrwb/enc/inc/main.h
diff --git a/media/codecs/amrwb/enc/inc/math_op.h b/media/module/codecs/amrwb/enc/inc/math_op.h
similarity index 100%
rename from media/codecs/amrwb/enc/inc/math_op.h
rename to media/module/codecs/amrwb/enc/inc/math_op.h
diff --git a/media/codecs/amrwb/enc/inc/mem_align.h b/media/module/codecs/amrwb/enc/inc/mem_align.h
similarity index 100%
rename from media/codecs/amrwb/enc/inc/mem_align.h
rename to media/module/codecs/amrwb/enc/inc/mem_align.h
diff --git a/media/codecs/amrwb/enc/inc/mime_io.tab b/media/module/codecs/amrwb/enc/inc/mime_io.tab
similarity index 100%
rename from media/codecs/amrwb/enc/inc/mime_io.tab
rename to media/module/codecs/amrwb/enc/inc/mime_io.tab
diff --git a/media/codecs/amrwb/enc/inc/oper_32b.h b/media/module/codecs/amrwb/enc/inc/oper_32b.h
similarity index 100%
rename from media/codecs/amrwb/enc/inc/oper_32b.h
rename to media/module/codecs/amrwb/enc/inc/oper_32b.h
diff --git a/media/codecs/amrwb/enc/inc/p_med_o.h b/media/module/codecs/amrwb/enc/inc/p_med_o.h
similarity index 100%
rename from media/codecs/amrwb/enc/inc/p_med_o.h
rename to media/module/codecs/amrwb/enc/inc/p_med_o.h
diff --git a/media/codecs/amrwb/enc/inc/p_med_ol.tab b/media/module/codecs/amrwb/enc/inc/p_med_ol.tab
similarity index 100%
rename from media/codecs/amrwb/enc/inc/p_med_ol.tab
rename to media/module/codecs/amrwb/enc/inc/p_med_ol.tab
diff --git a/media/codecs/amrwb/enc/inc/q_gain2.tab b/media/module/codecs/amrwb/enc/inc/q_gain2.tab
similarity index 100%
rename from media/codecs/amrwb/enc/inc/q_gain2.tab
rename to media/module/codecs/amrwb/enc/inc/q_gain2.tab
diff --git a/media/codecs/amrwb/enc/inc/q_pulse.h b/media/module/codecs/amrwb/enc/inc/q_pulse.h
similarity index 100%
rename from media/codecs/amrwb/enc/inc/q_pulse.h
rename to media/module/codecs/amrwb/enc/inc/q_pulse.h
diff --git a/media/codecs/amrwb/enc/inc/qisf_ns.tab b/media/module/codecs/amrwb/enc/inc/qisf_ns.tab
similarity index 100%
rename from media/codecs/amrwb/enc/inc/qisf_ns.tab
rename to media/module/codecs/amrwb/enc/inc/qisf_ns.tab
diff --git a/media/codecs/amrwb/enc/inc/qpisf_2s.tab b/media/module/codecs/amrwb/enc/inc/qpisf_2s.tab
similarity index 100%
rename from media/codecs/amrwb/enc/inc/qpisf_2s.tab
rename to media/module/codecs/amrwb/enc/inc/qpisf_2s.tab
diff --git a/media/codecs/amrwb/enc/inc/stream.h b/media/module/codecs/amrwb/enc/inc/stream.h
similarity index 100%
rename from media/codecs/amrwb/enc/inc/stream.h
rename to media/module/codecs/amrwb/enc/inc/stream.h
diff --git a/media/codecs/amrwb/enc/inc/typedef.h b/media/module/codecs/amrwb/enc/inc/typedef.h
similarity index 100%
rename from media/codecs/amrwb/enc/inc/typedef.h
rename to media/module/codecs/amrwb/enc/inc/typedef.h
diff --git a/media/codecs/amrwb/enc/inc/typedefs.h b/media/module/codecs/amrwb/enc/inc/typedefs.h
similarity index 100%
rename from media/codecs/amrwb/enc/inc/typedefs.h
rename to media/module/codecs/amrwb/enc/inc/typedefs.h
diff --git a/media/codecs/amrwb/enc/inc/wb_vad.h b/media/module/codecs/amrwb/enc/inc/wb_vad.h
similarity index 100%
rename from media/codecs/amrwb/enc/inc/wb_vad.h
rename to media/module/codecs/amrwb/enc/inc/wb_vad.h
diff --git a/media/codecs/amrwb/enc/inc/wb_vad_c.h b/media/module/codecs/amrwb/enc/inc/wb_vad_c.h
similarity index 100%
rename from media/codecs/amrwb/enc/inc/wb_vad_c.h
rename to media/module/codecs/amrwb/enc/inc/wb_vad_c.h
diff --git a/media/codecs/amrwb/enc/patent_disclaimer.txt b/media/module/codecs/amrwb/enc/patent_disclaimer.txt
similarity index 100%
rename from media/codecs/amrwb/enc/patent_disclaimer.txt
rename to media/module/codecs/amrwb/enc/patent_disclaimer.txt
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV5E/Deemph_32_opt.s b/media/module/codecs/amrwb/enc/src/asm/ARMV5E/Deemph_32_opt.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV5E/Deemph_32_opt.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV5E/Deemph_32_opt.s
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV5E/Dot_p_opt.s b/media/module/codecs/amrwb/enc/src/asm/ARMV5E/Dot_p_opt.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV5E/Dot_p_opt.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV5E/Dot_p_opt.s
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV5E/Filt_6k_7k_opt.s b/media/module/codecs/amrwb/enc/src/asm/ARMV5E/Filt_6k_7k_opt.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV5E/Filt_6k_7k_opt.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV5E/Filt_6k_7k_opt.s
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV5E/Norm_Corr_opt.s b/media/module/codecs/amrwb/enc/src/asm/ARMV5E/Norm_Corr_opt.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV5E/Norm_Corr_opt.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV5E/Norm_Corr_opt.s
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV5E/Syn_filt_32_opt.s b/media/module/codecs/amrwb/enc/src/asm/ARMV5E/Syn_filt_32_opt.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV5E/Syn_filt_32_opt.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV5E/Syn_filt_32_opt.s
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV5E/convolve_opt.s b/media/module/codecs/amrwb/enc/src/asm/ARMV5E/convolve_opt.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV5E/convolve_opt.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV5E/convolve_opt.s
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV5E/cor_h_vec_opt.s b/media/module/codecs/amrwb/enc/src/asm/ARMV5E/cor_h_vec_opt.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV5E/cor_h_vec_opt.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV5E/cor_h_vec_opt.s
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV5E/pred_lt4_1_opt.s b/media/module/codecs/amrwb/enc/src/asm/ARMV5E/pred_lt4_1_opt.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV5E/pred_lt4_1_opt.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV5E/pred_lt4_1_opt.s
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV5E/residu_asm_opt.s b/media/module/codecs/amrwb/enc/src/asm/ARMV5E/residu_asm_opt.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV5E/residu_asm_opt.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV5E/residu_asm_opt.s
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV5E/scale_sig_opt.s b/media/module/codecs/amrwb/enc/src/asm/ARMV5E/scale_sig_opt.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV5E/scale_sig_opt.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV5E/scale_sig_opt.s
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV5E/syn_filt_opt.s b/media/module/codecs/amrwb/enc/src/asm/ARMV5E/syn_filt_opt.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV5E/syn_filt_opt.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV5E/syn_filt_opt.s
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV7/Deemph_32_neon.s b/media/module/codecs/amrwb/enc/src/asm/ARMV7/Deemph_32_neon.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV7/Deemph_32_neon.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV7/Deemph_32_neon.s
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV7/Dot_p_neon.s b/media/module/codecs/amrwb/enc/src/asm/ARMV7/Dot_p_neon.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV7/Dot_p_neon.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV7/Dot_p_neon.s
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV7/Filt_6k_7k_neon.s b/media/module/codecs/amrwb/enc/src/asm/ARMV7/Filt_6k_7k_neon.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV7/Filt_6k_7k_neon.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV7/Filt_6k_7k_neon.s
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV7/Norm_Corr_neon.s b/media/module/codecs/amrwb/enc/src/asm/ARMV7/Norm_Corr_neon.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV7/Norm_Corr_neon.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV7/Norm_Corr_neon.s
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV7/Syn_filt_32_neon.s b/media/module/codecs/amrwb/enc/src/asm/ARMV7/Syn_filt_32_neon.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV7/Syn_filt_32_neon.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV7/Syn_filt_32_neon.s
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV7/convolve_neon.s b/media/module/codecs/amrwb/enc/src/asm/ARMV7/convolve_neon.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV7/convolve_neon.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV7/convolve_neon.s
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV7/cor_h_vec_neon.s b/media/module/codecs/amrwb/enc/src/asm/ARMV7/cor_h_vec_neon.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV7/cor_h_vec_neon.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV7/cor_h_vec_neon.s
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV7/pred_lt4_1_neon.s b/media/module/codecs/amrwb/enc/src/asm/ARMV7/pred_lt4_1_neon.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV7/pred_lt4_1_neon.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV7/pred_lt4_1_neon.s
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV7/residu_asm_neon.s b/media/module/codecs/amrwb/enc/src/asm/ARMV7/residu_asm_neon.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV7/residu_asm_neon.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV7/residu_asm_neon.s
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV7/scale_sig_neon.s b/media/module/codecs/amrwb/enc/src/asm/ARMV7/scale_sig_neon.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV7/scale_sig_neon.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV7/scale_sig_neon.s
diff --git a/media/codecs/amrwb/enc/src/asm/ARMV7/syn_filt_neon.s b/media/module/codecs/amrwb/enc/src/asm/ARMV7/syn_filt_neon.s
similarity index 100%
rename from media/codecs/amrwb/enc/src/asm/ARMV7/syn_filt_neon.s
rename to media/module/codecs/amrwb/enc/src/asm/ARMV7/syn_filt_neon.s
diff --git a/media/codecs/amrwb/enc/src/autocorr.c b/media/module/codecs/amrwb/enc/src/autocorr.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/autocorr.c
rename to media/module/codecs/amrwb/enc/src/autocorr.c
diff --git a/media/codecs/amrwb/enc/src/az_isp.c b/media/module/codecs/amrwb/enc/src/az_isp.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/az_isp.c
rename to media/module/codecs/amrwb/enc/src/az_isp.c
diff --git a/media/codecs/amrwb/enc/src/bits.c b/media/module/codecs/amrwb/enc/src/bits.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/bits.c
rename to media/module/codecs/amrwb/enc/src/bits.c
diff --git a/media/codecs/amrwb/enc/src/c2t64fx.c b/media/module/codecs/amrwb/enc/src/c2t64fx.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/c2t64fx.c
rename to media/module/codecs/amrwb/enc/src/c2t64fx.c
diff --git a/media/codecs/amrwb/enc/src/c4t64fx.c b/media/module/codecs/amrwb/enc/src/c4t64fx.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/c4t64fx.c
rename to media/module/codecs/amrwb/enc/src/c4t64fx.c
diff --git a/media/codecs/amrwb/enc/src/convolve.c b/media/module/codecs/amrwb/enc/src/convolve.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/convolve.c
rename to media/module/codecs/amrwb/enc/src/convolve.c
diff --git a/media/codecs/amrwb/enc/src/cor_h_x.c b/media/module/codecs/amrwb/enc/src/cor_h_x.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/cor_h_x.c
rename to media/module/codecs/amrwb/enc/src/cor_h_x.c
diff --git a/media/codecs/amrwb/enc/src/decim54.c b/media/module/codecs/amrwb/enc/src/decim54.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/decim54.c
rename to media/module/codecs/amrwb/enc/src/decim54.c
diff --git a/media/codecs/amrwb/enc/src/deemph.c b/media/module/codecs/amrwb/enc/src/deemph.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/deemph.c
rename to media/module/codecs/amrwb/enc/src/deemph.c
diff --git a/media/codecs/amrwb/enc/src/dtx.c b/media/module/codecs/amrwb/enc/src/dtx.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/dtx.c
rename to media/module/codecs/amrwb/enc/src/dtx.c
diff --git a/media/codecs/amrwb/enc/src/g_pitch.c b/media/module/codecs/amrwb/enc/src/g_pitch.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/g_pitch.c
rename to media/module/codecs/amrwb/enc/src/g_pitch.c
diff --git a/media/codecs/amrwb/enc/src/gpclip.c b/media/module/codecs/amrwb/enc/src/gpclip.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/gpclip.c
rename to media/module/codecs/amrwb/enc/src/gpclip.c
diff --git a/media/codecs/amrwb/enc/src/homing.c b/media/module/codecs/amrwb/enc/src/homing.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/homing.c
rename to media/module/codecs/amrwb/enc/src/homing.c
diff --git a/media/codecs/amrwb/enc/src/hp400.c b/media/module/codecs/amrwb/enc/src/hp400.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/hp400.c
rename to media/module/codecs/amrwb/enc/src/hp400.c
diff --git a/media/codecs/amrwb/enc/src/hp50.c b/media/module/codecs/amrwb/enc/src/hp50.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/hp50.c
rename to media/module/codecs/amrwb/enc/src/hp50.c
diff --git a/media/codecs/amrwb/enc/src/hp6k.c b/media/module/codecs/amrwb/enc/src/hp6k.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/hp6k.c
rename to media/module/codecs/amrwb/enc/src/hp6k.c
diff --git a/media/codecs/amrwb/enc/src/hp_wsp.c b/media/module/codecs/amrwb/enc/src/hp_wsp.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/hp_wsp.c
rename to media/module/codecs/amrwb/enc/src/hp_wsp.c
diff --git a/media/codecs/amrwb/enc/src/int_lpc.c b/media/module/codecs/amrwb/enc/src/int_lpc.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/int_lpc.c
rename to media/module/codecs/amrwb/enc/src/int_lpc.c
diff --git a/media/codecs/amrwb/enc/src/isp_az.c b/media/module/codecs/amrwb/enc/src/isp_az.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/isp_az.c
rename to media/module/codecs/amrwb/enc/src/isp_az.c
diff --git a/media/codecs/amrwb/enc/src/isp_isf.c b/media/module/codecs/amrwb/enc/src/isp_isf.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/isp_isf.c
rename to media/module/codecs/amrwb/enc/src/isp_isf.c
diff --git a/media/codecs/amrwb/enc/src/lag_wind.c b/media/module/codecs/amrwb/enc/src/lag_wind.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/lag_wind.c
rename to media/module/codecs/amrwb/enc/src/lag_wind.c
diff --git a/media/codecs/amrwb/enc/src/levinson.c b/media/module/codecs/amrwb/enc/src/levinson.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/levinson.c
rename to media/module/codecs/amrwb/enc/src/levinson.c
diff --git a/media/codecs/amrwb/enc/src/log2.c b/media/module/codecs/amrwb/enc/src/log2.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/log2.c
rename to media/module/codecs/amrwb/enc/src/log2.c
diff --git a/media/codecs/amrwb/enc/src/lp_dec2.c b/media/module/codecs/amrwb/enc/src/lp_dec2.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/lp_dec2.c
rename to media/module/codecs/amrwb/enc/src/lp_dec2.c
diff --git a/media/codecs/amrwb/enc/src/math_op.c b/media/module/codecs/amrwb/enc/src/math_op.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/math_op.c
rename to media/module/codecs/amrwb/enc/src/math_op.c
diff --git a/media/codecs/amrwb/enc/src/mem_align.c b/media/module/codecs/amrwb/enc/src/mem_align.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/mem_align.c
rename to media/module/codecs/amrwb/enc/src/mem_align.c
diff --git a/media/codecs/amrwb/enc/src/oper_32b.c b/media/module/codecs/amrwb/enc/src/oper_32b.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/oper_32b.c
rename to media/module/codecs/amrwb/enc/src/oper_32b.c
diff --git a/media/codecs/amrwb/enc/src/p_med_ol.c b/media/module/codecs/amrwb/enc/src/p_med_ol.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/p_med_ol.c
rename to media/module/codecs/amrwb/enc/src/p_med_ol.c
diff --git a/media/codecs/amrwb/enc/src/pit_shrp.c b/media/module/codecs/amrwb/enc/src/pit_shrp.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/pit_shrp.c
rename to media/module/codecs/amrwb/enc/src/pit_shrp.c
diff --git a/media/codecs/amrwb/enc/src/pitch_f4.c b/media/module/codecs/amrwb/enc/src/pitch_f4.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/pitch_f4.c
rename to media/module/codecs/amrwb/enc/src/pitch_f4.c
diff --git a/media/codecs/amrwb/enc/src/pred_lt4.c b/media/module/codecs/amrwb/enc/src/pred_lt4.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/pred_lt4.c
rename to media/module/codecs/amrwb/enc/src/pred_lt4.c
diff --git a/media/codecs/amrwb/enc/src/preemph.c b/media/module/codecs/amrwb/enc/src/preemph.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/preemph.c
rename to media/module/codecs/amrwb/enc/src/preemph.c
diff --git a/media/codecs/amrwb/enc/src/q_gain2.c b/media/module/codecs/amrwb/enc/src/q_gain2.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/q_gain2.c
rename to media/module/codecs/amrwb/enc/src/q_gain2.c
diff --git a/media/codecs/amrwb/enc/src/q_pulse.c b/media/module/codecs/amrwb/enc/src/q_pulse.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/q_pulse.c
rename to media/module/codecs/amrwb/enc/src/q_pulse.c
diff --git a/media/codecs/amrwb/enc/src/qisf_ns.c b/media/module/codecs/amrwb/enc/src/qisf_ns.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/qisf_ns.c
rename to media/module/codecs/amrwb/enc/src/qisf_ns.c
diff --git a/media/codecs/amrwb/enc/src/qpisf_2s.c b/media/module/codecs/amrwb/enc/src/qpisf_2s.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/qpisf_2s.c
rename to media/module/codecs/amrwb/enc/src/qpisf_2s.c
diff --git a/media/codecs/amrwb/enc/src/random.c b/media/module/codecs/amrwb/enc/src/random.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/random.c
rename to media/module/codecs/amrwb/enc/src/random.c
diff --git a/media/codecs/amrwb/enc/src/residu.c b/media/module/codecs/amrwb/enc/src/residu.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/residu.c
rename to media/module/codecs/amrwb/enc/src/residu.c
diff --git a/media/codecs/amrwb/enc/src/scale.c b/media/module/codecs/amrwb/enc/src/scale.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/scale.c
rename to media/module/codecs/amrwb/enc/src/scale.c
diff --git a/media/codecs/amrwb/enc/src/stream.c b/media/module/codecs/amrwb/enc/src/stream.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/stream.c
rename to media/module/codecs/amrwb/enc/src/stream.c
diff --git a/media/codecs/amrwb/enc/src/syn_filt.c b/media/module/codecs/amrwb/enc/src/syn_filt.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/syn_filt.c
rename to media/module/codecs/amrwb/enc/src/syn_filt.c
diff --git a/media/codecs/amrwb/enc/src/updt_tar.c b/media/module/codecs/amrwb/enc/src/updt_tar.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/updt_tar.c
rename to media/module/codecs/amrwb/enc/src/updt_tar.c
diff --git a/media/codecs/amrwb/enc/src/util.c b/media/module/codecs/amrwb/enc/src/util.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/util.c
rename to media/module/codecs/amrwb/enc/src/util.c
diff --git a/media/codecs/amrwb/enc/src/voAMRWBEnc.c b/media/module/codecs/amrwb/enc/src/voAMRWBEnc.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/voAMRWBEnc.c
rename to media/module/codecs/amrwb/enc/src/voAMRWBEnc.c
diff --git a/media/codecs/amrwb/enc/src/voicefac.c b/media/module/codecs/amrwb/enc/src/voicefac.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/voicefac.c
rename to media/module/codecs/amrwb/enc/src/voicefac.c
diff --git a/media/codecs/amrwb/enc/src/wb_vad.c b/media/module/codecs/amrwb/enc/src/wb_vad.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/wb_vad.c
rename to media/module/codecs/amrwb/enc/src/wb_vad.c
diff --git a/media/codecs/amrwb/enc/src/weight_a.c b/media/module/codecs/amrwb/enc/src/weight_a.c
similarity index 100%
rename from media/codecs/amrwb/enc/src/weight_a.c
rename to media/module/codecs/amrwb/enc/src/weight_a.c
diff --git a/media/codecs/amrwb/enc/test/AmrwbEncTestEnvironment.h b/media/module/codecs/amrwb/enc/test/AmrwbEncTestEnvironment.h
similarity index 100%
rename from media/codecs/amrwb/enc/test/AmrwbEncTestEnvironment.h
rename to media/module/codecs/amrwb/enc/test/AmrwbEncTestEnvironment.h
diff --git a/media/codecs/amrwb/enc/test/AmrwbEncoderTest.cpp b/media/module/codecs/amrwb/enc/test/AmrwbEncoderTest.cpp
similarity index 100%
rename from media/codecs/amrwb/enc/test/AmrwbEncoderTest.cpp
rename to media/module/codecs/amrwb/enc/test/AmrwbEncoderTest.cpp
diff --git a/media/codecs/amrwb/enc/test/Android.bp b/media/module/codecs/amrwb/enc/test/Android.bp
similarity index 100%
rename from media/codecs/amrwb/enc/test/Android.bp
rename to media/module/codecs/amrwb/enc/test/Android.bp
diff --git a/media/codecs/amrwb/enc/test/AndroidTest.xml b/media/module/codecs/amrwb/enc/test/AndroidTest.xml
similarity index 100%
rename from media/codecs/amrwb/enc/test/AndroidTest.xml
rename to media/module/codecs/amrwb/enc/test/AndroidTest.xml
diff --git a/media/codecs/amrwb/enc/test/README.md b/media/module/codecs/amrwb/enc/test/README.md
similarity index 100%
rename from media/codecs/amrwb/enc/test/README.md
rename to media/module/codecs/amrwb/enc/test/README.md
diff --git a/media/libstagefright/codecs/common/Android.bp b/media/module/codecs/common/Android.bp
similarity index 100%
rename from media/libstagefright/codecs/common/Android.bp
rename to media/module/codecs/common/Android.bp
diff --git a/media/libstagefright/codecs/common/MODULE_LICENSE_APACHE2 b/media/module/codecs/common/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/libstagefright/codecs/common/MODULE_LICENSE_APACHE2
rename to media/module/codecs/common/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/codecs/common/NOTICE b/media/module/codecs/common/NOTICE
similarity index 100%
rename from media/libstagefright/codecs/common/NOTICE
rename to media/module/codecs/common/NOTICE
diff --git a/media/libstagefright/codecs/common/cmnMemory.c b/media/module/codecs/common/cmnMemory.c
similarity index 100%
rename from media/libstagefright/codecs/common/cmnMemory.c
rename to media/module/codecs/common/cmnMemory.c
diff --git a/media/libstagefright/codecs/common/include/cmnMemory.h b/media/module/codecs/common/include/cmnMemory.h
similarity index 100%
rename from media/libstagefright/codecs/common/include/cmnMemory.h
rename to media/module/codecs/common/include/cmnMemory.h
diff --git a/media/libstagefright/codecs/common/include/voAAC.h b/media/module/codecs/common/include/voAAC.h
similarity index 100%
rename from media/libstagefright/codecs/common/include/voAAC.h
rename to media/module/codecs/common/include/voAAC.h
diff --git a/media/libstagefright/codecs/common/include/voAMRWB.h b/media/module/codecs/common/include/voAMRWB.h
similarity index 100%
rename from media/libstagefright/codecs/common/include/voAMRWB.h
rename to media/module/codecs/common/include/voAMRWB.h
diff --git a/media/libstagefright/codecs/common/include/voAudio.h b/media/module/codecs/common/include/voAudio.h
similarity index 100%
rename from media/libstagefright/codecs/common/include/voAudio.h
rename to media/module/codecs/common/include/voAudio.h
diff --git a/media/libstagefright/codecs/common/include/voIndex.h b/media/module/codecs/common/include/voIndex.h
similarity index 100%
rename from media/libstagefright/codecs/common/include/voIndex.h
rename to media/module/codecs/common/include/voIndex.h
diff --git a/media/libstagefright/codecs/common/include/voMem.h b/media/module/codecs/common/include/voMem.h
similarity index 100%
rename from media/libstagefright/codecs/common/include/voMem.h
rename to media/module/codecs/common/include/voMem.h
diff --git a/media/libstagefright/codecs/common/include/voType.h b/media/module/codecs/common/include/voType.h
similarity index 100%
rename from media/libstagefright/codecs/common/include/voType.h
rename to media/module/codecs/common/include/voType.h
diff --git a/media/libstagefright/flac/dec/Android.bp b/media/module/codecs/flac/dec/Android.bp
similarity index 100%
rename from media/libstagefright/flac/dec/Android.bp
rename to media/module/codecs/flac/dec/Android.bp
diff --git a/media/libstagefright/flac/dec/FLACDecoder.cpp b/media/module/codecs/flac/dec/FLACDecoder.cpp
similarity index 100%
rename from media/libstagefright/flac/dec/FLACDecoder.cpp
rename to media/module/codecs/flac/dec/FLACDecoder.cpp
diff --git a/media/libstagefright/flac/dec/FLACDecoder.h b/media/module/codecs/flac/dec/FLACDecoder.h
similarity index 100%
rename from media/libstagefright/flac/dec/FLACDecoder.h
rename to media/module/codecs/flac/dec/FLACDecoder.h
diff --git a/media/libstagefright/flac/dec/MODULE_LICENSE_APACHE2 b/media/module/codecs/flac/dec/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/libstagefright/flac/dec/MODULE_LICENSE_APACHE2
rename to media/module/codecs/flac/dec/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/flac/dec/NOTICE b/media/module/codecs/flac/dec/NOTICE
similarity index 100%
rename from media/libstagefright/flac/dec/NOTICE
rename to media/module/codecs/flac/dec/NOTICE
diff --git a/media/libstagefright/flac/dec/test/Android.bp b/media/module/codecs/flac/dec/test/Android.bp
similarity index 100%
rename from media/libstagefright/flac/dec/test/Android.bp
rename to media/module/codecs/flac/dec/test/Android.bp
diff --git a/media/libstagefright/flac/dec/test/AndroidTest.xml b/media/module/codecs/flac/dec/test/AndroidTest.xml
similarity index 100%
rename from media/libstagefright/flac/dec/test/AndroidTest.xml
rename to media/module/codecs/flac/dec/test/AndroidTest.xml
diff --git a/media/libstagefright/flac/dec/test/FlacDecoderTest.cpp b/media/module/codecs/flac/dec/test/FlacDecoderTest.cpp
similarity index 100%
rename from media/libstagefright/flac/dec/test/FlacDecoderTest.cpp
rename to media/module/codecs/flac/dec/test/FlacDecoderTest.cpp
diff --git a/media/libstagefright/flac/dec/test/FlacDecoderTestEnvironment.h b/media/module/codecs/flac/dec/test/FlacDecoderTestEnvironment.h
similarity index 100%
rename from media/libstagefright/flac/dec/test/FlacDecoderTestEnvironment.h
rename to media/module/codecs/flac/dec/test/FlacDecoderTestEnvironment.h
diff --git a/media/libstagefright/flac/dec/test/README.md b/media/module/codecs/flac/dec/test/README.md
similarity index 100%
rename from media/libstagefright/flac/dec/test/README.md
rename to media/module/codecs/flac/dec/test/README.md
diff --git a/media/codecs/g711/decoder/Android.bp b/media/module/codecs/g711/decoder/Android.bp
similarity index 100%
rename from media/codecs/g711/decoder/Android.bp
rename to media/module/codecs/g711/decoder/Android.bp
diff --git a/media/codecs/g711/decoder/g711Dec.h b/media/module/codecs/g711/decoder/g711Dec.h
similarity index 100%
rename from media/codecs/g711/decoder/g711Dec.h
rename to media/module/codecs/g711/decoder/g711Dec.h
diff --git a/media/codecs/g711/decoder/g711DecAlaw.cpp b/media/module/codecs/g711/decoder/g711DecAlaw.cpp
similarity index 100%
rename from media/codecs/g711/decoder/g711DecAlaw.cpp
rename to media/module/codecs/g711/decoder/g711DecAlaw.cpp
diff --git a/media/codecs/g711/decoder/g711DecMlaw.cpp b/media/module/codecs/g711/decoder/g711DecMlaw.cpp
similarity index 100%
rename from media/codecs/g711/decoder/g711DecMlaw.cpp
rename to media/module/codecs/g711/decoder/g711DecMlaw.cpp
diff --git a/media/codecs/g711/fuzzer/Android.bp b/media/module/codecs/g711/fuzzer/Android.bp
similarity index 100%
rename from media/codecs/g711/fuzzer/Android.bp
rename to media/module/codecs/g711/fuzzer/Android.bp
diff --git a/media/codecs/g711/fuzzer/README.md b/media/module/codecs/g711/fuzzer/README.md
similarity index 100%
rename from media/codecs/g711/fuzzer/README.md
rename to media/module/codecs/g711/fuzzer/README.md
diff --git a/media/codecs/g711/fuzzer/g711_dec_fuzzer.cpp b/media/module/codecs/g711/fuzzer/g711_dec_fuzzer.cpp
similarity index 100%
rename from media/codecs/g711/fuzzer/g711_dec_fuzzer.cpp
rename to media/module/codecs/g711/fuzzer/g711_dec_fuzzer.cpp
diff --git a/media/codecs/m4v_h263/TEST_MAPPING b/media/module/codecs/m4v_h263/TEST_MAPPING
similarity index 100%
rename from media/codecs/m4v_h263/TEST_MAPPING
rename to media/module/codecs/m4v_h263/TEST_MAPPING
diff --git a/media/codecs/m4v_h263/dec/Android.bp b/media/module/codecs/m4v_h263/dec/Android.bp
similarity index 100%
rename from media/codecs/m4v_h263/dec/Android.bp
rename to media/module/codecs/m4v_h263/dec/Android.bp
diff --git a/media/codecs/m4v_h263/dec/MODULE_LICENSE_APACHE2 b/media/module/codecs/m4v_h263/dec/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/codecs/m4v_h263/dec/MODULE_LICENSE_APACHE2
rename to media/module/codecs/m4v_h263/dec/MODULE_LICENSE_APACHE2
diff --git a/media/codecs/m4v_h263/dec/NOTICE b/media/module/codecs/m4v_h263/dec/NOTICE
similarity index 100%
rename from media/codecs/m4v_h263/dec/NOTICE
rename to media/module/codecs/m4v_h263/dec/NOTICE
diff --git a/media/codecs/m4v_h263/dec/include/m4vh263_decoder_pv_types.h b/media/module/codecs/m4v_h263/dec/include/m4vh263_decoder_pv_types.h
similarity index 100%
rename from media/codecs/m4v_h263/dec/include/m4vh263_decoder_pv_types.h
rename to media/module/codecs/m4v_h263/dec/include/m4vh263_decoder_pv_types.h
diff --git a/media/codecs/m4v_h263/dec/include/mp4dec_api.h b/media/module/codecs/m4v_h263/dec/include/mp4dec_api.h
similarity index 100%
rename from media/codecs/m4v_h263/dec/include/mp4dec_api.h
rename to media/module/codecs/m4v_h263/dec/include/mp4dec_api.h
diff --git a/media/codecs/m4v_h263/dec/include/visual_header.h b/media/module/codecs/m4v_h263/dec/include/visual_header.h
similarity index 100%
rename from media/codecs/m4v_h263/dec/include/visual_header.h
rename to media/module/codecs/m4v_h263/dec/include/visual_header.h
diff --git a/media/codecs/m4v_h263/dec/src/bitstream.cpp b/media/module/codecs/m4v_h263/dec/src/bitstream.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/bitstream.cpp
rename to media/module/codecs/m4v_h263/dec/src/bitstream.cpp
diff --git a/media/codecs/m4v_h263/dec/src/bitstream.h b/media/module/codecs/m4v_h263/dec/src/bitstream.h
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/bitstream.h
rename to media/module/codecs/m4v_h263/dec/src/bitstream.h
diff --git a/media/codecs/m4v_h263/dec/src/block_idct.cpp b/media/module/codecs/m4v_h263/dec/src/block_idct.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/block_idct.cpp
rename to media/module/codecs/m4v_h263/dec/src/block_idct.cpp
diff --git a/media/codecs/m4v_h263/dec/src/cal_dc_scaler.cpp b/media/module/codecs/m4v_h263/dec/src/cal_dc_scaler.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/cal_dc_scaler.cpp
rename to media/module/codecs/m4v_h263/dec/src/cal_dc_scaler.cpp
diff --git a/media/codecs/m4v_h263/dec/src/combined_decode.cpp b/media/module/codecs/m4v_h263/dec/src/combined_decode.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/combined_decode.cpp
rename to media/module/codecs/m4v_h263/dec/src/combined_decode.cpp
diff --git a/media/codecs/m4v_h263/dec/src/conceal.cpp b/media/module/codecs/m4v_h263/dec/src/conceal.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/conceal.cpp
rename to media/module/codecs/m4v_h263/dec/src/conceal.cpp
diff --git a/media/codecs/m4v_h263/dec/src/datapart_decode.cpp b/media/module/codecs/m4v_h263/dec/src/datapart_decode.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/datapart_decode.cpp
rename to media/module/codecs/m4v_h263/dec/src/datapart_decode.cpp
diff --git a/media/codecs/m4v_h263/dec/src/dcac_prediction.cpp b/media/module/codecs/m4v_h263/dec/src/dcac_prediction.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/dcac_prediction.cpp
rename to media/module/codecs/m4v_h263/dec/src/dcac_prediction.cpp
diff --git a/media/codecs/m4v_h263/dec/src/dec_pred_intra_dc.cpp b/media/module/codecs/m4v_h263/dec/src/dec_pred_intra_dc.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/dec_pred_intra_dc.cpp
rename to media/module/codecs/m4v_h263/dec/src/dec_pred_intra_dc.cpp
diff --git a/media/codecs/m4v_h263/dec/src/get_pred_adv_b_add.cpp b/media/module/codecs/m4v_h263/dec/src/get_pred_adv_b_add.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/get_pred_adv_b_add.cpp
rename to media/module/codecs/m4v_h263/dec/src/get_pred_adv_b_add.cpp
diff --git a/media/codecs/m4v_h263/dec/src/get_pred_outside.cpp b/media/module/codecs/m4v_h263/dec/src/get_pred_outside.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/get_pred_outside.cpp
rename to media/module/codecs/m4v_h263/dec/src/get_pred_outside.cpp
diff --git a/media/codecs/m4v_h263/dec/src/idct.cpp b/media/module/codecs/m4v_h263/dec/src/idct.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/idct.cpp
rename to media/module/codecs/m4v_h263/dec/src/idct.cpp
diff --git a/media/codecs/m4v_h263/dec/src/idct.h b/media/module/codecs/m4v_h263/dec/src/idct.h
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/idct.h
rename to media/module/codecs/m4v_h263/dec/src/idct.h
diff --git a/media/codecs/m4v_h263/dec/src/idct_vca.cpp b/media/module/codecs/m4v_h263/dec/src/idct_vca.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/idct_vca.cpp
rename to media/module/codecs/m4v_h263/dec/src/idct_vca.cpp
diff --git a/media/codecs/m4v_h263/dec/src/max_level.h b/media/module/codecs/m4v_h263/dec/src/max_level.h
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/max_level.h
rename to media/module/codecs/m4v_h263/dec/src/max_level.h
diff --git a/media/codecs/m4v_h263/dec/src/mb_motion_comp.cpp b/media/module/codecs/m4v_h263/dec/src/mb_motion_comp.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/mb_motion_comp.cpp
rename to media/module/codecs/m4v_h263/dec/src/mb_motion_comp.cpp
diff --git a/media/codecs/m4v_h263/dec/src/mb_utils.cpp b/media/module/codecs/m4v_h263/dec/src/mb_utils.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/mb_utils.cpp
rename to media/module/codecs/m4v_h263/dec/src/mb_utils.cpp
diff --git a/media/codecs/m4v_h263/dec/src/mbtype_mode.h b/media/module/codecs/m4v_h263/dec/src/mbtype_mode.h
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/mbtype_mode.h
rename to media/module/codecs/m4v_h263/dec/src/mbtype_mode.h
diff --git a/media/codecs/m4v_h263/dec/src/motion_comp.h b/media/module/codecs/m4v_h263/dec/src/motion_comp.h
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/motion_comp.h
rename to media/module/codecs/m4v_h263/dec/src/motion_comp.h
diff --git a/media/codecs/m4v_h263/dec/src/mp4dec_lib.h b/media/module/codecs/m4v_h263/dec/src/mp4dec_lib.h
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/mp4dec_lib.h
rename to media/module/codecs/m4v_h263/dec/src/mp4dec_lib.h
diff --git a/media/codecs/m4v_h263/dec/src/mp4def.h b/media/module/codecs/m4v_h263/dec/src/mp4def.h
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/mp4def.h
rename to media/module/codecs/m4v_h263/dec/src/mp4def.h
diff --git a/media/codecs/m4v_h263/dec/src/mp4lib_int.h b/media/module/codecs/m4v_h263/dec/src/mp4lib_int.h
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/mp4lib_int.h
rename to media/module/codecs/m4v_h263/dec/src/mp4lib_int.h
diff --git a/media/codecs/m4v_h263/dec/src/packet_util.cpp b/media/module/codecs/m4v_h263/dec/src/packet_util.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/packet_util.cpp
rename to media/module/codecs/m4v_h263/dec/src/packet_util.cpp
diff --git a/media/codecs/m4v_h263/dec/src/post_filter.cpp b/media/module/codecs/m4v_h263/dec/src/post_filter.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/post_filter.cpp
rename to media/module/codecs/m4v_h263/dec/src/post_filter.cpp
diff --git a/media/codecs/m4v_h263/dec/src/post_proc.h b/media/module/codecs/m4v_h263/dec/src/post_proc.h
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/post_proc.h
rename to media/module/codecs/m4v_h263/dec/src/post_proc.h
diff --git a/media/codecs/m4v_h263/dec/src/pvdec_api.cpp b/media/module/codecs/m4v_h263/dec/src/pvdec_api.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/pvdec_api.cpp
rename to media/module/codecs/m4v_h263/dec/src/pvdec_api.cpp
diff --git a/media/codecs/m4v_h263/dec/src/scaling.h b/media/module/codecs/m4v_h263/dec/src/scaling.h
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/scaling.h
rename to media/module/codecs/m4v_h263/dec/src/scaling.h
diff --git a/media/codecs/m4v_h263/dec/src/scaling_tab.cpp b/media/module/codecs/m4v_h263/dec/src/scaling_tab.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/scaling_tab.cpp
rename to media/module/codecs/m4v_h263/dec/src/scaling_tab.cpp
diff --git a/media/codecs/m4v_h263/dec/src/vlc_dec_tab.h b/media/module/codecs/m4v_h263/dec/src/vlc_dec_tab.h
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/vlc_dec_tab.h
rename to media/module/codecs/m4v_h263/dec/src/vlc_dec_tab.h
diff --git a/media/codecs/m4v_h263/dec/src/vlc_decode.cpp b/media/module/codecs/m4v_h263/dec/src/vlc_decode.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/vlc_decode.cpp
rename to media/module/codecs/m4v_h263/dec/src/vlc_decode.cpp
diff --git a/media/codecs/m4v_h263/dec/src/vlc_decode.h b/media/module/codecs/m4v_h263/dec/src/vlc_decode.h
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/vlc_decode.h
rename to media/module/codecs/m4v_h263/dec/src/vlc_decode.h
diff --git a/media/codecs/m4v_h263/dec/src/vlc_dequant.cpp b/media/module/codecs/m4v_h263/dec/src/vlc_dequant.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/vlc_dequant.cpp
rename to media/module/codecs/m4v_h263/dec/src/vlc_dequant.cpp
diff --git a/media/codecs/m4v_h263/dec/src/vlc_tab.cpp b/media/module/codecs/m4v_h263/dec/src/vlc_tab.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/vlc_tab.cpp
rename to media/module/codecs/m4v_h263/dec/src/vlc_tab.cpp
diff --git a/media/codecs/m4v_h263/dec/src/vop.cpp b/media/module/codecs/m4v_h263/dec/src/vop.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/vop.cpp
rename to media/module/codecs/m4v_h263/dec/src/vop.cpp
diff --git a/media/codecs/m4v_h263/dec/src/zigzag.h b/media/module/codecs/m4v_h263/dec/src/zigzag.h
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/zigzag.h
rename to media/module/codecs/m4v_h263/dec/src/zigzag.h
diff --git a/media/codecs/m4v_h263/dec/src/zigzag_tab.cpp b/media/module/codecs/m4v_h263/dec/src/zigzag_tab.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/src/zigzag_tab.cpp
rename to media/module/codecs/m4v_h263/dec/src/zigzag_tab.cpp
diff --git a/media/codecs/m4v_h263/dec/test/Android.bp b/media/module/codecs/m4v_h263/dec/test/Android.bp
similarity index 100%
rename from media/codecs/m4v_h263/dec/test/Android.bp
rename to media/module/codecs/m4v_h263/dec/test/Android.bp
diff --git a/media/codecs/m4v_h263/dec/test/AndroidTest.xml b/media/module/codecs/m4v_h263/dec/test/AndroidTest.xml
similarity index 100%
rename from media/codecs/m4v_h263/dec/test/AndroidTest.xml
rename to media/module/codecs/m4v_h263/dec/test/AndroidTest.xml
diff --git a/media/codecs/m4v_h263/dec/test/Mpeg4H263DecoderTest.cpp b/media/module/codecs/m4v_h263/dec/test/Mpeg4H263DecoderTest.cpp
similarity index 100%
rename from media/codecs/m4v_h263/dec/test/Mpeg4H263DecoderTest.cpp
rename to media/module/codecs/m4v_h263/dec/test/Mpeg4H263DecoderTest.cpp
diff --git a/media/codecs/m4v_h263/dec/test/Mpeg4H263DecoderTestEnvironment.h b/media/module/codecs/m4v_h263/dec/test/Mpeg4H263DecoderTestEnvironment.h
similarity index 100%
rename from media/codecs/m4v_h263/dec/test/Mpeg4H263DecoderTestEnvironment.h
rename to media/module/codecs/m4v_h263/dec/test/Mpeg4H263DecoderTestEnvironment.h
diff --git a/media/codecs/m4v_h263/dec/test/README.md b/media/module/codecs/m4v_h263/dec/test/README.md
similarity index 100%
rename from media/codecs/m4v_h263/dec/test/README.md
rename to media/module/codecs/m4v_h263/dec/test/README.md
diff --git a/media/codecs/m4v_h263/enc/Android.bp b/media/module/codecs/m4v_h263/enc/Android.bp
similarity index 100%
rename from media/codecs/m4v_h263/enc/Android.bp
rename to media/module/codecs/m4v_h263/enc/Android.bp
diff --git a/media/codecs/m4v_h263/enc/MODULE_LICENSE_APACHE2 b/media/module/codecs/m4v_h263/enc/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/codecs/m4v_h263/enc/MODULE_LICENSE_APACHE2
rename to media/module/codecs/m4v_h263/enc/MODULE_LICENSE_APACHE2
diff --git a/media/codecs/m4v_h263/enc/NOTICE b/media/module/codecs/m4v_h263/enc/NOTICE
similarity index 100%
rename from media/codecs/m4v_h263/enc/NOTICE
rename to media/module/codecs/m4v_h263/enc/NOTICE
diff --git a/media/codecs/m4v_h263/enc/include/cvei.h b/media/module/codecs/m4v_h263/enc/include/cvei.h
similarity index 100%
rename from media/codecs/m4v_h263/enc/include/cvei.h
rename to media/module/codecs/m4v_h263/enc/include/cvei.h
diff --git a/media/codecs/m4v_h263/enc/include/mp4enc_api.h b/media/module/codecs/m4v_h263/enc/include/mp4enc_api.h
similarity index 100%
rename from media/codecs/m4v_h263/enc/include/mp4enc_api.h
rename to media/module/codecs/m4v_h263/enc/include/mp4enc_api.h
diff --git a/media/codecs/m4v_h263/enc/src/bitstream_io.cpp b/media/module/codecs/m4v_h263/enc/src/bitstream_io.cpp
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/bitstream_io.cpp
rename to media/module/codecs/m4v_h263/enc/src/bitstream_io.cpp
diff --git a/media/codecs/m4v_h263/enc/src/bitstream_io.h b/media/module/codecs/m4v_h263/enc/src/bitstream_io.h
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/bitstream_io.h
rename to media/module/codecs/m4v_h263/enc/src/bitstream_io.h
diff --git a/media/codecs/m4v_h263/enc/src/combined_encode.cpp b/media/module/codecs/m4v_h263/enc/src/combined_encode.cpp
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/combined_encode.cpp
rename to media/module/codecs/m4v_h263/enc/src/combined_encode.cpp
diff --git a/media/codecs/m4v_h263/enc/src/datapart_encode.cpp b/media/module/codecs/m4v_h263/enc/src/datapart_encode.cpp
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/datapart_encode.cpp
rename to media/module/codecs/m4v_h263/enc/src/datapart_encode.cpp
diff --git a/media/codecs/m4v_h263/enc/src/dct.cpp b/media/module/codecs/m4v_h263/enc/src/dct.cpp
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/dct.cpp
rename to media/module/codecs/m4v_h263/enc/src/dct.cpp
diff --git a/media/codecs/m4v_h263/enc/src/dct.h b/media/module/codecs/m4v_h263/enc/src/dct.h
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/dct.h
rename to media/module/codecs/m4v_h263/enc/src/dct.h
diff --git a/media/codecs/m4v_h263/enc/src/dct_inline.h b/media/module/codecs/m4v_h263/enc/src/dct_inline.h
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/dct_inline.h
rename to media/module/codecs/m4v_h263/enc/src/dct_inline.h
diff --git a/media/codecs/m4v_h263/enc/src/fastcodemb.cpp b/media/module/codecs/m4v_h263/enc/src/fastcodemb.cpp
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/fastcodemb.cpp
rename to media/module/codecs/m4v_h263/enc/src/fastcodemb.cpp
diff --git a/media/codecs/m4v_h263/enc/src/fastcodemb.h b/media/module/codecs/m4v_h263/enc/src/fastcodemb.h
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/fastcodemb.h
rename to media/module/codecs/m4v_h263/enc/src/fastcodemb.h
diff --git a/media/codecs/m4v_h263/enc/src/fastidct.cpp b/media/module/codecs/m4v_h263/enc/src/fastidct.cpp
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/fastidct.cpp
rename to media/module/codecs/m4v_h263/enc/src/fastidct.cpp
diff --git a/media/codecs/m4v_h263/enc/src/fastquant.cpp b/media/module/codecs/m4v_h263/enc/src/fastquant.cpp
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/fastquant.cpp
rename to media/module/codecs/m4v_h263/enc/src/fastquant.cpp
diff --git a/media/codecs/m4v_h263/enc/src/fastquant_inline.h b/media/module/codecs/m4v_h263/enc/src/fastquant_inline.h
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/fastquant_inline.h
rename to media/module/codecs/m4v_h263/enc/src/fastquant_inline.h
diff --git a/media/codecs/m4v_h263/enc/src/findhalfpel.cpp b/media/module/codecs/m4v_h263/enc/src/findhalfpel.cpp
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/findhalfpel.cpp
rename to media/module/codecs/m4v_h263/enc/src/findhalfpel.cpp
diff --git a/media/codecs/m4v_h263/enc/src/m4venc_oscl.h b/media/module/codecs/m4v_h263/enc/src/m4venc_oscl.h
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/m4venc_oscl.h
rename to media/module/codecs/m4v_h263/enc/src/m4venc_oscl.h
diff --git a/media/codecs/m4v_h263/enc/src/me_utils.cpp b/media/module/codecs/m4v_h263/enc/src/me_utils.cpp
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/me_utils.cpp
rename to media/module/codecs/m4v_h263/enc/src/me_utils.cpp
diff --git a/media/codecs/m4v_h263/enc/src/motion_comp.cpp b/media/module/codecs/m4v_h263/enc/src/motion_comp.cpp
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/motion_comp.cpp
rename to media/module/codecs/m4v_h263/enc/src/motion_comp.cpp
diff --git a/media/codecs/m4v_h263/enc/src/motion_est.cpp b/media/module/codecs/m4v_h263/enc/src/motion_est.cpp
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/motion_est.cpp
rename to media/module/codecs/m4v_h263/enc/src/motion_est.cpp
diff --git a/media/codecs/m4v_h263/enc/src/mp4def.h b/media/module/codecs/m4v_h263/enc/src/mp4def.h
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/mp4def.h
rename to media/module/codecs/m4v_h263/enc/src/mp4def.h
diff --git a/media/codecs/m4v_h263/enc/src/mp4enc_api.cpp b/media/module/codecs/m4v_h263/enc/src/mp4enc_api.cpp
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/mp4enc_api.cpp
rename to media/module/codecs/m4v_h263/enc/src/mp4enc_api.cpp
diff --git a/media/codecs/m4v_h263/enc/src/mp4enc_lib.h b/media/module/codecs/m4v_h263/enc/src/mp4enc_lib.h
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/mp4enc_lib.h
rename to media/module/codecs/m4v_h263/enc/src/mp4enc_lib.h
diff --git a/media/codecs/m4v_h263/enc/src/mp4lib_int.h b/media/module/codecs/m4v_h263/enc/src/mp4lib_int.h
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/mp4lib_int.h
rename to media/module/codecs/m4v_h263/enc/src/mp4lib_int.h
diff --git a/media/codecs/m4v_h263/enc/src/rate_control.cpp b/media/module/codecs/m4v_h263/enc/src/rate_control.cpp
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/rate_control.cpp
rename to media/module/codecs/m4v_h263/enc/src/rate_control.cpp
diff --git a/media/codecs/m4v_h263/enc/src/rate_control.h b/media/module/codecs/m4v_h263/enc/src/rate_control.h
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/rate_control.h
rename to media/module/codecs/m4v_h263/enc/src/rate_control.h
diff --git a/media/codecs/m4v_h263/enc/src/sad.cpp b/media/module/codecs/m4v_h263/enc/src/sad.cpp
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/sad.cpp
rename to media/module/codecs/m4v_h263/enc/src/sad.cpp
diff --git a/media/codecs/m4v_h263/enc/src/sad_halfpel.cpp b/media/module/codecs/m4v_h263/enc/src/sad_halfpel.cpp
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/sad_halfpel.cpp
rename to media/module/codecs/m4v_h263/enc/src/sad_halfpel.cpp
diff --git a/media/codecs/m4v_h263/enc/src/sad_halfpel_inline.h b/media/module/codecs/m4v_h263/enc/src/sad_halfpel_inline.h
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/sad_halfpel_inline.h
rename to media/module/codecs/m4v_h263/enc/src/sad_halfpel_inline.h
diff --git a/media/codecs/m4v_h263/enc/src/sad_inline.h b/media/module/codecs/m4v_h263/enc/src/sad_inline.h
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/sad_inline.h
rename to media/module/codecs/m4v_h263/enc/src/sad_inline.h
diff --git a/media/codecs/m4v_h263/enc/src/sad_mb_offset.h b/media/module/codecs/m4v_h263/enc/src/sad_mb_offset.h
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/sad_mb_offset.h
rename to media/module/codecs/m4v_h263/enc/src/sad_mb_offset.h
diff --git a/media/codecs/m4v_h263/enc/src/vlc_enc_tab.h b/media/module/codecs/m4v_h263/enc/src/vlc_enc_tab.h
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/vlc_enc_tab.h
rename to media/module/codecs/m4v_h263/enc/src/vlc_enc_tab.h
diff --git a/media/codecs/m4v_h263/enc/src/vlc_encode.cpp b/media/module/codecs/m4v_h263/enc/src/vlc_encode.cpp
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/vlc_encode.cpp
rename to media/module/codecs/m4v_h263/enc/src/vlc_encode.cpp
diff --git a/media/codecs/m4v_h263/enc/src/vlc_encode.h b/media/module/codecs/m4v_h263/enc/src/vlc_encode.h
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/vlc_encode.h
rename to media/module/codecs/m4v_h263/enc/src/vlc_encode.h
diff --git a/media/codecs/m4v_h263/enc/src/vlc_encode_inline.h b/media/module/codecs/m4v_h263/enc/src/vlc_encode_inline.h
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/vlc_encode_inline.h
rename to media/module/codecs/m4v_h263/enc/src/vlc_encode_inline.h
diff --git a/media/codecs/m4v_h263/enc/src/vop.cpp b/media/module/codecs/m4v_h263/enc/src/vop.cpp
similarity index 100%
rename from media/codecs/m4v_h263/enc/src/vop.cpp
rename to media/module/codecs/m4v_h263/enc/src/vop.cpp
diff --git a/media/codecs/m4v_h263/enc/test/Android.bp b/media/module/codecs/m4v_h263/enc/test/Android.bp
similarity index 100%
rename from media/codecs/m4v_h263/enc/test/Android.bp
rename to media/module/codecs/m4v_h263/enc/test/Android.bp
diff --git a/media/codecs/m4v_h263/enc/test/AndroidTest.xml b/media/module/codecs/m4v_h263/enc/test/AndroidTest.xml
similarity index 100%
rename from media/codecs/m4v_h263/enc/test/AndroidTest.xml
rename to media/module/codecs/m4v_h263/enc/test/AndroidTest.xml
diff --git a/media/codecs/m4v_h263/enc/test/Mpeg4H263EncoderTest.cpp b/media/module/codecs/m4v_h263/enc/test/Mpeg4H263EncoderTest.cpp
similarity index 100%
rename from media/codecs/m4v_h263/enc/test/Mpeg4H263EncoderTest.cpp
rename to media/module/codecs/m4v_h263/enc/test/Mpeg4H263EncoderTest.cpp
diff --git a/media/codecs/m4v_h263/enc/test/Mpeg4H263EncoderTestEnvironment.h b/media/module/codecs/m4v_h263/enc/test/Mpeg4H263EncoderTestEnvironment.h
similarity index 100%
rename from media/codecs/m4v_h263/enc/test/Mpeg4H263EncoderTestEnvironment.h
rename to media/module/codecs/m4v_h263/enc/test/Mpeg4H263EncoderTestEnvironment.h
diff --git a/media/codecs/m4v_h263/enc/test/README.md b/media/module/codecs/m4v_h263/enc/test/README.md
similarity index 100%
rename from media/codecs/m4v_h263/enc/test/README.md
rename to media/module/codecs/m4v_h263/enc/test/README.md
diff --git a/media/codecs/m4v_h263/enc/test/m4v_h263_enc_test.cpp b/media/module/codecs/m4v_h263/enc/test/m4v_h263_enc_test.cpp
similarity index 100%
rename from media/codecs/m4v_h263/enc/test/m4v_h263_enc_test.cpp
rename to media/module/codecs/m4v_h263/enc/test/m4v_h263_enc_test.cpp
diff --git a/media/codecs/m4v_h263/fuzzer/Android.bp b/media/module/codecs/m4v_h263/fuzzer/Android.bp
similarity index 100%
rename from media/codecs/m4v_h263/fuzzer/Android.bp
rename to media/module/codecs/m4v_h263/fuzzer/Android.bp
diff --git a/media/codecs/m4v_h263/fuzzer/README.md b/media/module/codecs/m4v_h263/fuzzer/README.md
similarity index 100%
rename from media/codecs/m4v_h263/fuzzer/README.md
rename to media/module/codecs/m4v_h263/fuzzer/README.md
diff --git a/media/codecs/m4v_h263/fuzzer/h263_dec_fuzzer.dict b/media/module/codecs/m4v_h263/fuzzer/h263_dec_fuzzer.dict
similarity index 100%
rename from media/codecs/m4v_h263/fuzzer/h263_dec_fuzzer.dict
rename to media/module/codecs/m4v_h263/fuzzer/h263_dec_fuzzer.dict
diff --git a/media/codecs/m4v_h263/fuzzer/mpeg4_dec_fuzzer.dict b/media/module/codecs/m4v_h263/fuzzer/mpeg4_dec_fuzzer.dict
similarity index 100%
rename from media/codecs/m4v_h263/fuzzer/mpeg4_dec_fuzzer.dict
rename to media/module/codecs/m4v_h263/fuzzer/mpeg4_dec_fuzzer.dict
diff --git a/media/codecs/m4v_h263/fuzzer/mpeg4_h263_dec_fuzzer.cpp b/media/module/codecs/m4v_h263/fuzzer/mpeg4_h263_dec_fuzzer.cpp
similarity index 100%
rename from media/codecs/m4v_h263/fuzzer/mpeg4_h263_dec_fuzzer.cpp
rename to media/module/codecs/m4v_h263/fuzzer/mpeg4_h263_dec_fuzzer.cpp
diff --git a/media/codecs/m4v_h263/fuzzer/mpeg4_h263_enc_fuzzer.cpp b/media/module/codecs/m4v_h263/fuzzer/mpeg4_h263_enc_fuzzer.cpp
similarity index 100%
rename from media/codecs/m4v_h263/fuzzer/mpeg4_h263_enc_fuzzer.cpp
rename to media/module/codecs/m4v_h263/fuzzer/mpeg4_h263_enc_fuzzer.cpp
diff --git a/media/codecs/m4v_h263/patent_disclaimer.txt b/media/module/codecs/m4v_h263/patent_disclaimer.txt
similarity index 100%
rename from media/codecs/m4v_h263/patent_disclaimer.txt
rename to media/module/codecs/m4v_h263/patent_disclaimer.txt
diff --git a/media/codecs/mp3dec/Android.bp b/media/module/codecs/mp3dec/Android.bp
similarity index 100%
rename from media/codecs/mp3dec/Android.bp
rename to media/module/codecs/mp3dec/Android.bp
diff --git a/media/codecs/mp3dec/MODULE_LICENSE_APACHE2 b/media/module/codecs/mp3dec/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/codecs/mp3dec/MODULE_LICENSE_APACHE2
rename to media/module/codecs/mp3dec/MODULE_LICENSE_APACHE2
diff --git a/media/codecs/mp3dec/NOTICE b/media/module/codecs/mp3dec/NOTICE
similarity index 100%
rename from media/codecs/mp3dec/NOTICE
rename to media/module/codecs/mp3dec/NOTICE
diff --git a/media/codecs/mp3dec/TEST_MAPPING b/media/module/codecs/mp3dec/TEST_MAPPING
similarity index 100%
rename from media/codecs/mp3dec/TEST_MAPPING
rename to media/module/codecs/mp3dec/TEST_MAPPING
diff --git a/media/codecs/mp3dec/fuzzer/Android.bp b/media/module/codecs/mp3dec/fuzzer/Android.bp
similarity index 100%
rename from media/codecs/mp3dec/fuzzer/Android.bp
rename to media/module/codecs/mp3dec/fuzzer/Android.bp
diff --git a/media/codecs/mp3dec/fuzzer/README.md b/media/module/codecs/mp3dec/fuzzer/README.md
similarity index 100%
rename from media/codecs/mp3dec/fuzzer/README.md
rename to media/module/codecs/mp3dec/fuzzer/README.md
diff --git a/media/codecs/mp3dec/fuzzer/mp3_dec_fuzzer.cpp b/media/module/codecs/mp3dec/fuzzer/mp3_dec_fuzzer.cpp
similarity index 100%
rename from media/codecs/mp3dec/fuzzer/mp3_dec_fuzzer.cpp
rename to media/module/codecs/mp3dec/fuzzer/mp3_dec_fuzzer.cpp
diff --git a/media/codecs/mp3dec/include/mp3_decoder_selection.h b/media/module/codecs/mp3dec/include/mp3_decoder_selection.h
similarity index 100%
rename from media/codecs/mp3dec/include/mp3_decoder_selection.h
rename to media/module/codecs/mp3dec/include/mp3_decoder_selection.h
diff --git a/media/codecs/mp3dec/include/pvmp3_audio_type_defs.h b/media/module/codecs/mp3dec/include/pvmp3_audio_type_defs.h
similarity index 100%
rename from media/codecs/mp3dec/include/pvmp3_audio_type_defs.h
rename to media/module/codecs/mp3dec/include/pvmp3_audio_type_defs.h
diff --git a/media/codecs/mp3dec/include/pvmp3decoder_api.h b/media/module/codecs/mp3dec/include/pvmp3decoder_api.h
similarity index 100%
rename from media/codecs/mp3dec/include/pvmp3decoder_api.h
rename to media/module/codecs/mp3dec/include/pvmp3decoder_api.h
diff --git a/media/codecs/mp3dec/patent_disclaimer.txt b/media/module/codecs/mp3dec/patent_disclaimer.txt
similarity index 100%
rename from media/codecs/mp3dec/patent_disclaimer.txt
rename to media/module/codecs/mp3dec/patent_disclaimer.txt
diff --git a/media/codecs/mp3dec/src/asm/pvmp3_dct_16_gcc.s b/media/module/codecs/mp3dec/src/asm/pvmp3_dct_16_gcc.s
similarity index 100%
rename from media/codecs/mp3dec/src/asm/pvmp3_dct_16_gcc.s
rename to media/module/codecs/mp3dec/src/asm/pvmp3_dct_16_gcc.s
diff --git a/media/codecs/mp3dec/src/asm/pvmp3_dct_9_gcc.s b/media/module/codecs/mp3dec/src/asm/pvmp3_dct_9_gcc.s
similarity index 100%
rename from media/codecs/mp3dec/src/asm/pvmp3_dct_9_gcc.s
rename to media/module/codecs/mp3dec/src/asm/pvmp3_dct_9_gcc.s
diff --git a/media/codecs/mp3dec/src/asm/pvmp3_mdct_18_gcc.s b/media/module/codecs/mp3dec/src/asm/pvmp3_mdct_18_gcc.s
similarity index 100%
rename from media/codecs/mp3dec/src/asm/pvmp3_mdct_18_gcc.s
rename to media/module/codecs/mp3dec/src/asm/pvmp3_mdct_18_gcc.s
diff --git a/media/codecs/mp3dec/src/asm/pvmp3_polyphase_filter_window_gcc.s b/media/module/codecs/mp3dec/src/asm/pvmp3_polyphase_filter_window_gcc.s
similarity index 100%
rename from media/codecs/mp3dec/src/asm/pvmp3_polyphase_filter_window_gcc.s
rename to media/module/codecs/mp3dec/src/asm/pvmp3_polyphase_filter_window_gcc.s
diff --git a/media/codecs/mp3dec/src/mp3_mem_funcs.h b/media/module/codecs/mp3dec/src/mp3_mem_funcs.h
similarity index 100%
rename from media/codecs/mp3dec/src/mp3_mem_funcs.h
rename to media/module/codecs/mp3dec/src/mp3_mem_funcs.h
diff --git a/media/codecs/mp3dec/src/pv_mp3_huffman.h b/media/module/codecs/mp3dec/src/pv_mp3_huffman.h
similarity index 100%
rename from media/codecs/mp3dec/src/pv_mp3_huffman.h
rename to media/module/codecs/mp3dec/src/pv_mp3_huffman.h
diff --git a/media/codecs/mp3dec/src/pv_mp3dec_fxd_op.h b/media/module/codecs/mp3dec/src/pv_mp3dec_fxd_op.h
similarity index 100%
rename from media/codecs/mp3dec/src/pv_mp3dec_fxd_op.h
rename to media/module/codecs/mp3dec/src/pv_mp3dec_fxd_op.h
diff --git a/media/codecs/mp3dec/src/pv_mp3dec_fxd_op_arm.h b/media/module/codecs/mp3dec/src/pv_mp3dec_fxd_op_arm.h
similarity index 100%
rename from media/codecs/mp3dec/src/pv_mp3dec_fxd_op_arm.h
rename to media/module/codecs/mp3dec/src/pv_mp3dec_fxd_op_arm.h
diff --git a/media/codecs/mp3dec/src/pv_mp3dec_fxd_op_arm_gcc.h b/media/module/codecs/mp3dec/src/pv_mp3dec_fxd_op_arm_gcc.h
similarity index 100%
rename from media/codecs/mp3dec/src/pv_mp3dec_fxd_op_arm_gcc.h
rename to media/module/codecs/mp3dec/src/pv_mp3dec_fxd_op_arm_gcc.h
diff --git a/media/codecs/mp3dec/src/pv_mp3dec_fxd_op_c_equivalent.h b/media/module/codecs/mp3dec/src/pv_mp3dec_fxd_op_c_equivalent.h
similarity index 100%
rename from media/codecs/mp3dec/src/pv_mp3dec_fxd_op_c_equivalent.h
rename to media/module/codecs/mp3dec/src/pv_mp3dec_fxd_op_c_equivalent.h
diff --git a/media/codecs/mp3dec/src/pv_mp3dec_fxd_op_msc_evc.h b/media/module/codecs/mp3dec/src/pv_mp3dec_fxd_op_msc_evc.h
similarity index 100%
rename from media/codecs/mp3dec/src/pv_mp3dec_fxd_op_msc_evc.h
rename to media/module/codecs/mp3dec/src/pv_mp3dec_fxd_op_msc_evc.h
diff --git a/media/codecs/mp3dec/src/pvmp3_alias_reduction.cpp b/media/module/codecs/mp3dec/src/pvmp3_alias_reduction.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_alias_reduction.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_alias_reduction.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_alias_reduction.h b/media/module/codecs/mp3dec/src/pvmp3_alias_reduction.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_alias_reduction.h
rename to media/module/codecs/mp3dec/src/pvmp3_alias_reduction.h
diff --git a/media/codecs/mp3dec/src/pvmp3_crc.cpp b/media/module/codecs/mp3dec/src/pvmp3_crc.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_crc.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_crc.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_crc.h b/media/module/codecs/mp3dec/src/pvmp3_crc.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_crc.h
rename to media/module/codecs/mp3dec/src/pvmp3_crc.h
diff --git a/media/codecs/mp3dec/src/pvmp3_dct_16.cpp b/media/module/codecs/mp3dec/src/pvmp3_dct_16.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_dct_16.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_dct_16.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_dct_16.h b/media/module/codecs/mp3dec/src/pvmp3_dct_16.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_dct_16.h
rename to media/module/codecs/mp3dec/src/pvmp3_dct_16.h
diff --git a/media/codecs/mp3dec/src/pvmp3_dct_6.cpp b/media/module/codecs/mp3dec/src/pvmp3_dct_6.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_dct_6.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_dct_6.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_dct_9.cpp b/media/module/codecs/mp3dec/src/pvmp3_dct_9.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_dct_9.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_dct_9.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_dec_defs.h b/media/module/codecs/mp3dec/src/pvmp3_dec_defs.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_dec_defs.h
rename to media/module/codecs/mp3dec/src/pvmp3_dec_defs.h
diff --git a/media/codecs/mp3dec/src/pvmp3_decode_header.cpp b/media/module/codecs/mp3dec/src/pvmp3_decode_header.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_decode_header.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_decode_header.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_decode_header.h b/media/module/codecs/mp3dec/src/pvmp3_decode_header.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_decode_header.h
rename to media/module/codecs/mp3dec/src/pvmp3_decode_header.h
diff --git a/media/codecs/mp3dec/src/pvmp3_decode_huff_cw.cpp b/media/module/codecs/mp3dec/src/pvmp3_decode_huff_cw.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_decode_huff_cw.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_decode_huff_cw.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_decode_huff_cw.h b/media/module/codecs/mp3dec/src/pvmp3_decode_huff_cw.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_decode_huff_cw.h
rename to media/module/codecs/mp3dec/src/pvmp3_decode_huff_cw.h
diff --git a/media/codecs/mp3dec/src/pvmp3_dequantize_sample.cpp b/media/module/codecs/mp3dec/src/pvmp3_dequantize_sample.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_dequantize_sample.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_dequantize_sample.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_dequantize_sample.h b/media/module/codecs/mp3dec/src/pvmp3_dequantize_sample.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_dequantize_sample.h
rename to media/module/codecs/mp3dec/src/pvmp3_dequantize_sample.h
diff --git a/media/codecs/mp3dec/src/pvmp3_equalizer.cpp b/media/module/codecs/mp3dec/src/pvmp3_equalizer.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_equalizer.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_equalizer.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_equalizer.h b/media/module/codecs/mp3dec/src/pvmp3_equalizer.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_equalizer.h
rename to media/module/codecs/mp3dec/src/pvmp3_equalizer.h
diff --git a/media/codecs/mp3dec/src/pvmp3_framedecoder.cpp b/media/module/codecs/mp3dec/src/pvmp3_framedecoder.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_framedecoder.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_framedecoder.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_framedecoder.h b/media/module/codecs/mp3dec/src/pvmp3_framedecoder.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_framedecoder.h
rename to media/module/codecs/mp3dec/src/pvmp3_framedecoder.h
diff --git a/media/codecs/mp3dec/src/pvmp3_get_main_data_size.cpp b/media/module/codecs/mp3dec/src/pvmp3_get_main_data_size.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_get_main_data_size.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_get_main_data_size.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_get_main_data_size.h b/media/module/codecs/mp3dec/src/pvmp3_get_main_data_size.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_get_main_data_size.h
rename to media/module/codecs/mp3dec/src/pvmp3_get_main_data_size.h
diff --git a/media/codecs/mp3dec/src/pvmp3_get_scale_factors.cpp b/media/module/codecs/mp3dec/src/pvmp3_get_scale_factors.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_get_scale_factors.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_get_scale_factors.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_get_scale_factors.h b/media/module/codecs/mp3dec/src/pvmp3_get_scale_factors.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_get_scale_factors.h
rename to media/module/codecs/mp3dec/src/pvmp3_get_scale_factors.h
diff --git a/media/codecs/mp3dec/src/pvmp3_get_side_info.cpp b/media/module/codecs/mp3dec/src/pvmp3_get_side_info.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_get_side_info.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_get_side_info.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_get_side_info.h b/media/module/codecs/mp3dec/src/pvmp3_get_side_info.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_get_side_info.h
rename to media/module/codecs/mp3dec/src/pvmp3_get_side_info.h
diff --git a/media/codecs/mp3dec/src/pvmp3_getbits.cpp b/media/module/codecs/mp3dec/src/pvmp3_getbits.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_getbits.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_getbits.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_getbits.h b/media/module/codecs/mp3dec/src/pvmp3_getbits.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_getbits.h
rename to media/module/codecs/mp3dec/src/pvmp3_getbits.h
diff --git a/media/codecs/mp3dec/src/pvmp3_huffman_decoding.cpp b/media/module/codecs/mp3dec/src/pvmp3_huffman_decoding.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_huffman_decoding.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_huffman_decoding.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_huffman_parsing.cpp b/media/module/codecs/mp3dec/src/pvmp3_huffman_parsing.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_huffman_parsing.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_huffman_parsing.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_imdct_synth.cpp b/media/module/codecs/mp3dec/src/pvmp3_imdct_synth.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_imdct_synth.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_imdct_synth.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_imdct_synth.h b/media/module/codecs/mp3dec/src/pvmp3_imdct_synth.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_imdct_synth.h
rename to media/module/codecs/mp3dec/src/pvmp3_imdct_synth.h
diff --git a/media/codecs/mp3dec/src/pvmp3_mdct_18.cpp b/media/module/codecs/mp3dec/src/pvmp3_mdct_18.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_mdct_18.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_mdct_18.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_mdct_18.h b/media/module/codecs/mp3dec/src/pvmp3_mdct_18.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_mdct_18.h
rename to media/module/codecs/mp3dec/src/pvmp3_mdct_18.h
diff --git a/media/codecs/mp3dec/src/pvmp3_mdct_6.cpp b/media/module/codecs/mp3dec/src/pvmp3_mdct_6.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_mdct_6.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_mdct_6.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_mdct_6.h b/media/module/codecs/mp3dec/src/pvmp3_mdct_6.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_mdct_6.h
rename to media/module/codecs/mp3dec/src/pvmp3_mdct_6.h
diff --git a/media/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_data.cpp b/media/module/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_data.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_data.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_data.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_data.h b/media/module/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_data.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_data.h
rename to media/module/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_data.h
diff --git a/media/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_factors.cpp b/media/module/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_factors.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_factors.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_factors.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_factors.h b/media/module/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_factors.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_factors.h
rename to media/module/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_factors.h
diff --git a/media/codecs/mp3dec/src/pvmp3_mpeg2_stereo_proc.cpp b/media/module/codecs/mp3dec/src/pvmp3_mpeg2_stereo_proc.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_mpeg2_stereo_proc.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_mpeg2_stereo_proc.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_mpeg2_stereo_proc.h b/media/module/codecs/mp3dec/src/pvmp3_mpeg2_stereo_proc.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_mpeg2_stereo_proc.h
rename to media/module/codecs/mp3dec/src/pvmp3_mpeg2_stereo_proc.h
diff --git a/media/codecs/mp3dec/src/pvmp3_normalize.cpp b/media/module/codecs/mp3dec/src/pvmp3_normalize.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_normalize.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_normalize.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_normalize.h b/media/module/codecs/mp3dec/src/pvmp3_normalize.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_normalize.h
rename to media/module/codecs/mp3dec/src/pvmp3_normalize.h
diff --git a/media/codecs/mp3dec/src/pvmp3_poly_phase_synthesis.cpp b/media/module/codecs/mp3dec/src/pvmp3_poly_phase_synthesis.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_poly_phase_synthesis.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_poly_phase_synthesis.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_poly_phase_synthesis.h b/media/module/codecs/mp3dec/src/pvmp3_poly_phase_synthesis.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_poly_phase_synthesis.h
rename to media/module/codecs/mp3dec/src/pvmp3_poly_phase_synthesis.h
diff --git a/media/codecs/mp3dec/src/pvmp3_polyphase_filter_window.cpp b/media/module/codecs/mp3dec/src/pvmp3_polyphase_filter_window.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_polyphase_filter_window.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_polyphase_filter_window.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_polyphase_filter_window.h b/media/module/codecs/mp3dec/src/pvmp3_polyphase_filter_window.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_polyphase_filter_window.h
rename to media/module/codecs/mp3dec/src/pvmp3_polyphase_filter_window.h
diff --git a/media/codecs/mp3dec/src/pvmp3_reorder.cpp b/media/module/codecs/mp3dec/src/pvmp3_reorder.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_reorder.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_reorder.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_reorder.h b/media/module/codecs/mp3dec/src/pvmp3_reorder.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_reorder.h
rename to media/module/codecs/mp3dec/src/pvmp3_reorder.h
diff --git a/media/codecs/mp3dec/src/pvmp3_seek_synch.cpp b/media/module/codecs/mp3dec/src/pvmp3_seek_synch.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_seek_synch.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_seek_synch.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_seek_synch.h b/media/module/codecs/mp3dec/src/pvmp3_seek_synch.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_seek_synch.h
rename to media/module/codecs/mp3dec/src/pvmp3_seek_synch.h
diff --git a/media/codecs/mp3dec/src/pvmp3_stereo_proc.cpp b/media/module/codecs/mp3dec/src/pvmp3_stereo_proc.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_stereo_proc.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_stereo_proc.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_stereo_proc.h b/media/module/codecs/mp3dec/src/pvmp3_stereo_proc.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_stereo_proc.h
rename to media/module/codecs/mp3dec/src/pvmp3_stereo_proc.h
diff --git a/media/codecs/mp3dec/src/pvmp3_tables.cpp b/media/module/codecs/mp3dec/src/pvmp3_tables.cpp
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_tables.cpp
rename to media/module/codecs/mp3dec/src/pvmp3_tables.cpp
diff --git a/media/codecs/mp3dec/src/pvmp3_tables.h b/media/module/codecs/mp3dec/src/pvmp3_tables.h
similarity index 100%
rename from media/codecs/mp3dec/src/pvmp3_tables.h
rename to media/module/codecs/mp3dec/src/pvmp3_tables.h
diff --git a/media/codecs/mp3dec/src/s_huffcodetab.h b/media/module/codecs/mp3dec/src/s_huffcodetab.h
similarity index 100%
rename from media/codecs/mp3dec/src/s_huffcodetab.h
rename to media/module/codecs/mp3dec/src/s_huffcodetab.h
diff --git a/media/codecs/mp3dec/src/s_mp3bits.h b/media/module/codecs/mp3dec/src/s_mp3bits.h
similarity index 100%
rename from media/codecs/mp3dec/src/s_mp3bits.h
rename to media/module/codecs/mp3dec/src/s_mp3bits.h
diff --git a/media/codecs/mp3dec/src/s_tmp3dec_chan.h b/media/module/codecs/mp3dec/src/s_tmp3dec_chan.h
similarity index 100%
rename from media/codecs/mp3dec/src/s_tmp3dec_chan.h
rename to media/module/codecs/mp3dec/src/s_tmp3dec_chan.h
diff --git a/media/codecs/mp3dec/src/s_tmp3dec_file.h b/media/module/codecs/mp3dec/src/s_tmp3dec_file.h
similarity index 100%
rename from media/codecs/mp3dec/src/s_tmp3dec_file.h
rename to media/module/codecs/mp3dec/src/s_tmp3dec_file.h
diff --git a/media/codecs/mp3dec/test/Android.bp b/media/module/codecs/mp3dec/test/Android.bp
similarity index 100%
rename from media/codecs/mp3dec/test/Android.bp
rename to media/module/codecs/mp3dec/test/Android.bp
diff --git a/media/codecs/mp3dec/test/AndroidTest.xml b/media/module/codecs/mp3dec/test/AndroidTest.xml
similarity index 100%
rename from media/codecs/mp3dec/test/AndroidTest.xml
rename to media/module/codecs/mp3dec/test/AndroidTest.xml
diff --git a/media/codecs/mp3dec/test/Mp3DecoderTest.cpp b/media/module/codecs/mp3dec/test/Mp3DecoderTest.cpp
similarity index 89%
rename from media/codecs/mp3dec/test/Mp3DecoderTest.cpp
rename to media/module/codecs/mp3dec/test/Mp3DecoderTest.cpp
index 91326a8..88e9eae 100644
--- a/media/codecs/mp3dec/test/Mp3DecoderTest.cpp
+++ b/media/module/codecs/mp3dec/test/Mp3DecoderTest.cpp
@@ -20,6 +20,7 @@
#include <utils/Log.h>
#include <audio_utils/sndfile.h>
+#include <memory>
#include <stdio.h>
#include "mp3reader.h"
@@ -99,27 +100,23 @@
TEST_F(Mp3DecoderTest, MultiCreateMp3DecoderTest) {
size_t memRequirements = pvmp3_decoderMemRequirements();
ASSERT_NE(memRequirements, 0) << "Failed to get the memory requirement size";
- void *decoderBuf = malloc(memRequirements);
+ unique_ptr<char[]> decoderBuf(new char[memRequirements]);
ASSERT_NE(decoderBuf, nullptr)
<< "Failed to allocate decoder memory of size " << memRequirements;
for (int count = 0; count < kMaxCount; count++) {
- pvmp3_InitDecoder(mConfig, decoderBuf);
+ pvmp3_InitDecoder(mConfig, (void*)decoderBuf.get());
ALOGV("Decoder created successfully");
}
- if (decoderBuf) {
- free(decoderBuf);
- decoderBuf = nullptr;
- }
}
TEST_P(Mp3DecoderTest, DecodeTest) {
size_t memRequirements = pvmp3_decoderMemRequirements();
ASSERT_NE(memRequirements, 0) << "Failed to get the memory requirement size";
- void *decoderBuf = malloc(memRequirements);
+ unique_ptr<char[]> decoderBuf(new char[memRequirements]);
ASSERT_NE(decoderBuf, nullptr)
<< "Failed to allocate decoder memory of size " << memRequirements;
- pvmp3_InitDecoder(mConfig, decoderBuf);
+ pvmp3_InitDecoder(mConfig, (void*)decoderBuf.get());
ALOGV("Decoder created successfully");
string inputFile = gEnv->getRes() + GetParam();
bool status = mMp3Reader.init(inputFile.c_str());
@@ -130,27 +127,23 @@
SNDFILE *outFileHandle = openOutputFile(&sfInfo);
ASSERT_NE(outFileHandle, nullptr) << "Error opening output file for writing decoded output";
- ERROR_CODE decoderErr = DecodeFrames(decoderBuf, outFileHandle, sfInfo);
+ ERROR_CODE decoderErr = DecodeFrames((void*)decoderBuf.get(), outFileHandle, sfInfo);
ASSERT_EQ(decoderErr, NO_DECODING_ERROR) << "Failed to decode the frames";
ASSERT_EQ(sfInfo.channels, mConfig->num_channels) << "Number of channels does not match";
ASSERT_EQ(sfInfo.samplerate, mConfig->samplingRate) << "Sample rate does not match";
mMp3Reader.close();
sf_close(outFileHandle);
- if (decoderBuf) {
- free(decoderBuf);
- decoderBuf = nullptr;
- }
}
TEST_P(Mp3DecoderTest, ResetDecoderTest) {
size_t memRequirements = pvmp3_decoderMemRequirements();
ASSERT_NE(memRequirements, 0) << "Failed to get the memory requirement size";
- void *decoderBuf = malloc(memRequirements);
+ unique_ptr<char[]> decoderBuf(new char[memRequirements]);
ASSERT_NE(decoderBuf, nullptr)
<< "Failed to allocate decoder memory of size " << memRequirements;
- pvmp3_InitDecoder(mConfig, decoderBuf);
+ pvmp3_InitDecoder(mConfig, (void*)decoderBuf.get());
ALOGV("Decoder created successfully.");
string inputFile = gEnv->getRes() + GetParam();
bool status = mMp3Reader.init(inputFile.c_str());
@@ -162,24 +155,20 @@
ASSERT_NE(outFileHandle, nullptr) << "Error opening output file for writing decoded output";
ERROR_CODE decoderErr;
- decoderErr = DecodeFrames(decoderBuf, outFileHandle, sfInfo, kNumFrameReset);
+ decoderErr = DecodeFrames((void*)decoderBuf.get(), outFileHandle, sfInfo, kNumFrameReset);
ASSERT_EQ(decoderErr, NO_DECODING_ERROR) << "Failed to decode the frames";
ASSERT_EQ(sfInfo.channels, mConfig->num_channels) << "Number of channels does not match";
ASSERT_EQ(sfInfo.samplerate, mConfig->samplingRate) << "Sample rate does not match";
- pvmp3_resetDecoder(decoderBuf);
+ pvmp3_resetDecoder((void*)decoderBuf.get());
// Decode the same file.
- decoderErr = DecodeFrames(decoderBuf, outFileHandle, sfInfo);
+ decoderErr = DecodeFrames((void*)decoderBuf.get(), outFileHandle, sfInfo);
ASSERT_EQ(decoderErr, NO_DECODING_ERROR) << "Failed to decode the frames";
ASSERT_EQ(sfInfo.channels, mConfig->num_channels) << "Number of channels does not match";
ASSERT_EQ(sfInfo.samplerate, mConfig->samplingRate) << "Sample rate does not match";
mMp3Reader.close();
sf_close(outFileHandle);
- if (decoderBuf) {
- free(decoderBuf);
- decoderBuf = nullptr;
- }
}
INSTANTIATE_TEST_SUITE_P(Mp3DecoderTestAll, Mp3DecoderTest,
diff --git a/media/codecs/mp3dec/test/Mp3DecoderTestEnvironment.h b/media/module/codecs/mp3dec/test/Mp3DecoderTestEnvironment.h
similarity index 100%
rename from media/codecs/mp3dec/test/Mp3DecoderTestEnvironment.h
rename to media/module/codecs/mp3dec/test/Mp3DecoderTestEnvironment.h
diff --git a/media/codecs/mp3dec/test/README.md b/media/module/codecs/mp3dec/test/README.md
similarity index 100%
rename from media/codecs/mp3dec/test/README.md
rename to media/module/codecs/mp3dec/test/README.md
diff --git a/media/codecs/mp3dec/test/mp3dec_test.cpp b/media/module/codecs/mp3dec/test/mp3dec_test.cpp
similarity index 100%
rename from media/codecs/mp3dec/test/mp3dec_test.cpp
rename to media/module/codecs/mp3dec/test/mp3dec_test.cpp
diff --git a/media/codecs/mp3dec/test/mp3reader.cpp b/media/module/codecs/mp3dec/test/mp3reader.cpp
similarity index 100%
rename from media/codecs/mp3dec/test/mp3reader.cpp
rename to media/module/codecs/mp3dec/test/mp3reader.cpp
diff --git a/media/codecs/mp3dec/test/mp3reader.h b/media/module/codecs/mp3dec/test/mp3reader.h
similarity index 100%
rename from media/codecs/mp3dec/test/mp3reader.h
rename to media/module/codecs/mp3dec/test/mp3reader.h
diff --git a/services/mediacodec/registrant/Android.bp b/media/module/codecserviceregistrant/Android.bp
similarity index 95%
rename from services/mediacodec/registrant/Android.bp
rename to media/module/codecserviceregistrant/Android.bp
index 12cc32a..5637b37 100644
--- a/services/mediacodec/registrant/Android.bp
+++ b/media/module/codecserviceregistrant/Android.bp
@@ -4,7 +4,6 @@
// all of the 'license_kinds' from "frameworks_av_services_mediacodec_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["frameworks_av_services_mediacodec_license"],
}
cc_library {
diff --git a/services/mediacodec/registrant/CodecServiceRegistrant.cpp b/media/module/codecserviceregistrant/CodecServiceRegistrant.cpp
similarity index 100%
rename from services/mediacodec/registrant/CodecServiceRegistrant.cpp
rename to media/module/codecserviceregistrant/CodecServiceRegistrant.cpp
diff --git a/services/mediacodec/registrant/fuzzer/Android.bp b/media/module/codecserviceregistrant/fuzzer/Android.bp
similarity index 94%
rename from services/mediacodec/registrant/fuzzer/Android.bp
rename to media/module/codecserviceregistrant/fuzzer/Android.bp
index 43afbf1..0b9affd 100644
--- a/services/mediacodec/registrant/fuzzer/Android.bp
+++ b/media/module/codecserviceregistrant/fuzzer/Android.bp
@@ -20,7 +20,6 @@
// all of the 'license_kinds' from "frameworks_av_services_mediacodec_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["frameworks_av_services_mediacodec_license"],
}
cc_fuzz {
diff --git a/services/mediacodec/registrant/fuzzer/README.md b/media/module/codecserviceregistrant/fuzzer/README.md
similarity index 100%
rename from services/mediacodec/registrant/fuzzer/README.md
rename to media/module/codecserviceregistrant/fuzzer/README.md
diff --git a/services/mediacodec/registrant/fuzzer/codecServiceRegistrant_fuzzer.cpp b/media/module/codecserviceregistrant/fuzzer/codecServiceRegistrant_fuzzer.cpp
similarity index 100%
rename from services/mediacodec/registrant/fuzzer/codecServiceRegistrant_fuzzer.cpp
rename to media/module/codecserviceregistrant/fuzzer/codecServiceRegistrant_fuzzer.cpp
diff --git a/media/module/esds/Android.bp b/media/module/esds/Android.bp
new file mode 100644
index 0000000..272d4d7
--- /dev/null
+++ b/media/module/esds/Android.bp
@@ -0,0 +1,44 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_av_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_av_license"],
+}
+
+cc_library_static {
+ name: "libstagefright_esds",
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.media",
+ ],
+ min_sdk_version: "29",
+
+ export_include_dirs: ["include"],
+
+ local_include_dirs: ["include"],
+
+ srcs: ["ESDS.cpp"],
+
+ cflags: [
+ "-Werror",
+ "-Wall",
+ ],
+ sanitize: {
+ misc_undefined: [
+ "signed-integer-overflow",
+ ],
+ cfi: true,
+ },
+ shared_libs: [
+ "libstagefright_foundation",
+ "libutils"
+ ],
+ host_supported: true,
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
+}
diff --git a/media/libstagefright/ESDS.cpp b/media/module/esds/ESDS.cpp
similarity index 99%
rename from media/libstagefright/ESDS.cpp
rename to media/module/esds/ESDS.cpp
index ea059e8..906250b 100644
--- a/media/libstagefright/ESDS.cpp
+++ b/media/module/esds/ESDS.cpp
@@ -20,7 +20,7 @@
#include <media/stagefright/foundation/ByteUtils.h>
-#include "include/ESDS.h"
+#include <media/esds/ESDS.h>
#include <string.h>
diff --git a/media/module/esds/TEST_MAPPING b/media/module/esds/TEST_MAPPING
new file mode 100644
index 0000000..9368b6d
--- /dev/null
+++ b/media/module/esds/TEST_MAPPING
@@ -0,0 +1,9 @@
+// mappings for frameworks/av/media/module/esds
+{
+ // tests which require dynamic content
+ // invoke with: atest -- --enable-module-dynamic-download=true
+ // TODO(b/148094059): unit tests not allowed to download content
+ "dynamic-presubmit": [
+ { "name": "ESDSTest" }
+ ]
+}
diff --git a/media/libstagefright/include/ESDS.h b/media/module/esds/include/media/esds/ESDS.h
similarity index 100%
rename from media/libstagefright/include/ESDS.h
rename to media/module/esds/include/media/esds/ESDS.h
diff --git a/media/libstagefright/tests/ESDS/Android.bp b/media/module/esds/tests/Android.bp
similarity index 93%
rename from media/libstagefright/tests/ESDS/Android.bp
rename to media/module/esds/tests/Android.bp
index 04e9b29..aea611e 100644
--- a/media/libstagefright/tests/ESDS/Android.bp
+++ b/media/module/esds/tests/Android.bp
@@ -20,9 +20,6 @@
// all of the 'license_kinds' from "frameworks_av_media_libstagefright_tests_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: [
- "frameworks_av_media_libstagefright_tests_license",
- ],
}
cc_test {
diff --git a/media/libstagefright/tests/ESDS/AndroidTest.xml b/media/module/esds/tests/AndroidTest.xml
similarity index 100%
rename from media/libstagefright/tests/ESDS/AndroidTest.xml
rename to media/module/esds/tests/AndroidTest.xml
diff --git a/media/libstagefright/tests/ESDS/ESDSTest.cpp b/media/module/esds/tests/ESDSTest.cpp
similarity index 96%
rename from media/libstagefright/tests/ESDS/ESDSTest.cpp
rename to media/module/esds/tests/ESDSTest.cpp
index 101e00c..33bdcac 100644
--- a/media/libstagefright/tests/ESDS/ESDSTest.cpp
+++ b/media/module/esds/tests/ESDSTest.cpp
@@ -21,8 +21,9 @@
#include <stdio.h>
#include <string.h>
#include <fstream>
+#include <memory>
-#include <ESDS.h>
+#include <media/esds/ESDS.h>
#include <binder/ProcessState.h>
#include <datasource/FileSource.h>
#include <media/stagefright/MediaExtractorFactory.h>
@@ -121,18 +122,16 @@
};
TEST_P(ESDSUnitTest, InvalidDataTest) {
- void *invalidData = calloc(mESDSSize, 1);
+ std::unique_ptr<char[]> invalidData(new char[mESDSSize]());
ASSERT_NE(invalidData, nullptr) << "Unable to allocate memory";
- ESDS esds(invalidData, mESDSSize);
- free(invalidData);
+ ESDS esds((void*)invalidData.get(), mESDSSize);
ASSERT_NE(esds.InitCheck(), OK) << "invalid ESDS data accepted";
}
TEST(ESDSSanityUnitTest, ConstructorSanityTest) {
- void *invalidData = malloc(1);
+ std::unique_ptr<char[]> invalidData(new char[1]());
ASSERT_NE(invalidData, nullptr) << "Unable to allocate memory";
- ESDS esds_zero(invalidData, 0);
- free(invalidData);
+ ESDS esds_zero((void*)invalidData.get(), 0);
ASSERT_NE(esds_zero.InitCheck(), OK) << "invalid ESDS data accepted";
ESDS esds_null(NULL, 0);
diff --git a/media/libstagefright/tests/ESDS/ESDSTestEnvironment.h b/media/module/esds/tests/ESDSTestEnvironment.h
similarity index 100%
rename from media/libstagefright/tests/ESDS/ESDSTestEnvironment.h
rename to media/module/esds/tests/ESDSTestEnvironment.h
diff --git a/media/libstagefright/tests/ESDS/README.md b/media/module/esds/tests/README.md
similarity index 100%
rename from media/libstagefright/tests/ESDS/README.md
rename to media/module/esds/tests/README.md
diff --git a/media/extractors/Android.bp b/media/module/extractors/Android.bp
similarity index 100%
rename from media/extractors/Android.bp
rename to media/module/extractors/Android.bp
diff --git a/media/extractors/TEST_MAPPING b/media/module/extractors/TEST_MAPPING
similarity index 100%
rename from media/extractors/TEST_MAPPING
rename to media/module/extractors/TEST_MAPPING
diff --git a/media/extractors/aac/AACExtractor.cpp b/media/module/extractors/aac/AACExtractor.cpp
similarity index 98%
rename from media/extractors/aac/AACExtractor.cpp
rename to media/module/extractors/aac/AACExtractor.cpp
index 2fc4584..a44fb61 100644
--- a/media/extractors/aac/AACExtractor.cpp
+++ b/media/module/extractors/aac/AACExtractor.cpp
@@ -310,9 +310,9 @@
return AMEDIA_ERROR_END_OF_STREAM;
}
- MediaBufferHelper *buffer;
+ MediaBufferHelper *buffer = nullptr;
status_t err = mBufferGroup->acquire_buffer(&buffer);
- if (err != OK) {
+ if (err != OK || buffer == nullptr) {
return AMEDIA_ERROR_UNKNOWN;
}
diff --git a/media/extractors/aac/Android.bp b/media/module/extractors/aac/Android.bp
similarity index 100%
rename from media/extractors/aac/Android.bp
rename to media/module/extractors/aac/Android.bp
diff --git a/media/extractors/aac/MODULE_LICENSE_APACHE2 b/media/module/extractors/aac/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/extractors/aac/MODULE_LICENSE_APACHE2
rename to media/module/extractors/aac/MODULE_LICENSE_APACHE2
diff --git a/media/extractors/aac/NOTICE b/media/module/extractors/aac/NOTICE
similarity index 100%
rename from media/extractors/aac/NOTICE
rename to media/module/extractors/aac/NOTICE
diff --git a/media/extractors/aac/exports.lds b/media/module/extractors/aac/exports.lds
similarity index 100%
rename from media/extractors/aac/exports.lds
rename to media/module/extractors/aac/exports.lds
diff --git a/media/extractors/aac/include/AACExtractor.h b/media/module/extractors/aac/include/AACExtractor.h
similarity index 100%
rename from media/extractors/aac/include/AACExtractor.h
rename to media/module/extractors/aac/include/AACExtractor.h
diff --git a/media/extractors/amr/AMRExtractor.cpp b/media/module/extractors/amr/AMRExtractor.cpp
similarity index 98%
rename from media/extractors/amr/AMRExtractor.cpp
rename to media/module/extractors/amr/AMRExtractor.cpp
index e26ff0a..b0f69ce 100644
--- a/media/extractors/amr/AMRExtractor.cpp
+++ b/media/module/extractors/amr/AMRExtractor.cpp
@@ -341,9 +341,9 @@
return AMEDIA_ERROR_MALFORMED;
}
- MediaBufferHelper *buffer;
+ MediaBufferHelper *buffer = nullptr;
status_t err = mBufferGroup->acquire_buffer(&buffer);
- if (err != OK) {
+ if (err != OK || buffer == nullptr) {
return AMEDIA_ERROR_UNKNOWN;
}
diff --git a/media/extractors/amr/Android.bp b/media/module/extractors/amr/Android.bp
similarity index 100%
rename from media/extractors/amr/Android.bp
rename to media/module/extractors/amr/Android.bp
diff --git a/media/extractors/amr/MODULE_LICENSE_APACHE2 b/media/module/extractors/amr/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/extractors/amr/MODULE_LICENSE_APACHE2
rename to media/module/extractors/amr/MODULE_LICENSE_APACHE2
diff --git a/media/extractors/amr/NOTICE b/media/module/extractors/amr/NOTICE
similarity index 100%
rename from media/extractors/amr/NOTICE
rename to media/module/extractors/amr/NOTICE
diff --git a/media/extractors/amr/exports.lds b/media/module/extractors/amr/exports.lds
similarity index 100%
rename from media/extractors/amr/exports.lds
rename to media/module/extractors/amr/exports.lds
diff --git a/media/extractors/amr/include/AMRExtractor.h b/media/module/extractors/amr/include/AMRExtractor.h
similarity index 100%
rename from media/extractors/amr/include/AMRExtractor.h
rename to media/module/extractors/amr/include/AMRExtractor.h
diff --git a/media/extractors/flac/Android.bp b/media/module/extractors/flac/Android.bp
similarity index 100%
rename from media/extractors/flac/Android.bp
rename to media/module/extractors/flac/Android.bp
diff --git a/media/extractors/flac/FLACExtractor.cpp b/media/module/extractors/flac/FLACExtractor.cpp
similarity index 99%
rename from media/extractors/flac/FLACExtractor.cpp
rename to media/module/extractors/flac/FLACExtractor.cpp
index ec7cb24..2434e41 100644
--- a/media/extractors/flac/FLACExtractor.cpp
+++ b/media/module/extractors/flac/FLACExtractor.cpp
@@ -614,9 +614,9 @@
}
// acquire a media buffer
CHECK(mGroup != NULL);
- MediaBufferHelper *buffer;
+ MediaBufferHelper *buffer = nullptr;
status_t err = mGroup->acquire_buffer(&buffer);
- if (err != OK) {
+ if (err != OK || buffer == nullptr) {
return NULL;
}
const size_t bufferSize = blocksize * getChannels() * getOutputSampleSize();
diff --git a/media/extractors/flac/MODULE_LICENSE_APACHE2 b/media/module/extractors/flac/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/extractors/flac/MODULE_LICENSE_APACHE2
rename to media/module/extractors/flac/MODULE_LICENSE_APACHE2
diff --git a/media/extractors/flac/NOTICE b/media/module/extractors/flac/NOTICE
similarity index 100%
rename from media/extractors/flac/NOTICE
rename to media/module/extractors/flac/NOTICE
diff --git a/media/extractors/flac/exports.lds b/media/module/extractors/flac/exports.lds
similarity index 100%
rename from media/extractors/flac/exports.lds
rename to media/module/extractors/flac/exports.lds
diff --git a/media/extractors/flac/include/FLACExtractor.h b/media/module/extractors/flac/include/FLACExtractor.h
similarity index 100%
rename from media/extractors/flac/include/FLACExtractor.h
rename to media/module/extractors/flac/include/FLACExtractor.h
diff --git a/media/extractors/fuzzers/Android.bp b/media/module/extractors/fuzzers/Android.bp
similarity index 99%
rename from media/extractors/fuzzers/Android.bp
rename to media/module/extractors/fuzzers/Android.bp
index 490e195..b3e34d2 100644
--- a/media/extractors/fuzzers/Android.bp
+++ b/media/module/extractors/fuzzers/Android.bp
@@ -173,7 +173,7 @@
],
static_libs: [
- "libwebm",
+ "libwebm_mkvparser",
"libstagefright_flacdec",
"libstagefright_metadatautils",
"libmkvextractor",
diff --git a/media/extractors/fuzzers/ExtractorFuzzerBase.cpp b/media/module/extractors/fuzzers/ExtractorFuzzerBase.cpp
similarity index 100%
rename from media/extractors/fuzzers/ExtractorFuzzerBase.cpp
rename to media/module/extractors/fuzzers/ExtractorFuzzerBase.cpp
diff --git a/media/extractors/fuzzers/README.md b/media/module/extractors/fuzzers/README.md
similarity index 100%
rename from media/extractors/fuzzers/README.md
rename to media/module/extractors/fuzzers/README.md
diff --git a/media/extractors/fuzzers/aac_extractor_fuzzer.cpp b/media/module/extractors/fuzzers/aac_extractor_fuzzer.cpp
similarity index 100%
rename from media/extractors/fuzzers/aac_extractor_fuzzer.cpp
rename to media/module/extractors/fuzzers/aac_extractor_fuzzer.cpp
diff --git a/media/extractors/fuzzers/amr_extractor_fuzzer.cpp b/media/module/extractors/fuzzers/amr_extractor_fuzzer.cpp
similarity index 100%
rename from media/extractors/fuzzers/amr_extractor_fuzzer.cpp
rename to media/module/extractors/fuzzers/amr_extractor_fuzzer.cpp
diff --git a/media/extractors/fuzzers/amr_extractor_fuzzer.dict b/media/module/extractors/fuzzers/amr_extractor_fuzzer.dict
similarity index 100%
rename from media/extractors/fuzzers/amr_extractor_fuzzer.dict
rename to media/module/extractors/fuzzers/amr_extractor_fuzzer.dict
diff --git a/media/extractors/fuzzers/flac_extractor_fuzzer.cpp b/media/module/extractors/fuzzers/flac_extractor_fuzzer.cpp
similarity index 100%
rename from media/extractors/fuzzers/flac_extractor_fuzzer.cpp
rename to media/module/extractors/fuzzers/flac_extractor_fuzzer.cpp
diff --git a/media/extractors/fuzzers/flac_extractor_fuzzer.dict b/media/module/extractors/fuzzers/flac_extractor_fuzzer.dict
similarity index 100%
rename from media/extractors/fuzzers/flac_extractor_fuzzer.dict
rename to media/module/extractors/fuzzers/flac_extractor_fuzzer.dict
diff --git a/media/extractors/fuzzers/include/ExtractorFuzzerBase.h b/media/module/extractors/fuzzers/include/ExtractorFuzzerBase.h
similarity index 100%
rename from media/extractors/fuzzers/include/ExtractorFuzzerBase.h
rename to media/module/extractors/fuzzers/include/ExtractorFuzzerBase.h
diff --git a/media/extractors/fuzzers/midi_extractor_fuzzer.cpp b/media/module/extractors/fuzzers/midi_extractor_fuzzer.cpp
similarity index 100%
rename from media/extractors/fuzzers/midi_extractor_fuzzer.cpp
rename to media/module/extractors/fuzzers/midi_extractor_fuzzer.cpp
diff --git a/media/extractors/fuzzers/midi_extractor_fuzzer.dict b/media/module/extractors/fuzzers/midi_extractor_fuzzer.dict
similarity index 100%
rename from media/extractors/fuzzers/midi_extractor_fuzzer.dict
rename to media/module/extractors/fuzzers/midi_extractor_fuzzer.dict
diff --git a/media/extractors/fuzzers/mkv_extractor_fuzzer.cpp b/media/module/extractors/fuzzers/mkv_extractor_fuzzer.cpp
similarity index 100%
rename from media/extractors/fuzzers/mkv_extractor_fuzzer.cpp
rename to media/module/extractors/fuzzers/mkv_extractor_fuzzer.cpp
diff --git a/media/extractors/fuzzers/mkv_extractor_fuzzer.dict b/media/module/extractors/fuzzers/mkv_extractor_fuzzer.dict
similarity index 100%
rename from media/extractors/fuzzers/mkv_extractor_fuzzer.dict
rename to media/module/extractors/fuzzers/mkv_extractor_fuzzer.dict
diff --git a/media/extractors/fuzzers/mp3_extractor_fuzzer.cpp b/media/module/extractors/fuzzers/mp3_extractor_fuzzer.cpp
similarity index 100%
rename from media/extractors/fuzzers/mp3_extractor_fuzzer.cpp
rename to media/module/extractors/fuzzers/mp3_extractor_fuzzer.cpp
diff --git a/media/extractors/fuzzers/mp4_extractor_fuzzer.cpp b/media/module/extractors/fuzzers/mp4_extractor_fuzzer.cpp
similarity index 100%
rename from media/extractors/fuzzers/mp4_extractor_fuzzer.cpp
rename to media/module/extractors/fuzzers/mp4_extractor_fuzzer.cpp
diff --git a/media/extractors/fuzzers/mp4_extractor_fuzzer.dict b/media/module/extractors/fuzzers/mp4_extractor_fuzzer.dict
similarity index 100%
rename from media/extractors/fuzzers/mp4_extractor_fuzzer.dict
rename to media/module/extractors/fuzzers/mp4_extractor_fuzzer.dict
diff --git a/media/extractors/fuzzers/mpeg2_extractor_fuzzer.cpp b/media/module/extractors/fuzzers/mpeg2_extractor_fuzzer.cpp
similarity index 100%
rename from media/extractors/fuzzers/mpeg2_extractor_fuzzer.cpp
rename to media/module/extractors/fuzzers/mpeg2_extractor_fuzzer.cpp
diff --git a/media/extractors/fuzzers/mpeg2ps_extractor_fuzzer.dict b/media/module/extractors/fuzzers/mpeg2ps_extractor_fuzzer.dict
similarity index 100%
rename from media/extractors/fuzzers/mpeg2ps_extractor_fuzzer.dict
rename to media/module/extractors/fuzzers/mpeg2ps_extractor_fuzzer.dict
diff --git a/media/extractors/fuzzers/mpeg2ts_extractor_fuzzer.dict b/media/module/extractors/fuzzers/mpeg2ts_extractor_fuzzer.dict
similarity index 100%
rename from media/extractors/fuzzers/mpeg2ts_extractor_fuzzer.dict
rename to media/module/extractors/fuzzers/mpeg2ts_extractor_fuzzer.dict
diff --git a/media/extractors/fuzzers/ogg_extractor_fuzzer.cpp b/media/module/extractors/fuzzers/ogg_extractor_fuzzer.cpp
similarity index 100%
rename from media/extractors/fuzzers/ogg_extractor_fuzzer.cpp
rename to media/module/extractors/fuzzers/ogg_extractor_fuzzer.cpp
diff --git a/media/extractors/fuzzers/ogg_extractor_fuzzer.dict b/media/module/extractors/fuzzers/ogg_extractor_fuzzer.dict
similarity index 100%
rename from media/extractors/fuzzers/ogg_extractor_fuzzer.dict
rename to media/module/extractors/fuzzers/ogg_extractor_fuzzer.dict
diff --git a/media/extractors/fuzzers/wav_extractor_fuzzer.cpp b/media/module/extractors/fuzzers/wav_extractor_fuzzer.cpp
similarity index 100%
rename from media/extractors/fuzzers/wav_extractor_fuzzer.cpp
rename to media/module/extractors/fuzzers/wav_extractor_fuzzer.cpp
diff --git a/media/extractors/midi/Android.bp b/media/module/extractors/midi/Android.bp
similarity index 100%
rename from media/extractors/midi/Android.bp
rename to media/module/extractors/midi/Android.bp
diff --git a/media/extractors/midi/MODULE_LICENSE_APACHE2 b/media/module/extractors/midi/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/extractors/midi/MODULE_LICENSE_APACHE2
rename to media/module/extractors/midi/MODULE_LICENSE_APACHE2
diff --git a/media/extractors/midi/MidiExtractor.cpp b/media/module/extractors/midi/MidiExtractor.cpp
similarity index 98%
rename from media/extractors/midi/MidiExtractor.cpp
rename to media/module/extractors/midi/MidiExtractor.cpp
index d0efb2f..167cc40 100644
--- a/media/extractors/midi/MidiExtractor.cpp
+++ b/media/module/extractors/midi/MidiExtractor.cpp
@@ -240,9 +240,9 @@
if ((state == EAS_STATE_STOPPED) || (state == EAS_STATE_ERROR)) {
return NULL;
}
- MediaBufferHelper *buffer;
+ MediaBufferHelper *buffer = nullptr;
status_t err = mGroup->acquire_buffer(&buffer);
- if (err != OK) {
+ if (err != OK || buffer == nullptr) {
ALOGE("readBuffer: no buffer");
return NULL;
}
diff --git a/media/extractors/midi/NOTICE b/media/module/extractors/midi/NOTICE
similarity index 100%
rename from media/extractors/midi/NOTICE
rename to media/module/extractors/midi/NOTICE
diff --git a/media/extractors/midi/exports.lds b/media/module/extractors/midi/exports.lds
similarity index 100%
rename from media/extractors/midi/exports.lds
rename to media/module/extractors/midi/exports.lds
diff --git a/media/extractors/midi/include/MidiExtractor.h b/media/module/extractors/midi/include/MidiExtractor.h
similarity index 100%
rename from media/extractors/midi/include/MidiExtractor.h
rename to media/module/extractors/midi/include/MidiExtractor.h
diff --git a/media/extractors/mkv/Android.bp b/media/module/extractors/mkv/Android.bp
similarity index 96%
rename from media/extractors/mkv/Android.bp
rename to media/module/extractors/mkv/Android.bp
index 98ce305..c4b67eb 100644
--- a/media/extractors/mkv/Android.bp
+++ b/media/module/extractors/mkv/Android.bp
@@ -33,7 +33,7 @@
"libstagefright_foundation_colorutils_ndk", // for mainline-safe ColorUtils
"libstagefright_foundation",
"libstagefright_metadatautils",
- "libwebm",
+ "libwebm_mkvparser",
"libutils",
],
diff --git a/media/extractors/mkv/MODULE_LICENSE_APACHE2 b/media/module/extractors/mkv/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/extractors/mkv/MODULE_LICENSE_APACHE2
rename to media/module/extractors/mkv/MODULE_LICENSE_APACHE2
diff --git a/media/extractors/mkv/MatroskaExtractor.cpp b/media/module/extractors/mkv/MatroskaExtractor.cpp
similarity index 99%
rename from media/extractors/mkv/MatroskaExtractor.cpp
rename to media/module/extractors/mkv/MatroskaExtractor.cpp
index 443e26c..2b72387 100644
--- a/media/extractors/mkv/MatroskaExtractor.cpp
+++ b/media/module/extractors/mkv/MatroskaExtractor.cpp
@@ -790,6 +790,7 @@
int64_t timeUs = mBlockIter.blockTimeUs();
for (int i = 0; i < block->GetFrameCount(); ++i) {
+ status_t err;
MatroskaExtractor::TrackInfo *trackInfo = &mExtractor->mTracks.editItemAt(mTrackIndex);
const mkvparser::Block::Frame &frame = block->GetFrame(i);
size_t len = frame.len;
@@ -798,8 +799,13 @@
}
len += trackInfo->mHeaderLen;
- MediaBufferHelper *mbuf;
- mBufferGroup->acquire_buffer(&mbuf, false /* nonblocking */, len /* requested size */);
+ MediaBufferHelper *mbuf = nullptr;
+ err = mBufferGroup->acquire_buffer(&mbuf, false /* nonblocking */,
+ len /* requested size */);
+ if (err != OK || mbuf == nullptr) {
+ ALOGE("readBlock: no buffer");
+ return AMEDIA_ERROR_UNKNOWN;
+ }
mbuf->set_range(0, len);
uint8_t *data = static_cast<uint8_t *>(mbuf->data());
if (trackInfo->mHeader) {
@@ -832,7 +838,7 @@
}
}
- status_t err = frame.Read(mExtractor->mReader, data + trackInfo->mHeaderLen);
+ err = frame.Read(mExtractor->mReader, data + trackInfo->mHeaderLen);
if (err == OK
&& mExtractor->mIsWebm
&& trackInfo->mEncrypted) {
diff --git a/media/extractors/mkv/NOTICE b/media/module/extractors/mkv/NOTICE
similarity index 100%
rename from media/extractors/mkv/NOTICE
rename to media/module/extractors/mkv/NOTICE
diff --git a/media/extractors/mkv/exports.lds b/media/module/extractors/mkv/exports.lds
similarity index 100%
rename from media/extractors/mkv/exports.lds
rename to media/module/extractors/mkv/exports.lds
diff --git a/media/extractors/mkv/include/MatroskaExtractor.h b/media/module/extractors/mkv/include/MatroskaExtractor.h
similarity index 100%
rename from media/extractors/mkv/include/MatroskaExtractor.h
rename to media/module/extractors/mkv/include/MatroskaExtractor.h
diff --git a/media/extractors/mp3/Android.bp b/media/module/extractors/mp3/Android.bp
similarity index 100%
rename from media/extractors/mp3/Android.bp
rename to media/module/extractors/mp3/Android.bp
diff --git a/media/extractors/mp3/MP3Extractor.cpp b/media/module/extractors/mp3/MP3Extractor.cpp
similarity index 99%
rename from media/extractors/mp3/MP3Extractor.cpp
rename to media/module/extractors/mp3/MP3Extractor.cpp
index 248a39c..328b790 100644
--- a/media/extractors/mp3/MP3Extractor.cpp
+++ b/media/module/extractors/mp3/MP3Extractor.cpp
@@ -521,9 +521,9 @@
mSamplesRead = 0;
}
- MediaBufferHelper *buffer;
+ MediaBufferHelper *buffer = nullptr;
status_t err = mBufferGroup->acquire_buffer(&buffer);
- if (err != OK) {
+ if (err != OK || buffer == nullptr) {
return AMEDIA_ERROR_UNKNOWN;
}
diff --git a/media/extractors/mp3/VBRISeeker.cpp b/media/module/extractors/mp3/VBRISeeker.cpp
similarity index 100%
rename from media/extractors/mp3/VBRISeeker.cpp
rename to media/module/extractors/mp3/VBRISeeker.cpp
diff --git a/media/extractors/mp3/XINGSeeker.cpp b/media/module/extractors/mp3/XINGSeeker.cpp
similarity index 100%
rename from media/extractors/mp3/XINGSeeker.cpp
rename to media/module/extractors/mp3/XINGSeeker.cpp
diff --git a/media/extractors/mp3/exports.lds b/media/module/extractors/mp3/exports.lds
similarity index 100%
rename from media/extractors/mp3/exports.lds
rename to media/module/extractors/mp3/exports.lds
diff --git a/media/extractors/mp3/include/MP3Extractor.h b/media/module/extractors/mp3/include/MP3Extractor.h
similarity index 100%
rename from media/extractors/mp3/include/MP3Extractor.h
rename to media/module/extractors/mp3/include/MP3Extractor.h
diff --git a/media/extractors/mp3/include/MP3Seeker.h b/media/module/extractors/mp3/include/MP3Seeker.h
similarity index 100%
rename from media/extractors/mp3/include/MP3Seeker.h
rename to media/module/extractors/mp3/include/MP3Seeker.h
diff --git a/media/extractors/mp3/include/VBRISeeker.h b/media/module/extractors/mp3/include/VBRISeeker.h
similarity index 100%
rename from media/extractors/mp3/include/VBRISeeker.h
rename to media/module/extractors/mp3/include/VBRISeeker.h
diff --git a/media/extractors/mp3/include/XINGSeeker.h b/media/module/extractors/mp3/include/XINGSeeker.h
similarity index 100%
rename from media/extractors/mp3/include/XINGSeeker.h
rename to media/module/extractors/mp3/include/XINGSeeker.h
diff --git a/media/extractors/mp4/AC4Parser.cpp b/media/module/extractors/mp4/AC4Parser.cpp
similarity index 100%
rename from media/extractors/mp4/AC4Parser.cpp
rename to media/module/extractors/mp4/AC4Parser.cpp
diff --git a/media/extractors/mp4/Android.bp b/media/module/extractors/mp4/Android.bp
similarity index 100%
rename from media/extractors/mp4/Android.bp
rename to media/module/extractors/mp4/Android.bp
diff --git a/media/extractors/mp4/ItemTable.cpp b/media/module/extractors/mp4/ItemTable.cpp
similarity index 100%
rename from media/extractors/mp4/ItemTable.cpp
rename to media/module/extractors/mp4/ItemTable.cpp
diff --git a/media/extractors/mp4/MODULE_LICENSE_APACHE2 b/media/module/extractors/mp4/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/extractors/mp4/MODULE_LICENSE_APACHE2
rename to media/module/extractors/mp4/MODULE_LICENSE_APACHE2
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/module/extractors/mp4/MPEG4Extractor.cpp
similarity index 99%
rename from media/extractors/mp4/MPEG4Extractor.cpp
rename to media/module/extractors/mp4/MPEG4Extractor.cpp
index fb9dfb4..1d88785 100644
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/module/extractors/mp4/MPEG4Extractor.cpp
@@ -34,7 +34,7 @@
#include "SampleTable.h"
#include "ItemTable.h"
-#include <ESDS.h>
+#include <media/esds/ESDS.h>
#include <ID3.h>
#include <media/stagefright/DataSourceBase.h>
#include <media/ExtractorUtils.h>
@@ -394,6 +394,15 @@
return MEDIA_MIMETYPE_AUDIO_MPEGH_MHA1;
case FOURCC("mhm1"):
return MEDIA_MIMETYPE_AUDIO_MPEGH_MHM1;
+ case FOURCC("dtsc"):
+ return MEDIA_MIMETYPE_AUDIO_DTS;
+ case FOURCC("dtse"):
+ case FOURCC("dtsh"):
+ return MEDIA_MIMETYPE_AUDIO_DTS_HD;
+ case FOURCC("dtsl"):
+ return MEDIA_MIMETYPE_AUDIO_DTS_HD_MA;
+ case FOURCC("dtsx"):
+ return MEDIA_MIMETYPE_AUDIO_DTS_UHD_P2;
default:
ALOGW("Unknown fourcc: %c%c%c%c",
(fourcc >> 24) & 0xff,
@@ -1804,6 +1813,11 @@
case 0x6D730055: // "ms U" mp3 audio
case FOURCC("mha1"):
case FOURCC("mhm1"):
+ case FOURCC("dtsc"):
+ case FOURCC("dtse"):
+ case FOURCC("dtsh"):
+ case FOURCC("dtsl"):
+ case FOURCC("dtsx"):
{
if (mIsQT && depth >= 1 && mPath[depth - 1] == FOURCC("wave")) {
@@ -1969,26 +1983,8 @@
}
if (chunk_type == FOURCC("fLaC")) {
-
- // From https://github.com/xiph/flac/blob/master/doc/isoflac.txt
- // 4 for mime, 4 for blockType and BlockLen, 34 for metadata
- uint8_t flacInfo[4 + 4 + 34];
- // skipping dFla, version
- data_offset += sizeof(buffer) + 12;
- size_t flacOffset = 4;
- // Add flaC header mime type to CSD
- strncpy((char *)flacInfo, "fLaC", 4);
- if (mDataSource->readAt(
- data_offset, flacInfo + flacOffset, sizeof(flacInfo) - flacOffset) <
- (ssize_t)sizeof(flacInfo) - flacOffset) {
- return ERROR_IO;
- }
- data_offset += sizeof(flacInfo) - flacOffset;
-
- AMediaFormat_setBuffer(mLastTrack->meta, AMEDIAFORMAT_KEY_CSD_0, flacInfo,
- sizeof(flacInfo));
+ data_offset += sizeof(buffer);
*offset = data_offset;
- CHECK_EQ(*offset, stop_offset);
}
while (*offset < stop_offset) {
@@ -2521,6 +2517,35 @@
break;
}
+ case FOURCC("dfLa"):
+ {
+ *offset += chunk_size;
+
+ // From https://github.com/xiph/flac/blob/master/doc/isoflac.txt
+ // 4 for mediaType, 4 for blockType and BlockLen, 34 for metadata
+ uint8_t flacInfo[4 + 4 + 34];
+
+ if (chunk_data_size != sizeof(flacInfo)) {
+ return ERROR_MALFORMED;
+ }
+
+ data_offset += 4;
+ size_t flacOffset = 4;
+ // Add flaC header mediaType to CSD
+ strncpy((char *)flacInfo, "fLaC", 4);
+
+ ssize_t bytesToRead = sizeof(flacInfo) - flacOffset;
+ if (mDataSource->readAt(
+ data_offset, flacInfo + flacOffset, bytesToRead) < bytesToRead) {
+ return ERROR_IO;
+ }
+
+ data_offset += bytesToRead;
+ AMediaFormat_setBuffer(mLastTrack->meta, AMEDIAFORMAT_KEY_CSD_0, flacInfo,
+ sizeof(flacInfo));
+ break;
+ }
+
case FOURCC("avcC"):
{
*offset += chunk_size;
@@ -6312,7 +6337,7 @@
err = mBufferGroup->acquire_buffer(&mBuffer);
- if (err != OK) {
+ if (err != OK || mBuffer == nullptr) {
CHECK(mBuffer == NULL);
return AMEDIA_ERROR_UNKNOWN;
}
@@ -6712,7 +6737,7 @@
const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex];
offset = smpl->offset;
size = smpl->size;
- cts = mCurrentTime + smpl->compositionOffset;
+ cts = (int64_t)mCurrentTime + (int64_t)smpl->compositionOffset;
if (mElstInitialEmptyEditTicks > 0) {
cts += mElstInitialEmptyEditTicks;
diff --git a/media/extractors/mp4/NOTICE b/media/module/extractors/mp4/NOTICE
similarity index 100%
rename from media/extractors/mp4/NOTICE
rename to media/module/extractors/mp4/NOTICE
diff --git a/media/extractors/mp4/SampleIterator.cpp b/media/module/extractors/mp4/SampleIterator.cpp
similarity index 100%
rename from media/extractors/mp4/SampleIterator.cpp
rename to media/module/extractors/mp4/SampleIterator.cpp
diff --git a/media/extractors/mp4/SampleTable.cpp b/media/module/extractors/mp4/SampleTable.cpp
similarity index 100%
rename from media/extractors/mp4/SampleTable.cpp
rename to media/module/extractors/mp4/SampleTable.cpp
diff --git a/media/extractors/mp4/exports.lds b/media/module/extractors/mp4/exports.lds
similarity index 100%
rename from media/extractors/mp4/exports.lds
rename to media/module/extractors/mp4/exports.lds
diff --git a/media/extractors/mp4/include/AC4Parser.h b/media/module/extractors/mp4/include/AC4Parser.h
similarity index 100%
rename from media/extractors/mp4/include/AC4Parser.h
rename to media/module/extractors/mp4/include/AC4Parser.h
diff --git a/media/extractors/mp4/include/ItemTable.h b/media/module/extractors/mp4/include/ItemTable.h
similarity index 100%
rename from media/extractors/mp4/include/ItemTable.h
rename to media/module/extractors/mp4/include/ItemTable.h
diff --git a/media/extractors/mp4/include/MPEG4Extractor.h b/media/module/extractors/mp4/include/MPEG4Extractor.h
similarity index 100%
rename from media/extractors/mp4/include/MPEG4Extractor.h
rename to media/module/extractors/mp4/include/MPEG4Extractor.h
diff --git a/media/extractors/mp4/include/SampleIterator.h b/media/module/extractors/mp4/include/SampleIterator.h
similarity index 100%
rename from media/extractors/mp4/include/SampleIterator.h
rename to media/module/extractors/mp4/include/SampleIterator.h
diff --git a/media/extractors/mp4/include/SampleTable.h b/media/module/extractors/mp4/include/SampleTable.h
similarity index 100%
rename from media/extractors/mp4/include/SampleTable.h
rename to media/module/extractors/mp4/include/SampleTable.h
diff --git a/media/extractors/mpeg2/Android.bp b/media/module/extractors/mpeg2/Android.bp
similarity index 100%
rename from media/extractors/mpeg2/Android.bp
rename to media/module/extractors/mpeg2/Android.bp
diff --git a/media/extractors/mpeg2/ExtractorBundle.cpp b/media/module/extractors/mpeg2/ExtractorBundle.cpp
similarity index 100%
rename from media/extractors/mpeg2/ExtractorBundle.cpp
rename to media/module/extractors/mpeg2/ExtractorBundle.cpp
diff --git a/media/extractors/mpeg2/MODULE_LICENSE_APACHE2 b/media/module/extractors/mpeg2/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/extractors/mpeg2/MODULE_LICENSE_APACHE2
rename to media/module/extractors/mpeg2/MODULE_LICENSE_APACHE2
diff --git a/media/extractors/mpeg2/MPEG2PSExtractor.cpp b/media/module/extractors/mpeg2/MPEG2PSExtractor.cpp
similarity index 97%
rename from media/extractors/mpeg2/MPEG2PSExtractor.cpp
rename to media/module/extractors/mpeg2/MPEG2PSExtractor.cpp
index afd28ef..44c8937 100644
--- a/media/extractors/mpeg2/MPEG2PSExtractor.cpp
+++ b/media/module/extractors/mpeg2/MPEG2PSExtractor.cpp
@@ -699,11 +699,26 @@
}
}
- MediaBufferBase *mbuf;
- mSource->read(&mbuf, (MediaTrack::ReadOptions*) options);
+ MediaBufferBase *mbuf = nullptr;
+ status_t err_read = mSource->read(&mbuf, (MediaTrack::ReadOptions*) options);
+ if (mbuf == nullptr) {
+ ALOGE("Track::read: null buffer read from source");
+ return AMEDIA_ERROR_UNKNOWN;
+ }
+ if (err_read != OK) {
+ ALOGE("Track::read: no buffer read from source");
+ mbuf->release();
+ return AMEDIA_ERROR_UNKNOWN;
+ }
+
size_t length = mbuf->range_length();
- MediaBufferHelper *outbuf;
- mBufferGroup->acquire_buffer(&outbuf, false, length);
+ MediaBufferHelper *outbuf = nullptr;
+ status_t err = mBufferGroup->acquire_buffer(&outbuf, false, length);
+ if (err != OK || outbuf == nullptr) {
+ ALOGE("Track::read: no buffer");
+ mbuf->release();
+ return AMEDIA_ERROR_UNKNOWN;
+ }
memcpy(outbuf->data(), mbuf->data(), length);
outbuf->set_range(0, length);
*buffer = outbuf;
diff --git a/media/extractors/mpeg2/MPEG2TSExtractor.cpp b/media/module/extractors/mpeg2/MPEG2TSExtractor.cpp
similarity index 97%
rename from media/extractors/mpeg2/MPEG2TSExtractor.cpp
rename to media/module/extractors/mpeg2/MPEG2TSExtractor.cpp
index 9a3cd92..736b817 100644
--- a/media/extractors/mpeg2/MPEG2TSExtractor.cpp
+++ b/media/module/extractors/mpeg2/MPEG2TSExtractor.cpp
@@ -182,11 +182,26 @@
return AMEDIA_ERROR_END_OF_STREAM;
}
- MediaBufferBase *mbuf;
- mImpl->read(&mbuf, (MediaTrack::ReadOptions*) options);
+ MediaBufferBase *mbuf = nullptr;
+ status_t err_read = mImpl->read(&mbuf, (MediaTrack::ReadOptions*) options);
+ if (mbuf == nullptr) {
+ ALOGE("Track::read: null buffer read from source");
+ return AMEDIA_ERROR_UNKNOWN;
+ }
+ if (err_read != OK) {
+ ALOGE("Track::read: no buffer read from source");
+ mbuf->release();
+ return AMEDIA_ERROR_UNKNOWN;
+ }
+
size_t length = mbuf->range_length();
- MediaBufferHelper *outbuf;
- mBufferGroup->acquire_buffer(&outbuf, false, length);
+ MediaBufferHelper *outbuf = nullptr;
+ status_t err = mBufferGroup->acquire_buffer(&outbuf, false, length);
+ if (err != OK || outbuf == nullptr) {
+ ALOGE("read: no buffer");
+ mbuf->release();
+ return AMEDIA_ERROR_UNKNOWN;
+ }
memcpy(outbuf->data(), mbuf->data(), length);
outbuf->set_range(0, length);
*out = outbuf;
diff --git a/media/extractors/mpeg2/NOTICE b/media/module/extractors/mpeg2/NOTICE
similarity index 100%
rename from media/extractors/mpeg2/NOTICE
rename to media/module/extractors/mpeg2/NOTICE
diff --git a/media/extractors/mpeg2/exports.lds b/media/module/extractors/mpeg2/exports.lds
similarity index 100%
rename from media/extractors/mpeg2/exports.lds
rename to media/module/extractors/mpeg2/exports.lds
diff --git a/media/extractors/mpeg2/include/MPEG2PSExtractor.h b/media/module/extractors/mpeg2/include/MPEG2PSExtractor.h
similarity index 100%
rename from media/extractors/mpeg2/include/MPEG2PSExtractor.h
rename to media/module/extractors/mpeg2/include/MPEG2PSExtractor.h
diff --git a/media/extractors/mpeg2/include/MPEG2TSExtractor.h b/media/module/extractors/mpeg2/include/MPEG2TSExtractor.h
similarity index 100%
rename from media/extractors/mpeg2/include/MPEG2TSExtractor.h
rename to media/module/extractors/mpeg2/include/MPEG2TSExtractor.h
diff --git a/media/extractors/ogg/Android.bp b/media/module/extractors/ogg/Android.bp
similarity index 100%
rename from media/extractors/ogg/Android.bp
rename to media/module/extractors/ogg/Android.bp
diff --git a/media/extractors/ogg/MODULE_LICENSE_APACHE2 b/media/module/extractors/ogg/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/extractors/ogg/MODULE_LICENSE_APACHE2
rename to media/module/extractors/ogg/MODULE_LICENSE_APACHE2
diff --git a/media/extractors/ogg/NOTICE b/media/module/extractors/ogg/NOTICE
similarity index 100%
rename from media/extractors/ogg/NOTICE
rename to media/module/extractors/ogg/NOTICE
diff --git a/media/extractors/ogg/OggExtractor.cpp b/media/module/extractors/ogg/OggExtractor.cpp
similarity index 98%
rename from media/extractors/ogg/OggExtractor.cpp
rename to media/module/extractors/ogg/OggExtractor.cpp
index eb2246d..1c6f516 100644
--- a/media/extractors/ogg/OggExtractor.cpp
+++ b/media/module/extractors/ogg/OggExtractor.cpp
@@ -790,7 +790,8 @@
}
MediaBufferHelper *tmp;
if (mBufferGroup) {
- mBufferGroup->acquire_buffer(&tmp, false, fullSize);
+ // ignore return code here. instead, check tmp below.
+ (void) mBufferGroup->acquire_buffer(&tmp, false, fullSize);
ALOGV("acquired buffer %p from group", tmp);
} else {
tmp = new StandAloneMediaBuffer(fullSize);
@@ -924,13 +925,16 @@
status_t MyOggExtractor::init() {
AMediaFormat_setString(mMeta, AMEDIAFORMAT_KEY_MIME, mMimeType);
- media_status_t err;
- MediaBufferHelper *packet;
for (size_t i = 0; i < mNumHeaders; ++i) {
+ media_status_t err;
+ MediaBufferHelper *packet = nullptr;
// ignore timestamp for configuration packets
if ((err = _readNextPacket(&packet, /* calcVorbisTimestamp = */ false)) != AMEDIA_OK) {
return err;
}
+ if (packet == nullptr) {
+ return AMEDIA_ERROR_UNKNOWN;
+ }
ALOGV("read packet of size %zu\n", packet->range_length());
err = verifyHeader(packet, /* type = */ i * 2 + 1);
packet->release();
diff --git a/media/extractors/ogg/exports.lds b/media/module/extractors/ogg/exports.lds
similarity index 100%
rename from media/extractors/ogg/exports.lds
rename to media/module/extractors/ogg/exports.lds
diff --git a/media/extractors/ogg/include/OggExtractor.h b/media/module/extractors/ogg/include/OggExtractor.h
similarity index 100%
rename from media/extractors/ogg/include/OggExtractor.h
rename to media/module/extractors/ogg/include/OggExtractor.h
diff --git a/media/extractors/tests/Android.bp b/media/module/extractors/tests/Android.bp
similarity index 98%
rename from media/extractors/tests/Android.bp
rename to media/module/extractors/tests/Android.bp
index 3c3bbdc..d6e79c7 100644
--- a/media/extractors/tests/Android.bp
+++ b/media/module/extractors/tests/Android.bp
@@ -55,7 +55,7 @@
"libmedia_midiiowrapper",
"libsonivoxwithoutjet",
"libvorbisidec",
- "libwebm",
+ "libwebm_mkvparser",
"libFLAC",
],
diff --git a/media/extractors/tests/AndroidTest.xml b/media/module/extractors/tests/AndroidTest.xml
similarity index 100%
rename from media/extractors/tests/AndroidTest.xml
rename to media/module/extractors/tests/AndroidTest.xml
diff --git a/media/extractors/tests/ExtractorUnitTest.cpp b/media/module/extractors/tests/ExtractorUnitTest.cpp
similarity index 100%
rename from media/extractors/tests/ExtractorUnitTest.cpp
rename to media/module/extractors/tests/ExtractorUnitTest.cpp
diff --git a/media/extractors/tests/ExtractorUnitTestEnvironment.h b/media/module/extractors/tests/ExtractorUnitTestEnvironment.h
similarity index 100%
rename from media/extractors/tests/ExtractorUnitTestEnvironment.h
rename to media/module/extractors/tests/ExtractorUnitTestEnvironment.h
diff --git a/media/extractors/tests/README.md b/media/module/extractors/tests/README.md
similarity index 100%
rename from media/extractors/tests/README.md
rename to media/module/extractors/tests/README.md
diff --git a/media/extractors/wav/Android.bp b/media/module/extractors/wav/Android.bp
similarity index 100%
rename from media/extractors/wav/Android.bp
rename to media/module/extractors/wav/Android.bp
diff --git a/media/extractors/wav/MODULE_LICENSE_APACHE2 b/media/module/extractors/wav/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/extractors/wav/MODULE_LICENSE_APACHE2
rename to media/module/extractors/wav/MODULE_LICENSE_APACHE2
diff --git a/media/extractors/wav/NOTICE b/media/module/extractors/wav/NOTICE
similarity index 100%
rename from media/extractors/wav/NOTICE
rename to media/module/extractors/wav/NOTICE
diff --git a/media/extractors/wav/WAVExtractor.cpp b/media/module/extractors/wav/WAVExtractor.cpp
similarity index 98%
rename from media/extractors/wav/WAVExtractor.cpp
rename to media/module/extractors/wav/WAVExtractor.cpp
index 9e94587..9c3bac6 100644
--- a/media/extractors/wav/WAVExtractor.cpp
+++ b/media/module/extractors/wav/WAVExtractor.cpp
@@ -459,11 +459,15 @@
mCurrentPos = pos + mOffset;
}
- MediaBufferHelper *buffer;
+ MediaBufferHelper *buffer = nullptr;
media_status_t err = mBufferGroup->acquire_buffer(&buffer);
if (err != OK) {
return err;
}
+ if (buffer == nullptr) {
+ ALOGE("acquire_buffer OK, but no buffer");
+ return AMEDIA_ERROR_UNKNOWN;
+ }
// maxBytesToRead may be reduced so that in-place data conversion will fit in buffer size.
const size_t bufferSize = std::min(buffer->size(), kMaxFrameSize);
diff --git a/media/extractors/wav/exports.lds b/media/module/extractors/wav/exports.lds
similarity index 100%
rename from media/extractors/wav/exports.lds
rename to media/module/extractors/wav/exports.lds
diff --git a/media/extractors/wav/include/WAVExtractor.h b/media/module/extractors/wav/include/WAVExtractor.h
similarity index 100%
rename from media/extractors/wav/include/WAVExtractor.h
rename to media/module/extractors/wav/include/WAVExtractor.h
diff --git a/media/libstagefright/foundation/AAtomizer.cpp b/media/module/foundation/AAtomizer.cpp
similarity index 100%
rename from media/libstagefright/foundation/AAtomizer.cpp
rename to media/module/foundation/AAtomizer.cpp
diff --git a/media/libstagefright/foundation/ABitReader.cpp b/media/module/foundation/ABitReader.cpp
similarity index 100%
rename from media/libstagefright/foundation/ABitReader.cpp
rename to media/module/foundation/ABitReader.cpp
diff --git a/media/libstagefright/foundation/ABuffer.cpp b/media/module/foundation/ABuffer.cpp
similarity index 100%
rename from media/libstagefright/foundation/ABuffer.cpp
rename to media/module/foundation/ABuffer.cpp
diff --git a/media/libstagefright/foundation/ADebug.cpp b/media/module/foundation/ADebug.cpp
similarity index 100%
rename from media/libstagefright/foundation/ADebug.cpp
rename to media/module/foundation/ADebug.cpp
diff --git a/media/libstagefright/foundation/AHandler.cpp b/media/module/foundation/AHandler.cpp
similarity index 100%
rename from media/libstagefright/foundation/AHandler.cpp
rename to media/module/foundation/AHandler.cpp
diff --git a/media/libstagefright/foundation/ALooper.cpp b/media/module/foundation/ALooper.cpp
similarity index 100%
rename from media/libstagefright/foundation/ALooper.cpp
rename to media/module/foundation/ALooper.cpp
diff --git a/media/libstagefright/foundation/ALooperRoster.cpp b/media/module/foundation/ALooperRoster.cpp
similarity index 100%
rename from media/libstagefright/foundation/ALooperRoster.cpp
rename to media/module/foundation/ALooperRoster.cpp
diff --git a/media/libstagefright/foundation/AMessage.cpp b/media/module/foundation/AMessage.cpp
similarity index 100%
rename from media/libstagefright/foundation/AMessage.cpp
rename to media/module/foundation/AMessage.cpp
diff --git a/media/libstagefright/foundation/AString.cpp b/media/module/foundation/AString.cpp
similarity index 100%
rename from media/libstagefright/foundation/AString.cpp
rename to media/module/foundation/AString.cpp
diff --git a/media/libstagefright/foundation/AStringUtils.cpp b/media/module/foundation/AStringUtils.cpp
similarity index 100%
rename from media/libstagefright/foundation/AStringUtils.cpp
rename to media/module/foundation/AStringUtils.cpp
diff --git a/media/libstagefright/foundation/Android.bp b/media/module/foundation/Android.bp
similarity index 100%
rename from media/libstagefright/foundation/Android.bp
rename to media/module/foundation/Android.bp
diff --git a/media/libstagefright/foundation/AudioPresentationInfo.cpp b/media/module/foundation/AudioPresentationInfo.cpp
similarity index 100%
rename from media/libstagefright/foundation/AudioPresentationInfo.cpp
rename to media/module/foundation/AudioPresentationInfo.cpp
diff --git a/media/libstagefright/foundation/ByteUtils.cpp b/media/module/foundation/ByteUtils.cpp
similarity index 100%
rename from media/libstagefright/foundation/ByteUtils.cpp
rename to media/module/foundation/ByteUtils.cpp
diff --git a/media/libstagefright/foundation/ColorUtils.cpp b/media/module/foundation/ColorUtils.cpp
similarity index 100%
rename from media/libstagefright/foundation/ColorUtils.cpp
rename to media/module/foundation/ColorUtils.cpp
diff --git a/media/libstagefright/foundation/ColorUtils_fill.cpp b/media/module/foundation/ColorUtils_fill.cpp
similarity index 100%
rename from media/libstagefright/foundation/ColorUtils_fill.cpp
rename to media/module/foundation/ColorUtils_fill.cpp
diff --git a/media/libstagefright/foundation/ColorUtils_ndk.cpp b/media/module/foundation/ColorUtils_ndk.cpp
similarity index 100%
rename from media/libstagefright/foundation/ColorUtils_ndk.cpp
rename to media/module/foundation/ColorUtils_ndk.cpp
diff --git a/media/libstagefright/foundation/FoundationUtils.cpp b/media/module/foundation/FoundationUtils.cpp
similarity index 100%
rename from media/libstagefright/foundation/FoundationUtils.cpp
rename to media/module/foundation/FoundationUtils.cpp
diff --git a/media/libstagefright/foundation/MODULE_LICENSE_APACHE2 b/media/module/foundation/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/libstagefright/foundation/MODULE_LICENSE_APACHE2
rename to media/module/foundation/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/foundation/MediaBuffer.cpp b/media/module/foundation/MediaBuffer.cpp
similarity index 100%
rename from media/libstagefright/foundation/MediaBuffer.cpp
rename to media/module/foundation/MediaBuffer.cpp
diff --git a/media/libstagefright/foundation/MediaBufferBase.cpp b/media/module/foundation/MediaBufferBase.cpp
similarity index 100%
rename from media/libstagefright/foundation/MediaBufferBase.cpp
rename to media/module/foundation/MediaBufferBase.cpp
diff --git a/media/libstagefright/foundation/MediaBufferGroup.cpp b/media/module/foundation/MediaBufferGroup.cpp
similarity index 100%
rename from media/libstagefright/foundation/MediaBufferGroup.cpp
rename to media/module/foundation/MediaBufferGroup.cpp
diff --git a/media/libstagefright/foundation/MediaDefs.cpp b/media/module/foundation/MediaDefs.cpp
similarity index 96%
rename from media/libstagefright/foundation/MediaDefs.cpp
rename to media/module/foundation/MediaDefs.cpp
index 5c4ec17..4a75f90 100644
--- a/media/libstagefright/foundation/MediaDefs.cpp
+++ b/media/module/foundation/MediaDefs.cpp
@@ -71,7 +71,9 @@
const char *MEDIA_MIMETYPE_AUDIO_DVI_IMA_ADPCM = "audio/x-adpcm-dvi-ima";
const char *MEDIA_MIMETYPE_AUDIO_DTS = "audio/vnd.dts";
const char *MEDIA_MIMETYPE_AUDIO_DTS_HD = "audio/vnd.dts.hd";
-const char *MEDIA_MIMETYPE_AUDIO_DTS_UHD = "audio/vnd.dts.uhd";
+const char *MEDIA_MIMETYPE_AUDIO_DTS_HD_MA = "audio/vnd.dts.hd;profile=dtsma";
+const char *MEDIA_MIMETYPE_AUDIO_DTS_UHD_P1 = "audio/vnd.dts.uhd;profile=p1";
+const char *MEDIA_MIMETYPE_AUDIO_DTS_UHD_P2 = "audio/vnd.dts.uhd;profile=p2";
const char *MEDIA_MIMETYPE_AUDIO_EVRC = "audio/evrc";
const char *MEDIA_MIMETYPE_AUDIO_EVRCB = "audio/evrcb";
const char *MEDIA_MIMETYPE_AUDIO_EVRCWB = "audio/evrcwb";
diff --git a/media/libstagefright/foundation/MediaKeys.cpp b/media/module/foundation/MediaKeys.cpp
similarity index 100%
rename from media/libstagefright/foundation/MediaKeys.cpp
rename to media/module/foundation/MediaKeys.cpp
diff --git a/media/libstagefright/foundation/MetaData.cpp b/media/module/foundation/MetaData.cpp
similarity index 100%
rename from media/libstagefright/foundation/MetaData.cpp
rename to media/module/foundation/MetaData.cpp
diff --git a/media/libstagefright/foundation/MetaDataBase.cpp b/media/module/foundation/MetaDataBase.cpp
similarity index 100%
rename from media/libstagefright/foundation/MetaDataBase.cpp
rename to media/module/foundation/MetaDataBase.cpp
diff --git a/media/libstagefright/foundation/NOTICE b/media/module/foundation/NOTICE
similarity index 100%
rename from media/libstagefright/foundation/NOTICE
rename to media/module/foundation/NOTICE
diff --git a/media/libstagefright/foundation/OpusHeader.cpp b/media/module/foundation/OpusHeader.cpp
similarity index 100%
rename from media/libstagefright/foundation/OpusHeader.cpp
rename to media/module/foundation/OpusHeader.cpp
diff --git a/media/libstagefright/foundation/TEST_MAPPING b/media/module/foundation/TEST_MAPPING
similarity index 100%
rename from media/libstagefright/foundation/TEST_MAPPING
rename to media/module/foundation/TEST_MAPPING
diff --git a/media/libstagefright/foundation/avc_utils.cpp b/media/module/foundation/avc_utils.cpp
similarity index 100%
rename from media/libstagefright/foundation/avc_utils.cpp
rename to media/module/foundation/avc_utils.cpp
diff --git a/media/libstagefright/foundation/base64.cpp b/media/module/foundation/base64.cpp
similarity index 100%
rename from media/libstagefright/foundation/base64.cpp
rename to media/module/foundation/base64.cpp
diff --git a/media/libstagefright/foundation/hexdump.cpp b/media/module/foundation/hexdump.cpp
similarity index 100%
rename from media/libstagefright/foundation/hexdump.cpp
rename to media/module/foundation/hexdump.cpp
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/AAtomizer.h b/media/module/foundation/include/media/stagefright/foundation/AAtomizer.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/AAtomizer.h
rename to media/module/foundation/include/media/stagefright/foundation/AAtomizer.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/ABase.h b/media/module/foundation/include/media/stagefright/foundation/ABase.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/ABase.h
rename to media/module/foundation/include/media/stagefright/foundation/ABase.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/ABitReader.h b/media/module/foundation/include/media/stagefright/foundation/ABitReader.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/ABitReader.h
rename to media/module/foundation/include/media/stagefright/foundation/ABitReader.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/ABuffer.h b/media/module/foundation/include/media/stagefright/foundation/ABuffer.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/ABuffer.h
rename to media/module/foundation/include/media/stagefright/foundation/ABuffer.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/AData.h b/media/module/foundation/include/media/stagefright/foundation/AData.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/AData.h
rename to media/module/foundation/include/media/stagefright/foundation/AData.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/ADebug.h b/media/module/foundation/include/media/stagefright/foundation/ADebug.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/ADebug.h
rename to media/module/foundation/include/media/stagefright/foundation/ADebug.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/AHandler.h b/media/module/foundation/include/media/stagefright/foundation/AHandler.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/AHandler.h
rename to media/module/foundation/include/media/stagefright/foundation/AHandler.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/AHandlerReflector.h b/media/module/foundation/include/media/stagefright/foundation/AHandlerReflector.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/AHandlerReflector.h
rename to media/module/foundation/include/media/stagefright/foundation/AHandlerReflector.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/ALookup.h b/media/module/foundation/include/media/stagefright/foundation/ALookup.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/ALookup.h
rename to media/module/foundation/include/media/stagefright/foundation/ALookup.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/ALooper.h b/media/module/foundation/include/media/stagefright/foundation/ALooper.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/ALooper.h
rename to media/module/foundation/include/media/stagefright/foundation/ALooper.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/ALooperRoster.h b/media/module/foundation/include/media/stagefright/foundation/ALooperRoster.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/ALooperRoster.h
rename to media/module/foundation/include/media/stagefright/foundation/ALooperRoster.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/AMessage.h b/media/module/foundation/include/media/stagefright/foundation/AMessage.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/AMessage.h
rename to media/module/foundation/include/media/stagefright/foundation/AMessage.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/AString.h b/media/module/foundation/include/media/stagefright/foundation/AString.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/AString.h
rename to media/module/foundation/include/media/stagefright/foundation/AString.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/AStringUtils.h b/media/module/foundation/include/media/stagefright/foundation/AStringUtils.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/AStringUtils.h
rename to media/module/foundation/include/media/stagefright/foundation/AStringUtils.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/AUtils.h b/media/module/foundation/include/media/stagefright/foundation/AUtils.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/AUtils.h
rename to media/module/foundation/include/media/stagefright/foundation/AUtils.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/AudioPresentationInfo.h b/media/module/foundation/include/media/stagefright/foundation/AudioPresentationInfo.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/AudioPresentationInfo.h
rename to media/module/foundation/include/media/stagefright/foundation/AudioPresentationInfo.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/ByteUtils.h b/media/module/foundation/include/media/stagefright/foundation/ByteUtils.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/ByteUtils.h
rename to media/module/foundation/include/media/stagefright/foundation/ByteUtils.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/ColorUtils.h b/media/module/foundation/include/media/stagefright/foundation/ColorUtils.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/ColorUtils.h
rename to media/module/foundation/include/media/stagefright/foundation/ColorUtils.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/FileDescriptor.h b/media/module/foundation/include/media/stagefright/foundation/FileDescriptor.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/FileDescriptor.h
rename to media/module/foundation/include/media/stagefright/foundation/FileDescriptor.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/Flagged.h b/media/module/foundation/include/media/stagefright/foundation/Flagged.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/Flagged.h
rename to media/module/foundation/include/media/stagefright/foundation/Flagged.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/MediaDefs.h b/media/module/foundation/include/media/stagefright/foundation/MediaDefs.h
similarity index 97%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/MediaDefs.h
rename to media/module/foundation/include/media/stagefright/foundation/MediaDefs.h
index fb8c299..740336a 100644
--- a/media/libstagefright/foundation/include/media/stagefright/foundation/MediaDefs.h
+++ b/media/module/foundation/include/media/stagefright/foundation/MediaDefs.h
@@ -73,7 +73,9 @@
extern const char *MEDIA_MIMETYPE_AUDIO_DVI_IMA_ADPCM;
extern const char *MEDIA_MIMETYPE_AUDIO_DTS;
extern const char *MEDIA_MIMETYPE_AUDIO_DTS_HD;
-extern const char *MEDIA_MIMETYPE_AUDIO_DTS_UHD;
+extern const char *MEDIA_MIMETYPE_AUDIO_DTS_HD_MA;
+extern const char *MEDIA_MIMETYPE_AUDIO_DTS_UHD_P1;
+extern const char *MEDIA_MIMETYPE_AUDIO_DTS_UHD_P2;
extern const char *MEDIA_MIMETYPE_AUDIO_EVRC;
extern const char *MEDIA_MIMETYPE_AUDIO_EVRCB;
extern const char *MEDIA_MIMETYPE_AUDIO_EVRCWB;
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/MediaKeys.h b/media/module/foundation/include/media/stagefright/foundation/MediaKeys.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/MediaKeys.h
rename to media/module/foundation/include/media/stagefright/foundation/MediaKeys.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/Mutexed.h b/media/module/foundation/include/media/stagefright/foundation/Mutexed.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/Mutexed.h
rename to media/module/foundation/include/media/stagefright/foundation/Mutexed.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/OpusHeader.h b/media/module/foundation/include/media/stagefright/foundation/OpusHeader.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/OpusHeader.h
rename to media/module/foundation/include/media/stagefright/foundation/OpusHeader.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/TypeTraits.h b/media/module/foundation/include/media/stagefright/foundation/TypeTraits.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/TypeTraits.h
rename to media/module/foundation/include/media/stagefright/foundation/TypeTraits.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/avc_utils.h b/media/module/foundation/include/media/stagefright/foundation/avc_utils.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/avc_utils.h
rename to media/module/foundation/include/media/stagefright/foundation/avc_utils.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/base64.h b/media/module/foundation/include/media/stagefright/foundation/base64.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/base64.h
rename to media/module/foundation/include/media/stagefright/foundation/base64.h
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/hexdump.h b/media/module/foundation/include/media/stagefright/foundation/hexdump.h
similarity index 100%
rename from media/libstagefright/foundation/include/media/stagefright/foundation/hexdump.h
rename to media/module/foundation/include/media/stagefright/foundation/hexdump.h
diff --git a/media/libstagefright/foundation/tests/AData_test.cpp b/media/module/foundation/tests/AData_test.cpp
similarity index 100%
rename from media/libstagefright/foundation/tests/AData_test.cpp
rename to media/module/foundation/tests/AData_test.cpp
diff --git a/media/libstagefright/foundation/tests/AMessage_test.cpp b/media/module/foundation/tests/AMessage_test.cpp
similarity index 100%
rename from media/libstagefright/foundation/tests/AMessage_test.cpp
rename to media/module/foundation/tests/AMessage_test.cpp
diff --git a/media/libstagefright/foundation/tests/AVCUtils/AVCUtilsTestEnvironment.h b/media/module/foundation/tests/AVCUtils/AVCUtilsTestEnvironment.h
similarity index 100%
rename from media/libstagefright/foundation/tests/AVCUtils/AVCUtilsTestEnvironment.h
rename to media/module/foundation/tests/AVCUtils/AVCUtilsTestEnvironment.h
diff --git a/media/libstagefright/foundation/tests/AVCUtils/AVCUtilsUnitTest.cpp b/media/module/foundation/tests/AVCUtils/AVCUtilsUnitTest.cpp
similarity index 92%
rename from media/libstagefright/foundation/tests/AVCUtils/AVCUtilsUnitTest.cpp
rename to media/module/foundation/tests/AVCUtils/AVCUtilsUnitTest.cpp
index 77a8599..57ac822 100644
--- a/media/libstagefright/foundation/tests/AVCUtils/AVCUtilsUnitTest.cpp
+++ b/media/module/foundation/tests/AVCUtils/AVCUtilsUnitTest.cpp
@@ -19,6 +19,7 @@
#include <utils/Log.h>
#include <fstream>
+#include <memory>
#include "media/stagefright/foundation/ABitReader.h"
#include "media/stagefright/foundation/avc_utils.h"
@@ -151,10 +152,10 @@
size_t fileSize = buf.st_size;
ASSERT_NE(fileSize, 0) << "Invalid file size found";
- const uint8_t *volBuffer = new uint8_t[fileSize];
+ std::unique_ptr<uint8_t[]> volBuffer(new uint8_t[fileSize]);
ASSERT_NE(volBuffer, nullptr) << "Failed to allocate VOL buffer of size: " << fileSize;
- inputFileStream.read((char *)(volBuffer), fileSize);
+ inputFileStream.read((char *)(volBuffer.get()), fileSize);
ASSERT_EQ(inputFileStream.gcount(), fileSize)
<< "Failed to read complete file, bytes read: " << inputFileStream.gcount();
@@ -163,15 +164,13 @@
int32_t volWidth = -1;
int32_t volHeight = -1;
- bool status = ExtractDimensionsFromVOLHeader(volBuffer, fileSize, &volWidth, &volHeight);
+ bool status = ExtractDimensionsFromVOLHeader(volBuffer.get(), fileSize, &volWidth, &volHeight);
ASSERT_TRUE(status)
<< "Failed to get VOL dimensions from function: ExtractDimensionsFromVOLHeader()";
ASSERT_EQ(volWidth, width) << "Expected width: " << width << "Found: " << volWidth;
ASSERT_EQ(volHeight, height) << "Expected height: " << height << "Found: " << volHeight;
-
- delete[] volBuffer;
}
TEST_P(AVCDimensionTest, DimensionTest) {
@@ -186,7 +185,8 @@
stringLine >> type >> chunkLength;
ASSERT_GT(chunkLength, 0) << "Length of the data chunk must be greater than zero";
- const uint8_t *data = new uint8_t[chunkLength];
+ std::unique_ptr<uint8_t[]> dataArray(new uint8_t[chunkLength]);
+ const uint8_t *data = dataArray.get();
ASSERT_NE(data, nullptr) << "Failed to create a data buffer of size: " << chunkLength;
const uint8_t *nalStart;
@@ -197,9 +197,11 @@
<< "Failed to read complete file, bytes read: " << mInputFileStream.gcount();
size_t smallBufferSize = kSmallBufferSize;
- const uint8_t *sanityData = new uint8_t[smallBufferSize];
+ uint8_t sanityDataBuffer[smallBufferSize];
+ const uint8_t *sanityData = sanityDataBuffer;
memcpy((void *)sanityData, (void *)data, smallBufferSize);
+ // sanityData could be changed, but sanityDataPtr is not and can be cleaned up.
status_t result = getNextNALUnit(&sanityData, &smallBufferSize, &nalStart, &nalSize, true);
ASSERT_EQ(result, -EAGAIN) << "Invalid result found when wrong NAL unit passed";
@@ -221,7 +223,6 @@
ASSERT_EQ(avcHeight, mFrameHeight)
<< "Expected height: " << mFrameHeight << "Found: " << avcHeight;
}
- delete[] data;
}
if (mNalUnitsExpected < 0) {
ASSERT_GT(numNalUnits, 0) << "Failed to find an NAL Unit";
@@ -251,7 +252,8 @@
accessUnitLength += chunkLength;
if (!type.compare("SPS")) {
- const uint8_t *data = new uint8_t[chunkLength];
+ std::unique_ptr<uint8_t[]> dataArray(new uint8_t[chunkLength]);
+ const uint8_t *data = dataArray.get();
ASSERT_NE(data, nullptr) << "Failed to create a data buffer of size: " << chunkLength;
const uint8_t *nalStart;
@@ -271,14 +273,13 @@
profile = nalStart[1];
level = nalStart[3];
}
- delete[] data;
}
}
- const uint8_t *accessUnitData = new uint8_t[accessUnitLength];
+ std::unique_ptr<uint8_t[]> accessUnitData(new uint8_t[accessUnitLength]);
ASSERT_NE(accessUnitData, nullptr) << "Failed to create a buffer of size: " << accessUnitLength;
mInputFileStream.seekg(0, ios::beg);
- mInputFileStream.read((char *)accessUnitData, accessUnitLength);
+ mInputFileStream.read((char *)accessUnitData.get(), accessUnitLength);
ASSERT_EQ(mInputFileStream.gcount(), accessUnitLength)
<< "Failed to read complete file, bytes read: " << mInputFileStream.gcount();
@@ -286,7 +287,7 @@
ASSERT_NE(accessUnit, nullptr)
<< "Failed to create an android data buffer of size: " << accessUnitLength;
- memcpy(accessUnit->data(), accessUnitData, accessUnitLength);
+ memcpy(accessUnit->data(), accessUnitData.get(), accessUnitLength);
sp<ABuffer> csdDataBuffer = MakeAVCCodecSpecificData(accessUnit, &avcWidth, &avcHeight);
ASSERT_NE(csdDataBuffer, nullptr) << "No data returned from MakeAVCCodecSpecificData()";
@@ -306,7 +307,6 @@
ASSERT_EQ(*(csdData + 3), level)
<< "Expected AVC level: " << level << " found: " << *(csdData + 3);
csdDataBuffer.clear();
- delete[] accessUnitData;
accessUnit.clear();
}
@@ -321,32 +321,31 @@
stringLine >> type >> chunkLength >> frameLayerID;
ASSERT_GT(chunkLength, 0) << "Length of the data chunk must be greater than zero";
- char *data = new char[chunkLength];
+ std::unique_ptr<char[]> data(new char[chunkLength]);
ASSERT_NE(data, nullptr) << "Failed to allocation data buffer of size: " << chunkLength;
- mInputFileStream.read(data, chunkLength);
+ mInputFileStream.read(data.get(), chunkLength);
ASSERT_EQ(mInputFileStream.gcount(), chunkLength)
<< "Failed to read complete file, bytes read: " << mInputFileStream.gcount();
if (!type.compare("IDR")) {
- bool isIDR = IsIDR((uint8_t *)data, chunkLength);
+ bool isIDR = IsIDR((uint8_t *)data.get(), chunkLength);
ASSERT_TRUE(isIDR);
- layerID = FindAVCLayerId((uint8_t *)data, chunkLength);
+ layerID = FindAVCLayerId((uint8_t *)data.get(), chunkLength);
ASSERT_EQ(layerID, frameLayerID) << "Wrong layer ID found";
} else if (!type.compare("P") || !type.compare("B")) {
sp<ABuffer> accessUnit = new ABuffer(chunkLength);
ASSERT_NE(accessUnit, nullptr) << "Unable to create access Unit";
- memcpy(accessUnit->data(), data, chunkLength);
+ memcpy(accessUnit->data(), data.get(), chunkLength);
bool isReferenceFrame = IsAVCReferenceFrame(accessUnit);
ASSERT_TRUE(isReferenceFrame);
accessUnit.clear();
- layerID = FindAVCLayerId((uint8_t *)data, chunkLength);
+ layerID = FindAVCLayerId((uint8_t *)data.get(), chunkLength);
ASSERT_EQ(layerID, frameLayerID) << "Wrong layer ID found";
}
- delete[] data;
}
}
diff --git a/media/libstagefright/foundation/tests/AVCUtils/Android.bp b/media/module/foundation/tests/AVCUtils/Android.bp
similarity index 100%
rename from media/libstagefright/foundation/tests/AVCUtils/Android.bp
rename to media/module/foundation/tests/AVCUtils/Android.bp
diff --git a/media/libstagefright/foundation/tests/AVCUtils/AndroidTest.xml b/media/module/foundation/tests/AVCUtils/AndroidTest.xml
similarity index 100%
rename from media/libstagefright/foundation/tests/AVCUtils/AndroidTest.xml
rename to media/module/foundation/tests/AVCUtils/AndroidTest.xml
diff --git a/media/libstagefright/foundation/tests/AVCUtils/README.md b/media/module/foundation/tests/AVCUtils/README.md
similarity index 100%
rename from media/libstagefright/foundation/tests/AVCUtils/README.md
rename to media/module/foundation/tests/AVCUtils/README.md
diff --git a/media/libstagefright/foundation/tests/Android.bp b/media/module/foundation/tests/Android.bp
similarity index 100%
rename from media/libstagefright/foundation/tests/Android.bp
rename to media/module/foundation/tests/Android.bp
diff --git a/media/libstagefright/foundation/tests/Base64_test.cpp b/media/module/foundation/tests/Base64_test.cpp
similarity index 100%
rename from media/libstagefright/foundation/tests/Base64_test.cpp
rename to media/module/foundation/tests/Base64_test.cpp
diff --git a/media/libstagefright/foundation/tests/Flagged_test.cpp b/media/module/foundation/tests/Flagged_test.cpp
similarity index 100%
rename from media/libstagefright/foundation/tests/Flagged_test.cpp
rename to media/module/foundation/tests/Flagged_test.cpp
diff --git a/media/libstagefright/foundation/tests/MetaDataBaseUnitTest.cpp b/media/module/foundation/tests/MetaDataBaseUnitTest.cpp
similarity index 96%
rename from media/libstagefright/foundation/tests/MetaDataBaseUnitTest.cpp
rename to media/module/foundation/tests/MetaDataBaseUnitTest.cpp
index 0aed4d2..b562e07 100644
--- a/media/libstagefright/foundation/tests/MetaDataBaseUnitTest.cpp
+++ b/media/module/foundation/tests/MetaDataBaseUnitTest.cpp
@@ -19,6 +19,7 @@
#include <string.h>
#include <sys/stat.h>
#include <fstream>
+#include <memory>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MetaDataBase.h>
@@ -48,18 +49,16 @@
class MetaDataBaseUnitTest : public ::testing::Test {};
TEST_F(MetaDataBaseUnitTest, CreateMetaDataBaseTest) {
- MetaDataBase *metaData = new MetaDataBase();
+ std::unique_ptr<MetaDataBase> metaData(new MetaDataBase());
ASSERT_NE(metaData, nullptr) << "Failed to create meta data";
// Testing copy constructor
- MetaDataBase *metaDataCopy = metaData;
+ MetaDataBase *metaDataCopy = metaData.get();
ASSERT_NE(metaDataCopy, nullptr) << "Failed to create meta data copy";
-
- delete metaData;
}
TEST_F(MetaDataBaseUnitTest, SetAndFindDataTest) {
- MetaDataBase *metaData = new MetaDataBase();
+ std::unique_ptr<MetaDataBase> metaData(new MetaDataBase());
ASSERT_NE(metaData, nullptr) << "Failed to create meta data";
// Setting the different key-value pair type for first time, overwrite
@@ -142,12 +141,10 @@
int32_t angle;
status = metaData->findInt32(kKeyRotation, &angle);
ASSERT_FALSE(status) << "Value for an invalid key is returned when the key is not set";
-
- delete (metaData);
}
TEST_F(MetaDataBaseUnitTest, OverWriteFunctionalityTest) {
- MetaDataBase *metaData = new MetaDataBase();
+ std::unique_ptr<MetaDataBase> metaData(new MetaDataBase());
ASSERT_NE(metaData, nullptr) << "Failed to create meta data";
// set/set/read to check first overwrite operation
@@ -186,12 +183,10 @@
status = metaData->findInt32(kKeyHeight, &height);
ASSERT_TRUE(status) << "kKeyHeight key does not exists in metadata";
ASSERT_EQ(height, kHeight3) << "Value of height is not overwritten";
-
- delete (metaData);
}
TEST_F(MetaDataBaseUnitTest, RemoveKeyTest) {
- MetaDataBase *metaData = new MetaDataBase();
+ std::unique_ptr<MetaDataBase> metaData(new MetaDataBase());
ASSERT_NE(metaData, nullptr) << "Failed to create meta data";
bool status = metaData->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
@@ -246,12 +241,10 @@
metaData->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_HEVC);
ASSERT_FALSE(status) << "Overwrite should be false since the metadata was cleared";
-
- delete (metaData);
}
TEST_F(MetaDataBaseUnitTest, ConvertToStringTest) {
- MetaDataBase *metaData = new MetaDataBase();
+ std::unique_ptr<MetaDataBase> metaData(new MetaDataBase());
ASSERT_NE(metaData, nullptr) << "Failed to create meta data";
String8 info = metaData->toString();
@@ -281,8 +274,6 @@
info = metaData->toString();
ASSERT_EQ(info.length(), 0) << "MetaData length is non-zero after clearing it: "
<< info.length();
-
- delete (metaData);
}
} // namespace android
diff --git a/media/libstagefright/foundation/tests/OpusHeader/Android.bp b/media/module/foundation/tests/OpusHeader/Android.bp
similarity index 100%
rename from media/libstagefright/foundation/tests/OpusHeader/Android.bp
rename to media/module/foundation/tests/OpusHeader/Android.bp
diff --git a/media/libstagefright/foundation/tests/OpusHeader/AndroidTest.xml b/media/module/foundation/tests/OpusHeader/AndroidTest.xml
similarity index 100%
rename from media/libstagefright/foundation/tests/OpusHeader/AndroidTest.xml
rename to media/module/foundation/tests/OpusHeader/AndroidTest.xml
diff --git a/media/libstagefright/foundation/tests/OpusHeader/OpusHeaderTest.cpp b/media/module/foundation/tests/OpusHeader/OpusHeaderTest.cpp
similarity index 100%
rename from media/libstagefright/foundation/tests/OpusHeader/OpusHeaderTest.cpp
rename to media/module/foundation/tests/OpusHeader/OpusHeaderTest.cpp
diff --git a/media/libstagefright/foundation/tests/OpusHeader/OpusHeaderTestEnvironment.h b/media/module/foundation/tests/OpusHeader/OpusHeaderTestEnvironment.h
similarity index 100%
rename from media/libstagefright/foundation/tests/OpusHeader/OpusHeaderTestEnvironment.h
rename to media/module/foundation/tests/OpusHeader/OpusHeaderTestEnvironment.h
diff --git a/media/libstagefright/foundation/tests/OpusHeader/README.md b/media/module/foundation/tests/OpusHeader/README.md
similarity index 100%
rename from media/libstagefright/foundation/tests/OpusHeader/README.md
rename to media/module/foundation/tests/OpusHeader/README.md
diff --git a/media/libstagefright/foundation/tests/TypeTraits_test.cpp b/media/module/foundation/tests/TypeTraits_test.cpp
similarity index 100%
rename from media/libstagefright/foundation/tests/TypeTraits_test.cpp
rename to media/module/foundation/tests/TypeTraits_test.cpp
diff --git a/media/libstagefright/foundation/tests/Utils_test.cpp b/media/module/foundation/tests/Utils_test.cpp
similarity index 100%
rename from media/libstagefright/foundation/tests/Utils_test.cpp
rename to media/module/foundation/tests/Utils_test.cpp
diff --git a/media/libstagefright/foundation/tests/colorutils/Android.bp b/media/module/foundation/tests/colorutils/Android.bp
similarity index 100%
rename from media/libstagefright/foundation/tests/colorutils/Android.bp
rename to media/module/foundation/tests/colorutils/Android.bp
diff --git a/media/libstagefright/foundation/tests/colorutils/ColorUtilsTest.cpp b/media/module/foundation/tests/colorutils/ColorUtilsTest.cpp
similarity index 100%
rename from media/libstagefright/foundation/tests/colorutils/ColorUtilsTest.cpp
rename to media/module/foundation/tests/colorutils/ColorUtilsTest.cpp
diff --git a/media/libstagefright/id3/Android.bp b/media/module/id3/Android.bp
similarity index 100%
rename from media/libstagefright/id3/Android.bp
rename to media/module/id3/Android.bp
diff --git a/media/libstagefright/id3/ID3.cpp b/media/module/id3/ID3.cpp
similarity index 100%
rename from media/libstagefright/id3/ID3.cpp
rename to media/module/id3/ID3.cpp
diff --git a/media/libstagefright/id3/MODULE_LICENSE_APACHE2 b/media/module/id3/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/libstagefright/id3/MODULE_LICENSE_APACHE2
rename to media/module/id3/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/id3/NOTICE b/media/module/id3/NOTICE
similarity index 100%
rename from media/libstagefright/id3/NOTICE
rename to media/module/id3/NOTICE
diff --git a/media/libstagefright/id3/TEST_MAPPING b/media/module/id3/TEST_MAPPING
similarity index 100%
rename from media/libstagefright/id3/TEST_MAPPING
rename to media/module/id3/TEST_MAPPING
diff --git a/media/libstagefright/id3/test/Android.bp b/media/module/id3/test/Android.bp
similarity index 100%
rename from media/libstagefright/id3/test/Android.bp
rename to media/module/id3/test/Android.bp
diff --git a/media/libstagefright/id3/test/AndroidTest.xml b/media/module/id3/test/AndroidTest.xml
similarity index 100%
rename from media/libstagefright/id3/test/AndroidTest.xml
rename to media/module/id3/test/AndroidTest.xml
diff --git a/media/libstagefright/id3/test/ID3Test.cpp b/media/module/id3/test/ID3Test.cpp
similarity index 100%
rename from media/libstagefright/id3/test/ID3Test.cpp
rename to media/module/id3/test/ID3Test.cpp
diff --git a/media/libstagefright/id3/test/ID3TestEnvironment.h b/media/module/id3/test/ID3TestEnvironment.h
similarity index 100%
rename from media/libstagefright/id3/test/ID3TestEnvironment.h
rename to media/module/id3/test/ID3TestEnvironment.h
diff --git a/media/libstagefright/id3/test/README.md b/media/module/id3/test/README.md
similarity index 100%
rename from media/libstagefright/id3/test/README.md
rename to media/module/id3/test/README.md
diff --git a/media/libstagefright/id3/testid3.cpp b/media/module/id3/testid3.cpp
similarity index 100%
rename from media/libstagefright/id3/testid3.cpp
rename to media/module/id3/testid3.cpp
diff --git a/media/libmediaformatshaper/Android.bp b/media/module/libmediaformatshaper/Android.bp
similarity index 100%
rename from media/libmediaformatshaper/Android.bp
rename to media/module/libmediaformatshaper/Android.bp
diff --git a/media/libmediaformatshaper/CodecProperties.cpp b/media/module/libmediaformatshaper/CodecProperties.cpp
similarity index 100%
rename from media/libmediaformatshaper/CodecProperties.cpp
rename to media/module/libmediaformatshaper/CodecProperties.cpp
diff --git a/media/libmediaformatshaper/CodecProperties.h b/media/module/libmediaformatshaper/CodecProperties.h
similarity index 100%
rename from media/libmediaformatshaper/CodecProperties.h
rename to media/module/libmediaformatshaper/CodecProperties.h
diff --git a/media/libmediaformatshaper/CodecSeeding.cpp b/media/module/libmediaformatshaper/CodecSeeding.cpp
similarity index 100%
rename from media/libmediaformatshaper/CodecSeeding.cpp
rename to media/module/libmediaformatshaper/CodecSeeding.cpp
diff --git a/media/libmediaformatshaper/FormatShaper.cpp b/media/module/libmediaformatshaper/FormatShaper.cpp
similarity index 100%
rename from media/libmediaformatshaper/FormatShaper.cpp
rename to media/module/libmediaformatshaper/FormatShaper.cpp
diff --git a/media/libmediaformatshaper/ManageShapingCodecs.cpp b/media/module/libmediaformatshaper/ManageShapingCodecs.cpp
similarity index 100%
rename from media/libmediaformatshaper/ManageShapingCodecs.cpp
rename to media/module/libmediaformatshaper/ManageShapingCodecs.cpp
diff --git a/media/libmediaformatshaper/VQApply.cpp b/media/module/libmediaformatshaper/VQApply.cpp
similarity index 100%
rename from media/libmediaformatshaper/VQApply.cpp
rename to media/module/libmediaformatshaper/VQApply.cpp
diff --git a/media/libmediaformatshaper/VQops.h b/media/module/libmediaformatshaper/VQops.h
similarity index 100%
rename from media/libmediaformatshaper/VQops.h
rename to media/module/libmediaformatshaper/VQops.h
diff --git a/media/libmediaformatshaper/VideoShaper.cpp b/media/module/libmediaformatshaper/VideoShaper.cpp
similarity index 100%
rename from media/libmediaformatshaper/VideoShaper.cpp
rename to media/module/libmediaformatshaper/VideoShaper.cpp
diff --git a/media/libmediaformatshaper/VideoShaper.h b/media/module/libmediaformatshaper/VideoShaper.h
similarity index 100%
rename from media/libmediaformatshaper/VideoShaper.h
rename to media/module/libmediaformatshaper/VideoShaper.h
diff --git a/media/libmediaformatshaper/exports.lds b/media/module/libmediaformatshaper/exports.lds
similarity index 100%
rename from media/libmediaformatshaper/exports.lds
rename to media/module/libmediaformatshaper/exports.lds
diff --git a/media/libmediaformatshaper/include/media/formatshaper/FormatShaper.h b/media/module/libmediaformatshaper/include/media/formatshaper/FormatShaper.h
similarity index 100%
rename from media/libmediaformatshaper/include/media/formatshaper/FormatShaper.h
rename to media/module/libmediaformatshaper/include/media/formatshaper/FormatShaper.h
diff --git a/media/libmediatranscoding/.clang-format b/media/module/libmediatranscoding/.clang-format
similarity index 100%
rename from media/libmediatranscoding/.clang-format
rename to media/module/libmediatranscoding/.clang-format
diff --git a/media/libmediatranscoding/Android.bp b/media/module/libmediatranscoding/Android.bp
similarity index 100%
rename from media/libmediatranscoding/Android.bp
rename to media/module/libmediatranscoding/Android.bp
diff --git a/media/libmediatranscoding/OWNERS b/media/module/libmediatranscoding/OWNERS
similarity index 100%
rename from media/libmediatranscoding/OWNERS
rename to media/module/libmediatranscoding/OWNERS
diff --git a/media/libmediatranscoding/TEST_MAPPING b/media/module/libmediatranscoding/TEST_MAPPING
similarity index 100%
rename from media/libmediatranscoding/TEST_MAPPING
rename to media/module/libmediatranscoding/TEST_MAPPING
diff --git a/media/libmediatranscoding/TranscoderWrapper.cpp b/media/module/libmediatranscoding/TranscoderWrapper.cpp
similarity index 100%
rename from media/libmediatranscoding/TranscoderWrapper.cpp
rename to media/module/libmediatranscoding/TranscoderWrapper.cpp
diff --git a/media/libmediatranscoding/TranscodingClientManager.cpp b/media/module/libmediatranscoding/TranscodingClientManager.cpp
similarity index 100%
rename from media/libmediatranscoding/TranscodingClientManager.cpp
rename to media/module/libmediatranscoding/TranscodingClientManager.cpp
diff --git a/media/libmediatranscoding/TranscodingLogger.cpp b/media/module/libmediatranscoding/TranscodingLogger.cpp
similarity index 100%
rename from media/libmediatranscoding/TranscodingLogger.cpp
rename to media/module/libmediatranscoding/TranscodingLogger.cpp
diff --git a/media/libmediatranscoding/TranscodingResourcePolicy.cpp b/media/module/libmediatranscoding/TranscodingResourcePolicy.cpp
similarity index 100%
rename from media/libmediatranscoding/TranscodingResourcePolicy.cpp
rename to media/module/libmediatranscoding/TranscodingResourcePolicy.cpp
diff --git a/media/libmediatranscoding/TranscodingSessionController.cpp b/media/module/libmediatranscoding/TranscodingSessionController.cpp
similarity index 100%
rename from media/libmediatranscoding/TranscodingSessionController.cpp
rename to media/module/libmediatranscoding/TranscodingSessionController.cpp
diff --git a/media/libmediatranscoding/TranscodingThermalPolicy.cpp b/media/module/libmediatranscoding/TranscodingThermalPolicy.cpp
similarity index 100%
rename from media/libmediatranscoding/TranscodingThermalPolicy.cpp
rename to media/module/libmediatranscoding/TranscodingThermalPolicy.cpp
diff --git a/media/libmediatranscoding/TranscodingUidPolicy.cpp b/media/module/libmediatranscoding/TranscodingUidPolicy.cpp
similarity index 100%
rename from media/libmediatranscoding/TranscodingUidPolicy.cpp
rename to media/module/libmediatranscoding/TranscodingUidPolicy.cpp
diff --git a/media/libmediatranscoding/aidl/android/media/IMediaTranscodingService.aidl b/media/module/libmediatranscoding/aidl/android/media/IMediaTranscodingService.aidl
similarity index 100%
rename from media/libmediatranscoding/aidl/android/media/IMediaTranscodingService.aidl
rename to media/module/libmediatranscoding/aidl/android/media/IMediaTranscodingService.aidl
diff --git a/media/libmediatranscoding/aidl/android/media/ITranscodingClient.aidl b/media/module/libmediatranscoding/aidl/android/media/ITranscodingClient.aidl
similarity index 100%
rename from media/libmediatranscoding/aidl/android/media/ITranscodingClient.aidl
rename to media/module/libmediatranscoding/aidl/android/media/ITranscodingClient.aidl
diff --git a/media/libmediatranscoding/aidl/android/media/ITranscodingClientCallback.aidl b/media/module/libmediatranscoding/aidl/android/media/ITranscodingClientCallback.aidl
similarity index 100%
rename from media/libmediatranscoding/aidl/android/media/ITranscodingClientCallback.aidl
rename to media/module/libmediatranscoding/aidl/android/media/ITranscodingClientCallback.aidl
diff --git a/media/libmediatranscoding/aidl/android/media/TranscodingErrorCode.aidl b/media/module/libmediatranscoding/aidl/android/media/TranscodingErrorCode.aidl
similarity index 100%
rename from media/libmediatranscoding/aidl/android/media/TranscodingErrorCode.aidl
rename to media/module/libmediatranscoding/aidl/android/media/TranscodingErrorCode.aidl
diff --git a/media/libmediatranscoding/aidl/android/media/TranscodingRequestParcel.aidl b/media/module/libmediatranscoding/aidl/android/media/TranscodingRequestParcel.aidl
similarity index 100%
rename from media/libmediatranscoding/aidl/android/media/TranscodingRequestParcel.aidl
rename to media/module/libmediatranscoding/aidl/android/media/TranscodingRequestParcel.aidl
diff --git a/media/libmediatranscoding/aidl/android/media/TranscodingResultParcel.aidl b/media/module/libmediatranscoding/aidl/android/media/TranscodingResultParcel.aidl
similarity index 100%
rename from media/libmediatranscoding/aidl/android/media/TranscodingResultParcel.aidl
rename to media/module/libmediatranscoding/aidl/android/media/TranscodingResultParcel.aidl
diff --git a/media/libmediatranscoding/aidl/android/media/TranscodingSessionParcel.aidl b/media/module/libmediatranscoding/aidl/android/media/TranscodingSessionParcel.aidl
similarity index 100%
rename from media/libmediatranscoding/aidl/android/media/TranscodingSessionParcel.aidl
rename to media/module/libmediatranscoding/aidl/android/media/TranscodingSessionParcel.aidl
diff --git a/media/libmediatranscoding/aidl/android/media/TranscodingSessionPriority.aidl b/media/module/libmediatranscoding/aidl/android/media/TranscodingSessionPriority.aidl
similarity index 100%
rename from media/libmediatranscoding/aidl/android/media/TranscodingSessionPriority.aidl
rename to media/module/libmediatranscoding/aidl/android/media/TranscodingSessionPriority.aidl
diff --git a/media/libmediatranscoding/aidl/android/media/TranscodingSessionStats.aidl b/media/module/libmediatranscoding/aidl/android/media/TranscodingSessionStats.aidl
similarity index 100%
rename from media/libmediatranscoding/aidl/android/media/TranscodingSessionStats.aidl
rename to media/module/libmediatranscoding/aidl/android/media/TranscodingSessionStats.aidl
diff --git a/media/libmediatranscoding/aidl/android/media/TranscodingTestConfig.aidl b/media/module/libmediatranscoding/aidl/android/media/TranscodingTestConfig.aidl
similarity index 100%
rename from media/libmediatranscoding/aidl/android/media/TranscodingTestConfig.aidl
rename to media/module/libmediatranscoding/aidl/android/media/TranscodingTestConfig.aidl
diff --git a/media/libmediatranscoding/aidl/android/media/TranscodingType.aidl b/media/module/libmediatranscoding/aidl/android/media/TranscodingType.aidl
similarity index 100%
rename from media/libmediatranscoding/aidl/android/media/TranscodingType.aidl
rename to media/module/libmediatranscoding/aidl/android/media/TranscodingType.aidl
diff --git a/media/libmediatranscoding/aidl/android/media/TranscodingVideoCodecType.aidl b/media/module/libmediatranscoding/aidl/android/media/TranscodingVideoCodecType.aidl
similarity index 100%
rename from media/libmediatranscoding/aidl/android/media/TranscodingVideoCodecType.aidl
rename to media/module/libmediatranscoding/aidl/android/media/TranscodingVideoCodecType.aidl
diff --git a/media/libmediatranscoding/aidl/android/media/TranscodingVideoTrackFormat.aidl b/media/module/libmediatranscoding/aidl/android/media/TranscodingVideoTrackFormat.aidl
similarity index 100%
rename from media/libmediatranscoding/aidl/android/media/TranscodingVideoTrackFormat.aidl
rename to media/module/libmediatranscoding/aidl/android/media/TranscodingVideoTrackFormat.aidl
diff --git a/media/libmediatranscoding/build_and_run_all_unit_tests.sh b/media/module/libmediatranscoding/build_and_run_all_unit_tests.sh
similarity index 100%
rename from media/libmediatranscoding/build_and_run_all_unit_tests.sh
rename to media/module/libmediatranscoding/build_and_run_all_unit_tests.sh
diff --git a/media/libmediatranscoding/include/media/AdjustableMaxPriorityQueue.h b/media/module/libmediatranscoding/include/media/AdjustableMaxPriorityQueue.h
similarity index 100%
rename from media/libmediatranscoding/include/media/AdjustableMaxPriorityQueue.h
rename to media/module/libmediatranscoding/include/media/AdjustableMaxPriorityQueue.h
diff --git a/media/libmediatranscoding/include/media/ControllerClientInterface.h b/media/module/libmediatranscoding/include/media/ControllerClientInterface.h
similarity index 100%
rename from media/libmediatranscoding/include/media/ControllerClientInterface.h
rename to media/module/libmediatranscoding/include/media/ControllerClientInterface.h
diff --git a/media/libmediatranscoding/include/media/ResourcePolicyInterface.h b/media/module/libmediatranscoding/include/media/ResourcePolicyInterface.h
similarity index 100%
rename from media/libmediatranscoding/include/media/ResourcePolicyInterface.h
rename to media/module/libmediatranscoding/include/media/ResourcePolicyInterface.h
diff --git a/media/libmediatranscoding/include/media/ThermalPolicyInterface.h b/media/module/libmediatranscoding/include/media/ThermalPolicyInterface.h
similarity index 100%
rename from media/libmediatranscoding/include/media/ThermalPolicyInterface.h
rename to media/module/libmediatranscoding/include/media/ThermalPolicyInterface.h
diff --git a/media/libmediatranscoding/include/media/TranscoderInterface.h b/media/module/libmediatranscoding/include/media/TranscoderInterface.h
similarity index 100%
rename from media/libmediatranscoding/include/media/TranscoderInterface.h
rename to media/module/libmediatranscoding/include/media/TranscoderInterface.h
diff --git a/media/libmediatranscoding/include/media/TranscoderWrapper.h b/media/module/libmediatranscoding/include/media/TranscoderWrapper.h
similarity index 100%
rename from media/libmediatranscoding/include/media/TranscoderWrapper.h
rename to media/module/libmediatranscoding/include/media/TranscoderWrapper.h
diff --git a/media/libmediatranscoding/include/media/TranscodingClientManager.h b/media/module/libmediatranscoding/include/media/TranscodingClientManager.h
similarity index 100%
rename from media/libmediatranscoding/include/media/TranscodingClientManager.h
rename to media/module/libmediatranscoding/include/media/TranscodingClientManager.h
diff --git a/media/libmediatranscoding/include/media/TranscodingDefs.h b/media/module/libmediatranscoding/include/media/TranscodingDefs.h
similarity index 100%
rename from media/libmediatranscoding/include/media/TranscodingDefs.h
rename to media/module/libmediatranscoding/include/media/TranscodingDefs.h
diff --git a/media/libmediatranscoding/include/media/TranscodingLogger.h b/media/module/libmediatranscoding/include/media/TranscodingLogger.h
similarity index 100%
rename from media/libmediatranscoding/include/media/TranscodingLogger.h
rename to media/module/libmediatranscoding/include/media/TranscodingLogger.h
diff --git a/media/libmediatranscoding/include/media/TranscodingRequest.h b/media/module/libmediatranscoding/include/media/TranscodingRequest.h
similarity index 100%
rename from media/libmediatranscoding/include/media/TranscodingRequest.h
rename to media/module/libmediatranscoding/include/media/TranscodingRequest.h
diff --git a/media/libmediatranscoding/include/media/TranscodingResourcePolicy.h b/media/module/libmediatranscoding/include/media/TranscodingResourcePolicy.h
similarity index 100%
rename from media/libmediatranscoding/include/media/TranscodingResourcePolicy.h
rename to media/module/libmediatranscoding/include/media/TranscodingResourcePolicy.h
diff --git a/media/libmediatranscoding/include/media/TranscodingSessionController.h b/media/module/libmediatranscoding/include/media/TranscodingSessionController.h
similarity index 100%
rename from media/libmediatranscoding/include/media/TranscodingSessionController.h
rename to media/module/libmediatranscoding/include/media/TranscodingSessionController.h
diff --git a/media/libmediatranscoding/include/media/TranscodingThermalPolicy.h b/media/module/libmediatranscoding/include/media/TranscodingThermalPolicy.h
similarity index 100%
rename from media/libmediatranscoding/include/media/TranscodingThermalPolicy.h
rename to media/module/libmediatranscoding/include/media/TranscodingThermalPolicy.h
diff --git a/media/libmediatranscoding/include/media/TranscodingUidPolicy.h b/media/module/libmediatranscoding/include/media/TranscodingUidPolicy.h
similarity index 100%
rename from media/libmediatranscoding/include/media/TranscodingUidPolicy.h
rename to media/module/libmediatranscoding/include/media/TranscodingUidPolicy.h
diff --git a/media/libmediatranscoding/include/media/UidPolicyInterface.h b/media/module/libmediatranscoding/include/media/UidPolicyInterface.h
similarity index 100%
rename from media/libmediatranscoding/include/media/UidPolicyInterface.h
rename to media/module/libmediatranscoding/include/media/UidPolicyInterface.h
diff --git a/media/libmediatranscoding/tests/AdjustableMaxPriorityQueue_tests.cpp b/media/module/libmediatranscoding/tests/AdjustableMaxPriorityQueue_tests.cpp
similarity index 100%
rename from media/libmediatranscoding/tests/AdjustableMaxPriorityQueue_tests.cpp
rename to media/module/libmediatranscoding/tests/AdjustableMaxPriorityQueue_tests.cpp
diff --git a/media/libmediatranscoding/tests/Android.bp b/media/module/libmediatranscoding/tests/Android.bp
similarity index 100%
rename from media/libmediatranscoding/tests/Android.bp
rename to media/module/libmediatranscoding/tests/Android.bp
diff --git a/media/libmediatranscoding/tests/TranscodingClientManager_tests.cpp b/media/module/libmediatranscoding/tests/TranscodingClientManager_tests.cpp
similarity index 100%
rename from media/libmediatranscoding/tests/TranscodingClientManager_tests.cpp
rename to media/module/libmediatranscoding/tests/TranscodingClientManager_tests.cpp
diff --git a/media/libmediatranscoding/tests/TranscodingLogger_tests.cpp b/media/module/libmediatranscoding/tests/TranscodingLogger_tests.cpp
similarity index 100%
rename from media/libmediatranscoding/tests/TranscodingLogger_tests.cpp
rename to media/module/libmediatranscoding/tests/TranscodingLogger_tests.cpp
diff --git a/media/libmediatranscoding/tests/TranscodingSessionController_tests.cpp b/media/module/libmediatranscoding/tests/TranscodingSessionController_tests.cpp
similarity index 99%
rename from media/libmediatranscoding/tests/TranscodingSessionController_tests.cpp
rename to media/module/libmediatranscoding/tests/TranscodingSessionController_tests.cpp
index ef9c4f8..fdd327f 100644
--- a/media/libmediatranscoding/tests/TranscodingSessionController_tests.cpp
+++ b/media/module/libmediatranscoding/tests/TranscodingSessionController_tests.cpp
@@ -337,6 +337,8 @@
// Should have created new transcoder.
EXPECT_EQ(mTranscoder->getGeneration(), generation);
EXPECT_EQ(mTranscoder.use_count(), 2);
+ // b/240537336: Allow extra time to finish onError call
+ sleep(1);
}
void testPacerHelper(int numSubmits, int sessionDurationMs, int expectedSuccess) {
diff --git a/media/libmediatranscoding/tests/assets/TranscodingTestAssets/Video_4K_HEVC_10Frames_Audio.mp4 b/media/module/libmediatranscoding/tests/assets/TranscodingTestAssets/Video_4K_HEVC_10Frames_Audio.mp4
similarity index 100%
rename from media/libmediatranscoding/tests/assets/TranscodingTestAssets/Video_4K_HEVC_10Frames_Audio.mp4
rename to media/module/libmediatranscoding/tests/assets/TranscodingTestAssets/Video_4K_HEVC_10Frames_Audio.mp4
Binary files differ
diff --git a/media/libmediatranscoding/tests/assets/TranscodingTestAssets/backyard_hevc_1920x1080_20Mbps.mp4 b/media/module/libmediatranscoding/tests/assets/TranscodingTestAssets/backyard_hevc_1920x1080_20Mbps.mp4
similarity index 100%
rename from media/libmediatranscoding/tests/assets/TranscodingTestAssets/backyard_hevc_1920x1080_20Mbps.mp4
rename to media/module/libmediatranscoding/tests/assets/TranscodingTestAssets/backyard_hevc_1920x1080_20Mbps.mp4
Binary files differ
diff --git a/media/libmediatranscoding/tests/assets/TranscodingTestAssets/cubicle_avc_480x240_aac_24KHz.mp4 b/media/module/libmediatranscoding/tests/assets/TranscodingTestAssets/cubicle_avc_480x240_aac_24KHz.mp4
similarity index 100%
rename from media/libmediatranscoding/tests/assets/TranscodingTestAssets/cubicle_avc_480x240_aac_24KHz.mp4
rename to media/module/libmediatranscoding/tests/assets/TranscodingTestAssets/cubicle_avc_480x240_aac_24KHz.mp4
Binary files differ
diff --git a/media/libmediatranscoding/tests/assets/TranscodingTestAssets/desk_hevc_1920x1080_aac_48KHz_rot90.mp4 b/media/module/libmediatranscoding/tests/assets/TranscodingTestAssets/desk_hevc_1920x1080_aac_48KHz_rot90.mp4
similarity index 100%
rename from media/libmediatranscoding/tests/assets/TranscodingTestAssets/desk_hevc_1920x1080_aac_48KHz_rot90.mp4
rename to media/module/libmediatranscoding/tests/assets/TranscodingTestAssets/desk_hevc_1920x1080_aac_48KHz_rot90.mp4
Binary files differ
diff --git a/media/libmediatranscoding/tests/assets/TranscodingTestAssets/jets_hevc_1280x720_20Mbps.mp4 b/media/module/libmediatranscoding/tests/assets/TranscodingTestAssets/jets_hevc_1280x720_20Mbps.mp4
similarity index 100%
rename from media/libmediatranscoding/tests/assets/TranscodingTestAssets/jets_hevc_1280x720_20Mbps.mp4
rename to media/module/libmediatranscoding/tests/assets/TranscodingTestAssets/jets_hevc_1280x720_20Mbps.mp4
Binary files differ
diff --git a/media/libmediatranscoding/tests/assets/TranscodingTestAssets/longtest_15s.mp4 b/media/module/libmediatranscoding/tests/assets/TranscodingTestAssets/longtest_15s.mp4
similarity index 100%
rename from media/libmediatranscoding/tests/assets/TranscodingTestAssets/longtest_15s.mp4
rename to media/module/libmediatranscoding/tests/assets/TranscodingTestAssets/longtest_15s.mp4
Binary files differ
diff --git a/media/libmediatranscoding/tests/assets/TranscodingTestAssets/plex_hevc_3840x2160_12Mbps.mp4 b/media/module/libmediatranscoding/tests/assets/TranscodingTestAssets/plex_hevc_3840x2160_12Mbps.mp4
similarity index 100%
rename from media/libmediatranscoding/tests/assets/TranscodingTestAssets/plex_hevc_3840x2160_12Mbps.mp4
rename to media/module/libmediatranscoding/tests/assets/TranscodingTestAssets/plex_hevc_3840x2160_12Mbps.mp4
Binary files differ
diff --git a/media/libmediatranscoding/tests/assets/TranscodingTestAssets/plex_hevc_3840x2160_20Mbps.mp4 b/media/module/libmediatranscoding/tests/assets/TranscodingTestAssets/plex_hevc_3840x2160_20Mbps.mp4
similarity index 100%
rename from media/libmediatranscoding/tests/assets/TranscodingTestAssets/plex_hevc_3840x2160_20Mbps.mp4
rename to media/module/libmediatranscoding/tests/assets/TranscodingTestAssets/plex_hevc_3840x2160_20Mbps.mp4
Binary files differ
diff --git a/media/libmediatranscoding/tests/assets/TranscodingTestAssets/video_1280x720_hevc_hdr10_static_3mbps.mp4 b/media/module/libmediatranscoding/tests/assets/TranscodingTestAssets/video_1280x720_hevc_hdr10_static_3mbps.mp4
similarity index 100%
rename from media/libmediatranscoding/tests/assets/TranscodingTestAssets/video_1280x720_hevc_hdr10_static_3mbps.mp4
rename to media/module/libmediatranscoding/tests/assets/TranscodingTestAssets/video_1280x720_hevc_hdr10_static_3mbps.mp4
Binary files differ
diff --git a/media/libmediatranscoding/tests/build_and_run_all_unit_tests.sh b/media/module/libmediatranscoding/tests/build_and_run_all_unit_tests.sh
similarity index 100%
rename from media/libmediatranscoding/tests/build_and_run_all_unit_tests.sh
rename to media/module/libmediatranscoding/tests/build_and_run_all_unit_tests.sh
diff --git a/media/libmediatranscoding/tests/push_assets.sh b/media/module/libmediatranscoding/tests/push_assets.sh
similarity index 100%
rename from media/libmediatranscoding/tests/push_assets.sh
rename to media/module/libmediatranscoding/tests/push_assets.sh
diff --git a/media/libmediatranscoding/transcoder/Android.bp b/media/module/libmediatranscoding/transcoder/Android.bp
similarity index 100%
rename from media/libmediatranscoding/transcoder/Android.bp
rename to media/module/libmediatranscoding/transcoder/Android.bp
diff --git a/media/libmediatranscoding/transcoder/MediaSampleQueue.cpp b/media/module/libmediatranscoding/transcoder/MediaSampleQueue.cpp
similarity index 100%
rename from media/libmediatranscoding/transcoder/MediaSampleQueue.cpp
rename to media/module/libmediatranscoding/transcoder/MediaSampleQueue.cpp
diff --git a/media/libmediatranscoding/transcoder/MediaSampleReaderNDK.cpp b/media/module/libmediatranscoding/transcoder/MediaSampleReaderNDK.cpp
similarity index 100%
rename from media/libmediatranscoding/transcoder/MediaSampleReaderNDK.cpp
rename to media/module/libmediatranscoding/transcoder/MediaSampleReaderNDK.cpp
diff --git a/media/libmediatranscoding/transcoder/MediaSampleWriter.cpp b/media/module/libmediatranscoding/transcoder/MediaSampleWriter.cpp
similarity index 100%
rename from media/libmediatranscoding/transcoder/MediaSampleWriter.cpp
rename to media/module/libmediatranscoding/transcoder/MediaSampleWriter.cpp
diff --git a/media/libmediatranscoding/transcoder/MediaTrackTranscoder.cpp b/media/module/libmediatranscoding/transcoder/MediaTrackTranscoder.cpp
similarity index 100%
rename from media/libmediatranscoding/transcoder/MediaTrackTranscoder.cpp
rename to media/module/libmediatranscoding/transcoder/MediaTrackTranscoder.cpp
diff --git a/media/libmediatranscoding/transcoder/MediaTranscoder.cpp b/media/module/libmediatranscoding/transcoder/MediaTranscoder.cpp
similarity index 100%
rename from media/libmediatranscoding/transcoder/MediaTranscoder.cpp
rename to media/module/libmediatranscoding/transcoder/MediaTranscoder.cpp
diff --git a/media/libmediatranscoding/transcoder/NdkCommon.cpp b/media/module/libmediatranscoding/transcoder/NdkCommon.cpp
similarity index 100%
rename from media/libmediatranscoding/transcoder/NdkCommon.cpp
rename to media/module/libmediatranscoding/transcoder/NdkCommon.cpp
diff --git a/media/libmediatranscoding/transcoder/PassthroughTrackTranscoder.cpp b/media/module/libmediatranscoding/transcoder/PassthroughTrackTranscoder.cpp
similarity index 100%
rename from media/libmediatranscoding/transcoder/PassthroughTrackTranscoder.cpp
rename to media/module/libmediatranscoding/transcoder/PassthroughTrackTranscoder.cpp
diff --git a/media/libmediatranscoding/transcoder/VideoTrackTranscoder.cpp b/media/module/libmediatranscoding/transcoder/VideoTrackTranscoder.cpp
similarity index 100%
rename from media/libmediatranscoding/transcoder/VideoTrackTranscoder.cpp
rename to media/module/libmediatranscoding/transcoder/VideoTrackTranscoder.cpp
diff --git a/media/libmediatranscoding/transcoder/benchmark/Android.bp b/media/module/libmediatranscoding/transcoder/benchmark/Android.bp
similarity index 100%
rename from media/libmediatranscoding/transcoder/benchmark/Android.bp
rename to media/module/libmediatranscoding/transcoder/benchmark/Android.bp
diff --git a/media/libmediatranscoding/transcoder/benchmark/AndroidTestTemplate.xml b/media/module/libmediatranscoding/transcoder/benchmark/AndroidTestTemplate.xml
similarity index 100%
rename from media/libmediatranscoding/transcoder/benchmark/AndroidTestTemplate.xml
rename to media/module/libmediatranscoding/transcoder/benchmark/AndroidTestTemplate.xml
diff --git a/media/libmediatranscoding/transcoder/benchmark/MediaSampleReaderBenchmark.cpp b/media/module/libmediatranscoding/transcoder/benchmark/MediaSampleReaderBenchmark.cpp
similarity index 100%
rename from media/libmediatranscoding/transcoder/benchmark/MediaSampleReaderBenchmark.cpp
rename to media/module/libmediatranscoding/transcoder/benchmark/MediaSampleReaderBenchmark.cpp
diff --git a/media/libmediatranscoding/transcoder/benchmark/MediaTrackTranscoderBenchmark.cpp b/media/module/libmediatranscoding/transcoder/benchmark/MediaTrackTranscoderBenchmark.cpp
similarity index 100%
rename from media/libmediatranscoding/transcoder/benchmark/MediaTrackTranscoderBenchmark.cpp
rename to media/module/libmediatranscoding/transcoder/benchmark/MediaTrackTranscoderBenchmark.cpp
diff --git a/media/libmediatranscoding/transcoder/benchmark/MediaTranscoderBenchmark.cpp b/media/module/libmediatranscoding/transcoder/benchmark/MediaTranscoderBenchmark.cpp
similarity index 100%
rename from media/libmediatranscoding/transcoder/benchmark/MediaTranscoderBenchmark.cpp
rename to media/module/libmediatranscoding/transcoder/benchmark/MediaTranscoderBenchmark.cpp
diff --git a/media/libmediatranscoding/transcoder/include/media/MediaSample.h b/media/module/libmediatranscoding/transcoder/include/media/MediaSample.h
similarity index 100%
rename from media/libmediatranscoding/transcoder/include/media/MediaSample.h
rename to media/module/libmediatranscoding/transcoder/include/media/MediaSample.h
diff --git a/media/libmediatranscoding/transcoder/include/media/MediaSampleQueue.h b/media/module/libmediatranscoding/transcoder/include/media/MediaSampleQueue.h
similarity index 100%
rename from media/libmediatranscoding/transcoder/include/media/MediaSampleQueue.h
rename to media/module/libmediatranscoding/transcoder/include/media/MediaSampleQueue.h
diff --git a/media/libmediatranscoding/transcoder/include/media/MediaSampleReader.h b/media/module/libmediatranscoding/transcoder/include/media/MediaSampleReader.h
similarity index 100%
rename from media/libmediatranscoding/transcoder/include/media/MediaSampleReader.h
rename to media/module/libmediatranscoding/transcoder/include/media/MediaSampleReader.h
diff --git a/media/libmediatranscoding/transcoder/include/media/MediaSampleReaderNDK.h b/media/module/libmediatranscoding/transcoder/include/media/MediaSampleReaderNDK.h
similarity index 100%
rename from media/libmediatranscoding/transcoder/include/media/MediaSampleReaderNDK.h
rename to media/module/libmediatranscoding/transcoder/include/media/MediaSampleReaderNDK.h
diff --git a/media/libmediatranscoding/transcoder/include/media/MediaSampleWriter.h b/media/module/libmediatranscoding/transcoder/include/media/MediaSampleWriter.h
similarity index 100%
rename from media/libmediatranscoding/transcoder/include/media/MediaSampleWriter.h
rename to media/module/libmediatranscoding/transcoder/include/media/MediaSampleWriter.h
diff --git a/media/libmediatranscoding/transcoder/include/media/MediaTrackTranscoder.h b/media/module/libmediatranscoding/transcoder/include/media/MediaTrackTranscoder.h
similarity index 100%
rename from media/libmediatranscoding/transcoder/include/media/MediaTrackTranscoder.h
rename to media/module/libmediatranscoding/transcoder/include/media/MediaTrackTranscoder.h
diff --git a/media/libmediatranscoding/transcoder/include/media/MediaTrackTranscoderCallback.h b/media/module/libmediatranscoding/transcoder/include/media/MediaTrackTranscoderCallback.h
similarity index 100%
rename from media/libmediatranscoding/transcoder/include/media/MediaTrackTranscoderCallback.h
rename to media/module/libmediatranscoding/transcoder/include/media/MediaTrackTranscoderCallback.h
diff --git a/media/libmediatranscoding/transcoder/include/media/MediaTranscoder.h b/media/module/libmediatranscoding/transcoder/include/media/MediaTranscoder.h
similarity index 100%
rename from media/libmediatranscoding/transcoder/include/media/MediaTranscoder.h
rename to media/module/libmediatranscoding/transcoder/include/media/MediaTranscoder.h
diff --git a/media/libmediatranscoding/transcoder/include/media/NdkCommon.h b/media/module/libmediatranscoding/transcoder/include/media/NdkCommon.h
similarity index 100%
rename from media/libmediatranscoding/transcoder/include/media/NdkCommon.h
rename to media/module/libmediatranscoding/transcoder/include/media/NdkCommon.h
diff --git a/media/libmediatranscoding/transcoder/include/media/PassthroughTrackTranscoder.h b/media/module/libmediatranscoding/transcoder/include/media/PassthroughTrackTranscoder.h
similarity index 100%
rename from media/libmediatranscoding/transcoder/include/media/PassthroughTrackTranscoder.h
rename to media/module/libmediatranscoding/transcoder/include/media/PassthroughTrackTranscoder.h
diff --git a/media/libmediatranscoding/transcoder/include/media/VideoTrackTranscoder.h b/media/module/libmediatranscoding/transcoder/include/media/VideoTrackTranscoder.h
similarity index 100%
rename from media/libmediatranscoding/transcoder/include/media/VideoTrackTranscoder.h
rename to media/module/libmediatranscoding/transcoder/include/media/VideoTrackTranscoder.h
diff --git a/media/libmediatranscoding/transcoder/setloglevel.sh b/media/module/libmediatranscoding/transcoder/setloglevel.sh
similarity index 100%
rename from media/libmediatranscoding/transcoder/setloglevel.sh
rename to media/module/libmediatranscoding/transcoder/setloglevel.sh
diff --git a/media/libmediatranscoding/transcoder/tests/Android.bp b/media/module/libmediatranscoding/transcoder/tests/Android.bp
similarity index 100%
rename from media/libmediatranscoding/transcoder/tests/Android.bp
rename to media/module/libmediatranscoding/transcoder/tests/Android.bp
diff --git a/media/libmediatranscoding/transcoder/tests/AndroidTestTemplate.xml b/media/module/libmediatranscoding/transcoder/tests/AndroidTestTemplate.xml
similarity index 100%
rename from media/libmediatranscoding/transcoder/tests/AndroidTestTemplate.xml
rename to media/module/libmediatranscoding/transcoder/tests/AndroidTestTemplate.xml
diff --git a/media/libmediatranscoding/transcoder/tests/HdrTranscodeTests.cpp b/media/module/libmediatranscoding/transcoder/tests/HdrTranscodeTests.cpp
similarity index 100%
rename from media/libmediatranscoding/transcoder/tests/HdrTranscodeTests.cpp
rename to media/module/libmediatranscoding/transcoder/tests/HdrTranscodeTests.cpp
diff --git a/media/libmediatranscoding/transcoder/tests/MediaSampleQueueTests.cpp b/media/module/libmediatranscoding/transcoder/tests/MediaSampleQueueTests.cpp
similarity index 100%
rename from media/libmediatranscoding/transcoder/tests/MediaSampleQueueTests.cpp
rename to media/module/libmediatranscoding/transcoder/tests/MediaSampleQueueTests.cpp
diff --git a/media/libmediatranscoding/transcoder/tests/MediaSampleReaderNDKTests.cpp b/media/module/libmediatranscoding/transcoder/tests/MediaSampleReaderNDKTests.cpp
similarity index 100%
rename from media/libmediatranscoding/transcoder/tests/MediaSampleReaderNDKTests.cpp
rename to media/module/libmediatranscoding/transcoder/tests/MediaSampleReaderNDKTests.cpp
diff --git a/media/libmediatranscoding/transcoder/tests/MediaSampleWriterTests.cpp b/media/module/libmediatranscoding/transcoder/tests/MediaSampleWriterTests.cpp
similarity index 100%
rename from media/libmediatranscoding/transcoder/tests/MediaSampleWriterTests.cpp
rename to media/module/libmediatranscoding/transcoder/tests/MediaSampleWriterTests.cpp
diff --git a/media/libmediatranscoding/transcoder/tests/MediaTrackTranscoderTests.cpp b/media/module/libmediatranscoding/transcoder/tests/MediaTrackTranscoderTests.cpp
similarity index 100%
rename from media/libmediatranscoding/transcoder/tests/MediaTrackTranscoderTests.cpp
rename to media/module/libmediatranscoding/transcoder/tests/MediaTrackTranscoderTests.cpp
diff --git a/media/libmediatranscoding/transcoder/tests/MediaTranscoderTests.cpp b/media/module/libmediatranscoding/transcoder/tests/MediaTranscoderTests.cpp
similarity index 100%
rename from media/libmediatranscoding/transcoder/tests/MediaTranscoderTests.cpp
rename to media/module/libmediatranscoding/transcoder/tests/MediaTranscoderTests.cpp
diff --git a/media/libmediatranscoding/transcoder/tests/PassthroughTrackTranscoderTests.cpp b/media/module/libmediatranscoding/transcoder/tests/PassthroughTrackTranscoderTests.cpp
similarity index 100%
rename from media/libmediatranscoding/transcoder/tests/PassthroughTrackTranscoderTests.cpp
rename to media/module/libmediatranscoding/transcoder/tests/PassthroughTrackTranscoderTests.cpp
diff --git a/media/libmediatranscoding/transcoder/tests/README.md b/media/module/libmediatranscoding/transcoder/tests/README.md
similarity index 100%
rename from media/libmediatranscoding/transcoder/tests/README.md
rename to media/module/libmediatranscoding/transcoder/tests/README.md
diff --git a/media/libmediatranscoding/transcoder/tests/TranscoderTestUtils.h b/media/module/libmediatranscoding/transcoder/tests/TranscoderTestUtils.h
similarity index 100%
rename from media/libmediatranscoding/transcoder/tests/TranscoderTestUtils.h
rename to media/module/libmediatranscoding/transcoder/tests/TranscoderTestUtils.h
diff --git a/media/libmediatranscoding/transcoder/tests/VideoTrackTranscoderTests.cpp b/media/module/libmediatranscoding/transcoder/tests/VideoTrackTranscoderTests.cpp
similarity index 100%
rename from media/libmediatranscoding/transcoder/tests/VideoTrackTranscoderTests.cpp
rename to media/module/libmediatranscoding/transcoder/tests/VideoTrackTranscoderTests.cpp
diff --git a/media/libmediatranscoding/transcoder/tests/build_and_run_all_unit_tests.sh b/media/module/libmediatranscoding/transcoder/tests/build_and_run_all_unit_tests.sh
similarity index 100%
rename from media/libmediatranscoding/transcoder/tests/build_and_run_all_unit_tests.sh
rename to media/module/libmediatranscoding/transcoder/tests/build_and_run_all_unit_tests.sh
diff --git a/media/libmediatranscoding/transcoder/tests/fuzzer/Android.bp b/media/module/libmediatranscoding/transcoder/tests/fuzzer/Android.bp
similarity index 100%
rename from media/libmediatranscoding/transcoder/tests/fuzzer/Android.bp
rename to media/module/libmediatranscoding/transcoder/tests/fuzzer/Android.bp
diff --git a/media/libmediatranscoding/transcoder/tests/fuzzer/README.md b/media/module/libmediatranscoding/transcoder/tests/fuzzer/README.md
similarity index 100%
rename from media/libmediatranscoding/transcoder/tests/fuzzer/README.md
rename to media/module/libmediatranscoding/transcoder/tests/fuzzer/README.md
diff --git a/media/libmediatranscoding/transcoder/tests/fuzzer/media_transcoder_fuzzer.cpp b/media/module/libmediatranscoding/transcoder/tests/fuzzer/media_transcoder_fuzzer.cpp
similarity index 100%
rename from media/libmediatranscoding/transcoder/tests/fuzzer/media_transcoder_fuzzer.cpp
rename to media/module/libmediatranscoding/transcoder/tests/fuzzer/media_transcoder_fuzzer.cpp
diff --git a/media/libmediatranscoding/transcoder/tools/Android.bp b/media/module/libmediatranscoding/transcoder/tools/Android.bp
similarity index 100%
rename from media/libmediatranscoding/transcoder/tools/Android.bp
rename to media/module/libmediatranscoding/transcoder/tools/Android.bp
diff --git a/media/libmediatranscoding/transcoder/tools/Transcode.cpp b/media/module/libmediatranscoding/transcoder/tools/Transcode.cpp
similarity index 100%
rename from media/libmediatranscoding/transcoder/tools/Transcode.cpp
rename to media/module/libmediatranscoding/transcoder/tools/Transcode.cpp
diff --git a/media/libwatchdog/Android.bp b/media/module/libwatchdog/Android.bp
similarity index 100%
rename from media/libwatchdog/Android.bp
rename to media/module/libwatchdog/Android.bp
diff --git a/media/libwatchdog/Watchdog.cpp b/media/module/libwatchdog/Watchdog.cpp
similarity index 100%
rename from media/libwatchdog/Watchdog.cpp
rename to media/module/libwatchdog/Watchdog.cpp
diff --git a/media/libwatchdog/include/watchdog/Watchdog.h b/media/module/libwatchdog/include/watchdog/Watchdog.h
similarity index 100%
rename from media/libwatchdog/include/watchdog/Watchdog.h
rename to media/module/libwatchdog/include/watchdog/Watchdog.h
diff --git a/media/module/metadatautils/Android.bp b/media/module/metadatautils/Android.bp
new file mode 100644
index 0000000..c77474f
--- /dev/null
+++ b/media/module/metadatautils/Android.bp
@@ -0,0 +1,46 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_av_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_av_license"],
+}
+
+cc_library_static {
+ name: "libstagefright_metadatautils",
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.media",
+ ],
+ min_sdk_version: "29",
+
+ srcs: ["MetaDataUtils.cpp"],
+
+ cflags: [
+ "-Werror",
+ "-Wall",
+ ],
+ sanitize: {
+ misc_undefined: [
+ "signed-integer-overflow",
+ ],
+ cfi: true,
+ },
+
+ header_libs: [
+ "libaudioclient_headers",
+ "libstagefright_headers",
+ "libstagefright_foundation_headers",
+ "media_ndk_headers",
+ ],
+
+ host_supported: true,
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
+
+ export_include_dirs: ["include"],
+}
diff --git a/media/libstagefright/MetaDataUtils.cpp b/media/module/metadatautils/MetaDataUtils.cpp
similarity index 100%
rename from media/libstagefright/MetaDataUtils.cpp
rename to media/module/metadatautils/MetaDataUtils.cpp
diff --git a/media/module/metadatautils/TEST_MAPPING b/media/module/metadatautils/TEST_MAPPING
new file mode 100644
index 0000000..21836a5
--- /dev/null
+++ b/media/module/metadatautils/TEST_MAPPING
@@ -0,0 +1,9 @@
+// mappings for frameworks/av/media/module/metadatautils
+{
+ // tests which require dynamic content
+ // invoke with: atest -- --enable-module-dynamic-download=true
+ // TODO(b/148094059): unit tests not allowed to download content
+ "dynamic-presubmit": [
+ { "name": "MetaDataUtilsTest" }
+ ]
+}
diff --git a/media/libstagefright/include/media/stagefright/MetaDataUtils.h b/media/module/metadatautils/include/media/stagefright/MetaDataUtils.h
similarity index 100%
rename from media/libstagefright/include/media/stagefright/MetaDataUtils.h
rename to media/module/metadatautils/include/media/stagefright/MetaDataUtils.h
diff --git a/media/libstagefright/tests/metadatautils/Android.bp b/media/module/metadatautils/test/Android.bp
similarity index 93%
rename from media/libstagefright/tests/metadatautils/Android.bp
rename to media/module/metadatautils/test/Android.bp
index ecdf89b..21f38f6 100644
--- a/media/libstagefright/tests/metadatautils/Android.bp
+++ b/media/module/metadatautils/test/Android.bp
@@ -20,9 +20,6 @@
// all of the 'license_kinds' from "frameworks_av_media_libstagefright_tests_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: [
- "frameworks_av_media_libstagefright_tests_license",
- ],
}
cc_test {
diff --git a/media/libstagefright/tests/metadatautils/AndroidTest.xml b/media/module/metadatautils/test/AndroidTest.xml
similarity index 100%
rename from media/libstagefright/tests/metadatautils/AndroidTest.xml
rename to media/module/metadatautils/test/AndroidTest.xml
diff --git a/media/libstagefright/tests/metadatautils/MetaDataUtilsTest.cpp b/media/module/metadatautils/test/MetaDataUtilsTest.cpp
similarity index 96%
rename from media/libstagefright/tests/metadatautils/MetaDataUtilsTest.cpp
rename to media/module/metadatautils/test/MetaDataUtilsTest.cpp
index 9fd5fdb..7c35249 100644
--- a/media/libstagefright/tests/metadatautils/MetaDataUtilsTest.cpp
+++ b/media/module/metadatautils/test/MetaDataUtilsTest.cpp
@@ -19,9 +19,10 @@
#include <utils/Log.h>
#include <fstream>
+#include <memory>
#include <string>
-#include <ESDS.h>
+#include <media/esds/ESDS.h>
#include <media/NdkMediaFormat.h>
#include <media/stagefright/MediaCodecConstants.h>
#include <media/stagefright/MediaDefs.h>
@@ -228,7 +229,7 @@
ASSERT_TRUE(status) << "Failed to get the mime type";
ASSERT_STREQ(mimeType, MEDIA_MIMETYPE_VIDEO_AVC);
- MetaDataBase *metaData = new MetaDataBase();
+ std::unique_ptr<MetaDataBase> metaData(new MetaDataBase());
ASSERT_NE(metaData, nullptr) << "Failed to create MetaData Base";
status = MakeAVCCodecSpecificData(*metaData, mInputBuffer, mInputBufferSize);
@@ -264,7 +265,6 @@
int32_t result = memcmp(csdAMediaFormatBuffer, csdMetaDataBaseBuffer, csdAMediaFormatSize);
ASSERT_EQ(result, 0) << "CSD from AMediaFormat and MetaDataBase do not match";
- delete metaData;
AMediaFormat_delete(csdData);
}
@@ -275,7 +275,7 @@
bool status = MakeAVCCodecSpecificData(csdData, mInputBuffer, mInputBufferSize);
ASSERT_FALSE(status) << "MakeAVCCodecSpecificData with AMediaFormat succeeds with invalid data";
- MetaDataBase *metaData = new MetaDataBase();
+ std::unique_ptr<MetaDataBase> metaData(new MetaDataBase());
ASSERT_NE(metaData, nullptr) << "Failed to create MetaData Base";
status = MakeAVCCodecSpecificData(*metaData, mInputBuffer, mInputBufferSize);
@@ -307,7 +307,7 @@
ASSERT_TRUE(status) << "Failed to get the mime type";
ASSERT_STREQ(mimeType, MEDIA_MIMETYPE_AUDIO_AAC);
- MetaDataBase *metaData = new MetaDataBase();
+ std::unique_ptr<MetaDataBase> metaData(new MetaDataBase());
ASSERT_NE(metaData, nullptr) << "Failed to create MetaData Base";
status = MakeAACCodecSpecificData(*metaData, mAacProfile, mAacSamplingFreqIndex,
@@ -356,11 +356,10 @@
ASSERT_EQ(memcmpResult, 0) << "AMediaFormat and MetaDataBase CSDs do not match";
AMediaFormat_delete(csdData);
- delete metaData;
}
TEST_P(AacADTSTest, AacADTSValidationTest) {
- MetaDataBase *metaData = new MetaDataBase();
+ std::unique_ptr<MetaDataBase> metaData(new MetaDataBase());
ASSERT_NE(metaData, nullptr) << "Failed to create meta data";
bool status = MakeAACCodecSpecificData(*metaData, mInputBuffer, kAdtsCsdSize);
@@ -380,12 +379,10 @@
status = metaData->findCString(kKeyMIMEType, &mimeType);
ASSERT_TRUE(status) << "Failed to get mime type";
ASSERT_STREQ(mimeType, MEDIA_MIMETYPE_AUDIO_AAC);
-
- delete metaData;
}
TEST_P(AacCSDValidateTest, AacInvalidInputTest) {
- MetaDataBase *metaData = new MetaDataBase();
+ std::unique_ptr<MetaDataBase> metaData(new MetaDataBase());
ASSERT_NE(metaData, nullptr) << "Failed to create meta data";
bool status = MakeAACCodecSpecificData(*metaData, mInputBuffer, kAdtsCsdSize);
@@ -412,14 +409,14 @@
istringstream dataStringLine(dataLine);
dataStringLine >> comment;
- char *buffer = strndup(comment.c_str(), commentLength);
+ std::unique_ptr<char[]> buffer(new char[commentLength]);
ASSERT_NE(buffer, nullptr) << "Failed to allocate buffer of size: " << commentLength;
+ strncpy(buffer.get(), comment.c_str(), commentLength);
AMediaFormat *fileMeta = AMediaFormat_new();
ASSERT_NE(fileMeta, nullptr) << "Failed to create AMedia format";
- parseVorbisComment(fileMeta, buffer, commentLength);
- free(buffer);
+ parseVorbisComment(fileMeta, buffer.get(), commentLength);
if (!strncasecmp(tag.c_str(), "ANDROID_HAPTIC", sizeof(tag))) {
int32_t numChannelExpected = stoi(value);
diff --git a/media/libstagefright/tests/metadatautils/MetaDataUtilsTestEnvironment.h b/media/module/metadatautils/test/MetaDataUtilsTestEnvironment.h
similarity index 100%
rename from media/libstagefright/tests/metadatautils/MetaDataUtilsTestEnvironment.h
rename to media/module/metadatautils/test/MetaDataUtilsTestEnvironment.h
diff --git a/media/libstagefright/tests/metadatautils/README.md b/media/module/metadatautils/test/README.md
similarity index 100%
rename from media/libstagefright/tests/metadatautils/README.md
rename to media/module/metadatautils/test/README.md
diff --git a/services/minijail/Android.bp b/media/module/minijail/Android.bp
similarity index 100%
rename from services/minijail/Android.bp
rename to media/module/minijail/Android.bp
diff --git a/services/minijail/OWNERS b/media/module/minijail/OWNERS
similarity index 100%
rename from services/minijail/OWNERS
rename to media/module/minijail/OWNERS
diff --git a/services/minijail/TEST_MAPPING b/media/module/minijail/TEST_MAPPING
similarity index 100%
rename from services/minijail/TEST_MAPPING
rename to media/module/minijail/TEST_MAPPING
diff --git a/services/minijail/av_services_minijail_unittest.cpp b/media/module/minijail/av_services_minijail_unittest.cpp
similarity index 100%
rename from services/minijail/av_services_minijail_unittest.cpp
rename to media/module/minijail/av_services_minijail_unittest.cpp
diff --git a/services/minijail/minijail.cpp b/media/module/minijail/minijail.cpp
similarity index 100%
rename from services/minijail/minijail.cpp
rename to media/module/minijail/minijail.cpp
diff --git a/services/minijail/minijail.h b/media/module/minijail/minijail.h
similarity index 100%
rename from services/minijail/minijail.h
rename to media/module/minijail/minijail.h
diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/module/mpeg2ts/ATSParser.cpp
similarity index 100%
rename from media/libstagefright/mpeg2ts/ATSParser.cpp
rename to media/module/mpeg2ts/ATSParser.cpp
diff --git a/media/libstagefright/mpeg2ts/Android.bp b/media/module/mpeg2ts/Android.bp
similarity index 98%
rename from media/libstagefright/mpeg2ts/Android.bp
rename to media/module/mpeg2ts/Android.bp
index 283df1e..bf762c6 100644
--- a/media/libstagefright/mpeg2ts/Android.bp
+++ b/media/module/mpeg2ts/Android.bp
@@ -51,6 +51,7 @@
"libmedia_datasource_headers",
"libaudioclient_headers",
"media_ndk_headers",
+ "libstagefright_headers",
"libstagefright_foundation_headers",
],
diff --git a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp b/media/module/mpeg2ts/AnotherPacketSource.cpp
similarity index 100%
rename from media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
rename to media/module/mpeg2ts/AnotherPacketSource.cpp
diff --git a/media/libstagefright/mpeg2ts/CasManager.cpp b/media/module/mpeg2ts/CasManager.cpp
similarity index 100%
rename from media/libstagefright/mpeg2ts/CasManager.cpp
rename to media/module/mpeg2ts/CasManager.cpp
diff --git a/media/libstagefright/mpeg2ts/ESQueue.cpp b/media/module/mpeg2ts/ESQueue.cpp
similarity index 100%
rename from media/libstagefright/mpeg2ts/ESQueue.cpp
rename to media/module/mpeg2ts/ESQueue.cpp
diff --git a/media/libstagefright/mpeg2ts/HlsSampleDecryptor.cpp b/media/module/mpeg2ts/HlsSampleDecryptor.cpp
similarity index 100%
rename from media/libstagefright/mpeg2ts/HlsSampleDecryptor.cpp
rename to media/module/mpeg2ts/HlsSampleDecryptor.cpp
diff --git a/media/libstagefright/mpeg2ts/MODULE_LICENSE_APACHE2 b/media/module/mpeg2ts/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/libstagefright/mpeg2ts/MODULE_LICENSE_APACHE2
rename to media/module/mpeg2ts/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/mpeg2ts/NOTICE b/media/module/mpeg2ts/NOTICE
similarity index 100%
rename from media/libstagefright/mpeg2ts/NOTICE
rename to media/module/mpeg2ts/NOTICE
diff --git a/media/libstagefright/mpeg2ts/TEST_MAPPING b/media/module/mpeg2ts/TEST_MAPPING
similarity index 100%
rename from media/libstagefright/mpeg2ts/TEST_MAPPING
rename to media/module/mpeg2ts/TEST_MAPPING
diff --git a/media/libstagefright/mpeg2ts/include/mpeg2ts/ATSParser.h b/media/module/mpeg2ts/include/mpeg2ts/ATSParser.h
similarity index 100%
rename from media/libstagefright/mpeg2ts/include/mpeg2ts/ATSParser.h
rename to media/module/mpeg2ts/include/mpeg2ts/ATSParser.h
diff --git a/media/libstagefright/mpeg2ts/include/mpeg2ts/AnotherPacketSource.h b/media/module/mpeg2ts/include/mpeg2ts/AnotherPacketSource.h
similarity index 100%
rename from media/libstagefright/mpeg2ts/include/mpeg2ts/AnotherPacketSource.h
rename to media/module/mpeg2ts/include/mpeg2ts/AnotherPacketSource.h
diff --git a/media/libstagefright/mpeg2ts/include/mpeg2ts/CasManager.h b/media/module/mpeg2ts/include/mpeg2ts/CasManager.h
similarity index 100%
rename from media/libstagefright/mpeg2ts/include/mpeg2ts/CasManager.h
rename to media/module/mpeg2ts/include/mpeg2ts/CasManager.h
diff --git a/media/libstagefright/mpeg2ts/include/mpeg2ts/ESQueue.h b/media/module/mpeg2ts/include/mpeg2ts/ESQueue.h
similarity index 100%
rename from media/libstagefright/mpeg2ts/include/mpeg2ts/ESQueue.h
rename to media/module/mpeg2ts/include/mpeg2ts/ESQueue.h
diff --git a/media/libstagefright/mpeg2ts/include/mpeg2ts/HlsSampleDecryptor.h b/media/module/mpeg2ts/include/mpeg2ts/HlsSampleDecryptor.h
similarity index 100%
rename from media/libstagefright/mpeg2ts/include/mpeg2ts/HlsSampleDecryptor.h
rename to media/module/mpeg2ts/include/mpeg2ts/HlsSampleDecryptor.h
diff --git a/media/libstagefright/mpeg2ts/include/mpeg2ts/SampleDecryptor.h b/media/module/mpeg2ts/include/mpeg2ts/SampleDecryptor.h
similarity index 100%
rename from media/libstagefright/mpeg2ts/include/mpeg2ts/SampleDecryptor.h
rename to media/module/mpeg2ts/include/mpeg2ts/SampleDecryptor.h
diff --git a/media/libstagefright/mpeg2ts/test/Android.bp b/media/module/mpeg2ts/test/Android.bp
similarity index 100%
rename from media/libstagefright/mpeg2ts/test/Android.bp
rename to media/module/mpeg2ts/test/Android.bp
diff --git a/media/libstagefright/mpeg2ts/test/AndroidTest.xml b/media/module/mpeg2ts/test/AndroidTest.xml
similarity index 100%
rename from media/libstagefright/mpeg2ts/test/AndroidTest.xml
rename to media/module/mpeg2ts/test/AndroidTest.xml
diff --git a/media/libstagefright/mpeg2ts/test/Mpeg2tsUnitTest.cpp b/media/module/mpeg2ts/test/Mpeg2tsUnitTest.cpp
similarity index 100%
rename from media/libstagefright/mpeg2ts/test/Mpeg2tsUnitTest.cpp
rename to media/module/mpeg2ts/test/Mpeg2tsUnitTest.cpp
diff --git a/media/libstagefright/mpeg2ts/test/Mpeg2tsUnitTestEnvironment.h b/media/module/mpeg2ts/test/Mpeg2tsUnitTestEnvironment.h
similarity index 100%
rename from media/libstagefright/mpeg2ts/test/Mpeg2tsUnitTestEnvironment.h
rename to media/module/mpeg2ts/test/Mpeg2tsUnitTestEnvironment.h
diff --git a/media/libstagefright/mpeg2ts/test/README.md b/media/module/mpeg2ts/test/README.md
similarity index 100%
rename from media/libstagefright/mpeg2ts/test/README.md
rename to media/module/mpeg2ts/test/README.md
diff --git a/services/mediatranscoding/.clang-format b/media/module/service.mediatranscoding/.clang-format
similarity index 100%
rename from services/mediatranscoding/.clang-format
rename to media/module/service.mediatranscoding/.clang-format
diff --git a/services/mediatranscoding/Android.bp b/media/module/service.mediatranscoding/Android.bp
similarity index 96%
rename from services/mediatranscoding/Android.bp
rename to media/module/service.mediatranscoding/Android.bp
index fa5eb4e..37f354b 100644
--- a/services/mediatranscoding/Android.bp
+++ b/media/module/service.mediatranscoding/Android.bp
@@ -26,6 +26,10 @@
"SimulatedTranscoder.cpp",
],
+ export_include_dirs: [
+ ".",
+ ],
+
min_sdk_version: "29",
apex_available: [
"com.android.media",
diff --git a/services/mediatranscoding/MODULE_LICENSE_APACHE2 b/media/module/service.mediatranscoding/MODULE_LICENSE_APACHE2
similarity index 100%
rename from services/mediatranscoding/MODULE_LICENSE_APACHE2
rename to media/module/service.mediatranscoding/MODULE_LICENSE_APACHE2
diff --git a/services/mediatranscoding/MediaTranscodingService.cpp b/media/module/service.mediatranscoding/MediaTranscodingService.cpp
similarity index 100%
rename from services/mediatranscoding/MediaTranscodingService.cpp
rename to media/module/service.mediatranscoding/MediaTranscodingService.cpp
diff --git a/services/mediatranscoding/MediaTranscodingService.h b/media/module/service.mediatranscoding/MediaTranscodingService.h
similarity index 100%
rename from services/mediatranscoding/MediaTranscodingService.h
rename to media/module/service.mediatranscoding/MediaTranscodingService.h
diff --git a/services/mediatranscoding/NOTICE b/media/module/service.mediatranscoding/NOTICE
similarity index 100%
rename from services/mediatranscoding/NOTICE
rename to media/module/service.mediatranscoding/NOTICE
diff --git a/services/mediatranscoding/OWNERS b/media/module/service.mediatranscoding/OWNERS
similarity index 100%
rename from services/mediatranscoding/OWNERS
rename to media/module/service.mediatranscoding/OWNERS
diff --git a/services/mediatranscoding/SimulatedTranscoder.cpp b/media/module/service.mediatranscoding/SimulatedTranscoder.cpp
similarity index 100%
rename from services/mediatranscoding/SimulatedTranscoder.cpp
rename to media/module/service.mediatranscoding/SimulatedTranscoder.cpp
diff --git a/services/mediatranscoding/SimulatedTranscoder.h b/media/module/service.mediatranscoding/SimulatedTranscoder.h
similarity index 100%
rename from services/mediatranscoding/SimulatedTranscoder.h
rename to media/module/service.mediatranscoding/SimulatedTranscoder.h
diff --git a/services/mediatranscoding/main_mediatranscodingservice.cpp b/media/module/service.mediatranscoding/main_mediatranscodingservice.cpp
similarity index 100%
rename from services/mediatranscoding/main_mediatranscodingservice.cpp
rename to media/module/service.mediatranscoding/main_mediatranscodingservice.cpp
diff --git a/services/mediatranscoding/tests/Android.bp b/media/module/service.mediatranscoding/tests/Android.bp
similarity index 95%
rename from services/mediatranscoding/tests/Android.bp
rename to media/module/service.mediatranscoding/tests/Android.bp
index ae13656..97fbd4c 100644
--- a/services/mediatranscoding/tests/Android.bp
+++ b/media/module/service.mediatranscoding/tests/Android.bp
@@ -20,10 +20,6 @@
"-Wextra",
],
- include_dirs: [
- "frameworks/av/services/mediatranscoding",
- ],
-
shared_libs: [
"libactivitymanager_aidl",
"libbinder",
diff --git a/services/mediatranscoding/tests/MediaTranscodingServiceTestHelper.h b/media/module/service.mediatranscoding/tests/MediaTranscodingServiceTestHelper.h
similarity index 100%
rename from services/mediatranscoding/tests/MediaTranscodingServiceTestHelper.h
rename to media/module/service.mediatranscoding/tests/MediaTranscodingServiceTestHelper.h
diff --git a/services/mediatranscoding/tests/README.txt b/media/module/service.mediatranscoding/tests/README.txt
similarity index 100%
rename from services/mediatranscoding/tests/README.txt
rename to media/module/service.mediatranscoding/tests/README.txt
diff --git a/services/mediatranscoding/tests/TranscodingUidPolicyTestApp/Android.bp b/media/module/service.mediatranscoding/tests/TranscodingUidPolicyTestApp/Android.bp
similarity index 100%
rename from services/mediatranscoding/tests/TranscodingUidPolicyTestApp/Android.bp
rename to media/module/service.mediatranscoding/tests/TranscodingUidPolicyTestApp/Android.bp
diff --git a/services/mediatranscoding/tests/TranscodingUidPolicyTestApp/TestAppA.xml b/media/module/service.mediatranscoding/tests/TranscodingUidPolicyTestApp/TestAppA.xml
similarity index 100%
rename from services/mediatranscoding/tests/TranscodingUidPolicyTestApp/TestAppA.xml
rename to media/module/service.mediatranscoding/tests/TranscodingUidPolicyTestApp/TestAppA.xml
diff --git a/services/mediatranscoding/tests/TranscodingUidPolicyTestApp/TestAppB.xml b/media/module/service.mediatranscoding/tests/TranscodingUidPolicyTestApp/TestAppB.xml
similarity index 100%
rename from services/mediatranscoding/tests/TranscodingUidPolicyTestApp/TestAppB.xml
rename to media/module/service.mediatranscoding/tests/TranscodingUidPolicyTestApp/TestAppB.xml
diff --git a/services/mediatranscoding/tests/TranscodingUidPolicyTestApp/TestAppC.xml b/media/module/service.mediatranscoding/tests/TranscodingUidPolicyTestApp/TestAppC.xml
similarity index 100%
rename from services/mediatranscoding/tests/TranscodingUidPolicyTestApp/TestAppC.xml
rename to media/module/service.mediatranscoding/tests/TranscodingUidPolicyTestApp/TestAppC.xml
diff --git a/services/mediatranscoding/tests/TranscodingUidPolicyTestApp/src/com/android/tests/transcoding/MainActivity.java b/media/module/service.mediatranscoding/tests/TranscodingUidPolicyTestApp/src/com/android/tests/transcoding/MainActivity.java
similarity index 100%
rename from services/mediatranscoding/tests/TranscodingUidPolicyTestApp/src/com/android/tests/transcoding/MainActivity.java
rename to media/module/service.mediatranscoding/tests/TranscodingUidPolicyTestApp/src/com/android/tests/transcoding/MainActivity.java
diff --git a/services/mediatranscoding/tests/TranscodingUidPolicyTestApp/src/com/android/tests/transcoding/ResourcePolicyTestActivity.java b/media/module/service.mediatranscoding/tests/TranscodingUidPolicyTestApp/src/com/android/tests/transcoding/ResourcePolicyTestActivity.java
similarity index 100%
rename from services/mediatranscoding/tests/TranscodingUidPolicyTestApp/src/com/android/tests/transcoding/ResourcePolicyTestActivity.java
rename to media/module/service.mediatranscoding/tests/TranscodingUidPolicyTestApp/src/com/android/tests/transcoding/ResourcePolicyTestActivity.java
diff --git a/services/mediatranscoding/tests/build_and_run_all_unit_tests.sh b/media/module/service.mediatranscoding/tests/build_and_run_all_unit_tests.sh
similarity index 100%
rename from services/mediatranscoding/tests/build_and_run_all_unit_tests.sh
rename to media/module/service.mediatranscoding/tests/build_and_run_all_unit_tests.sh
diff --git a/services/mediatranscoding/tests/mediatranscodingservice_real_tests.cpp b/media/module/service.mediatranscoding/tests/mediatranscodingservice_real_tests.cpp
similarity index 100%
rename from services/mediatranscoding/tests/mediatranscodingservice_real_tests.cpp
rename to media/module/service.mediatranscoding/tests/mediatranscodingservice_real_tests.cpp
diff --git a/services/mediatranscoding/tests/mediatranscodingservice_resource_tests.cpp b/media/module/service.mediatranscoding/tests/mediatranscodingservice_resource_tests.cpp
similarity index 100%
rename from services/mediatranscoding/tests/mediatranscodingservice_resource_tests.cpp
rename to media/module/service.mediatranscoding/tests/mediatranscodingservice_resource_tests.cpp
diff --git a/services/mediatranscoding/tests/mediatranscodingservice_simulated_tests.cpp b/media/module/service.mediatranscoding/tests/mediatranscodingservice_simulated_tests.cpp
similarity index 100%
rename from services/mediatranscoding/tests/mediatranscodingservice_simulated_tests.cpp
rename to media/module/service.mediatranscoding/tests/mediatranscodingservice_simulated_tests.cpp
diff --git a/media/mtp/Android.bp b/media/mtp/Android.bp
index 97e2a22..719d05a 100644
--- a/media/mtp/Android.bp
+++ b/media/mtp/Android.bp
@@ -31,8 +31,8 @@
],
}
-cc_library_shared {
- name: "libmtp",
+cc_defaults {
+ name: "libmtp_defaults",
srcs: [
"MtpDataPacket.cpp",
"MtpDebug.cpp",
@@ -71,3 +71,14 @@
],
header_libs: ["libcutils_headers"],
}
+
+cc_library_shared {
+ name: "libmtp",
+ defaults: ["libmtp_defaults"],
+}
+
+cc_library_shared {
+ name: "libmtp_fuzz",
+ defaults: ["libmtp_defaults"],
+ cflags: ["-DMTP_FUZZER"],
+}
diff --git a/media/mtp/MtpDescriptors.h b/media/mtp/MtpDescriptors.h
index d600a24..9b98a71 100644
--- a/media/mtp/MtpDescriptors.h
+++ b/media/mtp/MtpDescriptors.h
@@ -23,6 +23,17 @@
namespace android {
+#ifdef MTP_FUZZER
+constexpr char FFS_MTP_EP0[] = "/data/local/tmp/usb-ffs/mtp/ep0";
+constexpr char FFS_MTP_EP_IN[] = "/data/local/tmp/usb-ffs/mtp/ep1";
+constexpr char FFS_MTP_EP_OUT[] = "/data/local/tmp/usb-ffs/mtp/ep2";
+constexpr char FFS_MTP_EP_INTR[] = "/data/local/tmp/usb-ffs/mtp/ep3";
+
+constexpr char FFS_PTP_EP0[] = "/data/local/tmp/usb-ffs/ptp/ep0";
+constexpr char FFS_PTP_EP_IN[] = "/data/local/tmp/usb-ffs/ptp/ep1";
+constexpr char FFS_PTP_EP_OUT[] = "/data/local/tmp/usb-ffs/ptp/ep2";
+constexpr char FFS_PTP_EP_INTR[] = "/data/local/tmp/usb-ffs/ptp/ep3";
+#else
constexpr char FFS_MTP_EP0[] = "/dev/usb-ffs/mtp/ep0";
constexpr char FFS_MTP_EP_IN[] = "/dev/usb-ffs/mtp/ep1";
constexpr char FFS_MTP_EP_OUT[] = "/dev/usb-ffs/mtp/ep2";
@@ -32,6 +43,7 @@
constexpr char FFS_PTP_EP_IN[] = "/dev/usb-ffs/ptp/ep1";
constexpr char FFS_PTP_EP_OUT[] = "/dev/usb-ffs/ptp/ep2";
constexpr char FFS_PTP_EP_INTR[] = "/dev/usb-ffs/ptp/ep3";
+#endif
constexpr int MAX_PACKET_SIZE_FS = 64;
constexpr int MAX_PACKET_SIZE_HS = 512;
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index 6fcf119..d917772 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -985,7 +985,7 @@
int type = storage->getType();
if (type == MTP_STORAGE_REMOVABLE_RAM) {
- std::string str = android::base::Trim((const char*)name);
+ std::string str = android::base::Trim(name);
name.set(str.c_str());
}
ALOGV("name: %s format: 0x%04X (%s)\n", (const char*)name, format,
diff --git a/media/mtp/MtpStringBuffer.h b/media/mtp/MtpStringBuffer.h
index 4cec58a..30d1bc1 100644
--- a/media/mtp/MtpStringBuffer.h
+++ b/media/mtp/MtpStringBuffer.h
@@ -20,6 +20,7 @@
#include <log/log.h>
#include <stdint.h>
#include <string>
+#include <string_view>
// Max Character number of a MTP String
#define MTP_STRING_MAX_CHARACTER_NUMBER 255
@@ -55,6 +56,7 @@
inline int size() const { return mString.length(); }
inline operator const char*() const { return mString.c_str(); }
+ operator std::string_view() const { return mString; }
};
inline void MtpStringBuffer::append(const char* other) {
diff --git a/media/mtp/tests/MtpFuzzer/Android.bp b/media/mtp/tests/MtpFuzzer/Android.bp
index 5365f4b..9e41680 100644
--- a/media/mtp/tests/MtpFuzzer/Android.bp
+++ b/media/mtp/tests/MtpFuzzer/Android.bp
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
package {
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
@@ -6,29 +22,20 @@
// SPDX-license-identifier-Apache-2.0
default_applicable_licenses: ["frameworks_av_media_mtp_license"],
}
-
-cc_fuzz {
- name: "mtp_fuzzer",
- srcs: [
- "mtp_fuzzer.cpp",
- "MtpMockDatabase.cpp",
- ],
+cc_defaults {
+ name: "mtp_fuzzer_defaults",
shared_libs: [
- "libmtp",
- "libbase",
- "liblog",
- "libutils",
+ "libbase",
+ "liblog",
+ "libutils",
],
+ static_libs: ["libc++fs",],
cflags: [
"-Wall",
"-Wextra",
"-Werror",
- "-DMTP_DEVICE",
"-Wno-unused-parameter",
],
- dictionary: "mtp_fuzzer.dict",
- corpus: ["corpus/*"],
-
fuzz_config: {
cc: ["jameswei@google.com"],
@@ -38,3 +45,107 @@
],
},
}
+cc_fuzz {
+ name: "mtp_fuzzer",
+ srcs: [
+ "mtp_fuzzer.cpp",
+ "MtpMockDatabase.cpp",
+ ],
+ cflags: ["-DMTP_DEVICE",],
+ shared_libs: ["libmtp",],
+ defaults: ["mtp_fuzzer_defaults"],
+ dictionary: "mtp_fuzzer.dict",
+ corpus: ["corpus/*"],
+}
+
+cc_defaults {
+ name: "mtp_property_fuzzer_defaults",
+ srcs: ["mtp_property_fuzzer.cpp"],
+ shared_libs: [
+ "libmtp",
+ "libasyncio",
+ "libusbhost",
+ ],
+ defaults: ["mtp_fuzzer_defaults"],
+}
+
+cc_fuzz {
+ name: "mtp_device_property_fuzzer",
+ defaults: ["mtp_property_fuzzer_defaults"],
+ cflags: [
+ "-DMTP_DEVICE",
+ ],
+}
+
+cc_fuzz {
+ name: "mtp_host_property_fuzzer",
+ defaults: ["mtp_property_fuzzer_defaults"],
+ cflags: [
+ "-DMTP_HOST",
+ ],
+}
+
+cc_fuzz {
+ name: "mtp_handle_fuzzer",
+ srcs: ["mtp_handle_fuzzer.cpp"],
+ shared_libs: ["libmtp_fuzz"],
+ defaults: ["mtp_fuzzer_defaults"],
+ cflags: ["-DMTP_FUZZER"],
+}
+
+cc_defaults {
+ name: "mtp_packet_defaults",
+ shared_libs: [
+ "libmtp",
+ "libasyncio",
+ "libusbhost",
+ ],
+ defaults: ["mtp_fuzzer_defaults"],
+ cflags: [
+ "-DMTP_HOST",
+ "-DMTP_DEVICE",
+ ],
+}
+
+cc_fuzz {
+ name: "mtp_packet_fuzzer",
+ srcs: ["mtp_packet_fuzzer.cpp"],
+ defaults: ["mtp_packet_defaults"],
+}
+
+cc_fuzz {
+ name: "mtp_device_fuzzer",
+ srcs: ["mtp_device_fuzzer.cpp"],
+ shared_libs: [
+ "libmtp",
+ "libusbhost",
+ ],
+ defaults: ["mtp_fuzzer_defaults"],
+ cflags: [
+ "-DMTP_DEVICE",
+ ],
+}
+
+cc_fuzz {
+ name: "mtp_request_packet_fuzzer",
+ srcs: ["mtp_request_packet_fuzzer.cpp"],
+ defaults: ["mtp_packet_defaults"],
+}
+
+cc_fuzz {
+ name: "mtp_event_packet_fuzzer",
+ srcs: ["mtp_event_packet_fuzzer.cpp"],
+ defaults: ["mtp_packet_defaults"],
+}
+
+cc_fuzz {
+ name: "mtp_response_packet_fuzzer",
+ srcs: ["mtp_response_packet_fuzzer.cpp"],
+ defaults: ["mtp_packet_defaults"],
+}
+
+cc_fuzz {
+ name: "mtp_data_packet_fuzzer",
+ srcs: ["mtp_data_packet_fuzzer.cpp"],
+ defaults: ["mtp_packet_defaults"],
+}
diff --git a/media/mtp/tests/MtpFuzzer/MtpPacketFuzzerUtils.h b/media/mtp/tests/MtpFuzzer/MtpPacketFuzzerUtils.h
new file mode 100644
index 0000000..87fea9f
--- /dev/null
+++ b/media/mtp/tests/MtpFuzzer/MtpPacketFuzzerUtils.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <MtpStringBuffer.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <linux/usbdevice_fs.h>
+#include <sys/mman.h>
+#include <usbhost/usbhost.h>
+#include <MtpTypes.h>
+
+using namespace android;
+constexpr UrbPacketDivisionMode kUrbPacketDivisionModes[] = {FIRST_PACKET_ONLY_HEADER,
+ FIRST_PACKET_HAS_PAYLOAD};
+
+constexpr size_t kMinSize = 0;
+constexpr size_t kMaxSize = 1000;
+constexpr size_t kMaxLength = 1000;
+
+class MtpPacketFuzzerUtils {
+ protected:
+ struct usb_request mUsbRequest;
+ struct usbdevfs_urb* mUsbDevFsUrb;
+ std::string mPath;
+
+ void fillFd(int32_t& fd, FuzzedDataProvider* fdp) {
+ if (fdp->ConsumeBool()) {
+ std::string text = fdp->ConsumeRandomLengthString(kMaxLength);
+ write(fd, text.c_str(), text.length());
+ }
+ };
+
+ void fillFilePath(FuzzedDataProvider* fdp) {
+ mPath= fdp->ConsumeRandomLengthString(kMaxLength);
+ };
+
+ void fillUsbDevFsUrb(FuzzedDataProvider* fdp) {
+ mUsbDevFsUrb->type = fdp->ConsumeIntegral<unsigned char>();
+ mUsbDevFsUrb->endpoint = fdp->ConsumeIntegral<unsigned char>();
+ mUsbDevFsUrb->flags = fdp->ConsumeIntegral<uint32_t>();
+ std::vector<uint8_t> buffer =
+ fdp->ConsumeBytes<uint8_t>(fdp->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize));
+ mUsbDevFsUrb->buffer = static_cast<void*>(buffer.data());
+ mUsbDevFsUrb->buffer_length = buffer.size();
+ mUsbDevFsUrb->actual_length = fdp->ConsumeIntegral<uint32_t>();
+ mUsbDevFsUrb->start_frame = fdp->ConsumeIntegral<uint32_t>();
+ mUsbDevFsUrb->number_of_packets = fdp->ConsumeIntegral<uint32_t>();
+ mUsbDevFsUrb->stream_id = fdp->ConsumeIntegral<uint32_t>();
+ mUsbDevFsUrb->error_count = fdp->ConsumeIntegral<size_t>();
+ mUsbDevFsUrb->signr = fdp->ConsumeIntegral<uint32_t>();
+ std::vector<uint8_t> userBuffer = (fdp->ConsumeBytes<uint8_t>(
+ fdp->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize)));
+ mUsbDevFsUrb->usercontext = static_cast<void*>(userBuffer.data());
+ mUsbDevFsUrb->iso_frame_desc[0].length = fdp->ConsumeIntegral<uint32_t>();
+ mUsbDevFsUrb->iso_frame_desc[0].actual_length = fdp->ConsumeIntegral<uint32_t>();
+ };
+
+ void fillUsbRequest(int32_t& fd, FuzzedDataProvider* fdp) {
+ fillUsbDevFsUrb(fdp);
+ fillFd(fd, fdp);
+ std::vector<uint8_t> buffer =
+ fdp->ConsumeBytes<uint8_t>(fdp->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize));
+ mUsbRequest.buffer = static_cast<void*>(buffer.data());
+ mUsbRequest.buffer_length = buffer.size();
+ mUsbRequest.actual_length = fdp->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
+ mUsbRequest.max_packet_size = fdp->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
+ mUsbRequest.private_data = static_cast<void*>(mUsbDevFsUrb);
+ mUsbRequest.endpoint = fdp->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
+ std::vector<uint8_t> clientBuffer = (fdp->ConsumeBytes<uint8_t>(
+ fdp->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize)));
+ mUsbRequest.client_data = static_cast<void*>(clientBuffer.data());
+ };
+
+ template <typename Object>
+ void writeHandle(Object obj, FuzzedDataProvider* fdp) {
+ MtpDevHandle handle;
+ std::vector<uint8_t> initData =
+ fdp->ConsumeBytes<uint8_t>(fdp->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize));
+ handle.write(initData.data(), initData.size());
+ obj->write(&handle);
+ };
+};
diff --git a/media/mtp/tests/MtpFuzzer/README.md b/media/mtp/tests/MtpFuzzer/README.md
new file mode 100644
index 0000000..7efaf67
--- /dev/null
+++ b/media/mtp/tests/MtpFuzzer/README.md
@@ -0,0 +1,210 @@
+# Fuzzers for libmtp
+
+## Table of contents
++ [mtp_fuzzer](#MtpServer)
++ [mtp_host_property_fuzzer](#MtpHostProperty)
++ [mtp_device_property_fuzzer](#MtpDeviceProperty)
++ [mtp_handle_fuzzer](#MtpHandle)
++ [mtp_packet_fuzzer](#MtpPacket)
+ + [mtp_device_fuzzer](#MtpDevice)
++ [mtp_request_packet_fuzzer](#MtpRequestPacket)
++ [mtp_event_packet_fuzzer](#MtpEventPacket)
++ [mtp_response_packet_fuzzer](#MtpResponsePacket)
++ [mtp_data_packet_fuzzer](#MtpDataPacket)
+
+# <a name="MtpServer"></a> Fuzzer for MtpServer
+
+MtpServer supports the following parameters:
+1. PacketData (parameter name: "packetData")
+
+| Parameter| Valid Values |Configured Value|
+|-------------|----------|----- |
+|`packetData`| `String` |Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+ $ mm -j$(nproc) mtp_fuzzer
+```
+2. Run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/mtp_fuzzer/mtp_fuzzer corpus/ -dict=mtp_fuzzer.dict
+```
+
+# <a name="MtpHostProperty"></a> Fuzzer for MtpHostProperty
+
+MtpHostProperty supports the following parameters:
+1. Feasible Type (parameter name: "kFeasibleTypes")
+2. UrbPacket Division Mode (parameter name: "kUrbPacketDivisionModes")
+
+| Parameter| Valid Values |Configured Value|
+|-------------|----------|----- |
+| `kFeasibleType`| 1. `MTP_TYPE_UNDEFINED`, 2. `MTP_TYPE_INT8`, 3.`MTP_TYPE_UINT8`, 4.`MTP_TYPE_INT16`, 5.`MTP_TYPE_UINT16`, 6.`MTP_TYPE_INT32`, 7.`MTP_TYPE_UINT32`, 8.`MTP_TYPE_INT64`, 9.`MTP_TYPE_UINT64`, 10.`MTP_TYPE_INT128`, 11.`MTP_TYPE_UINT128`, 12.`MTP_TYPE_AINT8`, 13.`MTP_TYPE_AUINT8`, 14.`MTP_TYPE_AINT16`, 15.`MTP_TYPE_AUINT16`, 16.`MTP_TYPE_AINT32`, 17.`MTP_TYPE_AUINT32`, 18.`MTP_TYPE_AINT64`, 19.`MTP_TYPE_AUINT64`, 20.`MTP_TYPE_AINT128`, 21.`MTP_TYPE_AUINT128`, 22.`MTP_TYPE_STR`,| Value obtained from FuzzedDataProvider|
+|`kUrbPacketDivisionMode`| 1. `FIRST_PACKET_ONLY_HEADER`, 2. `FIRST_PACKET_HAS_PAYLOAD`, |Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+ $ mm -j$(nproc) mtp_host_property_fuzzer
+```
+2. Run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/mtp_host_property_fuzzer/mtp_host_property_fuzzer
+```
+
+# <a name="MtpDeviceProperty"></a> Fuzzer for MtpDeviceProperty
+
+MtpDeviceProperty supports the following parameters:
+1. Feasible Type (parameter name: "kFeasibleType")
+
+| Parameter| Valid Values |Configured Value|
+|-------------|----------|----- |
+| `kFeasibleType`| 1. `MTP_TYPE_UNDEFINED`, 2. `MTP_TYPE_INT8`, 3.`MTP_TYPE_UINT8`, 4.`MTP_TYPE_INT16`, 5.`MTP_TYPE_UINT16`, 6.`MTP_TYPE_INT32`, 7.`MTP_TYPE_UINT32`, 8.`MTP_TYPE_INT64`, 9.`MTP_TYPE_UINT64`, 10.`MTP_TYPE_INT128`, 11.`MTP_TYPE_UINT128`, 12.`MTP_TYPE_AINT8`, 13.`MTP_TYPE_AUINT8`, 14.`MTP_TYPE_AINT16`, 15.`MTP_TYPE_AUINT16`, 16.`MTP_TYPE_AINT32`, 17.`MTP_TYPE_AUINT32`, 18.`MTP_TYPE_AINT64`, 19.`MTP_TYPE_AUINT64`, 20.`MTP_TYPE_AINT128`, 21.`MTP_TYPE_AUINT128`, 22.`MTP_TYPE_STR`,| Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+ $ mm -j$(nproc) mtp_device_property_fuzzer
+```
+2. Run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/mtp_device_property_fuzzer/mtp_device_property_fuzzer
+```
+
+# <a name="MtpHandle"></a>Fuzzer for MtpHandle
+
+#### Steps to run
+1. Build the fuzzer
+```
+ $ mm -j$(nproc) mtp_handle_fuzzer
+```
+2. Run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/mtp_handle_fuzzer/mtp_handle_fuzzer
+```
+
+# <a name="MtpPacket"></a> Fuzzer for MtpPacket
+
+MtpPacket supports the following parameters:
+1. bufferSize (parameter name: "size")
+
+| Parameter| Valid Values |Configured Value|
+|-------------|----------|----- |
+|`bufferSize`| Integer `1` to `1000`, |Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+ $ mm -j$(nproc) mtp_packet_fuzzer
+```
+2. Run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/mtp_packet_fuzzer/mtp_packet_fuzzer
+```
+
+# <a name="MtpDevice"></a> Fuzzer for MtpDevice
+
+MtpDevice supports the following parameters:
+1. Device Name (parameter name: "deviceName")
+
+| Parameter| Valid Values |Configured Value|
+|-------------|----------|----- |
+|`deviceName`| `String` |Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+ $ mm -j$(nproc) mtp_device_fuzzer
+```
+2. Run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/mtp_device_fuzzer/mtp_device_fuzzer
+```
+
+# <a name="MtpRequestPacket"></a> Fuzzer for MtpRequestPacket
+
+MtpRequestPacket supports the following parameters:
+1. Data (parameter name: "data")
+
+| Parameter| Valid Values |Configured Value|
+|-------------|----------|----- |
+|`data`| Vector of positive Integer |Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+ $ mm -j$(nproc) mtp_request_packet_fuzzer
+```
+2. Run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/mtp_request_packet_fuzzer/mtp_request_packet_fuzzer
+```
+
+# <a name="MtpEventPacket"></a> Fuzzer for MtpEventPacket
+
+MtpEventPacket supports the following parameters:
+1. Size (parameter name: "size")
+
+| Parameter| Valid Values |Configured Value|
+|-------------|----------|----- |
+|`size`| Integer `1` to `1000`, |Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+ $ mm -j$(nproc) mtp_event_packet_fuzzer
+```
+2. Run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/mtp_event_packet_fuzzer/mtp_event_packet_fuzzer
+```
+
+# <a name="MtpResponsePacket"></a> Fuzzer for MtpResponsePacket
+
+MtpResponsePacket supports the following parameters:
+1. Size (parameter name: "size")
+
+| Parameter| Valid Values |Configured Value|
+|-------------|----------|----- |
+|`size`| Integer `1` to `1000`, |Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+ $ mm -j$(nproc) mtp_response_packet_fuzzer
+```
+2. Run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/mtp_response_packet_fuzzer/mtp_response_packet_fuzzer
+```
+
+# <a name="MtpDataPacket"></a> Fuzzer for MtpDataPacket
+
+MtpDataPacket supports the following parameters:
+1. UrbPacket Division Mode (parameter name: "kUrbPacketDivisionModes")
+2. Size (parameter name: "size")
+
+| Parameter| Valid Values |Configured Value|
+|-------------|----------|----- |
+|`kUrbPacketDivisionMode`| 1. `FIRST_PACKET_ONLY_HEADER`, 2. `FIRST_PACKET_HAS_PAYLOAD`, |Value obtained from FuzzedDataProvider|
+|`size`| Integer `1` to `1000`, |Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+ $ mm -j$(nproc) mtp_data_packet_fuzzer
+```
+2. Run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/mtp_data_packet_fuzzer/mtp_data_packet_fuzzer
+```
diff --git a/media/mtp/tests/MtpFuzzer/corpus/6-mtp-open_session_send_object_info.pkt b/media/mtp/tests/MtpFuzzer/corpus/6-mtp-open_session_send_object_info.pkt
new file mode 100644
index 0000000..71f2836
--- /dev/null
+++ b/media/mtp/tests/MtpFuzzer/corpus/6-mtp-open_session_send_object_info.pkt
Binary files differ
diff --git a/media/mtp/tests/MtpFuzzer/mtp_data_packet_fuzzer.cpp b/media/mtp/tests/MtpFuzzer/mtp_data_packet_fuzzer.cpp
new file mode 100644
index 0000000..f5faf77
--- /dev/null
+++ b/media/mtp/tests/MtpFuzzer/mtp_data_packet_fuzzer.cpp
@@ -0,0 +1,365 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <MtpDataPacket.h>
+#include <MtpDevHandle.h>
+#include <MtpPacketFuzzerUtils.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <utils/String16.h>
+
+using namespace android;
+
+class MtpDataPacketFuzzer : MtpPacketFuzzerUtils {
+ public:
+ MtpDataPacketFuzzer(const uint8_t* data, size_t size) : mFdp(data, size) {
+ mUsbDevFsUrb = (struct usbdevfs_urb*)malloc(sizeof(struct usbdevfs_urb) +
+ sizeof(struct usbdevfs_iso_packet_desc));
+ };
+ ~MtpDataPacketFuzzer() { free(mUsbDevFsUrb); };
+ void process();
+
+ private:
+ FuzzedDataProvider mFdp;
+};
+
+void MtpDataPacketFuzzer::process() {
+ MtpDataPacket mtpDataPacket;
+ while (mFdp.remaining_bytes() > 0) {
+ auto mtpDataAPI = mFdp.PickValueInArray<const std::function<void()>>({
+ [&]() { mtpDataPacket.allocate(mFdp.ConsumeIntegralInRange(kMinSize, kMaxSize)); },
+ [&]() { mtpDataPacket.reset(); },
+ [&]() {
+ mtpDataPacket.setOperationCode(mFdp.ConsumeIntegralInRange(kMinSize, kMaxSize));
+ },
+ [&]() {
+ mtpDataPacket.setTransactionID(mFdp.ConsumeIntegralInRange(kMinSize, kMaxSize));
+ },
+ [&]() {
+ Int8List* result = mtpDataPacket.getAInt8();
+ delete result;
+ },
+ [&]() {
+ Int16List* result = mtpDataPacket.getAInt16();
+ delete result;
+ },
+ [&]() {
+ Int32List* result = mtpDataPacket.getAInt32();
+ delete result;
+ },
+ [&]() {
+ Int64List* result = mtpDataPacket.getAInt64();
+ delete result;
+ },
+ [&]() {
+ UInt8List* result = mtpDataPacket.getAUInt8();
+ delete result;
+ },
+ [&]() {
+ UInt16List* result = mtpDataPacket.getAUInt16();
+ delete result;
+ },
+ [&]() {
+ UInt32List* result = mtpDataPacket.getAUInt32();
+ delete result;
+ },
+ [&]() {
+ UInt64List* result = mtpDataPacket.getAUInt64();
+ delete result;
+ },
+ [&]() {
+ if (mFdp.ConsumeBool()) {
+ std::vector<uint8_t> initData =
+ mFdp.ConsumeBytes<uint8_t>(mFdp.ConsumeIntegral<uint8_t>());
+ mtpDataPacket.putAUInt8(initData.data(), initData.size());
+ } else {
+ mtpDataPacket.putAUInt8(nullptr, 0);
+ }
+ },
+ [&]() {
+ if (mFdp.ConsumeBool()) {
+ size_t size = mFdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
+ uint16_t arr[size];
+ for (size_t idx = 0; idx < size; ++idx) {
+ arr[idx] = mFdp.ConsumeIntegral<uint16_t>();
+ }
+ mtpDataPacket.putAUInt16(arr, size);
+ } else {
+ mtpDataPacket.putAUInt16(nullptr, 0);
+ }
+ },
+ [&]() {
+ if (mFdp.ConsumeBool()) {
+ size_t size = mFdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
+ uint32_t arr[size];
+ for (size_t idx = 0; idx < size; ++idx) {
+ arr[idx] = mFdp.ConsumeIntegral<uint32_t>();
+ }
+ mtpDataPacket.putAUInt32(arr, size);
+ } else {
+ mtpDataPacket.putAUInt32(nullptr, 0);
+ }
+ },
+ [&]() {
+ if (mFdp.ConsumeBool()) {
+ size_t size = mFdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
+ uint64_t arr[size];
+ for (size_t idx = 0; idx < size; ++idx) {
+ arr[idx] = mFdp.ConsumeIntegral<uint64_t>();
+ }
+ mtpDataPacket.putAUInt64(arr, size);
+ } else {
+ mtpDataPacket.putAUInt64(nullptr, 0);
+ }
+ },
+ [&]() {
+ if (mFdp.ConsumeBool()) {
+ size_t size = mFdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
+ int64_t arr[size];
+ for (size_t idx = 0; idx < size; ++idx) {
+ arr[idx] = mFdp.ConsumeIntegral<int64_t>();
+ }
+ mtpDataPacket.putAInt64(arr, size);
+ } else {
+ mtpDataPacket.putAInt64(nullptr, 0);
+ }
+ },
+ [&]() {
+ if (mFdp.ConsumeBool()) {
+ std::vector<uint16_t> arr;
+ size_t size = mFdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
+ for (size_t idx = 0; idx < size; ++idx) {
+ arr.push_back(mFdp.ConsumeIntegral<uint16_t>());
+ }
+ mtpDataPacket.putAUInt16(&arr);
+ } else {
+ mtpDataPacket.putAUInt16(nullptr);
+ }
+ },
+ [&]() {
+ if (mFdp.ConsumeBool()) {
+ std::vector<uint32_t> arr;
+ size_t size = mFdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
+ for (size_t idx = 0; idx < size; ++idx) {
+ arr.push_back(mFdp.ConsumeIntegral<uint32_t>());
+ }
+ mtpDataPacket.putAUInt32(&arr);
+ } else {
+ mtpDataPacket.putAUInt32(nullptr);
+ }
+ },
+
+ [&]() {
+ if (mFdp.ConsumeBool()) {
+ size_t size = mFdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
+ int32_t arr[size];
+ for (size_t idx = 0; idx < size; ++idx) {
+ arr[idx] = mFdp.ConsumeIntegral<int32_t>();
+ }
+ mtpDataPacket.putAInt32(arr, size);
+ } else {
+ mtpDataPacket.putAInt32(nullptr, 0);
+ }
+ },
+ [&]() {
+ if (mFdp.ConsumeBool()) {
+ mtpDataPacket.putString(
+ (mFdp.ConsumeRandomLengthString(kMaxLength)).c_str());
+ } else {
+ mtpDataPacket.putString(static_cast<char*>(nullptr));
+ }
+ },
+ [&]() {
+ android::MtpStringBuffer sBuffer(
+ (mFdp.ConsumeRandomLengthString(kMaxLength)).c_str());
+ if (mFdp.ConsumeBool()) {
+ mtpDataPacket.getString(sBuffer);
+ } else {
+ mtpDataPacket.putString(sBuffer);
+ }
+ },
+ [&]() {
+ MtpDevHandle handle;
+ handle.start(mFdp.ConsumeBool());
+ std::string text = mFdp.ConsumeRandomLengthString(kMaxLength);
+ char* data = const_cast<char*>(text.c_str());
+ handle.read(static_cast<void*>(data), text.length());
+ if (mFdp.ConsumeBool()) {
+ mtpDataPacket.read(&handle);
+ } else if (mFdp.ConsumeBool()) {
+ mtpDataPacket.write(&handle);
+ } else {
+ std::string textData = mFdp.ConsumeRandomLengthString(kMaxLength);
+ char* Data = const_cast<char*>(textData.c_str());
+ mtpDataPacket.writeData(&handle, static_cast<void*>(Data),
+ textData.length());
+ }
+ handle.close();
+ },
+ [&]() {
+ if (mFdp.ConsumeBool()) {
+ std::string str = mFdp.ConsumeRandomLengthString(kMaxLength);
+ android::String16 s(str.c_str());
+ char16_t* data = const_cast<char16_t*>(s.string());
+ mtpDataPacket.putString(reinterpret_cast<uint16_t*>(data));
+ } else {
+ mtpDataPacket.putString(static_cast<uint16_t*>(nullptr));
+ }
+ },
+ [&]() {
+ if (mFdp.ConsumeBool()) {
+ std::vector<int8_t> data = mFdp.ConsumeBytes<int8_t>(
+ mFdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize));
+ mtpDataPacket.putAInt8(data.data(), data.size());
+ } else {
+ mtpDataPacket.putAInt8(nullptr, 0);
+ }
+ },
+ [&]() {
+ if (mFdp.ConsumeBool()) {
+ std::vector<uint8_t> data = mFdp.ConsumeBytes<uint8_t>(
+ mFdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize));
+ mtpDataPacket.putAUInt8(data.data(), data.size());
+ } else {
+ mtpDataPacket.putAUInt8(nullptr, 0);
+ }
+ },
+ [&]() {
+ fillFilePath(&mFdp);
+ int32_t fd = memfd_create(mPath.c_str(), MFD_ALLOW_SEALING);
+ fillUsbRequest(fd, &mFdp);
+ mUsbRequest.dev = usb_device_new(mPath.c_str(), fd);
+ std::vector<int8_t> data = mFdp.ConsumeBytes<int8_t>(
+ mFdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize));
+ mtpDataPacket.readData(&mUsbRequest, data.data(), data.size());
+ usb_device_close(mUsbRequest.dev);
+ },
+ [&]() {
+ fillFilePath(&mFdp);
+ int32_t fd = memfd_create(mPath.c_str(), MFD_ALLOW_SEALING);
+ fillUsbRequest(fd, &mFdp);
+ mUsbRequest.dev = usb_device_new(mPath.c_str(), fd);
+ mtpDataPacket.write(
+ &mUsbRequest,
+ mFdp.PickValueInArray<UrbPacketDivisionMode>(kUrbPacketDivisionModes),
+ fd, mFdp.ConsumeIntegralInRange(kMinSize, kMaxSize));
+ usb_device_close(mUsbRequest.dev);
+ },
+ [&]() {
+ fillFilePath(&mFdp);
+ int32_t fd = memfd_create(mPath.c_str(), MFD_ALLOW_SEALING);
+ fillUsbRequest(fd, &mFdp);
+ mUsbRequest.dev = usb_device_new(mPath.c_str(), fd);
+ mtpDataPacket.read(&mUsbRequest);
+ usb_device_close(mUsbRequest.dev);
+ },
+ [&]() {
+ fillFilePath(&mFdp);
+ int32_t fd = memfd_create(mPath.c_str(), MFD_ALLOW_SEALING);
+ fillUsbRequest(fd, &mFdp);
+ mUsbRequest.dev = usb_device_new(mPath.c_str(), fd);
+ mtpDataPacket.write(&mUsbRequest, mFdp.PickValueInArray<UrbPacketDivisionMode>(
+ kUrbPacketDivisionModes));
+ usb_device_close(mUsbRequest.dev);
+ },
+ [&]() {
+ fillFilePath(&mFdp);
+ int32_t fd = memfd_create(mPath.c_str(), MFD_ALLOW_SEALING);
+ fillUsbRequest(fd, &mFdp);
+ mUsbRequest.dev = usb_device_new(mPath.c_str(), fd);
+ mtpDataPacket.readDataHeader(&mUsbRequest);
+ usb_device_close(mUsbRequest.dev);
+ },
+ [&]() {
+ fillFilePath(&mFdp);
+ int32_t fd = memfd_create(mPath.c_str(), MFD_ALLOW_SEALING);
+ fillUsbRequest(fd, &mFdp);
+ mUsbRequest.dev = usb_device_new(mPath.c_str(), fd);
+ mtpDataPacket.readDataAsync(&mUsbRequest);
+ usb_device_close(mUsbRequest.dev);
+ },
+ [&]() {
+ fillFilePath(&mFdp);
+ int32_t fd = memfd_create(mPath.c_str(), MFD_ALLOW_SEALING);
+ fillUsbRequest(fd, &mFdp);
+ mUsbRequest.dev = usb_device_new(mPath.c_str(), fd);
+ mtpDataPacket.readDataWait(mUsbRequest.dev);
+ usb_device_close(mUsbRequest.dev);
+ },
+ [&]() {
+ if (mFdp.ConsumeBool()) {
+ std::vector<int16_t> data;
+ for (size_t idx = 0;
+ idx < mFdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize); ++idx) {
+ data.push_back(mFdp.ConsumeIntegral<int16_t>());
+ }
+ mtpDataPacket.putAInt16(data.data(), data.size());
+ } else {
+ mtpDataPacket.putAInt16(nullptr, 0);
+ }
+ },
+ [&]() {
+ int32_t arr[4];
+ for (size_t idx = 0; idx < 4; ++idx) {
+ arr[idx] = mFdp.ConsumeIntegral<int32_t>();
+ }
+ mtpDataPacket.putInt128(arr);
+ },
+ [&]() { mtpDataPacket.putInt64(mFdp.ConsumeIntegral<int64_t>()); },
+ [&]() {
+ int16_t out;
+ mtpDataPacket.getInt16(out);
+ },
+ [&]() {
+ int32_t out;
+ mtpDataPacket.getInt32(out);
+ },
+ [&]() {
+ int8_t out;
+ mtpDataPacket.getInt8(out);
+ },
+ [&]() {
+ uint32_t arr[4];
+ for (size_t idx = 0; idx < 4; ++idx) {
+ arr[idx] = mFdp.ConsumeIntegral<uint32_t>();
+ }
+ if (mFdp.ConsumeBool()) {
+ mtpDataPacket.putUInt128(arr);
+ } else {
+ mtpDataPacket.getUInt128(arr);
+ }
+ },
+ [&]() { mtpDataPacket.putUInt64(mFdp.ConsumeIntegral<uint64_t>()); },
+ [&]() {
+ uint64_t out;
+ mtpDataPacket.getUInt64(out);
+ },
+ [&]() { mtpDataPacket.putInt128(mFdp.ConsumeIntegral<int64_t>()); },
+ [&]() { mtpDataPacket.putUInt128(mFdp.ConsumeIntegral<uint64_t>()); },
+ [&]() {
+ int32_t length;
+ void* data = mtpDataPacket.getData(&length);
+ free(data);
+ },
+ });
+ mtpDataAPI();
+ }
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ MtpDataPacketFuzzer mtpDataPacketFuzzer(data, size);
+ mtpDataPacketFuzzer.process();
+ return 0;
+}
diff --git a/media/mtp/tests/MtpFuzzer/mtp_device_fuzzer.cpp b/media/mtp/tests/MtpFuzzer/mtp_device_fuzzer.cpp
new file mode 100644
index 0000000..c32d28a
--- /dev/null
+++ b/media/mtp/tests/MtpFuzzer/mtp_device_fuzzer.cpp
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <MtpDevHandle.h>
+#include <MtpDevice.h>
+#include <MtpDeviceInfo.h>
+#include <MtpObjectInfo.h>
+#include <MtpProperty.h>
+#include <MtpStorageInfo.h>
+#include <MtpStringBuffer.h>
+#include <android-base/unique_fd.h>
+#include <fcntl.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <linux/usb/ch9.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <usbhost/usbhost.h>
+
+using namespace android;
+
+constexpr int32_t kMaxStringLength = 20;
+constexpr int32_t kMaxBytes = 200;
+constexpr int32_t kMaxDataSize = 20;
+constexpr uint16_t kWMaxPacketSize = 64;
+constexpr uint16_t kEndpointsCount = 3;
+const std::string kInputFile = "/dev/null";
+const std::string kConfigFilePath = "/data/local/tmp/config";
+
+static bool readCallback(void* data, uint32_t offset, uint32_t length, void* clientData) {
+ return true;
+}
+
+struct fdDescriptors {
+ struct usb_interface_descriptor interface;
+ struct usb_endpoint_descriptor ep[kEndpointsCount];
+};
+
+fdDescriptors writeDescriptorsToFd(int32_t fd, FuzzedDataProvider& fdp) {
+ fdDescriptors desc;
+ desc.interface.bLength = sizeof(desc.interface);
+ desc.interface.bDescriptorType = USB_DT_INTERFACE;
+ desc.interface.bInterfaceNumber = fdp.ConsumeIntegral<uint8_t>();
+ desc.interface.bNumEndpoints = kEndpointsCount;
+ desc.interface.bInterfaceClass =
+ fdp.ConsumeBool() ? USB_CLASS_STILL_IMAGE : USB_CLASS_VENDOR_SPEC;
+ desc.interface.bInterfaceSubClass = fdp.ConsumeBool() ? 1 : 0xFF;
+ desc.interface.bInterfaceProtocol = fdp.ConsumeBool() ? 1 : 0;
+ desc.interface.iInterface = fdp.ConsumeIntegral<uint8_t>();
+ for (uint16_t idx = 0; idx < kEndpointsCount; ++idx) {
+ desc.ep[idx].bLength = sizeof(desc.ep[idx]);
+ desc.ep[idx].bDescriptorType = USB_DT_ENDPOINT;
+ desc.ep[idx].bEndpointAddress = idx | (fdp.ConsumeBool() ? USB_DIR_OUT : USB_DIR_IN);
+ desc.ep[idx].bmAttributes =
+ fdp.ConsumeBool() ? USB_ENDPOINT_XFER_BULK : USB_ENDPOINT_XFER_INT;
+ desc.ep[idx].wMaxPacketSize = kWMaxPacketSize;
+ }
+ write(fd, &desc, sizeof(fdDescriptors));
+ return desc;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ FuzzedDataProvider fdp(data, size);
+ int32_t fd = memfd_create(kConfigFilePath.c_str(), MFD_ALLOW_SEALING);
+ fdDescriptors descriptor = writeDescriptorsToFd(fd, fdp);
+ std::string deviceName = fdp.ConsumeRandomLengthString(kMaxStringLength);
+ usb_device* device = usb_device_new(deviceName.c_str(), fd);
+ MtpDevice mtpDevice(device, fdp.ConsumeIntegral<int32_t>(), &descriptor.ep[0],
+ &descriptor.ep[1], &descriptor.ep[2]);
+ while (fdp.remaining_bytes()) {
+ auto mtpDeviceFunction = fdp.PickValueInArray<const std::function<void()>>(
+ {[&]() { mtpDevice.getStorageIDs(); },
+ [&]() {
+ mtpDevice.getStorageInfo(fdp.ConsumeIntegral<int32_t>() /* storageID */);
+ },
+ [&]() {
+ mtpDevice.getObjectHandles(fdp.ConsumeIntegral<uint32_t>() /* storageID */,
+ fdp.ConsumeIntegral<uint16_t>() /* format */,
+ fdp.ConsumeIntegral<uint32_t>() /* parent */);
+ },
+ [&]() { mtpDevice.initialize(); },
+ [&]() {
+ int32_t outLength = 0;
+ mtpDevice.getThumbnail(fdp.ConsumeIntegral<uint32_t>() /* handle */,
+ outLength);
+ },
+ [&]() {
+ MtpObjectInfo mtpObjectInfo(fdp.ConsumeIntegral<uint32_t>() /* handle */);
+ std::string name = fdp.ConsumeRandomLengthString(kMaxStringLength);
+ std::string keywords = fdp.ConsumeRandomLengthString(kMaxStringLength);
+ mtpObjectInfo.mName = strdup(name.c_str());
+ mtpObjectInfo.mKeywords = strdup(keywords.c_str());
+ mtpDevice.sendObjectInfo(&mtpObjectInfo);
+ },
+ [&]() {
+ mtpDevice.sendObject(fdp.ConsumeIntegral<uint32_t>() /* handle */,
+ fdp.ConsumeIntegral<uint32_t>() /* size */, fd);
+ },
+ [&]() { mtpDevice.deleteObject(fdp.ConsumeIntegral<uint32_t>() /* handle */); },
+ [&]() {
+ mtpDevice.getObjectPropsSupported(
+ fdp.ConsumeIntegral<uint16_t>() /* format */);
+ },
+ [&]() {
+ MtpDataType dataType = fdp.ConsumeIntegral<int16_t>();
+ MtpProperty mtpProperty(fdp.ConsumeIntegral<int16_t>() /* propCode */,
+ dataType, fdp.ConsumeBool() /* writeable */,
+ fdp.ConsumeIntegral<int32_t>() /* defaultValue */);
+ if (dataType == MTP_TYPE_STR) {
+ mtpProperty.setCurrentValue(
+ fdp.ConsumeRandomLengthString(kMaxStringLength).c_str());
+ }
+ mtpDevice.setDevicePropValueStr(&mtpProperty);
+ },
+ [&]() {
+ mtpDevice.getObjectPropDesc(fdp.ConsumeIntegral<uint16_t>() /* code */,
+ fdp.ConsumeIntegral<uint16_t>() /* format */);
+ },
+ [&]() {
+ MtpProperty property;
+ mtpDevice.getObjectPropValue(fdp.ConsumeIntegral<uint16_t>() /* handle */,
+ &property);
+ },
+ [&]() {
+ std::vector<uint8_t> clientData = fdp.ConsumeBytes<uint8_t>(kMaxDataSize);
+ mtpDevice.readObject(
+ fdp.ConsumeIntegral<uint32_t>() /* handle */, readCallback,
+ fdp.ConsumeIntegral<uint32_t>() /* objectSize */, &clientData);
+ },
+ [&]() {
+ std::vector<uint8_t> clientData = fdp.ConsumeBytes<uint8_t>(kMaxDataSize);
+ uint32_t writtenSize = 0;
+ mtpDevice.readPartialObject(fdp.ConsumeIntegral<uint32_t>() /* handle */,
+ fdp.ConsumeIntegral<uint32_t>() /* offset */,
+ fdp.ConsumeIntegral<uint32_t>() /* size */,
+ &writtenSize, readCallback, &clientData);
+ },
+ [&]() {
+ std::vector<uint8_t> clientData = fdp.ConsumeBytes<uint8_t>(kMaxDataSize);
+ uint32_t writtenSize = 0;
+ mtpDevice.readPartialObject(fdp.ConsumeIntegral<uint32_t>() /* handle */,
+ fdp.ConsumeIntegral<uint64_t>() /* offset */,
+ fdp.ConsumeIntegral<uint32_t>() /* size */,
+ &writtenSize, readCallback, &clientData);
+ },
+ [&]() {
+ if (mtpDevice.submitEventRequest() != -1) {
+ uint32_t parameters[3];
+ mtpDevice.reapEventRequest(fdp.ConsumeIntegral<int32_t>() /* handle */,
+ ¶meters);
+ }
+ },
+ [&]() {
+ mtpDevice.discardEventRequest(fdp.ConsumeIntegral<int32_t>() /*handle*/);
+ },
+ [&]() {
+ mtpDevice.discardEventRequest(fdp.ConsumeIntegral<int32_t>() /* handle */);
+ },
+ [&]() { mtpDevice.print(); },
+ [&]() { mtpDevice.getDeviceName(); },
+ [&]() { mtpDevice.getObjectInfo(fdp.ConsumeIntegral<uint32_t>() /* handle */); },
+ [&]() { mtpDevice.getParent(fdp.ConsumeIntegral<uint32_t>() /* handle */); },
+ [&]() { mtpDevice.getStorageID(fdp.ConsumeIntegral<uint32_t>() /* handle */); },
+ [&]() { mtpDevice.getDevicePropDesc(fdp.ConsumeIntegral<uint16_t>() /* code */); },
+ [&]() {
+ mtpDevice.readObject(
+ fdp.ConsumeIntegral<uint32_t>() /* handle */,
+ fdp.ConsumeRandomLengthString(kMaxStringLength).c_str() /* destPath */,
+ fdp.ConsumeIntegral<int32_t>() /* group */,
+ fdp.ConsumeIntegral<int32_t>() /* perm */);
+ },
+ [&]() {
+ int32_t filefd = open(kConfigFilePath.c_str(), O_CREAT | O_RDWR);
+ mtpDevice.readObject(fdp.ConsumeIntegral<uint16_t>() /* handle */, filefd);
+ close(filefd);
+ },
+ [&]() { MtpDevice::open(deviceName.c_str(), fd); },
+ [&]() {
+ MtpObjectInfo objectinfo(fdp.ConsumeIntegral<uint32_t>() /* handle */);
+ MtpDataPacket mtpDataPacket;
+ MtpDevHandle devHandle;
+ std::vector<uint8_t> packet = fdp.ConsumeBytes<uint8_t>(kMaxBytes);
+ mtpDataPacket.writeData(&devHandle, packet.data(), packet.size());
+ objectinfo.read(mtpDataPacket);
+ objectinfo.print();
+ },
+ [&]() {
+ MtpStorageInfo storageInfo(fdp.ConsumeIntegral<uint32_t>() /* id */);
+ MtpDataPacket mtpDataPacket;
+ MtpDevHandle devHandle;
+ std::vector<uint8_t> packet = fdp.ConsumeBytes<uint8_t>(kMaxBytes);
+ mtpDataPacket.writeData(&devHandle, packet.data(), packet.size());
+ storageInfo.read(mtpDataPacket);
+ storageInfo.print();
+ }});
+ mtpDeviceFunction();
+ }
+ close(fd);
+ return 0;
+}
diff --git a/media/mtp/tests/MtpFuzzer/mtp_event_packet_fuzzer.cpp b/media/mtp/tests/MtpFuzzer/mtp_event_packet_fuzzer.cpp
new file mode 100644
index 0000000..3bd3be2
--- /dev/null
+++ b/media/mtp/tests/MtpFuzzer/mtp_event_packet_fuzzer.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <MtpDevHandle.h>
+#include <MtpEventPacket.h>
+#include <MtpPacketFuzzerUtils.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+using namespace android;
+
+class MtpEventPacketFuzzer : MtpPacketFuzzerUtils {
+ public:
+ MtpEventPacketFuzzer(const uint8_t* data, size_t size) : mFdp(data, size) {
+ mUsbDevFsUrb = (struct usbdevfs_urb*)malloc(sizeof(struct usbdevfs_urb) +
+ sizeof(struct usbdevfs_iso_packet_desc));
+ };
+ ~MtpEventPacketFuzzer() { free(mUsbDevFsUrb); };
+ void process();
+
+ private:
+ FuzzedDataProvider mFdp;
+};
+
+void MtpEventPacketFuzzer::process() {
+ MtpEventPacket mtpEventPacket;
+ while (mFdp.remaining_bytes() > 0) {
+ auto mtpEventAPI = mFdp.PickValueInArray<const std::function<void()>>({
+ [&]() { mtpEventPacket.allocate(mFdp.ConsumeIntegralInRange(kMinSize, kMaxSize)); },
+ [&]() { mtpEventPacket.reset(); },
+ [&]() { writeHandle(&mtpEventPacket, &mFdp); },
+ [&]() {
+ fillFilePath(&mFdp);
+ int32_t fd = memfd_create(mPath.c_str(), MFD_ALLOW_SEALING);
+ fillUsbRequest(fd, &mFdp);
+ mUsbRequest.dev = usb_device_new(mPath.c_str(), fd);
+ mtpEventPacket.sendRequest(&mUsbRequest);
+ usb_device_close(mUsbRequest.dev);
+ },
+ [&]() {
+ fillFilePath(&mFdp);
+ int32_t fd = memfd_create(mPath.c_str(), MFD_ALLOW_SEALING);
+ fillFd(fd, &mFdp);
+ struct usb_device* device = usb_device_new(mPath.c_str(), fd);
+ mtpEventPacket.readResponse(device);
+ usb_device_close(device);
+ },
+ });
+ mtpEventAPI();
+ }
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ MtpEventPacketFuzzer mtpEventPacketFuzzer(data, size);
+ mtpEventPacketFuzzer.process();
+ return 0;
+}
diff --git a/media/mtp/tests/MtpFuzzer/mtp_fuzzer.cpp b/media/mtp/tests/MtpFuzzer/mtp_fuzzer.cpp
index f578462..e886816 100644
--- a/media/mtp/tests/MtpFuzzer/mtp_fuzzer.cpp
+++ b/media/mtp/tests/MtpFuzzer/mtp_fuzzer.cpp
@@ -14,12 +14,15 @@
* limitations under the License.
*/
+#include <android-base/properties.h>
#include <android-base/unique_fd.h>
+#include <fuzzer/FuzzedDataProvider.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
-
+#include <filesystem>
+#include <fstream>
#include <string>
#define LOG_TAG "MtpFuzzer"
@@ -32,38 +35,40 @@
#include "MtpStorage.h"
#include "MtpUtils.h"
-const char* storage_desc = "Fuzz Storage";
+constexpr int32_t kMinFiles = 0;
+constexpr int32_t kMaxFiles = 5;
+constexpr int32_t kMaxBytes = 128;
+constexpr float kMinDataSizeFactor = 0.8;
// prefer tmpfs for file operations to avoid wearing out flash
const char* storage_path = "/storage/fuzzer/0";
-const char* source_database = "srcdb/";
+const char* source_database = "/data/local/tmp/srcdb/";
+const std::string test_path = std::string(source_database) + "TestDir/";
+const std::string kPropertyKey = "sys.fuse.transcode_mtp";
namespace android {
class MtpMockServer {
-public:
- std::unique_ptr<MtpMockHandle> mHandle;
- std::unique_ptr<MtpStorage> mStorage;
- std::unique_ptr<MtpMockDatabase> mDatabase;
- std::unique_ptr<MtpServer> mMtp;
- int mStorageId;
-
- MtpMockServer(const char* storage_path) : mStorageId(0) {
- bool ptp = false;
- const char* manu = "Google";
- const char* model = "Pixel 3XL";
- const char* version = "1.0";
- const char* serial = "ABDEF1231";
-
+ public:
+ MtpMockServer(const uint8_t* data, size_t size) : mFdp(data, size) {
// This is unused in our harness
int controlFd = -1;
mHandle = std::make_unique<MtpMockHandle>();
- mStorage = std::make_unique<MtpStorage>(mStorageId, storage_path, storage_desc, true,
- 0x200000000L);
+ mStorage = std::make_unique<MtpStorage>(
+ mFdp.ConsumeIntegral<uint32_t>() /* storageId */, storage_path,
+ mFdp.ConsumeRandomLengthString(kMaxBytes).c_str() /* descriptor */,
+ mFdp.ConsumeBool() /* removable */,
+ mFdp.ConsumeIntegral<uint64_t>() /* maxFileSize */);
mDatabase = std::make_unique<MtpMockDatabase>();
mDatabase->addStorage(mStorage.get());
- mMtp = std::make_unique<MtpServer>(mDatabase.get(), controlFd, ptp, manu, model, version,
- serial);
+ init(data, size);
+
+ mMtp = std::make_unique<MtpServer>(
+ mDatabase.get(), controlFd, mFdp.ConsumeBool() /* ptp */,
+ mFdp.ConsumeRandomLengthString(kMaxBytes).c_str() /* manu */,
+ mFdp.ConsumeRandomLengthString(kMaxBytes).c_str() /* model */,
+ mFdp.ConsumeRandomLengthString(kMaxBytes).c_str() /* version */,
+ mFdp.ConsumeRandomLengthString(kMaxBytes).c_str() /* serial */);
mMtp->addStorage(mStorage.get());
// clear the old handle first, so we don't leak memory
@@ -71,7 +76,76 @@
mMtp->mHandle = mHandle.get();
}
- void run() { mMtp->run(); }
+ void process() {
+ if (mFdp.ConsumeBool()) {
+ createDatabaseFromSourceDir(source_database, storage_path, MTP_PARENT_ROOT);
+ }
+
+ while (mFdp.remaining_bytes()) {
+ MtpStorage storage(mFdp.ConsumeIntegral<uint32_t>() /* id */,
+ mFdp.ConsumeRandomLengthString(kMaxBytes).c_str() /* filePath */,
+ mFdp.ConsumeRandomLengthString(kMaxBytes).c_str() /* description */,
+ mFdp.ConsumeBool() /* removable */,
+ mFdp.ConsumeIntegral<uint64_t>() /* maxFileSize */);
+
+ auto invokeMtpServerAPI = mFdp.PickValueInArray<const std::function<void()>>({
+ [&]() { mMtp->run(); },
+ [&]() { mMtp->sendObjectAdded(mFdp.ConsumeIntegral<uint32_t>()); },
+ [&]() { mMtp->sendObjectRemoved(mFdp.ConsumeIntegral<uint32_t>()); },
+ [&]() { mMtp->sendObjectInfoChanged(mFdp.ConsumeIntegral<uint32_t>()); },
+ [&]() { mMtp->sendDevicePropertyChanged(mFdp.ConsumeIntegral<uint16_t>()); },
+ [&]() { mMtp->addStorage(&storage); },
+ [&]() { mMtp->removeStorage(&storage); },
+ });
+
+ invokeMtpServerAPI();
+ }
+
+ std::filesystem::remove_all(source_database);
+ }
+
+ private:
+ void createFiles(std::string path, size_t fileCount) {
+ std::ofstream file;
+ for (size_t idx = 0; idx < fileCount; ++idx) {
+ file.open(path.append(std::to_string(idx)));
+ file.close();
+ }
+ }
+
+ void addPackets(const uint8_t* data, size_t size) {
+ size_t off = 0;
+ for (size_t i = 0; i < size; ++i) {
+ // A longer delimiter could be used, but this worked in practice
+ if (data[i] == '@') {
+ size_t pktsz = i - off;
+ if (pktsz > 0) {
+ packet_t pkt = packet_t((unsigned char*)data + off, (unsigned char*)data + i);
+ // insert into packet buffer
+ mHandle->add_packet(pkt);
+ off = i;
+ }
+ }
+ }
+ }
+
+ void init(const uint8_t* data, size_t size) {
+ std::vector<uint8_t> packetData = mFdp.ConsumeBytes<uint8_t>(
+ mFdp.ConsumeIntegralInRange<int32_t>(kMinDataSizeFactor * size, size));
+
+ // Packetize the input stream
+ addPackets(packetData.data(), packetData.size());
+
+ // Setting the property to true/false to randomly fuzz the PoC depended on it
+ base::SetProperty(kPropertyKey, mFdp.ConsumeBool() ? "true" : "false");
+
+ std::filesystem::create_directories(source_database);
+ if (mFdp.ConsumeBool()) {
+ std::filesystem::create_directories(test_path);
+ createFiles(test_path, mFdp.ConsumeIntegralInRange<size_t>(kMinFiles, kMaxFiles));
+ }
+ createFiles(source_database, mFdp.ConsumeIntegralInRange<size_t>(kMinFiles, kMaxFiles));
+ }
int createDatabaseFromSourceDir(const char* fromPath, const char* toPath,
MtpObjectHandle parentHandle) {
@@ -130,8 +204,14 @@
closedir(dir);
return ret;
}
+
+ FuzzedDataProvider mFdp;
+ std::unique_ptr<MtpMockHandle> mHandle;
+ std::unique_ptr<MtpStorage> mStorage;
+ std::unique_ptr<MtpMockDatabase> mDatabase;
+ std::unique_ptr<MtpServer> mMtp;
};
-}; // namespace android
+}; // namespace android
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) __attribute__((optnone)) {
// reset our storage (from MtpUtils.h)
@@ -140,26 +220,9 @@
android::makeFolder(storage_path);
std::unique_ptr<android::MtpMockServer> mtp =
- std::make_unique<android::MtpMockServer>(storage_path);
+ std::make_unique<android::MtpMockServer>(data, size);
+ mtp->process();
- size_t off = 0;
-
- // Packetize the input stream
- for (size_t i = 0; i < size; i++) {
- // A longer delimiter could be used, but this worked in practice
- if (data[i] == '@') {
- size_t pktsz = i - off;
- if (pktsz > 0) {
- packet_t pkt = packet_t((unsigned char*)data + off, (unsigned char*)data + i);
- // insert into packet buffer
- mtp->mHandle->add_packet(pkt);
- off = i;
- }
- }
- }
-
- mtp->createDatabaseFromSourceDir(source_database, storage_path, MTP_PARENT_ROOT);
- mtp->run();
-
+ std::filesystem::remove_all("/storage/fuzzer");
return 0;
}
diff --git a/media/mtp/tests/MtpFuzzer/mtp_handle_fuzzer.cpp b/media/mtp/tests/MtpFuzzer/mtp_handle_fuzzer.cpp
new file mode 100644
index 0000000..676345a
--- /dev/null
+++ b/media/mtp/tests/MtpFuzzer/mtp_handle_fuzzer.cpp
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <MtpDescriptors.h>
+#include <MtpFfsCompatHandle.h>
+#include <android-base/file.h>
+#include <fcntl.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <mtp.h>
+
+using namespace android;
+
+constexpr int32_t kMaxStringLength = 64;
+constexpr int32_t kMinAPICase = 0;
+constexpr int32_t kMaxMtpHandleAPI = 5;
+constexpr int32_t kMinBufferSize = 0;
+constexpr uint32_t kMaxMtpFileSize = 0xFFFFFFFF;
+constexpr float kDataSizeFactor = 0.1;
+
+const std::string kTempPath = "/data/local/tmp/";
+const std::string kFuzzerUsbDirPath = kTempPath + "usb-ffs";
+const std::string kFuzzerMtpPath = kFuzzerUsbDirPath + "/mtp";
+const std::string kFuzzerPtpPath = kFuzzerUsbDirPath + "/ptp";
+const std::string kFuzzerTestFile = kTempPath + "FuzzerTestDescriptorFile";
+const std::string kFuzzerMtpInputFile = kTempPath + "FuzzerMtpInputFile";
+const std::string kFuzzerMtpOutputFile = kTempPath + "FuzzerMtpOutputFile";
+
+const std::string kDeviceFilePaths[] = {FFS_MTP_EP0, FFS_MTP_EP_IN, FFS_MTP_EP_INTR,
+ FFS_PTP_EP0, FFS_PTP_EP_IN, FFS_PTP_EP_INTR,
+ FFS_MTP_EP_OUT, FFS_PTP_EP_OUT};
+
+class MtpFfsHandleFuzzer {
+ public:
+ MtpFfsHandleFuzzer(const uint8_t* data, size_t size) : mFdp(data, size) {
+ mDataSize = kDataSizeFactor * size;
+ createFiles();
+ };
+ void process();
+
+ ~MtpFfsHandleFuzzer() { removeFiles(); };
+
+ private:
+ FuzzedDataProvider mFdp;
+ void invokeWriteDescriptor();
+ void invokeMtpFfsHandle();
+ void createFiles();
+ void removeFiles();
+ void createDeviceFile(const char* file);
+ void writeDeviceFile(const char* file);
+ int32_t writeInputFile(int32_t fd);
+ uint32_t mDataSize = 0;
+};
+
+int32_t MtpFfsHandleFuzzer::writeInputFile(int32_t fd) {
+ uint32_t minFileSize = std::min((uint32_t)MTP_BUFFER_SIZE, mDataSize);
+ uint32_t maxFileSize = std::min(mDataSize, kMaxMtpFileSize);
+ std::vector<char> dataBuffer = mFdp.ConsumeBytes<char>(
+ mFdp.ConsumeIntegralInRange<uint32_t>(minFileSize, maxFileSize));
+ write(fd, dataBuffer.data(), dataBuffer.size());
+ lseek(fd, 0, SEEK_SET);
+ return dataBuffer.size();
+}
+
+void MtpFfsHandleFuzzer::createDeviceFile(const char* file) {
+ int32_t fd = open(file, O_CREAT | O_RDWR | O_NONBLOCK);
+ close(fd);
+}
+
+void MtpFfsHandleFuzzer::writeDeviceFile(const char* file) {
+ int32_t fd = open(file, O_RDWR | O_NONBLOCK);
+ writeInputFile(fd);
+ close(fd);
+}
+
+void MtpFfsHandleFuzzer::createFiles() {
+ mkdir(kFuzzerUsbDirPath.c_str(), 0755);
+ mkdir(kFuzzerMtpPath.c_str(), 0755);
+ mkdir(kFuzzerPtpPath.c_str(), 0755);
+
+ for (auto path : kDeviceFilePaths) {
+ createDeviceFile(path.c_str());
+ }
+
+ writeDeviceFile(FFS_MTP_EP_OUT);
+ writeDeviceFile(FFS_PTP_EP_OUT);
+}
+
+void MtpFfsHandleFuzzer::removeFiles() {
+ for (auto path : kDeviceFilePaths) {
+ remove(path.c_str());
+ }
+
+ rmdir(kFuzzerMtpPath.c_str());
+ rmdir(kFuzzerPtpPath.c_str());
+ rmdir(kFuzzerUsbDirPath.c_str());
+}
+
+void MtpFfsHandleFuzzer::invokeWriteDescriptor() {
+ while (mFdp.remaining_bytes() > 0) {
+ int32_t controlFd = mFdp.ConsumeBool()
+ ? -1 /* Invalid fd*/
+ : open(kFuzzerTestFile.c_str(), O_CREAT | O_RDWR | O_NONBLOCK);
+ std::unique_ptr<MtpFfsHandle> handle(new MtpFfsHandle(controlFd));
+ handle->writeDescriptors(mFdp.ConsumeBool());
+ handle->close();
+ close(controlFd);
+ remove(kFuzzerTestFile.c_str());
+ }
+}
+
+void MtpFfsHandleFuzzer::invokeMtpFfsHandle() {
+ while (mFdp.remaining_bytes() > 0) {
+ int32_t controlFd = open(kFuzzerTestFile.c_str(), O_CREAT | O_RDWR | O_NONBLOCK);
+ writeInputFile(controlFd);
+
+ std::unique_ptr<IMtpHandle> handle;
+ if (mFdp.ConsumeBool()) {
+ std::unique_ptr<IMtpHandle> mtpCompactHandle(new MtpFfsCompatHandle(controlFd));
+ handle = move(mtpCompactHandle);
+ } else {
+ std::unique_ptr<IMtpHandle> mtpHandle(new MtpFfsHandle(controlFd));
+ handle = move(mtpHandle);
+ }
+
+ int32_t mtpHandle = mFdp.ConsumeIntegralInRange<size_t>(kMinAPICase, kMaxMtpHandleAPI);
+ switch (mtpHandle) {
+ case 0: {
+ handle->start(mFdp.ConsumeBool());
+ break;
+ }
+ case 1: {
+ std::string data = mFdp.ConsumeRandomLengthString(MTP_BUFFER_SIZE);
+ handle->write(data.c_str(), data.length());
+ break;
+ }
+ case 2: {
+ int32_t bufferSize =
+ mFdp.ConsumeIntegralInRange<size_t>(kMinBufferSize, MTP_BUFFER_SIZE);
+ uint8_t buffer[bufferSize + 1];
+ handle->read(buffer, bufferSize);
+ break;
+ }
+ case 3: {
+ mtp_file_range mfr;
+ mfr.fd = open(kFuzzerMtpInputFile.c_str(), O_CREAT | O_RDWR | O_NONBLOCK);
+ mfr.length = writeInputFile(mfr.fd);
+ mfr.offset = 0; /* Offset point to the start of the file */
+ mfr.command = mFdp.ConsumeIntegral<uint16_t>();
+ mfr.transaction_id = mFdp.ConsumeIntegral<uint32_t>();
+ handle->sendFile(mfr);
+ close(mfr.fd);
+ remove(kFuzzerMtpInputFile.c_str());
+ break;
+ }
+ case 4: {
+ struct mtp_event event;
+ std::string dataValue = mFdp.ConsumeRandomLengthString(kMaxStringLength);
+ event.data = const_cast<char*>(dataValue.c_str());
+ event.length = dataValue.length();
+ handle->sendEvent(event);
+ break;
+ }
+ case 5:
+ default: {
+ mtp_file_range mfr;
+ mfr.fd = open(kFuzzerMtpOutputFile.c_str(), O_CREAT | O_RDWR | O_NONBLOCK);
+ mfr.offset = 0; /* Offset point to the start of the file */
+ mfr.length = kMaxMtpFileSize;
+ handle->receiveFile(mfr, mFdp.ConsumeBool());
+ close(mfr.fd);
+ remove(kFuzzerMtpOutputFile.c_str());
+ break;
+ }
+ }
+ handle->close();
+ close(controlFd);
+ remove(kFuzzerTestFile.c_str());
+ }
+}
+
+void MtpFfsHandleFuzzer::process() {
+ if (mFdp.ConsumeBool()) {
+ invokeMtpFfsHandle();
+ } else {
+ invokeWriteDescriptor();
+ }
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ MtpFfsHandleFuzzer mtpFfsHandleFuzzer(data, size);
+ mtpFfsHandleFuzzer.process();
+ return 0;
+}
diff --git a/media/mtp/tests/MtpFuzzer/mtp_packet_fuzzer.cpp b/media/mtp/tests/MtpFuzzer/mtp_packet_fuzzer.cpp
new file mode 100644
index 0000000..6fc2a96
--- /dev/null
+++ b/media/mtp/tests/MtpFuzzer/mtp_packet_fuzzer.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <MtpDevHandle.h>
+#include <MtpPacket.h>
+#include <MtpPacketFuzzerUtils.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+using namespace android;
+
+class MtpPacketFuzzer : MtpPacketFuzzerUtils {
+ public:
+ MtpPacketFuzzer(const uint8_t* data, size_t size) : mFdp(data, size) {
+ mUsbDevFsUrb = (struct usbdevfs_urb*)malloc(sizeof(struct usbdevfs_urb) +
+ sizeof(struct usbdevfs_iso_packet_desc));
+ };
+ ~MtpPacketFuzzer() { free(mUsbDevFsUrb); };
+ void process();
+
+ private:
+ FuzzedDataProvider mFdp;
+};
+
+void MtpPacketFuzzer::process() {
+ MtpPacket mtpPacket(mFdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize)); /*bufferSize*/
+ while (mFdp.remaining_bytes() > 0) {
+ auto mtpPacketAPI = mFdp.PickValueInArray<const std::function<void()>>({
+ [&]() {
+ mtpPacket.allocate(mFdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize));
+ },
+ [&]() { mtpPacket.reset(); },
+ [&]() { mtpPacket.getContainerType(); },
+ [&]() { mtpPacket.getContainerCode(); },
+ [&]() { mtpPacket.dump(); },
+ [&]() { mtpPacket.getTransactionID(); },
+ [&]() {
+ mtpPacket.setContainerCode(
+ mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, kMaxSize));
+ },
+ [&]() {
+ mtpPacket.setTransactionID(
+ mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, kMaxSize));
+ },
+ [&]() {
+ mtpPacket.getParameter(
+ mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, kMaxSize));
+ },
+ [&]() {
+ mtpPacket.setParameter(
+ mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, kMaxSize),
+ mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, kMaxSize));
+ },
+ [&]() {
+ MtpPacket testMtpPacket(
+ mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, kMaxSize));
+ testMtpPacket.copyFrom(mtpPacket);
+ },
+ [&]() {
+ fillFilePath(&mFdp);
+ int32_t fd = memfd_create(mPath.c_str(), MFD_ALLOW_SEALING);
+ fillUsbRequest(fd, &mFdp);
+ mUsbRequest.dev = usb_device_new(mPath.c_str(), fd);
+ mtpPacket.transfer(&mUsbRequest);
+ usb_device_close(mUsbRequest.dev);
+ },
+ });
+ mtpPacketAPI();
+ }
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ MtpPacketFuzzer mtpPacketFuzzer(data, size);
+ mtpPacketFuzzer.process();
+ return 0;
+}
diff --git a/media/mtp/tests/MtpFuzzer/mtp_property_fuzzer.cpp b/media/mtp/tests/MtpFuzzer/mtp_property_fuzzer.cpp
new file mode 100644
index 0000000..b4e659c
--- /dev/null
+++ b/media/mtp/tests/MtpFuzzer/mtp_property_fuzzer.cpp
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <MtpDataPacket.h>
+#include <MtpDevHandle.h>
+#include <MtpPacketFuzzerUtils.h>
+#include <MtpProperty.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <utils/String16.h>
+
+using namespace android;
+
+constexpr uint16_t kFeasibleTypes[] = {
+ MTP_TYPE_UNDEFINED, MTP_TYPE_INT8, MTP_TYPE_UINT8, MTP_TYPE_INT16, MTP_TYPE_UINT16,
+ MTP_TYPE_INT32, MTP_TYPE_UINT32, MTP_TYPE_INT64, MTP_TYPE_UINT64, MTP_TYPE_INT128,
+ MTP_TYPE_UINT128, MTP_TYPE_AINT8, MTP_TYPE_AUINT8, MTP_TYPE_AINT16, MTP_TYPE_AUINT16,
+ MTP_TYPE_AINT32, MTP_TYPE_AUINT32, MTP_TYPE_AINT64, MTP_TYPE_AUINT64, MTP_TYPE_AINT128,
+ MTP_TYPE_AUINT128, MTP_TYPE_STR,
+};
+
+class MtpPropertyFuzzer : MtpPacketFuzzerUtils {
+ public:
+ MtpPropertyFuzzer(const uint8_t* data, size_t size) : mFdp(data, size) {
+ mUsbDevFsUrb = (struct usbdevfs_urb*)malloc(sizeof(struct usbdevfs_urb) +
+ sizeof(struct usbdevfs_iso_packet_desc));
+ };
+ ~MtpPropertyFuzzer() { free(mUsbDevFsUrb); };
+ void process();
+
+ private:
+ FuzzedDataProvider mFdp;
+};
+
+void MtpPropertyFuzzer::process() {
+ MtpProperty* mtpProperty = nullptr;
+ if (mFdp.ConsumeBool()) {
+ mtpProperty = new MtpProperty();
+ } else {
+ uint16_t type = mFdp.ConsumeBool() ? mFdp.ConsumeIntegral<uint16_t>()
+ : mFdp.PickValueInArray<uint16_t>(kFeasibleTypes);
+ mtpProperty = new MtpProperty(mFdp.ConsumeIntegral<uint16_t>(), type, mFdp.ConsumeBool(),
+ mFdp.ConsumeIntegral<uint16_t>());
+ }
+
+ while (mFdp.remaining_bytes() > 0) {
+ auto invokeMtpPropertyFuzzer = mFdp.PickValueInArray<const std::function<void()>>({
+ [&]() {
+ MtpDataPacket mtpDataPacket;
+ if (mFdp.ConsumeBool()) {
+ mtpProperty->read(mtpDataPacket);
+
+ } else {
+ if (mFdp.ConsumeBool()) {
+#ifdef MTP_DEVICE
+ android::IMtpHandle* h = new MtpDevHandle();
+ h->start(mFdp.ConsumeBool());
+ std::string text = mFdp.ConsumeRandomLengthString(kMaxLength);
+ char* data = const_cast<char*>(text.c_str());
+ h->read(static_cast<void*>(data), text.length());
+ mtpDataPacket.write(h);
+ h->close();
+ delete h;
+#endif
+
+#ifdef MTP_HOST
+ fillFilePath(&mFdp);
+ int32_t fd = memfd_create(mPath.c_str(), MFD_ALLOW_SEALING);
+ fillUsbRequest(fd, &mFdp);
+ mUsbRequest.dev = usb_device_new(mPath.c_str(), fd);
+ mtpDataPacket.write(&mUsbRequest,
+ mFdp.PickValueInArray<UrbPacketDivisionMode>(
+ kUrbPacketDivisionModes),
+ fd,
+ mFdp.ConsumeIntegralInRange(kMinSize, kMaxSize));
+ usb_device_close(mUsbRequest.dev);
+#endif
+ }
+
+ if (mFdp.ConsumeBool()) {
+ mtpProperty->write(mtpDataPacket);
+ } else {
+ mtpProperty->setCurrentValue(mtpDataPacket);
+ }
+ }
+ },
+ [&]() {
+ char16_t* data = nullptr;
+ std::string str = mFdp.ConsumeRandomLengthString(kMaxLength);
+ android::String16 s(str.c_str());
+ if (mFdp.ConsumeBool()) {
+ data = const_cast<char16_t*>(s.string());
+ }
+
+ if (mFdp.ConsumeBool()) {
+ mtpProperty->setDefaultValue(reinterpret_cast<uint16_t*>(data));
+ } else if (mFdp.ConsumeBool()) {
+ mtpProperty->setCurrentValue(reinterpret_cast<uint16_t*>(data));
+ } else {
+ mtpProperty->setCurrentValue(str.c_str());
+ }
+ },
+ [&]() {
+ mtpProperty->setFormRange(mFdp.ConsumeIntegral<int32_t>(),
+ mFdp.ConsumeIntegral<int32_t>(),
+ mFdp.ConsumeIntegral<int32_t>());
+ },
+ [&]() {
+ std::vector<int32_t> init;
+ for (size_t idx = 0; idx < mFdp.ConsumeIntegralInRange(kMinSize, kMaxSize);
+ ++idx) {
+ init.push_back(mFdp.ConsumeIntegral<int32_t>());
+ }
+ mtpProperty->setFormEnum(init.data(), init.size());
+ },
+ });
+ invokeMtpPropertyFuzzer();
+ }
+
+ delete (mtpProperty);
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ MtpPropertyFuzzer mtpPropertyFuzzer(data, size);
+ mtpPropertyFuzzer.process();
+ return 0;
+}
diff --git a/media/mtp/tests/MtpFuzzer/mtp_request_packet_fuzzer.cpp b/media/mtp/tests/MtpFuzzer/mtp_request_packet_fuzzer.cpp
new file mode 100644
index 0000000..19fbc5b
--- /dev/null
+++ b/media/mtp/tests/MtpFuzzer/mtp_request_packet_fuzzer.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <MtpDevHandle.h>
+#include <MtpPacketFuzzerUtils.h>
+#include <MtpRequestPacket.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <fstream>
+
+using namespace android;
+
+std::string kMtpDevPath = "/dev/mtp_usb";
+constexpr int32_t kMaxBytes = 100000;
+
+class MtpRequestPacketFuzzer : MtpPacketFuzzerUtils {
+ public:
+ MtpRequestPacketFuzzer(const uint8_t* data, size_t size) : mFdp(data, size) {
+ mUsbDevFsUrb = (struct usbdevfs_urb*)malloc(sizeof(struct usbdevfs_urb) +
+ sizeof(struct usbdevfs_iso_packet_desc));
+ };
+ ~MtpRequestPacketFuzzer() { free(mUsbDevFsUrb); };
+ void process();
+
+ private:
+ FuzzedDataProvider mFdp;
+ void makeFile(std::string s);
+};
+
+void MtpRequestPacketFuzzer::process() {
+ MtpRequestPacket mtpRequestPacket;
+ while (mFdp.remaining_bytes() > 0) {
+ auto mtpRequestAPI = mFdp.PickValueInArray<const std::function<void()>>({
+ [&]() {
+ mtpRequestPacket.allocate(mFdp.ConsumeIntegralInRange(kMinSize, kMaxSize));
+ },
+ [&]() { mtpRequestPacket.reset(); },
+ [&]() {
+ MtpDevHandle handle;
+ makeFile(kMtpDevPath);
+ handle.start(mFdp.ConsumeBool());
+ std::vector<uint8_t> data = mFdp.ConsumeBytes<uint8_t>(
+ mFdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize));
+ handle.write(data.data(), data.size());
+ mtpRequestPacket.read(&handle);
+ handle.close();
+ remove(kMtpDevPath.c_str());
+ },
+ [&]() {
+ fillFilePath(&mFdp);
+ int32_t fd = memfd_create(mPath.c_str(), MFD_ALLOW_SEALING);
+ fillUsbRequest(fd, &mFdp);
+ mUsbRequest.dev = usb_device_new(mPath.c_str(), fd);
+ mtpRequestPacket.write(&mUsbRequest);
+ usb_device_close(mUsbRequest.dev);
+ },
+ });
+ mtpRequestAPI();
+ }
+}
+
+void MtpRequestPacketFuzzer::makeFile(std::string s) {
+ std::ofstream out;
+ out.open(s, std::ios::binary | std::ofstream::trunc);
+ for (int32_t idx = 0; idx < mFdp.ConsumeIntegralInRange<int32_t>(kMinSize, kMaxSize); ++idx) {
+ out << mFdp.ConsumeRandomLengthString(kMaxBytes) << "\n";
+ }
+ out.close();
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ MtpRequestPacketFuzzer mtpRequestPacketFuzzer(data, size);
+ mtpRequestPacketFuzzer.process();
+ return 0;
+}
diff --git a/media/mtp/tests/MtpFuzzer/mtp_response_packet_fuzzer.cpp b/media/mtp/tests/MtpFuzzer/mtp_response_packet_fuzzer.cpp
new file mode 100644
index 0000000..697785f
--- /dev/null
+++ b/media/mtp/tests/MtpFuzzer/mtp_response_packet_fuzzer.cpp
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <MtpDevHandle.h>
+#include <MtpPacketFuzzerUtils.h>
+#include <MtpResponsePacket.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+using namespace android;
+
+class MtpResponsePacketFuzzer : MtpPacketFuzzerUtils {
+ public:
+ MtpResponsePacketFuzzer(const uint8_t* data, size_t size) : mFdp(data, size) {
+ mUsbDevFsUrb = (struct usbdevfs_urb*)malloc(sizeof(struct usbdevfs_urb) +
+ sizeof(struct usbdevfs_iso_packet_desc));
+ };
+ ~MtpResponsePacketFuzzer() { free(mUsbDevFsUrb); };
+ void process();
+
+ private:
+ FuzzedDataProvider mFdp;
+};
+
+void MtpResponsePacketFuzzer::process() {
+ MtpResponsePacket mtpResponsePacket;
+ while (mFdp.remaining_bytes() > 0) {
+ auto mtpResponseAPI = mFdp.PickValueInArray<const std::function<void()>>({
+ [&]() {
+ mtpResponsePacket.allocate(
+ mFdp.ConsumeIntegralInRange(kMinSize, kMaxSize)); /*size*/
+ },
+ [&]() { mtpResponsePacket.reset(); },
+ [&]() { writeHandle(&mtpResponsePacket, &mFdp); },
+ [&]() {
+ fillFilePath(&mFdp);
+ int32_t fd = memfd_create(mPath.c_str(), MFD_ALLOW_SEALING);
+ fillUsbRequest(fd, &mFdp);
+ mUsbRequest.dev = usb_device_new(mPath.c_str(), fd);
+ mtpResponsePacket.read(&mUsbRequest);
+ usb_device_close(mUsbRequest.dev);
+ },
+ });
+ mtpResponseAPI();
+ }
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ MtpResponsePacketFuzzer mtpResponsePacketFuzzer(data, size);
+ mtpResponsePacketFuzzer.process();
+ return 0;
+}
diff --git a/media/ndk/Android.bp b/media/ndk/Android.bp
index ddc71db..fded4f5 100644
--- a/media/ndk/Android.bp
+++ b/media/ndk/Android.bp
@@ -52,6 +52,9 @@
symbol_file: "libmediandk.map.txt",
first_version: "21",
unversioned_until: "current",
+ export_header_libs: [
+ "libmediandk_headers",
+ ],
}
ndk_headers {
@@ -167,7 +170,7 @@
stubs: {
symbol_file: "libmediandk.map.txt",
versions: ["29"],
- }
+ },
}
cc_library {
diff --git a/media/ndk/NdkMediaDrm.cpp b/media/ndk/NdkMediaDrm.cpp
index f4674de..5005365 100644
--- a/media/ndk/NdkMediaDrm.cpp
+++ b/media/ndk/NdkMediaDrm.cpp
@@ -253,7 +253,7 @@
}
static sp<IDrm> CreateDrm() {
- return DrmUtils::MakeDrm();
+ return DrmUtils::MakeDrm(IDRM_NDK);
}
diff --git a/media/ndk/NdkMediaFormat.cpp b/media/ndk/NdkMediaFormat.cpp
index 923453a..a95e874 100644
--- a/media/ndk/NdkMediaFormat.cpp
+++ b/media/ndk/NdkMediaFormat.cpp
@@ -147,38 +147,80 @@
EXPORT
bool AMediaFormat_getInt32(AMediaFormat* format, const char *name, int32_t *out) {
+ if (format == nullptr) {
+ return false;
+ }
+ if (name == nullptr) {
+ return false;
+ }
return format->mFormat->findInt32(name, out);
}
EXPORT
bool AMediaFormat_getInt64(AMediaFormat* format, const char *name, int64_t *out) {
+ if (format == nullptr) {
+ return false;
+ }
+ if (name == nullptr) {
+ return false;
+ }
return format->mFormat->findInt64(name, out);
}
EXPORT
bool AMediaFormat_getFloat(AMediaFormat* format, const char *name, float *out) {
+ if (format == nullptr) {
+ return false;
+ }
+ if (name == nullptr) {
+ return false;
+ }
return format->mFormat->findFloat(name, out);
}
EXPORT
bool AMediaFormat_getDouble(AMediaFormat* format, const char *name, double *out) {
+ if (format == nullptr) {
+ return false;
+ }
+ if (name == nullptr) {
+ return false;
+ }
return format->mFormat->findDouble(name, out);
}
EXPORT
bool AMediaFormat_getSize(AMediaFormat* format, const char *name, size_t *out) {
+ if (format == nullptr) {
+ return false;
+ }
+ if (name == nullptr) {
+ return false;
+ }
return format->mFormat->findSize(name, out);
}
EXPORT
bool AMediaFormat_getRect(AMediaFormat* format, const char *name,
int32_t *left, int32_t *top, int32_t *right, int32_t *bottom) {
+ if (format == nullptr) {
+ return false;
+ }
+ if (name == nullptr) {
+ return false;
+ }
return format->mFormat->findRect(name, left, top, right, bottom);
}
EXPORT
bool AMediaFormat_getBuffer(AMediaFormat* format, const char *name, void** data, size_t *outsize) {
sp<ABuffer> buf;
+ if (format == nullptr) {
+ return false;
+ }
+ if (name == nullptr) {
+ return false;
+ }
if (format->mFormat->findBuffer(name, &buf)) {
*data = buf->data() + buf->offset();
*outsize = buf->size();
@@ -189,7 +231,12 @@
EXPORT
bool AMediaFormat_getString(AMediaFormat* mData, const char *name, const char **out) {
-
+ if (mData == nullptr) {
+ return false;
+ }
+ if (name == nullptr) {
+ return false;
+ }
for (size_t i = 0; i < mData->mStringCache.size(); i++) {
if (strcmp(mData->mStringCache.keyAt(i).string(), name) == 0) {
mData->mStringCache.removeItemsAt(i, 1);
@@ -212,43 +259,91 @@
EXPORT
void AMediaFormat_setInt32(AMediaFormat* format, const char *name, int32_t value) {
+ if (format == nullptr) {
+ return;
+ }
+ if (name == nullptr) {
+ return;
+ }
format->mFormat->setInt32(name, value);
}
EXPORT
void AMediaFormat_setInt64(AMediaFormat* format, const char *name, int64_t value) {
+ if (format == nullptr) {
+ return;
+ }
+ if (name == nullptr) {
+ return;
+ }
format->mFormat->setInt64(name, value);
}
EXPORT
void AMediaFormat_setFloat(AMediaFormat* format, const char* name, float value) {
+ if (format == nullptr) {
+ return;
+ }
+ if (name == nullptr) {
+ return;
+ }
format->mFormat->setFloat(name, value);
}
EXPORT
void AMediaFormat_setDouble(AMediaFormat* format, const char* name, double value) {
+ if (format == nullptr) {
+ return;
+ }
+ if (name == nullptr) {
+ return;
+ }
format->mFormat->setDouble(name, value);
}
EXPORT
void AMediaFormat_setSize(AMediaFormat* format, const char* name, size_t value) {
+ if (format == nullptr) {
+ return;
+ }
+ if (name == nullptr) {
+ return;
+ }
format->mFormat->setSize(name, value);
}
EXPORT
void AMediaFormat_setRect(AMediaFormat* format, const char *name,
int32_t left, int32_t top, int32_t right, int32_t bottom) {
+ if (format == nullptr) {
+ return;
+ }
+ if (name == nullptr) {
+ return;
+ }
format->mFormat->setRect(name, left, top, right, bottom);
}
EXPORT
void AMediaFormat_setString(AMediaFormat* format, const char* name, const char* value) {
+ if (format == nullptr) {
+ return;
+ }
+ if (name == nullptr) {
+ return;
+ }
// AMessage::setString() makes a copy of the string
format->mFormat->setString(name, value, strlen(value));
}
EXPORT
void AMediaFormat_setBuffer(AMediaFormat* format, const char* name, const void* data, size_t size) {
+ if (format == nullptr) {
+ return;
+ }
+ if (name == nullptr) {
+ return;
+ }
// the ABuffer(void*, size_t) constructor doesn't take ownership of the data, so create
// a new buffer and copy the data into it
sp<ABuffer> buf = new ABuffer(size);
diff --git a/media/ndk/NdkMediaMuxer.cpp b/media/ndk/NdkMediaMuxer.cpp
index 1965e62..9d62884 100644
--- a/media/ndk/NdkMediaMuxer.cpp
+++ b/media/ndk/NdkMediaMuxer.cpp
@@ -46,7 +46,7 @@
if (mData == nullptr) {
return nullptr;
}
- mData->mImpl = new (std::nothrow) MediaMuxer(fd, (android::MediaMuxer::OutputFormat)format);
+ mData->mImpl = MediaMuxer::create(fd, (MediaMuxer::OutputFormat)format);
if (mData->mImpl == nullptr) {
delete mData;
return nullptr;
diff --git a/media/ndk/include/media/NdkMediaDrm.h b/media/ndk/include/media/NdkMediaDrm.h
index 4eca3d7..8044140 100644
--- a/media/ndk/include/media/NdkMediaDrm.h
+++ b/media/ndk/include/media/NdkMediaDrm.h
@@ -261,8 +261,8 @@
/**
* Open a new session with the MediaDrm object. A session ID is returned.
*
- * Returns MEDIADRM_NOT_PROVISIONED_ERROR if provisioning is needed.
- * Returns MEDIADRM_RESOURCE_BUSY_ERROR if required resources are in use.
+ * Returns AMEDIA_DRM_NOT_PROVISIONED if provisioning is needed.
+ * Returns AMEDIA_DRM_RESOURCE_BUSY if required resources are in use.
*
* Available since API level 21.
*/
@@ -327,7 +327,7 @@
* 2. keyRequestSize will be set to the size of the request
* If this does not return AMEDIA_OK, value of these parameters should not be used.
*
- * Returns MEDIADRM_NOT_PROVISIONED_ERROR if reprovisioning is needed, due to a
+ * Returns AMEDIA_DRM_NOT_PROVISIONED if reprovisioning is needed, due to a
* problem with the device certificate.
*
* Available since API level 21.
@@ -390,7 +390,7 @@
* 4. keyRequestType will be set to the key request type. Passing in NULL means
* you don't need it to be reported.
*
- * Returns MEDIADRM_NOT_PROVISIONED_ERROR if reprovisioning is needed, due to a
+ * Returns AMEDIA_DRM_NOT_PROVISIONED if reprovisioning is needed, due to a
* problem with the device certificate.
*
* Available since API level 33.
@@ -457,7 +457,7 @@
* On entry, numPairs should be set by the caller to the maximum number of pairs
* that can be returned (the size of the array). On exit, numPairs will be set
* to the number of entries written to the array. If the number of {key, value} pairs
- * to be returned is greater than *numPairs, MEDIADRM_SHORT_BUFFER will be returned
+ * to be returned is greater than *numPairs, AMEDIA_DRM_SHORT_BUFFER will be returned
* and numPairs will be set to the number of pairs available.
*
* Available since API level 21.
@@ -495,7 +495,7 @@
* DRM engine plugin.
* responseSize is the length of the provisioning response in bytes.
*
- * Returns MEDIADRM_DEVICE_REVOKED_ERROR if the response indicates that the
+ * Returns AMEDIA_DRM_DEVICE_REVOKED if the response indicates that the
* server rejected the request
*
* Available since API level 21.
@@ -522,7 +522,7 @@
* numSecureStops is set by the caller to the maximum number of secure stops to
* return. On exit, *numSecureStops will be set to the number actually returned.
* If *numSecureStops is too small for the number of secure stops available,
- * MEDIADRM_SHORT_BUFFER will be returned and *numSecureStops will be set to the
+ * AMEDIA_DRM_SHORT_BUFFER will be returned and *numSecureStops will be set to the
* number required.
*
* Available since API level 21.
@@ -657,7 +657,7 @@
* Generate a signature using the specified macAlgorithm over the message data
* referenced by message of size messageSize and store the signature in the
* buffer referenced signature of max size *signatureSize. If the buffer is not
- * large enough to hold the signature, MEDIADRM_SHORT_BUFFER is returned and
+ * large enough to hold the signature, AMEDIA_DRM_SHORT_BUFFER is returned and
* *signatureSize is set to the buffer size required. The key to use is identified
* by the 16 byte keyId. The key must have been loaded into the session using
* provideKeyResponse.
@@ -670,7 +670,7 @@
/*
* Perform a signature verification using the specified macAlgorithm over the message
- * data referenced by the message parameter of size messageSize. Returns MEDIADRM_OK
+ * data referenced by the message parameter of size messageSize. Returns AMEDIA_OK
* if the signature matches, otherwise MEDAIDRM_VERIFY_FAILED is returned. The key to
* use is identified by the 16 byte keyId. The key must have been loaded into the
* session using provideKeyResponse.
diff --git a/media/ndk/tests/NdkMediaFormat_test.cpp b/media/ndk/tests/NdkMediaFormat_test.cpp
index 668d0a4..18690b8 100644
--- a/media/ndk/tests/NdkMediaFormat_test.cpp
+++ b/media/ndk/tests/NdkMediaFormat_test.cpp
@@ -51,6 +51,13 @@
EXPECT_FALSE(AMediaFormat_getInt64(fmt1, "five", &i64));
EXPECT_EQ(i32, 5);
+ // verify detecting some bad parameters.
+ AMediaFormat_setInt32(nullptr, "whatever", 6);
+ AMediaFormat_setInt32(fmt1, nullptr, 6);
+
+ EXPECT_FALSE(AMediaFormat_getInt32(nullptr, "whatever", &i32));
+ EXPECT_FALSE(AMediaFormat_getInt32(fmt1, nullptr, &i32));
+
AMediaFormat_delete(fmt1);
}
@@ -67,6 +74,13 @@
EXPECT_FALSE(AMediaFormat_getInt64(fmt1, "five", &i64));
EXPECT_EQ(i64, -1);
+ // verify detecting some bad parameters.
+ AMediaFormat_setInt64(nullptr, "whatever", 6);
+ AMediaFormat_setInt64(fmt1, nullptr, 6);
+
+ EXPECT_FALSE(AMediaFormat_getInt64(nullptr, "whatever", &i64));
+ EXPECT_FALSE(AMediaFormat_getInt64(fmt1, nullptr, &i64));
+
AMediaFormat_delete(fmt1);
}
@@ -80,6 +94,13 @@
EXPECT_TRUE(AMediaFormat_getSize(fmt1, "medium", &size));
EXPECT_EQ(size, 10);
+ // verify detecting some bad parameters.
+ AMediaFormat_setSize(nullptr, "whatever", 6);
+ AMediaFormat_setSize(fmt1, nullptr, 6);
+
+ EXPECT_FALSE(AMediaFormat_getSize(nullptr, "whatever", &size));
+ EXPECT_FALSE(AMediaFormat_getSize(fmt1, nullptr, &size));
+
AMediaFormat_delete(fmt1);
}
@@ -90,6 +111,14 @@
AMediaFormat_setFloat(fmt1, "ship", 0.5);
EXPECT_TRUE(AMediaFormat_getFloat(fmt1, "boat", &f));
EXPECT_EQ(f, 1.5);
+
+ // verify detecting some bad parameters.
+ AMediaFormat_setFloat(nullptr, "whatever", 1.5);
+ AMediaFormat_setFloat(fmt1, nullptr, 1.5);
+
+ EXPECT_FALSE(AMediaFormat_getFloat(nullptr, "whatever", &f));
+ EXPECT_FALSE(AMediaFormat_getFloat(fmt1, nullptr, &f));
+
AMediaFormat_delete(fmt1);
}
@@ -100,6 +129,14 @@
AMediaFormat_setDouble(fmt1, "dip", 0.5);
EXPECT_TRUE(AMediaFormat_getDouble(fmt1, "trouble", &d));
EXPECT_EQ(d, 100.5);
+
+ // verify detecting some bad parameters.
+ AMediaFormat_setDouble(nullptr, "whatever", 1.5);
+ AMediaFormat_setDouble(fmt1, nullptr, 1.5);
+
+ EXPECT_FALSE(AMediaFormat_getDouble(nullptr, "whatever", &d));
+ EXPECT_FALSE(AMediaFormat_getDouble(fmt1, nullptr, &d));
+
AMediaFormat_delete(fmt1);
}
@@ -111,8 +148,16 @@
AMediaFormat_setString(fmt1, "stringtheory", content);
EXPECT_TRUE(AMediaFormat_getString(fmt1, "stringtheory", &out));
EXPECT_NE(out, nullptr);
+ EXPECT_NE(out, content); // should not be the original
EXPECT_EQ(strcmp(out,content), 0);
+ // verify detecting some bad parameters.
+ AMediaFormat_setString(nullptr, "whatever", content);
+ AMediaFormat_setString(fmt1, nullptr, content);
+
+ EXPECT_FALSE(AMediaFormat_getString(nullptr, "whatever", &out));
+ EXPECT_FALSE(AMediaFormat_getString(fmt1, nullptr, &out));
+
AMediaFormat_delete(fmt1);
}
diff --git a/media/tests/benchmark/MediaBenchmarkTest/src/androidTest/java/com/android/media/benchmark/tests/MuxerTest.java b/media/tests/benchmark/MediaBenchmarkTest/src/androidTest/java/com/android/media/benchmark/tests/MuxerTest.java
index 21ba957..7fd2752 100644
--- a/media/tests/benchmark/MediaBenchmarkTest/src/androidTest/java/com/android/media/benchmark/tests/MuxerTest.java
+++ b/media/tests/benchmark/MediaBenchmarkTest/src/androidTest/java/com/android/media/benchmark/tests/MuxerTest.java
@@ -60,14 +60,12 @@
private static final String mStatsFile =
mContext.getExternalFilesDir(null) + "/Muxer." + System.currentTimeMillis() + ".csv";
private static final String TAG = "MuxerTest";
- private static final Map<String, Integer> mMapFormat = new Hashtable<String, Integer>() {
- {
- put("mp4", MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
- put("webm", MediaMuxer.OutputFormat.MUXER_OUTPUT_WEBM);
- put("3gpp", MediaMuxer.OutputFormat.MUXER_OUTPUT_3GPP);
- put("ogg", MediaMuxer.OutputFormat.MUXER_OUTPUT_OGG);
- }
- };
+ private static final Map<String, Integer> mMapFormat = Map.of(
+ "mp4", MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4,
+ "webm", MediaMuxer.OutputFormat.MUXER_OUTPUT_WEBM,
+ "3gpp", MediaMuxer.OutputFormat.MUXER_OUTPUT_3GPP,
+ "ogg", MediaMuxer.OutputFormat.MUXER_OUTPUT_OGG);
+
private String mInputFileName;
private String mFormat;
diff --git a/media/tests/benchmark/MediaBenchmarkTest/src/main/cpp/NativeDecoder.cpp b/media/tests/benchmark/MediaBenchmarkTest/src/main/cpp/NativeDecoder.cpp
index 043bc9e..a0628fa 100644
--- a/media/tests/benchmark/MediaBenchmarkTest/src/main/cpp/NativeDecoder.cpp
+++ b/media/tests/benchmark/MediaBenchmarkTest/src/main/cpp/NativeDecoder.cpp
@@ -19,6 +19,7 @@
#include <jni.h>
#include <fstream>
+#include <memory>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
@@ -42,7 +43,7 @@
return -1;
}
- Decoder *decoder = new Decoder();
+ std::unique_ptr<Decoder> decoder(new (std::nothrow) Decoder());
Extractor *extractor = decoder->getExtractor();
if (!extractor) {
ALOGE("Extractor creation failed");
@@ -125,6 +126,5 @@
inputFp = nullptr;
}
extractor->deInitExtractor();
- delete decoder;
return 0;
}
diff --git a/media/tests/benchmark/MediaBenchmarkTest/src/main/cpp/NativeMuxer.cpp b/media/tests/benchmark/MediaBenchmarkTest/src/main/cpp/NativeMuxer.cpp
index a5ef5b8..a297526 100644
--- a/media/tests/benchmark/MediaBenchmarkTest/src/main/cpp/NativeMuxer.cpp
+++ b/media/tests/benchmark/MediaBenchmarkTest/src/main/cpp/NativeMuxer.cpp
@@ -19,6 +19,7 @@
#include <jni.h>
#include <fstream>
+#include <memory>
#include <string>
#include <sys/stat.h>
@@ -47,7 +48,7 @@
return MUXER_OUTPUT_FORMAT_INVALID;
}
- Muxer *muxerObj = new Muxer();
+ std::unique_ptr<Muxer> muxerObj(new (std::nothrow) Muxer());
Extractor *extractor = muxerObj->getExtractor();
if (!extractor) {
ALOGE("Extractor creation failed");
@@ -159,7 +160,6 @@
}
env->ReleaseStringUTFChars(jFormat, fmt);
extractor->deInitExtractor();
- delete muxerObj;
return 0;
}
diff --git a/media/tests/benchmark/src/native/common/BenchmarkCommon.h b/media/tests/benchmark/src/native/common/BenchmarkCommon.h
index 40a8c9e..ba3e81a 100644
--- a/media/tests/benchmark/src/native/common/BenchmarkCommon.h
+++ b/media/tests/benchmark/src/native/common/BenchmarkCommon.h
@@ -50,7 +50,7 @@
{
lock_guard<mutex> lock(mMutex);
needsNotify = mQueue.empty();
- mQueue.push(move(elem));
+ mQueue.push(std::move(elem));
}
if (needsNotify) mQueueNotEmptyCondition.notify_one();
}
diff --git a/media/tests/benchmark/src/native/encoder/C2Encoder.cpp b/media/tests/benchmark/src/native/encoder/C2Encoder.cpp
index ca79881..5b7a471 100644
--- a/media/tests/benchmark/src/native/encoder/C2Encoder.cpp
+++ b/media/tests/benchmark/src/native/encoder/C2Encoder.cpp
@@ -17,11 +17,13 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "C2Encoder"
+#include <memory>
+
#include "C2Encoder.h"
int32_t C2Encoder::createCodec2Component(string compName, AMediaFormat *format) {
ALOGV("In %s", __func__);
- mListener.reset(new CodecListener(
+ mListener.reset(new (std::nothrow) CodecListener(
[this](std::list<std::unique_ptr<C2Work>> &workItems) { handleWorkDone(workItems); }));
if (!mListener) return -1;
@@ -125,7 +127,7 @@
}
int32_t numFrames = (inputBufferSize + frameSize - 1) / frameSize;
// Temporary buffer to read data from the input file
- char *data = (char *)malloc(frameSize);
+ std::unique_ptr<char[]> data(new (std::nothrow) char[frameSize]);
if (!data) {
ALOGE("Insufficient memory to read from input file");
return -1;
@@ -169,7 +171,7 @@
if (inputBufferSize - offset < frameSize) {
frameSize = inputBufferSize - offset;
}
- eleStream.read(data, frameSize);
+ eleStream.read(data.get(), frameSize);
if (eleStream.gcount() != frameSize) {
ALOGE("read() from file failed. Incorrect bytes read");
return -1;
@@ -191,8 +193,8 @@
return view.error();
}
- memcpy(view.base(), data, frameSize);
- work->input.buffers.emplace_back(new LinearBuffer(block));
+ memcpy(view.base(), data.get(), frameSize);
+ work->input.buffers.emplace_back(new (std::nothrow) LinearBuffer(block));
} else {
std::shared_ptr<C2GraphicBlock> block;
status = mGraphicPool->fetchGraphicBlock(
@@ -211,16 +213,16 @@
uint8_t *pY = view.data()[C2PlanarLayout::PLANE_Y];
uint8_t *pU = view.data()[C2PlanarLayout::PLANE_U];
uint8_t *pV = view.data()[C2PlanarLayout::PLANE_V];
- memcpy(pY, data, mWidth * mHeight);
- memcpy(pU, data + mWidth * mHeight, (mWidth * mHeight >> 2));
- memcpy(pV, data + (mWidth * mHeight * 5 >> 2), mWidth * mHeight >> 2);
- work->input.buffers.emplace_back(new GraphicBuffer(block));
+ memcpy(pY, data.get(), mWidth * mHeight);
+ memcpy(pU, data.get() + mWidth * mHeight, (mWidth * mHeight >> 2));
+ memcpy(pV, data.get() + (mWidth * mHeight * 5 >> 2), mWidth * mHeight >> 2);
+ work->input.buffers.emplace_back(new (std::nothrow) GraphicBuffer(block));
}
mStats->addFrameSize(frameSize);
}
work->worklets.clear();
- work->worklets.emplace_back(new C2Worklet);
+ work->worklets.emplace_back(new (std::nothrow) C2Worklet);
std::list<std::unique_ptr<C2Work>> items;
items.push_back(std::move(work));
@@ -234,7 +236,6 @@
numFrames--;
mNumInputFrame++;
}
- free(data);
return status;
}
diff --git a/media/tests/benchmark/tests/C2DecoderTest.cpp b/media/tests/benchmark/tests/C2DecoderTest.cpp
index 85dcbc1..6e4d9e1 100644
--- a/media/tests/benchmark/tests/C2DecoderTest.cpp
+++ b/media/tests/benchmark/tests/C2DecoderTest.cpp
@@ -20,6 +20,7 @@
#include <fstream>
#include <iostream>
#include <limits>
+#include <memory>
#include "BenchmarkTestEnvironment.h"
#include "C2Decoder.h"
@@ -50,7 +51,7 @@
};
void C2DecoderTest::setupC2DecoderTest() {
- mDecoder = new C2Decoder();
+ mDecoder = new (std::nothrow) C2Decoder();
ASSERT_NE(mDecoder, nullptr) << "C2Decoder creation failed";
int32_t status = mDecoder->setupCodec2();
@@ -66,7 +67,7 @@
FILE *inputFp = fopen(inputFile.c_str(), "rb");
ASSERT_NE(inputFp, nullptr) << "Unable to open " << inputFile << " file for reading";
- Extractor *extractor = new Extractor();
+ std::unique_ptr<Extractor> extractor(new (std::nothrow) Extractor());
ASSERT_NE(extractor, nullptr) << "Extractor creation failed";
// Read file properties
@@ -85,7 +86,7 @@
int32_t status = extractor->setupTrackFormat(curTrack);
ASSERT_EQ(status, 0) << "Track Format invalid";
- uint8_t *inputBuffer = (uint8_t *)malloc(fileSize);
+ std::unique_ptr<uint8_t[]> inputBuffer(new (std::nothrow) uint8_t[fileSize]);
ASSERT_NE(inputBuffer, nullptr) << "Insufficient memory";
vector<AMediaCodecBufferInfo> frameInfo;
@@ -100,7 +101,7 @@
// copy the meta data and buffer to be passed to decoder
ASSERT_LE(inputBufferOffset + info.size, fileSize) << "Memory allocated not sufficient";
- memcpy(inputBuffer + inputBufferOffset, csdBuffer, info.size);
+ memcpy(inputBuffer.get() + inputBufferOffset, csdBuffer, info.size);
frameInfo.push_back(info);
inputBufferOffset += info.size;
idx++;
@@ -113,7 +114,7 @@
// copy the meta data and buffer to be passed to decoder
ASSERT_LE(inputBufferOffset + info.size, fileSize) << "Memory allocated not sufficient";
- memcpy(inputBuffer + inputBufferOffset, extractor->getFrameBuf(), info.size);
+ memcpy(inputBuffer.get() + inputBufferOffset, extractor->getFrameBuf(), info.size);
frameInfo.push_back(info);
inputBufferOffset += info.size;
}
@@ -127,7 +128,7 @@
ASSERT_EQ(status, 0) << "Create component failed for " << codecName;
// Send the inputs to C2 Decoder and wait till all buffers are returned.
- status = mDecoder->decodeFrames(inputBuffer, frameInfo);
+ status = mDecoder->decodeFrames(inputBuffer.get(), frameInfo);
ASSERT_EQ(status, 0) << "Decoder failed for " << codecName;
mDecoder->waitOnInputConsumption();
@@ -141,10 +142,8 @@
mDecoder->resetDecoder();
}
}
- free(inputBuffer);
fclose(inputFp);
extractor->deInitExtractor();
- delete extractor;
delete mDecoder;
mDecoder = nullptr;
}
@@ -174,7 +173,7 @@
make_pair("crowd_1920x1080_25fps_4000kbps_h265.mkv", "hevc")));
int main(int argc, char **argv) {
- gEnv = new BenchmarkTestEnvironment();
+ gEnv = new (std::nothrow) BenchmarkTestEnvironment();
::testing::AddGlobalTestEnvironment(gEnv);
::testing::InitGoogleTest(&argc, argv);
int status = gEnv->initFromOptions(argc, argv);
diff --git a/media/tests/benchmark/tests/C2EncoderTest.cpp b/media/tests/benchmark/tests/C2EncoderTest.cpp
index b18d856..dfbe496 100644
--- a/media/tests/benchmark/tests/C2EncoderTest.cpp
+++ b/media/tests/benchmark/tests/C2EncoderTest.cpp
@@ -20,6 +20,7 @@
#include <fstream>
#include <iostream>
#include <limits>
+#include <memory>
#include "BenchmarkTestEnvironment.h"
#include "C2Encoder.h"
@@ -50,7 +51,7 @@
};
void C2EncoderTest::setupC2EncoderTest() {
- mEncoder = new C2Encoder();
+ mEncoder = new (std::nothrow) C2Encoder();
ASSERT_NE(mEncoder, nullptr) << "C2Encoder creation failed";
int32_t status = mEncoder->setupCodec2();
@@ -66,7 +67,7 @@
FILE *inputFp = fopen(inputFile.c_str(), "rb");
ASSERT_NE(inputFp, nullptr) << "Unable to open input file for reading";
- Decoder *decoder = new Decoder();
+ std::unique_ptr<Decoder> decoder(new (std::nothrow) Decoder());
ASSERT_NE(decoder, nullptr) << "Decoder creation failed";
Extractor *extractor = decoder->getExtractor();
@@ -88,7 +89,7 @@
int32_t status = extractor->setupTrackFormat(curTrack);
ASSERT_EQ(status, 0) << "Track Format invalid";
- uint8_t *inputBuffer = (uint8_t *)malloc(fileSize);
+ std::unique_ptr<uint8_t[]> inputBuffer(new (std::nothrow) uint8_t[fileSize]);
ASSERT_NE(inputBuffer, nullptr) << "Insufficient memory";
vector<AMediaCodecBufferInfo> frameInfo;
@@ -102,7 +103,7 @@
// copy the meta data and buffer to be passed to decoder
ASSERT_LE(inputBufferOffset + info.size, fileSize) << "Memory allocated not sufficient";
- memcpy(inputBuffer + inputBufferOffset, extractor->getFrameBuf(), info.size);
+ memcpy(inputBuffer.get() + inputBufferOffset, extractor->getFrameBuf(), info.size);
frameInfo.push_back(info);
inputBufferOffset += info.size;
}
@@ -114,7 +115,8 @@
<< " for dumping decoder's output";
decoder->setupDecoder();
- status = decoder->decode(inputBuffer, frameInfo, decName, false /*asyncMode */, outFp);
+ status = decoder->decode(inputBuffer.get(), frameInfo, decName,
+ false /*asyncMode */, outFp);
ASSERT_EQ(status, AMEDIA_OK) << "Decode returned error : " << status;
// Encode the given input stream for all C2 codecs supported by device
@@ -149,11 +151,9 @@
// Destroy the decoder for the given input
decoder->deInitCodec();
decoder->resetDecoder();
- free(inputBuffer);
}
fclose(inputFp);
extractor->deInitExtractor();
- delete decoder;
delete mEncoder;
mEncoder = nullptr;
}
@@ -176,7 +176,7 @@
make_pair("crowd_1920x1080_25fps_4000kbps_h265.mkv", "hevc")));
int main(int argc, char **argv) {
- gEnv = new BenchmarkTestEnvironment();
+ gEnv = new (std::nothrow) BenchmarkTestEnvironment();
::testing::AddGlobalTestEnvironment(gEnv);
::testing::InitGoogleTest(&argc, argv);
int status = gEnv->initFromOptions(argc, argv);
diff --git a/media/tests/benchmark/tests/DecoderTest.cpp b/media/tests/benchmark/tests/DecoderTest.cpp
index 3666724..b363df3 100644
--- a/media/tests/benchmark/tests/DecoderTest.cpp
+++ b/media/tests/benchmark/tests/DecoderTest.cpp
@@ -20,6 +20,7 @@
#include <fstream>
#include <iostream>
#include <limits>
+#include <memory>
#include <android/binder_process.h>
@@ -38,7 +39,7 @@
FILE *inputFp = fopen(inputFile.c_str(), "rb");
ASSERT_NE(inputFp, nullptr) << "Unable to open " << inputFile << " file for reading";
- Decoder *decoder = new Decoder();
+ std::unique_ptr<Decoder> decoder(new (std::nothrow) Decoder());
ASSERT_NE(decoder, nullptr) << "Decoder creation failed";
Extractor *extractor = decoder->getExtractor();
@@ -57,7 +58,7 @@
int32_t status = extractor->setupTrackFormat(curTrack);
ASSERT_EQ(status, 0) << "Track Format invalid";
- uint8_t *inputBuffer = (uint8_t *)malloc(kMaxBufferSize);
+ std::unique_ptr<uint8_t[]> inputBuffer(new (std::nothrow) uint8_t[kMaxBufferSize]);
ASSERT_NE(inputBuffer, nullptr) << "Insufficient memory";
vector<AMediaCodecBufferInfo> frameInfo;
@@ -72,7 +73,7 @@
ASSERT_LE(inputBufferOffset + info.size, kMaxBufferSize)
<< "Memory allocated not sufficient";
- memcpy(inputBuffer + inputBufferOffset, extractor->getFrameBuf(), info.size);
+ memcpy(inputBuffer.get() + inputBufferOffset, extractor->getFrameBuf(), info.size);
frameInfo.push_back(info);
inputBufferOffset += info.size;
}
@@ -80,7 +81,7 @@
string codecName = get<1>(params);
bool asyncMode = get<2>(params);
decoder->setupDecoder();
- status = decoder->decode(inputBuffer, frameInfo, codecName, asyncMode);
+ status = decoder->decode(inputBuffer.get(), frameInfo, codecName, asyncMode);
ASSERT_EQ(status, AMEDIA_OK) << "Decoder failed for " << codecName;
decoder->deInitCodec();
@@ -88,12 +89,10 @@
string inputReference = get<0>(params);
decoder->dumpStatistics(inputReference, codecName, (asyncMode ? "async" : "sync"),
gEnv->getStatsFile());
- free(inputBuffer);
decoder->resetDecoder();
}
fclose(inputFp);
extractor->deInitExtractor();
- delete decoder;
}
// TODO: (b/140549596)
@@ -178,7 +177,7 @@
int main(int argc, char **argv) {
ABinderProcess_startThreadPool();
- gEnv = new BenchmarkTestEnvironment();
+ gEnv = new (std::nothrow) BenchmarkTestEnvironment();
::testing::AddGlobalTestEnvironment(gEnv);
::testing::InitGoogleTest(&argc, argv);
int status = gEnv->initFromOptions(argc, argv);
@@ -190,4 +189,4 @@
ALOGV("Decoder Test result = %d\n", status);
}
return status;
-}
\ No newline at end of file
+}
diff --git a/media/tests/benchmark/tests/EncoderTest.cpp b/media/tests/benchmark/tests/EncoderTest.cpp
index 7e1681d..6703b99 100644
--- a/media/tests/benchmark/tests/EncoderTest.cpp
+++ b/media/tests/benchmark/tests/EncoderTest.cpp
@@ -18,6 +18,7 @@
#define LOG_TAG "encoderTest"
#include <fstream>
+#include <memory>
#include "BenchmarkTestEnvironment.h"
#include "Decoder.h"
@@ -39,7 +40,7 @@
FILE *inputFp = fopen(inputFile.c_str(), "rb");
ASSERT_NE(inputFp, nullptr) << "Unable to open " << inputFile << " file for reading";
- Decoder *decoder = new Decoder();
+ std::unique_ptr<Decoder> decoder(new (std::nothrow) Decoder());
ASSERT_NE(decoder, nullptr) << "Decoder creation failed";
Extractor *extractor = decoder->getExtractor();
@@ -54,14 +55,14 @@
int32_t trackCount = extractor->initExtractor(fd, fileSize);
ASSERT_GT(trackCount, 0) << "initExtractor failed";
- Encoder *encoder = new Encoder();
+ std::unique_ptr<Encoder> encoder(new (std::nothrow) Encoder());
ASSERT_NE(encoder, nullptr) << "Decoder creation failed";
for (int curTrack = 0; curTrack < trackCount; curTrack++) {
int32_t status = extractor->setupTrackFormat(curTrack);
ASSERT_EQ(status, 0) << "Track Format invalid";
- uint8_t *inputBuffer = (uint8_t *)malloc(kMaxBufferSize);
+ std::unique_ptr<uint8_t[]> inputBuffer(new (std::nothrow) uint8_t[kMaxBufferSize]);
ASSERT_NE(inputBuffer, nullptr) << "Insufficient memory";
vector<AMediaCodecBufferInfo> frameInfo;
@@ -76,7 +77,7 @@
ASSERT_LE(inputBufferOffset + info.size, kMaxBufferSize)
<< "Memory allocated not sufficient";
- memcpy(inputBuffer + inputBufferOffset, extractor->getFrameBuf(), info.size);
+ memcpy(inputBuffer.get() + inputBufferOffset, extractor->getFrameBuf(), info.size);
frameInfo.push_back(info);
inputBufferOffset += info.size;
}
@@ -88,7 +89,7 @@
<< " for dumping decoder's output";
decoder->setupDecoder();
- status = decoder->decode(inputBuffer, frameInfo, decName, false /*asyncMode */, outFp);
+ status = decoder->decode(inputBuffer.get(), frameInfo, decName, false /*asyncMode */, outFp);
ASSERT_EQ(status, AMEDIA_OK) << "Decode returned error : " << status;
AMediaFormat *decoderFormat = decoder->getFormat();
@@ -154,13 +155,10 @@
}
encoder->resetEncoder();
decoder->deInitCodec();
- free(inputBuffer);
decoder->resetDecoder();
}
- delete encoder;
fclose(inputFp);
extractor->deInitExtractor();
- delete decoder;
}
INSTANTIATE_TEST_SUITE_P(
@@ -220,7 +218,7 @@
"c2.android.hevc.encoder", true)));
int main(int argc, char **argv) {
- gEnv = new BenchmarkTestEnvironment();
+ gEnv = new (std::nothrow) BenchmarkTestEnvironment();
::testing::AddGlobalTestEnvironment(gEnv);
::testing::InitGoogleTest(&argc, argv);
int status = gEnv->initFromOptions(argc, argv);
diff --git a/media/tests/benchmark/tests/ExtractorTest.cpp b/media/tests/benchmark/tests/ExtractorTest.cpp
index 27ee9ba..35fb465 100644
--- a/media/tests/benchmark/tests/ExtractorTest.cpp
+++ b/media/tests/benchmark/tests/ExtractorTest.cpp
@@ -17,6 +17,8 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "extractorTest"
+#include <memory>
+
#include <gtest/gtest.h>
#include <android/binder_process.h>
@@ -29,7 +31,7 @@
class ExtractorTest : public ::testing::TestWithParam<pair<string, int32_t>> {};
TEST_P(ExtractorTest, Extract) {
- Extractor *extractObj = new Extractor();
+ std::unique_ptr<Extractor> extractObj(new (std::nothrow) Extractor());
ASSERT_NE(extractObj, nullptr) << "Extractor creation failed";
string inputFile = gEnv->getRes() + GetParam().first;
@@ -53,7 +55,6 @@
extractObj->dumpStatistics(GetParam().first, "", gEnv->getStatsFile());
fclose(inputFp);
- delete extractObj;
}
INSTANTIATE_TEST_SUITE_P(ExtractorTestAll, ExtractorTest,
@@ -76,7 +77,7 @@
int main(int argc, char **argv) {
ABinderProcess_startThreadPool();
- gEnv = new BenchmarkTestEnvironment();
+ gEnv = new (std::nothrow) BenchmarkTestEnvironment();
::testing::AddGlobalTestEnvironment(gEnv);
::testing::InitGoogleTest(&argc, argv);
int status = gEnv->initFromOptions(argc, argv);
diff --git a/media/tests/benchmark/tests/MuxerTest.cpp b/media/tests/benchmark/tests/MuxerTest.cpp
index 991644b..65a3df4 100644
--- a/media/tests/benchmark/tests/MuxerTest.cpp
+++ b/media/tests/benchmark/tests/MuxerTest.cpp
@@ -20,6 +20,7 @@
#include <fstream>
#include <iostream>
+#include <memory>
#include "BenchmarkTestEnvironment.h"
#include "Muxer.h"
@@ -59,7 +60,7 @@
MUXER_OUTPUT_T outputFormat = getMuxerOutFormat(fmt);
ASSERT_NE(outputFormat, MUXER_OUTPUT_FORMAT_INVALID) << "Invalid muxer output format";
- Muxer *muxerObj = new Muxer();
+ std::unique_ptr<Muxer> muxerObj(new (std::nothrow) Muxer());
ASSERT_NE(muxerObj, nullptr) << "Muxer creation failed";
Extractor *extractor = muxerObj->getExtractor();
@@ -78,7 +79,7 @@
int32_t status = extractor->setupTrackFormat(curTrack);
ASSERT_EQ(status, 0) << "Track Format invalid";
- uint8_t *inputBuffer = (uint8_t *)malloc(kMaxBufferSize);
+ std::unique_ptr<uint8_t[]> inputBuffer(new (std::nothrow) uint8_t[kMaxBufferSize]);
ASSERT_NE(inputBuffer, nullptr) << "Insufficient memory";
// AMediaCodecBufferInfo : <size of frame> <flags> <presentationTimeUs> <offset>
@@ -94,7 +95,7 @@
ASSERT_LE(inputBufferOffset + info.size, kMaxBufferSize)
<< "Memory allocated not sufficient";
- memcpy(inputBuffer + inputBufferOffset, extractor->getFrameBuf(), info.size);
+ memcpy(inputBuffer.get() + inputBufferOffset, extractor->getFrameBuf(), info.size);
info.offset = inputBufferOffset;
frameInfos.push_back(info);
inputBufferOffset += info.size;
@@ -109,18 +110,16 @@
status = muxerObj->initMuxer(fd, outputFormat);
ASSERT_EQ(status, 0) << "initMuxer failed";
- status = muxerObj->mux(inputBuffer, frameInfos);
+ status = muxerObj->mux(inputBuffer.get(), frameInfos);
ASSERT_EQ(status, 0) << "Mux failed";
muxerObj->deInitMuxer();
muxerObj->dumpStatistics(GetParam().first + "." + fmt.c_str(), fmt, gEnv->getStatsFile());
- free(inputBuffer);
fclose(outputFp);
muxerObj->resetMuxer();
}
fclose(inputFp);
extractor->deInitExtractor();
- delete muxerObj;
}
INSTANTIATE_TEST_SUITE_P(
@@ -146,7 +145,7 @@
make_pair("bbb_16000hz_1ch_9kbps_amrwb_5mins.3gp", "3gpp")));
int main(int argc, char **argv) {
- gEnv = new BenchmarkTestEnvironment();
+ gEnv = new (std::nothrow) BenchmarkTestEnvironment();
::testing::AddGlobalTestEnvironment(gEnv);
::testing::InitGoogleTest(&argc, argv);
int status = gEnv->initFromOptions(argc, argv);
diff --git a/media/utils/MemoryLeakTrackUtil.cpp b/media/utils/MemoryLeakTrackUtil.cpp
index fdb8c4f..7451033 100644
--- a/media/utils/MemoryLeakTrackUtil.cpp
+++ b/media/utils/MemoryLeakTrackUtil.cpp
@@ -33,10 +33,8 @@
#define ABI_STRING "arm"
#elif defined(__aarch64__)
#define ABI_STRING "arm64"
-#elif defined(__mips__) && !defined(__LP64__)
-#define ABI_STRING "mips"
-#elif defined(__mips__) && defined(__LP64__)
-#define ABI_STRING "mips64"
+#elif defined(__riscv)
+#define ABI_STRING "riscv64"
#elif defined(__i386__)
#define ABI_STRING "x86"
#elif defined(__x86_64__)
diff --git a/media/utils/TimeCheck.cpp b/media/utils/TimeCheck.cpp
index 6823f4f..65b2c52 100644
--- a/media/utils/TimeCheck.cpp
+++ b/media/utils/TimeCheck.cpp
@@ -283,7 +283,7 @@
}
// Automatically create a TimeCheck class for a class and method.
-// This is used for Audio HIDL support.
+// This is used for Audio HAL support.
mediautils::TimeCheck makeTimeCheckStatsForClassMethod(
std::string_view className, std::string_view methodName) {
std::shared_ptr<MethodStatistics<std::string>> statistics =
diff --git a/media/utils/fuzzers/SchedulingPolicyServiceFuzz.cpp b/media/utils/fuzzers/SchedulingPolicyServiceFuzz.cpp
index 130feee..32fc3be 100644
--- a/media/utils/fuzzers/SchedulingPolicyServiceFuzz.cpp
+++ b/media/utils/fuzzers/SchedulingPolicyServiceFuzz.cpp
@@ -34,11 +34,16 @@
const sp<IServiceManager> sm(defaultServiceManager());
if (sm != nullptr) {
const String16 name("batterystats");
- batteryStatService = checked_interface_cast<IBatteryStats>(sm->checkService(name));
- if (batteryStatService == nullptr) {
+ sp<IBinder> obj = sm->checkService(name);
+ if (!obj) {
ALOGW("batterystats service unavailable!");
return nullptr;
}
+ batteryStatService = checked_interface_cast<IBatteryStats>(obj);
+ if (batteryStatService == nullptr) {
+ ALOGW("batterystats service interface is invalid");
+ return nullptr;
+ }
}
return batteryStatService;
}
diff --git a/media/utils/fuzzers/ServiceUtilitiesFuzz.cpp b/media/utils/fuzzers/ServiceUtilitiesFuzz.cpp
index 51e8d7a..15f043a 100644
--- a/media/utils/fuzzers/ServiceUtilitiesFuzz.cpp
+++ b/media/utils/fuzzers/ServiceUtilitiesFuzz.cpp
@@ -25,6 +25,7 @@
static constexpr int kMaxOperations = 50;
static constexpr int kMaxStringLen = 256;
+static constexpr int kMaxSpaces = 1000;
using android::content::AttributionSourceState;
@@ -35,7 +36,9 @@
pm.allowPlaybackCapture(uid);
},
[](FuzzedDataProvider* data_provider, android::MediaPackageManager pm) -> void {
- int spaces = data_provider->ConsumeIntegral<int>();
+ /* The large value of spaces was taking time in file write operation.
+ * Limited spaces values in range to avoid timeout.*/
+ int spaces = data_provider->ConsumeIntegralInRange<int>(0, kMaxSpaces);
// Dump everything into /dev/null
int fd = open("/dev/null", O_WRONLY);
diff --git a/media/utils/include/mediautils/TimeCheck.h b/media/utils/include/mediautils/TimeCheck.h
index bdb5337..0823669 100644
--- a/media/utils/include/mediautils/TimeCheck.h
+++ b/media/utils/include/mediautils/TimeCheck.h
@@ -148,4 +148,9 @@
TimeCheck makeTimeCheckStatsForClassMethod(
std::string_view className, std::string_view methodName);
+// A handy statement-like macro to put at the beginning of almost every method
+// which calls into HAL. Note that it requires the class to implement 'getClassName'.
+#define TIME_CHECK() auto timeCheck = \
+ mediautils::makeTimeCheckStatsForClassMethod(getClassName(), __func__)
+
} // namespace android::mediautils
diff --git a/services/OWNERS b/services/OWNERS
deleted file mode 100644
index 17e605d..0000000
--- a/services/OWNERS
+++ /dev/null
@@ -1,6 +0,0 @@
-elaurent@google.com
-essick@google.com
-etalvala@google.com
-hunga@google.com
-nchalko@google.com
-quxiangfang@google.com
diff --git a/services/audioflinger/Android.bp b/services/audioflinger/Android.bp
index 763c070..6d4c3a3 100644
--- a/services/audioflinger/Android.bp
+++ b/services/audioflinger/Android.bp
@@ -22,6 +22,10 @@
cc_library_shared {
name: "libaudioflinger",
+ defaults: [
+ "latest_android_media_audio_common_types_cpp_shared",
+ ],
+
srcs: [
"AudioFlinger.cpp",
"AudioHwDevice.cpp",
@@ -55,7 +59,6 @@
],
shared_libs: [
- "android.media.audio.common.types-V1-cpp",
"audioflinger-aidl-cpp",
"audioclient-types-aidl-cpp",
"av-types-aidl-cpp",
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index d2363d8..f1f8a8f 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -39,6 +39,7 @@
#include <utils/Log.h>
#include <utils/Trace.h>
#include <binder/Parcel.h>
+#include <media/audiohal/AudioHalVersionInfo.h>
#include <media/audiohal/DeviceHalInterface.h>
#include <media/audiohal/DevicesFactoryHalInterface.h>
#include <media/audiohal/EffectsFactoryHalInterface.h>
@@ -106,13 +107,15 @@
namespace android {
-#define MAX_AAUDIO_PROPERTY_DEVICE_HAL_VERSION 7.1
-
using ::android::base::StringPrintf;
using media::IEffectClient;
using media::audio::common::AudioMMapPolicyInfo;
using media::audio::common::AudioMMapPolicyType;
using android::content::AttributionSourceState;
+using android::detail::AudioHalVersionInfo;
+
+static const AudioHalVersionInfo kMaxAAudioPropertyDeviceHalVersion =
+ AudioHalVersionInfo(AudioHalVersionInfo::Type::HIDL, 7, 1);
static const char kDeadlockedString[] = "AudioFlinger may be deadlocked\n";
static const char kHardwareLockedString[] = "Hardware lock is taken\n";
@@ -228,7 +231,9 @@
BINDER_METHOD_ENTRY(setDeviceConnectedState) \
BINDER_METHOD_ENTRY(setRequestedLatencyMode) \
BINDER_METHOD_ENTRY(getSupportedLatencyModes) \
-
+BINDER_METHOD_ENTRY(setBluetoothVariableLatencyEnabled) \
+BINDER_METHOD_ENTRY(isBluetoothVariableLatencyEnabled) \
+BINDER_METHOD_ENTRY(supportsBluetoothVariableLatency) \
// singleton for Binder Method Statistics for IAudioFlinger
static auto& getIAudioFlingerStatistics() {
@@ -322,7 +327,8 @@
mGlobalEffectEnableTime(0),
mPatchPanel(this),
mDeviceEffectManager(this),
- mSystemReady(false)
+ mSystemReady(false),
+ mBluetoothLatencyModesEnabled(true)
{
// Move the audio session unique ID generator start base as time passes to limit risk of
// generating the same ID again after an audioserver restart.
@@ -398,7 +404,7 @@
mDevicesFactoryHalCallback = new DevicesFactoryHalCallbackImpl;
mDevicesFactoryHal->setCallbackOnce(mDevicesFactoryHalCallback);
- if (mDevicesFactoryHal->getHalVersion() <= MAX_AAUDIO_PROPERTY_DEVICE_HAL_VERSION) {
+ if (mDevicesFactoryHal->getHalVersion() <= kMaxAAudioPropertyDeviceHalVersion) {
mAAudioBurstsPerBuffer = getAAudioMixerBurstCountFromSystemProperty();
mAAudioHwBurstMinMicros = getAAudioHardwareBurstMinUsecFromSystemProperty();
}
@@ -444,7 +450,7 @@
*policyInfos = it->second;
return NO_ERROR;
}
- if (mDevicesFactoryHal->getHalVersion() > MAX_AAUDIO_PROPERTY_DEVICE_HAL_VERSION) {
+ if (mDevicesFactoryHal->getHalVersion() > kMaxAAudioPropertyDeviceHalVersion) {
AutoMutex lock(mHardwareLock);
for (size_t i = 0; i < mAudioHwDevs.size(); ++i) {
AudioHwDevice *dev = mAudioHwDevs.valueAt(i);
@@ -1640,6 +1646,44 @@
return thread->getSupportedLatencyModes(modes);
}
+status_t AudioFlinger::setBluetoothVariableLatencyEnabled(bool enabled) {
+ Mutex::Autolock _l(mLock);
+ status_t status = INVALID_OPERATION;
+ for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
+ // Success if at least one PlaybackThread supports Bluetooth latency modes
+ if (mPlaybackThreads.valueAt(i)->setBluetoothVariableLatencyEnabled(enabled) == NO_ERROR) {
+ status = NO_ERROR;
+ }
+ }
+ if (status == NO_ERROR) {
+ mBluetoothLatencyModesEnabled.store(enabled);
+ }
+ return status;
+}
+
+status_t AudioFlinger::isBluetoothVariableLatencyEnabled(bool *enabled) {
+ if (enabled == nullptr) {
+ return BAD_VALUE;
+ }
+ *enabled = mBluetoothLatencyModesEnabled.load();
+ return NO_ERROR;
+}
+
+status_t AudioFlinger::supportsBluetoothVariableLatency(bool* support) {
+ if (support == nullptr) {
+ return BAD_VALUE;
+ }
+ Mutex::Autolock _l(mLock);
+ *support = false;
+ for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
+ if (mAudioHwDevs.valueAt(i)->supportsBluetoothVariableLatency()) {
+ *support = true;
+ break;
+ }
+ }
+ return NO_ERROR;
+}
+
status_t AudioFlinger::setStreamMute(audio_stream_type_t stream, bool muted)
{
// check calling permissions
@@ -2142,9 +2186,9 @@
void AudioFlinger::onSupportedLatencyModesChanged(
audio_io_handle_t output, const std::vector<audio_latency_mode_t>& modes) {
int32_t outputAidl = VALUE_OR_FATAL(legacy2aidl_audio_io_handle_t_int32_t(output));
- std::vector<media::LatencyMode> modesAidl = VALUE_OR_FATAL(
- convertContainer<std::vector<media::LatencyMode>>(modes,
- legacy2aidl_audio_latency_mode_t_LatencyMode));
+ std::vector<media::audio::common::AudioLatencyMode> modesAidl = VALUE_OR_FATAL(
+ convertContainer<std::vector<media::audio::common::AudioLatencyMode>>(
+ modes, legacy2aidl_audio_latency_mode_t_AudioLatencyMode));
Mutex::Autolock _l(mClientLock);
size_t size = mNotificationClients.size();
@@ -2541,6 +2585,13 @@
flags = static_cast<AudioHwDevice::Flags>(flags | AudioHwDevice::AHWD_IS_INSERT);
}
+
+ if (bool supports = false;
+ dev->supportsBluetoothVariableLatency(&supports) == NO_ERROR && supports) {
+ flags = static_cast<AudioHwDevice::Flags>(flags |
+ AudioHwDevice::AHWD_SUPPORTS_BT_LATENCY_MODES);
+ }
+
audio_module_handle_t handle = (audio_module_handle_t) nextUniqueId(AUDIO_UNIQUE_ID_USE_MODULE);
AudioHwDevice *audioDevice = new AudioHwDevice(handle, name, dev, flags);
if (strcmp(name, AUDIO_HARDWARE_MODULE_ID_PRIMARY) == 0) {
@@ -2550,7 +2601,7 @@
mHardwareStatus = AUDIO_HW_IDLE;
}
- if (mDevicesFactoryHal->getHalVersion() > MAX_AAUDIO_PROPERTY_DEVICE_HAL_VERSION) {
+ if (mDevicesFactoryHal->getHalVersion() > kMaxAAudioPropertyDeviceHalVersion) {
if (int32_t mixerBursts = dev->getAAudioMixerBurstCount();
mixerBursts > 0 && mixerBursts > mAAudioBurstsPerBuffer) {
mAAudioBurstsPerBuffer = mixerBursts;
@@ -2754,14 +2805,15 @@
status_t status = INVALID_OPERATION;
for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
- std::vector<media::MicrophoneInfo> mics;
+ std::vector<audio_microphone_characteristic_t> mics;
AudioHwDevice *dev = mAudioHwDevs.valueAt(i);
mHardwareStatus = AUDIO_HW_GET_MICROPHONES;
status_t devStatus = dev->hwDevice()->getMicrophones(&mics);
mHardwareStatus = AUDIO_HW_IDLE;
if (devStatus == NO_ERROR) {
- microphones->insert(microphones->begin(), mics.begin(), mics.end());
// report success if at least one HW module supports the function.
+ std::transform(mics.begin(), mics.end(), std::back_inserter(*microphones),
+ [](auto& mic) { return media::MicrophoneInfo(mic); });
status = NO_ERROR;
}
}
@@ -2869,13 +2921,15 @@
ALOGV("openOutput_l() created spatializer output: ID %d thread %p",
*output, thread.get());
} else if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
- thread = new OffloadThread(this, outputStream, *output, mSystemReady);
+ thread = new OffloadThread(this, outputStream, *output,
+ mSystemReady, halConfig->offload_info);
ALOGV("openOutput_l() created offload output: ID %d thread %p",
*output, thread.get());
} else if ((flags & AUDIO_OUTPUT_FLAG_DIRECT)
|| !isValidPcmSinkFormat(halConfig->format)
|| !isValidPcmSinkChannelMask(halConfig->channel_mask)) {
- thread = new DirectOutputThread(this, outputStream, *output, mSystemReady);
+ thread = new DirectOutputThread(this, outputStream, *output,
+ mSystemReady, halConfig->offload_info);
ALOGV("openOutput_l() created direct output: ID %d thread %p",
*output, thread.get());
} else {
@@ -2889,6 +2943,7 @@
if (thread->isMsdDevice()) {
thread->setDownStreamPatch(&patch);
}
+ thread->setBluetoothVariableLatencyEnabled(mBluetoothLatencyModesEnabled.load());
return thread;
}
}
@@ -4585,7 +4640,10 @@
case TransactionCode::SYSTEM_READY:
case TransactionCode::SET_AUDIO_HAL_PIDS:
case TransactionCode::SET_VIBRATOR_INFOS:
- case TransactionCode::UPDATE_SECONDARY_OUTPUTS: {
+ case TransactionCode::UPDATE_SECONDARY_OUTPUTS:
+ case TransactionCode::SET_BLUETOOTH_VARIABLE_LATENCY_ENABLED:
+ case TransactionCode::IS_BLUETOOTH_VARIABLE_LATENCY_ENABLED:
+ case TransactionCode::SUPPORTS_BLUETOOTH_VARIABLE_LATENCY: {
if (!isServiceUid(IPCThreadState::self()->getCallingUid())) {
ALOGW("%s: transaction %d received from PID %d unauthorized UID %d",
__func__, code, IPCThreadState::self()->getCallingPid(),
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index fc4c807..cb303cf 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -299,6 +299,12 @@
virtual status_t getSupportedLatencyModes(audio_io_handle_t output,
std::vector<audio_latency_mode_t>* modes);
+ virtual status_t setBluetoothVariableLatencyEnabled(bool enabled);
+
+ virtual status_t isBluetoothVariableLatencyEnabled(bool* enabled);
+
+ virtual status_t supportsBluetoothVariableLatency(bool* support);
+
status_t onTransactWrapper(TransactionCode code, const Parcel& data, uint32_t flags,
const std::function<status_t()>& delegate) override;
@@ -678,14 +684,16 @@
binder::Status getVolumeShaperState(
int32_t id,
std::optional<media::VolumeShaperState>* _aidl_return) override;
- binder::Status getDualMonoMode(media::AudioDualMonoMode* _aidl_return) override;
- binder::Status setDualMonoMode(media::AudioDualMonoMode mode) override;
+ binder::Status getDualMonoMode(
+ media::audio::common::AudioDualMonoMode* _aidl_return) override;
+ binder::Status setDualMonoMode(
+ media::audio::common::AudioDualMonoMode mode) override;
binder::Status getAudioDescriptionMixLevel(float* _aidl_return) override;
binder::Status setAudioDescriptionMixLevel(float leveldB) override;
binder::Status getPlaybackRateParameters(
- media::AudioPlaybackRate* _aidl_return) override;
+ media::audio::common::AudioPlaybackRate* _aidl_return) override;
binder::Status setPlaybackRateParameters(
- const media::AudioPlaybackRate& playbackRate) override;
+ const media::audio::common::AudioPlaybackRate& playbackRate) override;
private:
const sp<PlaybackThread::Track> mTrack;
@@ -1029,6 +1037,9 @@
std::vector<media::audio::common::AudioMMapPolicyInfo>> mPolicyInfos;
int32_t mAAudioBurstsPerBuffer = 0;
int32_t mAAudioHwBurstMinMicros = 0;
+
+ // Bluetooth Variable latency control logic is enabled or disabled
+ std::atomic_bool mBluetoothLatencyModesEnabled;
};
#undef INCLUDING_FROM_AUDIOFLINGER_H
diff --git a/services/audioflinger/AudioHwDevice.h b/services/audioflinger/AudioHwDevice.h
index 8c5d239..1749f3f 100644
--- a/services/audioflinger/AudioHwDevice.h
+++ b/services/audioflinger/AudioHwDevice.h
@@ -40,6 +40,8 @@
// Means that this isn't a terminal module, and software patches
// are used to transport audio data further.
AHWD_IS_INSERT = 0x4,
+ // This Module supports BT Latency mode control
+ AHWD_SUPPORTS_BT_LATENCY_MODES = 0x8,
};
AudioHwDevice(audio_module_handle_t handle,
@@ -64,6 +66,10 @@
return (0 != (mFlags & AHWD_IS_INSERT));
}
+ bool supportsBluetoothVariableLatency() const {
+ return (0 != (mFlags & AHWD_SUPPORTS_BT_LATENCY_MODES));
+ }
+
audio_module_handle_t handle() const { return mHandle; }
const char *moduleName() const { return mModuleName; }
sp<DeviceHalInterface> hwDevice() const { return mHwDevice; }
diff --git a/services/audioflinger/DeviceEffectManager.cpp b/services/audioflinger/DeviceEffectManager.cpp
index 53ac5cb..3a8c1bc 100644
--- a/services/audioflinger/DeviceEffectManager.cpp
+++ b/services/audioflinger/DeviceEffectManager.cpp
@@ -30,6 +30,7 @@
namespace android {
+using detail::AudioHalVersionInfo;
using media::IEffectClient;
void AudioFlinger::DeviceEffectManager::createAudioPatch(audio_patch_handle_t handle,
@@ -106,8 +107,13 @@
if (lStatus == NO_ERROR) {
lStatus = effect->addHandle(handle.get());
if (lStatus == NO_ERROR) {
- effect->init(patches);
- mDeviceEffects.emplace(device, effect);
+ lStatus = effect->init(patches);
+ if (lStatus == NAME_NOT_FOUND) {
+ lStatus = NO_ERROR;
+ }
+ if (lStatus == NO_ERROR || lStatus == ALREADY_EXISTS) {
+ mDeviceEffects.emplace(device, effect);
+ }
}
}
}
@@ -125,14 +131,17 @@
return BAD_VALUE;
}
- static const float sMinDeviceEffectHalVersion = 6.0;
- float halVersion = effectsFactory->getHalVersion();
+ static AudioHalVersionInfo sMinDeviceEffectHalVersion =
+ AudioHalVersionInfo(AudioHalVersionInfo::Type::HIDL, 6, 0);
+ AudioHalVersionInfo halVersion = effectsFactory->getHalVersion();
+ // We can trust AIDL generated AudioHalVersionInfo comparison operator (based on std::tie) as
+ // long as the type, major and minor sequence doesn't change in the definition.
if (((desc->flags & EFFECT_FLAG_TYPE_MASK) != EFFECT_FLAG_TYPE_PRE_PROC
&& (desc->flags & EFFECT_FLAG_TYPE_MASK) != EFFECT_FLAG_TYPE_POST_PROC)
|| halVersion < sMinDeviceEffectHalVersion) {
- ALOGW("%s() non pre/post processing device effect %s or incompatible API version %f",
- __func__, desc->name, halVersion);
+ ALOGW("%s() non pre/post processing device effect %s or incompatible API version %s",
+ __func__, desc->name, halVersion.toString().c_str());
return BAD_VALUE;
}
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index 9ebff0b..98829d0 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -569,7 +569,8 @@
mMaxDisableWaitCnt(1), // set by configure(), should be >= 1
mDisableWaitCnt(0), // set by process() and updateState()
mOffloaded(false),
- mAddedToHal(false)
+ mAddedToHal(false),
+ mIsOutput(false)
#ifdef FLOAT_EFFECT_CHAIN
, mSupportsFloat(false)
#endif
@@ -962,6 +963,7 @@
mConfig.outputCfg.mask = EFFECT_CONFIG_ALL;
mConfig.inputCfg.buffer.frameCount = callback->frameCount();
mConfig.outputCfg.buffer.frameCount = mConfig.inputCfg.buffer.frameCount;
+ mIsOutput = callback->isOutput();
ALOGV("configure() %p chain %p buffer %p framecount %zu",
this, callback->chain().promote().get(),
@@ -980,7 +982,7 @@
#ifdef MULTICHANNEL_EFFECT_CHAIN
if (status != NO_ERROR &&
- callback->isOutput() &&
+ mIsOutput &&
(mConfig.inputCfg.channels != AUDIO_CHANNEL_OUT_STEREO
|| mConfig.outputCfg.channels != AUDIO_CHANNEL_OUT_STEREO)) {
// Older effects may require exact STEREO position mask.
@@ -1056,6 +1058,13 @@
&size,
&cmdStatus);
}
+
+ if (isVolumeControl()) {
+ // Force initializing the volume as 0 for volume control effect for safer ramping
+ uint32_t left = 0;
+ uint32_t right = 0;
+ setVolumeInternal(&left, &right, true /*controller*/);
+ }
}
// mConfig.outputCfg.buffer.frameCount cannot be zero.
@@ -1429,23 +1438,24 @@
((mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_CTRL ||
(mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_IND ||
(mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_MONITOR)) {
- uint32_t volume[2];
- uint32_t *pVolume = NULL;
- uint32_t size = sizeof(volume);
- volume[0] = *left;
- volume[1] = *right;
- if (controller) {
- pVolume = volume;
- }
- status = mEffectInterface->command(EFFECT_CMD_SET_VOLUME,
- size,
- volume,
- &size,
- pVolume);
- if (controller && status == NO_ERROR && size == sizeof(volume)) {
- *left = volume[0];
- *right = volume[1];
- }
+ status = setVolumeInternal(left, right, controller);
+ }
+ return status;
+}
+
+status_t AudioFlinger::EffectModule::setVolumeInternal(
+ uint32_t *left, uint32_t *right, bool controller) {
+ uint32_t volume[2] = {*left, *right};
+ uint32_t *pVolume = controller ? volume : nullptr;
+ uint32_t size = sizeof(volume);
+ status_t status = mEffectInterface->command(EFFECT_CMD_SET_VOLUME,
+ size,
+ volume,
+ &size,
+ pVolume);
+ if (controller && status == NO_ERROR && size == sizeof(volume)) {
+ *left = volume[0];
+ *right = volume[1];
}
return status;
}
@@ -1643,6 +1653,22 @@
return status;
}
+status_t AudioFlinger::EffectModule::getConfigs(
+ audio_config_base_t* inputCfg, audio_config_base_t* outputCfg, bool* isOutput) const {
+ Mutex::Autolock _l(mLock);
+ if (mConfig.inputCfg.mask == 0 || mConfig.outputCfg.mask == 0) {
+ return NO_INIT;
+ }
+ inputCfg->sample_rate = mConfig.inputCfg.samplingRate;
+ inputCfg->channel_mask = static_cast<audio_channel_mask_t>(mConfig.inputCfg.channels);
+ inputCfg->format = static_cast<audio_format_t>(mConfig.inputCfg.format);
+ outputCfg->sample_rate = mConfig.outputCfg.samplingRate;
+ outputCfg->channel_mask = static_cast<audio_channel_mask_t>(mConfig.outputCfg.channels);
+ outputCfg->format = static_cast<audio_format_t>(mConfig.outputCfg.format);
+ *isOutput = mIsOutput;
+ return NO_ERROR;
+}
+
static std::string dumpInOutBuffer(bool isInput, const sp<EffectBufferHalInterface> &buffer) {
std::stringstream ss;
@@ -1761,6 +1787,7 @@
BINDER_METHOD_ENTRY(command) \
BINDER_METHOD_ENTRY(disconnect) \
BINDER_METHOD_ENTRY(getCblk) \
+BINDER_METHOD_ENTRY(getConfig) \
// singleton for Binder Method Statistics for IEffect
mediautils::MethodStatistics<int>& getIEffectStatistics() {
@@ -1804,6 +1831,13 @@
*_aidl_return = (code); \
return Status::ok();
+#define VALUE_OR_RETURN_STATUS_AS_OUT(exp) \
+ ({ \
+ auto _tmp = (exp); \
+ if (!_tmp.ok()) { RETURN(_tmp.error()); } \
+ std::move(_tmp.value()); \
+ })
+
Status AudioFlinger::EffectHandle::enable(int32_t* _aidl_return)
{
AutoMutex _l(mLock);
@@ -1915,6 +1949,32 @@
return Status::ok();
}
+Status AudioFlinger::EffectHandle::getConfig(
+ media::EffectConfig* _config, int32_t* _aidl_return) {
+ AutoMutex _l(mLock);
+ sp<EffectBase> effect = mEffect.promote();
+ if (effect == nullptr || mDisconnected) {
+ RETURN(DEAD_OBJECT);
+ }
+ sp<EffectModule> effectModule = effect->asEffectModule();
+ if (effectModule == nullptr) {
+ RETURN(INVALID_OPERATION);
+ }
+ audio_config_base_t inputCfg = AUDIO_CONFIG_BASE_INITIALIZER;
+ audio_config_base_t outputCfg = AUDIO_CONFIG_BASE_INITIALIZER;
+ bool isOutput;
+ status_t status = effectModule->getConfigs(&inputCfg, &outputCfg, &isOutput);
+ if (status == NO_ERROR) {
+ constexpr bool isInput = false; // effects always use 'OUT' channel masks.
+ _config->inputCfg = VALUE_OR_RETURN_STATUS_AS_OUT(
+ legacy2aidl_audio_config_base_t_AudioConfigBase(inputCfg, isInput));
+ _config->outputCfg = VALUE_OR_RETURN_STATUS_AS_OUT(
+ legacy2aidl_audio_config_base_t_AudioConfigBase(outputCfg, isInput));
+ _config->isOnInputStream = !isOutput;
+ }
+ RETURN(status);
+}
+
Status AudioFlinger::EffectHandle::command(int32_t cmdCode,
const std::vector<uint8_t>& cmdData,
int32_t maxResponseSize,
diff --git a/services/audioflinger/Effects.h b/services/audioflinger/Effects.h
index 42614cc..78788df 100644
--- a/services/audioflinger/Effects.h
+++ b/services/audioflinger/Effects.h
@@ -283,6 +283,10 @@
status_t setHapticIntensity(int id, int intensity);
status_t setVibratorInfo(const media::AudioVibratorInfo& vibratorInfo);
+ status_t getConfigs(audio_config_base_t* inputCfg,
+ audio_config_base_t* outputCfg,
+ bool* isOutput) const;
+
void dump(int fd, const Vector<String16>& args);
private:
@@ -302,6 +306,8 @@
? EFFECT_BUFFER_ACCESS_WRITE : EFFECT_BUFFER_ACCESS_ACCUMULATE;
}
+ status_t setVolumeInternal(uint32_t *left, uint32_t *right, bool controller);
+
effect_config_t mConfig; // input and output audio configuration
sp<EffectHalInterface> mEffectInterface; // Effect module HAL
@@ -314,6 +320,7 @@
uint32_t mDisableWaitCnt; // current process() calls count during disable period.
bool mOffloaded; // effect is currently offloaded to the audio DSP
bool mAddedToHal; // effect has been added to the audio HAL
+ bool mIsOutput; // direction of the AF thread
#ifdef FLOAT_EFFECT_CHAIN
bool mSupportsFloat; // effect supports float processing
@@ -370,6 +377,8 @@
int32_t* _aidl_return) override;
android::binder::Status disconnect() override;
android::binder::Status getCblk(media::SharedFileRegion* _aidl_return) override;
+ android::binder::Status getConfig(media::EffectConfig* _config,
+ int32_t* _aidl_return) override;
sp<Client> client() const { return mClient; }
diff --git a/services/audioflinger/PatchPanel.h b/services/audioflinger/PatchPanel.h
index 93593a3..68a3800 100644
--- a/services/audioflinger/PatchPanel.h
+++ b/services/audioflinger/PatchPanel.h
@@ -31,7 +31,6 @@
mPlaybackThreadHandle(playbackThreadHandle),
mRecordThreadHandle(recordThreadHandle) {}
SoftwarePatch(const SoftwarePatch&) = default;
- SoftwarePatch& operator=(const SoftwarePatch&) = default;
// Must be called under AudioFlinger::mLock
status_t getLatencyMs_l(double *latencyMs) const;
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index 6a138bb..33983d7 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -310,6 +310,7 @@
binder::Status unmute(/*out*/ bool *ret) override;
private:
Track* const mTrack;
+ bool setMute(bool muted);
};
sp<AudioVibrationController> mAudioVibrationController;
sp<os::ExternalVibration> mExternalVibration;
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 73ee691..f759d58 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -271,8 +271,8 @@
static std::string toString(audio_latency_mode_t mode) {
// We convert to the AIDL type to print (eventually the legacy type will be removed).
- const auto result = legacy2aidl_audio_latency_mode_t_LatencyMode(mode);
- return result.has_value() ? media::toString(*result) : "UNKNOWN";
+ const auto result = legacy2aidl_audio_latency_mode_t_AudioLatencyMode(mode);
+ return result.has_value() ? media::audio::common::toString(*result) : "UNKNOWN";
}
// Could be made a template, but other toString overloads for std::vector are confused.
@@ -2063,7 +2063,8 @@
mHwSupportsPause(false), mHwPaused(false), mFlushPending(false),
mLeftVolFloat(-1.0), mRightVolFloat(-1.0),
mDownStreamPatch{},
- mIsTimestampAdvancing(kMinimumTimeBetweenTimestampChecksNs)
+ mIsTimestampAdvancing(kMinimumTimeBetweenTimestampChecksNs),
+ mBluetoothLatencyModesEnabled(true)
{
snprintf(mThreadName, kThreadNameLength, "AudioOut_%X", id);
mNBLogWriter = audioFlinger->newWriter_l(kLogSize, mThreadName);
@@ -2908,7 +2909,14 @@
void AudioFlinger::PlaybackThread::onCodecFormatChanged(
const std::basic_string<uint8_t>& metadataBs)
{
- std::thread([this, metadataBs]() {
+ wp<AudioFlinger::PlaybackThread> weakPointerThis = this;
+ std::thread([this, metadataBs, weakPointerThis]() {
+ sp<AudioFlinger::PlaybackThread> playbackThread = weakPointerThis.promote();
+ if (playbackThread == nullptr) {
+ ALOGW("PlaybackThread was destroyed, skip codec format change event");
+ return;
+ }
+
audio_utils::metadata::Data metadata =
audio_utils::metadata::dataFromByteString(metadataBs);
if (metadata.empty()) {
@@ -6133,8 +6141,10 @@
// ----------------------------------------------------------------------------
AudioFlinger::DirectOutputThread::DirectOutputThread(const sp<AudioFlinger>& audioFlinger,
- AudioStreamOut* output, audio_io_handle_t id, ThreadBase::type_t type, bool systemReady)
+ AudioStreamOut* output, audio_io_handle_t id, ThreadBase::type_t type, bool systemReady,
+ const audio_offload_info_t& offloadInfo)
: PlaybackThread(audioFlinger, output, id, type, systemReady)
+ , mOffloadInfo(offloadInfo)
{
setMasterBalance(audioFlinger->getMasterBalance_l());
}
@@ -6400,7 +6410,8 @@
// fill a buffer, then remove it from active list.
// Only consider last track started for mixer state control
bool isTimestampAdvancing = mIsTimestampAdvancing.check(mOutput);
- if (--(track->mRetryCount) <= 0) {
+ if (!isTunerStream() // tuner streams remain active in underrun
+ && --(track->mRetryCount) <= 0) {
if (isTimestampAdvancing) { // HAL is still playing audio, give us more time.
track->mRetryCount = kMaxTrackRetriesOffload;
} else {
@@ -6444,6 +6455,7 @@
(doHwPause || (mFlushPending && !mHwPaused && (count != 0)))) {
status_t result = mOutput->stream->pause();
ALOGE_IF(result != OK, "Error when pausing output stream: %d", result);
+ doHwResume = !doHwPause; // resume if pause is due to flush.
}
if (mFlushPending) {
flushHw_l();
@@ -6763,8 +6775,9 @@
// ----------------------------------------------------------------------------
AudioFlinger::OffloadThread::OffloadThread(const sp<AudioFlinger>& audioFlinger,
- AudioStreamOut* output, audio_io_handle_t id, bool systemReady)
- : DirectOutputThread(audioFlinger, output, id, OFFLOAD, systemReady),
+ AudioStreamOut* output, audio_io_handle_t id, bool systemReady,
+ const audio_offload_info_t& offloadInfo)
+ : DirectOutputThread(audioFlinger, output, id, OFFLOAD, systemReady, offloadInfo),
mPausedWriteLength(0), mPausedBytesRemaining(0), mKeepWakeLock(true)
{
//FIXME: mStandby should be set to true by ThreadBase constructo
@@ -6983,7 +6996,8 @@
// No buffers for this track. Give it a few chances to
// fill a buffer, then remove it from active list.
bool isTimestampAdvancing = mIsTimestampAdvancing.check(mOutput);
- if (--(track->mRetryCount) <= 0) {
+ if (!isTunerStream() // tuner streams remain active in underrun
+ && --(track->mRetryCount) <= 0) {
if (isTimestampAdvancing) { // HAL is still playing audio, give us more time.
track->mRetryCount = kMaxTrackRetriesOffload;
} else {
@@ -7012,6 +7026,7 @@
if (!mStandby && (doHwPause || (mFlushPending && !mHwPaused && (count != 0)))) {
status_t result = mOutput->stream->pause();
ALOGE_IF(result != OK, "Error when pausing output stream: %d", result);
+ doHwResume = !doHwPause; // resume if pause is due to flush.
}
if (mFlushPending) {
flushHw_l();
@@ -7427,6 +7442,15 @@
return NO_ERROR;
}
+status_t AudioFlinger::PlaybackThread::setBluetoothVariableLatencyEnabled(bool enabled) {
+ if (mOutput == nullptr || mOutput->audioHwDev == nullptr
+ || !mOutput->audioHwDev->supportsBluetoothVariableLatency()) {
+ return INVALID_OPERATION;
+ }
+ mBluetoothLatencyModesEnabled.store(enabled);
+ return NO_ERROR;
+}
+
void AudioFlinger::SpatializerThread::checkOutputStageEffects()
{
bool hasVirtualizer = false;
@@ -7561,10 +7585,11 @@
ALOGV("%p kUseFastCapture = Always, initFastCapture = true", this);
break;
case FastCapture_Static:
- initFastCapture = (mFrameCount * 1000) / mSampleRate < kMinNormalCaptureBufferSizeMs;
- ALOGV("%p kUseFastCapture = Static, (%lld * 1000) / %u vs %u, initFastCapture = %d",
- this, (long long)mFrameCount, mSampleRate, kMinNormalCaptureBufferSizeMs,
- initFastCapture);
+ initFastCapture = !mIsMsdDevice // Disable fast capture for MSD BUS devices.
+ && (mFrameCount * 1000) / mSampleRate < kMinNormalCaptureBufferSizeMs;
+ ALOGV("%p kUseFastCapture = Static, (%lld * 1000) / %u vs %u, initFastCapture = %d "
+ "mIsMsdDevice = %d", this, (long long)mFrameCount, mSampleRate,
+ kMinNormalCaptureBufferSizeMs, initFastCapture, mIsMsdDevice);
break;
// case FastCapture_Dynamic:
}
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index ad5617d..bb42f22 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -1086,6 +1086,8 @@
return INVALID_OPERATION;
}
+ virtual status_t setBluetoothVariableLatencyEnabled(bool enabled);
+
protected:
// updated by readOutputParameters_l()
size_t mNormalFrameCount; // normal mixer and effects
@@ -1436,6 +1438,9 @@
virtual void flushHw_l() {
mIsTimestampAdvancing.clear();
}
+
+ // Bluetooth Variable latency control logic is enabled or disabled for this thread
+ std::atomic_bool mBluetoothLatencyModesEnabled;
};
class MixerThread : public PlaybackThread {
@@ -1541,8 +1546,9 @@
public:
DirectOutputThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output,
- audio_io_handle_t id, bool systemReady)
- : DirectOutputThread(audioFlinger, output, id, DIRECT, systemReady) { }
+ audio_io_handle_t id, bool systemReady,
+ const audio_offload_info_t& offloadInfo)
+ : DirectOutputThread(audioFlinger, output, id, DIRECT, systemReady, offloadInfo) { }
virtual ~DirectOutputThread();
@@ -1574,11 +1580,14 @@
virtual void onAddNewTrack_l();
+ const audio_offload_info_t mOffloadInfo;
bool mVolumeShaperActive = false;
DirectOutputThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output,
- audio_io_handle_t id, ThreadBase::type_t type, bool systemReady);
+ audio_io_handle_t id, ThreadBase::type_t type, bool systemReady,
+ const audio_offload_info_t& offloadInfo);
void processVolume_l(Track *track, bool lastTrack);
+ bool isTunerStream() const { return (mOffloadInfo.content_id > 0); }
// prepareTracks_l() tells threadLoop_mix() the name of the single active track
sp<Track> mActiveTrack;
@@ -1616,7 +1625,8 @@
public:
OffloadThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output,
- audio_io_handle_t id, bool systemReady);
+ audio_io_handle_t id, bool systemReady,
+ const audio_offload_info_t& offloadInfo);
virtual ~OffloadThread() {};
void flushHw_l() override;
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 10f9f73..a3a5df4 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -439,7 +439,8 @@
return Status::ok();
}
-Status AudioFlinger::TrackHandle::getDualMonoMode(media::AudioDualMonoMode* _aidl_return)
+Status AudioFlinger::TrackHandle::getDualMonoMode(
+ media::audio::common::AudioDualMonoMode* _aidl_return)
{
audio_dual_mono_mode_t mode = AUDIO_DUAL_MONO_MODE_OFF;
const status_t status = mTrack->getDualMonoMode(&mode)
@@ -452,7 +453,7 @@
}
Status AudioFlinger::TrackHandle::setDualMonoMode(
- media::AudioDualMonoMode mode)
+ media::audio::common::AudioDualMonoMode mode)
{
const auto localMonoMode = VALUE_OR_RETURN_BINDER_STATUS(
aidl2legacy_AudioDualMonoMode_audio_dual_mono_mode_t(mode));
@@ -476,7 +477,7 @@
}
Status AudioFlinger::TrackHandle::getPlaybackRateParameters(
- media::AudioPlaybackRate* _aidl_return)
+ media::audio::common::AudioPlaybackRate* _aidl_return)
{
audio_playback_rate_t localPlaybackRate{};
status_t status = mTrack->getPlaybackRateParameters(&localPlaybackRate)
@@ -489,7 +490,7 @@
}
Status AudioFlinger::TrackHandle::setPlaybackRateParameters(
- const media::AudioPlaybackRate& playbackRate)
+ const media::audio::common::AudioPlaybackRate& playbackRate)
{
const audio_playback_rate_t localPlaybackRate = VALUE_OR_RETURN_BINDER_STATUS(
aidl2legacy_AudioPlaybackRate_audio_playback_rate_t(playbackRate));
@@ -1916,9 +1917,7 @@
}
}
-binder::Status AudioFlinger::PlaybackThread::Track::AudioVibrationController::mute(
- /*out*/ bool *ret) {
- *ret = false;
+bool AudioFlinger::PlaybackThread::Track::AudioVibrationController::setMute(bool muted) {
sp<ThreadBase> thread = mTrack->mThread.promote();
if (thread != 0) {
// Lock for updating mHapticPlaybackEnabled.
@@ -1926,27 +1925,22 @@
PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
if ((mTrack->channelMask() & AUDIO_CHANNEL_HAPTIC_ALL) != AUDIO_CHANNEL_NONE
&& playbackThread->mHapticChannelCount > 0) {
- mTrack->setHapticPlaybackEnabled(false);
- *ret = true;
+ mTrack->setHapticPlaybackEnabled(!muted);
+ return true;
}
}
+ return false;
+}
+
+binder::Status AudioFlinger::PlaybackThread::Track::AudioVibrationController::mute(
+ /*out*/ bool *ret) {
+ *ret = setMute(true);
return binder::Status::ok();
}
binder::Status AudioFlinger::PlaybackThread::Track::AudioVibrationController::unmute(
/*out*/ bool *ret) {
- *ret = false;
- sp<ThreadBase> thread = mTrack->mThread.promote();
- if (thread != 0) {
- // Lock for updating mHapticPlaybackEnabled.
- Mutex::Autolock _l(thread->mLock);
- PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
- if ((mTrack->channelMask() & AUDIO_CHANNEL_HAPTIC_ALL) != AUDIO_CHANNEL_NONE
- && playbackThread->mHapticChannelCount > 0) {
- mTrack->setHapticPlaybackEnabled(true);
- *ret = true;
- }
- }
+ *ret = setMute(false);
return binder::Status::ok();
}
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h
index cf1f64c..a62d3f0 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h
@@ -194,6 +194,9 @@
{AUDIO_FORMAT_E_AC3, {}},
{AUDIO_FORMAT_DTS, {}},
{AUDIO_FORMAT_DTS_HD, {}},
+ {AUDIO_FORMAT_DTS_HD_MA, {}},
+ {AUDIO_FORMAT_DTS_UHD, {}},
+ {AUDIO_FORMAT_DTS_UHD_P2, {}},
{AUDIO_FORMAT_AAC_LC, {
AUDIO_FORMAT_AAC_HE_V1, AUDIO_FORMAT_AAC_HE_V2, AUDIO_FORMAT_AAC_ELD,
AUDIO_FORMAT_AAC_XHE}},
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
index bb1699e..3b19e52 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
@@ -55,7 +55,7 @@
status_t getAudioPolicyMix(audio_devices_t deviceType,
const String8& address, sp<AudioPolicyMix> &policyMix) const;
- status_t registerMix(AudioMix mix, sp<SwAudioOutputDescriptor> desc);
+ status_t registerMix(const AudioMix& mix, const sp<SwAudioOutputDescriptor>& desc);
status_t unregisterMix(const AudioMix& mix);
@@ -76,7 +76,7 @@
sp<AudioPolicyMix> &primaryMix,
std::vector<sp<AudioPolicyMix>> *secondaryMixes);
- sp<DeviceDescriptor> getDeviceAndMixForInputSource(audio_source_t inputSource,
+ sp<DeviceDescriptor> getDeviceAndMixForInputSource(const audio_attributes_t& attributes,
const DeviceVector &availableDeviceTypes,
uid_t uid,
sp<AudioPolicyMix> *policyMix) const;
@@ -124,7 +124,7 @@
void dump(String8 *dst) const;
private:
- enum class MixMatchStatus { MATCH, NO_MATCH, INVALID_MIX };
+ enum class MixMatchStatus { MATCH, NO_MATCH };
MixMatchStatus mixMatch(const AudioMix* mix, size_t mixIndex,
const audio_attributes_t& attributes,
const audio_config_base_t& config,
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
index e142bef..56c0603 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
@@ -17,6 +17,7 @@
#define LOG_TAG "APM_AudioPolicyMix"
//#define LOG_NDEBUG 0
+#include <algorithm>
#include "AudioPolicyMix.h"
#include "TypeConverter.h"
#include "HwModule.h"
@@ -25,6 +26,89 @@
#include <AudioOutputDescriptor.h>
namespace android {
+namespace {
+
+// Returns true if the criterion matches.
+// The exclude criteria are handled in the same way as positive
+// ones - only condition is matched (the function will return
+// same result both for RULE_MATCH_X and RULE_EXCLUDE_X).
+bool isCriterionMatched(const AudioMixMatchCriterion& criterion,
+ const audio_attributes_t& attr,
+ const uid_t uid) {
+ uint32_t ruleWithoutExclusion = criterion.mRule & ~RULE_EXCLUSION_MASK;
+ switch(ruleWithoutExclusion) {
+ case RULE_MATCH_ATTRIBUTE_USAGE:
+ return criterion.mValue.mUsage == attr.usage;
+ case RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET:
+ return criterion.mValue.mSource == attr.source;
+ case RULE_MATCH_UID:
+ return criterion.mValue.mUid == uid;
+ case RULE_MATCH_USERID:
+ {
+ userid_t userId = multiuser_get_user_id(uid);
+ return criterion.mValue.mUserId == userId;
+ }
+ }
+ ALOGE("Encountered invalid mix rule 0x%x", criterion.mRule);
+ return false;
+}
+
+// Returns true if vector of criteria is matched:
+// - If any of the exclude criteria is matched the criteria doesn't match.
+// - Otherwise, for each 'dimension' of positive rule present
+// (usage, capture preset, uid, userid...) at least one rule must match
+// for the criteria to match.
+bool areMixCriteriaMatched(const std::vector<AudioMixMatchCriterion>& criteria,
+ const audio_attributes_t& attr,
+ const uid_t uid) {
+ // If any of the exclusion criteria are matched the mix doesn't match.
+ auto isMatchingExcludeCriterion = [&](const AudioMixMatchCriterion& c) {
+ return c.isExcludeCriterion() && isCriterionMatched(c, attr, uid);
+ };
+ if (std::any_of(criteria.begin(), criteria.end(), isMatchingExcludeCriterion)) {
+ return false;
+ }
+
+ uint32_t presentPositiveRules = 0; // Bitmask of all present positive criteria.
+ uint32_t matchedPositiveRules = 0; // Bitmask of all matched positive criteria.
+ for (const auto& criterion : criteria) {
+ if (criterion.isExcludeCriterion()) {
+ continue;
+ }
+ presentPositiveRules |= criterion.mRule;
+ if (isCriterionMatched(criterion, attr, uid)) {
+ matchedPositiveRules |= criterion.mRule;
+ }
+ }
+ return presentPositiveRules == matchedPositiveRules;
+}
+
+// Consistency checks: for each "dimension" of rules (usage, uid...), we can
+// only have MATCH rules, or EXCLUDE rules in each dimension, not a combination.
+bool areMixCriteriaConsistent(const std::vector<AudioMixMatchCriterion>& criteria) {
+ std::set<uint32_t> positiveCriteria;
+ for (const AudioMixMatchCriterion& c : criteria) {
+ if (c.isExcludeCriterion()) {
+ continue;
+ }
+ positiveCriteria.insert(c.mRule);
+ }
+
+ auto isConflictingCriterion = [&positiveCriteria](const AudioMixMatchCriterion& c) {
+ uint32_t ruleWithoutExclusion = c.mRule & ~RULE_EXCLUSION_MASK;
+ return c.isExcludeCriterion() &&
+ (positiveCriteria.find(ruleWithoutExclusion) != positiveCriteria.end());
+ };
+ return std::none_of(criteria.begin(), criteria.end(), isConflictingCriterion);
+}
+
+template <typename Predicate>
+void EraseCriteriaIf(std::vector<AudioMixMatchCriterion>& v,
+ const Predicate& predicate) {
+ v.erase(std::remove_if(v.begin(), v.end(), predicate), v.end());
+}
+
+} // namespace
void AudioPolicyMix::dump(String8 *dst, int spaces, int index) const
{
@@ -78,7 +162,8 @@
}
}
-status_t AudioPolicyMixCollection::registerMix(AudioMix mix, sp<SwAudioOutputDescriptor> desc)
+status_t AudioPolicyMixCollection::registerMix(const AudioMix& mix,
+ const sp<SwAudioOutputDescriptor>& desc)
{
for (size_t i = 0; i < size(); i++) {
const sp<AudioPolicyMix>& registeredMix = itemAt(i);
@@ -89,12 +174,17 @@
return BAD_VALUE;
}
}
- sp<AudioPolicyMix> policyMix = new AudioPolicyMix(mix);
+ if (!areMixCriteriaConsistent(mix.mCriteria)) {
+ ALOGE("registerMix(): Mix contains inconsistent criteria "
+ "(MATCH & EXCLUDE criteria of the same type)");
+ return BAD_VALUE;
+ }
+ sp<AudioPolicyMix> policyMix = sp<AudioPolicyMix>::make(mix);
add(policyMix);
ALOGD("registerMix(): adding mix for dev=0x%x addr=%s",
policyMix->mDeviceType, policyMix->mDeviceAddress.string());
- if (desc != 0) {
+ if (desc != nullptr) {
desc->mPolicyMix = policyMix;
policyMix->setOutput(desc);
}
@@ -177,15 +267,9 @@
continue; // Primary output already found
}
- switch (mixMatch(policyMix.get(), i, attributes, config, uid)) {
- case MixMatchStatus::INVALID_MIX:
- // The mix has contradictory rules, ignore it
- // TODO: reject invalid mix at registration
- continue;
- case MixMatchStatus::NO_MATCH:
- ALOGV("%s: Mix %zu: does not match", __func__, i);
- continue; // skip the mix
- case MixMatchStatus::MATCH:;
+ if(mixMatch(policyMix.get(), i, attributes, config, uid) == MixMatchStatus::NO_MATCH) {
+ ALOGV("%s: Mix %zu: does not match", __func__, i);
+ continue; // skip the mix
}
if (primaryOutputMix) {
@@ -239,136 +323,19 @@
return MixMatchStatus::NO_MATCH;
}
- int userId = (int) multiuser_get_user_id(uid);
-
- // TODO if adding more player rules (currently only 2), make rule handling "generic"
- // as there is no difference in the treatment of usage- or uid-based rules
- bool hasUsageMatchRules = false;
- bool hasUsageExcludeRules = false;
- bool usageMatchFound = false;
- bool usageExclusionFound = false;
-
- bool hasUidMatchRules = false;
- bool hasUidExcludeRules = false;
- bool uidMatchFound = false;
- bool uidExclusionFound = false;
-
- bool hasUserIdExcludeRules = false;
- bool userIdExclusionFound = false;
- bool hasUserIdMatchRules = false;
- bool userIdMatchFound = false;
-
-
- bool hasAddrMatch = false;
-
- // iterate over all mix criteria to list what rules this mix contains
- for (size_t j = 0; j < mix->mCriteria.size(); j++) {
- ALOGV(" getOutputForAttr: mix %zu: inspecting mix criteria %zu of %zu",
- mixIndex, j, mix->mCriteria.size());
-
- // if there is an address match, prioritize that match
- if (strncmp(attributes.tags, "addr=", strlen("addr=")) == 0 &&
- strncmp(attributes.tags + strlen("addr="),
- mix->mDeviceAddress.string(),
- AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - strlen("addr=") - 1) == 0) {
- hasAddrMatch = true;
- break;
- }
-
- switch (mix->mCriteria[j].mRule) {
- case RULE_MATCH_ATTRIBUTE_USAGE:
- ALOGV("\tmix has RULE_MATCH_ATTRIBUTE_USAGE for usage %d",
- mix->mCriteria[j].mValue.mUsage);
- hasUsageMatchRules = true;
- if (mix->mCriteria[j].mValue.mUsage == attributes.usage) {
- // found one match against all allowed usages
- usageMatchFound = true;
- }
- break;
- case RULE_EXCLUDE_ATTRIBUTE_USAGE:
- ALOGV("\tmix has RULE_EXCLUDE_ATTRIBUTE_USAGE for usage %d",
- mix->mCriteria[j].mValue.mUsage);
- hasUsageExcludeRules = true;
- if (mix->mCriteria[j].mValue.mUsage == attributes.usage) {
- // found this usage is to be excluded
- usageExclusionFound = true;
- }
- break;
- case RULE_MATCH_UID:
- ALOGV("\tmix has RULE_MATCH_UID for uid %d", mix->mCriteria[j].mValue.mUid);
- hasUidMatchRules = true;
- if (mix->mCriteria[j].mValue.mUid == uid) {
- // found one UID match against all allowed UIDs
- uidMatchFound = true;
- }
- break;
- case RULE_EXCLUDE_UID:
- ALOGV("\tmix has RULE_EXCLUDE_UID for uid %d", mix->mCriteria[j].mValue.mUid);
- hasUidExcludeRules = true;
- if (mix->mCriteria[j].mValue.mUid == uid) {
- // found this UID is to be excluded
- uidExclusionFound = true;
- }
- break;
- case RULE_MATCH_USERID:
- ALOGV("\tmix has RULE_MATCH_USERID for userId %d",
- mix->mCriteria[j].mValue.mUserId);
- hasUserIdMatchRules = true;
- if (mix->mCriteria[j].mValue.mUserId == userId) {
- // found one userId match against all allowed userIds
- userIdMatchFound = true;
- }
- break;
- case RULE_EXCLUDE_USERID:
- ALOGV("\tmix has RULE_EXCLUDE_USERID for userId %d",
- mix->mCriteria[j].mValue.mUserId);
- hasUserIdExcludeRules = true;
- if (mix->mCriteria[j].mValue.mUserId == userId) {
- // found this userId is to be excluded
- userIdExclusionFound = true;
- }
- break;
- default:
- break;
- }
-
- // consistency checks: for each "dimension" of rules (usage, uid...), we can
- // only have MATCH rules, or EXCLUDE rules in each dimension, not a combination
- if (hasUsageMatchRules && hasUsageExcludeRules) {
- ALOGE("getOutputForAttr: invalid combination of RULE_MATCH_ATTRIBUTE_USAGE"
- " and RULE_EXCLUDE_ATTRIBUTE_USAGE in mix %zu", mixIndex);
- return MixMatchStatus::INVALID_MIX;
- }
- if (hasUidMatchRules && hasUidExcludeRules) {
- ALOGE("getOutputForAttr: invalid combination of RULE_MATCH_UID"
- " and RULE_EXCLUDE_UID in mix %zu", mixIndex);
- return MixMatchStatus::INVALID_MIX;
- }
- if (hasUserIdMatchRules && hasUserIdExcludeRules) {
- ALOGE("getOutputForAttr: invalid combination of RULE_MATCH_USERID"
- " and RULE_EXCLUDE_USERID in mix %zu", mixIndex);
- return MixMatchStatus::INVALID_MIX;
- }
-
- if ((hasUsageExcludeRules && usageExclusionFound)
- || (hasUidExcludeRules && uidExclusionFound)
- || (hasUserIdExcludeRules && userIdExclusionFound)) {
- break; // stop iterating on criteria because an exclusion was found (will fail)
- }
- }//iterate on mix criteria
-
- // determine if exiting on success (or implicit failure as desc is 0)
- if (hasAddrMatch ||
- !((hasUsageExcludeRules && usageExclusionFound) ||
- (hasUsageMatchRules && !usageMatchFound) ||
- (hasUidExcludeRules && uidExclusionFound) ||
- (hasUidMatchRules && !uidMatchFound) ||
- (hasUserIdExcludeRules && userIdExclusionFound) ||
- (hasUserIdMatchRules && !userIdMatchFound))) {
+ // if there is an address match, prioritize that match
+ if (strncmp(attributes.tags, "addr=", strlen("addr=")) == 0 &&
+ strncmp(attributes.tags + strlen("addr="),
+ mix->mDeviceAddress.string(),
+ AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - strlen("addr=") - 1) == 0) {
ALOGV("\tgetOutputForAttr will use mix %zu", mixIndex);
return MixMatchStatus::MATCH;
}
+ if (areMixCriteriaMatched(mix->mCriteria, attributes, uid)) {
+ ALOGV("\tgetOutputForAttr will use mix %zu", mixIndex);
+ return MixMatchStatus::MATCH;
+ }
} else if (mix->mMixType == MIX_TYPE_RECORDERS) {
if (attributes.usage == AUDIO_USAGE_VIRTUAL_SOURCE &&
strncmp(attributes.tags, "addr=", strlen("addr=")) == 0 &&
@@ -399,7 +366,7 @@
}
sp<DeviceDescriptor> AudioPolicyMixCollection::getDeviceAndMixForInputSource(
- audio_source_t inputSource,
+ const audio_attributes_t& attributes,
const DeviceVector &availDevices,
uid_t uid,
sp<AudioPolicyMix> *policyMix) const
@@ -409,28 +376,17 @@
if (mix->mMixType != MIX_TYPE_RECORDERS) {
continue;
}
- for (size_t j = 0; j < mix->mCriteria.size(); j++) {
- if ((RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET == mix->mCriteria[j].mRule &&
- mix->mCriteria[j].mValue.mSource == inputSource) ||
- (RULE_EXCLUDE_ATTRIBUTE_CAPTURE_PRESET == mix->mCriteria[j].mRule &&
- mix->mCriteria[j].mValue.mSource != inputSource) ||
- (RULE_MATCH_UID == mix->mCriteria[j].mRule &&
- mix->mCriteria[j].mValue.mUid == uid) ||
- (RULE_EXCLUDE_UID == mix->mCriteria[j].mRule &&
- mix->mCriteria[j].mValue.mUid != uid)) {
- // assuming PolicyMix only for remote submix for input
- // so mix->mDeviceType can only be AUDIO_DEVICE_OUT_REMOTE_SUBMIX
- audio_devices_t device = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
- auto mixDevice =
- availDevices.getDevice(device, mix->mDeviceAddress, AUDIO_FORMAT_DEFAULT);
+ if (areMixCriteriaMatched(mix->mCriteria, attributes, uid)) {
+ // Assuming PolicyMix only for remote submix for input
+ // so mix->mDeviceType can only be AUDIO_DEVICE_OUT_REMOTE_SUBMIX.
+ auto mixDevice = availDevices.getDevice(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
+ mix->mDeviceAddress, AUDIO_FORMAT_DEFAULT);
if (mixDevice != nullptr) {
if (policyMix != nullptr) {
*policyMix = mix;
}
return mixDevice;
}
- break;
- }
}
}
return nullptr;
@@ -501,7 +457,7 @@
// AND it doesn't have a "match uid" rule
// THEN add a rule to exclude the uid
for (size_t i = 0; i < size(); i++) {
- const AudioPolicyMix *mix = itemAt(i).get();
+ AudioPolicyMix *mix = itemAt(i).get();
if (!mix->isDeviceAffinityCompatible()) {
continue;
}
@@ -531,27 +487,16 @@
status_t AudioPolicyMixCollection::removeUidDeviceAffinities(uid_t uid) {
// for each player mix: remove existing rules that match or exclude this uid
for (size_t i = 0; i < size(); i++) {
- bool foundUidRule = false;
- const AudioPolicyMix *mix = itemAt(i).get();
+ AudioPolicyMix *mix = itemAt(i).get();
if (!mix->isDeviceAffinityCompatible()) {
continue;
}
- std::vector<size_t> criteriaToRemove;
- for (size_t j = 0; j < mix->mCriteria.size(); j++) {
- const uint32_t rule = mix->mCriteria[j].mRule;
- // is this rule excluding the uid? (not considering uid match rules
- // as those are not used for uid-device affinity)
- if (rule == RULE_EXCLUDE_UID
- && uid == mix->mCriteria[j].mValue.mUid) {
- foundUidRule = true;
- criteriaToRemove.insert(criteriaToRemove.begin(), j);
- }
- }
- if (foundUidRule) {
- for (size_t j = 0; j < criteriaToRemove.size(); j++) {
- mix->mCriteria.removeAt(criteriaToRemove[j]);
- }
- }
+
+ // is this rule excluding the uid? (not considering uid match rules
+ // as those are not used for uid-device affinity)
+ EraseCriteriaIf(mix->mCriteria, [uid](const AudioMixMatchCriterion& c) {
+ return c.mRule == RULE_EXCLUDE_UID && c.mValue.mUid == uid;
+ });
}
return NO_ERROR;
}
@@ -586,7 +531,7 @@
// "match userId" rule for this userId, return an error
// (adding a userId-device affinity would result in contradictory rules)
for (size_t i = 0; i < size(); i++) {
- const AudioPolicyMix* mix = itemAt(i).get();
+ AudioPolicyMix* mix = itemAt(i).get();
if (!mix->isDeviceAffinityCompatible()) {
continue;
}
@@ -603,7 +548,7 @@
// AND it doesn't have a "match userId" rule
// THEN add a rule to exclude the userId
for (size_t i = 0; i < size(); i++) {
- const AudioPolicyMix *mix = itemAt(i).get();
+ AudioPolicyMix *mix = itemAt(i).get();
if (!mix->isDeviceAffinityCompatible()) {
continue;
}
@@ -633,27 +578,16 @@
status_t AudioPolicyMixCollection::removeUserIdDeviceAffinities(int userId) {
// for each player mix: remove existing rules that match or exclude this userId
for (size_t i = 0; i < size(); i++) {
- bool foundUserIdRule = false;
- const AudioPolicyMix *mix = itemAt(i).get();
+ AudioPolicyMix *mix = itemAt(i).get();
if (!mix->isDeviceAffinityCompatible()) {
continue;
}
- std::vector<size_t> criteriaToRemove;
- for (size_t j = 0; j < mix->mCriteria.size(); j++) {
- const uint32_t rule = mix->mCriteria[j].mRule;
- // is this rule excluding the userId? (not considering userId match rules
- // as those are not used for userId-device affinity)
- if (rule == RULE_EXCLUDE_USERID
- && userId == mix->mCriteria[j].mValue.mUserId) {
- foundUserIdRule = true;
- criteriaToRemove.insert(criteriaToRemove.begin(), j);
- }
- }
- if (foundUserIdRule) {
- for (size_t j = 0; j < criteriaToRemove.size(); j++) {
- mix->mCriteria.removeAt(criteriaToRemove[j]);
- }
- }
+
+ // is this rule excluding the userId? (not considering userId match rules
+ // as those are not used for userId-device affinity)
+ EraseCriteriaIf(mix->mCriteria, [userId](const AudioMixMatchCriterion& c) {
+ return c.mRule == RULE_EXCLUDE_USERID && c.mValue.mUserId == userId;
+ });
}
return NO_ERROR;
}
diff --git a/services/audiopolicy/config/surround_sound_configuration_aidl.xml b/services/audiopolicy/config/surround_sound_configuration_aidl.xml
new file mode 100644
index 0000000..cf15711
--- /dev/null
+++ b/services/audiopolicy/config/surround_sound_configuration_aidl.xml
@@ -0,0 +1,34 @@
+<?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.
+-->
+<surroundSound>
+ <!-- Each of the listed formats gets an entry in Surround Settings dialog on TV devices.
+ There must be a corresponding Java ENCODING_... constant defined in AudioFormat.java,
+ and a display name defined in AudioFormat.toDisplayName. For the formats that don't
+ need a dedicated Surround Settings dialog entry, a subformats list has to be used. -->
+ <formats>
+ <format name="AUDIO_FORMAT_AC3" />
+ <format name="AUDIO_FORMAT_E_AC3" />
+ <format name="AUDIO_FORMAT_E_AC3_JOC" />
+ <format name="AUDIO_FORMAT_DOLBY_TRUEHD" />
+ <format name="AUDIO_FORMAT_DTS" />
+ <format name="AUDIO_FORMAT_DTS_HD" />
+ <format name="AUDIO_FORMAT_DTS_HD_MA" />
+ <format name="AUDIO_FORMAT_DTS_UHD" />
+ <format name="AUDIO_FORMAT_DTS_UHD_P2" />
+ <format name="AUDIO_FORMAT_AAC_LC" subformats="AUDIO_FORMAT_AAC_HE_V1 AUDIO_FORMAT_AAC_HE_V2 AUDIO_FORMAT_AAC_ELD AUDIO_FORMAT_AAC_XHE" />
+ <format name="AUDIO_FORMAT_AC4" />
+ </formats>
+</surroundSound>
diff --git a/services/audiopolicy/engine/common/src/VolumeCurve.cpp b/services/audiopolicy/engine/common/src/VolumeCurve.cpp
index 8aa4b08..fccbc60 100644
--- a/services/audiopolicy/engine/common/src/VolumeCurve.cpp
+++ b/services/audiopolicy/engine/common/src/VolumeCurve.cpp
@@ -52,7 +52,7 @@
volIdx = volIndexMin;
} else {
// This would result in a divide-by-zero below
- ALOG_ASSERT(volIndexmin != volIndexMax, "Invalid volume index range & value: 0");
+ ALOG_ASSERT(volIndexMin != volIndexMax, "Invalid volume index range & value: 0");
return NAN;
}
} else {
diff --git a/services/audiopolicy/engineconfigurable/src/Engine.cpp b/services/audiopolicy/engineconfigurable/src/Engine.cpp
index 3d74920..2831a9b 100644
--- a/services/audiopolicy/engineconfigurable/src/Engine.cpp
+++ b/services/audiopolicy/engineconfigurable/src/Engine.cpp
@@ -333,7 +333,7 @@
return device;
}
- device = policyMixes.getDeviceAndMixForInputSource(attr.source,
+ device = policyMixes.getDeviceAndMixForInputSource(attr,
availableInputDevices,
uid,
mix);
diff --git a/services/audiopolicy/engineconfigurable/tools/Android.bp b/services/audiopolicy/engineconfigurable/tools/Android.bp
index 40efb3d..b6089b7 100644
--- a/services/audiopolicy/engineconfigurable/tools/Android.bp
+++ b/services/audiopolicy/engineconfigurable/tools/Android.bp
@@ -21,36 +21,23 @@
default_applicable_licenses: ["frameworks_av_license"],
}
-python_defaults {
- name: "tools_default",
- version: {
- py2: {
- enabled: false,
- },
- py3: {
- enabled: true,
- },
- },
-}
-
//##################################################################################################
// Tools for audio policy engine criterion type configuration file
//
python_binary_host {
- name: "buildPolicyCriterionTypes.py",
+ name: "buildPolicyCriterionTypes",
main: "buildPolicyCriterionTypes.py",
srcs: [
"buildPolicyCriterionTypes.py",
],
- defaults: ["tools_default"],
}
genrule_defaults {
name: "buildpolicycriteriontypesrule",
- tools: ["buildPolicyCriterionTypes.py"],
+ tools: ["buildPolicyCriterionTypes"],
cmd: "cp $(locations :audio_policy_configuration_files) $(genDir)/. && " +
"cp $(location :audio_policy_configuration_top_file) $(genDir)/audio_policy_configuration.xml && " +
- "$(location buildPolicyCriterionTypes.py) " +
+ "$(location buildPolicyCriterionTypes) " +
" --androidaudiobaseheader $(location :libaudio_system_audio_base) " +
" --androidaudiocommonbaseheader $(location :libaudio_system_audio_common_base) " +
"--audiopolicyconfigurationfile $(genDir)/audio_policy_configuration.xml " +
@@ -72,12 +59,11 @@
// Tools for audio policy engine parameter framework configurable domains
//
python_binary_host {
- name: "domainGeneratorPolicy.py",
+ name: "domainGeneratorPolicy",
main: "domainGeneratorPolicy.py",
srcs: [
"domainGeneratorPolicy.py",
],
- defaults: ["tools_default"],
libs: [
"EddParser.py",
"hostConfig.py",
@@ -91,13 +77,13 @@
genrule_defaults {
name: "domaingeneratorpolicyrule",
tools: [
- "domainGeneratorPolicy.py",
+ "domainGeneratorPolicy",
"domainGeneratorConnector",
],
cmd: "mkdir -p $(genDir)/Structure/Policy && " +
"cp $(locations :audio_policy_pfw_structure_files) $(genDir)/Structure/Policy && " +
"cp $(location :audio_policy_pfw_toplevel) $(genDir)/top_level && " +
- "$(location domainGeneratorPolicy.py) " +
+ "$(location domainGeneratorPolicy) " +
"--validate " +
"--domain-generator-tool $(location domainGeneratorConnector) " +
"--toplevel-config $(genDir)/top_level " +
@@ -121,19 +107,18 @@
// Tools for policy parameter-framework product strategies structure file generation
//
python_binary_host {
- name: "buildStrategiesStructureFile.py",
+ name: "buildStrategiesStructureFile",
main: "buildStrategiesStructureFile.py",
srcs: [
"buildStrategiesStructureFile.py",
],
- defaults: ["tools_default"],
}
genrule_defaults {
name: "buildstrategiesstructurerule",
- tools: ["buildStrategiesStructureFile.py"],
+ tools: ["buildStrategiesStructureFile"],
cmd: "cp $(locations :audio_policy_engine_configuration_files) $(genDir) && ls -l $(genDir) &&"+
- "$(location buildStrategiesStructureFile.py) " +
+ "$(location buildStrategiesStructureFile) " +
"--audiopolicyengineconfigurationfile $(genDir)/audio_policy_engine_configuration.xml "+
"--productstrategiesstructurefile $(location :product_strategies_structure_template) " +
"--outputfile $(out)",
@@ -149,18 +134,17 @@
// Tools for policy parameter-framework common type structure file generation
//
python_binary_host {
- name: "buildCommonTypesStructureFile.py",
+ name: "buildCommonTypesStructureFile",
main: "buildCommonTypesStructureFile.py",
srcs: [
"buildCommonTypesStructureFile.py",
],
- defaults: ["tools_default"],
}
genrule_defaults {
name: "buildcommontypesstructurerule",
- tools: ["buildCommonTypesStructureFile.py"],
- cmd: "$(location buildCommonTypesStructureFile.py) " +
+ tools: ["buildCommonTypesStructureFile"],
+ cmd: "$(location buildCommonTypesStructureFile) " +
"--androidaudiobaseheader $(location :libaudio_system_audio_base) " +
"--commontypesstructure $(location :common_types_structure_template) " +
"--outputfile $(out)",
diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
index 08d6453..45c5eac 100644
--- a/services/audiopolicy/enginedefault/src/Engine.cpp
+++ b/services/audiopolicy/enginedefault/src/Engine.cpp
@@ -772,7 +772,7 @@
return device;
}
- device = policyMixes.getDeviceAndMixForInputSource(attr.source,
+ device = policyMixes.getDeviceAndMixForInputSource(attr,
availableInputDevices,
uid,
mix);
diff --git a/services/audiopolicy/fuzzer/audiopolicy_fuzzer.cpp b/services/audiopolicy/fuzzer/audiopolicy_fuzzer.cpp
index 48f7410..28268c9 100644
--- a/services/audiopolicy/fuzzer/audiopolicy_fuzzer.cpp
+++ b/services/audiopolicy/fuzzer/audiopolicy_fuzzer.cpp
@@ -544,10 +544,11 @@
status_t AudioPolicyManagerFuzzerDynamicPolicy::addPolicyMix(
int mixType, int mixFlag, audio_devices_t deviceType, std::string mixAddress,
const audio_config_t &audioConfig, const std::vector<PolicyMixTuple> &rules) {
- Vector<AudioMixMatchCriterion> myMixMatchCriteria;
+ std::vector<AudioMixMatchCriterion> myMixMatchCriteria;
+ myMixMatchCriteria.reserve(rules.size());
for (const auto &rule : rules) {
- myMixMatchCriteria.add(
+ myMixMatchCriteria.push_back(
AudioMixMatchCriterion(std::get<0>(rule), std::get<1>(rule), std::get<2>(rule)));
}
diff --git a/services/audiopolicy/managerdefault/Android.bp b/services/audiopolicy/managerdefault/Android.bp
index 4b4817e..6e34eb0 100644
--- a/services/audiopolicy/managerdefault/Android.bp
+++ b/services/audiopolicy/managerdefault/Android.bp
@@ -10,6 +10,10 @@
cc_library_shared {
name: "libaudiopolicymanagerdefault",
+ defaults: [
+ "latest_android_media_audio_common_types_cpp_shared",
+ ],
+
srcs: [
"AudioPolicyManager.cpp",
"EngineLibrary.cpp",
@@ -36,7 +40,6 @@
"libaudiopolicyenginedefault",
"framework-permission-aidl-cpp",
"libaudioclient_aidl_conversion",
- "android.media.audio.common.types-V1-cpp",
"audioclient-types-aidl-cpp",
],
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 4573382..2938b14 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -68,16 +68,6 @@
// media / notification / system volume.
constexpr float IN_CALL_EARPIECE_HEADROOM_DB = 3.f;
-// Compressed formats for MSD module, ordered from most preferred to least preferred.
-static const std::vector<audio_format_t> msdCompressedFormatsOrder = {{
- AUDIO_FORMAT_IEC60958, AUDIO_FORMAT_MAT_2_1, AUDIO_FORMAT_MAT_2_0, AUDIO_FORMAT_E_AC3,
- AUDIO_FORMAT_AC3, AUDIO_FORMAT_PCM_16_BIT }};
-// Channel masks for MSD module, 3D > 2D > 1D ordering (most preferred to least preferred).
-static const std::vector<audio_channel_mask_t> msdSurroundChannelMasksOrder = {{
- AUDIO_CHANNEL_OUT_3POINT1POINT2, AUDIO_CHANNEL_OUT_3POINT0POINT2,
- AUDIO_CHANNEL_OUT_2POINT1POINT2, AUDIO_CHANNEL_OUT_2POINT0POINT2,
- AUDIO_CHANNEL_OUT_5POINT1, AUDIO_CHANNEL_OUT_STEREO }};
-
template <typename T>
bool operator== (const SortedVector<T> &left, const SortedVector<T> &right)
{
@@ -114,7 +104,7 @@
const char* device_address,
const char* device_name,
audio_format_t encodedFormat) {
- media::AudioPort aidlPort;
+ media::AudioPortFw aidlPort;
if (status_t status = deviceToAudioPort(device, device_address, device_name, &aidlPort);
status == OK) {
return setDeviceConnectionState(state, aidlPort.hal, encodedFormat);
@@ -140,8 +130,6 @@
status_t AudioPolicyManager::setDeviceConnectionStateInt(
audio_policy_dev_state_t state, const android::media::audio::common::AudioPort& port,
audio_format_t encodedFormat) {
- // TODO: b/211601178 Forward 'port' to Audio HAL via mHwModules. For now, only device_type,
- // device_address and device_name are forwarded.
if (port.ext.getTag() != AudioPortExt::device) {
return BAD_VALUE;
}
@@ -160,7 +148,13 @@
sp<DeviceDescriptor> device = mHwModules.getDeviceDescriptor(
device_type, device_address.c_str(), device_name, encodedFormat,
state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
- return device ? setDeviceConnectionStateInt(device, state) : INVALID_OPERATION;
+ if (device == nullptr) {
+ return INVALID_OPERATION;
+ }
+ if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
+ device->setExtraAudioDescriptors(port.extraAudioDescriptors);
+ }
+ return setDeviceConnectionStateInt(device, state);
}
status_t AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t deviceType,
@@ -168,7 +162,7 @@
const char* device_address,
const char* device_name,
audio_format_t encodedFormat) {
- media::AudioPort aidlPort;
+ media::AudioPortFw aidlPort;
if (status_t status = deviceToAudioPort(deviceType, device_address, device_name, &aidlPort);
status == OK) {
return setDeviceConnectionStateInt(state, aidlPort.hal, encodedFormat);
@@ -450,7 +444,7 @@
status_t AudioPolicyManager::deviceToAudioPort(audio_devices_t device, const char* device_address,
const char* device_name,
- media::AudioPort* aidlPort) {
+ media::AudioPortFw* aidlPort) {
DeviceDescriptorBase devDescr(device, device_address);
devDescr.setName(device_name);
return devDescr.writeToParcelable(aidlPort);
@@ -1641,10 +1635,28 @@
const AudioProfileVector &sourceProfiles, const AudioProfileVector &sinkProfiles,
audio_port_config *sourceConfig, audio_port_config *sinkConfig) const
{
+ // Compressed formats for MSD module, ordered from most preferred to least preferred.
+ static const std::vector<audio_format_t> formatsOrder = {{
+ AUDIO_FORMAT_IEC60958, AUDIO_FORMAT_MAT_2_1, AUDIO_FORMAT_MAT_2_0, AUDIO_FORMAT_E_AC3,
+ AUDIO_FORMAT_AC3, AUDIO_FORMAT_PCM_16_BIT }};
+ static const std::vector<audio_channel_mask_t> channelMasksOrder = [](){
+ // Channel position masks for MSD module, 3D > 2D > 1D ordering (most preferred to least
+ // preferred).
+ std::vector<audio_channel_mask_t> masks = {{
+ AUDIO_CHANNEL_OUT_3POINT1POINT2, AUDIO_CHANNEL_OUT_3POINT0POINT2,
+ AUDIO_CHANNEL_OUT_2POINT1POINT2, AUDIO_CHANNEL_OUT_2POINT0POINT2,
+ AUDIO_CHANNEL_OUT_5POINT1, AUDIO_CHANNEL_OUT_STEREO }};
+ // insert index masks (higher counts most preferred) as preferred over position masks
+ for (int i = 1; i <= AUDIO_CHANNEL_COUNT_MAX; i++) {
+ masks.insert(
+ masks.begin(), audio_channel_mask_for_index_assignment_from_count(i));
+ }
+ return masks;
+ }();
+
struct audio_config_base bestSinkConfig;
- status_t result = findBestMatchingOutputConfig(sourceProfiles, sinkProfiles,
- msdCompressedFormatsOrder, msdSurroundChannelMasksOrder,
- true /*preferHigherSamplingRates*/, bestSinkConfig);
+ status_t result = findBestMatchingOutputConfig(sourceProfiles, sinkProfiles, formatsOrder,
+ channelMasksOrder, true /*preferHigherSamplingRates*/, bestSinkConfig);
if (result != NO_ERROR) {
ALOGD("%s() no matching config found for sink, hwAvSync: %d",
__func__, hwAvSync);
@@ -1666,7 +1678,10 @@
}
sourceConfig->sample_rate = bestSinkConfig.sample_rate;
// Specify exact channel mask to prevent guessing by bit count in PatchPanel.
- sourceConfig->channel_mask = audio_channel_mask_out_to_in(bestSinkConfig.channel_mask);
+ sourceConfig->channel_mask =
+ audio_channel_mask_get_representation(bestSinkConfig.channel_mask)
+ == AUDIO_CHANNEL_REPRESENTATION_INDEX ?
+ bestSinkConfig.channel_mask : audio_channel_mask_out_to_in(bestSinkConfig.channel_mask);
sourceConfig->format = bestSinkConfig.format;
// Copy input stream directly without any processing (e.g. resampling).
sourceConfig->flags.input = static_cast<audio_input_flags_t>(
@@ -3159,7 +3174,7 @@
// stream by the engine.
DeviceTypeSet deviceTypes = {device};
if (device == AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME) {
- DeviceTypeSet deviceTypes = mEngine->getOutputDevicesForAttributes(
+ deviceTypes = mEngine->getOutputDevicesForAttributes(
attr, nullptr, true /*fromCache*/).types();
}
return getVolumeIndex(getVolumeCurves(attr), index, deviceTypes);
@@ -3169,7 +3184,7 @@
int &index,
const DeviceTypeSet& deviceTypes) const
{
- if (isSingleDeviceType(deviceTypes, audio_is_output_device)) {
+ if (!isSingleDeviceType(deviceTypes, audio_is_output_device)) {
return BAD_VALUE;
}
index = curves.getVolumeIndex(deviceTypes);
@@ -7857,6 +7872,9 @@
addOutput(output, desc);
+ sp<DeviceDescriptor> speaker = mAvailableOutputDevices.getDevice(
+ AUDIO_DEVICE_OUT_SPEAKER, String8(""), AUDIO_FORMAT_DEFAULT);
+
if (audio_is_remote_submix_device(deviceType) && address != "0") {
sp<AudioPolicyMix> policyMix;
if (mPolicyMixes.getAudioPolicyMix(deviceType, address, policyMix) == NO_ERROR) {
@@ -7867,13 +7885,13 @@
address.string());
}
- } else if (hasPrimaryOutput() && profile->getModule()
- != mHwModules.getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY)
+ } else if (hasPrimaryOutput() && speaker != nullptr
+ && mPrimaryOutput->supportsDevice(speaker) && !desc->supportsDevice(speaker)
&& ((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0)) {
// no duplicated output for:
// - direct outputs
// - outputs used by dynamic policy mixes
- // - outputs opened on the primary HW module
+ // - outputs that supports SPEAKER while the primary output does not.
audio_io_handle_t duplicatedOutput = AUDIO_IO_HANDLE_NONE;
//TODO: configure audio effect output stage here
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index a69e088..8466d097 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -1016,7 +1016,7 @@
// Called by setDeviceConnectionState()
status_t deviceToAudioPort(audio_devices_t deviceType, const char* device_address,
- const char* device_name, media::AudioPort* aidPort);
+ const char* device_name, media::AudioPortFw* aidPort);
bool isMsdPatch(const audio_patch_handle_t &handle) const;
private:
diff --git a/services/audiopolicy/service/Android.bp b/services/audiopolicy/service/Android.bp
index cdad9a6..4c19d40 100644
--- a/services/audiopolicy/service/Android.bp
+++ b/services/audiopolicy/service/Android.bp
@@ -10,6 +10,10 @@
cc_library_shared {
name: "libaudiopolicyservice",
+ defaults: [
+ "latest_android_media_audio_common_types_cpp_shared",
+ ],
+
srcs: [
"AudioPolicyClientImpl.cpp",
"AudioPolicyEffects.cpp",
@@ -49,7 +53,6 @@
"libshmemcompat",
"libutils",
"libstagefright_foundation",
- "android.media.audio.common.types-V1-cpp",
"audioclient-types-aidl-cpp",
"audioflinger-aidl-cpp",
"audiopolicy-aidl-cpp",
diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp
index 70fdfcb..c7a60c2 100644
--- a/services/audiopolicy/service/AudioPolicyEffects.cpp
+++ b/services/audiopolicy/service/AudioPolicyEffects.cpp
@@ -127,7 +127,8 @@
attributionSource.packageName = "android";
attributionSource.token = sp<BBinder>::make();
sp<AudioEffect> fx = new AudioEffect(attributionSource);
- fx->set(NULL, &effect->mUuid, -1, 0, 0, audioSession, input);
+ fx->set(nullptr /*type */, &effect->mUuid, -1 /* priority */, nullptr /* callback */,
+ audioSession, input);
status_t status = fx->initCheck();
if (status != NO_ERROR && status != ALREADY_EXISTS) {
ALOGW("addInputEffects(): failed to create Fx %s on source %d",
@@ -279,7 +280,8 @@
attributionSource.packageName = "android";
attributionSource.token = sp<BBinder>::make();
sp<AudioEffect> fx = new AudioEffect(attributionSource);
- fx->set(NULL, &effect->mUuid, 0, 0, 0, audioSession, output);
+ fx->set(nullptr /* type */, &effect->mUuid, 0 /* priority */, nullptr /* callback */,
+ audioSession, output);
status_t status = fx->initCheck();
if (status != NO_ERROR && status != ALREADY_EXISTS) {
ALOGE("addOutputSessionEffects(): failed to create Fx %s on session %d",
@@ -984,8 +986,8 @@
attributionSource.packageName = "android";
attributionSource.token = sp<BBinder>::make();
sp<AudioEffect> fx = new AudioEffect(attributionSource);
- fx->set(EFFECT_UUID_NULL, &effectDesc->mUuid, 0, nullptr,
- nullptr, AUDIO_SESSION_DEVICE, AUDIO_IO_HANDLE_NONE,
+ fx->set(EFFECT_UUID_NULL, &effectDesc->mUuid, 0 /* priority */, nullptr /* callback */,
+ AUDIO_SESSION_DEVICE, AUDIO_IO_HANDLE_NONE,
AudioDeviceTypeAddr{deviceEffects->getDeviceType(),
deviceEffects->getDeviceAddress()});
status_t status = fx->initCheck();
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 49224c5..fdf5787 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -1485,7 +1485,7 @@
Status AudioPolicyService::listAudioPorts(media::AudioPortRole roleAidl,
media::AudioPortType typeAidl, Int* count,
- std::vector<media::AudioPort>* portsAidl,
+ std::vector<media::AudioPortFw>* portsAidl,
int32_t* _aidl_return) {
audio_port_role_t role = VALUE_OR_RETURN_BINDER_STATUS(
aidl2legacy_AudioPortRole_audio_port_role_t(roleAidl));
@@ -1510,14 +1510,14 @@
numPortsReq = std::min(numPortsReq, num_ports);
RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(
convertRange(ports.get(), ports.get() + numPortsReq, std::back_inserter(*portsAidl),
- legacy2aidl_audio_port_v7_AudioPort)));
+ legacy2aidl_audio_port_v7_AudioPortFw)));
count->value = VALUE_OR_RETURN_BINDER_STATUS(convertIntegral<int32_t>(num_ports));
*_aidl_return = VALUE_OR_RETURN_BINDER_STATUS(convertIntegral<int32_t>(generation));
return Status::ok();
}
Status AudioPolicyService::getAudioPort(int portId,
- media::AudioPort* _aidl_return) {
+ media::AudioPortFw* _aidl_return) {
audio_port_v7 port{ .id = portId };
Mutex::Autolock _l(mLock);
if (mAudioPolicyManager == NULL) {
@@ -1525,14 +1525,15 @@
}
AutoCallerClear acc;
RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(mAudioPolicyManager->getAudioPort(&port)));
- *_aidl_return = VALUE_OR_RETURN_BINDER_STATUS(legacy2aidl_audio_port_v7_AudioPort(port));
+ *_aidl_return = VALUE_OR_RETURN_BINDER_STATUS(legacy2aidl_audio_port_v7_AudioPortFw(port));
return Status::ok();
}
-Status AudioPolicyService::createAudioPatch(const media::AudioPatch& patchAidl, int32_t handleAidl,
+Status AudioPolicyService::createAudioPatch(const media::AudioPatchFw& patchAidl,
+ int32_t handleAidl,
int32_t* _aidl_return) {
audio_patch patch = VALUE_OR_RETURN_BINDER_STATUS(
- aidl2legacy_AudioPatch_audio_patch(patchAidl));
+ aidl2legacy_AudioPatchFw_audio_patch(patchAidl));
audio_patch_handle_t handle = VALUE_OR_RETURN_BINDER_STATUS(
aidl2legacy_int32_t_audio_port_handle_t(handleAidl));
RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(AudioValidator::validateAudioPatch(patch)));
@@ -1570,7 +1571,7 @@
}
Status AudioPolicyService::listAudioPatches(Int* count,
- std::vector<media::AudioPatch>* patchesAidl,
+ std::vector<media::AudioPatchFw>* patchesAidl,
int32_t* _aidl_return) {
unsigned int num_patches = VALUE_OR_RETURN_BINDER_STATUS(
convertIntegral<unsigned int>(count->value));
@@ -1591,16 +1592,16 @@
numPatchesReq = std::min(numPatchesReq, num_patches);
RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(
convertRange(patches.get(), patches.get() + numPatchesReq,
- std::back_inserter(*patchesAidl), legacy2aidl_audio_patch_AudioPatch)));
+ std::back_inserter(*patchesAidl), legacy2aidl_audio_patch_AudioPatchFw)));
count->value = VALUE_OR_RETURN_BINDER_STATUS(convertIntegral<int32_t>(num_patches));
*_aidl_return = VALUE_OR_RETURN_BINDER_STATUS(convertIntegral<int32_t>(generation));
return Status::ok();
}
-Status AudioPolicyService::setAudioPortConfig(const media::AudioPortConfig& configAidl)
+Status AudioPolicyService::setAudioPortConfig(const media::AudioPortConfigFw& configAidl)
{
audio_port_config config = VALUE_OR_RETURN_BINDER_STATUS(
- aidl2legacy_AudioPortConfig_audio_port_config(configAidl));
+ aidl2legacy_AudioPortConfigFw_audio_port_config(configAidl));
RETURN_IF_BINDER_ERROR(
binderStatusFromStatusT(AudioValidator::validateAudioPortConfig(config)));
@@ -1770,11 +1771,11 @@
return binderStatusFromStatusT(mAudioPolicyManager->removeUserIdDeviceAffinities(userId));
}
-Status AudioPolicyService::startAudioSource(const media::AudioPortConfig& sourceAidl,
+Status AudioPolicyService::startAudioSource(const media::AudioPortConfigFw& sourceAidl,
const media::AudioAttributesInternal& attributesAidl,
int32_t* _aidl_return) {
audio_port_config source = VALUE_OR_RETURN_BINDER_STATUS(
- aidl2legacy_AudioPortConfig_audio_port_config(sourceAidl));
+ aidl2legacy_AudioPortConfigFw_audio_port_config(sourceAidl));
audio_attributes_t attributes = VALUE_OR_RETURN_BINDER_STATUS(
aidl2legacy_AudioAttributesInternal_audio_attributes_t(attributesAidl));
audio_port_handle_t portId;
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index 70349c2..09b6f3b 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -1733,6 +1733,7 @@
}
bool AudioPolicyService::UidPolicy::isA11yOnTop() {
+ Mutex::Autolock _l(mLock);
for (const auto &uid : mCachedUids) {
if (!isA11yUid(uid.first)) {
continue;
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index a87d871..860bd18 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -172,16 +172,16 @@
const media::AudioAttributesInternal& attributes,
bool* _aidl_return) override;
binder::Status listAudioPorts(media::AudioPortRole role, media::AudioPortType type,
- Int* count, std::vector<media::AudioPort>* ports,
+ Int* count, std::vector<media::AudioPortFw>* ports,
int32_t* _aidl_return) override;
binder::Status getAudioPort(int portId,
- media::AudioPort* _aidl_return) override;
- binder::Status createAudioPatch(const media::AudioPatch& patch, int32_t handle,
+ media::AudioPortFw* _aidl_return) override;
+ binder::Status createAudioPatch(const media::AudioPatchFw& patch, int32_t handle,
int32_t* _aidl_return) override;
binder::Status releaseAudioPatch(int32_t handle) override;
- binder::Status listAudioPatches(Int* count, std::vector<media::AudioPatch>* patches,
+ binder::Status listAudioPatches(Int* count, std::vector<media::AudioPatchFw>* patches,
int32_t* _aidl_return) override;
- binder::Status setAudioPortConfig(const media::AudioPortConfig& config) override;
+ binder::Status setAudioPortConfig(const media::AudioPortConfigFw& config) override;
binder::Status registerClient(const sp<media::IAudioPolicyServiceClient>& client) override;
binder::Status setAudioPortCallbacksEnabled(bool enabled) override;
binder::Status setAudioVolumeGroupCallbacksEnabled(bool enabled) override;
@@ -197,7 +197,7 @@
int32_t userId,
const std::vector<AudioDevice>& devices) override;
binder::Status removeUserIdDeviceAffinities(int32_t userId) override;
- binder::Status startAudioSource(const media::AudioPortConfig& source,
+ binder::Status startAudioSource(const media::AudioPortConfigFw& source,
const media::AudioAttributesInternal& attributes,
int32_t* _aidl_return) override;
binder::Status stopAudioSource(int32_t portId) override;
@@ -475,8 +475,8 @@
Mutex mLock;
ActivityManager mAm;
bool mObserverRegistered = false;
- std::unordered_map<uid_t, std::pair<bool, int>> mOverrideUids;
- std::unordered_map<uid_t, std::pair<bool, int>> mCachedUids;
+ std::unordered_map<uid_t, std::pair<bool, int>> mOverrideUids GUARDED_BY(mLock);
+ std::unordered_map<uid_t, std::pair<bool, int>> mCachedUids GUARDED_BY(mLock);
std::vector<uid_t> mAssistantUids;
std::vector<uid_t> mActiveAssistantUids;
std::vector<uid_t> mA11yUids;
diff --git a/services/audiopolicy/service/Spatializer.h b/services/audiopolicy/service/Spatializer.h
index 7415b1e..0f6bafe 100644
--- a/services/audiopolicy/service/Spatializer.h
+++ b/services/audiopolicy/service/Spatializer.h
@@ -23,6 +23,7 @@
#include <android/media/SpatializationLevel.h>
#include <android/media/SpatializationMode.h>
#include <android/media/SpatializerHeadTrackingMode.h>
+#include <android/media/audio/common/AudioLatencyMode.h>
#include <audio_utils/SimpleLog.h>
#include <math.h>
#include <media/AudioEffect.h>
@@ -166,8 +167,9 @@
static std::string toString(audio_latency_mode_t mode) {
// We convert to the AIDL type to print (eventually the legacy type will be removed).
- const auto result = legacy2aidl_audio_latency_mode_t_LatencyMode(mode);
- return result.has_value() ? media::toString(*result) : "unknown_latency_mode";
+ const auto result = legacy2aidl_audio_latency_mode_t_AudioLatencyMode(mode);
+ return result.has_value() ?
+ media::audio::common::toString(*result) : "unknown_latency_mode";
}
/**
diff --git a/services/audiopolicy/tests/Android.bp b/services/audiopolicy/tests/Android.bp
index 2e220bc..6813587 100644
--- a/services/audiopolicy/tests/Android.bp
+++ b/services/audiopolicy/tests/Android.bp
@@ -10,6 +10,10 @@
cc_test {
name: "audiopolicy_tests",
+ defaults: [
+ "latest_android_media_audio_common_types_cpp_static",
+ ],
+
include_dirs: [
"frameworks/av/services/audiopolicy",
],
@@ -30,6 +34,7 @@
],
static_libs: [
+ "audioclient-types-aidl-cpp",
"libaudiopolicycomponents",
"libgmock",
],
@@ -56,6 +61,11 @@
cc_test {
name: "audio_health_tests",
+
+ defaults: [
+ "latest_android_media_audio_common_types_cpp_shared",
+ ],
+
require_root: true,
shared_libs: [
@@ -65,7 +75,6 @@
"liblog",
"libmedia_helper",
"libutils",
- "android.media.audio.common.types-V1-cpp",
"libaudioclient_aidl_conversion",
"libstagefright_foundation",
"libshmemcompat",
diff --git a/services/audiopolicy/tests/AudioPolicyManagerTestClient.h b/services/audiopolicy/tests/AudioPolicyManagerTestClient.h
index 057fa58..96f58d2 100644
--- a/services/audiopolicy/tests/AudioPolicyManagerTestClient.h
+++ b/services/audiopolicy/tests/AudioPolicyManagerTestClient.h
@@ -103,8 +103,12 @@
++mAudioPortListUpdateCount;
}
- status_t setDeviceConnectedState(
- const struct audio_port_v7 *port __unused, bool connected __unused) override {
+ status_t setDeviceConnectedState(const struct audio_port_v7 *port, bool connected) override {
+ if (connected) {
+ mConnectedDevicePorts.push_back(*port);
+ } else {
+ mDisconnectedDevicePorts.push_back(*port);
+ }
return NO_ERROR;
}
@@ -150,6 +154,30 @@
return NO_ERROR;
}
+ size_t getConnectedDevicePortCount() const {
+ return mConnectedDevicePorts.size();
+ }
+
+ const struct audio_port_v7 *getLastConnectedDevicePort() const {
+ if (mConnectedDevicePorts.empty()) {
+ return nullptr;
+ }
+ auto it = --mConnectedDevicePorts.end();
+ return &(*it);
+ }
+
+ size_t getDisconnectedDevicePortCount() const {
+ return mDisconnectedDevicePorts.size();
+ }
+
+ const struct audio_port_v7 *getLastDisconnectedDevicePort() const {
+ if (mDisconnectedDevicePorts.empty()) {
+ return nullptr;
+ }
+ auto it = --mDisconnectedDevicePorts.end();
+ return &(*it);
+ }
+
private:
audio_module_handle_t mNextModuleHandle = AUDIO_MODULE_HANDLE_NONE + 1;
audio_io_handle_t mNextIoHandle = AUDIO_IO_HANDLE_NONE + 1;
@@ -158,6 +186,8 @@
std::set<std::string> mAllowedModuleNames;
size_t mAudioPortListUpdateCount = 0;
size_t mRoutingUpdatedUpdateCount = 0;
+ std::vector<struct audio_port_v7> mConnectedDevicePorts;
+ std::vector<struct audio_port_v7> mDisconnectedDevicePorts;
};
} // namespace android
diff --git a/services/audiopolicy/tests/AudioPolicyTestManager.h b/services/audiopolicy/tests/AudioPolicyTestManager.h
index 7441f20..2a7a060 100644
--- a/services/audiopolicy/tests/AudioPolicyTestManager.h
+++ b/services/audiopolicy/tests/AudioPolicyTestManager.h
@@ -37,6 +37,7 @@
using AudioPolicyManager::getDirectProfilesForAttributes;
using AudioPolicyManager::setDeviceConnectionState;
using AudioPolicyManager::deviceToAudioPort;
+ using AudioPolicyManager::handleDeviceConfigChange;
uint32_t getAudioPortGeneration() const { return mAudioPortGeneration; }
};
diff --git a/services/audiopolicy/tests/audio_health_tests.cpp b/services/audiopolicy/tests/audio_health_tests.cpp
index 10f8dc0..798332c 100644
--- a/services/audiopolicy/tests/audio_health_tests.cpp
+++ b/services/audiopolicy/tests/audio_health_tests.cpp
@@ -111,7 +111,7 @@
continue;
}
std::string address = "11:22:33:44:55:66";
- media::AudioPort aidlPort;
+ media::AudioPortFw aidlPort;
ASSERT_EQ(OK, manager.deviceToAudioPort(device->type(), address.c_str(), "" /*name*/,
&aidlPort));
ASSERT_EQ(AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
diff --git a/services/audiopolicy/tests/audiopolicymanager_tests.cpp b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
index 43b1a2a..1c40cfd 100644
--- a/services/audiopolicy/tests/audiopolicymanager_tests.cpp
+++ b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
@@ -42,6 +42,32 @@
using testing::UnorderedElementsAre;
using android::content::AttributionSourceState;
+namespace {
+
+AudioMixMatchCriterion createUidCriterion(uint32_t uid, bool exclude = false) {
+ AudioMixMatchCriterion criterion;
+ criterion.mValue.mUid = uid;
+ criterion.mRule = exclude ? RULE_EXCLUDE_UID : RULE_MATCH_UID;
+ return criterion;
+}
+
+AudioMixMatchCriterion createUsageCriterion(audio_usage_t usage, bool exclude = false) {
+ AudioMixMatchCriterion criterion;
+ criterion.mValue.mUsage = usage;
+ criterion.mRule = exclude ? RULE_EXCLUDE_ATTRIBUTE_USAGE : RULE_MATCH_ATTRIBUTE_USAGE;
+ return criterion;
+}
+
+AudioMixMatchCriterion createCapturePresetCriterion(audio_source_t source, bool exclude = false) {
+ AudioMixMatchCriterion criterion;
+ criterion.mValue.mSource = source;
+ criterion.mRule = exclude ?
+ RULE_EXCLUDE_ATTRIBUTE_CAPTURE_PRESET : RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET;
+ return criterion;
+}
+
+} // namespace
+
TEST(AudioPolicyManagerTestInit, EngineFailure) {
AudioPolicyTestClient client;
AudioPolicyTestManager manager(&client);
@@ -420,7 +446,7 @@
sp<AudioProfile> ac3OutputProfile = new AudioProfile(
AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1, k48000SamplingRate);
sp<AudioProfile> iec958OutputProfile = new AudioProfile(
- AUDIO_FORMAT_IEC60958, AUDIO_CHANNEL_OUT_STEREO, k48000SamplingRate);
+ AUDIO_FORMAT_IEC60958, AUDIO_CHANNEL_INDEX_MASK_24, k48000SamplingRate);
mMsdOutputDevice->addAudioProfile(pcmOutputProfile);
mMsdOutputDevice->addAudioProfile(ac3OutputProfile);
mMsdOutputDevice->addAudioProfile(iec958OutputProfile);
@@ -493,7 +519,7 @@
// Add HDMI input device with IEC60958 profile for HDMI in -> MSD patching.
mHdmiInputDevice = new DeviceDescriptor(AUDIO_DEVICE_IN_HDMI);
sp<AudioProfile> iec958InputProfile = new AudioProfile(
- AUDIO_FORMAT_IEC60958, AUDIO_CHANNEL_IN_STEREO, k48000SamplingRate);
+ AUDIO_FORMAT_IEC60958, AUDIO_CHANNEL_INDEX_MASK_24, k48000SamplingRate);
mHdmiInputDevice->addAudioProfile(iec958InputProfile);
config.addDevice(mHdmiInputDevice);
sp<InputProfile> hdmiInputProfile = new InputProfile("hdmi input");
@@ -651,8 +677,8 @@
ASSERT_EQ(AUDIO_PORT_ROLE_SINK, patch->mPatch.sinks[0].role);
ASSERT_EQ(AUDIO_FORMAT_IEC60958, patch->mPatch.sources[0].format);
ASSERT_EQ(AUDIO_FORMAT_IEC60958, patch->mPatch.sinks[0].format);
- ASSERT_EQ(AUDIO_CHANNEL_IN_STEREO, patch->mPatch.sources[0].channel_mask);
- ASSERT_EQ(AUDIO_CHANNEL_OUT_STEREO, patch->mPatch.sinks[0].channel_mask);
+ ASSERT_EQ(AUDIO_CHANNEL_INDEX_MASK_24, patch->mPatch.sources[0].channel_mask);
+ ASSERT_EQ(AUDIO_CHANNEL_INDEX_MASK_24, patch->mPatch.sinks[0].channel_mask);
ASSERT_EQ(k48000SamplingRate, patch->mPatch.sources[0].sample_rate);
ASSERT_EQ(k48000SamplingRate, patch->mPatch.sinks[0].sample_rate);
ASSERT_EQ(1, patchCount.deltaFromSnapshot());
@@ -728,7 +754,7 @@
audio_config_base_t msdDirectConfig2 = AUDIO_CONFIG_BASE_INITIALIZER;
msdDirectConfig2.format = AUDIO_FORMAT_IEC60958;
msdDirectConfig2.sample_rate = 48000;
- msdDirectConfig2.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+ msdDirectConfig2.channel_mask = AUDIO_CHANNEL_INDEX_MASK_24;
audio_config_base_t msdNonDirectConfig = AUDIO_CONFIG_BASE_INITIALIZER;
msdNonDirectConfig.format = AUDIO_FORMAT_PCM_16_BIT;
@@ -795,7 +821,7 @@
audio_config_t msdDirectConfig2 = AUDIO_CONFIG_INITIALIZER;
msdDirectConfig2.format = AUDIO_FORMAT_IEC60958;
msdDirectConfig2.sample_rate = 48000;
- msdDirectConfig2.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+ msdDirectConfig2.channel_mask = AUDIO_CHANNEL_INDEX_MASK_24;
audio_config_t msdNonDirectConfig = AUDIO_CONFIG_INITIALIZER;
msdNonDirectConfig.format = AUDIO_FORMAT_PCM_16_BIT;
@@ -919,7 +945,29 @@
EXPECT_TRUE(foundVoipTx);
}
-using PolicyMixTuple = std::tuple<audio_usage_t, audio_source_t, uint32_t>;
+TEST_F(AudioPolicyManagerTestWithConfigurationFile, HandleDeviceConfigChange) {
+ {
+ const auto prevCounter = mClient->getRoutingUpdatedCounter();
+
+ EXPECT_EQ(NO_ERROR, mManager->setDeviceConnectionState(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP,
+ AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
+ "", "", AUDIO_FORMAT_LDAC));
+ const auto currCounter = mClient->getRoutingUpdatedCounter();
+ EXPECT_GT(currCounter, prevCounter);
+ }
+ {
+ const auto prevCounter = mClient->getRoutingUpdatedCounter();
+ // Update device configuration
+ EXPECT_EQ(NO_ERROR, mManager->handleDeviceConfigChange(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP,
+ "" /*address*/, "" /*name*/,
+ AUDIO_FORMAT_AAC));
+
+ // As mClient marks isReconfigA2dpSupported to false, device state needs to be toggled for
+ // config changes to take effect
+ const auto currCounter = mClient->getRoutingUpdatedCounter();
+ EXPECT_GT(currCounter, prevCounter);
+ }
+}
class AudioPolicyManagerTestDynamicPolicy : public AudioPolicyManagerTestWithConfigurationFile {
protected:
@@ -927,7 +975,7 @@
status_t addPolicyMix(int mixType, int mixFlag, audio_devices_t deviceType,
std::string mixAddress, const audio_config_t& audioConfig,
- const std::vector<PolicyMixTuple>& rules);
+ const std::vector<AudioMixMatchCriterion>& matchCriteria);
void clearPolicyMix();
Vector<AudioMix> mAudioMixes;
@@ -941,15 +989,8 @@
status_t AudioPolicyManagerTestDynamicPolicy::addPolicyMix(int mixType, int mixFlag,
audio_devices_t deviceType, std::string mixAddress, const audio_config_t& audioConfig,
- const std::vector<PolicyMixTuple>& rules) {
- Vector<AudioMixMatchCriterion> myMixMatchCriteria;
-
- for(const auto &rule: rules) {
- myMixMatchCriteria.add(AudioMixMatchCriterion(
- std::get<0>(rule), std::get<1>(rule), std::get<2>(rule)));
- }
-
- AudioMix myAudioMix(myMixMatchCriteria, mixType, audioConfig, mixFlag,
+ const std::vector<AudioMixMatchCriterion>& matchCriteria = {}) {
+ AudioMix myAudioMix(matchCriteria, mixType, audioConfig, mixFlag,
String8(mixAddress.c_str()), 0);
myAudioMix.mDeviceType = deviceType;
// Clear mAudioMix before add new one to make sure we don't add already exist mixes.
@@ -983,13 +1024,13 @@
// Only capture of playback is allowed in LOOP_BACK &RENDER mode
ret = addPolicyMix(MIX_TYPE_RECORDERS, MIX_ROUTE_FLAG_LOOP_BACK_AND_RENDER,
- AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "", audioConfig, std::vector<PolicyMixTuple>());
+ AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "", audioConfig);
ASSERT_EQ(INVALID_OPERATION, ret);
// Fail due to the device is already connected.
clearPolicyMix();
ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
- AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "", audioConfig, std::vector<PolicyMixTuple>());
+ AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "", audioConfig);
ASSERT_EQ(INVALID_OPERATION, ret);
// The first time to register policy mixes with valid parameter should succeed.
@@ -998,8 +1039,7 @@
audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
audioConfig.sample_rate = k48000SamplingRate;
ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
- AUDIO_DEVICE_OUT_REMOTE_SUBMIX, mMixAddress, audioConfig,
- std::vector<PolicyMixTuple>());
+ AUDIO_DEVICE_OUT_REMOTE_SUBMIX, mMixAddress, audioConfig);
ASSERT_EQ(NO_ERROR, ret);
// Registering the same policy mixes should fail.
ret = mManager->registerPolicyMixes(mAudioMixes);
@@ -1010,19 +1050,19 @@
// This will need to be updated if earpiece is added in the test configuration file.
clearPolicyMix();
ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
- AUDIO_DEVICE_OUT_EARPIECE, "", audioConfig, std::vector<PolicyMixTuple>());
+ AUDIO_DEVICE_OUT_EARPIECE, "", audioConfig);
ASSERT_EQ(INVALID_OPERATION, ret);
// Registration should fail due to output not found.
clearPolicyMix();
ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
- AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "", audioConfig, std::vector<PolicyMixTuple>());
+ AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "", audioConfig);
ASSERT_EQ(INVALID_OPERATION, ret);
// The first time to register valid policy mixes should succeed.
clearPolicyMix();
ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
- AUDIO_DEVICE_OUT_SPEAKER, "", audioConfig, std::vector<PolicyMixTuple>());
+ AUDIO_DEVICE_OUT_SPEAKER, "", audioConfig);
ASSERT_EQ(NO_ERROR, ret);
// Registering the same policy mixes should fail.
ret = mManager->registerPolicyMixes(mAudioMixes);
@@ -1037,8 +1077,7 @@
audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
audioConfig.sample_rate = k48000SamplingRate;
ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
- AUDIO_DEVICE_OUT_REMOTE_SUBMIX, mMixAddress, audioConfig,
- std::vector<PolicyMixTuple>());
+ AUDIO_DEVICE_OUT_REMOTE_SUBMIX, mMixAddress, audioConfig);
ASSERT_EQ(NO_ERROR, ret);
// After successfully registering policy mixes, it should be able to unregister.
@@ -1051,6 +1090,37 @@
ASSERT_EQ(INVALID_OPERATION, ret);
}
+TEST_F(AudioPolicyManagerTestDynamicPolicy, RegisterPolicyWithConsistentMixSucceeds) {
+ audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
+ audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+ audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
+ audioConfig.sample_rate = k48000SamplingRate;
+
+ std::vector<AudioMixMatchCriterion> mixMatchCriteria = {
+ createUidCriterion(/*uid=*/42),
+ createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/true)};
+ status_t ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
+ AUDIO_DEVICE_OUT_REMOTE_SUBMIX, mMixAddress, audioConfig,
+ mixMatchCriteria);
+ ASSERT_EQ(NO_ERROR, ret);
+}
+
+TEST_F(AudioPolicyManagerTestDynamicPolicy, RegisterPolicyWithInconsistentMixFails) {
+ audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
+ audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+ audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
+ audioConfig.sample_rate = k48000SamplingRate;
+
+ std::vector<AudioMixMatchCriterion> mixMatchCriteria = {
+ createUidCriterion(/*uid=*/42),
+ createUidCriterion(/*uid=*/1235, /*exclude=*/true),
+ createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/true)};
+ status_t ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
+ AUDIO_DEVICE_OUT_REMOTE_SUBMIX, mMixAddress, audioConfig,
+ mixMatchCriteria);
+ ASSERT_EQ(INVALID_OPERATION, ret);
+}
+
class AudioPolicyManagerTestForHdmi
: public AudioPolicyManagerTestWithConfigurationFile,
public testing::WithParamInterface<audio_format_t> {
@@ -1275,7 +1345,7 @@
audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
audioConfig.sample_rate = k48000SamplingRate;
ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_LOOP_BACK,
- AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "", audioConfig, std::vector<PolicyMixTuple>());
+ AUDIO_DEVICE_OUT_REMOTE_SUBMIX, "", audioConfig);
ASSERT_EQ(INVALID_OPERATION, ret);
ret = mManager->unregisterPolicyMixes(mAudioMixes);
@@ -1290,9 +1360,9 @@
std::unique_ptr<RecordingActivityTracker> mTracker;
- std::vector<PolicyMixTuple> mUsageRules = {
- {AUDIO_USAGE_MEDIA, AUDIO_SOURCE_DEFAULT, RULE_MATCH_ATTRIBUTE_USAGE},
- {AUDIO_USAGE_ALARM, AUDIO_SOURCE_DEFAULT, RULE_MATCH_ATTRIBUTE_USAGE}
+ std::vector<AudioMixMatchCriterion> mUsageRules = {
+ createUsageCriterion(AUDIO_USAGE_MEDIA),
+ createUsageCriterion(AUDIO_USAGE_ALARM)
};
struct audio_port_v7 mInjectionPort;
@@ -1352,9 +1422,10 @@
getOutputForAttr(&playbackRoutedPortId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
k48000SamplingRate, AUDIO_OUTPUT_FLAG_NONE, nullptr /*output*/, nullptr /*portId*/,
attr);
- if (std::find_if(begin(mUsageRules), end(mUsageRules), [&usage](const auto &usageRule) {
- return (std::get<0>(usageRule) == usage) &&
- (std::get<2>(usageRule) == RULE_MATCH_ATTRIBUTE_USAGE);}) != end(mUsageRules) ||
+ if (std::find_if(begin(mUsageRules), end(mUsageRules),
+ [&usage](const AudioMixMatchCriterion &c) {
+ return c.mRule == RULE_MATCH_ATTRIBUTE_USAGE &&
+ c.mValue.mUsage == usage;}) != end(mUsageRules) ||
(strncmp(attr.tags, "addr=", strlen("addr=")) == 0 &&
strncmp(attr.tags + strlen("addr="), mMixAddress.c_str(),
AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - strlen("addr=") - 1) == 0)) {
@@ -1475,10 +1546,10 @@
std::unique_ptr<RecordingActivityTracker> mTracker;
- std::vector<PolicyMixTuple> mSourceRules = {
- {AUDIO_USAGE_UNKNOWN, AUDIO_SOURCE_CAMCORDER, RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET},
- {AUDIO_USAGE_UNKNOWN, AUDIO_SOURCE_MIC, RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET},
- {AUDIO_USAGE_UNKNOWN, AUDIO_SOURCE_VOICE_COMMUNICATION, RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET}
+ std::vector<AudioMixMatchCriterion> mSourceRules = {
+ createCapturePresetCriterion(AUDIO_SOURCE_CAMCORDER),
+ createCapturePresetCriterion(AUDIO_SOURCE_MIC),
+ createCapturePresetCriterion(AUDIO_SOURCE_VOICE_COMMUNICATION)
};
struct audio_port_v7 mExtractionPort;
@@ -1538,9 +1609,10 @@
audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;
getInputForAttr(attr, mTracker->getRiid(), &captureRoutedPortId, AUDIO_FORMAT_PCM_16_BIT,
AUDIO_CHANNEL_IN_STEREO, k48000SamplingRate, AUDIO_INPUT_FLAG_NONE, &portId);
- if (std::find_if(begin(mSourceRules), end(mSourceRules), [&source](const auto &sourceRule) {
- return (std::get<1>(sourceRule) == source) &&
- (std::get<2>(sourceRule) == RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET);})
+ if (std::find_if(begin(mSourceRules), end(mSourceRules),
+ [&source](const AudioMixMatchCriterion &c) {
+ return c.mRule == RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET &&
+ c.mValue.mSource == source;})
!= end(mSourceRules)) {
EXPECT_EQ(mExtractionPort.id, captureRoutedPortId);
} else {
@@ -1700,6 +1772,45 @@
address.c_str(), name.c_str(), AUDIO_FORMAT_DEFAULT));
}
+android::media::audio::common::ExtraAudioDescriptor make_ExtraAudioDescriptor(
+ android::media::audio::common::AudioStandard audioStandard,
+ android::media::audio::common::AudioEncapsulationType audioEncapsulationType) {
+ android::media::audio::common::ExtraAudioDescriptor result;
+ result.standard = audioStandard;
+ result.audioDescriptor = {0xb4, 0xaf, 0x98, 0x1a};
+ result.encapsulationType = audioEncapsulationType;
+ return result;
+}
+
+TEST_P(AudioPolicyManagerTestDeviceConnection, PassingExtraAudioDescriptors) {
+ const audio_devices_t type = std::get<0>(GetParam());
+ if (!audio_device_is_digital(type)) {
+ // EADs are used only for HDMI devices.
+ GTEST_SKIP() << "Not a digital device type: " << audio_device_to_string(type);
+ }
+ const std::string name = std::get<1>(GetParam());
+ const std::string address = std::get<2>(GetParam());
+ android::media::AudioPortFw audioPort;
+ ASSERT_EQ(NO_ERROR,
+ mManager->deviceToAudioPort(type, address.c_str(), name.c_str(), &audioPort));
+ android::media::audio::common::AudioPort& port = audioPort.hal;
+ port.extraAudioDescriptors.push_back(make_ExtraAudioDescriptor(
+ android::media::audio::common::AudioStandard::EDID,
+ android::media::audio::common::AudioEncapsulationType::IEC61937));
+ const size_t lastConnectedDevicePortCount = mClient->getConnectedDevicePortCount();
+ const size_t lastDisconnectedDevicePortCount = mClient->getDisconnectedDevicePortCount();
+ EXPECT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
+ AUDIO_POLICY_DEVICE_STATE_AVAILABLE, port, AUDIO_FORMAT_DEFAULT));
+ EXPECT_EQ(lastConnectedDevicePortCount + 1, mClient->getConnectedDevicePortCount());
+ EXPECT_EQ(lastDisconnectedDevicePortCount, mClient->getDisconnectedDevicePortCount());
+ const audio_port_v7* devicePort = mClient->getLastConnectedDevicePort();
+ EXPECT_EQ(port.extraAudioDescriptors.size(), devicePort->num_extra_audio_descriptors);
+ EXPECT_EQ(AUDIO_STANDARD_EDID, devicePort->extra_audio_descriptors[0].standard);
+ EXPECT_EQ(AUDIO_ENCAPSULATION_TYPE_IEC61937,
+ devicePort->extra_audio_descriptors[0].encapsulation_type);
+ EXPECT_NE(0, devicePort->extra_audio_descriptors[0].descriptor[0]);
+}
+
INSTANTIATE_TEST_CASE_P(
DeviceConnectionState,
AudioPolicyManagerTestDeviceConnection,
@@ -1738,7 +1849,7 @@
audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
const std::string kTestBusMediaOutput = "bus0_media_out";
ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
- AUDIO_DEVICE_OUT_BUS, kTestBusMediaOutput, audioConfig, std::vector<PolicyMixTuple>());
+ AUDIO_DEVICE_OUT_BUS, kTestBusMediaOutput, audioConfig);
ASSERT_EQ(NO_ERROR, ret);
audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
diff --git a/services/audiopolicy/tests/resources/test_audio_policy_configuration.xml b/services/audiopolicy/tests/resources/test_audio_policy_configuration.xml
index 5e1822a..d342aea 100644
--- a/services/audiopolicy/tests/resources/test_audio_policy_configuration.xml
+++ b/services/audiopolicy/tests/resources/test_audio_policy_configuration.xml
@@ -71,6 +71,9 @@
<devicePort tagName="BT SCO Headset Mic" type="AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET"
role="source" address="hfp_client_in">
</devicePort>
+ <devicePort tagName="BT A2DP Out" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP" role="sink"
+ encodedFormats="AUDIO_FORMAT_LDAC AUDIO_FORMAT_APTX AUDIO_FORMAT_APTX_HD AUDIO_FORMAT_AAC AUDIO_FORMAT_SBC">
+ </devicePort>
</devicePorts>
<routes>
<route type="mix" sink="Speaker"
@@ -85,6 +88,8 @@
sources="mixport_bt_hfp_output,voip_rx"/>
<route type="mix" sink="mixport_bt_hfp_input"
sources="BT SCO Headset Mic"/>
+ <route type="mix" sink="BT A2DP Out"
+ sources="primary output"/>
</routes>
</module>
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index d87b630..a7c9bac 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -4023,7 +4023,7 @@
int toggleType __unused, int sensor __unused, bool enabled) {
{
Mutex::Autolock _l(mSensorPrivacyLock);
- mSensorPrivacyEnabled = mSpm.isToggleSensorPrivacyEnabled(SensorPrivacyManager::TOGGLE_SENSOR_CAMERA);
+ mSensorPrivacyEnabled = enabled;
}
// if sensor privacy is enabled then block all clients from accessing the camera
if (enabled) {
diff --git a/services/camera/libcameraservice/api1/client2/Parameters.cpp b/services/camera/libcameraservice/api1/client2/Parameters.cpp
index 123cd75..8b2af90 100644
--- a/services/camera/libcameraservice/api1/client2/Parameters.cpp
+++ b/services/camera/libcameraservice/api1/client2/Parameters.cpp
@@ -953,6 +953,12 @@
false);
if (availableVideoStabilizationModes.count > 1) {
+ for (size_t i = 0; i < availableVideoStabilizationModes.count; i++) {
+ if (availableVideoStabilizationModes.data.u8[i] ==
+ ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_ON) {
+ videoStabilizationOnSupported = true;
+ }
+ }
params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
CameraParameters::TRUE);
} else {
@@ -2373,9 +2379,11 @@
reqCropRegion, 4);
if (res != OK) return res;
- uint8_t reqVstabMode = videoStabilization ?
+ uint8_t reqVstabMode = videoStabilization ? videoStabilizationOnSupported ?
ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_ON :
+ ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_PREVIEW_STABILIZATION :
ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF;
+
res = request->update(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
&reqVstabMode, 1);
if (res != OK) return res;
diff --git a/services/camera/libcameraservice/api1/client2/Parameters.h b/services/camera/libcameraservice/api1/client2/Parameters.h
index cbe62a7..fd18a5d 100644
--- a/services/camera/libcameraservice/api1/client2/Parameters.h
+++ b/services/camera/libcameraservice/api1/client2/Parameters.h
@@ -147,6 +147,7 @@
bool recordingHint;
bool videoStabilization;
+ bool videoStabilizationOnSupported = false;
CameraParameters2 params;
String8 paramsFlattened;
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index 1f86414..214a5b7 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -947,8 +947,8 @@
std::vector<int> surfaceIds;
bool isDepthCompositeStream =
camera3::DepthCompositeStream::isDepthCompositeStream(surfaces[0]);
- bool isHeicCompisiteStream = camera3::HeicCompositeStream::isHeicCompositeStream(surfaces[0]);
- if (isDepthCompositeStream || isHeicCompisiteStream) {
+ bool isHeicCompositeStream = camera3::HeicCompositeStream::isHeicCompositeStream(surfaces[0]);
+ if (isDepthCompositeStream || isHeicCompositeStream) {
sp<CompositeStream> compositeStream;
if (isDepthCompositeStream) {
compositeStream = new camera3::DepthCompositeStream(mDevice, getRemoteCallback());
diff --git a/services/camera/libcameraservice/api2/HeicCompositeStream.cpp b/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
index 237ce5e..2cc8e33 100644
--- a/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
+++ b/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
@@ -931,7 +931,7 @@
tempOutputFile.str().c_str(), errno);
return NO_INIT;
}
- inputFrame.muxer = new MediaMuxer(inputFrame.fileFd, MediaMuxer::OUTPUT_FORMAT_HEIF);
+ inputFrame.muxer = MediaMuxer::create(inputFrame.fileFd, MediaMuxer::OUTPUT_FORMAT_HEIF);
if (inputFrame.muxer == nullptr) {
ALOGE("%s: Failed to create MediaMuxer for file fd %d",
__FUNCTION__, inputFrame.fileFd);
@@ -1601,7 +1601,7 @@
return OK;
}
-void HeicCompositeStream::initCopyRowFunction(int32_t width)
+void HeicCompositeStream::initCopyRowFunction([[maybe_unused]] int32_t width)
{
using namespace libyuv;
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index 788064e..2ac2776 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -586,7 +586,11 @@
std::lock_guard<std::mutex> lock(mInterfaceMutex);
mDeviceState = newState;
status_t res = OK;
- for (auto& provider : mProviders) {
+ // Make a copy of mProviders because we unlock mInterfaceMutex temporarily
+ // within the loop. It's possible that during the time mInterfaceMutex is
+ // unlocked, mProviders has changed.
+ auto providers = mProviders;
+ for (auto& provider : providers) {
ALOGV("%s: Notifying %s for new state 0x%" PRIx64,
__FUNCTION__, provider->mProviderName.c_str(), newState);
// b/199240726 Camera providers can for example try to add/remove
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index d033395..e631f8b 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -258,20 +258,28 @@
Mutex::Autolock l(mLock);
if (mStatus == STATUS_UNINITIALIZED) return res;
- if (mStatus == STATUS_ACTIVE ||
- (mStatus == STATUS_ERROR && mRequestThread != NULL)) {
- res = mRequestThread->clearRepeatingRequests();
- if (res != OK) {
- SET_ERR_L("Can't stop streaming");
- // Continue to close device even in case of error
- } else {
- res = waitUntilStateThenRelock(/*active*/ false, maxExpectedDuration);
+ if (mRequestThread != NULL) {
+ if (mStatus == STATUS_ACTIVE || mStatus == STATUS_ERROR) {
+ res = mRequestThread->clear();
if (res != OK) {
- SET_ERR_L("Timeout waiting for HAL to drain (% " PRIi64 " ns)",
- maxExpectedDuration);
+ SET_ERR_L("Can't stop streaming");
// Continue to close device even in case of error
+ } else {
+ res = waitUntilStateThenRelock(/*active*/ false, maxExpectedDuration);
+ if (res != OK) {
+ SET_ERR_L("Timeout waiting for HAL to drain (% " PRIi64 " ns)",
+ maxExpectedDuration);
+ // Continue to close device even in case of error
+ }
}
}
+ // Signal to request thread that we're not expecting any
+ // more requests. This will be true since once we're in
+ // disconnect and we've cleared off the request queue, the
+ // request thread can't receive any new requests through
+ // binder calls - since disconnect holds
+ // mBinderSerialization lock.
+ mRequestThread->setRequestClearing();
}
if (mStatus == STATUS_ERROR) {
@@ -3060,7 +3068,8 @@
}
-status_t Camera3Device::RequestThread::clearRepeatingRequestsLocked(/*out*/int64_t *lastFrameNumber) {
+status_t Camera3Device::RequestThread::clearRepeatingRequestsLocked(
+ /*out*/int64_t *lastFrameNumber) {
std::vector<int32_t> streamIds;
for (const auto& request : mRepeatingRequests) {
for (const auto& stream : request->mOutputStreams) {
@@ -3085,8 +3094,6 @@
Mutex::Autolock l(mRequestLock);
ALOGV("RequestThread::%s:", __FUNCTION__);
- mRepeatingRequests.clear();
-
// Send errors for all requests pending in the request queue, including
// pending repeating requests
sp<NotificationListener> listener = mListener.promote();
@@ -3124,10 +3131,7 @@
Mutex::Autolock al(mTriggerMutex);
mTriggerMap.clear();
- if (lastFrameNumber != NULL) {
- *lastFrameNumber = mRepeatingLastFrameNumber;
- }
- mRepeatingLastFrameNumber = hardware::camera2::ICameraDeviceUser::NO_IN_FLIGHT_REPEATING_FRAMES;
+ clearRepeatingRequestsLocked(lastFrameNumber);
mRequestClearing = true;
mRequestSignal.signal();
return OK;
@@ -4252,6 +4256,11 @@
return;
}
+void Camera3Device::RequestThread::setRequestClearing() {
+ Mutex::Autolock l(mRequestLock);
+ mRequestClearing = true;
+}
+
sp<Camera3Device::CaptureRequest>
Camera3Device::RequestThread::waitForNextRequestLocked() {
status_t res;
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index cd214f6..a6d2eb3 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -466,6 +466,28 @@
// Verify buffer caches
std::vector<uint64_t> bufIds(offlineStream.circulatingBufferIds.begin(),
offlineStream.circulatingBufferIds.end());
+ {
+ // Due to timing it is possible that we may not have any remaining pending
+ // capture requests that can update the caches on Hal side. This can result in
+ // buffer cache mismatch between the service and the Hal and must be accounted
+ // for.
+ std::lock_guard<std::mutex> l(mFreedBuffersLock);
+ for (const auto& it : mFreedBuffers) {
+ if (it.first == id) {
+ ALOGV("%s: stream ID %d buffer id %" PRIu64 " cache removal still "
+ "pending", __FUNCTION__, id, it.second);
+ const auto& cachedEntry = std::find(bufIds.begin(), bufIds.end(),
+ it.second);
+ if (cachedEntry != bufIds.end()) {
+ bufIds.erase(cachedEntry);
+ } else {
+ ALOGE("%s: stream ID %d buffer id %" PRIu64 " cache removal still "
+ "pending however buffer is no longer in the offline stream "
+ "info!", __FUNCTION__, id, it.second);
+ }
+ }
+ }
+ }
if (!verifyBufferIds(id, bufIds)) {
ALOGE("%s: stream ID %d buffer cache records mismatch!", __FUNCTION__, id);
return UNKNOWN_ERROR;
@@ -848,6 +870,9 @@
*/
void setPaused(bool paused);
+ // set mRequestClearing - no new requests are expected to be queued to RequestThread
+ void setRequestClearing();
+
/**
* Wait until thread processes the capture request with settings'
* android.request.id == requestId.
diff --git a/services/mediacodec/Android.bp b/services/mediacodec/Android.bp
index 4488efb..a2f17c2 100644
--- a/services/mediacodec/Android.bp
+++ b/services/mediacodec/Android.bp
@@ -54,6 +54,9 @@
arm64: {
src: "seccomp_policy/mediaswcodec-arm64.policy",
},
+ riscv64: {
+ src: "seccomp_policy/mediaswcodec-riscv64.policy",
+ },
x86: {
src: "seccomp_policy/mediaswcodec-x86.policy",
},
@@ -144,6 +147,9 @@
arm64: {
src: "seccomp_policy/mediacodec-arm64.policy",
},
+ riscv64: {
+ enabled: false,
+ },
x86: {
src: "seccomp_policy/mediacodec-x86.policy",
},
diff --git a/services/mediacodec/seccomp_policy/mediaswcodec-riscv64.policy b/services/mediacodec/seccomp_policy/mediaswcodec-riscv64.policy
new file mode 100644
index 0000000..a55c3eb
--- /dev/null
+++ b/services/mediacodec/seccomp_policy/mediaswcodec-riscv64.policy
@@ -0,0 +1,60 @@
+# Copyright (C) 2021 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.
+
+read: 1
+mprotect: 1
+prctl: 1
+openat: 1
+getuid: 1
+getrlimit: 1
+writev: 1
+ioctl: 1
+close: 1
+mmap: 1
+munmap: 1
+fstat: 1
+madvise: 1
+newfstatat: 1
+futex: 1
+faccessat: 1
+lseek: 1
+clone: 1
+sigaltstack: 1
+rt_sigprocmask: 1
+setpriority: 1
+restart_syscall: 1
+exit: 1
+exit_group: 1
+rt_sigreturn: 1
+readlinkat: 1
+fstatfs: 1
+pread64: 1
+mremap: 1
+dup: 1
+set_tid_address: 1
+write: 1
+nanosleep: 1
+sched_setscheduler: 1
+uname: 1
+memfd_create: 1
+ftruncate: 1
+getdents64: 1
+ppoll: 1
+
+# Required by AddressSanitizer
+gettid: 1
+sched_yield: 1
+getpid: 1
+
+@include /apex/com.android.media.swcodec/etc/seccomp_policy/code_coverage.riscv64.policy
diff --git a/services/mediaextractor/Android.bp b/services/mediaextractor/Android.bp
index 85ce110..acafe56 100644
--- a/services/mediaextractor/Android.bp
+++ b/services/mediaextractor/Android.bp
@@ -74,6 +74,9 @@
arm64: {
src: "seccomp_policy/mediaextractor-arm64.policy",
},
+ riscv64: {
+ src: "seccomp_policy/mediaextractor-riscv64.policy",
+ },
x86: {
src: "seccomp_policy/mediaextractor-x86.policy",
},
diff --git a/services/mediaextractor/seccomp_policy/mediaextractor-riscv64.policy b/services/mediaextractor/seccomp_policy/mediaextractor-riscv64.policy
new file mode 100644
index 0000000..df143dd
--- /dev/null
+++ b/services/mediaextractor/seccomp_policy/mediaextractor-riscv64.policy
@@ -0,0 +1,48 @@
+# Organized by frequency of systemcall - in descending order for
+# best performance.
+ioctl: 1
+futex: 1
+prctl: 1
+write: 1
+getpriority: 1
+close: 1
+dup: 1
+mmap: 1
+munmap: 1
+openat: 1
+mprotect: 1
+madvise: 1
+getuid: 1
+fstat: 1
+fstatfs: 1
+read: 1
+setpriority: 1
+sigaltstack: 1
+clone: 1
+sched_setscheduler: 1
+lseek: 1
+newfstatat: 1
+faccessat: 1
+restart_syscall: 1
+exit: 1
+exit_group: 1
+rt_sigreturn: 1
+rt_sigprocmask: 1
+getrlimit: 1
+nanosleep: 1
+getrandom: 1
+timer_create: 1
+timer_settime: 1
+timer_delete: 1
+
+# for dynamically loading extractors
+getdents64: 1
+readlinkat: 1
+pread64: 1
+mremap: 1
+
+# Required by Sanitizers
+sched_yield: 1
+
+@include /apex/com.android.media/etc/seccomp_policy/crash_dump.riscv64.policy
+@include /apex/com.android.media/etc/seccomp_policy/code_coverage.riscv64.policy
diff --git a/services/mediametrics/MediaMetricsService.cpp b/services/mediametrics/MediaMetricsService.cpp
index 8a7e8a9..18c0b50 100644
--- a/services/mediametrics/MediaMetricsService.cpp
+++ b/services/mediametrics/MediaMetricsService.cpp
@@ -72,6 +72,7 @@
bool MediaMetricsService::useUidForPackage(
const std::string& package, const std::string& installer)
{
+ // NOLINTBEGIN(bugprone-branch-clone)
if (strchr(package.c_str(), '.') == nullptr) {
return false; // not of form 'com.whatever...'; assume internal and ok
} else if (strncmp(package.c_str(), "android.", 8) == 0) {
@@ -85,6 +86,7 @@
} else {
return true; // we're not sure where it came from, use uid only.
}
+ // NOLINTEND(bugprone-branch-clone)
}
/* static */
@@ -509,6 +511,8 @@
const std::string &key = item->getKey();
if (startsWith(key, "audio.")) return true;
if (startsWith(key, "drm.vendor.")) return true;
+ if (startsWith(key, "mediadrm.")) return true;
+
// the list of allowedKey uses statsd_handlers
// in iface_statsd.cpp as reference
// drmmanager is from a trusted uid, therefore not needed here
diff --git a/services/mediametrics/include/mediametricsservice/AudioPowerUsage.h b/services/mediametrics/include/mediametricsservice/AudioPowerUsage.h
index b7215e6..6e5a5cf 100644
--- a/services/mediametrics/include/mediametricsservice/AudioPowerUsage.h
+++ b/services/mediametrics/include/mediametricsservice/AudioPowerUsage.h
@@ -50,7 +50,7 @@
*/
std::pair<std::string, int32_t> dump(int32_t lines = INT32_MAX) const;
- // align with message AudioUsageDataReported in frameworks/base/cmds/statsd/src/atoms.proto
+ // align with message AudioPowerUsageDataReported in frameworks/proto_logging/stats/atoms.proto
enum AudioType {
UNKNOWN_TYPE = 0,
VOICE_CALL_TYPE = 1, // voice call
diff --git a/services/mediametrics/statsd_audiorecord.cpp b/services/mediametrics/statsd_audiorecord.cpp
index a7b045e..01adf7f 100644
--- a/services/mediametrics/statsd_audiorecord.cpp
+++ b/services/mediametrics/statsd_audiorecord.cpp
@@ -99,16 +99,14 @@
}
int32_t error_code = -1;
- if (item->getInt32("android.media.audiorecord.errcode", &error_code)) {
- metrics_proto.set_error_code(error_code);
- } else if (item->getInt32("android.media.audiorecord.lastError.code", &error_code)) {
+ if (item->getInt32("android.media.audiorecord.errcode", &error_code) ||
+ item->getInt32("android.media.audiorecord.lastError.code", &error_code)) {
metrics_proto.set_error_code(error_code);
}
std::string error_function;
- if (item->getString("android.media.audiorecord.errfunc", &error_function)) {
- metrics_proto.set_error_function(error_function);
- } else if (item->getString("android.media.audiorecord.lastError.at", &error_function)) {
+ if (item->getString("android.media.audiorecord.errfunc", &error_function) ||
+ item->getString("android.media.audiorecord.lastError.at", &error_function)) {
metrics_proto.set_error_function(error_function);
}
diff --git a/services/mediaresourcemanager/ResourceManagerService.cpp b/services/mediaresourcemanager/ResourceManagerService.cpp
index b4610bc..4d18876 100644
--- a/services/mediaresourcemanager/ResourceManagerService.cpp
+++ b/services/mediaresourcemanager/ResourceManagerService.cpp
@@ -271,10 +271,9 @@
snprintf(buffer, SIZE, " Id: %lld\n", (long long)infos[j].clientId);
result.append(buffer);
- std::string clientName;
- Status status = infos[j].client->getName(&clientName);
- if (!status.isOk()) {
- clientName = "<unknown client>";
+ std::string clientName = "<unknown client>";
+ if (infos[j].client != nullptr) {
+ Status status = infos[j].client->getName(&clientName);
}
snprintf(buffer, SIZE, " Name: %s\n", clientName.c_str());
result.append(buffer);
diff --git a/services/oboeservice/Android.bp b/services/oboeservice/Android.bp
index 80e4296..5076239 100644
--- a/services/oboeservice/Android.bp
+++ b/services/oboeservice/Android.bp
@@ -25,6 +25,10 @@
name: "libaaudioservice",
+ defaults: [
+ "latest_android_media_audio_common_types_cpp_shared",
+ ],
+
srcs: [
"AAudioClientTracker.cpp",
"AAudioCommandQueue.cpp",
@@ -70,7 +74,6 @@
"framework-permission-aidl-cpp",
"libaudioclient_aidl_conversion",
"packagemanager_aidl-cpp",
- "android.media.audio.common.types-V1-cpp",
],
export_shared_lib_headers: [
diff --git a/tools/OWNERS b/tools/OWNERS
new file mode 100644
index 0000000..7598c6f
--- /dev/null
+++ b/tools/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 1344
+essick@google.com
+
+# reliability builds mainline trains, so needs to manage these scripts
+include platform/frameworks/av/:/media/janitors/reliability_mainline_OWNERS
diff --git a/tools/mainline_hook_partial.sh b/tools/mainline_hook_partial.sh
index bd82315..cd3e579 100755
--- a/tools/mainline_hook_partial.sh
+++ b/tools/mainline_hook_partial.sh
Binary files differ
diff --git a/tools/mainline_hook_project.sh b/tools/mainline_hook_project.sh
index cb5fc44..1cc3b2b 100755
--- a/tools/mainline_hook_project.sh
+++ b/tools/mainline_hook_project.sh
@@ -17,7 +17,7 @@
# tunables
DEV_BRANCH=master
-MAINLINE_BRANCH=sc-mainline-prod
+MAINLINE_BRANCH=tm-mainline-prod
###
RED=$(tput setaf 1)