Merge "C2Config: correct declaration of tunnel-peek mode"
diff --git a/Android.bp b/Android.bp
index 5aa2029..37f6457 100644
--- a/Android.bp
+++ b/Android.bp
@@ -44,7 +44,7 @@
srcs: [
"aidl/android/media/InterpolatorConfig.aidl",
"aidl/android/media/InterpolatorType.aidl",
- "aidl/android/media/MicrophoneInfoData.aidl",
+ "aidl/android/media/MicrophoneInfoFw.aidl",
"aidl/android/media/VolumeShaperConfiguration.aidl",
"aidl/android/media/VolumeShaperConfigurationOptionFlag.aidl",
"aidl/android/media/VolumeShaperConfigurationType.aidl",
@@ -52,6 +52,9 @@
"aidl/android/media/VolumeShaperOperationFlag.aidl",
"aidl/android/media/VolumeShaperState.aidl",
],
+ imports: [
+ "android.media.audio.common.types-V2",
+ ],
backend: {
cpp: {
min_sdk_version: "29",
@@ -62,6 +65,9 @@
"com.android.media.swcodec",
],
},
+ java: {
+ sdk_version: "module_current",
+ },
},
}
diff --git a/aidl/android/media/MicrophoneInfoData.aidl b/aidl/android/media/MicrophoneInfoFw.aidl
similarity index 62%
rename from aidl/android/media/MicrophoneInfoData.aidl
rename to aidl/android/media/MicrophoneInfoFw.aidl
index 747bfa5..bad0e0a 100644
--- a/aidl/android/media/MicrophoneInfoData.aidl
+++ b/aidl/android/media/MicrophoneInfoFw.aidl
@@ -16,24 +16,14 @@
package android.media;
+import android.media.audio.common.MicrophoneDynamicInfo;
+import android.media.audio.common.MicrophoneInfo;
+
/**
* {@hide}
*/
-parcelable MicrophoneInfoData {
- @utf8InCpp String deviceId;
+parcelable MicrophoneInfoFw {
+ MicrophoneInfo info;
+ MicrophoneDynamicInfo dynamic;
int portId;
- int type;
- @utf8InCpp String address;
- int deviceLocation;
- int deviceGroup;
- int indexInTheGroup;
- float[] geometricLocation;
- float[] orientation;
- float[] frequencies;
- float[] frequencyResponses;
- int[] channelMapping;
- float sensitivity;
- float maxSpl;
- float minSpl;
- int directionality;
}
diff --git a/camera/ndk/include/camera/NdkCameraMetadataTags.h b/camera/ndk/include/camera/NdkCameraMetadataTags.h
index 0d156a5..9174adf 100644
--- a/camera/ndk/include/camera/NdkCameraMetadataTags.h
+++ b/camera/ndk/include/camera/NdkCameraMetadataTags.h
@@ -9215,24 +9215,25 @@
* camera's crop region is set to maximum size, the FOV of the physical streams for the
* ultrawide lens will be the same as the logical stream, by making the crop region
* smaller than its active array size to compensate for the smaller focal length.</p>
- * <p>There are two ways for the application to capture RAW images from a logical camera
- * with RAW capability:</p>
+ * <p>For a logical camera, typically the underlying physical cameras have different RAW
+ * capabilities (such as resolution or CFA pattern). There are two ways for the
+ * application to capture RAW images from the logical camera:</p>
* <ul>
- * <li>Because the underlying physical cameras may have different RAW capabilities (such
- * as resolution or CFA pattern), to maintain backward compatibility, when a RAW stream
- * is configured, the camera device makes sure the default active physical camera remains
- * active and does not switch to other physical cameras. (One exception is that, if the
- * logical camera consists of identical image sensors and advertises multiple focalLength
- * due to different lenses, the camera device may generate RAW images from different
- * physical cameras based on the focalLength being set by the application.) This
- * backward-compatible approach usually results in loss of optical zoom, to telephoto
- * lens or to ultrawide lens.</li>
- * <li>Alternatively, to take advantage of the full zoomRatio range of the logical camera,
- * the application should use <a href="https://developer.android.com/reference/android/hardware/camera2/MultiResolutionImageReader.html">MultiResolutionImageReader</a>
- * to capture RAW images from the currently active physical camera. Because different
- * physical camera may have different RAW characteristics, the application needs to use
- * the characteristics and result metadata of the active physical camera for the
- * relevant RAW metadata.</li>
+ * <li>If the logical camera has RAW capability, the application can create and use RAW
+ * streams in the same way as before. In case a RAW stream is configured, to maintain
+ * backward compatibility, the camera device makes sure the default active physical
+ * camera remains active and does not switch to other physical cameras. (One exception
+ * is that, if the logical camera consists of identical image sensors and advertises
+ * multiple focalLength due to different lenses, the camera device may generate RAW
+ * images from different physical cameras based on the focalLength being set by the
+ * application.) This backward-compatible approach usually results in loss of optical
+ * zoom, to telephoto lens or to ultrawide lens.</li>
+ * <li>Alternatively, if supported by the device,
+ * <a href="https://developer.android.com/reference/android/hardware/camera2/MultiResolutionImageReader.html">MultiResolutionImageReader</a>
+ * can be used to capture RAW images from one of the underlying physical cameras (
+ * depending on current zoom level). Because different physical cameras may have
+ * different RAW characteristics, the application needs to use the characteristics
+ * and result metadata of the active physical camera for the relevant RAW metadata.</li>
* </ul>
* <p>The capture request and result metadata tags required for backward compatible camera
* functionalities will be solely based on the logical camera capability. On the other
diff --git a/drm/TEST_MAPPING b/drm/TEST_MAPPING
index 3642898..b2d4d6e 100644
--- a/drm/TEST_MAPPING
+++ b/drm/TEST_MAPPING
@@ -1,5 +1,5 @@
{
- "presubmit-large": [
+ "presubmit": [
// The following tests validate codec and drm path.
{
"name": "GtsMediaTestCases",
diff --git a/drm/drmserver/Android.bp b/drm/drmserver/Android.bp
index df3a6a2..ab25c65 100644
--- a/drm/drmserver/Android.bp
+++ b/drm/drmserver/Android.bp
@@ -63,3 +63,39 @@
init_rc: ["drmserver.rc"],
}
+
+cc_fuzz {
+ name: "drmserver_fuzzer",
+
+ defaults: [
+ "service_fuzzer_defaults",
+ ],
+
+ srcs: [
+ "fuzzer/DrmFuzzer.cpp",
+ "DrmManagerService.cpp",
+ "DrmManager.cpp",
+ ],
+
+ static_libs: [
+ "libmediautils",
+ "liblog",
+ "libdl",
+ "libdrmframeworkcommon",
+ "libselinux",
+ "libstagefright_foundation",
+ ],
+
+ shared_libs: [
+ "libmediametrics",
+ ],
+
+ fuzz_config: {
+ libfuzzer_options: [
+ "max_len=50000",
+ ],
+ cc: [
+ "android-drm-team@google.com",
+ ],
+ },
+}
\ No newline at end of file
diff --git a/drm/drmserver/DrmManagerService.h b/drm/drmserver/DrmManagerService.h
index f9b8bef..56201d9 100644
--- a/drm/drmserver/DrmManagerService.h
+++ b/drm/drmserver/DrmManagerService.h
@@ -141,6 +141,8 @@
virtual status_t dump(int fd, const Vector<String16>& args);
+ friend class DrmManagerServiceFuzzer;
+
private:
sp<DrmManager> mDrmManager;
};
diff --git a/drm/drmserver/fuzzer/DrmFuzzer.cpp b/drm/drmserver/fuzzer/DrmFuzzer.cpp
new file mode 100644
index 0000000..4b23679
--- /dev/null
+++ b/drm/drmserver/fuzzer/DrmFuzzer.cpp
@@ -0,0 +1,38 @@
+/*
+ * 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 <fuzzbinder/libbinder_driver.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+#include "DrmManagerService.h"
+
+namespace android {
+class DrmManagerServiceFuzzer {
+public:
+ DrmManagerServiceFuzzer() {}
+
+ void fuzz(const uint8_t* data, size_t size) {
+ auto drmService = new DrmManagerService();
+ fuzzService(drmService, FuzzedDataProvider(data, size));
+ }
+};
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ android::DrmManagerServiceFuzzer serviceFuzzer;
+ serviceFuzzer.fuzz(data, size);
+ return 0;
+}
\ No newline at end of file
diff --git a/drm/libmediadrm/DrmHalAidl.cpp b/drm/libmediadrm/DrmHalAidl.cpp
index c369529..5ec7337 100644
--- a/drm/libmediadrm/DrmHalAidl.cpp
+++ b/drm/libmediadrm/DrmHalAidl.cpp
@@ -393,7 +393,8 @@
// DrmHalAidl methods
DrmHalAidl::DrmHalAidl()
- : mListener(::ndk::SharedRefBase::make<DrmHalListener>(&mMetrics)),
+ : mMetrics(std::make_shared<MediaDrmMetrics>()),
+ mListener(::ndk::SharedRefBase::make<DrmHalListener>(mMetrics)),
mFactories(DrmUtils::makeDrmFactoriesAidl()),
mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {}
@@ -458,12 +459,12 @@
DrmStatus DrmHalAidl::createPlugin(const uint8_t uuid[16], const String8& appPackageName) {
Mutex::Autolock autoLock(mLock);
-
+ if (mInitCheck == ERROR_UNSUPPORTED) return mInitCheck;
Uuid uuidAidl = DrmUtils::toAidlUuid(uuid);
std::string appPackageNameAidl = toStdString(appPackageName);
std::shared_ptr<IDrmPluginAidl> pluginAidl;
- mMetrics.SetAppPackageName(appPackageName);
- mMetrics.SetAppUid(AIBinder_getCallingUid());
+ mMetrics->SetAppPackageName(appPackageName);
+ mMetrics->SetAppUid(AIBinder_getCallingUid());
for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
::ndk::ScopedAStatus status =
mFactories[i]->createDrmPlugin(uuidAidl, appPackageNameAidl, &pluginAidl);
@@ -539,10 +540,10 @@
AIBinder_getCallingPid(), std::static_pointer_cast<IResourceManagerClient>(client),
sessionId);
mOpenSessions.push_back(client);
- mMetrics.SetSessionStart(sessionId);
+ mMetrics->SetSessionStart(sessionId);
}
- mMetrics.mOpenSessionCounter.Increment(err);
+ mMetrics->mOpenSessionCounter.Increment(err);
return err;
}
@@ -562,10 +563,10 @@
}
}
- mMetrics.SetSessionEnd(sessionId);
+ mMetrics->SetSessionEnd(sessionId);
}
- mMetrics.mCloseSessionCounter.Increment(response);
+ mMetrics->mCloseSessionCounter.Increment(response);
return response;
}
@@ -577,7 +578,7 @@
DrmPlugin::KeyRequestType* keyRequestType) {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
- EventTimer<status_t> keyRequestTimer(&mMetrics.mGetKeyRequestTimeUs);
+ EventTimer<status_t> keyRequestTimer(&mMetrics->mGetKeyRequestTimeUs);
DrmSessionManager::Instance()->useSession(sessionId);
@@ -618,7 +619,7 @@
Vector<uint8_t>& keySetId) {
Mutex::Autolock autoLock(mLock);
INIT_CHECK();
- EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTimeUs);
+ EventTimer<status_t> keyResponseTimer(&mMetrics->mProvideKeyResponseTimeUs);
DrmSessionManager::Instance()->useSession(sessionId);
@@ -687,7 +688,7 @@
defaultUrl = toString8(requestAidl.defaultUrl);
err = statusAidlToDrmStatus(status);
- mMetrics.mGetProvisionRequestCounter.Increment(err);
+ mMetrics->mGetProvisionRequestCounter.Increment(err);
return err;
}
@@ -704,7 +705,7 @@
certificate = toVector(result.certificate);
wrappedKey = toVector(result.wrappedKey);
err = statusAidlToDrmStatus(status);
- mMetrics.mProvideProvisionResponseCounter.Increment(err);
+ mMetrics->mProvideProvisionResponseCounter.Increment(err);
return err;
}
@@ -914,7 +915,7 @@
value = toVector(result);
err = statusAidlToDrmStatus(status);
if (name == kPropertyDeviceUniqueId) {
- mMetrics.mGetDeviceUniqueIdCounter.Increment(err);
+ mMetrics->mGetDeviceUniqueIdCounter.Increment(err);
}
return err;
}
@@ -940,7 +941,7 @@
if (consumer == nullptr) {
return DrmStatus(UNEXPECTED_NULL);
}
- consumer->consumeFrameworkMetrics(mMetrics);
+ consumer->consumeFrameworkMetrics(*mMetrics.get());
// Append vendor metrics if they are supported.
@@ -1146,7 +1147,7 @@
getPropertyByteArrayInternal(String8("metrics"), metricsVector) == OK) {
metricsString = toBase64StringNoPad(metricsVector.array(), metricsVector.size());
status_t res = android::reportDrmPluginMetrics(metricsString, vendor, description,
- mMetrics.GetAppUid());
+ mMetrics->GetAppUid());
if (res != OK) {
ALOGE("Metrics were retrieved but could not be reported: %d", res);
}
@@ -1156,7 +1157,7 @@
std::string DrmHalAidl::reportFrameworkMetrics(const std::string& pluginMetrics) const {
mediametrics_handle_t item(mediametrics_create("mediadrm"));
- mediametrics_setUid(item, mMetrics.GetAppUid());
+ mediametrics_setUid(item, mMetrics->GetAppUid());
String8 vendor;
String8 description;
status_t result = getPropertyStringInternal(String8("vendor"), vendor);
@@ -1173,7 +1174,7 @@
}
std::string serializedMetrics;
- result = mMetrics.GetSerializedMetrics(&serializedMetrics);
+ result = mMetrics->GetSerializedMetrics(&serializedMetrics);
if (result != OK) {
ALOGE("Failed to serialize framework metrics: %d", result);
}
@@ -1215,7 +1216,7 @@
closeOpenSessions();
Mutex::Autolock autoLock(mLock);
- reportFrameworkMetrics(reportPluginMetrics());
+ if (mInitCheck == OK) reportFrameworkMetrics(reportPluginMetrics());
setListener(NULL);
mInitCheck = NO_INIT;
diff --git a/drm/libmediadrm/DrmHalHidl.cpp b/drm/libmediadrm/DrmHalHidl.cpp
index 6010739..6106aa7 100644
--- a/drm/libmediadrm/DrmHalHidl.cpp
+++ b/drm/libmediadrm/DrmHalHidl.cpp
@@ -557,6 +557,7 @@
DrmStatus DrmHalHidl::createPlugin(const uint8_t uuid[16], const String8& appPackageName) {
Mutex::Autolock autoLock(mLock);
+ if (mInitCheck == ERROR_UNSUPPORTED) return mInitCheck;
for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
auto hResult = mFactories[i]->isCryptoSchemeSupported(uuid);
if (hResult.isOk() && hResult) {
diff --git a/drm/libmediadrm/DrmHalListener.cpp b/drm/libmediadrm/DrmHalListener.cpp
index cfcf475..4e868ac 100644
--- a/drm/libmediadrm/DrmHalListener.cpp
+++ b/drm/libmediadrm/DrmHalListener.cpp
@@ -37,12 +37,12 @@
return vec;
}
-DrmHalListener::DrmHalListener(MediaDrmMetrics* metrics)
+DrmHalListener::DrmHalListener(const std::shared_ptr<MediaDrmMetrics>& metrics)
: mMetrics(metrics) {}
DrmHalListener::~DrmHalListener() {}
-void DrmHalListener::setListener(sp<IDrmClient> listener) {
+void DrmHalListener::setListener(const sp<IDrmClient>& listener) {
Mutex::Autolock lock(mEventLock);
mListener = listener;
}
diff --git a/drm/libmediadrm/DrmMetricsLogger.cpp b/drm/libmediadrm/DrmMetricsLogger.cpp
index 89b1dcc..de6d097 100644
--- a/drm/libmediadrm/DrmMetricsLogger.cpp
+++ b/drm/libmediadrm/DrmMetricsLogger.cpp
@@ -63,6 +63,8 @@
DrmStatus DrmMetricsLogger::createPlugin(const uint8_t uuid[IDRM_UUID_SIZE],
const String8& appPackageName) {
std::memcpy(mUuid.data(), uuid, IDRM_UUID_SIZE);
+ mUuid[0] = betoh64(mUuid[0]);
+ mUuid[1] = betoh64(mUuid[1]);
if (kUuidSchemeMap.count(mUuid)) {
mScheme = kUuidSchemeMap.at(mUuid);
} else {
@@ -460,8 +462,8 @@
void DrmMetricsLogger::reportMediaDrmCreated() const {
mediametrics_handle_t handle(mediametrics_create("mediadrm.created"));
mediametrics_setCString(handle, "scheme", mScheme.c_str());
- mediametrics_setInt64(handle, "uuid_msb", be64toh(mUuid[0]));
- mediametrics_setInt64(handle, "uuid_lsb", be64toh(mUuid[1]));
+ mediametrics_setInt64(handle, "uuid_msb", mUuid[0]);
+ mediametrics_setInt64(handle, "uuid_lsb", mUuid[1]);
mediametrics_setInt32(handle, "frontend", mFrontend);
mediametrics_setCString(handle, "object_nonce", mObjNonce.c_str());
mediametrics_selfRecord(handle);
@@ -471,8 +473,8 @@
void DrmMetricsLogger::reportMediaDrmSessionOpened(const std::vector<uint8_t>& sessionId) const {
mediametrics_handle_t handle(mediametrics_create("mediadrm.session_opened"));
mediametrics_setCString(handle, "scheme", mScheme.c_str());
- mediametrics_setInt64(handle, "uuid_msb", be64toh(mUuid[0]));
- mediametrics_setInt64(handle, "uuid_lsb", be64toh(mUuid[1]));
+ mediametrics_setInt64(handle, "uuid_msb", mUuid[0]);
+ mediametrics_setInt64(handle, "uuid_lsb", mUuid[1]);
mediametrics_setInt32(handle, "frontend", mFrontend);
mediametrics_setCString(handle, "object_nonce", mObjNonce.c_str());
const std::lock_guard<std::mutex> lock(mSessionMapMutex);
@@ -490,8 +492,8 @@
const std::vector<uint8_t>& sessionId) const {
mediametrics_handle_t handle(mediametrics_create("mediadrm.errored"));
mediametrics_setCString(handle, "scheme", mScheme.c_str());
- mediametrics_setInt64(handle, "uuid_msb", be64toh(mUuid[0]));
- mediametrics_setInt64(handle, "uuid_lsb", be64toh(mUuid[1]));
+ mediametrics_setInt64(handle, "uuid_msb", mUuid[0]);
+ mediametrics_setInt64(handle, "uuid_lsb", mUuid[1]);
mediametrics_setInt32(handle, "frontend", mFrontend);
mediametrics_setCString(handle, "object_nonce", mObjNonce.c_str());
if (!sessionId.empty()) {
diff --git a/drm/libmediadrm/DrmSessionManager.cpp b/drm/libmediadrm/DrmSessionManager.cpp
index e31395d..301538f 100644
--- a/drm/libmediadrm/DrmSessionManager.cpp
+++ b/drm/libmediadrm/DrmSessionManager.cpp
@@ -34,6 +34,7 @@
namespace android {
using aidl::android::media::MediaResourceParcel;
+using aidl::android::media::ClientInfoParcel;
namespace {
void ResourceManagerServiceDied(void* cookie) {
@@ -137,7 +138,10 @@
static int64_t clientId = 0;
mSessionMap[toStdVec(sessionId)] = (SessionInfo){pid, uid, clientId};
- mService->addResource(pid, uid, clientId++, drm, toResourceVec(sessionId, INT64_MAX));
+ ClientInfoParcel clientInfo{.pid = static_cast<int32_t>(pid),
+ .uid = static_cast<int32_t>(uid),
+ .id = clientId++};
+ mService->addResource(clientInfo, drm, toResourceVec(sessionId, INT64_MAX));
}
void DrmSessionManager::useSession(const Vector<uint8_t> &sessionId) {
@@ -150,7 +154,10 @@
}
auto info = it->second;
- mService->addResource(info.pid, info.uid, info.clientId, NULL, toResourceVec(sessionId, -1));
+ ClientInfoParcel clientInfo{.pid = static_cast<int32_t>(info.pid),
+ .uid = static_cast<int32_t>(info.uid),
+ .id = info.clientId};
+ mService->addResource(clientInfo, NULL, toResourceVec(sessionId, -1));
}
void DrmSessionManager::removeSession(const Vector<uint8_t> &sessionId) {
@@ -164,7 +171,10 @@
auto info = it->second;
// removeClient instead of removeSession because each client has only one session
- mService->removeClient(info.pid, info.clientId);
+ ClientInfoParcel clientInfo{.pid = static_cast<int32_t>(info.pid),
+ .uid = static_cast<int32_t>(info.uid),
+ .id = info.clientId};
+ mService->removeClient(clientInfo);
mSessionMap.erase(it);
}
@@ -182,9 +192,13 @@
// cannot update mSessionMap because we do not know which sessionId is reclaimed;
// we rely on IResourceManagerClient to removeSession in reclaimResource
- Vector<uint8_t> dummy;
+ Vector<uint8_t> placeHolder;
bool success;
- ScopedAStatus status = service->reclaimResource(callingPid, toResourceVec(dummy, INT64_MAX), &success);
+ uid_t uid = AIBinder_getCallingUid();
+ ClientInfoParcel clientInfo{.pid = static_cast<int32_t>(callingPid),
+ .uid = static_cast<int32_t>(uid)};
+ ScopedAStatus status = service->reclaimResource(
+ clientInfo, toResourceVec(placeHolder, INT64_MAX), &success);
return status.isOk() && success;
}
diff --git a/drm/libmediadrm/include/mediadrm/DrmHalAidl.h b/drm/libmediadrm/include/mediadrm/DrmHalAidl.h
index e0b8341..a81b312 100644
--- a/drm/libmediadrm/include/mediadrm/DrmHalAidl.h
+++ b/drm/libmediadrm/include/mediadrm/DrmHalAidl.h
@@ -123,7 +123,7 @@
::ndk::ScopedAStatus onSessionLostState(const std::vector<uint8_t>& in_sessionId);
private:
static Mutex mLock;
- mutable MediaDrmMetrics mMetrics;
+ std::shared_ptr<MediaDrmMetrics> mMetrics;
std::shared_ptr<DrmHalListener> mListener;
const std::vector<std::shared_ptr<IDrmFactoryAidl>> mFactories;
std::shared_ptr<IDrmPluginAidl> mPlugin;
diff --git a/drm/libmediadrm/include/mediadrm/DrmHalListener.h b/drm/libmediadrm/include/mediadrm/DrmHalListener.h
index 22361ad..0eed929 100644
--- a/drm/libmediadrm/include/mediadrm/DrmHalListener.h
+++ b/drm/libmediadrm/include/mediadrm/DrmHalListener.h
@@ -27,7 +27,7 @@
namespace android {
struct DrmHalListener : public BnDrmPluginListener {
- explicit DrmHalListener(MediaDrmMetrics* mMetrics);
+ explicit DrmHalListener(const std::shared_ptr<MediaDrmMetrics>& in_metrics);
~DrmHalListener();
::ndk::ScopedAStatus onEvent(EventTypeAidl in_eventType,
const std::vector<uint8_t>& in_sessionId,
@@ -38,9 +38,9 @@
const std::vector<KeyStatusAidl>& in_keyStatusList,
bool in_hasNewUsableKey);
::ndk::ScopedAStatus onSessionLostState(const std::vector<uint8_t>& in_sessionId);
- void setListener(sp<IDrmClient> listener);
+ void setListener(const sp<IDrmClient>& listener);
private:
- mutable MediaDrmMetrics* mMetrics;
+ std::shared_ptr<MediaDrmMetrics> mMetrics;
sp<IDrmClient> mListener;
mutable Mutex mEventLock;
mutable Mutex mNotifyLock;
diff --git a/drm/libmediadrm/interface/mediadrm/DrmUtils.h b/drm/libmediadrm/interface/mediadrm/DrmUtils.h
index 94cf743..ba20b95 100644
--- a/drm/libmediadrm/interface/mediadrm/DrmUtils.h
+++ b/drm/libmediadrm/interface/mediadrm/DrmUtils.h
@@ -37,6 +37,7 @@
#include <ctime>
#include <deque>
#include <endian.h>
+#include <inttypes.h>
#include <iterator>
#include <mutex>
#include <string>
@@ -105,9 +106,9 @@
void LogToBuffer(android_LogPriority level, const uint8_t uuid[16], const char *fmt, Args... args) {
uint64_t uuid2[2] = {};
std::memcpy(uuid2, uuid, sizeof(uuid2));
- std::string uuidFmt("uuid=[%lx %lx] ");
+ std::string uuidFmt("uuid=[%" PRIx64 " %" PRIx64 "] ");
uuidFmt += fmt;
- LogToBuffer(level, uuidFmt.c_str(), htobe64(uuid2[0]), htobe64(uuid2[1]), args...);
+ LogToBuffer(level, uuidFmt.c_str(), betoh64(uuid2[0]), betoh64(uuid2[1]), args...);
}
#ifndef LOG2BE
diff --git a/include/media/MicrophoneInfo.h b/include/media/MicrophoneInfo.h
deleted file mode 100644
index 6d6c594..0000000
--- a/include/media/MicrophoneInfo.h
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef ANDROID_MICROPHONE_INFO_H
-#define ANDROID_MICROPHONE_INFO_H
-
-#include <android/media/MicrophoneInfoData.h>
-#include <binder/Parcel.h>
-#include <binder/Parcelable.h>
-#include <media/AidlConversionUtil.h>
-#include <system/audio.h>
-
-namespace android {
-namespace media {
-
-class MicrophoneInfo : public Parcelable {
-public:
- MicrophoneInfo() = default;
- MicrophoneInfo(const MicrophoneInfo& microphoneInfo) = default;
- MicrophoneInfo(audio_microphone_characteristic_t& characteristic) {
- mDeviceId = std::string(&characteristic.device_id[0]);
- mPortId = characteristic.id;
- mType = characteristic.device;
- mAddress = std::string(&characteristic.address[0]);
- mDeviceLocation = characteristic.location;
- mDeviceGroup = characteristic.group;
- mIndexInTheGroup = characteristic.index_in_the_group;
- mGeometricLocation.push_back(characteristic.geometric_location.x);
- mGeometricLocation.push_back(characteristic.geometric_location.y);
- mGeometricLocation.push_back(characteristic.geometric_location.z);
- mOrientation.push_back(characteristic.orientation.x);
- mOrientation.push_back(characteristic.orientation.y);
- mOrientation.push_back(characteristic.orientation.z);
- std::vector<float> frequencies;
- std::vector<float> responses;
- for (size_t i = 0; i < characteristic.num_frequency_responses; i++) {
- frequencies.push_back(characteristic.frequency_responses[0][i]);
- responses.push_back(characteristic.frequency_responses[1][i]);
- }
- mFrequencyResponses.push_back(frequencies);
- mFrequencyResponses.push_back(responses);
- for (size_t i = 0; i < AUDIO_CHANNEL_COUNT_MAX; i++) {
- mChannelMapping.push_back(characteristic.channel_mapping[i]);
- }
- mSensitivity = characteristic.sensitivity;
- mMaxSpl = characteristic.max_spl;
- mMinSpl = characteristic.min_spl;
- mDirectionality = characteristic.directionality;
- }
-
- virtual ~MicrophoneInfo() = default;
-
- virtual status_t writeToParcel(Parcel* parcel) const {
- MicrophoneInfoData parcelable;
- return writeToParcelable(&parcelable)
- ?: parcelable.writeToParcel(parcel);
- }
-
- 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));
- parcelable->address = mAddress;
- parcelable->deviceGroup = mDeviceGroup;
- parcelable->indexInTheGroup = mIndexInTheGroup;
- parcelable->geometricLocation = mGeometricLocation;
- parcelable->orientation = mOrientation;
- if (mFrequencyResponses.size() != 2) {
- return BAD_VALUE;
- }
- parcelable->frequencies = mFrequencyResponses[0];
- parcelable->frequencyResponses = mFrequencyResponses[1];
- parcelable->channelMapping = mChannelMapping;
- parcelable->sensitivity = mSensitivity;
- parcelable->maxSpl = mMaxSpl;
- parcelable->minSpl = mMinSpl;
- parcelable->directionality = mDirectionality;
- return OK;
- }
-
- virtual status_t readFromParcel(const Parcel* parcel) {
- MicrophoneInfoData data;
- return data.readFromParcel(parcel)
- ?: readFromParcelable(data);
- }
-
- 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));
- mAddress = parcelable.address;
- mDeviceLocation = parcelable.deviceLocation;
- mDeviceGroup = parcelable.deviceGroup;
- mIndexInTheGroup = parcelable.indexInTheGroup;
- if (parcelable.geometricLocation.size() != 3) {
- return BAD_VALUE;
- }
- mGeometricLocation = parcelable.geometricLocation;
- if (parcelable.orientation.size() != 3) {
- return BAD_VALUE;
- }
- mOrientation = parcelable.orientation;
- if (parcelable.frequencies.size() != parcelable.frequencyResponses.size()) {
- return BAD_VALUE;
- }
-
- mFrequencyResponses.push_back(parcelable.frequencies);
- mFrequencyResponses.push_back(parcelable.frequencyResponses);
- if (parcelable.channelMapping.size() != AUDIO_CHANNEL_COUNT_MAX) {
- return BAD_VALUE;
- }
- mChannelMapping = parcelable.channelMapping;
- mSensitivity = parcelable.sensitivity;
- mMaxSpl = parcelable.maxSpl;
- mMinSpl = parcelable.minSpl;
- mDirectionality = parcelable.directionality;
- return OK;
- }
-
- std::string getDeviceId() const {
- return mDeviceId;
- }
-
- int getPortId() const {
- return mPortId;
- }
-
- unsigned int getType() const {
- return mType;
- }
-
- std::string getAddress() const {
- return mAddress;
- }
-
- int getDeviceLocation() const {
- return mDeviceLocation;
- }
-
- int getDeviceGroup() const {
- return mDeviceGroup;
- }
-
- int getIndexInTheGroup() const {
- return mIndexInTheGroup;
- }
-
- const std::vector<float>& getGeometricLocation() const {
- return mGeometricLocation;
- }
-
- const std::vector<float>& getOrientation() const {
- return mOrientation;
- }
-
- const std::vector<std::vector<float>>& getFrequencyResponses() const {
- return mFrequencyResponses;
- }
-
- const std::vector<int>& getChannelMapping() const {
- return mChannelMapping;
- }
-
- float getSensitivity() const {
- return mSensitivity;
- }
-
- float getMaxSpl() const {
- return mMaxSpl;
- }
-
- float getMinSpl() const {
- return mMinSpl;
- }
-
- int getDirectionality() const {
- return mDirectionality;
- }
-
-private:
- std::string mDeviceId;
- int32_t mPortId;
- uint32_t mType;
- std::string mAddress;
- int32_t mDeviceLocation;
- int32_t mDeviceGroup;
- int32_t mIndexInTheGroup;
- std::vector<float> mGeometricLocation;
- std::vector<float> mOrientation;
- std::vector<std::vector<float>> mFrequencyResponses;
- std::vector<int> mChannelMapping;
- float mSensitivity;
- float mMaxSpl;
- float mMinSpl;
- 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) {
- MicrophoneInfo legacy;
- RETURN_IF_ERROR(legacy.readFromParcelable(aidl));
- return legacy;
-}
-
-inline ConversionResult<media::MicrophoneInfoData>
-legacy2aidl_MicrophoneInfo(const MicrophoneInfo& legacy) {
- media::MicrophoneInfoData aidl;
- RETURN_IF_ERROR(legacy.writeToParcelable(&aidl));
- return aidl;
-}
-
-} // namespace media
-} // namespace android
-
-#endif
diff --git a/media/audioaidlconversion/AidlConversionCppNdk.cpp b/media/audioaidlconversion/AidlConversionCppNdk.cpp
index 8704314..d3907c3 100644
--- a/media/audioaidlconversion/AidlConversionCppNdk.cpp
+++ b/media/audioaidlconversion/AidlConversionCppNdk.cpp
@@ -83,6 +83,8 @@
using media::audio::common::AudioUuid;
using media::audio::common::ExtraAudioDescriptor;
using media::audio::common::Int;
+using media::audio::common::MicrophoneDynamicInfo;
+using media::audio::common::MicrophoneInfo;
using media::audio::common::PcmType;
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -2182,6 +2184,11 @@
audio_port_device_ext legacy{};
RETURN_IF_ERROR(aidl2legacy_AudioDevice_audio_device(
aidl.device, &legacy.type, legacy.address));
+ legacy.encapsulation_modes = VALUE_OR_RETURN(
+ aidl2legacy_AudioEncapsulationMode_mask(aidl.encapsulationModes));
+ legacy.encapsulation_metadata_types = VALUE_OR_RETURN(
+ aidl2legacy_AudioEncapsulationMetadataType_mask(
+ aidl.encapsulationMetadataTypes));
return legacy;
}
@@ -2190,6 +2197,10 @@
AudioPortDeviceExt aidl;
aidl.device = VALUE_OR_RETURN(
legacy2aidl_audio_device_AudioDevice(legacy.type, legacy.address));
+ aidl.encapsulationModes = VALUE_OR_RETURN(
+ legacy2aidl_AudioEncapsulationMode_mask(legacy.encapsulation_modes));
+ aidl.encapsulationMetadataTypes = VALUE_OR_RETURN(
+ legacy2aidl_AudioEncapsulationMetadataType_mask(legacy.encapsulation_metadata_types));
return aidl;
}
@@ -2711,6 +2722,280 @@
return unexpected(BAD_VALUE);
}
+ConversionResult<audio_microphone_location_t>
+aidl2legacy_MicrophoneInfoLocation_audio_microphone_location_t(MicrophoneInfo::Location aidl) {
+ switch (aidl) {
+ case MicrophoneInfo::Location::UNKNOWN:
+ return AUDIO_MICROPHONE_LOCATION_UNKNOWN;
+ case MicrophoneInfo::Location::MAINBODY:
+ return AUDIO_MICROPHONE_LOCATION_MAINBODY;
+ case MicrophoneInfo::Location::MAINBODY_MOVABLE:
+ return AUDIO_MICROPHONE_LOCATION_MAINBODY_MOVABLE;
+ case MicrophoneInfo::Location::PERIPHERAL:
+ return AUDIO_MICROPHONE_LOCATION_PERIPHERAL;
+ }
+ return unexpected(BAD_VALUE);
+}
+ConversionResult<MicrophoneInfo::Location>
+legacy2aidl_audio_microphone_location_t_MicrophoneInfoLocation(audio_microphone_location_t legacy) {
+ switch (legacy) {
+ case AUDIO_MICROPHONE_LOCATION_UNKNOWN:
+ return MicrophoneInfo::Location::UNKNOWN;
+ case AUDIO_MICROPHONE_LOCATION_MAINBODY:
+ return MicrophoneInfo::Location::MAINBODY;
+ case AUDIO_MICROPHONE_LOCATION_MAINBODY_MOVABLE:
+ return MicrophoneInfo::Location::MAINBODY_MOVABLE;
+ case AUDIO_MICROPHONE_LOCATION_PERIPHERAL:
+ return MicrophoneInfo::Location::PERIPHERAL;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<audio_microphone_group_t> aidl2legacy_int32_t_audio_microphone_group_t(
+ int32_t aidl) {
+ return convertReinterpret<audio_microphone_group_t>(aidl);
+}
+
+ConversionResult<int32_t> legacy2aidl_audio_microphone_group_t_int32_t(
+ audio_microphone_group_t legacy) {
+ return convertReinterpret<int32_t>(legacy);
+}
+
+ConversionResult<audio_microphone_directionality_t>
+aidl2legacy_MicrophoneInfoDirectionality_audio_microphone_directionality_t(
+ MicrophoneInfo::Directionality aidl) {
+ switch (aidl) {
+ case MicrophoneInfo::Directionality::UNKNOWN:
+ return AUDIO_MICROPHONE_DIRECTIONALITY_UNKNOWN;
+ case MicrophoneInfo::Directionality::OMNI:
+ return AUDIO_MICROPHONE_DIRECTIONALITY_OMNI;
+ case MicrophoneInfo::Directionality::BI_DIRECTIONAL:
+ return AUDIO_MICROPHONE_DIRECTIONALITY_BI_DIRECTIONAL;
+ case MicrophoneInfo::Directionality::CARDIOID:
+ return AUDIO_MICROPHONE_DIRECTIONALITY_CARDIOID;
+ case MicrophoneInfo::Directionality::HYPER_CARDIOID:
+ return AUDIO_MICROPHONE_DIRECTIONALITY_HYPER_CARDIOID;
+ case MicrophoneInfo::Directionality::SUPER_CARDIOID:
+ return AUDIO_MICROPHONE_DIRECTIONALITY_SUPER_CARDIOID;
+ }
+ return unexpected(BAD_VALUE);
+}
+ConversionResult<MicrophoneInfo::Directionality>
+legacy2aidl_audio_microphone_directionality_t_MicrophoneInfoDirectionality(
+ audio_microphone_directionality_t legacy) {
+ switch (legacy) {
+ case AUDIO_MICROPHONE_DIRECTIONALITY_UNKNOWN:
+ return MicrophoneInfo::Directionality::UNKNOWN;
+ case AUDIO_MICROPHONE_DIRECTIONALITY_OMNI:
+ return MicrophoneInfo::Directionality::OMNI;
+ case AUDIO_MICROPHONE_DIRECTIONALITY_BI_DIRECTIONAL:
+ return MicrophoneInfo::Directionality::BI_DIRECTIONAL;
+ case AUDIO_MICROPHONE_DIRECTIONALITY_CARDIOID:
+ return MicrophoneInfo::Directionality::CARDIOID;
+ case AUDIO_MICROPHONE_DIRECTIONALITY_HYPER_CARDIOID:
+ return MicrophoneInfo::Directionality::HYPER_CARDIOID;
+ case AUDIO_MICROPHONE_DIRECTIONALITY_SUPER_CARDIOID:
+ return MicrophoneInfo::Directionality::SUPER_CARDIOID;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<audio_microphone_coordinate>
+aidl2legacy_MicrophoneInfoCoordinate_audio_microphone_coordinate(
+ const MicrophoneInfo::Coordinate& aidl) {
+ audio_microphone_coordinate legacy;
+ legacy.x = aidl.x;
+ legacy.y = aidl.y;
+ legacy.z = aidl.z;
+ return legacy;
+}
+ConversionResult<MicrophoneInfo::Coordinate>
+legacy2aidl_audio_microphone_coordinate_MicrophoneInfoCoordinate(
+ const audio_microphone_coordinate& legacy) {
+ MicrophoneInfo::Coordinate aidl;
+ aidl.x = legacy.x;
+ aidl.y = legacy.y;
+ aidl.z = legacy.z;
+ return aidl;
+}
+
+ConversionResult<audio_microphone_channel_mapping_t>
+aidl2legacy_MicrophoneDynamicInfoChannelMapping_audio_microphone_channel_mapping_t(
+ MicrophoneDynamicInfo::ChannelMapping aidl) {
+ switch (aidl) {
+ case MicrophoneDynamicInfo::ChannelMapping::UNUSED:
+ return AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED;
+ case MicrophoneDynamicInfo::ChannelMapping::DIRECT:
+ return AUDIO_MICROPHONE_CHANNEL_MAPPING_DIRECT;
+ case MicrophoneDynamicInfo::ChannelMapping::PROCESSED:
+ return AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED;
+ }
+ return unexpected(BAD_VALUE);
+}
+ConversionResult<MicrophoneDynamicInfo::ChannelMapping>
+legacy2aidl_audio_microphone_channel_mapping_t_MicrophoneDynamicInfoChannelMapping(
+ audio_microphone_channel_mapping_t legacy) {
+ switch (legacy) {
+ case AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED:
+ return MicrophoneDynamicInfo::ChannelMapping::UNUSED;
+ case AUDIO_MICROPHONE_CHANNEL_MAPPING_DIRECT:
+ return MicrophoneDynamicInfo::ChannelMapping::DIRECT;
+ case AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED:
+ return MicrophoneDynamicInfo::ChannelMapping::PROCESSED;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<audio_microphone_characteristic_t>
+aidl2legacy_MicrophoneInfos_audio_microphone_characteristic_t(
+ const MicrophoneInfo& aidlInfo, const MicrophoneDynamicInfo& aidlDynamic) {
+ static const audio_microphone_coordinate kCoordinateUnknown = {
+ AUDIO_MICROPHONE_COORDINATE_UNKNOWN, AUDIO_MICROPHONE_COORDINATE_UNKNOWN,
+ AUDIO_MICROPHONE_COORDINATE_UNKNOWN };
+ audio_microphone_characteristic_t legacy{};
+ if (aidlInfo.id != aidlDynamic.id) {
+ return unexpected(BAD_VALUE);
+ }
+ // Note: in the legacy structure, 'device_id' is the mic's ID, 'id' is APM port id.
+ RETURN_IF_ERROR(aidl2legacy_string(aidlInfo.id, legacy.device_id, AUDIO_MICROPHONE_ID_MAX_LEN));
+ RETURN_IF_ERROR(aidl2legacy_AudioDevice_audio_device(
+ aidlInfo.device, &legacy.device, legacy.address));
+ legacy.location = VALUE_OR_RETURN(
+ aidl2legacy_MicrophoneInfoLocation_audio_microphone_location_t(aidlInfo.location));
+ legacy.group = VALUE_OR_RETURN(aidl2legacy_int32_t_audio_microphone_group_t(aidlInfo.group));
+ // For some reason, the legacy field is unsigned, however in the SDK layer it is signed,
+ // as it is in AIDL. So, use UINT_MAX for INDEX_IN_THE_GROUP_UNKNOWN which is -1.
+ if (aidlInfo.indexInTheGroup != MicrophoneInfo::INDEX_IN_THE_GROUP_UNKNOWN) {
+ legacy.index_in_the_group = VALUE_OR_RETURN(
+ convertReinterpret<unsigned int>(aidlInfo.indexInTheGroup));
+ } else {
+ legacy.index_in_the_group = UINT_MAX;
+ }
+ if (aidlInfo.sensitivity.has_value()) {
+ legacy.sensitivity = aidlInfo.sensitivity.value().leveldBFS;
+ legacy.max_spl = aidlInfo.sensitivity.value().maxSpldB;
+ legacy.min_spl = aidlInfo.sensitivity.value().minSpldB;
+ } else {
+ legacy.sensitivity = AUDIO_MICROPHONE_SENSITIVITY_UNKNOWN;
+ legacy.max_spl = AUDIO_MICROPHONE_SPL_UNKNOWN;
+ legacy.min_spl = AUDIO_MICROPHONE_SPL_UNKNOWN;
+ }
+ legacy.directionality = VALUE_OR_RETURN(
+ aidl2legacy_MicrophoneInfoDirectionality_audio_microphone_directionality_t(
+ aidlInfo.directionality));
+ if (aidlInfo.frequencyResponse.size() > AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES) {
+ return unexpected(BAD_VALUE);
+ }
+ legacy.num_frequency_responses = 0;
+ for (const auto& p: aidlInfo.frequencyResponse) {
+ legacy.frequency_responses[0][legacy.num_frequency_responses] = p.frequencyHz;
+ legacy.frequency_responses[1][legacy.num_frequency_responses++] = p.leveldB;
+ }
+ if (aidlInfo.position.has_value()) {
+ legacy.geometric_location = VALUE_OR_RETURN(
+ aidl2legacy_MicrophoneInfoCoordinate_audio_microphone_coordinate(
+ aidlInfo.position.value()));
+ } else {
+ legacy.geometric_location = kCoordinateUnknown;
+ }
+ if (aidlInfo.orientation.has_value()) {
+ legacy.orientation = VALUE_OR_RETURN(
+ aidl2legacy_MicrophoneInfoCoordinate_audio_microphone_coordinate(
+ aidlInfo.orientation.value()));
+ } else {
+ legacy.orientation = kCoordinateUnknown;
+ }
+ if (aidlDynamic.channelMapping.size() > AUDIO_CHANNEL_COUNT_MAX) {
+ return unexpected(BAD_VALUE);
+ }
+ size_t i = 0;
+ for (; i < aidlDynamic.channelMapping.size(); ++i) {
+ legacy.channel_mapping[i] = VALUE_OR_RETURN(
+ aidl2legacy_MicrophoneDynamicInfoChannelMapping_audio_microphone_channel_mapping_t(
+ aidlDynamic.channelMapping[i]));
+ }
+ for (; i < AUDIO_CHANNEL_COUNT_MAX; ++i) {
+ legacy.channel_mapping[i] = AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED;
+ }
+ return legacy;
+}
+
+status_t
+legacy2aidl_audio_microphone_characteristic_t_MicrophoneInfos(
+ const audio_microphone_characteristic_t& legacy,
+ MicrophoneInfo* aidlInfo, MicrophoneDynamicInfo* aidlDynamic) {
+ aidlInfo->id = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_string(legacy.device_id, AUDIO_MICROPHONE_ID_MAX_LEN));
+ aidlDynamic->id = aidlInfo->id;
+ aidlInfo->device = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_device_AudioDevice(
+ legacy.device, legacy.address));
+ aidlInfo->location = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_microphone_location_t_MicrophoneInfoLocation(legacy.location));
+ aidlInfo->group = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_microphone_group_t_int32_t(legacy.group));
+ // For some reason, the legacy field is unsigned, however in the SDK layer it is signed,
+ // as it is in AIDL. So, use UINT_MAX for INDEX_IN_THE_GROUP_UNKNOWN which is -1.
+ if (legacy.index_in_the_group != UINT_MAX) {
+ aidlInfo->indexInTheGroup = VALUE_OR_RETURN_STATUS(
+ convertReinterpret<int32_t>(legacy.index_in_the_group));
+ } else {
+ aidlInfo->indexInTheGroup = MicrophoneInfo::INDEX_IN_THE_GROUP_UNKNOWN;
+ }
+ if (legacy.sensitivity != AUDIO_MICROPHONE_SENSITIVITY_UNKNOWN &&
+ legacy.max_spl != AUDIO_MICROPHONE_SPL_UNKNOWN &&
+ legacy.min_spl != AUDIO_MICROPHONE_SPL_UNKNOWN) {
+ MicrophoneInfo::Sensitivity sensitivity;
+ sensitivity.leveldBFS = legacy.sensitivity;
+ sensitivity.maxSpldB = legacy.max_spl;
+ sensitivity.minSpldB = legacy.min_spl;
+ aidlInfo->sensitivity = std::move(sensitivity);
+ } else {
+ aidlInfo->sensitivity = {};
+ }
+ aidlInfo->directionality = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_microphone_directionality_t_MicrophoneInfoDirectionality(
+ legacy.directionality));
+ if (legacy.num_frequency_responses > AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES) {
+ return BAD_VALUE;
+ }
+ aidlInfo->frequencyResponse.resize(legacy.num_frequency_responses);
+ for (size_t i = 0; i < legacy.num_frequency_responses; ++i) {
+ aidlInfo->frequencyResponse[i].frequencyHz = legacy.frequency_responses[0][i];
+ aidlInfo->frequencyResponse[i].leveldB = legacy.frequency_responses[1][i];
+ }
+ if (legacy.geometric_location.x != AUDIO_MICROPHONE_COORDINATE_UNKNOWN &&
+ legacy.geometric_location.y != AUDIO_MICROPHONE_COORDINATE_UNKNOWN &&
+ legacy.geometric_location.z != AUDIO_MICROPHONE_COORDINATE_UNKNOWN) {
+ aidlInfo->position = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_microphone_coordinate_MicrophoneInfoCoordinate(
+ legacy.geometric_location));
+ } else {
+ aidlInfo->position = {};
+ }
+ if (legacy.orientation.x != AUDIO_MICROPHONE_COORDINATE_UNKNOWN &&
+ legacy.orientation.y != AUDIO_MICROPHONE_COORDINATE_UNKNOWN &&
+ legacy.orientation.z != AUDIO_MICROPHONE_COORDINATE_UNKNOWN) {
+ aidlInfo->orientation = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_microphone_coordinate_MicrophoneInfoCoordinate(
+ legacy.orientation));
+ } else {
+ aidlInfo->orientation = {};
+ }
+ size_t channelsUsed = AUDIO_CHANNEL_COUNT_MAX;
+ while (channelsUsed != 0 &&
+ legacy.channel_mapping[--channelsUsed] == AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED) {}
+ // Doing an increment is correct even when channel 0 is 'UNUSED',
+ // that's because AIDL requires to have at least 1 element in the mapping.
+ ++channelsUsed;
+ aidlDynamic->channelMapping.resize(channelsUsed);
+ for (size_t i = 0; i < channelsUsed; ++i) {
+ aidlDynamic->channelMapping[i] = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_microphone_channel_mapping_t_MicrophoneDynamicInfoChannelMapping(
+ legacy.channel_mapping[i]));
+ }
+ return OK;
+}
+
} // namespace android
#if defined(BACKEND_NDK)
diff --git a/media/audioaidlconversion/AidlConversionEffect.cpp b/media/audioaidlconversion/AidlConversionEffect.cpp
index ad27c64..c053a5d 100644
--- a/media/audioaidlconversion/AidlConversionEffect.cpp
+++ b/media/audioaidlconversion/AidlConversionEffect.cpp
@@ -14,12 +14,16 @@
* limitations under the License.
*/
+#include <cstdint>
+#include <inttypes.h>
#include <utility>
#define LOG_TAG "AidlConversionEffect"
//#define LOG_NDEBUG 0
#include <utils/Log.h>
+#include <aidl/android/hardware/audio/effect/DefaultExtension.h>
+#include <aidl/android/hardware/audio/effect/VendorExtension.h>
#include <media/AidlConversionCppNdk.h>
#include <media/AidlConversionEffect.h>
@@ -30,18 +34,24 @@
namespace android {
using ::aidl::android::hardware::audio::effect::AcousticEchoCanceler;
-using ::aidl::android::hardware::audio::effect::AutomaticGainControl;
+using ::aidl::android::hardware::audio::effect::AutomaticGainControlV2;
using ::aidl::android::hardware::audio::effect::BassBoost;
+using ::aidl::android::hardware::audio::effect::DefaultExtension;
using ::aidl::android::hardware::audio::effect::Descriptor;
using ::aidl::android::hardware::audio::effect::Downmix;
using ::aidl::android::hardware::audio::effect::DynamicsProcessing;
using ::aidl::android::hardware::audio::effect::Flags;
using ::aidl::android::hardware::audio::effect::Parameter;
using ::aidl::android::hardware::audio::effect::PresetReverb;
+using ::aidl::android::hardware::audio::effect::VendorExtension;
+using ::aidl::android::hardware::audio::effect::Visualizer;
using ::aidl::android::media::audio::common::AudioDeviceDescription;
using ::android::BAD_VALUE;
+using ::android::OK;
using ::android::base::unexpected;
+using ::android::effect::utils::EffectParamReader;
+using ::android::effect::utils::EffectParamWriter;
////////////////////////////////////////////////////////////////////////////////////////////////////
// Converters
@@ -260,46 +270,47 @@
ConversionResult<uint32_t> aidl2legacy_Parameter_agc_uint32_fixedDigitalGain(
const Parameter& aidl) {
int gain = VALUE_OR_RETURN(
- GET_PARAMETER_SPECIFIC_FIELD(aidl, AutomaticGainControl, automaticGainControl,
- AutomaticGainControl::fixedDigitalGainMb, int));
+ GET_PARAMETER_SPECIFIC_FIELD(aidl, AutomaticGainControlV2, automaticGainControlV2,
+ AutomaticGainControlV2::fixedDigitalGainMb, int));
return VALUE_OR_RETURN(convertReinterpret<uint32_t>(gain));
}
ConversionResult<Parameter> legacy2aidl_uint32_fixedDigitalGain_Parameter_agc(uint32_t legacy) {
int gain = VALUE_OR_RETURN(convertReinterpret<int>(legacy));
- return MAKE_SPECIFIC_PARAMETER(AutomaticGainControl, automaticGainControl, fixedDigitalGainMb,
- gain);
+ return MAKE_SPECIFIC_PARAMETER(AutomaticGainControlV2, automaticGainControlV2,
+ fixedDigitalGainMb, gain);
}
ConversionResult<uint32_t> aidl2legacy_Parameter_agc_uint32_levelEstimator(
const Parameter& aidl) {
const auto& le = VALUE_OR_RETURN(GET_PARAMETER_SPECIFIC_FIELD(
- aidl, AutomaticGainControl, automaticGainControl, AutomaticGainControl::levelEstimator,
- AutomaticGainControl::LevelEstimator));
+ aidl, AutomaticGainControlV2, automaticGainControlV2,
+ AutomaticGainControlV2::levelEstimator, AutomaticGainControlV2::LevelEstimator));
return static_cast<uint32_t>(le);
}
ConversionResult<Parameter> legacy2aidl_uint32_levelEstimator_Parameter_agc(uint32_t legacy) {
- if (legacy > (uint32_t) AutomaticGainControl::LevelEstimator::PEAK) {
+ if (legacy > (uint32_t)AutomaticGainControlV2::LevelEstimator::PEAK) {
return unexpected(BAD_VALUE);
}
- AutomaticGainControl::LevelEstimator le =
- static_cast<AutomaticGainControl::LevelEstimator>(legacy);
- return MAKE_SPECIFIC_PARAMETER(AutomaticGainControl, automaticGainControl, levelEstimator, le);
+ AutomaticGainControlV2::LevelEstimator le =
+ static_cast<AutomaticGainControlV2::LevelEstimator>(legacy);
+ return MAKE_SPECIFIC_PARAMETER(AutomaticGainControlV2, automaticGainControlV2, levelEstimator,
+ le);
}
ConversionResult<uint32_t> aidl2legacy_Parameter_agc_uint32_saturationMargin(
const Parameter& aidl) {
int saturationMargin = VALUE_OR_RETURN(
- GET_PARAMETER_SPECIFIC_FIELD(aidl, AutomaticGainControl, automaticGainControl,
- AutomaticGainControl::saturationMarginMb, int));
+ GET_PARAMETER_SPECIFIC_FIELD(aidl, AutomaticGainControlV2, automaticGainControlV2,
+ AutomaticGainControlV2::saturationMarginMb, int));
return VALUE_OR_RETURN(convertIntegral<uint32_t>(saturationMargin));
}
ConversionResult<Parameter> legacy2aidl_uint32_saturationMargin_Parameter_agc(uint32_t legacy) {
int saturationMargin = VALUE_OR_RETURN(convertIntegral<int>(legacy));
- return MAKE_SPECIFIC_PARAMETER(AutomaticGainControl, automaticGainControl, saturationMarginMb,
- saturationMargin);
+ return MAKE_SPECIFIC_PARAMETER(AutomaticGainControlV2, automaticGainControlV2,
+ saturationMarginMb, saturationMargin);
}
ConversionResult<uint16_t> aidl2legacy_Parameter_BassBoost_uint16_strengthPm(
@@ -348,5 +359,116 @@
return static_cast<int32_t>(aidl);
}
+ConversionResult<uint32_t> aidl2legacy_Parameter_Visualizer_ScalingMode_uint32(
+ Visualizer::ScalingMode aidl) {
+ switch (aidl) {
+ case Visualizer::ScalingMode::NORMALIZED: {
+ return 0;
+ }
+ case Visualizer::ScalingMode::AS_PLAYED: {
+ return 1;
+ }
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<Visualizer::ScalingMode> legacy2aidl_Parameter_Visualizer_uint32_ScalingMode(
+ uint32_t legacy) {
+ if (legacy == 0) {
+ return Visualizer::ScalingMode::NORMALIZED;
+ } else if (legacy == 1) {
+ return Visualizer::ScalingMode::AS_PLAYED;
+ } else {
+ return unexpected(BAD_VALUE);
+ }
+}
+
+ConversionResult<uint32_t> aidl2legacy_Parameter_Visualizer_MeasurementMode_uint32(
+ Visualizer::MeasurementMode aidl) {
+ switch (aidl) {
+ case Visualizer::MeasurementMode::NONE: {
+ return 0;
+ }
+ case Visualizer::MeasurementMode::PEAK_RMS: {
+ return 1;
+ }
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<Visualizer::MeasurementMode>
+legacy2aidl_Parameter_Visualizer_uint32_MeasurementMode(uint32_t legacy) {
+ if (legacy == 0) {
+ return Visualizer::MeasurementMode::NONE;
+ } else if (legacy == 1) {
+ return Visualizer::MeasurementMode::PEAK_RMS;
+ } else {
+ return unexpected(BAD_VALUE);
+ }
+}
+
+/**
+ * Copy the parameter area of effect_param_t to DefaultExtension::bytes.
+ */
+ConversionResult<VendorExtension> legacy2aidl_EffectParameterReader_Param_VendorExtension(
+ EffectParamReader& param) {
+ size_t len = param.getParameterSize();
+ DefaultExtension defaultExt;
+ defaultExt.bytes.resize(len);
+ RETURN_IF_ERROR(param.readFromParameter(defaultExt.bytes.data(), len));
+
+ VendorExtension ext;
+ ext.extension.setParcelable(defaultExt);
+ return ext;
+}
+
+/**
+ * Copy the data area of effect_param_t to DefaultExtension::bytes.
+ */
+ConversionResult<VendorExtension> legacy2aidl_EffectParameterReader_Data_VendorExtension(
+ EffectParamReader& param) {
+ size_t len = param.getValueSize();
+ DefaultExtension defaultExt;
+ defaultExt.bytes.resize(len);
+ RETURN_IF_ERROR(param.readFromValue(defaultExt.bytes.data(), len));
+
+ VendorExtension ext;
+ ext.extension.setParcelable(defaultExt);
+ return ext;
+}
+
+/**
+ * Copy DefaultExtension::bytes to the data area of effect_param_t.
+ */
+ConversionResult<status_t> aidl2legacy_VendorExtension_EffectParameterWriter_Data(
+ EffectParamWriter& param, VendorExtension ext) {
+ std::optional<DefaultExtension> defaultExt;
+ RETURN_IF_ERROR(ext.extension.getParcelable(&defaultExt));
+ if (!defaultExt.has_value()) {
+ return unexpected(BAD_VALUE);
+ }
+
+ RETURN_IF_ERROR(param.writeToValue(defaultExt->bytes.data(), defaultExt->bytes.size()));
+
+ return OK;
+}
+
+ConversionResult<Parameter> legacy2aidl_EffectParameterReader_ParameterExtension(
+ EffectParamReader& param) {
+ VendorExtension ext =
+ VALUE_OR_RETURN(legacy2aidl_EffectParameterReader_Data_VendorExtension(param));
+ return UNION_MAKE(Parameter, specific, UNION_MAKE(Parameter::Specific, vendorEffect, ext));
+}
+
+ConversionResult<::android::status_t> aidl2legacy_ParameterExtension_EffectParameterWriter(
+ const ::aidl::android::hardware::audio::effect::Parameter& aidl,
+ EffectParamWriter& legacy) {
+ VendorExtension ext = VALUE_OR_RETURN(
+ (::aidl::android::getParameterSpecific<Parameter, VendorExtension,
+ Parameter::Specific::vendorEffect>(aidl)));
+ return VALUE_OR_RETURN_STATUS(
+ aidl2legacy_VendorExtension_EffectParameterWriter_Data(legacy, ext));
+}
+
} // namespace android
} // aidl
diff --git a/media/audioaidlconversion/include/media/AidlConversionCppNdk.h b/media/audioaidlconversion/include/media/AidlConversionCppNdk.h
index c412238..e1daf31 100644
--- a/media/audioaidlconversion/include/media/AidlConversionCppNdk.h
+++ b/media/audioaidlconversion/include/media/AidlConversionCppNdk.h
@@ -61,6 +61,8 @@
#include PREFIX(android/media/audio/common/AudioUuid.h)
#include PREFIX(android/media/audio/common/ExtraAudioDescriptor.h)
#include PREFIX(android/media/audio/common/Int.h)
+#include PREFIX(android/media/audio/common/MicrophoneDynamicInfo.h)
+#include PREFIX(android/media/audio/common/MicrophoneInfo.h)
#undef PREFIX
#include <media/AidlConversionUtil.h>
@@ -125,6 +127,11 @@
ConversionResult<media::audio::common::AudioChannelLayout>
legacy2aidl_audio_channel_mask_t_AudioChannelLayout(audio_channel_mask_t legacy, bool isInput);
+audio_channel_mask_t aidl2legacy_AudioChannelLayout_layout_audio_channel_mask_t_bits(
+ int aidlLayout, bool isInput);
+int legacy2aidl_audio_channel_mask_t_bits_AudioChannelLayout_layout(
+ audio_channel_mask_t legacy, bool isInput);
+
enum class AudioPortDirection {
INPUT, OUTPUT
};
@@ -371,6 +378,48 @@
ConversionResult<media::audio::common::AudioLatencyMode>
legacy2aidl_audio_latency_mode_t_AudioLatencyMode(audio_latency_mode_t legacy);
+ConversionResult<audio_microphone_location_t>
+aidl2legacy_MicrophoneInfoLocation_audio_microphone_location_t(
+ media::audio::common::MicrophoneInfo::Location aidl);
+ConversionResult<media::audio::common::MicrophoneInfo::Location>
+legacy2aidl_audio_microphone_location_t_MicrophoneInfoLocation(audio_microphone_location_t legacy);
+
+ConversionResult<audio_microphone_group_t> aidl2legacy_int32_t_audio_microphone_group_t(
+ int32_t aidl);
+ConversionResult<int32_t> legacy2aidl_audio_microphone_group_t_int32_t(
+ audio_microphone_group_t legacy);
+
+ConversionResult<audio_microphone_directionality_t>
+aidl2legacy_MicrophoneInfoDirectionality_audio_microphone_directionality_t(
+ media::audio::common::MicrophoneInfo::Directionality aidl);
+ConversionResult<media::audio::common::MicrophoneInfo::Directionality>
+legacy2aidl_audio_microphone_directionality_t_MicrophoneInfoDirectionality(
+ audio_microphone_directionality_t legacy);
+
+ConversionResult<audio_microphone_coordinate>
+aidl2legacy_MicrophoneInfoCoordinate_audio_microphone_coordinate(
+ const media::audio::common::MicrophoneInfo::Coordinate& aidl);
+ConversionResult<media::audio::common::MicrophoneInfo::Coordinate>
+legacy2aidl_audio_microphone_coordinate_MicrophoneInfoCoordinate(
+ const audio_microphone_coordinate& legacy);
+
+ConversionResult<audio_microphone_channel_mapping_t>
+aidl2legacy_MicrophoneDynamicInfoChannelMapping_audio_microphone_channel_mapping_t(
+ media::audio::common::MicrophoneDynamicInfo::ChannelMapping aidl);
+ConversionResult<media::audio::common::MicrophoneDynamicInfo::ChannelMapping>
+legacy2aidl_audio_microphone_channel_mapping_t_MicrophoneDynamicInfoChannelMapping(
+ audio_microphone_channel_mapping_t legacy);
+
+ConversionResult<audio_microphone_characteristic_t>
+aidl2legacy_MicrophoneInfos_audio_microphone_characteristic_t(
+ const media::audio::common::MicrophoneInfo& aidlInfo,
+ const media::audio::common::MicrophoneDynamicInfo& aidlDynamic);
+status_t
+legacy2aidl_audio_microphone_characteristic_t_MicrophoneInfos(
+ const audio_microphone_characteristic_t& legacy,
+ media::audio::common::MicrophoneInfo* aidlInfo,
+ media::audio::common::MicrophoneDynamicInfo* aidlDynamic);
+
} // namespace android
#if defined(BACKEND_NDK)
diff --git a/media/audioaidlconversion/include/media/AidlConversionEffect.h b/media/audioaidlconversion/include/media/AidlConversionEffect.h
index 83aa614..5e245a7 100644
--- a/media/audioaidlconversion/include/media/AidlConversionEffect.h
+++ b/media/audioaidlconversion/include/media/AidlConversionEffect.h
@@ -26,6 +26,7 @@
#include <hardware/audio_effect.h>
#include <media/AidlConversionUtil.h>
#include <system/audio_effect.h>
+#include <system/audio_effects/audio_effects_utils.h>
#include <aidl/android/hardware/audio/effect/IEffect.h>
@@ -45,19 +46,39 @@
return VALUE_OR_RETURN((unionGetField<T, field>(spec)));
}
-#define GET_PARAMETER_SPECIFIC_FIELD(u, specific, tag, field, fieldType) \
- getParameterSpecificField<std::decay_t<decltype(u)>, specific, \
- aidl::android::hardware::audio::effect::Parameter::Specific::tag, \
- specific::field, fieldType>(u)
+#define GET_PARAMETER_SPECIFIC_FIELD(_u, _effect, _tag, _field, _fieldType) \
+ getParameterSpecificField<std::decay_t<decltype(_u)>, _effect, \
+ aidl::android::hardware::audio::effect::Parameter::Specific::_tag, \
+ _effect::_field, _fieldType>(_u)
-#define MAKE_SPECIFIC_PARAMETER(spec, tag, field, value) \
- UNION_MAKE(aidl::android::hardware::audio::effect::Parameter, specific, \
- UNION_MAKE(aidl::android::hardware::audio::effect::Parameter::Specific, tag, \
- UNION_MAKE(spec, field, value)))
+#define MAKE_SPECIFIC_PARAMETER(_spec, _tag, _field, _value) \
+ UNION_MAKE(aidl::android::hardware::audio::effect::Parameter, specific, \
+ UNION_MAKE(aidl::android::hardware::audio::effect::Parameter::Specific, _tag, \
+ UNION_MAKE(_spec, _field, _value)))
-#define MAKE_SPECIFIC_PARAMETER_ID(spec, tag, field) \
- UNION_MAKE(aidl::android::hardware::audio::effect::Parameter::Id, tag, \
- UNION_MAKE(spec::Id, commonTag, field))
+#define MAKE_SPECIFIC_PARAMETER_ID(_spec, _tag, _field) \
+ UNION_MAKE(aidl::android::hardware::audio::effect::Parameter::Id, _tag, \
+ UNION_MAKE(_spec::Id, commonTag, _field))
+
+#define MAKE_EXTENSION_PARAMETER_ID(_effect, _tag, _field) \
+ UNION_MAKE(aidl::android::hardware::audio::effect::Parameter::Id, _tag, \
+ UNION_MAKE(_effect::Id, vendorExtensionTag, _field))
+
+#define VENDOR_EXTENSION_GET_AND_RETURN(_effect, _tag, _param) \
+ { \
+ aidl::android::hardware::audio::effect::VendorExtension _extId = VALUE_OR_RETURN_STATUS( \
+ aidl::android::legacy2aidl_EffectParameterReader_Param_VendorExtension(_param)); \
+ aidl::android::hardware::audio::effect::Parameter::Id _id = \
+ MAKE_EXTENSION_PARAMETER_ID(_effect, _tag##Tag, _extId); \
+ aidl::android::hardware::audio::effect::Parameter _aidlParam; \
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(_id, &_aidlParam))); \
+ aidl::android::hardware::audio::effect::VendorExtension _ext = \
+ VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD( \
+ _aidlParam, _effect, _tag, _effect::vendor, VendorExtension)); \
+ return VALUE_OR_RETURN_STATUS( \
+ aidl::android::aidl2legacy_ParameterExtension_EffectParameterWriter(_aidlParam, \
+ _param)); \
+ }
ConversionResult<uint32_t> aidl2legacy_Flags_Type_uint32(
::aidl::android::hardware::audio::effect::Flags::Type type);
@@ -126,5 +147,36 @@
ConversionResult<int32_t> aidl2legacy_DynamicsProcessing_ResolutionPreference_int32(
::aidl::android::hardware::audio::effect::DynamicsProcessing::ResolutionPreference aidl);
+ConversionResult<uint32_t> aidl2legacy_Parameter_Visualizer_ScalingMode_uint32(
+ ::aidl::android::hardware::audio::effect::Visualizer::ScalingMode aidl);
+ConversionResult<::aidl::android::hardware::audio::effect::Visualizer::ScalingMode>
+legacy2aidl_Parameter_Visualizer_uint32_ScalingMode(uint32_t legacy);
+
+ConversionResult<uint32_t> aidl2legacy_Parameter_Visualizer_MeasurementMode_uint32(
+ ::aidl::android::hardware::audio::effect::Visualizer::MeasurementMode aidl);
+ConversionResult<::aidl::android::hardware::audio::effect::Visualizer::MeasurementMode>
+legacy2aidl_Parameter_Visualizer_uint32_MeasurementMode(uint32_t legacy);
+
+ConversionResult<::aidl::android::hardware::audio::effect::Parameter>
+legacy2aidl_EffectParameterReader_ParameterExtension(
+ ::android::effect::utils::EffectParamReader& param);
+ConversionResult<::android::status_t> aidl2legacy_ParameterExtension_EffectParameterWriter(
+ const ::aidl::android::hardware::audio::effect::Parameter& aidl,
+ ::android::effect::utils::EffectParamWriter& legacy);
+
+ConversionResult<::aidl::android::hardware::audio::effect::VendorExtension>
+legacy2aidl_EffectParameterReader_Param_VendorExtension(
+ ::android::effect::utils::EffectParamReader& param);
+ConversionResult<::aidl::android::hardware::audio::effect::VendorExtension>
+legacy2aidl_EffectParameterReader_Data_VendorExtension(
+ ::android::effect::utils::EffectParamReader& param);
+
+ConversionResult<::android::status_t> aidl2legacy_VendorExtension_EffectParameterWriter_Data(
+ ::android::effect::utils::EffectParamWriter& param,
+ ::aidl::android::hardware::audio::effect::VendorExtension ext);
+ConversionResult<::aidl::android::hardware::audio::effect::Parameter>
+legacy2aidl_EffectParameterReader_ParameterExtension(
+ ::android::effect::utils::EffectParamReader& param);
+
} // namespace android
} // namespace aidl
diff --git a/media/codec2/vndk/internal/C2BlockInternal.h b/media/codec2/vndk/internal/C2BlockInternal.h
index c510fca..6bcad4a 100644
--- a/media/codec2/vndk/internal/C2BlockInternal.h
+++ b/media/codec2/vndk/internal/C2BlockInternal.h
@@ -238,7 +238,7 @@
* - Local migration on blockpool side will be done automatically by
* blockpool.
* - Before attachBuffer(), BeginAttachBlockToBufferQueue() should be called
- * to test eligiblity.
+ * to test eligibility.
* - After attachBuffer() is called, EndAttachBlockToBufferQueue() should
* be called. This will set "held" status to true. If it returned
* false, cancelBuffer() should be called.
diff --git a/media/libaaudio/examples/loopback/src/loopback.cpp b/media/libaaudio/examples/loopback/src/loopback.cpp
index 6fff568..4affaed 100644
--- a/media/libaaudio/examples/loopback/src/loopback.cpp
+++ b/media/libaaudio/examples/loopback/src/loopback.cpp
@@ -108,7 +108,7 @@
aaudio_result_t outputError = AAUDIO_OK;
GlitchAnalyzer sineAnalyzer;
- PulseLatencyAnalyzer echoAnalyzer;
+ WhiteNoiseLatencyAnalyzer echoAnalyzer;
AudioRecording audioRecording;
LoopbackProcessor *loopbackProcessor;
diff --git a/media/libaudioclient/AidlConversion.cpp b/media/libaudioclient/AidlConversion.cpp
index b3c8643..b32667e 100644
--- a/media/libaudioclient/AidlConversion.cpp
+++ b/media/libaudioclient/AidlConversion.cpp
@@ -724,11 +724,6 @@
aidl2legacy_AudioPortDeviceExt_audio_port_device_ext(aidl));
legacy.hw_module = VALUE_OR_RETURN(
aidl2legacy_int32_t_audio_module_handle_t(aidlSys.hwModule));
- 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;
}
@@ -738,10 +733,6 @@
*aidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_port_device_ext_AudioPortDeviceExt(legacy));
aidlDeviceExt->hwModule = VALUE_OR_RETURN_STATUS(
legacy2aidl_audio_module_handle_t_int32_t(legacy.hw_module));
- 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;
}
@@ -990,4 +981,24 @@
indexToEnum_bitmask<audio_direct_mode_t>,
enumToMask_index<int32_t, media::AudioDirectMode>);
}
+
+ConversionResult<audio_microphone_characteristic_t>
+aidl2legacy_MicrophoneInfoFw_audio_microphone_characteristic_t(
+ const media::MicrophoneInfoFw& aidl) {
+ audio_microphone_characteristic_t legacy =
+ VALUE_OR_RETURN(aidl2legacy_MicrophoneInfos_audio_microphone_characteristic_t(
+ aidl.info, aidl.dynamic));
+ legacy.id = VALUE_OR_RETURN(aidl2legacy_int32_t_audio_port_handle_t(aidl.portId));
+ return legacy;
+}
+ConversionResult<media::MicrophoneInfoFw>
+legacy2aidl_audio_microphone_characteristic_t_MicrophoneInfoFw(
+ const audio_microphone_characteristic_t& legacy) {
+ media::MicrophoneInfoFw aidl;
+ RETURN_IF_ERROR(legacy2aidl_audio_microphone_characteristic_t_MicrophoneInfos(
+ legacy, &aidl.info, &aidl.dynamic));
+ aidl.portId = VALUE_OR_RETURN(legacy2aidl_audio_port_handle_t_int32_t(legacy.id));
+ return aidl;
+}
+
} // namespace android
diff --git a/media/libaudioclient/Android.bp b/media/libaudioclient/Android.bp
index 1c0535d..30658f7 100644
--- a/media/libaudioclient/Android.bp
+++ b/media/libaudioclient/Android.bp
@@ -199,6 +199,7 @@
srcs: ["AidlConversion.cpp"],
shared_libs: [
"audioclient-types-aidl-cpp",
+ "av-types-aidl-cpp",
],
static_libs: [
"libaudio_aidl_conversion_common_cpp",
@@ -212,6 +213,7 @@
],
export_shared_lib_headers: [
"audioclient-types-aidl-cpp",
+ "av-types-aidl-cpp",
],
defaults: [
"audio_aidl_conversion_common_default",
diff --git a/media/libaudioclient/AudioRecord.cpp b/media/libaudioclient/AudioRecord.cpp
index 69d73ad..91b54a8 100644
--- a/media/libaudioclient/AudioRecord.cpp
+++ b/media/libaudioclient/AudioRecord.cpp
@@ -1617,16 +1617,10 @@
// -------------------------------------------------------------------------
-status_t AudioRecord::getActiveMicrophones(std::vector<media::MicrophoneInfo>* activeMicrophones)
+status_t AudioRecord::getActiveMicrophones(std::vector<media::MicrophoneInfoFw>* activeMicrophones)
{
AutoMutex lock(mLock);
- std::vector<media::MicrophoneInfoData> mics;
- status_t status = statusTFromBinderStatus(mAudioRecord->getActiveMicrophones(&mics));
- activeMicrophones->resize(mics.size());
- for (size_t i = 0; status == OK && i < mics.size(); ++i) {
- status = activeMicrophones->at(i).readFromParcelable(mics[i]);
- }
- return status;
+ return statusTFromBinderStatus(mAudioRecord->getActiveMicrophones(activeMicrophones));
}
status_t AudioRecord::setPreferredMicrophoneDirection(audio_microphone_direction_t direction)
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index 31d95e6..6ffbdc4 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -1904,7 +1904,7 @@
return result.value_or(NAN);
}
-status_t AudioSystem::getMicrophones(std::vector<media::MicrophoneInfo>* microphones) {
+status_t AudioSystem::getMicrophones(std::vector<media::MicrophoneInfoFw>* microphones) {
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
return af->getMicrophones(microphones);
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index 255fd1e..a005ab4 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -746,14 +746,11 @@
}
status_t
-AudioFlingerClientAdapter::getMicrophones(std::vector<media::MicrophoneInfo>* microphones) {
- std::vector<media::MicrophoneInfoData> aidlRet;
- RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
- mDelegate->getMicrophones(&aidlRet)));
+AudioFlingerClientAdapter::getMicrophones(std::vector<media::MicrophoneInfoFw>* microphones) {
+ std::vector<media::MicrophoneInfoFw> aidlRet;
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mDelegate->getMicrophones(&aidlRet)));
if (microphones != nullptr) {
- *microphones = VALUE_OR_RETURN_STATUS(
- convertContainer<std::vector<media::MicrophoneInfo>>(aidlRet,
- media::aidl2legacy_MicrophoneInfo));
+ *microphones = std::move(aidlRet);
}
return OK;
}
@@ -1309,11 +1306,8 @@
}
Status AudioFlingerServerAdapter::getMicrophones(
- std::vector<media::MicrophoneInfoData>* _aidl_return) {
- std::vector<media::MicrophoneInfo> resultLegacy;
- RETURN_BINDER_IF_ERROR(mDelegate->getMicrophones(&resultLegacy));
- *_aidl_return = VALUE_OR_RETURN_BINDER(convertContainer<std::vector<media::MicrophoneInfoData>>(
- resultLegacy, media::legacy2aidl_MicrophoneInfo));
+ std::vector<media::MicrophoneInfoFw>* _aidl_return) {
+ RETURN_BINDER_IF_ERROR(mDelegate->getMicrophones(_aidl_return));
return Status::ok();
}
diff --git a/media/libaudioclient/aidl/android/media/AudioPortDeviceExtSys.aidl b/media/libaudioclient/aidl/android/media/AudioPortDeviceExtSys.aidl
index 0f5a9b6..24ec230 100644
--- a/media/libaudioclient/aidl/android/media/AudioPortDeviceExtSys.aidl
+++ b/media/libaudioclient/aidl/android/media/AudioPortDeviceExtSys.aidl
@@ -22,8 +22,4 @@
parcelable AudioPortDeviceExtSys {
/** Module the device is attached to. Interpreted as audio_module_handle_t. */
int hwModule;
- /** Bitmask, indexed by AudioEncapsulationMode. */
- int encapsulationModes;
- /** Bitmask, indexed by AudioEncapsulationMetadataType. */
- int encapsulationMetadataTypes;
}
diff --git a/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl b/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl
index 51bf05a..7c44c74 100644
--- a/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl
+++ b/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl
@@ -35,7 +35,7 @@
import android.media.IAudioFlingerClient;
import android.media.IAudioRecord;
import android.media.IAudioTrack;
-import android.media.MicrophoneInfoData;
+import android.media.MicrophoneInfoFw;
import android.media.RenderPosition;
import android.media.TrackSecondaryOutputInfo;
import android.media.audio.common.AudioChannelLayout;
@@ -208,7 +208,7 @@
long frameCountHAL(int /* audio_io_handle_t */ ioHandle);
/* List available microphones and their characteristics */
- MicrophoneInfoData[] getMicrophones();
+ MicrophoneInfoFw[] getMicrophones();
void setAudioHalPids(in int[] /* pid_t[] */ pids);
diff --git a/media/libaudioclient/aidl/android/media/IAudioRecord.aidl b/media/libaudioclient/aidl/android/media/IAudioRecord.aidl
index 44ef80b..1ea4156 100644
--- a/media/libaudioclient/aidl/android/media/IAudioRecord.aidl
+++ b/media/libaudioclient/aidl/android/media/IAudioRecord.aidl
@@ -16,7 +16,7 @@
package android.media;
-import android.media.MicrophoneInfoData;
+import android.media.MicrophoneInfoFw;
/**
* Native code must specify namespace media (media::IAudioRecord) when referring to this class.
@@ -39,7 +39,7 @@
/* Get a list of current active microphones.
*/
- void getActiveMicrophones(out MicrophoneInfoData[] activeMicrophones);
+ void getActiveMicrophones(out MicrophoneInfoFw[] activeMicrophones);
/* Set the microphone direction (for processing).
*/
diff --git a/media/libaudioclient/fuzzer/audioflinger_fuzzer.cpp b/media/libaudioclient/fuzzer/audioflinger_fuzzer.cpp
index 036e72e..d881447 100644
--- a/media/libaudioclient/fuzzer/audioflinger_fuzzer.cpp
+++ b/media/libaudioclient/fuzzer/audioflinger_fuzzer.cpp
@@ -359,7 +359,7 @@
record->getInputFramesLost();
record->getFlags();
- std::vector<media::MicrophoneInfo> activeMicrophones;
+ std::vector<media::MicrophoneInfoFw> activeMicrophones;
record->getActiveMicrophones(&activeMicrophones);
record->releaseBuffer(&audioBuffer);
@@ -541,7 +541,7 @@
AudioSystem::getPrimaryOutputFrameCount();
AudioSystem::setLowRamDevice(mFdp.ConsumeBool(), mFdp.ConsumeIntegral<int64_t>());
- std::vector<media::MicrophoneInfo> microphones;
+ std::vector<media::MicrophoneInfoFw> microphones;
AudioSystem::getMicrophones(µphones);
std::vector<pid_t> pids;
diff --git a/media/libaudioclient/include/media/AidlConversion.h b/media/libaudioclient/include/media/AidlConversion.h
index f0e58ae..5bd0114 100644
--- a/media/libaudioclient/include/media/AidlConversion.h
+++ b/media/libaudioclient/include/media/AidlConversion.h
@@ -33,6 +33,7 @@
#include <android/media/AudioTimestampInternal.h>
#include <android/media/AudioUniqueIdUse.h>
#include <android/media/EffectDescriptor.h>
+#include <android/media/MicrophoneInfoFw.h>
#include <android/media/TrackSecondaryOutputInfo.h>
#include <android/media/SharedFileRegion.h>
@@ -198,4 +199,11 @@
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_microphone_characteristic_t>
+aidl2legacy_MicrophoneInfoFw_audio_microphone_characteristic_t(
+ const media::MicrophoneInfoFw& aidl);
+ConversionResult<media::MicrophoneInfoFw>
+legacy2aidl_audio_microphone_characteristic_t_MicrophoneInfoFw(
+ const audio_microphone_characteristic_t& legacy);
+
} // namespace android
diff --git a/media/libaudioclient/include/media/AudioRecord.h b/media/libaudioclient/include/media/AudioRecord.h
index 5a1ff65..ae70a7f 100644
--- a/media/libaudioclient/include/media/AudioRecord.h
+++ b/media/libaudioclient/include/media/AudioRecord.h
@@ -26,7 +26,6 @@
#include <media/AudioTimestamp.h>
#include <media/MediaMetricsItem.h>
#include <media/Modulo.h>
-#include <media/MicrophoneInfo.h>
#include <media/RecordingActivityTracker.h>
#include <utils/RefBase.h>
#include <utils/threads.h>
@@ -575,10 +574,11 @@
/* Get the flags */
audio_input_flags_t getFlags() const { AutoMutex _l(mLock); return mFlags; }
- /* Get active microphones. A empty vector of MicrophoneInfo will be passed as a parameter,
+ /* Get active microphones. A empty vector of MicrophoneInfoFw will be passed as a parameter,
* the data will be filled when querying the hal.
*/
- status_t getActiveMicrophones(std::vector<media::MicrophoneInfo>* activeMicrophones);
+ status_t getActiveMicrophones(
+ std::vector<media::MicrophoneInfoFw>* activeMicrophones);
/* Set the Microphone direction (for processing purposes).
*/
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index 3b7cc39..543ce00 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -28,6 +28,7 @@
#include <android/media/BnAudioPolicyServiceClient.h>
#include <android/media/INativeSpatializerCallback.h>
#include <android/media/ISpatializer.h>
+#include <android/media/MicrophoneInfoFw.h>
#include <android/media/audio/common/AudioMMapPolicyInfo.h>
#include <android/media/audio/common/AudioMMapPolicyType.h>
#include <android/media/audio/common/AudioPort.h>
@@ -38,7 +39,6 @@
#include <media/AudioProductStrategy.h>
#include <media/AudioVolumeGroup.h>
#include <media/AudioIoDescriptor.h>
-#include <media/MicrophoneInfo.h>
#include <system/audio.h>
#include <system/audio_effect.h>
#include <system/audio_policy.h>
@@ -428,7 +428,7 @@
static float getStreamVolumeDB(
audio_stream_type_t stream, int index, audio_devices_t device);
- static status_t getMicrophones(std::vector<media::MicrophoneInfo> *microphones);
+ static status_t getMicrophones(std::vector<media::MicrophoneInfoFw> *microphones);
static status_t getHwOffloadFormatsSupportedForBluetoothMedia(
audio_devices_t device, std::vector<audio_format_t> *formats);
diff --git a/media/libaudioclient/include/media/IAudioFlinger.h b/media/libaudioclient/include/media/IAudioFlinger.h
index 1177e5a..25b5414 100644
--- a/media/libaudioclient/include/media/IAudioFlinger.h
+++ b/media/libaudioclient/include/media/IAudioFlinger.h
@@ -32,7 +32,6 @@
#include <system/audio_effect.h>
#include <system/audio_policy.h>
#include <utils/String8.h>
-#include <media/MicrophoneInfo.h>
#include <map>
#include <string>
#include <vector>
@@ -339,7 +338,7 @@
virtual size_t frameCountHAL(audio_io_handle_t ioHandle) const = 0;
/* List available microphones and their characteristics */
- virtual status_t getMicrophones(std::vector<media::MicrophoneInfo> *microphones) = 0;
+ virtual status_t getMicrophones(std::vector<media::MicrophoneInfoFw> *microphones) = 0;
virtual status_t setAudioHalPids(const std::vector<pid_t>& pids) = 0;
@@ -463,7 +462,7 @@
status_t audioPolicyReady() override;
size_t frameCountHAL(audio_io_handle_t ioHandle) const override;
- status_t getMicrophones(std::vector<media::MicrophoneInfo>* microphones) override;
+ status_t getMicrophones(std::vector<media::MicrophoneInfoFw>* microphones) override;
status_t setAudioHalPids(const std::vector<pid_t>& pids) override;
status_t setVibratorInfos(const std::vector<media::AudioVibratorInfo>& vibratorInfos) override;
status_t updateSecondaryOutputs(
@@ -688,7 +687,7 @@
Status systemReady() override;
Status audioPolicyReady() override;
Status frameCountHAL(int32_t ioHandle, int64_t* _aidl_return) override;
- Status getMicrophones(std::vector<media::MicrophoneInfoData>* _aidl_return) override;
+ Status getMicrophones(std::vector<media::MicrophoneInfoFw>* _aidl_return) override;
Status setAudioHalPids(const std::vector<int32_t>& pids) override;
Status setVibratorInfos(const std::vector<media::AudioVibratorInfo>& vibratorInfos) override;
Status updateSecondaryOutputs(
diff --git a/media/libaudioclient/tests/Android.bp b/media/libaudioclient/tests/Android.bp
index dcb6c25..2189521 100644
--- a/media/libaudioclient/tests/Android.bp
+++ b/media/libaudioclient/tests/Android.bp
@@ -39,6 +39,7 @@
"libaudioclient_aidl_conversion",
"libaudio_aidl_conversion_common_cpp",
"audioclient-types-aidl-cpp",
+ "av-types-aidl-cpp",
"libstagefright_foundation",
],
}
diff --git a/media/libaudioclient/tests/audio_aidl_legacy_conversion_tests.cpp b/media/libaudioclient/tests/audio_aidl_legacy_conversion_tests.cpp
index 5fbd090..e2216a0 100644
--- a/media/libaudioclient/tests/audio_aidl_legacy_conversion_tests.cpp
+++ b/media/libaudioclient/tests/audio_aidl_legacy_conversion_tests.cpp
@@ -47,6 +47,8 @@
using media::audio::common::AudioStandard;
using media::audio::common::ExtraAudioDescriptor;
using media::audio::common::Int;
+using media::audio::common::MicrophoneDynamicInfo;
+using media::audio::common::MicrophoneInfo;
using media::audio::common::PcmType;
// Provide value printers for types generated from AIDL
@@ -663,3 +665,73 @@
}
}
INSTANTIATE_TEST_SUITE_P(AudioGain, AudioGainTest, testing::Values(true, false));
+
+TEST(AudioMicrophoneInfoFw, Aidl2Legacy2Aidl) {
+ media::MicrophoneInfoFw initial{};
+ // HALs must return at least 1 element in channelMapping. The zero value is 'UNUSED'.
+ initial.dynamic.channelMapping.resize(1);
+ auto conv = aidl2legacy_MicrophoneInfoFw_audio_microphone_characteristic_t(initial);
+ ASSERT_TRUE(conv.ok());
+ auto convBack = legacy2aidl_audio_microphone_characteristic_t_MicrophoneInfoFw(conv.value());
+ ASSERT_TRUE(convBack.ok());
+ EXPECT_EQ(initial, convBack.value());
+}
+
+TEST(AudioMicrophoneInfoFw, UnknownValues) {
+ {
+ media::MicrophoneInfoFw initial;
+ initial.dynamic.channelMapping.resize(1);
+ initial.info.indexInTheGroup = MicrophoneInfo::INDEX_IN_THE_GROUP_UNKNOWN;
+ auto conv = aidl2legacy_MicrophoneInfoFw_audio_microphone_characteristic_t(initial);
+ ASSERT_TRUE(conv.ok());
+ auto convBack =
+ legacy2aidl_audio_microphone_characteristic_t_MicrophoneInfoFw(conv.value());
+ ASSERT_TRUE(convBack.ok());
+ EXPECT_EQ(initial, convBack.value());
+ }
+ for (const auto f : {&audio_microphone_characteristic_t::sensitivity,
+ &audio_microphone_characteristic_t::max_spl,
+ &audio_microphone_characteristic_t::min_spl}) {
+ audio_microphone_characteristic_t mic{};
+ if (f == &audio_microphone_characteristic_t::sensitivity) {
+ mic.*f = AUDIO_MICROPHONE_SENSITIVITY_UNKNOWN;
+ } else {
+ mic.*f = AUDIO_MICROPHONE_SPL_UNKNOWN;
+ }
+ auto aidl = legacy2aidl_audio_microphone_characteristic_t_MicrophoneInfoFw(mic);
+ ASSERT_TRUE(aidl.ok());
+ EXPECT_FALSE(aidl.value().info.sensitivity.has_value());
+ }
+ for (const auto f : {&audio_microphone_characteristic_t::geometric_location,
+ &audio_microphone_characteristic_t::orientation}) {
+ for (const auto c : {&audio_microphone_coordinate::x, &audio_microphone_coordinate::y,
+ &audio_microphone_coordinate::z}) {
+ audio_microphone_characteristic_t mic{};
+ mic.*f.*c = AUDIO_MICROPHONE_COORDINATE_UNKNOWN;
+ auto conv = legacy2aidl_audio_microphone_characteristic_t_MicrophoneInfoFw(mic);
+ ASSERT_TRUE(conv.ok());
+ const auto& aidl = conv.value();
+ if (f == &audio_microphone_characteristic_t::geometric_location) {
+ EXPECT_FALSE(aidl.info.position.has_value());
+ EXPECT_TRUE(aidl.info.orientation.has_value());
+ } else {
+ EXPECT_TRUE(aidl.info.position.has_value());
+ EXPECT_FALSE(aidl.info.orientation.has_value());
+ }
+ }
+ }
+}
+
+TEST(AudioMicrophoneInfoFw, ChannelMapping) {
+ audio_microphone_characteristic_t mic{};
+ mic.channel_mapping[1] = AUDIO_MICROPHONE_CHANNEL_MAPPING_DIRECT;
+ mic.channel_mapping[3] = AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED;
+ auto conv = legacy2aidl_audio_microphone_characteristic_t_MicrophoneInfoFw(mic);
+ ASSERT_TRUE(conv.ok());
+ const auto& aidl = conv.value();
+ EXPECT_EQ(4, aidl.dynamic.channelMapping.size());
+ EXPECT_EQ(MicrophoneDynamicInfo::ChannelMapping::UNUSED, aidl.dynamic.channelMapping[0]);
+ EXPECT_EQ(MicrophoneDynamicInfo::ChannelMapping::DIRECT, aidl.dynamic.channelMapping[1]);
+ EXPECT_EQ(MicrophoneDynamicInfo::ChannelMapping::UNUSED, aidl.dynamic.channelMapping[2]);
+ EXPECT_EQ(MicrophoneDynamicInfo::ChannelMapping::PROCESSED, aidl.dynamic.channelMapping[3]);
+}
diff --git a/media/libaudiofoundation/AudioContainers.cpp b/media/libaudiofoundation/AudioContainers.cpp
index 0a8188f..202a400 100644
--- a/media/libaudiofoundation/AudioContainers.cpp
+++ b/media/libaudiofoundation/AudioContainers.cpp
@@ -77,6 +77,13 @@
return audioDeviceOutLeAudioUnicastSet;
}
+const DeviceTypeSet& getAudioDeviceOutLeAudioBroadcastSet() {
+ static const DeviceTypeSet audioDeviceOutLeAudioUnicastSet = DeviceTypeSet(
+ std::begin(AUDIO_DEVICE_OUT_BLE_BROADCAST_ARRAY),
+ std::end(AUDIO_DEVICE_OUT_BLE_BROADCAST_ARRAY));
+ return audioDeviceOutLeAudioUnicastSet;
+}
+
std::string deviceTypesToString(const DeviceTypeSet &deviceTypes) {
if (deviceTypes.empty()) {
return "Empty device types";
diff --git a/media/libaudiofoundation/DeviceDescriptorBase.cpp b/media/libaudiofoundation/DeviceDescriptorBase.cpp
index 4185b5f..9ffc75b 100644
--- a/media/libaudiofoundation/DeviceDescriptorBase.cpp
+++ b/media/libaudiofoundation/DeviceDescriptorBase.cpp
@@ -186,12 +186,12 @@
deviceExt.encodedFormats = VALUE_OR_RETURN_STATUS(
convertContainer<std::vector<media::audio::common::AudioFormatDescription>>(
mEncodedFormats, legacy2aidl_audio_format_t_AudioFormatDescription));
+ deviceExt.encapsulationModes = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_AudioEncapsulationMode_mask(mEncapsulationModes));
+ deviceExt.encapsulationMetadataTypes = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_AudioEncapsulationMetadataType_mask(mEncapsulationMetadataTypes));
UNION_SET(parcelable->hal.ext, device, deviceExt);
media::AudioPortDeviceExtSys deviceSys;
- deviceSys.encapsulationModes = VALUE_OR_RETURN_STATUS(
- legacy2aidl_AudioEncapsulationMode_mask(mEncapsulationModes));
- deviceSys.encapsulationMetadataTypes = VALUE_OR_RETURN_STATUS(
- legacy2aidl_AudioEncapsulationMetadataType_mask(mEncapsulationMetadataTypes));
UNION_SET(parcelable->sys.ext, device, deviceSys);
return OK;
}
@@ -214,12 +214,12 @@
mEncodedFormats = VALUE_OR_RETURN_STATUS(
convertContainer<FormatVector>(deviceExt.encodedFormats,
aidl2legacy_AudioFormatDescription_audio_format_t));
+ mEncapsulationModes = VALUE_OR_RETURN_STATUS(
+ aidl2legacy_AudioEncapsulationMode_mask(deviceExt.encapsulationModes));
+ mEncapsulationMetadataTypes = VALUE_OR_RETURN_STATUS(
+ aidl2legacy_AudioEncapsulationMetadataType_mask(deviceExt.encapsulationMetadataTypes));
media::AudioPortDeviceExtSys deviceSys = VALUE_OR_RETURN_STATUS(
UNION_GET(parcelable.sys.ext, device));
- mEncapsulationModes = VALUE_OR_RETURN_STATUS(
- aidl2legacy_AudioEncapsulationMode_mask(deviceSys.encapsulationModes));
- mEncapsulationMetadataTypes = VALUE_OR_RETURN_STATUS(
- aidl2legacy_AudioEncapsulationMetadataType_mask(deviceSys.encapsulationMetadataTypes));
return OK;
}
diff --git a/media/libaudiofoundation/include/media/AudioContainers.h b/media/libaudiofoundation/include/media/AudioContainers.h
index 6c01e29..3f79ea2 100644
--- a/media/libaudiofoundation/include/media/AudioContainers.h
+++ b/media/libaudiofoundation/include/media/AudioContainers.h
@@ -42,6 +42,7 @@
const DeviceTypeSet& getAudioDeviceInAllUsbSet();
const DeviceTypeSet& getAudioDeviceOutAllBleSet();
const DeviceTypeSet& getAudioDeviceOutLeAudioUnicastSet();
+const DeviceTypeSet& getAudioDeviceOutLeAudioBroadcastSet();
template<typename T>
static std::vector<T> Intersection(const std::set<T>& a, const std::set<T>& b) {
diff --git a/media/libaudiohal/impl/Android.bp b/media/libaudiohal/impl/Android.bp
index aae8dbd..aea31a0 100644
--- a/media/libaudiohal/impl/Android.bp
+++ b/media/libaudiohal/impl/Android.bp
@@ -55,6 +55,7 @@
shared_libs: [
"audioclient-types-aidl-cpp",
"av-types-aidl-cpp",
+ "libaudioclient_aidl_conversion",
"libaudiofoundation",
"libaudioutils",
"libbase",
@@ -71,6 +72,9 @@
"libaudioclient_headers",
"libaudiohal_headers"
],
+ defaults: [
+ "latest_android_media_audio_common_types_cpp_export_shared",
+ ],
export_shared_lib_headers: [
"libfmq",
@@ -241,7 +245,7 @@
"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_hardware_audio_effect_ndk_shared",
"latest_android_media_audio_common_types_ndk_shared",
],
srcs: [
@@ -252,6 +256,7 @@
"EffectBufferHalAidl.cpp",
"EffectHalAidl.cpp",
"effectsAidlConversion/AidlConversionAec.cpp",
+ "effectsAidlConversion/AidlConversionAgc1.cpp",
"effectsAidlConversion/AidlConversionAgc2.cpp",
"effectsAidlConversion/AidlConversionBassBoost.cpp",
"effectsAidlConversion/AidlConversionDownmix.cpp",
@@ -281,7 +286,6 @@
"libaudioaidlcommon",
],
header_libs: [
- "libaudio_aidl_conversion_common_util_ndk",
"libaudio_system_headers",
],
cflags: [
diff --git a/media/libaudiohal/impl/DeviceHalAidl.cpp b/media/libaudiohal/impl/DeviceHalAidl.cpp
index 32ebe36..67f9493 100644
--- a/media/libaudiohal/impl/DeviceHalAidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalAidl.cpp
@@ -45,6 +45,7 @@
using aidl::android::media::audio::common::AudioPort;
using aidl::android::media::audio::common::AudioPortConfig;
using aidl::android::media::audio::common::AudioPortDeviceExt;
+using aidl::android::media::audio::common::AudioPortMixExt;
using aidl::android::media::audio::common::AudioPortExt;
using aidl::android::media::audio::common::AudioSource;
using aidl::android::media::audio::common::Int;
@@ -460,7 +461,7 @@
args.eventCallback = eventCb;
::aidl::android::hardware::audio::core::IModule::OpenOutputStreamReturn ret;
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->openOutputStream(args, &ret)));
- StreamContextAidl context(ret.desc);
+ StreamContextAidl context(ret.desc, isOffload);
if (!context.isValid()) {
ALOGE("%s: Failed to created a valid stream context from the descriptor: %s",
__func__, ret.desc.toString().c_str());
@@ -520,7 +521,7 @@
args.bufferSizeFrames = aidlConfig.frameCount;
::aidl::android::hardware::audio::core::IModule::OpenInputStreamReturn ret;
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->openInputStream(args, &ret)));
- StreamContextAidl context(ret.desc);
+ StreamContextAidl context(ret.desc, false /*isAsynchronous*/);
if (!context.isValid()) {
ALOGE("%s: Failed to created a valid stream context from the descriptor: %s",
__func__, ret.desc.toString().c_str());
@@ -549,8 +550,19 @@
sources == nullptr || sinks == nullptr || patch == nullptr) {
return BAD_VALUE;
}
- // Note that the patch handle (*patch) is provided by the framework.
- // In tests it's possible that its value is AUDIO_PATCH_HANDLE_NONE.
+ // When the patch handle (*patch) is AUDIO_PATCH_HANDLE_NONE, it means
+ // the framework wants to create a new patch. The handle has to be generated
+ // by the HAL. Since handles generated this way can only be unique within
+ // a HAL module, the framework generates a globally unique handle, and maps
+ // it on the <HAL module, patch handle> pair.
+ // When the patch handle is set, it meant the framework intends to update
+ // an existing patch.
+ //
+ // This behavior corresponds to HAL module behavior, with the only difference
+ // that the HAL module uses `int32_t` for patch IDs. The following assert ensures
+ // that both the framework and the HAL use the same value for "no ID":
+ static_assert(AUDIO_PATCH_HANDLE_NONE == 0);
+ int32_t halPatchId = static_cast<int32_t>(*patch);
// Upon conversion, mix port configs contain audio configuration, while
// device port configs contain device address. This data is used to find
@@ -573,17 +585,12 @@
sinks[i], isInput, 0)));
}
Cleanups cleanups;
- auto existingPatchIt = mPatches.end();
- auto fwkHandlesIt = *patch != AUDIO_PATCH_HANDLE_NONE ?
- mFwkHandles.find(*patch) : mFwkHandles.end();
+ auto existingPatchIt = halPatchId != 0 ? mPatches.find(halPatchId): mPatches.end();
AudioPatch aidlPatch;
- if (fwkHandlesIt != mFwkHandles.end()) {
- existingPatchIt = mPatches.find(fwkHandlesIt->second);
- if (existingPatchIt != mPatches.end()) {
- aidlPatch = existingPatchIt->second;
- aidlPatch.sourcePortConfigIds.clear();
- aidlPatch.sinkPortConfigIds.clear();
- }
+ if (existingPatchIt != mPatches.end()) {
+ aidlPatch = existingPatchIt->second;
+ aidlPatch.sourcePortConfigIds.clear();
+ aidlPatch.sinkPortConfigIds.clear();
}
ALOGD("%s: sources: %s, sinks: %s",
__func__, ::android::internal::ToString(aidlSources).c_str(),
@@ -611,20 +618,8 @@
bool created = false;
RETURN_STATUS_IF_ERROR(findOrCreatePatch(aidlPatch, &aidlPatch, &created));
// Since no cleanup of the patch is needed, 'created' is ignored.
- if (fwkHandlesIt != mFwkHandles.end()) {
- fwkHandlesIt->second = aidlPatch.id;
- // Patch handle (*patch) stays the same.
- } else {
- if (*patch == AUDIO_PATCH_HANDLE_NONE) {
- // This isn't good as the module can't provide a handle which is really unique.
- // However, this situation should only happen in tests.
- *patch = aidlPatch.id;
- LOG_ALWAYS_FATAL_IF(mFwkHandles.count(*patch) > 0,
- "%s: patch id %d clashes with another framework patch handle",
- __func__, *patch);
- }
- mFwkHandles.emplace(*patch, aidlPatch.id);
- }
+ halPatchId = aidlPatch.id;
+ *patch = static_cast<audio_patch_handle_t>(halPatchId);
}
cleanups.disarmAll();
return OK;
@@ -634,12 +629,18 @@
ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
TIME_CHECK();
if (!mModule) return NO_INIT;
- auto idMapIt = mFwkHandles.find(patch);
- if (idMapIt == mFwkHandles.end()) {
+ static_assert(AUDIO_PATCH_HANDLE_NONE == 0);
+ if (patch == AUDIO_PATCH_HANDLE_NONE) {
return BAD_VALUE;
}
- RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->resetAudioPatch(idMapIt->second)));
- mFwkHandles.erase(idMapIt);
+ int32_t halPatchId = static_cast<int32_t>(patch);
+ auto patchIt = mPatches.find(halPatchId);
+ if (patchIt == mPatches.end()) {
+ ALOGE("%s: patch with id %d not found", __func__, halPatchId);
+ return BAD_VALUE;
+ }
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->resetAudioPatch(halPatchId)));
+ mPatches.erase(patchIt);
return OK;
}
@@ -744,22 +745,27 @@
return p.ext.get<AudioPortExt::Tag::device>().device == device;
}
-status_t DeviceHalAidl::createPortConfig(const AudioPortConfig& requestedPortConfig,
- AudioPortConfig* appliedPortConfig) {
+status_t DeviceHalAidl::createPortConfig(
+ const AudioPortConfig& requestedPortConfig, PortConfigs::iterator* result) {
TIME_CHECK();
+ AudioPortConfig appliedPortConfig;
bool applied = false;
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->setAudioPortConfig(
- requestedPortConfig, appliedPortConfig, &applied)));
+ requestedPortConfig, &appliedPortConfig, &applied)));
if (!applied) {
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->setAudioPortConfig(
- *appliedPortConfig, appliedPortConfig, &applied)));
+ appliedPortConfig, &appliedPortConfig, &applied)));
if (!applied) {
ALOGE("%s: module %s did not apply suggested config %s",
- __func__, mInstance.c_str(), appliedPortConfig->toString().c_str());
+ __func__, mInstance.c_str(), appliedPortConfig.toString().c_str());
return NO_INIT;
}
}
- mPortConfigs.emplace(appliedPortConfig->id, *appliedPortConfig);
+ auto id = appliedPortConfig.id;
+ auto [it, inserted] = mPortConfigs.emplace(std::move(id), std::move(appliedPortConfig));
+ LOG_ALWAYS_FATAL_IF(!inserted, "%s: port config with id %d already exists",
+ __func__, it->first);
+ *result = it;
return OK;
}
@@ -806,10 +812,7 @@
}
AudioPortConfig requestedPortConfig;
requestedPortConfig.portId = portsIt->first;
- AudioPortConfig appliedPortConfig;
- RETURN_STATUS_IF_ERROR(createPortConfig(requestedPortConfig, &appliedPortConfig));
- portConfigIt = mPortConfigs.insert(
- mPortConfigs.end(), std::make_pair(appliedPortConfig.id, appliedPortConfig));
+ RETURN_STATUS_IF_ERROR(createPortConfig(requestedPortConfig, &portConfigIt));
*created = true;
} else {
*created = false;
@@ -821,23 +824,40 @@
status_t DeviceHalAidl::findOrCreatePortConfig(
const AudioConfig& config, const std::optional<AudioIoFlags>& flags, int32_t ioHandle,
AudioPortConfig* portConfig, bool* created) {
+ // These flags get removed one by one in this order when retrying port finding.
+ static const std::vector<AudioInputFlags> kOptionalInputFlags{
+ AudioInputFlags::FAST, AudioInputFlags::RAW };
auto portConfigIt = findPortConfig(config, flags, ioHandle);
if (portConfigIt == mPortConfigs.end() && flags.has_value()) {
- auto portsIt = findPort(config, flags.value());
+ auto optionalInputFlagsIt = kOptionalInputFlags.begin();
+ AudioIoFlags matchFlags = flags.value();
+ auto portsIt = findPort(config, matchFlags);
+ while (portsIt == mPorts.end() && matchFlags.getTag() == AudioIoFlags::Tag::input
+ && optionalInputFlagsIt != kOptionalInputFlags.end()) {
+ if (!isBitPositionFlagSet(
+ matchFlags.get<AudioIoFlags::Tag::input>(), *optionalInputFlagsIt)) {
+ ++optionalInputFlagsIt;
+ continue;
+ }
+ matchFlags.set<AudioIoFlags::Tag::input>(matchFlags.get<AudioIoFlags::Tag::input>() &
+ ~makeBitPositionFlagMask(*optionalInputFlagsIt++));
+ portsIt = findPort(config, matchFlags);
+ ALOGI("%s: mix port for config %s, flags %s was not found in the module %s, "
+ "retried with flags %s", __func__, config.toString().c_str(),
+ flags.value().toString().c_str(), mInstance.c_str(),
+ matchFlags.toString().c_str());
+ }
if (portsIt == mPorts.end()) {
ALOGE("%s: mix port for config %s, flags %s is not found in the module %s",
- __func__, config.toString().c_str(), flags.value().toString().c_str(),
+ __func__, config.toString().c_str(), matchFlags.toString().c_str(),
mInstance.c_str());
return BAD_VALUE;
}
AudioPortConfig requestedPortConfig;
requestedPortConfig.portId = portsIt->first;
setPortConfigFromConfig(&requestedPortConfig, config);
- AudioPortConfig appliedPortConfig;
- RETURN_STATUS_IF_ERROR(createPortConfig(requestedPortConfig, &appliedPortConfig));
- appliedPortConfig.ext.get<AudioPortExt::Tag::mix>().handle = ioHandle;
- portConfigIt = mPortConfigs.insert(
- mPortConfigs.end(), std::make_pair(appliedPortConfig.id, appliedPortConfig));
+ requestedPortConfig.ext = AudioPortMixExt{ .handle = ioHandle };
+ RETURN_STATUS_IF_ERROR(createPortConfig(requestedPortConfig, &portConfigIt));
*created = true;
} else if (!flags.has_value()) {
ALOGW("%s: mix port config for %s, handle %d not found in the module %s, "
@@ -899,12 +919,10 @@
DeviceHalAidl::Ports::iterator DeviceHalAidl::findPort(
const AudioConfig& config, const AudioIoFlags& flags) {
- using Tag = AudioPortExt::Tag;
- AudioIoFlags matchFlags = flags;
auto matcher = [&](const auto& pair) {
const auto& p = pair.second;
- return p.ext.getTag() == Tag::mix &&
- p.flags == matchFlags &&
+ return p.ext.getTag() == AudioPortExt::Tag::mix &&
+ p.flags == flags &&
std::find_if(p.profiles.begin(), p.profiles.end(),
[&](const auto& prof) {
return prof.format == config.base.format &&
@@ -913,15 +931,7 @@
std::find(prof.sampleRates.begin(), prof.sampleRates.end(),
config.base.sampleRate) != prof.sampleRates.end();
}) != p.profiles.end(); };
- auto it = std::find_if(mPorts.begin(), mPorts.end(), matcher);
- if (it == mPorts.end() && flags.getTag() == AudioIoFlags::Tag::input &&
- isBitPositionFlagSet(flags.get<AudioIoFlags::Tag::input>(), AudioInputFlags::FAST)) {
- // "Fast" input is not a mandatory flag, try without it.
- matchFlags.set<AudioIoFlags::Tag::input>(flags.get<AudioIoFlags::Tag::input>() &
- ~makeBitPositionFlagMask(AudioInputFlags::FAST));
- it = std::find_if(mPorts.begin(), mPorts.end(), matcher);
- }
- return it;
+ return std::find_if(mPorts.begin(), mPorts.end(), matcher);
}
DeviceHalAidl::PortConfigs::iterator DeviceHalAidl::findPortConfig(const AudioDevice& device) {
diff --git a/media/libaudiohal/impl/DeviceHalAidl.h b/media/libaudiohal/impl/DeviceHalAidl.h
index 6f16daf..4077f7e 100644
--- a/media/libaudiohal/impl/DeviceHalAidl.h
+++ b/media/libaudiohal/impl/DeviceHalAidl.h
@@ -179,7 +179,7 @@
const ::aidl::android::media::audio::common::AudioPortConfig& p);
status_t createPortConfig(
const ::aidl::android::media::audio::common::AudioPortConfig& requestedPortConfig,
- ::aidl::android::media::audio::common::AudioPortConfig* appliedPortConfig);
+ PortConfigs::iterator* result);
status_t findOrCreatePatch(
const std::set<int32_t>& sourcePortConfigIds,
const std::set<int32_t>& sinkPortConfigIds,
@@ -248,7 +248,6 @@
int32_t mDefaultOutputPortId = -1;
PortConfigs mPortConfigs;
Patches mPatches;
- std::map<audio_patch_handle_t, int32_t /*patch ID*/> mFwkHandles;
std::mutex mLock;
std::map<void*, Callbacks> mCallbacks GUARDED_BY(mLock);
};
diff --git a/media/libaudiohal/impl/EffectBufferHalAidl.cpp b/media/libaudiohal/impl/EffectBufferHalAidl.cpp
index 5af8e24..a701852 100644
--- a/media/libaudiohal/impl/EffectBufferHalAidl.cpp
+++ b/media/libaudiohal/impl/EffectBufferHalAidl.cpp
@@ -14,26 +14,39 @@
* limitations under the License.
*/
+#include <algorithm>
+#include <cstdint>
+#include <cstring>
+#include <sys/mman.h>
#define LOG_TAG "EffectBufferHalAidl"
//#define LOG_NDEBUG 0
+#include <cutils/ashmem.h>
#include <utils/Log.h>
#include "EffectBufferHalAidl.h"
+using ndk::ScopedFileDescriptor;
+
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);
+ sp<EffectBufferHalAidl> tempBuffer = new EffectBufferHalAidl(size);
+ status_t status = tempBuffer.get()->init();
+ if (status != OK) {
+ ALOGE("%s init failed %d", __func__, status);
+ return status;
+ }
+
+ tempBuffer->setExternalData(external);
+ *buffer = tempBuffer;
return OK;
}
@@ -48,7 +61,22 @@
}
status_t EffectBufferHalAidl::init() {
- ALOGW("%s not implemented yet", __func__);
+ int fd = ashmem_create_region("audioEffectAidl", mBufferSize);
+ if (fd < 0) {
+ ALOGE("%s create ashmem failed %d", __func__, fd);
+ return fd;
+ }
+
+ ScopedFileDescriptor tempFd(fd);
+ mAudioBuffer.raw = mmap(nullptr /* address */, mBufferSize /* length */, PROT_READ | PROT_WRITE,
+ MAP_SHARED, fd, 0 /* offset */);
+ if (mAudioBuffer.raw == MAP_FAILED) {
+ ALOGE("mmap failed for fd %d", fd);
+ mAudioBuffer.raw = nullptr;
+ return INVALID_OPERATION;
+ }
+
+ mMemory = {std::move(tempFd), static_cast<int64_t>(mBufferSize)};
return OK;
}
@@ -76,11 +104,26 @@
}
void EffectBufferHalAidl::update() {
- ALOGW("%s not implemented yet", __func__);
+ update(mBufferSize);
}
void EffectBufferHalAidl::commit() {
- ALOGW("%s not implemented yet", __func__);
+ commit(mBufferSize);
+}
+
+void EffectBufferHalAidl::copy(void* dst, const void* src, size_t n) const {
+ if (!dst || !src) {
+ return;
+ }
+ std::memcpy(dst, src, std::min(n, mBufferSize));
+}
+
+void EffectBufferHalAidl::update(size_t n) {
+ copy(mAudioBuffer.raw, mExternalData, n);
+}
+
+void EffectBufferHalAidl::commit(size_t n) {
+ copy(mExternalData, mAudioBuffer.raw, n);
}
} // namespace effect
diff --git a/media/libaudiohal/impl/EffectBufferHalAidl.h b/media/libaudiohal/impl/EffectBufferHalAidl.h
index f488708..035314b 100644
--- a/media/libaudiohal/impl/EffectBufferHalAidl.h
+++ b/media/libaudiohal/impl/EffectBufferHalAidl.h
@@ -16,6 +16,8 @@
#pragma once
+#include <aidl/android/hardware/common/Ashmem.h>
+
#include <media/audiohal/EffectBufferHalInterface.h>
#include <system/audio_effect.h>
@@ -44,16 +46,18 @@
private:
friend class EffectBufferHalInterface;
+ // buffer size in bytes
const size_t mBufferSize;
bool mFrameCountChanged;
void* mExternalData;
+ aidl::android::hardware::common::Ashmem mMemory;
audio_buffer_t mAudioBuffer;
// Can not be constructed directly by clients.
explicit EffectBufferHalAidl(size_t size);
~EffectBufferHalAidl();
-
+ void copy(void* dst, const void* src, size_t n) const;
status_t init();
};
diff --git a/media/libaudiohal/impl/EffectConversionHelperAidl.cpp b/media/libaudiohal/impl/EffectConversionHelperAidl.cpp
index 7e25b04..519b871 100644
--- a/media/libaudiohal/impl/EffectConversionHelperAidl.cpp
+++ b/media/libaudiohal/impl/EffectConversionHelperAidl.cpp
@@ -24,6 +24,7 @@
#include <media/AidlConversionCppNdk.h>
#include <media/AidlConversionNdk.h>
#include <media/AidlConversionEffect.h>
+#include <system/audio_effects/effect_visualizer.h>
#include <utils/Log.h>
@@ -35,6 +36,7 @@
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::Flags;
using ::aidl::android::hardware::audio::effect::Parameter;
using ::aidl::android::media::audio::common::AudioDeviceDescription;
using ::aidl::android::media::audio::common::AudioMode;
@@ -59,12 +61,18 @@
{EFFECT_CMD_SET_INPUT_DEVICE, &EffectConversionHelperAidl::handleSetDevice},
{EFFECT_CMD_SET_VOLUME, &EffectConversionHelperAidl::handleSetVolume},
{EFFECT_CMD_OFFLOAD, &EffectConversionHelperAidl::handleSetOffload},
- {EFFECT_CMD_FIRST_PROPRIETARY, &EffectConversionHelperAidl::handleFirstPriority}};
+ // Only visualizer support these commands, reuse of EFFECT_CMD_FIRST_PROPRIETARY
+ {VISUALIZER_CMD_CAPTURE, &EffectConversionHelperAidl::handleVisualizerCapture},
+ {VISUALIZER_CMD_MEASURE, &EffectConversionHelperAidl::handleVisualizerMeasure}};
EffectConversionHelperAidl::EffectConversionHelperAidl(
std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> effect,
int32_t sessionId, int32_t ioId, const Descriptor& desc)
- : mSessionId(sessionId), mIoId(ioId), mDesc(desc), mEffect(std::move(effect)) {
+ : mSessionId(sessionId),
+ mIoId(ioId),
+ mDesc(desc),
+ mEffect(std::move(effect)),
+ mIsInputStream(mDesc.common.flags.type == Flags::Type::PRE_PROC) {
mCommon.session = sessionId;
mCommon.ioHandle = ioId;
mCommon.input = mCommon.output = kDefaultAudioConfig;
@@ -136,16 +144,32 @@
return ret;
}
-status_t EffectConversionHelperAidl::handleSetConfig(uint32_t cmdSize,
- const void* pCmdData __unused,
+status_t EffectConversionHelperAidl::handleSetConfig(uint32_t cmdSize, const void* pCmdData,
uint32_t* replySize, void* pReplyData) {
if (!replySize || *replySize != sizeof(int) || !pReplyData ||
cmdSize != sizeof(effect_config_t)) {
+ ALOGE("%s parameter invalid %u %p %p %p", __func__, cmdSize, pCmdData, replySize,
+ pReplyData);
return BAD_VALUE;
}
- // TODO: need to implement setConfig with setParameter(common)
- return *static_cast<int32_t*>(pReplyData) = OK;
+ effect_config_t* config = (effect_config_t*)pCmdData;
+ Parameter::Common aidlCommon = {
+ .session = mSessionId,
+ .ioHandle = mIoId,
+ .input = {.base = VALUE_OR_RETURN_STATUS(
+ ::aidl::android::legacy2aidl_buffer_config_t_AudioConfigBase(
+ config->inputCfg, mIsInputStream))},
+ .output = {.base = VALUE_OR_RETURN_STATUS(
+ ::aidl::android::legacy2aidl_buffer_config_t_AudioConfigBase(
+ config->outputCfg, mIsInputStream))}};
+
+ Parameter aidlParam = UNION_MAKE(Parameter, common, aidlCommon);
+
+ status_t ret = statusTFromBinderStatus(mEffect->setParameter(aidlParam));
+ EffectParamWriter writer(*(effect_param_t*)pReplyData);
+ writer.setStatus(ret);
+ return ret;
}
status_t EffectConversionHelperAidl::handleGetConfig(uint32_t cmdSize __unused,
@@ -250,17 +274,17 @@
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 || !pReplyData) {
- ALOGE("%s parameter invalid %u %p %p %p", __func__, cmdSize, pCmdData, replySize,
- pReplyData);
+ uint32_t* replySize __unused,
+ void* pReplyData __unused) {
+ if (cmdSize != 2 * sizeof(uint32_t) || !pCmdData) {
+ ALOGE("%s parameter invalid %u %p", __func__, cmdSize, pCmdData);
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;
+ return OK;
}
status_t EffectConversionHelperAidl::handleSetOffload(uint32_t cmdSize, const void* pCmdData,
@@ -274,16 +298,44 @@
return *static_cast<int32_t*>(pReplyData) = OK;
}
-status_t EffectConversionHelperAidl::handleFirstPriority(uint32_t cmdSize __unused,
- const void* pCmdData __unused,
- uint32_t* replySize, void* pReplyData) {
+status_t EffectConversionHelperAidl::handleVisualizerCapture(uint32_t cmdSize __unused,
+ const void* pCmdData __unused,
+ uint32_t* replySize,
+ void* pReplyData) {
if (!replySize || !pReplyData) {
ALOGE("%s parameter invalid %p %p", __func__, replySize, pReplyData);
return BAD_VALUE;
}
- // TODO to be implemented
- return OK;
+ const auto& uuid = VALUE_OR_RETURN_STATUS(
+ ::aidl::android::aidl2legacy_AudioUuid_audio_uuid_t(mDesc.common.id.type));
+ if (0 != memcmp(&uuid, SL_IID_VISUALIZATION, sizeof(effect_uuid_t))) {
+ ALOGE("%s visualizer command not supported by %s", __func__,
+ mDesc.common.id.toString().c_str());
+ return BAD_VALUE;
+ }
+
+ return visualizerCapture(replySize, pReplyData);
+}
+
+status_t EffectConversionHelperAidl::handleVisualizerMeasure(uint32_t cmdSize __unused,
+ const void* pCmdData __unused,
+ uint32_t* replySize,
+ void* pReplyData) {
+ if (!replySize || !pReplyData) {
+ ALOGE("%s parameter invalid %p %p", __func__, replySize, pReplyData);
+ return BAD_VALUE;
+ }
+
+ const auto& uuid = VALUE_OR_RETURN_STATUS(
+ ::aidl::android::aidl2legacy_AudioUuid_audio_uuid_t(mDesc.common.id.type));
+ if (0 != memcmp(&uuid, SL_IID_VISUALIZATION, sizeof(effect_uuid_t))) {
+ ALOGE("%s visualizer command not supported by %s", __func__,
+ mDesc.common.id.toString().c_str());
+ return BAD_VALUE;
+ }
+
+ return visualizerMeasure(replySize, pReplyData);
}
} // namespace effect
diff --git a/media/libaudiohal/impl/EffectConversionHelperAidl.h b/media/libaudiohal/impl/EffectConversionHelperAidl.h
index 94435c6..54df1b8 100644
--- a/media/libaudiohal/impl/EffectConversionHelperAidl.h
+++ b/media/libaudiohal/impl/EffectConversionHelperAidl.h
@@ -30,12 +30,18 @@
status_t handleCommand(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData, uint32_t* replySize,
void* pReplyData);
virtual ~EffectConversionHelperAidl() {}
+ const ::aidl::android::hardware::audio::effect::IEffect::OpenEffectReturn&
+ getEffectReturnParam() const {
+ return mOpenReturn;
+ }
protected:
const int32_t mSessionId;
const int32_t mIoId;
const ::aidl::android::hardware::audio::effect::Descriptor mDesc;
const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> mEffect;
+ // whether the effect is instantiated on an input stream
+ const bool mIsInputStream;
::aidl::android::hardware::audio::effect::IEffect::OpenEffectReturn mOpenReturn;
::aidl::android::hardware::audio::effect::Parameter::Common mCommon;
@@ -92,12 +98,20 @@
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);
+ status_t handleVisualizerCapture(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
+ void* pReplyData);
+ status_t handleVisualizerMeasure(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
+ void* pReplyData);
// implemented by conversion of each effect
virtual status_t setParameter(utils::EffectParamReader& param) = 0;
virtual status_t getParameter(utils::EffectParamWriter& param) = 0;
+ virtual status_t visualizerCapture(uint32_t* replySize __unused, void* pReplyData __unused) {
+ return BAD_VALUE;
+ }
+ virtual status_t visualizerMeasure(uint32_t* replySize __unused, void* pReplyData __unused) {
+ return BAD_VALUE;
+ }
};
} // namespace effect
diff --git a/media/libaudiohal/impl/EffectHalAidl.cpp b/media/libaudiohal/impl/EffectHalAidl.cpp
index 8fa301a..3e843c6 100644
--- a/media/libaudiohal/impl/EffectHalAidl.cpp
+++ b/media/libaudiohal/impl/EffectHalAidl.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <cstddef>
#define LOG_TAG "EffectHalAidl"
//#define LOG_NDEBUG 0
@@ -34,6 +35,7 @@
#include <aidl/android/hardware/audio/effect/IEffect.h>
#include "effectsAidlConversion/AidlConversionAec.h"
+#include "effectsAidlConversion/AidlConversionAgc1.h"
#include "effectsAidlConversion/AidlConversionAgc2.h"
#include "effectsAidlConversion/AidlConversionBassBoost.h"
#include "effectsAidlConversion/AidlConversionDownmix.h"
@@ -88,6 +90,9 @@
if (typeUuid == kAcousticEchoCancelerTypeUUID) {
mConversion =
std::make_unique<android::effect::AidlConversionAec>(effect, sessionId, ioId, desc);
+ } else if (typeUuid == kAutomaticGainControl1TypeUUID) {
+ mConversion = std::make_unique<android::effect::AidlConversionAgc1>(effect, sessionId, ioId,
+ desc);
} else if (typeUuid == kAutomaticGainControl2TypeUUID) {
mConversion = std::make_unique<android::effect::AidlConversionAgc2>(effect, sessionId, ioId,
desc);
@@ -136,24 +141,51 @@
}
status_t EffectHalAidl::setInBuffer(const sp<EffectBufferHalInterface>& buffer) {
- if (buffer == nullptr) {
- return BAD_VALUE;
- }
- ALOGW("%s not implemented yet", __func__);
+ mInBuffer = buffer;
return OK;
}
status_t EffectHalAidl::setOutBuffer(const sp<EffectBufferHalInterface>& buffer) {
- if (buffer == nullptr) {
- return BAD_VALUE;
- }
- ALOGW("%s not implemented yet", __func__);
+ mOutBuffer = buffer;
return OK;
}
+
+// write to input FMQ here, wait for statusMQ STATUS_OK, and read from output FMQ
status_t EffectHalAidl::process() {
- ALOGW("%s not implemented yet", __func__);
- // write to input FMQ here, and wait for statusMQ STATUS_OK
+ size_t available = mInputQ->availableToWrite();
+ size_t floatsToWrite = std::min(available, mInBuffer->getSize() / sizeof(float));
+ if (floatsToWrite == 0) {
+ ALOGW("%s not able to write, floats in buffer %zu, space in FMQ %zu", __func__,
+ mInBuffer->getSize() / sizeof(float), available);
+ return INVALID_OPERATION;
+ }
+ if (!mInputQ->write((float*)mInBuffer->ptr(), floatsToWrite)) {
+ ALOGW("%s failed to write %zu into inputQ", __func__, floatsToWrite);
+ return INVALID_OPERATION;
+ }
+
+ IEffect::Status retStatus{};
+ if (!mStatusQ->readBlocking(&retStatus, 1) || retStatus.status != OK ||
+ (size_t)retStatus.fmqConsumed != floatsToWrite || retStatus.fmqProduced == 0) {
+ ALOGW("%s read status failed: %s", __func__, retStatus.toString().c_str());
+ return INVALID_OPERATION;
+ }
+
+ available = mOutputQ->availableToRead();
+ size_t floatsToRead = std::min(available, mOutBuffer->getSize() / sizeof(float));
+ if (floatsToRead == 0) {
+ ALOGW("%s not able to read, buffer space %zu, floats in FMQ %zu", __func__,
+ mOutBuffer->getSize() / sizeof(float), available);
+ return INVALID_OPERATION;
+ }
+ if (!mOutputQ->read((float*)mOutBuffer->ptr(), floatsToRead)) {
+ ALOGW("%s failed to read %zu from outputQ", __func__, floatsToRead);
+ return INVALID_OPERATION;
+ }
+
+ ALOGD("%s %s consumed %zu produced %zu", __func__, mDesc.common.name.c_str(), floatsToWrite,
+ floatsToRead);
return OK;
}
@@ -165,14 +197,32 @@
status_t EffectHalAidl::command(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData,
uint32_t* replySize, void* pReplyData) {
- return mConversion
- ? mConversion->handleCommand(cmdCode, cmdSize, pCmdData, replySize, pReplyData)
- : INVALID_OPERATION;
+ TIME_CHECK();
+ if (!mConversion) {
+ ALOGE("%s can not handle command %d when conversion not exist", __func__, cmdCode);
+ return INVALID_OPERATION;
+ }
+
+ status_t ret = mConversion->handleCommand(cmdCode, cmdSize, pCmdData, replySize, pReplyData);
+ // update FMQs when effect open successfully
+ if (ret == OK && cmdCode == EFFECT_CMD_INIT) {
+ const auto& retParam = mConversion->getEffectReturnParam();
+ mStatusQ = std::make_unique<StatusMQ>(retParam.statusMQ);
+ mInputQ = std::make_unique<DataMQ>(retParam.inputDataMQ);
+ mOutputQ = std::make_unique<DataMQ>(retParam.outputDataMQ);
+ if (!mStatusQ->isValid() || !mInputQ->isValid() || !mOutputQ->isValid()) {
+ ALOGE("%s return with invalid FMQ", __func__);
+ return NO_INIT;
+ }
+ }
+
+ return ret;
}
status_t EffectHalAidl::getDescriptor(effect_descriptor_t* pDescriptor) {
- ALOGW("%s %p", __func__, pDescriptor);
+ TIME_CHECK();
if (pDescriptor == nullptr) {
+ ALOGE("%s null descriptor pointer", __func__);
return BAD_VALUE;
}
Descriptor aidlDesc;
@@ -184,12 +234,13 @@
}
status_t EffectHalAidl::close() {
+ TIME_CHECK();
return statusTFromBinderStatus(mEffect->close());
}
status_t EffectHalAidl::dump(int fd) {
- ALOGW("%s not implemented yet, fd %d", __func__, fd);
- return OK;
+ TIME_CHECK();
+ return mEffect->dump(fd, nullptr, 0);
}
} // namespace effect
diff --git a/media/libaudiohal/impl/EffectHalAidl.h b/media/libaudiohal/impl/EffectHalAidl.h
index 83b644b..194150d 100644
--- a/media/libaudiohal/impl/EffectHalAidl.h
+++ b/media/libaudiohal/impl/EffectHalAidl.h
@@ -16,11 +16,13 @@
#pragma once
+#include <memory>
+
#include <aidl/android/hardware/audio/effect/IEffect.h>
#include <aidl/android/hardware/audio/effect/IFactory.h>
+#include <fmq/AidlMessageQueue.h>
#include <media/audiohal/EffectHalInterface.h>
#include <system/audio_effect.h>
-#include <memory>
#include "EffectConversionHelperAidl.h"
@@ -29,6 +31,12 @@
class EffectHalAidl : public EffectHalInterface {
public:
+ using StatusMQ = ::android::AidlMessageQueue<
+ ::aidl::android::hardware::audio::effect::IEffect::Status,
+ ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>;
+ using DataMQ = ::android::AidlMessageQueue<
+ float, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>;
+
// Set the input buffer.
status_t setInBuffer(const sp<EffectBufferHalInterface>& buffer) override;
@@ -63,6 +71,9 @@
return mEffect;
}
+ // for TIME_CHECK
+ const std::string getClassName() const { return "EffectHalAidl"; }
+
private:
friend class sp<EffectHalAidl>;
@@ -73,6 +84,8 @@
const int32_t mIoId;
const ::aidl::android::hardware::audio::effect::Descriptor mDesc;
std::unique_ptr<EffectConversionHelperAidl> mConversion;
+ std::unique_ptr<StatusMQ> mStatusQ;
+ std::unique_ptr<DataMQ> mInputQ, mOutputQ;
sp<EffectBufferHalInterface> mInBuffer, mOutBuffer;
effect_config_t mConfig;
diff --git a/media/libaudiohal/impl/EffectHalHidl.cpp b/media/libaudiohal/impl/EffectHalHidl.cpp
index ed952a3..7ecdbd2 100644
--- a/media/libaudiohal/impl/EffectHalHidl.cpp
+++ b/media/libaudiohal/impl/EffectHalHidl.cpp
@@ -107,13 +107,13 @@
}
status_t EffectHalHidl::process() {
- // TIME_CHECK(); // TODO(b/238654698) reenable only when optimized.
+ // TIME_CHECK(); // TODO(b/243839867) reenable only when optimized.
return processImpl(static_cast<uint32_t>(MessageQueueFlagBits::REQUEST_PROCESS));
}
status_t EffectHalHidl::processReverse() {
- // TIME_CHECK(); // TODO(b/238654698) reenable only when optimized.
+ // TIME_CHECK(); // TODO(b/243839867) reenable only when optimized.
return processImpl(static_cast<uint32_t>(MessageQueueFlagBits::REQUEST_PROCESS_REVERSE));
}
diff --git a/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp b/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
index 0aae87b..b418b6c 100644
--- a/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
+++ b/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
@@ -20,7 +20,6 @@
#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>
@@ -139,20 +138,18 @@
}
status_t EffectsFactoryHalAidl::dumpEffects(int fd) {
- ALOGE("%s not implemented yet, fd %d", __func__, fd);
- return INVALID_OPERATION;
+ // TODO: add proxy dump here because AIDL service EffectFactory doesn't have proxy handle
+ return mFactory->dump(fd, nullptr, 0);
}
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);
}
diff --git a/media/libaudiohal/impl/EffectsFactoryHalAidl.h b/media/libaudiohal/impl/EffectsFactoryHalAidl.h
index 1e85da9..9c3643b 100644
--- a/media/libaudiohal/impl/EffectsFactoryHalAidl.h
+++ b/media/libaudiohal/impl/EffectsFactoryHalAidl.h
@@ -20,6 +20,7 @@
#include <memory>
#include <mutex>
+#include <aidl/android/hardware/audio/effect/IFactory.h>
#include <android-base/thread_annotations.h>
#include <media/audiohal/EffectsFactoryHalInterface.h>
#include <system/thread_defs.h>
@@ -59,6 +60,9 @@
detail::AudioHalVersionInfo getHalVersion() const override;
+ // for TIME_CHECK
+ const std::string getClassName() const { return "EffectHalAidl"; }
+
private:
std::mutex mLock;
const std::shared_ptr<IFactory> mFactory;
diff --git a/media/libaudiohal/impl/StreamHalAidl.cpp b/media/libaudiohal/impl/StreamHalAidl.cpp
index a97bd02..9d67b67 100644
--- a/media/libaudiohal/impl/StreamHalAidl.cpp
+++ b/media/libaudiohal/impl/StreamHalAidl.cpp
@@ -21,12 +21,14 @@
#include <cstdint>
#include <audio_utils/clock.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::hardware::audio::core::IStreamCommon;
using ::aidl::android::hardware::audio::core::IStreamIn;
using ::aidl::android::hardware::audio::core::IStreamOut;
@@ -172,10 +174,17 @@
FALLTHROUGH_INTENDED;
case StreamDescriptor::State::PAUSED:
case StreamDescriptor::State::DRAIN_PAUSED:
- return flush();
+ if (mIsInput) return flush();
+ if (status_t status = flush(&reply); status != OK) return status;
+ if (reply.state != StreamDescriptor::State::IDLE) {
+ ALOGE("%s: unexpected stream state: %s (expected IDLE)",
+ __func__, toString(reply.state).c_str());
+ return INVALID_OPERATION;
+ }
+ FALLTHROUGH_INTENDED;
case StreamDescriptor::State::IDLE:
if (status_t status = sendCommand(makeHalCommand<HalCommand::Tag::standby>(),
- &reply); status != OK) {
+ &reply, true /*safeFromNonWorkerThread*/); status != OK) {
return status;
}
if (reply.state != StreamDescriptor::State::STANDBY) {
@@ -252,7 +261,7 @@
status_t StreamHalAidl::transfer(void *buffer, size_t bytes, size_t *transferred) {
ALOGV("%p %s::%s", this, getClassName().c_str(), __func__);
- // TIME_CHECK(); // TODO(b/238654698) reenable only when optimized.
+ // TIME_CHECK(); // TODO(b/243839867) reenable only when optimized.
if (!mStream || mContext.getDataMQ() == nullptr) return NO_INIT;
mWorkerTid.store(gettid(), std::memory_order_release);
// Switch the stream into an active state if needed.
@@ -286,13 +295,14 @@
if (status_t status = sendCommand(burst, &reply); status != OK) {
return status;
}
+ *transferred = reply.fmqByteCount;
if (mIsInput) {
- *transferred = reply.fmqByteCount;
LOG_ALWAYS_FATAL_IF(*transferred > bytes,
"%s: HAL module read %zu bytes, which exceeds requested count %zu",
__func__, *transferred, bytes);
- if (!mContext.getDataMQ()->read(static_cast<int8_t*>(buffer), *transferred)) {
- ALOGE("%s: failed to read %zu bytes to data MQ", __func__, *transferred);
+ if (auto toRead = mContext.getDataMQ()->availableToRead();
+ toRead != 0 && !mContext.getDataMQ()->read(static_cast<int8_t*>(buffer), toRead)) {
+ ALOGE("%s: failed to read %zu bytes to data MQ", __func__, toRead);
return NOT_ENOUGH_DATA;
}
}
@@ -315,6 +325,26 @@
if (mIsInput) {
return sendCommand(makeHalCommand<HalCommand::Tag::burst>(0), reply);
} else {
+ if (mContext.isAsynchronous()) {
+ // Handle pause-flush-resume sequence. 'flush' from PAUSED goes to
+ // IDLE. We move here from IDLE to ACTIVE (same as 'start' from PAUSED).
+ const auto state = getState();
+ if (state == StreamDescriptor::State::IDLE) {
+ StreamDescriptor::Reply localReply{};
+ StreamDescriptor::Reply* innerReply = reply ?: &localReply;
+ if (status_t status =
+ sendCommand(makeHalCommand<HalCommand::Tag::burst>(0), innerReply);
+ status != OK) {
+ return status;
+ }
+ if (innerReply->state != StreamDescriptor::State::ACTIVE) {
+ ALOGE("%s: unexpected stream state: %s (expected ACTIVE)",
+ __func__, toString(innerReply->state).c_str());
+ return INVALID_OPERATION;
+ }
+ return OK;
+ }
+ }
return sendCommand(makeHalCommand<HalCommand::Tag::start>(), reply);
}
}
@@ -326,7 +356,8 @@
return sendCommand(makeHalCommand<HalCommand::Tag::drain>(
mIsInput ? StreamDescriptor::DrainMode::DRAIN_UNSPECIFIED :
earlyNotify ? StreamDescriptor::DrainMode::DRAIN_EARLY_NOTIFY :
- StreamDescriptor::DrainMode::DRAIN_ALL), reply);
+ StreamDescriptor::DrainMode::DRAIN_ALL), reply,
+ true /*safeFromNonWorkerThread*/);
}
status_t StreamHalAidl::flush(StreamDescriptor::Reply* reply) {
@@ -396,7 +427,7 @@
const ::aidl::android::hardware::audio::core::StreamDescriptor::Command &command,
::aidl::android::hardware::audio::core::StreamDescriptor::Reply* reply,
bool safeFromNonWorkerThread) {
- // TIME_CHECK(); // TODO(b/238654698) reenable only when optimized.
+ // TIME_CHECK(); // TODO(b/243839867) reenable only when optimized.
if (!safeFromNonWorkerThread) {
const pid_t workerTid = mWorkerTid.load(std::memory_order_acquire);
LOG_ALWAYS_FATAL_IF(workerTid != gettid(),
@@ -464,11 +495,10 @@
return StreamHalAidl::getLatency(latency);
}
-status_t StreamOutHalAidl::setVolume(float left __unused, float right __unused) {
+status_t StreamOutHalAidl::setVolume(float left, float right) {
TIME_CHECK();
if (!mStream) return NO_INIT;
- ALOGE("%s not implemented yet", __func__);
- return OK;
+ return statusTFromBinderStatus(mStream->setHwVolume({left, right}));
}
status_t StreamOutHalAidl::selectPresentation(int presentationId __unused, int programId __unused) {
@@ -506,6 +536,10 @@
status_t StreamOutHalAidl::setCallback(wp<StreamOutHalInterfaceCallback> callback) {
TIME_CHECK();
if (!mStream) return NO_INIT;
+ if (!mContext.isAsynchronous()) {
+ ALOGE("%s: the callback is intended for asynchronous streams only", __func__);
+ return INVALID_OPERATION;
+ }
if (auto broker = mCallbackBroker.promote(); broker != nullptr) {
if (auto cb = callback.promote(); cb != nullptr) {
broker->setStreamOutCallback(this, cb);
@@ -609,7 +643,7 @@
TIME_CHECK();
if (!mStream) return NO_INIT;
ALOGE("%s not implemented yet", __func__);
- return OK;
+ return BAD_VALUE;
}
status_t StreamOutHalAidl::setPlaybackRateParameters(
@@ -617,7 +651,7 @@
TIME_CHECK();
if (!mStream) return NO_INIT;
ALOGE("%s not implemented yet", __func__);
- return OK;
+ return BAD_VALUE;
}
status_t StreamOutHalAidl::setEventCallback(
@@ -700,7 +734,7 @@
}
status_t StreamInHalAidl::getActiveMicrophones(
- std::vector<media::MicrophoneInfo> *microphones __unused) {
+ std::vector<media::MicrophoneInfoFw> *microphones __unused) {
TIME_CHECK();
if (!mStream) return NO_INIT;
ALOGE("%s not implemented yet", __func__);
diff --git a/media/libaudiohal/impl/StreamHalAidl.h b/media/libaudiohal/impl/StreamHalAidl.h
index 162c7bc..d00774c 100644
--- a/media/libaudiohal/impl/StreamHalAidl.h
+++ b/media/libaudiohal/impl/StreamHalAidl.h
@@ -43,24 +43,28 @@
::aidl::android::hardware::common::fmq::SynchronizedReadWrite> DataMQ;
explicit StreamContextAidl(
- const ::aidl::android::hardware::audio::core::StreamDescriptor& descriptor)
+ const ::aidl::android::hardware::audio::core::StreamDescriptor& descriptor,
+ bool isAsynchronous)
: mFrameSizeBytes(descriptor.frameSizeBytes),
mCommandMQ(new CommandMQ(descriptor.command)),
mReplyMQ(new ReplyMQ(descriptor.reply)),
mBufferSizeFrames(descriptor.bufferSizeFrames),
- mDataMQ(maybeCreateDataMQ(descriptor)) {}
+ mDataMQ(maybeCreateDataMQ(descriptor)),
+ mIsAsynchronous(isAsynchronous) {}
StreamContextAidl(StreamContextAidl&& other) :
mFrameSizeBytes(other.mFrameSizeBytes),
mCommandMQ(std::move(other.mCommandMQ)),
mReplyMQ(std::move(other.mReplyMQ)),
mBufferSizeFrames(other.mBufferSizeFrames),
- mDataMQ(std::move(other.mDataMQ)) {}
+ mDataMQ(std::move(other.mDataMQ)),
+ mIsAsynchronous(other.mIsAsynchronous) {}
StreamContextAidl& operator=(StreamContextAidl&& other) {
mFrameSizeBytes = other.mFrameSizeBytes;
mCommandMQ = std::move(other.mCommandMQ);
mReplyMQ = std::move(other.mReplyMQ);
mBufferSizeFrames = other.mBufferSizeFrames;
mDataMQ = std::move(other.mDataMQ);
+ mIsAsynchronous = other.mIsAsynchronous;
return *this;
}
bool isValid() const {
@@ -78,6 +82,7 @@
DataMQ* getDataMQ() const { return mDataMQ.get(); }
size_t getFrameSizeBytes() const { return mFrameSizeBytes; }
ReplyMQ* getReplyMQ() const { return mReplyMQ.get(); }
+ bool isAsynchronous() const { return mIsAsynchronous; }
private:
static std::unique_ptr<DataMQ> maybeCreateDataMQ(
@@ -94,6 +99,7 @@
std::unique_ptr<ReplyMQ> mReplyMQ;
size_t mBufferSizeFrames;
std::unique_ptr<DataMQ> mDataMQ;
+ bool mIsAsynchronous;
};
class StreamHalAidl : public virtual StreamHalInterface, public ConversionHelperAidl {
@@ -328,7 +334,7 @@
status_t getCapturePosition(int64_t *frames, int64_t *time) override;
// Get active microphones
- status_t getActiveMicrophones(std::vector<media::MicrophoneInfo> *microphones) override;
+ status_t getActiveMicrophones(std::vector<media::MicrophoneInfoFw> *microphones) override;
// Set microphone direction (for processing)
status_t setPreferredMicrophoneDirection(
diff --git a/media/libaudiohal/impl/StreamHalHidl.cpp b/media/libaudiohal/impl/StreamHalHidl.cpp
index 2c289e1..192790c 100644
--- a/media/libaudiohal/impl/StreamHalHidl.cpp
+++ b/media/libaudiohal/impl/StreamHalHidl.cpp
@@ -24,6 +24,9 @@
#include <mediautils/SchedulingPolicyService.h>
#include <mediautils/TimeCheck.h>
#include <utils/Log.h>
+#if MAJOR_VERSION >= 4
+#include <media/AidlConversion.h>
+#endif
#include PATH(android/hardware/audio/CORE_TYPES_FILE_VERSION/IStreamOutCallback.h)
#include <HidlUtils.h>
@@ -438,7 +441,7 @@
#endif
status_t StreamOutHalHidl::write(const void *buffer, size_t bytes, size_t *written) {
- // TIME_CHECK(); // TODO(b/238654698) reenable only when optimized.
+ // TIME_CHECK(); // TODO(b/243839867) reenable only when optimized.
if (mStream == 0) return NO_INIT;
*written = 0;
@@ -584,7 +587,7 @@
}
status_t StreamOutHalHidl::getRenderPosition(uint32_t *dspFrames) {
- // TIME_CHECK(); // TODO(b/238654698) reenable only when optimized.
+ // TIME_CHECK(); // TODO(b/243839867) reenable only when optimized.
if (mStream == 0) return NO_INIT;
Result retval;
Return<void> ret = mStream->getRenderPosition(
@@ -665,7 +668,7 @@
}
status_t StreamOutHalHidl::getPresentationPosition(uint64_t *frames, struct timespec *timestamp) {
- // TIME_CHECK(); // TODO(b/238654698) reenable only when optimized.
+ // TIME_CHECK(); // TODO(b/243839867) reenable only when optimized.
if (mStream == 0) return NO_INIT;
if (mWriterClient == gettid() && mCommandMQ) {
return callWriterThread(
@@ -1009,7 +1012,7 @@
}
status_t StreamInHalHidl::read(void *buffer, size_t bytes, size_t *read) {
- // TIME_CHECK(); // TODO(b/238654698) reenable only when optimized.
+ // TIME_CHECK(); // TODO(b/243839867) reenable only when optimized.
if (mStream == 0) return NO_INIT;
*read = 0;
@@ -1143,7 +1146,7 @@
}
status_t StreamInHalHidl::getCapturePosition(int64_t *frames, int64_t *time) {
- // TIME_CHECK(); // TODO(b/238654698) reenable only when optimized.
+ // TIME_CHECK(); // TODO(b/243839867) reenable only when optimized.
if (mStream == 0) return NO_INIT;
if (mReaderClient == gettid() && mCommandMQ) {
ReadParameters params;
@@ -1169,7 +1172,7 @@
#if MAJOR_VERSION == 2
status_t StreamInHalHidl::getActiveMicrophones(
- std::vector<media::MicrophoneInfo> *microphones __unused) {
+ std::vector<media::MicrophoneInfoFw> *microphones __unused) {
if (mStream == 0) return NO_INIT;
return INVALID_OPERATION;
}
@@ -1182,7 +1185,7 @@
#elif MAJOR_VERSION >= 4
status_t StreamInHalHidl::getActiveMicrophones(
- std::vector<media::MicrophoneInfo> *microphonesInfo) {
+ std::vector<media::MicrophoneInfoFw> *microphonesInfo) {
TIME_CHECK();
if (!mStream) return NO_INIT;
Result retval;
@@ -1190,11 +1193,17 @@
[&](Result r, hidl_vec<MicrophoneInfo> micArrayHal) {
retval = r;
for (size_t k = 0; k < micArrayHal.size(); k++) {
+ // Convert via legacy.
audio_microphone_characteristic_t dst;
- // convert
(void)CoreUtils::microphoneInfoToHal(micArrayHal[k], &dst);
- media::MicrophoneInfo microphone = media::MicrophoneInfo(dst);
- microphonesInfo->push_back(microphone);
+ auto conv = legacy2aidl_audio_microphone_characteristic_t_MicrophoneInfoFw(dst);
+ if (conv.ok()) {
+ microphonesInfo->push_back(conv.value());
+ } else {
+ ALOGW("getActiveMicrophones: could not convert %s to AIDL: %d",
+ toString(micArrayHal[k]).c_str(), conv.error());
+ microphonesInfo->push_back(media::MicrophoneInfoFw{});
+ }
}
});
return processReturn("getActiveMicrophones", ret, retval);
diff --git a/media/libaudiohal/impl/StreamHalHidl.h b/media/libaudiohal/impl/StreamHalHidl.h
index 54fbefe..5361047 100644
--- a/media/libaudiohal/impl/StreamHalHidl.h
+++ b/media/libaudiohal/impl/StreamHalHidl.h
@@ -253,7 +253,7 @@
virtual status_t getCapturePosition(int64_t *frames, int64_t *time);
// Get active microphones
- virtual status_t getActiveMicrophones(std::vector<media::MicrophoneInfo> *microphones);
+ status_t getActiveMicrophones(std::vector<media::MicrophoneInfoFw> *microphones) override;
// Set microphone direction (for processing)
virtual status_t setPreferredMicrophoneDirection(
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAec.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAec.cpp
index 15768b3..0bc23f9 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAec.cpp
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAec.cpp
@@ -33,9 +33,11 @@
namespace android {
namespace effect {
+using ::aidl::android::getParameterSpecificField;
using ::aidl::android::aidl_utils::statusTFromBinderStatus;
using ::aidl::android::hardware::audio::effect::AcousticEchoCanceler;
using ::aidl::android::hardware::audio::effect::Parameter;
+using ::aidl::android::hardware::audio::effect::VendorExtension;
using ::android::status_t;
using utils::EffectParamReader;
using utils::EffectParamWriter;
@@ -64,8 +66,13 @@
break;
}
default: {
- ALOGW("%s unknown param %s", __func__, param.toString().c_str());
- return BAD_VALUE;
+ // for vendor extension, copy data area to the DefaultExtension, parameter ignored
+ VendorExtension ext = VALUE_OR_RETURN_STATUS(
+ aidl::android::legacy2aidl_EffectParameterReader_Data_VendorExtension(param));
+ aidlParam = MAKE_SPECIFIC_PARAMETER(AcousticEchoCanceler, acousticEchoCanceler, vendor,
+ ext);
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->setParameter(aidlParam)));
+ break;
}
}
@@ -73,7 +80,7 @@
}
status_t AidlConversionAec::getParameter(EffectParamWriter& param) {
- uint32_t type = 0, value = 0;
+ uint32_t type = 0;
if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint32_t)) ||
OK != param.readFromParameter(&type)) {
param.setStatus(BAD_VALUE);
@@ -85,29 +92,30 @@
case AEC_PARAM_ECHO_DELAY:
FALLTHROUGH_INTENDED;
case AEC_PARAM_PROPERTIES: {
+ int32_t delay = 0;
Parameter::Id id =
MAKE_SPECIFIC_PARAMETER_ID(AcousticEchoCanceler, acousticEchoCancelerTag,
AcousticEchoCanceler::echoDelayUs);
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
- value = VALUE_OR_RETURN_STATUS(
+ delay = VALUE_OR_RETURN_STATUS(
aidl::android::aidl2legacy_Parameter_aec_uint32_echoDelay(aidlParam));
- break;
+ return param.writeToValue(&delay);
}
case AEC_PARAM_MOBILE_MODE: {
+ int32_t mode = 0;
Parameter::Id id =
MAKE_SPECIFIC_PARAMETER_ID(AcousticEchoCanceler, acousticEchoCancelerTag,
AcousticEchoCanceler::mobileMode);
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
- value = VALUE_OR_RETURN_STATUS(
+ mode = VALUE_OR_RETURN_STATUS(
aidl::android::aidl2legacy_Parameter_aec_uint32_mobileMode(aidlParam));
- break;
+ return param.writeToValue(&mode);
}
- default:
- // use vendor extension implementation
- ALOGW("%s unknown param %s", __func__, param.toString().c_str());
- return BAD_VALUE;
+ default: {
+ // use vendor extension implementation, the first 32bits (param type) won't pass to HAL
+ VENDOR_EXTENSION_GET_AND_RETURN(AcousticEchoCanceler, acousticEchoCanceler, param);
+ }
}
- return param.writeToValue(&value);
}
} // namespace effect
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAgc1.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAgc1.cpp
new file mode 100644
index 0000000..8c19612
--- /dev/null
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAgc1.cpp
@@ -0,0 +1,164 @@
+/*
+ * 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>
+#include <optional>
+#define LOG_TAG "AidlConversionAgc1"
+//#define LOG_NDEBUG 0
+
+#include <error/expected_utils.h>
+#include <media/AidlConversionNdk.h>
+#include <media/AidlConversionEffect.h>
+#include <media/audiohal/AudioEffectUuid.h>
+#include <system/audio_effects/effect_agc.h>
+
+#include <utils/Log.h>
+
+#include "AidlConversionAgc1.h"
+
+namespace android {
+namespace effect {
+
+using ::aidl::android::getParameterSpecificField;
+using ::aidl::android::aidl_utils::statusTFromBinderStatus;
+using ::aidl::android::hardware::audio::effect::AutomaticGainControlV1;
+using ::aidl::android::hardware::audio::effect::Parameter;
+using ::aidl::android::hardware::audio::effect::VendorExtension;
+using ::android::status_t;
+using utils::EffectParamReader;
+using utils::EffectParamWriter;
+
+status_t AidlConversionAgc1::setParameterLevel(EffectParamReader& param) {
+ int16_t level;
+ RETURN_STATUS_IF_ERROR(param.readFromValue(&level));
+ Parameter aidlParam = MAKE_SPECIFIC_PARAMETER(AutomaticGainControlV1, automaticGainControlV1,
+ targetPeakLevelDbFs, level);
+ return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
+}
+
+status_t AidlConversionAgc1::setParameterGain(EffectParamReader& param) {
+ int16_t gain;
+ RETURN_STATUS_IF_ERROR(param.readFromValue(&gain));
+ Parameter aidlParam = MAKE_SPECIFIC_PARAMETER(AutomaticGainControlV1, automaticGainControlV1,
+ maxCompressionGainDb, gain);
+ return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
+}
+
+status_t AidlConversionAgc1::setParameterLimiterEnable(EffectParamReader& param) {
+ bool enable;
+ RETURN_STATUS_IF_ERROR(param.readFromValue(&enable));
+ Parameter aidlParam = MAKE_SPECIFIC_PARAMETER(AutomaticGainControlV1, automaticGainControlV1,
+ enableLimiter, enable);
+ return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
+}
+
+status_t AidlConversionAgc1::setParameter(EffectParamReader& param) {
+ uint32_t type = 0;
+ if (OK != param.readFromParameter(&type)) {
+ ALOGE("%s invalid param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ switch (type) {
+ case AGC_PARAM_TARGET_LEVEL: {
+ return setParameterLevel(param);
+ }
+ case AGC_PARAM_COMP_GAIN: {
+ return setParameterGain(param);
+ }
+ case AGC_PARAM_LIMITER_ENA: {
+ return setParameterLimiterEnable(param);
+ }
+ case AGC_PARAM_PROPERTIES: {
+ RETURN_STATUS_IF_ERROR(setParameterLevel(param));
+ RETURN_STATUS_IF_ERROR(setParameterGain(param));
+ RETURN_STATUS_IF_ERROR(setParameterLimiterEnable(param));
+ return OK;
+ }
+ default: {
+ // for vendor extension, copy data area to the DefaultExtension, parameter ignored
+ VendorExtension ext = VALUE_OR_RETURN_STATUS(
+ aidl::android::legacy2aidl_EffectParameterReader_Data_VendorExtension(param));
+ Parameter aidlParam = MAKE_SPECIFIC_PARAMETER(AutomaticGainControlV1,
+ automaticGainControlV1, vendor, ext);
+ return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
+ }
+ }
+}
+
+status_t AidlConversionAgc1::getParameterLevel(EffectParamWriter& param) {
+ Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(AutomaticGainControlV1, automaticGainControlV1Tag,
+ AutomaticGainControlV1::targetPeakLevelDbFs);
+ Parameter aidlParam;
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+ int32_t level = VALUE_OR_RETURN_STATUS(
+ GET_PARAMETER_SPECIFIC_FIELD(aidlParam, AutomaticGainControlV1, automaticGainControlV1,
+ AutomaticGainControlV1::targetPeakLevelDbFs, int32_t));
+ return param.writeToValue(&level);
+}
+
+status_t AidlConversionAgc1::getParameterGain(EffectParamWriter& param) {
+ Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(AutomaticGainControlV1, automaticGainControlV1Tag,
+ AutomaticGainControlV1::maxCompressionGainDb);
+ Parameter aidlParam;
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+ int32_t gain = VALUE_OR_RETURN_STATUS(
+ GET_PARAMETER_SPECIFIC_FIELD(aidlParam, AutomaticGainControlV1, automaticGainControlV1,
+ AutomaticGainControlV1::maxCompressionGainDb, int32_t));
+ return param.writeToValue(&gain);
+}
+
+status_t AidlConversionAgc1::getParameterLimiterEnable(EffectParamWriter& param) {
+ Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(AutomaticGainControlV1, automaticGainControlV1Tag,
+ AutomaticGainControlV1::enableLimiter);
+ Parameter aidlParam;
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+ bool enable = VALUE_OR_RETURN_STATUS(
+ GET_PARAMETER_SPECIFIC_FIELD(aidlParam, AutomaticGainControlV1, automaticGainControlV1,
+ AutomaticGainControlV1::enableLimiter, bool));
+ return param.writeToValue(&enable);
+}
+
+status_t AidlConversionAgc1::getParameter(EffectParamWriter& param) {
+ uint32_t type = 0;
+ if (OK != param.readFromParameter(&type)) {
+ ALOGE("%s invalid param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ switch (type) {
+ case AGC_PARAM_TARGET_LEVEL: {
+ return getParameterLevel(param);
+ }
+ case AGC_PARAM_COMP_GAIN: {
+ return getParameterGain(param);
+ }
+ case AGC_PARAM_LIMITER_ENA: {
+ return getParameterLimiterEnable(param);
+ }
+ case AGC_PARAM_PROPERTIES: {
+ RETURN_STATUS_IF_ERROR(getParameterLevel(param));
+ RETURN_STATUS_IF_ERROR(getParameterGain(param));
+ RETURN_STATUS_IF_ERROR(getParameterLimiterEnable(param));
+ return OK;
+ }
+ default: {
+ VENDOR_EXTENSION_GET_AND_RETURN(AutomaticGainControlV1, automaticGainControlV1, param);
+ }
+ }
+}
+
+} // namespace effect
+} // namespace android
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAgc1.h b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAgc1.h
new file mode 100644
index 0000000..b0509fd
--- /dev/null
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAgc1.h
@@ -0,0 +1,46 @@
+/*
+ * 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/IEffect.h>
+#include "EffectConversionHelperAidl.h"
+
+namespace android {
+namespace effect {
+
+class AidlConversionAgc1 : public EffectConversionHelperAidl {
+ public:
+ AidlConversionAgc1(std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> effect,
+ int32_t sessionId, int32_t ioId,
+ const ::aidl::android::hardware::audio::effect::Descriptor& desc)
+ : EffectConversionHelperAidl(effect, sessionId, ioId, desc) {}
+ ~AidlConversionAgc1() {}
+
+ private:
+ status_t setParameterLevel(utils::EffectParamReader& param);
+ status_t setParameterGain(utils::EffectParamReader& param);
+ status_t setParameterLimiterEnable(utils::EffectParamReader& param);
+ status_t setParameter(utils::EffectParamReader& param) override;
+
+ status_t getParameterLevel(utils::EffectParamWriter& param);
+ status_t getParameterGain(utils::EffectParamWriter& param);
+ status_t getParameterLimiterEnable(utils::EffectParamWriter& param);
+ status_t getParameter(utils::EffectParamWriter& param) override;
+};
+
+} // namespace effect
+} // namespace android
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAgc2.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAgc2.cpp
index 80df2b8..82cea3d 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAgc2.cpp
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAgc2.cpp
@@ -33,9 +33,11 @@
namespace android {
namespace effect {
+using ::aidl::android::getParameterSpecificField;
using ::aidl::android::aidl_utils::statusTFromBinderStatus;
-using ::aidl::android::hardware::audio::effect::AutomaticGainControl;
+using ::aidl::android::hardware::audio::effect::AutomaticGainControlV2;
using ::aidl::android::hardware::audio::effect::Parameter;
+using ::aidl::android::hardware::audio::effect::VendorExtension;
using ::android::status_t;
using utils::EffectParamReader;
using utils::EffectParamWriter;
@@ -65,8 +67,12 @@
break;
}
default: {
- ALOGW("%s unknown param %s", __func__, param.toString().c_str());
- return BAD_VALUE;
+ // for vendor extension, copy data area to the DefaultExtension, parameter ignored
+ VendorExtension ext = VALUE_OR_RETURN_STATUS(
+ aidl::android::legacy2aidl_EffectParameterReader_Data_VendorExtension(param));
+ aidlParam = MAKE_SPECIFIC_PARAMETER(AutomaticGainControlV2, automaticGainControlV2,
+ vendor, ext);
+ break;
}
}
@@ -84,8 +90,8 @@
switch (type) {
case AGC2_PARAM_FIXED_DIGITAL_GAIN: {
Parameter::Id id =
- MAKE_SPECIFIC_PARAMETER_ID(AutomaticGainControl, automaticGainControlTag,
- AutomaticGainControl::fixedDigitalGainMb);
+ MAKE_SPECIFIC_PARAMETER_ID(AutomaticGainControlV2, automaticGainControlV2Tag,
+ AutomaticGainControlV2::fixedDigitalGainMb);
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
value = VALUE_OR_RETURN_STATUS(
aidl::android::aidl2legacy_Parameter_agc_uint32_fixedDigitalGain(aidlParam));
@@ -93,8 +99,8 @@
}
case AGC2_PARAM_ADAPT_DIGI_LEVEL_ESTIMATOR: {
Parameter::Id id =
- MAKE_SPECIFIC_PARAMETER_ID(AutomaticGainControl, automaticGainControlTag,
- AutomaticGainControl::levelEstimator);
+ MAKE_SPECIFIC_PARAMETER_ID(AutomaticGainControlV2, automaticGainControlV2Tag,
+ AutomaticGainControlV2::levelEstimator);
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
value = VALUE_OR_RETURN_STATUS(
aidl::android::aidl2legacy_Parameter_agc_uint32_levelEstimator(aidlParam));
@@ -102,16 +108,15 @@
}
case AGC2_PARAM_ADAPT_DIGI_EXTRA_SATURATION_MARGIN: {
Parameter::Id id =
- MAKE_SPECIFIC_PARAMETER_ID(AutomaticGainControl, automaticGainControlTag,
- AutomaticGainControl::saturationMarginMb);
+ MAKE_SPECIFIC_PARAMETER_ID(AutomaticGainControlV2, automaticGainControlV2Tag,
+ AutomaticGainControlV2::saturationMarginMb);
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
value = VALUE_OR_RETURN_STATUS(
aidl::android::aidl2legacy_Parameter_agc_uint32_saturationMargin(aidlParam));
break;
}
default: {
- ALOGW("%s unknown param %s", __func__, param.toString().c_str());
- return BAD_VALUE;
+ VENDOR_EXTENSION_GET_AND_RETURN(AutomaticGainControlV2, automaticGainControlV2, param);
}
}
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionBassBoost.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionBassBoost.cpp
index 038b7df..1cf2c73 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionBassBoost.cpp
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionBassBoost.cpp
@@ -24,6 +24,7 @@
#include <media/AidlConversionNdk.h>
#include <media/AidlConversionEffect.h>
#include <media/audiohal/AudioEffectUuid.h>
+#include <system/audio_effects/aidl_effects_utils.h>
#include <system/audio_effects/effect_bassboost.h>
#include <utils/Log.h>
@@ -34,9 +35,12 @@
namespace effect {
using ::aidl::android::convertIntegral;
+using ::aidl::android::getParameterSpecificField;
using ::aidl::android::aidl_utils::statusTFromBinderStatus;
using ::aidl::android::hardware::audio::effect::BassBoost;
using ::aidl::android::hardware::audio::effect::Parameter;
+using ::aidl::android::hardware::audio::effect::Range;
+using ::aidl::android::hardware::audio::effect::VendorExtension;
using ::android::status_t;
using utils::EffectParamReader;
using utils::EffectParamWriter;
@@ -61,8 +65,11 @@
return BAD_VALUE;
}
default: {
- ALOGW("%s unknown param %s", __func__, param.toString().c_str());
- return BAD_VALUE;
+ // for vendor extension, copy data area to the DefaultExtension, parameter ignored
+ VendorExtension ext = VALUE_OR_RETURN_STATUS(
+ aidl::android::legacy2aidl_EffectParameterReader_Data_VendorExtension(param));
+ aidlParam = MAKE_SPECIFIC_PARAMETER(BassBoost, bassBoost, vendor, ext);
+ break;
}
}
@@ -80,7 +87,7 @@
Parameter aidlParam;
switch (type) {
case BASSBOOST_PARAM_STRENGTH: {
- uint32_t value;
+ uint16_t value;
Parameter::Id id =
MAKE_SPECIFIC_PARAMETER_ID(BassBoost, bassBoostTag, BassBoost::strengthPm);
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
@@ -89,15 +96,14 @@
return param.writeToValue(&value);
}
case BASSBOOST_PARAM_STRENGTH_SUPPORTED: {
- uint16_t value;
- const auto& cap =
- VALUE_OR_RETURN_STATUS(aidl::android::UNION_GET(mDesc.capability, bassBoost));
- value = VALUE_OR_RETURN_STATUS(convertIntegral<uint32_t>(cap.strengthSupported));
+ // an invalid range indicates not setting support for this parameter
+ uint32_t value =
+ ::aidl::android::hardware::audio::effect::isRangeValid<Range::Tag::bassBoost>(
+ BassBoost::strengthPm, mDesc.capability);
return param.writeToValue(&value);
}
default: {
- ALOGW("%s unknown param %s", __func__, param.toString().c_str());
- return BAD_VALUE;
+ VENDOR_EXTENSION_GET_AND_RETURN(BassBoost, bassBoost, param);
}
}
}
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionDownmix.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionDownmix.cpp
index 17cedf7..7bee37b 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionDownmix.cpp
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionDownmix.cpp
@@ -34,9 +34,11 @@
namespace android {
namespace effect {
+using ::aidl::android::getParameterSpecificField;
using ::aidl::android::aidl_utils::statusTFromBinderStatus;
using ::aidl::android::hardware::audio::effect::Downmix;
using ::aidl::android::hardware::audio::effect::Parameter;
+using ::aidl::android::hardware::audio::effect::VendorExtension;
using ::android::status_t;
using utils::EffectParamReader;
using utils::EffectParamWriter;
@@ -57,8 +59,10 @@
break;
}
default: {
- ALOGW("%s unknown param %s", __func__, param.toString().c_str());
- return BAD_VALUE;
+ // for vendor extension, copy data area to the DefaultExtension, parameter ignored
+ VendorExtension ext = VALUE_OR_RETURN_STATUS(
+ aidl::android::legacy2aidl_EffectParameterReader_Data_VendorExtension(param));
+ aidlParam = MAKE_SPECIFIC_PARAMETER(Downmix, downmix, vendor, ext);
}
}
@@ -83,8 +87,7 @@
break;
}
default: {
- ALOGW("%s unknown param %s", __func__, param.toString().c_str());
- return BAD_VALUE;
+ VENDOR_EXTENSION_GET_AND_RETURN(Downmix, downmix, param);
}
}
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionDynamicsProcessing.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionDynamicsProcessing.cpp
index 4ecaa07..6e1ceae 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionDynamicsProcessing.cpp
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionDynamicsProcessing.cpp
@@ -27,7 +27,7 @@
#include <media/audiohal/AudioEffectUuid.h>
#include <system/audio_effect.h>
#include <system/audio_effects/effect_dynamicsprocessing.h>
-
+#include <Utils.h>
#include <utils/Log.h>
#include "AidlConversionDynamicsProcessing.h"
@@ -36,30 +36,26 @@
namespace effect {
using ::aidl::android::convertIntegral;
+using ::aidl::android::getParameterSpecificField;
using ::aidl::android::aidl_utils::statusTFromBinderStatus;
using ::aidl::android::hardware::audio::effect::Capability;
using ::aidl::android::hardware::audio::effect::DynamicsProcessing;
using ::aidl::android::hardware::audio::effect::Parameter;
using ::aidl::android::hardware::audio::effect::toString;
+using ::aidl::android::hardware::audio::effect::VendorExtension;
using ::android::status_t;
using utils::EffectParamReader;
using utils::EffectParamWriter;
status_t AidlConversionDp::setParameter(EffectParamReader& param) {
uint32_t type = 0;
- if (OK != param.readFromParameter(&type)) {
- ALOGE("%s invalid param %s", __func__, param.toString().c_str());
- return BAD_VALUE;
- }
+ RETURN_STATUS_IF_ERROR(param.readFromParameter(&type));
Parameter aidlParam;
switch (type) {
case DP_PARAM_INPUT_GAIN: {
DynamicsProcessing::InputGain inputGainAidl;
- if (OK != param.readFromParameter(&inputGainAidl.channel) ||
- OK != param.readFromValue(&inputGainAidl.gainDb)) {
- ALOGE("%s invalid inputGain %s", __func__, param.toString().c_str());
- return BAD_VALUE;
- }
+ RETURN_STATUS_IF_ERROR(param.readFromParameter(&inputGainAidl.channel));
+ RETURN_STATUS_IF_ERROR(param.readFromValue(&inputGainAidl.gainDb));
aidlParam = MAKE_SPECIFIC_PARAMETER(DynamicsProcessing, dynamicsProcessing, inputGain,
{inputGainAidl});
break;
@@ -122,8 +118,12 @@
break;
}
default: {
- ALOGW("%s unknown param %s", __func__, param.toString().c_str());
- return BAD_VALUE;
+ // for vendor extension, copy data area to the DefaultExtension, parameter ignored
+ VendorExtension ext = VALUE_OR_RETURN_STATUS(
+ aidl::android::legacy2aidl_EffectParameterReader_Data_VendorExtension(param));
+ aidlParam =
+ MAKE_SPECIFIC_PARAMETER(DynamicsProcessing, dynamicsProcessing, vendor, ext);
+ break;
}
}
@@ -132,23 +132,16 @@
status_t AidlConversionDp::getParameter(EffectParamWriter& param) {
uint32_t type = 0;
- if (OK != param.readFromParameter(&type)) {
- ALOGE("%s invalid param %s", __func__, param.toString().c_str());
- }
+ RETURN_STATUS_IF_ERROR(param.readFromParameter(&type));
Parameter aidlParam;
switch (type) {
case DP_PARAM_INPUT_GAIN: {
int32_t channel;
- if (OK != param.readFromParameter(&channel)) {
- ALOGE("%s invalid inputGain %s", __func__, param.toString().c_str());
- return BAD_VALUE;
- }
+ RETURN_STATUS_IF_ERROR(param.readFromParameter(&channel));
Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(DynamicsProcessing, dynamicsProcessingTag,
DynamicsProcessing::inputGain);
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
- DynamicsProcessing::Capability cap =
- mDesc.capability.get<Capability::dynamicsProcessing>();
std::vector<DynamicsProcessing::InputGain> gains =
VALUE_OR_RETURN_STATUS(aidl::android::GET_PARAMETER_SPECIFIC_FIELD(
aidlParam, DynamicsProcessing, dynamicsProcessing,
@@ -163,11 +156,6 @@
return BAD_VALUE;
}
case DP_PARAM_ENGINE_ARCHITECTURE: {
- int32_t channel;
- if (OK != param.readFromParameter(&channel)) {
- ALOGE("%s invalid inputGain %s", __func__, param.toString().c_str());
- return BAD_VALUE;
- }
Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(DynamicsProcessing, dynamicsProcessingTag,
DynamicsProcessing::engineArchitecture);
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
@@ -188,18 +176,15 @@
VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(engine.postEqStage.inUse));
int32_t limiterInUse =
VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(engine.limiterInUse));
- if (OK != param.writeToValue(&resolution) ||
- OK != param.writeToValue(&engine.preferredProcessingDurationMs) ||
- OK != param.writeToValue(&preEqInUse) ||
- OK != param.writeToValue(&engine.preEqStage.bandCount) ||
- OK != param.writeToValue(&mbcInUse) ||
- OK != param.writeToValue(&engine.mbcStage.bandCount) ||
- OK != param.writeToValue(&postEqInUse) ||
- OK != param.writeToValue(&engine.postEqStage.bandCount) ||
- OK != param.writeToValue(&limiterInUse)) {
- ALOGE("%s invalid engineArchitecture %s", __func__, param.toString().c_str());
- return BAD_VALUE;
- }
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&resolution));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&engine.preferredProcessingDurationMs));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&preEqInUse));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&engine.preEqStage.bandCount));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&mbcInUse));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&engine.mbcStage.bandCount));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&postEqInUse));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&engine.postEqStage.bandCount));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&limiterInUse));
mEngine = engine;
return OK;
}
@@ -225,19 +210,13 @@
return getLimiterConfig(param);
}
case DP_PARAM_GET_CHANNEL_COUNT: {
- uint32_t channel = VALUE_OR_RETURN_STATUS(
- aidl::android::aidl2legacy_AudioChannelLayout_audio_channel_mask_t(
- mCommon.input.base.channelMask, true /* input */));
- if (OK != param.writeToValue(&channel)) {
- ALOGE("%s write channel number %d to param failed %s", __func__, channel,
- param.toString().c_str());
- return BAD_VALUE;
- }
+ uint32_t channel = ::android::hardware::audio::common::getChannelCount(
+ mCommon.input.base.channelMask);
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&channel));
return OK;
}
default: {
- ALOGW("%s unknown param %s", __func__, param.toString().c_str());
- return BAD_VALUE;
+ VENDOR_EXTENSION_GET_AND_RETURN(DynamicsProcessing, dynamicsProcessing, param);
}
}
}
@@ -245,10 +224,9 @@
aidl::ConversionResult<DynamicsProcessing::ChannelConfig>
AidlConversionDp::readChannelConfigFromParam(EffectParamReader& param) {
int32_t enable, channel;
- if (OK != param.readFromParameter(&channel) || OK != param.readFromValue(&enable)) {
- ALOGE("%s invalid channel config param %s", __func__, param.toString().c_str());
- return ::android::base::unexpected(::android::BAD_VALUE);
- }
+ RETURN_IF_ERROR(param.readFromParameter(&channel));
+ RETURN_IF_ERROR(param.readFromValue(&enable));
+
return DynamicsProcessing::ChannelConfig(
{.enable = VALUE_OR_RETURN(convertIntegral<bool>(enable)), .channel = channel});
}
@@ -257,14 +235,12 @@
AidlConversionDp::readEqBandConfigFromParam(EffectParamReader& param) {
DynamicsProcessing::EqBandConfig config;
int32_t enable;
- if (OK != param.readFromParameter(&config.channel) ||
- OK != param.readFromParameter(&config.band) ||
- OK != param.readFromValue(&enable) ||
- OK != param.readFromValue(&config.cutoffFrequencyHz) ||
- OK != param.readFromValue(&config.gainDb)) {
- ALOGE("%s invalid eq band param %s", __func__, param.toString().c_str());
- return ::android::base::unexpected(::android::BAD_VALUE);
- }
+ RETURN_IF_ERROR(param.readFromParameter(&config.channel));
+ RETURN_IF_ERROR(param.readFromParameter(&config.band));
+ RETURN_IF_ERROR(param.readFromValue(&enable));
+ RETURN_IF_ERROR(param.readFromValue(&config.cutoffFrequencyHz));
+ RETURN_IF_ERROR(param.readFromValue(&config.gainDb));
+
config.enable = VALUE_OR_RETURN(convertIntegral<bool>(enable));
return config;
}
@@ -273,22 +249,20 @@
AidlConversionDp::readMbcBandConfigFromParam(EffectParamReader& param) {
DynamicsProcessing::MbcBandConfig config;
int32_t enable;
- if (OK != param.readFromParameter(&config.channel) ||
- OK != param.readFromParameter(&config.band) ||
- OK != param.readFromValue(&enable) ||
- OK != param.readFromValue(&config.cutoffFrequencyHz) ||
- OK != param.readFromValue(&config.attackTimeMs) ||
- OK != param.readFromValue(&config.releaseTimeMs) ||
- OK != param.readFromValue(&config.ratio) ||
- OK != param.readFromValue(&config.thresholdDb) ||
- OK != param.readFromValue(&config.kneeWidthDb) ||
- OK != param.readFromValue(&config.noiseGateThresholdDb) ||
- OK != param.readFromValue(&config.expanderRatio) ||
- OK != param.readFromValue(&config.preGainDb) ||
- OK != param.readFromValue(&config.postGainDb)) {
- ALOGE("%s invalid mbc band config param %s", __func__, param.toString().c_str());
- return ::android::base::unexpected(::android::BAD_VALUE);
- }
+ RETURN_IF_ERROR(param.readFromParameter(&config.channel));
+ RETURN_IF_ERROR(param.readFromParameter(&config.band));
+ RETURN_IF_ERROR(param.readFromValue(&enable));
+ RETURN_IF_ERROR(param.readFromValue(&config.cutoffFrequencyHz));
+ RETURN_IF_ERROR(param.readFromValue(&config.attackTimeMs));
+ RETURN_IF_ERROR(param.readFromValue(&config.releaseTimeMs));
+ RETURN_IF_ERROR(param.readFromValue(&config.ratio));
+ RETURN_IF_ERROR(param.readFromValue(&config.thresholdDb));
+ RETURN_IF_ERROR(param.readFromValue(&config.kneeWidthDb));
+ RETURN_IF_ERROR(param.readFromValue(&config.noiseGateThresholdDb));
+ RETURN_IF_ERROR(param.readFromValue(&config.expanderRatio));
+ RETURN_IF_ERROR(param.readFromValue(&config.preGainDb));
+ RETURN_IF_ERROR(param.readFromValue(&config.postGainDb));
+
config.enable = VALUE_OR_RETURN(convertIntegral<bool>(enable));
return config;
}
@@ -297,18 +271,16 @@
AidlConversionDp::readLimiterConfigFromParam(EffectParamReader& param) {
DynamicsProcessing::LimiterConfig config;
int32_t enable, inUse;
- if (OK != param.readFromParameter(&config.channel) ||
- OK != param.readFromValue(&inUse) ||
- OK != param.readFromValue(&enable) ||
- OK != param.readFromValue(&config.linkGroup) ||
- OK != param.readFromValue(&config.attackTimeMs) ||
- OK != param.readFromValue(&config.releaseTimeMs) ||
- OK != param.readFromValue(&config.ratio) ||
- OK != param.readFromValue(&config.thresholdDb) ||
- OK != param.readFromValue(&config.postGainDb)) {
- ALOGE("%s invalid limiter config param %s", __func__, param.toString().c_str());
- return ::android::base::unexpected(::android::BAD_VALUE);
- }
+ RETURN_IF_ERROR(param.readFromParameter(&config.channel));
+ RETURN_IF_ERROR(param.readFromValue(&inUse));
+ RETURN_IF_ERROR(param.readFromValue(&enable));
+ RETURN_IF_ERROR(param.readFromValue(&config.linkGroup));
+ RETURN_IF_ERROR(param.readFromValue(&config.attackTimeMs));
+ RETURN_IF_ERROR(param.readFromValue(&config.releaseTimeMs));
+ RETURN_IF_ERROR(param.readFromValue(&config.ratio));
+ RETURN_IF_ERROR(param.readFromValue(&config.thresholdDb));
+ RETURN_IF_ERROR(param.readFromValue(&config.postGainDb));
+
config.enable = VALUE_OR_RETURN(convertIntegral<bool>(enable));
return config;
}
@@ -317,18 +289,15 @@
AidlConversionDp::readEngineArchitectureFromParam(EffectParamReader& param) {
DynamicsProcessing::EngineArchitecture engine;
int32_t variant, preEqInUse, mbcInUse, postEqInUse, limiterInUse;
- if (OK != param.readFromValue(&variant) &&
- OK != param.readFromValue(&engine.preferredProcessingDurationMs) &&
- OK != param.readFromValue(&preEqInUse) &&
- OK != param.readFromValue(&engine.preEqStage.bandCount) &&
- OK != param.readFromValue(&mbcInUse) &&
- OK != param.readFromValue(&engine.mbcStage.bandCount) &&
- OK != param.readFromValue(&postEqInUse) &&
- OK != param.readFromValue(&engine.postEqStage.bandCount) &&
- OK != param.readFromValue(&limiterInUse)) {
- ALOGE("%s invalid engineArchitecture %s", __func__, param.toString().c_str());
- return ::android::base::unexpected(::android::BAD_VALUE);
- }
+ RETURN_IF_ERROR(param.readFromValue(&variant));
+ RETURN_IF_ERROR(param.readFromValue(&engine.preferredProcessingDurationMs));
+ RETURN_IF_ERROR(param.readFromValue(&preEqInUse));
+ RETURN_IF_ERROR(param.readFromValue(&engine.preEqStage.bandCount));
+ RETURN_IF_ERROR(param.readFromValue(&mbcInUse));
+ RETURN_IF_ERROR(param.readFromValue(&engine.mbcStage.bandCount));
+ RETURN_IF_ERROR(param.readFromValue(&postEqInUse));
+ RETURN_IF_ERROR(param.readFromValue(&engine.postEqStage.bandCount));
+ RETURN_IF_ERROR(param.readFromValue(&limiterInUse));
engine.resolutionPreference = VALUE_OR_RETURN(
aidl::android::legacy2aidl_int32_DynamicsProcessing_ResolutionPreference(variant));
@@ -341,10 +310,7 @@
status_t AidlConversionDp::getChannelConfig(DynamicsProcessing::Tag tag, EffectParamWriter& param) {
int32_t channel;
- if (OK != param.readFromParameter(&channel)) {
- ALOGE("%s invalid parameter %s", __func__, param.toString().c_str());
- return BAD_VALUE;
- }
+ RETURN_STATUS_IF_ERROR(param.readFromParameter(&channel));
Parameter aidlParam;
Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(DynamicsProcessing, dynamicsProcessingTag, tag);
@@ -386,13 +352,9 @@
for (const auto& ch : channels) {
if (ch.channel == channel) {
int32_t enable = ch.enable;
- if (OK != param.writeToValue(&inUse) ||
- OK != param.writeToValue(&enable) ||
- OK != param.writeToValue(&bandCount)) {
- ALOGE("%s failed to write into param value %s", __func__,
- param.toString().c_str());
- return BAD_VALUE;
- }
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&inUse));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&enable));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&bandCount));
return OK;
}
}
@@ -402,10 +364,8 @@
status_t AidlConversionDp::getEqBandConfig(DynamicsProcessing::Tag tag, EffectParamWriter& param) {
int32_t channel, band;
- if (OK != param.readFromParameter(&channel) || OK != param.readFromParameter(&band)) {
- ALOGE("%s invalid parameter %s", __func__, param.toString().c_str());
- return BAD_VALUE;
- }
+ RETURN_STATUS_IF_ERROR(param.readFromParameter(&channel));
+ RETURN_STATUS_IF_ERROR(param.readFromParameter(&band));
Parameter aidlParam;
Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(DynamicsProcessing, dynamicsProcessingTag, tag);
@@ -427,12 +387,9 @@
for (const auto& bandIt : bands) {
if (bandIt.channel == channel && bandIt.band == band) {
int32_t enable = bandIt.enable;
- if (OK != param.writeToValue(&enable) ||
- OK != param.writeToValue(&bandIt.cutoffFrequencyHz) ||
- OK != param.writeToValue(&bandIt.gainDb)) {
- ALOGE("%s failed to write into param value %s", __func__, param.toString().c_str());
- return BAD_VALUE;
- }
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&enable));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&bandIt.cutoffFrequencyHz));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&bandIt.gainDb));
return OK;
}
}
@@ -442,10 +399,8 @@
status_t AidlConversionDp::getMbcBandConfig(EffectParamWriter& param) {
int32_t channel, band;
- if (OK != param.readFromParameter(&channel) || OK != param.readFromParameter(&band)) {
- ALOGE("%s invalid parameter %s", __func__, param.toString().c_str());
- return BAD_VALUE;
- }
+ RETURN_STATUS_IF_ERROR(param.readFromParameter(&channel));
+ RETURN_STATUS_IF_ERROR(param.readFromParameter(&band));
Parameter aidlParam;
Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(DynamicsProcessing, dynamicsProcessingTag,
DynamicsProcessing::mbcBand);
@@ -459,20 +414,17 @@
for (const auto& bandIt : bands) {
if (bandIt.channel == channel && bandIt.band == band) {
int32_t enable = bandIt.enable;
- if (OK != param.writeToValue(&enable) ||
- OK != param.writeToValue(&bandIt.cutoffFrequencyHz) ||
- OK != param.writeToValue(&bandIt.attackTimeMs) ||
- OK != param.writeToValue(&bandIt.releaseTimeMs) ||
- OK != param.writeToValue(&bandIt.ratio) ||
- OK != param.writeToValue(&bandIt.thresholdDb) ||
- OK != param.writeToValue(&bandIt.kneeWidthDb) ||
- OK != param.writeToValue(&bandIt.noiseGateThresholdDb) ||
- OK != param.writeToValue(&bandIt.expanderRatio) ||
- OK != param.writeToValue(&bandIt.preGainDb) ||
- OK != param.writeToValue(&bandIt.postGainDb)) {
- ALOGE("%s failed to write into param value %s", __func__, param.toString().c_str());
- return BAD_VALUE;
- }
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&enable));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&bandIt.cutoffFrequencyHz));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&bandIt.attackTimeMs));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&bandIt.releaseTimeMs));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&bandIt.ratio));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&bandIt.thresholdDb));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&bandIt.kneeWidthDb));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&bandIt.noiseGateThresholdDb));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&bandIt.expanderRatio));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&bandIt.preGainDb));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&bandIt.postGainDb));
return OK;
}
}
@@ -482,10 +434,7 @@
status_t AidlConversionDp::getLimiterConfig(EffectParamWriter& param) {
int32_t channel;
- if (OK != param.readFromParameter(&channel)) {
- ALOGE("%s invalid parameter %s", __func__, param.toString().c_str());
- return BAD_VALUE;
- }
+ RETURN_STATUS_IF_ERROR(param.readFromParameter(&channel));
Parameter aidlParam;
Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(DynamicsProcessing, dynamicsProcessingTag,
DynamicsProcessing::limiter);
@@ -500,17 +449,14 @@
if (config.channel == channel) {
int32_t inUse = mEngine.limiterInUse;
int32_t enable = config.enable;
- if (OK != param.writeToValue(&inUse) ||
- OK != param.writeToValue(&enable) ||
- OK != param.writeToValue(&config.linkGroup) ||
- OK != param.writeToValue(&config.attackTimeMs) ||
- OK != param.writeToValue(&config.releaseTimeMs) ||
- OK != param.writeToValue(&config.ratio) ||
- OK != param.writeToValue(&config.thresholdDb) ||
- OK != param.writeToValue(&config.postGainDb)) {
- ALOGE("%s failed to write into param value %s", __func__, param.toString().c_str());
- return BAD_VALUE;
- }
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&inUse));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&enable));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&config.linkGroup));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&config.attackTimeMs));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&config.releaseTimeMs));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&config.ratio));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&config.thresholdDb));
+ RETURN_STATUS_IF_ERROR(param.writeToValue(&config.postGainDb));
return OK;
}
}
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionEnvReverb.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionEnvReverb.cpp
index 960273b..49e41a4 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionEnvReverb.cpp
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionEnvReverb.cpp
@@ -39,161 +39,218 @@
using ::aidl::android::aidl_utils::statusTFromBinderStatus;
using ::aidl::android::hardware::audio::effect::EnvironmentalReverb;
using ::aidl::android::hardware::audio::effect::Parameter;
+using ::aidl::android::hardware::audio::effect::VendorExtension;
using ::android::status_t;
using utils::EffectParamReader;
using utils::EffectParamWriter;
-#define MAKE_AIDL_PARAMETER(aidlParam, param, value, tag) \
- { \
- if (OK != param.readFromValue(&value)) { \
- ALOGE("%s invalid parameter %s %d", __func__, #tag, value); \
- return BAD_VALUE; \
- } \
- aidlParam = MAKE_SPECIFIC_PARAMETER( \
- EnvironmentalReverb, environmentalReverb, tag, \
- VALUE_OR_RETURN_STATUS(aidl::android::convertIntegral<int>(value))); \
+/**
+ * Macro to get a parameter from effect_param_t wrapper and set it to AIDL effect.
+ *
+ * Return if there is any error, otherwise continue execution.
+ *
+ * @param param EffectParamReader, a reader wrapper of effect_param_t.
+ * @param aidlType Type of the AIDL parameter field, used to construct AIDL Parameter union.
+ * @param valueType Type of the value get from effect_param_t.
+ * @param tag The AIDL parameter union field tag.
+ */
+#define SET_AIDL_PARAMETER(param, aidlType, valueType, tag) \
+ { \
+ Parameter aidlParam; \
+ valueType value; \
+ if (status_t status = param.readFromValue(&value); status != OK) { \
+ ALOGE("%s %s read from parameter failed, ret %d", __func__, #tag, status); \
+ return status; \
+ } \
+ aidlParam = MAKE_SPECIFIC_PARAMETER( \
+ EnvironmentalReverb, environmentalReverb, tag, \
+ VALUE_OR_RETURN_STATUS(aidl::android::convertIntegral<aidlType>(value))); \
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->setParameter(aidlParam))); \
}
-#define GET_AIDL_PARAMETER(tag, value, param) \
+/**
+ * Macro to get a parameter from AIDL effect and write the value to effect_param_t with wrapper.
+ *
+ * Return if there is any error, otherwise continue execution.
+ *
+ * @param param EffectParamWriter, a writer wrapper of effect_param_t.
+ * @param aidlType Type of the AIDL parameter field, used to construct AIDL Parameter union.
+ * @param valueType Type of the value get from effect_param_t.
+ * @param tag The AIDL parameter union field tag.
+ */
+#define GET_AIDL_PARAMETER(param, aidltype, valueType, tag) \
{ \
+ aidltype value; \
Parameter aidlParam; \
Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(EnvironmentalReverb, environmentalReverbTag, \
EnvironmentalReverb::tag); \
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam))); \
- value = VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD( \
- aidlParam, EnvironmentalReverb, environmentalReverb, EnvironmentalReverb::tag, \
- std::decay_t<decltype(value)>)); \
- return param.writeToValue(&value); \
+ value = VALUE_OR_RETURN_STATUS( \
+ GET_PARAMETER_SPECIFIC_FIELD(aidlParam, EnvironmentalReverb, environmentalReverb, \
+ EnvironmentalReverb::tag, std::decay_t<aidltype>)); \
+ if (status_t status = param.writeToValue((valueType*)&value); status != OK) { \
+ param.setStatus(status); \
+ ALOGE("%s %s write to parameter failed %d, ret %d", __func__, #tag, value, status); \
+ return status; \
+ } \
}
status_t AidlConversionEnvReverb::setParameter(EffectParamReader& param) {
uint32_t type = 0;
- if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint16_t)) ||
- OK != param.readFromParameter(&type)) {
- ALOGE("%s invalid param %s", __func__, param.toString().c_str());
+ if (status_t status = param.readFromParameter(&type); status != OK) {
+ ALOGE("%s failed to read type from %s, ret %d", __func__, param.toString().c_str(), status);
return BAD_VALUE;
}
- Parameter aidlParam;
- uint16_t value16;
- uint32_t value32;
+
switch (type) {
case REVERB_PARAM_ROOM_LEVEL: {
- MAKE_AIDL_PARAMETER(aidlParam, param, value16, roomLevelMb);
+ SET_AIDL_PARAMETER(param, int32_t, int16_t, roomLevelMb);
break;
}
case REVERB_PARAM_ROOM_HF_LEVEL: {
- MAKE_AIDL_PARAMETER(aidlParam, param, value16, roomHfLevelMb);
+ SET_AIDL_PARAMETER(param, int32_t, int16_t, roomHfLevelMb);
break;
}
case REVERB_PARAM_DECAY_TIME: {
- MAKE_AIDL_PARAMETER(aidlParam, param, value32, decayTimeMs);
+ SET_AIDL_PARAMETER(param, int32_t, uint32_t, decayTimeMs);
break;
}
case REVERB_PARAM_DECAY_HF_RATIO: {
- MAKE_AIDL_PARAMETER(aidlParam, param, value16, decayHfRatioPm);
- break;
- }
- case REVERB_PARAM_REVERB_LEVEL: {
- MAKE_AIDL_PARAMETER(aidlParam, param, value16, levelMb);
- break;
- }
- case REVERB_PARAM_REVERB_DELAY: {
- MAKE_AIDL_PARAMETER(aidlParam, param, value32, delayMs);
- break;
- }
- case REVERB_PARAM_DIFFUSION: {
- MAKE_AIDL_PARAMETER(aidlParam, param, value16, diffusionPm);
- break;
- }
- case REVERB_PARAM_DENSITY: {
- MAKE_AIDL_PARAMETER(aidlParam, param, value16, densityPm);
- break;
- }
- case REVERB_PARAM_BYPASS: {
- if (OK != param.readFromValue(&value32)) {
- ALOGE("%s invalid bypass parameter %d", __func__, value32);
- return BAD_VALUE;
- }
- bool isByPass = VALUE_OR_RETURN_STATUS(aidl::android::convertIntegral<bool>(value32));
- aidlParam = MAKE_SPECIFIC_PARAMETER(EnvironmentalReverb, environmentalReverb, bypass,
- isByPass);
+ SET_AIDL_PARAMETER(param, int32_t, int16_t, decayHfRatioPm);
break;
}
case REVERB_PARAM_REFLECTIONS_LEVEL: {
- // TODO
+ SET_AIDL_PARAMETER(param, int32_t, int16_t, reflectionsLevelMb);
break;
}
case REVERB_PARAM_REFLECTIONS_DELAY: {
- // TODO
+ SET_AIDL_PARAMETER(param, int32_t, uint32_t, reflectionsDelayMs);
+ break;
+ }
+ case REVERB_PARAM_REVERB_LEVEL: {
+ SET_AIDL_PARAMETER(param, int32_t, int16_t, levelMb);
+ break;
+ }
+ case REVERB_PARAM_REVERB_DELAY: {
+ SET_AIDL_PARAMETER(param, int32_t, uint32_t, delayMs);
+ break;
+ }
+ case REVERB_PARAM_DIFFUSION: {
+ SET_AIDL_PARAMETER(param, int32_t, int16_t, diffusionPm);
+ break;
+ }
+ case REVERB_PARAM_DENSITY: {
+ SET_AIDL_PARAMETER(param, int32_t, int16_t, densityPm);
+ break;
+ }
+ case REVERB_PARAM_BYPASS: {
+ SET_AIDL_PARAMETER(param, bool, int32_t, bypass);
break;
}
case REVERB_PARAM_PROPERTIES: {
- // TODO
+ if (sizeof(t_reverb_settings) > param.getValueSize()) {
+ ALOGE("%s vsize %zu less than t_reverb_settings size %zu", __func__,
+ param.getValueSize(), sizeof(t_reverb_settings));
+ return BAD_VALUE;
+ }
+ // this sequency needs to be aligned with t_reverb_settings
+ SET_AIDL_PARAMETER(param, int32_t, int16_t, roomLevelMb);
+ SET_AIDL_PARAMETER(param, int32_t, int16_t, roomHfLevelMb);
+ SET_AIDL_PARAMETER(param, int32_t, uint32_t, decayTimeMs);
+ SET_AIDL_PARAMETER(param, int32_t, int16_t, decayHfRatioPm);
+ SET_AIDL_PARAMETER(param, int32_t, int16_t, reflectionsLevelMb);
+ SET_AIDL_PARAMETER(param, int32_t, uint32_t, reflectionsDelayMs);
+ SET_AIDL_PARAMETER(param, int32_t, int16_t, levelMb);
+ SET_AIDL_PARAMETER(param, int32_t, uint32_t, delayMs);
+ SET_AIDL_PARAMETER(param, int32_t, int16_t, diffusionPm);
+ SET_AIDL_PARAMETER(param, int32_t, int16_t, densityPm);
break;
}
default: {
- // TODO: handle with vendor extension
+ // for vendor extension, copy data area to the DefaultExtension, parameter ignored
+ VendorExtension ext = VALUE_OR_RETURN_STATUS(
+ aidl::android::legacy2aidl_EffectParameterReader_Data_VendorExtension(param));
+ Parameter aidlParam = MAKE_SPECIFIC_PARAMETER(EnvironmentalReverb,
+ environmentalReverb, vendor, ext);
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->setParameter(aidlParam)));
+ break;
}
}
- return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
+ return OK;
}
status_t AidlConversionEnvReverb::getParameter(EffectParamWriter& param) {
uint32_t type = 0;
- if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint32_t)) ||
- OK != param.readFromParameter(&type)) {
- ALOGE("%s invalid param %s", __func__, param.toString().c_str());
- param.setStatus(BAD_VALUE);
- return BAD_VALUE;
+ if (status_t status = param.readFromParameter(&type); status != OK) {
+ ALOGE("%s failed to read type from %s", __func__, param.toString().c_str());
+ param.setStatus(status);
+ return status;
}
- uint16_t value16;
- uint32_t value32;
+
switch (type) {
case REVERB_PARAM_ROOM_LEVEL: {
- GET_AIDL_PARAMETER(roomLevelMb, value16, param);
+ GET_AIDL_PARAMETER(param, int32_t, int16_t, roomLevelMb);
+ break;
}
case REVERB_PARAM_ROOM_HF_LEVEL: {
- GET_AIDL_PARAMETER(roomHfLevelMb, value16, param);
+ GET_AIDL_PARAMETER(param, int32_t, int16_t, roomHfLevelMb);
+ break;
}
case REVERB_PARAM_DECAY_TIME: {
- GET_AIDL_PARAMETER(decayTimeMs, value32, param);
+ GET_AIDL_PARAMETER(param, int32_t, uint32_t, decayTimeMs);
+ break;
}
case REVERB_PARAM_DECAY_HF_RATIO: {
- GET_AIDL_PARAMETER(decayHfRatioPm, value16, param);
- }
- case REVERB_PARAM_REVERB_LEVEL: {
- GET_AIDL_PARAMETER(levelMb, value16, param);
- }
- case REVERB_PARAM_REVERB_DELAY: {
- GET_AIDL_PARAMETER(delayMs, value32, param);
- }
- case REVERB_PARAM_DIFFUSION: {
- GET_AIDL_PARAMETER(diffusionPm, value16, param);
- }
- case REVERB_PARAM_DENSITY: {
- GET_AIDL_PARAMETER(densityPm, value16, param);
- }
- case REVERB_PARAM_BYPASS: {
- bool isByPass;
- GET_AIDL_PARAMETER(bypass, isByPass, param);
+ GET_AIDL_PARAMETER(param, int32_t, int16_t, decayHfRatioPm);
+ break;
}
case REVERB_PARAM_REFLECTIONS_LEVEL: {
- // TODO
+ GET_AIDL_PARAMETER(param, int32_t, int16_t, reflectionsLevelMb);
break;
}
case REVERB_PARAM_REFLECTIONS_DELAY: {
- // TODO
+ GET_AIDL_PARAMETER(param, int32_t, uint32_t, reflectionsDelayMs);
+ break;
+ }
+ case REVERB_PARAM_REVERB_LEVEL: {
+ GET_AIDL_PARAMETER(param, int32_t, int16_t, levelMb);
+ break;
+ }
+ case REVERB_PARAM_REVERB_DELAY: {
+ GET_AIDL_PARAMETER(param, int32_t, uint32_t, delayMs);
+ break;
+ }
+ case REVERB_PARAM_DIFFUSION: {
+ GET_AIDL_PARAMETER(param, int32_t, int16_t, diffusionPm);
+ break;
+ }
+ case REVERB_PARAM_DENSITY: {
+ GET_AIDL_PARAMETER(param, int32_t, int16_t, densityPm);
+ break;
+ }
+ case REVERB_PARAM_BYPASS: {
+ GET_AIDL_PARAMETER(param, bool, int32_t, bypass);
break;
}
case REVERB_PARAM_PROPERTIES: {
- // TODO
+ // this sequency needs to be aligned with t_reverb_settings
+ GET_AIDL_PARAMETER(param, int32_t, int16_t, roomLevelMb);
+ GET_AIDL_PARAMETER(param, int32_t, int16_t, roomHfLevelMb);
+ GET_AIDL_PARAMETER(param, int32_t, uint32_t, decayTimeMs);
+ GET_AIDL_PARAMETER(param, int32_t, int16_t, decayHfRatioPm);
+ GET_AIDL_PARAMETER(param, int32_t, int16_t, reflectionsLevelMb);
+ GET_AIDL_PARAMETER(param, int32_t, uint32_t, reflectionsDelayMs);
+ GET_AIDL_PARAMETER(param, int32_t, int16_t, levelMb);
+ GET_AIDL_PARAMETER(param, int32_t, uint32_t, delayMs);
+ GET_AIDL_PARAMETER(param, int32_t, int16_t, diffusionPm);
+ GET_AIDL_PARAMETER(param, int32_t, int16_t, densityPm);
break;
}
default: {
- // TODO: handle with vendor extension
+ VENDOR_EXTENSION_GET_AND_RETURN(EnvironmentalReverb, environmentalReverb, param);
}
}
- return BAD_VALUE;
+ return OK;
}
} // namespace effect
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionEq.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionEq.cpp
index a10d271..f1c2926 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionEq.cpp
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionEq.cpp
@@ -37,16 +37,16 @@
using ::aidl::android::aidl_utils::statusTFromBinderStatus;
using ::aidl::android::hardware::audio::effect::Equalizer;
using ::aidl::android::hardware::audio::effect::Parameter;
+using ::aidl::android::hardware::audio::effect::Range;
+using ::aidl::android::hardware::audio::effect::VendorExtension;
+using ::android::base::unexpected;
using ::android::status_t;
using utils::EffectParamReader;
using utils::EffectParamWriter;
status_t AidlConversionEq::setParameter(EffectParamReader& param) {
uint32_t type;
- uint16_t value = 0;
- if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint32_t)) ||
- OK != param.readFromParameter(&type) ||
- OK != param.readFromValue(&value)) {
+ if (OK != param.readFromParameter(&type)) {
ALOGE("%s invalid param %s", __func__, param.toString().c_str());
return BAD_VALUE;
}
@@ -54,13 +54,18 @@
Parameter aidlParam;
switch (type) {
case EQ_PARAM_CUR_PRESET: {
+ uint16_t value = 0;
+ if (OK != param.readFromValue(&value)) {
+ ALOGE("%s invalid param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
aidlParam = MAKE_SPECIFIC_PARAMETER(Equalizer, equalizer, preset, (int)value);
break;
}
case EQ_PARAM_BAND_LEVEL: {
int32_t band;
- uint16_t level;
- if (OK != param.readFromParameter(&band) || OK != param.readFromParameter(&level)) {
+ int16_t level;
+ if (OK != param.readFromParameter(&band) || OK != param.readFromValue(&level)) {
ALOGE("%s invalid bandLevel param %s", __func__, param.toString().c_str());
return BAD_VALUE;
}
@@ -69,13 +74,39 @@
break;
}
case EQ_PARAM_PROPERTIES: {
- // TODO: handle properties setting
+ int16_t num;
+ if (OK != param.readFromValue(&num)) {
+ ALOGE("%s invalid param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ // set preset if it's valid
+ if (num >= 0) {
+ aidlParam = MAKE_SPECIFIC_PARAMETER(Equalizer, equalizer, preset, (int)num);
+ break;
+ }
+ // set bandLevel if no preset was set
+ if (OK != param.readFromValue(&num)) {
+ ALOGE("%s invalid param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ std::vector<Equalizer::BandLevel> bandLevels;
+ for (int i = 0; i < num; i++) {
+ Equalizer::BandLevel level({.index = i});
+ if (OK != param.readFromValue((uint16_t*)&level.levelMb)) {
+ ALOGE("%s invalid param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ bandLevels.push_back(level);
+ }
+ aidlParam = MAKE_SPECIFIC_PARAMETER(Equalizer, equalizer, bandLevels, bandLevels);
break;
}
default: {
- // TODO: implement vendor extension parameters
- ALOGW("%s unknown param %s", __func__, param.toString().c_str());
- return BAD_VALUE;
+ // for vendor extension, copy data area to the DefaultExtension, parameter ignored
+ VendorExtension ext = VALUE_OR_RETURN_STATUS(
+ aidl::android::legacy2aidl_EffectParameterReader_Data_VendorExtension(param));
+ aidlParam = MAKE_SPECIFIC_PARAMETER(Equalizer, equalizer, vendor, ext);
+ break;
}
}
@@ -89,29 +120,187 @@
return aidlParam;
}
+aidl::ConversionResult<int32_t> AidlConversionEq::getParameterPreset() {
+ Parameter aidlParam = VALUE_OR_RETURN_STATUS(getAidlParameter(Equalizer::preset));
+ return VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(aidlParam, Equalizer, equalizer,
+ Equalizer::preset, int32_t));
+}
+
+aidl::ConversionResult<std::string> AidlConversionEq::getParameterPresetName(
+ EffectParamWriter& param) {
+ int32_t presetIdx;
+ if (OK != param.readFromParameter(&presetIdx)) {
+ ALOGE("%s invalid param %s", __func__, param.toString().c_str());
+ return unexpected(BAD_VALUE);
+ }
+ Parameter aidlParam = VALUE_OR_RETURN(getAidlParameter(Equalizer::presets));
+ const auto& presets = VALUE_OR_RETURN(GET_PARAMETER_SPECIFIC_FIELD(
+ aidlParam, Equalizer, equalizer, Equalizer::presets, std::vector<Equalizer::Preset>));
+ for (const auto& preset : presets) {
+ if (presetIdx == preset.index) {
+ return preset.name;
+ }
+ }
+ return unexpected(BAD_VALUE);
+}
+
status_t AidlConversionEq::getParameter(EffectParamWriter& param) {
- uint32_t type = 0, value = 0;
- if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint32_t)) ||
- OK != param.readFromParameter(&type)) {
+ uint32_t type = 0;
+ if (OK != param.readFromParameter(&type)) {
param.setStatus(BAD_VALUE);
ALOGE("%s invalid param %s", __func__, param.toString().c_str());
return BAD_VALUE;
}
- Parameter aidlParam;
+
switch (type) {
case EQ_PARAM_NUM_BANDS: {
- aidlParam = VALUE_OR_RETURN_STATUS(getAidlParameter(Equalizer::bandLevels));
- auto bandLevels = VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(
+ Parameter aidlParam = VALUE_OR_RETURN_STATUS(getAidlParameter(Equalizer::bandLevels));
+ const auto& bandLevels = VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(
aidlParam, Equalizer, equalizer, Equalizer::bandLevels,
std::vector<Equalizer::BandLevel>));
- uint32_t num = bandLevels.size();
+ uint16_t bands = bandLevels.size();
+ return param.writeToValue(&bands);
+ }
+ case EQ_PARAM_LEVEL_RANGE: {
+ const auto& ranges = mDesc.capability.range.get<Range::equalizer>();
+ for (const auto& r : ranges) {
+ if (r.min.getTag() == Equalizer::bandLevels &&
+ r.max.getTag() == Equalizer::bandLevels) {
+ const auto& aidlMin = r.min.get<Equalizer::bandLevels>();
+ const auto& aidlMax = r.max.get<Equalizer::bandLevels>();
+ int16_t min =
+ std::min_element(aidlMin.begin(), aidlMin.end(), [](auto& a, auto& b) {
+ return a.levelMb < b.levelMb;
+ })->levelMb;
+ int16_t max =
+ std::max_element(aidlMax.begin(), aidlMax.end(), [](auto& a, auto& b) {
+ return a.levelMb < b.levelMb;
+ })->levelMb;
+ return (OK == param.writeToValue(&min) && OK == param.writeToValue(&max))
+ ? OK
+ : BAD_VALUE;
+ }
+ }
+ break;
+ }
+ case EQ_PARAM_BAND_LEVEL: {
+ int32_t bandIdx;
+ if (OK != param.readFromParameter(&bandIdx)) {
+ break;
+ }
+
+ Parameter aidlParam = VALUE_OR_RETURN_STATUS(getAidlParameter(Equalizer::bandLevels));
+ const auto& bandLevels = VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(
+ aidlParam, Equalizer, equalizer, Equalizer::bandLevels,
+ std::vector<Equalizer::BandLevel>));
+ for (const auto& band : bandLevels) {
+ if (band.index == bandIdx) {
+ return param.writeToValue((uint16_t *)&band.levelMb);
+ }
+ }
+ break;
+ }
+ case EQ_PARAM_CENTER_FREQ: {
+ int32_t index;
+ if (OK != param.readFromParameter(&index)) {
+ break;
+ }
+
+ Parameter aidlParam = VALUE_OR_RETURN_STATUS(getAidlParameter(Equalizer::centerFreqMh));
+ const auto& freqs = VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(
+ aidlParam, Equalizer, equalizer, Equalizer::centerFreqMh, std::vector<int>));
+ if ((size_t)index >= freqs.size()) {
+ ALOGE("%s index %d exceed size %zu", __func__, index, freqs.size());
+ break;
+ }
+ return param.writeToValue(&freqs[index]);
+ }
+ case EQ_PARAM_BAND_FREQ_RANGE: {
+ int32_t index;
+ if (OK != param.readFromParameter(&index)) {
+ break;
+ }
+
+ Parameter aidlParam =
+ VALUE_OR_RETURN_STATUS(getAidlParameter(Equalizer::bandFrequencies));
+ const auto& bands = VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(
+ aidlParam, Equalizer, equalizer, Equalizer::bandFrequencies,
+ std::vector<Equalizer::BandFrequency>));
+ for (const auto& band : bands) {
+ if (band.index == index) {
+ return (OK == param.writeToValue(&band.minMh) &&
+ OK == param.writeToValue(&band.maxMh))
+ ? OK
+ : BAD_VALUE;
+ }
+ }
+ break;
+ }
+ case EQ_PARAM_GET_BAND: {
+ int32_t freq;
+ if (OK != param.readFromParameter(&freq)) {
+ break;
+ }
+
+ Parameter aidlParam =
+ VALUE_OR_RETURN_STATUS(getAidlParameter(Equalizer::bandFrequencies));
+ const auto& bands = VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(
+ aidlParam, Equalizer, equalizer, Equalizer::bandFrequencies,
+ std::vector<Equalizer::BandFrequency>));
+ for (const auto& band : bands) {
+ if (freq >= band.minMh && freq <= band.maxMh) {
+ return param.writeToValue((uint16_t*)&band.index);
+ }
+ }
+ break;
+ }
+ case EQ_PARAM_CUR_PRESET: {
+ int32_t preset = VALUE_OR_RETURN_STATUS(getParameterPreset());
+ return param.writeToValue((uint16_t*)&preset);
+ }
+ case EQ_PARAM_GET_NUM_OF_PRESETS: {
+ Parameter aidlParam = VALUE_OR_RETURN_STATUS(getAidlParameter(Equalizer::presets));
+ const auto& presets = VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(
+ aidlParam, Equalizer, equalizer, Equalizer::presets,
+ std::vector<Equalizer::Preset>));
+ uint16_t num = presets.size();
return param.writeToValue(&num);
}
- default:
- ALOGW("%s unknown param %s", __func__, param.toString().c_str());
- return BAD_VALUE;
+ case EQ_PARAM_GET_PRESET_NAME: {
+ std::string name = VALUE_OR_RETURN_STATUS(getParameterPresetName(param));
+ return param.writeToValue(name.c_str(), name.length());
+ }
+ case EQ_PARAM_PROPERTIES: {
+ int32_t preset = VALUE_OR_RETURN_STATUS(getParameterPreset());
+ if (OK != param.writeToValue((uint16_t*)&preset)) {
+ break;
+ }
+ Parameter aidlParam = VALUE_OR_RETURN_STATUS(getAidlParameter(Equalizer::bandLevels));
+ std::vector<Equalizer::BandLevel> bandLevels =
+ VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(
+ aidlParam, Equalizer, equalizer, Equalizer::bandLevels,
+ std::vector<Equalizer::BandLevel>));
+ uint16_t bands = bandLevels.size();
+ if (OK != param.writeToValue(&bands)) {
+ break;
+ }
+ std::sort(bandLevels.begin(), bandLevels.end(),
+ [](const auto& a, const auto& b) { return a.index < b.index; });
+ for (const auto& level : bandLevels) {
+ if (status_t status = param.writeToValue((uint16_t*)&level.levelMb); status != OK) {
+ return status;
+ }
+ }
+ return OK;
+ }
+ default: {
+ VENDOR_EXTENSION_GET_AND_RETURN(Equalizer, equalizer, param);
+ }
}
- return param.writeToValue(&value);
+
+ param.setStatus(BAD_VALUE);
+ ALOGE("%s invalid param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
}
} // namespace effect
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionEq.h b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionEq.h
index 0433965..2509c20 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionEq.h
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionEq.h
@@ -35,6 +35,8 @@
status_t getParameter(utils::EffectParamWriter& param) override;
aidl::ConversionResult<::aidl::android::hardware::audio::effect::Parameter> getAidlParameter(
::aidl::android::hardware::audio::effect::Equalizer::Tag tag);
+ aidl::ConversionResult<int32_t> getParameterPreset();
+ aidl::ConversionResult<std::string> getParameterPresetName(utils::EffectParamWriter& param);
};
} // namespace effect
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionHapticGenerator.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionHapticGenerator.cpp
index 814b58f..763e197 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionHapticGenerator.cpp
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionHapticGenerator.cpp
@@ -33,35 +33,65 @@
namespace android {
namespace effect {
+using ::aidl::android::getParameterSpecificField;
using ::aidl::android::aidl_utils::statusTFromBinderStatus;
+using ::aidl::android::hardware::audio::effect::HapticGenerator;
using ::aidl::android::hardware::audio::effect::Parameter;
+using ::aidl::android::hardware::audio::effect::VendorExtension;
using ::android::status_t;
using utils::EffectParamReader;
using utils::EffectParamWriter;
status_t AidlConversionHapticGenerator::setParameter(EffectParamReader& param) {
uint32_t type = 0;
- uint16_t value = 0;
if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint16_t)) ||
- OK != param.readFromParameter(&type) || OK != param.readFromValue(&value)) {
+ OK != param.readFromParameter(&type)) {
ALOGE("%s invalid param %s", __func__, param.toString().c_str());
return BAD_VALUE;
}
Parameter aidlParam;
- // TODO
+ switch (type) {
+ case HG_PARAM_HAPTIC_INTENSITY: {
+ int32_t id = 0, scale;
+ if (OK != param.readFromValue(&id) || OK != param.readFromValue(&scale)) {
+ ALOGE("%s invalid intensity %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ HapticGenerator::HapticScale hpScale(
+ {.id = id, .scale = (HapticGenerator::VibratorScale)(scale)});
+ aidlParam = MAKE_SPECIFIC_PARAMETER(HapticGenerator, hapticGenerator, hapticScales,
+ {hpScale});
+ break;
+ }
+ case HG_PARAM_VIBRATOR_INFO: {
+ float resonantFrequencyHz, qFactor, maxAmplitude;
+ if (OK != param.readFromValue(&resonantFrequencyHz) ||
+ OK != param.readFromValue(&qFactor) || OK != param.readFromValue(&maxAmplitude)) {
+ ALOGE("%s invalid vibrator info %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ HapticGenerator::VibratorInformation info({.resonantFrequencyHz = resonantFrequencyHz,
+ .qFactor = qFactor,
+ .maxAmplitude = maxAmplitude});
+ aidlParam =
+ MAKE_SPECIFIC_PARAMETER(HapticGenerator, hapticGenerator, vibratorInfo, info);
+ break;
+ }
+ default: {
+ // for vendor extension, copy data area to the DefaultExtension, parameter ignored
+ VendorExtension ext = VALUE_OR_RETURN_STATUS(
+ aidl::android::legacy2aidl_EffectParameterReader_Data_VendorExtension(param));
+ aidlParam = MAKE_SPECIFIC_PARAMETER(HapticGenerator, hapticGenerator, vendor, ext);
+ break;
+ }
+ }
+
return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
}
+// No parameter to get for HapticGenerator
status_t AidlConversionHapticGenerator::getParameter(EffectParamWriter& param) {
- uint32_t type = 0, value = 0;
- if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint32_t)) ||
- OK != param.readFromParameter(&type)) {
- ALOGE("%s invalid param %s", __func__, param.toString().c_str());
- param.setStatus(BAD_VALUE);
- return BAD_VALUE;
- }
- // TODO
- return param.writeToValue(&value);
+ VENDOR_EXTENSION_GET_AND_RETURN(HapticGenerator, hapticGenerator, param);
}
} // namespace effect
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionLoudnessEnhancer.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionLoudnessEnhancer.cpp
index 70e0428..fa74a79 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionLoudnessEnhancer.cpp
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionLoudnessEnhancer.cpp
@@ -34,34 +34,62 @@
namespace effect {
using ::aidl::android::aidl_utils::statusTFromBinderStatus;
+using ::aidl::android::getParameterSpecificField;
+using ::aidl::android::hardware::audio::effect::LoudnessEnhancer;
using ::aidl::android::hardware::audio::effect::Parameter;
+using ::aidl::android::hardware::audio::effect::VendorExtension;
using ::android::status_t;
using utils::EffectParamReader;
using utils::EffectParamWriter;
status_t AidlConversionLoudnessEnhancer::setParameter(EffectParamReader& param) {
uint32_t type = 0;
- uint16_t value = 0;
+ int32_t gain = 0;
if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint16_t)) ||
- OK != param.readFromParameter(&type) || OK != param.readFromValue(&value)) {
+ OK != param.readFromParameter(&type) || OK != param.readFromValue(&gain)) {
ALOGE("%s invalid param %s", __func__, param.toString().c_str());
return BAD_VALUE;
}
Parameter aidlParam;
- // TODO
+ switch (type) {
+ case LOUDNESS_ENHANCER_PARAM_TARGET_GAIN_MB: {
+ aidlParam = MAKE_SPECIFIC_PARAMETER(LoudnessEnhancer, loudnessEnhancer, gainMb, gain);
+ break;
+ }
+ default: {
+ // for vendor extension, copy data area to the DefaultExtension, parameter ignored
+ VendorExtension ext = VALUE_OR_RETURN_STATUS(
+ aidl::android::legacy2aidl_EffectParameterReader_Data_VendorExtension(param));
+ aidlParam = MAKE_SPECIFIC_PARAMETER(LoudnessEnhancer, loudnessEnhancer, vendor, ext);
+ break;
+ }
+ }
return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
}
status_t AidlConversionLoudnessEnhancer::getParameter(EffectParamWriter& param) {
- uint32_t type = 0, value = 0;
+ uint32_t type = 0;
if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint32_t)) ||
OK != param.readFromParameter(&type)) {
ALOGE("%s invalid param %s", __func__, param.toString().c_str());
param.setStatus(BAD_VALUE);
return BAD_VALUE;
}
- // TODO
- return param.writeToValue(&value);
+ switch (type) {
+ case LOUDNESS_ENHANCER_PARAM_TARGET_GAIN_MB: {
+ Parameter aidlParam;
+ Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(LoudnessEnhancer, loudnessEnhancerTag,
+ LoudnessEnhancer::gainMb);
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+ int32_t gain = VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(
+ aidlParam, LoudnessEnhancer, loudnessEnhancer, LoudnessEnhancer::gainMb,
+ std::decay_t<decltype(gain)>));
+ return param.writeToValue(&gain);
+ }
+ default: {
+ VENDOR_EXTENSION_GET_AND_RETURN(LoudnessEnhancer, loudnessEnhancer, param);
+ }
+ }
}
} // namespace effect
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionNoiseSuppression.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionNoiseSuppression.cpp
index 5faf645..3d75e48 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionNoiseSuppression.cpp
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionNoiseSuppression.cpp
@@ -33,34 +33,79 @@
namespace android {
namespace effect {
+using ::aidl::android::getParameterSpecificField;
using ::aidl::android::aidl_utils::statusTFromBinderStatus;
+using ::aidl::android::hardware::audio::effect::NoiseSuppression;
using ::aidl::android::hardware::audio::effect::Parameter;
+using ::aidl::android::hardware::audio::effect::VendorExtension;
using ::android::status_t;
using utils::EffectParamReader;
using utils::EffectParamWriter;
status_t AidlConversionNoiseSuppression::setParameter(EffectParamReader& param) {
- uint32_t type = 0;
- uint16_t value = 0;
+ uint32_t type = 0, value = 0;
if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint16_t)) ||
OK != param.readFromParameter(&type) || OK != param.readFromValue(&value)) {
ALOGE("%s invalid param %s", __func__, param.toString().c_str());
return BAD_VALUE;
}
Parameter aidlParam;
- // TODO
+ switch (type) {
+ case NS_PARAM_LEVEL: {
+ aidlParam = MAKE_SPECIFIC_PARAMETER(NoiseSuppression, noiseSuppression, level,
+ static_cast<NoiseSuppression::Level>(value));
+ break;
+ }
+ case NS_PARAM_TYPE: {
+ aidlParam = MAKE_SPECIFIC_PARAMETER(NoiseSuppression, noiseSuppression, type,
+ static_cast<NoiseSuppression::Type>(value));
+ break;
+ }
+ default: {
+ // for vendor extension, copy data area to the DefaultExtension, parameter ignored
+ VendorExtension ext = VALUE_OR_RETURN_STATUS(
+ aidl::android::legacy2aidl_EffectParameterReader_Data_VendorExtension(param));
+ aidlParam = MAKE_SPECIFIC_PARAMETER(NoiseSuppression, noiseSuppression, vendor, ext);
+ break;
+ }
+ }
return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
}
status_t AidlConversionNoiseSuppression::getParameter(EffectParamWriter& param) {
- uint32_t type = 0, value = 0;
+ uint32_t paramType = 0, value = 0;
if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint32_t)) ||
- OK != param.readFromParameter(&type)) {
+ OK != param.readFromParameter(¶mType)) {
ALOGE("%s invalid param %s", __func__, param.toString().c_str());
param.setStatus(BAD_VALUE);
return BAD_VALUE;
}
- // TODO
+ Parameter aidlParam;
+ switch (paramType) {
+ case NS_PARAM_LEVEL: {
+ Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(NoiseSuppression, noiseSuppressionTag,
+ NoiseSuppression::level);
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+ NoiseSuppression::Level level = VALUE_OR_RETURN_STATUS(
+ GET_PARAMETER_SPECIFIC_FIELD(aidlParam, NoiseSuppression, noiseSuppression,
+ NoiseSuppression::level, NoiseSuppression::Level));
+ value = static_cast<uint32_t>(level);
+ break;
+ }
+ case NS_PARAM_TYPE: {
+ Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(NoiseSuppression, noiseSuppressionTag,
+ NoiseSuppression::type);
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+ NoiseSuppression::Type nsType = VALUE_OR_RETURN_STATUS(
+ GET_PARAMETER_SPECIFIC_FIELD(aidlParam, NoiseSuppression, noiseSuppression,
+ NoiseSuppression::type, NoiseSuppression::Type));
+ value = static_cast<uint32_t>(nsType);
+ break;
+ }
+ default: {
+ VENDOR_EXTENSION_GET_AND_RETURN(NoiseSuppression, noiseSuppression, param);
+ }
+ }
return param.writeToValue(&value);
}
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionPresetReverb.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionPresetReverb.cpp
index 3e9bf4b..f04c118 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionPresetReverb.cpp
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionPresetReverb.cpp
@@ -38,6 +38,7 @@
using ::aidl::android::aidl_utils::statusTFromBinderStatus;
using ::aidl::android::hardware::audio::effect::Parameter;
using ::aidl::android::hardware::audio::effect::PresetReverb;
+using ::aidl::android::hardware::audio::effect::VendorExtension;
using ::android::status_t;
using utils::EffectParamReader;
using utils::EffectParamWriter;
@@ -59,7 +60,10 @@
aidlParam = MAKE_SPECIFIC_PARAMETER(PresetReverb, presetReverb, preset,
static_cast<PresetReverb::Presets>(value));
} else {
- // handle vendor extension
+ // for vendor extension, copy data area to the DefaultExtension, parameter ignored
+ VendorExtension ext = VALUE_OR_RETURN_STATUS(
+ aidl::android::legacy2aidl_EffectParameterReader_Data_VendorExtension(param));
+ aidlParam = MAKE_SPECIFIC_PARAMETER(PresetReverb, presetReverb, vendor, ext);
}
return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
@@ -86,6 +90,7 @@
value = static_cast<uint16_t>(aidlPreset);
} else {
// handle vendor extension
+ VENDOR_EXTENSION_GET_AND_RETURN(PresetReverb, presetReverb, param);
}
return param.writeToValue(&value);
}
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionSpatializer.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionSpatializer.cpp
index 1dac479..9a759d2 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionSpatializer.cpp
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionSpatializer.cpp
@@ -20,6 +20,8 @@
#define LOG_TAG "AidlConversionSpatializer"
//#define LOG_NDEBUG 0
+#include <aidl/android/hardware/audio/effect/DefaultExtension.h>
+#include <aidl/android/hardware/audio/effect/VendorExtension.h>
#include <error/expected_utils.h>
#include <media/AidlConversionNdk.h>
#include <media/AidlConversionEffect.h>
@@ -34,34 +36,37 @@
namespace effect {
using ::aidl::android::aidl_utils::statusTFromBinderStatus;
+using ::aidl::android::hardware::audio::effect::DefaultExtension;
using ::aidl::android::hardware::audio::effect::Parameter;
+using ::aidl::android::hardware::audio::effect::VendorExtension;
using ::android::status_t;
using utils::EffectParamReader;
using utils::EffectParamWriter;
status_t AidlConversionSpatializer::setParameter(EffectParamReader& param) {
- uint32_t type = 0;
- uint16_t value = 0;
- if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint16_t)) ||
- OK != param.readFromParameter(&type) || OK != param.readFromValue(&value)) {
- ALOGE("%s invalid param %s", __func__, param.toString().c_str());
- return BAD_VALUE;
- }
- Parameter aidlParam;
- // TODO
+ Parameter aidlParam = VALUE_OR_RETURN_STATUS(
+ ::aidl::android::legacy2aidl_EffectParameterReader_ParameterExtension(param));
return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
}
status_t AidlConversionSpatializer::getParameter(EffectParamWriter& param) {
- uint32_t type = 0, value = 0;
- if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint32_t)) ||
- OK != param.readFromParameter(&type)) {
+ DefaultExtension defaultExt;
+ // read parameters into DefaultExtension vector<uint8_t>
+ if (OK != param.readFromParameter(defaultExt.bytes.data(), param.getParameterSize())) {
ALOGE("%s invalid param %s", __func__, param.toString().c_str());
param.setStatus(BAD_VALUE);
return BAD_VALUE;
}
- // TODO
- return param.writeToValue(&value);
+
+ VendorExtension idTag;
+ idTag.extension.setParcelable(defaultExt);
+ Parameter::Id id = UNION_MAKE(Parameter::Id, vendorEffectTag, idTag);
+ Parameter aidlParam;
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+ // copy the AIDL extension data back to effect_param_t
+ return VALUE_OR_RETURN_STATUS(
+ ::aidl::android::aidl2legacy_ParameterExtension_EffectParameterWriter(aidlParam,
+ param));
}
} // namespace effect
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVendorExtension.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVendorExtension.cpp
index a035614..488d5cd 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVendorExtension.cpp
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVendorExtension.cpp
@@ -17,9 +17,12 @@
#include <cstdint>
#include <cstring>
#include <optional>
+#include <type_traits>
#define LOG_TAG "AidlConversionVendorExtension"
//#define LOG_NDEBUG 0
+#include <aidl/android/hardware/audio/effect/DefaultExtension.h>
+#include <aidl/android/hardware/audio/effect/VendorExtension.h>
#include <error/expected_utils.h>
#include <media/AidlConversionNdk.h>
#include <media/AidlConversionEffect.h>
@@ -32,34 +35,37 @@
namespace effect {
using ::aidl::android::aidl_utils::statusTFromBinderStatus;
+using ::aidl::android::hardware::audio::effect::DefaultExtension;
using ::aidl::android::hardware::audio::effect::Parameter;
+using ::aidl::android::hardware::audio::effect::VendorExtension;
using ::android::status_t;
using utils::EffectParamReader;
using utils::EffectParamWriter;
+/**
+ * For all effect types we currently don't support, add a default extension implementation to use
+ * std::vector<uint8_t> to pass through all data in the format of effect_param_t (the data we got
+ * from libaudioclient for now).
+ * This logic will be removed after we adopt to same AIDL parameter union AIDL in libaudioclient,
+ * after that framework doesn't need to do any AIDL conversion, and the vendor extension can be
+ * pass down in Parameter as is.
+ */
status_t AidlConversionVendorExtension::setParameter(EffectParamReader& param) {
- uint32_t type = 0;
- uint16_t value = 0;
- if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint16_t)) ||
- OK != param.readFromParameter(&type) || OK != param.readFromValue(&value)) {
- ALOGE("%s invalid param %s", __func__, param.toString().c_str());
- return BAD_VALUE;
- }
- Parameter aidlParam;
- // TODO
+ Parameter aidlParam = VALUE_OR_RETURN_STATUS(
+ ::aidl::android::legacy2aidl_EffectParameterReader_ParameterExtension(param));
return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
}
status_t AidlConversionVendorExtension::getParameter(EffectParamWriter& param) {
- uint32_t type = 0, value = 0;
- if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint32_t)) ||
- OK != param.readFromParameter(&type)) {
- ALOGE("%s invalid param %s", __func__, param.toString().c_str());
- param.setStatus(BAD_VALUE);
- return BAD_VALUE;
- }
- // TODO
- return param.writeToValue(&value);
+ VendorExtension extId = VALUE_OR_RETURN_STATUS(
+ aidl::android::legacy2aidl_EffectParameterReader_Param_VendorExtension(param));
+ Parameter::Id id = UNION_MAKE(Parameter::Id, vendorEffectTag, extId);
+ Parameter aidlParam;
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+ // copy the AIDL extension data back to effect_param_t
+ return VALUE_OR_RETURN_STATUS(
+ ::aidl::android::aidl2legacy_ParameterExtension_EffectParameterWriter(aidlParam,
+ param));
}
} // namespace effect
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVirtualizer.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVirtualizer.cpp
index 482114d..b34904b 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVirtualizer.cpp
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVirtualizer.cpp
@@ -21,10 +21,12 @@
//#define LOG_NDEBUG 0
#include <error/expected_utils.h>
+#include <media/AidlConversionCppNdk.h>
#include <media/AidlConversionNdk.h>
#include <media/AidlConversionEffect.h>
#include <media/audiohal/AudioEffectUuid.h>
-#include <system/audio_effects/effect_spatializer.h>
+#include <system/audio_effects/aidl_effects_utils.h>
+#include <system/audio_effects/effect_virtualizer.h>
#include <utils/Log.h>
@@ -34,34 +36,129 @@
namespace effect {
using ::aidl::android::aidl_utils::statusTFromBinderStatus;
+using ::aidl::android::getParameterSpecificField;
using ::aidl::android::hardware::audio::effect::Parameter;
+using ::aidl::android::hardware::audio::effect::Range;
+using ::aidl::android::hardware::audio::effect::Virtualizer;
+using ::aidl::android::hardware::audio::effect::VendorExtension;
+using ::aidl::android::media::audio::common::AudioDeviceDescription;
using ::android::status_t;
using utils::EffectParamReader;
using utils::EffectParamWriter;
status_t AidlConversionVirtualizer::setParameter(EffectParamReader& param) {
uint32_t type = 0;
- uint16_t value = 0;
- if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint16_t)) ||
- OK != param.readFromParameter(&type) || OK != param.readFromValue(&value)) {
+ if (OK != param.readFromParameter(&type)) {
ALOGE("%s invalid param %s", __func__, param.toString().c_str());
return BAD_VALUE;
}
Parameter aidlParam;
- // TODO
+ switch (type) {
+ case VIRTUALIZER_PARAM_STRENGTH: {
+ int16_t strength = 0;
+ if (OK != param.readFromValue(&strength)) {
+ ALOGE("%s invalid param %s for type %d", __func__, param.toString().c_str(), type);
+ return BAD_VALUE;
+ }
+ aidlParam = MAKE_SPECIFIC_PARAMETER(Virtualizer, virtualizer, strengthPm, strength);
+ break;
+ }
+ case VIRTUALIZER_PARAM_FORCE_VIRTUALIZATION_MODE: {
+ audio_devices_t deviceType;
+ if (OK != param.readFromValue(&deviceType)) {
+ ALOGE("%s invalid param %s for type %d", __func__, param.toString().c_str(), type);
+ return BAD_VALUE;
+ }
+ AudioDeviceDescription deviceDesc = VALUE_OR_RETURN_STATUS(
+ ::aidl::android::legacy2aidl_audio_devices_t_AudioDeviceDescription(
+ deviceType));
+ aidlParam = MAKE_SPECIFIC_PARAMETER(Virtualizer, virtualizer, device, deviceDesc);
+ break;
+ }
+ default: {
+ // for vendor extension, copy data area to the DefaultExtension, parameter ignored
+ VendorExtension ext = VALUE_OR_RETURN_STATUS(
+ aidl::android::legacy2aidl_EffectParameterReader_Data_VendorExtension(param));
+ aidlParam = MAKE_SPECIFIC_PARAMETER(Virtualizer, virtualizer, vendor, ext);
+ break;
+ }
+ }
return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
}
status_t AidlConversionVirtualizer::getParameter(EffectParamWriter& param) {
- uint32_t type = 0, value = 0;
- if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint32_t)) ||
- OK != param.readFromParameter(&type)) {
+ uint32_t type = 0;
+ if (OK != param.readFromParameter(&type)) {
ALOGE("%s invalid param %s", __func__, param.toString().c_str());
param.setStatus(BAD_VALUE);
return BAD_VALUE;
}
- // TODO
- return param.writeToValue(&value);
+ Parameter aidlParam;
+ switch (type) {
+ case VIRTUALIZER_PARAM_STRENGTH_SUPPORTED: {
+ // an invalid range indicates not setting support for this parameter
+ uint32_t support =
+ ::aidl::android::hardware::audio::effect::isRangeValid<Range::Tag::virtualizer>(
+ Virtualizer::strengthPm, mDesc.capability);
+ return param.writeToValue(&support);
+ }
+ case VIRTUALIZER_PARAM_STRENGTH: {
+ Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(Virtualizer, virtualizerTag,
+ Virtualizer::strengthPm);
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+ int16_t strength = VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(
+ aidlParam, Virtualizer, virtualizer, Virtualizer::strengthPm, int32_t));
+ return param.writeToValue(&strength);
+ }
+ case VIRTUALIZER_PARAM_VIRTUAL_SPEAKER_ANGLES: {
+ audio_channel_mask_t mask;
+ audio_devices_t device;
+ if (OK != param.readFromParameter(&mask) || OK != param.readFromParameter(&device)) {
+ ALOGW("%s illegal param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ Virtualizer::SpeakerAnglesPayload payload = {
+ .layout = VALUE_OR_RETURN_STATUS(
+ ::aidl::android::legacy2aidl_audio_channel_mask_t_AudioChannelLayout(
+ mask, false)),
+ .device = VALUE_OR_RETURN_STATUS(
+ ::aidl::android::legacy2aidl_audio_devices_t_AudioDeviceDescription(
+ device))};
+ Virtualizer::Id vId = UNION_MAKE(Virtualizer::Id, speakerAnglesPayload, payload);
+ Parameter::Id id = UNION_MAKE(Parameter::Id, virtualizerTag, vId);
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+ const auto& angles = VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(
+ aidlParam, Virtualizer, virtualizer, Virtualizer::speakerAngles,
+ std::vector<Virtualizer::ChannelAngle>));
+ for (const auto& angle : angles) {
+ const audio_channel_mask_t chMask = ::aidl::android::
+ aidl2legacy_AudioChannelLayout_layout_audio_channel_mask_t_bits(
+ angle.channel, false);
+ ALOGW("%s aidl %d ch %d", __func__, angle.channel, chMask);
+ if (OK != param.writeToValue(&chMask) ||
+ OK != param.writeToValue(&angle.azimuthDegree) ||
+ OK != param.writeToValue(&angle.elevationDegree)) {
+ ALOGW("%s can't write angles to param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ }
+ return OK;
+ }
+ case VIRTUALIZER_PARAM_VIRTUALIZATION_MODE: {
+ Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(Virtualizer, virtualizerTag,
+ Virtualizer::device);
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+ AudioDeviceDescription device = VALUE_OR_RETURN_STATUS(
+ GET_PARAMETER_SPECIFIC_FIELD(aidlParam, Virtualizer, virtualizer,
+ Virtualizer::device, AudioDeviceDescription));
+ const audio_devices_t deviceType = VALUE_OR_RETURN_STATUS(
+ ::aidl::android::aidl2legacy_AudioDeviceDescription_audio_devices_t(device));
+ return param.writeToValue(&deviceType);
+ }
+ default: {
+ VENDOR_EXTENSION_GET_AND_RETURN(Virtualizer, virtualizer, param);
+ }
+ }
}
} // namespace effect
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVisualizer.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVisualizer.cpp
index 9ed601f..72659ed 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVisualizer.cpp
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVisualizer.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <cstddef>
#include <cstdint>
#include <cstring>
#include <optional>
@@ -33,35 +34,144 @@
namespace android {
namespace effect {
+using ::aidl::android::getParameterSpecificField;
using ::aidl::android::aidl_utils::statusTFromBinderStatus;
using ::aidl::android::hardware::audio::effect::Parameter;
+using ::aidl::android::hardware::audio::effect::VendorExtension;
+using ::aidl::android::hardware::audio::effect::Visualizer;
using ::android::status_t;
using utils::EffectParamReader;
using utils::EffectParamWriter;
status_t AidlConversionVisualizer::setParameter(EffectParamReader& param) {
- uint32_t type = 0;
- uint16_t value = 0;
- if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint16_t)) ||
+ uint32_t type = 0, value = 0;
+ if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint32_t)) ||
OK != param.readFromParameter(&type) || OK != param.readFromValue(&value)) {
ALOGE("%s invalid param %s", __func__, param.toString().c_str());
return BAD_VALUE;
}
Parameter aidlParam;
- // TODO
+ switch (type) {
+ case VISUALIZER_PARAM_CAPTURE_SIZE: {
+ aidlParam = MAKE_SPECIFIC_PARAMETER(Visualizer, visualizer, captureSamples, value);
+ break;
+ }
+ case VISUALIZER_PARAM_SCALING_MODE: {
+ Visualizer::ScalingMode mode = VALUE_OR_RETURN_STATUS(
+ aidl::android::legacy2aidl_Parameter_Visualizer_uint32_ScalingMode(value));
+ aidlParam = MAKE_SPECIFIC_PARAMETER(Visualizer, visualizer, scalingMode, mode);
+ break;
+ }
+ case VISUALIZER_PARAM_LATENCY: {
+ aidlParam = MAKE_SPECIFIC_PARAMETER(Visualizer, visualizer, latencyMs, value);
+ break;
+ }
+ case VISUALIZER_PARAM_MEASUREMENT_MODE: {
+ Visualizer::MeasurementMode mode = VALUE_OR_RETURN_STATUS(
+ aidl::android::legacy2aidl_Parameter_Visualizer_uint32_MeasurementMode(value));
+ aidlParam = MAKE_SPECIFIC_PARAMETER(Visualizer, visualizer, measurementMode, mode);
+ break;
+ }
+ default: {
+ // for vendor extension, copy data area to the DefaultExtension, parameter ignored
+ VendorExtension ext = VALUE_OR_RETURN_STATUS(
+ aidl::android::legacy2aidl_EffectParameterReader_Data_VendorExtension(param));
+ aidlParam = MAKE_SPECIFIC_PARAMETER(Visualizer, visualizer, vendor, ext);
+ break;
+ }
+ }
return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
}
status_t AidlConversionVisualizer::getParameter(EffectParamWriter& param) {
uint32_t type = 0, value = 0;
- if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint32_t)) ||
+ if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(int32_t)) ||
OK != param.readFromParameter(&type)) {
ALOGE("%s invalid param %s", __func__, param.toString().c_str());
param.setStatus(BAD_VALUE);
return BAD_VALUE;
}
- // TODO
- return param.writeToValue(&value);
+ Parameter aidlParam;
+ switch (type) {
+ case VISUALIZER_PARAM_CAPTURE_SIZE: {
+ Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(Visualizer, visualizerTag,
+ Visualizer::captureSamples);
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+ value = VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(
+ aidlParam, Visualizer, visualizer, Visualizer::captureSamples, int32_t));
+ mCaptureSize = value;
+ return param.writeToValue(&value);
+ }
+ case VISUALIZER_PARAM_SCALING_MODE: {
+ Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(Visualizer, visualizerTag,
+ Visualizer::scalingMode);
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+ Visualizer::ScalingMode mode = VALUE_OR_RETURN_STATUS(
+ GET_PARAMETER_SPECIFIC_FIELD(aidlParam, Visualizer, visualizer,
+ Visualizer::scalingMode, Visualizer::ScalingMode));
+ value = VALUE_OR_RETURN_STATUS(
+ aidl::android::aidl2legacy_Parameter_Visualizer_ScalingMode_uint32(mode));
+ return param.writeToValue(&value);
+ }
+ case VISUALIZER_PARAM_LATENCY: {
+ Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(Visualizer, visualizerTag,
+ Visualizer::latencyMs);
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+ value = (int32_t)VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(
+ aidlParam, Visualizer, visualizer, Visualizer::latencyMs, int32_t));
+ return param.writeToValue(&value);
+ }
+ case VISUALIZER_PARAM_MEASUREMENT_MODE: {
+ Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(Visualizer, visualizerTag,
+ Visualizer::measurementMode);
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+ Visualizer::MeasurementMode mode = VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(
+ aidlParam, Visualizer, visualizer, Visualizer::measurementMode,
+ Visualizer::MeasurementMode));
+ value = VALUE_OR_RETURN_STATUS(
+ aidl::android::aidl2legacy_Parameter_Visualizer_MeasurementMode_uint32(mode));
+ return param.writeToValue(&value);
+ }
+ default: {
+ VENDOR_EXTENSION_GET_AND_RETURN(Visualizer, visualizer, param);
+ }
+ }
+}
+
+status_t AidlConversionVisualizer::visualizerCapture(uint32_t* replySize, void* pReplyData) {
+ if (!replySize || !pReplyData || *replySize != mCaptureSize) {
+ ALOGE("%s illegal param replySize %p pReplyData %p", __func__, replySize, pReplyData);
+ return BAD_VALUE;
+ }
+
+ Parameter aidlParam;
+ Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(Visualizer, visualizerTag,
+ Visualizer::captureSampleBuffer);
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+ const auto& samples = VALUE_OR_RETURN_STATUS(
+ GET_PARAMETER_SPECIFIC_FIELD(aidlParam, Visualizer, visualizer,
+ Visualizer::captureSampleBuffer, std::vector<uint8_t>));
+ size_t len = std::min((size_t)*replySize, samples.size());
+ std::memcpy(pReplyData, samples.data(), *replySize = len);
+ return OK;
+}
+
+status_t AidlConversionVisualizer::visualizerMeasure(uint32_t* replySize, void* pReplyData) {
+ if (!replySize || !pReplyData || *replySize != 2 * sizeof(int32_t)) {
+ ALOGE("%s illegal param replySize %p pReplyData %p", __func__, replySize, pReplyData);
+ return BAD_VALUE;
+ }
+
+ Parameter aidlParam;
+ Parameter::Id id =
+ MAKE_SPECIFIC_PARAMETER_ID(Visualizer, visualizerTag, Visualizer::measurement);
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+ const auto& measure = VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(
+ aidlParam, Visualizer, visualizer, Visualizer::measurement, Visualizer::Measurement));
+ int32_t* reply = (int32_t *) pReplyData;
+ *reply++ = measure.rms;
+ *reply = measure.peak;
+ return OK;
}
} // namespace effect
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVisualizer.h b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVisualizer.h
index a7e4ea1..e380bc6 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVisualizer.h
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVisualizer.h
@@ -32,8 +32,11 @@
~AidlConversionVisualizer() {}
private:
+ uint32_t mCaptureSize = 0;
status_t setParameter(utils::EffectParamReader& param) override;
status_t getParameter(utils::EffectParamWriter& param) override;
+ status_t visualizerCapture(uint32_t* replySize, void* pReplyData) override;
+ status_t visualizerMeasure(uint32_t* replySize, void* pReplyData) override;
};
} // namespace effect
diff --git a/media/libaudiohal/include/media/audiohal/AudioEffectUuid.h b/media/libaudiohal/include/media/audiohal/AudioEffectUuid.h
index b21e4c9..5d491a4 100644
--- a/media/libaudiohal/include/media/audiohal/AudioEffectUuid.h
+++ b/media/libaudiohal/include/media/audiohal/AudioEffectUuid.h
@@ -29,6 +29,12 @@
0x11e0,
0xbd61,
{0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
+// ae3c653b-be18-4ab8-8938-418f0a7f06ac
+static const AudioUuid kAutomaticGainControl1TypeUUID = {static_cast<int32_t>(0xae3c653b),
+ 0xbe18,
+ 0x4ab8,
+ 0x8938,
+ {0x41, 0x8f, 0x0a, 0x7f, 0x06, 0xac}};
// 0xae3c653b-be18-4ab8-8938-418f0a7f06ac
static const AudioUuid kAutomaticGainControl2TypeUUID = {static_cast<int32_t>(0xae3c653b),
0xbe18,
@@ -42,11 +48,11 @@
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}};
+static const AudioUuid kDownmixTypeUUID = {static_cast<int32_t>(0x381e49cc),
+ 0xa858,
+ 0x4aa2,
+ 0x87f6,
+ {0xe8, 0x38, 0x8e, 0x76, 0x01, 0xb2}};
// 7261676f-6d75-7369-6364-28e2fd3ac39e
static const AudioUuid kDynamicsProcessingTypeUUID = {static_cast<int32_t>(0x7261676f),
0x6d75,
@@ -101,12 +107,12 @@
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}};
+// e46b26a0-dddd-11db-8afd-0002a5d5c51b
+static const AudioUuid kVisualizerTypeUUID = {static_cast<int32_t>(0xe46b26a0),
+ 0xdddd,
+ 0x11db,
+ 0x8afd,
+ {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
// fa81a2b8-588b-11ed-9b6a-0242ac120002
static const AudioUuid kVolumeTypeUUID = {static_cast<int32_t>(0xfa81a2b8),
0x588b,
diff --git a/media/libaudiohal/include/media/audiohal/StreamHalInterface.h b/media/libaudiohal/include/media/audiohal/StreamHalInterface.h
index a651d9b..a780a17 100644
--- a/media/libaudiohal/include/media/audiohal/StreamHalInterface.h
+++ b/media/libaudiohal/include/media/audiohal/StreamHalInterface.h
@@ -19,8 +19,8 @@
#include <vector>
+#include <android/media/MicrophoneInfoFw.h>
#include <media/audiohal/EffectHalInterface.h>
-#include <media/MicrophoneInfo.h>
#include <system/audio.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>
@@ -273,7 +273,7 @@
virtual status_t getCapturePosition(int64_t *frames, int64_t *time) = 0;
// Get active microphones
- virtual status_t getActiveMicrophones(std::vector<media::MicrophoneInfo> *microphones) = 0;
+ virtual status_t getActiveMicrophones(std::vector<media::MicrophoneInfoFw> *microphones) = 0;
// Set direction for capture processing
virtual status_t setPreferredMicrophoneDirection(audio_microphone_direction_t) = 0;
diff --git a/media/libaudiohal/tests/Android.bp b/media/libaudiohal/tests/Android.bp
index 6600713..2f78dd0 100644
--- a/media/libaudiohal/tests/Android.bp
+++ b/media/libaudiohal/tests/Android.bp
@@ -46,6 +46,7 @@
"libaudiohal",
"liblog",
"libutils",
+ "libvibrator",
],
header_libs: [
diff --git a/media/libaudiohal/tests/EffectsFactoryHalInterface_test.cpp b/media/libaudiohal/tests/EffectsFactoryHalInterface_test.cpp
index b7742e4..c076ccc 100644
--- a/media/libaudiohal/tests/EffectsFactoryHalInterface_test.cpp
+++ b/media/libaudiohal/tests/EffectsFactoryHalInterface_test.cpp
@@ -27,14 +27,19 @@
#include <media/audiohal/EffectsFactoryHalInterface.h>
#include <system/audio_effects/audio_effects_utils.h>
#include <system/audio_effects/effect_aec.h>
+#include <system/audio_effects/effect_agc.h>
#include <system/audio_effects/effect_agc2.h>
#include <system/audio_effects/effect_bassboost.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_loudnessenhancer.h>
+#include <system/audio_effects/effect_ns.h>
#include <system/audio_effect.h>
#include <gtest/gtest.h>
#include <utils/RefBase.h>
+#include <vibrator/ExternalVibrationUtils.h>
namespace android {
@@ -146,10 +151,16 @@
using EffectParamTestTuple =
std::tuple<const effect_uuid_t* /* type UUID */, std::shared_ptr<EffectParamCombination>>;
+static const effect_uuid_t EXTEND_EFFECT_TYPE_UUID = {
+ 0xfa81dbde, 0x588b, 0x11ed, 0x9b6a, {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
+
std::vector<EffectParamTestTuple> testPairs = {
std::make_tuple(FX_IID_AEC,
createEffectParamCombination(AEC_PARAM_ECHO_DELAY, 0xff /* echoDelayMs */,
sizeof(int32_t) /* returnValueSize */)),
+ std::make_tuple(FX_IID_AGC,
+ createEffectParamCombination(AGC_PARAM_TARGET_LEVEL, 20 /* targetLevel */,
+ sizeof(int16_t) /* returnValueSize */)),
std::make_tuple(FX_IID_AGC2, createEffectParamCombination(
AGC2_PARAM_FIXED_DIGITAL_GAIN, 15 /* digitalGainDb */,
sizeof(int32_t) /* returnValueSize */)),
@@ -158,11 +169,27 @@
sizeof(int32_t) /* returnValueSize */)),
std::make_tuple(EFFECT_UIID_DOWNMIX,
createEffectParamCombination(DOWNMIX_PARAM_TYPE, DOWNMIX_TYPE_FOLD,
- sizeof(int32_t) /* returnValueSize */)),
+ sizeof(int16_t) /* returnValueSize */)),
std::make_tuple(SL_IID_DYNAMICSPROCESSING,
createEffectParamCombination(
std::array<uint32_t, 2>({DP_PARAM_INPUT_GAIN, 0 /* channel */}),
- 30 /* gainDb */, sizeof(int32_t) /* returnValueSize */))};
+ 30 /* gainDb */, sizeof(int32_t) /* returnValueSize */)),
+ std::make_tuple(
+ FX_IID_HAPTICGENERATOR,
+ createEffectParamCombination(
+ HG_PARAM_HAPTIC_INTENSITY,
+ std::array<uint32_t, 2>(
+ {1, uint32_t(::android::os::HapticScale::HIGH) /* scale */}),
+ 0 /* returnValueSize */)),
+ std::make_tuple(
+ FX_IID_LOUDNESS_ENHANCER,
+ createEffectParamCombination(LOUDNESS_ENHANCER_PARAM_TARGET_GAIN_MB, 5 /* gain */,
+ sizeof(int32_t) /* returnValueSize */)),
+ std::make_tuple(FX_IID_NS,
+ createEffectParamCombination(NS_PARAM_LEVEL, 1 /* level */,
+ sizeof(int32_t) /* returnValueSize */)),
+ std::make_tuple(&EXTEND_EFFECT_TYPE_UUID,
+ createEffectParamCombination(1, 0xbead, sizeof(int32_t)))};
class libAudioHalEffectParamTest : public ::testing::TestWithParam<EffectParamTestTuple> {
public:
@@ -186,6 +213,7 @@
}()) {}
void SetUp() override {
+ ASSERT_NE(0ul, mDescs.size());
for (const auto& desc : mDescs) {
sp<EffectHalInterface> interface = createEffectHal(desc);
ASSERT_NE(nullptr, interface);
@@ -237,10 +265,13 @@
&replySize, getParam));
EffectParamReader parameterGet(*getParam);
EXPECT_EQ(replySize, parameterGet.getTotalSize()) << parameterGet.toString();
- std::vector<uint8_t> response(mCombination->valueSize);
- EXPECT_EQ(OK, parameterGet.readFromValue(response.data(), mCombination->valueSize))
- << parameterGet.toString();
- EXPECT_EQ(response, mExpectedValue);
+ if (mCombination->valueSize) {
+ std::vector<uint8_t> response(mCombination->valueSize);
+ EXPECT_EQ(OK, parameterGet.readFromValue(response.data(), mCombination->valueSize))
+ << " try get valueSize " << mCombination->valueSize << " from "
+ << parameterGet.toString();
+ EXPECT_EQ(response, mExpectedValue);
+ }
}
const EffectParamTestTuple mParamTuple;
diff --git a/media/libeffects/dynamicsproc/aidl/DynamicsProcessing.cpp b/media/libeffects/dynamicsproc/aidl/DynamicsProcessing.cpp
index 203a27b..ca578eb 100644
--- a/media/libeffects/dynamicsproc/aidl/DynamicsProcessing.cpp
+++ b/media/libeffects/dynamicsproc/aidl/DynamicsProcessing.cpp
@@ -59,8 +59,34 @@
namespace aidl::android::hardware::audio::effect {
const std::string DynamicsProcessingImpl::kEffectName = "DynamicsProcessing";
-const DynamicsProcessing::Capability DynamicsProcessingImpl::kCapability = {.minCutOffFreq = 220,
- .maxCutOffFreq = 20000};
+
+const DynamicsProcessing::EqBandConfig DynamicsProcessingImpl::kEqBandConfigMin =
+ DynamicsProcessing::EqBandConfig({.channel = 0,
+ .band = 0,
+ .enable = false,
+ .cutoffFrequencyHz = 220,
+ .gainDb = std::numeric_limits<float>::min()});
+const DynamicsProcessing::EqBandConfig DynamicsProcessingImpl::kEqBandConfigMax =
+ DynamicsProcessing::EqBandConfig({.channel = std::numeric_limits<int>::max(),
+ .band = std::numeric_limits<int>::max(),
+ .enable = true,
+ .cutoffFrequencyHz = 20000,
+ .gainDb = std::numeric_limits<float>::max()});
+const Range::DynamicsProcessingRange DynamicsProcessingImpl::kPreEqBandRange = {
+ .min = DynamicsProcessing::make<DynamicsProcessing::preEqBand>(
+ {DynamicsProcessingImpl::kEqBandConfigMin}),
+ .max = DynamicsProcessing::make<DynamicsProcessing::preEqBand>(
+ {DynamicsProcessingImpl::kEqBandConfigMax})};
+const Range::DynamicsProcessingRange DynamicsProcessingImpl::kPostEqBandRange = {
+ .min = DynamicsProcessing::make<DynamicsProcessing::postEqBand>(
+ {DynamicsProcessingImpl::kEqBandConfigMin}),
+ .max = DynamicsProcessing::make<DynamicsProcessing::postEqBand>(
+ {DynamicsProcessingImpl::kEqBandConfigMax})};
+const Range DynamicsProcessingImpl::kRange =
+ Range::make<Range::dynamicsProcessing>({DynamicsProcessingImpl::kPreEqBandRange});
+
+const Capability DynamicsProcessingImpl::kCapability = {.range = {DynamicsProcessingImpl::kRange}};
+
const Descriptor DynamicsProcessingImpl::kDescriptor = {
.common = {.id = {.type = kDynamicsProcessingTypeUUID,
.uuid = kDynamicsProcessingImplUUID,
@@ -70,8 +96,7 @@
.volume = Flags::Volume::CTRL},
.name = DynamicsProcessingImpl::kEffectName,
.implementor = "The Android Open Source Project"},
- .capability = Capability::make<Capability::dynamicsProcessing>(
- DynamicsProcessingImpl::kCapability)};
+ .capability = DynamicsProcessingImpl::kCapability};
ndk::ScopedAStatus DynamicsProcessingImpl::open(const Parameter::Common& common,
const std::optional<Parameter::Specific>& specific,
@@ -138,6 +163,7 @@
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
auto& param = specific.get<Parameter::Specific::dynamicsProcessing>();
+ // TODO: check range here, dynamicsProcessing need customized method for nested parameters.
auto tag = param.getTag();
switch (tag) {
@@ -195,7 +221,7 @@
EX_ILLEGAL_ARGUMENT, "setInputGainFailed");
return ndk::ScopedAStatus::ok();
}
- case DynamicsProcessing::vendorExtension: {
+ case DynamicsProcessing::vendor: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
EX_ILLEGAL_ARGUMENT, "DPVendorExtensionTagNotSupported");
@@ -275,7 +301,7 @@
mContext->getInputGain()));
return ndk::ScopedAStatus::ok();
}
- case DynamicsProcessing::vendorExtension: {
+ case DynamicsProcessing::vendor: {
LOG(ERROR) << __func__ << " wrong vendor tag in CommonTag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
EX_ILLEGAL_ARGUMENT, "DPVendorExtensionTagInWrongId");
diff --git a/media/libeffects/dynamicsproc/aidl/DynamicsProcessing.h b/media/libeffects/dynamicsproc/aidl/DynamicsProcessing.h
index 824ebea..26b6ead 100644
--- a/media/libeffects/dynamicsproc/aidl/DynamicsProcessing.h
+++ b/media/libeffects/dynamicsproc/aidl/DynamicsProcessing.h
@@ -28,7 +28,7 @@
public:
static const std::string kEffectName;
static const Descriptor kDescriptor;
- static const DynamicsProcessing::Capability kCapability;
+ static const Capability kCapability;
DynamicsProcessingImpl() { LOG(DEBUG) << __func__; }
~DynamicsProcessingImpl() {
@@ -52,6 +52,11 @@
std::string getEffectName() override { return kEffectName; }
private:
+ static const DynamicsProcessing::EqBandConfig kEqBandConfigMin;
+ static const DynamicsProcessing::EqBandConfig kEqBandConfigMax;
+ static const Range::DynamicsProcessingRange kPreEqBandRange;
+ static const Range::DynamicsProcessingRange kPostEqBandRange;
+ static const Range kRange;
std::shared_ptr<DynamicsProcessingContext> mContext;
ndk::ScopedAStatus getParameterDynamicsProcessing(const DynamicsProcessing::Tag& tag,
Parameter::Specific* specific);
diff --git a/media/libeffects/dynamicsproc/aidl/DynamicsProcessingContext.cpp b/media/libeffects/dynamicsproc/aidl/DynamicsProcessingContext.cpp
index 57a2be9..7f21f5d 100644
--- a/media/libeffects/dynamicsproc/aidl/DynamicsProcessingContext.cpp
+++ b/media/libeffects/dynamicsproc/aidl/DynamicsProcessingContext.cpp
@@ -64,6 +64,7 @@
RetCode DynamicsProcessingContext::setCommon(const Parameter::Common& common) {
mCommon = common;
init();
+ LOG(INFO) << __func__ << common.toString();
return RetCode::SUCCESS;
}
@@ -420,24 +421,18 @@
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);
+ return validateChannel(band.channel, maxChannel) && validateBand(band.band, maxBand);
}
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);
+ validateTime(band.attackTimeMs) && validateTime(band.releaseTimeMs) &&
+ validateRatio(band.ratio) && validateBandDb(band.thresholdDb) &&
+ validateBandDb(band.kneeWidthDb) && validateBandDb(band.noiseGateThresholdDb) &&
+ validateRatio(band.expanderRatio);
}
bool DynamicsProcessingContext::validateLimiterConfig(
diff --git a/media/libeffects/lvm/tests/EffectReverbTest.cpp b/media/libeffects/lvm/tests/EffectReverbTest.cpp
index 59453eb..aaac782 100644
--- a/media/libeffects/lvm/tests/EffectReverbTest.cpp
+++ b/media/libeffects/lvm/tests/EffectReverbTest.cpp
@@ -33,6 +33,27 @@
constexpr size_t kNumEffectUuids = std::size(kEffectUuids);
+static constexpr audio_channel_mask_t kChMasks[] = {
+ AUDIO_CHANNEL_OUT_MONO, AUDIO_CHANNEL_OUT_STEREO,
+ AUDIO_CHANNEL_OUT_2POINT1, AUDIO_CHANNEL_OUT_5POINT1,
+ AUDIO_CHANNEL_OUT_7POINT1POINT4, AUDIO_CHANNEL_INDEX_MASK_23,
+ AUDIO_CHANNEL_OUT_22POINT2,
+};
+
+static constexpr size_t kNumChMasks = std::size(kChMasks);
+
+static constexpr size_t kSampleRates[] = {8000, 11025, 44100, 48000, 192000};
+
+static constexpr size_t kNumSampleRates = std::size(kSampleRates);
+
+static constexpr size_t kFrameCounts[] = {4, 512};
+
+static constexpr size_t kNumFrameCounts = std::size(kFrameCounts);
+
+static constexpr size_t kLoopCounts[] = {1, 4};
+
+static constexpr size_t kNumLoopCounts = std::size(kLoopCounts);
+
static bool isAuxMode(const effect_uuid_t* uuid) {
// Update this, if the order of effects in kEffectUuids is updated
return (uuid == &kEffectUuids[2] || uuid == &kEffectUuids[3]);
@@ -50,15 +71,15 @@
class SingleEffectTest : public ::testing::TestWithParam<SingleEffectTestParam> {
public:
SingleEffectTest()
- : mSampleRate(EffectTestHelper::kSampleRates[std::get<1>(GetParam())]),
- mFrameCount(EffectTestHelper::kFrameCounts[std::get<2>(GetParam())]),
- mLoopCount(EffectTestHelper::kLoopCounts[std::get<3>(GetParam())]),
+ : mSampleRate(kSampleRates[std::get<1>(GetParam())]),
+ mFrameCount(kFrameCounts[std::get<2>(GetParam())]),
+ mLoopCount(kLoopCounts[std::get<3>(GetParam())]),
mTotalFrameCount(mFrameCount * mLoopCount),
mUuid(&kEffectUuids[std::get<4>(GetParam())]),
mInChMask(isAuxMode(mUuid) ? AUDIO_CHANNEL_OUT_MONO
- : EffectTestHelper::kChMasks[std::get<0>(GetParam())]),
+ : kChMasks[std::get<0>(GetParam())]),
mInChannelCount(audio_channel_count_from_out_mask(mInChMask)),
- mOutChMask(EffectTestHelper::kChMasks[std::get<0>(GetParam())]),
+ mOutChMask(kChMasks[std::get<0>(GetParam())]),
mOutChannelCount(audio_channel_count_from_out_mask(mOutChMask)),
mPreset(kPresets[std::get<5>(GetParam())]) {}
@@ -100,10 +121,10 @@
INSTANTIATE_TEST_SUITE_P(
EffectReverbTestAll, SingleEffectTest,
- ::testing::Combine(::testing::Range(0, (int)EffectTestHelper::kNumChMasks),
- ::testing::Range(0, (int)EffectTestHelper::kNumSampleRates),
- ::testing::Range(0, (int)EffectTestHelper::kNumFrameCounts),
- ::testing::Range(0, (int)EffectTestHelper::kNumLoopCounts),
+ ::testing::Combine(::testing::Range(0, (int)kNumChMasks),
+ ::testing::Range(0, (int)kNumSampleRates),
+ ::testing::Range(0, (int)kNumFrameCounts),
+ ::testing::Range(0, (int)kNumLoopCounts),
::testing::Range(0, (int)kNumEffectUuids),
::testing::Range(0, (int)kNumPresets)));
@@ -112,9 +133,9 @@
: public ::testing::TestWithParam<SingleEffectComparisonTestParam> {
public:
SingleEffectComparisonTest()
- : mSampleRate(EffectTestHelper::kSampleRates[std::get<0>(GetParam())]),
- mFrameCount(EffectTestHelper::kFrameCounts[std::get<1>(GetParam())]),
- mLoopCount(EffectTestHelper::kLoopCounts[std::get<2>(GetParam())]),
+ : mSampleRate(kSampleRates[std::get<0>(GetParam())]),
+ mFrameCount(kFrameCounts[std::get<1>(GetParam())]),
+ mLoopCount(kLoopCounts[std::get<2>(GetParam())]),
mTotalFrameCount(mFrameCount * mLoopCount),
mUuid(&kEffectUuids[std::get<3>(GetParam())]),
mPreset(kPresets[std::get<4>(GetParam())]) {}
@@ -173,7 +194,7 @@
std::vector<int16_t> monoRefI16(mTotalFrameCount);
memcpy_to_i16_from_float(monoRefI16.data(), monoOutput.data(), mTotalFrameCount);
- for (size_t outChMask : EffectTestHelper::kChMasks) {
+ for (size_t outChMask : kChMasks) {
size_t outChannelCount = audio_channel_count_from_out_mask(outChMask);
size_t inChMask = isAuxMode(mUuid) ? AUDIO_CHANNEL_OUT_MONO : outChMask;
@@ -225,9 +246,9 @@
INSTANTIATE_TEST_SUITE_P(
EffectReverbTestAll, SingleEffectComparisonTest,
- ::testing::Combine(::testing::Range(0, (int)EffectTestHelper::kNumSampleRates),
- ::testing::Range(0, (int)EffectTestHelper::kNumFrameCounts),
- ::testing::Range(0, (int)EffectTestHelper::kNumLoopCounts),
+ ::testing::Combine(::testing::Range(0, (int)kNumSampleRates),
+ ::testing::Range(0, (int)kNumFrameCounts),
+ ::testing::Range(0, (int)kNumLoopCounts),
::testing::Range(0, (int)kNumEffectUuids),
::testing::Range(0, (int)kNumPresets)));
diff --git a/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp b/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp
index e303efd..6124356 100644
--- a/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp
+++ b/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp
@@ -531,11 +531,6 @@
}
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;
{
@@ -555,10 +550,6 @@
}
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 {
@@ -584,10 +575,6 @@
}
RetCode BundleContext::setVirtualizerStrength(int strength) {
- if (strength < 0 || strength > lvm::kVirtualizerCap.maxStrengthPm) {
- return RetCode::ERROR_ILLEGAL_PARAMETER;
- }
-
// Update Control Parameter
LVM_ControlParams_t params;
{
diff --git a/media/libeffects/lvm/wrapper/Aidl/BundleTypes.h b/media/libeffects/lvm/wrapper/Aidl/BundleTypes.h
index 1996240..520371b 100644
--- a/media/libeffects/lvm/wrapper/Aidl/BundleTypes.h
+++ b/media/libeffects/lvm/wrapper/Aidl/BundleTypes.h
@@ -67,46 +67,52 @@
{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};
+const std::vector<Range::EqualizerRange> kEqRanges = {
+ MAKE_RANGE(Equalizer, preset, 0, MAX_NUM_PRESETS - 1),
+ MAKE_RANGE(Equalizer, bandLevels,
+ std::vector<Equalizer::BandLevel>{
+ Equalizer::BandLevel({.index = 0, .levelMb = -15})},
+ std::vector<Equalizer::BandLevel>{
+ Equalizer::BandLevel({.index = MAX_NUM_BANDS - 1, .levelMb = 15})}),
+ /* capability definition */
+ MAKE_RANGE(Equalizer, bandFrequencies, kEqBandFrequency, kEqBandFrequency),
+ MAKE_RANGE(Equalizer, presets, kEqPresets, kEqPresets),
+ /* get only parameters with range min > max */
+ MAKE_RANGE(Equalizer, centerFreqMh, std::vector<int>({1}), std::vector<int>({}))};
+static const Capability kEqCap = {.range = kEqRanges};
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 = kEqCap};
-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 int mMaxStrengthSupported = 1000;
+static const std::vector<Range::BassBoostRange> kBassBoostRanges = {
+ MAKE_RANGE(BassBoost, strengthPm, 0, mMaxStrengthSupported)};
+static const Capability kBassBoostCap = {.range = kBassBoostRanges};
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 = kBassBoostCap};
-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::vector<Range::VirtualizerRange> kVirtualizerRanges = {
+ MAKE_RANGE(Virtualizer, strengthPm, 0, mMaxStrengthSupported)};
+static const Capability kVirtualizerCap = {.range = kVirtualizerRanges};
static const std::string kVirtualizerEffectName = "Virtualizer";
static const Descriptor kVirtualizerDesc = {
@@ -121,24 +127,23 @@
.memoryUsage = BUNDLE_MEM_USAGE,
.name = kVirtualizerEffectName,
.implementor = "NXP Software Ltd."},
- .capability = Capability::make<Capability::virtualizer>(kVirtualizerCap)};
+ .capability = kVirtualizerCap};
-static const Volume::Capability kVolumeCap = {.minLevelDb = -9600, .maxLevelDb = 0};
-
+static const std::vector<Range::VolumeRange> kVolumeRanges = {
+ MAKE_RANGE(Volume, levelDb, -9600, 0)};
+static const Capability kVolumeCap = {.range = kVolumeRanges};
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)};
+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 = 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
diff --git a/media/libeffects/lvm/wrapper/Aidl/EffectBundleAidl.cpp b/media/libeffects/lvm/wrapper/Aidl/EffectBundleAidl.cpp
index fd9f3dc..d65fbe5 100644
--- a/media/libeffects/lvm/wrapper/Aidl/EffectBundleAidl.cpp
+++ b/media/libeffects/lvm/wrapper/Aidl/EffectBundleAidl.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include "BundleTypes.h"
#define LOG_TAG "EffectBundleAidl"
#include <Utils.h>
#include <algorithm>
@@ -173,6 +174,7 @@
ndk::ScopedAStatus EffectBundleAidl::setParameterEqualizer(const Parameter::Specific& specific) {
auto& eq = specific.get<Parameter::Specific::equalizer>();
+ RETURN_IF(!inRange(eq, lvm::kEqRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
auto eqTag = eq.getTag();
switch (eqTag) {
case Equalizer::preset:
@@ -193,6 +195,7 @@
ndk::ScopedAStatus EffectBundleAidl::setParameterBassBoost(const Parameter::Specific& specific) {
auto& bb = specific.get<Parameter::Specific::bassBoost>();
+ RETURN_IF(!inRange(bb, lvm::kBassBoostRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
auto bbTag = bb.getTag();
switch (bbTag) {
case BassBoost::strengthPm: {
@@ -210,6 +213,7 @@
ndk::ScopedAStatus EffectBundleAidl::setParameterVirtualizer(const Parameter::Specific& specific) {
auto& vr = specific.get<Parameter::Specific::virtualizer>();
+ RETURN_IF(!inRange(vr, lvm::kVirtualizerRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
auto vrTag = vr.getTag();
switch (vrTag) {
case Virtualizer::strengthPm: {
@@ -235,6 +239,7 @@
ndk::ScopedAStatus EffectBundleAidl::setParameterVolume(const Parameter::Specific& specific) {
auto& vol = specific.get<Parameter::Specific::volume>();
+ RETURN_IF(!inRange(vol, lvm::kVolumeRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
auto volTag = vol.getTag();
switch (volTag) {
case Volume::levelDb: {
@@ -291,11 +296,19 @@
eqParam.set<Equalizer::preset>(mContext->getEqualizerPreset());
break;
}
+ case Equalizer::bandFrequencies: {
+ eqParam.set<Equalizer::bandFrequencies>(lvm::kEqBandFrequency);
+ break;
+ }
+ case Equalizer::presets: {
+ eqParam.set<Equalizer::presets>(lvm::kEqPresets);
+ break;
+ }
case Equalizer::centerFreqMh: {
eqParam.set<Equalizer::centerFreqMh>(mContext->getEqualizerCenterFreqs());
break;
}
- default: {
+ case Equalizer::vendor: {
LOG(ERROR) << __func__ << " not handled tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
EX_ILLEGAL_ARGUMENT, "unsupportedTag");
diff --git a/media/libeffects/lvm/wrapper/Reverb/aidl/EffectReverb.cpp b/media/libeffects/lvm/wrapper/Reverb/aidl/EffectReverb.cpp
index 51825ca..e9bdf94 100644
--- a/media/libeffects/lvm/wrapper/Reverb/aidl/EffectReverb.cpp
+++ b/media/libeffects/lvm/wrapper/Reverb/aidl/EffectReverb.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include "ReverbTypes.h"
#define LOG_TAG "EffectReverb"
#include <Utils.h>
#include <algorithm>
@@ -132,6 +133,7 @@
ndk::ScopedAStatus EffectReverb::setParameterPresetReverb(const Parameter::Specific& specific) {
auto& prParam = specific.get<Parameter::Specific::presetReverb>();
+ RETURN_IF(!inRange(prParam, lvm::kPresetReverbRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
auto tag = prParam.getTag();
switch (tag) {
@@ -152,6 +154,7 @@
ndk::ScopedAStatus EffectReverb::setParameterEnvironmentalReverb(
const Parameter::Specific& specific) {
auto& erParam = specific.get<Parameter::Specific::environmentalReverb>();
+ RETURN_IF(!inRange(erParam, lvm::kEnvReverbRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
auto tag = erParam.getTag();
switch (tag) {
@@ -181,6 +184,20 @@
EX_ILLEGAL_ARGUMENT, "setDecayHfRatioFailed");
return ndk::ScopedAStatus::ok();
}
+ case EnvironmentalReverb::reflectionsLevelMb: {
+ RETURN_IF(mContext->setReflectionsLevel(
+ erParam.get<EnvironmentalReverb::reflectionsLevelMb>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setReflectionsLevelFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ case EnvironmentalReverb::reflectionsDelayMs: {
+ RETURN_IF(mContext->setReflectionsDelay(
+ erParam.get<EnvironmentalReverb::reflectionsDelayMs>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setReflectionsDelayFailed");
+ return ndk::ScopedAStatus::ok();
+ }
case EnvironmentalReverb::levelMb: {
RETURN_IF(mContext->setEnvironmentalReverbLevel(
erParam.get<EnvironmentalReverb::levelMb>()) != RetCode::SUCCESS,
@@ -289,6 +306,14 @@
mContext->getEnvironmentalReverbDecayHfRatio());
break;
}
+ case EnvironmentalReverb::reflectionsLevelMb: {
+ erParam.set<EnvironmentalReverb::reflectionsLevelMb>(mContext->getReflectionsLevel());
+ break;
+ }
+ case EnvironmentalReverb::reflectionsDelayMs: {
+ erParam.set<EnvironmentalReverb::reflectionsDelayMs>(mContext->getReflectionsDelay());
+ break;
+ }
case EnvironmentalReverb::levelMb: {
erParam.set<EnvironmentalReverb::levelMb>(mContext->getEnvironmentalReverbLevel());
break;
diff --git a/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbContext.cpp b/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbContext.cpp
index d35c22b..87aa12b 100644
--- a/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbContext.cpp
+++ b/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbContext.cpp
@@ -139,12 +139,6 @@
}
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;
{
@@ -165,12 +159,6 @@
}
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;
{
@@ -188,10 +176,6 @@
}
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;
@@ -215,12 +199,6 @@
}
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;
{
@@ -238,11 +216,6 @@
}
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;
{
@@ -263,20 +236,11 @@
}
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;
{
@@ -294,11 +258,6 @@
}
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;
{
diff --git a/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbContext.h b/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbContext.h
index af49a25..9bb0b1a 100644
--- a/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbContext.h
+++ b/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbContext.h
@@ -83,6 +83,18 @@
RetCode setVolumeStereo(const Parameter::VolumeStereo& volumeStereo) override;
Parameter::VolumeStereo getVolumeStereo() override { return mVolumeStereo; }
+ RetCode setReflectionsDelay(int delay) {
+ mReflectionsDelayMs = delay;
+ return RetCode::SUCCESS;
+ }
+ bool getReflectionsDelay() const { return mReflectionsDelayMs; }
+
+ RetCode setReflectionsLevel(int level) {
+ mReflectionsLevelMb = level;
+ return RetCode::SUCCESS;
+ }
+ bool getReflectionsLevel() const { return mReflectionsLevelMb; }
+
IEffect::Status lvmProcess(float* in, float* out, int samples);
private:
@@ -146,15 +158,17 @@
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;
+ int mRoomLevel = 0;
+ int mRoomHfLevel = 0;
+ int mDecayTime = 0;
+ int mDecayHfRatio = 0;
+ int mLevel = 0;
+ int mDelay = 0;
+ int mDiffusion = 0;
+ int mDensity = 0;
+ bool mBypass = 0;
+ int mReflectionsLevelMb = 0;
+ int mReflectionsDelayMs = 0;
PresetReverb::Presets mPreset;
PresetReverb::Presets mNextPreset;
diff --git a/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbTypes.h b/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbTypes.h
index e37602c..8dcda87 100644
--- a/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbTypes.h
+++ b/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbTypes.h
@@ -21,6 +21,7 @@
#include <audio_effects/effect_environmentalreverb.h>
#include <audio_effects/effect_presetreverb.h>
#include "effect-impl/EffectUUID.h"
+#include "effect-impl/EffectTypes.h"
// from Reverb/lib
#include "LVREV.h"
@@ -35,51 +36,51 @@
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};
+static const std::vector<Range::EnvironmentalReverbRange> kEnvReverbRanges = {
+ MAKE_RANGE(EnvironmentalReverb, roomLevelMb, lvm::kMinLevel, 0),
+ MAKE_RANGE(EnvironmentalReverb, roomHfLevelMb, -4000, 0),
+ MAKE_RANGE(EnvironmentalReverb, decayTimeMs, 0, lvm::kMaxT60),
+ MAKE_RANGE(EnvironmentalReverb, decayHfRatioPm, 100, 2000),
+ MAKE_RANGE(EnvironmentalReverb, levelMb, lvm::kMinLevel, 0),
+ MAKE_RANGE(EnvironmentalReverb, delayMs, 0, 65),
+ MAKE_RANGE(EnvironmentalReverb, diffusionPm, 0, 1000),
+ MAKE_RANGE(EnvironmentalReverb, densityPm, 0, 1000)};
+static const Capability kEnvReverbCap = {
+ .range = Range::make<Range::environmentalReverb>(kEnvReverbRanges)};
// 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)};
+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 = 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 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 = 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};
+static const std::vector<Range::PresetReverbRange> kPresetReverbRanges = {
+ MAKE_RANGE(PresetReverb, supportedPresets, kSupportedPresets, kSupportedPresets)};
+static const Capability kPresetReverbCap = {
+ .range = Range::make<Range::presetReverb>(kPresetReverbRanges)};
// NXP SW auxiliary preset reverb
static const std::string kAuxPresetReverbEffectName = "Auxiliary Preset Reverb";
@@ -92,7 +93,7 @@
.memoryUsage = kMemUsage,
.name = kAuxPresetReverbEffectName,
.implementor = "NXP Software Ltd."},
- .capability = Capability::make<Capability::presetReverb>(kPresetReverbCap)};
+ .capability = kPresetReverbCap};
// NXP SW insert preset reverb
static const std::string kInsertPresetReverbEffectName = "Insert Preset Reverb";
@@ -107,7 +108,7 @@
.memoryUsage = kMemUsage,
.name = kInsertPresetReverbEffectName,
.implementor = "NXP Software Ltd."},
- .capability = Capability::make<Capability::presetReverb>(kPresetReverbCap)};
+ .capability = kPresetReverbCap};
enum class ReverbEffectType {
AUX_ENV,
diff --git a/media/libeffects/preprocessing/Android.bp b/media/libeffects/preprocessing/Android.bp
index c6e036a..d018c47 100644
--- a/media/libeffects/preprocessing/Android.bp
+++ b/media/libeffects/preprocessing/Android.bp
@@ -58,3 +58,39 @@
"libwebrtc_absl_headers",
],
}
+
+cc_library_shared {
+ name: "libpreprocessingaidl",
+ srcs: [
+ "aidl/PreProcessingContext.cpp",
+ "aidl/EffectPreProcessing.cpp",
+ ":effectCommonFile",
+ ],
+ defaults: [
+ "aidlaudioservice_defaults",
+ "latest_android_hardware_audio_effect_ndk_shared",
+ "latest_android_media_audio_common_types_ndk_shared",
+ ],
+ local_include_dirs: ["aidl"],
+ shared_libs: [
+ "liblog",
+ "libutils",
+ "libaudioutils",
+ ],
+ static_libs: [
+ "webrtc_audio_processing",
+ ],
+ header_libs: [
+ "libwebrtc_absl_headers",
+ "libaudioeffects",
+ "libhardware_headers",
+ ],
+ cflags: [
+ "-Wthread-safety",
+ "-Wno-unused-parameter",
+ ],
+ relative_install_path: "soundfx",
+ visibility: [
+ "//hardware/interfaces/audio/aidl/default",
+ ],
+}
diff --git a/media/libeffects/preprocessing/aidl/EffectPreProcessing.cpp b/media/libeffects/preprocessing/aidl/EffectPreProcessing.cpp
new file mode 100644
index 0000000..b9df915
--- /dev/null
+++ b/media/libeffects/preprocessing/aidl/EffectPreProcessing.cpp
@@ -0,0 +1,453 @@
+/*
+ * 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 "EffectPreProcessing"
+#include <algorithm>
+#include <unordered_set>
+
+#include <Utils.h>
+#include <android-base/logging.h>
+#include <fmq/AidlMessageQueue.h>
+
+#include "EffectPreProcessing.h"
+
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::EffectPreProcessing;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::kAcousticEchoCancelerSwImplUUID;
+using aidl::android::hardware::audio::effect::kAutomaticGainControlV1SwImplUUID;
+using aidl::android::hardware::audio::effect::kAutomaticGainControlV2SwImplUUID;
+using aidl::android::hardware::audio::effect::kNoiseSuppressionSwImplUUID;
+using aidl::android::hardware::audio::effect::State;
+using aidl::android::media::audio::common::AudioUuid;
+
+bool isPreProcessingUuidSupported(const AudioUuid& uuid) {
+ return (uuid == kAcousticEchoCancelerSwImplUUID || uuid == kAutomaticGainControlV1SwImplUUID ||
+ uuid == kAutomaticGainControlV2SwImplUUID || uuid == kNoiseSuppressionSwImplUUID);
+}
+
+extern "C" binder_exception_t createEffect(const AudioUuid* uuid,
+ std::shared_ptr<IEffect>* instanceSpp) {
+ if (!uuid || !isPreProcessingUuidSupported(*uuid)) {
+ LOG(ERROR) << __func__ << "uuid not supported";
+ return EX_ILLEGAL_ARGUMENT;
+ }
+ if (instanceSpp) {
+ *instanceSpp = ndk::SharedRefBase::make<EffectPreProcessing>(*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 || !isPreProcessingUuidSupported(*in_impl_uuid)) {
+ LOG(ERROR) << __func__ << "uuid not supported";
+ return EX_ILLEGAL_ARGUMENT;
+ }
+ if (*in_impl_uuid == kAcousticEchoCancelerSwImplUUID) {
+ *_aidl_return = aidl::android::hardware::audio::effect::kAcousticEchoCancelerDesc;
+ } else if (*in_impl_uuid == kAutomaticGainControlV1SwImplUUID) {
+ *_aidl_return = aidl::android::hardware::audio::effect::kAutomaticGainControlV1Desc;
+ } else if (*in_impl_uuid == kAutomaticGainControlV2SwImplUUID) {
+ *_aidl_return = aidl::android::hardware::audio::effect::kAutomaticGainControlV2Desc;
+ } else if (*in_impl_uuid == kNoiseSuppressionSwImplUUID) {
+ *_aidl_return = aidl::android::hardware::audio::effect::kNoiseSuppressionDesc;
+ }
+ return EX_NONE;
+}
+
+namespace aidl::android::hardware::audio::effect {
+
+EffectPreProcessing::EffectPreProcessing(const AudioUuid& uuid) {
+ LOG(DEBUG) << __func__ << uuid.toString();
+ if (uuid == kAcousticEchoCancelerSwImplUUID) {
+ mType = PreProcessingEffectType::ACOUSTIC_ECHO_CANCELLATION;
+ mDescriptor = &kAcousticEchoCancelerDesc;
+ mEffectName = &kAcousticEchoCancelerEffectName;
+ } else if (uuid == kAutomaticGainControlV1SwImplUUID) {
+ mType = PreProcessingEffectType::AUTOMATIC_GAIN_CONTROL_V1;
+ mDescriptor = &kAutomaticGainControlV1Desc;
+ mEffectName = &kAutomaticGainControlV1EffectName;
+ } else if (uuid == kAutomaticGainControlV2SwImplUUID) {
+ mType = PreProcessingEffectType::AUTOMATIC_GAIN_CONTROL_V2;
+ mDescriptor = &kAutomaticGainControlV2Desc;
+ mEffectName = &kAutomaticGainControlV2EffectName;
+ } else if (uuid == kNoiseSuppressionSwImplUUID) {
+ mType = PreProcessingEffectType::NOISE_SUPPRESSION;
+ mDescriptor = &kNoiseSuppressionDesc;
+ mEffectName = &kNoiseSuppressionEffectName;
+ } else {
+ LOG(ERROR) << __func__ << uuid.toString() << " not supported!";
+ }
+}
+
+EffectPreProcessing::~EffectPreProcessing() {
+ cleanUp();
+ LOG(DEBUG) << __func__;
+}
+
+ndk::ScopedAStatus EffectPreProcessing::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 EffectPreProcessing::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::acousticEchoCanceler:
+ return setParameterAcousticEchoCanceler(specific);
+ case Parameter::Specific::automaticGainControlV1:
+ return setParameterAutomaticGainControlV1(specific);
+ case Parameter::Specific::automaticGainControlV2:
+ return setParameterAutomaticGainControlV2(specific);
+ case Parameter::Specific::noiseSuppression:
+ return setParameterNoiseSuppression(specific);
+ default:
+ LOG(ERROR) << __func__ << " unsupported tag " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "specificParamNotSupported");
+ }
+}
+
+ndk::ScopedAStatus EffectPreProcessing::setParameterAcousticEchoCanceler(
+ const Parameter::Specific& specific) {
+ auto& param = specific.get<Parameter::Specific::acousticEchoCanceler>();
+ RETURN_IF(!inRange(param, kAcousticEchoCancelerRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
+ auto tag = param.getTag();
+
+ switch (tag) {
+ case AcousticEchoCanceler::echoDelayUs: {
+ RETURN_IF(mContext->setAcousticEchoCancelerEchoDelay(
+ param.get<AcousticEchoCanceler::echoDelayUs>()) != RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "echoDelayNotSupported");
+ return ndk::ScopedAStatus::ok();
+ }
+ case AcousticEchoCanceler::mobileMode: {
+ RETURN_IF(mContext->setAcousticEchoCancelerMobileMode(
+ param.get<AcousticEchoCanceler::mobileMode>()) != RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "SettingMobileModeNotSupported");
+ return ndk::ScopedAStatus::ok();
+ }
+ default: {
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+ EX_ILLEGAL_ARGUMENT, "AcousticEchoCancelerTagNotSupported");
+ }
+ }
+}
+
+ndk::ScopedAStatus EffectPreProcessing::setParameterAutomaticGainControlV1(
+ const Parameter::Specific& specific) {
+ auto& param = specific.get<Parameter::Specific::automaticGainControlV1>();
+ RETURN_IF(!inRange(param, kAutomaticGainControlV1Ranges), EX_ILLEGAL_ARGUMENT, "outOfRange");
+ auto tag = param.getTag();
+
+ switch (tag) {
+ case AutomaticGainControlV1::targetPeakLevelDbFs: {
+ RETURN_IF(mContext->setAutomaticGainControlV1TargetPeakLevel(
+ param.get<AutomaticGainControlV1::targetPeakLevelDbFs>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "targetPeakLevelNotSupported");
+ return ndk::ScopedAStatus::ok();
+ }
+ case AutomaticGainControlV1::maxCompressionGainDb: {
+ RETURN_IF(mContext->setAutomaticGainControlV1MaxCompressionGain(
+ param.get<AutomaticGainControlV1::maxCompressionGainDb>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "maxCompressionGainNotSupported");
+ return ndk::ScopedAStatus::ok();
+ }
+ case AutomaticGainControlV1::enableLimiter: {
+ RETURN_IF(
+ mContext->setAutomaticGainControlV1EnableLimiter(
+ param.get<AutomaticGainControlV1::enableLimiter>()) != RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "enableLimiterNotSupported");
+ return ndk::ScopedAStatus::ok();
+ }
+ default: {
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+ EX_ILLEGAL_ARGUMENT, "AutomaticGainControlV1TagNotSupported");
+ }
+ }
+}
+
+ndk::ScopedAStatus EffectPreProcessing::setParameterAutomaticGainControlV2(
+ const Parameter::Specific& specific) {
+ auto& param = specific.get<Parameter::Specific::automaticGainControlV2>();
+ RETURN_IF(!inRange(param, kAutomaticGainControlV2Ranges), EX_ILLEGAL_ARGUMENT, "outOfRange");
+ auto tag = param.getTag();
+
+ switch (tag) {
+ case AutomaticGainControlV2::fixedDigitalGainMb: {
+ RETURN_IF(mContext->setAutomaticGainControlV2DigitalGain(
+ param.get<AutomaticGainControlV2::fixedDigitalGainMb>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "digitalGainNotSupported");
+ return ndk::ScopedAStatus::ok();
+ }
+ case AutomaticGainControlV2::levelEstimator: {
+ RETURN_IF(mContext->setAutomaticGainControlV2LevelEstimator(
+ param.get<AutomaticGainControlV2::levelEstimator>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "levelEstimatorNotSupported");
+ return ndk::ScopedAStatus::ok();
+ }
+ case AutomaticGainControlV2::saturationMarginMb: {
+ RETURN_IF(mContext->setAutomaticGainControlV2SaturationMargin(
+ param.get<AutomaticGainControlV2::saturationMarginMb>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "saturationMarginNotSupported");
+ return ndk::ScopedAStatus::ok();
+ }
+ default: {
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+ EX_ILLEGAL_ARGUMENT, "AutomaticGainControlV2TagNotSupported");
+ }
+ }
+}
+
+ndk::ScopedAStatus EffectPreProcessing::setParameterNoiseSuppression(
+ const Parameter::Specific& specific) {
+ auto& param = specific.get<Parameter::Specific::noiseSuppression>();
+ auto tag = param.getTag();
+
+ switch (tag) {
+ case NoiseSuppression::level: {
+ RETURN_IF(mContext->setNoiseSuppressionLevel(param.get<NoiseSuppression::level>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "levelNotSupported");
+ return ndk::ScopedAStatus::ok();
+ }
+ default: {
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+ EX_ILLEGAL_ARGUMENT, "NoiseSuppressionTagNotSupported");
+ }
+ }
+}
+
+ndk::ScopedAStatus EffectPreProcessing::getParameterSpecific(const Parameter::Id& id,
+ Parameter::Specific* specific) {
+ RETURN_IF(!specific, EX_NULL_POINTER, "nullPtr");
+ auto tag = id.getTag();
+
+ switch (tag) {
+ case Parameter::Id::acousticEchoCancelerTag:
+ return getParameterAcousticEchoCanceler(
+ id.get<Parameter::Id::acousticEchoCancelerTag>(), specific);
+ case Parameter::Id::automaticGainControlV1Tag:
+ return getParameterAutomaticGainControlV1(
+ id.get<Parameter::Id::automaticGainControlV1Tag>(), specific);
+ case Parameter::Id::automaticGainControlV2Tag:
+ return getParameterAutomaticGainControlV2(
+ id.get<Parameter::Id::automaticGainControlV2Tag>(), specific);
+ case Parameter::Id::noiseSuppressionTag:
+ return getParameterNoiseSuppression(id.get<Parameter::Id::noiseSuppressionTag>(),
+ specific);
+ default:
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "wrongIdTag");
+ }
+}
+
+ndk::ScopedAStatus EffectPreProcessing::getParameterAcousticEchoCanceler(
+ const AcousticEchoCanceler::Id& id, Parameter::Specific* specific) {
+ RETURN_IF(id.getTag() != AcousticEchoCanceler::Id::commonTag, EX_ILLEGAL_ARGUMENT,
+ "AcousticEchoCancelerTagNotSupported");
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+ AcousticEchoCanceler param;
+ auto tag = id.get<AcousticEchoCanceler::Id::commonTag>();
+ switch (tag) {
+ case AcousticEchoCanceler::echoDelayUs: {
+ param.set<AcousticEchoCanceler::echoDelayUs>(
+ mContext->getAcousticEchoCancelerEchoDelay());
+ break;
+ }
+ case AcousticEchoCanceler::mobileMode: {
+ param.set<AcousticEchoCanceler::mobileMode>(
+ mContext->getAcousticEchoCancelerMobileMode());
+ break;
+ }
+ default: {
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+ EX_ILLEGAL_ARGUMENT, "AcousticEchoCancelerTagNotSupported");
+ }
+ }
+
+ specific->set<Parameter::Specific::acousticEchoCanceler>(param);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus EffectPreProcessing::getParameterAutomaticGainControlV1(
+ const AutomaticGainControlV1::Id& id, Parameter::Specific* specific) {
+ RETURN_IF(id.getTag() != AutomaticGainControlV1::Id::commonTag, EX_ILLEGAL_ARGUMENT,
+ "AutomaticGainControlV1TagNotSupported");
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+ AutomaticGainControlV1 param;
+
+ auto tag = id.get<AutomaticGainControlV1::Id::commonTag>();
+ switch (tag) {
+ case AutomaticGainControlV1::targetPeakLevelDbFs: {
+ param.set<AutomaticGainControlV1::targetPeakLevelDbFs>(
+ mContext->getAutomaticGainControlV1TargetPeakLevel());
+ break;
+ }
+ case AutomaticGainControlV1::maxCompressionGainDb: {
+ param.set<AutomaticGainControlV1::maxCompressionGainDb>(
+ mContext->getAutomaticGainControlV1MaxCompressionGain());
+ break;
+ }
+ case AutomaticGainControlV1::enableLimiter: {
+ param.set<AutomaticGainControlV1::enableLimiter>(
+ mContext->getAutomaticGainControlV1EnableLimiter());
+ break;
+ }
+ default: {
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+ EX_ILLEGAL_ARGUMENT, "AutomaticGainControlV1TagNotSupported");
+ }
+ }
+
+ specific->set<Parameter::Specific::automaticGainControlV1>(param);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus EffectPreProcessing::getParameterAutomaticGainControlV2(
+ const AutomaticGainControlV2::Id& id, Parameter::Specific* specific) {
+ RETURN_IF(id.getTag() != AutomaticGainControlV2::Id::commonTag, EX_ILLEGAL_ARGUMENT,
+ "AutomaticGainControlV2TagNotSupported");
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+ AutomaticGainControlV2 param;
+
+ auto tag = id.get<AutomaticGainControlV2::Id::commonTag>();
+ switch (tag) {
+ case AutomaticGainControlV2::fixedDigitalGainMb: {
+ param.set<AutomaticGainControlV2::fixedDigitalGainMb>(
+ mContext->getAutomaticGainControlV2DigitalGain());
+ break;
+ }
+ case AutomaticGainControlV2::levelEstimator: {
+ param.set<AutomaticGainControlV2::levelEstimator>(
+ mContext->getAutomaticGainControlV2LevelEstimator());
+ break;
+ }
+ case AutomaticGainControlV2::saturationMarginMb: {
+ param.set<AutomaticGainControlV2::saturationMarginMb>(
+ mContext->getAutomaticGainControlV2SaturationMargin());
+ break;
+ }
+ default: {
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+ EX_ILLEGAL_ARGUMENT, "AutomaticGainControlV2TagNotSupported");
+ }
+ }
+
+ specific->set<Parameter::Specific::automaticGainControlV2>(param);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus EffectPreProcessing::getParameterNoiseSuppression(
+ const NoiseSuppression::Id& id, Parameter::Specific* specific) {
+ RETURN_IF(id.getTag() != NoiseSuppression::Id::commonTag, EX_ILLEGAL_ARGUMENT,
+ "NoiseSuppressionTagNotSupported");
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+ NoiseSuppression param;
+
+ auto tag = id.get<NoiseSuppression::Id::commonTag>();
+ switch (tag) {
+ case NoiseSuppression::level: {
+ param.set<NoiseSuppression::level>(mContext->getNoiseSuppressionLevel());
+ break;
+ }
+ default: {
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+ EX_ILLEGAL_ARGUMENT, "NoiseSuppressionTagNotSupported");
+ }
+ }
+
+ specific->set<Parameter::Specific::noiseSuppression>(param);
+ return ndk::ScopedAStatus::ok();
+}
+
+std::shared_ptr<EffectContext> EffectPreProcessing::createContext(const Parameter::Common& common) {
+ if (mContext) {
+ LOG(DEBUG) << __func__ << " context already exist";
+ } else {
+ // PreProcessingSession is a singleton
+ mContext = PreProcessingSession::getPreProcessingSession().createSession(
+ mType, 1 /* statusFmqDepth */, common);
+ }
+
+ return mContext;
+}
+
+std::shared_ptr<EffectContext> EffectPreProcessing::getContext() {
+ return mContext;
+}
+
+RetCode EffectPreProcessing::releaseContext() {
+ if (mContext) {
+ PreProcessingSession::getPreProcessingSession().releaseSession(mType,
+ mContext->getSessionId());
+ mContext.reset();
+ }
+ return RetCode::SUCCESS;
+}
+
+ndk::ScopedAStatus EffectPreProcessing::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 EffectPreProcessing::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/preprocessing/aidl/EffectPreProcessing.h b/media/libeffects/preprocessing/aidl/EffectPreProcessing.h
new file mode 100644
index 0000000..fad848a
--- /dev/null
+++ b/media/libeffects/preprocessing/aidl/EffectPreProcessing.h
@@ -0,0 +1,71 @@
+/*
+ * 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 "PreProcessingContext.h"
+#include "PreProcessingSession.h"
+#include "effect-impl/EffectImpl.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+class EffectPreProcessing final : public EffectImpl {
+ public:
+ explicit EffectPreProcessing(const AudioUuid& uuid);
+ ~EffectPreProcessing() 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<PreProcessingContext> mContext;
+ const Descriptor* mDescriptor;
+ const std::string* mEffectName;
+ PreProcessingEffectType mType;
+
+ ndk::ScopedAStatus setParameterAcousticEchoCanceler(const Parameter::Specific& specific);
+ ndk::ScopedAStatus getParameterAcousticEchoCanceler(const AcousticEchoCanceler::Id& id,
+ Parameter::Specific* specific);
+
+ ndk::ScopedAStatus setParameterAutomaticGainControlV1(const Parameter::Specific& specific);
+ ndk::ScopedAStatus getParameterAutomaticGainControlV1(const AutomaticGainControlV1::Id& id,
+ Parameter::Specific* specific);
+
+ ndk::ScopedAStatus setParameterAutomaticGainControlV2(const Parameter::Specific& specific);
+ ndk::ScopedAStatus getParameterAutomaticGainControlV2(const AutomaticGainControlV2::Id& id,
+ Parameter::Specific* specific);
+
+ ndk::ScopedAStatus setParameterNoiseSuppression(const Parameter::Specific& specific);
+ ndk::ScopedAStatus getParameterNoiseSuppression(const NoiseSuppression::Id& id,
+ Parameter::Specific* specific);
+};
+
+} // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/preprocessing/aidl/PreProcessingContext.cpp b/media/libeffects/preprocessing/aidl/PreProcessingContext.cpp
new file mode 100644
index 0000000..104277e
--- /dev/null
+++ b/media/libeffects/preprocessing/aidl/PreProcessingContext.cpp
@@ -0,0 +1,311 @@
+/*
+ * 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 "PreProcessingContext"
+#include <Utils.h>
+
+#include "PreProcessingContext.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+using aidl::android::media::audio::common::AudioDeviceDescription;
+using aidl::android::media::audio::common::AudioDeviceType;
+
+RetCode PreProcessingContext::init(const Parameter::Common& common) {
+ std::lock_guard lg(mMutex);
+ webrtc::AudioProcessingBuilder apBuilder;
+ mAudioProcessingModule = apBuilder.Create();
+ if (mAudioProcessingModule == nullptr) {
+ LOG(ERROR) << "init could not get apm engine";
+ return RetCode::ERROR_EFFECT_LIB_ERROR;
+ }
+
+ updateConfigs(common);
+
+ mEnabledMsk = 0;
+ mProcessedMsk = 0;
+ mRevEnabledMsk = 0;
+ mRevProcessedMsk = 0;
+
+ auto config = mAudioProcessingModule->GetConfig();
+ switch (mType) {
+ case PreProcessingEffectType::ACOUSTIC_ECHO_CANCELLATION:
+ config.echo_canceller.mobile_mode = true;
+ break;
+ case PreProcessingEffectType::AUTOMATIC_GAIN_CONTROL_V1:
+ config.gain_controller1.target_level_dbfs = kAgcDefaultTargetLevel;
+ config.gain_controller1.compression_gain_db = kAgcDefaultCompGain;
+ config.gain_controller1.enable_limiter = kAgcDefaultLimiter;
+ break;
+ case PreProcessingEffectType::AUTOMATIC_GAIN_CONTROL_V2:
+ config.gain_controller2.fixed_digital.gain_db = 0.f;
+ break;
+ case PreProcessingEffectType::NOISE_SUPPRESSION:
+ config.noise_suppression.level = kNsDefaultLevel;
+ break;
+ }
+ mAudioProcessingModule->ApplyConfig(config);
+ mState = PRE_PROC_STATE_INITIALIZED;
+ return RetCode::SUCCESS;
+}
+
+RetCode PreProcessingContext::deInit() {
+ std::lock_guard lg(mMutex);
+ mAudioProcessingModule = nullptr;
+ mState = PRE_PROC_STATE_UNINITIALIZED;
+ return RetCode::SUCCESS;
+}
+
+RetCode PreProcessingContext::enable() {
+ if (mState != PRE_PROC_STATE_INITIALIZED) {
+ return RetCode::ERROR_EFFECT_LIB_ERROR;
+ }
+ int typeMsk = (1 << int(mType));
+ std::lock_guard lg(mMutex);
+ // Check if effect is already enabled.
+ if ((mEnabledMsk & typeMsk) == typeMsk) {
+ return RetCode::ERROR_ILLEGAL_PARAMETER;
+ }
+ mEnabledMsk |= typeMsk;
+ auto config = mAudioProcessingModule->GetConfig();
+ switch (mType) {
+ case PreProcessingEffectType::ACOUSTIC_ECHO_CANCELLATION:
+ config.echo_canceller.enabled = true;
+ // AEC has reverse stream
+ mRevEnabledMsk |= typeMsk;
+ mRevProcessedMsk = 0;
+ break;
+ case PreProcessingEffectType::AUTOMATIC_GAIN_CONTROL_V1:
+ config.gain_controller1.enabled = true;
+ break;
+ case PreProcessingEffectType::AUTOMATIC_GAIN_CONTROL_V2:
+ config.gain_controller2.enabled = true;
+ break;
+ case PreProcessingEffectType::NOISE_SUPPRESSION:
+ config.noise_suppression.enabled = true;
+ break;
+ }
+ mProcessedMsk = 0;
+ mAudioProcessingModule->ApplyConfig(config);
+ mState = PRE_PROC_STATE_ACTIVE;
+ return RetCode::SUCCESS;
+}
+
+RetCode PreProcessingContext::disable() {
+ if (mState != PRE_PROC_STATE_ACTIVE) {
+ return RetCode::ERROR_EFFECT_LIB_ERROR;
+ }
+ int typeMsk = (1 << int(mType));
+ std::lock_guard lg(mMutex);
+ // Check if effect is already disabled.
+ if ((mEnabledMsk & typeMsk) != typeMsk) {
+ return RetCode::ERROR_ILLEGAL_PARAMETER;
+ }
+ mEnabledMsk &= ~typeMsk;
+ auto config = mAudioProcessingModule->GetConfig();
+ switch (mType) {
+ case PreProcessingEffectType::ACOUSTIC_ECHO_CANCELLATION:
+ config.echo_canceller.enabled = false;
+ // AEC has reverse stream
+ mRevEnabledMsk &= ~typeMsk;
+ mRevProcessedMsk = 0;
+ break;
+ case PreProcessingEffectType::AUTOMATIC_GAIN_CONTROL_V1:
+ config.gain_controller1.enabled = false;
+ break;
+ case PreProcessingEffectType::AUTOMATIC_GAIN_CONTROL_V2:
+ config.gain_controller2.enabled = false;
+ break;
+ case PreProcessingEffectType::NOISE_SUPPRESSION:
+ config.noise_suppression.enabled = false;
+ break;
+ }
+ mProcessedMsk = 0;
+ mAudioProcessingModule->ApplyConfig(config);
+ mState = PRE_PROC_STATE_INITIALIZED;
+ return RetCode::SUCCESS;
+}
+
+RetCode PreProcessingContext::setCommon(const Parameter::Common& common) {
+ mCommon = common;
+ updateConfigs(common);
+ return RetCode::SUCCESS;
+}
+
+void PreProcessingContext::updateConfigs(const Parameter::Common& common) {
+ mInputConfig.set_sample_rate_hz(common.input.base.sampleRate);
+ mInputConfig.set_num_channels(
+ ::android::hardware::audio::common::getChannelCount(common.input.base.channelMask));
+ mOutputConfig.set_sample_rate_hz(common.input.base.sampleRate);
+ mOutputConfig.set_num_channels(
+ ::android::hardware::audio::common::getChannelCount(common.output.base.channelMask));
+}
+
+RetCode PreProcessingContext::setAcousticEchoCancelerEchoDelay(int echoDelayUs) {
+ mEchoDelayUs = echoDelayUs;
+ std::lock_guard lg(mMutex);
+ mAudioProcessingModule->set_stream_delay_ms(mEchoDelayUs / 1000);
+ return RetCode::SUCCESS;
+}
+
+int PreProcessingContext::getAcousticEchoCancelerEchoDelay() const {
+ return mEchoDelayUs;
+}
+
+RetCode PreProcessingContext::setAcousticEchoCancelerMobileMode(bool mobileMode) {
+ mMobileMode = mobileMode;
+ std::lock_guard lg(mMutex);
+ auto config = mAudioProcessingModule->GetConfig();
+ config.echo_canceller.mobile_mode = mobileMode;
+ mAudioProcessingModule->ApplyConfig(config);
+ return RetCode::SUCCESS;
+}
+
+bool PreProcessingContext::getAcousticEchoCancelerMobileMode() const {
+ return mMobileMode;
+}
+
+RetCode PreProcessingContext::setAutomaticGainControlV1TargetPeakLevel(int targetPeakLevel) {
+ mTargetPeakLevel = targetPeakLevel;
+ std::lock_guard lg(mMutex);
+ auto config = mAudioProcessingModule->GetConfig();
+ config.gain_controller1.target_level_dbfs = -(mTargetPeakLevel / 100);
+ mAudioProcessingModule->ApplyConfig(config);
+ return RetCode::SUCCESS;
+}
+
+int PreProcessingContext::getAutomaticGainControlV1TargetPeakLevel() const {
+ return mTargetPeakLevel;
+}
+
+RetCode PreProcessingContext::setAutomaticGainControlV1MaxCompressionGain(int maxCompressionGain) {
+ mMaxCompressionGain = maxCompressionGain;
+ std::lock_guard lg(mMutex);
+ auto config = mAudioProcessingModule->GetConfig();
+ config.gain_controller1.compression_gain_db = mMaxCompressionGain / 100;
+ mAudioProcessingModule->ApplyConfig(config);
+ return RetCode::SUCCESS;
+}
+
+int PreProcessingContext::getAutomaticGainControlV1MaxCompressionGain() const {
+ return mMaxCompressionGain;
+}
+
+RetCode PreProcessingContext::setAutomaticGainControlV1EnableLimiter(bool enableLimiter) {
+ mEnableLimiter = enableLimiter;
+ std::lock_guard lg(mMutex);
+ auto config = mAudioProcessingModule->GetConfig();
+ config.gain_controller1.enable_limiter = mEnableLimiter;
+ mAudioProcessingModule->ApplyConfig(config);
+ return RetCode::SUCCESS;
+}
+
+bool PreProcessingContext::getAutomaticGainControlV1EnableLimiter() const {
+ return mEnableLimiter;
+}
+
+RetCode PreProcessingContext::setAutomaticGainControlV2DigitalGain(int gain) {
+ mDigitalGain = gain;
+ std::lock_guard lg(mMutex);
+ auto config = mAudioProcessingModule->GetConfig();
+ config.gain_controller2.fixed_digital.gain_db = mDigitalGain;
+ mAudioProcessingModule->ApplyConfig(config);
+ return RetCode::SUCCESS;
+}
+
+int PreProcessingContext::getAutomaticGainControlV2DigitalGain() const {
+ return mDigitalGain;
+}
+
+RetCode PreProcessingContext::setAutomaticGainControlV2LevelEstimator(
+ AutomaticGainControlV2::LevelEstimator levelEstimator) {
+ mLevelEstimator = levelEstimator;
+ return RetCode::SUCCESS;
+}
+
+AutomaticGainControlV2::LevelEstimator
+PreProcessingContext::getAutomaticGainControlV2LevelEstimator() const {
+ return mLevelEstimator;
+}
+
+RetCode PreProcessingContext::setAutomaticGainControlV2SaturationMargin(int saturationMargin) {
+ mSaturationMargin = saturationMargin;
+ return RetCode::SUCCESS;
+}
+
+int PreProcessingContext::getAutomaticGainControlV2SaturationMargin() const {
+ return mSaturationMargin;
+}
+
+RetCode PreProcessingContext::setNoiseSuppressionLevel(NoiseSuppression::Level level) {
+ mLevel = level;
+ std::lock_guard lg(mMutex);
+ auto config = mAudioProcessingModule->GetConfig();
+ config.noise_suppression.level =
+ (webrtc::AudioProcessing::Config::NoiseSuppression::Level)level;
+ mAudioProcessingModule->ApplyConfig(config);
+ return RetCode::SUCCESS;
+}
+
+NoiseSuppression::Level PreProcessingContext::getNoiseSuppressionLevel() const {
+ return mLevel;
+}
+
+IEffect::Status PreProcessingContext::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);
+
+ mProcessedMsk |= (1 << int(mType));
+
+ // webrtc implementation clear out was_stream_delay_set every time after ProcessStream() call
+ mAudioProcessingModule->set_stream_delay_ms(mEchoDelayUs / 1000);
+
+ if ((mProcessedMsk & mEnabledMsk) == mEnabledMsk) {
+ mProcessedMsk = 0;
+ int processStatus = mAudioProcessingModule->ProcessStream(
+ (const int16_t* const)in, mInputConfig, mOutputConfig, (int16_t* const)out);
+ if (processStatus != 0) {
+ LOG(ERROR) << "Process stream failed with error " << processStatus;
+ return status;
+ }
+ }
+
+ mRevProcessedMsk |= (1 << int(mType));
+
+ if ((mRevProcessedMsk & mRevEnabledMsk) == mRevEnabledMsk) {
+ mRevProcessedMsk = 0;
+ int revProcessStatus = mAudioProcessingModule->ProcessReverseStream(
+ (const int16_t* const)in, mInputConfig, mInputConfig, (int16_t* const)out);
+ if (revProcessStatus != 0) {
+ LOG(ERROR) << "Process reverse stream failed with error " << revProcessStatus;
+ return status;
+ }
+ }
+
+ return {STATUS_OK, samples, samples};
+}
+
+} // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/preprocessing/aidl/PreProcessingContext.h b/media/libeffects/preprocessing/aidl/PreProcessingContext.h
new file mode 100644
index 0000000..9ba1bbe
--- /dev/null
+++ b/media/libeffects/preprocessing/aidl/PreProcessingContext.h
@@ -0,0 +1,125 @@
+/*
+ * 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 <audio_processing.h>
+#include <unordered_map>
+
+#include "PreProcessingTypes.h"
+#include "effect-impl/EffectContext.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+enum PreProcEffectState {
+ PRE_PROC_STATE_UNINITIALIZED,
+ PRE_PROC_STATE_INITIALIZED,
+ PRE_PROC_STATE_ACTIVE,
+};
+
+class PreProcessingContext final : public EffectContext {
+ public:
+ PreProcessingContext(int statusDepth, const Parameter::Common& common,
+ const PreProcessingEffectType& type)
+ : EffectContext(statusDepth, common), mType(type) {
+ LOG(DEBUG) << __func__ << type;
+ mState = PRE_PROC_STATE_UNINITIALIZED;
+ }
+ ~PreProcessingContext() override { LOG(DEBUG) << __func__; }
+
+ RetCode init(const Parameter::Common& common);
+ RetCode deInit();
+
+ PreProcessingEffectType getPreProcessingType() const { return mType; }
+
+ RetCode enable();
+ RetCode disable();
+
+ RetCode setCommon(const Parameter::Common& common) override;
+ void updateConfigs(const Parameter::Common& common);
+
+ RetCode setAcousticEchoCancelerEchoDelay(int echoDelayUs);
+ int getAcousticEchoCancelerEchoDelay() const;
+ RetCode setAcousticEchoCancelerMobileMode(bool mobileMode);
+ bool getAcousticEchoCancelerMobileMode() const;
+
+ RetCode setAutomaticGainControlV1TargetPeakLevel(int targetPeakLevel);
+ int getAutomaticGainControlV1TargetPeakLevel() const;
+ RetCode setAutomaticGainControlV1MaxCompressionGain(int maxCompressionGain);
+ int getAutomaticGainControlV1MaxCompressionGain() const;
+ RetCode setAutomaticGainControlV1EnableLimiter(bool enableLimiter);
+ bool getAutomaticGainControlV1EnableLimiter() const;
+
+ RetCode setAutomaticGainControlV2DigitalGain(int gain);
+ int getAutomaticGainControlV2DigitalGain() const;
+ RetCode setAutomaticGainControlV2LevelEstimator(
+ AutomaticGainControlV2::LevelEstimator levelEstimator);
+ AutomaticGainControlV2::LevelEstimator getAutomaticGainControlV2LevelEstimator() const;
+ RetCode setAutomaticGainControlV2SaturationMargin(int saturationMargin);
+ int getAutomaticGainControlV2SaturationMargin() const;
+
+ RetCode setNoiseSuppressionLevel(NoiseSuppression::Level level);
+ NoiseSuppression::Level getNoiseSuppressionLevel() const;
+
+ IEffect::Status lvmProcess(float* in, float* out, int samples);
+
+ private:
+ static constexpr inline int kAgcDefaultTargetLevel = 3;
+ static constexpr inline int kAgcDefaultCompGain = 9;
+ static constexpr inline bool kAgcDefaultLimiter = true;
+ static constexpr inline webrtc::AudioProcessing::Config::NoiseSuppression::Level
+ kNsDefaultLevel = webrtc::AudioProcessing::Config::NoiseSuppression::kModerate;
+
+ std::mutex mMutex;
+ const PreProcessingEffectType mType;
+ PreProcEffectState mState; // current state
+
+ // handle on webRTC audio processing module (APM)
+ rtc::scoped_refptr<webrtc::AudioProcessing> mAudioProcessingModule GUARDED_BY(mMutex);
+
+ int mEnabledMsk GUARDED_BY(mMutex); // bit field containing IDs of enabled pre processors
+ int mProcessedMsk GUARDED_BY(mMutex); // bit field containing IDs of pre processors already
+ // processed in current round
+ int mRevEnabledMsk GUARDED_BY(mMutex); // bit field containing IDs of enabled pre processors
+ // with reverse channel
+ int mRevProcessedMsk GUARDED_BY(mMutex); // bit field containing IDs of pre processors with
+ // reverse channel already processed in current round
+
+ webrtc::StreamConfig mInputConfig; // input stream configuration
+ webrtc::StreamConfig mOutputConfig; // output stream configuration
+
+ // Acoustic Echo Canceler
+ int mEchoDelayUs = 0;
+ bool mMobileMode = false;
+
+ // Automatic Gain Control V1
+ int mTargetPeakLevel = 0;
+ int mMaxCompressionGain = 0;
+ bool mEnableLimiter = false;
+
+ // Automatic Gain Control V2
+ int mDigitalGain = 0;
+ AutomaticGainControlV2::LevelEstimator mLevelEstimator =
+ AutomaticGainControlV2::LevelEstimator::RMS;
+ int mSaturationMargin = 2;
+
+ // NoiseSuppression
+ NoiseSuppression::Level mLevel = NoiseSuppression::Level::LOW;
+};
+
+} // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/preprocessing/aidl/PreProcessingSession.h b/media/libeffects/preprocessing/aidl/PreProcessingSession.h
new file mode 100644
index 0000000..877292f
--- /dev/null
+++ b/media/libeffects/preprocessing/aidl/PreProcessingSession.h
@@ -0,0 +1,119 @@
+/*
+ * 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 <algorithm>
+#include <memory>
+#include <unordered_map>
+
+#include <android-base/logging.h>
+#include <android-base/thread_annotations.h>
+
+#include "PreProcessingContext.h"
+#include "PreProcessingTypes.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+/**
+ * @brief Maintain all effect pre-processing sessions.
+ *
+ * Sessions are identified with the session ID, maximum of MAX_BUNDLE_SESSIONS is supported by the
+ * pre-processing implementation.
+ */
+class PreProcessingSession {
+ public:
+ static PreProcessingSession& getPreProcessingSession() {
+ static PreProcessingSession instance;
+ return instance;
+ }
+
+ static bool findPreProcessingTypeInList(
+ std::vector<std::shared_ptr<PreProcessingContext>>& list,
+ const PreProcessingEffectType& type, bool remove = false) {
+ auto itor = std::find_if(list.begin(), list.end(),
+ [type](const std::shared_ptr<PreProcessingContext>& bundle) {
+ return bundle->getPreProcessingType() == type;
+ });
+ if (itor == list.end()) {
+ return false;
+ }
+ if (remove) {
+ (*itor)->deInit();
+ list.erase(itor);
+ }
+ return true;
+ }
+
+ /**
+ * Create a certain type of PreProcessingContext in shared_ptr container, each session must not
+ * have more than one session for each type.
+ */
+ std::shared_ptr<PreProcessingContext> createSession(const PreProcessingEffectType& 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_PRE_PROC_SESSIONS) {
+ LOG(ERROR) << __func__ << " exceed max bundle session";
+ return nullptr;
+ }
+
+ if (mSessionMap.count(sessionId)) {
+ if (findPreProcessingTypeInList(mSessionMap[sessionId], type)) {
+ LOG(ERROR) << __func__ << type << " already exist in session " << sessionId;
+ return nullptr;
+ }
+ }
+
+ auto& list = mSessionMap[sessionId];
+ auto context = std::make_shared<PreProcessingContext>(statusDepth, common, type);
+ RETURN_VALUE_IF(!context, nullptr, "failedToCreateContext");
+
+ RetCode ret = context->init(common);
+ if (RetCode::SUCCESS != ret) {
+ LOG(ERROR) << __func__ << " context init ret " << ret;
+ return nullptr;
+ }
+ list.push_back(context);
+ return context;
+ }
+
+ void releaseSession(const PreProcessingEffectType& type, int sessionId) {
+ LOG(DEBUG) << __func__ << type << " sessionId " << sessionId;
+ std::lock_guard lg(mMutex);
+ if (mSessionMap.count(sessionId)) {
+ auto& list = mSessionMap[sessionId];
+ if (!findPreProcessingTypeInList(list, type, true /* remove */)) {
+ LOG(ERROR) << __func__ << " can't find " << type << "in session " << sessionId;
+ return;
+ }
+ if (list.empty()) {
+ mSessionMap.erase(sessionId);
+ }
+ }
+ }
+
+ private:
+ // Lock for mSessionMap access.
+ std::mutex mMutex;
+ // Max session number supported.
+ static constexpr int MAX_PRE_PROC_SESSIONS = 8;
+ std::unordered_map<int /* session ID */, std::vector<std::shared_ptr<PreProcessingContext>>>
+ mSessionMap GUARDED_BY(mMutex);
+};
+} // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/preprocessing/aidl/PreProcessingTypes.h b/media/libeffects/preprocessing/aidl/PreProcessingTypes.h
new file mode 100644
index 0000000..2c880d4
--- /dev/null
+++ b/media/libeffects/preprocessing/aidl/PreProcessingTypes.h
@@ -0,0 +1,111 @@
+/*
+ * 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 <audio_effects/effect_aec.h>
+#include <audio_effects/effect_agc.h>
+#include <audio_effects/effect_agc2.h>
+#include <audio_effects/effect_ns.h>
+
+#include "effect-impl/EffectTypes.h"
+#include "effect-impl/EffectUUID.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+// Acoustic Echo Cancellation
+static const std::string kAcousticEchoCancelerEffectName = "Acoustic Echo Canceler";
+static const std::vector<Range::AcousticEchoCancelerRange> kAcousticEchoCancelerRanges = {
+ MAKE_RANGE(AcousticEchoCanceler, AcousticEchoCanceler::echoDelayUs, 0, 500)};
+static const Capability kAcousticEchoCancelerCap = {.range = kAcousticEchoCancelerRanges};
+static const Descriptor kAcousticEchoCancelerDesc = {
+ .common = {.id = {.type = kAcousticEchoCancelerTypeUUID,
+ .uuid = kAcousticEchoCancelerSwImplUUID,
+ .proxy = kEffectNullUuid},
+ .flags = {.type = Flags::Type::PRE_PROC, .deviceIndication = true},
+ .name = kAcousticEchoCancelerEffectName,
+ .implementor = "The Android Open Source Project"},
+ .capability = kAcousticEchoCancelerCap};
+
+// Automatic Gain Control 1
+static const std::string kAutomaticGainControlV1EffectName = "Automatic Gain Control V1";
+static const std::vector<Range::AutomaticGainControlV1Range> kAutomaticGainControlV1Ranges = {
+ MAKE_RANGE(AutomaticGainControlV1, AutomaticGainControlV1::targetPeakLevelDbFs, -3100, 0),
+ MAKE_RANGE(AutomaticGainControlV1, AutomaticGainControlV1::maxCompressionGainDb, 0, 9000)};
+static const Capability kAutomaticGainControlV1Cap = {.range = kAutomaticGainControlV1Ranges};
+static const Descriptor kAutomaticGainControlV1Desc = {
+ .common = {.id = {.type = kAutomaticGainControlV1TypeUUID,
+ .uuid = kAutomaticGainControlV1SwImplUUID,
+ .proxy = kEffectNullUuid},
+ .flags = {.type = Flags::Type::PRE_PROC, .deviceIndication = true},
+ .name = kAutomaticGainControlV1EffectName,
+ .implementor = "The Android Open Source Project"},
+ .capability = kAutomaticGainControlV1Cap};
+
+// Automatic Gain Control 2
+static const std::string kAutomaticGainControlV2EffectName = "Automatic Gain Control V2";
+const std::vector<Range::AutomaticGainControlV2Range> kAutomaticGainControlV2Ranges = {
+ MAKE_RANGE(AutomaticGainControlV2, AutomaticGainControlV2::fixedDigitalGainMb, 0, 90),
+ // extra_staturation_margin_db is no longer configurable in webrtc
+ MAKE_RANGE(AutomaticGainControlV2, AutomaticGainControlV2::saturationMarginMb, 2, 2),
+ // WebRTC only supports RMS level estimator now
+ MAKE_RANGE(AutomaticGainControlV2, AutomaticGainControlV2::levelEstimator,
+ AutomaticGainControlV2::LevelEstimator::RMS,
+ AutomaticGainControlV2::LevelEstimator::RMS)};
+static const Capability kAutomaticGainControlV2Cap = {.range = kAutomaticGainControlV2Ranges};
+static const Descriptor kAutomaticGainControlV2Desc = {
+ .common = {.id = {.type = kAutomaticGainControlV2TypeUUID,
+ .uuid = kAutomaticGainControlV2SwImplUUID,
+ .proxy = kEffectNullUuid},
+ .flags = {.type = Flags::Type::PRE_PROC, .deviceIndication = true},
+ .name = kAutomaticGainControlV2EffectName,
+ .implementor = "The Android Open Source Project"},
+ .capability = kAutomaticGainControlV2Cap};
+
+// Noise suppression
+static const std::string kNoiseSuppressionEffectName = "Noise Suppression";
+static const Descriptor kNoiseSuppressionDesc = {
+ .common = {.id = {.type = kNoiseSuppressionTypeUUID,
+ .uuid = kNoiseSuppressionSwImplUUID,
+ .proxy = kEffectNullUuid},
+ .flags = {.type = Flags::Type::PRE_PROC, .deviceIndication = true},
+ .name = kNoiseSuppressionEffectName,
+ .implementor = "The Android Open Source Project"}};
+
+enum class PreProcessingEffectType {
+ ACOUSTIC_ECHO_CANCELLATION,
+ AUTOMATIC_GAIN_CONTROL_V1,
+ AUTOMATIC_GAIN_CONTROL_V2,
+ NOISE_SUPPRESSION,
+};
+
+inline std::ostream& operator<<(std::ostream& out, const PreProcessingEffectType& type) {
+ switch (type) {
+ case PreProcessingEffectType::ACOUSTIC_ECHO_CANCELLATION:
+ return out << kAcousticEchoCancelerEffectName;
+ case PreProcessingEffectType::AUTOMATIC_GAIN_CONTROL_V1:
+ return out << kAutomaticGainControlV1EffectName;
+ case PreProcessingEffectType::AUTOMATIC_GAIN_CONTROL_V2:
+ return out << kAutomaticGainControlV2EffectName;
+ case PreProcessingEffectType::NOISE_SUPPRESSION:
+ return out << kNoiseSuppressionEffectName;
+ }
+ return out << "EnumPreProcessingEffectTypeError";
+}
+
+} // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/visualizer/aidl/Visualizer.cpp b/media/libeffects/visualizer/aidl/Visualizer.cpp
index 28a7287..6e7833c 100644
--- a/media/libeffects/visualizer/aidl/Visualizer.cpp
+++ b/media/libeffects/visualizer/aidl/Visualizer.cpp
@@ -54,9 +54,16 @@
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 std::vector<Range::VisualizerRange> VisualizerImpl::kRanges = {
+ MAKE_RANGE(Visualizer, latencyMs, 0, VisualizerContext::kMaxLatencyMs),
+ MAKE_RANGE(Visualizer, captureSamples, 0, VisualizerContext::kMaxCaptureBufSize),
+ /* get only parameters, set invalid range (min > max) to indicate not support set */
+ MAKE_RANGE(Visualizer, measurement, Visualizer::Measurement({.peak = 1, .rms = 1}),
+ Visualizer::Measurement({.peak = 0, .rms = 0})),
+ MAKE_RANGE(Visualizer, captureSampleBuffer, std::vector<uint8_t>({1}),
+ std::vector<uint8_t>({0}))};
+const Capability VisualizerImpl::kCapability = {
+ .range = Range::make<Range::visualizer>(VisualizerImpl::kRanges)};
const Descriptor VisualizerImpl::kDescriptor = {
.common = {.id = {.type = kVisualizerTypeUUID,
.uuid = kVisualizerImplUUID,
@@ -66,7 +73,7 @@
.volume = Flags::Volume::CTRL},
.name = VisualizerImpl::kEffectName,
.implementor = "The Android Open Source Project"},
- .capability = Capability::make<Capability::visualizer>(VisualizerImpl::kCapability)};
+ .capability = VisualizerImpl::kCapability};
ndk::ScopedAStatus VisualizerImpl::getDescriptor(Descriptor* _aidl_return) {
RETURN_IF(!_aidl_return, EX_ILLEGAL_ARGUMENT, "Parameter:nullptr");
@@ -96,32 +103,13 @@
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>();
+ RETURN_IF(!inRange(param, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
const auto tag = param.getTag();
switch (tag) {
case Visualizer::captureSamples: {
@@ -142,8 +130,11 @@
EX_ILLEGAL_ARGUMENT, "setMeasurementModeFailed");
return ndk::ScopedAStatus::ok();
}
- case Visualizer::setOnlyParameters: {
- return setOnlyParameter(param.get<Visualizer::setOnlyParameters>());
+ case Visualizer::latencyMs: {
+ RETURN_IF(mContext->setDownstreamLatency(param.get<Visualizer::latencyMs>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setLatencyFailed");
+ return ndk::ScopedAStatus::ok();
}
default: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
@@ -153,30 +144,6 @@
}
}
-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");
@@ -188,9 +155,6 @@
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,
@@ -218,6 +182,18 @@
param.set<Visualizer::measurementMode>(mContext->getMeasurementMode());
break;
}
+ case Visualizer::measurement: {
+ param.set<Visualizer::measurement>(mContext->getMeasure());
+ break;
+ }
+ case Visualizer::captureSampleBuffer: {
+ param.set<Visualizer::captureSampleBuffer>(mContext->capture());
+ break;
+ }
+ case Visualizer::latencyMs: {
+ param.set<Visualizer::latencyMs>(mContext->getDownstreamLatency());
+ break;
+ }
default: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
diff --git a/media/libeffects/visualizer/aidl/Visualizer.h b/media/libeffects/visualizer/aidl/Visualizer.h
index 5908d9a..f6e1d6d 100644
--- a/media/libeffects/visualizer/aidl/Visualizer.h
+++ b/media/libeffects/visualizer/aidl/Visualizer.h
@@ -28,7 +28,7 @@
class VisualizerImpl final : public EffectImpl {
public:
static const std::string kEffectName;
- static const Visualizer::Capability kCapability;
+ static const Capability kCapability;
static const Descriptor kDescriptor;
VisualizerImpl() { LOG(DEBUG) << __func__; }
~VisualizerImpl() {
@@ -49,12 +49,10 @@
std::string getEffectName() override { return kEffectName; }
private:
+ static const std::vector<Range::VisualizerRange> kRanges;
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
index 1965e0e..5bf22f2 100644
--- a/media/libeffects/visualizer/aidl/VisualizerContext.cpp
+++ b/media/libeffects/visualizer/aidl/VisualizerContext.cpp
@@ -88,11 +88,6 @@
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;
}
@@ -122,16 +117,16 @@
}
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;
}
+int VisualizerContext::getDownstreamLatency() {
+ std::lock_guard lg(mMutex);
+ return mDownstreamLatency;
+}
+
uint32_t VisualizerContext::getDeltaTimeMsFromUpdatedTime_l() {
uint32_t deltaMs = 0;
if (mBufferUpdateTime.tv_sec != 0) {
@@ -149,7 +144,7 @@
return deltaMs;
}
-Visualizer::GetOnlyParameters::Measurement VisualizerContext::getMeasure() {
+Visualizer::Measurement VisualizerContext::getMeasure() {
uint16_t peakU16 = 0;
float sumRmsSquared = 0.0f;
uint8_t nbValidMeasurements = 0;
@@ -184,7 +179,7 @@
}
float rms = nbValidMeasurements == 0 ? 0.0f : sqrtf(sumRmsSquared / nbValidMeasurements);
- Visualizer::GetOnlyParameters::Measurement measure;
+ Visualizer::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));
@@ -196,9 +191,15 @@
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();
+ // cts android.media.audio.cts.VisualizerTest expecting silence data when effect not running
+ // RETURN_VALUE_IF(mState != State::ACTIVE, result, "illegalState");
+ if (mState != State::ACTIVE) {
+ result.resize(mCaptureSamples);
+ memset(result.data(), 0x80, mCaptureSamples);
+ return result;
+ }
+ 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) &&
diff --git a/media/libeffects/visualizer/aidl/VisualizerContext.h b/media/libeffects/visualizer/aidl/VisualizerContext.h
index bfda0b9..958035f 100644
--- a/media/libeffects/visualizer/aidl/VisualizerContext.h
+++ b/media/libeffects/visualizer/aidl/VisualizerContext.h
@@ -45,10 +45,11 @@
RetCode setScalingMode(Visualizer::ScalingMode mode);
Visualizer::ScalingMode getScalingMode();
RetCode setDownstreamLatency(int latency);
+ int getDownstreamLatency();
IEffect::Status process(float* in, float* out, int samples);
// Gets the current measurements, measured by process() and consumed by getParameter()
- Visualizer::GetOnlyParameters::Measurement getMeasure();
+ Visualizer::Measurement getMeasure();
// Gets the latest PCM capture, data captured by process() and consumed by getParameter()
std::vector<uint8_t> capture();
@@ -82,7 +83,7 @@
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
+ // capture buf with 8 bits mono PCM samples
std::array<uint8_t, kMaxCaptureBufSize> mCaptureBuf GUARDED_BY(mMutex);
uint32_t mDownstreamLatency GUARDED_BY(mMutex) = 0;
uint32_t mCaptureSamples GUARDED_BY(mMutex) = kMaxCaptureBufSize;
diff --git a/media/libmedia/IMediaRecorder.cpp b/media/libmedia/IMediaRecorder.cpp
index 154988d..e191999 100644
--- a/media/libmedia/IMediaRecorder.cpp
+++ b/media/libmedia/IMediaRecorder.cpp
@@ -428,7 +428,7 @@
return reply.readInt32();
}
- status_t getActiveMicrophones(std::vector<media::MicrophoneInfo>* activeMicrophones)
+ status_t getActiveMicrophones(std::vector<media::MicrophoneInfoFw>* activeMicrophones)
{
ALOGV("getActiveMicrophones");
Parcel data, reply;
@@ -756,7 +756,7 @@
case GET_ACTIVE_MICROPHONES: {
ALOGV("GET_ACTIVE_MICROPHONES");
CHECK_INTERFACE(IMediaRecorder, data, reply);
- std::vector<media::MicrophoneInfo> activeMicrophones;
+ std::vector<media::MicrophoneInfoFw> activeMicrophones;
status_t status = getActiveMicrophones(&activeMicrophones);
reply->writeInt32(status);
if (status != NO_ERROR) {
diff --git a/media/libmedia/MediaProfiles.cpp b/media/libmedia/MediaProfiles.cpp
index 85768bd..5aa9adc 100644
--- a/media/libmedia/MediaProfiles.cpp
+++ b/media/libmedia/MediaProfiles.cpp
@@ -898,10 +898,9 @@
}
}
- for (size_t cameraId = 0; cameraId < mCameraIds.size(); ++cameraId) {
+ for (size_t refIndex = 0; refIndex < mCameraIds.size(); ++refIndex) {
+ const int cameraId = mCameraIds[refIndex];
for (size_t j = 0; j < kNumRequiredProfiles; ++j) {
- int refIndex = getRequiredProfileRefIndex(cameraId);
- CHECK(refIndex != -1);
RequiredProfileRefInfo *info =
&mRequiredProfileRefs[refIndex].mRefs[j];
@@ -931,14 +930,14 @@
int index = getCamcorderProfileIndex(cameraId, profile->mQuality);
if (index != -1) {
- ALOGV("Profile quality %d for camera %zu already exists",
+ ALOGV("Profile quality %d for camera %d already exists",
profile->mQuality, cameraId);
CHECK(index == refIndex);
continue;
}
// Insert the new profile
- ALOGV("Add a profile: quality %d=>%d for camera %zu",
+ ALOGV("Add a profile: quality %d=>%d for camera %d",
mCamcorderProfiles[info->mRefProfileIndex]->mQuality,
profile->mQuality, cameraId);
diff --git a/media/libmedia/include/media/IMediaRecorder.h b/media/libmedia/include/media/IMediaRecorder.h
index 6e69782..05da5c2 100644
--- a/media/libmedia/include/media/IMediaRecorder.h
+++ b/media/libmedia/include/media/IMediaRecorder.h
@@ -18,8 +18,8 @@
#ifndef ANDROID_IMEDIARECORDER_H
#define ANDROID_IMEDIARECORDER_H
+#include <android/media/MicrophoneInfoFw.h>
#include <binder/IInterface.h>
-#include <media/MicrophoneInfo.h>
#include <system/audio.h>
#include <vector>
@@ -74,7 +74,7 @@
virtual status_t getRoutedDeviceId(audio_port_handle_t *deviceId) = 0;
virtual status_t enableAudioDeviceCallback(bool enabled) = 0;
virtual status_t getActiveMicrophones(
- std::vector<media::MicrophoneInfo>* activeMicrophones) = 0;
+ std::vector<media::MicrophoneInfoFw>* activeMicrophones) = 0;
virtual status_t setPreferredMicrophoneDirection(audio_microphone_direction_t direction) = 0;
virtual status_t setPreferredMicrophoneFieldDimension(float zoom) = 0;
virtual status_t getPortId(audio_port_handle_t *portId) = 0;
diff --git a/media/libmedia/include/media/MediaRecorderBase.h b/media/libmedia/include/media/MediaRecorderBase.h
index 2b7818d..82ec9c5 100644
--- a/media/libmedia/include/media/MediaRecorderBase.h
+++ b/media/libmedia/include/media/MediaRecorderBase.h
@@ -19,7 +19,6 @@
#define MEDIA_RECORDER_BASE_H_
#include <media/AudioSystem.h>
-#include <media/MicrophoneInfo.h>
#include <media/mediarecorder.h>
#include <android/content/AttributionSourceState.h>
@@ -74,7 +73,7 @@
virtual void setAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback>& callback) = 0;
virtual status_t enableAudioDeviceCallback(bool enabled) = 0;
virtual status_t getActiveMicrophones(
- std::vector<media::MicrophoneInfo>* activeMicrophones) = 0;
+ std::vector<media::MicrophoneInfoFw>* activeMicrophones) = 0;
virtual status_t setPreferredMicrophoneDirection(audio_microphone_direction_t direction) = 0;
virtual status_t setPreferredMicrophoneFieldDimension(float zoom) = 0;
virtual status_t getPortId(audio_port_handle_t *portId) const = 0;
diff --git a/media/libmedia/include/media/mediarecorder.h b/media/libmedia/include/media/mediarecorder.h
index dd18144..602f72e 100644
--- a/media/libmedia/include/media/mediarecorder.h
+++ b/media/libmedia/include/media/mediarecorder.h
@@ -24,7 +24,7 @@
#include <utils/Errors.h>
#include <media/IMediaRecorderClient.h>
#include <media/IMediaDeathNotifier.h>
-#include <media/MicrophoneInfo.h>
+#include <android/media/MicrophoneInfoFw.h>
#include <android/content/AttributionSourceState.h>
namespace android {
@@ -268,7 +268,7 @@
status_t setInputDevice(audio_port_handle_t deviceId);
status_t getRoutedDeviceId(audio_port_handle_t *deviceId);
status_t enableAudioDeviceCallback(bool enabled);
- status_t getActiveMicrophones(std::vector<media::MicrophoneInfo>* activeMicrophones);
+ status_t getActiveMicrophones(std::vector<media::MicrophoneInfoFw>* activeMicrophones);
status_t setPreferredMicrophoneDirection(audio_microphone_direction_t direction);
status_t setPreferredMicrophoneFieldDimension(float zoom);
diff --git a/media/libmedia/mediarecorder.cpp b/media/libmedia/mediarecorder.cpp
index cf12c36..bd06fb6 100644
--- a/media/libmedia/mediarecorder.cpp
+++ b/media/libmedia/mediarecorder.cpp
@@ -884,7 +884,8 @@
return mMediaRecorder->enableAudioDeviceCallback(enabled);
}
-status_t MediaRecorder::getActiveMicrophones(std::vector<media::MicrophoneInfo>* activeMicrophones)
+status_t MediaRecorder::getActiveMicrophones(
+ std::vector<media::MicrophoneInfoFw>* activeMicrophones)
{
ALOGV("getActiveMicrophones");
diff --git a/media/libmediaplayerservice/MediaRecorderClient.cpp b/media/libmediaplayerservice/MediaRecorderClient.cpp
index 4aa80be..58fc06d 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.cpp
+++ b/media/libmediaplayerservice/MediaRecorderClient.cpp
@@ -563,7 +563,7 @@
}
status_t MediaRecorderClient::getActiveMicrophones(
- std::vector<media::MicrophoneInfo>* activeMicrophones) {
+ std::vector<media::MicrophoneInfoFw>* activeMicrophones) {
ALOGV("getActiveMicrophones");
Mutex::Autolock lock(mLock);
if (mRecorder != NULL) {
diff --git a/media/libmediaplayerservice/MediaRecorderClient.h b/media/libmediaplayerservice/MediaRecorderClient.h
index dcb9f82..dec0c99 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.h
+++ b/media/libmediaplayerservice/MediaRecorderClient.h
@@ -83,7 +83,7 @@
virtual status_t getRoutedDeviceId(audio_port_handle_t* deviceId);
virtual status_t enableAudioDeviceCallback(bool enabled);
virtual status_t getActiveMicrophones(
- std::vector<media::MicrophoneInfo>* activeMicrophones);
+ std::vector<media::MicrophoneInfoFw>* activeMicrophones);
virtual status_t setPreferredMicrophoneDirection(audio_microphone_direction_t direction);
virtual status_t setPreferredMicrophoneFieldDimension(float zoom);
status_t getPortId(audio_port_handle_t *portId) override;
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index a0bc8ca..18bbf7b 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -2560,7 +2560,7 @@
}
status_t StagefrightRecorder::getActiveMicrophones(
- std::vector<media::MicrophoneInfo>* activeMicrophones) {
+ std::vector<media::MicrophoneInfoFw>* activeMicrophones) {
if (mAudioSourceNode != 0) {
return mAudioSourceNode->getActiveMicrophones(activeMicrophones);
}
diff --git a/media/libmediaplayerservice/StagefrightRecorder.h b/media/libmediaplayerservice/StagefrightRecorder.h
index d7785da..67c6e20 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.h
+++ b/media/libmediaplayerservice/StagefrightRecorder.h
@@ -83,7 +83,7 @@
virtual status_t getRoutedDeviceId(audio_port_handle_t* deviceId);
virtual void setAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback>& callback);
virtual status_t enableAudioDeviceCallback(bool enabled);
- virtual status_t getActiveMicrophones(std::vector<media::MicrophoneInfo>* activeMicrophones);
+ virtual status_t getActiveMicrophones(std::vector<media::MicrophoneInfoFw>* activeMicrophones);
virtual status_t setPreferredMicrophoneDirection(audio_microphone_direction_t direction);
virtual status_t setPreferredMicrophoneFieldDimension(float zoom);
status_t getPortId(audio_port_handle_t *portId) const override;
diff --git a/media/libmediaplayerservice/fuzzer/mediarecorder_fuzzer.cpp b/media/libmediaplayerservice/fuzzer/mediarecorder_fuzzer.cpp
index b0040fe..43b3c37 100644
--- a/media/libmediaplayerservice/fuzzer/mediarecorder_fuzzer.cpp
+++ b/media/libmediaplayerservice/fuzzer/mediarecorder_fuzzer.cpp
@@ -193,7 +193,7 @@
mStfRecorder->setInputDevice(deviceId);
mStfRecorder->getRoutedDeviceId(&deviceId);
- vector<android::media::MicrophoneInfo> activeMicrophones{};
+ vector<android::media::MicrophoneInfoFw> activeMicrophones{};
mStfRecorder->getActiveMicrophones(&activeMicrophones);
int32_t portId;
diff --git a/media/libmediaplayerservice/tests/stagefrightRecorder/StagefrightRecorderTest.cpp b/media/libmediaplayerservice/tests/stagefrightRecorder/StagefrightRecorderTest.cpp
index 162c187..9514021 100644
--- a/media/libmediaplayerservice/tests/stagefrightRecorder/StagefrightRecorderTest.cpp
+++ b/media/libmediaplayerservice/tests/stagefrightRecorder/StagefrightRecorderTest.cpp
@@ -286,7 +286,7 @@
// Record media for 4 secs
std::this_thread::sleep_for(std::chrono::seconds(kClipDurationInSec));
- std::vector<media::MicrophoneInfo> activeMicrophones{};
+ std::vector<media::MicrophoneInfoFw> activeMicrophones{};
status = mStfRecorder->getActiveMicrophones(&activeMicrophones);
ASSERT_EQ(status, OK) << "Failed to get Active Microphones";
ASSERT_GT(activeMicrophones.size(), 0) << "No active microphones are found";
diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp
index bfe8538..584dad6 100644
--- a/media/libstagefright/AudioSource.cpp
+++ b/media/libstagefright/AudioSource.cpp
@@ -522,7 +522,7 @@
}
status_t AudioSource::getActiveMicrophones(
- std::vector<media::MicrophoneInfo>* activeMicrophones) {
+ std::vector<media::MicrophoneInfoFw>* activeMicrophones) {
if (mRecord != 0) {
return mRecord->getActiveMicrophones(activeMicrophones);
}
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index ebbbb5f..cdfd2dd 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -88,6 +88,7 @@
using aidl::android::media::BnResourceManagerClient;
using aidl::android::media::IResourceManagerClient;
using aidl::android::media::IResourceManagerService;
+using aidl::android::media::ClientInfoParcel;
// key for media statistics
static const char *kCodecKeyName = "codec";
@@ -209,8 +210,8 @@
////////////////////////////////////////////////////////////////////////////////
struct ResourceManagerClient : public BnResourceManagerClient {
- explicit ResourceManagerClient(MediaCodec* codec, int32_t pid) :
- mMediaCodec(codec), mPid(pid) {}
+ explicit ResourceManagerClient(MediaCodec* codec, int32_t pid, int32_t uid) :
+ mMediaCodec(codec), mPid(pid), mUid(uid) {}
Status reclaimResource(bool* _aidl_return) override {
sp<MediaCodec> codec = mMediaCodec.promote();
@@ -222,7 +223,10 @@
if (service == nullptr) {
ALOGW("MediaCodec::ResourceManagerClient unable to find ResourceManagerService");
}
- service->removeClient(mPid, getId(this));
+ ClientInfoParcel clientInfo{.pid = static_cast<int32_t>(mPid),
+ .uid = static_cast<int32_t>(mUid),
+ .id = getId(this)};
+ service->removeClient(clientInfo);
*_aidl_return = true;
return Status::ok();
}
@@ -260,6 +264,7 @@
private:
wp<MediaCodec> mMediaCodec;
int32_t mPid;
+ int32_t mUid;
DISALLOW_EVIL_CONSTRUCTORS(ResourceManagerClient);
};
@@ -285,10 +290,15 @@
void markClientForPendingRemoval();
bool reclaimResource(const std::vector<MediaResourceParcel> &resources);
+ inline void setCodecName(const char* name) {
+ mCodecName = name;
+ }
+
private:
Mutex mLock;
pid_t mPid;
uid_t mUid;
+ std::string mCodecName;
std::shared_ptr<IResourceManagerService> mService;
std::shared_ptr<IResourceManagerClient> mClient;
::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
@@ -392,7 +402,11 @@
if (mService == nullptr) {
return;
}
- mService->addResource(mPid, mUid, getId(mClient), mClient, resources);
+ ClientInfoParcel clientInfo{.pid = static_cast<int32_t>(mPid),
+ .uid = static_cast<int32_t>(mUid),
+ .id = getId(mClient),
+ .name = mCodecName};
+ mService->addResource(clientInfo, mClient, resources);
}
void MediaCodec::ResourceManagerServiceProxy::removeResource(
@@ -404,7 +418,11 @@
if (mService == nullptr) {
return;
}
- mService->removeResource(mPid, getId(mClient), resources);
+ ClientInfoParcel clientInfo{.pid = static_cast<int32_t>(mPid),
+ .uid = static_cast<int32_t>(mUid),
+ .id = getId(mClient),
+ .name = mCodecName};
+ mService->removeResource(clientInfo, resources);
}
void MediaCodec::ResourceManagerServiceProxy::removeClient() {
@@ -412,7 +430,11 @@
if (mService == nullptr) {
return;
}
- mService->removeClient(mPid, getId(mClient));
+ ClientInfoParcel clientInfo{.pid = static_cast<int32_t>(mPid),
+ .uid = static_cast<int32_t>(mUid),
+ .id = getId(mClient),
+ .name = mCodecName};
+ mService->removeClient(clientInfo);
}
void MediaCodec::ResourceManagerServiceProxy::markClientForPendingRemoval() {
@@ -420,7 +442,11 @@
if (mService == nullptr) {
return;
}
- mService->markClientForPendingRemoval(mPid, getId(mClient));
+ ClientInfoParcel clientInfo{.pid = static_cast<int32_t>(mPid),
+ .uid = static_cast<int32_t>(mUid),
+ .id = getId(mClient),
+ .name = mCodecName};
+ mService->markClientForPendingRemoval(clientInfo);
}
bool MediaCodec::ResourceManagerServiceProxy::reclaimResource(
@@ -430,7 +456,11 @@
return false;
}
bool success;
- Status status = mService->reclaimResource(mPid, resources, &success);
+ ClientInfoParcel clientInfo{.pid = static_cast<int32_t>(mPid),
+ .uid = static_cast<int32_t>(mUid),
+ .id = getId(mClient),
+ .name = mCodecName};
+ Status status = mService->reclaimResource(clientInfo, resources, &success);
return status.isOk() && success;
}
@@ -835,7 +865,7 @@
mGetCodecBase(getCodecBase),
mGetCodecInfo(getCodecInfo) {
mResourceManagerProxy = new ResourceManagerServiceProxy(pid, uid,
- ::ndk::SharedRefBase::make<ResourceManagerClient>(this, pid));
+ ::ndk::SharedRefBase::make<ResourceManagerClient>(this, pid, uid));
if (!mGetCodecBase) {
mGetCodecBase = [](const AString &name, const char *owner) {
return GetCodecBase(name, owner);
@@ -1606,6 +1636,11 @@
std::vector<MediaResourceParcel> resources;
resources.push_back(MediaResource::CodecResource(secureCodec, toMediaResourceSubType(mDomain)));
+
+ // If the ComponentName is not set yet, use the name passed by the user.
+ if (mComponentName.empty()) {
+ mResourceManagerProxy->setCodecName(name.c_str());
+ }
for (int i = 0; i <= kMaxRetry; ++i) {
if (i > 0) {
// Don't try to reclaim resource for the first time.
@@ -3387,6 +3422,8 @@
if (mComponentName.c_str()) {
mediametrics_setCString(mMetricsHandle, kCodecCodec,
mComponentName.c_str());
+ // Update the codec name.
+ mResourceManagerProxy->setCodecName(mComponentName.c_str());
}
const char *owner = mCodecInfo ? mCodecInfo->getOwnerName() : "";
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index c5b5199..863177d 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -798,6 +798,8 @@
{ "dvb-audio-description", kKeyDvbAudioDescription},
{ "dvb-teletext-magazine-number", kKeyDvbTeletextMagazineNumber},
{ "dvb-teletext-page-number", kKeyDvbTeletextPageNumber},
+ { "profile", kKeyAudioProfile },
+ { "level", kKeyAudioLevel },
}
};
diff --git a/media/libstagefright/include/media/stagefright/AudioSource.h b/media/libstagefright/include/media/stagefright/AudioSource.h
index 5e84977..65d5246 100644
--- a/media/libstagefright/include/media/stagefright/AudioSource.h
+++ b/media/libstagefright/include/media/stagefright/AudioSource.h
@@ -21,7 +21,6 @@
#include <media/AudioRecord.h>
#include <media/AudioSystem.h>
#include <media/stagefright/MediaSource.h>
-#include <media/MicrophoneInfo.h>
#include <media/stagefright/MediaBuffer.h>
#include <utils/List.h>
@@ -83,7 +82,7 @@
status_t addAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback>& callback);
status_t removeAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback>& callback);
- status_t getActiveMicrophones(std::vector<media::MicrophoneInfo>* activeMicrophones);
+ status_t getActiveMicrophones(std::vector<media::MicrophoneInfoFw>* activeMicrophones);
status_t setPreferredMicrophoneDirection(audio_microphone_direction_t direction);
status_t setPreferredMicrophoneFieldDimension(float zoom);
diff --git a/media/libstagefright/include/media/stagefright/MetaDataBase.h b/media/libstagefright/include/media/stagefright/MetaDataBase.h
index 33f224c..80a1170 100644
--- a/media/libstagefright/include/media/stagefright/MetaDataBase.h
+++ b/media/libstagefright/include/media/stagefright/MetaDataBase.h
@@ -117,6 +117,12 @@
kKeyVideoProfile = 'vprf', // int32_t
kKeyVideoLevel = 'vlev', // int32_t
+ // audio profile and level
+ // The codec framework doesn't distinguish between video and audio profiles,
+ // so there is no need to define a separate key
+ kKeyAudioProfile = 'vprf', // int32_t
+ kKeyAudioLevel = 'vlev', // int32_t
+
kKey2ByteNalLength = '2NAL', // int32_t (bool)
// Identify the file output format for authoring
diff --git a/media/libstagefright/webm/WebmFrameThread.cpp b/media/libstagefright/webm/WebmFrameThread.cpp
index 59ce8db..cdbd745 100644
--- a/media/libstagefright/webm/WebmFrameThread.cpp
+++ b/media/libstagefright/webm/WebmFrameThread.cpp
@@ -197,7 +197,6 @@
}
status_t WebmFrameSinkThread::stop() {
- mDone = true;
mVideoFrames.push(WebmFrame::EOS);
mAudioFrames.push(WebmFrame::EOS);
return WebmFrameThread::stop();
diff --git a/media/module/extractors/ogg/OggExtractor.cpp b/media/module/extractors/ogg/OggExtractor.cpp
index 1c6f516..4c106b2 100644
--- a/media/module/extractors/ogg/OggExtractor.cpp
+++ b/media/module/extractors/ogg/OggExtractor.cpp
@@ -34,6 +34,9 @@
#include <system/audio.h>
#include <utils/String8.h>
+#include <inttypes.h>
+#include <stdint.h>
+
extern "C" {
#include <Tremolo/codec_internal.h>
@@ -346,66 +349,118 @@
off64_t startOffset, off64_t *pageOffset) {
*pageOffset = startOffset;
- for (;;) {
- char signature[4];
- ssize_t n = mSource->readAt(*pageOffset, &signature, 4);
+ // balance between larger reads and reducing how much we over-read.
+ const int FIND_BUF_SIZE = 2048;
+ const int lenOggS = strlen("OggS");
+ while(1) {
- if (n < 4) {
+ // work with big buffers to amortize readAt() costs
+ char signatureBuffer[FIND_BUF_SIZE];
+ ssize_t n = mSource->readAt(*pageOffset, &signatureBuffer, sizeof(signatureBuffer));
+
+ if (n < lenOggS) {
*pageOffset = 0;
-
return (n < 0) ? n : (status_t)ERROR_END_OF_STREAM;
}
- if (!memcmp(signature, "OggS", 4)) {
- if (*pageOffset > startOffset) {
- ALOGV("skipped %lld bytes of junk to reach next frame",
- (long long)(*pageOffset - startOffset));
- }
-
- return OK;
- }
-
- // see how far ahead to skip; avoid some fruitless comparisons
- unsigned int i;
- for (i = 1; i < 4 ; i++) {
- if (signature[i] == 'O')
+ for(int i = 0; i < n - (lenOggS - 1) ; i++) {
+ // fast scan for 1st character in a signature
+ char *p = (char *)memchr(&signatureBuffer[i], 'O', n - (lenOggS - 1) - i);
+ if (p == NULL) {
+ // no signature start in the rest of this buffer.
break;
+ }
+ int jump = (p-&signatureBuffer[i]);
+ i += jump;
+ if (memcmp("OggS", &signatureBuffer[i], lenOggS) == 0) {
+ *pageOffset += i;
+ if (*pageOffset > startOffset) {
+ ALOGD("skipped %" PRIu64 " bytes of junk to reach next frame",
+ (*pageOffset - startOffset));
+ }
+ return OK;
+ }
}
- *pageOffset += i;
+
+ // on to next block. buffer didn't end with "OggS", but could end with "Ogg".
+ // overlap enough to detect this. n >= lenOggS, so this always advances.
+ *pageOffset += n - (lenOggS - 1);
}
+ return (status_t)ERROR_END_OF_STREAM;
}
// Given the offset of the "current" page, find the page immediately preceding
// it (if any) and return its granule position.
// To do this we back up from the "current" page's offset until we find any
// page preceding it and then scan forward to just before the current page.
+//
status_t MyOggExtractor::findPrevGranulePosition(
off64_t pageOffset, uint64_t *granulePos) {
*granulePos = 0;
- off64_t prevPageOffset = 0;
- off64_t prevGuess = pageOffset;
- for (;;) {
- if (prevGuess >= 5000) {
- prevGuess -= 5000;
+ const int FIND_BUF_SIZE = 2048;
+ const int lenOggS = strlen("OggS");
+
+ if (pageOffset == 0) {
+ ALOGV("no page before the first page");
+ return UNKNOWN_ERROR;
+ }
+
+ off64_t prevPageOffset = pageOffset;
+
+ // we start our search on the byte immediately in front of pageOffset
+ // which could mean "O" immediately before and "ggS" starting at pageOffset
+ //
+ // if there was an "OggS" at pageOffset, we'll have scanned a few extra bytes
+ // but if pageOffset was chosen by a seek operation, we don't know that it
+ // reflects the beginning of a page. By choosing to scan 3 possibly unneeded
+ // bytes at the start we cover both cases.
+ //
+ off64_t firstAfter = pageOffset + lenOggS - 1; // NOT within our buffer
+ off64_t nextOffset = pageOffset;
+
+ while(prevPageOffset == pageOffset) {
+ // work with big buffers to amortize readAt() costs
+ char signatureBuffer[FIND_BUF_SIZE];
+
+ ssize_t desired = sizeof(signatureBuffer);
+ if (firstAfter >= desired) {
+ nextOffset = firstAfter - desired;
} else {
- prevGuess = 0;
+ nextOffset = 0;
+ desired = firstAfter;
}
+ ssize_t n = mSource->readAt(nextOffset, &signatureBuffer, desired);
- ALOGV("backing up %lld bytes", (long long)(pageOffset - prevGuess));
-
- status_t err = findNextPage(prevGuess, &prevPageOffset);
- if (err == ERROR_END_OF_STREAM) {
- // We are at the last page and didn't back off enough;
- // back off 5000 bytes more and try again.
- continue;
- } else if (err != OK) {
- return err;
- }
-
- if (prevPageOffset < pageOffset || prevGuess == 0) {
+ if (n < lenOggS) {
+ ALOGD("short read, get out");
break;
}
+
+ // work backwards
+ // loop control ok for n >= 0
+ for(int i = n - lenOggS; i >= 0 ; i--) {
+ // fast scan for 1st character in the signature
+ char *p = (char *)memrchr(&signatureBuffer[0], 'O', i);
+ if (p == NULL) {
+ // no signature start in the rest of this buffer.
+ break;
+ }
+ i = (p-&signatureBuffer[0]);
+ // loop start chosen to ensure we will always have lenOggS bytes
+ if (memcmp("OggS", &signatureBuffer[i], lenOggS) == 0) {
+ prevPageOffset = nextOffset + i;
+ break;
+ }
+ }
+
+ // back up for next read; make sure we catch overlaps
+ if (nextOffset == 0) {
+ // can't back up any further
+ break;
+ }
+ // current buffer might start with "ggS", include those bytes in the next iteration
+ firstAfter = nextOffset + lenOggS - 1;
}
if (prevPageOffset == pageOffset) {
@@ -413,8 +468,8 @@
return UNKNOWN_ERROR;
}
- ALOGV("prevPageOffset at %lld, pageOffset at %lld",
- (long long)prevPageOffset, (long long)pageOffset);
+ ALOGV("prevPageOffset at %" PRIu64 ", pageOffset at %" PRIu64,
+ prevPageOffset, pageOffset);
uint8_t flag = 0;
for (;;) {
Page prevPage;
@@ -993,16 +1048,21 @@
size_t numerator = mTableOfContents.size();
if (numerator > kMaxNumTOCEntries) {
- size_t denom = numerator - kMaxNumTOCEntries;
+ Vector<TOCEntry> maxTOC;
+ maxTOC.setCapacity(kMaxNumTOCEntries);
+ size_t denom = numerator - kMaxNumTOCEntries;
size_t accum = 0;
- for (ssize_t i = mTableOfContents.size(); i > 0; --i) {
+ for (ssize_t i = 0; i < mTableOfContents.size(); i++) {
accum += denom;
if (accum >= numerator) {
- mTableOfContents.removeAt(i);
accum -= numerator;
+ } else {
+ maxTOC.push(mTableOfContents.itemAt(i));
}
}
+
+ mTableOfContents = maxTOC;
}
}
diff --git a/media/module/foundation/MediaDefs.cpp b/media/module/foundation/MediaDefs.cpp
index 4a75f90..7abab63 100644
--- a/media/module/foundation/MediaDefs.cpp
+++ b/media/module/foundation/MediaDefs.cpp
@@ -72,6 +72,7 @@
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_HD_MA = "audio/vnd.dts.hd;profile=dtsma";
+const char *MEDIA_MIMETYPE_AUDIO_DTS_UHD = "audio/vnd.dts.uhd";
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";
diff --git a/media/module/foundation/include/media/stagefright/foundation/MediaDefs.h b/media/module/foundation/include/media/stagefright/foundation/MediaDefs.h
index 740336a..05ee7fc 100644
--- a/media/module/foundation/include/media/stagefright/foundation/MediaDefs.h
+++ b/media/module/foundation/include/media/stagefright/foundation/MediaDefs.h
@@ -74,6 +74,7 @@
extern const char *MEDIA_MIMETYPE_AUDIO_DTS;
extern const char *MEDIA_MIMETYPE_AUDIO_DTS_HD;
extern const char *MEDIA_MIMETYPE_AUDIO_DTS_HD_MA;
+extern const char *MEDIA_MIMETYPE_AUDIO_DTS_UHD;
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;
diff --git a/media/module/mpeg2ts/ATSParser.cpp b/media/module/mpeg2ts/ATSParser.cpp
index 1482072..6aeea3b 100644
--- a/media/module/mpeg2ts/ATSParser.cpp
+++ b/media/module/mpeg2ts/ATSParser.cpp
@@ -556,7 +556,15 @@
if (descriptor_length > ES_info_length) {
return ERROR_MALFORMED;
}
- if (descriptor_tag == DESCRIPTOR_CA && descriptor_length >= 4) {
+
+ // The DTS descriptor is used in the PSI PMT to identify streams which carry
+ // DTS audio(core only). If a DTS descriptor is present, a DTS-HD or DTS-UHD
+ // descriptors shall not be present in the same ES_info descriptor loop.
+ if (descriptor_tag == DESCRIPTOR_DTS) {
+ info.mType = STREAMTYPE_DTS;
+ ES_info_length -= descriptor_length;
+ br->skipBits(descriptor_length * 8);
+ } else if (descriptor_tag == DESCRIPTOR_CA && descriptor_length >= 4) {
hasStreamCA = true;
streamCA.mSystemID = br->getBits(16);
streamCA.mPID = br->getBits(16) & 0x1fff;
@@ -575,6 +583,16 @@
if (descTagExt == EXT_DESCRIPTOR_DVB_AC4) {
info.mTypeExt = EXT_DESCRIPTOR_DVB_AC4;
br->skipBits(descriptor_length * 8);
+ } else if (descTagExt == EXT_DESCRIPTOR_DVB_DTS_HD) {
+ // DTS HD extended descriptor which can accommodate core only formats
+ // as well as extension only and core + extension combinations.
+ info.mTypeExt = EXT_DESCRIPTOR_DVB_DTS_HD;
+ br->skipBits(descriptor_length * 8);
+ } else if (descTagExt == EXT_DESCRIPTOR_DVB_DTS_UHD) {
+ // The DTS-UHD descriptor is used in the PSI PMT to identify streams
+ // which carry DTS-UHD audio
+ info.mTypeExt = EXT_DESCRIPTOR_DVB_DTS_UHD;
+ br->skipBits(descriptor_length * 8);
} else if (descTagExt == EXT_DESCRIPTOR_DVB_AUDIO_PRESELECTION &&
descriptor_length >= 1) {
// DVB BlueBook A038 Table 110
@@ -920,9 +938,17 @@
mode = ElementaryStreamQueue::EAC3;
break;
+ case STREAMTYPE_DTS:
+ mode = ElementaryStreamQueue::DTS;
+ break;
+
case STREAMTYPE_PES_PRIVATE_DATA:
if (mStreamTypeExt == EXT_DESCRIPTOR_DVB_AC4) {
mode = ElementaryStreamQueue::AC4;
+ } else if (mStreamTypeExt == EXT_DESCRIPTOR_DVB_DTS_HD) {
+ mode = ElementaryStreamQueue::DTS_HD;
+ } else if (mStreamTypeExt == EXT_DESCRIPTOR_DVB_DTS_UHD) {
+ mode = ElementaryStreamQueue::DTS_UHD;
}
break;
@@ -1158,9 +1184,12 @@
case STREAMTYPE_EAC3:
case STREAMTYPE_AAC_ENCRYPTED:
case STREAMTYPE_AC3_ENCRYPTED:
+ case STREAMTYPE_DTS:
return true;
case STREAMTYPE_PES_PRIVATE_DATA:
- return mStreamTypeExt == EXT_DESCRIPTOR_DVB_AC4;
+ return (mStreamTypeExt == EXT_DESCRIPTOR_DVB_AC4
+ || mStreamTypeExt == EXT_DESCRIPTOR_DVB_DTS_HD
+ || mStreamTypeExt == EXT_DESCRIPTOR_DVB_DTS_UHD);
default:
return false;
diff --git a/media/module/mpeg2ts/ESQueue.cpp b/media/module/mpeg2ts/ESQueue.cpp
index 192ba77..2dc7b0a 100644
--- a/media/module/mpeg2ts/ESQueue.cpp
+++ b/media/module/mpeg2ts/ESQueue.cpp
@@ -362,6 +362,436 @@
return OK;
}
+#define RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bitstream, size) \
+ do { \
+ if ((bitstream).numBitsLeft() < (size)) { \
+ ALOGE("Not enough bits left for further parsing"); \
+ return ERROR_MALFORMED; } \
+ } while (0)
+
+// Parse DTS Digital Surround and DTS Express(LBR) stream header
+static status_t parseDTSHDSyncFrame(
+ const uint8_t *ptr, size_t size, unsigned &frameSize, sp<MetaData> *metaData) {
+ static const unsigned channelCountTable[] = {1, 2, 2, 2, 2, 3, 3, 4,
+ 4, 5, 6, 6, 6, 7, 8, 8};
+ static const unsigned samplingRateTableCoreSS[] = {0, 8000, 16000, 32000, 0, 0, 11025, 22050,
+ 44100, 0, 0, 12000, 24000, 48000, 0, 0};
+ static const unsigned samplingRateTableExtSS[] = {8000, 16000, 32000, 64000, 128000,
+ 22050, 44100, 88200, 176400, 352800,
+ 12000, 24000, 48000, 96000, 192000, 384000};
+
+ const uint32_t DTSHD_SYNC_CORE_16BIT_BE = 0x7ffe8001;
+ const uint32_t DTSHD_SYNC_EXSS_16BIT_BE = 0x64582025;
+
+ uint32_t numChannels = 0, samplingRate = 0;
+ bool isLBR = false;
+
+ ABitReader bits(ptr, size);
+
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, 32);
+ uint32_t dtshdSyncWord = bits.getBits(32);
+
+ // Expecting DTS Digital Surround or DTS Express(LBR) streams only
+ if (dtshdSyncWord == DTSHD_SYNC_CORE_16BIT_BE) { // DTS Digital Surround Header
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, (1 + 5 + 1 + 7 + 14 + 6 + 4 + 15 + 2));
+
+ // FTYPE, SHORT, CRC, NBLKS
+ bits.skipBits(1 + 5 + 1 + 7);
+
+ frameSize = bits.getBits(14) + 1;
+ uint32_t amode = bits.getBits(6);
+ uint32_t freqIndex = bits.getBits(4);
+
+ // RATE, FIXEDBIT, DYNF, TIMEF, AUXF, HDCD, EXT_AUDIO_ID, EXT_AUDIO, ASPF
+ bits.skipBits(5 + 1 + 1 + 1 + 1 + 1 + 3 + 1 + 1);
+
+ uint32_t lfeFlag = bits.getBits(2);
+ numChannels = (amode <= 15) ? channelCountTable[amode] : 0;
+ numChannels += ((lfeFlag == 1) || (lfeFlag == 2)) ? 1 : 0;
+ samplingRate = (freqIndex <= 15) ? samplingRateTableCoreSS[freqIndex] : 0;
+
+ isLBR = false;
+ } else if (dtshdSyncWord == DTSHD_SYNC_EXSS_16BIT_BE) { // DTS Express(LBR) Header
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, (8 + 2 + 1));
+
+ uint32_t extHeadersize, extSSFsize;
+ uint32_t numAudioPresent = 1, numAssets = 1;
+ uint32_t nuActiveExSSMask[8];
+
+ // userDefinedBits
+ bits.skipBits(8);
+
+ uint32_t extSSIndex = bits.getBits(2);
+ uint32_t headerSizeType = bits.getBits(1);
+
+ if (headerSizeType == 0) {
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, (8 + 16));
+
+ extHeadersize = bits.getBits(8) + 1;
+ extSSFsize = bits.getBits(16) + 1;
+ } else {
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, (12 + 20));
+
+ extHeadersize = bits.getBits(12) + 1;
+ extSSFsize = bits.getBits(20) + 1;
+ }
+
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, (1));
+
+ uint32_t staticFieldsPresent = bits.getBits(1);
+
+ if (staticFieldsPresent) {
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, (2 + 3 + 1));
+
+ // nuRefClockCode, nuExSSFrameDurationCode
+ bits.skipBits(2 + 3);
+
+ if (bits.getBits(1)) {
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, (32 + 4));
+
+ bits.skipBits(32 + 4);
+ }
+
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, (3 + 3));
+
+ // numAudioPresent, numAssets
+ bits.skipBits(3 + 3);
+
+ for (uint32_t nAuPr = 0; nAuPr < numAudioPresent; nAuPr++) {
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, (extSSIndex + 1));
+
+ nuActiveExSSMask[nAuPr] = bits.getBits(extSSIndex + 1);
+ }
+
+ for (uint32_t nAuPr = 0; nAuPr < numAudioPresent; nAuPr++) {
+ for (uint32_t nSS = 0; nSS < extSSIndex + 1; nSS++) {
+ if (((nuActiveExSSMask[nAuPr] >> nSS) & 0x1) == 1) {
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, 8);
+
+ // nuActiveAssetMask
+ bits.skipBits(8);
+ }
+ }
+ }
+
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, 1);
+
+ // bMixMetadataEnbl
+ if (bits.getBits(1)) {
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, (2 + 2 + 2));
+
+ // nuMixMetadataAdjLevel
+ bits.skipBits(2);
+
+ uint32_t bits4MixOutMask = (bits.getBits(2) + 1) << 2;
+ uint32_t numMixOutConfigs = bits.getBits(2) + 1;
+
+ for (int ns = 0; ns < numMixOutConfigs; ns++) {
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, bits4MixOutMask);
+
+ // nuMixOutChMask
+ bits.skipBits(bits4MixOutMask);
+ }
+ }
+ }
+
+ for (int nAst = 0; nAst < numAssets; nAst++) {
+ int bits4ExSSFsize = (headerSizeType == 0) ? 16 : 20;
+
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, bits4ExSSFsize);
+
+ bits.skipBits(bits4ExSSFsize);
+ }
+
+ /* Asset descriptor */
+ for (int nAst = 0; nAst < numAssets; nAst++) {
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, (9 + 3));
+
+ // nuAssetDescriptFsize, nuAssetIndex
+ bits.skipBits(9 + 3);
+
+ if (staticFieldsPresent) {
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, 1);
+
+ // bAssetTypeDescrPresent
+ if (bits.getBits(1)) {
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, 4);
+
+ // nuAssetTypeDescriptor
+ bits.skipBits(4);
+ }
+
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, 1);
+
+ // bLanguageDescrPresent
+ if (bits.getBits(1)) {
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, 24);
+
+ // LanguageDescriptor
+ bits.skipBits(24);
+ }
+
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, 1);
+
+ // bInfoTextPresent
+ if (bits.getBits(1)) {
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, 10);
+
+ uint32_t nuInfoTextByteSize = bits.getBits(10) + 1;
+
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, (nuInfoTextByteSize * 8));
+
+ // InfoTextString
+ bits.skipBits(nuInfoTextByteSize * 8);
+ }
+
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, (5 + 4 + 8));
+
+ // nuBitResolution
+ bits.skipBits(5);
+
+ samplingRate = samplingRateTableExtSS[bits.getBits(4)];
+ numChannels = bits.getBits(8) + 1;
+ }
+ }
+
+ frameSize = extHeadersize + extSSFsize;
+ isLBR = true;
+ } else {
+ ALOGE("No valid sync word in DTS/DTSHD header");
+ return ERROR_MALFORMED;
+ }
+
+ if (metaData != NULL) {
+ if (isLBR) {
+ (*metaData)->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_DTS_HD);
+ (*metaData)->setInt32(kKeyAudioProfile, 0x2); // CodecProfileLevel.DTS_HDProfileLBR
+ } else {
+ (*metaData)->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_DTS);
+ }
+ (*metaData)->setInt32(kKeyChannelCount, numChannels);
+ (*metaData)->setInt32(kKeySampleRate, samplingRate);
+ }
+ return OK;
+}
+
+static status_t extractVarLenBitFields(
+ ABitReader *bits, size_t *bitsUsed, uint32_t *value,
+ unsigned ucTable[], bool extractAndAddFlag) {
+
+ static const unsigned bitsUsedTbl[8] = {1, 1, 1, 1, 2, 2, 3, 3}; // prefix code lengths
+ static const unsigned indexTbl[8] = {0, 0, 0, 0, 1, 1, 2, 3}; // code to prefix code index map
+
+ /* Clone the bitstream */
+ ABitReader bitStream(bits->data(), bits->numBitsLeft() / 8);
+ ABitReader bitstreamClone(bits->data(), bits->numBitsLeft() / 8);
+
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bitstreamClone, 3);
+
+ unsigned code = bitstreamClone.getBits(3);
+ unsigned totalBitsUsed = bitsUsedTbl[code];
+ unsigned unIndex = indexTbl[code];
+
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bitStream, totalBitsUsed);
+
+ bitStream.skipBits(totalBitsUsed);
+
+ uint32_t unValue = 0;
+ if (ucTable[unIndex] > 0) {
+ if (extractAndAddFlag) {
+ for (unsigned un = 0; un < unIndex; un++) {
+ unValue += (1 << ucTable[un]);
+ }
+
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bitStream, ucTable[unIndex]);
+
+ unValue += bitStream.getBits(ucTable[unIndex]);
+ totalBitsUsed += ucTable[unIndex];
+ } else {
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bitStream, ucTable[unIndex]);
+
+ unValue += bitStream.getBits(ucTable[unIndex]);
+ totalBitsUsed += ucTable[unIndex];
+ }
+ }
+
+ *bitsUsed = (size_t)totalBitsUsed;
+ *value = unValue;
+ return OK;
+}
+
+// Parse DTS UHD Profile-2 stream header
+static status_t parseDTSUHDSyncFrame(
+ const uint8_t *ptr, size_t size, unsigned &frameSize, sp<MetaData> *metaData) {
+
+ static const uint32_t DTSUHD_SYNC_CORE_16BIT_BE = 0x40411BF2;
+ static const uint32_t DTSUHD_NONSYNC_CORE_16BIT_BE = 0x71C442E8;
+
+ unsigned audioSamplRate = 0;
+
+ ABitReader bits(ptr, size);
+
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, 32);
+
+ uint32_t syncWord = bits.getBits(32);
+
+ bool isSyncFrameFlag = false;
+ switch (syncWord) {
+ case DTSUHD_SYNC_CORE_16BIT_BE:
+ isSyncFrameFlag = true;
+ break;
+ case DTSUHD_NONSYNC_CORE_16BIT_BE:
+ isSyncFrameFlag = false;
+ break;
+ default:
+ ALOGE("No valid sync word in DTSUHD header");
+ return ERROR_MALFORMED; // invalid sync word
+ }
+
+ unsigned uctable1[4] = { 5, 8, 10, 12 };
+ uint32_t sizeOfFTOCPayload = 0;
+ size_t nuBitsUsed = 0;
+ status_t status = OK;
+
+ status = extractVarLenBitFields(&bits, &nuBitsUsed, &sizeOfFTOCPayload, uctable1, true);
+
+ if (status != OK) {
+ ALOGE("Failed to extractVarLenBitFields from DTSUHD header");
+ return ERROR_MALFORMED;
+ }
+
+ bits.skipBits(nuBitsUsed);
+
+ if (isSyncFrameFlag) {
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, (1 + 2 + 3 + 2 + 1));
+
+ // FullChannelBasedMixFlag, ETSI TS 103 491 V1.2.1, Section 6.4.6.1
+ if (!(bits.getBits(1))) {
+ // This implementation only supports full channel mask-based
+ // audio presentation (i.e. 2.0, 5.1, 11.1 mix without objects)
+ ALOGE("Objects not supported, only DTSUHD full channel mask-based mix");
+ return ERROR_MALFORMED;
+ }
+
+ // BaseDuration, FrameDuration
+ bits.skipBits(2 + 3);
+
+ unsigned clockRateIndex = bits.getBits(2);
+ unsigned clockRateHertz = 0;
+
+ switch (clockRateIndex) {
+ case 0:
+ clockRateHertz = 32000;
+ break;
+ case 1:
+ clockRateHertz = 44100;
+ break;
+ case 2:
+ clockRateHertz = 48000;
+ break;
+ default:
+ ALOGE("Invalid clockRateIndex in DTSUHD header");
+ return ERROR_MALFORMED;
+ }
+
+ if (bits.getBits(1)) {
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, (32 + 4));
+
+ bits.skipBits(32 + 4);
+ }
+
+ RETURN_ERROR_IF_NOT_ENOUGH_BYTES_LEFT(bits, 2);
+
+ unsigned samplRateMultiplier = (1 << bits.getBits(2));
+ audioSamplRate = clockRateHertz * samplRateMultiplier;
+ }
+
+ uint32_t chunkPayloadBytes = 0;
+ int numOfMDChunks = isSyncFrameFlag ? 1 : 0; // Metadata chunks
+ for (int nmdc = 0; nmdc < numOfMDChunks; nmdc++) {
+ unsigned uctable2[4] = {6, 9, 12, 15};
+ uint32_t nuMDChunkSize = 0;
+ nuBitsUsed = 0;
+
+ status = extractVarLenBitFields(&bits, &nuBitsUsed, &nuMDChunkSize, uctable2, true);
+ if (status != OK) {
+ ALOGE("Failed to extractVarLenBitFields from DTSUHD header");
+ return ERROR_MALFORMED;
+ }
+
+ bits.skipBits(nuBitsUsed);
+
+ if (nuMDChunkSize > 32767) {
+ ALOGE("Unsupported number of metadata chunks in DTSUHD header");
+ return ERROR_MALFORMED;
+ }
+ chunkPayloadBytes += nuMDChunkSize;
+ }
+
+ // Ony one audio chunk is supported
+ int numAudioChunks = 1;
+ for (int nac = 0; nac < numAudioChunks; nac++) {
+ uint32_t acID = 256, nuAudioChunkSize = 0;
+
+ // isSyncFrameFlag means that ACID is present
+ if (isSyncFrameFlag) {
+ unsigned uctable3[4] = {2, 4, 6, 8};
+ nuBitsUsed = 0;
+
+ status = extractVarLenBitFields(&bits, &nuBitsUsed, &acID, uctable3, true);
+
+ if (status != OK) {
+ ALOGE("Failed to extractVarLenBitFields from DTSUHD header");
+ return ERROR_MALFORMED;
+ }
+
+ bits.skipBits(nuBitsUsed);
+ }
+
+ nuBitsUsed = 0;
+ if (acID == 0) {
+ nuAudioChunkSize = 0;
+ } else {
+ unsigned uctable4[4] = {9, 11, 13, 16};
+
+ status = extractVarLenBitFields(&bits, &nuBitsUsed, &nuAudioChunkSize, uctable4, true);
+
+ if (status != OK) {
+ ALOGE("Failed to extractVarLenBitFields from DTSUHD header");
+ return ERROR_MALFORMED;
+ }
+ }
+
+ if (nuAudioChunkSize > 65535){
+ ALOGE("Unsupported number of audio chunks in DTSUHD header");
+ return ERROR_MALFORMED;
+ }
+
+ chunkPayloadBytes += nuAudioChunkSize;
+ }
+
+ frameSize = (sizeOfFTOCPayload + 1) + chunkPayloadBytes;
+
+ if (metaData != NULL) {
+ (*metaData)->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_DTS_UHD);
+ (*metaData)->setInt32(kKeyAudioProfile, 0x2); // CodecProfileLevel.DTS_UHDProfileP2
+ (*metaData)->setInt32(kKeyChannelCount, 2); // Setting default channel count as stereo
+ (*metaData)->setInt32(kKeySampleRate, audioSamplRate);
+ }
+
+ return OK;
+}
+
+static status_t isSeeminglyValidDTSHDHeader(const uint8_t *ptr, size_t size,unsigned &frameSize)
+{
+ return parseDTSHDSyncFrame(ptr, size, frameSize, NULL);
+}
+
+static status_t isSeeminglyValidDTSUHDHeader(const uint8_t *ptr, size_t size,unsigned &frameSize)
+{
+ return parseDTSUHDSyncFrame(ptr, size, frameSize, NULL);
+}
+
static status_t IsSeeminglyValidAC4Header(const uint8_t *ptr, size_t size, unsigned &frameSize) {
return parseAC4SyncFrame(ptr, size, frameSize, NULL);
}
@@ -655,6 +1085,70 @@
break;
}
+ case DTS: // Checking for DTS or DTS-HD syncword
+ case DTS_HD:
+ {
+ uint8_t *ptr = (uint8_t *)data;
+ unsigned frameSize = 0;
+ ssize_t startOffset = -1;
+
+ for (size_t i = 0; i < size; ++i) {
+ if (isSeeminglyValidDTSHDHeader(&ptr[i], size - i, frameSize) == OK) {
+ startOffset = i;
+ break;
+ }
+ }
+
+ if (startOffset < 0) {
+ return ERROR_MALFORMED;
+ }
+ if (startOffset > 0) {
+ ALOGI("found something resembling a DTS-HD syncword at "
+ "offset %zd",
+ startOffset);
+ }
+
+ if (frameSize != size - startOffset) {
+ ALOGV("DTS-HD frame size is %u bytes, while the buffer size is %zd bytes.",
+ frameSize, size - startOffset);
+ }
+
+ data = &ptr[startOffset];
+ size -= startOffset;
+ break;
+ }
+
+ case DTS_UHD:
+ {
+ uint8_t *ptr = (uint8_t *)data;
+ ssize_t startOffset = -1;
+ unsigned frameSize = 0;
+
+ for (size_t i = 0; i < size; ++i) {
+ if (isSeeminglyValidDTSUHDHeader(&ptr[i], size - i, frameSize) == OK) {
+ startOffset = i;
+ break;
+ }
+ }
+
+ if (startOffset < 0) {
+ return ERROR_MALFORMED;
+ }
+ if (startOffset >= 0) {
+ ALOGI("found something resembling a DTS UHD syncword"
+ "syncword at offset %zd",
+ startOffset);
+ }
+
+ if (frameSize != size - startOffset) {
+ ALOGV("DTS-UHD frame size is %u bytes, while the buffer size is %zd bytes.",
+ frameSize, size - startOffset);
+ }
+ data = &ptr[startOffset];
+ size -= startOffset;
+ break;
+ }
+
case PCM_AUDIO:
case METADATA:
{
@@ -928,6 +1422,11 @@
return dequeueAccessUnitPCMAudio();
case METADATA:
return dequeueAccessUnitMetadata();
+ case DTS: // Using same dequeue function for both DTS and DTS-HD types.
+ case DTS_HD:
+ return dequeueAccessUnitDTSOrDTSHD();
+ case DTS_UHD:
+ return dequeueAccessUnitDTSUHD();
default:
if (mMode != MPEG_AUDIO) {
ALOGE("Unknown mode");
@@ -937,6 +1436,113 @@
}
}
+sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitDTSOrDTSHD() {
+ unsigned syncStartPos = 0; // in bytes
+ unsigned payloadSize = 0;
+ sp<MetaData> format = new MetaData;
+
+ ALOGV("dequeueAccessUnitDTSOrDTSHD[%d]: mBuffer %p(%zu)", mAUIndex,
+ mBuffer->data(), mBuffer->size());
+
+ while (true) {
+ if (syncStartPos + 4 >= mBuffer->size()) {
+ return NULL;
+ }
+ uint8_t *ptr = mBuffer->data() + syncStartPos;
+ size_t size = mBuffer->size() - syncStartPos;
+ status_t status = parseDTSHDSyncFrame(ptr, size, payloadSize, &format);
+ if (status == 0) {
+ break;
+ }
+ ++syncStartPos;
+ }
+
+ if (mBuffer->size() < syncStartPos + payloadSize) {
+ ALOGV("Not enough buffer size for DTS/DTS-HD");
+ return NULL;
+ }
+
+ if (mFormat == NULL) {
+ mFormat = format;
+ }
+
+ int64_t timeUs = fetchTimestamp(syncStartPos + payloadSize);
+ if (timeUs < 0LL) {
+ ALOGE("negative timeUs");
+ return NULL;
+ }
+ mAUIndex++;
+
+ sp<ABuffer> accessUnit = new ABuffer(syncStartPos + payloadSize);
+ memcpy(accessUnit->data(), mBuffer->data(), syncStartPos + payloadSize);
+
+ accessUnit->meta()->setInt64("timeUs", timeUs);
+ accessUnit->meta()->setInt32("isSync", 1);
+
+ memmove(
+ mBuffer->data(),
+ mBuffer->data() + syncStartPos + payloadSize,
+ mBuffer->size() - syncStartPos - payloadSize);
+
+ mBuffer->setRange(0, mBuffer->size() - syncStartPos - payloadSize);
+
+ return accessUnit;
+}
+
+sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitDTSUHD()
+{
+ unsigned syncStartPos = 0; // in bytes
+ unsigned payloadSize = 0;
+ sp<MetaData> format = new MetaData;
+
+ ALOGV("dequeueAccessUnitDTSUHD[%d]: mBuffer %p(%zu)", mAUIndex,
+ mBuffer->data(), mBuffer->size());
+
+ while (true) {
+ if (syncStartPos + 4 >= mBuffer->size()) {
+ return NULL;
+ }
+ uint8_t *ptr = mBuffer->data() + syncStartPos;
+ size_t size = mBuffer->size() - syncStartPos;
+ status_t status = parseDTSUHDSyncFrame(ptr, size, payloadSize, &format);
+ if (status == 0) {
+ break;
+ }
+ ++syncStartPos;
+ }
+
+ if (mBuffer->size() < syncStartPos + payloadSize) {
+ ALOGV("Not enough buffer size for DTS-UHD");
+ return NULL;
+ }
+
+ if (mFormat == NULL) {
+ mFormat = format;
+ }
+
+ int64_t timeUs = fetchTimestamp(syncStartPos + payloadSize);
+ if (timeUs < 0LL) {
+ ALOGE("negative timeUs");
+ return NULL;
+ }
+ mAUIndex++;
+
+ sp<ABuffer> accessUnit = new ABuffer(syncStartPos + payloadSize);
+ memcpy(accessUnit->data(), mBuffer->data(), syncStartPos + payloadSize);
+
+ accessUnit->meta()->setInt64("timeUs", timeUs);
+ accessUnit->meta()->setInt32("isSync", 1);
+
+ memmove(
+ mBuffer->data(),
+ mBuffer->data() + syncStartPos + payloadSize,
+ mBuffer->size() - syncStartPos - payloadSize);
+
+ mBuffer->setRange(0, mBuffer->size() - syncStartPos - payloadSize);
+
+ return accessUnit;
+}
+
sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitEAC3() {
unsigned syncStartPos = 0; // in bytes
unsigned payloadSize = 0;
diff --git a/media/module/mpeg2ts/include/mpeg2ts/ATSParser.h b/media/module/mpeg2ts/include/mpeg2ts/ATSParser.h
index 49578d3..b658c5a 100644
--- a/media/module/mpeg2ts/include/mpeg2ts/ATSParser.h
+++ b/media/module/mpeg2ts/include/mpeg2ts/ATSParser.h
@@ -157,6 +157,9 @@
STREAMTYPE_LPCM_AC3 = 0x83,
STREAMTYPE_EAC3 = 0x87,
+ // DTS audio stream type which contains only Core substream
+ STREAMTYPE_DTS = 0x8A,
+
//Sample Encrypted types
STREAMTYPE_H264_ENCRYPTED = 0xDB,
STREAMTYPE_AAC_ENCRYPTED = 0xCF,
@@ -168,6 +171,7 @@
DESCRIPTOR_CA = 0x09,
// DVB BlueBook A038 Table 12
+ DESCRIPTOR_DTS = 0x7B,
DESCRIPTOR_DVB_EXTENSION = 0x7F,
};
@@ -175,6 +179,8 @@
enum {
EXT_DESCRIPTOR_DVB_AC4 = 0x15,
EXT_DESCRIPTOR_DVB_AUDIO_PRESELECTION = 0x19,
+ EXT_DESCRIPTOR_DVB_DTS_HD = 0x0E,
+ EXT_DESCRIPTOR_DVB_DTS_UHD = 0x21,
EXT_DESCRIPTOR_DVB_RESERVED_MAX = 0x7F,
};
diff --git a/media/module/mpeg2ts/include/mpeg2ts/ESQueue.h b/media/module/mpeg2ts/include/mpeg2ts/ESQueue.h
index a06bd6a..550a0e4 100644
--- a/media/module/mpeg2ts/include/mpeg2ts/ESQueue.h
+++ b/media/module/mpeg2ts/include/mpeg2ts/ESQueue.h
@@ -45,6 +45,9 @@
MPEG4_VIDEO,
PCM_AUDIO,
METADATA,
+ DTS,
+ DTS_HD,
+ DTS_UHD,
};
enum Flags {
@@ -125,6 +128,8 @@
sp<ABuffer> dequeueAccessUnitMPEG4Video();
sp<ABuffer> dequeueAccessUnitPCMAudio();
sp<ABuffer> dequeueAccessUnitMetadata();
+ sp<ABuffer> dequeueAccessUnitDTSOrDTSHD();
+ sp<ABuffer> dequeueAccessUnitDTSUHD();
// consume a logical (compressed) access unit of size "size",
// returns its timestamp in us (or -1 if no time information).
diff --git a/media/mtp/tests/MtpFuzzer/mtp_handle_fuzzer.cpp b/media/mtp/tests/MtpFuzzer/mtp_handle_fuzzer.cpp
index 676345a..7dcdc3f 100644
--- a/media/mtp/tests/MtpFuzzer/mtp_handle_fuzzer.cpp
+++ b/media/mtp/tests/MtpFuzzer/mtp_handle_fuzzer.cpp
@@ -128,10 +128,10 @@
std::unique_ptr<IMtpHandle> handle;
if (mFdp.ConsumeBool()) {
std::unique_ptr<IMtpHandle> mtpCompactHandle(new MtpFfsCompatHandle(controlFd));
- handle = move(mtpCompactHandle);
+ handle = std::move(mtpCompactHandle);
} else {
std::unique_ptr<IMtpHandle> mtpHandle(new MtpFfsHandle(controlFd));
- handle = move(mtpHandle);
+ handle = std::move(mtpHandle);
}
int32_t mtpHandle = mFdp.ConsumeIntegralInRange<size_t>(kMinAPICase, kMaxMtpHandleAPI);
diff --git a/media/ndk/NdkMediaDrm.cpp b/media/ndk/NdkMediaDrm.cpp
index 5005365..0df7636 100644
--- a/media/ndk/NdkMediaDrm.cpp
+++ b/media/ndk/NdkMediaDrm.cpp
@@ -758,6 +758,9 @@
EXPORT
media_status_t AMediaDrm_setPropertyByteArray(AMediaDrm *mObj,
const char *propertyName, const uint8_t *value, size_t valueSize) {
+ if (!mObj || mObj->mDrm == NULL) {
+ return AMEDIA_ERROR_INVALID_OBJECT;
+ }
Vector<uint8_t> byteArray;
byteArray.appendArray(value, valueSize);
diff --git a/media/utils/Android.bp b/media/utils/Android.bp
index a38ef57..fddbece 100644
--- a/media/utils/Android.bp
+++ b/media/utils/Android.bp
@@ -69,6 +69,7 @@
"-Wall",
"-Wextra",
"-Werror",
+ "-Wthread-safety",
],
header_libs: [
diff --git a/media/utils/ProcessInfo.cpp b/media/utils/ProcessInfo.cpp
index da199c4..8437222 100644
--- a/media/utils/ProcessInfo.cpp
+++ b/media/utils/ProcessInfo.cpp
@@ -40,11 +40,11 @@
int32_t state;
int32_t score = INVALID_ADJ;
status_t err = service->getProcessStatesAndOomScoresFromPids(length, &pid, &state, &score);
+ ALOGV("%s: pid:%d state:%d score:%d err:%d", __FUNCTION__, pid, state, score, err);
if (err != OK) {
ALOGE("getProcessStatesAndOomScoresFromPids failed");
return false;
}
- ALOGV("pid %d state %d score %d", pid, state, score);
if (score <= NATIVE_ADJ) {
std::scoped_lock lock{mOverrideLock};
diff --git a/media/utils/TimerThread.cpp b/media/utils/TimerThread.cpp
index 5e58a3d..d4da28f 100644
--- a/media/utils/TimerThread.cpp
+++ b/media/utils/TimerThread.cpp
@@ -292,6 +292,7 @@
void TimerThread::MonitorThread::threadFunc() {
std::unique_lock _l(mMutex);
+ ::android::base::ScopedLockAssertion lock_assertion(mMutex);
while (!mShouldExit) {
Handle nextDeadline = INVALID_HANDLE;
Handle now = INVALID_HANDLE;
@@ -385,6 +386,7 @@
std::shared_ptr<const TimerThread::Request> TimerThread::MonitorThread::remove(Handle handle) {
std::pair<std::shared_ptr<const Request>, TimerCallback> data;
std::unique_lock ul(mMutex);
+ ::android::base::ScopedLockAssertion lock_assertion(mMutex);
if (const auto it = mMonitorRequests.find(handle);
it != mMonitorRequests.end()) {
data = std::move(it->second);
diff --git a/media/utils/include/mediautils/TimerThread.h b/media/utils/include/mediautils/TimerThread.h
index c76fa7d..1e0d8c2 100644
--- a/media/utils/include/mediautils/TimerThread.h
+++ b/media/utils/include/mediautils/TimerThread.h
@@ -297,7 +297,7 @@
std::pair<std::shared_ptr<const Request>, TimerCallback>>
mSecondChanceRequests GUARDED_BY(mMutex);
- RequestQueue& mTimeoutQueue; // locked internally, added to when request times out.
+ RequestQueue& mTimeoutQueue GUARDED_BY(mMutex); // added to when request times out.
// Worker thread variables
bool mShouldExit GUARDED_BY(mMutex) = false;
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index f1f8a8f..c05aac1 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -2799,7 +2799,7 @@
return NO_ERROR;
}
-status_t AudioFlinger::getMicrophones(std::vector<media::MicrophoneInfo> *microphones)
+status_t AudioFlinger::getMicrophones(std::vector<media::MicrophoneInfoFw> *microphones)
{
AutoMutex lock(mHardwareLock);
status_t status = INVALID_OPERATION;
@@ -2812,8 +2812,12 @@
mHardwareStatus = AUDIO_HW_IDLE;
if (devStatus == NO_ERROR) {
// 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); });
+ std::transform(mics.begin(), mics.end(), std::back_inserter(*microphones), [](auto& mic)
+ {
+ auto microphone =
+ legacy2aidl_audio_microphone_characteristic_t_MicrophoneInfoFw(mic);
+ return microphone.ok() ? microphone.value() : media::MicrophoneInfoFw{};
+ });
status = NO_ERROR;
}
}
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index cb303cf..ebfe32c 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -274,7 +274,7 @@
bool isAudioPolicyReady() const { return mAudioPolicyReady.load(); }
- virtual status_t getMicrophones(std::vector<media::MicrophoneInfo> *microphones);
+ virtual status_t getMicrophones(std::vector<media::MicrophoneInfoFw> *microphones);
virtual status_t setAudioHalPids(const std::vector<pid_t>& pids);
@@ -708,7 +708,7 @@
int /*audio_session_t*/ triggerSession);
virtual binder::Status stop();
virtual binder::Status getActiveMicrophones(
- std::vector<media::MicrophoneInfoData>* activeMicrophones);
+ std::vector<media::MicrophoneInfoFw>* activeMicrophones);
virtual binder::Status setPreferredMicrophoneDirection(
int /*audio_microphone_direction_t*/ direction);
virtual binder::Status setPreferredMicrophoneFieldDimension(float zoom);
diff --git a/services/audioflinger/RecordTracks.h b/services/audioflinger/RecordTracks.h
index e8552c4..076417e 100644
--- a/services/audioflinger/RecordTracks.h
+++ b/services/audioflinger/RecordTracks.h
@@ -73,7 +73,8 @@
void setSilenced(bool silenced) { if (!isPatchTrack()) mSilenced = silenced; }
bool isSilenced() const { return mSilenced; }
- status_t getActiveMicrophones(std::vector<media::MicrophoneInfo>* activeMicrophones);
+ status_t getActiveMicrophones(
+ std::vector<media::MicrophoneInfoFw>* activeMicrophones);
status_t setPreferredMicrophoneDirection(audio_microphone_direction_t direction);
status_t setPreferredMicrophoneFieldDimension(float zoom);
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 355f411..00b612f 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -2140,9 +2140,19 @@
if (!isStreamInitialized()) {
ALOGE("The stream is not open yet"); // This should not happen.
} else {
- // setEventCallback will need a strong pointer as a parameter. Calling it
- // here instead of constructor of PlaybackThread so that the onFirstRef
- // callback would not be made on an incompletely constructed object.
+ // Callbacks take strong or weak pointers as a parameter.
+ // Since PlaybackThread passes itself as a callback handler, it can only
+ // be done outside of the constructor. Creating weak and especially strong
+ // pointers to a refcounted object in its own constructor is strongly
+ // discouraged, see comments in system/core/libutils/include/utils/RefBase.h.
+ // Even if a function takes a weak pointer, it is possible that it will
+ // need to convert it to a strong pointer down the line.
+ if (mOutput->flags & AUDIO_OUTPUT_FLAG_NON_BLOCKING &&
+ mOutput->stream->setCallback(this) == OK) {
+ mUseAsyncWrite = true;
+ mCallbackThread = new AudioFlinger::AsyncCallbackThread(this);
+ }
+
if (mOutput->stream->setEventCallback(this) != OK) {
ALOGD("Failed to add event callback");
}
@@ -3007,13 +3017,6 @@
mFrameCount);
}
- if (mOutput->flags & AUDIO_OUTPUT_FLAG_NON_BLOCKING) {
- if (mOutput->stream->setCallback(this) == OK) {
- mUseAsyncWrite = true;
- mCallbackThread = new AudioFlinger::AsyncCallbackThread(this);
- }
- }
-
mHwSupportsPause = false;
if (mOutput->flags & AUDIO_OUTPUT_FLAG_DIRECT) {
bool supportsPause = false, supportsResume = false;
@@ -8722,7 +8725,7 @@
}
status_t AudioFlinger::RecordThread::getActiveMicrophones(
- std::vector<media::MicrophoneInfo>* activeMicrophones)
+ std::vector<media::MicrophoneInfoFw>* activeMicrophones)
{
ALOGV("RecordThread::getActiveMicrophones");
AutoMutex _l(mLock);
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index bb42f22..ce90767 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -1941,7 +1941,8 @@
// Sets the UID records silence
void setRecordSilenced(audio_port_handle_t portId, bool silenced);
- status_t getActiveMicrophones(std::vector<media::MicrophoneInfo>* activeMicrophones);
+ status_t getActiveMicrophones(
+ std::vector<media::MicrophoneInfoFw>* activeMicrophones);
status_t setPreferredMicrophoneDirection(audio_microphone_direction_t direction);
status_t setPreferredMicrophoneFieldDimension(float zoom);
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 58f99e8..077a01a 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -2352,15 +2352,9 @@
}
binder::Status AudioFlinger::RecordHandle::getActiveMicrophones(
- std::vector<media::MicrophoneInfoData>* activeMicrophones) {
+ std::vector<media::MicrophoneInfoFw>* activeMicrophones) {
ALOGV("%s()", __func__);
- std::vector<media::MicrophoneInfo> mics;
- status_t status = mRecordTrack->getActiveMicrophones(&mics);
- activeMicrophones->resize(mics.size());
- for (size_t i = 0; status == OK && i < mics.size(); ++i) {
- status = mics[i].writeToParcelable(&activeMicrophones->at(i));
- }
- return binderStatusFromStatusT(status);
+ return binderStatusFromStatusT(mRecordTrack->getActiveMicrophones(activeMicrophones));
}
binder::Status AudioFlinger::RecordHandle::setPreferredMicrophoneDirection(
@@ -2680,7 +2674,7 @@
}
status_t AudioFlinger::RecordThread::RecordTrack::getActiveMicrophones(
- std::vector<media::MicrophoneInfo>* activeMicrophones)
+ std::vector<media::MicrophoneInfoFw>* activeMicrophones)
{
sp<ThreadBase> thread = mThread.promote();
if (thread != 0) {
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 7d3cdae..3d6bc5b 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -596,7 +596,10 @@
audioDeviceSet = getAudioDeviceOutAllA2dpSet();
break;
case AUDIO_DEVICE_OUT_BLE_HEADSET:
- audioDeviceSet = getAudioDeviceOutAllBleSet();
+ audioDeviceSet = getAudioDeviceOutLeAudioUnicastSet();
+ break;
+ case AUDIO_DEVICE_OUT_BLE_BROADCAST:
+ audioDeviceSet = getAudioDeviceOutLeAudioBroadcastSet();
break;
default:
ALOGE("%s() device type 0x%08x not supported", __func__, device);
@@ -1027,7 +1030,7 @@
// when searching for direct outputs, if several profiles are compatible, give priority
// to one with offload capability
- if (profile != 0 &&
+ if (profile != 0 &&
((curProfile->getFlags() & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0)) {
continue;
}
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index 2a8a103..b219cc8 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -1851,6 +1851,10 @@
mCompositeStreamMap.clear();
mInputStream = {false, 0, 0, 0, 0};
} else {
+ // In case we failed to register the offline client, ensure that it still initialized
+ // so that all failing requests can return back correctly once the object is released.
+ offlineClient->initialize(nullptr /*cameraProviderManager*/, String8()/*monitorTags*/);
+
switch(ret) {
case BAD_VALUE:
return STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
diff --git a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp
index beb655b..2cb3397 100644
--- a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp
@@ -29,6 +29,11 @@
status_t CameraOfflineSessionClient::initialize(sp<CameraProviderManager>, const String8&) {
ATRACE_CALL();
+ if (mFrameProcessor.get() != nullptr) {
+ // Already initialized
+ return OK;
+ }
+
// Verify ops permissions
auto res = startCameraOps();
if (res != OK) {
diff --git a/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp b/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp
index ef68f28..4664946 100644
--- a/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp
+++ b/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp
@@ -293,7 +293,7 @@
if (link != STATUS_OK) {
ALOGW("%s: Unable to link to provider '%s' death notifications",
__FUNCTION__, mProviderName.c_str());
- mManager->removeProvider(mProviderName);
+ mManager->removeProvider(mProviderInstance);
return nullptr;
}
diff --git a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
index d60565f..e9c4cb8 100644
--- a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
+++ b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
@@ -388,7 +388,7 @@
__FUNCTION__,
mProviderName.c_str(),
linked.description().c_str());
- mManager->removeProvider(mProviderName);
+ mManager->removeProvider(mProviderInstance);
return nullptr;
} else if (!linked) {
ALOGW("%s: Unable to link to provider '%s' death notifications",
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index 7dff809..78f3e25 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -1018,7 +1018,7 @@
wp<NotificationListener> mListener;
- const String8& mId; // The camera ID
+ const String8 mId; // The camera ID
int mStatusId; // The RequestThread's component ID for
// status tracking
diff --git a/services/camera/libcameraservice/device3/Camera3OfflineSession.cpp b/services/camera/libcameraservice/device3/Camera3OfflineSession.cpp
index 7cfa255..1e7bd57 100644
--- a/services/camera/libcameraservice/device3/Camera3OfflineSession.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OfflineSession.cpp
@@ -81,7 +81,6 @@
Camera3OfflineSession::~Camera3OfflineSession() {
ATRACE_CALL();
ALOGV("%s: Tearing down offline session for camera id %s", __FUNCTION__, mId.string());
- disconnectImpl();
}
const String8& Camera3OfflineSession::getId() const {
@@ -96,7 +95,6 @@
status_t Camera3OfflineSession::disconnect() {
ATRACE_CALL();
- disconnectSession();
return disconnectImpl();
}
@@ -132,6 +130,8 @@
streams.push_back(mInputStream);
}
+ closeSessionLocked();
+
FlushInflightReqStates states {
mId, mOfflineReqsLock, mOfflineReqs, mUseHalBufManager,
listener, *this, mBufferRecords, *this, mSessionStatsBuilder};
@@ -140,6 +140,7 @@
{
std::lock_guard<std::mutex> lock(mLock);
+ releaseSessionLocked();
mOutputStreams.clear();
mInputStream.clear();
mStatus = STATUS_CLOSED;
diff --git a/services/camera/libcameraservice/device3/Camera3OfflineSession.h b/services/camera/libcameraservice/device3/Camera3OfflineSession.h
index 5ee6ca5..e780043 100644
--- a/services/camera/libcameraservice/device3/Camera3OfflineSession.h
+++ b/services/camera/libcameraservice/device3/Camera3OfflineSession.h
@@ -274,7 +274,12 @@
void setErrorStateLockedV(const char *fmt, va_list args);
status_t disconnectImpl();
- virtual void disconnectSession() = 0;
+
+ // Clients need to ensure that 'mInterfaceLock' is acquired before calling this method
+ virtual void closeSessionLocked() = 0;
+
+ // Clients need to ensure that 'mLock' is acquired before calling this method
+ virtual void releaseSessionLocked() = 0;
}; // class Camera3OfflineSession
diff --git a/services/camera/libcameraservice/device3/aidl/AidlCamera3OfflineSession.cpp b/services/camera/libcameraservice/device3/aidl/AidlCamera3OfflineSession.cpp
index 8ff0b07..affdda6 100644
--- a/services/camera/libcameraservice/device3/aidl/AidlCamera3OfflineSession.cpp
+++ b/services/camera/libcameraservice/device3/aidl/AidlCamera3OfflineSession.cpp
@@ -48,7 +48,7 @@
AidlCamera3OfflineSession::~AidlCamera3OfflineSession() {
ATRACE_CALL();
ALOGV("%s: Tearing down aidl offline session for camera id %s", __FUNCTION__, mId.string());
- AidlCamera3OfflineSession::disconnectSession();
+ Camera3OfflineSession::disconnectImpl();
}
status_t AidlCamera3OfflineSession::initialize(wp<NotificationListener> listener) {
@@ -245,12 +245,17 @@
return ::ndk::ScopedAStatus::ok();
}
-void AidlCamera3OfflineSession::disconnectSession() {
- std::lock_guard<std::mutex> lock(mLock);
- if (mSession != nullptr) {
- mSession->close();
- }
- mSession.reset();
+void AidlCamera3OfflineSession::closeSessionLocked() {
+ if (mSession != nullptr) {
+ auto err = mSession->close();
+ if (!err.isOk()) {
+ ALOGE("%s: Close transaction error: %s", __FUNCTION__, err.getDescription().c_str());
+ }
+ }
+}
+
+void AidlCamera3OfflineSession::releaseSessionLocked() {
+ mSession.reset();
}
}; // namespace android
diff --git a/services/camera/libcameraservice/device3/aidl/AidlCamera3OfflineSession.h b/services/camera/libcameraservice/device3/aidl/AidlCamera3OfflineSession.h
index d107af6..b31ffb7 100644
--- a/services/camera/libcameraservice/device3/aidl/AidlCamera3OfflineSession.h
+++ b/services/camera/libcameraservice/device3/aidl/AidlCamera3OfflineSession.h
@@ -131,7 +131,9 @@
std::shared_ptr<AidlCameraDeviceCallbacks> mCallbacks;
- virtual void disconnectSession() override;
+ virtual void closeSessionLocked() override;
+
+ virtual void releaseSessionLocked() override;
}; // class AidlCamera3OfflineSession
diff --git a/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.h b/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.h
index 2e98fe0..d56ff53 100644
--- a/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.h
+++ b/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.h
@@ -81,9 +81,6 @@
const hardware::hidl_vec<
hardware::camera::device::V3_2::StreamBuffer>& buffers) override;
- // Handle one notify message
- void notify(const hardware::camera::device::V3_2::NotifyMsg& msg);
-
status_t switchToOffline(const std::vector<int32_t>& streamsToKeep,
/*out*/ sp<CameraOfflineSessionBase>* session) override;
diff --git a/services/camera/libcameraservice/device3/hidl/HidlCamera3OfflineSession.cpp b/services/camera/libcameraservice/device3/hidl/HidlCamera3OfflineSession.cpp
index 2b4f8a1..de01ac9 100644
--- a/services/camera/libcameraservice/device3/hidl/HidlCamera3OfflineSession.cpp
+++ b/services/camera/libcameraservice/device3/hidl/HidlCamera3OfflineSession.cpp
@@ -39,7 +39,7 @@
HidlCamera3OfflineSession::~HidlCamera3OfflineSession() {
ATRACE_CALL();
ALOGV("%s: Tearing down hidl offline session for camera id %s", __FUNCTION__, mId.string());
- HidlCamera3OfflineSession::disconnectSession();
+ Camera3OfflineSession::disconnectImpl();
}
status_t HidlCamera3OfflineSession::initialize(wp<NotificationListener> listener) {
@@ -226,13 +226,17 @@
return hardware::Void();
}
-void HidlCamera3OfflineSession::disconnectSession() {
- // TODO: Make sure this locking is correct.
- std::lock_guard<std::mutex> lock(mLock);
- if (mSession != nullptr) {
- mSession->close();
- }
- mSession.clear();
+void HidlCamera3OfflineSession::closeSessionLocked() {
+ if (mSession != nullptr) {
+ auto err = mSession->close();
+ if (!err.isOk()) {
+ ALOGE("%s: Close transaction error: %s", __FUNCTION__, err.description().c_str());
+ }
+ }
+}
+
+void HidlCamera3OfflineSession::releaseSessionLocked() {
+ mSession.clear();
}
}; // namespace android
diff --git a/services/camera/libcameraservice/device3/hidl/HidlCamera3OfflineSession.h b/services/camera/libcameraservice/device3/hidl/HidlCamera3OfflineSession.h
index 597cc5d..d22a447 100644
--- a/services/camera/libcameraservice/device3/hidl/HidlCamera3OfflineSession.h
+++ b/services/camera/libcameraservice/device3/hidl/HidlCamera3OfflineSession.h
@@ -101,7 +101,9 @@
// FMQ to write result on. Must be guarded by mProcessCaptureResultLock.
std::unique_ptr<ResultMetadataQueue> mResultMetadataQueue;
- virtual void disconnectSession() override;
+ virtual void closeSessionLocked() override;
+
+ virtual void releaseSessionLocked() override;
}; // class Camera3OfflineSession
}; // namespace android
diff --git a/services/mediametrics/statsd_drm.cpp b/services/mediametrics/statsd_drm.cpp
index 863fdbe..9f08eca 100644
--- a/services/mediametrics/statsd_drm.cpp
+++ b/services/mediametrics/statsd_drm.cpp
@@ -248,10 +248,10 @@
if (!item->getInt32("frontend", &frontend)) return false;
// Optional to be included
- int64_t apex_version = -1;
- item->getInt64("apex_version", &apex_version);
+ std::string version = "";
+ item->getString("version", &version);
const int result = stats_write(stats::media_metrics::MEDIA_DRM_CREATED,
- scheme, uuid_lsb, uuid_msb, uid, frontend, apex_version);
+ scheme, uuid_lsb, uuid_msb, uid, frontend, version.c_str());
std::stringstream log;
log << "result:" << result << " {"
@@ -262,7 +262,7 @@
<< " uuid_msb:" << uuid_msb
<< " uid:" << uid
<< " frontend:" << frontend
- << " apex_version:" << apex_version
+ << " version:" << version
<< " }";
statsdLog->log(stats::media_metrics::MEDIA_DRM_CREATED, log.str());
return true;
@@ -287,10 +287,10 @@
if (!item->getInt32("opened_security_level", &opened_security_level)) return false;
// Optional to be included
- int64_t apex_version = -1;
- item->getInt64("apex_version", &apex_version);
+ std::string version = "";
+ item->getString("version", &version);
const int result = stats_write(stats::media_metrics::MEDIA_DRM_SESSION_OPENED,
- scheme, uuid_lsb, uuid_msb, uid, frontend, apex_version,
+ scheme, uuid_lsb, uuid_msb, uid, frontend, version.c_str(),
object_nonce.c_str(), requested_security_level,
opened_security_level);
@@ -303,7 +303,7 @@
<< " uuid_msb:" << uuid_msb
<< " uid:" << uid
<< " frontend:" << frontend
- << " apex_version:" << apex_version
+ << " version:" << version
<< " object_nonce:" << object_nonce
<< " requested_security_level:" << requested_security_level
<< " opened_security_level:" << opened_security_level
@@ -334,8 +334,8 @@
if (!item->getInt32("error_code", &error_code)) return false;
// Optional to be included
- int64_t apex_version = -1;
- item->getInt64("apex_version", &apex_version);
+ std::string version = "";
+ item->getString("version", &version);
std::string session_nonce = "";
item->getString("session_nonce", &session_nonce);
@@ -347,7 +347,7 @@
item->getInt32("error_context", &error_context);
const int result = stats_write(stats::media_metrics::MEDIA_DRM_ERRORED, scheme, uuid_lsb,
- uuid_msb, uid, frontend, apex_version, object_nonce.c_str(),
+ uuid_msb, uid, frontend, version.c_str(), object_nonce.c_str(),
session_nonce.c_str(), security_level, api, error_code, cdm_err,
oem_err, error_context);
@@ -360,7 +360,7 @@
<< " uuid_msb:" << uuid_msb
<< " uid:" << uid
<< " frontend:" << frontend
- << " apex_version:" << apex_version
+ << " version:" << version
<< " object_nonce:" << object_nonce
<< " session_nonce:" << session_nonce
<< " security_level:" << security_level
diff --git a/services/mediaresourcemanager/Android.bp b/services/mediaresourcemanager/Android.bp
index 5d80744..2b8245e 100644
--- a/services/mediaresourcemanager/Android.bp
+++ b/services/mediaresourcemanager/Android.bp
@@ -16,6 +16,7 @@
"aidl/android/media/MediaResourceSubType.aidl",
"aidl/android/media/MediaResourceParcel.aidl",
"aidl/android/media/MediaResourcePolicyParcel.aidl",
+ "aidl/android/media/ClientInfoParcel.aidl",
],
path: "aidl",
}
@@ -87,10 +88,15 @@
"libbinder_ndk",
"libutils",
"liblog",
+ "libstats_media_metrics",
+ "libstatspull",
+ "libstatssocket",
+ "libprotobuf-cpp-lite",
],
static_libs: [
"resourceobserver_aidl_interface-V1-ndk",
+ "libplatformprotos",
],
include_dirs: ["frameworks/av/include"],
@@ -101,4 +107,10 @@
],
export_include_dirs: ["."],
+
+ export_shared_lib_headers: [
+ "libstats_media_metrics",
+ "libstatspull",
+ "libstatssocket",
+ ],
}
diff --git a/services/mediaresourcemanager/ResourceManagerService.cpp b/services/mediaresourcemanager/ResourceManagerService.cpp
index 4d18876..f94446f 100644
--- a/services/mediaresourcemanager/ResourceManagerService.cpp
+++ b/services/mediaresourcemanager/ResourceManagerService.cpp
@@ -34,6 +34,7 @@
#include <sys/stat.h>
#include <sys/time.h>
#include <unistd.h>
+#include <stats_media_metrics.h>
#include "IMediaResourceMonitor.h"
#include "ResourceManagerService.h"
@@ -42,6 +43,14 @@
namespace android {
+using stats::media_metrics::stats_write;
+using stats::media_metrics::MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED;
+using stats::media_metrics::MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED__RECLAIM_STATUS__RECLAIM_SUCCESS;
+using stats::media_metrics::\
+ MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED__RECLAIM_STATUS__RECLAIM_FAILED_NO_CLIENTS;
+using stats::media_metrics::\
+ MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED__RECLAIM_STATUS__RECLAIM_FAILED_RECLAIM_RESOURCES;
+
//static
std::mutex ResourceManagerService::sCookieLock;
//static
@@ -97,7 +106,8 @@
service->overridePid(mPid, -1);
// thiz is freed in the call below, so it must be last call referring thiz
- service->removeResource(mPid, mClientId, false /*checkValid*/);
+ ClientInfoParcel clientInfo{.pid = mPid, .id = mClientId};
+ service->removeResource(clientInfo, false /*checkValid*/);
}
class OverrideProcessInfoDeathNotifier : public DeathNotifier {
@@ -183,6 +193,7 @@
}
static ResourceInfo& getResourceInfoForEdit(uid_t uid, int64_t clientId,
+ const std::string& name,
const std::shared_ptr<IResourceManagerClient>& client, ResourceInfos& infos) {
ssize_t index = infos.indexOfKey(clientId);
@@ -190,6 +201,7 @@
ResourceInfo info;
info.uid = uid;
info.clientId = clientId;
+ info.name = name;
info.client = client;
info.cookie = 0;
info.pendingRemoval = false;
@@ -262,7 +274,15 @@
result.append(" Processes:\n");
for (size_t i = 0; i < mapCopy.size(); ++i) {
- snprintf(buffer, SIZE, " Pid: %d\n", mapCopy.keyAt(i));
+ int pid = mapCopy.keyAt(i);
+ snprintf(buffer, SIZE, " Pid: %d\n", pid);
+ result.append(buffer);
+ int priority = 0;
+ if (getPriority_l(pid, &priority)) {
+ snprintf(buffer, SIZE, " Priority: %d\n", priority);
+ } else {
+ snprintf(buffer, SIZE, " Priority: <unknown>\n");
+ }
result.append(buffer);
const ResourceInfos &infos = mapCopy.valueAt(i);
@@ -273,7 +293,7 @@
std::string clientName = "<unknown client>";
if (infos[j].client != nullptr) {
- Status status = infos[j].client->getName(&clientName);
+ clientName = infos[j].name;
}
snprintf(buffer, SIZE, " Name: %s\n", clientName.c_str());
result.append(buffer);
@@ -433,11 +453,15 @@
}
}
-Status ResourceManagerService::addResource(int32_t pid, int32_t uid, int64_t clientId,
+Status ResourceManagerService::addResource(const ClientInfoParcel& clientInfo,
const std::shared_ptr<IResourceManagerClient>& client,
const std::vector<MediaResourceParcel>& resources) {
- String8 log = String8::format("addResource(pid %d, clientId %lld, resources %s)",
- pid, (long long) clientId, getString(resources).string());
+ int32_t pid = clientInfo.pid;
+ int32_t uid = clientInfo.uid;
+ int64_t clientId = clientInfo.id;
+ const std::string& name = clientInfo.name;
+ String8 log = String8::format("addResource(pid %d, uid %d clientId %lld, resources %s)",
+ pid, uid, (long long) clientId, getString(resources).string());
mServiceLog->add(log);
Mutex::Autolock lock(mLock);
@@ -450,7 +474,7 @@
uid = callingUid;
}
ResourceInfos& infos = getResourceInfosForEdit(pid, mMap);
- ResourceInfo& info = getResourceInfoForEdit(uid, clientId, client, infos);
+ ResourceInfo& info = getResourceInfoForEdit(uid, clientId, name, client, infos);
ResourceList resourceAdded;
for (size_t i = 0; i < resources.size(); ++i) {
@@ -489,13 +513,50 @@
mObserverService->onResourceAdded(uid, pid, resourceAdded);
}
notifyResourceGranted(pid, resources);
+
+ // Increase the instance count of the resource associated with this client.
+ increaseResourceInstanceCount(clientId, name);
+
return Status::ok();
}
-Status ResourceManagerService::removeResource(int32_t pid, int64_t clientId,
+void ResourceManagerService::increaseResourceInstanceCount(int64_t clientId,
+ const std::string& name) {
+ // Check whether this client has been looked into already.
+ if (mClientIdSet.find(clientId) == mClientIdSet.end()) {
+ mClientIdSet.insert(clientId);
+ // Update the resource instance count.
+ auto found = mConcurrentResourceCountMap.find(name);
+ if (found == mConcurrentResourceCountMap.end()) {
+ mConcurrentResourceCountMap[name] = 1;
+ } else {
+ found->second++;
+ }
+ }
+}
+
+void ResourceManagerService::decreaseResourceInstanceCount(int64_t clientId,
+ const std::string& name) {
+ // Since this client has been removed, remove it from mClientIdSet
+ mClientIdSet.erase(clientId);
+ // Update the resource instance count also.
+ auto found = mConcurrentResourceCountMap.find(name);
+ if (found != mConcurrentResourceCountMap.end()) {
+ if (found->second == 1) {
+ mConcurrentResourceCountMap.erase(found);
+ } else {
+ found->second--;
+ }
+ }
+}
+
+Status ResourceManagerService::removeResource(const ClientInfoParcel& clientInfo,
const std::vector<MediaResourceParcel>& resources) {
- String8 log = String8::format("removeResource(pid %d, clientId %lld, resources %s)",
- pid, (long long) clientId, getString(resources).string());
+ int32_t pid = clientInfo.pid;
+ int32_t uid = clientInfo.uid;
+ int64_t clientId = clientInfo.id;
+ String8 log = String8::format("removeResource(pid %d, uid %d clientId %lld, resources %s)",
+ pid, uid, (long long) clientId, getString(resources).string());
mServiceLog->add(log);
Mutex::Autolock lock(mLock);
@@ -555,15 +616,17 @@
return Status::ok();
}
-Status ResourceManagerService::removeClient(int32_t pid, int64_t clientId) {
- removeResource(pid, clientId, true /*checkValid*/);
+Status ResourceManagerService::removeClient(const ClientInfoParcel& clientInfo) {
+ removeResource(clientInfo, true /*checkValid*/);
return Status::ok();
}
-Status ResourceManagerService::removeResource(int pid, int64_t clientId, bool checkValid) {
- String8 log = String8::format(
- "removeResource(pid %d, clientId %lld)",
- pid, (long long) clientId);
+Status ResourceManagerService::removeResource(const ClientInfoParcel& clientInfo, bool checkValid) {
+ int32_t pid = clientInfo.pid;
+ int32_t uid = clientInfo.uid;
+ int64_t clientId = clientInfo.id;
+ String8 log = String8::format("removeResource(pid %d, uid %d clientId %lld)",
+ pid, uid, (long long) clientId);
mServiceLog->add(log);
Mutex::Autolock lock(mLock);
@@ -591,6 +654,10 @@
onLastRemoved(it->second, info);
}
+ // Since this client has been removed, decrease the corresponding
+ // resources instance count.
+ decreaseResourceInstanceCount(clientId, info.name);
+
removeCookieAndUnlink_l(info.client, info.cookie);
if (mObserverService != nullptr && !info.resources.empty()) {
@@ -601,25 +668,30 @@
return Status::ok();
}
-void ResourceManagerService::getClientForResource_l(int callingPid, const MediaResourceParcel *res,
+void ResourceManagerService::getClientForResource_l(int callingPid,
+ const MediaResourceParcel *res,
+ PidUidVector* idVector,
Vector<std::shared_ptr<IResourceManagerClient>> *clients) {
if (res == NULL) {
return;
}
std::shared_ptr<IResourceManagerClient> client;
- if (getLowestPriorityBiggestClient_l(callingPid, res->type, res->subType, &client)) {
+ if (getLowestPriorityBiggestClient_l(callingPid, res->type, res->subType, idVector, &client)) {
clients->push_back(client);
}
}
-Status ResourceManagerService::reclaimResource(int32_t callingPid,
+Status ResourceManagerService::reclaimResource(const ClientInfoParcel& clientInfo,
const std::vector<MediaResourceParcel>& resources, bool* _aidl_return) {
- String8 log = String8::format("reclaimResource(callingPid %d, resources %s)",
- callingPid, getString(resources).string());
+ int32_t callingPid = clientInfo.pid;
+ std::string clientName = clientInfo.name;
+ String8 log = String8::format("reclaimResource(callingPid %d, uid %d resources %s)",
+ callingPid, clientInfo.uid, getString(resources).string());
mServiceLog->add(log);
*_aidl_return = false;
Vector<std::shared_ptr<IResourceManagerClient>> clients;
+ PidUidVector idVector;
{
Mutex::Autolock lock(mLock);
if (!mProcessInfo->isPidTrusted(callingPid)) {
@@ -655,13 +727,13 @@
if (secureCodec != NULL) {
if (!mSupportsMultipleSecureCodecs) {
if (!getAllClients_l(callingPid, MediaResource::Type::kSecureCodec,
- secureCodec->subType, &clients)) {
+ secureCodec->subType, &idVector, &clients)) {
return Status::ok();
}
}
if (!mSupportsSecureWithNonSecureCodec) {
if (!getAllClients_l(callingPid, MediaResource::Type::kNonSecureCodec,
- secureCodec->subType, &clients)) {
+ secureCodec->subType, &idVector, &clients)) {
return Status::ok();
}
}
@@ -669,13 +741,13 @@
if (nonSecureCodec != NULL) {
if (!mSupportsSecureWithNonSecureCodec) {
if (!getAllClients_l(callingPid, MediaResource::Type::kSecureCodec,
- nonSecureCodec->subType, &clients)) {
+ nonSecureCodec->subType, &idVector, &clients)) {
return Status::ok();
}
}
}
if (drmSession != NULL) {
- getClientForResource_l(callingPid, drmSession, &clients);
+ getClientForResource_l(callingPid, drmSession, &idVector, &clients);
if (clients.size() == 0) {
return Status::ok();
}
@@ -683,32 +755,108 @@
if (clients.size() == 0) {
// if no secure/non-secure codec conflict, run second pass to handle other resources.
- getClientForResource_l(callingPid, graphicMemory, &clients);
+ getClientForResource_l(callingPid, graphicMemory, &idVector, &clients);
}
if (clients.size() == 0) {
// if we are here, run the third pass to free one codec with the same type.
- getClientForResource_l(callingPid, secureCodec, &clients);
- getClientForResource_l(callingPid, nonSecureCodec, &clients);
+ getClientForResource_l(callingPid, secureCodec, &idVector, &clients);
+ getClientForResource_l(callingPid, nonSecureCodec, &idVector, &clients);
}
if (clients.size() == 0) {
// if we are here, run the fourth pass to free one codec with the different type.
if (secureCodec != NULL) {
MediaResource temp(MediaResource::Type::kNonSecureCodec, secureCodec->subType, 1);
- getClientForResource_l(callingPid, &temp, &clients);
+ getClientForResource_l(callingPid, &temp, &idVector, &clients);
}
if (nonSecureCodec != NULL) {
MediaResource temp(MediaResource::Type::kSecureCodec, nonSecureCodec->subType, 1);
- getClientForResource_l(callingPid, &temp, &clients);
+ getClientForResource_l(callingPid, &temp, &idVector, &clients);
}
}
}
*_aidl_return = reclaimUnconditionallyFrom(clients);
+
+ // Log Reclaim Pushed Atom to statsd
+ pushReclaimAtom(clientInfo, clients, idVector, *_aidl_return);
+
return Status::ok();
}
+void ResourceManagerService::pushReclaimAtom(const ClientInfoParcel& clientInfo,
+ const Vector<std::shared_ptr<IResourceManagerClient>>& clients,
+ const PidUidVector& idVector, bool reclaimed) {
+ // Construct the metrics for codec reclaim as a pushed atom.
+ // 1. Information about the requester.
+ // - UID and the priority (oom score)
+ int32_t callingPid = clientInfo.pid;
+ int32_t requesterUid = clientInfo.uid;
+ std::string clientName = clientInfo.name;
+ int requesterPriority = -1;
+ getPriority_l(callingPid, &requesterPriority);
+
+ // 2. Information about the codec.
+ // - Name of the codec requested
+ // - Number of concurrent codecs running.
+ int32_t noOfConcurrentCodecs = 0;
+ auto found = mConcurrentResourceCountMap.find(clientName);
+ if (found != mConcurrentResourceCountMap.end()) {
+ noOfConcurrentCodecs = found->second;
+ }
+
+ // 3. Information about the Reclaim:
+ // - Status of reclaim request
+ // - How many codecs are reclaimed
+ // - For each codecs reclaimed, information of the process that it belonged to:
+ // - UID and the Priority (oom score)
+ int32_t reclaimStatus = MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED__RECLAIM_STATUS__RECLAIM_SUCCESS;
+ if (!reclaimed) {
+ if (clients.size() == 0) {
+ // No clients to reclaim from
+ reclaimStatus =
+ MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED__RECLAIM_STATUS__RECLAIM_FAILED_NO_CLIENTS;
+ } else {
+ // Couldn't reclaim resources from the clients
+ reclaimStatus =
+ MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED__RECLAIM_STATUS__RECLAIM_FAILED_RECLAIM_RESOURCES;
+ }
+ }
+ int32_t noOfCodecsReclaimed = clients.size();
+ int32_t targetIndex = 1;
+ for (const auto& id : idVector) {
+ int32_t targetUid = id.second;
+ int targetPriority = -1;
+ getPriority_l(id.first, &targetPriority);
+ // Post the pushed atom
+ int result = stats_write(
+ MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED,
+ requesterUid,
+ requesterPriority,
+ clientName.c_str(),
+ noOfConcurrentCodecs,
+ reclaimStatus,
+ noOfCodecsReclaimed,
+ targetIndex,
+ targetUid,
+ targetPriority);
+ ALOGI("%s: Pushed MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED atom: "
+ "Requester[pid(%d): uid(%d): priority(%d)] "
+ "Codec: [%s] "
+ "No of concurrent codecs: %d "
+ "Reclaim Status: %d "
+ "No of codecs reclaimed: %d "
+ "Target[%d][pid(%d): uid(%d): priority(%d)] "
+ "Atom Size: %d",
+ __func__, callingPid, requesterUid, requesterPriority,
+ clientName.c_str(), noOfConcurrentCodecs,
+ reclaimStatus, noOfCodecsReclaimed,
+ targetIndex, id.first, targetUid, targetPriority, result);
+ targetIndex++;
+ }
+}
+
bool ResourceManagerService::reclaimUnconditionallyFrom(
const Vector<std::shared_ptr<IResourceManagerClient>> &clients) {
if (clients.size() == 0) {
@@ -868,7 +1016,9 @@
mProcessInfoOverrideMap.erase(pid);
}
-Status ResourceManagerService::markClientForPendingRemoval(int32_t pid, int64_t clientId) {
+Status ResourceManagerService::markClientForPendingRemoval(const ClientInfoParcel& clientInfo) {
+ int32_t pid = clientInfo.pid;
+ int64_t clientId = clientInfo.id;
String8 log = String8::format(
"markClientForPendingRemoval(pid %d, clientId %lld)",
pid, (long long) clientId);
@@ -926,7 +1076,8 @@
MediaResource::SubType::kVideoCodec,
MediaResource::SubType::kImageCodec}) {
std::shared_ptr<IResourceManagerClient> client;
- if (getBiggestClientPendingRemoval_l(pid, type, subType, &client)) {
+ uid_t uid = 0;
+ if (getBiggestClientPendingRemoval_l(pid, type, subType, uid, &client)) {
clients.add(client);
continue;
}
@@ -935,8 +1086,9 @@
// Non-codec resources are shared by audio, video and image codecs (no subtype).
default:
std::shared_ptr<IResourceManagerClient> client;
+ uid_t uid = 0;
if (getBiggestClientPendingRemoval_l(pid, type,
- MediaResource::SubType::kUnspecifiedSubType, &client)) {
+ MediaResource::SubType::kUnspecifiedSubType, uid, &client)) {
clients.add(client);
}
break;
@@ -963,8 +1115,12 @@
}
bool ResourceManagerService::getAllClients_l(int callingPid, MediaResource::Type type,
- MediaResource::SubType subType, Vector<std::shared_ptr<IResourceManagerClient>> *clients) {
+ MediaResource::SubType subType,
+ PidUidVector* idVector,
+ Vector<std::shared_ptr<IResourceManagerClient>> *clients) {
Vector<std::shared_ptr<IResourceManagerClient>> temp;
+ PidUidVector tempIdList;
+
for (size_t i = 0; i < mMap.size(); ++i) {
ResourceInfos &infos = mMap.editValueAt(i);
for (size_t j = 0; j < infos.size(); ++j) {
@@ -977,6 +1133,7 @@
return false;
}
temp.push_back(infos[j].client);
+ tempIdList.emplace_back(mMap.keyAt(i), infos[j].uid);
}
}
}
@@ -985,19 +1142,24 @@
return true;
}
clients->appendVector(temp);
+ idVector->insert(std::end(*idVector), std::begin(tempIdList), std::end(tempIdList));
return true;
}
bool ResourceManagerService::getLowestPriorityBiggestClient_l(int callingPid,
- MediaResource::Type type, MediaResource::SubType subType,
+ MediaResource::Type type,
+ MediaResource::SubType subType,
+ PidUidVector* idVector,
std::shared_ptr<IResourceManagerClient> *client) {
int lowestPriorityPid;
int lowestPriority;
int callingPriority;
+ uid_t uid = 0;
// Before looking into other processes, check if we have clients marked for
// pending removal in the same process.
- if (getBiggestClientPendingRemoval_l(callingPid, type, subType, client)) {
+ if (getBiggestClientPendingRemoval_l(callingPid, type, subType, uid, client)) {
+ idVector->emplace_back(callingPid, uid);
return true;
}
if (!getPriority_l(callingPid, &callingPriority)) {
@@ -1014,9 +1176,11 @@
return false;
}
- if (!getBiggestClient_l(lowestPriorityPid, type, subType, client)) {
+ if (!getBiggestClient_l(lowestPriorityPid, type, subType, uid, client)) {
return false;
}
+
+ idVector->emplace_back(lowestPriorityPid, uid);
return true;
}
@@ -1068,12 +1232,14 @@
}
bool ResourceManagerService::getBiggestClientPendingRemoval_l(int pid, MediaResource::Type type,
- MediaResource::SubType subType, std::shared_ptr<IResourceManagerClient> *client) {
- return getBiggestClient_l(pid, type, subType, client, true /* pendingRemovalOnly */);
+ MediaResource::SubType subType, uid_t& uid,
+ std::shared_ptr<IResourceManagerClient> *client) {
+ return getBiggestClient_l(pid, type, subType, uid, client, true /* pendingRemovalOnly */);
}
bool ResourceManagerService::getBiggestClient_l(int pid, MediaResource::Type type,
- MediaResource::SubType subType, std::shared_ptr<IResourceManagerClient> *client,
+ MediaResource::SubType subType, uid_t& uid,
+ std::shared_ptr<IResourceManagerClient> *client,
bool pendingRemovalOnly) {
ssize_t index = mMap.indexOfKey(pid);
if (index < 0) {
@@ -1096,6 +1262,7 @@
if (resource.value > largestValue) {
largestValue = resource.value;
clientTemp = infos[i].client;
+ uid = infos[i].uid;
}
}
}
diff --git a/services/mediaresourcemanager/ResourceManagerService.h b/services/mediaresourcemanager/ResourceManagerService.h
index c636a0f..0016a19 100644
--- a/services/mediaresourcemanager/ResourceManagerService.h
+++ b/services/mediaresourcemanager/ResourceManagerService.h
@@ -19,7 +19,9 @@
#define ANDROID_MEDIA_RESOURCEMANAGERSERVICE_H
#include <map>
+#include <set>
#include <mutex>
+#include <string>
#include <aidl/android/media/BnResourceManagerService.h>
#include <arpa/inet.h>
@@ -43,20 +45,24 @@
using ::aidl::android::media::BnResourceManagerService;
using ::aidl::android::media::MediaResourceParcel;
using ::aidl::android::media::MediaResourcePolicyParcel;
+using ::aidl::android::media::ClientInfoParcel;
typedef std::map<std::tuple<
MediaResource::Type, MediaResource::SubType, std::vector<uint8_t>>,
MediaResourceParcel> ResourceList;
struct ResourceInfo {
- int64_t clientId;
uid_t uid;
+ int64_t clientId;
+ std::string name;
std::shared_ptr<IResourceManagerClient> client;
uintptr_t cookie{0};
ResourceList resources;
bool pendingRemoval{false};
};
+typedef std::vector<std::pair<int32_t, uid_t>> PidUidVector;
+
// TODO: convert these to std::map
typedef KeyedVector<int64_t, ResourceInfo> ResourceInfos;
typedef KeyedVector<int, ResourceInfos> PidResourceInfosMap;
@@ -85,31 +91,32 @@
// IResourceManagerService interface
Status config(const std::vector<MediaResourcePolicyParcel>& policies) override;
- Status addResource(int32_t pid, int32_t uid, int64_t clientId,
- const std::shared_ptr<IResourceManagerClient>& client,
- const std::vector<MediaResourceParcel>& resources) override;
+ Status addResource(const ClientInfoParcel& clientInfo,
+ const std::shared_ptr<IResourceManagerClient>& client,
+ const std::vector<MediaResourceParcel>& resources) override;
- Status removeResource(int32_t pid, int64_t clientId,
- const std::vector<MediaResourceParcel>& resources) override;
+ Status removeResource(const ClientInfoParcel& clientInfo,
+ const std::vector<MediaResourceParcel>& resources) override;
- Status removeClient(int32_t pid, int64_t clientId) override;
+ Status removeClient(const ClientInfoParcel& clientInfo) override;
// Tries to reclaim resource from processes with lower priority than the calling process
// according to the requested resources.
// Returns true if any resource has been reclaimed, otherwise returns false.
- Status reclaimResource(int32_t callingPid, const std::vector<MediaResourceParcel>& resources,
- bool* _aidl_return) override;
+ Status reclaimResource(const ClientInfoParcel& clientInfo,
+ const std::vector<MediaResourceParcel>& resources,
+ bool* _aidl_return) override;
- Status overridePid(int originalPid, int newPid) override;
+ Status overridePid(int32_t originalPid, int32_t newPid) override;
- Status overrideProcessInfo(const std::shared_ptr<IResourceManagerClient>& client, int pid,
- int procState, int oomScore) override;
+ Status overrideProcessInfo(const std::shared_ptr<IResourceManagerClient>& client,
+ int32_t pid, int32_t procState, int32_t oomScore) override;
- Status markClientForPendingRemoval(int32_t pid, int64_t clientId) override;
+ Status markClientForPendingRemoval(const ClientInfoParcel& clientInfo) override;
Status reclaimResourcesFromClientsPendingRemoval(int32_t pid) override;
- Status removeResource(int pid, int64_t clientId, bool checkValid);
+ Status removeResource(const ClientInfoParcel& clientInfo, bool checkValid);
private:
friend class ResourceManagerServiceTest;
@@ -124,13 +131,15 @@
// Returns false if any client belongs to a process with higher priority than the
// calling process. The clients will remain unchanged if returns false.
bool getAllClients_l(int callingPid, MediaResource::Type type, MediaResource::SubType subType,
+ PidUidVector* idList,
Vector<std::shared_ptr<IResourceManagerClient>> *clients);
// Gets the client who owns specified resource type from lowest possible priority process.
// Returns false if the calling process priority is not higher than the lowest process
// priority. The client will remain unchanged if returns false.
bool getLowestPriorityBiggestClient_l(int callingPid, MediaResource::Type type,
- MediaResource::SubType subType, std::shared_ptr<IResourceManagerClient> *client);
+ MediaResource::SubType subType, PidUidVector* idList,
+ std::shared_ptr<IResourceManagerClient> *client);
// Gets lowest priority process that has the specified resource type.
// Returns false if failed. The output parameters will remain unchanged if failed.
@@ -141,17 +150,19 @@
// Returns false with no change to client if there are no clients holdiing resources of thisi
// type.
bool getBiggestClient_l(int pid, MediaResource::Type type, MediaResource::SubType subType,
- std::shared_ptr<IResourceManagerClient> *client,
+ uid_t& uid, std::shared_ptr<IResourceManagerClient> *client,
bool pendingRemovalOnly = false);
// Same method as above, but with pendingRemovalOnly as true.
bool getBiggestClientPendingRemoval_l(int pid, MediaResource::Type type,
- MediaResource::SubType subType, std::shared_ptr<IResourceManagerClient> *client);
+ MediaResource::SubType subType, uid_t& uid,
+ std::shared_ptr<IResourceManagerClient> *client);
bool isCallingPriorityHigher_l(int callingPid, int pid);
// A helper function basically calls getLowestPriorityBiggestClient_l and add
// the result client to the given Vector.
void getClientForResource_l(int callingPid, const MediaResourceParcel *res,
+ PidUidVector* idList,
Vector<std::shared_ptr<IResourceManagerClient>> *clients);
void onFirstAdded(const MediaResourceParcel& res, const ResourceInfo& clientInfo);
@@ -171,6 +182,15 @@
void removeCookieAndUnlink_l(const std::shared_ptr<IResourceManagerClient>& client,
uintptr_t cookie);
+ // To increase/decrease the number of instances of a given resource
+ // associated with a client.
+ void increaseResourceInstanceCount(int64_t clientId, const std::string& name);
+ void decreaseResourceInstanceCount(int64_t clientId, const std::string& name);
+
+ void pushReclaimAtom(const ClientInfoParcel& clientInfo,
+ const Vector<std::shared_ptr<IResourceManagerClient>>& clients,
+ const PidUidVector& idList, bool reclaimed);
+
mutable Mutex mLock;
sp<ProcessInfoInterface> mProcessInfo;
sp<SystemCallbackInterface> mSystemCB;
@@ -191,6 +211,11 @@
static std::map<uintptr_t, sp<DeathNotifier> > sCookieToDeathNotifierMap
GUARDED_BY(sCookieLock);
std::shared_ptr<ResourceObserverService> mObserverService;
+
+ // List of active clients
+ std::set<int64_t> mClientIdSet;
+ // Map of resources (name) and number of concurrent instances
+ std::map<std::string, int> mConcurrentResourceCountMap;
};
// ----------------------------------------------------------------------------
diff --git a/services/mediaresourcemanager/aidl/android/media/ClientInfoParcel.aidl b/services/mediaresourcemanager/aidl/android/media/ClientInfoParcel.aidl
new file mode 100644
index 0000000..eb4bc42
--- /dev/null
+++ b/services/mediaresourcemanager/aidl/android/media/ClientInfoParcel.aidl
@@ -0,0 +1,44 @@
+/**
+ * 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.
+ */
+
+package android.media;
+
+/**
+ * Description of a Client(codec) information.
+ *
+ * {@hide}
+ */
+parcelable ClientInfoParcel {
+ /**
+ * The PID of the client process.
+ */
+ int pid = -1;
+
+ /**
+ * The UID of the client process.
+ */
+ int uid = -1;
+
+ /**
+ * The ID of the client.
+ */
+ long id = 0;
+
+ /**
+ * Name of the resource associated with the client.
+ */
+ @utf8InCpp String name;
+}
diff --git a/services/mediaresourcemanager/aidl/android/media/IResourceManagerService.aidl b/services/mediaresourcemanager/aidl/android/media/IResourceManagerService.aidl
index 7a0a50f..30ad41b 100644
--- a/services/mediaresourcemanager/aidl/android/media/IResourceManagerService.aidl
+++ b/services/mediaresourcemanager/aidl/android/media/IResourceManagerService.aidl
@@ -19,6 +19,7 @@
import android.media.IResourceManagerClient;
import android.media.MediaResourceParcel;
import android.media.MediaResourcePolicyParcel;
+import android.media.ClientInfoParcel;
/**
* ResourceManagerService interface that keeps track of media resource
@@ -44,46 +45,40 @@
/**
* Add a client to a process with a list of resources.
*
- * @param pid pid of the client.
- * @param uid uid of the client.
- * @param clientId an identifier that uniquely identifies the client within the pid.
+ * @param clientInfo info of the calling client.
* @param client interface for the ResourceManagerService to call the client.
* @param resources an array of resources to be added.
*/
void addResource(
- int pid,
- int uid,
- long clientId,
+ in ClientInfoParcel clientInfo,
IResourceManagerClient client,
in MediaResourceParcel[] resources);
/**
* Remove the listed resources from a client.
*
- * @param pid pid from which the list of resources will be removed.
- * @param clientId clientId within the pid from which the list of resources will be removed.
+ * @param clientInfo info of the calling client.
* @param resources an array of resources to be removed from the client.
*/
- void removeResource(int pid, long clientId, in MediaResourceParcel[] resources);
+ void removeResource(in ClientInfoParcel clientInfo, in MediaResourceParcel[] resources);
/**
* Remove all resources from a client.
*
- * @param pid pid from which the client's resources will be removed.
- * @param clientId clientId within the pid that will be removed.
+ * @param clientInfo info of the calling client.
*/
- void removeClient(int pid, long clientId);
+ void removeClient(in ClientInfoParcel clientInfo);
/**
* Tries to reclaim resource from processes with lower priority than the
* calling process according to the requested resources.
*
- * @param callingPid pid of the calling process.
+ * @param clientInfo info of the calling client.
* @param resources an array of resources to be reclaimed.
*
* @return true if the reclaim was successful and false otherwise.
*/
- boolean reclaimResource(int callingPid, in MediaResourceParcel[] resources);
+ boolean reclaimResource(in ClientInfoParcel clientInfo, in MediaResourceParcel[] resources);
/**
* Override the pid of original calling process with the pid of the process
@@ -120,10 +115,9 @@
/**
* Mark a client for pending removal
*
- * @param pid pid from which the client's resources will be removed.
- * @param clientId clientId within the pid that will be removed.
+ * @param clientInfo info of the calling client.
*/
- void markClientForPendingRemoval(int pid, long clientId);
+ void markClientForPendingRemoval(in ClientInfoParcel clientInfo);
/**
* Reclaim resources from clients pending removal, if any.
diff --git a/services/mediaresourcemanager/fuzzer/Android.bp b/services/mediaresourcemanager/fuzzer/Android.bp
index 81c85e5..1d7f14f 100644
--- a/services/mediaresourcemanager/fuzzer/Android.bp
+++ b/services/mediaresourcemanager/fuzzer/Android.bp
@@ -41,6 +41,9 @@
"libbinder_ndk",
"libmedia",
"libutils",
+ "libstats_media_metrics",
+ "libstatspull",
+ "libstatssocket",
],
fuzz_config: {
cc: [
diff --git a/services/mediaresourcemanager/fuzzer/mediaresourcemanager_fuzzer.cpp b/services/mediaresourcemanager/fuzzer/mediaresourcemanager_fuzzer.cpp
index e4aaea0..5c2fef9 100644
--- a/services/mediaresourcemanager/fuzzer/mediaresourcemanager_fuzzer.cpp
+++ b/services/mediaresourcemanager/fuzzer/mediaresourcemanager_fuzzer.cpp
@@ -135,11 +135,15 @@
};
struct TestClient : public BnResourceManagerClient {
- TestClient(int pid, const shared_ptr<ResourceManagerService>& service)
- : mReclaimed(false), mPid(pid), mService(service) {}
+ TestClient(int pid, int uid, const shared_ptr<ResourceManagerService>& service)
+ : mReclaimed(false), mPid(pid), mUid(uid), mService(service) {}
Status reclaimResource(bool* aidlReturn) override {
- mService->removeClient(mPid, getId(ref<TestClient>()));
+ ClientInfoParcel clientInfo{.pid = static_cast<int32_t>(mPid),
+ .uid = static_cast<int32_t>(mUid),
+ .id = getId(ref<TestClient>()),
+ .name = ""};
+ mService->removeClient(clientInfo);
mReclaimed = true;
*aidlReturn = true;
return Status::ok();
@@ -155,6 +159,7 @@
private:
bool mReclaimed;
int mPid;
+ int mUid;
shared_ptr<ResourceManagerService> mService;
DISALLOW_EVIL_CONSTRUCTORS(TestClient);
};
@@ -176,9 +181,12 @@
static void* addResource(void* arg) {
resourceThreadArgs* tArgs = (resourceThreadArgs*)arg;
if (tArgs) {
+ ClientInfoParcel clientInfo{.pid = static_cast<int32_t>(tArgs->pid),
+ .uid = static_cast<int32_t>(tArgs->uid),
+ .id = tArgs->testClientId,
+ .name = ""};
(tArgs->service)
- ->addResource(tArgs->pid, tArgs->uid, tArgs->testClientId, tArgs->testClient,
- tArgs->mediaResource);
+ ->addResource(clientInfo, tArgs->testClient, tArgs->mediaResource);
}
return nullptr;
}
@@ -187,10 +195,14 @@
resourceThreadArgs* tArgs = (resourceThreadArgs*)arg;
if (tArgs) {
bool result;
- (tArgs->service)->markClientForPendingRemoval(tArgs->pid, tArgs->testClientId);
- (tArgs->service)->removeResource(tArgs->pid, tArgs->testClientId, tArgs->mediaResource);
- (tArgs->service)->reclaimResource(tArgs->pid, tArgs->mediaResource, &result);
- (tArgs->service)->removeClient(tArgs->pid, tArgs->testClientId);
+ ClientInfoParcel clientInfo{.pid = static_cast<int32_t>(tArgs->pid),
+ .uid = static_cast<int32_t>(tArgs->uid),
+ .id = tArgs->testClientId,
+ .name = ""};
+ (tArgs->service)->markClientForPendingRemoval(clientInfo);
+ (tArgs->service)->removeResource(clientInfo, tArgs->mediaResource);
+ (tArgs->service)->reclaimResource(clientInfo, tArgs->mediaResource, &result);
+ (tArgs->service)->removeClient(clientInfo);
(tArgs->service)->overridePid(tArgs->pid, tArgs->pid - 1);
}
return nullptr;
@@ -240,7 +252,8 @@
uint64_t mediaResourceValue = mFuzzedDataProvider->ConsumeIntegral<uint64_t>();
threadArgs[k].service = mService;
shared_ptr<IResourceManagerClient> testClient =
- ::ndk::SharedRefBase::make<TestClient>(threadArgs[k].pid, mService);
+ ::ndk::SharedRefBase::make<TestClient>(threadArgs[k].pid, threadArgs[k].uid,
+ mService);
threadArgs[k].testClient = testClient;
threadArgs[k].testClientId = getId(testClient);
mediaResource[k].push_back(MediaResource(static_cast<MedResType>(mediaResourceType),
@@ -258,7 +271,7 @@
// No resource was added with pid = 0
int32_t pidZero = 0;
shared_ptr<IResourceManagerClient> testClient =
- ::ndk::SharedRefBase::make<TestClient>(pidZero, mService);
+ ::ndk::SharedRefBase::make<TestClient>(pidZero, 0, mService);
int32_t mediaResourceType =
mFuzzedDataProvider->ConsumeIntegralInRange<int32_t>(kMinResourceType, kMaxResourceType);
int32_t mediaResourceSubType =
@@ -269,9 +282,13 @@
static_cast<MedResSubType>(mediaResourceSubType),
mediaResourceValue));
bool result;
- mService->reclaimResource(pidZero, mediaRes, &result);
- mService->removeResource(pidZero, getId(testClient), mediaRes);
- mService->removeClient(pidZero, getId(testClient));
+ ClientInfoParcel pidZeroClient{.pid = static_cast<int32_t>(pidZero),
+ .uid = static_cast<int32_t>(0),
+ .id = getId(testClient),
+ .name = ""};
+ mService->reclaimResource(pidZeroClient, mediaRes, &result);
+ mService->removeResource(pidZeroClient, mediaRes);
+ mService->removeClient(pidZeroClient);
}
void ResourceManagerServiceFuzzer::setServiceLog() {
diff --git a/services/mediaresourcemanager/test/Android.bp b/services/mediaresourcemanager/test/Android.bp
index 618626f..60bb8c3 100644
--- a/services/mediaresourcemanager/test/Android.bp
+++ b/services/mediaresourcemanager/test/Android.bp
@@ -19,6 +19,9 @@
"liblog",
"libmedia",
"libutils",
+ "libstats_media_metrics",
+ "libstatspull",
+ "libstatssocket",
],
include_dirs: [
"frameworks/av/include",
@@ -64,6 +67,9 @@
"liblog",
"libmedia",
"libutils",
+ "libstats_media_metrics",
+ "libstatspull",
+ "libstatssocket",
],
include_dirs: [
"frameworks/av/include",
diff --git a/services/mediaresourcemanager/test/ResourceManagerServiceTestUtils.h b/services/mediaresourcemanager/test/ResourceManagerServiceTestUtils.h
index 5bf44ce..8194e23 100644
--- a/services/mediaresourcemanager/test/ResourceManagerServiceTestUtils.h
+++ b/services/mediaresourcemanager/test/ResourceManagerServiceTestUtils.h
@@ -122,11 +122,15 @@
struct TestClient : public BnResourceManagerClient {
- TestClient(int pid, const std::shared_ptr<ResourceManagerService> &service)
- : mPid(pid), mService(service) {}
+ TestClient(int pid, int uid, const std::shared_ptr<ResourceManagerService> &service)
+ : mPid(pid), mUid(uid), mService(service) {}
Status reclaimResource(bool* _aidl_return) override {
- mService->removeClient(mPid, getId(ref<TestClient>()));
+ ClientInfoParcel clientInfo{.pid = static_cast<int32_t>(mPid),
+ .uid = static_cast<int32_t>(mUid),
+ .id = getId(ref<TestClient>()),
+ .name = "none"};
+ mService->removeClient(clientInfo);
mWasReclaimResourceCalled = true;
*_aidl_return = true;
return Status::ok();
@@ -148,6 +152,7 @@
private:
bool mWasReclaimResourceCalled = false;
int mPid;
+ int mUid;
std::shared_ptr<ResourceManagerService> mService;
DISALLOW_EVIL_CONSTRUCTORS(TestClient);
};
@@ -196,13 +201,13 @@
: mSystemCB(new TestSystemCallback()),
mService(::ndk::SharedRefBase::make<ResourceManagerService>(
new TestProcessInfo, mSystemCB)),
- mTestClient1(::ndk::SharedRefBase::make<TestClient>(kTestPid1, mService)),
- mTestClient2(::ndk::SharedRefBase::make<TestClient>(kTestPid2, mService)),
- mTestClient3(::ndk::SharedRefBase::make<TestClient>(kTestPid2, mService)) {
+ mTestClient1(::ndk::SharedRefBase::make<TestClient>(kTestPid1, kTestUid1, mService)),
+ mTestClient2(::ndk::SharedRefBase::make<TestClient>(kTestPid2, kTestUid2, mService)),
+ mTestClient3(::ndk::SharedRefBase::make<TestClient>(kTestPid2, kTestUid2, mService)) {
}
- std::shared_ptr<IResourceManagerClient> createTestClient(int pid) {
- return ::ndk::SharedRefBase::make<TestClient>(pid, mService);
+ std::shared_ptr<IResourceManagerClient> createTestClient(int pid, int uid) {
+ return ::ndk::SharedRefBase::make<TestClient>(pid, uid, mService);
}
sp<TestSystemCallback> mSystemCB;
diff --git a/services/mediaresourcemanager/test/ResourceManagerService_test.cpp b/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
index 8739c3b..41cccb8 100644
--- a/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
+++ b/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
@@ -98,24 +98,36 @@
// kTestPid1 mTestClient1
std::vector<MediaResourceParcel> resources1;
resources1.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
- mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
+ ClientInfoParcel client1Info{.pid = static_cast<int32_t>(kTestPid1),
+ .uid = static_cast<int32_t>(kTestUid1),
+ .id = getId(mTestClient1),
+ .name = "none"};
+ mService->addResource(client1Info, mTestClient1, resources1);
resources1.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 200));
std::vector<MediaResourceParcel> resources11;
resources11.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 200));
- mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources11);
+ mService->addResource(client1Info, mTestClient1, resources11);
// kTestPid2 mTestClient2
std::vector<MediaResourceParcel> resources2;
resources2.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1));
resources2.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 300));
- mService->addResource(kTestPid2, kTestUid2, getId(mTestClient2), mTestClient2, resources2);
+ ClientInfoParcel client2Info{.pid = static_cast<int32_t>(kTestPid2),
+ .uid = static_cast<int32_t>(kTestUid2),
+ .id = getId(mTestClient2),
+ .name = "none"};
+ mService->addResource(client2Info, mTestClient2, resources2);
// kTestPid2 mTestClient3
std::vector<MediaResourceParcel> resources3;
- mService->addResource(kTestPid2, kTestUid2, getId(mTestClient3), mTestClient3, resources3);
+ ClientInfoParcel client3Info{.pid = static_cast<int32_t>(kTestPid2),
+ .uid = static_cast<int32_t>(kTestUid2),
+ .id = getId(mTestClient3),
+ .name = "none"};
+ mService->addResource(client3Info, mTestClient3, resources3);
resources3.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
resources3.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 100));
- mService->addResource(kTestPid2, kTestUid2, getId(mTestClient3), mTestClient3, resources3);
+ mService->addResource(client3Info, mTestClient3, resources3);
const PidResourceInfosMap &map = mService->mMap;
EXPECT_EQ(2u, map.size());
@@ -138,7 +150,11 @@
std::vector<MediaResourceParcel> resources1;
resources1.push_back(MediaResource(MediaResource::Type::kDrmSession, -100));
resources1.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, -100));
- mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
+ ClientInfoParcel client1Info{.pid = static_cast<int32_t>(kTestPid1),
+ .uid = static_cast<int32_t>(kTestUid1),
+ .id = getId(mTestClient1),
+ .name = "none"};
+ mService->addResource(client1Info, mTestClient1, resources1);
// Expected result:
// 1) the client should have been added;
@@ -155,11 +171,11 @@
resources1.clear();
resources1.push_back(MediaResource(MediaResource::Type::kDrmSession, INT64_MAX));
resources1.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, INT64_MAX));
- mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
+ mService->addResource(client1Info, mTestClient1, resources1);
resources1.clear();
resources1.push_back(MediaResource(MediaResource::Type::kDrmSession, 10));
resources1.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 10));
- mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
+ mService->addResource(client1Info, mTestClient1, resources1);
// Expected result:
// Both values should saturate to INT64_MAX
@@ -170,7 +186,7 @@
resources1.clear();
resources1.push_back(MediaResource(MediaResource::Type::kDrmSession, -10));
resources1.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, -10));
- mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
+ mService->addResource(client1Info, mTestClient1, resources1);
// Expected result:
// 1) DrmSession resource should allow negative value addition, and value should drop accordingly
@@ -182,7 +198,7 @@
resources1.clear();
resources1.push_back(MediaResource(MediaResource::Type::kDrmSession, INT64_MIN));
expected.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, INT64_MIN));
- mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
+ mService->addResource(client1Info, mTestClient1, resources1);
// Expected result:
// 1) DrmSession resource value should drop to 0, but the entry shouldn't be removed.
@@ -228,11 +244,15 @@
// kTestPid1 mTestClient1
std::vector<MediaResourceParcel> resources1;
resources1.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
- mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
+ ClientInfoParcel client1Info{.pid = static_cast<int32_t>(kTestPid1),
+ .uid = static_cast<int32_t>(kTestUid1),
+ .id = getId(mTestClient1),
+ .name = "none"};
+ mService->addResource(client1Info, mTestClient1, resources1);
std::vector<MediaResourceParcel> resources11;
resources11.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 200));
- mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources11);
+ mService->addResource(client1Info, mTestClient1, resources11);
const PidResourceInfosMap &map = mService->mMap;
EXPECT_EQ(1u, map.size());
@@ -243,7 +263,7 @@
// test adding existing types to combine values
resources1.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 100));
- mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
+ mService->addResource(client1Info, mTestClient1, resources1);
std::vector<MediaResourceParcel> expected;
expected.push_back(MediaResource(MediaResource::Type::kSecureCodec, 2));
@@ -253,7 +273,7 @@
// test adding new types (including types that differs only in subType)
resources11.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1));
resources11.push_back(MediaResource(MediaResource::Type::kSecureCodec, MediaResource::SubType::kVideoCodec, 1));
- mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources11);
+ mService->addResource(client1Info, mTestClient1, resources11);
expected.clear();
expected.push_back(MediaResource(MediaResource::Type::kSecureCodec, 2));
@@ -267,11 +287,15 @@
// kTestPid1 mTestClient1
std::vector<MediaResourceParcel> resources1;
resources1.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
- mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
+ ClientInfoParcel client1Info{.pid = static_cast<int32_t>(kTestPid1),
+ .uid = static_cast<int32_t>(kTestUid1),
+ .id = getId(mTestClient1),
+ .name = "none"};
+ mService->addResource(client1Info, mTestClient1, resources1);
std::vector<MediaResourceParcel> resources11;
resources11.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 200));
- mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources11);
+ mService->addResource(client1Info, mTestClient1, resources11);
const PidResourceInfosMap &map = mService->mMap;
EXPECT_EQ(1u, map.size());
@@ -282,7 +306,7 @@
// test partial removal
resources11[0].value = 100;
- mService->removeResource(kTestPid1, getId(mTestClient1), resources11);
+ mService->removeResource(client1Info, resources11);
std::vector<MediaResourceParcel> expected;
expected.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
@@ -291,13 +315,13 @@
// test removal request with negative value, should be ignored
resources11[0].value = -10000;
- mService->removeResource(kTestPid1, getId(mTestClient1), resources11);
+ mService->removeResource(client1Info, resources11);
expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
// test complete removal with overshoot value
resources11[0].value = 1000;
- mService->removeResource(kTestPid1, getId(mTestClient1), resources11);
+ mService->removeResource(client1Info, resources11);
expected.clear();
expected.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
@@ -317,19 +341,35 @@
mService->mSupportsSecureWithNonSecureCodec = true;
// priority too low to reclaim resource
- CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
+ ClientInfoParcel clientInfo{.pid = static_cast<int32_t>(kLowPriorityPid),
+ .uid = static_cast<int32_t>(kTestUid1),
+ .id = 0,
+ .name = "none"};
+ CHECK_STATUS_FALSE(mService->reclaimResource(clientInfo, resources, &result));
// override Low Priority Pid with High Priority Pid
mService->overridePid(kLowPriorityPid, kHighPriorityPid);
- CHECK_STATUS_TRUE(mService->reclaimResource(kLowPriorityPid, resources, &result));
+ CHECK_STATUS_TRUE(mService->reclaimResource(clientInfo, resources, &result));
// restore Low Priority Pid
mService->overridePid(kLowPriorityPid, -1);
- CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
+ CHECK_STATUS_FALSE(mService->reclaimResource(clientInfo, resources, &result));
}
}
void testMarkClientForPendingRemoval() {
+ ClientInfoParcel client1Info{.pid = static_cast<int32_t>(kTestPid1),
+ .uid = static_cast<int32_t>(kTestUid1),
+ .id = getId(mTestClient1),
+ .name = "none"};
+ ClientInfoParcel client2Info{.pid = static_cast<int32_t>(kTestPid2),
+ .uid = static_cast<int32_t>(kTestUid2),
+ .id = getId(mTestClient2),
+ .name = "none"};
+ ClientInfoParcel client3Info{.pid = static_cast<int32_t>(kTestPid2),
+ .uid = static_cast<int32_t>(kTestUid2),
+ .id = getId(mTestClient3),
+ .name = "none"};
{
addResource();
mService->mSupportsSecureWithNonSecureCodec = true;
@@ -338,24 +378,24 @@
resources.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1));
// Remove low priority clients
- mService->removeClient(kTestPid1, getId(mTestClient1));
+ mService->removeClient(client1Info);
// no lower priority client
- CHECK_STATUS_FALSE(mService->reclaimResource(kTestPid2, resources, &result));
+ CHECK_STATUS_FALSE(mService->reclaimResource(client2Info, resources, &result));
EXPECT_EQ(false, toTestClient(mTestClient1)->checkIfReclaimedAndReset());
EXPECT_EQ(false, toTestClient(mTestClient2)->checkIfReclaimedAndReset());
EXPECT_EQ(false, toTestClient(mTestClient3)->checkIfReclaimedAndReset());
- mService->markClientForPendingRemoval(kTestPid2, getId(mTestClient2));
+ mService->markClientForPendingRemoval(client2Info);
// client marked for pending removal from the same process got reclaimed
- CHECK_STATUS_TRUE(mService->reclaimResource(kTestPid2, resources, &result));
+ CHECK_STATUS_TRUE(mService->reclaimResource(client2Info, resources, &result));
EXPECT_EQ(false, toTestClient(mTestClient1)->checkIfReclaimedAndReset());
EXPECT_EQ(true, toTestClient(mTestClient2)->checkIfReclaimedAndReset());
EXPECT_EQ(false, toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// clean up client 3 which still left
- mService->removeClient(kTestPid2, getId(mTestClient3));
+ mService->removeClient(client3Info);
}
{
@@ -365,30 +405,30 @@
std::vector<MediaResourceParcel> resources;
resources.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1));
- mService->markClientForPendingRemoval(kTestPid2, getId(mTestClient2));
+ mService->markClientForPendingRemoval(client2Info);
// client marked for pending removal from the same process got reclaimed
// first, even though there are lower priority process
- CHECK_STATUS_TRUE(mService->reclaimResource(kTestPid2, resources, &result));
+ CHECK_STATUS_TRUE(mService->reclaimResource(client2Info, resources, &result));
EXPECT_EQ(false, toTestClient(mTestClient1)->checkIfReclaimedAndReset());
EXPECT_EQ(true, toTestClient(mTestClient2)->checkIfReclaimedAndReset());
EXPECT_EQ(false, toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// lower priority client got reclaimed
- CHECK_STATUS_TRUE(mService->reclaimResource(kTestPid2, resources, &result));
+ CHECK_STATUS_TRUE(mService->reclaimResource(client2Info, resources, &result));
EXPECT_EQ(true, toTestClient(mTestClient1)->checkIfReclaimedAndReset());
EXPECT_EQ(false, toTestClient(mTestClient2)->checkIfReclaimedAndReset());
EXPECT_EQ(false, toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// clean up client 3 which still left
- mService->removeClient(kTestPid2, getId(mTestClient3));
+ mService->removeClient(client3Info);
}
{
addResource();
mService->mSupportsSecureWithNonSecureCodec = true;
- mService->markClientForPendingRemoval(kTestPid2, getId(mTestClient2));
+ mService->markClientForPendingRemoval(client2Info);
// client marked for pending removal got reclaimed
EXPECT_TRUE(mService->reclaimResourcesFromClientsPendingRemoval(kTestPid2).isOk());
@@ -402,7 +442,7 @@
EXPECT_EQ(false, toTestClient(mTestClient2)->checkIfReclaimedAndReset());
EXPECT_EQ(false, toTestClient(mTestClient3)->checkIfReclaimedAndReset());
- mService->markClientForPendingRemoval(kTestPid2, getId(mTestClient3));
+ mService->markClientForPendingRemoval(client3Info);
// client marked for pending removal got reclaimed
EXPECT_TRUE(mService->reclaimResourcesFromClientsPendingRemoval(kTestPid2).isOk());
@@ -411,14 +451,18 @@
EXPECT_EQ(true, toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// clean up client 1 which still left
- mService->removeClient(kTestPid1, getId(mTestClient1));
+ mService->removeClient(client1Info);
}
}
void testRemoveClient() {
addResource();
- mService->removeClient(kTestPid2, getId(mTestClient2));
+ ClientInfoParcel client2Info{.pid = static_cast<int32_t>(kTestPid2),
+ .uid = static_cast<int32_t>(kTestUid2),
+ .id = getId(mTestClient2),
+ .name = "none"};
+ mService->removeClient(client2Info);
const PidResourceInfosMap &map = mService->mMap;
EXPECT_EQ(2u, map.size());
@@ -437,11 +481,12 @@
MediaResource::SubType subType = MediaResource::SubType::kUnspecifiedSubType;
Vector<std::shared_ptr<IResourceManagerClient> > clients;
- EXPECT_FALSE(mService->getAllClients_l(kLowPriorityPid, type, subType, &clients));
+ PidUidVector idList;
+ EXPECT_FALSE(mService->getAllClients_l(kLowPriorityPid, type, subType, &idList, &clients));
// some higher priority process (e.g. kTestPid2) owns the resource, so getAllClients_l
// will fail.
- EXPECT_FALSE(mService->getAllClients_l(kMidPriorityPid, type, subType, &clients));
- EXPECT_TRUE(mService->getAllClients_l(kHighPriorityPid, type, subType, &clients));
+ EXPECT_FALSE(mService->getAllClients_l(kMidPriorityPid, type, subType, &idList, &clients));
+ EXPECT_TRUE(mService->getAllClients_l(kHighPriorityPid, type, subType, &idList, &clients));
EXPECT_EQ(2u, clients.size());
// (OK to require ordering in clients[], as the pid map is sorted)
@@ -454,6 +499,19 @@
resources.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
resources.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 150));
+ ClientInfoParcel lowPriorityClient{.pid = static_cast<int32_t>(kLowPriorityPid),
+ .uid = static_cast<int32_t>(kTestUid2),
+ .id = 0,
+ .name = "none"};
+ ClientInfoParcel midPriorityClient{.pid = static_cast<int32_t>(kMidPriorityPid),
+ .uid = static_cast<int32_t>(kTestUid2),
+ .id = 0,
+ .name = "none"};
+ ClientInfoParcel highPriorityClient{.pid = static_cast<int32_t>(kHighPriorityPid),
+ .uid = static_cast<int32_t>(kTestUid2),
+ .id = 0,
+ .name = "none"};
+
// ### secure codec can't coexist and secure codec can coexist with non-secure codec ###
{
addResource();
@@ -461,23 +519,23 @@
mService->mSupportsSecureWithNonSecureCodec = true;
// priority too low
- CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
- CHECK_STATUS_FALSE(mService->reclaimResource(kMidPriorityPid, resources, &result));
+ CHECK_STATUS_FALSE(mService->reclaimResource(lowPriorityClient, resources, &result));
+ CHECK_STATUS_FALSE(mService->reclaimResource(midPriorityClient, resources, &result));
// reclaim all secure codecs
- CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
+ CHECK_STATUS_TRUE(mService->reclaimResource(highPriorityClient, resources, &result));
EXPECT_TRUE(toTestClient(mTestClient1)->checkIfReclaimedAndReset());
EXPECT_FALSE(toTestClient(mTestClient2)->checkIfReclaimedAndReset());
EXPECT_TRUE(toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// call again should reclaim one largest graphic memory from lowest process
- CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
+ CHECK_STATUS_TRUE(mService->reclaimResource(highPriorityClient, resources, &result));
EXPECT_FALSE(toTestClient(mTestClient1)->checkIfReclaimedAndReset());
EXPECT_TRUE(toTestClient(mTestClient2)->checkIfReclaimedAndReset());
EXPECT_FALSE(toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// nothing left
- CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result));
+ CHECK_STATUS_FALSE(mService->reclaimResource(highPriorityClient, resources, &result));
}
// ### secure codecs can't coexist and secure codec can't coexist with non-secure codec ###
@@ -487,17 +545,17 @@
mService->mSupportsSecureWithNonSecureCodec = false;
// priority too low
- CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
- CHECK_STATUS_FALSE(mService->reclaimResource(kMidPriorityPid, resources, &result));
+ CHECK_STATUS_FALSE(mService->reclaimResource(lowPriorityClient, resources, &result));
+ CHECK_STATUS_FALSE(mService->reclaimResource(midPriorityClient, resources, &result));
// reclaim all secure and non-secure codecs
- CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
+ CHECK_STATUS_TRUE(mService->reclaimResource(highPriorityClient, resources, &result));
EXPECT_TRUE(toTestClient(mTestClient1)->checkIfReclaimedAndReset());
EXPECT_TRUE(toTestClient(mTestClient2)->checkIfReclaimedAndReset());
EXPECT_TRUE(toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// nothing left
- CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result));
+ CHECK_STATUS_FALSE(mService->reclaimResource(highPriorityClient, resources, &result));
}
@@ -508,29 +566,29 @@
mService->mSupportsSecureWithNonSecureCodec = false;
// priority too low
- CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
- CHECK_STATUS_FALSE(mService->reclaimResource(kMidPriorityPid, resources, &result));
+ CHECK_STATUS_FALSE(mService->reclaimResource(lowPriorityClient, resources, &result));
+ CHECK_STATUS_FALSE(mService->reclaimResource(midPriorityClient, resources, &result));
// reclaim all non-secure codecs
- CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
+ CHECK_STATUS_TRUE(mService->reclaimResource(highPriorityClient, resources, &result));
EXPECT_FALSE(toTestClient(mTestClient1)->checkIfReclaimedAndReset());
EXPECT_TRUE(toTestClient(mTestClient2)->checkIfReclaimedAndReset());
EXPECT_FALSE(toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// call again should reclaim one largest graphic memory from lowest process
- CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
+ CHECK_STATUS_TRUE(mService->reclaimResource(highPriorityClient, resources, &result));
EXPECT_TRUE(toTestClient(mTestClient1)->checkIfReclaimedAndReset());
EXPECT_FALSE(toTestClient(mTestClient2)->checkIfReclaimedAndReset());
EXPECT_FALSE(toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// call again should reclaim another largest graphic memory from lowest process
- CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
+ CHECK_STATUS_TRUE(mService->reclaimResource(highPriorityClient, resources, &result));
EXPECT_FALSE(toTestClient(mTestClient1)->checkIfReclaimedAndReset());
EXPECT_FALSE(toTestClient(mTestClient2)->checkIfReclaimedAndReset());
EXPECT_TRUE(toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// nothing left
- CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result));
+ CHECK_STATUS_FALSE(mService->reclaimResource(highPriorityClient, resources, &result));
}
// ### secure codecs can coexist and secure codec can coexist with non-secure codec ###
@@ -540,28 +598,28 @@
mService->mSupportsSecureWithNonSecureCodec = true;
// priority too low
- CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
+ CHECK_STATUS_FALSE(mService->reclaimResource(lowPriorityClient, resources, &result));
- CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
+ CHECK_STATUS_TRUE(mService->reclaimResource(highPriorityClient, resources, &result));
// one largest graphic memory from lowest process got reclaimed
EXPECT_TRUE(toTestClient(mTestClient1)->checkIfReclaimedAndReset());
EXPECT_FALSE(toTestClient(mTestClient2)->checkIfReclaimedAndReset());
EXPECT_FALSE(toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// call again should reclaim another graphic memory from lowest process
- CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
+ CHECK_STATUS_TRUE(mService->reclaimResource(highPriorityClient, resources, &result));
EXPECT_FALSE(toTestClient(mTestClient1)->checkIfReclaimedAndReset());
EXPECT_TRUE(toTestClient(mTestClient2)->checkIfReclaimedAndReset());
EXPECT_FALSE(toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// call again should reclaim another graphic memory from lowest process
- CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
+ CHECK_STATUS_TRUE(mService->reclaimResource(highPriorityClient, resources, &result));
EXPECT_FALSE(toTestClient(mTestClient1)->checkIfReclaimedAndReset());
EXPECT_FALSE(toTestClient(mTestClient2)->checkIfReclaimedAndReset());
EXPECT_TRUE(toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// nothing left
- CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result));
+ CHECK_STATUS_FALSE(mService->reclaimResource(highPriorityClient, resources, &result));
}
// ### secure codecs can coexist and secure codec can coexist with non-secure codec ###
@@ -573,20 +631,20 @@
std::vector<MediaResourceParcel> resources;
resources.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
- CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
+ CHECK_STATUS_TRUE(mService->reclaimResource(highPriorityClient, resources, &result));
// secure codec from lowest process got reclaimed
EXPECT_TRUE(toTestClient(mTestClient1)->checkIfReclaimedAndReset());
EXPECT_FALSE(toTestClient(mTestClient2)->checkIfReclaimedAndReset());
EXPECT_FALSE(toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// call again should reclaim another secure codec from lowest process
- CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
+ CHECK_STATUS_TRUE(mService->reclaimResource(highPriorityClient, resources, &result));
EXPECT_FALSE(toTestClient(mTestClient1)->checkIfReclaimedAndReset());
EXPECT_FALSE(toTestClient(mTestClient2)->checkIfReclaimedAndReset());
EXPECT_TRUE(toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// no more secure codec, non-secure codec will be reclaimed.
- CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
+ CHECK_STATUS_TRUE(mService->reclaimResource(highPriorityClient, resources, &result));
EXPECT_FALSE(toTestClient(mTestClient1)->checkIfReclaimedAndReset());
EXPECT_TRUE(toTestClient(mTestClient2)->checkIfReclaimedAndReset());
EXPECT_FALSE(toTestClient(mTestClient3)->checkIfReclaimedAndReset());
@@ -598,29 +656,42 @@
resources.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1));
resources.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 150));
+ ClientInfoParcel lowPriorityClient{.pid = static_cast<int32_t>(kLowPriorityPid),
+ .uid = static_cast<int32_t>(kTestUid2),
+ .id = 0,
+ .name = "none"};
+ ClientInfoParcel midPriorityClient{.pid = static_cast<int32_t>(kMidPriorityPid),
+ .uid = static_cast<int32_t>(kTestUid2),
+ .id = 0,
+ .name = "none"};
+ ClientInfoParcel highPriorityClient{.pid = static_cast<int32_t>(kHighPriorityPid),
+ .uid = static_cast<int32_t>(kTestUid2),
+ .id = 0,
+ .name = "none"};
+
// ### secure codec can't coexist with non-secure codec ###
{
addResource();
mService->mSupportsSecureWithNonSecureCodec = false;
// priority too low
- CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
- CHECK_STATUS_FALSE(mService->reclaimResource(kMidPriorityPid, resources, &result));
+ CHECK_STATUS_FALSE(mService->reclaimResource(lowPriorityClient, resources, &result));
+ CHECK_STATUS_FALSE(mService->reclaimResource(midPriorityClient, resources, &result));
// reclaim all secure codecs
- CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
+ CHECK_STATUS_TRUE(mService->reclaimResource(highPriorityClient, resources, &result));
EXPECT_TRUE(toTestClient(mTestClient1)->checkIfReclaimedAndReset());
EXPECT_FALSE(toTestClient(mTestClient2)->checkIfReclaimedAndReset());
EXPECT_TRUE(toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// call again should reclaim one graphic memory from lowest process
- CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
+ CHECK_STATUS_TRUE(mService->reclaimResource(highPriorityClient, resources, &result));
EXPECT_FALSE(toTestClient(mTestClient1)->checkIfReclaimedAndReset());
EXPECT_TRUE(toTestClient(mTestClient2)->checkIfReclaimedAndReset());
EXPECT_FALSE(toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// nothing left
- CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result));
+ CHECK_STATUS_FALSE(mService->reclaimResource(highPriorityClient, resources, &result));
}
@@ -630,28 +701,28 @@
mService->mSupportsSecureWithNonSecureCodec = true;
// priority too low
- CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
+ CHECK_STATUS_FALSE(mService->reclaimResource(lowPriorityClient, resources, &result));
- CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
+ CHECK_STATUS_TRUE(mService->reclaimResource(highPriorityClient, resources, &result));
// one largest graphic memory from lowest process got reclaimed
EXPECT_TRUE(toTestClient(mTestClient1)->checkIfReclaimedAndReset());
EXPECT_FALSE(toTestClient(mTestClient2)->checkIfReclaimedAndReset());
EXPECT_FALSE(toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// call again should reclaim another graphic memory from lowest process
- CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
+ CHECK_STATUS_TRUE(mService->reclaimResource(highPriorityClient, resources, &result));
EXPECT_FALSE(toTestClient(mTestClient1)->checkIfReclaimedAndReset());
EXPECT_TRUE(toTestClient(mTestClient2)->checkIfReclaimedAndReset());
EXPECT_FALSE(toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// call again should reclaim another graphic memory from lowest process
- CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
+ CHECK_STATUS_TRUE(mService->reclaimResource(highPriorityClient, resources, &result));
EXPECT_FALSE(toTestClient(mTestClient1)->checkIfReclaimedAndReset());
EXPECT_FALSE(toTestClient(mTestClient2)->checkIfReclaimedAndReset());
EXPECT_TRUE(toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// nothing left
- CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result));
+ CHECK_STATUS_FALSE(mService->reclaimResource(highPriorityClient, resources, &result));
}
// ### secure codec can coexist with non-secure codec ###
@@ -662,20 +733,24 @@
std::vector<MediaResourceParcel> resources;
resources.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1));
- CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
+ CHECK_STATUS_TRUE(mService->reclaimResource(highPriorityClient, resources, &result));
// one non secure codec from lowest process got reclaimed
EXPECT_FALSE(toTestClient(mTestClient1)->checkIfReclaimedAndReset());
EXPECT_TRUE(toTestClient(mTestClient2)->checkIfReclaimedAndReset());
EXPECT_FALSE(toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// no more non-secure codec, secure codec from lowest priority process will be reclaimed
- CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
+ CHECK_STATUS_TRUE(mService->reclaimResource(highPriorityClient, resources, &result));
EXPECT_TRUE(toTestClient(mTestClient1)->checkIfReclaimedAndReset());
EXPECT_FALSE(toTestClient(mTestClient2)->checkIfReclaimedAndReset());
EXPECT_FALSE(toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// clean up client 3 which still left
- mService->removeClient(kTestPid2, getId(mTestClient3));
+ ClientInfoParcel clientInfo{.pid = static_cast<int32_t>(kTestPid2),
+ .uid = static_cast<int32_t>(kTestUid2),
+ .id = getId(mTestClient3),
+ .name = "none"};
+ mService->removeClient(clientInfo);
}
}
@@ -683,15 +758,16 @@
MediaResource::Type type = MediaResource::Type::kGraphicMemory;
MediaResource::SubType subType = MediaResource::SubType::kUnspecifiedSubType;
std::shared_ptr<IResourceManagerClient> client;
+ PidUidVector idList;
EXPECT_FALSE(mService->getLowestPriorityBiggestClient_l(kHighPriorityPid, type, subType,
- &client));
+ &idList, &client));
addResource();
EXPECT_FALSE(mService->getLowestPriorityBiggestClient_l(kLowPriorityPid, type, subType,
- &client));
+ &idList, &client));
EXPECT_TRUE(mService->getLowestPriorityBiggestClient_l(kHighPriorityPid, type, subType,
- &client));
+ &idList, &client));
// kTestPid1 is the lowest priority process with MediaResource::Type::kGraphicMemory.
// mTestClient1 has the largest MediaResource::Type::kGraphicMemory within kTestPid1.
@@ -737,33 +813,41 @@
// new client request should cause VIDEO_ON
std::vector<MediaResourceParcel> resources1;
resources1.push_back(MediaResource(MediaResource::Type::kBattery, MediaResource::SubType::kVideoCodec, 1));
- mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
+ ClientInfoParcel client1Info{.pid = static_cast<int32_t>(kTestPid1),
+ .uid = static_cast<int32_t>(kTestUid1),
+ .id = getId(mTestClient1),
+ .name = "none"};
+ mService->addResource(client1Info, mTestClient1, resources1);
EXPECT_EQ(2u, mSystemCB->eventCount());
EXPECT_EQ(EventEntry({EventType::VIDEO_ON, kTestUid1}), mSystemCB->lastEvent());
// each client should only cause 1 VIDEO_ON
- mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
+ mService->addResource(client1Info, mTestClient1, resources1);
EXPECT_EQ(2u, mSystemCB->eventCount());
// new client request should cause VIDEO_ON
std::vector<MediaResourceParcel> resources2;
resources2.push_back(MediaResource(MediaResource::Type::kBattery, MediaResource::SubType::kVideoCodec, 2));
- mService->addResource(kTestPid2, kTestUid2, getId(mTestClient2), mTestClient2, resources2);
+ ClientInfoParcel client2Info{.pid = static_cast<int32_t>(kTestPid2),
+ .uid = static_cast<int32_t>(kTestUid2),
+ .id = getId(mTestClient2),
+ .name = "none"};
+ mService->addResource(client2Info, mTestClient2, resources2);
EXPECT_EQ(3u, mSystemCB->eventCount());
EXPECT_EQ(EventEntry({EventType::VIDEO_ON, kTestUid2}), mSystemCB->lastEvent());
// partially remove mTestClient1's request, shouldn't be any VIDEO_OFF
- mService->removeResource(kTestPid1, getId(mTestClient1), resources1);
+ mService->removeResource(client1Info, resources1);
EXPECT_EQ(3u, mSystemCB->eventCount());
// remove mTestClient1's request, should be VIDEO_OFF for kTestUid1
// (use resource2 to test removing more instances than previously requested)
- mService->removeResource(kTestPid1, getId(mTestClient1), resources2);
+ mService->removeResource(client1Info, resources2);
EXPECT_EQ(4u, mSystemCB->eventCount());
EXPECT_EQ(EventEntry({EventType::VIDEO_OFF, kTestUid1}), mSystemCB->lastEvent());
// remove mTestClient2, should be VIDEO_OFF for kTestUid2
- mService->removeClient(kTestPid2, getId(mTestClient2));
+ mService->removeClient(client2Info);
EXPECT_EQ(5u, mSystemCB->eventCount());
EXPECT_EQ(EventEntry({EventType::VIDEO_OFF, kTestUid2}), mSystemCB->lastEvent());
}
@@ -776,32 +860,40 @@
// new client request should cause CPUSET_ENABLE
std::vector<MediaResourceParcel> resources1;
resources1.push_back(MediaResource(MediaResource::Type::kCpuBoost, 1));
- mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
+ ClientInfoParcel client1Info{.pid = static_cast<int32_t>(kTestPid1),
+ .uid = static_cast<int32_t>(kTestUid1),
+ .id = getId(mTestClient1),
+ .name = "none"};
+ mService->addResource(client1Info, mTestClient1, resources1);
EXPECT_EQ(2u, mSystemCB->eventCount());
EXPECT_EQ(EventType::CPUSET_ENABLE, mSystemCB->lastEventType());
// each client should only cause 1 CPUSET_ENABLE
- mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
+ mService->addResource(client1Info, mTestClient1, resources1);
EXPECT_EQ(2u, mSystemCB->eventCount());
// new client request should cause CPUSET_ENABLE
std::vector<MediaResourceParcel> resources2;
resources2.push_back(MediaResource(MediaResource::Type::kCpuBoost, 2));
- mService->addResource(kTestPid2, kTestUid2, getId(mTestClient2), mTestClient2, resources2);
+ ClientInfoParcel client2Info{.pid = static_cast<int32_t>(kTestPid2),
+ .uid = static_cast<int32_t>(kTestUid2),
+ .id = getId(mTestClient2),
+ .name = "none"};
+ mService->addResource(client2Info, mTestClient2, resources2);
EXPECT_EQ(3u, mSystemCB->eventCount());
EXPECT_EQ(EventType::CPUSET_ENABLE, mSystemCB->lastEventType());
// remove mTestClient2 should not cause CPUSET_DISABLE, mTestClient1 still active
- mService->removeClient(kTestPid2, getId(mTestClient2));
+ mService->removeClient(client2Info);
EXPECT_EQ(3u, mSystemCB->eventCount());
// remove 1 cpuboost from mTestClient1, should not be CPUSET_DISABLE (still 1 left)
- mService->removeResource(kTestPid1, getId(mTestClient1), resources1);
+ mService->removeResource(client1Info, resources1);
EXPECT_EQ(3u, mSystemCB->eventCount());
// remove 2 cpuboost from mTestClient1, should be CPUSET_DISABLE
// (use resource2 to test removing more than previously requested)
- mService->removeResource(kTestPid1, getId(mTestClient1), resources2);
+ mService->removeResource(client1Info, resources2);
EXPECT_EQ(4u, mSystemCB->eventCount());
EXPECT_EQ(EventType::CPUSET_DISABLE, mSystemCB->lastEventType());
}
@@ -814,22 +906,32 @@
std::vector<MediaResourceParcel> audioImageResources;
audioImageResources.push_back(createNonSecureAudioCodecResource());
audioImageResources.push_back(createNonSecureImageCodecResource());
- mService->addResource(kLowPriorityPid, kTestUid1, getId(audioImageTestClient),
- audioImageTestClient, audioImageResources);
+ ClientInfoParcel client1Info{.pid = static_cast<int32_t>(kLowPriorityPid),
+ .uid = static_cast<int32_t>(kTestUid1),
+ .id = getId(audioImageTestClient),
+ .name = "none"};
+ mService->addResource(client1Info, audioImageTestClient, audioImageResources);
// Fail to reclaim a video codec resource
std::vector<MediaResourceParcel> reclaimResources;
reclaimResources.push_back(createNonSecureVideoCodecResource());
- CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, reclaimResources, &result));
+ ClientInfoParcel highPriorityClient{.pid = static_cast<int32_t>(kHighPriorityPid),
+ .uid = static_cast<int32_t>(kTestUid2),
+ .id = 0,
+ .name = "none"};
+ CHECK_STATUS_FALSE(mService->reclaimResource(highPriorityClient, reclaimResources, &result));
// Now add a video codec resource
std::vector<MediaResourceParcel> videoResources;
videoResources.push_back(createNonSecureVideoCodecResource());
- mService->addResource(kLowPriorityPid, kTestUid1, getId(videoTestClient), videoTestClient,
- videoResources);
+ ClientInfoParcel client2Info{.pid = static_cast<int32_t>(kLowPriorityPid),
+ .uid = static_cast<int32_t>(kTestUid1),
+ .id = getId(videoTestClient),
+ .name = "none"};
+ mService->addResource(client2Info, videoTestClient, videoResources);
// Verify that the newly-created video codec resource can be reclaimed
- CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, reclaimResources, &result));
+ CHECK_STATUS_TRUE(mService->reclaimResource(highPriorityClient, reclaimResources, &result));
// Verify that the audio and image resources are untouched
EXPECT_FALSE(toTestClient(audioImageTestClient)->checkIfReclaimedAndReset());
@@ -845,22 +947,32 @@
std::vector<MediaResourceParcel> videoImageResources;
videoImageResources.push_back(createNonSecureVideoCodecResource());
videoImageResources.push_back(createNonSecureImageCodecResource());
- mService->addResource(kLowPriorityPid, kTestUid1, getId(videoImageTestClient),
- videoImageTestClient, videoImageResources);
+ ClientInfoParcel client1Info{.pid = static_cast<int32_t>(kLowPriorityPid),
+ .uid = static_cast<int32_t>(kTestUid1),
+ .id = getId(videoImageTestClient),
+ .name = "none"};
+ mService->addResource(client1Info, videoImageTestClient, videoImageResources);
// Fail to reclaim an audio codec resource
std::vector<MediaResourceParcel> reclaimResources;
reclaimResources.push_back(createNonSecureAudioCodecResource());
- CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, reclaimResources, &result));
+ ClientInfoParcel highPriorityClient{.pid = static_cast<int32_t>(kHighPriorityPid),
+ .uid = static_cast<int32_t>(kTestUid2),
+ .id = 0,
+ .name = "none"};
+ CHECK_STATUS_FALSE(mService->reclaimResource(highPriorityClient, reclaimResources, &result));
// Now add an audio codec resource
std::vector<MediaResourceParcel> audioResources;
audioResources.push_back(createNonSecureAudioCodecResource());
- mService->addResource(kLowPriorityPid, kTestUid2, getId(audioTestClient), audioTestClient,
- audioResources);
+ ClientInfoParcel client2Info{.pid = static_cast<int32_t>(kLowPriorityPid),
+ .uid = static_cast<int32_t>(kTestUid2),
+ .id = getId(audioTestClient),
+ .name = "none"};
+ mService->addResource(client2Info, audioTestClient, audioResources);
// Verify that the newly-created audio codec resource can be reclaimed
- CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, reclaimResources, &result));
+ CHECK_STATUS_TRUE(mService->reclaimResource(highPriorityClient, reclaimResources, &result));
// Verify that the video and image resources are untouched
EXPECT_FALSE(toTestClient(videoImageTestClient)->checkIfReclaimedAndReset());
@@ -876,22 +988,32 @@
std::vector<MediaResourceParcel> videoAudioResources;
videoAudioResources.push_back(createNonSecureVideoCodecResource());
videoAudioResources.push_back(createNonSecureAudioCodecResource());
- mService->addResource(kLowPriorityPid, kTestUid1, getId(videoAudioTestClient),
- videoAudioTestClient, videoAudioResources);
+ ClientInfoParcel client1Info{.pid = static_cast<int32_t>(kLowPriorityPid),
+ .uid = static_cast<int32_t>(kTestUid1),
+ .id = getId(videoAudioTestClient),
+ .name = "none"};
+ mService->addResource(client1Info, videoAudioTestClient, videoAudioResources);
// Fail to reclaim an image codec resource
std::vector<MediaResourceParcel> reclaimResources;
reclaimResources.push_back(createNonSecureImageCodecResource());
- CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, reclaimResources, &result));
+ ClientInfoParcel highPriorityClient{.pid = static_cast<int32_t>(kHighPriorityPid),
+ .uid = static_cast<int32_t>(kTestUid2),
+ .id = 0,
+ .name = "none"};
+ CHECK_STATUS_FALSE(mService->reclaimResource(highPriorityClient, reclaimResources, &result));
// Now add an image codec resource
std::vector<MediaResourceParcel> imageResources;
imageResources.push_back(createNonSecureImageCodecResource());
- mService->addResource(kLowPriorityPid, kTestUid2, getId(imageTestClient), imageTestClient,
- imageResources);
+ ClientInfoParcel client2Info{.pid = static_cast<int32_t>(kLowPriorityPid),
+ .uid = static_cast<int32_t>(kTestUid2),
+ .id = getId(imageTestClient),
+ .name = "none"};
+ mService->addResource(client2Info, imageTestClient, imageResources);
// Verify that the newly-created image codec resource can be reclaimed
- CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, reclaimResources, &result));
+ CHECK_STATUS_TRUE(mService->reclaimResource(highPriorityClient, reclaimResources, &result));
// Verify that the video and audio resources are untouched
EXPECT_FALSE(toTestClient(mTestClient1)->checkIfReclaimedAndReset());
@@ -901,20 +1023,27 @@
void testReclaimResources_whenPartialResourceMatch_reclaims() {
const int onlyUid = kTestUid1;
- const auto onlyClient = createTestClient(kLowPriorityPid);
+ const auto onlyClient = createTestClient(kLowPriorityPid, onlyUid);
std::vector<MediaResourceParcel> ownedResources;
ownedResources.push_back(createNonSecureVideoCodecResource());
ownedResources.push_back(createGraphicMemoryResource(100));
- mService->addResource(kLowPriorityPid, onlyUid, getId(onlyClient), onlyClient,
- ownedResources);
+ ClientInfoParcel onlyClientInfo{.pid = static_cast<int32_t>(kLowPriorityPid),
+ .uid = static_cast<int32_t>(onlyUid),
+ .id = getId(onlyClient),
+ .name = "none"};
+ mService->addResource(onlyClientInfo, onlyClient, ownedResources);
// Reclaim an image codec instead of the video codec that is owned, but also reclaim
// graphics memory, which will trigger the reclaim.
std::vector<MediaResourceParcel> reclaimResources;
reclaimResources.push_back(createNonSecureImageCodecResource());
reclaimResources.push_back(createGraphicMemoryResource(100));
- CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, reclaimResources, &result));
+ ClientInfoParcel highPriorityClient{.pid = static_cast<int32_t>(kHighPriorityPid),
+ .uid = static_cast<int32_t>(kTestUid2),
+ .id = 0,
+ .name = "none"};
+ CHECK_STATUS_TRUE(mService->reclaimResource(highPriorityClient, reclaimResources, &result));
// Verify that the video codec resources (including the needed graphic memory) is reclaimed
EXPECT_TRUE(toTestClient(onlyClient)->checkIfReclaimedAndReset());
@@ -926,200 +1055,278 @@
const int onlyUid = kTestUid1;
// secure video codec
- const auto smallSecureVideoMarkedClient = createTestClient(onlyPid);
- const auto largeSecureVideoMarkedClient = createTestClient(onlyPid);
- const auto largestSecureVideoActiveClient = createTestClient(onlyPid);
+ const auto smallSecureVideoMarkedClient = createTestClient(onlyPid, onlyUid);
+ const auto largeSecureVideoMarkedClient = createTestClient(onlyPid, onlyUid);
+ const auto largestSecureVideoActiveClient = createTestClient(onlyPid, onlyUid);
+ ClientInfoParcel clientA{.pid = static_cast<int32_t>(onlyPid),
+ .uid = static_cast<int32_t>(onlyUid),
+ .id = getId(smallSecureVideoMarkedClient),
+ .name = "none"};
+ ClientInfoParcel clientB{.pid = static_cast<int32_t>(onlyPid),
+ .uid = static_cast<int32_t>(onlyUid),
+ .id = getId(largeSecureVideoMarkedClient),
+ .name = "none"};
+ ClientInfoParcel clientC{.pid = static_cast<int32_t>(onlyPid),
+ .uid = static_cast<int32_t>(onlyUid),
+ .id = getId(largestSecureVideoActiveClient),
+ .name = "none"};
{
std::vector<MediaResourceParcel> resources;
resources.push_back(createSecureVideoCodecResource(1));
- mService->addResource(onlyPid, onlyUid, getId(smallSecureVideoMarkedClient),
- smallSecureVideoMarkedClient, resources);
+ mService->addResource(clientA, smallSecureVideoMarkedClient, resources);
resources.clear();
resources.push_back(createSecureVideoCodecResource(2));
- mService->addResource(onlyPid, onlyUid, getId(largeSecureVideoMarkedClient),
- largeSecureVideoMarkedClient, resources);
+ mService->addResource(clientB, largeSecureVideoMarkedClient, resources);
resources.clear();
resources.push_back(createSecureVideoCodecResource(3));
- mService->addResource(onlyPid, onlyUid, getId(largestSecureVideoActiveClient),
- largestSecureVideoActiveClient, resources);
+ mService->addResource(clientC, largestSecureVideoActiveClient, resources);
}
- mService->markClientForPendingRemoval(onlyPid, getId(smallSecureVideoMarkedClient));
- mService->markClientForPendingRemoval(onlyPid, getId(largeSecureVideoMarkedClient));
+ mService->markClientForPendingRemoval(clientA);
+ mService->markClientForPendingRemoval(clientB);
// don't mark the largest client
// non-secure video codec
- const auto smallNonSecureVideoMarkedClient = createTestClient(onlyPid);
- const auto largeNonSecureVideoMarkedClient = createTestClient(onlyPid);
- const auto largestNonSecureVideoActiveClient = createTestClient(onlyPid);
+ const auto smallNonSecureVideoMarkedClient = createTestClient(onlyPid, onlyUid);
+ const auto largeNonSecureVideoMarkedClient = createTestClient(onlyPid, onlyUid);
+ const auto largestNonSecureVideoActiveClient = createTestClient(onlyPid, onlyUid);
+ ClientInfoParcel clientD{.pid = static_cast<int32_t>(onlyPid),
+ .uid = static_cast<int32_t>(onlyUid),
+ .id = getId(smallNonSecureVideoMarkedClient),
+ .name = "none"};
+ ClientInfoParcel clientE{.pid = static_cast<int32_t>(onlyPid),
+ .uid = static_cast<int32_t>(onlyUid),
+ .id = getId(largeNonSecureVideoMarkedClient),
+ .name = "none"};
+ ClientInfoParcel clientF{.pid = static_cast<int32_t>(onlyPid),
+ .uid = static_cast<int32_t>(onlyUid),
+ .id = getId(largestNonSecureVideoActiveClient),
+ .name = "none"};
{
std::vector<MediaResourceParcel> resources;
resources.push_back(createNonSecureVideoCodecResource(1));
- mService->addResource(onlyPid, onlyUid, getId(smallNonSecureVideoMarkedClient),
- smallNonSecureVideoMarkedClient, resources);
+ mService->addResource(clientD, smallNonSecureVideoMarkedClient, resources);
resources.clear();
resources.push_back(createNonSecureVideoCodecResource(2));
- mService->addResource(onlyPid, onlyUid, getId(largeNonSecureVideoMarkedClient),
- largeNonSecureVideoMarkedClient, resources);
+ mService->addResource(clientE, largeNonSecureVideoMarkedClient, resources);
resources.clear();
resources.push_back(createNonSecureVideoCodecResource(3));
- mService->addResource(onlyPid, onlyUid, getId(largestNonSecureVideoActiveClient),
- largestNonSecureVideoActiveClient, resources);
+ mService->addResource(clientF, largestNonSecureVideoActiveClient, resources);
}
- mService->markClientForPendingRemoval(onlyPid, getId(smallNonSecureVideoMarkedClient));
- mService->markClientForPendingRemoval(onlyPid, getId(largeNonSecureVideoMarkedClient));
+ mService->markClientForPendingRemoval(clientD);
+ mService->markClientForPendingRemoval(clientE);
// don't mark the largest client
// secure audio codec
- const auto smallSecureAudioMarkedClient = createTestClient(onlyPid);
- const auto largeSecureAudioMarkedClient = createTestClient(onlyPid);
- const auto largestSecureAudioActiveClient = createTestClient(onlyPid);
+ const auto smallSecureAudioMarkedClient = createTestClient(onlyPid, onlyUid);
+ const auto largeSecureAudioMarkedClient = createTestClient(onlyPid, onlyUid);
+ const auto largestSecureAudioActiveClient = createTestClient(onlyPid, onlyUid);
+ ClientInfoParcel clientG{.pid = static_cast<int32_t>(onlyPid),
+ .uid = static_cast<int32_t>(onlyUid),
+ .id = getId(smallSecureAudioMarkedClient),
+ .name = "none"};
+ ClientInfoParcel clientH{.pid = static_cast<int32_t>(onlyPid),
+ .uid = static_cast<int32_t>(onlyUid),
+ .id = getId(largeSecureAudioMarkedClient),
+ .name = "none"};
+ ClientInfoParcel clientI{.pid = static_cast<int32_t>(onlyPid),
+ .uid = static_cast<int32_t>(onlyUid),
+ .id = getId(largestSecureVideoActiveClient),
+ .name = "none"};
{
std::vector<MediaResourceParcel> resources;
resources.push_back(createSecureAudioCodecResource(1));
- mService->addResource(onlyPid, onlyUid, getId(smallSecureAudioMarkedClient),
- smallSecureAudioMarkedClient, resources);
+ mService->addResource(clientG, smallSecureAudioMarkedClient, resources);
resources.clear();
resources.push_back(createSecureAudioCodecResource(2));
- mService->addResource(onlyPid, onlyUid, getId(largeSecureAudioMarkedClient),
- largeSecureAudioMarkedClient, resources);
+ mService->addResource(clientH, largeSecureAudioMarkedClient, resources);
resources.clear();
resources.push_back(createSecureAudioCodecResource(3));
- mService->addResource(onlyPid, onlyUid, getId(largestSecureVideoActiveClient),
- largestSecureVideoActiveClient, resources);
+ mService->addResource(clientI, largestSecureVideoActiveClient, resources);
}
- mService->markClientForPendingRemoval(onlyPid, getId(smallSecureAudioMarkedClient));
- mService->markClientForPendingRemoval(onlyPid, getId(largeSecureAudioMarkedClient));
+ mService->markClientForPendingRemoval(clientG);
+ mService->markClientForPendingRemoval(clientH);
// don't mark the largest client
// non-secure audio codec
- const auto smallNonSecureAudioMarkedClient = createTestClient(onlyPid);
- const auto largeNonSecureAudioMarkedClient = createTestClient(onlyPid);
- const auto largestNonSecureAudioActiveClient = createTestClient(onlyPid);
+ const auto smallNonSecureAudioMarkedClient = createTestClient(onlyPid, onlyUid);
+ const auto largeNonSecureAudioMarkedClient = createTestClient(onlyPid, onlyUid);
+ const auto largestNonSecureAudioActiveClient = createTestClient(onlyPid, onlyUid);
+ ClientInfoParcel clientJ{.pid = static_cast<int32_t>(onlyPid),
+ .uid = static_cast<int32_t>(onlyUid),
+ .id = getId(smallNonSecureAudioMarkedClient),
+ .name = "none"};
+ ClientInfoParcel clientK{.pid = static_cast<int32_t>(onlyPid),
+ .uid = static_cast<int32_t>(onlyUid),
+ .id = getId(largeNonSecureAudioMarkedClient),
+ .name = "none"};
+ ClientInfoParcel clientL{.pid = static_cast<int32_t>(onlyPid),
+ .uid = static_cast<int32_t>(onlyUid),
+ .id = getId(largestNonSecureAudioActiveClient),
+ .name = "none"};
{
std::vector<MediaResourceParcel> resources;
resources.push_back(createNonSecureAudioCodecResource(1));
- mService->addResource(onlyPid, onlyUid, getId(smallNonSecureAudioMarkedClient),
- smallNonSecureAudioMarkedClient, resources);
+ mService->addResource(clientJ, smallNonSecureAudioMarkedClient, resources);
resources.clear();
resources.push_back(createNonSecureAudioCodecResource(2));
- mService->addResource(onlyPid, onlyUid, getId(largeNonSecureAudioMarkedClient),
- largeNonSecureAudioMarkedClient, resources);
+ mService->addResource(clientK, largeNonSecureAudioMarkedClient, resources);
resources.clear();
resources.push_back(createNonSecureAudioCodecResource(3));
- mService->addResource(onlyPid, onlyUid, getId(largestNonSecureAudioActiveClient),
- largestNonSecureAudioActiveClient, resources);
+ mService->addResource(clientL, largestNonSecureAudioActiveClient, resources);
}
- mService->markClientForPendingRemoval(onlyPid, getId(smallNonSecureAudioMarkedClient));
- mService->markClientForPendingRemoval(onlyPid, getId(largeNonSecureAudioMarkedClient));
+ mService->markClientForPendingRemoval(clientJ);
+ mService->markClientForPendingRemoval(clientK);
// don't mark the largest client
// secure image codec
- const auto smallSecureImageMarkedClient = createTestClient(onlyPid);
- const auto largeSecureImageMarkedClient = createTestClient(onlyPid);
- const auto largestSecureImageActiveClient = createTestClient(onlyPid);
+ const auto smallSecureImageMarkedClient = createTestClient(onlyPid, onlyUid);
+ const auto largeSecureImageMarkedClient = createTestClient(onlyPid, onlyUid);
+ const auto largestSecureImageActiveClient = createTestClient(onlyPid, onlyUid);
+ ClientInfoParcel clientM{.pid = static_cast<int32_t>(onlyPid),
+ .uid = static_cast<int32_t>(onlyUid),
+ .id = getId(smallSecureImageMarkedClient),
+ .name = "none"};
+ ClientInfoParcel clientN{.pid = static_cast<int32_t>(onlyPid),
+ .uid = static_cast<int32_t>(onlyUid),
+ .id = getId(largeSecureImageMarkedClient),
+ .name = "none"};
+ ClientInfoParcel clientO{.pid = static_cast<int32_t>(onlyPid),
+ .uid = static_cast<int32_t>(onlyUid),
+ .id = getId(largestSecureImageActiveClient),
+ .name = "none"};
{
std::vector<MediaResourceParcel> resources;
resources.push_back(createSecureImageCodecResource(1));
- mService->addResource(onlyPid, onlyUid, getId(smallSecureImageMarkedClient),
- smallSecureImageMarkedClient, resources);
+ mService->addResource(clientM, smallSecureImageMarkedClient, resources);
resources.clear();
resources.push_back(createSecureImageCodecResource(2));
- mService->addResource(onlyPid, onlyUid, getId(largeSecureImageMarkedClient),
- largeSecureImageMarkedClient, resources);
+ mService->addResource(clientN, largeSecureImageMarkedClient, resources);
resources.clear();
resources.push_back(createSecureImageCodecResource(3));
- mService->addResource(onlyPid, onlyUid, getId(largestSecureImageActiveClient),
- largestSecureImageActiveClient, resources);
+ mService->addResource(clientO, largestSecureImageActiveClient, resources);
}
- mService->markClientForPendingRemoval(onlyPid, getId(smallSecureImageMarkedClient));
- mService->markClientForPendingRemoval(onlyPid, getId(largeSecureImageMarkedClient));
+ mService->markClientForPendingRemoval(clientM);
+ mService->markClientForPendingRemoval(clientN);
// don't mark the largest client
// non-secure image codec
- const auto smallNonSecureImageMarkedClient = createTestClient(onlyPid);
- const auto largeNonSecureImageMarkedClient = createTestClient(onlyPid);
- const auto largestNonSecureImageActiveClient = createTestClient(onlyPid);
+ const auto smallNonSecureImageMarkedClient = createTestClient(onlyPid, onlyUid);
+ const auto largeNonSecureImageMarkedClient = createTestClient(onlyPid, onlyUid);
+ const auto largestNonSecureImageActiveClient = createTestClient(onlyPid, onlyUid);
+ ClientInfoParcel clientP{.pid = static_cast<int32_t>(onlyPid),
+ .uid = static_cast<int32_t>(onlyUid),
+ .id = getId(smallNonSecureImageMarkedClient),
+ .name = "none"};
+ ClientInfoParcel clientQ{.pid = static_cast<int32_t>(onlyPid),
+ .uid = static_cast<int32_t>(onlyUid),
+ .id = getId(largeNonSecureImageMarkedClient),
+ .name = "none"};
+ ClientInfoParcel clientR{.pid = static_cast<int32_t>(onlyPid),
+ .uid = static_cast<int32_t>(onlyUid),
+ .id = getId(largestNonSecureImageActiveClient),
+ .name = "none"};
{
std::vector<MediaResourceParcel> resources;
resources.push_back(createNonSecureImageCodecResource(1));
- mService->addResource(onlyPid, onlyUid, getId(smallNonSecureImageMarkedClient),
- smallNonSecureImageMarkedClient, resources);
+ mService->addResource(clientP, smallNonSecureImageMarkedClient, resources);
resources.clear();
resources.push_back(createNonSecureImageCodecResource(2));
- mService->addResource(onlyPid, onlyUid, getId(largeNonSecureImageMarkedClient),
- largeNonSecureImageMarkedClient, resources);
+ mService->addResource(clientQ, largeNonSecureImageMarkedClient, resources);
resources.clear();
resources.push_back(createNonSecureImageCodecResource(3));
- mService->addResource(onlyPid, onlyUid, getId(largestNonSecureImageActiveClient),
- largestNonSecureImageActiveClient, resources);
+ mService->addResource(clientR, largestNonSecureImageActiveClient, resources);
}
- mService->markClientForPendingRemoval(onlyPid, getId(smallNonSecureImageMarkedClient));
- mService->markClientForPendingRemoval(onlyPid, getId(largeNonSecureImageMarkedClient));
+ mService->markClientForPendingRemoval(clientP);
+ mService->markClientForPendingRemoval(clientQ);
// don't mark the largest client
// graphic memory
- const auto smallGraphicMemoryMarkedClient = createTestClient(onlyPid);
- const auto largeGraphicMemoryMarkedClient = createTestClient(onlyPid);
- const auto largestGraphicMemoryActiveClient = createTestClient(onlyPid);
+ const auto smallGraphicMemoryMarkedClient = createTestClient(onlyPid, onlyUid);
+ const auto largeGraphicMemoryMarkedClient = createTestClient(onlyPid, onlyUid);
+ const auto largestGraphicMemoryActiveClient = createTestClient(onlyPid, onlyUid);
+ ClientInfoParcel clientS{.pid = static_cast<int32_t>(onlyPid),
+ .uid = static_cast<int32_t>(onlyUid),
+ .id = getId(smallGraphicMemoryMarkedClient),
+ .name = "none"};
+ ClientInfoParcel clientT{.pid = static_cast<int32_t>(onlyPid),
+ .uid = static_cast<int32_t>(onlyUid),
+ .id = getId(largeGraphicMemoryMarkedClient),
+ .name = "none"};
+ ClientInfoParcel clientU{.pid = static_cast<int32_t>(onlyPid),
+ .uid = static_cast<int32_t>(onlyUid),
+ .id = getId(largestGraphicMemoryActiveClient),
+ .name = "none"};
{
std::vector<MediaResourceParcel> resources;
resources.push_back(createGraphicMemoryResource(100));
- mService->addResource(onlyPid, onlyUid, getId(smallGraphicMemoryMarkedClient),
- smallGraphicMemoryMarkedClient, resources);
+ mService->addResource(clientS, smallGraphicMemoryMarkedClient, resources);
resources.clear();
resources.push_back(createGraphicMemoryResource(200));
- mService->addResource(onlyPid, onlyUid, getId(largeGraphicMemoryMarkedClient),
- largeGraphicMemoryMarkedClient, resources);
+ mService->addResource(clientT, largeGraphicMemoryMarkedClient, resources);
resources.clear();
resources.push_back(createGraphicMemoryResource(300));
- mService->addResource(onlyPid, onlyUid, getId(largestGraphicMemoryActiveClient),
- largestGraphicMemoryActiveClient, resources);
+ mService->addResource(clientU, largestGraphicMemoryActiveClient, resources);
}
- mService->markClientForPendingRemoval(onlyPid, getId(smallGraphicMemoryMarkedClient));
- mService->markClientForPendingRemoval(onlyPid, getId(largeGraphicMemoryMarkedClient));
+ mService->markClientForPendingRemoval(clientS);
+ mService->markClientForPendingRemoval(clientT);
// don't mark the largest client
// DRM session
- const auto smallDrmSessionMarkedClient = createTestClient(onlyPid);
- const auto largeDrmSessionMarkedClient = createTestClient(onlyPid);
- const auto largestDrmSessionActiveClient = createTestClient(onlyPid);
+ const auto smallDrmSessionMarkedClient = createTestClient(onlyPid, onlyUid);
+ const auto largeDrmSessionMarkedClient = createTestClient(onlyPid, onlyUid);
+ const auto largestDrmSessionActiveClient = createTestClient(onlyPid, onlyUid);
+ ClientInfoParcel clientV{.pid = static_cast<int32_t>(onlyPid),
+ .uid = static_cast<int32_t>(onlyUid),
+ .id = getId(smallDrmSessionMarkedClient),
+ .name = "none"};
+ ClientInfoParcel clientW{.pid = static_cast<int32_t>(onlyPid),
+ .uid = static_cast<int32_t>(onlyUid),
+ .id = getId(largeDrmSessionMarkedClient),
+ .name = "none"};
+ ClientInfoParcel clientX{.pid = static_cast<int32_t>(onlyPid),
+ .uid = static_cast<int32_t>(onlyUid),
+ .id = getId(largestDrmSessionActiveClient),
+ .name = "none"};
{
std::vector<MediaResourceParcel> resources;
resources.push_back(createDrmSessionResource(1));
- mService->addResource(onlyPid, onlyUid, getId(smallDrmSessionMarkedClient),
- smallDrmSessionMarkedClient, resources);
+ mService->addResource(clientV, smallDrmSessionMarkedClient, resources);
resources.clear();
resources.push_back(createDrmSessionResource(2));
- mService->addResource(onlyPid, onlyUid, getId(largeDrmSessionMarkedClient),
- largeDrmSessionMarkedClient, resources);
+ mService->addResource(clientW, largeDrmSessionMarkedClient, resources);
resources.clear();
resources.push_back(createDrmSessionResource(3));
- mService->addResource(onlyPid, onlyUid, getId(largestDrmSessionActiveClient),
- largestDrmSessionActiveClient, resources);
+ mService->addResource(clientX, largestDrmSessionActiveClient, resources);
}
- mService->markClientForPendingRemoval(onlyPid, getId(smallDrmSessionMarkedClient));
- mService->markClientForPendingRemoval(onlyPid, getId(largeDrmSessionMarkedClient));
+ mService->markClientForPendingRemoval(clientV);
+ mService->markClientForPendingRemoval(clientW);
// don't mark the largest client
// battery
- const auto batteryMarkedClient = createTestClient(onlyPid);
+ const auto batteryMarkedClient = createTestClient(onlyPid, onlyUid);
+ ClientInfoParcel clientY{.pid = static_cast<int32_t>(onlyPid),
+ .uid = static_cast<int32_t>(onlyUid),
+ .id = getId(batteryMarkedClient),
+ .name = "none"};
{
std::vector<MediaResourceParcel> resources;
resources.push_back(createBatteryResource());
- mService->addResource(onlyPid, onlyUid, getId(batteryMarkedClient),
- batteryMarkedClient, resources);
+ mService->addResource(clientY, batteryMarkedClient, resources);
}
- mService->markClientForPendingRemoval(onlyPid, getId(batteryMarkedClient));
+ mService->markClientForPendingRemoval(clientY);
// CPU boost
- const auto cpuBoostMarkedClient = createTestClient(onlyPid);
+ const auto cpuBoostMarkedClient = createTestClient(onlyPid, onlyUid);
+ ClientInfoParcel clientZ{.pid = static_cast<int32_t>(onlyPid),
+ .uid = static_cast<int32_t>(onlyUid),
+ .id = getId(cpuBoostMarkedClient),
+ .name = "none"};
{
std::vector<MediaResourceParcel> resources;
resources.push_back(createCpuBoostResource());
- mService->addResource(onlyPid, onlyUid, getId(cpuBoostMarkedClient),
- cpuBoostMarkedClient, resources);
+ mService->addResource(clientZ, cpuBoostMarkedClient, resources);
}
- mService->markClientForPendingRemoval(onlyPid, getId(cpuBoostMarkedClient));
+ mService->markClientForPendingRemoval(clientZ);
// now we expect that we only reclaim resources from the biggest marked client
EXPECT_TRUE(mService->reclaimResourcesFromClientsPendingRemoval(onlyPid).isOk());
diff --git a/services/mediaresourcemanager/test/ResourceObserverService_test.cpp b/services/mediaresourcemanager/test/ResourceObserverService_test.cpp
index 003569d..a0d728c 100644
--- a/services/mediaresourcemanager/test/ResourceObserverService_test.cpp
+++ b/services/mediaresourcemanager/test/ResourceObserverService_test.cpp
@@ -251,17 +251,31 @@
observables3 = {{MediaObservableType::kVideoSecureCodec, 1},
{MediaObservableType::kVideoNonSecureCodec, 1}};
+ ClientInfoParcel client1Info{.pid = static_cast<int32_t>(kTestPid1),
+ .uid = static_cast<int32_t>(kTestUid1),
+ .id = getId(mTestClient1),
+ .name = "none"};
+
+ ClientInfoParcel client2Info{.pid = static_cast<int32_t>(kTestPid2),
+ .uid = static_cast<int32_t>(kTestUid2),
+ .id = getId(mTestClient2),
+ .name = "none"};
+
+ ClientInfoParcel client3Info{.pid = static_cast<int32_t>(kTestPid2),
+ .uid = static_cast<int32_t>(kTestUid2),
+ .id = getId(mTestClient3),
+ .name = "none"};
std::vector<MediaResourceParcel> resources;
// Add secure video codec.
resources = {createSecureVideoCodecResource()};
- mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources);
+ mService->addResource(client1Info, mTestClient1, resources);
EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid1, kTestPid1, observables1));
EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid1, kTestPid1, observables1));
// Add non-secure video codec.
resources = {createNonSecureVideoCodecResource()};
- mService->addResource(kTestPid2, kTestUid2, getId(mTestClient2), mTestClient2, resources);
+ mService->addResource(client2Info, mTestClient2, resources);
EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
EXPECT_EQ(mTestObserver2->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
@@ -269,7 +283,7 @@
// Add secure & non-secure video codecs.
resources = {createSecureVideoCodecResource(),
createNonSecureVideoCodecResource()};
- mService->addResource(kTestPid2, kTestUid2, getId(mTestClient3), mTestClient3, resources);
+ mService->addResource(client3Info, mTestClient3, resources);
EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables1));
EXPECT_EQ(mTestObserver2->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables3));
@@ -277,7 +291,7 @@
// Add additional audio codecs, should be ignored.
resources.push_back(createSecureAudioCodecResource());
resources.push_back(createNonSecureAudioCodecResource());
- mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources);
+ mService->addResource(client1Info, mTestClient1, resources);
EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid1, kTestPid1, observables1));
EXPECT_EQ(mTestObserver2->pop(), EventTracker::Busy(kTestUid1, kTestPid1, observables2));
EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid1, kTestPid1, observables3));
@@ -303,7 +317,11 @@
observables2 = {{MediaObservableType::kVideoNonSecureCodec, 3}};
observables3 = {{MediaObservableType::kVideoSecureCodec, 2},
{MediaObservableType::kVideoNonSecureCodec, 3}};
- mService->addResource(kTestPid2, kTestUid2, getId(mTestClient3), mTestClient3, resources);
+ ClientInfoParcel client3Info{.pid = static_cast<int32_t>(kTestPid2),
+ .uid = static_cast<int32_t>(kTestUid2),
+ .id = getId(mTestClient3),
+ .name = "none"};
+ mService->addResource(client3Info, mTestClient3, resources);
EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables1));
EXPECT_EQ(mTestObserver2->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables3));
@@ -318,47 +336,61 @@
observables3 = {{MediaObservableType::kVideoSecureCodec, 1},
{MediaObservableType::kVideoNonSecureCodec, 1}};
+ ClientInfoParcel client1Info{.pid = static_cast<int32_t>(kTestPid1),
+ .uid = static_cast<int32_t>(kTestUid1),
+ .id = getId(mTestClient1),
+ .name = "none"};
+
+ ClientInfoParcel client2Info{.pid = static_cast<int32_t>(kTestPid2),
+ .uid = static_cast<int32_t>(kTestUid2),
+ .id = getId(mTestClient2),
+ .name = "none"};
+
+ ClientInfoParcel client3Info{.pid = static_cast<int32_t>(kTestPid2),
+ .uid = static_cast<int32_t>(kTestUid2),
+ .id = getId(mTestClient3),
+ .name = "none"};
std::vector<MediaResourceParcel> resources;
// Add secure video codec to client1.
resources = {createSecureVideoCodecResource()};
- mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources);
+ mService->addResource(client1Info, mTestClient1, resources);
EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid1, kTestPid1, observables1));
EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid1, kTestPid1, observables1));
// Remove secure video codec. observer 1&3 should receive updates.
- mService->removeResource(kTestPid1, getId(mTestClient1), resources);
+ mService->removeResource(client1Info, resources);
EXPECT_EQ(mTestObserver1->pop(), EventTracker::Idle(kTestUid1, kTestPid1, observables1));
EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
EXPECT_EQ(mTestObserver3->pop(), EventTracker::Idle(kTestUid1, kTestPid1, observables1));
// Remove secure video codec again, should have no event.
- mService->removeResource(kTestPid1, getId(mTestClient1), resources);
+ mService->removeResource(client1Info, resources);
EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
EXPECT_EQ(mTestObserver3->pop(), EventTracker::NoEvent);
// Remove client1, should have no event.
- mService->removeClient(kTestPid1, getId(mTestClient1));
+ mService->removeClient(client1Info);
EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
EXPECT_EQ(mTestObserver3->pop(), EventTracker::NoEvent);
// Add non-secure video codec to client2.
resources = {createNonSecureVideoCodecResource()};
- mService->addResource(kTestPid2, kTestUid2, getId(mTestClient2), mTestClient2, resources);
+ mService->addResource(client2Info, mTestClient2, resources);
EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
EXPECT_EQ(mTestObserver2->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
// Remove client2, observer 2&3 should receive updates.
- mService->removeClient(kTestPid2, getId(mTestClient2));
+ mService->removeClient(client2Info);
EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
EXPECT_EQ(mTestObserver2->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables2));
EXPECT_EQ(mTestObserver3->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables2));
// Remove non-secure codec after client2 removed, should have no event.
- mService->removeResource(kTestPid2, getId(mTestClient2), resources);
+ mService->removeResource(client2Info, resources);
EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
EXPECT_EQ(mTestObserver3->pop(), EventTracker::NoEvent);
// Remove client2 again, should have no event.
- mService->removeClient(kTestPid2, getId(mTestClient2));
+ mService->removeClient(client2Info);
EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
EXPECT_EQ(mTestObserver3->pop(), EventTracker::NoEvent);
@@ -368,13 +400,13 @@
createNonSecureVideoCodecResource(),
createSecureAudioCodecResource(),
createNonSecureAudioCodecResource()};
- mService->addResource(kTestPid2, kTestUid2, getId(mTestClient3), mTestClient3, resources);
+ mService->addResource(client3Info, mTestClient3, resources);
EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables1));
EXPECT_EQ(mTestObserver2->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables3));
// Remove one audio codec, should have no event.
resources = {createSecureAudioCodecResource()};
- mService->removeResource(kTestPid2, getId(mTestClient3), resources);
+ mService->removeResource(client3Info, resources);
EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
EXPECT_EQ(mTestObserver3->pop(), EventTracker::NoEvent);
@@ -382,12 +414,12 @@
// removal should be reported.
resources = {createNonSecureAudioCodecResource(),
createSecureVideoCodecResource()};
- mService->removeResource(kTestPid2, getId(mTestClient3), resources);
+ mService->removeResource(client3Info, resources);
EXPECT_EQ(mTestObserver1->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables1));
EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
EXPECT_EQ(mTestObserver3->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables1));
// Remove client3 entirely. Non-secure video codec removal should be reported.
- mService->removeClient(kTestPid2, getId(mTestClient3));
+ mService->removeClient(client3Info);
EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
EXPECT_EQ(mTestObserver2->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables2));
EXPECT_EQ(mTestObserver3->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables2));
@@ -410,7 +442,12 @@
createNonSecureVideoCodecResource(4),
createSecureAudioCodecResource(),
createNonSecureAudioCodecResource()};
- mService->addResource(kTestPid2, kTestUid2, getId(mTestClient3), mTestClient3, resources);
+
+ ClientInfoParcel client3Info{.pid = static_cast<int32_t>(kTestPid2),
+ .uid = static_cast<int32_t>(kTestUid2),
+ .id = getId(mTestClient3),
+ .name = "none"};
+ mService->addResource(client3Info, mTestClient3, resources);
observables1 = {{MediaObservableType::kVideoSecureCodec, 1}};
observables2 = {{MediaObservableType::kVideoNonSecureCodec, 4}};
observables3 = {{MediaObservableType::kVideoSecureCodec, 1},
@@ -424,7 +461,7 @@
createSecureVideoCodecResource(),
createSecureVideoCodecResource(),
createNonSecureVideoCodecResource(2)};
- mService->removeResource(kTestPid2, getId(mTestClient3), resources);
+ mService->removeResource(client3Info, resources);
observables1 = {{MediaObservableType::kVideoSecureCodec, 1}};
observables2 = {{MediaObservableType::kVideoNonSecureCodec, 2}};
observables3 = {{MediaObservableType::kVideoSecureCodec, 1},
@@ -433,7 +470,7 @@
EXPECT_EQ(mTestObserver2->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables2));
EXPECT_EQ(mTestObserver3->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables3));
// Remove client3 entirely. 2 non-secure video codecs removal should be reported.
- mService->removeClient(kTestPid2, getId(mTestClient3));
+ mService->removeClient(client3Info);
EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
EXPECT_EQ(mTestObserver2->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables2));
EXPECT_EQ(mTestObserver3->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables2));
@@ -465,13 +502,27 @@
// Add secure & non-secure video codecs.
resources = {createSecureVideoCodecResource(),
createNonSecureVideoCodecResource()};
- mService->addResource(kTestPid2, kTestUid2, getId(mTestClient3), mTestClient3, resources);
+ ClientInfoParcel client1Info{.pid = static_cast<int32_t>(kTestPid1),
+ .uid = static_cast<int32_t>(kTestUid1),
+ .id = getId(mTestClient1),
+ .name = "none"};
+
+ ClientInfoParcel client2Info{.pid = static_cast<int32_t>(kTestPid2),
+ .uid = static_cast<int32_t>(kTestUid2),
+ .id = getId(mTestClient2),
+ .name = "none"};
+
+ ClientInfoParcel client3Info{.pid = static_cast<int32_t>(kTestPid2),
+ .uid = static_cast<int32_t>(kTestUid2),
+ .id = getId(mTestClient3),
+ .name = "none"};
+ mService->addResource(client3Info, mTestClient3, resources);
EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables1));
EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
// Remove secure & non-secure video codecs.
- mService->removeResource(kTestPid2, getId(mTestClient3), resources);
+ mService->removeResource(client3Info, resources);
EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
EXPECT_EQ(mTestObserver2->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables2));
EXPECT_EQ(mTestObserver3->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables1));
diff --git a/services/tuner/hidl/TunerHidlDvr.cpp b/services/tuner/hidl/TunerHidlDvr.cpp
index 1a619d5..3ea1eb1 100644
--- a/services/tuner/hidl/TunerHidlDvr.cpp
+++ b/services/tuner/hidl/TunerHidlDvr.cpp
@@ -72,7 +72,7 @@
AidlMQDesc aidlMQDesc;
unsafeHidlToAidlMQDescriptor<uint8_t, int8_t, SynchronizedReadWrite>(dvrMQDesc, &aidlMQDesc);
- *_aidl_return = move(aidlMQDesc);
+ *_aidl_return = std::move(aidlMQDesc);
return ::ndk::ScopedAStatus::ok();
}
diff --git a/services/tuner/hidl/TunerHidlFilter.cpp b/services/tuner/hidl/TunerHidlFilter.cpp
index fe74a5c..c82732b 100644
--- a/services/tuner/hidl/TunerHidlFilter.cpp
+++ b/services/tuner/hidl/TunerHidlFilter.cpp
@@ -139,7 +139,7 @@
AidlMQDesc aidlMQDesc;
unsafeHidlToAidlMQDescriptor<uint8_t, int8_t, SynchronizedReadWrite>(filterMQDesc, &aidlMQDesc);
- *_aidl_return = move(aidlMQDesc);
+ *_aidl_return = std::move(aidlMQDesc);
return ::ndk::ScopedAStatus::ok();
}
@@ -1084,8 +1084,8 @@
}
DemuxFilterEvent filterEvent;
- filterEvent.set<DemuxFilterEvent::media>(move(media));
- res.push_back(move(filterEvent));
+ filterEvent.set<DemuxFilterEvent::media>(std::move(media));
+ res.push_back(std::move(filterEvent));
}
}
@@ -1101,8 +1101,8 @@
section.dataLength = static_cast<int64_t>(sectionEvent.dataLength);
DemuxFilterEvent filterEvent;
- filterEvent.set<DemuxFilterEvent::section>(move(section));
- res.push_back(move(filterEvent));
+ filterEvent.set<DemuxFilterEvent::section>(std::move(section));
+ res.push_back(std::move(filterEvent));
}
}
@@ -1117,8 +1117,8 @@
pes.mpuSequenceNumber = static_cast<int32_t>(pesEvent.mpuSequenceNumber);
DemuxFilterEvent filterEvent;
- filterEvent.set<DemuxFilterEvent::pes>(move(pes));
- res.push_back(move(filterEvent));
+ filterEvent.set<DemuxFilterEvent::pes>(std::move(pes));
+ res.push_back(std::move(filterEvent));
}
}
@@ -1167,8 +1167,8 @@
}
DemuxFilterEvent filterEvent;
- filterEvent.set<DemuxFilterEvent::tsRecord>(move(tsRecord));
- res.push_back(move(filterEvent));
+ filterEvent.set<DemuxFilterEvent::tsRecord>(std::move(tsRecord));
+ res.push_back(std::move(filterEvent));
}
}
@@ -1194,8 +1194,8 @@
}
DemuxFilterEvent filterEvent;
- filterEvent.set<DemuxFilterEvent::mmtpRecord>(move(mmtpRecord));
- res.push_back(move(filterEvent));
+ filterEvent.set<DemuxFilterEvent::mmtpRecord>(std::move(mmtpRecord));
+ res.push_back(std::move(filterEvent));
}
}
@@ -1213,8 +1213,8 @@
download.dataLength = static_cast<int32_t>(downloadEvent.dataLength);
DemuxFilterEvent filterEvent;
- filterEvent.set<DemuxFilterEvent::download>(move(download));
- res.push_back(move(filterEvent));
+ filterEvent.set<DemuxFilterEvent::download>(std::move(download));
+ res.push_back(std::move(filterEvent));
}
}
@@ -1227,8 +1227,8 @@
ipPayload.dataLength = static_cast<int32_t>(ipPayloadEvent.dataLength);
DemuxFilterEvent filterEvent;
- filterEvent.set<DemuxFilterEvent::ipPayload>(move(ipPayload));
- res.push_back(move(filterEvent));
+ filterEvent.set<DemuxFilterEvent::ipPayload>(std::move(ipPayload));
+ res.push_back(std::move(filterEvent));
}
}
@@ -1245,8 +1245,8 @@
copy(descrData.begin(), descrData.end(), temi.descrData.begin());
DemuxFilterEvent filterEvent;
- filterEvent.set<DemuxFilterEvent::temi>(move(temi));
- res.push_back(move(filterEvent));
+ filterEvent.set<DemuxFilterEvent::temi>(std::move(temi));
+ res.push_back(std::move(filterEvent));
}
}
@@ -1268,15 +1268,15 @@
}
DemuxFilterEvent filterEvent;
- filterEvent.set<DemuxFilterEvent::monitorEvent>(move(monitor));
- res.push_back(move(filterEvent));
+ filterEvent.set<DemuxFilterEvent::monitorEvent>(std::move(monitor));
+ res.push_back(std::move(filterEvent));
}
void TunerHidlFilter::FilterCallback::getRestartEvent(
const vector<HidlDemuxFilterEventExt::Event>& eventsExt, vector<DemuxFilterEvent>& res) {
DemuxFilterEvent filterEvent;
filterEvent.set<DemuxFilterEvent::startId>(static_cast<int32_t>(eventsExt[0].startId()));
- res.push_back(move(filterEvent));
+ res.push_back(std::move(filterEvent));
}
} // namespace tuner