Revert "Listen for foreground AppOps changes" am: 8b11bc9a38 am: 7e70c76b6c
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/av/+/23817399
Change-Id: Ib49702b46141077d343cdc80900f470ed55ae646
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/Android.bp b/Android.bp
index 37f6457..302e250 100644
--- a/Android.bp
+++ b/Android.bp
@@ -102,3 +102,27 @@
},
},
}
+
+aidl_interface {
+ name: "av-audio-types-aidl",
+ unstable: true,
+ host_supported: true,
+ vendor_available: true,
+ double_loadable: true,
+ local_include_dir: "aidl",
+ srcs: [
+ "aidl/android/media/audio/IHalAdapterVendorExtension.aidl",
+ ],
+ imports: [
+ "android.hardware.audio.core-V1",
+ ],
+ backend: {
+ // The C++ backend is disabled transitively due to use of FMQ by the audio core HAL.
+ cpp: {
+ enabled: false,
+ },
+ java: {
+ sdk_version: "module_current",
+ },
+ },
+}
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index 1f7083b..62cf827 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -12,3 +12,4 @@
media/libmediatranscoding/
services/mediatranscoding/
media/libaudioclient/tests/
+ media/libaudiohal/tests/
diff --git a/aidl/android/media/audio/IHalAdapterVendorExtension.aidl b/aidl/android/media/audio/IHalAdapterVendorExtension.aidl
new file mode 100644
index 0000000..b7a7678
--- /dev/null
+++ b/aidl/android/media/audio/IHalAdapterVendorExtension.aidl
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.audio;
+
+import android.hardware.audio.core.VendorParameter;
+
+/**
+ * This interface is used by the HAL adapter of the Audio Server. Implementation
+ * is optional. Vendors may provide an implementation on the system_ext
+ * partition. The default instance of this interface, if provided, must be
+ * registered prior to the moment when the audio server connects to HAL modules.
+ *
+ * {@hide}
+ */
+interface IHalAdapterVendorExtension {
+ enum ParameterScope {
+ MODULE = 0,
+ STREAM = 1,
+ }
+
+ /**
+ * Parse raw parameter keys into vendor parameter ids.
+ *
+ * This method prepares arguments for a call to the 'getVendorParameters'
+ * method of an 'IModule' or an 'IStreamCommon' interface instance,
+ * depending on the provided scope.
+ *
+ * The client calls this method in order to prepare arguments for a call to
+ * the particular Core HAL interface. The result returned by the HAL is then
+ * processed using the 'processVendorParameters' method. It is not required
+ * to maintain a 1:1 correspondence between the provided raw keys and the
+ * elements of the parsed result. If the returned list is empty, the call of
+ * 'getVendorParameters' is skipped. The implementation can either ignore
+ * keys which it does not recognize, or throw an error. The latter is
+ * preferred as it can help in discovering malformed key names.
+ *
+ * @param scope The scope of all raw parameter keys.
+ * @param rawKeys Raw parameter keys, joined into a string using a semicolon
+ * (';') as the delimiter.
+ * @return A list of vendor parameter IDs, see android.hardware.audio.core.VendorParameter.
+ * @throws EX_ILLEGAL_ARGUMENT If the implementation can not parse the raw keys
+ * and prefers to signal an error.
+ */
+ @utf8InCpp String[] parseVendorParameterIds(
+ ParameterScope scope, in @utf8InCpp String rawKeys);
+
+ /**
+ * Parse raw parameter key-value pairs into vendor parameters.
+ *
+ * This method prepares arguments for a call to the 'setVendorParameters'
+ * method of an 'IModule' or an 'IStreamCommon' interface instance,
+ * depending on the provided scope.
+ *
+ * The vendor parameters returned using 'syncParameters' argument is then
+ * used to call the 'setVendorParameters' method with 'async = false', and
+ * 'asyncParameters' is used in a subsequent call to the same method, but
+ * with 'async = true'. It is not required to maintain a 1:1 correspondence
+ * between the provided key-value pairs and the elements of parsed
+ * results. If any of the returned lists of vendor parameters is empty, then
+ * the corresponding call is skipped. The implementation can either ignore
+ * keys which it does not recognize, and invalid values, or throw an
+ * error. The latter is preferred as it can help in discovering malformed
+ * key names and values.
+ *
+ * @param scope The scope of all raw key-value pairs.
+ * @param rawKeys Raw key-value pairs, separated by the "equals" sign ('='),
+ * joined into a string using a semicolon (';') as the delimiter.
+ * @param syncParameters A list of vendor parameters to be set synchronously.
+ * @param asyncParameters A list of vendor parameters to be set asynchronously.
+ * @throws EX_ILLEGAL_ARGUMENT If the implementation can not parse raw key-value
+ * pairs and prefers to signal an error.
+ */
+ void parseVendorParameters(
+ ParameterScope scope, in @utf8InCpp String rawKeysAndValues,
+ out VendorParameter[] syncParameters, out VendorParameter[] asyncParameters);
+
+ /**
+ * Parse raw value of the parameter for BT A2DP reconfiguration.
+ *
+ * This method may return any number of vendor parameters (including zero)
+ * which will be passed to the 'IBluetoothA2dp.reconfigureOffload' method.
+ *
+ * @param rawValue An unparsed value of the legacy parameter.
+ * @return A list of vendor parameters.
+ * @throws EX_ILLEGAL_ARGUMENT If the implementation can not parse the raw value.
+ */
+ VendorParameter[] parseBluetoothA2dpReconfigureOffload(in @utf8InCpp String rawValue);
+
+ /**
+ * Parse raw value of the parameter for BT LE reconfiguration.
+ *
+ * This method may return any number of vendor parameters (including zero)
+ * which will be passed to the 'IBluetoothLe.reconfigureOffload' method.
+ *
+ * @param rawValue An unparsed value of the legacy parameter.
+ * @return A list of vendor parameters.
+ * @throws EX_ILLEGAL_ARGUMENT If the implementation can not parse the raw value.
+ */
+ VendorParameter[] parseBluetoothLeReconfigureOffload(in @utf8InCpp String rawValue);
+
+ /**
+ * Process vendor parameters returned by the Audio Core HAL.
+ *
+ * This processes the result returned from a call to the
+ * 'getVendorParameters' method of an 'IModule' or an 'IStreamCommon'
+ * interface instance, depending on the provided scope.
+ *
+ * See 'parseVendorParameterIds' method for the flow description. It is not
+ * required to maintain a 1:1 correspondence between the elements of the
+ * provided list and the emitted key-value pairs. The returned string with
+ * raw key-value pairs is passed back to the framework.
+ *
+ * @param scope The scope of vendor parameters.
+ * @param parameters Vendor parameters, see android.hardware.audio.core.VendorParameter.
+ * @return Key-value pairs, separated by the "equals" sign ('='),
+ * joined into a string using a semicolon (';') as the delimiter.
+ * @throws EX_ILLEGAL_ARGUMENT If the implementation can not emit raw key-value
+ * pairs and prefers to signal an error.
+ */
+ @utf8InCpp String processVendorParameters(
+ ParameterScope scope, in VendorParameter[] parameters);
+}
diff --git a/media/audioaidlconversion/AidlConversionCppNdk.cpp b/media/audioaidlconversion/AidlConversionCppNdk.cpp
index 3b06245..4d3f9bd 100644
--- a/media/audioaidlconversion/AidlConversionCppNdk.cpp
+++ b/media/audioaidlconversion/AidlConversionCppNdk.cpp
@@ -18,6 +18,7 @@
#include <algorithm>
#include <map>
+#include <sstream>
#include <utility>
#include <vector>
@@ -50,6 +51,7 @@
using ::android::status_t;
using ::android::base::unexpected;
+using media::audio::common::AudioAttributes;
using media::audio::common::AudioChannelLayout;
using media::audio::common::AudioConfig;
using media::audio::common::AudioConfigBase;
@@ -62,6 +64,7 @@
using media::audio::common::AudioEncapsulationMetadataType;
using media::audio::common::AudioEncapsulationMode;
using media::audio::common::AudioEncapsulationType;
+using media::audio::common::AudioFlag;
using media::audio::common::AudioFormatDescription;
using media::audio::common::AudioFormatType;
using media::audio::common::AudioGain;
@@ -95,6 +98,20 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// Converters
+namespace {
+
+std::vector<std::string> splitString(const std::string& s, char separator) {
+ std::istringstream iss(s);
+ std::string t;
+ std::vector<std::string> result;
+ while (std::getline(iss, t, separator)) {
+ result.push_back(std::move(t));
+ }
+ return result;
+}
+
+} // namespace
+
::android::status_t aidl2legacy_string(std::string_view aidl, char* dest, size_t maxSize) {
if (aidl.size() > maxSize - 1) {
return BAD_VALUE;
@@ -262,12 +279,17 @@
DEFINE_INPUT_LAYOUT(MONO),
DEFINE_INPUT_LAYOUT(STEREO),
+ DEFINE_INPUT_LAYOUT(2POINT1),
DEFINE_INPUT_LAYOUT(FRONT_BACK),
+ DEFINE_INPUT_LAYOUT(TRI),
+ DEFINE_INPUT_LAYOUT(3POINT1),
// AUDIO_CHANNEL_IN_6 not supported
DEFINE_INPUT_LAYOUT(2POINT0POINT2),
DEFINE_INPUT_LAYOUT(2POINT1POINT2),
DEFINE_INPUT_LAYOUT(3POINT0POINT2),
DEFINE_INPUT_LAYOUT(3POINT1POINT2),
+ DEFINE_INPUT_LAYOUT(QUAD),
+ DEFINE_INPUT_LAYOUT(PENTA),
DEFINE_INPUT_LAYOUT(5POINT1)
#undef DEFINE_INPUT_LAYOUT
};
@@ -1799,6 +1821,156 @@
return unexpected(BAD_VALUE);
}
+ConversionResult<audio_flags_mask_t>
+aidl2legacy_AudioFlag_audio_flags_mask_t(AudioFlag aidl) {
+ switch (aidl) {
+ case AudioFlag::NONE:
+ return AUDIO_FLAG_NONE;
+ case AudioFlag::AUDIBILITY_ENFORCED:
+ return AUDIO_FLAG_AUDIBILITY_ENFORCED;
+ // The is no AudioFlag::SECURE, see the comment in the AudioFlag.aidl
+ // return AUDIO_FLAG_SECURE;
+ case AudioFlag::SCO:
+ return AUDIO_FLAG_SCO;
+ case AudioFlag::BEACON:
+ return AUDIO_FLAG_BEACON;
+ case AudioFlag::HW_AV_SYNC:
+ return AUDIO_FLAG_HW_AV_SYNC;
+ case AudioFlag::HW_HOTWORD:
+ return AUDIO_FLAG_HW_HOTWORD;
+ case AudioFlag::BYPASS_INTERRUPTION_POLICY:
+ return AUDIO_FLAG_BYPASS_INTERRUPTION_POLICY;
+ case AudioFlag::BYPASS_MUTE:
+ return AUDIO_FLAG_BYPASS_MUTE;
+ case AudioFlag::LOW_LATENCY:
+ return AUDIO_FLAG_LOW_LATENCY;
+ case AudioFlag::DEEP_BUFFER:
+ return AUDIO_FLAG_DEEP_BUFFER;
+ case AudioFlag::NO_MEDIA_PROJECTION:
+ return AUDIO_FLAG_NO_MEDIA_PROJECTION;
+ case AudioFlag::MUTE_HAPTIC:
+ return AUDIO_FLAG_MUTE_HAPTIC;
+ case AudioFlag::NO_SYSTEM_CAPTURE:
+ return AUDIO_FLAG_NO_SYSTEM_CAPTURE;
+ case AudioFlag::CAPTURE_PRIVATE:
+ return AUDIO_FLAG_CAPTURE_PRIVATE;
+ case AudioFlag::CONTENT_SPATIALIZED:
+ return AUDIO_FLAG_CONTENT_SPATIALIZED;
+ case AudioFlag::NEVER_SPATIALIZE:
+ return AUDIO_FLAG_NEVER_SPATIALIZE;
+ case AudioFlag::CALL_REDIRECTION:
+ return AUDIO_FLAG_CALL_REDIRECTION;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<AudioFlag>
+legacy2aidl_audio_flags_mask_t_AudioFlag(audio_flags_mask_t legacy) {
+ switch (legacy) {
+ case AUDIO_FLAG_NONE:
+ return AudioFlag::NONE;
+ case AUDIO_FLAG_AUDIBILITY_ENFORCED:
+ return AudioFlag::AUDIBILITY_ENFORCED;
+ case AUDIO_FLAG_SECURE:
+ return unexpected(BAD_VALUE);
+ case AUDIO_FLAG_SCO:
+ return AudioFlag::SCO;
+ case AUDIO_FLAG_BEACON:
+ return AudioFlag::BEACON;
+ case AUDIO_FLAG_HW_AV_SYNC:
+ return AudioFlag::HW_AV_SYNC;
+ case AUDIO_FLAG_HW_HOTWORD:
+ return AudioFlag::HW_HOTWORD;
+ case AUDIO_FLAG_BYPASS_INTERRUPTION_POLICY:
+ return AudioFlag::BYPASS_INTERRUPTION_POLICY;
+ case AUDIO_FLAG_BYPASS_MUTE:
+ return AudioFlag::BYPASS_MUTE;
+ case AUDIO_FLAG_LOW_LATENCY:
+ return AudioFlag::LOW_LATENCY;
+ case AUDIO_FLAG_DEEP_BUFFER:
+ return AudioFlag::DEEP_BUFFER;
+ case AUDIO_FLAG_NO_MEDIA_PROJECTION:
+ return AudioFlag::NO_MEDIA_PROJECTION;
+ case AUDIO_FLAG_MUTE_HAPTIC:
+ return AudioFlag::MUTE_HAPTIC;
+ case AUDIO_FLAG_NO_SYSTEM_CAPTURE:
+ return AudioFlag::NO_SYSTEM_CAPTURE;
+ case AUDIO_FLAG_CAPTURE_PRIVATE:
+ return AudioFlag::CAPTURE_PRIVATE;
+ case AUDIO_FLAG_CONTENT_SPATIALIZED:
+ return AudioFlag::CONTENT_SPATIALIZED;
+ case AUDIO_FLAG_NEVER_SPATIALIZE:
+ return AudioFlag::NEVER_SPATIALIZE;
+ case AUDIO_FLAG_CALL_REDIRECTION:
+ return AudioFlag::CALL_REDIRECTION;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<audio_flags_mask_t>
+aidl2legacy_int32_t_audio_flags_mask_t_mask(int32_t aidl) {
+ return convertBitmask<audio_flags_mask_t, int32_t, audio_flags_mask_t, AudioFlag>(
+ aidl, aidl2legacy_AudioFlag_audio_flags_mask_t, indexToEnum_bitmask<AudioFlag>,
+ enumToMask_bitmask<audio_flags_mask_t, audio_flags_mask_t>);
+}
+
+ConversionResult<int32_t>
+legacy2aidl_audio_flags_mask_t_int32_t_mask(audio_flags_mask_t legacy) {
+ return convertBitmask<int32_t, audio_flags_mask_t, AudioFlag, audio_flags_mask_t>(
+ legacy, legacy2aidl_audio_flags_mask_t_AudioFlag,
+ indexToEnum_bitmask<audio_flags_mask_t>,
+ enumToMask_bitmask<int32_t, AudioFlag>);
+}
+
+ConversionResult<std::string>
+aidl2legacy_AudioTags_string(const std::vector<std::string>& aidl) {
+ std::ostringstream tagsBuffer;
+ bool hasValue = false;
+ for (const auto& tag : aidl) {
+ if (hasValue) {
+ tagsBuffer << AUDIO_ATTRIBUTES_TAGS_SEPARATOR;
+ }
+ if (strchr(tag.c_str(), AUDIO_ATTRIBUTES_TAGS_SEPARATOR) == nullptr) {
+ tagsBuffer << tag;
+ hasValue = true;
+ } else {
+ ALOGE("Tag is ill-formed: \"%s\"", tag.c_str());
+ return unexpected(BAD_VALUE);
+ }
+ }
+ return tagsBuffer.str();
+}
+
+ConversionResult<std::vector<std::string>>
+legacy2aidl_string_AudioTags(const std::string& legacy) {
+ return splitString(legacy, AUDIO_ATTRIBUTES_TAGS_SEPARATOR);
+}
+
+ConversionResult<audio_attributes_t>
+aidl2legacy_AudioAttributes_audio_attributes_t(const AudioAttributes& aidl) {
+ audio_attributes_t legacy;
+ legacy.content_type = VALUE_OR_RETURN(
+ aidl2legacy_AudioContentType_audio_content_type_t(aidl.contentType));
+ legacy.usage = VALUE_OR_RETURN(aidl2legacy_AudioUsage_audio_usage_t(aidl.usage));
+ legacy.source = VALUE_OR_RETURN(aidl2legacy_AudioSource_audio_source_t(aidl.source));
+ legacy.flags = VALUE_OR_RETURN(aidl2legacy_int32_t_audio_flags_mask_t_mask(aidl.flags));
+ auto tagsString = VALUE_OR_RETURN(aidl2legacy_AudioTags_string(aidl.tags));
+ RETURN_IF_ERROR(aidl2legacy_string(tagsString, legacy.tags, sizeof(legacy.tags)));
+ return legacy;
+}
+
+ConversionResult<AudioAttributes>
+legacy2aidl_audio_attributes_t_AudioAttributes(const audio_attributes_t& legacy) {
+ AudioAttributes aidl;
+ aidl.contentType = VALUE_OR_RETURN(
+ legacy2aidl_audio_content_type_t_AudioContentType(legacy.content_type));
+ aidl.usage = VALUE_OR_RETURN(legacy2aidl_audio_usage_t_AudioUsage(legacy.usage));
+ aidl.source = VALUE_OR_RETURN(legacy2aidl_audio_source_t_AudioSource(legacy.source));
+ aidl.flags = VALUE_OR_RETURN(legacy2aidl_audio_flags_mask_t_int32_t_mask(legacy.flags));
+ auto tagsString = VALUE_OR_RETURN(legacy2aidl_string(legacy.tags, sizeof(legacy.tags)));
+ aidl.tags = VALUE_OR_RETURN(legacy2aidl_string_AudioTags(tagsString));
+ return aidl;
+}
ConversionResult<audio_encapsulation_mode_t>
aidl2legacy_AudioEncapsulationMode_audio_encapsulation_mode_t(AudioEncapsulationMode aidl) {
diff --git a/media/audioaidlconversion/AidlConversionNdkCpp.cpp b/media/audioaidlconversion/AidlConversionNdkCpp.cpp
index c64a074..ecd2e5e 100644
--- a/media/audioaidlconversion/AidlConversionNdkCpp.cpp
+++ b/media/audioaidlconversion/AidlConversionNdkCpp.cpp
@@ -15,6 +15,7 @@
*/
#include <algorithm>
+#include <regex>
#include <type_traits>
#define LOG_TAG "AidlConversionNdkCpp"
@@ -34,6 +35,24 @@
namespace {
+bool isVendorExtension(const std::string& s) {
+ // Per definition in AudioAttributes.aidl and {Playback|Record}TrackMetadata.aidl
+ static const std::regex vendorExtension("VX_[A-Z0-9]{3,}_[_A-Z0-9]+");
+ return std::regex_match(s.begin(), s.end(), vendorExtension);
+}
+
+inline bool isNotVendorExtension(const std::string& s) { return !isVendorExtension(s); }
+
+void filterOutNonVendorTagsInPlace(std::vector<std::string>& tags) {
+ if (std::find_if(tags.begin(), tags.end(), isNotVendorExtension) == tags.end()) {
+ return;
+ }
+ std::vector<std::string> temp;
+ temp.reserve(tags.size());
+ std::copy_if(tags.begin(), tags.end(), std::back_inserter(temp), isVendorExtension);
+ tags = std::move(temp);
+}
+
// cpp2ndk and ndk2cpp are universal converters which work for any type,
// however they are not the most efficient way to convert due to extra
// marshaling / unmarshaling step.
@@ -99,12 +118,15 @@
} // namespace
-#define GENERATE_CONVERTERS(packageName, className) \
- ConversionResult<::aidl::packageName::className> cpp2ndk_##className( \
+#define GENERATE_CONVERTERS(packageName, className) \
+ GENERATE_CONVERTERS_IMPL(packageName, _, className)
+
+#define GENERATE_CONVERTERS_IMPL(packageName, prefix, className) \
+ ConversionResult<::aidl::packageName::className> cpp2ndk##prefix##className( \
const ::packageName::className& cpp) { \
return cpp2ndk<::aidl::packageName::className>(cpp); \
} \
- ConversionResult<::packageName::className> ndk2cpp_##className( \
+ ConversionResult<::packageName::className> ndk2cpp##prefix##className( \
const ::aidl::packageName::className& ndk) { \
return ndk2cpp<::packageName::className>(ndk); \
}
@@ -120,10 +142,46 @@
}
GENERATE_CONVERTERS(android::media::audio::common, AudioFormatDescription);
-GENERATE_CONVERTERS(android::media::audio::common, AudioHalEngineConfig);
+GENERATE_CONVERTERS_IMPL(android::media::audio::common, _Impl_, AudioHalEngineConfig);
GENERATE_CONVERTERS(android::media::audio::common, AudioMMapPolicyInfo);
GENERATE_ENUM_CONVERTERS(android::media::audio::common, AudioMMapPolicyType);
GENERATE_ENUM_CONVERTERS(android::media::audio::common, AudioMode);
GENERATE_CONVERTERS(android::media::audio::common, AudioPort);
+namespace {
+
+// Filter out all AudioAttributes tags that do not conform to the vendor extension pattern.
+template<typename T>
+void filterOutNonVendorTags(T& audioHalEngineConfig) {
+ for (auto& strategy : audioHalEngineConfig.productStrategies) {
+ for (auto& group : strategy.attributesGroups) {
+ for (auto& attr : group.attributes) {
+ filterOutNonVendorTagsInPlace(attr.tags);
+ }
+ }
+ }
+}
+
+} // namespace
+
+ConversionResult<::aidl::android::media::audio::common::AudioHalEngineConfig>
+cpp2ndk_AudioHalEngineConfig(const ::android::media::audio::common::AudioHalEngineConfig& cpp) {
+ auto conv = cpp2ndk_Impl_AudioHalEngineConfig(cpp);
+ if (conv.ok()) {
+ filterOutNonVendorTags(conv.value());
+ }
+ return conv;
+}
+
+ConversionResult<::android::media::audio::common::AudioHalEngineConfig>
+ndk2cpp_AudioHalEngineConfig(
+ const ::aidl::android::media::audio::common::AudioHalEngineConfig& ndk) {
+ auto conv = ndk2cpp_Impl_AudioHalEngineConfig(ndk);
+ if (conv.ok()) {
+ filterOutNonVendorTags(conv.value());
+ }
+ return conv;
+}
+
+
} // namespace android
diff --git a/media/audioaidlconversion/TEST_MAPPING b/media/audioaidlconversion/TEST_MAPPING
index 903b88a..216bc12 100644
--- a/media/audioaidlconversion/TEST_MAPPING
+++ b/media/audioaidlconversion/TEST_MAPPING
@@ -1,6 +1,7 @@
{
"presubmit": [
{
+ "name": "audio_aidl_conversion_tests",
"name": "audio_aidl_ndk_conversion_tests",
"name": "audio_aidl_ndk_cpp_conversion_tests"
}
diff --git a/media/audioaidlconversion/include/media/AidlConversionCppNdk-impl.h b/media/audioaidlconversion/include/media/AidlConversionCppNdk-impl.h
index bc9d4d5..7268464 100644
--- a/media/audioaidlconversion/include/media/AidlConversionCppNdk-impl.h
+++ b/media/audioaidlconversion/include/media/AidlConversionCppNdk-impl.h
@@ -37,6 +37,7 @@
#define PREFIX(f) <f>
#endif
+#include PREFIX(android/media/audio/common/AudioAttributes.h)
#include PREFIX(android/media/audio/common/AudioChannelLayout.h)
#include PREFIX(android/media/audio/common/AudioConfig.h)
#include PREFIX(android/media/audio/common/AudioConfigBase.h)
@@ -46,6 +47,7 @@
#include PREFIX(android/media/audio/common/AudioEncapsulationMetadataType.h)
#include PREFIX(android/media/audio/common/AudioEncapsulationMode.h)
#include PREFIX(android/media/audio/common/AudioEncapsulationType.h)
+#include PREFIX(android/media/audio/common/AudioFlag.h)
#include PREFIX(android/media/audio/common/AudioFormatDescription.h)
#include PREFIX(android/media/audio/common/AudioGain.h)
#include PREFIX(android/media/audio/common/AudioGainConfig.h)
@@ -355,6 +357,26 @@
ConversionResult<media::audio::common::AudioUsage> legacy2aidl_audio_usage_t_AudioUsage(
audio_usage_t legacy);
+ConversionResult<audio_flags_mask_t>
+aidl2legacy_AudioFlag_audio_flags_mask_t(media::audio::common::AudioFlag aidl);
+ConversionResult<media::audio::common::AudioFlag>
+legacy2aidl_audio_flags_mask_t_AudioFlag(audio_flags_mask_t legacy);
+
+ConversionResult<audio_flags_mask_t>
+aidl2legacy_int32_t_audio_flags_mask_t_mask(int32_t aidl);
+ConversionResult<int32_t>
+legacy2aidl_audio_flags_mask_t_int32_t_mask(audio_flags_mask_t legacy);
+
+ConversionResult<std::string>
+aidl2legacy_AudioTags_string(const std::vector<std::string>& aidl);
+ConversionResult<std::vector<std::string>>
+legacy2aidl_string_AudioTags(const std::string& legacy);
+
+ConversionResult<audio_attributes_t>
+aidl2legacy_AudioAttributes_audio_attributes_t(const media::audio::common::AudioAttributes& aidl);
+ConversionResult<media::audio::common::AudioAttributes>
+legacy2aidl_audio_attributes_t_AudioAttributes(const audio_attributes_t& legacy);
+
ConversionResult<audio_uuid_t> aidl2legacy_AudioUuid_audio_uuid_t(
const media::audio::common::AudioUuid &aidl);
ConversionResult<media::audio::common::AudioUuid> legacy2aidl_audio_uuid_t_AudioUuid(
diff --git a/media/audioaidlconversion/include/media/AidlConversionUtil-impl.h b/media/audioaidlconversion/include/media/AidlConversionUtil-impl.h
index f49f681..656d76a 100644
--- a/media/audioaidlconversion/include/media/AidlConversionUtil-impl.h
+++ b/media/audioaidlconversion/include/media/AidlConversionUtil-impl.h
@@ -119,6 +119,20 @@
}
/**
+ * A generic template that helps convert containers of convertible types without
+ * using an intermediate container.
+ */
+template<typename InputContainer, typename OutputContainer, typename Func>
+::android::status_t convertContainer(const InputContainer& input, OutputContainer* output,
+ const Func& itemConversion) {
+ auto ins = std::inserter(*output, output->begin());
+ for (const auto& item : input) {
+ *ins = VALUE_OR_RETURN_STATUS(itemConversion(item));
+ }
+ return ::android::OK;
+}
+
+/**
* A generic template that helps convert containers of convertible types.
*/
template<typename OutputContainer, typename InputContainer, typename Func>
@@ -208,6 +222,34 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// Utilities for handling bitmasks.
+// Some AIDL enums are specified using bit indices, for example:
+// `AidlEnum { FOO = 0, BAR = 1, BAZ = 2' }`
+// while corresponding legacy types universally uses actual bitmasks, for example:
+// `enum legacy_enum_t { LEGACY_FOO = 1 << 0, LEGACY_BAR = 1 << 1, LEGACY_BAZ = 1 << 2 }`
+// There is also the third type used to store the resulting mask, which is combined
+// from individual bits. In AIDL this is typically an int (`int32_t`), in legacy types this
+// is often the enum type itself (although, strictly this is not correct since masks are not
+// declared as part of the enum type). The bit index value always has an integer type.
+//
+// `indexToEnum_index` constructs an instance of the enum from an index,
+// for example `AidlEnum::BAR` from `1`.
+// `indexToEnum_bitmask` produces a corresponding legacy bitmask enum instance,
+// for example, `LEGACY_BAR` (`2`) from `1`.
+// `enumToMask_bitmask` simply casts an enum type to a bitmask type.
+// `enumToMask_index` creates a mask from an enum type which specifies an index.
+//
+// All these functions can be plugged into `convertBitmask`. For example, to implement
+// conversion from `AidlEnum` to `legacy_enum_t`, with a mask stored in `int32_t`,
+// the following call needs to be made:
+// convertBitmask<legacy_enum_t /*DestMask*/, int32_t /*SrcMask*/,
+// legacy_enum_t /*DestEnum*/, AidlEnum /*SrcEnum*/>(
+// maskField /*int32_t*/, aidl2legacy_AidlEnum_legacy_enum_t /*enumConversion*/,
+// indexToEnum_index<AidlEnum> /*srcIndexToEnum*/,
+// enumToMask_bitmask<legacy_enum_t, legacy_enum_t> /*destEnumToMask*/)
+//
+// The only extra function needed is for mapping between corresponding enum values
+// of the AidlEnum and the legacy_enum_t. Note that the mapping is between values
+// of enums, for example, `AidlEnum::BAZ` maps to `LEGACY_BAZ` and vice versa.
template<typename Enum>
Enum indexToEnum_index(int index) {
diff --git a/media/audioaidlconversion/tests/audio_aidl_ndk_conversion_tests.cpp b/media/audioaidlconversion/tests/audio_aidl_ndk_conversion_tests.cpp
index c505e60..60727b4 100644
--- a/media/audioaidlconversion/tests/audio_aidl_ndk_conversion_tests.cpp
+++ b/media/audioaidlconversion/tests/audio_aidl_ndk_conversion_tests.cpp
@@ -19,6 +19,7 @@
#include <gtest/gtest.h>
+#include <media/AidlConversionCppNdk.h>
#include <media/AidlConversionNdk.h>
namespace {
@@ -89,3 +90,48 @@
ASSERT_EQ(1, convBack.value().tags.size());
EXPECT_EQ(initial.tags[1], convBack.value().tags[0]);
}
+
+class AudioTagsRoundTripTest : public testing::TestWithParam<std::vector<std::string>>
+{
+};
+TEST_P(AudioTagsRoundTripTest, Aidl2Legacy2Aidl) {
+ const auto& initial = GetParam();
+ auto conv = aidl2legacy_AudioTags_string(initial);
+ ASSERT_TRUE(conv.ok());
+ auto convBack = legacy2aidl_string_AudioTags(conv.value());
+ ASSERT_TRUE(convBack.ok());
+ EXPECT_EQ(initial, convBack.value());
+}
+INSTANTIATE_TEST_SUITE_P(AudioTagsRoundTrip, AudioTagsRoundTripTest,
+ testing::Values(std::vector<std::string>{},
+ std::vector<std::string>{"VX_GOOGLE_41"},
+ std::vector<std::string>{"VX_GOOGLE_41", "VX_GOOGLE_42"}));
+
+TEST(AudioTags, NonVendorTagsAllowed) {
+ const std::string separator(1, AUDIO_ATTRIBUTES_TAGS_SEPARATOR);
+ const std::vector<std::string> initial{"random_string", "VX_GOOGLE_42"};
+ auto conv = aidl2legacy_AudioTags_string(initial);
+ ASSERT_TRUE(conv.ok());
+ EXPECT_EQ("random_string" + separator + "VX_GOOGLE_42", conv.value());
+}
+
+TEST(AudioTags, IllFormedAidlTag) {
+ const std::string separator(1, AUDIO_ATTRIBUTES_TAGS_SEPARATOR);
+ {
+ const std::vector<std::string> initial{"VX_GOOGLE" + separator + "42", "VX_GOOGLE_42"};
+ auto conv = aidl2legacy_AudioTags_string(initial);
+ if (conv.ok()) {
+ EXPECT_EQ("VX_GOOGLE_42", conv.value());
+ }
+ // Failing this conversion is also OK. The result depends on whether the conversion
+ // only passes through vendor tags.
+ }
+ {
+ const std::vector<std::string> initial{
+ "random_string", "random" + separator + "string", "VX_GOOGLE_42"};
+ auto conv = aidl2legacy_AudioTags_string(initial);
+ if (conv.ok()) {
+ EXPECT_EQ("VX_GOOGLE_42", conv.value());
+ }
+ }
+}
diff --git a/media/audioaidlconversion/tests/audio_aidl_ndk_cpp_conversion_tests.cpp b/media/audioaidlconversion/tests/audio_aidl_ndk_cpp_conversion_tests.cpp
index 735a14b..206c35b 100644
--- a/media/audioaidlconversion/tests/audio_aidl_ndk_cpp_conversion_tests.cpp
+++ b/media/audioaidlconversion/tests/audio_aidl_ndk_cpp_conversion_tests.cpp
@@ -125,3 +125,12 @@
INSTANTIATE_TEST_SUITE_P(AudioFormatDescriptionRoundTrip, AudioFormatDescriptionRoundTripTest,
testing::Values(make_AFD_Invalid(), make_AFD_Default(), make_AFD_Pcm16Bit(),
make_AFD_Bitstream(), make_AFD_Encap(), make_AFD_Encap_with_Enc()));
+
+TEST(AudioPortRoundTripTest, Ndk2Cpp2Ndk) {
+ const AudioPort initial;
+ auto conv = ndk2cpp_AudioPort(initial);
+ ASSERT_TRUE(conv.ok());
+ auto convBack = cpp2ndk_AudioPort(conv.value());
+ ASSERT_TRUE(convBack.ok());
+ EXPECT_EQ(initial, convBack.value());
+}
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp
index 5e53acc..86fd8ab 100644
--- a/media/codec2/sfplugin/CCodec.cpp
+++ b/media/codec2/sfplugin/CCodec.cpp
@@ -1808,6 +1808,10 @@
ACTION_CODE_FATAL);
return;
}
+
+ // clear the deadline after the component starts
+ setDeadline(TimePoint::max(), 0ms, "none");
+
sp<AMessage> inputFormat;
sp<AMessage> outputFormat;
status_t err2 = OK;
diff --git a/media/libaudioclient/AidlConversion.cpp b/media/libaudioclient/AidlConversion.cpp
index b32667e..2377fc8 100644
--- a/media/libaudioclient/AidlConversion.cpp
+++ b/media/libaudioclient/AidlConversion.cpp
@@ -480,129 +480,6 @@
return aidl;
}
-ConversionResult<audio_flags_mask_t>
-aidl2legacy_AudioFlag_audio_flags_mask_t(media::AudioFlag aidl) {
- switch (aidl) {
- case media::AudioFlag::AUDIBILITY_ENFORCED:
- return AUDIO_FLAG_AUDIBILITY_ENFORCED;
- case media::AudioFlag::SECURE:
- return AUDIO_FLAG_SECURE;
- case media::AudioFlag::SCO:
- return AUDIO_FLAG_SCO;
- case media::AudioFlag::BEACON:
- return AUDIO_FLAG_BEACON;
- case media::AudioFlag::HW_AV_SYNC:
- return AUDIO_FLAG_HW_AV_SYNC;
- case media::AudioFlag::HW_HOTWORD:
- return AUDIO_FLAG_HW_HOTWORD;
- case media::AudioFlag::BYPASS_INTERRUPTION_POLICY:
- return AUDIO_FLAG_BYPASS_INTERRUPTION_POLICY;
- case media::AudioFlag::BYPASS_MUTE:
- return AUDIO_FLAG_BYPASS_MUTE;
- case media::AudioFlag::LOW_LATENCY:
- return AUDIO_FLAG_LOW_LATENCY;
- case media::AudioFlag::DEEP_BUFFER:
- return AUDIO_FLAG_DEEP_BUFFER;
- case media::AudioFlag::NO_MEDIA_PROJECTION:
- return AUDIO_FLAG_NO_MEDIA_PROJECTION;
- case media::AudioFlag::MUTE_HAPTIC:
- return AUDIO_FLAG_MUTE_HAPTIC;
- case media::AudioFlag::NO_SYSTEM_CAPTURE:
- return AUDIO_FLAG_NO_SYSTEM_CAPTURE;
- case media::AudioFlag::CAPTURE_PRIVATE:
- return AUDIO_FLAG_CAPTURE_PRIVATE;
- case media::AudioFlag::CONTENT_SPATIALIZED:
- return AUDIO_FLAG_CONTENT_SPATIALIZED;
- case media::AudioFlag::NEVER_SPATIALIZE:
- return AUDIO_FLAG_NEVER_SPATIALIZE;
- case media::AudioFlag::CALL_REDIRECTION:
- return AUDIO_FLAG_CALL_REDIRECTION;
- }
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<media::AudioFlag>
-legacy2aidl_audio_flags_mask_t_AudioFlag(audio_flags_mask_t legacy) {
- switch (legacy) {
- case AUDIO_FLAG_NONE:
- return unexpected(BAD_VALUE);
- case AUDIO_FLAG_AUDIBILITY_ENFORCED:
- return media::AudioFlag::AUDIBILITY_ENFORCED;
- case AUDIO_FLAG_SECURE:
- return media::AudioFlag::SECURE;
- case AUDIO_FLAG_SCO:
- return media::AudioFlag::SCO;
- case AUDIO_FLAG_BEACON:
- return media::AudioFlag::BEACON;
- case AUDIO_FLAG_HW_AV_SYNC:
- return media::AudioFlag::HW_AV_SYNC;
- case AUDIO_FLAG_HW_HOTWORD:
- return media::AudioFlag::HW_HOTWORD;
- case AUDIO_FLAG_BYPASS_INTERRUPTION_POLICY:
- return media::AudioFlag::BYPASS_INTERRUPTION_POLICY;
- case AUDIO_FLAG_BYPASS_MUTE:
- return media::AudioFlag::BYPASS_MUTE;
- case AUDIO_FLAG_LOW_LATENCY:
- return media::AudioFlag::LOW_LATENCY;
- case AUDIO_FLAG_DEEP_BUFFER:
- return media::AudioFlag::DEEP_BUFFER;
- case AUDIO_FLAG_NO_MEDIA_PROJECTION:
- return media::AudioFlag::NO_MEDIA_PROJECTION;
- case AUDIO_FLAG_MUTE_HAPTIC:
- return media::AudioFlag::MUTE_HAPTIC;
- case AUDIO_FLAG_NO_SYSTEM_CAPTURE:
- return media::AudioFlag::NO_SYSTEM_CAPTURE;
- case AUDIO_FLAG_CAPTURE_PRIVATE:
- return media::AudioFlag::CAPTURE_PRIVATE;
- case AUDIO_FLAG_CONTENT_SPATIALIZED:
- return media::AudioFlag::CONTENT_SPATIALIZED;
- case AUDIO_FLAG_NEVER_SPATIALIZE:
- return media::AudioFlag::NEVER_SPATIALIZE;
- case AUDIO_FLAG_CALL_REDIRECTION:
- return media::AudioFlag::CALL_REDIRECTION;
- }
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<audio_flags_mask_t>
-aidl2legacy_int32_t_audio_flags_mask_t_mask(int32_t aidl) {
- return convertBitmask<audio_flags_mask_t, int32_t, audio_flags_mask_t, media::AudioFlag>(
- aidl, aidl2legacy_AudioFlag_audio_flags_mask_t, indexToEnum_index<media::AudioFlag>,
- enumToMask_bitmask<audio_flags_mask_t, audio_flags_mask_t>);
-}
-
-ConversionResult<int32_t>
-legacy2aidl_audio_flags_mask_t_int32_t_mask(audio_flags_mask_t legacy) {
- return convertBitmask<int32_t, audio_flags_mask_t, media::AudioFlag, audio_flags_mask_t>(
- legacy, legacy2aidl_audio_flags_mask_t_AudioFlag,
- indexToEnum_bitmask<audio_flags_mask_t>,
- enumToMask_index<int32_t, media::AudioFlag>);
-}
-
-ConversionResult<audio_attributes_t>
-aidl2legacy_AudioAttributesInternal_audio_attributes_t(const media::AudioAttributesInternal& aidl) {
- audio_attributes_t legacy;
- legacy.content_type = VALUE_OR_RETURN(
- aidl2legacy_AudioContentType_audio_content_type_t(aidl.contentType));
- legacy.usage = VALUE_OR_RETURN(aidl2legacy_AudioUsage_audio_usage_t(aidl.usage));
- legacy.source = VALUE_OR_RETURN(aidl2legacy_AudioSource_audio_source_t(aidl.source));
- legacy.flags = VALUE_OR_RETURN(aidl2legacy_int32_t_audio_flags_mask_t_mask(aidl.flags));
- RETURN_IF_ERROR(aidl2legacy_string(aidl.tags, legacy.tags, sizeof(legacy.tags)));
- return legacy;
-}
-
-ConversionResult<media::AudioAttributesInternal>
-legacy2aidl_audio_attributes_t_AudioAttributesInternal(const audio_attributes_t& legacy) {
- media::AudioAttributesInternal aidl;
- aidl.contentType = VALUE_OR_RETURN(
- legacy2aidl_audio_content_type_t_AudioContentType(legacy.content_type));
- aidl.usage = VALUE_OR_RETURN(legacy2aidl_audio_usage_t_AudioUsage(legacy.usage));
- aidl.source = VALUE_OR_RETURN(legacy2aidl_audio_source_t_AudioSource(legacy.source));
- aidl.flags = VALUE_OR_RETURN(legacy2aidl_audio_flags_mask_t_int32_t_mask(legacy.flags));
- aidl.tags = VALUE_OR_RETURN(legacy2aidl_string(legacy.tags, sizeof(legacy.tags)));
- return aidl;
-}
-
ConversionResult<sp<IMemory>>
aidl2legacy_SharedFileRegion_IMemory(const media::SharedFileRegion& aidl) {
sp<IMemory> legacy;
@@ -651,7 +528,7 @@
ConversionResult<media::AudioTimestampInternal>
legacy2aidl_AudioTimestamp_AudioTimestampInternal(const AudioTimestamp& legacy) {
media::AudioTimestampInternal aidl;
- aidl.position = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.mPosition));
+ aidl.position = VALUE_OR_RETURN(convertIntegral<int64_t>(legacy.mPosition));
aidl.sec = VALUE_OR_RETURN(convertIntegral<int64_t>(legacy.mTime.tv_sec));
aidl.nsec = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.mTime.tv_nsec));
return aidl;
diff --git a/media/libaudioclient/Android.bp b/media/libaudioclient/Android.bp
index 7122af1..01e3d53 100644
--- a/media/libaudioclient/Android.bp
+++ b/media/libaudioclient/Android.bp
@@ -281,10 +281,8 @@
double_loadable: true,
local_include_dir: "aidl",
srcs: [
- "aidl/android/media/AudioAttributesInternal.aidl",
"aidl/android/media/AudioClient.aidl",
"aidl/android/media/AudioDirectMode.aidl",
- "aidl/android/media/AudioFlag.aidl",
"aidl/android/media/AudioGainSys.aidl",
"aidl/android/media/AudioHalVersion.aidl",
"aidl/android/media/AudioHwModule.aidl",
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index 4527e0f..7cec2e8 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -1066,8 +1066,8 @@
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return NO_INIT;
- media::AudioAttributesInternal attrAidl = VALUE_OR_RETURN_STATUS(
- legacy2aidl_audio_attributes_t_AudioAttributesInternal(*attr));
+ media::audio::common::AudioAttributes attrAidl = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_attributes_t_AudioAttributes(*attr));
int32_t sessionAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_session_t_int32_t(session));
AudioConfig configAidl = VALUE_OR_RETURN_STATUS(
legacy2aidl_audio_config_t_AudioConfig(*config, false /*isInput*/));
@@ -1106,7 +1106,7 @@
*isSpatialized = responseAidl.isSpatialized;
*isBitPerfect = responseAidl.isBitPerfect;
*attr = VALUE_OR_RETURN_STATUS(
- aidl2legacy_AudioAttributesInternal_audio_attributes_t(responseAidl.attr));
+ aidl2legacy_AudioAttributes_audio_attributes_t(responseAidl.attr));
return OK;
}
@@ -1171,8 +1171,8 @@
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return NO_INIT;
- media::AudioAttributesInternal attrAidl = VALUE_OR_RETURN_STATUS(
- legacy2aidl_audio_attributes_t_AudioAttributesInternal(*attr));
+ media::audio::common::AudioAttributes attrAidl = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_attributes_t_AudioAttributes(*attr));
int32_t inputAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_io_handle_t_int32_t(*input));
int32_t riidAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_unique_id_t_int32_t(riid));
int32_t sessionAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_session_t_int32_t(session));
@@ -1293,8 +1293,8 @@
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
- media::AudioAttributesInternal attrAidl = VALUE_OR_RETURN_STATUS(
- legacy2aidl_audio_attributes_t_AudioAttributesInternal(attr));
+ media::audio::common::AudioAttributes attrAidl = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_attributes_t_AudioAttributes(attr));
int32_t indexAidl = VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(index));
AudioDeviceDescription deviceAidl = VALUE_OR_RETURN_STATUS(
legacy2aidl_audio_devices_t_AudioDeviceDescription(device));
@@ -1308,8 +1308,8 @@
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
- media::AudioAttributesInternal attrAidl = VALUE_OR_RETURN_STATUS(
- legacy2aidl_audio_attributes_t_AudioAttributesInternal(attr));
+ media::audio::common::AudioAttributes attrAidl = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_attributes_t_AudioAttributes(attr));
AudioDeviceDescription deviceAidl = VALUE_OR_RETURN_STATUS(
legacy2aidl_audio_devices_t_AudioDeviceDescription(device));
int32_t indexAidl;
@@ -1323,8 +1323,8 @@
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
- media::AudioAttributesInternal attrAidl = VALUE_OR_RETURN_STATUS(
- legacy2aidl_audio_attributes_t_AudioAttributesInternal(attr));
+ media::audio::common::AudioAttributes attrAidl = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_attributes_t_AudioAttributes(attr));
int32_t indexAidl;
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
aps->getMaxVolumeIndexForAttributes(attrAidl, &indexAidl)));
@@ -1336,8 +1336,8 @@
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
- media::AudioAttributesInternal attrAidl = VALUE_OR_RETURN_STATUS(
- legacy2aidl_audio_attributes_t_AudioAttributesInternal(attr));
+ media::audio::common::AudioAttributes attrAidl = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_attributes_t_AudioAttributes(attr));
int32_t indexAidl;
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
aps->getMinVolumeIndexForAttributes(attrAidl, &indexAidl)));
@@ -1369,8 +1369,8 @@
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
- media::AudioAttributesInternal aaAidl = VALUE_OR_RETURN_STATUS(
- legacy2aidl_audio_attributes_t_AudioAttributesInternal(aa));
+ media::audio::common::AudioAttributes aaAidl = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_attributes_t_AudioAttributes(aa));
std::vector<AudioDevice> retAidl;
RETURN_STATUS_IF_ERROR(
statusTFromBinderStatus(aps->getDevicesForAttributes(aaAidl, forVolume, &retAidl)));
@@ -1888,8 +1888,8 @@
media::AudioPortConfigFw sourceAidl = VALUE_OR_RETURN_STATUS(
legacy2aidl_audio_port_config_AudioPortConfigFw(*source));
- media::AudioAttributesInternal attributesAidl = VALUE_OR_RETURN_STATUS(
- legacy2aidl_audio_attributes_t_AudioAttributesInternal(*attributes));
+ media::audio::common::AudioAttributes attributesAidl = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_attributes_t_AudioAttributes(*attributes));
int32_t portIdAidl;
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
aps->startAudioSource(sourceAidl, attributesAidl, &portIdAidl)));
@@ -2175,8 +2175,8 @@
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
- media::AudioAttributesInternal aaAidl = VALUE_OR_RETURN_STATUS(
- legacy2aidl_audio_attributes_t_AudioAttributesInternal(aa));
+ media::audio::common::AudioAttributes aaAidl = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_attributes_t_AudioAttributes(aa));
int32_t productStrategyAidl;
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
@@ -2205,8 +2205,8 @@
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
- media::AudioAttributesInternal aaAidl = VALUE_OR_RETURN_STATUS(
- legacy2aidl_audio_attributes_t_AudioAttributesInternal(aa));
+ media::audio::common::AudioAttributes aaAidl = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_attributes_t_AudioAttributes(aa));
int32_t volumeGroupAidl;
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
aps->getVolumeGroupFromAudioAttributes(aaAidl, fallbackOnDefault, &volumeGroupAidl)));
@@ -2411,8 +2411,8 @@
audio_attributes_t attributes = attr != nullptr ? *attr : AUDIO_ATTRIBUTES_INITIALIZER;
audio_config_t configuration = config != nullptr ? *config : AUDIO_CONFIG_INITIALIZER;
- std::optional<media::AudioAttributesInternal> attrAidl = VALUE_OR_RETURN_STATUS(
- legacy2aidl_audio_attributes_t_AudioAttributesInternal(attributes));
+ std::optional<media::audio::common::AudioAttributes> attrAidl = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_attributes_t_AudioAttributes(attributes));
std::optional<AudioConfig> configAidl = VALUE_OR_RETURN_STATUS(
legacy2aidl_audio_config_t_AudioConfig(configuration, false /*isInput*/));
std::vector<AudioDevice> devicesAidl = VALUE_OR_RETURN_STATUS(
@@ -2449,8 +2449,8 @@
return PERMISSION_DENIED;
}
- media::AudioAttributesInternal attrAidl = VALUE_OR_RETURN_STATUS(
- legacy2aidl_audio_attributes_t_AudioAttributesInternal(*attr));
+ media::audio::common::AudioAttributes attrAidl = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_attributes_t_AudioAttributes(*attr));
AudioConfig configAidl = VALUE_OR_RETURN_STATUS(
legacy2aidl_audio_config_t_AudioConfig(*config, false /*isInput*/));
@@ -2473,8 +2473,8 @@
return PERMISSION_DENIED;
}
- media::AudioAttributesInternal attrAidl = VALUE_OR_RETURN_STATUS(
- legacy2aidl_audio_attributes_t_AudioAttributesInternal(*attr));
+ media::audio::common::AudioAttributes attrAidl = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_attributes_t_AudioAttributes(*attr));
std::vector<media::audio::common::AudioProfile> audioProfilesAidl;
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
@@ -2653,8 +2653,8 @@
return PERMISSION_DENIED;
}
- media::AudioAttributesInternal attrAidl = VALUE_OR_RETURN_STATUS(
- legacy2aidl_audio_attributes_t_AudioAttributesInternal(*attr));
+ media::audio::common::AudioAttributes attrAidl = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_attributes_t_AudioAttributes(*attr));
media::AudioMixerAttributesInternal mixerAttrAidl = VALUE_OR_RETURN_STATUS(
legacy2aidl_audio_mixer_attributes_t_AudioMixerAttributesInternal(*mixerAttr));
int32_t uidAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_uid_t_int32_t(uid));
@@ -2673,8 +2673,8 @@
return PERMISSION_DENIED;
}
- media::AudioAttributesInternal attrAidl = VALUE_OR_RETURN_STATUS(
- legacy2aidl_audio_attributes_t_AudioAttributesInternal(*attr));
+ media::audio::common::AudioAttributes attrAidl = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_attributes_t_AudioAttributes(*attr));
int32_t portIdAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_port_handle_t_int32_t(portId));
std::optional<media::AudioMixerAttributesInternal> _aidlReturn;
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
@@ -2696,8 +2696,8 @@
return PERMISSION_DENIED;
}
- media::AudioAttributesInternal attrAidl = VALUE_OR_RETURN_STATUS(
- legacy2aidl_audio_attributes_t_AudioAttributesInternal(*attr));
+ media::audio::common::AudioAttributes attrAidl = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_attributes_t_AudioAttributes(*attr));
int32_t uidAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_uid_t_int32_t(uid));
int32_t portIdAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_port_handle_t_int32_t(portId));
return statusTFromBinderStatus(
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index f01b653..359c140 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -178,8 +178,8 @@
auto result = [&]() -> ConversionResult<bool> {
media::audio::common::AudioConfigBase configAidl = VALUE_OR_RETURN(
legacy2aidl_audio_config_base_t_AudioConfigBase(config, false /*isInput*/));
- media::AudioAttributesInternal attributesAidl = VALUE_OR_RETURN(
- legacy2aidl_audio_attributes_t_AudioAttributesInternal(attributes));
+ media::audio::common::AudioAttributes attributesAidl = VALUE_OR_RETURN(
+ legacy2aidl_audio_attributes_t_AudioAttributes(attributes));
bool retAidl;
RETURN_IF_ERROR(aidl_utils::statusTFromBinderStatus(
aps->isDirectOutputSupported(configAidl, attributesAidl, &retAidl)));
diff --git a/media/libaudioclient/AudioVolumeGroup.cpp b/media/libaudioclient/AudioVolumeGroup.cpp
index 978599e..c4ca5b9 100644
--- a/media/libaudioclient/AudioVolumeGroup.cpp
+++ b/media/libaudioclient/AudioVolumeGroup.cpp
@@ -49,9 +49,9 @@
aidl.groupId = VALUE_OR_RETURN(legacy2aidl_volume_group_t_int32_t(legacy.getId()));
aidl.name = legacy.getName();
aidl.audioAttributes = VALUE_OR_RETURN(
- convertContainer<std::vector<media::AudioAttributesInternal>>(
+ convertContainer<std::vector<media::audio::common::AudioAttributes>>(
legacy.getAudioAttributes(),
- legacy2aidl_audio_attributes_t_AudioAttributesInternal));
+ legacy2aidl_audio_attributes_t_AudioAttributes));
aidl.streams = VALUE_OR_RETURN(
convertContainer<std::vector<AudioStreamType>>(legacy.getStreamTypes(),
legacy2aidl_audio_stream_type_t_AudioStreamType));
@@ -65,7 +65,7 @@
VALUE_OR_RETURN(aidl2legacy_int32_t_volume_group_t(aidl.groupId)),
VALUE_OR_RETURN(convertContainer<AttributesVector>(
aidl.audioAttributes,
- aidl2legacy_AudioAttributesInternal_audio_attributes_t)),
+ aidl2legacy_AudioAttributes_audio_attributes_t)),
VALUE_OR_RETURN(convertContainer<StreamTypeVector>(
aidl.streams,
aidl2legacy_AudioStreamType_audio_stream_type_t))
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index 7b33a00..7caaaaf 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -56,7 +56,7 @@
ConversionResult<media::CreateTrackRequest> IAudioFlinger::CreateTrackInput::toAidl() const {
media::CreateTrackRequest aidl;
- aidl.attr = VALUE_OR_RETURN(legacy2aidl_audio_attributes_t_AudioAttributesInternal(attr));
+ aidl.attr = VALUE_OR_RETURN(legacy2aidl_audio_attributes_t_AudioAttributes(attr));
// Do not be mislead by 'Input'--this is an input to 'createTrack', which creates output tracks.
aidl.config = VALUE_OR_RETURN(legacy2aidl_audio_config_t_AudioConfig(
config, false /*isInput*/));
@@ -77,7 +77,7 @@
ConversionResult<IAudioFlinger::CreateTrackInput>
IAudioFlinger::CreateTrackInput::fromAidl(const media::CreateTrackRequest& aidl) {
IAudioFlinger::CreateTrackInput legacy;
- legacy.attr = VALUE_OR_RETURN(aidl2legacy_AudioAttributesInternal_audio_attributes_t(aidl.attr));
+ legacy.attr = VALUE_OR_RETURN(aidl2legacy_AudioAttributes_audio_attributes_t(aidl.attr));
// Do not be mislead by 'Input'--this is an input to 'createTrack', which creates output tracks.
legacy.config = VALUE_OR_RETURN(
aidl2legacy_AudioConfig_audio_config_t(aidl.config, false /*isInput*/));
@@ -153,7 +153,7 @@
ConversionResult<media::CreateRecordRequest>
IAudioFlinger::CreateRecordInput::toAidl() const {
media::CreateRecordRequest aidl;
- aidl.attr = VALUE_OR_RETURN(legacy2aidl_audio_attributes_t_AudioAttributesInternal(attr));
+ aidl.attr = VALUE_OR_RETURN(legacy2aidl_audio_attributes_t_AudioAttributes(attr));
aidl.config = VALUE_OR_RETURN(
legacy2aidl_audio_config_base_t_AudioConfigBase(config, true /*isInput*/));
aidl.clientInfo = VALUE_OR_RETURN(legacy2aidl_AudioClient_AudioClient(clientInfo));
@@ -174,7 +174,7 @@
const media::CreateRecordRequest& aidl) {
IAudioFlinger::CreateRecordInput legacy;
legacy.attr = VALUE_OR_RETURN(
- aidl2legacy_AudioAttributesInternal_audio_attributes_t(aidl.attr));
+ aidl2legacy_AudioAttributes_audio_attributes_t(aidl.attr));
legacy.config = VALUE_OR_RETURN(
aidl2legacy_AudioConfigBase_audio_config_base_t(aidl.config, true /*isInput*/));
legacy.clientInfo = VALUE_OR_RETURN(aidl2legacy_AudioClient_AudioClient(aidl.clientInfo));
diff --git a/media/libaudioclient/VolumeGroupAttributes.cpp b/media/libaudioclient/VolumeGroupAttributes.cpp
index 530e73f..938e574 100644
--- a/media/libaudioclient/VolumeGroupAttributes.cpp
+++ b/media/libaudioclient/VolumeGroupAttributes.cpp
@@ -48,7 +48,7 @@
legacy2aidl_VolumeGroupAttributes_AudioAttributesEx(const VolumeGroupAttributes& legacy) {
media::AudioAttributesEx aidl;
aidl.attributes = VALUE_OR_RETURN(
- legacy2aidl_audio_attributes_t_AudioAttributesInternal(legacy.getAttributes()));
+ legacy2aidl_audio_attributes_t_AudioAttributes(legacy.getAttributes()));
aidl.streamType = VALUE_OR_RETURN(
legacy2aidl_audio_stream_type_t_AudioStreamType(legacy.getStreamType()));
aidl.groupId = VALUE_OR_RETURN(legacy2aidl_volume_group_t_int32_t(legacy.getGroupId()));
@@ -60,7 +60,7 @@
return VolumeGroupAttributes(VALUE_OR_RETURN(aidl2legacy_int32_t_volume_group_t(aidl.groupId)),
VALUE_OR_RETURN(aidl2legacy_AudioStreamType_audio_stream_type_t(
aidl.streamType)),
- VALUE_OR_RETURN(aidl2legacy_AudioAttributesInternal_audio_attributes_t(
+ VALUE_OR_RETURN(aidl2legacy_AudioAttributes_audio_attributes_t(
aidl.attributes)));
}
diff --git a/media/libaudioclient/aidl/android/media/AudioAttributesEx.aidl b/media/libaudioclient/aidl/android/media/AudioAttributesEx.aidl
index 335866f..7827bdb 100644
--- a/media/libaudioclient/aidl/android/media/AudioAttributesEx.aidl
+++ b/media/libaudioclient/aidl/android/media/AudioAttributesEx.aidl
@@ -16,7 +16,7 @@
package android.media;
-import android.media.AudioAttributesInternal;
+import android.media.audio.common.AudioAttributes;
import android.media.audio.common.AudioStreamType;
/**
@@ -24,7 +24,7 @@
* {@hide}
*/
parcelable AudioAttributesEx {
- AudioAttributesInternal attributes;
+ AudioAttributes attributes;
AudioStreamType streamType;
/** Interpreted as volume_group_t. */
int groupId;
diff --git a/media/libaudioclient/aidl/android/media/AudioAttributesInternal.aidl b/media/libaudioclient/aidl/android/media/AudioAttributesInternal.aidl
deleted file mode 100644
index 2e74206..0000000
--- a/media/libaudioclient/aidl/android/media/AudioAttributesInternal.aidl
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media;
-
-import android.media.audio.common.AudioContentType;
-import android.media.audio.common.AudioSource;
-import android.media.audio.common.AudioUsage;
-
-/**
- * The "Internal" suffix of this type name is to disambiguate it from the
- * android.media.AudioAttributes SDK type.
- * {@hide}
- */
-parcelable AudioAttributesInternal {
- AudioContentType contentType;
- AudioUsage usage;
- AudioSource source;
- // Bitmask, indexed by AudioFlag.
- int flags;
- @utf8InCpp String tags; /* UTF8 */
-}
diff --git a/media/libaudioclient/aidl/android/media/AudioFlag.aidl b/media/libaudioclient/aidl/android/media/AudioFlag.aidl
deleted file mode 100644
index acf4e6d..0000000
--- a/media/libaudioclient/aidl/android/media/AudioFlag.aidl
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.media;
-
-/**
- * {@hide}
- */
-@Backing(type="int")
-enum AudioFlag {
- AUDIBILITY_ENFORCED = 0,
- SECURE = 1,
- SCO = 2,
- BEACON = 3,
- HW_AV_SYNC = 4,
- HW_HOTWORD = 5,
- BYPASS_INTERRUPTION_POLICY = 6,
- BYPASS_MUTE = 7,
- LOW_LATENCY = 8,
- DEEP_BUFFER = 9,
- NO_MEDIA_PROJECTION = 10,
- MUTE_HAPTIC = 11,
- NO_SYSTEM_CAPTURE = 12,
- CAPTURE_PRIVATE = 13,
- CONTENT_SPATIALIZED = 14,
- NEVER_SPATIALIZE = 15,
- CALL_REDIRECTION = 16,
-}
diff --git a/media/libaudioclient/aidl/android/media/AudioTimestampInternal.aidl b/media/libaudioclient/aidl/android/media/AudioTimestampInternal.aidl
index 8bbfb57..1f16525 100644
--- a/media/libaudioclient/aidl/android/media/AudioTimestampInternal.aidl
+++ b/media/libaudioclient/aidl/android/media/AudioTimestampInternal.aidl
@@ -22,8 +22,11 @@
* {@hide}
*/
parcelable AudioTimestampInternal {
- /** A frame position in AudioTrack::getPosition() units. */
- int position;
+ /**
+ * A frame position in AudioTrack::getPosition() units. Use 'long' to accommodate
+ * all values from 'uint32_t'.
+ */
+ long position;
/** corresponding CLOCK_MONOTONIC when frame is expected to present. */
long sec;
int nsec;
diff --git a/media/libaudioclient/aidl/android/media/AudioVolumeGroup.aidl b/media/libaudioclient/aidl/android/media/AudioVolumeGroup.aidl
index b95a1d3..424f8b8 100644
--- a/media/libaudioclient/aidl/android/media/AudioVolumeGroup.aidl
+++ b/media/libaudioclient/aidl/android/media/AudioVolumeGroup.aidl
@@ -16,7 +16,7 @@
package android.media;
-import android.media.AudioAttributesInternal;
+import android.media.audio.common.AudioAttributes;
import android.media.audio.common.AudioStreamType;
/**
@@ -26,6 +26,6 @@
/** Interpreted as volume_group_t. */
int groupId;
@utf8InCpp String name;
- AudioAttributesInternal[] audioAttributes;
+ AudioAttributes[] audioAttributes;
AudioStreamType[] streams;
}
diff --git a/media/libaudioclient/aidl/android/media/CreateRecordRequest.aidl b/media/libaudioclient/aidl/android/media/CreateRecordRequest.aidl
index b938a3e..57e8f42 100644
--- a/media/libaudioclient/aidl/android/media/CreateRecordRequest.aidl
+++ b/media/libaudioclient/aidl/android/media/CreateRecordRequest.aidl
@@ -16,8 +16,8 @@
package android.media;
-import android.media.AudioAttributesInternal;
import android.media.AudioClient;
+import android.media.audio.common.AudioAttributes;
import android.media.audio.common.AudioConfigBase;
/**
@@ -28,7 +28,7 @@
* {@hide}
*/
parcelable CreateRecordRequest {
- AudioAttributesInternal attr;
+ AudioAttributes attr;
AudioConfigBase config;
AudioClient clientInfo;
/** Interpreted as audio_unique_id_t. */
diff --git a/media/libaudioclient/aidl/android/media/CreateTrackRequest.aidl b/media/libaudioclient/aidl/android/media/CreateTrackRequest.aidl
index 212221e..24e6a6c 100644
--- a/media/libaudioclient/aidl/android/media/CreateTrackRequest.aidl
+++ b/media/libaudioclient/aidl/android/media/CreateTrackRequest.aidl
@@ -16,7 +16,7 @@
package android.media;
-import android.media.AudioAttributesInternal;
+import android.media.audio.common.AudioAttributes;
import android.media.AudioClient;
import android.media.IAudioTrackCallback;
import android.media.SharedFileRegion;
@@ -30,7 +30,7 @@
* {@hide}
*/
parcelable CreateTrackRequest {
- AudioAttributesInternal attr;
+ AudioAttributes attr;
AudioConfig config;
AudioClient clientInfo;
@nullable SharedFileRegion sharedBuffer;
diff --git a/media/libaudioclient/aidl/android/media/GetOutputForAttrResponse.aidl b/media/libaudioclient/aidl/android/media/GetOutputForAttrResponse.aidl
index 9d44bb0..b814b85 100644
--- a/media/libaudioclient/aidl/android/media/GetOutputForAttrResponse.aidl
+++ b/media/libaudioclient/aidl/android/media/GetOutputForAttrResponse.aidl
@@ -16,9 +16,9 @@
package android.media;
+import android.media.audio.common.AudioAttributes;
import android.media.audio.common.AudioConfigBase;
import android.media.audio.common.AudioStreamType;
-import android.media.AudioAttributesInternal;
/**
* {@hide}
*/
@@ -38,5 +38,5 @@
AudioConfigBase configBase;
boolean isBitPerfect;
/** The corrected audio attributes. **/
- AudioAttributesInternal attr;
+ AudioAttributes attr;
}
diff --git a/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl b/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
index 90ede8b..3e9b27f 100644
--- a/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
+++ b/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
@@ -18,8 +18,6 @@
import android.content.AttributionSourceState;
-import android.media.AudioAttributesEx;
-import android.media.AudioAttributesInternal;
import android.media.AudioDirectMode;
import android.media.AudioMix;
import android.media.AudioMixerAttributesInternal;
@@ -43,6 +41,7 @@
import android.media.ICaptureStateListener;
import android.media.INativeSpatializerCallback;
import android.media.SoundTriggerSession;
+import android.media.audio.common.AudioAttributes;
import android.media.audio.common.AudioConfig;
import android.media.audio.common.AudioConfigBase;
import android.media.audio.common.AudioDevice;
@@ -85,7 +84,7 @@
int /* audio_io_handle_t */ getOutput(AudioStreamType stream);
- GetOutputForAttrResponse getOutputForAttr(in AudioAttributesInternal attr,
+ GetOutputForAttrResponse getOutputForAttr(in AudioAttributes attr,
int /* audio_session_t */ session,
in AttributionSourceState attributionSource,
in AudioConfig config,
@@ -98,7 +97,7 @@
void releaseOutput(int /* audio_port_handle_t */ portId);
- GetInputForAttrResponse getInputForAttr(in AudioAttributesInternal attr,
+ GetInputForAttrResponse getInputForAttr(in AudioAttributes attr,
int /* audio_io_handle_t */ input,
int /* audio_unique_id_t */ riid,
int /* audio_session_t */ session,
@@ -125,20 +124,20 @@
int getStreamVolumeIndex(AudioStreamType stream,
in AudioDeviceDescription device);
- void setVolumeIndexForAttributes(in AudioAttributesInternal attr,
+ void setVolumeIndexForAttributes(in AudioAttributes attr,
in AudioDeviceDescription device,
int index);
- int getVolumeIndexForAttributes(in AudioAttributesInternal attr,
+ int getVolumeIndexForAttributes(in AudioAttributes attr,
in AudioDeviceDescription device);
- int getMaxVolumeIndexForAttributes(in AudioAttributesInternal attr);
+ int getMaxVolumeIndexForAttributes(in AudioAttributes attr);
- int getMinVolumeIndexForAttributes(in AudioAttributesInternal attr);
+ int getMinVolumeIndexForAttributes(in AudioAttributes attr);
int /* product_strategy_t */ getStrategyForStream(AudioStreamType stream);
- AudioDevice[] getDevicesForAttributes(in AudioAttributesInternal attr, boolean forVolume);
+ AudioDevice[] getDevicesForAttributes(in AudioAttributes attr, boolean forVolume);
int /* audio_io_handle_t */ getOutputForEffect(in EffectDescriptor desc);
@@ -200,7 +199,7 @@
* Check if direct playback is possible for given format, sample rate, channel mask and flags.
*/
boolean isDirectOutputSupported(in AudioConfigBase config,
- in AudioAttributesInternal attributes);
+ in AudioAttributes attributes);
/**
* List currently attached audio ports and their attributes. Returns the generation.
@@ -272,7 +271,7 @@
void removeUserIdDeviceAffinities(int userId);
int /* audio_port_handle_t */ startAudioSource(in AudioPortConfigFw source,
- in AudioAttributesInternal attributes);
+ in AudioAttributes attributes);
void stopAudioSource(int /* audio_port_handle_t */ portId);
@@ -333,10 +332,10 @@
AudioProductStrategy[] listAudioProductStrategies();
int /* product_strategy_t */ getProductStrategyFromAudioAttributes(
- in AudioAttributesInternal aa, boolean fallbackOnDefault);
+ in AudioAttributes aa, boolean fallbackOnDefault);
AudioVolumeGroup[] listAudioVolumeGroups();
- int /* volume_group_t */ getVolumeGroupFromAudioAttributes(in AudioAttributesInternal aa,
+ int /* volume_group_t */ getVolumeGroupFromAudioAttributes(in AudioAttributes aa,
boolean fallbackOnDefault);
void setRttEnabled(boolean enabled);
@@ -397,21 +396,21 @@
* supported criteria. For instance, supplying no argument will tell if spatialization is
* supported or not in general.
*/
- boolean canBeSpatialized(in @nullable AudioAttributesInternal attr,
+ boolean canBeSpatialized(in @nullable AudioAttributes attr,
in @nullable AudioConfig config,
in AudioDevice[] devices);
/**
* Query how the direct playback is currently supported on the device.
*/
- AudioDirectMode getDirectPlaybackSupport(in AudioAttributesInternal attr,
+ AudioDirectMode getDirectPlaybackSupport(in AudioAttributes attr,
in AudioConfig config);
/**
* Query audio profiles available for direct playback on the current output device(s)
* for the specified audio attributes.
*/
- AudioProfile[] getDirectProfilesForAttributes(in AudioAttributesInternal attr);
+ AudioProfile[] getDirectProfilesForAttributes(in AudioAttributes attr);
/**
* Return a list of AudioMixerAttributes that can be used to set preferred mixer attributes
@@ -435,7 +434,7 @@
* playback is routed to the given device.
* @param mixerAttr the preferred mixer attributes.
*/
- void setPreferredMixerAttributes(in AudioAttributesInternal attr,
+ void setPreferredMixerAttributes(in AudioAttributes attr,
int /* audio_port_handle_t */ portId,
int /* uid_t */ uid,
in AudioMixerAttributesInternal mixerAttr);
@@ -449,7 +448,7 @@
* @param portId the port id of the device to be routed.
*/
@nullable AudioMixerAttributesInternal getPreferredMixerAttributes(
- in AudioAttributesInternal attr,
+ in AudioAttributes attr,
int /* audio_port_handle_t */ portId);
/**
@@ -462,7 +461,7 @@
* preferred mixer attributes. The preferred mixer attributes will only be cleared
* if the uid is the same as the owner of current preferred mixer attributes.
*/
- void clearPreferredMixerAttributes(in AudioAttributesInternal attr,
+ void clearPreferredMixerAttributes(in AudioAttributes attr,
int /* audio_port_handle_t */ portId,
int /* uid_t */ uid);
diff --git a/media/libaudioclient/include/media/AidlConversion.h b/media/libaudioclient/include/media/AidlConversion.h
index b0d48b7..10f6d4a 100644
--- a/media/libaudioclient/include/media/AidlConversion.h
+++ b/media/libaudioclient/include/media/AidlConversion.h
@@ -21,10 +21,8 @@
#include <system/audio.h>
-#include <android/media/AudioAttributesInternal.h>
#include <android/media/AudioClient.h>
#include <android/media/AudioDirectMode.h>
-#include <android/media/AudioFlag.h>
#include <android/media/AudioIoConfigEvent.h>
#include <android/media/AudioIoDescriptor.h>
#include <android/media/AudioPortFw.h>
@@ -105,21 +103,6 @@
ConversionResult<media::AudioClient> legacy2aidl_AudioClient_AudioClient(
const AudioClient& legacy);
-ConversionResult<audio_flags_mask_t>
-aidl2legacy_AudioFlag_audio_flags_mask_t(media::AudioFlag aidl);
-ConversionResult<media::AudioFlag>
-legacy2aidl_audio_flags_mask_t_AudioFlag(audio_flags_mask_t legacy);
-
-ConversionResult<audio_flags_mask_t>
-aidl2legacy_int32_t_audio_flags_mask_t_mask(int32_t aidl);
-ConversionResult<int32_t>
-legacy2aidl_audio_flags_mask_t_int32_t_mask(audio_flags_mask_t legacy);
-
-ConversionResult<audio_attributes_t>
-aidl2legacy_AudioAttributesInternal_audio_attributes_t(const media::AudioAttributesInternal& aidl);
-ConversionResult<media::AudioAttributesInternal>
-legacy2aidl_audio_attributes_t_AudioAttributesInternal(const audio_attributes_t& legacy);
-
ConversionResult<sp<IMemory>>
aidl2legacy_SharedFileRegion_IMemory(const media::SharedFileRegion& aidl);
ConversionResult<media::SharedFileRegion>
diff --git a/media/libaudioclient/tests/audio_aidl_legacy_conversion_tests.cpp b/media/libaudioclient/tests/audio_aidl_legacy_conversion_tests.cpp
index 0d12f9d..976a532 100644
--- a/media/libaudioclient/tests/audio_aidl_legacy_conversion_tests.cpp
+++ b/media/libaudioclient/tests/audio_aidl_legacy_conversion_tests.cpp
@@ -94,6 +94,11 @@
AudioChannelLayout::LAYOUT_STEREO);
}
+AudioChannelLayout make_ACL_Tri() {
+ return AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
+ AudioChannelLayout::LAYOUT_TRI);
+}
+
AudioChannelLayout make_ACL_LayoutArbitrary() {
return AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
// Use channels that exist both for input and output,
@@ -311,8 +316,8 @@
AudioChannelLayoutRoundTrip, AudioChannelLayoutRoundTripTest,
testing::Combine(
testing::Values(AudioChannelLayout{}, make_ACL_Invalid(), make_ACL_Stereo(),
- make_ACL_LayoutArbitrary(), make_ACL_ChannelIndex2(),
- make_ACL_ChannelIndexArbitrary(),
+ make_ACL_Tri(), make_ACL_LayoutArbitrary(),
+ make_ACL_ChannelIndex2(), make_ACL_ChannelIndexArbitrary(),
AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
AudioChannelLayout::CHANNEL_FRONT_LEFT),
AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
diff --git a/media/libaudioclient/tests/audioclient_serialization_tests.cpp b/media/libaudioclient/tests/audioclient_serialization_tests.cpp
index d1e3d16..707b9b3 100644
--- a/media/libaudioclient/tests/audioclient_serialization_tests.cpp
+++ b/media/libaudioclient/tests/audioclient_serialization_tests.cpp
@@ -103,7 +103,7 @@
attr.usage = kUsages[rand() % kUsages.size()];
attr.source = kInputSources[rand() % kInputSources.size()];
// attr.flags -> [0, (1 << (CAPTURE_PRIVATE + 1) - 1)]
- attr.flags = static_cast<audio_flags_mask_t>(rand() & 0x3fff);
+ attr.flags = static_cast<audio_flags_mask_t>(rand() & 0x3ffd); // exclude AUDIO_FLAG_SECURE
sprintf(attr.tags, "%s",
CreateRandomString((int)rand() % (AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1)).c_str());
}
@@ -119,6 +119,7 @@
TEST_F(SerializationTest, AudioProductStrategyBinderization) {
for (int j = 0; j < 512; j++) {
const std::string name{"Test APSBinderization for seed::" + std::to_string(mSeed)};
+ SCOPED_TRACE(name);
std::vector<VolumeGroupAttributes> volumeGroupAttrVector;
for (auto i = 0; i < 16; i++) {
audio_attributes_t attributes;
@@ -132,20 +133,19 @@
AudioProductStrategy aps{name, volumeGroupAttrVector, psId};
Parcel p;
- EXPECT_EQ(NO_ERROR, aps.writeToParcel(&p)) << name;
+ EXPECT_EQ(NO_ERROR, aps.writeToParcel(&p));
AudioProductStrategy apsCopy;
p.setDataPosition(0);
- EXPECT_EQ(NO_ERROR, apsCopy.readFromParcel(&p)) << name;
- EXPECT_EQ(apsCopy.getName(), name) << name;
- EXPECT_EQ(apsCopy.getId(), psId) << name;
+ EXPECT_EQ(NO_ERROR, apsCopy.readFromParcel(&p));
+ EXPECT_EQ(apsCopy.getName(), name);
+ EXPECT_EQ(apsCopy.getId(), psId);
auto avec = apsCopy.getVolumeGroupAttributes();
- EXPECT_EQ(avec.size(), volumeGroupAttrVector.size()) << name;
- for (int i = 0; i < volumeGroupAttrVector.size(); i++) {
- EXPECT_EQ(avec[i].getGroupId(), volumeGroupAttrVector[i].getGroupId()) << name;
- EXPECT_EQ(avec[i].getStreamType(), volumeGroupAttrVector[i].getStreamType()) << name;
- EXPECT_TRUE(avec[i].getAttributes() == volumeGroupAttrVector[i].getAttributes())
- << name;
+ EXPECT_EQ(avec.size(), volumeGroupAttrVector.size());
+ for (int i = 0; i < std::min(avec.size(), volumeGroupAttrVector.size()); i++) {
+ EXPECT_EQ(avec[i].getGroupId(), volumeGroupAttrVector[i].getGroupId());
+ EXPECT_EQ(avec[i].getStreamType(), volumeGroupAttrVector[i].getStreamType());
+ EXPECT_TRUE(avec[i].getAttributes() == volumeGroupAttrVector[i].getAttributes());
}
}
}
diff --git a/media/libaudiohal/TEST_MAPPING b/media/libaudiohal/TEST_MAPPING
index 5d3fb0a..90f481b 100644
--- a/media/libaudiohal/TEST_MAPPING
+++ b/media/libaudiohal/TEST_MAPPING
@@ -16,6 +16,9 @@
"include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic_TestAAudioBasic_TestBasic_LOW_LATENCY__OUTPUT"
}
]
+ },
+ {
+ "name": "CoreAudioHalAidlTest"
}
]
}
diff --git a/media/libaudiohal/impl/Android.bp b/media/libaudiohal/impl/Android.bp
index 09e70eb..1689365 100644
--- a/media/libaudiohal/impl/Android.bp
+++ b/media/libaudiohal/impl/Android.bp
@@ -245,20 +245,48 @@
]
}
-cc_library_shared {
- name: "libaudiohal@aidl",
+cc_defaults {
+ name: "libaudiohal_aidl_default",
defaults: [
- "libaudiohal_default",
"latest_android_hardware_audio_common_ndk_shared",
"latest_android_hardware_audio_core_ndk_shared",
"latest_android_hardware_audio_core_sounddose_ndk_shared",
"latest_android_hardware_audio_effect_ndk_shared",
"latest_android_media_audio_common_types_ndk_shared",
],
+ shared_libs: [
+ "android.hardware.common-V2-ndk",
+ "android.hardware.common.fmq-V1-ndk",
+ "av-audio-types-aidl-ndk",
+ "libaudio_aidl_conversion_common_cpp",
+ "libaudio_aidl_conversion_common_ndk",
+ "libaudio_aidl_conversion_common_ndk_cpp",
+ "libaudio_aidl_conversion_core_ndk",
+ "libaudio_aidl_conversion_effect_ndk",
+ "libaudioaidlcommon",
+ "libbinder_ndk",
+ ],
+ header_libs: [
+ "libaudio_system_headers",
+ "libeffectsconfig_headers",
+ ],
+ cflags: [
+ "-Wall",
+ "-Wextra",
+ "-Werror",
+ "-Wthread-safety",
+ "-DBACKEND_CPP_NDK",
+ ],
+}
+
+cc_library_shared {
+ name: "libaudiohal@aidl",
+ defaults: [
+ "libaudiohal_default",
+ "libaudiohal_aidl_default",
+ ],
srcs: [
- "DeviceHalAidl.cpp",
"DevicesFactoryHalEntry.cpp",
- "DevicesFactoryHalAidl.cpp",
"EffectConversionHelperAidl.cpp",
"EffectBufferHalAidl.cpp",
"EffectHalAidl.cpp",
@@ -280,32 +308,18 @@
"effectsAidlConversion/AidlConversionVisualizer.cpp",
"EffectsFactoryHalAidl.cpp",
"EffectsFactoryHalEntry.cpp",
+ ":audio_effectproxy_src_files",
+ ":core_audio_hal_aidl_src_files",
+ ],
+}
+
+filegroup {
+ name: "core_audio_hal_aidl_src_files",
+ srcs: [
+ "ConversionHelperAidl.cpp",
+ "DeviceHalAidl.cpp",
+ "DevicesFactoryHalAidl.cpp",
"StreamHalAidl.cpp",
- ":audio_effectproxy_src_files"
- ],
- static_libs: [
- "android.hardware.common-V2-ndk",
- "android.hardware.common.fmq-V1-ndk",
- ],
- shared_libs: [
- "libaudio_aidl_conversion_common_cpp",
- "libaudio_aidl_conversion_common_ndk",
- "libaudio_aidl_conversion_common_ndk_cpp",
- "libaudio_aidl_conversion_core_ndk",
- "libaudio_aidl_conversion_effect_ndk",
- "libaudioaidlcommon",
- "libbinder_ndk",
- ],
- header_libs: [
- "libaudio_system_headers",
- "libeffectsconfig_headers",
- ],
- cflags: [
- "-Wall",
- "-Wextra",
- "-Werror",
- "-Wthread-safety",
- "-DBACKEND_CPP_NDK",
],
}
diff --git a/media/libaudiohal/impl/ConversionHelperAidl.cpp b/media/libaudiohal/impl/ConversionHelperAidl.cpp
new file mode 100644
index 0000000..7197bf2
--- /dev/null
+++ b/media/libaudiohal/impl/ConversionHelperAidl.cpp
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "ConversionHelperAidl"
+
+#include <memory>
+
+#include <media/AidlConversionUtil.h>
+#include <utils/Log.h>
+
+#include "ConversionHelperAidl.h"
+
+using aidl::android::aidl_utils::statusTFromBinderStatus;
+using aidl::android::hardware::audio::core::VendorParameter;
+using aidl::android::media::audio::IHalAdapterVendorExtension;
+
+namespace android {
+
+status_t parseAndGetVendorParameters(
+ std::shared_ptr<IHalAdapterVendorExtension> vendorExt,
+ const VendorParametersRecipient& recipient,
+ const AudioParameter& parameterKeys,
+ String8* values) {
+ using ParameterScope = IHalAdapterVendorExtension::ParameterScope;
+ if (parameterKeys.size() == 0) return OK;
+ const String8 rawKeys = parameterKeys.keysToString();
+ if (vendorExt == nullptr) {
+ ALOGW("%s: unknown parameters, ignored: \"%s\"", __func__, rawKeys.c_str());
+ return OK;
+ }
+
+ std::vector<std::string> parameterIds;
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(vendorExt->parseVendorParameterIds(
+ ParameterScope(recipient.index()),
+ std::string(rawKeys.c_str()), ¶meterIds)));
+ if (parameterIds.empty()) return OK;
+
+ std::vector<VendorParameter> parameters;
+ if (recipient.index() == static_cast<int>(ParameterScope::MODULE)) {
+ auto module = std::get<static_cast<int>(ParameterScope::MODULE)>(recipient);
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(module->getVendorParameters(
+ parameterIds, ¶meters)));
+ } else if (recipient.index() == static_cast<int>(ParameterScope::STREAM)) {
+ auto stream = std::get<static_cast<int>(ParameterScope::STREAM)>(recipient);
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(stream->getVendorParameters(
+ parameterIds, ¶meters)));
+ } else {
+ LOG_ALWAYS_FATAL("%s: unexpected recipient variant index: %zu",
+ __func__, recipient.index());
+ }
+ if (!parameters.empty()) {
+ std::string vendorParameters;
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(vendorExt->processVendorParameters(
+ ParameterScope(recipient.index()),
+ parameters, &vendorParameters)));
+ // Re-parse the vendor-provided string to ensure that it is correct.
+ AudioParameter reparse(String8(vendorParameters.c_str()));
+ if (reparse.size() != 0) {
+ if (!values->empty()) {
+ values->append(";");
+ }
+ values->append(reparse.toString().c_str());
+ }
+ }
+ return OK;
+}
+
+status_t parseAndSetVendorParameters(
+ std::shared_ptr<IHalAdapterVendorExtension> vendorExt,
+ const VendorParametersRecipient& recipient,
+ const AudioParameter& parameters) {
+ using ParameterScope = IHalAdapterVendorExtension::ParameterScope;
+ if (parameters.size() == 0) return OK;
+ const String8 rawKeysAndValues = parameters.toString();
+ if (vendorExt == nullptr) {
+ ALOGW("%s: unknown parameters, ignored: \"%s\"", __func__, rawKeysAndValues.c_str());
+ return OK;
+ }
+
+ std::vector<VendorParameter> syncParameters, asyncParameters;
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(vendorExt->parseVendorParameters(
+ ParameterScope(recipient.index()),
+ std::string(rawKeysAndValues.c_str()),
+ &syncParameters, &asyncParameters)));
+ if (recipient.index() == static_cast<int>(ParameterScope::MODULE)) {
+ auto module = std::get<static_cast<int>(ParameterScope::MODULE)>(recipient);
+ if (!syncParameters.empty()) {
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(module->setVendorParameters(
+ syncParameters, false /*async*/)));
+ }
+ if (!asyncParameters.empty()) {
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(module->setVendorParameters(
+ asyncParameters, true /*async*/)));
+ }
+ } else if (recipient.index() == static_cast<int>(ParameterScope::STREAM)) {
+ auto stream = std::get<static_cast<int>(ParameterScope::STREAM)>(recipient);
+ if (!syncParameters.empty()) {
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(stream->setVendorParameters(
+ syncParameters, false /*async*/)));
+ }
+ if (!asyncParameters.empty()) {
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(stream->setVendorParameters(
+ asyncParameters, true /*async*/)));
+ }
+ } else {
+ LOG_ALWAYS_FATAL("%s: unexpected recipient variant index: %zu",
+ __func__, recipient.index());
+ }
+ return OK;
+}
+
+} // namespace android
diff --git a/media/libaudiohal/impl/ConversionHelperAidl.h b/media/libaudiohal/impl/ConversionHelperAidl.h
index 5534d13..0fadd9c 100644
--- a/media/libaudiohal/impl/ConversionHelperAidl.h
+++ b/media/libaudiohal/impl/ConversionHelperAidl.h
@@ -18,8 +18,12 @@
#include <string>
#include <string_view>
+#include <variant>
#include <vector>
+#include <aidl/android/hardware/audio/core/IModule.h>
+#include <aidl/android/hardware/audio/core/IStreamCommon.h>
+#include <aidl/android/media/audio/IHalAdapterVendorExtension.h>
#include <android-base/expected.h>
#include <error/Result.h>
#include <media/AudioParameter.h>
@@ -74,4 +78,18 @@
return false;
}
+// Must use the same order of elements as IHalAdapterVendorExtension::ParameterScope.
+using VendorParametersRecipient = std::variant<
+ std::shared_ptr<::aidl::android::hardware::audio::core::IModule>,
+ std::shared_ptr<::aidl::android::hardware::audio::core::IStreamCommon>>;
+status_t parseAndGetVendorParameters(
+ std::shared_ptr<::aidl::android::media::audio::IHalAdapterVendorExtension> vendorExt,
+ const VendorParametersRecipient& recipient,
+ const AudioParameter& parameterKeys,
+ String8* values);
+status_t parseAndSetVendorParameters(
+ std::shared_ptr<::aidl::android::media::audio::IHalAdapterVendorExtension> vendorExt,
+ const VendorParametersRecipient& recipient,
+ const AudioParameter& parameters);
+
} // namespace android
diff --git a/media/libaudiohal/impl/DeviceHalAidl.cpp b/media/libaudiohal/impl/DeviceHalAidl.cpp
index 3125e311..ae15190 100644
--- a/media/libaudiohal/impl/DeviceHalAidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalAidl.cpp
@@ -32,6 +32,7 @@
#include <utils/Log.h>
#include "DeviceHalAidl.h"
+#include "EffectHalAidl.h"
#include "StreamHalAidl.h"
using aidl::android::aidl_utils::statusTFromBinderStatus;
@@ -62,6 +63,7 @@
using aidl::android::media::audio::common::Int;
using aidl::android::media::audio::common::MicrophoneDynamicInfo;
using aidl::android::media::audio::common::MicrophoneInfo;
+using aidl::android::media::audio::IHalAdapterVendorExtension;
using aidl::android::hardware::audio::common::getFrameSizeInBytes;
using aidl::android::hardware::audio::common::isBitPositionFlagSet;
using aidl::android::hardware::audio::common::isDefaultAudioFormat;
@@ -76,6 +78,7 @@
using aidl::android::hardware::audio::core::ITelephony;
using aidl::android::hardware::audio::core::ModuleDebug;
using aidl::android::hardware::audio::core::StreamDescriptor;
+using aidl::android::hardware::audio::core::VendorParameter;
namespace android {
@@ -125,9 +128,10 @@
} // namespace
-DeviceHalAidl::DeviceHalAidl(const std::string& instance, const std::shared_ptr<IModule>& module)
+DeviceHalAidl::DeviceHalAidl(const std::string& instance, const std::shared_ptr<IModule>& module,
+ const std::shared_ptr<IHalAdapterVendorExtension>& vext)
: ConversionHelperAidl("DeviceHalAidl"),
- mInstance(instance), mModule(module),
+ mInstance(instance), mModule(module), mVendorExt(vext),
mTelephony(retrieveSubInterface<ITelephony>(module, &IModule::getTelephony)),
mBluetooth(retrieveSubInterface<IBluetooth>(module, &IModule::getBluetooth)),
mBluetoothA2dp(retrieveSubInterface<IBluetoothA2dp>(module, &IModule::getBluetoothA2dp)),
@@ -135,11 +139,8 @@
}
status_t DeviceHalAidl::getAudioPorts(std::vector<media::audio::common::AudioPort> *ports) {
- auto convertAudioPortFromMap = [](const Ports::value_type& pair) {
- return ndk2cpp_AudioPort(pair.second);
- };
- return ::aidl::android::convertRange(mPorts.begin(), mPorts.end(), ports->begin(),
- convertAudioPortFromMap);
+ return ::aidl::android::convertContainer(mPorts, ports,
+ [](const Ports::value_type& pair) { return ndk2cpp_AudioPort(pair.second); });
}
status_t DeviceHalAidl::getAudioRoutes(std::vector<media::AudioRoute> *routes) {
@@ -289,19 +290,24 @@
if (status_t status = filterAndUpdateBtScoParameters(parameters); status != OK) {
ALOGW("%s: filtering or updating BT SCO parameters failed: %d", __func__, status);
}
-
- ALOGW_IF(parameters.size() != 0, "%s: unknown parameters, ignored: \"%s\"",
- __func__, parameters.toString().c_str());
- return OK;
+ if (status_t status = filterAndUpdateScreenParameters(parameters); status != OK) {
+ ALOGW("%s: filtering or updating screen parameters failed: %d", __func__, status);
+ }
+ return parseAndSetVendorParameters(mVendorExt, mModule, parameters);
}
-status_t DeviceHalAidl::getParameters(const String8& keys __unused, String8 *values) {
+status_t DeviceHalAidl::getParameters(const String8& keys, String8 *values) {
TIME_CHECK();
- // FIXME(b/278976019): Support keyReconfigA2dpSupported via vendor plugin
- values->clear();
if (!mModule) return NO_INIT;
- ALOGE("%s not implemented yet", __func__);
- return OK;
+ if (values == nullptr) {
+ return BAD_VALUE;
+ }
+ AudioParameter parameterKeys(keys), result;
+ if (status_t status = filterAndRetrieveBtA2dpParameters(parameterKeys, &result); status != OK) {
+ ALOGW("%s: filtering or retrieving BT A2DP parameters failed: %d", __func__, status);
+ }
+ *values = result.toString();
+ return parseAndGetVendorParameters(mVendorExt, mModule, parameterKeys, values);
}
namespace {
@@ -571,7 +577,7 @@
return NO_INIT;
}
*outStream = sp<StreamOutHalAidl>::make(*config, std::move(context), aidlPatch.latenciesMs[0],
- std::move(ret.stream), this /*callbackBroker*/);
+ std::move(ret.stream), mVendorExt, this /*callbackBroker*/);
mStreams.insert(std::pair(*outStream, aidlPatch.id));
void* cbCookie = (*outStream).get();
{
@@ -632,7 +638,7 @@
return NO_INIT;
}
*inStream = sp<StreamInHalAidl>::make(*config, std::move(context), aidlPatch.latenciesMs[0],
- std::move(ret.stream), this /*micInfoProvider*/);
+ std::move(ret.stream), mVendorExt, this /*micInfoProvider*/);
mStreams.insert(std::pair(*inStream, aidlPatch.id));
cleanups.disarmAll();
return OK;
@@ -877,25 +883,64 @@
return OK;
}
-status_t DeviceHalAidl::addDeviceEffect(audio_port_handle_t device __unused,
- sp<EffectHalInterface> effect) {
+status_t DeviceHalAidl::addDeviceEffect(
+ const struct audio_port_config *device, sp<EffectHalInterface> effect) {
+ TIME_CHECK();
+ if (!mModule) return NO_INIT;
if (!effect) {
return BAD_VALUE;
}
- TIME_CHECK();
- if (!mModule) return NO_INIT;
- ALOGE("%s not implemented yet", __func__);
+ bool isInput = VALUE_OR_RETURN_STATUS(::aidl::android::portDirection(
+ device->role, device->type)) == ::aidl::android::AudioPortDirection::INPUT;
+ auto requestedPortConfig = VALUE_OR_RETURN_STATUS(
+ ::aidl::android::legacy2aidl_audio_port_config_AudioPortConfig(
+ *device, isInput, 0));
+ if (requestedPortConfig.ext.getTag() != AudioPortExt::Tag::device) {
+ ALOGE("%s: provided port config is not a device port config: %s",
+ __func__, requestedPortConfig.toString().c_str());
+ return BAD_VALUE;
+ }
+ AudioPortConfig devicePortConfig;
+ bool created;
+ RETURN_STATUS_IF_ERROR(findOrCreatePortConfig(
+ requestedPortConfig, {} /*destinationPortIds*/, &devicePortConfig, &created));
+ Cleanups cleanups;
+ if (created) {
+ cleanups.emplace_front(this, &DeviceHalAidl::resetPortConfig, devicePortConfig.id);
+ }
+ auto aidlEffect = sp<effect::EffectHalAidl>::cast(effect);
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->addDeviceEffect(
+ devicePortConfig.id, aidlEffect->getIEffect())));
+ cleanups.disarmAll();
return OK;
}
-status_t DeviceHalAidl::removeDeviceEffect(audio_port_handle_t device __unused,
- sp<EffectHalInterface> effect) {
+status_t DeviceHalAidl::removeDeviceEffect(
+ const struct audio_port_config *device, sp<EffectHalInterface> effect) {
+ TIME_CHECK();
+ if (!mModule) return NO_INIT;
if (!effect) {
return BAD_VALUE;
}
- TIME_CHECK();
- if (!mModule) return NO_INIT;
- ALOGE("%s not implemented yet", __func__);
- return OK;
+ bool isInput = VALUE_OR_RETURN_STATUS(::aidl::android::portDirection(
+ device->role, device->type)) == ::aidl::android::AudioPortDirection::INPUT;
+ auto requestedPortConfig = VALUE_OR_RETURN_STATUS(
+ ::aidl::android::legacy2aidl_audio_port_config_AudioPortConfig(
+ *device, isInput, 0));
+ if (requestedPortConfig.ext.getTag() != AudioPortExt::Tag::device) {
+ ALOGE("%s: provided port config is not a device port config: %s",
+ __func__, requestedPortConfig.toString().c_str());
+ return BAD_VALUE;
+ }
+ auto existingPortConfigIt = findPortConfig(
+ requestedPortConfig.ext.get<AudioPortExt::Tag::device>().device);
+ if (existingPortConfigIt == mPortConfigs.end()) {
+ ALOGE("%s: could not find a configured device port for the config %s",
+ __func__, requestedPortConfig.toString().c_str());
+ return BAD_VALUE;
+ }
+ auto aidlEffect = sp<effect::EffectHalAidl>::cast(effect);
+ return statusTFromBinderStatus(mModule->removeDeviceEffect(
+ existingPortConfigIt->first, aidlEffect->getIEffect()));
}
status_t DeviceHalAidl::getMmapPolicyInfos(
@@ -1112,9 +1157,23 @@
return OK;
}
+status_t DeviceHalAidl::filterAndRetrieveBtA2dpParameters(
+ AudioParameter &keys, AudioParameter *result) {
+ TIME_CHECK();
+ if (String8 key = String8(AudioParameter::keyReconfigA2dpSupported); keys.containsKey(key)) {
+ keys.remove(key);
+ bool supports;
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
+ mBluetoothA2dp->supportsOffloadReconfiguration(&supports)));
+ result->addInt(key, supports ? 1 : 0);
+ }
+ return OK;
+}
+
status_t DeviceHalAidl::filterAndUpdateBtA2dpParameters(AudioParameter ¶meters) {
TIME_CHECK();
std::optional<bool> a2dpEnabled;
+ std::optional<std::vector<VendorParameter>> reconfigureOffload;
(void)VALUE_OR_RETURN_STATUS(filterOutAndProcessParameter<String8>(
parameters, String8(AudioParameter::keyBtA2dpSuspended),
[&a2dpEnabled](const String8& trueOrFalse) {
@@ -1129,10 +1188,27 @@
AudioParameter::keyBtA2dpSuspended, trueOrFalse.c_str());
return BAD_VALUE;
}));
- // FIXME(b/278976019): Support keyReconfigA2dp via vendor plugin
+ (void)VALUE_OR_RETURN_STATUS(filterOutAndProcessParameter<String8>(
+ parameters, String8(AudioParameter::keyReconfigA2dp),
+ [&](const String8& value) -> status_t {
+ if (mVendorExt != nullptr) {
+ std::vector<VendorParameter> result;
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
+ mVendorExt->parseBluetoothA2dpReconfigureOffload(
+ std::string(value.c_str()), &result)));
+ reconfigureOffload = std::move(result);
+ } else {
+ reconfigureOffload = std::vector<VendorParameter>();
+ }
+ return OK;
+ }));
if (mBluetoothA2dp != nullptr && a2dpEnabled.has_value()) {
return statusTFromBinderStatus(mBluetoothA2dp->setEnabled(a2dpEnabled.value()));
}
+ if (mBluetoothA2dp != nullptr && reconfigureOffload.has_value()) {
+ return statusTFromBinderStatus(mBluetoothA2dp->reconfigureOffload(
+ reconfigureOffload.value()));
+ }
return OK;
}
@@ -1256,6 +1332,44 @@
return OK;
}
+status_t DeviceHalAidl::filterAndUpdateScreenParameters(AudioParameter ¶meters) {
+ TIME_CHECK();
+ (void)VALUE_OR_RETURN_STATUS(filterOutAndProcessParameter<String8>(
+ parameters, String8(AudioParameter::keyScreenState),
+ [&](const String8& onOrOff) -> status_t {
+ std::optional<bool> isTurnedOn;
+ if (onOrOff == AudioParameter::valueOn) {
+ isTurnedOn = true;
+ } else if (onOrOff == AudioParameter::valueOff) {
+ isTurnedOn = false;
+ }
+ if (!isTurnedOn.has_value()) {
+ ALOGE("setParameters: parameter key \"%s\" has invalid value \"%s\"",
+ AudioParameter::keyScreenState, onOrOff.c_str());
+ return BAD_VALUE;
+ }
+ return statusTFromBinderStatus(
+ mModule->updateScreenState(isTurnedOn.value()));
+ }));
+ (void)VALUE_OR_RETURN_STATUS(filterOutAndProcessParameter<int>(
+ parameters, String8(AudioParameter::keyScreenRotation),
+ [&](int rotationDegrees) -> status_t {
+ IModule::ScreenRotation rotation;
+ switch (rotationDegrees) {
+ case 0: rotation = IModule::ScreenRotation::DEG_0; break;
+ case 90: rotation = IModule::ScreenRotation::DEG_90; break;
+ case 180: rotation = IModule::ScreenRotation::DEG_180; break;
+ case 270: rotation = IModule::ScreenRotation::DEG_270; break;
+ default:
+ ALOGE("setParameters: parameter key \"%s\" has invalid value %d",
+ AudioParameter::keyScreenRotation, rotationDegrees);
+ return BAD_VALUE;
+ }
+ return statusTFromBinderStatus(mModule->updateScreenRotation(rotation));
+ }));
+ return OK;
+}
+
status_t DeviceHalAidl::findOrCreatePatch(
const AudioPatch& requestedPatch, AudioPatch* patch, bool* created) {
std::set<int32_t> sourcePortConfigIds(requestedPatch.sourcePortConfigIds.begin(),
diff --git a/media/libaudiohal/impl/DeviceHalAidl.h b/media/libaudiohal/impl/DeviceHalAidl.h
index 37d800b..74a8b51 100644
--- a/media/libaudiohal/impl/DeviceHalAidl.h
+++ b/media/libaudiohal/impl/DeviceHalAidl.h
@@ -20,6 +20,7 @@
#include <set>
#include <vector>
+#include <aidl/android/media/audio/IHalAdapterVendorExtension.h>
#include <aidl/android/hardware/audio/core/BpModule.h>
#include <aidl/android/hardware/audio/core/sounddose/BpSoundDose.h>
#include <android-base/thread_annotations.h>
@@ -148,9 +149,11 @@
// List microphones
status_t getMicrophones(std::vector<audio_microphone_characteristic_t>* microphones) override;
- status_t addDeviceEffect(audio_port_handle_t device, sp<EffectHalInterface> effect) override;
+ status_t addDeviceEffect(
+ const struct audio_port_config *device, sp<EffectHalInterface> effect) override;
- status_t removeDeviceEffect(audio_port_handle_t device, sp<EffectHalInterface> effect) override;
+ status_t removeDeviceEffect(
+ const struct audio_port_config *device, sp<EffectHalInterface> effect) override;
status_t getMmapPolicyInfos(media::audio::common::AudioMMapPolicyType policyType __unused,
std::vector<media::audio::common::AudioMMapPolicyInfo>* policyInfos
@@ -203,7 +206,8 @@
// Must not be constructed directly by clients.
DeviceHalAidl(
const std::string& instance,
- const std::shared_ptr<::aidl::android::hardware::audio::core::IModule>& module);
+ const std::shared_ptr<::aidl::android::hardware::audio::core::IModule>& module,
+ const std::shared_ptr<::aidl::android::media::audio::IHalAdapterVendorExtension>& vext);
~DeviceHalAidl() override = default;
@@ -214,10 +218,12 @@
status_t createOrUpdatePortConfig(
const ::aidl::android::media::audio::common::AudioPortConfig& requestedPortConfig,
PortConfigs::iterator* result, bool *created);
+ status_t filterAndRetrieveBtA2dpParameters(AudioParameter &keys, AudioParameter *result);
status_t filterAndUpdateBtA2dpParameters(AudioParameter ¶meters);
status_t filterAndUpdateBtHfpParameters(AudioParameter ¶meters);
status_t filterAndUpdateBtLeParameters(AudioParameter ¶meters);
status_t filterAndUpdateBtScoParameters(AudioParameter ¶meters);
+ status_t filterAndUpdateScreenParameters(AudioParameter ¶meters);
status_t findOrCreatePatch(
const std::set<int32_t>& sourcePortConfigIds,
const std::set<int32_t>& sinkPortConfigIds,
@@ -291,6 +297,7 @@
const std::string mInstance;
const std::shared_ptr<::aidl::android::hardware::audio::core::IModule> mModule;
+ const std::shared_ptr<::aidl::android::media::audio::IHalAdapterVendorExtension> mVendorExt;
const std::shared_ptr<::aidl::android::hardware::audio::core::ITelephony> mTelephony;
const std::shared_ptr<::aidl::android::hardware::audio::core::IBluetooth> mBluetooth;
const std::shared_ptr<::aidl::android::hardware::audio::core::IBluetoothA2dp> mBluetoothA2dp;
diff --git a/media/libaudiohal/impl/DeviceHalHidl.cpp b/media/libaudiohal/impl/DeviceHalHidl.cpp
index 826461f..f96d419 100644
--- a/media/libaudiohal/impl/DeviceHalHidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalHidl.cpp
@@ -32,6 +32,7 @@
#include <util/CoreUtils.h>
#include "DeviceHalHidl.h"
+#include "EffectHalHidl.h"
#include "ParameterUtils.h"
#include "StreamHalHidl.h"
@@ -523,30 +524,32 @@
#if MAJOR_VERSION >= 6
status_t DeviceHalHidl::addDeviceEffect(
- audio_port_handle_t device, sp<EffectHalInterface> effect) {
+ const struct audio_port_config *device, sp<EffectHalInterface> effect) {
TIME_CHECK();
if (mDevice == 0) return NO_INIT;
+ auto hidlEffect = sp<effect::EffectHalHidl>::cast(effect);
return processReturn("addDeviceEffect", mDevice->addDeviceEffect(
- static_cast<AudioPortHandle>(device), effect->effectId()));
+ static_cast<AudioPortHandle>(device->id), hidlEffect->effectId()));
}
#else
status_t DeviceHalHidl::addDeviceEffect(
- audio_port_handle_t device __unused, sp<EffectHalInterface> effect __unused) {
+ const struct audio_port_config *device __unused, sp<EffectHalInterface> effect __unused) {
return INVALID_OPERATION;
}
#endif
#if MAJOR_VERSION >= 6
status_t DeviceHalHidl::removeDeviceEffect(
- audio_port_handle_t device, sp<EffectHalInterface> effect) {
+ const struct audio_port_config *device, sp<EffectHalInterface> effect) {
TIME_CHECK();
if (mDevice == 0) return NO_INIT;
+ auto hidlEffect = sp<effect::EffectHalHidl>::cast(effect);
return processReturn("removeDeviceEffect", mDevice->removeDeviceEffect(
- static_cast<AudioPortHandle>(device), effect->effectId()));
+ static_cast<AudioPortHandle>(device->id), hidlEffect->effectId()));
}
#else
status_t DeviceHalHidl::removeDeviceEffect(
- audio_port_handle_t device __unused, sp<EffectHalInterface> effect __unused) {
+ const struct audio_port_config *device __unused, sp<EffectHalInterface> effect __unused) {
return INVALID_OPERATION;
}
#endif
diff --git a/media/libaudiohal/impl/DeviceHalHidl.h b/media/libaudiohal/impl/DeviceHalHidl.h
index c5addde..989c1f5 100644
--- a/media/libaudiohal/impl/DeviceHalHidl.h
+++ b/media/libaudiohal/impl/DeviceHalHidl.h
@@ -105,8 +105,10 @@
// List microphones
status_t getMicrophones(std::vector<audio_microphone_characteristic_t>* microphones) override;
- status_t addDeviceEffect(audio_port_handle_t device, sp<EffectHalInterface> effect) override;
- status_t removeDeviceEffect(audio_port_handle_t device, sp<EffectHalInterface> effect) override;
+ status_t addDeviceEffect(
+ const struct audio_port_config *device, sp<EffectHalInterface> effect) override;
+ status_t removeDeviceEffect(
+ const struct audio_port_config *device, sp<EffectHalInterface> effect) override;
status_t getMmapPolicyInfos(
media::audio::common::AudioMMapPolicyType policyType __unused,
diff --git a/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp b/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp
index 8345cd2..f00b1a0 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp
+++ b/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp
@@ -34,7 +34,8 @@
using aidl::android::hardware::audio::core::IModule;
using aidl::android::hardware::audio::core::SurroundSoundConfig;
using aidl::android::media::audio::common::AudioHalEngineConfig;
-using ::android::detail::AudioHalVersionInfo;
+using aidl::android::media::audio::IHalAdapterVendorExtension;
+using android::detail::AudioHalVersionInfo;
namespace android {
@@ -83,25 +84,16 @@
if (name == nullptr || device == nullptr) {
return BAD_VALUE;
}
-
- // FIXME: Remove this call and the check for the supported module names
- // after implementing retrieval of module names on the framework side.
- // Currently it is still using the legacy XML config.
- std::vector<std::string> deviceNames;
- if (status_t status = getDeviceNames(&deviceNames); status != OK) {
- return status;
- }
std::shared_ptr<IModule> service;
- if (std::find(deviceNames.begin(), deviceNames.end(), name) != deviceNames.end()) {
- if (strcmp(name, "primary") == 0) name = "default";
- auto serviceName = std::string(IModule::descriptor) + "/" + name;
- service = IModule::fromBinder(
- ndk::SpAIBinder(AServiceManager_waitForService(serviceName.c_str())));
- ALOGE_IF(service == nullptr, "%s fromBinder %s failed", __func__, serviceName.c_str());
+ if (strcmp(name, "primary") == 0) name = "default";
+ auto serviceName = std::string(IModule::descriptor) + "/" + name;
+ service = IModule::fromBinder(
+ ndk::SpAIBinder(AServiceManager_waitForService(serviceName.c_str())));
+ if (service == nullptr) {
+ ALOGE("%s fromBinder %s failed", __func__, serviceName.c_str());
+ return NO_INIT;
}
- // If the service is a nullptr, the device object will not be really functional,
- // but will not crash either.
- *device = sp<DeviceHalAidl>::make(name, service);
+ *device = sp<DeviceHalAidl>::make(name, service, getVendorExtension());
return OK;
}
@@ -163,6 +155,20 @@
return OK;
}
+std::shared_ptr<IHalAdapterVendorExtension> DevicesFactoryHalAidl::getVendorExtension() {
+ if (!mVendorExt.has_value()) {
+ auto serviceName = std::string(IHalAdapterVendorExtension::descriptor) + "/default";
+ if (AServiceManager_isDeclared(serviceName.c_str())) {
+ mVendorExt = std::shared_ptr<IHalAdapterVendorExtension>(
+ IHalAdapterVendorExtension::fromBinder(ndk::SpAIBinder(
+ AServiceManager_waitForService(serviceName.c_str()))));
+ } else {
+ mVendorExt = nullptr;
+ }
+ }
+ return mVendorExt.value();
+}
+
// Main entry-point to the shared library.
extern "C" __attribute__((visibility("default"))) void* createIDevicesFactoryImpl() {
auto serviceName = std::string(IConfig::descriptor) + "/default";
diff --git a/media/libaudiohal/impl/DevicesFactoryHalAidl.h b/media/libaudiohal/impl/DevicesFactoryHalAidl.h
index 21957bc..97e3796 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalAidl.h
+++ b/media/libaudiohal/impl/DevicesFactoryHalAidl.h
@@ -17,6 +17,7 @@
#pragma once
#include <aidl/android/hardware/audio/core/IConfig.h>
+#include <aidl/android/media/audio/IHalAdapterVendorExtension.h>
#include <media/audiohal/DevicesFactoryHalInterface.h>
#include <utils/RefBase.h>
@@ -46,6 +47,11 @@
private:
const std::shared_ptr<::aidl::android::hardware::audio::core::IConfig> mConfig;
+ std::optional<std::shared_ptr<::aidl::android::media::audio::IHalAdapterVendorExtension>>
+ mVendorExt;
+
+ std::shared_ptr<::aidl::android::media::audio::IHalAdapterVendorExtension> getVendorExtension();
+
~DevicesFactoryHalAidl() = default;
};
diff --git a/media/libaudiohal/impl/EffectConversionHelperAidl.cpp b/media/libaudiohal/impl/EffectConversionHelperAidl.cpp
index 52fed91..72aa7d8 100644
--- a/media/libaudiohal/impl/EffectConversionHelperAidl.cpp
+++ b/media/libaudiohal/impl/EffectConversionHelperAidl.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <csignal>
#include <cstddef>
#include <cstdint>
#include <cstring>
@@ -72,14 +73,13 @@
EffectConversionHelperAidl::EffectConversionHelperAidl(
std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> effect,
- int32_t sessionId, int32_t ioId, const Descriptor& desc)
+ int32_t sessionId, int32_t ioId, const Descriptor& desc, bool isProxy)
: mSessionId(sessionId),
mIoId(ioId),
mDesc(desc),
mEffect(std::move(effect)),
mIsInputStream(mDesc.common.flags.type == Flags::Type::PRE_PROC),
- mIsProxyEffect(mDesc.common.id.proxy.has_value() &&
- mDesc.common.id.proxy.value() == mDesc.common.id.uuid) {
+ mIsProxyEffect(isProxy) {
mCommon.session = sessionId;
mCommon.ioHandle = ioId;
mCommon.input = mCommon.output = kDefaultAudioConfig;
@@ -195,11 +195,9 @@
statusTFromBinderStatus(mEffect->open(common, std::nullopt, &openReturn)));
if (mIsProxyEffect) {
- const auto& ret =
- std::static_pointer_cast<EffectProxy>(mEffect)->getEffectReturnParam();
- mStatusQ = std::make_shared<StatusMQ>(ret->statusMQ);
- mInputQ = std::make_shared<DataMQ>(ret->inputDataMQ);
- mOutputQ = std::make_shared<DataMQ>(ret->outputDataMQ);
+ mStatusQ = std::static_pointer_cast<EffectProxy>(mEffect)->getStatusMQ();
+ mInputQ = std::static_pointer_cast<EffectProxy>(mEffect)->getInputMQ();
+ mOutputQ = std::static_pointer_cast<EffectProxy>(mEffect)->getOutputMQ();
} else {
mStatusQ = std::make_shared<StatusMQ>(openReturn.statusMQ);
mInputQ = std::make_shared<DataMQ>(openReturn.inputDataMQ);
@@ -207,6 +205,7 @@
}
if (status_t status = updateEventFlags(); status != OK) {
+ ALOGV("%s closing at status %d", __func__, status);
mEffect->close();
return status;
}
@@ -319,17 +318,25 @@
mEffect->setParameter(Parameter::make<Parameter::deviceDescription>(aidlDevices))));
return *static_cast<int32_t*>(pReplyData) = OK;
}
+
status_t EffectConversionHelperAidl::handleSetVolume(uint32_t cmdSize, const void* pCmdData,
- uint32_t* replySize __unused,
- void* pReplyData __unused) {
+ uint32_t* replySize, void* pReplyData) {
if (cmdSize != 2 * sizeof(uint32_t) || !pCmdData) {
ALOGE("%s parameter invalid %u %p", __func__, cmdSize, pCmdData);
return BAD_VALUE;
}
- Parameter::VolumeStereo volume = {.left = (float)(*(uint32_t*)pCmdData) / (1 << 24),
- .right = (float)(*(uint32_t*)pCmdData + 1) / (1 << 24)};
+
+ constexpr uint32_t unityGain = 1 << 24;
+ Parameter::VolumeStereo volume = {.left = (float)(*(uint32_t*)pCmdData) / unityGain,
+ .right = (float)(*(uint32_t*)pCmdData + 1) / unityGain};
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
mEffect->setParameter(Parameter::make<Parameter::volumeStereo>(volume))));
+
+ // write unity gain back if volume was successfully set
+ if (replySize && *replySize == 2 * sizeof(uint32_t) && pReplyData) {
+ constexpr uint32_t vol_ret[2] = {unityGain, unityGain};
+ memcpy(pReplyData, vol_ret, sizeof(vol_ret));
+ }
return OK;
}
@@ -346,14 +353,15 @@
ALOGI("%s offload param offload %s ioHandle %d", __func__,
offload->isOffload ? "true" : "false", offload->ioHandle);
mCommon.ioHandle = offload->ioHandle;
- RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
- std::static_pointer_cast<EffectProxy>(mEffect)->setOffloadParam(offload)));
- // update FMQs
- const auto& ret = std::static_pointer_cast<EffectProxy>(mEffect)->getEffectReturnParam();
- mStatusQ = std::make_shared<StatusMQ>(ret->statusMQ);
- mInputQ = std::make_shared<DataMQ>(ret->inputDataMQ);
- mOutputQ = std::make_shared<DataMQ>(ret->outputDataMQ);
- RETURN_STATUS_IF_ERROR(updateEventFlags());
+ const auto& effectProxy = std::static_pointer_cast<EffectProxy>(mEffect);
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(effectProxy->setOffloadParam(offload)));
+ // update FMQs if the effect instance already open
+ if (State state; effectProxy->getState(&state).isOk() && state != State::INIT) {
+ mStatusQ = effectProxy->getStatusMQ();
+ mInputQ = effectProxy->getInputMQ();
+ mOutputQ = effectProxy->getOutputMQ();
+ updateEventFlags();
+ }
}
return *static_cast<int32_t*>(pReplyData) = OK;
}
@@ -401,17 +409,27 @@
status_t EffectConversionHelperAidl::updateEventFlags() {
status_t status = BAD_VALUE;
EventFlag* efGroup = nullptr;
- if (mStatusQ->isValid()) {
+ if (mStatusQ && mStatusQ->isValid()) {
status = EventFlag::createEventFlag(mStatusQ->getEventFlagWord(), &efGroup);
if (status != OK || !efGroup) {
ALOGE("%s: create EventFlagGroup failed, ret %d, egGroup %p", __func__, status,
efGroup);
status = (status == OK) ? BAD_VALUE : status;
}
+ } else if (isBypassing()) {
+ // for effect with bypass (no processing) flag, it's okay to not have statusQ
+ return OK;
}
+
mEfGroup.reset(efGroup, EventFlagDeleter());
return status;
}
+bool EffectConversionHelperAidl::isBypassing() const {
+ return mEffect &&
+ (mDesc.common.flags.bypass ||
+ (mIsProxyEffect && std::static_pointer_cast<EffectProxy>(mEffect)->isBypassing()));
+}
+
} // namespace effect
} // namespace android
diff --git a/media/libaudiohal/impl/EffectConversionHelperAidl.h b/media/libaudiohal/impl/EffectConversionHelperAidl.h
index 0c682ff..7c8f11b 100644
--- a/media/libaudiohal/impl/EffectConversionHelperAidl.h
+++ b/media/libaudiohal/impl/EffectConversionHelperAidl.h
@@ -41,6 +41,7 @@
std::shared_ptr<DataMQ> getInputMQ() { return mInputQ; }
std::shared_ptr<DataMQ> getOutputMQ() { return mOutputQ; }
std::shared_ptr<android::hardware::EventFlag> getEventFlagGroup() { return mEfGroup; }
+ bool isBypassing() const;
protected:
const int32_t mSessionId;
@@ -54,7 +55,7 @@
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);
+ const ::aidl::android::hardware::audio::effect::Descriptor& desc, bool isProxy);
status_t handleSetParameter(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
void* pReplyData);
diff --git a/media/libaudiohal/impl/EffectConversionHelperHidl.h b/media/libaudiohal/impl/EffectConversionHelperHidl.h
index 4371d12..ed696bf 100644
--- a/media/libaudiohal/impl/EffectConversionHelperHidl.h
+++ b/media/libaudiohal/impl/EffectConversionHelperHidl.h
@@ -19,9 +19,9 @@
#include "ConversionHelperHidl.h"
-#include PATH(android/hardware/audio/effect/FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/effect/COMMON_TYPES_FILE_VERSION/types.h)
-using EffectResult = ::android::hardware::audio::effect::CPP_VERSION::Result;
+using EffectResult = ::android::hardware::audio::effect::COMMON_TYPES_CPP_VERSION::Result;
namespace android {
diff --git a/media/libaudiohal/impl/EffectHalAidl.cpp b/media/libaudiohal/impl/EffectHalAidl.cpp
index faf5f45..e4c3309 100644
--- a/media/libaudiohal/impl/EffectHalAidl.cpp
+++ b/media/libaudiohal/impl/EffectHalAidl.cpp
@@ -61,12 +61,11 @@
namespace effect {
EffectHalAidl::EffectHalAidl(const std::shared_ptr<IFactory>& factory,
- const std::shared_ptr<IEffect>& effect, uint64_t effectId,
+ const std::shared_ptr<IEffect>& effect,
int32_t sessionId, int32_t ioId, const Descriptor& desc,
bool isProxyEffect)
: mFactory(factory),
mEffect(effect),
- mEffectId(effectId),
mSessionId(sessionId),
mIoId(ioId),
mDesc(desc),
@@ -75,9 +74,12 @@
}
EffectHalAidl::~EffectHalAidl() {
- if (mEffect) {
- mIsProxyEffect ? std::static_pointer_cast<EffectProxy>(mEffect)->destroy()
- : mFactory->destroyEffect(mEffect);
+ if (mFactory && mEffect) {
+ if (mIsProxyEffect) {
+ std::static_pointer_cast<EffectProxy>(mEffect)->destroy();
+ } else {
+ mFactory->destroyEffect(mEffect);
+ }
}
}
@@ -89,64 +91,64 @@
ALOGI("%s create UUID %s", __func__, typeUuid.toString().c_str());
if (typeUuid ==
::aidl::android::hardware::audio::effect::getEffectTypeUuidAcousticEchoCanceler()) {
- mConversion =
- std::make_unique<android::effect::AidlConversionAec>(effect, sessionId, ioId, desc);
+ mConversion = std::make_unique<android::effect::AidlConversionAec>(effect, sessionId, ioId,
+ desc, mIsProxyEffect);
} else if (typeUuid == ::aidl::android::hardware::audio::effect::
getEffectTypeUuidAutomaticGainControlV1()) {
mConversion = std::make_unique<android::effect::AidlConversionAgc1>(effect, sessionId, ioId,
- desc);
+ desc, mIsProxyEffect);
} else if (typeUuid == ::aidl::android::hardware::audio::effect::
getEffectTypeUuidAutomaticGainControlV2()) {
mConversion = std::make_unique<android::effect::AidlConversionAgc2>(effect, sessionId, ioId,
- desc);
+ desc, mIsProxyEffect);
} else if (typeUuid == ::aidl::android::hardware::audio::effect::getEffectTypeUuidBassBoost()) {
- mConversion = std::make_unique<android::effect::AidlConversionBassBoost>(effect, sessionId,
- ioId, desc);
+ mConversion = std::make_unique<android::effect::AidlConversionBassBoost>(
+ effect, sessionId, ioId, desc, mIsProxyEffect);
} else if (typeUuid == ::aidl::android::hardware::audio::effect::getEffectTypeUuidDownmix()) {
- mConversion = std::make_unique<android::effect::AidlConversionDownmix>(effect, sessionId,
- ioId, desc);
+ mConversion = std::make_unique<android::effect::AidlConversionDownmix>(
+ effect, sessionId, ioId, desc, mIsProxyEffect);
} else if (typeUuid ==
::aidl::android::hardware::audio::effect::getEffectTypeUuidDynamicsProcessing()) {
- mConversion =
- std::make_unique<android::effect::AidlConversionDp>(effect, sessionId, ioId, desc);
+ mConversion = std::make_unique<android::effect::AidlConversionDp>(effect, sessionId, ioId,
+ desc, mIsProxyEffect);
} else if (typeUuid == ::aidl::android::hardware::audio::effect::getEffectTypeUuidEnvReverb()) {
- mConversion = std::make_unique<android::effect::AidlConversionEnvReverb>(effect, sessionId,
- ioId, desc);
+ mConversion = std::make_unique<android::effect::AidlConversionEnvReverb>(
+ effect, sessionId, ioId, desc, mIsProxyEffect);
} else if (typeUuid == ::aidl::android::hardware::audio::effect::getEffectTypeUuidEqualizer()) {
- mConversion =
- std::make_unique<android::effect::AidlConversionEq>(effect, sessionId, ioId, desc);
+ mConversion = std::make_unique<android::effect::AidlConversionEq>(effect, sessionId, ioId,
+ desc, mIsProxyEffect);
} else if (typeUuid ==
::aidl::android::hardware::audio::effect::getEffectTypeUuidHapticGenerator()) {
mConversion = std::make_unique<android::effect::AidlConversionHapticGenerator>(
- effect, sessionId, ioId, desc);
+ effect, sessionId, ioId, desc, mIsProxyEffect);
} else if (typeUuid ==
::aidl::android::hardware::audio::effect::getEffectTypeUuidLoudnessEnhancer()) {
mConversion = std::make_unique<android::effect::AidlConversionLoudnessEnhancer>(
- effect, sessionId, ioId, desc);
+ effect, sessionId, ioId, desc, mIsProxyEffect);
} else if (typeUuid ==
::aidl::android::hardware::audio::effect::getEffectTypeUuidNoiseSuppression()) {
mConversion = std::make_unique<android::effect::AidlConversionNoiseSuppression>(
- effect, sessionId, ioId, desc);
+ effect, sessionId, ioId, desc, mIsProxyEffect);
} else if (typeUuid ==
::aidl::android::hardware::audio::effect::getEffectTypeUuidPresetReverb()) {
mConversion = std::make_unique<android::effect::AidlConversionPresetReverb>(
- effect, sessionId, ioId, desc);
+ effect, sessionId, ioId, desc, mIsProxyEffect);
} else if (typeUuid ==
::aidl::android::hardware::audio::effect::getEffectTypeUuidSpatializer()) {
mConversion = std::make_unique<android::effect::AidlConversionSpatializer>(
- effect, sessionId, ioId, desc);
+ effect, sessionId, ioId, desc, mIsProxyEffect);
} else if (typeUuid ==
::aidl::android::hardware::audio::effect::getEffectTypeUuidVirtualizer()) {
mConversion = std::make_unique<android::effect::AidlConversionVirtualizer>(
- effect, sessionId, ioId, desc);
+ effect, sessionId, ioId, desc, mIsProxyEffect);
} else if (typeUuid ==
::aidl::android::hardware::audio::effect::getEffectTypeUuidVisualizer()) {
- mConversion = std::make_unique<android::effect::AidlConversionVisualizer>(effect, sessionId,
- ioId, desc);
+ mConversion = std::make_unique<android::effect::AidlConversionVisualizer>(
+ effect, sessionId, ioId, desc, mIsProxyEffect);
} else {
// For unknown UUID, use vendor extension implementation
mConversion = std::make_unique<android::effect::AidlConversionVendorExtension>(
- effect, sessionId, ioId, desc);
+ effect, sessionId, ioId, desc, mIsProxyEffect);
}
return OK;
}
@@ -167,6 +169,9 @@
auto inputQ = mConversion->getInputMQ();
auto outputQ = mConversion->getOutputMQ();
auto efGroup = mConversion->getEventFlagGroup();
+ if (mConversion->isBypassing()) {
+ return OK;
+ }
if (!statusQ || !statusQ->isValid() || !inputQ || !inputQ->isValid() || !outputQ ||
!outputQ->isValid() || !efGroup) {
ALOGE("%s invalid FMQ [Status %d I %d O %d] efGroup %p", __func__,
diff --git a/media/libaudiohal/impl/EffectHalAidl.h b/media/libaudiohal/impl/EffectHalAidl.h
index 47049d7..1b7a3d6 100644
--- a/media/libaudiohal/impl/EffectHalAidl.h
+++ b/media/libaudiohal/impl/EffectHalAidl.h
@@ -56,13 +56,8 @@
// Free resources on the remote side.
status_t close() override;
- // Whether it's a local implementation.
- bool isLocal() const override { return false; }
-
status_t dump(int fd) override;
- uint64_t effectId() const override { return mEffectId; }
-
const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> getIEffect() const {
return mEffect;
}
@@ -75,7 +70,6 @@
const std::shared_ptr<::aidl::android::hardware::audio::effect::IFactory> mFactory;
const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> mEffect;
- const uint64_t mEffectId;
const int32_t mSessionId;
const int32_t mIoId;
const ::aidl::android::hardware::audio::effect::Descriptor mDesc;
@@ -93,7 +87,7 @@
EffectHalAidl(
const std::shared_ptr<::aidl::android::hardware::audio::effect::IFactory>& factory,
const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& effect,
- uint64_t effectId, int32_t sessionId, int32_t ioId,
+ int32_t sessionId, int32_t ioId,
const ::aidl::android::hardware::audio::effect::Descriptor& desc,
bool isProxyEffect);
bool setEffectReverse(bool reverse);
diff --git a/media/libaudiohal/impl/EffectHalHidl.h b/media/libaudiohal/impl/EffectHalHidl.h
index 94dcd7e..dda21ed 100644
--- a/media/libaudiohal/impl/EffectHalHidl.h
+++ b/media/libaudiohal/impl/EffectHalHidl.h
@@ -17,7 +17,7 @@
#ifndef ANDROID_HARDWARE_EFFECT_HAL_HIDL_H
#define ANDROID_HARDWARE_EFFECT_HAL_HIDL_H
-#include PATH(android/hardware/audio/effect/FILE_VERSION/IEffect.h)
+#include PATH(android/hardware/audio/effect/COMMON_TYPES_FILE_VERSION/IEffect.h)
#include <media/audiohal/EffectHalInterface.h>
#include <fmq/EventFlag.h>
#include <fmq/MessageQueue.h>
@@ -31,7 +31,7 @@
namespace android {
namespace effect {
-using namespace ::android::hardware::audio::effect::CPP_VERSION;
+using namespace ::android::hardware::audio::effect::COMMON_TYPES_CPP_VERSION;
class EffectHalHidl : public EffectHalInterface, public EffectConversionHelperHidl
{
@@ -59,12 +59,9 @@
// Free resources on the remote side.
virtual status_t close();
- // Whether it's a local implementation.
- virtual bool isLocal() const { return false; }
-
virtual status_t dump(int fd);
- virtual uint64_t effectId() const { return mEffectId; }
+ uint64_t effectId() const { return mEffectId; }
private:
friend class EffectsFactoryHalHidl;
diff --git a/media/libaudiohal/impl/EffectProxy.cpp b/media/libaudiohal/impl/EffectProxy.cpp
index b61532d..f83d479 100644
--- a/media/libaudiohal/impl/EffectProxy.cpp
+++ b/media/libaudiohal/impl/EffectProxy.cpp
@@ -15,15 +15,18 @@
*/
#include <algorithm>
+#include <iterator>
#include <memory>
#define LOG_TAG "EffectProxy"
-//#define LOG_NDEBUG 0
+// #define LOG_NDEBUG 0
#include <fmq/AidlMessageQueue.h>
+#include <system/audio_aidl_utils.h>
#include <utils/Log.h>
#include "EffectProxy.h"
+using ::aidl::android::hardware::audio::effect::Capability;
using ::aidl::android::hardware::audio::effect::CommandId;
using ::aidl::android::hardware::audio::effect::Descriptor;
using ::aidl::android::hardware::audio::effect::Flags;
@@ -33,17 +36,27 @@
using ::aidl::android::hardware::audio::effect::State;
using ::aidl::android::media::audio::common::AudioUuid;
-namespace android {
-namespace effect {
+namespace android::effect {
-EffectProxy::EffectProxy(const Descriptor::Identity& id, const std::shared_ptr<IFactory>& factory)
- : mIdentity([](const Descriptor::Identity& subId) {
- // update EffectProxy implementation UUID to the sub-effect proxy UUID
- ALOG_ASSERT(subId.proxy.has_value(), "Sub-effect Identity must have valid proxy UUID");
- Descriptor::Identity tempId = subId;
- tempId.uuid = subId.proxy.value();
- return tempId;
- }(id)),
+EffectProxy::EffectProxy(const AudioUuid& uuid, const std::vector<Descriptor>& descriptors,
+ const std::shared_ptr<IFactory>& factory)
+ : mDescriptorCommon(buildDescriptorCommon(uuid, descriptors)),
+ mSubEffects(
+ [](const std::vector<Descriptor>& descs, const std::shared_ptr<IFactory>& factory) {
+ std::vector<SubEffect> subEffects;
+ ALOG_ASSERT(factory, "invalid EffectFactory handle");
+ ndk::ScopedAStatus status = ndk::ScopedAStatus::ok();
+ for (const auto& desc : descs) {
+ SubEffect sub({.descriptor = desc});
+ status = factory->createEffect(desc.common.id.uuid, &sub.handle);
+ if (!status.isOk() || !sub.handle) {
+ ALOGW("%s create sub-effect %s failed", __func__,
+ ::android::audio::utils::toString(desc.common.id.uuid).c_str());
+ }
+ subEffects.emplace_back(sub);
+ }
+ return subEffects;
+ }(descriptors, factory)),
mFactory(factory) {}
EffectProxy::~EffectProxy() {
@@ -52,68 +65,9 @@
mSubEffects.clear();
}
-// sub effect must have same proxy UUID as EffectProxy, and the type UUID must match.
-ndk::ScopedAStatus EffectProxy::addSubEffect(const Descriptor& sub) {
- ALOGV("%s: %s", __func__, mIdentity.type.toString().c_str());
- if (0 != mSubEffects.count(sub.common.id) || !sub.common.id.proxy.has_value() ||
- sub.common.id.proxy.value() != mIdentity.uuid) {
- ALOGE("%s sub effect already exist or mismatch %s", __func__, sub.toString().c_str());
- return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
- "illegalSubEffect");
- }
-
- // not create sub-effect yet
- std::get<SubEffectTupleIndex::HANDLE>(mSubEffects[sub.common.id]) = nullptr;
- std::get<SubEffectTupleIndex::DESCRIPTOR>(mSubEffects[sub.common.id]) = sub;
- // set the last added sub-effect to active before setOffloadParam()
- mActiveSub = sub.common.id;
- ALOGI("%s add %s to proxy %s flag %s", __func__, mActiveSub.toString().c_str(),
- mIdentity.toString().c_str(), sub.common.flags.toString().c_str());
-
- if (sub.common.flags.hwAcceleratorMode == Flags::HardwareAccelerator::TUNNEL) {
- mSubFlags.hwAcceleratorMode = Flags::HardwareAccelerator::TUNNEL;
- }
-
- // initial flag values before we know which sub-effect to active (with setOffloadParam)
- // same as HIDL EffectProxy flags
- mSubFlags.type = Flags::Type::INSERT;
- mSubFlags.insert = Flags::Insert::LAST;
- mSubFlags.volume = Flags::Volume::CTRL;
-
- // set indication if any sub-effect indication was set
- mSubFlags.offloadIndication |= sub.common.flags.offloadIndication;
- mSubFlags.deviceIndication |= sub.common.flags.deviceIndication;
- mSubFlags.audioModeIndication |= sub.common.flags.audioModeIndication;
- mSubFlags.audioSourceIndication |= sub.common.flags.audioSourceIndication;
-
- // set bypass when all sub-effects are bypassing
- mSubFlags.bypass &= sub.common.flags.bypass;
- return ndk::ScopedAStatus::ok();
-}
-
-ndk::ScopedAStatus EffectProxy::create() {
- ALOGV("%s: %s", __func__, mIdentity.type.toString().c_str());
- ndk::ScopedAStatus status = ndk::ScopedAStatus::ok();
-
- for (auto& sub : mSubEffects) {
- auto& effectHandle = std::get<SubEffectTupleIndex::HANDLE>(sub.second);
- ALOGI("%s sub-effect %s", __func__, sub.first.uuid.toString().c_str());
- status = mFactory->createEffect(sub.first.uuid, &effectHandle);
- if (!status.isOk() || !effectHandle) {
- ALOGE("%s sub-effect failed %s", __func__, sub.first.uuid.toString().c_str());
- break;
- }
- }
-
- // destroy all created effects if failure
- if (!status.isOk()) {
- destroy();
- }
- return status;
-}
-
ndk::ScopedAStatus EffectProxy::destroy() {
- ALOGV("%s: %s", __func__, mIdentity.type.toString().c_str());
+ ALOGV("%s: %s", __func__,
+ ::android::audio::utils::toString(mDescriptorCommon.id.type).c_str());
return runWithAllSubEffects([&](std::shared_ptr<IEffect>& effect) {
ndk::ScopedAStatus status = mFactory->destroyEffect(effect);
if (status.isOk()) {
@@ -123,28 +77,24 @@
});
}
-const IEffect::OpenEffectReturn* EffectProxy::getEffectReturnParam() {
- return &std::get<SubEffectTupleIndex::RETURN>(mSubEffects[mActiveSub]);
-}
-
ndk::ScopedAStatus EffectProxy::setOffloadParam(const effect_offload_param_t* offload) {
const auto& itor = std::find_if(mSubEffects.begin(), mSubEffects.end(), [&](const auto& sub) {
- const auto& desc = std::get<SubEffectTupleIndex::DESCRIPTOR>(sub.second);
- ALOGI("%s: isOffload %d sub-effect: %s, flags %s", __func__, offload->isOffload,
- desc.common.id.uuid.toString().c_str(), desc.common.flags.toString().c_str());
+ const auto& desc = sub.descriptor;
return offload->isOffload ==
(desc.common.flags.hwAcceleratorMode == Flags::HardwareAccelerator::TUNNEL);
});
if (itor == mSubEffects.end()) {
ALOGE("%s no %soffload sub-effect found", __func__, offload->isOffload ? "" : "non-");
+ mActiveSubIdx = 0;
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_NULL_POINTER,
"noActiveEffctFound");
}
- mActiveSub = itor->first;
- ALOGI("%s: active %soffload sub-effect: %s, flags %s", __func__,
- offload->isOffload ? "" : "non-", mActiveSub.uuid.toString().c_str(),
- std::get<SubEffectTupleIndex::DESCRIPTOR>(itor->second).common.flags.toString().c_str());
+ mActiveSubIdx = std::distance(mSubEffects.begin(), itor);
+ ALOGV("%s: active %soffload sub-effect %zu descriptor: %s", __func__,
+ offload->isOffload ? "" : "non-", mActiveSubIdx,
+ ::android::audio::utils::toString(mSubEffects[mActiveSubIdx].descriptor.common.id.uuid)
+ .c_str());
return ndk::ScopedAStatus::ok();
}
@@ -152,20 +102,24 @@
ndk::ScopedAStatus EffectProxy::open(const Parameter::Common& common,
const std::optional<Parameter::Specific>& specific,
IEffect::OpenEffectReturn* ret __unused) {
- ALOGV("%s: %s", __func__, mIdentity.type.toString().c_str());
ndk::ScopedAStatus status = ndk::ScopedAStatus::fromExceptionCodeWithMessage(
EX_ILLEGAL_ARGUMENT, "nullEffectHandle");
for (auto& sub : mSubEffects) {
- auto& effect = std::get<SubEffectTupleIndex::HANDLE>(sub.second);
- auto& openRet = std::get<SubEffectTupleIndex::RETURN>(sub.second);
- if (!effect || !(status = effect->open(common, specific, &openRet)).isOk()) {
- ALOGE("%s: failed to open UUID %s", __func__, sub.first.uuid.toString().c_str());
+ IEffect::OpenEffectReturn openReturn;
+ if (!sub.handle || !(status = sub.handle->open(common, specific, &openReturn)).isOk()) {
+ ALOGE("%s: failed to open %p UUID %s", __func__, sub.handle.get(),
+ ::android::audio::utils::toString(sub.descriptor.common.id.uuid).c_str());
break;
}
+ sub.effectMq.statusQ = std::make_shared<StatusMQ>(openReturn.statusMQ);
+ sub.effectMq.inputQ = std::make_shared<DataMQ>(openReturn.inputDataMQ);
+ sub.effectMq.outputQ = std::make_shared<DataMQ>(openReturn.outputDataMQ);
}
// close all opened effects if failure
if (!status.isOk()) {
+ ALOGE("%s: closing all sub-effects with error %s", __func__,
+ status.getDescription().c_str());
close();
}
@@ -173,38 +127,68 @@
}
ndk::ScopedAStatus EffectProxy::close() {
- ALOGV("%s: %s", __func__, mIdentity.type.toString().c_str());
return runWithAllSubEffects([&](std::shared_ptr<IEffect>& effect) {
return effect->close();
});
}
ndk::ScopedAStatus EffectProxy::getDescriptor(Descriptor* desc) {
+ desc->common = mDescriptorCommon;
+ desc->capability = mSubEffects[mActiveSubIdx].descriptor.capability;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus EffectProxy::buildDescriptor(const AudioUuid& uuid,
+ const std::vector<Descriptor>& subEffectDescs,
+ Descriptor* desc) {
if (!desc) {
- ALOGE("%s: nuull descriptor pointer", __func__);
+ ALOGE("%s: null descriptor pointer", __func__);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_NULL_POINTER, "nullptr");
}
- auto& activeSubEffect = std::get<SubEffectTupleIndex::HANDLE>(mSubEffects[mActiveSub]);
- // return initial descriptor if no active sub-effect exist
- if (!activeSubEffect) {
- desc->common.id = mIdentity;
- desc->common.flags = mSubFlags;
- desc->common.name = "Proxy";
- desc->common.implementor = "AOSP";
- } else {
- *desc = std::get<SubEffectTupleIndex::DESCRIPTOR>(mSubEffects[mActiveSub]);
- desc->common.id = mIdentity;
+ if (subEffectDescs.size() < 2) {
+ ALOGE("%s: proxy need at least 2 sub-effects, got %zu", __func__, subEffectDescs.size());
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "needMoreSubEffects");
}
- ALOGI("%s with %s", __func__, desc->toString().c_str());
+ desc->common = buildDescriptorCommon(uuid, subEffectDescs);
return ndk::ScopedAStatus::ok();
}
+Descriptor::Common EffectProxy::buildDescriptorCommon(
+ const AudioUuid& uuid, const std::vector<Descriptor>& subEffectDescs) {
+ Descriptor::Common common;
+ for (const auto& desc : subEffectDescs) {
+ if (desc.common.flags.hwAcceleratorMode == Flags::HardwareAccelerator::TUNNEL) {
+ common.flags.hwAcceleratorMode = Flags::HardwareAccelerator::TUNNEL;
+ }
+
+ // initial flag values before we know which sub-effect to active (with setOffloadParam)
+ // same as HIDL EffectProxy flags
+ common.flags.type = Flags::Type::INSERT;
+ common.flags.insert = Flags::Insert::LAST;
+ common.flags.volume = Flags::Volume::CTRL;
+
+ // set indication if any sub-effect indication was set
+ common.flags.offloadIndication |= desc.common.flags.offloadIndication;
+ common.flags.deviceIndication |= desc.common.flags.deviceIndication;
+ common.flags.audioModeIndication |= desc.common.flags.audioModeIndication;
+ common.flags.audioSourceIndication |= desc.common.flags.audioSourceIndication;
+ }
+
+ // copy type UUID from any of sub-effects, all sub-effects should have same type
+ common.id.type = subEffectDescs[0].common.id.type;
+ // replace implementation UUID with proxy UUID.
+ common.id.uuid = uuid;
+ common.id.proxy = std::nullopt;
+ common.name = "Proxy";
+ common.implementor = "AOSP";
+ return common;
+}
+
// Handle with active sub-effect first, only send to other sub-effects when success
ndk::ScopedAStatus EffectProxy::command(CommandId id) {
- ALOGV("%s: %s, command %s", __func__, mIdentity.type.toString().c_str(),
- android::internal::ToString(id).c_str());
return runWithActiveSubEffectThenOthers(
[&](const std::shared_ptr<IEffect>& effect) -> ndk::ScopedAStatus {
return effect->command(id);
@@ -239,34 +223,30 @@
std::function<ndk::ScopedAStatus(const std::shared_ptr<IEffect>&)> const& func) {
ndk::ScopedAStatus status = runWithActiveSubEffect(func);
if (!status.isOk()) {
- return status;
+ ALOGE("%s active sub-effect return error %s", __func__, status.getDescription().c_str());
}
- // proceed with others if active sub-effect success
- for (const auto& sub : mSubEffects) {
- auto& effect = std::get<SubEffectTupleIndex::HANDLE>(sub.second);
- if (sub.first != mActiveSub) {
- if (!effect) {
- ALOGE("%s null sub-effect interface for %s", __func__,
- sub.first.toString().c_str());
- continue;
- }
- func(effect);
+ // proceed with others
+ for (size_t i = 0; i < mSubEffects.size() && i != mActiveSubIdx; i++) {
+ if (!mSubEffects[i].handle) {
+ ALOGE("%s null sub-effect interface for %s", __func__,
+ mSubEffects[i].descriptor.common.id.uuid.toString().c_str());
+ continue;
}
+ func(mSubEffects[i].handle);
}
return status;
}
ndk::ScopedAStatus EffectProxy::runWithActiveSubEffect(
std::function<ndk::ScopedAStatus(const std::shared_ptr<IEffect>&)> const& func) {
- auto& effect = std::get<SubEffectTupleIndex::HANDLE>(mSubEffects[mActiveSub]);
- if (!effect) {
+ if (!mSubEffects[mActiveSubIdx].handle) {
ALOGE("%s null active sub-effect interface, active %s", __func__,
- mActiveSub.toString().c_str());
+ mSubEffects[mActiveSubIdx].descriptor.toString().c_str());
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_NULL_POINTER,
"activeSubEffectNull");
}
- return func(effect);
+ return func(mSubEffects[mActiveSubIdx].handle);
}
ndk::ScopedAStatus EffectProxy::runWithAllSubEffects(
@@ -274,12 +254,11 @@
ndk::ScopedAStatus status = ndk::ScopedAStatus::ok();
// proceed with others if active sub-effect success
for (auto& sub : mSubEffects) {
- auto& effect = std::get<SubEffectTupleIndex::HANDLE>(sub.second);
- if (!effect) {
- ALOGW("%s null sub-effect interface for %s", __func__, sub.first.toString().c_str());
+ if (!sub.handle) {
+ ALOGW("%s null sub-effect interface %s", __func__, sub.descriptor.toString().c_str());
continue;
}
- ndk::ScopedAStatus temp = func(effect);
+ ndk::ScopedAStatus temp = func(sub.handle);
if (!temp.isOk()) {
status = ndk::ScopedAStatus::fromStatus(temp.getStatus());
}
@@ -287,5 +266,34 @@
return status;
}
-} // namespace effect
-} // namespace android
+bool EffectProxy::isBypassing() const {
+ return mSubEffects[mActiveSubIdx].descriptor.common.flags.bypass;
+}
+
+binder_status_t EffectProxy::dump(int fd, const char** args, uint32_t numArgs) {
+ const std::string dumpString = toString();
+ write(fd, dumpString.c_str(), dumpString.size());
+
+ return runWithAllSubEffects([&](std::shared_ptr<IEffect>& effect) {
+ return ndk::ScopedAStatus::fromStatus(effect->dump(fd, args, numArgs));
+ })
+ .getStatus();
+}
+
+std::string EffectProxy::toString(size_t level) const {
+ std::string prefixSpace(level, ' ');
+ std::string ss = prefixSpace + "EffectProxy:\n";
+ prefixSpace += " ";
+ base::StringAppendF(&ss, "%sDescriptorCommon: %s\n", prefixSpace.c_str(),
+ mDescriptorCommon.toString().c_str());
+ base::StringAppendF(&ss, "%sActiveSubIdx: %zu\n", prefixSpace.c_str(), mActiveSubIdx);
+ base::StringAppendF(&ss, "%sAllSubEffects:\n", prefixSpace.c_str());
+ for (size_t i = 0; i < mSubEffects.size(); i++) {
+ base::StringAppendF(&ss, "%s[%zu] - Handle: %p, %s\n", prefixSpace.c_str(), i,
+ mSubEffects[i].handle ? mSubEffects[i].handle.get() : nullptr,
+ mSubEffects[i].descriptor.toString().c_str());
+ }
+ return ss;
+}
+
+} // namespace android::effect
diff --git a/media/libaudiohal/impl/EffectProxy.h b/media/libaudiohal/impl/EffectProxy.h
index ffb8a19..18e1567 100644
--- a/media/libaudiohal/impl/EffectProxy.h
+++ b/media/libaudiohal/impl/EffectProxy.h
@@ -40,27 +40,10 @@
*/
class EffectProxy final : public ::aidl::android::hardware::audio::effect::BnEffect {
public:
- EffectProxy(const ::aidl::android::hardware::audio::effect::Descriptor::Identity& id,
- const std::shared_ptr<::aidl::android::hardware::audio::effect::IFactory>& factory);
-
- /**
- * Add a sub effect into the proxy, the descriptor of candidate sub-effect need to have same
- * proxy UUID as mUuid.
- */
- ndk::ScopedAStatus addSubEffect(
- const ::aidl::android::hardware::audio::effect::Descriptor& sub);
-
- /**
- * Create all sub-effects via AIDL IFactory, always call create() after all sub-effects added
- * successfully with addSubEffect.
- */
- ndk::ScopedAStatus create();
-
- /**
- * Destroy all sub-effects via AIDL IFactory, always call create() after all sub-effects added
- * successfully with addSubEffect.
- */
- ndk::ScopedAStatus destroy();
+ EffectProxy(
+ const ::aidl::android::media::audio::common::AudioUuid& uuid,
+ const std::vector<::aidl::android::hardware::audio::effect::Descriptor>& descriptors,
+ const std::shared_ptr<::aidl::android::hardware::audio::effect::IFactory>& factory);
/**
* Handle offload parameter setting from framework.
@@ -68,11 +51,9 @@
ndk::ScopedAStatus setOffloadParam(const effect_offload_param_t* offload);
/**
- * Get the const reference of the active sub-effect return parameters.
- * Always use this interface to get the effect open return parameters (FMQs) after a success
- * setOffloadParam() call.
+ * Destroy all sub-effects via AIDL IFactory.
*/
- const IEffect::OpenEffectReturn* getEffectReturnParam();
+ ndk::ScopedAStatus destroy();
// IEffect interfaces override
ndk::ScopedAStatus open(
@@ -91,25 +72,59 @@
const ::aidl::android::hardware::audio::effect::Parameter::Id& id,
::aidl::android::hardware::audio::effect::Parameter* param) override;
+ static ndk::ScopedAStatus buildDescriptor(
+ const ::aidl::android::media::audio::common::AudioUuid& uuid,
+ const std::vector<::aidl::android::hardware::audio::effect::Descriptor>& subEffectDescs,
+ ::aidl::android::hardware::audio::effect::Descriptor* desc);
+
+ /**
+ * Get the const reference of the active sub-effect return parameters.
+ * Always use this interface to get the effect open return parameters (FMQs) after a success
+ * setOffloadParam() call.
+ */
+ using StatusMQ = ::android::AidlMessageQueue<
+ ::aidl::android::hardware::audio::effect::IEffect::Status,
+ ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>;
+ using DataMQ = ::android::AidlMessageQueue<
+ float, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>;
+ const std::shared_ptr<StatusMQ>& getStatusMQ() const {
+ return mSubEffects[mActiveSubIdx].effectMq.statusQ;
+ }
+ const std::shared_ptr<DataMQ>& getInputMQ() const {
+ return mSubEffects[mActiveSubIdx].effectMq.inputQ;
+ }
+ const std::shared_ptr<DataMQ>& getOutputMQ() const {
+ return mSubEffects[mActiveSubIdx].effectMq.outputQ;
+ }
+
+ bool isBypassing() const;
+
+ // call dump for all sub-effects
+ binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
+
+ std::string toString(size_t indent = 0) const;
+
private:
- // Proxy identity, copy from one sub-effect, and update the implementation UUID to proxy UUID
- const ::aidl::android::hardware::audio::effect::Descriptor::Identity mIdentity;
+ // Proxy descriptor common part, copy from one sub-effect, and update the implementation UUID to
+ // proxy UUID, proxy descriptor capability part comes from the active sub-effect capability
+ const ::aidl::android::hardware::audio::effect::Descriptor::Common mDescriptorCommon;
+
+ struct EffectMQ {
+ std::shared_ptr<StatusMQ> statusQ;
+ std::shared_ptr<DataMQ> inputQ, outputQ;
+ };
+ struct SubEffect {
+ const ::aidl::android::hardware::audio::effect::Descriptor descriptor;
+ std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> handle;
+ EffectMQ effectMq;
+ };
+ std::vector<SubEffect> mSubEffects;
+
const std::shared_ptr<::aidl::android::hardware::audio::effect::IFactory> mFactory;
- // A map of sub effects descriptor to the IEffect handle and return FMQ
- enum SubEffectTupleIndex { HANDLE, DESCRIPTOR, RETURN };
- using EffectProxySub =
- std::tuple<std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>,
- ::aidl::android::hardware::audio::effect::Descriptor,
- ::aidl::android::hardware::audio::effect::IEffect::OpenEffectReturn>;
- std::map<const ::aidl::android::hardware::audio::effect::Descriptor::Identity, EffectProxySub>
- mSubEffects;
-
- // Descriptor of the only active effect in the mSubEffects map
- ::aidl::android::hardware::audio::effect::Descriptor::Identity mActiveSub;
-
- // keep the flag of sub-effects
- ::aidl::android::hardware::audio::effect::Flags mSubFlags;
+ // index of the active sub-effects, by default use the first one (index 0)
+ // It's safe to assume there will always at least two SubEffects in mSubEffects
+ size_t mActiveSubIdx = 0;
ndk::ScopedAStatus runWithActiveSubEffectThenOthers(
std::function<ndk::ScopedAStatus(
@@ -122,6 +137,12 @@
ndk::ScopedAStatus runWithAllSubEffects(
std::function<ndk::ScopedAStatus(std::shared_ptr<IEffect>&)> const& func);
+ // build Descriptor.Common with all sub-effect descriptors
+ static ::aidl::android::hardware::audio::effect::Descriptor::Common buildDescriptorCommon(
+ const ::aidl::android::media::audio::common::AudioUuid& uuid,
+ const std::vector<::aidl::android::hardware::audio::effect::Descriptor>&
+ subEffectDescs);
+
// close and release all sub-effects
~EffectProxy();
};
diff --git a/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp b/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
index 7b9088e..1c5e474 100644
--- a/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
+++ b/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
@@ -28,6 +28,7 @@
#include <media/AidlConversionCppNdk.h>
#include <media/AidlConversionEffect.h>
#include <system/audio.h>
+#include <system/audio_aidl_utils.h>
#include <utils/Log.h>
#include "EffectBufferHalAidl.h"
@@ -43,6 +44,7 @@
using ::aidl::android::media::audio::common::AudioSource;
using ::aidl::android::media::audio::common::AudioStreamType;
using ::aidl::android::media::audio::common::AudioUuid;
+using ::android::audio::utils::toString;
using ::android::base::unexpected;
using ::android::detail::AudioHalVersionInfo;
@@ -66,26 +68,28 @@
}
return list;
}()),
- mUuidProxyMap([this]() {
- std::map<AudioUuid, std::shared_ptr<EffectProxy>> proxyMap;
- for (const auto& desc : mHalDescList) {
- // create EffectProxy
+ mProxyUuidDescriptorMap([this]() {
+ std::map<AudioUuid, std::vector<Descriptor>> proxyUuidMap;
+ for (auto& desc : mHalDescList) {
if (desc.common.id.proxy.has_value()) {
- const auto& uuid = desc.common.id.proxy.value();
- if (0 == proxyMap.count(uuid)) {
- proxyMap.insert({uuid, ndk::SharedRefBase::make<EffectProxy>(desc.common.id,
- mFactory)});
+ auto& uuid = desc.common.id.proxy.value();
+ if (proxyUuidMap.count(uuid) == 0) {
+ proxyUuidMap.insert({uuid, {desc}});
+ } else {
+ proxyUuidMap[uuid].emplace_back(desc);
}
- proxyMap[uuid]->addSubEffect(desc);
- ALOGI("%s addSubEffect %s", __func__, desc.common.toString().c_str());
}
}
- return proxyMap;
+ return proxyUuidMap;
}()),
mProxyDescList([this]() {
std::vector<Descriptor> list;
- for (const auto& proxy : mUuidProxyMap) {
- if (Descriptor desc; proxy.second && proxy.second->getDescriptor(&desc).isOk()) {
+ for (const auto& proxy : mProxyUuidDescriptorMap) {
+ if (Descriptor desc;
+ EffectProxy::buildDescriptor(proxy.first /* uuid */,
+ proxy.second /* sub-effect descriptor list */,
+ &desc /* proxy descriptor */)
+ .isOk()) {
list.emplace_back(std::move(desc));
}
}
@@ -116,7 +120,8 @@
}
*pNumEffects = mEffectCount;
- ALOGI("%s %d", __func__, *pNumEffects);
+ ALOGD("%s %d non %zu proxyMap %zu proxyDesc %zu", __func__, *pNumEffects,
+ mNonProxyDescList.size(), mProxyUuidDescriptorMap.size(), mProxyDescList.size());
return OK;
}
@@ -181,38 +186,31 @@
// Use EffectProxy interface instead of IFactory to create
const bool isProxy = isProxyEffect(aidlUuid);
if (isProxy) {
- aidlEffect = mUuidProxyMap.at(aidlUuid);
- RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mUuidProxyMap.at(aidlUuid)->create()));
+ aidlEffect = ndk::SharedRefBase::make<EffectProxy>(
+ aidlUuid, mProxyUuidDescriptorMap.at(aidlUuid) /* sub-effect descriptor list */,
+ mFactory);
+ mProxyList.emplace_back(std::static_pointer_cast<EffectProxy>(aidlEffect));
} else {
RETURN_STATUS_IF_ERROR(
statusTFromBinderStatus(mFactory->createEffect(aidlUuid, &aidlEffect)));
}
if (aidlEffect == nullptr) {
- ALOGE("%s failed to create effect with UUID: %s", __func__, aidlUuid.toString().c_str());
+ ALOGE("%s failed to create effect with UUID: %s", __func__, toString(aidlUuid).c_str());
return NAME_NOT_FOUND;
}
Descriptor desc;
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(aidlEffect->getDescriptor(&desc)));
- uint64_t effectId;
- {
- std::lock_guard lg(mLock);
- effectId = ++mEffectIdCounter;
- }
-
- *effect =
- sp<EffectHalAidl>::make(mFactory, aidlEffect, effectId, sessionId, ioId, desc, isProxy);
+ *effect = sp<EffectHalAidl>::make(mFactory, aidlEffect, sessionId, ioId, desc, isProxy);
return OK;
}
status_t EffectsFactoryHalAidl::dumpEffects(int fd) {
status_t ret = OK;
// record the error ret and continue dump as many effects as possible
- for (const auto& proxy : mUuidProxyMap) {
- if (proxy.second) {
- if (status_t temp = proxy.second->dump(fd, nullptr, 0); temp != OK) {
- ret = temp;
- }
+ for (const auto& proxy : mProxyList) {
+ if (status_t temp = BAD_VALUE; proxy && (temp = proxy->dump(fd, nullptr, 0)) != OK) {
+ ret = temp;
}
}
RETURN_STATUS_IF_ERROR(mFactory->dump(fd, nullptr, 0));
@@ -244,10 +242,10 @@
auto matchIt = std::find_if(list.begin(), list.end(),
[&](const auto& desc) { return desc.common.id.uuid == uuid; });
if (matchIt == list.end()) {
- ALOGE("%s UUID not found in HAL and proxy list %s", __func__, uuid.toString().c_str());
+ ALOGE("%s UUID not found in HAL and proxy list %s", __func__, toString(uuid).c_str());
return BAD_VALUE;
}
- ALOGI("%s UUID impl found %s", __func__, uuid.toString().c_str());
+ ALOGI("%s UUID impl found %s", __func__, toString(uuid).c_str());
*pDescriptor = VALUE_OR_RETURN_STATUS(
::aidl::android::aidl2legacy_Descriptor_effect_descriptor(*matchIt));
@@ -266,10 +264,10 @@
std::copy_if(mProxyDescList.begin(), mProxyDescList.end(), std::back_inserter(result),
[&](auto& desc) { return desc.common.id.type == type; });
if (result.empty()) {
- ALOGW("%s UUID type not found in HAL and proxy list %s", __func__, type.toString().c_str());
+ ALOGW("%s UUID type not found in HAL and proxy list %s", __func__, toString(type).c_str());
return BAD_VALUE;
}
- ALOGI("%s UUID type found %zu \n %s", __func__, result.size(), type.toString().c_str());
+ ALOGI("%s UUID type found %zu \n %s", __func__, result.size(), toString(type).c_str());
*descriptors = VALUE_OR_RETURN_STATUS(
aidl::android::convertContainer<std::vector<effect_descriptor_t>>(
@@ -278,7 +276,7 @@
}
bool EffectsFactoryHalAidl::isProxyEffect(const AudioUuid& uuid) const {
- return 0 != mUuidProxyMap.count(uuid);
+ return 0 != mProxyUuidDescriptorMap.count(uuid);
}
std::shared_ptr<const effectsConfig::Processings> EffectsFactoryHalAidl::getProcessings() const {
diff --git a/media/libaudiohal/impl/EffectsFactoryHalAidl.h b/media/libaudiohal/impl/EffectsFactoryHalAidl.h
index 39beea2..73089b0 100644
--- a/media/libaudiohal/impl/EffectsFactoryHalAidl.h
+++ b/media/libaudiohal/impl/EffectsFactoryHalAidl.h
@@ -17,8 +17,8 @@
#pragma once
#include <cstddef>
+#include <list>
#include <memory>
-#include <mutex>
#include <aidl/android/hardware/audio/effect/IFactory.h>
#include <aidl/android/hardware/audio/effect/Processing.h>
@@ -72,10 +72,9 @@
const detail::AudioHalVersionInfo mHalVersion;
// Full list of HAL effect descriptors
const std::vector<Descriptor> mHalDescList;
- // Map of proxy UUID (key) to the proxy object
- const std::map<::aidl::android::media::audio::common::AudioUuid /* proxy impl UUID */,
- std::shared_ptr<EffectProxy>>
- mUuidProxyMap;
+ // Map of proxy UUID (key) to the Descriptor of sub-effects
+ const std::map<::aidl::android::media::audio::common::AudioUuid, std::vector<Descriptor>>
+ mProxyUuidDescriptorMap;
// List of effect proxy, initialize after mUuidProxyMap because it need to have all sub-effects
const std::vector<Descriptor> mProxyDescList;
// List of non-proxy effects
@@ -85,16 +84,16 @@
// Query result of pre and post processing from effect factory
const std::vector<Processing> mAidlProcessings;
- std::mutex mLock;
- uint64_t mEffectIdCounter GUARDED_BY(mLock) = 0; // Align with HIDL (0 is INVALID_ID)
+ // list of the EffectProxy instances
+ std::list<std::shared_ptr<EffectProxy>> mProxyList;
virtual ~EffectsFactoryHalAidl() = default;
status_t getHalDescriptorWithImplUuid(
- const aidl::android::media::audio::common::AudioUuid& uuid,
+ const ::aidl::android::media::audio::common::AudioUuid& uuid,
effect_descriptor_t* pDescriptor);
status_t getHalDescriptorWithTypeUuid(
- const aidl::android::media::audio::common::AudioUuid& type,
+ const ::aidl::android::media::audio::common::AudioUuid& type,
std::vector<effect_descriptor_t>* descriptors);
bool isProxyEffect(const aidl::android::media::audio::common::AudioUuid& uuid) const;
diff --git a/media/libaudiohal/impl/StreamHalAidl.cpp b/media/libaudiohal/impl/StreamHalAidl.cpp
index d1044dc..80e19a0 100644
--- a/media/libaudiohal/impl/StreamHalAidl.cpp
+++ b/media/libaudiohal/impl/StreamHalAidl.cpp
@@ -32,6 +32,7 @@
#include <utils/Log.h>
#include "DeviceHalAidl.h"
+#include "EffectHalAidl.h"
#include "StreamHalAidl.h"
using ::aidl::android::aidl_utils::statusTFromBinderStatus;
@@ -43,6 +44,7 @@
using ::aidl::android::hardware::audio::core::StreamDescriptor;
using ::aidl::android::hardware::audio::core::MmapBufferDescriptor;
using ::aidl::android::media::audio::common::MicrophoneDynamicInfo;
+using ::aidl::android::media::audio::IHalAdapterVendorExtension;
namespace android {
@@ -73,12 +75,14 @@
StreamHalAidl::StreamHalAidl(
std::string_view className, bool isInput, const audio_config& config,
int32_t nominalLatency, StreamContextAidl&& context,
- const std::shared_ptr<IStreamCommon>& stream)
+ const std::shared_ptr<IStreamCommon>& stream,
+ const std::shared_ptr<IHalAdapterVendorExtension>& vext)
: ConversionHelperAidl(className),
mIsInput(isInput),
mConfig(configToBase(config)),
mContext(std::move(context)),
- mStream(stream) {
+ mStream(stream),
+ mVendorExt(vext) {
{
std::lock_guard l(mLock);
mLastReply.latencyMs = nominalLatency;
@@ -125,7 +129,6 @@
status_t StreamHalAidl::setParameters(const String8& kvPairs) {
TIME_CHECK();
if (!mStream) return NO_INIT;
-
AudioParameter parameters(kvPairs);
ALOGD("%s: parameters: %s", __func__, parameters.toString().c_str());
@@ -134,18 +137,18 @@
[&](int hwAvSyncId) {
return statusTFromBinderStatus(mStream->updateHwAvSyncId(hwAvSyncId));
}));
-
- ALOGW_IF(parameters.size() != 0, "%s: unknown parameters, ignored: %s",
- __func__, parameters.toString().c_str());
- return OK;
+ return parseAndSetVendorParameters(mVendorExt, mStream, parameters);
}
status_t StreamHalAidl::getParameters(const String8& keys __unused, String8 *values) {
- ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
TIME_CHECK();
- values->clear();
- // AIDL HAL doesn't support getParameters API.
- return INVALID_OPERATION;
+ if (!mStream) return NO_INIT;
+ if (values == nullptr) {
+ return BAD_VALUE;
+ }
+ AudioParameter parameterKeys(keys), result;
+ *values = result.toString();
+ return parseAndGetVendorParameters(mVendorExt, mStream, parameterKeys, values);
}
status_t StreamHalAidl::getFrameSize(size_t *size) {
@@ -160,20 +163,26 @@
return OK;
}
-status_t StreamHalAidl::addEffect(sp<EffectHalInterface> effect __unused) {
+status_t StreamHalAidl::addEffect(sp<EffectHalInterface> effect) {
ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
TIME_CHECK();
if (!mStream) return NO_INIT;
- ALOGE("%s not implemented yet", __func__);
- return OK;
+ if (effect == nullptr) {
+ return BAD_VALUE;
+ }
+ auto aidlEffect = sp<effect::EffectHalAidl>::cast(effect);
+ return statusTFromBinderStatus(mStream->addEffect(aidlEffect->getIEffect()));
}
-status_t StreamHalAidl::removeEffect(sp<EffectHalInterface> effect __unused) {
+status_t StreamHalAidl::removeEffect(sp<EffectHalInterface> effect) {
ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
TIME_CHECK();
if (!mStream) return NO_INIT;
- ALOGE("%s not implemented yet", __func__);
- return OK;
+ if (effect == nullptr) {
+ return BAD_VALUE;
+ }
+ auto aidlEffect = sp<effect::EffectHalAidl>::cast(effect);
+ return statusTFromBinderStatus(mStream->removeEffect(aidlEffect->getIEffect()));
}
status_t StreamHalAidl::standby() {
@@ -533,9 +542,11 @@
StreamOutHalAidl::StreamOutHalAidl(
const audio_config& config, StreamContextAidl&& context, int32_t nominalLatency,
- const std::shared_ptr<IStreamOut>& stream, const sp<CallbackBroker>& callbackBroker)
+ const std::shared_ptr<IStreamOut>& stream,
+ const std::shared_ptr<IHalAdapterVendorExtension>& vext,
+ const sp<CallbackBroker>& callbackBroker)
: StreamHalAidl("StreamOutHalAidl", false /*isInput*/, config, nominalLatency,
- std::move(context), getStreamCommon(stream)),
+ std::move(context), getStreamCommon(stream), vext),
mStream(stream), mCallbackBroker(callbackBroker) {
// Initialize the offload metadata
mOffloadMetadata.sampleRate = static_cast<int32_t>(config.sample_rate);
@@ -861,9 +872,11 @@
StreamInHalAidl::StreamInHalAidl(
const audio_config& config, StreamContextAidl&& context, int32_t nominalLatency,
- const std::shared_ptr<IStreamIn>& stream, const sp<MicrophoneInfoProvider>& micInfoProvider)
+ const std::shared_ptr<IStreamIn>& stream,
+ const std::shared_ptr<IHalAdapterVendorExtension>& vext,
+ const sp<MicrophoneInfoProvider>& micInfoProvider)
: StreamHalAidl("StreamInHalAidl", true /*isInput*/, config, nominalLatency,
- std::move(context), getStreamCommon(stream)),
+ std::move(context), getStreamCommon(stream), vext),
mStream(stream), mMicInfoProvider(micInfoProvider) {}
status_t StreamInHalAidl::setGain(float gain) {
diff --git a/media/libaudiohal/impl/StreamHalAidl.h b/media/libaudiohal/impl/StreamHalAidl.h
index 75a1dd9..3b369bd 100644
--- a/media/libaudiohal/impl/StreamHalAidl.h
+++ b/media/libaudiohal/impl/StreamHalAidl.h
@@ -26,9 +26,11 @@
#include <aidl/android/hardware/audio/core/BpStreamIn.h>
#include <aidl/android/hardware/audio/core/BpStreamOut.h>
#include <aidl/android/hardware/audio/core/MmapBufferDescriptor.h>
+#include <aidl/android/media/audio/IHalAdapterVendorExtension.h>
#include <fmq/AidlMessageQueue.h>
#include <media/audiohal/EffectHalInterface.h>
#include <media/audiohal/StreamHalInterface.h>
+#include <media/AidlConversionUtil.h>
#include <media/AudioParameter.h>
#include "ConversionHelperAidl.h"
@@ -48,7 +50,7 @@
typedef AidlMessageQueue<int8_t,
::aidl::android::hardware::common::fmq::SynchronizedReadWrite> DataMQ;
- explicit StreamContextAidl(
+ StreamContextAidl(
::aidl::android::hardware::audio::core::StreamDescriptor& descriptor,
bool isAsynchronous)
: mFrameSizeBytes(descriptor.frameSizeBytes),
@@ -185,6 +187,9 @@
status_t legacyReleaseAudioPatch() override;
protected:
+ // For tests.
+ friend class sp<StreamHalAidl>;
+
template<class T>
static std::shared_ptr<::aidl::android::hardware::audio::core::IStreamCommon> getStreamCommon(
const std::shared_ptr<T>& stream);
@@ -195,7 +200,8 @@
const audio_config& config,
int32_t nominalLatency,
StreamContextAidl&& context,
- const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamCommon>& stream);
+ const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamCommon>& stream,
+ const std::shared_ptr<::aidl::android::media::audio::IHalAdapterVendorExtension>& vext);
~StreamHalAidl() override;
@@ -247,6 +253,7 @@
::aidl::android::hardware::audio::core::StreamDescriptor::Reply* reply = nullptr);
const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamCommon> mStream;
+ const std::shared_ptr<::aidl::android::media::audio::IHalAdapterVendorExtension> mVendorExt;
std::mutex mLock;
::aidl::android::hardware::audio::core::StreamDescriptor::Reply mLastReply GUARDED_BY(mLock);
// mStreamPowerLog is used for audio signal power logging.
@@ -349,6 +356,7 @@
StreamOutHalAidl(
const audio_config& config, StreamContextAidl&& context, int32_t nominalLatency,
const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamOut>& stream,
+ const std::shared_ptr<::aidl::android::media::audio::IHalAdapterVendorExtension>& vext,
const sp<CallbackBroker>& callbackBroker);
~StreamOutHalAidl() override;
@@ -401,6 +409,7 @@
StreamInHalAidl(
const audio_config& config, StreamContextAidl&& context, int32_t nominalLatency,
const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamIn>& stream,
+ const std::shared_ptr<::aidl::android::media::audio::IHalAdapterVendorExtension>& vext,
const sp<MicrophoneInfoProvider>& micInfoProvider);
~StreamInHalAidl() override = default;
diff --git a/media/libaudiohal/impl/StreamHalHidl.cpp b/media/libaudiohal/impl/StreamHalHidl.cpp
index 2b0af49..72eadc6 100644
--- a/media/libaudiohal/impl/StreamHalHidl.cpp
+++ b/media/libaudiohal/impl/StreamHalHidl.cpp
@@ -33,6 +33,7 @@
#include <util/CoreUtils.h>
#include "DeviceHalHidl.h"
+#include "EffectHalHidl.h"
#include "ParameterUtils.h"
#include "StreamHalHidl.h"
@@ -144,13 +145,15 @@
status_t StreamHalHidl::addEffect(sp<EffectHalInterface> effect) {
TIME_CHECK();
if (!mStream) return NO_INIT;
- return processReturn("addEffect", mStream->addEffect(effect->effectId()));
+ auto hidlEffect = sp<effect::EffectHalHidl>::cast(effect);
+ return processReturn("addEffect", mStream->addEffect(hidlEffect->effectId()));
}
status_t StreamHalHidl::removeEffect(sp<EffectHalInterface> effect) {
TIME_CHECK();
if (!mStream) return NO_INIT;
- return processReturn("removeEffect", mStream->removeEffect(effect->effectId()));
+ auto hidlEffect = sp<effect::EffectHalHidl>::cast(effect);
+ return processReturn("removeEffect", mStream->removeEffect(hidlEffect->effectId()));
}
status_t StreamHalHidl::standby() {
@@ -979,9 +982,10 @@
}
status_t StreamOutHalHidl::exit() {
- // Signal exiting to remote_submix HAL.
+ // Signal exiting to HALs that use intermediate pipes to close them.
AudioParameter param;
param.addInt(String8(AudioParameter::keyExiting), 1);
+ param.add(String8(AudioParameter::keyClosing), String8(AudioParameter::valueTrue));
return setParameters(param.toString());
}
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAec.h b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAec.h
index 3ee419a..61dd36a 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAec.h
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAec.h
@@ -26,8 +26,9 @@
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) {}
+ const ::aidl::android::hardware::audio::effect::Descriptor& desc,
+ bool isProxyEffect)
+ : EffectConversionHelperAidl(effect, sessionId, ioId, desc, isProxyEffect) {}
~AidlConversionAec() {}
private:
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAgc1.h b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAgc1.h
index b0509fd..364b473 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAgc1.h
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAgc1.h
@@ -26,8 +26,9 @@
public:
AidlConversionAgc1(std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> effect,
int32_t sessionId, int32_t ioId,
- const ::aidl::android::hardware::audio::effect::Descriptor& desc)
- : EffectConversionHelperAidl(effect, sessionId, ioId, desc) {}
+ const ::aidl::android::hardware::audio::effect::Descriptor& desc,
+ bool isProxyEffect)
+ : EffectConversionHelperAidl(effect, sessionId, ioId, desc, isProxyEffect) {}
~AidlConversionAgc1() {}
private:
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAgc2.h b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAgc2.h
index 8f7eac7..df9a9ec 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAgc2.h
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionAgc2.h
@@ -26,8 +26,9 @@
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) {}
+ const ::aidl::android::hardware::audio::effect::Descriptor& desc,
+ bool isProxyEffect)
+ : EffectConversionHelperAidl(effect, sessionId, ioId, desc, isProxyEffect) {}
~AidlConversionAgc2() {}
private:
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionBassBoost.h b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionBassBoost.h
index 9664aa1..424b837 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionBassBoost.h
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionBassBoost.h
@@ -27,8 +27,8 @@
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) {}
+ const ::aidl::android::hardware::audio::effect::Descriptor& desc, bool isProxyEffect)
+ : EffectConversionHelperAidl(effect, sessionId, ioId, desc, isProxyEffect) {}
~AidlConversionBassBoost() {}
private:
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionDownmix.h b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionDownmix.h
index 8b28ca3..f963f66 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionDownmix.h
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionDownmix.h
@@ -26,8 +26,9 @@
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) {}
+ const ::aidl::android::hardware::audio::effect::Descriptor& desc,
+ bool isProxyEffect)
+ : EffectConversionHelperAidl(effect, sessionId, ioId, desc, isProxyEffect) {}
~AidlConversionDownmix() {}
private:
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionDynamicsProcessing.h b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionDynamicsProcessing.h
index c5d5a54..62714c3 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionDynamicsProcessing.h
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionDynamicsProcessing.h
@@ -26,8 +26,9 @@
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) {}
+ const ::aidl::android::hardware::audio::effect::Descriptor& desc,
+ bool isProxyEffect)
+ : EffectConversionHelperAidl(effect, sessionId, ioId, desc, isProxyEffect) {}
~AidlConversionDp() {}
private:
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionEnvReverb.h b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionEnvReverb.h
index 8b92374..95042eb 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionEnvReverb.h
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionEnvReverb.h
@@ -27,8 +27,8 @@
AidlConversionEnvReverb(
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) {}
+ const ::aidl::android::hardware::audio::effect::Descriptor& desc, bool isProxyEffect)
+ : EffectConversionHelperAidl(effect, sessionId, ioId, desc, isProxyEffect) {}
~AidlConversionEnvReverb() {}
private:
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionEq.cpp b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionEq.cpp
index 45b98a1..fc867c7 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionEq.cpp
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionEq.cpp
@@ -161,6 +161,9 @@
return param.writeToValue(&bands);
}
case EQ_PARAM_LEVEL_RANGE: {
+ if (mDesc.capability.range.getTag() != Range::equalizer) {
+ return OK;
+ }
const auto& ranges = mDesc.capability.range.get<Range::equalizer>();
for (const auto& r : ranges) {
if (r.min.getTag() == Equalizer::bandLevels &&
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionEq.h b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionEq.h
index f94556c..53566e2 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionEq.h
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionEq.h
@@ -25,9 +25,10 @@
class AidlConversionEq : public EffectConversionHelperAidl {
public:
AidlConversionEq(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) {}
+ int32_t sessionId, int32_t ioId,
+ const ::aidl::android::hardware::audio::effect::Descriptor& desc,
+ bool isProxyEffect)
+ : EffectConversionHelperAidl(effect, sessionId, ioId, desc, isProxyEffect) {}
~AidlConversionEq() {}
private:
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionHapticGenerator.h b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionHapticGenerator.h
index 03114a5..9890bfb 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionHapticGenerator.h
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionHapticGenerator.h
@@ -27,8 +27,8 @@
AidlConversionHapticGenerator(
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) {}
+ const ::aidl::android::hardware::audio::effect::Descriptor& desc, bool isProxyEffect)
+ : EffectConversionHelperAidl(effect, sessionId, ioId, desc, isProxyEffect) {}
~AidlConversionHapticGenerator() {}
private:
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionLoudnessEnhancer.h b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionLoudnessEnhancer.h
index c0402f9..2ce14a6 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionLoudnessEnhancer.h
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionLoudnessEnhancer.h
@@ -27,8 +27,8 @@
AidlConversionLoudnessEnhancer(
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) {}
+ const ::aidl::android::hardware::audio::effect::Descriptor& desc, bool isProxyEffect)
+ : EffectConversionHelperAidl(effect, sessionId, ioId, desc, isProxyEffect) {}
~AidlConversionLoudnessEnhancer() {}
private:
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionNoiseSuppression.h b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionNoiseSuppression.h
index f51e13a..fac121d 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionNoiseSuppression.h
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionNoiseSuppression.h
@@ -27,8 +27,8 @@
AidlConversionNoiseSuppression(
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) {}
+ const ::aidl::android::hardware::audio::effect::Descriptor& desc, bool isProxyEffect)
+ : EffectConversionHelperAidl(effect, sessionId, ioId, desc, isProxyEffect) {}
~AidlConversionNoiseSuppression() {}
private:
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionPresetReverb.h b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionPresetReverb.h
index 397d6e6..b975d72 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionPresetReverb.h
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionPresetReverb.h
@@ -27,8 +27,8 @@
AidlConversionPresetReverb(
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) {}
+ const ::aidl::android::hardware::audio::effect::Descriptor& desc, bool isProxyEffect)
+ : EffectConversionHelperAidl(effect, sessionId, ioId, desc, isProxyEffect) {}
~AidlConversionPresetReverb() {}
private:
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionSpatializer.h b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionSpatializer.h
index c44567c..7c60b14 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionSpatializer.h
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionSpatializer.h
@@ -27,8 +27,8 @@
AidlConversionSpatializer(
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) {}
+ const ::aidl::android::hardware::audio::effect::Descriptor& desc, bool isProxyEffect)
+ : EffectConversionHelperAidl(effect, sessionId, ioId, desc, isProxyEffect) {}
~AidlConversionSpatializer() {}
private:
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVendorExtension.h b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVendorExtension.h
index fd22e5c..16bfeba 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVendorExtension.h
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVendorExtension.h
@@ -27,8 +27,8 @@
AidlConversionVendorExtension(
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) {}
+ const ::aidl::android::hardware::audio::effect::Descriptor& desc, bool isProxyEffect)
+ : EffectConversionHelperAidl(effect, sessionId, ioId, desc, isProxyEffect) {}
~AidlConversionVendorExtension() {}
private:
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVirtualizer.h b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVirtualizer.h
index 91c0fcd..359d884 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVirtualizer.h
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVirtualizer.h
@@ -27,8 +27,8 @@
AidlConversionVirtualizer(
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) {}
+ const ::aidl::android::hardware::audio::effect::Descriptor& desc, bool isProxyEffect)
+ : EffectConversionHelperAidl(effect, sessionId, ioId, desc, isProxyEffect) {}
~AidlConversionVirtualizer() {}
private:
diff --git a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVisualizer.h b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVisualizer.h
index e380bc6..bc9320f 100644
--- a/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVisualizer.h
+++ b/media/libaudiohal/impl/effectsAidlConversion/AidlConversionVisualizer.h
@@ -27,8 +27,8 @@
AidlConversionVisualizer(
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) {}
+ const ::aidl::android::hardware::audio::effect::Descriptor& desc, bool isProxyEffect)
+ : EffectConversionHelperAidl(effect, sessionId, ioId, desc, isProxyEffect) {}
~AidlConversionVisualizer() {}
private:
diff --git a/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
index 71e5e7a..a965709 100644
--- a/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
+++ b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
@@ -132,9 +132,9 @@
std::vector<audio_microphone_characteristic_t>* microphones) = 0;
virtual status_t addDeviceEffect(
- audio_port_handle_t device, sp<EffectHalInterface> effect) = 0;
+ const struct audio_port_config *device, sp<EffectHalInterface> effect) = 0;
virtual status_t removeDeviceEffect(
- audio_port_handle_t device, sp<EffectHalInterface> effect) = 0;
+ const struct audio_port_config *device, sp<EffectHalInterface> effect) = 0;
virtual status_t getMmapPolicyInfos(
media::audio::common::AudioMMapPolicyType policyType,
diff --git a/media/libaudiohal/include/media/audiohal/EffectHalInterface.h b/media/libaudiohal/include/media/audiohal/EffectHalInterface.h
index 2969c92..cf8d7f0 100644
--- a/media/libaudiohal/include/media/audiohal/EffectHalInterface.h
+++ b/media/libaudiohal/include/media/audiohal/EffectHalInterface.h
@@ -52,20 +52,14 @@
// Free resources on the remote side.
virtual status_t close() = 0;
- // Whether it's a local implementation.
- virtual bool isLocal() const = 0;
-
virtual status_t dump(int fd) = 0;
- // Unique effect ID to use with the core HAL.
- virtual uint64_t effectId() const = 0;
-
protected:
// Subclasses can not be constructed directly by clients.
- EffectHalInterface() {}
+ EffectHalInterface() = default;
// The destructor automatically releases the effect.
- virtual ~EffectHalInterface() {}
+ virtual ~EffectHalInterface() = default;
};
} // namespace android
diff --git a/media/libaudiohal/tests/Android.bp b/media/libaudiohal/tests/Android.bp
index 8210f7d..8f011c8 100644
--- a/media/libaudiohal/tests/Android.bp
+++ b/media/libaudiohal/tests/Android.bp
@@ -21,34 +21,34 @@
}
cc_defaults {
- name: "AudioHalTestDefaults",
+ name: "libaudiohal_aidl_test_default",
test_suites: ["device-tests"],
defaults: [
- "latest_android_media_audio_common_types_ndk_shared",
+ "libaudiohal_default",
+ "libaudiohal_aidl_default",
],
- cflags: [
- "-Wall",
- "-Wextra",
- "-Werror",
- "-Wthread-safety",
- "-DBACKEND_NDK",
- ],
-
shared_libs: [
- "audioclient-types-aidl-cpp",
- "libaudio_aidl_conversion_common_ndk",
"libaudiohal",
- "liblog",
- "libutils",
- "libvibrator",
],
}
cc_test {
+ name: "CoreAudioHalAidlTest",
+ srcs: [
+ "CoreAudioHalAidl_test.cpp",
+ ":core_audio_hal_aidl_src_files",
+ ],
+ defaults: ["libaudiohal_aidl_test_default"],
+ header_libs: ["libaudiohalimpl_headers"],
+}
+
+cc_test {
name: "EffectsFactoryHalInterfaceTest",
srcs: ["EffectsFactoryHalInterface_test.cpp"],
- defaults: ["AudioHalTestDefaults"],
- header_libs: ["libaudiohal_headers"],
+ defaults: ["libaudiohal_aidl_test_default"],
+ shared_libs: [
+ "libvibrator",
+ ],
}
cc_test {
@@ -58,15 +58,8 @@
":audio_effectproxy_src_files",
],
defaults: [
- "AudioHalTestDefaults",
- "latest_android_hardware_audio_effect_ndk_shared",
- "libaudiohal_default",
+ "libaudiohal_aidl_test_default",
"use_libaidlvintf_gtest_helper_static",
],
- shared_libs: [
- "android.hardware.common.fmq-V1-ndk",
- "libbinder_ndk",
- "libfmq",
- ],
header_libs: ["libaudiohalimpl_headers"],
}
diff --git a/media/libaudiohal/tests/CoreAudioHalAidl_test.cpp b/media/libaudiohal/tests/CoreAudioHalAidl_test.cpp
new file mode 100644
index 0000000..ea20794
--- /dev/null
+++ b/media/libaudiohal/tests/CoreAudioHalAidl_test.cpp
@@ -0,0 +1,607 @@
+/*
+ * Copyright 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 <memory>
+#include <string>
+#include <vector>
+
+#define LOG_TAG "CoreAudioHalAidlTest"
+#include <gtest/gtest.h>
+
+#include <DeviceHalAidl.h>
+#include <StreamHalAidl.h>
+#include <aidl/android/hardware/audio/core/BnModule.h>
+#include <aidl/android/hardware/audio/core/BnStreamCommon.h>
+#include <aidl/android/media/audio/BnHalAdapterVendorExtension.h>
+#include <aidl/android/media/audio/common/Int.h>
+#include <utils/Log.h>
+
+namespace {
+
+using ::aidl::android::hardware::audio::core::VendorParameter;
+
+class VendorParameterMock {
+ public:
+ const std::vector<std::string>& getRetrievedParameterIds() const { return mGetParameterIds; }
+ const std::vector<VendorParameter>& getAsyncParameters() const { return mAsyncParameters; }
+ const std::vector<VendorParameter>& getSyncParameters() const { return mSyncParameters; }
+
+ protected:
+ ndk::ScopedAStatus getVendorParametersImpl(const std::vector<std::string>& in_parameterIds) {
+ mGetParameterIds.insert(mGetParameterIds.end(), in_parameterIds.begin(),
+ in_parameterIds.end());
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus setVendorParametersImpl(const std::vector<VendorParameter>& in_parameters,
+ bool async) {
+ if (async) {
+ mAsyncParameters.insert(mAsyncParameters.end(), in_parameters.begin(),
+ in_parameters.end());
+ } else {
+ mSyncParameters.insert(mSyncParameters.end(), in_parameters.begin(),
+ in_parameters.end());
+ }
+ return ndk::ScopedAStatus::ok();
+ }
+
+ private:
+ std::vector<std::string> mGetParameterIds;
+ std::vector<VendorParameter> mAsyncParameters;
+ std::vector<VendorParameter> mSyncParameters;
+};
+
+class ModuleMock : public ::aidl::android::hardware::audio::core::BnModule,
+ public VendorParameterMock {
+ public:
+ bool isScreenTurnedOn() const { return mIsScreenTurnedOn; }
+ ScreenRotation getScreenRotation() const { return mScreenRotation; }
+
+ private:
+ ndk::ScopedAStatus setModuleDebug(
+ const ::aidl::android::hardware::audio::core::ModuleDebug&) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus getTelephony(
+ std::shared_ptr<::aidl::android::hardware::audio::core::ITelephony>*) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus getBluetooth(
+ std::shared_ptr<::aidl::android::hardware::audio::core::IBluetooth>*) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus getBluetoothA2dp(
+ std::shared_ptr<::aidl::android::hardware::audio::core::IBluetoothA2dp>*) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus getBluetoothLe(
+ std::shared_ptr<::aidl::android::hardware::audio::core::IBluetoothLe>*) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus connectExternalDevice(
+ const ::aidl::android::media::audio::common::AudioPort&,
+ ::aidl::android::media::audio::common::AudioPort*) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus disconnectExternalDevice(int32_t) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus getAudioPatches(
+ std::vector<::aidl::android::hardware::audio::core::AudioPatch>*) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus getAudioPort(int32_t,
+ ::aidl::android::media::audio::common::AudioPort*) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus getAudioPortConfigs(
+ std::vector<::aidl::android::media::audio::common::AudioPortConfig>*) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus getAudioPorts(
+ std::vector<::aidl::android::media::audio::common::AudioPort>*) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus getAudioRoutes(
+ std::vector<::aidl::android::hardware::audio::core::AudioRoute>*) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus getAudioRoutesForAudioPort(
+ int32_t, std::vector<::aidl::android::hardware::audio::core::AudioRoute>*) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus openInputStream(const OpenInputStreamArguments&,
+ OpenInputStreamReturn*) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus openOutputStream(const OpenOutputStreamArguments&,
+ OpenOutputStreamReturn*) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus getSupportedPlaybackRateFactors(SupportedPlaybackRateFactors*) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus setAudioPatch(const ::aidl::android::hardware::audio::core::AudioPatch&,
+ ::aidl::android::hardware::audio::core::AudioPatch*) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus setAudioPortConfig(
+ const ::aidl::android::media::audio::common::AudioPortConfig&,
+ ::aidl::android::media::audio::common::AudioPortConfig*, bool*) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus resetAudioPatch(int32_t) override { return ndk::ScopedAStatus::ok(); }
+ ndk::ScopedAStatus resetAudioPortConfig(int32_t) override { return ndk::ScopedAStatus::ok(); }
+ ndk::ScopedAStatus getMasterMute(bool*) override { return ndk::ScopedAStatus::ok(); }
+ ndk::ScopedAStatus setMasterMute(bool) override { return ndk::ScopedAStatus::ok(); }
+ ndk::ScopedAStatus getMasterVolume(float*) override { return ndk::ScopedAStatus::ok(); }
+ ndk::ScopedAStatus setMasterVolume(float) override { return ndk::ScopedAStatus::ok(); }
+ ndk::ScopedAStatus getMicMute(bool*) override { return ndk::ScopedAStatus::ok(); }
+ ndk::ScopedAStatus setMicMute(bool) override { return ndk::ScopedAStatus::ok(); }
+ ndk::ScopedAStatus getMicrophones(
+ std::vector<::aidl::android::media::audio::common::MicrophoneInfo>*) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus updateAudioMode(::aidl::android::media::audio::common::AudioMode) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus updateScreenRotation(ScreenRotation in_rotation) override {
+ mScreenRotation = in_rotation;
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus updateScreenState(bool in_isTurnedOn) override {
+ mIsScreenTurnedOn = in_isTurnedOn;
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus getSoundDose(
+ std::shared_ptr<::aidl::android::hardware::audio::core::sounddose::ISoundDose>*)
+ override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus generateHwAvSyncId(int32_t*) override { return ndk::ScopedAStatus::ok(); }
+ ndk::ScopedAStatus getVendorParameters(const std::vector<std::string>& in_parameterIds,
+ std::vector<VendorParameter>*) override {
+ return getVendorParametersImpl(in_parameterIds);
+ }
+ ndk::ScopedAStatus setVendorParameters(const std::vector<VendorParameter>& in_parameters,
+ bool async) override {
+ return setVendorParametersImpl(in_parameters, async);
+ }
+ ndk::ScopedAStatus addDeviceEffect(
+ int32_t,
+ const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>&) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus removeDeviceEffect(
+ int32_t,
+ const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>&) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus getMmapPolicyInfos(
+ ::aidl::android::media::audio::common::AudioMMapPolicyType,
+ std::vector<::aidl::android::media::audio::common::AudioMMapPolicyInfo>*) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus supportsVariableLatency(bool*) override { return ndk::ScopedAStatus::ok(); }
+ ndk::ScopedAStatus getAAudioMixerBurstCount(int32_t*) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus getAAudioHardwareBurstMinUsec(int32_t*) override {
+ return ndk::ScopedAStatus::ok();
+ }
+
+ bool mIsScreenTurnedOn = false;
+ ScreenRotation mScreenRotation = ScreenRotation::DEG_0;
+};
+
+class StreamCommonMock : public ::aidl::android::hardware::audio::core::BnStreamCommon,
+ public VendorParameterMock {
+ ndk::ScopedAStatus close() override { return ndk::ScopedAStatus::ok(); }
+ ndk::ScopedAStatus prepareToClose() override { return ndk::ScopedAStatus::ok(); }
+ ndk::ScopedAStatus updateHwAvSyncId(int32_t) override { return ndk::ScopedAStatus::ok(); }
+ ndk::ScopedAStatus getVendorParameters(const std::vector<std::string>& in_parameterIds,
+ std::vector<VendorParameter>*) override {
+ return getVendorParametersImpl(in_parameterIds);
+ }
+ ndk::ScopedAStatus setVendorParameters(const std::vector<VendorParameter>& in_parameters,
+ bool async) override {
+ return setVendorParametersImpl(in_parameters, async);
+ }
+ ndk::ScopedAStatus addEffect(
+ const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>&) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus removeEffect(
+ const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>&) override {
+ return ndk::ScopedAStatus::ok();
+ }
+};
+
+VendorParameter makeVendorParameter(const std::string& id, int value) {
+ VendorParameter result{.id = id};
+ // Note: in real life, a parcelable type defined by vendor must be used,
+ // here we use Int just for test purposes.
+ ::aidl::android::media::audio::common::Int vendorValue{.value = value};
+ result.ext.setParcelable(std::move(vendorValue));
+ return result;
+}
+
+android::status_t parseVendorParameter(const VendorParameter& param, int* value) {
+ std::optional<::aidl::android::media::audio::common::Int> vendorValue;
+ RETURN_STATUS_IF_ERROR(param.ext.getParcelable(&vendorValue));
+ if (!vendorValue.has_value()) return android::BAD_VALUE;
+ *value = vendorValue.value().value;
+ return android::OK;
+}
+
+class TestHalAdapterVendorExtension
+ : public ::aidl::android::media::audio::BnHalAdapterVendorExtension {
+ public:
+ static const std::string kLegacyParameterKey;
+ static const std::string kLegacyAsyncParameterKey;
+ static const std::string kModuleVendorParameterId;
+ static const std::string kStreamVendorParameterId;
+
+ private:
+ ndk::ScopedAStatus parseVendorParameterIds(ParameterScope in_scope,
+ const std::string& in_rawKeys,
+ std::vector<std::string>* _aidl_return) override {
+ android::AudioParameter keys(android::String8(in_rawKeys.c_str()));
+ for (size_t i = 0; i < keys.size(); ++i) {
+ android::String8 key;
+ if (android::status_t status = keys.getAt(i, key); status != android::OK) {
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ switch (in_scope) {
+ case ParameterScope::MODULE:
+ if (key == android::String8(kLegacyParameterKey.c_str()) ||
+ key == android::String8(kLegacyAsyncParameterKey.c_str())) {
+ _aidl_return->push_back(kModuleVendorParameterId);
+ } else {
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ break;
+ case ParameterScope::STREAM:
+ if (key == android::String8(kLegacyParameterKey.c_str()) ||
+ key == android::String8(kLegacyAsyncParameterKey.c_str())) {
+ _aidl_return->push_back(kStreamVendorParameterId);
+ } else {
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ break;
+ }
+ }
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus parseVendorParameters(
+ ParameterScope in_scope, const std::string& in_rawKeysAndValues,
+ std::vector<VendorParameter>* out_syncParameters,
+ std::vector<VendorParameter>* out_asyncParameters) override {
+ android::AudioParameter legacy(android::String8(in_rawKeysAndValues.c_str()));
+ for (size_t i = 0; i < legacy.size(); ++i) {
+ android::String8 key;
+ if (android::status_t status = legacy.getAt(i, key); status != android::OK) {
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ int value;
+ if (android::status_t status = legacy.getInt(key, value); status != android::OK) {
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ std::string parameterId;
+ switch (in_scope) {
+ case ParameterScope::MODULE:
+ parameterId = kModuleVendorParameterId;
+ break;
+ case ParameterScope::STREAM:
+ parameterId = kStreamVendorParameterId;
+ break;
+ }
+ if (key == android::String8(kLegacyParameterKey.c_str())) {
+ out_syncParameters->push_back(makeVendorParameter(parameterId, value));
+ } else if (key == android::String8(kLegacyAsyncParameterKey.c_str())) {
+ out_asyncParameters->push_back(makeVendorParameter(parameterId, value));
+ } else {
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ }
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus parseBluetoothA2dpReconfigureOffload(
+ const std::string&, std::vector<VendorParameter>*) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus parseBluetoothLeReconfigureOffload(const std::string&,
+ std::vector<VendorParameter>*) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus processVendorParameters(ParameterScope in_scope,
+ const std::vector<VendorParameter>& in_parameters,
+ std::string* _aidl_return) override {
+ android::AudioParameter legacy;
+ for (const auto& vendorParam : in_parameters) {
+ if ((in_scope == ParameterScope::MODULE &&
+ vendorParam.id == kModuleVendorParameterId) ||
+ (in_scope == ParameterScope::STREAM &&
+ vendorParam.id == kStreamVendorParameterId)) {
+ int value;
+ if (android::status_t status = parseVendorParameter(vendorParam, &value);
+ status != android::OK) {
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ legacy.addInt(android::String8(kLegacyParameterKey.c_str()), value);
+ }
+ }
+ *_aidl_return = legacy.toString().c_str();
+ return ndk::ScopedAStatus::ok();
+ }
+};
+
+const std::string TestHalAdapterVendorExtension::kLegacyParameterKey = "aosp_test_param";
+const std::string TestHalAdapterVendorExtension::kLegacyAsyncParameterKey = "aosp_test_param_async";
+// Note: in real life, there is no need to explicitly separate "module" and "stream"
+// parameters, here it's done just for test purposes.
+const std::string TestHalAdapterVendorExtension::kModuleVendorParameterId =
+ "aosp.test.module.parameter";
+const std::string TestHalAdapterVendorExtension::kStreamVendorParameterId =
+ "aosp.test.stream.parameter";
+
+android::String8 createParameterString(const std::string& key, const std::string& value) {
+ android::AudioParameter params;
+ params.add(android::String8(key.c_str()), android::String8(value.c_str()));
+ return params.toString();
+}
+
+android::String8 createParameterString(const std::string& key, int value) {
+ android::AudioParameter params;
+ params.addInt(android::String8(key.c_str()), value);
+ return params.toString();
+}
+
+template <typename>
+struct mf_traits {};
+template <class T, class U>
+struct mf_traits<U T::*> {
+ using member_type = U;
+};
+
+} // namespace
+
+// Provide value printers for types generated from AIDL
+// They need to be in the same namespace as the types we intend to print
+namespace aidl::android::hardware::audio::core {
+template <typename P>
+std::enable_if_t<std::is_function_v<typename mf_traits<decltype(&P::toString)>::member_type>,
+ std::ostream&>
+operator<<(std::ostream& os, const P& p) {
+ return os << p.toString();
+}
+template <typename E>
+std::enable_if_t<std::is_enum_v<E>, std::ostream&> operator<<(std::ostream& os, const E& e) {
+ return os << toString(e);
+}
+} // namespace aidl::android::hardware::audio::core
+
+using namespace android;
+
+class DeviceHalAidlTest : public testing::Test {
+ public:
+ void SetUp() override {
+ mModule = ndk::SharedRefBase::make<ModuleMock>();
+ mDevice = sp<DeviceHalAidl>::make("test", mModule, nullptr /*vext*/);
+ }
+ void TearDown() override {
+ mDevice.clear();
+ mModule.reset();
+ }
+
+ protected:
+ std::shared_ptr<ModuleMock> mModule;
+ sp<DeviceHalAidl> mDevice;
+};
+
+TEST_F(DeviceHalAidlTest, ScreenState) {
+ EXPECT_FALSE(mModule->isScreenTurnedOn());
+ EXPECT_EQ(OK, mDevice->setParameters(createParameterString(AudioParameter::keyScreenState,
+ AudioParameter::valueOn)));
+ EXPECT_TRUE(mModule->isScreenTurnedOn());
+ EXPECT_EQ(OK, mDevice->setParameters(createParameterString(AudioParameter::keyScreenState,
+ AudioParameter::valueOff)));
+ EXPECT_FALSE(mModule->isScreenTurnedOn());
+ // The adaptation layer only logs a warning.
+ EXPECT_EQ(OK, mDevice->setParameters(
+ createParameterString(AudioParameter::keyScreenState, "blah")));
+ EXPECT_FALSE(mModule->isScreenTurnedOn());
+}
+
+TEST_F(DeviceHalAidlTest, ScreenRotation) {
+ using ScreenRotation = ::aidl::android::hardware::audio::core::IModule::ScreenRotation;
+ EXPECT_EQ(ScreenRotation::DEG_0, mModule->getScreenRotation());
+ EXPECT_EQ(OK,
+ mDevice->setParameters(createParameterString(AudioParameter::keyScreenRotation, 90)));
+ EXPECT_EQ(ScreenRotation::DEG_90, mModule->getScreenRotation());
+ EXPECT_EQ(OK,
+ mDevice->setParameters(createParameterString(AudioParameter::keyScreenRotation, 0)));
+ EXPECT_EQ(ScreenRotation::DEG_0, mModule->getScreenRotation());
+ // The adaptation layer only logs a warning.
+ EXPECT_EQ(OK,
+ mDevice->setParameters(createParameterString(AudioParameter::keyScreenRotation, 42)));
+ EXPECT_EQ(ScreenRotation::DEG_0, mModule->getScreenRotation());
+}
+
+// Without a vendor extension, any unrecognized parameters must be ignored.
+TEST_F(DeviceHalAidlTest, VendorParameterIgnored) {
+ EXPECT_EQ(0UL, mModule->getAsyncParameters().size());
+ EXPECT_EQ(0UL, mModule->getSyncParameters().size());
+ EXPECT_EQ(OK, mDevice->setParameters(createParameterString("random_name", "random_value")));
+ EXPECT_EQ(0UL, mModule->getAsyncParameters().size());
+ EXPECT_EQ(0UL, mModule->getSyncParameters().size());
+
+ EXPECT_EQ(0UL, mModule->getRetrievedParameterIds().size());
+ String8 values;
+ EXPECT_EQ(OK, mDevice->getParameters(String8("random_name"), &values));
+ EXPECT_EQ(0UL, mModule->getRetrievedParameterIds().size());
+ EXPECT_TRUE(values.empty());
+}
+
+class DeviceHalAidlVendorParametersTest : public testing::Test {
+ public:
+ void SetUp() override {
+ mModule = ndk::SharedRefBase::make<ModuleMock>();
+ mVendorExt = ndk::SharedRefBase::make<TestHalAdapterVendorExtension>();
+ mDevice = sp<DeviceHalAidl>::make("test", mModule, mVendorExt);
+ }
+ void TearDown() override {
+ mDevice.clear();
+ mVendorExt.reset();
+ mModule.reset();
+ }
+
+ protected:
+ std::shared_ptr<ModuleMock> mModule;
+ std::shared_ptr<TestHalAdapterVendorExtension> mVendorExt;
+ sp<DeviceHalAidl> mDevice;
+};
+
+TEST_F(DeviceHalAidlVendorParametersTest, GetVendorParameter) {
+ EXPECT_EQ(0UL, mModule->getRetrievedParameterIds().size());
+ String8 values;
+ EXPECT_EQ(OK, mDevice->getParameters(
+ String8(TestHalAdapterVendorExtension::kLegacyParameterKey.c_str()),
+ &values));
+ EXPECT_EQ(1UL, mModule->getRetrievedParameterIds().size());
+ if (mModule->getRetrievedParameterIds().size() >= 1) {
+ EXPECT_EQ(TestHalAdapterVendorExtension::kModuleVendorParameterId,
+ mModule->getRetrievedParameterIds()[0]);
+ }
+}
+
+TEST_F(DeviceHalAidlVendorParametersTest, SetVendorParameter) {
+ EXPECT_EQ(0UL, mModule->getAsyncParameters().size());
+ EXPECT_EQ(0UL, mModule->getSyncParameters().size());
+ EXPECT_EQ(OK, mDevice->setParameters(createParameterString(
+ TestHalAdapterVendorExtension::kLegacyParameterKey, 42)));
+ EXPECT_EQ(0UL, mModule->getAsyncParameters().size());
+ EXPECT_EQ(1UL, mModule->getSyncParameters().size());
+ EXPECT_EQ(OK, mDevice->setParameters(createParameterString(
+ TestHalAdapterVendorExtension::kLegacyAsyncParameterKey, 43)));
+ EXPECT_EQ(1UL, mModule->getAsyncParameters().size());
+ EXPECT_EQ(1UL, mModule->getSyncParameters().size());
+ if (mModule->getSyncParameters().size() >= 1) {
+ EXPECT_EQ(TestHalAdapterVendorExtension::kModuleVendorParameterId,
+ mModule->getSyncParameters()[0].id);
+ int value{};
+ EXPECT_EQ(android::OK, parseVendorParameter(mModule->getSyncParameters()[0], &value));
+ EXPECT_EQ(42, value);
+ }
+ if (mModule->getAsyncParameters().size() >= 1) {
+ EXPECT_EQ(TestHalAdapterVendorExtension::kModuleVendorParameterId,
+ mModule->getAsyncParameters()[0].id);
+ int value{};
+ EXPECT_EQ(android::OK, parseVendorParameter(mModule->getAsyncParameters()[0], &value));
+ EXPECT_EQ(43, value);
+ }
+}
+
+TEST_F(DeviceHalAidlVendorParametersTest, SetInvalidVendorParameters) {
+ android::AudioParameter legacy;
+ legacy.addInt(android::String8(TestHalAdapterVendorExtension::kLegacyParameterKey.c_str()), 42);
+ legacy.addInt(android::String8(TestHalAdapterVendorExtension::kLegacyAsyncParameterKey.c_str()),
+ 43);
+ legacy.addInt(android::String8("random_name"), 44);
+ EXPECT_EQ(0UL, mModule->getAsyncParameters().size());
+ EXPECT_EQ(0UL, mModule->getSyncParameters().size());
+ // TestHalAdapterVendorExtension throws an error for unknown parameters.
+ EXPECT_EQ(android::BAD_VALUE, mDevice->setParameters(legacy.toString()));
+ EXPECT_EQ(0UL, mModule->getAsyncParameters().size());
+ EXPECT_EQ(0UL, mModule->getSyncParameters().size());
+}
+
+class StreamHalAidlVendorParametersTest : public testing::Test {
+ public:
+ void SetUp() override {
+ mStreamCommon = ndk::SharedRefBase::make<StreamCommonMock>();
+ mVendorExt = ndk::SharedRefBase::make<TestHalAdapterVendorExtension>();
+ struct audio_config config = AUDIO_CONFIG_INITIALIZER;
+ ::aidl::android::hardware::audio::core::StreamDescriptor descriptor;
+ mStream = sp<StreamHalAidl>::make("test", false /*isInput*/, config, 0 /*nominalLatency*/,
+ StreamContextAidl(descriptor, false /*isAsynchronous*/),
+ mStreamCommon, mVendorExt);
+ }
+ void TearDown() override {
+ mStream.clear();
+ mVendorExt.reset();
+ mStreamCommon.reset();
+ }
+
+ protected:
+ std::shared_ptr<StreamCommonMock> mStreamCommon;
+ std::shared_ptr<TestHalAdapterVendorExtension> mVendorExt;
+ sp<StreamHalAidl> mStream;
+};
+
+TEST_F(StreamHalAidlVendorParametersTest, GetVendorParameter) {
+ EXPECT_EQ(0UL, mStreamCommon->getRetrievedParameterIds().size());
+ String8 values;
+ EXPECT_EQ(OK, mStream->getParameters(
+ String8(TestHalAdapterVendorExtension::kLegacyParameterKey.c_str()),
+ &values));
+ EXPECT_EQ(1UL, mStreamCommon->getRetrievedParameterIds().size());
+ if (mStreamCommon->getRetrievedParameterIds().size() >= 1) {
+ EXPECT_EQ(TestHalAdapterVendorExtension::kStreamVendorParameterId,
+ mStreamCommon->getRetrievedParameterIds()[0]);
+ }
+}
+
+TEST_F(StreamHalAidlVendorParametersTest, SetVendorParameter) {
+ EXPECT_EQ(0UL, mStreamCommon->getAsyncParameters().size());
+ EXPECT_EQ(0UL, mStreamCommon->getSyncParameters().size());
+ EXPECT_EQ(OK, mStream->setParameters(createParameterString(
+ TestHalAdapterVendorExtension::kLegacyParameterKey, 42)));
+ EXPECT_EQ(0UL, mStreamCommon->getAsyncParameters().size());
+ EXPECT_EQ(1UL, mStreamCommon->getSyncParameters().size());
+ EXPECT_EQ(OK, mStream->setParameters(createParameterString(
+ TestHalAdapterVendorExtension::kLegacyAsyncParameterKey, 43)));
+ EXPECT_EQ(1UL, mStreamCommon->getAsyncParameters().size());
+ EXPECT_EQ(1UL, mStreamCommon->getSyncParameters().size());
+ if (mStreamCommon->getSyncParameters().size() >= 1) {
+ EXPECT_EQ(TestHalAdapterVendorExtension::kStreamVendorParameterId,
+ mStreamCommon->getSyncParameters()[0].id);
+ int value{};
+ EXPECT_EQ(android::OK, parseVendorParameter(mStreamCommon->getSyncParameters()[0], &value));
+ EXPECT_EQ(42, value);
+ }
+ if (mStreamCommon->getAsyncParameters().size() >= 1) {
+ EXPECT_EQ(TestHalAdapterVendorExtension::kStreamVendorParameterId,
+ mStreamCommon->getAsyncParameters()[0].id);
+ int value{};
+ EXPECT_EQ(android::OK,
+ parseVendorParameter(mStreamCommon->getAsyncParameters()[0], &value));
+ EXPECT_EQ(43, value);
+ }
+}
+
+TEST_F(StreamHalAidlVendorParametersTest, SetInvalidVendorParameters) {
+ android::AudioParameter legacy;
+ legacy.addInt(android::String8(TestHalAdapterVendorExtension::kLegacyParameterKey.c_str()), 42);
+ legacy.addInt(android::String8(TestHalAdapterVendorExtension::kLegacyAsyncParameterKey.c_str()),
+ 43);
+ legacy.addInt(android::String8("random_name"), 44);
+ EXPECT_EQ(0UL, mStreamCommon->getAsyncParameters().size());
+ EXPECT_EQ(0UL, mStreamCommon->getSyncParameters().size());
+ // TestHalAdapterVendorExtension throws an error for unknown parameters.
+ EXPECT_EQ(android::BAD_VALUE, mStream->setParameters(legacy.toString()));
+ EXPECT_EQ(0UL, mStreamCommon->getAsyncParameters().size());
+ EXPECT_EQ(0UL, mStreamCommon->getSyncParameters().size());
+}
diff --git a/media/libaudiohal/tests/EffectProxy_test.cpp b/media/libaudiohal/tests/EffectProxy_test.cpp
index 92e3dce..8668e85 100644
--- a/media/libaudiohal/tests/EffectProxy_test.cpp
+++ b/media/libaudiohal/tests/EffectProxy_test.cpp
@@ -60,7 +60,7 @@
mFactory->queryEffects(std::nullopt, std::nullopt, std::nullopt, &mDescs);
for (const auto& desc : mDescs) {
if (desc.common.id.proxy.has_value()) {
- mProxyDescs.insert({desc.common.id, desc});
+ mProxyDescs[desc.common.id.proxy.value()].emplace_back(desc);
}
}
}
@@ -96,44 +96,24 @@
return common;
}
- static bool isFlagSet(const ::aidl::android::hardware::audio::effect::Descriptor& desc,
- Flags::HardwareAccelerator flag) {
- return desc.common.flags.hwAcceleratorMode == flag;
- }
-
enum TupleIndex { HANDLE, DESCRIPTOR };
using EffectProxyTuple = std::tuple<std::shared_ptr<EffectProxy>, std::vector<Descriptor>>;
std::map<AudioUuid, EffectProxyTuple> createAllProxies() {
std::map<AudioUuid, EffectProxyTuple> proxyMap;
for (const auto& itor : mProxyDescs) {
- const auto& uuid = itor.first.proxy.value();
+ const auto& uuid = itor.first;
if (proxyMap.end() == proxyMap.find(uuid)) {
std::get<TupleIndex::HANDLE>(proxyMap[uuid]) =
- ndk::SharedRefBase::make<EffectProxy>(itor.first, mFactory);
+ ndk::SharedRefBase::make<EffectProxy>(itor.first, itor.second, mFactory);
}
}
return proxyMap;
}
- bool addAllSubEffects(std::map<AudioUuid, EffectProxyTuple> proxyMap) {
- for (auto& itor : mProxyDescs) {
- const auto& uuid = itor.first.proxy.value();
- if (proxyMap.end() == proxyMap.find(uuid)) {
- return false;
- }
- auto& proxy = std::get<TupleIndex::HANDLE>(proxyMap[uuid]);
- if (!proxy->addSubEffect(itor.second).isOk()) {
- return false;
- }
- std::get<TupleIndex::DESCRIPTOR>(proxyMap[uuid]).emplace_back(itor.second);
- }
- return true;
- }
-
std::shared_ptr<IFactory> mFactory;
std::vector<Descriptor> mDescs;
- std::map<Descriptor::Identity, Descriptor> mProxyDescs;
+ std::map<const AudioUuid, std::vector<Descriptor>> mProxyDescs;
};
TEST_F(EffectProxyTest, createProxy) {
@@ -144,24 +124,20 @@
TEST_F(EffectProxyTest, addSubEffectsCreateAndDestroy) {
auto proxyMap = createAllProxies();
- ASSERT_TRUE(addAllSubEffects(proxyMap));
for (const auto& itor : proxyMap) {
auto& proxy = std::get<TupleIndex::HANDLE>(itor.second);
- EXPECT_TRUE(proxy->create().isOk());
EXPECT_TRUE(proxy->destroy().isOk());
}
}
TEST_F(EffectProxyTest, addSubEffectsCreateOpenCloseDestroy) {
auto proxyMap = createAllProxies();
- EXPECT_TRUE(addAllSubEffects(proxyMap));
Parameter::Common common = createParamCommon();
IEffect::OpenEffectReturn ret;
for (const auto& itor : proxyMap) {
auto& proxy = std::get<TupleIndex::HANDLE>(itor.second);
- EXPECT_TRUE(proxy->create().isOk());
EXPECT_TRUE(proxy->open(common, std::nullopt, &ret).isOk());
EXPECT_TRUE(proxy->close().isOk());
EXPECT_TRUE(proxy->destroy().isOk());
@@ -171,33 +147,23 @@
// Add sub-effects, set active sub-effect with different checkers
TEST_F(EffectProxyTest, setOffloadParam) {
auto proxyMap = createAllProxies();
- EXPECT_TRUE(addAllSubEffects(proxyMap));
// Any flag exist should be able to set successfully
- bool isNoneExist = false, isSimpleExist = false, isTunnelExist = false;
- for (const auto& itor : mProxyDescs) {
- isNoneExist = isNoneExist || isFlagSet(itor.second, Flags::HardwareAccelerator::NONE);
- isSimpleExist = isSimpleExist || isFlagSet(itor.second, Flags::HardwareAccelerator::SIMPLE);
- isTunnelExist = isTunnelExist || isFlagSet(itor.second, Flags::HardwareAccelerator::TUNNEL);
- }
-
Parameter::Common common = createParamCommon();
IEffect::OpenEffectReturn ret;
for (const auto& itor : proxyMap) {
auto& proxy = std::get<TupleIndex::HANDLE>(itor.second);
- EXPECT_TRUE(proxy->create().isOk());
EXPECT_TRUE(proxy->open(common, std::nullopt, &ret).isOk());
effect_offload_param_t offloadParam{false, 0};
- EXPECT_EQ(isNoneExist || isSimpleExist, proxy->setOffloadParam(&offloadParam).isOk());
+ EXPECT_TRUE(proxy->setOffloadParam(&offloadParam).isOk());
offloadParam.isOffload = true;
- EXPECT_EQ(isTunnelExist, proxy->setOffloadParam(&offloadParam).isOk());
+ EXPECT_TRUE(proxy->setOffloadParam(&offloadParam).isOk());
EXPECT_TRUE(proxy->close().isOk());
EXPECT_TRUE(proxy->destroy().isOk());
}
}
TEST_F(EffectProxyTest, destroyWithoutCreate) {
auto proxyMap = createAllProxies();
- ASSERT_TRUE(addAllSubEffects(proxyMap));
for (const auto& itor : proxyMap) {
auto& proxy = std::get<TupleIndex::HANDLE>(itor.second);
@@ -207,11 +173,9 @@
TEST_F(EffectProxyTest, closeWithoutOpen) {
auto proxyMap = createAllProxies();
- ASSERT_TRUE(addAllSubEffects(proxyMap));
for (const auto& itor : proxyMap) {
auto& proxy = std::get<TupleIndex::HANDLE>(itor.second);
- EXPECT_TRUE(proxy->create().isOk());
EXPECT_TRUE(proxy->close().isOk());
EXPECT_TRUE(proxy->destroy().isOk());
@@ -221,16 +185,6 @@
// Add sub-effects, set active sub-effect, create, open, and send command, expect success handling
TEST_F(EffectProxyTest, normalSequency) {
auto proxyMap = createAllProxies();
- ASSERT_TRUE(addAllSubEffects(proxyMap));
-
- bool isTunnelExist = [&]() {
- for (const auto& itor : mProxyDescs) {
- if (isFlagSet(itor.second, Flags::HardwareAccelerator::TUNNEL)) {
- return true;
- }
- }
- return false;
- }();
Parameter::Common common = createParamCommon();
IEffect::OpenEffectReturn ret;
@@ -242,14 +196,14 @@
Parameter expect;
auto& proxy = std::get<TupleIndex::HANDLE>(itor.second);
effect_offload_param_t offloadParam{true, 0};
- EXPECT_EQ(isTunnelExist, proxy->setOffloadParam(&offloadParam).isOk());
+ EXPECT_TRUE(proxy->setOffloadParam(&offloadParam).isOk());
- EXPECT_TRUE(proxy->create().isOk());
EXPECT_TRUE(proxy->open(common, std::nullopt, &ret).isOk());
EXPECT_TRUE(proxy->setParameter(param).isOk());
EXPECT_TRUE(proxy->getParameter(id, &expect).isOk());
- EXPECT_EQ(expect, param);
+ EXPECT_EQ(expect, param) << " EXPECTED: " << expect.toString()
+ << "\nACTUAL: " << param.toString();
EXPECT_TRUE(proxy->command(CommandId::START).isOk());
EXPECT_TRUE(proxy->getState(&state).isOk());
@@ -267,14 +221,6 @@
// setParameter, change active sub-effect, verify with getParameter
TEST_F(EffectProxyTest, changeActiveSubAndVerifyParameter) {
auto proxyMap = createAllProxies();
- EXPECT_TRUE(addAllSubEffects(proxyMap));
-
- bool isNoneExist = false, isSimpleExist = false, isTunnelExist = false;
- for (const auto& itor : mProxyDescs) {
- isNoneExist = isNoneExist || isFlagSet(itor.second, Flags::HardwareAccelerator::NONE);
- isSimpleExist = isSimpleExist || isFlagSet(itor.second, Flags::HardwareAccelerator::SIMPLE);
- isTunnelExist = isTunnelExist || isFlagSet(itor.second, Flags::HardwareAccelerator::TUNNEL);
- }
Parameter::Common common = createParamCommon();
IEffect::OpenEffectReturn ret;
@@ -284,19 +230,18 @@
for (const auto& itor : proxyMap) {
Parameter expect;
auto& proxy = std::get<TupleIndex::HANDLE>(itor.second);
- EXPECT_TRUE(proxy->create().isOk());
EXPECT_TRUE(proxy->open(common, std::nullopt, &ret).isOk());
EXPECT_TRUE(proxy->setParameter(param).isOk());
EXPECT_TRUE(proxy->getParameter(id, &expect).isOk());
EXPECT_EQ(expect, param);
effect_offload_param_t offloadParam{false, 0};
- EXPECT_EQ(isNoneExist || isSimpleExist, proxy->setOffloadParam(&offloadParam).isOk());
+ EXPECT_TRUE(proxy->setOffloadParam(&offloadParam).isOk());
EXPECT_TRUE(proxy->getParameter(id, &expect).isOk());
EXPECT_EQ(expect, param);
offloadParam.isOffload = true;
- EXPECT_EQ(isTunnelExist, proxy->setOffloadParam(&offloadParam).isOk());
+ EXPECT_TRUE(proxy->setOffloadParam(&offloadParam).isOk());
EXPECT_TRUE(proxy->getParameter(id, &expect).isOk());
EXPECT_EQ(expect, param);
@@ -308,14 +253,6 @@
// send command, change active sub-effect, then verify the state with getState
TEST_F(EffectProxyTest, changeActiveSubAndVerifyState) {
auto proxyMap = createAllProxies();
- ASSERT_TRUE(addAllSubEffects(proxyMap));
-
- bool isNoneExist = false, isSimpleExist = false, isTunnelExist = false;
- for (const auto& itor : mProxyDescs) {
- isNoneExist = isNoneExist || isFlagSet(itor.second, Flags::HardwareAccelerator::NONE);
- isSimpleExist = isSimpleExist || isFlagSet(itor.second, Flags::HardwareAccelerator::SIMPLE);
- isTunnelExist = isTunnelExist || isFlagSet(itor.second, Flags::HardwareAccelerator::TUNNEL);
- }
Parameter::Common common = createParamCommon();
IEffect::OpenEffectReturn ret;
@@ -323,7 +260,6 @@
for (const auto& itor : proxyMap) {
Parameter expect;
auto& proxy = std::get<TupleIndex::HANDLE>(itor.second);
- EXPECT_TRUE(proxy->create().isOk());
EXPECT_TRUE(proxy->getState(&state).isOk());
EXPECT_EQ(State::INIT, state);
EXPECT_TRUE(proxy->open(common, std::nullopt, &ret).isOk());
@@ -334,12 +270,12 @@
EXPECT_EQ(State::PROCESSING, state);
effect_offload_param_t offloadParam{false, 0};
- EXPECT_EQ(isNoneExist || isSimpleExist, proxy->setOffloadParam(&offloadParam).isOk());
+ EXPECT_TRUE(proxy->setOffloadParam(&offloadParam).isOk());
EXPECT_TRUE(proxy->getState(&state).isOk());
EXPECT_EQ(State::PROCESSING, state);
offloadParam.isOffload = true;
- EXPECT_EQ(isTunnelExist, proxy->setOffloadParam(&offloadParam).isOk());
+ EXPECT_TRUE(proxy->setOffloadParam(&offloadParam).isOk());
EXPECT_TRUE(proxy->getState(&state).isOk());
EXPECT_EQ(State::PROCESSING, state);
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Process.cpp b/media/libeffects/lvm/lib/Bundle/src/LVM_Process.cpp
index 4eea04f..bfc5059 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Process.cpp
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Process.cpp
@@ -166,9 +166,9 @@
* Bypass mode or everything off, so copy the input to the output
*/
if (pToProcess != pProcessed) {
- Copy_Float(pToProcess, /* Source */
- pProcessed, /* Destination */
- (LVM_INT16)(NrChannels * NrFrames)); /* Copy all samples */
+ Copy_Float(pToProcess, /* Source */
+ pProcessed, /* Destination */
+ SampleCount); /* Copy all samples */
}
/*
diff --git a/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp b/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp
index d026e2b..0db7a73 100644
--- a/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp
+++ b/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp
@@ -15,9 +15,11 @@
*/
#include <cstddef>
+#include <cstdio>
#define LOG_TAG "BundleContext"
#include <android-base/logging.h>
+#include <audio_utils/power.h>
#include <Utils.h>
#include "BundleContext.h"
@@ -34,7 +36,7 @@
std::lock_guard lg(mMutex);
// init with pre-defined preset NORMAL
for (std::size_t i = 0; i < lvm::MAX_NUM_BANDS; i++) {
- mBandGaindB[i] = lvm::kSoftPresets[0 /* normal */][i];
+ mBandGainMdB[i] = lvm::kSoftPresets[0 /* normal */][i] * 100;
}
// allocate lvm instance
@@ -212,7 +214,7 @@
if (eqEnabled) {
for (int i = 0; i < lvm::MAX_NUM_BANDS; i++) {
- float bandFactor = mBandGaindB[i] / 15.0;
+ float bandFactor = mBandGainMdB[i] / 1500.0;
float bandCoefficient = lvm::kBandEnergyCoefficient[i];
float bandEnergy = bandFactor * bandCoefficient * bandCoefficient;
if (bandEnergy > 0) energyContribution += bandEnergy;
@@ -221,8 +223,8 @@
// cross EQ coefficients
float bandFactorSum = 0;
for (int i = 0; i < lvm::MAX_NUM_BANDS - 1; i++) {
- float bandFactor1 = mBandGaindB[i] / 15.0;
- float bandFactor2 = mBandGaindB[i + 1] / 15.0;
+ float bandFactor1 = mBandGainMdB[i] / 1500.0;
+ float bandFactor2 = mBandGainMdB[i + 1] / 1500.0;
if (bandFactor1 > 0 && bandFactor2 > 0) {
float crossEnergy =
@@ -244,7 +246,7 @@
if (eqEnabled) {
for (int i = 0; i < lvm::MAX_NUM_BANDS; i++) {
- float bandFactor = mBandGaindB[i] / 15.0;
+ float bandFactor = mBandGainMdB[i] / 1500.0;
float bandCrossCoefficient = lvm::kBassBoostEnergyCrossCoefficient[i];
float bandEnergy = boostFactor * bandFactor * bandCrossCoefficient;
if (bandEnergy > 0) energyBassBoost += bandEnergy;
@@ -397,15 +399,10 @@
return db_fix;
}
-// TODO: replace with more generic approach, like: audio_utils_power_from_amplitude
-int16_t BundleContext::VolToDb(uint32_t vol) const {
- int16_t dB;
-
- dB = LVC_ToDB_s32Tos16(vol << 7);
- dB = (dB + 8) >> 4;
- dB = (dB < -96) ? -96 : dB;
-
- return dB;
+/* static */
+float BundleContext::VolToDb(float vol) {
+ float dB = audio_utils_power_from_amplitude(vol);
+ return std::max(dB, -96.f);
}
RetCode BundleContext::setVolumeStereo(const Parameter::VolumeStereo& volume) {
@@ -413,11 +410,12 @@
LVM_ReturnStatus_en status = LVM_SUCCESS;
// Convert volume to dB
- int leftdB = VolToDb(volume.left);
- int rightdB = VolToDb(volume.right);
- int maxdB = std::max(leftdB, rightdB);
- int pandB = rightdB - leftdB;
- setVolumeLevel(maxdB * 100);
+ float leftdB = VolToDb(volume.left);
+ float rightdB = VolToDb(volume.right);
+
+ float maxdB = std::max(leftdB, rightdB);
+ float pandB = rightdB - leftdB;
+ setVolumeLevel(maxdB);
LOG(DEBUG) << __func__ << " pandB: " << pandB << " maxdB " << maxdB;
{
@@ -441,8 +439,8 @@
std::vector<Equalizer::BandLevel> bandLevels;
bandLevels.reserve(lvm::MAX_NUM_BANDS);
for (std::size_t i = 0; i < lvm::MAX_NUM_BANDS; i++) {
- bandLevels.emplace_back(
- Equalizer::BandLevel{static_cast<int32_t>(i), lvm::kSoftPresets[presetIdx][i]});
+ bandLevels.emplace_back(Equalizer::BandLevel{static_cast<int32_t>(i),
+ lvm::kSoftPresets[presetIdx][i] * 100});
}
RetCode ret = updateControlParameter(bandLevels);
@@ -472,7 +470,8 @@
std::vector<Equalizer::BandLevel> bandLevels;
bandLevels.reserve(lvm::MAX_NUM_BANDS);
for (std::size_t i = 0; i < lvm::MAX_NUM_BANDS; i++) {
- bandLevels.emplace_back(Equalizer::BandLevel{static_cast<int32_t>(i), mBandGaindB[i]});
+ bandLevels.emplace_back(
+ Equalizer::BandLevel{static_cast<int32_t>(i), mBandGainMdB[i]});
}
return bandLevels;
}
@@ -506,7 +505,7 @@
RETURN_VALUE_IF(!isBandLevelIndexInRange(bandLevels), RetCode::ERROR_ILLEGAL_PARAMETER,
"indexOutOfRange");
- std::array<int, lvm::MAX_NUM_BANDS> tempLevel;
+ std::array<int, lvm::MAX_NUM_BANDS> tempLevel(mBandGainMdB);
for (const auto& it : bandLevels) {
tempLevel[it.index] = it.levelMb;
}
@@ -520,14 +519,16 @@
for (std::size_t i = 0; i < lvm::MAX_NUM_BANDS; i++) {
params.pEQNB_BandDefinition[i].Frequency = lvm::kPresetsFrequencies[i];
params.pEQNB_BandDefinition[i].QFactor = lvm::kPresetsQFactors[i];
- params.pEQNB_BandDefinition[i].Gain = tempLevel[i];
+ params.pEQNB_BandDefinition[i].Gain =
+ tempLevel[i] > 0 ? (tempLevel[i] + 50) / 100 : (tempLevel[i] - 50) / 100;
}
RETURN_VALUE_IF(LVM_SUCCESS != LVM_SetControlParameters(mInstance, ¶ms),
RetCode::ERROR_EFFECT_LIB_ERROR, " setControlParamFailed");
}
- mBandGaindB = tempLevel;
- LOG(INFO) << __func__ << " update bandGain to " << ::android::internal::ToString(mBandGaindB);
+ mBandGainMdB = tempLevel;
+ LOG(DEBUG) << __func__ << " update bandGain to " << ::android::internal::ToString(mBandGainMdB)
+ << "mdB";
return RetCode::SUCCESS;
}
@@ -551,18 +552,18 @@
return limitLevel();
}
-RetCode BundleContext::setVolumeLevel(int level) {
+RetCode BundleContext::setVolumeLevel(float level) {
if (mMuteEnabled) {
- mLevelSaved = level / 100;
+ mLevelSaved = level;
} else {
- mVolume = level / 100;
+ mVolume = level;
}
LOG(INFO) << __func__ << " success with level " << level;
return limitLevel();
}
-int BundleContext::getVolumeLevel() const {
- return (mMuteEnabled ? mLevelSaved * 100 : mVolume * 100);
+float BundleContext::getVolumeLevel() const {
+ return (mMuteEnabled ? mLevelSaved : mVolume);
}
RetCode BundleContext::setVolumeMute(bool mute) {
diff --git a/media/libeffects/lvm/wrapper/Aidl/BundleContext.h b/media/libeffects/lvm/wrapper/Aidl/BundleContext.h
index 47d5e5a..62bb6e4 100644
--- a/media/libeffects/lvm/wrapper/Aidl/BundleContext.h
+++ b/media/libeffects/lvm/wrapper/Aidl/BundleContext.h
@@ -80,8 +80,8 @@
RetCode setBassBoostStrength(int strength);
int getBassBoostStrength() const { return mBassStrengthSaved; }
- RetCode setVolumeLevel(int level);
- int getVolumeLevel() const;
+ RetCode setVolumeLevel(float level);
+ float getVolumeLevel() const;
RetCode setVolumeMute(bool mute);
int getVolumeMute() const { return mMuteEnabled; }
@@ -135,20 +135,20 @@
int mBassStrengthSaved = 0;
// Equalizer
int mCurPresetIdx = lvm::PRESET_CUSTOM; /* Current preset being used */
- std::array<int, lvm::MAX_NUM_BANDS> mBandGaindB;
+ std::array<int, lvm::MAX_NUM_BANDS> mBandGainMdB; /* band gain in millibels */
// Virtualizer
int mVirtStrengthSaved = 0; /* Conversion between Get/Set */
bool mVirtualizerTempDisabled = false;
::aidl::android::media::audio::common::AudioDeviceDescription mForceDevice;
// Volume
- int mLevelSaved = 0; /* for when mute is set, level must be saved */
- int mVolume = 0;
+ float mLevelSaved = 0; /* for when mute is set, level must be saved */
+ float mVolume = 0;
bool mMuteEnabled = false; /* Must store as mute = -96dB level */
void initControlParameter(LVM_ControlParams_t& params) const;
void initHeadroomParameter(LVM_HeadroomParams_t& params) const;
RetCode limitLevel();
- int16_t VolToDb(uint32_t vol) const;
+ static float VolToDb(float vol);
LVM_INT16 LVC_ToDB_s32Tos16(LVM_INT32 Lin_fix) const;
RetCode updateControlParameter(const std::vector<Equalizer::BandLevel>& bandLevels);
bool isBandLevelIndexInRange(const std::vector<Equalizer::BandLevel>& bandLevels) const;
diff --git a/media/libeffects/lvm/wrapper/Aidl/BundleTypes.h b/media/libeffects/lvm/wrapper/Aidl/BundleTypes.h
index 3bc889c..143329d 100644
--- a/media/libeffects/lvm/wrapper/Aidl/BundleTypes.h
+++ b/media/libeffects/lvm/wrapper/Aidl/BundleTypes.h
@@ -73,9 +73,9 @@
MAKE_RANGE(Equalizer, preset, 0, MAX_NUM_PRESETS - 1),
MAKE_RANGE(Equalizer, bandLevels,
std::vector<Equalizer::BandLevel>{
- Equalizer::BandLevel({.index = 0, .levelMb = -15})},
+ Equalizer::BandLevel({.index = 0, .levelMb = -1500})},
std::vector<Equalizer::BandLevel>{
- Equalizer::BandLevel({.index = MAX_NUM_BANDS - 1, .levelMb = 15})}),
+ Equalizer::BandLevel({.index = MAX_NUM_BANDS - 1, .levelMb = 1500})}),
/* capability definition */
MAKE_RANGE(Equalizer, bandFrequencies, kEqBandFrequency, kEqBandFrequency),
MAKE_RANGE(Equalizer, presets, kEqPresets, kEqPresets),
diff --git a/media/libeffects/lvm/wrapper/Aidl/EffectBundleAidl.cpp b/media/libeffects/lvm/wrapper/Aidl/EffectBundleAidl.cpp
index cd9fb60..eb7ab1a 100644
--- a/media/libeffects/lvm/wrapper/Aidl/EffectBundleAidl.cpp
+++ b/media/libeffects/lvm/wrapper/Aidl/EffectBundleAidl.cpp
@@ -355,7 +355,7 @@
auto tag = id.get<Volume::Id::commonTag>();
switch (tag) {
case Volume::levelDb: {
- volParam.set<Volume::levelDb>(mContext->getVolumeLevel());
+ volParam.set<Volume::levelDb>(static_cast<int>(mContext->getVolumeLevel()));
break;
}
case Volume::mute: {
@@ -384,6 +384,7 @@
if (id.getTag() == Virtualizer::Id::speakerAnglesPayload) {
auto angles = mContext->getSpeakerAngles(id.get<Virtualizer::Id::speakerAnglesPayload>());
+ RETURN_IF(angles.size() == 0, EX_ILLEGAL_ARGUMENT, "getSpeakerAnglesFailed");
Virtualizer param = Virtualizer::make<Virtualizer::speakerAngles>(angles);
specific->set<Parameter::Specific::virtualizer>(param);
return ndk::ScopedAStatus::ok();
diff --git a/media/libmediahelper/AudioParameter.cpp b/media/libmediahelper/AudioParameter.cpp
index a61a1bc..3832e90 100644
--- a/media/libmediahelper/AudioParameter.cpp
+++ b/media/libmediahelper/AudioParameter.cpp
@@ -33,6 +33,7 @@
const char * const AudioParameter::keyFrameCount = AUDIO_PARAMETER_STREAM_FRAME_COUNT;
const char * const AudioParameter::keyInputSource = AUDIO_PARAMETER_STREAM_INPUT_SOURCE;
const char * const AudioParameter::keyScreenState = AUDIO_PARAMETER_KEY_SCREEN_STATE;
+const char * const AudioParameter::keyScreenRotation = AUDIO_PARAMETER_KEY_ROTATION;
const char * const AudioParameter::keyClosing = AUDIO_PARAMETER_KEY_CLOSING;
const char * const AudioParameter::keyExiting = AUDIO_PARAMETER_KEY_EXITING;
const char * const AudioParameter::keyBtSco = AUDIO_PARAMETER_KEY_BT_SCO;
diff --git a/media/libmediahelper/include/media/AudioParameter.h b/media/libmediahelper/include/media/AudioParameter.h
index 70f8af3..3eee854 100644
--- a/media/libmediahelper/include/media/AudioParameter.h
+++ b/media/libmediahelper/include/media/AudioParameter.h
@@ -41,6 +41,7 @@
// keyInputSource: to change audio input source, value is an int in audio_source_t
// (defined in media/mediarecorder.h)
// keyScreenState: either "on" or "off"
+ // keyScreenRotation: one of: 0, 90, 180, 270
static const char * const keyRouting;
static const char * const keySamplingRate;
static const char * const keyFormat;
@@ -48,9 +49,9 @@
static const char * const keyFrameCount;
static const char * const keyInputSource;
static const char * const keyScreenState;
+ static const char * const keyScreenRotation;
- // TODO(b/73175392) consider improvement to AIDL StreamOut interface.
- // keyClosing: "true" when AudioOutputDescriptor is closing. Used by A2DP HAL.
+ // keyClosing: "true" on AudioFlinger Thread preExit. Used by A2DP HAL.
// keyExiting: "1" on AudioFlinger Thread preExit. Used by remote_submix and A2DP HAL.
static const char * const keyClosing;
static const char * const keyExiting;
diff --git a/media/libstagefright/RemoteMediaExtractor.cpp b/media/libstagefright/RemoteMediaExtractor.cpp
index baa2ca1..574fc1a 100644
--- a/media/libstagefright/RemoteMediaExtractor.cpp
+++ b/media/libstagefright/RemoteMediaExtractor.cpp
@@ -16,9 +16,16 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "RemoteMediaExtractor"
+
+#include <list>
+#include <pthread.h>
+#include <condition_variable>
+#include <mutex>
+
#include <utils/Log.h>
#include <binder/IPCThreadState.h>
+#include <cutils/properties.h>
#include <media/stagefright/InterfaceUtils.h>
#include <media/MediaMetricsItem.h>
#include <media/stagefright/MediaSource.h>
@@ -90,10 +97,65 @@
}
}
+static pthread_t myThread;
+static std::list<sp<DataSource>> pending;
+static std::mutex pending_mutex;
+static std::condition_variable pending_added;
+
+static void* closing_thread_func(void *arg) {
+ while (true) {
+ sp<DataSource> ds = nullptr;
+ std::unique_lock _lk(pending_mutex);
+ pending_added.wait(_lk, []{return !pending.empty();});
+ ALOGV("worker thread wake up with %zu entries", pending.size());
+ if (!pending.empty()) {
+ ds = pending.front();
+ (void) pending.pop_front();
+ }
+ _lk.unlock(); // unique_lock is not scoped
+ if (ds != nullptr) {
+ ds->close();
+ }
+ }
+
+ ALOGE("[unexpected] worker thread quit");
+ return arg;
+}
+
+// this can be '&ds' as long as the pending.push_back() bumps the
+// reference counts to ensure the object lives long enough
+static void start_close_thread(sp<DataSource> &ds) {
+
+ // make sure we have our (single) worker thread
+ static std::once_flag sCheckOnce;
+ std::call_once(sCheckOnce, [&](){
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+ pthread_create(&myThread, &attr, closing_thread_func, nullptr);
+ pthread_attr_destroy(&attr);
+ });
+
+ {
+ std::lock_guard _lm(pending_mutex); // scoped, no explicit unlock
+ pending.push_back(ds);
+ }
+ pending_added.notify_one(); // get the worker thread going
+}
+
RemoteMediaExtractor::~RemoteMediaExtractor() {
delete mExtractor;
- mSource->close();
- mSource.clear();
+ // TODO(287851984) hook for changing behavior this dynamically, drop after testing
+ int8_t new_scheme = property_get_bool("debug.mediaextractor.delayedclose", 1);
+ if (new_scheme != 0) {
+ ALOGV("deferred close()");
+ start_close_thread(mSource);
+ mSource.clear();
+ } else {
+ ALOGV("immediate close()");
+ mSource->close();
+ mSource.clear();
+ }
mExtractorPlugin = nullptr;
// log the current record, provided it has some information worth recording
if (MEDIA_LOG) {
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 325adfa..02531bd 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -731,24 +731,24 @@
}
}
-status_t AudioFlinger::addEffectToHal(audio_port_handle_t deviceId,
- audio_module_handle_t hwModuleId, const sp<EffectHalInterface>& effect) {
+status_t AudioFlinger::addEffectToHal(
+ const struct audio_port_config *device, const sp<EffectHalInterface>& effect) {
AutoMutex lock(mHardwareLock);
- AudioHwDevice *audioHwDevice = mAudioHwDevs.valueFor(hwModuleId);
+ AudioHwDevice *audioHwDevice = mAudioHwDevs.valueFor(device->ext.device.hw_module);
if (audioHwDevice == nullptr) {
return NO_INIT;
}
- return audioHwDevice->hwDevice()->addDeviceEffect(deviceId, effect);
+ return audioHwDevice->hwDevice()->addDeviceEffect(device, effect);
}
-status_t AudioFlinger::removeEffectFromHal(audio_port_handle_t deviceId,
- audio_module_handle_t hwModuleId, const sp<EffectHalInterface>& effect) {
+status_t AudioFlinger::removeEffectFromHal(
+ const struct audio_port_config *device, const sp<EffectHalInterface>& effect) {
AutoMutex lock(mHardwareLock);
- AudioHwDevice *audioHwDevice = mAudioHwDevs.valueFor(hwModuleId);
+ AudioHwDevice *audioHwDevice = mAudioHwDevs.valueFor(device->ext.device.hw_module);
if (audioHwDevice == nullptr) {
return NO_INIT;
}
- return audioHwDevice->hwDevice()->removeDeviceEffect(deviceId, effect);
+ return audioHwDevice->hwDevice()->removeDeviceEffect(device, effect);
}
static const char * const audio_interfaces[] = {
@@ -4000,7 +4000,7 @@
patchTrack->setPeerProxy(patchRecord, true /* holdReference */);
patchRecord->setPeerProxy(patchTrack, false /* holdReference */);
}
- track->setTeePatchesToUpdate(std::move(teePatches));
+ track->setTeePatchesToUpdate_l(std::move(teePatches));
}
sp<AudioFlinger::SyncEvent> AudioFlinger::createSyncEvent(AudioSystem::sync_event_t type,
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 10bfdb9..c3ca1b0 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -344,10 +344,10 @@
const sp<os::ExternalVibration>& externalVibration);
static void onExternalVibrationStop(const sp<os::ExternalVibration>& externalVibration);
- status_t addEffectToHal(audio_port_handle_t deviceId,
- audio_module_handle_t hwModuleId, const sp<EffectHalInterface>& effect);
- status_t removeEffectFromHal(audio_port_handle_t deviceId,
- audio_module_handle_t hwModuleId, const sp<EffectHalInterface>& effect);
+ status_t addEffectToHal(
+ const struct audio_port_config *device, const sp<EffectHalInterface>& effect);
+ status_t removeEffectFromHal(
+ const struct audio_port_config *device, const sp<EffectHalInterface>& effect);
void updateDownStreamPatches_l(const struct audio_patch *patch,
const std::set<audio_io_handle_t>& streams);
diff --git a/services/audioflinger/DeviceEffectManager.h b/services/audioflinger/DeviceEffectManager.h
index 395781d..b87f830 100644
--- a/services/audioflinger/DeviceEffectManager.h
+++ b/services/audioflinger/DeviceEffectManager.h
@@ -44,13 +44,13 @@
status_t createEffectHal(const effect_uuid_t *pEffectUuid,
int32_t sessionId, int32_t deviceId,
sp<EffectHalInterface> *effect);
- status_t addEffectToHal(audio_port_handle_t deviceId, audio_module_handle_t hwModuleId,
+ status_t addEffectToHal(const struct audio_port_config *device,
const sp<EffectHalInterface>& effect) {
- return mAudioFlinger.addEffectToHal(deviceId, hwModuleId, effect);
+ return mAudioFlinger.addEffectToHal(device, effect);
};
- status_t removeEffectFromHal(audio_port_handle_t deviceId, audio_module_handle_t hwModuleId,
+ status_t removeEffectFromHal(const struct audio_port_config *device,
const sp<EffectHalInterface>& effect) {
- return mAudioFlinger.removeEffectFromHal(deviceId, hwModuleId, effect);
+ return mAudioFlinger.removeEffectFromHal(device, effect);
};
AudioFlinger& audioFlinger() const { return mAudioFlinger; }
@@ -132,13 +132,13 @@
int newEffectId() { return mManager.audioFlinger().nextUniqueId(AUDIO_UNIQUE_ID_USE_EFFECT); }
- status_t addEffectToHal(audio_port_handle_t deviceId,
- audio_module_handle_t hwModuleId, const sp<EffectHalInterface>& effect) {
- return mManager.addEffectToHal(deviceId, hwModuleId, effect);
+ status_t addEffectToHal(const struct audio_port_config *device,
+ const sp<EffectHalInterface>& effect) {
+ return mManager.addEffectToHal(device, effect);
}
- status_t removeEffectFromHal(audio_port_handle_t deviceId,
- audio_module_handle_t hwModuleId, const sp<EffectHalInterface>& effect) {
- return mManager.removeEffectFromHal(deviceId, hwModuleId, effect);
+ status_t removeEffectFromHal(const struct audio_port_config *device,
+ const sp<EffectHalInterface>& effect) {
+ return mManager.removeEffectFromHal(device, effect);
}
private:
DeviceEffectManager& mManager;
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index 77aa804..7c7548a 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -3486,8 +3486,7 @@
if (mHalEffect == nullptr) {
return NO_INIT;
}
- return mManagerCallback->addEffectToHal(
- mDevicePort.id, mDevicePort.ext.device.hw_module, effect);
+ return mManagerCallback->addEffectToHal(&mDevicePort, effect);
}
status_t AudioFlinger::DeviceEffectProxy::removeEffectFromHal(
@@ -3495,8 +3494,7 @@
if (mHalEffect == nullptr) {
return NO_INIT;
}
- return mManagerCallback->removeEffectFromHal(
- mDevicePort.id, mDevicePort.ext.device.hw_module, effect);
+ return mManagerCallback->removeEffectFromHal(&mDevicePort, effect);
}
bool AudioFlinger::DeviceEffectProxy::isOutput() const {
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index 0e1a3c9..d485ccc 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -187,8 +187,8 @@
sp<os::ExternalVibration> getExternalVibration() const { return mExternalVibration; }
// This function should be called with holding thread lock.
- void updateTeePatches();
- void setTeePatchesToUpdate(TeePatches teePatchesToUpdate);
+ void updateTeePatches_l();
+ void setTeePatchesToUpdate_l(TeePatches teePatchesToUpdate);
void tallyUnderrunFrames(size_t frames) override {
if (isOut()) { // we expect this from output tracks only
@@ -335,8 +335,9 @@
private:
void interceptBuffer(const AudioBufferProvider::Buffer& buffer);
+ // Must hold thread lock to access tee patches
template <class F>
- void forEachTeePatchTrack(F f) {
+ void forEachTeePatchTrack_l(F f) {
for (auto& tp : mTeePatches) { f(tp.patchTrack); }
};
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 700bdd2..d86042f 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -4100,7 +4100,7 @@
setHalLatencyMode_l();
for (const auto &track : mActiveTracks ) {
- track->updateTeePatches();
+ track->updateTeePatches_l();
}
// signal actual start of output stream when the render position reported by the kernel
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 7d2c4db..7f99599 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -779,12 +779,12 @@
Mutex::Autolock _l(thread->mLock);
PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
wasActive = playbackThread->destroyTrack_l(this);
+ forEachTeePatchTrack_l([](const auto& patchTrack) { patchTrack->destroy(); });
}
if (isExternalTrack() && !wasActive) {
AudioSystem::releaseOutput(mPortId);
}
}
- forEachTeePatchTrack([](auto patchTrack) { patchTrack->destroy(); });
}
void AudioFlinger::PlaybackThread::Track::appendDumpHeader(String8& result)
@@ -1157,12 +1157,13 @@
buffer.mFrameCount = 1;
(void) mAudioTrackServerProxy->obtainBuffer(&buffer, true /*ackFlush*/);
}
+ if (status == NO_ERROR) {
+ forEachTeePatchTrack_l([](const auto& patchTrack) { patchTrack->start(); });
+ }
} else {
status = BAD_VALUE;
}
if (status == NO_ERROR) {
- forEachTeePatchTrack([](auto patchTrack) { patchTrack->start(); });
-
// send format to AudioManager for playback activity monitoring
sp<IAudioManager> audioManager = thread->mAudioFlinger->getOrCreateAudioManager();
if (audioManager && mPortId != AUDIO_PORT_HANDLE_NONE) {
@@ -1212,8 +1213,8 @@
ALOGV("%s(%d): not stopping/stopped => stopping/stopped on thread %d",
__func__, mId, (int)mThreadIoHandle);
}
+ forEachTeePatchTrack_l([](const auto& patchTrack) { patchTrack->stop(); });
}
- forEachTeePatchTrack([](auto patchTrack) { patchTrack->stop(); });
}
void AudioFlinger::PlaybackThread::Track::pause()
@@ -1248,9 +1249,9 @@
default:
break;
}
+ // Pausing the TeePatch to avoid a glitch on underrun, at the cost of buffered audio loss.
+ forEachTeePatchTrack_l([](const auto& patchTrack) { patchTrack->pause(); });
}
- // Pausing the TeePatch to avoid a glitch on underrun, at the cost of buffered audio loss.
- forEachTeePatchTrack([](auto patchTrack) { patchTrack->pause(); });
}
void AudioFlinger::PlaybackThread::Track::flush()
@@ -1311,9 +1312,10 @@
// before mixer thread can run. This is important when offloading
// because the hardware buffer could hold a large amount of audio
playbackThread->broadcast_l();
+ // Flush the Tee to avoid on resume playing old data and glitching on the transition to
+ // new data
+ forEachTeePatchTrack_l([](const auto& patchTrack) { patchTrack->flush(); });
}
- // Flush the Tee to avoid on resume playing old data and glitching on the transition to new data
- forEachTeePatchTrack([](auto patchTrack) { patchTrack->flush(); });
}
// must be called with thread lock held
@@ -1491,19 +1493,19 @@
*backInserter++ = metadata;
}
-void AudioFlinger::PlaybackThread::Track::updateTeePatches() {
+void AudioFlinger::PlaybackThread::Track::updateTeePatches_l() {
if (mTeePatchesToUpdate.has_value()) {
- forEachTeePatchTrack([](auto patchTrack) { patchTrack->destroy(); });
+ forEachTeePatchTrack_l([](const auto& patchTrack) { patchTrack->destroy(); });
mTeePatches = mTeePatchesToUpdate.value();
if (mState == TrackBase::ACTIVE || mState == TrackBase::RESUMING ||
mState == TrackBase::STOPPING_1) {
- forEachTeePatchTrack([](auto patchTrack) { patchTrack->start(); });
+ forEachTeePatchTrack_l([](const auto& patchTrack) { patchTrack->start(); });
}
mTeePatchesToUpdate.reset();
}
}
-void AudioFlinger::PlaybackThread::Track::setTeePatchesToUpdate(TeePatches teePatchesToUpdate) {
+void AudioFlinger::PlaybackThread::Track::setTeePatchesToUpdate_l(TeePatches teePatchesToUpdate) {
ALOGW_IF(mTeePatchesToUpdate.has_value(),
"%s, existing tee patches to update will be ignored", __func__);
mTeePatchesToUpdate = std::move(teePatchesToUpdate);
diff --git a/services/audiopolicy/common/managerdefinitions/Android.bp b/services/audiopolicy/common/managerdefinitions/Android.bp
index 1d570b7..8b76842 100644
--- a/services/audiopolicy/common/managerdefinitions/Android.bp
+++ b/services/audiopolicy/common/managerdefinitions/Android.bp
@@ -7,9 +7,13 @@
default_applicable_licenses: ["frameworks_av_license"],
}
-cc_library_static {
+cc_library {
name: "libaudiopolicycomponents",
+ defaults: [
+ "latest_android_media_audio_common_types_cpp_shared",
+ ],
+
srcs: [
"src/AudioCollections.cpp",
"src/AudioInputDescriptor.cpp",
@@ -31,7 +35,11 @@
"src/TypeConverter.cpp",
],
shared_libs: [
+ "audioclient-types-aidl-cpp",
+ "audiopolicy-types-aidl-cpp",
+ "libaudioclient_aidl_conversion",
"libaudiofoundation",
+ "libaudiopolicy",
"libbase",
"libcutils",
"libhidlbase",
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
index 876911d..febccac 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
@@ -424,6 +424,15 @@
bool supportsAllDevices(const DeviceVector &devices) const;
/**
+ * @brief supportsAtLeastOne checks if any device in devices is currently supported
+ * @param devices to be checked against
+ * @return true if the device is weakly supported by type (e.g. for non bus / rsubmix devices),
+ * true if the device is supported (both type and address) for bus / remote submix
+ * false otherwise
+ */
+ bool supportsAtLeastOne(const DeviceVector &devices) const;
+
+ /**
* @brief supportsDevicesForPlayback
* @param devices to be checked against
* @return true if the devices is a supported combo for playback
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h
index 32c78a1..1f6002f 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h
@@ -23,6 +23,7 @@
#include <DeviceDescriptor.h>
#include <HwModule.h>
+#include <android/media/AudioPolicyConfig.h>
#include <error/Result.h>
#include <utils/StrongPointer.h>
#include <utils/RefBase.h>
@@ -42,6 +43,8 @@
// Surround formats, with an optional list of subformats that are equivalent from users' POV.
using SurroundFormats = std::unordered_map<audio_format_t, std::unordered_set<audio_format_t>>;
+ // The source used to indicate the configuration from the AIDL HAL.
+ static const constexpr char* const kAidlConfigSource = "AIDL HAL";
// The source used to indicate the default fallback configuration.
static const constexpr char* const kDefaultConfigSource = "AudioPolicyConfig::setDefault";
// The suffix of the "engine default" implementation shared library name.
@@ -49,6 +52,9 @@
// Creates the default (fallback) configuration.
static sp<const AudioPolicyConfig> createDefault();
+ // Attempts to load the configuration from the AIDL config falls back to default on failure.
+ static sp<const AudioPolicyConfig> loadFromApmAidlConfigWithFallback(
+ const media::AudioPolicyConfig& aidl);
// Attempts to load the configuration from the XML file, falls back to default on failure.
// If the XML file path is not provided, uses `audio_get_audio_policy_config_file` function.
static sp<const AudioPolicyConfig> loadFromApmXmlConfigWithFallback(
@@ -140,6 +146,7 @@
AudioPolicyConfig() = default;
void augmentData();
+ status_t loadFromAidl(const media::AudioPolicyConfig& aidl);
status_t loadFromXml(const std::string& xmlFilePath, bool forVts);
std::string mSource; // Not kDefaultConfigSource. Empty source means an empty config.
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
index 92292e1..7e29e10 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
@@ -138,7 +138,7 @@
*/
status_t setUserIdDeviceAffinities(int userId, const AudioDeviceTypeAddrVector& devices);
status_t removeUserIdDeviceAffinities(int userId);
- status_t getDevicesForUserId(int userId, Vector<AudioDeviceTypeAddr>& devices) const;
+ status_t getDevicesForUserId(int userId, AudioDeviceTypeAddrVector& devices) const;
void dump(String8 *dst) const;
diff --git a/services/audiopolicy/common/managerdefinitions/include/HwModule.h b/services/audiopolicy/common/managerdefinitions/include/HwModule.h
index 436fcc1..e994758 100644
--- a/services/audiopolicy/common/managerdefinitions/include/HwModule.h
+++ b/services/audiopolicy/common/managerdefinitions/include/HwModule.h
@@ -39,7 +39,8 @@
class HwModule : public RefBase
{
public:
- explicit HwModule(const char *name, uint32_t halVersionMajor = 0, uint32_t halVersionMinor = 0);
+ explicit HwModule(const char *name, uint32_t halVersionMajor, uint32_t halVersionMinor);
+ HwModule(const char *name, uint32_t halVersion = 0);
~HwModule();
const char *getName() const { return mName.string(); }
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
index 09ca989..8b23311 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
@@ -389,6 +389,11 @@
return supportedDevices().containsAllDevices(devices);
}
+bool SwAudioOutputDescriptor::supportsAtLeastOne(const DeviceVector &devices) const
+{
+ return filterSupportedDevices(devices).size() > 0;
+}
+
bool SwAudioOutputDescriptor::supportsDevicesForPlayback(const DeviceVector &devices) const
{
// No considering duplicated output
@@ -701,12 +706,6 @@
}
}
- // TODO(b/73175392) consider improving the AIDL interface.
- // Signal closing to A2DP HAL.
- AudioParameter param;
- param.add(String8(AudioParameter::keyClosing), String8("true"));
- mClientInterface->setParameters(mIoHandle, param.toString());
-
mClientInterface->closeOutput(mIoHandle);
LOG_ALWAYS_FATAL_IF(mProfile->curOpenCount < 1, "%s profile open count %u",
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyConfig.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyConfig.cpp
index 42c76e2..e214ae9 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyConfig.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyConfig.cpp
@@ -19,6 +19,9 @@
#include <AudioPolicyConfig.h>
#include <IOProfile.h>
#include <Serializer.h>
+#include <hardware/audio.h>
+#include <media/AidlConversion.h>
+#include <media/AidlConversionUtil.h>
#include <media/AudioProfile.h>
#include <system/audio.h>
#include <system/audio_config.h>
@@ -26,6 +29,142 @@
namespace android {
+using media::audio::common::AudioIoFlags;
+using media::audio::common::AudioPortDeviceExt;
+using media::audio::common::AudioPortExt;
+
+namespace {
+
+ConversionResult<sp<PolicyAudioPort>>
+aidl2legacy_portId_PolicyAudioPort(int32_t portId,
+ const std::unordered_map<int32_t, sp<PolicyAudioPort>>& ports) {
+ if (auto it = ports.find(portId); it != ports.end()) {
+ return it->second;
+ }
+ return base::unexpected(BAD_VALUE);
+}
+
+ConversionResult<sp<AudioRoute>>
+aidl2legacy_AudioRoute(const media::AudioRoute& aidl,
+ const std::unordered_map<int32_t, sp<PolicyAudioPort>>& ports) {
+ auto legacy = sp<AudioRoute>::make(aidl.isExclusive ? AUDIO_ROUTE_MUX : AUDIO_ROUTE_MIX);
+ auto legacySink = VALUE_OR_RETURN(aidl2legacy_portId_PolicyAudioPort(aidl.sinkPortId, ports));
+ legacy->setSink(legacySink);
+ PolicyAudioPortVector legacySources;
+ for (int32_t portId : aidl.sourcePortIds) {
+ sp<PolicyAudioPort> legacyPort = VALUE_OR_RETURN(
+ aidl2legacy_portId_PolicyAudioPort(portId, ports));
+ legacySources.add(legacyPort);
+ }
+ legacy->setSources(legacySources);
+ legacySink->addRoute(legacy);
+ for (const auto& legacySource : legacySources) {
+ legacySource->addRoute(legacy);
+ }
+ return legacy;
+}
+
+status_t aidl2legacy_AudioHwModule_HwModule(const media::AudioHwModule& aidl,
+ sp<HwModule>* legacy,
+ DeviceVector* attachedInputDevices, DeviceVector* attachedOutputDevices,
+ sp<DeviceDescriptor>* defaultOutputDevice) {
+ *legacy = sp<HwModule>::make(aidl.name.c_str(), AUDIO_DEVICE_API_VERSION_CURRENT);
+ audio_module_handle_t legacyHandle = VALUE_OR_RETURN_STATUS(
+ aidl2legacy_int32_t_audio_module_handle_t(aidl.handle));
+ (*legacy)->setHandle(legacyHandle);
+ IOProfileCollection mixPorts;
+ DeviceVector devicePorts;
+ const int defaultDeviceFlag = 1 << AudioPortDeviceExt::FLAG_INDEX_DEFAULT_DEVICE;
+ std::unordered_map<int32_t, sp<PolicyAudioPort>> ports;
+ for (const auto& aidlPort : aidl.ports) {
+ const bool isInput = aidlPort.flags.getTag() == AudioIoFlags::input;
+ audio_port_v7 legacyPort = VALUE_OR_RETURN_STATUS(
+ aidl2legacy_AudioPort_audio_port_v7(aidlPort, isInput));
+ // This conversion fills out both 'hal' and 'sys' parts.
+ media::AudioPortFw fwPort = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_port_v7_AudioPortFw(legacyPort));
+ // Since audio_port_v7 lacks some fields, for example, 'maxOpen/ActiveCount',
+ // replace the converted data with the actual data from the HAL.
+ fwPort.hal = aidlPort;
+ if (aidlPort.ext.getTag() == AudioPortExt::mix) {
+ auto mixPort = sp<IOProfile>::make("", AUDIO_PORT_ROLE_NONE);
+ RETURN_STATUS_IF_ERROR(mixPort->readFromParcelable(fwPort));
+ sortAudioProfiles(mixPort->getAudioProfiles());
+ mixPorts.add(mixPort);
+ ports.emplace(aidlPort.id, mixPort);
+ } else if (aidlPort.ext.getTag() == AudioPortExt::device) {
+ // In the legacy XML, device ports use 'tagName' instead of 'AudioPort.name'.
+ auto devicePort =
+ sp<DeviceDescriptor>::make(AUDIO_DEVICE_NONE, aidlPort.name);
+ RETURN_STATUS_IF_ERROR(devicePort->readFromParcelable(fwPort));
+ devicePort->setName("");
+ auto& profiles = devicePort->getAudioProfiles();
+ if (profiles.empty()) {
+ profiles.add(AudioProfile::createFullDynamic(gDynamicFormat));
+ } else {
+ sortAudioProfiles(profiles);
+ }
+ devicePorts.add(devicePort);
+ ports.emplace(aidlPort.id, devicePort);
+
+ if (const auto& deviceExt = aidlPort.ext.get<AudioPortExt::device>();
+ deviceExt.device.type.connection.empty()) { // Attached device
+ if (isInput) {
+ attachedInputDevices->add(devicePort);
+ } else {
+ attachedOutputDevices->add(devicePort);
+ if ((deviceExt.flags & defaultDeviceFlag) != 0) {
+ *defaultOutputDevice = devicePort;
+ }
+ }
+ }
+ } else {
+ return BAD_VALUE;
+ }
+ }
+ (*legacy)->setProfiles(mixPorts);
+ (*legacy)->setDeclaredDevices(devicePorts);
+ AudioRouteVector routes;
+ for (const auto& aidlRoute : aidl.routes) {
+ sp<AudioRoute> legacy = VALUE_OR_RETURN_STATUS(aidl2legacy_AudioRoute(aidlRoute, ports));
+ routes.add(legacy);
+ }
+ (*legacy)->setRoutes(routes);
+ return OK;
+}
+
+status_t aidl2legacy_AudioHwModules_HwModuleCollection(
+ const std::vector<media::AudioHwModule>& aidl,
+ HwModuleCollection* legacyModules, DeviceVector* attachedInputDevices,
+ DeviceVector* attachedOutputDevices, sp<DeviceDescriptor>* defaultOutputDevice) {
+ for (const auto& aidlModule : aidl) {
+ sp<HwModule> legacy;
+ RETURN_STATUS_IF_ERROR(aidl2legacy_AudioHwModule_HwModule(aidlModule, &legacy,
+ attachedInputDevices, attachedOutputDevices, defaultOutputDevice));
+ legacyModules->add(legacy);
+ }
+ return OK;
+}
+
+using SurroundFormatFamily = AudioPolicyConfig::SurroundFormats::value_type;
+ConversionResult<SurroundFormatFamily>
+aidl2legacy_SurroundFormatFamily(const media::SurroundSoundConfig::SurroundFormatFamily& aidl) {
+ audio_format_t legacyPrimary = VALUE_OR_RETURN(
+ aidl2legacy_AudioFormatDescription_audio_format_t(aidl.primaryFormat));
+ std::unordered_set<audio_format_t> legacySubs = VALUE_OR_RETURN(
+ convertContainer<std::unordered_set<audio_format_t>>(
+ aidl.subFormats, aidl2legacy_AudioFormatDescription_audio_format_t));
+ return std::make_pair(legacyPrimary, legacySubs);
+}
+
+ConversionResult<AudioPolicyConfig::SurroundFormats>
+aidl2legacy_SurroundSoundConfig_SurroundFormats(const media::SurroundSoundConfig& aidl) {
+ return convertContainer<AudioPolicyConfig::SurroundFormats>(aidl.formatFamilies,
+ aidl2legacy_SurroundFormatFamily);
+};
+
+} // namespace
+
// static
sp<const AudioPolicyConfig> AudioPolicyConfig::createDefault() {
auto config = sp<AudioPolicyConfig>::make();
@@ -34,6 +173,16 @@
}
// static
+sp<const AudioPolicyConfig> AudioPolicyConfig::loadFromApmAidlConfigWithFallback(
+ const media::AudioPolicyConfig& aidl) {
+ auto config = sp<AudioPolicyConfig>::make();
+ if (status_t status = config->loadFromAidl(aidl); status == NO_ERROR) {
+ return config;
+ }
+ return createDefault();
+}
+
+// static
sp<const AudioPolicyConfig> AudioPolicyConfig::loadFromApmXmlConfigWithFallback(
const std::string& xmlFilePath) {
const std::string filePath =
@@ -100,6 +249,18 @@
}
}
+status_t AudioPolicyConfig::loadFromAidl(const media::AudioPolicyConfig& aidl) {
+ RETURN_STATUS_IF_ERROR(aidl2legacy_AudioHwModules_HwModuleCollection(aidl.modules,
+ &mHwModules, &mInputDevices, &mOutputDevices, &mDefaultOutputDevice));
+ mIsCallScreenModeSupported = std::find(aidl.supportedModes.begin(), aidl.supportedModes.end(),
+ media::audio::common::AudioMode::CALL_SCREEN) != aidl.supportedModes.end();
+ mSurroundFormats = VALUE_OR_RETURN_STATUS(
+ aidl2legacy_SurroundSoundConfig_SurroundFormats(aidl.surroundSoundConfig));
+ mSource = kAidlConfigSource;
+ // No need to augmentData() as AIDL HAL must provide correct mic addresses.
+ return NO_ERROR;
+}
+
status_t AudioPolicyConfig::loadFromXml(const std::string& xmlFilePath, bool forVts) {
if (xmlFilePath.empty()) {
ALOGE("Audio policy configuration file name is empty");
@@ -131,7 +292,8 @@
mOutputDevices.add(mDefaultOutputDevice);
mInputDevices.add(defaultInputDevice);
- sp<HwModule> module = new HwModule(AUDIO_HARDWARE_MODULE_ID_PRIMARY, 2 /*halVersionMajor*/);
+ sp<HwModule> module = new HwModule(
+ AUDIO_HARDWARE_MODULE_ID_PRIMARY, AUDIO_DEVICE_API_VERSION_2_0);
mHwModules.add(module);
sp<OutputProfile> outProfile = new OutputProfile("primary");
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
index 6b9757d..bc2ba31 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
@@ -642,7 +642,7 @@
}
status_t AudioPolicyMixCollection::getDevicesForUserId(int userId,
- Vector<AudioDeviceTypeAddr>& devices) const {
+ AudioDeviceTypeAddrVector& devices) const {
// for each player mix:
// find rules that don't exclude this userId, and add the device to the list
for (size_t i = 0; i < size(); i++) {
@@ -660,7 +660,7 @@
}
}
if (ruleAllowsUserId) {
- devices.add(AudioDeviceTypeAddr(mix->mDeviceType, mix->mDeviceAddress.string()));
+ devices.push_back(AudioDeviceTypeAddr(mix->mDeviceType, mix->mDeviceAddress.string()));
}
}
return NO_ERROR;
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioProfileVectorHelper.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioProfileVectorHelper.cpp
index 8ccb8b9..82f51ad 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioProfileVectorHelper.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioProfileVectorHelper.cpp
@@ -115,12 +115,22 @@
profile->setDynamicFormat(true);
profile->setDynamicChannels(dynamicFormatProfile->isDynamicChannels());
profile->setDynamicRate(dynamicFormatProfile->isDynamicRate());
- addAudioProfileAndSort(audioProfileVector, profile);
+ size_t profileIndex = 0;
+ for (; profileIndex < audioProfileVector.size(); profileIndex++) {
+ if (profile->equals(audioProfileVector.at(profileIndex))) {
+ // The dynamic profile is already there
+ break;
+ }
+ }
+ if (profileIndex >= audioProfileVector.size()) {
+ // Only add when the dynamic profile is not there
+ addAudioProfileAndSort(audioProfileVector, profile);
+ }
}
}
void addDynamicAudioProfileAndSort(AudioProfileVector &audioProfileVector,
- const sp<AudioProfile> &profileToAdd)
+ const sp<AudioProfile> &profileToAdd)
{
// Check valid profile to add:
if (!profileToAdd->hasValidFormat()) {
@@ -143,11 +153,15 @@
audioProfileVector, profileToAdd->getChannels(), profileToAdd->getFormat());
return;
}
+ const bool originalIsDynamicFormat = profileToAdd->isDynamicFormat();
+ profileToAdd->setDynamicFormat(true); // set the format as dynamic to allow removal
// Go through the list of profile to avoid duplicates
for (size_t profileIndex = 0; profileIndex < audioProfileVector.size(); profileIndex++) {
const sp<AudioProfile> &profile = audioProfileVector.at(profileIndex);
- if (profile->isValid() && profile == profileToAdd) {
- // Nothing to do
+ if (profile->isValid() && profile->equals(profileToAdd)) {
+ // The same profile is already there, no need to add.
+ // Reset `isDynamicProfile` as original value.
+ profileToAdd->setDynamicFormat(originalIsDynamicFormat);
return;
}
}
diff --git a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
index 418b7eb..5f14ee4 100644
--- a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
@@ -33,6 +33,13 @@
setHalVersion(halVersionMajor, halVersionMinor);
}
+HwModule::HwModule(const char *name, uint32_t halVersion)
+ : mName(String8(name)),
+ mHandle(AUDIO_MODULE_HANDLE_NONE),
+ mHalVersion(halVersion)
+{
+}
+
HwModule::~HwModule()
{
for (size_t i = 0; i < mOutputProfiles.size(); i++) {
diff --git a/services/audiopolicy/engine/common/Android.bp b/services/audiopolicy/engine/common/Android.bp
index 50c5eab..6c46c54 100644
--- a/services/audiopolicy/engine/common/Android.bp
+++ b/services/audiopolicy/engine/common/Android.bp
@@ -51,10 +51,10 @@
"libaudiopolicyengine_common_headers",
],
static_libs: [
- "libaudiopolicycomponents",
"libaudiopolicyengine_config",
],
shared_libs: [
"libaudiofoundation",
+ "libaudiopolicycomponents",
],
}
diff --git a/services/audiopolicy/engine/common/include/EngineBase.h b/services/audiopolicy/engine/common/include/EngineBase.h
index bac51f5..b9c94a4 100644
--- a/services/audiopolicy/engine/common/include/EngineBase.h
+++ b/services/audiopolicy/engine/common/include/EngineBase.h
@@ -16,6 +16,9 @@
#pragma once
+#include <functional>
+
+#include <android/media/audio/common/AudioHalEngineConfig.h>
#include <EngineConfig.h>
#include <EngineInterface.h>
#include <ProductStrategy.h>
@@ -113,6 +116,9 @@
status_t getDevicesForRoleAndStrategy(product_strategy_t strategy, device_role_t role,
AudioDeviceTypeAddrVector &devices) const override;
+ engineConfig::ParsingResult loadAudioPolicyEngineConfig(
+ const media::audio::common::AudioHalEngineConfig& aidlConfig);
+
engineConfig::ParsingResult loadAudioPolicyEngineConfig(const std::string& xmlFilePath = "");
const ProductStrategyMap &getProductStrategies() const { return mProductStrategies; }
@@ -176,6 +182,8 @@
const DeviceVector& availableOutputDevices, product_strategy_t strategy) const;
private:
+ engineConfig::ParsingResult processParsingResult(engineConfig::ParsingResult&& rawResult);
+
/**
* Get media devices as the given role
*
diff --git a/services/audiopolicy/engine/common/src/EngineBase.cpp b/services/audiopolicy/engine/common/src/EngineBase.cpp
index 7d6a308..218aff8 100644
--- a/services/audiopolicy/engine/common/src/EngineBase.cpp
+++ b/services/audiopolicy/engine/common/src/EngineBase.cpp
@@ -115,10 +115,53 @@
return PRODUCT_STRATEGY_NONE;
}
+engineConfig::ParsingResult EngineBase::loadAudioPolicyEngineConfig(
+ const media::audio::common::AudioHalEngineConfig& aidlConfig)
+{
+ engineConfig::ParsingResult result = engineConfig::convert(aidlConfig);
+ if (result.parsedConfig == nullptr) {
+ ALOGE("%s: There was an error parsing AIDL data", __func__);
+ result = {std::make_unique<engineConfig::Config>(gDefaultEngineConfig), 1};
+ } else {
+ // It is allowed for the HAL to return an empty list of strategies.
+ if (result.parsedConfig->productStrategies.empty()) {
+ result.parsedConfig->productStrategies = gDefaultEngineConfig.productStrategies;
+ }
+ }
+ return processParsingResult(std::move(result));
+}
+
engineConfig::ParsingResult EngineBase::loadAudioPolicyEngineConfig(const std::string& xmlFilePath)
{
+ auto fileExists = [](const char* path) {
+ struct stat fileStat;
+ return stat(path, &fileStat) == 0 && S_ISREG(fileStat.st_mode);
+ };
+ const std::string filePath = xmlFilePath.empty() ? engineConfig::DEFAULT_PATH : xmlFilePath;
+ engineConfig::ParsingResult result =
+ fileExists(filePath.c_str()) ?
+ engineConfig::parse(filePath.c_str()) : engineConfig::ParsingResult{};
+ if (result.parsedConfig == nullptr) {
+ ALOGD("%s: No configuration found, using default matching phone experience.", __FUNCTION__);
+ engineConfig::Config config = gDefaultEngineConfig;
+ android::status_t ret = engineConfig::parseLegacyVolumes(config.volumeGroups);
+ result = {std::make_unique<engineConfig::Config>(config),
+ static_cast<size_t>(ret == NO_ERROR ? 0 : 1)};
+ } else {
+ // Append for internal use only volume groups (e.g. rerouting/patch)
+ result.parsedConfig->volumeGroups.insert(
+ std::end(result.parsedConfig->volumeGroups),
+ std::begin(gSystemVolumeGroups), std::end(gSystemVolumeGroups));
+ }
+ ALOGE_IF(result.nbSkippedElement != 0, "skipped %zu elements", result.nbSkippedElement);
+ return processParsingResult(std::move(result));
+}
+
+engineConfig::ParsingResult EngineBase::processParsingResult(
+ engineConfig::ParsingResult&& rawResult)
+{
auto loadVolumeConfig = [](auto &volumeGroups, auto &volumeConfig) {
- // Ensure name unicity to prevent duplicate
+ // Ensure volume group name uniqueness.
LOG_ALWAYS_FATAL_IF(std::any_of(std::begin(volumeGroups), std::end(volumeGroups),
[&volumeConfig](const auto &volumeGroup) {
return volumeConfig.name == volumeGroup.second->getName(); }),
@@ -158,42 +201,21 @@
});
return iter != end(volumeGroups);
};
- auto fileExists = [](const char* path) {
- struct stat fileStat;
- return stat(path, &fileStat) == 0 && S_ISREG(fileStat.st_mode);
- };
- const std::string filePath = xmlFilePath.empty() ? engineConfig::DEFAULT_PATH : xmlFilePath;
- auto result = fileExists(filePath.c_str()) ?
- engineConfig::parse(filePath.c_str()) : engineConfig::ParsingResult{};
- if (result.parsedConfig == nullptr) {
- ALOGD("%s: No configuration found, using default matching phone experience.", __FUNCTION__);
- engineConfig::Config config = gDefaultEngineConfig;
- android::status_t ret = engineConfig::parseLegacyVolumes(config.volumeGroups);
- result = {std::make_unique<engineConfig::Config>(config),
- static_cast<size_t>(ret == NO_ERROR ? 0 : 1)};
- } else {
- // Append for internal use only volume groups (e.g. rerouting/patch)
- result.parsedConfig->volumeGroups.insert(
- std::end(result.parsedConfig->volumeGroups),
- std::begin(gSystemVolumeGroups), std::end(gSystemVolumeGroups));
- }
+ auto result = std::move(rawResult);
// Append for internal use only strategies (e.g. rerouting/patch)
result.parsedConfig->productStrategies.insert(
std::end(result.parsedConfig->productStrategies),
std::begin(gOrderedSystemStrategies), std::end(gOrderedSystemStrategies));
-
- ALOGE_IF(result.nbSkippedElement != 0, "skipped %zu elements", result.nbSkippedElement);
-
engineConfig::VolumeGroup defaultVolumeConfig;
engineConfig::VolumeGroup defaultSystemVolumeConfig;
for (auto &volumeConfig : result.parsedConfig->volumeGroups) {
// save default volume config for streams not defined in configuration
- if (volumeConfig.name.compare("AUDIO_STREAM_MUSIC") == 0) {
+ if (volumeConfig.name.compare(audio_stream_type_to_string(AUDIO_STREAM_MUSIC)) == 0) {
defaultVolumeConfig = volumeConfig;
}
- if (volumeConfig.name.compare("AUDIO_STREAM_PATCH") == 0) {
+ if (volumeConfig.name.compare(audio_stream_type_to_string(AUDIO_STREAM_PATCH)) == 0) {
defaultSystemVolumeConfig = volumeConfig;
}
loadVolumeConfig(mVolumeGroups, volumeConfig);
diff --git a/services/audiopolicy/engine/config/Android.bp b/services/audiopolicy/engine/config/Android.bp
index 459cc78..12597de 100644
--- a/services/audiopolicy/engine/config/Android.bp
+++ b/services/audiopolicy/engine/config/Android.bp
@@ -22,11 +22,13 @@
"-Wextra",
],
shared_libs: [
- "libmedia_helper",
- "libxml2",
- "libutils",
- "liblog",
+ "libaudio_aidl_conversion_common_cpp",
+ "libaudiopolicycomponents",
"libcutils",
+ "liblog",
+ "libmedia_helper",
+ "libutils",
+ "libxml2",
],
header_libs: [
"libaudio_system_headers",
diff --git a/services/audiopolicy/engine/config/include/EngineConfig.h b/services/audiopolicy/engine/config/include/EngineConfig.h
index 4de16c5..119dbd6 100644
--- a/services/audiopolicy/engine/config/include/EngineConfig.h
+++ b/services/audiopolicy/engine/config/include/EngineConfig.h
@@ -16,10 +16,11 @@
#pragma once
-#include <system/audio.h>
-
#include <string>
#include <vector>
+
+#include <android/media/audio/common/AudioHalEngineConfig.h>
+#include <system/audio.h>
#include <utils/Errors.h>
struct _xmlNode;
@@ -116,6 +117,7 @@
*/
ParsingResult parse(const char* path = DEFAULT_PATH);
android::status_t parseLegacyVolumes(VolumeGroups &volumeGroups);
+ParsingResult convert(const ::android::media::audio::common::AudioHalEngineConfig& aidlConfig);
// Exposed for testing.
android::status_t parseLegacyVolumeFile(const char* path, VolumeGroups &volumeGroups);
diff --git a/services/audiopolicy/engine/config/src/EngineConfig.cpp b/services/audiopolicy/engine/config/src/EngineConfig.cpp
index ac117f0..ca78ce7 100644
--- a/services/audiopolicy/engine/config/src/EngineConfig.cpp
+++ b/services/audiopolicy/engine/config/src/EngineConfig.cpp
@@ -14,26 +14,30 @@
* limitations under the License.
*/
+#include <cstdint>
+#include <istream>
+#include <map>
+#include <sstream>
+#include <stdarg.h>
+#include <string>
+#include <string>
+#include <vector>
+
#define LOG_TAG "APM::AudioPolicyEngine/Config"
//#define LOG_NDEBUG 0
#include "EngineConfig.h"
+#include <TypeConverter.h>
+#include <Volume.h>
#include <cutils/properties.h>
+#include <libxml/parser.h>
+#include <libxml/xinclude.h>
+#include <media/AidlConversion.h>
+#include <media/AidlConversionUtil.h>
#include <media/TypeConverter.h>
#include <media/convert.h>
#include <system/audio_config.h>
#include <utils/Log.h>
-#include <libxml/parser.h>
-#include <libxml/xinclude.h>
-#include <string>
-#include <vector>
-#include <map>
-#include <sstream>
-#include <istream>
-
-#include <cstdint>
-#include <stdarg.h>
-#include <string>
namespace android {
@@ -45,6 +49,85 @@
static const char *const gReferenceElementName = "reference";
static const char *const gReferenceAttributeName = "name";
+namespace {
+
+ConversionResult<AttributesGroup> aidl2legacy_AudioHalAttributeGroup_AttributesGroup(
+ const media::audio::common::AudioHalAttributesGroup& aidl) {
+ AttributesGroup legacy;
+ legacy.stream = VALUE_OR_RETURN(
+ aidl2legacy_AudioStreamType_audio_stream_type_t(aidl.streamType));
+ legacy.volumeGroup = aidl.volumeGroupName;
+ legacy.attributesVect = VALUE_OR_RETURN(convertContainer<AttributesVector>(
+ aidl.attributes, aidl2legacy_AudioAttributes_audio_attributes_t));
+ return legacy;
+}
+
+ConversionResult<ProductStrategy> aidl2legacy_AudioHalProductStrategy_ProductStrategy(
+ const media::audio::common::AudioHalProductStrategy& aidl) {
+ ProductStrategy legacy;
+ legacy.name = "strategy_" + std::to_string(aidl.id);
+ legacy.attributesGroups = VALUE_OR_RETURN(convertContainer<AttributesGroups>(
+ aidl.attributesGroups,
+ aidl2legacy_AudioHalAttributeGroup_AttributesGroup));
+ return legacy;
+}
+
+ConversionResult<std::string> legacy_device_category_to_string(device_category legacy) {
+ std::string s;
+ if (DeviceCategoryConverter::toString(legacy, s)) {
+ return s;
+ }
+ return base::unexpected(BAD_VALUE);
+}
+
+ConversionResult<std::string> aidl2legacy_DeviceCategory(
+ const media::audio::common::AudioHalVolumeCurve::DeviceCategory aidl) {
+ using DeviceCategory = media::audio::common::AudioHalVolumeCurve::DeviceCategory;
+ switch (aidl) {
+ case DeviceCategory::HEADSET:
+ return legacy_device_category_to_string(DEVICE_CATEGORY_HEADSET);
+ case DeviceCategory::SPEAKER:
+ return legacy_device_category_to_string(DEVICE_CATEGORY_SPEAKER);
+ case DeviceCategory::EARPIECE:
+ return legacy_device_category_to_string(DEVICE_CATEGORY_EARPIECE);
+ case DeviceCategory::EXT_MEDIA:
+ return legacy_device_category_to_string(DEVICE_CATEGORY_EXT_MEDIA);
+ case DeviceCategory::HEARING_AID:
+ return legacy_device_category_to_string(DEVICE_CATEGORY_HEARING_AID);
+ }
+ return base::unexpected(BAD_VALUE);
+}
+
+ConversionResult<CurvePoint> aidl2legacy_AudioHalCurvePoint_CurvePoint(
+ const media::audio::common::AudioHalVolumeCurve::CurvePoint& aidl) {
+ CurvePoint legacy;
+ legacy.index = VALUE_OR_RETURN(convertIntegral<int>(aidl.index));
+ legacy.attenuationInMb = aidl.attenuationMb;
+ return legacy;
+}
+
+ConversionResult<VolumeCurve> aidl2legacy_AudioHalVolumeCurve_VolumeCurve(
+ const media::audio::common::AudioHalVolumeCurve& aidl) {
+ VolumeCurve legacy;
+ legacy.deviceCategory = VALUE_OR_RETURN(aidl2legacy_DeviceCategory(aidl.deviceCategory));
+ legacy.curvePoints = VALUE_OR_RETURN(convertContainer<CurvePoints>(
+ aidl.curvePoints, aidl2legacy_AudioHalCurvePoint_CurvePoint));
+ return legacy;
+}
+
+ConversionResult<VolumeGroup> aidl2legacy_AudioHalVolumeGroup_VolumeGroup(
+ const media::audio::common::AudioHalVolumeGroup& aidl) {
+ VolumeGroup legacy;
+ legacy.name = aidl.name;
+ legacy.indexMin = aidl.minIndex;
+ legacy.indexMax = aidl.maxIndex;
+ legacy.volumeCurves = VALUE_OR_RETURN(convertContainer<VolumeCurves>(
+ aidl.volumeCurves, aidl2legacy_AudioHalVolumeCurve_VolumeCurve));
+ return legacy;
+}
+
+} // namespace
+
template<typename E, typename C>
struct BaseSerializerTraits {
typedef E Element;
@@ -724,5 +807,25 @@
}
}
+ParsingResult convert(const ::android::media::audio::common::AudioHalEngineConfig& aidlConfig) {
+ auto config = std::make_unique<engineConfig::Config>();
+ config->version = 1.0f;
+ if (auto conv = convertContainer<engineConfig::ProductStrategies>(
+ aidlConfig.productStrategies,
+ aidl2legacy_AudioHalProductStrategy_ProductStrategy); conv.ok()) {
+ config->productStrategies = std::move(conv.value());
+ } else {
+ return ParsingResult{};
+ }
+ if (auto conv = convertContainer<engineConfig::VolumeGroups>(
+ aidlConfig.volumeGroups,
+ aidl2legacy_AudioHalVolumeGroup_VolumeGroup); conv.ok()) {
+ config->volumeGroups = std::move(conv.value());
+ } else {
+ return ParsingResult{};
+ }
+ return {.parsedConfig=std::move(config), .nbSkippedElement=0};
+ }
+
} // namespace engineConfig
} // namespace android
diff --git a/services/audiopolicy/engine/config/tests/Android.bp b/services/audiopolicy/engine/config/tests/Android.bp
index 5791f17..5d1aa16 100644
--- a/services/audiopolicy/engine/config/tests/Android.bp
+++ b/services/audiopolicy/engine/config/tests/Android.bp
@@ -11,6 +11,7 @@
name: "audiopolicy_engineconfig_tests",
shared_libs: [
+ "libaudiopolicycomponents",
"libbase",
"liblog",
"libmedia_helper",
diff --git a/services/audiopolicy/engine/interface/EngineInterface.h b/services/audiopolicy/engine/interface/EngineInterface.h
index dd7ac1a..70461ad 100644
--- a/services/audiopolicy/engine/interface/EngineInterface.h
+++ b/services/audiopolicy/engine/interface/EngineInterface.h
@@ -20,6 +20,7 @@
#include <utility>
#include <AudioPolicyManagerObserver.h>
+#include <android/media/audio/common/AudioHalEngineConfig.h>
#include <media/AudioProductStrategy.h>
#include <media/AudioVolumeGroup.h>
#include <IVolumeCurves.h>
@@ -47,6 +48,14 @@
{
public:
/**
+ * Loads the engine configuration from AIDL configuration data.
+ * If loading failed, tries to fall back to some default configuration. If fallback
+ * is impossible, returns an error.
+ */
+ virtual status_t loadFromHalConfigWithFallback(
+ const media::audio::common::AudioHalEngineConfig& config) = 0;
+
+ /**
* Loads the engine configuration from the specified or the default config file.
* If loading failed, tries to fall back to some default configuration. If fallback
* is impossible, returns an error.
diff --git a/services/audiopolicy/engineconfigurable/Android.bp b/services/audiopolicy/engineconfigurable/Android.bp
index dc8d9cf..eb2e2f4 100644
--- a/services/audiopolicy/engineconfigurable/Android.bp
+++ b/services/audiopolicy/engineconfigurable/Android.bp
@@ -35,14 +35,15 @@
"libaudiopolicyengineconfigurable_interface_headers",
],
static_libs: [
- "libaudiopolicycomponents",
"libaudiopolicyengine_common",
"libaudiopolicyengine_config",
"libaudiopolicyengineconfigurable_pfwwrapper",
],
shared_libs: [
+ "libaudio_aidl_conversion_common_cpp",
"libaudiofoundation",
+ "libaudiopolicycomponents",
"libbase",
"liblog",
"libcutils",
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Android.bp b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Android.bp
index 0398fc7..f7159c5 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Android.bp
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Android.bp
@@ -31,11 +31,11 @@
"libaudiopolicyengineconfigurable_interface_headers",
],
static_libs: [
- "libaudiopolicycomponents",
"libaudiopolicyengine_common",
"libpfw_utility",
],
shared_libs: [
+ "libaudiopolicycomponents",
"libaudiopolicyengineconfigurable",
"liblog",
"libutils",
diff --git a/services/audiopolicy/engineconfigurable/src/Engine.cpp b/services/audiopolicy/engineconfigurable/src/Engine.cpp
index 2eb0177..ccd4316 100644
--- a/services/audiopolicy/engineconfigurable/src/Engine.cpp
+++ b/services/audiopolicy/engineconfigurable/src/Engine.cpp
@@ -70,6 +70,12 @@
{
}
+status_t Engine::loadFromHalConfigWithFallback(
+ const media::audio::common::AudioHalEngineConfig& config __unused) {
+ // b/242678729. Need to implement for the configurable engine.
+ return INVALID_OPERATION;
+}
+
status_t Engine::loadFromXmlConfigWithFallback(const std::string& xmlFilePath)
{
status_t loadResult = loadAudioPolicyEngineConfig(xmlFilePath);
diff --git a/services/audiopolicy/engineconfigurable/src/Engine.h b/services/audiopolicy/engineconfigurable/src/Engine.h
index b964cd6..4f3e620 100644
--- a/services/audiopolicy/engineconfigurable/src/Engine.h
+++ b/services/audiopolicy/engineconfigurable/src/Engine.h
@@ -41,12 +41,15 @@
///
/// from EngineInterface
///
- android::status_t loadFromXmlConfigWithFallback(const std::string& xmlFilePath = "") override;
+ status_t loadFromHalConfigWithFallback(
+ const media::audio::common::AudioHalEngineConfig& config) override;
+
+ status_t loadFromXmlConfigWithFallback(const std::string& xmlFilePath = "") override;
///
/// from EngineBase
///
- android::status_t initCheck() override;
+ status_t initCheck() override;
status_t setPhoneState(audio_mode_t mode) override;
@@ -56,8 +59,8 @@
audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage) const override;
- android::status_t setDeviceConnectionState(const sp<DeviceDescriptor> devDesc,
- audio_policy_dev_state_t state) override;
+ status_t setDeviceConnectionState(const sp<DeviceDescriptor> devDesc,
+ audio_policy_dev_state_t state) override;
DeviceVector getOutputDevicesForAttributes(const audio_attributes_t &attr,
const sp<DeviceDescriptor> &preferedDevice = nullptr,
diff --git a/services/audiopolicy/enginedefault/Android.bp b/services/audiopolicy/enginedefault/Android.bp
index 4671fe9..7d4ccab 100644
--- a/services/audiopolicy/enginedefault/Android.bp
+++ b/services/audiopolicy/enginedefault/Android.bp
@@ -25,12 +25,13 @@
"libaudiopolicyengine_interface_headers",
],
static_libs: [
- "libaudiopolicycomponents",
"libaudiopolicyengine_common",
"libaudiopolicyengine_config",
],
shared_libs: [
+ "libaudio_aidl_conversion_common_cpp",
"libaudiofoundation",
+ "libaudiopolicycomponents",
"libbase",
"liblog",
"libcutils",
diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
index 88cbb7d..15f7842 100644
--- a/services/audiopolicy/enginedefault/src/Engine.cpp
+++ b/services/audiopolicy/enginedefault/src/Engine.cpp
@@ -35,10 +35,7 @@
#include <utils/String8.h>
#include <utils/Log.h>
-namespace android
-{
-namespace audio_policy
-{
+namespace android::audio_policy {
struct legacy_strategy_map { const char *name; legacy_strategy id; };
static const std::vector<legacy_strategy_map>& getLegacyStrategy() {
@@ -59,8 +56,18 @@
return legacyStrategy;
}
+status_t Engine::loadFromHalConfigWithFallback(
+ const media::audio::common::AudioHalEngineConfig& aidlConfig) {
+ return loadWithFallback(aidlConfig);
+}
+
status_t Engine::loadFromXmlConfigWithFallback(const std::string& xmlFilePath) {
- auto result = EngineBase::loadAudioPolicyEngineConfig(xmlFilePath);
+ return loadWithFallback(xmlFilePath);
+}
+
+template<typename T>
+status_t Engine::loadWithFallback(const T& configSource) {
+ auto result = EngineBase::loadAudioPolicyEngineConfig(configSource);
ALOGE_IF(result.nbSkippedElement != 0,
"Policy Engine configuration is partially invalid, skipped %zu elements",
result.nbSkippedElement);
@@ -73,6 +80,7 @@
return OK;
}
+
status_t Engine::setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config)
{
switch(usage) {
@@ -844,5 +852,4 @@
AUDIO_FORMAT_DEFAULT);
}
-} // namespace audio_policy
-} // namespace android
+} // namespace android::audio_policy
diff --git a/services/audiopolicy/enginedefault/src/Engine.h b/services/audiopolicy/enginedefault/src/Engine.h
index 8410560..878bca9 100644
--- a/services/audiopolicy/enginedefault/src/Engine.h
+++ b/services/audiopolicy/enginedefault/src/Engine.h
@@ -47,10 +47,14 @@
public:
Engine() = default;
virtual ~Engine() = default;
+ Engine(const Engine &object) = delete;
+ Engine &operator=(const Engine &object) = delete;
///
/// from EngineInterface
///
+ status_t loadFromHalConfigWithFallback(
+ const media::audio::common::AudioHalEngineConfig& config) override;
status_t loadFromXmlConfigWithFallback(const std::string& xmlFilePath = "") override;
private:
@@ -79,9 +83,8 @@
DeviceVector getDevicesForProductStrategy(product_strategy_t strategy) const override;
private:
- /* Copy facilities are put private to disable copy. */
- Engine(const Engine &object);
- Engine &operator=(const Engine &object);
+ template<typename T>
+ status_t loadWithFallback(const T& configSource);
status_t setDefaultDevice(audio_devices_t device);
diff --git a/services/audiopolicy/fuzzer/Android.bp b/services/audiopolicy/fuzzer/Android.bp
index 621f643..c4b3751 100644
--- a/services/audiopolicy/fuzzer/Android.bp
+++ b/services/audiopolicy/fuzzer/Android.bp
@@ -38,6 +38,7 @@
"capture_state_listener-aidl-cpp",
"libaudioclient",
"libaudiofoundation",
+ "libaudiopolicycomponents",
"libbase",
"libcutils",
"libhidlbase",
@@ -54,7 +55,6 @@
],
static_libs: [
"android.hardware.audio.common@7.0-enums",
- "libaudiopolicycomponents",
],
header_libs: [
"libaudiopolicycommon",
diff --git a/services/audiopolicy/managerdefault/Android.bp b/services/audiopolicy/managerdefault/Android.bp
index 6e34eb0..a1785da 100644
--- a/services/audiopolicy/managerdefault/Android.bp
+++ b/services/audiopolicy/managerdefault/Android.bp
@@ -23,6 +23,7 @@
shared_libs: [
"libaudiofoundation",
+ "libaudiopolicycomponents",
"libcutils",
"libdl",
"libutils",
@@ -49,8 +50,6 @@
"libaudiopolicymanager_interface_headers",
],
- static_libs: ["libaudiopolicycomponents"],
-
cflags: [
"-Wall",
"-Werror",
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index f093e68..3f2b196 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -1293,7 +1293,8 @@
if (outputDevices.size() == 1) {
info = getPreferredMixerAttributesInfo(
outputDevices.itemAt(0)->getId(),
- mEngine->getProductStrategyForAttributes(*resultAttr));
+ mEngine->getProductStrategyForAttributes(*resultAttr),
+ true /*activeBitPerfectPreferred*/);
// Only use preferred mixer if the uid matches or the preferred mixer is bit-perfect
// and it is currently active.
if (info != nullptr && info->getUid() != uid &&
@@ -2147,6 +2148,26 @@
return DEAD_OBJECT;
}
info->increaseActiveClient();
+ if (info->getActiveClientCount() == 1 &&
+ (info->getFlags() & AUDIO_OUTPUT_FLAG_BIT_PERFECT) != AUDIO_OUTPUT_FLAG_NONE) {
+ // If it is first bit-perfect client, reroute all clients that will be routed to
+ // the bit-perfect sink so that it is guaranteed only bit-perfect stream is active.
+ PortHandleVector clientsToInvalidate;
+ for (size_t i = 0; i < mOutputs.size(); i++) {
+ if (mOutputs[i] == outputDesc ||
+ !mOutputs[i]->devices().filter(outputDesc->devices()).isEmpty()) {
+ continue;
+ }
+ for (const auto& c : mOutputs[i]->getClientIterable()) {
+ clientsToInvalidate.push_back(c->portId());
+ }
+ }
+ if (!clientsToInvalidate.empty()) {
+ ALOGD("%s Invalidate clients due to first bit-perfect client started",
+ __func__);
+ mpClientInterface->invalidateTracks(clientsToInvalidate);
+ }
+ }
}
}
@@ -3782,6 +3803,44 @@
return true;
}
+void AudioPolicyManager::changeOutputDevicesMuteState(
+ const AudioDeviceTypeAddrVector& devices) {
+ ALOGVV("%s() num devices %zu", __func__, devices.size());
+
+ std::vector<sp<SwAudioOutputDescriptor>> outputs =
+ getSoftwareOutputsForDevices(devices);
+
+ for (size_t i = 0; i < outputs.size(); i++) {
+ sp<SwAudioOutputDescriptor> outputDesc = outputs[i];
+ DeviceVector prevDevices = outputDesc->devices();
+ checkDeviceMuteStrategies(outputDesc, prevDevices, 0 /* delayMs */);
+ }
+}
+
+std::vector<sp<SwAudioOutputDescriptor>> AudioPolicyManager::getSoftwareOutputsForDevices(
+ const AudioDeviceTypeAddrVector& devices) const
+{
+ std::vector<sp<SwAudioOutputDescriptor>> outputs;
+ DeviceVector deviceDescriptors;
+ for (size_t j = 0; j < devices.size(); j++) {
+ sp<DeviceDescriptor> desc = mHwModules.getDeviceDescriptor(
+ devices[j].mType, devices[j].getAddress(), String8(), AUDIO_FORMAT_DEFAULT);
+ if (desc == nullptr || !audio_is_output_device(devices[j].mType)) {
+ ALOGE("%s: device type %#x address %s not supported or not an output device",
+ __func__, devices[j].mType, devices[j].getAddress());
+ continue;
+ }
+ deviceDescriptors.add(desc);
+ }
+ for (size_t i = 0; i < mOutputs.size(); i++) {
+ if (!mOutputs.valueAt(i)->supportsAtLeastOne(deviceDescriptors)) {
+ continue;
+ }
+ outputs.push_back(mOutputs.valueAt(i));
+ }
+ return outputs;
+}
+
status_t AudioPolicyManager::setUidDeviceAffinities(uid_t uid,
const AudioDeviceTypeAddrVector& devices) {
ALOGV("%s() uid=%d num devices %zu", __FUNCTION__, uid, devices.size());
@@ -3848,7 +3907,8 @@
return NO_ERROR;
}
-void AudioPolicyManager::updateCallAndOutputRouting(bool forceVolumeReeval, uint32_t delayMs)
+void AudioPolicyManager::updateCallAndOutputRouting(bool forceVolumeReeval, uint32_t delayMs,
+ bool skipDelays)
{
uint32_t waitMs = 0;
bool wasLeUnicastActive = isLeUnicastActive();
@@ -3874,8 +3934,8 @@
continue;
}
waitMs = setOutputDevices(outputDesc, newDevices, forceRouting, delayMs, nullptr,
- true /*requiresMuteCheck*/,
- !forceRouting /*requiresVolumeCheck*/);
+ !skipDelays /*requiresMuteCheck*/,
+ !forceRouting /*requiresVolumeCheck*/, skipDelays);
// Only apply special touch sound delay once
delayMs = 0;
}
@@ -4060,13 +4120,18 @@
// reevaluate outputs for all devices
checkForDeviceAndOutputChanges();
- updateCallAndOutputRouting();
+ changeOutputDevicesMuteState(devices);
+ updateCallAndOutputRouting(false /* forceVolumeReeval */, 0 /* delayMs */,
+ true /* skipDelays */);
+ changeOutputDevicesMuteState(devices);
return NO_ERROR;
}
status_t AudioPolicyManager::removeUserIdDeviceAffinities(int userId) {
ALOGV("%s() userId=%d", __FUNCTION__, userId);
+ AudioDeviceTypeAddrVector devices;
+ mPolicyMixes.getDevicesForUserId(userId, devices);
status_t status = mPolicyMixes.removeUserIdDeviceAffinities(userId);
if (status != NO_ERROR) {
ALOGE("%s() Could not remove all device affinities fo userId = %d",
@@ -4076,7 +4141,10 @@
// reevaluate outputs for all devices
checkForDeviceAndOutputChanges();
- updateCallAndOutputRouting();
+ changeOutputDevicesMuteState(devices);
+ updateCallAndOutputRouting(false /* forceVolumeReeval */, 0 /* delayMs */,
+ true /* skipDelays */);
+ changeOutputDevicesMuteState(devices);
return NO_ERROR;
}
@@ -4485,16 +4553,24 @@
}
sp<PreferredMixerAttributesInfo> AudioPolicyManager::getPreferredMixerAttributesInfo(
- audio_port_handle_t devicePortId, product_strategy_t strategy) {
+ audio_port_handle_t devicePortId,
+ product_strategy_t strategy,
+ bool activeBitPerfectPreferred) {
auto it = mPreferredMixerAttrInfos.find(devicePortId);
if (it == mPreferredMixerAttrInfos.end()) {
return nullptr;
}
- auto mixerAttrInfoIt = it->second.find(strategy);
- if (mixerAttrInfoIt == it->second.end()) {
- return nullptr;
+ if (activeBitPerfectPreferred) {
+ for (auto [strategy, info] : it->second) {
+ if ((info->getFlags() & AUDIO_OUTPUT_FLAG_BIT_PERFECT) != AUDIO_OUTPUT_FLAG_NONE
+ && info->getActiveClientCount() != 0) {
+ return info;
+ }
+ }
}
- return mixerAttrInfoIt->second;
+ auto strategyMatchedMixerAttrInfoIt = it->second.find(strategy);
+ return strategyMatchedMixerAttrInfoIt == it->second.end()
+ ? nullptr : strategyMatchedMixerAttrInfoIt->second;
}
status_t AudioPolicyManager::getPreferredMixerAttributes(
@@ -7315,7 +7391,8 @@
bool force,
int delayMs,
audio_patch_handle_t *patchHandle,
- bool requiresMuteCheck, bool requiresVolumeCheck)
+ bool requiresMuteCheck, bool requiresVolumeCheck,
+ bool skipMuteDelay)
{
// TODO(b/262404095): Consider if the output need to be reopened.
ALOGV("%s device %s delayMs %d", __func__, devices.toString().c_str(), delayMs);
@@ -7323,9 +7400,9 @@
if (outputDesc->isDuplicated()) {
muteWaitMs = setOutputDevices(outputDesc->subOutput1(), devices, force, delayMs,
- nullptr /* patchHandle */, requiresMuteCheck);
+ nullptr /* patchHandle */, requiresMuteCheck, skipMuteDelay);
muteWaitMs += setOutputDevices(outputDesc->subOutput2(), devices, force, delayMs,
- nullptr /* patchHandle */, requiresMuteCheck);
+ nullptr /* patchHandle */, requiresMuteCheck, skipMuteDelay);
return muteWaitMs;
}
@@ -7391,12 +7468,16 @@
// Add half reported latency to delayMs when muteWaitMs is null in order
// to avoid disordered sequence of muting volume and changing devices.
- installPatch(__func__, patchHandle, outputDesc.get(), patchBuilder.patch(),
- muteWaitMs == 0 ? (delayMs + (outputDesc->latency() / 2)) : delayMs);
+ int actualDelayMs = !skipMuteDelay && muteWaitMs == 0
+ ? (delayMs + (outputDesc->latency() / 2)) : delayMs;
+ installPatch(__func__, patchHandle, outputDesc.get(), patchBuilder.patch(), actualDelayMs);
}
- // update stream volumes according to new device
- applyStreamVolumes(outputDesc, filteredDevices.types(), delayMs);
+ // Since the mute is skip, also skip the apply stream volume as that will be applied externally
+ if (!skipMuteDelay) {
+ // update stream volumes according to new device
+ applyStreamVolumes(outputDesc, filteredDevices.types(), delayMs);
+ }
return muteWaitMs;
}
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 88bafef..863c785 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -535,8 +535,9 @@
* and currently active, allow to have proper drain and avoid pops
* @param requiresVolumeCheck true if called requires to reapply volume if the routing did
* not change (but the output is still routed).
+ * @param skipMuteDelay if true will skip mute delay when installing audio patch
* @return the number of ms we have slept to allow new routing to take effect in certain
- * cases.
+ * cases.
*/
uint32_t setOutputDevices(const sp<SwAudioOutputDescriptor>& outputDesc,
const DeviceVector &device,
@@ -544,7 +545,8 @@
int delayMs = 0,
audio_patch_handle_t *patchHandle = NULL,
bool requiresMuteCheck = true,
- bool requiresVolumeCheck = false);
+ bool requiresVolumeCheck = false,
+ bool skipMuteDelay = false);
status_t resetOutputDevice(const sp<AudioOutputDescriptor>& outputDesc,
int delayMs = 0,
audio_patch_handle_t *patchHandle = NULL);
@@ -647,8 +649,10 @@
/**
* @brief updates routing for all outputs (including call if call in progress).
* @param delayMs delay for unmuting if required
+ * @param skipDelays if true all the delays will be skip while updating routing
*/
- void updateCallAndOutputRouting(bool forceVolumeReeval = true, uint32_t delayMs = 0);
+ void updateCallAndOutputRouting(bool forceVolumeReeval = true, uint32_t delayMs = 0,
+ bool skipDelays = false);
bool isCallRxAudioSource(const sp<SourceClientDescriptor> &source) {
return mCallRxSourceClient != nullptr && source == mCallRxSourceClient;
@@ -1241,6 +1245,21 @@
const char* context,
bool matchAddress = true);
+ /**
+ * @brief changeOutputDevicesMuteState mute/unmute devices using checkDeviceMuteStrategies
+ * @param devices devices to mute/unmute
+ */
+ void changeOutputDevicesMuteState(const AudioDeviceTypeAddrVector& devices);
+
+ /**
+ * @brief Returns a vector of software output descriptor that support the queried devices
+ * @param devices devices to query
+ * @param openOutputs open outputs where the devices are supported as determined by
+ * SwAudioOutputDescriptor::supportsAtLeastOne
+ */
+ std::vector<sp<SwAudioOutputDescriptor>> getSoftwareOutputsForDevices(
+ const AudioDeviceTypeAddrVector& devices) const;
+
bool isScoRequestedForComm() const;
bool isHearingAidUsedForComm() const;
@@ -1298,8 +1317,15 @@
uint32_t flags,
bool isInput);
+ /**
+ * Returns the preferred mixer attributes info for the given device port id and strategy.
+ * Bit-perfect mixer attributes will be returned if it is active and
+ * `activeBitPerfectPreferred` is true.
+ */
sp<PreferredMixerAttributesInfo> getPreferredMixerAttributesInfo(
- audio_port_handle_t devicePortId, product_strategy_t strategy);
+ audio_port_handle_t devicePortId,
+ product_strategy_t strategy,
+ bool activeBitPerfectPreferred = false);
sp<SwAudioOutputDescriptor> reopenOutput(
sp<SwAudioOutputDescriptor> outputDesc,
diff --git a/services/audiopolicy/managerdefault/EngineLibrary.cpp b/services/audiopolicy/managerdefault/EngineLibrary.cpp
index 939fbc5..ab77941 100644
--- a/services/audiopolicy/managerdefault/EngineLibrary.cpp
+++ b/services/audiopolicy/managerdefault/EngineLibrary.cpp
@@ -40,6 +40,23 @@
return engine;
}
+EngineInstance loadApmEngineLibraryAndCreateEngine(const std::string& librarySuffix,
+ const media::audio::common::AudioHalEngineConfig& config)
+{
+ auto engLib = EngineLibrary::load(librarySuffix);
+ if (!engLib) {
+ ALOGE("%s: Failed to load the engine library, suffix \"%s\"",
+ __func__, librarySuffix.c_str());
+ return nullptr;
+ }
+ auto engine = engLib->createEngineUsingHalConfig(config);
+ if (engine == nullptr) {
+ ALOGE("%s: Failed to instantiate the APM engine", __func__);
+ return nullptr;
+ }
+ return engine;
+}
+
// static
std::shared_ptr<EngineLibrary> EngineLibrary::load(const std::string& librarySuffix)
{
@@ -53,7 +70,8 @@
close();
}
-EngineInstance EngineLibrary::createEngineUsingXmlConfig(const std::string& xmlFilePath) {
+EngineInstance EngineLibrary::createEngineUsingXmlConfig(const std::string& xmlFilePath)
+{
auto instance = createEngine();
if (instance != nullptr) {
if (status_t status = instance->loadFromXmlConfigWithFallback(xmlFilePath);
@@ -67,6 +85,21 @@
return nullptr;
}
+EngineInstance EngineLibrary::createEngineUsingHalConfig(
+ const media::audio::common::AudioHalEngineConfig& config)
+{
+ auto instance = createEngine();
+ if (instance != nullptr) {
+ if (status_t status = instance->loadFromHalConfigWithFallback(config); status == OK) {
+ return instance;
+ } else {
+ ALOGE("%s: loading of the engine config with HAL configuration \"%s\" failed: %d",
+ __func__, config.toString().c_str(), status);
+ }
+ }
+ return nullptr;
+}
+
bool EngineLibrary::init(std::string libraryPath)
{
mLibraryHandle = dlopen(libraryPath.c_str(), 0);
diff --git a/services/audiopolicy/managerdefault/EngineLibrary.h b/services/audiopolicy/managerdefault/EngineLibrary.h
index dc138a1..4710e34 100644
--- a/services/audiopolicy/managerdefault/EngineLibrary.h
+++ b/services/audiopolicy/managerdefault/EngineLibrary.h
@@ -21,6 +21,7 @@
#include <string>
#include <EngineInterface.h>
+#include <android/media/audio/common/AudioHalEngineConfig.h>
namespace android {
@@ -28,6 +29,8 @@
EngineInstance loadApmEngineLibraryAndCreateEngine(const std::string& librarySuffix,
const std::string& configXmlFilePath = "");
+EngineInstance loadApmEngineLibraryAndCreateEngine(const std::string& librarySuffix,
+ const media::audio::common::AudioHalEngineConfig& config);
class EngineLibrary : public std::enable_shared_from_this<EngineLibrary> {
public:
@@ -40,6 +43,8 @@
EngineLibrary& operator=(EngineLibrary&&) = delete;
EngineInstance createEngineUsingXmlConfig(const std::string& xmlFilePath);
+ EngineInstance createEngineUsingHalConfig(
+ const media::audio::common::AudioHalEngineConfig& config);
private:
EngineLibrary() = default;
diff --git a/services/audiopolicy/service/Android.bp b/services/audiopolicy/service/Android.bp
index 2f677da..f4fc8f1 100644
--- a/services/audiopolicy/service/Android.bp
+++ b/services/audiopolicy/service/Android.bp
@@ -35,6 +35,7 @@
"libaudiofoundation",
"libaudiohal",
"libaudiopolicy",
+ "libaudiopolicycomponents",
"libaudiopolicymanagerdefault",
"libaudiousecasevalidation",
"libaudioutils",
@@ -66,7 +67,6 @@
],
static_libs: [
- "libaudiopolicycomponents",
"framework-permission-aidl-cpp",
],
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 2e7b3ff..5d86e7c 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -318,7 +318,7 @@
return Status::ok();
}
-Status AudioPolicyService::getOutputForAttr(const media::AudioAttributesInternal& attrAidl,
+Status AudioPolicyService::getOutputForAttr(const media::audio::common::AudioAttributes& attrAidl,
int32_t sessionAidl,
const AttributionSourceState& attributionSource,
const AudioConfig& configAidl,
@@ -327,7 +327,7 @@
media::GetOutputForAttrResponse* _aidl_return)
{
audio_attributes_t attr = VALUE_OR_RETURN_BINDER_STATUS(
- aidl2legacy_AudioAttributesInternal_audio_attributes_t(attrAidl));
+ aidl2legacy_AudioAttributes_audio_attributes_t(attrAidl));
audio_session_t session = VALUE_OR_RETURN_BINDER_STATUS(
aidl2legacy_int32_t_audio_session_t(sessionAidl));
audio_stream_type_t stream = AUDIO_STREAM_DEFAULT;
@@ -440,7 +440,7 @@
_aidl_return->isSpatialized = isSpatialized;
_aidl_return->isBitPerfect = isBitPerfect;
_aidl_return->attr = VALUE_OR_RETURN_BINDER_STATUS(
- legacy2aidl_audio_attributes_t_AudioAttributesInternal(attr));
+ legacy2aidl_audio_attributes_t_AudioAttributes(attr));
} else {
_aidl_return->configBase.format = VALUE_OR_RETURN_BINDER_STATUS(
legacy2aidl_audio_format_t_AudioFormatDescription(config.format));
@@ -575,7 +575,7 @@
mAudioPolicyManager->releaseOutput(portId);
}
-Status AudioPolicyService::getInputForAttr(const media::AudioAttributesInternal& attrAidl,
+Status AudioPolicyService::getInputForAttr(const media::audio::common::AudioAttributes& attrAidl,
int32_t inputAidl,
int32_t riidAidl,
int32_t sessionAidl,
@@ -585,7 +585,7 @@
int32_t selectedDeviceIdAidl,
media::GetInputForAttrResponse* _aidl_return) {
audio_attributes_t attr = VALUE_OR_RETURN_BINDER_STATUS(
- aidl2legacy_AudioAttributesInternal_audio_attributes_t(attrAidl));
+ aidl2legacy_AudioAttributes_audio_attributes_t(attrAidl));
audio_io_handle_t input = VALUE_OR_RETURN_BINDER_STATUS(
aidl2legacy_int32_t_audio_io_handle_t(inputAidl));
audio_unique_id_t riid = VALUE_OR_RETURN_BINDER_STATUS(
@@ -1073,10 +1073,10 @@
}
Status AudioPolicyService::setVolumeIndexForAttributes(
- const media::AudioAttributesInternal& attrAidl,
+ const media::audio::common::AudioAttributes& attrAidl,
const AudioDeviceDescription& deviceAidl, int32_t indexAidl) {
audio_attributes_t attributes = VALUE_OR_RETURN_BINDER_STATUS(
- aidl2legacy_AudioAttributesInternal_audio_attributes_t(attrAidl));
+ aidl2legacy_AudioAttributes_audio_attributes_t(attrAidl));
int index = VALUE_OR_RETURN_BINDER_STATUS(convertIntegral<int>(indexAidl));
audio_devices_t device = VALUE_OR_RETURN_BINDER_STATUS(
aidl2legacy_AudioDeviceDescription_audio_devices_t(deviceAidl));
@@ -1096,10 +1096,10 @@
}
Status AudioPolicyService::getVolumeIndexForAttributes(
- const media::AudioAttributesInternal& attrAidl,
+ const media::audio::common::AudioAttributes& attrAidl,
const AudioDeviceDescription& deviceAidl, int32_t* _aidl_return) {
audio_attributes_t attributes = VALUE_OR_RETURN_BINDER_STATUS(
- aidl2legacy_AudioAttributesInternal_audio_attributes_t(attrAidl));
+ aidl2legacy_AudioAttributes_audio_attributes_t(attrAidl));
audio_devices_t device = VALUE_OR_RETURN_BINDER_STATUS(
aidl2legacy_AudioDeviceDescription_audio_devices_t(deviceAidl));
int index;
@@ -1118,9 +1118,9 @@
}
Status AudioPolicyService::getMinVolumeIndexForAttributes(
- const media::AudioAttributesInternal& attrAidl, int32_t* _aidl_return) {
+ const media::audio::common::AudioAttributes& attrAidl, int32_t* _aidl_return) {
audio_attributes_t attributes = VALUE_OR_RETURN_BINDER_STATUS(
- aidl2legacy_AudioAttributesInternal_audio_attributes_t(attrAidl));
+ aidl2legacy_AudioAttributes_audio_attributes_t(attrAidl));
int index;
RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(
AudioValidator::validateAudioAttributes(attributes, "169572641")));
@@ -1137,9 +1137,9 @@
}
Status AudioPolicyService::getMaxVolumeIndexForAttributes(
- const media::AudioAttributesInternal& attrAidl, int32_t* _aidl_return) {
+ const media::audio::common::AudioAttributes& attrAidl, int32_t* _aidl_return) {
audio_attributes_t attributes = VALUE_OR_RETURN_BINDER_STATUS(
- aidl2legacy_AudioAttributesInternal_audio_attributes_t(attrAidl));
+ aidl2legacy_AudioAttributes_audio_attributes_t(attrAidl));
int index;
RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(
AudioValidator::validateAudioAttributes(attributes, "169572641")));
@@ -1177,12 +1177,13 @@
return Status::ok();
}
-Status AudioPolicyService::getDevicesForAttributes(const media::AudioAttributesInternal& attrAidl,
- bool forVolume,
- std::vector<AudioDevice>* _aidl_return)
+Status AudioPolicyService::getDevicesForAttributes(
+ const media::audio::common::AudioAttributes& attrAidl,
+ bool forVolume,
+ std::vector<AudioDevice>* _aidl_return)
{
audio_attributes_t aa = VALUE_OR_RETURN_BINDER_STATUS(
- aidl2legacy_AudioAttributesInternal_audio_attributes_t(attrAidl));
+ aidl2legacy_AudioAttributes_audio_attributes_t(attrAidl));
AudioDeviceTypeAddrVector devices;
if (mAudioPolicyManager == NULL) {
@@ -1507,12 +1508,12 @@
Status AudioPolicyService::isDirectOutputSupported(
const AudioConfigBase& configAidl,
- const media::AudioAttributesInternal& attributesAidl,
+ const media::audio::common::AudioAttributes& attributesAidl,
bool* _aidl_return) {
audio_config_base_t config = VALUE_OR_RETURN_BINDER_STATUS(
aidl2legacy_AudioConfigBase_audio_config_base_t(configAidl, false /*isInput*/));
audio_attributes_t attributes = VALUE_OR_RETURN_BINDER_STATUS(
- aidl2legacy_AudioAttributesInternal_audio_attributes_t(attributesAidl));
+ aidl2legacy_AudioAttributes_audio_attributes_t(attributesAidl));
RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(
AudioValidator::validateAudioAttributes(attributes, "169572641")));
@@ -1829,12 +1830,12 @@
}
Status AudioPolicyService::startAudioSource(const media::AudioPortConfigFw& sourceAidl,
- const media::AudioAttributesInternal& attributesAidl,
- int32_t* _aidl_return) {
+ const media::audio::common::AudioAttributes& attributesAidl,
+ int32_t* _aidl_return) {
audio_port_config source = VALUE_OR_RETURN_BINDER_STATUS(
aidl2legacy_AudioPortConfigFw_audio_port_config(sourceAidl));
audio_attributes_t attributes = VALUE_OR_RETURN_BINDER_STATUS(
- aidl2legacy_AudioAttributesInternal_audio_attributes_t(attributesAidl));
+ aidl2legacy_AudioAttributes_audio_attributes_t(attributesAidl));
audio_port_handle_t portId;
RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(
AudioValidator::validateAudioPortConfig(source)));
@@ -2107,10 +2108,10 @@
}
Status AudioPolicyService::getProductStrategyFromAudioAttributes(
- const media::AudioAttributesInternal& aaAidl,
+ const media::audio::common::AudioAttributes& aaAidl,
bool fallbackOnDefault, int32_t* _aidl_return) {
audio_attributes_t aa = VALUE_OR_RETURN_BINDER_STATUS(
- aidl2legacy_AudioAttributesInternal_audio_attributes_t(aaAidl));
+ aidl2legacy_AudioAttributes_audio_attributes_t(aaAidl));
product_strategy_t productStrategy;
if (mAudioPolicyManager == NULL) {
@@ -2141,10 +2142,10 @@
}
Status AudioPolicyService::getVolumeGroupFromAudioAttributes(
- const media::AudioAttributesInternal& aaAidl,
+ const media::audio::common::AudioAttributes& aaAidl,
bool fallbackOnDefault, int32_t* _aidl_return) {
audio_attributes_t aa = VALUE_OR_RETURN_BINDER_STATUS(
- aidl2legacy_AudioAttributesInternal_audio_attributes_t(aaAidl));
+ aidl2legacy_AudioAttributes_audio_attributes_t(aaAidl));
volume_group_t volumeGroup;
if (mAudioPolicyManager == NULL) {
@@ -2381,7 +2382,7 @@
}
Status AudioPolicyService::canBeSpatialized(
- const std::optional<media::AudioAttributesInternal>& attrAidl,
+ const std::optional<media::audio::common::AudioAttributes>& attrAidl,
const std::optional<AudioConfig>& configAidl,
const std::vector<AudioDevice>& devicesAidl,
bool* _aidl_return) {
@@ -2391,7 +2392,7 @@
audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER;
if (attrAidl.has_value()) {
attr = VALUE_OR_RETURN_BINDER_STATUS(
- aidl2legacy_AudioAttributesInternal_audio_attributes_t(attrAidl.value()));
+ aidl2legacy_AudioAttributes_audio_attributes_t(attrAidl.value()));
}
audio_config_t config = AUDIO_CONFIG_INITIALIZER;
if (configAidl.has_value()) {
@@ -2408,9 +2409,10 @@
return Status::ok();
}
-Status AudioPolicyService::getDirectPlaybackSupport(const media::AudioAttributesInternal &attrAidl,
- const AudioConfig &configAidl,
- media::AudioDirectMode *_aidl_return) {
+Status AudioPolicyService::getDirectPlaybackSupport(
+ const media::audio::common::AudioAttributes &attrAidl,
+ const AudioConfig &configAidl,
+ media::AudioDirectMode *_aidl_return) {
if (mAudioPolicyManager == nullptr) {
return binderStatusFromStatusT(NO_INIT);
}
@@ -2418,7 +2420,7 @@
return binderStatusFromStatusT(BAD_VALUE);
}
audio_attributes_t attr = VALUE_OR_RETURN_BINDER_STATUS(
- aidl2legacy_AudioAttributesInternal_audio_attributes_t(attrAidl));
+ aidl2legacy_AudioAttributes_audio_attributes_t(attrAidl));
audio_config_t config = VALUE_OR_RETURN_BINDER_STATUS(
aidl2legacy_AudioConfig_audio_config_t(configAidl, false /*isInput*/));
Mutex::Autolock _l(mLock);
@@ -2429,13 +2431,13 @@
}
Status AudioPolicyService::getDirectProfilesForAttributes(
- const media::AudioAttributesInternal& attrAidl,
+ const media::audio::common::AudioAttributes& attrAidl,
std::vector<media::audio::common::AudioProfile>* _aidl_return) {
if (mAudioPolicyManager == nullptr) {
return binderStatusFromStatusT(NO_INIT);
}
audio_attributes_t attr = VALUE_OR_RETURN_BINDER_STATUS(
- aidl2legacy_AudioAttributesInternal_audio_attributes_t(attrAidl));
+ aidl2legacy_AudioAttributes_audio_attributes_t(attrAidl));
AudioProfileVector audioProfiles;
Mutex::Autolock _l(mLock);
@@ -2470,7 +2472,7 @@
}
Status AudioPolicyService::setPreferredMixerAttributes(
- const media::AudioAttributesInternal& attrAidl,
+ const media::audio::common::AudioAttributes& attrAidl,
int32_t portIdAidl,
int32_t uidAidl,
const media::AudioMixerAttributesInternal& mixerAttrAidl) {
@@ -2479,7 +2481,7 @@
}
audio_attributes_t attr = VALUE_OR_RETURN_BINDER_STATUS(
- aidl2legacy_AudioAttributesInternal_audio_attributes_t(attrAidl));
+ aidl2legacy_AudioAttributes_audio_attributes_t(attrAidl));
audio_mixer_attributes_t mixerAttr = VALUE_OR_RETURN_BINDER_STATUS(
aidl2legacy_AudioMixerAttributesInternal_audio_mixer_attributes_t(mixerAttrAidl));
uid_t uid = VALUE_OR_RETURN_BINDER_STATUS(aidl2legacy_int32_t_uid_t(uidAidl));
@@ -2492,7 +2494,7 @@
}
Status AudioPolicyService::getPreferredMixerAttributes(
- const media::AudioAttributesInternal& attrAidl,
+ const media::audio::common::AudioAttributes& attrAidl,
int32_t portIdAidl,
std::optional<media::AudioMixerAttributesInternal>* _aidl_return) {
if (mAudioPolicyManager == nullptr) {
@@ -2500,7 +2502,7 @@
}
audio_attributes_t attr = VALUE_OR_RETURN_BINDER_STATUS(
- aidl2legacy_AudioAttributesInternal_audio_attributes_t(attrAidl));
+ aidl2legacy_AudioAttributes_audio_attributes_t(attrAidl));
audio_port_handle_t portId = VALUE_OR_RETURN_BINDER_STATUS(
aidl2legacy_int32_t_audio_port_handle_t(portIdAidl));
@@ -2515,7 +2517,7 @@
}
Status AudioPolicyService::clearPreferredMixerAttributes(
- const media::AudioAttributesInternal& attrAidl,
+ const media::audio::common::AudioAttributes& attrAidl,
int32_t portIdAidl,
int32_t uidAidl) {
if (mAudioPolicyManager == nullptr) {
@@ -2523,7 +2525,7 @@
}
audio_attributes_t attr = VALUE_OR_RETURN_BINDER_STATUS(
- aidl2legacy_AudioAttributesInternal_audio_attributes_t(attrAidl));
+ aidl2legacy_AudioAttributes_audio_attributes_t(attrAidl));
uid_t uid = VALUE_OR_RETURN_BINDER_STATUS(aidl2legacy_int32_t_uid_t(uidAidl));
audio_port_handle_t portId = VALUE_OR_RETURN_BINDER_STATUS(
aidl2legacy_int32_t_audio_port_handle_t(portIdAidl));
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index df0c59f..5d22ed4 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -186,10 +186,23 @@
static AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface)
{
- auto config = AudioPolicyConfig::loadFromApmXmlConfigWithFallback(); // This can't fail.
- AudioPolicyManager *apm = new AudioPolicyManager(
- config, loadApmEngineLibraryAndCreateEngine(config->getEngineLibraryNameSuffix()),
- clientInterface);
+ AudioPolicyManager *apm = nullptr;
+ media::AudioPolicyConfig apmConfig;
+ if (status_t status = clientInterface->getAudioPolicyConfig(&apmConfig); status == OK) {
+ auto config = AudioPolicyConfig::loadFromApmAidlConfigWithFallback(apmConfig);
+ LOG_ALWAYS_FATAL_IF(config->getEngineLibraryNameSuffix() !=
+ AudioPolicyConfig::kDefaultEngineLibraryNameSuffix,
+ "Only default engine is currently supported with the AIDL HAL");
+ apm = new AudioPolicyManager(config,
+ loadApmEngineLibraryAndCreateEngine(
+ config->getEngineLibraryNameSuffix(), apmConfig.engineConfig),
+ clientInterface);
+ } else {
+ auto config = AudioPolicyConfig::loadFromApmXmlConfigWithFallback(); // This can't fail.
+ apm = new AudioPolicyManager(config,
+ loadApmEngineLibraryAndCreateEngine(config->getEngineLibraryNameSuffix()),
+ clientInterface);
+ }
status_t status = apm->initialize();
if (status != NO_ERROR) {
delete apm;
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 4710a8a..d0cde64 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -98,7 +98,8 @@
binder::Status getForceUse(media::AudioPolicyForceUse usage,
media::AudioPolicyForcedConfig* _aidl_return) override;
binder::Status getOutput(AudioStreamType stream, int32_t* _aidl_return) override;
- binder::Status getOutputForAttr(const media::AudioAttributesInternal& attr, int32_t session,
+ binder::Status getOutputForAttr(const media::audio::common::AudioAttributes& attr,
+ int32_t session,
const AttributionSourceState &attributionSource,
const AudioConfig& config,
int32_t flags, int32_t selectedDeviceId,
@@ -106,7 +107,7 @@
binder::Status startOutput(int32_t portId) override;
binder::Status stopOutput(int32_t portId) override;
binder::Status releaseOutput(int32_t portId) override;
- binder::Status getInputForAttr(const media::AudioAttributesInternal& attr, int32_t input,
+ binder::Status getInputForAttr(const media::audio::common::AudioAttributes& attr, int32_t input,
int32_t riid, int32_t session,
const AttributionSourceState &attributionSource,
const AudioConfigBase& config, int32_t flags,
@@ -123,19 +124,19 @@
binder::Status getStreamVolumeIndex(AudioStreamType stream,
const AudioDeviceDescription& device,
int32_t* _aidl_return) override;
- binder::Status setVolumeIndexForAttributes(const media::AudioAttributesInternal& attr,
+ binder::Status setVolumeIndexForAttributes(const media::audio::common::AudioAttributes& attr,
const AudioDeviceDescription& device,
int32_t index) override;
- binder::Status getVolumeIndexForAttributes(const media::AudioAttributesInternal& attr,
+ binder::Status getVolumeIndexForAttributes(const media::audio::common::AudioAttributes& attr,
const AudioDeviceDescription& device,
int32_t* _aidl_return) override;
- binder::Status getMaxVolumeIndexForAttributes(const media::AudioAttributesInternal& attr,
+ binder::Status getMaxVolumeIndexForAttributes(const media::audio::common::AudioAttributes& attr,
int32_t* _aidl_return) override;
- binder::Status getMinVolumeIndexForAttributes(const media::AudioAttributesInternal& attr,
+ binder::Status getMinVolumeIndexForAttributes(const media::audio::common::AudioAttributes& attr,
int32_t* _aidl_return) override;
binder::Status getStrategyForStream(AudioStreamType stream,
int32_t* _aidl_return) override;
- binder::Status getDevicesForAttributes(const media::AudioAttributesInternal& attr,
+ binder::Status getDevicesForAttributes(const media::audio::common::AudioAttributes& attr,
bool forVolume,
std::vector<AudioDevice>* _aidl_return) override;
binder::Status getOutputForEffect(const media::EffectDescriptor& desc,
@@ -170,7 +171,7 @@
binder::Status getOffloadSupport(const media::audio::common::AudioOffloadInfo& info,
media::AudioOffloadMode* _aidl_return) override;
binder::Status isDirectOutputSupported(const AudioConfigBase& config,
- const media::AudioAttributesInternal& attributes,
+ const media::audio::common::AudioAttributes& attributes,
bool* _aidl_return) override;
binder::Status listAudioPorts(media::AudioPortRole role, media::AudioPortType type,
Int* count, std::vector<media::AudioPortFw>* ports,
@@ -201,7 +202,7 @@
const std::vector<AudioDevice>& devices) override;
binder::Status removeUserIdDeviceAffinities(int32_t userId) override;
binder::Status startAudioSource(const media::AudioPortConfigFw& source,
- const media::AudioAttributesInternal& attributes,
+ const media::audio::common::AudioAttributes& attributes,
int32_t* _aidl_return) override;
binder::Status stopAudioSource(int32_t portId) override;
binder::Status setMasterMono(bool mono) override;
@@ -228,14 +229,16 @@
binder::Status isHotwordStreamSupported(bool lookbackAudio, bool* _aidl_return) override;
binder::Status listAudioProductStrategies(
std::vector<media::AudioProductStrategy>* _aidl_return) override;
- binder::Status getProductStrategyFromAudioAttributes(const media::AudioAttributesInternal& aa,
- bool fallbackOnDefault,
- int32_t* _aidl_return) override;
+ binder::Status getProductStrategyFromAudioAttributes(
+ const media::audio::common::AudioAttributes& aa,
+ bool fallbackOnDefault,
+ int32_t* _aidl_return) override;
binder::Status listAudioVolumeGroups(
std::vector<media::AudioVolumeGroup>* _aidl_return) override;
- binder::Status getVolumeGroupFromAudioAttributes(const media::AudioAttributesInternal& aa,
- bool fallbackOnDefault,
- int32_t* _aidl_return) override;
+ binder::Status getVolumeGroupFromAudioAttributes(
+ const media::audio::common::AudioAttributes& aa,
+ bool fallbackOnDefault,
+ int32_t* _aidl_return) override;
binder::Status setRttEnabled(bool enabled) override;
binder::Status isCallScreenModeSupported(bool* _aidl_return) override;
binder::Status setDevicesRoleForStrategy(
@@ -274,31 +277,31 @@
binder::Status getSpatializer(const sp<media::INativeSpatializerCallback>& callback,
media::GetSpatializerResponse* _aidl_return) override;
binder::Status canBeSpatialized(
- const std::optional<media::AudioAttributesInternal>& attr,
+ const std::optional<media::audio::common::AudioAttributes>& attr,
const std::optional<AudioConfig>& config,
const std::vector<AudioDevice>& devices,
bool* _aidl_return) override;
- binder::Status getDirectPlaybackSupport(const media::AudioAttributesInternal& attr,
+ binder::Status getDirectPlaybackSupport(const media::audio::common::AudioAttributes& attr,
const AudioConfig& config,
media::AudioDirectMode* _aidl_return) override;
- binder::Status getDirectProfilesForAttributes(const media::AudioAttributesInternal& attr,
+ binder::Status getDirectProfilesForAttributes(const media::audio::common::AudioAttributes& attr,
std::vector<media::audio::common::AudioProfile>* _aidl_return) override;
binder::Status getSupportedMixerAttributes(
int32_t portId,
std::vector<media::AudioMixerAttributesInternal>* _aidl_return) override;
binder::Status setPreferredMixerAttributes(
- const media::AudioAttributesInternal& attr,
+ const media::audio::common::AudioAttributes& attr,
int32_t portId,
int32_t uid,
const media::AudioMixerAttributesInternal& mixerAttr) override;
binder::Status getPreferredMixerAttributes(
- const media::AudioAttributesInternal& attr,
+ const media::audio::common::AudioAttributes& attr,
int32_t portId,
std::optional<media::AudioMixerAttributesInternal>* _aidl_return) override;
- binder::Status clearPreferredMixerAttributes(const media::AudioAttributesInternal& attr,
+ binder::Status clearPreferredMixerAttributes(const media::audio::common::AudioAttributes& attr,
int32_t portId,
int32_t uid) override;
diff --git a/services/audiopolicy/service/Spatializer.cpp b/services/audiopolicy/service/Spatializer.cpp
index ee2e0eb..1245b1e 100644
--- a/services/audiopolicy/service/Spatializer.cpp
+++ b/services/audiopolicy/service/Spatializer.cpp
@@ -236,18 +236,15 @@
sp<EffectHalInterface> effect;
status = effectsFactoryHal->createEffect(&descriptors[0].uuid, AUDIO_SESSION_OUTPUT_STAGE,
AUDIO_IO_HANDLE_NONE, AUDIO_PORT_HANDLE_NONE, &effect);
- ALOGI("%s FX create status %d effect ID %" PRId64, __func__, status,
- effect ? effect->effectId() : 0);
+ ALOGI("%s FX create status %d effect %p", __func__, status, effect.get());
if (status == NO_ERROR && effect != nullptr) {
spatializer = new Spatializer(descriptors[0], callback);
if (spatializer->loadEngineConfiguration(effect) != NO_ERROR) {
spatializer.clear();
- ALOGW("%s loadEngine error: %d effect Id %" PRId64,
- __func__, status, effect ? effect->effectId() : 0);
+ ALOGW("%s loadEngine error: %d effect %p", __func__, status, effect.get());
} else {
- spatializer->mLocalLog.log("%s with effect Id %" PRId64, __func__,
- effect ? effect->effectId() : 0);
+ spatializer->mLocalLog.log("%s with effect Id %p", __func__, effect.get());
}
}
diff --git a/services/audiopolicy/tests/Android.bp b/services/audiopolicy/tests/Android.bp
index 285b354..a4a0cd4 100644
--- a/services/audiopolicy/tests/Android.bp
+++ b/services/audiopolicy/tests/Android.bp
@@ -78,6 +78,7 @@
"libaudioclient",
"libaudioclient_aidl_conversion",
"libaudiofoundation",
+ "libaudiopolicycomponents",
"libaudiopolicymanagerdefault",
"libcutils",
"liblog",
@@ -89,8 +90,6 @@
"libxml2",
],
- static_libs: ["libaudiopolicycomponents"],
-
header_libs: [
"libaudiopolicyengine_interface_headers",
"libaudiopolicymanager_interface_headers",
diff --git a/services/audiopolicy/tests/audiopolicymanager_tests.cpp b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
index 5e58dbb..15eae14 100644
--- a/services/audiopolicy/tests/audiopolicymanager_tests.cpp
+++ b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
@@ -1232,6 +1232,19 @@
EXPECT_FALSE(isBitPerfect);
EXPECT_EQ(bitPerfectOutput, output);
+ const audio_attributes_t dtmfAttr = {
+ .content_type = AUDIO_CONTENT_TYPE_UNKNOWN,
+ .usage = AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING,
+ };
+ audio_io_handle_t dtmfOutput = AUDIO_IO_HANDLE_NONE;
+ selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ portId = AUDIO_PORT_HANDLE_NONE;
+ getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
+ 48000, AUDIO_OUTPUT_FLAG_NONE, &dtmfOutput, &portId, dtmfAttr,
+ AUDIO_SESSION_NONE, anotherUid, &isBitPerfect);
+ EXPECT_FALSE(isBitPerfect);
+ EXPECT_EQ(bitPerfectOutput, dtmfOutput);
+
// When configuration matches preferred mixer attributes, which is bit-perfect, but the client
// is not the owner of preferred mixer attributes, the playback will not be bit-perfect.
getOutputForAttr(&selectedDeviceId, bitPerfectFormat, bitPerfectChannelMask,