Merge "Enable isolated_like app to request camera service binder"
diff --git a/apex/ld.config.txt b/apex/ld.config.txt
index 713f0b7..4dc5fb1 100644
--- a/apex/ld.config.txt
+++ b/apex/ld.config.txt
@@ -33,7 +33,7 @@
# TODO: replace the following when apex has a way to auto-generate this list
# namespace.default.link.platform.shared_libs = %LLNDK_LIBRARIES%
# namespace.default.link.platform.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
-namespace.default.link.platform.shared_libs = libEGL.so:libGLESv1_CM.so:libGLESv2.so:libGLESv3.so:libRS.so:libandroid_net.so:libc.so:libcgrouprc.so:libclang_rt.asan-aarch64-android.so:libclang_rt.asan-arm-android.so:libclang_rt.hwasan-aarch64-android.so:libclang_rt.asan-i686-android.so:libclang_rt.asan-x86_64-android.so:libdl.so:libft2.so:liblog.so:libm.so:libmediandk.so:libnativewindow.so:libneuralnetworks.so:libsync.so:libvndksupport.so:libdl_android.so:libvulkan.so:libbinder_ndk.so
+namespace.default.link.platform.shared_libs = libEGL.so:libGLESv1_CM.so:libGLESv2.so:libGLESv3.so:libandroid_net.so:libc.so:libcgrouprc.so:libclang_rt.asan-aarch64-android.so:libclang_rt.asan-arm-android.so:libclang_rt.hwasan-aarch64-android.so:libclang_rt.asan-i686-android.so:libclang_rt.asan-x86_64-android.so:libdl.so:libft2.so:liblog.so:libm.so:libmediandk.so:libnativewindow.so:libneuralnetworks.so:libsync.so:libvndksupport.so:libdl_android.so:libvulkan.so:libbinder_ndk.so
###############################################################################
# "platform" namespace
@@ -138,7 +138,7 @@
# TODO: replace the following when apex has a way to auto-generate this list
# namespace.sphal.link.platform.shared_libs = %LLNDK_LIBRARIES%
# namespace.sphal.link.platform.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
-namespace.sphal.link.platform.shared_libs = libEGL.so:libGLESv1_CM.so:libGLESv2.so:libGLESv3.so:libRS.so:libandroid_net.so:libc.so:libcgrouprc.so:libclang_rt.asan-aarch64-android.so:libclang_rt.asan-arm-android.so:libclang_rt.hwasan-aarch64-android.so:libclang_rt.asan-i686-android.so:libclang_rt.asan-x86_64-android.so:libdl.so:libft2.so:liblog.so:libm.so:libmediandk.so:libnativewindow.so:libneuralnetworks.so:libsync.so:libvndksupport.so:libvulkan.so:libbinder_ndk.so
+namespace.sphal.link.platform.shared_libs = libEGL.so:libGLESv1_CM.so:libGLESv2.so:libGLESv3.so:libandroid_net.so:libc.so:libcgrouprc.so:libclang_rt.asan-aarch64-android.so:libclang_rt.asan-arm-android.so:libclang_rt.hwasan-aarch64-android.so:libclang_rt.asan-i686-android.so:libclang_rt.asan-x86_64-android.so:libdl.so:libft2.so:liblog.so:libm.so:libmediandk.so:libnativewindow.so:libneuralnetworks.so:libsync.so:libvndksupport.so:libvulkan.so:libbinder_ndk.so
# Add a link for libz.so which is llndk on devices where VNDK is not enforced.
namespace.sphal.link.platform.shared_libs += libz.so
diff --git a/drm/libmediadrm/DrmHalHidl.cpp b/drm/libmediadrm/DrmHalHidl.cpp
index 2e0bfee..56d63c5 100644
--- a/drm/libmediadrm/DrmHalHidl.cpp
+++ b/drm/libmediadrm/DrmHalHidl.cpp
@@ -514,10 +514,14 @@
if (mimeType == "") {
// isCryptoSchemeSupported(uuid)
*isSupported = true;
- } else {
- // isCryptoSchemeSupported(uuid, mimeType)
- *isSupported = factory->isContentTypeSupported(mimeType.string());
+ return DrmStatus(OK);
}
+ // isCryptoSchemeSupported(uuid, mimeType)
+ auto hResult = factory->isContentTypeSupported(mimeType.string());
+ if (!hResult.isOk()) {
+ return DrmStatus(DEAD_OBJECT);
+ }
+ *isSupported = hResult;
return DrmStatus(OK);
} else if (mimeType == "") {
return DrmStatus(BAD_VALUE);
@@ -527,8 +531,12 @@
if (factoryV1_2 == NULL) {
return DrmStatus(ERROR_UNSUPPORTED);
} else {
- *isSupported = factoryV1_2->isCryptoSchemeSupported_1_2(uuid, mimeType.string(),
+ auto hResult = factoryV1_2->isCryptoSchemeSupported_1_2(uuid, mimeType.string(),
toHidlSecurityLevel(level));
+ if (!hResult.isOk()) {
+ return DrmStatus(DEAD_OBJECT);
+ }
+ *isSupported = hResult;
return DrmStatus(OK);
}
}
@@ -538,7 +546,8 @@
Mutex::Autolock autoLock(mLock);
*isSupported = false;
for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
- if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
+ auto hResult = mFactories[i]->isCryptoSchemeSupported(uuid);
+ if (hResult.isOk() && hResult) {
return matchMimeTypeAndSecurityLevel(mFactories[i], uuid, mimeType, level, isSupported);
}
}
diff --git a/drm/mediadrm/plugins/clearkey/aidl/Android.bp b/drm/mediadrm/plugins/clearkey/aidl/Android.bp
index 2732aa7..eaf5051 100644
--- a/drm/mediadrm/plugins/clearkey/aidl/Android.bp
+++ b/drm/mediadrm/plugins/clearkey/aidl/Android.bp
@@ -37,6 +37,7 @@
static_libs: [
"android.hardware.common-V2-ndk",
"libclearkeybase",
+ "libjsoncpp",
],
local_include_dirs: ["include"],
@@ -99,6 +100,7 @@
static_libs: [
"android.hardware.common-V2-ndk",
"libclearkeybase_fuzz",
+ "libjsoncpp",
],
local_include_dirs: ["include"],
@@ -114,13 +116,10 @@
"fuzz_aidl_clearkey_service_defaults",
"service_fuzzer_defaults",
],
- static_libs: [
- "liblog",
- ],
srcs: ["fuzzer.cpp"],
fuzz_config: {
cc: [
"hamzeh@google.com",
],
},
-}
\ No newline at end of file
+}
diff --git a/drm/mediadrm/plugins/clearkey/aidl/DrmPlugin.cpp b/drm/mediadrm/plugins/clearkey/aidl/DrmPlugin.cpp
index 054eabd..31cb7c0 100644
--- a/drm/mediadrm/plugins/clearkey/aidl/DrmPlugin.cpp
+++ b/drm/mediadrm/plugins/clearkey/aidl/DrmPlugin.cpp
@@ -16,6 +16,7 @@
#define LOG_TAG "clearkey-DrmPlugin"
#include <aidl/android/hardware/drm/DrmMetric.h>
+#include <android-base/parseint.h>
#include <utils/Log.h>
#include <inttypes.h>
@@ -83,12 +84,14 @@
void DrmPlugin::initProperties() {
mStringProperties.clear();
mStringProperties[kVendorKey] = kAidlVendorValue;
- mStringProperties[kVersionKey] = kAidlVersionValue;
+ mStringProperties[kVersionKey] = kVersionValue;
mStringProperties[kPluginDescriptionKey] = kAidlPluginDescriptionValue;
mStringProperties[kAlgorithmsKey] = kAidlAlgorithmsValue;
mStringProperties[kListenerTestSupportKey] = kAidlListenerTestSupportValue;
mStringProperties[kDrmErrorTestKey] = kAidlDrmErrorTestValue;
mStringProperties[kAidlVersionKey] = kAidlVersionValue;
+ mStringProperties[kOemErrorKey] = "0";
+ mStringProperties[kErrorContextKey] = "0";
std::vector<uint8_t> valueVector;
valueVector.clear();
@@ -102,6 +105,26 @@
mByteArrayProperties[kMetricsKey] = valueVector;
}
+int32_t DrmPlugin::getIntProperty(const std::string& prop, int32_t defaultVal) const {
+ if (!mStringProperties.count(prop)) {
+ return defaultVal;
+ }
+ int32_t out = defaultVal;
+ if (!::android::base::ParseInt(mStringProperties.at(prop), &out)) {
+ return defaultVal;
+ }
+ return out;
+}
+
+int32_t DrmPlugin::getOemError() const {
+ return getIntProperty(kOemErrorKey);
+}
+
+int32_t DrmPlugin::getErrorContext() const {
+ return getIntProperty(kErrorContextKey);
+}
+
+//
// The secure stop in ClearKey implementation is not installed securely.
// This function merely creates a test environment for testing secure stops APIs.
// The content in this secure stop is implementation dependent, the clearkey
@@ -127,7 +150,10 @@
mSessionLibrary->destroySession(session);
if (session->getMockError() != clearkeydrm::OK) {
sendSessionLostState(in_sessionId);
- return toNdkScopedAStatus(Status::ERROR_DRM_INVALID_STATE);
+ return toNdkScopedAStatus(Status::ERROR_DRM_INVALID_STATE,
+ nullptr,
+ getOemError(),
+ getErrorContext());
}
mCloseSessionOkCount++;
return toNdkScopedAStatus(Status::OK);
@@ -198,7 +224,8 @@
if (!session.get()) {
return toNdkScopedAStatus(Status::ERROR_DRM_SESSION_NOT_OPENED);
} else if (session->getMockError() != clearkeydrm::OK) {
- return toNdkScopedAStatus(session->getMockError());
+ auto err = static_cast<Status>(session->getMockError());
+ return toNdkScopedAStatus(err, nullptr, getOemError(), getErrorContext());
}
keyRequestType = KeyRequestType::INITIAL;
}
@@ -381,6 +408,10 @@
value = mStringProperties[kDrmErrorTestKey];
} else if (name == kAidlVersionKey) {
value = mStringProperties[kAidlVersionKey];
+ } else if (name == kOemErrorKey) {
+ value = mStringProperties[kOemErrorKey];
+ } else if (name == kErrorContextKey) {
+ value = mStringProperties[kErrorContextKey];
} else {
ALOGE("App requested unknown string property %s", name.c_str());
status = Status::ERROR_DRM_CANNOT_HANDLE;
@@ -921,6 +952,13 @@
}
}
+ if (in_propertyName == kOemErrorKey || in_propertyName == kErrorContextKey) {
+ int32_t err = 0;
+ if (!::android::base::ParseInt(in_value, &err)) {
+ return toNdkScopedAStatus(Status::BAD_VALUE);
+ }
+ }
+
mStringProperties[key] = std::string(in_value.c_str());
return toNdkScopedAStatus(Status::OK);
}
diff --git a/drm/mediadrm/plugins/clearkey/aidl/include/AidlUtils.h b/drm/mediadrm/plugins/clearkey/aidl/include/AidlUtils.h
index 9257b17..0db3c37 100644
--- a/drm/mediadrm/plugins/clearkey/aidl/include/AidlUtils.h
+++ b/drm/mediadrm/plugins/clearkey/aidl/include/AidlUtils.h
@@ -15,9 +15,12 @@
*/
#pragma once
+#include <cstdint>
#include <string>
#include <vector>
+#include <json/json.h>
+
#include <android/binder_auto_utils.h>
#include "aidl/android/hardware/drm/Status.h"
#include "ClearKeyTypes.h"
@@ -41,17 +44,32 @@
}
inline ::ndk::ScopedAStatus toNdkScopedAStatus(::aidl::android::hardware::drm::Status status,
- const char* msg = nullptr) {
+ const char* msg = nullptr,
+ int32_t oemError = 0,
+ int32_t errorContext = 0) {
+
+
if (Status::OK == status) {
return ::ndk::ScopedAStatus::ok();
- } else {
- auto err = static_cast<int32_t>(status);
- if (msg) {
- return ::ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(err, msg);
- } else {
- return ::ndk::ScopedAStatus::fromServiceSpecificError(err);
- }
}
+
+ Json::Value errObj(Json::objectValue);
+ auto err = static_cast<int32_t>(status);
+ errObj["cdmError"] = err;
+
+ if (oemError) {
+ errObj["oemError"] = oemError;
+ }
+ if (errorContext) {
+ errObj["context"] = errorContext;
+ }
+ if (msg) {
+ errObj["errorMessage"] = msg;
+ }
+
+ Json::FastWriter writer;
+ return ::ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+ err, writer.write(errObj).c_str());
}
inline ::ndk::ScopedAStatus toNdkScopedAStatus(clearkeydrm::CdmResponseType res) {
diff --git a/drm/mediadrm/plugins/clearkey/aidl/include/DrmPlugin.h b/drm/mediadrm/plugins/clearkey/aidl/include/DrmPlugin.h
index 7acc1b6..694013a 100644
--- a/drm/mediadrm/plugins/clearkey/aidl/include/DrmPlugin.h
+++ b/drm/mediadrm/plugins/clearkey/aidl/include/DrmPlugin.h
@@ -148,6 +148,9 @@
private:
void initProperties();
+ int32_t getIntProperty(const std::string& prop, int32_t defaultVal = 0) const;
+ int32_t getOemError() const;
+ int32_t getErrorContext() const;
void installSecureStop(const std::vector<uint8_t>& sessionId);
bool makeKeySetId(std::string* keySetId);
void setPlayPolicy();
diff --git a/drm/mediadrm/plugins/clearkey/common/include/clearkeydrm/ClearKeyDrmProperties.h b/drm/mediadrm/plugins/clearkey/common/include/clearkeydrm/ClearKeyDrmProperties.h
index bfda388..d4e641e 100644
--- a/drm/mediadrm/plugins/clearkey/common/include/clearkeydrm/ClearKeyDrmProperties.h
+++ b/drm/mediadrm/plugins/clearkey/common/include/clearkeydrm/ClearKeyDrmProperties.h
@@ -21,7 +21,7 @@
static const std::string kVendorKey("vendor");
static const std::string kVendorValue("Google");
static const std::string kVersionKey("version");
-static const std::string kVersionValue("1.2");
+static const std::string kVersionValue("14"); // sync with Android OS version
static const std::string kPluginDescriptionKey("description");
static const std::string kPluginDescriptionValue("ClearKey CDM");
static const std::string kAlgorithmsKey("algorithms");
@@ -35,6 +35,8 @@
static const std::string kFrameTooLargeValue("frameTooLarge");
static const std::string kInvalidStateValue("invalidState");
static const std::string kAidlVersionKey("aidlVersion");
+static const std::string kOemErrorKey("oemError");
+static const std::string kErrorContextKey("errorContext");
static const std::string kDeviceIdKey("deviceId");
static const uint8_t kTestDeviceIdData[] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
diff --git a/media/audioaidlconversion/AidlConversionEffect.cpp b/media/audioaidlconversion/AidlConversionEffect.cpp
new file mode 100644
index 0000000..9660072
--- /dev/null
+++ b/media/audioaidlconversion/AidlConversionEffect.cpp
@@ -0,0 +1,352 @@
+/*
+ * 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 <utility>
+
+#define LOG_TAG "AidlConversionEffect"
+//#define LOG_NDEBUG 0
+#include <utils/Log.h>
+
+#include <media/AidlConversionCppNdk.h>
+#include <media/AidlConversionEffect.h>
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// AIDL NDK backend to legacy audio data structure conversion utilities.
+
+namespace aidl {
+namespace android {
+
+using ::aidl::android::hardware::audio::effect::AcousticEchoCanceler;
+using ::aidl::android::hardware::audio::effect::AutomaticGainControl;
+using ::aidl::android::hardware::audio::effect::BassBoost;
+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::media::audio::common::AudioDeviceDescription;
+
+using ::android::BAD_VALUE;
+using ::android::base::unexpected;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Converters
+
+ConversionResult<uint32_t> aidl2legacy_Flags_Type_uint32(Flags::Type type) {
+ switch (type) {
+ case Flags::Type::INSERT:
+ return EFFECT_FLAG_TYPE_INSERT;
+ case Flags::Type::AUXILIARY:
+ return EFFECT_FLAG_TYPE_AUXILIARY;
+ case Flags::Type::REPLACE:
+ return EFFECT_FLAG_TYPE_REPLACE;
+ case Flags::Type::PRE_PROC:
+ return EFFECT_FLAG_TYPE_PRE_PROC;
+ case Flags::Type::POST_PROC:
+ return EFFECT_FLAG_TYPE_POST_PROC;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<Flags::Type> legacy2aidl_uint32_Flags_Type(uint32_t legacy) {
+ switch (legacy & EFFECT_FLAG_TYPE_MASK) {
+ case EFFECT_FLAG_TYPE_INSERT:
+ return Flags::Type::INSERT;
+ case EFFECT_FLAG_TYPE_AUXILIARY:
+ return Flags::Type::AUXILIARY;
+ case EFFECT_FLAG_TYPE_REPLACE:
+ return Flags::Type::REPLACE;
+ case EFFECT_FLAG_TYPE_PRE_PROC:
+ return Flags::Type::PRE_PROC;
+ case EFFECT_FLAG_TYPE_POST_PROC:
+ return Flags::Type::POST_PROC;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<uint32_t> aidl2legacy_Flags_Insert_uint32(Flags::Insert insert) {
+ switch (insert) {
+ case Flags::Insert::ANY:
+ return EFFECT_FLAG_INSERT_ANY;
+ case Flags::Insert::FIRST:
+ return EFFECT_FLAG_INSERT_FIRST;
+ case Flags::Insert::LAST:
+ return EFFECT_FLAG_INSERT_LAST;
+ case Flags::Insert::EXCLUSIVE:
+ return EFFECT_FLAG_INSERT_EXCLUSIVE;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<Flags::Insert> legacy2aidl_uint32_Flags_Insert(uint32_t legacy) {
+ switch (legacy & EFFECT_FLAG_INSERT_MASK) {
+ case EFFECT_FLAG_INSERT_ANY:
+ return Flags::Insert::ANY;
+ case EFFECT_FLAG_INSERT_FIRST:
+ return Flags::Insert::FIRST;
+ case EFFECT_FLAG_INSERT_LAST:
+ return Flags::Insert::LAST;
+ case EFFECT_FLAG_INSERT_EXCLUSIVE:
+ return Flags::Insert::EXCLUSIVE;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<uint32_t> aidl2legacy_Flags_Volume_uint32(Flags::Volume volume) {
+ switch (volume) {
+ case Flags::Volume::NONE:
+ return 0;
+ case Flags::Volume::CTRL:
+ return EFFECT_FLAG_VOLUME_CTRL;
+ case Flags::Volume::IND:
+ return EFFECT_FLAG_VOLUME_IND;
+ case Flags::Volume::MONITOR:
+ return EFFECT_FLAG_VOLUME_MONITOR;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<Flags::Volume> legacy2aidl_uint32_Flags_Volume(uint32_t legacy) {
+ switch (legacy & EFFECT_FLAG_VOLUME_MASK) {
+ case EFFECT_FLAG_VOLUME_CTRL:
+ return Flags::Volume::CTRL;
+ case EFFECT_FLAG_VOLUME_IND:
+ return Flags::Volume::IND;
+ case EFFECT_FLAG_VOLUME_MONITOR:
+ return Flags::Volume::MONITOR;
+ case EFFECT_FLAG_VOLUME_NONE:
+ return Flags::Volume::NONE;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<uint32_t> aidl2legacy_Flags_uint32(Flags aidl) {
+ uint32_t legacy = 0;
+ legacy |= VALUE_OR_RETURN(aidl2legacy_Flags_Type_uint32(aidl.type));
+ legacy |= VALUE_OR_RETURN(aidl2legacy_Flags_Insert_uint32(aidl.insert));
+ legacy |= VALUE_OR_RETURN(aidl2legacy_Flags_Volume_uint32(aidl.volume));
+ legacy |= VALUE_OR_RETURN(aidl2legacy_Flags_HardwareAccelerator_uint32(aidl.hwAcceleratorMode));
+
+ if (aidl.offloadIndication) {
+ legacy |= EFFECT_FLAG_OFFLOAD_SUPPORTED;
+ }
+ if (aidl.deviceIndication) {
+ legacy |= EFFECT_FLAG_DEVICE_IND;
+ }
+ if (aidl.audioModeIndication) {
+ legacy |= EFFECT_FLAG_AUDIO_MODE_IND;
+ }
+ if (aidl.audioSourceIndication) {
+ legacy |= EFFECT_FLAG_AUDIO_SOURCE_IND;
+ }
+ if (aidl.noProcessing) {
+ legacy |= EFFECT_FLAG_NO_PROCESS;
+ }
+ return legacy;
+}
+
+ConversionResult<Flags> legacy2aidl_uint32_Flags(uint32_t legacy) {
+ Flags aidl;
+
+ aidl.type = VALUE_OR_RETURN(legacy2aidl_uint32_Flags_Type(legacy));
+ aidl.insert = VALUE_OR_RETURN(legacy2aidl_uint32_Flags_Insert(legacy));
+ aidl.volume = VALUE_OR_RETURN(legacy2aidl_uint32_Flags_Volume(legacy));
+ aidl.hwAcceleratorMode = VALUE_OR_RETURN(legacy2aidl_uint32_Flags_HardwareAccelerator(legacy));
+ aidl.offloadIndication = (legacy & EFFECT_FLAG_OFFLOAD_SUPPORTED);
+ aidl.deviceIndication = (legacy & EFFECT_FLAG_DEVICE_IND);
+ aidl.audioModeIndication = (legacy & EFFECT_FLAG_AUDIO_MODE_IND);
+ aidl.audioSourceIndication = (legacy & EFFECT_FLAG_AUDIO_SOURCE_IND);
+ aidl.noProcessing = (legacy & EFFECT_FLAG_NO_PROCESS);
+ return aidl;
+}
+
+ConversionResult<uint32_t> aidl2legacy_Flags_HardwareAccelerator_uint32(
+ Flags::HardwareAccelerator hwAcceleratorMode) {
+ switch (hwAcceleratorMode) {
+ case Flags::HardwareAccelerator::NONE:
+ return 0;
+ case Flags::HardwareAccelerator::SIMPLE:
+ return EFFECT_FLAG_HW_ACC_SIMPLE;
+ case Flags::HardwareAccelerator::TUNNEL:
+ return EFFECT_FLAG_HW_ACC_TUNNEL;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<Flags::HardwareAccelerator> legacy2aidl_uint32_Flags_HardwareAccelerator(
+ uint32_t legacy) {
+ switch (legacy & EFFECT_FLAG_HW_ACC_MASK) {
+ case EFFECT_FLAG_HW_ACC_SIMPLE:
+ return Flags::HardwareAccelerator::SIMPLE;
+ case EFFECT_FLAG_HW_ACC_TUNNEL:
+ return Flags::HardwareAccelerator::TUNNEL;
+ case 0:
+ return Flags::HardwareAccelerator::NONE;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<effect_descriptor_t>
+aidl2legacy_Descriptor_effect_descriptor(const Descriptor& aidl) {
+ effect_descriptor_t legacy;
+ legacy.type = VALUE_OR_RETURN(aidl2legacy_AudioUuid_audio_uuid_t(aidl.common.id.type));
+ legacy.uuid = VALUE_OR_RETURN(aidl2legacy_AudioUuid_audio_uuid_t(aidl.common.id.uuid));
+ // legacy descriptor doesn't have proxy information
+ // proxy = VALUE_OR_RETURN(aidl2legacy_AudioUuid_audio_uuid_t(aidl.proxy));
+ legacy.apiVersion = EFFECT_CONTROL_API_VERSION;
+ legacy.flags = VALUE_OR_RETURN(aidl2legacy_Flags_uint32(aidl.common.flags));
+ legacy.cpuLoad = VALUE_OR_RETURN(convertIntegral<uint16_t>(aidl.common.cpuLoad));
+ legacy.memoryUsage = VALUE_OR_RETURN(convertIntegral<uint16_t>(aidl.common.memoryUsage));
+ RETURN_IF_ERROR(aidl2legacy_string(aidl.common.name, legacy.name, sizeof(legacy.name)));
+ RETURN_IF_ERROR(aidl2legacy_string(aidl.common.implementor, legacy.implementor,
+ sizeof(legacy.implementor)));
+ return legacy;
+}
+
+ConversionResult<Descriptor>
+legacy2aidl_effect_descriptor_Descriptor(const effect_descriptor_t& legacy) {
+ Descriptor aidl;
+ aidl.common.id.type = VALUE_OR_RETURN(legacy2aidl_audio_uuid_t_AudioUuid(legacy.type));
+ aidl.common.id.uuid = VALUE_OR_RETURN(legacy2aidl_audio_uuid_t_AudioUuid(legacy.uuid));
+ // legacy descriptor doesn't have proxy information
+ // aidl.common.id.proxy
+ aidl.common.flags = VALUE_OR_RETURN(legacy2aidl_uint32_Flags(legacy.flags));
+ aidl.common.cpuLoad = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.cpuLoad));
+ aidl.common.memoryUsage = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.memoryUsage));
+ aidl.common.name = VALUE_OR_RETURN(legacy2aidl_string(legacy.name, sizeof(legacy.name)));
+ aidl.common.implementor =
+ VALUE_OR_RETURN(legacy2aidl_string(legacy.implementor, sizeof(legacy.implementor)));
+ return aidl;
+}
+
+ConversionResult<uint32_t> aidl2legacy_Parameter_aec_uint32_echoDelay(const Parameter& aidl) {
+ int echoDelay = VALUE_OR_RETURN(
+ GET_PARAMETER_SPECIFIC_FIELD(aidl, AcousticEchoCanceler, acousticEchoCanceler,
+ AcousticEchoCanceler::echoDelayUs, int));
+ return VALUE_OR_RETURN(convertReinterpret<uint32_t>(echoDelay));
+}
+
+ConversionResult<Parameter> legacy2aidl_uint32_echoDelay_Parameter_aec(uint32_t legacy) {
+ int delay = VALUE_OR_RETURN(convertReinterpret<int32_t>(legacy));
+ return MAKE_SPECIFIC_PARAMETER(AcousticEchoCanceler, acousticEchoCanceler, echoDelayUs, delay);
+}
+
+ConversionResult<uint32_t> aidl2legacy_Parameter_aec_uint32_mobileMode(const Parameter& aidl) {
+ bool mobileMode = VALUE_OR_RETURN(
+ GET_PARAMETER_SPECIFIC_FIELD(aidl, AcousticEchoCanceler, acousticEchoCanceler,
+ AcousticEchoCanceler::mobileMode, bool));
+ return VALUE_OR_RETURN(convertIntegral<uint32_t>(mobileMode));
+}
+
+ConversionResult<Parameter> legacy2aidl_uint32_mobileMode_Parameter_aec(uint32_t legacy) {
+ bool mode = VALUE_OR_RETURN(convertIntegral<bool>(legacy));
+ return MAKE_SPECIFIC_PARAMETER(AcousticEchoCanceler, acousticEchoCanceler, mobileMode, mode);
+}
+
+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));
+ 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);
+}
+
+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));
+ return static_cast<uint32_t>(le);
+}
+
+ConversionResult<Parameter> legacy2aidl_uint32_levelEstimator_Parameter_agc(uint32_t legacy) {
+ if (legacy > (uint32_t) AutomaticGainControl::LevelEstimator::PEAK) {
+ return unexpected(BAD_VALUE);
+ }
+ AutomaticGainControl::LevelEstimator le =
+ static_cast<AutomaticGainControl::LevelEstimator>(legacy);
+ return MAKE_SPECIFIC_PARAMETER(AutomaticGainControl, automaticGainControl, 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));
+ 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);
+}
+
+ConversionResult<uint16_t> aidl2legacy_Parameter_BassBoost_uint16_strengthPm(
+ const Parameter& aidl) {
+ int strength = VALUE_OR_RETURN(
+ GET_PARAMETER_SPECIFIC_FIELD(aidl, BassBoost, bassBoost, BassBoost::strengthPm, int));
+ return VALUE_OR_RETURN(convertIntegral<uint16_t>(strength));
+}
+
+ConversionResult<Parameter> legacy2aidl_uint16_strengthPm_Parameter_BassBoost(uint16_t legacy) {
+ int strength = VALUE_OR_RETURN(convertIntegral<int>(legacy));
+ return MAKE_SPECIFIC_PARAMETER(BassBoost, bassBoost, strengthPm, strength);
+}
+
+ConversionResult<int16_t> aidl2legacy_Parameter_Downmix_int16_type(const Parameter& aidl) {
+ Downmix::Type aidlType = VALUE_OR_RETURN(
+ GET_PARAMETER_SPECIFIC_FIELD(aidl, Downmix, downmix, Downmix::type, Downmix::Type));
+ return VALUE_OR_RETURN(convertIntegral<int16_t>(static_cast<uint32_t>(aidlType)));
+}
+
+ConversionResult<Parameter> legacy2aidl_int16_type_Parameter_Downmix(int16_t legacy) {
+ if (legacy > (uint32_t) Downmix::Type::FOLD) {
+ return unexpected(BAD_VALUE);
+ }
+ Downmix::Type aidlType = static_cast<Downmix::Type>(legacy);
+ return MAKE_SPECIFIC_PARAMETER(Downmix, downmix, type, aidlType);
+}
+
+ConversionResult<int16_t> aidl2legacy_DynamicsProcessing_ResolutionPreference_uint32_(
+ const Parameter& aidl) {
+ Downmix::Type aidlType = VALUE_OR_RETURN(
+ GET_PARAMETER_SPECIFIC_FIELD(aidl, Downmix, downmix, Downmix::type, Downmix::Type));
+ return VALUE_OR_RETURN(convertIntegral<int16_t>(static_cast<uint32_t>(aidlType)));
+}
+
+ConversionResult<DynamicsProcessing::ResolutionPreference>
+legacy2aidl_int32_DynamicsProcessing_ResolutionPreference(int32_t legacy) {
+ if (legacy > (int32_t)DynamicsProcessing::ResolutionPreference::FAVOR_TIME_RESOLUTION) {
+ return unexpected(BAD_VALUE);
+ }
+ return static_cast<DynamicsProcessing::ResolutionPreference>(legacy);
+}
+
+ConversionResult<int32_t> aidl2legacy_DynamicsProcessing_ResolutionPreference_int32(
+ DynamicsProcessing::ResolutionPreference aidl) {
+ return static_cast<int32_t>(aidl);
+}
+
+
+} // namespace android
+} // aidl
diff --git a/media/audioaidlconversion/AidlConversionNdk.cpp b/media/audioaidlconversion/AidlConversionNdk.cpp
index 8fec660..7c63339 100644
--- a/media/audioaidlconversion/AidlConversionNdk.cpp
+++ b/media/audioaidlconversion/AidlConversionNdk.cpp
@@ -29,208 +29,6 @@
namespace aidl {
namespace android {
-using ::aidl::android::hardware::audio::effect::AcousticEchoCanceler;
-using ::aidl::android::hardware::audio::effect::AutomaticGainControl;
-using ::aidl::android::hardware::audio::effect::BassBoost;
-using ::aidl::android::hardware::audio::effect::Descriptor;
-using ::aidl::android::hardware::audio::effect::Downmix;
-using ::aidl::android::hardware::audio::effect::Flags;
-using ::aidl::android::hardware::audio::effect::Parameter;
-using ::aidl::android::media::audio::common::AudioDeviceDescription;
-
-using ::android::BAD_VALUE;
-using ::android::base::unexpected;
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-// Converters
-
-ConversionResult<uint32_t> aidl2legacy_Flags_Type_uint32(Flags::Type type) {
- switch (type) {
- case Flags::Type::INSERT:
- return EFFECT_FLAG_TYPE_INSERT;
- case Flags::Type::AUXILIARY:
- return EFFECT_FLAG_TYPE_AUXILIARY;
- case Flags::Type::REPLACE:
- return EFFECT_FLAG_TYPE_REPLACE;
- case Flags::Type::PRE_PROC:
- return EFFECT_FLAG_TYPE_PRE_PROC;
- case Flags::Type::POST_PROC:
- return EFFECT_FLAG_TYPE_POST_PROC;
- }
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<Flags::Type> legacy2aidl_uint32_Flags_Type(uint32_t legacy) {
- switch (legacy & EFFECT_FLAG_TYPE_MASK) {
- case EFFECT_FLAG_TYPE_INSERT:
- return Flags::Type::INSERT;
- case EFFECT_FLAG_TYPE_AUXILIARY:
- return Flags::Type::AUXILIARY;
- case EFFECT_FLAG_TYPE_REPLACE:
- return Flags::Type::REPLACE;
- case EFFECT_FLAG_TYPE_PRE_PROC:
- return Flags::Type::PRE_PROC;
- case EFFECT_FLAG_TYPE_POST_PROC:
- return Flags::Type::POST_PROC;
- }
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<uint32_t> aidl2legacy_Flags_Insert_uint32(Flags::Insert insert) {
- switch (insert) {
- case Flags::Insert::ANY:
- return EFFECT_FLAG_INSERT_ANY;
- case Flags::Insert::FIRST:
- return EFFECT_FLAG_INSERT_FIRST;
- case Flags::Insert::LAST:
- return EFFECT_FLAG_INSERT_LAST;
- case Flags::Insert::EXCLUSIVE:
- return EFFECT_FLAG_INSERT_EXCLUSIVE;
- }
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<Flags::Insert> legacy2aidl_uint32_Flags_Insert(uint32_t legacy) {
- switch (legacy & EFFECT_FLAG_INSERT_MASK) {
- case EFFECT_FLAG_INSERT_ANY:
- return Flags::Insert::ANY;
- case EFFECT_FLAG_INSERT_FIRST:
- return Flags::Insert::FIRST;
- case EFFECT_FLAG_INSERT_LAST:
- return Flags::Insert::LAST;
- case EFFECT_FLAG_INSERT_EXCLUSIVE:
- return Flags::Insert::EXCLUSIVE;
- }
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<uint32_t> aidl2legacy_Flags_Volume_uint32(Flags::Volume volume) {
- switch (volume) {
- case Flags::Volume::NONE:
- return 0;
- case Flags::Volume::CTRL:
- return EFFECT_FLAG_VOLUME_CTRL;
- case Flags::Volume::IND:
- return EFFECT_FLAG_VOLUME_IND;
- case Flags::Volume::MONITOR:
- return EFFECT_FLAG_VOLUME_MONITOR;
- }
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<Flags::Volume> legacy2aidl_uint32_Flags_Volume(uint32_t legacy) {
- switch (legacy & EFFECT_FLAG_VOLUME_MASK) {
- case EFFECT_FLAG_VOLUME_CTRL:
- return Flags::Volume::CTRL;
- case EFFECT_FLAG_VOLUME_IND:
- return Flags::Volume::IND;
- case EFFECT_FLAG_VOLUME_MONITOR:
- return Flags::Volume::MONITOR;
- case EFFECT_FLAG_VOLUME_NONE:
- return Flags::Volume::NONE;
- }
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<uint32_t> aidl2legacy_Flags_uint32(Flags aidl) {
- uint32_t legacy = 0;
- legacy |= VALUE_OR_RETURN(aidl2legacy_Flags_Type_uint32(aidl.type));
- legacy |= VALUE_OR_RETURN(aidl2legacy_Flags_Insert_uint32(aidl.insert));
- legacy |= VALUE_OR_RETURN(aidl2legacy_Flags_Volume_uint32(aidl.volume));
- legacy |= VALUE_OR_RETURN(aidl2legacy_Flags_HardwareAccelerator_uint32(aidl.hwAcceleratorMode));
-
- if (aidl.offloadIndication) {
- legacy |= EFFECT_FLAG_OFFLOAD_SUPPORTED;
- }
- if (aidl.deviceIndication) {
- legacy |= EFFECT_FLAG_DEVICE_IND;
- }
- if (aidl.audioModeIndication) {
- legacy |= EFFECT_FLAG_AUDIO_MODE_IND;
- }
- if (aidl.audioSourceIndication) {
- legacy |= EFFECT_FLAG_AUDIO_SOURCE_IND;
- }
- if (aidl.noProcessing) {
- legacy |= EFFECT_FLAG_NO_PROCESS;
- }
- return legacy;
-}
-
-ConversionResult<Flags> legacy2aidl_uint32_Flags(uint32_t legacy) {
- Flags aidl;
-
- aidl.type = VALUE_OR_RETURN(legacy2aidl_uint32_Flags_Type(legacy));
- aidl.insert = VALUE_OR_RETURN(legacy2aidl_uint32_Flags_Insert(legacy));
- aidl.volume = VALUE_OR_RETURN(legacy2aidl_uint32_Flags_Volume(legacy));
- aidl.hwAcceleratorMode = VALUE_OR_RETURN(legacy2aidl_uint32_Flags_HardwareAccelerator(legacy));
- aidl.offloadIndication = (legacy & EFFECT_FLAG_OFFLOAD_SUPPORTED);
- aidl.deviceIndication = (legacy & EFFECT_FLAG_DEVICE_IND);
- aidl.audioModeIndication = (legacy & EFFECT_FLAG_AUDIO_MODE_IND);
- aidl.audioSourceIndication = (legacy & EFFECT_FLAG_AUDIO_SOURCE_IND);
- aidl.noProcessing = (legacy & EFFECT_FLAG_NO_PROCESS);
- return aidl;
-}
-
-ConversionResult<uint32_t> aidl2legacy_Flags_HardwareAccelerator_uint32(
- Flags::HardwareAccelerator hwAcceleratorMode) {
- switch (hwAcceleratorMode) {
- case Flags::HardwareAccelerator::NONE:
- return 0;
- case Flags::HardwareAccelerator::SIMPLE:
- return EFFECT_FLAG_HW_ACC_SIMPLE;
- case Flags::HardwareAccelerator::TUNNEL:
- return EFFECT_FLAG_HW_ACC_TUNNEL;
- }
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<Flags::HardwareAccelerator> legacy2aidl_uint32_Flags_HardwareAccelerator(
- uint32_t legacy) {
- switch (legacy & EFFECT_FLAG_HW_ACC_MASK) {
- case EFFECT_FLAG_HW_ACC_SIMPLE:
- return Flags::HardwareAccelerator::SIMPLE;
- case EFFECT_FLAG_HW_ACC_TUNNEL:
- return Flags::HardwareAccelerator::TUNNEL;
- case 0:
- return Flags::HardwareAccelerator::NONE;
- }
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<effect_descriptor_t>
-aidl2legacy_Descriptor_effect_descriptor(const Descriptor& aidl) {
- effect_descriptor_t legacy;
- legacy.type = VALUE_OR_RETURN(aidl2legacy_AudioUuid_audio_uuid_t(aidl.common.id.type));
- legacy.uuid = VALUE_OR_RETURN(aidl2legacy_AudioUuid_audio_uuid_t(aidl.common.id.uuid));
- // legacy descriptor doesn't have proxy information
- // proxy = VALUE_OR_RETURN(aidl2legacy_AudioUuid_audio_uuid_t(aidl.proxy));
- legacy.apiVersion = EFFECT_CONTROL_API_VERSION;
- legacy.flags = VALUE_OR_RETURN(aidl2legacy_Flags_uint32(aidl.common.flags));
- legacy.cpuLoad = VALUE_OR_RETURN(convertIntegral<uint16_t>(aidl.common.cpuLoad));
- legacy.memoryUsage = VALUE_OR_RETURN(convertIntegral<uint16_t>(aidl.common.memoryUsage));
- RETURN_IF_ERROR(aidl2legacy_string(aidl.common.name, legacy.name, sizeof(legacy.name)));
- RETURN_IF_ERROR(aidl2legacy_string(aidl.common.implementor, legacy.implementor,
- sizeof(legacy.implementor)));
- return legacy;
-}
-
-ConversionResult<Descriptor>
-legacy2aidl_effect_descriptor_Descriptor(const effect_descriptor_t& legacy) {
- Descriptor aidl;
- aidl.common.id.type = VALUE_OR_RETURN(legacy2aidl_audio_uuid_t_AudioUuid(legacy.type));
- aidl.common.id.uuid = VALUE_OR_RETURN(legacy2aidl_audio_uuid_t_AudioUuid(legacy.uuid));
- // legacy descriptor doesn't have proxy information
- // aidl.common.id.proxy
- aidl.common.flags = VALUE_OR_RETURN(legacy2aidl_uint32_Flags(legacy.flags));
- aidl.common.cpuLoad = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.cpuLoad));
- aidl.common.memoryUsage = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.memoryUsage));
- aidl.common.name = VALUE_OR_RETURN(legacy2aidl_string(legacy.name, sizeof(legacy.name)));
- aidl.common.implementor =
- VALUE_OR_RETURN(legacy2aidl_string(legacy.implementor, sizeof(legacy.implementor)));
- return aidl;
-}
-
// buffer_provider_t is not supported thus skipped
ConversionResult<buffer_config_t> aidl2legacy_AudioConfigBase_buffer_config_t(
const media::audio::common::AudioConfigBase& aidl, bool isInput) {
@@ -270,96 +68,5 @@
return aidl;
}
-ConversionResult<uint32_t> aidl2legacy_Parameter_aec_uint32_echoDelay(const Parameter& aidl) {
- int echoDelay = VALUE_OR_RETURN(GET_PARAMETER_SPECIFIC_FIELD(
- aidl, AcousticEchoCanceler, acousticEchoCanceler, echoDelayUs, int));
- return VALUE_OR_RETURN(convertReinterpret<uint32_t>(echoDelay));
-}
-
-ConversionResult<Parameter> legacy2aidl_uint32_echoDelay_Parameter_aec(uint32_t legacy) {
- int delay = VALUE_OR_RETURN(convertReinterpret<int32_t>(legacy));
- return MAKE_SPECIFIC_PARAMETER(AcousticEchoCanceler, acousticEchoCanceler, echoDelayUs, delay);
-}
-
-ConversionResult<uint32_t> aidl2legacy_Parameter_aec_uint32_mobileMode(const Parameter& aidl) {
- bool mobileMode = VALUE_OR_RETURN(GET_PARAMETER_SPECIFIC_FIELD(
- aidl, AcousticEchoCanceler, acousticEchoCanceler, mobileMode, bool));
- return VALUE_OR_RETURN(convertIntegral<uint32_t>(mobileMode));
-}
-
-ConversionResult<Parameter> legacy2aidl_uint32_mobileMode_Parameter_aec(uint32_t legacy) {
- bool mode = VALUE_OR_RETURN(convertIntegral<bool>(legacy));
- return MAKE_SPECIFIC_PARAMETER(AcousticEchoCanceler, acousticEchoCanceler, mobileMode, mode);
-}
-
-ConversionResult<uint32_t> aidl2legacy_Parameter_agc_uint32_fixedDigitalGain(
- const Parameter& aidl) {
- int gain = VALUE_OR_RETURN(GET_PARAMETER_SPECIFIC_FIELD(
- aidl, AutomaticGainControl, automaticGainControl, 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);
-}
-
-ConversionResult<uint32_t> aidl2legacy_Parameter_agc_uint32_levelEstimator(
- const Parameter& aidl) {
- const auto& le = VALUE_OR_RETURN(
- GET_PARAMETER_SPECIFIC_FIELD(aidl, AutomaticGainControl, automaticGainControl,
- levelEstimator, AutomaticGainControl::LevelEstimator));
- return static_cast<uint32_t>(le);
-}
-
-ConversionResult<Parameter> legacy2aidl_uint32_levelEstimator_Parameter_agc(uint32_t legacy) {
- if (legacy > (uint32_t) AutomaticGainControl::LevelEstimator::PEAK) {
- return unexpected(BAD_VALUE);
- }
- AutomaticGainControl::LevelEstimator le =
- static_cast<AutomaticGainControl::LevelEstimator>(legacy);
- return MAKE_SPECIFIC_PARAMETER(AutomaticGainControl, automaticGainControl, 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, 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);
-}
-
-ConversionResult<uint16_t> aidl2legacy_Parameter_BassBoost_uint16_strengthPm(
- const Parameter& aidl) {
- int strength = VALUE_OR_RETURN(
- GET_PARAMETER_SPECIFIC_FIELD(aidl, BassBoost, bassBoost, strengthPm, int));
- return VALUE_OR_RETURN(convertIntegral<uint16_t>(strength));
-}
-
-ConversionResult<Parameter> legacy2aidl_uint16_strengthPm_Parameter_BassBoost(uint16_t legacy) {
- int strength = VALUE_OR_RETURN(convertIntegral<int>(legacy));
- return MAKE_SPECIFIC_PARAMETER(BassBoost, bassBoost, strengthPm, strength);
-}
-
-ConversionResult<int16_t> aidl2legacy_Parameter_Downmix_int16_type(const Parameter& aidl) {
- Downmix::Type aidlType = VALUE_OR_RETURN(
- GET_PARAMETER_SPECIFIC_FIELD(aidl, Downmix, downmix, type, Downmix::Type));
- return VALUE_OR_RETURN(convertIntegral<int16_t>(static_cast<uint32_t>(aidlType)));
-}
-
-ConversionResult<Parameter> legacy2aidl_int16_type_Parameter_Downmix(int16_t legacy) {
- if (legacy > (uint32_t) Downmix::Type::FOLD) {
- return unexpected(BAD_VALUE);
- }
- Downmix::Type aidlType = static_cast<Downmix::Type>(legacy);
- return MAKE_SPECIFIC_PARAMETER(Downmix, downmix, type, aidlType);
-}
-
} // namespace android
} // aidl
diff --git a/media/audioaidlconversion/Android.bp b/media/audioaidlconversion/Android.bp
index 86f455e..c0024ef 100644
--- a/media/audioaidlconversion/Android.bp
+++ b/media/audioaidlconversion/Android.bp
@@ -135,11 +135,40 @@
],
defaults: [
"audio_aidl_conversion_common_default",
+ "latest_android_media_audio_common_types_ndk_shared",
+ ],
+ shared_libs: [
+ "libbinder_ndk",
+ "libbase",
+ ],
+ cflags: [
+ "-DBACKEND_NDK",
+ ],
+ min_sdk_version: "31", //AParcelableHolder has been introduced in 31
+}
+
+/**
+ * Only including AIDL effect HAL conversion.
+ */
+cc_library {
+ name: "libaudio_aidl_conversion_effect_ndk",
+ srcs: [
+ "AidlConversionEffect.cpp",
+ ],
+ header_libs: [
+ "libaudio_aidl_conversion_common_util_ndk",
+ ],
+ export_header_lib_headers: [
+ "libaudio_aidl_conversion_common_util_ndk",
+ ],
+ defaults: [
+ "audio_aidl_conversion_common_default",
"latest_android_hardware_audio_common_ndk_shared",
"latest_android_hardware_audio_effect_ndk_shared",
"latest_android_media_audio_common_types_ndk_shared",
],
shared_libs: [
+ "libaudio_aidl_conversion_common_ndk",
"libbinder_ndk",
"libbase",
],
diff --git a/media/audioaidlconversion/include/media/AidlConversionEffect.h b/media/audioaidlconversion/include/media/AidlConversionEffect.h
new file mode 100644
index 0000000..83aa614
--- /dev/null
+++ b/media/audioaidlconversion/include/media/AidlConversionEffect.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/binder_auto_utils.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+/**
+ * Can only handle conversion between AIDL (NDK backend) and legacy type.
+ */
+#include <hardware/audio_effect.h>
+#include <media/AidlConversionUtil.h>
+#include <system/audio_effect.h>
+
+#include <aidl/android/hardware/audio/effect/IEffect.h>
+
+namespace aidl {
+namespace android {
+
+template <typename P, typename T, typename P::Specific::Tag tag>
+ConversionResult<T> getParameterSpecific(const P& u) {
+ const auto& spec = VALUE_OR_RETURN(UNION_GET(u, specific));
+ return unionGetField<typename P::Specific, tag>(spec);
+}
+
+template <typename P, typename T, typename P::Specific::Tag tag, typename T::Tag field, typename F>
+ConversionResult<F> getParameterSpecificField(const P& u) {
+ const auto& spec =
+ VALUE_OR_RETURN((getParameterSpecific<std::decay_t<decltype(u)>, T, tag>(u)));
+ 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 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))
+
+ConversionResult<uint32_t> aidl2legacy_Flags_Type_uint32(
+ ::aidl::android::hardware::audio::effect::Flags::Type type);
+ConversionResult<uint32_t> aidl2legacy_Flags_Insert_uint32(
+ ::aidl::android::hardware::audio::effect::Flags::Insert insert);
+ConversionResult<uint32_t> aidl2legacy_Flags_Volume_uint32(
+ ::aidl::android::hardware::audio::effect::Flags::Volume volume);
+ConversionResult<uint32_t> aidl2legacy_Flags_HardwareAccelerator_uint32(
+ ::aidl::android::hardware::audio::effect::Flags::HardwareAccelerator hwAcceleratorMode);
+ConversionResult<uint32_t> aidl2legacy_Flags_uint32(
+ const ::aidl::android::hardware::audio::effect::Flags aidl);
+
+ConversionResult<::aidl::android::hardware::audio::effect::Flags::Type>
+legacy2aidl_uint32_Flags_Type(uint32_t legacy);
+ConversionResult<::aidl::android::hardware::audio::effect::Flags::Insert>
+legacy2aidl_uint32_Flags_Insert(uint32_t legacy);
+ConversionResult<::aidl::android::hardware::audio::effect::Flags::Volume>
+legacy2aidl_uint32_Flags_Volume(uint32_t legacy);
+ConversionResult<::aidl::android::hardware::audio::effect::Flags::HardwareAccelerator>
+legacy2aidl_uint32_Flags_HardwareAccelerator(uint32_t legacy);
+ConversionResult<::aidl::android::hardware::audio::effect::Flags> legacy2aidl_uint32_Flags(
+ uint32_t hal);
+
+ConversionResult<effect_descriptor_t> aidl2legacy_Descriptor_effect_descriptor(
+ const ::aidl::android::hardware::audio::effect::Descriptor& aidl);
+ConversionResult<::aidl::android::hardware::audio::effect::Descriptor>
+legacy2aidl_effect_descriptor_Descriptor(const effect_descriptor_t& hal);
+
+ConversionResult<uint32_t> aidl2legacy_Parameter_aec_uint32_echoDelay(
+ const ::aidl::android::hardware::audio::effect::Parameter& aidl);
+ConversionResult<::aidl::android::hardware::audio::effect::Parameter>
+legacy2aidl_uint32_echoDelay_Parameter_aec(uint32_t legacy);
+
+ConversionResult<uint32_t> aidl2legacy_Parameter_aec_uint32_mobileMode(
+ const ::aidl::android::hardware::audio::effect::Parameter& aidl);
+ConversionResult<::aidl::android::hardware::audio::effect::Parameter>
+legacy2aidl_uint32_mobileMode_Parameter_aec(uint32_t legacy);
+
+ConversionResult<uint32_t> aidl2legacy_Parameter_agc_uint32_fixedDigitalGain(
+ const ::aidl::android::hardware::audio::effect::Parameter& aidl);
+ConversionResult<::aidl::android::hardware::audio::effect::Parameter>
+legacy2aidl_uint32_fixedDigitalGain_Parameter_agc(uint32_t legacy);
+
+ConversionResult<uint32_t> aidl2legacy_Parameter_agc_uint32_levelEstimator(
+ const ::aidl::android::hardware::audio::effect::Parameter& aidl);
+ConversionResult<::aidl::android::hardware::audio::effect::Parameter>
+legacy2aidl_uint32_levelEstimator_Parameter_agc(uint32_t legacy);
+
+ConversionResult<uint32_t> aidl2legacy_Parameter_agc_uint32_saturationMargin(
+ const ::aidl::android::hardware::audio::effect::Parameter& aidl);
+ConversionResult<::aidl::android::hardware::audio::effect::Parameter>
+legacy2aidl_uint32_saturationMargin_Parameter_agc(uint32_t legacy);
+
+ConversionResult<uint16_t> aidl2legacy_Parameter_BassBoost_uint16_strengthPm(
+ const ::aidl::android::hardware::audio::effect::Parameter& aidl);
+ConversionResult<::aidl::android::hardware::audio::effect::Parameter>
+legacy2aidl_uint16_strengthPm_Parameter_BassBoost(uint16_t legacy);
+
+ConversionResult<int16_t> aidl2legacy_Parameter_Downmix_int16_type(
+ const ::aidl::android::hardware::audio::effect::Parameter& aidl);
+ConversionResult<::aidl::android::hardware::audio::effect::Parameter>
+legacy2aidl_int16_type_Parameter_Downmix(int16_t legacy);
+
+ConversionResult<::aidl::android::hardware::audio::effect::DynamicsProcessing::ResolutionPreference>
+legacy2aidl_int32_DynamicsProcessing_ResolutionPreference(int32_t legacy);
+ConversionResult<int32_t> aidl2legacy_DynamicsProcessing_ResolutionPreference_int32(
+ ::aidl::android::hardware::audio::effect::DynamicsProcessing::ResolutionPreference aidl);
+
+} // namespace android
+} // namespace aidl
diff --git a/media/audioaidlconversion/include/media/AidlConversionNdk.h b/media/audioaidlconversion/include/media/AidlConversionNdk.h
index d094dff..98a7d41 100644
--- a/media/audioaidlconversion/include/media/AidlConversionNdk.h
+++ b/media/audioaidlconversion/include/media/AidlConversionNdk.h
@@ -26,105 +26,15 @@
#include <hardware/audio_effect.h>
#include <media/AidlConversionUtil.h>
#include <system/audio_effect.h>
-
-#include <aidl/android/hardware/audio/effect/IEffect.h>
+#include <aidl/android/media/audio/common/AudioConfig.h>
namespace aidl {
namespace android {
-template <typename P, typename T, typename P::Specific::Tag tag>
-ConversionResult<T> getParameterSpecific(const P& u) {
- const auto& spec = VALUE_OR_RETURN(UNION_GET(u, specific));
- return unionGetField<typename P::Specific, tag>(spec);
-}
-
-template <typename P, typename T, typename P::Specific::Tag tag, typename T::Tag field, typename F>
-ConversionResult<F> getParameterSpecificField(const P& u) {
- const auto& spec =
- VALUE_OR_RETURN((getParameterSpecific<std::decay_t<decltype(u)>, T, tag>(u)));
- 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 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, spec::field))
-
-ConversionResult<uint32_t> aidl2legacy_Flags_Type_uint32(
- ::aidl::android::hardware::audio::effect::Flags::Type type);
-ConversionResult<uint32_t> aidl2legacy_Flags_Insert_uint32(
- ::aidl::android::hardware::audio::effect::Flags::Insert insert);
-ConversionResult<uint32_t> aidl2legacy_Flags_Volume_uint32(
- ::aidl::android::hardware::audio::effect::Flags::Volume volume);
-ConversionResult<uint32_t> aidl2legacy_Flags_HardwareAccelerator_uint32(
- ::aidl::android::hardware::audio::effect::Flags::HardwareAccelerator hwAcceleratorMode);
-ConversionResult<uint32_t> aidl2legacy_Flags_uint32(
- const ::aidl::android::hardware::audio::effect::Flags aidl);
-
-ConversionResult<::aidl::android::hardware::audio::effect::Flags::Type>
-legacy2aidl_uint32_Flags_Type(uint32_t legacy);
-ConversionResult<::aidl::android::hardware::audio::effect::Flags::Insert>
-legacy2aidl_uint32_Flags_Insert(uint32_t legacy);
-ConversionResult<::aidl::android::hardware::audio::effect::Flags::Volume>
-legacy2aidl_uint32_Flags_Volume(uint32_t legacy);
-ConversionResult<::aidl::android::hardware::audio::effect::Flags::HardwareAccelerator>
-legacy2aidl_uint32_Flags_HardwareAccelerator(uint32_t legacy);
-ConversionResult<::aidl::android::hardware::audio::effect::Flags> legacy2aidl_uint32_Flags(
- uint32_t hal);
-
-ConversionResult<effect_descriptor_t> aidl2legacy_Descriptor_effect_descriptor(
- const ::aidl::android::hardware::audio::effect::Descriptor& aidl);
-ConversionResult<::aidl::android::hardware::audio::effect::Descriptor>
-legacy2aidl_effect_descriptor_Descriptor(const effect_descriptor_t& hal);
-
ConversionResult<buffer_config_t> aidl2legacy_AudioConfigBase_buffer_config_t(
const media::audio::common::AudioConfigBase& aidl, bool isInput);
ConversionResult<media::audio::common::AudioConfigBase> legacy2aidl_buffer_config_t_AudioConfigBase(
const buffer_config_t& legacy, bool isInput);
-ConversionResult<uint32_t> aidl2legacy_Parameter_aec_uint32_echoDelay(
- const ::aidl::android::hardware::audio::effect::Parameter& aidl);
-ConversionResult<::aidl::android::hardware::audio::effect::Parameter>
-legacy2aidl_uint32_echoDelay_Parameter_aec(uint32_t legacy);
-
-ConversionResult<uint32_t> aidl2legacy_Parameter_aec_uint32_mobileMode(
- const ::aidl::android::hardware::audio::effect::Parameter& aidl);
-ConversionResult<::aidl::android::hardware::audio::effect::Parameter>
-legacy2aidl_uint32_mobileMode_Parameter_aec(uint32_t legacy);
-
-ConversionResult<uint32_t> aidl2legacy_Parameter_agc_uint32_fixedDigitalGain(
- const ::aidl::android::hardware::audio::effect::Parameter& aidl);
-ConversionResult<::aidl::android::hardware::audio::effect::Parameter>
-legacy2aidl_uint32_fixedDigitalGain_Parameter_agc(uint32_t legacy);
-
-ConversionResult<uint32_t> aidl2legacy_Parameter_agc_uint32_levelEstimator(
- const ::aidl::android::hardware::audio::effect::Parameter& aidl);
-ConversionResult<::aidl::android::hardware::audio::effect::Parameter>
-legacy2aidl_uint32_levelEstimator_Parameter_agc(uint32_t legacy);
-
-ConversionResult<uint32_t> aidl2legacy_Parameter_agc_uint32_saturationMargin(
- const ::aidl::android::hardware::audio::effect::Parameter& aidl);
-ConversionResult<::aidl::android::hardware::audio::effect::Parameter>
-legacy2aidl_uint32_saturationMargin_Parameter_agc(uint32_t legacy);
-
-ConversionResult<uint16_t> aidl2legacy_Parameter_BassBoost_uint16_strengthPm(
- const ::aidl::android::hardware::audio::effect::Parameter& aidl);
-ConversionResult<::aidl::android::hardware::audio::effect::Parameter>
-legacy2aidl_uint16_strengthPm_Parameter_BassBoost(uint16_t legacy);
-
-ConversionResult<int16_t> aidl2legacy_Parameter_Downmix_int16_type(
- const ::aidl::android::hardware::audio::effect::Parameter& aidl);
-ConversionResult<::aidl::android::hardware::audio::effect::Parameter>
-legacy2aidl_int16_type_Parameter_Downmix(int16_t legacy);
-
} // namespace android
} // namespace aidl
diff --git a/media/codec2/components/aom/C2SoftAomEnc.cpp b/media/codec2/components/aom/C2SoftAomEnc.cpp
index f5620a4..8b852a2 100644
--- a/media/codec2/components/aom/C2SoftAomEnc.cpp
+++ b/media/codec2/components/aom/C2SoftAomEnc.cpp
@@ -22,6 +22,7 @@
#include <media/stagefright/foundation/MediaDefs.h>
#include <C2Debug.h>
+#include <Codec2Mapper.h>
#include <C2PlatformSupport.h>
#include <SimpleC2Interface.h>
@@ -390,6 +391,36 @@
codec_return = aom_codec_control(mCodecContext, AV1E_SET_MAX_REFERENCE_FRAMES, 3);
if (codec_return != AOM_CODEC_OK) goto BailOut;
+ ColorAspects sfAspects;
+ if (!C2Mapper::map(mColorAspects->primaries, &sfAspects.mPrimaries)) {
+ sfAspects.mPrimaries = android::ColorAspects::PrimariesUnspecified;
+ }
+ if (!C2Mapper::map(mColorAspects->range, &sfAspects.mRange)) {
+ sfAspects.mRange = android::ColorAspects::RangeUnspecified;
+ }
+ if (!C2Mapper::map(mColorAspects->matrix, &sfAspects.mMatrixCoeffs)) {
+ sfAspects.mMatrixCoeffs = android::ColorAspects::MatrixUnspecified;
+ }
+ if (!C2Mapper::map(mColorAspects->transfer, &sfAspects.mTransfer)) {
+ sfAspects.mTransfer = android::ColorAspects::TransferUnspecified;
+ }
+ int32_t primaries, transfer, matrixCoeffs;
+ bool range;
+ ColorUtils::convertCodecColorAspectsToIsoAspects(sfAspects,
+ &primaries,
+ &transfer,
+ &matrixCoeffs,
+ &range);
+
+ codec_return = aom_codec_control(mCodecContext, AV1E_SET_COLOR_RANGE, range);
+ if (codec_return != AOM_CODEC_OK) goto BailOut;
+ codec_return = aom_codec_control(mCodecContext, AV1E_SET_COLOR_PRIMARIES, primaries);
+ if (codec_return != AOM_CODEC_OK) goto BailOut;
+ codec_return = aom_codec_control(mCodecContext, AV1E_SET_TRANSFER_CHARACTERISTICS, transfer);
+ if (codec_return != AOM_CODEC_OK) goto BailOut;
+ codec_return = aom_codec_control(mCodecContext, AV1E_SET_MATRIX_COEFFICIENTS, matrixCoeffs);
+ if (codec_return != AOM_CODEC_OK) goto BailOut;
+
BailOut:
return codec_return;
}
@@ -406,6 +437,7 @@
mFrameRate = mIntf->getFrameRate_l();
mIntraRefresh = mIntf->getIntraRefresh_l();
mRequestSync = mIntf->getRequestSync_l();
+ mColorAspects = mIntf->getCodedColorAspects_l();
}
diff --git a/media/codec2/components/aom/C2SoftAomEnc.h b/media/codec2/components/aom/C2SoftAomEnc.h
index 2d1bb07..3e42855 100644
--- a/media/codec2/components/aom/C2SoftAomEnc.h
+++ b/media/codec2/components/aom/C2SoftAomEnc.h
@@ -104,6 +104,7 @@
std::shared_ptr<C2StreamBitrateInfo::output> mBitrate;
std::shared_ptr<C2StreamBitrateModeTuning::output> mBitrateMode;
std::shared_ptr<C2StreamRequestSyncFrameTuning::output> mRequestSync;
+ std::shared_ptr<C2StreamColorAspectsInfo::output> mColorAspects;
aom_codec_err_t setupCodecParameters();
};
diff --git a/media/codec2/components/gav1/Android.bp b/media/codec2/components/gav1/Android.bp
index 162339f..9781b6d 100644
--- a/media/codec2/components/gav1/Android.bp
+++ b/media/codec2/components/gav1/Android.bp
@@ -21,7 +21,10 @@
],
srcs: ["C2SoftGav1Dec.cpp"],
- static_libs: ["libgav1"],
+ static_libs: [
+ "libgav1",
+ "libyuv_static",
+ ],
apex_available: [
"//apex_available:platform",
diff --git a/media/codec2/components/gav1/C2SoftGav1Dec.cpp b/media/codec2/components/gav1/C2SoftGav1Dec.cpp
index 9c5ce9f..8aed623 100644
--- a/media/codec2/components/gav1/C2SoftGav1Dec.cpp
+++ b/media/codec2/components/gav1/C2SoftGav1Dec.cpp
@@ -24,6 +24,7 @@
#include <Codec2CommonUtils.h>
#include <Codec2Mapper.h>
#include <SimpleC2Interface.h>
+#include <libyuv.h>
#include <log/log.h>
#include <media/stagefright/foundation/AUtils.h>
#include <media/stagefright/foundation/MediaDefs.h>
@@ -725,6 +726,24 @@
}
}
+void C2SoftGav1Dec::setError(const std::unique_ptr<C2Work> &work, c2_status_t error) {
+ mSignalledError = true;
+ work->result = error;
+ work->workletsProcessed = 1u;
+}
+
+bool C2SoftGav1Dec::allocTmpFrameBuffer(size_t size) {
+ if (size > mTmpFrameBufferSize) {
+ mTmpFrameBuffer = std::make_unique<uint16_t[]>(size);
+ if (mTmpFrameBuffer == nullptr) {
+ mTmpFrameBufferSize = 0;
+ return false;
+ }
+ mTmpFrameBufferSize = size;
+ }
+ return true;
+}
+
bool C2SoftGav1Dec::outputBuffer(const std::shared_ptr<C2BlockPool> &pool,
const std::unique_ptr<C2Work> &work) {
if (!(work && pool)) return false;
@@ -771,14 +790,6 @@
getHDRStaticParams(buffer, work);
getHDR10PlusInfoData(buffer, work);
- if (!(buffer->image_format == libgav1::kImageFormatYuv420 ||
- buffer->image_format == libgav1::kImageFormatMonochrome400)) {
- ALOGE("image_format %d not supported", buffer->image_format);
- mSignalledError = true;
- work->workletsProcessed = 1u;
- work->result = C2_CORRUPTED;
- return false;
- }
const bool isMonochrome =
buffer->image_format == libgav1::kImageFormatMonochrome400;
@@ -851,9 +862,6 @@
uint8_t *dstY = const_cast<uint8_t *>(wView.data()[C2PlanarLayout::PLANE_Y]);
uint8_t *dstU = const_cast<uint8_t *>(wView.data()[C2PlanarLayout::PLANE_U]);
uint8_t *dstV = const_cast<uint8_t *>(wView.data()[C2PlanarLayout::PLANE_V]);
- size_t srcYStride = buffer->stride[0];
- size_t srcUStride = buffer->stride[1];
- size_t srcVStride = buffer->stride[2];
C2PlanarLayout layout = wView.layout();
size_t dstYStride = layout.planes[C2PlanarLayout::PLANE_Y].rowInc;
@@ -864,29 +872,102 @@
const uint16_t *srcY = (const uint16_t *)buffer->plane[0];
const uint16_t *srcU = (const uint16_t *)buffer->plane[1];
const uint16_t *srcV = (const uint16_t *)buffer->plane[2];
+ size_t srcYStride = buffer->stride[0] / 2;
+ size_t srcUStride = buffer->stride[1] / 2;
+ size_t srcVStride = buffer->stride[2] / 2;
if (format == HAL_PIXEL_FORMAT_RGBA_1010102) {
convertYUV420Planar16ToY410OrRGBA1010102(
- (uint32_t *)dstY, srcY, srcU, srcV, srcYStride / 2,
- srcUStride / 2, srcVStride / 2,
+ (uint32_t *)dstY, srcY, srcU, srcV, srcYStride,
+ srcUStride, srcVStride,
dstYStride / sizeof(uint32_t), mWidth, mHeight,
std::static_pointer_cast<const C2ColorAspectsStruct>(codedColorAspects));
} else if (format == HAL_PIXEL_FORMAT_YCBCR_P010) {
- convertYUV420Planar16ToP010((uint16_t *)dstY, (uint16_t *)dstU, srcY, srcU, srcV,
- srcYStride / 2, srcUStride / 2, srcVStride / 2, dstYStride / 2,
- dstUStride / 2, mWidth, mHeight, isMonochrome);
+ dstYStride /= 2;
+ dstUStride /= 2;
+ dstVStride /= 2;
+ if (buffer->image_format == libgav1::kImageFormatYuv444 ||
+ buffer->image_format == libgav1::kImageFormatYuv422) {
+ // TODO(https://crbug.com/libyuv/952): replace this block with libyuv::I410ToP010 and
+ // libyuv::I210ToP010 when they are available.
+ // Note it may be safe to alias dstY in I010ToP010, but the libyuv API doesn't make any
+ // guarantees.
+ const size_t tmpSize = dstYStride * mHeight + dstUStride * align(mHeight, 2);
+ if (!allocTmpFrameBuffer(tmpSize)) {
+ ALOGE("Error allocating temp conversion buffer (%zu bytes)", tmpSize);
+ setError(work, C2_NO_MEMORY);
+ return false;
+ }
+ uint16_t *const tmpY = mTmpFrameBuffer.get();
+ uint16_t *const tmpU = tmpY + dstYStride * mHeight;
+ uint16_t *const tmpV = tmpU + dstUStride * align(mHeight, 2) / 2;
+ if (buffer->image_format == libgav1::kImageFormatYuv444) {
+ libyuv::I410ToI010(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride,
+ tmpY, dstYStride, tmpU, dstUStride, tmpV, dstUStride,
+ mWidth, mHeight);
+ } else {
+ libyuv::I210ToI010(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride,
+ tmpY, dstYStride, tmpU, dstUStride, tmpV, dstUStride,
+ mWidth, mHeight);
+ }
+ libyuv::I010ToP010(tmpY, dstYStride, tmpU, dstUStride, tmpV, dstVStride,
+ (uint16_t*)dstY, dstYStride, (uint16_t*)dstU, dstUStride,
+ mWidth, mHeight);
+ } else {
+ convertYUV420Planar16ToP010((uint16_t *)dstY, (uint16_t *)dstU, srcY, srcU, srcV,
+ srcYStride, srcUStride, srcVStride, dstYStride,
+ dstUStride, mWidth, mHeight, isMonochrome);
+ }
} else {
- convertYUV420Planar16ToYV12(dstY, dstU, dstV, srcY, srcU, srcV, srcYStride / 2,
- srcUStride / 2, srcVStride / 2, dstYStride, dstUStride, mWidth,
- mHeight, isMonochrome);
+ if (buffer->image_format == libgav1::kImageFormatYuv444) {
+ // TODO(https://crbug.com/libyuv/950): replace this block with libyuv::I410ToI420 when
+ // it's available.
+ const size_t tmpSize = dstYStride * mHeight + dstUStride * align(mHeight, 2);
+ if (!allocTmpFrameBuffer(tmpSize)) {
+ ALOGE("Error allocating temp conversion buffer (%zu bytes)", tmpSize);
+ setError(work, C2_NO_MEMORY);
+ return false;
+ }
+ uint16_t *const tmpY = mTmpFrameBuffer.get();
+ uint16_t *const tmpU = tmpY + dstYStride * mHeight;
+ uint16_t *const tmpV = tmpU + dstUStride * align(mHeight, 2) / 2;
+ libyuv::I410ToI010(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride,
+ tmpY, dstYStride, tmpU, dstUStride, tmpV, dstVStride,
+ mWidth, mHeight);
+ libyuv::I010ToI420(tmpY, dstYStride, tmpU, dstUStride, tmpV, dstUStride,
+ dstY, dstYStride, dstU, dstUStride, dstV, dstVStride,
+ mWidth, mHeight);
+ } else if (buffer->image_format == libgav1::kImageFormatYuv422) {
+ libyuv::I210ToI420(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride,
+ dstY, dstYStride, dstU, dstUStride, dstV, dstVStride,
+ mWidth, mHeight);
+ } else {
+ convertYUV420Planar16ToYV12(dstY, dstU, dstV, srcY, srcU, srcV, srcYStride / 2,
+ srcUStride / 2, srcVStride / 2, dstYStride, dstUStride,
+ mWidth, mHeight, isMonochrome);
+ }
}
} else {
const uint8_t *srcY = (const uint8_t *)buffer->plane[0];
const uint8_t *srcU = (const uint8_t *)buffer->plane[1];
const uint8_t *srcV = (const uint8_t *)buffer->plane[2];
- convertYUV420Planar8ToYV12(dstY, dstU, dstV, srcY, srcU, srcV, srcYStride, srcUStride,
- srcVStride, dstYStride, dstUStride, dstVStride, mWidth, mHeight,
- isMonochrome);
+ size_t srcYStride = buffer->stride[0];
+ size_t srcUStride = buffer->stride[1];
+ size_t srcVStride = buffer->stride[2];
+
+ if (buffer->image_format == libgav1::kImageFormatYuv444) {
+ libyuv::I444ToI420(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride,
+ dstY, dstYStride, dstU, dstUStride, dstV, dstVStride,
+ mWidth, mHeight);
+ } else if (buffer->image_format == libgav1::kImageFormatYuv422) {
+ libyuv::I422ToI420(srcY, srcYStride, srcU, srcUStride, srcV, srcVStride,
+ dstY, dstYStride, dstU, dstUStride, dstV, dstVStride,
+ mWidth, mHeight);
+ } else {
+ convertYUV420Planar8ToYV12(dstY, dstU, dstV, srcY, srcU, srcV, srcYStride, srcUStride,
+ srcVStride, dstYStride, dstUStride, dstVStride, mWidth, mHeight,
+ isMonochrome);
+ }
}
finishWork(buffer->user_private_data, work, std::move(block));
block = nullptr;
diff --git a/media/codec2/components/gav1/C2SoftGav1Dec.h b/media/codec2/components/gav1/C2SoftGav1Dec.h
index f0e14d7..c3b27ea 100644
--- a/media/codec2/components/gav1/C2SoftGav1Dec.h
+++ b/media/codec2/components/gav1/C2SoftGav1Dec.h
@@ -19,6 +19,8 @@
#include <inttypes.h>
+#include <memory>
+
#include <media/stagefright/foundation/ColorUtils.h>
#include <SimpleC2Component.h>
@@ -60,6 +62,9 @@
uint32_t mHeight;
bool mSignalledOutputEos;
bool mSignalledError;
+ // Used during 10-bit I444/I422 to 10-bit P010 & 8-bit I420 conversions.
+ std::unique_ptr<uint16_t[]> mTmpFrameBuffer;
+ size_t mTmpFrameBufferSize = 0;
C2StreamHdrStaticMetadataInfo::output mHdrStaticMetadataInfo;
std::unique_ptr<C2StreamHdr10PlusInfo::output> mHdr10PlusInfo = nullptr;
@@ -97,6 +102,9 @@
void destroyDecoder();
void finishWork(uint64_t index, const std::unique_ptr<C2Work>& work,
const std::shared_ptr<C2GraphicBlock>& block);
+ // Sets |work->result| and mSignalledError. Returns false.
+ void setError(const std::unique_ptr<C2Work> &work, c2_status_t error);
+ bool allocTmpFrameBuffer(size_t size);
bool outputBuffer(const std::shared_ptr<C2BlockPool>& pool,
const std::unique_ptr<C2Work>& work);
c2_status_t drainInternal(uint32_t drainMode,
diff --git a/media/libaaudio/include/aaudio/AAudio.h b/media/libaaudio/include/aaudio/AAudio.h
index 6c364c9..13e430a 100644
--- a/media/libaaudio/include/aaudio/AAudio.h
+++ b/media/libaaudio/include/aaudio/AAudio.h
@@ -758,7 +758,8 @@
*
* @return pointer to a text representation of an AAudio result code.
*/
-AAUDIO_API const char * AAudio_convertResultToText(aaudio_result_t returnCode) __INTRODUCED_IN(26);
+AAUDIO_API const char * _Nonnull AAudio_convertResultToText(aaudio_result_t returnCode)
+ __INTRODUCED_IN(26);
/**
* The text is the ASCII symbol corresponding to the stream state,
@@ -770,7 +771,7 @@
*
* @return pointer to a text representation of an AAudio state.
*/
-AAUDIO_API const char * AAudio_convertStreamStateToText(aaudio_stream_state_t state)
+AAUDIO_API const char * _Nonnull AAudio_convertStreamStateToText(aaudio_stream_state_t state)
__INTRODUCED_IN(26);
// ============================================================
@@ -791,8 +792,8 @@
*
* Available since API level 26.
*/
-AAUDIO_API aaudio_result_t AAudio_createStreamBuilder(AAudioStreamBuilder** builder)
- __INTRODUCED_IN(26);
+AAUDIO_API aaudio_result_t AAudio_createStreamBuilder(AAudioStreamBuilder* _Nullable* _Nonnull
+ builder) __INTRODUCED_IN(26);
/**
* Request an audio device identified by an ID.
@@ -814,7 +815,7 @@
* @param builder reference provided by AAudio_createStreamBuilder()
* @param deviceId device identifier or {@link #AAUDIO_UNSPECIFIED}
*/
-AAUDIO_API void AAudioStreamBuilder_setDeviceId(AAudioStreamBuilder* builder,
+AAUDIO_API void AAudioStreamBuilder_setDeviceId(AAudioStreamBuilder* _Nonnull builder,
int32_t deviceId) __INTRODUCED_IN(26);
/**
@@ -834,8 +835,8 @@
* @param builder reference provided by AAudio_createStreamBuilder()
* @param packageName packageName of the calling app.
*/
-AAUDIO_API void AAudioStreamBuilder_setPackageName(AAudioStreamBuilder* builder,
- const char * packageName) __INTRODUCED_IN(31);
+AAUDIO_API void AAudioStreamBuilder_setPackageName(AAudioStreamBuilder* _Nonnull builder,
+ const char * _Nonnull packageName) __INTRODUCED_IN(31);
/**
* Declare the attribution tag of the context creating the stream.
@@ -849,8 +850,8 @@
* @param builder reference provided by AAudio_createStreamBuilder()
* @param attributionTag attributionTag of the calling context.
*/
-AAUDIO_API void AAudioStreamBuilder_setAttributionTag(AAudioStreamBuilder* builder,
- const char * attributionTag) __INTRODUCED_IN(31);
+AAUDIO_API void AAudioStreamBuilder_setAttributionTag(AAudioStreamBuilder* _Nonnull builder,
+ const char * _Nonnull attributionTag) __INTRODUCED_IN(31);
/**
* Request a sample rate in Hertz.
@@ -868,7 +869,7 @@
* @param builder reference provided by AAudio_createStreamBuilder()
* @param sampleRate frames per second. Common rates include 44100 and 48000 Hz.
*/
-AAUDIO_API void AAudioStreamBuilder_setSampleRate(AAudioStreamBuilder* builder,
+AAUDIO_API void AAudioStreamBuilder_setSampleRate(AAudioStreamBuilder* _Nonnull builder,
int32_t sampleRate) __INTRODUCED_IN(26);
/**
@@ -898,7 +899,7 @@
* @param builder reference provided by AAudio_createStreamBuilder()
* @param channelCount Number of channels desired.
*/
-AAUDIO_API void AAudioStreamBuilder_setChannelCount(AAudioStreamBuilder* builder,
+AAUDIO_API void AAudioStreamBuilder_setChannelCount(AAudioStreamBuilder* _Nonnull builder,
int32_t channelCount) __INTRODUCED_IN(26);
/**
@@ -911,7 +912,7 @@
*
* @deprecated use {@link AAudioStreamBuilder_setChannelCount}
*/
-AAUDIO_API void AAudioStreamBuilder_setSamplesPerFrame(AAudioStreamBuilder* builder,
+AAUDIO_API void AAudioStreamBuilder_setSamplesPerFrame(AAudioStreamBuilder* _Nonnull builder,
int32_t samplesPerFrame) __INTRODUCED_IN(26);
/**
@@ -931,7 +932,7 @@
* @param format common formats are {@link #AAUDIO_FORMAT_PCM_FLOAT} and
* {@link #AAUDIO_FORMAT_PCM_I16}.
*/
-AAUDIO_API void AAudioStreamBuilder_setFormat(AAudioStreamBuilder* builder,
+AAUDIO_API void AAudioStreamBuilder_setFormat(AAudioStreamBuilder* _Nonnull builder,
aaudio_format_t format) __INTRODUCED_IN(26);
/**
@@ -947,7 +948,7 @@
* @param builder reference provided by AAudio_createStreamBuilder()
* @param sharingMode {@link #AAUDIO_SHARING_MODE_SHARED} or {@link #AAUDIO_SHARING_MODE_EXCLUSIVE}
*/
-AAUDIO_API void AAudioStreamBuilder_setSharingMode(AAudioStreamBuilder* builder,
+AAUDIO_API void AAudioStreamBuilder_setSharingMode(AAudioStreamBuilder* _Nonnull builder,
aaudio_sharing_mode_t sharingMode) __INTRODUCED_IN(26);
/**
@@ -960,7 +961,7 @@
* @param builder reference provided by AAudio_createStreamBuilder()
* @param direction {@link #AAUDIO_DIRECTION_OUTPUT} or {@link #AAUDIO_DIRECTION_INPUT}
*/
-AAUDIO_API void AAudioStreamBuilder_setDirection(AAudioStreamBuilder* builder,
+AAUDIO_API void AAudioStreamBuilder_setDirection(AAudioStreamBuilder* _Nonnull builder,
aaudio_direction_t direction) __INTRODUCED_IN(26);
/**
@@ -974,8 +975,8 @@
* @param builder reference provided by AAudio_createStreamBuilder()
* @param numFrames the desired buffer capacity in frames or {@link #AAUDIO_UNSPECIFIED}
*/
-AAUDIO_API void AAudioStreamBuilder_setBufferCapacityInFrames(AAudioStreamBuilder* builder,
- int32_t numFrames) __INTRODUCED_IN(26);
+AAUDIO_API void AAudioStreamBuilder_setBufferCapacityInFrames(
+ AAudioStreamBuilder* _Nonnull builder, int32_t numFrames) __INTRODUCED_IN(26);
/**
* Set the requested performance mode.
@@ -994,7 +995,7 @@
* @param builder reference provided by AAudio_createStreamBuilder()
* @param mode the desired performance mode, eg. {@link #AAUDIO_PERFORMANCE_MODE_LOW_LATENCY}
*/
-AAUDIO_API void AAudioStreamBuilder_setPerformanceMode(AAudioStreamBuilder* builder,
+AAUDIO_API void AAudioStreamBuilder_setPerformanceMode(AAudioStreamBuilder* _Nonnull builder,
aaudio_performance_mode_t mode) __INTRODUCED_IN(26);
/**
@@ -1011,7 +1012,7 @@
* @param builder reference provided by AAudio_createStreamBuilder()
* @param usage the desired usage, eg. {@link #AAUDIO_USAGE_GAME}
*/
-AAUDIO_API void AAudioStreamBuilder_setUsage(AAudioStreamBuilder* builder,
+AAUDIO_API void AAudioStreamBuilder_setUsage(AAudioStreamBuilder* _Nonnull builder,
aaudio_usage_t usage) __INTRODUCED_IN(28);
/**
@@ -1028,7 +1029,7 @@
* @param builder reference provided by AAudio_createStreamBuilder()
* @param contentType the type of audio data, eg. {@link #AAUDIO_CONTENT_TYPE_SPEECH}
*/
-AAUDIO_API void AAudioStreamBuilder_setContentType(AAudioStreamBuilder* builder,
+AAUDIO_API void AAudioStreamBuilder_setContentType(AAudioStreamBuilder* _Nonnull builder,
aaudio_content_type_t contentType) __INTRODUCED_IN(28);
/**
@@ -1043,7 +1044,8 @@
* @param spatializationBehavior the desired behavior with regards to spatialization, eg.
* {@link #AAUDIO_SPATIALIZATION_BEHAVIOR_AUTO}
*/
-AAUDIO_API void AAudioStreamBuilder_setSpatializationBehavior(AAudioStreamBuilder* builder,
+AAUDIO_API void AAudioStreamBuilder_setSpatializationBehavior(
+ AAudioStreamBuilder* _Nonnull builder,
aaudio_spatialization_behavior_t spatializationBehavior) __INTRODUCED_IN(32);
/**
@@ -1059,7 +1061,7 @@
* @param isSpatialized true if the content is already processed for binaural or transaural spatial
* rendering, false otherwise.
*/
-AAUDIO_API void AAudioStreamBuilder_setIsContentSpatialized(AAudioStreamBuilder* builder,
+AAUDIO_API void AAudioStreamBuilder_setIsContentSpatialized(AAudioStreamBuilder* _Nonnull builder,
bool isSpatialized) __INTRODUCED_IN(32);
/**
@@ -1079,7 +1081,7 @@
* @param builder reference provided by AAudio_createStreamBuilder()
* @param inputPreset the desired configuration for recording
*/
-AAUDIO_API void AAudioStreamBuilder_setInputPreset(AAudioStreamBuilder* builder,
+AAUDIO_API void AAudioStreamBuilder_setInputPreset(AAudioStreamBuilder* _Nonnull builder,
aaudio_input_preset_t inputPreset) __INTRODUCED_IN(28);
/**
@@ -1097,7 +1099,7 @@
* @param builder reference provided by AAudio_createStreamBuilder()
* @param capturePolicy the desired level of opt-out from being captured.
*/
-AAUDIO_API void AAudioStreamBuilder_setAllowedCapturePolicy(AAudioStreamBuilder* builder,
+AAUDIO_API void AAudioStreamBuilder_setAllowedCapturePolicy(AAudioStreamBuilder* _Nonnull builder,
aaudio_allowed_capture_policy_t capturePolicy) __INTRODUCED_IN(29);
/** Set the requested session ID.
@@ -1127,7 +1129,7 @@
* @param builder reference provided by AAudio_createStreamBuilder()
* @param sessionId an allocated sessionID or {@link #AAUDIO_SESSION_ID_ALLOCATE}
*/
-AAUDIO_API void AAudioStreamBuilder_setSessionId(AAudioStreamBuilder* builder,
+AAUDIO_API void AAudioStreamBuilder_setSessionId(AAudioStreamBuilder* _Nonnull builder,
aaudio_session_id_t sessionId) __INTRODUCED_IN(28);
@@ -1149,7 +1151,7 @@
* @param privacySensitive true if capture from this stream must be marked as privacy sensitive,
* false otherwise.
*/
-AAUDIO_API void AAudioStreamBuilder_setPrivacySensitive(AAudioStreamBuilder* builder,
+AAUDIO_API void AAudioStreamBuilder_setPrivacySensitive(AAudioStreamBuilder* _Nonnull builder,
bool privacySensitive) __INTRODUCED_IN(30);
/**
@@ -1223,9 +1225,9 @@
* @return AAUDIO_CALLBACK_RESULT_*
*/
typedef aaudio_data_callback_result_t (*AAudioStream_dataCallback)(
- AAudioStream *stream,
- void *userData,
- void *audioData,
+ AAudioStream* _Nonnull stream,
+ void* _Nullable userData,
+ void* _Nonnull audioData,
int32_t numFrames);
/**
@@ -1254,8 +1256,9 @@
* @param userData pointer to an application data structure that will be passed
* to the callback functions.
*/
-AAUDIO_API void AAudioStreamBuilder_setDataCallback(AAudioStreamBuilder* builder,
- AAudioStream_dataCallback callback, void *userData) __INTRODUCED_IN(26);
+AAUDIO_API void AAudioStreamBuilder_setDataCallback(AAudioStreamBuilder* _Nonnull builder,
+ AAudioStream_dataCallback _Nullable callback, void* _Nullable userData)
+ __INTRODUCED_IN(26);
/**
* Set the requested data callback buffer size in frames.
@@ -1282,8 +1285,8 @@
* @param builder reference provided by AAudio_createStreamBuilder()
* @param numFrames the desired buffer size in frames or {@link #AAUDIO_UNSPECIFIED}
*/
-AAUDIO_API void AAudioStreamBuilder_setFramesPerDataCallback(AAudioStreamBuilder* builder,
- int32_t numFrames) __INTRODUCED_IN(26);
+AAUDIO_API void AAudioStreamBuilder_setFramesPerDataCallback(AAudioStreamBuilder* _Nonnull builder,
+ int32_t numFrames) __INTRODUCED_IN(26);
/**
* Prototype for the callback function that is passed to
@@ -1310,8 +1313,8 @@
* @param error an AAUDIO_ERROR_* value.
*/
typedef void (*AAudioStream_errorCallback)(
- AAudioStream *stream,
- void *userData,
+ AAudioStream* _Nonnull stream,
+ void* _Nullable userData,
aaudio_result_t error);
/**
@@ -1337,8 +1340,9 @@
* @param userData pointer to an application data structure that will be passed
* to the callback functions.
*/
-AAUDIO_API void AAudioStreamBuilder_setErrorCallback(AAudioStreamBuilder* builder,
- AAudioStream_errorCallback callback, void *userData) __INTRODUCED_IN(26);
+AAUDIO_API void AAudioStreamBuilder_setErrorCallback(AAudioStreamBuilder* _Nonnull builder,
+ AAudioStream_errorCallback _Nullable callback, void* _Nullable userData)
+ __INTRODUCED_IN(26);
/**
* Open a stream based on the options in the StreamBuilder.
@@ -1352,8 +1356,8 @@
* @param stream pointer to a variable to receive the new stream reference
* @return {@link #AAUDIO_OK} or a negative error.
*/
-AAUDIO_API aaudio_result_t AAudioStreamBuilder_openStream(AAudioStreamBuilder* builder,
- AAudioStream** stream) __INTRODUCED_IN(26);
+AAUDIO_API aaudio_result_t AAudioStreamBuilder_openStream(AAudioStreamBuilder* _Nonnull builder,
+ AAudioStream* _Nullable* _Nonnull stream) __INTRODUCED_IN(26);
/**
* Delete the resources associated with the StreamBuilder.
@@ -1363,7 +1367,7 @@
* @param builder reference provided by AAudio_createStreamBuilder()
* @return {@link #AAUDIO_OK} or a negative error.
*/
-AAUDIO_API aaudio_result_t AAudioStreamBuilder_delete(AAudioStreamBuilder* builder)
+AAUDIO_API aaudio_result_t AAudioStreamBuilder_delete(AAudioStreamBuilder* _Nonnull builder)
__INTRODUCED_IN(26);
/**
@@ -1389,7 +1393,7 @@
* @param builder reference provided by AAudio_createStreamBuilder()
* @param channelMask Audio channel mask desired.
*/
-AAUDIO_API void AAudioStreamBuilder_setChannelMask(AAudioStreamBuilder* builder,
+AAUDIO_API void AAudioStreamBuilder_setChannelMask(AAudioStreamBuilder* _Nonnull builder,
aaudio_channel_mask_t channelMask) __INTRODUCED_IN(32);
// ============================================================
@@ -1418,7 +1422,8 @@
* @param stream reference provided by AAudioStreamBuilder_openStream()
* @return {@link #AAUDIO_OK} or a negative error.
*/
-AAUDIO_API aaudio_result_t AAudioStream_release(AAudioStream* stream) __INTRODUCED_IN(30);
+AAUDIO_API aaudio_result_t AAudioStream_release(AAudioStream* _Nonnull stream)
+ __INTRODUCED_IN(30);
/**
* Delete the internal data structures associated with the stream created
@@ -1431,7 +1436,7 @@
* @param stream reference provided by AAudioStreamBuilder_openStream()
* @return {@link #AAUDIO_OK} or a negative error.
*/
-AAUDIO_API aaudio_result_t AAudioStream_close(AAudioStream* stream) __INTRODUCED_IN(26);
+AAUDIO_API aaudio_result_t AAudioStream_close(AAudioStream* _Nonnull stream) __INTRODUCED_IN(26);
/**
* Asynchronously request to start playing the stream. For output streams, one should
@@ -1445,7 +1450,8 @@
* @param stream reference provided by AAudioStreamBuilder_openStream()
* @return {@link #AAUDIO_OK} or a negative error.
*/
-AAUDIO_API aaudio_result_t AAudioStream_requestStart(AAudioStream* stream) __INTRODUCED_IN(26);
+AAUDIO_API aaudio_result_t AAudioStream_requestStart(AAudioStream* _Nonnull stream)
+ __INTRODUCED_IN(26);
/**
* Asynchronous request for the stream to pause.
@@ -1462,7 +1468,8 @@
* @param stream reference provided by AAudioStreamBuilder_openStream()
* @return {@link #AAUDIO_OK} or a negative error.
*/
-AAUDIO_API aaudio_result_t AAudioStream_requestPause(AAudioStream* stream) __INTRODUCED_IN(26);
+AAUDIO_API aaudio_result_t AAudioStream_requestPause(AAudioStream* _Nonnull stream)
+ __INTRODUCED_IN(26);
/**
* Asynchronous request for the stream to flush.
@@ -1482,7 +1489,8 @@
* @param stream reference provided by AAudioStreamBuilder_openStream()
* @return {@link #AAUDIO_OK} or a negative error.
*/
-AAUDIO_API aaudio_result_t AAudioStream_requestFlush(AAudioStream* stream) __INTRODUCED_IN(26);
+AAUDIO_API aaudio_result_t AAudioStream_requestFlush(AAudioStream* _Nonnull stream)
+ __INTRODUCED_IN(26);
/**
* Asynchronous request for the stream to stop.
@@ -1495,7 +1503,8 @@
* @param stream reference provided by AAudioStreamBuilder_openStream()
* @return {@link #AAUDIO_OK} or a negative error.
*/
-AAUDIO_API aaudio_result_t AAudioStream_requestStop(AAudioStream* stream) __INTRODUCED_IN(26);
+AAUDIO_API aaudio_result_t AAudioStream_requestStop(AAudioStream* _Nonnull stream)
+ __INTRODUCED_IN(26);
/**
* Query the current state of the client, eg. {@link #AAUDIO_STREAM_STATE_PAUSING}
@@ -1509,7 +1518,8 @@
*
* @param stream reference provided by AAudioStreamBuilder_openStream()
*/
-AAUDIO_API aaudio_stream_state_t AAudioStream_getState(AAudioStream* stream) __INTRODUCED_IN(26);
+AAUDIO_API aaudio_stream_state_t AAudioStream_getState(AAudioStream* _Nonnull stream)
+ __INTRODUCED_IN(26);
/**
* Wait until the current state no longer matches the input state.
@@ -1535,8 +1545,8 @@
* @param timeoutNanoseconds Maximum number of nanoseconds to wait for completion.
* @return {@link #AAUDIO_OK} or a negative error.
*/
-AAUDIO_API aaudio_result_t AAudioStream_waitForStateChange(AAudioStream* stream,
- aaudio_stream_state_t inputState, aaudio_stream_state_t *nextState,
+AAUDIO_API aaudio_result_t AAudioStream_waitForStateChange(AAudioStream* _Nonnull stream,
+ aaudio_stream_state_t inputState, aaudio_stream_state_t* _Nullable nextState,
int64_t timeoutNanoseconds) __INTRODUCED_IN(26);
// ============================================================
@@ -1565,8 +1575,8 @@
* @param timeoutNanoseconds Maximum number of nanoseconds to wait for completion.
* @return The number of frames actually read or a negative error.
*/
-AAUDIO_API aaudio_result_t AAudioStream_read(AAudioStream* stream,
- void *buffer, int32_t numFrames, int64_t timeoutNanoseconds) __INTRODUCED_IN(26);
+AAUDIO_API aaudio_result_t AAudioStream_read(AAudioStream* _Nonnull stream,
+ void* _Nonnull buffer, int32_t numFrames, int64_t timeoutNanoseconds) __INTRODUCED_IN(26);
/**
* Write data to the stream.
@@ -1590,8 +1600,9 @@
* @param timeoutNanoseconds Maximum number of nanoseconds to wait for completion.
* @return The number of frames actually written or a negative error.
*/
-AAUDIO_API aaudio_result_t AAudioStream_write(AAudioStream* stream,
- const void *buffer, int32_t numFrames, int64_t timeoutNanoseconds) __INTRODUCED_IN(26);
+AAUDIO_API aaudio_result_t AAudioStream_write(AAudioStream* _Nonnull stream,
+ const void* _Nonnull buffer, int32_t numFrames, int64_t timeoutNanoseconds)
+ __INTRODUCED_IN(26);
// ============================================================
// Stream - queries
@@ -1615,7 +1626,7 @@
* @param numFrames requested number of frames that can be filled without blocking
* @return actual buffer size in frames or a negative error
*/
-AAUDIO_API aaudio_result_t AAudioStream_setBufferSizeInFrames(AAudioStream* stream,
+AAUDIO_API aaudio_result_t AAudioStream_setBufferSizeInFrames(AAudioStream* _Nonnull stream,
int32_t numFrames) __INTRODUCED_IN(26);
/**
@@ -1626,7 +1637,8 @@
* @param stream reference provided by AAudioStreamBuilder_openStream()
* @return buffer size in frames.
*/
-AAUDIO_API int32_t AAudioStream_getBufferSizeInFrames(AAudioStream* stream) __INTRODUCED_IN(26);
+AAUDIO_API int32_t AAudioStream_getBufferSizeInFrames(AAudioStream* _Nonnull stream)
+ __INTRODUCED_IN(26);
/**
* Query the number of frames that the application should read or write at
@@ -1643,7 +1655,8 @@
* @param stream reference provided by AAudioStreamBuilder_openStream()
* @return burst size
*/
-AAUDIO_API int32_t AAudioStream_getFramesPerBurst(AAudioStream* stream) __INTRODUCED_IN(26);
+AAUDIO_API int32_t AAudioStream_getFramesPerBurst(AAudioStream* _Nonnull stream)
+ __INTRODUCED_IN(26);
/**
* Query maximum buffer capacity in frames.
@@ -1653,7 +1666,8 @@
* @param stream reference provided by AAudioStreamBuilder_openStream()
* @return buffer capacity in frames
*/
-AAUDIO_API int32_t AAudioStream_getBufferCapacityInFrames(AAudioStream* stream) __INTRODUCED_IN(26);
+AAUDIO_API int32_t AAudioStream_getBufferCapacityInFrames(AAudioStream* _Nonnull stream)
+ __INTRODUCED_IN(26);
/**
* Query the size of the buffer that will be passed to the dataProc callback
@@ -1676,7 +1690,8 @@
* @param stream reference provided by AAudioStreamBuilder_openStream()
* @return callback buffer size in frames or {@link #AAUDIO_UNSPECIFIED}
*/
-AAUDIO_API int32_t AAudioStream_getFramesPerDataCallback(AAudioStream* stream) __INTRODUCED_IN(26);
+AAUDIO_API int32_t AAudioStream_getFramesPerDataCallback(AAudioStream* _Nonnull stream)
+ __INTRODUCED_IN(26);
/**
* An XRun is an Underrun or an Overrun.
@@ -1695,7 +1710,7 @@
* @param stream reference provided by AAudioStreamBuilder_openStream()
* @return the underrun or overrun count
*/
-AAUDIO_API int32_t AAudioStream_getXRunCount(AAudioStream* stream) __INTRODUCED_IN(26);
+AAUDIO_API int32_t AAudioStream_getXRunCount(AAudioStream* _Nonnull stream) __INTRODUCED_IN(26);
/**
* Available since API level 26.
@@ -1703,13 +1718,13 @@
* @param stream reference provided by AAudioStreamBuilder_openStream()
* @return actual sample rate of the stream
*/
-AAUDIO_API int32_t AAudioStream_getSampleRate(AAudioStream* stream) __INTRODUCED_IN(26);
+AAUDIO_API int32_t AAudioStream_getSampleRate(AAudioStream* _Nonnull stream) __INTRODUCED_IN(26);
/**
* There may be sample rate conversions in the Audio framework.
* The sample rate set in the stream builder may not be actual sample rate used in the hardware.
*
- * This returns the sample rate used by the hardware.
+ * This returns the sample rate used by the hardware in Hertz.
*
* If AAudioStreamBuilder_openStream() returned AAUDIO_OK, the result should always be valid.
*
@@ -1718,7 +1733,7 @@
* @param stream reference provided by AAudioStreamBuilder_openStream()
* @return actual sample rate of the underlying hardware
*/
-AAUDIO_API int32_t AAudioStream_getHardwareSampleRate(AAudioStream* stream)
+AAUDIO_API int32_t AAudioStream_getHardwareSampleRate(AAudioStream* _Nonnull stream)
__INTRODUCED_IN(__ANDROID_API_U__);
/**
@@ -1730,7 +1745,7 @@
* @param stream reference provided by AAudioStreamBuilder_openStream()
* @return actual number of channels of the stream
*/
-AAUDIO_API int32_t AAudioStream_getChannelCount(AAudioStream* stream) __INTRODUCED_IN(26);
+AAUDIO_API int32_t AAudioStream_getChannelCount(AAudioStream* _Nonnull stream) __INTRODUCED_IN(26);
/**
* There may be channel conversions in the Audio framework.
@@ -1746,7 +1761,7 @@
* @param stream reference provided by AAudioStreamBuilder_openStream()
* @return actual number of channels of the underlying hardware
*/
-AAUDIO_API int32_t AAudioStream_getHardwareChannelCount(AAudioStream* stream)
+AAUDIO_API int32_t AAudioStream_getHardwareChannelCount(AAudioStream* _Nonnull stream)
__INTRODUCED_IN(__ANDROID_API_U__);
/**
@@ -1757,7 +1772,8 @@
* @param stream reference provided by AAudioStreamBuilder_openStream()
* @return actual number of samples frame
*/
-AAUDIO_API int32_t AAudioStream_getSamplesPerFrame(AAudioStream* stream) __INTRODUCED_IN(26);
+AAUDIO_API int32_t AAudioStream_getSamplesPerFrame(AAudioStream* _Nonnull stream)
+ __INTRODUCED_IN(26);
/**
* Available since API level 26.
@@ -1765,7 +1781,7 @@
* @param stream reference provided by AAudioStreamBuilder_openStream()
* @return actual device ID
*/
-AAUDIO_API int32_t AAudioStream_getDeviceId(AAudioStream* stream) __INTRODUCED_IN(26);
+AAUDIO_API int32_t AAudioStream_getDeviceId(AAudioStream* _Nonnull stream) __INTRODUCED_IN(26);
/**
* Available since API level 26.
@@ -1773,22 +1789,30 @@
* @param stream reference provided by AAudioStreamBuilder_openStream()
* @return actual data format of the stream
*/
-AAUDIO_API aaudio_format_t AAudioStream_getFormat(AAudioStream* stream) __INTRODUCED_IN(26);
+AAUDIO_API aaudio_format_t AAudioStream_getFormat(AAudioStream* _Nonnull stream)
+ __INTRODUCED_IN(26);
/**
* There may be data format conversions in the Audio framework.
* The data format set in the stream builder may not be actual format used in the hardware.
*
* This returns the audio format used by the hardware.
+ *
+ * If AAudioStreamBuilder_openStream() returned AAUDIO_OK, this should always return an
+ * aaudio_format_t.
+ *
* AUDIO_FORMAT_PCM_8_24_BIT is currently not supported in AAudio, but the hardware may use it.
* If AUDIO_FORMAT_PCM_8_24_BIT is used by the hardware, return AAUDIO_FORMAT_PCM_I24_PACKED.
*
+ * If any other format used by the hardware is not supported by AAudio, this will return
+ * AAUDIO_FORMAT_INVALID.
+ *
* Available since API level 34.
*
* @param stream reference provided by AAudioStreamBuilder_openStream()
* @return actual data format of the underlying hardware.
*/
-AAUDIO_API aaudio_format_t AAudioStream_getHardwareFormat(AAudioStream* stream)
+AAUDIO_API aaudio_format_t AAudioStream_getHardwareFormat(AAudioStream* _Nonnull stream)
__INTRODUCED_IN(__ANDROID_API_U__);
/**
@@ -1799,7 +1823,7 @@
* @param stream reference provided by AAudioStreamBuilder_openStream()
* @return actual sharing mode
*/
-AAUDIO_API aaudio_sharing_mode_t AAudioStream_getSharingMode(AAudioStream* stream)
+AAUDIO_API aaudio_sharing_mode_t AAudioStream_getSharingMode(AAudioStream* _Nonnull stream)
__INTRODUCED_IN(26);
/**
@@ -1809,7 +1833,7 @@
*
* @param stream reference provided by AAudioStreamBuilder_openStream()
*/
-AAUDIO_API aaudio_performance_mode_t AAudioStream_getPerformanceMode(AAudioStream* stream)
+AAUDIO_API aaudio_performance_mode_t AAudioStream_getPerformanceMode(AAudioStream* _Nonnull stream)
__INTRODUCED_IN(26);
/**
@@ -1818,7 +1842,8 @@
* @param stream reference provided by AAudioStreamBuilder_openStream()
* @return direction
*/
-AAUDIO_API aaudio_direction_t AAudioStream_getDirection(AAudioStream* stream) __INTRODUCED_IN(26);
+AAUDIO_API aaudio_direction_t AAudioStream_getDirection(AAudioStream* _Nonnull stream)
+ __INTRODUCED_IN(26);
/**
* Passes back the number of frames that have been written since the stream was created.
@@ -1833,7 +1858,8 @@
* @param stream reference provided by AAudioStreamBuilder_openStream()
* @return frames written
*/
-AAUDIO_API int64_t AAudioStream_getFramesWritten(AAudioStream* stream) __INTRODUCED_IN(26);
+AAUDIO_API int64_t AAudioStream_getFramesWritten(AAudioStream* _Nonnull stream)
+ __INTRODUCED_IN(26);
/**
* Passes back the number of frames that have been read since the stream was created.
@@ -1848,7 +1874,7 @@
* @param stream reference provided by AAudioStreamBuilder_openStream()
* @return frames read
*/
-AAUDIO_API int64_t AAudioStream_getFramesRead(AAudioStream* stream) __INTRODUCED_IN(26);
+AAUDIO_API int64_t AAudioStream_getFramesRead(AAudioStream* _Nonnull stream) __INTRODUCED_IN(26);
/**
* Passes back the session ID associated with this stream.
@@ -1873,7 +1899,8 @@
* @param stream reference provided by AAudioStreamBuilder_openStream()
* @return session ID or {@link #AAUDIO_SESSION_ID_NONE}
*/
-AAUDIO_API aaudio_session_id_t AAudioStream_getSessionId(AAudioStream* stream) __INTRODUCED_IN(28);
+AAUDIO_API aaudio_session_id_t AAudioStream_getSessionId(AAudioStream* _Nonnull stream)
+ __INTRODUCED_IN(28);
/**
* Passes back the time at which a particular frame was presented.
@@ -1899,8 +1926,9 @@
* @param timeNanoseconds pointer to a variable to receive the time
* @return {@link #AAUDIO_OK} or a negative error
*/
-AAUDIO_API aaudio_result_t AAudioStream_getTimestamp(AAudioStream* stream,
- clockid_t clockid, int64_t *framePosition, int64_t *timeNanoseconds) __INTRODUCED_IN(26);
+AAUDIO_API aaudio_result_t AAudioStream_getTimestamp(AAudioStream* _Nonnull stream,
+ clockid_t clockid, int64_t* _Nonnull framePosition, int64_t* _Nonnull timeNanoseconds)
+ __INTRODUCED_IN(26);
/**
* Return the use case for the stream.
@@ -1910,7 +1938,7 @@
* @param stream reference provided by AAudioStreamBuilder_openStream()
* @return frames read
*/
-AAUDIO_API aaudio_usage_t AAudioStream_getUsage(AAudioStream* stream) __INTRODUCED_IN(28);
+AAUDIO_API aaudio_usage_t AAudioStream_getUsage(AAudioStream* _Nonnull stream) __INTRODUCED_IN(28);
/**
* Return the content type for the stream.
@@ -1920,7 +1948,7 @@
* @param stream reference provided by AAudioStreamBuilder_openStream()
* @return content type, for example {@link #AAUDIO_CONTENT_TYPE_MUSIC}
*/
-AAUDIO_API aaudio_content_type_t AAudioStream_getContentType(AAudioStream* stream)
+AAUDIO_API aaudio_content_type_t AAudioStream_getContentType(AAudioStream* _Nonnull stream)
__INTRODUCED_IN(28);
/**
@@ -1935,7 +1963,7 @@
* @return spatialization behavior, for example {@link #AAUDIO_SPATIALIZATION_BEHAVIOR_AUTO}
*/
AAUDIO_API aaudio_spatialization_behavior_t AAudioStream_getSpatializationBehavior(
- AAudioStream* stream) __INTRODUCED_IN(32);
+ AAudioStream* _Nonnull stream) __INTRODUCED_IN(32);
/**
* Return whether the content of the stream is spatialized.
@@ -1945,7 +1973,8 @@
* @param stream reference provided by AAudioStreamBuilder_openStream()
* @return true if the content is spatialized
*/
-AAUDIO_API bool AAudioStream_isContentSpatialized(AAudioStream* stream) __INTRODUCED_IN(32);
+AAUDIO_API bool AAudioStream_isContentSpatialized(AAudioStream* _Nonnull stream)
+ __INTRODUCED_IN(32);
/**
@@ -1956,7 +1985,7 @@
* @param stream reference provided by AAudioStreamBuilder_openStream()
* @return input preset, for example {@link #AAUDIO_INPUT_PRESET_CAMCORDER}
*/
-AAUDIO_API aaudio_input_preset_t AAudioStream_getInputPreset(AAudioStream* stream)
+AAUDIO_API aaudio_input_preset_t AAudioStream_getInputPreset(AAudioStream* _Nonnull stream)
__INTRODUCED_IN(28);
/**
@@ -1969,7 +1998,7 @@
* @return the allowed capture policy, for example {@link #AAUDIO_ALLOW_CAPTURE_BY_ALL}
*/
AAUDIO_API aaudio_allowed_capture_policy_t AAudioStream_getAllowedCapturePolicy(
- AAudioStream* stream) __INTRODUCED_IN(29);
+ AAudioStream* _Nonnull stream) __INTRODUCED_IN(29);
/**
@@ -1982,7 +2011,7 @@
* @param stream reference provided by AAudioStreamBuilder_openStream()
* @return true if privacy sensitive, false otherwise
*/
-AAUDIO_API bool AAudioStream_isPrivacySensitive(AAudioStream* stream)
+AAUDIO_API bool AAudioStream_isPrivacySensitive(AAudioStream* _Nonnull stream)
__INTRODUCED_IN(30);
/**
@@ -1994,7 +2023,7 @@
* @param stream reference provided by AAudioStreamBuilder_openStream()
* @return actual channel mask
*/
-AAUDIO_API aaudio_channel_mask_t AAudioStream_getChannelMask(AAudioStream* stream)
+AAUDIO_API aaudio_channel_mask_t AAudioStream_getChannelMask(AAudioStream* _Nonnull stream)
__INTRODUCED_IN(32);
#ifdef __cplusplus
diff --git a/media/libaudioclient/AudioPolicy.cpp b/media/libaudioclient/AudioPolicy.cpp
index 750ce1c..1b9936f 100644
--- a/media/libaudioclient/AudioPolicy.cpp
+++ b/media/libaudioclient/AudioPolicy.cpp
@@ -215,7 +215,7 @@
bool AudioMix::isDeviceAffinityCompatible() const {
return ((mMixType == MIX_TYPE_PLAYERS)
- && (mRouteFlags == MIX_ROUTE_FLAG_RENDER));
+ && ((mRouteFlags & MIX_ROUTE_FLAG_RENDER) == MIX_ROUTE_FLAG_RENDER));
}
} // namespace android
diff --git a/media/libaudiohal/impl/Android.bp b/media/libaudiohal/impl/Android.bp
index b6602ec..fd2f126 100644
--- a/media/libaudiohal/impl/Android.bp
+++ b/media/libaudiohal/impl/Android.bp
@@ -257,6 +257,11 @@
"EffectConversionHelperAidl.cpp",
"EffectBufferHalAidl.cpp",
"EffectHalAidl.cpp",
+ "effectsAidlConversion/AidlConversionAec.cpp",
+ "effectsAidlConversion/AidlConversionAgc2.cpp",
+ "effectsAidlConversion/AidlConversionBassBoost.cpp",
+ "effectsAidlConversion/AidlConversionDownmix.cpp",
+ "effectsAidlConversion/AidlConversionDynamicsProcessing.cpp",
"EffectsFactoryHalAidl.cpp",
"EffectsFactoryHalEntry.cpp",
"StreamHalAidl.cpp",
@@ -268,6 +273,7 @@
shared_libs: [
"libbinder_ndk",
"libaudio_aidl_conversion_common_ndk",
+ "libaudio_aidl_conversion_effect_ndk",
],
header_libs: [
"libaudio_aidl_conversion_common_util_ndk",
diff --git a/media/libaudiohal/impl/DeviceHalAidl.cpp b/media/libaudiohal/impl/DeviceHalAidl.cpp
index 280306d..1445e49 100644
--- a/media/libaudiohal/impl/DeviceHalAidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalAidl.cpp
@@ -17,6 +17,9 @@
#define LOG_TAG "DeviceHalAidl"
// #define LOG_NDEBUG 0
+#include <algorithm>
+#include <forward_list>
+
#include <aidl/android/hardware/audio/core/StreamDescriptor.h>
#include <error/expected_utils.h>
#include <media/AidlConversionCppNdk.h>
@@ -28,8 +31,19 @@
#include "StreamHalAidl.h"
using aidl::android::aidl_utils::statusTFromBinderStatus;
+using aidl::android::media::audio::common::AudioConfig;
+using aidl::android::media::audio::common::AudioDevice;
+using aidl::android::media::audio::common::AudioIoFlags;
using aidl::android::media::audio::common::AudioMode;
+using aidl::android::media::audio::common::AudioOutputFlags;
+using aidl::android::media::audio::common::AudioPort;
+using aidl::android::media::audio::common::AudioPortConfig;
+using aidl::android::media::audio::common::AudioPortExt;
+using aidl::android::media::audio::common::AudioSource;
+using aidl::android::media::audio::common::Int;
using aidl::android::media::audio::common::Float;
+using aidl::android::hardware::audio::common::RecordTrackMetadata;
+using aidl::android::hardware::audio::core::AudioPatch;
using aidl::android::hardware::audio::core::IModule;
using aidl::android::hardware::audio::core::ITelephony;
using aidl::android::hardware::audio::core::StreamDescriptor;
@@ -37,14 +51,55 @@
namespace android {
+namespace {
+
+bool isConfigEqualToPortConfig(const AudioConfig& config, const AudioPortConfig& portConfig) {
+ return portConfig.sampleRate.value().value == config.base.sampleRate &&
+ portConfig.channelMask.value() == config.base.channelMask &&
+ portConfig.format.value() == config.base.format;
+}
+
+void setConfigFromPortConfig(AudioConfig* config, const AudioPortConfig& portConfig) {
+ config->base.sampleRate = portConfig.sampleRate.value().value;
+ config->base.channelMask = portConfig.channelMask.value();
+ config->base.format = portConfig.format.value();
+}
+
+void setPortConfigFromConfig(AudioPortConfig* portConfig, const AudioConfig& config) {
+ portConfig->sampleRate = Int{ .value = config.base.sampleRate };
+ portConfig->channelMask = config.base.channelMask;
+ portConfig->format = config.base.format;
+}
+
+} // namespace
+
status_t DeviceHalAidl::getSupportedDevices(uint32_t*) {
// Obsolete.
return INVALID_OPERATION;
}
status_t DeviceHalAidl::initCheck() {
+ TIME_CHECK();
if (mModule == nullptr) return NO_INIT;
- // HAL modules are already initialized by the time they are published to the SM.
+ std::vector<AudioPort> ports;
+ RETURN_STATUS_IF_ERROR(
+ statusTFromBinderStatus(mModule->getAudioPorts(&ports)));
+ ALOGW_IF(ports.empty(), "%s: module %s returned an empty list of audio ports",
+ __func__, mInstance.c_str());
+ std::transform(ports.begin(), ports.end(), std::inserter(mPorts, mPorts.end()),
+ [](const auto& p) { return std::make_pair(p.id, p); });
+ std::vector<AudioPortConfig> portConfigs;
+ RETURN_STATUS_IF_ERROR(
+ statusTFromBinderStatus(mModule->getAudioPortConfigs(&portConfigs))); // OK if empty
+ std::transform(portConfigs.begin(), portConfigs.end(),
+ std::inserter(mPortConfigs, mPortConfigs.end()),
+ [](const auto& p) { return std::make_pair(p.id, p); });
+ std::vector<AudioPatch> patches;
+ RETURN_STATUS_IF_ERROR(
+ statusTFromBinderStatus(mModule->getAudioPatches(&patches))); // OK if empty
+ std::transform(patches.begin(), patches.end(),
+ std::inserter(mPatches, mPatches.end()),
+ [](const auto& p) { return std::make_pair(p.id, p); });
return OK;
}
@@ -135,47 +190,152 @@
return OK;
}
+namespace {
+
+class Cleanup {
+ public:
+ typedef void (DeviceHalAidl::*Cleaner)(int32_t);
+
+ Cleanup(DeviceHalAidl* device, Cleaner cleaner, int32_t id) :
+ mDevice(device), mCleaner(cleaner), mId(id) {}
+ ~Cleanup() { clean(); }
+ void clean() {
+ if (mDevice != nullptr) (mDevice->*mCleaner)(mId);
+ disarm();
+ }
+ void disarm() { mDevice = nullptr; }
+
+ private:
+ DeviceHalAidl* mDevice;
+ const Cleaner mCleaner;
+ const int32_t mId;
+};
+
+} // namespace
+
+// Since the order of container elements destruction is unspecified,
+// ensure that cleanups are performed from the most recent one and upwards.
+// This is the same as if there were individual Cleanup instances on the stack,
+// however the bonus is that we can disarm all of them with just one statement.
+class DeviceHalAidl::Cleanups : public std::forward_list<Cleanup> {
+ public:
+ ~Cleanups() { for (auto& c : *this) c.clean(); }
+ void disarmAll() { for (auto& c : *this) c.disarm(); }
+};
+
+status_t DeviceHalAidl::prepareToOpenStream(
+ int32_t aidlHandle, const AudioDevice& aidlDevice, const AudioIoFlags& aidlFlags,
+ struct audio_config* config,
+ Cleanups* cleanups, AudioConfig* aidlConfig, AudioPortConfig* mixPortConfig) {
+ const bool isInput = aidlFlags.getTag() == AudioIoFlags::Tag::input;
+ // Find / create AudioPortConfigs for the device port and the mix port,
+ // then find / create a patch between them, and open a stream on the mix port.
+ AudioPortConfig devicePortConfig;
+ bool created = false;
+ RETURN_STATUS_IF_ERROR(findOrCreatePortConfig(aidlDevice, &devicePortConfig, &created));
+ if (created) {
+ cleanups->emplace_front(this, &DeviceHalAidl::resetPortConfig, devicePortConfig.id);
+ }
+ RETURN_STATUS_IF_ERROR(findOrCreatePortConfig(*aidlConfig, aidlFlags, aidlHandle,
+ mixPortConfig, &created));
+ if (created) {
+ cleanups->emplace_front(this, &DeviceHalAidl::resetPortConfig, mixPortConfig->id);
+ }
+ setConfigFromPortConfig(aidlConfig, *mixPortConfig);
+ AudioPatch patch;
+ if (isInput) {
+ RETURN_STATUS_IF_ERROR(findOrCreatePatch(
+ {devicePortConfig.id}, {mixPortConfig->id}, &patch, &created));
+ } else {
+ RETURN_STATUS_IF_ERROR(findOrCreatePatch(
+ {mixPortConfig->id}, {devicePortConfig.id}, &patch, &created));
+ }
+ if (created) {
+ cleanups->emplace_front(this, &DeviceHalAidl::resetPatch, patch.id);
+ }
+ if (aidlConfig->frameCount <= 0) {
+ aidlConfig->frameCount = patch.minimumStreamBufferSizeFrames;
+ }
+ *config = VALUE_OR_RETURN_STATUS(
+ ::aidl::android::aidl2legacy_AudioConfig_audio_config_t(*aidlConfig, isInput));
+ return OK;
+}
+
status_t DeviceHalAidl::openOutputStream(
- audio_io_handle_t handle __unused, audio_devices_t devices __unused,
- audio_output_flags_t flags __unused, struct audio_config* config,
- const char* address __unused,
+ audio_io_handle_t handle, audio_devices_t devices,
+ audio_output_flags_t flags, struct audio_config* config,
+ const char* address,
sp<StreamOutHalInterface>* outStream) {
if (!outStream || !config) {
return BAD_VALUE;
}
TIME_CHECK();
if (!mModule) return NO_INIT;
- config->sample_rate = 48000;
- config->format = AUDIO_FORMAT_PCM_24_BIT_PACKED;
- config->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
- StreamDescriptor descriptor;
- descriptor.frameSizeBytes = audio_bytes_per_sample(config->format) *
- audio_channel_count_from_out_mask(config->channel_mask);
- descriptor.bufferSizeFrames = 600;
- *outStream = sp<StreamOutHalAidl>::make(descriptor, nullptr);
+ int32_t aidlHandle = VALUE_OR_RETURN_STATUS(
+ ::aidl::android::legacy2aidl_audio_io_handle_t_int32_t(handle));
+ AudioConfig aidlConfig = VALUE_OR_RETURN_STATUS(
+ ::aidl::android::legacy2aidl_audio_config_t_AudioConfig(*config, false /*isInput*/));
+ AudioDevice aidlDevice = VALUE_OR_RETURN_STATUS(
+ ::aidl::android::legacy2aidl_audio_device_AudioDevice(devices, address));
+ int32_t aidlOutputFlags = VALUE_OR_RETURN_STATUS(
+ ::aidl::android::legacy2aidl_audio_output_flags_t_int32_t_mask(flags));
+ AudioIoFlags aidlFlags = AudioIoFlags::make<AudioIoFlags::Tag::output>(aidlOutputFlags);
+ AudioPortConfig mixPortConfig;
+ Cleanups cleanups;
+ RETURN_STATUS_IF_ERROR(prepareToOpenStream(aidlHandle, aidlDevice, aidlFlags, config,
+ &cleanups, &aidlConfig, &mixPortConfig));
+ ::aidl::android::hardware::audio::core::IModule::OpenOutputStreamArguments args;
+ args.portConfigId = mixPortConfig.id;
+ args.offloadInfo = aidlConfig.offloadInfo;
+ args.bufferSizeFrames = aidlConfig.frameCount;
+ ::aidl::android::hardware::audio::core::IModule::OpenOutputStreamReturn ret;
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->openOutputStream(args, &ret)));
+ *outStream = sp<StreamOutHalAidl>::make(*config, std::move(ret.desc), std::move(ret.stream));
+ cleanups.disarmAll();
return OK;
}
status_t DeviceHalAidl::openInputStream(
- audio_io_handle_t handle __unused, audio_devices_t devices __unused,
- struct audio_config* config, audio_input_flags_t flags __unused,
- const char* address __unused, audio_source_t source __unused,
- audio_devices_t outputDevice __unused,
- const char* outputDeviceAddress __unused,
+ audio_io_handle_t handle, audio_devices_t devices,
+ struct audio_config* config, audio_input_flags_t flags,
+ const char* address, audio_source_t source,
+ audio_devices_t outputDevice, const char* outputDeviceAddress,
sp<StreamInHalInterface>* inStream) {
if (!inStream || !config) {
return BAD_VALUE;
}
TIME_CHECK();
if (!mModule) return NO_INIT;
- config->sample_rate = 48000;
- config->format = AUDIO_FORMAT_PCM_24_BIT_PACKED;
- config->channel_mask = AUDIO_CHANNEL_IN_STEREO;
- StreamDescriptor descriptor;
- descriptor.frameSizeBytes = audio_bytes_per_sample(config->format) *
- audio_channel_count_from_out_mask(config->channel_mask);
- descriptor.bufferSizeFrames = 600;
- *inStream = sp<StreamInHalAidl>::make(descriptor, nullptr);
+ int32_t aidlHandle = VALUE_OR_RETURN_STATUS(
+ ::aidl::android::legacy2aidl_audio_io_handle_t_int32_t(handle));
+ AudioConfig aidlConfig = VALUE_OR_RETURN_STATUS(
+ ::aidl::android::legacy2aidl_audio_config_t_AudioConfig(*config, true /*isInput*/));
+ AudioDevice aidlDevice = VALUE_OR_RETURN_STATUS(
+ ::aidl::android::legacy2aidl_audio_device_AudioDevice(devices, address));
+ int32_t aidlInputFlags = VALUE_OR_RETURN_STATUS(
+ ::aidl::android::legacy2aidl_audio_input_flags_t_int32_t_mask(flags));
+ AudioIoFlags aidlFlags = AudioIoFlags::make<AudioIoFlags::Tag::input>(aidlInputFlags);
+ AudioSource aidlSource = VALUE_OR_RETURN_STATUS(
+ ::aidl::android::legacy2aidl_audio_source_t_AudioSource(source));
+ AudioPortConfig mixPortConfig;
+ Cleanups cleanups;
+ RETURN_STATUS_IF_ERROR(prepareToOpenStream(aidlHandle, aidlDevice, aidlFlags, config,
+ &cleanups, &aidlConfig, &mixPortConfig));
+ ::aidl::android::hardware::audio::core::IModule::OpenInputStreamArguments args;
+ args.portConfigId = mixPortConfig.id;
+ RecordTrackMetadata aidlTrackMetadata{
+ .source = aidlSource, .gain = 1, .channelMask = aidlConfig.base.channelMask };
+ if (outputDevice != AUDIO_DEVICE_NONE) {
+ aidlTrackMetadata.destinationDevice = VALUE_OR_RETURN_STATUS(
+ ::aidl::android::legacy2aidl_audio_device_AudioDevice(
+ outputDevice, outputDeviceAddress));
+ }
+ args.sinkMetadata.tracks.push_back(std::move(aidlTrackMetadata));
+ args.bufferSizeFrames = aidlConfig.frameCount;
+ ::aidl::android::hardware::audio::core::IModule::OpenInputStreamReturn ret;
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->openInputStream(args, &ret)));
+ *inStream = sp<StreamInHalAidl>::make(*config, std::move(ret.desc), std::move(ret.stream));
+ cleanups.disarmAll();
return OK;
}
@@ -184,21 +344,104 @@
return OK;
}
-status_t DeviceHalAidl::createAudioPatch(unsigned int num_sources __unused,
- const struct audio_port_config* sources __unused,
- unsigned int num_sinks __unused,
- const struct audio_port_config* sinks __unused,
- audio_patch_handle_t* patch __unused) {
+status_t DeviceHalAidl::createAudioPatch(unsigned int num_sources,
+ const struct audio_port_config* sources,
+ unsigned int num_sinks,
+ const struct audio_port_config* sinks,
+ audio_patch_handle_t* patch) {
TIME_CHECK();
if (!mModule) return NO_INIT;
- ALOGE("%s not implemented yet", __func__);
+ if (num_sinks > AUDIO_PATCH_PORTS_MAX || num_sources > AUDIO_PATCH_PORTS_MAX ||
+ 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.
+
+ // Upon conversion, mix port configs contain audio configuration, while
+ // device port configs contain device address. This data is used to find
+ // or create HAL configs.
+ std::vector<AudioPortConfig> aidlSources, aidlSinks;
+ for (unsigned int i = 0; i < num_sources; ++i) {
+ bool isInput = VALUE_OR_RETURN_STATUS(::aidl::android::portDirection(
+ sources[i].role, sources[i].type)) ==
+ ::aidl::android::AudioPortDirection::INPUT;
+ aidlSources.push_back(VALUE_OR_RETURN_STATUS(
+ ::aidl::android::legacy2aidl_audio_port_config_AudioPortConfig(
+ sources[i], isInput, 0)));
+ }
+ for (unsigned int i = 0; i < num_sinks; ++i) {
+ bool isInput = VALUE_OR_RETURN_STATUS(::aidl::android::portDirection(
+ sinks[i].role, sinks[i].type)) ==
+ ::aidl::android::AudioPortDirection::INPUT;
+ aidlSinks.push_back(VALUE_OR_RETURN_STATUS(
+ ::aidl::android::legacy2aidl_audio_port_config_AudioPortConfig(
+ sinks[i], isInput, 0)));
+ }
+ Cleanups cleanups;
+ auto existingPatchIt = mPatches.end();
+ auto fwkHandlesIt = *patch != AUDIO_PATCH_HANDLE_NONE ?
+ mFwkHandles.find(*patch) : mFwkHandles.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();
+ }
+ }
+ auto fillPortConfigs = [&](
+ const std::vector<AudioPortConfig>& configs, std::vector<int32_t>* ids) -> status_t {
+ for (const auto& s : configs) {
+ AudioPortConfig portConfig;
+ bool created = false;
+ RETURN_STATUS_IF_ERROR(findOrCreatePortConfig(s, &portConfig, &created));
+ if (created) {
+ cleanups.emplace_front(this, &DeviceHalAidl::resetPortConfig, portConfig.id);
+ }
+ ids->push_back(portConfig.id);
+ }
+ return OK;
+ };
+ RETURN_STATUS_IF_ERROR(fillPortConfigs(aidlSources, &aidlPatch.sourcePortConfigIds));
+ RETURN_STATUS_IF_ERROR(fillPortConfigs(aidlSinks, &aidlPatch.sinkPortConfigIds));
+ if (existingPatchIt != mPatches.end()) {
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
+ mModule->setAudioPatch(aidlPatch, &aidlPatch)));
+ existingPatchIt->second = aidlPatch;
+ } else {
+ 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);
+ }
+ }
+ cleanups.disarmAll();
return OK;
}
-status_t DeviceHalAidl::releaseAudioPatch(audio_patch_handle_t patch __unused) {
+status_t DeviceHalAidl::releaseAudioPatch(audio_patch_handle_t patch) {
TIME_CHECK();
if (!mModule) return NO_INIT;
- ALOGE("%s not implemented yet", __func__);
+ auto idMapIt = mFwkHandles.find(patch);
+ if (idMapIt == mFwkHandles.end()) {
+ return BAD_VALUE;
+ }
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->resetAudioPatch(idMapIt->second)));
+ mFwkHandles.erase(idMapIt);
return OK;
}
@@ -308,4 +551,253 @@
return OK;
}
+status_t DeviceHalAidl::createPortConfig(const AudioPortConfig& requestedPortConfig,
+ AudioPortConfig* appliedPortConfig) {
+ TIME_CHECK();
+ bool applied = false;
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->setAudioPortConfig(
+ requestedPortConfig, appliedPortConfig, &applied)));
+ if (!applied) {
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->setAudioPortConfig(
+ *appliedPortConfig, appliedPortConfig, &applied)));
+ if (!applied) {
+ ALOGE("%s: module %s did not apply suggested config %s",
+ __func__, mInstance.c_str(), appliedPortConfig->toString().c_str());
+ return NO_INIT;
+ }
+ }
+ mPortConfigs.emplace(appliedPortConfig->id, *appliedPortConfig);
+ return OK;
+}
+
+status_t DeviceHalAidl::findOrCreatePatch(
+ const AudioPatch& requestedPatch, AudioPatch* patch, bool* created) {
+ std::set<int32_t> sourcePortConfigIds(requestedPatch.sourcePortConfigIds.begin(),
+ requestedPatch.sourcePortConfigIds.end());
+ std::set<int32_t> sinkPortConfigIds(requestedPatch.sinkPortConfigIds.begin(),
+ requestedPatch.sinkPortConfigIds.end());
+ return findOrCreatePatch(sourcePortConfigIds, sinkPortConfigIds, patch, created);
+}
+
+status_t DeviceHalAidl::findOrCreatePatch(
+ const std::set<int32_t>& sourcePortConfigIds, const std::set<int32_t>& sinkPortConfigIds,
+ AudioPatch* patch, bool* created) {
+ auto patchIt = findPatch(sourcePortConfigIds, sinkPortConfigIds);
+ if (patchIt == mPatches.end()) {
+ TIME_CHECK();
+ AudioPatch requestedPatch, appliedPatch;
+ requestedPatch.sourcePortConfigIds.insert(requestedPatch.sourcePortConfigIds.end(),
+ sourcePortConfigIds.begin(), sourcePortConfigIds.end());
+ requestedPatch.sinkPortConfigIds.insert(requestedPatch.sinkPortConfigIds.end(),
+ sinkPortConfigIds.begin(), sinkPortConfigIds.end());
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->setAudioPatch(
+ requestedPatch, &appliedPatch)));
+ patchIt = mPatches.insert(mPatches.end(), std::make_pair(appliedPatch.id, appliedPatch));
+ *created = true;
+ } else {
+ *created = false;
+ }
+ *patch = patchIt->second;
+ return OK;
+}
+
+status_t DeviceHalAidl::findOrCreatePortConfig(const AudioDevice& device,
+ AudioPortConfig* portConfig, bool* created) {
+ auto portConfigIt = findPortConfig(device);
+ if (portConfigIt == mPortConfigs.end()) {
+ auto portsIt = findPort(device);
+ if (portsIt == mPorts.end()) {
+ ALOGE("%s: device port for device %s is not found in the module %s",
+ __func__, device.toString().c_str(), mInstance.c_str());
+ return BAD_VALUE;
+ }
+ 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));
+ *created = true;
+ } else {
+ *created = false;
+ }
+ *portConfig = portConfigIt->second;
+ return OK;
+}
+
+status_t DeviceHalAidl::findOrCreatePortConfig(
+ const AudioConfig& config, const AudioIoFlags& flags, int32_t ioHandle,
+ AudioPortConfig* portConfig, bool* created) {
+ auto portConfigIt = findPortConfig(config, flags, ioHandle);
+ if (portConfigIt == mPortConfigs.end()) {
+ auto portsIt = findPort(config, flags);
+ 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.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));
+ *created = true;
+ } else {
+ *created = false;
+ }
+ *portConfig = portConfigIt->second;
+ return OK;
+}
+
+status_t DeviceHalAidl::findOrCreatePortConfig(
+ const AudioPortConfig& requestedPortConfig, AudioPortConfig* portConfig, bool* created) {
+ using Tag = AudioPortExt::Tag;
+ if (requestedPortConfig.ext.getTag() == Tag::mix) {
+ if (const auto& p = requestedPortConfig;
+ !p.sampleRate.has_value() || !p.channelMask.has_value() ||
+ !p.format.has_value() || !p.flags.has_value()) {
+ ALOGW("%s: provided mix port config is not fully specified: %s",
+ __func__, p.toString().c_str());
+ return BAD_VALUE;
+ }
+ AudioConfig config;
+ setConfigFromPortConfig(&config, requestedPortConfig);
+ return findOrCreatePortConfig(config, requestedPortConfig.flags.value(),
+ requestedPortConfig.ext.get<Tag::mix>().handle, portConfig, created);
+ } else if (requestedPortConfig.ext.getTag() == Tag::device) {
+ return findOrCreatePortConfig(
+ requestedPortConfig.ext.get<Tag::device>().device, portConfig, created);
+ }
+ ALOGW("%s: unsupported audio port config: %s",
+ __func__, requestedPortConfig.toString().c_str());
+ return BAD_VALUE;
+}
+
+DeviceHalAidl::Patches::iterator DeviceHalAidl::findPatch(
+ const std::set<int32_t>& sourcePortConfigIds, const std::set<int32_t>& sinkPortConfigIds) {
+ return std::find_if(mPatches.begin(), mPatches.end(),
+ [&](const auto& pair) {
+ const auto& p = pair.second;
+ std::set<int32_t> patchSrcs(
+ p.sourcePortConfigIds.begin(), p.sourcePortConfigIds.end());
+ std::set<int32_t> patchSinks(
+ p.sinkPortConfigIds.begin(), p.sinkPortConfigIds.end());
+ return sourcePortConfigIds == patchSrcs && sinkPortConfigIds == patchSinks; });
+}
+
+DeviceHalAidl::Ports::iterator DeviceHalAidl::findPort(const AudioDevice& device) {
+ using Tag = AudioPortExt::Tag;
+ return std::find_if(mPorts.begin(), mPorts.end(),
+ [&](const auto& pair) {
+ const auto& p = pair.second;
+ return p.ext.getTag() == Tag::device &&
+ p.ext.template get<Tag::device>().device == device; });
+}
+
+DeviceHalAidl::Ports::iterator DeviceHalAidl::findPort(
+ const AudioConfig& config, const AudioIoFlags& flags) {
+ using Tag = AudioPortExt::Tag;
+ return std::find_if(mPorts.begin(), mPorts.end(),
+ [&](const auto& pair) {
+ const auto& p = pair.second;
+ return p.ext.getTag() == Tag::mix &&
+ p.flags == flags &&
+ std::find_if(p.profiles.begin(), p.profiles.end(),
+ [&](const auto& prof) {
+ return prof.format == config.base.format &&
+ std::find(prof.channelMasks.begin(),
+ prof.channelMasks.end(),
+ config.base.channelMask) !=
+ prof.channelMasks.end() &&
+ std::find(prof.sampleRates.begin(),
+ prof.sampleRates.end(),
+ config.base.sampleRate) !=
+ prof.sampleRates.end();
+ }) != p.profiles.end(); });
+}
+
+DeviceHalAidl::PortConfigs::iterator DeviceHalAidl::findPortConfig(const AudioDevice& device) {
+ using Tag = AudioPortExt::Tag;
+ return std::find_if(mPortConfigs.begin(), mPortConfigs.end(),
+ [&](const auto& pair) {
+ const auto& p = pair.second;
+ return p.ext.getTag() == Tag::device &&
+ p.ext.template get<Tag::device>().device == device; });
+}
+
+DeviceHalAidl::PortConfigs::iterator DeviceHalAidl::findPortConfig(
+ const AudioConfig& config, const AudioIoFlags& flags, int32_t ioHandle) {
+ using Tag = AudioPortExt::Tag;
+ return std::find_if(mPortConfigs.begin(), mPortConfigs.end(),
+ [&](const auto& pair) {
+ const auto& p = pair.second;
+ LOG_ALWAYS_FATAL_IF(p.ext.getTag() == Tag::mix &&
+ !p.sampleRate.has_value() || !p.channelMask.has_value() ||
+ !p.format.has_value() || !p.flags.has_value(),
+ "%s: stored mix port config is not fully specified: %s",
+ __func__, p.toString().c_str());
+ return p.ext.getTag() == Tag::mix &&
+ isConfigEqualToPortConfig(config, p) &&
+ p.flags.value() == flags &&
+ p.ext.template get<Tag::mix>().handle == ioHandle; });
+}
+/*
+DeviceHalAidl::PortConfigs::iterator DeviceHalAidl::findPortConfig(
+ const AudioPortConfig& portConfig) {
+ using Tag = AudioPortExt::Tag;
+ if (portConfig.ext.getTag() == Tag::mix) {
+ return std::find_if(mPortConfigs.begin(), mPortConfigs.end(),
+ [&](const auto& pair) {
+ const auto& p = pair.second;
+ LOG_ALWAYS_FATAL_IF(p.ext.getTag() == Tag::mix &&
+ !p.sampleRate.has_value() || !p.channelMask.has_value() ||
+ !p.format.has_value() || !p.flags.has_value(),
+ "%s: stored mix port config is not fully specified: %s",
+ __func__, p.toString().c_str());
+ return p.ext.getTag() == Tag::mix &&
+ (!portConfig.sampleRate.has_value() ||
+ p.sampleRate == portConfig.sampleRate) &&
+ (!portConfig.channelMask.has_value() ||
+ p.channelMask == portConfig.channelMask) &&
+ (!portConfig.format.has_value() || p.format == portConfig.format) &&
+ (!portConfig.flags.has_value() || p.flags == portConfig.flags) &&
+ p.ext.template get<Tag::mix>().handle ==
+ portConfig.ext.template get<Tag::mix>().handle; });
+ } else if (portConfig.ext.getTag() == Tag::device) {
+ return findPortConfig(portConfig.ext.get<Tag::device>().device);
+ }
+ return mPortConfigs.end();
+}
+*/
+void DeviceHalAidl::resetPatch(int32_t patchId) {
+ if (auto it = mPatches.find(patchId); it != mPatches.end()) {
+ mPatches.erase(it);
+ TIME_CHECK();
+ if (ndk::ScopedAStatus status = mModule->resetAudioPatch(patchId); !status.isOk()) {
+ ALOGE("%s: error while resetting patch %d: %s",
+ __func__, patchId, status.getDescription().c_str());
+ }
+ return;
+ }
+ ALOGE("%s: patch id %d not found", __func__, patchId);
+}
+
+void DeviceHalAidl::resetPortConfig(int32_t portConfigId) {
+ if (auto it = mPortConfigs.find(portConfigId); it != mPortConfigs.end()) {
+ mPortConfigs.erase(it);
+ TIME_CHECK();
+ if (ndk::ScopedAStatus status = mModule->resetAudioPortConfig(portConfigId);
+ !status.isOk()) {
+ ALOGE("%s: error while resetting port config %d: %s",
+ __func__, portConfigId, status.getDescription().c_str());
+ }
+ return;
+ }
+ ALOGE("%s: port config id %d not found", __func__, portConfigId);
+}
+
} // namespace android
diff --git a/media/libaudiohal/impl/DeviceHalAidl.h b/media/libaudiohal/impl/DeviceHalAidl.h
index b1aa351..0662cf2 100644
--- a/media/libaudiohal/impl/DeviceHalAidl.h
+++ b/media/libaudiohal/impl/DeviceHalAidl.h
@@ -16,8 +16,12 @@
#pragma once
-#include <aidl/android/hardware/audio/core/sounddose/BpSoundDose.h>
+#include <map>
+#include <set>
+#include <vector>
+
#include <aidl/android/hardware/audio/core/BpModule.h>
+#include <aidl/android/hardware/audio/core/sounddose/BpSoundDose.h>
#include <media/audiohal/DeviceHalInterface.h>
#include <media/audiohal/EffectHalInterface.h>
@@ -123,17 +127,77 @@
private:
friend class sp<DeviceHalAidl>;
+ using Patches = std::map<int32_t /*patch ID*/,
+ ::aidl::android::hardware::audio::core::AudioPatch>;
+ using PortConfigs = std::map<int32_t /*port config ID*/,
+ ::aidl::android::media::audio::common::AudioPortConfig>;
+ using Ports = std::map<int32_t /*port ID*/, ::aidl::android::media::audio::common::AudioPort>;
+ class Cleanups;
+ // Must not be constructed directly by clients.
+ DeviceHalAidl(
+ const std::string& instance,
+ const std::shared_ptr<::aidl::android::hardware::audio::core::IModule>& module)
+ : ConversionHelperAidl("DeviceHalAidl"), mInstance(instance), mModule(module) {}
+
+ ~DeviceHalAidl() override = default;
+
+ status_t createPortConfig(
+ const ::aidl::android::media::audio::common::AudioPortConfig& requestedPortConfig,
+ ::aidl::android::media::audio::common::AudioPortConfig* appliedPortConfig);
+ status_t findOrCreatePatch(
+ const std::set<int32_t>& sourcePortConfigIds,
+ const std::set<int32_t>& sinkPortConfigIds,
+ ::aidl::android::hardware::audio::core::AudioPatch* patch, bool* created);
+ status_t findOrCreatePatch(
+ const ::aidl::android::hardware::audio::core::AudioPatch& requestedPatch,
+ ::aidl::android::hardware::audio::core::AudioPatch* patch, bool* created);
+ status_t findOrCreatePortConfig(
+ const ::aidl::android::media::audio::common::AudioDevice& device,
+ ::aidl::android::media::audio::common::AudioPortConfig* portConfig,
+ bool* created);
+ status_t findOrCreatePortConfig(
+ const ::aidl::android::media::audio::common::AudioConfig& config,
+ const ::aidl::android::media::audio::common::AudioIoFlags& flags,
+ int32_t ioHandle,
+ ::aidl::android::media::audio::common::AudioPortConfig* portConfig, bool* created);
+ status_t findOrCreatePortConfig(
+ const ::aidl::android::media::audio::common::AudioPortConfig& requestedPortConfig,
+ ::aidl::android::media::audio::common::AudioPortConfig* portConfig, bool* created);
+ Patches::iterator findPatch(const std::set<int32_t>& sourcePortConfigIds,
+ const std::set<int32_t>& sinkPortConfigIds);
+ Ports::iterator findPort(const ::aidl::android::media::audio::common::AudioDevice& device);
+ Ports::iterator findPort(
+ const ::aidl::android::media::audio::common::AudioConfig& config,
+ const ::aidl::android::media::audio::common::AudioIoFlags& flags);
+ PortConfigs::iterator findPortConfig(
+ const ::aidl::android::media::audio::common::AudioDevice& device);
+ PortConfigs::iterator findPortConfig(
+ const ::aidl::android::media::audio::common::AudioConfig& config,
+ const ::aidl::android::media::audio::common::AudioIoFlags& flags,
+ int32_t ioHandle);
+ // Currently unused but may be useful for implementing setAudioPortConfig
+ // PortConfigs::iterator findPortConfig(
+ // const ::aidl::android::media::audio::common::AudioPortConfig& portConfig);
+ status_t prepareToOpenStream(
+ int32_t aidlHandle,
+ const ::aidl::android::media::audio::common::AudioDevice& aidlDevice,
+ const ::aidl::android::media::audio::common::AudioIoFlags& aidlFlags,
+ struct audio_config* config,
+ Cleanups* cleanups,
+ ::aidl::android::media::audio::common::AudioConfig* aidlConfig,
+ ::aidl::android::media::audio::common::AudioPortConfig* mixPortConfig);
+ void resetPatch(int32_t patchId);
+ void resetPortConfig(int32_t portConfigId);
+
+ const std::string mInstance;
const std::shared_ptr<::aidl::android::hardware::audio::core::IModule> mModule;
std::shared_ptr<::aidl::android::hardware::audio::core::sounddose::ISoundDose>
mSoundDose = nullptr;
-
- // Can not be constructed directly by clients.
- explicit DeviceHalAidl(
- const std::shared_ptr<::aidl::android::hardware::audio::core::IModule>& module)
- : ConversionHelperAidl("DeviceHalAidl"), mModule(module) {}
-
- ~DeviceHalAidl() override = default;
+ Ports mPorts;
+ PortConfigs mPortConfigs;
+ Patches mPatches;
+ std::map<audio_patch_handle_t, int32_t /* patch ID */> mFwkHandles;
};
} // namespace android
diff --git a/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp b/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp
index 78d03e7..b452fa3 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp
+++ b/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp
@@ -57,7 +57,7 @@
}
// If the service is a nullptr, the device will not be really functional,
// but will not crash either.
- *device = sp<DeviceHalAidl>::make(service);
+ *device = sp<DeviceHalAidl>::make(name, service);
return OK;
}
diff --git a/media/libaudiohal/impl/EffectConversionHelperAidl.cpp b/media/libaudiohal/impl/EffectConversionHelperAidl.cpp
index ec8abd7..da89e20 100644
--- a/media/libaudiohal/impl/EffectConversionHelperAidl.cpp
+++ b/media/libaudiohal/impl/EffectConversionHelperAidl.cpp
@@ -21,21 +21,8 @@
//#define LOG_NDEBUG 0
#include <error/expected_utils.h>
-#include <media/audiohal/AudioEffectUuid.h>
-#include <system/audio_effects/effect_aec.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_environmentalreverb.h>
-#include <system/audio_effects/effect_equalizer.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_effects/effect_presetreverb.h>
-#include <system/audio_effects/effect_spatializer.h>
-#include <system/audio_effects/effect_virtualizer.h>
-#include <system/audio_effects/effect_visualizer.h>
+#include <media/AidlConversionNdk.h>
+#include <media/AidlConversionEffect.h>
#include <utils/Log.h>
@@ -45,15 +32,10 @@
namespace effect {
using ::aidl::android::aidl_utils::statusTFromBinderStatus;
-using ::aidl::android::hardware::audio::effect::AcousticEchoCanceler;
-using ::aidl::android::hardware::audio::effect::AutomaticGainControl;
-using ::aidl::android::hardware::audio::effect::BassBoost;
using ::aidl::android::hardware::audio::effect::CommandId;
using ::aidl::android::hardware::audio::effect::Descriptor;
-using ::aidl::android::hardware::audio::effect::Downmix;
using ::aidl::android::hardware::audio::effect::Parameter;
using ::aidl::android::media::audio::common::AudioDeviceDescription;
-using ::aidl::android::media::audio::common::AudioUuid;
using android::effect::utils::EffectParamReader;
using android::effect::utils::EffectParamWriter;
@@ -75,26 +57,9 @@
{EFFECT_CMD_OFFLOAD, &EffectConversionHelperAidl::handleSetOffload},
{EFFECT_CMD_FIRST_PROPRIETARY, &EffectConversionHelperAidl::handleFirstPriority}};
-const std::map<AudioUuid /* TypeUUID */, std::pair<EffectConversionHelperAidl::SetParameter,
- EffectConversionHelperAidl::GetParameter>>
- EffectConversionHelperAidl::mParameterHandlerMap = {
- {kAcousticEchoCancelerTypeUUID,
- {&EffectConversionHelperAidl::setAecParameter,
- &EffectConversionHelperAidl::getAecParameter}},
- {kAutomaticGainControlTypeUUID,
- {&EffectConversionHelperAidl::setAgcParameter,
- &EffectConversionHelperAidl::getAgcParameter}},
- {kBassBoostTypeUUID,
- {&EffectConversionHelperAidl::setBassBoostParameter,
- &EffectConversionHelperAidl::getBassBoostParameter}},
- {kDownmixTypeUUID,
- {&EffectConversionHelperAidl::setDownmixParameter,
- &EffectConversionHelperAidl::getDownmixParameter}}};
-
EffectConversionHelperAidl::EffectConversionHelperAidl(
std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> effect,
- int32_t sessionId, int32_t ioId,
- const ::aidl::android::hardware::audio::effect::Descriptor& desc)
+ int32_t sessionId, int32_t ioId, const Descriptor& desc)
: mSessionId(sessionId), mIoId(ioId), mDesc(desc), mEffect(std::move(effect)) {
mCommon.session = sessionId;
mCommon.ioHandle = ioId;
@@ -136,14 +101,7 @@
return BAD_VALUE;
}
- const auto& handler = mParameterHandlerMap.find(mDesc.common.id.type);
- if (handler == mParameterHandlerMap.end() || !handler->second.first) {
- ALOGE("%s handler for uuid %s not found", __func__,
- mDesc.common.id.type.toString().c_str());
- return BAD_VALUE;
- }
- const SetParameter& functor = handler->second.first;
- return *(status_t*)pReplyData = (this->*functor)(reader);
+ return *(status_t*)pReplyData = setParameter(reader);
}
status_t EffectConversionHelperAidl::handleGetParameter(uint32_t cmdSize, const void* pCmdData,
@@ -153,24 +111,20 @@
}
const auto reader = EffectParamReader(*(effect_param_t*)pCmdData);
- if (!reader.validateCmdSize(cmdSize)) {
- ALOGE("%s illegal param %s, replysize %u", __func__, reader.toString().c_str(),
+ if (!reader.validateCmdSize(cmdSize) ||
+ *replySize < sizeof(effect_param_t) + reader.getParameterSize()) {
+ ALOGE("%s illegal param %s, replySize %u", __func__, reader.toString().c_str(),
*replySize);
return BAD_VALUE;
}
- const auto& handler = mParameterHandlerMap.find(mDesc.common.id.type);
- if (handler == mParameterHandlerMap.end() || !handler->second.second) {
- ALOGE("%s handler for uuid %s not found", __func__,
- mDesc.common.id.type.toString().c_str());
- return BAD_VALUE;
- }
- const GetParameter& functor = handler->second.second;
+ // copy effect_param_t and parameters
memcpy(pReplyData, pCmdData, sizeof(effect_param_t) + reader.getParameterSize());
- auto writer = EffectParamWriter(*(effect_param_t *)pReplyData);
- (this->*functor)(writer);
+ auto writer = EffectParamWriter(*(effect_param_t*)pReplyData);
+ status_t ret = getParameter(writer);
+ writer.finishValueWrite();
*replySize = writer.getTotalSize();
- return writer.getStatus();
+ return ret;
}
status_t EffectConversionHelperAidl::handleSetConfig(uint32_t cmdSize, const void* pCmdData,
@@ -182,17 +136,19 @@
const auto& legacyConfig = static_cast<const effect_config_t*>(pCmdData);
// already open, apply latest settings
- mCommon.input.base =
+ Parameter::Common common;
+ common.input.base =
VALUE_OR_RETURN_STATUS(::aidl::android::legacy2aidl_buffer_config_t_AudioConfigBase(
legacyConfig->inputCfg, true /* isInput */));
- mCommon.output.base =
+ common.output.base =
VALUE_OR_RETURN_STATUS(::aidl::android::legacy2aidl_buffer_config_t_AudioConfigBase(
legacyConfig->outputCfg, false /* isInput */));
- mCommon.session = mSessionId;
- mCommon.ioHandle = mIoId;
+ common.session = mSessionId;
+ common.ioHandle = mIoId;
// TODO: add access mode support
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
- mEffect->setParameter(Parameter::make<Parameter::common>(mCommon))));
+ mEffect->setParameter(Parameter::make<Parameter::common>(common))));
+ mCommon = common;
return *static_cast<int32_t*>(pReplyData) = OK;
}
@@ -215,6 +171,7 @@
pConfig->outputCfg =
VALUE_OR_RETURN_STATUS(::aidl::android::aidl2legacy_AudioConfigBase_buffer_config_t(
common.output.base, false));
+ mCommon = common;
return OK;
}
@@ -306,262 +263,5 @@
return OK;
}
-status_t EffectConversionHelperAidl::setAecParameter(EffectParamReader& param) {
- uint32_t type, value = 0;
- if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint32_t)) ||
- OK != param.readFromParameter(&type) ||
- OK != param.readFromValue(&value)) {
- ALOGW("%s invalid param %s", __func__, param.toString().c_str());
- return BAD_VALUE;
- }
-
- Parameter aidlParam;
- switch (type) {
- case AEC_PARAM_ECHO_DELAY:
- FALLTHROUGH_INTENDED;
- case AEC_PARAM_PROPERTIES: {
- aidlParam = VALUE_OR_RETURN_STATUS(
- aidl::android::legacy2aidl_uint32_echoDelay_Parameter_aec(value));
- break;
- }
- case AEC_PARAM_MOBILE_MODE: {
- aidlParam = VALUE_OR_RETURN_STATUS(
- aidl::android::legacy2aidl_uint32_mobileMode_Parameter_aec(value));
- break;
- }
- default: {
- ALOGW("%s unknown param %s", __func__, param.toString().c_str());
- return BAD_VALUE;
- }
- }
-
- return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
-}
-
-status_t EffectConversionHelperAidl::getAecParameter(EffectParamWriter& param) {
- uint32_t type = 0, value = 0;
- if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint32_t)) ||
- OK != param.readFromParameter(&type) || OK != param.readFromValue(&value)) {
- param.setStatus(BAD_VALUE);
- ALOGW("%s invalid param %s", __func__, param.toString().c_str());
- return BAD_VALUE;
- }
- Parameter aidlParam;
- switch (type) {
- case AEC_PARAM_ECHO_DELAY:
- FALLTHROUGH_INTENDED;
- case AEC_PARAM_PROPERTIES: {
- Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(AcousticEchoCanceler,
- acousticEchoCancelerTag, echoDelayUs);
- RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
- value = VALUE_OR_RETURN_STATUS(
- aidl::android::aidl2legacy_Parameter_aec_uint32_echoDelay(aidlParam));
- break;
- }
- case AEC_PARAM_MOBILE_MODE: {
- Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(AcousticEchoCanceler,
- acousticEchoCancelerTag, mobileMode);
- RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
- value = VALUE_OR_RETURN_STATUS(
- aidl::android::aidl2legacy_Parameter_aec_uint32_mobileMode(aidlParam));
- break;
- }
- default:
- ALOGW("%s unknown param %s", __func__, param.toString().c_str());
- return BAD_VALUE;
- }
- param.writeToValue(&value);
- return OK;
-}
-
-status_t EffectConversionHelperAidl::setAgcParameter(EffectParamReader& param) {
- uint32_t type = 0, value = 0;
- if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint32_t)) ||
- OK != param.readFromParameter(&type) || OK != param.readFromValue(&value)) {
- ALOGW("%s invalid param %s", __func__, param.toString().c_str());
- return BAD_VALUE;
- }
- Parameter aidlParam;
- switch (type) {
- case AGC2_PARAM_FIXED_DIGITAL_GAIN: {
- aidlParam = VALUE_OR_RETURN_STATUS(
- aidl::android::legacy2aidl_uint32_fixedDigitalGain_Parameter_agc(value));
- break;
- }
- case AGC2_PARAM_ADAPT_DIGI_LEVEL_ESTIMATOR: {
- aidlParam = VALUE_OR_RETURN_STATUS(
- aidl::android::legacy2aidl_uint32_levelEstimator_Parameter_agc(value));
- break;
- }
- case AGC2_PARAM_ADAPT_DIGI_EXTRA_SATURATION_MARGIN: {
- aidlParam = VALUE_OR_RETURN_STATUS(
- aidl::android::legacy2aidl_uint32_saturationMargin_Parameter_agc(value));
- break;
- }
- default: {
- ALOGW("%s unknown param %s", __func__, param.toString().c_str());
- return BAD_VALUE;
- }
- }
-
- return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
-}
-
-status_t EffectConversionHelperAidl::getAgcParameter(EffectParamWriter& param) {
- uint32_t type = 0, value = 0;
- if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint32_t)) ||
- OK != param.readFromParameter(&type) || OK != param.readFromValue(&value)) {
- ALOGW("%s invalid param %s", __func__, param.toString().c_str());
- return BAD_VALUE;
- }
- Parameter aidlParam;
- switch (type) {
- case AGC2_PARAM_FIXED_DIGITAL_GAIN: {
- Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(
- AutomaticGainControl, automaticGainControlTag, fixedDigitalGainMb);
- RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
- value = VALUE_OR_RETURN_STATUS(
- aidl::android::aidl2legacy_Parameter_agc_uint32_fixedDigitalGain(aidlParam));
- break;
- }
- case AGC2_PARAM_ADAPT_DIGI_LEVEL_ESTIMATOR: {
- Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(AutomaticGainControl,
- automaticGainControlTag, levelEstimator);
- RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
- value = VALUE_OR_RETURN_STATUS(
- aidl::android::aidl2legacy_Parameter_agc_uint32_levelEstimator(aidlParam));
- break;
- }
- case AGC2_PARAM_ADAPT_DIGI_EXTRA_SATURATION_MARGIN: {
- Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(
- AutomaticGainControl, automaticGainControlTag, 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;
- }
- }
-
- param.writeToValue(&value);
- return OK;
-}
-
-status_t EffectConversionHelperAidl::setBassBoostParameter(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)) {
- ALOGW("%s invalid param %s", __func__, param.toString().c_str());
- return BAD_VALUE;
- }
- Parameter aidlParam;
- switch (type) {
- case BASSBOOST_PARAM_STRENGTH: {
- aidlParam = VALUE_OR_RETURN_STATUS(
- aidl::android::legacy2aidl_uint16_strengthPm_Parameter_BassBoost(value));
- break;
- }
- case BASSBOOST_PARAM_STRENGTH_SUPPORTED: {
- ALOGW("%s set BASSBOOST_PARAM_STRENGTH_SUPPORTED not supported", __func__);
- return BAD_VALUE;
- }
- default: {
- ALOGW("%s unknown param %s", __func__, param.toString().c_str());
- return BAD_VALUE;
- }
- }
-
- return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
-}
-
-status_t EffectConversionHelperAidl::getBassBoostParameter(EffectParamWriter& param) {
- uint32_t type = 0, value = 0;
- if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint32_t)) ||
- OK != param.readFromParameter(&type) || OK != param.readFromValue(&value)) {
- ALOGW("%s invalid param %s", __func__, param.toString().c_str());
- param.setStatus(BAD_VALUE);
- return BAD_VALUE;
- }
- Parameter aidlParam;
- switch (type) {
- case BASSBOOST_PARAM_STRENGTH: {
- Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(BassBoost, bassBoostTag, strengthPm);
- RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
- value = VALUE_OR_RETURN_STATUS(
- aidl::android::aidl2legacy_Parameter_BassBoost_uint16_strengthPm(aidlParam));
- break;
- }
- case BASSBOOST_PARAM_STRENGTH_SUPPORTED: {
- const auto& cap =
- VALUE_OR_RETURN_STATUS(aidl::android::UNION_GET(mDesc.capability, bassBoost));
- value = VALUE_OR_RETURN_STATUS(
- aidl::android::convertIntegral<uint32_t>(cap.strengthSupported));
- break;
- }
- default: {
- ALOGW("%s unknown param %s", __func__, param.toString().c_str());
- return BAD_VALUE;
- }
- }
-
- param.writeToValue(&value);
- return OK;
-}
-
-status_t EffectConversionHelperAidl::setDownmixParameter(EffectParamReader& param) {
- uint32_t type = 0;
- int16_t value = 0;
- if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(int16_t)) ||
- OK != param.readFromParameter(&type) || OK != param.readFromValue(&value)) {
- ALOGW("%s invalid param %s", __func__, param.toString().c_str());
- return BAD_VALUE;
- }
- Parameter aidlParam;
- switch (type) {
- case DOWNMIX_PARAM_TYPE: {
- aidlParam = VALUE_OR_RETURN_STATUS(
- aidl::android::legacy2aidl_int16_type_Parameter_Downmix(value));
- break;
- }
- default: {
- ALOGW("%s unknown param %s", __func__, param.toString().c_str());
- return BAD_VALUE;
- }
- }
-
- return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
-}
-
-status_t EffectConversionHelperAidl::getDownmixParameter(EffectParamWriter& param) {
- int16_t value = 0;
- uint32_t type = 0;
- if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint16_t)) ||
- OK != param.readFromParameter(&type) || OK != param.readFromValue(&value)) {
- param.setStatus(BAD_VALUE);
- return BAD_VALUE;
- }
- Parameter aidlParam;
- switch (type) {
- case DOWNMIX_PARAM_TYPE: {
- Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(Downmix, downmixTag, type);
- RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
- value = VALUE_OR_RETURN_STATUS(
- aidl::android::aidl2legacy_Parameter_Downmix_int16_type(aidlParam));
- break;
- }
- default: {
- ALOGW("%s unknown param %s", __func__, param.toString().c_str());
- return BAD_VALUE;
- }
- }
-
- param.writeToValue(&value);
- return OK;
-}
-
-} // namespace effect
-} // namespace android
+} // namespace effect
+} // namespace android
diff --git a/media/libaudiohal/impl/EffectConversionHelperAidl.h b/media/libaudiohal/impl/EffectConversionHelperAidl.h
index 35249f5..490a1dc 100644
--- a/media/libaudiohal/impl/EffectConversionHelperAidl.h
+++ b/media/libaudiohal/impl/EffectConversionHelperAidl.h
@@ -16,14 +16,9 @@
#pragma once
-#include <cstddef>
-#include <map>
-#include <memory>
#include <utils/Errors.h>
-#include <aidl/android/hardware/audio/effect/IEffect.h>
-
-#include <media/AidlConversionNdk.h>
+#include <aidl/android/hardware/audio/effect/BpEffect.h>
#include <system/audio_effect.h>
#include <system/audio_effects/audio_effects_utils.h>
@@ -31,24 +26,30 @@
namespace effect {
class EffectConversionHelperAidl {
+ public:
+ status_t handleCommand(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData, uint32_t* replySize,
+ void* pReplyData);
+ virtual ~EffectConversionHelperAidl() {}
+
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;
+ ::aidl::android::hardware::audio::effect::IEffect::OpenEffectReturn mOpenReturn;
+ ::aidl::android::hardware::audio::effect::Parameter::Common mCommon;
+
EffectConversionHelperAidl(
std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> effect,
int32_t sessionId, int32_t ioId,
const ::aidl::android::hardware::audio::effect::Descriptor& desc);
- status_t handleCommand(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData, uint32_t* replySize,
- void* pReplyData);
+ status_t handleSetParameter(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
+ void* pReplyData);
+ status_t handleGetParameter(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
+ void* pReplyData);
private:
- const int32_t mSessionId;
- const int32_t mIoId;
- const ::aidl::android::hardware::audio::effect::Descriptor mDesc;
- ::aidl::android::media::audio::common::AudioUuid mTypeUuid;
- const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> mEffect;
- ::aidl::android::hardware::audio::effect::IEffect::OpenEffectReturn mOpenReturn;
- ::aidl::android::hardware::audio::effect::Parameter::Common mCommon;
-
const aidl::android::media::audio::common::AudioFormatDescription kDefaultFormatDescription = {
.type = aidl::android::media::audio::common::AudioFormatType::PCM,
.pcm = aidl::android::media::audio::common::PcmType::FLOAT_32_BIT};
@@ -69,21 +70,8 @@
void* /* pReplyData */);
static const std::map<uint32_t /* effect_command_e */, CommandHandler> mCommandHandlerMap;
- // parameter set/get handler map
- typedef status_t (EffectConversionHelperAidl::*SetParameter)(
- android::effect::utils::EffectParamReader& param);
- typedef status_t (EffectConversionHelperAidl::*GetParameter)(
- android::effect::utils::EffectParamWriter& param);
- static const std::map<::aidl::android::media::audio::common::AudioUuid /* TypeUUID */,
- std::pair<SetParameter, GetParameter>>
- mParameterHandlerMap;
-
status_t handleInit(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
void* pReplyData);
- status_t handleSetParameter(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
- void* pReplyData);
- status_t handleGetParameter(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
- void* pReplyData);
status_t handleSetConfig(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
void* pReplyData);
status_t handleGetConfig(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
@@ -103,15 +91,9 @@
status_t handleFirstPriority(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
void* pReplyData);
- // set/get parameter handler
- status_t setAecParameter(android::effect::utils::EffectParamReader& param);
- status_t getAecParameter(android::effect::utils::EffectParamWriter& param);
- status_t setAgcParameter(android::effect::utils::EffectParamReader& param);
- status_t getAgcParameter(android::effect::utils::EffectParamWriter& param);
- status_t setBassBoostParameter(android::effect::utils::EffectParamReader& param);
- status_t getBassBoostParameter(android::effect::utils::EffectParamWriter& param);
- status_t setDownmixParameter(android::effect::utils::EffectParamReader& param);
- status_t getDownmixParameter(android::effect::utils::EffectParamWriter& param);
+ // implemented by conversion of each effect
+ virtual status_t setParameter(utils::EffectParamReader& param) = 0;
+ virtual status_t getParameter(utils::EffectParamWriter& param) = 0;
};
} // namespace effect
diff --git a/media/libaudiohal/impl/EffectHalAidl.cpp b/media/libaudiohal/impl/EffectHalAidl.cpp
index 0c37552..08040f3 100644
--- a/media/libaudiohal/impl/EffectHalAidl.cpp
+++ b/media/libaudiohal/impl/EffectHalAidl.cpp
@@ -14,13 +14,15 @@
* limitations under the License.
*/
+#include <memory>
#define LOG_TAG "EffectHalAidl"
//#define LOG_NDEBUG 0
#include <error/expected_utils.h>
#include <media/AidlConversionCppNdk.h>
-#include <media/AidlConversionNdk.h>
+#include <media/AidlConversionEffect.h>
#include <media/AidlConversionUtil.h>
+#include <media/audiohal/AudioEffectUuid.h>
#include <media/EffectsFactoryApi.h>
#include <mediautils/TimeCheck.h>
#include <utils/Log.h>
@@ -38,6 +40,12 @@
#include <system/audio.h>
#include <aidl/android/hardware/audio/effect/IEffect.h>
+#include "effectsAidlConversion/AidlConversionAec.h"
+#include "effectsAidlConversion/AidlConversionAgc2.h"
+#include "effectsAidlConversion/AidlConversionBassBoost.h"
+#include "effectsAidlConversion/AidlConversionDownmix.h"
+#include "effectsAidlConversion/AidlConversionDynamicsProcessing.h"
+
using ::aidl::android::aidl_utils::statusTFromBinderStatus;
using ::aidl::android::hardware::audio::effect::CommandId;
using ::aidl::android::hardware::audio::effect::Descriptor;
@@ -53,13 +61,14 @@
const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& effect,
uint64_t effectId, int32_t sessionId, int32_t ioId,
const ::aidl::android::hardware::audio::effect::Descriptor& desc)
- : EffectConversionHelperAidl(effect, sessionId, ioId, desc),
- mFactory(factory),
+ : mFactory(factory),
mEffect(effect),
mEffectId(effectId),
mSessionId(sessionId),
mIoId(ioId),
- mDesc(desc) {}
+ mDesc(desc) {
+ createAidlConversion(effect, sessionId, ioId, desc);
+}
EffectHalAidl::~EffectHalAidl() {
if (mFactory) {
@@ -67,6 +76,34 @@
}
}
+status_t EffectHalAidl::createAidlConversion(
+ std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> effect,
+ int32_t sessionId, int32_t ioId,
+ const ::aidl::android::hardware::audio::effect::Descriptor& desc) {
+ const auto& typeUuid = desc.common.id.type;
+ if (typeUuid == kAcousticEchoCancelerTypeUUID) {
+ mConversion =
+ std::make_unique<android::effect::AidlConversionAec>(effect, sessionId, ioId, desc);
+ } else if (typeUuid == kAutomaticGainControlTypeUUID) {
+ mConversion = std::make_unique<android::effect::AidlConversionAgc2>(effect, sessionId, ioId,
+ desc);
+ } else if (typeUuid == kBassBoostTypeUUID) {
+ mConversion = std::make_unique<android::effect::AidlConversionBassBoost>(effect, sessionId,
+ ioId, desc);
+ } else if (typeUuid == kDownmixTypeUUID) {
+ mConversion = std::make_unique<android::effect::AidlConversionDownmix>(effect, sessionId,
+ ioId, desc);
+ } else if (typeUuid == kDynamicsProcessingTypeUUID) {
+ mConversion =
+ std::make_unique<android::effect::AidlConversionDp>(effect, sessionId, ioId, desc);
+ } else {
+ ALOGE("%s effect not implemented yet, UUID type: %s", __func__,
+ typeUuid.toString().c_str());
+ return BAD_VALUE;
+ }
+ return OK;
+}
+
status_t EffectHalAidl::setInBuffer(const sp<EffectBufferHalInterface>& buffer) {
if (buffer == nullptr) {
return BAD_VALUE;
@@ -97,7 +134,9 @@
status_t EffectHalAidl::command(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData,
uint32_t* replySize, void* pReplyData) {
- return handleCommand(cmdCode, cmdSize, pCmdData, replySize, pReplyData);
+ return mConversion
+ ? mConversion->handleCommand(cmdCode, cmdSize, pCmdData, replySize, pReplyData)
+ : INVALID_OPERATION;
}
status_t EffectHalAidl::getDescriptor(effect_descriptor_t* pDescriptor) {
diff --git a/media/libaudiohal/impl/EffectHalAidl.h b/media/libaudiohal/impl/EffectHalAidl.h
index 6a1ec1c..83b644b 100644
--- a/media/libaudiohal/impl/EffectHalAidl.h
+++ b/media/libaudiohal/impl/EffectHalAidl.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * 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.
@@ -20,13 +20,14 @@
#include <aidl/android/hardware/audio/effect/IFactory.h>
#include <media/audiohal/EffectHalInterface.h>
#include <system/audio_effect.h>
+#include <memory>
#include "EffectConversionHelperAidl.h"
namespace android {
namespace effect {
-class EffectHalAidl : public EffectHalInterface, public EffectConversionHelperAidl {
+class EffectHalAidl : public EffectHalInterface {
public:
// Set the input buffer.
status_t setInBuffer(const sp<EffectBufferHalInterface>& buffer) override;
@@ -71,10 +72,15 @@
const int32_t mSessionId;
const int32_t mIoId;
const ::aidl::android::hardware::audio::effect::Descriptor mDesc;
+ std::unique_ptr<EffectConversionHelperAidl> mConversion;
sp<EffectBufferHalInterface> mInBuffer, mOutBuffer;
effect_config_t mConfig;
+ status_t createAidlConversion(
+ std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> effect,
+ int32_t sessionId, int32_t ioId,
+ const ::aidl::android::hardware::audio::effect::Descriptor& desc);
// Can not be constructed directly by clients.
EffectHalAidl(
const std::shared_ptr<::aidl::android::hardware::audio::effect::IFactory>& factory,
diff --git a/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp b/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
index 878c19e..0aae87b 100644
--- a/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
+++ b/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
@@ -24,7 +24,7 @@
#include <error/expected_utils.h>
#include <android/binder_manager.h>
#include <media/AidlConversionCppNdk.h>
-#include <media/AidlConversionNdk.h>
+#include <media/AidlConversionEffect.h>
#include <system/audio.h>
#include <utils/Log.h>
diff --git a/media/libaudiohal/impl/StreamHalAidl.cpp b/media/libaudiohal/impl/StreamHalAidl.cpp
index 1c6a014..2b7856b 100644
--- a/media/libaudiohal/impl/StreamHalAidl.cpp
+++ b/media/libaudiohal/impl/StreamHalAidl.cpp
@@ -46,10 +46,11 @@
}
StreamHalAidl::StreamHalAidl(
- std::string_view className, bool isInput, const StreamDescriptor& descriptor,
- const std::shared_ptr<IStreamCommon>& stream)
+ std::string_view className, bool isInput, const audio_config& config,
+ const StreamDescriptor& descriptor, const std::shared_ptr<IStreamCommon>& stream)
: ConversionHelperAidl(className),
mIsInput(isInput),
+ mConfig(configToBase(config)),
mFrameSizeBytes(descriptor.frameSizeBytes),
mBufferSizeFrames(descriptor.bufferSizeFrames),
mCommandMQ(new CommandMQ(descriptor.command)),
@@ -76,7 +77,7 @@
if (size == nullptr) {
return BAD_VALUE;
}
- if (mFrameSizeBytes == 0 || mBufferSizeFrames == 0) {
+ if (mFrameSizeBytes == 0 || mBufferSizeFrames == 0 || !mStream) {
return NO_INIT;
}
*size = mFrameSizeBytes * mBufferSizeFrames;
@@ -87,13 +88,8 @@
if (configBase == nullptr) {
return BAD_VALUE;
}
- TIME_CHECK();
- *configBase = AUDIO_CONFIG_BASE_INITIALIZER;
- configBase->sample_rate = 48000;
- configBase->format = AUDIO_FORMAT_PCM_24_BIT_PACKED;
- configBase->channel_mask = mIsInput ? AUDIO_CHANNEL_IN_STEREO : AUDIO_CHANNEL_OUT_STEREO;
- // if (!mStream) return NO_INIT;
- ALOGE("%s not implemented yet", __func__);
+ if (!mStream) return NO_INIT;
+ *configBase = mConfig;
return OK;
}
@@ -116,7 +112,7 @@
if (size == nullptr) {
return BAD_VALUE;
}
- if (mFrameSizeBytes == 0) {
+ if (mFrameSizeBytes == 0 || !mStream) {
return NO_INIT;
}
*size = mFrameSizeBytes;
@@ -140,6 +136,9 @@
status_t StreamHalAidl::standby() {
TIME_CHECK();
if (!mStream) return NO_INIT;
+ if (mState == StreamDescriptor::State::STANDBY) {
+ return OK;
+ }
ALOGE("%s not implemented yet", __func__);
return OK;
}
@@ -180,7 +179,7 @@
}
status_t StreamHalAidl::setHalThreadPriority(int priority __unused) {
- mHalThreadPriority = priority;
+ // Obsolete, must be done by the HAL module.
return OK;
}
@@ -192,12 +191,8 @@
}
bool StreamHalAidl::requestHalThreadPriority(pid_t threadPid __unused, pid_t threadId __unused) {
- if (mHalThreadPriority == HAL_THREAD_PRIORITY_DEFAULT) {
- return true;
- }
- if (!mStream) return NO_INIT;
- ALOGE("%s not implemented yet", __func__);
- return OK;
+ // Obsolete, must be done by the HAL module.
+ return true;
}
status_t StreamHalAidl::legacyCreateAudioPatch(const struct audio_port_config& port __unused,
@@ -244,8 +239,10 @@
} // namespace
StreamOutHalAidl::StreamOutHalAidl(
+ const audio_config& config,
const StreamDescriptor& descriptor, const std::shared_ptr<IStreamOut>& stream)
- : StreamHalAidl("StreamOutHalAidl", false /*isInput*/, descriptor, getStreamCommon(stream)),
+ : StreamHalAidl("StreamOutHalAidl", false /*isInput*/, config,
+ descriptor, getStreamCommon(stream)),
mStream(stream) {}
status_t StreamOutHalAidl::getLatency(uint32_t *latency) {
@@ -360,34 +357,55 @@
}
status_t StreamOutHalAidl::getDualMonoMode(audio_dual_mono_mode_t* mode __unused) {
- return INVALID_OPERATION;
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
}
status_t StreamOutHalAidl::setDualMonoMode(audio_dual_mono_mode_t mode __unused) {
- return INVALID_OPERATION;
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
}
status_t StreamOutHalAidl::getAudioDescriptionMixLevel(float* leveldB __unused) {
- return INVALID_OPERATION;
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
}
status_t StreamOutHalAidl::setAudioDescriptionMixLevel(float leveldB __unused) {
- return INVALID_OPERATION;
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
}
status_t StreamOutHalAidl::getPlaybackRateParameters(
audio_playback_rate_t* playbackRate __unused) {
- return INVALID_OPERATION;
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
}
status_t StreamOutHalAidl::setPlaybackRateParameters(
const audio_playback_rate_t& playbackRate __unused) {
- return INVALID_OPERATION;
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
}
status_t StreamOutHalAidl::setEventCallback(
const sp<StreamOutHalInterfaceEventCallback>& callback __unused) {
- return INVALID_OPERATION;
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
}
namespace {
@@ -401,17 +419,26 @@
} // namespace
status_t StreamOutHalAidl::setLatencyMode(audio_latency_mode_t mode __unused) {
- return INVALID_OPERATION;
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
};
status_t StreamOutHalAidl::getRecommendedLatencyModes(
std::vector<audio_latency_mode_t> *modes __unused) {
- return INVALID_OPERATION;
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
};
status_t StreamOutHalAidl::setLatencyModeCallback(
const sp<StreamOutHalInterfaceLatencyModeCallback>& callback __unused) {
- return INVALID_OPERATION;
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
};
void StreamOutHalAidl::onWriteReady() {
@@ -458,8 +485,10 @@
}
StreamInHalAidl::StreamInHalAidl(
+ const audio_config& config,
const StreamDescriptor& descriptor, const std::shared_ptr<IStreamIn>& stream)
- : StreamHalAidl("StreamInHalAidl", true /*isInput*/, descriptor, getStreamCommon(stream)),
+ : StreamHalAidl("StreamInHalAidl", true /*isInput*/, config,
+ descriptor, getStreamCommon(stream)),
mStream(stream) {}
status_t StreamInHalAidl::setGain(float gain __unused) {
@@ -494,24 +523,33 @@
status_t StreamInHalAidl::getActiveMicrophones(
std::vector<media::MicrophoneInfo> *microphones __unused) {
- if (mStream == 0) return NO_INIT;
- return INVALID_OPERATION;
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
}
status_t StreamInHalAidl::updateSinkMetadata(
const StreamInHalInterface::SinkMetadata& sinkMetadata __unused) {
- return INVALID_OPERATION;
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
}
status_t StreamInHalAidl::setPreferredMicrophoneDirection(
audio_microphone_direction_t direction __unused) {
- if (mStream == 0) return NO_INIT;
- return INVALID_OPERATION;
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
}
status_t StreamInHalAidl::setPreferredMicrophoneFieldDimension(float zoom __unused) {
- if (mStream == 0) return NO_INIT;
- return INVALID_OPERATION;
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
}
} // namespace android
diff --git a/media/libaudiohal/impl/StreamHalAidl.h b/media/libaudiohal/impl/StreamHalAidl.h
index c56d5e3..e55c413 100644
--- a/media/libaudiohal/impl/StreamHalAidl.h
+++ b/media/libaudiohal/impl/StreamHalAidl.h
@@ -101,6 +101,7 @@
// Subclasses can not be constructed directly by clients.
StreamHalAidl(std::string_view className,
bool isInput,
+ const audio_config& config,
const ::aidl::android::hardware::audio::core::StreamDescriptor& descriptor,
const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamCommon>& stream);
@@ -111,6 +112,7 @@
bool requestHalThreadPriority(pid_t threadPid, pid_t threadId);
const bool mIsInput;
+ const audio_config_base_t mConfig;
const size_t mFrameSizeBytes;
const size_t mBufferSizeFrames;
const std::unique_ptr<CommandMQ> mCommandMQ;
@@ -118,8 +120,17 @@
const std::unique_ptr<DataMQ> mDataMQ;
// mStreamPowerLog is used for audio signal power logging.
StreamPowerLog mStreamPowerLog;
+ ::aidl::android::hardware::audio::core::StreamDescriptor::State mState =
+ ::aidl::android::hardware::audio::core::StreamDescriptor::State::STANDBY;
private:
+ static audio_config_base_t configToBase(const audio_config& config) {
+ audio_config_base_t result = AUDIO_CONFIG_BASE_INITIALIZER;
+ result.sample_rate = config.sample_rate;
+ result.channel_mask = config.channel_mask;
+ result.format = config.format;
+ return result;
+ }
static std::unique_ptr<DataMQ> maybeCreateDataMQ(
const ::aidl::android::hardware::audio::core::StreamDescriptor& descriptor) {
using Tag = ::aidl::android::hardware::audio::core::StreamDescriptor::AudioBuffer::Tag;
@@ -129,9 +140,7 @@
return nullptr;
}
- const int HAL_THREAD_PRIORITY_DEFAULT = -1;
const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamCommon> mStream;
- int mHalThreadPriority = HAL_THREAD_PRIORITY_DEFAULT;
};
class StreamOutHalAidl : public StreamOutHalInterface, public StreamHalAidl {
@@ -230,6 +239,7 @@
// Can not be constructed directly by clients.
StreamOutHalAidl(
+ const audio_config& config,
const ::aidl::android::hardware::audio::core::StreamDescriptor& descriptor,
const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamOut>& stream);
@@ -271,6 +281,7 @@
// Can not be constructed directly by clients.
StreamInHalAidl(
+ const audio_config& config,
const ::aidl::android::hardware::audio::core::StreamDescriptor& descriptor,
const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamIn>& stream);
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAec.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAec.cpp
new file mode 100644
index 0000000..901566e
--- /dev/null
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAec.cpp
@@ -0,0 +1,113 @@
+/*
+ * 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 "AidlConversionAec"
+//#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_aec.h>
+
+#include <utils/Log.h>
+
+#include "AidlConversionAec.h"
+
+namespace android {
+namespace effect {
+
+using ::aidl::android::aidl_utils::statusTFromBinderStatus;
+using ::aidl::android::hardware::audio::effect::AcousticEchoCanceler;
+using ::aidl::android::hardware::audio::effect::Parameter;
+using ::android::status_t;
+using utils::EffectParamReader;
+using utils::EffectParamWriter;
+
+status_t AidlConversionAec::setParameter(EffectParamReader& param) {
+ uint32_t type, 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;
+ switch (type) {
+ case AEC_PARAM_ECHO_DELAY:
+ FALLTHROUGH_INTENDED;
+ case AEC_PARAM_PROPERTIES: {
+ aidlParam = VALUE_OR_RETURN_STATUS(
+ aidl::android::legacy2aidl_uint32_echoDelay_Parameter_aec(value));
+ break;
+ }
+ case AEC_PARAM_MOBILE_MODE: {
+ aidlParam = VALUE_OR_RETURN_STATUS(
+ aidl::android::legacy2aidl_uint32_mobileMode_Parameter_aec(value));
+ break;
+ }
+ default: {
+ ALOGW("%s unknown param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ }
+
+ return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
+}
+
+status_t AidlConversionAec::getParameter(EffectParamWriter& param) {
+ uint32_t type = 0, value = 0;
+ if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint32_t)) ||
+ 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 AEC_PARAM_ECHO_DELAY:
+ FALLTHROUGH_INTENDED;
+ case AEC_PARAM_PROPERTIES: {
+ 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(
+ aidl::android::aidl2legacy_Parameter_aec_uint32_echoDelay(aidlParam));
+ break;
+ }
+ case AEC_PARAM_MOBILE_MODE: {
+ 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(
+ aidl::android::aidl2legacy_Parameter_aec_uint32_mobileMode(aidlParam));
+ break;
+ }
+ default:
+ ALOGW("%s unknown param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ return param.writeToValue(&value);
+}
+
+} // namespace effect
+} // namespace android
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAec.h b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAec.h
new file mode 100644
index 0000000..3ee419a
--- /dev/null
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAec.h
@@ -0,0 +1,39 @@
+/*
+ * 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 AidlConversionAec : public EffectConversionHelperAidl {
+ public:
+ AidlConversionAec(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) {}
+ ~AidlConversionAec() {}
+
+ private:
+ status_t setParameter(utils::EffectParamReader& param) override;
+ 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
new file mode 100644
index 0000000..80df2b8
--- /dev/null
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAgc2.cpp
@@ -0,0 +1,122 @@
+/*
+ * 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 "AidlConversionAgc2"
+//#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_agc2.h>
+
+#include <utils/Log.h>
+
+#include "AidlConversionAgc2.h"
+
+namespace android {
+namespace effect {
+
+using ::aidl::android::aidl_utils::statusTFromBinderStatus;
+using ::aidl::android::hardware::audio::effect::AutomaticGainControl;
+using ::aidl::android::hardware::audio::effect::Parameter;
+using ::android::status_t;
+using utils::EffectParamReader;
+using utils::EffectParamWriter;
+
+status_t AidlConversionAgc2::setParameter(EffectParamReader& param) {
+ 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;
+ switch (type) {
+ case AGC2_PARAM_FIXED_DIGITAL_GAIN: {
+ aidlParam = VALUE_OR_RETURN_STATUS(
+ aidl::android::legacy2aidl_uint32_fixedDigitalGain_Parameter_agc(value));
+ break;
+ }
+ case AGC2_PARAM_ADAPT_DIGI_LEVEL_ESTIMATOR: {
+ aidlParam = VALUE_OR_RETURN_STATUS(
+ aidl::android::legacy2aidl_uint32_levelEstimator_Parameter_agc(value));
+ break;
+ }
+ case AGC2_PARAM_ADAPT_DIGI_EXTRA_SATURATION_MARGIN: {
+ aidlParam = VALUE_OR_RETURN_STATUS(
+ aidl::android::legacy2aidl_uint32_saturationMargin_Parameter_agc(value));
+ break;
+ }
+ default: {
+ ALOGW("%s unknown param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ }
+
+ return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
+}
+
+status_t AidlConversionAgc2::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());
+ return BAD_VALUE;
+ }
+ Parameter aidlParam;
+ switch (type) {
+ case AGC2_PARAM_FIXED_DIGITAL_GAIN: {
+ Parameter::Id id =
+ MAKE_SPECIFIC_PARAMETER_ID(AutomaticGainControl, automaticGainControlTag,
+ AutomaticGainControl::fixedDigitalGainMb);
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+ value = VALUE_OR_RETURN_STATUS(
+ aidl::android::aidl2legacy_Parameter_agc_uint32_fixedDigitalGain(aidlParam));
+ break;
+ }
+ case AGC2_PARAM_ADAPT_DIGI_LEVEL_ESTIMATOR: {
+ Parameter::Id id =
+ MAKE_SPECIFIC_PARAMETER_ID(AutomaticGainControl, automaticGainControlTag,
+ AutomaticGainControl::levelEstimator);
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+ value = VALUE_OR_RETURN_STATUS(
+ aidl::android::aidl2legacy_Parameter_agc_uint32_levelEstimator(aidlParam));
+ break;
+ }
+ case AGC2_PARAM_ADAPT_DIGI_EXTRA_SATURATION_MARGIN: {
+ Parameter::Id id =
+ MAKE_SPECIFIC_PARAMETER_ID(AutomaticGainControl, automaticGainControlTag,
+ AutomaticGainControl::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;
+ }
+ }
+
+ return param.writeToValue(&value);
+}
+
+} // namespace effect
+} // namespace android
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAgc2.h b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAgc2.h
new file mode 100644
index 0000000..8f7eac7
--- /dev/null
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAgc2.h
@@ -0,0 +1,39 @@
+/*
+ * 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 AidlConversionAgc2 : public EffectConversionHelperAidl {
+ public:
+ AidlConversionAgc2(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) {}
+ ~AidlConversionAgc2() {}
+
+ private:
+ status_t setParameter(utils::EffectParamReader& param) override;
+ status_t getParameter(utils::EffectParamWriter& param) override;
+};
+
+} // namespace effect
+} // namespace android
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionBassBoost.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionBassBoost.cpp
new file mode 100644
index 0000000..ba8148f
--- /dev/null
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionBassBoost.cpp
@@ -0,0 +1,106 @@
+/*
+ * 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 "AidlConversionBassBoost"
+//#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_bassboost.h>
+
+#include <utils/Log.h>
+
+#include "AidlConversionBassBoost.h"
+
+namespace android {
+namespace effect {
+
+using ::aidl::android::convertIntegral;
+using ::aidl::android::aidl_utils::statusTFromBinderStatus;
+using ::aidl::android::hardware::audio::effect::BassBoost;
+using ::aidl::android::hardware::audio::effect::Parameter;
+using ::android::status_t;
+using utils::EffectParamReader;
+using utils::EffectParamWriter;
+
+status_t AidlConversionBassBoost::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;
+ switch (type) {
+ case BASSBOOST_PARAM_STRENGTH: {
+ aidlParam = VALUE_OR_RETURN_STATUS(
+ aidl::android::legacy2aidl_uint16_strengthPm_Parameter_BassBoost(value));
+ break;
+ }
+ case BASSBOOST_PARAM_STRENGTH_SUPPORTED: {
+ ALOGW("%s set BASSBOOST_PARAM_STRENGTH_SUPPORTED not supported", __func__);
+ return BAD_VALUE;
+ }
+ default: {
+ ALOGW("%s unknown param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ }
+
+ return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
+}
+
+status_t AidlConversionBassBoost::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;
+ }
+ Parameter aidlParam;
+ switch (type) {
+ case BASSBOOST_PARAM_STRENGTH: {
+ Parameter::Id id =
+ MAKE_SPECIFIC_PARAMETER_ID(BassBoost, bassBoostTag, BassBoost::strengthPm);
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+ value = VALUE_OR_RETURN_STATUS(
+ aidl::android::aidl2legacy_Parameter_BassBoost_uint16_strengthPm(aidlParam));
+ break;
+ }
+ case BASSBOOST_PARAM_STRENGTH_SUPPORTED: {
+ const auto& cap =
+ VALUE_OR_RETURN_STATUS(aidl::android::UNION_GET(mDesc.capability, bassBoost));
+ value = VALUE_OR_RETURN_STATUS(convertIntegral<uint32_t>(cap.strengthSupported));
+ break;
+ }
+ default: {
+ ALOGW("%s unknown param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ }
+
+ return param.writeToValue(&value);
+}
+
+} // namespace effect
+} // namespace android
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionBassBoost.h b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionBassBoost.h
new file mode 100644
index 0000000..9664aa1
--- /dev/null
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionBassBoost.h
@@ -0,0 +1,40 @@
+/*
+ * 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 AidlConversionBassBoost : public EffectConversionHelperAidl {
+ public:
+ AidlConversionBassBoost(
+ 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) {}
+ ~AidlConversionBassBoost() {}
+
+ private:
+ status_t setParameter(utils::EffectParamReader& param) override;
+ status_t getParameter(utils::EffectParamWriter& param) override;
+};
+
+} // namespace effect
+} // namespace android
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionDownmix.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionDownmix.cpp
new file mode 100644
index 0000000..17cedf7
--- /dev/null
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionDownmix.cpp
@@ -0,0 +1,95 @@
+/*
+ * 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 "AidlConversionDownmix"
+//#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_downmix.h>
+
+#include <system/audio_effect.h>
+#include <utils/Log.h>
+
+#include "AidlConversionDownmix.h"
+
+namespace android {
+namespace effect {
+
+using ::aidl::android::aidl_utils::statusTFromBinderStatus;
+using ::aidl::android::hardware::audio::effect::Downmix;
+using ::aidl::android::hardware::audio::effect::Parameter;
+using ::android::status_t;
+using utils::EffectParamReader;
+using utils::EffectParamWriter;
+
+status_t AidlConversionDownmix::setParameter(EffectParamReader& param) {
+ uint32_t type = 0;
+ int16_t value = 0;
+ if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(int16_t)) ||
+ OK != param.readFromParameter(&type) || OK != param.readFromValue(&value)) {
+ ALOGE("%s invalid param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ Parameter aidlParam;
+ switch (type) {
+ case DOWNMIX_PARAM_TYPE: {
+ aidlParam = VALUE_OR_RETURN_STATUS(
+ aidl::android::legacy2aidl_int16_type_Parameter_Downmix(value));
+ break;
+ }
+ default: {
+ ALOGW("%s unknown param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ }
+
+ return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
+}
+
+status_t AidlConversionDownmix::getParameter(EffectParamWriter& param) {
+ int16_t value = 0;
+ uint32_t type = 0;
+ if (!param.validateParamValueSize(sizeof(uint32_t), sizeof(uint16_t)) ||
+ OK != param.readFromParameter(&type)) {
+ param.setStatus(BAD_VALUE);
+ return BAD_VALUE;
+ }
+ Parameter aidlParam;
+ switch (type) {
+ case DOWNMIX_PARAM_TYPE: {
+ Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(Downmix, downmixTag, Downmix::type);
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+ value = VALUE_OR_RETURN_STATUS(
+ aidl::android::aidl2legacy_Parameter_Downmix_int16_type(aidlParam));
+ break;
+ }
+ default: {
+ ALOGW("%s unknown param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ }
+
+ return param.writeToValue(&value);
+}
+
+} // namespace effect
+} // namespace android
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionDownmix.h b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionDownmix.h
new file mode 100644
index 0000000..8b28ca3
--- /dev/null
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionDownmix.h
@@ -0,0 +1,39 @@
+/*
+ * 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/BpEffect.h>
+#include "EffectConversionHelperAidl.h"
+
+namespace android {
+namespace effect {
+
+class AidlConversionDownmix : public EffectConversionHelperAidl {
+ public:
+ AidlConversionDownmix(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) {}
+ ~AidlConversionDownmix() {}
+
+ private:
+ status_t setParameter(utils::EffectParamReader& param) override;
+ status_t getParameter(utils::EffectParamWriter& param) override;
+};
+
+} // namespace effect
+} // namespace android
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionDynamicsProcessing.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionDynamicsProcessing.cpp
new file mode 100644
index 0000000..4ecaa07
--- /dev/null
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionDynamicsProcessing.cpp
@@ -0,0 +1,522 @@
+/*
+ * 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 "AidlConversionDp"
+//#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_effect.h>
+#include <system/audio_effects/effect_dynamicsprocessing.h>
+
+#include <utils/Log.h>
+
+#include "AidlConversionDynamicsProcessing.h"
+
+namespace android {
+namespace effect {
+
+using ::aidl::android::convertIntegral;
+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 ::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;
+ }
+ 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;
+ }
+ aidlParam = MAKE_SPECIFIC_PARAMETER(DynamicsProcessing, dynamicsProcessing, inputGain,
+ {inputGainAidl});
+ break;
+ }
+ case DP_PARAM_ENGINE_ARCHITECTURE: {
+ DynamicsProcessing::EngineArchitecture engine =
+ VALUE_OR_RETURN_STATUS(readEngineArchitectureFromParam(param));
+ aidlParam = MAKE_SPECIFIC_PARAMETER(DynamicsProcessing, dynamicsProcessing,
+ engineArchitecture, engine);
+ mEngine = engine;
+ break;
+ }
+ case DP_PARAM_PRE_EQ: {
+ DynamicsProcessing::ChannelConfig chConfig =
+ VALUE_OR_RETURN_STATUS(readChannelConfigFromParam(param));
+ aidlParam = MAKE_SPECIFIC_PARAMETER(DynamicsProcessing, dynamicsProcessing, preEq,
+ {chConfig});
+ break;
+ }
+ case DP_PARAM_POST_EQ: {
+ DynamicsProcessing::ChannelConfig chConfig =
+ VALUE_OR_RETURN_STATUS(readChannelConfigFromParam(param));
+ aidlParam = MAKE_SPECIFIC_PARAMETER(DynamicsProcessing, dynamicsProcessing, postEq,
+ {chConfig});
+ break;
+ }
+ case DP_PARAM_MBC: {
+ DynamicsProcessing::ChannelConfig chConfig =
+ VALUE_OR_RETURN_STATUS(readChannelConfigFromParam(param));
+ aidlParam = MAKE_SPECIFIC_PARAMETER(DynamicsProcessing, dynamicsProcessing, mbc,
+ {chConfig});
+ break;
+ }
+ case DP_PARAM_PRE_EQ_BAND: {
+ DynamicsProcessing::EqBandConfig bandConfig =
+ VALUE_OR_RETURN_STATUS(readEqBandConfigFromParam(param));
+ aidlParam = MAKE_SPECIFIC_PARAMETER(DynamicsProcessing, dynamicsProcessing, preEqBand,
+ {bandConfig});
+ break;
+ }
+ case DP_PARAM_POST_EQ_BAND: {
+ DynamicsProcessing::EqBandConfig bandConfig =
+ VALUE_OR_RETURN_STATUS(readEqBandConfigFromParam(param));
+ aidlParam = MAKE_SPECIFIC_PARAMETER(DynamicsProcessing, dynamicsProcessing, postEqBand,
+ {bandConfig});
+ break;
+ }
+ case DP_PARAM_MBC_BAND: {
+ DynamicsProcessing::MbcBandConfig bandConfig =
+ VALUE_OR_RETURN_STATUS(readMbcBandConfigFromParam(param));
+ aidlParam = MAKE_SPECIFIC_PARAMETER(DynamicsProcessing, dynamicsProcessing, mbcBand,
+ {bandConfig});
+ break;
+ }
+ case DP_PARAM_LIMITER: {
+ DynamicsProcessing::LimiterConfig config =
+ VALUE_OR_RETURN_STATUS(readLimiterConfigFromParam(param));
+ aidlParam = MAKE_SPECIFIC_PARAMETER(DynamicsProcessing, dynamicsProcessing, limiter,
+ {config});
+ break;
+ }
+ default: {
+ ALOGW("%s unknown param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ }
+
+ return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
+}
+
+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());
+ }
+ 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;
+ }
+ 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,
+ DynamicsProcessing::inputGain,
+ std::vector<DynamicsProcessing::InputGain>));
+ for (const auto& gain : gains) {
+ if (gain.channel == channel) {
+ return param.writeToValue(&gain.gainDb);
+ }
+ }
+ ALOGE("%s not able to find channel %d", __func__, channel);
+ 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)));
+
+ DynamicsProcessing::EngineArchitecture engine =
+ VALUE_OR_RETURN_STATUS(aidl::android::GET_PARAMETER_SPECIFIC_FIELD(
+ aidlParam, DynamicsProcessing, dynamicsProcessing,
+ DynamicsProcessing::engineArchitecture,
+ DynamicsProcessing::EngineArchitecture));
+ int32_t resolution = VALUE_OR_RETURN_STATUS(
+ aidl::android::aidl2legacy_DynamicsProcessing_ResolutionPreference_int32(
+ engine.resolutionPreference));
+ int32_t preEqInUse =
+ VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(engine.preEqStage.inUse));
+ int32_t mbcInUse =
+ VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(engine.mbcStage.inUse));
+ int32_t postEqInUse =
+ 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;
+ }
+ mEngine = engine;
+ return OK;
+ }
+ case DP_PARAM_PRE_EQ: {
+ return getChannelConfig(DynamicsProcessing::preEq, param);
+ }
+ case DP_PARAM_POST_EQ: {
+ return getChannelConfig(DynamicsProcessing::postEq, param);
+ }
+ case DP_PARAM_MBC: {
+ return getChannelConfig(DynamicsProcessing::mbc, param);
+ }
+ case DP_PARAM_PRE_EQ_BAND: {
+ return getEqBandConfig(DynamicsProcessing::preEqBand, param);
+ }
+ case DP_PARAM_POST_EQ_BAND: {
+ return getEqBandConfig(DynamicsProcessing::postEqBand, param);
+ }
+ case DP_PARAM_MBC_BAND: {
+ return getMbcBandConfig(param);
+ }
+ case DP_PARAM_LIMITER: {
+ 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;
+ }
+ return OK;
+ }
+ default: {
+ ALOGW("%s unknown param %s", __func__, param.toString().c_str());
+ return BAD_VALUE;
+ }
+ }
+}
+
+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 DynamicsProcessing::ChannelConfig(
+ {.enable = VALUE_OR_RETURN(convertIntegral<bool>(enable)), .channel = channel});
+}
+
+aidl::ConversionResult<DynamicsProcessing::EqBandConfig>
+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);
+ }
+ config.enable = VALUE_OR_RETURN(convertIntegral<bool>(enable));
+ return config;
+}
+
+aidl::ConversionResult<DynamicsProcessing::MbcBandConfig>
+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);
+ }
+ config.enable = VALUE_OR_RETURN(convertIntegral<bool>(enable));
+ return config;
+}
+
+aidl::ConversionResult<DynamicsProcessing::LimiterConfig>
+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);
+ }
+ config.enable = VALUE_OR_RETURN(convertIntegral<bool>(enable));
+ return config;
+}
+
+aidl::ConversionResult<DynamicsProcessing::EngineArchitecture>
+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);
+ }
+
+ engine.resolutionPreference = VALUE_OR_RETURN(
+ aidl::android::legacy2aidl_int32_DynamicsProcessing_ResolutionPreference(variant));
+ engine.preEqStage.inUse = VALUE_OR_RETURN(convertIntegral<bool>(preEqInUse));
+ engine.mbcStage.inUse = VALUE_OR_RETURN(convertIntegral<bool>(mbcInUse));
+ engine.postEqStage.inUse = VALUE_OR_RETURN(convertIntegral<bool>(postEqInUse));
+ engine.limiterInUse = VALUE_OR_RETURN(convertIntegral<bool>(limiterInUse));
+ return engine;
+}
+
+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;
+ }
+
+ Parameter aidlParam;
+ Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(DynamicsProcessing, dynamicsProcessingTag, tag);
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+
+ std::vector<DynamicsProcessing::ChannelConfig> channels;
+ int32_t inUse, bandCount;
+ switch (tag) {
+ case DynamicsProcessing::preEq: {
+ inUse = mEngine.preEqStage.inUse;
+ bandCount = mEngine.preEqStage.bandCount;
+ channels = VALUE_OR_RETURN_STATUS(aidl::android::GET_PARAMETER_SPECIFIC_FIELD(
+ aidlParam, DynamicsProcessing, dynamicsProcessing, DynamicsProcessing::preEq,
+ std::vector<DynamicsProcessing::ChannelConfig>));
+ break;
+ }
+ case DynamicsProcessing::postEq: {
+ inUse = mEngine.postEqStage.inUse;
+ bandCount = mEngine.postEqStage.bandCount;
+ channels = VALUE_OR_RETURN_STATUS(aidl::android::GET_PARAMETER_SPECIFIC_FIELD(
+ aidlParam, DynamicsProcessing, dynamicsProcessing, DynamicsProcessing::postEq,
+ std::vector<DynamicsProcessing::ChannelConfig>));
+ break;
+ }
+ case DynamicsProcessing::mbc: {
+ inUse = mEngine.mbcStage.inUse;
+ bandCount = mEngine.mbcStage.bandCount;
+ channels = VALUE_OR_RETURN_STATUS(aidl::android::GET_PARAMETER_SPECIFIC_FIELD(
+ aidlParam, DynamicsProcessing, dynamicsProcessing, DynamicsProcessing::mbc,
+ std::vector<DynamicsProcessing::ChannelConfig>));
+ break;
+ }
+ default: {
+ ALOGE("%s unsupported tag %s", __func__, toString(tag).c_str());
+ return BAD_VALUE;
+ }
+ }
+
+ 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 OK;
+ }
+ }
+ ALOGE("%s not able to find channel %d", __func__, channel);
+ return BAD_VALUE;
+}
+
+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;
+ }
+
+ Parameter aidlParam;
+ Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(DynamicsProcessing, dynamicsProcessingTag, tag);
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+
+ std::vector<DynamicsProcessing::EqBandConfig> bands;
+ if (tag == DynamicsProcessing::preEqBand) {
+ bands = VALUE_OR_RETURN_STATUS(aidl::android::GET_PARAMETER_SPECIFIC_FIELD(
+ aidlParam, DynamicsProcessing, dynamicsProcessing, preEqBand,
+ std::vector<DynamicsProcessing::EqBandConfig>));
+ } else if (tag == DynamicsProcessing::postEqBand) {
+ bands = VALUE_OR_RETURN_STATUS(aidl::android::GET_PARAMETER_SPECIFIC_FIELD(
+ aidlParam, DynamicsProcessing, dynamicsProcessing, postEqBand,
+ std::vector<DynamicsProcessing::EqBandConfig>));
+ } else {
+ return BAD_VALUE;
+ }
+
+ 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 OK;
+ }
+ }
+ ALOGE("%s not able to find channel %d band %d", __func__, channel, band);
+ return BAD_VALUE;
+}
+
+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;
+ }
+ Parameter aidlParam;
+ Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(DynamicsProcessing, dynamicsProcessingTag,
+ DynamicsProcessing::mbcBand);
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+
+ std::vector<DynamicsProcessing::MbcBandConfig> bands =
+ VALUE_OR_RETURN_STATUS(aidl::android::GET_PARAMETER_SPECIFIC_FIELD(
+ aidlParam, DynamicsProcessing, dynamicsProcessing, mbcBand,
+ std::vector<DynamicsProcessing::MbcBandConfig>));
+
+ 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 OK;
+ }
+ }
+ ALOGE("%s not able to find channel %d band %d", __func__, channel, band);
+ return BAD_VALUE;
+}
+
+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;
+ }
+ Parameter aidlParam;
+ Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(DynamicsProcessing, dynamicsProcessingTag,
+ DynamicsProcessing::limiter);
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
+
+ std::vector<DynamicsProcessing::LimiterConfig> configs =
+ VALUE_OR_RETURN_STATUS(aidl::android::GET_PARAMETER_SPECIFIC_FIELD(
+ aidlParam, DynamicsProcessing, dynamicsProcessing, limiter,
+ std::vector<DynamicsProcessing::LimiterConfig>));
+
+ for (const auto& config : configs) {
+ 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 OK;
+ }
+ }
+ ALOGE("%s not able to find channel %d", __func__, channel);
+ return BAD_VALUE;
+}
+
+} // namespace effect
+} // namespace android
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionDynamicsProcessing.h b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionDynamicsProcessing.h
new file mode 100644
index 0000000..6bab18d
--- /dev/null
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionDynamicsProcessing.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/audio/effect/BpEffect.h>
+#include "EffectConversionHelperAidl.h"
+
+namespace android {
+namespace effect {
+
+class AidlConversionDp : public EffectConversionHelperAidl {
+ public:
+ AidlConversionDp(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) {}
+ ~AidlConversionDp() {}
+
+ private:
+ aidl::android::hardware::audio::effect::DynamicsProcessing::EngineArchitecture mEngine;
+
+ status_t setParameter(utils::EffectParamReader& param) override;
+ status_t getParameter(utils::EffectParamWriter& param) override;
+
+ aidl::ConversionResult<
+ aidl::android::hardware::audio::effect::DynamicsProcessing::ChannelConfig>
+ readChannelConfigFromParam(utils::EffectParamReader& param);
+ aidl::ConversionResult<aidl::android::hardware::audio::effect::DynamicsProcessing::EqBandConfig>
+ readEqBandConfigFromParam(utils::EffectParamReader& param);
+ aidl::ConversionResult<
+ aidl::android::hardware::audio::effect::DynamicsProcessing::MbcBandConfig>
+ readMbcBandConfigFromParam(utils::EffectParamReader& param);
+ aidl::ConversionResult<
+ aidl::android::hardware::audio::effect::DynamicsProcessing::LimiterConfig>
+ readLimiterConfigFromParam(utils::EffectParamReader& param);
+ aidl::ConversionResult<
+ aidl::android::hardware::audio::effect::DynamicsProcessing::EngineArchitecture>
+ readEngineArchitectureFromParam(utils::EffectParamReader& param);
+
+ status_t getChannelConfig(aidl::android::hardware::audio::effect::DynamicsProcessing::Tag tag,
+ utils::EffectParamWriter& writer);
+ status_t getEqBandConfig(aidl::android::hardware::audio::effect::DynamicsProcessing::Tag tag,
+ utils::EffectParamWriter& param);
+ status_t getMbcBandConfig(utils::EffectParamWriter& param);
+ status_t getLimiterConfig(utils::EffectParamWriter& param);
+
+};
+
+} // namespace effect
+} // namespace android
diff --git a/media/libaudiohal/include/media/audiohal/AudioEffectUuid.h b/media/libaudiohal/include/media/audiohal/AudioEffectUuid.h
index 20a10f6..77563e8 100644
--- a/media/libaudiohal/include/media/audiohal/AudioEffectUuid.h
+++ b/media/libaudiohal/include/media/audiohal/AudioEffectUuid.h
@@ -47,18 +47,18 @@
0x11ed,
0x9b6a,
{0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
-// 0bed4300-ddd6-11db-8f34-0002a5d5c51b.
-static const AudioUuid kEqualizerTypeUUID = {static_cast<int32_t>(0x0bed4300),
- 0xddd6,
- 0x11db,
- 0x8f34,
- {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
// 7261676f-6d75-7369-6364-28e2fd3ac39e
static const AudioUuid kDynamicsProcessingTypeUUID = {static_cast<int32_t>(0x7261676f),
0x6d75,
0x7369,
0x6364,
{0x28, 0xe2, 0xfd, 0x3a, 0xc3, 0x9e}};
+// 0bed4300-ddd6-11db-8f34-0002a5d5c51b.
+static const AudioUuid kEqualizerTypeUUID = {static_cast<int32_t>(0x0bed4300),
+ 0xddd6,
+ 0x11db,
+ 0x8f34,
+ {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
// 1411e6d6-aecd-4021-a1cf-a6aceb0d71e5
static const AudioUuid kHapticGeneratorTypeUUID = {static_cast<int32_t>(0x1411e6d6),
0xaecd,
diff --git a/media/libaudiohal/tests/EffectsFactoryHalInterface_test.cpp b/media/libaudiohal/tests/EffectsFactoryHalInterface_test.cpp
index c2e2ba7..9b2d0e2 100644
--- a/media/libaudiohal/tests/EffectsFactoryHalInterface_test.cpp
+++ b/media/libaudiohal/tests/EffectsFactoryHalInterface_test.cpp
@@ -22,6 +22,7 @@
#include <system/audio_effects/audio_effects_utils.h>
#include <system/audio_effects/effect_aec.h>
+#include <system/audio_effects/effect_dynamicsprocessing.h>
#include <system/audio_effect.h>
#include <gtest/gtest.h>
@@ -29,6 +30,7 @@
namespace android {
+using effect::utils::EffectParamReader;
using effect::utils::EffectParamWriter;
// EffectsFactoryHalInterface
@@ -124,7 +126,7 @@
EXPECT_EQ(OK, factory->getDescriptors(&FX_IID_AEC_, &descs));
static constexpr uint32_t delayValue = 0x20;
for (const auto& desc : descs) {
- ASSERT_EQ(0, std::memcmp(&desc.type, &FX_IID_AEC_, sizeof(FX_IID_AEC_)));
+ ASSERT_EQ(0, std::memcmp(&desc.type, &FX_IID_AEC_, sizeof(effect_uuid_t)));
sp<EffectHalInterface> interface;
EXPECT_EQ(OK, factory->createEffect(&desc.uuid, 1 /* sessionId */, 1 /* ioId */,
1 /* deviceId */, &interface));
@@ -133,7 +135,6 @@
uint32_t type = AEC_PARAM_ECHO_DELAY, value = delayValue;
param->psize = sizeof(type);
param->vsize = sizeof(value);
- //EXPECT_EQ(1, 0) << param->psize << " " << param->vsize;
EffectParamWriter writer(*param);
EXPECT_EQ(OK, writer.writeToParameter(&type)) << writer.toString();
EXPECT_EQ(OK, writer.writeToValue(&value)) << writer.toString();
@@ -141,24 +142,24 @@
uint32_t replySize = sizeof(reply);
EXPECT_EQ(OK, interface->command(EFFECT_CMD_INIT, 0, nullptr, &replySize, &reply));
EXPECT_EQ(OK, interface->command(EFFECT_CMD_SET_PARAM, (uint32_t)writer.getTotalSize(),
- param, &replySize, &reply));
+ param, &replySize, &reply)) << writer.toString();
EXPECT_EQ(replySize, sizeof(reply));
EXPECT_EQ(OK, reply);
effect_param_t* responseParam = (effect_param_t*)testResponseBuffer;
param->psize = sizeof(type);
param->vsize = sizeof(value);
- EffectParamWriter response(*param);
- EXPECT_EQ(OK, response.writeToParameter(&type)) << response.toString();
- replySize = response.getTotalSize();
+ EffectParamWriter request(*param);
+ EXPECT_EQ(OK, request.writeToParameter(&type)) << request.toString();
+ replySize = request.getTotalSize();
EXPECT_EQ(OK, interface->command(EFFECT_CMD_GET_PARAM, (uint32_t)writer.getTotalSize(),
param, &replySize, responseParam));
- EXPECT_EQ(replySize, response.getTotalSize());
- EXPECT_EQ(OK, response.readFromValue(&value));
- EXPECT_EQ(delayValue, value);
+ EffectParamReader response(*responseParam);
+ EXPECT_EQ(replySize, response.getTotalSize()) << response.toString();
+ EXPECT_EQ(OK, response.readFromValue(&value)) << response.toString();
+ EXPECT_EQ(delayValue, value) << response.toString();
}
}
-
// TODO: b/263986405 Add multi-thread testing
} // namespace android
diff --git a/media/libmedia/Android.bp b/media/libmedia/Android.bp
index ab1cf69..590a7b7 100644
--- a/media/libmedia/Android.bp
+++ b/media/libmedia/Android.bp
@@ -384,7 +384,6 @@
export_shared_lib_headers: [
"libaudioclient",
"libbinder",
- "libandroidicu",
//"libsonivox",
"libmedia_omx",
"framework-permission-aidl-cpp",
diff --git a/media/libmedia/include/media/CharacterEncodingDetector.h b/media/libmedia/include/media/CharacterEncodingDetector.h
index 62564b1..2acc868 100644
--- a/media/libmedia/include/media/CharacterEncodingDetector.h
+++ b/media/libmedia/include/media/CharacterEncodingDetector.h
@@ -21,9 +21,12 @@
#include "StringArray.h"
-#include "unicode/ucnv.h"
-#include "unicode/ucsdet.h"
-#include "unicode/ustring.h"
+/** Declare opaque structures from ICU4C. */
+struct UConverter;
+typedef struct UConverter UConverter;
+
+struct UCharsetMatch;
+typedef struct UCharsetMatch UCharsetMatch;
namespace android {
diff --git a/media/libstagefright/Android.bp b/media/libstagefright/Android.bp
index 59d1be5..32e40c3 100644
--- a/media/libstagefright/Android.bp
+++ b/media/libstagefright/Android.bp
@@ -301,7 +301,6 @@
"libstagefright_codecbase",
"libstagefright_foundation",
"libstagefright_omx_utils",
- "libRScpp",
"libhidlallocatorutils",
"libhidlbase",
"libhidlmemory",
diff --git a/media/libstagefright/include/media/stagefright/RenderScriptWrapper.h b/media/libstagefright/include/media/stagefright/RenderScriptWrapper.h
deleted file mode 100644
index b42649e..0000000
--- a/media/libstagefright/include/media/stagefright/RenderScriptWrapper.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef RENDERSCRIPT_WRAPPER_H_
-#define RENDERSCRIPT_WRAPPER_H_
-
-#include <RenderScript.h>
-
-namespace android {
-
-struct RenderScriptWrapper : public RefBase {
-public:
- struct RSFilterCallback : public RefBase {
- public:
- // called by RSFilter to process each input buffer
- virtual status_t processBuffers(
- RSC::Allocation* inBuffer,
- RSC::Allocation* outBuffer) = 0;
-
- virtual status_t handleSetParameters(const sp<AMessage> &msg) = 0;
- };
-
- sp<RSFilterCallback> mCallback;
- RSC::sp<RSC::RS> mContext;
-};
-
-} // namespace android
-
-#endif // RENDERSCRIPT_WRAPPER_H_
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index e910c3d..d09e426 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -3916,7 +3916,8 @@
status_t status = mEngine->clearDevicesRoleForStrategy(strategy, role);
if (status != NO_ERROR) {
- ALOGV("Engine could not remove device role for strategy %d status %d",
+ ALOGW_IF(status != NAME_NOT_FOUND,
+ "Engine could not remove device role for strategy %d status %d",
strategy, status);
return status;
}
@@ -3988,10 +3989,11 @@
status_t status = mEngine->removeDevicesRoleForCapturePreset(
audioSource, role, devices);
- ALOGW_IF(status != NO_ERROR,
+ ALOGW_IF(status != NO_ERROR && status != NAME_NOT_FOUND,
"Engine could not remove devices role (%d) for capture preset %d", role, audioSource);
-
- updateInputRouting();
+ if (status == NO_ERROR) {
+ updateInputRouting();
+ }
return status;
}
@@ -4000,10 +4002,11 @@
ALOGV("%s() audioSource=%d role=%d", __func__, audioSource, role);
status_t status = mEngine->clearDevicesRoleForCapturePreset(audioSource, role);
- ALOGW_IF(status != NO_ERROR,
+ ALOGW_IF(status != NO_ERROR && status != NAME_NOT_FOUND,
"Engine could not clear devices role (%d) for capture preset %d", role, audioSource);
-
- updateInputRouting();
+ if (status == NO_ERROR) {
+ updateInputRouting();
+ }
return status;
}
diff --git a/services/audiopolicy/tests/Android.bp b/services/audiopolicy/tests/Android.bp
index 6813587..b2546d2 100644
--- a/services/audiopolicy/tests/Android.bp
+++ b/services/audiopolicy/tests/Android.bp
@@ -28,6 +28,7 @@
"liblog",
"libmedia_helper",
"libutils",
+ "libcutils",
"libxml2",
"framework-permission-aidl-cpp",
"libbinder",
diff --git a/services/audiopolicy/tests/audiopolicymanager_tests.cpp b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
index d209c81..ef829e1 100644
--- a/services/audiopolicy/tests/audiopolicymanager_tests.cpp
+++ b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
@@ -32,6 +32,7 @@
#include <media/RecordingActivityTracker.h>
#include <utils/Log.h>
#include <utils/Vector.h>
+#include <cutils/multiuser.h>
#include "AudioPolicyInterface.h"
#include "AudioPolicyManagerTestClient.h"
@@ -2170,6 +2171,8 @@
static const std::string sCarConfig;
static const std::string sCarBusMediaOutput;
static const std::string sCarBusNavigationOutput;
+ static const std::string sCarRearZoneOneOutput;
+ static const std::string sCarRearZoneTwoOutput;
};
const std::string AudioPolicyManagerCarTest::sCarConfig =
@@ -2179,6 +2182,10 @@
const std::string AudioPolicyManagerCarTest::sCarBusNavigationOutput = "bus1_navigation_out";
+const std::string AudioPolicyManagerCarTest::sCarRearZoneOneOutput = "bus100_audio_zone_1";
+
+const std::string AudioPolicyManagerCarTest::sCarRearZoneTwoOutput = "bus200_audio_zone_2";
+
TEST_F(AudioPolicyManagerCarTest, InitSuccess) {
// SetUp must finish with no assertions.
}
@@ -2304,7 +2311,7 @@
ASSERT_EQ(NO_ERROR, ret);
const AudioDeviceTypeAddr mediaOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput);
const AudioDeviceTypeAddrVector outputDevices = {mediaOutputDevice};
- mManager->setUserIdDeviceAffinities(0, outputDevices);
+ mManager->setUserIdDeviceAffinities(/* userId */ 0, outputDevices);
audio_port_v7 navDevicePort;
ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
sCarBusNavigationOutput, &navDevicePort));
@@ -2410,7 +2417,7 @@
const AudioDeviceTypeAddr mediaOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput);
const AudioDeviceTypeAddr navOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput);
const AudioDeviceTypeAddrVector outputDevices = {mediaOutputDevice, navOutputDevice};
- mManager->setUserIdDeviceAffinities(0, outputDevices);
+ mManager->setUserIdDeviceAffinities(/* userId */ 0, outputDevices);
audio_port_v7 navDevicePort;
ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
sCarBusNavigationOutput, &navDevicePort));
@@ -2448,7 +2455,7 @@
const AudioDeviceTypeAddr mediaOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput);
const AudioDeviceTypeAddr navOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput);
const AudioDeviceTypeAddrVector outputDevices = {mediaOutputDevice, navOutputDevice};
- mManager->setUserIdDeviceAffinities(0, outputDevices);
+ mManager->setUserIdDeviceAffinities(/* userId */ 0, outputDevices);
audio_port_v7 navDevicePort;
ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
sCarBusNavigationOutput, &navDevicePort));
@@ -2465,6 +2472,132 @@
ASSERT_EQ(navDevicePort.id, selectedDeviceId);
}
+TEST_F(AudioPolicyManagerCarTest,
+ GetOutputForAttrWithMatMixAfterUserAffinitiesForOneUser) {
+ status_t ret;
+ audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
+ audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+ audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
+ audioConfig.sample_rate = k48000SamplingRate;
+ std::vector<AudioMixMatchCriterion> mediaMatchCriteria = {
+ createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/ false)};
+ ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
+ AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
+ ASSERT_EQ(NO_ERROR, ret);
+ ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
+ AUDIO_DEVICE_OUT_BUS, sCarRearZoneOneOutput, audioConfig, mediaMatchCriteria);
+ ASSERT_EQ(NO_ERROR, ret);
+ ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
+ AUDIO_DEVICE_OUT_BUS, sCarRearZoneTwoOutput, audioConfig, mediaMatchCriteria);
+ ASSERT_EQ(NO_ERROR, ret);
+ const AudioDeviceTypeAddr mediaOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput);
+ const AudioDeviceTypeAddrVector primaryZoneDevices = {mediaOutputDevice};
+ mManager->setUserIdDeviceAffinities(/* userId */ 0, primaryZoneDevices);
+ audio_port_v7 primaryZoneDevicePort;
+ ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
+ sCarBusMediaOutput, &primaryZoneDevicePort));
+ audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ audio_io_handle_t output;
+ audio_port_handle_t portId;
+ const audio_attributes_t mediaAttribute = {
+ AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
+ AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
+ uid_t user11AppUid = multiuser_get_uid(/* user_id */ 11, /* app_id */ 12345);
+
+ getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
+ k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, mediaAttribute,
+ AUDIO_SESSION_NONE, user11AppUid);
+
+ ASSERT_EQ(primaryZoneDevicePort.id, selectedDeviceId);
+}
+
+TEST_F(AudioPolicyManagerCarTest,
+ GetOutputForAttrWithMatMixAfterUserAffinitiesForTwoUsers) {
+ status_t ret;
+ audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
+ audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+ audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
+ audioConfig.sample_rate = k48000SamplingRate;
+ std::vector<AudioMixMatchCriterion> mediaMatchCriteria = {
+ createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/ false)};
+ ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
+ AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
+ ASSERT_EQ(NO_ERROR, ret);
+ ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
+ AUDIO_DEVICE_OUT_BUS, sCarRearZoneOneOutput, audioConfig, mediaMatchCriteria);
+ ASSERT_EQ(NO_ERROR, ret);
+ ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
+ AUDIO_DEVICE_OUT_BUS, sCarRearZoneTwoOutput, audioConfig, mediaMatchCriteria);
+ ASSERT_EQ(NO_ERROR, ret);
+ const AudioDeviceTypeAddr mediaOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput);
+ const AudioDeviceTypeAddrVector primaryZoneDevices = {mediaOutputDevice};
+ mManager->setUserIdDeviceAffinities(/* userId */ 0, primaryZoneDevices);
+ const AudioDeviceTypeAddr secondaryOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarRearZoneOneOutput);
+ const AudioDeviceTypeAddrVector secondaryZoneDevices = {secondaryOutputDevice};
+ mManager->setUserIdDeviceAffinities(/* userId */ 11, secondaryZoneDevices);
+ audio_port_v7 secondaryZoneDevicePort;
+ ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
+ sCarRearZoneOneOutput, &secondaryZoneDevicePort));
+ audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ audio_io_handle_t output;
+ audio_port_handle_t portId;
+ const audio_attributes_t mediaAttribute = {
+ AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
+ AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
+ uid_t user11AppUid = multiuser_get_uid(/* user_id */ 11, /* app_id */ 12345);
+
+ getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
+ k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, mediaAttribute,
+ AUDIO_SESSION_NONE, user11AppUid);
+
+ ASSERT_EQ(secondaryZoneDevicePort.id, selectedDeviceId);
+}
+
+TEST_F(AudioPolicyManagerCarTest,
+ GetOutputForAttrWithMatMixAfterUserAffinitiesForThreeUsers) {
+ status_t ret;
+ audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
+ audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+ audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
+ audioConfig.sample_rate = k48000SamplingRate;
+ std::vector<AudioMixMatchCriterion> mediaMatchCriteria = {
+ createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/ false)};
+ ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
+ AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
+ ASSERT_EQ(NO_ERROR, ret);
+ ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
+ AUDIO_DEVICE_OUT_BUS, sCarRearZoneOneOutput, audioConfig, mediaMatchCriteria);
+ ASSERT_EQ(NO_ERROR, ret);
+ ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
+ AUDIO_DEVICE_OUT_BUS, sCarRearZoneTwoOutput, audioConfig, mediaMatchCriteria);
+ ASSERT_EQ(NO_ERROR, ret);
+ const AudioDeviceTypeAddr mediaOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput);
+ const AudioDeviceTypeAddrVector primaryZoneDevices = {mediaOutputDevice};
+ mManager->setUserIdDeviceAffinities(/* userId */ 0, primaryZoneDevices);
+ const AudioDeviceTypeAddr secondaryOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarRearZoneOneOutput);
+ const AudioDeviceTypeAddrVector secondaryZoneDevices = {secondaryOutputDevice};
+ mManager->setUserIdDeviceAffinities(/* userId */ 11, secondaryZoneDevices);
+ const AudioDeviceTypeAddr tertiaryOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarRearZoneTwoOutput);
+ const AudioDeviceTypeAddrVector tertiaryZoneDevices = {tertiaryOutputDevice};
+ mManager->setUserIdDeviceAffinities(/* userId */ 15, tertiaryZoneDevices);
+ audio_port_v7 tertiaryZoneDevicePort;
+ ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
+ sCarRearZoneTwoOutput, &tertiaryZoneDevicePort));
+ audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ audio_io_handle_t output;
+ audio_port_handle_t portId;
+ const audio_attributes_t mediaAttribute = {
+ AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
+ AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
+ uid_t user15AppUid = multiuser_get_uid(/* user_id */ 15, /* app_id */ 12345);
+
+ getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
+ k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, mediaAttribute,
+ AUDIO_SESSION_NONE, user15AppUid);
+
+ ASSERT_EQ(tertiaryZoneDevicePort.id, selectedDeviceId);
+}
+
TEST_F(AudioPolicyManagerCarTest, GetOutputForAttrWithNoMatchingMix) {
status_t ret;
audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
@@ -2485,7 +2618,7 @@
const AudioDeviceTypeAddr mediaOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput);
const AudioDeviceTypeAddr navOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput);
const AudioDeviceTypeAddrVector outputDevices = {mediaOutputDevice, navOutputDevice};
- mManager->setUserIdDeviceAffinities(0, outputDevices);
+ mManager->setUserIdDeviceAffinities(/* userId */ 0, outputDevices);
audio_port_v7 navDevicePort;
ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
sCarBusNavigationOutput, &navDevicePort));
diff --git a/services/camera/libcameraservice/Android.bp b/services/camera/libcameraservice/Android.bp
index 7b1759e..1c922ce 100644
--- a/services/camera/libcameraservice/Android.bp
+++ b/services/camera/libcameraservice/Android.bp
@@ -143,6 +143,7 @@
"libhidlbase",
"libimage_io",
"libjpeg",
+ "libjpegrecoverymap",
"libmedia_codeclist",
"libmedia_omx",
"libmemunreachable",
@@ -182,9 +183,6 @@
"libbinderthreadstateutils",
"media_permission-aidl-cpp",
"libcameraservice_device_independent",
- "libjpegrecoverymap",
- "libjpegencoder",
- "libjpegdecoder",
],
export_shared_lib_headers: [
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 5eb068f..c812cd7 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -37,6 +37,7 @@
#include <android-base/macros.h>
#include <android-base/parseint.h>
#include <android-base/stringprintf.h>
+#include <android/permission/PermissionChecker.h>
#include <binder/ActivityManager.h>
#include <binder/AppOpsManager.h>
#include <binder/IPCThreadState.h>
@@ -696,11 +697,18 @@
broadcastTorchModeStatus(cameraId, newStatus, systemCameraKind);
}
-static bool hasPermissionsForSystemCamera(int callingPid, int callingUid,
- bool logPermissionFailure = false) {
- return checkPermission(sSystemCameraPermission, callingPid, callingUid,
- logPermissionFailure) &&
- checkPermission(sCameraPermission, callingPid, callingUid);
+static bool hasPermissionsForSystemCamera(int callingPid, int callingUid) {
+ permission::PermissionChecker permissionChecker;
+ AttributionSourceState attributionSource{};
+ attributionSource.pid = callingPid;
+ attributionSource.uid = callingUid;
+ bool checkPermissionForSystemCamera = permissionChecker.checkPermissionForPreflight(
+ sSystemCameraPermission, attributionSource, String16(), AppOpsManager::OP_NONE)
+ != permission::PermissionChecker::PERMISSION_HARD_DENIED;
+ bool checkPermissionForCamera = permissionChecker.checkPermissionForPreflight(
+ sCameraPermission, attributionSource, String16(), AppOpsManager::OP_NONE)
+ != permission::PermissionChecker::PERMISSION_HARD_DENIED;
+ return checkPermissionForSystemCamera && checkPermissionForCamera;
}
Status CameraService::getNumberOfCameras(int32_t type, int32_t* numCameras) {
@@ -779,8 +787,14 @@
const std::vector<std::string> *deviceIds = &mNormalDeviceIdsWithoutSystemCamera;
auto callingPid = CameraThreadState::getCallingPid();
auto callingUid = CameraThreadState::getCallingUid();
- if (checkPermission(sSystemCameraPermission, callingPid, callingUid,
- /*logPermissionFailure*/false) || getpid() == callingPid) {
+ permission::PermissionChecker permissionChecker;
+ AttributionSourceState attributionSource{};
+ attributionSource.pid = callingPid;
+ attributionSource.uid = callingUid;
+ bool checkPermissionForSystemCamera = permissionChecker.checkPermissionForPreflight(
+ sSystemCameraPermission, attributionSource, String16(), AppOpsManager::OP_NONE)
+ != permission::PermissionChecker::PERMISSION_HARD_DENIED;
+ if (checkPermissionForSystemCamera || getpid() == callingPid) {
deviceIds = &mNormalDeviceIds;
}
if (cameraIdInt < 0 || cameraIdInt >= static_cast<int>(deviceIds->size())) {
@@ -851,9 +865,16 @@
// If it's not calling from cameraserver, check the permission only if
// android.permission.CAMERA is required. If android.permission.SYSTEM_CAMERA was needed,
// it would've already been checked in shouldRejectSystemCameraConnection.
+ permission::PermissionChecker permissionChecker;
+ AttributionSourceState attributionSource{};
+ attributionSource.pid = callingPid;
+ attributionSource.uid = callingUid;
+ bool checkPermissionForCamera = permissionChecker.checkPermissionForPreflight(
+ sCameraPermission, attributionSource, String16(), AppOpsManager::OP_NONE)
+ != permission::PermissionChecker::PERMISSION_HARD_DENIED;
if ((callingPid != getpid()) &&
(deviceKind != SystemCameraKind::SYSTEM_ONLY_CAMERA) &&
- !checkPermission(sCameraPermission, callingPid, callingUid)) {
+ !checkPermissionForCamera) {
res = cameraInfo->removePermissionEntries(
mCameraProviderManager->getProviderTagIdLocked(String8(cameraId).string()),
&tagsRemoved);
@@ -1287,6 +1308,9 @@
Status CameraService::validateClientPermissionsLocked(const String8& cameraId,
const String8& clientName8, int& clientUid, int& clientPid,
/*out*/int& originalClientPid) const {
+ permission::PermissionChecker permissionChecker;
+ AttributionSourceState attributionSource{};
+
int callingPid = CameraThreadState::getCallingPid();
int callingUid = CameraThreadState::getCallingUid();
@@ -1333,9 +1357,14 @@
// If it's not calling from cameraserver, check the permission if the
// device isn't a system only camera (shouldRejectSystemCameraConnection already checks for
// android.permission.SYSTEM_CAMERA for system only camera devices).
+ attributionSource.pid = clientPid;
+ attributionSource.uid = clientUid;
+ attributionSource.packageName = clientName8;
+ bool checkPermissionForCamera = permissionChecker.checkPermissionForPreflight(
+ sCameraPermission, attributionSource, String16(), AppOpsManager::OP_NONE)
+ != permission::PermissionChecker::PERMISSION_HARD_DENIED;
if (callingPid != getpid() &&
- (deviceKind != SystemCameraKind::SYSTEM_ONLY_CAMERA) &&
- !checkPermission(sCameraPermission, clientPid, clientUid)) {
+ (deviceKind != SystemCameraKind::SYSTEM_ONLY_CAMERA) && !checkPermissionForCamera) {
ALOGE("Permission Denial: can't use the camera pid=%d, uid=%d", clientPid, clientUid);
return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
"Caller \"%s\" (PID %d, UID %d) cannot open camera \"%s\" without camera permission",
@@ -1724,7 +1753,7 @@
// characteristics) even if clients don't have android.permission.CAMERA. We do not want the
// same behavior for system camera devices.
if (!systemClient && systemCameraKind == SystemCameraKind::SYSTEM_ONLY_CAMERA &&
- !hasPermissionsForSystemCamera(cPid, cUid, /*logPermissionFailure*/true)) {
+ !hasPermissionsForSystemCamera(cPid, cUid)) {
ALOGW("Rejecting access to system only camera %s, inadequete permissions",
cameraId.c_str());
return true;
@@ -2678,7 +2707,14 @@
// Check for camera permissions
int callingPid = CameraThreadState::getCallingPid();
int callingUid = CameraThreadState::getCallingUid();
- if ((callingPid != getpid()) && !checkPermission(sCameraPermission, callingPid, callingUid)) {
+ permission::PermissionChecker permissionChecker;
+ AttributionSourceState attributionSource{};
+ attributionSource.pid = callingPid;
+ attributionSource.uid = callingUid;
+ bool checkPermissionForCamera = permissionChecker.checkPermissionForPreflight(
+ sCameraPermission, attributionSource, String16(), AppOpsManager::OP_NONE)
+ != permission::PermissionChecker::PERMISSION_HARD_DENIED;
+ if ((callingPid != getpid()) && !checkPermissionForCamera) {
ALOGE("%s: pid %d doesn't have camera permissions", __FUNCTION__, callingPid);
return STATUS_ERROR(ERROR_PERMISSION_DENIED,
"android.permission.CAMERA needed to call"
@@ -2725,8 +2761,13 @@
auto clientUid = CameraThreadState::getCallingUid();
auto clientPid = CameraThreadState::getCallingPid();
- bool openCloseCallbackAllowed = checkPermission(sCameraOpenCloseListenerPermission,
- clientPid, clientUid, /*logPermissionFailure*/false);
+ permission::PermissionChecker permissionChecker;
+ AttributionSourceState attributionSource{};
+ attributionSource.uid = clientUid;
+ attributionSource.pid = clientPid;
+ bool openCloseCallbackAllowed = permissionChecker.checkPermissionForPreflight(
+ sCameraOpenCloseListenerPermission, attributionSource, String16(),
+ AppOpsManager::OP_NONE) != permission::PermissionChecker::PERMISSION_HARD_DENIED;
Mutex::Autolock lock(mServiceLock);