Merge "Bind Fingerprint Virutal HAL with IVirtual interface" into main
diff --git a/Android.bp b/Android.bp
index 223a1a9..baf3291 100644
--- a/Android.bp
+++ b/Android.bp
@@ -51,7 +51,6 @@
// Lists all dependencies that can *not* be expected on the device.
static_libs: [
"VtsHalHidlTestUtils",
- "libhidlbase",
"libhidl-gen-utils",
],
@@ -64,6 +63,7 @@
"libbase",
// All the following are dependencies of any HAL definition library.
"libcutils",
+ "libhidlbase",
"liblog",
"libutils",
],
@@ -72,14 +72,6 @@
"-g",
],
- target: {
- android: {
- shared_libs: [
- "libvndksupport",
- ],
- },
- },
-
require_root: true,
}
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/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/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 f5b590b..f51f65e 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",
@@ -83,14 +84,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",
],
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/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/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/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/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/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/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/primary/StreamPrimary.cpp b/audio/aidl/default/primary/StreamPrimary.cpp
index 7325a91..498f029 100644
--- a/audio/aidl/default/primary/StreamPrimary.cpp
+++ b/audio/aidl/default/primary/StreamPrimary.cpp
@@ -116,8 +116,7 @@
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());
+ device.type.connection == AudioDeviceDescription::CONNECTION_BUS /*deprecated */;
}
StreamSwitcher::DeviceSwitchBehavior StreamInPrimary::switchCurrentStream(
@@ -188,8 +187,7 @@
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());
+ device.type.connection == AudioDeviceDescription::CONNECTION_BUS /*deprecated*/;
}
StreamSwitcher::DeviceSwitchBehavior StreamOutPrimary::switchCurrentStream(
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/VtsHalHapticGeneratorTargetTest.cpp b/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
index d8332aa..154a5af 100644
--- a/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
@@ -78,6 +78,8 @@
const std::vector<float> kQFactorValues = {MIN_FLOAT, 100, MAX_FLOAT};
const std::vector<float> kMaxAmplitude = {MIN_FLOAT, 100, MAX_FLOAT};
+constexpr int HAPTIC_SCALE_FACTORS_EFFECT_MIN_VERSION = 3;
+
class HapticGeneratorParamTest : public ::testing::TestWithParam<HapticGeneratorParamTestParam>,
public EffectHelper {
public:
@@ -95,6 +97,7 @@
void SetUp() override {
ASSERT_NE(nullptr, mFactory);
ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+ EXPECT_STATUS(EX_NONE, mEffect->getInterfaceVersion(&mEffectInterfaceVersion));
Parameter::Common common = createParamCommon(
0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
@@ -113,6 +116,7 @@
std::shared_ptr<IFactory> mFactory;
std::shared_ptr<IEffect> mEffect;
Descriptor mDescriptor;
+ int mEffectInterfaceVersion;
int mParamHapticScaleId = 0;
HapticGenerator::VibratorScale mParamVibratorScale = HapticGenerator::VibratorScale::MUTE;
float mParamScaleFactor = HapticGenerator::HapticScale::UNDEFINED_SCALE_FACTOR;
@@ -148,11 +152,15 @@
void addHapticScaleParam(int id, HapticGenerator::VibratorScale scale, float scaleFactor,
float adaptiveScaleFactor) {
HapticGenerator setHg;
- std::vector<HapticGenerator::HapticScale> hapticScales = {
- {.id = id,
- .scale = scale,
- .scaleFactor = scaleFactor,
- .adaptiveScaleFactor = adaptiveScaleFactor}};
+ std::vector<HapticGenerator::HapticScale> hapticScales;
+ if (mEffectInterfaceVersion >= HAPTIC_SCALE_FACTORS_EFFECT_MIN_VERSION) {
+ hapticScales = {{.id = id,
+ .scale = scale,
+ .scaleFactor = scaleFactor,
+ .adaptiveScaleFactor = adaptiveScaleFactor}};
+ } else {
+ hapticScales = {{.id = id, .scale = scale}};
+ }
setHg.set<HapticGenerator::hapticScales>(hapticScales);
mTags.push_back({HapticGenerator::hapticScales, setHg});
}
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/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/Android.bp b/automotive/vehicle/Android.bp
index e614937..606e108 100644
--- a/automotive/vehicle/Android.bp
+++ b/automotive/vehicle/Android.bp
@@ -22,7 +22,7 @@
name: "VehicleHalInterfaceDefaults",
static_libs: [
"android.hardware.automotive.vehicle-V3-ndk",
- "android.hardware.automotive.vehicle.property-V3-ndk",
+ "android.hardware.automotive.vehicle.property-V4-ndk",
],
}
@@ -30,6 +30,14 @@
name: "VehicleHalInterfaceRustDefaults",
rustlibs: [
"android.hardware.automotive.vehicle-V3-rust",
- "android.hardware.automotive.vehicle.property-V3-rust",
+ "android.hardware.automotive.vehicle.property-V4-rust",
+ ],
+}
+
+aidl_interface_defaults {
+ name: "android.hardware.automotive.vehicle-latest-defaults",
+ imports: [
+ "android.hardware.automotive.vehicle-V3",
+ "android.hardware.automotive.vehicle.property-V4",
],
}
diff --git a/automotive/vehicle/aidl/aidl_test/Android.bp b/automotive/vehicle/aidl/aidl_test/Android.bp
index f517df8..1e43070 100644
--- a/automotive/vehicle/aidl/aidl_test/Android.bp
+++ b/automotive/vehicle/aidl/aidl_test/Android.bp
@@ -40,7 +40,7 @@
cc_test {
name: "VehiclePropertyAnnotationCppTest",
srcs: ["VehiclePropertyAnnotationCppTest.cpp"],
- header_libs: ["IVehicleGeneratedHeaders-V3"],
+ header_libs: ["IVehicleGeneratedHeaders-V4"],
defaults: ["VehicleHalInterfaceDefaults"],
test_suites: ["general-tests"],
}
@@ -49,11 +49,11 @@
name: "VehiclePropertyAnnotationJavaTest",
srcs: [
"VehiclePropertyAnnotationJavaTest.java",
- ":IVehicleGeneratedJavaFiles-V3",
+ ":IVehicleGeneratedJavaFiles-V4",
],
static_libs: [
"android.hardware.automotive.vehicle-V3-java",
- "android.hardware.automotive.vehicle.property-V3-java",
+ "android.hardware.automotive.vehicle.property-V4-java",
"androidx.test.runner",
"truth",
],
diff --git a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/Android.bp b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/Android.bp
index 28c95ce..aef2909 100644
--- a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/Android.bp
+++ b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/Android.bp
@@ -27,7 +27,7 @@
defaults: ["VehicleHalDefaults"],
static_libs: ["VehicleHalUtils"],
header_libs: [
- "IVehicleGeneratedHeaders-V3",
+ "IVehicleGeneratedHeaders-V4",
],
shared_libs: ["libjsoncpp"],
}
@@ -44,7 +44,7 @@
defaults: ["VehicleHalDefaults"],
static_libs: ["VehicleHalUtils"],
header_libs: [
- "IVehicleGeneratedHeaders-V3",
+ "IVehicleGeneratedHeaders-V4",
"libbinder_headers",
],
cflags: ["-DENABLE_VEHICLE_HAL_TEST_PROPERTIES"],
@@ -60,7 +60,7 @@
defaults: ["VehicleHalDefaults"],
static_libs: ["VehicleHalUtils"],
header_libs: [
- "IVehicleGeneratedHeaders-V3",
+ "IVehicleGeneratedHeaders-V4",
],
shared_libs: ["libjsoncpp"],
}
diff --git a/automotive/vehicle/aidl/impl/default_config/test/Android.bp b/automotive/vehicle/aidl/impl/default_config/test/Android.bp
index 70933be..52014fb 100644
--- a/automotive/vehicle/aidl/impl/default_config/test/Android.bp
+++ b/automotive/vehicle/aidl/impl/default_config/test/Android.bp
@@ -31,7 +31,7 @@
"libgtest",
],
header_libs: [
- "IVehicleGeneratedHeaders-V3",
+ "IVehicleGeneratedHeaders-V4",
],
shared_libs: [
"libjsoncpp",
@@ -57,7 +57,7 @@
"-DENABLE_VEHICLE_HAL_TEST_PROPERTIES",
],
header_libs: [
- "IVehicleGeneratedHeaders-V3",
+ "IVehicleGeneratedHeaders-V4",
],
shared_libs: [
"libjsoncpp",
diff --git a/automotive/vehicle/aidl/impl/vhal/Android.bp b/automotive/vehicle/aidl/impl/vhal/Android.bp
index 5cc071d..54d148e 100644
--- a/automotive/vehicle/aidl/impl/vhal/Android.bp
+++ b/automotive/vehicle/aidl/impl/vhal/Android.bp
@@ -66,7 +66,7 @@
],
header_libs: [
"IVehicleHardware",
- "IVehicleGeneratedHeaders-V3",
+ "IVehicleGeneratedHeaders-V4",
],
shared_libs: [
"libbinder_ndk",
diff --git a/automotive/vehicle/tools/generate_emu_metadata/src/com/android/car/tool/EmuMetadataGenerator.java b/automotive/vehicle/tools/generate_emu_metadata/src/com/android/car/tool/EmuMetadataGenerator.java
index bea5951..7f4ceb8 100644
--- a/automotive/vehicle/tools/generate_emu_metadata/src/com/android/car/tool/EmuMetadataGenerator.java
+++ b/automotive/vehicle/tools/generate_emu_metadata/src/com/android/car/tool/EmuMetadataGenerator.java
@@ -79,17 +79,18 @@
+ "either this or input_files must be specified\n" + INPUT_FILES_OPTION
+ ": one or more Java files, this is used to decide the input "
+ "directory\n" + PACKAGE_NAME_OPTION
- + ": the optional package name for the interface, by default is " + DEFAULT_PACKAGE_NAME
- + "\n" + OUTPUT_JSON_OPTION + ": The output JSON file\n" + OUTPUT_EMPTY_FILE_OPTION
- + ": Only used for check_mode, this file will be created if "
+ + ": the optional package name for the interface, by default is "
+ + DEFAULT_PACKAGE_NAME + "\n" + OUTPUT_JSON_OPTION + ": The output JSON file\n"
+ + OUTPUT_EMPTY_FILE_OPTION + ": Only used for check_mode, this file will be created if "
+ "check passed\n" + CHECK_AGAINST_OPTION
+ ": An optional JSON file to check against. If specified, the "
- + "generated output file will be checked against this file, if they are not the same, "
+ + ("generated output file will be checked against this file, if they are not the "
+ + "same, ")
+ "the script will fail, otherwise, the output_empty_file will be created\n"
+ "For example: \n"
+ "EnumMetadataGenerator --input_dir out/soong/.intermediates/hardware/"
+ "interfaces/automotive/vehicle/aidl_property/android.hardware.automotive.vehicle."
- + "property-V3-java-source/gen/ --package_name android.hardware.automotive.vehicle "
+ + "property-V4-java-source/gen/ --package_name android.hardware.automotive.vehicle "
+ "--output_json /tmp/android.hardware.automotive.vehicle-types-meta.json";
private static final String VEHICLE_PROPERTY_FILE = "VehicleProperty.java";
private static final String CHECK_FILE_PATH =
diff --git a/automotive/vehicle/vhal_static_cpp_lib.mk b/automotive/vehicle/vhal_static_cpp_lib.mk
index 6b3d486..9371453 100644
--- a/automotive/vehicle/vhal_static_cpp_lib.mk
+++ b/automotive/vehicle/vhal_static_cpp_lib.mk
@@ -17,4 +17,4 @@
LOCAL_STATIC_LIBRARIES += \
android.hardware.automotive.vehicle-V3-ndk \
- android.hardware.automotive.vehicle.property-V3-ndk
+ android.hardware.automotive.vehicle.property-V4-ndk
diff --git a/automotive/vehicle/vts/Android.bp b/automotive/vehicle/vts/Android.bp
index 40aec59..433ac41 100644
--- a/automotive/vehicle/vts/Android.bp
+++ b/automotive/vehicle/vts/Android.bp
@@ -43,7 +43,7 @@
"vhalclient_defaults",
],
header_libs: [
- "IVehicleGeneratedHeaders-V3",
+ "IVehicleGeneratedHeaders-V4",
],
test_suites: [
"general-tests",
diff --git a/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp b/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
index ad8d4c8..e0e3a0e 100644
--- a/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
+++ b/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
@@ -288,77 +288,70 @@
}
TEST_P(CameraAidlTest, getSessionCharacteristics) {
- if (flags::feature_combination_query()) {
- std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
+ std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
- for (const auto& name : cameraDeviceNames) {
- std::shared_ptr<ICameraDevice> device;
- ALOGI("getSessionCharacteristics: Testing camera device %s", name.c_str());
- ndk::ScopedAStatus ret = mProvider->getCameraDeviceInterface(name, &device);
- ALOGI("getCameraDeviceInterface returns: %d:%d", ret.getExceptionCode(),
- ret.getServiceSpecificError());
- ASSERT_TRUE(ret.isOk());
- ASSERT_NE(device, nullptr);
+ for (const auto& name : cameraDeviceNames) {
+ std::shared_ptr<ICameraDevice> device;
+ ALOGI("getSessionCharacteristics: Testing camera device %s", name.c_str());
+ ndk::ScopedAStatus ret = mProvider->getCameraDeviceInterface(name, &device);
+ ALOGI("getCameraDeviceInterface returns: %d:%d", ret.getExceptionCode(),
+ ret.getServiceSpecificError());
+ ASSERT_TRUE(ret.isOk());
+ ASSERT_NE(device, nullptr);
- int32_t interfaceVersion = -1;
- ret = device->getInterfaceVersion(&interfaceVersion);
- ASSERT_TRUE(ret.isOk());
- bool supportSessionCharacteristics =
- (interfaceVersion >= CAMERA_DEVICE_API_MINOR_VERSION_3);
- if (!supportSessionCharacteristics) {
- continue;
- }
-
- CameraMetadata meta;
- openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/,
- &device /*out*/);
-
- std::vector<AvailableStream> outputStreams;
- camera_metadata_t* staticMeta =
- reinterpret_cast<camera_metadata_t*>(meta.metadata.data());
- outputStreams.clear();
- ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams));
- ASSERT_NE(0u, outputStreams.size());
-
- AvailableStream sampleStream = outputStreams[0];
-
- int32_t streamId = 0;
- Stream stream = {streamId,
- StreamType::OUTPUT,
- sampleStream.width,
- sampleStream.height,
- static_cast<PixelFormat>(sampleStream.format),
- static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
- GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER),
- Dataspace::UNKNOWN,
- StreamRotation::ROTATION_0,
- std::string(),
- /*bufferSize*/ 0,
- /*groupId*/ -1,
- {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
- RequestAvailableDynamicRangeProfilesMap::
- ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD};
-
- std::vector<Stream> streams = {stream};
- StreamConfiguration config;
- createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config);
-
- CameraMetadata camera_chars;
- ret = device->getCameraCharacteristics(&camera_chars);
- ASSERT_TRUE(ret.isOk());
-
- CameraMetadata session_chars;
- ret = device->getSessionCharacteristics(config, &session_chars);
- ASSERT_TRUE(ret.isOk());
- verifySessionCharacteristics(session_chars, camera_chars);
-
- ret = mSession->close();
- mSession = nullptr;
- ASSERT_TRUE(ret.isOk());
+ int32_t interfaceVersion = -1;
+ ret = device->getInterfaceVersion(&interfaceVersion);
+ ASSERT_TRUE(ret.isOk());
+ bool supportSessionCharacteristics =
+ (interfaceVersion >= CAMERA_DEVICE_API_MINOR_VERSION_3);
+ if (!supportSessionCharacteristics) {
+ continue;
}
- } else {
- ALOGI("getSessionCharacteristics: Test skipped.\n");
- GTEST_SKIP();
+
+ CameraMetadata meta;
+ openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/, &device /*out*/);
+
+ std::vector<AvailableStream> outputStreams;
+ camera_metadata_t* staticMeta = reinterpret_cast<camera_metadata_t*>(meta.metadata.data());
+ outputStreams.clear();
+ ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams));
+ ASSERT_NE(0u, outputStreams.size());
+
+ AvailableStream sampleStream = outputStreams[0];
+
+ int32_t streamId = 0;
+ Stream stream = {streamId,
+ StreamType::OUTPUT,
+ sampleStream.width,
+ sampleStream.height,
+ static_cast<PixelFormat>(sampleStream.format),
+ static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
+ GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER),
+ Dataspace::UNKNOWN,
+ StreamRotation::ROTATION_0,
+ std::string(),
+ /*bufferSize*/ 0,
+ /*groupId*/ -1,
+ {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
+ RequestAvailableDynamicRangeProfilesMap::
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD};
+
+ std::vector<Stream> streams = {stream};
+ StreamConfiguration config;
+ createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config);
+
+ CameraMetadata camera_chars;
+ ret = device->getCameraCharacteristics(&camera_chars);
+ ASSERT_TRUE(ret.isOk());
+
+ CameraMetadata session_chars;
+ ret = device->getSessionCharacteristics(config, &session_chars);
+ ASSERT_TRUE(ret.isOk());
+ verifySessionCharacteristics(session_chars, camera_chars);
+
+ ret = mSession->close();
+ mSession = nullptr;
+ ASSERT_TRUE(ret.isOk());
}
}
@@ -615,19 +608,17 @@
ASSERT_EQ(0u, rawMetadata.metadata.size());
}
- if (flags::feature_combination_query()) {
- if (supportFeatureCombinationQuery) {
- CameraMetadata rawMetadata2;
- ndk::ScopedAStatus ret2 =
- device->constructDefaultRequestSettings(reqTemplate, &rawMetadata2);
+ if (supportFeatureCombinationQuery) {
+ CameraMetadata rawMetadata2;
+ ndk::ScopedAStatus ret2 =
+ device->constructDefaultRequestSettings(reqTemplate, &rawMetadata2);
- ASSERT_EQ(ret.isOk(), ret2.isOk());
- ASSERT_EQ(ret.getStatus(), ret2.getStatus());
+ ASSERT_EQ(ret.isOk(), ret2.isOk());
+ ASSERT_EQ(ret.getStatus(), ret2.getStatus());
- ASSERT_EQ(rawMetadata.metadata.size(), rawMetadata2.metadata.size());
- if (ret2.isOk()) {
- validateDefaultRequestMetadata(reqTemplate, rawMetadata2);
- }
+ ASSERT_EQ(rawMetadata.metadata.size(), rawMetadata2.metadata.size());
+ if (ret2.isOk()) {
+ validateDefaultRequestMetadata(reqTemplate, rawMetadata2);
}
}
}
diff --git a/camera/provider/aidl/vts/camera_aidl_test.cpp b/camera/provider/aidl/vts/camera_aidl_test.cpp
index f905011..6ecd451 100644
--- a/camera/provider/aidl/vts/camera_aidl_test.cpp
+++ b/camera/provider/aidl/vts/camera_aidl_test.cpp
@@ -1920,28 +1920,22 @@
ASSERT_TRUE(ret.isOk());
ASSERT_EQ(expectedStatus, streamCombinationSupported);
- if (flags::feature_combination_query()) {
- int32_t interfaceVersion;
- ret = device->getInterfaceVersion(&interfaceVersion);
+ int32_t interfaceVersion;
+ ret = device->getInterfaceVersion(&interfaceVersion);
+ ASSERT_TRUE(ret.isOk());
+ bool supportFeatureCombinationQuery =
+ (interfaceVersion >= CAMERA_DEVICE_API_MINOR_VERSION_3);
+ if (supportFeatureCombinationQuery) {
+ ret = device->isStreamCombinationWithSettingsSupported(config,
+ &streamCombinationSupported);
ASSERT_TRUE(ret.isOk());
- bool supportFeatureCombinationQuery =
- (interfaceVersion >= CAMERA_DEVICE_API_MINOR_VERSION_3);
- if (supportFeatureCombinationQuery) {
- ret = device->isStreamCombinationWithSettingsSupported(config,
- &streamCombinationSupported);
- ASSERT_TRUE(ret.isOk());
- ASSERT_EQ(expectedStatus, streamCombinationSupported);
- }
+ ASSERT_EQ(expectedStatus, streamCombinationSupported);
}
}
}
void CameraAidlTest::verifySessionCharacteristics(const CameraMetadata& session_chars,
const CameraMetadata& camera_chars) {
- if (!flags::feature_combination_query()) {
- return;
- }
-
const camera_metadata_t* session_metadata =
reinterpret_cast<const camera_metadata_t*>(session_chars.metadata.data());
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/compatibility_matrix.202504.xml b/compatibility_matrices/compatibility_matrix.202504.xml
index 9b7866c..ed45c1b 100644
--- a/compatibility_matrices/compatibility_matrix.202504.xml
+++ b/compatibility_matrices/compatibility_matrix.202504.xml
@@ -662,7 +662,7 @@
</hal>
<hal format="aidl">
<name>android.hardware.wifi.hostapd</name>
- <version>1-2</version>
+ <version>2-3</version>
<interface>
<name>IHostapd</name>
<instance>default</instance>
diff --git a/compatibility_matrices/compatibility_matrix.mk b/compatibility_matrices/compatibility_matrix.mk
deleted file mode 100644
index 64cd645..0000000
--- a/compatibility_matrices/compatibility_matrix.mk
+++ /dev/null
@@ -1,94 +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_FLAGS: Add additional command line arguments to assemble_vintf invocation.
-# 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)
-$(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 \
- $(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
-
-my_matrix_src_files := \
- $(addprefix $(LOCAL_PATH)/,$(LOCAL_SRC_FILES)) \
- $(LOCAL_GENERATED_SOURCES)
-
-$(GEN): PRIVATE_SRC_FILES := $(my_matrix_src_files)
-$(GEN): $(my_matrix_src_files) $(HOST_OUT_EXECUTABLES)/assemble_vintf
- $(foreach varname,$(PRIVATE_ENV_VARS),$(varname)="$($(varname))") \
- $(HOST_OUT_EXECUTABLES)/assemble_vintf \
- -i $(call normalize-path-list,$(PRIVATE_SRC_FILES)) \
- -o $@ \
- $(PRIVATE_FLAGS)
-
-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/drm/common/aidl/Android.bp b/drm/common/aidl/Android.bp
index 1e4b8e0..c5cb441 100644
--- a/drm/common/aidl/Android.bp
+++ b/drm/common/aidl/Android.bp
@@ -9,6 +9,7 @@
aidl_interface {
name: "android.hardware.drm.common",
+ host_supported: true,
vendor_available: true,
srcs: ["android/hardware/drm/*.aidl"],
stability: "vintf",
@@ -22,6 +23,9 @@
ndk: {
min_sdk_version: "34",
},
+ rust: {
+ enabled: true,
+ },
},
double_loadable: true,
versions_with_info: [
diff --git a/graphics/Android.bp b/graphics/Android.bp
index 352f3bd..c33f7ff 100644
--- a/graphics/Android.bp
+++ b/graphics/Android.bp
@@ -53,6 +53,7 @@
cc_defaults {
name: "android.hardware.graphics.composer3-ndk_static",
static_libs: [
+ "android.hardware.drm.common-V1-ndk",
"android.hardware.graphics.composer3-V4-ndk",
],
}
@@ -60,6 +61,7 @@
cc_defaults {
name: "android.hardware.graphics.composer3-ndk_shared",
shared_libs: [
+ "android.hardware.drm.common-V1-ndk",
"android.hardware.graphics.composer3-V4-ndk",
],
}
diff --git a/graphics/composer/aidl/Android.bp b/graphics/composer/aidl/Android.bp
index 3b60f68..1728f78 100644
--- a/graphics/composer/aidl/Android.bp
+++ b/graphics/composer/aidl/Android.bp
@@ -37,6 +37,7 @@
imports: [
"android.hardware.graphics.common-V5",
"android.hardware.common-V2",
+ "android.hardware.drm.common-V1",
],
backend: {
cpp: {
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayLuts.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayLuts.aidl
index 869db5b..327e84c 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayLuts.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayLuts.aidl
@@ -35,5 +35,9 @@
@VintfStability
parcelable DisplayLuts {
long display;
- android.hardware.graphics.composer3.Lut[] luts;
+ android.hardware.graphics.composer3.DisplayLuts.LayerLut[] layerLuts;
+ parcelable LayerLut {
+ long layer;
+ android.hardware.graphics.composer3.Lut lut;
+ }
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerCallback.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerCallback.aidl
index e64bd52..cd27360 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerCallback.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerCallback.aidl
@@ -45,4 +45,5 @@
oneway void onVsyncIdle(long display);
oneway void onRefreshRateChangedDebug(in android.hardware.graphics.composer3.RefreshRateChangedDebugData data);
void onHotplugEvent(long display, android.hardware.graphics.common.DisplayHotplugEvent event);
+ oneway void onHdcpLevelsChanged(long display, in android.hardware.drm.HdcpLevels levels);
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Lut.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Lut.aidl
index 39245b5..5fae35b 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Lut.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Lut.aidl
@@ -34,7 +34,6 @@
package android.hardware.graphics.composer3;
@VintfStability
parcelable Lut {
- long layer;
@nullable ParcelFileDescriptor pfd;
android.hardware.graphics.composer3.LutProperties lutProperties;
}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayLuts.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayLuts.aidl
index 56381e0..ac0a606 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayLuts.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayLuts.aidl
@@ -27,12 +27,20 @@
@VintfStability
parcelable DisplayLuts {
/**
- * The display which this commands refers to.
+ * The display which the layerLuts list is for.
*/
long display;
- /**
- * A Lut list specified by the HWC for given HDR layers that don't have Luts provided.
- */
- Lut[] luts;
+ parcelable LayerLut {
+ /**
+ * The layer that the HWC is requesting a LUT to be applied during GPU composition.
+ */
+ long layer;
+ /**
+ * A Lut specified by the HWC for given HDR layers that don't have Luts provided.
+ */
+ Lut lut;
+ }
+
+ LayerLut[] layerLuts;
}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerCallback.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerCallback.aidl
index 96eccd7..a1d61fd 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerCallback.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerCallback.aidl
@@ -16,6 +16,7 @@
package android.hardware.graphics.composer3;
+import android.hardware.drm.HdcpLevels;
import android.hardware.graphics.common.DisplayHotplugEvent;
import android.hardware.graphics.composer3.RefreshRateChangedDebugData;
import android.hardware.graphics.composer3.VsyncPeriodChangeTimeline;
@@ -139,4 +140,12 @@
* @param event is the type of event that occurred.
*/
void onHotplugEvent(long display, DisplayHotplugEvent event);
+
+ /**
+ * Notify the client the HDCP levels of the display changed.
+ *
+ * @param display is the display whose HDCP levels have changed.
+ * @param levels is the new HDCP levels.
+ */
+ oneway void onHdcpLevelsChanged(long display, in HdcpLevels levels);
}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/Lut.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/Lut.aidl
index e4320f5..abfeb14 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/Lut.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/Lut.aidl
@@ -28,11 +28,6 @@
@VintfStability
parcelable Lut {
/**
- * The layer which this commands refer to.
- */
- long layer;
-
- /**
* A handle to a memory region.
* If the file descriptor is not set, this means that the HWC doesn't specify a Lut.
*
diff --git a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientReader.h b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientReader.h
index fc96882..331d717 100644
--- a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientReader.h
+++ b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientReader.h
@@ -186,7 +186,7 @@
}
// Get the lut(s) requested by hardware composer.
- std::vector<Lut> takeDisplayLuts(int64_t display) {
+ std::vector<DisplayLuts::LayerLut> takeDisplayLuts(int64_t display) {
LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
auto found = mReturnData.find(display);
@@ -196,7 +196,7 @@
}
ReturnData& data = found->second;
- return std::move(data.luts);
+ return std::move(data.layerLuts);
}
private:
@@ -247,10 +247,11 @@
void parseSetDisplayLuts(DisplayLuts&& displayLuts) {
LOG_ALWAYS_FATAL_IF(mDisplay && displayLuts.display != *mDisplay);
auto& data = mReturnData[displayLuts.display];
- for (auto& lut : displayLuts.luts) {
- if (lut.pfd.get() >= 0) {
- data.luts.push_back({lut.layer, ndk::ScopedFileDescriptor(lut.pfd.release()),
- lut.lutProperties});
+ for (auto& layerLut : displayLuts.layerLuts) {
+ if (layerLut.lut.pfd.get() >= 0) {
+ data.layerLuts.push_back(
+ {layerLut.layer, Lut{ndk::ScopedFileDescriptor(layerLut.lut.pfd.release()),
+ layerLut.lut.lutProperties}});
}
}
}
@@ -266,7 +267,7 @@
.clientTargetProperty = {common::PixelFormat::RGBA_8888, Dataspace::UNKNOWN},
.brightness = 1.f,
};
- std::vector<Lut> luts;
+ std::vector<DisplayLuts::LayerLut> layerLuts;
};
std::vector<CommandError> mErrors;
diff --git a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h
index a1ccbfe..02fb3aa 100644
--- a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h
+++ b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h
@@ -30,6 +30,7 @@
#include <aidl/android/hardware/graphics/composer3/DisplayBrightness.h>
#include <aidl/android/hardware/graphics/composer3/LayerBrightness.h>
#include <aidl/android/hardware/graphics/composer3/LayerLifecycleBatchCommandType.h>
+#include <aidl/android/hardware/graphics/composer3/Lut.h>
#include <aidl/android/hardware/graphics/composer3/PerFrameMetadata.h>
#include <aidl/android/hardware/graphics/composer3/PerFrameMetadataBlob.h>
@@ -245,6 +246,15 @@
getLayerCommand(display, layer).blockingRegion.emplace(blocking.begin(), blocking.end());
}
+ void setLayerLuts(int64_t display, int64_t layer, std::vector<Lut>& luts) {
+ std::vector<std::optional<Lut>> currentLuts;
+ for (auto& lut : luts) {
+ currentLuts.push_back(std::make_optional<Lut>(
+ {ndk::ScopedFileDescriptor(lut.pfd.release()), lut.lutProperties}));
+ }
+ getLayerCommand(display, layer).luts.emplace(std::move(currentLuts));
+ }
+
std::vector<DisplayCommand> takePendingCommands() {
flushLayerCommand();
flushDisplayCommand();
diff --git a/graphics/composer/aidl/vts/Android.bp b/graphics/composer/aidl/vts/Android.bp
index a2ab3d6..894ca52 100644
--- a/graphics/composer/aidl/vts/Android.bp
+++ b/graphics/composer/aidl/vts/Android.bp
@@ -66,6 +66,7 @@
"android.hardware.graphics.common@1.2",
"android.hardware.common-V2-ndk",
"android.hardware.common.fmq-V1-ndk",
+ "android.hardware.drm.common-V1-ndk",
"libaidlcommonsupport",
"libarect",
"libbase",
diff --git a/graphics/composer/aidl/vts/GraphicsComposerCallback.cpp b/graphics/composer/aidl/vts/GraphicsComposerCallback.cpp
index 544f692..1f7972c 100644
--- a/graphics/composer/aidl/vts/GraphicsComposerCallback.cpp
+++ b/graphics/composer/aidl/vts/GraphicsComposerCallback.cpp
@@ -208,4 +208,15 @@
}
}
+::ndk::ScopedAStatus GraphicsComposerCallback::onHdcpLevelsChanged(
+ int64_t in_display, const ::aidl::android::hardware::drm::HdcpLevels&) {
+ std::scoped_lock lock(mMutex);
+
+ const auto it = std::find(mDisplays.begin(), mDisplays.end(), in_display);
+ if (it != mDisplays.end()) {
+ mHdcpLevelChangedCount++;
+ }
+ return ::ndk::ScopedAStatus::ok();
+}
+
} // namespace aidl::android::hardware::graphics::composer3::vts
diff --git a/graphics/composer/aidl/vts/GraphicsComposerCallback.h b/graphics/composer/aidl/vts/GraphicsComposerCallback.h
index 7a8d4a3..97f8e2b 100644
--- a/graphics/composer/aidl/vts/GraphicsComposerCallback.h
+++ b/graphics/composer/aidl/vts/GraphicsComposerCallback.h
@@ -65,6 +65,8 @@
const RefreshRateChangedDebugData&) override;
virtual ::ndk::ScopedAStatus onHotplugEvent(int64_t in_display,
common::DisplayHotplugEvent) override;
+ virtual ::ndk::ScopedAStatus onHdcpLevelsChanged(
+ int64_t in_display, const ::aidl::android::hardware::drm::HdcpLevels&) override;
mutable std::mutex mMutex;
// the set of all currently connected displays
@@ -88,6 +90,7 @@
int32_t mInvalidVsyncPeriodChangeCount GUARDED_BY(mMutex) = 0;
int32_t mInvalidSeamlessPossibleCount GUARDED_BY(mMutex) = 0;
int32_t mInvalidRefreshRateDebugEnabledCallbackCount GUARDED_BY(mMutex) = 0;
+ int32_t mHdcpLevelChangedCount GUARDED_BY(mMutex) = 0;
};
} // namespace aidl::android::hardware::graphics::composer3::vts
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/utils/libhealthloop/HealthLoop.cpp b/health/utils/libhealthloop/HealthLoop.cpp
index d43c2d5..c5ad5a8 100644
--- a/health/utils/libhealthloop/HealthLoop.cpp
+++ b/health/utils/libhealthloop/HealthLoop.cpp
@@ -43,6 +43,8 @@
namespace hardware {
namespace health {
+static constexpr uint32_t kUeventMsgLen = 2048;
+
HealthLoop::HealthLoop() {
InitHealthdConfig(&healthd_config_);
awake_poll_interval_ = -1;
@@ -61,14 +63,13 @@
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;
@@ -121,32 +122,42 @@
ScheduleBatteryUpdate();
}
-#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();
}
}
@@ -169,7 +180,7 @@
}
void HealthLoop::UeventInit(void) {
- uevent_fd_.reset(uevent_create_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");
@@ -183,9 +194,9 @@
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", error_msg.c_str());
+ KLOG_WARNING(LOG_TAG, "%s\n", error_msg.c_str());
} else {
- KLOG_INFO(LOG_TAG, "Successfully attached the BPF filter to the uevent socket");
+ KLOG_INFO(LOG_TAG, "Successfully attached the BPF filter to the uevent socket\n");
}
if (RegisterEvent(uevent_fd_, &HealthLoop::UeventEvent, EVENT_WAKEUP_FD))
diff --git a/health/utils/libhealthloop/filterPowerSupplyEventsTest.cpp b/health/utils/libhealthloop/filterPowerSupplyEventsTest.cpp
index e885f0b..04b8bcd 100644
--- a/health/utils/libhealthloop/filterPowerSupplyEventsTest.cpp
+++ b/health/utils/libhealthloop/filterPowerSupplyEventsTest.cpp
@@ -192,16 +192,21 @@
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, "a"},
- test_data{true, std::string_view("abc\0SUBSYSTEM=block\0", 20)},
- test_data{true, std::string_view("\0SUBSYSTEM=block", 16)},
- test_data{true, std::string_view("\0SUBSYSTEM=power_supply", 23)},
- test_data{false, std::string_view("\0SUBSYSTEM=power_supply\0", 24)},
- test_data{
- false,
- "012345678901234567890123456789012345678901234567890123456789012345"
- "678901234567890123456789012345678901234567890123456789012345678901"
- "234567890123456789012345678901234567890123456789012345678901234567"
- "890123456789012345678901234567890123456789\0SUBSYSTEM=block\0"}));
+ 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 1af7274..43c38dc 100644
--- a/health/utils/libhealthloop/include/health/HealthLoop.h
+++ b/health/utils/libhealthloop/include/health/HealthLoop.h
@@ -93,6 +93,7 @@
void WakeAlarmInit();
void WakeAlarmEvent(uint32_t);
void UeventInit();
+ bool RecvUevents();
void UeventEvent(uint32_t);
void WakeAlarmSetInterval(int interval);
void PeriodicChores();
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/radio_sim_test.cpp b/radio/aidl/vts/radio_sim_test.cpp
index 9d1c356..6ffe2c5 100644
--- a/radio/aidl/vts/radio_sim_test.cpp
+++ b/radio/aidl/vts/radio_sim_test.cpp
@@ -531,7 +531,7 @@
EXPECT_EQ(RadioError::NONE, radioRsp_sim->rspInfo.error);
if (aidl_version <= 2) {
- EXPECT_EQ(1, radioRsp_sim->carrierRestrictionsResp.allowedCarriers.size());
+ ASSERT_EQ(1, radioRsp_sim->carrierRestrictionsResp.allowedCarriers.size());
EXPECT_EQ(0, radioRsp_sim->carrierRestrictionsResp.excludedCarriers.size());
ASSERT_TRUE(std::string("123") ==
@@ -543,7 +543,7 @@
ASSERT_TRUE(radioRsp_sim->carrierRestrictionsResp.allowedCarriersPrioritized);
EXPECT_EQ(SimLockMultiSimPolicy::NO_MULTISIM_POLICY, radioRsp_sim->multiSimPolicyResp);
} else {
- EXPECT_EQ(1, radioRsp_sim->carrierRestrictionsResp.allowedCarrierInfoList.size());
+ ASSERT_EQ(1, radioRsp_sim->carrierRestrictionsResp.allowedCarrierInfoList.size());
EXPECT_EQ(0, radioRsp_sim->carrierRestrictionsResp.excludedCarrierInfoList.size());
ASSERT_TRUE(std::string("321") ==
radioRsp_sim->carrierRestrictionsResp.allowedCarrierInfoList[0].mcc);
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/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index 2ba75a3..c19ab11 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -236,10 +236,10 @@
/**
* An API to determine device IDs attestation is required or not,
- * which is mandatory for KeyMint version 2 or first_api_level 33 or greater.
+ * which is mandatory for KeyMint version 2 and first_api_level 33 or greater.
*/
bool KeyMintAidlTestBase::isDeviceIdAttestationRequired() {
- return AidlVersion() >= 2 || property_get_int32("ro.vendor.api_level", 0) >= __ANDROID_API_T__;
+ return AidlVersion() >= 2 && property_get_int32("ro.vendor.api_level", 0) >= __ANDROID_API_T__;
}
/**
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..b7c32ca 100644
--- a/security/keymint/support/include/remote_prov/remote_prov_utils.h
+++ b/security/keymint/support/include/remote_prov/remote_prov_utils.h
@@ -167,7 +167,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
@@ -181,7 +182,8 @@
*/
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);
diff --git a/security/keymint/support/remote_prov_utils.cpp b/security/keymint/support/remote_prov_utils.cpp
index 29124af..646037c 100644
--- a/security/keymint/support/remote_prov_utils.cpp
+++ b/security/keymint/support/remote_prov_utils.cpp
@@ -325,9 +325,16 @@
}
ErrMsgOr<std::vector<BccEntryData>> validateBcc(const cppbor::Array* bcc,
- hwtrust::DiceChain::Kind kind) {
+ hwtrust::DiceChain::Kind kind, bool allowAnyMode) {
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();
auto keys = chain->CosePublicKeys();
if (!keys.ok()) return keys.error().message();
@@ -638,7 +645,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 +701,7 @@
}
// BCC is [ pubkey, + BccEntry]
- auto bccContents = validateBcc(bcc->asArray(), hwtrust::DiceChain::Kind::kVsr13);
+ auto bccContents = validateBcc(bcc->asArray(), hwtrust::DiceChain::Kind::kVsr13, allowAnyMode);
if (!bccContents) {
return bccContents.message() + "\n" + prettyPrint(bcc.get());
}
@@ -747,10 +754,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) {
@@ -988,7 +996,8 @@
}
ErrMsgOr<bytevec> parseAndValidateAuthenticatedRequest(const std::vector<uint8_t>& request,
- const std::vector<uint8_t>& challenge) {
+ const std::vector<uint8_t>& challenge,
+ bool allowAnyMode = false) {
auto [parsedRequest, _, csrErrMsg] = cppbor::parse(request);
if (!parsedRequest) {
return csrErrMsg;
@@ -1026,7 +1035,7 @@
return diceChainKind.message();
}
- auto diceContents = validateBcc(diceCertChain, *diceChainKind);
+ auto diceContents = validateBcc(diceCertChain, *diceChainKind, allowAnyMode);
if (!diceContents) {
return diceContents.message() + "\n" + prettyPrint(diceCertChain);
}
@@ -1055,7 +1064,7 @@
const std::vector<uint8_t>& csr,
IRemotelyProvisionedComponent* provisionable,
const std::vector<uint8_t>& challenge,
- bool isFactory) {
+ bool isFactory, bool allowAnyMode = false) {
RpcHardwareInfo info;
provisionable->getHardwareInfo(&info);
if (info.versionNumber != 3) {
@@ -1063,7 +1072,7 @@
") does not match expected version (3).";
}
- auto csrPayload = parseAndValidateAuthenticatedRequest(csr, challenge);
+ auto csrPayload = parseAndValidateAuthenticatedRequest(csr, challenge, allowAnyMode);
if (!csrPayload) {
return csrPayload.message();
}
@@ -1079,8 +1088,9 @@
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) {
@@ -1114,7 +1124,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/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/threadnetwork/aidl/default/Android.bp b/threadnetwork/aidl/default/Android.bp
index 51e5c25..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",
diff --git a/threadnetwork/aidl/default/socket_interface.cpp b/threadnetwork/aidl/default/socket_interface.cpp
index 339fd6b..a5aa2b4 100644
--- a/threadnetwork/aidl/default/socket_interface.cpp
+++ b/threadnetwork/aidl/default/socket_interface.cpp
@@ -94,8 +94,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 +133,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;
@@ -314,8 +314,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/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 5dbc7f6..a76a653 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/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/vts/VtsHalVibratorTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
index 33e8660..bc017ae 100644
--- a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
+++ b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
@@ -1053,59 +1053,62 @@
}
TEST_P(VibratorAidl, PwleV2FrequencyToOutputAccelerationMapHasValidFrequencyRange) {
+ if (!(capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS_V2)) {
+ GTEST_SKIP() << "PWLE V2 not supported, skipping test";
+ return;
+ }
+
std::vector<PwleV2OutputMapEntry> frequencyToOutputAccelerationMap;
ndk::ScopedAStatus status =
vibrator->getPwleV2FrequencyToOutputAccelerationMap(&frequencyToOutputAccelerationMap);
- if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS_V2) {
- EXPECT_OK(std::move(status));
- ASSERT_FALSE(frequencyToOutputAccelerationMap.empty());
- auto sharpnessRange =
- pwle_v2_utils::getPwleV2SharpnessRange(vibrator, frequencyToOutputAccelerationMap);
- // Validate the curve provides a usable sharpness range, which is a range of frequencies
- // that are supported by the device.
- ASSERT_TRUE(sharpnessRange.first >= 0);
- // Validate that the sharpness range is a valid interval, not a single point.
- ASSERT_TRUE(sharpnessRange.first < sharpnessRange.second);
- } else {
- EXPECT_UNKNOWN_OR_UNSUPPORTED(std::move(status));
- }
+ EXPECT_OK(std::move(status));
+ ASSERT_FALSE(frequencyToOutputAccelerationMap.empty());
+ auto sharpnessRange =
+ pwle_v2_utils::getPwleV2SharpnessRange(vibrator, frequencyToOutputAccelerationMap);
+ // Validate the curve provides a usable sharpness range, which is a range of frequencies
+ // that are supported by the device.
+ ASSERT_TRUE(sharpnessRange.first >= 0);
+ // Validate that the sharpness range is a valid interval, not a single point.
+ ASSERT_TRUE(sharpnessRange.first < sharpnessRange.second);
}
TEST_P(VibratorAidl, GetPwleV2PrimitiveDurationMaxMillis) {
+ if (!(capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS_V2)) {
+ GTEST_SKIP() << "PWLE V2 not supported, skipping test";
+ return;
+ }
+
int32_t durationMs;
ndk::ScopedAStatus status = vibrator->getPwleV2PrimitiveDurationMaxMillis(&durationMs);
- if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS_V2) {
- EXPECT_OK(std::move(status));
- ASSERT_GT(durationMs, 0); // Ensure greater than zero
- ASSERT_GE(durationMs,
- pwle_v2_utils::COMPOSE_PWLE_V2_MIN_REQUIRED_PRIMITIVE_MAX_DURATION_MS);
- } else {
- EXPECT_UNKNOWN_OR_UNSUPPORTED(std::move(status));
- }
+ EXPECT_OK(std::move(status));
+ ASSERT_GT(durationMs, 0); // Ensure greater than zero
+ ASSERT_GE(durationMs, pwle_v2_utils::COMPOSE_PWLE_V2_MIN_REQUIRED_PRIMITIVE_MAX_DURATION_MS);
}
TEST_P(VibratorAidl, GetPwleV2CompositionSizeMax) {
+ if (!(capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS_V2)) {
+ GTEST_SKIP() << "PWLE V2 not supported, skipping test";
+ return;
+ }
+
int32_t maxSize;
ndk::ScopedAStatus status = vibrator->getPwleV2CompositionSizeMax(&maxSize);
- if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS_V2) {
- EXPECT_OK(std::move(status));
- ASSERT_GT(maxSize, 0); // Ensure greater than zero
- ASSERT_GE(maxSize, pwle_v2_utils::COMPOSE_PWLE_V2_MIN_REQUIRED_SIZE);
- } else {
- EXPECT_UNKNOWN_OR_UNSUPPORTED(std::move(status));
- }
+ EXPECT_OK(std::move(status));
+ ASSERT_GT(maxSize, 0); // Ensure greater than zero
+ ASSERT_GE(maxSize, pwle_v2_utils::COMPOSE_PWLE_V2_MIN_REQUIRED_SIZE);
}
TEST_P(VibratorAidl, GetPwleV2PrimitiveDurationMinMillis) {
+ if (!(capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS_V2)) {
+ GTEST_SKIP() << "PWLE V2 not supported, skipping test";
+ return;
+ }
+
int32_t durationMs;
ndk::ScopedAStatus status = vibrator->getPwleV2PrimitiveDurationMinMillis(&durationMs);
- if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS_V2) {
- EXPECT_OK(std::move(status));
- ASSERT_GT(durationMs, 0); // Ensure greater than zero
- ASSERT_LE(durationMs, pwle_v2_utils::COMPOSE_PWLE_V2_MAX_ALLOWED_PRIMITIVE_MIN_DURATION_MS);
- } else {
- EXPECT_UNKNOWN_OR_UNSUPPORTED(std::move(status));
- }
+ EXPECT_OK(std::move(status));
+ ASSERT_GT(durationMs, 0); // Ensure greater than zero
+ ASSERT_LE(durationMs, pwle_v2_utils::COMPOSE_PWLE_V2_MAX_ALLOWED_PRIMITIVE_MIN_DURATION_MS);
}
TEST_P(VibratorAidl, ComposeValidPwleV2Effect) {
@@ -1125,8 +1128,10 @@
}
if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS_V2) return;
- EXPECT_UNKNOWN_OR_UNSUPPORTED(
- vibrator->composePwleV2(pwle_v2_utils::composeValidPwleV2Effect(vibrator), nullptr));
+ std::vector<PwleV2Primitive> pwleEffect{
+ PwleV2Primitive(/*amplitude=*/1.0f, /*frequencyHz=*/100.0f, /*timeMillis=*/50)};
+
+ EXPECT_UNKNOWN_OR_UNSUPPORTED(vibrator->composePwleV2(pwleEffect, nullptr));
}
TEST_P(VibratorAidl, ComposeValidPwleV2EffectWithCallback) {
diff --git a/vibrator/aidl/vts/pwle_v2_utils.h b/vibrator/aidl/vts/pwle_v2_utils.h
index feb8790..2163908 100644
--- a/vibrator/aidl/vts/pwle_v2_utils.h
+++ b/vibrator/aidl/vts/pwle_v2_utils.h
@@ -120,6 +120,11 @@
EXPECT_OK(
vibrator->getPwleV2FrequencyToOutputAccelerationMap(&frequencyToOutputAccelerationMap));
EXPECT_TRUE(!frequencyToOutputAccelerationMap.empty());
+ // We can't use ASSERT_TRUE() above because this is a non-void function,
+ // but we need to return to assure we don't crash from a null dereference.
+ if (frequencyToOutputAccelerationMap.empty()) {
+ return std::numeric_limits<float>::quiet_NaN();
+ }
auto entry = std::min_element(
frequencyToOutputAccelerationMap.begin(), frequencyToOutputAccelerationMap.end(),
@@ -133,6 +138,11 @@
EXPECT_OK(
vibrator->getPwleV2FrequencyToOutputAccelerationMap(&frequencyToOutputAccelerationMap));
EXPECT_TRUE(!frequencyToOutputAccelerationMap.empty());
+ // We can't use ASSERT_TRUE() above because this is a non-void function,
+ // but we need to return to assure we don't crash from a null dereference.
+ if (frequencyToOutputAccelerationMap.empty()) {
+ return std::numeric_limits<float>::quiet_NaN();
+ }
auto entry = std::max_element(
frequencyToOutputAccelerationMap.begin(), frequencyToOutputAccelerationMap.end(),
diff --git a/weaver/vts/VtsHalWeaverTargetTest.cpp b/weaver/vts/VtsHalWeaverTargetTest.cpp
index 40e9558..8952dfc 100644
--- a/weaver/vts/VtsHalWeaverTargetTest.cpp
+++ b/weaver/vts/VtsHalWeaverTargetTest.cpp
@@ -221,7 +221,10 @@
}
}
// 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.
+ // supported at all. This is true even if an LSKF hasn't been set yet, since Weaver is used to
+ // protect the initial binding of each user's synthetic password to ensure that binding can be
+ // securely deleted if an LSKF is set later. Make sure we saw at least one slot, as otherwise
+ // the Weaver implementation must have a bug that makes it not fully usable by Android.
ASSERT_FALSE(used_slots.empty())
<< "Could not determine which Weaver slots are in use by the system";
diff --git a/wifi/aidl/default/Android.bp b/wifi/aidl/default/Android.bp
index 2047807..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 {
diff --git a/wifi/hostapd/aidl/Android.bp b/wifi/hostapd/aidl/Android.bp
index 2e4d4d1..88f4ef2 100644
--- a/wifi/hostapd/aidl/Android.bp
+++ b/wifi/hostapd/aidl/Android.bp
@@ -65,5 +65,5 @@
},
],
- frozen: true,
+ frozen: false,
}
diff --git a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/BandMask.aidl b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/BandMask.aidl
index b1e7f66..fa9f198 100644
--- a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/BandMask.aidl
+++ b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/BandMask.aidl
@@ -34,8 +34,8 @@
package android.hardware.wifi.hostapd;
@Backing(type="int") @VintfStability
enum BandMask {
- BAND_2_GHZ = 1,
- BAND_5_GHZ = 2,
- BAND_6_GHZ = 4,
- BAND_60_GHZ = 8,
+ BAND_2_GHZ = (1 << 0) /* 1 */,
+ BAND_5_GHZ = (1 << 1) /* 2 */,
+ BAND_6_GHZ = (1 << 2) /* 4 */,
+ BAND_60_GHZ = (1 << 3) /* 8 */,
}
diff --git a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/EncryptionType.aidl b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/EncryptionType.aidl
index a7b20fa..840b875 100644
--- a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/EncryptionType.aidl
+++ b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/EncryptionType.aidl
@@ -34,11 +34,11 @@
package android.hardware.wifi.hostapd;
@Backing(type="int") @VintfStability
enum EncryptionType {
- NONE = 0,
- WPA = 1,
- WPA2 = 2,
- WPA3_SAE_TRANSITION = 3,
- WPA3_SAE = 4,
- WPA3_OWE_TRANSITION = 5,
- WPA3_OWE = 6,
+ NONE,
+ WPA,
+ WPA2,
+ WPA3_SAE_TRANSITION,
+ WPA3_SAE,
+ WPA3_OWE_TRANSITION,
+ WPA3_OWE,
}
diff --git a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/Generation.aidl b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/Generation.aidl
index 5bb0d32..a0c1886 100644
--- a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/Generation.aidl
+++ b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/Generation.aidl
@@ -34,7 +34,7 @@
package android.hardware.wifi.hostapd;
@Backing(type="int") @VintfStability
enum Generation {
- WIFI_STANDARD_UNKNOWN = -1,
+ WIFI_STANDARD_UNKNOWN = (-1) /* -1 */,
WIFI_STANDARD_LEGACY = 0,
WIFI_STANDARD_11N = 1,
WIFI_STANDARD_11AC = 2,
diff --git a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/HostapdStatusCode.aidl b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/HostapdStatusCode.aidl
index 548e497..7edff15 100644
--- a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/HostapdStatusCode.aidl
+++ b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/HostapdStatusCode.aidl
@@ -34,10 +34,10 @@
package android.hardware.wifi.hostapd;
@Backing(type="int") @VintfStability
enum HostapdStatusCode {
- SUCCESS = 0,
- FAILURE_UNKNOWN = 1,
- FAILURE_ARGS_INVALID = 2,
- FAILURE_IFACE_UNKNOWN = 3,
- FAILURE_IFACE_EXISTS = 4,
- FAILURE_CLIENT_UNKNOWN = 5,
+ SUCCESS,
+ FAILURE_UNKNOWN,
+ FAILURE_ARGS_INVALID,
+ FAILURE_IFACE_UNKNOWN,
+ FAILURE_IFACE_EXISTS,
+ FAILURE_CLIENT_UNKNOWN,
}
diff --git a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/IfaceParams.aidl b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/IfaceParams.aidl
index 64367bb..8da3441 100644
--- a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/IfaceParams.aidl
+++ b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/IfaceParams.aidl
@@ -38,4 +38,6 @@
android.hardware.wifi.hostapd.HwModeParams hwModeParams;
android.hardware.wifi.hostapd.ChannelParams[] channelParams;
@nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
+ @nullable String[] instanceIdentities;
+ boolean isMlo;
}
diff --git a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/IfaceParams.aidl b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/IfaceParams.aidl
index 3f8ee39..bb646e3 100644
--- a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/IfaceParams.aidl
+++ b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/IfaceParams.aidl
@@ -41,4 +41,12 @@
* Optional vendor-specific configuration parameters.
*/
@nullable OuiKeyedData[] vendorData;
+ /**
+ * The list of the instance identities.
+ */
+ @nullable String[] instanceIdentities;
+ /**
+ * Whether the current iface is MLO.
+ */
+ boolean isMlo;
}
diff --git a/wifi/hostapd/aidl/vts/functional/Android.bp b/wifi/hostapd/aidl/vts/functional/Android.bp
index f614679..bf1b0d0 100644
--- a/wifi/hostapd/aidl/vts/functional/Android.bp
+++ b/wifi/hostapd/aidl/vts/functional/Android.bp
@@ -21,7 +21,7 @@
"libvndksupport",
],
static_libs: [
- "android.hardware.wifi.hostapd-V2-ndk",
+ "android.hardware.wifi.hostapd-V3-ndk",
"VtsHalWifiV1_0TargetTestUtil",
"VtsHalWifiV1_5TargetTestUtil",
"VtsHalWifiV1_6TargetTestUtil",