mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 16:50:18 +00:00
Merge "audio: Create libraries for data types in core and effect" am: 1df025e5f4
Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/1566743 MUST ONLY BE SUBMITTED BY AUTOMERGER Change-Id: I09365ca3d301325acd9c239d1b526507a9329003
This commit is contained in:
@@ -255,7 +255,6 @@ package android.audio.policy.configuration.V7_0 {
|
||||
enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_HW_AV_SYNC;
|
||||
enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_HW_HOTWORD;
|
||||
enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_MMAP_NOIRQ;
|
||||
enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_NONE;
|
||||
enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_RAW;
|
||||
enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_SYNC;
|
||||
enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_VOIP_TX;
|
||||
@@ -268,7 +267,6 @@ package android.audio.policy.configuration.V7_0 {
|
||||
enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO;
|
||||
enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_INCALL_MUSIC;
|
||||
enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_MMAP_NOIRQ;
|
||||
enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_NONE;
|
||||
enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_NON_BLOCKING;
|
||||
enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_PRIMARY;
|
||||
enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_RAW;
|
||||
|
||||
@@ -159,13 +159,9 @@
|
||||
<xs:annotation>
|
||||
<xs:documentation xml:lang="en">
|
||||
The flags indicate suggested stream attributes supported by the profile.
|
||||
Use of AUDIO_{INPUT|OUTPUT}_FLAG_NONE in the XML file isn't required
|
||||
as empty flag lists are allowed. However these constants are useful for
|
||||
representing an empty enum value.
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:enumeration value="AUDIO_OUTPUT_FLAG_NONE" />
|
||||
<xs:enumeration value="AUDIO_OUTPUT_FLAG_DIRECT" />
|
||||
<xs:enumeration value="AUDIO_OUTPUT_FLAG_PRIMARY" />
|
||||
<xs:enumeration value="AUDIO_OUTPUT_FLAG_FAST" />
|
||||
@@ -181,7 +177,6 @@
|
||||
<xs:enumeration value="AUDIO_OUTPUT_FLAG_MMAP_NOIRQ" />
|
||||
<xs:enumeration value="AUDIO_OUTPUT_FLAG_VOIP_RX" />
|
||||
<xs:enumeration value="AUDIO_OUTPUT_FLAG_INCALL_MUSIC" />
|
||||
<xs:enumeration value="AUDIO_INPUT_FLAG_NONE" />
|
||||
<xs:enumeration value="AUDIO_INPUT_FLAG_FAST" />
|
||||
<xs:enumeration value="AUDIO_INPUT_FLAG_HW_HOTWORD" />
|
||||
<xs:enumeration value="AUDIO_INPUT_FLAG_RAW" />
|
||||
|
||||
@@ -7,47 +7,49 @@ based on an existing one.
|
||||
|
||||
## Directory Structure
|
||||
|
||||
* `2.0` -- version 2.0 of the core HIDL API. Note that `.hal` files
|
||||
* `2.0` — version 2.0 of the core HIDL API. Note that `.hal` files
|
||||
can not be moved into the `core` directory because that would change
|
||||
its namespace and include path.
|
||||
- `config` -- the XSD schema for the Audio Policy Manager
|
||||
- `config` — the XSD schema for the Audio Policy Manager
|
||||
configuration file.
|
||||
* `4.0` -- version 4.0 of the core HIDL API.
|
||||
* `4.0` — version 4.0 of the core HIDL API.
|
||||
* ...
|
||||
* `common` -- common types for audio core and effect HIDL API.
|
||||
- `2.0` -- version 2.0 of the common types HIDL API.
|
||||
- `4.0` -- version 4.0.
|
||||
* `common` — common types for audio core and effect HIDL API.
|
||||
- `2.0` — version 2.0 of the common types HIDL API.
|
||||
- `4.0` — version 4.0.
|
||||
- ...
|
||||
- `7.0` -- version 7.0.
|
||||
- `example` -- example implementation of the core and effect
|
||||
- `7.0` — version 7.0.
|
||||
- `example` — example implementation of the core and effect
|
||||
V7.0 API. It represents a "fake" audio HAL that doesn't
|
||||
actually communicate with hardware.
|
||||
- `all-versions` -- code common to all version of both core and effect API.
|
||||
- `default` -- shared code of the default implementation.
|
||||
- `service` -- vendor HAL service for hosting the default
|
||||
- `all-versions` — code common to all version of both core and effect API.
|
||||
- `default` — shared code of the default implementation.
|
||||
- `service` — vendor HAL service for hosting the default
|
||||
implementation.
|
||||
- `test` -- utilities used by tests.
|
||||
- `util` -- utilities used by both implementation and tests.
|
||||
* `core` -- VTS tests and the default implementation of the core API
|
||||
- `test` — utilities used by tests.
|
||||
- `util` — utilities used by both implementation and tests.
|
||||
* `core` — VTS tests and the default implementation of the core API
|
||||
(not HIDL API, it's in `audio/N.M`).
|
||||
- `7.0` -- code specific to version V7.0 of the core HIDL API
|
||||
- `all-versions` -- the code is common between all versions,
|
||||
- `7.0` — code specific to version V7.0 of the core HIDL API
|
||||
- `all-versions` — the code is common between all versions,
|
||||
version-specific parts are enclosed into conditional directives
|
||||
of preprocessor or reside in dedicated files.
|
||||
- `default` -- code that wraps the legacy API (from
|
||||
- `default` — code that wraps the legacy API (from
|
||||
`hardware/libhardware`).
|
||||
- `util` — utilities for the default implementation.
|
||||
- `vts` VTS tests for the core HIDL API.
|
||||
* `effect` -- same for the effect HIDL API.
|
||||
* `effect` — same for the effect HIDL API.
|
||||
- `2.0`
|
||||
- `config` -- the XSD schema for the Audio Effects configuration
|
||||
file.
|
||||
- `config` — the XSD schema for the Audio Effects configuration file.
|
||||
- `4.0`
|
||||
- ...
|
||||
- `all-versions`
|
||||
- `default`
|
||||
- `vts`
|
||||
* `policy` -- Configurable Audio Policy schemes.
|
||||
- `1.0` -- note that versions of CAP are not linked to the versions
|
||||
- `default` — code that wraps the legacy API (from
|
||||
`hardware/libhardware`).
|
||||
- `util` — utilities for the default implementation.
|
||||
- `vts` VTS tests for the effect HIDL API.
|
||||
* `policy` — Configurable Audio Policy schemes.
|
||||
- `1.0` — note that versions of CAP are not linked to the versions
|
||||
of audio HAL.
|
||||
- `vts` -- VTS tests for validating actual configuration files.
|
||||
- `xml` -- XSD schemas for CAP configuration files.
|
||||
- `vts` — VTS tests for validating actual configuration files.
|
||||
- `xml` — XSD schemas for CAP configuration files.
|
||||
|
||||
@@ -212,10 +212,16 @@ static inline bool isOutputDevice(const std::string& device) {
|
||||
return isOutputDevice(stringToAudioDevice(device));
|
||||
}
|
||||
|
||||
static inline bool maybeVendorExtension(const std::string& s) {
|
||||
// Only checks whether the string starts with the "vendor prefix".
|
||||
static const std::string vendorPrefix = "VX_";
|
||||
return s.size() > vendorPrefix.size() && s.substr(0, vendorPrefix.size()) == vendorPrefix;
|
||||
}
|
||||
|
||||
static inline bool isVendorExtension(const std::string& s) {
|
||||
// Must match the "vendorExtension" rule from the XSD file.
|
||||
static const std::string vendorPrefix = "VX_";
|
||||
return s.size() > vendorPrefix.size() && s.substr(0, vendorPrefix.size()) == vendorPrefix &&
|
||||
return maybeVendorExtension(s) &&
|
||||
std::all_of(s.begin() + vendorPrefix.size(), s.end(),
|
||||
[](unsigned char c) { return c == '_' || std::isalnum(c); });
|
||||
}
|
||||
|
||||
@@ -309,15 +309,15 @@ typedef string AudioTag;
|
||||
struct PlaybackTrackMetadata {
|
||||
AudioUsage usage;
|
||||
AudioContentType contentType;
|
||||
/** Tags from AudioTrack audio atttributes */
|
||||
vec<AudioTag> tags;
|
||||
AudioChannelMask channelMask;
|
||||
/**
|
||||
* Positive linear gain applied to the track samples. 0 being muted and 1 is no attenuation,
|
||||
* 2 means double amplification...
|
||||
* Must not be negative.
|
||||
*/
|
||||
float gain;
|
||||
AudioChannelMask channelMask;
|
||||
/** Tags from AudioTrack audio atttributes */
|
||||
vec<AudioTag> tags;
|
||||
};
|
||||
|
||||
/** Metadatas of the source of a StreamOut. */
|
||||
@@ -328,9 +328,6 @@ struct SourceMetadata {
|
||||
/** Metadata of a record track for a StreamIn. */
|
||||
struct RecordTrackMetadata {
|
||||
AudioSource source;
|
||||
/** Tags from AudioTrack audio atttributes */
|
||||
vec<AudioTag> tags;
|
||||
AudioChannelMask channelMask;
|
||||
/**
|
||||
* Positive linear gain applied to the track samples. 0 being muted and 1 is no attenuation,
|
||||
* 2 means double amplification...
|
||||
@@ -344,6 +341,9 @@ struct RecordTrackMetadata {
|
||||
Monostate unspecified;
|
||||
DeviceAddress device;
|
||||
} destination;
|
||||
AudioChannelMask channelMask;
|
||||
/** Tags from AudioTrack audio atttributes */
|
||||
vec<AudioTag> tags;
|
||||
};
|
||||
|
||||
/** Metadatas of the sink of a StreamIn. */
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <algorithm>
|
||||
|
||||
#define LOG_TAG "HidlUtils"
|
||||
#include <log/log.h>
|
||||
@@ -281,7 +282,7 @@ status_t HidlUtils::audioGainModeMaskFromHal(audio_gain_mode_t halGainModeMask,
|
||||
hidl_vec<AudioGainMode>* gainModeMask) {
|
||||
status_t status = NO_ERROR;
|
||||
std::vector<AudioGainMode> result;
|
||||
for (uint32_t bit = 0; bit < sizeof(audio_gain_mode_t) * 8; ++bit) {
|
||||
for (uint32_t bit = 0; halGainModeMask != 0 && bit < sizeof(audio_gain_mode_t) * 8; ++bit) {
|
||||
audio_gain_mode_t flag = static_cast<audio_gain_mode_t>(1u << bit);
|
||||
if ((flag & halGainModeMask) == flag) {
|
||||
AudioGainMode flagStr = audio_gain_mode_to_string(flag);
|
||||
@@ -291,6 +292,7 @@ status_t HidlUtils::audioGainModeMaskFromHal(audio_gain_mode_t halGainModeMask,
|
||||
ALOGE("Unknown audio gain mode value 0x%X", flag);
|
||||
status = BAD_VALUE;
|
||||
}
|
||||
halGainModeMask = static_cast<audio_gain_mode_t>(halGainModeMask & ~flag);
|
||||
}
|
||||
}
|
||||
*gainModeMask = result;
|
||||
@@ -858,15 +860,17 @@ status_t HidlUtils::audioProfileToHal(const AudioProfile& profile,
|
||||
return result;
|
||||
}
|
||||
|
||||
status_t HidlUtils::audioTagsFromHal(const char* halTags, hidl_vec<AudioTag>* tags) {
|
||||
std::vector<std::string> strTags = utils::splitString(halTags, sAudioTagSeparator);
|
||||
status_t HidlUtils::audioTagsFromHal(const std::vector<std::string>& strTags,
|
||||
hidl_vec<AudioTag>* tags) {
|
||||
status_t result = NO_ERROR;
|
||||
tags->resize(strTags.size());
|
||||
size_t to = 0;
|
||||
for (size_t from = 0; from < strTags.size(); ++from) {
|
||||
if (xsd::isVendorExtension(strTags[from])) {
|
||||
(*tags)[to++] = strTags[from];
|
||||
const auto& tag = strTags[from];
|
||||
if (xsd::isVendorExtension(tag)) {
|
||||
(*tags)[to++] = tag;
|
||||
} else {
|
||||
ALOGE("Vendor extension tag is ill-formed: \"%s\"", tag.c_str());
|
||||
result = BAD_VALUE;
|
||||
}
|
||||
}
|
||||
@@ -889,6 +893,7 @@ status_t HidlUtils::audioTagsToHal(const hidl_vec<AudioTag>& tags, char* halTags
|
||||
halTagsBuffer << tag;
|
||||
hasValue = true;
|
||||
} else {
|
||||
ALOGE("Vendor extension tag is ill-formed: \"%s\"", tag.c_str());
|
||||
result = BAD_VALUE;
|
||||
}
|
||||
}
|
||||
@@ -899,6 +904,31 @@ status_t HidlUtils::audioTagsToHal(const hidl_vec<AudioTag>& tags, char* halTags
|
||||
return result;
|
||||
}
|
||||
|
||||
hidl_vec<AudioTag> HidlUtils::filterOutNonVendorTags(const hidl_vec<AudioTag>& tags) {
|
||||
hidl_vec<AudioTag> result;
|
||||
result.resize(tags.size());
|
||||
size_t resultIdx = 0;
|
||||
for (const auto& tag : tags) {
|
||||
if (xsd::maybeVendorExtension(tag)) {
|
||||
result[resultIdx++] = tag;
|
||||
}
|
||||
}
|
||||
if (resultIdx != result.size()) {
|
||||
result.resize(resultIdx);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<std::string> HidlUtils::filterOutNonVendorTags(const std::vector<std::string>& tags) {
|
||||
std::vector<std::string> result;
|
||||
std::copy_if(tags.begin(), tags.end(), std::back_inserter(result), xsd::maybeVendorExtension);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<std::string> HidlUtils::splitAudioTags(const char* halTags) {
|
||||
return utils::splitString(halTags, sAudioTagSeparator);
|
||||
}
|
||||
|
||||
status_t HidlUtils::deviceAddressFromHal(audio_devices_t halDeviceType,
|
||||
const char* halDeviceAddress, DeviceAddress* device) {
|
||||
status_t result = NO_ERROR;
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <system/audio.h>
|
||||
|
||||
@@ -118,8 +120,12 @@ struct HidlUtils {
|
||||
AudioStreamType* streamType);
|
||||
static status_t audioStreamTypeToHal(const AudioStreamType& streamType,
|
||||
audio_stream_type_t* halStreamType);
|
||||
static status_t audioTagsFromHal(const char* halTags, hidl_vec<AudioTag>* tags);
|
||||
static status_t audioTagsFromHal(const std::vector<std::string>& strTags,
|
||||
hidl_vec<AudioTag>* tags);
|
||||
static status_t audioTagsToHal(const hidl_vec<AudioTag>& tags, char* halTags);
|
||||
static hidl_vec<AudioTag> filterOutNonVendorTags(const hidl_vec<AudioTag>& tags);
|
||||
static std::vector<std::string> filterOutNonVendorTags(const std::vector<std::string>& tags);
|
||||
static std::vector<std::string> splitAudioTags(const char* halTags);
|
||||
|
||||
private:
|
||||
static status_t audioIndexChannelMaskFromHal(audio_channel_mask_t halChannelMask,
|
||||
|
||||
@@ -42,6 +42,14 @@ void UuidUtils::uuidToHal(const Uuid& uuid, audio_uuid_t* halUuid) {
|
||||
memcpy(halUuid->node, uuid.node.data(), uuid.node.size());
|
||||
}
|
||||
|
||||
std::string UuidUtils::uuidToString(const audio_uuid_t& halUuid) {
|
||||
char str[64];
|
||||
snprintf(str, sizeof(str), "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x", halUuid.timeLow,
|
||||
halUuid.timeMid, halUuid.timeHiAndVersion, halUuid.clockSeq, halUuid.node[0],
|
||||
halUuid.node[1], halUuid.node[2], halUuid.node[3], halUuid.node[4], halUuid.node[5]);
|
||||
return str;
|
||||
}
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace CPP_VERSION
|
||||
} // namespace common
|
||||
|
||||
@@ -17,14 +17,14 @@
|
||||
#ifndef android_hardware_audio_Uuid_Utils_H_
|
||||
#define android_hardware_audio_Uuid_Utils_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
// clang-format off
|
||||
#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
|
||||
// clang-format on
|
||||
|
||||
#include <system/audio.h>
|
||||
|
||||
using ::android::hardware::hidl_vec;
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace audio {
|
||||
@@ -38,6 +38,7 @@ class UuidUtils {
|
||||
public:
|
||||
static void uuidFromHal(const audio_uuid_t& halUuid, Uuid* uuid);
|
||||
static void uuidToHal(const Uuid& uuid, audio_uuid_t* halUuid);
|
||||
static std::string uuidToString(const audio_uuid_t& halUuid);
|
||||
};
|
||||
|
||||
} // namespace implementation
|
||||
|
||||
@@ -762,9 +762,7 @@ TEST(HidlUtils, ConvertInvalidOffloadInfo) {
|
||||
|
||||
TEST(HidlUtils, ConvertOffloadInfo) {
|
||||
AudioOffloadInfo offloadInfo = {};
|
||||
offloadInfo.base.sampleRateHz = 44100;
|
||||
offloadInfo.base.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO);
|
||||
offloadInfo.base.format = toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT);
|
||||
offloadInfo.base = generateValidConfigBase(false /*isInput*/);
|
||||
offloadInfo.streamType = toString(xsd::AudioStreamType::AUDIO_STREAM_MUSIC);
|
||||
offloadInfo.bitRatePerSecond = 320;
|
||||
offloadInfo.durationMicroseconds = -1;
|
||||
@@ -783,33 +781,76 @@ TEST(HidlUtils, ConvertOffloadInfo) {
|
||||
|
||||
TEST(HidlUtils, ConvertInvalidConfig) {
|
||||
AudioConfig invalid;
|
||||
audio_config_t halInvalid = AUDIO_CONFIG_INITIALIZER;
|
||||
halInvalid.channel_mask = kInvalidHalChannelMask;
|
||||
halInvalid.format = kInvalidHalFormat;
|
||||
EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigFromHal(halInvalid, false /*isInput*/, &invalid));
|
||||
EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigFromHal(halInvalid, true /*isInput*/, &invalid));
|
||||
invalid.base.channelMask = "random string";
|
||||
invalid.base.format = "random string";
|
||||
EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigToHal(invalid, &halInvalid));
|
||||
audio_config_t halInvalidChannelMask = AUDIO_CONFIG_INITIALIZER;
|
||||
halInvalidChannelMask.channel_mask = kInvalidHalChannelMask;
|
||||
EXPECT_EQ(BAD_VALUE,
|
||||
HidlUtils::audioConfigFromHal(halInvalidChannelMask, false /*isInput*/, &invalid));
|
||||
EXPECT_EQ(BAD_VALUE,
|
||||
HidlUtils::audioConfigFromHal(halInvalidChannelMask, true /*isInput*/, &invalid));
|
||||
audio_config_t halInvalidFormat = AUDIO_CONFIG_INITIALIZER;
|
||||
halInvalidFormat.format = kInvalidHalFormat;
|
||||
EXPECT_EQ(BAD_VALUE,
|
||||
HidlUtils::audioConfigFromHal(halInvalidFormat, false /*isInput*/, &invalid));
|
||||
EXPECT_EQ(BAD_VALUE,
|
||||
HidlUtils::audioConfigFromHal(halInvalidFormat, true /*isInput*/, &invalid));
|
||||
|
||||
AudioConfig invalidChannelMask;
|
||||
audio_config_t halInvalid;
|
||||
invalidChannelMask.base.channelMask = "random string";
|
||||
invalidChannelMask.base.format = toString(xsd::AudioFormat::AUDIO_FORMAT_DEFAULT);
|
||||
EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigToHal(invalidChannelMask, &halInvalid));
|
||||
AudioConfig invalidFormat;
|
||||
invalidFormat.base.format = "random string";
|
||||
invalidFormat.base.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_NONE);
|
||||
EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigToHal(invalidFormat, &halInvalid));
|
||||
}
|
||||
|
||||
TEST(HidlUtils, ConvertConfigDefault) {
|
||||
audio_config_t halDefault = AUDIO_CONFIG_INITIALIZER;
|
||||
AudioConfig defaultOut, defaultIn;
|
||||
EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigFromHal(halDefault, false /*isInput*/, &defaultOut));
|
||||
EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigFromHal(halDefault, true /*isInput*/, &defaultIn));
|
||||
EXPECT_EQ(defaultOut, defaultIn);
|
||||
EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigToHal(defaultOut, &halDefault));
|
||||
|
||||
// Note: empty channel mask and config are not valid values.
|
||||
AudioConfig defaultCfg{};
|
||||
defaultCfg.base.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_NONE);
|
||||
defaultCfg.base.format = toString(xsd::AudioFormat::AUDIO_FORMAT_DEFAULT);
|
||||
audio_config_t halDefaultCfg;
|
||||
EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigToHal(defaultCfg, &halDefaultCfg));
|
||||
AudioConfig defaultCfgBackOut, defaultCfgBackIn;
|
||||
EXPECT_EQ(NO_ERROR,
|
||||
HidlUtils::audioConfigFromHal(halDefaultCfg, false /*isInput*/, &defaultCfgBackOut));
|
||||
EXPECT_EQ(NO_ERROR,
|
||||
HidlUtils::audioConfigFromHal(halDefaultCfg, true /*isInput*/, &defaultCfgBackIn));
|
||||
EXPECT_EQ(defaultCfgBackOut, defaultCfgBackIn);
|
||||
EXPECT_EQ(defaultCfg, defaultCfgBackOut);
|
||||
}
|
||||
|
||||
TEST(HidlUtils, ConvertConfig) {
|
||||
AudioConfig config = {};
|
||||
config.base.sampleRateHz = 44100;
|
||||
config.base.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO);
|
||||
config.base.format = toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT);
|
||||
audio_config_t halConfig;
|
||||
EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigToHal(config, &halConfig));
|
||||
AudioConfig configBack;
|
||||
EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigFromHal(halConfig, false /*isInput*/, &configBack));
|
||||
EXPECT_EQ(config, configBack);
|
||||
AudioConfig configOut{};
|
||||
configOut.base = generateValidConfigBase(false /*isInput*/);
|
||||
audio_config_t halConfigOut;
|
||||
EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigToHal(configOut, &halConfigOut));
|
||||
AudioConfig configOutBack;
|
||||
EXPECT_EQ(NO_ERROR,
|
||||
HidlUtils::audioConfigFromHal(halConfigOut, false /*isInput*/, &configOutBack));
|
||||
EXPECT_EQ(configOut, configOutBack);
|
||||
|
||||
AudioConfig configIn{};
|
||||
configIn.base = generateValidConfigBase(true /*isInput*/);
|
||||
audio_config_t halConfigIn;
|
||||
EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigToHal(configIn, &halConfigIn));
|
||||
AudioConfig configInBack;
|
||||
EXPECT_EQ(NO_ERROR,
|
||||
HidlUtils::audioConfigFromHal(halConfigIn, true /*isInput*/, &configInBack));
|
||||
EXPECT_EQ(configIn, configInBack);
|
||||
}
|
||||
|
||||
TEST(HidlUtils, ConvertConfigWithOffloadInfo) {
|
||||
AudioConfig config = {};
|
||||
config.base.sampleRateHz = 44100;
|
||||
config.base.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO);
|
||||
config.base.format = toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT);
|
||||
config.base = generateValidConfigBase(false /*isInput*/);
|
||||
config.offloadInfo.info(
|
||||
AudioOffloadInfo{.base = config.base,
|
||||
.streamType = toString(xsd::AudioStreamType::AUDIO_STREAM_MUSIC),
|
||||
@@ -952,20 +993,51 @@ TEST(HidlUtils, ConvertAudioTags) {
|
||||
char halEmptyTags[AUDIO_ATTRIBUTES_TAGS_MAX_SIZE] = {};
|
||||
EXPECT_EQ(NO_ERROR, HidlUtils::audioTagsToHal(emptyTags, halEmptyTags));
|
||||
hidl_vec<AudioTag> emptyTagsBack;
|
||||
EXPECT_EQ(NO_ERROR, HidlUtils::audioTagsFromHal(halEmptyTags, &emptyTagsBack));
|
||||
EXPECT_EQ(NO_ERROR,
|
||||
HidlUtils::audioTagsFromHal(HidlUtils::splitAudioTags(halEmptyTags), &emptyTagsBack));
|
||||
EXPECT_EQ(emptyTags, emptyTagsBack);
|
||||
|
||||
hidl_vec<AudioTag> oneTag = {{"VX_GOOGLE_VR"}};
|
||||
char halOneTag[AUDIO_ATTRIBUTES_TAGS_MAX_SIZE] = {};
|
||||
EXPECT_EQ(NO_ERROR, HidlUtils::audioTagsToHal(oneTag, halOneTag));
|
||||
hidl_vec<AudioTag> oneTagBack;
|
||||
EXPECT_EQ(NO_ERROR, HidlUtils::audioTagsFromHal(halOneTag, &oneTagBack));
|
||||
EXPECT_EQ(NO_ERROR,
|
||||
HidlUtils::audioTagsFromHal(HidlUtils::splitAudioTags(halOneTag), &oneTagBack));
|
||||
EXPECT_EQ(oneTag, oneTagBack);
|
||||
|
||||
hidl_vec<AudioTag> twoTags = {{"VX_GOOGLE_VR_42", "VX_GOOGLE_1E100"}};
|
||||
char halTwoTags[AUDIO_ATTRIBUTES_TAGS_MAX_SIZE] = {};
|
||||
EXPECT_EQ(NO_ERROR, HidlUtils::audioTagsToHal(twoTags, halTwoTags));
|
||||
hidl_vec<AudioTag> twoTagsBack;
|
||||
EXPECT_EQ(NO_ERROR, HidlUtils::audioTagsFromHal(halTwoTags, &twoTagsBack));
|
||||
EXPECT_EQ(NO_ERROR,
|
||||
HidlUtils::audioTagsFromHal(HidlUtils::splitAudioTags(halTwoTags), &twoTagsBack));
|
||||
EXPECT_EQ(twoTags, twoTagsBack);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
class FilterTest : public ::testing::Test {};
|
||||
using FilterTestTypeParams = ::testing::Types<hidl_vec<AudioTag>, std::vector<std::string>>;
|
||||
TYPED_TEST_SUITE(FilterTest, FilterTestTypeParams);
|
||||
|
||||
TYPED_TEST(FilterTest, FilterOutNonVendorTags) {
|
||||
TypeParam emptyTags;
|
||||
EXPECT_EQ(emptyTags, HidlUtils::filterOutNonVendorTags(emptyTags));
|
||||
|
||||
TypeParam allVendorTags = {{"VX_GOOGLE_VR_42", "VX_GOOGLE_1E100"}};
|
||||
EXPECT_EQ(allVendorTags, HidlUtils::filterOutNonVendorTags(allVendorTags));
|
||||
|
||||
TypeParam oneVendorTag = {{"", "VX_GOOGLE_VR", "random_string"}};
|
||||
TypeParam oneVendorTagOnly = HidlUtils::filterOutNonVendorTags(oneVendorTag);
|
||||
EXPECT_EQ(1, oneVendorTagOnly.size());
|
||||
EXPECT_EQ(oneVendorTag[1], oneVendorTagOnly[0]);
|
||||
|
||||
// The vendor extension isn't valid, however it must not be filtered out
|
||||
// so the converter can detect the issue.
|
||||
TypeParam oneMaybeVendorTag = {{"", "random string", "VX_GOOGLE_$$"}};
|
||||
TypeParam oneMaybeVendorTagOnly = HidlUtils::filterOutNonVendorTags(oneMaybeVendorTag);
|
||||
EXPECT_EQ(1, oneMaybeVendorTagOnly.size());
|
||||
EXPECT_EQ(oneMaybeVendorTag[2], oneMaybeVendorTagOnly[0]);
|
||||
|
||||
TypeParam noVendorTags = {{"", "random string", "V_"}};
|
||||
EXPECT_EQ(emptyTags, HidlUtils::filterOutNonVendorTags(noVendorTags));
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
filegroup {
|
||||
name: "android.hardware.audio-impl_srcs",
|
||||
srcs: [
|
||||
"Conversions.cpp",
|
||||
"Device.cpp",
|
||||
"DevicesFactory.cpp",
|
||||
"ParametersUtil.cpp",
|
||||
@@ -63,6 +62,7 @@ cc_library_shared {
|
||||
defaults: ["android.hardware.audio-impl_default"],
|
||||
shared_libs: [
|
||||
"android.hardware.audio@2.0",
|
||||
"android.hardware.audio@2.0-util",
|
||||
"android.hardware.audio.common@2.0",
|
||||
"android.hardware.audio.common@2.0-util",
|
||||
],
|
||||
@@ -79,6 +79,7 @@ cc_library_shared {
|
||||
|
||||
shared_libs: [
|
||||
"android.hardware.audio@4.0",
|
||||
"android.hardware.audio@4.0-util",
|
||||
"android.hardware.audio.common@4.0",
|
||||
"android.hardware.audio.common@4.0-util",
|
||||
],
|
||||
@@ -94,6 +95,7 @@ cc_library_shared {
|
||||
defaults: ["android.hardware.audio-impl_default"],
|
||||
shared_libs: [
|
||||
"android.hardware.audio@5.0",
|
||||
"android.hardware.audio@5.0-util",
|
||||
"android.hardware.audio.common@5.0",
|
||||
"android.hardware.audio.common@5.0-util",
|
||||
],
|
||||
@@ -109,6 +111,7 @@ cc_defaults {
|
||||
defaults: ["android.hardware.audio-impl_default"],
|
||||
shared_libs: [
|
||||
"android.hardware.audio@6.0",
|
||||
"android.hardware.audio@6.0-util",
|
||||
"android.hardware.audio.common@6.0",
|
||||
"android.hardware.audio.common@6.0-util",
|
||||
],
|
||||
@@ -129,6 +132,7 @@ cc_library_shared {
|
||||
defaults: ["android.hardware.audio-impl_default"],
|
||||
shared_libs: [
|
||||
"android.hardware.audio@7.0",
|
||||
"android.hardware.audio@7.0-util",
|
||||
"android.hardware.audio.common@7.0",
|
||||
"android.hardware.audio.common@7.0-enums",
|
||||
"android.hardware.audio.common@7.0-util",
|
||||
|
||||
@@ -1,230 +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.
|
||||
*/
|
||||
|
||||
#include "core/default/Conversions.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#if MAJOR_VERSION >= 7
|
||||
#include <android_audio_policy_configuration_V7_0-enums.h>
|
||||
#endif
|
||||
#include <HidlUtils.h>
|
||||
#include <log/log.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace audio {
|
||||
namespace CPP_VERSION {
|
||||
namespace implementation {
|
||||
|
||||
using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
|
||||
|
||||
#define CONVERT_CHECKED(expr, result) \
|
||||
if (status_t status = (expr); status != NO_ERROR) { \
|
||||
result = status; \
|
||||
}
|
||||
|
||||
status_t deviceAddressToHal(const DeviceAddress& device, audio_devices_t* halDeviceType,
|
||||
char* halDeviceAddress) {
|
||||
#if MAJOR_VERSION >= 5
|
||||
return HidlUtils::deviceAddressToHal(device, halDeviceType, halDeviceAddress);
|
||||
#else
|
||||
return HidlUtils::deviceAddressToHalImpl(device, halDeviceType, halDeviceAddress);
|
||||
#endif
|
||||
}
|
||||
|
||||
status_t deviceAddressFromHal(audio_devices_t halDeviceType, const char* halDeviceAddress,
|
||||
DeviceAddress* device) {
|
||||
#if MAJOR_VERSION >= 5
|
||||
return HidlUtils::deviceAddressFromHal(halDeviceType, halDeviceAddress, device);
|
||||
#else
|
||||
return HidlUtils::deviceAddressFromHalImpl(halDeviceType, halDeviceAddress, device);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if MAJOR_VERSION >= 4
|
||||
bool halToMicrophoneCharacteristics(MicrophoneInfo* pDst,
|
||||
const struct audio_microphone_characteristic_t& src) {
|
||||
bool status = false;
|
||||
if (pDst != NULL) {
|
||||
pDst->deviceId = src.device_id;
|
||||
|
||||
if (deviceAddressFromHal(src.device, src.address, &pDst->deviceAddress) != OK) {
|
||||
return false;
|
||||
}
|
||||
pDst->channelMapping.resize(AUDIO_CHANNEL_COUNT_MAX);
|
||||
for (size_t ch = 0; ch < pDst->channelMapping.size(); ch++) {
|
||||
pDst->channelMapping[ch] = AudioMicrophoneChannelMapping(src.channel_mapping[ch]);
|
||||
}
|
||||
pDst->location = AudioMicrophoneLocation(src.location);
|
||||
pDst->group = (AudioMicrophoneGroup)src.group;
|
||||
pDst->indexInTheGroup = (uint32_t)src.index_in_the_group;
|
||||
pDst->sensitivity = src.sensitivity;
|
||||
pDst->maxSpl = src.max_spl;
|
||||
pDst->minSpl = src.min_spl;
|
||||
pDst->directionality = AudioMicrophoneDirectionality(src.directionality);
|
||||
pDst->frequencyResponse.resize(src.num_frequency_responses);
|
||||
for (size_t k = 0; k < src.num_frequency_responses; k++) {
|
||||
pDst->frequencyResponse[k].frequency = src.frequency_responses[0][k];
|
||||
pDst->frequencyResponse[k].level = src.frequency_responses[1][k];
|
||||
}
|
||||
pDst->position.x = src.geometric_location.x;
|
||||
pDst->position.y = src.geometric_location.y;
|
||||
pDst->position.z = src.geometric_location.z;
|
||||
|
||||
pDst->orientation.x = src.orientation.x;
|
||||
pDst->orientation.y = src.orientation.y;
|
||||
pDst->orientation.z = src.orientation.z;
|
||||
|
||||
status = true;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
status_t sinkMetadataToHal(const SinkMetadata& sinkMetadata,
|
||||
std::vector<record_track_metadata>* halTracks) {
|
||||
status_t result = NO_ERROR;
|
||||
if (halTracks != nullptr) {
|
||||
halTracks->reserve(sinkMetadata.tracks.size());
|
||||
}
|
||||
for (auto& metadata : sinkMetadata.tracks) {
|
||||
record_track_metadata halTrackMetadata{.gain = metadata.gain};
|
||||
CONVERT_CHECKED(HidlUtils::audioSourceToHal(metadata.source, &halTrackMetadata.source),
|
||||
result);
|
||||
#if MAJOR_VERSION >= 5
|
||||
if (metadata.destination.getDiscriminator() ==
|
||||
RecordTrackMetadata::Destination::hidl_discriminator::device) {
|
||||
CONVERT_CHECKED(
|
||||
deviceAddressToHal(metadata.destination.device(), &halTrackMetadata.dest_device,
|
||||
halTrackMetadata.dest_device_address),
|
||||
result);
|
||||
}
|
||||
#endif
|
||||
if (halTracks != nullptr) {
|
||||
halTracks->push_back(std::move(halTrackMetadata));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
status_t sourceMetadataToHal(const SourceMetadata& sourceMetadata,
|
||||
std::vector<playback_track_metadata_t>* halTracks) {
|
||||
status_t result = NO_ERROR;
|
||||
if (halTracks != nullptr) {
|
||||
halTracks->reserve(sourceMetadata.tracks.size());
|
||||
}
|
||||
for (auto& metadata : sourceMetadata.tracks) {
|
||||
playback_track_metadata_t halTrackMetadata{.gain = metadata.gain};
|
||||
CONVERT_CHECKED(HidlUtils::audioUsageToHal(metadata.usage, &halTrackMetadata.usage),
|
||||
result);
|
||||
CONVERT_CHECKED(HidlUtils::audioContentTypeToHal(metadata.contentType,
|
||||
&halTrackMetadata.content_type),
|
||||
result);
|
||||
if (halTracks != nullptr) {
|
||||
halTracks->push_back(std::move(halTrackMetadata));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#endif // MAJOR_VERSION >= 4
|
||||
|
||||
#if MAJOR_VERSION >= 7
|
||||
namespace xsd {
|
||||
using namespace ::android::audio::policy::configuration::V7_0;
|
||||
}
|
||||
|
||||
bool audioInputFlagsToHal(const hidl_vec<AudioInOutFlag>& flags, audio_input_flags_t* halFlags) {
|
||||
bool success = true;
|
||||
*halFlags = {};
|
||||
for (const auto& flag : flags) {
|
||||
audio_input_flags_t halFlag;
|
||||
if (!xsd::isUnknownAudioInOutFlag(flag) &&
|
||||
audio_input_flag_from_string(flag.c_str(), &halFlag)) {
|
||||
*halFlags = static_cast<audio_input_flags_t>(*halFlags | halFlag);
|
||||
} else {
|
||||
ALOGE("Unknown audio input flag \"%s\"", flag.c_str());
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
bool audioOutputFlagsToHal(const hidl_vec<AudioInOutFlag>& flags, audio_output_flags_t* halFlags) {
|
||||
bool success = true;
|
||||
*halFlags = {};
|
||||
for (const auto& flag : flags) {
|
||||
audio_output_flags_t halFlag;
|
||||
if (!xsd::isUnknownAudioInOutFlag(flag) &&
|
||||
audio_output_flag_from_string(flag.c_str(), &halFlag)) {
|
||||
*halFlags = static_cast<audio_output_flags_t>(*halFlags | halFlag);
|
||||
} else {
|
||||
ALOGE("Unknown audio output flag \"%s\"", flag.c_str());
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
status_t sinkMetadataToHalV7(const SinkMetadata& sinkMetadata,
|
||||
std::vector<record_track_metadata_v7_t>* halTracks) {
|
||||
std::vector<record_track_metadata> bases;
|
||||
status_t result = sinkMetadataToHal(sinkMetadata, halTracks != nullptr ? &bases : nullptr);
|
||||
if (halTracks != nullptr) {
|
||||
halTracks->reserve(bases.size());
|
||||
}
|
||||
auto baseIter = std::make_move_iterator(bases.begin());
|
||||
for (auto& metadata : sinkMetadata.tracks) {
|
||||
record_track_metadata_v7_t halTrackMetadata;
|
||||
CONVERT_CHECKED(HidlUtils::audioChannelMaskToHal(metadata.channelMask,
|
||||
&halTrackMetadata.channel_mask),
|
||||
result);
|
||||
CONVERT_CHECKED(HidlUtils::audioTagsToHal(metadata.tags, halTrackMetadata.tags), result);
|
||||
if (halTracks != nullptr) {
|
||||
halTrackMetadata.base = std::move(*baseIter++);
|
||||
halTracks->push_back(std::move(halTrackMetadata));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
status_t sourceMetadataToHalV7(const SourceMetadata& sourceMetadata,
|
||||
std::vector<playback_track_metadata_v7_t>* halTracks) {
|
||||
std::vector<playback_track_metadata_t> bases;
|
||||
status_t result = sourceMetadataToHal(sourceMetadata, halTracks != nullptr ? &bases : nullptr);
|
||||
if (halTracks != nullptr) {
|
||||
halTracks->reserve(bases.size());
|
||||
}
|
||||
auto baseIter = std::make_move_iterator(bases.begin());
|
||||
for (auto& metadata : sourceMetadata.tracks) {
|
||||
playback_track_metadata_v7_t halTrackMetadata;
|
||||
CONVERT_CHECKED(HidlUtils::audioChannelMaskToHal(metadata.channelMask,
|
||||
&halTrackMetadata.channel_mask),
|
||||
result);
|
||||
CONVERT_CHECKED(HidlUtils::audioTagsToHal(metadata.tags, halTrackMetadata.tags), result);
|
||||
if (halTracks != nullptr) {
|
||||
halTrackMetadata.base = std::move(*baseIter++);
|
||||
halTracks->push_back(std::move(halTrackMetadata));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace CPP_VERSION
|
||||
} // namespace audio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
@@ -17,9 +17,7 @@
|
||||
#define LOG_TAG "DeviceHAL"
|
||||
|
||||
#include "core/default/Device.h"
|
||||
#include <HidlUtils.h>
|
||||
#include "common/all-versions/default/EffectMap.h"
|
||||
#include "core/default/Conversions.h"
|
||||
#include "core/default/StreamIn.h"
|
||||
#include "core/default/StreamOut.h"
|
||||
#include "core/default/Util.h"
|
||||
@@ -33,6 +31,8 @@
|
||||
|
||||
#include <android/log.h>
|
||||
|
||||
#include <HidlUtils.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace audio {
|
||||
@@ -160,11 +160,11 @@ std::tuple<Result, sp<IStreamOut>> Device::openOutputStreamImpl(int32_t ioHandle
|
||||
audio_stream_out_t* halStream;
|
||||
audio_devices_t halDevice;
|
||||
char halDeviceAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN];
|
||||
if (deviceAddressToHal(device, &halDevice, halDeviceAddress) != NO_ERROR) {
|
||||
if (CoreUtils::deviceAddressToHal(device, &halDevice, halDeviceAddress) != NO_ERROR) {
|
||||
return {Result::INVALID_ARGUMENTS, nullptr};
|
||||
}
|
||||
audio_output_flags_t halFlags;
|
||||
if (!audioOutputFlagsToHal(flags, &halFlags)) {
|
||||
if (CoreUtils::audioOutputFlagsToHal(flags, &halFlags) != NO_ERROR) {
|
||||
return {Result::INVALID_ARGUMENTS, nullptr};
|
||||
}
|
||||
ALOGV("open_output_stream handle: %d devices: %x flags: %#x "
|
||||
@@ -195,12 +195,12 @@ std::tuple<Result, sp<IStreamIn>> Device::openInputStreamImpl(
|
||||
audio_stream_in_t* halStream;
|
||||
audio_devices_t halDevice;
|
||||
char halDeviceAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN];
|
||||
if (deviceAddressToHal(device, &halDevice, halDeviceAddress) != NO_ERROR) {
|
||||
if (CoreUtils::deviceAddressToHal(device, &halDevice, halDeviceAddress) != NO_ERROR) {
|
||||
return {Result::INVALID_ARGUMENTS, nullptr};
|
||||
}
|
||||
audio_input_flags_t halFlags;
|
||||
audio_source_t halSource;
|
||||
if (!audioInputFlagsToHal(flags, &halFlags) ||
|
||||
if (CoreUtils::audioInputFlagsToHal(flags, &halFlags) != NO_ERROR ||
|
||||
HidlUtils::audioSourceToHal(source, &halSource) != NO_ERROR) {
|
||||
return {Result::INVALID_ARGUMENTS, nullptr};
|
||||
}
|
||||
@@ -254,9 +254,12 @@ Return<void> Device::openOutputStream(int32_t ioHandle, const DeviceAddress& dev
|
||||
const SourceMetadata& sourceMetadata,
|
||||
openOutputStream_cb _hidl_cb) {
|
||||
#if MAJOR_VERSION <= 6
|
||||
if (status_t status = sourceMetadataToHal(sourceMetadata, nullptr); status != NO_ERROR) {
|
||||
if (status_t status = CoreUtils::sourceMetadataToHal(sourceMetadata, nullptr);
|
||||
status != NO_ERROR) {
|
||||
#else
|
||||
if (status_t status = sourceMetadataToHalV7(sourceMetadata, nullptr); status != NO_ERROR) {
|
||||
if (status_t status = CoreUtils::sourceMetadataToHalV7(sourceMetadata,
|
||||
false /*ignoreNonVendorTags*/, nullptr);
|
||||
status != NO_ERROR) {
|
||||
#endif
|
||||
_hidl_cb(analyzeStatus("sourceMetadataToHal", status), nullptr, AudioConfig{});
|
||||
return Void();
|
||||
@@ -288,9 +291,11 @@ Return<void> Device::openInputStream(int32_t ioHandle, const DeviceAddress& devi
|
||||
return Void();
|
||||
}
|
||||
#if MAJOR_VERSION <= 6
|
||||
if (status_t status = sinkMetadataToHal(sinkMetadata, nullptr); status != NO_ERROR) {
|
||||
if (status_t status = CoreUtils::sinkMetadataToHal(sinkMetadata, nullptr); status != NO_ERROR) {
|
||||
#else
|
||||
if (status_t status = sinkMetadataToHalV7(sinkMetadata, nullptr); status != NO_ERROR) {
|
||||
if (status_t status = CoreUtils::sinkMetadataToHalV7(sinkMetadata,
|
||||
false /*ignoreNonVendorTags*/, nullptr);
|
||||
status != NO_ERROR) {
|
||||
#endif
|
||||
_hidl_cb(analyzeStatus("sinkMetadataToHal", status), nullptr, AudioConfig{});
|
||||
return Void();
|
||||
@@ -444,7 +449,7 @@ Return<void> Device::getMicrophones(getMicrophones_cb _hidl_cb) {
|
||||
mDevice->get_microphones(mDevice, &mic_array[0], &actual_mics) == 0) {
|
||||
microphones.resize(actual_mics);
|
||||
for (size_t i = 0; i < actual_mics; ++i) {
|
||||
halToMicrophoneCharacteristics(µphones[i], mic_array[i]);
|
||||
(void)CoreUtils::microphoneInfoFromHal(mic_array[i], µphones[i]);
|
||||
}
|
||||
retval = Result::OK;
|
||||
}
|
||||
|
||||
@@ -15,11 +15,12 @@
|
||||
*/
|
||||
|
||||
#include "core/default/ParametersUtil.h"
|
||||
#include "core/default/Conversions.h"
|
||||
#include "core/default/Util.h"
|
||||
|
||||
#include <system/audio.h>
|
||||
|
||||
#include <util/CoreUtils.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace audio {
|
||||
@@ -153,7 +154,7 @@ Result ParametersUtil::setParametersImpl(const hidl_vec<ParameterValue>& context
|
||||
Result ParametersUtil::setParam(const char* name, const DeviceAddress& address) {
|
||||
audio_devices_t halDeviceType;
|
||||
char halDeviceAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN];
|
||||
if (deviceAddressToHal(address, &halDeviceType, halDeviceAddress) != NO_ERROR) {
|
||||
if (CoreUtils::deviceAddressToHal(address, &halDeviceType, halDeviceAddress) != NO_ERROR) {
|
||||
return Result::INVALID_ARGUMENTS;
|
||||
}
|
||||
AudioParameter params{String8(halDeviceAddress)};
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
#include "core/default/Stream.h"
|
||||
#include "common/all-versions/HidlSupport.h"
|
||||
#include "common/all-versions/default/EffectMap.h"
|
||||
#include "core/default/Conversions.h"
|
||||
#include "core/default/Util.h"
|
||||
|
||||
#include <inttypes.h>
|
||||
@@ -30,6 +29,7 @@
|
||||
#include <hardware/audio_effect.h>
|
||||
#include <media/AudioContainers.h>
|
||||
#include <media/TypeConverter.h>
|
||||
#include <util/CoreUtils.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
@@ -373,9 +373,10 @@ Return<void> Stream::getDevices(getDevices_cb _hidl_cb) {
|
||||
hidl_vec<DeviceAddress> devices;
|
||||
if (retval == Result::OK) {
|
||||
devices.resize(1);
|
||||
retval = Stream::analyzeStatus("get_devices",
|
||||
deviceAddressFromHal(static_cast<audio_devices_t>(halDevice),
|
||||
nullptr, &devices[0]));
|
||||
retval = Stream::analyzeStatus(
|
||||
"get_devices",
|
||||
CoreUtils::deviceAddressFromHal(static_cast<audio_devices_t>(halDevice), nullptr,
|
||||
&devices[0]));
|
||||
}
|
||||
_hidl_cb(retval, devices);
|
||||
return Void();
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#define LOG_TAG "StreamInHAL"
|
||||
|
||||
#include "core/default/StreamIn.h"
|
||||
#include "core/default/Conversions.h"
|
||||
#include "core/default/Util.h"
|
||||
#include "common/all-versions/HidlSupport.h"
|
||||
|
||||
@@ -27,6 +26,7 @@
|
||||
#include <HidlUtils.h>
|
||||
#include <android/log.h>
|
||||
#include <hardware/audio.h>
|
||||
#include <util/CoreUtils.h>
|
||||
#include <utils/Trace.h>
|
||||
#include <cmath>
|
||||
#include <memory>
|
||||
@@ -481,13 +481,15 @@ Return<void> StreamIn::debug(const hidl_handle& fd, const hidl_vec<hidl_string>&
|
||||
Result StreamIn::doUpdateSinkMetadata(const SinkMetadata& sinkMetadata) {
|
||||
std::vector<record_track_metadata> halTracks;
|
||||
#if MAJOR_VERSION <= 6
|
||||
(void)sinkMetadataToHal(sinkMetadata, &halTracks);
|
||||
(void)CoreUtils::sinkMetadataToHal(sinkMetadata, &halTracks);
|
||||
#else
|
||||
// Validate whether a conversion to V7 is possible. This is needed
|
||||
// to have a consistent behavior of the HAL regardless of the API
|
||||
// version of the legacy HAL (and also to be consistent with openInputStream).
|
||||
std::vector<record_track_metadata_v7> halTracksV7;
|
||||
if (status_t status = sinkMetadataToHalV7(sinkMetadata, &halTracksV7); status == NO_ERROR) {
|
||||
if (status_t status = CoreUtils::sinkMetadataToHalV7(
|
||||
sinkMetadata, false /*ignoreNonVendorTags*/, &halTracksV7);
|
||||
status == NO_ERROR) {
|
||||
halTracks.reserve(halTracksV7.size());
|
||||
for (auto metadata_v7 : halTracksV7) {
|
||||
halTracks.push_back(std::move(metadata_v7.base));
|
||||
@@ -507,7 +509,9 @@ Result StreamIn::doUpdateSinkMetadata(const SinkMetadata& sinkMetadata) {
|
||||
#if MAJOR_VERSION >= 7
|
||||
Result StreamIn::doUpdateSinkMetadataV7(const SinkMetadata& sinkMetadata) {
|
||||
std::vector<record_track_metadata_v7> halTracks;
|
||||
if (status_t status = sinkMetadataToHalV7(sinkMetadata, &halTracks); status != NO_ERROR) {
|
||||
if (status_t status = CoreUtils::sinkMetadataToHalV7(sinkMetadata,
|
||||
false /*ignoreNonVendorTags*/, &halTracks);
|
||||
status != NO_ERROR) {
|
||||
return Stream::analyzeStatus("sinkMetadataToHal", status);
|
||||
}
|
||||
const sink_metadata_v7_t halMetadata = {
|
||||
@@ -553,7 +557,7 @@ Return<void> StreamIn::getActiveMicrophones(getActiveMicrophones_cb _hidl_cb) {
|
||||
mStream->get_active_microphones(mStream, &mic_array[0], &actual_mics) == 0) {
|
||||
microphones.resize(actual_mics);
|
||||
for (size_t i = 0; i < actual_mics; ++i) {
|
||||
halToMicrophoneCharacteristics(µphones[i], mic_array[i]);
|
||||
(void)CoreUtils::microphoneInfoFromHal(mic_array[i], µphones[i]);
|
||||
}
|
||||
retval = Result::OK;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#define LOG_TAG "StreamOutHAL"
|
||||
|
||||
#include "core/default/StreamOut.h"
|
||||
#include "core/default/Conversions.h"
|
||||
#include "core/default/Util.h"
|
||||
|
||||
//#define LOG_NDEBUG 0
|
||||
@@ -30,6 +29,7 @@
|
||||
#include <HidlUtils.h>
|
||||
#include <android/log.h>
|
||||
#include <hardware/audio.h>
|
||||
#include <util/CoreUtils.h>
|
||||
#include <utils/Trace.h>
|
||||
|
||||
namespace android {
|
||||
@@ -589,13 +589,15 @@ Return<void> StreamOut::debug(const hidl_handle& fd, const hidl_vec<hidl_string>
|
||||
Result StreamOut::doUpdateSourceMetadata(const SourceMetadata& sourceMetadata) {
|
||||
std::vector<playback_track_metadata_t> halTracks;
|
||||
#if MAJOR_VERSION <= 6
|
||||
(void)sourceMetadataToHal(sourceMetadata, &halTracks);
|
||||
(void)CoreUtils::sourceMetadataToHal(sourceMetadata, &halTracks);
|
||||
#else
|
||||
// Validate whether a conversion to V7 is possible. This is needed
|
||||
// to have a consistent behavior of the HAL regardless of the API
|
||||
// version of the legacy HAL (and also to be consistent with openOutputStream).
|
||||
std::vector<playback_track_metadata_v7> halTracksV7;
|
||||
if (status_t status = sourceMetadataToHalV7(sourceMetadata, &halTracksV7); status == NO_ERROR) {
|
||||
if (status_t status = CoreUtils::sourceMetadataToHalV7(
|
||||
sourceMetadata, false /*ignoreNonVendorTags*/, &halTracksV7);
|
||||
status == NO_ERROR) {
|
||||
halTracks.reserve(halTracksV7.size());
|
||||
for (auto metadata_v7 : halTracksV7) {
|
||||
halTracks.push_back(std::move(metadata_v7.base));
|
||||
@@ -615,7 +617,9 @@ Result StreamOut::doUpdateSourceMetadata(const SourceMetadata& sourceMetadata) {
|
||||
#if MAJOR_VERSION >= 7
|
||||
Result StreamOut::doUpdateSourceMetadataV7(const SourceMetadata& sourceMetadata) {
|
||||
std::vector<playback_track_metadata_v7> halTracks;
|
||||
if (status_t status = sourceMetadataToHalV7(sourceMetadata, &halTracks); status != NO_ERROR) {
|
||||
if (status_t status = CoreUtils::sourceMetadataToHalV7(
|
||||
sourceMetadata, false /*ignoreNonVendorTags*/, &halTracks);
|
||||
status != NO_ERROR) {
|
||||
return Stream::analyzeStatus("sourceMetadataToHal", status);
|
||||
}
|
||||
const source_metadata_v7_t halMetadata = {
|
||||
|
||||
7
audio/core/all-versions/default/TEST_MAPPING
Normal file
7
audio/core/all-versions/default/TEST_MAPPING
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"presubmit": [
|
||||
{
|
||||
"name": "android.hardware.audio@7.0-util_tests"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_HARDWARE_AUDIO_CONVERSIONS_H_
|
||||
#define ANDROID_HARDWARE_AUDIO_CONVERSIONS_H_
|
||||
|
||||
#include PATH(android/hardware/audio/FILE_VERSION/types.h)
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <system/audio.h>
|
||||
|
||||
#include <VersionUtils.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace audio {
|
||||
namespace CPP_VERSION {
|
||||
namespace implementation {
|
||||
|
||||
using ::android::hardware::hidl_vec;
|
||||
using namespace ::android::hardware::audio::common::CPP_VERSION;
|
||||
using namespace ::android::hardware::audio::CPP_VERSION;
|
||||
|
||||
status_t deviceAddressToHal(const DeviceAddress& device, audio_devices_t* halDeviceType,
|
||||
char* halDeviceAddress);
|
||||
status_t deviceAddressFromHal(audio_devices_t halDeviceType, const char* halDeviceAddress,
|
||||
DeviceAddress* device);
|
||||
|
||||
#if MAJOR_VERSION >= 4
|
||||
bool halToMicrophoneCharacteristics(MicrophoneInfo* pDst,
|
||||
const struct audio_microphone_characteristic_t& src);
|
||||
status_t sinkMetadataToHal(const SinkMetadata& sinkMetadata,
|
||||
std::vector<record_track_metadata>* halTracks);
|
||||
status_t sourceMetadataToHal(const SourceMetadata& sourceMetadata,
|
||||
std::vector<playback_track_metadata_t>* halTracks);
|
||||
#endif
|
||||
|
||||
#if MAJOR_VERSION <= 6
|
||||
using AudioInputFlags =
|
||||
::android::hardware::audio::common::CPP_VERSION::implementation::AudioInputFlagBitfield;
|
||||
using AudioOutputFlags =
|
||||
::android::hardware::audio::common::CPP_VERSION::implementation::AudioOutputFlagBitfield;
|
||||
|
||||
inline bool audioInputFlagsToHal(AudioInputFlags flags, audio_input_flags_t* halFlags) {
|
||||
*halFlags = static_cast<audio_input_flags_t>(flags);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool audioOutputFlagsToHal(AudioOutputFlags flags, audio_output_flags_t* halFlags) {
|
||||
*halFlags = static_cast<audio_output_flags_t>(flags);
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
bool audioInputFlagsToHal(const hidl_vec<AudioInOutFlag>& flags, audio_input_flags_t* halFlags);
|
||||
bool audioOutputFlagsToHal(const hidl_vec<AudioInOutFlag>& flags, audio_output_flags_t* halFlags);
|
||||
// Overloading isn't convenient when passing a nullptr.
|
||||
status_t sinkMetadataToHalV7(const SinkMetadata& sinkMetadata,
|
||||
std::vector<record_track_metadata_v7_t>* halTracks);
|
||||
status_t sourceMetadataToHalV7(const SourceMetadata& sourceMetadata,
|
||||
std::vector<playback_track_metadata_v7_t>* halTracks);
|
||||
#endif
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace CPP_VERSION
|
||||
} // namespace audio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
||||
#endif // ANDROID_HARDWARE_AUDIO_CONVERSIONS_H_
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <hidl/MQDescriptor.h>
|
||||
|
||||
#include <VersionUtils.h>
|
||||
#include <util/CoreUtils.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
@@ -43,17 +44,10 @@ using ::android::hardware::hidl_string;
|
||||
using ::android::hardware::hidl_vec;
|
||||
using ::android::hardware::Return;
|
||||
using ::android::hardware::Void;
|
||||
#if MAJOR_VERSION <= 6
|
||||
using AudioInputFlags =
|
||||
::android::hardware::audio::common::CPP_VERSION::implementation::AudioInputFlagBitfield;
|
||||
using AudioOutputFlags =
|
||||
::android::hardware::audio::common::CPP_VERSION::implementation::AudioOutputFlagBitfield;
|
||||
#else
|
||||
using AudioInputFlags = hidl_vec<::android::hardware::audio::CPP_VERSION::AudioInOutFlag>;
|
||||
using AudioOutputFlags = hidl_vec<::android::hardware::audio::CPP_VERSION::AudioInOutFlag>;
|
||||
#endif
|
||||
using namespace ::android::hardware::audio::common::CPP_VERSION;
|
||||
using namespace ::android::hardware::audio::CPP_VERSION;
|
||||
using AudioInputFlags = CoreUtils::AudioInputFlags;
|
||||
using AudioOutputFlags = CoreUtils::AudioOutputFlags;
|
||||
|
||||
struct Device : public IDevice, public ParametersUtil {
|
||||
explicit Device(audio_hw_device_t* device);
|
||||
|
||||
139
audio/core/all-versions/default/util/Android.bp
Normal file
139
audio/core/all-versions/default/util/Android.bp
Normal file
@@ -0,0 +1,139 @@
|
||||
cc_defaults {
|
||||
name: "android.hardware.audio-util_default",
|
||||
defaults: ["hidl_defaults"],
|
||||
|
||||
vendor_available: true,
|
||||
|
||||
export_include_dirs: ["include"],
|
||||
|
||||
srcs: [
|
||||
"CoreUtils.cpp",
|
||||
],
|
||||
|
||||
shared_libs: [
|
||||
"liblog",
|
||||
"libutils",
|
||||
"libhidlbase",
|
||||
"android.hardware.audio.common-util",
|
||||
],
|
||||
export_shared_lib_headers: [
|
||||
"android.hardware.audio.common-util",
|
||||
],
|
||||
|
||||
header_libs: [
|
||||
"libaudio_system_headers",
|
||||
"libhardware_headers",
|
||||
],
|
||||
}
|
||||
|
||||
cc_library_shared {
|
||||
name: "android.hardware.audio@2.0-util",
|
||||
defaults: ["android.hardware.audio-util_default"],
|
||||
shared_libs: [
|
||||
"android.hardware.audio.common@2.0",
|
||||
"android.hardware.audio.common@2.0-util",
|
||||
"android.hardware.audio@2.0",
|
||||
],
|
||||
cflags: [
|
||||
"-DMAJOR_VERSION=2",
|
||||
"-DMINOR_VERSION=0",
|
||||
"-include common/all-versions/VersionMacro.h",
|
||||
],
|
||||
}
|
||||
|
||||
cc_library_shared {
|
||||
name: "android.hardware.audio@4.0-util",
|
||||
defaults: ["android.hardware.audio-util_default"],
|
||||
shared_libs: [
|
||||
"android.hardware.audio.common@4.0",
|
||||
"android.hardware.audio.common@4.0-util",
|
||||
"android.hardware.audio@4.0",
|
||||
],
|
||||
cflags: [
|
||||
"-DMAJOR_VERSION=4",
|
||||
"-DMINOR_VERSION=0",
|
||||
"-include common/all-versions/VersionMacro.h",
|
||||
],
|
||||
}
|
||||
|
||||
cc_library_shared {
|
||||
name: "android.hardware.audio@5.0-util",
|
||||
defaults: ["android.hardware.audio-util_default"],
|
||||
shared_libs: [
|
||||
"android.hardware.audio.common@5.0",
|
||||
"android.hardware.audio.common@5.0-util",
|
||||
"android.hardware.audio@5.0",
|
||||
],
|
||||
cflags: [
|
||||
"-DMAJOR_VERSION=5",
|
||||
"-DMINOR_VERSION=0",
|
||||
"-include common/all-versions/VersionMacro.h",
|
||||
],
|
||||
}
|
||||
|
||||
cc_library_shared {
|
||||
name: "android.hardware.audio@6.0-util",
|
||||
defaults: ["android.hardware.audio-util_default"],
|
||||
shared_libs: [
|
||||
"android.hardware.audio.common@6.0",
|
||||
"android.hardware.audio.common@6.0-util",
|
||||
"android.hardware.audio@6.0",
|
||||
],
|
||||
cflags: [
|
||||
"-DMAJOR_VERSION=6",
|
||||
"-DMINOR_VERSION=0",
|
||||
"-include common/all-versions/VersionMacro.h",
|
||||
],
|
||||
}
|
||||
|
||||
cc_library {
|
||||
name: "android.hardware.audio@7.0-util",
|
||||
defaults: ["android.hardware.audio-util_default"],
|
||||
shared_libs: [
|
||||
"android.hardware.audio.common@7.0",
|
||||
"android.hardware.audio.common@7.0-enums",
|
||||
"android.hardware.audio.common@7.0-util",
|
||||
"android.hardware.audio@7.0",
|
||||
"libbase",
|
||||
"libxml2",
|
||||
],
|
||||
cflags: [
|
||||
"-DMAJOR_VERSION=7",
|
||||
"-DMINOR_VERSION=0",
|
||||
"-include common/all-versions/VersionMacro.h",
|
||||
],
|
||||
}
|
||||
|
||||
// Note: this isn't a VTS test, but rather a unit test
|
||||
// to verify correctness of conversion utilities.
|
||||
cc_test {
|
||||
name: "android.hardware.audio@7.0-util_tests",
|
||||
defaults: ["android.hardware.audio-util_default"],
|
||||
|
||||
srcs: ["tests/coreutils_tests.cpp"],
|
||||
|
||||
// Use static linking to allow running in presubmit on
|
||||
// targets that don't have HAL V7.
|
||||
static_libs: [
|
||||
"android.hardware.audio.common@7.0",
|
||||
"android.hardware.audio.common@7.0-enums",
|
||||
"android.hardware.audio.common@7.0-util",
|
||||
"android.hardware.audio@7.0",
|
||||
"android.hardware.audio@7.0-util",
|
||||
],
|
||||
|
||||
shared_libs: [
|
||||
"libbase",
|
||||
"libxml2",
|
||||
],
|
||||
|
||||
cflags: [
|
||||
"-Werror",
|
||||
"-Wall",
|
||||
"-DMAJOR_VERSION=7",
|
||||
"-DMINOR_VERSION=0",
|
||||
"-include common/all-versions/VersionMacro.h",
|
||||
],
|
||||
|
||||
test_suites: ["device-tests"],
|
||||
}
|
||||
476
audio/core/all-versions/default/util/CoreUtils.cpp
Normal file
476
audio/core/all-versions/default/util/CoreUtils.cpp
Normal file
@@ -0,0 +1,476 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.
|
||||
*/
|
||||
|
||||
#if MAJOR_VERSION >= 7
|
||||
#include <android_audio_policy_configuration_V7_0-enums.h>
|
||||
#endif
|
||||
#include <HidlUtils.h>
|
||||
#include <log/log.h>
|
||||
|
||||
#include "util/CoreUtils.h"
|
||||
|
||||
using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
|
||||
#if MAJOR_VERSION >= 7
|
||||
namespace xsd {
|
||||
using namespace ::android::audio::policy::configuration::V7_0;
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace audio {
|
||||
namespace CPP_VERSION {
|
||||
namespace implementation {
|
||||
|
||||
#define CONVERT_CHECKED(expr, result) \
|
||||
if (status_t status = (expr); status != NO_ERROR) { \
|
||||
result = status; \
|
||||
}
|
||||
|
||||
status_t CoreUtils::deviceAddressToHal(const DeviceAddress& device, audio_devices_t* halDeviceType,
|
||||
char* halDeviceAddress) {
|
||||
#if MAJOR_VERSION >= 5
|
||||
return HidlUtils::deviceAddressToHal(device, halDeviceType, halDeviceAddress);
|
||||
#else
|
||||
return HidlUtils::deviceAddressToHalImpl(device, halDeviceType, halDeviceAddress);
|
||||
#endif
|
||||
}
|
||||
|
||||
status_t CoreUtils::deviceAddressFromHal(audio_devices_t halDeviceType,
|
||||
const char* halDeviceAddress, DeviceAddress* device) {
|
||||
#if MAJOR_VERSION >= 5
|
||||
return HidlUtils::deviceAddressFromHal(halDeviceType, halDeviceAddress, device);
|
||||
#else
|
||||
return HidlUtils::deviceAddressFromHalImpl(halDeviceType, halDeviceAddress, device);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if MAJOR_VERSION >= 4
|
||||
status_t CoreUtils::microphoneInfoFromHal(
|
||||
const struct audio_microphone_characteristic_t& halMicInfo, MicrophoneInfo* micInfo) {
|
||||
status_t result = NO_ERROR;
|
||||
micInfo->deviceId = halMicInfo.device_id;
|
||||
CONVERT_CHECKED(
|
||||
deviceAddressFromHal(halMicInfo.device, halMicInfo.address, &micInfo->deviceAddress),
|
||||
result);
|
||||
size_t chCount;
|
||||
for (chCount = 0; chCount < AUDIO_CHANNEL_COUNT_MAX; ++chCount) {
|
||||
if (halMicInfo.channel_mapping[chCount] == AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
micInfo->channelMapping.resize(chCount);
|
||||
for (size_t ch = 0; ch < micInfo->channelMapping.size(); ch++) {
|
||||
micInfo->channelMapping[ch] = AudioMicrophoneChannelMapping(halMicInfo.channel_mapping[ch]);
|
||||
}
|
||||
micInfo->location = AudioMicrophoneLocation(halMicInfo.location);
|
||||
micInfo->group = AudioMicrophoneGroup(halMicInfo.group);
|
||||
micInfo->indexInTheGroup = static_cast<uint32_t>(halMicInfo.index_in_the_group);
|
||||
micInfo->sensitivity = halMicInfo.sensitivity;
|
||||
micInfo->maxSpl = halMicInfo.max_spl;
|
||||
micInfo->minSpl = halMicInfo.min_spl;
|
||||
micInfo->directionality = AudioMicrophoneDirectionality(halMicInfo.directionality);
|
||||
micInfo->frequencyResponse.resize(halMicInfo.num_frequency_responses);
|
||||
for (size_t k = 0; k < halMicInfo.num_frequency_responses; k++) {
|
||||
micInfo->frequencyResponse[k].frequency = halMicInfo.frequency_responses[0][k];
|
||||
micInfo->frequencyResponse[k].level = halMicInfo.frequency_responses[1][k];
|
||||
}
|
||||
micInfo->position.x = halMicInfo.geometric_location.x;
|
||||
micInfo->position.y = halMicInfo.geometric_location.y;
|
||||
micInfo->position.z = halMicInfo.geometric_location.z;
|
||||
micInfo->orientation.x = halMicInfo.orientation.x;
|
||||
micInfo->orientation.y = halMicInfo.orientation.y;
|
||||
micInfo->orientation.z = halMicInfo.orientation.z;
|
||||
return result;
|
||||
}
|
||||
|
||||
status_t CoreUtils::microphoneInfoToHal(const MicrophoneInfo& micInfo,
|
||||
audio_microphone_characteristic_t* halMicInfo) {
|
||||
status_t result = NO_ERROR;
|
||||
strncpy(halMicInfo->device_id, micInfo.deviceId.c_str(), AUDIO_MICROPHONE_ID_MAX_LEN);
|
||||
halMicInfo->device_id[AUDIO_MICROPHONE_ID_MAX_LEN - 1] = '\0';
|
||||
if (micInfo.deviceId.size() >= AUDIO_MICROPHONE_ID_MAX_LEN) {
|
||||
ALOGE("HIDL MicrophoneInfo device ID is too long: %zu", micInfo.deviceId.size());
|
||||
result = BAD_VALUE;
|
||||
}
|
||||
CONVERT_CHECKED(
|
||||
deviceAddressToHal(micInfo.deviceAddress, &halMicInfo->device, halMicInfo->address),
|
||||
result);
|
||||
if (micInfo.channelMapping.size() > AUDIO_CHANNEL_COUNT_MAX) {
|
||||
ALOGE("HIDL MicrophoneInfo has too many channelMapping elements: %zu",
|
||||
micInfo.channelMapping.size());
|
||||
result = BAD_VALUE;
|
||||
}
|
||||
size_t ch;
|
||||
for (ch = 0; ch < micInfo.channelMapping.size() && ch < AUDIO_CHANNEL_COUNT_MAX; ch++) {
|
||||
halMicInfo->channel_mapping[ch] =
|
||||
static_cast<audio_microphone_channel_mapping_t>(micInfo.channelMapping[ch]);
|
||||
}
|
||||
for (; ch < AUDIO_CHANNEL_COUNT_MAX; ch++) {
|
||||
halMicInfo->channel_mapping[ch] = AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED;
|
||||
}
|
||||
halMicInfo->location = static_cast<audio_microphone_location_t>(micInfo.location);
|
||||
halMicInfo->group = static_cast<audio_microphone_group_t>(micInfo.group);
|
||||
halMicInfo->index_in_the_group = static_cast<unsigned int>(micInfo.indexInTheGroup);
|
||||
halMicInfo->sensitivity = micInfo.sensitivity;
|
||||
halMicInfo->max_spl = micInfo.maxSpl;
|
||||
halMicInfo->min_spl = micInfo.minSpl;
|
||||
halMicInfo->directionality =
|
||||
static_cast<audio_microphone_directionality_t>(micInfo.directionality);
|
||||
halMicInfo->num_frequency_responses =
|
||||
static_cast<unsigned int>(micInfo.frequencyResponse.size());
|
||||
if (halMicInfo->num_frequency_responses > AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES) {
|
||||
ALOGE("HIDL MicrophoneInfo has too many frequency responses: %u",
|
||||
halMicInfo->num_frequency_responses);
|
||||
halMicInfo->num_frequency_responses = AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES;
|
||||
result = BAD_VALUE;
|
||||
}
|
||||
for (size_t k = 0; k < halMicInfo->num_frequency_responses; k++) {
|
||||
halMicInfo->frequency_responses[0][k] = micInfo.frequencyResponse[k].frequency;
|
||||
halMicInfo->frequency_responses[1][k] = micInfo.frequencyResponse[k].level;
|
||||
}
|
||||
halMicInfo->geometric_location.x = micInfo.position.x;
|
||||
halMicInfo->geometric_location.y = micInfo.position.y;
|
||||
halMicInfo->geometric_location.z = micInfo.position.z;
|
||||
halMicInfo->orientation.x = micInfo.orientation.x;
|
||||
halMicInfo->orientation.y = micInfo.orientation.y;
|
||||
halMicInfo->orientation.z = micInfo.orientation.z;
|
||||
return result;
|
||||
}
|
||||
|
||||
status_t CoreUtils::sinkMetadataFromHal(const std::vector<record_track_metadata_t>& halTracks,
|
||||
SinkMetadata* sinkMetadata) {
|
||||
status_t result = NO_ERROR;
|
||||
sinkMetadata->tracks.resize(halTracks.size());
|
||||
for (size_t i = 0; i < sinkMetadata->tracks.size(); ++i) {
|
||||
const auto& halTrackMetadata = halTracks[i];
|
||||
RecordTrackMetadata trackMetadata{};
|
||||
CONVERT_CHECKED(
|
||||
HidlUtils::audioSourceFromHal(halTrackMetadata.source, &trackMetadata.source),
|
||||
result);
|
||||
trackMetadata.gain = halTrackMetadata.gain;
|
||||
#if MAJOR_VERSION >= 5
|
||||
if (halTrackMetadata.dest_device != AUDIO_DEVICE_NONE) {
|
||||
DeviceAddress address;
|
||||
if (status_t status =
|
||||
deviceAddressFromHal(halTrackMetadata.dest_device,
|
||||
halTrackMetadata.dest_device_address, &address);
|
||||
status == NO_ERROR) {
|
||||
trackMetadata.destination.device(std::move(address));
|
||||
} else {
|
||||
result = status;
|
||||
}
|
||||
}
|
||||
#if MAJOR_VERSION >= 7
|
||||
trackMetadata.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_NONE);
|
||||
#endif
|
||||
#endif // MAJOR_VERSION >= 5
|
||||
sinkMetadata->tracks[i] = std::move(trackMetadata);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
status_t CoreUtils::sinkMetadataFromHalV7(const std::vector<record_track_metadata_v7_t>& halTracks,
|
||||
bool ignoreNonVendorTags, SinkMetadata* sinkMetadata) {
|
||||
std::vector<record_track_metadata_t> bases;
|
||||
bases.reserve(halTracks.size());
|
||||
std::transform(halTracks.begin(), halTracks.end(), std::back_inserter(bases),
|
||||
[](const record_track_metadata_v7_t& src) -> record_track_metadata_t {
|
||||
record_track_metadata_t result;
|
||||
record_track_metadata_from_v7(&result, &src);
|
||||
return result;
|
||||
});
|
||||
status_t result = sinkMetadataFromHal(bases, sinkMetadata);
|
||||
#if MAJOR_VERSION >= 7
|
||||
for (size_t i = 0; i < halTracks.size(); ++i) {
|
||||
auto& trackMetadata = sinkMetadata->tracks[i];
|
||||
const auto& halTrackMetadata = halTracks[i];
|
||||
CONVERT_CHECKED(
|
||||
HidlUtils::audioChannelMaskFromHal(halTrackMetadata.channel_mask, true /*isInput*/,
|
||||
&trackMetadata.channelMask),
|
||||
result);
|
||||
std::vector<std::string> strTags = HidlUtils::splitAudioTags(halTrackMetadata.tags);
|
||||
if (ignoreNonVendorTags) {
|
||||
strTags = HidlUtils::filterOutNonVendorTags(strTags);
|
||||
}
|
||||
CONVERT_CHECKED(HidlUtils::audioTagsFromHal(strTags, &trackMetadata.tags), result);
|
||||
}
|
||||
#else
|
||||
(void)ignoreNonVendorTags;
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
status_t CoreUtils::sinkMetadataToHal(const SinkMetadata& sinkMetadata,
|
||||
std::vector<record_track_metadata_t>* halTracks) {
|
||||
status_t result = NO_ERROR;
|
||||
if (halTracks != nullptr) {
|
||||
halTracks->reserve(sinkMetadata.tracks.size());
|
||||
}
|
||||
for (auto& trackMetadata : sinkMetadata.tracks) {
|
||||
record_track_metadata halTrackMetadata{.gain = trackMetadata.gain};
|
||||
CONVERT_CHECKED(HidlUtils::audioSourceToHal(trackMetadata.source, &halTrackMetadata.source),
|
||||
result);
|
||||
#if MAJOR_VERSION >= 5
|
||||
if (trackMetadata.destination.getDiscriminator() ==
|
||||
RecordTrackMetadata::Destination::hidl_discriminator::device) {
|
||||
CONVERT_CHECKED(deviceAddressToHal(trackMetadata.destination.device(),
|
||||
&halTrackMetadata.dest_device,
|
||||
halTrackMetadata.dest_device_address),
|
||||
result);
|
||||
}
|
||||
#endif
|
||||
if (halTracks != nullptr) {
|
||||
halTracks->push_back(std::move(halTrackMetadata));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
status_t CoreUtils::sinkMetadataToHalV7(const SinkMetadata& sinkMetadata, bool ignoreNonVendorTags,
|
||||
std::vector<record_track_metadata_v7_t>* halTracks) {
|
||||
std::vector<record_track_metadata> bases;
|
||||
status_t result = sinkMetadataToHal(sinkMetadata, halTracks != nullptr ? &bases : nullptr);
|
||||
if (halTracks != nullptr) {
|
||||
halTracks->reserve(sinkMetadata.tracks.size());
|
||||
}
|
||||
for (size_t i = 0; i < sinkMetadata.tracks.size(); ++i) {
|
||||
record_track_metadata_v7_t halTrackMetadata;
|
||||
if (halTracks != nullptr) {
|
||||
record_track_metadata_to_v7(&halTrackMetadata, &bases[i]);
|
||||
}
|
||||
#if MAJOR_VERSION >= 7
|
||||
const auto& trackMetadata = sinkMetadata.tracks[i];
|
||||
CONVERT_CHECKED(HidlUtils::audioChannelMaskToHal(trackMetadata.channelMask,
|
||||
&halTrackMetadata.channel_mask),
|
||||
result);
|
||||
if (ignoreNonVendorTags) {
|
||||
CONVERT_CHECKED(
|
||||
HidlUtils::audioTagsToHal(HidlUtils::filterOutNonVendorTags(trackMetadata.tags),
|
||||
halTrackMetadata.tags),
|
||||
result);
|
||||
} else {
|
||||
CONVERT_CHECKED(HidlUtils::audioTagsToHal(trackMetadata.tags, halTrackMetadata.tags),
|
||||
result);
|
||||
}
|
||||
#else
|
||||
(void)ignoreNonVendorTags;
|
||||
#endif
|
||||
if (halTracks != nullptr) {
|
||||
halTracks->push_back(std::move(halTrackMetadata));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
status_t CoreUtils::sourceMetadataFromHal(const std::vector<playback_track_metadata_t>& halTracks,
|
||||
SourceMetadata* sourceMetadata) {
|
||||
status_t result = NO_ERROR;
|
||||
sourceMetadata->tracks.resize(halTracks.size());
|
||||
for (size_t i = 0; i < sourceMetadata->tracks.size(); ++i) {
|
||||
const auto& halTrackMetadata = halTracks[i];
|
||||
PlaybackTrackMetadata trackMetadata{};
|
||||
CONVERT_CHECKED(HidlUtils::audioUsageFromHal(halTrackMetadata.usage, &trackMetadata.usage),
|
||||
result);
|
||||
CONVERT_CHECKED(HidlUtils::audioContentTypeFromHal(halTrackMetadata.content_type,
|
||||
&trackMetadata.contentType),
|
||||
result);
|
||||
trackMetadata.gain = halTrackMetadata.gain;
|
||||
#if MAJOR_VERSION >= 7
|
||||
trackMetadata.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_NONE);
|
||||
#endif
|
||||
sourceMetadata->tracks[i] = std::move(trackMetadata);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
status_t CoreUtils::sourceMetadataFromHalV7(
|
||||
const std::vector<playback_track_metadata_v7_t>& halTracks, bool ignoreNonVendorTags,
|
||||
SourceMetadata* sourceMetadata) {
|
||||
std::vector<playback_track_metadata_t> bases;
|
||||
bases.reserve(halTracks.size());
|
||||
std::transform(halTracks.begin(), halTracks.end(), std::back_inserter(bases),
|
||||
[](const playback_track_metadata_v7_t& src) -> playback_track_metadata_t {
|
||||
playback_track_metadata_t result;
|
||||
playback_track_metadata_from_v7(&result, &src);
|
||||
return result;
|
||||
});
|
||||
status_t result = sourceMetadataFromHal(bases, sourceMetadata);
|
||||
#if MAJOR_VERSION >= 7
|
||||
for (size_t i = 0; i < halTracks.size(); ++i) {
|
||||
auto& trackMetadata = sourceMetadata->tracks[i];
|
||||
const auto& halTrackMetadata = halTracks[i];
|
||||
CONVERT_CHECKED(
|
||||
HidlUtils::audioChannelMaskFromHal(halTrackMetadata.channel_mask, false /*isInput*/,
|
||||
&trackMetadata.channelMask),
|
||||
result);
|
||||
std::vector<std::string> strTags = HidlUtils::splitAudioTags(halTrackMetadata.tags);
|
||||
if (ignoreNonVendorTags) {
|
||||
strTags = HidlUtils::filterOutNonVendorTags(strTags);
|
||||
}
|
||||
CONVERT_CHECKED(HidlUtils::audioTagsFromHal(strTags, &trackMetadata.tags), result);
|
||||
}
|
||||
#else
|
||||
(void)ignoreNonVendorTags;
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
status_t CoreUtils::sourceMetadataToHal(const SourceMetadata& sourceMetadata,
|
||||
std::vector<playback_track_metadata_t>* halTracks) {
|
||||
status_t result = NO_ERROR;
|
||||
if (halTracks != nullptr) {
|
||||
halTracks->reserve(sourceMetadata.tracks.size());
|
||||
}
|
||||
for (auto& trackMetadata : sourceMetadata.tracks) {
|
||||
playback_track_metadata_t halTrackMetadata{.gain = trackMetadata.gain};
|
||||
CONVERT_CHECKED(HidlUtils::audioUsageToHal(trackMetadata.usage, &halTrackMetadata.usage),
|
||||
result);
|
||||
CONVERT_CHECKED(HidlUtils::audioContentTypeToHal(trackMetadata.contentType,
|
||||
&halTrackMetadata.content_type),
|
||||
result);
|
||||
if (halTracks != nullptr) {
|
||||
halTracks->push_back(std::move(halTrackMetadata));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
status_t CoreUtils::sourceMetadataToHalV7(const SourceMetadata& sourceMetadata,
|
||||
bool ignoreNonVendorTags,
|
||||
std::vector<playback_track_metadata_v7_t>* halTracks) {
|
||||
std::vector<playback_track_metadata_t> bases;
|
||||
status_t result = sourceMetadataToHal(sourceMetadata, halTracks != nullptr ? &bases : nullptr);
|
||||
if (halTracks != nullptr) {
|
||||
halTracks->reserve(sourceMetadata.tracks.size());
|
||||
}
|
||||
for (size_t i = 0; i < sourceMetadata.tracks.size(); ++i) {
|
||||
playback_track_metadata_v7_t halTrackMetadata;
|
||||
if (halTracks != nullptr) {
|
||||
playback_track_metadata_to_v7(&halTrackMetadata, &bases[i]);
|
||||
}
|
||||
#if MAJOR_VERSION >= 7
|
||||
const auto& trackMetadata = sourceMetadata.tracks[i];
|
||||
CONVERT_CHECKED(HidlUtils::audioChannelMaskToHal(trackMetadata.channelMask,
|
||||
&halTrackMetadata.channel_mask),
|
||||
result);
|
||||
if (ignoreNonVendorTags) {
|
||||
CONVERT_CHECKED(
|
||||
HidlUtils::audioTagsToHal(HidlUtils::filterOutNonVendorTags(trackMetadata.tags),
|
||||
halTrackMetadata.tags),
|
||||
result);
|
||||
} else {
|
||||
CONVERT_CHECKED(HidlUtils::audioTagsToHal(trackMetadata.tags, halTrackMetadata.tags),
|
||||
result);
|
||||
}
|
||||
#else
|
||||
(void)ignoreNonVendorTags;
|
||||
#endif
|
||||
if (halTracks != nullptr) {
|
||||
halTracks->push_back(std::move(halTrackMetadata));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#endif // MAJOR_VERSION >= 4
|
||||
|
||||
#if MAJOR_VERSION >= 7
|
||||
namespace xsd {
|
||||
using namespace ::android::audio::policy::configuration::V7_0;
|
||||
}
|
||||
|
||||
status_t CoreUtils::audioInputFlagsFromHal(audio_input_flags_t halFlagMask,
|
||||
AudioInputFlags* flags) {
|
||||
status_t status = NO_ERROR;
|
||||
std::vector<AudioInOutFlag> result;
|
||||
for (uint32_t bit = 0; halFlagMask != 0 && bit < sizeof(audio_input_flags_t) * 8; ++bit) {
|
||||
audio_input_flags_t flag = static_cast<audio_input_flags_t>(1u << bit);
|
||||
if ((flag & halFlagMask) == flag) {
|
||||
AudioInOutFlag flagStr = audio_input_flag_to_string(flag);
|
||||
if (!flagStr.empty() && !xsd::isUnknownAudioInOutFlag(flagStr)) {
|
||||
result.push_back(flagStr);
|
||||
} else {
|
||||
ALOGE("Unknown audio input flag value 0x%X", flag);
|
||||
status = BAD_VALUE;
|
||||
}
|
||||
halFlagMask = static_cast<audio_input_flags_t>(halFlagMask & ~flag);
|
||||
}
|
||||
}
|
||||
*flags = result;
|
||||
return status;
|
||||
}
|
||||
|
||||
status_t CoreUtils::audioInputFlagsToHal(const AudioInputFlags& flags,
|
||||
audio_input_flags_t* halFlagMask) {
|
||||
status_t status = NO_ERROR;
|
||||
*halFlagMask = {};
|
||||
for (const auto& flag : flags) {
|
||||
audio_input_flags_t halFlag;
|
||||
if (!xsd::isUnknownAudioInOutFlag(flag) &&
|
||||
audio_input_flag_from_string(flag.c_str(), &halFlag)) {
|
||||
*halFlagMask = static_cast<audio_input_flags_t>(*halFlagMask | halFlag);
|
||||
} else {
|
||||
ALOGE("Unknown audio input flag \"%s\"", flag.c_str());
|
||||
status = BAD_VALUE;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
status_t CoreUtils::audioOutputFlagsFromHal(audio_output_flags_t halFlagMask,
|
||||
AudioOutputFlags* flags) {
|
||||
status_t status = NO_ERROR;
|
||||
std::vector<AudioInOutFlag> result;
|
||||
for (uint32_t bit = 0; halFlagMask != 0 && bit < sizeof(audio_output_flags_t) * 8; ++bit) {
|
||||
audio_output_flags_t flag = static_cast<audio_output_flags_t>(1u << bit);
|
||||
if ((flag & halFlagMask) == flag) {
|
||||
AudioInOutFlag flagStr = audio_output_flag_to_string(flag);
|
||||
if (!flagStr.empty() && !xsd::isUnknownAudioInOutFlag(flagStr)) {
|
||||
result.push_back(flagStr);
|
||||
} else {
|
||||
ALOGE("Unknown audio output flag value 0x%X", flag);
|
||||
status = BAD_VALUE;
|
||||
}
|
||||
halFlagMask = static_cast<audio_output_flags_t>(halFlagMask & ~flag);
|
||||
}
|
||||
}
|
||||
*flags = result;
|
||||
return status;
|
||||
}
|
||||
|
||||
status_t CoreUtils::audioOutputFlagsToHal(const AudioOutputFlags& flags,
|
||||
audio_output_flags_t* halFlagMask) {
|
||||
status_t status = NO_ERROR;
|
||||
*halFlagMask = {};
|
||||
for (const auto& flag : flags) {
|
||||
audio_output_flags_t halFlag;
|
||||
if (!xsd::isUnknownAudioInOutFlag(flag) &&
|
||||
audio_output_flag_from_string(flag.c_str(), &halFlag)) {
|
||||
*halFlagMask = static_cast<audio_output_flags_t>(*halFlagMask | halFlag);
|
||||
} else {
|
||||
ALOGE("Unknown audio output flag \"%s\"", flag.c_str());
|
||||
status = BAD_VALUE;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace CPP_VERSION
|
||||
} // namespace audio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
110
audio/core/all-versions/default/util/include/util/CoreUtils.h
Normal file
110
audio/core/all-versions/default/util/include/util/CoreUtils.h
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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
|
||||
|
||||
// clang-format off
|
||||
#include PATH(android/hardware/audio/FILE_VERSION/types.h)
|
||||
// clang-format off
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <system/audio.h>
|
||||
|
||||
#include <common/all-versions/VersionUtils.h>
|
||||
#include <VersionUtils.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace audio {
|
||||
namespace CPP_VERSION {
|
||||
namespace implementation {
|
||||
|
||||
using ::android::hardware::audio::common::utils::EnumBitfield;
|
||||
using ::android::hardware::hidl_vec;
|
||||
using namespace ::android::hardware::audio::common::CPP_VERSION;
|
||||
using namespace ::android::hardware::audio::CPP_VERSION;
|
||||
|
||||
struct CoreUtils {
|
||||
// Note: the converters for DeviceAddress have to be in CoreUtils for HAL V4
|
||||
// because DeviceAddress used to be defined in the core HAL. For V5 and above
|
||||
// these functions simply delegate to HidlUtils.
|
||||
static status_t deviceAddressToHal(const DeviceAddress& device, audio_devices_t* halDeviceType,
|
||||
char* halDeviceAddress);
|
||||
static status_t deviceAddressFromHal(audio_devices_t halDeviceType, const char* halDeviceAddress,
|
||||
DeviceAddress* device);
|
||||
#if MAJOR_VERSION >= 4
|
||||
static status_t microphoneInfoFromHal(const struct audio_microphone_characteristic_t& halMicInfo,
|
||||
MicrophoneInfo* micInfo);
|
||||
static status_t microphoneInfoToHal(const MicrophoneInfo& micInfo, audio_microphone_characteristic_t* halMicInfo);
|
||||
// Note: {Sink|Source}Metadata types are defined in 'common' (since V5), so they can be used
|
||||
// by the BT HAL. However, the converters are defined here, not in HidlUtils to avoid adding
|
||||
// conditionals to handle V4. The converters are only used by 'core' HAL anyways.
|
||||
static status_t sinkMetadataFromHal(const std::vector<record_track_metadata_t>& halTracks,
|
||||
SinkMetadata* sinkMetadata);
|
||||
static status_t sinkMetadataFromHalV7(const std::vector<record_track_metadata_v7_t>& halTracks,
|
||||
bool ignoreNonVendorTags, SinkMetadata* sinkMetadata);
|
||||
static status_t sinkMetadataToHal(const SinkMetadata& sinkMetadata,
|
||||
std::vector<record_track_metadata_t>* halTracks);
|
||||
static status_t sinkMetadataToHalV7(const SinkMetadata& sinkMetadata, bool ignoreNonVendorTags,
|
||||
std::vector<record_track_metadata_v7_t>* halTracks);
|
||||
static status_t sourceMetadataFromHal(const std::vector<playback_track_metadata_t>& halTracks,
|
||||
SourceMetadata* sourceMetadata);
|
||||
static status_t sourceMetadataFromHalV7(const std::vector<playback_track_metadata_v7_t>& halTracks,
|
||||
bool ignoreNonVendorTags, SourceMetadata* sourceMetadata);
|
||||
static status_t sourceMetadataToHal(const SourceMetadata& sourceMetadata,
|
||||
std::vector<playback_track_metadata_t>* halTracks);
|
||||
static status_t sourceMetadataToHalV7(const SourceMetadata& sourceMetadata, bool ignoreNonVendorTags,
|
||||
std::vector<playback_track_metadata_v7_t>* halTracks);
|
||||
#endif
|
||||
|
||||
#if MAJOR_VERSION <= 6
|
||||
using AudioInputFlags =
|
||||
::android::hardware::audio::common::CPP_VERSION::implementation::AudioInputFlagBitfield;
|
||||
using AudioOutputFlags =
|
||||
::android::hardware::audio::common::CPP_VERSION::implementation::AudioOutputFlagBitfield;
|
||||
static inline status_t audioInputFlagsFromHal(audio_input_flags_t halFlagMask, AudioInputFlags* flags) {
|
||||
*flags = EnumBitfield<AudioInputFlag>(halFlagMask);
|
||||
return NO_ERROR;
|
||||
}
|
||||
static inline status_t audioInputFlagsToHal(AudioInputFlags flags, audio_input_flags_t* halFlagMask) {
|
||||
*halFlagMask = static_cast<audio_input_flags_t>(flags);
|
||||
return NO_ERROR;
|
||||
}
|
||||
static inline status_t audioOutputFlagsFromHal(audio_output_flags_t halFlagMask, AudioOutputFlags* flags) {
|
||||
*flags = EnumBitfield<AudioOutputFlag>(halFlagMask);
|
||||
return NO_ERROR;
|
||||
}
|
||||
static inline status_t audioOutputFlagsToHal(AudioOutputFlags flags, audio_output_flags_t* halFlagMask) {
|
||||
*halFlagMask = static_cast<audio_output_flags_t>(flags);
|
||||
return NO_ERROR;
|
||||
}
|
||||
#else
|
||||
using AudioInputFlags = hidl_vec<::android::hardware::audio::CPP_VERSION::AudioInOutFlag>;
|
||||
using AudioOutputFlags = hidl_vec<::android::hardware::audio::CPP_VERSION::AudioInOutFlag>;
|
||||
static status_t audioInputFlagsFromHal(audio_input_flags_t halFlagMask, AudioInputFlags* flags);
|
||||
static status_t audioInputFlagsToHal(const AudioInputFlags& flags, audio_input_flags_t* halFlagMask);
|
||||
static status_t audioOutputFlagsFromHal(audio_output_flags_t halFlagMask, AudioOutputFlags* flags);
|
||||
static status_t audioOutputFlagsToHal(const AudioOutputFlags& flags, audio_output_flags_t* halFlagMask);
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace CPP_VERSION
|
||||
} // namespace audio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
525
audio/core/all-versions/default/util/tests/coreutils_tests.cpp
Normal file
525
audio/core/all-versions/default/util/tests/coreutils_tests.cpp
Normal file
@@ -0,0 +1,525 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#define LOG_TAG "CoreUtils_Test"
|
||||
#include <log/log.h>
|
||||
|
||||
#include <android_audio_policy_configuration_V7_0-enums.h>
|
||||
#include <system/audio.h>
|
||||
#include <util/CoreUtils.h>
|
||||
#include <xsdc/XsdcSupport.h>
|
||||
|
||||
using namespace android;
|
||||
using namespace ::android::hardware::audio::common::CPP_VERSION;
|
||||
using namespace ::android::hardware::audio::CPP_VERSION;
|
||||
using ::android::hardware::hidl_vec;
|
||||
using ::android::hardware::audio::CPP_VERSION::implementation::CoreUtils;
|
||||
namespace xsd {
|
||||
using namespace ::android::audio::policy::configuration::V7_0;
|
||||
}
|
||||
|
||||
static constexpr audio_channel_mask_t kInvalidHalChannelMask = AUDIO_CHANNEL_INVALID;
|
||||
static constexpr audio_content_type_t kInvalidHalContentType =
|
||||
static_cast<audio_content_type_t>(0xFFFFFFFFU);
|
||||
static constexpr audio_devices_t kInvalidHalDevice = static_cast<audio_devices_t>(0xFFFFFFFFU);
|
||||
static constexpr audio_input_flags_t kInvalidInputFlags =
|
||||
static_cast<audio_input_flags_t>(0xFFFFFFFFU);
|
||||
static constexpr audio_output_flags_t kInvalidOutputFlags =
|
||||
static_cast<audio_output_flags_t>(0xFFFFFFFFU);
|
||||
// AUDIO_SOURCE_INVALID is framework-only.
|
||||
static constexpr audio_source_t kInvalidHalSource = static_cast<audio_source_t>(-1);
|
||||
static constexpr audio_usage_t kInvalidHalUsage = static_cast<audio_usage_t>(0xFFFFFFFFU);
|
||||
|
||||
static bool isInputFlag(xsd::AudioInOutFlag flag) {
|
||||
return toString(flag).find("_INPUT_FLAG_") != std::string::npos;
|
||||
}
|
||||
|
||||
static bool isOutputFlag(xsd::AudioInOutFlag flag) {
|
||||
return toString(flag).find("_OUTPUT_FLAG_") != std::string::npos;
|
||||
}
|
||||
|
||||
TEST(CoreUtils, ConvertInvalidInputFlagMask) {
|
||||
CoreUtils::AudioInputFlags invalid;
|
||||
EXPECT_EQ(BAD_VALUE, CoreUtils::audioInputFlagsFromHal(kInvalidInputFlags, &invalid));
|
||||
audio_input_flags_t halInvalid;
|
||||
invalid.resize(1);
|
||||
invalid[0] = "random string";
|
||||
EXPECT_EQ(BAD_VALUE, CoreUtils::audioInputFlagsToHal(invalid, &halInvalid));
|
||||
}
|
||||
|
||||
TEST(CoreUtils, ConvertInputFlagMask) {
|
||||
CoreUtils::AudioInputFlags emptyInputFlags;
|
||||
audio_input_flags_t halEmptyInputFlags;
|
||||
EXPECT_EQ(NO_ERROR, CoreUtils::audioInputFlagsToHal(emptyInputFlags, &halEmptyInputFlags));
|
||||
EXPECT_EQ(AUDIO_INPUT_FLAG_NONE, halEmptyInputFlags);
|
||||
CoreUtils::AudioInputFlags emptyInputFlagsBack;
|
||||
EXPECT_EQ(NO_ERROR,
|
||||
CoreUtils::audioInputFlagsFromHal(halEmptyInputFlags, &emptyInputFlagsBack));
|
||||
EXPECT_EQ(emptyInputFlags, emptyInputFlagsBack);
|
||||
CoreUtils::AudioInputFlags emptyInputFlagsFromNone;
|
||||
EXPECT_EQ(NO_ERROR,
|
||||
CoreUtils::audioInputFlagsFromHal(AUDIO_INPUT_FLAG_NONE, &emptyInputFlagsFromNone));
|
||||
EXPECT_EQ(emptyInputFlags, emptyInputFlagsFromNone);
|
||||
|
||||
std::vector<std::string> allEnumValues;
|
||||
for (const auto enumVal : xsdc_enum_range<xsd::AudioInOutFlag>{}) {
|
||||
if (isInputFlag(enumVal)) {
|
||||
allEnumValues.push_back(toString(enumVal));
|
||||
}
|
||||
}
|
||||
CoreUtils::AudioInputFlags allInputFlags;
|
||||
allInputFlags.resize(allEnumValues.size());
|
||||
for (size_t i = 0; i < allEnumValues.size(); ++i) {
|
||||
allInputFlags[i] = allEnumValues[i];
|
||||
}
|
||||
audio_input_flags_t halAllInputFlags;
|
||||
EXPECT_EQ(NO_ERROR, CoreUtils::audioInputFlagsToHal(allInputFlags, &halAllInputFlags));
|
||||
CoreUtils::AudioInputFlags allInputFlagsBack;
|
||||
EXPECT_EQ(NO_ERROR, CoreUtils::audioInputFlagsFromHal(halAllInputFlags, &allInputFlagsBack));
|
||||
EXPECT_EQ(allInputFlags, allInputFlagsBack);
|
||||
}
|
||||
|
||||
TEST(CoreUtils, ConvertInvalidOutputFlagMask) {
|
||||
CoreUtils::AudioOutputFlags invalid;
|
||||
EXPECT_EQ(BAD_VALUE, CoreUtils::audioOutputFlagsFromHal(kInvalidOutputFlags, &invalid));
|
||||
audio_output_flags_t halInvalid;
|
||||
invalid.resize(1);
|
||||
invalid[0] = "random string";
|
||||
EXPECT_EQ(BAD_VALUE, CoreUtils::audioOutputFlagsToHal(invalid, &halInvalid));
|
||||
}
|
||||
|
||||
TEST(CoreUtils, ConvertOutputFlagMask) {
|
||||
CoreUtils::AudioOutputFlags emptyOutputFlags;
|
||||
audio_output_flags_t halEmptyOutputFlags;
|
||||
EXPECT_EQ(NO_ERROR, CoreUtils::audioOutputFlagsToHal(emptyOutputFlags, &halEmptyOutputFlags));
|
||||
EXPECT_EQ(AUDIO_OUTPUT_FLAG_NONE, halEmptyOutputFlags);
|
||||
CoreUtils::AudioOutputFlags emptyOutputFlagsBack;
|
||||
EXPECT_EQ(NO_ERROR,
|
||||
CoreUtils::audioOutputFlagsFromHal(halEmptyOutputFlags, &emptyOutputFlagsBack));
|
||||
EXPECT_EQ(emptyOutputFlags, emptyOutputFlagsBack);
|
||||
CoreUtils::AudioOutputFlags emptyOutputFlagsFromNone;
|
||||
EXPECT_EQ(NO_ERROR, CoreUtils::audioOutputFlagsFromHal(AUDIO_OUTPUT_FLAG_NONE,
|
||||
&emptyOutputFlagsFromNone));
|
||||
EXPECT_EQ(emptyOutputFlags, emptyOutputFlagsFromNone);
|
||||
|
||||
std::vector<std::string> allEnumValues;
|
||||
for (const auto enumVal : xsdc_enum_range<xsd::AudioInOutFlag>{}) {
|
||||
if (isOutputFlag(enumVal)) {
|
||||
allEnumValues.push_back(toString(enumVal));
|
||||
}
|
||||
}
|
||||
CoreUtils::AudioOutputFlags allOutputFlags;
|
||||
allOutputFlags.resize(allEnumValues.size());
|
||||
for (size_t i = 0; i < allEnumValues.size(); ++i) {
|
||||
allOutputFlags[i] = allEnumValues[i];
|
||||
}
|
||||
audio_output_flags_t halAllOutputFlags;
|
||||
EXPECT_EQ(NO_ERROR, CoreUtils::audioOutputFlagsToHal(allOutputFlags, &halAllOutputFlags));
|
||||
CoreUtils::AudioOutputFlags allOutputFlagsBack;
|
||||
EXPECT_EQ(NO_ERROR, CoreUtils::audioOutputFlagsFromHal(halAllOutputFlags, &allOutputFlagsBack));
|
||||
EXPECT_EQ(allOutputFlags, allOutputFlagsBack);
|
||||
}
|
||||
|
||||
static MicrophoneInfo generateValidMicrophoneInfo() {
|
||||
MicrophoneInfo micInfo{};
|
||||
micInfo.deviceAddress.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_IN_BUILTIN_MIC);
|
||||
micInfo.channelMapping.resize(1);
|
||||
micInfo.channelMapping[0] = AudioMicrophoneChannelMapping::DIRECT;
|
||||
micInfo.location = AudioMicrophoneLocation::MAINBODY_MOVABLE;
|
||||
micInfo.group = 42;
|
||||
micInfo.indexInTheGroup = 13;
|
||||
micInfo.sensitivity = 65.5;
|
||||
micInfo.maxSpl = 100.5;
|
||||
micInfo.minSpl = 36.6;
|
||||
micInfo.directionality = AudioMicrophoneDirectionality::HYPER_CARDIOID;
|
||||
micInfo.frequencyResponse.resize(1);
|
||||
micInfo.frequencyResponse[0].frequency = 1000;
|
||||
micInfo.frequencyResponse[0].level = 85;
|
||||
micInfo.position.x = 0;
|
||||
micInfo.position.y = 1;
|
||||
micInfo.position.z = 0;
|
||||
micInfo.orientation.x = 0;
|
||||
micInfo.orientation.y = 0;
|
||||
micInfo.orientation.z = 1;
|
||||
return micInfo;
|
||||
}
|
||||
|
||||
TEST(CoreUtils, ConvertInvalidMicrophoneInfo) {
|
||||
MicrophoneInfo invalid;
|
||||
audio_microphone_characteristic_t halInvalid{};
|
||||
halInvalid.device = kInvalidHalDevice;
|
||||
EXPECT_EQ(BAD_VALUE, CoreUtils::microphoneInfoFromHal(halInvalid, &invalid));
|
||||
|
||||
MicrophoneInfo oversizeDeviceId = generateValidMicrophoneInfo();
|
||||
oversizeDeviceId.deviceId = std::string(AUDIO_MICROPHONE_ID_MAX_LEN + 1, 'A');
|
||||
EXPECT_EQ(BAD_VALUE, CoreUtils::microphoneInfoToHal(oversizeDeviceId, &halInvalid));
|
||||
MicrophoneInfo invalidDeviceType = generateValidMicrophoneInfo();
|
||||
invalidDeviceType.deviceAddress.deviceType = "random string";
|
||||
EXPECT_EQ(BAD_VALUE, CoreUtils::microphoneInfoToHal(invalidDeviceType, &halInvalid));
|
||||
MicrophoneInfo oversizeChannelMapping = generateValidMicrophoneInfo();
|
||||
oversizeChannelMapping.channelMapping.resize(AUDIO_CHANNEL_COUNT_MAX + 1);
|
||||
EXPECT_EQ(BAD_VALUE, CoreUtils::microphoneInfoToHal(oversizeChannelMapping, &halInvalid));
|
||||
MicrophoneInfo oversizeFrequencyResponses = generateValidMicrophoneInfo();
|
||||
oversizeFrequencyResponses.frequencyResponse.resize(AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES +
|
||||
1);
|
||||
EXPECT_EQ(BAD_VALUE, CoreUtils::microphoneInfoToHal(oversizeFrequencyResponses, &halInvalid));
|
||||
}
|
||||
|
||||
TEST(CoreUtils, ConvertMicrophoneInfo) {
|
||||
MicrophoneInfo micInfo = generateValidMicrophoneInfo();
|
||||
audio_microphone_characteristic_t halMicInfo;
|
||||
EXPECT_EQ(NO_ERROR, CoreUtils::microphoneInfoToHal(micInfo, &halMicInfo));
|
||||
MicrophoneInfo micInfoBack;
|
||||
EXPECT_EQ(NO_ERROR, CoreUtils::microphoneInfoFromHal(halMicInfo, &micInfoBack));
|
||||
EXPECT_EQ(micInfo, micInfoBack);
|
||||
}
|
||||
|
||||
static RecordTrackMetadata generateMinimalRecordTrackMetadata() {
|
||||
RecordTrackMetadata metadata{};
|
||||
metadata.source = toString(xsd::AudioSource::AUDIO_SOURCE_DEFAULT);
|
||||
metadata.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_NONE);
|
||||
return metadata;
|
||||
}
|
||||
|
||||
static RecordTrackMetadata generateValidRecordTrackMetadata() {
|
||||
RecordTrackMetadata metadata = generateMinimalRecordTrackMetadata();
|
||||
metadata.tags.resize(1);
|
||||
metadata.tags[0] = "VX_GOOGLE_42";
|
||||
metadata.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_IN_MONO);
|
||||
metadata.gain = 1.0;
|
||||
return metadata;
|
||||
}
|
||||
|
||||
static RecordTrackMetadata generateValidRecordTrackMetadataWithDevice() {
|
||||
RecordTrackMetadata metadata = generateValidRecordTrackMetadata();
|
||||
metadata.destination.device({});
|
||||
metadata.destination.device().deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_SPEAKER);
|
||||
return metadata;
|
||||
}
|
||||
|
||||
using SinkTracks = hidl_vec<RecordTrackMetadata>;
|
||||
|
||||
TEST(CoreUtils, ConvertInvalidSinkMetadata) {
|
||||
SinkMetadata invalidSource;
|
||||
invalidSource.tracks = SinkTracks{generateMinimalRecordTrackMetadata()};
|
||||
invalidSource.tracks[0].source = "random string";
|
||||
EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataToHal(invalidSource, nullptr));
|
||||
EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataToHalV7(invalidSource,
|
||||
false /*ignoreNonVendorTags*/, nullptr));
|
||||
EXPECT_EQ(BAD_VALUE,
|
||||
CoreUtils::sinkMetadataToHalV7(invalidSource, true /*ignoreNonVendorTags*/, nullptr));
|
||||
SinkMetadata invalidDeviceType;
|
||||
invalidDeviceType.tracks = SinkTracks{generateValidRecordTrackMetadataWithDevice()};
|
||||
invalidDeviceType.tracks[0].destination.device().deviceType = "random string";
|
||||
EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataToHal(invalidDeviceType, nullptr));
|
||||
EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataToHalV7(invalidDeviceType,
|
||||
false /*ignoreNonVendorTags*/, nullptr));
|
||||
EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataToHalV7(invalidDeviceType,
|
||||
true /*ignoreNonVendorTags*/, nullptr));
|
||||
SinkMetadata invalidChannelMask;
|
||||
invalidChannelMask.tracks = SinkTracks{generateValidRecordTrackMetadata()};
|
||||
invalidChannelMask.tracks[0].channelMask = "random string";
|
||||
// Channel mask is sliced away by 'sinkMetadataToHal'
|
||||
EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataToHal(invalidChannelMask, nullptr));
|
||||
EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataToHalV7(invalidChannelMask,
|
||||
false /*ignoreNonVendorTags*/, nullptr));
|
||||
EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataToHalV7(invalidChannelMask,
|
||||
true /*ignoreNonVendorTags*/, nullptr));
|
||||
SinkMetadata invalidTags;
|
||||
invalidTags.tracks = SinkTracks{generateValidRecordTrackMetadata()};
|
||||
invalidTags.tracks[0].tags[0] = "random string";
|
||||
// Tags are sliced away by 'sinkMetadataToHal'
|
||||
EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataToHal(invalidTags, nullptr));
|
||||
EXPECT_EQ(BAD_VALUE,
|
||||
CoreUtils::sinkMetadataToHalV7(invalidTags, false /*ignoreNonVendorTags*/, nullptr));
|
||||
// Non-vendor tags should be filtered out.
|
||||
EXPECT_EQ(NO_ERROR,
|
||||
CoreUtils::sinkMetadataToHalV7(invalidTags, true /*ignoreNonVendorTags*/, nullptr));
|
||||
|
||||
// Verify that a default-initialized metadata is valid.
|
||||
std::vector<record_track_metadata_t> halValid(1, record_track_metadata_t{});
|
||||
std::vector<record_track_metadata_v7_t> halValidV7(1, record_track_metadata_v7_t{});
|
||||
SinkMetadata valid;
|
||||
EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataFromHal(halValid, &valid));
|
||||
EXPECT_EQ(NO_ERROR,
|
||||
CoreUtils::sinkMetadataFromHalV7(halValidV7, false /*ignoreNonVendorTags*/, &valid));
|
||||
EXPECT_EQ(NO_ERROR,
|
||||
CoreUtils::sinkMetadataFromHalV7(halValidV7, true /*ignoreNonVendorTags*/, &valid));
|
||||
|
||||
std::vector<record_track_metadata_t> halInvalidSource = {{.source = kInvalidHalSource}};
|
||||
std::vector<record_track_metadata_v7_t> halInvalidSourceV7 = {
|
||||
{.base = {.source = kInvalidHalSource}}};
|
||||
EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataFromHal(halInvalidSource, &invalidSource));
|
||||
EXPECT_EQ(BAD_VALUE,
|
||||
CoreUtils::sinkMetadataFromHalV7(halInvalidSourceV7, false /*ignoreNonVendorTags*/,
|
||||
&invalidSource));
|
||||
EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataFromHalV7(
|
||||
halInvalidSourceV7, true /*ignoreNonVendorTags*/, &invalidSource));
|
||||
std::vector<record_track_metadata_t> halInvalidDeviceType = {
|
||||
{.dest_device = kInvalidHalDevice}};
|
||||
std::vector<record_track_metadata_v7_t> halInvalidDeviceTypeV7 = {
|
||||
{.base = {.dest_device = kInvalidHalDevice}}};
|
||||
EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataFromHal(halInvalidDeviceType, &invalidDeviceType));
|
||||
EXPECT_EQ(BAD_VALUE,
|
||||
CoreUtils::sinkMetadataFromHalV7(halInvalidDeviceTypeV7,
|
||||
false /*ignoreNonVendorTags*/, &invalidDeviceType));
|
||||
EXPECT_EQ(BAD_VALUE,
|
||||
CoreUtils::sinkMetadataFromHalV7(halInvalidDeviceTypeV7, true /*ignoreNonVendorTags*/,
|
||||
&invalidDeviceType));
|
||||
std::vector<record_track_metadata_v7_t> halInvalidChannelMaskV7 = {
|
||||
{.channel_mask = kInvalidHalChannelMask}};
|
||||
EXPECT_EQ(BAD_VALUE,
|
||||
CoreUtils::sinkMetadataFromHalV7(halInvalidChannelMaskV7,
|
||||
false /*ignoreNonVendorTags*/, &invalidChannelMask));
|
||||
EXPECT_EQ(BAD_VALUE,
|
||||
CoreUtils::sinkMetadataFromHalV7(halInvalidChannelMaskV7,
|
||||
true /*ignoreNonVendorTags*/, &invalidChannelMask));
|
||||
std::vector<record_track_metadata_v7_t> halInvalidTagsV7 = {{.tags = "random string"}};
|
||||
EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataFromHalV7(
|
||||
halInvalidTagsV7, false /*ignoreNonVendorTags*/, &invalidTags));
|
||||
// Non-vendor tags should be filtered out.
|
||||
EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataFromHalV7(
|
||||
halInvalidTagsV7, true /*ignoreNonVendorTags*/, &invalidTags));
|
||||
}
|
||||
|
||||
TEST(CoreUtils, ConvertEmptySinkMetadata) {
|
||||
SinkMetadata emptySinkMetadata;
|
||||
std::vector<record_track_metadata_t> halEmptySinkMetadata;
|
||||
EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataToHal(emptySinkMetadata, &halEmptySinkMetadata));
|
||||
EXPECT_TRUE(halEmptySinkMetadata.empty());
|
||||
SinkMetadata emptySinkMetadataBack;
|
||||
EXPECT_EQ(NO_ERROR,
|
||||
CoreUtils::sinkMetadataFromHal(halEmptySinkMetadata, &emptySinkMetadataBack));
|
||||
EXPECT_EQ(emptySinkMetadata, emptySinkMetadataBack);
|
||||
std::vector<record_track_metadata_v7_t> halEmptySinkMetadataV7;
|
||||
EXPECT_EQ(NO_ERROR,
|
||||
CoreUtils::sinkMetadataToHalV7(emptySinkMetadata, false /*ignoreNonVendorTags*/,
|
||||
&halEmptySinkMetadataV7));
|
||||
EXPECT_TRUE(halEmptySinkMetadataV7.empty());
|
||||
SinkMetadata emptySinkMetadataBackFromV7;
|
||||
EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataFromHalV7(halEmptySinkMetadataV7,
|
||||
false /*ignoreNonVendorTags*/,
|
||||
&emptySinkMetadataBackFromV7));
|
||||
EXPECT_EQ(emptySinkMetadata, emptySinkMetadataBackFromV7);
|
||||
}
|
||||
|
||||
class SinkMetadataConvertTest : public ::testing::TestWithParam<SinkTracks> {};
|
||||
|
||||
TEST_P(SinkMetadataConvertTest, ToFromHal) {
|
||||
SinkMetadata sinkMetadata;
|
||||
sinkMetadata.tracks = GetParam();
|
||||
std::vector<record_track_metadata_t> halSinkMetadata;
|
||||
EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataToHal(sinkMetadata, &halSinkMetadata));
|
||||
EXPECT_EQ(sinkMetadata.tracks.size(), halSinkMetadata.size());
|
||||
SinkMetadata sinkMetadataBackTrimmed;
|
||||
EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataFromHal(halSinkMetadata, &sinkMetadataBackTrimmed));
|
||||
// Can't compare 'sinkMetadata' to 'sinkMetadataBackTrimmed'
|
||||
std::vector<record_track_metadata_v7_t> halSinkMetadataV7;
|
||||
EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataToHalV7(sinkMetadata, false /*ignoreNonVendorTags*/,
|
||||
&halSinkMetadataV7));
|
||||
EXPECT_EQ(sinkMetadata.tracks.size(), halSinkMetadataV7.size());
|
||||
SinkMetadata sinkMetadataBackFromV7;
|
||||
EXPECT_EQ(NO_ERROR,
|
||||
CoreUtils::sinkMetadataFromHalV7(halSinkMetadataV7, false /*ignoreNonVendorTags*/,
|
||||
&sinkMetadataBackFromV7));
|
||||
EXPECT_EQ(sinkMetadata, sinkMetadataBackFromV7);
|
||||
std::vector<record_track_metadata_v7_t> halSinkMetadataV7FromTrimmed;
|
||||
EXPECT_EQ(NO_ERROR,
|
||||
CoreUtils::sinkMetadataToHalV7(sinkMetadataBackTrimmed, false /*ignoreNonVendorTags*/,
|
||||
&halSinkMetadataV7FromTrimmed));
|
||||
EXPECT_EQ(sinkMetadata.tracks.size(), halSinkMetadataV7FromTrimmed.size());
|
||||
SinkMetadata sinkMetadataBackFromV7Trimmed;
|
||||
EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataFromHalV7(halSinkMetadataV7FromTrimmed,
|
||||
false /*ignoreNonVendorTags*/,
|
||||
&sinkMetadataBackFromV7Trimmed));
|
||||
EXPECT_EQ(sinkMetadataBackTrimmed, sinkMetadataBackFromV7Trimmed);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(ValidRecordTrackMetadatas, SinkMetadataConvertTest,
|
||||
::testing::Values(SinkTracks{generateMinimalRecordTrackMetadata()},
|
||||
SinkTracks{generateValidRecordTrackMetadata()},
|
||||
SinkTracks{generateValidRecordTrackMetadataWithDevice()},
|
||||
SinkTracks{
|
||||
generateMinimalRecordTrackMetadata(),
|
||||
generateValidRecordTrackMetadata(),
|
||||
generateValidRecordTrackMetadataWithDevice()}));
|
||||
|
||||
static PlaybackTrackMetadata generateMinimalPlaybackTrackMetadata() {
|
||||
PlaybackTrackMetadata metadata{};
|
||||
metadata.usage = toString(xsd::AudioUsage::AUDIO_USAGE_UNKNOWN);
|
||||
metadata.contentType = toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_UNKNOWN);
|
||||
metadata.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_NONE);
|
||||
return metadata;
|
||||
}
|
||||
|
||||
static PlaybackTrackMetadata generateValidPlaybackTrackMetadata() {
|
||||
PlaybackTrackMetadata metadata = generateMinimalPlaybackTrackMetadata();
|
||||
metadata.tags.resize(1);
|
||||
metadata.tags[0] = "VX_GOOGLE_42";
|
||||
metadata.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_MONO);
|
||||
metadata.gain = 1.0;
|
||||
return metadata;
|
||||
}
|
||||
|
||||
using SourceTracks = hidl_vec<PlaybackTrackMetadata>;
|
||||
|
||||
TEST(CoreUtils, ConvertInvalidSourceMetadata) {
|
||||
SourceMetadata invalidUsage;
|
||||
invalidUsage.tracks = SourceTracks{generateMinimalPlaybackTrackMetadata()};
|
||||
invalidUsage.tracks[0].usage = "random string";
|
||||
EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataToHal(invalidUsage, nullptr));
|
||||
EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataToHalV7(invalidUsage,
|
||||
false /*ignoreNonVendorTags*/, nullptr));
|
||||
SourceMetadata invalidContentType;
|
||||
invalidContentType.tracks = SourceTracks{generateMinimalPlaybackTrackMetadata()};
|
||||
invalidContentType.tracks[0].contentType = "random string";
|
||||
EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataToHal(invalidContentType, nullptr));
|
||||
EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataToHalV7(invalidContentType,
|
||||
false /*ignoreNonVendorTags*/, nullptr));
|
||||
EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataToHalV7(invalidContentType,
|
||||
true /*ignoreNonVendorTags*/, nullptr));
|
||||
SourceMetadata invalidChannelMask;
|
||||
invalidChannelMask.tracks = SourceTracks{generateValidPlaybackTrackMetadata()};
|
||||
invalidChannelMask.tracks[0].channelMask = "random string";
|
||||
// Channel mask is sliced away by 'sourceMetadataToHal'
|
||||
EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataToHal(invalidChannelMask, nullptr));
|
||||
EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataToHalV7(invalidChannelMask,
|
||||
false /*ignoreNonVendorTags*/, nullptr));
|
||||
EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataToHalV7(invalidChannelMask,
|
||||
true /*ignoreNonVendorTags*/, nullptr));
|
||||
SourceMetadata invalidTags;
|
||||
invalidTags.tracks = SourceTracks{generateValidPlaybackTrackMetadata()};
|
||||
invalidTags.tracks[0].tags[0] = "random string";
|
||||
// Tags are sliced away by 'sourceMetadataToHal'
|
||||
EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataToHal(invalidTags, nullptr));
|
||||
EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataToHalV7(invalidTags,
|
||||
false /*ignoreNonVendorTags*/, nullptr));
|
||||
// Non-vendor tags should be filtered out.
|
||||
EXPECT_EQ(NO_ERROR,
|
||||
CoreUtils::sourceMetadataToHalV7(invalidTags, true /*ignoreNonVendorTags*/, nullptr));
|
||||
|
||||
// Verify that a default-initialized metadata is valid.
|
||||
std::vector<playback_track_metadata_t> halValid(1, playback_track_metadata_t{});
|
||||
std::vector<playback_track_metadata_v7_t> halValidV7(1, playback_track_metadata_v7_t{});
|
||||
SourceMetadata valid;
|
||||
EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataFromHal(halValid, &valid));
|
||||
EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataFromHalV7(halValidV7,
|
||||
false /*ignoreNonVendorTags*/, &valid));
|
||||
EXPECT_EQ(NO_ERROR,
|
||||
CoreUtils::sourceMetadataFromHalV7(halValidV7, true /*ignoreNonVendorTags*/, &valid));
|
||||
|
||||
std::vector<playback_track_metadata_t> halInvalidUsage = {{.usage = kInvalidHalUsage}};
|
||||
std::vector<playback_track_metadata_v7_t> halInvalidUsageV7 = {
|
||||
{.base = {.usage = kInvalidHalUsage}}};
|
||||
EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataFromHal(halInvalidUsage, &invalidUsage));
|
||||
EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataFromHalV7(
|
||||
halInvalidUsageV7, false /*ignoreNonVendorTags*/, &invalidUsage));
|
||||
EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataFromHalV7(
|
||||
halInvalidUsageV7, true /*ignoreNonVendorTags*/, &invalidUsage));
|
||||
std::vector<playback_track_metadata_t> halInvalidContentType = {
|
||||
{.content_type = kInvalidHalContentType}};
|
||||
std::vector<playback_track_metadata_v7_t> halInvalidContentTypeV7 = {
|
||||
{.base = {.content_type = kInvalidHalContentType}}};
|
||||
EXPECT_EQ(BAD_VALUE,
|
||||
CoreUtils::sourceMetadataFromHal(halInvalidContentType, &invalidContentType));
|
||||
EXPECT_EQ(BAD_VALUE,
|
||||
CoreUtils::sourceMetadataFromHalV7(
|
||||
halInvalidContentTypeV7, false /*ignoreNonVendorTags*/, &invalidContentType));
|
||||
EXPECT_EQ(BAD_VALUE,
|
||||
CoreUtils::sourceMetadataFromHalV7(
|
||||
halInvalidContentTypeV7, true /*ignoreNonVendorTags*/, &invalidContentType));
|
||||
std::vector<playback_track_metadata_v7_t> halInvalidChannelMaskV7 = {
|
||||
{.channel_mask = kInvalidHalChannelMask}};
|
||||
EXPECT_EQ(BAD_VALUE,
|
||||
CoreUtils::sourceMetadataFromHalV7(
|
||||
halInvalidChannelMaskV7, false /*ignoreNonVendorTags*/, &invalidChannelMask));
|
||||
EXPECT_EQ(BAD_VALUE,
|
||||
CoreUtils::sourceMetadataFromHalV7(
|
||||
halInvalidChannelMaskV7, true /*ignoreNonVendorTags*/, &invalidChannelMask));
|
||||
std::vector<playback_track_metadata_v7_t> halInvalidTagsV7 = {{.tags = "random string"}};
|
||||
EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataFromHalV7(
|
||||
halInvalidTagsV7, false /*ignoreNonVendorTags*/, &invalidTags));
|
||||
// Non-vendor tags should be filtered out.
|
||||
EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataFromHalV7(
|
||||
halInvalidTagsV7, true /*ignoreNonVendorTags*/, &invalidTags));
|
||||
}
|
||||
|
||||
TEST(CoreUtils, ConvertEmptySourceMetadata) {
|
||||
SourceMetadata emptySourceMetadata;
|
||||
std::vector<playback_track_metadata_t> halEmptySourceMetadata;
|
||||
EXPECT_EQ(NO_ERROR,
|
||||
CoreUtils::sourceMetadataToHal(emptySourceMetadata, &halEmptySourceMetadata));
|
||||
EXPECT_TRUE(halEmptySourceMetadata.empty());
|
||||
SourceMetadata emptySourceMetadataBack;
|
||||
EXPECT_EQ(NO_ERROR,
|
||||
CoreUtils::sourceMetadataFromHal(halEmptySourceMetadata, &emptySourceMetadataBack));
|
||||
EXPECT_EQ(emptySourceMetadata, emptySourceMetadataBack);
|
||||
std::vector<playback_track_metadata_v7_t> halEmptySourceMetadataV7;
|
||||
EXPECT_EQ(NO_ERROR,
|
||||
CoreUtils::sourceMetadataToHalV7(emptySourceMetadata, false /*ignoreNonVendorTags*/,
|
||||
&halEmptySourceMetadataV7));
|
||||
EXPECT_TRUE(halEmptySourceMetadataV7.empty());
|
||||
SourceMetadata emptySourceMetadataBackFromV7;
|
||||
EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataFromHalV7(halEmptySourceMetadataV7,
|
||||
false /*ignoreNonVendorTags*/,
|
||||
&emptySourceMetadataBackFromV7));
|
||||
EXPECT_EQ(emptySourceMetadata, emptySourceMetadataBackFromV7);
|
||||
}
|
||||
|
||||
class SourceMetadataConvertTest : public ::testing::TestWithParam<SourceTracks> {};
|
||||
|
||||
TEST_P(SourceMetadataConvertTest, ToFromHal) {
|
||||
SourceMetadata sourceMetadata;
|
||||
sourceMetadata.tracks = GetParam();
|
||||
std::vector<playback_track_metadata_t> halSourceMetadata;
|
||||
EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataToHal(sourceMetadata, &halSourceMetadata));
|
||||
EXPECT_EQ(sourceMetadata.tracks.size(), halSourceMetadata.size());
|
||||
SourceMetadata sourceMetadataBackTrimmed;
|
||||
EXPECT_EQ(NO_ERROR,
|
||||
CoreUtils::sourceMetadataFromHal(halSourceMetadata, &sourceMetadataBackTrimmed));
|
||||
// Can't compare 'sourceMetadata' to 'sourceMetadataBackTrimmed'
|
||||
std::vector<playback_track_metadata_v7_t> halSourceMetadataV7;
|
||||
EXPECT_EQ(NO_ERROR,
|
||||
CoreUtils::sourceMetadataToHalV7(sourceMetadata, false /*ignoreNonVendorTags*/,
|
||||
&halSourceMetadataV7));
|
||||
EXPECT_EQ(sourceMetadata.tracks.size(), halSourceMetadataV7.size());
|
||||
SourceMetadata sourceMetadataBackFromV7;
|
||||
EXPECT_EQ(NO_ERROR,
|
||||
CoreUtils::sourceMetadataFromHalV7(halSourceMetadataV7, false /*ignoreNonVendorTags*/,
|
||||
&sourceMetadataBackFromV7));
|
||||
EXPECT_EQ(sourceMetadata, sourceMetadataBackFromV7);
|
||||
std::vector<playback_track_metadata_v7_t> halSourceMetadataV7FromTrimmed;
|
||||
EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataToHalV7(sourceMetadataBackTrimmed,
|
||||
false /*ignoreNonVendorTags*/,
|
||||
&halSourceMetadataV7FromTrimmed));
|
||||
EXPECT_EQ(sourceMetadata.tracks.size(), halSourceMetadataV7FromTrimmed.size());
|
||||
SourceMetadata sourceMetadataBackFromV7Trimmed;
|
||||
EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataFromHalV7(halSourceMetadataV7FromTrimmed,
|
||||
false /*ignoreNonVendorTags*/,
|
||||
&sourceMetadataBackFromV7Trimmed));
|
||||
EXPECT_EQ(sourceMetadataBackTrimmed, sourceMetadataBackFromV7Trimmed);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(ValidPlaybackTrackMetadatas, SourceMetadataConvertTest,
|
||||
::testing::Values(SourceTracks{generateMinimalPlaybackTrackMetadata()},
|
||||
SourceTracks{generateValidPlaybackTrackMetadata()},
|
||||
SourceTracks{generateMinimalPlaybackTrackMetadata(),
|
||||
generateValidPlaybackTrackMetadata()}));
|
||||
@@ -336,24 +336,24 @@ TEST_P(OutputStreamTest, updateSourceMetadata) {
|
||||
ASSERT_RESULT(okOrNotSupported, stream->updateSourceMetadata(
|
||||
{{{toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA),
|
||||
toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_MUSIC),
|
||||
{},
|
||||
0.1, // gain
|
||||
toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO),
|
||||
0.1},
|
||||
{}}, // tags
|
||||
{toString(xsd::AudioUsage::AUDIO_USAGE_VOICE_COMMUNICATION),
|
||||
toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_SPEECH),
|
||||
{}, // tags
|
||||
1.0,
|
||||
toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_MONO),
|
||||
1.0},
|
||||
{}},
|
||||
{toString(xsd::AudioUsage::AUDIO_USAGE_ALARM),
|
||||
toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_SONIFICATION),
|
||||
{}, // tags
|
||||
0.0,
|
||||
toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO),
|
||||
0.0},
|
||||
{}},
|
||||
{toString(xsd::AudioUsage::AUDIO_USAGE_ASSISTANT),
|
||||
toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_UNKNOWN),
|
||||
{},
|
||||
0.3,
|
||||
toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_MONO),
|
||||
0.3}}}
|
||||
{}}}}
|
||||
));
|
||||
// clang-format on
|
||||
// Set no metadata as if all stream track had stopped
|
||||
|
||||
@@ -8,7 +8,6 @@ cc_defaults {
|
||||
"AudioBufferManager.cpp",
|
||||
"AutomaticGainControlEffect.cpp",
|
||||
"BassBoostEffect.cpp",
|
||||
"Conversions.cpp",
|
||||
"DownmixEffect.cpp",
|
||||
"Effect.cpp",
|
||||
"EffectsFactory.cpp",
|
||||
@@ -51,6 +50,7 @@ cc_library_shared {
|
||||
"android.hardware.audio.common@2.0",
|
||||
"android.hardware.audio.common@2.0-util",
|
||||
"android.hardware.audio.effect@2.0",
|
||||
"android.hardware.audio.effect@2.0-util",
|
||||
],
|
||||
cflags: [
|
||||
"-DMAJOR_VERSION=2",
|
||||
@@ -66,6 +66,7 @@ cc_library_shared {
|
||||
"android.hardware.audio.common@4.0",
|
||||
"android.hardware.audio.common@4.0-util",
|
||||
"android.hardware.audio.effect@4.0",
|
||||
"android.hardware.audio.effect@4.0-util",
|
||||
],
|
||||
cflags: [
|
||||
"-DMAJOR_VERSION=4",
|
||||
@@ -81,6 +82,7 @@ cc_library_shared {
|
||||
"android.hardware.audio.common@5.0",
|
||||
"android.hardware.audio.common@5.0-util",
|
||||
"android.hardware.audio.effect@5.0",
|
||||
"android.hardware.audio.effect@5.0-util",
|
||||
],
|
||||
cflags: [
|
||||
"-DMAJOR_VERSION=5",
|
||||
@@ -96,6 +98,7 @@ cc_library_shared {
|
||||
"android.hardware.audio.common@6.0",
|
||||
"android.hardware.audio.common@6.0-util",
|
||||
"android.hardware.audio.effect@6.0",
|
||||
"android.hardware.audio.effect@6.0-util",
|
||||
],
|
||||
cflags: [
|
||||
"-DMAJOR_VERSION=6",
|
||||
@@ -111,6 +114,7 @@ cc_library_shared {
|
||||
"android.hardware.audio.common@7.0",
|
||||
"android.hardware.audio.common@7.0-util",
|
||||
"android.hardware.audio.effect@7.0",
|
||||
"android.hardware.audio.effect@7.0-util",
|
||||
],
|
||||
cflags: [
|
||||
"-DMAJOR_VERSION=7",
|
||||
|
||||
@@ -1,61 +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.
|
||||
*/
|
||||
|
||||
#include "Conversions.h"
|
||||
#include "UuidUtils.h"
|
||||
|
||||
#include <memory.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <common/all-versions/VersionUtils.h>
|
||||
|
||||
using ::android::hardware::audio::common::utils::EnumBitfield;
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace audio {
|
||||
namespace effect {
|
||||
namespace CPP_VERSION {
|
||||
namespace implementation {
|
||||
|
||||
using ::android::hardware::audio::common::CPP_VERSION::implementation::UuidUtils;
|
||||
|
||||
void effectDescriptorFromHal(const effect_descriptor_t& halDescriptor,
|
||||
EffectDescriptor* descriptor) {
|
||||
UuidUtils::uuidFromHal(halDescriptor.type, &descriptor->type);
|
||||
UuidUtils::uuidFromHal(halDescriptor.uuid, &descriptor->uuid);
|
||||
descriptor->flags = EnumBitfield<EffectFlags>(halDescriptor.flags);
|
||||
descriptor->cpuLoad = halDescriptor.cpuLoad;
|
||||
descriptor->memoryUsage = halDescriptor.memoryUsage;
|
||||
memcpy(descriptor->name.data(), halDescriptor.name, descriptor->name.size());
|
||||
memcpy(descriptor->implementor.data(), halDescriptor.implementor,
|
||||
descriptor->implementor.size());
|
||||
}
|
||||
|
||||
std::string uuidToString(const effect_uuid_t& halUuid) {
|
||||
char str[64];
|
||||
snprintf(str, sizeof(str), "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x", halUuid.timeLow,
|
||||
halUuid.timeMid, halUuid.timeHiAndVersion, halUuid.clockSeq, halUuid.node[0],
|
||||
halUuid.node[1], halUuid.node[2], halUuid.node[3], halUuid.node[4], halUuid.node[5]);
|
||||
return str;
|
||||
}
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace CPP_VERSION
|
||||
} // namespace effect
|
||||
} // namespace audio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_HARDWARE_AUDIO_EFFECT_CONVERSIONS_H_
|
||||
#define ANDROID_HARDWARE_AUDIO_EFFECT_CONVERSIONS_H_
|
||||
|
||||
#include PATH(android/hardware/audio/effect/FILE_VERSION/types.h)
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <system/audio_effect.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace audio {
|
||||
namespace effect {
|
||||
namespace CPP_VERSION {
|
||||
namespace implementation {
|
||||
|
||||
using ::android::hardware::audio::effect::CPP_VERSION::EffectDescriptor;
|
||||
|
||||
void effectDescriptorFromHal(const effect_descriptor_t& halDescriptor,
|
||||
EffectDescriptor* descriptor);
|
||||
std::string uuidToString(const effect_uuid_t& halUuid);
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace CPP_VERSION
|
||||
} // namespace effect
|
||||
} // namespace audio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
||||
#endif // ANDROID_HARDWARE_AUDIO_EFFECT_CONVERSIONS_H_
|
||||
@@ -19,7 +19,6 @@
|
||||
#define LOG_TAG "EffectHAL"
|
||||
#define ATRACE_TAG ATRACE_TAG_AUDIO
|
||||
|
||||
#include "Conversions.h"
|
||||
#include "Effect.h"
|
||||
#include "common/all-versions/default/EffectMap.h"
|
||||
|
||||
@@ -30,6 +29,7 @@
|
||||
#include <HidlUtils.h>
|
||||
#include <android/log.h>
|
||||
#include <media/EffectsFactoryApi.h>
|
||||
#include <util/EffectUtils.h>
|
||||
#include <utils/Trace.h>
|
||||
|
||||
#include "VersionUtils.h"
|
||||
@@ -202,34 +202,6 @@ void Effect::effectAuxChannelsConfigToHal(const EffectAuxChannelsConfig& config,
|
||||
halConfig->aux_channels = static_cast<audio_channel_mask_t>(config.auxChannels);
|
||||
}
|
||||
|
||||
void Effect::effectBufferConfigFromHal(const buffer_config_t& halConfig,
|
||||
EffectBufferConfig* config) {
|
||||
config->buffer.id = 0;
|
||||
config->buffer.frameCount = 0;
|
||||
config->samplingRateHz = halConfig.samplingRate;
|
||||
config->channels = AudioChannelBitfield(halConfig.channels);
|
||||
config->format = AudioFormat(halConfig.format);
|
||||
config->accessMode = EffectBufferAccess(halConfig.accessMode);
|
||||
config->mask = static_cast<decltype(config->mask)>(halConfig.mask);
|
||||
}
|
||||
|
||||
// static
|
||||
void Effect::effectBufferConfigToHal(const EffectBufferConfig& config, buffer_config_t* halConfig) {
|
||||
// Note: setting the buffers directly is considered obsolete. They need to be set
|
||||
// using 'setProcessBuffers'.
|
||||
halConfig->buffer.frameCount = 0;
|
||||
halConfig->buffer.raw = NULL;
|
||||
halConfig->samplingRate = config.samplingRateHz;
|
||||
halConfig->channels = static_cast<uint32_t>(config.channels);
|
||||
// Note: The framework code does not use BP.
|
||||
halConfig->bufferProvider.cookie = NULL;
|
||||
halConfig->bufferProvider.getBuffer = NULL;
|
||||
halConfig->bufferProvider.releaseBuffer = NULL;
|
||||
halConfig->format = static_cast<uint8_t>(config.format);
|
||||
halConfig->accessMode = static_cast<uint8_t>(config.accessMode);
|
||||
halConfig->mask = static_cast<uint8_t>(config.mask);
|
||||
}
|
||||
|
||||
#else // MAJOR_VERSION <= 6
|
||||
|
||||
void Effect::effectAuxChannelsConfigFromHal(const channel_config_t& halConfig,
|
||||
@@ -247,68 +219,8 @@ void Effect::effectAuxChannelsConfigToHal(const EffectAuxChannelsConfig& config,
|
||||
(void)HidlUtils::audioChannelMaskToHal(config.auxChannels, &halConfig->aux_channels);
|
||||
}
|
||||
|
||||
void Effect::effectBufferConfigFromHal(const buffer_config_t& halConfig,
|
||||
EffectBufferConfig* config) {
|
||||
config->buffer.unspecified();
|
||||
audio_config_base_t halConfigBase = {halConfig.samplingRate,
|
||||
static_cast<audio_channel_mask_t>(halConfig.channels),
|
||||
static_cast<audio_format_t>(halConfig.format)};
|
||||
(void)HidlUtils::audioConfigBaseOptionalFromHal(
|
||||
halConfigBase, mIsInput, halConfig.mask & EFFECT_CONFIG_FORMAT,
|
||||
halConfig.mask & EFFECT_CONFIG_SMP_RATE, halConfig.mask & EFFECT_CONFIG_CHANNELS,
|
||||
&config->base);
|
||||
if (halConfig.mask & EFFECT_CONFIG_ACC_MODE) {
|
||||
config->accessMode.value(EffectBufferAccess(halConfig.accessMode));
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void Effect::effectBufferConfigToHal(const EffectBufferConfig& config, buffer_config_t* halConfig) {
|
||||
// Note: setting the buffers directly is considered obsolete. They need to be set
|
||||
// using 'setProcessBuffers'.
|
||||
halConfig->buffer.frameCount = 0;
|
||||
halConfig->buffer.raw = nullptr;
|
||||
audio_config_base_t halConfigBase = AUDIO_CONFIG_BASE_INITIALIZER;
|
||||
bool formatSpecified = false, sRateSpecified = false, channelMaskSpecified = false;
|
||||
(void)HidlUtils::audioConfigBaseOptionalToHal(config.base, &halConfigBase, &formatSpecified,
|
||||
&sRateSpecified, &channelMaskSpecified);
|
||||
halConfig->mask = 0;
|
||||
if (sRateSpecified) {
|
||||
halConfig->mask |= EFFECT_CONFIG_SMP_RATE;
|
||||
halConfig->samplingRate = halConfigBase.sample_rate;
|
||||
}
|
||||
if (channelMaskSpecified) {
|
||||
halConfig->mask |= EFFECT_CONFIG_CHANNELS;
|
||||
halConfig->channels = halConfigBase.channel_mask;
|
||||
}
|
||||
if (formatSpecified) {
|
||||
halConfig->mask |= EFFECT_CONFIG_FORMAT;
|
||||
halConfig->format = halConfigBase.format;
|
||||
}
|
||||
// Note: The framework code does not use BP.
|
||||
halConfig->bufferProvider.cookie = nullptr;
|
||||
halConfig->bufferProvider.getBuffer = nullptr;
|
||||
halConfig->bufferProvider.releaseBuffer = nullptr;
|
||||
if (config.accessMode.getDiscriminator() ==
|
||||
EffectBufferConfig::OptionalAccessMode::hidl_discriminator::value) {
|
||||
halConfig->mask |= EFFECT_CONFIG_ACC_MODE;
|
||||
halConfig->accessMode = static_cast<uint8_t>(config.accessMode.value());
|
||||
}
|
||||
}
|
||||
|
||||
#endif // MAJOR_VERSION <= 6
|
||||
|
||||
void Effect::effectConfigFromHal(const effect_config_t& halConfig, EffectConfig* config) {
|
||||
effectBufferConfigFromHal(halConfig.inputCfg, &config->inputCfg);
|
||||
effectBufferConfigFromHal(halConfig.outputCfg, &config->outputCfg);
|
||||
}
|
||||
|
||||
// static
|
||||
void Effect::effectConfigToHal(const EffectConfig& config, effect_config_t* halConfig) {
|
||||
effectBufferConfigToHal(config.inputCfg, &halConfig->inputCfg);
|
||||
effectBufferConfigToHal(config.outputCfg, &halConfig->outputCfg);
|
||||
}
|
||||
|
||||
// static
|
||||
void Effect::effectOffloadParamToHal(const EffectOffloadParameter& offload,
|
||||
effect_offload_param_t* halOffload) {
|
||||
@@ -373,7 +285,7 @@ void Effect::getConfigImpl(int commandCode, const char* commandName, GetConfigCa
|
||||
(*mHandle)->command(mHandle, commandCode, 0, NULL, &halResultSize, &halConfig);
|
||||
EffectConfig config;
|
||||
if (status == OK) {
|
||||
effectConfigFromHal(halConfig, &config);
|
||||
status = EffectUtils::effectConfigFromHal(halConfig, mIsInput, &config);
|
||||
}
|
||||
cb(analyzeCommandStatus(commandName, sContextCallToCommand, status), config);
|
||||
}
|
||||
@@ -538,7 +450,7 @@ Result Effect::setConfigImpl(int commandCode, const char* commandName, const Eff
|
||||
const sp<IEffectBufferProviderCallback>& inputBufferProvider,
|
||||
const sp<IEffectBufferProviderCallback>& outputBufferProvider) {
|
||||
effect_config_t halConfig;
|
||||
effectConfigToHal(config, &halConfig);
|
||||
EffectUtils::effectConfigToHal(config, &halConfig);
|
||||
if (inputBufferProvider != 0) {
|
||||
LOG_FATAL("Using input buffer provider is not supported");
|
||||
}
|
||||
@@ -733,7 +645,7 @@ Return<void> Effect::getDescriptor(getDescriptor_cb _hidl_cb) {
|
||||
status_t status = (*mHandle)->get_descriptor(mHandle, &halDescriptor);
|
||||
EffectDescriptor descriptor;
|
||||
if (status == OK) {
|
||||
effectDescriptorFromHal(halDescriptor, &descriptor);
|
||||
status = EffectUtils::effectDescriptorFromHal(halDescriptor, &descriptor);
|
||||
}
|
||||
_hidl_cb(analyzeStatus("get_descriptor", "", sContextCallFunction, status), descriptor);
|
||||
return Void();
|
||||
|
||||
@@ -203,11 +203,6 @@ struct Effect : public IEffect {
|
||||
EffectAuxChannelsConfig* config);
|
||||
static void effectAuxChannelsConfigToHal(const EffectAuxChannelsConfig& config,
|
||||
channel_config_t* halConfig);
|
||||
void effectBufferConfigFromHal(const buffer_config_t& halConfig, EffectBufferConfig* config);
|
||||
static void effectBufferConfigToHal(const EffectBufferConfig& config,
|
||||
buffer_config_t* halConfig);
|
||||
void effectConfigFromHal(const effect_config_t& halConfig, EffectConfig* config);
|
||||
static void effectConfigToHal(const EffectConfig& config, effect_config_t* halConfig);
|
||||
static void effectOffloadParamToHal(const EffectOffloadParameter& offload,
|
||||
effect_offload_param_t* halOffload);
|
||||
static std::vector<uint8_t> parameterToHal(uint32_t paramSize, const void* paramData,
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
#include "AcousticEchoCancelerEffect.h"
|
||||
#include "AutomaticGainControlEffect.h"
|
||||
#include "BassBoostEffect.h"
|
||||
#include "Conversions.h"
|
||||
#include "DownmixEffect.h"
|
||||
#include "Effect.h"
|
||||
#include "EnvironmentalReverbEffect.h"
|
||||
@@ -27,11 +26,11 @@
|
||||
#include "LoudnessEnhancerEffect.h"
|
||||
#include "NoiseSuppressionEffect.h"
|
||||
#include "PresetReverbEffect.h"
|
||||
#include "UuidUtils.h"
|
||||
#include "VirtualizerEffect.h"
|
||||
#include "VisualizerEffect.h"
|
||||
#include "common/all-versions/default/EffectMap.h"
|
||||
|
||||
#include <UuidUtils.h>
|
||||
#include <android/log.h>
|
||||
#include <media/EffectsFactoryApi.h>
|
||||
#include <system/audio_effects/effect_aec.h>
|
||||
@@ -45,6 +44,7 @@
|
||||
#include <system/audio_effects/effect_presetreverb.h>
|
||||
#include <system/audio_effects/effect_virtualizer.h>
|
||||
#include <system/audio_effects/effect_visualizer.h>
|
||||
#include <util/EffectUtils.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
@@ -107,7 +107,7 @@ restart:
|
||||
effect_descriptor_t halDescriptor;
|
||||
status = EffectQueryEffect(i, &halDescriptor);
|
||||
if (status == OK) {
|
||||
effectDescriptorFromHal(halDescriptor, &result[i]);
|
||||
EffectUtils::effectDescriptorFromHal(halDescriptor, &result[i]);
|
||||
} else {
|
||||
ALOGE("Error querying effect at position %d / %d: %s", i, numEffects,
|
||||
strerror(-status));
|
||||
@@ -141,11 +141,11 @@ Return<void> EffectsFactory::getDescriptor(const Uuid& uuid, getDescriptor_cb _h
|
||||
effect_descriptor_t halDescriptor;
|
||||
status_t status = EffectGetDescriptor(&halUuid, &halDescriptor);
|
||||
EffectDescriptor descriptor;
|
||||
effectDescriptorFromHal(halDescriptor, &descriptor);
|
||||
EffectUtils::effectDescriptorFromHal(halDescriptor, &descriptor);
|
||||
Result retval(Result::OK);
|
||||
if (status != OK) {
|
||||
ALOGE("Error querying effect descriptor for %s: %s", uuidToString(halUuid).c_str(),
|
||||
strerror(-status));
|
||||
ALOGE("Error querying effect descriptor for %s: %s",
|
||||
UuidUtils::uuidToString(halUuid).c_str(), strerror(-status));
|
||||
if (status == -ENOENT) {
|
||||
retval = Result::INVALID_ARGUMENTS;
|
||||
} else {
|
||||
@@ -191,13 +191,14 @@ Return<void> EffectsFactory::createEffectImpl(const Uuid& uuid, int32_t session,
|
||||
effect = dispatchEffectInstanceCreation(halDescriptor, handle);
|
||||
effectId = EffectMap::getInstance().add(handle);
|
||||
} else {
|
||||
ALOGE("Error querying effect descriptor for %s: %s", uuidToString(halUuid).c_str(),
|
||||
strerror(-status));
|
||||
ALOGE("Error querying effect descriptor for %s: %s",
|
||||
UuidUtils::uuidToString(halUuid).c_str(), strerror(-status));
|
||||
EffectRelease(handle);
|
||||
}
|
||||
}
|
||||
if (status != OK) {
|
||||
ALOGE("Error creating effect %s: %s", uuidToString(halUuid).c_str(), strerror(-status));
|
||||
ALOGE("Error creating effect %s: %s", UuidUtils::uuidToString(halUuid).c_str(),
|
||||
strerror(-status));
|
||||
if (status == -ENOENT) {
|
||||
retval = Result::INVALID_ARGUMENTS;
|
||||
} else {
|
||||
|
||||
7
audio/effect/all-versions/default/TEST_MAPPING
Normal file
7
audio/effect/all-versions/default/TEST_MAPPING
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"presubmit": [
|
||||
{
|
||||
"name": "android.hardware.audio.effect@7.0-util_tests"
|
||||
}
|
||||
]
|
||||
}
|
||||
136
audio/effect/all-versions/default/util/Android.bp
Normal file
136
audio/effect/all-versions/default/util/Android.bp
Normal file
@@ -0,0 +1,136 @@
|
||||
cc_defaults {
|
||||
name: "android.hardware.audio.effect-util_default",
|
||||
defaults: ["hidl_defaults"],
|
||||
|
||||
vendor_available: true,
|
||||
|
||||
export_include_dirs: ["include"],
|
||||
|
||||
srcs: [
|
||||
"EffectUtils.cpp",
|
||||
],
|
||||
|
||||
shared_libs: [
|
||||
"liblog",
|
||||
"libutils",
|
||||
"libhidlbase",
|
||||
"android.hardware.audio.common-util",
|
||||
],
|
||||
export_shared_lib_headers: [
|
||||
"android.hardware.audio.common-util",
|
||||
],
|
||||
|
||||
header_libs: [
|
||||
"libaudio_system_headers",
|
||||
"libhardware_headers",
|
||||
],
|
||||
}
|
||||
|
||||
cc_library_shared {
|
||||
name: "android.hardware.audio.effect@2.0-util",
|
||||
defaults: ["android.hardware.audio.effect-util_default"],
|
||||
shared_libs: [
|
||||
"android.hardware.audio.common@2.0",
|
||||
"android.hardware.audio.common@2.0-util",
|
||||
"android.hardware.audio.effect@2.0",
|
||||
],
|
||||
cflags: [
|
||||
"-DMAJOR_VERSION=2",
|
||||
"-DMINOR_VERSION=0",
|
||||
"-include common/all-versions/VersionMacro.h",
|
||||
],
|
||||
}
|
||||
|
||||
cc_library_shared {
|
||||
name: "android.hardware.audio.effect@4.0-util",
|
||||
defaults: ["android.hardware.audio.effect-util_default"],
|
||||
shared_libs: [
|
||||
"android.hardware.audio.common@4.0",
|
||||
"android.hardware.audio.common@4.0-util",
|
||||
"android.hardware.audio.effect@4.0",
|
||||
],
|
||||
cflags: [
|
||||
"-DMAJOR_VERSION=4",
|
||||
"-DMINOR_VERSION=0",
|
||||
"-include common/all-versions/VersionMacro.h",
|
||||
],
|
||||
}
|
||||
|
||||
cc_library_shared {
|
||||
name: "android.hardware.audio.effect@5.0-util",
|
||||
defaults: ["android.hardware.audio.effect-util_default"],
|
||||
shared_libs: [
|
||||
"android.hardware.audio.common@5.0",
|
||||
"android.hardware.audio.common@5.0-util",
|
||||
"android.hardware.audio.effect@5.0",
|
||||
],
|
||||
cflags: [
|
||||
"-DMAJOR_VERSION=5",
|
||||
"-DMINOR_VERSION=0",
|
||||
"-include common/all-versions/VersionMacro.h",
|
||||
],
|
||||
}
|
||||
|
||||
cc_library_shared {
|
||||
name: "android.hardware.audio.effect@6.0-util",
|
||||
defaults: ["android.hardware.audio.effect-util_default"],
|
||||
shared_libs: [
|
||||
"android.hardware.audio.common@6.0",
|
||||
"android.hardware.audio.common@6.0-util",
|
||||
"android.hardware.audio.effect@6.0",
|
||||
],
|
||||
cflags: [
|
||||
"-DMAJOR_VERSION=6",
|
||||
"-DMINOR_VERSION=0",
|
||||
"-include common/all-versions/VersionMacro.h",
|
||||
],
|
||||
}
|
||||
|
||||
cc_library {
|
||||
name: "android.hardware.audio.effect@7.0-util",
|
||||
defaults: ["android.hardware.audio.effect-util_default"],
|
||||
shared_libs: [
|
||||
"android.hardware.audio.common@7.0",
|
||||
"android.hardware.audio.common@7.0-util",
|
||||
"android.hardware.audio.effect@7.0",
|
||||
],
|
||||
cflags: [
|
||||
"-DMAJOR_VERSION=7",
|
||||
"-DMINOR_VERSION=0",
|
||||
"-include common/all-versions/VersionMacro.h",
|
||||
],
|
||||
}
|
||||
|
||||
// Note: this isn't a VTS test, but rather a unit test
|
||||
// to verify correctness of conversion utilities.
|
||||
cc_test {
|
||||
name: "android.hardware.audio.effect@7.0-util_tests",
|
||||
defaults: ["android.hardware.audio.effect-util_default"],
|
||||
|
||||
srcs: ["tests/effectutils_tests.cpp"],
|
||||
|
||||
// Use static linking to allow running in presubmit on
|
||||
// targets that don't have HAL V7.
|
||||
static_libs: [
|
||||
"android.hardware.audio.common@7.0",
|
||||
"android.hardware.audio.common@7.0-enums",
|
||||
"android.hardware.audio.common@7.0-util",
|
||||
"android.hardware.audio.effect@7.0",
|
||||
"android.hardware.audio.effect@7.0-util",
|
||||
],
|
||||
|
||||
shared_libs: [
|
||||
"libbase",
|
||||
"libxml2",
|
||||
],
|
||||
|
||||
cflags: [
|
||||
"-Werror",
|
||||
"-Wall",
|
||||
"-DMAJOR_VERSION=7",
|
||||
"-DMINOR_VERSION=0",
|
||||
"-include common/all-versions/VersionMacro.h",
|
||||
],
|
||||
|
||||
test_suites: ["device-tests"],
|
||||
}
|
||||
183
audio/effect/all-versions/default/util/EffectUtils.cpp
Normal file
183
audio/effect/all-versions/default/util/EffectUtils.cpp
Normal file
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <memory.h>
|
||||
|
||||
#include <HidlUtils.h>
|
||||
#include <UuidUtils.h>
|
||||
#include <common/all-versions/VersionUtils.h>
|
||||
|
||||
#include "util/EffectUtils.h"
|
||||
|
||||
using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
|
||||
using ::android::hardware::audio::common::CPP_VERSION::implementation::UuidUtils;
|
||||
using ::android::hardware::audio::common::utils::EnumBitfield;
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace audio {
|
||||
namespace effect {
|
||||
namespace CPP_VERSION {
|
||||
namespace implementation {
|
||||
|
||||
using namespace ::android::hardware::audio::common::CPP_VERSION;
|
||||
|
||||
#define CONVERT_CHECKED(expr, result) \
|
||||
if (status_t status = (expr); status != NO_ERROR) { \
|
||||
result = status; \
|
||||
}
|
||||
|
||||
#if MAJOR_VERSION <= 6
|
||||
|
||||
status_t EffectUtils::effectBufferConfigFromHal(const buffer_config_t& halConfig, bool /*isInput*/,
|
||||
EffectBufferConfig* config) {
|
||||
config->buffer.id = 0;
|
||||
config->buffer.frameCount = 0;
|
||||
config->samplingRateHz = halConfig.samplingRate;
|
||||
config->channels = EnumBitfield<AudioChannelMask>(halConfig.channels);
|
||||
config->format = AudioFormat(halConfig.format);
|
||||
config->accessMode = EffectBufferAccess(halConfig.accessMode);
|
||||
config->mask = EnumBitfield<EffectConfigParameters>(halConfig.mask);
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
status_t EffectUtils::effectBufferConfigToHal(const EffectBufferConfig& config,
|
||||
buffer_config_t* halConfig) {
|
||||
// Note: setting the buffers directly is considered obsolete. They need to be set
|
||||
// using 'setProcessBuffers'.
|
||||
halConfig->buffer.frameCount = 0;
|
||||
halConfig->buffer.raw = nullptr;
|
||||
halConfig->samplingRate = config.samplingRateHz;
|
||||
halConfig->channels = static_cast<uint32_t>(config.channels);
|
||||
// Note: The framework code does not use BP.
|
||||
halConfig->bufferProvider.cookie = nullptr;
|
||||
halConfig->bufferProvider.getBuffer = nullptr;
|
||||
halConfig->bufferProvider.releaseBuffer = nullptr;
|
||||
halConfig->format = static_cast<uint8_t>(config.format);
|
||||
halConfig->accessMode = static_cast<uint8_t>(config.accessMode);
|
||||
halConfig->mask = static_cast<uint8_t>(config.mask);
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
status_t EffectUtils::effectBufferConfigFromHal(const buffer_config_t& halConfig, bool isInput,
|
||||
EffectBufferConfig* config) {
|
||||
status_t result = NO_ERROR;
|
||||
config->buffer.unspecified();
|
||||
audio_config_base_t halConfigBase = {halConfig.samplingRate,
|
||||
static_cast<audio_channel_mask_t>(halConfig.channels),
|
||||
static_cast<audio_format_t>(halConfig.format)};
|
||||
CONVERT_CHECKED(HidlUtils::audioConfigBaseOptionalFromHal(
|
||||
halConfigBase, isInput, halConfig.mask & EFFECT_CONFIG_FORMAT,
|
||||
halConfig.mask & EFFECT_CONFIG_SMP_RATE,
|
||||
halConfig.mask & EFFECT_CONFIG_CHANNELS, &config->base),
|
||||
result);
|
||||
if (halConfig.mask & EFFECT_CONFIG_ACC_MODE) {
|
||||
config->accessMode.value(EffectBufferAccess(halConfig.accessMode));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
status_t EffectUtils::effectBufferConfigToHal(const EffectBufferConfig& config,
|
||||
buffer_config_t* halConfig) {
|
||||
status_t result = NO_ERROR;
|
||||
// Note: setting the buffers directly is considered obsolete. They need to be set
|
||||
// using 'setProcessBuffers'.
|
||||
halConfig->buffer.frameCount = 0;
|
||||
halConfig->buffer.raw = nullptr;
|
||||
audio_config_base_t halConfigBase = AUDIO_CONFIG_BASE_INITIALIZER;
|
||||
bool formatSpecified = false, sRateSpecified = false, channelMaskSpecified = false;
|
||||
CONVERT_CHECKED(
|
||||
HidlUtils::audioConfigBaseOptionalToHal(config.base, &halConfigBase, &formatSpecified,
|
||||
&sRateSpecified, &channelMaskSpecified),
|
||||
result);
|
||||
halConfig->mask = 0;
|
||||
if (sRateSpecified) {
|
||||
halConfig->mask |= EFFECT_CONFIG_SMP_RATE;
|
||||
halConfig->samplingRate = halConfigBase.sample_rate;
|
||||
}
|
||||
if (channelMaskSpecified) {
|
||||
halConfig->mask |= EFFECT_CONFIG_CHANNELS;
|
||||
halConfig->channels = halConfigBase.channel_mask;
|
||||
}
|
||||
if (formatSpecified) {
|
||||
halConfig->mask |= EFFECT_CONFIG_FORMAT;
|
||||
halConfig->format = halConfigBase.format;
|
||||
}
|
||||
// Note: The framework code does not use BP.
|
||||
halConfig->bufferProvider.cookie = nullptr;
|
||||
halConfig->bufferProvider.getBuffer = nullptr;
|
||||
halConfig->bufferProvider.releaseBuffer = nullptr;
|
||||
if (config.accessMode.getDiscriminator() ==
|
||||
EffectBufferConfig::OptionalAccessMode::hidl_discriminator::value) {
|
||||
halConfig->mask |= EFFECT_CONFIG_ACC_MODE;
|
||||
halConfig->accessMode = static_cast<uint8_t>(config.accessMode.value());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // MAJOR_VERSION >= 6
|
||||
|
||||
status_t EffectUtils::effectConfigFromHal(const effect_config_t& halConfig, bool isInput,
|
||||
EffectConfig* config) {
|
||||
status_t result = NO_ERROR;
|
||||
CONVERT_CHECKED(effectBufferConfigFromHal(halConfig.inputCfg, isInput, &config->inputCfg),
|
||||
result);
|
||||
CONVERT_CHECKED(effectBufferConfigFromHal(halConfig.outputCfg, isInput, &config->outputCfg),
|
||||
result);
|
||||
return result;
|
||||
}
|
||||
|
||||
status_t EffectUtils::effectConfigToHal(const EffectConfig& config, effect_config_t* halConfig) {
|
||||
status_t result = NO_ERROR;
|
||||
CONVERT_CHECKED(effectBufferConfigToHal(config.inputCfg, &halConfig->inputCfg), result);
|
||||
CONVERT_CHECKED(effectBufferConfigToHal(config.outputCfg, &halConfig->outputCfg), result);
|
||||
return result;
|
||||
}
|
||||
|
||||
status_t EffectUtils::effectDescriptorFromHal(const effect_descriptor_t& halDescriptor,
|
||||
EffectDescriptor* descriptor) {
|
||||
UuidUtils::uuidFromHal(halDescriptor.type, &descriptor->type);
|
||||
UuidUtils::uuidFromHal(halDescriptor.uuid, &descriptor->uuid);
|
||||
descriptor->flags = EnumBitfield<EffectFlags>(halDescriptor.flags);
|
||||
descriptor->cpuLoad = halDescriptor.cpuLoad;
|
||||
descriptor->memoryUsage = halDescriptor.memoryUsage;
|
||||
memcpy(descriptor->name.data(), halDescriptor.name, descriptor->name.size());
|
||||
memcpy(descriptor->implementor.data(), halDescriptor.implementor,
|
||||
descriptor->implementor.size());
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
status_t EffectUtils::effectDescriptorToHal(const EffectDescriptor& descriptor,
|
||||
effect_descriptor_t* halDescriptor) {
|
||||
UuidUtils::uuidToHal(descriptor.type, &halDescriptor->type);
|
||||
UuidUtils::uuidToHal(descriptor.uuid, &halDescriptor->uuid);
|
||||
halDescriptor->flags = static_cast<uint32_t>(descriptor.flags);
|
||||
halDescriptor->cpuLoad = descriptor.cpuLoad;
|
||||
halDescriptor->memoryUsage = descriptor.memoryUsage;
|
||||
memcpy(halDescriptor->name, descriptor.name.data(), descriptor.name.size());
|
||||
memcpy(halDescriptor->implementor, descriptor.implementor.data(),
|
||||
descriptor.implementor.size());
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace CPP_VERSION
|
||||
} // namespace effect
|
||||
} // namespace audio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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
|
||||
|
||||
// clang-format off
|
||||
#include PATH(android/hardware/audio/effect/FILE_VERSION/types.h)
|
||||
// clang-format on
|
||||
|
||||
#include <system/audio_effect.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace audio {
|
||||
namespace effect {
|
||||
namespace CPP_VERSION {
|
||||
namespace implementation {
|
||||
|
||||
using namespace ::android::hardware::audio::effect::CPP_VERSION;
|
||||
|
||||
struct EffectUtils {
|
||||
static status_t effectBufferConfigFromHal(const buffer_config_t& halConfig, bool isInput,
|
||||
EffectBufferConfig* config);
|
||||
static status_t effectBufferConfigToHal(const EffectBufferConfig& config,
|
||||
buffer_config_t* halConfig);
|
||||
static status_t effectConfigFromHal(const effect_config_t& halConfig, bool isInput,
|
||||
EffectConfig* config);
|
||||
static status_t effectConfigToHal(const EffectConfig& config, effect_config_t* halConfig);
|
||||
static status_t effectDescriptorFromHal(const effect_descriptor_t& halDescriptor,
|
||||
EffectDescriptor* descriptor);
|
||||
static status_t effectDescriptorToHal(const EffectDescriptor& descriptor,
|
||||
effect_descriptor_t* halDescriptor);
|
||||
};
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace CPP_VERSION
|
||||
} // namespace effect
|
||||
} // namespace audio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#define LOG_TAG "EffectUtils_Test"
|
||||
#include <log/log.h>
|
||||
|
||||
#include <android_audio_policy_configuration_V7_0-enums.h>
|
||||
#include <system/audio_effect.h>
|
||||
#include <util/EffectUtils.h>
|
||||
#include <xsdc/XsdcSupport.h>
|
||||
|
||||
using namespace android;
|
||||
using namespace ::android::hardware::audio::common::CPP_VERSION;
|
||||
using namespace ::android::hardware::audio::effect::CPP_VERSION;
|
||||
using ::android::hardware::audio::effect::CPP_VERSION::implementation::EffectUtils;
|
||||
namespace xsd {
|
||||
using namespace ::android::audio::policy::configuration::V7_0;
|
||||
}
|
||||
|
||||
static constexpr audio_channel_mask_t kInvalidHalChannelMask = AUDIO_CHANNEL_INVALID;
|
||||
static constexpr audio_format_t kInvalidHalFormat = AUDIO_FORMAT_INVALID;
|
||||
|
||||
// Not generated automatically because AudioBuffer contains
|
||||
// instances of hidl_memory which can't be compared properly
|
||||
// in general case due to presence of handles.
|
||||
//
|
||||
// However, in this particular case, handles must not present
|
||||
// thus comparison is possible.
|
||||
//
|
||||
// operator== must be defined in the same namespace as the structures.
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace audio {
|
||||
namespace effect {
|
||||
namespace CPP_VERSION {
|
||||
inline bool operator==(const AudioBuffer& lhs, const AudioBuffer& rhs) {
|
||||
return lhs.id == rhs.id && lhs.frameCount == rhs.frameCount && lhs.data.handle() == nullptr &&
|
||||
rhs.data.handle() == nullptr;
|
||||
}
|
||||
|
||||
inline bool operator==(const EffectBufferConfig& lhs, const EffectBufferConfig& rhs) {
|
||||
return lhs.buffer.getDiscriminator() == rhs.buffer.getDiscriminator() &&
|
||||
(lhs.buffer.getDiscriminator() ==
|
||||
EffectBufferConfig::OptionalBuffer::hidl_discriminator::unspecified ||
|
||||
lhs.buffer.buf() == rhs.buffer.buf()) &&
|
||||
lhs.base == rhs.base && lhs.accessMode == rhs.accessMode;
|
||||
}
|
||||
|
||||
inline bool operator==(const EffectConfig& lhs, const EffectConfig& rhs) {
|
||||
return lhs.inputCfg == rhs.inputCfg && lhs.outputCfg == rhs.outputCfg;
|
||||
}
|
||||
} // namespace CPP_VERSION
|
||||
} // namespace effect
|
||||
} // namespace audio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
||||
TEST(EffectUtils, ConvertInvalidBufferConfig) {
|
||||
buffer_config_t halInvalid;
|
||||
EffectBufferConfig invalidChannelMask;
|
||||
invalidChannelMask.base.channelMask.value("random string");
|
||||
EXPECT_EQ(BAD_VALUE, EffectUtils::effectBufferConfigToHal(invalidChannelMask, &halInvalid));
|
||||
EffectBufferConfig invalidFormat;
|
||||
invalidFormat.base.format.value("random string");
|
||||
EXPECT_EQ(BAD_VALUE, EffectUtils::effectBufferConfigToHal(invalidFormat, &halInvalid));
|
||||
|
||||
buffer_config_t halInvalidChannelMask;
|
||||
EffectBufferConfig invalid;
|
||||
halInvalidChannelMask.channels = kInvalidHalChannelMask;
|
||||
halInvalidChannelMask.mask = EFFECT_CONFIG_CHANNELS;
|
||||
EXPECT_EQ(BAD_VALUE, EffectUtils::effectBufferConfigFromHal(halInvalidChannelMask,
|
||||
false /*isInput*/, &invalid));
|
||||
EXPECT_EQ(BAD_VALUE, EffectUtils::effectBufferConfigFromHal(halInvalidChannelMask,
|
||||
true /*isInput*/, &invalid));
|
||||
buffer_config_t halInvalidFormat;
|
||||
halInvalidFormat.format = (uint8_t)kInvalidHalFormat;
|
||||
halInvalidFormat.mask = EFFECT_CONFIG_FORMAT;
|
||||
EXPECT_EQ(BAD_VALUE, EffectUtils::effectBufferConfigFromHal(halInvalidFormat, false /*isInput*/,
|
||||
&invalid));
|
||||
EXPECT_EQ(BAD_VALUE,
|
||||
EffectUtils::effectBufferConfigFromHal(halInvalidFormat, true /*isInput*/, &invalid));
|
||||
}
|
||||
|
||||
TEST(EffectUtils, ConvertBufferConfig) {
|
||||
EffectBufferConfig empty;
|
||||
buffer_config_t halEmpty;
|
||||
EXPECT_EQ(NO_ERROR, EffectUtils::effectBufferConfigToHal(empty, &halEmpty));
|
||||
EffectBufferConfig emptyBackOut;
|
||||
EXPECT_EQ(NO_ERROR,
|
||||
EffectUtils::effectBufferConfigFromHal(halEmpty, false /*isInput*/, &emptyBackOut));
|
||||
EXPECT_EQ(empty, emptyBackOut);
|
||||
EffectBufferConfig emptyBackIn;
|
||||
EXPECT_EQ(NO_ERROR,
|
||||
EffectUtils::effectBufferConfigFromHal(halEmpty, true /*isInput*/, &emptyBackIn));
|
||||
EXPECT_EQ(empty, emptyBackIn);
|
||||
|
||||
EffectBufferConfig chanMask;
|
||||
chanMask.base.channelMask.value(toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO));
|
||||
buffer_config_t halChanMask;
|
||||
EXPECT_EQ(NO_ERROR, EffectUtils::effectBufferConfigToHal(chanMask, &halChanMask));
|
||||
EffectBufferConfig chanMaskBack;
|
||||
EXPECT_EQ(NO_ERROR, EffectUtils::effectBufferConfigFromHal(halChanMask, false /*isInput*/,
|
||||
&chanMaskBack));
|
||||
EXPECT_EQ(chanMask, chanMaskBack);
|
||||
|
||||
EffectBufferConfig format;
|
||||
format.base.format.value(toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT));
|
||||
buffer_config_t halFormat;
|
||||
EXPECT_EQ(NO_ERROR, EffectUtils::effectBufferConfigToHal(format, &halFormat));
|
||||
EffectBufferConfig formatBackOut;
|
||||
EXPECT_EQ(NO_ERROR,
|
||||
EffectUtils::effectBufferConfigFromHal(halFormat, false /*isInput*/, &formatBackOut));
|
||||
EXPECT_EQ(format, formatBackOut);
|
||||
EffectBufferConfig formatBackIn;
|
||||
EXPECT_EQ(NO_ERROR,
|
||||
EffectUtils::effectBufferConfigFromHal(halFormat, true /*isInput*/, &formatBackIn));
|
||||
EXPECT_EQ(format, formatBackIn);
|
||||
}
|
||||
|
||||
TEST(EffectUtils, ConvertDescriptor) {
|
||||
EffectDescriptor desc{};
|
||||
effect_descriptor_t halDesc;
|
||||
EXPECT_EQ(NO_ERROR, EffectUtils::effectDescriptorToHal(desc, &halDesc));
|
||||
EffectDescriptor descBack;
|
||||
EXPECT_EQ(NO_ERROR, EffectUtils::effectDescriptorFromHal(halDesc, &descBack));
|
||||
EXPECT_EQ(desc, descBack);
|
||||
}
|
||||
Reference in New Issue
Block a user