Merge "composer: hold a sp<IComposer> from the service itself"
diff --git a/audio/7.0/IDevice.hal b/audio/7.0/IDevice.hal
index eecd92e..e30e545 100644
--- a/audio/7.0/IDevice.hal
+++ b/audio/7.0/IDevice.hal
@@ -117,7 +117,7 @@
AudioIoHandle ioHandle,
DeviceAddress device,
AudioConfig config,
- bitfield<AudioOutputFlag> flags,
+ vec<AudioInOutFlag> flags,
SourceMetadata sourceMetadata) generates (
Result retval,
IStreamOut outStream,
@@ -142,7 +142,7 @@
AudioIoHandle ioHandle,
DeviceAddress device,
AudioConfig config,
- bitfield<AudioInputFlag> flags,
+ vec<AudioInOutFlag> flags,
SinkMetadata sinkMetadata) generates (
Result retval,
IStreamIn inStream,
diff --git a/audio/7.0/IStream.hal b/audio/7.0/IStream.hal
index 789cb1d..4fe8218 100644
--- a/audio/7.0/IStream.hal
+++ b/audio/7.0/IStream.hal
@@ -44,49 +44,23 @@
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<uint32_t> 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<vec<AudioChannelMask>> 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<AudioFormat> formats);
+ getSupportedProfiles()
+ generates (Result retval, vec<AudioProfile> profiles);
/**
* Retrieves basic stream configuration: sample rate, audio format,
@@ -94,18 +68,18 @@
*
* @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/IStreamOut.hal b/audio/7.0/IStreamOut.hal
index 38d750f..0951a9e 100644
--- a/audio/7.0/IStreamOut.hal
+++ b/audio/7.0/IStreamOut.hal
@@ -271,8 +271,6 @@
* timestamp must correspond to N rather than N+M. The terms 'recent' and
* 'small' are not defined. They reflect the quality of the implementation.
*
- * Optional method
- *
* @return retval operation completion status.
* @return frames count of presented audio frames.
* @return timeStamp associated clock time.
diff --git a/audio/7.0/config/api/current.txt b/audio/7.0/config/api/current.txt
index fd9a8ef..ac8dc8a 100644
--- a/audio/7.0/config/api/current.txt
+++ b/audio/7.0/config/api/current.txt
@@ -228,6 +228,33 @@
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 @@
public static class MixPorts.MixPort {
ctor public MixPorts.MixPort();
- method public String getFlags();
+ method public java.util.List<audio.policy.configuration.V7_0.AudioInOutFlag> getFlags();
method public audio.policy.configuration.V7_0.Gains getGains();
method public long getMaxActiveCount();
method public long getMaxOpenCount();
@@ -404,7 +431,7 @@
method public java.util.List<audio.policy.configuration.V7_0.AudioUsage> getPreferredUsage();
method public java.util.List<audio.policy.configuration.V7_0.Profile> getProfile();
method public audio.policy.configuration.V7_0.Role getRole();
- method public void setFlags(String);
+ method public void setFlags(java.util.List<audio.policy.configuration.V7_0.AudioInOutFlag>);
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 4555a88..20fe020 100644
--- a/audio/7.0/config/audio_policy_configuration.xsd
+++ b/audio/7.0/config/audio_policy_configuration.xsd
@@ -155,16 +155,41 @@
<xs:element name="item" type="xs:token" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
- <xs:simpleType name="audioInOutFlags">
+ <xs:simpleType name="audioInOutFlag">
<xs:annotation>
<xs:documentation xml:lang="en">
- "|" separated list of audio_output_flags_t or audio_input_flags_t.
+ The flags indicate suggested stream attributes supported by the profile.
</xs:documentation>
</xs:annotation>
<xs:restriction base="xs:string">
- <xs:pattern value="|[_A-Z]+(\|[_A-Z]+)*"/>
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_DIRECT" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_PRIMARY" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_FAST" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_DEEP_BUFFER" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_NON_BLOCKING" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_HW_AV_SYNC" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_TTS" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_RAW" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_SYNC" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_DIRECT_PCM" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_MMAP_NOIRQ" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_VOIP_RX" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_INCALL_MUSIC" />
+ <xs:enumeration value="AUDIO_INPUT_FLAG_FAST" />
+ <xs:enumeration value="AUDIO_INPUT_FLAG_HW_HOTWORD" />
+ <xs:enumeration value="AUDIO_INPUT_FLAG_RAW" />
+ <xs:enumeration value="AUDIO_INPUT_FLAG_SYNC" />
+ <xs:enumeration value="AUDIO_INPUT_FLAG_MMAP_NOIRQ" />
+ <xs:enumeration value="AUDIO_INPUT_FLAG_VOIP_TX" />
+ <xs:enumeration value="AUDIO_INPUT_FLAG_HW_AV_SYNC" />
+ <xs:enumeration value="AUDIO_INPUT_FLAG_DIRECT" />
</xs:restriction>
</xs:simpleType>
+ <xs:simpleType name="audioInOutFlags">
+ <xs:list itemType="audioInOutFlag" />
+ </xs:simpleType>
<xs:simpleType name="role">
<xs:restriction base="xs:string">
<xs:enumeration value="sink"/>
diff --git a/audio/7.0/config/update_audio_policy_config.sh b/audio/7.0/config/update_audio_policy_config.sh
index 8714b5f..051a0df 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 @@
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 15ca492..4a9e289 100644
--- a/audio/7.0/types.hal
+++ b/audio/7.0/types.hal
@@ -357,56 +357,15 @@
};
/**
- * 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/README b/audio/README
deleted file mode 100644
index afafbe3..0000000
--- 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 0000000..b77b9ba
--- /dev/null
+++ b/audio/README.md
@@ -0,0 +1,53 @@
+# 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.
+ - ...
+ - `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
+ 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.
diff --git a/audio/common/7.0/Android.bp b/audio/common/7.0/Android.bp
index e24871c..1c016b4 100644
--- a/audio/common/7.0/Android.bp
+++ b/audio/common/7.0/Android.bp
@@ -16,9 +16,12 @@
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 0000000..d5fedce
--- /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 <sys/types.h>
+
+#include <audio_policy_configuration_V7_0.h>
+
+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/common/7.0/example/Android.bp b/audio/common/7.0/example/Android.bp
new file mode 100644
index 0000000..03c1cd8
--- /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 0000000..ddd5fef
--- /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 <log/log.h>
+
+#include "DevicesFactory.h"
+
+using ::android::hardware::hidl_string;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+
+namespace android::hardware::audio::V7_0::implementation {
+
+Return<void> DevicesFactory::openDevice(const hidl_string& device, openDevice_cb _hidl_cb) {
+ (void)device;
+ _hidl_cb(Result::INVALID_ARGUMENTS, nullptr);
+ return Void();
+}
+
+Return<void> 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 0000000..00f665c
--- /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 <android/hardware/audio/7.0/IDevicesFactory.h>
+
+namespace android::hardware::audio::V7_0::implementation {
+
+class DevicesFactory : public IDevicesFactory {
+ public:
+ DevicesFactory() = default;
+
+ ::android::hardware::Return<void> openDevice(const ::android::hardware::hidl_string& device,
+ openDevice_cb _hidl_cb) override;
+
+ ::android::hardware::Return<void> 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 0000000..423754d
--- /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 <log/log.h>
+
+#include <audio_policy_configuration_V7_0.h>
+
+#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<Result> Effect::init() {
+ return Result::OK;
+}
+
+Return<Result> Effect::setConfig(
+ const EffectConfig& config,
+ const ::android::sp<IEffectBufferProviderCallback>& inputBufferProvider,
+ const ::android::sp<IEffectBufferProviderCallback>& outputBufferProvider) {
+ (void)config;
+ (void)inputBufferProvider;
+ (void)outputBufferProvider;
+ return Result::OK;
+}
+
+Return<Result> Effect::reset() {
+ return Result::OK;
+}
+
+Return<Result> Effect::enable() {
+ if (!mEnabled) {
+ mEnabled = true;
+ return Result::OK;
+ } else {
+ return Result::NOT_SUPPORTED;
+ }
+}
+
+Return<Result> Effect::disable() {
+ if (mEnabled) {
+ mEnabled = false;
+ return Result::OK;
+ } else {
+ return Result::NOT_SUPPORTED;
+ }
+}
+
+Return<Result> Effect::setDevice(const DeviceAddress& device) {
+ (void)device;
+ return Result::OK;
+}
+
+Return<void> Effect::setAndGetVolume(const hidl_vec<uint32_t>& volumes,
+ setAndGetVolume_cb _hidl_cb) {
+ (void)volumes;
+ _hidl_cb(Result::OK, hidl_vec<uint32_t>{});
+ return Void();
+}
+
+Return<Result> Effect::volumeChangeNotification(const hidl_vec<uint32_t>& volumes) {
+ (void)volumes;
+ return Result::OK;
+}
+
+Return<Result> Effect::setAudioMode(AudioMode mode) {
+ (void)mode;
+ return Result::OK;
+}
+
+Return<Result> Effect::setConfigReverse(
+ const EffectConfig& config,
+ const ::android::sp<IEffectBufferProviderCallback>& inputBufferProvider,
+ const ::android::sp<IEffectBufferProviderCallback>& outputBufferProvider) {
+ (void)config;
+ (void)inputBufferProvider;
+ (void)outputBufferProvider;
+ return Result::OK;
+}
+
+Return<Result> Effect::setInputDevice(const DeviceAddress& device) {
+ (void)device;
+ return Result::OK;
+}
+
+Return<void> 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<void> Effect::getConfigReverse(getConfigReverse_cb _hidl_cb) {
+ _hidl_cb(Result::OK, EffectConfig{});
+ return Void();
+}
+
+Return<void> Effect::getSupportedAuxChannelsConfigs(uint32_t maxConfigs,
+ getSupportedAuxChannelsConfigs_cb _hidl_cb) {
+ (void)maxConfigs;
+ _hidl_cb(Result::OK, hidl_vec<EffectAuxChannelsConfig>{});
+ return Void();
+}
+
+Return<void> Effect::getAuxChannelsConfig(getAuxChannelsConfig_cb _hidl_cb) {
+ _hidl_cb(Result::OK, EffectAuxChannelsConfig{});
+ return Void();
+}
+
+Return<Result> Effect::setAuxChannelsConfig(const EffectAuxChannelsConfig& config) {
+ (void)config;
+ return Result::OK;
+}
+
+Return<Result> Effect::setAudioSource(const hidl_string& source) {
+ (void)source;
+ return Result::OK;
+}
+
+Return<Result> Effect::offload(const EffectOffloadParameter& param) {
+ (void)param;
+ return Result::OK;
+}
+
+Return<void> Effect::getDescriptor(getDescriptor_cb _hidl_cb) {
+ _hidl_cb(Result::OK, mDescriptor);
+ return Void();
+}
+
+Return<void> Effect::prepareForProcessing(prepareForProcessing_cb _hidl_cb) {
+ _hidl_cb(Result::OK, MQDescriptor<Result, kSynchronizedReadWrite>{});
+ return Void();
+}
+
+Return<Result> Effect::setProcessBuffers(const AudioBuffer& inBuffer,
+ const AudioBuffer& outBuffer) {
+ (void)inBuffer;
+ (void)outBuffer;
+ return Result::OK;
+}
+
+Return<void> Effect::command(uint32_t commandId, const hidl_vec<uint8_t>& data,
+ uint32_t resultMaxSize, command_cb _hidl_cb) {
+ (void)commandId;
+ (void)data;
+ (void)resultMaxSize;
+ _hidl_cb(-EINVAL, hidl_vec<uint8_t>{});
+ return Void();
+}
+
+Return<Result> Effect::setParameter(const hidl_vec<uint8_t>& parameter,
+ const hidl_vec<uint8_t>& value) {
+ (void)parameter;
+ (void)value;
+ return Result::OK;
+}
+
+Return<void> Effect::getParameter(const hidl_vec<uint8_t>& parameter, uint32_t valueMaxSize,
+ getParameter_cb _hidl_cb) {
+ (void)parameter;
+ (void)valueMaxSize;
+ _hidl_cb(Result::OK, hidl_vec<uint8_t>{});
+ return Void();
+}
+
+Return<void> 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<uint8_t>{});
+ return Void();
+}
+
+Return<void> Effect::getCurrentConfigForFeature(uint32_t featureId, uint32_t configSize,
+ getCurrentConfigForFeature_cb _hidl_cb) {
+ (void)featureId;
+ (void)configSize;
+ _hidl_cb(Result::OK, hidl_vec<uint8_t>{});
+ return Void();
+}
+
+Return<Result> Effect::setCurrentConfigForFeature(uint32_t featureId,
+ const hidl_vec<uint8_t>& configData) {
+ (void)featureId;
+ (void)configData;
+ return Result::OK;
+}
+
+Return<Result> 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 0000000..fa7f41b
--- /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 <android/hardware/audio/effect/7.0/IEffect.h>
+
+namespace android::hardware::audio::effect::V7_0::implementation {
+
+class Effect : public IEffect {
+ public:
+ explicit Effect(const EffectDescriptor& descriptor) : mDescriptor(descriptor) {}
+
+ ::android::hardware::Return<Result> init() override;
+ ::android::hardware::Return<Result> setConfig(
+ const EffectConfig& config,
+ const ::android::sp<IEffectBufferProviderCallback>& inputBufferProvider,
+ const ::android::sp<IEffectBufferProviderCallback>& outputBufferProvider) override;
+ ::android::hardware::Return<Result> reset() override;
+ ::android::hardware::Return<Result> enable() override;
+ ::android::hardware::Return<Result> disable() override;
+ ::android::hardware::Return<Result> setDevice(
+ const ::android::hardware::audio::common::V7_0::DeviceAddress& device) override;
+ ::android::hardware::Return<void> setAndGetVolume(
+ const ::android::hardware::hidl_vec<uint32_t>& volumes,
+ setAndGetVolume_cb _hidl_cb) override;
+ ::android::hardware::Return<Result> volumeChangeNotification(
+ const ::android::hardware::hidl_vec<uint32_t>& volumes) override;
+ ::android::hardware::Return<Result> setAudioMode(
+ ::android::hardware::audio::common::V7_0::AudioMode mode) override;
+ ::android::hardware::Return<Result> setConfigReverse(
+ const EffectConfig& config,
+ const ::android::sp<IEffectBufferProviderCallback>& inputBufferProvider,
+ const ::android::sp<IEffectBufferProviderCallback>& outputBufferProvider) override;
+ ::android::hardware::Return<Result> setInputDevice(
+ const ::android::hardware::audio::common::V7_0::DeviceAddress& device) override;
+ ::android::hardware::Return<void> getConfig(getConfig_cb _hidl_cb) override;
+ ::android::hardware::Return<void> getConfigReverse(getConfigReverse_cb _hidl_cb) override;
+ ::android::hardware::Return<void> getSupportedAuxChannelsConfigs(
+ uint32_t maxConfigs, getSupportedAuxChannelsConfigs_cb _hidl_cb) override;
+ ::android::hardware::Return<void> getAuxChannelsConfig(
+ getAuxChannelsConfig_cb _hidl_cb) override;
+ ::android::hardware::Return<Result> setAuxChannelsConfig(
+ const EffectAuxChannelsConfig& config) override;
+ ::android::hardware::Return<Result> setAudioSource(
+ const ::android::hardware::hidl_string& source) override;
+ ::android::hardware::Return<Result> offload(const EffectOffloadParameter& param) override;
+ ::android::hardware::Return<void> getDescriptor(getDescriptor_cb _hidl_cb) override;
+ ::android::hardware::Return<void> prepareForProcessing(
+ prepareForProcessing_cb _hidl_cb) override;
+ ::android::hardware::Return<Result> setProcessBuffers(const AudioBuffer& inBuffer,
+ const AudioBuffer& outBuffer) override;
+ ::android::hardware::Return<void> command(uint32_t commandId,
+ const ::android::hardware::hidl_vec<uint8_t>& data,
+ uint32_t resultMaxSize, command_cb _hidl_cb) override;
+ ::android::hardware::Return<Result> setParameter(
+ const ::android::hardware::hidl_vec<uint8_t>& parameter,
+ const ::android::hardware::hidl_vec<uint8_t>& value) override;
+ ::android::hardware::Return<void> getParameter(
+ const ::android::hardware::hidl_vec<uint8_t>& parameter, uint32_t valueMaxSize,
+ getParameter_cb _hidl_cb) override;
+ ::android::hardware::Return<void> getSupportedConfigsForFeature(
+ uint32_t featureId, uint32_t maxConfigs, uint32_t configSize,
+ getSupportedConfigsForFeature_cb _hidl_cb) override;
+ ::android::hardware::Return<void> getCurrentConfigForFeature(
+ uint32_t featureId, uint32_t configSize,
+ getCurrentConfigForFeature_cb _hidl_cb) override;
+ ::android::hardware::Return<Result> setCurrentConfigForFeature(
+ uint32_t featureId, const ::android::hardware::hidl_vec<uint8_t>& configData) override;
+ ::android::hardware::Return<Result> 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 0000000..7d333ae
--- /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 <log/log.h>
+
+#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<void> EffectsFactory::getAllDescriptors(getAllDescriptors_cb _hidl_cb) {
+ hidl_vec<EffectDescriptor> descriptors;
+ descriptors.resize(2);
+ descriptors[0] = EqualizerEffect::getDescriptor();
+ descriptors[1] = LoudnessEnhancerEffect::getDescriptor();
+ _hidl_cb(Result::OK, descriptors);
+ return Void();
+}
+
+Return<void> 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<void> 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<void> EffectsFactory::debug(const hidl_handle& fd, const hidl_vec<hidl_string>& 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 0000000..8fec70c
--- /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 <android/hardware/audio/effect/7.0/IEffectsFactory.h>
+
+namespace android::hardware::audio::effect::V7_0::implementation {
+
+class EffectsFactory : public IEffectsFactory {
+ public:
+ EffectsFactory() = default;
+
+ ::android::hardware::Return<void> getAllDescriptors(getAllDescriptors_cb _hidl_cb) override;
+ ::android::hardware::Return<void> getDescriptor(
+ const ::android::hardware::audio::common::V7_0::Uuid& uuid,
+ getDescriptor_cb _hidl_cb) override;
+ ::android::hardware::Return<void> 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<void>
+ 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 0000000..c93c5a9
--- /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 <limits>
+
+#define LOG_TAG "EffectsFactory7.0"
+#include <log/log.h>
+
+#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<uint8_t, 6>{{0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}},
+ .uuid = {0, 0, 0, 1, std::array<uint8_t, 6>{{0, 0, 0, 0, 0, 0}}}};
+ return descriptor;
+}
+
+EqualizerEffect::EqualizerEffect() : mEffect(new Effect(getDescriptor())) {
+ mProperties.bandLevels.resize(kNumBands);
+}
+
+Return<void> EqualizerEffect::getNumBands(getNumBands_cb _hidl_cb) {
+ _hidl_cb(Result::OK, kNumBands);
+ return Void();
+}
+
+Return<void> EqualizerEffect::getLevelRange(getLevelRange_cb _hidl_cb) {
+ _hidl_cb(Result::OK, std::numeric_limits<int16_t>::min(), std::numeric_limits<int16_t>::max());
+ return Void();
+}
+
+Return<Result> EqualizerEffect::setBandLevel(uint16_t band, int16_t level) {
+ if (band < kNumBands) {
+ mProperties.bandLevels[band] = level;
+ return Result::OK;
+ } else {
+ return Result::INVALID_ARGUMENTS;
+ }
+}
+
+Return<void> 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<void> EqualizerEffect::getBandCenterFrequency(uint16_t band,
+ getBandCenterFrequency_cb _hidl_cb) {
+ (void)band;
+ _hidl_cb(Result::OK, 0);
+ return Void();
+}
+
+Return<void> EqualizerEffect::getBandFrequencyRange(uint16_t band,
+ getBandFrequencyRange_cb _hidl_cb) {
+ (void)band;
+ _hidl_cb(Result::OK, 0, 1);
+ return Void();
+}
+
+Return<void> EqualizerEffect::getBandForFrequency(uint32_t freq, getBandForFrequency_cb _hidl_cb) {
+ (void)freq;
+ _hidl_cb(Result::OK, 0);
+ return Void();
+}
+
+Return<void> EqualizerEffect::getPresetNames(getPresetNames_cb _hidl_cb) {
+ hidl_vec<hidl_string> presetNames;
+ presetNames.resize(kNumPresets);
+ presetNames[0] = "default";
+ _hidl_cb(Result::OK, presetNames);
+ return Void();
+}
+
+Return<Result> EqualizerEffect::setCurrentPreset(uint16_t preset) {
+ if (preset < kNumPresets) {
+ mProperties.curPreset = preset;
+ return Result::OK;
+ } else {
+ return Result::INVALID_ARGUMENTS;
+ }
+}
+
+Return<void> EqualizerEffect::getCurrentPreset(getCurrentPreset_cb _hidl_cb) {
+ _hidl_cb(Result::OK, mProperties.curPreset);
+ return Void();
+}
+
+Return<Result> EqualizerEffect::setAllProperties(
+ const IEqualizerEffect::AllProperties& properties) {
+ mProperties = properties;
+ return Result::OK;
+}
+
+Return<void> 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 0000000..11853c3
--- /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 <android/hardware/audio/effect/7.0/IEqualizerEffect.h>
+
+#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<Result> init() override { return mEffect->init(); }
+ ::android::hardware::Return<Result> setConfig(
+ const EffectConfig& config,
+ const ::android::sp<IEffectBufferProviderCallback>& inputBufferProvider,
+ const ::android::sp<IEffectBufferProviderCallback>& outputBufferProvider) override {
+ return mEffect->setConfig(config, inputBufferProvider, outputBufferProvider);
+ }
+ ::android::hardware::Return<Result> reset() override { return mEffect->reset(); }
+ ::android::hardware::Return<Result> enable() override { return mEffect->enable(); }
+ ::android::hardware::Return<Result> disable() override { return mEffect->disable(); }
+ ::android::hardware::Return<Result> setDevice(
+ const ::android::hardware::audio::common::V7_0::DeviceAddress& device) override {
+ return mEffect->setDevice(device);
+ }
+ ::android::hardware::Return<void> setAndGetVolume(
+ const ::android::hardware::hidl_vec<uint32_t>& volumes,
+ setAndGetVolume_cb _hidl_cb) override {
+ return mEffect->setAndGetVolume(volumes, _hidl_cb);
+ }
+ ::android::hardware::Return<Result> volumeChangeNotification(
+ const ::android::hardware::hidl_vec<uint32_t>& volumes) override {
+ return mEffect->volumeChangeNotification(volumes);
+ }
+ ::android::hardware::Return<Result> setAudioMode(
+ ::android::hardware::audio::common::V7_0::AudioMode mode) override {
+ return mEffect->setAudioMode(mode);
+ }
+ ::android::hardware::Return<Result> setConfigReverse(
+ const EffectConfig& config,
+ const ::android::sp<IEffectBufferProviderCallback>& inputBufferProvider,
+ const ::android::sp<IEffectBufferProviderCallback>& outputBufferProvider) override {
+ return mEffect->setConfigReverse(config, inputBufferProvider, outputBufferProvider);
+ }
+ ::android::hardware::Return<Result> setInputDevice(
+ const ::android::hardware::audio::common::V7_0::DeviceAddress& device) override {
+ return mEffect->setInputDevice(device);
+ }
+ ::android::hardware::Return<void> getConfig(getConfig_cb _hidl_cb) override {
+ return mEffect->getConfig(_hidl_cb);
+ }
+ ::android::hardware::Return<void> getConfigReverse(getConfigReverse_cb _hidl_cb) override {
+ return mEffect->getConfigReverse(_hidl_cb);
+ }
+ ::android::hardware::Return<void> getSupportedAuxChannelsConfigs(
+ uint32_t maxConfigs, getSupportedAuxChannelsConfigs_cb _hidl_cb) override {
+ return mEffect->getSupportedAuxChannelsConfigs(maxConfigs, _hidl_cb);
+ }
+ ::android::hardware::Return<void> getAuxChannelsConfig(
+ getAuxChannelsConfig_cb _hidl_cb) override {
+ return mEffect->getAuxChannelsConfig(_hidl_cb);
+ }
+ ::android::hardware::Return<Result> setAuxChannelsConfig(
+ const EffectAuxChannelsConfig& config) override {
+ return mEffect->setAuxChannelsConfig(config);
+ }
+ ::android::hardware::Return<Result> setAudioSource(
+ const ::android::hardware::hidl_string& source) override {
+ return mEffect->setAudioSource(source);
+ }
+ ::android::hardware::Return<Result> offload(const EffectOffloadParameter& param) override {
+ return mEffect->offload(param);
+ }
+ ::android::hardware::Return<void> getDescriptor(getDescriptor_cb _hidl_cb) override {
+ return mEffect->getDescriptor(_hidl_cb);
+ }
+ ::android::hardware::Return<void> prepareForProcessing(
+ prepareForProcessing_cb _hidl_cb) override {
+ return mEffect->prepareForProcessing(_hidl_cb);
+ }
+ ::android::hardware::Return<Result> setProcessBuffers(const AudioBuffer& inBuffer,
+ const AudioBuffer& outBuffer) override {
+ return mEffect->setProcessBuffers(inBuffer, outBuffer);
+ }
+ ::android::hardware::Return<void> command(uint32_t commandId,
+ const ::android::hardware::hidl_vec<uint8_t>& data,
+ uint32_t resultMaxSize,
+ command_cb _hidl_cb) override {
+ return mEffect->command(commandId, data, resultMaxSize, _hidl_cb);
+ }
+ ::android::hardware::Return<Result> setParameter(
+ const ::android::hardware::hidl_vec<uint8_t>& parameter,
+ const ::android::hardware::hidl_vec<uint8_t>& value) override {
+ return mEffect->setParameter(parameter, value);
+ }
+ ::android::hardware::Return<void> getParameter(
+ const ::android::hardware::hidl_vec<uint8_t>& parameter, uint32_t valueMaxSize,
+ getParameter_cb _hidl_cb) override {
+ return mEffect->getParameter(parameter, valueMaxSize, _hidl_cb);
+ }
+ ::android::hardware::Return<void> 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<void> getCurrentConfigForFeature(
+ uint32_t featureId, uint32_t configSize,
+ getCurrentConfigForFeature_cb _hidl_cb) override {
+ return mEffect->getCurrentConfigForFeature(featureId, configSize, _hidl_cb);
+ }
+ ::android::hardware::Return<Result> setCurrentConfigForFeature(
+ uint32_t featureId, const ::android::hardware::hidl_vec<uint8_t>& configData) override {
+ return mEffect->setCurrentConfigForFeature(featureId, configData);
+ }
+ ::android::hardware::Return<Result> close() override { return mEffect->close(); }
+
+ // Methods from IEqualizerEffect interface.
+ ::android::hardware::Return<void> getNumBands(getNumBands_cb _hidl_cb) override;
+ ::android::hardware::Return<void> getLevelRange(getLevelRange_cb _hidl_cb) override;
+ ::android::hardware::Return<Result> setBandLevel(uint16_t band, int16_t level) override;
+ ::android::hardware::Return<void> getBandLevel(uint16_t band,
+ getBandLevel_cb _hidl_cb) override;
+ ::android::hardware::Return<void> getBandCenterFrequency(
+ uint16_t band, getBandCenterFrequency_cb _hidl_cb) override;
+ ::android::hardware::Return<void> getBandFrequencyRange(
+ uint16_t band, getBandFrequencyRange_cb _hidl_cb) override;
+ ::android::hardware::Return<void> getBandForFrequency(uint32_t freq,
+ getBandForFrequency_cb _hidl_cb) override;
+ ::android::hardware::Return<void> getPresetNames(getPresetNames_cb _hidl_cb) override;
+ ::android::hardware::Return<Result> setCurrentPreset(uint16_t preset) override;
+ ::android::hardware::Return<void> getCurrentPreset(getCurrentPreset_cb _hidl_cb) override;
+ ::android::hardware::Return<Result> setAllProperties(
+ const IEqualizerEffect::AllProperties& properties) override;
+ ::android::hardware::Return<void> getAllProperties(getAllProperties_cb _hidl_cb) override;
+
+ private:
+ static constexpr size_t kNumBands = 1;
+ static constexpr size_t kNumPresets = 1;
+ sp<Effect> 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 0000000..38269b3
--- /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 <log/log.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 {
+
+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<uint8_t, 6>{{0x11, 0x26, 0x0e, 0xb6, 0x3c, 0xf1}}},
+ .uuid = {0, 0, 0, 2, std::array<uint8_t, 6>{{0, 0, 0, 0, 0, 0}}}};
+ return descriptor;
+} // namespace android::hardware::audio::effect::V7_0::implementation
+
+LoudnessEnhancerEffect::LoudnessEnhancerEffect() : mEffect(new Effect(getDescriptor())) {}
+
+Return<Result> LoudnessEnhancerEffect::setTargetGain(int32_t targetGainMb) {
+ mTargetGainMb = targetGainMb;
+ return Result::OK;
+}
+
+Return<void> 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 0000000..1af0d9f
--- /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 <android/hardware/audio/effect/7.0/ILoudnessEnhancerEffect.h>
+
+#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<Result> init() override { return mEffect->init(); }
+ ::android::hardware::Return<Result> setConfig(
+ const EffectConfig& config,
+ const ::android::sp<IEffectBufferProviderCallback>& inputBufferProvider,
+ const ::android::sp<IEffectBufferProviderCallback>& outputBufferProvider) override {
+ return mEffect->setConfig(config, inputBufferProvider, outputBufferProvider);
+ }
+ ::android::hardware::Return<Result> reset() override { return mEffect->reset(); }
+ ::android::hardware::Return<Result> enable() override { return mEffect->enable(); }
+ ::android::hardware::Return<Result> disable() override { return mEffect->disable(); }
+ ::android::hardware::Return<Result> setDevice(
+ const ::android::hardware::audio::common::V7_0::DeviceAddress& device) override {
+ return mEffect->setDevice(device);
+ }
+ ::android::hardware::Return<void> setAndGetVolume(
+ const ::android::hardware::hidl_vec<uint32_t>& volumes,
+ setAndGetVolume_cb _hidl_cb) override {
+ return mEffect->setAndGetVolume(volumes, _hidl_cb);
+ }
+ ::android::hardware::Return<Result> volumeChangeNotification(
+ const ::android::hardware::hidl_vec<uint32_t>& volumes) override {
+ return mEffect->volumeChangeNotification(volumes);
+ }
+ ::android::hardware::Return<Result> setAudioMode(
+ ::android::hardware::audio::common::V7_0::AudioMode mode) override {
+ return mEffect->setAudioMode(mode);
+ }
+ ::android::hardware::Return<Result> setConfigReverse(
+ const EffectConfig& config,
+ const ::android::sp<IEffectBufferProviderCallback>& inputBufferProvider,
+ const ::android::sp<IEffectBufferProviderCallback>& outputBufferProvider) override {
+ return mEffect->setConfigReverse(config, inputBufferProvider, outputBufferProvider);
+ }
+ ::android::hardware::Return<Result> setInputDevice(
+ const ::android::hardware::audio::common::V7_0::DeviceAddress& device) override {
+ return mEffect->setInputDevice(device);
+ }
+ ::android::hardware::Return<void> getConfig(getConfig_cb _hidl_cb) override {
+ return mEffect->getConfig(_hidl_cb);
+ }
+ ::android::hardware::Return<void> getConfigReverse(getConfigReverse_cb _hidl_cb) override {
+ return mEffect->getConfigReverse(_hidl_cb);
+ }
+ ::android::hardware::Return<void> getSupportedAuxChannelsConfigs(
+ uint32_t maxConfigs, getSupportedAuxChannelsConfigs_cb _hidl_cb) override {
+ return mEffect->getSupportedAuxChannelsConfigs(maxConfigs, _hidl_cb);
+ }
+ ::android::hardware::Return<void> getAuxChannelsConfig(
+ getAuxChannelsConfig_cb _hidl_cb) override {
+ return mEffect->getAuxChannelsConfig(_hidl_cb);
+ }
+ ::android::hardware::Return<Result> setAuxChannelsConfig(
+ const EffectAuxChannelsConfig& config) override {
+ return mEffect->setAuxChannelsConfig(config);
+ }
+ ::android::hardware::Return<Result> setAudioSource(
+ const ::android::hardware::hidl_string& source) override {
+ return mEffect->setAudioSource(source);
+ }
+ ::android::hardware::Return<Result> offload(const EffectOffloadParameter& param) override {
+ return mEffect->offload(param);
+ }
+ ::android::hardware::Return<void> getDescriptor(getDescriptor_cb _hidl_cb) override {
+ return mEffect->getDescriptor(_hidl_cb);
+ }
+ ::android::hardware::Return<void> prepareForProcessing(
+ prepareForProcessing_cb _hidl_cb) override {
+ return mEffect->prepareForProcessing(_hidl_cb);
+ }
+ ::android::hardware::Return<Result> setProcessBuffers(const AudioBuffer& inBuffer,
+ const AudioBuffer& outBuffer) override {
+ return mEffect->setProcessBuffers(inBuffer, outBuffer);
+ }
+ ::android::hardware::Return<void> command(uint32_t commandId,
+ const ::android::hardware::hidl_vec<uint8_t>& data,
+ uint32_t resultMaxSize,
+ command_cb _hidl_cb) override {
+ return mEffect->command(commandId, data, resultMaxSize, _hidl_cb);
+ }
+ ::android::hardware::Return<Result> setParameter(
+ const ::android::hardware::hidl_vec<uint8_t>& parameter,
+ const ::android::hardware::hidl_vec<uint8_t>& value) override {
+ return mEffect->setParameter(parameter, value);
+ }
+ ::android::hardware::Return<void> getParameter(
+ const ::android::hardware::hidl_vec<uint8_t>& parameter, uint32_t valueMaxSize,
+ getParameter_cb _hidl_cb) override {
+ return mEffect->getParameter(parameter, valueMaxSize, _hidl_cb);
+ }
+ ::android::hardware::Return<void> 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<void> getCurrentConfigForFeature(
+ uint32_t featureId, uint32_t configSize,
+ getCurrentConfigForFeature_cb _hidl_cb) override {
+ return mEffect->getCurrentConfigForFeature(featureId, configSize, _hidl_cb);
+ }
+ ::android::hardware::Return<Result> setCurrentConfigForFeature(
+ uint32_t featureId, const ::android::hardware::hidl_vec<uint8_t>& configData) override {
+ return mEffect->setCurrentConfigForFeature(featureId, configData);
+ }
+ ::android::hardware::Return<Result> close() override { return mEffect->close(); }
+
+ // Methods from ILoudnessEnhancerEffect interface.
+ ::android::hardware::Return<Result> setTargetGain(int32_t targetGainMb) override;
+ ::android::hardware::Return<void> getTargetGain(getTargetGain_cb _hidl_cb) override;
+
+ private:
+ sp<Effect> mEffect;
+ int32_t mTargetGainMb = 0;
+};
+
+} // namespace android::hardware::audio::effect::V7_0::implementation
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 0000000..cf8b51f
--- /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 0000000..b91b061
--- /dev/null
+++ b/audio/common/7.0/example/android.hardware.audio@7.0-service.example.xml
@@ -0,0 +1,20 @@
+<manifest version="1.0" type="device">
+ <hal format="hidl">
+ <name>android.hardware.audio</name>
+ <transport>hwbinder</transport>
+ <version>7.0</version>
+ <interface>
+ <name>IDevicesFactory</name>
+ <instance>example</instance>
+ </interface>
+ </hal>
+ <hal format="hidl">
+ <name>android.hardware.audio.effect</name>
+ <transport>hwbinder</transport>
+ <version>7.0</version>
+ <interface>
+ <name>IEffectsFactory</name>
+ <instance>example</instance>
+ </interface>
+ </hal>
+</manifest>
diff --git a/audio/common/7.0/example/service.cpp b/audio/common/7.0/example/service.cpp
new file mode 100644
index 0000000..641e2c9
--- /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 <hidl/HidlTransportSupport.h>
+#include <log/log.h>
+
+#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;
+}
diff --git a/audio/common/7.0/types.hal b/audio/common/7.0/types.hal
index 94d0af7..31c7388 100644
--- a/audio/common/7.0/types.hal
+++ b/audio/common/7.0/types.hal
@@ -112,12 +112,28 @@
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<AudioChannelMask> 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<uint32_t> 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<vec<AudioChannelMask>> channelMasks;
};
/**
@@ -137,17 +153,20 @@
};
/**
+ * 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 @@
* 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 @@
* Commonly used audio stream configuration parameters.
*/
struct AudioConfig {
- AudioBasicConfig base;
+ AudioConfigBase base;
AudioOffloadInfo offloadInfo;
uint64_t frameCount;
};
@@ -372,9 +391,9 @@
/**
* 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 @@
*/
string name;
/** List of audio profiles supported by the port. */
- struct AudioProfile {
- AudioFormat format;
- /** List of the sample rates supported by the profile. */
- vec<uint32_t> sampleRates;
- /** List of channel masks supported by the profile. */
- vec<AudioChannelMask> channelMasks;
- };
vec<AudioProfile> profiles;
/** List of gain controls attached to the port. */
vec<AudioGain> gains;
diff --git a/audio/common/all-versions/default/VersionUtils.h b/audio/common/all-versions/default/VersionUtils.h
index e7755b1..9bfca0c 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::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<common::CPP_VERSION::AudioDevice> AudioDeviceBitfield;
typedef hidl_bitfield<common::CPP_VERSION::AudioChannelMask> AudioChannelBitfield;
typedef hidl_bitfield<common::CPP_VERSION::AudioOutputFlag> 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 b0e72d9..907acd7 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_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;
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 b0eb2e0..2466fd1 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 <audio_policy_configuration_V7_0.h>
+#include <xsdc/XsdcSupport.h>
+
+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 @@
"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>(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<hidl_string> 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<IStreamIn> stream;
@@ -81,16 +103,16 @@
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, 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 @@
}
// 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 @@
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_P(InputStreamTest, updateSinkMetadata) {
doc::test("The HAL should not crash on metadata change");
+#if MAJOR_VERSION <= 6
hidl_enum_range<AudioSource> range;
+#elif MAJOR_VERSION >= 7
+ xsdc_enum_range<audio::policy::configuration::V7_0::AudioSource> 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, updateSourceMetadata) {
doc::test("The HAL should not crash on metadata change");
+#if MAJOR_VERSION <= 6
hidl_enum_range<AudioUsage> usageRange;
hidl_enum_range<AudioContentType> contentRange;
+#elif MAJOR_VERSION >= 7
+ xsdc_enum_range<audio::policy::configuration::V7_0::AudioUsage> usageRange;
+ xsdc_enum_range<audio::policy::configuration::V7_0::AudioContentType> 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 @@
}
}
+ // 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 7a52d0e..81a1f7b 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 @@
}
};
+#if MAJOR_VERSION <= 6
struct GetSupported {
static auto getFormat(IStream* stream) {
auto ret = stream->getFormat();
@@ -80,7 +81,7 @@
EXPECT_OK(stream->getSupportedFormats(returnIn(capabilities)));
return Result::OK;
}
-#elif MAJOR_VERSION >= 6
+#else // MAJOR_VERSION == 6
static Result formats(IStream* stream, hidl_vec<AudioFormat>& capabilities) {
Result res;
EXPECT_OK(stream->getSupportedFormats(returnIn(res, capabilities)));
@@ -88,6 +89,7 @@
}
#endif
};
+#endif // MAJOR_VERSION <= 6
template <class T>
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 54d4bbd..bd8de2d 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<DeviceConfigParameter>& getOutputDeviceConfigParameters() {
static std::vector<DeviceConfigParameter> parameters = [] {
std::vector<DeviceConfigParameter> result;
@@ -28,8 +29,8 @@
const auto& channels = profile->getChannels();
const auto& sampleRates = profile->getSampleRates();
auto configs = ConfigHelper::combineAudioConfig(
- vector<audio_channel_mask_t>(channels.begin(), channels.end()),
- vector<uint32_t>(sampleRates.begin(), sampleRates.end()),
+ std::vector<audio_channel_mask_t>(channels.begin(), channels.end()),
+ std::vector<uint32_t>(sampleRates.begin(), sampleRates.end()),
profile->getFormat());
auto flags = ioProfile->getFlags();
for (auto& config : configs) {
@@ -46,8 +47,8 @@
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 auto& channels = profile->getChannels();
const auto& sampleRates = profile->getSampleRates();
auto configs = ConfigHelper::combineAudioConfig(
- vector<audio_channel_mask_t>(channels.begin(), channels.end()),
- vector<uint32_t>(sampleRates.begin(), sampleRates.end()),
+ std::vector<audio_channel_mask_t>(channels.begin(), channels.end()),
+ std::vector<uint32_t>(sampleRates.begin(), sampleRates.end()),
profile->getFormat());
for (const auto& config : configs) {
result.emplace_back(device, config, AudioInputFlag(ioProfile->getFlags()));
@@ -87,13 +88,22 @@
}();
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>(AudioOutputFlag::NONE);
SourceMetadata initMetadata = {{{AudioUsage::MEDIA, AudioContentType::MUSIC, 1 /* gain */}}};
+ auto flags = hidl_bitfield<AudioOutputFlag>(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<AudioInOutFlag> flags;
+#endif
+ AudioConfig config{};
sp<IStreamOut> stream;
StreamHelper<IStreamOut> helper(stream);
AudioConfig suggestedConfig{};
@@ -111,14 +121,20 @@
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>(AudioInputFlag::NONE);
SinkMetadata initMetadata = {{{.source = AudioSource::MIC, .gain = 1}}};
+ auto flags = hidl_bitfield<AudioInputFlag>(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<AudioInOutFlag> flags;
+#endif
+ AudioConfig config{};
sp<IStreamIn> stream;
StreamHelper<IStreamIn> helper(stream);
AudioConfig suggestedConfig{};
@@ -137,9 +153,8 @@
TEST_P(AudioPatchHidlTest, UpdatePatchInvalidHandle) {
doc::test("Verify that passing an invalid handle to updateAudioPatch is checked");
AudioPatchHandle ignored;
- ASSERT_OK(getDevice()->updateAudioPatch(
- static_cast<int32_t>(AudioHandleConsts::AUDIO_PATCH_HANDLE_NONE),
- hidl_vec<AudioPortConfig>(), hidl_vec<AudioPortConfig>(), returnIn(res, ignored)));
+ ASSERT_OK(getDevice()->updateAudioPatch(AudioPatchHandle{}, hidl_vec<AudioPortConfig>(),
+ hidl_vec<AudioPortConfig>(), 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 33efa6f..63eaea8 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<AudioConfig> combineAudioConfig(std::vector<xsd::AudioChannelMask> channelMasks,
+ std::vector<int64_t> sampleRates,
+ const std::string& format) {
+ std::vector<AudioConfig> 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<DeviceConfigParameter>& getOutputDeviceConfigParameters() {
+ static std::vector<DeviceConfigParameter> parameters = [] {
+ std::vector<DeviceConfigParameter> result;
+ const std::vector<AudioInOutFlag> 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<PARAM_DEVICE_NAME>(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<AudioInOutFlag> 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<DeviceConfigParameter>& getInputDeviceConfigParameters() {
+ static std::vector<DeviceConfigParameter> parameters = [] {
+ std::vector<DeviceConfigParameter> result;
+ for (const auto& device : getDeviceParameters()) {
+ auto module =
+ getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
+ for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) {
+ if (mixPort.getRole() != xsd::Role::sink) continue; // not an input profile
+ std::vector<AudioInOutFlag> 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 0000000..d790b34
--- /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<std::string>& 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<xsd::AudioPolicyConfiguration> mConfig;
+ status_t mStatus = NO_INIT;
+ const xsd::Module* mPrimaryModule;
+ std::set<std::string> mModulesWithDevicesNames;
+};
diff --git a/audio/core/all-versions/vts/functional/Android.bp b/audio/core/all-versions/vts/functional/Android.bp
index 6ac9b20..c7bfe08 100644
--- a/audio/core/all-versions/vts/functional/Android.bp
+++ b/audio/core/all-versions/vts/functional/Android.bp
@@ -19,9 +19,6 @@
defaults: ["VtsHalTargetTestDefaults"],
static_libs: [
"android.hardware.audio.common.test.utility",
- "libaudiofoundation",
- "libaudiopolicycomponents",
- "libmedia_helper",
"libxml2",
],
shared_libs: [
@@ -44,6 +41,9 @@
"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 @@
"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 @@
"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 @@
"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 {
- enabled: false,
name: "VtsHalAudioV7_0TargetTest",
defaults: ["VtsHalAudioTargetTest_defaults"],
srcs: [
@@ -139,6 +147,7 @@
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 01bdd69..5e4b414 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 <audio_policy_configuration_V7_0-enums.h>
+#include <audio_policy_configuration_V7_0.h>
+#endif
-#include <Serializer.h>
#include <fmq/EventFlag.h>
#include <fmq/MessageQueue.h>
#include <hidl/GtestPrinter.h>
@@ -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 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 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 @@
////////////////////////// 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<android::DeviceDescriptor> 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<const HwModule> getModuleFromName(const std::string& name) const {
- return getHwModules().getModuleFromName(name.c_str());
- }
- sp<const HwModule> getPrimaryModule() const { return mPrimaryModule; }
- const std::set<std::string>& getModulesWithDevicesNames() const {
- return mModulesWithDevicesNames;
- }
-
- private:
- status_t mStatus = NO_INIT;
- std::string mFilePath;
- sp<HwModule> mPrimaryModule = nullptr;
- std::set<std::string> 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> policyConfig = [] {
- auto config = std::make_unique<PolicyConfig>();
+ auto config = std::make_unique<PolicyConfig>(kConfigFileName);
return config;
}();
return *policyConfig;
@@ -449,9 +387,10 @@
* The getter and/or the setter may return NOT_SUPPORTED if optionality == OPTIONAL.
*/
template <Optionality optionality = REQUIRED, class IUTGetter, class Getter, class Setter>
- void testAccessors(IUTGetter iutGetter, const string& propertyName,
- const Initial expectedInitial, list<Property> valuesToTest, Setter setter,
- Getter getter, const vector<Property>& invalidValues = {}) {
+ void testAccessors(IUTGetter iutGetter, const std::string& propertyName,
+ const Initial expectedInitial, std::list<Property> valuesToTest,
+ Setter setter, Getter getter,
+ const std::vector<Property>& invalidValues = {}) {
const auto expectedResults = {Result::OK,
optionality == OPTIONAL ? Result::NOT_SUPPORTED : Result::OK};
@@ -495,9 +434,9 @@
EXPECT_RESULT(expectedResults, ((this->*iutGetter)().get()->*setter)(initialValue));
}
template <Optionality optionality = REQUIRED, class Getter, class Setter>
- void testAccessors(const string& propertyName, const Initial expectedInitial,
- list<Property> valuesToTest, Setter setter, Getter getter,
- const vector<Property>& invalidValues = {}) {
+ void testAccessors(const std::string& propertyName, const Initial expectedInitial,
+ std::list<Property> valuesToTest, Setter setter, Getter getter,
+ const std::vector<Property>& invalidValues = {}) {
testAccessors<optionality>(&BaseTestClass::getDevice, propertyName, expectedInitial,
valuesToTest, setter, getter, invalidValues);
}
@@ -573,9 +512,13 @@
// 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<DeviceParameter, AudioConfig, std::variant<AudioInputFlag, AudioOutputFlag>>;
+#elif MAJOR_VERSION >= 7
+using DeviceConfigParameter = std::tuple<DeviceParameter, AudioConfig, std::vector<AudioInOutFlag>>;
+#endif
#if MAJOR_VERSION >= 6
const std::vector<DeviceConfigParameter>& getInputDeviceConfigParameters();
@@ -583,8 +526,8 @@
#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 @@
* 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<DeviceConfigParameter>& info) {
const AudioConfig& config = std::get<PARAM_CONFIG>(info.param);
const auto deviceName = DeviceParameterToString(::testing::TestParamInfo<DeviceParameter>{
std::get<PARAM_DEVICE>(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))
+ 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<PARAM_FLAGS>(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<decltype(arg)>;
+ // Need to use FQN of toString to avoid confusing the compiler
+ return ::android::hardware::audio::common::CPP_VERSION::toString<T>(
+ hidl_bitfield<T>(arg));
+ },
+ std::get<PARAM_FLAGS>(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<PARAM_FLAGS>(info.param)));
#endif
- ) +
- "_" +
-#if MAJOR_VERSION == 2
- std::visit([](auto&& arg) -> std::string { return ::testing::PrintToString(arg); },
- std::get<PARAM_FLAGS>(info.param));
-#elif MAJOR_VERSION >= 4
- SanitizeStringForGTestName(std::visit(
- [](auto&& arg) -> std::string {
- using T = std::decay_t<decltype(arg)>;
- // Need to use FQN of toString to avoid confusing the compiler
- return ::android::hardware::audio::common::CPP_VERSION::toString<T>(
- hidl_bitfield<T>(arg));
- },
- std::get<PARAM_FLAGS>(info.param)));
-#endif
+ return devicePart + "__" + configPart;
}
class AudioHidlTestWithDeviceConfigParameter
@@ -660,7 +617,7 @@
AudioOutputFlag getOutputFlags() const {
return std::get<INDEX_OUTPUT>(std::get<PARAM_FLAGS>(GetParam()));
}
-#elif MAJOR_VERSION >= 4
+#elif MAJOR_VERSION >= 4 && MAJOR_VERSION <= 6
hidl_bitfield<AudioInputFlag> getInputFlags() const {
return hidl_bitfield<AudioInputFlag>(
std::get<INDEX_INPUT>(std::get<PARAM_FLAGS>(GetParam())));
@@ -669,10 +626,17 @@
return hidl_bitfield<AudioOutputFlag>(
std::get<INDEX_OUTPUT>(std::get<PARAM_FLAGS>(GetParam())));
}
+#elif MAJOR_VERSION >= 7
+ hidl_vec<AudioInOutFlag> getInputFlags() const { return std::get<PARAM_FLAGS>(GetParam()); }
+ hidl_vec<AudioInOutFlag> getOutputFlags() const { return std::get<PARAM_FLAGS>(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 @@
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 OutputStreamTest : public OpenStreamTest<IStreamOut> {
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 @@
},
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 @@
class InputStreamTest : public OpenStreamTest<IStreamIn> {
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 @@
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 @@
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(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 @@
ASSERT_GE(extract(stream->getBufferSize()), extract(stream->getFrameSize())));
template <class Property, class CapabilityGetter>
-static void testCapabilityGetter(const string& name, IStream* stream,
+static void testCapabilityGetter(const std::string& name, IStream* stream,
CapabilityGetter capabilityGetter,
Return<Property> (IStream::*getter)(),
Return<Result> (IStream::*setter)(Property),
@@ -1120,6 +1103,7 @@
}
}
+#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(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<AudioProfile> 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<AudioProfile> 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<AudioChannelMask>({});
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 @@
ASSERT_RESULT(okOrNotSupportedOrInvalidArgs, stream->setHwAvSync(666)))
static void checkGetNoParameter(IStream* stream, hidl_vec<hidl_string> keys,
- initializer_list<Result> expectedResults) {
+ std::initializer_list<Result> expectedResults) {
hidl_vec<ParameterValue> parameters;
Result res;
ASSERT_OK(Parameters::get(stream, keys, returnIn(res, parameters)));
@@ -1271,7 +1307,11 @@
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<Return<Result>(float)> setGain) {
@@ -1286,7 +1326,7 @@
}
static void testOptionalUnitaryGain(std::function<Return<Result>(float)> setGain,
- string debugName) {
+ std::string debugName) {
auto result = setGain(1);
ASSERT_IS_OK(result);
if (result == Result::NOT_SUPPORTED) {
@@ -1306,7 +1346,7 @@
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 @@
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 8ef2b43..1a1dbea 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 @@
}
// Cache result ?
- static const vector<AudioConfig> getRequiredSupportPlaybackAudioConfig() {
+ static const std::vector<AudioConfig> getRequiredSupportPlaybackAudioConfig() {
return combineAudioConfig({AudioChannelMask::OUT_STEREO, AudioChannelMask::OUT_MONO},
{8000, 11025, 16000, 22050, 32000, 44100},
{AudioFormat::PCM_16_BIT});
}
- static const vector<AudioConfig> getRecommendedSupportPlaybackAudioConfig() {
+ static const std::vector<AudioConfig> getRecommendedSupportPlaybackAudioConfig() {
return combineAudioConfig({AudioChannelMask::OUT_STEREO, AudioChannelMask::OUT_MONO},
{24000, 48000}, {AudioFormat::PCM_16_BIT});
}
- static const vector<AudioConfig> getRequiredSupportCaptureAudioConfig() {
+ static const std::vector<AudioConfig> getRequiredSupportCaptureAudioConfig() {
if (!primaryHasMic()) return {};
return combineAudioConfig({AudioChannelMask::IN_MONO}, {8000, 11025, 16000, 44100},
{AudioFormat::PCM_16_BIT});
}
- static const vector<AudioConfig> getRecommendedSupportCaptureAudioConfig() {
+ static const std::vector<AudioConfig> getRecommendedSupportCaptureAudioConfig() {
if (!primaryHasMic()) return {};
return combineAudioConfig({AudioChannelMask::IN_STEREO}, {22050, 48000},
{AudioFormat::PCM_16_BIT});
}
- static vector<AudioConfig> combineAudioConfig(vector<audio_channel_mask_t> channelMasks,
- vector<uint32_t> sampleRates,
- audio_format_t format) {
- vector<AudioConfig> configs;
+ static std::vector<AudioConfig> combineAudioConfig(
+ std::vector<audio_channel_mask_t> channelMasks, std::vector<uint32_t> sampleRates,
+ audio_format_t format) {
+ std::vector<AudioConfig> configs;
configs.reserve(channelMasks.size() * sampleRates.size());
for (auto channelMask : channelMasks) {
for (auto sampleRate : sampleRates) {
@@ -86,10 +88,10 @@
return configs;
}
- static vector<AudioConfig> combineAudioConfig(vector<AudioChannelMask> channelMasks,
- vector<uint32_t> sampleRates,
- vector<AudioFormat> formats) {
- vector<AudioConfig> configs;
+ static std::vector<AudioConfig> combineAudioConfig(std::vector<AudioChannelMask> channelMasks,
+ std::vector<uint32_t> sampleRates,
+ std::vector<AudioFormat> formats) {
+ std::vector<AudioConfig> 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 0c0727f..6efed79 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 Derived, class Key, class Interface>
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 0000000..c9e0c0d
--- /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 <Serializer.h>
+
+struct PolicyConfigData {
+ android::HwModuleCollection hwModules;
+ android::DeviceVector availableOutputDevices;
+ android::DeviceVector availableInputDevices;
+ sp<android::DeviceDescriptor> 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<const android::HwModule> getModuleFromName(const std::string& name) const {
+ return getHwModules().getModuleFromName(name.c_str());
+ }
+ sp<const android::HwModule> getPrimaryModule() const { return mPrimaryModule; }
+ const std::set<std::string>& 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<const android::HwModule> mPrimaryModule = nullptr;
+ std::set<std::string> mModulesWithDevicesNames;
+};
diff --git a/audio/effect/all-versions/vts/functional/Android.bp b/audio/effect/all-versions/vts/functional/Android.bp
index 7cdb18f..f4a7283 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 {
- enabled: false,
name: "VtsHalAudioEffectV7_0TargetTest",
defaults: ["VtsHalAudioEffectTargetTest_default"],
// Use test_config for vts suite.
@@ -126,6 +125,7 @@
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 4787c09..b64f105 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 <android-base/logging.h>
+#if MAJOR_VERSION <= 6
#include <system/audio.h>
+#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 <android/hidl/allocator/1.0/IAllocator.h>
#include <android/hidl/memory/1.0/IMemory.h>
+#if MAJOR_VERSION >= 7
+#include <audio_policy_configuration_V7_0-enums.h>
+#include <audio_policy_configuration_V7_0.h>
+#endif
#include <common/all-versions/VersionUtils.h>
@@ -45,6 +51,12 @@
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 @@
effectsFactory = IEffectsFactory::getService(std::get<PARAM_FACTORY_NAME>(GetParam()));
ASSERT_NE(nullptr, effectsFactory.get());
- findAndCreateEffect(getEffectType());
+ ASSERT_NO_FATAL_FAILURE(findAndCreateEffect(getEffectType()));
ASSERT_NE(nullptr, effect.get());
Return<Result> ret = effect->init();
@@ -201,7 +213,7 @@
void AudioEffectHidlTest::findAndCreateEffect(const Uuid& type) {
Uuid effectUuid;
- findEffectInstance(type, &effectUuid);
+ ASSERT_NO_FATAL_FAILURE(findEffectInstance(type, &effectUuid));
Return<void> ret = effectsFactory->createEffect(
effectUuid, 1 /*session*/, 1 /*ioHandle*/,
#if MAJOR_VERSION >= 6
@@ -244,10 +256,16 @@
});
ASSERT_TRUE(ret.isOk());
ASSERT_EQ(Result::OK, retval);
+#if MAJOR_VERSION <= 6
ASSERT_TRUE(audio_channel_mask_is_valid(
static_cast<audio_channel_mask_t>(currentConfig.outputCfg.channels)));
*channelCount = audio_channel_count_from_out_mask(
static_cast<audio_channel_mask_t>(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, SetDevice) {
description("Verify that SetDevice works for an output chain effect");
+#if MAJOR_VERSION <= 6
Return<Result> ret = effect->setDevice(mkEnumBitfield(AudioDevice::OUT_SPEAKER));
+#else
+ DeviceAddress device{.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_SPEAKER)};
+ Return<Result> ret = effect->setDevice(device);
+#endif
EXPECT_TRUE(ret.isOk());
EXPECT_EQ(Result::OK, ret);
}
@@ -441,22 +464,28 @@
TEST_P(AudioEffectHidlTest, SetInputDevice) {
description("Verify that SetInputDevice does not crash");
+#if MAJOR_VERSION <= 6
Return<Result> ret = effect->setInputDevice(mkEnumBitfield(AudioDevice::IN_BUILTIN_MIC));
+#else
+ DeviceAddress device{.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_IN_BUILTIN_MIC)};
+ Return<Result> 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<Result> ret = effect->setAudioSource(AudioSource::MIC);
+#else
+ Return<Result> 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<int>(AudioHandleConsts::AUDIO_IO_HANDLE_NONE);
- Return<Result> ret = effect->offload(offloadParam);
+ Return<Result> ret = effect->offload(EffectOffloadParameter{});
EXPECT_TRUE(ret.isOk());
}
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index bb26bd3..9400543 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -220,6 +220,13 @@
<instance>default</instance>
</interface>
</hal>
+ <hal format="aidl" optional="true">
+ <name>android.hardware.gnss</name>
+ <interface>
+ <name>IGnss</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
<hal format="hidl" optional="false">
<name>android.hardware.graphics.allocator</name>
<!-- New, non-Go devices should use 4.0, tested in vts_treble_vintf_vendor_test -->
diff --git a/current.txt b/current.txt
index 9c5091b..c9a923e 100644
--- a/current.txt
+++ b/current.txt
@@ -767,6 +767,7 @@
98592d193a717066facf91428426e5abe211e3bd718bc372e29fb944ddbe6e7c android.hardware.wifi.supplicant@1.3::types
# ABI preserving changes to HALs during Android S
+3da3ce039247872d95c6bd48621dbfdfa1c2d2a91a90f257862f87ee2bc46300 android.hardware.health@2.1::types
cd84ab19c590e0e73dd2307b591a3093ee18147ef95e6d5418644463a6620076 android.hardware.neuralnetworks@1.2::IDevice
9625e85f56515ad2cf87b6a1847906db669f746ea4ab02cd3d4ca25abc9b0109 android.hardware.neuralnetworks@1.2::types
9e758e208d14f7256e0885d6d8ad0b61121b21d8c313864f981727ae55bffd16 android.hardware.neuralnetworks@1.3::types
diff --git a/gnss/aidl/Android.bp b/gnss/aidl/Android.bp
new file mode 100644
index 0000000..c503190
--- /dev/null
+++ b/gnss/aidl/Android.bp
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+aidl_interface {
+ name: "android.hardware.gnss",
+ vendor_available: true,
+ srcs: ["android/hardware/gnss/*.aidl"],
+ stability: "vintf",
+ backend: {
+ java: {
+ platform_apis: true,
+ },
+ ndk: {
+ vndk: {
+ enabled: true,
+ },
+ },
+ },
+}
diff --git a/gnss/aidl/OWNERS b/gnss/aidl/OWNERS
new file mode 100644
index 0000000..b7b4a2e
--- /dev/null
+++ b/gnss/aidl/OWNERS
@@ -0,0 +1,4 @@
+gomo@google.com
+smalkos@google.com
+wyattriley@google.com
+yuhany@google.com
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
new file mode 100644
index 0000000..33377ca
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.gnss;
+@VintfStability
+interface IGnss {
+ android.hardware.gnss.IGnssPsds getExtensionPsds();
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsds.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsds.aidl
new file mode 100644
index 0000000..352a694
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsds.aidl
@@ -0,0 +1,23 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.gnss;
+@VintfStability
+interface IGnssPsds {
+ boolean injectPsdsData(in android.hardware.gnss.PsdsType psdsType, in byte[] psdsData);
+ boolean setCallback(in android.hardware.gnss.IGnssPsdsCallback callback);
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsdsCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsdsCallback.aidl
new file mode 100644
index 0000000..8413d2c
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsdsCallback.aidl
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.gnss;
+@VintfStability
+interface IGnssPsdsCallback {
+ void downloadRequestCb(in android.hardware.gnss.PsdsType psdsType);
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/PsdsType.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/PsdsType.aidl
new file mode 100644
index 0000000..9d1984e
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/PsdsType.aidl
@@ -0,0 +1,24 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.gnss;
+@Backing(type="int") @VintfStability
+enum PsdsType {
+ LONG_TERM = 1,
+ NORMAL = 2,
+ REALTIME = 3,
+}
diff --git a/gnss/aidl/android/hardware/gnss/IGnss.aidl b/gnss/aidl/android/hardware/gnss/IGnss.aidl
new file mode 100644
index 0000000..1da254c
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/IGnss.aidl
@@ -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.
+ */
+
+package android.hardware.gnss;
+
+import android.hardware.gnss.IGnssPsds;
+
+/**
+ * Represents the standard GNSS (Global Navigation Satellite System) interface.
+ */
+@VintfStability
+interface IGnss {
+
+ /**
+ * This method returns the IGnssPsds interface.
+ *
+ * @return Handle to the IGnssPsds interface.
+ */
+ IGnssPsds getExtensionPsds();
+}
\ No newline at end of file
diff --git a/gnss/aidl/android/hardware/gnss/IGnssPsds.aidl b/gnss/aidl/android/hardware/gnss/IGnssPsds.aidl
new file mode 100644
index 0000000..6f53d6f
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/IGnssPsds.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gnss;
+
+import android.hardware.gnss.IGnssPsdsCallback;
+import android.hardware.gnss.PsdsType;
+
+/**
+ * This interface is used by the GNSS HAL to request the framework to download Predicted Satellite
+ * Data Service data.
+ */
+@VintfStability
+interface IGnssPsds {
+
+ /**
+ * Inject the downloaded PSDS data into the GNSS receiver.
+ *
+ * @param psdsType Type of PSDS data.
+ * @param psdsData GNSS PSDS data. Framework must not parse the data since the data format is
+ * opaque to framework.
+ *
+ * @return True if the operation is successful.
+ */
+ boolean injectPsdsData(in PsdsType psdsType, in byte[] psdsData);
+
+ /**
+ * Opens the PSDS interface and provides the callback routines to the implementation of this
+ * interface.
+ *
+ * @param callback Handle to the IGnssPsdsCallback interface.
+ *
+ * @return True if the operation is successful.
+ */
+ boolean setCallback(in IGnssPsdsCallback callback);
+}
\ No newline at end of file
diff --git a/gnss/aidl/android/hardware/gnss/IGnssPsdsCallback.aidl b/gnss/aidl/android/hardware/gnss/IGnssPsdsCallback.aidl
new file mode 100644
index 0000000..72b693b
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/IGnssPsdsCallback.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gnss;
+
+import android.hardware.gnss.PsdsType;
+
+/**
+ * This interface is used by the GNSS HAL to request download data from Predicted Satellite Data
+ * Service (PSDS).
+ */
+@VintfStability
+interface IGnssPsdsCallback {
+
+ /**
+ * Callback to request the client to download PSDS data from one of the URLs defined in the
+ * framework specified by psdsType. The URLs must be specified via properties on the vendor
+ * partitions. E.g., LONGTERM_PSDS_SERVER_1, NORMAL_PSDS_SERVER, or REALTIME_PSDS_SERVER. The
+ * client must download PSDS data and inject it by calling injectPsdsData().
+ *
+ * @param psdsType Type of PSDS data.
+ */
+ void downloadRequestCb(in PsdsType psdsType);
+}
\ No newline at end of file
diff --git a/gnss/aidl/android/hardware/gnss/PsdsType.aidl b/gnss/aidl/android/hardware/gnss/PsdsType.aidl
new file mode 100644
index 0000000..d4fec77
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/PsdsType.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gnss;
+
+/** The type of PSDS data. */
+@VintfStability
+@Backing(type="int")
+enum PsdsType {
+
+ /**
+ * Long-Term type PSDS data, which lasts for many hours to several days and often provides
+ * satellite orbit and clock accuracy of 2 - 20 meters.
+ */
+ LONG_TERM = 1,
+
+ /**
+ * Normal type PSDS data, which is similar to broadcast ephemeris in longevity - lasting for
+ * hours and providings satellite orbit and clock accuracy of 1 - 2 meters.
+ */
+ NORMAL = 2,
+
+ /**
+ * Real-Time type PSDS data, which lasts for minutes and provides brief satellite status
+ * information such as temporary malfunction, but does not include satellite orbit or clock
+ * information.
+ */
+ REALTIME = 3,
+}
diff --git a/gnss/aidl/default/Android.bp b/gnss/aidl/default/Android.bp
new file mode 100644
index 0000000..8c4ee40
--- /dev/null
+++ b/gnss/aidl/default/Android.bp
@@ -0,0 +1,38 @@
+/*
+ * 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.gnss-service.example",
+ relative_install_path: "hw",
+ init_rc: ["gnss-default.rc"],
+ vintf_fragments: ["gnss-default.xml"],
+ vendor: true,
+ cflags: [
+ "-Wall",
+ "-Wextra",
+ ],
+ shared_libs: [
+ "libbase",
+ "libbinder_ndk",
+ "liblog",
+ "android.hardware.gnss-ndk_platform",
+ ],
+ srcs: [
+ "Gnss.cpp",
+ "GnssPsds.cpp",
+ "service.cpp",
+ ],
+}
diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp
new file mode 100644
index 0000000..2a35924
--- /dev/null
+++ b/gnss/aidl/default/Gnss.cpp
@@ -0,0 +1,31 @@
+/*
+ * 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 "GnssAidl"
+
+#include "Gnss.h"
+#include <log/log.h>
+#include "GnssPsds.h"
+
+namespace aidl::android::hardware::gnss {
+
+ndk::ScopedAStatus Gnss::getExtensionPsds(std::shared_ptr<IGnssPsds>* iGnssPsds) {
+ ALOGD("Gnss::getExtensionPsds");
+ *iGnssPsds = SharedRefBase::make<GnssPsds>();
+ return ndk::ScopedAStatus::ok();
+}
+
+} // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/Gnss.h b/gnss/aidl/default/Gnss.h
new file mode 100644
index 0000000..9864e9d
--- /dev/null
+++ b/gnss/aidl/default/Gnss.h
@@ -0,0 +1,28 @@
+/*
+ * 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 <aidl/android/hardware/gnss/BnGnss.h>
+#include <aidl/android/hardware/gnss/BnGnssPsds.h>
+
+namespace aidl::android::hardware::gnss {
+
+class Gnss : public BnGnss {
+ ndk::ScopedAStatus getExtensionPsds(std::shared_ptr<IGnssPsds>* iGnssPsds) override;
+};
+
+} // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/GnssPsds.cpp b/gnss/aidl/default/GnssPsds.cpp
new file mode 100644
index 0000000..c354217
--- /dev/null
+++ b/gnss/aidl/default/GnssPsds.cpp
@@ -0,0 +1,43 @@
+/*
+ * 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 "GnssPsdsAidl"
+
+#include "GnssPsds.h"
+
+#include <log/log.h>
+
+namespace aidl::android::hardware::gnss {
+
+std::shared_ptr<IGnssPsdsCallback> GnssPsds::sCallback = nullptr;
+
+ndk::ScopedAStatus GnssPsds::setCallback(const std::shared_ptr<IGnssPsdsCallback>& callback,
+ bool* success) {
+ ALOGD("setCallback");
+ std::unique_lock<std::mutex> lock(mMutex);
+ sCallback = callback;
+ *success = true;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus GnssPsds::injectPsdsData(PsdsType psdsType, const std::vector<uint8_t>& psdsData,
+ bool* success) {
+ ALOGD("injectPsdsData. psdsType: %d, psdsData: %d bytes", static_cast<int>(psdsType),
+ static_cast<int>(psdsData.size()));
+ *success = (psdsData.size() > 0);
+ return ndk::ScopedAStatus::ok();
+}
+} // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/GnssPsds.h b/gnss/aidl/default/GnssPsds.h
new file mode 100644
index 0000000..fc65bc1
--- /dev/null
+++ b/gnss/aidl/default/GnssPsds.h
@@ -0,0 +1,38 @@
+/*
+ * 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 <aidl/android/hardware/gnss/BnGnssPsds.h>
+
+namespace aidl::android::hardware::gnss {
+
+struct GnssPsds : public BnGnssPsds {
+ public:
+ ndk::ScopedAStatus setCallback(const std::shared_ptr<IGnssPsdsCallback>& callback,
+ bool* success) override;
+ ndk::ScopedAStatus injectPsdsData(PsdsType psdsType, const std::vector<uint8_t>& psdsData,
+ bool* success) override;
+
+ private:
+ // Guarded by mMutex
+ static std::shared_ptr<IGnssPsdsCallback> sCallback;
+
+ // Synchronization lock for sCallback
+ mutable std::mutex mMutex;
+};
+
+} // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/gnss-default.rc b/gnss/aidl/default/gnss-default.rc
new file mode 100644
index 0000000..fe179c3
--- /dev/null
+++ b/gnss/aidl/default/gnss-default.rc
@@ -0,0 +1,4 @@
+service vendor.gnss-default /vendor/bin/hw/android.hardware.gnss-service.example
+ class hal
+ user nobody
+ group nobody
diff --git a/gnss/aidl/default/gnss-default.xml b/gnss/aidl/default/gnss-default.xml
new file mode 100644
index 0000000..2b06cd2
--- /dev/null
+++ b/gnss/aidl/default/gnss-default.xml
@@ -0,0 +1,9 @@
+<manifest version="1.0" type="device">
+ <hal format="aidl">
+ <name>android.hardware.gnss</name>
+ <interface>
+ <name>IGnss</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+</manifest>
diff --git a/gnss/aidl/default/service.cpp b/gnss/aidl/default/service.cpp
new file mode 100644
index 0000000..c79a271
--- /dev/null
+++ b/gnss/aidl/default/service.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright 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 "Gnss.h"
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+using aidl::android::hardware::gnss::Gnss;
+
+int main() {
+ ABinderProcess_setThreadPoolMaxThreadCount(0);
+ std::shared_ptr<Gnss> vib = ndk::SharedRefBase::make<Gnss>();
+
+ const std::string instance = std::string() + Gnss::descriptor + "/default";
+ binder_status_t status = AServiceManager_addService(vib->asBinder().get(), instance.c_str());
+ CHECK(status == STATUS_OK);
+
+ ABinderProcess_joinThreadPool();
+ return EXIT_FAILURE; // should not reach
+}
diff --git a/gnss/aidl/vts/Android.bp b/gnss/aidl/vts/Android.bp
new file mode 100644
index 0000000..e57b421
--- /dev/null
+++ b/gnss/aidl/vts/Android.bp
@@ -0,0 +1,31 @@
+// 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_test {
+ name: "VtsHalGnssTargetTest",
+ defaults: [
+ "VtsHalTargetTestDefaults",
+ "use_libaidlvintf_gtest_helper_static",
+ ],
+ srcs: ["VtsHalGnssTargetTest.cpp"],
+ shared_libs: [
+ "libbinder",
+ ],
+ static_libs: [
+ "android.hardware.gnss-cpp",
+ ],
+ test_suites: [
+ "vts",
+ ],
+}
diff --git a/gnss/aidl/vts/VtsHalGnssTargetTest.cpp b/gnss/aidl/vts/VtsHalGnssTargetTest.cpp
new file mode 100644
index 0000000..e7ffc05
--- /dev/null
+++ b/gnss/aidl/vts/VtsHalGnssTargetTest.cpp
@@ -0,0 +1,77 @@
+/*
+ * 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 <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+
+#include <android/hardware/gnss/IGnss.h>
+#include <android/hardware/gnss/IGnssPsds.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+
+using android::ProcessState;
+using android::sp;
+using android::String16;
+using android::binder::Status;
+using android::hardware::gnss::IGnss;
+using android::hardware::gnss::IGnssPsds;
+using android::hardware::gnss::PsdsType;
+
+class GnssAidlHalTest : public testing::TestWithParam<std::string> {
+ public:
+ virtual void SetUp() override {
+ gnss_hal_ = android::waitForDeclaredService<IGnss>(String16(GetParam().c_str()));
+ ASSERT_NE(gnss_hal_, nullptr);
+ }
+
+ sp<IGnss> gnss_hal_;
+};
+
+/*
+ * SetupTeardownCreateCleanup:
+ * Requests the gnss HAL then calls cleanup
+ *
+ * Empty test fixture to verify basic Setup & Teardown
+ */
+TEST_P(GnssAidlHalTest, SetupTeardownCreateCleanup) {}
+
+/*
+ * TestPsdsExtension:
+ * 1. Gets the PsdsExtension and verifies that it returns a non-null extension.
+ * 2. Injects empty PSDS data and verifies that it returns false.
+ */
+TEST_P(GnssAidlHalTest, TestPsdsExtension) {
+ sp<IGnssPsds> iGnssPsds;
+ auto status = gnss_hal_->getExtensionPsds(&iGnssPsds);
+ ASSERT_TRUE(status.isOk());
+ ASSERT_TRUE(iGnssPsds != nullptr);
+
+ bool success;
+ status = iGnssPsds->injectPsdsData(PsdsType::LONG_TERM, std::vector<uint8_t>(), &success);
+ ASSERT_TRUE(status.isOk());
+ ASSERT_FALSE(success);
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GnssAidlHalTest);
+INSTANTIATE_TEST_SUITE_P(, GnssAidlHalTest,
+ testing::ValuesIn(android::getAidlHalInstanceNames(IGnss::descriptor)),
+ android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ ProcessState::self()->setThreadPoolMaxThreadCount(1);
+ ProcessState::self()->startThreadPool();
+ return RUN_ALL_TESTS();
+}
\ No newline at end of file
diff --git a/graphics/composer/2.1/utils/resources/include/composer-resources/2.1/ComposerResources.h b/graphics/composer/2.1/utils/resources/include/composer-resources/2.1/ComposerResources.h
index 3738278..df5513e 100644
--- a/graphics/composer/2.1/utils/resources/include/composer-resources/2.1/ComposerResources.h
+++ b/graphics/composer/2.1/utils/resources/include/composer-resources/2.1/ComposerResources.h
@@ -177,7 +177,8 @@
bool mustValidateDisplay(Display display);
// When a buffer in the cache is replaced by a new one, we must keep it
- // alive until it has been replaced in ComposerHal.
+ // alive until it has been replaced in ComposerHal because it is still using
+ // the old buffer.
class ReplacedHandle {
public:
explicit ReplacedHandle(bool isBuffer) : mIsBuffer(isBuffer) {}
diff --git a/health/2.1/types.hal b/health/2.1/types.hal
index d775491..6d7b661 100644
--- a/health/2.1/types.hal
+++ b/health/2.1/types.hal
@@ -98,9 +98,8 @@
/**
* Estimated battery full charge design capacity (in microamp hours, uAh).
* Value must be 0 if unknown.
- * Value must be positive if known.
- * Value must be greater than 100 000 uAh.
- * Value must be less than 100 000 000 uAh.
+ * Value must be greater than 100 000 uAh if known.
+ * Value must be less than 100 000 000 uAh if known.
*/
int32_t batteryFullChargeDesignCapacityUah;
};
diff --git a/health/2.1/vts/functional/VtsHalHealthV2_1TargetTest.cpp b/health/2.1/vts/functional/VtsHalHealthV2_1TargetTest.cpp
index d0b0d60..4ae443a 100644
--- a/health/2.1/vts/functional/VtsHalHealthV2_1TargetTest.cpp
+++ b/health/2.1/vts/functional/VtsHalHealthV2_1TargetTest.cpp
@@ -235,14 +235,15 @@
EXPECT_TRUE(IsEnum(value.batteryCapacityLevel)) << " BatteryCapacityLevel";
EXPECT_GE(value.batteryChargeTimeToFullNowSeconds, -1);
- EXPECT_GE(value.batteryFullChargeDesignCapacityUah, 0)
- << "batteryFullChargeDesignCapacityUah should not be negative";
+ if (value.batteryFullChargeDesignCapacityUah != 0) {
+ EXPECT_GT((long)value.batteryFullChargeDesignCapacityUah, FULL_CHARGE_DESIGN_CAP_MIN)
+ << "batteryFullChargeDesignCapacityUah should be greater than 100 mAh, or 0 if "
+ "unknown";
- EXPECT_GT((long)value.batteryFullChargeDesignCapacityUah, FULL_CHARGE_DESIGN_CAP_MIN)
- << "batteryFullChargeDesignCapacityUah should be greater than 100 mAh";
-
- EXPECT_LT((long)value.batteryFullChargeDesignCapacityUah, FULL_CHARGE_DESIGN_CAP_MAX)
- << "batteryFullChargeDesignCapacityUah should be less than 100,000 mAh";
+ EXPECT_LT((long)value.batteryFullChargeDesignCapacityUah, FULL_CHARGE_DESIGN_CAP_MAX)
+ << "batteryFullChargeDesignCapacityUah should be less than 100,000 mAh, or 0 "
+ "if unknown";
+ }
})));
}
diff --git a/tests/baz/1.0/IBase.hal b/tests/baz/1.0/IBase.hal
index 0c1b61f..7b60a8a 100644
--- a/tests/baz/1.0/IBase.hal
+++ b/tests/baz/1.0/IBase.hal
@@ -101,6 +101,8 @@
DoubleThreeDim double3;
};
+ isJava() generates (bool isJava);
+
someBaseMethod();
someBoolMethod(bool x) generates (bool y);
diff --git a/tests/baz/1.0/default/Baz.cpp b/tests/baz/1.0/default/Baz.cpp
index 2ce096c..0c3a59e 100644
--- a/tests/baz/1.0/default/Baz.cpp
+++ b/tests/baz/1.0/default/Baz.cpp
@@ -43,6 +43,12 @@
}
// Methods from ::android::hardware::tests::baz::V1_0::IBase follow.
+Return<bool> Baz::isJava() {
+ LOG(INFO) << "Baz::isJava";
+
+ return false;
+}
+
Return<void> Baz::someBaseMethod() {
LOG(INFO) << "Baz::someBaseMethod";
@@ -331,7 +337,7 @@
Return<IBaz::SomeEnum> Baz::useAnEnum(IBaz::SomeEnum zzz) {
LOG(INFO) << "useAnEnum " << (int)zzz;
- return SomeEnum::goober;
+ return SomeEnum::quux;
}
Return<void> Baz::haveSomeStrings(const hidl_array<hidl_string, 3>& array,
diff --git a/tests/baz/1.0/default/Baz.h b/tests/baz/1.0/default/Baz.h
index 1e24d52..38bbcad 100644
--- a/tests/baz/1.0/default/Baz.h
+++ b/tests/baz/1.0/default/Baz.h
@@ -27,6 +27,7 @@
struct Baz : public IBaz {
// Methods from ::android::hardware::tests::baz::V1_0::IBase follow.
+ Return<bool> isJava() override;
Return<void> someBaseMethod() override;
Return<bool> someBoolMethod(bool x) override;
Return<void> someBoolArrayMethod(const hidl_array<bool, 3>& x,
diff --git a/tests/msgq/1.0/default/Android.bp b/tests/msgq/1.0/default/Android.bp
index a5ba23d..9c1b3f9 100644
--- a/tests/msgq/1.0/default/Android.bp
+++ b/tests/msgq/1.0/default/Android.bp
@@ -79,7 +79,11 @@
suffix: "64",
},
},
- test_suites: ["device-tests"],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
+ auto_gen_config: false,
// Allow dlsym'ing self for statically linked passthrough implementations
ldflags: ["-rdynamic"],
diff --git a/tv/tuner/1.1/Android.bp b/tv/tuner/1.1/Android.bp
index 6cf47f5..daa3683 100644
--- a/tv/tuner/1.1/Android.bp
+++ b/tv/tuner/1.1/Android.bp
@@ -7,6 +7,7 @@
"IFilter.hal",
"IFrontend.hal",
"IFilterCallback.hal",
+ "IFrontendCallback.hal",
"ITuner.hal",
"types.hal",
],
diff --git a/tv/tuner/1.1/IFrontend.hal b/tv/tuner/1.1/IFrontend.hal
index 9858d4b..e9c5e19 100644
--- a/tv/tuner/1.1/IFrontend.hal
+++ b/tv/tuner/1.1/IFrontend.hal
@@ -37,7 +37,7 @@
*
* @param settings Signal delivery information the frontend uses to
* search and lock the signal.
- * @param settingsExt Extended information that would be used in the 1.1 Frontend to
+ * @param settingsExt1_1 v1_1 Extended information that would be used in the 1.1 Frontend to
* search and lock the signal in a better way.
*
* @return result Result status of the operation.
@@ -45,7 +45,7 @@
* INVALID_STATE if tuning can't be applied at current stage,
* UNKNOWN_ERROR if tuning failed for other reasons.
*/
- tune_1_1(FrontendSettings settings, FrontendSettingsExt settingsExt)
+ tune_1_1(FrontendSettings settings, FrontendSettingsExt1_1 settingsExt1_1)
generates (Result result);
/**
@@ -59,15 +59,15 @@
* @param settings Signal delivery information which the frontend uses to
* scan the signal.
* @param type the type which the frontend uses to scan the signal.
- * @param settingsExt Extended information that would be used in the 1.1 Frontend to
+ * @param settingsExt1_1 v1_1 Extended information that would be used in the 1.1 Frontend to
* search and lock the signal in a better way.
* @return result Result status of the operation.
* SUCCESS if successful,
* INVALID_STATE if tuning can't be applied at current stage,
* UNKNOWN_ERROR if tuning failed for other reasons.
*/
- scan_1_1(FrontendSettings settings, FrontendScanType type, FrontendSettingsExt settingsExt)
- generates (Result result);
+ scan_1_1(FrontendSettings settings, FrontendScanType type,
+ FrontendSettingsExt1_1 settingsExt1_1) generates (Result result);
/**
* Link Conditional Access Modules (CAM) to Frontend support Common Interface (CI) bypass mode.
@@ -82,4 +82,20 @@
* UNKNOWN_ERROR if failed for other reasons.
*/
linkCiCam(uint32_t ciCamId) generates (Result result);
+
+ /**
+ * Get the v1_1 extended statuses of the frontend.
+ *
+ * This retrieve the extended statuses of the frontend for given extended status types.
+ *
+ * @param statusTypes an array of the extended status types which the caller request.
+ *
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_STATE if tuning can't be applied at current stage,
+ * UNKNOWN_ERROR if tuning failed for other reasons.
+ * @return statuses an array of extended statuses the caller requests for.
+ */
+ getStatusExt1_1(vec<FrontendStatusTypeExt1_1> statusTypes)
+ generates (Result result, vec<FrontendStatusExt1_1> statuses);
};
diff --git a/tv/tuner/1.1/IFrontendCallback.hal b/tv/tuner/1.1/IFrontendCallback.hal
new file mode 100644
index 0000000..e148b1e
--- /dev/null
+++ b/tv/tuner/1.1/IFrontendCallback.hal
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.tuner@1.1;
+
+import @1.0::IFrontendCallback;
+import FrontendScanMessageExt1_1;
+import FrontendScanMessageTypeExt1_1;
+
+interface IFrontendCallback extends @1.0::IFrontendCallback {
+ /**
+ * The callback function that must be called by HAL implementation to notify
+ * the client of the v1_1 extended scan messages.
+ *
+ * @param type the type of v1_1 extended scan message.
+ * @param message the v1_1 extended scan message sent by HAL to the client.
+ */
+ onScanMessageExt1_1(FrontendScanMessageTypeExt1_1 type, FrontendScanMessageExt1_1 messageExt);
+};
diff --git a/tv/tuner/1.1/ITuner.hal b/tv/tuner/1.1/ITuner.hal
index 915fb85..d59c425 100644
--- a/tv/tuner/1.1/ITuner.hal
+++ b/tv/tuner/1.1/ITuner.hal
@@ -16,6 +16,7 @@
package android.hardware.tv.tuner@1.1;
+import @1.0::FrontendId;
import @1.0::ITuner;
import @1.0::Result;
@@ -23,4 +24,10 @@
* Top level interface to manage Frontend, Demux and Decrambler hardware
* resources which are needed for Android TV.
*/
-interface ITuner extends @1.0::ITuner {};
+interface ITuner extends @1.0::ITuner {
+ /**
+ * Get Dtmb Frontend Capabilities. If no dtmb exists, Result::UNAVAILABLE would be returned.
+ */
+ getFrontendDtmbCapabilities(FrontendId frontendId)
+ generates (Result result, FrontendDtmbCapabilities caps);
+};
diff --git a/tv/tuner/1.1/default/Frontend.cpp b/tv/tuner/1.1/default/Frontend.cpp
index 467d547..971e335 100644
--- a/tv/tuner/1.1/default/Frontend.cpp
+++ b/tv/tuner/1.1/default/Frontend.cpp
@@ -17,7 +17,7 @@
#define LOG_TAG "android.hardware.tv.tuner@1.1-Frontend"
#include "Frontend.h"
-#include <android/hardware/tv/tuner/1.0/IFrontendCallback.h>
+#include <android/hardware/tv/tuner/1.1/IFrontendCallback.h>
#include <utils/Log.h>
namespace android {
@@ -72,7 +72,7 @@
}
Return<Result> Frontend::tune_1_1(const FrontendSettings& settings,
- const V1_1::FrontendSettingsExt& /*settingsExt*/) {
+ const V1_1::FrontendSettingsExt1_1& /*settingsExt1_1*/) {
ALOGV("%s", __FUNCTION__);
return tune(settings);
}
@@ -118,11 +118,22 @@
mCallback->onScanMessage(FrontendScanMessageType::LOCKED, msg);
mIsLocked = true;
+ sp<V1_1::IFrontendCallback> frontendCallback_v1_1 =
+ V1_1::IFrontendCallback::castFrom(mCallback);
+ if (frontendCallback_v1_1 != NULL) {
+ V1_1::FrontendScanMessageExt1_1 msg;
+ msg.dvbc(FrontendDvbcModulation::MOD_16QAM);
+ frontendCallback_v1_1->onScanMessageExt1_1(V1_1::FrontendScanMessageTypeExt1_1::MODULATION,
+ msg);
+ } else {
+ ALOGD("[Filter] Couldn't cast to V1_1 IFrontendCallback");
+ }
+
return Result::SUCCESS;
}
Return<Result> Frontend::scan_1_1(const FrontendSettings& settings, FrontendScanType type,
- const V1_1::FrontendSettingsExt& /*settingsExt*/) {
+ const V1_1::FrontendSettingsExt1_1& /*settingsExt1_1*/) {
ALOGV("%s", __FUNCTION__);
return scan(settings, type);
}
@@ -259,6 +270,83 @@
return Void();
}
+Return<void> Frontend::getStatusExt1_1(const hidl_vec<V1_1::FrontendStatusTypeExt1_1>& statusTypes,
+ V1_1::IFrontend::getStatusExt1_1_cb _hidl_cb) {
+ ALOGV("%s", __FUNCTION__);
+
+ vector<V1_1::FrontendStatusExt1_1> statuses;
+ for (int i = 0; i < statusTypes.size(); i++) {
+ V1_1::FrontendStatusTypeExt1_1 type = statusTypes[i];
+ V1_1::FrontendStatusExt1_1 status;
+ // assign randomly selected values for testing.
+ switch (type) {
+ case V1_1::FrontendStatusTypeExt1_1::MODULATIONS: {
+ vector<V1_1::FrontendModulation> modulations;
+ V1_1::FrontendModulation modulation;
+ modulation.isdbt(FrontendIsdbtModulation::MOD_16QAM); // value = 1 << 3
+ modulations.push_back(modulation);
+ status.modulations(modulations);
+ break;
+ }
+ case V1_1::FrontendStatusTypeExt1_1::BERS: {
+ vector<uint32_t> bers = {1};
+ status.bers(bers);
+ break;
+ }
+ case V1_1::FrontendStatusTypeExt1_1::CODERATES: {
+ // value = 1 << 39
+ vector<V1_1::FrontendInnerFec> codeRates = {V1_1::FrontendInnerFec::FEC_6_15};
+ status.codeRates(codeRates);
+ break;
+ }
+ case V1_1::FrontendStatusTypeExt1_1::GUARD_INTERVAL: {
+ V1_1::FrontendGuardInterval interval;
+ interval.dvbt(FrontendDvbtGuardInterval::INTERVAL_1_32); // value = 1 << 1
+ status.interval(interval);
+ break;
+ }
+ case V1_1::FrontendStatusTypeExt1_1::TRANSMISSION_MODE: {
+ V1_1::FrontendTransmissionMode transMode;
+ transMode.dvbt(V1_1::FrontendDvbtTransmissionMode::AUTO); // value = 1 << 0
+ status.transmissionMode(transMode);
+ break;
+ }
+ case V1_1::FrontendStatusTypeExt1_1::UEC: {
+ status.uec(4);
+ break;
+ }
+ case V1_1::FrontendStatusTypeExt1_1::T2_SYSTEM_ID: {
+ status.systemId(5);
+ break;
+ }
+ case V1_1::FrontendStatusTypeExt1_1::INTERLEAVINGS: {
+ V1_1::FrontendInterleaveMode interleave;
+ interleave.atsc3(FrontendAtsc3TimeInterleaveMode::AUTO);
+ vector<V1_1::FrontendInterleaveMode> interleaving = {interleave};
+ status.interleaving(interleaving);
+ break;
+ }
+ case V1_1::FrontendStatusTypeExt1_1::ISDBT_SEGMENTS: {
+ vector<uint8_t> segments = {2, 3};
+ status.isdbtSegment(segments);
+ break;
+ }
+ case V1_1::FrontendStatusTypeExt1_1::TS_DATA_RATES: {
+ vector<uint32_t> dataRates = {4, 5};
+ status.tsDataRate(dataRates);
+ break;
+ }
+ default: {
+ continue;
+ }
+ }
+ statuses.push_back(status);
+ }
+ _hidl_cb(Result::SUCCESS, statuses);
+
+ return Void();
+}
+
Return<Result> Frontend::setLna(bool /* bEnable */) {
ALOGV("%s", __FUNCTION__);
diff --git a/tv/tuner/1.1/default/Frontend.h b/tv/tuner/1.1/default/Frontend.h
index 6a80232..4c35718 100644
--- a/tv/tuner/1.1/default/Frontend.h
+++ b/tv/tuner/1.1/default/Frontend.h
@@ -44,20 +44,24 @@
virtual Return<Result> tune(const FrontendSettings& settings) override;
virtual Return<Result> tune_1_1(const FrontendSettings& settings,
- const V1_1::FrontendSettingsExt& settingsExt) override;
+ const V1_1::FrontendSettingsExt1_1& settingsExt1_1) override;
virtual Return<Result> stopTune() override;
virtual Return<Result> scan(const FrontendSettings& settings, FrontendScanType type) override;
virtual Return<Result> scan_1_1(const FrontendSettings& settings, FrontendScanType type,
- const V1_1::FrontendSettingsExt& settingsExt) override;
+ const V1_1::FrontendSettingsExt1_1& settingsExt1_1) override;
virtual Return<Result> stopScan() override;
virtual Return<void> getStatus(const hidl_vec<FrontendStatusType>& statusTypes,
getStatus_cb _hidl_cb) override;
+ virtual Return<void> getStatusExt1_1(
+ const hidl_vec<V1_1::FrontendStatusTypeExt1_1>& statusTypes,
+ V1_1::IFrontend::getStatusExt1_1_cb _hidl_cb) override;
+
virtual Return<Result> setLna(bool bEnable) override;
virtual Return<Result> setLnb(uint32_t lnb) override;
diff --git a/tv/tuner/1.1/default/Tuner.cpp b/tv/tuner/1.1/default/Tuner.cpp
index 87a4d36..c3dcd1d 100644
--- a/tv/tuner/1.1/default/Tuner.cpp
+++ b/tv/tuner/1.1/default/Tuner.cpp
@@ -33,7 +33,7 @@
Tuner::Tuner() {
// Static Frontends array to maintain local frontends information
// Array index matches their FrontendId in the default impl
- mFrontendSize = 8;
+ mFrontendSize = 9;
mFrontends[0] = new Frontend(FrontendType::DVBT, 0, this);
mFrontends[1] = new Frontend(FrontendType::ATSC, 1, this);
mFrontends[2] = new Frontend(FrontendType::DVBC, 2, this);
@@ -42,6 +42,8 @@
mFrontends[5] = new Frontend(FrontendType::ISDBT, 5, this);
mFrontends[6] = new Frontend(FrontendType::ANALOG, 6, this);
mFrontends[7] = new Frontend(FrontendType::ATSC, 7, this);
+ mFrontends[8] =
+ new Frontend(static_cast<V1_0::FrontendType>(V1_1::FrontendType::DTMB), 8, this);
FrontendInfo::FrontendCapabilities caps;
caps = FrontendInfo::FrontendCapabilities();
@@ -224,6 +226,20 @@
return Void();
}
+Return<void> Tuner::getFrontendDtmbCapabilities(uint32_t frontendId,
+ getFrontendDtmbCapabilities_cb _hidl_cb) {
+ ALOGV("%s", __FUNCTION__);
+
+ if (mFrontends[frontendId] != nullptr &&
+ (mFrontends[frontendId]->getFrontendType() ==
+ static_cast<V1_0::FrontendType>(V1_1::FrontendType::DTMB))) {
+ _hidl_cb(Result::SUCCESS, mDtmbCaps);
+ } else {
+ _hidl_cb(Result::UNAVAILABLE, mDtmbCaps);
+ }
+ return Void();
+}
+
void Tuner::setFrontendAsDemuxSource(uint32_t frontendId, uint32_t demuxId) {
mFrontendToDemux[frontendId] = demuxId;
if (mFrontends[frontendId] != nullptr && mFrontends[frontendId]->isLocked()) {
diff --git a/tv/tuner/1.1/default/Tuner.h b/tv/tuner/1.1/default/Tuner.h
index 3b1574b..fda3636 100644
--- a/tv/tuner/1.1/default/Tuner.h
+++ b/tv/tuner/1.1/default/Tuner.h
@@ -62,6 +62,9 @@
virtual Return<void> openLnbByName(const hidl_string& lnbName,
openLnbByName_cb _hidl_cb) override;
+ virtual Return<void> getFrontendDtmbCapabilities(
+ uint32_t frontendId, getFrontendDtmbCapabilities_cb _hidl_cb) override;
+
sp<Frontend> getFrontendById(uint32_t frontendId);
void setFrontendAsDemuxSource(uint32_t frontendId, uint32_t demuxId);
@@ -76,6 +79,7 @@
// Static mFrontends array to maintain local frontends information
map<uint32_t, sp<Frontend>> mFrontends;
map<uint32_t, FrontendInfo::FrontendCapabilities> mFrontendCaps;
+ V1_1::FrontendDtmbCapabilities mDtmbCaps;
map<uint32_t, uint32_t> mFrontendToDemux;
map<uint32_t, sp<Demux>> mDemuxes;
// To maintain how many Frontends we have
diff --git a/tv/tuner/1.1/types.hal b/tv/tuner/1.1/types.hal
index af8d628..29b999f 100644
--- a/tv/tuner/1.1/types.hal
+++ b/tv/tuner/1.1/types.hal
@@ -19,9 +19,27 @@
import @1.0::Constant;
import @1.0::DemuxFilterMmtpRecordEvent;
import @1.0::DemuxFilterTsRecordEvent;
+import @1.0::FrontendAtsc3Bandwidth;
+import @1.0::FrontendAtsc3Modulation;
+import @1.0::FrontendAtsc3TimeInterleaveMode;
+import @1.0::FrontendAtscModulation;
+import @1.0::FrontendDvbcModulation;
+import @1.0::FrontendDvbtBandwidth;
import @1.0::FrontendDvbcSpectralInversion;
+import @1.0::FrontendDvbsModulation;
import @1.0::FrontendDvbtConstellation;
import @1.0::FrontendDvbtTransmissionMode;
+import @1.0::FrontendDvbtGuardInterval;
+import @1.0::FrontendInnerFec;
+import @1.0::FrontendIsdbs3Modulation;
+import @1.0::FrontendIsdbsModulation;
+import @1.0::FrontendIsdbtBandwidth;
+import @1.0::FrontendIsdbtGuardInterval;
+import @1.0::FrontendIsdbtMode;
+import @1.0::FrontendIsdbtModulation;
+import @1.0::FrontendScanMessageType;
+import @1.0::FrontendStatusType;
+import @1.0::FrontendType;
import android.hidl.safe_union@1.0;
import android.hidl.safe_union@1.0::Monostate;
@@ -64,8 +82,7 @@
struct DemuxFilterRecordEventExt {
/**
* The Presentation Time Stamp(PTS) for the audio or video frame. It is based on 90KHz
- * and has the same format as the PTS in ISO/IEC 13818-1. It is used only for the SC and
- * the SC_HEVC.
+ * and has the same format as the PTS in ISO/IEC 13818-1.
*/
uint64_t pts;
@@ -145,14 +162,16 @@
/**
* Extended Signal Settings for a DVBS Frontend.
*/
-struct FrontendDvbsSettingsExt {
+struct FrontendDvbsSettingsExt1_1 {
FrontendDvbsScanType scanType;
+
+ bool isDiseqcRxMessage;
};
/**
* Extended Signal Settings for a DVBT Frontend.
*/
-struct FrontendDvbtSettingsExt {
+struct FrontendDvbtSettingsExt1_1 {
FrontendDvbtConstellation constellation;
FrontendDvbtTransmissionMode transmissionMode;
@@ -161,14 +180,14 @@
/**
* Extended Signal Settings for an Analog Frontend.
*/
-struct FrontendAnalogSettingsExt {
+struct FrontendAnalogSettingsExt1_1 {
FrontendAnalogAftFlag aftFlag;
};
/**
* Extended Signal Settings for Frontend.
*/
-struct FrontendSettingsExt {
+struct FrontendSettingsExt1_1 {
uint32_t endFrequency;
FrontendSpectralInversion inversion;
@@ -176,10 +195,337 @@
safe_union SettingsExt {
Monostate noinit;
- FrontendAnalogSettingsExt analog;
+ FrontendAnalogSettingsExt1_1 analog;
- FrontendDvbsSettingsExt dvbs;
+ FrontendDvbsSettingsExt1_1 dvbs;
- FrontendDvbtSettingsExt dvbt;
+ FrontendDvbtSettingsExt1_1 dvbt;
+
+ FrontendDtmbSettings dtmb;
} settingExt;
};
+
+/**
+ * Extended Frontend Type.
+ */
+@export
+enum FrontendType : @1.0::FrontendType {
+ /**
+ * DTMB (Digital Terrestrial Multimedia Broadcast) standard.
+ */
+ DTMB,
+};
+
+/**
+ * Bandwidth Type for DTMB.
+ */
+@export
+enum FrontendDtmbBandwidth : uint32_t {
+ UNDEFINED = 0,
+ /**
+ * hardware is able to detect and set Bandwidth automatically
+ */
+ AUTO = 1 << 0,
+ BANDWIDTH_8MHZ = 1 << 1,
+ BANDWIDTH_6MHZ = 1 << 2,
+};
+
+/**
+ * TimeInterleaveMode Type for DTMB.
+ */
+@export
+enum FrontendDtmbTimeInterleaveMode : uint32_t {
+ UNDEFINED = 0,
+ /**
+ * hardware is able to detect and set time interleave mode automatically
+ */
+ AUTO = 1 << 0,
+ TIMER_INT_240 = 1 << 1,
+ TIMER_INT_720 = 1 << 2,
+};
+
+/**
+ * FrontendDtmbModulation Type for DTMB.
+ */
+@export
+enum FrontendDtmbModulation : uint32_t {
+ UNDEFINED = 0,
+ /**
+ * hardware is able to detect and set Constellation automatically
+ */
+ AUTO = 1 << 0,
+ CONSTELLATION_4QAM = 1 << 1,
+ CONSTELLATION_4QAM_NR = 1 << 2,
+ CONSTELLATION_16QAM = 1 << 3,
+ CONSTELLATION_32QAM = 1 << 4,
+ CONSTELLATION_64QAM = 1 << 5,
+};
+
+/**
+ * CODERATE Type for DTMB.
+ */
+@export
+enum FrontendDtmbCodeRate : uint32_t {
+ UNDEFINED = 0,
+ /**
+ * hardware is able to detect and set code rate automatically
+ */
+ AUTO = 1 << 0,
+ CODERATE_2_5 = 1 << 1,
+ CODERATE_3_5 = 1 << 2,
+ CODERATE_4_5 = 1 << 3,
+};
+
+/**
+ * Guard Interval Type for DTMB.
+ */
+@export
+enum FrontendDtmbGuardInterval : uint32_t {
+ UNDEFINED = 0,
+ /**
+ * hardware is able to detect and set Guard Interval automatically
+ */
+ AUTO = 1 << 0,
+ PN_420_VARIOUS = 1 << 1,
+ PN_595_CONST = 1 << 2,
+ PN_945_VARIOUS = 1 << 3,
+ PN_420_CONST = 1 << 4,
+ PN_945_CONST = 1 << 5,
+ PN_RESERVED = 1 << 6,
+};
+
+/**
+ * Transmission Mode for DTMB.
+ */
+@export
+enum FrontendDtmbTransmissionMode : uint32_t {
+ UNDEFINED = 0,
+ /**
+ * hardware is able to detect and set Transmission Mode automatically
+ */
+ AUTO = 1 << 0,
+ C1 = 1 << 1,
+ C3780 = 1 << 2,
+};
+
+/**
+ * Signal Setting for DTMB Frontend.
+ */
+struct FrontendDtmbSettings {
+ uint32_t frequency;
+
+ FrontendDtmbTransmissionMode transmissionMode;
+
+ FrontendDtmbBandwidth bandwidth;
+
+ FrontendDtmbModulation modulation;
+
+ FrontendDtmbCodeRate codeRate;
+
+ FrontendDtmbGuardInterval guardInterval;
+
+ FrontendDtmbTimeInterleaveMode interleaveMode;
+};
+
+/**
+ * Capabilities for DTMB Frontend.
+ */
+struct FrontendDtmbCapabilities {
+ bitfield<FrontendDtmbTransmissionMode> transmissionModeCap;
+
+ bitfield<FrontendDtmbBandwidth> bandwidthCap;
+
+ bitfield<FrontendDtmbModulation> modulationCap;
+
+ bitfield<FrontendDtmbCodeRate> codeRateCap;
+
+ bitfield<FrontendDtmbGuardInterval> guardIntervalCap;
+
+ bitfield<FrontendDtmbTimeInterleaveMode> interleaveModeCap;
+};
+
+safe_union FrontendModulation {
+ @1.0::FrontendDvbcModulation dvbc;
+
+ @1.0::FrontendDvbsModulation dvbs;
+
+ FrontendDvbtConstellation dvbt;
+
+ @1.0::FrontendIsdbsModulation isdbs;
+
+ @1.0::FrontendIsdbs3Modulation isdbs3;
+
+ @1.0::FrontendIsdbtModulation isdbt;
+
+ @1.0::FrontendAtscModulation atsc;
+
+ @1.0::FrontendAtsc3Modulation atsc3;
+
+ FrontendDtmbModulation dtmb;
+};
+
+safe_union FrontendInterleaveMode {
+ @1.0::FrontendAtsc3TimeInterleaveMode atsc3;
+
+ FrontendDtmbTimeInterleaveMode dtmb;
+};
+
+@export
+enum FrontendInnerFec : @1.0::FrontendInnerFec {
+ FEC_2_15 = 1 << 36,
+ FEC_3_15 = 1 << 37,
+ FEC_5_15 = 1 << 38,
+ FEC_6_15 = 1 << 39,
+ FEC_9_15 = 1 << 40,
+ FEC_10_15 = 1 << 41,
+ FEC_12_15 = 1 << 42,
+ FEC_13_15 = 1 << 43,
+ FEC_18_30 = 1 << 44,
+ FEC_20_30 = 1 << 45,
+ FEC_90_180 = 1 << 46,
+ FEC_96_180 = 1 << 47,
+ FEC_104_180 = 1 << 48,
+ FEC_128_180 = 1 << 49,
+ FEC_132_180 = 1 << 50,
+ FEC_135_180 = 1 << 51,
+ FEC_140_180 = 1 << 52,
+};
+
+safe_union FrontendBandwidth {
+ @1.0::FrontendAtsc3Bandwidth atsc3;
+
+ @1.0::FrontendDvbtBandwidth dvbt;
+
+ @1.0::FrontendIsdbtBandwidth isdbt;
+
+ FrontendDtmbBandwidth dtmb;
+};
+
+safe_union FrontendGuardInterval {
+ @1.0::FrontendDvbtGuardInterval dvbt;
+
+ @1.0::FrontendIsdbtGuardInterval isdbt;
+
+ FrontendDtmbGuardInterval dtmb;
+};
+
+safe_union FrontendTransmissionMode {
+ FrontendDvbtTransmissionMode dvbt;
+
+ @1.0::FrontendIsdbtMode isdbt;
+
+ FrontendDtmbTransmissionMode dtmb;
+};
+
+@export
+enum FrontendStatusTypeExt1_1 : uint32_t {
+ /**
+ * Modulation Types.
+ */
+ MODULATIONS = @1.0::FrontendStatusType:ATSC3_PLP_INFO + 1,
+ /**
+ * Bit Error Ratios.
+ */
+ BERS,
+ /**
+ * Code Rates.
+ */
+ CODERATES,
+ /**
+ * Extended Bandwidth.
+ */
+ BANDWIDTH,
+ /**
+ * Extended Guard Intervals.
+ */
+ GUARD_INTERVAL,
+ /**
+ * Extended Transmission Mode.
+ */
+ TRANSMISSION_MODE,
+ /**
+ * Uncorrectable Error Counts of the frontend's Physical Layer Pipe (PLP)
+ * since the last tune operation.
+ */
+ UEC,
+ /**
+ * DVB-T2 System Id.
+ */
+ T2_SYSTEM_ID,
+ /**
+ * Frontend Interleaving Modes.
+ */
+ INTERLEAVINGS,
+ /**
+ * Segments in ISDB-T Specification of all the channels.
+ */
+ ISDBT_SEGMENTS,
+ /**
+ * Transport Stream Data Rate in BPS of the current channel.
+ */
+ TS_DATA_RATES,
+};
+
+safe_union FrontendStatusExt1_1 {
+ /**
+ * Extended modulation status.
+ */
+ vec<FrontendModulation> modulations;
+
+ /**
+ * Extended bit error ratio status.
+ */
+ vec<uint32_t> bers;
+
+ /**
+ * Extended code rate status.
+ */
+ vec<FrontendInnerFec> codeRates;
+
+ /**
+ * Extended bandwidth status.
+ */
+ FrontendBandwidth bandwidth;
+
+ /**
+ * Extended guard interval status.
+ */
+ FrontendGuardInterval interval;
+
+ /**
+ * Extended transmission mode status.
+ */
+ FrontendTransmissionMode transmissionMode;
+
+ /**
+ * Uncorrectable Error Counts of the frontend's Physical Layer Pipe (PLP)
+ * since the last tune operation.
+ */
+ uint32_t uec;
+
+ /**
+ * The current DVB-T2 system id status.
+ */
+ uint16_t systemId;
+
+ /**
+ * Frontend Interleaving Modes.
+ */
+ vec<FrontendInterleaveMode> interleaving;
+
+ /**
+ * Segments in ISDB-T Specification of all the channels.
+ */
+ vec<uint8_t> isdbtSegment;
+
+ /**
+ * Transport Stream Data Rate in BPS of the current channel.
+ */
+ vec<uint32_t> tsDataRate;
+};
+
+enum FrontendScanMessageTypeExt1_1 : uint32_t {
+ MODULATION = @1.0::FrontendScanMessageType:ATSC3_PLP_INFO + 1,
+};
+
+typedef FrontendModulation FrontendScanMessageExt1_1;
diff --git a/tv/tuner/1.1/vts/functional/FrontendTests.cpp b/tv/tuner/1.1/vts/functional/FrontendTests.cpp
index 5e2b288..3bc7114 100644
--- a/tv/tuner/1.1/vts/functional/FrontendTests.cpp
+++ b/tv/tuner/1.1/vts/functional/FrontendTests.cpp
@@ -47,8 +47,53 @@
return Void();
}
+Return<void> FrontendCallback::onScanMessageExt1_1(FrontendScanMessageTypeExt1_1 type,
+ const FrontendScanMessageExt1_1& message) {
+ android::Mutex::Autolock autoLock(mMsgLock);
+ ALOGD("[vts] frontend ext1_1 scan message. Type: %d", type);
+ switch (type) {
+ case FrontendScanMessageTypeExt1_1::MODULATION:
+ readFrontendScanMessageExt1_1Modulation(message);
+ break;
+ default:
+ break;
+ }
+ return Void();
+}
+
+void FrontendCallback::readFrontendScanMessageExt1_1Modulation(FrontendModulation modulation) {
+ switch (modulation.getDiscriminator()) {
+ case FrontendModulation::hidl_discriminator::dvbc:
+ ALOGD("[vts] frontend ext1_1 scan message modulation dvbc: %d", modulation.dvbc());
+ break;
+ case FrontendModulation::hidl_discriminator::dvbs:
+ ALOGD("[vts] frontend ext1_1 scan message modulation dvbs: %d", modulation.dvbs());
+ break;
+ case FrontendModulation::hidl_discriminator::isdbs:
+ ALOGD("[vts] frontend ext1_1 scan message modulation isdbs: %d", modulation.isdbs());
+ break;
+ case FrontendModulation::hidl_discriminator::isdbs3:
+ ALOGD("[vts] frontend ext1_1 scan message modulation isdbs3: %d", modulation.isdbs3());
+ break;
+ case FrontendModulation::hidl_discriminator::isdbt:
+ ALOGD("[vts] frontend ext1_1 scan message modulation isdbt: %d", modulation.isdbt());
+ break;
+ case FrontendModulation::hidl_discriminator::atsc:
+ ALOGD("[vts] frontend ext1_1 scan message modulation atsc: %d", modulation.atsc());
+ break;
+ case FrontendModulation::hidl_discriminator::atsc3:
+ ALOGD("[vts] frontend ext1_1 scan message modulation atsc3: %d", modulation.atsc3());
+ break;
+ case FrontendModulation::hidl_discriminator::dvbt:
+ ALOGD("[vts] frontend ext1_1 scan message modulation dvbt: %d", modulation.dvbt());
+ break;
+ default:
+ break;
+ }
+}
+
void FrontendCallback::tuneTestOnLock(sp<IFrontend>& frontend, FrontendSettings settings,
- FrontendSettingsExt settingsExt) {
+ FrontendSettingsExt1_1 settingsExt1_1) {
sp<android::hardware::tv::tuner::V1_1::IFrontend> frontend_1_1;
frontend_1_1 = android::hardware::tv::tuner::V1_1::IFrontend::castFrom(frontend);
if (frontend_1_1 == nullptr) {
@@ -56,7 +101,7 @@
return;
}
- Result result = frontend_1_1->tune_1_1(settings, settingsExt);
+ Result result = frontend_1_1->tune_1_1(settings, settingsExt1_1);
EXPECT_TRUE(result == Result::SUCCESS);
android::Mutex::Autolock autoLock(mMsgLock);
@@ -88,7 +133,7 @@
resetBlindScanStartingFrequency(config, targetFrequency - 100);
}
- Result result = frontend_1_1->scan_1_1(config.settings, type, config.settingsExt);
+ Result result = frontend_1_1->scan_1_1(config.settings, type, config.settingsExt1_1);
EXPECT_TRUE(result == Result::SUCCESS);
bool scanMsgLockedReceived = false;
@@ -108,7 +153,7 @@
if (mScanMessageType != FrontendScanMessageType::END) {
if (mScanMessageType == FrontendScanMessageType::LOCKED) {
scanMsgLockedReceived = true;
- Result result = frontend_1_1->scan_1_1(config.settings, type, config.settingsExt);
+ Result result = frontend_1_1->scan_1_1(config.settings, type, config.settingsExt1_1);
EXPECT_TRUE(result == Result::SUCCESS);
}
@@ -243,118 +288,92 @@
EXPECT_TRUE(mFrontend) << "Test with openFrontendById first.";
Result status;
status = mFrontend->stopScan();
+
return AssertionResult(status == Result::SUCCESS);
}
-void FrontendTests::verifyFrontendStatus(vector<FrontendStatusType> statusTypes,
- vector<FrontendStatus> expectStatuses) {
+AssertionResult FrontendTests::getFrontendDtmbCaps(uint32_t id) {
+ Result status;
+ mService->getFrontendDtmbCapabilities(
+ id, [&](Result result, const FrontendDtmbCapabilities& /*caps*/) { status = result; });
+ return AssertionResult(status == Result::SUCCESS);
+}
+
+void FrontendTests::verifyFrontendStatusExt1_1(vector<FrontendStatusTypeExt1_1> statusTypes,
+ vector<FrontendStatusExt1_1> expectStatuses) {
ASSERT_TRUE(mFrontend) << "Frontend is not opened yet.";
Result status;
- vector<FrontendStatus> realStatuses;
+ vector<FrontendStatusExt1_1> realStatuses;
- mFrontend->getStatus(statusTypes, [&](Result result, const hidl_vec<FrontendStatus>& statuses) {
- status = result;
- realStatuses = statuses;
- });
+ sp<android::hardware::tv::tuner::V1_1::IFrontend> frontend_1_1;
+ frontend_1_1 = android::hardware::tv::tuner::V1_1::IFrontend::castFrom(mFrontend);
+ if (frontend_1_1 == nullptr) {
+ EXPECT_TRUE(false) << "Couldn't get 1.1 IFrontend from the Hal implementation.";
+ return;
+ }
+
+ frontend_1_1->getStatusExt1_1(
+ statusTypes, [&](Result result, const hidl_vec<FrontendStatusExt1_1>& statuses) {
+ status = result;
+ realStatuses = statuses;
+ });
ASSERT_TRUE(realStatuses.size() == statusTypes.size());
for (int i = 0; i < statusTypes.size(); i++) {
- FrontendStatusType type = statusTypes[i];
+ FrontendStatusTypeExt1_1 type = statusTypes[i];
switch (type) {
- case FrontendStatusType::DEMOD_LOCK: {
- ASSERT_TRUE(realStatuses[i].isDemodLocked() == expectStatuses[i].isDemodLocked());
+ case FrontendStatusTypeExt1_1::MODULATIONS: {
+ // TODO: verify modulations
break;
}
- case FrontendStatusType::SNR: {
- ASSERT_TRUE(realStatuses[i].snr() == expectStatuses[i].snr());
+ case FrontendStatusTypeExt1_1::BERS: {
+ ASSERT_TRUE(std::equal(realStatuses[i].bers().begin(), realStatuses[i].bers().end(),
+ expectStatuses[i].bers().begin()));
break;
}
- case FrontendStatusType::BER: {
- ASSERT_TRUE(realStatuses[i].ber() == expectStatuses[i].ber());
+ case FrontendStatusTypeExt1_1::CODERATES: {
+ ASSERT_TRUE(std::equal(realStatuses[i].codeRates().begin(),
+ realStatuses[i].codeRates().end(),
+ expectStatuses[i].codeRates().begin()));
break;
}
- case FrontendStatusType::PER: {
- ASSERT_TRUE(realStatuses[i].per() == expectStatuses[i].per());
+ case FrontendStatusTypeExt1_1::GUARD_INTERVAL: {
+ // TODO: verify interval
break;
}
- case FrontendStatusType::PRE_BER: {
- ASSERT_TRUE(realStatuses[i].preBer() == expectStatuses[i].preBer());
+ case FrontendStatusTypeExt1_1::TRANSMISSION_MODE: {
+ // TODO: verify tranmission mode
break;
}
- case FrontendStatusType::SIGNAL_QUALITY: {
- ASSERT_TRUE(realStatuses[i].signalQuality() == expectStatuses[i].signalQuality());
+ case FrontendStatusTypeExt1_1::UEC: {
+ ASSERT_TRUE(realStatuses[i].uec() == expectStatuses[i].uec());
break;
}
- case FrontendStatusType::SIGNAL_STRENGTH: {
- ASSERT_TRUE(realStatuses[i].signalStrength() == expectStatuses[i].signalStrength());
+ case FrontendStatusTypeExt1_1::T2_SYSTEM_ID: {
+ ASSERT_TRUE(realStatuses[i].systemId() == expectStatuses[i].systemId());
break;
}
- case FrontendStatusType::SYMBOL_RATE: {
- ASSERT_TRUE(realStatuses[i].symbolRate() == expectStatuses[i].symbolRate());
+ case FrontendStatusTypeExt1_1::INTERLEAVINGS: {
+ ASSERT_TRUE(std::equal(realStatuses[i].interleaving().begin(),
+ realStatuses[i].interleaving().end(),
+ expectStatuses[i].interleaving().begin()));
break;
}
- case FrontendStatusType::FEC: {
- ASSERT_TRUE(realStatuses[i].innerFec() == expectStatuses[i].innerFec());
+ case FrontendStatusTypeExt1_1::ISDBT_SEGMENTS: {
+ ASSERT_TRUE(std::equal(realStatuses[i].isdbtSegment().begin(),
+ realStatuses[i].isdbtSegment().end(),
+ expectStatuses[i].isdbtSegment().begin()));
break;
}
- case FrontendStatusType::MODULATION: {
- // TODO: check modulation status
+ case FrontendStatusTypeExt1_1::TS_DATA_RATES: {
+ ASSERT_TRUE(std::equal(realStatuses[i].tsDataRate().begin(),
+ realStatuses[i].tsDataRate().end(),
+ expectStatuses[i].tsDataRate().begin()));
break;
}
- case FrontendStatusType::SPECTRAL: {
- ASSERT_TRUE(realStatuses[i].inversion() == expectStatuses[i].inversion());
- break;
- }
- case FrontendStatusType::LNB_VOLTAGE: {
- ASSERT_TRUE(realStatuses[i].lnbVoltage() == expectStatuses[i].lnbVoltage());
- break;
- }
- case FrontendStatusType::PLP_ID: {
- ASSERT_TRUE(realStatuses[i].plpId() == expectStatuses[i].plpId());
- break;
- }
- case FrontendStatusType::EWBS: {
- ASSERT_TRUE(realStatuses[i].isEWBS() == expectStatuses[i].isEWBS());
- break;
- }
- case FrontendStatusType::AGC: {
- ASSERT_TRUE(realStatuses[i].agc() == expectStatuses[i].agc());
- break;
- }
- case FrontendStatusType::LNA: {
- ASSERT_TRUE(realStatuses[i].isLnaOn() == expectStatuses[i].isLnaOn());
- break;
- }
- case FrontendStatusType::LAYER_ERROR: {
- vector<bool> realLayberError = realStatuses[i].isLayerError();
- vector<bool> expectLayerError = expectStatuses[i].isLayerError();
- ASSERT_TRUE(realLayberError.size() == expectLayerError.size());
- for (int i = 0; i < realLayberError.size(); i++) {
- ASSERT_TRUE(realLayberError[i] == expectLayerError[i]);
- }
- break;
- }
- case FrontendStatusType::MER: {
- ASSERT_TRUE(realStatuses[i].mer() == expectStatuses[i].mer());
- break;
- }
- case FrontendStatusType::FREQ_OFFSET: {
- ASSERT_TRUE(realStatuses[i].freqOffset() == expectStatuses[i].freqOffset());
- break;
- }
- case FrontendStatusType::HIERARCHY: {
- ASSERT_TRUE(realStatuses[i].hierarchy() == expectStatuses[i].hierarchy());
- break;
- }
- case FrontendStatusType::RF_LOCK: {
- ASSERT_TRUE(realStatuses[i].isRfLocked() == expectStatuses[i].isRfLocked());
- break;
- }
- case FrontendStatusType::ATSC3_PLP_INFO:
- // TODO: verify plpinfo
- break;
- default:
+ default: {
continue;
+ }
}
}
ASSERT_TRUE(status == Result::SUCCESS);
@@ -380,7 +399,7 @@
return failure();
}
}
- mFrontendCallback->tuneTestOnLock(mFrontend, config.settings, config.settingsExt);
+ mFrontendCallback->tuneTestOnLock(mFrontend, config.settings, config.settingsExt1_1);
return AssertionResult(true);
}
@@ -425,7 +444,7 @@
ASSERT_TRUE(openFrontendById(feId));
ASSERT_TRUE(setFrontendCallback());
ASSERT_TRUE(tuneFrontend(frontendConf, false /*testWithDemux*/));
- verifyFrontendStatus(frontendConf.tuneStatusTypes, frontendConf.expectTuneStatuses);
+ verifyFrontendStatusExt1_1(frontendConf.tuneStatusTypes, frontendConf.expectTuneStatuses);
ASSERT_TRUE(stopTuneFrontend(false /*testWithDemux*/));
ASSERT_TRUE(closeFrontend());
}
@@ -440,3 +459,14 @@
ASSERT_TRUE(stopScanFrontend());
ASSERT_TRUE(closeFrontend());
}
+
+void FrontendTests::getFrontendDtmbCapsTest() {
+ uint32_t feId;
+ getFrontendIdByType(
+ static_cast<FrontendType>(android::hardware::tv::tuner::V1_1::FrontendType::DTMB),
+ feId);
+ if (feId != INVALID_ID) {
+ ALOGD("[vts] Found DTMB Frontend");
+ ASSERT_TRUE(getFrontendDtmbCaps(feId));
+ }
+}
diff --git a/tv/tuner/1.1/vts/functional/FrontendTests.h b/tv/tuner/1.1/vts/functional/FrontendTests.h
index 8986d81..243d9de 100644
--- a/tv/tuner/1.1/vts/functional/FrontendTests.h
+++ b/tv/tuner/1.1/vts/functional/FrontendTests.h
@@ -15,9 +15,9 @@
*/
#include <android-base/logging.h>
-#include <android/hardware/tv/tuner/1.0/IFrontendCallback.h>
#include <android/hardware/tv/tuner/1.0/types.h>
#include <android/hardware/tv/tuner/1.1/IFrontend.h>
+#include <android/hardware/tv/tuner/1.1/IFrontendCallback.h>
#include <android/hardware/tv/tuner/1.1/ITuner.h>
#include <binder/MemoryDealer.h>
#include <gtest/gtest.h>
@@ -54,8 +54,12 @@
using android::hardware::tv::tuner::V1_0::FrontendScanMessageType;
using android::hardware::tv::tuner::V1_0::FrontendScanType;
using android::hardware::tv::tuner::V1_0::IFrontend;
-using android::hardware::tv::tuner::V1_0::IFrontendCallback;
using android::hardware::tv::tuner::V1_0::Result;
+using android::hardware::tv::tuner::V1_1::FrontendDtmbCapabilities;
+using android::hardware::tv::tuner::V1_1::FrontendModulation;
+using android::hardware::tv::tuner::V1_1::FrontendScanMessageExt1_1;
+using android::hardware::tv::tuner::V1_1::FrontendScanMessageTypeExt1_1;
+using android::hardware::tv::tuner::V1_1::IFrontendCallback;
using android::hardware::tv::tuner::V1_1::ITuner;
using ::testing::AssertionResult;
@@ -70,9 +74,11 @@
virtual Return<void> onEvent(FrontendEventType frontendEventType) override;
virtual Return<void> onScanMessage(FrontendScanMessageType type,
const FrontendScanMessage& message) override;
+ virtual Return<void> onScanMessageExt1_1(FrontendScanMessageTypeExt1_1 type,
+ const FrontendScanMessageExt1_1& message) override;
void tuneTestOnLock(sp<IFrontend>& frontend, FrontendSettings settings,
- FrontendSettingsExt settingsExt);
+ FrontendSettingsExt1_1 settingsExt1_1);
void scanTest(sp<IFrontend>& frontend, FrontendConfig config, FrontendScanType type);
// Helper methods
@@ -80,6 +86,8 @@
void resetBlindScanStartingFrequency(FrontendConfig& config, uint32_t resetingFreq);
private:
+ void readFrontendScanMessageExt1_1Modulation(FrontendModulation modulation);
+
bool mEventReceived = false;
bool mScanMessageReceived = false;
bool mLockMsgReceived = false;
@@ -109,14 +117,16 @@
AssertionResult scanFrontend(FrontendConfig config, FrontendScanType type);
AssertionResult stopScanFrontend();
AssertionResult tuneFrontend(FrontendConfig config, bool testWithDemux);
- void verifyFrontendStatus(vector<FrontendStatusType> statusTypes,
- vector<FrontendStatus> expectStatuses);
+ void verifyFrontendStatusExt1_1(vector<FrontendStatusTypeExt1_1> statusTypes,
+ vector<FrontendStatusExt1_1> expectStatuses);
AssertionResult stopTuneFrontend(bool testWithDemux);
AssertionResult closeFrontend();
+ AssertionResult getFrontendDtmbCaps(uint32_t);
void getFrontendIdByType(FrontendType feType, uint32_t& feId);
void tuneTest(FrontendConfig frontendConf);
void scanTest(FrontendConfig frontend, FrontendScanType type);
+ void getFrontendDtmbCapsTest();
void setDvrTests(DvrTests dvrTests) { mDvrTests = dvrTests; }
void setDemux(sp<IDemux> demux) { mDvrTests.setDemux(demux); }
diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp
index f87fa3c..263b0e9 100644
--- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp
+++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp
@@ -142,13 +142,13 @@
recordSingleFilterTest(filterArray[TS_RECORD0], frontendArray[DVBT], dvrArray[DVR_RECORD0]);
}
-TEST_P(TunerFrontendHidlTest, TuneFrontendWithFrontendSettingsExt) {
- description("Tune one Frontend with specific setting and check Lock event");
+TEST_P(TunerFrontendHidlTest, TuneFrontendWithFrontendSettingsExt1_1) {
+ description("Tune one Frontend with v1_1 extended setting and check Lock event");
mFrontendTests.tuneTest(frontendArray[DVBT]);
}
TEST_P(TunerFrontendHidlTest, BlindScanFrontendWithEndFrequency) {
- description("Run an blind frontend scan with specific setting and check lock scanMessage");
+ description("Run an blind frontend scan with v1_1 extended setting and check lock scanMessage");
mFrontendTests.scanTest(frontendScanArray[SCAN_DVBT], FrontendScanType::SCAN_BLIND);
}
@@ -157,6 +157,11 @@
mediaFilterUsingSharedMemoryTest(filterArray[TS_VIDEO0], frontendArray[DVBT]);
}
+TEST_P(TunerFrontendHidlTest, GetFrontendDtmbCaps) {
+ description("Test to query Dtmb frontend caps if exists");
+ mFrontendTests.getFrontendDtmbCapsTest();
+}
+
INSTANTIATE_TEST_SUITE_P(
PerInstance, TunerBroadcastHidlTest,
testing::ValuesIn(android::hardware::getAllHalInstanceNames(ITuner::descriptor)),
diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h
index 36b4bd2..a3bfa1f 100644
--- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h
+++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h
@@ -43,12 +43,12 @@
using android::hardware::tv::tuner::V1_0::FrontendDvbtStandard;
using android::hardware::tv::tuner::V1_0::FrontendDvbtTransmissionMode;
using android::hardware::tv::tuner::V1_0::FrontendSettings;
-using android::hardware::tv::tuner::V1_0::FrontendStatus;
-using android::hardware::tv::tuner::V1_0::FrontendStatusType;
using android::hardware::tv::tuner::V1_0::FrontendType;
using android::hardware::tv::tuner::V1_0::PlaybackSettings;
using android::hardware::tv::tuner::V1_0::RecordSettings;
-using android::hardware::tv::tuner::V1_1::FrontendSettingsExt;
+using android::hardware::tv::tuner::V1_1::FrontendSettingsExt1_1;
+using android::hardware::tv::tuner::V1_1::FrontendStatusExt1_1;
+using android::hardware::tv::tuner::V1_1::FrontendStatusTypeExt1_1;
using namespace std;
@@ -100,9 +100,9 @@
bool isSoftwareFe;
FrontendType type;
FrontendSettings settings;
- FrontendSettingsExt settingsExt;
- vector<FrontendStatusType> tuneStatusTypes;
- vector<FrontendStatus> expectTuneStatuses;
+ FrontendSettingsExt1_1 settingsExt1_1;
+ vector<FrontendStatusTypeExt1_1> tuneStatusTypes;
+ vector<FrontendStatusExt1_1> expectTuneStatuses;
};
struct DvrConfig {
@@ -132,16 +132,16 @@
.standard = FrontendDvbtStandard::T,
};
frontendArray[DVBT].type = FrontendType::DVBT, frontendArray[DVBT].settings.dvbt(dvbtSettings);
- vector<FrontendStatusType> types;
- types.push_back(FrontendStatusType::DEMOD_LOCK);
- FrontendStatus status;
- status.isDemodLocked(true);
- vector<FrontendStatus> statuses;
+ vector<FrontendStatusTypeExt1_1> types;
+ types.push_back(FrontendStatusTypeExt1_1::UEC);
+ FrontendStatusExt1_1 status;
+ status.uec(4);
+ vector<FrontendStatusExt1_1> statuses;
statuses.push_back(status);
frontendArray[DVBT].tuneStatusTypes = types;
frontendArray[DVBT].expectTuneStatuses = statuses;
frontendArray[DVBT].isSoftwareFe = true;
- frontendArray[DVBT].settingsExt.settingExt.dvbt({
+ frontendArray[DVBT].settingsExt1_1.settingExt.dvbt({
.transmissionMode =
android::hardware::tv::tuner::V1_1::FrontendDvbtTransmissionMode::MODE_8K_E,
});
@@ -164,8 +164,8 @@
.isHighPriority = true,
.standard = FrontendDvbtStandard::T,
});
- frontendScanArray[SCAN_DVBT].settingsExt.endFrequency = 800000;
- frontendScanArray[SCAN_DVBT].settingsExt.settingExt.dvbt({
+ frontendScanArray[SCAN_DVBT].settingsExt1_1.endFrequency = 800000;
+ frontendScanArray[SCAN_DVBT].settingsExt1_1.settingExt.dvbt({
.transmissionMode =
android::hardware::tv::tuner::V1_1::FrontendDvbtTransmissionMode::MODE_8K_E,
});
diff --git a/tv/tuner/README.md b/tv/tuner/README.md
index aa1f62d..2a358f5 100644
--- a/tv/tuner/README.md
+++ b/tv/tuner/README.md
@@ -5,8 +5,3 @@
TV specific tuners.
See 1.0/ITuner.hal for an overview.
-
-*** note
-**Warning:** The HALs are not (yet) frozen, as the HAL definition is
-expected to evolve between Android releases.
-***
diff --git a/wifi/hostapd/1.2/vts/functional/Android.bp b/wifi/hostapd/1.2/vts/functional/Android.bp
index cec1782..577174b 100644
--- a/wifi/hostapd/1.2/vts/functional/Android.bp
+++ b/wifi/hostapd/1.2/vts/functional/Android.bp
@@ -25,12 +25,15 @@
"VtsHalWifiHostapdV1_0TargetTestUtil",
"android.hardware.wifi.hostapd@1.0",
"android.hardware.wifi.hostapd@1.1",
- "android.hardware.wifi.hostapd@1.2",
+ "android.hardware.wifi.hostapd@1.2",
+ "android.hardware.wifi.hostapd@1.3",
"android.hardware.wifi@1.0",
"libgmock",
"libwifi-system",
"libwifi-system-iface",
],
- test_suites: ["general-tests", "vts"],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
}
-
diff --git a/wifi/hostapd/1.2/vts/functional/hostapd_hidl_test.cpp b/wifi/hostapd/1.2/vts/functional/hostapd_hidl_test.cpp
index 99784a4..c40c582 100644
--- a/wifi/hostapd/1.2/vts/functional/hostapd_hidl_test.cpp
+++ b/wifi/hostapd/1.2/vts/functional/hostapd_hidl_test.cpp
@@ -25,6 +25,7 @@
#include <android/hardware/wifi/1.0/IWifi.h>
#include <android/hardware/wifi/hostapd/1.2/IHostapd.h>
+#include <android/hardware/wifi/hostapd/1.3/IHostapd.h>
#include "hostapd_hidl_call_util.h"
#include "hostapd_hidl_test_utils.h"
@@ -216,12 +217,20 @@
std::string hostapd_instance_name_;
};
+bool is_1_3(const sp<IHostapd>& hostapd) {
+ sp<::android::hardware::wifi::hostapd::V1_3::IHostapd> hostapd_1_3 =
+ ::android::hardware::wifi::hostapd::V1_3::IHostapd::castFrom(hostapd);
+ return hostapd_1_3.get() != nullptr;
+}
+
/**
* Adds an access point with PSK network config & ACS enabled.
* Access point creation should pass.
*/
TEST_P(HostapdHidlTest, AddPskAccessPointWithAcs) {
if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
+ if (is_1_3(hostapd_))
+ GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
getIfaceParamsWithAcs(), getPskNwParams());
EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
@@ -233,6 +242,8 @@
*/
TEST_P(HostapdHidlTest, AddPskAccessPointWithAcsAndFreqRange) {
if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
+ if (is_1_3(hostapd_))
+ GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
auto status =
HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
getIfaceParamsWithAcsAndFreqRange(), getPskNwParams());
@@ -245,6 +256,8 @@
*/
TEST_P(HostapdHidlTest, AddPskAccessPointWithAcsAndInvalidFreqRange) {
if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
+ if (is_1_3(hostapd_))
+ GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
getIfaceParamsWithAcsAndInvalidFreqRange(),
getPskNwParams());
@@ -257,6 +270,8 @@
*/
TEST_P(HostapdHidlTest, AddOpenAccessPointWithAcs) {
if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
+ if (is_1_3(hostapd_))
+ GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
getIfaceParamsWithAcs(), getOpenNwParams());
EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
@@ -267,6 +282,8 @@
* Access point creation should pass.
*/
TEST_P(HostapdHidlTest, AddPskAccessPointWithoutAcs) {
+ if (is_1_3(hostapd_))
+ GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
getIfaceParamsWithoutAcs(), getPskNwParams());
EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
@@ -277,6 +294,8 @@
* Access point creation should pass.
*/
TEST_P(HostapdHidlTest, AddOpenAccessPointWithoutAcs) {
+ if (is_1_3(hostapd_))
+ GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
getIfaceParamsWithoutAcs(), getOpenNwParams());
EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
@@ -288,6 +307,8 @@
*/
TEST_P(HostapdHidlTest, AddSaeTransitionAccessPointWithoutAcs) {
if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support";
+ if (is_1_3(hostapd_))
+ GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
auto status =
HIDL_INVOKE(hostapd_, addAccessPoint_1_2, getIfaceParamsWithoutAcs(),
getSaeTransitionNwParams());
@@ -300,6 +321,8 @@
*/
TEST_P(HostapdHidlTest, AddSAEAccessPointWithoutAcs) {
if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support";
+ if (is_1_3(hostapd_))
+ GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
getIfaceParamsWithoutAcs(), getSaeNwParams());
EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
@@ -311,6 +334,8 @@
*/
TEST_P(HostapdHidlTest, RemoveAccessPointWithAcs) {
if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
+ if (is_1_3(hostapd_))
+ GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
auto status_1_2 = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
getIfaceParamsWithAcs(), getPskNwParams());
EXPECT_EQ(HostapdStatusCode::SUCCESS, status_1_2.code);
@@ -326,6 +351,8 @@
* Access point creation & removal should pass.
*/
TEST_P(HostapdHidlTest, RemoveAccessPointWithoutAcs) {
+ if (is_1_3(hostapd_))
+ GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
auto status_1_2 = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
getIfaceParamsWithoutAcs(), getPskNwParams());
EXPECT_EQ(HostapdStatusCode::SUCCESS, status_1_2.code);
@@ -341,6 +368,8 @@
* Access point creation should fail.
*/
TEST_P(HostapdHidlTest, AddPskAccessPointWithInvalidChannel) {
+ if (is_1_3(hostapd_))
+ GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
auto status =
HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
getIfaceParamsWithInvalidChannel(), getPskNwParams());
@@ -352,6 +381,8 @@
* Access point creation should fail.
*/
TEST_P(HostapdHidlTest, AddInvalidPskAccessPointWithoutAcs) {
+ if (is_1_3(hostapd_))
+ GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
auto status =
HIDL_INVOKE(hostapd_, addAccessPoint_1_2, getIfaceParamsWithoutAcs(),
getInvalidPskNwParams());
@@ -364,6 +395,8 @@
*/
TEST_P(HostapdHidlTest, AddInvalidSaeTransitionAccessPointWithoutAcs) {
if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support";
+ if (is_1_3(hostapd_))
+ GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
auto status =
HIDL_INVOKE(hostapd_, addAccessPoint_1_2, getIfaceParamsWithoutAcs(),
getInvalidSaeTransitionNwParams());
@@ -376,6 +409,8 @@
*/
TEST_P(HostapdHidlTest, AddInvalidSaeAccessPointWithoutAcs) {
if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support";
+ if (is_1_3(hostapd_))
+ GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
auto status =
HIDL_INVOKE(hostapd_, addAccessPoint_1_2, getIfaceParamsWithoutAcs(),
getInvalidSaeNwParams());
@@ -398,6 +433,8 @@
* when hotspot interface available.
*/
TEST_P(HostapdHidlTest, DisconnectClientWhenIfacAvailable) {
+ if (is_1_3(hostapd_))
+ GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
auto status_1_2 =
HIDL_INVOKE(hostapd_, addAccessPoint_1_2, getIfaceParamsWithoutAcs(),
getOpenNwParams());
diff --git a/wifi/hostapd/1.3/vts/OWNERS b/wifi/hostapd/1.3/vts/OWNERS
new file mode 100644
index 0000000..8bfb148
--- /dev/null
+++ b/wifi/hostapd/1.3/vts/OWNERS
@@ -0,0 +1,2 @@
+rpius@google.com
+etancohen@google.com
diff --git a/wifi/hostapd/1.3/vts/functional/Android.bp b/wifi/hostapd/1.3/vts/functional/Android.bp
new file mode 100644
index 0000000..07cebb0
--- /dev/null
+++ b/wifi/hostapd/1.3/vts/functional/Android.bp
@@ -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.
+//
+
+cc_test {
+ name: "VtsHalWifiHostapdV1_3TargetTest",
+ defaults: ["VtsHalTargetTestDefaults"],
+ srcs: [
+ "hostapd_hidl_test.cpp",
+ ],
+ static_libs: [
+ "VtsHalWifiV1_0TargetTestUtil",
+ "VtsHalWifiHostapdV1_0TargetTestUtil",
+ "android.hardware.wifi.hostapd@1.0",
+ "android.hardware.wifi.hostapd@1.1",
+ "android.hardware.wifi.hostapd@1.2",
+ "android.hardware.wifi.hostapd@1.3",
+ "android.hardware.wifi@1.0",
+ "libgmock",
+ "libwifi-system",
+ "libwifi-system-iface",
+ ],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
+}
diff --git a/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp b/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp
new file mode 100644
index 0000000..d6c750f
--- /dev/null
+++ b/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp
@@ -0,0 +1,433 @@
+/*
+ * 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 <VtsCoreUtil.h>
+
+#include <android-base/logging.h>
+#include <cutils/properties.h>
+
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+
+#include <android/hardware/wifi/1.0/IWifi.h>
+#include <android/hardware/wifi/hostapd/1.3/IHostapd.h>
+
+#include "hostapd_hidl_call_util.h"
+#include "hostapd_hidl_test_utils.h"
+
+using ::android::sp;
+using ::android::hardware::hidl_string;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::wifi::hostapd::V1_2::DebugLevel;
+using ::android::hardware::wifi::hostapd::V1_2::HostapdStatusCode;
+using ::android::hardware::wifi::hostapd::V1_2::Ieee80211ReasonCode;
+using ::android::hardware::wifi::hostapd::V1_3::IHostapd;
+using ::android::hardware::wifi::V1_0::IWifi;
+
+namespace {
+constexpr unsigned char kNwSsid[] = {'t', 'e', 's', 't', '1',
+ '2', '3', '4', '5'};
+constexpr char kNwPassphrase[] = "test12345";
+constexpr char kInvalidMaxPskNwPassphrase[] =
+ "0123456789012345678901234567890123456789012345678901234567890123456789";
+constexpr char kInvalidMinPskNwPassphrase[] = "test";
+constexpr int kIfaceChannel = 6;
+constexpr int kIfaceInvalidChannel = 567;
+constexpr uint8_t kTestZeroMacAddr[] = {[0 ... 5] = 0x0};
+constexpr Ieee80211ReasonCode kTestDisconnectReasonCode =
+ Ieee80211ReasonCode::WLAN_REASON_UNSPECIFIED;
+} // namespace
+
+class HostapdHidlTest
+ : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {
+ public:
+ virtual void SetUp() override {
+ wifi_instance_name_ = std::get<0>(GetParam());
+ hostapd_instance_name_ = std::get<1>(GetParam());
+ stopSupplicantIfNeeded(wifi_instance_name_);
+ startHostapdAndWaitForHidlService(wifi_instance_name_,
+ hostapd_instance_name_);
+ hostapd_ = IHostapd::getService(hostapd_instance_name_);
+ ASSERT_NE(hostapd_.get(), nullptr);
+ HIDL_INVOKE(hostapd_, setDebugParams, DebugLevel::EXCESSIVE);
+ isAcsSupport_ = testing::checkSubstringInCommandOutput(
+ "/system/bin/cmd wifi get-softap-supported-features",
+ "wifi_softap_acs_supported");
+ isWpa3SaeSupport_ = testing::checkSubstringInCommandOutput(
+ "/system/bin/cmd wifi get-softap-supported-features",
+ "wifi_softap_wpa3_sae_supported");
+ }
+
+ virtual void TearDown() override {
+ HIDL_INVOKE_VOID_WITHOUT_ARGUMENTS(hostapd_, terminate);
+ stopHostapd(wifi_instance_name_);
+ }
+
+ protected:
+ bool isWpa3SaeSupport_ = false;
+ bool isAcsSupport_ = false;
+ std::string getPrimaryWlanIfaceName() {
+ std::array<char, PROPERTY_VALUE_MAX> buffer;
+ auto res = property_get("ro.vendor.wifi.sap.interface", buffer.data(),
+ nullptr);
+ if (res > 0) return buffer.data();
+ property_get("wifi.interface", buffer.data(), "wlan0");
+ return buffer.data();
+ }
+
+ IHostapd::IfaceParams getIfaceParamsWithoutAcs() {
+ ::android::hardware::wifi::hostapd::V1_0::IHostapd::IfaceParams
+ iface_params;
+ ::android::hardware::wifi::hostapd::V1_1::IHostapd::IfaceParams
+ iface_params_1_1;
+ IHostapd::IfaceParams iface_params_1_2;
+
+ iface_params.ifaceName = getPrimaryWlanIfaceName();
+ iface_params.hwModeParams.enable80211N = true;
+ iface_params.hwModeParams.enable80211AC = false;
+ iface_params.channelParams.enableAcs = false;
+ iface_params.channelParams.acsShouldExcludeDfs = false;
+ iface_params.channelParams.channel = kIfaceChannel;
+ iface_params_1_1.V1_0 = iface_params;
+ iface_params_1_2.V1_1 = iface_params_1_1;
+ // Newly added attributes in V1_2
+ iface_params_1_2.hwModeParams.enable80211AX = false;
+ iface_params_1_2.hwModeParams.enable6GhzBand = false;
+ iface_params_1_2.channelParams.bandMask = 0;
+ iface_params_1_2.channelParams.bandMask |=
+ IHostapd::BandMask::BAND_2_GHZ;
+ return iface_params_1_2;
+ }
+
+ IHostapd::IfaceParams getIfaceParamsWithAcs() {
+ // First get the settings for WithoutAcs and then make changes
+ IHostapd::IfaceParams iface_params_1_2 = getIfaceParamsWithoutAcs();
+ iface_params_1_2.V1_1.V1_0.channelParams.enableAcs = true;
+ iface_params_1_2.V1_1.V1_0.channelParams.acsShouldExcludeDfs = true;
+ iface_params_1_2.V1_1.V1_0.channelParams.channel = 0;
+ iface_params_1_2.channelParams.bandMask |=
+ IHostapd::BandMask::BAND_5_GHZ;
+
+ return iface_params_1_2;
+ }
+
+ IHostapd::IfaceParams getIfaceParamsWithAcsAndFreqRange() {
+ IHostapd::IfaceParams iface_params_1_2 = getIfaceParamsWithAcs();
+ ::android::hardware::wifi::hostapd::V1_2::IHostapd::AcsFrequencyRange
+ acsFrequencyRange;
+ acsFrequencyRange.start = 2412;
+ acsFrequencyRange.end = 2462;
+ std::vector<::android::hardware::wifi::hostapd::V1_2::IHostapd::
+ AcsFrequencyRange>
+ vec_acsFrequencyRange;
+ vec_acsFrequencyRange.push_back(acsFrequencyRange);
+ iface_params_1_2.channelParams.acsChannelFreqRangesMhz =
+ vec_acsFrequencyRange;
+ return iface_params_1_2;
+ }
+
+ IHostapd::IfaceParams getIfaceParamsWithAcsAndInvalidFreqRange() {
+ IHostapd::IfaceParams iface_params_1_2 =
+ getIfaceParamsWithAcsAndFreqRange();
+ iface_params_1_2.channelParams.acsChannelFreqRangesMhz[0].start = 222;
+ iface_params_1_2.channelParams.acsChannelFreqRangesMhz[0].end = 999;
+ return iface_params_1_2;
+ }
+
+ IHostapd::NetworkParams getOpenNwParams() {
+ IHostapd::NetworkParams nw_params_1_3;
+ ::android::hardware::wifi::hostapd::V1_2::IHostapd::NetworkParams
+ nw_params_1_2;
+ ::android::hardware::wifi::hostapd::V1_0::IHostapd::NetworkParams
+ nw_params_1_0;
+ nw_params_1_0.ssid =
+ std::vector<uint8_t>(kNwSsid, kNwSsid + sizeof(kNwSsid));
+ nw_params_1_0.isHidden = false;
+ nw_params_1_2.V1_0 = nw_params_1_0;
+ nw_params_1_2.encryptionType = IHostapd::EncryptionType::NONE;
+ nw_params_1_3.V1_2 = nw_params_1_2;
+ nw_params_1_3.isMetered = true;
+ return nw_params_1_3;
+ }
+
+ IHostapd::NetworkParams getPskNwParamsWithNonMetered() {
+ IHostapd::NetworkParams nw_params_1_3 = getOpenNwParams();
+ nw_params_1_3.V1_2.encryptionType = IHostapd::EncryptionType::WPA2;
+ nw_params_1_3.V1_2.passphrase = kNwPassphrase;
+ nw_params_1_3.isMetered = false;
+ return nw_params_1_3;
+ }
+
+ IHostapd::NetworkParams getPskNwParams() {
+ IHostapd::NetworkParams nw_params_1_3 = getOpenNwParams();
+ nw_params_1_3.V1_2.encryptionType = IHostapd::EncryptionType::WPA2;
+ nw_params_1_3.V1_2.passphrase = kNwPassphrase;
+ return nw_params_1_3;
+ }
+
+ IHostapd::NetworkParams getInvalidPskNwParams() {
+ IHostapd::NetworkParams nw_params_1_3 = getOpenNwParams();
+ nw_params_1_3.V1_2.encryptionType = IHostapd::EncryptionType::WPA2;
+ nw_params_1_3.V1_2.passphrase = kInvalidMaxPskNwPassphrase;
+
+ return nw_params_1_3;
+ }
+
+ IHostapd::NetworkParams getSaeTransitionNwParams() {
+ IHostapd::NetworkParams nw_params_1_3 = getOpenNwParams();
+ nw_params_1_3.V1_2.encryptionType =
+ IHostapd::EncryptionType::WPA3_SAE_TRANSITION;
+ nw_params_1_3.V1_2.passphrase = kNwPassphrase;
+ return nw_params_1_3;
+ }
+
+ IHostapd::NetworkParams getInvalidSaeTransitionNwParams() {
+ IHostapd::NetworkParams nw_params_1_3 = getOpenNwParams();
+ nw_params_1_3.V1_2.encryptionType = IHostapd::EncryptionType::WPA2;
+ nw_params_1_3.V1_2.passphrase = kInvalidMinPskNwPassphrase;
+ return nw_params_1_3;
+ }
+
+ IHostapd::NetworkParams getSaeNwParams() {
+ IHostapd::NetworkParams nw_params_1_3 = getOpenNwParams();
+ nw_params_1_3.V1_2.encryptionType = IHostapd::EncryptionType::WPA3_SAE;
+ nw_params_1_3.V1_2.passphrase = kNwPassphrase;
+ return nw_params_1_3;
+ }
+
+ IHostapd::NetworkParams getInvalidSaeNwParams() {
+ IHostapd::NetworkParams nw_params_1_3 = getOpenNwParams();
+ nw_params_1_3.V1_2.encryptionType = IHostapd::EncryptionType::WPA3_SAE;
+ nw_params_1_3.V1_2.passphrase = "";
+ return nw_params_1_3;
+ }
+
+ IHostapd::IfaceParams getIfaceParamsWithInvalidChannel() {
+ IHostapd::IfaceParams iface_params_1_2 = getIfaceParamsWithoutAcs();
+ iface_params_1_2.V1_1.V1_0.channelParams.channel = kIfaceInvalidChannel;
+ return iface_params_1_2;
+ }
+
+ // IHostapd object used for all tests in this fixture.
+ sp<IHostapd> hostapd_;
+ std::string wifi_instance_name_;
+ std::string hostapd_instance_name_;
+};
+
+/**
+ * Adds an access point with PSK network config & ACS enabled.
+ * Access point creation should pass.
+ */
+TEST_P(HostapdHidlTest, AddPskAccessPointWithAcs) {
+ if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
+ auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3,
+ getIfaceParamsWithAcs(), getPskNwParams());
+ EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
+}
+
+/**
+ * Adds an access point with PSK network config, ACS enabled & frequency Range.
+ * Access point creation should pass.
+ */
+TEST_P(HostapdHidlTest, AddPskAccessPointWithAcsAndFreqRange) {
+ if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
+ auto status =
+ HIDL_INVOKE(hostapd_, addAccessPoint_1_3,
+ getIfaceParamsWithAcsAndFreqRange(), getPskNwParams());
+ EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
+}
+
+/**
+ * Adds an access point with invalid channel range.
+ * Access point creation should fail.
+ */
+TEST_P(HostapdHidlTest, AddPskAccessPointWithAcsAndInvalidFreqRange) {
+ if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
+ auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3,
+ getIfaceParamsWithAcsAndInvalidFreqRange(),
+ getPskNwParams());
+ EXPECT_NE(HostapdStatusCode::SUCCESS, status.code);
+}
+
+/**
+ * Adds an access point with Open network config & ACS enabled.
+ * Access point creation should pass.
+ */
+TEST_P(HostapdHidlTest, AddOpenAccessPointWithAcs) {
+ if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
+ auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3,
+ getIfaceParamsWithAcs(), getOpenNwParams());
+ EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
+}
+
+/**
+ * Adds an access point with PSK network config & ACS disabled.
+ * Access point creation should pass.
+ */
+TEST_P(HostapdHidlTest, AddPskAccessPointWithoutAcs) {
+ auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3,
+ getIfaceParamsWithoutAcs(), getPskNwParams());
+ EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
+}
+
+/**
+ * Adds an access point with PSK network config, ACS disabled & Non metered.
+ * Access point creation should pass.
+ */
+TEST_P(HostapdHidlTest, AddPskAccessPointWithoutAcsAndNonMetered) {
+ auto status =
+ HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(),
+ getPskNwParamsWithNonMetered());
+ EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
+}
+
+/**
+ * Adds an access point with Open network config & ACS disabled.
+ * Access point creation should pass.
+ */
+TEST_P(HostapdHidlTest, AddOpenAccessPointWithoutAcs) {
+ auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3,
+ getIfaceParamsWithoutAcs(), getOpenNwParams());
+ EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
+}
+
+/**
+ * Adds an access point with SAE Transition network config & ACS disabled.
+ * Access point creation should pass.
+ */
+TEST_P(HostapdHidlTest, AddSaeTransitionAccessPointWithoutAcs) {
+ if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support";
+ auto status =
+ HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(),
+ getSaeTransitionNwParams());
+ EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
+}
+
+/**
+ * Adds an access point with SAE network config & ACS disabled.
+ * Access point creation should pass.
+ */
+TEST_P(HostapdHidlTest, AddSAEAccessPointWithoutAcs) {
+ if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support";
+ auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3,
+ getIfaceParamsWithoutAcs(), getSaeNwParams());
+ EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
+}
+
+/**
+ * Adds & then removes an access point with PSK network config & ACS enabled.
+ * Access point creation & removal should pass.
+ */
+TEST_P(HostapdHidlTest, RemoveAccessPointWithAcs) {
+ if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
+ auto status_1_2 = HIDL_INVOKE(hostapd_, addAccessPoint_1_3,
+ getIfaceParamsWithAcs(), getPskNwParams());
+ EXPECT_EQ(HostapdStatusCode::SUCCESS, status_1_2.code);
+ auto status =
+ HIDL_INVOKE(hostapd_, removeAccessPoint, getPrimaryWlanIfaceName());
+ EXPECT_EQ(
+ android::hardware::wifi::hostapd::V1_0::HostapdStatusCode::SUCCESS,
+ status.code);
+}
+
+/**
+ * Adds & then removes an access point with PSK network config & ACS disabled.
+ * Access point creation & removal should pass.
+ */
+TEST_P(HostapdHidlTest, RemoveAccessPointWithoutAcs) {
+ auto status_1_2 = HIDL_INVOKE(hostapd_, addAccessPoint_1_3,
+ getIfaceParamsWithoutAcs(), getPskNwParams());
+ EXPECT_EQ(HostapdStatusCode::SUCCESS, status_1_2.code);
+ auto status =
+ HIDL_INVOKE(hostapd_, removeAccessPoint, getPrimaryWlanIfaceName());
+ EXPECT_EQ(
+ android::hardware::wifi::hostapd::V1_0::HostapdStatusCode::SUCCESS,
+ status.code);
+}
+
+/**
+ * Adds an access point with invalid channel.
+ * Access point creation should fail.
+ */
+TEST_P(HostapdHidlTest, AddPskAccessPointWithInvalidChannel) {
+ auto status =
+ HIDL_INVOKE(hostapd_, addAccessPoint_1_3,
+ getIfaceParamsWithInvalidChannel(), getPskNwParams());
+ EXPECT_NE(HostapdStatusCode::SUCCESS, status.code);
+}
+
+/**
+ * Adds an access point with invalid PSK network config.
+ * Access point creation should fail.
+ */
+TEST_P(HostapdHidlTest, AddInvalidPskAccessPointWithoutAcs) {
+ auto status =
+ HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(),
+ getInvalidPskNwParams());
+ EXPECT_NE(HostapdStatusCode::SUCCESS, status.code);
+}
+
+/**
+ * Adds an access point with invalid SAE transition network config.
+ * Access point creation should fail.
+ */
+TEST_P(HostapdHidlTest, AddInvalidSaeTransitionAccessPointWithoutAcs) {
+ if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support";
+ auto status =
+ HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(),
+ getInvalidSaeTransitionNwParams());
+ EXPECT_NE(HostapdStatusCode::SUCCESS, status.code);
+}
+
+/**
+ * Adds an access point with invalid SAE network config.
+ * Access point creation should fail.
+ */
+TEST_P(HostapdHidlTest, AddInvalidSaeAccessPointWithoutAcs) {
+ if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support";
+ auto status =
+ HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(),
+ getInvalidSaeNwParams());
+ EXPECT_NE(HostapdStatusCode::SUCCESS, status.code);
+}
+
+/**
+ * forceClientDisconnect should return FAILURE_CLIENT_UNKNOWN
+ * when hotspot interface available.
+ */
+TEST_P(HostapdHidlTest, DisconnectClientWhenIfacAvailable) {
+ auto status_1_2 =
+ HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(),
+ getOpenNwParams());
+ EXPECT_EQ(HostapdStatusCode::SUCCESS, status_1_2.code);
+
+ status_1_2 =
+ HIDL_INVOKE(hostapd_, forceClientDisconnect, getPrimaryWlanIfaceName(),
+ kTestZeroMacAddr, kTestDisconnectReasonCode);
+ EXPECT_EQ(HostapdStatusCode::FAILURE_CLIENT_UNKNOWN, status_1_2.code);
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HostapdHidlTest);
+INSTANTIATE_TEST_CASE_P(
+ PerInstance, HostapdHidlTest,
+ testing::Combine(
+ testing::ValuesIn(
+ android::hardware::getAllHalInstanceNames(IWifi::descriptor)),
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+ android::hardware::wifi::hostapd::V1_2::IHostapd::descriptor))),
+ android::hardware::PrintInstanceTupleNameToString<>);
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp
index da3996b..be6aad9 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp
@@ -52,6 +52,10 @@
// Helper function to initialize the driver and firmware to STA mode
// using the vendor HAL HIDL interface.
void initilializeDriverAndFirmware(const std::string& wifi_instance_name) {
+ // Skip if wifi instance is not set.
+ if (wifi_instance_name == "") {
+ return;
+ }
if (getWifi(wifi_instance_name) != nullptr) {
sp<IWifiChip> wifi_chip = getWifiChip(wifi_instance_name);
ChipModeId mode_id;
@@ -65,6 +69,10 @@
// Helper function to deinitialize the driver and firmware
// using the vendor HAL HIDL interface.
void deInitilializeDriverAndFirmware(const std::string& wifi_instance_name) {
+ // Skip if wifi instance is not set.
+ if (wifi_instance_name == "") {
+ return;
+ }
if (getWifi(wifi_instance_name) != nullptr) {
stopWifi(wifi_instance_name);
} else {
diff --git a/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp b/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp
index 3c4d06b..8d7ea54 100644
--- a/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp
+++ b/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp
@@ -33,6 +33,7 @@
using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode;
using ::android::hardware::wifi::supplicant::V1_0::IfaceType;
using ::android::hardware::wifi::supplicant::V1_1::ISupplicant;
+using ::android::hardware::wifi::V1_0::IWifi;
using ::android::sp;
class SupplicantHidlTest : public SupplicantHidlTestBaseV1_1 {
@@ -139,21 +140,12 @@
*/
TEST_P(SupplicantHidlTest, Terminate) { supplicant_->terminate(); }
-static std::vector<std::string> get_wifi_instances() {
- std::vector<std::string> instances =
- android::hardware::getAllHalInstanceNames(
- android::hardware::wifi::V1_0::IWifi::descriptor);
- // Also test when wifi instance is not set.
- instances.push_back("");
-
- return instances;
-}
-
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantHidlTest);
INSTANTIATE_TEST_CASE_P(
PerInstance, SupplicantHidlTest,
testing::Combine(
- testing::ValuesIn(get_wifi_instances()),
+ testing::ValuesIn(
+ android::hardware::getAllHalInstanceNames(IWifi::descriptor)),
testing::ValuesIn(android::hardware::getAllHalInstanceNames(
android::hardware::wifi::supplicant::V1_1::ISupplicant::
descriptor))),