[automerger skipped] Avoid leaking RenderEngine am: 5eb07e3b88 am: 9cbed70311 -s ours
am skip reason: Merged-In Ief71d8931ec3560780a850d8bb8bc727bbff5c52 with SHA-1 64f73a4c5f is already in history
Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/3311018
Change-Id: I58144d977c7e51f7896a394013d7da8dfe671983
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index de7aa35..8c53006 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -5,6 +5,7 @@
bpfmt = true
clang_format = true
aidl_format = true
+gofmt = true
[Hook Scripts]
aosp_hook_confirmationui = ${REPO_ROOT}/frameworks/base/tools/aosp/aosp_sha.sh ${PREUPLOAD_COMMIT} confirmationui
diff --git a/audio/OWNERS b/audio/OWNERS
index 3671685..80e2765 100644
--- a/audio/OWNERS
+++ b/audio/OWNERS
@@ -2,3 +2,4 @@
elaurent@google.com
mnaganov@google.com
+yaoshunkai@google.com
diff --git a/audio/aidl/TEST_MAPPING b/audio/aidl/TEST_MAPPING
index e325001..26f4b3a 100644
--- a/audio/aidl/TEST_MAPPING
+++ b/audio/aidl/TEST_MAPPING
@@ -72,12 +72,7 @@
"name": "audiosystem_tests"
},
{
- "name": "CtsVirtualDevicesTestCases",
- "options" : [
- {
- "include-filter": "android.virtualdevice.cts.VirtualAudioTest"
- }
- ]
+ "name": "CtsVirtualDevicesAudioTestCases"
}
]
}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Processing.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Processing.aidl
index f6d6ee2..96d57d8 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Processing.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Processing.aidl
@@ -40,5 +40,6 @@
union Type {
android.media.audio.common.AudioStreamType streamType = android.media.audio.common.AudioStreamType.INVALID;
android.media.audio.common.AudioSource source;
+ android.media.audio.common.AudioDevice device;
}
}
diff --git a/audio/aidl/android/hardware/audio/core/StreamDescriptor.aidl b/audio/aidl/android/hardware/audio/core/StreamDescriptor.aidl
index 65ea9ef..cfe001e 100644
--- a/audio/aidl/android/hardware/audio/core/StreamDescriptor.aidl
+++ b/audio/aidl/android/hardware/audio/core/StreamDescriptor.aidl
@@ -386,14 +386,23 @@
* For input streams: the moment when data at the specified stream position
* was acquired (i.e. capture position).
*
- * The observable position must never be reset by the HAL module.
- * The data type of the frame counter is large enough to support
- * continuous counting for years of operation.
+ * The observable position must never be reset by the HAL module,
+ * providing an abstraction of continuous audio data flow. The data
+ * type of the frame counter is large enough to support continuous
+ * counting for years of operation.
*/
Position observable;
/**
* Used only for MMap streams to provide the hardware read / write
* position for audio data in the shared memory buffer 'audio.mmap'.
+ * Similar to the observable position, the 'Position::UNKNOWN' value
+ * can be returned when the HAL module is unable to retrieve the current
+ * position.
+ *
+ * The hardware position must never be reset by the HAL module,
+ * providing an abstraction of continuous audio data flow. The data
+ * type of the frame counter is large enough to support continuous
+ * counting for years of operation.
*/
Position hardware;
/**
diff --git a/audio/aidl/android/hardware/audio/effect/Processing.aidl b/audio/aidl/android/hardware/audio/effect/Processing.aidl
index cb77350..928ce16 100644
--- a/audio/aidl/android/hardware/audio/effect/Processing.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Processing.aidl
@@ -17,6 +17,7 @@
package android.hardware.audio.effect;
import android.hardware.audio.effect.Descriptor;
+import android.media.audio.common.AudioDevice;
import android.media.audio.common.AudioSource;
import android.media.audio.common.AudioStreamType;
import android.media.audio.common.AudioUuid;
@@ -30,6 +31,7 @@
union Type {
AudioStreamType streamType = AudioStreamType.INVALID;
AudioSource source;
+ AudioDevice device;
}
/**
diff --git a/audio/aidl/common/Android.bp b/audio/aidl/common/Android.bp
index 5c0c685..c14d19d 100644
--- a/audio/aidl/common/Android.bp
+++ b/audio/aidl/common/Android.bp
@@ -32,10 +32,12 @@
header_libs: [
"libbase_headers",
"libsystem_headers",
+ "libutils_headers",
],
export_header_lib_headers: [
"libbase_headers",
"libsystem_headers",
+ "libutils_headers",
],
srcs: [
"StreamWorker.cpp",
diff --git a/audio/aidl/common/include/Utils.h b/audio/aidl/common/include/Utils.h
index 6241f44..ce29635 100644
--- a/audio/aidl/common/include/Utils.h
+++ b/audio/aidl/common/include/Utils.h
@@ -29,8 +29,10 @@
#include <aidl/android/media/audio/common/AudioIoFlags.h>
#include <aidl/android/media/audio/common/AudioMode.h>
#include <aidl/android/media/audio/common/AudioOutputFlags.h>
+#include <aidl/android/media/audio/common/AudioPolicyForcedConfig.h>
#include <aidl/android/media/audio/common/PcmType.h>
#include <android/binder_auto_utils.h>
+#include <utils/FastStrcmp.h>
namespace ndk {
@@ -61,6 +63,36 @@
::aidl::android::media::audio::common::AudioMode::CALL_SCREEN,
};
+constexpr std::array<::aidl::android::media::audio::common::AudioPolicyForcedConfig, 17>
+ kValidAudioPolicyForcedConfig = {
+ ::aidl::android::media::audio::common::AudioPolicyForcedConfig::NONE,
+ ::aidl::android::media::audio::common::AudioPolicyForcedConfig::SPEAKER,
+ ::aidl::android::media::audio::common::AudioPolicyForcedConfig::HEADPHONES,
+ ::aidl::android::media::audio::common::AudioPolicyForcedConfig::BT_SCO,
+ ::aidl::android::media::audio::common::AudioPolicyForcedConfig::BT_A2DP,
+ ::aidl::android::media::audio::common::AudioPolicyForcedConfig::WIRED_ACCESSORY,
+ ::aidl::android::media::audio::common::AudioPolicyForcedConfig::BT_CAR_DOCK,
+ ::aidl::android::media::audio::common::AudioPolicyForcedConfig::BT_DESK_DOCK,
+ ::aidl::android::media::audio::common::AudioPolicyForcedConfig::ANALOG_DOCK,
+ ::aidl::android::media::audio::common::AudioPolicyForcedConfig::DIGITAL_DOCK,
+ ::aidl::android::media::audio::common::AudioPolicyForcedConfig::NO_BT_A2DP,
+ ::aidl::android::media::audio::common::AudioPolicyForcedConfig::SYSTEM_ENFORCED,
+ ::aidl::android::media::audio::common::AudioPolicyForcedConfig::
+ HDMI_SYSTEM_AUDIO_ENFORCED,
+ ::aidl::android::media::audio::common::AudioPolicyForcedConfig::
+ ENCODED_SURROUND_NEVER,
+ ::aidl::android::media::audio::common::AudioPolicyForcedConfig::
+ ENCODED_SURROUND_ALWAYS,
+ ::aidl::android::media::audio::common::AudioPolicyForcedConfig::
+ ENCODED_SURROUND_MANUAL,
+ ::aidl::android::media::audio::common::AudioPolicyForcedConfig::BT_BLE,
+};
+
+constexpr bool iequals(const std::string& str1, const std::string& str2) {
+ return str1.length() == str2.length() &&
+ !fasticmp<strncmp>(str1.c_str(), str2.c_str(), str1.length());
+}
+
constexpr size_t getPcmSampleSizeInBytes(::aidl::android::media::audio::common::PcmType pcm) {
using ::aidl::android::media::audio::common::PcmType;
switch (pcm) {
@@ -136,6 +168,12 @@
kValidAudioModes.end();
}
+constexpr bool isValidAudioPolicyForcedConfig(
+ ::aidl::android::media::audio::common::AudioPolicyForcedConfig config) {
+ return std::find(kValidAudioPolicyForcedConfig.begin(), kValidAudioPolicyForcedConfig.end(),
+ config) != kValidAudioPolicyForcedConfig.end();
+}
+
static inline bool maybeVendorExtension(const std::string& s) {
// Only checks whether the string starts with the "vendor prefix".
static const std::string vendorPrefix = "VX_";
diff --git a/audio/aidl/default/Android.bp b/audio/aidl/default/Android.bp
index 844f1e9..73d7626 100644
--- a/audio/aidl/default/Android.bp
+++ b/audio/aidl/default/Android.bp
@@ -54,6 +54,7 @@
"AidlConversionXsdc.cpp",
"AudioPolicyConfigXmlConverter.cpp",
"Bluetooth.cpp",
+ "CapEngineConfigXmlConverter.cpp",
"Config.cpp",
"Configuration.cpp",
"EngineConfigXmlConverter.cpp",
@@ -61,7 +62,6 @@
"ModulePrimary.cpp",
"SoundDose.cpp",
"Stream.cpp",
- "StreamSwitcher.cpp",
"Telephony.cpp",
"XsdcConversion.cpp",
"alsa/Mixer.cpp",
@@ -71,11 +71,13 @@
"bluetooth/DevicePortProxy.cpp",
"bluetooth/ModuleBluetooth.cpp",
"bluetooth/StreamBluetooth.cpp",
+ "deprecated/StreamSwitcher.cpp",
"primary/PrimaryMixer.cpp",
"primary/StreamPrimary.cpp",
"r_submix/ModuleRemoteSubmix.cpp",
"r_submix/SubmixRoute.cpp",
"r_submix/StreamRemoteSubmix.cpp",
+ "stub/DriverStubImpl.cpp",
"stub/ModuleStub.cpp",
"stub/StreamStub.cpp",
"usb/ModuleUsb.cpp",
@@ -83,14 +85,17 @@
"usb/UsbAlsaMixerControl.cpp",
],
generated_sources: [
+ "audio_policy_capengine_configuration_aidl_default",
"audio_policy_configuration_aidl_default",
"audio_policy_engine_configuration_aidl_default",
],
generated_headers: [
+ "audio_policy_capengine_configuration_aidl_default",
"audio_policy_configuration_aidl_default",
"audio_policy_engine_configuration_aidl_default",
],
export_generated_headers: [
+ "audio_policy_capengine_configuration_aidl_default",
"audio_policy_configuration_aidl_default",
"audio_policy_engine_configuration_aidl_default",
],
@@ -203,6 +208,7 @@
],
vendor: true,
shared_libs: [
+ "libaudio_aidl_conversion_common_ndk",
"libaudioaidlcommon",
"libaudioutils",
"libbase",
@@ -224,6 +230,7 @@
"-Wextra",
"-Werror",
"-Wthread-safety",
+ "-DBACKEND_NDK",
],
}
diff --git a/audio/aidl/default/CapEngineConfigXmlConverter.cpp b/audio/aidl/default/CapEngineConfigXmlConverter.cpp
new file mode 100644
index 0000000..8210664
--- /dev/null
+++ b/audio/aidl/default/CapEngineConfigXmlConverter.cpp
@@ -0,0 +1,386 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AHAL_Config"
+
+#include <aidl/android/media/audio/common/AudioProductStrategyType.h>
+#include <android-base/logging.h>
+#include <media/AidlConversionCppNdk.h>
+#include <media/TypeConverter.h>
+#include <media/convert.h>
+#include <utils/FastStrcmp.h>
+
+#include "core-impl/CapEngineConfigXmlConverter.h"
+#include "core-impl/XsdcConversion.h"
+
+using aidl::android::hardware::audio::common::iequals;
+using aidl::android::media::audio::common::AudioDeviceAddress;
+using aidl::android::media::audio::common::AudioDeviceDescription;
+using aidl::android::media::audio::common::AudioHalCapConfiguration;
+using aidl::android::media::audio::common::AudioHalCapCriterionV2;
+using aidl::android::media::audio::common::AudioHalCapDomain;
+using aidl::android::media::audio::common::AudioHalCapParameter;
+using aidl::android::media::audio::common::AudioHalCapRule;
+using aidl::android::media::audio::common::AudioPolicyForceUse;
+using aidl::android::media::audio::common::AudioSource;
+using aidl::android::media::audio::common::AudioStreamType;
+
+using ::android::BAD_VALUE;
+using ::android::base::unexpected;
+using ::android::utilities::convertTo;
+
+namespace eng_xsd = android::audio::policy::capengine::configuration;
+
+namespace aidl::android::hardware::audio::core::internal {
+
+static constexpr const char* gStrategiesParameter = "product_strategies";
+static constexpr const char* gInputSourcesParameter = "input_sources";
+static constexpr const char* gStreamsParameter = "streams";
+static constexpr const char* gOutputDevicesParameter = "selected_output_devices";
+static constexpr const char* gOutputDeviceAddressParameter = "device_address";
+static constexpr const char* gStrategyPrefix = "vx_";
+static constexpr const char* gLegacyOutputDevicePrefix = "AUDIO_DEVICE_OUT_";
+static constexpr const char* gLegacyInputDevicePrefix = "AUDIO_DEVICE_IN_";
+static constexpr const char* gLegacyStreamPrefix = "AUDIO_STREAM_";
+static constexpr const char* gLegacySourcePrefix = "AUDIO_SOURCE_";
+
+std::optional<std::vector<std::optional<AudioHalCapDomain>>>&
+CapEngineConfigXmlConverter::getAidlCapEngineConfig() {
+ return mAidlCapDomains;
+}
+
+ConversionResult<AudioHalCapRule::CriterionRule> convertCriterionRuleToAidl(
+ const eng_xsd::SelectionCriterionRuleType& xsdcRule) {
+ using Tag = AudioHalCapCriterionV2::Tag;
+ AudioHalCapRule::CriterionRule rule{};
+ std::string criterionName = xsdcRule.getSelectionCriterion();
+ std::string criterionValue = xsdcRule.getValue();
+ if (iequals(criterionName, toString(Tag::availableInputDevices))) {
+ rule.criterion = AudioHalCapCriterionV2::make<Tag::availableInputDevices>();
+ rule.criterionTypeValue =
+ VALUE_OR_RETURN(convertDeviceTypeToAidl(gLegacyInputDevicePrefix + criterionValue));
+ } else if (iequals(criterionName, toString(Tag::availableOutputDevices))) {
+ rule.criterion = AudioHalCapCriterionV2::make<Tag::availableOutputDevices>();
+ rule.criterionTypeValue = VALUE_OR_RETURN(
+ convertDeviceTypeToAidl(gLegacyOutputDevicePrefix + criterionValue));
+ } else if (iequals(criterionName, toString(Tag::availableInputDevicesAddresses))) {
+ rule.criterion = AudioHalCapCriterionV2::make<Tag::availableInputDevicesAddresses>();
+ rule.criterionTypeValue =
+ AudioDeviceAddress::make<AudioDeviceAddress::Tag::id>(criterionValue);
+ } else if (iequals(criterionName, toString(Tag::availableOutputDevicesAddresses))) {
+ rule.criterion = AudioHalCapCriterionV2::make<Tag::availableOutputDevicesAddresses>();
+ rule.criterionTypeValue =
+ AudioDeviceAddress::make<AudioDeviceAddress::Tag::id>(criterionValue);
+ } else if (iequals(criterionName, toString(Tag::telephonyMode))) {
+ rule.criterion = AudioHalCapCriterionV2::make<Tag::telephonyMode>();
+ rule.criterionTypeValue = VALUE_OR_RETURN(convertTelephonyModeToAidl(criterionValue));
+ } else if (!fastcmp<strncmp>(criterionName.c_str(), kXsdcForceConfigForUse,
+ strlen(kXsdcForceConfigForUse))) {
+ rule.criterion = AudioHalCapCriterionV2::make<Tag::forceConfigForUse>(
+ VALUE_OR_RETURN(convertForceUseCriterionToAidl(criterionName)));
+ rule.criterionTypeValue = VALUE_OR_RETURN(convertForcedConfigToAidl(criterionValue));
+ } else {
+ LOG(ERROR) << __func__ << " unrecognized criterion " << criterionName;
+ return unexpected(BAD_VALUE);
+ }
+ if (xsdcRule.getMatchesWhen() == eng_xsd::MatchesWhenEnum::Excludes) {
+ rule.matchingRule = AudioHalCapRule::MatchingRule::EXCLUDES;
+ } else if (xsdcRule.getMatchesWhen() == eng_xsd::MatchesWhenEnum::Includes) {
+ rule.matchingRule = AudioHalCapRule::MatchingRule::INCLUDES;
+ } else if (xsdcRule.getMatchesWhen() == eng_xsd::MatchesWhenEnum::Is) {
+ rule.matchingRule = AudioHalCapRule::MatchingRule::IS;
+ } else if (xsdcRule.getMatchesWhen() == eng_xsd::MatchesWhenEnum::IsNot) {
+ rule.matchingRule = AudioHalCapRule::MatchingRule::IS_NOT;
+ } else {
+ LOG(ERROR) << "Unsupported match when rule.";
+ return unexpected(BAD_VALUE);
+ }
+ return rule;
+}
+
+ConversionResult<AudioHalCapRule> convertRule(const eng_xsd::CompoundRuleType& xsdcCompoundRule) {
+ AudioHalCapRule rule{};
+ bool isPreviousCompoundRule = true;
+ if (xsdcCompoundRule.getType() == eng_xsd::TypeEnum::Any) {
+ rule.compoundRule = AudioHalCapRule::CompoundRule::ANY;
+ } else if (xsdcCompoundRule.getType() == eng_xsd::TypeEnum::All) {
+ rule.compoundRule = AudioHalCapRule::CompoundRule::ALL;
+ } else {
+ LOG(ERROR) << "Unsupported compound rule type.";
+ return unexpected(BAD_VALUE);
+ }
+ for (const auto& childXsdcCoumpoundRule : xsdcCompoundRule.getCompoundRule_optional()) {
+ if (childXsdcCoumpoundRule.hasCompoundRule_optional()) {
+ rule.nestedRules.push_back(VALUE_OR_FATAL(convertRule(childXsdcCoumpoundRule)));
+ } else if (childXsdcCoumpoundRule.hasSelectionCriterionRule_optional()) {
+ rule.nestedRules.push_back(VALUE_OR_FATAL(convertRule(childXsdcCoumpoundRule)));
+ }
+ }
+ if (xsdcCompoundRule.hasSelectionCriterionRule_optional()) {
+ for (const auto& xsdcRule : xsdcCompoundRule.getSelectionCriterionRule_optional()) {
+ rule.criterionRules.push_back(VALUE_OR_FATAL(convertCriterionRuleToAidl(xsdcRule)));
+ }
+ }
+ return rule;
+}
+
+ConversionResult<int> getAudioProductStrategyId(const std::string& path) {
+ std::vector<std::string> strings;
+ std::istringstream pathStream(path);
+ std::string stringToken;
+ while (getline(pathStream, stringToken, '/')) {
+ std::size_t pos = stringToken.find(gStrategyPrefix);
+ if (pos != std::string::npos) {
+ std::string strategyIdLiteral = stringToken.substr(pos + std::strlen(gStrategyPrefix));
+ int strategyId;
+ if (!convertTo(strategyIdLiteral, strategyId)) {
+ LOG(ERROR) << "Invalid strategy " << stringToken << " from path " << path;
+ return unexpected(BAD_VALUE);
+ }
+ return strategyId;
+ }
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<AudioSource> getAudioSource(const std::string& path) {
+ std::vector<std::string> strings;
+ std::istringstream pathStream(path);
+ std::string stringToken;
+ while (getline(pathStream, stringToken, '/')) {
+ if (stringToken.find(gInputSourcesParameter) != std::string::npos) {
+ getline(pathStream, stringToken, '/');
+ std::transform(stringToken.begin(), stringToken.end(), stringToken.begin(),
+ [](char c) { return std::toupper(c); });
+ std::string legacySourceLiteral = "AUDIO_SOURCE_" + stringToken;
+ audio_source_t legacySource;
+ if (!::android::SourceTypeConverter::fromString(legacySourceLiteral, legacySource)) {
+ LOG(ERROR) << "Invalid source " << stringToken << " from path " << path;
+ return unexpected(BAD_VALUE);
+ }
+ return legacy2aidl_audio_source_t_AudioSource(legacySource);
+ }
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<AudioStreamType> getAudioStreamType(const std::string& path) {
+ std::vector<std::string> strings;
+ std::istringstream pathStream(path);
+ std::string stringToken;
+
+ while (getline(pathStream, stringToken, '/')) {
+ if (stringToken.find(gStreamsParameter) != std::string::npos) {
+ getline(pathStream, stringToken, '/');
+ std::transform(stringToken.begin(), stringToken.end(), stringToken.begin(),
+ [](char c) { return std::toupper(c); });
+ std::string legacyStreamLiteral = std::string(gLegacyStreamPrefix) + stringToken;
+ audio_stream_type_t legacyStream;
+ if (!::android::StreamTypeConverter::fromString(legacyStreamLiteral, legacyStream)) {
+ LOG(ERROR) << "Invalid stream " << stringToken << " from path " << path;
+ return unexpected(BAD_VALUE);
+ }
+ return legacy2aidl_audio_stream_type_t_AudioStreamType(legacyStream);
+ }
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<std::string> toUpperAndAppendPrefix(const std::string& capName,
+ const std::string& legacyPrefix) {
+ std::string legacyName = capName;
+ std::transform(legacyName.begin(), legacyName.end(), legacyName.begin(),
+ [](char c) { return std::toupper(c); });
+ return legacyPrefix + legacyName;
+}
+
+ConversionResult<AudioHalCapParameter> CapEngineConfigXmlConverter::convertParamToAidl(
+ const eng_xsd::ConfigurableElementSettingsType& element) {
+ const auto& path = element.getPath();
+
+ AudioHalCapParameter parameterSetting;
+ if (path.find(gStrategiesParameter) != std::string::npos) {
+ int strategyId = VALUE_OR_FATAL(getAudioProductStrategyId(path));
+ if (path.find(gOutputDevicesParameter) != std::string::npos) {
+ // Value is 1 or 0
+ if (!element.hasBitParameter_optional()) {
+ LOG(ERROR) << "Invalid strategy value type";
+ return unexpected(BAD_VALUE);
+ }
+ // Convert name to output device type
+ const auto* xsdcParam = element.getFirstBitParameter_optional();
+ std::string outputDevice = VALUE_OR_FATAL(toUpperAndAppendPrefix(
+ eng_xsd::toString(xsdcParam->getName()), gLegacyOutputDevicePrefix));
+ audio_devices_t legacyType;
+ if (!::android::OutputDeviceConverter::fromString(outputDevice, legacyType)) {
+ LOG(ERROR) << "Invalid strategy device type " << outputDevice;
+ return unexpected(BAD_VALUE);
+ }
+ AudioDeviceDescription aidlDevice =
+ VALUE_OR_FATAL(legacy2aidl_audio_devices_t_AudioDeviceDescription(legacyType));
+ bool isSelected;
+ if (!convertTo(xsdcParam->getValue(), isSelected)) {
+ LOG(ERROR) << "Invalid strategy device selection value " << xsdcParam->getValue();
+ return unexpected(BAD_VALUE);
+ }
+ parameterSetting =
+ AudioHalCapParameter::StrategyDevice(aidlDevice, strategyId, isSelected);
+ } else if (path.find(gOutputDeviceAddressParameter) != std::string::npos) {
+ // Value is the address
+ if (!element.hasStringParameter_optional()) {
+ return unexpected(BAD_VALUE);
+ }
+ std::string address = element.getFirstStringParameter_optional()->getValue();
+ parameterSetting = AudioHalCapParameter::StrategyDeviceAddress(
+ AudioDeviceAddress(address), strategyId);
+ }
+ } else if (path.find(gInputSourcesParameter) != std::string::npos) {
+ // Value is 1 or 0
+ if (!element.hasBitParameter_optional()) {
+ LOG(ERROR) << "Invalid source value type";
+ return unexpected(BAD_VALUE);
+ }
+ AudioSource audioSourceAidl = VALUE_OR_FATAL(getAudioSource(path));
+ const auto* xsdcParam = element.getFirstBitParameter_optional();
+ std::string inputDeviceLiteral = VALUE_OR_FATAL(toUpperAndAppendPrefix(
+ eng_xsd::toString(xsdcParam->getName()), gLegacyInputDevicePrefix));
+ audio_devices_t inputDeviceType;
+ if (!::android::InputDeviceConverter::fromString(inputDeviceLiteral, inputDeviceType)) {
+ LOG(ERROR) << "Invalid source device type " << inputDeviceLiteral;
+ return unexpected(BAD_VALUE);
+ }
+ AudioDeviceDescription aidlDevice =
+ VALUE_OR_FATAL(legacy2aidl_audio_devices_t_AudioDeviceDescription(inputDeviceType));
+
+ bool isSelected;
+ if (!convertTo(xsdcParam->getValue(), isSelected)) {
+ LOG(ERROR) << "Invalid source value type " << xsdcParam->getValue();
+ return unexpected(BAD_VALUE);
+ }
+ parameterSetting =
+ AudioHalCapParameter::InputSourceDevice(aidlDevice, audioSourceAidl, isSelected);
+ } else if (path.find(gStreamsParameter) != std::string::npos) {
+ AudioStreamType audioStreamAidl = VALUE_OR_FATAL(getAudioStreamType(path));
+ if (!element.hasEnumParameter_optional()) {
+ LOG(ERROR) << "Invalid stream value type";
+ return unexpected(BAD_VALUE);
+ }
+ const auto* xsdcParam = element.getFirstEnumParameter_optional();
+ std::string profileLiteral =
+ VALUE_OR_FATAL(toUpperAndAppendPrefix(xsdcParam->getValue(), gLegacyStreamPrefix));
+ audio_stream_type_t profileLegacyStream;
+ if (!::android::StreamTypeConverter::fromString(profileLiteral, profileLegacyStream)) {
+ LOG(ERROR) << "Invalid stream value " << profileLiteral;
+ return unexpected(BAD_VALUE);
+ }
+ AudioStreamType profileStreamAidl = VALUE_OR_FATAL(
+ legacy2aidl_audio_stream_type_t_AudioStreamType(profileLegacyStream));
+ parameterSetting =
+ AudioHalCapParameter::StreamVolumeProfile(audioStreamAidl, profileStreamAidl);
+ }
+ return parameterSetting;
+}
+
+ConversionResult<std::vector<AudioHalCapParameter>>
+CapEngineConfigXmlConverter::convertSettingToAidl(
+ const eng_xsd::SettingsType::Configuration& xsdcSetting) {
+ std::vector<AudioHalCapParameter> aidlCapParameterSettings;
+ for (const auto& element : xsdcSetting.getConfigurableElement()) {
+ aidlCapParameterSettings.push_back(VALUE_OR_FATAL(convertParamToAidl(element)));
+ }
+ return aidlCapParameterSettings;
+}
+
+ConversionResult<AudioHalCapConfiguration> CapEngineConfigXmlConverter::convertConfigurationToAidl(
+ const eng_xsd::ConfigurationsType::Configuration& xsdcConfiguration,
+ const eng_xsd::SettingsType::Configuration& xsdcSettingConfiguration) {
+ AudioHalCapConfiguration aidlCapConfiguration;
+ aidlCapConfiguration.name = xsdcConfiguration.getName();
+ if (xsdcConfiguration.hasCompoundRule()) {
+ if (xsdcConfiguration.getCompoundRule().size() != 1) {
+ return unexpected(BAD_VALUE);
+ }
+ aidlCapConfiguration.rule =
+ VALUE_OR_FATAL(convertRule(xsdcConfiguration.getCompoundRule()[0]));
+ aidlCapConfiguration.parameterSettings =
+ VALUE_OR_FATAL(convertSettingToAidl(xsdcSettingConfiguration));
+ }
+ return aidlCapConfiguration;
+}
+
+ConversionResult<eng_xsd::SettingsType::Configuration> getConfigurationByName(
+ const std::string& name, const std::vector<eng_xsd::SettingsType>& xsdcSettingsVec) {
+ for (const auto& xsdcSettings : xsdcSettingsVec) {
+ for (const auto& xsdcConfiguration : xsdcSettings.getConfiguration()) {
+ if (xsdcConfiguration.getName() == name) {
+ return xsdcConfiguration;
+ }
+ }
+ }
+ LOG(ERROR) << __func__ << " failed to find configuration " << name;
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<std::vector<AudioHalCapConfiguration>>
+CapEngineConfigXmlConverter::convertConfigurationsToAidl(
+ const std::vector<eng_xsd::ConfigurationsType>& xsdcConfigurationsVec,
+ const std::vector<eng_xsd::SettingsType>& xsdcSettingsVec) {
+ if (xsdcConfigurationsVec.empty() || xsdcSettingsVec.empty()) {
+ LOG(ERROR) << __func__ << " empty configurations/settings";
+ return unexpected(BAD_VALUE);
+ }
+ std::vector<AudioHalCapConfiguration> aidlConfigurations;
+ for (const auto& xsdcConfigurations : xsdcConfigurationsVec) {
+ for (const auto& xsdcConfiguration : xsdcConfigurations.getConfiguration()) {
+ auto xsdcSettingConfiguration = VALUE_OR_FATAL(
+ getConfigurationByName(xsdcConfiguration.getName(), xsdcSettingsVec));
+ aidlConfigurations.push_back(VALUE_OR_FATAL(
+ convertConfigurationToAidl(xsdcConfiguration, xsdcSettingConfiguration)));
+ }
+ }
+ return aidlConfigurations;
+}
+
+ConversionResult<AudioHalCapDomain> CapEngineConfigXmlConverter::convertConfigurableDomainToAidl(
+ const eng_xsd::ConfigurableDomainType& xsdcConfigurableDomain) {
+ AudioHalCapDomain aidlConfigurableDomain;
+
+ aidlConfigurableDomain.name = xsdcConfigurableDomain.getName();
+ if (xsdcConfigurableDomain.hasSequenceAware() && xsdcConfigurableDomain.getSequenceAware()) {
+ LOG(ERROR) << "sequence aware not supported.";
+ return unexpected(BAD_VALUE);
+ }
+ if (xsdcConfigurableDomain.hasConfigurations() && xsdcConfigurableDomain.hasSettings()) {
+ aidlConfigurableDomain.configurations = VALUE_OR_FATAL(convertConfigurationsToAidl(
+ xsdcConfigurableDomain.getConfigurations(), xsdcConfigurableDomain.getSettings()));
+ }
+ return aidlConfigurableDomain;
+}
+
+void CapEngineConfigXmlConverter::init() {
+ if (getXsdcConfig()->hasConfigurableDomain()) {
+ mAidlCapDomains = std::make_optional<>(VALUE_OR_FATAL(
+ (convertCollectionToAidlOptionalValues<eng_xsd::ConfigurableDomainType,
+ AudioHalCapDomain>(
+ getXsdcConfig()->getConfigurableDomain(),
+ std::bind(&CapEngineConfigXmlConverter::convertConfigurableDomainToAidl,
+ this, std::placeholders::_1)))));
+ } else {
+ mAidlCapDomains = std::nullopt;
+ }
+}
+
+} // namespace aidl::android::hardware::audio::core::internal
diff --git a/audio/aidl/default/Configuration.cpp b/audio/aidl/default/Configuration.cpp
index 54e2d18..0ff8eb4 100644
--- a/audio/aidl/default/Configuration.cpp
+++ b/audio/aidl/default/Configuration.cpp
@@ -324,9 +324,9 @@
//
// Mix ports:
// * "r_submix output", maximum 10 opened streams, maximum 10 active streams
-// - profile PCM 16-bit; STEREO; 8000, 11025, 16000, 32000, 44100, 48000
+// - profile PCM 16-bit; STEREO; 8000, 11025, 16000, 32000, 44100, 48000, 192000
// * "r_submix input", maximum 10 opened streams, maximum 10 active streams
-// - profile PCM 16-bit; STEREO; 8000, 11025, 16000, 32000, 44100, 48000
+// - profile PCM 16-bit; STEREO; 8000, 11025, 16000, 32000, 44100, 48000, 192000
//
// Routes:
// "r_submix output" -> "Remote Submix Out"
@@ -337,7 +337,7 @@
Configuration c;
const std::vector<AudioProfile> remoteSubmixPcmAudioProfiles{
createProfile(PcmType::INT_16_BIT, {AudioChannelLayout::LAYOUT_STEREO},
- {8000, 11025, 16000, 32000, 44100, 48000})};
+ {8000, 11025, 16000, 32000, 44100, 48000, 192000})};
// Device ports
diff --git a/audio/aidl/default/EffectConfig.cpp b/audio/aidl/default/EffectConfig.cpp
index eb0c015..9c335ba 100644
--- a/audio/aidl/default/EffectConfig.cpp
+++ b/audio/aidl/default/EffectConfig.cpp
@@ -18,6 +18,8 @@
#include <string>
#define LOG_TAG "AHAL_EffectConfig"
#include <android-base/logging.h>
+#include <media/AidlConversionCppNdk.h>
+#include <system/audio.h>
#include <system/audio_aidl_utils.h>
#include <system/audio_effects/audio_effects_conf.h>
#include <system/audio_effects/effect_uuid.h>
@@ -28,6 +30,10 @@
#include <android/apexsupport.h>
#endif
+using aidl::android::media::audio::common::AudioDevice;
+using aidl::android::media::audio::common::AudioDeviceAddress;
+using aidl::android::media::audio::common::AudioDeviceDescription;
+using aidl::android::media::audio::common::AudioDeviceType;
using aidl::android::media::audio::common::AudioSource;
using aidl::android::media::audio::common::AudioStreamType;
using aidl::android::media::audio::common::AudioUuid;
@@ -76,6 +82,14 @@
registerFailure(parseProcessing(Processing::Type::streamType, xmlStream));
}
}
+
+ // Parse device effect chains
+ for (auto& xmlDeviceEffects : getChildren(xmlConfig, "deviceEffects")) {
+ for (auto& xmlDevice : getChildren(xmlDeviceEffects, "device")) {
+ // AudioDevice
+ registerFailure(parseProcessing(Processing::Type::device, xmlDevice));
+ }
+ }
}
LOG(DEBUG) << __func__ << " successfully parsed " << file << ", skipping " << mSkippedElements
<< " element(s)";
@@ -195,7 +209,8 @@
}
std::optional<Processing::Type> EffectConfig::stringToProcessingType(Processing::Type::Tag typeTag,
- const std::string& type) {
+ const std::string& type,
+ const std::string& address) {
// see list of audio stream types in audio_stream_type_t:
// system/media/audio/include/system/audio_effects/audio_effects_conf.h
// AUDIO_STREAM_DEFAULT_TAG is not listed here because according to SYS_RESERVED_DEFAULT in
@@ -238,6 +253,19 @@
if (typeIter != sAudioSourceTable.end()) {
return typeIter->second;
}
+ } else if (typeTag == Processing::Type::device) {
+ audio_devices_t deviceType;
+ if (!audio_device_from_string(type.c_str(), &deviceType)) {
+ LOG(ERROR) << __func__ << "DeviceEffect: invalid type " << type;
+ return std::nullopt;
+ }
+ auto ret = ::aidl::android::legacy2aidl_audio_device_AudioDevice(deviceType, address);
+ if (!ret.ok()) {
+ LOG(ERROR) << __func__ << "DeviceEffect: Failed to get AudioDevice from type "
+ << deviceType << ", address " << address;
+ return std::nullopt;
+ }
+ return ret.value();
}
return std::nullopt;
@@ -246,7 +274,10 @@
bool EffectConfig::parseProcessing(Processing::Type::Tag typeTag, const tinyxml2::XMLElement& xml) {
LOG(VERBOSE) << __func__ << dump(xml);
const char* typeStr = xml.Attribute("type");
- auto aidlType = stringToProcessingType(typeTag, typeStr);
+ const char* addressStr = xml.Attribute("address");
+ // For device effect, device address is optional, match will be done for the given device type
+ // with empty address.
+ auto aidlType = stringToProcessingType(typeTag, typeStr, addressStr ? addressStr : "");
RETURN_VALUE_IF(!aidlType.has_value(), false, "illegalStreamType");
RETURN_VALUE_IF(0 != mProcessingMap.count(aidlType.value()), false, "duplicateStreamType");
diff --git a/audio/aidl/default/EffectContext.cpp b/audio/aidl/default/EffectContext.cpp
index 7b8cfb1..26c88b2 100644
--- a/audio/aidl/default/EffectContext.cpp
+++ b/audio/aidl/default/EffectContext.cpp
@@ -63,13 +63,18 @@
}
void EffectContext::dupeFmqWithReopen(IEffect::OpenEffectReturn* effectRet) {
+ const size_t inBufferSizeInFloat = mCommon.input.frameCount * mInputFrameSize / sizeof(float);
+ const size_t outBufferSizeInFloat =
+ mCommon.output.frameCount * mOutputFrameSize / sizeof(float);
+ const size_t bufferSize = std::max(inBufferSizeInFloat, outBufferSizeInFloat);
if (!mInputMQ) {
- mInputMQ = std::make_shared<DataMQ>(mCommon.input.frameCount * mInputFrameSize /
- sizeof(float));
+ mInputMQ = std::make_shared<DataMQ>(inBufferSizeInFloat);
}
if (!mOutputMQ) {
- mOutputMQ = std::make_shared<DataMQ>(mCommon.output.frameCount * mOutputFrameSize /
- sizeof(float));
+ mOutputMQ = std::make_shared<DataMQ>(outBufferSizeInFloat);
+ }
+ if (mWorkBuffer.size() != bufferSize) {
+ mWorkBuffer.resize(bufferSize);
}
dupeFmq(effectRet);
}
@@ -222,8 +227,6 @@
}
if (needUpdateMq) {
- mWorkBuffer.resize(std::max(common.input.frameCount * mInputFrameSize / sizeof(float),
- common.output.frameCount * mOutputFrameSize / sizeof(float)));
return notifyDataMqUpdate();
}
return RetCode::SUCCESS;
@@ -242,4 +245,17 @@
LOG(VERBOSE) << __func__ << " : signal client for reopen";
return RetCode::SUCCESS;
}
+
+RetCode EffectContext::enable() {
+ return RetCode::SUCCESS;
+}
+
+RetCode EffectContext::disable() {
+ return RetCode::SUCCESS;
+}
+
+RetCode EffectContext::reset() {
+ return RetCode::SUCCESS;
+}
+
} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/EffectImpl.cpp b/audio/aidl/default/EffectImpl.cpp
index 7192d97..3e61335 100644
--- a/audio/aidl/default/EffectImpl.cpp
+++ b/audio/aidl/default/EffectImpl.cpp
@@ -246,7 +246,6 @@
startThread();
break;
case CommandId::STOP:
- case CommandId::RESET:
RETURN_OK_IF(mState == State::IDLE);
mState = State::IDLE;
RETURN_IF(notifyEventFlag(mDataMqNotEmptyEf) != RetCode::SUCCESS, EX_ILLEGAL_STATE,
@@ -254,6 +253,13 @@
stopThread();
RETURN_IF_ASTATUS_NOT_OK(commandImpl(command), "commandImplFailed");
break;
+ case CommandId::RESET:
+ mState = State::IDLE;
+ RETURN_IF(notifyEventFlag(mDataMqNotEmptyEf) != RetCode::SUCCESS, EX_ILLEGAL_STATE,
+ "notifyEventFlagNotEmptyFailed");
+ stopThread();
+ RETURN_IF_ASTATUS_NOT_OK(commandImpl(command), "commandImplFailed");
+ break;
default:
LOG(ERROR) << getEffectNameWithVersion() << __func__ << " instance still processing";
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
@@ -266,8 +272,22 @@
ndk::ScopedAStatus EffectImpl::commandImpl(CommandId command) {
RETURN_IF(!mImplContext, EX_NULL_POINTER, "nullContext");
- if (command == CommandId::RESET) {
- mImplContext->resetBuffer();
+ switch (command) {
+ case CommandId::START:
+ mImplContext->enable();
+ break;
+ case CommandId::STOP:
+ mImplContext->disable();
+ break;
+ case CommandId::RESET:
+ mImplContext->disable();
+ mImplContext->reset();
+ mImplContext->resetBuffer();
+ break;
+ default:
+ LOG(ERROR) << __func__ << " commandId " << toString(command) << " not supported";
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "commandIdNotSupported");
}
return ndk::ScopedAStatus::ok();
}
diff --git a/audio/aidl/default/EffectMain.cpp b/audio/aidl/default/EffectMain.cpp
index a300cfd..7a6141a 100644
--- a/audio/aidl/default/EffectMain.cpp
+++ b/audio/aidl/default/EffectMain.cpp
@@ -38,7 +38,7 @@
candidatePath.append(apexName).append("/etc/").append(kDefaultConfigName);
LOG(DEBUG) << __func__ << " effect lib path " << candidatePath;
if (access(candidatePath.c_str(), R_OK) == 0) {
- return std::move(candidatePath);
+ return candidatePath;
}
}
} else {
diff --git a/audio/aidl/default/EngineConfigXmlConverter.cpp b/audio/aidl/default/EngineConfigXmlConverter.cpp
index 631cdce..5a8b0a3 100644
--- a/audio/aidl/default/EngineConfigXmlConverter.cpp
+++ b/audio/aidl/default/EngineConfigXmlConverter.cpp
@@ -26,15 +26,19 @@
#include <aidl/android/media/audio/common/AudioProductStrategyType.h>
#include <android-base/logging.h>
+#include "core-impl/CapEngineConfigXmlConverter.h"
#include "core-impl/EngineConfigXmlConverter.h"
#include "core-impl/XsdcConversion.h"
+using aidl::android::hardware::audio::core::internal::CapEngineConfigXmlConverter;
+using aidl::android::hardware::audio::core::internal::convertAudioUsageToAidl;
using aidl::android::media::audio::common::AudioAttributes;
using aidl::android::media::audio::common::AudioContentType;
using aidl::android::media::audio::common::AudioFlag;
using aidl::android::media::audio::common::AudioHalAttributesGroup;
using aidl::android::media::audio::common::AudioHalCapCriterion;
using aidl::android::media::audio::common::AudioHalCapCriterionType;
+using aidl::android::media::audio::common::AudioHalCapCriterionV2;
using aidl::android::media::audio::common::AudioHalEngineConfig;
using aidl::android::media::audio::common::AudioHalProductStrategy;
using aidl::android::media::audio::common::AudioHalVolumeCurve;
@@ -43,6 +47,7 @@
using aidl::android::media::audio::common::AudioSource;
using aidl::android::media::audio::common::AudioStreamType;
using aidl::android::media::audio::common::AudioUsage;
+
using ::android::BAD_VALUE;
using ::android::base::unexpected;
@@ -50,6 +55,10 @@
namespace aidl::android::hardware::audio::core::internal {
+/** Default path of audio policy cap engine configuration file. */
+static constexpr char kCapEngineConfigFileName[] =
+ "/parameter-framework/Settings/Policy/PolicyConfigurableDomains.xml";
+
void EngineConfigXmlConverter::initProductStrategyMap() {
#define STRATEGY_ENTRY(name) {"STRATEGY_" #name, static_cast<int>(AudioProductStrategyType::name)}
@@ -74,6 +83,13 @@
return it->second;
}
+ConversionResult<int> EngineConfigXmlConverter::convertProductStrategyIdToAidl(int xsdcId) {
+ if (xsdcId < AudioHalProductStrategy::VENDOR_STRATEGY_ID_START) {
+ return unexpected(BAD_VALUE);
+ }
+ return xsdcId;
+}
+
bool isDefaultAudioAttributes(const AudioAttributes& attributes) {
return ((attributes.contentType == AudioContentType::UNKNOWN) &&
(attributes.usage == AudioUsage::UNKNOWN) &&
@@ -95,29 +111,26 @@
}
AudioAttributes aidlAudioAttributes;
if (xsdcAudioAttributes.hasContentType()) {
- aidlAudioAttributes.contentType = static_cast<AudioContentType>(
- xsdcAudioAttributes.getFirstContentType()->getValue());
+ aidlAudioAttributes.contentType = VALUE_OR_FATAL(convertAudioContentTypeToAidl(
+ xsdcAudioAttributes.getFirstContentType()->getValue()));
}
if (xsdcAudioAttributes.hasUsage()) {
- aidlAudioAttributes.usage =
- static_cast<AudioUsage>(xsdcAudioAttributes.getFirstUsage()->getValue());
+ aidlAudioAttributes.usage = VALUE_OR_FATAL(
+ convertAudioUsageToAidl(xsdcAudioAttributes.getFirstUsage()->getValue()));
}
if (xsdcAudioAttributes.hasSource()) {
- aidlAudioAttributes.source =
- static_cast<AudioSource>(xsdcAudioAttributes.getFirstSource()->getValue());
+ aidlAudioAttributes.source = VALUE_OR_FATAL(
+ convertAudioSourceToAidl(xsdcAudioAttributes.getFirstSource()->getValue()));
}
if (xsdcAudioAttributes.hasFlags()) {
std::vector<eng_xsd::FlagType> xsdcFlagTypeVec =
xsdcAudioAttributes.getFirstFlags()->getValue();
- for (const eng_xsd::FlagType& xsdcFlagType : xsdcFlagTypeVec) {
- if (xsdcFlagType != eng_xsd::FlagType::AUDIO_FLAG_NONE) {
- aidlAudioAttributes.flags |= 1 << (static_cast<int>(xsdcFlagType) - 1);
- }
- }
+ aidlAudioAttributes.flags = VALUE_OR_FATAL(convertAudioFlagsToAidl(xsdcFlagTypeVec));
}
if (xsdcAudioAttributes.hasBundle()) {
const eng_xsd::BundleType* xsdcBundle = xsdcAudioAttributes.getFirstBundle();
- aidlAudioAttributes.tags[0] = xsdcBundle->getKey() + "=" + xsdcBundle->getValue();
+ aidlAudioAttributes.tags.reserve(1);
+ aidlAudioAttributes.tags.push_back(xsdcBundle->getKey() + "_" + xsdcBundle->getValue());
}
if (isDefaultAudioAttributes(aidlAudioAttributes)) {
mDefaultProductStrategyId = std::optional<int>{-1};
@@ -131,8 +144,10 @@
static const int kStreamTypeEnumOffset =
static_cast<int>(eng_xsd::Stream::AUDIO_STREAM_VOICE_CALL) -
static_cast<int>(AudioStreamType::VOICE_CALL);
- aidlAttributesGroup.streamType = static_cast<AudioStreamType>(
- static_cast<int>(xsdcAttributesGroup.getStreamType()) - kStreamTypeEnumOffset);
+ aidlAttributesGroup.streamType = xsdcAttributesGroup.hasStreamType()
+ ? VALUE_OR_FATAL(convertAudioStreamTypeToAidl(
+ xsdcAttributesGroup.getStreamType()))
+ : AudioStreamType::INVALID;
aidlAttributesGroup.volumeGroupName = xsdcAttributesGroup.getVolumeGroup();
if (xsdcAttributesGroup.hasAttributes_optional()) {
aidlAttributesGroup.attributes =
@@ -165,7 +180,8 @@
AudioHalProductStrategy aidlProductStrategy;
aidlProductStrategy.id =
- VALUE_OR_FATAL(convertProductStrategyNameToAidl(xsdcProductStrategy.getName()));
+ VALUE_OR_FATAL(convertProductStrategyIdToAidl(xsdcProductStrategy.getId()));
+ aidlProductStrategy.name = xsdcProductStrategy.getName();
if (xsdcProductStrategy.hasAttributesGroup()) {
aidlProductStrategy.attributesGroups = VALUE_OR_FATAL(
@@ -247,18 +263,15 @@
}
if (getXsdcConfig()->hasCriteria() && getXsdcConfig()->hasCriterion_types()) {
AudioHalEngineConfig::CapSpecificConfig capSpecificConfig;
- capSpecificConfig.criteria = VALUE_OR_FATAL(
- (convertWrappedCollectionToAidl<eng_xsd::CriteriaType, eng_xsd::CriterionType,
- AudioHalCapCriterion>(
- getXsdcConfig()->getCriteria(), &eng_xsd::CriteriaType::getCriterion,
- &convertCapCriterionToAidl)));
- capSpecificConfig.criterionTypes =
- VALUE_OR_FATAL((convertWrappedCollectionToAidl<eng_xsd::CriterionTypesType,
- eng_xsd::CriterionTypeType,
- AudioHalCapCriterionType>(
- getXsdcConfig()->getCriterion_types(),
- &eng_xsd::CriterionTypesType::getCriterion_type,
- &convertCapCriterionTypeToAidl)));
+ capSpecificConfig.criteriaV2 =
+ std::make_optional<>(VALUE_OR_FATAL((convertCapCriteriaCollectionToAidl(
+ getXsdcConfig()->getCriteria(), getXsdcConfig()->getCriterion_types()))));
+ internal::CapEngineConfigXmlConverter capEngConfigConverter{
+ ::android::audio_find_readable_configuration_file(kCapEngineConfigFileName)};
+ if (capEngConfigConverter.getStatus() == ::android::OK) {
+ capSpecificConfig.domains = std::move(capEngConfigConverter.getAidlCapEngineConfig());
+ }
+ mAidlEngineConfig.capSpecificConfig = capSpecificConfig;
}
}
} // namespace aidl::android::hardware::audio::core::internal
diff --git a/audio/aidl/default/Module.cpp b/audio/aidl/default/Module.cpp
index 543efd1..45ce5ef 100644
--- a/audio/aidl/default/Module.cpp
+++ b/audio/aidl/default/Module.cpp
@@ -47,6 +47,7 @@
using aidl::android::media::audio::common::AudioDeviceType;
using aidl::android::media::audio::common::AudioFormatDescription;
using aidl::android::media::audio::common::AudioFormatType;
+using aidl::android::media::audio::common::AudioGainConfig;
using aidl::android::media::audio::common::AudioInputFlags;
using aidl::android::media::audio::common::AudioIoFlags;
using aidl::android::media::audio::common::AudioMMapPolicy;
@@ -391,7 +392,7 @@
Module::Configuration& Module::getConfig() {
if (!mConfig) {
- mConfig = std::move(initializeConfig());
+ mConfig = initializeConfig();
}
return *mConfig;
}
@@ -1200,7 +1201,9 @@
}
if (in_requested.gain.has_value()) {
- // Let's pretend that gain can always be applied.
+ if (!setAudioPortConfigGain(*portIt, in_requested.gain.value())) {
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
out_suggested->gain = in_requested.gain.value();
}
@@ -1242,6 +1245,52 @@
return ndk::ScopedAStatus::ok();
}
+bool Module::setAudioPortConfigGain(const AudioPort& port, const AudioGainConfig& gainRequested) {
+ auto& ports = getConfig().ports;
+ if (gainRequested.index < 0 || gainRequested.index >= (int)port.gains.size()) {
+ LOG(ERROR) << __func__ << ": gains for port " << port.id << " is undefined";
+ return false;
+ }
+ int stepValue = port.gains[gainRequested.index].stepValue;
+ if (stepValue == 0) {
+ LOG(ERROR) << __func__ << ": port gain step value is 0";
+ return false;
+ }
+ int minValue = port.gains[gainRequested.index].minValue;
+ int maxValue = port.gains[gainRequested.index].maxValue;
+ if (gainRequested.values[0] > maxValue || gainRequested.values[0] < minValue) {
+ LOG(ERROR) << __func__ << ": gain value " << gainRequested.values[0]
+ << " out of range of min and max gain config";
+ return false;
+ }
+ int gainIndex = (gainRequested.values[0] - minValue) / stepValue;
+ int totalSteps = (maxValue - minValue) / stepValue;
+ if (totalSteps == 0) {
+ LOG(ERROR) << __func__ << ": difference between port gain min value " << minValue
+ << " and max value " << maxValue << " is less than step value " << stepValue;
+ return false;
+ }
+ // Root-power quantities are used in curve:
+ // 10^((minMb / 100 + (maxMb / 100 - minMb / 100) * gainIndex / totalSteps) / (10 * 2))
+ // where 100 is the conversion from mB to dB, 10 comes from the log 10 conversion from power
+ // ratios, and 2 means are the square of amplitude.
+ float gain =
+ pow(10, (minValue + (maxValue - minValue) * (gainIndex / (float)totalSteps)) / 2000);
+ if (gain < 0) {
+ LOG(ERROR) << __func__ << ": gain " << gain << " is less than 0";
+ return false;
+ }
+ for (const auto& route : getConfig().routes) {
+ if (route.sinkPortId != port.id) {
+ continue;
+ }
+ for (const auto sourcePortId : route.sourcePortIds) {
+ mStreams.setGain(sourcePortId, gain);
+ }
+ }
+ return true;
+}
+
ndk::ScopedAStatus Module::resetAudioPatch(int32_t in_patchId) {
auto& patches = getConfig().patches;
auto patchIt = findById<AudioPatch>(patches, in_patchId);
diff --git a/audio/aidl/default/Stream.cpp b/audio/aidl/default/Stream.cpp
index 8f5e839..de66293 100644
--- a/audio/aidl/default/Stream.cpp
+++ b/audio/aidl/default/Stream.cpp
@@ -47,6 +47,17 @@
namespace aidl::android::hardware::audio::core {
+namespace {
+
+template <typename MQTypeError>
+auto fmqErrorHandler(const char* mqName) {
+ return [m = std::string(mqName)](MQTypeError fmqError, std::string&& errorMessage) {
+ CHECK_EQ(fmqError, MQTypeError::NONE) << m << ": " << errorMessage;
+ };
+}
+
+} // namespace
+
void StreamContext::fillDescriptor(StreamDescriptor* desc) {
if (mCommandMQ) {
desc->command = mCommandMQ->dupeDesc();
@@ -332,11 +343,7 @@
bool StreamInWorkerLogic::read(size_t clientSize, StreamDescriptor::Reply* reply) {
ATRACE_CALL();
StreamContext::DataMQ* const dataMQ = mContext->getDataMQ();
- StreamContext::DataMQ::Error fmqError = StreamContext::DataMQ::Error::NONE;
- std::string fmqErrorMsg;
- const size_t byteCount = std::min(
- {clientSize, dataMQ->availableToWrite(&fmqError, &fmqErrorMsg), mDataBufferSize});
- CHECK(fmqError == StreamContext::DataMQ::Error::NONE) << fmqErrorMsg;
+ const size_t byteCount = std::min({clientSize, dataMQ->availableToWrite(), mDataBufferSize});
const bool isConnected = mIsConnected;
const size_t frameSize = mContext->getFrameSize();
size_t actualFrameCount = 0;
@@ -612,10 +619,7 @@
bool StreamOutWorkerLogic::write(size_t clientSize, StreamDescriptor::Reply* reply) {
ATRACE_CALL();
StreamContext::DataMQ* const dataMQ = mContext->getDataMQ();
- StreamContext::DataMQ::Error fmqError = StreamContext::DataMQ::Error::NONE;
- std::string fmqErrorMsg;
- const size_t readByteCount = dataMQ->availableToRead(&fmqError, &fmqErrorMsg);
- CHECK(fmqError == StreamContext::DataMQ::Error::NONE) << fmqErrorMsg;
+ const size_t readByteCount = dataMQ->availableToRead();
const size_t frameSize = mContext->getFrameSize();
bool fatal = false;
int32_t latency = mContext->getNominalLatencyMs();
@@ -663,10 +667,14 @@
}
StreamCommonImpl::~StreamCommonImpl() {
- if (!isClosed()) {
- LOG(ERROR) << __func__ << ": stream was not closed prior to destruction, resource leak";
- stopWorker();
- // The worker and the context should clean up by themselves via destructors.
+ // It is responsibility of the class that implements 'DriverInterface' to call 'cleanupWorker'
+ // in the destructor. Note that 'cleanupWorker' can not be properly called from this destructor
+ // because any subclasses have already been destroyed and thus the 'DriverInterface'
+ // implementation is not valid. Thus, here it can only be asserted whether the subclass has done
+ // its job.
+ if (!mWorkerStopIssued && !isClosed()) {
+ LOG(FATAL) << __func__ << ": the stream implementation must call 'cleanupWorker' "
+ << "in order to clean up the worker thread.";
}
}
@@ -715,6 +723,14 @@
LOG(WARNING) << __func__ << ": invalid worker tid: " << workerTid;
}
}
+ getContext().getCommandMQ()->setErrorHandler(
+ fmqErrorHandler<StreamContext::CommandMQ::Error>("CommandMQ"));
+ getContext().getReplyMQ()->setErrorHandler(
+ fmqErrorHandler<StreamContext::ReplyMQ::Error>("ReplyMQ"));
+ if (getContext().getDataMQ() != nullptr) {
+ getContext().getDataMQ()->setErrorHandler(
+ fmqErrorHandler<StreamContext::DataMQ::Error>("DataMQ"));
+ }
return ndk::ScopedAStatus::ok();
}
@@ -770,10 +786,7 @@
ndk::ScopedAStatus StreamCommonImpl::close() {
LOG(DEBUG) << __func__;
if (!isClosed()) {
- stopWorker();
- LOG(DEBUG) << __func__ << ": joining the worker thread...";
- mWorker->stop();
- LOG(DEBUG) << __func__ << ": worker thread joined";
+ stopAndJoinWorker();
onClose(mWorker->setClosed());
return ndk::ScopedAStatus::ok();
} else {
@@ -791,6 +804,20 @@
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
}
+void StreamCommonImpl::cleanupWorker() {
+ if (!isClosed()) {
+ LOG(ERROR) << __func__ << ": stream was not closed prior to destruction, resource leak";
+ stopAndJoinWorker();
+ }
+}
+
+void StreamCommonImpl::stopAndJoinWorker() {
+ stopWorker();
+ LOG(DEBUG) << __func__ << ": joining the worker thread...";
+ mWorker->join();
+ LOG(DEBUG) << __func__ << ": worker thread joined";
+}
+
void StreamCommonImpl::stopWorker() {
if (auto commandMQ = mContext.getCommandMQ(); commandMQ != nullptr) {
LOG(DEBUG) << __func__ << ": asking the worker to exit...";
@@ -805,6 +832,7 @@
}
LOG(DEBUG) << __func__ << ": done";
}
+ mWorkerStopIssued = true;
}
ndk::ScopedAStatus StreamCommonImpl::updateMetadataCommon(const Metadata& metadata) {
@@ -827,6 +855,11 @@
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus StreamCommonImpl::setGain(float gain) {
+ LOG(DEBUG) << __func__ << ": gain " << gain;
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
ndk::ScopedAStatus StreamCommonImpl::bluetoothParametersUpdated() {
LOG(DEBUG) << __func__;
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
diff --git a/audio/aidl/default/XsdcConversion.cpp b/audio/aidl/default/XsdcConversion.cpp
index 1720949..ba6110d 100644
--- a/audio/aidl/default/XsdcConversion.cpp
+++ b/audio/aidl/default/XsdcConversion.cpp
@@ -10,11 +10,21 @@
#include <aidl/android/media/audio/common/AudioPortConfig.h>
#include <media/AidlConversionCppNdk.h>
#include <media/TypeConverter.h>
+#include <media/convert.h>
+#include <utils/FastStrcmp.h>
+
+#include <Utils.h>
#include "core-impl/XmlConverter.h"
#include "core-impl/XsdcConversion.h"
+using aidl::android::hardware::audio::common::iequals;
+using aidl::android::hardware::audio::common::isValidAudioMode;
+using aidl::android::hardware::audio::common::isValidAudioPolicyForcedConfig;
+using aidl::android::hardware::audio::common::kValidAudioModes;
+using aidl::android::hardware::audio::common::kValidAudioPolicyForcedConfig;
using aidl::android::media::audio::common::AudioChannelLayout;
+using aidl::android::media::audio::common::AudioContentType;
using aidl::android::media::audio::common::AudioDevice;
using aidl::android::media::audio::common::AudioDeviceAddress;
using aidl::android::media::audio::common::AudioDeviceDescription;
@@ -24,22 +34,39 @@
using aidl::android::media::audio::common::AudioGain;
using aidl::android::media::audio::common::AudioHalCapCriterion;
using aidl::android::media::audio::common::AudioHalCapCriterionType;
+using aidl::android::media::audio::common::AudioHalCapCriterionV2;
using aidl::android::media::audio::common::AudioHalVolumeCurve;
using aidl::android::media::audio::common::AudioIoFlags;
+using aidl::android::media::audio::common::AudioMode;
+using aidl::android::media::audio::common::AudioPolicyForcedConfig;
+using aidl::android::media::audio::common::AudioPolicyForceUse;
using aidl::android::media::audio::common::AudioPort;
using aidl::android::media::audio::common::AudioPortConfig;
using aidl::android::media::audio::common::AudioPortDeviceExt;
using aidl::android::media::audio::common::AudioPortExt;
using aidl::android::media::audio::common::AudioPortMixExt;
using aidl::android::media::audio::common::AudioProfile;
+using aidl::android::media::audio::common::AudioSource;
+using aidl::android::media::audio::common::AudioStreamType;
+using aidl::android::media::audio::common::AudioUsage;
using ::android::BAD_VALUE;
using ::android::base::unexpected;
+using ::android::utilities::convertTo;
namespace ap_xsd = android::audio::policy::configuration;
namespace eng_xsd = android::audio::policy::engine::configuration;
namespace aidl::android::hardware::audio::core::internal {
+static constexpr const char kXsdcForceConfigForCommunication[] = "ForceUseForCommunication";
+static constexpr const char kXsdcForceConfigForMedia[] = "ForceUseForMedia";
+static constexpr const char kXsdcForceConfigForRecord[] = "ForceUseForRecord";
+static constexpr const char kXsdcForceConfigForDock[] = "ForceUseForDock";
+static constexpr const char kXsdcForceConfigForSystem[] = "ForceUseForSystem";
+static constexpr const char kXsdcForceConfigForHdmiSystemAudio[] = "ForceUseForHdmiSystemAudio";
+static constexpr const char kXsdcForceConfigForEncodedSurround[] = "ForceUseForEncodedSurround";
+static constexpr const char kXsdcForceConfigForVibrateRinging[] = "ForceUseForVibrateRinging";
+
inline ConversionResult<std::string> assertNonEmpty(const std::string& s) {
if (s.empty()) {
LOG(ERROR) << __func__ << " Review Audio Policy config: "
@@ -51,6 +78,100 @@
#define NON_EMPTY_STRING_OR_FATAL(s) VALUE_OR_FATAL(assertNonEmpty(s))
+ConversionResult<int32_t> convertAudioFlagsToAidl(
+ const std::vector<eng_xsd::FlagType>& xsdcFlagTypeVec) {
+ int legacyFlagMask = 0;
+ for (const eng_xsd::FlagType& xsdcFlagType : xsdcFlagTypeVec) {
+ if (xsdcFlagType != eng_xsd::FlagType::AUDIO_FLAG_NONE) {
+ audio_flags_mask_t legacyFlag = AUDIO_FLAG_NONE;
+ if (!::android::AudioFlagConverter::fromString(eng_xsd::toString(xsdcFlagType),
+ legacyFlag)) {
+ LOG(ERROR) << __func__ << " Review Audio Policy config, "
+ << eng_xsd::toString(xsdcFlagType) << " is not a valid flag.";
+ return unexpected(BAD_VALUE);
+ }
+ legacyFlagMask |= static_cast<int>(legacyFlag);
+ }
+ }
+ ConversionResult<int32_t> result = legacy2aidl_audio_flags_mask_t_int32_t_mask(
+ static_cast<audio_flags_mask_t>(legacyFlagMask));
+ if (!result.ok()) {
+ LOG(ERROR) << __func__ << " Review Audio Policy config, " << legacyFlagMask
+ << " has invalid flag(s).";
+ return unexpected(BAD_VALUE);
+ }
+ return result;
+}
+
+ConversionResult<AudioStreamType> convertAudioStreamTypeToAidl(const eng_xsd::Stream& xsdcStream) {
+ audio_stream_type_t legacyStreamType;
+ if (!::android::StreamTypeConverter::fromString(eng_xsd::toString(xsdcStream),
+ legacyStreamType)) {
+ LOG(ERROR) << __func__ << " Review Audio Policy config, " << eng_xsd::toString(xsdcStream)
+ << " is not a valid audio stream type.";
+ return unexpected(BAD_VALUE);
+ }
+ ConversionResult<AudioStreamType> result =
+ legacy2aidl_audio_stream_type_t_AudioStreamType(legacyStreamType);
+ if (!result.ok()) {
+ LOG(ERROR) << __func__ << " Review Audio Policy config, " << legacyStreamType
+ << " is not a valid audio stream type.";
+ return unexpected(BAD_VALUE);
+ }
+ return result;
+}
+
+ConversionResult<AudioSource> convertAudioSourceToAidl(
+ const eng_xsd::SourceEnumType& xsdcSourceType) {
+ audio_source_t legacySourceType;
+ if (!::android::SourceTypeConverter::fromString(eng_xsd::toString(xsdcSourceType),
+ legacySourceType)) {
+ LOG(ERROR) << __func__ << " Review Audio Policy config, "
+ << eng_xsd::toString(xsdcSourceType) << " is not a valid audio source.";
+ return unexpected(BAD_VALUE);
+ }
+ ConversionResult<AudioSource> result = legacy2aidl_audio_source_t_AudioSource(legacySourceType);
+ if (!result.ok()) {
+ LOG(ERROR) << __func__ << " Review Audio Policy config, " << legacySourceType
+ << " is not a valid audio source.";
+ return unexpected(BAD_VALUE);
+ }
+ return result;
+}
+
+ConversionResult<AudioContentType> convertAudioContentTypeToAidl(
+ const eng_xsd::ContentType& xsdcContentType) {
+ audio_content_type_t legacyContentType;
+ if (!::android::AudioContentTypeConverter::fromString(eng_xsd::toString(xsdcContentType),
+ legacyContentType)) {
+ LOG(ERROR) << __func__ << " Review Audio Policy config, "
+ << eng_xsd::toString(xsdcContentType) << " is not a valid audio content type.";
+ return unexpected(BAD_VALUE);
+ }
+ ConversionResult<AudioContentType> result =
+ legacy2aidl_audio_content_type_t_AudioContentType(legacyContentType);
+ if (!result.ok()) {
+ LOG(ERROR) << __func__ << " Review Audio Policy config, " << legacyContentType
+ << " is not a valid audio content type.";
+ return unexpected(BAD_VALUE);
+ }
+ return result;
+}
+
+ConversionResult<AudioUsage> convertAudioUsageToAidl(const eng_xsd::UsageEnumType& xsdcUsage) {
+ audio_usage_t legacyUsage;
+ if (!::android::UsageTypeConverter::fromString(eng_xsd::toString(xsdcUsage), legacyUsage)) {
+ LOG(ERROR) << __func__ << " Review Audio Policy config, not a valid audio usage.";
+ return unexpected(BAD_VALUE);
+ }
+ ConversionResult<AudioUsage> result = legacy2aidl_audio_usage_t_AudioUsage(legacyUsage);
+ if (!result.ok()) {
+ LOG(ERROR) << __func__ << " Review Audio Policy config, not a valid audio usage.";
+ return unexpected(BAD_VALUE);
+ }
+ return result;
+}
+
ConversionResult<AudioFormatDescription> convertAudioFormatToAidl(const std::string& xsdcFormat) {
audio_format_t legacyFormat = ::android::formatFromString(xsdcFormat, AUDIO_FORMAT_DEFAULT);
ConversionResult<AudioFormatDescription> result =
@@ -410,32 +531,240 @@
return result;
}
+ConversionResult<AudioPolicyForcedConfig> convertForcedConfigToAidl(
+ const std::string& xsdcForcedConfigCriterionType) {
+ const auto it = std::find_if(
+ kValidAudioPolicyForcedConfig.begin(), kValidAudioPolicyForcedConfig.end(),
+ [&](const auto& config) { return toString(config) == xsdcForcedConfigCriterionType; });
+ if (it == kValidAudioPolicyForcedConfig.end()) {
+ LOG(ERROR) << __func__ << " invalid forced config " << xsdcForcedConfigCriterionType;
+ return unexpected(BAD_VALUE);
+ }
+ return *it;
+}
+
+ConversionResult<AudioMode> convertTelephonyModeToAidl(const std::string& xsdcModeCriterionType) {
+ const auto it = std::find_if(kValidAudioModes.begin(), kValidAudioModes.end(),
+ [&xsdcModeCriterionType](const auto& mode) {
+ return toString(mode) == xsdcModeCriterionType;
+ });
+ if (it == kValidAudioModes.end()) {
+ LOG(ERROR) << __func__ << " invalid mode " << xsdcModeCriterionType;
+ return unexpected(BAD_VALUE);
+ }
+ return *it;
+}
+
+ConversionResult<AudioDeviceAddress> convertDeviceAddressToAidl(const std::string& xsdcAddress) {
+ return AudioDeviceAddress::make<AudioDeviceAddress::Tag::id>(xsdcAddress);
+}
+
+ConversionResult<eng_xsd::CriterionTypeType> getCriterionTypeByName(
+ const std::string& name,
+ const std::vector<eng_xsd::CriterionTypesType>& xsdcCriterionTypesVec) {
+ for (const auto& xsdCriterionTypes : xsdcCriterionTypesVec) {
+ for (const auto& xsdcCriterionType : xsdCriterionTypes.getCriterion_type()) {
+ if (xsdcCriterionType.getName() == name) {
+ return xsdcCriterionType;
+ }
+ }
+ }
+ LOG(ERROR) << __func__ << " failed to find criterion type " << name;
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<std::vector<std::optional<AudioHalCapCriterionV2>>>
+convertCapCriteriaCollectionToAidl(
+ const std::vector<eng_xsd::CriteriaType>& xsdcCriteriaVec,
+ const std::vector<eng_xsd::CriterionTypesType>& xsdcCriterionTypesVec) {
+ std::vector<std::optional<AudioHalCapCriterionV2>> resultAidlCriterionVec;
+ if (xsdcCriteriaVec.empty() || xsdcCriterionTypesVec.empty()) {
+ LOG(ERROR) << __func__ << " empty criteria/criterionTypes";
+ return unexpected(BAD_VALUE);
+ }
+ for (const auto& xsdCriteria : xsdcCriteriaVec) {
+ for (const auto& xsdcCriterion : xsdCriteria.getCriterion()) {
+ resultAidlCriterionVec.push_back(
+ std::optional<AudioHalCapCriterionV2>(VALUE_OR_FATAL(
+ convertCapCriterionV2ToAidl(xsdcCriterion, xsdcCriterionTypesVec))));
+ }
+ }
+ return resultAidlCriterionVec;
+}
+
+ConversionResult<std::vector<AudioDeviceDescription>> convertDevicesToAidl(
+ const eng_xsd::CriterionTypeType& xsdcDeviceCriterionType) {
+ if (xsdcDeviceCriterionType.getValues().empty()) {
+ LOG(ERROR) << __func__ << " no values provided";
+ return unexpected(BAD_VALUE);
+ }
+ std::vector<AudioDeviceDescription> aidlDevices;
+ for (eng_xsd::ValuesType xsdcValues : xsdcDeviceCriterionType.getValues()) {
+ aidlDevices.reserve(xsdcValues.getValue().size());
+ for (const eng_xsd::ValueType& xsdcValue : xsdcValues.getValue()) {
+ if (!xsdcValue.hasAndroid_type()) {
+ LOG(ERROR) << __func__ << " empty android type";
+ return unexpected(BAD_VALUE);
+ }
+ uint32_t integerValue;
+ if (!convertTo(xsdcValue.getAndroid_type(), integerValue)) {
+ LOG(ERROR) << __func__ << " failed to convert android type "
+ << xsdcValue.getAndroid_type();
+ return unexpected(BAD_VALUE);
+ }
+ aidlDevices.push_back(
+ VALUE_OR_RETURN(legacy2aidl_audio_devices_t_AudioDeviceDescription(
+ static_cast<audio_devices_t>(integerValue))));
+ }
+ }
+ return aidlDevices;
+}
+
+ConversionResult<std::vector<AudioDeviceAddress>> convertDeviceAddressesToAidl(
+ const eng_xsd::CriterionTypeType& xsdcDeviceAddressesCriterionType) {
+ if (xsdcDeviceAddressesCriterionType.getValues().empty()) {
+ LOG(ERROR) << __func__ << " no values provided";
+ return unexpected(BAD_VALUE);
+ }
+ std::vector<AudioDeviceAddress> aidlDeviceAddresses;
+ for (eng_xsd::ValuesType xsdcValues : xsdcDeviceAddressesCriterionType.getValues()) {
+ aidlDeviceAddresses.reserve(xsdcValues.getValue().size());
+ for (const eng_xsd::ValueType& xsdcValue : xsdcValues.getValue()) {
+ aidlDeviceAddresses.push_back(
+ AudioDeviceAddress::make<AudioDeviceAddress::Tag::id>(xsdcValue.getLiteral()));
+ }
+ }
+ return aidlDeviceAddresses;
+}
+
+ConversionResult<std::vector<AudioMode>> convertTelephonyModesToAidl(
+ const eng_xsd::CriterionTypeType& xsdcTelephonyModeCriterionType) {
+ if (xsdcTelephonyModeCriterionType.getValues().empty()) {
+ LOG(ERROR) << __func__ << " no values provided";
+ return unexpected(BAD_VALUE);
+ }
+ std::vector<AudioMode> aidlAudioModes;
+ for (eng_xsd::ValuesType xsdcValues : xsdcTelephonyModeCriterionType.getValues()) {
+ aidlAudioModes.reserve(xsdcValues.getValue().size());
+ for (const eng_xsd::ValueType& xsdcValue : xsdcValues.getValue()) {
+ int integerValue = xsdcValue.getNumerical();
+ if (!isValidAudioMode(AudioMode(integerValue))) {
+ LOG(ERROR) << __func__ << " invalid audio mode " << integerValue;
+ return unexpected(BAD_VALUE);
+ }
+ aidlAudioModes.push_back(AudioMode(integerValue));
+ }
+ }
+ return aidlAudioModes;
+}
+
+ConversionResult<std::vector<AudioPolicyForcedConfig>> convertForcedConfigsToAidl(
+ const eng_xsd::CriterionTypeType& xsdcForcedConfigCriterionType) {
+ if (xsdcForcedConfigCriterionType.getValues().empty()) {
+ LOG(ERROR) << __func__ << " no values provided";
+ return unexpected(BAD_VALUE);
+ }
+ std::vector<AudioPolicyForcedConfig> aidlForcedConfigs;
+ for (eng_xsd::ValuesType xsdcValues : xsdcForcedConfigCriterionType.getValues()) {
+ aidlForcedConfigs.reserve(xsdcValues.getValue().size());
+ for (const eng_xsd::ValueType& xsdcValue : xsdcValues.getValue()) {
+ int integerValue = xsdcValue.getNumerical();
+ if (!isValidAudioPolicyForcedConfig(AudioPolicyForcedConfig(integerValue))) {
+ LOG(ERROR) << __func__ << " invalid forced config mode " << integerValue;
+ return unexpected(BAD_VALUE);
+ }
+ aidlForcedConfigs.push_back(AudioPolicyForcedConfig(integerValue));
+ }
+ }
+ return aidlForcedConfigs;
+}
+
+ConversionResult<AudioPolicyForceUse> convertForceUseCriterionToAidl(
+ const std::string& xsdcCriterionName) {
+ if (!fastcmp<strncmp>(xsdcCriterionName.c_str(), kXsdcForceConfigForCommunication,
+ strlen(kXsdcForceConfigForCommunication))) {
+ return AudioPolicyForceUse::COMMUNICATION;
+ }
+ if (!fasticmp<strncmp>(xsdcCriterionName.c_str(), kXsdcForceConfigForMedia,
+ strlen(kXsdcForceConfigForMedia))) {
+ return AudioPolicyForceUse::MEDIA;
+ }
+ if (!fasticmp<strncmp>(xsdcCriterionName.c_str(), kXsdcForceConfigForRecord,
+ strlen(kXsdcForceConfigForRecord))) {
+ return AudioPolicyForceUse::RECORD;
+ }
+ if (!fasticmp<strncmp>(xsdcCriterionName.c_str(), kXsdcForceConfigForDock,
+ strlen(kXsdcForceConfigForDock))) {
+ return AudioPolicyForceUse::DOCK;
+ }
+ if (!fasticmp<strncmp>(xsdcCriterionName.c_str(), kXsdcForceConfigForSystem,
+ strlen(kXsdcForceConfigForSystem))) {
+ return AudioPolicyForceUse::SYSTEM;
+ }
+ if (!fasticmp<strncmp>(xsdcCriterionName.c_str(), kXsdcForceConfigForHdmiSystemAudio,
+ strlen(kXsdcForceConfigForHdmiSystemAudio))) {
+ return AudioPolicyForceUse::HDMI_SYSTEM_AUDIO;
+ }
+ if (!fasticmp<strncmp>(xsdcCriterionName.c_str(), kXsdcForceConfigForEncodedSurround,
+ strlen(kXsdcForceConfigForEncodedSurround))) {
+ return AudioPolicyForceUse::ENCODED_SURROUND;
+ }
+ if (!fasticmp<strncmp>(xsdcCriterionName.c_str(), kXsdcForceConfigForVibrateRinging,
+ strlen(kXsdcForceConfigForVibrateRinging))) {
+ return AudioPolicyForceUse::VIBRATE_RINGING;
+ }
+ LOG(ERROR) << __func__ << " unrecognized force use " << xsdcCriterionName;
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<AudioHalCapCriterionV2> convertCapCriterionV2ToAidl(
+ const eng_xsd::CriterionType& xsdcCriterion,
+ const std::vector<eng_xsd::CriterionTypesType>& xsdcCriterionTypesVec) {
+ eng_xsd::CriterionTypeType xsdcCriterionType =
+ VALUE_OR_RETURN(getCriterionTypeByName(xsdcCriterion.getType(), xsdcCriterionTypesVec));
+ std::string defaultLiteralValue =
+ xsdcCriterion.has_default() ? xsdcCriterion.get_default() : "";
+ using Tag = AudioHalCapCriterionV2::Tag;
+ if (iequals(xsdcCriterion.getName(), toString(Tag::availableInputDevices))) {
+ return AudioHalCapCriterionV2::make<Tag::availableInputDevices>(
+ VALUE_OR_RETURN(convertDevicesToAidl(xsdcCriterionType)));
+ }
+ if (iequals(xsdcCriterion.getName(), toString(Tag::availableOutputDevices))) {
+ return AudioHalCapCriterionV2::make<Tag::availableOutputDevices>(
+ VALUE_OR_RETURN(convertDevicesToAidl(xsdcCriterionType)));
+ }
+ if (iequals(xsdcCriterion.getName(), toString(Tag::availableInputDevicesAddresses))) {
+ return AudioHalCapCriterionV2::make<Tag::availableInputDevicesAddresses>(
+ VALUE_OR_RETURN(convertDeviceAddressesToAidl(xsdcCriterionType)));
+ }
+ if (iequals(xsdcCriterion.getName(), toString(Tag::availableOutputDevicesAddresses))) {
+ return AudioHalCapCriterionV2::make<Tag::availableOutputDevicesAddresses>(
+ VALUE_OR_RETURN(convertDeviceAddressesToAidl(xsdcCriterionType)));
+ }
+ if (iequals(xsdcCriterion.getName(), toString(Tag::telephonyMode))) {
+ return AudioHalCapCriterionV2::make<Tag::telephonyMode>(
+ VALUE_OR_RETURN(convertTelephonyModesToAidl(xsdcCriterionType)));
+ }
+ if (!fastcmp<strncmp>(xsdcCriterion.getName().c_str(), kXsdcForceConfigForUse,
+ strlen(kXsdcForceConfigForUse))) {
+ return AudioHalCapCriterionV2::make<Tag::forceConfigForUse>(
+ VALUE_OR_RETURN(convertForceUseCriterionToAidl(xsdcCriterion.getName())),
+ VALUE_OR_RETURN(convertForcedConfigsToAidl(xsdcCriterionType)));
+ }
+ LOG(ERROR) << __func__ << " unrecognized criterion " << xsdcCriterion.getName();
+ return unexpected(BAD_VALUE);
+}
+
ConversionResult<AudioHalCapCriterion> convertCapCriterionToAidl(
const eng_xsd::CriterionType& xsdcCriterion) {
AudioHalCapCriterion aidlCapCriterion;
aidlCapCriterion.name = xsdcCriterion.getName();
aidlCapCriterion.criterionTypeName = xsdcCriterion.getType();
- aidlCapCriterion.defaultLiteralValue = xsdcCriterion.get_default();
+ aidlCapCriterion.defaultLiteralValue =
+ xsdcCriterion.has_default() ? xsdcCriterion.get_default() : "";
return aidlCapCriterion;
}
-ConversionResult<std::string> convertCriterionTypeValueToAidl(
- const eng_xsd::ValueType& xsdcCriterionTypeValue) {
- return xsdcCriterionTypeValue.getLiteral();
-}
-
-ConversionResult<AudioHalCapCriterionType> convertCapCriterionTypeToAidl(
- const eng_xsd::CriterionTypeType& xsdcCriterionType) {
- AudioHalCapCriterionType aidlCapCriterionType;
- aidlCapCriterionType.name = xsdcCriterionType.getName();
- aidlCapCriterionType.isInclusive = !(static_cast<bool>(xsdcCriterionType.getType()));
- aidlCapCriterionType.values = VALUE_OR_RETURN(
- (convertWrappedCollectionToAidl<eng_xsd::ValuesType, eng_xsd::ValueType, std::string>(
- xsdcCriterionType.getValues(), &eng_xsd::ValuesType::getValue,
- &convertCriterionTypeValueToAidl)));
- return aidlCapCriterionType;
-}
-
ConversionResult<AudioHalVolumeCurve::CurvePoint> convertCurvePointToAidl(
const std::string& xsdcCurvePoint) {
AudioHalVolumeCurve::CurvePoint aidlCurvePoint{};
diff --git a/audio/aidl/default/alsa/StreamAlsa.cpp b/audio/aidl/default/alsa/StreamAlsa.cpp
index e57d538..c77bfca 100644
--- a/audio/aidl/default/alsa/StreamAlsa.cpp
+++ b/audio/aidl/default/alsa/StreamAlsa.cpp
@@ -37,6 +37,10 @@
mConfig(alsa::getPcmConfig(getContext(), mIsInput)),
mReadWriteRetries(readWriteRetries) {}
+StreamAlsa::~StreamAlsa() {
+ cleanupWorker();
+}
+
::android::status_t StreamAlsa::init() {
return mConfig.has_value() ? ::android::OK : ::android::NO_INIT;
}
@@ -71,6 +75,10 @@
}
decltype(mAlsaDeviceProxies) alsaDeviceProxies;
for (const auto& device : getDeviceProfiles()) {
+ if ((device.direction == PCM_OUT && mIsInput) ||
+ (device.direction == PCM_IN && !mIsInput)) {
+ continue;
+ }
alsa::DeviceProxy proxy;
if (device.isExternal) {
// Always ask alsa configure as required since the configuration should be supported
@@ -88,6 +96,9 @@
}
alsaDeviceProxies.push_back(std::move(proxy));
}
+ if (alsaDeviceProxies.empty()) {
+ return ::android::NO_INIT;
+ }
mAlsaDeviceProxies = std::move(alsaDeviceProxies);
return ::android::OK;
}
@@ -106,6 +117,7 @@
mReadWriteRetries);
maxLatency = proxy_get_latency(mAlsaDeviceProxies[0].get());
} else {
+ alsa::applyGain(buffer, mGain, bytesToTransfer, mConfig.value().format, mConfig->channels);
for (auto& proxy : mAlsaDeviceProxies) {
proxy_write_with_retries(proxy.get(), buffer, bytesToTransfer, mReadWriteRetries);
maxLatency = std::max(maxLatency, proxy_get_latency(proxy.get()));
@@ -155,4 +167,9 @@
mAlsaDeviceProxies.clear();
}
+ndk::ScopedAStatus StreamAlsa::setGain(float gain) {
+ mGain = gain;
+ return ndk::ScopedAStatus::ok();
+}
+
} // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/alsa/Utils.cpp b/audio/aidl/default/alsa/Utils.cpp
index c08836c..10374f2 100644
--- a/audio/aidl/default/alsa/Utils.cpp
+++ b/audio/aidl/default/alsa/Utils.cpp
@@ -22,6 +22,8 @@
#include <aidl/android/media/audio/common/AudioFormatType.h>
#include <aidl/android/media/audio/common/PcmType.h>
#include <android-base/logging.h>
+#include <audio_utils/primitives.h>
+#include <cutils/compiler.h>
#include "Utils.h"
#include "core-impl/utils.h"
@@ -80,11 +82,8 @@
const AudioChannelCountToMaskMap& getSupportedChannelOutLayoutMap() {
static const std::set<AudioChannelLayout> supportedOutChannelLayouts = {
- DEFINE_CHANNEL_LAYOUT_MASK(MONO), DEFINE_CHANNEL_LAYOUT_MASK(STEREO),
- DEFINE_CHANNEL_LAYOUT_MASK(2POINT1), DEFINE_CHANNEL_LAYOUT_MASK(QUAD),
- DEFINE_CHANNEL_LAYOUT_MASK(PENTA), DEFINE_CHANNEL_LAYOUT_MASK(5POINT1),
- DEFINE_CHANNEL_LAYOUT_MASK(6POINT1), DEFINE_CHANNEL_LAYOUT_MASK(7POINT1),
- DEFINE_CHANNEL_LAYOUT_MASK(7POINT1POINT4), DEFINE_CHANNEL_LAYOUT_MASK(22POINT2),
+ DEFINE_CHANNEL_LAYOUT_MASK(MONO),
+ DEFINE_CHANNEL_LAYOUT_MASK(STEREO),
};
static const AudioChannelCountToMaskMap outLayouts =
make_ChannelCountToMaskMap(supportedOutChannelLayouts);
@@ -346,4 +345,68 @@
return findValueOrDefault(getAudioFormatDescriptorToPcmFormatMap(), aidl, PCM_FORMAT_INVALID);
}
+void applyGain(void* buffer, float gain, size_t bytesToTransfer, enum pcm_format pcmFormat,
+ int channelCount) {
+ if (channelCount != 1 && channelCount != 2) {
+ LOG(WARNING) << __func__ << ": unsupported channel count " << channelCount;
+ return;
+ }
+ if (!getPcmFormatToAudioFormatDescMap().contains(pcmFormat)) {
+ LOG(WARNING) << __func__ << ": unsupported pcm format " << pcmFormat;
+ return;
+ }
+ const float unityGainFloat = 1.0f;
+ if (std::abs(gain - unityGainFloat) < 1e-6) {
+ return;
+ }
+ int numFrames;
+ switch (pcmFormat) {
+ case PCM_FORMAT_S16_LE: {
+ const uint16_t unityGainQ4_12 = u4_12_from_float(unityGainFloat);
+ const uint16_t vl = u4_12_from_float(gain);
+ const uint32_t vrl = (vl << 16) | vl;
+ if (channelCount == 2) {
+ numFrames = bytesToTransfer / sizeof(uint32_t);
+ uint32_t* intBuffer = (uint32_t*)buffer;
+ if (CC_UNLIKELY(vl > unityGainQ4_12)) {
+ // volume is boosted, so we might need to clamp even though
+ // we process only one track.
+ do {
+ int32_t l = mulRL(1, *intBuffer, vrl) >> 12;
+ int32_t r = mulRL(0, *intBuffer, vrl) >> 12;
+ l = clamp16(l);
+ r = clamp16(r);
+ *intBuffer++ = (r << 16) | (l & 0xFFFF);
+ } while (--numFrames);
+ } else {
+ do {
+ int32_t l = mulRL(1, *intBuffer, vrl) >> 12;
+ int32_t r = mulRL(0, *intBuffer, vrl) >> 12;
+ *intBuffer++ = (r << 16) | (l & 0xFFFF);
+ } while (--numFrames);
+ }
+ } else {
+ numFrames = bytesToTransfer / sizeof(uint16_t);
+ int16_t* intBuffer = (int16_t*)buffer;
+ if (CC_UNLIKELY(vl > unityGainQ4_12)) {
+ // volume is boosted, so we might need to clamp even though
+ // we process only one track.
+ do {
+ int32_t mono = mulRL(1, *intBuffer, vrl) >> 12;
+ *intBuffer++ = clamp16(mono);
+ } while (--numFrames);
+ } else {
+ do {
+ int32_t mono = mulRL(1, *intBuffer, vrl) >> 12;
+ *intBuffer++ = static_cast<int16_t>(mono & 0xFFFF);
+ } while (--numFrames);
+ }
+ }
+ } break;
+ default:
+ // TODO(336370745): Implement gain for other supported formats
+ break;
+ }
+}
+
} // namespace aidl::android::hardware::audio::core::alsa
diff --git a/audio/aidl/default/alsa/Utils.h b/audio/aidl/default/alsa/Utils.h
index 980f685..a97ea10 100644
--- a/audio/aidl/default/alsa/Utils.h
+++ b/audio/aidl/default/alsa/Utils.h
@@ -59,6 +59,8 @@
AlsaProxy mProxy;
};
+void applyGain(void* buffer, float gain, size_t bytesToTransfer, enum pcm_format pcmFormat,
+ int channelCount);
::aidl::android::media::audio::common::AudioChannelLayout getChannelLayoutMaskFromChannelCount(
unsigned int channelCount, int isInput);
::aidl::android::media::audio::common::AudioChannelLayout getChannelIndexMaskFromChannelCount(
diff --git a/audio/aidl/default/audio_effects_config.xml b/audio/aidl/default/audio_effects_config.xml
index 11683d2..a54f4db 100644
--- a/audio/aidl/default/audio_effects_config.xml
+++ b/audio/aidl/default/audio_effects_config.xml
@@ -140,4 +140,37 @@
</postprocess>
-->
+ <!-- Device pre/post processor configurations.
+ The device pre/post processor configuration is described in a deviceEffects element and
+ consists in a list of elements each describing pre/post processor settings for a given
+ device.
+ Each device element has a "type" attribute corresponding to the device type (e.g.
+ speaker, bus), an "address" attribute corresponding to the device address and contains a
+ list of "apply" elements indicating one effect to apply.
+ If the device is a source, only pre processing effects are expected, if the
+ device is a sink, only post processing effects are expected.
+ The effect to apply is designated by its name in the "effects" elements.
+ The effect will be enabled by default and the audio framework will automatically add
+ and activate the effect if the given port is involved in an audio patch.
+ If the patch is "HW", the effect must be HW accelerated.
+ Note:
+ -Device are not expected to be always attached. It may be loaded dynamically. As the device
+ effect manager is getting called on any audio patch operation, it will ensure if the given
+ device is involved in an audio patch and attach the requested effect.
+ -Address is optional. If not set, the match to instantiate the device effect will be done
+ using the given type and device (of this type) with empty address only.
+
+ <deviceEffects>
+ <device type="AUDIO_DEVICE_OUT_BUS" address="BUS00_USAGE_MAIN">
+ <apply effect="equalizer"/>
+ </device>
+ <device type="AUDIO_DEVICE_OUT_BUS" address="BUS04_USAGE_VOICE">
+ <apply effect="volume"/>
+ </device>
+ <device type="AUDIO_DEVICE_IN_BUILTIN_MIC" address="bottom">
+ <apply effect="agc"/>
+ </device>
+ </deviceEffects>
+ -->
+
</audio_effects_conf>
diff --git a/audio/aidl/default/bluetooth/StreamBluetooth.cpp b/audio/aidl/default/bluetooth/StreamBluetooth.cpp
index efab470..6e1a811 100644
--- a/audio/aidl/default/bluetooth/StreamBluetooth.cpp
+++ b/audio/aidl/default/bluetooth/StreamBluetooth.cpp
@@ -66,6 +66,10 @@
1000),
mBtDeviceProxy(btDeviceProxy) {}
+StreamBluetooth::~StreamBluetooth() {
+ cleanupWorker();
+}
+
::android::status_t StreamBluetooth::init() {
std::lock_guard guard(mLock);
if (mBtDeviceProxy == nullptr) {
diff --git a/audio/aidl/default/config/audioPolicy/api/current.txt b/audio/aidl/default/config/audioPolicy/api/current.txt
index 3547f54..e57c108 100644
--- a/audio/aidl/default/config/audioPolicy/api/current.txt
+++ b/audio/aidl/default/config/audioPolicy/api/current.txt
@@ -191,6 +191,7 @@
enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_XHE;
enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AC3;
enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AC4;
+ enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AC4_L4;
enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_ALAC;
enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AMR_NB;
enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AMR_WB;
diff --git a/audio/aidl/default/config/audioPolicy/audio_policy_configuration.xsd b/audio/aidl/default/config/audioPolicy/audio_policy_configuration.xsd
index d93f697..108a6a3 100644
--- a/audio/aidl/default/config/audioPolicy/audio_policy_configuration.xsd
+++ b/audio/aidl/default/config/audioPolicy/audio_policy_configuration.xsd
@@ -389,6 +389,7 @@
<xs:enumeration value="AUDIO_FORMAT_APTX"/>
<xs:enumeration value="AUDIO_FORMAT_APTX_HD"/>
<xs:enumeration value="AUDIO_FORMAT_AC4"/>
+ <xs:enumeration value="AUDIO_FORMAT_AC4_L4"/>
<xs:enumeration value="AUDIO_FORMAT_LDAC"/>
<xs:enumeration value="AUDIO_FORMAT_MAT"/>
<xs:enumeration value="AUDIO_FORMAT_MAT_1_0"/>
diff --git a/audio/aidl/default/config/audioPolicy/capengine/Android.bp b/audio/aidl/default/config/audioPolicy/capengine/Android.bp
new file mode 100644
index 0000000..cb99923
--- /dev/null
+++ b/audio/aidl/default/config/audioPolicy/capengine/Android.bp
@@ -0,0 +1,17 @@
+package {
+ default_team: "trendy_team_android_media_audio_framework",
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+xsd_config {
+ name: "audio_policy_capengine_configuration_aidl_default",
+ srcs: ["PolicyConfigurableDomains.xsd"],
+ package_name: "android.audio.policy.capengine.configuration",
+ nullability: true,
+ root_elements: ["ConfigurableDomains"],
+}
diff --git a/audio/aidl/default/config/audioPolicy/capengine/PolicyConfigurableDomains.xsd b/audio/aidl/default/config/audioPolicy/capengine/PolicyConfigurableDomains.xsd
new file mode 100644
index 0000000..4e7c0bb
--- /dev/null
+++ b/audio/aidl/default/config/audioPolicy/capengine/PolicyConfigurableDomains.xsd
@@ -0,0 +1,467 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+ <!-- BEGIN W3cXmlAttributes.xsd -->
+ <xs:annotation>
+ <xs:documentation>
+ See http://www.w3.org/XML/1998/namespace.html and
+ http://www.w3.org/TR/REC-xml for information about this namespace.
+
+ This schema document describes the XML namespace, in a form
+ suitable for import by other schema documents.
+
+ Note that local names in this namespace are intended to be defined
+ only by the World Wide Web Consortium or its subgroups. The
+ following names are currently defined in this namespace and should
+ not be used with conflicting semantics by any Working Group,
+ specification, or document instance:
+
+ base (as an attribute name): denotes an attribute whose value
+ provides a URI to be used as the base for interpreting any
+ relative URIs in the scope of the element on which it
+ appears; its value is inherited. This name is reserved
+ by virtue of its definition in the XML Base specification.
+
+ id (as an attribute name): denotes an attribute whose value
+ should be interpreted as if declared to be of type ID.
+ The xml:id specification is not yet a W3C Recommendation,
+ but this attribute is included here to facilitate experimentation
+ with the mechanisms it proposes. Note that it is _not_ included
+ in the specialAttrs attribute group.
+
+ lang (as an attribute name): denotes an attribute whose value
+ is a language code for the natural language of the content of
+ any element; its value is inherited. This name is reserved
+ by virtue of its definition in the XML specification.
+
+ space (as an attribute name): denotes an attribute whose
+ value is a keyword indicating what whitespace processing
+ discipline is intended for the content of the element; its
+ value is inherited. This name is reserved by virtue of its
+ definition in the XML specification.
+
+ Father (in any context at all): denotes Jon Bosak, the chair of
+ the original XML Working Group. This name is reserved by
+ the following decision of the W3C XML Plenary and
+ XML Coordination groups:
+
+ In appreciation for his vision, leadership and dedication
+ the W3C XML Plenary on this 10th day of February, 2000
+ reserves for Jon Bosak in perpetuity the XML name
+ xml:Father
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:annotation>
+ <xs:documentation>This schema defines attributes and an attribute group
+ suitable for use by
+ schemas wishing to allow xml:base, xml:lang, xml:space or xml:id
+ attributes on elements they define.
+
+ To enable this, such a schema must import this schema
+ for the XML namespace, e.g. as follows:
+ <schema . . .>
+ . . .
+ <import namespace="http://www.w3.org/XML/1998/namespace"
+ schemaLocation="http://www.w3.org/2005/08/xml.xsd"/>
+
+ Subsequently, qualified reference to any of the attributes
+ or the group defined below will have the desired effect, e.g.
+
+ <type . . .>
+ . . .
+ <attributeGroup ref="xml:specialAttrs"/>
+
+ will define a type which will schema-validate an instance
+ element with any of those attributes</xs:documentation>
+ </xs:annotation>
+
+ <xs:annotation>
+ <xs:documentation>In keeping with the XML Schema WG's standard versioning
+ policy, this schema document will persist at
+ http://www.w3.org/2005/08/xml.xsd.
+ At the date of issue it can also be found at
+ http://www.w3.org/2001/xml.xsd.
+ The schema document at that URI may however change in the future,
+ in order to remain compatible with the latest version of XML Schema
+ itself, or with the XML namespace itself. In other words, if the XML
+ Schema or XML namespaces change, the version of this document at
+ http://www.w3.org/2001/xml.xsd will change
+ accordingly; the version at
+ http://www.w3.org/2005/08/xml.xsd will not change.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:attribute name="lang">
+ <xs:annotation>
+ <xs:documentation>Attempting to install the relevant ISO 2- and 3-letter
+ codes as the enumerated possible values is probably never
+ going to be a realistic possibility. See
+ RFC 3066 at http://www.ietf.org/rfc/rfc3066.txt and the IANA registry
+ at http://www.iana.org/assignments/lang-tag-apps.htm for
+ further information.
+
+ The union allows for the 'un-declaration' of xml:lang with
+ the empty string.</xs:documentation>
+ </xs:annotation>
+ <xs:simpleType>
+ <xs:union memberTypes="xs:language">
+ <xs:simpleType name="langEnum">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value=""/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:union>
+ </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="space">
+ <xs:simpleType name="spaceEnum">
+ <xs:restriction base="xs:NCName">
+ <xs:enumeration value="default"/>
+ <xs:enumeration value="preserve"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="base" type="xs:anyURI">
+ <xs:annotation>
+ <xs:documentation>See http://www.w3.org/TR/xmlbase/ for
+ information about this attribute.</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="id" type="xs:ID">
+ <xs:annotation>
+ <xs:documentation>See http://www.w3.org/TR/xml-id/ for
+ information about this attribute.</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attributeGroup name="specialAttrs">
+ <xs:attribute ref="xml:base"/>
+ <xs:attribute ref="xml:lang"/>
+ <xs:attribute ref="xml:space"/>
+ </xs:attributeGroup>
+ <!-- END W3cXmlAttributes.xsd -->
+
+ <!-- BEGIN ParameterSettings.xsd -->
+ <!-- BUG b/147297854 - removed "abstract" from type definition -->
+ <xs:complexType name="BooleanParameterType">
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute name="Name" type="ParameterNameEnumType" use="required"/>
+ </xs:extension>
+ <!--xs:restriction base="xs:string">
+ <xs:pattern value="([01][\s]*)+"/>
+ <xs:pattern value="((0x0|0x1)[\s]*)+"/>
+ <xs:attribute name="Name" type="xs:string" use="required"/>
+ </xs:restriction-->
+ </xs:simpleContent>
+ </xs:complexType>
+ <xs:complexType name="IntegerParameterType">
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute name="Name" type="ParameterNameEnumType" use="required"/>
+ </xs:extension>
+ <!--xs:restriction base="xs:string">
+ <xs:pattern value="(0|([+-]?[1-9][0-9]*))(\s+(0|([+-]?[1-9][0-9]*)))*"/>
+ <xs:pattern value="(0x[0-9a-fA-F]+)(\s+(0x[0-9a-fA-F]+))*"/>
+ <xs:attribute name="Name" type="xs:string" use="required"/>
+ </xs:restriction-->
+ </xs:simpleContent>
+ </xs:complexType>
+ <xs:complexType name="EnumParameterType">
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute name="Name" type="ParameterNameEnumType" use="required"/>
+ </xs:extension>
+ <!--xs:extension base="xs:string">
+ <xs:attribute name="Name" type="xs:string" use="required"/>
+ </xs:extension-->
+ </xs:simpleContent>
+ </xs:complexType>
+ <xs:complexType name="PointParameterType">
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute name="Name" type="ParameterNameEnumType" use="required"/>
+ </xs:extension>
+ <!--xs:restriction base="xs:string">
+ <xs:pattern value="((0|[+-]?0\.[0-9]+|(([+-]?[1-9][0-9]*)(\.[0-9]+)?))([Ee][+-]?[0-9]+)?)(\s+(0|[+-]?0\.[0-9]+|(([+-]?[1-9][0-9]*)(\.[0-9]+)?))([Ee][+-]?[0-9]+)?)*"/>
+ <xs:pattern value="(0x[0-9a-fA-F]+)(\s+(0x[0-9a-fA-F]+))*"/>
+ <xs:attribute name="Name" type="xs:NMTOKEN" use="required"/>
+ </xs:restriction-->
+ </xs:simpleContent>
+ </xs:complexType>
+ <xs:complexType name="BitParameterBlockType">
+ <xs:sequence>
+ <xs:element name="BitParameter" maxOccurs="unbounded" type="IntegerParameterType"/>
+ </xs:sequence>
+ <xs:attribute name="Name" type="ParameterNameEnumType" use="required"/>
+ </xs:complexType>
+ <xs:complexType name="StringParameterType">
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute name="Name" type="ParameterNameEnumType" use="required"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ <xs:group name="ParameterBlockGroup">
+ <xs:choice>
+ <xs:element name="BooleanParameter" type="BooleanParameterType"/>
+ <xs:element name="IntegerParameter" type="IntegerParameterType"/>
+ <xs:element name="EnumParameter" type="EnumParameterType"/>
+ <xs:element name="FixedPointParameter" type="PointParameterType"/>
+ <xs:element name="FloatingPointParameter" type="PointParameterType"/>
+ <xs:element name="BitParameterBlock" type="BitParameterBlockType">
+ <xs:unique name="BitParameterBlockSubElementsUniqueness">
+ <xs:selector xpath="*"/>
+ <xs:field xpath="@Name"/>
+ </xs:unique>
+ </xs:element>
+ <xs:element name="StringParameter" type="StringParameterType"/>
+ <!--xs:element name="Component" type="ParameterBlockType"/-->
+ <xs:element name="ParameterBlock" type="ParameterBlockType">
+ <xs:unique name="ParameterBlockSubElementsUniqueness">
+ <xs:selector xpath="*"/>
+ <xs:field xpath="@Name"/>
+ </xs:unique>
+ </xs:element>
+ </xs:choice>
+ </xs:group>
+ <xs:complexType name="ParameterBlockType">
+ <xs:sequence>
+ <xs:group ref="ParameterBlockGroup" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:attribute name="Name" type="xs:NMTOKEN" use="required"/>
+ </xs:complexType>
+ <!-- END ParameterSettings.xsd -->
+
+ <!-- BEGIN ConfigurableDomain.xsd -->
+ <xs:complexType name="SelectionCriterionRuleType">
+ <xs:attribute name="SelectionCriterion" type="xs:NMTOKEN" use="required"/>
+ <xs:attribute name="MatchesWhen" use="required">
+ <xs:simpleType name="MatchesWhenEnum">
+ <xs:restriction base="xs:NMTOKEN">
+ <xs:enumeration value="Is"/>
+ <xs:enumeration value="IsNot"/>
+ <xs:enumeration value="Includes"/>
+ <xs:enumeration value="Excludes"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ <xs:attribute name="Value" use="required" type="xs:NMTOKEN"/>
+ </xs:complexType>
+ <xs:group name="RuleGroup">
+ <xs:choice>
+ <xs:element name="CompoundRule" type="CompoundRuleType"/>
+ <xs:element name="SelectionCriterionRule" type="SelectionCriterionRuleType"/>
+ </xs:choice>
+ </xs:group>
+ <xs:complexType name="CompoundRuleType">
+ <xs:sequence>
+ <xs:group ref="RuleGroup" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:attribute name="Type">
+ <xs:simpleType name="TypeEnum">
+ <xs:restriction base="xs:NMTOKEN">
+ <xs:enumeration value="Any"/>
+ <xs:enumeration value="All"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ </xs:complexType>
+ <xs:complexType name="ConfigurationsType">
+ <xs:sequence>
+ <xs:element maxOccurs="unbounded" name="Configuration">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="CompoundRule" type="CompoundRuleType" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ <xs:attribute name="Name" use="required" type="xs:NCName"/>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:group name="ComponentGroup">
+ <xs:sequence>
+ <xs:group ref="ParameterBlockGroup"/>
+ </xs:sequence>
+ </xs:group>
+ <xs:complexType name="ComponentType">
+ <xs:sequence>
+ <xs:choice>
+ <xs:group ref="ComponentGroup" maxOccurs="unbounded"/>
+ <xs:element name="Subsystem" type="ComponentType" maxOccurs="unbounded"/>
+ </xs:choice>
+ </xs:sequence>
+ <xs:attribute name="Name" use="required" type="xs:NCName"/>
+ </xs:complexType>
+ <xs:complexType name="ConfigurableElementsType">
+ <xs:sequence>
+ <xs:element maxOccurs="unbounded" minOccurs="0" name="ConfigurableElement">
+ <xs:complexType>
+ <xs:attribute name="Path" use="required">
+ <xs:simpleType>
+ <xs:restriction base="xs:anyURI">
+ <xs:pattern value="/.*[^/]"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="ConfigurableElementSettingsType">
+ <xs:choice>
+ <xs:element name="BooleanParameter" type="BooleanParameterType"/>
+ <xs:element name="IntegerParameter" type="IntegerParameterType"/>
+ <xs:element name="EnumParameter" type="EnumParameterType"/>
+ <xs:element name="FixedPointParameter" type="PointParameterType"/>
+ <xs:element name="FloatingPointParameter" type="PointParameterType"/>
+ <xs:element name="BitParameter" type="IntegerParameterType"/>
+ <xs:element name="BitParameterBlock" type="BitParameterBlockType">
+ <xs:unique name="BitParameterBlockSubElementsUniqueness">
+ <xs:selector xpath="*"/>
+ <xs:field xpath="@Name"/>
+ </xs:unique>
+ </xs:element>
+ <xs:element name="StringParameter" type="StringParameterType"/>
+ <!--xs:element name="Component" type="ParameterBlockType"/-->
+ <xs:element name="ParameterBlock" type="ParameterBlockType">
+ <xs:unique name="ParameterBlockSubElementsUniqueness">
+ <xs:selector xpath="*"/>
+ <xs:field xpath="@Name"/>
+ </xs:unique>
+ </xs:element>
+ </xs:choice>
+ <!--xs:choice>
+ <xs:element name="BitParameter" type="IntegerParameterType"/>
+ <xs:group ref="ComponentGroup"/>
+ </xs:choice-->
+ <xs:attribute name="Path" use="required">
+ <xs:simpleType>
+ <xs:restriction base="xs:anyURI">
+ <xs:pattern value="/.*[^/]"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ </xs:complexType>
+ <xs:complexType name="SettingsType">
+ <xs:sequence>
+ <xs:element maxOccurs="unbounded" minOccurs="0" name="Configuration">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="ConfigurableElement" minOccurs="0" maxOccurs="unbounded" type="ConfigurableElementSettingsType"/>
+ </xs:sequence>
+ <xs:attribute name="Name" use="required" type="xs:NCName"/>
+ </xs:complexType>
+ <xs:unique name="ConfigurableElementUniqueness">
+ <xs:selector xpath="ConfigurableElement"/>
+ <xs:field xpath="@Path"/>
+ </xs:unique>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="ConfigurableDomainType">
+ <xs:sequence>
+ <xs:element name="Configurations" type="ConfigurationsType"/>
+ <xs:element name="ConfigurableElements" type="ConfigurableElementsType"/>
+ <xs:element name="Settings" type="SettingsType" minOccurs="0"/>
+ </xs:sequence>
+ <xs:attribute name="Name" use="required" type="xs:NCName"/>
+ <xs:attribute name="SequenceAware" use="optional" type="xs:boolean" default="false"/>
+ </xs:complexType>
+ <xs:element name="ConfigurableDomain" type="ConfigurableDomainType"/>
+ <!-- END ConfigurableDomain.xsd -->
+
+ <!-- BEGIN ConfigurableDomains.xsd -->
+ <xs:element name="ConfigurableDomains">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element maxOccurs="unbounded" name="ConfigurableDomain" type="ConfigurableDomainType">
+ <xs:key name="ConfigurableElementKey">
+ <xs:selector xpath="ConfigurableElements/ConfigurableElement"/>
+ <xs:field xpath="@Path"/>
+ </xs:key>
+ <xs:keyref refer="ConfigurableElementKey" name="ConfigurableDomainReference">
+ <xs:selector xpath="Settings/Configuration/ConfigurableElement"/>
+ <xs:field xpath="@Path"/>
+ </xs:keyref>
+ <xs:key name="ConfigurationKey">
+ <xs:selector xpath="Configurations/Configuration"/>
+ <xs:field xpath="@Name"/>
+ </xs:key>
+ <xs:keyref refer="ConfigurationKey" name="ConfigurationReference2">
+ <xs:selector xpath="ConfigurableElements/ConfigurableElement/Configuration"/>
+ <xs:field xpath="@Name"/>
+ </xs:keyref>
+ <xs:keyref refer="ConfigurationKey" name="ConfigurationReference">
+ <xs:selector xpath="Settings/Configuration"/>
+ <xs:field xpath="@Name"/>
+ </xs:keyref>
+ </xs:element>
+ </xs:sequence>
+ <xs:attribute name="SystemClassName" use="required" type="xs:NCName"/>
+ </xs:complexType>
+ <xs:unique name="ConfigurableDomainUniqueness">
+ <xs:selector xpath="ConfigurableDomain"/>
+ <xs:field xpath="@Name"/>
+ </xs:unique>
+ </xs:element>
+ <!-- END ConfigurableDomains.xsd -->
+
+ <xs:simpleType name="ParameterNameEnumType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="volume_profile"/>
+
+ <xs:enumeration value="communication"/>
+ <xs:enumeration value="ambient"/>
+ <xs:enumeration value="builtin_mic"/>
+ <xs:enumeration value="bluetooth_sco_headset"/>
+ <xs:enumeration value="wired_headset"/>
+ <xs:enumeration value="hdmi"/>
+ <xs:enumeration value="telephony_rx"/>
+ <xs:enumeration value="back_mic"/>
+ <xs:enumeration value="remote_submix"/>
+ <xs:enumeration value="anlg_dock_headset"/>
+ <xs:enumeration value="dgtl_dock_headset"/>
+ <xs:enumeration value="usb_accessory"/>
+ <xs:enumeration value="usb_device"/>
+ <xs:enumeration value="fm_tuner"/>
+ <xs:enumeration value="tv_tuner"/>
+ <xs:enumeration value="line"/>
+ <xs:enumeration value="spdif"/>
+ <xs:enumeration value="bluetooth_a2dp" />
+ <xs:enumeration value="loopback" />
+ <xs:enumeration value="ip" />
+ <xs:enumeration value="bus" />
+ <xs:enumeration value="proxy"/>
+ <xs:enumeration value="usb_headset"/>
+ <xs:enumeration value="bluetooth_ble"/>
+ <xs:enumeration value="hdmi_arc"/>
+ <xs:enumeration value="echo_reference"/>
+ <xs:enumeration value="ble_headset"/>
+ <xs:enumeration value="stub"/>
+ <xs:enumeration value="hdmi_earc"/>
+
+ <xs:enumeration value="device_address"/>
+
+ <xs:enumeration value="earpiece" />
+ <xs:enumeration value="speaker" />
+ <xs:enumeration value="wired_headphone" />
+ <xs:enumeration value="bluetooth_sco" />
+ <xs:enumeration value="bluetooth_sco_carkit"/>
+ <xs:enumeration value="bluetooth_a2dp_headphones"/>
+ <xs:enumeration value="bluetooth_a2dp_speaker"/>
+ <xs:enumeration value="telephony_tx"/>
+ <xs:enumeration value="fm"/>
+ <xs:enumeration value="aux_line"/>
+ <xs:enumeration value="speaker_safe"/>
+ <xs:enumeration value="hearing_aid" />
+ <xs:enumeration value="echo_canceller" />
+ <xs:enumeration value="ble_speaker" />
+ <xs:enumeration value="ble_broadcast" />
+ </xs:restriction>
+ </xs:simpleType>
+</xs:schema>
diff --git a/audio/aidl/default/config/audioPolicy/capengine/api/current.txt b/audio/aidl/default/config/audioPolicy/capengine/api/current.txt
new file mode 100644
index 0000000..481abbf
--- /dev/null
+++ b/audio/aidl/default/config/audioPolicy/capengine/api/current.txt
@@ -0,0 +1,264 @@
+// Signature format: 2.0
+package android.audio.policy.capengine.configuration {
+
+ public class BitParameterBlockType {
+ ctor public BitParameterBlockType();
+ method @Nullable public java.util.List<android.audio.policy.capengine.configuration.IntegerParameterType> getBitParameter();
+ method @Nullable public android.audio.policy.capengine.configuration.ParameterNameEnumType getName();
+ method public void setName(@Nullable android.audio.policy.capengine.configuration.ParameterNameEnumType);
+ }
+
+ public class BooleanParameterType {
+ ctor public BooleanParameterType();
+ method @Nullable public android.audio.policy.capengine.configuration.ParameterNameEnumType getName();
+ method @Nullable public String getValue();
+ method public void setName(@Nullable android.audio.policy.capengine.configuration.ParameterNameEnumType);
+ method public void setValue(@Nullable String);
+ }
+
+ public class ComponentType {
+ ctor public ComponentType();
+ method @Nullable public String getName();
+ method @Nullable public java.util.List<android.audio.policy.capengine.configuration.ComponentType> getSubsystem_optional();
+ method public void setName(@Nullable String);
+ }
+
+ public class CompoundRuleType {
+ ctor public CompoundRuleType();
+ method @Nullable public android.audio.policy.capengine.configuration.CompoundRuleType getCompoundRule_optional();
+ method @Nullable public android.audio.policy.capengine.configuration.SelectionCriterionRuleType getSelectionCriterionRule_optional();
+ method @Nullable public android.audio.policy.capengine.configuration.TypeEnum getType();
+ method public void setCompoundRule_optional(@Nullable android.audio.policy.capengine.configuration.CompoundRuleType);
+ method public void setSelectionCriterionRule_optional(@Nullable android.audio.policy.capengine.configuration.SelectionCriterionRuleType);
+ method public void setType(@Nullable android.audio.policy.capengine.configuration.TypeEnum);
+ }
+
+ public class ConfigurableDomainType {
+ ctor public ConfigurableDomainType();
+ method @Nullable public android.audio.policy.capengine.configuration.ConfigurableElementsType getConfigurableElements();
+ method @Nullable public android.audio.policy.capengine.configuration.ConfigurationsType getConfigurations();
+ method @Nullable public String getName();
+ method @Nullable public boolean getSequenceAware();
+ method @Nullable public android.audio.policy.capengine.configuration.SettingsType getSettings();
+ method public void setConfigurableElements(@Nullable android.audio.policy.capengine.configuration.ConfigurableElementsType);
+ method public void setConfigurations(@Nullable android.audio.policy.capengine.configuration.ConfigurationsType);
+ method public void setName(@Nullable String);
+ method public void setSequenceAware(@Nullable boolean);
+ method public void setSettings(@Nullable android.audio.policy.capengine.configuration.SettingsType);
+ }
+
+ public class ConfigurableDomains {
+ ctor public ConfigurableDomains();
+ method @Nullable public java.util.List<android.audio.policy.capengine.configuration.ConfigurableDomainType> getConfigurableDomain();
+ method @Nullable public String getSystemClassName();
+ method public void setSystemClassName(@Nullable String);
+ }
+
+ public class ConfigurableElementSettingsType {
+ ctor public ConfigurableElementSettingsType();
+ method @Nullable public android.audio.policy.capengine.configuration.BitParameterBlockType getBitParameterBlock_optional();
+ method @Nullable public android.audio.policy.capengine.configuration.IntegerParameterType getBitParameter_optional();
+ method @Nullable public android.audio.policy.capengine.configuration.BooleanParameterType getBooleanParameter_optional();
+ method @Nullable public android.audio.policy.capengine.configuration.EnumParameterType getEnumParameter_optional();
+ method @Nullable public android.audio.policy.capengine.configuration.PointParameterType getFixedPointParameter_optional();
+ method @Nullable public android.audio.policy.capengine.configuration.PointParameterType getFloatingPointParameter_optional();
+ method @Nullable public android.audio.policy.capengine.configuration.IntegerParameterType getIntegerParameter_optional();
+ method @Nullable public android.audio.policy.capengine.configuration.ParameterBlockType getParameterBlock_optional();
+ method @Nullable public String getPath();
+ method @Nullable public android.audio.policy.capengine.configuration.StringParameterType getStringParameter_optional();
+ method public void setBitParameterBlock_optional(@Nullable android.audio.policy.capengine.configuration.BitParameterBlockType);
+ method public void setBitParameter_optional(@Nullable android.audio.policy.capengine.configuration.IntegerParameterType);
+ method public void setBooleanParameter_optional(@Nullable android.audio.policy.capengine.configuration.BooleanParameterType);
+ method public void setEnumParameter_optional(@Nullable android.audio.policy.capengine.configuration.EnumParameterType);
+ method public void setFixedPointParameter_optional(@Nullable android.audio.policy.capengine.configuration.PointParameterType);
+ method public void setFloatingPointParameter_optional(@Nullable android.audio.policy.capengine.configuration.PointParameterType);
+ method public void setIntegerParameter_optional(@Nullable android.audio.policy.capengine.configuration.IntegerParameterType);
+ method public void setParameterBlock_optional(@Nullable android.audio.policy.capengine.configuration.ParameterBlockType);
+ method public void setPath(@Nullable String);
+ method public void setStringParameter_optional(@Nullable android.audio.policy.capengine.configuration.StringParameterType);
+ }
+
+ public class ConfigurableElementsType {
+ ctor public ConfigurableElementsType();
+ method @Nullable public java.util.List<android.audio.policy.capengine.configuration.ConfigurableElementsType.ConfigurableElement> getConfigurableElement();
+ }
+
+ public static class ConfigurableElementsType.ConfigurableElement {
+ ctor public ConfigurableElementsType.ConfigurableElement();
+ method @Nullable public String getPath();
+ method public void setPath(@Nullable String);
+ }
+
+ public class ConfigurationsType {
+ ctor public ConfigurationsType();
+ method @Nullable public java.util.List<android.audio.policy.capengine.configuration.ConfigurationsType.Configuration> getConfiguration();
+ }
+
+ public static class ConfigurationsType.Configuration {
+ ctor public ConfigurationsType.Configuration();
+ method @Nullable public android.audio.policy.capengine.configuration.CompoundRuleType getCompoundRule();
+ method @Nullable public String getName();
+ method public void setCompoundRule(@Nullable android.audio.policy.capengine.configuration.CompoundRuleType);
+ method public void setName(@Nullable String);
+ }
+
+ public class EnumParameterType {
+ ctor public EnumParameterType();
+ method @Nullable public android.audio.policy.capengine.configuration.ParameterNameEnumType getName();
+ method @Nullable public String getValue();
+ method public void setName(@Nullable android.audio.policy.capengine.configuration.ParameterNameEnumType);
+ method public void setValue(@Nullable String);
+ }
+
+ public class IntegerParameterType {
+ ctor public IntegerParameterType();
+ method @Nullable public android.audio.policy.capengine.configuration.ParameterNameEnumType getName();
+ method @Nullable public String getValue();
+ method public void setName(@Nullable android.audio.policy.capengine.configuration.ParameterNameEnumType);
+ method public void setValue(@Nullable String);
+ }
+
+ public enum LangEnum {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.audio.policy.capengine.configuration.LangEnum EMPTY;
+ }
+
+ public enum MatchesWhenEnum {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.audio.policy.capengine.configuration.MatchesWhenEnum Excludes;
+ enum_constant public static final android.audio.policy.capengine.configuration.MatchesWhenEnum Includes;
+ enum_constant public static final android.audio.policy.capengine.configuration.MatchesWhenEnum Is;
+ enum_constant public static final android.audio.policy.capengine.configuration.MatchesWhenEnum IsNot;
+ }
+
+ public class ParameterBlockType {
+ ctor public ParameterBlockType();
+ method @Nullable public android.audio.policy.capengine.configuration.BitParameterBlockType getBitParameterBlock_optional();
+ method @Nullable public android.audio.policy.capengine.configuration.BooleanParameterType getBooleanParameter_optional();
+ method @Nullable public android.audio.policy.capengine.configuration.EnumParameterType getEnumParameter_optional();
+ method @Nullable public android.audio.policy.capengine.configuration.PointParameterType getFixedPointParameter_optional();
+ method @Nullable public android.audio.policy.capengine.configuration.PointParameterType getFloatingPointParameter_optional();
+ method @Nullable public android.audio.policy.capengine.configuration.IntegerParameterType getIntegerParameter_optional();
+ method @Nullable public String getName();
+ method @Nullable public android.audio.policy.capengine.configuration.ParameterBlockType getParameterBlock_optional();
+ method @Nullable public android.audio.policy.capengine.configuration.StringParameterType getStringParameter_optional();
+ method public void setBitParameterBlock_optional(@Nullable android.audio.policy.capengine.configuration.BitParameterBlockType);
+ method public void setBooleanParameter_optional(@Nullable android.audio.policy.capengine.configuration.BooleanParameterType);
+ method public void setEnumParameter_optional(@Nullable android.audio.policy.capengine.configuration.EnumParameterType);
+ method public void setFixedPointParameter_optional(@Nullable android.audio.policy.capengine.configuration.PointParameterType);
+ method public void setFloatingPointParameter_optional(@Nullable android.audio.policy.capengine.configuration.PointParameterType);
+ method public void setIntegerParameter_optional(@Nullable android.audio.policy.capengine.configuration.IntegerParameterType);
+ method public void setName(@Nullable String);
+ method public void setParameterBlock_optional(@Nullable android.audio.policy.capengine.configuration.ParameterBlockType);
+ method public void setStringParameter_optional(@Nullable android.audio.policy.capengine.configuration.StringParameterType);
+ }
+
+ public enum ParameterNameEnumType {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType ambient;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType anlg_dock_headset;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType aux_line;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType back_mic;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType ble_broadcast;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType ble_headset;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType ble_speaker;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType bluetooth_a2dp;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType bluetooth_a2dp_headphones;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType bluetooth_a2dp_speaker;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType bluetooth_ble;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType bluetooth_sco;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType bluetooth_sco_carkit;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType bluetooth_sco_headset;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType builtin_mic;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType bus;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType communication;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType device_address;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType dgtl_dock_headset;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType earpiece;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType echo_canceller;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType echo_reference;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType fm;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType fm_tuner;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType hdmi;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType hdmi_arc;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType hdmi_earc;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType hearing_aid;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType ip;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType line;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType loopback;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType proxy;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType remote_submix;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType spdif;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType speaker;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType speaker_safe;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType stub;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType telephony_rx;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType telephony_tx;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType tv_tuner;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType usb_accessory;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType usb_device;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType usb_headset;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType volume_profile;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType wired_headphone;
+ enum_constant public static final android.audio.policy.capengine.configuration.ParameterNameEnumType wired_headset;
+ }
+
+ public class PointParameterType {
+ ctor public PointParameterType();
+ method @Nullable public android.audio.policy.capengine.configuration.ParameterNameEnumType getName();
+ method @Nullable public String getValue();
+ method public void setName(@Nullable android.audio.policy.capengine.configuration.ParameterNameEnumType);
+ method public void setValue(@Nullable String);
+ }
+
+ public class SelectionCriterionRuleType {
+ ctor public SelectionCriterionRuleType();
+ method @Nullable public android.audio.policy.capengine.configuration.MatchesWhenEnum getMatchesWhen();
+ method @Nullable public String getSelectionCriterion();
+ method @Nullable public String getValue();
+ method public void setMatchesWhen(@Nullable android.audio.policy.capengine.configuration.MatchesWhenEnum);
+ method public void setSelectionCriterion(@Nullable String);
+ method public void setValue(@Nullable String);
+ }
+
+ public class SettingsType {
+ ctor public SettingsType();
+ method @Nullable public java.util.List<android.audio.policy.capengine.configuration.SettingsType.Configuration> getConfiguration();
+ }
+
+ public static class SettingsType.Configuration {
+ ctor public SettingsType.Configuration();
+ method @Nullable public java.util.List<android.audio.policy.capengine.configuration.ConfigurableElementSettingsType> getConfigurableElement();
+ method @Nullable public String getName();
+ method public void setName(@Nullable String);
+ }
+
+ public enum SpaceEnum {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.audio.policy.capengine.configuration.SpaceEnum _default;
+ enum_constant public static final android.audio.policy.capengine.configuration.SpaceEnum preserve;
+ }
+
+ public class StringParameterType {
+ ctor public StringParameterType();
+ method @Nullable public android.audio.policy.capengine.configuration.ParameterNameEnumType getName();
+ method @Nullable public String getValue();
+ method public void setName(@Nullable android.audio.policy.capengine.configuration.ParameterNameEnumType);
+ method public void setValue(@Nullable String);
+ }
+
+ public enum TypeEnum {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.audio.policy.capengine.configuration.TypeEnum All;
+ enum_constant public static final android.audio.policy.capengine.configuration.TypeEnum Any;
+ }
+
+ public class XmlParser {
+ ctor public XmlParser();
+ method @Nullable public static android.audio.policy.capengine.configuration.ConfigurableDomains readConfigurableDomains(@NonNull java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ method @Nullable public static String readText(@NonNull org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ method public static void skip(@NonNull org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ }
+
+}
+
diff --git a/audio/aidl/default/config/audioPolicy/capengine/api/last_current.txt b/audio/aidl/default/config/audioPolicy/capengine/api/last_current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/audio/aidl/default/config/audioPolicy/capengine/api/last_current.txt
diff --git a/audio/aidl/default/config/audioPolicy/capengine/api/last_removed.txt b/audio/aidl/default/config/audioPolicy/capengine/api/last_removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/audio/aidl/default/config/audioPolicy/capengine/api/last_removed.txt
diff --git a/audio/aidl/default/config/audioPolicy/capengine/api/removed.txt b/audio/aidl/default/config/audioPolicy/capengine/api/removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/audio/aidl/default/config/audioPolicy/capengine/api/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/audio/aidl/default/config/audioPolicy/engine/api/current.txt b/audio/aidl/default/config/audioPolicy/engine/api/current.txt
index 063b05d..8e0e9a2 100644
--- a/audio/aidl/default/config/audioPolicy/engine/api/current.txt
+++ b/audio/aidl/default/config/audioPolicy/engine/api/current.txt
@@ -162,7 +162,9 @@
public static class ProductStrategies.ProductStrategy {
ctor public ProductStrategies.ProductStrategy();
method @Nullable public java.util.List<android.audio.policy.engine.configuration.AttributesGroup> getAttributesGroup();
+ method @Nullable public int getId();
method @Nullable public String getName();
+ method public void setId(@Nullable int);
method public void setName(@Nullable String);
}
diff --git a/audio/aidl/default/config/audioPolicy/engine/audio_policy_engine_configuration.xsd b/audio/aidl/default/config/audioPolicy/engine/audio_policy_engine_configuration.xsd
index 40396bb..e2508ea 100644
--- a/audio/aidl/default/config/audioPolicy/engine/audio_policy_engine_configuration.xsd
+++ b/audio/aidl/default/config/audioPolicy/engine/audio_policy_engine_configuration.xsd
@@ -105,6 +105,7 @@
<xs:element name="AttributesGroup" type="AttributesGroup" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
+ <xs:attribute name="id" type="xs:int" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
@@ -188,6 +189,19 @@
</xs:sequence>
</xs:complexType>
<xs:complexType name="valueType">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Criterion type is provided as a tuple of 'human readable' string (referred as the
+ literal part, that will allow to express 'human readable' rules, numerical value
+ associated in order to improve performances of the parameter framework library used,
+ and an optional android type.
+ This android type is reserved for device type mapping with parameter framework
+ representation on a bitfield (Only one bit is expected to represent a device) and
+ android representation of a type that may use several bits.
+ The lookup table will allow wrap android device type to parameter framework device
+ types data model.
+ </xs:documentation>
+ </xs:annotation>
<xs:attribute name="literal" type="xs:string" use="required"/>
<xs:attribute name="numerical" type="xs:long" use="required"/>
<xs:attribute name="android_type" type="longDecimalOrHexType" use="optional"/>
diff --git a/audio/aidl/default/StreamSwitcher.cpp b/audio/aidl/default/deprecated/StreamSwitcher.cpp
similarity index 95%
rename from audio/aidl/default/StreamSwitcher.cpp
rename to audio/aidl/default/deprecated/StreamSwitcher.cpp
index 8ba15a8..f1e0f52 100644
--- a/audio/aidl/default/StreamSwitcher.cpp
+++ b/audio/aidl/default/deprecated/StreamSwitcher.cpp
@@ -23,12 +23,12 @@
#include <error/expected_utils.h>
#include "core-impl/StreamStub.h"
-#include "core-impl/StreamSwitcher.h"
+#include "deprecated/StreamSwitcher.h"
using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::media::audio::common::AudioDevice;
-namespace aidl::android::hardware::audio::core {
+namespace aidl::android::hardware::audio::core::deprecated {
StreamSwitcher::StreamSwitcher(StreamContext* context, const Metadata& metadata)
: mContext(context),
@@ -260,4 +260,12 @@
return mStream->bluetoothParametersUpdated();
}
-} // namespace aidl::android::hardware::audio::core
+ndk::ScopedAStatus StreamSwitcher::setGain(float gain) {
+ if (mStream == nullptr) {
+ LOG(ERROR) << __func__ << ": stream was closed";
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+ }
+ return mStream->setGain(gain);
+}
+
+} // namespace aidl::android::hardware::audio::core::deprecated
diff --git a/audio/aidl/default/include/core-impl/StreamSwitcher.h b/audio/aidl/default/deprecated/StreamSwitcher.h
similarity index 95%
rename from audio/aidl/default/include/core-impl/StreamSwitcher.h
rename to audio/aidl/default/deprecated/StreamSwitcher.h
index 5764ad6..56fdd23 100644
--- a/audio/aidl/default/include/core-impl/StreamSwitcher.h
+++ b/audio/aidl/default/deprecated/StreamSwitcher.h
@@ -14,11 +14,18 @@
* limitations under the License.
*/
+/**
+ ** This class is deprecated because its use causes threading issues
+ ** with the FMQ due to change of threads reading and writing into FMQ.
+ **
+ ** DO NOT USE. These files will be removed.
+ **/
+
#pragma once
-#include "Stream.h"
+#include "core-impl/Stream.h"
-namespace aidl::android::hardware::audio::core {
+namespace aidl::android::hardware::audio::core::deprecated {
// 'StreamSwitcher' is an implementation of 'StreamCommonInterface' which allows
// dynamically switching the underlying stream implementation based on currently
@@ -130,6 +137,7 @@
const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices)
override;
ndk::ScopedAStatus bluetoothParametersUpdated() override;
+ ndk::ScopedAStatus setGain(float gain) override;
protected:
// Since switching a stream requires closing down the current stream, StreamSwitcher
@@ -191,4 +199,4 @@
bool mBluetoothParametersUpdated = false;
};
-} // namespace aidl::android::hardware::audio::core
+} // namespace aidl::android::hardware::audio::core::deprecated
diff --git a/audio/aidl/default/include/core-impl/CapEngineConfigXmlConverter.h b/audio/aidl/default/include/core-impl/CapEngineConfigXmlConverter.h
new file mode 100644
index 0000000..e5da4f4
--- /dev/null
+++ b/audio/aidl/default/include/core-impl/CapEngineConfigXmlConverter.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/audio/core/BnConfig.h>
+#include <aidl/android/media/audio/common/AudioHalEngineConfig.h>
+#include <system/audio_config.h>
+
+#include <android_audio_policy_capengine_configuration.h>
+#include <android_audio_policy_capengine_configuration_enums.h>
+
+#include "EngineConfigXmlConverter.h"
+
+namespace aidl::android::hardware::audio::core::internal {
+
+namespace capconfiguration = ::android::audio::policy::capengine::configuration;
+namespace aidlcommon = ::aidl::android::media::audio::common;
+
+class CapEngineConfigXmlConverter {
+ public:
+ explicit CapEngineConfigXmlConverter(const std::string& configFilePath)
+ : mConverter(configFilePath, &capconfiguration::readConfigurableDomains) {
+ if (mConverter.getXsdcConfig()) {
+ init();
+ }
+ }
+ std::string getError() const { return mConverter.getError(); }
+ ::android::status_t getStatus() const { return mConverter.getStatus(); }
+
+ std::optional<
+ std::vector<std::optional<::aidl::android::media::audio::common::AudioHalCapDomain>>>&
+ getAidlCapEngineConfig();
+
+ private:
+ ConversionResult<std::vector<aidlcommon::AudioHalCapParameter>> convertSettingToAidl(
+ const capconfiguration::SettingsType::Configuration& xsdcSetting);
+
+ ConversionResult<std::vector<aidlcommon::AudioHalCapConfiguration>> convertConfigurationsToAidl(
+ const std::vector<capconfiguration::ConfigurationsType>& xsdcConfigurationsVec,
+ const std::vector<capconfiguration::SettingsType>& xsdcSettingsVec);
+
+ ConversionResult<aidlcommon::AudioHalCapConfiguration> convertConfigurationToAidl(
+ const capconfiguration::ConfigurationsType::Configuration& xsdcConfiguration,
+ const capconfiguration::SettingsType::Configuration& xsdcSettingConfiguration);
+
+ ConversionResult<aidlcommon::AudioHalCapParameter> convertParamToAidl(
+ const capconfiguration::ConfigurableElementSettingsType& element);
+
+ ConversionResult<aidlcommon::AudioHalCapConfiguration> convertConfigurationToAidl(
+ const capconfiguration::ConfigurationsType::Configuration& xsdcConfiguration);
+ ConversionResult<aidlcommon::AudioHalCapDomain> convertConfigurableDomainToAidl(
+ const capconfiguration::ConfigurableDomainType& xsdcConfigurableDomain);
+
+ const std::optional<capconfiguration::ConfigurableDomains>& getXsdcConfig() {
+ return mConverter.getXsdcConfig();
+ }
+ void init();
+
+ std::optional<std::vector<std::optional<aidlcommon::AudioHalCapDomain>>> mAidlCapDomains;
+ XmlConverter<capconfiguration::ConfigurableDomains> mConverter;
+};
+} // namespace aidl::android::hardware::audio::core::internal
diff --git a/audio/aidl/default/include/core-impl/DriverStubImpl.h b/audio/aidl/default/include/core-impl/DriverStubImpl.h
new file mode 100644
index 0000000..40a9fea
--- /dev/null
+++ b/audio/aidl/default/include/core-impl/DriverStubImpl.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "core-impl/Stream.h"
+
+namespace aidl::android::hardware::audio::core {
+
+class DriverStubImpl : virtual public DriverInterface {
+ public:
+ explicit DriverStubImpl(const StreamContext& context);
+
+ ::android::status_t init() override;
+ ::android::status_t drain(StreamDescriptor::DrainMode) override;
+ ::android::status_t flush() override;
+ ::android::status_t pause() override;
+ ::android::status_t standby() override;
+ ::android::status_t start() override;
+ ::android::status_t transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
+ int32_t* latencyMs) override;
+ void shutdown() override;
+
+ private:
+ const size_t mBufferSizeFrames;
+ const size_t mFrameSizeBytes;
+ const int mSampleRate;
+ const bool mIsAsynchronous;
+ const bool mIsInput;
+ bool mIsInitialized = false; // Used for validating the state machine logic.
+ bool mIsStandby = true; // Used for validating the state machine logic.
+ int64_t mStartTimeNs = 0;
+ long mFramesSinceStart = 0;
+};
+
+} // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/include/core-impl/EngineConfigXmlConverter.h b/audio/aidl/default/include/core-impl/EngineConfigXmlConverter.h
index 22ac8cb..211c16f 100644
--- a/audio/aidl/default/include/core-impl/EngineConfigXmlConverter.h
+++ b/audio/aidl/default/include/core-impl/EngineConfigXmlConverter.h
@@ -59,6 +59,7 @@
ConversionResult<::aidl::android::media::audio::common::AudioHalProductStrategy>
convertProductStrategyToAidl(const ::android::audio::policy::engine::configuration::
ProductStrategies::ProductStrategy& xsdcProductStrategy);
+ ConversionResult<int> convertProductStrategyIdToAidl(int xsdcId);
ConversionResult<int> convertProductStrategyNameToAidl(
const std::string& xsdcProductStrategyName);
ConversionResult<::aidl::android::media::audio::common::AudioHalVolumeCurve>
diff --git a/audio/aidl/default/include/core-impl/Module.h b/audio/aidl/default/include/core-impl/Module.h
index 00eeb4e..8548aff 100644
--- a/audio/aidl/default/include/core-impl/Module.h
+++ b/audio/aidl/default/include/core-impl/Module.h
@@ -263,6 +263,9 @@
::aidl::android::media::audio::common::AudioPortConfig* out_suggested, bool* applied);
ndk::ScopedAStatus updateStreamsConnectedState(const AudioPatch& oldPatch,
const AudioPatch& newPatch);
+ bool setAudioPortConfigGain(
+ const ::aidl::android::media::audio::common::AudioPort& port,
+ const ::aidl::android::media::audio::common::AudioGainConfig& gainRequested);
};
std::ostream& operator<<(std::ostream& os, Module::Type t);
diff --git a/audio/aidl/default/include/core-impl/Stream.h b/audio/aidl/default/include/core-impl/Stream.h
index 6b45866..f7b9269 100644
--- a/audio/aidl/default/include/core-impl/Stream.h
+++ b/audio/aidl/default/include/core-impl/Stream.h
@@ -38,6 +38,7 @@
#include <aidl/android/media/audio/common/AudioIoFlags.h>
#include <aidl/android/media/audio/common/AudioOffloadInfo.h>
#include <aidl/android/media/audio/common/MicrophoneInfo.h>
+#include <android-base/thread_annotations.h>
#include <error/expected_utils.h>
#include <fmq/AidlMessageQueue.h>
#include <system/thread_defs.h>
@@ -132,6 +133,9 @@
ReplyMQ* getReplyMQ() const { return mReplyMQ.get(); }
int getTransientStateDelayMs() const { return mDebugParameters.transientStateDelayMs; }
int getSampleRate() const { return mSampleRate; }
+ bool isInput() const {
+ return mFlags.getTag() == ::aidl::android::media::audio::common::AudioIoFlags::input;
+ }
bool isValid() const;
// 'reset' is called on a Binder thread when closing the stream. Does not use
// locking because it only cleans MQ pointers which were also set on the Binder thread.
@@ -245,7 +249,7 @@
virtual StreamDescriptor::State setClosed() = 0;
virtual bool start() = 0;
virtual pid_t getTid() = 0;
- virtual void stop() = 0;
+ virtual void join() = 0;
virtual std::string getError() = 0;
};
@@ -265,7 +269,7 @@
return WorkerImpl::start(WorkerImpl::kThreadName, ANDROID_PRIORITY_URGENT_AUDIO);
}
pid_t getTid() override { return WorkerImpl::getTid(); }
- void stop() override { return WorkerImpl::stop(); }
+ void join() override { return WorkerImpl::join(); }
std::string getError() override { return WorkerImpl::getError(); }
};
@@ -342,6 +346,7 @@
virtual ndk::ScopedAStatus setConnectedDevices(
const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices) = 0;
virtual ndk::ScopedAStatus bluetoothParametersUpdated() = 0;
+ virtual ndk::ScopedAStatus setGain(float gain) = 0;
};
// This is equivalent to automatically generated 'IStreamCommonDelegator' but uses
@@ -443,6 +448,7 @@
const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices)
override;
ndk::ScopedAStatus bluetoothParametersUpdated() override;
+ ndk::ScopedAStatus setGain(float gain) override;
protected:
static StreamWorkerInterface::CreateInstance getDefaultInWorkerCreator() {
@@ -457,6 +463,11 @@
}
virtual void onClose(StreamDescriptor::State statePriorToClosing) = 0;
+ // Any stream class implementing 'DriverInterface::shutdown' must call 'cleanupWorker' in
+ // the destructor in order to stop and join the worker thread in the case when the client
+ // has not called 'IStreamCommon::close' method.
+ void cleanupWorker();
+ void stopAndJoinWorker();
void stopWorker();
const StreamContext& mContext;
@@ -464,6 +475,9 @@
std::unique_ptr<StreamWorkerInterface> mWorker;
ChildInterface<StreamCommonDelegator> mCommon;
ConnectedDevices mConnectedDevices;
+
+ private:
+ std::atomic<bool> mWorkerStopIssued = false;
};
// Note: 'StreamIn/Out' can not be used on their own. Instead, they must be used for defining
@@ -601,6 +615,12 @@
return ndk::ScopedAStatus::ok();
}
+ ndk::ScopedAStatus setGain(float gain) {
+ auto s = mStream.lock();
+ if (s) return s->setGain(gain);
+ return ndk::ScopedAStatus::ok();
+ }
+
private:
std::weak_ptr<StreamCommonInterface> mStream;
ndk::SpAIBinder mStreamBinder;
@@ -636,6 +656,12 @@
return isOk ? ndk::ScopedAStatus::ok()
: ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
+ ndk::ScopedAStatus setGain(int32_t portId, float gain) {
+ if (auto it = mStreams.find(portId); it != mStreams.end()) {
+ return it->second.setGain(gain);
+ }
+ return ndk::ScopedAStatus::ok();
+ }
private:
// Maps port ids and port config ids to streams. Multimap because a port
diff --git a/audio/aidl/default/include/core-impl/StreamAlsa.h b/audio/aidl/default/include/core-impl/StreamAlsa.h
index 2c3b284..8bdf208 100644
--- a/audio/aidl/default/include/core-impl/StreamAlsa.h
+++ b/audio/aidl/default/include/core-impl/StreamAlsa.h
@@ -32,6 +32,8 @@
class StreamAlsa : public StreamCommonImpl {
public:
StreamAlsa(StreamContext* context, const Metadata& metadata, int readWriteRetries);
+ ~StreamAlsa();
+
// Methods of 'DriverInterface'.
::android::status_t init() override;
::android::status_t drain(StreamDescriptor::DrainMode) override;
@@ -43,6 +45,7 @@
int32_t* latencyMs) override;
::android::status_t refinePosition(StreamDescriptor::Position* position) override;
void shutdown() override;
+ ndk::ScopedAStatus setGain(float gain) override;
protected:
// Called from 'start' to initialize 'mAlsaDeviceProxies', the vector must be non-empty.
@@ -56,6 +59,9 @@
const int mReadWriteRetries;
// All fields below are only used on the worker thread.
std::vector<alsa::DeviceProxy> mAlsaDeviceProxies;
+
+ private:
+ std::atomic<float> mGain = 1.0;
};
} // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/include/core-impl/StreamBluetooth.h b/audio/aidl/default/include/core-impl/StreamBluetooth.h
index 7f4239c..357a546 100644
--- a/audio/aidl/default/include/core-impl/StreamBluetooth.h
+++ b/audio/aidl/default/include/core-impl/StreamBluetooth.h
@@ -41,6 +41,8 @@
const std::shared_ptr<::android::bluetooth::audio::aidl::BluetoothAudioPortAidl>&
btDeviceProxy,
const ::aidl::android::hardware::bluetooth::audio::PcmConfiguration& pcmConfig);
+ ~StreamBluetooth();
+
// Methods of 'DriverInterface'.
::android::status_t init() override;
::android::status_t drain(StreamDescriptor::DrainMode) override;
diff --git a/audio/aidl/default/include/core-impl/StreamPrimary.h b/audio/aidl/default/include/core-impl/StreamPrimary.h
index 8d5c57d..4f19a46 100644
--- a/audio/aidl/default/include/core-impl/StreamPrimary.h
+++ b/audio/aidl/default/include/core-impl/StreamPrimary.h
@@ -16,10 +16,14 @@
#pragma once
+#include <mutex>
#include <vector>
+#include <android-base/thread_annotations.h>
+
+#include "DriverStubImpl.h"
#include "StreamAlsa.h"
-#include "StreamSwitcher.h"
+#include "primary/PrimaryMixer.h"
namespace aidl::android::hardware::audio::core {
@@ -27,21 +31,54 @@
public:
StreamPrimary(StreamContext* context, const Metadata& metadata);
+ // Methods of 'DriverInterface'.
+ ::android::status_t init() override;
+ ::android::status_t drain(StreamDescriptor::DrainMode mode) override;
+ ::android::status_t flush() override;
+ ::android::status_t pause() override;
+ ::android::status_t standby() override;
::android::status_t start() override;
::android::status_t transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
int32_t* latencyMs) override;
::android::status_t refinePosition(StreamDescriptor::Position* position) override;
+ void shutdown() override;
+
+ // Overridden methods of 'StreamCommonImpl', called on a Binder thread.
+ ndk::ScopedAStatus setConnectedDevices(const ConnectedDevices& devices) override;
protected:
std::vector<alsa::DeviceProfile> getDeviceProfiles() override;
+ bool isStubStream();
const bool mIsAsynchronous;
int64_t mStartTimeNs = 0;
long mFramesSinceStart = 0;
bool mSkipNextTransfer = false;
+
+ private:
+ using AlsaDeviceId = std::pair<int, int>;
+
+ static constexpr StreamPrimary::AlsaDeviceId kDefaultCardAndDeviceId{
+ primary::PrimaryMixer::kAlsaCard, primary::PrimaryMixer::kAlsaDevice};
+ static constexpr StreamPrimary::AlsaDeviceId kStubDeviceId{
+ primary::PrimaryMixer::kInvalidAlsaCard, primary::PrimaryMixer::kInvalidAlsaDevice};
+
+ static AlsaDeviceId getCardAndDeviceId(
+ const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices);
+ static bool useStubStream(bool isInput,
+ const ::aidl::android::media::audio::common::AudioDevice& device);
+
+ bool isStubStreamOnWorker() const { return mCurrAlsaDeviceId == kStubDeviceId; }
+
+ DriverStubImpl mStubDriver;
+ mutable std::mutex mLock;
+ AlsaDeviceId mAlsaDeviceId GUARDED_BY(mLock) = kStubDeviceId;
+
+ // Used by the worker thread only.
+ AlsaDeviceId mCurrAlsaDeviceId = kStubDeviceId;
};
-class StreamInPrimary final : public StreamIn, public StreamSwitcher, public StreamInHwGainHelper {
+class StreamInPrimary final : public StreamIn, public StreamPrimary, public StreamInHwGainHelper {
public:
friend class ndk::SharedRefBase;
StreamInPrimary(
@@ -50,14 +87,6 @@
const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones);
private:
- static bool useStubStream(const ::aidl::android::media::audio::common::AudioDevice& device);
-
- DeviceSwitchBehavior switchCurrentStream(
- const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices)
- override;
- std::unique_ptr<StreamCommonInterfaceEx> createNewStream(
- const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices,
- StreamContext* context, const Metadata& metadata) override;
void onClose(StreamDescriptor::State) override { defaultOnClose(); }
ndk::ScopedAStatus getHwGain(std::vector<float>* _aidl_return) override;
@@ -65,7 +94,7 @@
};
class StreamOutPrimary final : public StreamOut,
- public StreamSwitcher,
+ public StreamPrimary,
public StreamOutHwVolumeHelper {
public:
friend class ndk::SharedRefBase;
@@ -75,22 +104,10 @@
offloadInfo);
private:
- static bool useStubStream(const ::aidl::android::media::audio::common::AudioDevice& device);
-
- DeviceSwitchBehavior switchCurrentStream(
- const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices)
- override;
- std::unique_ptr<StreamCommonInterfaceEx> createNewStream(
- const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices,
- StreamContext* context, const Metadata& metadata) override;
void onClose(StreamDescriptor::State) override { defaultOnClose(); }
ndk::ScopedAStatus getHwVolume(std::vector<float>* _aidl_return) override;
ndk::ScopedAStatus setHwVolume(const std::vector<float>& in_channelVolumes) override;
-
- ndk::ScopedAStatus setConnectedDevices(
- const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices)
- override;
};
} // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h b/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h
index 0d50c96..e78e8b7 100644
--- a/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h
+++ b/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h
@@ -16,20 +16,21 @@
#pragma once
+#include <atomic>
+#include <mutex>
#include <vector>
#include "core-impl/Stream.h"
-#include "core-impl/StreamSwitcher.h"
#include "r_submix/SubmixRoute.h"
namespace aidl::android::hardware::audio::core {
class StreamRemoteSubmix : public StreamCommonImpl {
public:
- StreamRemoteSubmix(
- StreamContext* context, const Metadata& metadata,
- const ::aidl::android::media::audio::common::AudioDeviceAddress& deviceAddress);
+ StreamRemoteSubmix(StreamContext* context, const Metadata& metadata);
+ ~StreamRemoteSubmix();
+ // Methods of 'DriverInterface'.
::android::status_t init() override;
::android::status_t drain(StreamDescriptor::DrainMode) override;
::android::status_t flush() override;
@@ -43,17 +44,18 @@
// Overridden methods of 'StreamCommonImpl', called on a Binder thread.
ndk::ScopedAStatus prepareToClose() override;
+ ndk::ScopedAStatus setConnectedDevices(const ConnectedDevices& devices) override;
private:
long getDelayInUsForFrameCount(size_t frameCount);
+ ::aidl::android::media::audio::common::AudioDeviceAddress getDeviceAddress() const {
+ std::lock_guard guard(mLock);
+ return mDeviceAddress;
+ }
size_t getStreamPipeSizeInFrames();
- ::android::status_t outWrite(void* buffer, size_t frameCount, size_t* actualFrameCount);
::android::status_t inRead(void* buffer, size_t frameCount, size_t* actualFrameCount);
-
- const ::aidl::android::media::audio::common::AudioDeviceAddress mDeviceAddress;
- const bool mIsInput;
- r_submix::AudioConfig mStreamConfig;
- std::shared_ptr<r_submix::SubmixRoute> mCurrentRoute = nullptr;
+ ::android::status_t outWrite(void* buffer, size_t frameCount, size_t* actualFrameCount);
+ ::android::status_t setCurrentRoute();
// Limit for the number of error log entries to avoid spamming the logs.
static constexpr int kMaxErrorLogs = 5;
@@ -64,6 +66,15 @@
// 5ms between two read attempts when pipe is empty
static constexpr int kReadAttemptSleepUs = 5000;
+ const bool mIsInput;
+ const r_submix::AudioConfig mStreamConfig;
+
+ mutable std::mutex mLock;
+ ::aidl::android::media::audio::common::AudioDeviceAddress mDeviceAddress GUARDED_BY(mLock);
+ std::atomic<bool> mDeviceAddressUpdated = false;
+
+ // Used by the worker thread only.
+ std::shared_ptr<r_submix::SubmixRoute> mCurrentRoute = nullptr;
int64_t mStartTimeNs = 0;
long mFramesSinceStart = 0;
int mReadErrorCount = 0;
@@ -71,7 +82,7 @@
int mWriteShutdownCount = 0;
};
-class StreamInRemoteSubmix final : public StreamIn, public StreamSwitcher {
+class StreamInRemoteSubmix final : public StreamIn, public StreamRemoteSubmix {
public:
friend class ndk::SharedRefBase;
StreamInRemoteSubmix(
@@ -80,19 +91,13 @@
const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones);
private:
- DeviceSwitchBehavior switchCurrentStream(
- const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices)
- override;
- std::unique_ptr<StreamCommonInterfaceEx> createNewStream(
- const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices,
- StreamContext* context, const Metadata& metadata) override;
void onClose(StreamDescriptor::State) override { defaultOnClose(); }
ndk::ScopedAStatus getActiveMicrophones(
std::vector<::aidl::android::media::audio::common::MicrophoneDynamicInfo>* _aidl_return)
override;
};
-class StreamOutRemoteSubmix final : public StreamOut, public StreamSwitcher {
+class StreamOutRemoteSubmix final : public StreamOut, public StreamRemoteSubmix {
public:
friend class ndk::SharedRefBase;
StreamOutRemoteSubmix(
@@ -102,12 +107,6 @@
offloadInfo);
private:
- DeviceSwitchBehavior switchCurrentStream(
- const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices)
- override;
- std::unique_ptr<StreamCommonInterfaceEx> createNewStream(
- const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices,
- StreamContext* context, const Metadata& metadata) override;
void onClose(StreamDescriptor::State) override { defaultOnClose(); }
};
diff --git a/audio/aidl/default/include/core-impl/StreamStub.h b/audio/aidl/default/include/core-impl/StreamStub.h
index 3857e0e..cee44db 100644
--- a/audio/aidl/default/include/core-impl/StreamStub.h
+++ b/audio/aidl/default/include/core-impl/StreamStub.h
@@ -16,32 +16,15 @@
#pragma once
+#include "core-impl/DriverStubImpl.h"
#include "core-impl/Stream.h"
namespace aidl::android::hardware::audio::core {
-class StreamStub : public StreamCommonImpl {
+class StreamStub : public StreamCommonImpl, public DriverStubImpl {
public:
StreamStub(StreamContext* context, const Metadata& metadata);
- // Methods of 'DriverInterface'.
- ::android::status_t init() override;
- ::android::status_t drain(StreamDescriptor::DrainMode) override;
- ::android::status_t flush() override;
- ::android::status_t pause() override;
- ::android::status_t standby() override;
- ::android::status_t start() override;
- ::android::status_t transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
- int32_t* latencyMs) override;
- void shutdown() override;
-
- private:
- const size_t mBufferSizeFrames;
- const size_t mFrameSizeBytes;
- const int mSampleRate;
- const bool mIsAsynchronous;
- const bool mIsInput;
- bool mIsInitialized = false; // Used for validating the state machine logic.
- bool mIsStandby = true; // Used for validating the state machine logic.
+ ~StreamStub();
};
class StreamInStub final : public StreamIn, public StreamStub {
diff --git a/audio/aidl/default/include/core-impl/StreamUsb.h b/audio/aidl/default/include/core-impl/StreamUsb.h
index 608f27d..694fccf 100644
--- a/audio/aidl/default/include/core-impl/StreamUsb.h
+++ b/audio/aidl/default/include/core-impl/StreamUsb.h
@@ -29,6 +29,7 @@
class StreamUsb : public StreamAlsa {
public:
StreamUsb(StreamContext* context, const Metadata& metadata);
+
// Methods of 'DriverInterface'.
::android::status_t transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
int32_t* latencyMs) override;
diff --git a/audio/aidl/default/include/core-impl/XmlConverter.h b/audio/aidl/default/include/core-impl/XmlConverter.h
index 68e6b8e..4b99d72 100644
--- a/audio/aidl/default/include/core-impl/XmlConverter.h
+++ b/audio/aidl/default/include/core-impl/XmlConverter.h
@@ -106,6 +106,19 @@
}
template <typename X, typename A>
+static ConversionResult<std::vector<std::optional<A>>> convertCollectionToAidlOptionalValues(
+ const std::vector<X>& xsdcTypeVec,
+ std::function<ConversionResult<A>(const X&)> convertToAidl) {
+ std::vector<std::optional<A>> resultAidlTypeVec;
+ resultAidlTypeVec.reserve(xsdcTypeVec.size());
+ for (const X& xsdcType : xsdcTypeVec) {
+ resultAidlTypeVec.push_back(
+ std::optional<A>(std::move(VALUE_OR_FATAL(convertToAidl(xsdcType)))));
+ }
+ return resultAidlTypeVec;
+}
+
+template <typename X, typename A>
static ConversionResult<std::vector<A>> convertCollectionToAidl(
const std::vector<X>& xsdcTypeVec,
std::function<ConversionResult<A>(const X&)> convertToAidl) {
diff --git a/audio/aidl/default/include/core-impl/XsdcConversion.h b/audio/aidl/default/include/core-impl/XsdcConversion.h
index 30dc8b6..e855a3e 100644
--- a/audio/aidl/default/include/core-impl/XsdcConversion.h
+++ b/audio/aidl/default/include/core-impl/XsdcConversion.h
@@ -4,6 +4,7 @@
#include <aidl/android/media/audio/common/AudioHalCapCriterion.h>
#include <aidl/android/media/audio/common/AudioHalCapCriterionType.h>
+#include <aidl/android/media/audio/common/AudioHalCapCriterionV2.h>
#include <aidl/android/media/audio/common/AudioHalVolumeCurve.h>
#include <aidl/android/media/audio/common/AudioPort.h>
#include <android_audio_policy_configuration.h>
@@ -15,15 +16,40 @@
namespace aidl::android::hardware::audio::core::internal {
-ConversionResult<::aidl::android::media::audio::common::AudioHalCapCriterion>
-convertCapCriterionToAidl(
- const ::android::audio::policy::engine::configuration::CriterionType& xsdcCriterion);
-ConversionResult<::aidl::android::media::audio::common::AudioHalCapCriterionType>
-convertCapCriterionTypeToAidl(
- const ::android::audio::policy::engine::configuration::CriterionTypeType&
- xsdcCriterionType);
-ConversionResult<::aidl::android::media::audio::common::AudioHalVolumeCurve::CurvePoint>
-convertCurvePointToAidl(const std::string& xsdcCurvePoint);
+namespace engineconfiguration = ::android::audio::policy::engine::configuration;
+namespace aidlaudiocommon = ::aidl::android::media::audio::common;
+
+static constexpr const char kXsdcForceConfigForUse[] = "ForceUseFor";
+
+ConversionResult<aidlaudiocommon::AudioPolicyForceUse> convertForceUseCriterionToAidl(
+ const std::string& xsdcCriterionName);
+ConversionResult<aidlaudiocommon::AudioPolicyForcedConfig> convertForcedConfigToAidl(
+ const std::string& xsdcForcedConfigCriterionType);
+ConversionResult<aidlaudiocommon::AudioDeviceAddress> convertDeviceAddressToAidl(
+ const std::string& xsdcAddress);
+ConversionResult<aidlaudiocommon::AudioMode> convertTelephonyModeToAidl(
+ const std::string& xsdcModeCriterionType);
+ConversionResult<aidlaudiocommon::AudioDeviceDescription> convertDeviceTypeToAidl(
+ const std::string& xType);
+ConversionResult<std::vector<std::optional<aidlaudiocommon::AudioHalCapCriterionV2>>>
+convertCapCriteriaCollectionToAidl(
+ const std::vector<engineconfiguration::CriteriaType>& xsdcCriteriaVec,
+ const std::vector<engineconfiguration::CriterionTypesType>& xsdcCriterionTypesVec);
+ConversionResult<aidlaudiocommon::AudioHalCapCriterionV2> convertCapCriterionV2ToAidl(
+ const engineconfiguration::CriterionType& xsdcCriterion,
+ const std::vector<engineconfiguration::CriterionTypesType>& xsdcCriterionTypesVec);
+ConversionResult<aidlaudiocommon::AudioHalVolumeCurve::CurvePoint> convertCurvePointToAidl(
+ const std::string& xsdcCurvePoint);
ConversionResult<std::unique_ptr<Module::Configuration>> convertModuleConfigToAidl(
const ::android::audio::policy::configuration::Modules::Module& moduleConfig);
+ConversionResult<aidlaudiocommon::AudioUsage> convertAudioUsageToAidl(
+ const engineconfiguration::UsageEnumType& xsdcUsage);
+ConversionResult<aidlaudiocommon::AudioContentType> convertAudioContentTypeToAidl(
+ const engineconfiguration::ContentType& xsdcContentType);
+ConversionResult<aidlaudiocommon::AudioSource> convertAudioSourceToAidl(
+ const engineconfiguration::SourceEnumType& xsdcSourceType);
+ConversionResult<aidlaudiocommon::AudioStreamType> convertAudioStreamTypeToAidl(
+ const engineconfiguration::Stream& xsdStreamType);
+ConversionResult<int32_t> convertAudioFlagsToAidl(
+ const std::vector<engineconfiguration::FlagType>& xsdcFlagTypeVec);
} // namespace aidl::android::hardware::audio::core::internal
diff --git a/audio/aidl/default/include/effect-impl/EffectContext.h b/audio/aidl/default/include/effect-impl/EffectContext.h
index 275378e..02a4caa 100644
--- a/audio/aidl/default/include/effect-impl/EffectContext.h
+++ b/audio/aidl/default/include/effect-impl/EffectContext.h
@@ -82,6 +82,10 @@
virtual ::android::hardware::EventFlag* getStatusEventFlag();
+ virtual RetCode enable();
+ virtual RetCode disable();
+ virtual RetCode reset();
+
protected:
int mVersion = 0;
size_t mInputFrameSize = 0;
diff --git a/audio/aidl/default/include/effectFactory-impl/EffectConfig.h b/audio/aidl/default/include/effectFactory-impl/EffectConfig.h
index 7456b99..60bb9be 100644
--- a/audio/aidl/default/include/effectFactory-impl/EffectConfig.h
+++ b/audio/aidl/default/include/effectFactory-impl/EffectConfig.h
@@ -81,7 +81,7 @@
/* Parsed Effects result */
std::unordered_map<std::string, struct EffectLibraries> mEffectsMap;
/**
- * For parsed pre/post processing result: {key: AudioStreamType/AudioSource, value:
+ * For parsed pre/post processing result: {key: AudioStreamType/AudioSource/AudioDevice, value:
* EffectLibraries}
*/
ProcessingLibrariesMap mProcessingMap;
@@ -110,7 +110,8 @@
bool resolveLibrary(const std::string& path, std::string* resolvedPath);
std::optional<Processing::Type> stringToProcessingType(Processing::Type::Tag typeTag,
- const std::string& type);
+ const std::string& type,
+ const std::string& address);
};
} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/main.cpp b/audio/aidl/default/main.cpp
index 6ab747d..0b3e3ba 100644
--- a/audio/aidl/default/main.cpp
+++ b/audio/aidl/default/main.cpp
@@ -71,6 +71,7 @@
// For more logs, use VERBOSE, however this may hinder performance.
// android::base::SetMinimumLogSeverity(::android::base::VERBOSE);
ABinderProcess_setThreadPoolMaxThreadCount(16);
+ ABinderProcess_startThreadPool();
// Guaranteed log for b/210919187 and logd_integration_test
LOG(INFO) << "Init for Audio AIDL HAL";
diff --git a/audio/aidl/default/primary/PrimaryMixer.h b/audio/aidl/default/primary/PrimaryMixer.h
index 3806428..760d42f 100644
--- a/audio/aidl/default/primary/PrimaryMixer.h
+++ b/audio/aidl/default/primary/PrimaryMixer.h
@@ -16,20 +16,14 @@
#pragma once
-#include <map>
-#include <memory>
-#include <mutex>
-#include <vector>
-
-#include <android-base/thread_annotations.h>
-#include <android/binder_auto_utils.h>
-
#include "alsa/Mixer.h"
namespace aidl::android::hardware::audio::core::primary {
class PrimaryMixer : public alsa::Mixer {
public:
+ static constexpr int kInvalidAlsaCard = -1;
+ static constexpr int kInvalidAlsaDevice = -1;
static constexpr int kAlsaCard = 0;
static constexpr int kAlsaDevice = 0;
diff --git a/audio/aidl/default/primary/StreamPrimary.cpp b/audio/aidl/default/primary/StreamPrimary.cpp
index 7325a91..c1c1f03 100644
--- a/audio/aidl/default/primary/StreamPrimary.cpp
+++ b/audio/aidl/default/primary/StreamPrimary.cpp
@@ -15,19 +15,22 @@
*/
#define LOG_TAG "AHAL_StreamPrimary"
+
+#include <cstdio>
+
#include <android-base/logging.h>
+#include <android-base/parseint.h>
#include <android-base/properties.h>
#include <audio_utils/clock.h>
#include <error/Result.h>
#include <error/expected_utils.h>
-#include "PrimaryMixer.h"
#include "core-impl/StreamPrimary.h"
-#include "core-impl/StreamStub.h"
using aidl::android::hardware::audio::common::SinkMetadata;
using aidl::android::hardware::audio::common::SourceMetadata;
using aidl::android::media::audio::common::AudioDevice;
+using aidl::android::media::audio::common::AudioDeviceAddress;
using aidl::android::media::audio::common::AudioDeviceDescription;
using aidl::android::media::audio::common::AudioDeviceType;
using aidl::android::media::audio::common::AudioOffloadInfo;
@@ -38,11 +41,49 @@
StreamPrimary::StreamPrimary(StreamContext* context, const Metadata& metadata)
: StreamAlsa(context, metadata, 3 /*readWriteRetries*/),
- mIsAsynchronous(!!getContext().getAsyncCallback()) {
+ mIsAsynchronous(!!getContext().getAsyncCallback()),
+ mStubDriver(getContext()) {
context->startStreamDataProcessor();
}
+::android::status_t StreamPrimary::init() {
+ RETURN_STATUS_IF_ERROR(mStubDriver.init());
+ return StreamAlsa::init();
+}
+
+::android::status_t StreamPrimary::drain(StreamDescriptor::DrainMode mode) {
+ return isStubStreamOnWorker() ? mStubDriver.drain(mode) : StreamAlsa::drain(mode);
+}
+
+::android::status_t StreamPrimary::flush() {
+ RETURN_STATUS_IF_ERROR(isStubStreamOnWorker() ? mStubDriver.flush() : StreamAlsa::flush());
+ // TODO(b/372951987): consider if this needs to be done from 'StreamInWorkerLogic::cycle'.
+ return mIsInput ? standby() : ::android::OK;
+}
+
+::android::status_t StreamPrimary::pause() {
+ return isStubStreamOnWorker() ? mStubDriver.pause() : StreamAlsa::pause();
+}
+
+::android::status_t StreamPrimary::standby() {
+ return isStubStreamOnWorker() ? mStubDriver.standby() : StreamAlsa::standby();
+}
+
::android::status_t StreamPrimary::start() {
+ bool isStub = true, shutdownAlsaStream = false;
+ {
+ std::lock_guard l(mLock);
+ isStub = mAlsaDeviceId == kStubDeviceId;
+ shutdownAlsaStream =
+ mCurrAlsaDeviceId != mAlsaDeviceId && mCurrAlsaDeviceId != kStubDeviceId;
+ mCurrAlsaDeviceId = mAlsaDeviceId;
+ }
+ if (shutdownAlsaStream) {
+ StreamAlsa::shutdown(); // Close currently opened ALSA devices.
+ }
+ if (isStub) {
+ return mStubDriver.start();
+ }
RETURN_STATUS_IF_ERROR(StreamAlsa::start());
mStartTimeNs = ::android::uptimeNanos();
mFramesSinceStart = 0;
@@ -52,6 +93,9 @@
::android::status_t StreamPrimary::transfer(void* buffer, size_t frameCount,
size_t* actualFrameCount, int32_t* latencyMs) {
+ if (isStubStreamOnWorker()) {
+ return mStubDriver.transfer(buffer, frameCount, actualFrameCount, latencyMs);
+ }
// This is a workaround for the emulator implementation which has a host-side buffer
// and is not being able to achieve real-time behavior similar to ADSPs (b/302587331).
if (!mSkipNextTransfer) {
@@ -91,63 +135,85 @@
return ::android::OK;
}
+void StreamPrimary::shutdown() {
+ StreamAlsa::shutdown();
+ mStubDriver.shutdown();
+}
+
+ndk::ScopedAStatus StreamPrimary::setConnectedDevices(const ConnectedDevices& devices) {
+ LOG(DEBUG) << __func__ << ": " << ::android::internal::ToString(devices);
+ if (devices.size() > 1) {
+ LOG(ERROR) << __func__ << ": primary stream can only be connected to one device, got: "
+ << devices.size();
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+ }
+ {
+ const bool useStubDriver = devices.empty() || useStubStream(mIsInput, devices[0]);
+ std::lock_guard l(mLock);
+ mAlsaDeviceId = useStubDriver ? kStubDeviceId : getCardAndDeviceId(devices);
+ }
+ if (!devices.empty()) {
+ auto streamDataProcessor = getContext().getStreamDataProcessor().lock();
+ if (streamDataProcessor != nullptr) {
+ streamDataProcessor->setAudioDevice(devices[0]);
+ }
+ }
+ return StreamAlsa::setConnectedDevices(devices);
+}
+
std::vector<alsa::DeviceProfile> StreamPrimary::getDeviceProfiles() {
- static const std::vector<alsa::DeviceProfile> kBuiltInSource{
- alsa::DeviceProfile{.card = primary::PrimaryMixer::kAlsaCard,
- .device = primary::PrimaryMixer::kAlsaDevice,
- .direction = PCM_IN,
+ return {alsa::DeviceProfile{.card = mCurrAlsaDeviceId.first,
+ .device = mCurrAlsaDeviceId.second,
+ .direction = mIsInput ? PCM_IN : PCM_OUT,
.isExternal = false}};
- static const std::vector<alsa::DeviceProfile> kBuiltInSink{
- alsa::DeviceProfile{.card = primary::PrimaryMixer::kAlsaCard,
- .device = primary::PrimaryMixer::kAlsaDevice,
- .direction = PCM_OUT,
- .isExternal = false}};
- return mIsInput ? kBuiltInSource : kBuiltInSink;
+}
+
+bool StreamPrimary::isStubStream() {
+ std::lock_guard l(mLock);
+ return mAlsaDeviceId == kStubDeviceId;
+}
+
+// static
+StreamPrimary::AlsaDeviceId StreamPrimary::getCardAndDeviceId(
+ const std::vector<AudioDevice>& devices) {
+ if (devices.empty() || devices[0].address.getTag() != AudioDeviceAddress::id) {
+ return kDefaultCardAndDeviceId;
+ }
+ std::string deviceAddress = devices[0].address.get<AudioDeviceAddress::id>();
+ AlsaDeviceId cardAndDeviceId;
+ if (const size_t suffixPos = deviceAddress.rfind("CARD_");
+ suffixPos == std::string::npos ||
+ sscanf(deviceAddress.c_str() + suffixPos, "CARD_%d_DEV_%d", &cardAndDeviceId.first,
+ &cardAndDeviceId.second) != 2) {
+ return kDefaultCardAndDeviceId;
+ }
+ LOG(DEBUG) << __func__ << ": parsed with card id " << cardAndDeviceId.first << ", device id "
+ << cardAndDeviceId.second;
+ return cardAndDeviceId;
+}
+
+// static
+bool StreamPrimary::useStubStream(
+ bool isInput, const ::aidl::android::media::audio::common::AudioDevice& device) {
+ static const bool kSimulateInput =
+ GetBoolProperty("ro.boot.audio.tinyalsa.simulate_input", false);
+ static const bool kSimulateOutput =
+ GetBoolProperty("ro.boot.audio.tinyalsa.ignore_output", false);
+ if (isInput) {
+ return kSimulateInput || device.type.type == AudioDeviceType::IN_TELEPHONY_RX ||
+ device.type.type == AudioDeviceType::IN_FM_TUNER ||
+ device.type.connection == AudioDeviceDescription::CONNECTION_BUS /*deprecated */;
+ }
+ return kSimulateOutput || device.type.type == AudioDeviceType::OUT_TELEPHONY_TX ||
+ device.type.connection == AudioDeviceDescription::CONNECTION_BUS /*deprecated*/;
}
StreamInPrimary::StreamInPrimary(StreamContext&& context, const SinkMetadata& sinkMetadata,
const std::vector<MicrophoneInfo>& microphones)
: StreamIn(std::move(context), microphones),
- StreamSwitcher(&mContextInstance, sinkMetadata),
+ StreamPrimary(&mContextInstance, sinkMetadata),
StreamInHwGainHelper(&mContextInstance) {}
-bool StreamInPrimary::useStubStream(const AudioDevice& device) {
- static const bool kSimulateInput =
- GetBoolProperty("ro.boot.audio.tinyalsa.simulate_input", false);
- return kSimulateInput || device.type.type == AudioDeviceType::IN_TELEPHONY_RX ||
- device.type.type == AudioDeviceType::IN_FM_TUNER ||
- device.type.connection == AudioDeviceDescription::CONNECTION_BUS /*deprecated */ ||
- (device.type.type == AudioDeviceType::IN_BUS && device.type.connection.empty());
-}
-
-StreamSwitcher::DeviceSwitchBehavior StreamInPrimary::switchCurrentStream(
- const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices) {
- LOG(DEBUG) << __func__;
- if (devices.size() > 1) {
- LOG(ERROR) << __func__ << ": primary stream can only be connected to one device, got: "
- << devices.size();
- return DeviceSwitchBehavior::UNSUPPORTED_DEVICES;
- }
- if (devices.empty() || useStubStream(devices[0]) == isStubStream()) {
- return DeviceSwitchBehavior::USE_CURRENT_STREAM;
- }
- return DeviceSwitchBehavior::CREATE_NEW_STREAM;
-}
-
-std::unique_ptr<StreamCommonInterfaceEx> StreamInPrimary::createNewStream(
- const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices,
- StreamContext* context, const Metadata& metadata) {
- if (devices.empty()) {
- LOG(FATAL) << __func__ << ": called with empty devices"; // see 'switchCurrentStream'
- }
- if (useStubStream(devices[0])) {
- return std::unique_ptr<StreamCommonInterfaceEx>(
- new InnerStreamWrapper<StreamStub>(context, metadata));
- }
- return std::unique_ptr<StreamCommonInterfaceEx>(
- new InnerStreamWrapper<StreamPrimary>(context, metadata));
-}
-
ndk::ScopedAStatus StreamInPrimary::getHwGain(std::vector<float>* _aidl_return) {
if (isStubStream()) {
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
@@ -181,45 +247,9 @@
StreamOutPrimary::StreamOutPrimary(StreamContext&& context, const SourceMetadata& sourceMetadata,
const std::optional<AudioOffloadInfo>& offloadInfo)
: StreamOut(std::move(context), offloadInfo),
- StreamSwitcher(&mContextInstance, sourceMetadata),
+ StreamPrimary(&mContextInstance, sourceMetadata),
StreamOutHwVolumeHelper(&mContextInstance) {}
-bool StreamOutPrimary::useStubStream(const AudioDevice& device) {
- static const bool kSimulateOutput =
- GetBoolProperty("ro.boot.audio.tinyalsa.ignore_output", false);
- return kSimulateOutput || device.type.type == AudioDeviceType::OUT_TELEPHONY_TX ||
- device.type.connection == AudioDeviceDescription::CONNECTION_BUS /*deprecated*/ ||
- (device.type.type == AudioDeviceType::OUT_BUS && device.type.connection.empty());
-}
-
-StreamSwitcher::DeviceSwitchBehavior StreamOutPrimary::switchCurrentStream(
- const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices) {
- LOG(DEBUG) << __func__;
- if (devices.size() > 1) {
- LOG(ERROR) << __func__ << ": primary stream can only be connected to one device, got: "
- << devices.size();
- return DeviceSwitchBehavior::UNSUPPORTED_DEVICES;
- }
- if (devices.empty() || useStubStream(devices[0]) == isStubStream()) {
- return DeviceSwitchBehavior::USE_CURRENT_STREAM;
- }
- return DeviceSwitchBehavior::CREATE_NEW_STREAM;
-}
-
-std::unique_ptr<StreamCommonInterfaceEx> StreamOutPrimary::createNewStream(
- const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices,
- StreamContext* context, const Metadata& metadata) {
- if (devices.empty()) {
- LOG(FATAL) << __func__ << ": called with empty devices"; // see 'switchCurrentStream'
- }
- if (useStubStream(devices[0])) {
- return std::unique_ptr<StreamCommonInterfaceEx>(
- new InnerStreamWrapper<StreamStub>(context, metadata));
- }
- return std::unique_ptr<StreamCommonInterfaceEx>(
- new InnerStreamWrapper<StreamPrimary>(context, metadata));
-}
-
ndk::ScopedAStatus StreamOutPrimary::getHwVolume(std::vector<float>* _aidl_return) {
if (isStubStream()) {
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
@@ -245,15 +275,4 @@
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus StreamOutPrimary::setConnectedDevices(
- const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices) {
- if (!devices.empty()) {
- auto streamDataProcessor = mContextInstance.getStreamDataProcessor().lock();
- if (streamDataProcessor != nullptr) {
- streamDataProcessor->setAudioDevice(devices[0]);
- }
- }
- return StreamSwitcher::setConnectedDevices(devices);
-}
-
} // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp b/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp
index ca3f91a..93fe028 100644
--- a/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp
+++ b/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp
@@ -26,124 +26,106 @@
using aidl::android::hardware::audio::common::SourceMetadata;
using aidl::android::hardware::audio::core::r_submix::SubmixRoute;
using aidl::android::media::audio::common::AudioDeviceAddress;
+using aidl::android::media::audio::common::AudioDeviceType;
using aidl::android::media::audio::common::AudioOffloadInfo;
using aidl::android::media::audio::common::MicrophoneDynamicInfo;
using aidl::android::media::audio::common::MicrophoneInfo;
namespace aidl::android::hardware::audio::core {
-StreamRemoteSubmix::StreamRemoteSubmix(StreamContext* context, const Metadata& metadata,
- const AudioDeviceAddress& deviceAddress)
+StreamRemoteSubmix::StreamRemoteSubmix(StreamContext* context, const Metadata& metadata)
: StreamCommonImpl(context, metadata),
- mDeviceAddress(deviceAddress),
- mIsInput(isInput(metadata)) {
- mStreamConfig.frameSize = context->getFrameSize();
- mStreamConfig.format = context->getFormat();
- mStreamConfig.channelLayout = context->getChannelLayout();
- mStreamConfig.sampleRate = context->getSampleRate();
+ mIsInput(isInput(metadata)),
+ mStreamConfig{.sampleRate = context->getSampleRate(),
+ .format = context->getFormat(),
+ .channelLayout = context->getChannelLayout(),
+ .frameSize = context->getFrameSize()} {}
+
+StreamRemoteSubmix::~StreamRemoteSubmix() {
+ cleanupWorker();
}
::android::status_t StreamRemoteSubmix::init() {
- mCurrentRoute = SubmixRoute::findOrCreateRoute(mDeviceAddress, mStreamConfig);
- if (mCurrentRoute == nullptr) {
- return ::android::NO_INIT;
- }
- if (!mCurrentRoute->isStreamConfigValid(mIsInput, mStreamConfig)) {
- LOG(ERROR) << __func__ << ": invalid stream config";
- return ::android::NO_INIT;
- }
- sp<MonoPipe> sink = mCurrentRoute->getSink();
- if (sink == nullptr) {
- LOG(ERROR) << __func__ << ": nullptr sink when opening stream";
- return ::android::NO_INIT;
- }
- if ((!mIsInput || mCurrentRoute->isStreamInOpen()) && sink->isShutdown()) {
- LOG(DEBUG) << __func__ << ": Shut down sink when opening stream";
- if (::android::OK != mCurrentRoute->resetPipe()) {
- LOG(ERROR) << __func__ << ": reset pipe failed";
- return ::android::NO_INIT;
- }
- }
- mCurrentRoute->openStream(mIsInput);
return ::android::OK;
}
::android::status_t StreamRemoteSubmix::drain(StreamDescriptor::DrainMode) {
- usleep(1000);
return ::android::OK;
}
::android::status_t StreamRemoteSubmix::flush() {
- usleep(1000);
return ::android::OK;
}
::android::status_t StreamRemoteSubmix::pause() {
- usleep(1000);
return ::android::OK;
}
::android::status_t StreamRemoteSubmix::standby() {
- mCurrentRoute->standby(mIsInput);
+ if (mCurrentRoute) mCurrentRoute->standby(mIsInput);
return ::android::OK;
}
::android::status_t StreamRemoteSubmix::start() {
- mCurrentRoute->exitStandby(mIsInput);
+ if (mDeviceAddressUpdated.load(std::memory_order_acquire)) {
+ LOG(DEBUG) << __func__ << ": device address updated, reset current route";
+ shutdown();
+ mDeviceAddressUpdated.store(false, std::memory_order_release);
+ }
+ if (!mCurrentRoute) {
+ RETURN_STATUS_IF_ERROR(setCurrentRoute());
+ LOG(DEBUG) << __func__ << ": have current route? " << (mCurrentRoute != nullptr);
+ }
+ if (mCurrentRoute) mCurrentRoute->exitStandby(mIsInput);
mStartTimeNs = ::android::uptimeNanos();
mFramesSinceStart = 0;
return ::android::OK;
}
-ndk::ScopedAStatus StreamRemoteSubmix::prepareToClose() {
- if (!mIsInput) {
- std::shared_ptr<SubmixRoute> route = SubmixRoute::findRoute(mDeviceAddress);
- if (route != nullptr) {
- sp<MonoPipe> sink = route->getSink();
- if (sink == nullptr) {
- ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
- }
- LOG(DEBUG) << __func__ << ": shutting down MonoPipe sink";
-
- sink->shutdown(true);
- // The client already considers this stream as closed, release the output end.
- route->closeStream(mIsInput);
- } else {
- LOG(DEBUG) << __func__ << ": stream already closed.";
- ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
- }
- }
- return ndk::ScopedAStatus::ok();
-}
-
// Remove references to the specified input and output streams. When the device no longer
// references input and output streams destroy the associated pipe.
void StreamRemoteSubmix::shutdown() {
+ if (!mCurrentRoute) return;
mCurrentRoute->closeStream(mIsInput);
// If all stream instances are closed, we can remove route information for this port.
if (!mCurrentRoute->hasAtleastOneStreamOpen()) {
mCurrentRoute->releasePipe();
LOG(DEBUG) << __func__ << ": pipe destroyed";
- SubmixRoute::removeRoute(mDeviceAddress);
+ SubmixRoute::removeRoute(getDeviceAddress());
}
mCurrentRoute.reset();
}
::android::status_t StreamRemoteSubmix::transfer(void* buffer, size_t frameCount,
size_t* actualFrameCount, int32_t* latencyMs) {
+ if (mDeviceAddressUpdated.load(std::memory_order_acquire)) {
+ // 'setConnectedDevices' was called. I/O will be restarted.
+ return ::android::OK;
+ }
+
*latencyMs = getDelayInUsForFrameCount(getStreamPipeSizeInFrames()) / 1000;
LOG(VERBOSE) << __func__ << ": Latency " << *latencyMs << "ms";
- mCurrentRoute->exitStandby(mIsInput);
- ::android::status_t status = mIsInput ? inRead(buffer, frameCount, actualFrameCount)
- : outWrite(buffer, frameCount, actualFrameCount);
- if ((status != ::android::OK && mIsInput) ||
- ((status != ::android::OK && status != ::android::DEAD_OBJECT) && !mIsInput)) {
- return status;
+ ::android::status_t status = ::android::OK;
+ if (mCurrentRoute) {
+ mCurrentRoute->exitStandby(mIsInput);
+ status = mIsInput ? inRead(buffer, frameCount, actualFrameCount)
+ : outWrite(buffer, frameCount, actualFrameCount);
+ if ((status != ::android::OK && mIsInput) ||
+ ((status != ::android::OK && status != ::android::DEAD_OBJECT) && !mIsInput)) {
+ return status;
+ }
+ } else {
+ LOG(WARNING) << __func__ << ": no current route";
+ if (mIsInput) {
+ memset(buffer, 0, mStreamConfig.frameSize * frameCount);
+ }
+ *actualFrameCount = frameCount;
}
mFramesSinceStart += *actualFrameCount;
- if (!mIsInput && status != ::android::DEAD_OBJECT) return ::android::OK;
- // Input streams always need to block, output streams need to block when there is no sink.
- // When the sink exists, more sophisticated blocking algorithm is implemented by MonoPipe.
+ // If there is no route, always block, otherwise:
+ // - Input streams always need to block, output streams need to block when there is no sink.
+ // - When the sink exists, more sophisticated blocking algorithm is implemented by MonoPipe.
+ if (mCurrentRoute && !mIsInput && status != ::android::DEAD_OBJECT) return ::android::OK;
const long bufferDurationUs =
(*actualFrameCount) * MICROS_PER_SECOND / mContext.getSampleRate();
const auto totalDurationUs = (::android::uptimeNanos() - mStartTimeNs) / NANOS_PER_MICROSECOND;
@@ -159,6 +141,10 @@
}
::android::status_t StreamRemoteSubmix::refinePosition(StreamDescriptor::Position* position) {
+ if (!mCurrentRoute) {
+ RETURN_STATUS_IF_ERROR(setCurrentRoute());
+ if (!mCurrentRoute) return ::android::OK;
+ }
sp<MonoPipeReader> source = mCurrentRoute->getSource();
if (source == nullptr) {
return ::android::NO_INIT;
@@ -182,6 +168,7 @@
// Calculate the maximum size of the pipe buffer in frames for the specified stream.
size_t StreamRemoteSubmix::getStreamPipeSizeInFrames() {
+ if (!mCurrentRoute) return r_submix::kDefaultPipeSizeInFrames;
auto pipeConfig = mCurrentRoute->getPipeConfig();
const size_t maxFrameSize = std::max(mStreamConfig.frameSize, pipeConfig.frameSize);
return (pipeConfig.frameCount * pipeConfig.frameSize) / maxFrameSize;
@@ -205,7 +192,7 @@
}
mWriteShutdownCount = 0;
- LOG(VERBOSE) << __func__ << ": " << mDeviceAddress.toString() << ", " << frameCount
+ LOG(VERBOSE) << __func__ << ": " << getDeviceAddress().toString() << ", " << frameCount
<< " frames";
const bool shouldBlockWrite = mCurrentRoute->shouldBlockWrite();
@@ -279,15 +266,19 @@
}
mReadErrorCount = 0;
- LOG(VERBOSE) << __func__ << ": " << mDeviceAddress.toString() << ", " << frameCount
+ LOG(VERBOSE) << __func__ << ": " << getDeviceAddress().toString() << ", " << frameCount
<< " frames";
+
// read the data from the pipe
char* buff = (char*)buffer;
size_t actuallyRead = 0;
long remainingFrames = frameCount;
- const int64_t deadlineTimeNs =
- ::android::uptimeNanos() +
- getDelayInUsForFrameCount(frameCount) * NANOS_PER_MICROSECOND / 2;
+ // Try to wait as long as possible for the audio duration, but leave some time for the call to
+ // 'transfer' to complete. 'kReadAttemptSleepUs' is a good constant for this purpose because it
+ // is by definition "strictly inferior" to the typical buffer duration.
+ const long durationUs =
+ std::max(0L, getDelayInUsForFrameCount(frameCount) - kReadAttemptSleepUs);
+ const int64_t deadlineTimeNs = ::android::uptimeNanos() + durationUs * NANOS_PER_MICROSECOND;
while (remainingFrames > 0) {
ssize_t framesRead = source->read(buff, remainingFrames);
LOG(VERBOSE) << __func__ << ": frames read " << framesRead;
@@ -317,10 +308,91 @@
return ::android::OK;
}
+::android::status_t StreamRemoteSubmix::setCurrentRoute() {
+ const auto address = getDeviceAddress();
+ if (address == AudioDeviceAddress{}) {
+ return ::android::OK;
+ }
+ mCurrentRoute = SubmixRoute::findOrCreateRoute(address, mStreamConfig);
+ if (mCurrentRoute == nullptr) {
+ return ::android::NO_INIT;
+ }
+ if (!mCurrentRoute->isStreamConfigValid(mIsInput, mStreamConfig)) {
+ LOG(ERROR) << __func__ << ": invalid stream config";
+ return ::android::NO_INIT;
+ }
+ sp<MonoPipe> sink = mCurrentRoute->getSink();
+ if (sink == nullptr) {
+ LOG(ERROR) << __func__ << ": nullptr sink when opening stream";
+ return ::android::NO_INIT;
+ }
+ if ((!mIsInput || mCurrentRoute->isStreamInOpen()) && sink->isShutdown()) {
+ LOG(DEBUG) << __func__ << ": Shut down sink when opening stream";
+ if (::android::OK != mCurrentRoute->resetPipe()) {
+ LOG(ERROR) << __func__ << ": reset pipe failed";
+ return ::android::NO_INIT;
+ }
+ }
+ mCurrentRoute->openStream(mIsInput);
+ return ::android::OK;
+}
+
+ndk::ScopedAStatus StreamRemoteSubmix::prepareToClose() {
+ if (!mIsInput) {
+ const auto address = getDeviceAddress();
+ if (address == AudioDeviceAddress{}) return ndk::ScopedAStatus::ok();
+ std::shared_ptr<SubmixRoute> route = SubmixRoute::findRoute(address);
+ if (route != nullptr) {
+ sp<MonoPipe> sink = route->getSink();
+ if (sink == nullptr) {
+ ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+ }
+ LOG(DEBUG) << __func__ << ": shutting down MonoPipe sink";
+
+ sink->shutdown(true);
+ // The client already considers this stream as closed, release the output end.
+ route->closeStream(mIsInput);
+ } else {
+ LOG(DEBUG) << __func__ << ": stream already closed.";
+ ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+ }
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StreamRemoteSubmix::setConnectedDevices(const ConnectedDevices& devices) {
+ if (devices.size() > 1) {
+ LOG(ERROR) << __func__ << ": Only single device supported, got " << devices.size();
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+ }
+ AudioDeviceAddress newAddress;
+ if (!devices.empty()) {
+ if (auto deviceDesc = devices.front().type;
+ (mIsInput && deviceDesc.type != AudioDeviceType::IN_SUBMIX) ||
+ (!mIsInput && deviceDesc.type != AudioDeviceType::OUT_SUBMIX)) {
+ LOG(ERROR) << __func__ << ": Device type " << toString(deviceDesc.type)
+ << " not supported";
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+ }
+ newAddress = devices.front().address;
+ LOG(DEBUG) << __func__ << ": connected to " << newAddress.toString();
+ } else {
+ LOG(DEBUG) << __func__ << ": disconnected";
+ }
+ RETURN_STATUS_IF_ERROR(StreamCommonImpl::setConnectedDevices(devices));
+ std::lock_guard guard(mLock);
+ if (mDeviceAddress != newAddress) {
+ mDeviceAddress = newAddress;
+ mDeviceAddressUpdated.store(true, std::memory_order_release);
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
StreamInRemoteSubmix::StreamInRemoteSubmix(StreamContext&& context,
const SinkMetadata& sinkMetadata,
const std::vector<MicrophoneInfo>& microphones)
- : StreamIn(std::move(context), microphones), StreamSwitcher(&mContextInstance, sinkMetadata) {}
+ : StreamIn(std::move(context), microphones),
+ StreamRemoteSubmix(&mContextInstance, sinkMetadata) {}
ndk::ScopedAStatus StreamInRemoteSubmix::getActiveMicrophones(
std::vector<MicrophoneDynamicInfo>* _aidl_return) {
@@ -329,66 +401,10 @@
return ndk::ScopedAStatus::ok();
}
-StreamSwitcher::DeviceSwitchBehavior StreamInRemoteSubmix::switchCurrentStream(
- const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices) {
- // This implementation effectively postpones stream creation until
- // receiving the first call to 'setConnectedDevices' with a non-empty list.
- if (isStubStream()) {
- if (devices.size() == 1) {
- auto deviceDesc = devices.front().type;
- if (deviceDesc.type ==
- ::aidl::android::media::audio::common::AudioDeviceType::IN_SUBMIX) {
- return DeviceSwitchBehavior::CREATE_NEW_STREAM;
- }
- LOG(ERROR) << __func__ << ": Device type " << toString(deviceDesc.type)
- << " not supported";
- } else {
- LOG(ERROR) << __func__ << ": Only single device supported.";
- }
- return DeviceSwitchBehavior::UNSUPPORTED_DEVICES;
- }
- return DeviceSwitchBehavior::USE_CURRENT_STREAM;
-}
-
-std::unique_ptr<StreamCommonInterfaceEx> StreamInRemoteSubmix::createNewStream(
- const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices,
- StreamContext* context, const Metadata& metadata) {
- return std::unique_ptr<StreamCommonInterfaceEx>(
- new InnerStreamWrapper<StreamRemoteSubmix>(context, metadata, devices.front().address));
-}
-
StreamOutRemoteSubmix::StreamOutRemoteSubmix(StreamContext&& context,
const SourceMetadata& sourceMetadata,
const std::optional<AudioOffloadInfo>& offloadInfo)
: StreamOut(std::move(context), offloadInfo),
- StreamSwitcher(&mContextInstance, sourceMetadata) {}
-
-StreamSwitcher::DeviceSwitchBehavior StreamOutRemoteSubmix::switchCurrentStream(
- const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices) {
- // This implementation effectively postpones stream creation until
- // receiving the first call to 'setConnectedDevices' with a non-empty list.
- if (isStubStream()) {
- if (devices.size() == 1) {
- auto deviceDesc = devices.front().type;
- if (deviceDesc.type ==
- ::aidl::android::media::audio::common::AudioDeviceType::OUT_SUBMIX) {
- return DeviceSwitchBehavior::CREATE_NEW_STREAM;
- }
- LOG(ERROR) << __func__ << ": Device type " << toString(deviceDesc.type)
- << " not supported";
- } else {
- LOG(ERROR) << __func__ << ": Only single device supported.";
- }
- return DeviceSwitchBehavior::UNSUPPORTED_DEVICES;
- }
- return DeviceSwitchBehavior::USE_CURRENT_STREAM;
-}
-
-std::unique_ptr<StreamCommonInterfaceEx> StreamOutRemoteSubmix::createNewStream(
- const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices,
- StreamContext* context, const Metadata& metadata) {
- return std::unique_ptr<StreamCommonInterfaceEx>(
- new InnerStreamWrapper<StreamRemoteSubmix>(context, metadata, devices.front().address));
-}
+ StreamRemoteSubmix(&mContextInstance, sourceMetadata) {}
} // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/r_submix/SubmixRoute.h b/audio/aidl/default/r_submix/SubmixRoute.h
index 5425f12..0097f39 100644
--- a/audio/aidl/default/r_submix/SubmixRoute.h
+++ b/audio/aidl/default/r_submix/SubmixRoute.h
@@ -25,10 +25,12 @@
#include <media/nbaio/MonoPipe.h>
#include <media/nbaio/MonoPipeReader.h>
+#include <Utils.h>
#include <aidl/android/media/audio/common/AudioChannelLayout.h>
#include <aidl/android/media/audio/common/AudioDeviceAddress.h>
#include <aidl/android/media/audio/common/AudioFormatDescription.h>
+using aidl::android::hardware::audio::common::getFrameSizeInBytes;
using aidl::android::media::audio::common::AudioChannelLayout;
using aidl::android::media::audio::common::AudioFormatDescription;
using aidl::android::media::audio::common::AudioFormatType;
@@ -56,8 +58,8 @@
AudioChannelLayout channelLayout =
AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
AudioChannelLayout::LAYOUT_STEREO);
- size_t frameSize;
- size_t frameCount;
+ size_t frameSize = getFrameSizeInBytes(format, channelLayout);
+ size_t frameCount = 0;
};
class SubmixRoute {
diff --git a/audio/aidl/default/stub/DriverStubImpl.cpp b/audio/aidl/default/stub/DriverStubImpl.cpp
new file mode 100644
index 0000000..beb0114
--- /dev/null
+++ b/audio/aidl/default/stub/DriverStubImpl.cpp
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2024 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 <cmath>
+
+#define LOG_TAG "AHAL_Stream"
+#include <android-base/logging.h>
+#include <audio_utils/clock.h>
+
+#include "core-impl/DriverStubImpl.h"
+
+namespace aidl::android::hardware::audio::core {
+
+DriverStubImpl::DriverStubImpl(const StreamContext& context)
+ : mBufferSizeFrames(context.getBufferSizeInFrames()),
+ mFrameSizeBytes(context.getFrameSize()),
+ mSampleRate(context.getSampleRate()),
+ mIsAsynchronous(!!context.getAsyncCallback()),
+ mIsInput(context.isInput()) {}
+
+::android::status_t DriverStubImpl::init() {
+ mIsInitialized = true;
+ return ::android::OK;
+}
+
+::android::status_t DriverStubImpl::drain(StreamDescriptor::DrainMode) {
+ if (!mIsInitialized) {
+ LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
+ }
+ if (!mIsInput) {
+ if (!mIsAsynchronous) {
+ static constexpr float kMicrosPerSecond = MICROS_PER_SECOND;
+ const size_t delayUs = static_cast<size_t>(
+ std::roundf(mBufferSizeFrames * kMicrosPerSecond / mSampleRate));
+ usleep(delayUs);
+ } else {
+ usleep(500);
+ }
+ }
+ return ::android::OK;
+}
+
+::android::status_t DriverStubImpl::flush() {
+ if (!mIsInitialized) {
+ LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
+ }
+ return ::android::OK;
+}
+
+::android::status_t DriverStubImpl::pause() {
+ if (!mIsInitialized) {
+ LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
+ }
+ return ::android::OK;
+}
+
+::android::status_t DriverStubImpl::standby() {
+ if (!mIsInitialized) {
+ LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
+ }
+ mIsStandby = true;
+ return ::android::OK;
+}
+
+::android::status_t DriverStubImpl::start() {
+ if (!mIsInitialized) {
+ LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
+ }
+ mIsStandby = false;
+ mStartTimeNs = ::android::uptimeNanos();
+ mFramesSinceStart = 0;
+ return ::android::OK;
+}
+
+::android::status_t DriverStubImpl::transfer(void* buffer, size_t frameCount,
+ size_t* actualFrameCount, int32_t*) {
+ if (!mIsInitialized) {
+ LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
+ }
+ if (mIsStandby) {
+ LOG(FATAL) << __func__ << ": must not happen while in standby";
+ }
+ *actualFrameCount = frameCount;
+ if (mIsAsynchronous) {
+ usleep(500);
+ } else {
+ mFramesSinceStart += *actualFrameCount;
+ const long bufferDurationUs = (*actualFrameCount) * MICROS_PER_SECOND / mSampleRate;
+ const auto totalDurationUs =
+ (::android::uptimeNanos() - mStartTimeNs) / NANOS_PER_MICROSECOND;
+ const long totalOffsetUs =
+ mFramesSinceStart * MICROS_PER_SECOND / mSampleRate - totalDurationUs;
+ LOG(VERBOSE) << __func__ << ": totalOffsetUs " << totalOffsetUs;
+ if (totalOffsetUs > 0) {
+ const long sleepTimeUs = std::min(totalOffsetUs, bufferDurationUs);
+ LOG(VERBOSE) << __func__ << ": sleeping for " << sleepTimeUs << " us";
+ usleep(sleepTimeUs);
+ }
+ }
+ if (mIsInput) {
+ uint8_t* byteBuffer = static_cast<uint8_t*>(buffer);
+ for (size_t i = 0; i < frameCount * mFrameSizeBytes; ++i) {
+ byteBuffer[i] = std::rand() % 255;
+ }
+ }
+ return ::android::OK;
+}
+
+void DriverStubImpl::shutdown() {
+ mIsInitialized = false;
+}
+
+} // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/stub/StreamStub.cpp b/audio/aidl/default/stub/StreamStub.cpp
index 2422fe4..f6c87e1 100644
--- a/audio/aidl/default/stub/StreamStub.cpp
+++ b/audio/aidl/default/stub/StreamStub.cpp
@@ -32,96 +32,10 @@
namespace aidl::android::hardware::audio::core {
StreamStub::StreamStub(StreamContext* context, const Metadata& metadata)
- : StreamCommonImpl(context, metadata),
- mBufferSizeFrames(getContext().getBufferSizeInFrames()),
- mFrameSizeBytes(getContext().getFrameSize()),
- mSampleRate(getContext().getSampleRate()),
- mIsAsynchronous(!!getContext().getAsyncCallback()),
- mIsInput(isInput(metadata)) {}
+ : StreamCommonImpl(context, metadata), DriverStubImpl(getContext()) {}
-::android::status_t StreamStub::init() {
- mIsInitialized = true;
- return ::android::OK;
-}
-
-::android::status_t StreamStub::drain(StreamDescriptor::DrainMode) {
- if (!mIsInitialized) {
- LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
- }
- if (!mIsInput) {
- if (!mIsAsynchronous) {
- static constexpr float kMicrosPerSecond = MICROS_PER_SECOND;
- const size_t delayUs = static_cast<size_t>(
- std::roundf(mBufferSizeFrames * kMicrosPerSecond / mSampleRate));
- usleep(delayUs);
- } else {
- usleep(500);
- }
- }
- return ::android::OK;
-}
-
-::android::status_t StreamStub::flush() {
- if (!mIsInitialized) {
- LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
- }
- return ::android::OK;
-}
-
-::android::status_t StreamStub::pause() {
- if (!mIsInitialized) {
- LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
- }
- return ::android::OK;
-}
-
-::android::status_t StreamStub::standby() {
- if (!mIsInitialized) {
- LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
- }
- usleep(500);
- mIsStandby = true;
- return ::android::OK;
-}
-
-::android::status_t StreamStub::start() {
- if (!mIsInitialized) {
- LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
- }
- usleep(500);
- mIsStandby = false;
- return ::android::OK;
-}
-
-::android::status_t StreamStub::transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
- int32_t*) {
- if (!mIsInitialized) {
- LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
- }
- if (mIsStandby) {
- LOG(FATAL) << __func__ << ": must not happen while in standby";
- }
- static constexpr float kMicrosPerSecond = MICROS_PER_SECOND;
- static constexpr float kScaleFactor = .8f;
- if (mIsAsynchronous) {
- usleep(500);
- } else {
- const size_t delayUs = static_cast<size_t>(
- std::roundf(kScaleFactor * frameCount * kMicrosPerSecond / mSampleRate));
- usleep(delayUs);
- }
- if (mIsInput) {
- uint8_t* byteBuffer = static_cast<uint8_t*>(buffer);
- for (size_t i = 0; i < frameCount * mFrameSizeBytes; ++i) {
- byteBuffer[i] = std::rand() % 255;
- }
- }
- *actualFrameCount = frameCount;
- return ::android::OK;
-}
-
-void StreamStub::shutdown() {
- mIsInitialized = false;
+StreamStub::~StreamStub() {
+ cleanupWorker();
}
StreamInStub::StreamInStub(StreamContext&& context, const SinkMetadata& sinkMetadata,
diff --git a/audio/aidl/vts/EffectHelper.h b/audio/aidl/vts/EffectHelper.h
index cad1195..3877c60 100644
--- a/audio/aidl/vts/EffectHelper.h
+++ b/audio/aidl/vts/EffectHelper.h
@@ -83,6 +83,8 @@
return prefix;
}
+static constexpr float kMaxAudioSampleValue = 1;
+
class EffectHelper {
public:
void create(std::shared_ptr<IFactory> factory, std::shared_ptr<IEffect>& effect,
@@ -397,10 +399,10 @@
outputBuffer.size(), outputBuffer));
}
+ // Disable the process
ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, outputBuffer));
- // Disable the process
ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::RESET));
}
@@ -413,6 +415,19 @@
}
}
+ // Fill inputBuffer with random values between -maxAudioSampleValue to maxAudioSampleValue
+ void generateInputBuffer(std::vector<float>& inputBuffer, size_t startPosition, bool isStrip,
+ size_t channelCount,
+ float maxAudioSampleValue = kMaxAudioSampleValue) {
+ size_t increment = isStrip ? 1 /*Fill input at all the channels*/
+ : channelCount /*Fill input at only one channel*/;
+
+ for (size_t i = startPosition; i < inputBuffer.size(); i += increment) {
+ inputBuffer[i] =
+ ((static_cast<float>(std::rand()) / RAND_MAX) * 2 - 1) * maxAudioSampleValue;
+ }
+ }
+
// Generate multitone input between -1 to +1 using testFrequencies
void generateMultiTone(const std::vector<int>& testFrequencies, std::vector<float>& input,
const int samplingFrequency) {
diff --git a/audio/aidl/vts/VtsHalAudioCoreConfigTargetTest.cpp b/audio/aidl/vts/VtsHalAudioCoreConfigTargetTest.cpp
index f82e8e5..25fcd46 100644
--- a/audio/aidl/vts/VtsHalAudioCoreConfigTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioCoreConfigTargetTest.cpp
@@ -38,16 +38,24 @@
using aidl::android::hardware::audio::core::IConfig;
using aidl::android::hardware::audio::core::SurroundSoundConfig;
using aidl::android::media::audio::common::AudioAttributes;
+using aidl::android::media::audio::common::AudioDeviceAddress;
+using aidl::android::media::audio::common::AudioDeviceDescription;
using aidl::android::media::audio::common::AudioFlag;
using aidl::android::media::audio::common::AudioFormatDescription;
using aidl::android::media::audio::common::AudioFormatType;
using aidl::android::media::audio::common::AudioHalAttributesGroup;
-using aidl::android::media::audio::common::AudioHalCapCriterion;
-using aidl::android::media::audio::common::AudioHalCapCriterionType;
+using aidl::android::media::audio::common::AudioHalCapConfiguration;
+using aidl::android::media::audio::common::AudioHalCapCriterionV2;
+using aidl::android::media::audio::common::AudioHalCapDomain;
+using aidl::android::media::audio::common::AudioHalCapParameter;
+using aidl::android::media::audio::common::AudioHalCapRule;
using aidl::android::media::audio::common::AudioHalEngineConfig;
using aidl::android::media::audio::common::AudioHalProductStrategy;
using aidl::android::media::audio::common::AudioHalVolumeCurve;
using aidl::android::media::audio::common::AudioHalVolumeGroup;
+using aidl::android::media::audio::common::AudioMode;
+using aidl::android::media::audio::common::AudioPolicyForceUse;
+using aidl::android::media::audio::common::AudioPolicyForcedConfig;
using aidl::android::media::audio::common::AudioProductStrategyType;
using aidl::android::media::audio::common::AudioSource;
using aidl::android::media::audio::common::AudioStreamType;
@@ -256,48 +264,318 @@
}
/**
- * Verify defaultLiteralValue is empty for inclusive criterion.
+ * Verify criterion provides a non empty value list.
+ * Verify logic rule provided is the expected one.
*/
- void ValidateAudioHalCapCriterion(const AudioHalCapCriterion& criterion,
- const AudioHalCapCriterionType& criterionType) {
- if (criterionType.isInclusive) {
- EXPECT_TRUE(criterion.defaultLiteralValue.empty());
+ void ValidateAudioHalCapCriterion(const AudioHalCapCriterionV2& criterionV2) {
+ switch (criterionV2.getTag()) {
+ case AudioHalCapCriterionV2::availableInputDevices: {
+ auto criterion = criterionV2.get<AudioHalCapCriterionV2::availableInputDevices>();
+ EXPECT_FALSE(criterion.values.empty());
+ EXPECT_EQ(criterion.logic, AudioHalCapCriterionV2::LogicalDisjunction::INCLUSIVE);
+ break;
+ }
+ case AudioHalCapCriterionV2::availableOutputDevices: {
+ auto criterion = criterionV2.get<AudioHalCapCriterionV2::availableOutputDevices>();
+ EXPECT_FALSE(criterion.values.empty());
+ EXPECT_EQ(criterion.logic, AudioHalCapCriterionV2::LogicalDisjunction::INCLUSIVE);
+ break;
+ }
+ case AudioHalCapCriterionV2::availableInputDevicesAddresses: {
+ auto criterion =
+ criterionV2.get<AudioHalCapCriterionV2::availableInputDevicesAddresses>();
+ EXPECT_FALSE(criterion.values.empty());
+ EXPECT_EQ(criterion.logic, AudioHalCapCriterionV2::LogicalDisjunction::INCLUSIVE);
+ break;
+ }
+ case AudioHalCapCriterionV2::availableOutputDevicesAddresses: {
+ auto criterion =
+ criterionV2.get<AudioHalCapCriterionV2::availableOutputDevicesAddresses>();
+ EXPECT_FALSE(criterion.values.empty());
+ EXPECT_EQ(criterion.logic, AudioHalCapCriterionV2::LogicalDisjunction::INCLUSIVE);
+ break;
+ }
+ case AudioHalCapCriterionV2::telephonyMode: {
+ auto criterion = criterionV2.get<AudioHalCapCriterionV2::telephonyMode>();
+ EXPECT_FALSE(criterion.values.empty());
+ EXPECT_EQ(criterion.logic, AudioHalCapCriterionV2::LogicalDisjunction::EXCLUSIVE);
+ break;
+ }
+ case AudioHalCapCriterionV2::forceConfigForUse: {
+ auto criterion = criterionV2.get<AudioHalCapCriterionV2::forceConfigForUse>();
+ EXPECT_FALSE(criterion.values.empty());
+ EXPECT_EQ(criterion.logic, AudioHalCapCriterionV2::LogicalDisjunction::EXCLUSIVE);
+ break;
+ }
+ default:
+ ADD_FAILURE() << "Invalid criterion tag " << toString(criterionV2.getTag());
}
}
/**
- * Verify values only contain alphanumeric characters.
+ * Verify the rule involve the right matching logic according to the criterion logic.
+ * @param matchingRule logic followed by the rule
+ * @param logicalDisjunction logic exposed by the criterion
*/
- void ValidateAudioHalCapCriterionType(const AudioHalCapCriterionType& criterionType) {
- auto isNotAlnum = [](const char& c) { return !isalnum(c); };
- for (const std::string& value : criterionType.values) {
- EXPECT_EQ(find_if(value.begin(), value.end(), isNotAlnum), value.end());
+ void ValidateAudioHalCapRuleMatchingRule(
+ const AudioHalCapRule::MatchingRule matchingRule,
+ const AudioHalCapCriterionV2::LogicalDisjunction logicalDisjunction) {
+ if (logicalDisjunction == AudioHalCapCriterionV2::LogicalDisjunction::INCLUSIVE) {
+ EXPECT_TRUE(matchingRule == AudioHalCapRule::MatchingRule::EXCLUDES ||
+ matchingRule == AudioHalCapRule::MatchingRule::INCLUDES);
+ } else if (logicalDisjunction == AudioHalCapCriterionV2::LogicalDisjunction::EXCLUSIVE) {
+ EXPECT_TRUE(matchingRule == AudioHalCapRule::MatchingRule::IS ||
+ matchingRule == AudioHalCapRule::MatchingRule::IS_NOT);
+ } else {
+ ADD_FAILURE() << "Invalid criterion Logical rule";
}
}
/**
- * Verify each criterionType has a unique name.
- * Verify each criterion has a unique name.
- * Verify each criterion maps to a criterionType.
- * Verify each criterionType is used in a criterion.
- * Validate contained types.
+ * Verify that the value and the matching rule are supported by the given criterion
+ */
+ template <typename CriterionV2, typename Value>
+ void validateAudioHalCapRule(CriterionV2 criterionV2, Value value,
+ const AudioHalCapRule::MatchingRule matchingRule) {
+ ValidateAudioHalCapRuleMatchingRule(matchingRule, criterionV2.logic);
+ EXPECT_FALSE(criterionV2.values.empty());
+ auto values = criterionV2.values;
+ auto valueIt = find_if(values.begin(), values.end(),
+ [&](const auto& typedValue) { return typedValue == value; });
+ EXPECT_NE(valueIt, values.end());
+ }
+
+ /**
+ * Verify rule involves a supported criterion.
+ * Verify rule involves supported logic keyword according to logic rule exposed by the
+ * criterion.
+ * Verify rule involves a value supported by the associated criterion.
+ */
+ void ValidateAudioHalConfigurationRule(
+ const AudioHalCapRule& rule,
+ const std::vector<std::optional<AudioHalCapCriterionV2>>& criteria) {
+ const auto& compoundRule = rule.compoundRule;
+ using TypeTag = AudioHalCapCriterionV2::Type::Tag;
+ if (rule.nestedRules.empty() && rule.criterionRules.empty()) {
+ EXPECT_EQ(compoundRule, AudioHalCapRule::CompoundRule::ALL);
+ }
+ EXPECT_TRUE(compoundRule == AudioHalCapRule::CompoundRule::ANY ||
+ compoundRule == AudioHalCapRule::CompoundRule::ALL);
+ for (const auto& nestedRule : rule.nestedRules) {
+ ValidateAudioHalConfigurationRule(nestedRule, criteria);
+ }
+ for (const auto& criterionRule : rule.criterionRules) {
+ auto selectionCriterion = criterionRule.criterion;
+ auto criterionValue = criterionRule.criterionTypeValue;
+ auto matchesWhen = criterionRule.matchingRule;
+ auto criteriaIt = find_if(criteria.begin(), criteria.end(), [&](const auto& criterion) {
+ return criterion.has_value() &&
+ criterion.value().getTag() == selectionCriterion.getTag();
+ });
+ EXPECT_NE(criteriaIt, criteria.end())
+ << " Invalid rule criterion " << toString(selectionCriterion.getTag());
+ AudioHalCapCriterionV2 matchingCriterion = (*criteriaIt).value();
+ switch (selectionCriterion.getTag()) {
+ case AudioHalCapCriterionV2::availableInputDevices: {
+ EXPECT_EQ(criterionValue.getTag(), TypeTag::availableDevicesType);
+ validateAudioHalCapRule(
+ matchingCriterion.get<AudioHalCapCriterionV2::availableInputDevices>(),
+ criterionValue.get<TypeTag::availableDevicesType>(), matchesWhen);
+ break;
+ }
+ case AudioHalCapCriterionV2::availableOutputDevices: {
+ EXPECT_EQ(criterionValue.getTag(), TypeTag::availableDevicesType);
+ validateAudioHalCapRule(
+ matchingCriterion.get<AudioHalCapCriterionV2::availableOutputDevices>(),
+ criterionValue.get<TypeTag::availableDevicesType>(), matchesWhen);
+ break;
+ }
+ case AudioHalCapCriterionV2::availableInputDevicesAddresses: {
+ EXPECT_EQ(criterionValue.getTag(), TypeTag::availableDevicesAddressesType);
+ validateAudioHalCapRule(
+ matchingCriterion
+ .get<AudioHalCapCriterionV2::availableInputDevicesAddresses>(),
+ criterionValue.get<TypeTag::availableDevicesAddressesType>(),
+ matchesWhen);
+ break;
+ }
+ case AudioHalCapCriterionV2::availableOutputDevicesAddresses: {
+ EXPECT_EQ(criterionValue.getTag(), TypeTag::availableDevicesAddressesType);
+ validateAudioHalCapRule(
+ matchingCriterion
+ .get<AudioHalCapCriterionV2::availableOutputDevicesAddresses>(),
+ criterionValue.get<TypeTag::availableDevicesAddressesType>(),
+ matchesWhen);
+ break;
+ }
+ case AudioHalCapCriterionV2::telephonyMode: {
+ EXPECT_EQ(criterionValue.getTag(), TypeTag::telephonyModeType);
+ validateAudioHalCapRule(
+ matchingCriterion.get<AudioHalCapCriterionV2::telephonyMode>(),
+ criterionValue.get<TypeTag::telephonyModeType>(), matchesWhen);
+ break;
+ }
+ case AudioHalCapCriterionV2::forceConfigForUse: {
+ EXPECT_EQ(criterionValue.getTag(), TypeTag::forcedConfigType);
+ validateAudioHalCapRule(
+ matchingCriterion
+ .get<AudioHalCapCriterionV2::forceConfigForUse>(),
+ criterionValue.get<TypeTag::forcedConfigType>(), matchesWhen);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ }
+
+ /**
+ * Get the number of occurrence of a given parameter within a given vector of parameter.
+ * It just take into account the parameter, not its associated value.
+ * @param parameter to consider
+ * @param domainParameters to check against
+ * @return matching occurrence of the parameter within the provided vector.
+ */
+ size_t countsParameter(const AudioHalCapParameter& parameter,
+ const std::vector<AudioHalCapParameter>& domainParameters) {
+ size_t count = 0;
+ for (const auto& domainParameter : domainParameters) {
+ if (domainParameter.getTag() != parameter.getTag()) {
+ continue;
+ }
+ switch (domainParameter.getTag()) {
+ case AudioHalCapParameter::selectedStrategyDevice: {
+ auto typedDomainParam =
+ domainParameter.get<AudioHalCapParameter::selectedStrategyDevice>();
+ auto typedParam = parameter.get<AudioHalCapParameter::selectedStrategyDevice>();
+ if (typedDomainParam.id == typedParam.id &&
+ typedDomainParam.device == typedParam.device) {
+ count += 1;
+ }
+ break;
+ }
+ case AudioHalCapParameter::strategyDeviceAddress: {
+ auto typedDomainParam =
+ domainParameter.get<AudioHalCapParameter::strategyDeviceAddress>();
+ auto typedParam = parameter.get<AudioHalCapParameter::strategyDeviceAddress>();
+ if (typedDomainParam.id == typedParam.id) {
+ count += 1;
+ }
+ break;
+ }
+ case AudioHalCapParameter::selectedInputSourceDevice: {
+ auto typedDomainParam =
+ domainParameter.get<AudioHalCapParameter::selectedInputSourceDevice>();
+ auto typedParam =
+ parameter.get<AudioHalCapParameter::selectedInputSourceDevice>();
+ if (typedDomainParam.inputSource == typedParam.inputSource &&
+ typedDomainParam.device == typedParam.device) {
+ count += 1;
+ }
+ break;
+ }
+ case AudioHalCapParameter::streamVolumeProfile: {
+ auto typedDomainParam =
+ domainParameter.get<AudioHalCapParameter::streamVolumeProfile>();
+ auto typedParam = parameter.get<AudioHalCapParameter::streamVolumeProfile>();
+ if (typedDomainParam.stream == typedParam.stream) {
+ count += 1;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ return count;
+ }
+
+ /**
+ * Verify each configuration has unique name within a domain
+ * Verify no duplicate parameter within a domain.
+ * Verify that each configuration has no duplicated parameter.
+ * Verify that each configuration has an associated value for all parameter within a domain.
+ */
+ void ValidateAudioHalCapDomain(
+ const AudioHalCapDomain& domain,
+ const std::vector<std::optional<AudioHalCapCriterionV2>>& criteria) {
+ std::unordered_set<std::string> configurationNames;
+ for (const AudioHalCapConfiguration& configuration : domain.configurations) {
+ EXPECT_TRUE(configurationNames.insert(configuration.name).second);
+ ValidateAudioHalConfigurationRule(configuration.rule, criteria);
+ }
+ auto domainParameters = domain.configurations[0].parameterSettings;
+ for (const auto& settingParameter : domainParameters) {
+ EXPECT_EQ(1ul, countsParameter(settingParameter, domainParameters))
+ << "Duplicated parameter within domain " << domain.name << " configuration "
+ << domain.configurations[0].name << " for parameter "
+ << settingParameter.toString();
+ }
+ for (const auto& configuration : domain.configurations) {
+ auto configurationParameters = configuration.parameterSettings;
+ for (const auto& configurationParameter : configurationParameters) {
+ EXPECT_EQ(1ul, countsParameter(configurationParameter, configurationParameters))
+ << "Duplicated parameter within domain " << domain.name << " configuration "
+ << configuration.name << " for parameter "
+ << configurationParameter.toString();
+ }
+ EXPECT_EQ(domainParameters.size(), configurationParameters.size());
+ for (const auto& settingParameter : configuration.parameterSettings) {
+ EXPECT_EQ(1ul, countsParameter(settingParameter, domainParameters))
+ << "Confiugration " << configuration.name << " within domain "
+ << domain.name << " exposes invalid parameter "
+ << settingParameter.toString();
+ ;
+ }
+ }
+ }
+
+ /**
+ * Verify each domain has a unique name.
+ * Verify that a given parameter does not appear in more than one domain.
+ */
+ void ValidateAudioHalCapDomains(
+ const std::vector<std::optional<AudioHalCapDomain>>& domains,
+ const std::vector<std::optional<AudioHalCapCriterionV2>>& criteria) {
+ std::unordered_map<std::string, AudioHalCapDomain> domainMap;
+ std::vector<AudioHalCapParameter> allDomainParameters;
+ for (const auto& domain : domains) {
+ EXPECT_TRUE(domain.has_value());
+ EXPECT_FALSE(domain.value().configurations.empty());
+ auto domainParameters = domain.value().configurations[0].parameterSettings;
+ for (const auto& domainParameter : domainParameters) {
+ EXPECT_EQ(0ul, countsParameter(domainParameter, allDomainParameters))
+ << "Duplicated parameter in domain " << domain.value().name
+ << " for parameter " << domainParameter.toString();
+ allDomainParameters.push_back(domainParameter);
+ }
+ EXPECT_NO_FATAL_FAILURE(ValidateAudioHalCapDomain(domain.value(), criteria));
+ EXPECT_TRUE(domainMap.insert({domain.value().name, domain.value()}).second);
+ }
+ }
+
+ /**
+ * Verify unique criterion is provided for a given Tag, except for ForceUse
+ * Verify unique forceUse criterion are provided for usage
+ * Verify each criterion is validating.
+ * Verify domains.
*/
void ValidateCapSpecificConfig(const AudioHalEngineConfig::CapSpecificConfig& capCfg) {
- EXPECT_FALSE(capCfg.criteria.empty());
- EXPECT_FALSE(capCfg.criterionTypes.empty());
- std::unordered_map<std::string, AudioHalCapCriterionType> criterionTypeMap;
- for (const AudioHalCapCriterionType& criterionType : capCfg.criterionTypes) {
- EXPECT_NO_FATAL_FAILURE(ValidateAudioHalCapCriterionType(criterionType));
- EXPECT_TRUE(criterionTypeMap.insert({criterionType.name, criterionType}).second);
+ EXPECT_TRUE(capCfg.criteriaV2.has_value());
+ std::unordered_set<AudioHalCapCriterionV2::Tag> criterionTagSet;
+ std::unordered_set<AudioPolicyForceUse> forceUseCriterionUseSet;
+ for (const auto& criterion : capCfg.criteriaV2.value()) {
+ EXPECT_TRUE(criterion.has_value());
+ if (criterion.value().getTag() != AudioHalCapCriterionV2::forceConfigForUse) {
+ EXPECT_TRUE(criterionTagSet.insert(criterion.value().getTag()).second);
+ } else {
+ auto forceUseCriterion =
+ criterion.value().get<AudioHalCapCriterionV2::forceConfigForUse>();
+ EXPECT_TRUE(forceUseCriterionUseSet.insert(forceUseCriterion.forceUse).second);
+ }
+ EXPECT_NO_FATAL_FAILURE(ValidateAudioHalCapCriterion(criterion.value()));
}
- std::unordered_set<std::string> criterionNameSet;
- for (const AudioHalCapCriterion& criterion : capCfg.criteria) {
- EXPECT_TRUE(criterionNameSet.insert(criterion.name).second);
- EXPECT_EQ(criterionTypeMap.count(criterion.criterionTypeName), 1UL);
- EXPECT_NO_FATAL_FAILURE(ValidateAudioHalCapCriterion(
- criterion, criterionTypeMap.at(criterion.criterionTypeName)));
- }
- EXPECT_EQ(criterionTypeMap.size(), criterionNameSet.size());
+ ValidateAudioHalCapDomains(capCfg.domains.value(), capCfg.criteriaV2.value());
}
/**
diff --git a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
index 633fe52..9fe5801 100644
--- a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
@@ -87,6 +87,7 @@
using aidl::android::media::audio::common::AudioDeviceType;
using aidl::android::media::audio::common::AudioDualMonoMode;
using aidl::android::media::audio::common::AudioFormatType;
+using aidl::android::media::audio::common::AudioGainConfig;
using aidl::android::media::audio::common::AudioInputFlags;
using aidl::android::media::audio::common::AudioIoFlags;
using aidl::android::media::audio::common::AudioLatencyMode;
@@ -450,6 +451,7 @@
// This is implemented by the 'StreamFixture' utility class.
static constexpr int kNegativeTestBufferSizeFrames = 256;
static constexpr int kDefaultLargeBufferSizeFrames = 48000;
+ static constexpr int32_t kAidlVersion3 = 3;
void SetUpImpl(const std::string& moduleName, bool setUpDebug = true) {
ASSERT_NO_FATAL_FAILURE(ConnectToService(moduleName, setUpDebug));
@@ -478,6 +480,7 @@
if (setUpDebug) {
ASSERT_NO_FATAL_FAILURE(SetUpDebug());
}
+ ASSERT_TRUE(module->getInterfaceVersion(&aidlVersion).isOk());
}
void RestartService() {
@@ -490,6 +493,7 @@
if (setUpDebug) {
ASSERT_NO_FATAL_FAILURE(SetUpDebug());
}
+ ASSERT_TRUE(module->getInterfaceVersion(&aidlVersion).isOk());
}
void SetUpDebug() {
@@ -577,6 +581,7 @@
std::unique_ptr<WithDebugFlags> debug;
std::vector<AudioPort> initialPorts;
std::vector<AudioRoute> initialRoutes;
+ int32_t aidlVersion;
};
class WithDevicePortConnectedState {
@@ -1821,6 +1826,46 @@
}
}
+TEST_P(AudioCoreModule, SetAudioPortConfigInvalidPortAudioGain) {
+ if (aidlVersion < kAidlVersion3) {
+ GTEST_SKIP() << "Skip for audio HAL version lower than " << kAidlVersion3;
+ }
+ std::vector<AudioPort> ports;
+ ASSERT_IS_OK(module->getAudioPorts(&ports));
+ bool atLeastOnePortWithNonemptyGain = false;
+ for (const auto port : ports) {
+ AudioPortConfig portConfig;
+ portConfig.portId = port.id;
+ if (port.gains.empty()) {
+ continue;
+ }
+ atLeastOnePortWithNonemptyGain = true;
+ int index = 0;
+ ASSERT_NE(0, port.gains[index].stepValue) << "Invalid audio port config gain step 0";
+ portConfig.gain->index = index;
+ AudioGainConfig invalidGainConfig;
+
+ int invalidGain = port.gains[index].maxValue + port.gains[index].stepValue;
+ invalidGainConfig.values.push_back(invalidGain);
+ portConfig.gain.emplace(invalidGainConfig);
+ bool applied = true;
+ AudioPortConfig suggestedConfig;
+ EXPECT_STATUS(EX_ILLEGAL_ARGUMENT,
+ module->setAudioPortConfig(portConfig, &suggestedConfig, &applied))
+ << "invalid port gain " << invalidGain << " lower than min gain";
+
+ invalidGain = port.gains[index].minValue - port.gains[index].stepValue;
+ invalidGainConfig.values[0] = invalidGain;
+ portConfig.gain.emplace(invalidGainConfig);
+ EXPECT_STATUS(EX_ILLEGAL_ARGUMENT,
+ module->setAudioPortConfig(portConfig, &suggestedConfig, &applied))
+ << "invalid port gain " << invalidGain << "higher than max gain";
+ }
+ if (!atLeastOnePortWithNonemptyGain) {
+ GTEST_SKIP() << "No audio port contains non-empty gain configuration";
+ }
+}
+
TEST_P(AudioCoreModule, TryConnectMissingDevice) {
// Limit checks to connection types that are known to be detectable by HAL implementations.
static const std::set<std::string> kCheckedConnectionTypes{
@@ -2975,15 +3020,15 @@
// The five methods below is intended to be called after the worker
// thread has joined, thus no extra synchronization is needed.
- bool hasObservablePositionIncrease() const { return mObservablePositionIncrease; }
- bool hasObservableRetrogradePosition() const { return mRetrogradeObservablePosition; }
+ bool hasObservablePositionIncrease() const { return mObservable.hasPositionIncrease; }
+ bool hasObservableRetrogradePosition() const { return mObservable.hasRetrogradePosition; }
bool hasHardwarePositionIncrease() const {
// For non-MMap, always return true to pass the validation.
- return mIsMmap ? mHardwarePositionIncrease : true;
+ return mIsMmap ? mHardware.hasPositionIncrease : true;
}
bool hasHardwareRetrogradePosition() const {
// For non-MMap, always return false to pass the validation.
- return mIsMmap ? mRetrogradeHardwarePosition : false;
+ return mIsMmap ? mHardware.hasRetrogradePosition : false;
}
std::string getUnexpectedStateTransition() const { return mUnexpectedTransition; }
@@ -3011,25 +3056,9 @@
}
bool interceptRawReply(const StreamDescriptor::Reply&) override { return false; }
bool processValidReply(const StreamDescriptor::Reply& reply) override {
- if (reply.observable.frames != StreamDescriptor::Position::UNKNOWN) {
- if (mPreviousObservableFrames.has_value()) {
- if (reply.observable.frames > mPreviousObservableFrames.value()) {
- mObservablePositionIncrease = true;
- } else if (reply.observable.frames < mPreviousObservableFrames.value()) {
- mRetrogradeObservablePosition = true;
- }
- }
- mPreviousObservableFrames = reply.observable.frames;
- }
+ mObservable.update(reply.observable.frames);
if (mIsMmap) {
- if (mPreviousHardwareFrames.has_value()) {
- if (reply.hardware.frames > mPreviousHardwareFrames.value()) {
- mHardwarePositionIncrease = true;
- } else if (reply.hardware.frames < mPreviousHardwareFrames.value()) {
- mRetrogradeHardwarePosition = true;
- }
- }
- mPreviousHardwareFrames = reply.hardware.frames;
+ mHardware.update(reply.hardware.frames);
}
auto expected = mCommands->getExpectedStates();
@@ -3054,16 +3083,30 @@
}
protected:
+ struct FramesCounter {
+ std::optional<int64_t> previous;
+ bool hasPositionIncrease = false;
+ bool hasRetrogradePosition = false;
+
+ void update(int64_t position) {
+ if (position == StreamDescriptor::Position::UNKNOWN) return;
+ if (previous.has_value()) {
+ if (position > previous.value()) {
+ hasPositionIncrease = true;
+ } else if (position < previous.value()) {
+ hasRetrogradePosition = true;
+ }
+ }
+ previous = position;
+ }
+ };
+
std::shared_ptr<StateSequence> mCommands;
const size_t mFrameSizeBytes;
const bool mIsMmap;
std::optional<StreamDescriptor::State> mPreviousState;
- std::optional<int64_t> mPreviousObservableFrames;
- bool mObservablePositionIncrease = false;
- bool mRetrogradeObservablePosition = false;
- std::optional<int64_t> mPreviousHardwareFrames;
- bool mHardwarePositionIncrease = false;
- bool mRetrogradeHardwarePosition = false;
+ FramesCounter mObservable;
+ FramesCounter mHardware;
std::string mUnexpectedTransition;
};
diff --git a/audio/aidl/vts/VtsHalDownmixTargetTest.cpp b/audio/aidl/vts/VtsHalDownmixTargetTest.cpp
index a1491e6..bf22839 100644
--- a/audio/aidl/vts/VtsHalDownmixTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalDownmixTargetTest.cpp
@@ -149,22 +149,6 @@
mOutputBuffer.resize(mOutputBufferSize);
}
- // Generate mInputBuffer values between -kMaxDownmixSample to kMaxDownmixSample
- void generateInputBuffer(size_t position, bool isStrip) {
- size_t increment;
- if (isStrip)
- // Fill input at all the channels
- increment = 1;
- else
- // Fill input at only one channel
- increment = mInputChannelCount;
-
- for (size_t i = position; i < mInputBuffer.size(); i += increment) {
- mInputBuffer[i] =
- ((static_cast<float>(std::rand()) / RAND_MAX) * 2 - 1) * kMaxDownmixSample;
- }
- }
-
bool isLayoutValid(int32_t inputLayout) {
if (inputLayout & kMaxChannelMask) {
return false;
@@ -365,7 +349,8 @@
for (int32_t channel : supportedChannels) {
size_t position = std::distance(supportedChannels.begin(), supportedChannels.find(channel));
- generateInputBuffer(position, false /*isStripe*/);
+ generateInputBuffer(mInputBuffer, position, false /*isStripe*/,
+ mInputChannelCount /*channelCount*/, kMaxDownmixSample);
ASSERT_NO_FATAL_FAILURE(
processAndWriteToOutput(mInputBuffer, mOutputBuffer, mEffect, &mOpenEffectReturn));
validateOutput(channel, position);
@@ -417,7 +402,8 @@
ASSERT_NO_FATAL_FAILURE(setParameters(Downmix::Type::STRIP));
// Generate input buffer, call process and compare outputs
- generateInputBuffer(0 /*position*/, true /*isStripe*/);
+ generateInputBuffer(mInputBuffer, 0 /*position*/, true /*isStripe*/,
+ mInputChannelCount /*channelCount*/, kMaxDownmixSample);
ASSERT_NO_FATAL_FAILURE(
processAndWriteToOutput(mInputBuffer, mOutputBuffer, mEffect, &mOpenEffectReturn));
validateOutput();
diff --git a/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp b/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
index 1fe8beb..4c868a9 100644
--- a/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
@@ -32,7 +32,6 @@
using aidl::android::hardware::audio::effect::Parameter;
using android::hardware::audio::common::testing::detail::TestExecutionTracer;
-static constexpr float kMaxAudioSample = 1;
static constexpr int kZeroGain = 0;
static constexpr int kMaxGain = std::numeric_limits<int>::max();
static constexpr int kMinGain = std::numeric_limits<int>::min();
@@ -154,12 +153,14 @@
public:
LoudnessEnhancerDataTest() {
std::tie(mFactory, mDescriptor) = GetParam();
- mBufferSize = kFrameCount *
- getChannelCount(AudioChannelLayout::make<AudioChannelLayout::layoutMask>(
- AudioChannelLayout::LAYOUT_STEREO));
- generateInputBuffer();
+ size_t channelCount =
+ getChannelCount(AudioChannelLayout::make<AudioChannelLayout::layoutMask>(
+ AudioChannelLayout::LAYOUT_STEREO));
+ mBufferSizeInFrames = kFrameCount * channelCount;
+ mInputBuffer.resize(mBufferSizeInFrames);
+ generateInputBuffer(mInputBuffer, 0, true, channelCount, kMaxAudioSampleValue);
- mOutputBuffer.resize(mBufferSize);
+ mOutputBuffer.resize(mBufferSizeInFrames);
}
void SetUp() override {
@@ -177,14 +178,6 @@
TearDownLoudnessEnhancer();
}
- // Fill inputBuffer with random values between -kMaxAudioSample to kMaxAudioSample
- void generateInputBuffer() {
- for (size_t i = 0; i < mBufferSize; i++) {
- mInputBuffer.push_back(((static_cast<float>(std::rand()) / RAND_MAX) * 2 - 1) *
- kMaxAudioSample);
- }
- }
-
// Add gains to the mInputBuffer and store processed output to mOutputBuffer
void processAndWriteToOutput() {
// Check AidlMessageQueues are not null
@@ -220,7 +213,7 @@
}
void assertSequentialGains(const std::vector<int>& gainValues, bool isIncreasing) {
- std::vector<float> baseOutput(mBufferSize);
+ std::vector<float> baseOutput(mBufferSizeInFrames);
// Process a reference output buffer with 0 gain which gives compressed input values
binder_exception_t expected;
@@ -257,7 +250,7 @@
std::vector<float> mInputBuffer;
std::vector<float> mOutputBuffer;
- size_t mBufferSize;
+ size_t mBufferSizeInFrames;
};
TEST_P(LoudnessEnhancerDataTest, IncreasingGains) {
@@ -296,10 +289,10 @@
setParameters(kMaxGain, expected);
ASSERT_NO_FATAL_FAILURE(processAndWriteToOutput());
- // Validate that mOutputBuffer reaches to kMaxAudioSample for INT_MAX gain
+ // Validate that mOutputBuffer reaches to kMaxAudioSampleValue for INT_MAX gain
for (size_t i = 0; i < mOutputBuffer.size(); i++) {
if (mInputBuffer[i] != 0) {
- EXPECT_NEAR(kMaxAudioSample, abs(mOutputBuffer[i]), kAbsError);
+ EXPECT_NEAR(kMaxAudioSampleValue, abs(mOutputBuffer[i]), kAbsError);
} else {
ASSERT_EQ(mOutputBuffer[i], mInputBuffer[i]);
}
diff --git a/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp b/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp
index f215a8e..f89cb40 100644
--- a/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp
@@ -24,6 +24,7 @@
using namespace android;
+using aidl::android::hardware::audio::common::getChannelCount;
using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::getEffectTypeUuidVisualizer;
using aidl::android::hardware::audio::effect::IEffect;
@@ -56,6 +57,15 @@
mMeasurementMode(std::get<PARAM_MEASUREMENT_MODE>(GetParam())),
mLatency(std::get<PARAM_LATENCY>(GetParam())) {
std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
+
+ size_t channelCount =
+ getChannelCount(AudioChannelLayout::make<AudioChannelLayout::layoutMask>(
+ AudioChannelLayout::LAYOUT_STEREO));
+ mBufferSizeInFrames = kInputFrameCount * channelCount;
+ mInputBuffer.resize(mBufferSizeInFrames);
+ generateInputBuffer(mInputBuffer, 0, true, channelCount, kMaxAudioSampleValue);
+
+ mOutputBuffer.resize(mBufferSizeInFrames);
}
void SetUp() override {
@@ -65,14 +75,15 @@
Parameter::Common common = createParamCommon(
0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
- IEffect::OpenEffectReturn ret;
- ASSERT_NO_FATAL_FAILURE(open(mEffect, common, std::nullopt, &ret, EX_NONE));
+ ASSERT_NO_FATAL_FAILURE(open(mEffect, common, std::nullopt, &mOpenEffectReturn, EX_NONE));
ASSERT_NE(nullptr, mEffect);
+ mVersion = EffectFactoryHelper::getHalVersion(mFactory);
}
void TearDown() override {
ASSERT_NO_FATAL_FAILURE(close(mEffect));
ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+ mOpenEffectReturn = IEffect::OpenEffectReturn{};
}
static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
@@ -83,6 +94,12 @@
Visualizer::ScalingMode mScalingMode = Visualizer::ScalingMode::NORMALIZED;
Visualizer::MeasurementMode mMeasurementMode = Visualizer::MeasurementMode::NONE;
int mLatency = 0;
+ int mVersion = 0;
+ std::vector<float> mInputBuffer;
+ std::vector<float> mOutputBuffer;
+ size_t mBufferSizeInFrames;
+ IEffect::OpenEffectReturn mOpenEffectReturn;
+ bool mAllParamsValid = true;
void SetAndGetParameters() {
for (auto& it : mCommonTags) {
@@ -94,6 +111,7 @@
ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
const bool valid = isParameterValid<Visualizer, Range::visualizer>(vs, desc);
const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
+ if (expected == EX_ILLEGAL_ARGUMENT) mAllParamsValid = false;
// set parameter
Parameter expectParam;
@@ -153,23 +171,50 @@
};
TEST_P(VisualizerParamTest, SetAndGetCaptureSize) {
- EXPECT_NO_FATAL_FAILURE(addCaptureSizeParam(mCaptureSize));
- SetAndGetParameters();
+ ASSERT_NO_FATAL_FAILURE(addCaptureSizeParam(mCaptureSize));
+ ASSERT_NO_FATAL_FAILURE(SetAndGetParameters());
}
TEST_P(VisualizerParamTest, SetAndGetScalingMode) {
- EXPECT_NO_FATAL_FAILURE(addScalingModeParam(mScalingMode));
- SetAndGetParameters();
+ ASSERT_NO_FATAL_FAILURE(addScalingModeParam(mScalingMode));
+ ASSERT_NO_FATAL_FAILURE(SetAndGetParameters());
}
TEST_P(VisualizerParamTest, SetAndGetMeasurementMode) {
- EXPECT_NO_FATAL_FAILURE(addMeasurementModeParam(mMeasurementMode));
- SetAndGetParameters();
+ ASSERT_NO_FATAL_FAILURE(addMeasurementModeParam(mMeasurementMode));
+ ASSERT_NO_FATAL_FAILURE(SetAndGetParameters());
}
TEST_P(VisualizerParamTest, SetAndGetLatency) {
- EXPECT_NO_FATAL_FAILURE(addLatencyParam(mLatency));
- SetAndGetParameters();
+ ASSERT_NO_FATAL_FAILURE(addLatencyParam(mLatency));
+ ASSERT_NO_FATAL_FAILURE(SetAndGetParameters());
+}
+
+TEST_P(VisualizerParamTest, testCaptureSampleBufferSizeAndOutput) {
+ SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
+ ASSERT_NO_FATAL_FAILURE(addCaptureSizeParam(mCaptureSize));
+ ASSERT_NO_FATAL_FAILURE(addScalingModeParam(mScalingMode));
+ ASSERT_NO_FATAL_FAILURE(addMeasurementModeParam(mMeasurementMode));
+ ASSERT_NO_FATAL_FAILURE(addLatencyParam(mLatency));
+ ASSERT_NO_FATAL_FAILURE(SetAndGetParameters());
+
+ Parameter getParam;
+ Parameter::Id id;
+ Visualizer::Id vsId;
+ vsId.set<Visualizer::Id::commonTag>(Visualizer::captureSampleBuffer);
+ id.set<Parameter::Id::visualizerTag>(vsId);
+ EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam)) << " with: " << id.toString();
+
+ ASSERT_NO_FATAL_FAILURE(processAndWriteToOutput(mInputBuffer, mOutputBuffer, mEffect,
+ &mOpenEffectReturn, mVersion));
+ ASSERT_EQ(mInputBuffer, mOutputBuffer);
+
+ if (mAllParamsValid) {
+ std::vector<uint8_t> captureBuffer = getParam.get<Parameter::specific>()
+ .get<Parameter::Specific::visualizer>()
+ .get<Visualizer::captureSampleBuffer>();
+ ASSERT_EQ((size_t)mCaptureSize, captureBuffer.size());
+ }
}
std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
diff --git a/audio/common/all-versions/default/7.0/HidlUtils.cpp b/audio/common/all-versions/default/7.0/HidlUtils.cpp
index f89c898..bc056e2 100644
--- a/audio/common/all-versions/default/7.0/HidlUtils.cpp
+++ b/audio/common/all-versions/default/7.0/HidlUtils.cpp
@@ -1025,7 +1025,7 @@
result = BAD_VALUE;
}
}
- std::string fullHalTags{std::move(halTagsBuffer.str())};
+ std::string fullHalTags{halTagsBuffer.str()};
strncpy(halTags, fullHalTags.c_str(), AUDIO_ATTRIBUTES_TAGS_MAX_SIZE);
CONVERT_CHECKED(fullHalTags.length() <= AUDIO_ATTRIBUTES_TAGS_MAX_SIZE ? NO_ERROR : BAD_VALUE,
result);
diff --git a/audio/policy/1.0/vts/functional/Android.bp b/audio/policy/1.0/vts/functional/Android.bp
index b32c223..c2335e4 100644
--- a/audio/policy/1.0/vts/functional/Android.bp
+++ b/audio/policy/1.0/vts/functional/Android.bp
@@ -17,8 +17,9 @@
"libxml2",
"liblog",
"libmedia_helper",
- "libaudiopolicyengine_config",
+ "libaudiopolicycapengine_config",
"libaudiopolicycomponents",
+ "libaudiopolicyengine_config",
"libaudiopolicyengineconfigurable_pfwwrapper",
"android.hardware.audio.common.test.utility",
"libparameter",
diff --git a/audio/policy/1.0/xml/api/current.txt b/audio/policy/1.0/xml/api/current.txt
index 01d77d7..19a8123 100644
--- a/audio/policy/1.0/xml/api/current.txt
+++ b/audio/policy/1.0/xml/api/current.txt
@@ -162,7 +162,9 @@
public static class ProductStrategies.ProductStrategy {
ctor public ProductStrategies.ProductStrategy();
method public java.util.List<audio.policy.V1_0.AttributesGroup> getAttributesGroup();
+ method public int getId();
method public String getName();
+ method public void setId(int);
method public void setName(String);
}
diff --git a/audio/policy/1.0/xml/audio_policy_engine_configuration.xsd b/audio/policy/1.0/xml/audio_policy_engine_configuration.xsd
index 40396bb..02e593a 100644
--- a/audio/policy/1.0/xml/audio_policy_engine_configuration.xsd
+++ b/audio/policy/1.0/xml/audio_policy_engine_configuration.xsd
@@ -105,6 +105,7 @@
<xs:element name="AttributesGroup" type="AttributesGroup" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
+ <xs:attribute name="id" type="xs:int" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
diff --git a/authsecret/aidl/Android.bp b/authsecret/aidl/Android.bp
index 90e128d..b5e4e3d 100644
--- a/authsecret/aidl/Android.bp
+++ b/authsecret/aidl/Android.bp
@@ -10,6 +10,7 @@
aidl_interface {
name: "android.hardware.authsecret",
vendor_available: true,
+ frozen: true,
srcs: ["android/hardware/authsecret/*.aidl"],
stability: "vintf",
backend: {
diff --git a/automotive/evs/1.1/default/EvsCamera.cpp b/automotive/evs/1.1/default/EvsCamera.cpp
index 520670a..fb598ff 100644
--- a/automotive/evs/1.1/default/EvsCamera.cpp
+++ b/automotive/evs/1.1/default/EvsCamera.cpp
@@ -495,7 +495,7 @@
}
if (!stored) {
// Add a BufferRecord wrapping this handle to our set of available buffers
- mBuffers.push_back(std::move(BufferRecord(memHandle)));
+ mBuffers.push_back(BufferRecord(memHandle));
}
mFramesAllowed++;
diff --git a/automotive/evs/aidl/impl/default/src/ConfigManager.cpp b/automotive/evs/aidl/impl/default/src/ConfigManager.cpp
index ba4cdc0..d8961d0 100644
--- a/automotive/evs/aidl/impl/default/src/ConfigManager.cpp
+++ b/automotive/evs/aidl/impl/default/src/ConfigManager.cpp
@@ -199,8 +199,8 @@
CameraParam aParam;
if (ConfigManagerUtil::convertToEvsCameraParam(nameAttr, aParam)) {
- aCamera->controls.insert_or_assign(
- aParam, std::move(std::make_tuple(minVal, maxVal, stepVal)));
+ aCamera->controls.insert_or_assign(aParam,
+ std::make_tuple(minVal, maxVal, stepVal));
}
ctrlElem = ctrlElem->NextSiblingElement("control");
@@ -583,8 +583,8 @@
CameraCtrl* ptr = reinterpret_cast<CameraCtrl*>(p);
for (size_t idx = 0; idx < sz; ++idx) {
CameraCtrl temp = *ptr++;
- aCamera->controls.insert_or_assign(
- temp.cid, std::move(std::make_tuple(temp.min, temp.max, temp.step)));
+ aCamera->controls.insert_or_assign(temp.cid,
+ std::make_tuple(temp.min, temp.max, temp.step));
}
p = reinterpret_cast<char*>(ptr);
@@ -689,8 +689,8 @@
CameraCtrl* ptr = reinterpret_cast<CameraCtrl*>(p);
for (size_t idx = 0; idx < sz; ++idx) {
CameraCtrl temp = *ptr++;
- aCamera->controls.insert_or_assign(
- temp.cid, std::move(std::make_tuple(temp.min, temp.max, temp.step)));
+ aCamera->controls.insert_or_assign(temp.cid,
+ std::make_tuple(temp.min, temp.max, temp.step));
}
p = reinterpret_cast<char*>(ptr);
diff --git a/automotive/evs/aidl/impl/default/src/EvsGlDisplay.cpp b/automotive/evs/aidl/impl/default/src/EvsGlDisplay.cpp
index 5b5cbcc..cf94e38 100644
--- a/automotive/evs/aidl/impl/default/src/EvsGlDisplay.cpp
+++ b/automotive/evs/aidl/impl/default/src/EvsGlDisplay.cpp
@@ -353,7 +353,7 @@
.buffer =
{
.description = mBuffer.description,
- .handle = std::move(::android::dupToAidl(mBuffer.handle)),
+ .handle = ::android::dupToAidl(mBuffer.handle),
},
.pixelSizeBytes = 4, // RGBA_8888 is 4-byte-per-pixel format
.bufferId = mBuffer.fingerprint,
diff --git a/automotive/evs/aidl/vts/FrameHandler.cpp b/automotive/evs/aidl/vts/FrameHandler.cpp
index e51be67..88c3643 100644
--- a/automotive/evs/aidl/vts/FrameHandler.cpp
+++ b/automotive/evs/aidl/vts/FrameHandler.cpp
@@ -50,12 +50,12 @@
}
} else {
for (auto i = 0; i < handle.fds.size(); ++i) {
- dup.fds[i] = std::move(handle.fds[i].dup());
+ dup.fds[i] = handle.fds[i].dup();
}
}
dup.ints = handle.ints;
- return std::move(dup);
+ return dup;
}
HardwareBuffer dupHardwareBuffer(const HardwareBuffer& buffer, bool doDup) {
@@ -64,7 +64,7 @@
.handle = dupNativeHandle(buffer.handle, doDup),
};
- return std::move(dup);
+ return dup;
}
BufferDesc dupBufferDesc(const BufferDesc& src, bool doDup) {
@@ -77,7 +77,7 @@
.metadata = src.metadata,
};
- return std::move(dup);
+ return dup;
}
bool comparePayload(const EvsEventDesc& l, const EvsEventDesc& r) {
diff --git a/automotive/ivn_android_device/impl/default/src/IvnAndroidDeviceService.cpp b/automotive/ivn_android_device/impl/default/src/IvnAndroidDeviceService.cpp
index 81f18b2..4166fdc 100644
--- a/automotive/ivn_android_device/impl/default/src/IvnAndroidDeviceService.cpp
+++ b/automotive/ivn_android_device/impl/default/src/IvnAndroidDeviceService.cpp
@@ -48,7 +48,8 @@
}
bool IvnAndroidDeviceService::init() {
- std::ifstream configStream(mConfigPath);
+ std::string configPathStr(mConfigPath);
+ std::ifstream configStream(configPathStr);
if (!configStream) {
LOG(ERROR) << "couldn't open " << mConfigPath << " for parsing.";
return false;
diff --git a/automotive/occupant_awareness/aidl/Android.bp b/automotive/occupant_awareness/aidl/Android.bp
index 1a8124c..33406ba 100644
--- a/automotive/occupant_awareness/aidl/Android.bp
+++ b/automotive/occupant_awareness/aidl/Android.bp
@@ -14,6 +14,7 @@
"android/hardware/automotive/occupant_awareness/*.aidl",
],
stability: "vintf",
+ frozen: true,
backend: {
java: {
sdk_version: "module_current",
diff --git a/automotive/remoteaccess/hal/default/Android.bp b/automotive/remoteaccess/hal/default/Android.bp
index cc8f2b0..b6c0525 100644
--- a/automotive/remoteaccess/hal/default/Android.bp
+++ b/automotive/remoteaccess/hal/default/Android.bp
@@ -51,15 +51,22 @@
cc_binary {
name: "android.hardware.automotive.remoteaccess@V2-default-service",
defaults: ["remote-access-hal-defaults"],
- vintf_fragments: ["remoteaccess-default-service.xml"],
init_rc: ["remoteaccess-default-service.rc"],
+ vintf_fragment_modules: ["remoteaccess-default-service.xml"],
+
}
cc_binary {
name: "android.hardware.automotive.remoteaccess@V2-tcu-test-service",
defaults: ["remote-access-hal-defaults"],
- vintf_fragments: ["remoteaccess-default-service.xml"],
init_rc: ["remoteaccess-tcu-test-service.rc"],
+ vintf_fragment_modules: ["remoteaccess-default-service.xml"],
+}
+
+vintf_fragment {
+ name: "remoteaccess-default-service.xml",
+ src: "remoteaccess-default-service.xml",
+ vendor: true,
}
cc_library {
diff --git a/automotive/vehicle/2.0/default/common/src/VehicleHalManager.cpp b/automotive/vehicle/2.0/default/common/src/VehicleHalManager.cpp
index e34e692..3d6e475 100644
--- a/automotive/vehicle/2.0/default/common/src/VehicleHalManager.cpp
+++ b/automotive/vehicle/2.0/default/common/src/VehicleHalManager.cpp
@@ -583,12 +583,12 @@
while (*index < options.size()) {
std::string option = options[*index];
if (kSetPropOptions.find(option) != kSetPropOptions.end()) {
- return std::move(values);
+ return values;
}
values.push_back(option);
(*index)++;
}
- return std::move(values);
+ return values;
}
bool VehicleHalManager::parseSetPropOptions(int fd, const hidl_vec<hidl_string>& options,
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHalServer.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHalServer.cpp
index 4704917..86fc70a 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHalServer.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHalServer.cpp
@@ -509,7 +509,7 @@
int64_t timestamp;
int32_t areaId = 0;
if (options[1] == "--setint") {
- updatedPropValue = std::move(createVehiclePropValue(VehiclePropertyType::INT32, 1));
+ updatedPropValue = createVehiclePropValue(VehiclePropertyType::INT32, 1);
if (!android::base::ParseInt(options[3], &intValue)) {
result.buffer += "failed to parse value as int: \"" + options[3] + "\"\n";
result.buffer += getHelpInfo();
@@ -517,7 +517,7 @@
}
updatedPropValue->value.int32Values[0] = intValue;
} else if (options[1] == "--setbool") {
- updatedPropValue = std::move(createVehiclePropValue(VehiclePropertyType::BOOLEAN, 1));
+ updatedPropValue = createVehiclePropValue(VehiclePropertyType::BOOLEAN, 1);
if (options[3] == "true" || options[3] == "True") {
updatedPropValue->value.int32Values[0] = 1;
} else if (options[3] == "false" || options[3] == "False") {
@@ -529,7 +529,7 @@
return result;
}
} else {
- updatedPropValue = std::move(createVehiclePropValue(VehiclePropertyType::FLOAT, 1));
+ updatedPropValue = createVehiclePropValue(VehiclePropertyType::FLOAT, 1);
if (!android::base::ParseFloat(options[3], &floatValue)) {
result.buffer += "failed to parse value as float: \"" + options[3] + "\"\n";
result.buffer += getHelpInfo();
diff --git a/automotive/vehicle/aidl/emu_metadata/android.hardware.automotive.vehicle-types-meta.json b/automotive/vehicle/aidl/emu_metadata/android.hardware.automotive.vehicle-types-meta.json
index de0e398..8ef440d 100644
--- a/automotive/vehicle/aidl/emu_metadata/android.hardware.automotive.vehicle-types-meta.json
+++ b/automotive/vehicle/aidl/emu_metadata/android.hardware.automotive.vehicle-types-meta.json
@@ -501,7 +501,7 @@
{
"name": "AP_POWER_STATE_REQ",
"value": 289475072,
- "description": "Property to control power state of application processor\nIt is assumed that AP's power state is controlled by a separate power controller.\nFor configuration information, VehiclePropConfig.configArray must have bit flag combining values in VehicleApPowerStateConfigFlag.\nint32Values[0] : VehicleApPowerStateReq enum value int32Values[1] : additional parameter relevant for each state, 0 if not used."
+ "description": "Property to control power state of application processor\nIt is assumed that AP's power state is controlled by a separate power controller.\nFor configuration information, VehiclePropConfig.configArray must have bit flag combining values in VehicleApPowerStateConfigFlag.\nconfigArray[0] : Bit flag combining values in VehicleApPowerStateConfigFlag, 0x0 if not used, 0x1 for enabling suspend to ram, 0x2 for supporting powering on AP from off state after timeout. 0x4 for enabling suspend to disk,\nint32Values[0] : VehicleApPowerStateReq enum value int32Values[1] : additional parameter relevant for each state, 0 if not used."
},
{
"name": "AP_POWER_STATE_REPORT",
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h b/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
index ec69894..5916307 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
@@ -56,6 +56,13 @@
FakeVehicleHardware(std::string defaultConfigDir, std::string overrideConfigDir,
bool forceOverride);
+ // s2rS2dConfig is the config for whether S2R or S2D is supported, must be a bit flag combining
+ // values from VehicleApPowerStateConfigFlag.
+ // The default implementation is reading this from system property:
+ // "ro.vendor.fake_vhal.ap_power_state_req.config".
+ FakeVehicleHardware(std::string defaultConfigDir, std::string overrideConfigDir,
+ bool forceOverride, int32_t s2rS2dConfig);
+
~FakeVehicleHardware();
// Get all the property configs.
@@ -193,7 +200,7 @@
// provides power controlling related properties.
std::string mPowerControllerServiceAddress = "";
- void init();
+ void init(int32_t s2rS2dConfig);
// Stores the initial value to property store.
void storePropInitialValue(const ConfigDeclaration& config);
// The callback that would be called when a vehicle property value change happens.
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
index 54dcca2..b301557 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
@@ -348,6 +348,13 @@
FakeVehicleHardware::FakeVehicleHardware(std::string defaultConfigDir,
std::string overrideConfigDir, bool forceOverride)
+ : FakeVehicleHardware(defaultConfigDir, overrideConfigDir, forceOverride,
+ /*s2rS2dConfig=*/
+ GetIntProperty(POWER_STATE_REQ_CONFIG_PROPERTY, /*default_value=*/0)) {}
+
+FakeVehicleHardware::FakeVehicleHardware(std::string defaultConfigDir,
+ std::string overrideConfigDir, bool forceOverride,
+ int32_t s2rS2dConfig)
: mValuePool(std::make_unique<VehiclePropValuePool>()),
mServerSidePropStore(new VehiclePropertyStore(mValuePool)),
mDefaultConfigDir(defaultConfigDir),
@@ -360,7 +367,7 @@
mPendingGetValueRequests(this),
mPendingSetValueRequests(this),
mForceOverride(forceOverride) {
- init();
+ init(s2rS2dConfig);
}
FakeVehicleHardware::~FakeVehicleHardware() {
@@ -388,7 +395,7 @@
return configsByPropId;
}
-void FakeVehicleHardware::init() {
+void FakeVehicleHardware::init(int32_t s2rS2dConfig) {
maybeGetGrpcServiceInfo(&mPowerControllerServiceAddress);
for (auto& [_, configDeclaration] : loadConfigDeclarations()) {
@@ -396,8 +403,7 @@
VehiclePropertyStore::TokenFunction tokenFunction = nullptr;
if (cfg.prop == toInt(VehicleProperty::AP_POWER_STATE_REQ)) {
- int config = GetIntProperty(POWER_STATE_REQ_CONFIG_PROPERTY, /*default_value=*/0);
- cfg.configArray[0] = config;
+ cfg.configArray[0] = s2rS2dConfig;
} else if (cfg.prop == OBD2_FREEZE_FRAME) {
tokenFunction = [](const VehiclePropValue& propValue) { return propValue.timestamp; };
}
@@ -532,6 +538,9 @@
<< getErrorMsg(writeResult);
}
break;
+ case toInt(VehicleApPowerStateReport::ON):
+ ALOGI("Received VehicleApPowerStateReport::ON, entering normal operating state");
+ break;
default:
ALOGE("Unknown VehicleApPowerStateReport: %d", state);
break;
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
index 8dbba19..f6098ca 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
@@ -20,6 +20,7 @@
#include <FakeUserHal.h>
#include <PropertyUtils.h>
+#include <aidl/android/hardware/automotive/vehicle/VehicleApPowerStateConfigFlag.h>
#include <aidl/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.h>
#include <android/hardware/automotive/vehicle/TestVendorProperty.h>
@@ -73,6 +74,7 @@
using ::aidl::android::hardware::automotive::vehicle::SetValueResult;
using ::aidl::android::hardware::automotive::vehicle::StatusCode;
using ::aidl::android::hardware::automotive::vehicle::SubscribeOptions;
+using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateConfigFlag;
using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReport;
using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReq;
using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateShutdownParam;
@@ -1871,7 +1873,7 @@
TEST_F(FakeVehicleHardwareTest, testGetHvacPropNotAvailable) {
FakeVehicleHardwareTestHelper helper(getHardware());
- auto hvacPowerOnConfig = std::move(getVehiclePropConfig(toInt(VehicleProperty::HVAC_POWER_ON)));
+ auto hvacPowerOnConfig = getVehiclePropConfig(toInt(VehicleProperty::HVAC_POWER_ON));
EXPECT_NE(hvacPowerOnConfig, nullptr);
for (auto& hvacPowerOnAreaConfig : hvacPowerOnConfig->areaConfigs) {
int hvacPowerAreaId = hvacPowerOnAreaConfig.areaId;
@@ -1882,7 +1884,7 @@
EXPECT_EQ(status, StatusCode::OK);
for (auto& powerPropId : helper.getHvacPowerDependentProps()) {
- auto powerPropConfig = std::move(getVehiclePropConfig(powerPropId));
+ auto powerPropConfig = getVehiclePropConfig(powerPropId);
EXPECT_NE(powerPropConfig, nullptr);
if (powerPropConfig->access == VehiclePropertyAccess::WRITE) {
continue;
@@ -1918,7 +1920,7 @@
TEST_F(FakeVehicleHardwareTest, testSetHvacPropNotAvailable) {
FakeVehicleHardwareTestHelper helper(getHardware());
- auto hvacPowerOnConfig = std::move(getVehiclePropConfig(toInt(VehicleProperty::HVAC_POWER_ON)));
+ auto hvacPowerOnConfig = getVehiclePropConfig(toInt(VehicleProperty::HVAC_POWER_ON));
EXPECT_NE(hvacPowerOnConfig, nullptr);
for (auto& hvacPowerOnAreaConfig : hvacPowerOnConfig->areaConfigs) {
int hvacPowerAreaId = hvacPowerOnAreaConfig.areaId;
@@ -1929,7 +1931,7 @@
EXPECT_EQ(status, StatusCode::OK);
for (auto& powerPropId : helper.getHvacPowerDependentProps()) {
- auto powerPropConfig = std::move(getVehiclePropConfig(powerPropId));
+ auto powerPropConfig = getVehiclePropConfig(powerPropId);
EXPECT_NE(powerPropConfig, nullptr);
if (powerPropConfig->access == VehiclePropertyAccess::READ) {
continue;
@@ -1968,7 +1970,7 @@
TEST_F(FakeVehicleHardwareTest, testHvacPowerOnSendCurrentHvacPropValues) {
FakeVehicleHardwareTestHelper helper(getHardware());
- auto hvacPowerOnConfig = std::move(getVehiclePropConfig(toInt(VehicleProperty::HVAC_POWER_ON)));
+ auto hvacPowerOnConfig = getVehiclePropConfig(toInt(VehicleProperty::HVAC_POWER_ON));
EXPECT_NE(hvacPowerOnConfig, nullptr);
for (auto& hvacPowerOnAreaConfig : hvacPowerOnConfig->areaConfigs) {
int hvacPowerAreaId = hvacPowerOnAreaConfig.areaId;
@@ -2007,9 +2009,9 @@
}
TEST_F(FakeVehicleHardwareTest, testHvacDualOnSynchronizesTemp) {
- auto hvacDualOnConfig = std::move(getVehiclePropConfig(toInt(VehicleProperty::HVAC_DUAL_ON)));
+ auto hvacDualOnConfig = getVehiclePropConfig(toInt(VehicleProperty::HVAC_DUAL_ON));
auto hvacTemperatureSetConfig =
- std::move(getVehiclePropConfig(toInt(VehicleProperty::HVAC_TEMPERATURE_SET)));
+ getVehiclePropConfig(toInt(VehicleProperty::HVAC_TEMPERATURE_SET));
EXPECT_NE(hvacDualOnConfig, nullptr);
EXPECT_NE(hvacTemperatureSetConfig, nullptr);
for (auto& hvacTemperatureSetConfig : hvacTemperatureSetConfig->areaConfigs) {
@@ -3605,7 +3607,7 @@
// Config array values from HVAC_TEMPERATURE_SET in DefaultProperties.json
auto configs = getHardware()->getAllPropertyConfigs();
auto hvacTemperatureSetConfig =
- std::move(getVehiclePropConfig(toInt(VehicleProperty::HVAC_TEMPERATURE_SET)));
+ getVehiclePropConfig(toInt(VehicleProperty::HVAC_TEMPERATURE_SET));
EXPECT_NE(hvacTemperatureSetConfig, nullptr);
auto& hvacTemperatureSetConfigArray = hvacTemperatureSetConfig->configArray;
@@ -3863,6 +3865,25 @@
}
}
+TEST_F(FakeVehicleHardwareTest, testOverrideApPowerStateReqConfig) {
+ auto hardware = std::make_unique<FakeVehicleHardware>(
+ android::base::GetExecutableDirectory(),
+ /*overrideConfigDir=*/"",
+ /*forceOverride=*/false,
+ toInt(VehicleApPowerStateConfigFlag::ENABLE_DEEP_SLEEP_FLAG) |
+ toInt(VehicleApPowerStateConfigFlag::ENABLE_HIBERNATION_FLAG));
+
+ std::vector<VehiclePropConfig> configs = hardware->getAllPropertyConfigs();
+
+ for (const auto& config : configs) {
+ if (config.prop != toInt(VehicleProperty::AP_POWER_STATE_REQ)) {
+ continue;
+ }
+ ASSERT_EQ(config.configArray[0], 0x5);
+ break;
+ }
+}
+
} // namespace fake
} // namespace vehicle
} // namespace automotive
diff --git a/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp b/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp
index a7caeb1..c3a46c6 100644
--- a/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp
+++ b/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp
@@ -289,7 +289,7 @@
for (auto const& [_, record] : mRecordsByPropId) {
for (auto const& [_, value] : record.values) {
- allValues.push_back(std::move(mValuePool->obtain(*value)));
+ allValues.push_back(mValuePool->obtain(*value));
}
}
@@ -308,7 +308,7 @@
}
for (auto const& [_, value] : record->values) {
- values.push_back(std::move(mValuePool->obtain(*value)));
+ values.push_back(mValuePool->obtain(*value));
}
return values;
}
diff --git a/automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp b/automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp
index 6646b7e..22f5c73 100644
--- a/automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp
+++ b/automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp
@@ -328,7 +328,7 @@
TEST_F(VehiclePropertyStoreTest, testRemoveValuesForProperty) {
auto values = getTestPropValues();
for (const auto& value : values) {
- ASSERT_RESULT_OK(mStore->writeValue(std::move(mValuePool->obtain(value))));
+ ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(value)));
}
mStore->removeValuesForProperty(toInt(VehicleProperty::INFO_FUEL_CAPACITY));
diff --git a/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h b/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
index fa2a310..b58d0f5 100644
--- a/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
+++ b/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
@@ -31,6 +31,7 @@
#include <android-base/thread_annotations.h>
#include <android/binder_auto_utils.h>
+#include <functional>
#include <memory>
#include <mutex>
#include <shared_mutex>
@@ -138,12 +139,11 @@
// Only used for testing.
int32_t mTestInterfaceVersion = 0;
- // mConfigsByPropId and mConfigFile is lazy initialized.
- mutable std::mutex mConfigInitLock;
- mutable bool mConfigInit GUARDED_BY(mConfigInitLock) = false;
+ mutable std::atomic<bool> mConfigInit = false;
+ mutable std::shared_timed_mutex mConfigLock;
mutable std::unordered_map<int32_t, aidlvhal::VehiclePropConfig> mConfigsByPropId
- GUARDED_BY(mConfigInitLock);
- mutable std::unique_ptr<ndk::ScopedFileDescriptor> mConfigFile GUARDED_BY(mConfigInitLock);
+ GUARDED_BY(mConfigLock);
+ mutable std::unique_ptr<ndk::ScopedFileDescriptor> mConfigFile GUARDED_BY(mConfigLock);
std::mutex mLock;
std::unordered_map<const AIBinder*, std::unique_ptr<OnBinderDiedContext>> mOnBinderDiedContexts
@@ -175,7 +175,10 @@
android::base::Result<std::vector<int64_t>> checkDuplicateRequests(
const std::vector<aidlvhal::SetValueRequest>& requests);
- VhalResult<void> checkSubscribeOptions(const std::vector<aidlvhal::SubscribeOptions>& options);
+ VhalResult<void> checkSubscribeOptions(
+ const std::vector<aidlvhal::SubscribeOptions>& options,
+ const std::unordered_map<int32_t, aidlvhal::VehiclePropConfig>& configsByPropId)
+ REQUIRES_SHARED(mConfigLock);
VhalResult<void> checkPermissionHelper(const aidlvhal::VehiclePropValue& value,
aidlvhal::VehiclePropertyAccess accessToTest) const;
@@ -184,7 +187,7 @@
VhalResult<void> checkWritePermission(const aidlvhal::VehiclePropValue& value) const;
- android::base::Result<const aidlvhal::VehiclePropConfig*> getConfig(int32_t propId) const;
+ android::base::Result<aidlvhal::VehiclePropConfig> getConfig(int32_t propId) const;
void onBinderDiedWithContext(const AIBinder* clientId);
@@ -196,7 +199,7 @@
bool checkDumpPermission();
- bool getAllPropConfigsFromHardwareLocked() const REQUIRES(mConfigInitLock);
+ bool getAllPropConfigsFromHardwareLocked() const EXCLUDES(mConfigLock);
// The looping handler function to process all onBinderDied or onBinderUnlinked events in
// mBinderEvents.
@@ -209,10 +212,12 @@
int32_t getVhalInterfaceVersion() const;
- // Gets mConfigsByPropId, lazy init it if necessary.
- const std::unordered_map<int32_t, aidlvhal::VehiclePropConfig>& getConfigsByPropId() const;
- // Gets mConfigFile, lazy init it if necessary.
- const ndk::ScopedFileDescriptor* getConfigFile() const;
+ // Gets mConfigsByPropId, lazy init it if necessary. Note that the reference is only valid in
+ // the scope of the callback and it is guaranteed that read lock is obtained during the
+ // callback.
+ void getConfigsByPropId(
+ std::function<void(const std::unordered_map<int32_t, aidlvhal::VehiclePropConfig>&)>
+ callback) const EXCLUDES(mConfigLock);
// Puts the property change events into a queue so that they can handled in batch.
static void batchPropertyChangeEvent(
@@ -239,6 +244,12 @@
static void onBinderUnlinked(void* cookie);
+ static void parseSubscribeOptions(
+ const std::vector<aidlvhal::SubscribeOptions>& options,
+ const std::unordered_map<int32_t, aidlvhal::VehiclePropConfig>& configsByPropId,
+ std::vector<aidlvhal::SubscribeOptions>& onChangeSubscriptions,
+ std::vector<aidlvhal::SubscribeOptions>& continuousSubscriptions);
+
// Test-only
// Set the default timeout for pending requests.
void setTimeout(int64_t timeoutInNano);
diff --git a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
index 9dc039d..e062a28 100644
--- a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
@@ -95,6 +95,18 @@
return sampleRateHz;
}
+class SCOPED_CAPABILITY SharedScopedLockAssertion {
+ public:
+ SharedScopedLockAssertion(std::shared_timed_mutex& mutex) ACQUIRE_SHARED(mutex) {}
+ ~SharedScopedLockAssertion() RELEASE() {}
+};
+
+class SCOPED_CAPABILITY UniqueScopedLockAssertion {
+ public:
+ UniqueScopedLockAssertion(std::shared_timed_mutex& mutex) ACQUIRE(mutex) {}
+ ~UniqueScopedLockAssertion() RELEASE() {}
+};
+
} // namespace
DefaultVehicleHal::DefaultVehicleHal(std::unique_ptr<IVehicleHardware> vehicleHardware)
@@ -355,68 +367,82 @@
}
filteredConfigs.push_back(std::move(config));
}
- for (auto& config : filteredConfigs) {
- mConfigsByPropId[config.prop] = config;
- }
- VehiclePropConfigs vehiclePropConfigs;
- vehiclePropConfigs.payloads = std::move(filteredConfigs);
- auto result = LargeParcelableBase::parcelableToStableLargeParcelable(vehiclePropConfigs);
- if (!result.ok()) {
- ALOGE("failed to convert configs to shared memory file, error: %s, code: %d",
- result.error().message().c_str(), static_cast<int>(result.error().code()));
- mConfigFile = nullptr;
- return false;
+
+ {
+ std::unique_lock<std::shared_timed_mutex> configWriteLock(mConfigLock);
+ UniqueScopedLockAssertion lockAssertion(mConfigLock);
+
+ for (auto& config : filteredConfigs) {
+ mConfigsByPropId[config.prop] = config;
+ }
+ VehiclePropConfigs vehiclePropConfigs;
+ vehiclePropConfigs.payloads = std::move(filteredConfigs);
+ auto result = LargeParcelableBase::parcelableToStableLargeParcelable(vehiclePropConfigs);
+ if (!result.ok()) {
+ ALOGE("failed to convert configs to shared memory file, error: %s, code: %d",
+ result.error().message().c_str(), static_cast<int>(result.error().code()));
+ mConfigFile = nullptr;
+ return false;
+ }
+
+ if (result.value() != nullptr) {
+ mConfigFile = std::move(result.value());
+ }
}
- if (result.value() != nullptr) {
- mConfigFile = std::move(result.value());
- }
+ mConfigInit = true;
return true;
}
-const ScopedFileDescriptor* DefaultVehicleHal::getConfigFile() const {
- std::scoped_lock lockGuard(mConfigInitLock);
+void DefaultVehicleHal::getConfigsByPropId(
+ std::function<void(const std::unordered_map<int32_t, VehiclePropConfig>&)> callback) const {
if (!mConfigInit) {
CHECK(getAllPropConfigsFromHardwareLocked())
<< "Failed to get property configs from hardware";
- mConfigInit = true;
}
- return mConfigFile.get();
-}
-const std::unordered_map<int32_t, VehiclePropConfig>& DefaultVehicleHal::getConfigsByPropId()
- const {
- std::scoped_lock lockGuard(mConfigInitLock);
- if (!mConfigInit) {
- CHECK(getAllPropConfigsFromHardwareLocked())
- << "Failed to get property configs from hardware";
- mConfigInit = true;
- }
- return mConfigsByPropId;
+ std::shared_lock<std::shared_timed_mutex> configReadLock(mConfigLock);
+ SharedScopedLockAssertion lockAssertion(mConfigLock);
+
+ callback(mConfigsByPropId);
}
ScopedAStatus DefaultVehicleHal::getAllPropConfigs(VehiclePropConfigs* output) {
- const ScopedFileDescriptor* configFile = getConfigFile();
- const auto& configsByPropId = getConfigsByPropId();
- if (configFile != nullptr) {
+ if (!mConfigInit) {
+ CHECK(getAllPropConfigsFromHardwareLocked())
+ << "Failed to get property configs from hardware";
+ }
+
+ std::shared_lock<std::shared_timed_mutex> configReadLock(mConfigLock);
+ SharedScopedLockAssertion lockAssertion(mConfigLock);
+
+ if (mConfigFile != nullptr) {
output->payloads.clear();
- output->sharedMemoryFd.set(dup(configFile->get()));
+ output->sharedMemoryFd.set(dup(mConfigFile->get()));
return ScopedAStatus::ok();
}
- output->payloads.reserve(configsByPropId.size());
- for (const auto& [_, config] : configsByPropId) {
+
+ output->payloads.reserve(mConfigsByPropId.size());
+ for (const auto& [_, config] : mConfigsByPropId) {
output->payloads.push_back(config);
}
return ScopedAStatus::ok();
}
-Result<const VehiclePropConfig*> DefaultVehicleHal::getConfig(int32_t propId) const {
- const auto& configsByPropId = getConfigsByPropId();
- auto it = configsByPropId.find(propId);
- if (it == configsByPropId.end()) {
- return Error() << "no config for property, ID: " << propId;
- }
- return &(it->second);
+Result<VehiclePropConfig> DefaultVehicleHal::getConfig(int32_t propId) const {
+ Result<VehiclePropConfig> result;
+ getConfigsByPropId([this, &result, propId](const auto& configsByPropId) {
+ SharedScopedLockAssertion lockAssertion(mConfigLock);
+
+ auto it = configsByPropId.find(propId);
+ if (it == configsByPropId.end()) {
+ result = Error() << "no config for property, ID: " << propId;
+ return;
+ }
+ // Copy the VehiclePropConfig
+ result = it->second;
+ });
+ return result;
}
Result<void> DefaultVehicleHal::checkProperty(const VehiclePropValue& propValue) {
@@ -425,15 +451,15 @@
if (!result.ok()) {
return result.error();
}
- const VehiclePropConfig* config = result.value();
- const VehicleAreaConfig* areaConfig = getAreaConfig(propValue, *config);
+ const VehiclePropConfig& config = result.value();
+ const VehicleAreaConfig* areaConfig = getAreaConfig(propValue, config);
if (!isGlobalProp(propId) && areaConfig == nullptr) {
// Ignore areaId for global property. For non global property, check whether areaId is
// allowed. areaId must appear in areaConfig.
return Error() << "invalid area ID: " << propValue.areaId << " for prop ID: " << propId
<< ", not listed in config";
}
- if (auto result = checkPropValue(propValue, config); !result.ok()) {
+ if (auto result = checkPropValue(propValue, &config); !result.ok()) {
return Error() << "invalid property value: " << propValue.toString()
<< ", error: " << getErrorMsg(result);
}
@@ -659,17 +685,27 @@
ScopedAStatus DefaultVehicleHal::getPropConfigs(const std::vector<int32_t>& props,
VehiclePropConfigs* output) {
std::vector<VehiclePropConfig> configs;
- const auto& configsByPropId = getConfigsByPropId();
- for (int32_t prop : props) {
- auto it = configsByPropId.find(prop);
- if (it != configsByPropId.end()) {
- configs.push_back(it->second);
- } else {
- return ScopedAStatus::fromServiceSpecificErrorWithMessage(
- toInt(StatusCode::INVALID_ARG),
- StringPrintf("no config for property, ID: %" PRId32, prop).c_str());
+ ScopedAStatus status = ScopedAStatus::ok();
+ getConfigsByPropId([this, &configs, &status, &props](const auto& configsByPropId) {
+ SharedScopedLockAssertion lockAssertion(mConfigLock);
+
+ for (int32_t prop : props) {
+ auto it = configsByPropId.find(prop);
+ if (it != configsByPropId.end()) {
+ configs.push_back(it->second);
+ } else {
+ status = ScopedAStatus::fromServiceSpecificErrorWithMessage(
+ toInt(StatusCode::INVALID_ARG),
+ StringPrintf("no config for property, ID: %" PRId32, prop).c_str());
+ return;
+ }
}
+ });
+
+ if (!status.isOk()) {
+ return status;
}
+
return vectorToStableLargeParcelable(std::move(configs), output);
}
@@ -691,8 +727,8 @@
}
VhalResult<void> DefaultVehicleHal::checkSubscribeOptions(
- const std::vector<SubscribeOptions>& options) {
- const auto& configsByPropId = getConfigsByPropId();
+ const std::vector<SubscribeOptions>& options,
+ const std::unordered_map<int32_t, VehiclePropConfig>& configsByPropId) {
for (const auto& option : options) {
int32_t propId = option.propId;
auto it = configsByPropId.find(propId);
@@ -757,23 +793,15 @@
}
}
}
+
return {};
}
-ScopedAStatus DefaultVehicleHal::subscribe(const CallbackType& callback,
- const std::vector<SubscribeOptions>& options,
- [[maybe_unused]] int32_t maxSharedMemoryFileCount) {
- // TODO(b/205189110): Use shared memory file count.
- if (callback == nullptr) {
- return ScopedAStatus::fromExceptionCode(EX_NULL_POINTER);
- }
- if (auto result = checkSubscribeOptions(options); !result.ok()) {
- ALOGE("subscribe: invalid subscribe options: %s", getErrorMsg(result).c_str());
- return toScopedAStatus(result);
- }
- std::vector<SubscribeOptions> onChangeSubscriptions;
- std::vector<SubscribeOptions> continuousSubscriptions;
- const auto& configsByPropId = getConfigsByPropId();
+void DefaultVehicleHal::parseSubscribeOptions(
+ const std::vector<SubscribeOptions>& options,
+ const std::unordered_map<int32_t, VehiclePropConfig>& configsByPropId,
+ std::vector<SubscribeOptions>& onChangeSubscriptions,
+ std::vector<SubscribeOptions>& continuousSubscriptions) {
for (const auto& option : options) {
int32_t propId = option.propId;
// We have already validate config exists.
@@ -831,6 +859,34 @@
onChangeSubscriptions.push_back(std::move(optionCopy));
}
}
+}
+
+ScopedAStatus DefaultVehicleHal::subscribe(const CallbackType& callback,
+ const std::vector<SubscribeOptions>& options,
+ [[maybe_unused]] int32_t maxSharedMemoryFileCount) {
+ // TODO(b/205189110): Use shared memory file count.
+ if (callback == nullptr) {
+ return ScopedAStatus::fromExceptionCode(EX_NULL_POINTER);
+ }
+ std::vector<SubscribeOptions> onChangeSubscriptions;
+ std::vector<SubscribeOptions> continuousSubscriptions;
+ ScopedAStatus returnStatus = ScopedAStatus::ok();
+ getConfigsByPropId([this, &returnStatus, &options, &onChangeSubscriptions,
+ &continuousSubscriptions](const auto& configsByPropId) {
+ SharedScopedLockAssertion lockAssertion(mConfigLock);
+
+ if (auto result = checkSubscribeOptions(options, configsByPropId); !result.ok()) {
+ ALOGE("subscribe: invalid subscribe options: %s", getErrorMsg(result).c_str());
+ returnStatus = toScopedAStatus(result);
+ return;
+ }
+ parseSubscribeOptions(options, configsByPropId, onChangeSubscriptions,
+ continuousSubscriptions);
+ });
+
+ if (!returnStatus.isOk()) {
+ return returnStatus;
+ }
{
// Lock to make sure onBinderDied would not be called concurrently.
@@ -891,13 +947,13 @@
return StatusError(StatusCode::INVALID_ARG) << getErrorMsg(result);
}
- const VehiclePropConfig* config = result.value();
- const VehicleAreaConfig* areaConfig = getAreaConfig(value, *config);
+ const VehiclePropConfig& config = result.value();
+ const VehicleAreaConfig* areaConfig = getAreaConfig(value, config);
if (areaConfig == nullptr && !isGlobalProp(propId)) {
return StatusError(StatusCode::INVALID_ARG) << "no config for area ID: " << value.areaId;
}
- if (!hasRequiredAccess(config->access, accessToTest) &&
+ if (!hasRequiredAccess(config.access, accessToTest) &&
(areaConfig == nullptr || !hasRequiredAccess(areaConfig->access, accessToTest))) {
return StatusError(StatusCode::ACCESS_DENIED)
<< StringPrintf("Property %" PRId32 " does not have the following access: %" PRId32,
@@ -966,7 +1022,6 @@
}
DumpResult result = mVehicleHardware->dump(options);
if (result.refreshPropertyConfigs) {
- std::scoped_lock lockGuard(mConfigInitLock);
getAllPropConfigsFromHardwareLocked();
}
dprintf(fd, "%s", (result.buffer + "\n").c_str());
@@ -974,11 +1029,16 @@
return STATUS_OK;
}
dprintf(fd, "Vehicle HAL State: \n");
- const auto& configsByPropId = getConfigsByPropId();
+ std::unordered_map<int32_t, VehiclePropConfig> configsByPropIdCopy;
+ getConfigsByPropId([this, &configsByPropIdCopy](const auto& configsByPropId) {
+ SharedScopedLockAssertion lockAssertion(mConfigLock);
+
+ configsByPropIdCopy = configsByPropId;
+ });
{
std::scoped_lock<std::mutex> lockGuard(mLock);
dprintf(fd, "Interface version: %" PRId32 "\n", getVhalInterfaceVersion());
- dprintf(fd, "Containing %zu property configs\n", configsByPropId.size());
+ dprintf(fd, "Containing %zu property configs\n", configsByPropIdCopy.size());
dprintf(fd, "Currently have %zu getValues clients\n", mGetValuesClients.size());
dprintf(fd, "Currently have %zu setValues clients\n", mSetValuesClients.size());
dprintf(fd, "Currently have %zu subscribe clients\n", countSubscribeClients());
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
index 0863adf..e5c09b0 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
@@ -1677,6 +1677,12 @@
* For configuration information, VehiclePropConfig.configArray must have bit flag combining
* values in VehicleApPowerStateConfigFlag.
*
+ * configArray[0] : Bit flag combining values in VehicleApPowerStateConfigFlag,
+ * 0x0 if not used,
+ * 0x1 for enabling suspend to ram,
+ * 0x2 for supporting powering on AP from off state after timeout.
+ * 0x4 for enabling suspend to disk,
+ *
* int32Values[0] : VehicleApPowerStateReq enum value
* int32Values[1] : additional parameter relevant for each state,
* 0 if not used.
diff --git a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
index 608a328..fb3c8cd 100644
--- a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
+++ b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
@@ -95,7 +95,7 @@
std::lock_guard<std::mutex> lockGuard(mLock);
for (auto& value : values) {
int32_t propId = value->getPropId();
- mEvents[propId].push_back(std::move(value->clone()));
+ mEvents[propId].push_back(value->clone());
}
}
mEventCond.notify_one();
@@ -122,7 +122,7 @@
return events;
}
for (const auto& eventPtr : mEvents[propId]) {
- events.push_back(std::move(eventPtr->clone()));
+ events.push_back(eventPtr->clone());
}
return events;
}
diff --git a/biometrics/common/aidl/Android.bp b/biometrics/common/aidl/Android.bp
index 246bcf2..4afecb4 100644
--- a/biometrics/common/aidl/Android.bp
+++ b/biometrics/common/aidl/Android.bp
@@ -22,6 +22,9 @@
cpp: {
enabled: false,
},
+ rust: {
+ enabled: true,
+ },
},
versions_with_info: [
{
diff --git a/biometrics/fingerprint/aidl/Android.bp b/biometrics/fingerprint/aidl/Android.bp
index a395c01..d0c1b8b 100644
--- a/biometrics/fingerprint/aidl/Android.bp
+++ b/biometrics/fingerprint/aidl/Android.bp
@@ -25,6 +25,9 @@
cpp: {
enabled: false,
},
+ rust: {
+ enabled: true,
+ },
},
versions_with_info: [
{
diff --git a/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp b/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp
index dcb5fac..fcf1649 100644
--- a/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp
+++ b/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp
@@ -988,7 +988,16 @@
ASSERT_EQ(status, std::future_status::ready);
}
+// @VsrTest = 5.3.14-001
+// @VsrTest = 5.3.14-002
+// @VsrTest = 5.3.14-004
TEST_P(BluetoothAidlTest, Vsr_Bluetooth5Requirements) {
+ int api_level = get_vsr_api_level();
+ if (api_level < __ANDROID_API_U__) {
+ GTEST_SKIP() << "API level is lower than 34";
+ return;
+ }
+
std::vector<uint8_t> version_event;
send_and_wait_for_cmd_complete(ReadLocalVersionInformationBuilder::Create(),
version_event);
@@ -998,10 +1007,12 @@
ASSERT_TRUE(version_view.IsValid());
ASSERT_EQ(::bluetooth::hci::ErrorCode::SUCCESS, version_view.GetStatus());
auto version = version_view.GetLocalVersionInformation();
+
if (version.hci_version_ < ::bluetooth::hci::HciVersion::V_5_0) {
- // This test does not apply to controllers below 5.0
+ GTEST_SKIP() << "Bluetooth version is lower than 5.0";
return;
- };
+ }
+
// When HCI version is 5.0, LMP version must also be at least 5.0
ASSERT_GE(static_cast<int>(version.lmp_version_),
static_cast<int>(version.hci_version_));
@@ -1014,6 +1025,16 @@
std::make_shared<std::vector<uint8_t>>(le_features_event)))));
ASSERT_TRUE(le_features_view.IsValid());
ASSERT_EQ(::bluetooth::hci::ErrorCode::SUCCESS, le_features_view.GetStatus());
+
+ // CHIPSETs that set ro.board.api_level to 34 and report 5.0 or higher for
+ // the Bluetooth version through the IBluetoothHci HAL:
+ //
+ // [VSR-5.3.14-001] Must return TRUE for
+ // - LE 2M PHY
+ // - LE Coded PHY
+ // - LE Advertising Extension
+ // - LE Periodic Advertising
+ // - LE Link Layer Privacy
auto le_features = le_features_view.GetLeFeatures();
ASSERT_TRUE(le_features & static_cast<uint64_t>(LLFeaturesBits::LL_PRIVACY));
ASSERT_TRUE(le_features & static_cast<uint64_t>(LLFeaturesBits::LE_2M_PHY));
@@ -1021,6 +1042,8 @@
static_cast<uint64_t>(LLFeaturesBits::LE_CODED_PHY));
ASSERT_TRUE(le_features &
static_cast<uint64_t>(LLFeaturesBits::LE_EXTENDED_ADVERTISING));
+ ASSERT_TRUE(le_features &
+ static_cast<uint64_t>(LLFeaturesBits::LE_PERIODIC_ADVERTISING));
std::vector<uint8_t> num_adv_set_event;
send_and_wait_for_cmd_complete(
@@ -1034,6 +1057,10 @@
ASSERT_EQ(::bluetooth::hci::ErrorCode::SUCCESS, num_adv_set_view.GetStatus());
auto num_adv_set = num_adv_set_view.GetNumberSupportedAdvertisingSets();
+ // CHIPSETs that set ro.board.api_level to 34 and report 5.0 or higher for
+ // the Bluetooth version through the IBluetoothHci HAL:
+ //
+ // [VSR-5.3.14-002] MUST support at least 10 advertising sets.
if (isTv() && get_vsr_api_level() == __ANDROID_API_U__) {
ASSERT_GE(num_adv_set, kMinLeAdvSetForBt5ForTv);
} else {
@@ -1050,6 +1077,11 @@
ASSERT_EQ(::bluetooth::hci::ErrorCode::SUCCESS,
num_resolving_list_view.GetStatus());
auto num_resolving_list = num_resolving_list_view.GetResolvingListSize();
+
+ // CHIPSETs that set ro.board.api_level to 34 and report 5.0 or higher for
+ // the Bluetooth version through the IBluetoothHci HAL:
+ //
+ // [VSR-5.3.14-004] MUST support a resolving list size of at least 8 entries.
ASSERT_GE(num_resolving_list, kMinLeResolvingListForBt5);
}
diff --git a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp
index 6783c0f..61c29d3 100644
--- a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp
+++ b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp
@@ -121,6 +121,40 @@
return (sessionType == session_type_);
}
+std::string getSettingOutputString(
+ IBluetoothAudioProvider::LeAudioAseConfigurationSetting& setting) {
+ std::stringstream ss;
+ std::string name = "";
+ if (!setting.sinkAseConfiguration.has_value() &&
+ !setting.sourceAseConfiguration.has_value())
+ return "";
+ std::vector<
+ std::optional<LeAudioAseConfigurationSetting::AseDirectionConfiguration>>*
+ directionAseConfiguration;
+ if (setting.sinkAseConfiguration.has_value() &&
+ !setting.sinkAseConfiguration.value().empty())
+ directionAseConfiguration = &setting.sinkAseConfiguration.value();
+ else
+ directionAseConfiguration = &setting.sourceAseConfiguration.value();
+ for (auto& aseConfiguration : *directionAseConfiguration) {
+ if (aseConfiguration.has_value() &&
+ aseConfiguration.value().aseConfiguration.metadata.has_value()) {
+ for (auto& meta :
+ aseConfiguration.value().aseConfiguration.metadata.value()) {
+ if (meta.has_value() &&
+ meta.value().getTag() == MetadataLtv::vendorSpecific) {
+ auto k = meta.value().get<MetadataLtv::vendorSpecific>().opaqueValue;
+ name = std::string(k.begin(), k.end());
+ break;
+ }
+ }
+ }
+ }
+
+ ss << "setting name: " << name << ", setting: " << setting.toString();
+ return ss.str();
+}
+
ndk::ScopedAStatus LeAudioOffloadAudioProvider::startSession(
const std::shared_ptr<IBluetoothAudioPort>& host_if,
const AudioConfiguration& audio_config,
@@ -218,15 +252,24 @@
return false;
}
+int getCountFromBitmask(int bitmask) {
+ return std::bitset<32>(bitmask).count();
+}
+
bool LeAudioOffloadAudioProvider::isMatchedAudioChannel(
- CodecSpecificConfigurationLtv::AudioChannelAllocation&
- /*cfg_channel*/,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation& cfg_channel,
CodecSpecificCapabilitiesLtv::SupportedAudioChannelCounts&
- /*capability_channel*/) {
- // Simply ignore.
- // Later can use additional capabilities to match requirement.
- bool isMatched = true;
- return isMatched;
+ capability_channel) {
+ int count = getCountFromBitmask(cfg_channel.bitmask);
+ if (count == 1 &&
+ !(capability_channel.bitmask &
+ CodecSpecificCapabilitiesLtv::SupportedAudioChannelCounts::ONE))
+ return false;
+ if (count == 2 &&
+ !(capability_channel.bitmask &
+ CodecSpecificCapabilitiesLtv::SupportedAudioChannelCounts::TWO))
+ return false;
+ return true;
}
bool LeAudioOffloadAudioProvider::isMatchedCodecFramesPerSDU(
@@ -322,12 +365,6 @@
return true;
}
-bool isMonoConfig(
- CodecSpecificConfigurationLtv::AudioChannelAllocation allocation) {
- auto channel_count = std::bitset<32>(allocation.bitmask);
- return (channel_count.count() <= 1);
-}
-
bool LeAudioOffloadAudioProvider::filterMatchedAseConfiguration(
LeAudioAseConfiguration& setting_cfg,
const LeAudioAseConfiguration& requirement_cfg) {
@@ -337,9 +374,6 @@
if (!setting_cfg.codecId.has_value()) return false;
if (!isMatchedValidCodec(setting_cfg.codecId.value(),
requirement_cfg.codecId.value())) {
- LOG(WARNING) << __func__ << ": Doesn't match valid codec, cfg = "
- << setting_cfg.codecId.value().toString()
- << ", req = " << requirement_cfg.codecId.value().toString();
return false;
}
}
@@ -347,9 +381,6 @@
if (requirement_cfg.targetLatency !=
LeAudioAseConfiguration::TargetLatency::UNDEFINED &&
setting_cfg.targetLatency != requirement_cfg.targetLatency) {
- LOG(WARNING) << __func__ << ": Doesn't match target latency, cfg = "
- << int(setting_cfg.targetLatency)
- << ", req = " << int(requirement_cfg.targetLatency);
return false;
}
// Ignore PHY requirement
@@ -365,8 +396,6 @@
auto cfg = cfg_tag_map.find(requirement_cfg.getTag());
// Config not found for this requirement, cannot match
if (cfg == cfg_tag_map.end()) {
- LOG(WARNING) << __func__ << ": Config not found for the requirement "
- << requirement_cfg.toString();
return false;
}
@@ -377,10 +406,6 @@
continue;
if (cfg->second != requirement_cfg) {
- LOG(WARNING) << __func__
- << ": Config doesn't match the requirement, cfg = "
- << cfg->second.toString()
- << ", req = " << requirement_cfg.toString();
return false;
}
}
@@ -437,10 +462,6 @@
return 0;
}
-int getCountFromBitmask(int bitmask) {
- return std::bitset<32>(bitmask).count();
-}
-
std::optional<AseDirectionConfiguration> findValidMonoConfig(
std::vector<AseDirectionConfiguration>& valid_direction_configurations,
int bitmask) {
@@ -505,14 +526,13 @@
return {};
}
+// Check and filter each index to see if it's a match.
void LeAudioOffloadAudioProvider::filterRequirementAseDirectionConfiguration(
std::optional<std::vector<std::optional<AseDirectionConfiguration>>>&
direction_configurations,
const std::vector<std::optional<AseDirectionRequirement>>& requirements,
std::optional<std::vector<std::optional<AseDirectionConfiguration>>>&
- valid_direction_configurations,
- bool is_exact) {
- // For every requirement, find the matched ase configuration
+ valid_direction_configurations) {
if (!direction_configurations.has_value()) return;
if (!valid_direction_configurations.has_value()) {
@@ -520,38 +540,55 @@
std::vector<std::optional<AseDirectionConfiguration>>();
}
- for (auto& requirement : requirements) {
- if (!requirement.has_value()) continue;
- auto req_allocation_bitmask = getLeAudioAseConfigurationAllocationBitmask(
- requirement.value().aseConfiguration);
- auto req_channel_count = getCountFromBitmask(req_allocation_bitmask);
-
- auto temp = std::vector<AseDirectionConfiguration>();
-
- for (auto direction_configuration : direction_configurations.value()) {
- if (!direction_configuration.has_value()) continue;
- if (!filterMatchedAseConfiguration(
- direction_configuration.value().aseConfiguration,
- requirement.value().aseConfiguration))
- continue;
- // Valid if match any requirement.
- temp.push_back(direction_configuration.value());
- }
-
- // Get the best matching config based on channel allocation
- auto total_cfg_channel_count = 0;
- auto req_valid_configs = getValidConfigurationsFromAllocation(
- req_allocation_bitmask, temp, is_exact);
- // Count and check required channel counts
- for (auto& cfg : req_valid_configs) {
- total_cfg_channel_count += getCountFromBitmask(
- getLeAudioAseConfigurationAllocationBitmask(cfg.aseConfiguration));
- valid_direction_configurations.value().push_back(cfg);
- }
- if (total_cfg_channel_count != req_channel_count) {
+ // Exact matching process
+ // Need to respect the number of device
+ for (int i = 0; i < requirements.size(); ++i) {
+ auto requirement = requirements[i];
+ auto direction_configuration = direction_configurations.value()[i];
+ if (!direction_configuration.has_value()) {
valid_direction_configurations = std::nullopt;
return;
}
+ auto cfg = direction_configuration.value();
+ if (!filterMatchedAseConfiguration(cfg.aseConfiguration,
+ requirement.value().aseConfiguration)) {
+ valid_direction_configurations = std::nullopt;
+ return; // No way to match
+ }
+ // For exact match, we require this direction to have the same allocation.
+ // If stereo, need stereo.
+ // If mono, need mono (modified to the correct required allocation)
+ auto req_allocation_bitmask = getLeAudioAseConfigurationAllocationBitmask(
+ requirement.value().aseConfiguration);
+ int req_channel_count = getCountFromBitmask(req_allocation_bitmask);
+ int cfg_bitmask =
+ getLeAudioAseConfigurationAllocationBitmask(cfg.aseConfiguration);
+ int cfg_channel_count = getCountFromBitmask(cfg_bitmask);
+ if (req_channel_count <= 1) {
+ // MONO case, is a match if also mono, modify to the same allocation
+ if (cfg_channel_count > 1) {
+ valid_direction_configurations = std::nullopt;
+ return; // Not a match
+ }
+ // Modify the bitmask to be the same as the requirement
+ for (auto& codec_cfg : cfg.aseConfiguration.codecConfiguration) {
+ if (codec_cfg.getTag() ==
+ CodecSpecificConfigurationLtv::Tag::audioChannelAllocation) {
+ codec_cfg
+ .get<CodecSpecificConfigurationLtv::Tag::audioChannelAllocation>()
+ .bitmask = req_allocation_bitmask;
+ break;
+ }
+ }
+ } else {
+ // STEREO case, is a match if same allocation
+ if (req_allocation_bitmask != cfg_bitmask) {
+ valid_direction_configurations = std::nullopt;
+ return; // Not a match
+ }
+ }
+ // Push to list if valid
+ valid_direction_configurations.value().push_back(cfg);
}
}
@@ -564,7 +601,6 @@
const IBluetoothAudioProvider::LeAudioDeviceCapabilities& capabilities,
uint8_t direction) {
// Create a new LeAudioAseConfigurationSetting and return
- // For other direction will contain all settings
LeAudioAseConfigurationSetting filtered_setting{
.audioContext = setting.audioContext,
.sinkAseConfiguration = setting.sinkAseConfiguration,
@@ -612,27 +648,39 @@
std::optional<LeAudioAseConfigurationSetting>
LeAudioOffloadAudioProvider::getRequirementMatchedAseConfigurationSettings(
IBluetoothAudioProvider::LeAudioAseConfigurationSetting& setting,
- const IBluetoothAudioProvider::LeAudioConfigurationRequirement& requirement,
- bool is_exact) {
- // Try to match context in metadata.
- if ((setting.audioContext.bitmask & requirement.audioContext.bitmask) !=
- requirement.audioContext.bitmask)
- return std::nullopt;
-
- // Further filter setting's context
- setting.audioContext.bitmask &= requirement.audioContext.bitmask;
-
+ const IBluetoothAudioProvider::LeAudioConfigurationRequirement&
+ requirement) {
// Create a new LeAudioAseConfigurationSetting to return
+ // Make context the same as the requirement
LeAudioAseConfigurationSetting filtered_setting{
- .audioContext = setting.audioContext,
+ .audioContext = requirement.audioContext,
.packing = setting.packing,
.flags = setting.flags,
};
+ // The number of AseDirectionRequirement in the requirement
+ // is the number of device.
+
+ // The exact matching process is as follow:
+ // 1. Setting direction has the same number of cfg (ignore when null require)
+ // 2. For each index, it's a 1-1 filter / mapping.
+
+ if (requirement.sinkAseRequirement.has_value() &&
+ requirement.sinkAseRequirement.value().size() !=
+ setting.sinkAseConfiguration.value().size()) {
+ return std::nullopt;
+ }
+
+ if (requirement.sourceAseRequirement.has_value() &&
+ requirement.sourceAseRequirement.value().size() !=
+ setting.sourceAseConfiguration.value().size()) {
+ return std::nullopt;
+ }
+
if (requirement.sinkAseRequirement.has_value()) {
filterRequirementAseDirectionConfiguration(
setting.sinkAseConfiguration, requirement.sinkAseRequirement.value(),
- filtered_setting.sinkAseConfiguration, is_exact);
+ filtered_setting.sinkAseConfiguration);
if (!filtered_setting.sinkAseConfiguration.has_value()) {
return std::nullopt;
}
@@ -642,7 +690,7 @@
filterRequirementAseDirectionConfiguration(
setting.sourceAseConfiguration,
requirement.sourceAseRequirement.value(),
- filtered_setting.sourceAseConfiguration, is_exact);
+ filtered_setting.sourceAseConfiguration);
if (!filtered_setting.sourceAseConfiguration.has_value()) {
return std::nullopt;
}
@@ -651,47 +699,44 @@
return filtered_setting;
}
-std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>
+std::optional<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>
LeAudioOffloadAudioProvider::matchWithRequirement(
std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>&
matched_ase_configuration_settings,
- const std::vector<IBluetoothAudioProvider::LeAudioConfigurationRequirement>&
- in_requirements,
- bool is_exact) {
- // Each requirement will match with a valid setting
- std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting> result;
- for (auto& requirement : in_requirements) {
- LOG(INFO) << __func__ << ": Trying to match for the requirement "
- << requirement.toString();
- bool is_matched = false;
-
- for (auto& setting : matched_ase_configuration_settings) {
- auto filtered_ase_configuration_setting =
- getRequirementMatchedAseConfigurationSettings(setting, requirement,
- is_exact);
- if (filtered_ase_configuration_setting.has_value()) {
- result.push_back(filtered_ase_configuration_setting.value());
- LOG(INFO) << __func__ << ": Result = "
- << filtered_ase_configuration_setting.value().toString();
- // Found a matched setting, ignore other settings
- is_matched = true;
- break;
- }
+ const IBluetoothAudioProvider::LeAudioConfigurationRequirement& requirement,
+ bool isMatchContext) {
+ LOG(INFO) << __func__ << ": Trying to match for the requirement "
+ << requirement.toString() << ", match context = " << isMatchContext;
+ for (auto& setting : matched_ase_configuration_settings) {
+ // Try to match context in metadata.
+ if (isMatchContext) {
+ if ((setting.audioContext.bitmask & requirement.audioContext.bitmask) !=
+ requirement.audioContext.bitmask)
+ continue;
+ LOG(DEBUG) << __func__ << ": Setting with matched context: "
+ << getSettingOutputString(setting);
}
- if (!is_matched) {
- // If cannot satisfy this requirement, return an empty result
- LOG(WARNING) << __func__ << ": Cannot match the requirement "
- << requirement.toString();
- result.clear();
- break;
+
+ auto filtered_ase_configuration_setting =
+ getRequirementMatchedAseConfigurationSettings(setting, requirement);
+ if (filtered_ase_configuration_setting.has_value()) {
+ LOG(INFO) << __func__ << ": Result found: "
+ << getSettingOutputString(
+ filtered_ase_configuration_setting.value());
+ // Found a matched setting, ignore other settings
+ return filtered_ase_configuration_setting;
}
}
- return result;
+ // If cannot satisfy this requirement, return nullopt
+ LOG(WARNING) << __func__ << ": Cannot match the requirement "
+ << requirement.toString()
+ << ", match context = " << isMatchContext;
+ return std::nullopt;
}
// For each requirement, a valid ASE configuration will satify:
-// - matched with any sink capability (if presented)
-// - OR matched with any source capability (if presented)
+// - matched with the sink capability (if presented)
+// - AND matched with the source capability (if presented)
// - and the setting need to pass the requirement
ndk::ScopedAStatus LeAudioOffloadAudioProvider::getLeAudioAseConfiguration(
const std::optional<std::vector<
@@ -714,19 +759,15 @@
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
- // Split out preferred and non-preferred settings based on context
- // An example: preferred = MEDIA, available: MEDIA | CONVERSATION
- // -> preferred list will have settings with MEDIA context
- // -> non-preferred list will have settings with any context
- // We want to match requirement with preferred context settings first
+ // Matched ASE configuration with ignored audio context
+ std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>
+ sink_matched_ase_configuration_settings;
std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>
matched_ase_configuration_settings;
- // Matched ASE configuration with non-preferred audio context
- std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>
- non_prefer_matched_ase_configuration_settings;
- if (in_remoteSinkAudioCapabilities.has_value())
- // Matching each setting with any remote capabilities
+ // A setting must match both source and sink.
+ // First filter all setting matched with sink capability
+ if (in_remoteSinkAudioCapabilities.has_value()) {
for (auto& setting : ase_configuration_settings)
for (auto& capability : in_remoteSinkAudioCapabilities.value()) {
if (!capability.has_value()) continue;
@@ -734,81 +775,64 @@
getCapabilitiesMatchedAseConfigurationSettings(
setting, capability.value(), kLeAudioDirectionSink);
if (filtered_ase_configuration_setting.has_value()) {
- // Push to non-prefer first for the broadest matching possible
- non_prefer_matched_ase_configuration_settings.push_back(
+ sink_matched_ase_configuration_settings.push_back(
filtered_ase_configuration_setting.value());
- // Try to filter out prefer context to another vector.
- if (filterCapabilitiesMatchedContext(
- filtered_ase_configuration_setting.value().audioContext,
- capability.value())) {
- matched_ase_configuration_settings.push_back(
- filtered_ase_configuration_setting.value());
- }
}
}
+ } else {
+ sink_matched_ase_configuration_settings = ase_configuration_settings;
+ }
// Combine filter every source capability
- if (in_remoteSourceAudioCapabilities.has_value())
- // Matching each setting with any remote capabilities
- for (auto& setting : ase_configuration_settings)
+ if (in_remoteSourceAudioCapabilities.has_value()) {
+ for (auto& setting : sink_matched_ase_configuration_settings)
for (auto& capability : in_remoteSourceAudioCapabilities.value()) {
if (!capability.has_value()) continue;
auto filtered_ase_configuration_setting =
getCapabilitiesMatchedAseConfigurationSettings(
setting, capability.value(), kLeAudioDirectionSource);
if (filtered_ase_configuration_setting.has_value()) {
- // Put into the same list
- // possibly duplicated, filtered by requirement later
- // Push to non-prefer first for the broadest matching possible
- non_prefer_matched_ase_configuration_settings.push_back(
+ matched_ase_configuration_settings.push_back(
filtered_ase_configuration_setting.value());
- // Try to filter out prefer context to another vector.
- if (filterCapabilitiesMatchedContext(
- filtered_ase_configuration_setting.value().audioContext,
- capability.value())) {
- matched_ase_configuration_settings.push_back(
- filtered_ase_configuration_setting.value());
- }
}
}
+ } else {
+ matched_ase_configuration_settings =
+ sink_matched_ase_configuration_settings;
+ }
- // Matching priority list:
- // Preferred context - exact match with allocation
- // Any context - exact match with allocation
- // Preferred context - loose match with allocation
- // Any context - loose match with allocation
+ std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting> result;
+ for (auto& requirement : in_requirements) {
+ // For each requirement, try to match with a setting.
+ // If we cannot match, return an empty result.
- // A loose match will attempt to return 2 settings with the
- // combined allocation bitmask equal the required allocation.
- // For example, we can return 2 link (left link and right link) when
- // the requirement required 1 (left + right) link.
- auto result = matchWithRequirement(matched_ase_configuration_settings,
- in_requirements, true);
- if (result.empty()) {
- LOG(WARNING)
- << __func__
- << ": Cannot match with preferred context settings - exact match";
- result = matchWithRequirement(non_prefer_matched_ase_configuration_settings,
- in_requirements, true);
+ // Matching priority list:
+ // Preferred context - exact match with allocation
+ // Any context - exact match with allocation
+
+ auto matched_setting_with_context = matchWithRequirement(
+ matched_ase_configuration_settings, requirement, true);
+ if (matched_setting_with_context.has_value()) {
+ result.push_back(matched_setting_with_context.value());
+ } else {
+ auto matched_setting = matchWithRequirement(
+ matched_ase_configuration_settings, requirement, false);
+ if (matched_setting.has_value()) {
+ result.push_back(matched_setting.value());
+ } else {
+ // Cannot find a match for this requirement
+ // Immediately return
+ LOG(ERROR)
+ << __func__
+ << ": Cannot find any match for this requirement, exitting...";
+ result.clear();
+ *_aidl_return = result;
+ return ndk::ScopedAStatus::ok();
+ }
+ }
}
- if (result.empty()) {
- LOG(WARNING)
- << __func__
- << ": Cannot match with non-preferred context settings - exact match";
- result = matchWithRequirement(matched_ase_configuration_settings,
- in_requirements, false);
- }
- if (result.empty()) {
- LOG(WARNING) << __func__
- << ": Cannot match with preferred context settings - "
- "non-exact match";
- result = matchWithRequirement(non_prefer_matched_ase_configuration_settings,
- in_requirements, false);
- }
- if (result.empty())
- LOG(ERROR) << __func__
- << ": Cannot match with non preferred context settings - "
- "non-exact match";
+
+ LOG(INFO) << __func__ << ": Found matches for all requirements!";
*_aidl_return = result;
return ndk::ScopedAStatus::ok();
};
diff --git a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h
index 043d923..798f183 100644
--- a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h
+++ b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h
@@ -139,8 +139,7 @@
direction_configurations,
const std::vector<std::optional<AseDirectionRequirement>>& requirements,
std::optional<std::vector<std::optional<AseDirectionConfiguration>>>&
- valid_direction_configurations,
- bool is_exact);
+ valid_direction_configurations);
std::optional<LeAudioAseConfigurationSetting>
getCapabilitiesMatchedAseConfigurationSettings(
IBluetoothAudioProvider::LeAudioAseConfigurationSetting& setting,
@@ -150,8 +149,7 @@
getRequirementMatchedAseConfigurationSettings(
IBluetoothAudioProvider::LeAudioAseConfigurationSetting& setting,
const IBluetoothAudioProvider::LeAudioConfigurationRequirement&
- requirement,
- bool is_exact);
+ requirement);
bool isMatchedQosRequirement(LeAudioAseQosConfiguration setting_qos,
AseQosDirectionRequirement requirement_qos);
std::optional<LeAudioBroadcastConfigurationSetting>
@@ -169,14 +167,13 @@
AudioContext requirement_context,
IBluetoothAudioProvider::BroadcastQuality quality,
LeAudioBroadcastSubgroupConfiguration configuration);
- std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>
+ std::optional<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>
matchWithRequirement(
std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>&
matched_ase_configuration_settings,
- const std::vector<
- IBluetoothAudioProvider::LeAudioConfigurationRequirement>&
- in_requirements,
- bool is_exact);
+ const IBluetoothAudioProvider::LeAudioConfigurationRequirement&
+ requirements,
+ bool isMatchContext);
};
class LeAudioOffloadOutputAudioProvider : public LeAudioOffloadAudioProvider {
diff --git a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
index 110a628..4481238 100644
--- a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
+++ b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
@@ -142,6 +142,7 @@
VERSION_AIDL_V2,
VERSION_AIDL_V3,
VERSION_AIDL_V4,
+ VERSION_AIDL_V5,
};
// Some valid configs for HFP PCM configuration (software sessions)
@@ -683,6 +684,8 @@
return BluetoothAudioHalVersion::VERSION_AIDL_V3;
case 4:
return BluetoothAudioHalVersion::VERSION_AIDL_V4;
+ case 5:
+ return BluetoothAudioHalVersion::VERSION_AIDL_V5;
default:
return BluetoothAudioHalVersion::VERSION_UNAVAILABLE;
}
diff --git a/bluetooth/audio/utils/Android.bp b/bluetooth/audio/utils/Android.bp
index 1661362..d931c4d 100644
--- a/bluetooth/audio/utils/Android.bp
+++ b/bluetooth/audio/utils/Android.bp
@@ -81,9 +81,9 @@
],
required: [
"aidl_audio_set_configurations_bfbs",
- "aidl_audio_set_configurations_json",
+ "aidl_default_audio_set_configurations_json",
"aidl_audio_set_scenarios_bfbs",
- "aidl_audio_set_scenarios_json",
+ "aidl_default_audio_set_scenarios_json",
"hfp_codec_capabilities_xml",
],
}
@@ -215,9 +215,9 @@
}
prebuilt_etc {
- name: "aidl_audio_set_scenarios_json",
+ name: "aidl_default_audio_set_scenarios_json",
src: "le_audio_configuration_set/audio_set_scenarios.json",
- filename: "aidl_audio_set_scenarios.json",
+ filename: "aidl_default_audio_set_scenarios.json",
sub_dir: "aidl/le_audio",
vendor: true,
}
@@ -239,9 +239,9 @@
}
prebuilt_etc {
- name: "aidl_audio_set_configurations_json",
+ name: "aidl_default_audio_set_configurations_json",
src: "le_audio_configuration_set/audio_set_configurations.json",
- filename: "aidl_audio_set_configurations.json",
+ filename: "aidl_default_audio_set_configurations.json",
sub_dir: "aidl/le_audio",
vendor: true,
}
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
index d0f2a26..c62784e 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
@@ -139,21 +139,50 @@
<< toString(session_type_);
return;
}
+ } else if(session_type_ == SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH) {
+ if (audio_config.getTag() != AudioConfiguration::hfpConfig) {
+ LOG(ERROR) << __func__ << " invalid audio config type for SessionType ="
+ << toString(session_type_);
+ return;
+ }
+ } else if (session_type_ == SessionType::HFP_SOFTWARE_DECODING_DATAPATH ||
+ session_type_ == SessionType::HFP_SOFTWARE_ENCODING_DATAPATH) {
+ if (audio_config.getTag() != AudioConfiguration::pcmConfig) {
+ LOG(ERROR) << __func__ << " invalid audio config type for SessionType ="
+ << toString(session_type_);
+ return;
+ }
} else {
LOG(ERROR) << __func__ << " invalid SessionType ="
<< toString(session_type_);
return;
}
} else {
- if (session_type_ !=
- SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
- session_type_ !=
+ if (session_type_ ==
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
+ session_type_ ==
SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
- return;
- }
- if (audio_config.getTag() != AudioConfiguration::leAudioConfig) {
- LOG(ERROR) << __func__ << " invalid audio config type for SessionType ="
- << toString(session_type_);
+ if (audio_config.getTag() != AudioConfiguration::leAudioConfig) {
+ LOG(ERROR) << __func__ << " invalid audio config type for SessionType ="
+ << toString(session_type_);
+ return;
+ }
+ } else if(session_type_ == SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH) {
+ if (audio_config.getTag() != AudioConfiguration::hfpConfig) {
+ LOG(ERROR) << __func__ << " invalid audio config type for SessionType ="
+ << toString(session_type_);
+ return;
+ }
+ } else if (session_type_ == SessionType::HFP_SOFTWARE_DECODING_DATAPATH ||
+ session_type_ == SessionType::HFP_SOFTWARE_ENCODING_DATAPATH) {
+ if (audio_config.getTag() != AudioConfiguration::pcmConfig) {
+ LOG(ERROR) << __func__ << " invalid audio config type for SessionType ="
+ << toString(session_type_);
+ return;
+ }
+ } else {
+ LOG(ERROR) << __func__
+ << " invalid SessionType =" << toString(session_type_);
return;
}
}
@@ -589,7 +618,9 @@
if (session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
session_type_ == SessionType::A2DP_SOFTWARE_DECODING_DATAPATH ||
- session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
+ session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
+ session_type_ == SessionType::HFP_SOFTWARE_ENCODING_DATAPATH ||
+ session_type_ == SessionType::HFP_SOFTWARE_DECODING_DATAPATH) {
return false;
}
@@ -614,7 +645,9 @@
if (session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
session_type_ == SessionType::A2DP_SOFTWARE_DECODING_DATAPATH ||
- session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
+ session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
+ session_type_ == SessionType::HFP_SOFTWARE_ENCODING_DATAPATH ||
+ session_type_ == SessionType::HFP_SOFTWARE_DECODING_DATAPATH) {
return false;
}
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.cpp b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.cpp
index 780154a..37812fa 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.cpp
@@ -240,18 +240,31 @@
CodecSpecificConfigurationLtv::AudioChannelAllocation::RIGHT_SURROUND},
};
+// Set configuration and scenario files with fallback default
static const std::vector<
std::pair<const char* /*schema*/, const char* /*content*/>>
- kLeAudioSetConfigs = {{"/vendor/etc/aidl/le_audio/"
- "aidl_audio_set_configurations.bfbs",
- "/vendor/etc/aidl/le_audio/"
- "aidl_audio_set_configurations.json"}};
+ kLeAudioSetConfigs = {
+ {"/vendor/etc/aidl/le_audio/"
+ "aidl_audio_set_configurations.bfbs",
+ "/vendor/etc/aidl/le_audio/"
+ "aidl_audio_set_configurations.json"},
+
+ {"/vendor/etc/aidl/le_audio/"
+ "aidl_audio_set_configurations.bfbs",
+ "/vendor/etc/aidl/le_audio/"
+ "aidl_default_audio_set_configurations.json"},
+};
static const std::vector<
std::pair<const char* /*schema*/, const char* /*content*/>>
kLeAudioSetScenarios = {{"/vendor/etc/aidl/le_audio/"
"aidl_audio_set_scenarios.bfbs",
"/vendor/etc/aidl/le_audio/"
- "aidl_audio_set_scenarios.json"}};
+ "aidl_audio_set_scenarios.json"},
+
+ {"/vendor/etc/aidl/le_audio/"
+ "aidl_audio_set_scenarios.bfbs",
+ "/vendor/etc/aidl/le_audio/"
+ "aidl_default_audio_set_scenarios.json"}};
/* Implementation */
@@ -374,7 +387,7 @@
}
void AudioSetConfigurationProviderJson::populateAseConfiguration(
- LeAudioAseConfiguration& ase,
+ const std::string& name, LeAudioAseConfiguration& ase,
const le_audio::AudioSetSubConfiguration* flat_subconfig,
const le_audio::QosConfiguration* qos_cfg) {
// Target latency
@@ -411,20 +424,36 @@
}
// Codec configuration data
populateConfigurationData(ase, flat_subconfig->codec_configuration());
+ // Populate the config name for easier debug
+ auto meta = std::vector<std::optional<MetadataLtv>>();
+ MetadataLtv::VendorSpecific cfg_name;
+ cfg_name.opaqueValue = std::vector<uint8_t>(name.begin(), name.end());
+ meta.push_back(cfg_name);
+ ase.metadata = meta;
}
void AudioSetConfigurationProviderJson::populateAseQosConfiguration(
LeAudioAseQosConfiguration& qos, const le_audio::QosConfiguration* qos_cfg,
- LeAudioAseConfiguration& ase) {
+ LeAudioAseConfiguration& ase, uint8_t ase_channel_cnt) {
std::optional<CodecSpecificConfigurationLtv::CodecFrameBlocksPerSDU>
frameBlock = std::nullopt;
std::optional<CodecSpecificConfigurationLtv::FrameDuration> frameDuration =
std::nullopt;
- std::optional<CodecSpecificConfigurationLtv::AudioChannelAllocation>
- allocation = std::nullopt;
std::optional<CodecSpecificConfigurationLtv::OctetsPerCodecFrame> octet =
std::nullopt;
+ // Hack to put back allocation
+ CodecSpecificConfigurationLtv::AudioChannelAllocation allocation =
+ CodecSpecificConfigurationLtv::AudioChannelAllocation();
+ if (ase_channel_cnt == 1) {
+ allocation.bitmask |=
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_CENTER;
+
+ } else {
+ allocation.bitmask |=
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_LEFT |
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_RIGHT;
+ }
for (auto& cfg_ltv : ase.codecConfiguration) {
auto tag = cfg_ltv.getTag();
if (tag == CodecSpecificConfigurationLtv::codecFrameBlocksPerSDU) {
@@ -433,11 +462,12 @@
} else if (tag == CodecSpecificConfigurationLtv::frameDuration) {
frameDuration =
cfg_ltv.get<CodecSpecificConfigurationLtv::frameDuration>();
- } else if (tag == CodecSpecificConfigurationLtv::audioChannelAllocation) {
- allocation =
- cfg_ltv.get<CodecSpecificConfigurationLtv::audioChannelAllocation>();
} else if (tag == CodecSpecificConfigurationLtv::octetsPerCodecFrame) {
octet = cfg_ltv.get<CodecSpecificConfigurationLtv::octetsPerCodecFrame>();
+ } else if (tag == CodecSpecificConfigurationLtv::audioChannelAllocation) {
+ // Change to the old hack allocation
+ cfg_ltv.set<CodecSpecificConfigurationLtv::audioChannelAllocation>(
+ allocation);
}
}
@@ -445,9 +475,8 @@
if (frameBlock.has_value()) frameBlockValue = frameBlock.value().value;
// Populate maxSdu
- if (allocation.has_value() && octet.has_value()) {
- auto channel_count = std::bitset<32>(allocation.value().bitmask).count();
- qos.maxSdu = channel_count * octet.value().value * frameBlockValue;
+ if (octet.has_value()) {
+ qos.maxSdu = ase_channel_cnt * octet.value().value * frameBlockValue;
}
// Populate sduIntervalUs
if (frameDuration.has_value()) {
@@ -468,6 +497,7 @@
// Parse into AseDirectionConfiguration
AseDirectionConfiguration
AudioSetConfigurationProviderJson::SetConfigurationFromFlatSubconfig(
+ const std::string& name,
const le_audio::AudioSetSubConfiguration* flat_subconfig,
const le_audio::QosConfiguration* qos_cfg, CodecLocation location) {
AseDirectionConfiguration direction_conf;
@@ -477,10 +507,11 @@
LeAudioDataPathConfiguration path;
// Translate into LeAudioAseConfiguration
- populateAseConfiguration(ase, flat_subconfig, qos_cfg);
+ populateAseConfiguration(name, ase, flat_subconfig, qos_cfg);
// Translate into LeAudioAseQosConfiguration
- populateAseQosConfiguration(qos, qos_cfg, ase);
+ populateAseQosConfiguration(qos, qos_cfg, ase,
+ flat_subconfig->ase_channel_cnt());
// Translate location to data path id
switch (location) {
@@ -510,13 +541,18 @@
// Parse into AseDirectionConfiguration and the ConfigurationFlags
// and put them in the given list.
void AudioSetConfigurationProviderJson::processSubconfig(
+ const std::string& name,
const le_audio::AudioSetSubConfiguration* subconfig,
const le_audio::QosConfiguration* qos_cfg,
std::vector<std::optional<AseDirectionConfiguration>>&
directionAseConfiguration,
CodecLocation location) {
- directionAseConfiguration.push_back(
- SetConfigurationFromFlatSubconfig(subconfig, qos_cfg, location));
+ auto ase_cnt = subconfig->ase_cnt();
+ auto config =
+ SetConfigurationFromFlatSubconfig(name, subconfig, qos_cfg, location);
+ directionAseConfiguration.push_back(config);
+ // Put the same setting again.
+ if (ase_cnt == 2) directionAseConfiguration.push_back(config);
}
void AudioSetConfigurationProviderJson::PopulateAseConfigurationFromFlat(
@@ -587,11 +623,11 @@
/* Load subconfigurations */
for (auto subconfig : *codec_cfg->subconfigurations()) {
if (subconfig->direction() == kLeAudioDirectionSink) {
- processSubconfig(subconfig, qos_sink_cfg, sinkAseConfiguration,
- location);
+ processSubconfig(flat_cfg->name()->str(), subconfig, qos_sink_cfg,
+ sinkAseConfiguration, location);
} else {
- processSubconfig(subconfig, qos_source_cfg, sourceAseConfiguration,
- location);
+ processSubconfig(flat_cfg->name()->str(), subconfig, qos_source_cfg,
+ sourceAseConfiguration, location);
}
}
} else {
@@ -742,9 +778,6 @@
LOG(DEBUG) << "Updating " << flat_scenarios->size() << " scenarios.";
for (auto const& scenario : *flat_scenarios) {
- LOG(DEBUG) << "Scenario " << scenario->name()->c_str()
- << " configs: " << scenario->configurations()->size();
-
if (!scenario->configurations()) continue;
std::string scenario_name = scenario->name()->c_str();
AudioContext context;
@@ -758,6 +791,9 @@
context = AudioContext(game_context);
else if (scenario_name == "VoiceAssistants")
context = AudioContext(voice_assistants_context);
+ LOG(DEBUG) << "Scenario " << scenario->name()->c_str()
+ << " configs: " << scenario->configurations()->size()
+ << " context: " << context.toString();
for (auto it = scenario->configurations()->begin();
it != scenario->configurations()->end(); ++it) {
@@ -790,14 +826,22 @@
std::vector<std::pair<const char* /*schema*/, const char* /*content*/>>
scenario_files,
CodecLocation location) {
+ bool is_loaded_config = false;
for (auto [schema, content] : config_files) {
- if (!LoadConfigurationsFromFiles(schema, content, location)) return false;
+ if (LoadConfigurationsFromFiles(schema, content, location)) {
+ is_loaded_config = true;
+ break;
+ }
}
+ bool is_loaded_scenario = false;
for (auto [schema, content] : scenario_files) {
- if (!LoadScenariosFromFiles(schema, content)) return false;
+ if (LoadScenariosFromFiles(schema, content)) {
+ is_loaded_scenario = true;
+ break;
+ }
}
- return true;
+ return is_loaded_config && is_loaded_scenario;
}
} // namespace audio
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.h b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.h
index 6639009..fac6152 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.h
+++ b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.h
@@ -73,19 +73,22 @@
flat_codec_specific_params);
static void populateAseConfiguration(
- LeAudioAseConfiguration& ase,
+ const std::string& name, LeAudioAseConfiguration& ase,
const le_audio::AudioSetSubConfiguration* flat_subconfig,
const le_audio::QosConfiguration* qos_cfg);
static void populateAseQosConfiguration(
LeAudioAseQosConfiguration& qos,
- const le_audio::QosConfiguration* qos_cfg, LeAudioAseConfiguration& ase);
+ const le_audio::QosConfiguration* qos_cfg, LeAudioAseConfiguration& ase,
+ uint8_t ase_channel_cnt);
static AseDirectionConfiguration SetConfigurationFromFlatSubconfig(
+ const std::string& name,
const le_audio::AudioSetSubConfiguration* flat_subconfig,
const le_audio::QosConfiguration* qos_cfg, CodecLocation location);
static void processSubconfig(
+ const std::string& name,
const le_audio::AudioSetSubConfiguration* subconfig,
const le_audio::QosConfiguration* qos_cfg,
std::vector<std::optional<AseDirectionConfiguration>>&
diff --git a/bluetooth/audio/utils/le_audio_configuration_set/audio_set_configurations.fbs b/bluetooth/audio/utils/le_audio_configuration_set/audio_set_configurations.fbs
index bde467d..ed9ad49 100644
--- a/bluetooth/audio/utils/le_audio_configuration_set/audio_set_configurations.fbs
+++ b/bluetooth/audio/utils/le_audio_configuration_set/audio_set_configurations.fbs
@@ -56,10 +56,9 @@
HIGH_RELIABILITY = 0x03,
}
table AudioSetSubConfiguration {
- device_cnt: ubyte;
+ ase_channel_cnt: ubyte;
ase_cnt: ubyte;
direction: AudioSetConfigurationDirection = SINK;
- configuration_strategy: AudioSetConfigurationStrategy;
codec_id : CodecId (required);
codec_configuration: [CodecSpecificConfiguration] (required);
}
diff --git a/bluetooth/audio/utils/le_audio_configuration_set/audio_set_configurations.json b/bluetooth/audio/utils/le_audio_configuration_set/audio_set_configurations.json
index 404a48a..fbfa3f9 100644
--- a/bluetooth/audio/utils/le_audio_configuration_set/audio_set_configurations.json
+++ b/bluetooth/audio/utils/le_audio_configuration_set/audio_set_configurations.json
@@ -13,16 +13,11 @@
" Codec Configuration parameter types:",
" SUPPORTED_SAMPLING_FREQUENCY = 1",
" SUPPORTED_FRAME_DURATION = 2",
- " SUPPORTED_AUDIO_CHANNEL_ALLOCATION = 3",
" SUPPORTED_OCTETS_PER_CODEC_FRAME = 4",
" SUPPORTED_CODEC_FRAME_BLOCKS_PER_SDU = 5",
" Example values which can be used as 'codec_configuration.compound_value'",
" Codec Coding formats:",
" LC3 = 6",
- " ASE Configuration strategies:",
- " MONO_ONE_CIS_PER_DEVICE = 0",
- " STEREO_TWO_CISES_PER_DEVICE = 1",
- " STEREO_ONE_CIS_PER_DEVICE = 2",
" Sampling Frequencies: ",
" 8000Hz = 1",
" 11025Hz = 2",
@@ -43,1177 +38,1135 @@
],
"configurations": [
{
- "name": "DualDev_OneChanStereoSnk_16_1_Low_Latency",
- "codec_config_name": "DualDev_OneChanStereoSnk_16_1",
+ "name": "Two-OneChan-SnkAse-Lc3_16_1_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "DualDev_OneChanStereoSnk_16_1_Balanced_Reliability",
- "codec_config_name": "DualDev_OneChanStereoSnk_16_1",
+ "name": "Two-OneChan-SnkAse-Lc3_16_1_Balanced_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "DualDev_OneChanStereoSnk_16_1_1",
- "codec_config_name": "DualDev_OneChanStereoSnk_16_1",
+ "name": "Two-OneChan-SnkAse-Lc3_16_1_1",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1",
"qos_config_name": [
"QoS_Config_16_1_1"
]
},
{
- "name": "DualDev_OneChanStereoSnk_16_1_2",
- "codec_config_name": "DualDev_OneChanStereoSnk_16_1",
+ "name": "Two-OneChan-SnkAse-Lc3_16_1_2",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1",
"qos_config_name": [
"QoS_Config_16_1_2"
]
},
{
- "name": "DualDev_OneChanStereoSnk_16_2_Low_Latency",
- "codec_config_name": "DualDev_OneChanStereoSnk_16_2",
+ "name": "Two-OneChan-SnkAse-Lc3_16_2_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "DualDev_OneChanStereoSnk_16_2_Balanced_Reliability",
- "codec_config_name": "DualDev_OneChanStereoSnk_16_2",
+ "name": "Two-OneChan-SnkAse-Lc3_16_2_Balanced_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "DualDev_OneChanStereoSnk_16_2_1",
- "codec_config_name": "DualDev_OneChanStereoSnk_16_2",
+ "name": "Two-OneChan-SnkAse-Lc3_16_2_1",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_16_2_1"
]
},
{
- "name": "DualDev_OneChanStereoSnk_16_2_2",
- "codec_config_name": "DualDev_OneChanStereoSnk_16_2",
+ "name": "Two-OneChan-SnkAse-Lc3_16_2_2",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_16_2_2"
]
},
{
- "name": "SingleDev_OneChanStereoSnk_16_1_Low_Latency",
- "codec_config_name": "SingleDev_OneChanStereoSnk_16_1",
+ "name": "Two-OneChan-SnkAse-Lc3_16_1_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "SingleDev_OneChanStereoSnk_16_1_Balanced_Reliability",
- "codec_config_name": "SingleDev_OneChanStereoSnk_16_1",
+ "name": "Two-OneChan-SnkAse-Lc3_16_1_Balanced_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "SingleDev_OneChanStereoSnk_16_1_1",
- "codec_config_name": "SingleDev_OneChanStereoSnk_16_1",
+ "name": "Two-OneChan-SnkAse-Lc3_16_1_1",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1",
"qos_config_name": [
"QoS_Config_16_1_1"
]
},
{
- "name": "SingleDev_OneChanStereoSnk_16_1_2",
- "codec_config_name": "SingleDev_OneChanStereoSnk_16_1",
+ "name": "Two-OneChan-SnkAse-Lc3_16_1_2",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1",
"qos_config_name": [
"QoS_Config_16_1_2"
]
},
{
- "name": "SingleDev_OneChanStereoSnk_16_2_Low_Latency",
- "codec_config_name": "SingleDev_OneChanStereoSnk_16_2",
+ "name": "Two-OneChan-SnkAse-Lc3_16_2_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "SingleDev_OneChanStereoSnk_16_2_Balanced_Reliability",
- "codec_config_name": "SingleDev_OneChanStereoSnk_16_2",
+ "name": "Two-OneChan-SnkAse-Lc3_16_2_Balanced_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "SingleDev_OneChanStereoSnk_16_2_1",
- "codec_config_name": "SingleDev_OneChanStereoSnk_16_2",
+ "name": "Two-OneChan-SnkAse-Lc3_16_2_1",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_16_2_1"
]
},
{
- "name": "SingleDev_OneChanStereoSnk_16_2_2",
- "codec_config_name": "SingleDev_OneChanStereoSnk_16_2",
+ "name": "Two-OneChan-SnkAse-Lc3_16_2_2",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_16_2_2"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_16_1_Low_Latency",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_16_1",
+ "name": "One-TwoChan-SnkAse-Lc3_16_1_Low_Latency",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_1",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_16_1_Balanced_Reliability",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_16_1",
+ "name": "One-TwoChan-SnkAse-Lc3_16_1_Balanced_Reliability",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_1",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_16_1_1",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_16_1",
+ "name": "One-TwoChan-SnkAse-Lc3_16_1_1",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_1",
"qos_config_name": [
"QoS_Config_16_1_1"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_16_1_2",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_16_1",
+ "name": "One-TwoChan-SnkAse-Lc3_16_1_2",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_1",
"qos_config_name": [
"QoS_Config_16_1_2"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_16_2_Low_Latency",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_16_2",
+ "name": "One-TwoChan-SnkAse-Lc3_16_2_Low_Latency",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_16_2_Balanced_Reliability",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_16_2",
+ "name": "One-TwoChan-SnkAse-Lc3_16_2_Balanced_Reliability",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_16_2_1",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_16_2",
+ "name": "One-TwoChan-SnkAse-Lc3_16_2_1",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_16_2_1"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_16_2_2",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_16_2",
+ "name": "One-TwoChan-SnkAse-Lc3_16_2_2",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_16_2_2"
]
},
{
- "name": "SingleDev_OneChanMonoSnk_32_1_Balanced_Reliability",
- "codec_config_name": "SingleDev_OneChanMonoSnk_32_1",
+ "name": "One-OneChan-SnkAse-Lc3_32_1_Balanced_Reliability",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_32_1",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "SingleDev_OneChanMonoSnk_32_1_1",
- "codec_config_name": "SingleDev_OneChanMonoSnk_32_1",
+ "name": "One-OneChan-SnkAse-Lc3_32_1_1",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_32_1",
"qos_config_name": [
"QoS_Config_32_1_1"
]
},
{
- "name": "SingleDev_OneChanMonoSnk_32_2_Balanced_Reliability",
- "codec_config_name": "SingleDev_OneChanMonoSnk_32_2",
+ "name": "One-OneChan-SnkAse-Lc3_32_1_2",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_32_1",
+ "qos_config_name": [
+ "QoS_Config_32_1_2"
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_32_2_Balanced_Reliability",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_32_2",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "SingleDev_OneChanMonoSnk_32_2_1",
- "codec_config_name": "SingleDev_OneChanMonoSnk_32_2",
+ "name": "One-OneChan-SnkAse-Lc3_32_2_1",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_32_2",
"qos_config_name": [
"QoS_Config_32_2_1"
]
},
{
- "name": "SingleDev_OneChanMonoSnk_16_1_Balanced_Reliability",
- "codec_config_name": "SingleDev_OneChanMonoSnk_16_1",
+ "name": "One-OneChan-SnkAse-Lc3_32_2_2",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_32_2",
+ "qos_config_name": [
+ "QoS_Config_32_2_2"
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_16_1_Balanced_Reliability",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_16_1",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "SingleDev_OneChanMonoSnk_16_1_1",
- "codec_config_name": "SingleDev_OneChanMonoSnk_16_1",
+ "name": "One-OneChan-SnkAse-Lc3_16_1_1",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_16_1",
"qos_config_name": [
"QoS_Config_16_1_1"
]
},
{
- "name": "SingleDev_OneChanMonoSnk_16_1_2",
- "codec_config_name": "SingleDev_OneChanMonoSnk_16_1",
+ "name": "One-OneChan-SnkAse-Lc3_16_1_2",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_16_1",
"qos_config_name": [
"QoS_Config_16_1_2"
]
},
{
- "name": "DualDev_OneChanMonoSnk_16_2_Balanced_Reliability",
- "codec_config_name": "DualDev_OneChanMonoSnk_16_2",
+ "name": "Two-OneChan-SnkAse-Lc3_16_2_Balanced_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "SingleDev_OneChanMonoSnk_16_2_Balanced_Reliability",
- "codec_config_name": "SingleDev_OneChanMonoSnk_16_2",
+ "name": "One-OneChan-SnkAse-Lc3_16_2_Balanced_Reliability",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "SingleDev_OneChanMonoSnk_16_2_1",
- "codec_config_name": "SingleDev_OneChanMonoSnk_16_2",
+ "name": "One-OneChan-SnkAse-Lc3_16_2_1",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_16_2_1"
]
},
{
- "name": "SingleDev_OneChanMonoSnk_16_2_2",
- "codec_config_name": "SingleDev_OneChanMonoSnk_16_2",
+ "name": "One-OneChan-SnkAse-Lc3_16_2_2",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_16_2_2"
]
},
{
- "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency",
- "codec_config_name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_1",
+ "name": "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_1_1",
- "codec_config_name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_1",
+ "name": "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_1",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
"qos_config_name": [
"QoS_Config_16_1_1"
]
},
{
- "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_1_2",
- "codec_config_name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_1",
+ "name": "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_2",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
"qos_config_name": [
"QoS_Config_16_1_2"
]
},
{
- "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_Low_Latency",
- "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2",
+ "name": "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_2",
- "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2",
+ "name": "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2_2",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_16_2_2"
]
},
{
- "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_1",
- "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2",
+ "name": "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2_1",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_16_2_1"
]
},
{
- "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_Low_Latency",
- "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1",
+ "name": "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_2",
- "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1",
+ "name": "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1_2",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1",
"qos_config_name": [
"QoS_Config_16_1_2"
]
},
{
- "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_1",
- "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1",
+ "name": "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1_1",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1",
"qos_config_name": [
"QoS_Config_16_1_1"
]
},
{
- "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency",
- "codec_config_name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_2",
+ "name": "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_2_1",
- "codec_config_name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_2",
+ "name": "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_1",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_16_2_1"
]
},
{
- "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_2_2",
- "codec_config_name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_2",
+ "name": "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_2",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_16_2_2"
]
},
{
- "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1_Low_Latency",
- "codec_config_name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1",
+ "name": "One-TwoChan-SnkAse-Lc3_32_2-One-TwoChan-SrcAse-Lc3_32_2_Low_Latency",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_32_2-One-TwoChan-SrcAse-Lc3_32_2",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1_1",
- "codec_config_name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1",
- "qos_config_name": [
- "QoS_Config_16_1_1"
- ]
- },
- {
- "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2_Low_Latency",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2_1",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2",
+ "name": "One-TwoChan-SnkAse-Lc3_32_2-One-TwoChan-SrcAse-Lc3_32_2_1",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_32_2-One-TwoChan-SrcAse-Lc3_32_2",
"qos_config_name": [
"QoS_Config_32_2_1"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_Low_Latency",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2",
+ "name": "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2_Low_Latency",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_2",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2",
+ "name": "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2_2",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_16_2_2"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_1",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2",
+ "name": "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2_1",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_16_2_1"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_Low_Latency",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1",
+ "name": "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1_Low_Latency",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_2",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1",
+ "name": "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1_2",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1",
"qos_config_name": [
"QoS_Config_16_1_2"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_1",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1",
+ "name": "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1_1",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1",
"qos_config_name": [
"QoS_Config_16_1_1"
]
},
{
- "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1_2",
- "codec_config_name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1",
- "qos_config_name": [
- "QoS_Config_16_1_2"
- ]
- },
- {
- "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2_Low_Latency",
- "codec_config_name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2",
+ "name": "One-TwoChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2_1",
- "codec_config_name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2",
- "qos_config_name": [
- "QoS_Config_16_2_1"
- ]
- },
- {
- "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2_2",
- "codec_config_name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2",
- "qos_config_name": [
- "QoS_Config_16_2_2"
- ]
- },
- {
- "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1_1",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1",
+ "name": "One-TwoChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_1",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
"qos_config_name": [
"QoS_Config_16_1_1"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1_2",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1",
+ "name": "One-TwoChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_2",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
"qos_config_name": [
"QoS_Config_16_1_2"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2",
+ "name": "One-TwoChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2_1",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2",
+ "name": "One-TwoChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_1",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_16_2_1"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2_2",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2",
+ "name": "One-TwoChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_2",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_16_2_2"
]
},
{
- "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency",
- "codec_config_name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1",
+ "name": "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1_1",
- "codec_config_name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1",
+ "name": "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_1",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
"qos_config_name": [
"QoS_Config_16_1_1"
]
},
{
- "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1_2",
- "codec_config_name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1",
+ "name": "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_2",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
"qos_config_name": [
"QoS_Config_16_1_2"
]
},
{
- "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency",
- "codec_config_name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2",
+ "name": "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2_1",
- "codec_config_name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2",
+ "name": "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_1",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_16_2_1"
]
},
{
- "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2_2",
- "codec_config_name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2",
+ "name": "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_2",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_16_2_2"
]
},
{
- "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1_Low_Latency",
- "codec_config_name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1",
+ "name": "One-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1_1",
- "codec_config_name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1",
+ "name": "One-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_1",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
"qos_config_name": [
"QoS_Config_16_1_1"
]
},
{
- "name": "DualDev_OneChanMonoSrc_16_2_Balanced_Reliability",
- "codec_config_name": "DualDev_OneChanMonoSrc_16_2",
+ "name": "Two-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
+ "codec_config_name": "Two-OneChan-SrcAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "SingleDev_OneChanStereoSrc_16_2_Balanced_Reliability",
- "codec_config_name": "SingleDev_OneChanStereoSrc_16_2",
+ "name": "Two-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
+ "codec_config_name": "Two-OneChan-SrcAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "SingleDev_OneChanMonoSrc_48_4_Balanced_Reliability",
- "codec_config_name": "SingleDev_OneChanMonoSrc_48_4",
+ "name": "One-OneChan-SrcAse-Lc3_48_4_Balanced_Reliability",
+ "codec_config_name": "One-OneChan-SrcAse-Lc3_48_4",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "SingleDev_OneChanMonoSrc_48_3_Balanced_Reliability",
- "codec_config_name": "SingleDev_OneChanMonoSrc_48_3",
+ "name": "One-OneChan-SrcAse-Lc3_48_3_Balanced_Reliability",
+ "codec_config_name": "One-OneChan-SrcAse-Lc3_48_3",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "SingleDev_OneChanMonoSrc_48_2_Balanced_Reliability",
- "codec_config_name": "SingleDev_OneChanMonoSrc_48_2",
+ "name": "One-OneChan-SrcAse-Lc3_48_2_Balanced_Reliability",
+ "codec_config_name": "One-OneChan-SrcAse-Lc3_48_2",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "SingleDev_OneChanMonoSrc_48_1_Balanced_Reliability",
- "codec_config_name": "SingleDev_OneChanMonoSrc_48_1",
+ "name": "One-OneChan-SrcAse-Lc3_48_1_Balanced_Reliability",
+ "codec_config_name": "One-OneChan-SrcAse-Lc3_48_1",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "SingleDev_OneChanMonoSrc_32_2_Balanced_Reliability",
- "codec_config_name": "SingleDev_OneChanMonoSrc_32_2",
+ "name": "One-OneChan-SrcAse-Lc3_32_2_Balanced_Reliability",
+ "codec_config_name": "One-OneChan-SrcAse-Lc3_32_2",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "SingleDev_OneChanMonoSrc_32_1_Balanced_Reliability",
- "codec_config_name": "SingleDev_OneChanMonoSrc_32_1",
+ "name": "One-OneChan-SrcAse-Lc3_32_1_Balanced_Reliability",
+ "codec_config_name": "One-OneChan-SrcAse-Lc3_32_1",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "SingleDev_OneChanMonoSrc_24_2_Balanced_Reliability",
- "codec_config_name": "SingleDev_OneChanMonoSrc_24_2",
+ "name": "One-OneChan-SrcAse-Lc3_24_2_Balanced_Reliability",
+ "codec_config_name": "One-OneChan-SrcAse-Lc3_24_2",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "SingleDev_OneChanMonoSrc_24_1_Balanced_Reliability",
- "codec_config_name": "SingleDev_OneChanMonoSrc_24_1",
+ "name": "One-OneChan-SrcAse-Lc3_24_1_Balanced_Reliability",
+ "codec_config_name": "One-OneChan-SrcAse-Lc3_24_1",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "SingleDev_OneChanMonoSrc_16_2_Balanced_Reliability",
- "codec_config_name": "SingleDev_OneChanMonoSrc_16_2",
+ "name": "One-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
+ "codec_config_name": "One-OneChan-SrcAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "SingleDev_OneChanMonoSrc_16_1_Balanced_Reliability",
- "codec_config_name": "SingleDev_OneChanMonoSrc_16_1",
+ "name": "One-OneChan-SrcAse-Lc3_16_1_Balanced_Reliability",
+ "codec_config_name": "One-OneChan-SrcAse-Lc3_16_1",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1_2",
- "codec_config_name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1",
+ "name": "One-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_2",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
"qos_config_name": [
"QoS_Config_16_1_2"
]
},
{
- "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2_Low_Latency",
- "codec_config_name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2",
+ "name": "One-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2_1",
- "codec_config_name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2",
+ "name": "One-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_1",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_16_2_1"
]
},
{
- "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2_2",
- "codec_config_name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2",
+ "name": "One-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_2",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_16_2_2"
]
},
{
- "name": "DualDev_OneChanStereoSnk_24_1_Low_Latency",
- "codec_config_name": "DualDev_OneChanStereoSnk_24_1",
+ "name": "Two-OneChan-SnkAse-Lc3_24_1_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_24_1",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_24_1_Low_Latency",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_24_1",
+ "name": "One-TwoChan-SnkAse-Lc3_24_1_Low_Latency",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_24_1",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "SingleDev_OneChanStereoSnk_24_1_Low_Latency",
- "codec_config_name": "SingleDev_OneChanStereoSnk_24_2",
+ "name": "Two-OneChan-SnkAse-Lc3_24_2_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_24_2",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "DualDev_OneChanStereoSnk_24_2_Low_Latency",
- "codec_config_name": "DualDev_OneChanStereoSnk_24_2",
+ "name": "Two-OneChan-SnkAse-Lc3_24_2_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_24_2",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "DualDev_OneChanStereoSnk_24_2_Balanced_Reliability",
- "codec_config_name": "DualDev_OneChanStereoSnk_24_2",
+ "name": "Two-OneChan-SnkAse-Lc3_24_2_Balanced_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_24_2",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "DualDev_OneChanStereoSnk_24_2_2",
- "codec_config_name": "DualDev_OneChanStereoSnk_24_2",
+ "name": "Two-OneChan-SnkAse-Lc3_24_2_2",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_24_2",
"qos_config_name": [
"QoS_Config_24_2_2"
]
},
{
- "name": "SingleDev_OneChanStereoSnk_24_2_Low_Latency",
- "codec_config_name": "SingleDev_OneChanStereoSnk_24_2",
+ "name": "Two-OneChan-SnkAse-Lc3_24_2_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_24_2",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "SingleDev_OneChanStereoSnk_24_2_Balanced_Reliability",
- "codec_config_name": "SingleDev_OneChanStereoSnk_24_2",
+ "name": "Two-OneChan-SnkAse-Lc3_24_2_Balanced_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_24_2",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "SingleDev_OneChanStereoSnk_24_2_2",
- "codec_config_name": "SingleDev_OneChanStereoSnk_24_2",
+ "name": "Two-OneChan-SnkAse-Lc3_24_2_2",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_24_2",
"qos_config_name": [
"QoS_Config_24_2_2"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_24_2_Low_Latency",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_24_2",
+ "name": "One-TwoChan-SnkAse-Lc3_24_2_Low_Latency",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_24_2",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_24_2_Balanced_Reliability",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_24_2",
+ "name": "One-TwoChan-SnkAse-Lc3_24_2_Balanced_Reliability",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_24_2",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_24_2_2",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_24_2",
+ "name": "One-TwoChan-SnkAse-Lc3_24_2_2",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_24_2",
"qos_config_name": [
"QoS_Config_24_2_2"
]
},
{
- "name": "SingleDev_OneChanMonoSnk_24_2_Balanced_Reliability",
- "codec_config_name": "SingleDev_OneChanMonoSnk_24_2",
+ "name": "One-OneChan-SnkAse-Lc3_24_2_Balanced_Reliability",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_24_2",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "SingleDev_OneChanMonoSnk_24_2_2",
- "codec_config_name": "SingleDev_OneChanMonoSnk_24_2",
+ "name": "One-OneChan-SnkAse-Lc3_24_2_2",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_24_2",
"qos_config_name": [
"QoS_Config_24_2_2"
]
},
{
- "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2_Low_Latency",
- "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2",
+ "name": "Two-OneChan-SnkAse-Lc3_32_2-Two-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_32_2-Two-OneChan-SrcAse-Lc3_32_2",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2_1",
- "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2",
+ "name": "Two-OneChan-SnkAse-Lc3_32_2-Two-OneChan-SrcAse-Lc3_32_2_1",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_32_2-Two-OneChan-SrcAse-Lc3_32_2",
"qos_config_name": [
"QoS_Config_32_2_1"
]
},
{
- "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency",
- "codec_config_name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_32_2",
+ "name": "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_32_2_1",
- "codec_config_name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_32_2",
+ "name": "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_1",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2",
"qos_config_name": [
"QoS_Config_32_2_1"
]
},
{
- "name": "DualDev_OneChanStereoSnk_32_2_Low_Latency",
- "codec_config_name": "DualDev_OneChanStereoSnk_32_2",
+ "name": "Two-OneChan-SnkAse-Lc3_32_2_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_32_2",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "DualDev_OneChanStereoSnk_32_1_Low_Latency",
- "codec_config_name": "DualDev_OneChanStereoSnk_32_1",
+ "name": "Two-OneChan-SnkAse-Lc3_32_1_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_32_1",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_32_1_Low_Latency",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_32_1",
+ "name": "One-TwoChan-SnkAse-Lc3_32_1_Low_Latency",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_32_1",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "SingleDev_OneChanStereoSnk_32_2_Low_Latency",
- "codec_config_name": "SingleDev_OneChanStereoSnk_32_2",
+ "name": "Two-OneChan-SnkAse-Lc3_32_2_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_32_2",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "SingleDev_OneChanStereoSnk_32_1_Low_Latency",
- "codec_config_name": "SingleDev_OneChanStereoSnk_32_1",
+ "name": "Two-OneChan-SnkAse-Lc3_32_1_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_32_1",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_32_2_Low_Latency",
- "codec_config_name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_32_2",
+ "name": "One-TwoChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_32_2_1",
- "codec_config_name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_32_2",
+ "name": "One-TwoChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_1",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2",
"qos_config_name": [
"QoS_Config_32_2_1"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2",
+ "name": "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2_1",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2",
+ "name": "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_1",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2",
"qos_config_name": [
"QoS_Config_32_2_1"
]
},
{
- "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency",
- "codec_config_name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_32_2",
+ "name": "One-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_32_2_1",
- "codec_config_name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_32_2",
+ "name": "One-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_1",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2",
"qos_config_name": [
"QoS_Config_32_2_1"
]
},
{
- "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2_Low_Latency",
- "codec_config_name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2",
+ "name": "One-TwoChan-SnkAse-Lc3_32_2_Low_Latency",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_32_2",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2_1",
- "codec_config_name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2",
- "qos_config_name": [
- "QoS_Config_32_2_1"
- ]
- },
- {
- "name": "SingleDev_TwoChanStereoSnk_32_2_Low_Latency",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_32_2",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "DualDev_OneChanStereoSnk_48_4_High_Reliability",
- "codec_config_name": "DualDev_OneChanStereoSnk_48_4",
+ "name": "Two-OneChan-SnkAse-Lc3_48_4_High_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4",
"qos_config_name": [
"QoS_Config_High_Reliability"
]
},
{
- "name": "DualDev_OneChanStereoSnk_48_4_1",
- "codec_config_name": "DualDev_OneChanStereoSnk_48_4",
+ "name": "Two-OneChan-SnkAse-Lc3_48_4_1",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4",
"qos_config_name": [
"QoS_Config_48_4_1"
]
},
{
- "name": "DualDev_OneChanStereoSnk_48_4_2",
- "codec_config_name": "DualDev_OneChanStereoSnk_48_4",
+ "name": "Two-OneChan-SnkAse-Lc3_48_4_2",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4",
"qos_config_name": [
"QoS_Config_48_4_2"
]
},
{
- "name": "DualDev_OneChanStereoSnk_48_3_Low_Latency",
- "codec_config_name": "DualDev_OneChanStereoSnk_48_3",
+ "name": "Two-OneChan-SnkAse-Lc3_48_3_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_3",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "DualDev_OneChanStereoSnk_48_3_High_Reliability",
- "codec_config_name": "DualDev_OneChanStereoSnk_48_3",
+ "name": "Two-OneChan-SnkAse-Lc3_48_3_High_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_3",
"qos_config_name": [
"QoS_Config_High_Reliability"
]
},
{
- "name": "DualDev_OneChanStereoSnk_48_3_2",
- "codec_config_name": "DualDev_OneChanStereoSnk_48_3",
+ "name": "Two-OneChan-SnkAse-Lc3_48_3_2",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_3",
"qos_config_name": [
"QoS_Config_48_3_2"
]
},
{
- "name": "DualDev_OneChanStereoSnk_48_2_Low_Latency",
- "codec_config_name": "DualDev_OneChanStereoSnk_48_2",
+ "name": "Two-OneChan-SnkAse-Lc3_48_2_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_2",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "DualDev_OneChanStereoSnk_48_2_High_Reliability",
- "codec_config_name": "DualDev_OneChanStereoSnk_48_2",
+ "name": "Two-OneChan-SnkAse-Lc3_48_2_High_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_2",
"qos_config_name": [
"QoS_Config_High_Reliability"
]
},
{
- "name": "DualDev_OneChanStereoSnk_48_2_2",
- "codec_config_name": "DualDev_OneChanStereoSnk_48_2",
+ "name": "Two-OneChan-SnkAse-Lc3_48_2_2",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_2",
"qos_config_name": [
"QoS_Config_48_2_2"
]
},
{
- "name": "DualDev_OneChanStereoSnk_48_1_Low_Latency",
- "codec_config_name": "DualDev_OneChanStereoSnk_48_1",
+ "name": "Two-OneChan-SnkAse-Lc3_48_1_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_1",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "DualDev_OneChanStereoSnk_48_1_High_Reliability",
- "codec_config_name": "DualDev_OneChanStereoSnk_48_1",
+ "name": "Two-OneChan-SnkAse-Lc3_48_1_High_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_1",
"qos_config_name": [
"QoS_Config_High_Reliability"
]
},
{
- "name": "DualDev_OneChanStereoSnk_48_1_2",
- "codec_config_name": "DualDev_OneChanStereoSnk_48_1",
+ "name": "Two-OneChan-SnkAse-Lc3_48_1_2",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_1",
"qos_config_name": [
"QoS_Config_48_1_2"
]
},
{
- "name": "SingleDev_OneChanStereoSnk_48_4_High_Reliability",
- "codec_config_name": "SingleDev_OneChanStereoSnk_48_4",
+ "name": "Two-OneChan-SnkAse-Lc3_48_4_High_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4",
"qos_config_name": [
"QoS_Config_High_Reliability"
]
},
{
- "name": "SingleDev_OneChanStereoSnk_48_4_1",
- "codec_config_name": "SingleDev_OneChanStereoSnk_48_4",
+ "name": "Two-OneChan-SnkAse-Lc3_48_4_1",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4",
"qos_config_name": [
"QoS_Config_48_4_1"
]
},
{
- "name": "SingleDev_OneChanStereoSnk_48_4_2",
- "codec_config_name": "SingleDev_OneChanStereoSnk_48_4",
+ "name": "Two-OneChan-SnkAse-Lc3_48_4_2",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4",
"qos_config_name": [
"QoS_Config_48_4_2"
]
},
{
- "name": "SingleDev_OneChanStereoSnk_48_3_Low_Latency",
- "codec_config_name": "SingleDev_OneChanStereoSnk_48_3",
+ "name": "Two-OneChan-SnkAse-Lc3_48_3_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_3",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "SingleDev_OneChanStereoSnk_48_3_High_Reliability",
- "codec_config_name": "SingleDev_OneChanStereoSnk_48_3",
+ "name": "Two-OneChan-SnkAse-Lc3_48_3_High_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_3",
"qos_config_name": [
"QoS_Config_High_Reliability"
]
},
{
- "name": "SingleDev_OneChanStereoSnk_48_3_2",
- "codec_config_name": "SingleDev_OneChanStereoSnk_48_3",
+ "name": "Two-OneChan-SnkAse-Lc3_48_3_2",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_3",
"qos_config_name": [
"QoS_Config_48_3_2"
]
},
{
- "name": "SingleDev_OneChanStereoSnk_48_2_Low_Latency",
- "codec_config_name": "SingleDev_OneChanStereoSnk_48_2",
+ "name": "Two-OneChan-SnkAse-Lc3_48_2_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_2",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "SingleDev_OneChanStereoSnk_48_2_High_Reliability",
- "codec_config_name": "SingleDev_OneChanStereoSnk_48_2",
+ "name": "Two-OneChan-SnkAse-Lc3_48_2_High_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_2",
"qos_config_name": [
"QoS_Config_High_Reliability"
]
},
{
- "name": "SingleDev_OneChanStereoSnk_48_2_2",
- "codec_config_name": "SingleDev_OneChanStereoSnk_48_2",
+ "name": "Two-OneChan-SnkAse-Lc3_48_2_2",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_2",
"qos_config_name": [
"QoS_Config_48_2_2"
]
},
{
- "name": "SingleDev_OneChanStereoSnk_48_1_Low_Latency",
- "codec_config_name": "SingleDev_OneChanStereoSnk_48_1",
+ "name": "Two-OneChan-SnkAse-Lc3_48_1_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_1",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "SingleDev_OneChanStereoSnk_48_1_High_Reliability",
- "codec_config_name": "SingleDev_OneChanStereoSnk_48_1",
+ "name": "Two-OneChan-SnkAse-Lc3_48_1_High_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_1",
"qos_config_name": [
"QoS_Config_High_Reliability"
]
},
{
- "name": "SingleDev_OneChanStereoSnk_48_1_2",
- "codec_config_name": "SingleDev_OneChanStereoSnk_48_1",
+ "name": "Two-OneChan-SnkAse-Lc3_48_1_2",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_1",
"qos_config_name": [
"QoS_Config_48_1_2"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_48_4_High_Reliability",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_48_4",
+ "name": "One-TwoChan-SnkAse-Lc3_48_4_High_Reliability",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_4",
"qos_config_name": [
"QoS_Config_High_Reliability"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_48_4_1",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_48_4",
+ "name": "One-TwoChan-SnkAse-Lc3_48_4_1",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_4",
"qos_config_name": [
"QoS_Config_48_4_1"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_48_4_2",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_48_4",
+ "name": "One-TwoChan-SnkAse-Lc3_48_4_2",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_4",
"qos_config_name": [
"QoS_Config_48_4_2"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_48_3_Low_Latency",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_48_3",
+ "name": "One-TwoChan-SnkAse-Lc3_48_3_Low_Latency",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_3",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_48_3_High_Reliability",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_48_3",
+ "name": "One-TwoChan-SnkAse-Lc3_48_3_High_Reliability",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_3",
"qos_config_name": [
"QoS_Config_High_Reliability"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_48_3_2",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_48_3",
+ "name": "One-TwoChan-SnkAse-Lc3_48_3_2",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_3",
"qos_config_name": [
"QoS_Config_48_3_2"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_48_2_Low_Latency",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_48_2",
+ "name": "One-TwoChan-SnkAse-Lc3_48_2_Low_Latency",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_2",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_48_2_High_Reliability",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_48_2",
+ "name": "One-TwoChan-SnkAse-Lc3_48_2_High_Reliability",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_2",
"qos_config_name": [
"QoS_Config_High_Reliability"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_48_2_2",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_48_2",
+ "name": "One-TwoChan-SnkAse-Lc3_48_2_2",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_2",
"qos_config_name": [
"QoS_Config_48_2_2"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_48_1_Low_Latency",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_48_1",
+ "name": "One-TwoChan-SnkAse-Lc3_48_1_Low_Latency",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_1",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_48_1_High_Reliability",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_48_1",
+ "name": "One-TwoChan-SnkAse-Lc3_48_1_High_Reliability",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_1",
"qos_config_name": [
"QoS_Config_High_Reliability"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_48_1_2",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_48_1",
+ "name": "One-TwoChan-SnkAse-Lc3_48_1_2",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_1",
"qos_config_name": [
"QoS_Config_48_1_2"
]
},
{
- "name": "SingleDev_OneChanMonoSnk_48_4_High_Reliability",
- "codec_config_name": "SingleDev_OneChanMonoSnk_48_4",
+ "name": "One-OneChan-SnkAse-Lc3_48_4_High_Reliability",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_48_4",
"qos_config_name": [
"QoS_Config_High_Reliability"
]
},
{
- "name": "SingleDev_OneChanMonoSnk_48_4_1",
- "codec_config_name": "SingleDev_OneChanMonoSnk_48_4",
+ "name": "One-OneChan-SnkAse-Lc3_48_4_1",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_48_4",
"qos_config_name": [
"QoS_Config_48_4_1"
]
},
{
- "name": "SingleDev_OneChanMonoSnk_48_4_2",
- "codec_config_name": "SingleDev_OneChanMonoSnk_48_4",
+ "name": "One-OneChan-SnkAse-Lc3_48_4_2",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_48_4",
"qos_config_name": [
"QoS_Config_48_4_2"
]
},
{
- "name": "SingleDev_OneChanMonoSnk_48_3_High_Reliability",
- "codec_config_name": "SingleDev_OneChanMonoSnk_48_3",
+ "name": "One-OneChan-SnkAse-Lc3_48_3_High_Reliability",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_48_3",
"qos_config_name": [
"QoS_Config_High_Reliability"
]
},
{
- "name": "SingleDev_OneChanMonoSnk_48_3_2",
- "codec_config_name": "SingleDev_OneChanMonoSnk_48_3",
+ "name": "One-OneChan-SnkAse-Lc3_48_3_2",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_48_3",
"qos_config_name": [
"QoS_Config_48_3_2"
]
},
{
- "name": "SingleDev_OneChanMonoSnk_48_2_High_Reliability",
- "codec_config_name": "SingleDev_OneChanMonoSnk_48_2",
+ "name": "One-OneChan-SnkAse-Lc3_48_2_High_Reliability",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_48_2",
"qos_config_name": [
"QoS_Config_High_Reliability"
]
},
{
- "name": "SingleDev_OneChanMonoSnk_48_2_2",
- "codec_config_name": "SingleDev_OneChanMonoSnk_48_2",
+ "name": "One-OneChan-SnkAse-Lc3_48_2_2",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_48_2",
"qos_config_name": [
"QoS_Config_48_2_2"
]
},
{
- "name": "SingleDev_OneChanMonoSnk_48_1_High_Reliability",
- "codec_config_name": "SingleDev_OneChanMonoSnk_48_1",
+ "name": "One-OneChan-SnkAse-Lc3_48_1_High_Reliability",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_48_1",
"qos_config_name": [
"QoS_Config_High_Reliability"
]
},
{
- "name": "SingleDev_OneChanMonoSnk_48_1_2",
- "codec_config_name": "SingleDev_OneChanMonoSnk_48_1",
+ "name": "One-OneChan-SnkAse-Lc3_48_1_2",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_48_1",
"qos_config_name": [
"QoS_Config_48_1_2"
]
@@ -1289,176 +1242,155 @@
]
},
{
- "name": "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_32_2_Balanced_Reliability",
- "codec_config_name": "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_32_2",
+ "name": "Two-OneChan-SnkAse-Lc3_48_4-Two-OneChan-SrcAse-Lc3_32_2_Balanced_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4-Two-OneChan-SrcAse-Lc3_32_2",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_24_2_Balanced_Reliability",
- "codec_config_name": "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_24_2",
+ "name": "Two-OneChan-SnkAse-Lc3_48_4-Two-OneChan-SrcAse-Lc3_24_2_Balanced_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4-Two-OneChan-SrcAse-Lc3_24_2",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_16_2_Balanced_Reliability",
- "codec_config_name": "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_16_2",
+ "name": "Two-OneChan-SnkAse-Lc3_48_4-Two-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4-Two-OneChan-SrcAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_32_2_Balanced_Reliability",
- "codec_config_name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_32_2",
+ "name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2_Balanced_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_24_2_Balanced_Reliability",
- "codec_config_name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_24_2",
+ "name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2_Balanced_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_16_2_Balanced_Reliability",
- "codec_config_name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_16_2",
+ "name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_32_2_Balanced_Reliability",
- "codec_config_name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_32_2",
+ "name": "One-TwoChan-SnkAse-Lc3_48_4-One-TwoChan-SrcAse-Lc3_32_2_Balanced_Reliability",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_4-One-TwoChan-SrcAse-Lc3_32_2",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_24_2_Balanced_Reliability",
- "codec_config_name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_24_2",
+ "name": "One-TwoChan-SnkAse-Lc3_48_4-One-TwoChan-SrcAse-Lc3_24_2_Balanced_Reliability",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_4-One-TwoChan-SrcAse-Lc3_24_2",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_16_2_Balanced_Reliability",
- "codec_config_name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_16_2",
+ "name": "One-TwoChan-SnkAse-Lc3_48_4-One-TwoChan-SrcAse-Lc3_16_2_Balanced_Reliability",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_4-One-TwoChan-SrcAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_32_2_Balanced_Reliability",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_32_2",
+ "name": "One-TwoChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2_Balanced_Reliability",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_24_2_Balanced_Reliability",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_24_2",
+ "name": "One-TwoChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2_Balanced_Reliability",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_16_2_Balanced_Reliability",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_16_2",
+ "name": "One-TwoChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_48_4_OneChanMonoSrc_32_2_Balanced_Reliability",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_48_4_OneChanMonoSrc_32_2",
+ "name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2_Balanced_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_48_4_1_OneChanMonoSrc_24_2_Balanced_Reliability",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_48_4_OneChanMonoSrc_24_2",
+ "name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2_Balanced_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_48_4_1_OneChanMonoSrc_16_2_Balanced_Reliability",
- "codec_config_name": "SingleDev_TwoChanStereoSnk_48_4_OneChanMonoSrc_16_2",
+ "name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "SingleDev_OneChanStereoSnk_48_4_1_OneChanMonoSrc_32_2_Balanced_Reliability",
- "codec_config_name": "SingleDev_OneChanStereoSnk_48_4_OneChanMonoSrc_32_2",
+ "name": "One-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2_Balanced_Reliability",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "SingleDev_OneChanStereoSnk_48_4_1_OneChanMonoSrc_24_2_Balanced_Reliability",
- "codec_config_name": "SingleDev_OneChanStereoSnk_48_4_OneChanMonoSrc_24_2",
+ "name": "One-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2_Balanced_Reliability",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "SingleDev_OneChanStereoSnk_48_4_1_OneChanMonoSrc_16_2_Balanced_Reliability",
- "codec_config_name": "SingleDev_OneChanStereoSnk_48_4_OneChanMonoSrc_16_2",
+ "name": "One-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "SingleDev_OneChanMonoSnk_48_4_1_OneChanMonoSrc_32_2_Balanced_Reliability",
- "codec_config_name": "SingleDev_OneChanMonoSnk_48_4_OneChanMonoSrc_32_2",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "SingleDev_OneChanMonoSnk_48_4_1_OneChanMonoSrc_24_2_1_Balanced_Reliability",
- "codec_config_name": "SingleDev_OneChanMonoSnk_48_4_OneChanMonoSrc_24_2",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "SingleDev_OneChanMonoSnk_48_4_1_OneChanMonoSrc_16_2_Balanced_Reliability",
- "codec_config_name": "SingleDev_OneChanMonoSnk_48_4_OneChanMonoSrc_16_2",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_1_Low_Latency",
- "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_1",
+ "name": "Two-TwoChan-SnkAse-Lc3_48_1-Two-TwoChan-SrcAse-Lc3_48_1_Low_Latency",
+ "codec_config_name": "Two-TwoChan-SnkAse-Lc3_48_1-Two-TwoChan-SrcAse-Lc3_48_1",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_1_Balanced_Reliability",
- "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_1",
+ "name": "Two-TwoChan-SnkAse-Lc3_48_1-Two-TwoChan-SrcAse-Lc3_48_1_Balanced_Reliability",
+ "codec_config_name": "Two-TwoChan-SnkAse-Lc3_48_1-Two-TwoChan-SrcAse-Lc3_48_1",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
},
{
- "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_2_Low_Latency",
- "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_2",
+ "name": "Two-TwoChan-SnkAse-Lc3_48_2-Two-TwoChan-SrcAse-Lc3_48_2_Low_Latency",
+ "codec_config_name": "Two-TwoChan-SnkAse-Lc3_48_2-Two-TwoChan-SrcAse-Lc3_48_2",
"qos_config_name": [
"QoS_Config_Low_Latency"
]
},
{
- "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_2_Balanced_Reliability",
- "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_2",
+ "name": "Two-TwoChan-SnkAse-Lc3_48_2-Two-TwoChan-SrcAse-Lc3_48_2_Balanced_Reliability",
+ "codec_config_name": "Two-TwoChan-SnkAse-Lc3_48_2-Two-TwoChan-SrcAse-Lc3_48_2",
"qos_config_name": [
"QoS_Config_Balanced_Reliability"
]
@@ -1495,13 +1427,11 @@
],
"codec_configurations": [
{
- "name": "DualDev_OneChanStereoSnk_16_2",
+ "name": "Two-OneChan-SnkAse-Lc3_16_2",
"subconfigurations": [
{
- "device_cnt": 2,
"ase_cnt": 2,
"direction": "SINK",
- "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -1527,18 +1457,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -1557,18 +1475,17 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
}
]
},
{
- "name": "DualDev_OneChanStereoSnk_16_1",
+ "name": "Two-OneChan-SnkAse-Lc3_16_1",
"subconfigurations": [
{
- "device_cnt": 2,
"ase_cnt": 2,
"direction": "SINK",
- "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -1594,18 +1511,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -1624,152 +1529,17 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
}
]
},
{
- "name": "SingleDev_OneChanStereoSnk_16_2",
+ "name": "One-TwoChan-SnkAse-Lc3_16_2",
"subconfigurations": [
{
- "device_cnt": 1,
- "ase_cnt": 2,
- "direction": "SINK",
- "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 40,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- }
- ]
- },
- {
- "name": "SingleDev_OneChanStereoSnk_16_1",
- "subconfigurations": [
- {
- "device_cnt": 1,
- "ase_cnt": 2,
- "direction": "SINK",
- "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 30,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- }
- ]
- },
- {
- "name": "SingleDev_TwoChanStereoSnk_16_2",
- "subconfigurations": [
- {
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SINK",
- "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -1795,18 +1565,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 3,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -1825,18 +1583,17 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 2
}
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_16_1",
+ "name": "One-TwoChan-SnkAse-Lc3_16_1",
"subconfigurations": [
{
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SINK",
- "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -1862,18 +1619,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 3,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -1892,18 +1637,17 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 2
}
]
},
{
- "name": "SingleDev_OneChanStereoSrc_16_2",
+ "name": "Two-OneChan-SrcAse-Lc3_16_2",
"subconfigurations": [
{
- "device_cnt": 1,
"ase_cnt": 2,
"direction": "SOURCE",
- "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -1929,18 +1673,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -1959,15 +1691,15 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
}
]
},
{
- "name": "SingleDev_OneChanMonoSrc_24_2",
+ "name": "One-OneChan-SrcAse-Lc3_24_2",
"subconfigurations": [
{
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SOURCE",
"codec_id": {
@@ -1995,13 +1727,109 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
+ "name": "octets_per_codec_frame",
+ "type": 4,
"compound_value": {
"value": [
- 1,
- 0,
- 0,
+ 60,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_32_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_32_1",
+ "subconfigurations": [
+ {
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
0
]
}
@@ -2025,18 +1853,17 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
}
]
},
{
- "name": "DualDev_OneChanStereoSnk_32_2",
+ "name": "One-OneChan-SnkAse-Lc3_32_2",
"subconfigurations": [
{
- "device_cnt": 2,
- "ase_cnt": 2,
+ "ase_cnt": 1,
"direction": "SINK",
- "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -2062,18 +1889,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -2092,18 +1907,17 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
}
]
},
{
- "name": "DualDev_OneChanStereoSnk_32_1",
+ "name": "One-OneChan-SnkAse-Lc3_32_1",
"subconfigurations": [
{
- "device_cnt": 2,
- "ase_cnt": 2,
+ "ase_cnt": 1,
"direction": "SINK",
- "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -2129,18 +1943,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -2159,18 +1961,537 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
}
]
},
{
- "name": "SingleDev_OneChanMonoSnk_32_2",
+ "name": "One-OneChan-SnkAse-Lc3_16_2",
"subconfigurations": [
{
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SINK",
- "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_16_1",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ },
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ },
+ {
+ "ase_cnt": 2,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1",
+ "subconfigurations": [
+ {
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ },
+ {
+ "ase_cnt": 2,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
+ "subconfigurations": [
+ {
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ },
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_32_2-One-TwoChan-SrcAse-Lc3_32_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -2196,18 +2517,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -2226,344 +2535,10 @@
]
}
}
- ]
- }
- ]
- },
- {
- "name": "SingleDev_OneChanMonoSnk_32_1",
- "subconfigurations": [
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SINK",
- "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 60,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- }
- ]
- },
- {
- "name": "DualDev_OneChanMonoSnk_16_2",
- "subconfigurations": [
- {
- "device_cnt": 2,
- "ase_cnt": 2,
- "direction": "SINK",
- "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 40,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- }
- ]
- },
- {
- "name": "SingleDev_OneChanMonoSnk_16_2",
- "subconfigurations": [
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SINK",
- "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 40,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- }
- ]
- },
- {
- "name": "SingleDev_OneChanMonoSnk_16_1",
- "subconfigurations": [
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SINK",
- "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 30,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- }
- ]
- },
- {
- "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_2",
- "subconfigurations": [
- {
- "device_cnt": 2,
- "ase_cnt": 2,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 40,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
+ ],
+ "ase_channel_cnt": 2
},
{
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SOURCE",
"codec_id": {
@@ -2577,710 +2552,6 @@
"type": 1,
"compound_value": {
"value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 40,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- }
- ]
- },
- {
- "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2",
- "subconfigurations": [
- {
- "device_cnt": 2,
- "ase_cnt": 2,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 40,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- },
- {
- "device_cnt": 2,
- "ase_cnt": 2,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 40,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- }
- ]
- },
- {
- "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1",
- "subconfigurations": [
- {
- "device_cnt": 2,
- "ase_cnt": 2,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 30,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- },
- {
- "device_cnt": 2,
- "ase_cnt": 2,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 30,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- }
- ]
- },
- {
- "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_1",
- "subconfigurations": [
- {
- "device_cnt": 2,
- "ase_cnt": 2,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 30,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- },
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 30,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- }
- ]
- },
- {
- "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2",
- "subconfigurations": [
- {
- "device_cnt": 2,
- "ase_cnt": 4,
- "direction": "SINK",
- "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 40,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- },
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 40,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- }
- ]
- },
- {
- "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1",
- "subconfigurations": [
- {
- "device_cnt": 2,
- "ase_cnt": 4,
- "direction": "SINK",
- "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 30,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- },
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 30,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- }
- ]
- },
- {
- "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2",
- "subconfigurations": [
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SINK",
- "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
6
]
}
@@ -3295,18 +2566,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 3,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -3325,847 +2584,15 @@
]
}
}
- ]
- },
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SOURCE",
- "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 3,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 80,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
+ ],
+ "ase_channel_cnt": 2
}
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2",
+ "name": "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2",
"subconfigurations": [
{
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SINK",
- "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 3,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 40,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- },
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SOURCE",
- "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 3,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 40,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- }
- ]
- },
- {
- "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1",
- "subconfigurations": [
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SINK",
- "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 3,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 30,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- },
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SOURCE",
- "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 3,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 30,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- }
- ]
- },
- {
- "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2",
- "subconfigurations": [
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SINK",
- "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 3,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 40,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- },
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 40,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- }
- ]
- },
- {
- "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1",
- "subconfigurations": [
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SINK",
- "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 3,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 30,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- },
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 30,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- }
- ]
- },
- {
- "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2",
- "subconfigurations": [
- {
- "device_cnt": 1,
- "ase_cnt": 2,
- "direction": "SINK",
- "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 40,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- },
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 40,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- }
- ]
- },
- {
- "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1",
- "subconfigurations": [
- {
- "device_cnt": 1,
- "ase_cnt": 2,
- "direction": "SINK",
- "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 30,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- },
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 30,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- }
- ]
- },
- {
- "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2",
- "subconfigurations": [
- {
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SINK",
"codec_id": {
@@ -4193,18 +2620,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -4223,10 +2638,10 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 2
},
{
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SOURCE",
"codec_id": {
@@ -4254,18 +2669,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -4284,15 +2687,15 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 2
}
]
},
{
- "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1",
+ "name": "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1",
"subconfigurations": [
{
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SINK",
"codec_id": {
@@ -4320,18 +2723,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -4350,10 +2741,10 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 2
},
{
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SOURCE",
"codec_id": {
@@ -4381,18 +2772,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -4411,16 +2790,65 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 2
}
]
},
{
- "name": "DualDev_OneChanMonoSrc_16_2",
+ "name": "One-TwoChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
"subconfigurations": [
{
- "device_cnt": 2,
- "ase_cnt": 2,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ },
+ {
+ "ase_cnt": 1,
"direction": "SOURCE",
"codec_id": {
"coding_format": 6,
@@ -4447,18 +2875,163 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
+ "name": "octets_per_codec_frame",
+ "type": 4,
"compound_value": {
"value": [
- 1,
- 0,
- 0,
+ 40,
0
]
}
},
{
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ },
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -4477,15 +3050,167 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
+ },
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
}
]
},
{
- "name": "SingleDev_OneChanMonoSrc_48_4",
+ "name": "One-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
"subconfigurations": [
{
- "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ },
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-OneChan-SrcAse-Lc3_48_4",
+ "subconfigurations": [
+ {
"ase_cnt": 1,
"direction": "SOURCE",
"codec_id": {
@@ -4513,18 +3238,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -4543,15 +3256,15 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
}
]
},
{
- "name": "SingleDev_OneChanMonoSrc_48_3",
+ "name": "One-OneChan-SrcAse-Lc3_48_3",
"subconfigurations": [
{
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SOURCE",
"codec_id": {
@@ -4579,18 +3292,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -4609,15 +3310,15 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
}
]
},
{
- "name": "SingleDev_OneChanMonoSrc_48_2",
+ "name": "One-OneChan-SrcAse-Lc3_48_2",
"subconfigurations": [
{
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SOURCE",
"codec_id": {
@@ -4645,18 +3346,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -4675,15 +3364,15 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
}
]
},
{
- "name": "SingleDev_OneChanMonoSrc_48_1",
+ "name": "One-OneChan-SrcAse-Lc3_48_1",
"subconfigurations": [
{
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SOURCE",
"codec_id": {
@@ -4711,18 +3400,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -4741,15 +3418,15 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
}
]
},
{
- "name": "SingleDev_OneChanMonoSrc_32_2",
+ "name": "One-OneChan-SrcAse-Lc3_32_2",
"subconfigurations": [
{
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SOURCE",
"codec_id": {
@@ -4777,18 +3454,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -4807,15 +3472,15 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
}
]
},
{
- "name": "SingleDev_OneChanMonoSrc_32_1",
+ "name": "One-OneChan-SrcAse-Lc3_32_1",
"subconfigurations": [
{
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SOURCE",
"codec_id": {
@@ -4843,18 +3508,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -4873,15 +3526,15 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
}
]
},
{
- "name": "SingleDev_OneChanMonoSrc_24_2",
+ "name": "One-OneChan-SrcAse-Lc3_24_1",
"subconfigurations": [
{
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SOURCE",
"codec_id": {
@@ -4904,84 +3557,6 @@
"type": 2,
"compound_value": {
"value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 60,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- }
- ]
- },
- {
- "name": "SingleDev_OneChanMonoSrc_24_1",
- "subconfigurations": [
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 5
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
0
]
}
@@ -5005,15 +3580,15 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
}
]
},
{
- "name": "SingleDev_OneChanMonoSrc_16_2",
+ "name": "One-OneChan-SrcAse-Lc3_16_2",
"subconfigurations": [
{
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SOURCE",
"codec_id": {
@@ -5041,18 +3616,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -5071,15 +3634,15 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
}
]
},
{
- "name": "SingleDev_OneChanMonoSrc_16_1",
+ "name": "One-OneChan-SrcAse-Lc3_16_1",
"subconfigurations": [
{
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SOURCE",
"codec_id": {
@@ -5107,18 +3670,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -5137,18 +3688,17 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
}
]
},
{
- "name": "DualDev_OneChanStereoSnk_48_4",
+ "name": "Two-OneChan-SnkAse-Lc3_48_4",
"subconfigurations": [
{
- "device_cnt": 2,
"ase_cnt": 2,
"direction": "SINK",
- "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -5174,18 +3724,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -5204,18 +3742,17 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
}
]
},
{
- "name": "DualDev_OneChanStereoSnk_48_3",
+ "name": "Two-OneChan-SnkAse-Lc3_48_3",
"subconfigurations": [
{
- "device_cnt": 2,
"ase_cnt": 2,
"direction": "SINK",
- "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -5241,18 +3778,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -5271,18 +3796,17 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
}
]
},
{
- "name": "DualDev_OneChanStereoSnk_48_2",
+ "name": "Two-OneChan-SnkAse-Lc3_48_2",
"subconfigurations": [
{
- "device_cnt": 2,
"ase_cnt": 2,
"direction": "SINK",
- "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -5308,18 +3832,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -5338,18 +3850,17 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
}
]
},
{
- "name": "DualDev_OneChanStereoSnk_48_1",
+ "name": "Two-OneChan-SnkAse-Lc3_48_1",
"subconfigurations": [
{
- "device_cnt": 2,
"ase_cnt": 2,
"direction": "SINK",
- "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -5375,18 +3886,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -5405,18 +3904,17 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
}
]
},
{
- "name": "SingleDev_OneChanStereoSnk_48_4",
+ "name": "One-TwoChan-SnkAse-Lc3_48_4",
"subconfigurations": [
{
- "device_cnt": 1,
- "ase_cnt": 2,
+ "ase_cnt": 1,
"direction": "SINK",
- "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -5442,18 +3940,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -5472,18 +3958,17 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 2
}
]
},
{
- "name": "SingleDev_OneChanStereoSnk_48_3",
+ "name": "One-TwoChan-SnkAse-Lc3_48_3",
"subconfigurations": [
{
- "device_cnt": 1,
- "ase_cnt": 2,
+ "ase_cnt": 1,
"direction": "SINK",
- "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -5509,18 +3994,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -5539,18 +4012,17 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 2
}
]
},
{
- "name": "SingleDev_OneChanStereoSnk_48_2",
+ "name": "One-TwoChan-SnkAse-Lc3_48_2",
"subconfigurations": [
{
- "device_cnt": 1,
- "ase_cnt": 2,
+ "ase_cnt": 1,
"direction": "SINK",
- "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -5576,18 +4048,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -5606,18 +4066,17 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 2
}
]
},
{
- "name": "SingleDev_OneChanStereoSnk_48_1",
+ "name": "One-TwoChan-SnkAse-Lc3_48_1",
"subconfigurations": [
{
- "device_cnt": 1,
- "ase_cnt": 2,
+ "ase_cnt": 1,
"direction": "SINK",
- "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -5643,18 +4102,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -5673,18 +4120,17 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 2
}
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_48_4",
+ "name": "One-OneChan-SnkAse-Lc3_48_4",
"subconfigurations": [
{
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SINK",
- "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -5710,18 +4156,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 3,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -5740,18 +4174,17 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
}
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_48_3",
+ "name": "One-OneChan-SnkAse-Lc3_48_3",
"subconfigurations": [
{
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SINK",
- "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -5777,18 +4210,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 3,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -5807,18 +4228,17 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
}
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_48_2",
+ "name": "One-OneChan-SnkAse-Lc3_48_2",
"subconfigurations": [
{
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SINK",
- "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -5844,18 +4264,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 3,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -5874,18 +4282,17 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
}
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_48_1",
+ "name": "One-OneChan-SnkAse-Lc3_48_1",
"subconfigurations": [
{
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SINK",
- "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -5911,18 +4318,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 3,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -5941,275 +4336,8 @@
]
}
}
- ]
- }
- ]
- },
- {
- "name": "SingleDev_OneChanMonoSnk_48_4",
- "subconfigurations": [
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SINK",
- "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 120,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- }
- ]
- },
- {
- "name": "SingleDev_OneChanMonoSnk_48_3",
- "subconfigurations": [
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SINK",
- "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 90,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- }
- ]
- },
- {
- "name": "SingleDev_OneChanMonoSnk_48_2",
- "subconfigurations": [
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SINK",
- "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 100,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- }
- ]
- },
- {
- "name": "SingleDev_OneChanMonoSnk_48_1",
- "subconfigurations": [
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SINK",
- "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 75,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
+ ],
+ "ase_channel_cnt": 1
}
]
},
@@ -6217,10 +4345,8 @@
"name": "VND_SingleDev_TwoChanStereoSnk_48khz_100octs_1",
"subconfigurations": [
{
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SINK",
- "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -6246,18 +4372,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 3,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -6276,7 +4390,8 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 2
}
]
},
@@ -6284,10 +4399,8 @@
"name": "VND_DualDev_OneChanStereoSnk_48khz_100octs_1",
"subconfigurations": [
{
- "device_cnt": 2,
"ase_cnt": 2,
"direction": "SINK",
- "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -6313,18 +4426,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -6343,7 +4444,8 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
}
]
},
@@ -6351,10 +4453,8 @@
"name": "VND_SingleDev_OneChanStereoSnk_48khz_100octs_1",
"subconfigurations": [
{
- "device_cnt": 1,
"ase_cnt": 2,
"direction": "SINK",
- "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -6380,18 +4480,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -6410,7 +4498,8 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
}
]
},
@@ -6418,10 +4507,8 @@
"name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_1",
"subconfigurations": [
{
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SINK",
- "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -6447,18 +4534,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 3,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -6477,15 +4552,15 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 2
}
]
},
{
- "name": "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_32_2",
+ "name": "Two-OneChan-SnkAse-Lc3_48_4-Two-OneChan-SrcAse-Lc3_32_2",
"subconfigurations": [
{
- "device_cnt": 2,
"ase_cnt": 2,
"direction": "SINK",
"codec_id": {
@@ -6513,18 +4588,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -6543,10 +4606,10 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
},
{
- "device_cnt": 2,
"ase_cnt": 2,
"direction": "SOURCE",
"codec_id": {
@@ -6574,18 +4637,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -6604,15 +4655,15 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
}
]
},
{
- "name": "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_24_2",
+ "name": "Two-OneChan-SnkAse-Lc3_48_4-Two-OneChan-SrcAse-Lc3_24_2",
"subconfigurations": [
{
- "device_cnt": 2,
"ase_cnt": 2,
"direction": "SINK",
"codec_id": {
@@ -6640,18 +4691,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -6670,10 +4709,10 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
},
{
- "device_cnt": 2,
"ase_cnt": 2,
"direction": "SOURCE",
"codec_id": {
@@ -6701,23 +4740,11 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
"value": [
- 80,
+ 60,
0
]
}
@@ -6731,15 +4758,15 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
}
]
},
{
- "name": "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_16_2",
+ "name": "Two-OneChan-SnkAse-Lc3_48_4-Two-OneChan-SrcAse-Lc3_16_2",
"subconfigurations": [
{
- "device_cnt": 2,
"ase_cnt": 2,
"direction": "SINK",
"codec_id": {
@@ -6767,18 +4794,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -6797,10 +4812,10 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
},
{
- "device_cnt": 2,
"ase_cnt": 2,
"direction": "SOURCE",
"codec_id": {
@@ -6828,23 +4843,11 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
"value": [
- 80,
+ 40,
0
]
}
@@ -6858,15 +4861,15 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
}
]
},
{
- "name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_32_2",
+ "name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2",
"subconfigurations": [
{
- "device_cnt": 2,
"ase_cnt": 2,
"direction": "SINK",
"codec_id": {
@@ -6894,18 +4897,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -6924,10 +4915,10 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
},
{
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SOURCE",
"codec_id": {
@@ -6955,18 +4946,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -6985,15 +4964,15 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
}
]
},
{
- "name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_24_2",
+ "name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2",
"subconfigurations": [
{
- "device_cnt": 2,
"ase_cnt": 2,
"direction": "SINK",
"codec_id": {
@@ -7021,18 +5000,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -7051,10 +5018,10 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
},
{
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SOURCE",
"codec_id": {
@@ -7082,23 +5049,11 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
"value": [
- 80,
+ 60,
0
]
}
@@ -7112,15 +5067,15 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
}
]
},
{
- "name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_16_2",
+ "name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2",
"subconfigurations": [
{
- "device_cnt": 2,
"ase_cnt": 2,
"direction": "SINK",
"codec_id": {
@@ -7148,18 +5103,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -7178,10 +5121,10 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
},
{
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SOURCE",
"codec_id": {
@@ -7209,23 +5152,11 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
"value": [
- 80,
+ 40,
0
]
}
@@ -7239,18 +5170,17 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
}
]
},
{
- "name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_32_2",
+ "name": "One-TwoChan-SnkAse-Lc3_48_4-One-TwoChan-SrcAse-Lc3_32_2",
"subconfigurations": [
{
- "device_cnt": 2,
- "ase_cnt": 4,
+ "ase_cnt": 1,
"direction": "SINK",
- "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -7276,18 +5206,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -7306,10 +5224,10 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 2
},
{
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SOURCE",
"codec_id": {
@@ -7337,18 +5255,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -7367,18 +5273,17 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 2
}
]
},
{
- "name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_24_2",
+ "name": "One-TwoChan-SnkAse-Lc3_48_4-One-TwoChan-SrcAse-Lc3_24_2",
"subconfigurations": [
{
- "device_cnt": 2,
- "ase_cnt": 4,
+ "ase_cnt": 1,
"direction": "SINK",
- "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -7404,18 +5309,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -7434,10 +5327,10 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 2
},
{
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SOURCE",
"codec_id": {
@@ -7465,23 +5358,11 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
"value": [
- 80,
+ 60,
0
]
}
@@ -7495,18 +5376,17 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 2
}
]
},
{
- "name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_16_2",
+ "name": "One-TwoChan-SnkAse-Lc3_48_4-One-TwoChan-SrcAse-Lc3_16_2",
"subconfigurations": [
{
- "device_cnt": 2,
- "ase_cnt": 4,
+ "ase_cnt": 1,
"direction": "SINK",
- "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -7532,18 +5412,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -7562,10 +5430,10 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 2
},
{
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SOURCE",
"codec_id": {
@@ -7593,23 +5461,11 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
"value": [
- 80,
+ 40,
0
]
}
@@ -7623,18 +5479,17 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 2
}
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_32_2",
+ "name": "One-TwoChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2",
"subconfigurations": [
{
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SINK",
- "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -7660,18 +5515,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 3,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -7690,397 +5533,10 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 2
},
{
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SOURCE",
- "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 3,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 80,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- }
- ]
- },
- {
- "name": "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_24_2",
- "subconfigurations": [
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SINK",
- "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 3,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 120,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- },
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SOURCE",
- "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 5
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 3,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 80,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- }
- ]
- },
- {
- "name": "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_16_2",
- "subconfigurations": [
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SINK",
- "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 3,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 120,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- },
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SOURCE",
- "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 3,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 80,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- }
- ]
- },
- {
- "name": "SingleDev_TwoChanStereoSnk_48_4_OneChanMonoSrc_32_2",
- "subconfigurations": [
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SINK",
- "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 3,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 120,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- },
- {
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SOURCE",
"codec_id": {
@@ -8108,18 +5564,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -8138,18 +5582,17 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
}
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_48_4_OneChanMonoSrc_24_2",
+ "name": "One-TwoChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2",
"subconfigurations": [
{
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SINK",
- "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -8175,18 +5618,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 3,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -8205,10 +5636,10 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 2
},
{
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SOURCE",
"codec_id": {
@@ -8236,23 +5667,11 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
"value": [
- 80,
+ 60,
0
]
}
@@ -8266,18 +5685,17 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
}
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_48_4_OneChanMonoSrc_16_2",
+ "name": "One-TwoChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2",
"subconfigurations": [
{
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SINK",
- "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -8303,18 +5721,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 3,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -8333,10 +5739,10 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 2
},
{
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SOURCE",
"codec_id": {
@@ -8364,23 +5770,11 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
"value": [
- 80,
+ 40,
0
]
}
@@ -8394,18 +5788,17 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
}
]
},
{
- "name": "SingleDev_OneChanStereoSnk_48_4_OneChanMonoSrc_32_2",
+ "name": "One-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2",
"subconfigurations": [
{
- "device_cnt": 1,
- "ase_cnt": 2,
+ "ase_cnt": 1,
"direction": "SINK",
- "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -8431,18 +5824,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -8461,10 +5842,10 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
},
{
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SOURCE",
"codec_id": {
@@ -8492,18 +5873,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -8522,18 +5891,17 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
}
]
},
{
- "name": "SingleDev_OneChanStereoSnk_48_4_OneChanMonoSrc_24_2",
+ "name": "One-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2",
"subconfigurations": [
{
- "device_cnt": 1,
- "ase_cnt": 2,
+ "ase_cnt": 1,
"direction": "SINK",
- "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -8559,18 +5927,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -8589,10 +5945,10 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
},
{
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SOURCE",
"codec_id": {
@@ -8620,23 +5976,11 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
"value": [
- 80,
+ 60,
0
]
}
@@ -8650,18 +5994,17 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
}
]
},
{
- "name": "SingleDev_OneChanStereoSnk_48_4_OneChanMonoSrc_16_2",
+ "name": "One-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2",
"subconfigurations": [
{
- "device_cnt": 1,
- "ase_cnt": 2,
+ "ase_cnt": 1,
"direction": "SINK",
- "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -8687,18 +6030,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -8717,10 +6048,10 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
},
{
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SOURCE",
"codec_id": {
@@ -8748,23 +6079,11 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
"value": [
- 80,
+ 40,
0
]
}
@@ -8778,399 +6097,17 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
}
]
},
{
- "name": "SingleDev_OneChanMonoSnk_48_4_OneChanMonoSrc_32_2",
+ "name": "Two-TwoChan-SnkAse-Lc3_48_1-Two-TwoChan-SrcAse-Lc3_48_1",
"subconfigurations": [
{
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 120,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- },
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 80,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- }
- ]
- },
- {
- "name": "SingleDev_OneChanMonoSnk_48_4_OneChanMonoSrc_24_2",
- "subconfigurations": [
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 120,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- },
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 5
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 80,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- }
- ]
- },
- {
- "name": "SingleDev_OneChanMonoSnk_48_4_OneChanMonoSrc_16_2",
- "subconfigurations": [
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 120,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- },
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 80,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- }
- ]
- },
- {
- "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_1",
- "subconfigurations": [
- {
- "device_cnt": 2,
"ase_cnt": 2,
"direction": "SOURCE",
- "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -9196,18 +6133,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 3,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -9226,13 +6151,12 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 2
},
{
- "device_cnt": 2,
"ase_cnt": 2,
"direction": "SINK",
- "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -9258,18 +6182,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 3,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -9288,18 +6200,17 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 2
}
]
},
{
- "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_2",
+ "name": "Two-TwoChan-SnkAse-Lc3_48_2-Two-TwoChan-SrcAse-Lc3_48_2",
"subconfigurations": [
{
- "device_cnt": 2,
"ase_cnt": 2,
"direction": "SOURCE",
- "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -9325,18 +6236,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 3,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -9355,13 +6254,12 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 2
},
{
- "device_cnt": 2,
"ase_cnt": 2,
"direction": "SINK",
- "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -9387,18 +6285,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 3,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -9417,7 +6303,8 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 2
}
]
},
@@ -9425,10 +6312,8 @@
"name": "VND_SingleDev_TwoChanStereoSrc_48khz_100octs_1",
"subconfigurations": [
{
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SOURCE",
- "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -9454,18 +6339,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 3,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -9484,7 +6357,8 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 2
}
]
},
@@ -9492,10 +6366,8 @@
"name": "VND_SingleDev_TwoChanStereoSnk_OneChanStereoSrc_32khz_60octs_1",
"subconfigurations": [
{
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SINK",
- "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -9521,18 +6393,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 3,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -9551,10 +6411,10 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 2
},
{
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SOURCE",
"codec_id": {
@@ -9582,18 +6442,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -9612,7 +6460,8 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
}
]
},
@@ -9620,10 +6469,8 @@
"name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_TwoChanStereoSrc_16khz_30octs_1",
"subconfigurations": [
{
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SINK",
- "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -9649,18 +6496,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 3,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -9679,13 +6514,12 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 2
},
{
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SOURCE",
- "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -9711,18 +6545,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 3,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -9741,18 +6563,17 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 2
}
]
},
{
- "name": "DualDev_OneChanStereoSnk_24_2",
+ "name": "Two-OneChan-SnkAse-Lc3_24_2",
"subconfigurations": [
{
- "device_cnt": 2,
"ase_cnt": 2,
"direction": "SINK",
- "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -9778,18 +6599,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -9808,18 +6617,17 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
}
]
},
{
- "name": "DualDev_OneChanStereoSnk_24_1",
+ "name": "Two-OneChan-SnkAse-Lc3_24_1",
"subconfigurations": [
{
- "device_cnt": 2,
"ase_cnt": 2,
"direction": "SINK",
- "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -9845,18 +6653,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -9875,18 +6671,17 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 1
}
]
},
{
- "name": "SingleDev_OneChanStereoSnk_24_2",
+ "name": "One-TwoChan-SnkAse-Lc3_24_2",
"subconfigurations": [
{
- "device_cnt": 1,
- "ase_cnt": 2,
+ "ase_cnt": 1,
"direction": "SINK",
- "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -9912,18 +6707,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -9942,18 +6725,17 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 2
}
]
},
{
- "name": "SingleDev_OneChanStereoSnk_24_1",
+ "name": "One-TwoChan-SnkAse-Lc3_24_1",
"subconfigurations": [
{
- "device_cnt": 1,
- "ase_cnt": 2,
+ "ase_cnt": 1,
"direction": "SINK",
- "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -9979,18 +6761,6 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
"name": "octets_per_codec_frame",
"type": 4,
"compound_value": {
@@ -10009,18 +6779,17 @@
]
}
}
- ]
+ ],
+ "ase_channel_cnt": 2
}
]
},
{
- "name": "SingleDev_TwoChanStereoSnk_24_2",
+ "name": "One-OneChan-SnkAse-Lc3_24_2",
"subconfigurations": [
{
- "device_cnt": 1,
"ase_cnt": 1,
"direction": "SINK",
- "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
"codec_id": {
"coding_format": 6,
"vendor_company_id": 0,
@@ -10046,13 +6815,521 @@
}
},
{
- "name": "audio_channel_allocation",
- "type": 3,
+ "name": "octets_per_codec_frame",
+ "type": 4,
"compound_value": {
"value": [
- 3,
- 0,
- 0,
+ 60,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_32_2-Two-OneChan-SrcAse-Lc3_32_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ },
+ {
+ "ase_cnt": 2,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ },
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ },
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ },
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_32_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ }
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_32_1",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
0
]
}
@@ -10076,1174 +7353,8 @@
]
}
}
- ]
- }
- ]
- },
- {
- "name": "SingleDev_TwoChanStereoSnk_24_1",
- "subconfigurations": [
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SINK",
- "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 5
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 3,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 45,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- }
- ]
- },
- {
- "name": "SingleDev_OneChanMonoSnk_24_2",
- "subconfigurations": [
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SINK",
- "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 5
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 60,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- }
- ]
- },
- {
- "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2",
- "subconfigurations": [
- {
- "device_cnt": 2,
- "ase_cnt": 2,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 80,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- },
- {
- "device_cnt": 2,
- "ase_cnt": 2,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 80,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- }
- ]
- },
- {
- "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_32_2",
- "subconfigurations": [
- {
- "device_cnt": 2,
- "ase_cnt": 2,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 80,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- },
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 80,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- }
- ]
- },
- {
- "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_32_2",
- "subconfigurations": [
- {
- "device_cnt": 2,
- "ase_cnt": 4,
- "direction": "SINK",
- "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 80,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- },
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 80,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- }
- ]
- },
- {
- "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2",
- "subconfigurations": [
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SINK",
- "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 3,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 80,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- },
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 80,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- }
- ]
- },
- {
- "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_32_2",
- "subconfigurations": [
- {
- "device_cnt": 1,
- "ase_cnt": 2,
- "direction": "SINK",
- "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 80,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- },
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 80,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- }
- ]
- },
- {
- "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2",
- "subconfigurations": [
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 80,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- },
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 80,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- }
- ]
- },
- {
- "name": "SingleDev_TwoChanStereoSnk_32_2",
- "subconfigurations": [
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SINK",
- "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 3,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 80,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- }
- ]
- },
- {
- "name": "SingleDev_TwoChanStereoSnk_32_1",
- "subconfigurations": [
- {
- "device_cnt": 1,
- "ase_cnt": 1,
- "direction": "SINK",
- "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 3,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 60,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- }
- ]
- },
- {
- "name": "SingleDev_OneChanStereoSnk_32_2",
- "subconfigurations": [
- {
- "device_cnt": 1,
- "ase_cnt": 2,
- "direction": "SINK",
- "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 80,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
- }
- ]
- },
- {
- "name": "SingleDev_OneChanStereoSnk_32_1",
- "subconfigurations": [
- {
- "device_cnt": 1,
- "ase_cnt": 2,
- "direction": "SINK",
- "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "audio_channel_allocation",
- "type": 3,
- "compound_value": {
- "value": [
- 1,
- 0,
- 0,
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 60,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ]
+ ],
+ "ase_channel_cnt": 2
}
]
}
@@ -11377,6 +7488,5 @@
"retransmission_number": 0,
"max_transport_latency": 0
}
-
]
}
diff --git a/bluetooth/audio/utils/le_audio_configuration_set/audio_set_scenarios.json b/bluetooth/audio/utils/le_audio_configuration_set/audio_set_scenarios.json
index a28c6cd..448adca 100644
--- a/bluetooth/audio/utils/le_audio_configuration_set/audio_set_scenarios.json
+++ b/bluetooth/audio/utils/le_audio_configuration_set/audio_set_scenarios.json
@@ -8,251 +8,206 @@
{
"name": "Conversational",
"configurations": [
- "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2_Low_Latency",
- "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2_1",
- "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_Low_Latency",
- "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_1",
- "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_2",
- "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_Low_Latency",
- "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_1",
- "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_2",
- "DualDev_OneChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency",
- "DualDev_OneChanStereoSnk_OneChanMonoSrc_32_2_1",
- "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency",
- "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_2_1",
- "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency",
- "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_1_1",
- "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_32_2_Low_Latency",
- "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_32_2_1",
- "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2_Low_Latency",
- "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2_1",
- "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1_Low_Latency",
- "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1_1",
- "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2_Low_Latency",
- "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2_1",
- "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_Low_Latency",
- "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_1",
- "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_2",
- "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_Low_Latency",
- "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_1",
- "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_2",
- "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency",
- "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2_1",
- "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency",
- "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2_1",
- "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency",
- "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1_1",
- "SingleDev_OneChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency",
- "SingleDev_OneChanStereoSnk_OneChanMonoSrc_32_2_1",
- "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency",
- "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2_1",
- "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency",
- "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1_1",
- "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2_Low_Latency",
- "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2_1",
- "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2_Low_Latency",
- "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2_1",
- "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1_Low_Latency",
- "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1_1",
- "DualDev_OneChanMonoSrc_16_2_Balanced_Reliability",
- "SingleDev_OneChanStereoSrc_16_2_Balanced_Reliability",
- "SingleDev_OneChanMonoSrc_48_4_Balanced_Reliability",
- "SingleDev_OneChanMonoSrc_48_2_Balanced_Reliability",
- "SingleDev_OneChanMonoSrc_48_3_Balanced_Reliability",
- "SingleDev_OneChanMonoSrc_48_1_Balanced_Reliability",
- "SingleDev_OneChanMonoSrc_32_2_Balanced_Reliability",
- "SingleDev_OneChanMonoSrc_32_1_Balanced_Reliability",
- "SingleDev_OneChanMonoSrc_24_2_Balanced_Reliability",
- "SingleDev_OneChanMonoSrc_24_1_Balanced_Reliability",
- "SingleDev_OneChanMonoSrc_16_2_Balanced_Reliability",
- "SingleDev_OneChanMonoSrc_16_1_Balanced_Reliability",
- "VND_SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32khz_Server_Prefered_1",
- "VND_SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32khz_60oct_R3_L22_1",
- "DualDev_OneChanMonoSnk_16_2_Balanced_Reliability",
- "SingleDev_OneChanStereoSnk_16_2_Balanced_Reliability",
- "SingleDev_TwoChanStereoSnk_16_2_Balanced_Reliability",
- "SingleDev_OneChanMonoSnk_16_2_Balanced_Reliability"
+ "Two-OneChan-SnkAse-Lc3_32_2-Two-OneChan-SrcAse-Lc3_32_2_1",
+ "Two-OneChan-SnkAse-Lc3_32_2-Two-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2_1",
+ "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2_2",
+ "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1_1",
+ "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1_2",
+ "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_1",
+ "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_1",
+ "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_1",
+ "One-TwoChan-SnkAse-Lc3_32_2-One-TwoChan-SrcAse-Lc3_32_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_32_2-One-TwoChan-SrcAse-Lc3_32_2_1",
+ "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2_1",
+ "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2_2",
+ "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1_1",
+ "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1_2",
+ "One-TwoChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_1",
+ "One-TwoChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_1",
+ "One-TwoChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_1",
+ "One-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "One-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_1",
+ "One-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "One-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_1",
+ "One-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
+ "One-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_1",
+ "Two-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
+ "One-OneChan-SrcAse-Lc3_48_4_Balanced_Reliability",
+ "One-OneChan-SrcAse-Lc3_48_2_Balanced_Reliability",
+ "One-OneChan-SrcAse-Lc3_48_3_Balanced_Reliability",
+ "One-OneChan-SrcAse-Lc3_48_1_Balanced_Reliability",
+ "One-OneChan-SrcAse-Lc3_32_2_Balanced_Reliability",
+ "One-OneChan-SrcAse-Lc3_32_1_Balanced_Reliability",
+ "One-OneChan-SrcAse-Lc3_24_2_Balanced_Reliability",
+ "One-OneChan-SrcAse-Lc3_24_1_Balanced_Reliability",
+ "One-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
+ "One-OneChan-SrcAse-Lc3_16_1_Balanced_Reliability",
+ "VND_SingleDev_TwoChanStereoSnk_OneChanStereoSrc_32khz_60oct_R3_L22_1",
+ "Two-OneChan-SnkAse-Lc3_16_2_Balanced_Reliability",
+ "One-TwoChan-SnkAse-Lc3_16_2_Balanced_Reliability",
+ "One-OneChan-SnkAse-Lc3_16_2_Balanced_Reliability"
]
},
{
"name": "Media",
"configurations": [
- "DualDev_OneChanStereoSnk_48_4_High_Reliability",
- "DualDev_OneChanStereoSnk_48_4_2",
- "DualDev_OneChanStereoSnk_48_2_High_Reliability",
- "DualDev_OneChanStereoSnk_48_2_2",
- "DualDev_OneChanStereoSnk_48_3_High_Reliability",
- "DualDev_OneChanStereoSnk_48_3_2",
- "DualDev_OneChanStereoSnk_48_1_High_Reliability",
- "DualDev_OneChanStereoSnk_48_1_2",
- "DualDev_OneChanStereoSnk_24_2_Balanced_Reliability",
- "DualDev_OneChanStereoSnk_24_2_2",
- "DualDev_OneChanStereoSnk_16_2_Balanced_Reliability",
- "DualDev_OneChanStereoSnk_16_2_2",
- "DualDev_OneChanStereoSnk_16_1_Balanced_Reliability",
- "DualDev_OneChanStereoSnk_16_1_2",
- "SingleDev_OneChanStereoSnk_48_4_High_Reliability",
- "SingleDev_OneChanStereoSnk_48_4_2",
- "SingleDev_OneChanStereoSnk_48_2_High_Reliability",
- "SingleDev_OneChanStereoSnk_48_2_2",
- "SingleDev_OneChanStereoSnk_48_3_High_Reliability",
- "SingleDev_OneChanStereoSnk_48_3_2",
- "SingleDev_OneChanStereoSnk_48_1_High_Reliability",
- "SingleDev_OneChanStereoSnk_48_1_2",
- "SingleDev_OneChanStereoSnk_24_2_Balanced_Reliability",
- "SingleDev_OneChanStereoSnk_24_2_2",
- "SingleDev_OneChanStereoSnk_16_2_Balanced_Reliability",
- "SingleDev_OneChanStereoSnk_16_2_2",
- "SingleDev_OneChanStereoSnk_16_1_Balanced_Reliability",
- "SingleDev_OneChanStereoSnk_16_1_2",
- "SingleDev_TwoChanStereoSnk_48_4_High_Reliability",
- "SingleDev_TwoChanStereoSnk_48_4_2",
- "SingleDev_TwoChanStereoSnk_48_4_High_Reliability",
- "SingleDev_TwoChanStereoSnk_48_4_2",
- "SingleDev_TwoChanStereoSnk_48_2_High_Reliability",
- "SingleDev_TwoChanStereoSnk_48_2_2",
- "SingleDev_TwoChanStereoSnk_48_3_High_Reliability",
- "SingleDev_TwoChanStereoSnk_48_3_2",
- "SingleDev_TwoChanStereoSnk_48_1_High_Reliability",
- "SingleDev_TwoChanStereoSnk_48_1_2",
- "SingleDev_TwoChanStereoSnk_24_2_Balanced_Reliability",
- "SingleDev_TwoChanStereoSnk_24_2_2",
- "SingleDev_TwoChanStereoSnk_16_2_Balanced_Reliability",
- "SingleDev_TwoChanStereoSnk_16_2_2",
- "SingleDev_TwoChanStereoSnk_16_1_Balanced_Reliability",
- "SingleDev_TwoChanStereoSnk_16_1_2",
- "SingleDev_OneChanMonoSnk_48_4_High_Reliability",
- "SingleDev_OneChanMonoSnk_48_4_2",
- "SingleDev_OneChanMonoSnk_48_2_High_Reliability",
- "SingleDev_OneChanMonoSnk_48_2_2",
- "SingleDev_OneChanMonoSnk_48_3_High_Reliability",
- "SingleDev_OneChanMonoSnk_48_3_2",
- "SingleDev_OneChanMonoSnk_48_1_High_Reliability",
- "SingleDev_OneChanMonoSnk_48_1_2",
- "SingleDev_OneChanMonoSnk_32_2_Balanced_Reliability",
- "SingleDev_OneChanMonoSnk_32_2_2",
- "SingleDev_OneChanMonoSnk_32_1_Balanced_Reliability",
- "SingleDev_OneChanMonoSnk_32_1_2",
- "SingleDev_OneChanMonoSnk_24_2_Balanced_Reliability",
- "SingleDev_OneChanMonoSnk_24_2_2",
- "SingleDev_OneChanMonoSnk_16_2_Balanced_Reliability",
- "SingleDev_OneChanMonoSnk_16_2_2",
- "SingleDev_OneChanMonoSnk_16_1_Balanced_Reliability",
- "SingleDev_OneChanMonoSnk_16_1_2",
+ "Two-OneChan-SnkAse-Lc3_48_4_High_Reliability",
+ "Two-OneChan-SnkAse-Lc3_48_4_2",
+ "Two-OneChan-SnkAse-Lc3_48_2_High_Reliability",
+ "Two-OneChan-SnkAse-Lc3_48_2_2",
+ "Two-OneChan-SnkAse-Lc3_48_3_High_Reliability",
+ "Two-OneChan-SnkAse-Lc3_48_3_2",
+ "Two-OneChan-SnkAse-Lc3_48_1_High_Reliability",
+ "Two-OneChan-SnkAse-Lc3_48_1_2",
+ "Two-OneChan-SnkAse-Lc3_24_2_Balanced_Reliability",
+ "Two-OneChan-SnkAse-Lc3_24_2_2",
+ "Two-OneChan-SnkAse-Lc3_16_2_Balanced_Reliability",
+ "Two-OneChan-SnkAse-Lc3_16_2_2",
+ "Two-OneChan-SnkAse-Lc3_16_1_Balanced_Reliability",
+ "Two-OneChan-SnkAse-Lc3_16_1_2",
+ "One-TwoChan-SnkAse-Lc3_48_4_High_Reliability",
+ "One-TwoChan-SnkAse-Lc3_48_4_2",
+ "One-TwoChan-SnkAse-Lc3_48_2_High_Reliability",
+ "One-TwoChan-SnkAse-Lc3_48_2_2",
+ "One-TwoChan-SnkAse-Lc3_48_3_High_Reliability",
+ "One-TwoChan-SnkAse-Lc3_48_3_2",
+ "One-TwoChan-SnkAse-Lc3_48_1_High_Reliability",
+ "One-TwoChan-SnkAse-Lc3_48_1_2",
+ "One-TwoChan-SnkAse-Lc3_24_2_Balanced_Reliability",
+ "One-TwoChan-SnkAse-Lc3_24_2_2",
+ "One-TwoChan-SnkAse-Lc3_16_2_Balanced_Reliability",
+ "One-TwoChan-SnkAse-Lc3_16_2_2",
+ "One-TwoChan-SnkAse-Lc3_16_1_Balanced_Reliability",
+ "One-TwoChan-SnkAse-Lc3_16_1_2",
+ "One-OneChan-SnkAse-Lc3_48_4_High_Reliability",
+ "One-OneChan-SnkAse-Lc3_48_4_2",
+ "One-OneChan-SnkAse-Lc3_48_2_High_Reliability",
+ "One-OneChan-SnkAse-Lc3_48_2_2",
+ "One-OneChan-SnkAse-Lc3_48_3_High_Reliability",
+ "One-OneChan-SnkAse-Lc3_48_3_2",
+ "One-OneChan-SnkAse-Lc3_48_1_High_Reliability",
+ "One-OneChan-SnkAse-Lc3_48_1_2",
+ "One-OneChan-SnkAse-Lc3_32_2_Balanced_Reliability",
+ "One-OneChan-SnkAse-Lc3_32_2_2",
+ "One-OneChan-SnkAse-Lc3_32_1_Balanced_Reliability",
+ "One-OneChan-SnkAse-Lc3_32_1_2",
+ "One-OneChan-SnkAse-Lc3_24_2_Balanced_Reliability",
+ "One-OneChan-SnkAse-Lc3_24_2_2",
+ "One-OneChan-SnkAse-Lc3_16_2_Balanced_Reliability",
+ "One-OneChan-SnkAse-Lc3_16_2_2",
+ "One-OneChan-SnkAse-Lc3_16_1_Balanced_Reliability",
+ "One-OneChan-SnkAse-Lc3_16_1_2",
"VND_DualDev_OneChanStereoSnk_48khz_100octs_High_Reliability_1",
"VND_DualDev_OneChanStereoSnk_48khz_100octs_R15_L70_1",
"VND_SingleDev_TwoChanStereoSnk_48khz_100octs_High_Reliability_1",
"VND_SingleDev_TwoChanStereoSnk_48khz_100octs_R15_L70_1",
"VND_SingleDev_OneChanStereoSnk_48khz_100octs_High_Reliability_1",
"VND_SingleDev_OneChanStereoSnk_48khz_100octs_R15_L70_1",
- "DualDev_OneChanMonoSrc_16_2_Balanced_Reliability",
- "SingleDev_OneChanStereoSrc_16_2_Balanced_Reliability",
- "SingleDev_OneChanMonoSrc_16_2_Balanced_Reliability"
+ "Two-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
+ "One-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability"
]
},
{
"name": "Game",
"configurations": [
- "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2_Low_Latency",
- "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_Low_Latency",
- "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_Low_Latency",
- "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_2_Low_Latency",
- "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_1_Low_Latency",
- "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2_Low_Latency",
- "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_Low_Latency",
- "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_Low_Latency",
- "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency",
- "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency",
- "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_32_2-Two-OneChan-SrcAse-Lc3_32_2_1",
+ "Two-OneChan-SnkAse-Lc3_32_2-Two-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1_Low_Latency",
+ "Two-TwoChan-SnkAse-Lc3_48_2-Two-TwoChan-SrcAse-Lc3_48_2_Low_Latency",
+ "Two-TwoChan-SnkAse-Lc3_48_1-Two-TwoChan-SrcAse-Lc3_48_1_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_32_2-One-TwoChan-SrcAse-Lc3_32_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
"VND_SingleDev_TwoChanStereoSnk_48khz_75octs_TwoChanStereoSrc_16khz_30octs_Balanced_Reliability_1",
"VND_SingleDev_TwoChanStereoSnk_48khz_75octs_R5_L12_TwoChanStereoSrc_16khz_30octs_R3_L12_1",
"VND_SingleDev_TwoChanStereoSnk_48khz_75octs_High_Reliability_1",
"VND_SingleDev_TwoChanStereoSnk_48khz_75octs_R5_L12_1",
- "SingleDev_OneChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency",
- "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency",
- "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency",
- "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2_Low_Latency",
- "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2_Low_Latency",
- "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1_Low_Latency",
- "DualDev_OneChanStereoSnk_48_2_Low_Latency",
- "DualDev_OneChanStereoSnk_48_3_Low_Latency",
- "DualDev_OneChanStereoSnk_48_1_Low_Latency",
- "DualDev_OneChanStereoSnk_32_2_Low_Latency",
- "DualDev_OneChanStereoSnk_32_1_Low_Latency",
- "DualDev_OneChanStereoSnk_24_2_Low_Latency",
- "DualDev_OneChanStereoSnk_24_1_Low_Latency",
- "DualDev_OneChanStereoSnk_16_2_Low_Latency",
- "DualDev_OneChanStereoSnk_16_1_Low_Latency",
- "SingleDev_TwoChanStereoSnk_48_2_Low_Latency",
- "SingleDev_TwoChanStereoSnk_48_3_Low_Latency",
- "SingleDev_TwoChanStereoSnk_48_1_Low_Latency",
- "SingleDev_TwoChanStereoSnk_32_2_Low_Latency",
- "SingleDev_TwoChanStereoSnk_32_1_Low_Latency",
- "SingleDev_TwoChanStereoSnk_24_2_Low_Latency",
- "SingleDev_TwoChanStereoSnk_24_1_Low_Latency",
- "SingleDev_TwoChanStereoSnk_16_2_Low_Latency",
- "SingleDev_TwoChanStereoSnk_16_1_Low_Latency",
- "SingleDev_OneChanStereoSnk_48_2_Low_Latency",
- "SingleDev_OneChanStereoSnk_48_3_Low_Latency",
- "SingleDev_OneChanStereoSnk_48_1_Low_Latency",
- "SingleDev_OneChanStereoSnk_32_2_Low_Latency",
- "SingleDev_OneChanStereoSnk_32_1_Low_Latency",
- "SingleDev_OneChanStereoSnk_24_2_Low_Latency",
- "SingleDev_OneChanStereoSnk_24_1_Low_Latency",
- "SingleDev_OneChanStereoSnk_16_2_Low_Latency",
- "SingleDev_OneChanStereoSnk_16_1_Low_Latency"
+ "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_1",
+ "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
+ "One-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "One-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "One-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_48_2_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_48_3_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_48_1_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_32_2_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_32_1_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_24_2_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_24_1_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_2_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_1_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_48_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_48_3_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_48_1_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_32_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_32_1_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_24_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_24_1_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_16_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_16_1_Low_Latency"
]
},
{
"name": "VoiceAssistants",
"configurations": [
- "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2_Low_Latency",
- "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2_1",
- "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_Low_Latency",
- "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_1",
- "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_Low_Latency",
- "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_1",
- "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_2_Balanced_Reliability",
- "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_1_Balanced_Reliability",
- "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2_Low_Latency",
- "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2_1",
- "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_Low_Latency",
- "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_1",
- "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_Low_Latency",
- "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_1",
- "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency",
- "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2_1",
- "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency",
- "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2_1",
- "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency",
- "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1_1",
- "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2_Low_Latency",
- "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2_1",
- "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2_Low_Latency",
- "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2_1",
- "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1_Low_Latency",
- "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1_1",
- "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_16_2_Balanced_Reliability",
- "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_24_2_Balanced_Reliability",
- "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_32_2_Balanced_Reliability",
- "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_16_2_Balanced_Reliability",
- "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_24_2_Balanced_Reliability",
- "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_32_2_Balanced_Reliability",
- "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_16_2_Balanced_Reliability",
- "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_24_2_Balanced_Reliability",
- "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_32_2_Balanced_Reliability",
- "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_16_2_Balanced_Reliability",
- "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_24_2_Balanced_Reliability",
- "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_32_2_Balanced_Reliability",
- "SingleDev_TwoChanStereoSnk_48_4_OneChanMonoSrc_16_2_Balanced_Reliability",
- "SingleDev_TwoChanStereoSnk_48_4_OneChanMonoSrc_24_2_Balanced_Reliability",
- "SingleDev_TwoChanStereoSnk_48_4_OneChanMonoSrc_32_2_Balanced_Reliability",
- "SingleDev_OneChanStereoSnk_48_4_OneChanMonoSrc_16_2_Balanced_Reliability",
- "SingleDev_OneChanStereoSnk_48_4_OneChanMonoSrc_24_2_Balanced_Reliability",
- "SingleDev_OneChanStereoSnk_48_4_OneChanMonoSrc_32_2_Balanced_Reliability",
- "SingleDev_OneChanMonoSnk_48_4_OneChanMonoSrc_16_2_Balanced_Reliability",
- "SingleDev_OneChanMonoSnk_48_4_OneChanMonoSrc_24_2_Balanced_Reliability",
- "SingleDev_OneChanMonoSnk_48_4_OneChanMonoSrc_32_2_Balanced_Reliability"
+ "Two-OneChan-SnkAse-Lc3_32_2-Two-OneChan-SrcAse-Lc3_32_2_1",
+ "Two-OneChan-SnkAse-Lc3_32_2-Two-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2_1",
+ "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1_1",
+ "Two-TwoChan-SnkAse-Lc3_48_2-Two-TwoChan-SrcAse-Lc3_48_2_Balanced_Reliability",
+ "Two-TwoChan-SnkAse-Lc3_48_1-Two-TwoChan-SrcAse-Lc3_48_1_Balanced_Reliability",
+ "One-TwoChan-SnkAse-Lc3_32_2-One-TwoChan-SrcAse-Lc3_32_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_32_2-One-TwoChan-SrcAse-Lc3_32_2_1",
+ "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2_1",
+ "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1_1",
+ "One-TwoChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_1",
+ "One-TwoChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_1",
+ "One-TwoChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_1",
+ "One-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "One-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_1",
+ "One-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "One-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_1",
+ "One-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
+ "One-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_1",
+ "Two-OneChan-SnkAse-Lc3_48_4-Two-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
+ "Two-OneChan-SnkAse-Lc3_48_4-Two-OneChan-SrcAse-Lc3_24_2_Balanced_Reliability",
+ "Two-OneChan-SnkAse-Lc3_48_4-Two-OneChan-SrcAse-Lc3_32_2_Balanced_Reliability",
+ "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
+ "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2_Balanced_Reliability",
+ "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2_Balanced_Reliability",
+ "One-TwoChan-SnkAse-Lc3_48_4-One-TwoChan-SrcAse-Lc3_16_2_Balanced_Reliability",
+ "One-TwoChan-SnkAse-Lc3_48_4-One-TwoChan-SrcAse-Lc3_24_2_Balanced_Reliability",
+ "One-TwoChan-SnkAse-Lc3_48_4-One-TwoChan-SrcAse-Lc3_32_2_Balanced_Reliability",
+ "One-TwoChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
+ "One-TwoChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2_Balanced_Reliability",
+ "One-TwoChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2_Balanced_Reliability",
+ "One-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
+ "One-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2_Balanced_Reliability",
+ "One-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2_Balanced_Reliability"
]
},
{
@@ -260,44 +215,44 @@
"configurations": [
"VND_SingleDev_TwoChanStereoSrc_48khz_100octs_Balanced_Reliability_1",
"VND_SingleDev_TwoChanStereoSrc_48khz_100octs_R11_L40_1",
- "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2_Low_Latency",
- "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2_1",
- "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_Low_Latency",
- "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_1",
- "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_Low_Latency",
- "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_1",
- "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_2_Balanced_Reliability",
- "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_1_Balanced_Reliability",
- "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2_Low_Latency",
- "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2_1",
- "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_Low_Latency",
- "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_1",
- "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_Low_Latency",
- "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_1",
- "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency",
- "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2_1",
- "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency",
- "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2_1",
- "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency",
- "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1_1",
- "SingleDev_OneChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency",
- "SingleDev_OneChanStereoSnk_OneChanMonoSrc_32_2_1",
- "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency",
- "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2_1",
- "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency",
- "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1_1",
- "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2_Low_Latency",
- "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2_1",
- "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2_Low_Latency",
- "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2_1",
- "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1_Low_Latency",
- "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1_1",
- "SingleDev_OneChanMonoSrc_48_2_Balanced_Reliability",
- "SingleDev_OneChanMonoSrc_48_1_Balanced_Reliability",
- "SingleDev_OneChanMonoSrc_32_2_Balanced_Reliability",
- "SingleDev_OneChanMonoSrc_32_1_Balanced_Reliability",
- "SingleDev_OneChanMonoSrc_16_2_Balanced_Reliability",
- "SingleDev_OneChanMonoSrc_16_1_Balanced_Reliability"
+ "Two-OneChan-SnkAse-Lc3_32_2-Two-OneChan-SrcAse-Lc3_32_2_1",
+ "Two-OneChan-SnkAse-Lc3_32_2-Two-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2_1",
+ "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1_1",
+ "Two-TwoChan-SnkAse-Lc3_48_2-Two-TwoChan-SrcAse-Lc3_48_2_Balanced_Reliability",
+ "Two-TwoChan-SnkAse-Lc3_48_1-Two-TwoChan-SrcAse-Lc3_48_1_Balanced_Reliability",
+ "One-TwoChan-SnkAse-Lc3_32_2-One-TwoChan-SrcAse-Lc3_32_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_32_2-One-TwoChan-SrcAse-Lc3_32_2_1",
+ "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2_1",
+ "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1_1",
+ "One-TwoChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_1",
+ "One-TwoChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_1",
+ "One-TwoChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_1",
+ "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_1",
+ "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_1",
+ "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_1",
+ "One-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "One-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_1",
+ "One-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "One-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_1",
+ "One-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
+ "One-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_1",
+ "One-OneChan-SrcAse-Lc3_48_2_Balanced_Reliability",
+ "One-OneChan-SrcAse-Lc3_48_1_Balanced_Reliability",
+ "One-OneChan-SrcAse-Lc3_32_2_Balanced_Reliability",
+ "One-OneChan-SrcAse-Lc3_32_1_Balanced_Reliability",
+ "One-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
+ "One-OneChan-SrcAse-Lc3_16_1_Balanced_Reliability"
]
}
]
diff --git a/boot/aidl/client/BootControlClient.cpp b/boot/aidl/client/BootControlClient.cpp
index 89258d2..dca98c6 100644
--- a/boot/aidl/client/BootControlClient.cpp
+++ b/boot/aidl/client/BootControlClient.cpp
@@ -18,6 +18,7 @@
#include <aidl/android/hardware/boot/IBootControl.h>
#include <android-base/logging.h>
+#include <android/binder_ibinder.h>
#include <android/binder_manager.h>
#include <android/hardware/boot/1.0/IBootControl.h>
#include <android/hardware/boot/1.1/IBootControl.h>
@@ -65,63 +66,79 @@
using IBootControl = ::aidl::android::hardware::boot::IBootControl;
public:
- BootControlClientAidl(std::shared_ptr<IBootControl> module) : module_(module) {}
+ explicit BootControlClientAidl(std::shared_ptr<IBootControl> module)
+ : module_(module),
+ boot_control_death_recipient(AIBinder_DeathRecipient_new(onBootControlServiceDied)) {
+ binder_status_t status = AIBinder_linkToDeath(module->asBinder().get(),
+ boot_control_death_recipient, nullptr);
+ if (status != STATUS_OK) {
+ LOG(ERROR) << "Could not link to binder death";
+ return;
+ }
+ }
BootControlVersion GetVersion() const override { return BootControlVersion::BOOTCTL_AIDL; }
- ~BootControlClientAidl() = default;
- virtual int32_t GetNumSlots() const {
+ ~BootControlClientAidl() {
+ if (boot_control_death_recipient) {
+ AIBinder_unlinkToDeath(module_->asBinder().get(), boot_control_death_recipient, this);
+ }
+ }
+
+ void onBootControlServiceDied() { LOG(ERROR) << "boot control service AIDL died"; }
+
+ int32_t GetNumSlots() const override {
int32_t ret = -1;
LOG_NDK_STATUS(module_->getNumberSlots(&ret));
return ret;
}
- int32_t GetCurrentSlot() const {
+ int32_t GetCurrentSlot() const override {
int32_t ret = -1;
LOG_NDK_STATUS(module_->getCurrentSlot(&ret));
return ret;
}
- MergeStatus getSnapshotMergeStatus() const {
+ MergeStatus getSnapshotMergeStatus() const override {
MergeStatus status = MergeStatus::UNKNOWN;
LOG_NDK_STATUS(module_->getSnapshotMergeStatus(&status));
return status;
}
- std::string GetSuffix(int32_t slot) const {
+ std::string GetSuffix(int32_t slot) const override {
std::string ret;
const auto status = module_->getSuffix(slot, &ret);
if (!status.isOk()) {
- LOG(ERROR) << __FUNCTION__ << "(" << slot << ")"
- << " failed " << status.getDescription();
+ LOG(ERROR) << __FUNCTION__ << "(" << slot << ")" << " failed "
+ << status.getDescription();
return {};
}
return ret;
}
- std::optional<bool> IsSlotBootable(int32_t slot) const {
+ std::optional<bool> IsSlotBootable(int32_t slot) const override {
bool ret = false;
const auto status = module_->isSlotBootable(slot, &ret);
if (!status.isOk()) {
- LOG(ERROR) << __FUNCTION__ << "(" << slot << ")"
- << " failed " << status.getDescription();
+ LOG(ERROR) << __FUNCTION__ << "(" << slot << ")" << " failed "
+ << status.getDescription();
return {};
}
return ret;
}
- CommandResult MarkSlotUnbootable(int32_t slot) {
+ CommandResult MarkSlotUnbootable(int32_t slot) override {
const auto status = module_->setSlotAsUnbootable(slot);
if (!status.isOk()) {
- LOG(ERROR) << __FUNCTION__ << "(" << slot << ")"
- << " failed " << status.getDescription();
+ LOG(ERROR) << __FUNCTION__ << "(" << slot << ")" << " failed "
+ << status.getDescription();
}
return {.success = status.isOk(), .errMsg = status.getDescription()};
}
- CommandResult SetActiveBootSlot(int slot) {
+ CommandResult SetActiveBootSlot(int slot) override {
const auto status = module_->setActiveBootSlot(slot);
if (!status.isOk()) {
- LOG(ERROR) << __FUNCTION__ << "(" << slot << ")"
- << " failed " << status.getDescription();
+ LOG(ERROR) << __FUNCTION__ << "(" << slot << ")" << " failed "
+ << status.getDescription();
}
return {.success = status.isOk(), .errMsg = status.getDescription()};
}
@@ -132,18 +149,18 @@
}
// Check if |slot| is marked boot successfully.
- std::optional<bool> IsSlotMarkedSuccessful(int slot) const {
+ std::optional<bool> IsSlotMarkedSuccessful(int slot) const override {
bool ret = false;
const auto status = module_->isSlotMarkedSuccessful(slot, &ret);
if (!status.isOk()) {
- LOG(ERROR) << __FUNCTION__ << "(" << slot << ")"
- << " failed " << status.getDescription();
+ LOG(ERROR) << __FUNCTION__ << "(" << slot << ")" << " failed "
+ << status.getDescription();
return {};
}
return ret;
}
- CommandResult MarkBootSuccessful() {
+ CommandResult MarkBootSuccessful() override {
const auto status = module_->markBootSuccessful();
if (!status.isOk()) {
LOG(ERROR) << __FUNCTION__ << " failed " << status.getDescription();
@@ -151,17 +168,23 @@
return {.success = status.isOk(), .errMsg = status.getDescription()};
}
- CommandResult SetSnapshotMergeStatus(aidl::android::hardware::boot::MergeStatus merge_status) {
+ CommandResult SetSnapshotMergeStatus(
+ aidl::android::hardware::boot::MergeStatus merge_status) override {
const auto status = module_->setSnapshotMergeStatus(merge_status);
if (!status.isOk()) {
- LOG(ERROR) << __FUNCTION__ << "(" << merge_status << ")"
- << " failed " << status.getDescription();
+ LOG(ERROR) << __FUNCTION__ << "(" << merge_status << ")" << " failed "
+ << status.getDescription();
}
return {.success = status.isOk(), .errMsg = status.getDescription()};
}
private:
const std::shared_ptr<IBootControl> module_;
+ AIBinder_DeathRecipient* boot_control_death_recipient;
+ static void onBootControlServiceDied(void* client) {
+ BootControlClientAidl* self = static_cast<BootControlClientAidl*>(client);
+ self->onBootControlServiceDied();
+ }
};
using namespace android::hardware::boot;
@@ -183,7 +206,7 @@
return BootControlVersion::BOOTCTL_V1_0;
}
}
- int32_t GetNumSlots() const {
+ int32_t GetNumSlots() const override {
const auto ret = module_v1_->getNumberSlots();
if (!ret.isOk()) {
LOG(ERROR) << __FUNCTION__ << " failed " << ret.description();
@@ -191,7 +214,7 @@
return ret.withDefault(-1);
}
- int32_t GetCurrentSlot() const {
+ int32_t GetCurrentSlot() const override {
const auto ret = module_v1_->getCurrentSlot();
if (!ret.isOk()) {
LOG(ERROR) << __FUNCTION__ << " failed " << ret.description();
@@ -199,23 +222,21 @@
return ret.withDefault(-1);
}
- std::string GetSuffix(int32_t slot) const {
+ std::string GetSuffix(int32_t slot) const override {
std::string suffix;
const auto ret = module_v1_->getSuffix(
slot,
[&](const ::android::hardware::hidl_string& slotSuffix) { suffix = slotSuffix; });
if (!ret.isOk()) {
- LOG(ERROR) << __FUNCTION__ << "(" << slot << ")"
- << " failed " << ret.description();
+ LOG(ERROR) << __FUNCTION__ << "(" << slot << ")" << " failed " << ret.description();
}
return suffix;
}
- std::optional<bool> IsSlotBootable(int32_t slot) const {
+ std::optional<bool> IsSlotBootable(int32_t slot) const override {
const auto ret = module_v1_->isSlotBootable(slot);
if (!ret.isOk()) {
- LOG(ERROR) << __FUNCTION__ << "(" << slot << ")"
- << " failed " << ret.description();
+ LOG(ERROR) << __FUNCTION__ << "(" << slot << ")" << " failed " << ret.description();
return {};
}
const auto bool_result = ret.withDefault(V1_0::BoolResult::INVALID_SLOT);
@@ -225,7 +246,7 @@
return bool_result == V1_0::BoolResult::TRUE;
}
- CommandResult MarkSlotUnbootable(int32_t slot) {
+ CommandResult MarkSlotUnbootable(int32_t slot) override {
CommandResult result;
const auto ret =
module_v1_->setSlotAsUnbootable(slot, [&](const V1_0::CommandResult& error) {
@@ -233,26 +254,24 @@
result.errMsg = error.errMsg;
});
if (!ret.isOk()) {
- LOG(ERROR) << __FUNCTION__ << "(" << slot << ")"
- << " failed " << ret.description();
+ LOG(ERROR) << __FUNCTION__ << "(" << slot << ")" << " failed " << ret.description();
}
return result;
}
- CommandResult SetActiveBootSlot(int32_t slot) {
+ CommandResult SetActiveBootSlot(int32_t slot) override {
CommandResult result;
const auto ret = module_v1_->setActiveBootSlot(slot, [&](const V1_0::CommandResult& error) {
result.success = error.success;
result.errMsg = error.errMsg;
});
if (!ret.isOk()) {
- LOG(ERROR) << __FUNCTION__ << "(" << slot << ")"
- << " failed " << ret.description();
+ LOG(ERROR) << __FUNCTION__ << "(" << slot << ")" << " failed " << ret.description();
}
return result;
}
- CommandResult MarkBootSuccessful() {
+ CommandResult MarkBootSuccessful() override {
CommandResult result;
const auto ret = module_v1_->markBootSuccessful([&](const V1_0::CommandResult& error) {
result.success = error.success;
@@ -264,11 +283,10 @@
return result;
}
- std::optional<bool> IsSlotMarkedSuccessful(int32_t slot) const {
+ std::optional<bool> IsSlotMarkedSuccessful(int32_t slot) const override {
const auto ret = module_v1_->isSlotMarkedSuccessful(slot);
if (!ret.isOk()) {
- LOG(ERROR) << __FUNCTION__ << "(" << slot << ")"
- << " failed " << ret.description();
+ LOG(ERROR) << __FUNCTION__ << "(" << slot << ")" << " failed " << ret.description();
return {};
}
const auto bool_result = ret.withDefault(V1_0::BoolResult::INVALID_SLOT);
@@ -278,7 +296,7 @@
return bool_result == V1_0::BoolResult::TRUE;
}
- MergeStatus getSnapshotMergeStatus() const {
+ MergeStatus getSnapshotMergeStatus() const override {
if (module_v1_1_ == nullptr) {
LOG(ERROR) << __FUNCTION__ << " is unsupported, requires at least boot v1.1";
return MergeStatus::UNKNOWN;
@@ -291,7 +309,7 @@
ret.withDefault(static_cast<V1_1::MergeStatus>(MergeStatus::UNKNOWN)));
}
- CommandResult SetSnapshotMergeStatus(MergeStatus merge_status) {
+ CommandResult SetSnapshotMergeStatus(MergeStatus merge_status) override {
if (module_v1_1_ == nullptr) {
return {.success = false,
.errMsg = "setSnapshotMergeStatus is unsupported, requires at least boot v1.1"};
@@ -299,13 +317,13 @@
const auto ret =
module_v1_1_->setSnapshotMergeStatus(static_cast<V1_1::MergeStatus>(merge_status));
if (!ret.isOk()) {
- LOG(ERROR) << __FUNCTION__ << "(" << merge_status << ")"
- << " failed " << ret.description();
+ LOG(ERROR) << __FUNCTION__ << "(" << merge_status << ")" << " failed "
+ << ret.description();
}
return {.success = ret.isOk(), .errMsg = ret.description()};
}
- int32_t GetActiveBootSlot() const {
+ int32_t GetActiveBootSlot() const override {
if (module_v1_2_ == nullptr) {
LOG(ERROR) << __FUNCTION__ << " is unsupported, requires at least boot v1.2";
return -1;
@@ -326,7 +344,6 @@
std::unique_ptr<BootControlClient> BootControlClient::WaitForService() {
const auto instance_name =
std::string(::aidl::android::hardware::boot::IBootControl::descriptor) + "/default";
-
if (AServiceManager_isDeclared(instance_name.c_str())) {
auto module = ::aidl::android::hardware::boot::IBootControl::fromBinder(
ndk::SpAIBinder(AServiceManager_waitForService(instance_name.c_str())));
diff --git a/camera/device/default/ExternalCameraDeviceSession.cpp b/camera/device/default/ExternalCameraDeviceSession.cpp
index 91196d4..abd5d7e 100644
--- a/camera/device/default/ExternalCameraDeviceSession.cpp
+++ b/camera/device/default/ExternalCameraDeviceSession.cpp
@@ -1136,6 +1136,11 @@
uint32_t v4lBufferCount = (fps >= kDefaultFps) ? mCfg.numVideoBuffers : mCfg.numStillBuffers;
+ // Double the max lag in theory.
+ mMaxLagNs = v4lBufferCount * 1000000000LL * 2 / fps;
+ ALOGI("%s: set mMaxLagNs to %" PRIu64 " ns, v4lBufferCount %u", __FUNCTION__, mMaxLagNs,
+ v4lBufferCount);
+
// VIDIOC_REQBUFS: create buffers
v4l2_requestbuffers req_buffers{};
req_buffers.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
@@ -1232,40 +1237,67 @@
}
}
- ATRACE_BEGIN("VIDIOC_DQBUF");
+ uint64_t lagNs = 0;
v4l2_buffer buffer{};
- buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- buffer.memory = V4L2_MEMORY_MMAP;
- if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_DQBUF, &buffer)) < 0) {
- ALOGE("%s: DQBUF fails: %s", __FUNCTION__, strerror(errno));
- return ret;
- }
- ATRACE_END();
+ do {
+ ATRACE_BEGIN("VIDIOC_DQBUF");
+ buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ buffer.memory = V4L2_MEMORY_MMAP;
+ if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_DQBUF, &buffer)) < 0) {
+ ALOGE("%s: DQBUF fails: %s", __FUNCTION__, strerror(errno));
+ return ret;
+ }
+ ATRACE_END();
- if (buffer.index >= mV4L2BufferCount) {
- ALOGE("%s: Invalid buffer id: %d", __FUNCTION__, buffer.index);
- return ret;
- }
+ if (buffer.index >= mV4L2BufferCount) {
+ ALOGE("%s: Invalid buffer id: %d", __FUNCTION__, buffer.index);
+ return ret;
+ }
- if (buffer.flags & V4L2_BUF_FLAG_ERROR) {
- ALOGE("%s: v4l2 buf error! buf flag 0x%x", __FUNCTION__, buffer.flags);
- // TODO: try to dequeue again
- }
+ if (buffer.flags & V4L2_BUF_FLAG_ERROR) {
+ ALOGE("%s: v4l2 buf error! buf flag 0x%x", __FUNCTION__, buffer.flags);
+ // TODO: try to dequeue again
+ }
- if (buffer.bytesused > mMaxV4L2BufferSize) {
- ALOGE("%s: v4l2 buffer bytes used: %u maximum %u", __FUNCTION__, buffer.bytesused,
- mMaxV4L2BufferSize);
- return ret;
- }
+ if (buffer.bytesused > mMaxV4L2BufferSize) {
+ ALOGE("%s: v4l2 buffer bytes used: %u maximum %u", __FUNCTION__, buffer.bytesused,
+ mMaxV4L2BufferSize);
+ return ret;
+ }
- if (buffer.flags & V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC) {
- // Ideally we should also check for V4L2_BUF_FLAG_TSTAMP_SRC_SOE, but
- // even V4L2_BUF_FLAG_TSTAMP_SRC_EOF is better than capture a timestamp now
- *shutterTs = static_cast<nsecs_t>(buffer.timestamp.tv_sec) * 1000000000LL +
- buffer.timestamp.tv_usec * 1000LL;
- } else {
- *shutterTs = systemTime(SYSTEM_TIME_MONOTONIC);
- }
+ nsecs_t curTimeNs = systemTime(SYSTEM_TIME_MONOTONIC);
+
+ if (buffer.flags & V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC) {
+ // Ideally we should also check for V4L2_BUF_FLAG_TSTAMP_SRC_SOE, but
+ // even V4L2_BUF_FLAG_TSTAMP_SRC_EOF is better than capture a timestamp now
+ *shutterTs = static_cast<nsecs_t>(buffer.timestamp.tv_sec) * 1000000000LL +
+ buffer.timestamp.tv_usec * 1000LL;
+ } else {
+ *shutterTs = curTimeNs;
+ }
+
+ // The tactic only takes effect on v4l2 buffers with flag V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC.
+ // Most USB cameras should have the feature.
+ if (curTimeNs < *shutterTs) {
+ lagNs = 0;
+ ALOGW("%s: should not happen, the monotonic clock has issue, shutterTs is in the "
+ "future, curTimeNs %" PRId64 " < "
+ "shutterTs %" PRId64 "",
+ __func__, curTimeNs, *shutterTs);
+ } else {
+ lagNs = curTimeNs - *shutterTs;
+ }
+
+ if (lagNs > mMaxLagNs) {
+ ALOGI("%s: drop too old buffer, index %d, lag %" PRIu64 " ns > max %" PRIu64 " ns", __FUNCTION__,
+ buffer.index, lagNs, mMaxLagNs);
+ int retVal = ioctl(mV4l2Fd.get(), VIDIOC_QBUF, &buffer);
+ if (retVal) {
+ ALOGE("%s: unexpected VIDIOC_QBUF failed, retVal %d", __FUNCTION__, retVal);
+ return ret;
+ }
+ }
+ } while (lagNs > mMaxLagNs);
{
std::lock_guard<std::mutex> lk(mV4l2BufferLock);
diff --git a/camera/device/default/ExternalCameraDeviceSession.h b/camera/device/default/ExternalCameraDeviceSession.h
index 795b589..1c6ed06 100644
--- a/camera/device/default/ExternalCameraDeviceSession.h
+++ b/camera/device/default/ExternalCameraDeviceSession.h
@@ -382,6 +382,9 @@
std::string mExifMake;
std::string mExifModel;
/* End of members not changed after initialize() */
+
+ // The max tolerant lag between the dequeued v4l2 buffer and current capture request.
+ uint64_t mMaxLagNs;
};
} // namespace implementation
diff --git a/cas/1.2/default/Android.bp b/cas/1.2/default/Android.bp
index 38561fd..5bc8bad 100644
--- a/cas/1.2/default/Android.bp
+++ b/cas/1.2/default/Android.bp
@@ -46,6 +46,7 @@
vintf_fragments: ["android.hardware.cas@1.2-service.xml"],
defaults: ["cas_service_defaults@1.2"],
init_rc: ["android.hardware.cas@1.2-service.rc"],
+ overrides: ["com.android.hardware.cas"],
}
cc_binary {
diff --git a/common/fmq/aidl/Android.bp b/common/fmq/aidl/Android.bp
index 9c1b45d..4a3658e 100644
--- a/common/fmq/aidl/Android.bp
+++ b/common/fmq/aidl/Android.bp
@@ -35,8 +35,7 @@
ndk: {
apex_available: [
"//apex_available:platform",
- "com.android.btservices",
- "com.android.media.swcodec",
+ "//apex_available:anyapex",
],
min_sdk_version: "29",
},
diff --git a/compatibility_matrices/Android.bp b/compatibility_matrices/Android.bp
index ad42015..6a3fa32 100644
--- a/compatibility_matrices/Android.bp
+++ b/compatibility_matrices/Android.bp
@@ -93,6 +93,14 @@
}
+// Device framework compatibility matrix (common to all FCM versions)
+// Reference: https://source.android.com/docs/core/architecture/vintf/comp-matrices
+vintf_compatibility_matrix {
+ name: "framework_compatibility_matrix.device.xml",
+ stem: "compatibility_matrix.device.xml",
+ type: "device_fcm",
+}
+
// Phony target that installs all system compatibility matrix files
SYSTEM_MATRIX_DEPS = [
"framework_compatibility_matrix.5.xml",
@@ -114,3 +122,26 @@
},
},
}
+
+// Product Compatibility Matrix
+vintf_compatibility_matrix {
+ name: "product_compatibility_matrix.xml",
+ stem: "compatibility_matrix.xml",
+ product_specific: true,
+ type: "product_fcm",
+}
+
+// Phony target that installs all framework compatibility matrix files (system + product)
+FRAMEWORK_MATRIX_DEPS = SYSTEM_MATRIX_DEPS + ["product_compatibility_matrix.xml"]
+
+phony {
+ name: "framework_compatibility_matrix.xml",
+ required: FRAMEWORK_MATRIX_DEPS,
+ product_variables: {
+ release_aidl_use_unfrozen: {
+ required: [
+ "framework_compatibility_matrix.202504.xml",
+ ],
+ },
+ },
+}
diff --git a/compatibility_matrices/Android.mk b/compatibility_matrices/Android.mk
deleted file mode 100644
index 338c075..0000000
--- a/compatibility_matrices/Android.mk
+++ /dev/null
@@ -1,134 +0,0 @@
-#
-# Copyright (C) 2017 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.
-#
-
-LOCAL_PATH := $(call my-dir)
-
-BUILD_FRAMEWORK_COMPATIBILITY_MATRIX := $(LOCAL_PATH)/compatibility_matrix.mk
-my_empty_manifest := $(LOCAL_PATH)/manifest.empty.xml
-
-# System Compatibility Matrix (common to all FCM versions)
-
-include $(CLEAR_VARS)
-include $(LOCAL_PATH)/clear_vars.mk
-LOCAL_MODULE := framework_compatibility_matrix.device.xml
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../NOTICE
-LOCAL_MODULE_STEM := compatibility_matrix.device.xml
-# define LOCAL_MODULE_CLASS for local-generated-sources-dir.
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_RELATIVE_PATH := vintf
-
-ifndef DEVICE_FRAMEWORK_COMPATIBILITY_MATRIX_FILE
-LOCAL_SRC_FILES := compatibility_matrix.empty.xml
-else
-
-# DEVICE_FRAMEWORK_COMPATIBILITY_MATRIX_FILE specifies absolute paths
-LOCAL_GENERATED_SOURCES := $(DEVICE_FRAMEWORK_COMPATIBILITY_MATRIX_FILE)
-
-# Enforce that DEVICE_FRAMEWORK_COMPATIBILITY_MATRIX_FILE does not specify required HALs
-# by checking it against an empty manifest. But the empty manifest needs to contain
-# BOARD_SEPOLICY_VERS to be compatible with DEVICE_FRAMEWORK_COMPATIBILITY_MATRIX_FILE.
-my_gen_check_manifest := $(local-generated-sources-dir)/manifest.check.xml
-$(my_gen_check_manifest): PRIVATE_SRC_FILE := $(my_empty_manifest)
-$(my_gen_check_manifest): $(my_empty_manifest) $(HOST_OUT_EXECUTABLES)/assemble_vintf
- BOARD_SEPOLICY_VERS=$(BOARD_SEPOLICY_VERS) \
- VINTF_IGNORE_TARGET_FCM_VERSION=true \
- $(HOST_OUT_EXECUTABLES)/assemble_vintf -i $(PRIVATE_SRC_FILE) -o $@
-
-LOCAL_GEN_FILE_DEPENDENCIES += $(my_gen_check_manifest)
-LOCAL_ASSEMBLE_VINTF_FLAGS += -c "$(my_gen_check_manifest)"
-
-my_gen_check_manifest :=
-
-endif # DEVICE_FRAMEWORK_COMPATIBILITY_MATRIX_FILE
-
-# TODO(b/296875906): use POLICYVERS from Soong
-POLICYVERS ?= 30
-
-LOCAL_ADD_VBMETA_VERSION := true
-LOCAL_ASSEMBLE_VINTF_ENV_VARS := \
- POLICYVERS \
- PLATFORM_SEPOLICY_VERSION \
- PLATFORM_SEPOLICY_COMPAT_VERSIONS
-
-include $(BUILD_FRAMEWORK_COMPATIBILITY_MATRIX)
-
-# Product Compatibility Matrix
-
-include $(CLEAR_VARS)
-include $(LOCAL_PATH)/clear_vars.mk
-LOCAL_MODULE := product_compatibility_matrix.xml
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../NOTICE
-
-ifndef DEVICE_PRODUCT_COMPATIBILITY_MATRIX_FILE
-my_framework_matrix_deps :=
-include $(BUILD_PHONY_PACKAGE)
-else # DEVICE_PRODUCT_COMPATIBILITY_MATRIX_FILE
-
-LOCAL_MODULE_STEM := compatibility_matrix.xml
-LOCAL_PRODUCT_MODULE := true
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_RELATIVE_PATH := vintf
-
-# DEVICE_PRODUCT_COMPATIBILITY_MATRIX_FILE specifies absolute paths
-LOCAL_GENERATED_SOURCES := $(DEVICE_PRODUCT_COMPATIBILITY_MATRIX_FILE)
-
-# Enforce that DEVICE_PRODUCT_COMPATIBILITY_MATRIX_FILE does not specify required HALs
-# by checking it against an empty manifest.
-LOCAL_GEN_FILE_DEPENDENCIES += $(my_empty_manifest)
-LOCAL_ASSEMBLE_VINTF_FLAGS += -c "$(my_empty_manifest)"
-
-my_framework_matrix_deps := $(LOCAL_MODULE)
-
-include $(BUILD_FRAMEWORK_COMPATIBILITY_MATRIX)
-
-endif # DEVICE_PRODUCT_COMPATIBILITY_MATRIX_FILE
-
-my_system_matrix_deps := \
- framework_compatibility_matrix.5.xml \
- framework_compatibility_matrix.6.xml \
- framework_compatibility_matrix.7.xml \
- framework_compatibility_matrix.8.xml \
- framework_compatibility_matrix.202404.xml \
- framework_compatibility_matrix.device.xml \
-
-# Only allow the use of the unreleased compatibility matrix when we can use unfrozen
-# interfaces (in the `next` release configuration).
-ifeq ($(RELEASE_AIDL_USE_UNFROZEN),true)
-my_system_matrix_deps += \
- framework_compatibility_matrix.202504.xml \
-
-endif
-
-my_framework_matrix_deps += \
- $(my_system_matrix_deps)
-
-# Phony target that installs all framework compatibility matrix files (system + product)
-include $(CLEAR_VARS)
-LOCAL_MODULE := framework_compatibility_matrix.xml
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../NOTICE
-LOCAL_REQUIRED_MODULES := $(my_framework_matrix_deps)
-include $(BUILD_PHONY_PACKAGE)
-
-my_system_matrix_deps :=
-my_framework_matrix_deps :=
-my_empty_manifest :=
-BUILD_FRAMEWORK_COMPATIBILITY_MATRIX :=
diff --git a/compatibility_matrices/build/Android.bp b/compatibility_matrices/build/Android.bp
index 79ef36d..6011fcc 100644
--- a/compatibility_matrices/build/Android.bp
+++ b/compatibility_matrices/build/Android.bp
@@ -30,6 +30,7 @@
"kernel-config-soong-rules",
"soong",
"soong-android",
+ "soong-selinux",
],
srcs: [
"vintf_compatibility_matrix.go",
diff --git a/compatibility_matrices/build/vintf_compatibility_matrix.go b/compatibility_matrices/build/vintf_compatibility_matrix.go
index c72cbde..b8f2a14 100644
--- a/compatibility_matrices/build/vintf_compatibility_matrix.go
+++ b/compatibility_matrices/build/vintf_compatibility_matrix.go
@@ -24,6 +24,7 @@
"android/soong/android"
"android/soong/kernel/configs"
+ "android/soong/selinux"
)
type dependencyTag struct {
@@ -35,10 +36,10 @@
pctx = android.NewPackageContext("android/vintf")
assembleVintfRule = pctx.AndroidStaticRule("assemble_vintf", blueprint.RuleParams{
- Command: `${assembleVintfCmd} -i ${inputs} -o ${out}`,
- CommandDeps: []string{"${assembleVintfCmd}"},
+ Command: `${assembleVintfEnv} ${assembleVintfCmd} -i ${inputs} -o ${out} ${extraArgs}`,
+ CommandDeps: []string{"${assembleVintfCmd}", "${AvbToolCmd}"},
Description: "assemble_vintf -i ${inputs}",
- }, "inputs")
+ }, "inputs", "extraArgs", "assembleVintfEnv")
xmllintXsd = pctx.AndroidStaticRule("xmllint-xsd", blueprint.RuleParams{
Command: `$XmlLintCmd --quiet --schema $xsd $in > /dev/null && touch -a $out`,
@@ -52,7 +53,11 @@
)
const (
- relpath = "vintf"
+ relpath = "vintf"
+ emptyManifest = "hardware/interfaces/compatibility_matrices/manifest.empty.xml"
+ compatibilityEmptyMatrix = "hardware/interfaces/compatibility_matrices/compatibility_matrix.empty.xml"
+ deviceFcmType = "device_fcm"
+ productFcmType = "product_fcm"
)
type vintfCompatibilityMatrixProperties struct {
@@ -64,6 +69,9 @@
// list of kernel_config modules to be combined to final output
Kernel_configs []string
+
+ // Type of the FCM type, the allowed type are device_fcm and product_fcm and it should only be used under hardware/interfaces/compatibility_matrices
+ Type *string
}
type vintfCompatibilityMatrixRule struct {
@@ -72,11 +80,13 @@
genFile android.WritablePath
additionalDependencies android.WritablePaths
+ phonyOnly bool
}
func init() {
pctx.HostBinToolVariable("assembleVintfCmd", "assemble_vintf")
pctx.HostBinToolVariable("XmlLintCmd", "xmllint")
+ pctx.HostBinToolVariable("AvbToolCmd", "avbtool")
android.RegisterModuleType("vintf_compatibility_matrix", vintfCompatibilityMatrixFactory)
}
@@ -131,6 +141,20 @@
}
func (g *vintfCompatibilityMatrixRule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ // Types attribute only allow `device_fcm` or `product_fcm` if set and only restricted it being used under
+ // `hardware/interfaces/compatibility_matrices` to prevent accidental external usages.
+ matrixType := proptools.String(g.properties.Type)
+ if matrixType != "" {
+ if matrixType != deviceFcmType && matrixType != productFcmType {
+ panic(fmt.Errorf("The attribute 'type' value must be either 'device_fcm' or 'product_fcm' if set!"))
+ }
+ if !strings.HasPrefix(android.PathForModuleSrc(ctx).String(), "hardware/interfaces/compatibility_matrices") {
+ panic(fmt.Errorf("Attribute type can only be set for module under `hardware/interfaces/compatibility_matrices`!"))
+ }
+ if (len(g.properties.Srcs) + len(g.properties.Kernel_configs)) > 0 {
+ panic(fmt.Errorf("Attribute 'type' and 'srcs' or 'kernel_configs' should not set simultaneously! To update inputs for this rule, edit vintf_compatibility_matrix.go directly."))
+ }
+ }
outputFilename := proptools.String(g.properties.Stem)
if outputFilename == "" {
@@ -158,15 +182,72 @@
}
})
+ // For product_compatibility_matrix.xml the source is from the product configuration
+ // DEVICE_PRODUCT_COMPATIBILITY_MATRIX_FILE.
+ extraArgs := []string{}
+ if matrixType == productFcmType {
+ productMatrixs := android.PathsForSource(ctx, ctx.Config().DeviceProductCompatibilityMatrixFile())
+ if len(productMatrixs) > 0 {
+ inputPaths = append(inputPaths, productMatrixs...)
+ extraArgs = append(extraArgs, "-c", android.PathForSource(ctx, emptyManifest).String())
+ } else {
+ // For product_fcm, if DEVICE_PRODUCT_COMPATIBILITY_MATRIX_FILE not set, treat it as a phony target without any output generated.
+ g.phonyOnly = true
+ return
+ }
+ }
+
+ // For framework_compatibility_matrix.device.xml the source may come from the product configuration
+ // DEVICE_FRAMEWORK_COMPATIBILITY_MATRIX_FILE or use compatibilityEmptyMatrix if not set. We can't
+ // use a phony target because we still need to install framework_compatibility_matrix.device.xml to
+ // include sepolicy versions.
+ frameworkRuleImplicits := []android.Path{}
+
+ if matrixType == deviceFcmType {
+ frameworkMatrixs := android.PathsForSource(ctx, ctx.Config().DeviceFrameworkCompatibilityMatrixFile())
+ if len(frameworkMatrixs) > 0 {
+ inputPaths = append(inputPaths, frameworkMatrixs...)
+
+ // Generate BuildAction for generating the check manifest.
+ emptyManifestPath := android.PathForSource(ctx, emptyManifest)
+ genCheckManifest := android.PathForModuleGen(ctx, "manifest.check.xml")
+ checkManifestInputs := []android.Path{emptyManifestPath}
+ genCheckManifestEnvs := []string{
+ "BOARD_SEPOLICY_VERS=" + ctx.DeviceConfig().BoardSepolicyVers(),
+ "VINTF_IGNORE_TARGET_FCM_VERSION=true",
+ }
+
+ ctx.Build(pctx, android.BuildParams{
+ Rule: assembleVintfRule,
+ Description: "Framework Check Manifest",
+ Implicits: checkManifestInputs,
+ Output: genCheckManifest,
+ Args: map[string]string{
+ "inputs": android.PathForSource(ctx, emptyManifest).String(),
+ "extraArgs": "",
+ "assembleVintfEnv": strings.Join(genCheckManifestEnvs, " "),
+ },
+ })
+
+ frameworkRuleImplicits = append(frameworkRuleImplicits, genCheckManifest)
+ extraArgs = append(extraArgs, "-c", genCheckManifest.String())
+ } else {
+ inputPaths = append(inputPaths, android.PathForSource(ctx, compatibilityEmptyMatrix))
+ }
+ }
+
g.genFile = android.PathForModuleGen(ctx, outputFilename)
+ frameworkRuleImplicits = append(frameworkRuleImplicits, inputPaths...)
ctx.Build(pctx, android.BuildParams{
Rule: assembleVintfRule,
Description: "Framework Compatibility Matrix",
- Implicits: inputPaths,
+ Implicits: frameworkRuleImplicits,
Output: g.genFile,
Args: map[string]string{
- "inputs": strings.Join(inputPaths.Strings(), ":"),
+ "inputs": strings.Join(inputPaths.Strings(), ":"),
+ "extraArgs": strings.Join(extraArgs, " "),
+ "assembleVintfEnv": g.getAssembleVintfEnv(ctx),
},
})
g.generateValidateBuildAction(ctx, g.genFile, schema.Path())
@@ -174,7 +255,39 @@
ctx.InstallFile(android.PathForModuleInstall(ctx, "etc", relpath), outputFilename, g.genFile)
}
+func (g *vintfCompatibilityMatrixRule) getAssembleVintfEnv(ctx android.ModuleContext) string {
+ if proptools.String(g.properties.Type) == deviceFcmType {
+ assembleVintfEnvs := []string{
+ // POLICYVERS defined in system/sepolicy/build/soong/policy.go
+ fmt.Sprintf("POLICYVERS=%d", selinux.PolicyVers),
+ fmt.Sprintf("PLATFORM_SEPOLICY_VERSION=%s", ctx.DeviceConfig().PlatformSepolicyVersion()),
+ fmt.Sprintf("PLATFORM_SEPOLICY_COMPAT_VERSIONS=\"%s\"", strings.Join(ctx.DeviceConfig().PlatformSepolicyCompatVersions(), " ")),
+ }
+
+ if ctx.Config().BoardAvbEnable() {
+ assembleVintfEnvs = append(assembleVintfEnvs, fmt.Sprintf("FRAMEWORK_VBMETA_VERSION=\"$$(${AvbToolCmd} add_hashtree_footer --print_required_libavb_version %s)\"", strings.Join(ctx.Config().BoardAvbSystemAddHashtreeFooterArgs(), " ")))
+ } else {
+ assembleVintfEnvs = append(assembleVintfEnvs, "FRAMEWORK_VBMETA_VERSION=\"0.0\"")
+ }
+
+ return strings.Join(assembleVintfEnvs, " ")
+ }
+
+ return ""
+}
+
func (g *vintfCompatibilityMatrixRule) AndroidMk() android.AndroidMkData {
+ if g.phonyOnly {
+ return android.AndroidMkData{
+ Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
+ fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)", " # vintf.vintf_compatibility_matrix")
+ fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
+ fmt.Fprintln(w, "LOCAL_MODULE :=", name)
+ fmt.Fprintln(w, "include $(BUILD_PHONY_PACKAGE)")
+ },
+ }
+ }
+
return android.AndroidMkData{
Class: "ETC",
OutputFile: android.OptionalPathForPath(g.genFile),
diff --git a/compatibility_matrices/bump.py b/compatibility_matrices/bump.py
index a5a453b..ee2fa88 100755
--- a/compatibility_matrices/bump.py
+++ b/compatibility_matrices/bump.py
@@ -21,7 +21,7 @@
import argparse
import os
import pathlib
-import shutil
+import re
import subprocess
import textwrap
@@ -44,6 +44,7 @@
self.current_level = cmdline_args.current_level
self.current_letter = cmdline_args.current_letter
+ self.current_version = cmdline_args.platform_version
self.current_module_name = f"framework_compatibility_matrix.{self.current_level}.xml"
self.current_xml = self.interfaces_dir / f"compatibility_matrices/compatibility_matrix.{self.current_level}.xml"
self.device_module_name = "framework_compatibility_matrix.device.xml"
@@ -57,13 +58,13 @@
self.bump_kernel_configs()
self.copy_matrix()
self.edit_android_bp()
- self.edit_android_mk()
+ self.bump_libvintf()
def bump_kernel_configs(self):
check_call([
self.top / "kernel/configs/tools/bump.py",
- self.current_letter,
- self.next_letter,
+ self.current_letter.lower(),
+ self.next_letter.lower(),
])
def copy_matrix(self):
@@ -87,7 +88,7 @@
next_kernel_configs = check_output(
"""grep -rh name: | sed -E 's/^.*"(.*)".*/\\1/g'""",
cwd=self.top / "kernel/configs" /
- self.next_letter,
+ self.next_letter.lower(),
text=True,
shell=True,
).splitlines()
@@ -109,40 +110,85 @@
"kernel_configs", "-a", " ".join(next_kernel_configs), android_bp
])
- def edit_android_mk(self):
- android_mk = self.interfaces_dir / "compatibility_matrices/Android.mk"
+ # update the SYSTEM_MATRIX_DEPS variable and the phony module's
+ # product_variables entry.
lines = []
- with open(android_mk) as f:
- if self.next_module_name in f.read():
- return
- f.seek(0)
+ with open(android_bp) as f:
for line in f:
- if f" {self.device_module_name} \\\n" in line:
- lines.append(f" {self.current_module_name} \\\n")
+ if f" \"{self.device_module_name}\",\n" in line:
+ lines.append(f" \"{self.current_module_name}\",\n")
- if self.current_module_name in line:
- lines.append(f" {self.next_module_name} \\\n")
+ if f" \"{self.current_module_name}\",\n" in line:
+ lines.append(f" \"{self.next_module_name}\",\n")
else:
lines.append(line)
- with open(android_mk, "w") as f:
+ with open(android_bp, "w") as f:
f.write("".join(lines))
+ def bump_libvintf(self):
+ if not self.current_version:
+ print("Skip libvintf update...")
+ return
+ try:
+ check_call(["grep", "-h",
+ f"{self.current_letter.upper()} = {self.current_level}",
+ "system/libvintf/include/vintf/Level.h"])
+ except subprocess.CalledProcessError:
+ print("Adding new API level to libvintf")
+ add_lines_above("system/libvintf/analyze_matrix/analyze_matrix.cpp",
+ " case Level::UNSPECIFIED:",
+ textwrap.indent(textwrap.dedent(f"""\
+ case Level::{self.current_letter.upper()}:
+ return "Android {self.current_version} ({self.current_letter.upper()})";"""),
+ " "*2))
+ add_lines_above("system/libvintf/include/vintf/Level.h",
+ " // To add new values:",
+ f" {self.current_letter.upper()} = {self.current_level},")
+ add_lines_above("system/libvintf/include/vintf/Level.h",
+ " Level::UNSPECIFIED,",
+ f" Level::{self.current_letter.upper()},")
+ add_lines_above("system/libvintf/RuntimeInfo.cpp",
+ " // Add more levels above this line.",
+ textwrap.indent(textwrap.dedent(f"""\
+ case {self.current_version}: {{
+ ret = Level::{self.current_letter.upper()};
+ }} break;"""),
+ " "*3))
+
+
+def add_lines_above(file, pattern, lines):
+ with open(file, 'r+') as f:
+ text = f.read()
+ split_text = re.split(rf"\n{pattern}\n", text)
+ if len(split_text) != 2:
+ # Only one pattern must be found, otherwise the source must be
+ # changed unexpectedly.
+ raise Exception(
+ f'Pattern "{pattern}" not found or multiple patterns found in {file}')
+ f.seek(0)
+ f.write(f"\n{lines}\n{pattern}\n".join(split_text))
+ f.truncate()
+
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("current_level",
type=str,
- help="VINTF level of the current version (e.g. 9)")
+ help="VINTF level of the current version (e.g. 202404)")
parser.add_argument("next_level",
type=str,
- help="VINTF level of the next version (e.g. 10)")
+ help="VINTF level of the next version (e.g. 202504)")
parser.add_argument("current_letter",
type=str,
help="Letter of the API level of the current version (e.g. v)")
parser.add_argument("next_letter",
type=str,
help="Letter of the API level of the next version (e.g. w)")
+ parser.add_argument("platform_version",
+ type=str,
+ nargs="?",
+ help="Android release version number number (e.g. 15)")
cmdline_args = parser.parse_args()
Bump(cmdline_args).run()
diff --git a/compatibility_matrices/clear_vars.mk b/compatibility_matrices/clear_vars.mk
index 0e53885..3c62377 100644
--- a/compatibility_matrices/clear_vars.mk
+++ b/compatibility_matrices/clear_vars.mk
@@ -16,10 +16,6 @@
# Clear input variables to BUILD_FRAMEWORK_COMPATIBILITY_MATRIX
LOCAL_ADD_VBMETA_VERSION :=
-LOCAL_ADD_VBMETA_VERSION_OVERRIDE :=
LOCAL_ASSEMBLE_VINTF_ENV_VARS :=
-LOCAL_ASSEMBLE_VINTF_ENV_VARS_OVERRIDE :=
-LOCAL_ASSEMBLE_VINTF_ERROR_MESSAGE :=
LOCAL_ASSEMBLE_VINTF_FLAGS :=
-LOCAL_KERNEL_CONFIG_DATA_PATHS :=
LOCAL_GEN_FILE_DEPENDENCIES :=
diff --git a/compatibility_matrices/compatibility_matrix.202404.xml b/compatibility_matrices/compatibility_matrix.202404.xml
index 9ea476a..aa6b8f0 100644
--- a/compatibility_matrices/compatibility_matrix.202404.xml
+++ b/compatibility_matrices/compatibility_matrix.202404.xml
@@ -28,7 +28,7 @@
</hal>
<hal format="aidl">
<name>android.hardware.audio.sounddose</name>
- <version>1-2</version>
+ <version>1-3</version>
<interface>
<name>ISoundDoseFactory</name>
<instance>default</instance>
diff --git a/compatibility_matrices/compatibility_matrix.202504.xml b/compatibility_matrices/compatibility_matrix.202504.xml
index ee62163..7e19852 100644
--- a/compatibility_matrices/compatibility_matrix.202504.xml
+++ b/compatibility_matrices/compatibility_matrix.202504.xml
@@ -26,14 +26,6 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl">
- <name>android.hardware.audio.sounddose</name>
- <version>1-3</version>
- <interface>
- <name>ISoundDoseFactory</name>
- <instance>default</instance>
- </interface>
- </hal>
<hal format="aidl" updatable-via-apex="true">
<name>android.hardware.authsecret</name>
<version>1</version>
@@ -372,6 +364,7 @@
</hal>
<hal format="aidl" updatable-via-apex="true">
<name>android.hardware.nfc</name>
+ <version>1-2</version>
<interface>
<name>INfc</name>
<instance>default</instance>
diff --git a/compatibility_matrices/compatibility_matrix.mk b/compatibility_matrices/compatibility_matrix.mk
deleted file mode 100644
index d22e510..0000000
--- a/compatibility_matrices/compatibility_matrix.mk
+++ /dev/null
@@ -1,128 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-##### Input Variables:
-# LOCAL_MODULE: required. Module name for the build system.
-# LOCAL_MODULE_CLASS: optional. Default is ETC.
-# LOCAL_MODULE_PATH / LOCAL_MODULE_RELATIVE_PATH: required. (Relative) path of output file.
-# If not defined, LOCAL_MODULE_RELATIVE_PATH will be "vintf".
-# LOCAL_MODULE_STEM: optional. Name of output file. Default is $(LOCAL_MODULE).
-# LOCAL_SRC_FILES: required. Local source files provided to assemble_vintf
-# (command line argument -i).
-# LOCAL_GENERATED_SOURCES: optional. Global source files provided to assemble_vintf
-# (command line argument -i).
-#
-# LOCAL_ADD_VBMETA_VERSION: Use AVBTOOL to add avb version to the output matrix
-# (corresponds to <avb><vbmeta-version> tag)
-# LOCAL_ASSEMBLE_VINTF_ENV_VARS: Add a list of environment variable names from global variables in
-# the build system that is lazily evaluated (e.g. PRODUCT_ENFORCE_VINTF_MANIFEST).
-# LOCAL_ASSEMBLE_VINTF_ENV_VARS_OVERRIDE: Add a list of environment variables that is local to
-# assemble_vintf invocation. Format is "VINTF_ENFORCE_NO_UNUSED_HALS=true".
-# LOCAL_ASSEMBLE_VINTF_FLAGS: Add additional command line arguments to assemble_vintf invocation.
-# LOCAL_KERNEL_CONFIG_DATA_PATHS: Paths to search for kernel config requirements. Format for each is
-# <kernel version x.y.z>:<path that contains android-base*.config>.
-# LOCAL_GEN_FILE_DEPENDENCIES: A list of additional dependencies for the generated file.
-
-ifndef LOCAL_MODULE
-$(error LOCAL_MODULE must be defined.)
-endif
-
-ifndef LOCAL_MODULE_STEM
-LOCAL_MODULE_STEM := $(LOCAL_MODULE)
-endif
-
-ifndef LOCAL_MODULE_CLASS
-LOCAL_MODULE_CLASS := ETC
-endif
-
-ifndef LOCAL_MODULE_PATH
-ifndef LOCAL_MODULE_RELATIVE_PATH
-$(error Either LOCAL_MODULE_PATH or LOCAL_MODULE_RELATIVE_PATH must be defined.)
-endif
-endif
-
-GEN := $(local-generated-sources-dir)/$(LOCAL_MODULE_STEM)
-
-$(GEN): PRIVATE_ENV_VARS := $(LOCAL_ASSEMBLE_VINTF_ENV_VARS)
-$(GEN): PRIVATE_FLAGS := $(LOCAL_ASSEMBLE_VINTF_FLAGS)
-
-$(GEN): $(LOCAL_GEN_FILE_DEPENDENCIES)
-
-ifeq (true,$(strip $(LOCAL_ADD_VBMETA_VERSION)))
-ifeq (true,$(BOARD_AVB_ENABLE))
-$(GEN): $(AVBTOOL)
-# INTERNAL_AVB_SYSTEM_SIGNING_ARGS consists of BOARD_AVB_SYSTEM_KEY_PATH and
-# BOARD_AVB_SYSTEM_ALGORITHM. We should add the dependency of key path, which
-# is a file, here.
-$(GEN): $(BOARD_AVB_SYSTEM_KEY_PATH)
-# Use deferred assignment (=) instead of immediate assignment (:=).
-# Otherwise, cannot get INTERNAL_AVB_SYSTEM_SIGNING_ARGS.
-$(GEN): FRAMEWORK_VBMETA_VERSION = $$("$(AVBTOOL)" add_hashtree_footer \
- --print_required_libavb_version \
- $(INTERNAL_AVB_SYSTEM_SIGNING_ARGS) \
- $(BOARD_AVB_SYSTEM_ADD_HASHTREE_FOOTER_ARGS))
-else
-$(GEN): FRAMEWORK_VBMETA_VERSION := 0.0
-endif # BOARD_AVB_ENABLE
-$(GEN): PRIVATE_ENV_VARS += FRAMEWORK_VBMETA_VERSION
-endif # LOCAL_ADD_VBMETA_VERSION
-
-ifeq (true,$(strip $(LOCAL_ADD_VBMETA_VERSION_OVERRIDE)))
-ifneq ($(BOARD_OTA_FRAMEWORK_VBMETA_VERSION_OVERRIDE),)
-$(GEN): FRAMEWORK_VBMETA_VERSION_OVERRIDE := $(BOARD_OTA_FRAMEWORK_VBMETA_VERSION_OVERRIDE)
-$(GEN): PRIVATE_ENV_VARS += FRAMEWORK_VBMETA_VERSION_OVERRIDE
-endif
-endif
-
-ifneq (,$(strip $(LOCAL_KERNEL_CONFIG_DATA_PATHS)))
-$(GEN): PRIVATE_KERNEL_CONFIG_DATA_PATHS := $(LOCAL_KERNEL_CONFIG_DATA_PATHS)
-$(GEN): $(foreach pair,$(LOCAL_KERNEL_CONFIG_DATA_PATHS),\
- $(wildcard $(call word-colon,2,$(pair))/android-base*.config))
-$(GEN): PRIVATE_FLAGS += $(foreach pair,$(PRIVATE_KERNEL_CONFIG_DATA_PATHS),\
- --kernel=$(call word-colon,1,$(pair)):$(call normalize-path-list,\
- $(wildcard $(call word-colon,2,$(pair))/android-base*.config)))
-endif
-
-my_matrix_src_files := \
- $(addprefix $(LOCAL_PATH)/,$(LOCAL_SRC_FILES)) \
- $(LOCAL_GENERATED_SOURCES)
-
-$(GEN): PRIVATE_ADDITIONAL_ENV_VARS := $(LOCAL_ASSEMBLE_VINTF_ENV_VARS_OVERRIDE)
-
-ifneq (,$(strip $(LOCAL_ASSEMBLE_VINTF_ERROR_MESSAGE)))
-$(GEN): PRIVATE_COMMAND_TAIL := || (echo $(strip $(LOCAL_ASSEMBLE_VINTF_ERROR_MESSAGE)) && false)
-endif
-
-$(GEN): PRIVATE_SRC_FILES := $(my_matrix_src_files)
-$(GEN): $(my_matrix_src_files) $(HOST_OUT_EXECUTABLES)/assemble_vintf
- $(foreach varname,$(PRIVATE_ENV_VARS),\
- $(if $(findstring $(varname),$(PRIVATE_ADDITIONAL_ENV_VARS)),\
- $(error $(varname) should not be overridden by LOCAL_ASSEMBLE_VINTF_ENV_VARS_OVERRIDE.)))
- $(foreach varname,$(PRIVATE_ENV_VARS),$(varname)="$($(varname))") \
- $(PRIVATE_ADDITIONAL_ENV_VARS) \
- $(HOST_OUT_EXECUTABLES)/assemble_vintf \
- -i $(call normalize-path-list,$(PRIVATE_SRC_FILES)) \
- -o $@ \
- $(PRIVATE_FLAGS) $(PRIVATE_COMMAND_TAIL)
-
-LOCAL_PREBUILT_MODULE_FILE := $(GEN)
-LOCAL_SRC_FILES :=
-LOCAL_GENERATED_SOURCES :=
-
-include $(LOCAL_PATH)/clear_vars.mk
-my_matrix_src_files :=
-
-include $(BUILD_PREBUILT)
diff --git a/compatibility_matrices/exclude/fcm_exclude.cpp b/compatibility_matrices/exclude/fcm_exclude.cpp
index fca9e1c..b86f399 100644
--- a/compatibility_matrices/exclude/fcm_exclude.cpp
+++ b/compatibility_matrices/exclude/fcm_exclude.cpp
@@ -167,6 +167,7 @@
"android.hardware.audio.core.sounddose@3",
// Deprecated HALs.
+ "android.hardware.audio.sounddose@3",
"android.hardware.bluetooth.audio@1",
};
diff --git a/drm/aidl/Android.bp b/drm/aidl/Android.bp
index afcb603..c42e723 100644
--- a/drm/aidl/Android.bp
+++ b/drm/aidl/Android.bp
@@ -12,6 +12,7 @@
vendor_available: true,
srcs: ["android/hardware/drm/*.aidl"],
stability: "vintf",
+ frozen: true,
imports: [
"android.hardware.common-V2",
],
diff --git a/drm/aidl/aidl_api/android.hardware.drm/1/.hash b/drm/aidl/aidl_api/android.hardware.drm/1/.hash
index 0f8b839..886e28c 100644
--- a/drm/aidl/aidl_api/android.hardware.drm/1/.hash
+++ b/drm/aidl/aidl_api/android.hardware.drm/1/.hash
@@ -1,2 +1 @@
-3a0197fb44863256da9034c26e721b1eee12d1be
7b4b0a0f36a7a6bb22d2016375e4a9d4a033592f
diff --git a/dumpstate/aidl/Android.bp b/dumpstate/aidl/Android.bp
index 1eb8b32..45c992a 100644
--- a/dumpstate/aidl/Android.bp
+++ b/dumpstate/aidl/Android.bp
@@ -26,6 +26,7 @@
vendor_available: true,
srcs: ["android/hardware/dumpstate/*.aidl"],
stability: "vintf",
+ frozen: true,
backend: {
cpp: {
enabled: false,
diff --git a/graphics/composer/2.1/utils/command-buffer/include/composer-command-buffer/2.1/ComposerCommandBuffer.h b/graphics/composer/2.1/utils/command-buffer/include/composer-command-buffer/2.1/ComposerCommandBuffer.h
index 6a45987..9ce6eed 100644
--- a/graphics/composer/2.1/utils/command-buffer/include/composer-command-buffer/2.1/ComposerCommandBuffer.h
+++ b/graphics/composer/2.1/utils/command-buffer/include/composer-command-buffer/2.1/ComposerCommandBuffer.h
@@ -21,8 +21,7 @@
#warn "ComposerCommandBuffer.h included without LOG_TAG"
#endif
-#undef LOG_NDEBUG
-#define LOG_NDEBUG 0
+//#define LOG_NDEBUG 0
#include <algorithm>
#include <limits>
diff --git a/graphics/composer/2.2/default/Android.bp b/graphics/composer/2.2/default/Android.bp
new file mode 100644
index 0000000..5753bb0
--- /dev/null
+++ b/graphics/composer/2.2/default/Android.bp
@@ -0,0 +1,51 @@
+// Copyright (C) 2024 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+ // See: http://go/android-license-faq
+ default_applicable_licenses: [
+ "hardware_interfaces_license",
+ ],
+}
+
+cc_binary {
+ name: "android.hardware.graphics.composer@2.2-service",
+ vendor: true,
+ relative_install_path: "hw",
+ cflags: [
+ "-Wall",
+ "-Werror",
+ "-DLOG_TAG=\"ComposerHal\"",
+ ],
+ srcs: ["service.cpp"],
+ init_rc: ["android.hardware.graphics.composer@2.2-service.rc"],
+ header_libs: ["android.hardware.graphics.composer@2.2-passthrough"],
+ shared_libs: [
+ "android.hardware.graphics.composer@2.1",
+ "android.hardware.graphics.composer@2.2",
+ "android.hardware.graphics.composer@2.1-resources",
+ "android.hardware.graphics.composer@2.2-resources",
+ "libbase",
+ "libbinder",
+ "libcutils",
+ "libfmq",
+ "libhardware",
+ "libhidlbase",
+ "libhwc2on1adapter",
+ "libhwc2onfbadapter",
+ "liblog",
+ "libsync",
+ "libutils",
+ ],
+}
diff --git a/graphics/composer/2.2/default/Android.mk b/graphics/composer/2.2/default/Android.mk
deleted file mode 100644
index 6f7ef85..0000000
--- a/graphics/composer/2.2/default/Android.mk
+++ /dev/null
@@ -1,35 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.graphics.composer@2.2-service
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../../../NOTICE
-LOCAL_VENDOR_MODULE := true
-LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_CFLAGS := -Wall -Werror -DLOG_TAG=\"ComposerHal\"
-LOCAL_SRC_FILES := service.cpp
-LOCAL_INIT_RC := android.hardware.graphics.composer@2.2-service.rc
-LOCAL_HEADER_LIBRARIES := android.hardware.graphics.composer@2.2-passthrough
-LOCAL_SHARED_LIBRARIES := \
- android.hardware.graphics.composer@2.1 \
- android.hardware.graphics.composer@2.2 \
- android.hardware.graphics.composer@2.1-resources \
- android.hardware.graphics.composer@2.2-resources \
- libbase \
- libbinder \
- libcutils \
- libfmq \
- libhardware \
- libhidlbase \
- libhwc2on1adapter \
- libhwc2onfbadapter \
- liblog \
- libsync \
- libutils
-
-ifdef TARGET_USES_DISPLAY_RENDER_INTENTS
-LOCAL_CFLAGS += -DUSES_DISPLAY_RENDER_INTENTS
-endif
-
-include $(BUILD_EXECUTABLE)
diff --git a/graphics/composer/2.2/utils/command-buffer/include/composer-command-buffer/2.2/ComposerCommandBuffer.h b/graphics/composer/2.2/utils/command-buffer/include/composer-command-buffer/2.2/ComposerCommandBuffer.h
index 00f427a..cd47374 100644
--- a/graphics/composer/2.2/utils/command-buffer/include/composer-command-buffer/2.2/ComposerCommandBuffer.h
+++ b/graphics/composer/2.2/utils/command-buffer/include/composer-command-buffer/2.2/ComposerCommandBuffer.h
@@ -20,8 +20,7 @@
#warn "ComposerCommandBuffer.h included without LOG_TAG"
#endif
-#undef LOG_NDEBUG
-#define LOG_NDEBUG 0
+//#define LOG_NDEBUG 0
#include <algorithm>
#include <limits>
diff --git a/graphics/composer/2.3/utils/command-buffer/include/composer-command-buffer/2.3/ComposerCommandBuffer.h b/graphics/composer/2.3/utils/command-buffer/include/composer-command-buffer/2.3/ComposerCommandBuffer.h
index 5e9a287..1a9276c 100644
--- a/graphics/composer/2.3/utils/command-buffer/include/composer-command-buffer/2.3/ComposerCommandBuffer.h
+++ b/graphics/composer/2.3/utils/command-buffer/include/composer-command-buffer/2.3/ComposerCommandBuffer.h
@@ -20,8 +20,7 @@
#warn "ComposerCommandBuffer.h included without LOG_TAG"
#endif
-#undef LOG_NDEBUG
-#define LOG_NDEBUG 0
+//#define LOG_NDEBUG 0
#include <android/hardware/graphics/composer/2.3/IComposer.h>
#include <android/hardware/graphics/composer/2.3/IComposerClient.h>
diff --git a/graphics/composer/2.4/utils/command-buffer/include/composer-command-buffer/2.4/ComposerCommandBuffer.h b/graphics/composer/2.4/utils/command-buffer/include/composer-command-buffer/2.4/ComposerCommandBuffer.h
index eb35e5c..e981da6 100644
--- a/graphics/composer/2.4/utils/command-buffer/include/composer-command-buffer/2.4/ComposerCommandBuffer.h
+++ b/graphics/composer/2.4/utils/command-buffer/include/composer-command-buffer/2.4/ComposerCommandBuffer.h
@@ -20,8 +20,7 @@
#warn "ComposerCommandBuffer.h included without LOG_TAG"
#endif
-#undef LOG_NDEBUG
-#define LOG_NDEBUG 0
+//#define LOG_NDEBUG 0
#include <android/hardware/graphics/composer/2.4/IComposer.h>
#include <android/hardware/graphics/composer/2.4/IComposerClient.h>
diff --git a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
index ba15421..eaf23b5 100644
--- a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
+++ b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
@@ -1845,7 +1845,7 @@
writer.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 0.5f, -1.f);
execute();
const auto errors = mReader.takeErrors();
- EXPECT_EQ(1, errors.size());
+ ASSERT_EQ(1, errors.size());
EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, errors[0].errorCode);
GTEST_SUCCEED() << "SetDisplayBrightness is not supported";
return;
diff --git a/health/2.1/default/Android.bp b/health/2.1/default/Android.bp
index b7bcea5..00d89e2 100644
--- a/health/2.1/default/Android.bp
+++ b/health/2.1/default/Android.bp
@@ -81,7 +81,7 @@
],
vintf_fragments: [
- "android.hardware.health@2.1.xml"
+ "android.hardware.health@2.1.xml",
],
overrides: [
diff --git a/health/aidl/default/corpus/seed-2024-08-29-0 b/health/aidl/default/corpus/seed-2024-08-29-0
new file mode 100644
index 0000000..07fd0e9
--- /dev/null
+++ b/health/aidl/default/corpus/seed-2024-08-29-0
Binary files differ
diff --git a/health/aidl/default/corpus/seed-2024-08-29-1 b/health/aidl/default/corpus/seed-2024-08-29-1
new file mode 100644
index 0000000..ef19735
--- /dev/null
+++ b/health/aidl/default/corpus/seed-2024-08-29-1
Binary files differ
diff --git a/health/aidl/default/corpus/seed-2024-08-29-2 b/health/aidl/default/corpus/seed-2024-08-29-2
new file mode 100644
index 0000000..76addb7
--- /dev/null
+++ b/health/aidl/default/corpus/seed-2024-08-29-2
Binary files differ
diff --git a/health/storage/OWNERS b/health/storage/OWNERS
index 7af8d99..ec1fd8f 100644
--- a/health/storage/OWNERS
+++ b/health/storage/OWNERS
@@ -1,6 +1,9 @@
# Bug component: 30545
+# Don't inherit owners from hardware/interfaces/health/
set noparent
+# But inherit from hardware/interfaces
+include platform/hardware/interfaces:/OWNERS
jaegeuk@google.com
elsk@google.com
diff --git a/health/storage/aidl/Android.bp b/health/storage/aidl/Android.bp
index c614efb..44484d6 100644
--- a/health/storage/aidl/Android.bp
+++ b/health/storage/aidl/Android.bp
@@ -26,6 +26,7 @@
vendor_available: true,
srcs: ["android/hardware/health/storage/*.aidl"],
stability: "vintf",
+ frozen: true,
backend: {
cpp: {
enabled: false,
diff --git a/health/utils/libhealthloop/Android.bp b/health/utils/libhealthloop/Android.bp
index 7aaf905..4ebc575 100644
--- a/health/utils/libhealthloop/Android.bp
+++ b/health/utils/libhealthloop/Android.bp
@@ -21,6 +21,17 @@
default_applicable_licenses: ["hardware_interfaces_license"],
}
+bpf {
+ name: "filterPowerSupplyEvents.o",
+ srcs: ["filterPowerSupplyEvents.c"],
+ // "vendor: true" because all binaries that use this BPF filter are vendor
+ // binaries.
+ vendor: true,
+}
+
+// Since "required" sections are ignored in static library definitions,
+// filterPowerSupplyEvents.o has been added in
+// build/make/target/product/base_vendor.mk.
cc_library_static {
name: "libhealthloop",
vendor_available: true,
@@ -30,10 +41,11 @@
"utils.cpp",
],
shared_libs: [
- "libcutils",
"libbase",
+ "libcutils",
],
header_libs: [
+ "bpf_headers",
"libbatteryservice_headers",
"libhealthd_headers",
"libutils_headers",
@@ -42,3 +54,30 @@
"include",
],
}
+
+genrule {
+ name: "filterPowerSupplyEvents.h",
+ out: ["filterPowerSupplyEvents.h"],
+ srcs: [":filterPowerSupplyEvents.o"],
+ cmd: "cat $(in) | od -v -tx1 | cut -c9- | grep -v '^$$' | sed 's/^/0x/;s/ /, 0x/g;s/^, //;s/$$/,/' > $(out)",
+}
+
+cc_test_host {
+ name: "filterPowerSupplyEventsTest",
+ team: "trendy_team_pixel_system_sw_storage",
+ srcs: [
+ "filterPowerSupplyEventsTest.cpp",
+ ],
+ shared_libs: [
+ "libbase",
+ "libbpf",
+ ],
+ static_libs: [
+ "libgmock",
+ ],
+ generated_headers: [
+ "filterPowerSupplyEvents.h",
+ "libbpf_headers",
+ ],
+ compile_multilib: "64",
+}
diff --git a/health/utils/libhealthloop/HealthLoop.cpp b/health/utils/libhealthloop/HealthLoop.cpp
index 4190769..c5ad5a8 100644
--- a/health/utils/libhealthloop/HealthLoop.cpp
+++ b/health/utils/libhealthloop/HealthLoop.cpp
@@ -20,23 +20,22 @@
#include <health/HealthLoop.h>
#include <errno.h>
-#include <libgen.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/epoll.h>
+#include <sys/epoll.h> // epoll_create1(), epoll_ctl(), epoll_wait()
#include <sys/timerfd.h>
-#include <unistd.h>
+#include <unistd.h> // read()
#include <android-base/logging.h>
#include <batteryservice/BatteryService.h>
-#include <cutils/klog.h>
+#include <cutils/klog.h> // KLOG_*()
#include <cutils/uevent.h>
#include <healthd/healthd.h>
-#include <utils/Errors.h>
+#include <BpfSyscallWrappers.h>
#include <health/utils.h>
+using android::base::ErrnoError;
+using android::base::Result;
+using android::base::unique_fd;
using namespace android;
using namespace std::chrono_literals;
@@ -44,6 +43,8 @@
namespace hardware {
namespace health {
+static constexpr uint32_t kUeventMsgLen = 2048;
+
HealthLoop::HealthLoop() {
InitHealthdConfig(&healthd_config_);
awake_poll_interval_ = -1;
@@ -57,19 +58,18 @@
int HealthLoop::RegisterEvent(int fd, BoundFunction func, EventWakeup wakeup) {
CHECK(!reject_event_register_);
- auto* event_handler =
- event_handlers_
- .emplace_back(std::make_unique<EventHandler>(EventHandler{this, fd, func}))
- .get();
+ auto* event_handler = event_handlers_
+ .emplace_back(std::make_unique<EventHandler>(
+ EventHandler{this, fd, std::move(func)}))
+ .get();
- struct epoll_event ev;
-
- ev.events = EPOLLIN;
+ struct epoll_event ev = {
+ .events = EPOLLIN | EPOLLERR,
+ .data.ptr = reinterpret_cast<void*>(event_handler),
+ };
if (wakeup == EVENT_WAKEUP_FD) ev.events |= EPOLLWAKEUP;
- ev.data.ptr = reinterpret_cast<void*>(event_handler);
-
if (epoll_ctl(epollfd_, EPOLL_CTL_ADD, fd, &ev) == -1) {
KLOG_ERROR(LOG_TAG, "epoll_ctl failed; errno=%d\n", errno);
return -1;
@@ -122,38 +122,65 @@
ScheduleBatteryUpdate();
}
-// TODO(b/140330870): Use BPF instead.
-#define UEVENT_MSG_LEN 2048
-void HealthLoop::UeventEvent(uint32_t /*epevents*/) {
- // No need to lock because uevent_fd_ is guaranteed to be initialized.
-
- char msg[UEVENT_MSG_LEN + 2];
- char* cp;
- int n;
-
- n = uevent_kernel_multicast_recv(uevent_fd_, msg, UEVENT_MSG_LEN);
- if (n <= 0) return;
- if (n >= UEVENT_MSG_LEN) /* overflow -- discard */
- return;
-
- msg[n] = '\0';
- msg[n + 1] = '\0';
- cp = msg;
-
- while (*cp) {
- if (!strcmp(cp, "SUBSYSTEM=power_supply")) {
- ScheduleBatteryUpdate();
- break;
+// Returns true if and only if the battery statistics should be updated.
+bool HealthLoop::RecvUevents() {
+ bool update_stats = false;
+ for (;;) {
+ char msg[kUeventMsgLen + 2];
+ int n = uevent_kernel_multicast_recv(uevent_fd_, msg, kUeventMsgLen);
+ if (n < 0 && errno == ENOBUFS) {
+ update_stats = true;
+ }
+ if (n <= 0) return update_stats;
+ if (n >= kUeventMsgLen) {
+ // too long -- discard
+ continue;
+ }
+ if (update_stats) {
+ continue;
}
- /* advance to after the next \0 */
- while (*cp++)
- ;
+ msg[n] = '\0';
+ msg[n + 1] = '\0';
+ for (char* cp = msg; *cp;) {
+ if (strcmp(cp, "SUBSYSTEM=power_supply") == 0) {
+ update_stats = true;
+ break;
+ }
+
+ /* advance to after the next \0 */
+ while (*cp++) {
+ }
+ }
}
}
+void HealthLoop::UeventEvent(uint32_t /*epevents*/) {
+ if (RecvUevents()) {
+ ScheduleBatteryUpdate();
+ }
+}
+
+// Attach a BPF filter to the @uevent_fd file descriptor. This fails in recovery mode because BPF is
+// not supported in recovery mode. This fails for kernel versions 5.4 and before because the BPF
+// program is rejected by the BPF verifier of older kernels.
+Result<void> HealthLoop::AttachFilter(int uevent_fd) {
+ static const char prg[] =
+ "/sys/fs/bpf/vendor/prog_filterPowerSupplyEvents_skfilter_power_supply";
+ int filter_fd(bpf::retrieveProgram(prg));
+ if (filter_fd < 0) {
+ return ErrnoError() << "failed to load BPF program " << prg;
+ }
+ if (setsockopt(uevent_fd, SOL_SOCKET, SO_ATTACH_BPF, &filter_fd, sizeof(filter_fd)) < 0) {
+ close(filter_fd);
+ return ErrnoError() << "failed to attach BPF program";
+ }
+ close(filter_fd);
+ return {};
+}
+
void HealthLoop::UeventInit(void) {
- uevent_fd_.reset(uevent_open_socket(64 * 1024, true));
+ uevent_fd_.reset(uevent_create_socket(kUeventMsgLen, true));
if (uevent_fd_ < 0) {
KLOG_ERROR(LOG_TAG, "uevent_init: uevent_open_socket failed\n");
@@ -161,8 +188,25 @@
}
fcntl(uevent_fd_, F_SETFL, O_NONBLOCK);
+
+ Result<void> attach_result = AttachFilter(uevent_fd_);
+ if (!attach_result.ok()) {
+ std::string error_msg = attach_result.error().message();
+ error_msg +=
+ ". This is expected in recovery mode and also for kernel versions before 5.10.";
+ KLOG_WARNING(LOG_TAG, "%s\n", error_msg.c_str());
+ } else {
+ KLOG_INFO(LOG_TAG, "Successfully attached the BPF filter to the uevent socket\n");
+ }
+
if (RegisterEvent(uevent_fd_, &HealthLoop::UeventEvent, EVENT_WAKEUP_FD))
KLOG_ERROR(LOG_TAG, "register for uevent events failed\n");
+
+ if (uevent_bind(uevent_fd_.get()) < 0) {
+ uevent_fd_.reset();
+ KLOG_ERROR(LOG_TAG, "uevent_init: binding socket failed\n");
+ return;
+ }
}
void HealthLoop::WakeAlarmEvent(uint32_t /*epevents*/) {
diff --git a/health/utils/libhealthloop/filterPowerSupplyEvents.c b/health/utils/libhealthloop/filterPowerSupplyEvents.c
new file mode 100644
index 0000000..5296993
--- /dev/null
+++ b/health/utils/libhealthloop/filterPowerSupplyEvents.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2024 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 <bpf_helpers.h> // load_word()
+#include <linux/bpf.h> // struct __sk_buff
+#include <linux/netlink.h> // struct nlmsghdr
+#include <stdint.h> // uint32_t
+
+// M4: match 4 bytes. Returns 0 if all bytes match.
+static inline uint32_t M4(struct __sk_buff* skb, unsigned int offset, uint8_t c0, uint8_t c1,
+ uint8_t c2, uint8_t c3) {
+ return load_word(skb, offset) ^ ((c0 << 24) | (c1 << 16) | (c2 << 8) | c3);
+}
+
+// M2: match 2 bytes. Returns 0 if all bytes match.
+static inline uint16_t M2(struct __sk_buff* skb, unsigned int offset, uint8_t c0, uint8_t c1) {
+ return load_half(skb, offset) ^ ((c0 << 8) | c1);
+}
+
+// M1: match 1 byte. Returns 0 in case of a match.
+static inline uint8_t M1(struct __sk_buff* skb, unsigned int offset, uint8_t c0) {
+ return load_byte(skb, offset) ^ c0;
+}
+
+// Match "\0SUBSYSTEM=". Returns 0 in case of a match.
+#define MATCH_SUBSYSTEM_LENGTH 11
+static inline uint32_t match_subsystem(struct __sk_buff* skb, unsigned int offset) {
+ return M4(skb, offset + 0, '\0', 'S', 'U', 'B') | M4(skb, offset + 4, 'S', 'Y', 'S', 'T') |
+ M2(skb, offset + 8, 'E', 'M') | M1(skb, offset + 10, '=');
+}
+
+// Match "power_supply\0". Returns 0 in case of a match.
+#define MATCH_POWER_SUPPLY_LENGTH 13
+static inline uint32_t match_power_supply(struct __sk_buff* skb, unsigned int offset) {
+ return M4(skb, offset + 0, 'p', 'o', 'w', 'e') | M4(skb, offset + 4, 'r', '_', 's', 'u') |
+ M4(skb, offset + 8, 'p', 'p', 'l', 'y') | M1(skb, offset + 12, '\0');
+}
+
+// The Linux kernel 5.4 BPF verifier rejects this program, probably because of its size. Hence the
+// restriction that the kernel version must be at least 5.10.
+DEFINE_BPF_PROG_KVER("skfilter/power_supply", AID_ROOT, AID_SYSTEM, filterPowerSupplyEvents,
+ KVER(5, 10, 0))
+(struct __sk_buff* skb) {
+ uint32_t i;
+
+ // The first character matched by match_subsystem() is a '\0'. Starting
+ // right past the netlink message header is fine since the SUBSYSTEM= text
+ // never occurs at the start. See also the kobject_uevent_env() implementation:
+ // https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/lib/kobject_uevent.c?#n473
+ // The upper bound of this loop has been chosen not to exceed the maximum
+ // number of instructions in a BPF program (BPF loops are unrolled).
+ for (i = sizeof(struct nlmsghdr); i < 256; ++i) {
+ if (i + MATCH_SUBSYSTEM_LENGTH > skb->len) {
+ break;
+ }
+ if (match_subsystem(skb, i) == 0) {
+ goto found_subsystem;
+ }
+ }
+
+ // The SUBSYSTEM= text has not been found in the bytes that have been
+ // examined: let the user space software perform filtering.
+ return skb->len;
+
+found_subsystem:
+ i += MATCH_SUBSYSTEM_LENGTH;
+ if (i + MATCH_POWER_SUPPLY_LENGTH <= skb->len && match_power_supply(skb, i) == 0) {
+ return skb->len;
+ }
+ return 0;
+}
+
+LICENSE("Apache 2.0");
+CRITICAL("healthd");
diff --git a/health/utils/libhealthloop/filterPowerSupplyEventsTest.cpp b/health/utils/libhealthloop/filterPowerSupplyEventsTest.cpp
new file mode 100644
index 0000000..04b8bcd
--- /dev/null
+++ b/health/utils/libhealthloop/filterPowerSupplyEventsTest.cpp
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2024 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 <android-base/unique_fd.h>
+#include <bpf/libbpf.h>
+#include <gtest/gtest.h>
+#include <linux/bpf.h> // SO_ATTACH_BPF
+#include <linux/netlink.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <sys/socket.h>
+#include <string>
+#include <string_view>
+
+#define ASSERT_UNIX_OK(e) ASSERT_GE(e, 0) << strerror(errno)
+
+// TODO(bvanassche): remove the code below. See also b/357099095.
+#ifndef SO_ATTACH_BPF
+#define SO_ATTACH_BPF 50 // From <asm-generic/socket.h>.
+#endif
+
+using ::android::base::unique_fd;
+using ::testing::ScopedTrace;
+
+struct test_data {
+ bool discarded;
+ std::string_view str;
+};
+
+static const uint8_t binary_bpf_prog[] = {
+#include "filterPowerSupplyEvents.h"
+};
+
+static std::vector<std::unique_ptr<ScopedTrace>>* msg_vec;
+
+std::ostream& operator<<(std::ostream& os, const test_data& td) {
+ os << "{.discarded=" << td.discarded << ", .str=";
+ for (auto c : td.str) {
+ if (isprint(c)) {
+ os << c;
+ } else {
+ os << ".";
+ }
+ }
+ return os << '}';
+}
+
+#define RECORD_ERR_MSG(fmt, ...) \
+ do { \
+ char* str; \
+ if (asprintf(&str, fmt, ##__VA_ARGS__) < 0) break; \
+ auto st = std::make_unique<ScopedTrace>(__FILE__, __LINE__, str); \
+ msg_vec->emplace_back(std::move(st)); \
+ free(str); \
+ } while (0)
+
+int libbpf_print_fn(enum libbpf_print_level, const char* fmt, va_list args) {
+ char* str;
+ if (vasprintf(&str, fmt, args) < 0) {
+ return 0;
+ }
+ msg_vec->emplace_back(std::make_unique<ScopedTrace>(__FILE__, -1, str));
+ free(str);
+ return 0;
+}
+
+static void record_libbpf_output() {
+ libbpf_set_print(libbpf_print_fn);
+}
+
+class filterPseTest : public testing::TestWithParam<test_data> {};
+
+struct ConnectedSockets {
+ unique_fd write_fd;
+ unique_fd read_fd;
+};
+
+// socketpair() only supports AF_UNIX sockets. AF_UNIX sockets do not
+// support BPF filters. Hence connect two TCP sockets with each other.
+static ConnectedSockets ConnectSockets(int domain, int type, int protocol) {
+ int _server_fd = socket(domain, type, protocol);
+ if (_server_fd < 0) {
+ return {};
+ }
+ unique_fd server_fd(_server_fd);
+
+ int _write_fd = socket(domain, type, protocol);
+ if (_write_fd < 0) {
+ RECORD_ERR_MSG("socket: %s", strerror(errno));
+ return {};
+ }
+ unique_fd write_fd(_write_fd);
+
+ struct sockaddr_in sa = {.sin_family = AF_INET, .sin_addr.s_addr = INADDR_ANY};
+ if (bind(_server_fd, (const struct sockaddr*)&sa, sizeof(sa)) < 0) {
+ RECORD_ERR_MSG("bind: %s", strerror(errno));
+ return {};
+ }
+ if (listen(_server_fd, 1) < 0) {
+ RECORD_ERR_MSG("listen: %s", strerror(errno));
+ return {};
+ }
+ socklen_t addr_len = sizeof(sa);
+ if (getsockname(_server_fd, (struct sockaddr*)&sa, &addr_len) < 0) {
+ RECORD_ERR_MSG("getsockname: %s", strerror(errno));
+ return {};
+ }
+ errno = 0;
+ if (connect(_write_fd, (const struct sockaddr*)&sa, sizeof(sa)) < 0 && errno != EINPROGRESS) {
+ RECORD_ERR_MSG("connect: %s", strerror(errno));
+ return {};
+ }
+ int _read_fd = accept(_server_fd, NULL, NULL);
+ if (_read_fd < 0) {
+ RECORD_ERR_MSG("accept: %s", strerror(errno));
+ return {};
+ }
+ unique_fd read_fd(_read_fd);
+
+ return {.write_fd = std::move(write_fd), .read_fd = std::move(read_fd)};
+}
+
+TEST_P(filterPseTest, filterPse) {
+ if (getuid() != 0) {
+ GTEST_SKIP() << "Must be run as root.";
+ return;
+ }
+ if (!msg_vec) {
+ msg_vec = new typeof(*msg_vec);
+ }
+ std::unique_ptr<int, void (*)(int*)> clear_msg_vec_at_end_of_scope(new int, [](int* p) {
+ msg_vec->clear();
+ delete p;
+ });
+ record_libbpf_output();
+
+ auto connected_sockets = ConnectSockets(AF_INET, SOCK_STREAM, 0);
+ unique_fd write_fd = std::move(connected_sockets.write_fd);
+ unique_fd read_fd = std::move(connected_sockets.read_fd);
+
+ ASSERT_UNIX_OK(fcntl(read_fd, F_SETFL, O_NONBLOCK));
+
+ bpf_object* obj = bpf_object__open_mem(binary_bpf_prog, sizeof(binary_bpf_prog), NULL);
+ ASSERT_TRUE(obj) << "bpf_object__open() failed" << strerror(errno);
+
+ // Find the BPF program within the object.
+ bpf_program* prog = bpf_object__find_program_by_name(obj, "filterPowerSupplyEvents");
+ ASSERT_TRUE(prog);
+
+ ASSERT_UNIX_OK(bpf_program__set_type(prog, BPF_PROG_TYPE_SOCKET_FILTER));
+
+ ASSERT_UNIX_OK(bpf_object__load(obj));
+
+ int filter_fd = bpf_program__fd(prog);
+ ASSERT_UNIX_OK(filter_fd);
+
+ int setsockopt_result =
+ setsockopt(read_fd, SOL_SOCKET, SO_ATTACH_BPF, &filter_fd, sizeof(filter_fd));
+ ASSERT_UNIX_OK(setsockopt_result);
+
+ const test_data param = GetParam();
+ const std::string header(sizeof(struct nlmsghdr), '\0');
+ ASSERT_EQ(header.length(), sizeof(struct nlmsghdr));
+ const std::string data = header + std::string(param.str);
+ const size_t len = data.length();
+ std::cerr.write(data.data(), data.length());
+ std::cerr << ")\n";
+ ASSERT_EQ(write(write_fd, data.data(), len), len);
+ std::array<uint8_t, 512> read_buf;
+ int bytes_read = read(read_fd, read_buf.data(), read_buf.size());
+ if (bytes_read < 0) {
+ ASSERT_EQ(errno, EAGAIN);
+ bytes_read = 0;
+ } else {
+ ASSERT_LT(bytes_read, read_buf.size());
+ }
+ EXPECT_EQ(bytes_read, param.discarded ? 0 : len);
+
+ bpf_object__close(obj);
+}
+
+static constexpr char input0[] = "a";
+static constexpr char input1[] = "abc\0SUBSYSTEM=block\0";
+static constexpr char input2[] = "\0SUBSYSTEM=block";
+static constexpr char input3[] = "\0SUBSYSTEM=power_supply";
+static constexpr char input4[] = "\0SUBSYSTEM=power_supply\0";
+static constexpr char input5[] =
+ "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"
+ "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"
+ "012345678901234567890123456789012345678901234567890123456789\0SUBSYSTEM=block\0";
+
+INSTANTIATE_TEST_SUITE_P(
+ filterPse, filterPseTest,
+ testing::Values(test_data{false, std::string_view(input0, sizeof(input0) - 1)},
+ test_data{true, std::string_view(input1, sizeof(input1) - 1)},
+ test_data{true, std::string_view(input2, sizeof(input2) - 1)},
+ test_data{true, std::string_view(input3, sizeof(input3) - 1)},
+ test_data{false, std::string_view(input4, sizeof(input4) - 1)},
+ test_data{false, std::string_view(input5, sizeof(input5) - 1)}));
diff --git a/health/utils/libhealthloop/include/health/HealthLoop.h b/health/utils/libhealthloop/include/health/HealthLoop.h
index fc3066e..43c38dc 100644
--- a/health/utils/libhealthloop/include/health/HealthLoop.h
+++ b/health/utils/libhealthloop/include/health/HealthLoop.h
@@ -20,6 +20,7 @@
#include <mutex>
#include <vector>
+#include <android-base/result.h>
#include <android-base/unique_fd.h>
#include <healthd/healthd.h>
@@ -87,10 +88,12 @@
};
int InitInternal();
+ static android::base::Result<void> AttachFilter(int uevent_fd);
void MainLoop();
void WakeAlarmInit();
void WakeAlarmEvent(uint32_t);
void UeventInit();
+ bool RecvUevents();
void UeventEvent(uint32_t);
void WakeAlarmSetInterval(int interval);
void PeriodicChores();
diff --git a/input/common/aidl/Android.bp b/input/common/aidl/Android.bp
index 0759d2e..8721e5d 100644
--- a/input/common/aidl/Android.bp
+++ b/input/common/aidl/Android.bp
@@ -14,6 +14,7 @@
vendor_available: true,
srcs: ["android/hardware/input/common/*.aidl"],
stability: "vintf",
+ frozen: true,
backend: {
cpp: {
enabled: false,
diff --git a/input/processor/aidl/Android.bp b/input/processor/aidl/Android.bp
index 68adf32..6855b08 100644
--- a/input/processor/aidl/Android.bp
+++ b/input/processor/aidl/Android.bp
@@ -12,6 +12,7 @@
name: "android.hardware.input.processor",
host_supported: true,
vendor_available: true,
+ frozen: true,
srcs: ["android/hardware/input/processor/*.aidl"],
imports: [
"android.hardware.input.common-V1",
diff --git a/ir/aidl/Android.bp b/ir/aidl/Android.bp
index 25f6c8f..c561c52 100644
--- a/ir/aidl/Android.bp
+++ b/ir/aidl/Android.bp
@@ -26,6 +26,7 @@
vendor_available: true,
srcs: ["android/hardware/ir/*.aidl"],
stability: "vintf",
+ frozen: true,
backend: {
cpp: {
enabled: false,
diff --git a/keymaster/4.0/vts/performance/Android.bp b/keymaster/4.0/vts/performance/Android.bp
index d7342ad..8f26871 100644
--- a/keymaster/4.0/vts/performance/Android.bp
+++ b/keymaster/4.0/vts/performance/Android.bp
@@ -33,6 +33,5 @@
"android.hardware.keymaster@4.0",
"libkeymaster4support",
"libsoftkeymasterdevice",
- "libchrome"
],
}
diff --git a/keymaster/4.0/vts/performance/Benchmark.cpp b/keymaster/4.0/vts/performance/Benchmark.cpp
index e5fdff2..723b543 100644
--- a/keymaster/4.0/vts/performance/Benchmark.cpp
+++ b/keymaster/4.0/vts/performance/Benchmark.cpp
@@ -16,6 +16,8 @@
#define LOG_TAG "keymaster_benchmark"
+#include <getopt.h>
+
#include <android/hardware/keymaster/4.0/IKeymasterDevice.h>
#include <android/hardware/keymaster/4.0/types.h>
#include <keymaster/keymaster_configuration.h>
@@ -36,8 +38,6 @@
#include <benchmark/benchmark.h>
#include <hidl/Status.h>
-#include <base/command_line.h>
-
namespace android {
namespace hardware {
namespace keymaster {
@@ -700,14 +700,26 @@
} // namespace hardware
} // namespace android
+namespace {
+
+std::string ParseCommandLineFlags(int argc, char** argv) {
+ std::string service_name = "default";
+ static struct option long_options[] = {{"service_name", required_argument, 0, 's'},
+ {0, 0, 0, 0}};
+ int opt;
+ while ((opt = getopt_long(argc, argv, "s:", long_options, nullptr)) != -1) {
+ if (opt == 's') {
+ service_name = optarg;
+ }
+ }
+ return service_name;
+}
+
+} // namespace
+
int main(int argc, char** argv) {
::benchmark::Initialize(&argc, argv);
- base::CommandLine::Init(argc, argv);
- base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
- auto service_name = command_line->GetSwitchValueASCII("service_name");
- if (service_name.empty()) {
- service_name = "default";
- }
+ std::string service_name = ParseCommandLineFlags(argc, argv);
android::hardware::keymaster::V4_0::test::keymaster =
android::hardware::keymaster::V4_0::test::KeymasterWrapper::newInstance(service_name);
if (!android::hardware::keymaster::V4_0::test::keymaster) {
diff --git a/keymaster/aidl/Android.bp b/keymaster/aidl/Android.bp
index 0f2debd..56997a9 100644
--- a/keymaster/aidl/Android.bp
+++ b/keymaster/aidl/Android.bp
@@ -18,6 +18,9 @@
java: {
platform_apis: true,
},
+ rust: {
+ enabled: true,
+ },
},
versions_with_info: [
{
diff --git a/light/aidl/Android.bp b/light/aidl/Android.bp
index c9fba95..142be6d 100644
--- a/light/aidl/Android.bp
+++ b/light/aidl/Android.bp
@@ -14,6 +14,7 @@
"android/hardware/light/*.aidl",
],
stability: "vintf",
+ frozen: true,
backend: {
java: {
sdk_version: "module_current",
diff --git a/media/bufferpool/aidl/default/BufferPoolClient.cpp b/media/bufferpool/aidl/default/BufferPoolClient.cpp
index ce4ad8e..b61893f 100644
--- a/media/bufferpool/aidl/default/BufferPoolClient.cpp
+++ b/media/bufferpool/aidl/default/BufferPoolClient.cpp
@@ -748,6 +748,10 @@
} else {
connection = mRemoteConnection;
}
+ if (!connection) {
+ ALOGE("connection null: fetchBufferHandle()");
+ return ResultStatus::CRITICAL_ERROR;
+ }
std::vector<FetchInfo> infos;
std::vector<FetchResult> results;
infos.emplace_back(FetchInfo{ToAidl(transactionId), ToAidl(bufferId)});
diff --git a/media/omx/1.0/vts/functional/store/VtsHalMediaOmxV1_0TargetStoreTest.cpp b/media/omx/1.0/vts/functional/store/VtsHalMediaOmxV1_0TargetStoreTest.cpp
index d80e651..2d34afe 100644
--- a/media/omx/1.0/vts/functional/store/VtsHalMediaOmxV1_0TargetStoreTest.cpp
+++ b/media/omx/1.0/vts/functional/store/VtsHalMediaOmxV1_0TargetStoreTest.cpp
@@ -93,9 +93,9 @@
void validateAttributes(
const std::map<const std::string, const testing::internal::RE>& knownPatterns,
- const std::vector<const struct AttributePattern>& unknownPatterns,
+ const std::vector<struct AttributePattern>& unknownPatterns,
hidl_vec<IOmxStore::Attribute> attributes) {
- std::set<const std::string> attributeKeys;
+ std::set<std::string> attributeKeys;
for (const auto& attr : attributes) {
// Make sure there are no duplicates
const auto [nodeIter, inserted] = attributeKeys.insert(attr.key);
@@ -179,7 +179,7 @@
* tried for a match with the second element of the pair. If this second
* match fails, the test will fail.
*/
- const std::vector<const struct AttributePattern> unknownPatterns = {
+ const std::vector<struct AttributePattern> unknownPatterns = {
{"supports-[a-z0-9-]*", "0|1"}};
validateAttributes(knownPatterns, unknownPatterns, attributes);
@@ -248,7 +248,7 @@
};
// Strings for matching rules for node attributes with key patterns
- const std::vector<const struct AttributePattern> unknownPatterns = {
+ const std::vector<struct AttributePattern> unknownPatterns = {
{"measured-frame-rate-" + size + "-range", range_num},
{"feature-[a-zA-Z0-9_-]+", string},
};
@@ -257,9 +257,9 @@
const testing::internal::RE nodeNamePattern = "[a-zA-Z0-9._-]+";
const testing::internal::RE nodeOwnerPattern = "[a-zA-Z0-9._-]+";
- std::set<const std::string> roleKeys;
- std::map<const std::string, std::set<const std::string>> nodeToRoles;
- std::map<const std::string, std::set<const std::string>> ownerToNodes;
+ std::set<std::string> roleKeys;
+ std::map<const std::string, std::set<std::string>> nodeToRoles;
+ std::map<const std::string, std::set<std::string>> ownerToNodes;
for (const IOmxStore::RoleInfo& role : roleList) {
// Make sure there are no duplicates
const auto [roleIter, inserted] = roleKeys.insert(role.role);
@@ -276,7 +276,7 @@
}
// Check the nodes for this role
- std::set<const std::string> nodeKeys;
+ std::set<std::string> nodeKeys;
for (const IOmxStore::NodeInfo& node : role.nodes) {
// Make sure there are no duplicates
const auto [nodeIter, inserted] = nodeKeys.insert(node.name);
@@ -317,7 +317,7 @@
// Verify that roles for each node match with the information from
// IOmxStore::listRoles().
- std::set<const std::string> nodeKeys;
+ std::set<std::string> nodeKeys;
for (IOmx::ComponentInfo node : nodeList) {
// Make sure there are no duplicates
const auto [nodeIter, inserted] = nodeKeys.insert(node.mName);
@@ -334,7 +334,7 @@
// All the roles advertised by IOmxStore::listRoles() for this
// node must be included in roleKeys.
- std::set<const std::string> difference;
+ std::set<std::string> difference;
std::set_difference(nodeToRoles[node.mName].begin(), nodeToRoles[node.mName].end(),
roleKeys.begin(), roleKeys.end(),
std::inserter(difference, difference.begin()));
@@ -347,7 +347,7 @@
}
// Check that all nodes obtained from IOmxStore::listRoles() are
// supported by the their corresponding IOmx instances.
- std::set<const std::string> difference;
+ std::set<std::string> difference;
std::set_difference(nodes.begin(), nodes.end(), nodeKeys.begin(), nodeKeys.end(),
std::inserter(difference, difference.begin()));
EXPECT_EQ(difference.empty(), true) << "IOmx::listNodes() for IOmx "
diff --git a/memtrack/OWNERS b/memtrack/OWNERS
index a182ed9..8017da6 100644
--- a/memtrack/OWNERS
+++ b/memtrack/OWNERS
@@ -1,2 +1,3 @@
-# Bug component: 30545
-connoro@google.com
+# Bug component: 356484
+kaleshsingh@google.com
+surenb@google.com
diff --git a/neuralnetworks/aidl/Android.bp b/neuralnetworks/aidl/Android.bp
index 145604c..c9242ca 100644
--- a/neuralnetworks/aidl/Android.bp
+++ b/neuralnetworks/aidl/Android.bp
@@ -11,6 +11,7 @@
name: "android.hardware.neuralnetworks",
host_supported: true,
vendor_available: true,
+ frozen: true,
srcs: [
"android/hardware/neuralnetworks/*.aidl",
],
diff --git a/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp b/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp
index 2fc9e65..6d4936b 100644
--- a/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp
+++ b/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp
@@ -108,7 +108,7 @@
EXPECT_EQ(NfcStatus::OK, nfc_->open(nfc_cb_));
// Wait for OPEN_CPLT event
auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ(NfcEvent::OPEN_CPLT, res.args->last_event_);
EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
@@ -118,7 +118,7 @@
EXPECT_EQ(data.size(), nfc_->write(data));
// Wait for CORE_RESET_RSP
res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_GE(6ul, res.args->last_data_.size());
EXPECT_EQ((int)NfcStatus::OK, res.args->last_data_[3]);
if (res.args->last_data_.size() == 6) {
@@ -127,7 +127,7 @@
EXPECT_EQ(4ul, res.args->last_data_.size());
nci_version = NCI_VERSION_2;
res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
}
/*
@@ -137,14 +137,14 @@
EXPECT_EQ(NfcStatus::OK, nfc_->close());
// Wait for CLOSE_CPLT event
res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ(NfcEvent::CLOSE_CPLT, res.args->last_event_);
EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
EXPECT_EQ(NfcStatus::OK, nfc_->open(nfc_cb_));
// Wait for OPEN_CPLT event
res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ(NfcEvent::OPEN_CPLT, res.args->last_event_);
EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
}
@@ -153,7 +153,7 @@
EXPECT_EQ(NfcStatus::OK, nfc_->close());
// Wait for CLOSE_CPLT event
auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ(NfcEvent::CLOSE_CPLT, res.args->last_event_);
EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
}
@@ -186,7 +186,7 @@
EXPECT_EQ(data.size(), nfc_->write(data));
// Wait for CORE_RESET_RSP
auto res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
/* The response/notification format for CORE_RESET_CMD differs
* with NCI 1.0 and 2.0. */
@@ -200,7 +200,7 @@
EXPECT_EQ((int)NfcStatus::OK, res.args->last_data_[3]);
// Wait for CORE_RESET_NTF
res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
// Check if reset trigger was due to CORE_RESET_CMD
EXPECT_LE(8ul, res.args->last_data_.size());
EXPECT_EQ(2ul, res.args->last_data_[3]);
@@ -221,7 +221,7 @@
EXPECT_EQ(data.size(), nfc_->write(data));
// Wait for CORE_RESET_RSP
auto res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
/* The response/notification format for CORE_RESET_CMD differs
* with NCI 1.0 and 2.0. */
@@ -235,7 +235,7 @@
EXPECT_EQ((int)NfcStatus::OK, res.args->last_data_[3]);
// Wait for CORE_RESET_NTF
res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
// Check if reset trigger was due to CORE_RESET_CMD
EXPECT_LE(8ul, res.args->last_data_.size());
EXPECT_EQ(2ul, res.args->last_data_[3]);
@@ -257,7 +257,7 @@
EXPECT_EQ(data.size(), nfc_->write(data));
// Wait for RSP
auto res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ(4ul, res.args->last_data_.size());
EXPECT_EQ(SYNTAX_ERROR, res.args->last_data_[3]);
}
@@ -277,14 +277,14 @@
EXPECT_EQ(data.size(), nfc_->write(data));
// Wait for CORE_RESET_RSP
auto res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ((int)NfcStatus::OK, res.args->last_data_[3]);
/* NCI 2.0 sends CORE_RESET_NTF everytime. */
if (nci_version == NCI_VERSION_2) {
// Wait for CORE_RESET_NTF
res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
cmd = CORE_INIT_CMD_NCI20;
} else {
cmd = CORE_INIT_CMD;
@@ -294,7 +294,7 @@
EXPECT_EQ(data.size(), nfc_->write(data));
// Wait for CORE_INIT_RSP
res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ((int)NfcStatus::OK, res.args->last_data_[3]);
// Send an Error Data Packet
cmd = INVALID_COMMAND;
@@ -307,7 +307,7 @@
EXPECT_EQ(data.size(), nfc_->write(data));
// Wait for response with SYNTAX_ERROR
res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ(4ul, res.args->last_data_.size());
EXPECT_EQ(SYNTAX_ERROR, res.args->last_data_[3]);
}
@@ -317,7 +317,7 @@
EXPECT_EQ(data.size(), nfc_->write(data));
// Wait for CORE_CONN_CREATE_RSP
res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ(7ul, res.args->last_data_.size());
EXPECT_EQ((int)NfcStatus::OK, res.args->last_data_[3]);
}
@@ -335,14 +335,14 @@
EXPECT_EQ(data.size(), nfc_->write(data));
// Wait for CORE_RESET_RSP
auto res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ((int)NfcStatus::OK, res.args->last_data_[3]);
/* NCI 2.0 sends CORE_RESET_NTF everytime. */
if (nci_version == NCI_VERSION_2) {
// Wait for CORE_RESET_NTF
res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
cmd = CORE_INIT_CMD_NCI20;
} else {
cmd = CORE_INIT_CMD;
@@ -352,15 +352,15 @@
EXPECT_EQ(data.size(), nfc_->write(data));
// Wait for CORE_INIT_RSP
res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ((int)NfcStatus::OK, res.args->last_data_[3]);
cmd = CORE_CONN_CREATE_CMD;
data = cmd;
EXPECT_EQ(data.size(), nfc_->write(data));
// Wait for CORE_CONN_CREATE_RSP
res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
- EXPECT_TRUE(res.no_timeout);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ(7ul, res.args->last_data_.size());
EXPECT_EQ((int)NfcStatus::OK, res.args->last_data_[3]);
uint8_t conn_id = res.args->last_data_[6];
@@ -414,7 +414,7 @@
EXPECT_EQ(NfcStatus::OK, nfc_->powerCycle());
// Wait for NfcEvent.OPEN_CPLT
auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ(NfcEvent::OPEN_CPLT, res.args->last_event_);
EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
}
@@ -428,7 +428,7 @@
EXPECT_EQ(NfcStatus::OK, nfc_->close());
// Wait for CLOSE_CPLT event
auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ(NfcEvent::CLOSE_CPLT, res.args->last_event_);
EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
@@ -437,7 +437,7 @@
EXPECT_EQ(NfcStatus::OK, nfc_->open(nfc_cb_));
// Wait for OPEN_CPLT event
res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ(NfcEvent::OPEN_CPLT, res.args->last_event_);
EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
}
@@ -464,7 +464,7 @@
EXPECT_EQ(NfcStatus::OK, status);
// Wait for NfcEvent.POST_INIT_CPLT
auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ(NfcEvent::POST_INIT_CPLT, res.args->last_event_);
}
}
@@ -487,7 +487,7 @@
EXPECT_EQ(NfcStatus::OK, nfc_->close());
// Wait for CLOSE_CPLT event
auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ(NfcEvent::CLOSE_CPLT, res.args->last_event_);
EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
@@ -496,7 +496,7 @@
EXPECT_EQ(NfcStatus::OK, nfc_->open(nfc_cb_));
// Wait for OPEN_CPLT event
res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ(NfcEvent::OPEN_CPLT, res.args->last_event_);
EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
}
@@ -518,7 +518,7 @@
EXPECT_EQ(NfcStatus::OK, nfc_->close());
// Wait for CLOSE_CPLT event
auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ(NfcEvent::CLOSE_CPLT, res.args->last_event_);
EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
@@ -527,7 +527,7 @@
EXPECT_EQ(NfcStatus::OK, nfc_->open(nfc_cb_));
// Wait for OPEN_CPLT event
res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ(NfcEvent::OPEN_CPLT, res.args->last_event_);
EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
}
@@ -541,7 +541,7 @@
EXPECT_EQ(NfcStatus::OK, nfc_->close());
// Wait for CLOSE_CPLT event
auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ(NfcEvent::CLOSE_CPLT, res.args->last_event_);
EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
@@ -550,7 +550,7 @@
EXPECT_EQ(NfcStatus::OK, nfc_->open(nfc_cb_));
// Wait for OPEN_CPLT event
res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ(NfcEvent::OPEN_CPLT, res.args->last_event_);
EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
}
@@ -564,14 +564,14 @@
EXPECT_EQ(NfcStatus::OK, nfc_->open(nfc_cb_));
// Wait for OPEN_CPLT event
auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ(NfcEvent::OPEN_CPLT, res.args->last_event_);
EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
EXPECT_EQ(NfcStatus::OK, nfc_->open(nfc_cb_));
// Wait for OPEN_CPLT event
res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ(NfcEvent::OPEN_CPLT, res.args->last_event_);
EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
}
diff --git a/nfc/aidl/Android.bp b/nfc/aidl/Android.bp
index ae68f17..b34e4f2 100644
--- a/nfc/aidl/Android.bp
+++ b/nfc/aidl/Android.bp
@@ -27,6 +27,7 @@
vendor_available: true,
srcs: ["android/hardware/nfc/*.aidl"],
stability: "vintf",
+ frozen: false,
backend: {
cpp: {
enabled: false,
diff --git a/nfc/aidl/aidl_api/android.hardware.nfc/current/android/hardware/nfc/INfc.aidl b/nfc/aidl/aidl_api/android.hardware.nfc/current/android/hardware/nfc/INfc.aidl
index 7a0ae54..220912e 100644
--- a/nfc/aidl/aidl_api/android.hardware.nfc/current/android/hardware/nfc/INfc.aidl
+++ b/nfc/aidl/aidl_api/android.hardware.nfc/current/android/hardware/nfc/INfc.aidl
@@ -44,4 +44,5 @@
int write(in byte[] data);
void setEnableVerboseLogging(in boolean enable);
boolean isVerboseLoggingEnabled();
+ android.hardware.nfc.NfcStatus controlGranted();
}
diff --git a/nfc/aidl/aidl_api/android.hardware.nfc/current/android/hardware/nfc/NfcConfig.aidl b/nfc/aidl/aidl_api/android.hardware.nfc/current/android/hardware/nfc/NfcConfig.aidl
index 92e0a9a..0261a0a 100644
--- a/nfc/aidl/aidl_api/android.hardware.nfc/current/android/hardware/nfc/NfcConfig.aidl
+++ b/nfc/aidl/aidl_api/android.hardware.nfc/current/android/hardware/nfc/NfcConfig.aidl
@@ -49,4 +49,5 @@
byte[] offHostRouteUicc;
byte[] offHostRouteEse;
byte defaultIsoDepRoute;
+ byte[] offHostSimPipeIds = {};
}
diff --git a/nfc/aidl/aidl_api/android.hardware.nfc/current/android/hardware/nfc/NfcEvent.aidl b/nfc/aidl/aidl_api/android.hardware.nfc/current/android/hardware/nfc/NfcEvent.aidl
index dda258e..aebe836 100644
--- a/nfc/aidl/aidl_api/android.hardware.nfc/current/android/hardware/nfc/NfcEvent.aidl
+++ b/nfc/aidl/aidl_api/android.hardware.nfc/current/android/hardware/nfc/NfcEvent.aidl
@@ -40,4 +40,6 @@
PRE_DISCOVER_CPLT = 3,
HCI_NETWORK_RESET = 4,
ERROR = 5,
+ REQUEST_CONTROL = 6,
+ RELEASE_CONTROL = 7,
}
diff --git a/nfc/aidl/android/hardware/nfc/INfc.aidl b/nfc/aidl/android/hardware/nfc/INfc.aidl
index 662f8d4..1d18b9e 100644
--- a/nfc/aidl/android/hardware/nfc/INfc.aidl
+++ b/nfc/aidl/android/hardware/nfc/INfc.aidl
@@ -140,4 +140,13 @@
* @return true if verbose logging flag value is enabled, false if disabled.
*/
boolean isVerboseLoggingEnabled();
+
+ /**
+ * Requests control of NFCC to libnfc-nci.
+ * If an API request is sent when the framework has no control of NFCC, the request will be
+ * queued until the control is released from HAL.
+ * The control will be taken out of the framework for at most 2 seconds.
+ * @return NfcStatus::OK on success and NfcStatus::FAILED on error.
+ */
+ NfcStatus controlGranted();
}
diff --git a/nfc/aidl/android/hardware/nfc/NfcConfig.aidl b/nfc/aidl/android/hardware/nfc/NfcConfig.aidl
index 1b4fcfb..870cdbd 100644
--- a/nfc/aidl/android/hardware/nfc/NfcConfig.aidl
+++ b/nfc/aidl/android/hardware/nfc/NfcConfig.aidl
@@ -86,4 +86,8 @@
* Default IsoDep route. 0x00 if there aren't any. Refer to NCI spec.
*/
byte defaultIsoDepRoute;
+ /**
+ * Pipe IDs for UICC. Empty if not available
+ */
+ byte[] offHostSimPipeIds = {};
}
diff --git a/nfc/aidl/android/hardware/nfc/NfcEvent.aidl b/nfc/aidl/android/hardware/nfc/NfcEvent.aidl
index a78b1cd..7e0231a 100644
--- a/nfc/aidl/android/hardware/nfc/NfcEvent.aidl
+++ b/nfc/aidl/android/hardware/nfc/NfcEvent.aidl
@@ -50,4 +50,14 @@
* Error event to notify upper layer when there's an unknown error.
*/
ERROR = 5,
+ /**
+ * Request control event to notify upper layer when HAL
+ * request control of NFCC to libnfc-nci
+ */
+ REQUEST_CONTROL = 6,
+ /**
+ * Release control event to notify upper layer when HAL
+ * release control of NFCC to libnfc-nci.
+ */
+ RELEASE_CONTROL = 7,
}
diff --git a/nfc/aidl/vts/functional/Android.bp b/nfc/aidl/vts/functional/Android.bp
index d0b684b..f97405e 100644
--- a/nfc/aidl/vts/functional/Android.bp
+++ b/nfc/aidl/vts/functional/Android.bp
@@ -38,7 +38,7 @@
"libbinder_ndk",
],
static_libs: [
- "android.hardware.nfc-V1-ndk",
+ "android.hardware.nfc-V2-ndk",
],
test_suites: [
"general-tests",
@@ -49,6 +49,7 @@
cc_test {
name: "VtsNfcBehaviorChangesTest",
defaults: [
+ "aconfig_lib_cc_shared_link.defaults",
"VtsHalTargetTestDefaults",
"use_libaidlvintf_gtest_helper_static",
],
@@ -65,13 +66,14 @@
"system/nfc/utils/include",
],
shared_libs: [
+ "liblog",
"libbinder",
"libbinder_ndk",
"libnativehelper",
"libstatssocket",
],
static_libs: [
- "android.hardware.nfc-V1-ndk",
+ "android.hardware.nfc-V2-ndk",
"android.hardware.nfc@1.0",
"android.hardware.nfc@1.1",
"android.hardware.nfc@1.2",
diff --git a/nfc/aidl/vts/functional/VtsAidlHalNfcTargetTest.cpp b/nfc/aidl/vts/functional/VtsAidlHalNfcTargetTest.cpp
index 977b25c..6e6ca3e 100644
--- a/nfc/aidl/vts/functional/VtsAidlHalNfcTargetTest.cpp
+++ b/nfc/aidl/vts/functional/VtsAidlHalNfcTargetTest.cpp
@@ -423,6 +423,11 @@
EXPECT_GE((uint8_t)configValue.defaultIsoDepRoute, MIN_OFFHOST_ROUTE_ID);
EXPECT_LE((uint8_t)configValue.defaultIsoDepRoute, MAX_OFFHOST_ROUTE_ID);
}
+ for (auto simPipeId : configValue.offHostSimPipeIds) {
+ LOG(INFO) << StringPrintf("offHostSimPipeId= %x", simPipeId);
+ EXPECT_GE(simPipeId, MIN_OFFHOST_ROUTE_ID);
+ EXPECT_LE(simPipeId, MAX_OFFHOST_ROUTE_ID);
+ }
}
/*
@@ -440,6 +445,16 @@
EXPECT_TRUE(!enabled);
}
+TEST_P(NfcAidl, CheckControlGrantedStatus) {
+ int interface_version;
+ EXPECT_TRUE(infc_->getInterfaceVersion(&interface_version).isOk());
+ if (interface_version > 1) {
+ NfcStatus status;
+ EXPECT_TRUE(infc_->controlGranted(&status).isOk());
+ EXPECT_EQ(status, NfcStatus::OK);
+ }
+}
+
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(NfcAidl);
INSTANTIATE_TEST_SUITE_P(Nfc, NfcAidl,
testing::ValuesIn(::android::getAidlHalInstanceNames(INfc::descriptor)),
diff --git a/oemlock/aidl/Android.bp b/oemlock/aidl/Android.bp
index 1c19bb1..f4533ed 100644
--- a/oemlock/aidl/Android.bp
+++ b/oemlock/aidl/Android.bp
@@ -10,6 +10,7 @@
aidl_interface {
name: "android.hardware.oemlock",
vendor_available: true,
+ frozen: true,
srcs: ["android/hardware/oemlock/*.aidl"],
stability: "vintf",
backend: {
diff --git a/radio/aidl/android/hardware/radio/config/IRadioConfig.aidl b/radio/aidl/android/hardware/radio/config/IRadioConfig.aidl
index 8f4dff4..936315c 100644
--- a/radio/aidl/android/hardware/radio/config/IRadioConfig.aidl
+++ b/radio/aidl/android/hardware/radio/config/IRadioConfig.aidl
@@ -17,9 +17,10 @@
* This interface is used by telephony and telecom to talk to cellular radio for the purpose of
* radio configuration, and it is not associated with any specific modem or slot.
* All the functions have minimum one parameter:
- * serial: which corresponds to serial no. of request. Serial numbers must only be memorized for the
- * duration of a method call. If clients provide colliding serials (including passing the same
- * serial to different methods), multiple responses (one for each method call) must still be served.
+ * serial: which corresponds to the serial number of the request. Serial numbers must only be
+ * memorized for the duration of a method call. If clients provide colliding serials (including
+ * passing the same serial to different methods), multiple responses (one for each method call) must
+ * still be served.
*/
package android.hardware.radio.config;
@@ -108,12 +109,12 @@
/**
* Set preferred data modem Id.
- * In a multi-SIM device, notify modem layer which logical modem will be used primarily
- * for data. It helps modem with resource optimization and decisions of what data connections
- * should be satisfied.
+ * In a multi-SIM device, notify the modem layer which logical modem will be used primarily
+ * for data. It helps the modem with resource optimization and decisions of what data
+ * connections should be satisfied.
*
* @param serial Serial number of request.
- * @param modem Id the logical modem ID, which should match one of modem IDs returned
+ * @param modemId the logical modem ID which should match one of the modem IDs returned
* from getPhoneCapability().
*
* Response callback is IRadioConfigResponse.setPreferredDataModemResponse()
@@ -136,30 +137,30 @@
/**
* Set SIM Slot mapping.
*
- * Maps the logical slots to the SlotPortMapping which consist of both physical slot id and port
- * id. Logical slot is the slot that is seen by modem. Physical slot is the actual physical
- * slot. PortId is the id (enumerated value) for the associated port available on the SIM. Each
- * physical slot can have multiple ports which enables multi-enabled profile(MEP). If eUICC
- * physical slot supports 2 ports, then the portId is numbered 0,1 and if eUICC2 supports 4
- * ports then the portID is numbered 0,1,2,3. Each portId is unique within a UICC physical slot
- * but not necessarily unique across UICC’s. SEP(Single enabled profile) eUICC and non-eUICC
- * will only have portId 0.
+ * Maps the logical slots to the SlotPortMapping, which consists of both physical slot id and
+ * port id. Logical slot is the slot that is seen by the modem. Physical slot is the actual
+ * physical slot. PortId is the id (enumerated value) for the associated port available on the
+ * SIM. Each physical slot can have multiple ports, which enables multi-enabled profile(MEP). If
+ * eUICC physical slot supports 2 ports, then the portId is numbered 0,1 and if eUICC2 supports
+ * 4 ports then the portID is numbered 0,1,2,3. Each portId is unique within a UICC physical
+ * slot but not necessarily unique across UICC’s. SEP(Single enabled profile) eUICC and
+ * non-eUICC will only have portId 0.
*
* Logical slots that are already mapped to the requested SlotPortMapping are not impacted.
*
- * Example no. of logical slots 1 and physical slots 2 do not support MEP, each physical slot
- * has one port:
- * The only logical slot (index 0) can be mapped to first physical slot (value 0), port(index
- * 0). or second
- * physical slot(value 1), port (index 0), while the other physical slot remains unmapped and
- * inactive.
+ * Example: There is 1 logical slot, 2 physical slots, MEP is not supported and each physical
+ * slot has one port:
+ * The only logical slot (index 0) can be mapped to the first physical slot (value 0),
+ * port(index 0), or second physical slot(value 1), port (index 0), while the other physical
+ * slot remains unmapped and inactive.
* slotMap[0] = SlotPortMapping{0 //physical slot//, 0 //port//}
* slotMap[0] = SlotPortMapping{1 //physical slot//, 0 //port//}
*
- * Example no. of logical slots 2 and physical slots 2 supports MEP with 2 ports available:
- * Each logical slot must be mapped to a port (physical slot and port combination).
- * First logical slot (index 0) can be mapped to physical slot 1 and the second logical slot
- * can be mapped to either port from physical slot 2.
+ * Example: There are 2 logical slots, 2 physical slots, MEP is supported and there are 2 ports
+ * available:
+ * Each logical slot must be mapped to a port (physical slot and port combination). The first
+ * logical slot (index 0) can be mapped to the physical slot 1 and the second logical slot can
+ * be mapped to either port from physical slot 2.
*
* slotMap[0] = SlotPortMapping{0, 0} and slotMap[1] = SlotPortMapping{1, 0} or
* slotMap[0] = SlotPortMapping{0, 0} and slotMap[1] = SlotPortMapping{1, 1}
@@ -178,10 +179,10 @@
*
* @param serial Serial number of request
* @param slotMap Logical to physical slot and port mapping.
- * Index is mapping to logical slot and value to physical slot and port id, need to
- * provide all the slots mapping when sending request in case of multi slot device.
+ * The index maps to the logical slot, and the value to the physical slot and port id. In
+ * the case of a multi-slot device, provide all the slot mappings when sending a request.
*
- * EX: SlotPortMapping(physical slot, port id)
+ * Example: SlotPortMapping(physical slot, port id)
* index 0 is the first logical_slot number of logical slots is equal to number of Radio
* instances and number of physical slots is equal to size of slotStatus in
* getSimSlotsStatusResponse
diff --git a/radio/aidl/android/hardware/radio/config/IRadioConfigIndication.aidl b/radio/aidl/android/hardware/radio/config/IRadioConfigIndication.aidl
index 9eacb8e..0b60dbb 100644
--- a/radio/aidl/android/hardware/radio/config/IRadioConfigIndication.aidl
+++ b/radio/aidl/android/hardware/radio/config/IRadioConfigIndication.aidl
@@ -27,9 +27,9 @@
/**
* Indicates SIM slot status change.
*
- * This indication must be sent by the modem whenever there is any slot status change, even the
- * slot is inactive. For example, this indication must be triggered if a SIM card is inserted
- * into an inactive slot.
+ * This indication must be sent by the modem whenever there is any slot status change, even if
+ * the slot is inactive. For example, this indication must be triggered if a SIM card is
+ * inserted into an inactive slot.
*
* @param type Type of radio indication
* @param slotStatus new slot status info with size equals to the number of physical slots on
@@ -39,7 +39,7 @@
in android.hardware.radio.RadioIndicationType type, in SimSlotStatus[] slotStatus);
/**
- * The logical slots supporting simultaneous cellular calling has changed.
+ * The logical slots supporting simultaneous cellular calling have changed.
*
* @param enabledLogicalSlots The slots that have simultaneous cellular calling enabled. If
* there is a call active on logical slot X, then a simultaneous cellular call is only possible
diff --git a/radio/aidl/android/hardware/radio/config/IRadioConfigResponse.aidl b/radio/aidl/android/hardware/radio/config/IRadioConfigResponse.aidl
index 33b0ff0..8182cd1 100644
--- a/radio/aidl/android/hardware/radio/config/IRadioConfigResponse.aidl
+++ b/radio/aidl/android/hardware/radio/config/IRadioConfigResponse.aidl
@@ -26,18 +26,18 @@
@VintfStability
oneway interface IRadioConfigResponse {
/**
- * @param info Response info struct containing response type, serial no. and error
+ * @param info Response info struct containing response type, serial number and error
* @param modemReducedFeatureSet1 True indicates that the modem does NOT support the following
- * features.
- * - Providing either LinkCapacityEstimate:secondaryDownlinkCapacityKbps
- * or LinkCapacityEstimate:secondaryUplinkCapacityKbps when given from
- * RadioIndication:currentLinkCapacityEstimate
- * - Calling IRadio.setNrDualConnectivityState or querying
- * IRadio.isNrDualConnectivityEnabled
- * - Requesting IRadio.setDataThrottling()
- * - Providing SlicingConfig through getSlicingConfig()
+ * features:
+ * - Providing either LinkCapacityEstimate#secondaryDownlinkCapacityKbps
+ * or LinkCapacityEstimate#secondaryUplinkCapacityKbps when given from
+ * IRadioNetworkIndication#currentLinkCapacityEstimate
+ * - Calling IRadioNetwork#setNrDualConnectivityState or querying
+ * IRadioNetwork#isNrDualConnectivityEnabled
+ * - Requesting IRadioData#setDataThrottling
+ * - Providing SlicingConfig through IRadioData#getSlicingConfig
* - Providing PhysicalChannelConfig through
- * IRadioIndication.currentPhysicalChannelConfigs_1_6()
+ * IRadioNetworkIndication#currentPhysicalChannelConfigs
*
* Valid errors returned:
* RadioError:REQUEST_NOT_SUPPORTED when android.hardware.telephony is not defined
@@ -49,7 +49,7 @@
in android.hardware.radio.RadioResponseInfo info, in boolean modemReducedFeatureSet1);
/**
- * @param info Response info struct containing response type, serial no. and error
+ * @param info Response info struct containing response type, serial number and error
* @param numOfLiveModems <byte> indicate the number of live modems i.e. modems that
* are enabled and actively working as part of a working connectivity stack
*
@@ -62,8 +62,8 @@
in android.hardware.radio.RadioResponseInfo info, in byte numOfLiveModems);
/**
- * @param info Response info struct containing response type, serial no. and error
- * @param phoneCapability <PhoneCapability> it defines modem's capability for example
+ * @param info Response info struct containing response type, serial number and error
+ * @param phoneCapability <PhoneCapability> it defines the modem's capability. For example,
* how many logical modems it has, how many data connections it supports.
*
* Valid errors returned:
@@ -76,7 +76,7 @@
in android.hardware.radio.RadioResponseInfo info, in PhoneCapability phoneCapability);
/**
- * @param info Response info struct containing response type, serial no. and error
+ * @param info Response info struct containing response type, serial number and error
* @param slotStatus Sim slot struct containing all the physical SIM slots info with size
* equal to the number of physical slots on the device
*
@@ -93,7 +93,7 @@
in android.hardware.radio.RadioResponseInfo info, in SimSlotStatus[] slotStatus);
/**
- * @param info Response info struct containing response type, serial no. and error
+ * @param info Response info struct containing response type, serial number and error
*
* Valid errors returned:
* RadioError:REQUEST_NOT_SUPPORTED when android.hardware.telephony is not defined
@@ -104,7 +104,7 @@
void setNumOfLiveModemsResponse(in android.hardware.radio.RadioResponseInfo info);
/**
- * @param info Response info struct containing response type, serial no. and error
+ * @param info Response info struct containing response type, serial number and error
*
* Valid errors returned:
* RadioError:REQUEST_NOT_SUPPORTED when android.hardware.telephony.data is not defined
@@ -116,7 +116,7 @@
void setPreferredDataModemResponse(in android.hardware.radio.RadioResponseInfo info);
/**
- * @param info Response info struct containing response type, serial no. and error
+ * @param info Response info struct containing response type, serial number and error
*
* Valid errors returned:
* RadioError:REQUEST_NOT_SUPPORTED when android.hardware.telephony.subscription is not
@@ -134,7 +134,7 @@
* Response to the asynchronous
* {@link IRadioConfig#getSimultaneousCallingSupport} request.
*
- * @param info Response info struct containing response type, serial no. and error
+ * @param info Response info struct containing response type, serial number and error
* @param enabledLogicalSlots The slots that have simultaneous cellular calling enabled. If
* there is a call active on logical slot X, then a simultaneous cellular call is only possible
* on logical slot Y if BOTH slot X and slot Y are in enabledLogicalSlots. If simultaneous
diff --git a/radio/aidl/android/hardware/radio/config/PhoneCapability.aidl b/radio/aidl/android/hardware/radio/config/PhoneCapability.aidl
index 7936eb6..265ab96 100644
--- a/radio/aidl/android/hardware/radio/config/PhoneCapability.aidl
+++ b/radio/aidl/android/hardware/radio/config/PhoneCapability.aidl
@@ -17,8 +17,8 @@
package android.hardware.radio.config;
/**
- * Phone capability which describes the data connection capability of modem.
- * It's used to evaluate possible phone config change, for example from single
+ * Phone capability which describes the data connection capability of the modem.
+ * It's used to evaluate a possible phone config change, for example, from single
* SIM device to multi-SIM device.
* @hide
*/
@@ -27,21 +27,18 @@
parcelable PhoneCapability {
const byte UNKNOWN = -1;
/**
- * maxActiveData defines how many logical modems can have
- * PS attached simultaneously. For example, for L+L modem it
- * should be 2.
+ * maxActiveData defines how many logical modems can have PS attached simultaneously. For
+ * example, for a L+L modem, it should be 2.
*/
byte maxActiveData;
/**
- * maxActiveData defines how many logical modems can have
- * internet PDN connections simultaneously. For example, for L+L
- * DSDS modem it’s 1, and for DSDA modem it’s 2.
+ * maxActiveInternetData defines how many logical modems can have internet PDN connections
+ * simultaneously. For example, for a L+L DSDS modem, it’s 1, and for a DSDA modem, it’s 2.
*/
byte maxActiveInternetData;
/**
- * Whether modem supports both internet PDN up so
- * that we can do ping test before tearing down the
- * other one.
+ * Whether the modem supports both internet PDNs up, so that we can do a ping test on one PDN
+ * before tearing down the other PDN.
*/
boolean isInternetLingeringSupported;
/**
@@ -49,9 +46,8 @@
*/
byte[] logicalModemIds;
/**
- * maxActiveVoice defines how many logical modems can have
- * cellular voice calls simultaneously. For example, for cellular DSDA
- * with simultaneous calling support, it should be 2.
+ * maxActiveVoice defines how many logical modems can have cellular voice calls simultaneously.
+ * For example, for cellular DSDA with simultaneous calling support, it should be 2.
*/
byte maxActiveVoice = UNKNOWN;
}
diff --git a/radio/aidl/android/hardware/radio/config/SimPortInfo.aidl b/radio/aidl/android/hardware/radio/config/SimPortInfo.aidl
index f579639..380932e 100644
--- a/radio/aidl/android/hardware/radio/config/SimPortInfo.aidl
+++ b/radio/aidl/android/hardware/radio/config/SimPortInfo.aidl
@@ -21,8 +21,8 @@
@JavaDerive(toString=true)
parcelable SimPortInfo {
/**
- * Integrated Circuit Card IDentifier (ICCID) is unique identifier of the SIM card. File is
- * located in the SIM card at EFiccid (0x2FE2) as per ETSI 102.221. The ICCID is defined by
+ * Integrated Circuit Card IDentifier (ICCID) is the unique identifier of the SIM card. The file
+ * is located in the SIM card at EFiccid (0x2FE2) as per ETSI 102.221. The ICCID is defined by
* the ITU-T recommendation E.118 ISO/IEC 7816.
*
* This data is applicable only when cardState is CardStatus.STATE_PRESENT.
@@ -33,13 +33,13 @@
*/
String iccId;
/**
- * Logical slot id is identifier of the active slot
+ * The identifier of the active slot.
*/
int logicalSlotId;
/**
* Port active status in the slot.
- * Inactive means logical modem is no longer associated to the port.
- * Active means logical modem is associated to the port.
+ * Inactive means that the logical modem is no longer associated to the port.
+ * Active means that the logical modem is associated to the port.
*/
boolean portActive;
}
diff --git a/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl b/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl
index 34f98c5..171d97a 100644
--- a/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl
+++ b/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl
@@ -46,12 +46,12 @@
String eid;
/**
* PortInfo contains the ICCID, logical slot ID, and port state.
- * Cardstate has no relationship with whether the slot is active or inactive. Should always
- * report up at least 1 port otherwise the logicalSlotIndex and portActive info will be lost.
+ * Cardstate has no relationship with whether the slot is active or inactive. At least one port
+ * shall always be reported, otherwise the logicalSlotIndex and portActive info will be lost.
* For example, the pSIM can be removed, but the slot can still be active. In that case, the
* SIM_STATUS reported for the corresponding logical stack will show CARDSTATE_ABSENT.
- * Similarly, even if there is no profile enabled on the eSIM, that port can still be the
- * active port in the slot mapping.
+ * Similarly, even if there is no profile enabled on the eSIM, that port can still be the active
+ * port in the slot mapping.
*/
SimPortInfo[] portInfo;
/**
diff --git a/radio/aidl/vts/Android.bp b/radio/aidl/vts/Android.bp
index e83a7c1..9521068 100644
--- a/radio/aidl/vts/Android.bp
+++ b/radio/aidl/vts/Android.bp
@@ -25,6 +25,7 @@
cc_test {
name: "VtsHalRadioTargetTest",
defaults: [
+ "aconfig_lib_cc_shared_link.defaults",
"VtsHalTargetTestDefaults",
"use_libaidlvintf_gtest_helper_static",
],
diff --git a/rebootescrow/aidl/Android.bp b/rebootescrow/aidl/Android.bp
index 39aaa07..3d5b827 100644
--- a/rebootescrow/aidl/Android.bp
+++ b/rebootescrow/aidl/Android.bp
@@ -10,6 +10,7 @@
aidl_interface {
name: "android.hardware.rebootescrow",
vendor_available: true,
+ frozen: true,
srcs: [
"android/hardware/rebootescrow/IRebootEscrow.aidl",
],
diff --git a/secure_element/aidl/default/Android.bp b/secure_element/aidl/default/Android.bp
index b382822..6f5e5f7 100644
--- a/secure_element/aidl/default/Android.bp
+++ b/secure_element/aidl/default/Android.bp
@@ -55,6 +55,7 @@
prebuilts: [
"secure_element.rc",
"secure_element.xml",
- "android.hardware.se.omapi.ese.prebuilt.xml", // <feature>
+ // TODO (b/289193458): Add this back when access control is implemented for cuttlefish.
+ // "android.hardware.se.omapi.ese.prebuilt.xml", // <feature>
],
}
diff --git a/security/keymint/aidl/default/Android.bp b/security/keymint/aidl/default/Android.bp
index fbb6140..22a46ed 100644
--- a/security/keymint/aidl/default/Android.bp
+++ b/security/keymint/aidl/default/Android.bp
@@ -7,6 +7,24 @@
default_applicable_licenses: ["hardware_interfaces_license"],
}
+vintf_fragment {
+ name: "android.hardware.security.keymint-service.xml",
+ src: "android.hardware.security.keymint-service.xml",
+ vendor: true,
+}
+
+vintf_fragment {
+ name: "android.hardware.security.sharedsecret-service.xml",
+ src: "android.hardware.security.sharedsecret-service.xml",
+ vendor: true,
+}
+
+vintf_fragment {
+ name: "android.hardware.security.secureclock-service.xml",
+ src: "android.hardware.security.secureclock-service.xml",
+ vendor: true,
+}
+
// The following target has an insecure implementation of KeyMint where the
// trusted application (TA) code runs in-process alongside the HAL service
// code.
@@ -18,11 +36,6 @@
name: "android.hardware.security.keymint-service",
relative_install_path: "hw",
init_rc: ["android.hardware.security.keymint-service.rc"],
- vintf_fragments: [
- "android.hardware.security.keymint-service.xml",
- "android.hardware.security.sharedsecret-service.xml",
- "android.hardware.security.secureclock-service.xml",
- ],
vendor: true,
cflags: [
"-Wall",
@@ -51,6 +64,11 @@
required: [
"android.hardware.hardware_keystore.xml",
],
+ vintf_fragment_modules: [
+ "android.hardware.security.keymint-service.xml",
+ "android.hardware.security.sharedsecret-service.xml",
+ "android.hardware.security.secureclock-service.xml",
+ ],
}
// The following target has an insecure implementation of KeyMint where the
@@ -65,11 +83,6 @@
relative_install_path: "hw",
vendor: true,
init_rc: ["android.hardware.security.keymint-service.nonsecure.rc"],
- vintf_fragments: [
- "android.hardware.security.keymint-service.xml",
- "android.hardware.security.sharedsecret-service.xml",
- "android.hardware.security.secureclock-service.xml",
- ],
defaults: [
"keymint_use_latest_hal_aidl_rust",
],
@@ -87,6 +100,11 @@
required: [
"android.hardware.hardware_keystore.xml",
],
+ vintf_fragment_modules: [
+ "android.hardware.security.keymint-service.xml",
+ "android.hardware.security.sharedsecret-service.xml",
+ "android.hardware.security.secureclock-service.xml",
+ ],
}
prebuilt_etc {
diff --git a/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp b/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
index f669110..9e3e159 100644
--- a/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
+++ b/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
@@ -253,39 +253,14 @@
// Collection of valid attestation ID tags.
auto attestation_id_tags = AuthorizationSetBuilder();
- // Use ro.product.brand_for_attestation property for attestation if it is present else fallback
- // to ro.product.brand
- std::string prop_value =
- ::android::base::GetProperty("ro.product.brand_for_attestation", /* default= */ "");
- if (!prop_value.empty()) {
- add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_BRAND,
- "ro.product.brand_for_attestation");
- } else {
- add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_BRAND, "ro.product.brand");
- }
- add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_DEVICE, "ro.product.device");
- // Use ro.product.name_for_attestation property for attestation if it is present else fallback
- // to ro.product.name
- prop_value = ::android::base::GetProperty("ro.product.name_for_attestation", /* default= */ "");
- if (!prop_value.empty()) {
- add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_PRODUCT,
- "ro.product.name_for_attestation");
- } else {
- add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_PRODUCT, "ro.product.name");
- }
+
+ add_attestation_id(&attestation_id_tags, TAG_ATTESTATION_ID_BRAND, "brand");
+ add_attestation_id(&attestation_id_tags, TAG_ATTESTATION_ID_DEVICE, "device");
+ add_attestation_id(&attestation_id_tags, TAG_ATTESTATION_ID_PRODUCT, "name");
add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_SERIAL, "ro.serialno");
- add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_MANUFACTURER,
- "ro.product.manufacturer");
- // Use ro.product.model_for_attestation property for attestation if it is present else fallback
- // to ro.product.model
- prop_value =
- ::android::base::GetProperty("ro.product.model_for_attestation", /* default= */ "");
- if (!prop_value.empty()) {
- add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_MODEL,
- "ro.product.model_for_attestation");
- } else {
- add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_MODEL, "ro.product.model");
- }
+ add_attestation_id(&attestation_id_tags, TAG_ATTESTATION_ID_MANUFACTURER, "manufacturer");
+ add_attestation_id(&attestation_id_tags, TAG_ATTESTATION_ID_MODEL, "model");
+
vector<uint8_t> key_blob;
vector<KeyCharacteristics> key_characteristics;
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index c19ab11..cfe9fa7 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -2400,6 +2400,43 @@
return imei;
}
+std::optional<std::string> get_attestation_id(const char* prop) {
+ // The frameworks code (in AndroidKeyStoreKeyPairGeneratorSpi.java) populates device ID
+ // values from one of 3 places, so the same logic needs to be reproduced here so the tests
+ // check what's expected correctly.
+ //
+ // In order of preference, the properties checked are:
+ //
+ // 1) `ro.product.<device-id>_for_attestation`: This should only be set in special cases; in
+ // particular, AOSP builds for reference devices use a different value than the normal
+ // builds for the same device (e.g. model of "aosp_raven" instead of "raven").
+ ::android::String8 prop_name =
+ ::android::String8::format("ro.product.%s_for_attestation", prop);
+ std::string prop_value = ::android::base::GetProperty(prop_name.c_str(), /* default= */ "");
+ if (!prop_value.empty()) {
+ return prop_value;
+ }
+
+ // 2) `ro.product.vendor.<device-id>`: This property refers to the vendor code, and so is
+ // retained even in a GSI environment.
+ prop_name = ::android::String8::format("ro.product.vendor.%s", prop);
+ prop_value = ::android::base::GetProperty(prop_name.c_str(), /* default= */ "");
+ if (!prop_value.empty()) {
+ return prop_value;
+ }
+
+ // 3) `ro.product.<device-id>`: Note that this property is replaced by a default value when
+ // running a GSI environment, and so will *not* match the value expected/used by the
+ // vendor code on the device.
+ prop_name = ::android::String8::format("ro.product.%s", prop);
+ prop_value = ::android::base::GetProperty(prop_name.c_str(), /* default= */ "");
+ if (!prop_value.empty()) {
+ return prop_value;
+ }
+
+ return std::nullopt;
+}
+
} // namespace test
} // namespace aidl::android::hardware::security::keymint
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
index 0368bba..85ae93d 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
@@ -17,6 +17,7 @@
#pragma once
#include <functional>
+#include <optional>
#include <string_view>
#include <aidl/Gtest.h>
@@ -384,14 +385,20 @@
const string& plaintext, const string& exp_cipher_text);
};
+// If the given string is non-empty, add it to the tag set under the given tag ID.
+template <Tag tag>
+void add_tag(AuthorizationSetBuilder* tags, TypedTag<TagType::BYTES, tag> ttag,
+ const std::string& prop_value) {
+ if (!prop_value.empty()) {
+ tags->Authorization(ttag, prop_value.data(), prop_value.size());
+ }
+}
+
// If the given property is available, add it to the tag set under the given tag ID.
template <Tag tag>
void add_tag_from_prop(AuthorizationSetBuilder* tags, TypedTag<TagType::BYTES, tag> ttag,
const char* prop) {
- std::string prop_value = ::android::base::GetProperty(prop, /* default= */ "");
- if (!prop_value.empty()) {
- tags->Authorization(ttag, prop_value.data(), prop_value.size());
- }
+ add_tag(tags, ttag, ::android::base::GetProperty(prop, /* default= */ ""));
}
// Return the VSR API level for this device.
@@ -431,6 +438,20 @@
std::optional<int32_t> keymint_feature_value(bool strongbox);
std::string get_imei(int slot);
+// Retrieve a device ID property value, to match what is expected in attestations.
+std::optional<std::string> get_attestation_id(const char* prop);
+
+// Add the appropriate attestation device ID tag value to the provided `AuthorizationSetBuilder`,
+// if found.
+template <Tag tag>
+void add_attestation_id(AuthorizationSetBuilder* attestation_id_tags,
+ TypedTag<TagType::BYTES, tag> tag_type, const char* prop) {
+ auto prop_value = get_attestation_id(prop);
+ if (prop_value.has_value()) {
+ add_tag(attestation_id_tags, tag_type, prop_value.value());
+ }
+}
+
AuthorizationSet HwEnforcedAuthorizations(const vector<KeyCharacteristics>& key_characteristics);
AuthorizationSet SwEnforcedAuthorizations(const vector<KeyCharacteristics>& key_characteristics);
::testing::AssertionResult ChainSignaturesAreValid(const vector<Certificate>& chain,
@@ -444,29 +465,6 @@
::android::PrintInstanceNameToString); \
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(name);
-// Use `ro.product.<property>_for_attestation` property for attestation if it is present else
-// fallback to use `ro.product.vendor.<property>` if it is present else fallback to
-// `ro.product.<property>`. Similar logic can be seen in Java method `getVendorDeviceIdProperty`
-// in frameworks/base/core/java/android/os/Build.java.
-template <Tag tag>
-void add_attestation_id(AuthorizationSetBuilder* attestation_id_tags,
- TypedTag<TagType::BYTES, tag> tag_type, const char* prop) {
- ::android::String8 prop_name =
- ::android::String8::format("ro.product.%s_for_attestation", prop);
- std::string prop_value = ::android::base::GetProperty(prop_name.c_str(), /* default= */ "");
- if (!prop_value.empty()) {
- add_tag_from_prop(attestation_id_tags, tag_type, prop_name.c_str());
- } else {
- prop_name = ::android::String8::format("ro.product.vendor.%s", prop);
- prop_value = ::android::base::GetProperty(prop_name.c_str(), /* default= */ "");
- if (!prop_value.empty()) {
- add_tag_from_prop(attestation_id_tags, tag_type, prop_name.c_str());
- } else {
- prop_name = ::android::String8::format("ro.product.%s", prop);
- add_tag_from_prop(attestation_id_tags, tag_type, prop_name.c_str());
- }
- }
-}
} // namespace test
} // namespace aidl::android::hardware::security::keymint
diff --git a/security/keymint/support/Android.bp b/security/keymint/support/Android.bp
index 5c9efef..608d328 100644
--- a/security/keymint/support/Android.bp
+++ b/security/keymint/support/Android.bp
@@ -40,6 +40,9 @@
export_include_dirs: [
"include",
],
+ header_libs: [
+ "libhardware_headers",
+ ],
defaults: [
"keymint_use_latest_hal_aidl_ndk_shared",
],
diff --git a/security/keymint/support/fuzzer/keymint_attestation_fuzzer.cpp b/security/keymint/support/fuzzer/keymint_attestation_fuzzer.cpp
index bd781ac..1757997 100644
--- a/security/keymint/support/fuzzer/keymint_attestation_fuzzer.cpp
+++ b/security/keymint/support/fuzzer/keymint_attestation_fuzzer.cpp
@@ -151,7 +151,7 @@
extern "C" int LLVMFuzzerInitialize(int /* *argc */, char /* ***argv */) {
::ndk::SpAIBinder binder(AServiceManager_waitForService(kServiceName.c_str()));
- gKeyMint = std::move(IKeyMintDevice::fromBinder(binder));
+ gKeyMint = IKeyMintDevice::fromBinder(binder);
LOG_ALWAYS_FATAL_IF(!gKeyMint, "Failed to get IKeyMintDevice instance.");
return 0;
}
diff --git a/security/keymint/support/include/remote_prov/remote_prov_utils.h b/security/keymint/support/include/remote_prov/remote_prov_utils.h
index 1d7db6a..141f243 100644
--- a/security/keymint/support/include/remote_prov/remote_prov_utils.h
+++ b/security/keymint/support/include/remote_prov/remote_prov_utils.h
@@ -21,6 +21,7 @@
#include <vector>
#include "aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.h"
+#include <hwtrust/hwtrust.h>
#include <keymaster/cppcose/cppcose.h>
namespace aidl::android::hardware::security::keymint::remote_prov {
@@ -167,7 +168,8 @@
const DeviceInfo& deviceInfo, const cppbor::Array& keysToSign,
const std::vector<uint8_t>& keysToSignMac, const ProtectedData& protectedData,
const EekChain& eekChain, const std::vector<uint8_t>& eekId, int32_t supportedEekCurve,
- IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge);
+ IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge,
+ bool allowAnyMode = false);
/**
* Verify the CSR as if the device is still early in the factory process and may not
@@ -175,15 +177,22 @@
*/
ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyFactoryCsr(
const cppbor::Array& keysToSign, const std::vector<uint8_t>& csr,
- IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge);
+ IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge,
+ bool allowDegenerate = true);
/**
* Verify the CSR as if the device is a final production sample.
*/
ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyProductionCsr(
const cppbor::Array& keysToSign, const std::vector<uint8_t>& csr,
- IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge);
+ IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge,
+ bool allowAnyMode = false);
/** Checks whether the CSR has a proper DICE chain. */
ErrMsgOr<bool> isCsrWithProperDiceChain(const std::vector<uint8_t>& csr);
+/** Verify the DICE chain. */
+ErrMsgOr<std::vector<BccEntryData>> validateBcc(const cppbor::Array* bcc,
+ hwtrust::DiceChain::Kind kind, bool allowAnyMode,
+ bool allowDegenerate);
+
} // namespace aidl::android::hardware::security::keymint::remote_prov
diff --git a/security/keymint/support/remote_prov_utils.cpp b/security/keymint/support/remote_prov_utils.cpp
index 6638775..a679340 100644
--- a/security/keymint/support/remote_prov_utils.cpp
+++ b/security/keymint/support/remote_prov_utils.cpp
@@ -26,7 +26,6 @@
#include <android-base/macros.h>
#include <android-base/properties.h>
#include <cppbor.h>
-#include <hwtrust/hwtrust.h>
#include <json/json.h>
#include <keymaster/km_openssl/ec_key.h>
#include <keymaster/km_openssl/ecdsa_operation.h>
@@ -325,10 +324,23 @@
}
ErrMsgOr<std::vector<BccEntryData>> validateBcc(const cppbor::Array* bcc,
- hwtrust::DiceChain::Kind kind) {
+ hwtrust::DiceChain::Kind kind, bool allowAnyMode,
+ bool allowDegenerate) {
auto encodedBcc = bcc->encode();
- auto chain = hwtrust::DiceChain::Verify(encodedBcc, kind);
+
+ // Use ro.build.type instead of ro.debuggable because ro.debuggable=1 for VTS testing
+ std::string build_type = ::android::base::GetProperty("ro.build.type", "");
+ if (!build_type.empty() && build_type != "user") {
+ allowAnyMode = true;
+ }
+
+ auto chain = hwtrust::DiceChain::Verify(encodedBcc, kind, allowAnyMode);
if (!chain.ok()) return chain.error().message();
+
+ if (!allowDegenerate && !chain->IsProper()) {
+ return "DICE chain is degenerate";
+ }
+
auto keys = chain->CosePublicKeys();
if (!keys.ok()) return keys.error().message();
std::vector<BccEntryData> result;
@@ -638,7 +650,7 @@
const std::vector<uint8_t>& keysToSignMac, const ProtectedData& protectedData,
const EekChain& eekChain, const std::vector<uint8_t>& eekId, int32_t supportedEekCurve,
IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge,
- bool isFactory) {
+ bool isFactory, bool allowAnyMode = false) {
auto [parsedProtectedData, _, protDataErrMsg] = cppbor::parse(protectedData.protectedData);
if (!parsedProtectedData) {
return protDataErrMsg;
@@ -694,7 +706,8 @@
}
// BCC is [ pubkey, + BccEntry]
- auto bccContents = validateBcc(bcc->asArray(), hwtrust::DiceChain::Kind::kVsr13);
+ auto bccContents = validateBcc(bcc->asArray(), hwtrust::DiceChain::Kind::kVsr13, allowAnyMode,
+ /*allowDegenerate=*/true);
if (!bccContents) {
return bccContents.message() + "\n" + prettyPrint(bcc.get());
}
@@ -747,10 +760,11 @@
const DeviceInfo& deviceInfo, const cppbor::Array& keysToSign,
const std::vector<uint8_t>& keysToSignMac, const ProtectedData& protectedData,
const EekChain& eekChain, const std::vector<uint8_t>& eekId, int32_t supportedEekCurve,
- IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge) {
+ IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge,
+ bool allowAnyMode) {
return verifyProtectedData(deviceInfo, keysToSign, keysToSignMac, protectedData, eekChain,
eekId, supportedEekCurve, provisionable, challenge,
- /*isFactory=*/false);
+ /*isFactory=*/false, allowAnyMode);
}
ErrMsgOr<X509_Ptr> parseX509Cert(const std::vector<uint8_t>& cert) {
@@ -974,20 +988,23 @@
ErrMsgOr<hwtrust::DiceChain::Kind> getDiceChainKind() {
int vendor_api_level = ::android::base::GetIntProperty("ro.vendor.api_level", -1);
- switch (vendor_api_level) {
- case __ANDROID_API_T__:
- return hwtrust::DiceChain::Kind::kVsr13;
- case __ANDROID_API_U__:
- return hwtrust::DiceChain::Kind::kVsr14;
- case 202404: /* TODO(b/315056516) Use a version macro for vendor API 24Q2 */
- return hwtrust::DiceChain::Kind::kVsr15;
- default:
- return "Unsupported vendor API level: " + std::to_string(vendor_api_level);
+ if (vendor_api_level == __ANDROID_API_T__) {
+ return hwtrust::DiceChain::Kind::kVsr13;
+ } else if (vendor_api_level == __ANDROID_API_U__) {
+ return hwtrust::DiceChain::Kind::kVsr14;
+ } else if (vendor_api_level == 202404) {
+ return hwtrust::DiceChain::Kind::kVsr15;
+ } else if (vendor_api_level > 202404) {
+ return hwtrust::DiceChain::Kind::kVsr16;
+ } else {
+ return "Unsupported vendor API level: " + std::to_string(vendor_api_level);
}
}
ErrMsgOr<bytevec> parseAndValidateAuthenticatedRequest(const std::vector<uint8_t>& request,
- const std::vector<uint8_t>& challenge) {
+ const std::vector<uint8_t>& challenge,
+ bool allowAnyMode = false,
+ bool allowDegenerate = true) {
auto [parsedRequest, _, csrErrMsg] = cppbor::parse(request);
if (!parsedRequest) {
return csrErrMsg;
@@ -1025,19 +1042,20 @@
return diceChainKind.message();
}
- auto diceContents = validateBcc(diceCertChain, *diceChainKind);
+ auto diceContents = validateBcc(diceCertChain, *diceChainKind, allowAnyMode, allowDegenerate);
if (!diceContents) {
return diceContents.message() + "\n" + prettyPrint(diceCertChain);
}
- auto& udsPub = diceContents->back().pubKey;
+ auto udsPub = diceCertChain->get(0)->asMap()->encode();
+ auto& kmDiceKey = diceContents->back().pubKey;
auto error = validateUdsCerts(*udsCerts, udsPub);
if (!error.empty()) {
return error;
}
- auto signedPayload = verifyAndParseCoseSign1(signedData, udsPub, {} /* aad */);
+ auto signedPayload = verifyAndParseCoseSign1(signedData, kmDiceKey, {} /* aad */);
if (!signedPayload) {
return signedPayload.message();
}
@@ -1054,7 +1072,8 @@
const std::vector<uint8_t>& csr,
IRemotelyProvisionedComponent* provisionable,
const std::vector<uint8_t>& challenge,
- bool isFactory) {
+ bool isFactory, bool allowAnyMode = false,
+ bool allowDegenerate = true) {
RpcHardwareInfo info;
provisionable->getHardwareInfo(&info);
if (info.versionNumber != 3) {
@@ -1062,7 +1081,8 @@
") does not match expected version (3).";
}
- auto csrPayload = parseAndValidateAuthenticatedRequest(csr, challenge);
+ auto csrPayload =
+ parseAndValidateAuthenticatedRequest(csr, challenge, allowAnyMode, allowDegenerate);
if (!csrPayload) {
return csrPayload.message();
}
@@ -1072,14 +1092,17 @@
ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyFactoryCsr(
const cppbor::Array& keysToSign, const std::vector<uint8_t>& csr,
- IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge) {
- return verifyCsr(keysToSign, csr, provisionable, challenge, /*isFactory=*/true);
+ IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge,
+ bool allowDegenerate) {
+ return verifyCsr(keysToSign, csr, provisionable, challenge, /*isFactory=*/true,
+ /*allowAnyMode=*/false, allowDegenerate);
}
ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyProductionCsr(
const cppbor::Array& keysToSign, const std::vector<uint8_t>& csr,
- IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge) {
- return verifyCsr(keysToSign, csr, provisionable, challenge, /*isFactory=*/false);
+ IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge,
+ bool allowAnyMode) {
+ return verifyCsr(keysToSign, csr, provisionable, challenge, /*isFactory=*/false, allowAnyMode);
}
ErrMsgOr<bool> isCsrWithProperDiceChain(const std::vector<uint8_t>& csr) {
@@ -1113,7 +1136,8 @@
}
auto encodedDiceChain = diceCertChain->encode();
- auto chain = hwtrust::DiceChain::Verify(encodedDiceChain, *diceChainKind);
+ auto chain =
+ hwtrust::DiceChain::Verify(encodedDiceChain, *diceChainKind, /*allowAnyMode=*/false);
if (!chain.ok()) return chain.error().message();
return chain->IsProper();
}
diff --git a/security/keymint/support/remote_prov_utils_test.cpp b/security/keymint/support/remote_prov_utils_test.cpp
index 89469f1..82121cb 100644
--- a/security/keymint/support/remote_prov_utils_test.cpp
+++ b/security/keymint/support/remote_prov_utils_test.cpp
@@ -41,6 +41,41 @@
using ::testing::ElementsAreArray;
using byte_view = std::span<const uint8_t>;
+inline const std::vector<uint8_t> kDegenerateBcc{
+ 0x82, 0xa5, 0x01, 0x01, 0x03, 0x27, 0x04, 0x81, 0x02, 0x20, 0x06, 0x21, 0x58, 0x20, 0xf5,
+ 0x5a, 0xfb, 0x28, 0x06, 0x48, 0x68, 0xea, 0x49, 0x3e, 0x47, 0x80, 0x1d, 0xfe, 0x1f, 0xfc,
+ 0xa8, 0x84, 0xb3, 0x4d, 0xdb, 0x99, 0xc7, 0xbf, 0x23, 0x53, 0xe5, 0x71, 0x92, 0x41, 0x9b,
+ 0x46, 0x84, 0x43, 0xa1, 0x01, 0x27, 0xa0, 0x59, 0x01, 0x75, 0xa9, 0x01, 0x78, 0x28, 0x31,
+ 0x64, 0x34, 0x35, 0x65, 0x33, 0x35, 0x63, 0x34, 0x35, 0x37, 0x33, 0x31, 0x61, 0x32, 0x62,
+ 0x34, 0x35, 0x36, 0x37, 0x63, 0x33, 0x63, 0x65, 0x35, 0x31, 0x36, 0x66, 0x35, 0x63, 0x31,
+ 0x66, 0x34, 0x33, 0x61, 0x62, 0x64, 0x36, 0x30, 0x62, 0x02, 0x78, 0x28, 0x31, 0x64, 0x34,
+ 0x35, 0x65, 0x33, 0x35, 0x63, 0x34, 0x35, 0x37, 0x33, 0x31, 0x61, 0x32, 0x62, 0x34, 0x35,
+ 0x36, 0x37, 0x63, 0x33, 0x63, 0x65, 0x35, 0x31, 0x36, 0x66, 0x35, 0x63, 0x31, 0x66, 0x34,
+ 0x33, 0x61, 0x62, 0x64, 0x36, 0x30, 0x62, 0x3a, 0x00, 0x47, 0x44, 0x50, 0x58, 0x40, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x3a, 0x00, 0x47, 0x44, 0x53, 0x41, 0xa0, 0x3a, 0x00, 0x47, 0x44, 0x52,
+ 0x58, 0x40, 0x71, 0xd7, 0x47, 0x9e, 0x61, 0xb5, 0x30, 0xa3, 0xda, 0xe6, 0xac, 0xb2, 0x91,
+ 0xa4, 0xf9, 0xcf, 0x7f, 0xba, 0x6b, 0x5f, 0xf9, 0xa3, 0x7f, 0xba, 0xab, 0xac, 0x69, 0xdd,
+ 0x0b, 0x04, 0xd6, 0x34, 0xd2, 0x3f, 0x8f, 0x84, 0x96, 0xd7, 0x58, 0x51, 0x1d, 0x68, 0x25,
+ 0xea, 0xbe, 0x11, 0x11, 0x1e, 0xd8, 0xdf, 0x4b, 0x62, 0x78, 0x5c, 0xa8, 0xfa, 0xb7, 0x66,
+ 0x4e, 0x8d, 0xac, 0x3b, 0x00, 0x4c, 0x3a, 0x00, 0x47, 0x44, 0x54, 0x58, 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3a, 0x00, 0x47, 0x44, 0x56, 0x41, 0x00, 0x3a, 0x00, 0x47, 0x44, 0x57, 0x58,
+ 0x2d, 0xa5, 0x01, 0x01, 0x03, 0x27, 0x04, 0x81, 0x02, 0x20, 0x06, 0x21, 0x58, 0x20, 0xf5,
+ 0x5a, 0xfb, 0x28, 0x06, 0x48, 0x68, 0xea, 0x49, 0x3e, 0x47, 0x80, 0x1d, 0xfe, 0x1f, 0xfc,
+ 0xa8, 0x84, 0xb3, 0x4d, 0xdb, 0x99, 0xc7, 0xbf, 0x23, 0x53, 0xe5, 0x71, 0x92, 0x41, 0x9b,
+ 0x46, 0x3a, 0x00, 0x47, 0x44, 0x58, 0x41, 0x20, 0x58, 0x40, 0x31, 0x5c, 0x43, 0x87, 0xf9,
+ 0xbb, 0xb9, 0x45, 0x09, 0xa8, 0xe8, 0x08, 0x70, 0xc4, 0xd9, 0xdc, 0x4e, 0x5a, 0x19, 0x10,
+ 0x4f, 0xa3, 0x21, 0x20, 0x34, 0x05, 0x5b, 0x2e, 0x78, 0x91, 0xd1, 0xe2, 0x39, 0x43, 0x8b,
+ 0x50, 0x12, 0x82, 0x37, 0xfe, 0xa4, 0x07, 0xc3, 0xd5, 0xc3, 0x78, 0xcc, 0xf9, 0xef, 0xe1,
+ 0x95, 0x38, 0x9f, 0xb0, 0x79, 0x16, 0x4c, 0x4a, 0x23, 0xc4, 0xdc, 0x35, 0x4e, 0x0f};
+
inline bool equal_byte_views(const byte_view& view1, const byte_view& view2) {
return std::equal(view1.begin(), view1.end(), view2.begin(), view2.end());
}
@@ -258,5 +293,14 @@
EXPECT_THAT(eekPubY, ElementsAreArray(geek->getBstrValue(CoseKey::PUBKEY_Y).value_or(empty)));
}
+TEST(RemoteProvUtilsTest, validateBccDegenerate) {
+ auto [bcc, _, errMsg] = cppbor::parse(kDegenerateBcc);
+ ASSERT_TRUE(bcc) << "Error: " << errMsg;
+
+ EXPECT_TRUE(validateBcc(bcc->asArray(), hwtrust::DiceChain::Kind::kVsr16,
+ /*allowAnyMode=*/false, /*allowDegenerate=*/true));
+ EXPECT_FALSE(validateBcc(bcc->asArray(), hwtrust::DiceChain::Kind::kVsr16,
+ /*allowAnyMode=*/false, /*allowDegenerate=*/false));
+}
} // namespace
} // namespace aidl::android::hardware::security::keymint::remote_prov
diff --git a/security/rkp/OWNERS b/security/rkp/OWNERS
index d25977f..8f854b4 100644
--- a/security/rkp/OWNERS
+++ b/security/rkp/OWNERS
@@ -2,4 +2,3 @@
jbires@google.com
sethmo@google.com
-trong@google.com
diff --git a/security/rkp/aidl/android/hardware/security/keymint/generateCertificateRequestV2.cddl b/security/rkp/aidl/android/hardware/security/keymint/generateCertificateRequestV2.cddl
index 3c43238..7a02ff5 100644
--- a/security/rkp/aidl/android/hardware/security/keymint/generateCertificateRequestV2.cddl
+++ b/security/rkp/aidl/android/hardware/security/keymint/generateCertificateRequestV2.cddl
@@ -62,9 +62,13 @@
SignerName = tstr
UdsCertChain = [
- 2* X509Certificate ; Root -> ... -> Leaf. "Root" is the vendor self-signed
- ; cert, "Leaf" contains UDS_Public. There may also be
- ; intermediate certificates between Root and Leaf.
+ + X509Certificate ; Root -> ... -> Leaf. "Root" is the vendor self-signed
+ ; cert, "Leaf" contains UDS_Pub. It's recommended to
+ ; have at least 3 certificates in the chain.
+ ; The Root certificate is recommended to be generated in an air-gapped,
+ ; HSM-based secure environment. The intermediate signing keys may be
+ ; online, and should be rotated regularly (e.g. annually). Additionally,
+ ; the intermediate certificates may contain product family identifiers.
]
; A bstr containing a DER-encoded X.509 certificate (RSA, NIST P-curve, or EdDSA)
@@ -73,7 +77,7 @@
; The DICE Chain contains measurements about the device firmware.
; The first entry in the DICE Chain is the UDS_Pub, encoded as a COSE_key. All entries
; after the first describe a link in the boot chain (e.g. bootloaders: BL1, BL2, ... BLN)
-; Note that there is no DiceChainEntry for UDS_pub, only a "bare" COSE_key.
+; Note that there is no DiceChainEntry for UDS_Pub, only a "bare" COSE_key.
DiceCertChain = [
PubKeyEd25519 / PubKeyECDSA256 / PubKeyECDSA384, ; UDS_Pub
+ DiceChainEntry, ; First CDI_Certificate -> Last CDI_Certificate
diff --git a/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp b/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
index 2dbc73f..f68ff91 100644
--- a/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
+++ b/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
@@ -188,7 +188,8 @@
}
ASSERT_NE(provisionable_, nullptr);
auto status = provisionable_->getHardwareInfo(&rpcHardwareInfo);
- if (GetParam() == RKP_VM_INSTANCE_NAME) {
+ isRkpVmInstance_ = GetParam() == RKP_VM_INSTANCE_NAME;
+ if (isRkpVmInstance_) {
if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
GTEST_SKIP() << "The RKP VM is not supported on this system.";
}
@@ -209,6 +210,7 @@
protected:
std::shared_ptr<IRemotelyProvisionedComponent> provisionable_;
RpcHardwareInfo rpcHardwareInfo;
+ bool isRkpVmInstance_;
};
/**
@@ -765,7 +767,8 @@
provisionable_->generateCertificateRequestV2({} /* keysToSign */, challenge, &csr);
ASSERT_TRUE(status.isOk()) << status.getDescription();
- auto result = verifyProductionCsr(cppbor::Array(), csr, provisionable_.get(), challenge);
+ auto result = verifyProductionCsr(cppbor::Array(), csr, provisionable_.get(), challenge,
+ isRkpVmInstance_);
ASSERT_TRUE(result) << result.message();
}
}
@@ -786,7 +789,8 @@
auto status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge, &csr);
ASSERT_TRUE(status.isOk()) << status.getDescription();
- auto result = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), challenge);
+ auto result = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), challenge,
+ isRkpVmInstance_);
ASSERT_TRUE(result) << result.message();
}
}
@@ -816,13 +820,15 @@
auto status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge_, &csr);
ASSERT_TRUE(status.isOk()) << status.getDescription();
- auto firstCsr = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), challenge_);
+ auto firstCsr = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), challenge_,
+ isRkpVmInstance_);
ASSERT_TRUE(firstCsr) << firstCsr.message();
status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge_, &csr);
ASSERT_TRUE(status.isOk()) << status.getDescription();
- auto secondCsr = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), challenge_);
+ auto secondCsr = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), challenge_,
+ isRkpVmInstance_);
ASSERT_TRUE(secondCsr) << secondCsr.message();
ASSERT_EQ(**firstCsr, **secondCsr);
@@ -840,7 +846,8 @@
auto status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge_, &csr);
ASSERT_TRUE(status.isOk()) << status.getDescription();
- auto result = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), challenge_);
+ auto result = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), challenge_,
+ isRkpVmInstance_);
ASSERT_TRUE(result) << result.message();
}
diff --git a/security/secureclock/aidl/Android.bp b/security/secureclock/aidl/Android.bp
index 853ad89..d7e7b43 100644
--- a/security/secureclock/aidl/Android.bp
+++ b/security/secureclock/aidl/Android.bp
@@ -10,6 +10,7 @@
aidl_interface {
name: "android.hardware.security.secureclock",
vendor_available: true,
+ frozen: true,
srcs: [
"android/hardware/security/secureclock/*.aidl",
],
diff --git a/security/sharedsecret/aidl/Android.bp b/security/sharedsecret/aidl/Android.bp
index fe77c10..adf33d3 100644
--- a/security/sharedsecret/aidl/Android.bp
+++ b/security/sharedsecret/aidl/Android.bp
@@ -10,6 +10,7 @@
aidl_interface {
name: "android.hardware.security.sharedsecret",
vendor_available: true,
+ frozen: true,
srcs: [
"android/hardware/security/sharedsecret/*.aidl",
],
diff --git a/soundtrigger/2.0/default/Android.bp b/soundtrigger/2.0/default/Android.bp
index 2cbf041..2e61f9b 100644
--- a/soundtrigger/2.0/default/Android.bp
+++ b/soundtrigger/2.0/default/Android.bp
@@ -46,3 +46,36 @@
"libhardware_headers",
],
}
+
+soong_config_module_type {
+ name: "soundtrigger_cc_library_shared",
+ module_type: "cc_library_shared",
+ config_namespace: "soundtrigger",
+ value_variables: [
+ "audioserver_multilib",
+ ],
+ properties: ["compile_multilib"],
+}
+
+soundtrigger_cc_library_shared {
+ name: "android.hardware.soundtrigger@2.0-impl",
+ vendor: true,
+ relative_install_path: "hw",
+ srcs: ["FetchISoundTriggerHw.cpp"],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+ shared_libs: [
+ "libhardware",
+ "libutils",
+ "android.hardware.soundtrigger@2.0",
+ "android.hardware.soundtrigger@2.0-core",
+ ],
+ compile_multilib: "32",
+ soong_config_variables: {
+ audioserver_multilib: {
+ compile_multilib: "%s",
+ },
+ },
+}
diff --git a/soundtrigger/2.0/default/Android.mk b/soundtrigger/2.0/default/Android.mk
deleted file mode 100644
index 17e4440..0000000
--- a/soundtrigger/2.0/default/Android.mk
+++ /dev/null
@@ -1,45 +0,0 @@
-#
-# Copyright (C) 2016 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.
-
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.soundtrigger@2.0-impl
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../../NOTICE
-LOCAL_VENDOR_MODULE := true
-LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_SRC_FILES := \
- FetchISoundTriggerHw.cpp
-
-LOCAL_CFLAGS := -Wall -Werror
-
-LOCAL_SHARED_LIBRARIES := \
- libhardware \
- libutils \
- android.hardware.soundtrigger@2.0 \
- android.hardware.soundtrigger@2.0-core
-
-LOCAL_C_INCLUDE_DIRS := $(LOCAL_PATH)
-
-ifeq ($(strip $(AUDIOSERVER_MULTILIB)),)
-LOCAL_MULTILIB := 32
-else
-LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
-endif
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/soundtrigger/2.1/default/Android.bp b/soundtrigger/2.1/default/Android.bp
new file mode 100644
index 0000000..a246680
--- /dev/null
+++ b/soundtrigger/2.1/default/Android.bp
@@ -0,0 +1,57 @@
+//
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+ // See: http://go/android-license-faq
+ default_applicable_licenses: [
+ "hardware_interfaces_license",
+ ],
+}
+
+soong_config_module_type_import {
+ from: "hardware/interfaces/soundtrigger/2.0/default/Android.bp",
+ module_types: ["soundtrigger_cc_library_shared"],
+}
+
+soundtrigger_cc_library_shared {
+ name: "android.hardware.soundtrigger@2.1-impl",
+ vendor: true,
+ relative_install_path: "hw",
+ srcs: ["SoundTriggerHw.cpp"],
+
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+
+ shared_libs: [
+ "libhardware",
+ "libhidlbase",
+ "libhidlmemory",
+ "liblog",
+ "libutils",
+ "android.hardware.soundtrigger@2.1",
+ "android.hardware.soundtrigger@2.0",
+ "android.hardware.soundtrigger@2.0-core",
+ "android.hidl.allocator@1.0",
+ "android.hidl.memory@1.0",
+ ],
+ compile_multilib: "32",
+ soong_config_variables: {
+ audioserver_multilib: {
+ compile_multilib: "%s",
+ },
+ },
+}
diff --git a/soundtrigger/2.1/default/Android.mk b/soundtrigger/2.1/default/Android.mk
deleted file mode 100644
index 602f5a7..0000000
--- a/soundtrigger/2.1/default/Android.mk
+++ /dev/null
@@ -1,51 +0,0 @@
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.soundtrigger@2.1-impl
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../../NOTICE
-LOCAL_VENDOR_MODULE := true
-LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_SRC_FILES := \
- SoundTriggerHw.cpp
-
-LOCAL_CFLAGS := -Wall -Werror
-
-LOCAL_SHARED_LIBRARIES := \
- libhardware \
- libhidlbase \
- libhidlmemory \
- liblog \
- libutils \
- android.hardware.soundtrigger@2.1 \
- android.hardware.soundtrigger@2.0 \
- android.hardware.soundtrigger@2.0-core \
- android.hidl.allocator@1.0 \
- android.hidl.memory@1.0
-
-LOCAL_C_INCLUDE_DIRS := $(LOCAL_PATH)
-
-ifeq ($(strip $(AUDIOSERVER_MULTILIB)),)
-LOCAL_MULTILIB := 32
-else
-LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
-endif
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/staging/security/see/hwcrypto/aidl/Android.bp b/staging/security/see/hwcrypto/aidl/Android.bp
index 3e7ee9e..0a7e8be 100644
--- a/staging/security/see/hwcrypto/aidl/Android.bp
+++ b/staging/security/see/hwcrypto/aidl/Android.bp
@@ -10,6 +10,8 @@
aidl_interface {
name: "android.hardware.security.see",
unstable: false,
+ // TODO Remove this owner field when this interface is moved out of /staging
+ owner: "google_while_staging",
host_supported: true,
srcs: [
"android/hardware/security/see/hwcrypto/*.aidl",
diff --git a/staging/security/see/storage/aidl/android/hardware/security/see/storage/FileAvailability.aidl b/staging/security/see/storage/aidl/android/hardware/security/see/storage/Availability.aidl
similarity index 97%
rename from staging/security/see/storage/aidl/android/hardware/security/see/storage/FileAvailability.aidl
rename to staging/security/see/storage/aidl/android/hardware/security/see/storage/Availability.aidl
index d339170..21a275c 100644
--- a/staging/security/see/storage/aidl/android/hardware/security/see/storage/FileAvailability.aidl
+++ b/staging/security/see/storage/aidl/android/hardware/security/see/storage/Availability.aidl
@@ -16,7 +16,7 @@
package android.hardware.security.see.storage;
/** Determines how early during the boot process file is able to be accessed. */
-enum FileAvailability {
+enum Availability {
/** Available before userdata is mounted, but after android has booted. */
BEFORE_USERDATA,
diff --git a/staging/security/see/storage/aidl/android/hardware/security/see/storage/DeleteOptions.aidl b/staging/security/see/storage/aidl/android/hardware/security/see/storage/DeleteOptions.aidl
deleted file mode 100644
index 1a94eb2..0000000
--- a/staging/security/see/storage/aidl/android/hardware/security/see/storage/DeleteOptions.aidl
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2024 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.hardware.security.see.storage;
-
-import android.hardware.security.see.storage.ReadIntegrity;
-
-parcelable DeleteOptions {
- /**
- * Set to acknowledge possible files tampering.
- *
- * If unacknowledged tampering is detected, the operation will fail with an ERR_FS_*
- * service-specific code.
- */
- ReadIntegrity readIntegrity = ReadIntegrity.NO_TAMPER;
-
- /**
- * Allow writes to succeed while the filesystem is in the middle of an A/B update.
- *
- * If the A/B update fails, the operation will be rolled back. This rollback will not
- * cause subsequent operations fail with any ERR_FS_* code nor will need to be
- * acknowledged by setting the `readIntegrity`.
- */
- boolean allowWritesDuringAbUpdate = false;
-}
diff --git a/staging/security/see/storage/aidl/android/hardware/security/see/storage/FileProperties.aidl b/staging/security/see/storage/aidl/android/hardware/security/see/storage/FileProperties.aidl
deleted file mode 100644
index 733b5b0..0000000
--- a/staging/security/see/storage/aidl/android/hardware/security/see/storage/FileProperties.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright 2024 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.hardware.security.see.storage;
-
-import android.hardware.security.see.storage.FileAvailability;
-import android.hardware.security.see.storage.FileIntegrity;
-
-parcelable FileProperties {
- FileIntegrity integrity = FileIntegrity.TAMPER_PROOF_AT_REST;
- FileAvailability availability = FileAvailability.BEFORE_USERDATA;
-
- /** Whether the file is reset when user data is wiped. */
- boolean persistent;
-}
diff --git a/staging/security/see/storage/aidl/android/hardware/security/see/storage/Filesystem.aidl b/staging/security/see/storage/aidl/android/hardware/security/see/storage/Filesystem.aidl
new file mode 100644
index 0000000..ea8db53
--- /dev/null
+++ b/staging/security/see/storage/aidl/android/hardware/security/see/storage/Filesystem.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2024 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.hardware.security.see.storage;
+
+import android.hardware.security.see.storage.Availability;
+import android.hardware.security.see.storage.Integrity;
+
+/**
+ * Specifies minimum security requirements for a Secure Storage filesystem.
+ */
+parcelable Filesystem {
+ Integrity integrity = Integrity.TAMPER_PROOF_AT_REST;
+ Availability availability = Availability.BEFORE_USERDATA;
+
+ /**
+ * Whether the file is reset on factory resets. Factory resets will not be reported as
+ * tampering.
+ */
+ boolean persistent;
+}
diff --git a/staging/security/see/storage/aidl/android/hardware/security/see/storage/IDir.aidl b/staging/security/see/storage/aidl/android/hardware/security/see/storage/IDir.aidl
index a0a9f3d..5d9a761 100644
--- a/staging/security/see/storage/aidl/android/hardware/security/see/storage/IDir.aidl
+++ b/staging/security/see/storage/aidl/android/hardware/security/see/storage/IDir.aidl
@@ -26,15 +26,15 @@
*
* @maxCount:
* the maximum number of filenames to return. A @maxCount of 0 signifies no limit on the
- * number of filenames returned.
+ * number of filenames returned.
*
* Returns:
* An ordered list of filenames. If @maxCount > 0, the length of the returned list will be
- * less than or equal to @maxCount.
+ * less than or equal to @maxCount.
*
* May return service-specific errors:
- * - ERR_FS_* if the filesystem has been tampered with in a way that the `readIntegrity` the
- * dir was opened with does not acknowledge
+ * - ERR_FS_* if the filesystem has been tampered with in a way that the session did not
+ * acknowledge
*/
@utf8InCpp String[] readNextFilenames(int maxCount);
}
diff --git a/staging/security/see/storage/aidl/android/hardware/security/see/storage/IFile.aidl b/staging/security/see/storage/aidl/android/hardware/security/see/storage/IFile.aidl
index ff26aa4..fd2032e 100644
--- a/staging/security/see/storage/aidl/android/hardware/security/see/storage/IFile.aidl
+++ b/staging/security/see/storage/aidl/android/hardware/security/see/storage/IFile.aidl
@@ -32,8 +32,8 @@
* the sequence of bytes at [offset, offset + size) in the file
*
* May return service-specific errors:
- * - ERR_FS_* if the filesystem has been tampered with in a way that the `readIntegrity` the
- * file was opened with does not acknowledge
+ * - ERR_FS_* if the filesystem has been tampered with in a way that the session did not
+ * acknowledge
*/
byte[] read(long size, long offset);
@@ -47,8 +47,8 @@
* the number of bytes written successfully
*
* May return service-specific errors:
- * - ERR_FS_* if the filesystem has been tampered with in a way that the `readIntegrity` the
- * file was opened with does not acknowledge
+ * - ERR_FS_* if the filesystem has been tampered with in a way that the session did not
+ * acknowledge
*/
long write(long offset, in byte[] buffer);
@@ -56,8 +56,8 @@
* Reads this file's size.
*
* May return service-specific errors:
- * - ERR_FS_* if the filesystem has been tampered with in a way that the `readIntegrity` the
- * file was opened with does not acknowledge
+ * - ERR_FS_* if the filesystem has been tampered with in a way that the session did not
+ * acknowledge
*/
long getSize();
@@ -71,8 +71,8 @@
* the file's new size
*
* May return service-specific errors:
- * - ERR_FS_* if the filesystem has been tampered with in a way that the `readIntegrity` the
- * file was opened with does not acknowledge
+ * - ERR_FS_* if the filesystem has been tampered with in a way that the session did not
+ * acknowledge
*/
void setSize(long newSize);
@@ -88,8 +88,8 @@
* - ERR_NOT_FOUND if no file exists at @destPath and @destCreateMode is `NO_CREATE`
* - ERR_ALREADY_EXISTS if a file already exists at @destPath and @destCreateMode is
* `CREATE_EXCLUSIVE`
- * - ERR_FS_* if the filesystem has been tampered with in a way that the `readIntegrity` the
- * file was opened with does not acknowledge
+ * - ERR_FS_* if the filesystem has been tampered with in a way that the session did not
+ * acknowledge
*/
void rename(in @utf8InCpp String destPath, in CreationMode destCreateMode);
}
diff --git a/staging/security/see/storage/aidl/android/hardware/security/see/storage/ISecureStorage.aidl b/staging/security/see/storage/aidl/android/hardware/security/see/storage/ISecureStorage.aidl
index be3c045..022de9a 100644
--- a/staging/security/see/storage/aidl/android/hardware/security/see/storage/ISecureStorage.aidl
+++ b/staging/security/see/storage/aidl/android/hardware/security/see/storage/ISecureStorage.aidl
@@ -15,7 +15,7 @@
*/
package android.hardware.security.see.storage;
-import android.hardware.security.see.storage.FileProperties;
+import android.hardware.security.see.storage.Filesystem;
import android.hardware.security.see.storage.IStorageSession;
/**
@@ -28,20 +28,18 @@
const int ERR_NOT_FOUND = 2;
const int ERR_ALREADY_EXISTS = 3;
const int ERR_BAD_TRANSACTION = 4;
-
- const int ERR_FS_RESET = 5;
- const int ERR_FS_ROLLED_BACK = 6;
- const int ERR_FS_TAMPERED = 7;
+ const int ERR_AB_UPDATE_IN_PROGRESS = 5;
+ const int ERR_FS_TAMPERED = 6;
/**
* Starts a storage session for a filesystem.
*
- * @properties:
- * the minimum filesystem properties requested for the session.
+ * @filesystem:
+ * The minimum filesystem properties requested.
*
* May return service-specific errors:
* - ERR_UNSUPPORTED_PROPERTIES if no filesystems exist which meet the minimum requested
- * requirements
+ * requirements
*/
- IStorageSession startSession(in FileProperties properties);
+ IStorageSession startSession(in Filesystem filesystem);
}
diff --git a/staging/security/see/storage/aidl/android/hardware/security/see/storage/IStorageSession.aidl b/staging/security/see/storage/aidl/android/hardware/security/see/storage/IStorageSession.aidl
index cd126b8..1b70a0e 100644
--- a/staging/security/see/storage/aidl/android/hardware/security/see/storage/IStorageSession.aidl
+++ b/staging/security/see/storage/aidl/android/hardware/security/see/storage/IStorageSession.aidl
@@ -15,12 +15,10 @@
*/
package android.hardware.security.see.storage;
-import android.hardware.security.see.storage.DeleteOptions;
+import android.hardware.security.see.storage.CreationMode;
import android.hardware.security.see.storage.IDir;
import android.hardware.security.see.storage.IFile;
import android.hardware.security.see.storage.OpenOptions;
-import android.hardware.security.see.storage.ReadIntegrity;
-import android.hardware.security.see.storage.RenameOptions;
/**
* Interface for a Secure Storage session
@@ -66,8 +64,8 @@
* May return service-specific errors:
* - ERR_NOT_FOUND
* - ERR_ALREADY_EXISTS
- * - ERR_FS_* if the filesystem has been tampered with in a way that @options.readIntegrity
- * does not acknowledge
+ * - ERR_FS_* if the filesystem has been tampered with in a way that the session did not
+ * acknowledge
*/
IFile openFile(in @utf8InCpp String filePath, in OpenOptions options);
@@ -81,10 +79,10 @@
*
* May return service-specific errors:
* - ERR_NOT_FOUND
- * - ERR_FS_* if the filesystem has been tampered with in a way that @options.readIntegrity
- * does not acknowledge
+ * - ERR_FS_* if the filesystem has been tampered with in a way that the session did not
+ * acknowledge
*/
- void deleteFile(in @utf8InCpp String filePath, in DeleteOptions options);
+ void deleteFile(in @utf8InCpp String filePath);
/**
* Renames an existing file.
@@ -95,19 +93,19 @@
* path to the file, relative to filesystem root
* @destPath:
* the file's new path, relative to filesystem root
- * @options:
- * options controlling rename behavior
+ * @destCreateMode:
+ * creation behavior for the dest file
*
* May return service-specific errors:
- * - ERR_NOT_FOUND if no file exists at @currentPath, or if @options.destCreateMode is
- * `NO_CREATE` and no file exists at @destPath
- * - ERR_ALREADY_EXISTS if @options.destCreateMode is `CREATE_EXCLUSIVE` and a file exists at
+ * - ERR_NOT_FOUND if no file exists at @currentPath, or if @destCreateMode is `NO_CREATE` and
+ * no file exists at @destPath
+ * - ERR_ALREADY_EXISTS if @destCreateMode is `CREATE_EXCLUSIVE` and a file exists at
* @destPath
- * - ERR_FS_* if the filesystem has been tampered with in a way that @options.readIntegrity
- * does not acknowledge
+ * - ERR_FS_* if the filesystem has been tampered with in a way that the session did not
+ * acknowledge
*/
void renameFile(in @utf8InCpp String currentPath, in @utf8InCpp String destPath,
- in RenameOptions options);
+ in CreationMode destCreateMode);
/**
* Opens a directory from a filesystem with the given properties.
@@ -116,14 +114,11 @@
*
* @path:
* path to the directory, relative to filesystem root
- * @readIntegrity:
- * allow opening (and subsequent read/write operations) despite possible tampering for the
- * directory
*
* May return service-specific errors:
* - ERR_NOT_FOUND
- * - ERR_FS_* if the filesystem has been tampered with in a way that @readIntegrity does not
+ * - ERR_FS_* if the filesystem has been tampered with in a way that the session did not
* acknowledge
*/
- IDir openDir(in @utf8InCpp String path, in ReadIntegrity readIntegrity);
+ IDir openDir(in @utf8InCpp String path);
}
diff --git a/staging/security/see/storage/aidl/android/hardware/security/see/storage/FileIntegrity.aidl b/staging/security/see/storage/aidl/android/hardware/security/see/storage/Integrity.aidl
similarity index 83%
rename from staging/security/see/storage/aidl/android/hardware/security/see/storage/FileIntegrity.aidl
rename to staging/security/see/storage/aidl/android/hardware/security/see/storage/Integrity.aidl
index 1879b16..2f7f7ab 100644
--- a/staging/security/see/storage/aidl/android/hardware/security/see/storage/FileIntegrity.aidl
+++ b/staging/security/see/storage/aidl/android/hardware/security/see/storage/Integrity.aidl
@@ -15,7 +15,7 @@
*/
package android.hardware.security.see.storage;
-enum FileIntegrity {
+enum Integrity {
/** REE may prevent operations, but cannot alter data once written. */
TAMPER_PROOF_AT_REST,
@@ -24,10 +24,4 @@
* an error on read.
*/
TAMPER_DETECT,
-
- /**
- * REE may alter written data. Changes other than full filesystem resets will be detected and
- * reported.
- */
- TAMPER_DETECT_IGNORE_RESET,
}
diff --git a/staging/security/see/storage/aidl/android/hardware/security/see/storage/OpenOptions.aidl b/staging/security/see/storage/aidl/android/hardware/security/see/storage/OpenOptions.aidl
index 997ca62..9fdf9e5 100644
--- a/staging/security/see/storage/aidl/android/hardware/security/see/storage/OpenOptions.aidl
+++ b/staging/security/see/storage/aidl/android/hardware/security/see/storage/OpenOptions.aidl
@@ -17,7 +17,6 @@
import android.hardware.security.see.storage.CreationMode;
import android.hardware.security.see.storage.FileMode;
-import android.hardware.security.see.storage.ReadIntegrity;
parcelable OpenOptions {
/** Controls creation behavior of the to-be-opened file. See `CreationMode` docs for details. */
@@ -27,25 +26,8 @@
FileMode accessMode = FileMode.READ_WRITE;
/**
- * Set to acknowledge possible files tampering.
- *
- * If unacknowledged tampering is detected, the operation will fail with an ERR_FS_*
- * service-specific code.
- */
- ReadIntegrity readIntegrity = ReadIntegrity.NO_TAMPER;
-
- /**
* If this file already exists, discard existing content and open
* it as a new file. No semantic change if the file does not exist.
*/
boolean truncateOnOpen;
-
- /**
- * Allow writes to succeed while the filesystem is in the middle of an A/B update.
- *
- * If the A/B update fails, the operation will be rolled back. This rollback will not
- * cause subsequent operations fail with any ERR_FS_* code nor will need to be
- * acknowledged by setting the `readIntegrity`.
- */
- boolean allowWritesDuringAbUpdate = false;
}
diff --git a/staging/security/see/storage/aidl/android/hardware/security/see/storage/ReadIntegrity.aidl b/staging/security/see/storage/aidl/android/hardware/security/see/storage/ReadIntegrity.aidl
deleted file mode 100644
index cc0e4f9..0000000
--- a/staging/security/see/storage/aidl/android/hardware/security/see/storage/ReadIntegrity.aidl
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2024 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.hardware.security.see.storage;
-
-enum ReadIntegrity {
- /**
- * Return an error on reads if any REE alteration of the written data
- * has been detected.
- */
- NO_TAMPER,
-
- /**
- * Return an error on reads if any REE alteration other than a reset
- * has been detected.
- */
- IGNORE_RESET,
-
- /**
- * Return an error if any REE alteration other than a rollback to a
- * valid checkpoint has been detected. (What makes a checkpoint valid is
- * implementation defined; an implementation might take a checkpoint on its
- * first post-factory boot. A reset is a rollback to the initial state.)
- */
- IGNORE_ROLLBACK,
-
- // There's no `IGNORE_ALL` because if REE has done any alteration other
- // than a rollback, the file contents will be known-bad data.
-}
diff --git a/staging/security/see/storage/aidl/android/hardware/security/see/storage/RenameOptions.aidl b/staging/security/see/storage/aidl/android/hardware/security/see/storage/RenameOptions.aidl
deleted file mode 100644
index f55ea7f..0000000
--- a/staging/security/see/storage/aidl/android/hardware/security/see/storage/RenameOptions.aidl
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2024 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.hardware.security.see.storage;
-
-import android.hardware.security.see.storage.CreationMode;
-import android.hardware.security.see.storage.ReadIntegrity;
-
-parcelable RenameOptions {
- /** Controls creation behavior of the dest file. See `CreationMode` docs for details. */
- CreationMode destCreateMode = CreationMode.CREATE_EXCLUSIVE;
-
- /**
- * Set to acknowledge possible files tampering.
- *
- * If unacknowledged tampering is detected, the operation will fail with an ERR_FS_*
- * service-specific code.
- */
- ReadIntegrity readIntegrity = ReadIntegrity.NO_TAMPER;
-
- /**
- * Allow writes to succeed while the filesystem is in the middle of an A/B update.
- *
- * If the A/B update fails, the operation will be rolled back. This rollback will not
- * cause subsequent operations fail with any ERR_FS_* code nor will need to be
- * acknowledged by setting the `readIntegrity`.
- */
- boolean allowWritesDuringAbUpdate = false;
-}
diff --git a/staging/security/see/storage/aidl/android/hardware/security/see/storage/Tamper.aidl b/staging/security/see/storage/aidl/android/hardware/security/see/storage/Tamper.aidl
deleted file mode 100644
index 0a39fdd..0000000
--- a/staging/security/see/storage/aidl/android/hardware/security/see/storage/Tamper.aidl
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright 2024 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.hardware.security.see.storage;
-
-/** Specifies types of REE tampering the filesystem may detect */
-enum Tamper {
- /** REE has reset this file or the containing file system. */
- RESET,
-
- /** REE has rolled back this file or the containing file system to a previous state. */
- ROLLBACK,
-
- /** REE has made some other modification to the file. */
- OTHER,
-}
diff --git a/tests/msgq/1.0/ITestMsgQ.hal b/tests/msgq/1.0/ITestMsgQ.hal
index 0cf9c7c..62bef0a 100644
--- a/tests/msgq/1.0/ITestMsgQ.hal
+++ b/tests/msgq/1.0/ITestMsgQ.hal
@@ -18,8 +18,8 @@
interface ITestMsgQ {
enum EventFlagBits : uint32_t {
- FMQ_NOT_EMPTY = 1 << 0,
- FMQ_NOT_FULL = 1 << 1,
+ FMQ_NOT_FULL = 1 << 0,
+ FMQ_NOT_EMPTY = 1 << 1,
};
/**
diff --git a/tests/msgq/TEST_MAPPING b/tests/msgq/TEST_MAPPING
new file mode 100644
index 0000000..51c6c97
--- /dev/null
+++ b/tests/msgq/TEST_MAPPING
@@ -0,0 +1,18 @@
+{
+ "presubmit": [
+ {
+ "name": "fmq_unit_tests"
+ },
+ {
+ "name": "fmq_test"
+ }
+ ],
+ "hwasan-presubmit": [
+ {
+ "name": "fmq_unit_tests"
+ },
+ {
+ "name": "fmq_test"
+ }
+ ]
+}
diff --git a/threadnetwork/aidl/default/Android.bp b/threadnetwork/aidl/default/Android.bp
index 82a76e0..a840fa3 100644
--- a/threadnetwork/aidl/default/Android.bp
+++ b/threadnetwork/aidl/default/Android.bp
@@ -14,6 +14,8 @@
vendor: true,
relative_install_path: "hw",
+ defaults: ["android.hardware.threadnetwork-service.defaults"],
+
shared_libs: [
"libbinder_ndk",
"liblog",
@@ -43,6 +45,17 @@
],
}
+cc_defaults {
+ name: "android.hardware.threadnetwork-service.defaults",
+ product_variables: {
+ debuggable: {
+ cppflags: [
+ "-DDEV_BUILD",
+ ],
+ },
+ },
+}
+
cc_fuzz {
name: "android.hardware.threadnetwork-service.fuzzer",
@@ -90,10 +103,20 @@
installable: false,
}
+filegroup {
+ name: "com.android.hardware.threadnetwork_manifest",
+ srcs: ["manifest.json"],
+}
+
+filegroup {
+ name: "com.android.hardware.threadnetwork_file_contexts",
+ srcs: ["file_contexts"],
+}
+
apex {
name: "com.android.hardware.threadnetwork",
- manifest: "manifest.json",
- file_contexts: "file_contexts",
+ manifest: ":com.android.hardware.threadnetwork_manifest",
+ file_contexts: ":com.android.hardware.threadnetwork_file_contexts",
key: "com.android.hardware.key",
certificate: ":com.android.hardware.certificate",
updatable: false,
@@ -110,3 +133,21 @@
"android.hardware.thread_network.prebuilt.xml", // permission
],
}
+
+prebuilt_etc {
+ name: "threadnetwork-service-simulation-rcp.rc",
+ src: "threadnetwork-service-simulation-rcp.rc",
+ installable: false,
+}
+
+// Thread HAL service which uses a simulation RCP (i.e. ot-rcp),
+// typically used in emulator devices.
+override_apex {
+ name: "com.android.hardware.threadnetwork-simulation-rcp",
+ base: "com.android.hardware.threadnetwork",
+ prebuilts: [
+ "threadnetwork-service-simulation-rcp.rc",
+ "threadnetwork-default.xml",
+ "android.hardware.thread_network.prebuilt.xml",
+ ],
+}
diff --git a/threadnetwork/aidl/default/socket_interface.cpp b/threadnetwork/aidl/default/socket_interface.cpp
index 339fd6b..71c6b4f 100644
--- a/threadnetwork/aidl/default/socket_interface.cpp
+++ b/threadnetwork/aidl/default/socket_interface.cpp
@@ -36,6 +36,7 @@
#include <vector>
#include "common/code_utils.hpp"
+#include "openthread/error.h"
#include "openthread/openthread-system.h"
#include "platform-posix.h"
@@ -56,14 +57,9 @@
otError SocketInterface::Init(ReceiveFrameCallback aCallback, void* aCallbackContext,
RxFrameBuffer& aFrameBuffer) {
- otError error = OT_ERROR_NONE;
+ otError error = InitSocket();
- VerifyOrExit(mSockFd == -1, error = OT_ERROR_ALREADY);
-
- WaitForSocketFileCreated(mRadioUrl.GetPath());
-
- mSockFd = OpenFile(mRadioUrl);
- VerifyOrExit(mSockFd != -1, error = OT_ERROR_FAILED);
+ VerifyOrExit(error == OT_ERROR_NONE);
mReceiveFrameCallback = aCallback;
mReceiveFrameContext = aCallbackContext;
@@ -94,8 +90,8 @@
otError SocketInterface::WaitForFrame(uint64_t aTimeoutUs) {
otError error = OT_ERROR_NONE;
struct timeval timeout;
- timeout.tv_sec = static_cast<time_t>(aTimeoutUs / US_PER_S);
- timeout.tv_usec = static_cast<suseconds_t>(aTimeoutUs % US_PER_S);
+ timeout.tv_sec = static_cast<time_t>(aTimeoutUs / OT_US_PER_S);
+ timeout.tv_usec = static_cast<suseconds_t>(aTimeoutUs % OT_US_PER_S);
fd_set readFds;
fd_set errorFds;
@@ -133,8 +129,8 @@
while (mIsHardwareResetting && retries++ < kMaxRetriesForSocketCloseCheck) {
struct timeval timeout;
- timeout.tv_sec = static_cast<time_t>(aTimeoutMs / MS_PER_S);
- timeout.tv_usec = static_cast<suseconds_t>((aTimeoutMs % MS_PER_S) * MS_PER_S);
+ timeout.tv_sec = static_cast<time_t>(aTimeoutMs / OT_MS_PER_S);
+ timeout.tv_usec = static_cast<suseconds_t>((aTimeoutMs % OT_MS_PER_S) * OT_MS_PER_S);
fd_set readFds;
@@ -155,9 +151,22 @@
VerifyOrExit(!mIsHardwareResetting, error = OT_ERROR_FAILED);
- WaitForSocketFileCreated(mRadioUrl.GetPath());
- mSockFd = OpenFile(mRadioUrl);
- VerifyOrExit(mSockFd != -1, error = OT_ERROR_FAILED);
+exit:
+ return error;
+}
+
+otError SocketInterface::InitSocket() {
+ otError error = OT_ERROR_NONE;
+ int retries = 0;
+
+ VerifyOrExit(mSockFd == -1, error = OT_ERROR_ALREADY);
+
+ while (retries++ < kMaxRetriesForSocketInit) {
+ WaitForSocketFileCreated(mRadioUrl.GetPath());
+ mSockFd = OpenFile(mRadioUrl);
+ VerifyOrExit(mSockFd == -1);
+ }
+ error = OT_ERROR_FAILED;
exit:
return error;
@@ -168,11 +177,16 @@
assert(context != nullptr);
+ VerifyOrExit(mSockFd != -1);
+
FD_SET(mSockFd, &context->mReadFdSet);
if (context->mMaxFd < mSockFd) {
context->mMaxFd = mSockFd;
}
+
+exit:
+ return;
}
void SocketInterface::Process(const void* aMainloopContext) {
@@ -181,9 +195,14 @@
assert(context != nullptr);
+ VerifyOrExit(mSockFd != -1);
+
if (FD_ISSET(mSockFd, &context->mReadFdSet)) {
Read();
}
+
+exit:
+ return;
}
otError SocketInterface::HardwareReset(void) {
@@ -198,22 +217,24 @@
void SocketInterface::Read(void) {
uint8_t buffer[kMaxFrameSize];
+ ssize_t rval;
- ssize_t rval = TEMP_FAILURE_RETRY(read(mSockFd, buffer, sizeof(buffer)));
+ VerifyOrExit(mSockFd != -1);
+
+ rval = TEMP_FAILURE_RETRY(read(mSockFd, buffer, sizeof(buffer)));
if (rval > 0) {
ProcessReceivedData(buffer, static_cast<uint16_t>(rval));
} else if (rval < 0) {
DieNow(OT_EXIT_ERROR_ERRNO);
} else {
- if (mIsHardwareResetting) {
- LogInfo("Socket connection is closed due to hardware reset.");
- ResetStates();
- } else {
- LogCrit("Socket connection is closed by remote.");
- exit(OT_EXIT_FAILURE);
- }
+ LogWarn("Socket connection is closed by remote, isHardwareReset: %d", mIsHardwareResetting);
+ ResetStates();
+ InitSocket();
}
+
+exit:
+ return;
}
void SocketInterface::Write(const uint8_t* aFrame, uint16_t aLength) {
@@ -314,8 +335,8 @@
fd_set fds;
FD_ZERO(&fds);
FD_SET(inotifyFd, &fds);
- struct timeval timeout = {kMaxSelectTimeMs / MS_PER_S,
- (kMaxSelectTimeMs % MS_PER_S) * MS_PER_S};
+ struct timeval timeout = {kMaxSelectTimeMs / OT_MS_PER_S,
+ (kMaxSelectTimeMs % OT_MS_PER_S) * OT_MS_PER_S};
int rval = select(inotifyFd + 1, &fds, nullptr, nullptr, &timeout);
VerifyOrDie(rval >= 0, OT_EXIT_ERROR_ERRNO);
diff --git a/threadnetwork/aidl/default/socket_interface.hpp b/threadnetwork/aidl/default/socket_interface.hpp
index 494d76a..83c86e8 100644
--- a/threadnetwork/aidl/default/socket_interface.hpp
+++ b/threadnetwork/aidl/default/socket_interface.hpp
@@ -247,6 +247,15 @@
otError WaitForHardwareResetCompletion(uint32_t aTimeoutMs);
/**
+ * Initialize socket
+ *
+ * @retval TRUE Socket initialization is successful.
+ * @retval FALSE Socket initialization is failed.
+ *
+ */
+ otError InitSocket();
+
+ /**
* Reset socket interface to intitial state.
*
*/
@@ -257,6 +266,7 @@
///< descriptor to become available.
kMaxRetriesForSocketCloseCheck = 3, ///< Maximum retry times for checking
///< if socket is closed.
+ kMaxRetriesForSocketInit = 3, ///< Maximum retry times for socket initialization.
};
ReceiveFrameCallback mReceiveFrameCallback;
diff --git a/threadnetwork/aidl/default/threadnetwork-service-simulation-rcp.rc b/threadnetwork/aidl/default/threadnetwork-service-simulation-rcp.rc
new file mode 100644
index 0000000..3b889eb
--- /dev/null
+++ b/threadnetwork/aidl/default/threadnetwork-service-simulation-rcp.rc
@@ -0,0 +1,3 @@
+service vendor.threadnetwork_hal /apex/com.android.hardware.threadnetwork/bin/hw/android.hardware.threadnetwork-service spinel+hdlc+forkpty:///apex/com.android.hardware.threadnetwork/bin/ot-rcp?forkpty-arg=1
+ class hal
+ user thread_network
diff --git a/threadnetwork/aidl/default/utils.cpp b/threadnetwork/aidl/default/utils.cpp
index 3552b3a..740f331 100644
--- a/threadnetwork/aidl/default/utils.cpp
+++ b/threadnetwork/aidl/default/utils.cpp
@@ -43,6 +43,7 @@
}
void otDumpDebgPlat(const char* aText, const void* aData, uint16_t aDataLength) {
+#ifdef DEV_BUILD
constexpr uint16_t kBufSize = 512;
char buf[kBufSize];
@@ -55,6 +56,11 @@
__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "%s: %s", aText, buf);
}
+#else
+ OT_UNUSED_VARIABLE(aText);
+ OT_UNUSED_VARIABLE(aData);
+ OT_UNUSED_VARIABLE(aDataLength);
+#endif
}
OT_TOOL_WEAK void otPlatAlarmMilliFired(otInstance* aInstance) {
diff --git a/tv/tuner/aidl/default/Android.bp b/tv/tuner/aidl/default/Android.bp
index ed97d9c..4f0d04b 100644
--- a/tv/tuner/aidl/default/Android.bp
+++ b/tv/tuner/aidl/default/Android.bp
@@ -10,7 +10,6 @@
cc_defaults {
name: "tuner_hal_example_defaults",
relative_install_path: "hw",
- vintf_fragments: ["tuner-default.xml"],
vendor: true,
compile_multilib: "first",
srcs: [
@@ -43,6 +42,15 @@
header_libs: [
"media_plugin_headers",
],
+ vintf_fragment_modules: [
+ "tuner-default.xml",
+ ],
+}
+
+vintf_fragment {
+ name: "tuner-default.xml",
+ src: "tuner-default.xml",
+ vendor: true,
}
cc_binary {
diff --git a/uwb/aidl/Android.bp b/uwb/aidl/Android.bp
index abd6a23..655d8a2 100755
--- a/uwb/aidl/Android.bp
+++ b/uwb/aidl/Android.bp
@@ -16,6 +16,7 @@
srcs: ["android/hardware/uwb/*.aidl"],
stability: "vintf",
host_supported: true,
+ frozen: true,
backend: {
java: {
sdk_version: "module_Tiramisu",
@@ -56,6 +57,7 @@
vendor_available: true,
srcs: ["android/hardware/uwb/fira_android/*.aidl"],
stability: "vintf",
+ frozen: false,
backend: {
java: {
sdk_version: "module_Tiramisu",
diff --git a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
index 58919d1..09cdc26 100644
--- a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
@@ -35,6 +35,7 @@
@Backing(type="int") @VintfStability
enum UwbVendorCapabilityTlvTypes {
SUPPORTED_POWER_STATS_QUERY = 0xC0,
+ SUPPORTED_ANTENNA_MODES = 0xC1,
CCC_SUPPORTED_CHAPS_PER_SLOT = 0xA0,
CCC_SUPPORTED_SYNC_CODES = 0xA1,
CCC_SUPPORTED_HOPPING_CONFIG_MODES_AND_SEQUENCES = 0xA2,
diff --git a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvValues.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvValues.aidl
index 702e561..d9b7220 100644
--- a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvValues.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvValues.aidl
@@ -34,6 +34,8 @@
package android.hardware.uwb.fira_android;
@Backing(type="long") @VintfStability
enum UwbVendorCapabilityTlvValues {
+ ANTENNA_MODE_OMNI = 1,
+ ANTENNA_MODE_DIRECTIONAL = (1 << 1) /* 2 */,
UWB_CONFIG_0 = 0,
UWB_CONFIG_1 = 1,
PULSE_SHAPE_SYMMETRICAL_ROOT_RAISED_COSINE = 0,
diff --git a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
index 4df45b6..28e44ef 100644
--- a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
+++ b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
@@ -41,6 +41,13 @@
*/
SUPPORTED_POWER_STATS_QUERY = 0xC0,
+ /**
+ * 1 byte bitmask to indicate which antennas modes are supported.
+ * 0x01 = "Omni mode",
+ * 0x02 = "Directional mode",
+ */
+ SUPPORTED_ANTENNA_MODES = 0xC1,
+
/*********************************************
* CCC specific
********************************************/
diff --git a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvValues.aidl b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvValues.aidl
index 6ef52fe..e5165dc 100644
--- a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvValues.aidl
+++ b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvValues.aidl
@@ -25,6 +25,12 @@
@Backing(type="long")
enum UwbVendorCapabilityTlvValues {
/*********************************************
+ * Protocol agnostic
+ ********************************************/
+ ANTENNA_MODE_OMNI = 1,
+ ANTENNA_MODE_DIRECTIONAL = 1 << 1,
+
+ /*********************************************
* CCC specific
********************************************/
UWB_CONFIG_0 = 0,
diff --git a/uwb/aidl/default/Android.bp b/uwb/aidl/default/Android.bp
index eba18cf..037eac3 100644
--- a/uwb/aidl/default/Android.bp
+++ b/uwb/aidl/default/Android.bp
@@ -16,17 +16,13 @@
prefer_rlib: true,
rustlibs: [
"android.hardware.uwb-V1-rust",
- "liblibc",
"liblogger",
"liblog_rust",
"libbinder_rs",
"libbinder_tokio_rs",
"libtokio",
- "libtokio_util",
"libnix",
"libanyhow",
- "libpdl_runtime",
- "libuwb_uci_packets",
],
proc_macros: [
"libasync_trait",
diff --git a/uwb/aidl/default/src/service.rs b/uwb/aidl/default/src/service.rs
index e97b291..80fa8af 100644
--- a/uwb/aidl/default/src/service.rs
+++ b/uwb/aidl/default/src/service.rs
@@ -1,8 +1,6 @@
use android_hardware_uwb::aidl::android::hardware::uwb::IUwb::{self, IUwb as _};
use android_hardware_uwb::binder;
-use tokio::runtime::Runtime;
-
use std::env;
use std::panic;
@@ -25,13 +23,12 @@
log::info!("UWB HAL starting up");
- // Create the tokio runtime
- let rt = Runtime::new()?;
+ let rt = tokio::runtime::Runtime::new()?;
let chips = env::args()
.skip(1) // Skip binary name
.enumerate()
- .map(|(i, arg)| uwb_chip::UwbChip::new(i.to_string(), arg));
+ .map(|(i, arg)| rt.block_on(uwb_chip::UwbChip::new(i.to_string(), arg)));
binder::add_service(
&format!("{}/default", IUwb::BpUwb::get_descriptor()),
diff --git a/uwb/aidl/default/src/uwb_chip.rs b/uwb/aidl/default/src/uwb_chip.rs
index 956cf6c..0ed05d8 100644
--- a/uwb/aidl/default/src/uwb_chip.rs
+++ b/uwb/aidl/default/src/uwb_chip.rs
@@ -7,126 +7,113 @@
use binder::{DeathRecipient, IBinder, Result, Strong};
use std::sync::Arc;
-use tokio::io::unix::AsyncFd;
-use tokio::select;
+use tokio::fs;
+use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::sync::Mutex;
-use tokio_util::sync::CancellationToken;
-use std::fs::{File, OpenOptions};
-use std::io::{self, Read, Write};
-use std::os::unix::fs::OpenOptionsExt;
-
-use pdl_runtime::Packet;
-use uwb_uci_packets::{DeviceResetCmdBuilder, ResetConfig, UciControlPacket, UciControlPacketHal};
-
-enum State {
+enum ClientState {
Closed,
Opened {
callbacks: Strong<dyn IUwbClientCallback>,
- handle: tokio::task::JoinHandle<()>,
- serial: File,
- death_recipient: DeathRecipient,
- token: CancellationToken,
+ _death_recipient: DeathRecipient,
},
}
+struct ServiceState {
+ client_state: ClientState,
+ writer: fs::File,
+}
+
pub struct UwbChip {
name: String,
- path: String,
- state: Arc<Mutex<State>>,
+ _handle: tokio::task::JoinHandle<()>,
+ service_state: Arc<Mutex<ServiceState>>,
}
-impl UwbChip {
- pub fn new(name: String, path: String) -> Self {
- Self {
- name,
- path,
- state: Arc::new(Mutex::new(State::Closed)),
- }
- }
-}
-
-impl State {
- /// Terminate the reader task.
- async fn close(&mut self) -> Result<()> {
- if let State::Opened {
- ref mut token,
- ref callbacks,
- ref mut death_recipient,
- ref mut handle,
- ref mut serial,
- } = *self
- {
- log::info!("waiting for task cancellation");
- callbacks.as_binder().unlink_to_death(death_recipient)?;
- token.cancel();
- handle.await.unwrap();
- let packet: UciControlPacket = DeviceResetCmdBuilder {
- reset_config: ResetConfig::UwbsReset,
- }
- .build()
- .into();
- // DeviceResetCmd need to be send to reset the device to stop all running
- // activities on UWBS.
- let packet_vec: Vec<UciControlPacketHal> = packet.into();
- for hal_packet in packet_vec.into_iter() {
- serial
- .write(&hal_packet.encode_to_vec().unwrap())
- .map(|written| written as i32)
- .map_err(|_| binder::StatusCode::UNKNOWN_ERROR)?;
- }
- consume_device_reset_rsp_and_ntf(
- &mut serial
- .try_clone()
- .map_err(|_| binder::StatusCode::UNKNOWN_ERROR)?,
- );
- log::info!("task successfully cancelled");
- callbacks.onHalEvent(UwbEvent::CLOSE_CPLT, UwbStatus::OK)?;
- *self = State::Closed;
- }
- Ok(())
- }
-}
-
-fn consume_device_reset_rsp_and_ntf(reader: &mut File) {
- // Poll the DeviceResetRsp and DeviceStatusNtf before hal is closed to prevent
- // the host from getting response and notifications from a 'powered down' UWBS.
- // Do nothing when these packets are received.
- const DEVICE_RESET_RSP: [u8; 5] = [64, 0, 0, 1, 0];
- const DEVICE_STATUS_NTF: [u8; 5] = [96, 1, 0, 1, 1];
- let mut buffer = vec![0; DEVICE_RESET_RSP.len() + DEVICE_STATUS_NTF.len()];
- read_exact(reader, &mut buffer).unwrap();
-
- // Make sure received packets are the expected ones.
- assert_eq!(&buffer[0..DEVICE_RESET_RSP.len()], &DEVICE_RESET_RSP);
- assert_eq!(&buffer[DEVICE_RESET_RSP.len()..], &DEVICE_STATUS_NTF);
-}
-
-pub fn makeraw(file: File) -> io::Result<File> {
- // Configure the file descriptor as raw fd.
+/// Configure a file descriptor as raw fd.
+pub fn makeraw(file: fs::File) -> std::io::Result<fs::File> {
use nix::sys::termios::*;
let mut attrs = tcgetattr(&file)?;
cfmakeraw(&mut attrs);
tcsetattr(&file, SetArg::TCSANOW, &attrs)?;
-
Ok(file)
}
-/// Wrapper around Read::read to handle EWOULDBLOCK.
-/// /!\ will actively wait for more data, make sure to call
-/// this method only when data is immediately expected.
-fn read_exact(file: &mut File, mut buf: &mut [u8]) -> io::Result<()> {
- while buf.len() > 0 {
- match file.read(buf) {
- Ok(0) => panic!("unexpectedly reached end of file"),
- Ok(read_len) => buf = &mut buf[read_len..],
- Err(err) if err.kind() == io::ErrorKind::WouldBlock => continue,
- Err(err) => return Err(err),
+impl UwbChip {
+ pub async fn new(name: String, path: String) -> Self {
+ // Open the serial file and configure it as raw file
+ // descriptor.
+ let mut reader = fs::OpenOptions::new()
+ .read(true)
+ .write(true)
+ .create(false)
+ .open(&path)
+ .await
+ .and_then(makeraw)
+ .expect("failed to open the serial device");
+ let writer = reader
+ .try_clone()
+ .await
+ .expect("failed to clone serial for writing");
+
+ // Create the chip
+ let service_state = Arc::new(Mutex::new(ServiceState {
+ writer,
+ client_state: ClientState::Closed,
+ }));
+
+ // Spawn the task that will run the polling loop.
+ let handle = {
+ let service_state = service_state.clone();
+
+ tokio::task::spawn(async move {
+ log::info!("UCI reader task started");
+
+ const MESSAGE_TYPE_MASK: u8 = 0b11100000;
+ const DATA_MESSAGE_TYPE: u8 = 0b000;
+ const UCI_HEADER_SIZE: usize = 4;
+ const UCI_BUFFER_SIZE: usize = 1024;
+
+ let mut buffer = [0; UCI_BUFFER_SIZE];
+
+ loop {
+ reader
+ .read_exact(&mut buffer[0..UCI_HEADER_SIZE])
+ .await
+ .expect("failed to read uci header bytes");
+ let common_header = buffer[0];
+ let mt = (common_header & MESSAGE_TYPE_MASK) >> 5;
+ let payload_length = if mt == DATA_MESSAGE_TYPE {
+ u16::from_le_bytes([buffer[2], buffer[3]]) as usize
+ } else {
+ buffer[3] as usize
+ };
+
+ let total_packet_length = payload_length + UCI_HEADER_SIZE;
+ reader
+ .read_exact(&mut buffer[UCI_HEADER_SIZE..total_packet_length])
+ .await
+ .expect("failed to read uci payload bytes");
+
+ log::debug!(" <-- {:?}", &buffer[0..total_packet_length]);
+
+ let service_state = service_state.lock().await;
+ if let ClientState::Opened { ref callbacks, .. } = service_state.client_state {
+ callbacks
+ .onUciMessage(&buffer[0..total_packet_length])
+ .unwrap();
+ }
+ }
+ })
+ };
+
+ Self {
+ name,
+ _handle: handle,
+ service_state,
}
}
- Ok(())
}
-
impl binder::Interface for UwbChip {}
#[async_trait]
@@ -136,124 +123,30 @@
}
async fn open(&self, callbacks: &Strong<dyn IUwbClientCallback>) -> Result<()> {
- log::debug!("open: {:?}", &self.path);
+ log::debug!("open");
- let mut state = self.state.lock().await;
+ let mut service_state = self.service_state.lock().await;
- if matches!(*state, State::Opened { .. }) {
+ if matches!(service_state.client_state, ClientState::Opened { .. }) {
log::error!("the state is already opened");
return Err(binder::ExceptionCode::ILLEGAL_STATE.into());
}
- let serial = OpenOptions::new()
- .read(true)
- .write(true)
- .create(false)
- .custom_flags(libc::O_NONBLOCK)
- .open(&self.path)
- .and_then(makeraw)
- .map_err(|_| binder::StatusCode::UNKNOWN_ERROR)?;
-
- let state_death_recipient = self.state.clone();
- let mut death_recipient = DeathRecipient::new(move || {
- let mut state = state_death_recipient.blocking_lock();
- log::info!("Uwb service has died");
- if let State::Opened { ref mut token, .. } = *state {
- token.cancel();
- *state = State::Closed;
- }
- });
+ let mut death_recipient = {
+ let service_state = self.service_state.clone();
+ DeathRecipient::new(move || {
+ log::info!("Uwb service has died");
+ let mut service_state = service_state.blocking_lock();
+ service_state.client_state = ClientState::Closed;
+ })
+ };
callbacks.as_binder().link_to_death(&mut death_recipient)?;
-
- let token = CancellationToken::new();
- let cloned_token = token.clone();
-
- let client_callbacks = callbacks.clone();
-
- let reader = serial
- .try_clone()
- .map_err(|_| binder::StatusCode::UNKNOWN_ERROR)?;
-
- let join_handle = tokio::task::spawn(async move {
- log::info!("UCI reader task started");
- let mut reader = AsyncFd::new(reader).unwrap();
-
- loop {
- const MESSAGE_TYPE_MASK: u8 = 0b11100000;
- const DATA_MESSAGE_TYPE: u8 = 0b000;
- const UWB_HEADER_SIZE: usize = 4;
- let mut buffer = vec![0; UWB_HEADER_SIZE];
-
- // The only time where the task can be safely
- // cancelled is when no packet bytes have been read.
- //
- // - read_exact() cannot be used here since it is not
- // cancellation safe.
- // - read() cannot be used because it cannot be cancelled:
- // the syscall is executed blocking on the threadpool
- // and completes after termination of the task when
- // the pipe receives more data.
- let read_len = loop {
- // On some platforms, the readiness detecting mechanism
- // relies on edge-triggered notifications. This means that
- // the OS will only notify Tokio when the file descriptor
- // transitions from not-ready to ready. For this to work
- // you should first try to read or write and only poll for
- // readiness if that fails with an error of
- // std::io::ErrorKind::WouldBlock.
- match reader.get_mut().read(&mut buffer) {
- Ok(0) => {
- log::error!("file unexpectedly closed");
- return;
- }
- Ok(read_len) => break read_len,
- Err(err) if err.kind() == io::ErrorKind::WouldBlock => (),
- Err(_) => panic!("unexpected read failure"),
- }
-
- let mut guard = select! {
- _ = cloned_token.cancelled() => {
- log::info!("task is cancelled!");
- return;
- },
- result = reader.readable() => result.unwrap()
- };
-
- guard.clear_ready();
- };
-
- // Read the remaining header bytes, if truncated.
- read_exact(reader.get_mut(), &mut buffer[read_len..]).unwrap();
-
- let common_header = buffer[0];
- let mt = (common_header & MESSAGE_TYPE_MASK) >> 5;
- let payload_length = if mt == DATA_MESSAGE_TYPE {
- let payload_length_fields: [u8; 2] = buffer[2..=3].try_into().unwrap();
- u16::from_le_bytes(payload_length_fields) as usize
- } else {
- buffer[3] as usize
- };
-
- let length = payload_length + UWB_HEADER_SIZE;
- buffer.resize(length, 0);
-
- // Read the payload bytes.
- read_exact(reader.get_mut(), &mut buffer[UWB_HEADER_SIZE..]).unwrap();
-
- log::debug!(" <-- {:?}", buffer);
- client_callbacks.onUciMessage(&buffer).unwrap();
- }
- });
-
callbacks.onHalEvent(UwbEvent::OPEN_CPLT, UwbStatus::OK)?;
- *state = State::Opened {
+ service_state.client_state = ClientState::Opened {
callbacks: callbacks.clone(),
- handle: join_handle,
- serial,
- death_recipient,
- token,
+ _death_recipient: death_recipient,
};
Ok(())
@@ -262,19 +155,42 @@
async fn close(&self) -> Result<()> {
log::debug!("close");
- let mut state = self.state.lock().await;
+ let mut service_state = self.service_state.lock().await;
- if let State::Opened { .. } = *state {
- state.close().await
- } else {
- Err(binder::ExceptionCode::ILLEGAL_STATE.into())
+ if matches!(service_state.client_state, ClientState::Closed) {
+ log::error!("the state is already closed");
+ return Err(binder::ExceptionCode::ILLEGAL_STATE.into());
}
+
+ // Send the command Device Reset to stop all running activities
+ // on the UWBS emulator. This is necessary because the emulator
+ // is otherwise not notified of the power down (the serial stays
+ // open).
+ //
+ // The response to the command will be dropped by the polling loop,
+ // as the callbacks will have been removed then.
+ let uci_core_device_reset_cmd = [0x20, 0x00, 0x00, 0x01, 0x00];
+
+ service_state
+ .writer
+ .write_all(&uci_core_device_reset_cmd)
+ .await
+ .expect("failed to write UCI Device Reset command");
+
+ if let ClientState::Opened { ref callbacks, .. } = service_state.client_state {
+ callbacks.onHalEvent(UwbEvent::CLOSE_CPLT, UwbStatus::OK)?;
+ }
+
+ service_state.client_state = ClientState::Closed;
+ Ok(())
}
async fn coreInit(&self) -> Result<()> {
log::debug!("coreInit");
- if let State::Opened { ref callbacks, .. } = *self.state.lock().await {
+ let service_state = self.service_state.lock().await;
+
+ if let ClientState::Opened { ref callbacks, .. } = service_state.client_state {
callbacks.onHalEvent(UwbEvent::POST_INIT_CPLT, UwbStatus::OK)?;
Ok(())
} else {
@@ -289,22 +205,27 @@
}
async fn getSupportedAndroidUciVersion(&self) -> Result<i32> {
+ log::debug!("getSupportedAndroidUciVersion");
+
Ok(1)
}
async fn sendUciMessage(&self, data: &[u8]) -> Result<i32> {
log::debug!("sendUciMessage");
- if let State::Opened { ref mut serial, .. } = &mut *self.state.lock().await {
- log::debug!(" --> {:?}", data);
- let result = serial
- .write_all(data)
- .map(|_| data.len() as i32)
- .map_err(|_| binder::StatusCode::UNKNOWN_ERROR.into());
- log::debug!(" status: {:?}", result);
- result
- } else {
- Err(binder::ExceptionCode::ILLEGAL_STATE.into())
+ let mut service_state = self.service_state.lock().await;
+
+ if matches!(service_state.client_state, ClientState::Closed) {
+ log::error!("the state is not opened");
+ return Err(binder::ExceptionCode::ILLEGAL_STATE.into());
}
+
+ log::debug!(" --> {:?}", data);
+ service_state
+ .writer
+ .write_all(data)
+ .await
+ .map(|_| data.len() as i32)
+ .map_err(|_| binder::StatusCode::UNKNOWN_ERROR.into())
}
}
diff --git a/uwb/aidl/vts/VtsHalUwbTargetTest.cpp b/uwb/aidl/vts/VtsHalUwbTargetTest.cpp
index 548cae0..2b09f7e 100644
--- a/uwb/aidl/vts/VtsHalUwbTargetTest.cpp
+++ b/uwb/aidl/vts/VtsHalUwbTargetTest.cpp
@@ -201,14 +201,15 @@
EXPECT_EQ(retrieved_chip_name, chip_name);
}
-/**
TEST_P(UwbAidl, ChipSendUciMessage_GetDeviceInfo) {
-const auto iuwb_chip = getAnyChipAndOpen(callback);
-EXPECT_TRUE(iuwb_chip->coreInit(callback).isOk());
+ const auto iuwb_chip = getAnyChipAndOpen();
+ EXPECT_TRUE(iuwb_chip->coreInit().isOk());
-const std::vector<uint8_t>
-EXPECT_TRUE(iuwb_chip->sendUciMessage().isOk());
-} */
+ std::vector<uint8_t> uciMessage = {0x20, 0x02, 0x00, 0x00}; /** CoreGetDeviceInfo */
+ int32_t* return_status = new int32_t;
+ EXPECT_TRUE(iuwb_chip->sendUciMessage(uciMessage, return_status).isOk());
+ EXPECT_EQ(*return_status, 4 /* Status Ok */);
+}
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(UwbAidl);
INSTANTIATE_TEST_SUITE_P(Uwb, UwbAidl,
diff --git a/vibrator/aidl/Android.bp b/vibrator/aidl/Android.bp
index b5199e2..d3b72ee 100644
--- a/vibrator/aidl/Android.bp
+++ b/vibrator/aidl/Android.bp
@@ -25,4 +25,5 @@
"1",
"2",
],
+ frozen: true,
}
diff --git a/weaver/vts/VtsHalWeaverTargetTest.cpp b/weaver/vts/VtsHalWeaverTargetTest.cpp
index 40e9558..faa8416 100644
--- a/weaver/vts/VtsHalWeaverTargetTest.cpp
+++ b/weaver/vts/VtsHalWeaverTargetTest.cpp
@@ -220,10 +220,10 @@
used_slots.insert(slot);
}
}
- // Starting in Android 14, the system will always use at least one Weaver slot if Weaver is
- // supported at all. Make sure we saw at least one.
- ASSERT_FALSE(used_slots.empty())
- << "Could not determine which Weaver slots are in use by the system";
+
+ // We should assert !used_slots.empty() here, but that can't be done yet due to
+ // config_disableWeaverOnUnsecuredUsers being supported. The value of that option is not
+ // accessible from here, so we have to assume it might be set to true.
// Find the first free slot.
int found = 0;
diff --git a/wifi/aidl/default/Android.bp b/wifi/aidl/default/Android.bp
index 362ef1b..3fcb77f 100644
--- a/wifi/aidl/default/Android.bp
+++ b/wifi/aidl/default/Android.bp
@@ -112,9 +112,14 @@
export_include_dirs: ["."],
}
+vintf_fragment {
+ name: "android.hardware.wifi-service.xml",
+ src: "android.hardware.wifi-service.xml",
+ vendor: true,
+}
+
cc_binary {
name: "android.hardware.wifi-service",
- vintf_fragments: ["android.hardware.wifi-service.xml"],
relative_install_path: "hw",
proprietary: true,
cppflags: [
@@ -137,11 +142,11 @@
],
static_libs: ["android.hardware.wifi-service-lib"],
init_rc: ["android.hardware.wifi-service.rc"],
+ vintf_fragment_modules: ["android.hardware.wifi-service.xml"],
}
cc_binary {
name: "android.hardware.wifi-service-lazy",
- vintf_fragments: ["android.hardware.wifi-service.xml"],
overrides: ["android.hardware.wifi-service"],
cflags: ["-DLAZY_SERVICE"],
relative_install_path: "hw",
@@ -166,6 +171,7 @@
],
static_libs: ["android.hardware.wifi-service-lib"],
init_rc: ["android.hardware.wifi-service-lazy.rc"],
+ vintf_fragment_modules: ["android.hardware.wifi-service.xml"],
}
cc_test {
@@ -218,3 +224,8 @@
name: "default-android.hardware.wifi-service.xml",
srcs: ["android.hardware.wifi-service.xml"],
}
+
+filegroup {
+ name: "default-android.hardware.wifi-service-lazy.rc",
+ srcs: ["android.hardware.wifi-service-lazy.rc"],
+}
diff --git a/wifi/netlinkinterceptor/aidl/Android.bp b/wifi/netlinkinterceptor/aidl/Android.bp
index 8c04e31..bc02125 100644
--- a/wifi/netlinkinterceptor/aidl/Android.bp
+++ b/wifi/netlinkinterceptor/aidl/Android.bp
@@ -29,6 +29,7 @@
vendor_available: true,
srcs: ["android/hardware/net/nlinterceptor/*.aidl"],
stability: "vintf",
+ frozen: true,
backend: {
java: {
enabled: false,
diff --git a/wifi/netlinkinterceptor/aidl/default/Android.bp b/wifi/netlinkinterceptor/aidl/default/Android.bp
index 6bdd9fc..52f15e4 100644
--- a/wifi/netlinkinterceptor/aidl/default/Android.bp
+++ b/wifi/netlinkinterceptor/aidl/default/Android.bp
@@ -76,3 +76,13 @@
sub_dir: "vintf",
installable: false,
}
+
+filegroup {
+ name: "android.hardware.net.nlinterceptor-service.rc",
+ srcs: ["nlinterceptor.rc"],
+}
+
+filegroup {
+ name: "android.hardware.net.nlinterceptor.xml",
+ srcs: ["nlinterceptor.xml"],
+}