From 355dd0630ce3cdf321b5be7c0097be15b8cca077 Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Thu, 24 Sep 2020 18:00:44 +0000 Subject: [PATCH 1/5] audio: HAL V7 tweaks - rename AudioBasicConfig -> AudioConfigBase to better match a similar structure in audio.h; - define AudioProfile structure for defining an I/O profile; - use AudioProfile to replace IStream.getSupported* methods with a single IStream.getSupportedProfiles method; - define AudioDevice type for convenience and clarity; - move enums definition for AudioInputFlags and AudioOutputFlags into XSD. This allows parsing APM config w/o depending on the framework code. Bug: 142480271 Test: m Change-Id: I1951b2de383751fe53b96954dfd02cdd1ab6cc8f Merged-In: I1951b2de383751fe53b96954dfd02cdd1ab6cc8f --- audio/7.0/IDevice.hal | 4 +- audio/7.0/IStream.hal | 56 +++++------------- audio/7.0/config/api/current.txt | 31 +++++++++- .../7.0/config/audio_policy_configuration.xsd | 31 +++++++++- .../7.0/config/update_audio_policy_config.sh | 1 + audio/7.0/types.hal | 57 +++---------------- audio/common/7.0/types.hal | 54 +++++++++++------- .../all-versions/default/VersionUtils.h | 2 +- .../default/include/core/default/Device.h | 2 + 9 files changed, 119 insertions(+), 119 deletions(-) diff --git a/audio/7.0/IDevice.hal b/audio/7.0/IDevice.hal index eecd92ed7c..e30e5456bc 100644 --- a/audio/7.0/IDevice.hal +++ b/audio/7.0/IDevice.hal @@ -117,7 +117,7 @@ interface IDevice { AudioIoHandle ioHandle, DeviceAddress device, AudioConfig config, - bitfield flags, + vec flags, SourceMetadata sourceMetadata) generates ( Result retval, IStreamOut outStream, @@ -142,7 +142,7 @@ interface IDevice { AudioIoHandle ioHandle, DeviceAddress device, AudioConfig config, - bitfield flags, + vec flags, SinkMetadata sinkMetadata) generates ( Result retval, IStreamIn inStream, diff --git a/audio/7.0/IStream.hal b/audio/7.0/IStream.hal index 789cb1dfd1..4fe8218b28 100644 --- a/audio/7.0/IStream.hal +++ b/audio/7.0/IStream.hal @@ -44,49 +44,23 @@ interface IStream { getBufferSize() generates (uint64_t bufferSize); /** - * Return supported native sampling rates of the stream for a given format. - * A supported native sample rate is a sample rate that can be efficiently - * played by the hardware (typically without sample-rate conversions). + * Return supported audio profiles for this particular stream. This method + * is normally called for streams opened on devices that use dynamic + * profiles, e.g. HDMI and USB interfaces. Please note that supported + * profiles of the stream may differ from the capabilities of the connected + * physical device. * - * This function is only called for dynamic profile. If called for - * non-dynamic profile is should return NOT_SUPPORTED or the same list - * as in audio_policy_configuration.xml. - * - * Calling this method is equivalent to getting - * AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES on the legacy HAL. - * - * - * @param format audio format for which the sample rates are supported. - * @return retval operation completion status. - * Must be OK if the format is supported. - * @return sampleRateHz supported sample rates. - */ - getSupportedSampleRates(AudioFormat format) - generates (Result retval, vec sampleRates); - - /** - * Return supported channel masks of the stream. Calling this method is - * equivalent to getting AUDIO_PARAMETER_STREAM_SUP_CHANNELS on the legacy - * HAL. - * - * @param format audio format for which the channel masks are supported. - * @return retval operation completion status. - * Must be OK if the format is supported. - * @return masks supported audio masks. - */ - getSupportedChannelMasks(AudioFormat format) - generates (Result retval, vec> masks); - - /** - * Return supported audio formats of the stream. Calling this method is - * equivalent to getting AUDIO_PARAMETER_STREAM_SUP_FORMATS on the legacy - * HAL. + * For devices with fixed configurations, e.g. built-in audio devices, all + * the profiles are specified in the audio_policy_configuration.xml + * file. For such devices, this method must return the configuration from + * the config file, or NOT_SUPPORTED retval. * * @return retval operation completion status. - * @return formats supported audio formats. + * @return formats supported audio profiles. * Must be non empty if retval is OK. */ - getSupportedFormats() generates (Result retval, vec formats); + getSupportedProfiles() + generates (Result retval, vec profiles); /** * Retrieves basic stream configuration: sample rate, audio format, @@ -94,18 +68,18 @@ interface IStream { * * @return config basic stream configuration. */ - getAudioProperties() generates (AudioBasicConfig config); + getAudioProperties() generates (AudioConfigBase config); /** * Sets stream parameters. Only sets parameters that are specified. - * See the description of AudioBasicConfig for the details. + * See the description of AudioConfigBase for the details. * * Optional method. If implemented, only called on a stopped stream. * * @param config basic stream configuration. * @return retval operation completion status. */ - setAudioProperties(AudioBasicConfig config) generates (Result retval); + setAudioProperties(AudioConfigBase config) generates (Result retval); /** * Applies audio effect to the stream. diff --git a/audio/7.0/config/api/current.txt b/audio/7.0/config/api/current.txt index fd9a8ef200..ac8dc8ae0c 100644 --- a/audio/7.0/config/api/current.txt +++ b/audio/7.0/config/api/current.txt @@ -228,6 +228,33 @@ package audio.policy.configuration.V7_0 { enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_WMA_PRO; } + public enum AudioInOutFlag { + method public String getRawName(); + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_DIRECT; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_FAST; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_HW_AV_SYNC; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_HW_HOTWORD; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_MMAP_NOIRQ; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_RAW; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_SYNC; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_VOIP_TX; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_DEEP_BUFFER; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_DIRECT; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_DIRECT_PCM; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_FAST; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_HW_AV_SYNC; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_INCALL_MUSIC; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_MMAP_NOIRQ; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_NON_BLOCKING; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_PRIMARY; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_RAW; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_SYNC; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_TTS; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_VOIP_RX; + } + public class AudioPolicyConfiguration { ctor public AudioPolicyConfiguration(); method public audio.policy.configuration.V7_0.GlobalConfiguration getGlobalConfiguration(); @@ -396,7 +423,7 @@ package audio.policy.configuration.V7_0 { public static class MixPorts.MixPort { ctor public MixPorts.MixPort(); - method public String getFlags(); + method public java.util.List getFlags(); method public audio.policy.configuration.V7_0.Gains getGains(); method public long getMaxActiveCount(); method public long getMaxOpenCount(); @@ -404,7 +431,7 @@ package audio.policy.configuration.V7_0 { method public java.util.List getPreferredUsage(); method public java.util.List getProfile(); method public audio.policy.configuration.V7_0.Role getRole(); - method public void setFlags(String); + method public void setFlags(java.util.List); method public void setGains(audio.policy.configuration.V7_0.Gains); method public void setMaxActiveCount(long); method public void setMaxOpenCount(long); diff --git a/audio/7.0/config/audio_policy_configuration.xsd b/audio/7.0/config/audio_policy_configuration.xsd index 4555a88034..20fe02002e 100644 --- a/audio/7.0/config/audio_policy_configuration.xsd +++ b/audio/7.0/config/audio_policy_configuration.xsd @@ -155,16 +155,41 @@ - + - "|" separated list of audio_output_flags_t or audio_input_flags_t. + The flags indicate suggested stream attributes supported by the profile. - + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/audio/7.0/config/update_audio_policy_config.sh b/audio/7.0/config/update_audio_policy_config.sh index 8714b5f2d3..051a0df916 100755 --- a/audio/7.0/config/update_audio_policy_config.sh +++ b/audio/7.0/config/update_audio_policy_config.sh @@ -128,6 +128,7 @@ updateFile() { for F in $SOURCE_FILES; do updateFile ${F} "channelMasks" "," updateFile ${F} "samplingRates" "," + updateFile ${F} "flags" "|" done; updateIncludes() { diff --git a/audio/7.0/types.hal b/audio/7.0/types.hal index 15ca4921b0..4a9e28915a 100644 --- a/audio/7.0/types.hal +++ b/audio/7.0/types.hal @@ -357,56 +357,15 @@ struct PlaybackRate { }; /** - * The audio output flags serve two purposes: + * The audio flags serve two purposes: * - * - when an output stream is created they indicate its attributes; + * - when a stream is created they indicate its attributes; * - * - when present in an output profile descriptor listed for a particular audio - * hardware module, they indicate that an output stream can be opened that + * - when present in a profile descriptor listed for a particular audio + * hardware module, they indicate that a stream can be opened that * supports the attributes indicated by the flags. + * + * See 'audioIoFlag' in audio_policy_configuration.xsd for the + * list of allowed values. */ -@export(name="audio_output_flags_t", value_prefix="AUDIO_OUTPUT_FLAG_") -enum AudioOutputFlag : int32_t { - NONE = 0x0, // no attributes - DIRECT = 0x1, // this output directly connects a track - // to one output stream: no software mixer - PRIMARY = 0x2, // this output is the primary output of the device. It is - // unique and must be present. It is opened by default and - // receives routing, audio mode and volume controls related - // to voice calls. - FAST = 0x4, // output supports "fast tracks", defined elsewhere - DEEP_BUFFER = 0x8, // use deep audio buffers - COMPRESS_OFFLOAD = 0x10, // offload playback of compressed streams to - // hardware codec - NON_BLOCKING = 0x20, // use non-blocking write - HW_AV_SYNC = 0x40, // output uses a hardware A/V sync - TTS = 0x80, // output for streams transmitted through speaker at a - // sample rate high enough to accommodate lower-range - // ultrasonic p/b - RAW = 0x100, // minimize signal processing - SYNC = 0x200, // synchronize I/O streams - IEC958_NONAUDIO = 0x400, // Audio stream contains compressed audio in SPDIF - // data bursts, not PCM. - DIRECT_PCM = 0x2000, // Audio stream containing PCM data that needs - // to pass through compress path for DSP post proc. - MMAP_NOIRQ = 0x4000, // output operates in MMAP no IRQ mode. - VOIP_RX = 0x8000, // preferred output for VoIP calls. - /** preferred output for call music */ - INCALL_MUSIC = 0x10000, -}; - -/** - * The audio input flags are analogous to audio output flags. - */ -@export(name="audio_input_flags_t", value_prefix="AUDIO_INPUT_FLAG_") -enum AudioInputFlag : int32_t { - NONE = 0x0, // no attributes - FAST = 0x1, // prefer an input that supports "fast tracks" - HW_HOTWORD = 0x2, // prefer an input that captures from hw hotword source - RAW = 0x4, // minimize signal processing - SYNC = 0x8, // synchronize I/O streams - MMAP_NOIRQ = 0x10, // input operates in MMAP no IRQ mode. - VOIP_TX = 0x20, // preferred input for VoIP calls. - HW_AV_SYNC = 0x40, // input connected to an output that uses a hardware A/V sync - DIRECT = 0x80, // for acquiring encoded streams -}; +typedef string AudioInOutFlag; diff --git a/audio/common/7.0/types.hal b/audio/common/7.0/types.hal index 94d0af7673..31c7388329 100644 --- a/audio/common/7.0/types.hal +++ b/audio/common/7.0/types.hal @@ -112,12 +112,28 @@ typedef string AudioFormat; typedef string AudioChannelMask; /** - * Basic configuration applicable to any stream of audio. + * Base configuration attributes applicable to any stream of audio. */ -struct AudioBasicConfig { +struct AudioConfigBase { + AudioFormat format; // 'DEFAULT' means 'unspecified' uint32_t sampleRateHz; // 0 means 'unspecified' vec channelMask; // empty means 'unspecified' - AudioFormat format; // 'DEFAULT' means 'unspecified' +}; + +/** + * Configurations supported for a certain audio format. + */ +struct AudioProfile { + AudioFormat format; + /** List of the sample rates (in Hz) supported by the profile. */ + vec sampleRates; + /** + * List of channel masks supported by the profile. Every subvector might be + * comprised of several individual channel mask entries for non-traditional + * channel masks, e.g. a combination "OUT_FRONT_LEFT,OUT_FRONT_CENTER" which + * doesn't have a corresponding predefined channel mask. + */ + vec> channelMasks; }; /** @@ -136,18 +152,21 @@ enum AudioMode : int32_t { CALL_SCREEN = 4, }; +/** + * Audio device specifies type (or category) of audio I/O device + * (e.g. speaker or headphones). + * See 'audioDevice' in audio_policy_configuration.xsd for the + * list of allowed values. + */ +typedef string AudioDevice; + /** * Specifies a device address in case when several devices of the same type * can be connected (e.g. BT A2DP, USB). */ struct DeviceAddress { - /** - * Audio device specifies type (or category) of audio I/O device - * (e.g. speaker or headphones). - * See 'audioDevice' in audio_policy_configuration.xsd for the - * list of allowed values. - */ - string deviceType; + /** The type of the device. */ + AudioDevice deviceType; safe_union Address { /** * The address may be left unspecified if 'device' specifies @@ -209,7 +228,7 @@ enum AudioEncapsulationMode : int32_t { * Additional information about the stream passed to hardware decoders. */ struct AudioOffloadInfo { - AudioBasicConfig base; + AudioConfigBase base; AudioStreamType streamType; uint32_t bitRatePerSecond; int64_t durationMicroseconds; // -1 if unknown @@ -227,7 +246,7 @@ struct AudioOffloadInfo { * Commonly used audio stream configuration parameters. */ struct AudioConfig { - AudioBasicConfig base; + AudioConfigBase base; AudioOffloadInfo offloadInfo; uint64_t frameCount; }; @@ -372,9 +391,9 @@ struct AudioPortConfig { /** * Basic parameters: sampling rate, format, channel mask. Only some of the * parameters (or none) may be set. See the documentation of the - * AudioBasicConfig struct. + * AudioConfigBase struct. */ - AudioBasicConfig config; + AudioConfigBase config; /** Associated gain control. */ safe_union OptionalGain { Monostate unspecified; @@ -401,13 +420,6 @@ struct AudioPort { */ string name; /** List of audio profiles supported by the port. */ - struct AudioProfile { - AudioFormat format; - /** List of the sample rates supported by the profile. */ - vec sampleRates; - /** List of channel masks supported by the profile. */ - vec channelMasks; - }; vec profiles; /** List of gain controls attached to the port. */ vec gains; diff --git a/audio/common/all-versions/default/VersionUtils.h b/audio/common/all-versions/default/VersionUtils.h index e7755b1a7a..9bfca0cdcc 100644 --- a/audio/common/all-versions/default/VersionUtils.h +++ b/audio/common/all-versions/default/VersionUtils.h @@ -31,7 +31,7 @@ typedef common::CPP_VERSION::AudioDevice AudioDeviceBitfield; typedef common::CPP_VERSION::AudioChannelMask AudioChannelBitfield; typedef common::CPP_VERSION::AudioOutputFlag AudioOutputFlagBitfield; typedef common::CPP_VERSION::AudioInputFlag AudioInputFlagBitfield; -#elif MAJOR_VERSION >= 4 +#elif MAJOR_VERSION >= 4 && MAJOR_VERSION <= 6 typedef hidl_bitfield AudioDeviceBitfield; typedef hidl_bitfield AudioChannelBitfield; typedef hidl_bitfield AudioOutputFlagBitfield; diff --git a/audio/core/all-versions/default/include/core/default/Device.h b/audio/core/all-versions/default/include/core/default/Device.h index b0e72d9600..907acd7d7d 100644 --- a/audio/core/all-versions/default/include/core/default/Device.h +++ b/audio/core/all-versions/default/include/core/default/Device.h @@ -43,8 +43,10 @@ using ::android::hardware::hidl_string; using ::android::hardware::hidl_vec; using ::android::hardware::Return; using ::android::hardware::Void; +#if MAJOR_VERSION <= 6 using ::android::hardware::audio::common::CPP_VERSION::implementation::AudioInputFlagBitfield; using ::android::hardware::audio::common::CPP_VERSION::implementation::AudioOutputFlagBitfield; +#endif using namespace ::android::hardware::audio::common::CPP_VERSION; using namespace ::android::hardware::audio::CPP_VERSION; From 1074c22fe1c2b936d762a969e125e8f5c75f49e3 Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Tue, 11 Aug 2020 22:21:40 +0000 Subject: [PATCH 2/5] audio: Reformat README as Markdown Rename README -> README.md, reformat it as Markdown. Provide missing descriptions for some directories. Bug: 142480271 Test: N/A Change-Id: Ic6f60a21def4bf210a7e1446454d709f68a13422 Merged-In: Ic6f60a21def4bf210a7e1446454d709f68a13422 --- audio/README | 36 ------------------------------------ audio/README.md | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 36 deletions(-) delete mode 100644 audio/README create mode 100644 audio/README.md diff --git a/audio/README b/audio/README deleted file mode 100644 index afafbe32d2..0000000000 --- a/audio/README +++ /dev/null @@ -1,36 +0,0 @@ -Directory structure of the audio HIDL related code. - -Run `common/all-versions/copyHAL.sh` to create a new version of the audio HAL -based on an existing one. - -audio -|-- 2.0 <== core 2.0 HIDL API. .hal can not be moved into the core directory -| because that would change its namespace and include path -|-- 4.0 <== Version 4.0 of the core API -| -|-- ... -| -|-- common <== code common to audio core and effect API -| |-- 2.0 <== HIDL API of V2 -| |-- 4.0 -| |-- ... -| `-- all-versions <== code common to all version of both core and effect API -| |-- default <== implementation shared code between core and effect impl -| |-- test <== utilities used by tests -| `-- util <== utilities used by both implementation and tests -| -|-- core <== VTS and default implementation of the core API (not HIDL, see /audio/2.0)) -| `-- all-versions <== Code is version independent through #if and separate files -| |-- default <== code that wraps the legacy API -| `-- vts <== vts of core API -| |-- 2.0 <== 2.0 specific tests and helpers -| |-- 4.0 -| |-- ... -| -`-- effect <== idem for the effect API - |-- 2.0 - |-- 4.0 - |-- ... - `-- all-versions - |-- default - `-- vts diff --git a/audio/README.md b/audio/README.md new file mode 100644 index 0000000000..83ae6b26e8 --- /dev/null +++ b/audio/README.md @@ -0,0 +1,49 @@ +# Audio HAL + +Directory structure of the audio HAL related code. + +Run `common/all-versions/copyHAL.sh` to create a new version of the audio HAL +based on an existing one. + +## Directory Structure + +* `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 + configuration file. +* `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. + - ... + - `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 + (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, + version-specific parts are enclosed into conditional directives + of preprocessor or reside in dedicated files. + - `default` -- code that wraps the legacy API (from + `hardware/libhardware`). + - `vts` VTS tests for the core HIDL API. +* `effect` -- same for the effect HIDL API. + - `2.0` + - `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 + of audio HAL. + - `vts` -- VTS tests for validating actual configuration files. + - `xml` -- XSD schemas for CAP configuration files. From baf57fb1366bb5656801d7b77432b7a4934ea638 Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Tue, 11 Aug 2020 23:23:16 +0000 Subject: [PATCH 3/5] audio: Add example HAL implementation This is partial implementation of the example V7.0 audio HAL which passes VTS tests. Note that the 'core' part of the HAL (IDevice/IStream) isn't implemented yet. It passes VTS because it doesn't provide any devices (modules) and the audio HAL isn't the 'default' instance. Bug: 142480271 Test: atest VtsHalAudioV7_0TargetTest atest VtsHalAudioEffectV7_0TargetTest Change-Id: Ie3dd62c5db1cdb5534df4dd7f326c4c8776bf3c4 Merged-In: Ie3dd62c5db1cdb5534df4dd7f326c4c8776bf3c4 --- audio/README.md | 4 + audio/common/7.0/example/Android.bp | 45 ++++ audio/common/7.0/example/DevicesFactory.cpp | 39 +++ audio/common/7.0/example/DevicesFactory.h | 33 +++ audio/common/7.0/example/Effect.cpp | 224 ++++++++++++++++++ audio/common/7.0/example/Effect.h | 90 +++++++ audio/common/7.0/example/EffectsFactory.cpp | 75 ++++++ audio/common/7.0/example/EffectsFactory.h | 39 +++ audio/common/7.0/example/EqualizerEffect.cpp | 130 ++++++++++ audio/common/7.0/example/EqualizerEffect.h | 163 +++++++++++++ .../7.0/example/LoudnessEnhancerEffect.cpp | 55 +++++ .../7.0/example/LoudnessEnhancerEffect.h | 146 ++++++++++++ audio/common/7.0/example/PREUPLOAD.cfg | 2 + ...roid.hardware.audio@7.0-service.example.rc | 7 + ...oid.hardware.audio@7.0-service.example.xml | 20 ++ audio/common/7.0/example/service.cpp | 57 +++++ 16 files changed, 1129 insertions(+) create mode 100644 audio/common/7.0/example/Android.bp create mode 100644 audio/common/7.0/example/DevicesFactory.cpp create mode 100644 audio/common/7.0/example/DevicesFactory.h create mode 100644 audio/common/7.0/example/Effect.cpp create mode 100644 audio/common/7.0/example/Effect.h create mode 100644 audio/common/7.0/example/EffectsFactory.cpp create mode 100644 audio/common/7.0/example/EffectsFactory.h create mode 100644 audio/common/7.0/example/EqualizerEffect.cpp create mode 100644 audio/common/7.0/example/EqualizerEffect.h create mode 100644 audio/common/7.0/example/LoudnessEnhancerEffect.cpp create mode 100644 audio/common/7.0/example/LoudnessEnhancerEffect.h create mode 100644 audio/common/7.0/example/PREUPLOAD.cfg create mode 100644 audio/common/7.0/example/android.hardware.audio@7.0-service.example.rc create mode 100644 audio/common/7.0/example/android.hardware.audio@7.0-service.example.xml create mode 100644 audio/common/7.0/example/service.cpp diff --git a/audio/README.md b/audio/README.md index 83ae6b26e8..b77b9ba42d 100644 --- a/audio/README.md +++ b/audio/README.md @@ -18,6 +18,10 @@ based on an existing one. - `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 + 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 diff --git a/audio/common/7.0/example/Android.bp b/audio/common/7.0/example/Android.bp new file mode 100644 index 0000000000..03c1cd89cd --- /dev/null +++ b/audio/common/7.0/example/Android.bp @@ -0,0 +1,45 @@ +// +// Copyright (C) 2020 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +cc_binary { + name: "android.hardware.audio@7.0-service.example", + vendor: true, + relative_install_path: "hw", + init_rc: ["android.hardware.audio@7.0-service.example.rc"], + vintf_fragments: ["android.hardware.audio@7.0-service.example.xml"], + srcs: [ + "DevicesFactory.cpp", + "Effect.cpp", + "EffectsFactory.cpp", + "EqualizerEffect.cpp", + "LoudnessEnhancerEffect.cpp", + "service.cpp", + ], + cflags: [ + "-Wall", + "-Werror", + ], + shared_libs: [ + "libcutils", + "libhidlbase", + "liblog", + "libxml2", + "libutils", + "android.hardware.audio@7.0", + "android.hardware.audio.common@7.0", + "android.hardware.audio.common@7.0-enums", + "android.hardware.audio.effect@7.0", + ], +} diff --git a/audio/common/7.0/example/DevicesFactory.cpp b/audio/common/7.0/example/DevicesFactory.cpp new file mode 100644 index 0000000000..ddd5fef8f7 --- /dev/null +++ b/audio/common/7.0/example/DevicesFactory.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "DevicesFactory7.0" +#include + +#include "DevicesFactory.h" + +using ::android::hardware::hidl_string; +using ::android::hardware::Return; +using ::android::hardware::Void; + +namespace android::hardware::audio::V7_0::implementation { + +Return DevicesFactory::openDevice(const hidl_string& device, openDevice_cb _hidl_cb) { + (void)device; + _hidl_cb(Result::INVALID_ARGUMENTS, nullptr); + return Void(); +} + +Return DevicesFactory::openPrimaryDevice(openPrimaryDevice_cb _hidl_cb) { + _hidl_cb(Result::INVALID_ARGUMENTS, nullptr); + return Void(); +} + +} // namespace android::hardware::audio::V7_0::implementation diff --git a/audio/common/7.0/example/DevicesFactory.h b/audio/common/7.0/example/DevicesFactory.h new file mode 100644 index 0000000000..00f665c17e --- /dev/null +++ b/audio/common/7.0/example/DevicesFactory.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +namespace android::hardware::audio::V7_0::implementation { + +class DevicesFactory : public IDevicesFactory { + public: + DevicesFactory() = default; + + ::android::hardware::Return openDevice(const ::android::hardware::hidl_string& device, + openDevice_cb _hidl_cb) override; + + ::android::hardware::Return openPrimaryDevice(openPrimaryDevice_cb _hidl_cb) override; +}; + +} // namespace android::hardware::audio::V7_0::implementation diff --git a/audio/common/7.0/example/Effect.cpp b/audio/common/7.0/example/Effect.cpp new file mode 100644 index 0000000000..423754d593 --- /dev/null +++ b/audio/common/7.0/example/Effect.cpp @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "EffectsFactory7.0" +#include + +#include + +#include "Effect.h" + +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::Void; +using namespace ::android::hardware::audio::common::V7_0; +// Make an alias for enumerations generated from the APM config XSD. +namespace xsd { +using namespace ::audio::policy::configuration::V7_0; +} + +namespace android::hardware::audio::effect::V7_0::implementation { + +Return Effect::init() { + return Result::OK; +} + +Return Effect::setConfig( + const EffectConfig& config, + const ::android::sp& inputBufferProvider, + const ::android::sp& outputBufferProvider) { + (void)config; + (void)inputBufferProvider; + (void)outputBufferProvider; + return Result::OK; +} + +Return Effect::reset() { + return Result::OK; +} + +Return Effect::enable() { + if (!mEnabled) { + mEnabled = true; + return Result::OK; + } else { + return Result::NOT_SUPPORTED; + } +} + +Return Effect::disable() { + if (mEnabled) { + mEnabled = false; + return Result::OK; + } else { + return Result::NOT_SUPPORTED; + } +} + +Return Effect::setDevice(const DeviceAddress& device) { + (void)device; + return Result::OK; +} + +Return Effect::setAndGetVolume(const hidl_vec& volumes, + setAndGetVolume_cb _hidl_cb) { + (void)volumes; + _hidl_cb(Result::OK, hidl_vec{}); + return Void(); +} + +Return Effect::volumeChangeNotification(const hidl_vec& volumes) { + (void)volumes; + return Result::OK; +} + +Return Effect::setAudioMode(AudioMode mode) { + (void)mode; + return Result::OK; +} + +Return Effect::setConfigReverse( + const EffectConfig& config, + const ::android::sp& inputBufferProvider, + const ::android::sp& outputBufferProvider) { + (void)config; + (void)inputBufferProvider; + (void)outputBufferProvider; + return Result::OK; +} + +Return Effect::setInputDevice(const DeviceAddress& device) { + (void)device; + return Result::OK; +} + +Return Effect::getConfig(getConfig_cb _hidl_cb) { + const EffectConfig config = {{} /* inputCfg */, + // outputCfg + {{} /* buffer */, + 48000 /* samplingRateHz */, + toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO), + toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT), + EffectBufferAccess::ACCESS_ACCUMULATE, + 0 /* mask */}}; + _hidl_cb(Result::OK, config); + return Void(); +} + +Return Effect::getConfigReverse(getConfigReverse_cb _hidl_cb) { + _hidl_cb(Result::OK, EffectConfig{}); + return Void(); +} + +Return Effect::getSupportedAuxChannelsConfigs(uint32_t maxConfigs, + getSupportedAuxChannelsConfigs_cb _hidl_cb) { + (void)maxConfigs; + _hidl_cb(Result::OK, hidl_vec{}); + return Void(); +} + +Return Effect::getAuxChannelsConfig(getAuxChannelsConfig_cb _hidl_cb) { + _hidl_cb(Result::OK, EffectAuxChannelsConfig{}); + return Void(); +} + +Return Effect::setAuxChannelsConfig(const EffectAuxChannelsConfig& config) { + (void)config; + return Result::OK; +} + +Return Effect::setAudioSource(const hidl_string& source) { + (void)source; + return Result::OK; +} + +Return Effect::offload(const EffectOffloadParameter& param) { + (void)param; + return Result::OK; +} + +Return Effect::getDescriptor(getDescriptor_cb _hidl_cb) { + _hidl_cb(Result::OK, mDescriptor); + return Void(); +} + +Return Effect::prepareForProcessing(prepareForProcessing_cb _hidl_cb) { + _hidl_cb(Result::OK, MQDescriptor{}); + return Void(); +} + +Return Effect::setProcessBuffers(const AudioBuffer& inBuffer, + const AudioBuffer& outBuffer) { + (void)inBuffer; + (void)outBuffer; + return Result::OK; +} + +Return Effect::command(uint32_t commandId, const hidl_vec& data, + uint32_t resultMaxSize, command_cb _hidl_cb) { + (void)commandId; + (void)data; + (void)resultMaxSize; + _hidl_cb(-EINVAL, hidl_vec{}); + return Void(); +} + +Return Effect::setParameter(const hidl_vec& parameter, + const hidl_vec& value) { + (void)parameter; + (void)value; + return Result::OK; +} + +Return Effect::getParameter(const hidl_vec& parameter, uint32_t valueMaxSize, + getParameter_cb _hidl_cb) { + (void)parameter; + (void)valueMaxSize; + _hidl_cb(Result::OK, hidl_vec{}); + return Void(); +} + +Return Effect::getSupportedConfigsForFeature(uint32_t featureId, uint32_t maxConfigs, + uint32_t configSize, + getSupportedConfigsForFeature_cb _hidl_cb) { + (void)featureId; + (void)maxConfigs; + (void)configSize; + _hidl_cb(Result::OK, 0, hidl_vec{}); + return Void(); +} + +Return Effect::getCurrentConfigForFeature(uint32_t featureId, uint32_t configSize, + getCurrentConfigForFeature_cb _hidl_cb) { + (void)featureId; + (void)configSize; + _hidl_cb(Result::OK, hidl_vec{}); + return Void(); +} + +Return Effect::setCurrentConfigForFeature(uint32_t featureId, + const hidl_vec& configData) { + (void)featureId; + (void)configData; + return Result::OK; +} + +Return Effect::close() { + return Result::OK; +} + +} // namespace android::hardware::audio::effect::V7_0::implementation diff --git a/audio/common/7.0/example/Effect.h b/audio/common/7.0/example/Effect.h new file mode 100644 index 0000000000..fa7f41bda6 --- /dev/null +++ b/audio/common/7.0/example/Effect.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +namespace android::hardware::audio::effect::V7_0::implementation { + +class Effect : public IEffect { + public: + explicit Effect(const EffectDescriptor& descriptor) : mDescriptor(descriptor) {} + + ::android::hardware::Return init() override; + ::android::hardware::Return setConfig( + const EffectConfig& config, + const ::android::sp& inputBufferProvider, + const ::android::sp& outputBufferProvider) override; + ::android::hardware::Return reset() override; + ::android::hardware::Return enable() override; + ::android::hardware::Return disable() override; + ::android::hardware::Return setDevice( + const ::android::hardware::audio::common::V7_0::DeviceAddress& device) override; + ::android::hardware::Return setAndGetVolume( + const ::android::hardware::hidl_vec& volumes, + setAndGetVolume_cb _hidl_cb) override; + ::android::hardware::Return volumeChangeNotification( + const ::android::hardware::hidl_vec& volumes) override; + ::android::hardware::Return setAudioMode( + ::android::hardware::audio::common::V7_0::AudioMode mode) override; + ::android::hardware::Return setConfigReverse( + const EffectConfig& config, + const ::android::sp& inputBufferProvider, + const ::android::sp& outputBufferProvider) override; + ::android::hardware::Return setInputDevice( + const ::android::hardware::audio::common::V7_0::DeviceAddress& device) override; + ::android::hardware::Return getConfig(getConfig_cb _hidl_cb) override; + ::android::hardware::Return getConfigReverse(getConfigReverse_cb _hidl_cb) override; + ::android::hardware::Return getSupportedAuxChannelsConfigs( + uint32_t maxConfigs, getSupportedAuxChannelsConfigs_cb _hidl_cb) override; + ::android::hardware::Return getAuxChannelsConfig( + getAuxChannelsConfig_cb _hidl_cb) override; + ::android::hardware::Return setAuxChannelsConfig( + const EffectAuxChannelsConfig& config) override; + ::android::hardware::Return setAudioSource( + const ::android::hardware::hidl_string& source) override; + ::android::hardware::Return offload(const EffectOffloadParameter& param) override; + ::android::hardware::Return getDescriptor(getDescriptor_cb _hidl_cb) override; + ::android::hardware::Return prepareForProcessing( + prepareForProcessing_cb _hidl_cb) override; + ::android::hardware::Return setProcessBuffers(const AudioBuffer& inBuffer, + const AudioBuffer& outBuffer) override; + ::android::hardware::Return command(uint32_t commandId, + const ::android::hardware::hidl_vec& data, + uint32_t resultMaxSize, command_cb _hidl_cb) override; + ::android::hardware::Return setParameter( + const ::android::hardware::hidl_vec& parameter, + const ::android::hardware::hidl_vec& value) override; + ::android::hardware::Return getParameter( + const ::android::hardware::hidl_vec& parameter, uint32_t valueMaxSize, + getParameter_cb _hidl_cb) override; + ::android::hardware::Return getSupportedConfigsForFeature( + uint32_t featureId, uint32_t maxConfigs, uint32_t configSize, + getSupportedConfigsForFeature_cb _hidl_cb) override; + ::android::hardware::Return getCurrentConfigForFeature( + uint32_t featureId, uint32_t configSize, + getCurrentConfigForFeature_cb _hidl_cb) override; + ::android::hardware::Return setCurrentConfigForFeature( + uint32_t featureId, const ::android::hardware::hidl_vec& configData) override; + ::android::hardware::Return close() override; + + private: + const EffectDescriptor mDescriptor; + bool mEnabled = false; +}; + +} // namespace android::hardware::audio::effect::V7_0::implementation diff --git a/audio/common/7.0/example/EffectsFactory.cpp b/audio/common/7.0/example/EffectsFactory.cpp new file mode 100644 index 0000000000..7d333ae040 --- /dev/null +++ b/audio/common/7.0/example/EffectsFactory.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "EffectsFactory7.0" +#include + +#include "EffectsFactory.h" +#include "EqualizerEffect.h" +#include "LoudnessEnhancerEffect.h" + +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::Void; +using namespace ::android::hardware::audio::common::V7_0; + +namespace android::hardware::audio::effect::V7_0::implementation { + +Return EffectsFactory::getAllDescriptors(getAllDescriptors_cb _hidl_cb) { + hidl_vec descriptors; + descriptors.resize(2); + descriptors[0] = EqualizerEffect::getDescriptor(); + descriptors[1] = LoudnessEnhancerEffect::getDescriptor(); + _hidl_cb(Result::OK, descriptors); + return Void(); +} + +Return EffectsFactory::getDescriptor(const Uuid& uuid, getDescriptor_cb _hidl_cb) { + if (auto desc = EqualizerEffect::getDescriptor(); uuid == desc.type || uuid == desc.uuid) { + _hidl_cb(Result::OK, desc); + } else if (auto desc = LoudnessEnhancerEffect::getDescriptor(); + uuid == desc.type || uuid == desc.uuid) { + _hidl_cb(Result::OK, desc); + } else { + _hidl_cb(Result::INVALID_ARGUMENTS, EffectDescriptor{}); + } + return Void(); +} + +Return EffectsFactory::createEffect(const Uuid& uuid, int32_t session, int32_t ioHandle, + int32_t device, createEffect_cb _hidl_cb) { + (void)session; + (void)ioHandle; + (void)device; + if (auto desc = EqualizerEffect::getDescriptor(); uuid == desc.type || uuid == desc.uuid) { + _hidl_cb(Result::OK, new EqualizerEffect(), 0); + } else if (auto desc = LoudnessEnhancerEffect::getDescriptor(); + uuid == desc.type || uuid == desc.uuid) { + _hidl_cb(Result::OK, new LoudnessEnhancerEffect(), 0); + } else { + _hidl_cb(Result::INVALID_ARGUMENTS, nullptr, 0); + } + return Void(); +} + +Return EffectsFactory::debug(const hidl_handle& fd, const hidl_vec& options) { + (void)fd; + (void)options; + return Void(); +} + +} // namespace android::hardware::audio::effect::V7_0::implementation diff --git a/audio/common/7.0/example/EffectsFactory.h b/audio/common/7.0/example/EffectsFactory.h new file mode 100644 index 0000000000..8fec70cb35 --- /dev/null +++ b/audio/common/7.0/example/EffectsFactory.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +namespace android::hardware::audio::effect::V7_0::implementation { + +class EffectsFactory : public IEffectsFactory { + public: + EffectsFactory() = default; + + ::android::hardware::Return getAllDescriptors(getAllDescriptors_cb _hidl_cb) override; + ::android::hardware::Return getDescriptor( + const ::android::hardware::audio::common::V7_0::Uuid& uuid, + getDescriptor_cb _hidl_cb) override; + ::android::hardware::Return createEffect( + const ::android::hardware::audio::common::V7_0::Uuid& uuid, int32_t session, + int32_t ioHandle, int32_t device, createEffect_cb _hidl_cb) override; + ::android::hardware::Return + debug(const ::android::hardware::hidl_handle& fd, + const ::android::hardware::hidl_vec<::android::hardware::hidl_string>& options) override; +}; + +} // namespace android::hardware::audio::effect::V7_0::implementation diff --git a/audio/common/7.0/example/EqualizerEffect.cpp b/audio/common/7.0/example/EqualizerEffect.cpp new file mode 100644 index 0000000000..c93c5a90fb --- /dev/null +++ b/audio/common/7.0/example/EqualizerEffect.cpp @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#define LOG_TAG "EffectsFactory7.0" +#include + +#include "EqualizerEffect.h" + +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::Void; +using namespace ::android::hardware::audio::common::V7_0; + +namespace android::hardware::audio::effect::V7_0::implementation { + +const EffectDescriptor& EqualizerEffect::getDescriptor() { + // Note: for VTS tests only 'type' and 'uuid' fields are required. + // The actual implementation must provide meaningful values + // for all fields of the descriptor. + static const EffectDescriptor descriptor = { + .type = + {// Same UUID as AudioEffect.EFFECT_TYPE_EQUALIZER in Java. + 0x0bed4300, 0xddd6, 0x11db, 0x8f34, + std::array{{0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}}, + .uuid = {0, 0, 0, 1, std::array{{0, 0, 0, 0, 0, 0}}}}; + return descriptor; +} + +EqualizerEffect::EqualizerEffect() : mEffect(new Effect(getDescriptor())) { + mProperties.bandLevels.resize(kNumBands); +} + +Return EqualizerEffect::getNumBands(getNumBands_cb _hidl_cb) { + _hidl_cb(Result::OK, kNumBands); + return Void(); +} + +Return EqualizerEffect::getLevelRange(getLevelRange_cb _hidl_cb) { + _hidl_cb(Result::OK, std::numeric_limits::min(), std::numeric_limits::max()); + return Void(); +} + +Return EqualizerEffect::setBandLevel(uint16_t band, int16_t level) { + if (band < kNumBands) { + mProperties.bandLevels[band] = level; + return Result::OK; + } else { + return Result::INVALID_ARGUMENTS; + } +} + +Return EqualizerEffect::getBandLevel(uint16_t band, getBandLevel_cb _hidl_cb) { + if (band < kNumBands) { + _hidl_cb(Result::OK, mProperties.bandLevels[band]); + } else { + _hidl_cb(Result::INVALID_ARGUMENTS, 0); + } + return Void(); +} + +Return EqualizerEffect::getBandCenterFrequency(uint16_t band, + getBandCenterFrequency_cb _hidl_cb) { + (void)band; + _hidl_cb(Result::OK, 0); + return Void(); +} + +Return EqualizerEffect::getBandFrequencyRange(uint16_t band, + getBandFrequencyRange_cb _hidl_cb) { + (void)band; + _hidl_cb(Result::OK, 0, 1); + return Void(); +} + +Return EqualizerEffect::getBandForFrequency(uint32_t freq, getBandForFrequency_cb _hidl_cb) { + (void)freq; + _hidl_cb(Result::OK, 0); + return Void(); +} + +Return EqualizerEffect::getPresetNames(getPresetNames_cb _hidl_cb) { + hidl_vec presetNames; + presetNames.resize(kNumPresets); + presetNames[0] = "default"; + _hidl_cb(Result::OK, presetNames); + return Void(); +} + +Return EqualizerEffect::setCurrentPreset(uint16_t preset) { + if (preset < kNumPresets) { + mProperties.curPreset = preset; + return Result::OK; + } else { + return Result::INVALID_ARGUMENTS; + } +} + +Return EqualizerEffect::getCurrentPreset(getCurrentPreset_cb _hidl_cb) { + _hidl_cb(Result::OK, mProperties.curPreset); + return Void(); +} + +Return EqualizerEffect::setAllProperties( + const IEqualizerEffect::AllProperties& properties) { + mProperties = properties; + return Result::OK; +} + +Return EqualizerEffect::getAllProperties(getAllProperties_cb _hidl_cb) { + _hidl_cb(Result::OK, mProperties); + return Void(); +} + +} // namespace android::hardware::audio::effect::V7_0::implementation diff --git a/audio/common/7.0/example/EqualizerEffect.h b/audio/common/7.0/example/EqualizerEffect.h new file mode 100644 index 0000000000..11853c3392 --- /dev/null +++ b/audio/common/7.0/example/EqualizerEffect.h @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include "Effect.h" + +namespace android::hardware::audio::effect::V7_0::implementation { + +class EqualizerEffect : public IEqualizerEffect { + public: + static const EffectDescriptor& getDescriptor(); + + EqualizerEffect(); + + // Methods from IEffect interface. + ::android::hardware::Return init() override { return mEffect->init(); } + ::android::hardware::Return setConfig( + const EffectConfig& config, + const ::android::sp& inputBufferProvider, + const ::android::sp& outputBufferProvider) override { + return mEffect->setConfig(config, inputBufferProvider, outputBufferProvider); + } + ::android::hardware::Return reset() override { return mEffect->reset(); } + ::android::hardware::Return enable() override { return mEffect->enable(); } + ::android::hardware::Return disable() override { return mEffect->disable(); } + ::android::hardware::Return setDevice( + const ::android::hardware::audio::common::V7_0::DeviceAddress& device) override { + return mEffect->setDevice(device); + } + ::android::hardware::Return setAndGetVolume( + const ::android::hardware::hidl_vec& volumes, + setAndGetVolume_cb _hidl_cb) override { + return mEffect->setAndGetVolume(volumes, _hidl_cb); + } + ::android::hardware::Return volumeChangeNotification( + const ::android::hardware::hidl_vec& volumes) override { + return mEffect->volumeChangeNotification(volumes); + } + ::android::hardware::Return setAudioMode( + ::android::hardware::audio::common::V7_0::AudioMode mode) override { + return mEffect->setAudioMode(mode); + } + ::android::hardware::Return setConfigReverse( + const EffectConfig& config, + const ::android::sp& inputBufferProvider, + const ::android::sp& outputBufferProvider) override { + return mEffect->setConfigReverse(config, inputBufferProvider, outputBufferProvider); + } + ::android::hardware::Return setInputDevice( + const ::android::hardware::audio::common::V7_0::DeviceAddress& device) override { + return mEffect->setInputDevice(device); + } + ::android::hardware::Return getConfig(getConfig_cb _hidl_cb) override { + return mEffect->getConfig(_hidl_cb); + } + ::android::hardware::Return getConfigReverse(getConfigReverse_cb _hidl_cb) override { + return mEffect->getConfigReverse(_hidl_cb); + } + ::android::hardware::Return getSupportedAuxChannelsConfigs( + uint32_t maxConfigs, getSupportedAuxChannelsConfigs_cb _hidl_cb) override { + return mEffect->getSupportedAuxChannelsConfigs(maxConfigs, _hidl_cb); + } + ::android::hardware::Return getAuxChannelsConfig( + getAuxChannelsConfig_cb _hidl_cb) override { + return mEffect->getAuxChannelsConfig(_hidl_cb); + } + ::android::hardware::Return setAuxChannelsConfig( + const EffectAuxChannelsConfig& config) override { + return mEffect->setAuxChannelsConfig(config); + } + ::android::hardware::Return setAudioSource( + const ::android::hardware::hidl_string& source) override { + return mEffect->setAudioSource(source); + } + ::android::hardware::Return offload(const EffectOffloadParameter& param) override { + return mEffect->offload(param); + } + ::android::hardware::Return getDescriptor(getDescriptor_cb _hidl_cb) override { + return mEffect->getDescriptor(_hidl_cb); + } + ::android::hardware::Return prepareForProcessing( + prepareForProcessing_cb _hidl_cb) override { + return mEffect->prepareForProcessing(_hidl_cb); + } + ::android::hardware::Return setProcessBuffers(const AudioBuffer& inBuffer, + const AudioBuffer& outBuffer) override { + return mEffect->setProcessBuffers(inBuffer, outBuffer); + } + ::android::hardware::Return command(uint32_t commandId, + const ::android::hardware::hidl_vec& data, + uint32_t resultMaxSize, + command_cb _hidl_cb) override { + return mEffect->command(commandId, data, resultMaxSize, _hidl_cb); + } + ::android::hardware::Return setParameter( + const ::android::hardware::hidl_vec& parameter, + const ::android::hardware::hidl_vec& value) override { + return mEffect->setParameter(parameter, value); + } + ::android::hardware::Return getParameter( + const ::android::hardware::hidl_vec& parameter, uint32_t valueMaxSize, + getParameter_cb _hidl_cb) override { + return mEffect->getParameter(parameter, valueMaxSize, _hidl_cb); + } + ::android::hardware::Return getSupportedConfigsForFeature( + uint32_t featureId, uint32_t maxConfigs, uint32_t configSize, + getSupportedConfigsForFeature_cb _hidl_cb) override { + return mEffect->getSupportedConfigsForFeature(featureId, maxConfigs, configSize, _hidl_cb); + } + ::android::hardware::Return getCurrentConfigForFeature( + uint32_t featureId, uint32_t configSize, + getCurrentConfigForFeature_cb _hidl_cb) override { + return mEffect->getCurrentConfigForFeature(featureId, configSize, _hidl_cb); + } + ::android::hardware::Return setCurrentConfigForFeature( + uint32_t featureId, const ::android::hardware::hidl_vec& configData) override { + return mEffect->setCurrentConfigForFeature(featureId, configData); + } + ::android::hardware::Return close() override { return mEffect->close(); } + + // Methods from IEqualizerEffect interface. + ::android::hardware::Return getNumBands(getNumBands_cb _hidl_cb) override; + ::android::hardware::Return getLevelRange(getLevelRange_cb _hidl_cb) override; + ::android::hardware::Return setBandLevel(uint16_t band, int16_t level) override; + ::android::hardware::Return getBandLevel(uint16_t band, + getBandLevel_cb _hidl_cb) override; + ::android::hardware::Return getBandCenterFrequency( + uint16_t band, getBandCenterFrequency_cb _hidl_cb) override; + ::android::hardware::Return getBandFrequencyRange( + uint16_t band, getBandFrequencyRange_cb _hidl_cb) override; + ::android::hardware::Return getBandForFrequency(uint32_t freq, + getBandForFrequency_cb _hidl_cb) override; + ::android::hardware::Return getPresetNames(getPresetNames_cb _hidl_cb) override; + ::android::hardware::Return setCurrentPreset(uint16_t preset) override; + ::android::hardware::Return getCurrentPreset(getCurrentPreset_cb _hidl_cb) override; + ::android::hardware::Return setAllProperties( + const IEqualizerEffect::AllProperties& properties) override; + ::android::hardware::Return getAllProperties(getAllProperties_cb _hidl_cb) override; + + private: + static constexpr size_t kNumBands = 1; + static constexpr size_t kNumPresets = 1; + sp mEffect; + IEqualizerEffect::AllProperties mProperties{}; +}; + +} // namespace android::hardware::audio::effect::V7_0::implementation diff --git a/audio/common/7.0/example/LoudnessEnhancerEffect.cpp b/audio/common/7.0/example/LoudnessEnhancerEffect.cpp new file mode 100644 index 0000000000..38269b3308 --- /dev/null +++ b/audio/common/7.0/example/LoudnessEnhancerEffect.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "EffectsFactory7.0" +#include + +#include "LoudnessEnhancerEffect.h" + +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::Void; +using namespace ::android::hardware::audio::common::V7_0; + +namespace android::hardware::audio::effect::V7_0::implementation { + +const EffectDescriptor& LoudnessEnhancerEffect::getDescriptor() { + // Note: for VTS tests only 'type' and 'uuid' fields are required. + // The actual implementation must provide meaningful values + // for all fields of the descriptor. + static const EffectDescriptor descriptor = { + .type = + {// Same UUID as AudioEffect.EFFECT_TYPE_LOUDNESS_ENHANCER in Java. + 0xfe3199be, 0xaed0, 0x413f, 0x87bb, + std::array{{0x11, 0x26, 0x0e, 0xb6, 0x3c, 0xf1}}}, + .uuid = {0, 0, 0, 2, std::array{{0, 0, 0, 0, 0, 0}}}}; + return descriptor; +} // namespace android::hardware::audio::effect::V7_0::implementation + +LoudnessEnhancerEffect::LoudnessEnhancerEffect() : mEffect(new Effect(getDescriptor())) {} + +Return LoudnessEnhancerEffect::setTargetGain(int32_t targetGainMb) { + mTargetGainMb = targetGainMb; + return Result::OK; +} + +Return LoudnessEnhancerEffect::getTargetGain(getTargetGain_cb _hidl_cb) { + _hidl_cb(Result::OK, mTargetGainMb); + return Void(); +} + +} // namespace android::hardware::audio::effect::V7_0::implementation diff --git a/audio/common/7.0/example/LoudnessEnhancerEffect.h b/audio/common/7.0/example/LoudnessEnhancerEffect.h new file mode 100644 index 0000000000..1af0d9f852 --- /dev/null +++ b/audio/common/7.0/example/LoudnessEnhancerEffect.h @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include "Effect.h" + +namespace android::hardware::audio::effect::V7_0::implementation { + +class LoudnessEnhancerEffect : public ILoudnessEnhancerEffect { + public: + static const EffectDescriptor& getDescriptor(); + + LoudnessEnhancerEffect(); + + // Methods from IEffect interface. + ::android::hardware::Return init() override { return mEffect->init(); } + ::android::hardware::Return setConfig( + const EffectConfig& config, + const ::android::sp& inputBufferProvider, + const ::android::sp& outputBufferProvider) override { + return mEffect->setConfig(config, inputBufferProvider, outputBufferProvider); + } + ::android::hardware::Return reset() override { return mEffect->reset(); } + ::android::hardware::Return enable() override { return mEffect->enable(); } + ::android::hardware::Return disable() override { return mEffect->disable(); } + ::android::hardware::Return setDevice( + const ::android::hardware::audio::common::V7_0::DeviceAddress& device) override { + return mEffect->setDevice(device); + } + ::android::hardware::Return setAndGetVolume( + const ::android::hardware::hidl_vec& volumes, + setAndGetVolume_cb _hidl_cb) override { + return mEffect->setAndGetVolume(volumes, _hidl_cb); + } + ::android::hardware::Return volumeChangeNotification( + const ::android::hardware::hidl_vec& volumes) override { + return mEffect->volumeChangeNotification(volumes); + } + ::android::hardware::Return setAudioMode( + ::android::hardware::audio::common::V7_0::AudioMode mode) override { + return mEffect->setAudioMode(mode); + } + ::android::hardware::Return setConfigReverse( + const EffectConfig& config, + const ::android::sp& inputBufferProvider, + const ::android::sp& outputBufferProvider) override { + return mEffect->setConfigReverse(config, inputBufferProvider, outputBufferProvider); + } + ::android::hardware::Return setInputDevice( + const ::android::hardware::audio::common::V7_0::DeviceAddress& device) override { + return mEffect->setInputDevice(device); + } + ::android::hardware::Return getConfig(getConfig_cb _hidl_cb) override { + return mEffect->getConfig(_hidl_cb); + } + ::android::hardware::Return getConfigReverse(getConfigReverse_cb _hidl_cb) override { + return mEffect->getConfigReverse(_hidl_cb); + } + ::android::hardware::Return getSupportedAuxChannelsConfigs( + uint32_t maxConfigs, getSupportedAuxChannelsConfigs_cb _hidl_cb) override { + return mEffect->getSupportedAuxChannelsConfigs(maxConfigs, _hidl_cb); + } + ::android::hardware::Return getAuxChannelsConfig( + getAuxChannelsConfig_cb _hidl_cb) override { + return mEffect->getAuxChannelsConfig(_hidl_cb); + } + ::android::hardware::Return setAuxChannelsConfig( + const EffectAuxChannelsConfig& config) override { + return mEffect->setAuxChannelsConfig(config); + } + ::android::hardware::Return setAudioSource( + const ::android::hardware::hidl_string& source) override { + return mEffect->setAudioSource(source); + } + ::android::hardware::Return offload(const EffectOffloadParameter& param) override { + return mEffect->offload(param); + } + ::android::hardware::Return getDescriptor(getDescriptor_cb _hidl_cb) override { + return mEffect->getDescriptor(_hidl_cb); + } + ::android::hardware::Return prepareForProcessing( + prepareForProcessing_cb _hidl_cb) override { + return mEffect->prepareForProcessing(_hidl_cb); + } + ::android::hardware::Return setProcessBuffers(const AudioBuffer& inBuffer, + const AudioBuffer& outBuffer) override { + return mEffect->setProcessBuffers(inBuffer, outBuffer); + } + ::android::hardware::Return command(uint32_t commandId, + const ::android::hardware::hidl_vec& data, + uint32_t resultMaxSize, + command_cb _hidl_cb) override { + return mEffect->command(commandId, data, resultMaxSize, _hidl_cb); + } + ::android::hardware::Return setParameter( + const ::android::hardware::hidl_vec& parameter, + const ::android::hardware::hidl_vec& value) override { + return mEffect->setParameter(parameter, value); + } + ::android::hardware::Return getParameter( + const ::android::hardware::hidl_vec& parameter, uint32_t valueMaxSize, + getParameter_cb _hidl_cb) override { + return mEffect->getParameter(parameter, valueMaxSize, _hidl_cb); + } + ::android::hardware::Return getSupportedConfigsForFeature( + uint32_t featureId, uint32_t maxConfigs, uint32_t configSize, + getSupportedConfigsForFeature_cb _hidl_cb) override { + return mEffect->getSupportedConfigsForFeature(featureId, maxConfigs, configSize, _hidl_cb); + } + ::android::hardware::Return getCurrentConfigForFeature( + uint32_t featureId, uint32_t configSize, + getCurrentConfigForFeature_cb _hidl_cb) override { + return mEffect->getCurrentConfigForFeature(featureId, configSize, _hidl_cb); + } + ::android::hardware::Return setCurrentConfigForFeature( + uint32_t featureId, const ::android::hardware::hidl_vec& configData) override { + return mEffect->setCurrentConfigForFeature(featureId, configData); + } + ::android::hardware::Return close() override { return mEffect->close(); } + + // Methods from ILoudnessEnhancerEffect interface. + ::android::hardware::Return setTargetGain(int32_t targetGainMb) override; + ::android::hardware::Return getTargetGain(getTargetGain_cb _hidl_cb) override; + + private: + sp mEffect; + int32_t mTargetGainMb = 0; +}; + +} // namespace android::hardware::audio::effect::V7_0::implementation diff --git a/audio/common/7.0/example/PREUPLOAD.cfg b/audio/common/7.0/example/PREUPLOAD.cfg new file mode 100644 index 0000000000..6b7fd7137c --- /dev/null +++ b/audio/common/7.0/example/PREUPLOAD.cfg @@ -0,0 +1,2 @@ +[Builtin Hooks] +clang_format = true diff --git a/audio/common/7.0/example/android.hardware.audio@7.0-service.example.rc b/audio/common/7.0/example/android.hardware.audio@7.0-service.example.rc new file mode 100644 index 0000000000..cf8b51f07b --- /dev/null +++ b/audio/common/7.0/example/android.hardware.audio@7.0-service.example.rc @@ -0,0 +1,7 @@ +service vendor.audio-hal-7-0 /vendor/bin/hw/android.hardware.audio@7.0-service.example + class hal + user audioserver + group audio + capabilities BLOCK_SUSPEND + ioprio rt 4 + task_profiles ProcessCapacityHigh HighPerformance diff --git a/audio/common/7.0/example/android.hardware.audio@7.0-service.example.xml b/audio/common/7.0/example/android.hardware.audio@7.0-service.example.xml new file mode 100644 index 0000000000..b91b0612ce --- /dev/null +++ b/audio/common/7.0/example/android.hardware.audio@7.0-service.example.xml @@ -0,0 +1,20 @@ + + + android.hardware.audio + hwbinder + 7.0 + + IDevicesFactory + example + + + + android.hardware.audio.effect + hwbinder + 7.0 + + IEffectsFactory + example + + + diff --git a/audio/common/7.0/example/service.cpp b/audio/common/7.0/example/service.cpp new file mode 100644 index 0000000000..641e2c90ae --- /dev/null +++ b/audio/common/7.0/example/service.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "android.hardware.audio@7.0-service.example" +#include +#include + +#include "DevicesFactory.h" +#include "EffectsFactory.h" + +using android::hardware::configureRpcThreadpool; +using android::hardware::joinRpcThreadpool; +using namespace android; + +status_t registerDevicesFactoryService() { + sp<::android::hardware::audio::V7_0::IDevicesFactory> devicesFactory = + new ::android::hardware::audio::V7_0::implementation::DevicesFactory(); + status_t status = devicesFactory->registerAsService("example"); + ALOGE_IF(status != OK, "Error registering devices factory as service: %d", status); + return status; +} + +status_t registerEffectsFactoryService() { + sp<::android::hardware::audio::effect::V7_0::IEffectsFactory> devicesFactory = + new ::android::hardware::audio::effect::V7_0::implementation::EffectsFactory(); + status_t status = devicesFactory->registerAsService("example"); + ALOGE_IF(status != OK, "Error registering effects factory as service: %d", status); + return status; +} + +int main() { + configureRpcThreadpool(1, true); + status_t status = registerDevicesFactoryService(); + if (status != OK) { + return status; + } + status = registerEffectsFactoryService(); + if (status != OK) { + return status; + } + joinRpcThreadpool(); + + return 1; +} From d72a7c27ab130415a92ee15009990c7fc1740615 Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Fri, 14 Aug 2020 00:16:09 +0000 Subject: [PATCH 4/5] audio: Implement VTS tests for V7.0 The major change in V7.0 is use of enum values defined in the Audio Policy Configuration XSD schema. This allows decoupling types used at the HIDL layer from system/audio.h. Added a header audio_policy_configuration_V7_0-enums.h with utility functions analogous to ones from system/audio.h but defined for the types generated from XSD schema. Since the code of VTS tests is shared between versions, ensured that the VTS tests for the previous HAL versions didn't regress. Bug: 142480271 Test: atest VtsHalAudioV6_0TargetTest atest VtsHalAudioEffectV6_0TargetTest atest VtsHalAudioV7_0TargetTest atest VtsHalAudioEffectV7_0TargetTest Change-Id: Ia7c2d49a02783725080c8fed6a25853e91bba487 Merged-In: Ia7c2d49a02783725080c8fed6a25853e91bba487 --- audio/common/7.0/Android.bp | 5 +- .../audio_policy_configuration_V7_0-enums.h | 207 ++++++++++++ .../4.0/AudioPrimaryHidlHalTest.cpp | 100 +++++- .../functional/4.0/AudioPrimaryHidlHalUtils.h | 4 +- .../6.0/AudioPrimaryHidlHalTest.cpp | 45 ++- .../7.0/AudioPrimaryHidlHalTest.cpp | 98 ++++++ .../vts/functional/7.0/PolicyConfig.h | 91 ++++++ .../all-versions/vts/functional/Android.bp | 17 +- .../vts/functional/AudioPrimaryHidlHalTest.h | 300 ++++++++++-------- .../vts/functional/ConfigHelper.h | 26 +- .../vts/functional/DeviceManager.h | 9 +- .../vts/functional/PolicyConfig.h | 96 ++++++ .../all-versions/vts/functional/Android.bp | 2 +- .../VtsHalAudioEffectTargetTest.cpp | 41 ++- 14 files changed, 856 insertions(+), 185 deletions(-) create mode 100644 audio/common/7.0/enums/include/audio_policy_configuration_V7_0-enums.h create mode 100644 audio/core/all-versions/vts/functional/7.0/PolicyConfig.h create mode 100644 audio/core/all-versions/vts/functional/PolicyConfig.h diff --git a/audio/common/7.0/Android.bp b/audio/common/7.0/Android.bp index e24871c8b5..1c016b401b 100644 --- a/audio/common/7.0/Android.bp +++ b/audio/common/7.0/Android.bp @@ -16,9 +16,12 @@ hidl_interface { cc_library { name: "android.hardware.audio.common@7.0-enums", vendor_available: true, - generated_sources: ["audio_policy_configuration_V7_0"], generated_headers: ["audio_policy_configuration_V7_0"], + generated_sources: ["audio_policy_configuration_V7_0"], header_libs: ["libxsdc-utils"], + export_generated_headers: ["audio_policy_configuration_V7_0"], + export_header_lib_headers: ["libxsdc-utils"], + export_include_dirs: ["enums/include"], shared_libs: [ "libbase", "liblog", diff --git a/audio/common/7.0/enums/include/audio_policy_configuration_V7_0-enums.h b/audio/common/7.0/enums/include/audio_policy_configuration_V7_0-enums.h new file mode 100644 index 0000000000..d5fedce100 --- /dev/null +++ b/audio/common/7.0/enums/include/audio_policy_configuration_V7_0-enums.h @@ -0,0 +1,207 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AUDIO_POLICY_CONFIGURATION_V7_0_ENUMS_H +#define AUDIO_POLICY_CONFIGURATION_V7_0_ENUMS_H + +#include + +#include + +namespace audio::policy::configuration::V7_0 { + +static inline size_t getChannelCount(AudioChannelMask mask) { + switch (mask) { + case AudioChannelMask::AUDIO_CHANNEL_OUT_MONO: + case AudioChannelMask::AUDIO_CHANNEL_IN_MONO: + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_1: + return 1; + case AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO: + case AudioChannelMask::AUDIO_CHANNEL_OUT_MONO_HAPTIC_A: + case AudioChannelMask::AUDIO_CHANNEL_OUT_HAPTIC_AB: + case AudioChannelMask::AUDIO_CHANNEL_IN_STEREO: + case AudioChannelMask::AUDIO_CHANNEL_IN_FRONT_BACK: + case AudioChannelMask::AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO: + case AudioChannelMask::AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO: + case AudioChannelMask::AUDIO_CHANNEL_IN_VOICE_CALL_MONO: + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_2: + return 2; + case AudioChannelMask::AUDIO_CHANNEL_OUT_2POINT1: + case AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO_HAPTIC_A: + case AudioChannelMask::AUDIO_CHANNEL_OUT_MONO_HAPTIC_AB: + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_3: + return 3; + case AudioChannelMask::AUDIO_CHANNEL_OUT_2POINT0POINT2: + case AudioChannelMask::AUDIO_CHANNEL_OUT_QUAD: + case AudioChannelMask::AUDIO_CHANNEL_OUT_QUAD_BACK: + case AudioChannelMask::AUDIO_CHANNEL_OUT_QUAD_SIDE: + case AudioChannelMask::AUDIO_CHANNEL_OUT_SURROUND: + case AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO_HAPTIC_AB: + case AudioChannelMask::AUDIO_CHANNEL_IN_2POINT0POINT2: + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_4: + return 4; + case AudioChannelMask::AUDIO_CHANNEL_OUT_2POINT1POINT2: + case AudioChannelMask::AUDIO_CHANNEL_OUT_3POINT0POINT2: + case AudioChannelMask::AUDIO_CHANNEL_OUT_PENTA: + case AudioChannelMask::AUDIO_CHANNEL_IN_2POINT1POINT2: + case AudioChannelMask::AUDIO_CHANNEL_IN_3POINT0POINT2: + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_5: + return 5; + case AudioChannelMask::AUDIO_CHANNEL_OUT_3POINT1POINT2: + case AudioChannelMask::AUDIO_CHANNEL_OUT_5POINT1: + case AudioChannelMask::AUDIO_CHANNEL_OUT_5POINT1_BACK: + case AudioChannelMask::AUDIO_CHANNEL_OUT_5POINT1_SIDE: + case AudioChannelMask::AUDIO_CHANNEL_IN_6: + case AudioChannelMask::AUDIO_CHANNEL_IN_3POINT1POINT2: + case AudioChannelMask::AUDIO_CHANNEL_IN_5POINT1: + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_6: + return 6; + case AudioChannelMask::AUDIO_CHANNEL_OUT_6POINT1: + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_7: + return 7; + case AudioChannelMask::AUDIO_CHANNEL_OUT_5POINT1POINT2: + case AudioChannelMask::AUDIO_CHANNEL_OUT_7POINT1: + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_8: + return 8; + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_9: + return 9; + case AudioChannelMask::AUDIO_CHANNEL_OUT_5POINT1POINT4: + case AudioChannelMask::AUDIO_CHANNEL_OUT_7POINT1POINT2: + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_10: + return 10; + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_11: + return 11; + case AudioChannelMask::AUDIO_CHANNEL_OUT_7POINT1POINT4: + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_12: + return 12; + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_13: + return 13; + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_14: + return 14; + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_15: + return 15; + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_16: + return 16; + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_17: + return 17; + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_18: + return 18; + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_19: + return 19; + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_20: + return 20; + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_21: + return 21; + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_22: + return 22; + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_23: + return 23; + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_24: + return 24; + case AudioChannelMask::UNKNOWN: + return 0; + // No default to make sure all cases are covered. + } + // This is to avoid undefined behavior if 'mask' isn't a valid enum value. + return 0; +} + +static inline ssize_t getChannelCount(const std::string& mask) { + return getChannelCount(stringToAudioChannelMask(mask)); +} + +static inline bool isOutputDevice(AudioDevice device) { + switch (device) { + case AudioDevice::UNKNOWN: + case AudioDevice::AUDIO_DEVICE_NONE: + return false; + case AudioDevice::AUDIO_DEVICE_OUT_EARPIECE: + case AudioDevice::AUDIO_DEVICE_OUT_SPEAKER: + case AudioDevice::AUDIO_DEVICE_OUT_WIRED_HEADSET: + case AudioDevice::AUDIO_DEVICE_OUT_WIRED_HEADPHONE: + case AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_SCO: + case AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET: + case AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT: + case AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_A2DP: + case AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES: + case AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER: + case AudioDevice::AUDIO_DEVICE_OUT_AUX_DIGITAL: + case AudioDevice::AUDIO_DEVICE_OUT_HDMI: + case AudioDevice::AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET: + case AudioDevice::AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET: + case AudioDevice::AUDIO_DEVICE_OUT_USB_ACCESSORY: + case AudioDevice::AUDIO_DEVICE_OUT_USB_DEVICE: + case AudioDevice::AUDIO_DEVICE_OUT_REMOTE_SUBMIX: + case AudioDevice::AUDIO_DEVICE_OUT_TELEPHONY_TX: + case AudioDevice::AUDIO_DEVICE_OUT_LINE: + case AudioDevice::AUDIO_DEVICE_OUT_HDMI_ARC: + case AudioDevice::AUDIO_DEVICE_OUT_SPDIF: + case AudioDevice::AUDIO_DEVICE_OUT_FM: + case AudioDevice::AUDIO_DEVICE_OUT_AUX_LINE: + case AudioDevice::AUDIO_DEVICE_OUT_SPEAKER_SAFE: + case AudioDevice::AUDIO_DEVICE_OUT_IP: + case AudioDevice::AUDIO_DEVICE_OUT_BUS: + case AudioDevice::AUDIO_DEVICE_OUT_PROXY: + case AudioDevice::AUDIO_DEVICE_OUT_USB_HEADSET: + case AudioDevice::AUDIO_DEVICE_OUT_HEARING_AID: + case AudioDevice::AUDIO_DEVICE_OUT_ECHO_CANCELLER: + case AudioDevice::AUDIO_DEVICE_OUT_DEFAULT: + case AudioDevice::AUDIO_DEVICE_OUT_STUB: + return true; + case AudioDevice::AUDIO_DEVICE_IN_COMMUNICATION: + case AudioDevice::AUDIO_DEVICE_IN_AMBIENT: + case AudioDevice::AUDIO_DEVICE_IN_BUILTIN_MIC: + case AudioDevice::AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET: + case AudioDevice::AUDIO_DEVICE_IN_WIRED_HEADSET: + case AudioDevice::AUDIO_DEVICE_IN_AUX_DIGITAL: + case AudioDevice::AUDIO_DEVICE_IN_HDMI: + case AudioDevice::AUDIO_DEVICE_IN_VOICE_CALL: + case AudioDevice::AUDIO_DEVICE_IN_TELEPHONY_RX: + case AudioDevice::AUDIO_DEVICE_IN_BACK_MIC: + case AudioDevice::AUDIO_DEVICE_IN_REMOTE_SUBMIX: + case AudioDevice::AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET: + case AudioDevice::AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET: + case AudioDevice::AUDIO_DEVICE_IN_USB_ACCESSORY: + case AudioDevice::AUDIO_DEVICE_IN_USB_DEVICE: + case AudioDevice::AUDIO_DEVICE_IN_FM_TUNER: + case AudioDevice::AUDIO_DEVICE_IN_TV_TUNER: + case AudioDevice::AUDIO_DEVICE_IN_LINE: + case AudioDevice::AUDIO_DEVICE_IN_SPDIF: + case AudioDevice::AUDIO_DEVICE_IN_BLUETOOTH_A2DP: + case AudioDevice::AUDIO_DEVICE_IN_LOOPBACK: + case AudioDevice::AUDIO_DEVICE_IN_IP: + case AudioDevice::AUDIO_DEVICE_IN_BUS: + case AudioDevice::AUDIO_DEVICE_IN_PROXY: + case AudioDevice::AUDIO_DEVICE_IN_USB_HEADSET: + case AudioDevice::AUDIO_DEVICE_IN_BLUETOOTH_BLE: + case AudioDevice::AUDIO_DEVICE_IN_HDMI_ARC: + case AudioDevice::AUDIO_DEVICE_IN_ECHO_REFERENCE: + case AudioDevice::AUDIO_DEVICE_IN_DEFAULT: + case AudioDevice::AUDIO_DEVICE_IN_STUB: + return false; + // No default to make sure all cases are covered. + } + // This is to avoid undefined behavior if 'device' isn't a valid enum value. + return false; +} + +static inline bool isOutputDevice(const std::string& device) { + return isOutputDevice(stringToAudioDevice(device)); +} + +} // namespace audio::policy::configuration::V7_0 + +#endif // AUDIO_POLICY_CONFIGURATION_V7_0_ENUMS_H diff --git a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp index b0eb2e0cfb..2466fd120a 100644 --- a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp +++ b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp @@ -16,6 +16,13 @@ #include "AudioPrimaryHidlHalTest.h" +#if MAJOR_VERSION >= 7 +#include +#include + +using android::xsdc_enum_range; +#endif + TEST_P(AudioHidlTest, OpenPrimaryDeviceUsingGetDevice) { doc::test("Calling openDevice(\"primary\") should return the primary device."); if (getDeviceName() != DeviceManager::kPrimaryDevice) { @@ -53,14 +60,29 @@ TEST_P(AudioHidlDeviceTest, GetMicrophonesTest) { "Make sure getMicrophones always succeeds" "and getActiveMicrophones always succeeds when recording from these microphones."); AudioConfig config{}; +#if MAJOR_VERSION <= 6 config.channelMask = mkEnumBitfield(AudioChannelMask::IN_MONO); config.sampleRateHz = 8000; config.format = AudioFormat::PCM_16_BIT; auto flags = hidl_bitfield(AudioInputFlag::NONE); const SinkMetadata initMetadata = {{{.source = AudioSource::MIC, .gain = 1}}}; +#elif MAJOR_VERSION >= 7 + config.base.channelMask.resize(1); + config.base.channelMask[0] = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_IN_MONO); + config.base.sampleRateHz = 8000; + config.base.format = toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT); + hidl_vec flags; + const SinkMetadata initMetadata = { + {{.source = toString(xsd::AudioSource::AUDIO_SOURCE_MIC), .gain = 1}}}; +#endif EventFlag* efGroup; for (auto microphone : microphones) { +#if MAJOR_VERSION <= 6 if (microphone.deviceAddress.device != AudioDevice::IN_BUILTIN_MIC) { +#elif MAJOR_VERSION >= 7 + if (xsd::stringToAudioDevice(microphone.deviceAddress.deviceType) != + xsd::AudioDevice::AUDIO_DEVICE_IN_BUILTIN_MIC) { +#endif continue; } sp stream; @@ -81,16 +103,16 @@ TEST_P(AudioHidlDeviceTest, GetMicrophonesTest) { size_t frameSize = stream->getFrameSize(); size_t frameCount = stream->getBufferSize() / frameSize; ASSERT_OK(stream->prepareForReading( - frameSize, frameCount, [&](auto r, auto& c, auto& d, auto&, auto&) { - readRes = r; - if (readRes == Result::OK) { - commandMQ.reset(new CommandMQ(c)); - dataMQ.reset(new DataMQ(d)); - if (dataMQ->isValid() && dataMQ->getEventFlagWord()) { - EventFlag::createEventFlag(dataMQ->getEventFlagWord(), &efGroup); + frameSize, frameCount, [&](auto r, auto& c, auto& d, auto&, auto) { + readRes = r; + if (readRes == Result::OK) { + commandMQ.reset(new CommandMQ(c)); + dataMQ.reset(new DataMQ(d)); + if (dataMQ->isValid() && dataMQ->getEventFlagWord()) { + EventFlag::createEventFlag(dataMQ->getEventFlagWord(), &efGroup); + } } - } - })); + })); ASSERT_OK(readRes); IStreamIn::ReadParameters params; params.command = IStreamIn::ReadCommand::READ; @@ -116,13 +138,24 @@ TEST_P(AudioHidlDeviceTest, GetMicrophonesTest) { TEST_P(AudioHidlDeviceTest, SetConnectedState) { doc::test("Check that the HAL can be notified of device connection and deconnection"); +#if MAJOR_VERSION <= 6 using AD = AudioDevice; for (auto deviceType : {AD::OUT_HDMI, AD::OUT_WIRED_HEADPHONE, AD::IN_USB_HEADSET}) { +#elif MAJOR_VERSION >= 7 + using AD = xsd::AudioDevice; + for (auto deviceType : + {toString(AD::AUDIO_DEVICE_OUT_HDMI), toString(AD::AUDIO_DEVICE_OUT_WIRED_HEADPHONE), + toString(AD::AUDIO_DEVICE_IN_USB_HEADSET)}) { +#endif SCOPED_TRACE("device=" + ::testing::PrintToString(deviceType)); for (bool state : {true, false}) { SCOPED_TRACE("state=" + ::testing::PrintToString(state)); DeviceAddress address = {}; +#if MAJOR_VERSION <= 6 address.device = deviceType; +#elif MAJOR_VERSION >= 7 + address.deviceType = deviceType; +#endif auto ret = getDevice()->setConnectedState(address, state); ASSERT_TRUE(ret.isOk()); if (ret == Result::NOT_SUPPORTED) { @@ -148,7 +181,11 @@ static void testGetDevices(IStream* stream, AudioDevice expectedDevice) { } // The stream was constructed with one device, thus getDevices must only return one ASSERT_EQ(1U, devices.size()); +#if MAJOR_VERSION <= 6 AudioDevice device = devices[0].device; +#elif MAJOR_VERSION >= 7 + auto device = devices[0].deviceType; +#endif ASSERT_TRUE(device == expectedDevice) << "Expected: " << ::testing::PrintToString(expectedDevice) << "\n Actual: " << ::testing::PrintToString(device); @@ -156,12 +193,22 @@ static void testGetDevices(IStream* stream, AudioDevice expectedDevice) { TEST_IO_STREAM(GetDevices, "Check that the stream device == the one it was opened with", areAudioPatchesSupported() ? doc::partialTest("Audio patches are supported") +#if MAJOR_VERSION <= 6 : testGetDevices(stream.get(), address.device)) +#elif MAJOR_VERSION >= 7 + : testGetDevices(stream.get(), address.deviceType)) +#endif static void testSetDevices(IStream* stream, const DeviceAddress& address) { DeviceAddress otherAddress = address; +#if MAJOR_VERSION <= 6 otherAddress.device = (address.device & AudioDevice::BIT_IN) == 0 ? AudioDevice::OUT_SPEAKER : AudioDevice::IN_BUILTIN_MIC; +#elif MAJOR_VERSION >= 7 + otherAddress.deviceType = xsd::isOutputDevice(address.deviceType) + ? toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_SPEAKER) + : toString(xsd::AudioDevice::AUDIO_DEVICE_IN_BUILTIN_MIC); +#endif EXPECT_RESULT(okOrNotSupported, stream->setDevices({otherAddress})); ASSERT_RESULT(okOrNotSupported, @@ -186,11 +233,19 @@ TEST_IO_STREAM(GetHwAvSync, "Get hardware sync can not fail", checkGetHwAVSync(g TEST_P(InputStreamTest, updateSinkMetadata) { doc::test("The HAL should not crash on metadata change"); +#if MAJOR_VERSION <= 6 hidl_enum_range range; +#elif MAJOR_VERSION >= 7 + xsdc_enum_range range; +#endif // Test all possible track configuration - for (AudioSource source : range) { + for (auto source : range) { for (float volume : {0.0, 0.5, 1.0}) { +#if MAJOR_VERSION <= 6 const SinkMetadata metadata = {{{.source = source, .gain = volume}}}; +#elif MAJOR_VERSION >= 7 + const SinkMetadata metadata = {{{.source = toString(source), .gain = volume}}}; +#endif ASSERT_OK(stream->updateSinkMetadata(metadata)) << "source=" << toString(source) << ", volume=" << volume; } @@ -213,13 +268,22 @@ TEST_P(OutputStreamTest, SelectPresentation) { TEST_P(OutputStreamTest, updateSourceMetadata) { doc::test("The HAL should not crash on metadata change"); +#if MAJOR_VERSION <= 6 hidl_enum_range usageRange; hidl_enum_range contentRange; +#elif MAJOR_VERSION >= 7 + xsdc_enum_range usageRange; + xsdc_enum_range contentRange; +#endif // Test all possible track configuration for (auto usage : usageRange) { for (auto content : contentRange) { for (float volume : {0.0, 0.5, 1.0}) { +#if MAJOR_VERSION <= 6 const SourceMetadata metadata = {{{usage, content, volume}}}; +#elif MAJOR_VERSION >= 7 + const SourceMetadata metadata = {{{toString(usage), toString(content), volume}}}; +#endif ASSERT_OK(stream->updateSourceMetadata(metadata)) << "usage=" << toString(usage) << ", content=" << toString(content) << ", volume=" << volume; @@ -227,12 +291,26 @@ TEST_P(OutputStreamTest, updateSourceMetadata) { } } + // clang-format off // Set many track of different configuration ASSERT_OK(stream->updateSourceMetadata( +#if MAJOR_VERSION <= 6 {{{AudioUsage::MEDIA, AudioContentType::MUSIC, 0.1}, {AudioUsage::VOICE_COMMUNICATION, AudioContentType::SPEECH, 1.0}, {AudioUsage::ALARM, AudioContentType::SONIFICATION, 0.0}, - {AudioUsage::ASSISTANT, AudioContentType::UNKNOWN, 0.3}}})); + {AudioUsage::ASSISTANT, AudioContentType::UNKNOWN, 0.3}}} +#elif MAJOR_VERSION >= 7 + {{{toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA), + toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_MUSIC), 0.1}, + {toString(xsd::AudioUsage::AUDIO_USAGE_VOICE_COMMUNICATION), + toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_SPEECH), 1.0}, + {toString(xsd::AudioUsage::AUDIO_USAGE_ALARM), + toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_SONIFICATION), 0.0}, + {toString(xsd::AudioUsage::AUDIO_USAGE_ASSISTANT), + toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_UNKNOWN), 0.3}}} +#endif + )); + // clang-format on // Set no metadata as if all stream track had stopped ASSERT_OK(stream->updateSourceMetadata({})); diff --git a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalUtils.h b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalUtils.h index 7a52d0e364..81a1f7b4b7 100644 --- a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalUtils.h +++ b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalUtils.h @@ -56,6 +56,7 @@ struct Parameters { } }; +#if MAJOR_VERSION <= 6 struct GetSupported { static auto getFormat(IStream* stream) { auto ret = stream->getFormat(); @@ -80,7 +81,7 @@ struct GetSupported { EXPECT_OK(stream->getSupportedFormats(returnIn(capabilities))); return Result::OK; } -#elif MAJOR_VERSION >= 6 +#else // MAJOR_VERSION == 6 static Result formats(IStream* stream, hidl_vec& capabilities) { Result res; EXPECT_OK(stream->getSupportedFormats(returnIn(res, capabilities))); @@ -88,6 +89,7 @@ struct GetSupported { } #endif }; +#endif // MAJOR_VERSION <= 6 template auto dump(T t, hidl_handle handle) { diff --git a/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp index 54d4bbd2cc..bd8de2d0e6 100644 --- a/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp +++ b/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp @@ -17,6 +17,7 @@ // pull in all the <= 5.0 tests #include "5.0/AudioPrimaryHidlHalTest.cpp" +#if MAJOR_VERSION <= 6 const std::vector& getOutputDeviceConfigParameters() { static std::vector parameters = [] { std::vector result; @@ -28,8 +29,8 @@ const std::vector& getOutputDeviceConfigParameters() { const auto& channels = profile->getChannels(); const auto& sampleRates = profile->getSampleRates(); auto configs = ConfigHelper::combineAudioConfig( - vector(channels.begin(), channels.end()), - vector(sampleRates.begin(), sampleRates.end()), + std::vector(channels.begin(), channels.end()), + std::vector(sampleRates.begin(), sampleRates.end()), profile->getFormat()); auto flags = ioProfile->getFlags(); for (auto& config : configs) { @@ -46,8 +47,8 @@ const std::vector& getOutputDeviceConfigParameters() { config.offloadInfo.bufferSize = 256; // arbitrary value config.offloadInfo.usage = AudioUsage::MEDIA; result.emplace_back(device, config, - AudioOutputFlag(AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD | - AUDIO_OUTPUT_FLAG_DIRECT)); + AudioOutputFlag(AudioOutputFlag::COMPRESS_OFFLOAD | + AudioOutputFlag::DIRECT)); } else { if (flags & AUDIO_OUTPUT_FLAG_PRIMARY) { // ignore the flag flags &= ~AUDIO_OUTPUT_FLAG_PRIMARY; @@ -74,8 +75,8 @@ const std::vector& getInputDeviceConfigParameters() { const auto& channels = profile->getChannels(); const auto& sampleRates = profile->getSampleRates(); auto configs = ConfigHelper::combineAudioConfig( - vector(channels.begin(), channels.end()), - vector(sampleRates.begin(), sampleRates.end()), + std::vector(channels.begin(), channels.end()), + std::vector(sampleRates.begin(), sampleRates.end()), profile->getFormat()); for (const auto& config : configs) { result.emplace_back(device, config, AudioInputFlag(ioProfile->getFlags())); @@ -87,13 +88,22 @@ const std::vector& getInputDeviceConfigParameters() { }(); return parameters; } +#endif // MAJOR_VERSION <= 6 TEST_P(AudioHidlDeviceTest, CloseDeviceWithOpenedOutputStreams) { doc::test("Verify that a device can't be closed if there are streams opened"); +#if MAJOR_VERSION <= 6 DeviceAddress address{.device = AudioDevice::OUT_DEFAULT}; - AudioConfig config{}; - auto flags = hidl_bitfield(AudioOutputFlag::NONE); SourceMetadata initMetadata = {{{AudioUsage::MEDIA, AudioContentType::MUSIC, 1 /* gain */}}}; + auto flags = hidl_bitfield(AudioOutputFlag::NONE); +#elif MAJOR_VERSION >= 7 + DeviceAddress address{.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_DEFAULT)}; + SourceMetadata initMetadata = { + {{toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA), + toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_MUSIC), 1 /* gain */}}}; + hidl_vec flags; +#endif + AudioConfig config{}; sp stream; StreamHelper helper(stream); AudioConfig suggestedConfig{}; @@ -111,14 +121,20 @@ TEST_P(AudioHidlDeviceTest, CloseDeviceWithOpenedOutputStreams) { TEST_P(AudioHidlDeviceTest, CloseDeviceWithOpenedInputStreams) { doc::test("Verify that a device can't be closed if there are streams opened"); - auto module = getCachedPolicyConfig().getModuleFromName(getDeviceName()); - if (module->getInputProfiles().empty()) { + if (!getCachedPolicyConfig().haveInputProfilesInModule(getDeviceName())) { GTEST_SKIP() << "Device doesn't have input profiles"; } +#if MAJOR_VERSION <= 6 DeviceAddress address{.device = AudioDevice::IN_DEFAULT}; - AudioConfig config{}; - auto flags = hidl_bitfield(AudioInputFlag::NONE); SinkMetadata initMetadata = {{{.source = AudioSource::MIC, .gain = 1}}}; + auto flags = hidl_bitfield(AudioInputFlag::NONE); +#elif MAJOR_VERSION >= 7 + DeviceAddress address{.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_IN_DEFAULT)}; + SinkMetadata initMetadata = { + {{.source = toString(xsd::AudioSource::AUDIO_SOURCE_MIC), .gain = 1}}}; + hidl_vec flags; +#endif + AudioConfig config{}; sp stream; StreamHelper helper(stream); AudioConfig suggestedConfig{}; @@ -137,9 +153,8 @@ TEST_P(AudioHidlDeviceTest, CloseDeviceWithOpenedInputStreams) { TEST_P(AudioPatchHidlTest, UpdatePatchInvalidHandle) { doc::test("Verify that passing an invalid handle to updateAudioPatch is checked"); AudioPatchHandle ignored; - ASSERT_OK(getDevice()->updateAudioPatch( - static_cast(AudioHandleConsts::AUDIO_PATCH_HANDLE_NONE), - hidl_vec(), hidl_vec(), returnIn(res, ignored))); + ASSERT_OK(getDevice()->updateAudioPatch(AudioPatchHandle{}, hidl_vec(), + hidl_vec(), returnIn(res, ignored))); ASSERT_RESULT(Result::INVALID_ARGUMENTS, res); } diff --git a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp index 33efa6f4d6..63eaea8acc 100644 --- a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp +++ b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp @@ -16,3 +16,101 @@ // pull in all the <= 6.0 tests #include "6.0/AudioPrimaryHidlHalTest.cpp" + +static std::vector combineAudioConfig(std::vector channelMasks, + std::vector sampleRates, + const std::string& format) { + std::vector configs; + configs.reserve(channelMasks.size() * sampleRates.size()); + for (auto channelMask : channelMasks) { + for (auto sampleRate : sampleRates) { + AudioConfig config{}; + // leave offloadInfo to 0 + config.base.channelMask.resize(1); + config.base.channelMask[0] = toString(channelMask); + config.base.sampleRateHz = sampleRate; + config.base.format = format; + configs.push_back(config); + } + } + return configs; +} + +const std::vector& getOutputDeviceConfigParameters() { + static std::vector parameters = [] { + std::vector result; + const std::vector offloadFlags = { + toString(xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD), + toString(xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_DIRECT)}; + for (const auto& device : getDeviceParameters()) { + auto module = + getCachedPolicyConfig().getModuleFromName(std::get(device)); + for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) { + if (mixPort.getRole() != xsd::Role::source) continue; // not an output profile + auto xsdFlags = mixPort.getFlags(); + const bool isOffload = + std::find(xsdFlags.begin(), xsdFlags.end(), + xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != + xsdFlags.end(); + std::vector flags; + if (!isOffload) { + for (auto flag : xsdFlags) { + if (flag != xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_PRIMARY) { + flags.push_back(toString(flag)); + } + } + } else { + flags = offloadFlags; + } + for (const auto& profile : mixPort.getProfile()) { + auto configs = + combineAudioConfig(profile.getChannelMasks(), + profile.getSamplingRates(), profile.getFormat()); + for (auto& config : configs) { + // Some combinations of flags declared in the config file require special + // treatment. + if (isOffload) { + config.offloadInfo.base = config.base; + config.offloadInfo.streamType = + toString(xsd::AudioStreamType::AUDIO_STREAM_MUSIC); + config.offloadInfo.usage = toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA); + config.offloadInfo.bitRatePerSecond = 320; + config.offloadInfo.durationMicroseconds = -1; + config.offloadInfo.bitWidth = 16; + config.offloadInfo.bufferSize = 256; // arbitrary value + } + result.emplace_back(device, config, flags); + } + } + } + } + return result; + }(); + return parameters; +} + +const std::vector& getInputDeviceConfigParameters() { + static std::vector parameters = [] { + std::vector result; + for (const auto& device : getDeviceParameters()) { + auto module = + getCachedPolicyConfig().getModuleFromName(std::get(device)); + for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) { + if (mixPort.getRole() != xsd::Role::sink) continue; // not an input profile + std::vector flags; + std::transform(mixPort.getFlags().begin(), mixPort.getFlags().end(), flags.begin(), + [](auto flag) { return toString(flag); }); + for (const auto& profile : mixPort.getProfile()) { + auto configs = + combineAudioConfig(profile.getChannelMasks(), + profile.getSamplingRates(), profile.getFormat()); + for (const auto& config : configs) { + result.emplace_back(device, config, flags); + } + } + } + } + return result; + }(); + return parameters; +} diff --git a/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h b/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h new file mode 100644 index 0000000000..d790b34c46 --- /dev/null +++ b/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +// Note: it is assumed that this file is included from AudioPrimaryHidlTest.h +// and thus it doesn't have all '#include' and 'using' directives required +// for a standalone compilation. + +namespace xsd { +using Module = Modules::Module; +} + +class PolicyConfig { + public: + explicit PolicyConfig(const std::string& configFileName) + : mConfigFileName{configFileName}, + mFilePath{findExistingConfigurationFile(mConfigFileName)}, + mConfig{xsd::read(mFilePath.c_str())} { + if (mConfig) { + mStatus = OK; + mPrimaryModule = getModuleFromName(DeviceManager::kPrimaryDevice); + for (const auto& module : mConfig->getFirstModules()->get_module()) { + auto attachedDevices = module.getFirstAttachedDevices()->getItem(); + if (!attachedDevices.empty()) { + mModulesWithDevicesNames.insert(module.getName()); + } + } + } + } + status_t getStatus() const { return mStatus; } + std::string getError() const { + if (mFilePath.empty()) { + return std::string{"Could not find "} + mConfigFileName + + " file in: " + testing::PrintToString(android::audio_get_configuration_paths()); + } else { + return "Invalid config file: " + mFilePath; + } + } + const std::string& getFilePath() const { return mFilePath; } + const xsd::Module* getModuleFromName(const std::string& name) const { + if (mConfig) { + for (const auto& module : mConfig->getFirstModules()->get_module()) { + if (module.getName() == name) return &module; + } + } + return nullptr; + } + const xsd::Module* getPrimaryModule() const { return mPrimaryModule; } + const std::set& getModulesWithDevicesNames() const { + return mModulesWithDevicesNames; + } + bool haveInputProfilesInModule(const std::string& name) const { + auto module = getModuleFromName(name); + for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) { + if (mixPort.getRole() == xsd::Role::sink) return true; + } + return false; + } + + private: + static std::string findExistingConfigurationFile(const std::string& fileName) { + for (const auto& location : android::audio_get_configuration_paths()) { + std::string path = location + '/' + fileName; + if (access(path.c_str(), F_OK) == 0) { + return path; + } + } + return std::string{}; + } + + const std::string mConfigFileName; + const std::string mFilePath; + std::optional mConfig; + status_t mStatus = NO_INIT; + const xsd::Module* mPrimaryModule; + std::set mModulesWithDevicesNames; +}; diff --git a/audio/core/all-versions/vts/functional/Android.bp b/audio/core/all-versions/vts/functional/Android.bp index 6ac9b20f95..c7bfe08889 100644 --- a/audio/core/all-versions/vts/functional/Android.bp +++ b/audio/core/all-versions/vts/functional/Android.bp @@ -19,9 +19,6 @@ cc_defaults { defaults: ["VtsHalTargetTestDefaults"], static_libs: [ "android.hardware.audio.common.test.utility", - "libaudiofoundation", - "libaudiopolicycomponents", - "libmedia_helper", "libxml2", ], shared_libs: [ @@ -44,6 +41,9 @@ cc_test { "2.0/AudioPrimaryHidlHalTest.cpp", ], static_libs: [ + "libaudiofoundation", + "libaudiopolicycomponents", + "libmedia_helper", "android.hardware.audio@2.0", "android.hardware.audio.common@2.0", ], @@ -67,6 +67,9 @@ cc_test { "4.0/AudioPrimaryHidlHalTest.cpp", ], static_libs: [ + "libaudiofoundation", + "libaudiopolicycomponents", + "libmedia_helper", "android.hardware.audio@4.0", "android.hardware.audio.common@4.0", ], @@ -90,6 +93,9 @@ cc_test { "5.0/AudioPrimaryHidlHalTest.cpp", ], static_libs: [ + "libaudiofoundation", + "libaudiopolicycomponents", + "libmedia_helper", "android.hardware.audio@5.0", "android.hardware.audio.common@5.0", ], @@ -113,6 +119,9 @@ cc_test { "6.0/AudioPrimaryHidlHalTest.cpp", ], static_libs: [ + "libaudiofoundation", + "libaudiopolicycomponents", + "libmedia_helper", "android.hardware.audio@6.0", "android.hardware.audio.common@6.0", ], @@ -130,7 +139,6 @@ cc_test { } cc_test { - enabled: false, name: "VtsHalAudioV7_0TargetTest", defaults: ["VtsHalAudioTargetTest_defaults"], srcs: [ @@ -139,6 +147,7 @@ cc_test { static_libs: [ "android.hardware.audio@7.0", "android.hardware.audio.common@7.0", + "android.hardware.audio.common@7.0-enums", ], cflags: [ "-DMAJOR_VERSION=7", diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h index 01bdd69408..5e4b414d29 100644 --- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h +++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h @@ -42,8 +42,11 @@ #include PATH(android/hardware/audio/FILE_VERSION/IPrimaryDevice.h) #include PATH(android/hardware/audio/FILE_VERSION/types.h) #include PATH(android/hardware/audio/common/FILE_VERSION/types.h) +#if MAJOR_VERSION >= 7 +#include +#include +#endif -#include #include #include #include @@ -63,14 +66,6 @@ #include "4.0/AudioPrimaryHidlHalUtils.h" #endif -using std::initializer_list; -using std::list; -using std::string; -using std::to_string; -using std::vector; - -using ::android::AudioPolicyConfig; -using ::android::HwModule; using ::android::NO_INIT; using ::android::OK; using ::android::sp; @@ -93,6 +88,12 @@ using ::android::hardware::details::toHexString; using namespace ::android::hardware::audio::common::CPP_VERSION; using namespace ::android::hardware::audio::common::test::utility; using namespace ::android::hardware::audio::CPP_VERSION; +#if MAJOR_VERSION >= 7 +// Make an alias for enumerations generated from the APM config XSD. +namespace xsd { +using namespace ::audio::policy::configuration::CPP_VERSION; +} +#endif // Typical accepted results from interface methods static auto okOrNotSupported = {Result::OK, Result::NOT_SUPPORTED}; @@ -103,8 +104,12 @@ static auto okOrInvalidStateOrNotSupported = {Result::OK, Result::INVALID_STATE, static auto invalidArgsOrNotSupported = {Result::INVALID_ARGUMENTS, Result::NOT_SUPPORTED}; static auto invalidStateOrNotSupported = {Result::INVALID_STATE, Result::NOT_SUPPORTED}; -#define AUDIO_PRIMARY_HIDL_HAL_TEST #include "DeviceManager.h" +#if MAJOR_VERSION <= 6 +#include "PolicyConfig.h" +#elif MAJOR_VERSION >= 7 +#include "7.0/PolicyConfig.h" +#endif class HidlTest : public ::testing::Test { public: @@ -136,83 +141,16 @@ class HidlTest : public ::testing::Test { ////////////////////////// Audio policy configuration //////////////////////// ////////////////////////////////////////////////////////////////////////////// -static constexpr char kConfigFileName[] = "audio_policy_configuration.xml"; - // Stringify the argument. #define QUOTE(x) #x #define STRINGIFY(x) QUOTE(x) -struct PolicyConfigData { - android::HwModuleCollection hwModules; - android::DeviceVector availableOutputDevices; - android::DeviceVector availableInputDevices; - sp defaultOutputDevice; -}; - -class PolicyConfig : private PolicyConfigData, public AudioPolicyConfig { - public: - PolicyConfig() - : AudioPolicyConfig(hwModules, availableOutputDevices, availableInputDevices, - defaultOutputDevice) { - for (const auto& location : android::audio_get_configuration_paths()) { - std::string path = location + '/' + kConfigFileName; - if (access(path.c_str(), F_OK) == 0) { - mFilePath = path; - break; - } - } - mStatus = android::deserializeAudioPolicyFile(mFilePath.c_str(), this); - if (mStatus == OK) { - mPrimaryModule = getHwModules().getModuleFromName(DeviceManager::kPrimaryDevice); - // Available devices are not 'attached' to modules at this moment. - // Need to go over available devices and find their module. - for (const auto& device : availableOutputDevices) { - for (const auto& module : hwModules) { - if (module->getDeclaredDevices().indexOf(device) >= 0) { - mModulesWithDevicesNames.insert(module->getName()); - break; - } - } - } - for (const auto& device : availableInputDevices) { - for (const auto& module : hwModules) { - if (module->getDeclaredDevices().indexOf(device) >= 0) { - mModulesWithDevicesNames.insert(module->getName()); - break; - } - } - } - } - } - status_t getStatus() const { return mStatus; } - std::string getError() const { - if (mFilePath.empty()) { - return std::string{"Could not find "} + kConfigFileName + - " file in: " + testing::PrintToString(android::audio_get_configuration_paths()); - } else { - return "Invalid config file: " + mFilePath; - } - } - const std::string& getFilePath() const { return mFilePath; } - sp getModuleFromName(const std::string& name) const { - return getHwModules().getModuleFromName(name.c_str()); - } - sp getPrimaryModule() const { return mPrimaryModule; } - const std::set& getModulesWithDevicesNames() const { - return mModulesWithDevicesNames; - } - - private: - status_t mStatus = NO_INIT; - std::string mFilePath; - sp mPrimaryModule = nullptr; - std::set mModulesWithDevicesNames; -}; +static constexpr char kConfigFileName[] = "audio_policy_configuration.xml"; // Cached policy config after parsing for faster test startup const PolicyConfig& getCachedPolicyConfig() { static std::unique_ptr policyConfig = [] { - auto config = std::make_unique(); + auto config = std::make_unique(kConfigFileName); return config; }(); return *policyConfig; @@ -449,9 +387,10 @@ class AccessorHidlTest : public BaseTestClass { * The getter and/or the setter may return NOT_SUPPORTED if optionality == OPTIONAL. */ template - void testAccessors(IUTGetter iutGetter, const string& propertyName, - const Initial expectedInitial, list valuesToTest, Setter setter, - Getter getter, const vector& invalidValues = {}) { + void testAccessors(IUTGetter iutGetter, const std::string& propertyName, + const Initial expectedInitial, std::list valuesToTest, + Setter setter, Getter getter, + const std::vector& invalidValues = {}) { const auto expectedResults = {Result::OK, optionality == OPTIONAL ? Result::NOT_SUPPORTED : Result::OK}; @@ -495,9 +434,9 @@ class AccessorHidlTest : public BaseTestClass { EXPECT_RESULT(expectedResults, ((this->*iutGetter)().get()->*setter)(initialValue)); } template - void testAccessors(const string& propertyName, const Initial expectedInitial, - list valuesToTest, Setter setter, Getter getter, - const vector& invalidValues = {}) { + void testAccessors(const std::string& propertyName, const Initial expectedInitial, + std::list valuesToTest, Setter setter, Getter getter, + const std::vector& invalidValues = {}) { testAccessors(&BaseTestClass::getDevice, propertyName, expectedInitial, valuesToTest, setter, getter, invalidValues); } @@ -573,9 +512,13 @@ GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioPatchHidlTest); // Nesting a tuple in another tuple allows to use GTest Combine function to generate // all combinations of devices and configs. enum { PARAM_DEVICE, PARAM_CONFIG, PARAM_FLAGS }; +#if MAJOR_VERSION <= 6 enum { INDEX_INPUT, INDEX_OUTPUT }; using DeviceConfigParameter = std::tuple>; +#elif MAJOR_VERSION >= 7 +using DeviceConfigParameter = std::tuple>; +#endif #if MAJOR_VERSION >= 6 const std::vector& getInputDeviceConfigParameters(); @@ -583,8 +526,8 @@ const std::vector& getOutputDeviceConfigParameters(); #endif #if MAJOR_VERSION >= 4 -static string SanitizeStringForGTestName(const string& s) { - string result = s; +static std::string SanitizeStringForGTestName(const std::string& s) { + std::string result = s; for (size_t i = 0; i < result.size(); i++) { // gtest test names must only contain alphanumeric characters if (!std::isalnum(result[i])) result[i] = '_'; @@ -598,43 +541,57 @@ static string SanitizeStringForGTestName(const string& s) { * As the only parameter changing are channel mask and sample rate, * only print those ones in the test name. */ -static string DeviceConfigParameterToString( +static std::string DeviceConfigParameterToString( const testing::TestParamInfo& info) { const AudioConfig& config = std::get(info.param); const auto deviceName = DeviceParameterToString(::testing::TestParamInfo{ std::get(info.param), info.index}); - return (deviceName.empty() ? "" : deviceName + "_") + to_string(info.index) + "__" + - to_string(config.sampleRateHz) + "_" + - // "MONO" is more clear than "FRONT_LEFT" - ((config.channelMask == mkEnumBitfield(AudioChannelMask::OUT_MONO) || - config.channelMask == mkEnumBitfield(AudioChannelMask::IN_MONO)) - ? "MONO" + const auto devicePart = + (deviceName.empty() ? "" : deviceName + "_") + std::to_string(info.index); + // The types had changed a lot between versions 2, 4..6 and 7. Use separate + // code sections for easier understanding. #if MAJOR_VERSION == 2 - : ::testing::PrintToString(config.channelMask) -#elif MAJOR_VERSION >= 4 - // In V4 and above the channel mask is a bitfield. - // Printing its value using HIDL's toString for a bitfield emits a lot of extra - // text due to overlapping constant values. Instead, we print the bitfield value - // as if it was a single value + its hex representation - : SanitizeStringForGTestName( - ::testing::PrintToString(AudioChannelMask(config.channelMask)) + "_" + - toHexString(config.channelMask)) -#endif - ) + - "_" + -#if MAJOR_VERSION == 2 - std::visit([](auto&& arg) -> std::string { return ::testing::PrintToString(arg); }, - std::get(info.param)); -#elif MAJOR_VERSION >= 4 - SanitizeStringForGTestName(std::visit( - [](auto&& arg) -> std::string { - using T = std::decay_t; - // Need to use FQN of toString to avoid confusing the compiler - return ::android::hardware::audio::common::CPP_VERSION::toString( - hidl_bitfield(arg)); - }, - std::get(info.param))); + const auto configPart = + std::to_string(config.sampleRateHz) + "_" + + // "MONO" is more clear than "FRONT_LEFT" + (config.channelMask == AudioChannelMask::OUT_MONO || + config.channelMask == AudioChannelMask::IN_MONO + ? "MONO" + : ::testing::PrintToString(config.channelMask)) + + "_" + + std::visit([](auto&& arg) -> std::string { return ::testing::PrintToString(arg); }, + std::get(info.param)); +#elif MAJOR_VERSION >= 4 && MAJOR_VERSION <= 6 + const auto configPart = + std::to_string(config.sampleRateHz) + "_" + + // "MONO" is more clear than "FRONT_LEFT" + (config.channelMask == mkEnumBitfield(AudioChannelMask::OUT_MONO) || + config.channelMask == mkEnumBitfield(AudioChannelMask::IN_MONO) + ? "MONO" + // In V4 and above the channel mask is a bitfield. + // Printing its value using HIDL's toString for a bitfield emits a lot of extra + // text due to overlapping constant values. Instead, we print the bitfield + // value as if it was a single value + its hex representation + : SanitizeStringForGTestName( + ::testing::PrintToString(AudioChannelMask(config.channelMask)) + + "_" + toHexString(config.channelMask))) + + "_" + + SanitizeStringForGTestName(std::visit( + [](auto&& arg) -> std::string { + using T = std::decay_t; + // Need to use FQN of toString to avoid confusing the compiler + return ::android::hardware::audio::common::CPP_VERSION::toString( + hidl_bitfield(arg)); + }, + std::get(info.param))); +#elif MAJOR_VERSION >= 7 + const auto configPart = + std::to_string(config.base.sampleRateHz) + "_" + + // The channel masks and flags are vectors of strings, just need to sanitize them. + SanitizeStringForGTestName(::testing::PrintToString(config.base.channelMask)) + "_" + + SanitizeStringForGTestName(::testing::PrintToString(std::get(info.param))); #endif + return devicePart + "__" + configPart; } class AudioHidlTestWithDeviceConfigParameter @@ -660,7 +617,7 @@ class AudioHidlTestWithDeviceConfigParameter AudioOutputFlag getOutputFlags() const { return std::get(std::get(GetParam())); } -#elif MAJOR_VERSION >= 4 +#elif MAJOR_VERSION >= 4 && MAJOR_VERSION <= 6 hidl_bitfield getInputFlags() const { return hidl_bitfield( std::get(std::get(GetParam()))); @@ -669,10 +626,17 @@ class AudioHidlTestWithDeviceConfigParameter return hidl_bitfield( std::get(std::get(GetParam()))); } +#elif MAJOR_VERSION >= 7 + hidl_vec getInputFlags() const { return std::get(GetParam()); } + hidl_vec getOutputFlags() const { return std::get(GetParam()); } #endif }; +#if MAJOR_VERSION <= 6 +#define AUDIO_PRIMARY_HIDL_HAL_TEST #include "ConfigHelper.h" +#undef AUDIO_PRIMARY_HIDL_HAL_TEST +#endif ////////////////////////////////////////////////////////////////////////////// ///////////////////////////// getInputBufferSize ///////////////////////////// @@ -839,7 +803,7 @@ class StreamHelper { AudioConfig* suggestedConfigPtr) { // FIXME: Open a stream without an IOHandle // This is not required to be accepted by hal implementations - AudioIoHandle ioHandle = (AudioIoHandle)AudioHandleConsts::AUDIO_IO_HANDLE_NONE; + AudioIoHandle ioHandle{}; AudioConfig suggestedConfig{}; bool retryWithSuggestedConfig = true; if (suggestedConfigPtr == nullptr) { @@ -932,7 +896,11 @@ class OpenStreamTest : public AudioHidlTestWithDeviceConfigParameter { class OutputStreamTest : public OpenStreamTest { void SetUp() override { ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp()); // setup base +#if MAJOR_VERSION <= 6 address.device = AudioDevice::OUT_DEFAULT; +#elif MAJOR_VERSION >= 7 + address.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_DEFAULT); +#endif const AudioConfig& config = getConfig(); auto flags = getOutputFlags(); testOpen( @@ -946,13 +914,19 @@ class OutputStreamTest : public OpenStreamTest { }, config); } -#if MAJOR_VERSION >= 4 +#if MAJOR_VERSION >= 4 && MAJOR_VERSION <= 6 - protected: + protected: const SourceMetadata initMetadata = { { { AudioUsage::MEDIA, AudioContentType::MUSIC, 1 /* gain */ } }}; +#elif MAJOR_VERSION >= 7 + protected: + const SourceMetadata initMetadata = { + { { toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA), + toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_MUSIC), + 1 /* gain */ } }}; #endif }; TEST_P(OutputStreamTest, OpenOutputStreamTest) { @@ -995,7 +969,11 @@ GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(OutputStreamTest); class InputStreamTest : public OpenStreamTest { void SetUp() override { ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp()); // setup base +#if MAJOR_VERSION <= 6 address.device = AudioDevice::IN_DEFAULT; +#elif MAJOR_VERSION <= 7 + address.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_IN_DEFAULT); +#endif const AudioConfig& config = getConfig(); auto flags = getInputFlags(); testOpen( @@ -1009,8 +987,11 @@ class InputStreamTest : public OpenStreamTest { protected: #if MAJOR_VERSION == 2 const AudioSource initMetadata = AudioSource::DEFAULT; -#elif MAJOR_VERSION >= 4 - const SinkMetadata initMetadata = {{{.source = AudioSource::DEFAULT, .gain = 1}}}; +#elif MAJOR_VERSION >= 4 && MAJOR_VERSION <= 6 + const SinkMetadata initMetadata = {{ {.source = AudioSource::DEFAULT, .gain = 1 } }}; +#elif MAJOR_VERSION >= 7 + const SinkMetadata initMetadata = { + {{.source = toString(xsd::AudioSource::AUDIO_SOURCE_DEFAULT), .gain = 1}}}; #endif }; @@ -1067,6 +1048,7 @@ GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(InputStreamTest); TEST_IO_STREAM(GetFrameCount, "Check that getting stream frame count does not crash the HAL.", ASSERT_TRUE(stream->getFrameCount().isOk())) +#if MAJOR_VERSION <= 6 TEST_IO_STREAM(GetSampleRate, "Check that the stream sample rate == the one it was opened with", ASSERT_EQ(audioConfig.sampleRateHz, extract(stream->getSampleRate()))) @@ -1075,6 +1057,7 @@ TEST_IO_STREAM(GetChannelMask, "Check that the stream channel mask == the one it TEST_IO_STREAM(GetFormat, "Check that the stream format == the one it was opened with", ASSERT_EQ(audioConfig.format, extract(stream->getFormat()))) +#endif // TODO: for now only check that the framesize is not incoherent TEST_IO_STREAM(GetFrameSize, "Check that the stream frame size == the one it was opened with", @@ -1084,7 +1067,7 @@ TEST_IO_STREAM(GetBufferSize, "Check that the stream buffer size== the one it wa ASSERT_GE(extract(stream->getBufferSize()), extract(stream->getFrameSize()))); template -static void testCapabilityGetter(const string& name, IStream* stream, +static void testCapabilityGetter(const std::string& name, IStream* stream, CapabilityGetter capabilityGetter, Return (IStream::*getter)(), Return (IStream::*setter)(Property), @@ -1120,6 +1103,7 @@ static void testCapabilityGetter(const string& name, IStream* stream, } } +#if MAJOR_VERSION <= 6 TEST_IO_STREAM(SupportedSampleRate, "Check that the stream sample rate is declared as supported", testCapabilityGetter("getSupportedSampleRate", stream.get(), &GetSupported::sampleRates, &IStream::getSampleRate, @@ -1137,19 +1121,71 @@ TEST_IO_STREAM(SupportedChannelMask, "Check that the stream channel mask is decl TEST_IO_STREAM(SupportedFormat, "Check that the stream format is declared as supported", testCapabilityGetter("getSupportedFormat", stream.get(), &GetSupported::formats, &IStream::getFormat, &IStream::setFormat)) +#else +static void testGetSupportedProfiles(IStream* stream) { + Result res; + hidl_vec profiles; + auto ret = stream->getSupportedProfiles(returnIn(res, profiles)); + EXPECT_TRUE(ret.isOk()); + if (res == Result::OK) { + EXPECT_GT(profiles.size(), 0); + } else { + EXPECT_EQ(Result::NOT_SUPPORTED, res); + } +} + +TEST_IO_STREAM(GetSupportedProfiles, "Try to call optional method GetSupportedProfiles", + testGetSupportedProfiles(stream.get())) + +static void testSetAudioProperties(IStream* stream) { + Result res; + hidl_vec profiles; + auto ret = stream->getSupportedProfiles(returnIn(res, profiles)); + EXPECT_TRUE(ret.isOk()); + if (res == Result::NOT_SUPPORTED) { + GTEST_SKIP() << "Retrieving supported profiles is not implemented"; + } + for (const auto& profile : profiles) { + for (const auto& sampleRate : profile.sampleRates) { + for (const auto& channelMask : profile.channelMasks) { + AudioConfigBase config{.format = profile.format, + .sampleRateHz = sampleRate, + .channelMask = channelMask}; + auto ret = stream->setAudioProperties(config); + EXPECT_TRUE(ret.isOk()); + EXPECT_EQ(Result::OK, ret) << config.format << "; " << config.sampleRateHz << "; " + << toString(config.channelMask); + } + } + } +} + +TEST_IO_STREAM(SetAudioProperties, "Call setAudioProperties for all supported profiles", + testSetAudioProperties(stream.get())) +#endif static void testGetAudioProperties(IStream* stream, AudioConfig expectedConfig) { +#if MAJOR_VERSION <= 6 uint32_t sampleRateHz; auto mask = mkEnumBitfield({}); AudioFormat format; - stream->getAudioProperties(returnIn(sampleRateHz, mask, format)); + auto ret = stream->getAudioProperties(returnIn(sampleRateHz, mask, format)); + EXPECT_TRUE(ret.isOk()); // FIXME: the qcom hal it does not currently negotiate the sampleRate & // channel mask EXPECT_EQ(expectedConfig.sampleRateHz, sampleRateHz); EXPECT_EQ(expectedConfig.channelMask, mask); EXPECT_EQ(expectedConfig.format, format); +#elif MAJOR_VERSION >= 7 + AudioConfigBase actualConfig{}; + auto ret = stream->getAudioProperties(returnIn(actualConfig)); + EXPECT_TRUE(ret.isOk()); + EXPECT_EQ(expectedConfig.base.sampleRateHz, actualConfig.sampleRateHz); + EXPECT_EQ(expectedConfig.base.channelMask, actualConfig.channelMask); + EXPECT_EQ(expectedConfig.base.format, actualConfig.format); +#endif } TEST_IO_STREAM(GetAudioProperties, @@ -1160,7 +1196,7 @@ TEST_IO_STREAM(SetHwAvSync, "Try to set hardware sync to an invalid value", ASSERT_RESULT(okOrNotSupportedOrInvalidArgs, stream->setHwAvSync(666))) static void checkGetNoParameter(IStream* stream, hidl_vec keys, - initializer_list expectedResults) { + std::initializer_list expectedResults) { hidl_vec parameters; Result res; ASSERT_OK(Parameters::get(stream, keys, returnIn(res, parameters))); @@ -1271,7 +1307,11 @@ TEST_P(InputStreamTest, GetAudioSource) { return; } ASSERT_OK(res); +#if MAJOR_VERSION <= 6 ASSERT_EQ(AudioSource::DEFAULT, source); +#elif MAJOR_VERSION >= 7 + ASSERT_EQ(xsd::AudioSource::AUDIO_SOURCE_DEFAULT, xsd::stringToAudioSource(source)); +#endif } static void testUnitaryGain(std::function(float)> setGain) { @@ -1286,7 +1326,7 @@ static void testUnitaryGain(std::function(float)> setGain) { } static void testOptionalUnitaryGain(std::function(float)> setGain, - string debugName) { + std::string debugName) { auto result = setGain(1); ASSERT_IS_OK(result); if (result == Result::NOT_SUPPORTED) { @@ -1306,7 +1346,7 @@ static void testPrepareForReading(IStreamIn* stream, uint32_t frameSize, uint32_ Result res; // Ignore output parameters as the call should fail ASSERT_OK(stream->prepareForReading(frameSize, framesCount, - [&res](auto r, auto&, auto&, auto&, auto&) { res = r; })); + [&res](auto r, auto&, auto&, auto&, auto) { res = r; })); EXPECT_RESULT(Result::INVALID_ARGUMENTS, res); } @@ -1371,7 +1411,7 @@ static void testPrepareForWriting(IStreamOut* stream, uint32_t frameSize, uint32 Result res; // Ignore output parameters as the call should fail ASSERT_OK(stream->prepareForWriting(frameSize, framesCount, - [&res](auto r, auto&, auto&, auto&, auto&) { res = r; })); + [&res](auto r, auto&, auto&, auto&, auto) { res = r; })); EXPECT_RESULT(Result::INVALID_ARGUMENTS, res); } diff --git a/audio/core/all-versions/vts/functional/ConfigHelper.h b/audio/core/all-versions/vts/functional/ConfigHelper.h index 8ef2b436bb..1a1dbea939 100644 --- a/audio/core/all-versions/vts/functional/ConfigHelper.h +++ b/audio/core/all-versions/vts/functional/ConfigHelper.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#pragma once + // Code in this file uses 'getCachedPolicyConfig' #ifndef AUDIO_PRIMARY_HIDL_HAL_TEST #error Must be included from AudioPrimaryHidlTest.h @@ -46,32 +48,32 @@ struct ConfigHelper { } // Cache result ? - static const vector getRequiredSupportPlaybackAudioConfig() { + static const std::vector getRequiredSupportPlaybackAudioConfig() { return combineAudioConfig({AudioChannelMask::OUT_STEREO, AudioChannelMask::OUT_MONO}, {8000, 11025, 16000, 22050, 32000, 44100}, {AudioFormat::PCM_16_BIT}); } - static const vector getRecommendedSupportPlaybackAudioConfig() { + static const std::vector getRecommendedSupportPlaybackAudioConfig() { return combineAudioConfig({AudioChannelMask::OUT_STEREO, AudioChannelMask::OUT_MONO}, {24000, 48000}, {AudioFormat::PCM_16_BIT}); } - static const vector getRequiredSupportCaptureAudioConfig() { + static const std::vector getRequiredSupportCaptureAudioConfig() { if (!primaryHasMic()) return {}; return combineAudioConfig({AudioChannelMask::IN_MONO}, {8000, 11025, 16000, 44100}, {AudioFormat::PCM_16_BIT}); } - static const vector getRecommendedSupportCaptureAudioConfig() { + static const std::vector getRecommendedSupportCaptureAudioConfig() { if (!primaryHasMic()) return {}; return combineAudioConfig({AudioChannelMask::IN_STEREO}, {22050, 48000}, {AudioFormat::PCM_16_BIT}); } - static vector combineAudioConfig(vector channelMasks, - vector sampleRates, - audio_format_t format) { - vector configs; + static std::vector combineAudioConfig( + std::vector channelMasks, std::vector sampleRates, + audio_format_t format) { + std::vector configs; configs.reserve(channelMasks.size() * sampleRates.size()); for (auto channelMask : channelMasks) { for (auto sampleRate : sampleRates) { @@ -86,10 +88,10 @@ struct ConfigHelper { return configs; } - static vector combineAudioConfig(vector channelMasks, - vector sampleRates, - vector formats) { - vector configs; + static std::vector combineAudioConfig(std::vector channelMasks, + std::vector sampleRates, + std::vector formats) { + std::vector configs; configs.reserve(channelMasks.size() * sampleRates.size() * formats.size()); for (auto channelMask : channelMasks) { for (auto sampleRate : sampleRates) { diff --git a/audio/core/all-versions/vts/functional/DeviceManager.h b/audio/core/all-versions/vts/functional/DeviceManager.h index 0c0727f283..6efed7991e 100644 --- a/audio/core/all-versions/vts/functional/DeviceManager.h +++ b/audio/core/all-versions/vts/functional/DeviceManager.h @@ -14,10 +14,11 @@ * limitations under the License. */ -// Code in this file uses 'environment' -#ifndef AUDIO_PRIMARY_HIDL_HAL_TEST -#error Must be included from AudioPrimaryHidlTest.h -#endif +#pragma once + +// Note: it is assumed that this file is included from AudioPrimaryHidlTest.h +// and thus it doesn't have all '#include' and 'using' directives required +// for a standalone compilation. template class InterfaceManager { diff --git a/audio/core/all-versions/vts/functional/PolicyConfig.h b/audio/core/all-versions/vts/functional/PolicyConfig.h new file mode 100644 index 0000000000..c9e0c0dd5a --- /dev/null +++ b/audio/core/all-versions/vts/functional/PolicyConfig.h @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +// Note: it is assumed that this file is included from AudioPrimaryHidlTest.h +// and thus it doesn't have all '#include' and 'using' directives required +// for a standalone compilation. + +#include + +struct PolicyConfigData { + android::HwModuleCollection hwModules; + android::DeviceVector availableOutputDevices; + android::DeviceVector availableInputDevices; + sp defaultOutputDevice; +}; + +class PolicyConfig : private PolicyConfigData, public android::AudioPolicyConfig { + public: + explicit PolicyConfig(const std::string& configFileName) + : android::AudioPolicyConfig(hwModules, availableOutputDevices, availableInputDevices, + defaultOutputDevice), + mConfigFileName{configFileName} { + for (const auto& location : android::audio_get_configuration_paths()) { + std::string path = location + '/' + mConfigFileName; + if (access(path.c_str(), F_OK) == 0) { + mFilePath = path; + break; + } + } + mStatus = android::deserializeAudioPolicyFile(mFilePath.c_str(), this); + if (mStatus == OK) { + mPrimaryModule = getModuleFromName(DeviceManager::kPrimaryDevice); + // Available devices are not 'attached' to modules at this moment. + // Need to go over available devices and find their module. + for (const auto& device : availableOutputDevices) { + for (const auto& module : hwModules) { + if (module->getDeclaredDevices().indexOf(device) >= 0) { + mModulesWithDevicesNames.insert(module->getName()); + break; + } + } + } + for (const auto& device : availableInputDevices) { + for (const auto& module : hwModules) { + if (module->getDeclaredDevices().indexOf(device) >= 0) { + mModulesWithDevicesNames.insert(module->getName()); + break; + } + } + } + } + } + status_t getStatus() const { return mStatus; } + std::string getError() const { + if (mFilePath.empty()) { + return std::string{"Could not find "} + mConfigFileName + + " file in: " + testing::PrintToString(android::audio_get_configuration_paths()); + } else { + return "Invalid config file: " + mFilePath; + } + } + const std::string& getFilePath() const { return mFilePath; } + sp getModuleFromName(const std::string& name) const { + return getHwModules().getModuleFromName(name.c_str()); + } + sp getPrimaryModule() const { return mPrimaryModule; } + const std::set& getModulesWithDevicesNames() const { + return mModulesWithDevicesNames; + } + bool haveInputProfilesInModule(const std::string& name) const { + auto module = getModuleFromName(name); + return module && !module->getInputProfiles().empty(); + } + + private: + const std::string mConfigFileName; + status_t mStatus = NO_INIT; + std::string mFilePath; + sp mPrimaryModule = nullptr; + std::set mModulesWithDevicesNames; +}; diff --git a/audio/effect/all-versions/vts/functional/Android.bp b/audio/effect/all-versions/vts/functional/Android.bp index 7cdb18f95f..f4a72834d5 100644 --- a/audio/effect/all-versions/vts/functional/Android.bp +++ b/audio/effect/all-versions/vts/functional/Android.bp @@ -118,7 +118,6 @@ cc_test { } cc_test { - enabled: false, name: "VtsHalAudioEffectV7_0TargetTest", defaults: ["VtsHalAudioEffectTargetTest_default"], // Use test_config for vts suite. @@ -126,6 +125,7 @@ cc_test { test_config: "VtsHalAudioEffectV7_0TargetTest.xml", static_libs: [ "android.hardware.audio.common@7.0", + "android.hardware.audio.common@7.0-enums", "android.hardware.audio.effect@7.0", ], data: [ diff --git a/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp b/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp index 4787c091b2..b64f105eb4 100644 --- a/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp +++ b/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp @@ -16,7 +16,9 @@ #define LOG_TAG "AudioEffectHidlHalTest" #include +#if MAJOR_VERSION <= 6 #include +#endif #include PATH(android/hardware/audio/effect/FILE_VERSION/IEffect.h) #include PATH(android/hardware/audio/effect/FILE_VERSION/IEffectsFactory.h) @@ -25,6 +27,10 @@ #include PATH(android/hardware/audio/effect/FILE_VERSION/types.h) #include #include +#if MAJOR_VERSION >= 7 +#include +#include +#endif #include @@ -45,6 +51,12 @@ using ::android::hidl::allocator::V1_0::IAllocator; using ::android::hidl::memory::V1_0::IMemory; using namespace ::android::hardware::audio::common::CPP_VERSION; using namespace ::android::hardware::audio::effect::CPP_VERSION; +#if MAJOR_VERSION >= 7 +// Make an alias for enumerations generated from the APM config XSD. +namespace xsd { +using namespace ::audio::policy::configuration::CPP_VERSION; +} +#endif #ifndef ARRAY_SIZE #define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a))) @@ -171,7 +183,7 @@ class AudioEffectHidlTest : public ::testing::TestWithParam { effectsFactory = IEffectsFactory::getService(std::get(GetParam())); ASSERT_NE(nullptr, effectsFactory.get()); - findAndCreateEffect(getEffectType()); + ASSERT_NO_FATAL_FAILURE(findAndCreateEffect(getEffectType())); ASSERT_NE(nullptr, effect.get()); Return ret = effect->init(); @@ -201,7 +213,7 @@ class AudioEffectHidlTest : public ::testing::TestWithParam { void AudioEffectHidlTest::findAndCreateEffect(const Uuid& type) { Uuid effectUuid; - findEffectInstance(type, &effectUuid); + ASSERT_NO_FATAL_FAILURE(findEffectInstance(type, &effectUuid)); Return ret = effectsFactory->createEffect( effectUuid, 1 /*session*/, 1 /*ioHandle*/, #if MAJOR_VERSION >= 6 @@ -244,10 +256,16 @@ void AudioEffectHidlTest::getChannelCount(uint32_t* channelCount) { }); ASSERT_TRUE(ret.isOk()); ASSERT_EQ(Result::OK, retval); +#if MAJOR_VERSION <= 6 ASSERT_TRUE(audio_channel_mask_is_valid( static_cast(currentConfig.outputCfg.channels))); *channelCount = audio_channel_count_from_out_mask( static_cast(currentConfig.outputCfg.channels)); +#else + *channelCount = + audio::policy::configuration::V7_0::getChannelCount(currentConfig.outputCfg.channels); + ASSERT_NE(*channelCount, 0); +#endif } TEST_P(AudioEffectHidlTest, Close) { @@ -391,7 +409,12 @@ TEST_P(AudioEffectHidlTest, DisableEnableDisable) { TEST_P(AudioEffectHidlTest, SetDevice) { description("Verify that SetDevice works for an output chain effect"); +#if MAJOR_VERSION <= 6 Return ret = effect->setDevice(mkEnumBitfield(AudioDevice::OUT_SPEAKER)); +#else + DeviceAddress device{.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_SPEAKER)}; + Return ret = effect->setDevice(device); +#endif EXPECT_TRUE(ret.isOk()); EXPECT_EQ(Result::OK, ret); } @@ -441,22 +464,28 @@ TEST_P(AudioEffectHidlTest, SetConfigReverse) { TEST_P(AudioEffectHidlTest, SetInputDevice) { description("Verify that SetInputDevice does not crash"); +#if MAJOR_VERSION <= 6 Return ret = effect->setInputDevice(mkEnumBitfield(AudioDevice::IN_BUILTIN_MIC)); +#else + DeviceAddress device{.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_IN_BUILTIN_MIC)}; + Return ret = effect->setInputDevice(device); +#endif EXPECT_TRUE(ret.isOk()); } TEST_P(AudioEffectHidlTest, SetAudioSource) { description("Verify that SetAudioSource does not crash"); +#if MAJOR_VERSION <= 6 Return ret = effect->setAudioSource(AudioSource::MIC); +#else + Return ret = effect->setAudioSource(toString(xsd::AudioSource::AUDIO_SOURCE_MIC)); +#endif EXPECT_TRUE(ret.isOk()); } TEST_P(AudioEffectHidlTest, Offload) { description("Verify that calling Offload method does not crash"); - EffectOffloadParameter offloadParam; - offloadParam.isOffload = false; - offloadParam.ioHandle = static_cast(AudioHandleConsts::AUDIO_IO_HANDLE_NONE); - Return ret = effect->offload(offloadParam); + Return ret = effect->offload(EffectOffloadParameter{}); EXPECT_TRUE(ret.isOk()); } From 94ab03a3a264934009272f6ad13a615bdd7efdc4 Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Wed, 30 Sep 2020 00:09:16 +0000 Subject: [PATCH 5/5] Remove PREUPLOAD.cfg from audio HAL example As suggested by the comment on ag/12691153 Bug: 142480271 Test: N/A Change-Id: Ic9e2b986d3f9734dd884a2c88ca86d251147126b Merged-In: Ic9e2b986d3f9734dd884a2c88ca86d251147126b --- audio/common/7.0/example/PREUPLOAD.cfg | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 audio/common/7.0/example/PREUPLOAD.cfg diff --git a/audio/common/7.0/example/PREUPLOAD.cfg b/audio/common/7.0/example/PREUPLOAD.cfg deleted file mode 100644 index 6b7fd7137c..0000000000 --- a/audio/common/7.0/example/PREUPLOAD.cfg +++ /dev/null @@ -1,2 +0,0 @@ -[Builtin Hooks] -clang_format = true