diff options
author | Daniel Norman <danielnorman@google.com> | 2021-02-08 11:11:06 -0800 |
---|---|---|
committer | Daniel Norman <danielnorman@google.com> | 2021-02-08 14:07:55 -0800 |
commit | f86b976dba9b016816efa57156e791fffd498d64 (patch) | |
tree | 62e68f2885e6a7a73bf3386e8459f8fe98528ade | |
parent | a0da4d07b75fa61fcb4f5648ba304cbf4ac50f6a (diff) | |
parent | 7fd5ae363319c3d8fa9128c39075ea82799989ab (diff) |
Merge SP1A.210208.001
Change-Id: I0c596171de3bcead62935db7388b784e55444080
422 files changed, 9866 insertions, 3839 deletions
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg index 6740bb5397..2116e21c5a 100644 --- a/PREUPLOAD.cfg +++ b/PREUPLOAD.cfg @@ -4,6 +4,7 @@ ignore_merged_commits = true [Builtin Hooks] bpfmt = true clang_format = true +aidl_format = true [Hook Scripts] aosp_hook_confirmationui = ${REPO_ROOT}/frameworks/base/tools/aosp/aosp_sha.sh ${PREUPLOAD_COMMIT} confirmationui diff --git a/audio/5.0/config/api/current.txt b/audio/5.0/config/api/current.txt index a1d8e1e08b..8458a569c5 100644 --- a/audio/5.0/config/api/current.txt +++ b/audio/5.0/config/api/current.txt @@ -133,6 +133,7 @@ package audio.policy.configuration.V5_0 { enum_constant public static final audio.policy.configuration.V5_0.AudioFormat AUDIO_FORMAT_LDAC; enum_constant public static final audio.policy.configuration.V5_0.AudioFormat AUDIO_FORMAT_LHDC; enum_constant public static final audio.policy.configuration.V5_0.AudioFormat AUDIO_FORMAT_LHDC_LL; + enum_constant public static final audio.policy.configuration.V5_0.AudioFormat AUDIO_FORMAT_MAT; enum_constant public static final audio.policy.configuration.V5_0.AudioFormat AUDIO_FORMAT_MAT_1_0; enum_constant public static final audio.policy.configuration.V5_0.AudioFormat AUDIO_FORMAT_MAT_2_0; enum_constant public static final audio.policy.configuration.V5_0.AudioFormat AUDIO_FORMAT_MAT_2_1; diff --git a/audio/5.0/config/audio_policy_configuration.xsd b/audio/5.0/config/audio_policy_configuration.xsd index 284d2e27b4..b0d1e204bb 100644 --- a/audio/5.0/config/audio_policy_configuration.xsd +++ b/audio/5.0/config/audio_policy_configuration.xsd @@ -361,6 +361,7 @@ <xs:enumeration value="AUDIO_FORMAT_AC4"/> <xs:enumeration value="AUDIO_FORMAT_LDAC"/> <xs:enumeration value="AUDIO_FORMAT_E_AC3_JOC"/> + <xs:enumeration value="AUDIO_FORMAT_MAT"/> <xs:enumeration value="AUDIO_FORMAT_MAT_1_0"/> <xs:enumeration value="AUDIO_FORMAT_MAT_2_0"/> <xs:enumeration value="AUDIO_FORMAT_MAT_2_1"/> diff --git a/audio/6.0/config/api/current.txt b/audio/6.0/config/api/current.txt index 6b49e5ed31..f5d4798603 100644 --- a/audio/6.0/config/api/current.txt +++ b/audio/6.0/config/api/current.txt @@ -133,6 +133,7 @@ package audio.policy.configuration.V6_0 { enum_constant public static final audio.policy.configuration.V6_0.AudioFormat AUDIO_FORMAT_LDAC; enum_constant public static final audio.policy.configuration.V6_0.AudioFormat AUDIO_FORMAT_LHDC; enum_constant public static final audio.policy.configuration.V6_0.AudioFormat AUDIO_FORMAT_LHDC_LL; + enum_constant public static final audio.policy.configuration.V6_0.AudioFormat AUDIO_FORMAT_MAT; enum_constant public static final audio.policy.configuration.V6_0.AudioFormat AUDIO_FORMAT_MAT_1_0; enum_constant public static final audio.policy.configuration.V6_0.AudioFormat AUDIO_FORMAT_MAT_2_0; enum_constant public static final audio.policy.configuration.V6_0.AudioFormat AUDIO_FORMAT_MAT_2_1; diff --git a/audio/6.0/config/audio_policy_configuration.xsd b/audio/6.0/config/audio_policy_configuration.xsd index 341c6b337a..ead1cc20c4 100644 --- a/audio/6.0/config/audio_policy_configuration.xsd +++ b/audio/6.0/config/audio_policy_configuration.xsd @@ -363,6 +363,7 @@ <xs:enumeration value="AUDIO_FORMAT_AC4"/> <xs:enumeration value="AUDIO_FORMAT_LDAC"/> <xs:enumeration value="AUDIO_FORMAT_E_AC3_JOC"/> + <xs:enumeration value="AUDIO_FORMAT_MAT"/> <xs:enumeration value="AUDIO_FORMAT_MAT_1_0"/> <xs:enumeration value="AUDIO_FORMAT_MAT_2_0"/> <xs:enumeration value="AUDIO_FORMAT_MAT_2_1"/> diff --git a/audio/7.0/IStream.hal b/audio/7.0/IStream.hal index ab9aa7dae3..393e38f6a0 100644 --- a/audio/7.0/IStream.hal +++ b/audio/7.0/IStream.hal @@ -73,14 +73,14 @@ interface IStream { /** * Sets stream parameters. Only sets parameters that are specified. - * 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(AudioConfigBase config) generates (Result retval); + setAudioProperties(AudioConfigBaseOptional config) + generates (Result retval); /** * Applies audio effect to the stream. diff --git a/audio/7.0/config/api/current.txt b/audio/7.0/config/api/current.txt index 0b2e4a4d85..49cfd388ff 100644 --- a/audio/7.0/config/api/current.txt +++ b/audio/7.0/config/api/current.txt @@ -198,6 +198,7 @@ package android.audio.policy.configuration.V7_0 { enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_APTX_HD; enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_APTX_TWSP; enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_CELT; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DEFAULT; enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DOLBY_TRUEHD; enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DSD; enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DTS; @@ -222,6 +223,10 @@ package android.audio.policy.configuration.V7_0 { enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MAT_2_1; enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MP2; enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MP3; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MPEGH_BL_L3; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MPEGH_BL_L4; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MPEGH_LC_L3; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MPEGH_LC_L4; enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_OPUS; enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_PCM_16_BIT; enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_PCM_24_BIT_PACKED; @@ -250,7 +255,6 @@ package android.audio.policy.configuration.V7_0 { enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_HW_AV_SYNC; enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_HW_HOTWORD; enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_MMAP_NOIRQ; - enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_NONE; enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_RAW; enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_SYNC; enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_VOIP_TX; @@ -264,7 +268,6 @@ package android.audio.policy.configuration.V7_0 { enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO; enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_INCALL_MUSIC; enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_MMAP_NOIRQ; - enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_NONE; enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_NON_BLOCKING; enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_PRIMARY; enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_RAW; @@ -542,7 +545,7 @@ package android.audio.policy.configuration.V7_0 { public enum Version { method @NonNull public String getRawName(); - enum_constant public static final android.audio.policy.configuration.V7_0.Version _1_0; + enum_constant public static final android.audio.policy.configuration.V7_0.Version _7_0; } public class Volume { diff --git a/audio/7.0/config/audio_policy_configuration.xsd b/audio/7.0/config/audio_policy_configuration.xsd index a735c6de39..f20033d239 100644 --- a/audio/7.0/config/audio_policy_configuration.xsd +++ b/audio/7.0/config/audio_policy_configuration.xsd @@ -20,7 +20,7 @@ <!-- List the config versions supported by audio policy. --> <xs:simpleType name="version"> <xs:restriction base="xs:decimal"> - <xs:enumeration value="1.0"/> + <xs:enumeration value="7.0"/> </xs:restriction> </xs:simpleType> <xs:simpleType name="halVersion"> @@ -159,13 +159,9 @@ <xs:annotation> <xs:documentation xml:lang="en"> The flags indicate suggested stream attributes supported by the profile. - Use of AUDIO_{INPUT|OUTPUT}_FLAG_NONE in the XML file isn't required - as empty flag lists are allowed. However these constants are useful for - representing an empty enum value. </xs:documentation> </xs:annotation> <xs:restriction base="xs:string"> - <xs:enumeration value="AUDIO_OUTPUT_FLAG_NONE" /> <xs:enumeration value="AUDIO_OUTPUT_FLAG_DIRECT" /> <xs:enumeration value="AUDIO_OUTPUT_FLAG_PRIMARY" /> <xs:enumeration value="AUDIO_OUTPUT_FLAG_FAST" /> @@ -182,7 +178,6 @@ <xs:enumeration value="AUDIO_OUTPUT_FLAG_VOIP_RX" /> <xs:enumeration value="AUDIO_OUTPUT_FLAG_INCALL_MUSIC" /> <xs:enumeration value="AUDIO_OUTPUT_FLAG_GAPLESS_OFFLOAD" /> - <xs:enumeration value="AUDIO_INPUT_FLAG_NONE" /> <xs:enumeration value="AUDIO_INPUT_FLAG_FAST" /> <xs:enumeration value="AUDIO_INPUT_FLAG_HW_HOTWORD" /> <xs:enumeration value="AUDIO_INPUT_FLAG_RAW" /> @@ -330,6 +325,7 @@ </xs:simpleType> <xs:simpleType name="audioFormat"> <xs:restriction base="xs:string"> + <xs:enumeration value="AUDIO_FORMAT_DEFAULT" /> <xs:enumeration value="AUDIO_FORMAT_PCM_16_BIT" /> <xs:enumeration value="AUDIO_FORMAT_PCM_8_BIT"/> <xs:enumeration value="AUDIO_FORMAT_PCM_32_BIT"/> @@ -407,6 +403,10 @@ <xs:enumeration value="AUDIO_FORMAT_LHDC_LL"/> <xs:enumeration value="AUDIO_FORMAT_APTX_TWSP"/> <xs:enumeration value="AUDIO_FORMAT_LC3"/> + <xs:enumeration value="AUDIO_FORMAT_MPEGH_BL_L3"/> + <xs:enumeration value="AUDIO_FORMAT_MPEGH_BL_L4"/> + <xs:enumeration value="AUDIO_FORMAT_MPEGH_LC_L3"/> + <xs:enumeration value="AUDIO_FORMAT_MPEGH_LC_L4"/> </xs:restriction> </xs:simpleType> <xs:simpleType name="extendableAudioFormat"> diff --git a/audio/7.0/config/update_audio_policy_config.sh b/audio/7.0/config/update_audio_policy_config.sh index 051a0df916..159fa35946 100755 --- a/audio/7.0/config/update_audio_policy_config.sh +++ b/audio/7.0/config/update_audio_policy_config.sh @@ -113,6 +113,9 @@ echo "Will update paths to shared included files." echo "Press Ctrl-C to cancel, Enter to continue" read +# Update 'audioPolicyConfiguration version="1.0"' -> 7.0 in the main file +sed -i -r -e 's/(audioPolicyConfiguration version=")1.0/\17.0/' ${SOURCE_CONFIG} + updateFile() { FILE=$1 ATTR=$2 diff --git a/audio/README.md b/audio/README.md index b77b9ba42d..1938ad4d11 100644 --- a/audio/README.md +++ b/audio/README.md @@ -7,47 +7,49 @@ based on an existing one. ## Directory Structure -* `2.0` -- version 2.0 of the core HIDL API. Note that `.hal` files +* `2.0` — version 2.0 of the core HIDL API. Note that `.hal` files can not be moved into the `core` directory because that would change its namespace and include path. - - `config` -- the XSD schema for the Audio Policy Manager + - `config` — the XSD schema for the Audio Policy Manager configuration file. -* `4.0` -- version 4.0 of the core HIDL API. +* `4.0` — version 4.0 of the core HIDL API. * ... -* `common` -- common types for audio core and effect HIDL API. - - `2.0` -- version 2.0 of the common types HIDL API. - - `4.0` -- version 4.0. +* `common` — common types for audio core and effect HIDL API. + - `2.0` — version 2.0 of the common types HIDL API. + - `4.0` — version 4.0. - ... - - `7.0` -- version 7.0. - - `example` -- example implementation of the core and effect + - `7.0` — version 7.0. + - `example` — example implementation of the core and effect V7.0 API. It represents a "fake" audio HAL that doesn't actually communicate with hardware. - - `all-versions` -- code common to all version of both core and effect API. - - `default` -- shared code of the default implementation. - - `service` -- vendor HAL service for hosting the default + - `all-versions` — code common to all version of both core and effect API. + - `default` — shared code of the default implementation. + - `service` — vendor HAL service for hosting the default implementation. - - `test` -- utilities used by tests. - - `util` -- utilities used by both implementation and tests. -* `core` -- VTS tests and the default implementation of the core API + - `test` — utilities used by tests. + - `util` — utilities used by both implementation and tests. +* `core` — VTS tests and the default implementation of the core API (not HIDL API, it's in `audio/N.M`). - - `7.0` -- code specific to version V7.0 of the core HIDL API - - `all-versions` -- the code is common between all versions, + - `7.0` — code specific to version V7.0 of the core HIDL API + - `all-versions` — the code is common between all versions, version-specific parts are enclosed into conditional directives of preprocessor or reside in dedicated files. - - `default` -- code that wraps the legacy API (from + - `default` — code that wraps the legacy API (from `hardware/libhardware`). + - `util` — utilities for the default implementation. - `vts` VTS tests for the core HIDL API. -* `effect` -- same for the effect HIDL API. +* `effect` — same for the effect HIDL API. - `2.0` - - `config` -- the XSD schema for the Audio Effects configuration - file. + - `config` — the XSD schema for the Audio Effects configuration file. - `4.0` - ... - `all-versions` - - `default` - - `vts` -* `policy` -- Configurable Audio Policy schemes. - - `1.0` -- note that versions of CAP are not linked to the versions + - `default` — code that wraps the legacy API (from + `hardware/libhardware`). + - `util` — utilities for the default implementation. + - `vts` VTS tests for the effect HIDL API. +* `policy` — Configurable Audio Policy schemes. + - `1.0` — note that versions of CAP are not linked to the versions of audio HAL. - - `vts` -- VTS tests for validating actual configuration files. - - `xml` -- XSD schemas for CAP configuration files. + - `vts` — VTS tests for validating actual configuration files. + - `xml` — XSD schemas for CAP configuration files. diff --git a/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h b/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h index c0042db0ba..b427f3a0d4 100644 --- a/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h +++ b/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h @@ -212,10 +212,16 @@ static inline bool isOutputDevice(const std::string& device) { return isOutputDevice(stringToAudioDevice(device)); } +static inline bool maybeVendorExtension(const std::string& s) { + // Only checks whether the string starts with the "vendor prefix". + static const std::string vendorPrefix = "VX_"; + return s.size() > vendorPrefix.size() && s.substr(0, vendorPrefix.size()) == vendorPrefix; +} + static inline bool isVendorExtension(const std::string& s) { // Must match the "vendorExtension" rule from the XSD file. static const std::string vendorPrefix = "VX_"; - return s.size() > vendorPrefix.size() && s.substr(0, vendorPrefix.size()) == vendorPrefix && + return maybeVendorExtension(s) && std::all_of(s.begin() + vendorPrefix.size(), s.end(), [](unsigned char c) { return c == '_' || std::isalnum(c); }); } diff --git a/audio/common/7.0/example/Effect.cpp b/audio/common/7.0/example/Effect.cpp index 27f28c6ea6..578881148a 100644 --- a/audio/common/7.0/example/Effect.cpp +++ b/audio/common/7.0/example/Effect.cpp @@ -107,14 +107,13 @@ Return<Result> Effect::setInputDevice(const DeviceAddress& device) { } Return<void> Effect::getConfig(getConfig_cb _hidl_cb) { - const EffectConfig config = { - {} /* inputCfg */, - // outputCfg - {{} /* buffer */, - {toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT), 48000 /* samplingRateHz */, - toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO)}, /* base */ - EffectBufferAccess::ACCESS_ACCUMULATE, - 0 /* mask */}}; + EffectConfig config; + // inputCfg left unspecified. + config.outputCfg.base.format.value(toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT)); + config.outputCfg.base.sampleRateHz.value(48000); + config.outputCfg.base.channelMask.value( + toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO)); + config.outputCfg.accessMode.value(EffectBufferAccess::ACCESS_ACCUMULATE); _hidl_cb(Result::OK, config); return Void(); } diff --git a/audio/common/7.0/types.hal b/audio/common/7.0/types.hal index ed6d94f988..99c2e5a0eb 100644 --- a/audio/common/7.0/types.hal +++ b/audio/common/7.0/types.hal @@ -118,9 +118,28 @@ typedef string AudioChannelMask; * Base configuration attributes applicable to any stream of audio. */ struct AudioConfigBase { - AudioFormat format; // empty means 'unspecified' - uint32_t sampleRateHz; // 0 means 'unspecified' - AudioChannelMask channelMask; // empty means 'unspecified' + AudioFormat format; + uint32_t sampleRateHz; + AudioChannelMask channelMask; +}; + +/** + * Base configuration attributes applicable to any stream of audio. + * Any attribute may be left unspecified. + */ +struct AudioConfigBaseOptional { + safe_union Format { + Monostate unspecified; + AudioFormat value; + } format; + safe_union SampleRate { + Monostate unspecified; + uint32_t value; + } sampleRateHz; + safe_union ChannelMask { + Monostate unspecified; + AudioChannelMask value; + } channelMask; }; /** @@ -290,15 +309,15 @@ typedef string AudioTag; struct PlaybackTrackMetadata { AudioUsage usage; AudioContentType contentType; - /** Tags from AudioTrack audio atttributes */ - vec<AudioTag> tags; - AudioChannelMask channelMask; /** * Positive linear gain applied to the track samples. 0 being muted and 1 is no attenuation, * 2 means double amplification... * Must not be negative. */ float gain; + AudioChannelMask channelMask; + /** Tags from AudioTrack audio atttributes */ + vec<AudioTag> tags; }; /** Metadatas of the source of a StreamOut. */ @@ -309,9 +328,6 @@ struct SourceMetadata { /** Metadata of a record track for a StreamIn. */ struct RecordTrackMetadata { AudioSource source; - /** Tags from AudioTrack audio atttributes */ - vec<AudioTag> tags; - AudioChannelMask channelMask; /** * Positive linear gain applied to the track samples. 0 being muted and 1 is no attenuation, * 2 means double amplification... @@ -325,6 +341,9 @@ struct RecordTrackMetadata { Monostate unspecified; DeviceAddress device; } destination; + AudioChannelMask channelMask; + /** Tags from AudioTrack audio atttributes */ + vec<AudioTag> tags; }; /** Metadatas of the sink of a StreamIn. */ @@ -439,11 +458,9 @@ struct AudioPortConfig { */ AudioPortHandle id; /** - * Basic parameters: sampling rate, format, channel mask. Only some of the - * parameters (or none) may be set. See the documentation of the - * AudioConfigBase struct. + * Basic parameters: sampling rate, format, channel mask. */ - AudioConfigBase base; + AudioConfigBaseOptional base; /** Associated gain control. */ safe_union OptionalGain { Monostate unspecified; diff --git a/audio/common/all-versions/default/7.0/HidlUtils.cpp b/audio/common/all-versions/default/7.0/HidlUtils.cpp index de19faf153..bb3a5968b5 100644 --- a/audio/common/all-versions/default/7.0/HidlUtils.cpp +++ b/audio/common/all-versions/default/7.0/HidlUtils.cpp @@ -16,6 +16,7 @@ #include <stdio.h> #include <string.h> +#include <algorithm> #define LOG_TAG "HidlUtils" #include <log/log.h> @@ -147,6 +148,59 @@ status_t HidlUtils::audioConfigBaseToHal(const AudioConfigBase& configBase, return result; } +status_t HidlUtils::audioConfigBaseOptionalFromHal(const audio_config_base_t& halConfigBase, + bool isInput, bool formatSpecified, + bool sampleRateSpecified, + bool channelMaskSpecified, + AudioConfigBaseOptional* configBase) { + status_t result = NO_ERROR; + if (formatSpecified) { + AudioFormat value; + CONVERT_CHECKED(audioFormatFromHal(halConfigBase.format, &value), result); + configBase->format.value(std::move(value)); + } else { + configBase->format.unspecified({}); + } + if (sampleRateSpecified) { + configBase->sampleRateHz.value(halConfigBase.sample_rate); + } else { + configBase->sampleRateHz.unspecified({}); + } + if (channelMaskSpecified) { + AudioChannelMask value; + CONVERT_CHECKED(audioChannelMaskFromHal(halConfigBase.channel_mask, isInput, &value), + result); + configBase->channelMask.value(std::move(value)); + } + return result; +} + +status_t HidlUtils::audioConfigBaseOptionalToHal(const AudioConfigBaseOptional& configBase, + audio_config_base_t* halConfigBase, + bool* formatSpecified, bool* sampleRateSpecified, + bool* channelMaskSpecified) { + status_t result = NO_ERROR; + *formatSpecified = configBase.format.getDiscriminator() == + AudioConfigBaseOptional::Format::hidl_discriminator::value; + if (*formatSpecified) { + CONVERT_CHECKED(audioFormatToHal(configBase.format.value(), &halConfigBase->format), + result); + } + *sampleRateSpecified = configBase.sampleRateHz.getDiscriminator() == + AudioConfigBaseOptional::SampleRate::hidl_discriminator::value; + if (*sampleRateSpecified) { + halConfigBase->sample_rate = configBase.sampleRateHz.value(); + } + *channelMaskSpecified = configBase.channelMask.getDiscriminator() == + AudioConfigBaseOptional::ChannelMask::hidl_discriminator::value; + if (*channelMaskSpecified) { + CONVERT_CHECKED( + audioChannelMaskToHal(configBase.channelMask.value(), &halConfigBase->channel_mask), + result); + } + return result; +} + status_t HidlUtils::audioContentTypeFromHal(const audio_content_type_t halContentType, AudioContentType* contentType) { *contentType = audio_content_type_to_string(halContentType); @@ -228,7 +282,7 @@ status_t HidlUtils::audioGainModeMaskFromHal(audio_gain_mode_t halGainModeMask, hidl_vec<AudioGainMode>* gainModeMask) { status_t status = NO_ERROR; std::vector<AudioGainMode> result; - for (uint32_t bit = 0; bit < sizeof(audio_gain_mode_t) * 8; ++bit) { + for (uint32_t bit = 0; halGainModeMask != 0 && bit < sizeof(audio_gain_mode_t) * 8; ++bit) { audio_gain_mode_t flag = static_cast<audio_gain_mode_t>(1u << bit); if ((flag & halGainModeMask) == flag) { AudioGainMode flagStr = audio_gain_mode_to_string(flag); @@ -238,6 +292,7 @@ status_t HidlUtils::audioGainModeMaskFromHal(audio_gain_mode_t halGainModeMask, ALOGE("Unknown audio gain mode value 0x%X", flag); status = BAD_VALUE; } + halGainModeMask = static_cast<audio_gain_mode_t>(halGainModeMask & ~flag); } } *gainModeMask = result; @@ -508,23 +563,14 @@ status_t HidlUtils::audioPortConfigFromHal(const struct audio_port_config& halCo audio_port_config_has_input_direction(&halConfig), isInput); result = BAD_VALUE; } - if (halConfig.config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) { - config->base.sampleRateHz = halConfig.sample_rate; - } else { - config->base.sampleRateHz = {}; - } - if (halConfig.config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) { - CONVERT_CHECKED( - audioChannelMaskFromHal(halConfig.channel_mask, isInput, &config->base.channelMask), - result); - } else { - config->base.channelMask = {}; - } - if (halConfig.config_mask & AUDIO_PORT_CONFIG_FORMAT) { - CONVERT_CHECKED(audioFormatFromHal(halConfig.format, &config->base.format), result); - } else { - config->base.format = {}; - } + audio_config_base_t halConfigBase = {halConfig.sample_rate, halConfig.channel_mask, + halConfig.format}; + CONVERT_CHECKED( + audioConfigBaseOptionalFromHal( + halConfigBase, isInput, halConfig.config_mask & AUDIO_PORT_CONFIG_FORMAT, + halConfig.config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE, + halConfig.config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK, &config->base), + result); if (halConfig.config_mask & AUDIO_PORT_CONFIG_GAIN) { config->gain.config({}); CONVERT_CHECKED(audioGainConfigFromHal(halConfig.gain, isInput, &config->gain.config()), @@ -540,19 +586,23 @@ status_t HidlUtils::audioPortConfigToHal(const AudioPortConfig& config, status_t result = NO_ERROR; memset(halConfig, 0, sizeof(audio_port_config)); halConfig->id = config.id; - halConfig->config_mask = {}; - if (config.base.sampleRateHz != 0) { + halConfig->config_mask = 0; + audio_config_base_t halConfigBase = AUDIO_CONFIG_BASE_INITIALIZER; + bool formatSpecified = false, sRateSpecified = false, channelMaskSpecified = false; + CONVERT_CHECKED(audioConfigBaseOptionalToHal(config.base, &halConfigBase, &formatSpecified, + &sRateSpecified, &channelMaskSpecified), + result); + if (sRateSpecified) { halConfig->config_mask |= AUDIO_PORT_CONFIG_SAMPLE_RATE; - halConfig->sample_rate = config.base.sampleRateHz; + halConfig->sample_rate = halConfigBase.sample_rate; } - if (!config.base.channelMask.empty()) { + if (channelMaskSpecified) { halConfig->config_mask |= AUDIO_PORT_CONFIG_CHANNEL_MASK; - CONVERT_CHECKED(audioChannelMaskToHal(config.base.channelMask, &halConfig->channel_mask), - result); + halConfig->channel_mask = halConfigBase.channel_mask; } - if (!config.base.format.empty()) { + if (formatSpecified) { halConfig->config_mask |= AUDIO_PORT_CONFIG_FORMAT; - CONVERT_CHECKED(audioFormatToHal(config.base.format, &halConfig->format), result); + halConfig->format = halConfigBase.format; } if (config.gain.getDiscriminator() == AudioPortConfig::OptionalGain::hidl_discriminator::config) { @@ -810,15 +860,17 @@ status_t HidlUtils::audioProfileToHal(const AudioProfile& profile, return result; } -status_t HidlUtils::audioTagsFromHal(const char* halTags, hidl_vec<AudioTag>* tags) { - std::vector<std::string> strTags = utils::splitString(halTags, sAudioTagSeparator); +status_t HidlUtils::audioTagsFromHal(const std::vector<std::string>& strTags, + hidl_vec<AudioTag>* tags) { status_t result = NO_ERROR; tags->resize(strTags.size()); size_t to = 0; for (size_t from = 0; from < strTags.size(); ++from) { - if (xsd::isVendorExtension(strTags[from])) { - (*tags)[to++] = strTags[from]; + const auto& tag = strTags[from]; + if (xsd::isVendorExtension(tag)) { + (*tags)[to++] = tag; } else { + ALOGE("Vendor extension tag is ill-formed: \"%s\"", tag.c_str()); result = BAD_VALUE; } } @@ -841,6 +893,7 @@ status_t HidlUtils::audioTagsToHal(const hidl_vec<AudioTag>& tags, char* halTags halTagsBuffer << tag; hasValue = true; } else { + ALOGE("Vendor extension tag is ill-formed: \"%s\"", tag.c_str()); result = BAD_VALUE; } } @@ -851,6 +904,31 @@ status_t HidlUtils::audioTagsToHal(const hidl_vec<AudioTag>& tags, char* halTags return result; } +hidl_vec<AudioTag> HidlUtils::filterOutNonVendorTags(const hidl_vec<AudioTag>& tags) { + hidl_vec<AudioTag> result; + result.resize(tags.size()); + size_t resultIdx = 0; + for (const auto& tag : tags) { + if (xsd::maybeVendorExtension(tag)) { + result[resultIdx++] = tag; + } + } + if (resultIdx != result.size()) { + result.resize(resultIdx); + } + return result; +} + +std::vector<std::string> HidlUtils::filterOutNonVendorTags(const std::vector<std::string>& tags) { + std::vector<std::string> result; + std::copy_if(tags.begin(), tags.end(), std::back_inserter(result), xsd::maybeVendorExtension); + return result; +} + +std::vector<std::string> HidlUtils::splitAudioTags(const char* halTags) { + return utils::splitString(halTags, sAudioTagSeparator); +} + status_t HidlUtils::deviceAddressFromHal(audio_devices_t halDeviceType, const char* halDeviceAddress, DeviceAddress* device) { status_t result = NO_ERROR; diff --git a/audio/common/all-versions/default/HidlUtils.h b/audio/common/all-versions/default/HidlUtils.h index 8e9275c441..22b7152f99 100644 --- a/audio/common/all-versions/default/HidlUtils.h +++ b/audio/common/all-versions/default/HidlUtils.h @@ -20,6 +20,8 @@ #include PATH(android/hardware/audio/common/FILE_VERSION/types.h) #include <memory> +#include <string> +#include <vector> #include <system/audio.h> @@ -89,6 +91,15 @@ struct HidlUtils { AudioConfigBase* configBase); static status_t audioConfigBaseToHal(const AudioConfigBase& configBase, audio_config_base_t* halConfigBase); + static status_t audioConfigBaseOptionalFromHal(const audio_config_base_t& halConfigBase, + bool isInput, bool formatSpecified, + bool sampleRateSpecified, + bool channelMaskSpecified, + AudioConfigBaseOptional* configBase); + static status_t audioConfigBaseOptionalToHal(const AudioConfigBaseOptional& configBase, + audio_config_base_t* halConfigBase, + bool* formatSpecified, bool* sampleRateSpecified, + bool* channelMaskSpecified); static status_t audioDeviceTypeFromHal(audio_devices_t halDevice, AudioDevice* device); static status_t audioDeviceTypeToHal(const AudioDevice& device, audio_devices_t* halDevice); static status_t audioFormatFromHal(audio_format_t halFormat, AudioFormat* format); @@ -109,8 +120,12 @@ struct HidlUtils { AudioStreamType* streamType); static status_t audioStreamTypeToHal(const AudioStreamType& streamType, audio_stream_type_t* halStreamType); - static status_t audioTagsFromHal(const char* halTags, hidl_vec<AudioTag>* tags); + static status_t audioTagsFromHal(const std::vector<std::string>& strTags, + hidl_vec<AudioTag>* tags); static status_t audioTagsToHal(const hidl_vec<AudioTag>& tags, char* halTags); + static hidl_vec<AudioTag> filterOutNonVendorTags(const hidl_vec<AudioTag>& tags); + static std::vector<std::string> filterOutNonVendorTags(const std::vector<std::string>& tags); + static std::vector<std::string> splitAudioTags(const char* halTags); private: static status_t audioIndexChannelMaskFromHal(audio_channel_mask_t halChannelMask, diff --git a/audio/common/all-versions/default/UuidUtils.cpp b/audio/common/all-versions/default/UuidUtils.cpp index 85edc7b2f4..6c4c94d415 100644 --- a/audio/common/all-versions/default/UuidUtils.cpp +++ b/audio/common/all-versions/default/UuidUtils.cpp @@ -42,6 +42,14 @@ void UuidUtils::uuidToHal(const Uuid& uuid, audio_uuid_t* halUuid) { memcpy(halUuid->node, uuid.node.data(), uuid.node.size()); } +std::string UuidUtils::uuidToString(const audio_uuid_t& halUuid) { + char str[64]; + snprintf(str, sizeof(str), "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x", halUuid.timeLow, + halUuid.timeMid, halUuid.timeHiAndVersion, halUuid.clockSeq, halUuid.node[0], + halUuid.node[1], halUuid.node[2], halUuid.node[3], halUuid.node[4], halUuid.node[5]); + return str; +} + } // namespace implementation } // namespace CPP_VERSION } // namespace common diff --git a/audio/common/all-versions/default/UuidUtils.h b/audio/common/all-versions/default/UuidUtils.h index 38db48a730..cd04fb039a 100644 --- a/audio/common/all-versions/default/UuidUtils.h +++ b/audio/common/all-versions/default/UuidUtils.h @@ -17,14 +17,14 @@ #ifndef android_hardware_audio_Uuid_Utils_H_ #define android_hardware_audio_Uuid_Utils_H_ +#include <string> + // clang-format off #include PATH(android/hardware/audio/common/FILE_VERSION/types.h) // clang-format on #include <system/audio.h> -using ::android::hardware::hidl_vec; - namespace android { namespace hardware { namespace audio { @@ -38,6 +38,7 @@ class UuidUtils { public: static void uuidFromHal(const audio_uuid_t& halUuid, Uuid* uuid); static void uuidToHal(const Uuid& uuid, audio_uuid_t* halUuid); + static std::string uuidToString(const audio_uuid_t& halUuid); }; } // namespace implementation diff --git a/audio/common/all-versions/default/service/service.cpp b/audio/common/all-versions/default/service/service.cpp index d3fc3b5187..459fb15cba 100644 --- a/audio/common/all-versions/default/service/service.cpp +++ b/audio/common/all-versions/default/service/service.cpp @@ -78,17 +78,17 @@ int main(int /* argc */, char* /* argv */ []) { const std::vector<InterfacesList> mandatoryInterfaces = { { "Audio Core API", + "android.hardware.audio@7.0::IDevicesFactory", "android.hardware.audio@6.0::IDevicesFactory", "android.hardware.audio@5.0::IDevicesFactory", "android.hardware.audio@4.0::IDevicesFactory", - "android.hardware.audio@2.0::IDevicesFactory" }, { "Audio Effect API", + "android.hardware.audio.effect@7.0::IEffectsFactory", "android.hardware.audio.effect@6.0::IEffectsFactory", "android.hardware.audio.effect@5.0::IEffectsFactory", "android.hardware.audio.effect@4.0::IEffectsFactory", - "android.hardware.audio.effect@2.0::IEffectsFactory", } }; diff --git a/audio/common/all-versions/default/tests/hidlutils_tests.cpp b/audio/common/all-versions/default/tests/hidlutils_tests.cpp index fef88b450b..40fc5c81c6 100644 --- a/audio/common/all-versions/default/tests/hidlutils_tests.cpp +++ b/audio/common/all-versions/default/tests/hidlutils_tests.cpp @@ -35,30 +35,27 @@ namespace xsd { using namespace ::android::audio::policy::configuration::V7_0; } -static constexpr audio_channel_mask_t kInvalidHalChannelMask = - static_cast<audio_channel_mask_t>(0xFFFFFFFFU); +static constexpr audio_channel_mask_t kInvalidHalChannelMask = AUDIO_CHANNEL_INVALID; static constexpr audio_content_type_t kInvalidHalContentType = static_cast<audio_content_type_t>(0xFFFFFFFFU); static constexpr audio_devices_t kInvalidHalDevice = static_cast<audio_devices_t>(0xFFFFFFFFU); -static constexpr audio_format_t kInvalidHalFormat = static_cast<audio_format_t>(0xFFFFFFFFU); +static constexpr audio_format_t kInvalidHalFormat = AUDIO_FORMAT_INVALID; static constexpr audio_gain_mode_t kInvalidHalGainMode = static_cast<audio_gain_mode_t>(0xFFFFFFFFU); -static constexpr audio_source_t kInvalidHalSource = static_cast<audio_source_t>(0xFFFFFFFFU); +// AUDIO_SOURCE_INVALID is framework-only. +static constexpr audio_source_t kInvalidHalSource = static_cast<audio_source_t>(-1); static constexpr audio_stream_type_t kInvalidHalStreamType = static_cast<audio_stream_type_t>(0xFFFFFFFFU); static constexpr audio_usage_t kInvalidHalUsage = static_cast<audio_usage_t>(0xFFFFFFFFU); TEST(HidlUtils, ConvertInvalidChannelMask) { AudioChannelMask invalid; - EXPECT_EQ(BAD_VALUE, HidlUtils::audioChannelMaskFromHal(AUDIO_CHANNEL_INVALID, - false /*isInput*/, &invalid)); - EXPECT_EQ(BAD_VALUE, HidlUtils::audioChannelMaskFromHal(AUDIO_CHANNEL_INVALID, true /*isInput*/, - &invalid)); EXPECT_EQ(BAD_VALUE, HidlUtils::audioChannelMaskFromHal(kInvalidHalChannelMask, false /*isInput*/, &invalid)); EXPECT_EQ(BAD_VALUE, HidlUtils::audioChannelMaskFromHal(kInvalidHalChannelMask, true /*isInput*/, &invalid)); audio_channel_mask_t halInvalid; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioChannelMaskToHal("", &halInvalid)); // INVALID channel mask is not in XSD thus it's not allowed for transfer over HIDL. EXPECT_EQ(BAD_VALUE, HidlUtils::audioChannelMaskToHal("AUDIO_CHANNEL_INVALID", &halInvalid)); EXPECT_EQ(BAD_VALUE, HidlUtils::audioChannelMaskToHal("random string", &halInvalid)); @@ -148,40 +145,241 @@ TEST(HidlUtils, ConvertChannelMasksFromHal) { } } +static AudioConfigBase generateValidConfigBase(bool isInput) { + AudioConfigBase configBase; + configBase.sampleRateHz = 44100; + configBase.format = toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT); + configBase.channelMask = isInput ? toString(xsd::AudioChannelMask::AUDIO_CHANNEL_IN_STEREO) + : toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO); + return configBase; +} + TEST(HidlUtils, ConvertInvalidConfigBase) { AudioConfigBase invalid; - EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigBaseFromHal({.sample_rate = 0, - .channel_mask = kInvalidHalChannelMask, - .format = kInvalidHalFormat}, - false /*isInput*/, &invalid)); - EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigBaseFromHal({.sample_rate = 0, - .channel_mask = kInvalidHalChannelMask, - .format = kInvalidHalFormat}, - true /*isInput*/, &invalid)); + audio_config_base_t halInvalidChannelMask = AUDIO_CONFIG_BASE_INITIALIZER; + halInvalidChannelMask.channel_mask = kInvalidHalChannelMask; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigBaseFromHal(halInvalidChannelMask, false /*isInput*/, + &invalid)); + EXPECT_EQ(BAD_VALUE, + HidlUtils::audioConfigBaseFromHal(halInvalidChannelMask, true /*isInput*/, &invalid)); + audio_config_base_t halInvalidFormat = AUDIO_CONFIG_BASE_INITIALIZER; + halInvalidFormat.format = kInvalidHalFormat; + EXPECT_EQ(BAD_VALUE, + HidlUtils::audioConfigBaseFromHal(halInvalidFormat, false /*isInput*/, &invalid)); + EXPECT_EQ(BAD_VALUE, + HidlUtils::audioConfigBaseFromHal(halInvalidFormat, true /*isInput*/, &invalid)); + audio_config_base_t halInvalid; - invalid.sampleRateHz = 0; - invalid.channelMask = "random string"; - invalid.format = "random string"; - EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigBaseToHal(invalid, &halInvalid)); + AudioConfigBase invalidChannelMask = generateValidConfigBase(false /*isInput*/); + invalidChannelMask.channelMask = "random string"; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigBaseToHal(invalidChannelMask, &halInvalid)); + AudioConfigBase invalidFormat = generateValidConfigBase(false /*isInput*/); + invalidFormat.format = "random string"; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigBaseToHal(invalidFormat, &halInvalid)); +} + +TEST(HidlUtils, ConvertConfigBaseDefault) { + audio_config_base_t halBaseDefault = AUDIO_CONFIG_BASE_INITIALIZER; + AudioConfigBase baseDefaultOut, baseDefaultIn; + EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseFromHal(halBaseDefault, false /*isInput*/, + &baseDefaultOut)); + EXPECT_EQ(NO_ERROR, + HidlUtils::audioConfigBaseFromHal(halBaseDefault, true /*isInput*/, &baseDefaultIn)); + EXPECT_EQ(baseDefaultOut, baseDefaultIn); + audio_config_base_t halBaseDefaultBack; + EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseToHal(baseDefaultOut, &halBaseDefaultBack)); + EXPECT_EQ(halBaseDefault.sample_rate, halBaseDefaultBack.sample_rate); + EXPECT_EQ(halBaseDefault.channel_mask, halBaseDefaultBack.channel_mask); + EXPECT_EQ(halBaseDefault.format, halBaseDefaultBack.format); } TEST(HidlUtils, ConvertConfigBase) { - AudioConfigBase configBase; - configBase.sampleRateHz = 44100; - configBase.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO); - configBase.format = toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT); - audio_config_base_t halConfigBase; - EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseToHal(configBase, &halConfigBase)); - AudioConfigBase configBaseBack; + AudioConfigBase configBaseOut = generateValidConfigBase(false /*isInput*/); + audio_config_base_t halConfigBaseOut; + EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseToHal(configBaseOut, &halConfigBaseOut)); + AudioConfigBase configBaseOutBack; + EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseFromHal(halConfigBaseOut, false /*isInput*/, + &configBaseOutBack)); + EXPECT_EQ(configBaseOut, configBaseOutBack); + + AudioConfigBase configBaseIn = generateValidConfigBase(true /*isInput*/); + audio_config_base_t halConfigBaseIn; + EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseToHal(configBaseIn, &halConfigBaseIn)); + AudioConfigBase configBaseInBack; + EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseFromHal(halConfigBaseIn, true /*isInput*/, + &configBaseInBack)); + EXPECT_EQ(configBaseIn, configBaseInBack); +} + +TEST(HidlUtils, ConvertInvalidConfigBaseOptional) { + AudioConfigBaseOptional invalid; + audio_config_base_t halInvalidChannelMask = AUDIO_CONFIG_BASE_INITIALIZER; + halInvalidChannelMask.channel_mask = kInvalidHalChannelMask; + EXPECT_EQ(BAD_VALUE, + HidlUtils::audioConfigBaseOptionalFromHal( + halInvalidChannelMask, false /*isInput*/, false /*formatSpecified*/, + false /*sampleRateSpecified*/, true /*channelMaskSpecified*/, &invalid)); + EXPECT_EQ(BAD_VALUE, + HidlUtils::audioConfigBaseOptionalFromHal( + halInvalidChannelMask, true /*isInput*/, false /*formatSpecified*/, + false /*sampleRateSpecified*/, true /*channelMaskSpecified*/, &invalid)); + // Unspecified invalid values are ignored + AudioConfigBaseOptional unspecified; + EXPECT_EQ(NO_ERROR, + HidlUtils::audioConfigBaseOptionalFromHal( + halInvalidChannelMask, false /*isInput*/, false /*formatSpecified*/, + false /*sampleRateSpecified*/, false /*channelMaskSpecified*/, &unspecified)); + EXPECT_EQ(NO_ERROR, + HidlUtils::audioConfigBaseOptionalFromHal( + halInvalidChannelMask, true /*isInput*/, false /*formatSpecified*/, + false /*sampleRateSpecified*/, false /*channelMaskSpecified*/, &unspecified)); + audio_config_base_t halInvalidFormat = AUDIO_CONFIG_BASE_INITIALIZER; + halInvalidFormat.format = kInvalidHalFormat; + EXPECT_EQ(BAD_VALUE, + HidlUtils::audioConfigBaseOptionalFromHal( + halInvalidFormat, false /*isInput*/, true /*formatSpecified*/, + false /*sampleRateSpecified*/, false /*channelMaskSpecified*/, &invalid)); + EXPECT_EQ(BAD_VALUE, + HidlUtils::audioConfigBaseOptionalFromHal( + halInvalidFormat, true /*isInput*/, true /*formatSpecified*/, + false /*sampleRateSpecified*/, false /*channelMaskSpecified*/, &invalid)); + EXPECT_EQ(NO_ERROR, + HidlUtils::audioConfigBaseOptionalFromHal( + halInvalidFormat, false /*isInput*/, false /*formatSpecified*/, + false /*sampleRateSpecified*/, false /*channelMaskSpecified*/, &unspecified)); + EXPECT_EQ(NO_ERROR, + HidlUtils::audioConfigBaseOptionalFromHal( + halInvalidFormat, true /*isInput*/, false /*formatSpecified*/, + false /*sampleRateSpecified*/, false /*channelMaskSpecified*/, &unspecified)); + + audio_config_base_t halInvalid; + AudioConfigBaseOptional invalidChannelMask; + bool formatSpecified, sampleRateSpecified, channelMaskSpecified; + invalidChannelMask.channelMask.value("random string"); + EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigBaseOptionalToHal( + invalidChannelMask, &halInvalid, &formatSpecified, + &sampleRateSpecified, &channelMaskSpecified)); + AudioConfigBaseOptional invalidFormat; + invalidFormat.format.value("random string"); + EXPECT_EQ(BAD_VALUE, + HidlUtils::audioConfigBaseOptionalToHal(invalidFormat, &halInvalid, &formatSpecified, + &sampleRateSpecified, &channelMaskSpecified)); +} + +TEST(HidlUtils, ConvertConfigBaseOptionalDefault) { + audio_config_base_t halBaseDefault = AUDIO_CONFIG_BASE_INITIALIZER; + AudioConfigBaseOptional baseDefaultUnspecOut, baseDefaultUnspecIn; + EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseOptionalFromHal( + halBaseDefault, false /*isInput*/, false /*formatSpecified*/, + false /*sampleRateSpecified*/, false /*channelMaskSpecified*/, + &baseDefaultUnspecOut)); + EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseOptionalFromHal( + halBaseDefault, true /*isInput*/, false /*formatSpecified*/, + false /*sampleRateSpecified*/, false /*channelMaskSpecified*/, + &baseDefaultUnspecIn)); + EXPECT_EQ(baseDefaultUnspecOut, baseDefaultUnspecIn); + audio_config_base_t halBaseDefaultUnspecBack = AUDIO_CONFIG_BASE_INITIALIZER; + bool formatSpecified, sampleRateSpecified, channelMaskSpecified; + EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseOptionalToHal( + baseDefaultUnspecOut, &halBaseDefaultUnspecBack, &formatSpecified, + &sampleRateSpecified, &channelMaskSpecified)); + EXPECT_FALSE(formatSpecified); + EXPECT_FALSE(sampleRateSpecified); + EXPECT_FALSE(channelMaskSpecified); + EXPECT_EQ(halBaseDefault.sample_rate, halBaseDefaultUnspecBack.sample_rate); + EXPECT_EQ(halBaseDefault.channel_mask, halBaseDefaultUnspecBack.channel_mask); + EXPECT_EQ(halBaseDefault.format, halBaseDefaultUnspecBack.format); + + AudioConfigBaseOptional baseDefaultSpecOut, baseDefaultSpecIn; + EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseOptionalFromHal( + halBaseDefault, false /*isInput*/, true /*formatSpecified*/, + true /*sampleRateSpecified*/, true /*channelMaskSpecified*/, + &baseDefaultSpecOut)); + EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseOptionalFromHal( + halBaseDefault, true /*isInput*/, true /*formatSpecified*/, + true /*sampleRateSpecified*/, true /*channelMaskSpecified*/, + &baseDefaultSpecIn)); + EXPECT_EQ(baseDefaultSpecOut, baseDefaultSpecIn); + audio_config_base_t halBaseDefaultSpecBack; + EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseOptionalToHal( + baseDefaultSpecOut, &halBaseDefaultSpecBack, &formatSpecified, + &sampleRateSpecified, &channelMaskSpecified)); + EXPECT_TRUE(formatSpecified); + EXPECT_TRUE(sampleRateSpecified); + EXPECT_TRUE(channelMaskSpecified); + EXPECT_EQ(halBaseDefault.sample_rate, halBaseDefaultSpecBack.sample_rate); + EXPECT_EQ(halBaseDefault.channel_mask, halBaseDefaultSpecBack.channel_mask); + EXPECT_EQ(halBaseDefault.format, halBaseDefaultSpecBack.format); +} + +TEST(HidlUtils, ConvertConfigBaseOptionalEmpty) { + AudioConfigBaseOptional empty; + bool formatSpecified, sampleRateSpecified, channelMaskSpecified; + audio_config_base_t halEmpty = AUDIO_CONFIG_BASE_INITIALIZER; EXPECT_EQ(NO_ERROR, - HidlUtils::audioConfigBaseFromHal(halConfigBase, false /*isInput*/, &configBaseBack)); - EXPECT_EQ(configBase, configBaseBack); + HidlUtils::audioConfigBaseOptionalToHal(empty, &halEmpty, &formatSpecified, + &sampleRateSpecified, &channelMaskSpecified)); + EXPECT_FALSE(formatSpecified); + EXPECT_FALSE(sampleRateSpecified); + EXPECT_FALSE(channelMaskSpecified); + AudioConfigBaseOptional emptyOutBack, emptyInBack; + EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseOptionalFromHal( + halEmpty, false /*isInput*/, formatSpecified, sampleRateSpecified, + channelMaskSpecified, &emptyOutBack)); + EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseOptionalFromHal( + halEmpty, true /*isInput*/, formatSpecified, sampleRateSpecified, + channelMaskSpecified, &emptyInBack)); + EXPECT_EQ(emptyOutBack, emptyInBack); + EXPECT_EQ(empty, emptyOutBack); +} + +TEST(HidlUtils, ConvertConfigBaseOptional) { + AudioConfigBase validBaseOut = generateValidConfigBase(false /*isInput*/); + AudioConfigBaseOptional configBaseOut; + configBaseOut.format.value(validBaseOut.format); + configBaseOut.sampleRateHz.value(validBaseOut.sampleRateHz); + configBaseOut.channelMask.value(validBaseOut.channelMask); + audio_config_base_t halConfigBaseOut; + bool formatSpecified, sampleRateSpecified, channelMaskSpecified; + EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseOptionalToHal( + configBaseOut, &halConfigBaseOut, &formatSpecified, + &sampleRateSpecified, &channelMaskSpecified)); + EXPECT_TRUE(formatSpecified); + EXPECT_TRUE(sampleRateSpecified); + EXPECT_TRUE(channelMaskSpecified); + AudioConfigBaseOptional configBaseOutBack; + EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseOptionalFromHal( + halConfigBaseOut, false /*isInput*/, formatSpecified, + sampleRateSpecified, channelMaskSpecified, &configBaseOutBack)); + EXPECT_EQ(configBaseOut, configBaseOutBack); + + AudioConfigBase validBaseIn = generateValidConfigBase(true /*isInput*/); + AudioConfigBaseOptional configBaseIn; + configBaseIn.format.value(validBaseIn.format); + configBaseIn.sampleRateHz.value(validBaseIn.sampleRateHz); + configBaseIn.channelMask.value(validBaseIn.channelMask); + audio_config_base_t halConfigBaseIn; + formatSpecified = false; + sampleRateSpecified = false; + channelMaskSpecified = false; + EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseOptionalToHal( + configBaseIn, &halConfigBaseIn, &formatSpecified, + &sampleRateSpecified, &channelMaskSpecified)); + EXPECT_TRUE(formatSpecified); + EXPECT_TRUE(sampleRateSpecified); + EXPECT_TRUE(channelMaskSpecified); + AudioConfigBaseOptional configBaseInBack; + EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseOptionalFromHal( + halConfigBaseIn, true /*isInput*/, formatSpecified, + sampleRateSpecified, channelMaskSpecified, &configBaseInBack)); + EXPECT_EQ(configBaseIn, configBaseInBack); } TEST(HidlUtils, ConvertInvalidContentType) { AudioContentType invalid; EXPECT_EQ(BAD_VALUE, HidlUtils::audioContentTypeFromHal(kInvalidHalContentType, &invalid)); audio_content_type_t halInvalid; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioContentTypeToHal("", &halInvalid)); EXPECT_EQ(BAD_VALUE, HidlUtils::audioContentTypeToHal("random string", &halInvalid)); } @@ -202,6 +400,7 @@ TEST(HidlUtils, ConvertInvalidDeviceType) { AudioDevice invalid; EXPECT_EQ(BAD_VALUE, HidlUtils::audioDeviceTypeFromHal(kInvalidHalDevice, &invalid)); audio_devices_t halInvalid; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioDeviceTypeToHal("", &halInvalid)); EXPECT_EQ(BAD_VALUE, HidlUtils::audioDeviceTypeToHal("random string", &halInvalid)); } @@ -233,6 +432,7 @@ TEST(HidlUtils, ConvertDeviceType) { // The enums module is too small to have unit tests on its own. TEST(HidlUtils, VendorExtension) { EXPECT_TRUE(xsd::isVendorExtension("VX_GOOGLE_VR_42")); + EXPECT_FALSE(xsd::isVendorExtension("")); EXPECT_FALSE(xsd::isVendorExtension("random string")); EXPECT_FALSE(xsd::isVendorExtension("VX_")); EXPECT_FALSE(xsd::isVendorExtension("VX_GOOGLE_$$")); @@ -347,6 +547,9 @@ TEST(HidlUtils, ConvertInvalidFormat) { AudioFormat invalid; EXPECT_EQ(BAD_VALUE, HidlUtils::audioFormatFromHal(kInvalidHalFormat, &invalid)); audio_format_t halInvalid; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioFormatToHal("", &halInvalid)); + // INVALID format is not in XSD thus it's not allowed for transfer over HIDL. + EXPECT_EQ(BAD_VALUE, HidlUtils::audioFormatToHal("AUDIO_FORMAT_INVALID", &halInvalid)); EXPECT_EQ(BAD_VALUE, HidlUtils::audioFormatToHal("random string", &halInvalid)); } @@ -357,8 +560,9 @@ TEST(HidlUtils, ConvertFormat) { AudioFormat formatBack; EXPECT_EQ(NO_ERROR, HidlUtils::audioFormatToHal(format, &halFormat)) << "Conversion of \"" << format << "\" failed"; - EXPECT_TRUE(audio_is_valid_format(halFormat)) - << "Converted format \"" << format << "\" is invalid"; + EXPECT_EQ(enumVal != xsd::AudioFormat::AUDIO_FORMAT_DEFAULT, + audio_is_valid_format(halFormat)) + << "Validity of \"" << format << "\" is not as expected"; EXPECT_EQ(NO_ERROR, HidlUtils::audioFormatFromHal(halFormat, &formatBack)) << "Conversion of format " << halFormat << " failed"; EXPECT_EQ(format, formatBack); @@ -430,6 +634,9 @@ TEST(HidlUtils, ConvertInvalidSource) { AudioSource invalid; EXPECT_EQ(BAD_VALUE, HidlUtils::audioSourceFromHal(kInvalidHalSource, &invalid)); audio_source_t halInvalid; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioSourceToHal("", &halInvalid)); + // INVALID source is not in XSD thus it's not allowed for transfer over HIDL. + EXPECT_EQ(BAD_VALUE, HidlUtils::audioSourceToHal("AUDIO_SOURCE_INVALID", &halInvalid)); EXPECT_EQ(BAD_VALUE, HidlUtils::audioSourceToHal("random string", &halInvalid)); } @@ -453,6 +660,7 @@ TEST(HidlUtils, ConvertInvalidStreamType) { AudioStreamType invalid; EXPECT_EQ(BAD_VALUE, HidlUtils::audioStreamTypeFromHal(kInvalidHalStreamType, &invalid)); audio_stream_type_t halInvalid; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioStreamTypeToHal("", &halInvalid)); EXPECT_EQ(BAD_VALUE, HidlUtils::audioStreamTypeToHal("random string", &halInvalid)); } @@ -524,6 +732,7 @@ TEST(HidlUtils, ConvertInvalidUsage) { AudioUsage invalid; EXPECT_EQ(BAD_VALUE, HidlUtils::audioUsageFromHal(kInvalidHalUsage, &invalid)); audio_usage_t halInvalid; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioUsageToHal("", &halInvalid)); EXPECT_EQ(BAD_VALUE, HidlUtils::audioUsageToHal("random string", &halInvalid)); } @@ -543,7 +752,7 @@ TEST(HidlUtils, ConvertUsage) { TEST(HidlUtils, ConvertInvalidOffloadInfo) { AudioOffloadInfo invalid; audio_offload_info_t halInvalid = AUDIO_INFO_INITIALIZER; - halInvalid.channel_mask = AUDIO_CHANNEL_INVALID; + halInvalid.channel_mask = kInvalidHalChannelMask; halInvalid.format = kInvalidHalFormat; EXPECT_EQ(BAD_VALUE, HidlUtils::audioOffloadInfoFromHal(halInvalid, &invalid)); invalid.base.channelMask = "random string"; @@ -553,9 +762,7 @@ TEST(HidlUtils, ConvertInvalidOffloadInfo) { TEST(HidlUtils, ConvertOffloadInfo) { AudioOffloadInfo offloadInfo = {}; - offloadInfo.base.sampleRateHz = 44100; - offloadInfo.base.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO); - offloadInfo.base.format = toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT); + offloadInfo.base = generateValidConfigBase(false /*isInput*/); offloadInfo.streamType = toString(xsd::AudioStreamType::AUDIO_STREAM_MUSIC); offloadInfo.bitRatePerSecond = 320; offloadInfo.durationMicroseconds = -1; @@ -574,33 +781,76 @@ TEST(HidlUtils, ConvertOffloadInfo) { TEST(HidlUtils, ConvertInvalidConfig) { AudioConfig invalid; - audio_config_t halInvalid = AUDIO_CONFIG_INITIALIZER; - halInvalid.channel_mask = AUDIO_CHANNEL_INVALID; - halInvalid.format = kInvalidHalFormat; - EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigFromHal(halInvalid, false /*isInput*/, &invalid)); - EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigFromHal(halInvalid, true /*isInput*/, &invalid)); - invalid.base.channelMask = "random string"; - invalid.base.format = "random string"; - EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigToHal(invalid, &halInvalid)); + audio_config_t halInvalidChannelMask = AUDIO_CONFIG_INITIALIZER; + halInvalidChannelMask.channel_mask = kInvalidHalChannelMask; + EXPECT_EQ(BAD_VALUE, + HidlUtils::audioConfigFromHal(halInvalidChannelMask, false /*isInput*/, &invalid)); + EXPECT_EQ(BAD_VALUE, + HidlUtils::audioConfigFromHal(halInvalidChannelMask, true /*isInput*/, &invalid)); + audio_config_t halInvalidFormat = AUDIO_CONFIG_INITIALIZER; + halInvalidFormat.format = kInvalidHalFormat; + EXPECT_EQ(BAD_VALUE, + HidlUtils::audioConfigFromHal(halInvalidFormat, false /*isInput*/, &invalid)); + EXPECT_EQ(BAD_VALUE, + HidlUtils::audioConfigFromHal(halInvalidFormat, true /*isInput*/, &invalid)); + + AudioConfig invalidChannelMask; + audio_config_t halInvalid; + invalidChannelMask.base.channelMask = "random string"; + invalidChannelMask.base.format = toString(xsd::AudioFormat::AUDIO_FORMAT_DEFAULT); + EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigToHal(invalidChannelMask, &halInvalid)); + AudioConfig invalidFormat; + invalidFormat.base.format = "random string"; + invalidFormat.base.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_NONE); + EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigToHal(invalidFormat, &halInvalid)); +} + +TEST(HidlUtils, ConvertConfigDefault) { + audio_config_t halDefault = AUDIO_CONFIG_INITIALIZER; + AudioConfig defaultOut, defaultIn; + EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigFromHal(halDefault, false /*isInput*/, &defaultOut)); + EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigFromHal(halDefault, true /*isInput*/, &defaultIn)); + EXPECT_EQ(defaultOut, defaultIn); + EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigToHal(defaultOut, &halDefault)); + + // Note: empty channel mask and config are not valid values. + AudioConfig defaultCfg{}; + defaultCfg.base.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_NONE); + defaultCfg.base.format = toString(xsd::AudioFormat::AUDIO_FORMAT_DEFAULT); + audio_config_t halDefaultCfg; + EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigToHal(defaultCfg, &halDefaultCfg)); + AudioConfig defaultCfgBackOut, defaultCfgBackIn; + EXPECT_EQ(NO_ERROR, + HidlUtils::audioConfigFromHal(halDefaultCfg, false /*isInput*/, &defaultCfgBackOut)); + EXPECT_EQ(NO_ERROR, + HidlUtils::audioConfigFromHal(halDefaultCfg, true /*isInput*/, &defaultCfgBackIn)); + EXPECT_EQ(defaultCfgBackOut, defaultCfgBackIn); + EXPECT_EQ(defaultCfg, defaultCfgBackOut); } TEST(HidlUtils, ConvertConfig) { - AudioConfig config = {}; - config.base.sampleRateHz = 44100; - config.base.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO); - config.base.format = toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT); - audio_config_t halConfig; - EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigToHal(config, &halConfig)); - AudioConfig configBack; - EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigFromHal(halConfig, false /*isInput*/, &configBack)); - EXPECT_EQ(config, configBack); + AudioConfig configOut{}; + configOut.base = generateValidConfigBase(false /*isInput*/); + audio_config_t halConfigOut; + EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigToHal(configOut, &halConfigOut)); + AudioConfig configOutBack; + EXPECT_EQ(NO_ERROR, + HidlUtils::audioConfigFromHal(halConfigOut, false /*isInput*/, &configOutBack)); + EXPECT_EQ(configOut, configOutBack); + + AudioConfig configIn{}; + configIn.base = generateValidConfigBase(true /*isInput*/); + audio_config_t halConfigIn; + EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigToHal(configIn, &halConfigIn)); + AudioConfig configInBack; + EXPECT_EQ(NO_ERROR, + HidlUtils::audioConfigFromHal(halConfigIn, true /*isInput*/, &configInBack)); + EXPECT_EQ(configIn, configInBack); } TEST(HidlUtils, ConvertConfigWithOffloadInfo) { AudioConfig config = {}; - config.base.sampleRateHz = 44100; - config.base.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO); - config.base.format = toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT); + config.base = generateValidConfigBase(false /*isInput*/); config.offloadInfo.info( AudioOffloadInfo{.base = config.base, .streamType = toString(xsd::AudioStreamType::AUDIO_STREAM_MUSIC), @@ -655,18 +905,18 @@ TEST(HidlUtils, ConvertInvalidAudioPortConfig) { halInvalid.type = AUDIO_PORT_TYPE_MIX; halInvalid.role = AUDIO_PORT_ROLE_NONE; // note: this is valid. halInvalid.config_mask = AUDIO_PORT_CONFIG_CHANNEL_MASK; - halInvalid.channel_mask = AUDIO_CHANNEL_INVALID; + halInvalid.channel_mask = kInvalidHalChannelMask; EXPECT_EQ(BAD_VALUE, HidlUtils::audioPortConfigFromHal(halInvalid, &invalid)); - invalid.base.channelMask = "random string"; + invalid.base.channelMask.value("random string"); EXPECT_EQ(BAD_VALUE, HidlUtils::audioPortConfigToHal(invalid, &halInvalid)); } TEST(HidlUtils, ConvertAudioPortConfig) { AudioPortConfig config = {}; config.id = 42; - config.base.sampleRateHz = 44100; - config.base.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO); - config.base.format = toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT); + config.base.sampleRateHz.value(44100); + config.base.channelMask.value(toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO)); + config.base.format.value(toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT)); config.gain.config({}); config.gain.config().channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO); config.ext.device({}); @@ -734,7 +984,7 @@ TEST(HidlUtils, ConvertInvalidAudioTags) { {std::string(AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1, HidlUtils::sAudioTagSeparator)}}; EXPECT_EQ(BAD_VALUE, HidlUtils::audioTagsToHal(tagSeparator, halTag)); - hidl_vec<AudioTag> notExtensions = {{"random string", "VX_", "VX_GOOGLE_$$"}}; + hidl_vec<AudioTag> notExtensions = {{"", "random string", "VX_", "VX_GOOGLE_$$"}}; EXPECT_EQ(BAD_VALUE, HidlUtils::audioTagsToHal(notExtensions, halTag)); } @@ -743,20 +993,51 @@ TEST(HidlUtils, ConvertAudioTags) { char halEmptyTags[AUDIO_ATTRIBUTES_TAGS_MAX_SIZE] = {}; EXPECT_EQ(NO_ERROR, HidlUtils::audioTagsToHal(emptyTags, halEmptyTags)); hidl_vec<AudioTag> emptyTagsBack; - EXPECT_EQ(NO_ERROR, HidlUtils::audioTagsFromHal(halEmptyTags, &emptyTagsBack)); + EXPECT_EQ(NO_ERROR, + HidlUtils::audioTagsFromHal(HidlUtils::splitAudioTags(halEmptyTags), &emptyTagsBack)); EXPECT_EQ(emptyTags, emptyTagsBack); hidl_vec<AudioTag> oneTag = {{"VX_GOOGLE_VR"}}; char halOneTag[AUDIO_ATTRIBUTES_TAGS_MAX_SIZE] = {}; EXPECT_EQ(NO_ERROR, HidlUtils::audioTagsToHal(oneTag, halOneTag)); hidl_vec<AudioTag> oneTagBack; - EXPECT_EQ(NO_ERROR, HidlUtils::audioTagsFromHal(halOneTag, &oneTagBack)); + EXPECT_EQ(NO_ERROR, + HidlUtils::audioTagsFromHal(HidlUtils::splitAudioTags(halOneTag), &oneTagBack)); EXPECT_EQ(oneTag, oneTagBack); hidl_vec<AudioTag> twoTags = {{"VX_GOOGLE_VR_42", "VX_GOOGLE_1E100"}}; char halTwoTags[AUDIO_ATTRIBUTES_TAGS_MAX_SIZE] = {}; EXPECT_EQ(NO_ERROR, HidlUtils::audioTagsToHal(twoTags, halTwoTags)); hidl_vec<AudioTag> twoTagsBack; - EXPECT_EQ(NO_ERROR, HidlUtils::audioTagsFromHal(halTwoTags, &twoTagsBack)); + EXPECT_EQ(NO_ERROR, + HidlUtils::audioTagsFromHal(HidlUtils::splitAudioTags(halTwoTags), &twoTagsBack)); EXPECT_EQ(twoTags, twoTagsBack); } + +template <typename T> +class FilterTest : public ::testing::Test {}; +using FilterTestTypeParams = ::testing::Types<hidl_vec<AudioTag>, std::vector<std::string>>; +TYPED_TEST_SUITE(FilterTest, FilterTestTypeParams); + +TYPED_TEST(FilterTest, FilterOutNonVendorTags) { + TypeParam emptyTags; + EXPECT_EQ(emptyTags, HidlUtils::filterOutNonVendorTags(emptyTags)); + + TypeParam allVendorTags = {{"VX_GOOGLE_VR_42", "VX_GOOGLE_1E100"}}; + EXPECT_EQ(allVendorTags, HidlUtils::filterOutNonVendorTags(allVendorTags)); + + TypeParam oneVendorTag = {{"", "VX_GOOGLE_VR", "random_string"}}; + TypeParam oneVendorTagOnly = HidlUtils::filterOutNonVendorTags(oneVendorTag); + EXPECT_EQ(1, oneVendorTagOnly.size()); + EXPECT_EQ(oneVendorTag[1], oneVendorTagOnly[0]); + + // The vendor extension isn't valid, however it must not be filtered out + // so the converter can detect the issue. + TypeParam oneMaybeVendorTag = {{"", "random string", "VX_GOOGLE_$$"}}; + TypeParam oneMaybeVendorTagOnly = HidlUtils::filterOutNonVendorTags(oneMaybeVendorTag); + EXPECT_EQ(1, oneMaybeVendorTagOnly.size()); + EXPECT_EQ(oneMaybeVendorTag[2], oneMaybeVendorTagOnly[0]); + + TypeParam noVendorTags = {{"", "random string", "V_"}}; + EXPECT_EQ(emptyTags, HidlUtils::filterOutNonVendorTags(noVendorTags)); +} diff --git a/audio/core/all-versions/default/Android.bp b/audio/core/all-versions/default/Android.bp index c75c779a91..e0f089425f 100644 --- a/audio/core/all-versions/default/Android.bp +++ b/audio/core/all-versions/default/Android.bp @@ -1,7 +1,6 @@ filegroup { name: "android.hardware.audio-impl_srcs", srcs: [ - "Conversions.cpp", "Device.cpp", "DevicesFactory.cpp", "ParametersUtil.cpp", @@ -64,6 +63,7 @@ cc_library_shared { defaults: ["android.hardware.audio-impl_default"], shared_libs: [ "android.hardware.audio@2.0", + "android.hardware.audio@2.0-util", "android.hardware.audio.common@2.0", "android.hardware.audio.common@2.0-util", ], @@ -80,6 +80,7 @@ cc_library_shared { shared_libs: [ "android.hardware.audio@4.0", + "android.hardware.audio@4.0-util", "android.hardware.audio.common@4.0", "android.hardware.audio.common@4.0-util", ], @@ -95,6 +96,7 @@ cc_library_shared { defaults: ["android.hardware.audio-impl_default"], shared_libs: [ "android.hardware.audio@5.0", + "android.hardware.audio@5.0-util", "android.hardware.audio.common@5.0", "android.hardware.audio.common@5.0-util", ], @@ -110,6 +112,7 @@ cc_defaults { defaults: ["android.hardware.audio-impl_default"], shared_libs: [ "android.hardware.audio@6.0", + "android.hardware.audio@6.0-util", "android.hardware.audio.common@6.0", "android.hardware.audio.common@6.0-util", ], @@ -130,6 +133,7 @@ cc_library_shared { defaults: ["android.hardware.audio-impl_default"], shared_libs: [ "android.hardware.audio@7.0", + "android.hardware.audio@7.0-util", "android.hardware.audio.common@7.0", "android.hardware.audio.common@7.0-enums", "android.hardware.audio.common@7.0-util", diff --git a/audio/core/all-versions/default/Conversions.cpp b/audio/core/all-versions/default/Conversions.cpp deleted file mode 100644 index f1752ccba3..0000000000 --- a/audio/core/all-versions/default/Conversions.cpp +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "core/default/Conversions.h" - -#include <stdio.h> - -#if MAJOR_VERSION >= 7 -#include <android_audio_policy_configuration_V7_0-enums.h> -#endif -#include <HidlUtils.h> -#include <log/log.h> - -namespace android { -namespace hardware { -namespace audio { -namespace CPP_VERSION { -namespace implementation { - -using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils; - -#define CONVERT_CHECKED(expr, result) \ - if (status_t status = (expr); status != NO_ERROR) { \ - result = status; \ - } - -status_t deviceAddressToHal(const DeviceAddress& device, audio_devices_t* halDeviceType, - char* halDeviceAddress) { -#if MAJOR_VERSION >= 5 - return HidlUtils::deviceAddressToHal(device, halDeviceType, halDeviceAddress); -#else - return HidlUtils::deviceAddressToHalImpl(device, halDeviceType, halDeviceAddress); -#endif -} - -status_t deviceAddressFromHal(audio_devices_t halDeviceType, const char* halDeviceAddress, - DeviceAddress* device) { -#if MAJOR_VERSION >= 5 - return HidlUtils::deviceAddressFromHal(halDeviceType, halDeviceAddress, device); -#else - return HidlUtils::deviceAddressFromHalImpl(halDeviceType, halDeviceAddress, device); -#endif -} - -#if MAJOR_VERSION >= 4 -bool halToMicrophoneCharacteristics(MicrophoneInfo* pDst, - const struct audio_microphone_characteristic_t& src) { - bool status = false; - if (pDst != NULL) { - pDst->deviceId = src.device_id; - - if (deviceAddressFromHal(src.device, src.address, &pDst->deviceAddress) != OK) { - return false; - } - pDst->channelMapping.resize(AUDIO_CHANNEL_COUNT_MAX); - for (size_t ch = 0; ch < pDst->channelMapping.size(); ch++) { - pDst->channelMapping[ch] = AudioMicrophoneChannelMapping(src.channel_mapping[ch]); - } - pDst->location = AudioMicrophoneLocation(src.location); - pDst->group = (AudioMicrophoneGroup)src.group; - pDst->indexInTheGroup = (uint32_t)src.index_in_the_group; - pDst->sensitivity = src.sensitivity; - pDst->maxSpl = src.max_spl; - pDst->minSpl = src.min_spl; - pDst->directionality = AudioMicrophoneDirectionality(src.directionality); - pDst->frequencyResponse.resize(src.num_frequency_responses); - for (size_t k = 0; k < src.num_frequency_responses; k++) { - pDst->frequencyResponse[k].frequency = src.frequency_responses[0][k]; - pDst->frequencyResponse[k].level = src.frequency_responses[1][k]; - } - pDst->position.x = src.geometric_location.x; - pDst->position.y = src.geometric_location.y; - pDst->position.z = src.geometric_location.z; - - pDst->orientation.x = src.orientation.x; - pDst->orientation.y = src.orientation.y; - pDst->orientation.z = src.orientation.z; - - status = true; - } - return status; -} - -status_t sinkMetadataToHal(const SinkMetadata& sinkMetadata, - std::vector<record_track_metadata>* halTracks) { - status_t result = NO_ERROR; - if (halTracks != nullptr) { - halTracks->reserve(sinkMetadata.tracks.size()); - } - for (auto& metadata : sinkMetadata.tracks) { - record_track_metadata halTrackMetadata{.gain = metadata.gain}; - CONVERT_CHECKED(HidlUtils::audioSourceToHal(metadata.source, &halTrackMetadata.source), - result); -#if MAJOR_VERSION >= 5 - if (metadata.destination.getDiscriminator() == - RecordTrackMetadata::Destination::hidl_discriminator::device) { - CONVERT_CHECKED( - deviceAddressToHal(metadata.destination.device(), &halTrackMetadata.dest_device, - halTrackMetadata.dest_device_address), - result); - } -#endif - if (halTracks != nullptr) { - halTracks->push_back(std::move(halTrackMetadata)); - } - } - return result; -} - -status_t sourceMetadataToHal(const SourceMetadata& sourceMetadata, - std::vector<playback_track_metadata_t>* halTracks) { - status_t result = NO_ERROR; - if (halTracks != nullptr) { - halTracks->reserve(sourceMetadata.tracks.size()); - } - for (auto& metadata : sourceMetadata.tracks) { - playback_track_metadata_t halTrackMetadata{.gain = metadata.gain}; - CONVERT_CHECKED(HidlUtils::audioUsageToHal(metadata.usage, &halTrackMetadata.usage), - result); - CONVERT_CHECKED(HidlUtils::audioContentTypeToHal(metadata.contentType, - &halTrackMetadata.content_type), - result); - if (halTracks != nullptr) { - halTracks->push_back(std::move(halTrackMetadata)); - } - } - return result; -} -#endif // MAJOR_VERSION >= 4 - -#if MAJOR_VERSION >= 7 -namespace xsd { -using namespace ::android::audio::policy::configuration::V7_0; -} - -bool audioInputFlagsToHal(const hidl_vec<AudioInOutFlag>& flags, audio_input_flags_t* halFlags) { - bool success = true; - *halFlags = {}; - for (const auto& flag : flags) { - audio_input_flags_t halFlag; - if (!xsd::isUnknownAudioInOutFlag(flag) && - audio_input_flag_from_string(flag.c_str(), &halFlag)) { - *halFlags = static_cast<audio_input_flags_t>(*halFlags | halFlag); - } else { - ALOGE("Unknown audio input flag \"%s\"", flag.c_str()); - success = false; - } - } - return success; -} - -bool audioOutputFlagsToHal(const hidl_vec<AudioInOutFlag>& flags, audio_output_flags_t* halFlags) { - bool success = true; - *halFlags = {}; - for (const auto& flag : flags) { - audio_output_flags_t halFlag; - if (!xsd::isUnknownAudioInOutFlag(flag) && - audio_output_flag_from_string(flag.c_str(), &halFlag)) { - *halFlags = static_cast<audio_output_flags_t>(*halFlags | halFlag); - } else { - ALOGE("Unknown audio output flag \"%s\"", flag.c_str()); - success = false; - } - } - return success; -} - -status_t sinkMetadataToHalV7(const SinkMetadata& sinkMetadata, - std::vector<record_track_metadata_v7_t>* halTracks) { - std::vector<record_track_metadata> bases; - status_t result = sinkMetadataToHal(sinkMetadata, halTracks != nullptr ? &bases : nullptr); - if (halTracks != nullptr) { - halTracks->reserve(bases.size()); - } - auto baseIter = std::make_move_iterator(bases.begin()); - for (auto& metadata : sinkMetadata.tracks) { - record_track_metadata_v7_t halTrackMetadata; - CONVERT_CHECKED(HidlUtils::audioChannelMaskToHal(metadata.channelMask, - &halTrackMetadata.channel_mask), - result); - CONVERT_CHECKED(HidlUtils::audioTagsToHal(metadata.tags, halTrackMetadata.tags), result); - if (halTracks != nullptr) { - halTrackMetadata.base = std::move(*baseIter++); - halTracks->push_back(std::move(halTrackMetadata)); - } - } - return result; -} - -status_t sourceMetadataToHalV7(const SourceMetadata& sourceMetadata, - std::vector<playback_track_metadata_v7_t>* halTracks) { - std::vector<playback_track_metadata_t> bases; - status_t result = sourceMetadataToHal(sourceMetadata, halTracks != nullptr ? &bases : nullptr); - if (halTracks != nullptr) { - halTracks->reserve(bases.size()); - } - auto baseIter = std::make_move_iterator(bases.begin()); - for (auto& metadata : sourceMetadata.tracks) { - playback_track_metadata_v7_t halTrackMetadata; - CONVERT_CHECKED(HidlUtils::audioChannelMaskToHal(metadata.channelMask, - &halTrackMetadata.channel_mask), - result); - CONVERT_CHECKED(HidlUtils::audioTagsToHal(metadata.tags, halTrackMetadata.tags), result); - if (halTracks != nullptr) { - halTrackMetadata.base = std::move(*baseIter++); - halTracks->push_back(std::move(halTrackMetadata)); - } - } - return result; -} -#endif - -} // namespace implementation -} // namespace CPP_VERSION -} // namespace audio -} // namespace hardware -} // namespace android diff --git a/audio/core/all-versions/default/Device.cpp b/audio/core/all-versions/default/Device.cpp index 7caed44bc9..70a1a4d1c1 100644 --- a/audio/core/all-versions/default/Device.cpp +++ b/audio/core/all-versions/default/Device.cpp @@ -17,9 +17,7 @@ #define LOG_TAG "DeviceHAL" #include "core/default/Device.h" -#include <HidlUtils.h> #include "common/all-versions/default/EffectMap.h" -#include "core/default/Conversions.h" #include "core/default/StreamIn.h" #include "core/default/StreamOut.h" #include "core/default/Util.h" @@ -33,6 +31,8 @@ #include <android/log.h> +#include <HidlUtils.h> + namespace android { namespace hardware { namespace audio { @@ -160,11 +160,11 @@ std::tuple<Result, sp<IStreamOut>> Device::openOutputStreamImpl(int32_t ioHandle audio_stream_out_t* halStream; audio_devices_t halDevice; char halDeviceAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN]; - if (deviceAddressToHal(device, &halDevice, halDeviceAddress) != NO_ERROR) { + if (CoreUtils::deviceAddressToHal(device, &halDevice, halDeviceAddress) != NO_ERROR) { return {Result::INVALID_ARGUMENTS, nullptr}; } audio_output_flags_t halFlags; - if (!audioOutputFlagsToHal(flags, &halFlags)) { + if (CoreUtils::audioOutputFlagsToHal(flags, &halFlags) != NO_ERROR) { return {Result::INVALID_ARGUMENTS, nullptr}; } ALOGV("open_output_stream handle: %d devices: %x flags: %#x " @@ -195,12 +195,12 @@ std::tuple<Result, sp<IStreamIn>> Device::openInputStreamImpl( audio_stream_in_t* halStream; audio_devices_t halDevice; char halDeviceAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN]; - if (deviceAddressToHal(device, &halDevice, halDeviceAddress) != NO_ERROR) { + if (CoreUtils::deviceAddressToHal(device, &halDevice, halDeviceAddress) != NO_ERROR) { return {Result::INVALID_ARGUMENTS, nullptr}; } audio_input_flags_t halFlags; audio_source_t halSource; - if (!audioInputFlagsToHal(flags, &halFlags) || + if (CoreUtils::audioInputFlagsToHal(flags, &halFlags) != NO_ERROR || HidlUtils::audioSourceToHal(source, &halSource) != NO_ERROR) { return {Result::INVALID_ARGUMENTS, nullptr}; } @@ -254,9 +254,12 @@ Return<void> Device::openOutputStream(int32_t ioHandle, const DeviceAddress& dev const SourceMetadata& sourceMetadata, openOutputStream_cb _hidl_cb) { #if MAJOR_VERSION <= 6 - if (status_t status = sourceMetadataToHal(sourceMetadata, nullptr); status != NO_ERROR) { + if (status_t status = CoreUtils::sourceMetadataToHal(sourceMetadata, nullptr); + status != NO_ERROR) { #else - if (status_t status = sourceMetadataToHalV7(sourceMetadata, nullptr); status != NO_ERROR) { + if (status_t status = CoreUtils::sourceMetadataToHalV7(sourceMetadata, + false /*ignoreNonVendorTags*/, nullptr); + status != NO_ERROR) { #endif _hidl_cb(analyzeStatus("sourceMetadataToHal", status), nullptr, AudioConfig{}); return Void(); @@ -288,9 +291,11 @@ Return<void> Device::openInputStream(int32_t ioHandle, const DeviceAddress& devi return Void(); } #if MAJOR_VERSION <= 6 - if (status_t status = sinkMetadataToHal(sinkMetadata, nullptr); status != NO_ERROR) { + if (status_t status = CoreUtils::sinkMetadataToHal(sinkMetadata, nullptr); status != NO_ERROR) { #else - if (status_t status = sinkMetadataToHalV7(sinkMetadata, nullptr); status != NO_ERROR) { + if (status_t status = CoreUtils::sinkMetadataToHalV7(sinkMetadata, + false /*ignoreNonVendorTags*/, nullptr); + status != NO_ERROR) { #endif _hidl_cb(analyzeStatus("sinkMetadataToHal", status), nullptr, AudioConfig{}); return Void(); @@ -444,7 +449,7 @@ Return<void> Device::getMicrophones(getMicrophones_cb _hidl_cb) { mDevice->get_microphones(mDevice, &mic_array[0], &actual_mics) == 0) { microphones.resize(actual_mics); for (size_t i = 0; i < actual_mics; ++i) { - halToMicrophoneCharacteristics(µphones[i], mic_array[i]); + (void)CoreUtils::microphoneInfoFromHal(mic_array[i], µphones[i]); } retval = Result::OK; } diff --git a/audio/core/all-versions/default/ParametersUtil.cpp b/audio/core/all-versions/default/ParametersUtil.cpp index 694eb73aee..4d536455d4 100644 --- a/audio/core/all-versions/default/ParametersUtil.cpp +++ b/audio/core/all-versions/default/ParametersUtil.cpp @@ -15,11 +15,12 @@ */ #include "core/default/ParametersUtil.h" -#include "core/default/Conversions.h" #include "core/default/Util.h" #include <system/audio.h> +#include <util/CoreUtils.h> + namespace android { namespace hardware { namespace audio { @@ -153,7 +154,7 @@ Result ParametersUtil::setParametersImpl(const hidl_vec<ParameterValue>& context Result ParametersUtil::setParam(const char* name, const DeviceAddress& address) { audio_devices_t halDeviceType; char halDeviceAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN]; - if (deviceAddressToHal(address, &halDeviceType, halDeviceAddress) != NO_ERROR) { + if (CoreUtils::deviceAddressToHal(address, &halDeviceType, halDeviceAddress) != NO_ERROR) { return Result::INVALID_ARGUMENTS; } AudioParameter params{String8(halDeviceAddress)}; diff --git a/audio/core/all-versions/default/Stream.cpp b/audio/core/all-versions/default/Stream.cpp index f964cbb804..7e3257399c 100644 --- a/audio/core/all-versions/default/Stream.cpp +++ b/audio/core/all-versions/default/Stream.cpp @@ -19,7 +19,6 @@ #include "core/default/Stream.h" #include "common/all-versions/HidlSupport.h" #include "common/all-versions/default/EffectMap.h" -#include "core/default/Conversions.h" #include "core/default/Util.h" #include <inttypes.h> @@ -30,6 +29,7 @@ #include <hardware/audio_effect.h> #include <media/AudioContainers.h> #include <media/TypeConverter.h> +#include <util/CoreUtils.h> namespace android { namespace hardware { @@ -278,23 +278,36 @@ Return<void> Stream::getAudioProperties(getAudioProperties_cb _hidl_cb) { return Void(); } -Return<Result> Stream::setAudioProperties(const AudioConfigBase& config) { - audio_config_base_t halConfigBase = {}; - status_t status = HidlUtils::audioConfigBaseToHal(config, &halConfigBase); +Return<Result> Stream::setAudioProperties(const AudioConfigBaseOptional& config) { + audio_config_base_t halConfigBase = AUDIO_CONFIG_BASE_INITIALIZER; + bool formatSpecified, sRateSpecified, channelMaskSpecified; + status_t status = HidlUtils::audioConfigBaseOptionalToHal( + config, &halConfigBase, &formatSpecified, &sRateSpecified, &channelMaskSpecified); if (status != NO_ERROR) { return Stream::analyzeStatus("set_audio_properties", status); } - if (Result result = setParam(AudioParameter::keySamplingRate, - static_cast<int>(halConfigBase.sample_rate)); - result != Result::OK) { - return result; + if (sRateSpecified) { + if (Result result = setParam(AudioParameter::keySamplingRate, + static_cast<int>(halConfigBase.sample_rate)); + result != Result::OK) { + return result; + } + } + if (channelMaskSpecified) { + if (Result result = setParam(AudioParameter::keyChannels, + static_cast<int>(halConfigBase.channel_mask)); + result != Result::OK) { + return result; + } } - if (Result result = - setParam(AudioParameter::keyChannels, static_cast<int>(halConfigBase.channel_mask)); - result != Result::OK) { - return result; + if (formatSpecified) { + if (Result result = + setParam(AudioParameter::keyFormat, static_cast<int>(halConfigBase.format)); + result != Result::OK) { + return result; + } } - return setParam(AudioParameter::keyFormat, static_cast<int>(halConfigBase.format)); + return Result::OK; } #endif // MAJOR_VERSION <= 6 @@ -360,9 +373,10 @@ Return<void> Stream::getDevices(getDevices_cb _hidl_cb) { hidl_vec<DeviceAddress> devices; if (retval == Result::OK) { devices.resize(1); - retval = Stream::analyzeStatus("get_devices", - deviceAddressFromHal(static_cast<audio_devices_t>(halDevice), - nullptr, &devices[0])); + retval = Stream::analyzeStatus( + "get_devices", + CoreUtils::deviceAddressFromHal(static_cast<audio_devices_t>(halDevice), nullptr, + &devices[0])); } _hidl_cb(retval, devices); return Void(); diff --git a/audio/core/all-versions/default/StreamIn.cpp b/audio/core/all-versions/default/StreamIn.cpp index 2c5e9f1521..599f3c396e 100644 --- a/audio/core/all-versions/default/StreamIn.cpp +++ b/audio/core/all-versions/default/StreamIn.cpp @@ -17,7 +17,6 @@ #define LOG_TAG "StreamInHAL" #include "core/default/StreamIn.h" -#include "core/default/Conversions.h" #include "core/default/Util.h" #include "common/all-versions/HidlSupport.h" @@ -27,6 +26,7 @@ #include <HidlUtils.h> #include <android/log.h> #include <hardware/audio.h> +#include <util/CoreUtils.h> #include <utils/Trace.h> #include <cmath> #include <memory> @@ -233,7 +233,7 @@ Return<void> StreamIn::getSupportedProfiles(getSupportedProfiles_cb _hidl_cb) { return mStreamCommon->getSupportedProfiles(_hidl_cb); } -Return<Result> StreamIn::setAudioProperties(const AudioConfigBase& config) { +Return<Result> StreamIn::setAudioProperties(const AudioConfigBaseOptional& config) { return mStreamCommon->setAudioProperties(config); } @@ -481,13 +481,15 @@ Return<void> StreamIn::debug(const hidl_handle& fd, const hidl_vec<hidl_string>& Result StreamIn::doUpdateSinkMetadata(const SinkMetadata& sinkMetadata) { std::vector<record_track_metadata> halTracks; #if MAJOR_VERSION <= 6 - (void)sinkMetadataToHal(sinkMetadata, &halTracks); + (void)CoreUtils::sinkMetadataToHal(sinkMetadata, &halTracks); #else // Validate whether a conversion to V7 is possible. This is needed // to have a consistent behavior of the HAL regardless of the API // version of the legacy HAL (and also to be consistent with openInputStream). std::vector<record_track_metadata_v7> halTracksV7; - if (status_t status = sinkMetadataToHalV7(sinkMetadata, &halTracksV7); status == NO_ERROR) { + if (status_t status = CoreUtils::sinkMetadataToHalV7( + sinkMetadata, false /*ignoreNonVendorTags*/, &halTracksV7); + status == NO_ERROR) { halTracks.reserve(halTracksV7.size()); for (auto metadata_v7 : halTracksV7) { halTracks.push_back(std::move(metadata_v7.base)); @@ -507,7 +509,9 @@ Result StreamIn::doUpdateSinkMetadata(const SinkMetadata& sinkMetadata) { #if MAJOR_VERSION >= 7 Result StreamIn::doUpdateSinkMetadataV7(const SinkMetadata& sinkMetadata) { std::vector<record_track_metadata_v7> halTracks; - if (status_t status = sinkMetadataToHalV7(sinkMetadata, &halTracks); status != NO_ERROR) { + if (status_t status = CoreUtils::sinkMetadataToHalV7(sinkMetadata, + false /*ignoreNonVendorTags*/, &halTracks); + status != NO_ERROR) { return Stream::analyzeStatus("sinkMetadataToHal", status); } const sink_metadata_v7_t halMetadata = { @@ -553,7 +557,7 @@ Return<void> StreamIn::getActiveMicrophones(getActiveMicrophones_cb _hidl_cb) { mStream->get_active_microphones(mStream, &mic_array[0], &actual_mics) == 0) { microphones.resize(actual_mics); for (size_t i = 0; i < actual_mics; ++i) { - halToMicrophoneCharacteristics(µphones[i], mic_array[i]); + (void)CoreUtils::microphoneInfoFromHal(mic_array[i], µphones[i]); } retval = Result::OK; } diff --git a/audio/core/all-versions/default/StreamOut.cpp b/audio/core/all-versions/default/StreamOut.cpp index 357fd941bd..5e4dd2ad40 100644 --- a/audio/core/all-versions/default/StreamOut.cpp +++ b/audio/core/all-versions/default/StreamOut.cpp @@ -17,7 +17,6 @@ #define LOG_TAG "StreamOutHAL" #include "core/default/StreamOut.h" -#include "core/default/Conversions.h" #include "core/default/Util.h" //#define LOG_NDEBUG 0 @@ -30,6 +29,7 @@ #include <HidlUtils.h> #include <android/log.h> #include <hardware/audio.h> +#include <util/CoreUtils.h> #include <utils/Trace.h> namespace android { @@ -239,7 +239,7 @@ Return<void> StreamOut::getSupportedProfiles(getSupportedProfiles_cb _hidl_cb) { return mStreamCommon->getSupportedProfiles(_hidl_cb); } -Return<Result> StreamOut::setAudioProperties(const AudioConfigBase& config) { +Return<Result> StreamOut::setAudioProperties(const AudioConfigBaseOptional& config) { return mStreamCommon->setAudioProperties(config); } @@ -589,13 +589,15 @@ Return<void> StreamOut::debug(const hidl_handle& fd, const hidl_vec<hidl_string> Result StreamOut::doUpdateSourceMetadata(const SourceMetadata& sourceMetadata) { std::vector<playback_track_metadata_t> halTracks; #if MAJOR_VERSION <= 6 - (void)sourceMetadataToHal(sourceMetadata, &halTracks); + (void)CoreUtils::sourceMetadataToHal(sourceMetadata, &halTracks); #else // Validate whether a conversion to V7 is possible. This is needed // to have a consistent behavior of the HAL regardless of the API // version of the legacy HAL (and also to be consistent with openOutputStream). std::vector<playback_track_metadata_v7> halTracksV7; - if (status_t status = sourceMetadataToHalV7(sourceMetadata, &halTracksV7); status == NO_ERROR) { + if (status_t status = CoreUtils::sourceMetadataToHalV7( + sourceMetadata, false /*ignoreNonVendorTags*/, &halTracksV7); + status == NO_ERROR) { halTracks.reserve(halTracksV7.size()); for (auto metadata_v7 : halTracksV7) { halTracks.push_back(std::move(metadata_v7.base)); @@ -615,7 +617,9 @@ Result StreamOut::doUpdateSourceMetadata(const SourceMetadata& sourceMetadata) { #if MAJOR_VERSION >= 7 Result StreamOut::doUpdateSourceMetadataV7(const SourceMetadata& sourceMetadata) { std::vector<playback_track_metadata_v7> halTracks; - if (status_t status = sourceMetadataToHalV7(sourceMetadata, &halTracks); status != NO_ERROR) { + if (status_t status = CoreUtils::sourceMetadataToHalV7( + sourceMetadata, false /*ignoreNonVendorTags*/, &halTracks); + status != NO_ERROR) { return Stream::analyzeStatus("sourceMetadataToHal", status); } const source_metadata_v7_t halMetadata = { @@ -658,32 +662,65 @@ Return<Result> StreamOut::selectPresentation(int32_t /*presentationId*/, int32_t #if MAJOR_VERSION >= 6 Return<void> StreamOut::getDualMonoMode(getDualMonoMode_cb _hidl_cb) { - _hidl_cb(Result::NOT_SUPPORTED, DualMonoMode::OFF); + audio_dual_mono_mode_t mode = AUDIO_DUAL_MONO_MODE_OFF; + Result retval = mStream->get_dual_mono_mode != nullptr + ? Stream::analyzeStatus("get_dual_mono_mode", + mStream->get_dual_mono_mode(mStream, &mode)) + : Result::NOT_SUPPORTED; + _hidl_cb(retval, DualMonoMode(mode)); return Void(); } -Return<Result> StreamOut::setDualMonoMode(DualMonoMode /*mode*/) { - return Result::NOT_SUPPORTED; +Return<Result> StreamOut::setDualMonoMode(DualMonoMode mode) { + return mStream->set_dual_mono_mode != nullptr + ? Stream::analyzeStatus( + "set_dual_mono_mode", + mStream->set_dual_mono_mode(mStream, + static_cast<audio_dual_mono_mode_t>(mode))) + : Result::NOT_SUPPORTED; } Return<void> StreamOut::getAudioDescriptionMixLevel(getAudioDescriptionMixLevel_cb _hidl_cb) { - _hidl_cb(Result::NOT_SUPPORTED, -std::numeric_limits<float>::infinity()); + float leveldB = -std::numeric_limits<float>::infinity(); + Result retval = mStream->get_audio_description_mix_level != nullptr + ? Stream::analyzeStatus( + "get_audio_description_mix_level", + mStream->get_audio_description_mix_level(mStream, &leveldB)) + : Result::NOT_SUPPORTED; + _hidl_cb(retval, leveldB); return Void(); } -Return<Result> StreamOut::setAudioDescriptionMixLevel(float /*leveldB*/) { - return Result::NOT_SUPPORTED; +Return<Result> StreamOut::setAudioDescriptionMixLevel(float leveldB) { + return mStream->set_audio_description_mix_level != nullptr + ? Stream::analyzeStatus( + "set_audio_description_mix_level", + mStream->set_audio_description_mix_level(mStream, leveldB)) + : Result::NOT_SUPPORTED; } Return<void> StreamOut::getPlaybackRateParameters(getPlaybackRateParameters_cb _hidl_cb) { - _hidl_cb(Result::NOT_SUPPORTED, - // Same as AUDIO_PLAYBACK_RATE_INITIALIZER - PlaybackRate{1.0f, 1.0f, TimestretchMode::DEFAULT, TimestretchFallbackMode::FAIL}); + audio_playback_rate_t rate = AUDIO_PLAYBACK_RATE_INITIALIZER; + Result retval = + mStream->get_playback_rate_parameters != nullptr + ? Stream::analyzeStatus("get_playback_rate_parameters", + mStream->get_playback_rate_parameters(mStream, &rate)) + : Result::NOT_SUPPORTED; + _hidl_cb(retval, + PlaybackRate{rate.mSpeed, rate.mPitch, static_cast<TimestretchMode>(rate.mStretchMode), + static_cast<TimestretchFallbackMode>(rate.mFallbackMode)}); return Void(); } -Return<Result> StreamOut::setPlaybackRateParameters(const PlaybackRate& /*playbackRate*/) { - return Result::NOT_SUPPORTED; +Return<Result> StreamOut::setPlaybackRateParameters(const PlaybackRate& playbackRate) { + audio_playback_rate_t rate = { + playbackRate.speed, playbackRate.pitch, + static_cast<audio_timestretch_stretch_mode_t>(playbackRate.timestretchMode), + static_cast<audio_timestretch_fallback_mode_t>(playbackRate.fallbackMode)}; + return mStream->set_playback_rate_parameters != nullptr + ? Stream::analyzeStatus("set_playback_rate_parameters", + mStream->set_playback_rate_parameters(mStream, &rate)) + : Result::NOT_SUPPORTED; } Return<Result> StreamOut::setEventCallback(const sp<IStreamOutEventCallback>& callback) { diff --git a/audio/core/all-versions/default/TEST_MAPPING b/audio/core/all-versions/default/TEST_MAPPING new file mode 100644 index 0000000000..d53c97afaa --- /dev/null +++ b/audio/core/all-versions/default/TEST_MAPPING @@ -0,0 +1,7 @@ +{ + "presubmit": [ + { + "name": "android.hardware.audio@7.0-util_tests" + } + ] +} diff --git a/audio/core/all-versions/default/include/core/default/Conversions.h b/audio/core/all-versions/default/include/core/default/Conversions.h deleted file mode 100644 index 61720d5303..0000000000 --- a/audio/core/all-versions/default/include/core/default/Conversions.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_HARDWARE_AUDIO_CONVERSIONS_H_ -#define ANDROID_HARDWARE_AUDIO_CONVERSIONS_H_ - -#include PATH(android/hardware/audio/FILE_VERSION/types.h) - -#include <string> - -#include <system/audio.h> - -#include <VersionUtils.h> - -namespace android { -namespace hardware { -namespace audio { -namespace CPP_VERSION { -namespace implementation { - -using ::android::hardware::hidl_vec; -using namespace ::android::hardware::audio::common::CPP_VERSION; -using namespace ::android::hardware::audio::CPP_VERSION; - -status_t deviceAddressToHal(const DeviceAddress& device, audio_devices_t* halDeviceType, - char* halDeviceAddress); -status_t deviceAddressFromHal(audio_devices_t halDeviceType, const char* halDeviceAddress, - DeviceAddress* device); - -#if MAJOR_VERSION >= 4 -bool halToMicrophoneCharacteristics(MicrophoneInfo* pDst, - const struct audio_microphone_characteristic_t& src); -status_t sinkMetadataToHal(const SinkMetadata& sinkMetadata, - std::vector<record_track_metadata>* halTracks); -status_t sourceMetadataToHal(const SourceMetadata& sourceMetadata, - std::vector<playback_track_metadata_t>* halTracks); -#endif - -#if MAJOR_VERSION <= 6 -using AudioInputFlags = - ::android::hardware::audio::common::CPP_VERSION::implementation::AudioInputFlagBitfield; -using AudioOutputFlags = - ::android::hardware::audio::common::CPP_VERSION::implementation::AudioOutputFlagBitfield; - -inline bool audioInputFlagsToHal(AudioInputFlags flags, audio_input_flags_t* halFlags) { - *halFlags = static_cast<audio_input_flags_t>(flags); - return true; -} - -inline bool audioOutputFlagsToHal(AudioOutputFlags flags, audio_output_flags_t* halFlags) { - *halFlags = static_cast<audio_output_flags_t>(flags); - return true; -} -#else -bool audioInputFlagsToHal(const hidl_vec<AudioInOutFlag>& flags, audio_input_flags_t* halFlags); -bool audioOutputFlagsToHal(const hidl_vec<AudioInOutFlag>& flags, audio_output_flags_t* halFlags); -// Overloading isn't convenient when passing a nullptr. -status_t sinkMetadataToHalV7(const SinkMetadata& sinkMetadata, - std::vector<record_track_metadata_v7_t>* halTracks); -status_t sourceMetadataToHalV7(const SourceMetadata& sourceMetadata, - std::vector<playback_track_metadata_v7_t>* halTracks); -#endif - -} // namespace implementation -} // namespace CPP_VERSION -} // namespace audio -} // namespace hardware -} // namespace android - -#endif // ANDROID_HARDWARE_AUDIO_CONVERSIONS_H_ 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 2a4d22651a..5851fc949c 100644 --- a/audio/core/all-versions/default/include/core/default/Device.h +++ b/audio/core/all-versions/default/include/core/default/Device.h @@ -31,6 +31,7 @@ #include <hidl/MQDescriptor.h> #include <VersionUtils.h> +#include <util/CoreUtils.h> namespace android { namespace hardware { @@ -43,17 +44,10 @@ using ::android::hardware::hidl_string; using ::android::hardware::hidl_vec; using ::android::hardware::Return; using ::android::hardware::Void; -#if MAJOR_VERSION <= 6 -using AudioInputFlags = - ::android::hardware::audio::common::CPP_VERSION::implementation::AudioInputFlagBitfield; -using AudioOutputFlags = - ::android::hardware::audio::common::CPP_VERSION::implementation::AudioOutputFlagBitfield; -#else -using AudioInputFlags = hidl_vec<::android::hardware::audio::CPP_VERSION::AudioInOutFlag>; -using AudioOutputFlags = hidl_vec<::android::hardware::audio::CPP_VERSION::AudioInOutFlag>; -#endif using namespace ::android::hardware::audio::common::CPP_VERSION; using namespace ::android::hardware::audio::CPP_VERSION; +using AudioInputFlags = CoreUtils::AudioInputFlags; +using AudioOutputFlags = CoreUtils::AudioOutputFlags; struct Device : public IDevice, public ParametersUtil { explicit Device(audio_hw_device_t* device); diff --git a/audio/core/all-versions/default/include/core/default/Stream.h b/audio/core/all-versions/default/include/core/default/Stream.h index 0865992f95..66d60e3aa7 100644 --- a/audio/core/all-versions/default/include/core/default/Stream.h +++ b/audio/core/all-versions/default/include/core/default/Stream.h @@ -77,7 +77,7 @@ struct Stream : public IStream, public ParametersUtil { Return<Result> setFormat(AudioFormat format) override; #else Return<void> getSupportedProfiles(getSupportedProfiles_cb _hidl_cb) override; - Return<Result> setAudioProperties(const AudioConfigBase& config) override; + Return<Result> setAudioProperties(const AudioConfigBaseOptional& config) override; #endif // MAJOR_VERSION <= 6 Return<void> getAudioProperties(getAudioProperties_cb _hidl_cb) override; Return<Result> addEffect(uint64_t effectId) override; diff --git a/audio/core/all-versions/default/include/core/default/StreamIn.h b/audio/core/all-versions/default/include/core/default/StreamIn.h index 651b3a6ae1..a980f3f999 100644 --- a/audio/core/all-versions/default/include/core/default/StreamIn.h +++ b/audio/core/all-versions/default/include/core/default/StreamIn.h @@ -72,7 +72,7 @@ struct StreamIn : public IStreamIn { Return<Result> setFormat(AudioFormat format) override; #else Return<void> getSupportedProfiles(getSupportedProfiles_cb _hidl_cb) override; - Return<Result> setAudioProperties(const AudioConfigBase& config) override; + Return<Result> setAudioProperties(const AudioConfigBaseOptional& config) override; #endif // MAJOR_VERSION <= 6 Return<void> getAudioProperties(getAudioProperties_cb _hidl_cb) override; Return<Result> addEffect(uint64_t effectId) override; diff --git a/audio/core/all-versions/default/include/core/default/StreamOut.h b/audio/core/all-versions/default/include/core/default/StreamOut.h index 02d8e8962d..0b07972810 100644 --- a/audio/core/all-versions/default/include/core/default/StreamOut.h +++ b/audio/core/all-versions/default/include/core/default/StreamOut.h @@ -73,7 +73,7 @@ struct StreamOut : public IStreamOut { Return<Result> setFormat(AudioFormat format) override; #else Return<void> getSupportedProfiles(getSupportedProfiles_cb _hidl_cb) override; - Return<Result> setAudioProperties(const AudioConfigBase& config) override; + Return<Result> setAudioProperties(const AudioConfigBaseOptional& config) override; #endif // MAJOR_VERSION <= 6 Return<void> getAudioProperties(getAudioProperties_cb _hidl_cb) override; Return<Result> addEffect(uint64_t effectId) override; diff --git a/audio/core/all-versions/default/util/Android.bp b/audio/core/all-versions/default/util/Android.bp new file mode 100644 index 0000000000..447184bbe7 --- /dev/null +++ b/audio/core/all-versions/default/util/Android.bp @@ -0,0 +1,139 @@ +cc_defaults { + name: "android.hardware.audio-util_default", + defaults: ["hidl_defaults"], + + vendor_available: true, + + export_include_dirs: ["include"], + + srcs: [ + "CoreUtils.cpp", + ], + + shared_libs: [ + "liblog", + "libutils", + "libhidlbase", + "android.hardware.audio.common-util", + ], + export_shared_lib_headers: [ + "android.hardware.audio.common-util", + ], + + header_libs: [ + "libaudio_system_headers", + "libhardware_headers", + ], +} + +cc_library_shared { + name: "android.hardware.audio@2.0-util", + defaults: ["android.hardware.audio-util_default"], + shared_libs: [ + "android.hardware.audio.common@2.0", + "android.hardware.audio.common@2.0-util", + "android.hardware.audio@2.0", + ], + cflags: [ + "-DMAJOR_VERSION=2", + "-DMINOR_VERSION=0", + "-include common/all-versions/VersionMacro.h", + ], +} + +cc_library_shared { + name: "android.hardware.audio@4.0-util", + defaults: ["android.hardware.audio-util_default"], + shared_libs: [ + "android.hardware.audio.common@4.0", + "android.hardware.audio.common@4.0-util", + "android.hardware.audio@4.0", + ], + cflags: [ + "-DMAJOR_VERSION=4", + "-DMINOR_VERSION=0", + "-include common/all-versions/VersionMacro.h", + ], +} + +cc_library_shared { + name: "android.hardware.audio@5.0-util", + defaults: ["android.hardware.audio-util_default"], + shared_libs: [ + "android.hardware.audio.common@5.0", + "android.hardware.audio.common@5.0-util", + "android.hardware.audio@5.0", + ], + cflags: [ + "-DMAJOR_VERSION=5", + "-DMINOR_VERSION=0", + "-include common/all-versions/VersionMacro.h", + ], +} + +cc_library_shared { + name: "android.hardware.audio@6.0-util", + defaults: ["android.hardware.audio-util_default"], + shared_libs: [ + "android.hardware.audio.common@6.0", + "android.hardware.audio.common@6.0-util", + "android.hardware.audio@6.0", + ], + cflags: [ + "-DMAJOR_VERSION=6", + "-DMINOR_VERSION=0", + "-include common/all-versions/VersionMacro.h", + ], +} + +cc_library { + name: "android.hardware.audio@7.0-util", + defaults: ["android.hardware.audio-util_default"], + shared_libs: [ + "android.hardware.audio.common@7.0", + "android.hardware.audio.common@7.0-enums", + "android.hardware.audio.common@7.0-util", + "android.hardware.audio@7.0", + "libbase", + "libxml2", + ], + cflags: [ + "-DMAJOR_VERSION=7", + "-DMINOR_VERSION=0", + "-include common/all-versions/VersionMacro.h", + ], +} + +// Note: this isn't a VTS test, but rather a unit test +// to verify correctness of conversion utilities. +cc_test { + name: "android.hardware.audio@7.0-util_tests", + defaults: ["android.hardware.audio-util_default"], + + srcs: ["tests/coreutils_tests.cpp"], + + // Use static linking to allow running in presubmit on + // targets that don't have HAL V7. + static_libs: [ + "android.hardware.audio.common@7.0", + "android.hardware.audio.common@7.0-enums", + "android.hardware.audio.common@7.0-util", + "android.hardware.audio@7.0", + "android.hardware.audio@7.0-util", + ], + + shared_libs: [ + "libbase", + "libxml2", + ], + + cflags: [ + "-Werror", + "-Wall", + "-DMAJOR_VERSION=7", + "-DMINOR_VERSION=0", + "-include common/all-versions/VersionMacro.h", + ], + + test_suites: ["device-tests"], +} diff --git a/audio/core/all-versions/default/util/CoreUtils.cpp b/audio/core/all-versions/default/util/CoreUtils.cpp new file mode 100644 index 0000000000..14f76f3c65 --- /dev/null +++ b/audio/core/all-versions/default/util/CoreUtils.cpp @@ -0,0 +1,476 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if MAJOR_VERSION >= 7 +#include <android_audio_policy_configuration_V7_0-enums.h> +#endif +#include <HidlUtils.h> +#include <log/log.h> + +#include "util/CoreUtils.h" + +using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils; +#if MAJOR_VERSION >= 7 +namespace xsd { +using namespace ::android::audio::policy::configuration::V7_0; +} +#endif + +namespace android { +namespace hardware { +namespace audio { +namespace CPP_VERSION { +namespace implementation { + +#define CONVERT_CHECKED(expr, result) \ + if (status_t status = (expr); status != NO_ERROR) { \ + result = status; \ + } + +status_t CoreUtils::deviceAddressToHal(const DeviceAddress& device, audio_devices_t* halDeviceType, + char* halDeviceAddress) { +#if MAJOR_VERSION >= 5 + return HidlUtils::deviceAddressToHal(device, halDeviceType, halDeviceAddress); +#else + return HidlUtils::deviceAddressToHalImpl(device, halDeviceType, halDeviceAddress); +#endif +} + +status_t CoreUtils::deviceAddressFromHal(audio_devices_t halDeviceType, + const char* halDeviceAddress, DeviceAddress* device) { +#if MAJOR_VERSION >= 5 + return HidlUtils::deviceAddressFromHal(halDeviceType, halDeviceAddress, device); +#else + return HidlUtils::deviceAddressFromHalImpl(halDeviceType, halDeviceAddress, device); +#endif +} + +#if MAJOR_VERSION >= 4 +status_t CoreUtils::microphoneInfoFromHal( + const struct audio_microphone_characteristic_t& halMicInfo, MicrophoneInfo* micInfo) { + status_t result = NO_ERROR; + micInfo->deviceId = halMicInfo.device_id; + CONVERT_CHECKED( + deviceAddressFromHal(halMicInfo.device, halMicInfo.address, &micInfo->deviceAddress), + result); + size_t chCount; + for (chCount = 0; chCount < AUDIO_CHANNEL_COUNT_MAX; ++chCount) { + if (halMicInfo.channel_mapping[chCount] == AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED) { + break; + } + } + micInfo->channelMapping.resize(chCount); + for (size_t ch = 0; ch < micInfo->channelMapping.size(); ch++) { + micInfo->channelMapping[ch] = AudioMicrophoneChannelMapping(halMicInfo.channel_mapping[ch]); + } + micInfo->location = AudioMicrophoneLocation(halMicInfo.location); + micInfo->group = AudioMicrophoneGroup(halMicInfo.group); + micInfo->indexInTheGroup = static_cast<uint32_t>(halMicInfo.index_in_the_group); + micInfo->sensitivity = halMicInfo.sensitivity; + micInfo->maxSpl = halMicInfo.max_spl; + micInfo->minSpl = halMicInfo.min_spl; + micInfo->directionality = AudioMicrophoneDirectionality(halMicInfo.directionality); + micInfo->frequencyResponse.resize(halMicInfo.num_frequency_responses); + for (size_t k = 0; k < halMicInfo.num_frequency_responses; k++) { + micInfo->frequencyResponse[k].frequency = halMicInfo.frequency_responses[0][k]; + micInfo->frequencyResponse[k].level = halMicInfo.frequency_responses[1][k]; + } + micInfo->position.x = halMicInfo.geometric_location.x; + micInfo->position.y = halMicInfo.geometric_location.y; + micInfo->position.z = halMicInfo.geometric_location.z; + micInfo->orientation.x = halMicInfo.orientation.x; + micInfo->orientation.y = halMicInfo.orientation.y; + micInfo->orientation.z = halMicInfo.orientation.z; + return result; +} + +status_t CoreUtils::microphoneInfoToHal(const MicrophoneInfo& micInfo, + audio_microphone_characteristic_t* halMicInfo) { + status_t result = NO_ERROR; + strncpy(halMicInfo->device_id, micInfo.deviceId.c_str(), AUDIO_MICROPHONE_ID_MAX_LEN); + halMicInfo->device_id[AUDIO_MICROPHONE_ID_MAX_LEN - 1] = '\0'; + if (micInfo.deviceId.size() >= AUDIO_MICROPHONE_ID_MAX_LEN) { + ALOGE("HIDL MicrophoneInfo device ID is too long: %zu", micInfo.deviceId.size()); + result = BAD_VALUE; + } + CONVERT_CHECKED( + deviceAddressToHal(micInfo.deviceAddress, &halMicInfo->device, halMicInfo->address), + result); + if (micInfo.channelMapping.size() > AUDIO_CHANNEL_COUNT_MAX) { + ALOGE("HIDL MicrophoneInfo has too many channelMapping elements: %zu", + micInfo.channelMapping.size()); + result = BAD_VALUE; + } + size_t ch; + for (ch = 0; ch < micInfo.channelMapping.size() && ch < AUDIO_CHANNEL_COUNT_MAX; ch++) { + halMicInfo->channel_mapping[ch] = + static_cast<audio_microphone_channel_mapping_t>(micInfo.channelMapping[ch]); + } + for (; ch < AUDIO_CHANNEL_COUNT_MAX; ch++) { + halMicInfo->channel_mapping[ch] = AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED; + } + halMicInfo->location = static_cast<audio_microphone_location_t>(micInfo.location); + halMicInfo->group = static_cast<audio_microphone_group_t>(micInfo.group); + halMicInfo->index_in_the_group = static_cast<unsigned int>(micInfo.indexInTheGroup); + halMicInfo->sensitivity = micInfo.sensitivity; + halMicInfo->max_spl = micInfo.maxSpl; + halMicInfo->min_spl = micInfo.minSpl; + halMicInfo->directionality = + static_cast<audio_microphone_directionality_t>(micInfo.directionality); + halMicInfo->num_frequency_responses = + static_cast<unsigned int>(micInfo.frequencyResponse.size()); + if (halMicInfo->num_frequency_responses > AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES) { + ALOGE("HIDL MicrophoneInfo has too many frequency responses: %u", + halMicInfo->num_frequency_responses); + halMicInfo->num_frequency_responses = AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES; + result = BAD_VALUE; + } + for (size_t k = 0; k < halMicInfo->num_frequency_responses; k++) { + halMicInfo->frequency_responses[0][k] = micInfo.frequencyResponse[k].frequency; + halMicInfo->frequency_responses[1][k] = micInfo.frequencyResponse[k].level; + } + halMicInfo->geometric_location.x = micInfo.position.x; + halMicInfo->geometric_location.y = micInfo.position.y; + halMicInfo->geometric_location.z = micInfo.position.z; + halMicInfo->orientation.x = micInfo.orientation.x; + halMicInfo->orientation.y = micInfo.orientation.y; + halMicInfo->orientation.z = micInfo.orientation.z; + return result; +} + +status_t CoreUtils::sinkMetadataFromHal(const std::vector<record_track_metadata_t>& halTracks, + SinkMetadata* sinkMetadata) { + status_t result = NO_ERROR; + sinkMetadata->tracks.resize(halTracks.size()); + for (size_t i = 0; i < sinkMetadata->tracks.size(); ++i) { + const auto& halTrackMetadata = halTracks[i]; + RecordTrackMetadata trackMetadata{}; + CONVERT_CHECKED( + HidlUtils::audioSourceFromHal(halTrackMetadata.source, &trackMetadata.source), + result); + trackMetadata.gain = halTrackMetadata.gain; +#if MAJOR_VERSION >= 5 + if (halTrackMetadata.dest_device != AUDIO_DEVICE_NONE) { + DeviceAddress address; + if (status_t status = + deviceAddressFromHal(halTrackMetadata.dest_device, + halTrackMetadata.dest_device_address, &address); + status == NO_ERROR) { + trackMetadata.destination.device(std::move(address)); + } else { + result = status; + } + } +#if MAJOR_VERSION >= 7 + trackMetadata.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_NONE); +#endif +#endif // MAJOR_VERSION >= 5 + sinkMetadata->tracks[i] = std::move(trackMetadata); + } + return result; +} + +status_t CoreUtils::sinkMetadataFromHalV7(const std::vector<record_track_metadata_v7_t>& halTracks, + bool ignoreNonVendorTags, SinkMetadata* sinkMetadata) { + std::vector<record_track_metadata_t> bases; + bases.reserve(halTracks.size()); + std::transform(halTracks.begin(), halTracks.end(), std::back_inserter(bases), + [](const record_track_metadata_v7_t& src) -> record_track_metadata_t { + record_track_metadata_t result; + record_track_metadata_from_v7(&result, &src); + return result; + }); + status_t result = sinkMetadataFromHal(bases, sinkMetadata); +#if MAJOR_VERSION >= 7 + for (size_t i = 0; i < halTracks.size(); ++i) { + auto& trackMetadata = sinkMetadata->tracks[i]; + const auto& halTrackMetadata = halTracks[i]; + CONVERT_CHECKED( + HidlUtils::audioChannelMaskFromHal(halTrackMetadata.channel_mask, true /*isInput*/, + &trackMetadata.channelMask), + result); + std::vector<std::string> strTags = HidlUtils::splitAudioTags(halTrackMetadata.tags); + if (ignoreNonVendorTags) { + strTags = HidlUtils::filterOutNonVendorTags(strTags); + } + CONVERT_CHECKED(HidlUtils::audioTagsFromHal(strTags, &trackMetadata.tags), result); + } +#else + (void)ignoreNonVendorTags; +#endif + return result; +} + +status_t CoreUtils::sinkMetadataToHal(const SinkMetadata& sinkMetadata, + std::vector<record_track_metadata_t>* halTracks) { + status_t result = NO_ERROR; + if (halTracks != nullptr) { + halTracks->reserve(sinkMetadata.tracks.size()); + } + for (auto& trackMetadata : sinkMetadata.tracks) { + record_track_metadata halTrackMetadata{.gain = trackMetadata.gain}; + CONVERT_CHECKED(HidlUtils::audioSourceToHal(trackMetadata.source, &halTrackMetadata.source), + result); +#if MAJOR_VERSION >= 5 + if (trackMetadata.destination.getDiscriminator() == + RecordTrackMetadata::Destination::hidl_discriminator::device) { + CONVERT_CHECKED(deviceAddressToHal(trackMetadata.destination.device(), + &halTrackMetadata.dest_device, + halTrackMetadata.dest_device_address), + result); + } +#endif + if (halTracks != nullptr) { + halTracks->push_back(std::move(halTrackMetadata)); + } + } + return result; +} + +status_t CoreUtils::sinkMetadataToHalV7(const SinkMetadata& sinkMetadata, bool ignoreNonVendorTags, + std::vector<record_track_metadata_v7_t>* halTracks) { + std::vector<record_track_metadata> bases; + status_t result = sinkMetadataToHal(sinkMetadata, halTracks != nullptr ? &bases : nullptr); + if (halTracks != nullptr) { + halTracks->reserve(sinkMetadata.tracks.size()); + } + for (size_t i = 0; i < sinkMetadata.tracks.size(); ++i) { + record_track_metadata_v7_t halTrackMetadata; + if (halTracks != nullptr) { + record_track_metadata_to_v7(&halTrackMetadata, &bases[i]); + } +#if MAJOR_VERSION >= 7 + const auto& trackMetadata = sinkMetadata.tracks[i]; + CONVERT_CHECKED(HidlUtils::audioChannelMaskToHal(trackMetadata.channelMask, + &halTrackMetadata.channel_mask), + result); + if (ignoreNonVendorTags) { + CONVERT_CHECKED( + HidlUtils::audioTagsToHal(HidlUtils::filterOutNonVendorTags(trackMetadata.tags), + halTrackMetadata.tags), + result); + } else { + CONVERT_CHECKED(HidlUtils::audioTagsToHal(trackMetadata.tags, halTrackMetadata.tags), + result); + } +#else + (void)ignoreNonVendorTags; +#endif + if (halTracks != nullptr) { + halTracks->push_back(std::move(halTrackMetadata)); + } + } + return result; +} + +status_t CoreUtils::sourceMetadataFromHal(const std::vector<playback_track_metadata_t>& halTracks, + SourceMetadata* sourceMetadata) { + status_t result = NO_ERROR; + sourceMetadata->tracks.resize(halTracks.size()); + for (size_t i = 0; i < sourceMetadata->tracks.size(); ++i) { + const auto& halTrackMetadata = halTracks[i]; + PlaybackTrackMetadata trackMetadata{}; + CONVERT_CHECKED(HidlUtils::audioUsageFromHal(halTrackMetadata.usage, &trackMetadata.usage), + result); + CONVERT_CHECKED(HidlUtils::audioContentTypeFromHal(halTrackMetadata.content_type, + &trackMetadata.contentType), + result); + trackMetadata.gain = halTrackMetadata.gain; +#if MAJOR_VERSION >= 7 + trackMetadata.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_NONE); +#endif + sourceMetadata->tracks[i] = std::move(trackMetadata); + } + return result; +} + +status_t CoreUtils::sourceMetadataFromHalV7( + const std::vector<playback_track_metadata_v7_t>& halTracks, bool ignoreNonVendorTags, + SourceMetadata* sourceMetadata) { + std::vector<playback_track_metadata_t> bases; + bases.reserve(halTracks.size()); + std::transform(halTracks.begin(), halTracks.end(), std::back_inserter(bases), + [](const playback_track_metadata_v7_t& src) -> playback_track_metadata_t { + playback_track_metadata_t result; + playback_track_metadata_from_v7(&result, &src); + return result; + }); + status_t result = sourceMetadataFromHal(bases, sourceMetadata); +#if MAJOR_VERSION >= 7 + for (size_t i = 0; i < halTracks.size(); ++i) { + auto& trackMetadata = sourceMetadata->tracks[i]; + const auto& halTrackMetadata = halTracks[i]; + CONVERT_CHECKED( + HidlUtils::audioChannelMaskFromHal(halTrackMetadata.channel_mask, false /*isInput*/, + &trackMetadata.channelMask), + result); + std::vector<std::string> strTags = HidlUtils::splitAudioTags(halTrackMetadata.tags); + if (ignoreNonVendorTags) { + strTags = HidlUtils::filterOutNonVendorTags(strTags); + } + CONVERT_CHECKED(HidlUtils::audioTagsFromHal(strTags, &trackMetadata.tags), result); + } +#else + (void)ignoreNonVendorTags; +#endif + return result; +} + +status_t CoreUtils::sourceMetadataToHal(const SourceMetadata& sourceMetadata, + std::vector<playback_track_metadata_t>* halTracks) { + status_t result = NO_ERROR; + if (halTracks != nullptr) { + halTracks->reserve(sourceMetadata.tracks.size()); + } + for (auto& trackMetadata : sourceMetadata.tracks) { + playback_track_metadata_t halTrackMetadata{.gain = trackMetadata.gain}; + CONVERT_CHECKED(HidlUtils::audioUsageToHal(trackMetadata.usage, &halTrackMetadata.usage), + result); + CONVERT_CHECKED(HidlUtils::audioContentTypeToHal(trackMetadata.contentType, + &halTrackMetadata.content_type), + result); + if (halTracks != nullptr) { + halTracks->push_back(std::move(halTrackMetadata)); + } + } + return result; +} + +status_t CoreUtils::sourceMetadataToHalV7(const SourceMetadata& sourceMetadata, + bool ignoreNonVendorTags, + std::vector<playback_track_metadata_v7_t>* halTracks) { + std::vector<playback_track_metadata_t> bases; + status_t result = sourceMetadataToHal(sourceMetadata, halTracks != nullptr ? &bases : nullptr); + if (halTracks != nullptr) { + halTracks->reserve(sourceMetadata.tracks.size()); + } + for (size_t i = 0; i < sourceMetadata.tracks.size(); ++i) { + playback_track_metadata_v7_t halTrackMetadata; + if (halTracks != nullptr) { + playback_track_metadata_to_v7(&halTrackMetadata, &bases[i]); + } +#if MAJOR_VERSION >= 7 + const auto& trackMetadata = sourceMetadata.tracks[i]; + CONVERT_CHECKED(HidlUtils::audioChannelMaskToHal(trackMetadata.channelMask, + &halTrackMetadata.channel_mask), + result); + if (ignoreNonVendorTags) { + CONVERT_CHECKED( + HidlUtils::audioTagsToHal(HidlUtils::filterOutNonVendorTags(trackMetadata.tags), + halTrackMetadata.tags), + result); + } else { + CONVERT_CHECKED(HidlUtils::audioTagsToHal(trackMetadata.tags, halTrackMetadata.tags), + result); + } +#else + (void)ignoreNonVendorTags; +#endif + if (halTracks != nullptr) { + halTracks->push_back(std::move(halTrackMetadata)); + } + } + return result; +} +#endif // MAJOR_VERSION >= 4 + +#if MAJOR_VERSION >= 7 +namespace xsd { +using namespace ::android::audio::policy::configuration::V7_0; +} + +status_t CoreUtils::audioInputFlagsFromHal(audio_input_flags_t halFlagMask, + AudioInputFlags* flags) { + status_t status = NO_ERROR; + std::vector<AudioInOutFlag> result; + for (uint32_t bit = 0; halFlagMask != 0 && bit < sizeof(audio_input_flags_t) * 8; ++bit) { + audio_input_flags_t flag = static_cast<audio_input_flags_t>(1u << bit); + if ((flag & halFlagMask) == flag) { + AudioInOutFlag flagStr = audio_input_flag_to_string(flag); + if (!flagStr.empty() && !xsd::isUnknownAudioInOutFlag(flagStr)) { + result.push_back(flagStr); + } else { + ALOGE("Unknown audio input flag value 0x%X", flag); + status = BAD_VALUE; + } + halFlagMask = static_cast<audio_input_flags_t>(halFlagMask & ~flag); + } + } + *flags = result; + return status; +} + +status_t CoreUtils::audioInputFlagsToHal(const AudioInputFlags& flags, + audio_input_flags_t* halFlagMask) { + status_t status = NO_ERROR; + *halFlagMask = {}; + for (const auto& flag : flags) { + audio_input_flags_t halFlag; + if (!xsd::isUnknownAudioInOutFlag(flag) && + audio_input_flag_from_string(flag.c_str(), &halFlag)) { + *halFlagMask = static_cast<audio_input_flags_t>(*halFlagMask | halFlag); + } else { + ALOGE("Unknown audio input flag \"%s\"", flag.c_str()); + status = BAD_VALUE; + } + } + return status; +} + +status_t CoreUtils::audioOutputFlagsFromHal(audio_output_flags_t halFlagMask, + AudioOutputFlags* flags) { + status_t status = NO_ERROR; + std::vector<AudioInOutFlag> result; + for (uint32_t bit = 0; halFlagMask != 0 && bit < sizeof(audio_output_flags_t) * 8; ++bit) { + audio_output_flags_t flag = static_cast<audio_output_flags_t>(1u << bit); + if ((flag & halFlagMask) == flag) { + AudioInOutFlag flagStr = audio_output_flag_to_string(flag); + if (!flagStr.empty() && !xsd::isUnknownAudioInOutFlag(flagStr)) { + result.push_back(flagStr); + } else { + ALOGE("Unknown audio output flag value 0x%X", flag); + status = BAD_VALUE; + } + halFlagMask = static_cast<audio_output_flags_t>(halFlagMask & ~flag); + } + } + *flags = result; + return status; +} + +status_t CoreUtils::audioOutputFlagsToHal(const AudioOutputFlags& flags, + audio_output_flags_t* halFlagMask) { + status_t status = NO_ERROR; + *halFlagMask = {}; + for (const auto& flag : flags) { + audio_output_flags_t halFlag; + if (!xsd::isUnknownAudioInOutFlag(flag) && + audio_output_flag_from_string(flag.c_str(), &halFlag)) { + *halFlagMask = static_cast<audio_output_flags_t>(*halFlagMask | halFlag); + } else { + ALOGE("Unknown audio output flag \"%s\"", flag.c_str()); + status = BAD_VALUE; + } + } + return status; +} +#endif + +} // namespace implementation +} // namespace CPP_VERSION +} // namespace audio +} // namespace hardware +} // namespace android diff --git a/audio/core/all-versions/default/util/include/util/CoreUtils.h b/audio/core/all-versions/default/util/include/util/CoreUtils.h new file mode 100644 index 0000000000..1e5272a479 --- /dev/null +++ b/audio/core/all-versions/default/util/include/util/CoreUtils.h @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +// clang-format off +#include PATH(android/hardware/audio/FILE_VERSION/types.h) +// clang-format off + +#include <vector> + +#include <system/audio.h> + +#include <common/all-versions/VersionUtils.h> +#include <VersionUtils.h> + +namespace android { +namespace hardware { +namespace audio { +namespace CPP_VERSION { +namespace implementation { + +using ::android::hardware::audio::common::utils::EnumBitfield; +using ::android::hardware::hidl_vec; +using namespace ::android::hardware::audio::common::CPP_VERSION; +using namespace ::android::hardware::audio::CPP_VERSION; + +struct CoreUtils { + // Note: the converters for DeviceAddress have to be in CoreUtils for HAL V4 + // because DeviceAddress used to be defined in the core HAL. For V5 and above + // these functions simply delegate to HidlUtils. + static status_t deviceAddressToHal(const DeviceAddress& device, audio_devices_t* halDeviceType, + char* halDeviceAddress); + static status_t deviceAddressFromHal(audio_devices_t halDeviceType, const char* halDeviceAddress, + DeviceAddress* device); +#if MAJOR_VERSION >= 4 + static status_t microphoneInfoFromHal(const struct audio_microphone_characteristic_t& halMicInfo, + MicrophoneInfo* micInfo); + static status_t microphoneInfoToHal(const MicrophoneInfo& micInfo, audio_microphone_characteristic_t* halMicInfo); + // Note: {Sink|Source}Metadata types are defined in 'common' (since V5), so they can be used + // by the BT HAL. However, the converters are defined here, not in HidlUtils to avoid adding + // conditionals to handle V4. The converters are only used by 'core' HAL anyways. + static status_t sinkMetadataFromHal(const std::vector<record_track_metadata_t>& halTracks, + SinkMetadata* sinkMetadata); + static status_t sinkMetadataFromHalV7(const std::vector<record_track_metadata_v7_t>& halTracks, + bool ignoreNonVendorTags, SinkMetadata* sinkMetadata); + static status_t sinkMetadataToHal(const SinkMetadata& sinkMetadata, + std::vector<record_track_metadata_t>* halTracks); + static status_t sinkMetadataToHalV7(const SinkMetadata& sinkMetadata, bool ignoreNonVendorTags, + std::vector<record_track_metadata_v7_t>* halTracks); + static status_t sourceMetadataFromHal(const std::vector<playback_track_metadata_t>& halTracks, + SourceMetadata* sourceMetadata); + static status_t sourceMetadataFromHalV7(const std::vector<playback_track_metadata_v7_t>& halTracks, + bool ignoreNonVendorTags, SourceMetadata* sourceMetadata); + static status_t sourceMetadataToHal(const SourceMetadata& sourceMetadata, + std::vector<playback_track_metadata_t>* halTracks); + static status_t sourceMetadataToHalV7(const SourceMetadata& sourceMetadata, bool ignoreNonVendorTags, + std::vector<playback_track_metadata_v7_t>* halTracks); +#endif + +#if MAJOR_VERSION <= 6 + using AudioInputFlags = + ::android::hardware::audio::common::CPP_VERSION::implementation::AudioInputFlagBitfield; + using AudioOutputFlags = + ::android::hardware::audio::common::CPP_VERSION::implementation::AudioOutputFlagBitfield; + static inline status_t audioInputFlagsFromHal(audio_input_flags_t halFlagMask, AudioInputFlags* flags) { + *flags = EnumBitfield<AudioInputFlag>(halFlagMask); + return NO_ERROR; + } + static inline status_t audioInputFlagsToHal(AudioInputFlags flags, audio_input_flags_t* halFlagMask) { + *halFlagMask = static_cast<audio_input_flags_t>(flags); + return NO_ERROR; + } + static inline status_t audioOutputFlagsFromHal(audio_output_flags_t halFlagMask, AudioOutputFlags* flags) { + *flags = EnumBitfield<AudioOutputFlag>(halFlagMask); + return NO_ERROR; + } + static inline status_t audioOutputFlagsToHal(AudioOutputFlags flags, audio_output_flags_t* halFlagMask) { + *halFlagMask = static_cast<audio_output_flags_t>(flags); + return NO_ERROR; + } +#else + using AudioInputFlags = hidl_vec<::android::hardware::audio::CPP_VERSION::AudioInOutFlag>; + using AudioOutputFlags = hidl_vec<::android::hardware::audio::CPP_VERSION::AudioInOutFlag>; + static status_t audioInputFlagsFromHal(audio_input_flags_t halFlagMask, AudioInputFlags* flags); + static status_t audioInputFlagsToHal(const AudioInputFlags& flags, audio_input_flags_t* halFlagMask); + static status_t audioOutputFlagsFromHal(audio_output_flags_t halFlagMask, AudioOutputFlags* flags); + static status_t audioOutputFlagsToHal(const AudioOutputFlags& flags, audio_output_flags_t* halFlagMask); +#endif + +}; + +} // namespace implementation +} // namespace CPP_VERSION +} // namespace audio +} // namespace hardware +} // namespace android diff --git a/audio/core/all-versions/default/util/tests/coreutils_tests.cpp b/audio/core/all-versions/default/util/tests/coreutils_tests.cpp new file mode 100644 index 0000000000..0c18482632 --- /dev/null +++ b/audio/core/all-versions/default/util/tests/coreutils_tests.cpp @@ -0,0 +1,525 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <string> +#include <vector> + +#include <gtest/gtest.h> + +#define LOG_TAG "CoreUtils_Test" +#include <log/log.h> + +#include <android_audio_policy_configuration_V7_0-enums.h> +#include <system/audio.h> +#include <util/CoreUtils.h> +#include <xsdc/XsdcSupport.h> + +using namespace android; +using namespace ::android::hardware::audio::common::CPP_VERSION; +using namespace ::android::hardware::audio::CPP_VERSION; +using ::android::hardware::hidl_vec; +using ::android::hardware::audio::CPP_VERSION::implementation::CoreUtils; +namespace xsd { +using namespace ::android::audio::policy::configuration::V7_0; +} + +static constexpr audio_channel_mask_t kInvalidHalChannelMask = AUDIO_CHANNEL_INVALID; +static constexpr audio_content_type_t kInvalidHalContentType = + static_cast<audio_content_type_t>(0xFFFFFFFFU); +static constexpr audio_devices_t kInvalidHalDevice = static_cast<audio_devices_t>(0xFFFFFFFFU); +static constexpr audio_input_flags_t kInvalidInputFlags = + static_cast<audio_input_flags_t>(0xFFFFFFFFU); +static constexpr audio_output_flags_t kInvalidOutputFlags = + static_cast<audio_output_flags_t>(0xFFFFFFFFU); +// AUDIO_SOURCE_INVALID is framework-only. +static constexpr audio_source_t kInvalidHalSource = static_cast<audio_source_t>(-1); +static constexpr audio_usage_t kInvalidHalUsage = static_cast<audio_usage_t>(0xFFFFFFFFU); + +static bool isInputFlag(xsd::AudioInOutFlag flag) { + return toString(flag).find("_INPUT_FLAG_") != std::string::npos; +} + +static bool isOutputFlag(xsd::AudioInOutFlag flag) { + return toString(flag).find("_OUTPUT_FLAG_") != std::string::npos; +} + +TEST(CoreUtils, ConvertInvalidInputFlagMask) { + CoreUtils::AudioInputFlags invalid; + EXPECT_EQ(BAD_VALUE, CoreUtils::audioInputFlagsFromHal(kInvalidInputFlags, &invalid)); + audio_input_flags_t halInvalid; + invalid.resize(1); + invalid[0] = "random string"; + EXPECT_EQ(BAD_VALUE, CoreUtils::audioInputFlagsToHal(invalid, &halInvalid)); +} + +TEST(CoreUtils, ConvertInputFlagMask) { + CoreUtils::AudioInputFlags emptyInputFlags; + audio_input_flags_t halEmptyInputFlags; + EXPECT_EQ(NO_ERROR, CoreUtils::audioInputFlagsToHal(emptyInputFlags, &halEmptyInputFlags)); + EXPECT_EQ(AUDIO_INPUT_FLAG_NONE, halEmptyInputFlags); + CoreUtils::AudioInputFlags emptyInputFlagsBack; + EXPECT_EQ(NO_ERROR, + CoreUtils::audioInputFlagsFromHal(halEmptyInputFlags, &emptyInputFlagsBack)); + EXPECT_EQ(emptyInputFlags, emptyInputFlagsBack); + CoreUtils::AudioInputFlags emptyInputFlagsFromNone; + EXPECT_EQ(NO_ERROR, + CoreUtils::audioInputFlagsFromHal(AUDIO_INPUT_FLAG_NONE, &emptyInputFlagsFromNone)); + EXPECT_EQ(emptyInputFlags, emptyInputFlagsFromNone); + + std::vector<std::string> allEnumValues; + for (const auto enumVal : xsdc_enum_range<xsd::AudioInOutFlag>{}) { + if (isInputFlag(enumVal)) { + allEnumValues.push_back(toString(enumVal)); + } + } + CoreUtils::AudioInputFlags allInputFlags; + allInputFlags.resize(allEnumValues.size()); + for (size_t i = 0; i < allEnumValues.size(); ++i) { + allInputFlags[i] = allEnumValues[i]; + } + audio_input_flags_t halAllInputFlags; + EXPECT_EQ(NO_ERROR, CoreUtils::audioInputFlagsToHal(allInputFlags, &halAllInputFlags)); + CoreUtils::AudioInputFlags allInputFlagsBack; + EXPECT_EQ(NO_ERROR, CoreUtils::audioInputFlagsFromHal(halAllInputFlags, &allInputFlagsBack)); + EXPECT_EQ(allInputFlags, allInputFlagsBack); +} + +TEST(CoreUtils, ConvertInvalidOutputFlagMask) { + CoreUtils::AudioOutputFlags invalid; + EXPECT_EQ(BAD_VALUE, CoreUtils::audioOutputFlagsFromHal(kInvalidOutputFlags, &invalid)); + audio_output_flags_t halInvalid; + invalid.resize(1); + invalid[0] = "random string"; + EXPECT_EQ(BAD_VALUE, CoreUtils::audioOutputFlagsToHal(invalid, &halInvalid)); +} + +TEST(CoreUtils, ConvertOutputFlagMask) { + CoreUtils::AudioOutputFlags emptyOutputFlags; + audio_output_flags_t halEmptyOutputFlags; + EXPECT_EQ(NO_ERROR, CoreUtils::audioOutputFlagsToHal(emptyOutputFlags, &halEmptyOutputFlags)); + EXPECT_EQ(AUDIO_OUTPUT_FLAG_NONE, halEmptyOutputFlags); + CoreUtils::AudioOutputFlags emptyOutputFlagsBack; + EXPECT_EQ(NO_ERROR, + CoreUtils::audioOutputFlagsFromHal(halEmptyOutputFlags, &emptyOutputFlagsBack)); + EXPECT_EQ(emptyOutputFlags, emptyOutputFlagsBack); + CoreUtils::AudioOutputFlags emptyOutputFlagsFromNone; + EXPECT_EQ(NO_ERROR, CoreUtils::audioOutputFlagsFromHal(AUDIO_OUTPUT_FLAG_NONE, + &emptyOutputFlagsFromNone)); + EXPECT_EQ(emptyOutputFlags, emptyOutputFlagsFromNone); + + std::vector<std::string> allEnumValues; + for (const auto enumVal : xsdc_enum_range<xsd::AudioInOutFlag>{}) { + if (isOutputFlag(enumVal)) { + allEnumValues.push_back(toString(enumVal)); + } + } + CoreUtils::AudioOutputFlags allOutputFlags; + allOutputFlags.resize(allEnumValues.size()); + for (size_t i = 0; i < allEnumValues.size(); ++i) { + allOutputFlags[i] = allEnumValues[i]; + } + audio_output_flags_t halAllOutputFlags; + EXPECT_EQ(NO_ERROR, CoreUtils::audioOutputFlagsToHal(allOutputFlags, &halAllOutputFlags)); + CoreUtils::AudioOutputFlags allOutputFlagsBack; + EXPECT_EQ(NO_ERROR, CoreUtils::audioOutputFlagsFromHal(halAllOutputFlags, &allOutputFlagsBack)); + EXPECT_EQ(allOutputFlags, allOutputFlagsBack); +} + +static MicrophoneInfo generateValidMicrophoneInfo() { + MicrophoneInfo micInfo{}; + micInfo.deviceAddress.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_IN_BUILTIN_MIC); + micInfo.channelMapping.resize(1); + micInfo.channelMapping[0] = AudioMicrophoneChannelMapping::DIRECT; + micInfo.location = AudioMicrophoneLocation::MAINBODY_MOVABLE; + micInfo.group = 42; + micInfo.indexInTheGroup = 13; + micInfo.sensitivity = 65.5; + micInfo.maxSpl = 100.5; + micInfo.minSpl = 36.6; + micInfo.directionality = AudioMicrophoneDirectionality::HYPER_CARDIOID; + micInfo.frequencyResponse.resize(1); + micInfo.frequencyResponse[0].frequency = 1000; + micInfo.frequencyResponse[0].level = 85; + micInfo.position.x = 0; + micInfo.position.y = 1; + micInfo.position.z = 0; + micInfo.orientation.x = 0; + micInfo.orientation.y = 0; + micInfo.orientation.z = 1; + return micInfo; +} + +TEST(CoreUtils, ConvertInvalidMicrophoneInfo) { + MicrophoneInfo invalid; + audio_microphone_characteristic_t halInvalid{}; + halInvalid.device = kInvalidHalDevice; + EXPECT_EQ(BAD_VALUE, CoreUtils::microphoneInfoFromHal(halInvalid, &invalid)); + + MicrophoneInfo oversizeDeviceId = generateValidMicrophoneInfo(); + oversizeDeviceId.deviceId = std::string(AUDIO_MICROPHONE_ID_MAX_LEN + 1, 'A'); + EXPECT_EQ(BAD_VALUE, CoreUtils::microphoneInfoToHal(oversizeDeviceId, &halInvalid)); + MicrophoneInfo invalidDeviceType = generateValidMicrophoneInfo(); + invalidDeviceType.deviceAddress.deviceType = "random string"; + EXPECT_EQ(BAD_VALUE, CoreUtils::microphoneInfoToHal(invalidDeviceType, &halInvalid)); + MicrophoneInfo oversizeChannelMapping = generateValidMicrophoneInfo(); + oversizeChannelMapping.channelMapping.resize(AUDIO_CHANNEL_COUNT_MAX + 1); + EXPECT_EQ(BAD_VALUE, CoreUtils::microphoneInfoToHal(oversizeChannelMapping, &halInvalid)); + MicrophoneInfo oversizeFrequencyResponses = generateValidMicrophoneInfo(); + oversizeFrequencyResponses.frequencyResponse.resize(AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES + + 1); + EXPECT_EQ(BAD_VALUE, CoreUtils::microphoneInfoToHal(oversizeFrequencyResponses, &halInvalid)); +} + +TEST(CoreUtils, ConvertMicrophoneInfo) { + MicrophoneInfo micInfo = generateValidMicrophoneInfo(); + audio_microphone_characteristic_t halMicInfo; + EXPECT_EQ(NO_ERROR, CoreUtils::microphoneInfoToHal(micInfo, &halMicInfo)); + MicrophoneInfo micInfoBack; + EXPECT_EQ(NO_ERROR, CoreUtils::microphoneInfoFromHal(halMicInfo, &micInfoBack)); + EXPECT_EQ(micInfo, micInfoBack); +} + +static RecordTrackMetadata generateMinimalRecordTrackMetadata() { + RecordTrackMetadata metadata{}; + metadata.source = toString(xsd::AudioSource::AUDIO_SOURCE_DEFAULT); + metadata.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_NONE); + return metadata; +} + +static RecordTrackMetadata generateValidRecordTrackMetadata() { + RecordTrackMetadata metadata = generateMinimalRecordTrackMetadata(); + metadata.tags.resize(1); + metadata.tags[0] = "VX_GOOGLE_42"; + metadata.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_IN_MONO); + metadata.gain = 1.0; + return metadata; +} + +static RecordTrackMetadata generateValidRecordTrackMetadataWithDevice() { + RecordTrackMetadata metadata = generateValidRecordTrackMetadata(); + metadata.destination.device({}); + metadata.destination.device().deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_SPEAKER); + return metadata; +} + +using SinkTracks = hidl_vec<RecordTrackMetadata>; + +TEST(CoreUtils, ConvertInvalidSinkMetadata) { + SinkMetadata invalidSource; + invalidSource.tracks = SinkTracks{generateMinimalRecordTrackMetadata()}; + invalidSource.tracks[0].source = "random string"; + EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataToHal(invalidSource, nullptr)); + EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataToHalV7(invalidSource, + false /*ignoreNonVendorTags*/, nullptr)); + EXPECT_EQ(BAD_VALUE, + CoreUtils::sinkMetadataToHalV7(invalidSource, true /*ignoreNonVendorTags*/, nullptr)); + SinkMetadata invalidDeviceType; + invalidDeviceType.tracks = SinkTracks{generateValidRecordTrackMetadataWithDevice()}; + invalidDeviceType.tracks[0].destination.device().deviceType = "random string"; + EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataToHal(invalidDeviceType, nullptr)); + EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataToHalV7(invalidDeviceType, + false /*ignoreNonVendorTags*/, nullptr)); + EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataToHalV7(invalidDeviceType, + true /*ignoreNonVendorTags*/, nullptr)); + SinkMetadata invalidChannelMask; + invalidChannelMask.tracks = SinkTracks{generateValidRecordTrackMetadata()}; + invalidChannelMask.tracks[0].channelMask = "random string"; + // Channel mask is sliced away by 'sinkMetadataToHal' + EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataToHal(invalidChannelMask, nullptr)); + EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataToHalV7(invalidChannelMask, + false /*ignoreNonVendorTags*/, nullptr)); + EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataToHalV7(invalidChannelMask, + true /*ignoreNonVendorTags*/, nullptr)); + SinkMetadata invalidTags; + invalidTags.tracks = SinkTracks{generateValidRecordTrackMetadata()}; + invalidTags.tracks[0].tags[0] = "random string"; + // Tags are sliced away by 'sinkMetadataToHal' + EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataToHal(invalidTags, nullptr)); + EXPECT_EQ(BAD_VALUE, + CoreUtils::sinkMetadataToHalV7(invalidTags, false /*ignoreNonVendorTags*/, nullptr)); + // Non-vendor tags should be filtered out. + EXPECT_EQ(NO_ERROR, + CoreUtils::sinkMetadataToHalV7(invalidTags, true /*ignoreNonVendorTags*/, nullptr)); + + // Verify that a default-initialized metadata is valid. + std::vector<record_track_metadata_t> halValid(1, record_track_metadata_t{}); + std::vector<record_track_metadata_v7_t> halValidV7(1, record_track_metadata_v7_t{}); + SinkMetadata valid; + EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataFromHal(halValid, &valid)); + EXPECT_EQ(NO_ERROR, + CoreUtils::sinkMetadataFromHalV7(halValidV7, false /*ignoreNonVendorTags*/, &valid)); + EXPECT_EQ(NO_ERROR, + CoreUtils::sinkMetadataFromHalV7(halValidV7, true /*ignoreNonVendorTags*/, &valid)); + + std::vector<record_track_metadata_t> halInvalidSource = {{.source = kInvalidHalSource}}; + std::vector<record_track_metadata_v7_t> halInvalidSourceV7 = { + {.base = {.source = kInvalidHalSource}}}; + EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataFromHal(halInvalidSource, &invalidSource)); + EXPECT_EQ(BAD_VALUE, + CoreUtils::sinkMetadataFromHalV7(halInvalidSourceV7, false /*ignoreNonVendorTags*/, + &invalidSource)); + EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataFromHalV7( + halInvalidSourceV7, true /*ignoreNonVendorTags*/, &invalidSource)); + std::vector<record_track_metadata_t> halInvalidDeviceType = { + {.dest_device = kInvalidHalDevice}}; + std::vector<record_track_metadata_v7_t> halInvalidDeviceTypeV7 = { + {.base = {.dest_device = kInvalidHalDevice}}}; + EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataFromHal(halInvalidDeviceType, &invalidDeviceType)); + EXPECT_EQ(BAD_VALUE, + CoreUtils::sinkMetadataFromHalV7(halInvalidDeviceTypeV7, + false /*ignoreNonVendorTags*/, &invalidDeviceType)); + EXPECT_EQ(BAD_VALUE, + CoreUtils::sinkMetadataFromHalV7(halInvalidDeviceTypeV7, true /*ignoreNonVendorTags*/, + &invalidDeviceType)); + std::vector<record_track_metadata_v7_t> halInvalidChannelMaskV7 = { + {.channel_mask = kInvalidHalChannelMask}}; + EXPECT_EQ(BAD_VALUE, + CoreUtils::sinkMetadataFromHalV7(halInvalidChannelMaskV7, + false /*ignoreNonVendorTags*/, &invalidChannelMask)); + EXPECT_EQ(BAD_VALUE, + CoreUtils::sinkMetadataFromHalV7(halInvalidChannelMaskV7, + true /*ignoreNonVendorTags*/, &invalidChannelMask)); + std::vector<record_track_metadata_v7_t> halInvalidTagsV7 = {{.tags = "random string"}}; + EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataFromHalV7( + halInvalidTagsV7, false /*ignoreNonVendorTags*/, &invalidTags)); + // Non-vendor tags should be filtered out. + EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataFromHalV7( + halInvalidTagsV7, true /*ignoreNonVendorTags*/, &invalidTags)); +} + +TEST(CoreUtils, ConvertEmptySinkMetadata) { + SinkMetadata emptySinkMetadata; + std::vector<record_track_metadata_t> halEmptySinkMetadata; + EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataToHal(emptySinkMetadata, &halEmptySinkMetadata)); + EXPECT_TRUE(halEmptySinkMetadata.empty()); + SinkMetadata emptySinkMetadataBack; + EXPECT_EQ(NO_ERROR, + CoreUtils::sinkMetadataFromHal(halEmptySinkMetadata, &emptySinkMetadataBack)); + EXPECT_EQ(emptySinkMetadata, emptySinkMetadataBack); + std::vector<record_track_metadata_v7_t> halEmptySinkMetadataV7; + EXPECT_EQ(NO_ERROR, + CoreUtils::sinkMetadataToHalV7(emptySinkMetadata, false /*ignoreNonVendorTags*/, + &halEmptySinkMetadataV7)); + EXPECT_TRUE(halEmptySinkMetadataV7.empty()); + SinkMetadata emptySinkMetadataBackFromV7; + EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataFromHalV7(halEmptySinkMetadataV7, + false /*ignoreNonVendorTags*/, + &emptySinkMetadataBackFromV7)); + EXPECT_EQ(emptySinkMetadata, emptySinkMetadataBackFromV7); +} + +class SinkMetadataConvertTest : public ::testing::TestWithParam<SinkTracks> {}; + +TEST_P(SinkMetadataConvertTest, ToFromHal) { + SinkMetadata sinkMetadata; + sinkMetadata.tracks = GetParam(); + std::vector<record_track_metadata_t> halSinkMetadata; + EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataToHal(sinkMetadata, &halSinkMetadata)); + EXPECT_EQ(sinkMetadata.tracks.size(), halSinkMetadata.size()); + SinkMetadata sinkMetadataBackTrimmed; + EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataFromHal(halSinkMetadata, &sinkMetadataBackTrimmed)); + // Can't compare 'sinkMetadata' to 'sinkMetadataBackTrimmed' + std::vector<record_track_metadata_v7_t> halSinkMetadataV7; + EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataToHalV7(sinkMetadata, false /*ignoreNonVendorTags*/, + &halSinkMetadataV7)); + EXPECT_EQ(sinkMetadata.tracks.size(), halSinkMetadataV7.size()); + SinkMetadata sinkMetadataBackFromV7; + EXPECT_EQ(NO_ERROR, + CoreUtils::sinkMetadataFromHalV7(halSinkMetadataV7, false /*ignoreNonVendorTags*/, + &sinkMetadataBackFromV7)); + EXPECT_EQ(sinkMetadata, sinkMetadataBackFromV7); + std::vector<record_track_metadata_v7_t> halSinkMetadataV7FromTrimmed; + EXPECT_EQ(NO_ERROR, + CoreUtils::sinkMetadataToHalV7(sinkMetadataBackTrimmed, false /*ignoreNonVendorTags*/, + &halSinkMetadataV7FromTrimmed)); + EXPECT_EQ(sinkMetadata.tracks.size(), halSinkMetadataV7FromTrimmed.size()); + SinkMetadata sinkMetadataBackFromV7Trimmed; + EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataFromHalV7(halSinkMetadataV7FromTrimmed, + false /*ignoreNonVendorTags*/, + &sinkMetadataBackFromV7Trimmed)); + EXPECT_EQ(sinkMetadataBackTrimmed, sinkMetadataBackFromV7Trimmed); +} + +INSTANTIATE_TEST_SUITE_P(ValidRecordTrackMetadatas, SinkMetadataConvertTest, + ::testing::Values(SinkTracks{generateMinimalRecordTrackMetadata()}, + SinkTracks{generateValidRecordTrackMetadata()}, + SinkTracks{generateValidRecordTrackMetadataWithDevice()}, + SinkTracks{ + generateMinimalRecordTrackMetadata(), + generateValidRecordTrackMetadata(), + generateValidRecordTrackMetadataWithDevice()})); + +static PlaybackTrackMetadata generateMinimalPlaybackTrackMetadata() { + PlaybackTrackMetadata metadata{}; + metadata.usage = toString(xsd::AudioUsage::AUDIO_USAGE_UNKNOWN); + metadata.contentType = toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_UNKNOWN); + metadata.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_NONE); + return metadata; +} + +static PlaybackTrackMetadata generateValidPlaybackTrackMetadata() { + PlaybackTrackMetadata metadata = generateMinimalPlaybackTrackMetadata(); + metadata.tags.resize(1); + metadata.tags[0] = "VX_GOOGLE_42"; + metadata.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_MONO); + metadata.gain = 1.0; + return metadata; +} + +using SourceTracks = hidl_vec<PlaybackTrackMetadata>; + +TEST(CoreUtils, ConvertInvalidSourceMetadata) { + SourceMetadata invalidUsage; + invalidUsage.tracks = SourceTracks{generateMinimalPlaybackTrackMetadata()}; + invalidUsage.tracks[0].usage = "random string"; + EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataToHal(invalidUsage, nullptr)); + EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataToHalV7(invalidUsage, + false /*ignoreNonVendorTags*/, nullptr)); + SourceMetadata invalidContentType; + invalidContentType.tracks = SourceTracks{generateMinimalPlaybackTrackMetadata()}; + invalidContentType.tracks[0].contentType = "random string"; + EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataToHal(invalidContentType, nullptr)); + EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataToHalV7(invalidContentType, + false /*ignoreNonVendorTags*/, nullptr)); + EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataToHalV7(invalidContentType, + true /*ignoreNonVendorTags*/, nullptr)); + SourceMetadata invalidChannelMask; + invalidChannelMask.tracks = SourceTracks{generateValidPlaybackTrackMetadata()}; + invalidChannelMask.tracks[0].channelMask = "random string"; + // Channel mask is sliced away by 'sourceMetadataToHal' + EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataToHal(invalidChannelMask, nullptr)); + EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataToHalV7(invalidChannelMask, + false /*ignoreNonVendorTags*/, nullptr)); + EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataToHalV7(invalidChannelMask, + true /*ignoreNonVendorTags*/, nullptr)); + SourceMetadata invalidTags; + invalidTags.tracks = SourceTracks{generateValidPlaybackTrackMetadata()}; + invalidTags.tracks[0].tags[0] = "random string"; + // Tags are sliced away by 'sourceMetadataToHal' + EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataToHal(invalidTags, nullptr)); + EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataToHalV7(invalidTags, + false /*ignoreNonVendorTags*/, nullptr)); + // Non-vendor tags should be filtered out. + EXPECT_EQ(NO_ERROR, + CoreUtils::sourceMetadataToHalV7(invalidTags, true /*ignoreNonVendorTags*/, nullptr)); + + // Verify that a default-initialized metadata is valid. + std::vector<playback_track_metadata_t> halValid(1, playback_track_metadata_t{}); + std::vector<playback_track_metadata_v7_t> halValidV7(1, playback_track_metadata_v7_t{}); + SourceMetadata valid; + EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataFromHal(halValid, &valid)); + EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataFromHalV7(halValidV7, + false /*ignoreNonVendorTags*/, &valid)); + EXPECT_EQ(NO_ERROR, + CoreUtils::sourceMetadataFromHalV7(halValidV7, true /*ignoreNonVendorTags*/, &valid)); + + std::vector<playback_track_metadata_t> halInvalidUsage = {{.usage = kInvalidHalUsage}}; + std::vector<playback_track_metadata_v7_t> halInvalidUsageV7 = { + {.base = {.usage = kInvalidHalUsage}}}; + EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataFromHal(halInvalidUsage, &invalidUsage)); + EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataFromHalV7( + halInvalidUsageV7, false /*ignoreNonVendorTags*/, &invalidUsage)); + EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataFromHalV7( + halInvalidUsageV7, true /*ignoreNonVendorTags*/, &invalidUsage)); + std::vector<playback_track_metadata_t> halInvalidContentType = { + {.content_type = kInvalidHalContentType}}; + std::vector<playback_track_metadata_v7_t> halInvalidContentTypeV7 = { + {.base = {.content_type = kInvalidHalContentType}}}; + EXPECT_EQ(BAD_VALUE, + CoreUtils::sourceMetadataFromHal(halInvalidContentType, &invalidContentType)); + EXPECT_EQ(BAD_VALUE, + CoreUtils::sourceMetadataFromHalV7( + halInvalidContentTypeV7, false /*ignoreNonVendorTags*/, &invalidContentType)); + EXPECT_EQ(BAD_VALUE, + CoreUtils::sourceMetadataFromHalV7( + halInvalidContentTypeV7, true /*ignoreNonVendorTags*/, &invalidContentType)); + std::vector<playback_track_metadata_v7_t> halInvalidChannelMaskV7 = { + {.channel_mask = kInvalidHalChannelMask}}; + EXPECT_EQ(BAD_VALUE, + CoreUtils::sourceMetadataFromHalV7( + halInvalidChannelMaskV7, false /*ignoreNonVendorTags*/, &invalidChannelMask)); + EXPECT_EQ(BAD_VALUE, + CoreUtils::sourceMetadataFromHalV7( + halInvalidChannelMaskV7, true /*ignoreNonVendorTags*/, &invalidChannelMask)); + std::vector<playback_track_metadata_v7_t> halInvalidTagsV7 = {{.tags = "random string"}}; + EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataFromHalV7( + halInvalidTagsV7, false /*ignoreNonVendorTags*/, &invalidTags)); + // Non-vendor tags should be filtered out. + EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataFromHalV7( + halInvalidTagsV7, true /*ignoreNonVendorTags*/, &invalidTags)); +} + +TEST(CoreUtils, ConvertEmptySourceMetadata) { + SourceMetadata emptySourceMetadata; + std::vector<playback_track_metadata_t> halEmptySourceMetadata; + EXPECT_EQ(NO_ERROR, + CoreUtils::sourceMetadataToHal(emptySourceMetadata, &halEmptySourceMetadata)); + EXPECT_TRUE(halEmptySourceMetadata.empty()); + SourceMetadata emptySourceMetadataBack; + EXPECT_EQ(NO_ERROR, + CoreUtils::sourceMetadataFromHal(halEmptySourceMetadata, &emptySourceMetadataBack)); + EXPECT_EQ(emptySourceMetadata, emptySourceMetadataBack); + std::vector<playback_track_metadata_v7_t> halEmptySourceMetadataV7; + EXPECT_EQ(NO_ERROR, + CoreUtils::sourceMetadataToHalV7(emptySourceMetadata, false /*ignoreNonVendorTags*/, + &halEmptySourceMetadataV7)); + EXPECT_TRUE(halEmptySourceMetadataV7.empty()); + SourceMetadata emptySourceMetadataBackFromV7; + EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataFromHalV7(halEmptySourceMetadataV7, + false /*ignoreNonVendorTags*/, + &emptySourceMetadataBackFromV7)); + EXPECT_EQ(emptySourceMetadata, emptySourceMetadataBackFromV7); +} + +class SourceMetadataConvertTest : public ::testing::TestWithParam<SourceTracks> {}; + +TEST_P(SourceMetadataConvertTest, ToFromHal) { + SourceMetadata sourceMetadata; + sourceMetadata.tracks = GetParam(); + std::vector<playback_track_metadata_t> halSourceMetadata; + EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataToHal(sourceMetadata, &halSourceMetadata)); + EXPECT_EQ(sourceMetadata.tracks.size(), halSourceMetadata.size()); + SourceMetadata sourceMetadataBackTrimmed; + EXPECT_EQ(NO_ERROR, + CoreUtils::sourceMetadataFromHal(halSourceMetadata, &sourceMetadataBackTrimmed)); + // Can't compare 'sourceMetadata' to 'sourceMetadataBackTrimmed' + std::vector<playback_track_metadata_v7_t> halSourceMetadataV7; + EXPECT_EQ(NO_ERROR, + CoreUtils::sourceMetadataToHalV7(sourceMetadata, false /*ignoreNonVendorTags*/, + &halSourceMetadataV7)); + EXPECT_EQ(sourceMetadata.tracks.size(), halSourceMetadataV7.size()); + SourceMetadata sourceMetadataBackFromV7; + EXPECT_EQ(NO_ERROR, + CoreUtils::sourceMetadataFromHalV7(halSourceMetadataV7, false /*ignoreNonVendorTags*/, + &sourceMetadataBackFromV7)); + EXPECT_EQ(sourceMetadata, sourceMetadataBackFromV7); + std::vector<playback_track_metadata_v7_t> halSourceMetadataV7FromTrimmed; + EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataToHalV7(sourceMetadataBackTrimmed, + false /*ignoreNonVendorTags*/, + &halSourceMetadataV7FromTrimmed)); + EXPECT_EQ(sourceMetadata.tracks.size(), halSourceMetadataV7FromTrimmed.size()); + SourceMetadata sourceMetadataBackFromV7Trimmed; + EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataFromHalV7(halSourceMetadataV7FromTrimmed, + false /*ignoreNonVendorTags*/, + &sourceMetadataBackFromV7Trimmed)); + EXPECT_EQ(sourceMetadataBackTrimmed, sourceMetadataBackFromV7Trimmed); +} + +INSTANTIATE_TEST_SUITE_P(ValidPlaybackTrackMetadatas, SourceMetadataConvertTest, + ::testing::Values(SourceTracks{generateMinimalPlaybackTrackMetadata()}, + SourceTracks{generateValidPlaybackTrackMetadata()}, + SourceTracks{generateMinimalPlaybackTrackMetadata(), + generateValidPlaybackTrackMetadata()})); 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 5076dcfdb0..bb7c6d3d3e 100644 --- a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp +++ b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp @@ -336,24 +336,24 @@ TEST_P(OutputStreamTest, updateSourceMetadata) { ASSERT_RESULT(okOrNotSupported, stream->updateSourceMetadata( {{{toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA), toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_MUSIC), - {}, + 0.1, // gain toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO), - 0.1}, + {}}, // tags {toString(xsd::AudioUsage::AUDIO_USAGE_VOICE_COMMUNICATION), toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_SPEECH), - {}, // tags + 1.0, toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_MONO), - 1.0}, + {}}, {toString(xsd::AudioUsage::AUDIO_USAGE_ALARM), toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_SONIFICATION), - {}, // tags + 0.0, toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO), - 0.0}, + {}}, {toString(xsd::AudioUsage::AUDIO_USAGE_ASSISTANT), toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_UNKNOWN), - {}, + 0.3, toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_MONO), - 0.3}}} + {}}}} )); // clang-format on // Set no metadata as if all stream track had stopped 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 7fca61036d..be1ffbbcfe 100644 --- a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp +++ b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp @@ -367,10 +367,10 @@ static std::vector<AudioPortConfig>& generatePortConfigs(bool valid) { static std::vector<AudioPortConfig> invalids = [&] { std::vector<AudioPortConfig> result; AudioPortConfig invalidBaseChannelMask = valids[PORT_CONF_MINIMAL]; - invalidBaseChannelMask.base.channelMask = "random_string"; + invalidBaseChannelMask.base.channelMask.value("random_string"); result.push_back(std::move(invalidBaseChannelMask)); AudioPortConfig invalidBaseFormat = valids[PORT_CONF_MINIMAL]; - invalidBaseFormat.base.format = "random_string"; + invalidBaseFormat.base.format.value("random_string"); result.push_back(std::move(invalidBaseFormat)); AudioPortConfig invalidGainMode = valids[PORT_CONF_WITH_GAIN]; invalidGainMode.gain.config().mode = {{"random_string"}}; @@ -724,19 +724,19 @@ TEST_SINGLE_CONFIG_IO_STREAM( areAudioPatchesSupported() ? doc::partialTest("Audio patches are supported") : testSetDevicesInvalidDeviceAddress(stream.get())); -static void testSetAudioPropertiesInvalidArguments(IStream* stream, const AudioConfigBase& base) { - AudioConfigBase invalidFormat = base; - invalidFormat.format = "random_string"; +static void testSetAudioPropertiesInvalidArguments(IStream* stream) { + AudioConfigBaseOptional invalidFormat; + invalidFormat.format.value("random_string"); ASSERT_RESULT(invalidArgsOrNotSupported, stream->setAudioProperties(invalidFormat)); - AudioConfigBase invalidChannelMask = base; - invalidChannelMask.channelMask = "random_string"; + AudioConfigBaseOptional invalidChannelMask; + invalidChannelMask.channelMask.value("random_string"); ASSERT_RESULT(invalidArgsOrNotSupported, stream->setAudioProperties(invalidChannelMask)); } TEST_SINGLE_CONFIG_IO_STREAM( SetAudioPropertiesInvalidArguments, "Verify that invalid arguments are rejected by IStream::setAudioProperties", - testSetAudioPropertiesInvalidArguments(stream.get(), audioConfig.base)); + testSetAudioPropertiesInvalidArguments(stream.get())); TEST_P(SingleConfigOutputStreamTest, UpdateInvalidSourceMetadata) { doc::test("Verify that invalid metadata is rejected by IStreamOut::updateSourceMetadata"); diff --git a/audio/core/all-versions/vts/functional/Android.bp b/audio/core/all-versions/vts/functional/Android.bp index a809a92558..e8b704ca22 100644 --- a/audio/core/all-versions/vts/functional/Android.bp +++ b/audio/core/all-versions/vts/functional/Android.bp @@ -19,13 +19,13 @@ cc_defaults { defaults: ["VtsHalTargetTestDefaults"], static_libs: [ "android.hardware.audio.common.test.utility", - "libxml2", + "audioclient-types-aidl-cpp", + "libaudioclient_aidl_conversion", ], shared_libs: [ - "audioclient-types-aidl-unstable-cpp", - "libaudioclient_aidl_conversion", "libbinder", "libfmq", + "libxml2", ], header_libs: [ "android.hardware.audio.common.util@all-versions", diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h index f145b606de..61e99e8699 100644 --- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h +++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h @@ -928,9 +928,9 @@ class OutputStreamTest : public OpenStreamTest<IStreamOut> { const SourceMetadata initMetadata = { { { toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA), toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_MUSIC), - {}, + 1 /* gain */, toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO), - 1 /* gain */ } }}; + {} } }}; #endif }; TEST_P(OutputStreamTest, OpenOutputStreamTest) { @@ -1155,13 +1155,14 @@ static void testSetAudioProperties(IStream* stream) { 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}}}; + AudioConfigBaseOptional config; + config.format.value(profile.format); + config.sampleRateHz.value(sampleRate); + config.channelMask.value(channelMask); auto ret = stream->setAudioProperties(config); EXPECT_TRUE(ret.isOk()); - EXPECT_EQ(Result::OK, ret) << config.format << "; " << config.sampleRateHz << "; " - << toString(config.channelMask); + EXPECT_EQ(Result::OK, ret) + << profile.format << "; " << sampleRate << "; " << channelMask; } } } @@ -1169,7 +1170,7 @@ static void testSetAudioProperties(IStream* stream) { TEST_IO_STREAM(SetAudioProperties, "Call setAudioProperties for all supported profiles", testSetAudioProperties(stream.get())) -#endif +#endif // MAJOR_VERSION <= 6 static void testGetAudioProperties(IStream* stream, AudioConfig expectedConfig) { #if MAJOR_VERSION <= 6 diff --git a/audio/effect/7.0/types.hal b/audio/effect/7.0/types.hal index c4cb213a86..bb2d7b3d06 100644 --- a/audio/effect/7.0/types.hal +++ b/audio/effect/7.0/types.hal @@ -17,6 +17,7 @@ package android.hardware.audio.effect@7.0; import android.hardware.audio.common@7.0; +import android.hidl.safe_union@1.0; enum Result : int32_t { OK, @@ -248,32 +249,19 @@ enum EffectBufferAccess : int32_t { }; /** - * Determines what fields of EffectBufferConfig need to be considered. - */ -@export(name="", value_prefix="EFFECT_CONFIG_") -enum EffectConfigParameters : int32_t { - /** Buffer field. */ - BUFFER = 0x0001, - /** Sampling rate. */ - SMP_RATE = 0x0002, - /** Channels. */ - CHANNELS = 0x0004, - /** Format. */ - FORMAT = 0x0008, - /** Access mode. */ - ACC_MODE = 0x0010, - // Note that the 2.0 ALL have been moved to an helper function -}; - -/** * The buffer config structure specifies the input or output audio format * to be used by the effect engine. */ struct EffectBufferConfig { - AudioBuffer buffer; - AudioConfigBase base; - EffectBufferAccess accessMode; - bitfield<EffectConfigParameters> mask; + safe_union OptionalBuffer { + Monostate unspecified; + AudioBuffer buf; + } buffer; + AudioConfigBaseOptional base; + safe_union OptionalAccessMode { + Monostate unspecified; + EffectBufferAccess value; + } accessMode; }; struct EffectConfig { diff --git a/audio/effect/all-versions/default/Android.bp b/audio/effect/all-versions/default/Android.bp index a0cd6120e2..99b1120218 100644 --- a/audio/effect/all-versions/default/Android.bp +++ b/audio/effect/all-versions/default/Android.bp @@ -8,7 +8,6 @@ cc_defaults { "AudioBufferManager.cpp", "AutomaticGainControlEffect.cpp", "BassBoostEffect.cpp", - "Conversions.cpp", "DownmixEffect.cpp", "Effect.cpp", "EffectsFactory.cpp", @@ -51,6 +50,7 @@ cc_library_shared { "android.hardware.audio.common@2.0", "android.hardware.audio.common@2.0-util", "android.hardware.audio.effect@2.0", + "android.hardware.audio.effect@2.0-util", ], cflags: [ "-DMAJOR_VERSION=2", @@ -66,6 +66,7 @@ cc_library_shared { "android.hardware.audio.common@4.0", "android.hardware.audio.common@4.0-util", "android.hardware.audio.effect@4.0", + "android.hardware.audio.effect@4.0-util", ], cflags: [ "-DMAJOR_VERSION=4", @@ -81,6 +82,7 @@ cc_library_shared { "android.hardware.audio.common@5.0", "android.hardware.audio.common@5.0-util", "android.hardware.audio.effect@5.0", + "android.hardware.audio.effect@5.0-util", ], cflags: [ "-DMAJOR_VERSION=5", @@ -96,6 +98,7 @@ cc_library_shared { "android.hardware.audio.common@6.0", "android.hardware.audio.common@6.0-util", "android.hardware.audio.effect@6.0", + "android.hardware.audio.effect@6.0-util", ], cflags: [ "-DMAJOR_VERSION=6", @@ -111,6 +114,7 @@ cc_library_shared { "android.hardware.audio.common@7.0", "android.hardware.audio.common@7.0-util", "android.hardware.audio.effect@7.0", + "android.hardware.audio.effect@7.0-util", ], cflags: [ "-DMAJOR_VERSION=7", diff --git a/audio/effect/all-versions/default/Conversions.cpp b/audio/effect/all-versions/default/Conversions.cpp deleted file mode 100644 index 0cc8767e8d..0000000000 --- a/audio/effect/all-versions/default/Conversions.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "Conversions.h" -#include "UuidUtils.h" - -#include <memory.h> -#include <stdio.h> - -#include <common/all-versions/VersionUtils.h> - -using ::android::hardware::audio::common::utils::EnumBitfield; - -namespace android { -namespace hardware { -namespace audio { -namespace effect { -namespace CPP_VERSION { -namespace implementation { - -using ::android::hardware::audio::common::CPP_VERSION::implementation::UuidUtils; - -void effectDescriptorFromHal(const effect_descriptor_t& halDescriptor, - EffectDescriptor* descriptor) { - UuidUtils::uuidFromHal(halDescriptor.type, &descriptor->type); - UuidUtils::uuidFromHal(halDescriptor.uuid, &descriptor->uuid); - descriptor->flags = EnumBitfield<EffectFlags>(halDescriptor.flags); - descriptor->cpuLoad = halDescriptor.cpuLoad; - descriptor->memoryUsage = halDescriptor.memoryUsage; - memcpy(descriptor->name.data(), halDescriptor.name, descriptor->name.size()); - memcpy(descriptor->implementor.data(), halDescriptor.implementor, - descriptor->implementor.size()); -} - -std::string uuidToString(const effect_uuid_t& halUuid) { - char str[64]; - snprintf(str, sizeof(str), "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x", halUuid.timeLow, - halUuid.timeMid, halUuid.timeHiAndVersion, halUuid.clockSeq, halUuid.node[0], - halUuid.node[1], halUuid.node[2], halUuid.node[3], halUuid.node[4], halUuid.node[5]); - return str; -} - -} // namespace implementation -} // namespace CPP_VERSION -} // namespace effect -} // namespace audio -} // namespace hardware -} // namespace android diff --git a/audio/effect/all-versions/default/Conversions.h b/audio/effect/all-versions/default/Conversions.h deleted file mode 100644 index 75aab24efe..0000000000 --- a/audio/effect/all-versions/default/Conversions.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_HARDWARE_AUDIO_EFFECT_CONVERSIONS_H_ -#define ANDROID_HARDWARE_AUDIO_EFFECT_CONVERSIONS_H_ - -#include PATH(android/hardware/audio/effect/FILE_VERSION/types.h) - -#include <string> - -#include <system/audio_effect.h> - -namespace android { -namespace hardware { -namespace audio { -namespace effect { -namespace CPP_VERSION { -namespace implementation { - -using ::android::hardware::audio::effect::CPP_VERSION::EffectDescriptor; - -void effectDescriptorFromHal(const effect_descriptor_t& halDescriptor, - EffectDescriptor* descriptor); -std::string uuidToString(const effect_uuid_t& halUuid); - -} // namespace implementation -} // namespace CPP_VERSION -} // namespace effect -} // namespace audio -} // namespace hardware -} // namespace android - -#endif // ANDROID_HARDWARE_AUDIO_EFFECT_CONVERSIONS_H_ diff --git a/audio/effect/all-versions/default/Effect.cpp b/audio/effect/all-versions/default/Effect.cpp index edd364cd9b..ccfc6b22c9 100644 --- a/audio/effect/all-versions/default/Effect.cpp +++ b/audio/effect/all-versions/default/Effect.cpp @@ -19,7 +19,6 @@ #define LOG_TAG "EffectHAL" #define ATRACE_TAG ATRACE_TAG_AUDIO -#include "Conversions.h" #include "Effect.h" #include "common/all-versions/default/EffectMap.h" @@ -30,6 +29,7 @@ #include <HidlUtils.h> #include <android/log.h> #include <media/EffectsFactoryApi.h> +#include <util/EffectUtils.h> #include <utils/Trace.h> #include "VersionUtils.h" @@ -202,34 +202,6 @@ void Effect::effectAuxChannelsConfigToHal(const EffectAuxChannelsConfig& config, halConfig->aux_channels = static_cast<audio_channel_mask_t>(config.auxChannels); } -void Effect::effectBufferConfigFromHal(const buffer_config_t& halConfig, - EffectBufferConfig* config) { - config->buffer.id = 0; - config->buffer.frameCount = 0; - config->samplingRateHz = halConfig.samplingRate; - config->channels = AudioChannelBitfield(halConfig.channels); - config->format = AudioFormat(halConfig.format); - config->accessMode = EffectBufferAccess(halConfig.accessMode); - config->mask = static_cast<decltype(config->mask)>(halConfig.mask); -} - -// static -void Effect::effectBufferConfigToHal(const EffectBufferConfig& config, buffer_config_t* halConfig) { - // Note: setting the buffers directly is considered obsolete. They need to be set - // using 'setProcessBuffers'. - halConfig->buffer.frameCount = 0; - halConfig->buffer.raw = NULL; - halConfig->samplingRate = config.samplingRateHz; - halConfig->channels = static_cast<uint32_t>(config.channels); - // Note: The framework code does not use BP. - halConfig->bufferProvider.cookie = NULL; - halConfig->bufferProvider.getBuffer = NULL; - halConfig->bufferProvider.releaseBuffer = NULL; - halConfig->format = static_cast<uint8_t>(config.format); - halConfig->accessMode = static_cast<uint8_t>(config.accessMode); - halConfig->mask = static_cast<uint8_t>(config.mask); -} - #else // MAJOR_VERSION <= 6 void Effect::effectAuxChannelsConfigFromHal(const channel_config_t& halConfig, @@ -247,50 +219,8 @@ void Effect::effectAuxChannelsConfigToHal(const EffectAuxChannelsConfig& config, (void)HidlUtils::audioChannelMaskToHal(config.auxChannels, &halConfig->aux_channels); } -void Effect::effectBufferConfigFromHal(const buffer_config_t& halConfig, - EffectBufferConfig* config) { - config->buffer.id = 0; - config->buffer.frameCount = 0; - audio_config_base_t halConfigBase = {halConfig.samplingRate, - static_cast<audio_channel_mask_t>(halConfig.channels), - static_cast<audio_format_t>(halConfig.format)}; - (void)HidlUtils::audioConfigBaseFromHal(halConfigBase, mIsInput, &config->base); - config->accessMode = EffectBufferAccess(halConfig.accessMode); - config->mask = static_cast<decltype(config->mask)>(halConfig.mask); -} - -// static -void Effect::effectBufferConfigToHal(const EffectBufferConfig& config, buffer_config_t* halConfig) { - // Note: setting the buffers directly is considered obsolete. They need to be set - // using 'setProcessBuffers'. - halConfig->buffer.frameCount = 0; - halConfig->buffer.raw = nullptr; - audio_config_base_t halConfigBase; - (void)HidlUtils::audioConfigBaseToHal(config.base, &halConfigBase); - halConfig->samplingRate = halConfigBase.sample_rate; - halConfig->channels = halConfigBase.channel_mask; - halConfig->format = halConfigBase.format; - // Note: The framework code does not use BP. - halConfig->bufferProvider.cookie = nullptr; - halConfig->bufferProvider.getBuffer = nullptr; - halConfig->bufferProvider.releaseBuffer = nullptr; - halConfig->accessMode = static_cast<uint8_t>(config.accessMode); - halConfig->mask = static_cast<uint8_t>(config.mask); -} - #endif // MAJOR_VERSION <= 6 -void Effect::effectConfigFromHal(const effect_config_t& halConfig, EffectConfig* config) { - effectBufferConfigFromHal(halConfig.inputCfg, &config->inputCfg); - effectBufferConfigFromHal(halConfig.outputCfg, &config->outputCfg); -} - -// static -void Effect::effectConfigToHal(const EffectConfig& config, effect_config_t* halConfig) { - effectBufferConfigToHal(config.inputCfg, &halConfig->inputCfg); - effectBufferConfigToHal(config.outputCfg, &halConfig->outputCfg); -} - // static void Effect::effectOffloadParamToHal(const EffectOffloadParameter& offload, effect_offload_param_t* halOffload) { @@ -355,7 +285,7 @@ void Effect::getConfigImpl(int commandCode, const char* commandName, GetConfigCa (*mHandle)->command(mHandle, commandCode, 0, NULL, &halResultSize, &halConfig); EffectConfig config; if (status == OK) { - effectConfigFromHal(halConfig, &config); + status = EffectUtils::effectConfigFromHal(halConfig, mIsInput, &config); } cb(analyzeCommandStatus(commandName, sContextCallToCommand, status), config); } @@ -520,7 +450,7 @@ Result Effect::setConfigImpl(int commandCode, const char* commandName, const Eff const sp<IEffectBufferProviderCallback>& inputBufferProvider, const sp<IEffectBufferProviderCallback>& outputBufferProvider) { effect_config_t halConfig; - effectConfigToHal(config, &halConfig); + EffectUtils::effectConfigToHal(config, &halConfig); if (inputBufferProvider != 0) { LOG_FATAL("Using input buffer provider is not supported"); } @@ -715,7 +645,7 @@ Return<void> Effect::getDescriptor(getDescriptor_cb _hidl_cb) { status_t status = (*mHandle)->get_descriptor(mHandle, &halDescriptor); EffectDescriptor descriptor; if (status == OK) { - effectDescriptorFromHal(halDescriptor, &descriptor); + status = EffectUtils::effectDescriptorFromHal(halDescriptor, &descriptor); } _hidl_cb(analyzeStatus("get_descriptor", "", sContextCallFunction, status), descriptor); return Void(); diff --git a/audio/effect/all-versions/default/Effect.h b/audio/effect/all-versions/default/Effect.h index 9aa47ea7d9..d5218f7240 100644 --- a/audio/effect/all-versions/default/Effect.h +++ b/audio/effect/all-versions/default/Effect.h @@ -203,11 +203,6 @@ struct Effect : public IEffect { EffectAuxChannelsConfig* config); static void effectAuxChannelsConfigToHal(const EffectAuxChannelsConfig& config, channel_config_t* halConfig); - void effectBufferConfigFromHal(const buffer_config_t& halConfig, EffectBufferConfig* config); - static void effectBufferConfigToHal(const EffectBufferConfig& config, - buffer_config_t* halConfig); - void effectConfigFromHal(const effect_config_t& halConfig, EffectConfig* config); - static void effectConfigToHal(const EffectConfig& config, effect_config_t* halConfig); static void effectOffloadParamToHal(const EffectOffloadParameter& offload, effect_offload_param_t* halOffload); static std::vector<uint8_t> parameterToHal(uint32_t paramSize, const void* paramData, diff --git a/audio/effect/all-versions/default/EffectsFactory.cpp b/audio/effect/all-versions/default/EffectsFactory.cpp index 1ea990b3b6..eb1cb4971c 100644 --- a/audio/effect/all-versions/default/EffectsFactory.cpp +++ b/audio/effect/all-versions/default/EffectsFactory.cpp @@ -19,7 +19,6 @@ #include "AcousticEchoCancelerEffect.h" #include "AutomaticGainControlEffect.h" #include "BassBoostEffect.h" -#include "Conversions.h" #include "DownmixEffect.h" #include "Effect.h" #include "EnvironmentalReverbEffect.h" @@ -27,11 +26,11 @@ #include "LoudnessEnhancerEffect.h" #include "NoiseSuppressionEffect.h" #include "PresetReverbEffect.h" -#include "UuidUtils.h" #include "VirtualizerEffect.h" #include "VisualizerEffect.h" #include "common/all-versions/default/EffectMap.h" +#include <UuidUtils.h> #include <android/log.h> #include <media/EffectsFactoryApi.h> #include <system/audio_effects/effect_aec.h> @@ -45,6 +44,7 @@ #include <system/audio_effects/effect_presetreverb.h> #include <system/audio_effects/effect_virtualizer.h> #include <system/audio_effects/effect_visualizer.h> +#include <util/EffectUtils.h> namespace android { namespace hardware { @@ -107,7 +107,7 @@ restart: effect_descriptor_t halDescriptor; status = EffectQueryEffect(i, &halDescriptor); if (status == OK) { - effectDescriptorFromHal(halDescriptor, &result[i]); + EffectUtils::effectDescriptorFromHal(halDescriptor, &result[i]); } else { ALOGE("Error querying effect at position %d / %d: %s", i, numEffects, strerror(-status)); @@ -141,11 +141,11 @@ Return<void> EffectsFactory::getDescriptor(const Uuid& uuid, getDescriptor_cb _h effect_descriptor_t halDescriptor; status_t status = EffectGetDescriptor(&halUuid, &halDescriptor); EffectDescriptor descriptor; - effectDescriptorFromHal(halDescriptor, &descriptor); + EffectUtils::effectDescriptorFromHal(halDescriptor, &descriptor); Result retval(Result::OK); if (status != OK) { - ALOGE("Error querying effect descriptor for %s: %s", uuidToString(halUuid).c_str(), - strerror(-status)); + ALOGE("Error querying effect descriptor for %s: %s", + UuidUtils::uuidToString(halUuid).c_str(), strerror(-status)); if (status == -ENOENT) { retval = Result::INVALID_ARGUMENTS; } else { @@ -191,13 +191,14 @@ Return<void> EffectsFactory::createEffectImpl(const Uuid& uuid, int32_t session, effect = dispatchEffectInstanceCreation(halDescriptor, handle); effectId = EffectMap::getInstance().add(handle); } else { - ALOGE("Error querying effect descriptor for %s: %s", uuidToString(halUuid).c_str(), - strerror(-status)); + ALOGE("Error querying effect descriptor for %s: %s", + UuidUtils::uuidToString(halUuid).c_str(), strerror(-status)); EffectRelease(handle); } } if (status != OK) { - ALOGE("Error creating effect %s: %s", uuidToString(halUuid).c_str(), strerror(-status)); + ALOGE("Error creating effect %s: %s", UuidUtils::uuidToString(halUuid).c_str(), + strerror(-status)); if (status == -ENOENT) { retval = Result::INVALID_ARGUMENTS; } else { diff --git a/audio/effect/all-versions/default/TEST_MAPPING b/audio/effect/all-versions/default/TEST_MAPPING new file mode 100644 index 0000000000..b66e4e4758 --- /dev/null +++ b/audio/effect/all-versions/default/TEST_MAPPING @@ -0,0 +1,7 @@ +{ + "presubmit": [ + { + "name": "android.hardware.audio.effect@7.0-util_tests" + } + ] +} diff --git a/audio/effect/all-versions/default/util/Android.bp b/audio/effect/all-versions/default/util/Android.bp new file mode 100644 index 0000000000..5ba19d3a2d --- /dev/null +++ b/audio/effect/all-versions/default/util/Android.bp @@ -0,0 +1,136 @@ +cc_defaults { + name: "android.hardware.audio.effect-util_default", + defaults: ["hidl_defaults"], + + vendor_available: true, + + export_include_dirs: ["include"], + + srcs: [ + "EffectUtils.cpp", + ], + + shared_libs: [ + "liblog", + "libutils", + "libhidlbase", + "android.hardware.audio.common-util", + ], + export_shared_lib_headers: [ + "android.hardware.audio.common-util", + ], + + header_libs: [ + "libaudio_system_headers", + "libhardware_headers", + ], +} + +cc_library_shared { + name: "android.hardware.audio.effect@2.0-util", + defaults: ["android.hardware.audio.effect-util_default"], + shared_libs: [ + "android.hardware.audio.common@2.0", + "android.hardware.audio.common@2.0-util", + "android.hardware.audio.effect@2.0", + ], + cflags: [ + "-DMAJOR_VERSION=2", + "-DMINOR_VERSION=0", + "-include common/all-versions/VersionMacro.h", + ], +} + +cc_library_shared { + name: "android.hardware.audio.effect@4.0-util", + defaults: ["android.hardware.audio.effect-util_default"], + shared_libs: [ + "android.hardware.audio.common@4.0", + "android.hardware.audio.common@4.0-util", + "android.hardware.audio.effect@4.0", + ], + cflags: [ + "-DMAJOR_VERSION=4", + "-DMINOR_VERSION=0", + "-include common/all-versions/VersionMacro.h", + ], +} + +cc_library_shared { + name: "android.hardware.audio.effect@5.0-util", + defaults: ["android.hardware.audio.effect-util_default"], + shared_libs: [ + "android.hardware.audio.common@5.0", + "android.hardware.audio.common@5.0-util", + "android.hardware.audio.effect@5.0", + ], + cflags: [ + "-DMAJOR_VERSION=5", + "-DMINOR_VERSION=0", + "-include common/all-versions/VersionMacro.h", + ], +} + +cc_library_shared { + name: "android.hardware.audio.effect@6.0-util", + defaults: ["android.hardware.audio.effect-util_default"], + shared_libs: [ + "android.hardware.audio.common@6.0", + "android.hardware.audio.common@6.0-util", + "android.hardware.audio.effect@6.0", + ], + cflags: [ + "-DMAJOR_VERSION=6", + "-DMINOR_VERSION=0", + "-include common/all-versions/VersionMacro.h", + ], +} + +cc_library { + name: "android.hardware.audio.effect@7.0-util", + defaults: ["android.hardware.audio.effect-util_default"], + shared_libs: [ + "android.hardware.audio.common@7.0", + "android.hardware.audio.common@7.0-util", + "android.hardware.audio.effect@7.0", + ], + cflags: [ + "-DMAJOR_VERSION=7", + "-DMINOR_VERSION=0", + "-include common/all-versions/VersionMacro.h", + ], +} + +// Note: this isn't a VTS test, but rather a unit test +// to verify correctness of conversion utilities. +cc_test { + name: "android.hardware.audio.effect@7.0-util_tests", + defaults: ["android.hardware.audio.effect-util_default"], + + srcs: ["tests/effectutils_tests.cpp"], + + // Use static linking to allow running in presubmit on + // targets that don't have HAL V7. + static_libs: [ + "android.hardware.audio.common@7.0", + "android.hardware.audio.common@7.0-enums", + "android.hardware.audio.common@7.0-util", + "android.hardware.audio.effect@7.0", + "android.hardware.audio.effect@7.0-util", + ], + + shared_libs: [ + "libbase", + "libxml2", + ], + + cflags: [ + "-Werror", + "-Wall", + "-DMAJOR_VERSION=7", + "-DMINOR_VERSION=0", + "-include common/all-versions/VersionMacro.h", + ], + + test_suites: ["device-tests"], +} diff --git a/audio/effect/all-versions/default/util/EffectUtils.cpp b/audio/effect/all-versions/default/util/EffectUtils.cpp new file mode 100644 index 0000000000..1c0419aba3 --- /dev/null +++ b/audio/effect/all-versions/default/util/EffectUtils.cpp @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <memory.h> + +#include <HidlUtils.h> +#include <UuidUtils.h> +#include <common/all-versions/VersionUtils.h> + +#include "util/EffectUtils.h" + +using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils; +using ::android::hardware::audio::common::CPP_VERSION::implementation::UuidUtils; +using ::android::hardware::audio::common::utils::EnumBitfield; + +namespace android { +namespace hardware { +namespace audio { +namespace effect { +namespace CPP_VERSION { +namespace implementation { + +using namespace ::android::hardware::audio::common::CPP_VERSION; + +#define CONVERT_CHECKED(expr, result) \ + if (status_t status = (expr); status != NO_ERROR) { \ + result = status; \ + } + +#if MAJOR_VERSION <= 6 + +status_t EffectUtils::effectBufferConfigFromHal(const buffer_config_t& halConfig, bool /*isInput*/, + EffectBufferConfig* config) { + config->buffer.id = 0; + config->buffer.frameCount = 0; + config->samplingRateHz = halConfig.samplingRate; + config->channels = EnumBitfield<AudioChannelMask>(halConfig.channels); + config->format = AudioFormat(halConfig.format); + config->accessMode = EffectBufferAccess(halConfig.accessMode); + config->mask = EnumBitfield<EffectConfigParameters>(halConfig.mask); + return NO_ERROR; +} + +status_t EffectUtils::effectBufferConfigToHal(const EffectBufferConfig& config, + buffer_config_t* halConfig) { + // Note: setting the buffers directly is considered obsolete. They need to be set + // using 'setProcessBuffers'. + halConfig->buffer.frameCount = 0; + halConfig->buffer.raw = nullptr; + halConfig->samplingRate = config.samplingRateHz; + halConfig->channels = static_cast<uint32_t>(config.channels); + // Note: The framework code does not use BP. + halConfig->bufferProvider.cookie = nullptr; + halConfig->bufferProvider.getBuffer = nullptr; + halConfig->bufferProvider.releaseBuffer = nullptr; + halConfig->format = static_cast<uint8_t>(config.format); + halConfig->accessMode = static_cast<uint8_t>(config.accessMode); + halConfig->mask = static_cast<uint8_t>(config.mask); + return NO_ERROR; +} + +#else + +status_t EffectUtils::effectBufferConfigFromHal(const buffer_config_t& halConfig, bool isInput, + EffectBufferConfig* config) { + status_t result = NO_ERROR; + config->buffer.unspecified(); + audio_config_base_t halConfigBase = {halConfig.samplingRate, + static_cast<audio_channel_mask_t>(halConfig.channels), + static_cast<audio_format_t>(halConfig.format)}; + CONVERT_CHECKED(HidlUtils::audioConfigBaseOptionalFromHal( + halConfigBase, isInput, halConfig.mask & EFFECT_CONFIG_FORMAT, + halConfig.mask & EFFECT_CONFIG_SMP_RATE, + halConfig.mask & EFFECT_CONFIG_CHANNELS, &config->base), + result); + if (halConfig.mask & EFFECT_CONFIG_ACC_MODE) { + config->accessMode.value(EffectBufferAccess(halConfig.accessMode)); + } + return result; +} + +status_t EffectUtils::effectBufferConfigToHal(const EffectBufferConfig& config, + buffer_config_t* halConfig) { + status_t result = NO_ERROR; + // Note: setting the buffers directly is considered obsolete. They need to be set + // using 'setProcessBuffers'. + halConfig->buffer.frameCount = 0; + halConfig->buffer.raw = nullptr; + audio_config_base_t halConfigBase = AUDIO_CONFIG_BASE_INITIALIZER; + bool formatSpecified = false, sRateSpecified = false, channelMaskSpecified = false; + CONVERT_CHECKED( + HidlUtils::audioConfigBaseOptionalToHal(config.base, &halConfigBase, &formatSpecified, + &sRateSpecified, &channelMaskSpecified), + result); + halConfig->mask = 0; + if (sRateSpecified) { + halConfig->mask |= EFFECT_CONFIG_SMP_RATE; + halConfig->samplingRate = halConfigBase.sample_rate; + } + if (channelMaskSpecified) { + halConfig->mask |= EFFECT_CONFIG_CHANNELS; + halConfig->channels = halConfigBase.channel_mask; + } + if (formatSpecified) { + halConfig->mask |= EFFECT_CONFIG_FORMAT; + halConfig->format = halConfigBase.format; + } + // Note: The framework code does not use BP. + halConfig->bufferProvider.cookie = nullptr; + halConfig->bufferProvider.getBuffer = nullptr; + halConfig->bufferProvider.releaseBuffer = nullptr; + if (config.accessMode.getDiscriminator() == + EffectBufferConfig::OptionalAccessMode::hidl_discriminator::value) { + halConfig->mask |= EFFECT_CONFIG_ACC_MODE; + halConfig->accessMode = static_cast<uint8_t>(config.accessMode.value()); + } + return result; +} + +#endif // MAJOR_VERSION >= 6 + +status_t EffectUtils::effectConfigFromHal(const effect_config_t& halConfig, bool isInput, + EffectConfig* config) { + status_t result = NO_ERROR; + CONVERT_CHECKED(effectBufferConfigFromHal(halConfig.inputCfg, isInput, &config->inputCfg), + result); + CONVERT_CHECKED(effectBufferConfigFromHal(halConfig.outputCfg, isInput, &config->outputCfg), + result); + return result; +} + +status_t EffectUtils::effectConfigToHal(const EffectConfig& config, effect_config_t* halConfig) { + status_t result = NO_ERROR; + CONVERT_CHECKED(effectBufferConfigToHal(config.inputCfg, &halConfig->inputCfg), result); + CONVERT_CHECKED(effectBufferConfigToHal(config.outputCfg, &halConfig->outputCfg), result); + return result; +} + +status_t EffectUtils::effectDescriptorFromHal(const effect_descriptor_t& halDescriptor, + EffectDescriptor* descriptor) { + UuidUtils::uuidFromHal(halDescriptor.type, &descriptor->type); + UuidUtils::uuidFromHal(halDescriptor.uuid, &descriptor->uuid); + descriptor->flags = EnumBitfield<EffectFlags>(halDescriptor.flags); + descriptor->cpuLoad = halDescriptor.cpuLoad; + descriptor->memoryUsage = halDescriptor.memoryUsage; + memcpy(descriptor->name.data(), halDescriptor.name, descriptor->name.size()); + memcpy(descriptor->implementor.data(), halDescriptor.implementor, + descriptor->implementor.size()); + return NO_ERROR; +} + +status_t EffectUtils::effectDescriptorToHal(const EffectDescriptor& descriptor, + effect_descriptor_t* halDescriptor) { + UuidUtils::uuidToHal(descriptor.type, &halDescriptor->type); + UuidUtils::uuidToHal(descriptor.uuid, &halDescriptor->uuid); + halDescriptor->flags = static_cast<uint32_t>(descriptor.flags); + halDescriptor->cpuLoad = descriptor.cpuLoad; + halDescriptor->memoryUsage = descriptor.memoryUsage; + memcpy(halDescriptor->name, descriptor.name.data(), descriptor.name.size()); + memcpy(halDescriptor->implementor, descriptor.implementor.data(), + descriptor.implementor.size()); + return NO_ERROR; +} + +} // namespace implementation +} // namespace CPP_VERSION +} // namespace effect +} // namespace audio +} // namespace hardware +} // namespace android diff --git a/audio/effect/all-versions/default/util/include/util/EffectUtils.h b/audio/effect/all-versions/default/util/include/util/EffectUtils.h new file mode 100644 index 0000000000..23963b4d41 --- /dev/null +++ b/audio/effect/all-versions/default/util/include/util/EffectUtils.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +// clang-format off +#include PATH(android/hardware/audio/effect/FILE_VERSION/types.h) +// clang-format on + +#include <system/audio_effect.h> + +namespace android { +namespace hardware { +namespace audio { +namespace effect { +namespace CPP_VERSION { +namespace implementation { + +using namespace ::android::hardware::audio::effect::CPP_VERSION; + +struct EffectUtils { + static status_t effectBufferConfigFromHal(const buffer_config_t& halConfig, bool isInput, + EffectBufferConfig* config); + static status_t effectBufferConfigToHal(const EffectBufferConfig& config, + buffer_config_t* halConfig); + static status_t effectConfigFromHal(const effect_config_t& halConfig, bool isInput, + EffectConfig* config); + static status_t effectConfigToHal(const EffectConfig& config, effect_config_t* halConfig); + static status_t effectDescriptorFromHal(const effect_descriptor_t& halDescriptor, + EffectDescriptor* descriptor); + static status_t effectDescriptorToHal(const EffectDescriptor& descriptor, + effect_descriptor_t* halDescriptor); +}; + +} // namespace implementation +} // namespace CPP_VERSION +} // namespace effect +} // namespace audio +} // namespace hardware +} // namespace android diff --git a/audio/effect/all-versions/default/util/tests/effectutils_tests.cpp b/audio/effect/all-versions/default/util/tests/effectutils_tests.cpp new file mode 100644 index 0000000000..7eb8cd2958 --- /dev/null +++ b/audio/effect/all-versions/default/util/tests/effectutils_tests.cpp @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <string> + +#include <gtest/gtest.h> + +#define LOG_TAG "EffectUtils_Test" +#include <log/log.h> + +#include <android_audio_policy_configuration_V7_0-enums.h> +#include <system/audio_effect.h> +#include <util/EffectUtils.h> +#include <xsdc/XsdcSupport.h> + +using namespace android; +using namespace ::android::hardware::audio::common::CPP_VERSION; +using namespace ::android::hardware::audio::effect::CPP_VERSION; +using ::android::hardware::audio::effect::CPP_VERSION::implementation::EffectUtils; +namespace xsd { +using namespace ::android::audio::policy::configuration::V7_0; +} + +static constexpr audio_channel_mask_t kInvalidHalChannelMask = AUDIO_CHANNEL_INVALID; +static constexpr audio_format_t kInvalidHalFormat = AUDIO_FORMAT_INVALID; + +// Not generated automatically because AudioBuffer contains +// instances of hidl_memory which can't be compared properly +// in general case due to presence of handles. +// +// However, in this particular case, handles must not present +// thus comparison is possible. +// +// operator== must be defined in the same namespace as the structures. +namespace android { +namespace hardware { +namespace audio { +namespace effect { +namespace CPP_VERSION { +inline bool operator==(const AudioBuffer& lhs, const AudioBuffer& rhs) { + return lhs.id == rhs.id && lhs.frameCount == rhs.frameCount && lhs.data.handle() == nullptr && + rhs.data.handle() == nullptr; +} + +inline bool operator==(const EffectBufferConfig& lhs, const EffectBufferConfig& rhs) { + return lhs.buffer.getDiscriminator() == rhs.buffer.getDiscriminator() && + (lhs.buffer.getDiscriminator() == + EffectBufferConfig::OptionalBuffer::hidl_discriminator::unspecified || + lhs.buffer.buf() == rhs.buffer.buf()) && + lhs.base == rhs.base && lhs.accessMode == rhs.accessMode; +} + +inline bool operator==(const EffectConfig& lhs, const EffectConfig& rhs) { + return lhs.inputCfg == rhs.inputCfg && lhs.outputCfg == rhs.outputCfg; +} +} // namespace CPP_VERSION +} // namespace effect +} // namespace audio +} // namespace hardware +} // namespace android + +TEST(EffectUtils, ConvertInvalidBufferConfig) { + buffer_config_t halInvalid; + EffectBufferConfig invalidChannelMask; + invalidChannelMask.base.channelMask.value("random string"); + EXPECT_EQ(BAD_VALUE, EffectUtils::effectBufferConfigToHal(invalidChannelMask, &halInvalid)); + EffectBufferConfig invalidFormat; + invalidFormat.base.format.value("random string"); + EXPECT_EQ(BAD_VALUE, EffectUtils::effectBufferConfigToHal(invalidFormat, &halInvalid)); + + buffer_config_t halInvalidChannelMask; + EffectBufferConfig invalid; + halInvalidChannelMask.channels = kInvalidHalChannelMask; + halInvalidChannelMask.mask = EFFECT_CONFIG_CHANNELS; + EXPECT_EQ(BAD_VALUE, EffectUtils::effectBufferConfigFromHal(halInvalidChannelMask, + false /*isInput*/, &invalid)); + EXPECT_EQ(BAD_VALUE, EffectUtils::effectBufferConfigFromHal(halInvalidChannelMask, + true /*isInput*/, &invalid)); + buffer_config_t halInvalidFormat; + halInvalidFormat.format = (uint8_t)kInvalidHalFormat; + halInvalidFormat.mask = EFFECT_CONFIG_FORMAT; + EXPECT_EQ(BAD_VALUE, EffectUtils::effectBufferConfigFromHal(halInvalidFormat, false /*isInput*/, + &invalid)); + EXPECT_EQ(BAD_VALUE, + EffectUtils::effectBufferConfigFromHal(halInvalidFormat, true /*isInput*/, &invalid)); +} + +TEST(EffectUtils, ConvertBufferConfig) { + EffectBufferConfig empty; + buffer_config_t halEmpty; + EXPECT_EQ(NO_ERROR, EffectUtils::effectBufferConfigToHal(empty, &halEmpty)); + EffectBufferConfig emptyBackOut; + EXPECT_EQ(NO_ERROR, + EffectUtils::effectBufferConfigFromHal(halEmpty, false /*isInput*/, &emptyBackOut)); + EXPECT_EQ(empty, emptyBackOut); + EffectBufferConfig emptyBackIn; + EXPECT_EQ(NO_ERROR, + EffectUtils::effectBufferConfigFromHal(halEmpty, true /*isInput*/, &emptyBackIn)); + EXPECT_EQ(empty, emptyBackIn); + + EffectBufferConfig chanMask; + chanMask.base.channelMask.value(toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO)); + buffer_config_t halChanMask; + EXPECT_EQ(NO_ERROR, EffectUtils::effectBufferConfigToHal(chanMask, &halChanMask)); + EffectBufferConfig chanMaskBack; + EXPECT_EQ(NO_ERROR, EffectUtils::effectBufferConfigFromHal(halChanMask, false /*isInput*/, + &chanMaskBack)); + EXPECT_EQ(chanMask, chanMaskBack); + + EffectBufferConfig format; + format.base.format.value(toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT)); + buffer_config_t halFormat; + EXPECT_EQ(NO_ERROR, EffectUtils::effectBufferConfigToHal(format, &halFormat)); + EffectBufferConfig formatBackOut; + EXPECT_EQ(NO_ERROR, + EffectUtils::effectBufferConfigFromHal(halFormat, false /*isInput*/, &formatBackOut)); + EXPECT_EQ(format, formatBackOut); + EffectBufferConfig formatBackIn; + EXPECT_EQ(NO_ERROR, + EffectUtils::effectBufferConfigFromHal(halFormat, true /*isInput*/, &formatBackIn)); + EXPECT_EQ(format, formatBackIn); +} + +TEST(EffectUtils, ConvertDescriptor) { + EffectDescriptor desc{}; + effect_descriptor_t halDesc; + EXPECT_EQ(NO_ERROR, EffectUtils::effectDescriptorToHal(desc, &halDesc)); + EffectDescriptor descBack; + EXPECT_EQ(NO_ERROR, EffectUtils::effectDescriptorFromHal(halDesc, &descBack)); + EXPECT_EQ(desc, descBack); +} diff --git a/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp b/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp index 35ff8693a4..15a2fd928c 100644 --- a/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp +++ b/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp @@ -264,8 +264,10 @@ void AudioEffectHidlTest::getChannelCount(uint32_t* channelCount) { *channelCount = audio_channel_count_from_out_mask( static_cast<audio_channel_mask_t>(currentConfig.outputCfg.channels)); #else + ASSERT_EQ(AudioConfigBaseOptional::ChannelMask::hidl_discriminator::value, + currentConfig.outputCfg.base.channelMask.getDiscriminator()); *channelCount = android::audio::policy::configuration::V7_0::getChannelCount( - currentConfig.outputCfg.base.channelMask); + currentConfig.outputCfg.base.channelMask.value()); ASSERT_NE(*channelCount, 0); #endif } @@ -315,10 +317,10 @@ TEST_P(AudioEffectHidlTest, GetSetConfig) { std::vector<EffectBufferConfig> generateInvalidConfigs(const EffectBufferConfig& src) { std::vector<EffectBufferConfig> result; EffectBufferConfig invalidFormat = src; - invalidFormat.base.format = "random_string"; + invalidFormat.base.format.value("random_string"); result.push_back(std::move(invalidFormat)); EffectBufferConfig invalidChannelMask = src; - invalidChannelMask.base.channelMask = "random_string"; + invalidChannelMask.base.channelMask.value("random_string"); result.push_back(std::move(invalidChannelMask)); return result; } @@ -395,17 +397,22 @@ inline bool operator==(const AudioBuffer& lhs, const AudioBuffer& rhs) { rhs.data.handle() == nullptr; } +#if MAJOR_VERSION <= 6 inline bool operator==(const EffectBufferConfig& lhs, const EffectBufferConfig& rhs) { return lhs.buffer == rhs.buffer && -#if MAJOR_VERSION <= 6 lhs.samplingRateHz == rhs.samplingRateHz && lhs.channels == rhs.channels && lhs.format == rhs.format && -#else - lhs.base.sampleRateHz == rhs.base.sampleRateHz && - lhs.base.channelMask == rhs.base.channelMask && lhs.base.format == rhs.base.format && -#endif lhs.accessMode == rhs.accessMode && lhs.mask == rhs.mask; } +#else +inline bool operator==(const EffectBufferConfig& lhs, const EffectBufferConfig& rhs) { + return lhs.buffer.getDiscriminator() == rhs.buffer.getDiscriminator() && + (lhs.buffer.getDiscriminator() == + EffectBufferConfig::OptionalBuffer::hidl_discriminator::unspecified || + lhs.buffer.buf() == rhs.buffer.buf()) && + lhs.base == rhs.base && lhs.accessMode == rhs.accessMode; +} +#endif // MAJOR_VERSION <= 6 inline bool operator==(const EffectConfig& lhs, const EffectConfig& rhs) { return lhs.inputCfg == rhs.inputCfg && lhs.outputCfg == rhs.outputCfg; diff --git a/authsecret/aidl/default/Android.bp b/authsecret/aidl/default/Android.bp index d5983442f5..44e0711096 100644 --- a/authsecret/aidl/default/Android.bp +++ b/authsecret/aidl/default/Android.bp @@ -25,7 +25,7 @@ cc_binary { "AuthSecret.cpp", ], shared_libs: [ - "android.hardware.authsecret-ndk_platform", + "android.hardware.authsecret-V1-ndk_platform", "libbase", "libbinder_ndk", ], diff --git a/authsecret/aidl/vts/Android.bp b/authsecret/aidl/vts/Android.bp index 83a85b26ce..29b3bcc21d 100644 --- a/authsecret/aidl/vts/Android.bp +++ b/authsecret/aidl/vts/Android.bp @@ -21,7 +21,7 @@ cc_test { "use_libaidlvintf_gtest_helper_static", ], srcs: ["VtsHalAuthSecretTargetTest.cpp"], - static_libs: ["android.hardware.authsecret-ndk_platform"], + static_libs: ["android.hardware.authsecret-V1-ndk_platform"], shared_libs: ["libbinder_ndk"], test_suites: [ "general-tests", diff --git a/automotive/audiocontrol/aidl/default/Android.bp b/automotive/audiocontrol/aidl/default/Android.bp index 427709abb3..05fec79666 100644 --- a/automotive/audiocontrol/aidl/default/Android.bp +++ b/automotive/audiocontrol/aidl/default/Android.bp @@ -22,8 +22,8 @@ cc_binary { generated_sources: ["audio_policy_configuration_V7_0"], header_libs: ["libxsdc-utils"], shared_libs: [ - "android.frameworks.automotive.powerpolicy-ndk_platform", - "android.hardware.automotive.audiocontrol-ndk_platform", + "android.frameworks.automotive.powerpolicy-V1-ndk_platform", + "android.hardware.automotive.audiocontrol-V1-ndk_platform", "libbase", "libbinder_ndk", "libcutils", diff --git a/automotive/audiocontrol/aidl/vts/Android.bp b/automotive/audiocontrol/aidl/vts/Android.bp index 3d81e001c1..89f5f9266c 100644 --- a/automotive/audiocontrol/aidl/vts/Android.bp +++ b/automotive/audiocontrol/aidl/vts/Android.bp @@ -28,7 +28,7 @@ cc_test { "libxml2", ], static_libs: [ - "android.hardware.automotive.audiocontrol-cpp", + "android.hardware.automotive.audiocontrol-V1-cpp", "libgmock", ], test_suites: [ diff --git a/automotive/occupant_awareness/aidl/default/Android.bp b/automotive/occupant_awareness/aidl/default/Android.bp index 1b2fba2ea4..1e50930716 100644 --- a/automotive/occupant_awareness/aidl/default/Android.bp +++ b/automotive/occupant_awareness/aidl/default/Android.bp @@ -27,6 +27,6 @@ cc_binary { "libbase", "libbinder_ndk", "libutils", - "android.hardware.automotive.occupant_awareness-ndk_platform", + "android.hardware.automotive.occupant_awareness-V1-ndk_platform", ], } diff --git a/automotive/occupant_awareness/aidl/mock/Android.bp b/automotive/occupant_awareness/aidl/mock/Android.bp index 4b3086660c..64ca73377b 100644 --- a/automotive/occupant_awareness/aidl/mock/Android.bp +++ b/automotive/occupant_awareness/aidl/mock/Android.bp @@ -27,6 +27,6 @@ cc_binary { "libbase", "libbinder_ndk", "libutils", - "android.hardware.automotive.occupant_awareness-ndk_platform", + "android.hardware.automotive.occupant_awareness-V1-ndk_platform", ], } diff --git a/automotive/occupant_awareness/aidl/vts/functional/Android.bp b/automotive/occupant_awareness/aidl/vts/functional/Android.bp index 514b0afc2b..dbd0538de1 100644 --- a/automotive/occupant_awareness/aidl/vts/functional/Android.bp +++ b/automotive/occupant_awareness/aidl/vts/functional/Android.bp @@ -9,7 +9,7 @@ cc_test { "libbinder", ], static_libs: [ - "android.hardware.automotive.occupant_awareness-cpp", + "android.hardware.automotive.occupant_awareness-V1-cpp", ], test_suites: [ "vts", diff --git a/automotive/vehicle/2.0/default/Android.bp b/automotive/vehicle/2.0/default/Android.bp index bbb48e1489..c66c9cca11 100644 --- a/automotive/vehicle/2.0/default/Android.bp +++ b/automotive/vehicle/2.0/default/Android.bp @@ -32,7 +32,7 @@ cc_defaults { defaults: ["vhal_v2_0_defaults"], shared_libs: [ "libbinder_ndk", - "android.automotive.watchdog-ndk_platform", + "android.automotive.watchdog-V2-ndk_platform", ], } diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl index 56d097d5ff..8fd6c5f9a8 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AuthenticationFrame.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AuthenticationFrame.aidl index 3043000f39..a9e4de3bc3 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AuthenticationFrame.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AuthenticationFrame.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.aidl index 27821e3ece..a93510160b 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Cell.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Cell.aidl index 17c1ba3695..cc2bf53c1d 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Cell.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Cell.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.aidl index c736e7e743..cc78e6b077 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStage.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStage.aidl index af6be9061a..fefac68ad6 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStage.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStage.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.aidl index 268ce52e46..d13eccd0fe 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentType.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentType.aidl index 7295b3b4ee..3603c4e08c 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentType.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentType.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl index cba6ec595f..6bbe7871ac 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceSensorType.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceSensorType.aidl index b08c345b5d..481b678157 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceSensorType.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceSensorType.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Feature.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Feature.aidl new file mode 100644 index 0000000000..d9e561d518 --- /dev/null +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Feature.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *//////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m <name>-update-api`. +// +// You must not make a backward incompatible change to any AIDL file 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.biometrics.face; +@Backing(type="byte") @VintfStability +enum Feature { + WAVE_ATTENTION_REQUIREMENT = 0, + WAVE_DIVERSE_POSES_REQUIREMENT = 1, + DEBUG = 2, +} diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl index 65afaa493f..37345ec01b 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl index 203e2752b8..b855a9ede1 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// @@ -21,11 +35,13 @@ package android.hardware.biometrics.face; interface ISession { void generateChallenge(in int cookie, in int timeoutSec); void revokeChallenge(in int cookie, in long challenge); - android.hardware.biometrics.common.ICancellationSignal enroll(in int cookie, in android.hardware.biometrics.face.EnrollmentType enrollmentType, in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.common.NativeHandle previewSurface); + android.hardware.biometrics.common.ICancellationSignal enroll(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.biometrics.face.EnrollmentType type, in android.hardware.biometrics.face.Feature[] features, in android.hardware.common.NativeHandle previewSurface); android.hardware.biometrics.common.ICancellationSignal authenticate(in int cookie, in long operationId); android.hardware.biometrics.common.ICancellationSignal detectInteraction(in int cookie); void enumerateEnrollments(in int cookie); void removeEnrollments(in int cookie, in int[] enrollmentIds); + void getFeatures(in int cookie, in int enrollmentId); + void setFeature(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat, in int enrollmentId, in android.hardware.biometrics.face.Feature feature, boolean enabled); void getAuthenticatorId(in int cookie); void invalidateAuthenticatorId(in int cookie); void resetLockout(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat); diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl index a81c79a42b..6127c7b956 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// @@ -33,6 +47,8 @@ interface ISessionCallback { void onLockoutCleared(); void onInteractionDetected(); void onEnrollmentsEnumerated(in int[] enrollmentIds); + void onFeaturesRetrieved(in android.hardware.biometrics.face.Feature[] features, in int enrollmentId); + void onFeatureSet(in int enrollmentId, android.hardware.biometrics.face.Feature feature); void onEnrollmentsRemoved(in int[] enrollmentIds); void onAuthenticatorIdRetrieved(in long authenticatorId); void onAuthenticatorIdInvalidated(in long newAuthenticatorId); diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl index a52829cc5b..23a8d4dddc 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// @@ -27,4 +41,5 @@ parcelable SensorProps { float enrollTranslationX; float enrollTranslationY; float enrollPreviewScale; + boolean supportsDetectInteraction; } diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SessionState.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SessionState.aidl index 12a5eabbc4..46751d03d0 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SessionState.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SessionState.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// @@ -28,7 +42,9 @@ enum SessionState { DETECTING_INTERACTION = 6, ENUMERATING_ENROLLMENTS = 7, REMOVING_ENROLLMENTS = 8, - GETTING_AUTHENTICATOR_ID = 9, - INVALIDATING_AUTHENTICATOR_ID = 10, - RESETTING_LOCKOUT = 11, + GETTING_FEATURES = 9, + SETTING_FEATURE = 10, + GETTING_AUTHENTICATOR_ID = 11, + INVALIDATING_AUTHENTICATOR_ID = 12, + RESETTING_LOCKOUT = 13, } diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl index d88370f129..7230128989 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl @@ -32,9 +32,8 @@ enum Error { HW_UNAVAILABLE = 1, /** - * The current enroll or authenticate operation could not be completed, - * e.g. the sensor was unable to process the current image or the HAT was - * invalid. + * The current operation could not be completed, e.g. the sensor was unable + * to process the current image or the HAT was invalid. */ UNABLE_TO_PROCESS = 2, diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/Feature.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/Feature.aidl new file mode 100644 index 0000000000..b88050ab60 --- /dev/null +++ b/biometrics/face/aidl/android/hardware/biometrics/face/Feature.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.biometrics.face; + +@VintfStability +@Backing(type="byte") +enum Feature { + /** + * Do not require the user to look at the device during enrollment and authentication. Note + * this is to accommodate people who have limited vision. + */ + WAVE_ATTENTION_REQUIREMENT, + + /** + * Do not require a diverse set of poses during enrollment. This is to accommodate people with + * limited mobility. + */ + WAVE_DIVERSE_POSES_REQUIREMENT, + + /** + * Enable debugging functionality. + */ + DEBUG, +} + diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl index 34a1f8b5a9..f540502669 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl @@ -17,12 +17,12 @@ package android.hardware.biometrics.face; import android.hardware.biometrics.common.ICancellationSignal; +import android.hardware.biometrics.face.Feature; import android.hardware.biometrics.face.EnrollmentType; import android.hardware.keymaster.HardwareAuthToken; import android.hardware.common.NativeHandle; -/** - * A session is a collection of immutable state (sensorId, userId), mutable state (SessionState), +/** * A session is a collection of immutable state (sensorId, userId), mutable state (SessionState), * methods available for the framework to call, and a callback (ISessionCallback) to notify the * framework about the events and results. A session is used to establish communication between * the framework and the HAL. @@ -131,16 +131,17 @@ interface ISession { * * @param cookie An identifier used to track subsystem operations related to this call path. The * client must guarantee that it is unique per ISession. + * @param hat See above documentation. * @param enrollmentType See the EnrollmentType enum. + * @param features See the Feature enum. * @param previewSurface A surface provided by the framework if SensorProps#halControlsPreview is * set to true. The HAL must send the preview frames to previewSurface if * it's not null. - * @param hat See above documentation. * @return ICancellationSignal An object that can be used by the framework to cancel this * operation. */ - ICancellationSignal enroll(in int cookie, in EnrollmentType enrollmentType, - in HardwareAuthToken hat, in NativeHandle previewSurface); + ICancellationSignal enroll(in int cookie, in HardwareAuthToken hat, in EnrollmentType type, + in Feature[] features, in NativeHandle previewSurface); /** * authenticate: @@ -195,7 +196,9 @@ interface ISession { /** * detectInteraction: * - * A request to start looking for faces without performing matching. + * A request to start looking for faces without performing matching. Must only be called if + * SensorProps#supportsDetectInteraction is true. If invoked on implementations that do not + * support this functionality, the HAL must respond with ISession#onError(UNABLE_TO_PROCESS, 0). * * Once the HAL is able to start processing this request, it must notify the framework via * ISessionCallback#onStateChanged with SessionState::DETECTING_INTERACTION. @@ -266,6 +269,54 @@ interface ISession { void removeEnrollments(in int cookie, in int[] enrollmentIds); /** + * getFeatures: + * + * Returns a list of currently enabled features for the provided enrollmentId. + * + * If the enrollmentId is invalid, the HAL must invoke ISessionCallback#onError with + * Error::UNABLE_TO_PROCESS and return to SessionState::IDLING if no subsequent work is in the + * queue. + * + * Once the HAL is able to start processing this request, it must notify the framework by using + * ISessionCallback#onStateChanged with SessionState::GETTING_FEATURES. + * + * The HAL must notify the framework about the result by calling + * ISessionCallback#onFeaturesRetrieved. + * + * @param cookie An identifier used to track subsystem operations related to this call path. The + * client must guarantee that it is unique per ISession. + * @param enrollmentId the ID of the enrollment for which the features are requested. + */ + void getFeatures(in int cookie, in int enrollmentId); + + /** + * setFeature: + * + * Enables or disables a feature for the given enrollmentId. Because certain features may + * decrease security, the user must enter their password before this method is invoked + * (see @param hat). The HAL must verify the hat before changing any feature state. + * + * If either the hat or enrollmentId is invalid, the HAL must invoke ISessionCallback#onError + * with Error::UNABLE_TO_PROCESS and return to SessionState::IDLING if no subsequent work is in + * the queue. + * + * Once the HAL is able to start processing this request, it must notify the framework by using + * ISessionCallback#onStateChanged with SessionState::SETTING_FEATURE. + * + * After the feature is successfully set, the HAL must notify the framework by calling + * ISessionCallback#onFeatureSet. + * + * @param cookie An identifier used to track subsystem operations related to this call path. The + * client must guarantee that it is unique per ISession. + * @param hat HardwareAuthToken See above documentation. + * @param enrollmentId the ID of the enrollment for which the feature update is requested. + * @param feature The feature to be enabled or disabled. + * @param enabled Whether the provided features should be enabled or disabled. + */ + void setFeature(in int cookie, in HardwareAuthToken hat, in int enrollmentId, + in Feature feature, boolean enabled); + + /** * getAuthenticatorId: * * MUST return 0 via ISessionCallback#onAuthenticatorIdRetrieved for sensors that are configured diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl index 9178e3aa7b..354f4a7e19 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl @@ -17,6 +17,7 @@ package android.hardware.biometrics.face; import android.hardware.biometrics.face.AcquiredInfo; +import android.hardware.biometrics.face.Feature; import android.hardware.biometrics.face.AuthenticationFrame; import android.hardware.biometrics.face.EnrollmentFrame; import android.hardware.biometrics.face.Error; @@ -178,6 +179,26 @@ interface ISessionCallback { void onEnrollmentsEnumerated(in int[] enrollmentIds); /** + * This method must only be used to notify the framework during SessionState::GETTING_FEATURES. + * + * Provides a list of features that are currently enabled for the given enrollmentId. + * + * @param features A list of currently enabled features. See the Feature enum. + * @param enrollmentId The enrollment for which the features were requested. + */ + void onFeaturesRetrieved(in Feature[] features, in int enrollmentId); + + /** + * This method must only be used to notify the framework during SessionState::SETTING_FEATURE. + * + * Notifies the framework that ISession#setFeature has completed. + * + * @param enrollmentId The enrollment for which a feature was set. + * @param feature The feature that was set. + */ + void onFeatureSet(in int enrollmentId, Feature feature); + + /** * This method must only be used to notify the framework during * SessionState::REMOVING_ENROLLMENTS. * diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl index 335f2f9e52..091e3225a3 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl @@ -70,5 +70,10 @@ parcelable SensorProps { * be applied when configuring the preview texture. */ float enrollPreviewScale; + + /** + * Specifies whether or not the implementation supports ISession#detectInteraction. + */ + boolean supportsDetectInteraction; } diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/SessionState.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/SessionState.aidl index e56f5d84fc..76755649e4 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/SessionState.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/SessionState.aidl @@ -65,6 +65,16 @@ enum SessionState { REMOVING_ENROLLMENTS, /** + * The HAL is processing the ISession#getFeatures request. + */ + GETTING_FEATURES, + + /** + * The HAL is processing the ISession#setFeature request. + */ + SETTING_FEATURE, + + /** * The HAL is processing the ISession#getAuthenticatorId request. */ GETTING_AUTHENTICATOR_ID, diff --git a/biometrics/face/aidl/default/Android.bp b/biometrics/face/aidl/default/Android.bp index 51a8ef4488..a13b8cb09d 100644 --- a/biometrics/face/aidl/default/Android.bp +++ b/biometrics/face/aidl/default/Android.bp @@ -7,8 +7,8 @@ cc_binary { shared_libs: [ "libbase", "libbinder_ndk", - "android.hardware.biometrics.face-ndk_platform", - "android.hardware.biometrics.common-unstable-ndk_platform", + "android.hardware.biometrics.face-V1-ndk_platform", + "android.hardware.biometrics.common-V1-ndk_platform", ], srcs: [ "main.cpp", diff --git a/biometrics/face/aidl/default/Session.cpp b/biometrics/face/aidl/default/Session.cpp index df5187955f..63d1721314 100644 --- a/biometrics/face/aidl/default/Session.cpp +++ b/biometrics/face/aidl/default/Session.cpp @@ -55,8 +55,9 @@ ndk::ScopedAStatus Session::revokeChallenge(int32_t /*cookie*/, int64_t challeng } ndk::ScopedAStatus Session::enroll( - int32_t /*cookie*/, biometrics::face::EnrollmentType /*enrollmentType*/, - const keymaster::HardwareAuthToken& /*hat*/, const NativeHandle& /*previewSurface*/, + int32_t /*cookie*/, const keymaster::HardwareAuthToken& /*hat*/, + EnrollmentType /*enrollmentType*/, const std::vector<Feature>& /*features*/, + const NativeHandle& /*previewSurface*/, std::shared_ptr<biometrics::common::ICancellationSignal>* /*return_val*/) { return ndk::ScopedAStatus::ok(); } @@ -94,6 +95,17 @@ ndk::ScopedAStatus Session::removeEnrollments(int32_t /*cookie*/, return ndk::ScopedAStatus::ok(); } +ndk::ScopedAStatus Session::getFeatures(int32_t /*cookie*/, int32_t /*enrollmentId*/) { + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Session::setFeature(int32_t /*cookie*/, + const keymaster::HardwareAuthToken& /*hat*/, + int32_t /*enrollmentId*/, Feature /*feature*/, + bool /*enabled*/) { + return ndk::ScopedAStatus::ok(); +} + ndk::ScopedAStatus Session::getAuthenticatorId(int32_t /*cookie*/) { if (cb_) { cb_->onStateChanged(0, SessionState::GETTING_AUTHENTICATOR_ID); diff --git a/biometrics/face/aidl/default/Session.h b/biometrics/face/aidl/default/Session.h index 347d2020fc..83cb0641d6 100644 --- a/biometrics/face/aidl/default/Session.h +++ b/biometrics/face/aidl/default/Session.h @@ -34,10 +34,10 @@ class Session : public BnSession { ndk::ScopedAStatus revokeChallenge(int32_t cookie, int64_t challenge) override; - ndk::ScopedAStatus enroll( - int32_t cookie, biometrics::face::EnrollmentType enrollmentType, - const keymaster::HardwareAuthToken& hat, const NativeHandle& previewSurface, - std::shared_ptr<biometrics::common::ICancellationSignal>* return_val) override; + ndk::ScopedAStatus enroll(int32_t cookie, const keymaster::HardwareAuthToken& hat, + EnrollmentType enrollmentType, const std::vector<Feature>& features, + const NativeHandle& previewSurface, + std::shared_ptr<common::ICancellationSignal>* return_val) override; ndk::ScopedAStatus authenticate( int32_t cookie, int64_t keystoreOperationId, @@ -51,6 +51,11 @@ class Session : public BnSession { ndk::ScopedAStatus removeEnrollments(int32_t cookie, const std::vector<int32_t>& enrollmentIds) override; + ndk::ScopedAStatus getFeatures(int32_t cookie, int32_t enrollmentId) override; + + ndk::ScopedAStatus setFeature(int32_t cookie, const keymaster::HardwareAuthToken& hat, + int32_t enrollmentId, Feature feature, bool enabled) override; + ndk::ScopedAStatus getAuthenticatorId(int32_t cookie) override; ndk::ScopedAStatus invalidateAuthenticatorId(int32_t cookie) override; diff --git a/biometrics/face/aidl/vts/Android.bp b/biometrics/face/aidl/vts/Android.bp index 427b8785fb..a4c76f573a 100644 --- a/biometrics/face/aidl/vts/Android.bp +++ b/biometrics/face/aidl/vts/Android.bp @@ -7,7 +7,7 @@ cc_test { srcs: ["VtsHalBiometricsFaceTargetTest.cpp"], shared_libs: [ "libbinder_ndk", - "android.hardware.biometrics.face-ndk_platform", + "android.hardware.biometrics.face-V1-ndk_platform", ], test_suites: [ "general-tests", diff --git a/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp b/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp index 5b02a57ce8..4cc8b4afa0 100644 --- a/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp +++ b/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp @@ -103,6 +103,15 @@ class SessionCallback : public BnSessionCallback { return ndk::ScopedAStatus::ok(); } + ndk::ScopedAStatus onFeaturesRetrieved(const std::vector<Feature>& /*features*/, + int32_t /*enrollmentId*/) override { + return ndk::ScopedAStatus::ok(); + } + + ndk::ScopedAStatus onFeatureSet(int32_t /*enrollmentId*/, Feature /*feature*/) override { + return ndk::ScopedAStatus::ok(); + } + ndk::ScopedAStatus onAuthenticatorIdRetrieved(int64_t /*authenticatorId*/) override { return ndk::ScopedAStatus::ok(); } diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl index d5f2ed27c6..189095a7d7 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// @@ -27,4 +41,6 @@ enum AcquiredInfo { TOO_FAST = 5, VENDOR = 6, START = 7, + TOO_DARK = 8, + TOO_BRIGHT = 9, } diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl index aec499f229..cdbc2d2f67 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl index 784e1d0d2f..c81cad2971 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl index 51b4c63799..c5a5422d24 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl index 185d86ff24..be0029c53b 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl index cf663a5670..f20f15324e 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl index f8a40a964f..c3daacd5de 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// @@ -26,4 +40,5 @@ parcelable SensorProps { int sensorLocationY; int sensorRadius; int displayId; + boolean supportsDetectInteraction; } diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl index 3453f93763..44323ffb1d 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl index adb1c78cb2..3709a64b78 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl @@ -63,5 +63,17 @@ enum AcquiredInfo { * latency based on the time between the last START message and the onAuthenticated callback. */ START, + + /** + * For sensors that require illumination, such as optical under-display fingerprint sensors, + * the image was too dark to be used for matching. + */ + TOO_DARK, + + /** + * For sensors that require illumination, such as optical under-display fingerprint sensors, + * the image was too bright to be used for matching. + */ + TOO_BRIGHT, } diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl index 09bd04d4ef..f9c3732ac4 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl @@ -191,7 +191,9 @@ interface ISession { /** * detectInteraction: * - * A request to start looking for fingerprints without performing matching. + * A request to start looking for fingerprints without performing matching. Must only be called + * if SensorProps#supportsDetectInteraction is true. If invoked on implementations that do not + * support this functionality, the HAL must respond with ISession#onError(UNABLE_TO_PROCESS, 0). * * Once the HAL is able to start processing this request, it must notify the framework via * ISessionCallback#onStateChanged with SessionState::DETECTING_INTERACTION. diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl index ab70a5801c..afed175bbb 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl @@ -63,5 +63,10 @@ parcelable SensorProps { * android.hardware.DisplayManager#getDisplay Android API. */ int displayId; + + /** + * Specifies whether or not the implementation supports ISession#detectInteraction. + */ + boolean supportsDetectInteraction; } diff --git a/biometrics/fingerprint/aidl/default/Android.bp b/biometrics/fingerprint/aidl/default/Android.bp index ce1ff5964b..c8cb663686 100644 --- a/biometrics/fingerprint/aidl/default/Android.bp +++ b/biometrics/fingerprint/aidl/default/Android.bp @@ -7,8 +7,8 @@ cc_binary { shared_libs: [ "libbase", "libbinder_ndk", - "android.hardware.biometrics.fingerprint-ndk_platform", - "android.hardware.biometrics.common-unstable-ndk_platform", + "android.hardware.biometrics.fingerprint-V1-ndk_platform", + "android.hardware.biometrics.common-V1-ndk_platform", ], srcs: [ "main.cpp", diff --git a/biometrics/fingerprint/aidl/vts/Android.bp b/biometrics/fingerprint/aidl/vts/Android.bp index b441eb3bcb..07bccb5965 100644 --- a/biometrics/fingerprint/aidl/vts/Android.bp +++ b/biometrics/fingerprint/aidl/vts/Android.bp @@ -7,7 +7,7 @@ cc_test { srcs: ["VtsHalBiometricsFingerprintTargetTest.cpp"], shared_libs: [ "libbinder_ndk", - "android.hardware.biometrics.fingerprint-ndk_platform", + "android.hardware.biometrics.fingerprint-V1-ndk_platform", ], test_suites: [ "general-tests", diff --git a/camera/provider/2.4/default/service.cpp b/camera/provider/2.4/default/service.cpp index 84f48393fa..0a4f7874a6 100644 --- a/camera/provider/2.4/default/service.cpp +++ b/camera/provider/2.4/default/service.cpp @@ -22,9 +22,9 @@ #include <android/hardware/camera/provider/2.4/ICameraProvider.h> #include <binder/ProcessState.h> -#include <cutils/memory.h> #include <cutils/properties.h> #include <hidl/LegacySupport.h> +#include <malloc.h> using android::status_t; using android::hardware::defaultLazyPassthroughServiceImplementation; @@ -46,7 +46,13 @@ int main() // b/166675194 if (property_get_bool("ro.vendor.camera.provider24.disable_mem_init", false)) { - process_disable_memory_mitigations(); + if (mallopt(M_BIONIC_ZERO_INIT, 0) == 0) { + // Note - heap initialization is only present on devices with Scudo. + // Devices with jemalloc don't have heap-init, and thus the mallopt + // will fail. On these devices, you probably just want to remove the + // property. + ALOGE("Disabling heap initialization failed."); + } } status_t status; diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp index 9e2b077c5a..d6213448ea 100644 --- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp +++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp @@ -888,6 +888,8 @@ public: static Status getSystemCameraKind(const camera_metadata_t* staticMeta, SystemCameraKind* systemCameraKind); + static V3_2::DataspaceFlags getDataspace(PixelFormat format); + void processCaptureRequestInternal(uint64_t bufferusage, RequestTemplate reqTemplate, bool useSecureOnlyCameras); @@ -3196,7 +3198,6 @@ TEST_P(CameraHidlTest, constructDefaultRequestSettings) { } } - // Verify that all supported stream formats and sizes can be configured // successfully. TEST_P(CameraHidlTest, configureStreamsAvailableOutputs) { @@ -3239,17 +3240,7 @@ TEST_P(CameraHidlTest, configureStreamsAvailableOutputs) { uint32_t streamConfigCounter = 0; for (auto& it : outputStreams) { V3_2::Stream stream3_2; - V3_2::DataspaceFlags dataspaceFlag = 0; - switch (static_cast<PixelFormat>(it.format)) { - case PixelFormat::BLOB: - dataspaceFlag = static_cast<V3_2::DataspaceFlags>(Dataspace::V0_JFIF); - break; - case PixelFormat::Y16: - dataspaceFlag = static_cast<V3_2::DataspaceFlags>(Dataspace::DEPTH); - break; - default: - dataspaceFlag = static_cast<V3_2::DataspaceFlags>(Dataspace::UNKNOWN); - } + V3_2::DataspaceFlags dataspaceFlag = getDataspace(static_cast<PixelFormat>(it.format)); stream3_2 = {streamId, StreamType::OUTPUT, static_cast<uint32_t>(it.width), @@ -3369,17 +3360,8 @@ TEST_P(CameraHidlTest, configureConcurrentStreamsAvailableOutputs) { size_t j = 0; for (const auto& it : outputStreams) { V3_2::Stream stream3_2; - V3_2::DataspaceFlags dataspaceFlag = 0; - switch (static_cast<PixelFormat>(it.format)) { - case PixelFormat::BLOB: - dataspaceFlag = static_cast<V3_2::DataspaceFlags>(Dataspace::V0_JFIF); - break; - case PixelFormat::Y16: - dataspaceFlag = static_cast<V3_2::DataspaceFlags>(Dataspace::DEPTH); - break; - default: - dataspaceFlag = static_cast<V3_2::DataspaceFlags>(Dataspace::UNKNOWN); - } + V3_2::DataspaceFlags dataspaceFlag = getDataspace( + static_cast<PixelFormat>(it.format)); stream3_2 = {streamId++, StreamType::OUTPUT, static_cast<uint32_t>(it.width), @@ -5919,6 +5901,23 @@ Status CameraHidlTest::getSystemCameraKind(const camera_metadata_t* staticMeta, return ret; } +// Select an appropriate dataspace given a specific pixel format. +V3_2::DataspaceFlags CameraHidlTest::getDataspace(PixelFormat format) { + switch (format) { + case PixelFormat::BLOB: + return static_cast<V3_2::DataspaceFlags>(Dataspace::V0_JFIF); + case PixelFormat::Y16: + return static_cast<V3_2::DataspaceFlags>(Dataspace::DEPTH); + case PixelFormat::RAW16: + case PixelFormat::RAW_OPAQUE: + case PixelFormat::RAW10: + case PixelFormat::RAW12: + return static_cast<V3_2::DataspaceFlags>(Dataspace::ARBITRARY); + default: + return static_cast<V3_2::DataspaceFlags>(Dataspace::UNKNOWN); + } +} + // Check whether this is a monochrome camera using the static camera characteristics. Status CameraHidlTest::isMonochromeCamera(const camera_metadata_t *staticMeta) { Status ret = Status::METHOD_NOT_SUPPORTED; @@ -6293,17 +6292,8 @@ void CameraHidlTest::configureOfflineStillStream(const std::string &name, ASSERT_EQ(Status::OK, rc); ASSERT_FALSE(outputStreams.empty()); - V3_2::DataspaceFlags dataspaceFlag = 0; - switch (static_cast<PixelFormat>(outputStreams[idx].format)) { - case PixelFormat::BLOB: - dataspaceFlag = static_cast<V3_2::DataspaceFlags>(Dataspace::V0_JFIF); - break; - case PixelFormat::Y16: - dataspaceFlag = static_cast<V3_2::DataspaceFlags>(Dataspace::DEPTH); - break; - default: - dataspaceFlag = static_cast<V3_2::DataspaceFlags>(Dataspace::UNKNOWN); - } + V3_2::DataspaceFlags dataspaceFlag = getDataspace( + static_cast<PixelFormat>(outputStreams[idx].format)); ::android::hardware::hidl_vec<V3_4::Stream> streams3_4(/*size*/1); V3_4::Stream stream3_4 = {{ 0 /*streamId*/, StreamType::OUTPUT, diff --git a/cas/1.0/default/Android.bp b/cas/1.0/default/Android.bp index 3891a0e075..f968ee1b1f 100644 --- a/cas/1.0/default/Android.bp +++ b/cas/1.0/default/Android.bp @@ -12,7 +12,7 @@ cc_defaults { "TypeConvert.cpp", ], - compile_multilib: "32", + compile_multilib: "prefer32", shared_libs: [ "android.hardware.cas@1.0", diff --git a/cas/1.0/default/FactoryLoader.h b/cas/1.0/default/FactoryLoader.h index 18c2186dcb..45e515afbf 100644 --- a/cas/1.0/default/FactoryLoader.h +++ b/cas/1.0/default/FactoryLoader.h @@ -92,7 +92,12 @@ bool FactoryLoader<T>::findFactoryForScheme( } // no luck, have to search +#ifdef __LP64__ + String8 dirPath("/vendor/lib64/mediacas"); +#else String8 dirPath("/vendor/lib/mediacas"); +#endif + DIR* pDir = opendir(dirPath.string()); if (pDir == NULL) { @@ -127,7 +132,12 @@ bool FactoryLoader<T>::enumeratePlugins( results->clear(); +#ifdef __LP64__ + String8 dirPath("/vendor/lib64/mediacas"); +#else String8 dirPath("/vendor/lib/mediacas"); +#endif + DIR* pDir = opendir(dirPath.string()); if (pDir == NULL) { diff --git a/cas/1.1/default/Android.bp b/cas/1.1/default/Android.bp index 66a1eb8804..8e1f20772d 100644 --- a/cas/1.1/default/Android.bp +++ b/cas/1.1/default/Android.bp @@ -12,7 +12,7 @@ cc_defaults { "TypeConvert.cpp", ], - compile_multilib: "32", + compile_multilib: "prefer32", shared_libs: [ "android.hardware.cas@1.0", diff --git a/cas/1.1/default/FactoryLoader.h b/cas/1.1/default/FactoryLoader.h index c4a48e2852..121f90c333 100644 --- a/cas/1.1/default/FactoryLoader.h +++ b/cas/1.1/default/FactoryLoader.h @@ -85,7 +85,11 @@ bool FactoryLoader<T>::findFactoryForScheme(int32_t CA_system_id, sp<SharedLibra } // no luck, have to search +#ifdef __LP64__ + String8 dirPath("/vendor/lib64/mediacas"); +#else String8 dirPath("/vendor/lib/mediacas"); +#endif DIR* pDir = opendir(dirPath.string()); if (pDir == NULL) { @@ -118,7 +122,11 @@ bool FactoryLoader<T>::enumeratePlugins(vector<HidlCasPluginDescriptor>* results results->clear(); +#ifdef __LP64__ + String8 dirPath("/vendor/lib64/mediacas"); +#else String8 dirPath("/vendor/lib/mediacas"); +#endif DIR* pDir = opendir(dirPath.string()); if (pDir == NULL) { diff --git a/cas/1.2/default/Android.bp b/cas/1.2/default/Android.bp index 9e5314874f..d855e85a67 100644 --- a/cas/1.2/default/Android.bp +++ b/cas/1.2/default/Android.bp @@ -12,7 +12,7 @@ cc_defaults { "TypeConvert.cpp", ], - compile_multilib: "32", + compile_multilib: "prefer32", shared_libs: [ "android.hardware.cas@1.0", diff --git a/cas/1.2/default/FactoryLoader.h b/cas/1.2/default/FactoryLoader.h index 7403f86ac9..a374b31891 100644 --- a/cas/1.2/default/FactoryLoader.h +++ b/cas/1.2/default/FactoryLoader.h @@ -85,7 +85,11 @@ bool FactoryLoader<T>::findFactoryForScheme(int32_t CA_system_id, sp<SharedLibra } // no luck, have to search +#ifdef __LP64__ + String8 dirPath("/vendor/lib64/mediacas"); +#else String8 dirPath("/vendor/lib/mediacas"); +#endif DIR* pDir = opendir(dirPath.string()); if (pDir == NULL) { @@ -118,7 +122,11 @@ bool FactoryLoader<T>::enumeratePlugins(vector<HidlCasPluginDescriptor>* results results->clear(); +#ifdef __LP64__ + String8 dirPath("/vendor/lib64/mediacas"); +#else String8 dirPath("/vendor/lib/mediacas"); +#endif DIR* pDir = opendir(dirPath.string()); if (pDir == NULL) { diff --git a/common/fmq/aidl/Android.bp b/common/fmq/aidl/Android.bp index 004adab514..9389712733 100644 --- a/common/fmq/aidl/Android.bp +++ b/common/fmq/aidl/Android.bp @@ -9,6 +9,9 @@ aidl_interface { srcs: [ "android/hardware/common/fmq/*.aidl", ], + imports: [ + "android.hardware.common", + ], stability: "vintf", backend: { java: { diff --git a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/GrantorDescriptor.aidl b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/GrantorDescriptor.aidl index 7ac1930715..03277964ae 100644 --- a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/GrantorDescriptor.aidl +++ b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/GrantorDescriptor.aidl @@ -2,13 +2,14 @@ // 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. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m <name>-update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file 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 @@ -18,6 +19,7 @@ package android.hardware.common.fmq; @VintfStability parcelable GrantorDescriptor { + int fdIndex; int offset; long extent; } diff --git a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/MQDescriptor.aidl b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/MQDescriptor.aidl index 26073691f1..56f1de3cd8 100644 --- a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/MQDescriptor.aidl +++ b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/MQDescriptor.aidl @@ -2,13 +2,14 @@ // 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. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m <name>-update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file 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 @@ -19,7 +20,7 @@ package android.hardware.common.fmq; @VintfStability parcelable MQDescriptor { android.hardware.common.fmq.GrantorDescriptor[] grantors; - ParcelFileDescriptor fileDescriptor; + android.hardware.common.NativeHandle handle; int quantum; int flags; } diff --git a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/SynchronizedReadWrite.aidl b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/SynchronizedReadWrite.aidl index 2142bdbd13..264171dca1 100644 --- a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/SynchronizedReadWrite.aidl +++ b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/SynchronizedReadWrite.aidl @@ -2,13 +2,14 @@ // 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. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m <name>-update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file 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 diff --git a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/UnsynchronizedWrite.aidl b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/UnsynchronizedWrite.aidl index 1220674e13..eaf2ffdd16 100644 --- a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/UnsynchronizedWrite.aidl +++ b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/UnsynchronizedWrite.aidl @@ -2,13 +2,14 @@ // 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. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m <name>-update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file 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 diff --git a/common/fmq/aidl/android/hardware/common/fmq/GrantorDescriptor.aidl b/common/fmq/aidl/android/hardware/common/fmq/GrantorDescriptor.aidl index ca69d94d55..672415e65a 100644 --- a/common/fmq/aidl/android/hardware/common/fmq/GrantorDescriptor.aidl +++ b/common/fmq/aidl/android/hardware/common/fmq/GrantorDescriptor.aidl @@ -22,6 +22,10 @@ package android.hardware.common.fmq; @VintfStability parcelable GrantorDescriptor { /* + * Index of file descriptor for this grantor + */ + int fdIndex; + /* * The offset of this descriptor in the shared memory in bytes. */ int offset; diff --git a/common/fmq/aidl/android/hardware/common/fmq/MQDescriptor.aidl b/common/fmq/aidl/android/hardware/common/fmq/MQDescriptor.aidl index 82917d6fbe..46622f00a9 100644 --- a/common/fmq/aidl/android/hardware/common/fmq/MQDescriptor.aidl +++ b/common/fmq/aidl/android/hardware/common/fmq/MQDescriptor.aidl @@ -16,6 +16,7 @@ package android.hardware.common.fmq; +import android.hardware.common.NativeHandle; import android.hardware.common.fmq.GrantorDescriptor; /* @@ -34,8 +35,11 @@ parcelable MQDescriptor<T, Flavor> { * for blocking operations in the shared memory. */ GrantorDescriptor[] grantors; - /* File descriptor for shared memory used in the message queue */ - ParcelFileDescriptor fileDescriptor; + /* + * NativeHandle that contains the file descriptors for shared memory used + * in the message queue + */ + NativeHandle handle; /* Size of each item, T, in bytes */ int quantum; /* EventFlag word for blocking operations */ diff --git a/common/support/Android.bp b/common/support/Android.bp index 3bb48049f3..ce3aa3fbd6 100644 --- a/common/support/Android.bp +++ b/common/support/Android.bp @@ -6,7 +6,7 @@ cc_library_static { srcs: ["NativeHandle.cpp"], export_include_dirs: ["include"], shared_libs: [ - "android.hardware.common-unstable-ndk_platform", + "android.hardware.common-V2-ndk_platform", "libcutils", ], } @@ -17,10 +17,10 @@ cc_test { defaults: ["libbinder_ndk_host_user"], srcs: ["test.cpp"], static_libs: [ + "android.hardware.common-V2-ndk_platform", "libaidlcommonsupport", ], shared_libs: [ - "android.hardware.common-unstable-ndk_platform", "libcutils", ], test_suites: ["general-tests"], diff --git a/compatibility_matrices/compatibility_matrix.3.xml b/compatibility_matrices/compatibility_matrix.3.xml index 5888ab9d86..608890bcf1 100644 --- a/compatibility_matrices/compatibility_matrix.3.xml +++ b/compatibility_matrices/compatibility_matrix.3.xml @@ -310,6 +310,10 @@ <instance>slot2</instance> <instance>slot3</instance> </interface> + </hal> + <hal format="hidl" optional="true"> + <name>android.hardware.radio</name> + <version>1.0-2</version> <interface> <name>ISap</name> <instance>slot1</instance> diff --git a/compatibility_matrices/compatibility_matrix.4.xml b/compatibility_matrices/compatibility_matrix.4.xml index c362b026ce..9f486ddf36 100644 --- a/compatibility_matrices/compatibility_matrix.4.xml +++ b/compatibility_matrices/compatibility_matrix.4.xml @@ -432,7 +432,6 @@ <hal format="hidl" optional="true"> <name>android.hardware.tv.cec</name> <version>1.0</version> - <version>2.0</version> <interface> <name>IHdmiCec</name> <instance>default</instance> diff --git a/compatibility_matrices/compatibility_matrix.5.xml b/compatibility_matrices/compatibility_matrix.5.xml index d7e8215577..53b9be83b5 100644 --- a/compatibility_matrices/compatibility_matrix.5.xml +++ b/compatibility_matrices/compatibility_matrix.5.xml @@ -467,7 +467,6 @@ <hal format="hidl" optional="true"> <name>android.hardware.tv.cec</name> <version>1.0</version> - <version>2.0</version> <interface> <name>IHdmiCec</name> <instance>default</instance> diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index c616f8700a..8b94636c15 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -73,6 +73,7 @@ </hal> <hal format="aidl" optional="true"> <name>android.hardware.automotive.occupant_awareness</name> + <version>1</version> <interface> <name>IOccupantAwareness</name> <instance>default</instance> @@ -82,7 +83,7 @@ <name>android.hardware.automotive.sv</name> <version>1.0</version> <interface> - <name>ISurroundView</name> + <name>ISurroundViewService</name> <instance>default</instance> </interface> </hal> @@ -227,7 +228,6 @@ <hal format="hidl" optional="true"> <name>android.hardware.gnss</name> <version>2.0-1</version> - <version>3.0</version> <interface> <name>IGnss</name> <instance>default</instance> @@ -278,14 +278,6 @@ <instance>default</instance> </interface> </hal> - <hal format="hidl" optional="true"> - <name>android.hardware.health.storage</name> - <version>1.0</version> - <interface> - <name>IStorage</name> - <instance>default</instance> - </interface> - </hal> <hal format="aidl" optional="true"> <name>android.hardware.health.storage</name> <version>1</version> @@ -296,7 +288,7 @@ </hal> <hal format="aidl" optional="true"> <name>android.hardware.identity</name> - <version>1-2</version> + <version>1-3</version> <interface> <name>IIdentityCredentialStore</name> <instance>default</instance> @@ -345,6 +337,7 @@ </hal> <hal format="aidl" optional="true"> <name>android.hardware.security.keymint</name> + <version>1</version> <interface> <name>IKeyMintDevice</name> <instance>default</instance> @@ -353,6 +346,7 @@ </hal> <hal format="aidl" optional="true"> <name>android.hardware.light</name> + <version>1</version> <interface> <name>ILights</name> <instance>default</instance> @@ -381,6 +375,7 @@ </hal> <hal format="aidl" optional="true"> <name>android.hardware.memtrack</name> + <version>1</version> <interface> <name>IMemtrack</name> <instance>default</instance> @@ -420,6 +415,7 @@ </hal> <hal format="aidl" optional="false"> <name>android.hardware.power</name> + <version>1</version> <interface> <name>IPower</name> <instance>default</instance> @@ -479,6 +475,7 @@ </hal> <hal format="aidl" optional="true"> <name>android.hardware.rebootescrow</name> + <version>1</version> <interface> <name>IRebootEscrow</name> <instance>default</instance> @@ -495,6 +492,7 @@ </hal> <hal format="aidl" optional="true"> <name>android.hardware.security.secureclock</name> + <version>1</version> <interface> <name>ISecureClock</name> <instance>default</instance> @@ -502,6 +500,7 @@ </hal> <hal format="aidl" optional="true"> <name>android.hardware.security.sharedsecret</name> + <version>1</version> <interface> <name>ISharedSecret</name> <instance>default</instance> @@ -518,7 +517,7 @@ </hal> <hal format="hidl" optional="true"> <name>android.hardware.soundtrigger</name> - <version>2.0-3</version> + <version>2.3</version> <interface> <name>ISoundTriggerHw</name> <instance>default</instance> @@ -534,7 +533,7 @@ </hal> <hal format="hidl" optional="true"> <name>android.hardware.tetheroffload.control</name> - <version>1.0</version> + <version>1.1</version> <interface> <name>IOffloadControl</name> <instance>default</instance> @@ -551,7 +550,6 @@ <hal format="hidl" optional="true"> <name>android.hardware.tv.cec</name> <version>1.0</version> - <version>2.0</version> <interface> <name>IHdmiCec</name> <instance>default</instance> @@ -613,6 +611,14 @@ <instance>default</instance> </interface> </hal> + <hal format="aidl" optional="true"> + <name>android.hardware.weaver</name> + <version>1</version> + <interface> + <name>IWeaver</name> + <instance>default</instance> + </interface> + </hal> <hal format="hidl" optional="true"> <name>android.hardware.wifi</name> <version>1.3-5</version> diff --git a/compatibility_matrices/exclude/fcm_exclude.cpp b/compatibility_matrices/exclude/fcm_exclude.cpp index 6725a9884c..e67c892523 100644 --- a/compatibility_matrices/exclude/fcm_exclude.cpp +++ b/compatibility_matrices/exclude/fcm_exclude.cpp @@ -67,7 +67,7 @@ bool ShouldCheckMissingHalsInFcm(const std::string& package) { // TODO(b/171260360) Remove when HAL definition is removed "android.hardware.audio.effect@2.0", "android.hardware.audio@2.0", - // TODO(b/171260613) Remove when HAL definition is removed + // Health 1.0 HAL is deprecated. The top level interface are deleted. "android.hardware.health@1.0", // TODO(b/171260670) Remove when HAL definition is removed "android.hardware.nfc@1.0", diff --git a/drm/1.0/default/Android.bp b/drm/1.0/default/Android.bp index 93b3278a91..d5063fb2f9 100644 --- a/drm/1.0/default/Android.bp +++ b/drm/1.0/default/Android.bp @@ -46,7 +46,7 @@ soong_config_module_type { android_hardware_drm_1_0_multilib { name: "android.hardware.drm@1.0-multilib-lib", - compile_multilib: "32", + compile_multilib: "prefer32", soong_config_variables: { TARGET_ENABLE_MEDIADRM_64: { compile_multilib: "both", @@ -56,7 +56,7 @@ android_hardware_drm_1_0_multilib { android_hardware_drm_1_0_multilib { name: "android.hardware.drm@1.0-multilib-exe", - compile_multilib: "32", + compile_multilib: "prefer32", soong_config_variables: { TARGET_ENABLE_MEDIADRM_64: { compile_multilib: "first", diff --git a/drm/1.0/default/CryptoPlugin.cpp b/drm/1.0/default/CryptoPlugin.cpp index 2db360765b..e6d4e8447b 100644 --- a/drm/1.0/default/CryptoPlugin.cpp +++ b/drm/1.0/default/CryptoPlugin.cpp @@ -124,7 +124,11 @@ namespace implementation { return Void(); } - if (source.offset + offset + source.size > sourceBase->getSize()) { + size_t totalSize = 0; + if (__builtin_add_overflow(source.offset, offset, &totalSize) || + __builtin_add_overflow(totalSize, source.size, &totalSize) || + totalSize > sourceBase->getSize()) { + android_errorWriteLog(0x534e4554, "176496160"); _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size"); return Void(); } diff --git a/drm/1.4/Android.bp b/drm/1.4/Android.bp index 8e1dc93c9f..f40ff87b13 100644 --- a/drm/1.4/Android.bp +++ b/drm/1.4/Android.bp @@ -8,6 +8,7 @@ hidl_interface { "ICryptoPlugin.hal", "IDrmFactory.hal", "IDrmPlugin.hal", + "types.hal", ], interfaces: [ "android.hardware.drm@1.0", diff --git a/drm/1.4/ICryptoPlugin.hal b/drm/1.4/ICryptoPlugin.hal index 874ef4cd3b..addfdd08d9 100644 --- a/drm/1.4/ICryptoPlugin.hal +++ b/drm/1.4/ICryptoPlugin.hal @@ -16,6 +16,8 @@ package android.hardware.drm@1.4; import @1.2::ICryptoPlugin; +import @1.4::LogMessage; +import @1.4::Status; /** * ICryptoPlugin is the HAL for vendor-provided crypto plugins. @@ -23,4 +25,15 @@ import @1.2::ICryptoPlugin; * load crypto keys for a codec to decrypt protected video content. */ interface ICryptoPlugin extends @1.2::ICryptoPlugin { + + /** + * @return logMessages latest plugin level log messages. Can be used + * by apps in diagnosis of errors. + * @return status the status of the call. The status must be: + * OK on success; + * GENERAL_OEM_ERROR on OEM-provided, low-level component failures; + * GENERAL_PLUGIN_ERROR on unexpected plugin-level errors. + */ + getLogMessages() generates (@1.4::Status status, vec<LogMessage> logMessages); + }; diff --git a/drm/1.4/IDrmPlugin.hal b/drm/1.4/IDrmPlugin.hal index e8af230033..df04b9f226 100644 --- a/drm/1.4/IDrmPlugin.hal +++ b/drm/1.4/IDrmPlugin.hal @@ -19,6 +19,8 @@ import @1.0::Status; import @1.0::SessionId; import @1.1::SecurityLevel; import @1.2::IDrmPlugin; +import @1.4::LogMessage; +import @1.4::Status; /** * IDrmPlugin is used to interact with a specific drm plugin that was @@ -61,4 +63,14 @@ interface IDrmPlugin extends @1.2::IDrmPlugin { */ setPlaybackId(SessionId sessionId, string playbackId) generates (@1.0::Status status); + /** + * @return logMessages latest plugin level log messages. Can be used + * by apps in diagnosis of errors. + * @return status the status of the call. The status must be: + * OK on success; + * GENERAL_OEM_ERROR on OEM-provided, low-level component failures; + * GENERAL_PLUGIN_ERROR on unexpected plugin-level errors. + */ + getLogMessages() generates (@1.4::Status status, vec<LogMessage> logMessages); + }; diff --git a/drm/1.4/types.hal b/drm/1.4/types.hal new file mode 100644 index 0000000000..706c3aa92a --- /dev/null +++ b/drm/1.4/types.hal @@ -0,0 +1,51 @@ +/** + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.drm@1.4; + +import @1.2::Status; + +enum LogPriority : uint32_t { + ERROR, + WARN, + INFO, + DEBUG, + VERBOSE +}; + +/** + * Returned by getLogMessages to report error diagnostics to the + * app. + */ +struct LogMessage { + int64_t timeMs; + LogPriority priority; + string message; +}; + +enum Status : @1.2::Status { + + /** + * Non-specific error reported by the device OEM subsystem. + */ + GENERAL_OEM_ERROR, + + /** + * Unexpected internal failure in the drm/crypto plugin. + */ + GENERAL_PLUGIN_ERROR, + +}; diff --git a/gnss/1.1/default/Android.bp b/gnss/1.1/default/Android.bp index ef43a34947..6853ad948d 100644 --- a/gnss/1.1/default/Android.bp +++ b/gnss/1.1/default/Android.bp @@ -18,7 +18,7 @@ cc_binary { "android.hardware.gnss@2.0", "android.hardware.gnss@1.1", "android.hardware.gnss@1.0", - "android.hardware.gnss-ndk_platform", + "android.hardware.gnss-V1-ndk_platform", ], static_libs: [ "android.hardware.gnss@common-default-lib", diff --git a/gnss/2.0/default/Android.bp b/gnss/2.0/default/Android.bp index 7da462f977..be0455365d 100644 --- a/gnss/2.0/default/Android.bp +++ b/gnss/2.0/default/Android.bp @@ -41,7 +41,7 @@ cc_binary { "android.hardware.gnss@2.0", "android.hardware.gnss@1.1", "android.hardware.gnss@1.0", - "android.hardware.gnss-ndk_platform", + "android.hardware.gnss-V1-ndk_platform", ], static_libs: [ "android.hardware.gnss@common-default-lib", diff --git a/gnss/2.1/default/Android.bp b/gnss/2.1/default/Android.bp index 63e5013276..7c4b9c6fc5 100644 --- a/gnss/2.1/default/Android.bp +++ b/gnss/2.1/default/Android.bp @@ -34,7 +34,7 @@ cc_binary { "android.hardware.gnss@1.0", "android.hardware.gnss@1.1", "android.hardware.gnss@2.0", - "android.hardware.gnss-ndk_platform", + "android.hardware.gnss-V1-ndk_platform", ], static_libs: [ "android.hardware.gnss@common-default-lib", diff --git a/gnss/3.0/Android.bp b/gnss/3.0/Android.bp deleted file mode 100644 index dada17ced7..0000000000 --- a/gnss/3.0/Android.bp +++ /dev/null @@ -1,22 +0,0 @@ -// This file is autogenerated by hidl-gen -Landroidbp. - -hidl_interface { - name: "android.hardware.gnss@3.0", - root: "android.hardware", - srcs: [ - "IGnss.hal", - "IGnssPsds.hal", - "IGnssPsdsCallback.hal", - ], - interfaces: [ - "android.hardware.gnss.measurement_corrections@1.0", - "android.hardware.gnss.measurement_corrections@1.1", - "android.hardware.gnss.visibility_control@1.0", - "android.hardware.gnss@1.0", - "android.hardware.gnss@1.1", - "android.hardware.gnss@2.0", - "android.hardware.gnss@2.1", - "android.hidl.base@1.0", - ], - gen_java: true, -} diff --git a/gnss/3.0/IGnssPsds.hal b/gnss/3.0/IGnssPsds.hal deleted file mode 100644 index 5004570574..0000000000 --- a/gnss/3.0/IGnssPsds.hal +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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@3.0; - -import @1.0::IGnssXtra; -import IGnssPsdsCallback; - -/** - * This interface is used by the GNSS HAL to request the framework to download Predicted Satellite - * Data Service data. - */ -interface IGnssPsds extends @1.0::IGnssXtra { - /** - * Opens the PSDS interface and provides the callback routines to the implementation of this - * interface. - * - * @param callback Handle to the IGnssPsdsCallback interface. - * - * @return success True if the operation is successful. - */ - setCallback_3_0(IGnssPsdsCallback callback) generates (bool success); - - /** - * Inject the downloaded PSDS data into the GNSS receiver. - * - * @param psdsType Type of PSDS as defined in IGnssPsdsCallback.hal - * @param psdsData GNSS PSDS data. Framework must not parse the data since the data format is - * opaque to framework. - * - * @return success True if the operation is successful. - */ - injectPsdsData_3_0(int32_t psdsType, string psdsData) generates (bool success); -}; - diff --git a/gnss/3.0/IGnssPsdsCallback.hal b/gnss/3.0/IGnssPsdsCallback.hal deleted file mode 100644 index d91385f814..0000000000 --- a/gnss/3.0/IGnssPsdsCallback.hal +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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@3.0; - -import @1.0::IGnssXtraCallback; - -/** - * This interface is used by the GNSS HAL to request download data from Predicted Satellite Data - * Service (PSDS). - */ -interface IGnssPsdsCallback extends @1.0::IGnssXtraCallback { - /** - * Callback to request the client to download PSDS data. The client should - * download PSDS data and inject it by calling injectPsdsData(). - * - * psdsType represents the type of PSDS data requested. - * - Value 1 represents the 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. - * - Value 2 represents the 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. - * - Value 3 represents the 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. - */ - downloadRequestCb_3_0(int32_t psdsType); -}; diff --git a/gnss/3.0/default/Android.bp b/gnss/3.0/default/Android.bp deleted file mode 100644 index bb3c467923..0000000000 --- a/gnss/3.0/default/Android.bp +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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@3.0-service", - init_rc: ["android.hardware.gnss@3.0-service.rc"], - relative_install_path: "hw", - vendor: true, - vintf_fragments: ["android.hardware.gnss@3.0-service.xml"], - srcs: [ - "Gnss.cpp", - "GnssPsds.cpp", - "service.cpp", - ], - shared_libs: [ - "libhidlbase", - "libutils", - "liblog", - "android.hardware.gnss@1.0", - "android.hardware.gnss@1.1", - "android.hardware.gnss@2.0", - "android.hardware.gnss@2.1", - "android.hardware.gnss@3.0", - "android.hardware.gnss.measurement_corrections@1.1", - "android.hardware.gnss.measurement_corrections@1.0", - "android.hardware.gnss-ndk_platform", - ], - static_libs: [ - "android.hardware.gnss@common-default-lib", - ], -} diff --git a/gnss/3.0/default/Gnss.h b/gnss/3.0/default/Gnss.h deleted file mode 100644 index 7ae562ade3..0000000000 --- a/gnss/3.0/default/Gnss.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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/gnss/3.0/IGnss.h> -#include <hidl/MQDescriptor.h> -#include <hidl/Status.h> -#include <atomic> -#include <mutex> -#include <thread> -#include "v2_1/GnssTemplate.h" - -namespace android::hardware::gnss::V3_0::implementation { - -using ::android::sp; -using ::android::hardware::Return; -using ::android::hardware::Void; -using ::android::hardware::gnss::common::implementation::GnssTemplate; - -struct Gnss : public GnssTemplate<IGnss> { - Gnss(){}; - ~Gnss(){}; - - // Methods from V3_0::IGnss follow. - Return<sp<V3_0::IGnssPsds>> getExtensionPsds() override; -}; - -} // namespace android::hardware::gnss::V3_0::implementation diff --git a/gnss/3.0/default/GnssPsds.cpp b/gnss/3.0/default/GnssPsds.cpp deleted file mode 100644 index 44e096ebd3..0000000000 --- a/gnss/3.0/default/GnssPsds.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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 "GnssPsds" - -#include "GnssPsds.h" - -#include <log/log.h> - -namespace android::hardware::gnss::V3_0::implementation { - -sp<V3_0::IGnssPsdsCallback> GnssPsds::sCallback_3_0 = nullptr; - -// Methods from V1_0::IGnssXtra follow. -Return<bool> GnssPsds::setCallback(const sp<V1_0::IGnssXtraCallback>&) { - // TODO implement - return bool{}; -} - -Return<bool> GnssPsds::injectXtraData(const hidl_string&) { - // TODO implement - return bool{}; -} - -// Methods from V3_0::IGnssPsds follow. -Return<bool> GnssPsds::setCallback_3_0(const sp<V3_0::IGnssPsdsCallback>& callback) { - ALOGD("setCallback_3_0"); - std::unique_lock<std::mutex> lock(mMutex); - sCallback_3_0 = callback; - return true; -} - -Return<bool> GnssPsds::injectPsdsData_3_0(int32_t psdsType, const hidl_string& psdsData) { - ALOGD("injectPsdsData_3_0. psdsType: %d, psdsData: %s", psdsType, psdsData.c_str()); - return true; -} -} // namespace android::hardware::gnss::V3_0::implementation diff --git a/gnss/3.0/default/GnssPsds.h b/gnss/3.0/default/GnssPsds.h deleted file mode 100644 index 4053bf17c8..0000000000 --- a/gnss/3.0/default/GnssPsds.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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/gnss/3.0/IGnssPsds.h> -#include <hidl/MQDescriptor.h> -#include <hidl/Status.h> - -namespace android::hardware::gnss::V3_0::implementation { - -using ::android::sp; -using ::android::hardware::hidl_array; -using ::android::hardware::hidl_memory; -using ::android::hardware::hidl_string; -using ::android::hardware::hidl_vec; -using ::android::hardware::Return; -using ::android::hardware::Void; - -struct GnssPsds : public V3_0::IGnssPsds { - // Methods from V1_0::IGnssXtra follow. - Return<bool> setCallback(const sp<V1_0::IGnssXtraCallback>& callback) override; - Return<bool> injectXtraData(const hidl_string& xtraData) override; - - // Methods from V3_0::IGnssPsds follow. - Return<bool> setCallback_3_0(const sp<V3_0::IGnssPsdsCallback>& callback) override; - Return<bool> injectPsdsData_3_0(int32_t psdsType, const hidl_string& psdsData) override; - - private: - // Guarded by mMutex - static sp<V3_0::IGnssPsdsCallback> sCallback_3_0; - - // Synchronization lock for sCallback_3_0 - mutable std::mutex mMutex; -}; - -} // namespace android::hardware::gnss::V3_0::implementation diff --git a/gnss/3.0/default/OWNERS b/gnss/3.0/default/OWNERS deleted file mode 100644 index b7b4a2e902..0000000000 --- a/gnss/3.0/default/OWNERS +++ /dev/null @@ -1,4 +0,0 @@ -gomo@google.com -smalkos@google.com -wyattriley@google.com -yuhany@google.com diff --git a/gnss/3.0/default/android.hardware.gnss@3.0-service.rc b/gnss/3.0/default/android.hardware.gnss@3.0-service.rc deleted file mode 100644 index c2bfb91e22..0000000000 --- a/gnss/3.0/default/android.hardware.gnss@3.0-service.rc +++ /dev/null @@ -1,4 +0,0 @@ -service vendor.gnss-3-0 /vendor/bin/hw/android.hardware.gnss@3.0-service - class hal - user system - group system diff --git a/gnss/3.0/default/android.hardware.gnss@3.0-service.xml b/gnss/3.0/default/android.hardware.gnss@3.0-service.xml deleted file mode 100644 index 6709e0c3b5..0000000000 --- a/gnss/3.0/default/android.hardware.gnss@3.0-service.xml +++ /dev/null @@ -1,13 +0,0 @@ -<manifest version="1.0" type="device"> - <hal format="hidl"> - <name>android.hardware.gnss</name> - <transport>hwbinder</transport> - <version>3.0</version> - <version>2.1</version> - <version>1.1</version> - <interface> - <name>IGnss</name> - <instance>default</instance> - </interface> - </hal> -</manifest> diff --git a/gnss/3.0/default/service.cpp b/gnss/3.0/default/service.cpp deleted file mode 100644 index 87b458070b..0000000000 --- a/gnss/3.0/default/service.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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.gnss@3.0-service" - -#include <hidl/HidlSupport.h> -#include <hidl/HidlTransportSupport.h> -#include "Gnss.h" - -using ::android::OK; -using ::android::sp; -using ::android::hardware::configureRpcThreadpool; -using ::android::hardware::joinRpcThreadpool; -using ::android::hardware::gnss::V3_0::IGnss; -using ::android::hardware::gnss::V3_0::implementation::Gnss; - -int main(int /* argc */, char* /* argv */[]) { - sp<IGnss> gnss = new Gnss(); - configureRpcThreadpool(1, true /* will join */); - if (gnss->registerAsService() != OK) { - ALOGE("Could not register gnss 3.0 service."); - return 1; - } - joinRpcThreadpool(); - - ALOGE("Service exited!"); - return 1; -}
\ No newline at end of file diff --git a/gnss/3.0/vts/OWNERS b/gnss/3.0/vts/OWNERS deleted file mode 100644 index b7b4a2e902..0000000000 --- a/gnss/3.0/vts/OWNERS +++ /dev/null @@ -1,4 +0,0 @@ -gomo@google.com -smalkos@google.com -wyattriley@google.com -yuhany@google.com diff --git a/gnss/3.0/vts/functional/VtsHalGnssV3_0TargetTest.cpp b/gnss/3.0/vts/functional/VtsHalGnssV3_0TargetTest.cpp deleted file mode 100644 index 31e6164f9e..0000000000 --- a/gnss/3.0/vts/functional/VtsHalGnssV3_0TargetTest.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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 "VtsHalGnssV3_0TargetTest" - -#include <gtest/gtest.h> -#include <hidl/GtestPrinter.h> -#include <hidl/ServiceManagement.h> - -#include "gnss_hal_test.h" - -using android::hardware::gnss::V3_0::IGnss; - -GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GnssHalTest); -INSTANTIATE_TEST_SUITE_P( - PerInstance, GnssHalTest, - testing::ValuesIn(android::hardware::getAllHalInstanceNames(IGnss::descriptor)), - android::hardware::PrintInstanceNameToString);
\ No newline at end of file diff --git a/gnss/3.0/vts/functional/gnss_hal_test_cases.cpp b/gnss/3.0/vts/functional/gnss_hal_test_cases.cpp deleted file mode 100644 index cc5341c181..0000000000 --- a/gnss/3.0/vts/functional/gnss_hal_test_cases.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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 "GnssHalTestCases" - -#include <gnss_hal_test.h> -#include <cmath> -#include "Utils.h" - -#include <gtest/gtest.h> - -using android::hardware::hidl_string; -using android::hardware::hidl_vec; - -using android::hardware::gnss::common::Utils; - -using android::hardware::gnss::V3_0::IGnssPsds; - -/* - * SetupTeardownCreateCleanup: - * Requests the gnss HAL then calls cleanup - * - * Empty test fixture to verify basic Setup & Teardown - */ -TEST_P(GnssHalTest, SetupTeardownCreateCleanup) {} - -/* - * TestPsdsExtension: - * Gets the PsdsExtension and verifies that it returns a non-null extension. - */ -TEST_P(GnssHalTest, TestPsdsExtension) { - auto psds = gnss_hal_->getExtensionPsds(); - ASSERT_TRUE(psds.isOk()); - sp<IGnssPsds> iPsds = psds; - ASSERT_TRUE(iPsds != nullptr); -} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/BlocklistedSource.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/BlocklistedSource.aidl index 03026761f8..11cdcfcc9a 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/BlocklistedSource.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/BlocklistedSource.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/CorrelationVector.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/CorrelationVector.aidl index 1f713fa4e0..2d21748564 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/CorrelationVector.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/CorrelationVector.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/ElapsedRealtime.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/ElapsedRealtime.aidl index 933f659c57..fbcc8a3ac7 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/ElapsedRealtime.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/ElapsedRealtime.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssClock.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssClock.aidl index 53ac0efa37..15fe2e9b57 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssClock.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssClock.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssConstellationType.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssConstellationType.aidl index 18fdfa91c2..f873b87d7f 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssConstellationType.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssConstellationType.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssData.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssData.aidl index 73ead10ff7..9e05db7bd1 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssData.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssData.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl index 3d287e4a1a..728ff68a28 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMultipathIndicator.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMultipathIndicator.aidl index 5da60f7a6e..b9db34382e 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMultipathIndicator.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMultipathIndicator.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssPowerStats.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssPowerStats.aidl index 358b570157..6676e2eb7c 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssPowerStats.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssPowerStats.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssSignalType.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssSignalType.aidl index b2a498d009..f729d4c2ec 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssSignalType.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssSignalType.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// 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 index bd6f1ff34d..10b05a7ff1 100644 --- 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 @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// @@ -26,4 +40,6 @@ interface IGnss { android.hardware.gnss.IGnssMeasurementInterface getExtensionGnssMeasurement(); android.hardware.gnss.IGnssPowerIndication getExtensionGnssPowerIndication(); const int ERROR_INVALID_ARGUMENT = 1; + const int ERROR_ALREADY_INIT = 2; + const int ERROR_GENERIC = 3; } diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl index a0c4255df2..9ad9159d67 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssConfiguration.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssConfiguration.aidl index eb4ad82653..20dd781466 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssConfiguration.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssConfiguration.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementCallback.aidl index 764b896955..93894bfd6a 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementCallback.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementCallback.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementInterface.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementInterface.aidl index 7cb7395c18..07a51aeb5d 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementInterface.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementInterface.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndication.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndication.aidl index c44903eadb..1cc7f7114a 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndication.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndication.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndicationCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndicationCallback.aidl index 12e6762d2b..01f91dc3de 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndicationCallback.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndicationCallback.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// 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 index cae2ea6432..175879245a 100644 --- 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 @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// 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 index 6888632fa2..a1af1057ef 100644 --- 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 @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// 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 index d348c633d0..b387121d5b 100644 --- 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 @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteClockInfo.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteClockInfo.aidl index bdba6673ea..4dd45b2af7 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteClockInfo.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteClockInfo.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePositionEcef.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePositionEcef.aidl index 550fa4dbe9..c96b2e5344 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePositionEcef.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePositionEcef.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePvt.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePvt.aidl index 4ff025eff8..95af1524b3 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePvt.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePvt.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteVelocityEcef.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteVelocityEcef.aidl index 7db7ee6b5d..558aec992d 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteVelocityEcef.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteVelocityEcef.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/gnss/aidl/android/hardware/gnss/IGnss.aidl b/gnss/aidl/android/hardware/gnss/IGnss.aidl index c815e2dc93..f99b512c5f 100644 --- a/gnss/aidl/android/hardware/gnss/IGnss.aidl +++ b/gnss/aidl/android/hardware/gnss/IGnss.aidl @@ -34,6 +34,12 @@ interface IGnss { */ const int ERROR_INVALID_ARGUMENT = 1; + /** A callback has already been registered. */ + const int ERROR_ALREADY_INIT = 2; + + /** Any other error. */ + const int ERROR_GENERIC = 3; + /** * Opens the interface and provides the callback routines to the implementation of this * interface. diff --git a/gnss/aidl/android/hardware/gnss/IGnssMeasurementInterface.aidl b/gnss/aidl/android/hardware/gnss/IGnssMeasurementInterface.aidl index 04cdf6417b..08c83a42e7 100644 --- a/gnss/aidl/android/hardware/gnss/IGnssMeasurementInterface.aidl +++ b/gnss/aidl/android/hardware/gnss/IGnssMeasurementInterface.aidl @@ -40,10 +40,9 @@ interface IGnssMeasurementInterface { * @param enableCorrVecOutputs If true, enable correlation vectors as part of the raw GNSS * measurements outputs. If false, disable correlation vectors. * - * @return initRet Returns SUCCESS if successful. Returns ERROR_ALREADY_INIT if a callback has - * already been registered without a corresponding call to 'close'. Returns ERROR_GENERIC - * for any other error. The HAL must not generate any other updates upon returning this - * error code. + * Returns ok() if successful. Returns ERROR_ALREADY_INIT if a callback has already been + * registered without a corresponding call to 'close'. Returns ERROR_GENERIC for any other + * error. The HAL must not generate any other updates upon returning this error code. */ void setCallback(in IGnssMeasurementCallback callback, in boolean enableFullTracking, in boolean enableCorrVecOutputs); diff --git a/gnss/aidl/default/Android.bp b/gnss/aidl/default/Android.bp index 6694ce619c..b56a701935 100644 --- a/gnss/aidl/default/Android.bp +++ b/gnss/aidl/default/Android.bp @@ -42,7 +42,7 @@ cc_binary { "android.hardware.gnss.measurement_corrections@1.1", "android.hardware.gnss.measurement_corrections@1.0", "android.hardware.gnss.visibility_control@1.0", - "android.hardware.gnss-ndk_platform", + "android.hardware.gnss-V1-ndk_platform", ], srcs: [ "Gnss.cpp", diff --git a/gnss/aidl/vts/Android.bp b/gnss/aidl/vts/Android.bp index c10e809725..7cdc339633 100644 --- a/gnss/aidl/vts/Android.bp +++ b/gnss/aidl/vts/Android.bp @@ -34,7 +34,7 @@ cc_test { "libbinder", ], static_libs: [ - "android.hardware.gnss-cpp", + "android.hardware.gnss-V1-cpp", "android.hardware.gnss@common-vts-lib", ], test_suites: [ diff --git a/gnss/common/utils/default/Android.bp b/gnss/common/utils/default/Android.bp index be1d532288..c44968d674 100644 --- a/gnss/common/utils/default/Android.bp +++ b/gnss/common/utils/default/Android.bp @@ -42,6 +42,6 @@ cc_library_static { "android.hardware.gnss@2.1", "android.hardware.gnss.measurement_corrections@1.1", "android.hardware.gnss.measurement_corrections@1.0", - "android.hardware.gnss-ndk_platform", + "android.hardware.gnss-V1-ndk_platform", ], } diff --git a/gnss/common/utils/default/Utils.cpp b/gnss/common/utils/default/Utils.cpp index ccc7145d2c..9bc6786b80 100644 --- a/gnss/common/utils/default/Utils.cpp +++ b/gnss/common/utils/default/Utils.cpp @@ -190,7 +190,7 @@ GnssData Utils::getMockMeasurement(const bool enableCorrVecOutputs) { .tropoDelayMeters = 3.882265204404031}, .correlationVectors = {}}; - GnssClock clock = {.gnssClockFlags = GnssClock::HAS_FULL_BIAS | GnssClock::HAS_FULL_BIAS | + GnssClock clock = {.gnssClockFlags = GnssClock::HAS_FULL_BIAS | GnssClock::HAS_BIAS | GnssClock::HAS_BIAS_UNCERTAINTY | GnssClock::HAS_DRIFT | GnssClock::HAS_DRIFT_UNCERTAINTY, .timeNs = 35854545000000, diff --git a/graphics/allocator/2.0/default/OWNERS b/graphics/allocator/2.0/default/OWNERS index 2a56b381a4..c9f24d059f 100644 --- a/graphics/allocator/2.0/default/OWNERS +++ b/graphics/allocator/2.0/default/OWNERS @@ -1,4 +1,4 @@ # Graphics team chrisforbes@google.com -stoza@google.com -vhau@google.com +jreck@google.com +lpy@google.com diff --git a/graphics/allocator/2.0/utils/OWNERS b/graphics/allocator/2.0/utils/OWNERS index 2a56b381a4..c9f24d059f 100644 --- a/graphics/allocator/2.0/utils/OWNERS +++ b/graphics/allocator/2.0/utils/OWNERS @@ -1,4 +1,4 @@ # Graphics team chrisforbes@google.com -stoza@google.com -vhau@google.com +jreck@google.com +lpy@google.com diff --git a/graphics/composer/2.1/default/OWNERS b/graphics/composer/2.1/default/OWNERS index db8fb80631..709c4d1c35 100644 --- a/graphics/composer/2.1/default/OWNERS +++ b/graphics/composer/2.1/default/OWNERS @@ -1,6 +1,3 @@ # Graphics team -courtneygo@google.com -jessehall@google.com +adyabr@google.com lpy@google.com -stoza@google.com -vhau@google.com diff --git a/graphics/composer/2.1/utils/OWNERS b/graphics/composer/2.1/utils/OWNERS index 5acc631d05..7af69b4203 100644 --- a/graphics/composer/2.1/utils/OWNERS +++ b/graphics/composer/2.1/utils/OWNERS @@ -1,5 +1,2 @@ -courtneygo@google.com -jessehall@google.com +adyabr@google.com lpy@google.com -stoza@google.com -vhau@google.com diff --git a/graphics/composer/2.2/default/OWNERS b/graphics/composer/2.2/default/OWNERS index db8fb80631..709c4d1c35 100644 --- a/graphics/composer/2.2/default/OWNERS +++ b/graphics/composer/2.2/default/OWNERS @@ -1,6 +1,3 @@ # Graphics team -courtneygo@google.com -jessehall@google.com +adyabr@google.com lpy@google.com -stoza@google.com -vhau@google.com diff --git a/graphics/composer/2.2/utils/OWNERS b/graphics/composer/2.2/utils/OWNERS index 3f1e82c85a..709c4d1c35 100644 --- a/graphics/composer/2.2/utils/OWNERS +++ b/graphics/composer/2.2/utils/OWNERS @@ -1,5 +1,3 @@ # Graphics team -courtneygo@google.com +adyabr@google.com lpy@google.com -stoza@google.com -vhau@google.com diff --git a/graphics/composer/2.2/vts/functional/OWNERS b/graphics/composer/2.2/vts/functional/OWNERS index a17a50c1b9..ea06752da7 100644 --- a/graphics/composer/2.2/vts/functional/OWNERS +++ b/graphics/composer/2.2/vts/functional/OWNERS @@ -1,8 +1,6 @@ # Graphics team -courtneygo@google.com +adyabr@google.com lpy@google.com -stoza@google.com -vhau@google.com # VTS team yim@google.com diff --git a/graphics/composer/2.3/default/OWNERS b/graphics/composer/2.3/default/OWNERS index 820ebe6b1b..709c4d1c35 100644 --- a/graphics/composer/2.3/default/OWNERS +++ b/graphics/composer/2.3/default/OWNERS @@ -1,5 +1,3 @@ # Graphics team -jessehall@google.com +adyabr@google.com lpy@google.com -stoza@google.com -vhau@google.com diff --git a/graphics/composer/2.3/utils/OWNERS b/graphics/composer/2.3/utils/OWNERS index cc6d937cad..709c4d1c35 100644 --- a/graphics/composer/2.3/utils/OWNERS +++ b/graphics/composer/2.3/utils/OWNERS @@ -1,4 +1,3 @@ # Graphics team +adyabr@google.com lpy@google.com -stoza@google.com -vhau@google.com diff --git a/graphics/composer/2.3/vts/functional/OWNERS b/graphics/composer/2.3/vts/functional/OWNERS index b3ea6bef7b..ea06752da7 100644 --- a/graphics/composer/2.3/vts/functional/OWNERS +++ b/graphics/composer/2.3/vts/functional/OWNERS @@ -1,7 +1,6 @@ # Graphics team +adyabr@google.com lpy@google.com -stoza@google.com -vhau@google.com # VTS team yim@google.com diff --git a/graphics/composer/2.4/default/OWNERS b/graphics/composer/2.4/default/OWNERS index cc6d937cad..709c4d1c35 100644 --- a/graphics/composer/2.4/default/OWNERS +++ b/graphics/composer/2.4/default/OWNERS @@ -1,4 +1,3 @@ # Graphics team +adyabr@google.com lpy@google.com -stoza@google.com -vhau@google.com diff --git a/graphics/composer/2.4/utils/OWNERS b/graphics/composer/2.4/utils/OWNERS index cc6d937cad..709c4d1c35 100644 --- a/graphics/composer/2.4/utils/OWNERS +++ b/graphics/composer/2.4/utils/OWNERS @@ -1,4 +1,3 @@ # Graphics team +adyabr@google.com lpy@google.com -stoza@google.com -vhau@google.com diff --git a/graphics/composer/2.4/vts/functional/OWNERS b/graphics/composer/2.4/vts/functional/OWNERS index b3ea6bef7b..ea06752da7 100644 --- a/graphics/composer/2.4/vts/functional/OWNERS +++ b/graphics/composer/2.4/vts/functional/OWNERS @@ -1,7 +1,6 @@ # Graphics team +adyabr@google.com lpy@google.com -stoza@google.com -vhau@google.com # VTS team yim@google.com diff --git a/graphics/mapper/2.0/default/OWNERS b/graphics/mapper/2.0/default/OWNERS index 2a56b381a4..c9f24d059f 100644 --- a/graphics/mapper/2.0/default/OWNERS +++ b/graphics/mapper/2.0/default/OWNERS @@ -1,4 +1,4 @@ # Graphics team chrisforbes@google.com -stoza@google.com -vhau@google.com +jreck@google.com +lpy@google.com diff --git a/graphics/mapper/2.0/utils/OWNERS b/graphics/mapper/2.0/utils/OWNERS index 2a56b381a4..c9f24d059f 100644 --- a/graphics/mapper/2.0/utils/OWNERS +++ b/graphics/mapper/2.0/utils/OWNERS @@ -1,4 +1,4 @@ # Graphics team chrisforbes@google.com -stoza@google.com -vhau@google.com +jreck@google.com +lpy@google.com diff --git a/graphics/mapper/2.0/vts/OWNERS b/graphics/mapper/2.0/vts/OWNERS index 11b7d216ce..4177296c63 100644 --- a/graphics/mapper/2.0/vts/OWNERS +++ b/graphics/mapper/2.0/vts/OWNERS @@ -1,7 +1,7 @@ # Graphics team chrisforbes@google.com -stoza@google.com -vhau@google.com +jreck@google.com +lpy@google.com # VTS team yim@google.com diff --git a/graphics/mapper/2.1/default/OWNERS b/graphics/mapper/2.1/default/OWNERS index 2a56b381a4..c9f24d059f 100644 --- a/graphics/mapper/2.1/default/OWNERS +++ b/graphics/mapper/2.1/default/OWNERS @@ -1,4 +1,4 @@ # Graphics team chrisforbes@google.com -stoza@google.com -vhau@google.com +jreck@google.com +lpy@google.com diff --git a/graphics/mapper/2.1/utils/OWNERS b/graphics/mapper/2.1/utils/OWNERS index 2a56b381a4..c9f24d059f 100644 --- a/graphics/mapper/2.1/utils/OWNERS +++ b/graphics/mapper/2.1/utils/OWNERS @@ -1,4 +1,4 @@ # Graphics team chrisforbes@google.com -stoza@google.com -vhau@google.com +jreck@google.com +lpy@google.com diff --git a/graphics/mapper/2.1/vts/OWNERS b/graphics/mapper/2.1/vts/OWNERS index 11b7d216ce..4177296c63 100644 --- a/graphics/mapper/2.1/vts/OWNERS +++ b/graphics/mapper/2.1/vts/OWNERS @@ -1,7 +1,7 @@ # Graphics team chrisforbes@google.com -stoza@google.com -vhau@google.com +jreck@google.com +lpy@google.com # VTS team yim@google.com diff --git a/graphics/mapper/3.0/utils/OWNERS b/graphics/mapper/3.0/utils/OWNERS index 2a56b381a4..c9f24d059f 100644 --- a/graphics/mapper/3.0/utils/OWNERS +++ b/graphics/mapper/3.0/utils/OWNERS @@ -1,4 +1,4 @@ # Graphics team chrisforbes@google.com -stoza@google.com -vhau@google.com +jreck@google.com +lpy@google.com diff --git a/graphics/mapper/3.0/vts/OWNERS b/graphics/mapper/3.0/vts/OWNERS index 2a56b381a4..c9f24d059f 100644 --- a/graphics/mapper/3.0/vts/OWNERS +++ b/graphics/mapper/3.0/vts/OWNERS @@ -1,4 +1,4 @@ # Graphics team chrisforbes@google.com -stoza@google.com -vhau@google.com +jreck@google.com +lpy@google.com diff --git a/graphics/mapper/4.0/utils/OWNERS b/graphics/mapper/4.0/utils/OWNERS index 2a56b381a4..c9f24d059f 100644 --- a/graphics/mapper/4.0/utils/OWNERS +++ b/graphics/mapper/4.0/utils/OWNERS @@ -1,4 +1,4 @@ # Graphics team chrisforbes@google.com -stoza@google.com -vhau@google.com +jreck@google.com +lpy@google.com diff --git a/graphics/mapper/4.0/vts/OWNERS b/graphics/mapper/4.0/vts/OWNERS index 2a56b381a4..c9f24d059f 100644 --- a/graphics/mapper/4.0/vts/OWNERS +++ b/graphics/mapper/4.0/vts/OWNERS @@ -1,4 +1,4 @@ # Graphics team chrisforbes@google.com -stoza@google.com -vhau@google.com +jreck@google.com +lpy@google.com diff --git a/graphics/mapper/4.0/vts/functional/Android.bp b/graphics/mapper/4.0/vts/functional/Android.bp index 8bda42556b..2d39daaa0b 100644 --- a/graphics/mapper/4.0/vts/functional/Android.bp +++ b/graphics/mapper/4.0/vts/functional/Android.bp @@ -19,7 +19,7 @@ cc_test { defaults: ["VtsHalTargetTestDefaults"], srcs: ["VtsHalGraphicsMapperV4_0TargetTest.cpp"], static_libs: [ - "android.hardware.graphics.common-unstable-ndk_platform", + "android.hardware.graphics.common-V2-ndk_platform", "android.hardware.graphics.mapper@4.0-vts", "libgralloctypes", "libsync", diff --git a/health/1.0/Android.bp b/health/1.0/Android.bp index 7845871d6d..7786c08bdc 100644 --- a/health/1.0/Android.bp +++ b/health/1.0/Android.bp @@ -5,7 +5,6 @@ hidl_interface { root: "android.hardware", srcs: [ "types.hal", - "IHealth.hal", ], interfaces: [ "android.hidl.base@1.0", diff --git a/health/1.0/IHealth.hal b/health/1.0/IHealth.hal deleted file mode 100644 index 3828589159..0000000000 --- a/health/1.0/IHealth.hal +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.hardware.health@1.0; - -interface IHealth { - /** - * This function lets you change healthd configuration from default if - * desired. It must be called exactly once at startup time. - * - * The configuration values are described in 'struct HealthConfig'. - * To use default configuration, simply return without modifying the - * fields of the config parameter. - * - * @param default healthd configuration. - */ - init(HealthConfig config) generates (HealthConfig configOut); - - /** - * This function is a hook to update/change device's HealthInfo (as described - * in 'struct HealthInfo'). - * - * 'HealthInfo' describes device's battery and charging status, typically - * read from kernel. These values may be modified in this call. - * - * @param Device Health info as described in 'struct HealthInfo'. - * @return skipLogging Indication to the caller to add 'or' skip logging the health - * information. Return 'true' to skip logging the update. - * @return infoOut HealthInfo to be sent to client code. (May or may - * not be modified). - */ - update(HealthInfo info) generates (bool skipLogging, HealthInfo infoOut); - - /** - * This function is called by healthd when framework queries for remaining - * energy in the Battery through BatteryManager APIs. - * - * @return result Result of querying enery counter for the battery. - * @return energy Battery remaining energy in nanowatt-hours. - * Must be '0' if result is anything other than Result::SUCCESS. - */ - energyCounter() generates (Result result, int64_t energy); -}; diff --git a/health/1.0/default/include/hal_conversion.h b/health/1.0/default/include/hal_conversion.h index a92b208354..a8ddb73544 100644 --- a/health/1.0/default/include/hal_conversion.h +++ b/health/1.0/default/include/hal_conversion.h @@ -17,7 +17,7 @@ #ifndef HARDWARE_INTERFACES_HEALTH_V1_0_DEFAULT_INCLUDE_HAL_CONVERSION_H_ #define HARDWARE_INTERFACES_HEALTH_V1_0_DEFAULT_INCLUDE_HAL_CONVERSION_H_ -#include <android/hardware/health/1.0/IHealth.h> +#include <android/hardware/health/1.0/types.h> #include <healthd/healthd.h> namespace android { diff --git a/health/storage/aidl/default/Android.bp b/health/storage/aidl/default/Android.bp index 68a8ee267f..b53bc35f28 100644 --- a/health/storage/aidl/default/Android.bp +++ b/health/storage/aidl/default/Android.bp @@ -20,7 +20,7 @@ cc_defaults { shared_libs: [ "libbase", "libbinder_ndk", - "android.hardware.health.storage-unstable-ndk_platform", + "android.hardware.health.storage-V1-ndk_platform", ], static_libs: [ "libfstab", diff --git a/health/storage/aidl/vts/functional/Android.bp b/health/storage/aidl/vts/functional/Android.bp index 86b72a712d..0e7671df03 100644 --- a/health/storage/aidl/vts/functional/Android.bp +++ b/health/storage/aidl/vts/functional/Android.bp @@ -25,7 +25,7 @@ cc_test { "libbinder_ndk", ], static_libs: [ - "android.hardware.health.storage-ndk_platform", + "android.hardware.health.storage-V1-ndk_platform", ], header_libs: [ "libhealth_storage_test_common_headers", diff --git a/health/storage/impl_common/impl_common.cpp b/health/storage/impl_common/impl_common.cpp index 6e753d4655..1a7a7f1732 100644 --- a/health/storage/impl_common/impl_common.cpp +++ b/health/storage/impl_common/impl_common.cpp @@ -45,32 +45,59 @@ static std::string GetGarbageCollectPath() { return ""; } +static std::string GetWriteBoosterPath() { + Fstab fstab; + ReadDefaultFstab(&fstab); + + for (const auto& entry : fstab) { + if (!entry.sysfs_path.empty()) { + return entry.sysfs_path + "/attributes/wb_avail_buf"; + } + } + + return ""; +} + Result GarbageCollect(uint64_t timeout_seconds) { - std::string path = GetGarbageCollectPath(); + std::string gc_path = GetGarbageCollectPath(); - if (path.empty()) { + if (gc_path.empty()) { LOG(WARNING) << "Cannot find Dev GC path"; return Result::UNKNOWN_ERROR; } Result result = Result::SUCCESS; Timer timer; - LOG(INFO) << "Start Dev GC on " << path; + LOG(INFO) << "Start Dev GC on " << gc_path; while (1) { - std::string require; - if (!ReadFileToString(path, &require)) { - PLOG(WARNING) << "Reading manual_gc failed in " << path; + std::string require_gc; + if (!ReadFileToString(gc_path, &require_gc)) { + PLOG(WARNING) << "Reading manual_gc failed in " << gc_path; result = Result::IO_ERROR; break; } - require = Trim(require); - if (require == "" || require == "off" || require == "disabled") { + require_gc = Trim(require_gc); + + std::string wb_path = GetWriteBoosterPath(); + // Let's flush WB till 100% available + std::string wb_avail = "0x0000000A"; + if (!wb_path.empty() && !ReadFileToString(wb_path, &wb_avail)) { + PLOG(WARNING) << "Reading wb_avail_buf failed in " << wb_path; + } + wb_avail = Trim(wb_avail); + + if (require_gc == "disabled") { + LOG(DEBUG) << "Disabled Dev GC"; + break; + } + if ((require_gc == "" || require_gc == "off") && wb_avail == "0x0000000A") { LOG(DEBUG) << "No more to do Dev GC"; break; } - LOG(DEBUG) << "Trigger Dev GC on " << path; - if (!WriteStringToFile("1", path)) { - PLOG(WARNING) << "Start Dev GC failed on " << path; + LOG(DEBUG) << "Trigger Dev GC on " << gc_path << " having " << require_gc << ", WB on " + << wb_path << " having " << wb_avail; + if (!WriteStringToFile("1", gc_path)) { + PLOG(WARNING) << "Start Dev GC failed on " << gc_path; result = Result::IO_ERROR; break; } @@ -81,9 +108,9 @@ Result GarbageCollect(uint64_t timeout_seconds) { } sleep(2); } - LOG(INFO) << "Stop Dev GC on " << path; - if (!WriteStringToFile("0", path)) { - PLOG(WARNING) << "Stop Dev GC failed on " << path; + LOG(INFO) << "Stop Dev GC on " << gc_path; + if (!WriteStringToFile("0", gc_path)) { + PLOG(WARNING) << "Stop Dev GC failed on " << gc_path; result = Result::IO_ERROR; } @@ -97,17 +124,26 @@ void DebugDump(int fd) { if (path.empty()) { output << "Cannot find Dev GC path"; } else { - std::string require; + std::string require_gc; - if (ReadFileToString(path, &require)) { - output << path << ":" << require << std::endl; + if (ReadFileToString(path, &require_gc)) { + output << path << ":" << require_gc << std::endl; } if (WriteStringToFile("0", path)) { output << "stop success" << std::endl; } } + std::string wb_path = GetWriteBoosterPath(); + if (wb_path.empty()) { + output << "Cannot find Dev WriteBooster path"; + } else { + std::string wb_available; + if (ReadFileToString(wb_path, &wb_available)) { + output << wb_path << ":" << wb_available << std::endl; + } + } if (!WriteStringToFd(output.str(), fd)) { PLOG(WARNING) << "debug: cannot write to fd"; } diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/Certificate.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/Certificate.aidl index 7e3002d70a..d8a8128c8e 100644 --- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/Certificate.aidl +++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/Certificate.aidl @@ -1,14 +1,29 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // 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. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m <name>-update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file 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 diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/CipherSuite.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/CipherSuite.aidl index 447203faa6..2685525044 100644 --- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/CipherSuite.aidl +++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/CipherSuite.aidl @@ -1,14 +1,29 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // 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. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m <name>-update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file 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 diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/HardwareInformation.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/HardwareInformation.aidl index e1296e05e8..f8d5a9e7e6 100644 --- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/HardwareInformation.aidl +++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/HardwareInformation.aidl @@ -1,14 +1,29 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // 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. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m <name>-update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file 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 diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredential.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredential.aidl index 88104d9577..a097895b81 100644 --- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredential.aidl +++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredential.aidl @@ -1,14 +1,29 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // 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. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m <name>-update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file 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 @@ -18,6 +33,9 @@ package android.hardware.identity; @VintfStability interface IIdentityCredential { + /** + * @deprecated use deleteCredentalWithChallenge() instead. + */ byte[] deleteCredential(); byte[] createEphemeralKeyPair(); void setReaderEphemeralPublicKey(in byte[] publicKey); @@ -29,4 +47,7 @@ interface IIdentityCredential { android.hardware.identity.Certificate generateSigningKeyPair(out byte[] signingKeyBlob); void setRequestedNamespaces(in android.hardware.identity.RequestNamespace[] requestNamespaces); void setVerificationToken(in android.hardware.keymaster.VerificationToken verificationToken); + byte[] deleteCredentialWithChallenge(in byte[] challenge); + byte[] proveOwnership(in byte[] challenge); + android.hardware.identity.IWritableIdentityCredential updateCredential(); } diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredentialStore.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredentialStore.aidl index 5dafb76d1c..c6fb3c889e 100644 --- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredentialStore.aidl +++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredentialStore.aidl @@ -1,14 +1,29 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // 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. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m <name>-update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file 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 diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IWritableIdentityCredential.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IWritableIdentityCredential.aidl index c5ac9d6340..a713462940 100644 --- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IWritableIdentityCredential.aidl +++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IWritableIdentityCredential.aidl @@ -1,14 +1,29 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // 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. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m <name>-update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file 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 diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/RequestDataItem.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/RequestDataItem.aidl index 24ec26afdb..c9c2b9fec6 100644 --- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/RequestDataItem.aidl +++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/RequestDataItem.aidl @@ -1,14 +1,29 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // 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. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m <name>-update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file 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 diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/RequestNamespace.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/RequestNamespace.aidl index af00f3bb62..aaf1e20f1d 100644 --- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/RequestNamespace.aidl +++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/RequestNamespace.aidl @@ -1,14 +1,29 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // 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. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m <name>-update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file 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 diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/SecureAccessControlProfile.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/SecureAccessControlProfile.aidl index dfc1ad0681..695fb3fb26 100644 --- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/SecureAccessControlProfile.aidl +++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/SecureAccessControlProfile.aidl @@ -1,14 +1,29 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // 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. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m <name>-update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file 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 diff --git a/identity/aidl/android/hardware/identity/IIdentityCredential.aidl b/identity/aidl/android/hardware/identity/IIdentityCredential.aidl index 702334d0b6..d23f88cac8 100644 --- a/identity/aidl/android/hardware/identity/IIdentityCredential.aidl +++ b/identity/aidl/android/hardware/identity/IIdentityCredential.aidl @@ -19,6 +19,7 @@ package android.hardware.identity; import android.hardware.identity.Certificate; import android.hardware.identity.RequestNamespace; import android.hardware.identity.SecureAccessControlProfile; +import android.hardware.identity.IWritableIdentityCredential; import android.hardware.keymaster.HardwareAuthToken; import android.hardware.keymaster.VerificationToken; @@ -40,7 +41,11 @@ interface IIdentityCredential { * After this method has been called, the persistent storage used for credentialData should * be deleted. * - * @return a COSE_Sign1 signature described above. + * This method was deprecated in API version 3 because there's no challenge so freshness + * can't be checked. Use deleteCredentalWithChallenge() instead. + * + * @return a COSE_Sign1 signature described above + * @deprecated use deleteCredentalWithChallenge() instead. */ byte[] deleteCredential(); @@ -353,6 +358,18 @@ interface IIdentityCredential { * * - subjectPublicKeyInfo: must contain attested public key. * + * As of API version 3, the certificate shall also have an X.509 extension at + * OID 1.3.6.1.4.1.11129.2.1.26 which shall contain an OCTET STRING with the + * bytes of the CBOR with the following CDDL: + * + * ProofOfBinding = [ + * "ProofOfBinding", + * bstr, // Contains SHA-256(ProofOfProvisioning) + * ] + * + * This CBOR enables an issuer to determine the exact state of the credential it + * returns issuer-signed data for. + * * @param out signingKeyBlob contains an AES-GCM-ENC(storageKey, R, signingKey, docType) * where signingKey is an EC private key in uncompressed form. That is, the returned * blob is an encrypted copy of the newly-generated private signing key. @@ -381,4 +398,63 @@ interface IIdentityCredential { * The verification token. This token is only valid if the timestamp field is non-zero. */ void setVerificationToken(in VerificationToken verificationToken); + + /** + * Delete a credential. + * + * This method returns a COSE_Sign1 data structure signed by CredentialKey + * with payload set to the ProofOfDeletion CBOR below: + * + * ProofOfDeletion = [ + * "ProofOfDeletion", ; tstr + * tstr, ; DocType + * bstr, ; Challenge + * bool ; true if this is a test credential, should + * ; always be false. + * ] + * + * After this method has been called, the persistent storage used for credentialData should + * be deleted. + * + * This method was introduced in API version 3. + * + * @param challenge a challenge set by the issuer to ensure freshness. Maximum size is 32 bytes + * and it may be empty. Fails with STATUS_INVALID_DATA if bigger than 32 bytes. + * @return a COSE_Sign1 signature described above. + */ + byte[] deleteCredentialWithChallenge(in byte[] challenge); + + /** + * Prove ownership of credential. + * + * This method returns a COSE_Sign1 data structure signed by CredentialKey with payload + * set to the ProofOfOwnership CBOR below. + * + * ProofOfOwnership = [ + * "ProofOfOwnership", ; tstr + * tstr, ; DocType + * bstr, ; Challenge + * bool ; true if this is a test credential, should + * ; always be false. + * ] + * + * This method was introduced in API version 3. + * + * @param challenge a challenge set by the issuer to ensure freshness. Maximum size is 32 bytes + * and it may be empty. Fails with STATUS_INVALID_DATA if bigger than 32 bytes. + * @return a COSE_Sign1 signature described above. + */ + byte[] proveOwnership(in byte[] challenge); + + /** + * Called to start updating the credential with new data items. + * + * If the getAttestationCertificate() method is called on the returned object + * it fails with the error STATUS_FAILED. + * + * This method was introduced in API version 3. + * + * @return an IWritableIdentityCredential + */ + IWritableIdentityCredential updateCredential(); } diff --git a/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl b/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl index 33e25b1adf..638be796c4 100644 --- a/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl +++ b/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl @@ -104,6 +104,11 @@ import android.hardware.identity.CipherSuite; * All binder calls in the HAL may return a ServiceSpecificException with statuses from the * STATUS_* integers defined in this interface. Each method states which status can be returned * and under which circumstances. + * + * The API described here is API version 3 which corresponds to feature version 202101 + * of the android.security.identity Framework API. An XML file declaring the feature + * android.hardware.identity_credential (or android.hardware.identity_credential.direct_access + * if implementing the Direct Access HAL) should be included declaring this feature version. */ @VintfStability interface IIdentityCredentialStore { @@ -230,6 +235,9 @@ interface IIdentityCredentialStore { * return argument of the same name in finishAddingEntries(), in * IWritableIdentityCredential. * + * Note that the format of credentialData may depend on the feature version. + * Implementations must support credentialData created by an earlier feature version. + * * @return an IIdentityCredential interface that provides operations on the Credential. */ IIdentityCredential getCredential(in CipherSuite cipherSuite, in byte[] credentialData); diff --git a/identity/aidl/android/hardware/identity/IWritableIdentityCredential.aidl b/identity/aidl/android/hardware/identity/IWritableIdentityCredential.aidl index c48cb6682e..5f878eece2 100644 --- a/identity/aidl/android/hardware/identity/IWritableIdentityCredential.aidl +++ b/identity/aidl/android/hardware/identity/IWritableIdentityCredential.aidl @@ -263,14 +263,27 @@ interface IWritableIdentityCredential { * * where HBK is a unique hardware-bound key that has never existed outside of the secure * environment (except it's all zeroes if testCredential is True) and CredentialKeys is - * the CBOR-encoded structure (in CDDL notation): + * the CBOR-encoded structure (in CDDL notation) given below. + * + * In API versions 1 and 2 it was the following + * + * CredentialKeys = [ + * bstr, ; storageKey, a 128-bit AES key + * bstr ; credentialPrivKey, the private key for credentialKey + * ; in uncompressed form + * ] + * + * In API version 3 or later it must be the following * * CredentialKeys = [ * bstr, ; storageKey, a 128-bit AES key * bstr ; credentialPrivKey, the private key for credentialKey * ; in uncompressed form + * bstr ; SHA-256(ProofOfProvisioning) * ] * + * Additional elements may be added to the CredentialKeys array in future versions. + * * @param out proofOfProvisioningSignature proves to the IA that the credential was imported * into the secure hardware without alteration or error. When the final addEntry() call is * made (when the number of provisioned entries equals the sum of the items in @@ -321,4 +334,5 @@ interface IWritableIdentityCredential { * @param expectedProofOfProvisioningSize the expected size of ProofOfProvisioning. */ void setExpectedProofOfProvisioningSize(in int expectedProofOfProvisioningSize); + } diff --git a/identity/aidl/default/Android.bp b/identity/aidl/default/Android.bp index 7f342d087a..9659f576cf 100644 --- a/identity/aidl/default/Android.bp +++ b/identity/aidl/default/Android.bp @@ -12,6 +12,7 @@ cc_library_static { cflags: [ "-Wall", "-Wextra", + "-Wno-deprecated-declarations", ], shared_libs: [ "liblog", @@ -28,8 +29,8 @@ cc_library_static { "libsoft_attestation_cert", "libpuresoftkeymasterdevice", "android.hardware.identity-support-lib", - "android.hardware.identity-ndk_platform", - "android.hardware.keymaster-ndk_platform", + "android.hardware.identity-V3-ndk_platform", + "android.hardware.keymaster-V3-ndk_platform", ], } @@ -88,8 +89,8 @@ cc_binary { "libsoft_attestation_cert", "libpuresoftkeymasterdevice", "android.hardware.identity-support-lib", - "android.hardware.identity-ndk_platform", - "android.hardware.keymaster-ndk_platform", + "android.hardware.identity-V3-ndk_platform", + "android.hardware.keymaster-V3-ndk_platform", "android.hardware.identity-libeic-hal-common", "android.hardware.identity-libeic-library", ], @@ -97,4 +98,14 @@ cc_binary { "service.cpp", "FakeSecureHardwareProxy.cpp", ], + required: [ + "android.hardware.identity_credential.xml", + ], +} + +prebuilt_etc { + name: "android.hardware.identity_credential.xml", + sub_dir: "permissions", + vendor: true, + src: "android.hardware.identity_credential.xml", } diff --git a/identity/aidl/default/EicOpsImpl.cc b/identity/aidl/default/EicOpsImpl.cc index 3f2ec8b763..8ec4cc9b58 100644 --- a/identity/aidl/default/EicOpsImpl.cc +++ b/identity/aidl/default/EicOpsImpl.cc @@ -45,6 +45,7 @@ #include "EicOps.h" +using ::std::map; using ::std::optional; using ::std::string; using ::std::tuple; @@ -212,7 +213,8 @@ bool eicOpsCreateEcKey(uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE], return false; } if (privKey.value().size() != EIC_P256_PRIV_KEY_SIZE) { - eicDebug("Private key is not %zd bytes long as expected", (size_t)EIC_P256_PRIV_KEY_SIZE); + eicDebug("Private key is %zd bytes, expected %zd", privKey.value().size(), + (size_t)EIC_P256_PRIV_KEY_SIZE); return false; } @@ -224,7 +226,7 @@ bool eicOpsCreateEcKey(uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE], } // ecKeyPairGetPublicKey() returns 0x04 | x | y, we don't want the leading 0x04. if (pubKey.value().size() != EIC_P256_PUB_KEY_SIZE + 1) { - eicDebug("Private key is %zd bytes long, expected %zd", pubKey.value().size(), + eicDebug("Public key is %zd bytes long, expected %zd", pubKey.value().size(), (size_t)EIC_P256_PRIV_KEY_SIZE + 1); return false; } @@ -272,7 +274,8 @@ bool eicOpsCreateCredentialKey(uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE], const return false; } if (privKey.value().size() != EIC_P256_PRIV_KEY_SIZE) { - eicDebug("Private key is not %zd bytes long as expected", (size_t)EIC_P256_PRIV_KEY_SIZE); + eicDebug("Private key is %zd bytes, expected %zd", privKey.value().size(), + (size_t)EIC_P256_PRIV_KEY_SIZE); return false; } @@ -284,8 +287,8 @@ bool eicOpsCreateCredentialKey(uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE], const bool eicOpsSignEcKey(const uint8_t publicKey[EIC_P256_PUB_KEY_SIZE], const uint8_t signingKey[EIC_P256_PRIV_KEY_SIZE], unsigned int serial, const char* issuerName, const char* subjectName, time_t validityNotBefore, - time_t validityNotAfter, uint8_t* cert, - size_t* certSize) { // inout + time_t validityNotAfter, const uint8_t* proofOfBinding, + size_t proofOfBindingSize, uint8_t* cert, size_t* certSize) { // inout vector<uint8_t> signingKeyVec(EIC_P256_PRIV_KEY_SIZE); memcpy(signingKeyVec.data(), signingKey, EIC_P256_PRIV_KEY_SIZE); @@ -293,12 +296,18 @@ bool eicOpsSignEcKey(const uint8_t publicKey[EIC_P256_PUB_KEY_SIZE], pubKeyVec[0] = 0x04; memcpy(pubKeyVec.data() + 1, publicKey, EIC_P256_PUB_KEY_SIZE); - std::string serialDecimal = android::base::StringPrintf("%d", serial); + string serialDecimal = android::base::StringPrintf("%d", serial); + + map<string, vector<uint8_t>> extensions; + if (proofOfBinding != nullptr) { + vector<uint8_t> proofOfBindingVec(proofOfBinding, proofOfBinding + proofOfBindingSize); + extensions["1.3.6.1.4.1.11129.2.1.26"] = proofOfBindingVec; + } optional<vector<uint8_t>> certVec = android::hardware::identity::support::ecPublicKeyGenerateCertificate( pubKeyVec, signingKeyVec, serialDecimal, issuerName, subjectName, - validityNotBefore, validityNotAfter); + validityNotBefore, validityNotAfter, extensions); if (!certVec) { eicDebug("Error generating certificate"); return false; diff --git a/identity/aidl/default/FakeSecureHardwareProxy.cpp b/identity/aidl/default/FakeSecureHardwareProxy.cpp index de6762fc2e..287ffb82e1 100644 --- a/identity/aidl/default/FakeSecureHardwareProxy.cpp +++ b/identity/aidl/default/FakeSecureHardwareProxy.cpp @@ -67,6 +67,13 @@ bool FakeSecureHardwareProvisioningProxy::initialize(bool testCredential) { return eicProvisioningInit(&ctx_, testCredential); } +bool FakeSecureHardwareProvisioningProxy::initializeForUpdate( + bool testCredential, string docType, vector<uint8_t> encryptedCredentialKeys) { + return eicProvisioningInitForUpdate(&ctx_, testCredential, docType.c_str(), + encryptedCredentialKeys.data(), + encryptedCredentialKeys.size()); +} + // Returns public key certificate. optional<vector<uint8_t>> FakeSecureHardwareProvisioningProxy::createCredentialKey( const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId) { @@ -140,14 +147,16 @@ optional<vector<uint8_t>> FakeSecureHardwareProvisioningProxy::finishAddingEntri return signatureOfToBeSigned; } -// Returns encryptedCredentialKeys (80 bytes). +// Returns encryptedCredentialKeys. optional<vector<uint8_t>> FakeSecureHardwareProvisioningProxy::finishGetCredentialData( const string& docType) { - vector<uint8_t> encryptedCredentialKeys(80); + vector<uint8_t> encryptedCredentialKeys(116); + size_t size = encryptedCredentialKeys.size(); if (!eicProvisioningFinishGetCredentialData(&ctx_, docType.c_str(), - encryptedCredentialKeys.data())) { + encryptedCredentialKeys.data(), &size)) { return {}; } + encryptedCredentialKeys.resize(size); return encryptedCredentialKeys; } @@ -162,7 +171,7 @@ bool FakeSecureHardwarePresentationProxy::initialize(bool testCredential, string LOG(INFO) << "FakeSecureHardwarePresentationProxy created, sizeof(EicPresentation): " << sizeof(EicPresentation); return eicPresentationInit(&ctx_, testCredential, docType.c_str(), - encryptedCredentialKeys.data()); + encryptedCredentialKeys.data(), encryptedCredentialKeys.size()); } // Returns publicKeyCert (1st component) and signingKeyBlob (2nd component) @@ -312,13 +321,27 @@ optional<vector<uint8_t>> FakeSecureHardwarePresentationProxy::finishRetrieval() } optional<vector<uint8_t>> FakeSecureHardwarePresentationProxy::deleteCredential( - const string& docType, size_t proofOfDeletionCborSize) { + const string& docType, const vector<uint8_t>& challenge, bool includeChallenge, + size_t proofOfDeletionCborSize) { vector<uint8_t> signatureOfToBeSigned(EIC_ECDSA_P256_SIGNATURE_SIZE); - if (!eicPresentationDeleteCredential(&ctx_, docType.c_str(), proofOfDeletionCborSize, + if (!eicPresentationDeleteCredential(&ctx_, docType.c_str(), challenge.data(), challenge.size(), + includeChallenge, proofOfDeletionCborSize, signatureOfToBeSigned.data())) { return {}; } return signatureOfToBeSigned; } +optional<vector<uint8_t>> FakeSecureHardwarePresentationProxy::proveOwnership( + const string& docType, bool testCredential, const vector<uint8_t>& challenge, + size_t proofOfOwnershipCborSize) { + vector<uint8_t> signatureOfToBeSigned(EIC_ECDSA_P256_SIGNATURE_SIZE); + if (!eicPresentationProveOwnership(&ctx_, docType.c_str(), testCredential, challenge.data(), + challenge.size(), proofOfOwnershipCborSize, + signatureOfToBeSigned.data())) { + return {}; + } + return signatureOfToBeSigned; +} + } // namespace android::hardware::identity diff --git a/identity/aidl/default/FakeSecureHardwareProxy.h b/identity/aidl/default/FakeSecureHardwareProxy.h index b858dd409d..6852c1a979 100644 --- a/identity/aidl/default/FakeSecureHardwareProxy.h +++ b/identity/aidl/default/FakeSecureHardwareProxy.h @@ -32,6 +32,9 @@ class FakeSecureHardwareProvisioningProxy : public SecureHardwareProvisioningPro bool initialize(bool testCredential) override; + bool initializeForUpdate(bool testCredential, string docType, + vector<uint8_t> encryptedCredentialKeys) override; + bool shutdown() override; // Returns public key certificate. @@ -122,8 +125,14 @@ class FakeSecureHardwarePresentationProxy : public SecureHardwarePresentationPro optional<vector<uint8_t>> finishRetrieval() override; optional<vector<uint8_t>> deleteCredential(const string& docType, + const vector<uint8_t>& challenge, + bool includeChallenge, size_t proofOfDeletionCborSize) override; + optional<vector<uint8_t>> proveOwnership(const string& docType, bool testCredential, + const vector<uint8_t>& challenge, + size_t proofOfOwnershipCborSize) override; + bool shutdown() override; protected: diff --git a/identity/aidl/default/android.hardware.identity_credential.xml b/identity/aidl/default/android.hardware.identity_credential.xml new file mode 100644 index 0000000000..5149792b7f --- /dev/null +++ b/identity/aidl/default/android.hardware.identity_credential.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2021 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<permissions> + <feature name="android.hardware.identity_credential" version="202101" /> +</permissions> diff --git a/identity/aidl/default/common/IdentityCredential.cpp b/identity/aidl/default/common/IdentityCredential.cpp index 270fcfa8d0..94779971b1 100644 --- a/identity/aidl/default/common/IdentityCredential.cpp +++ b/identity/aidl/default/common/IdentityCredential.cpp @@ -30,6 +30,7 @@ #include <cppbor_parse.h> #include "FakeSecureHardwareProxy.h" +#include "WritableIdentityCredential.h" namespace aidl::android::hardware::identity { @@ -70,14 +71,8 @@ int IdentityCredential::initialize() { docType_ = docTypeItem->value(); testCredential_ = testCredentialItem->value(); - const vector<uint8_t>& encryptedCredentialKeys = encryptedCredentialKeysItem->value(); - - if (encryptedCredentialKeys.size() != 80) { - LOG(ERROR) << "Unexpected size for encrypted CredentialKeys"; - return IIdentityCredentialStore::STATUS_INVALID_DATA; - } - - if (!hwProxy_->initialize(testCredential_, docType_, encryptedCredentialKeys)) { + encryptedCredentialKeys_ = encryptedCredentialKeysItem->value(); + if (!hwProxy_->initialize(testCredential_, docType_, encryptedCredentialKeys_)) { LOG(ERROR) << "hwProxy->initialize failed"; return false; } @@ -87,12 +82,32 @@ int IdentityCredential::initialize() { ndk::ScopedAStatus IdentityCredential::deleteCredential( vector<uint8_t>* outProofOfDeletionSignature) { + return deleteCredentialCommon({}, false, outProofOfDeletionSignature); +} + +ndk::ScopedAStatus IdentityCredential::deleteCredentialWithChallenge( + const vector<uint8_t>& challenge, vector<uint8_t>* outProofOfDeletionSignature) { + return deleteCredentialCommon(challenge, true, outProofOfDeletionSignature); +} + +ndk::ScopedAStatus IdentityCredential::deleteCredentialCommon( + const vector<uint8_t>& challenge, bool includeChallenge, + vector<uint8_t>* outProofOfDeletionSignature) { + if (challenge.size() > 32) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_INVALID_DATA, "Challenge too big")); + } + cppbor::Array array = {"ProofOfDeletion", docType_, testCredential_}; + if (includeChallenge) { + array = {"ProofOfDeletion", docType_, challenge, testCredential_}; + } + vector<uint8_t> proofOfDeletionCbor = array.encode(); vector<uint8_t> podDigest = support::sha256(proofOfDeletionCbor); - optional<vector<uint8_t>> signatureOfToBeSigned = - hwProxy_->deleteCredential(docType_, proofOfDeletionCbor.size()); + optional<vector<uint8_t>> signatureOfToBeSigned = hwProxy_->deleteCredential( + docType_, challenge, includeChallenge, proofOfDeletionCbor.size()); if (!signatureOfToBeSigned) { return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( IIdentityCredentialStore::STATUS_FAILED, "Error signing ProofOfDeletion")); @@ -111,6 +126,38 @@ ndk::ScopedAStatus IdentityCredential::deleteCredential( return ndk::ScopedAStatus::ok(); } +ndk::ScopedAStatus IdentityCredential::proveOwnership( + const vector<uint8_t>& challenge, vector<uint8_t>* outProofOfOwnershipSignature) { + if (challenge.size() > 32) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_INVALID_DATA, "Challenge too big")); + } + + cppbor::Array array; + array = {"ProofOfOwnership", docType_, challenge, testCredential_}; + vector<uint8_t> proofOfOwnershipCbor = array.encode(); + vector<uint8_t> podDigest = support::sha256(proofOfOwnershipCbor); + + optional<vector<uint8_t>> signatureOfToBeSigned = hwProxy_->proveOwnership( + docType_, testCredential_, challenge, proofOfOwnershipCbor.size()); + if (!signatureOfToBeSigned) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_FAILED, "Error signing ProofOfOwnership")); + } + + optional<vector<uint8_t>> signature = + support::coseSignEcDsaWithSignature(signatureOfToBeSigned.value(), + proofOfOwnershipCbor, // data + {}); // certificateChain + if (!signature) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_FAILED, "Error signing data")); + } + + *outProofOfOwnershipSignature = signature.value(); + return ndk::ScopedAStatus::ok(); +} + ndk::ScopedAStatus IdentityCredential::createEphemeralKeyPair(vector<uint8_t>* outKeyPair) { optional<vector<uint8_t>> ephemeralPriv = hwProxy_->createEphemeralKeyPair(); if (!ephemeralPriv) { @@ -833,4 +880,19 @@ ndk::ScopedAStatus IdentityCredential::generateSigningKeyPair( return ndk::ScopedAStatus::ok(); } +ndk::ScopedAStatus IdentityCredential::updateCredential( + shared_ptr<IWritableIdentityCredential>* outWritableCredential) { + sp<SecureHardwareProvisioningProxy> hwProxy = hwProxyFactory_->createProvisioningProxy(); + shared_ptr<WritableIdentityCredential> wc = + ndk::SharedRefBase::make<WritableIdentityCredential>(hwProxy, docType_, + testCredential_); + if (!wc->initializeForUpdate(encryptedCredentialKeys_)) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_FAILED, + "Error initializing WritableIdentityCredential for update")); + } + *outWritableCredential = wc; + return ndk::ScopedAStatus::ok(); +} + } // namespace aidl::android::hardware::identity diff --git a/identity/aidl/default/common/IdentityCredential.h b/identity/aidl/default/common/IdentityCredential.h index 228182160a..9913b86869 100644 --- a/identity/aidl/default/common/IdentityCredential.h +++ b/identity/aidl/default/common/IdentityCredential.h @@ -45,9 +45,11 @@ using ::std::vector; class IdentityCredential : public BnIdentityCredential { public: - IdentityCredential(sp<SecureHardwarePresentationProxy> hwProxy, + IdentityCredential(sp<SecureHardwareProxyFactory> hwProxyFactory, + sp<SecureHardwarePresentationProxy> hwProxy, const vector<uint8_t>& credentialData) - : hwProxy_(hwProxy), + : hwProxyFactory_(hwProxyFactory), + hwProxy_(hwProxy), credentialData_(credentialData), numStartRetrievalCalls_(0), expectedDeviceNameSpacesSize_(0) {} @@ -58,6 +60,11 @@ class IdentityCredential : public BnIdentityCredential { // Methods from IIdentityCredential follow. ndk::ScopedAStatus deleteCredential(vector<uint8_t>* outProofOfDeletionSignature) override; + ndk::ScopedAStatus deleteCredentialWithChallenge( + const vector<uint8_t>& challenge, + vector<uint8_t>* outProofOfDeletionSignature) override; + ndk::ScopedAStatus proveOwnership(const vector<uint8_t>& challenge, + vector<uint8_t>* outProofOfOwnershipSignature) override; ndk::ScopedAStatus createEphemeralKeyPair(vector<uint8_t>* outKeyPair) override; ndk::ScopedAStatus setReaderEphemeralPublicKey(const vector<uint8_t>& publicKey) override; ndk::ScopedAStatus createAuthChallenge(int64_t* outChallenge) override; @@ -79,8 +86,16 @@ class IdentityCredential : public BnIdentityCredential { ndk::ScopedAStatus generateSigningKeyPair(vector<uint8_t>* outSigningKeyBlob, Certificate* outSigningKeyCertificate) override; + ndk::ScopedAStatus updateCredential( + shared_ptr<IWritableIdentityCredential>* outWritableCredential) override; + private: + ndk::ScopedAStatus deleteCredentialCommon(const vector<uint8_t>& challenge, + bool includeChallenge, + vector<uint8_t>* outProofOfDeletionSignature); + // Set by constructor + sp<SecureHardwareProxyFactory> hwProxyFactory_; sp<SecureHardwarePresentationProxy> hwProxy_; vector<uint8_t> credentialData_; int numStartRetrievalCalls_; @@ -88,6 +103,7 @@ class IdentityCredential : public BnIdentityCredential { // Set by initialize() string docType_; bool testCredential_; + vector<uint8_t> encryptedCredentialKeys_; // Set by createEphemeralKeyPair() vector<uint8_t> ephemeralPublicKey_; diff --git a/identity/aidl/default/common/IdentityCredentialStore.cpp b/identity/aidl/default/common/IdentityCredentialStore.cpp index 13f91aacf9..e6b5466096 100644 --- a/identity/aidl/default/common/IdentityCredentialStore.cpp +++ b/identity/aidl/default/common/IdentityCredentialStore.cpp @@ -63,7 +63,7 @@ ndk::ScopedAStatus IdentityCredentialStore::getCredential( sp<SecureHardwarePresentationProxy> hwProxy = hwProxyFactory_->createPresentationProxy(); shared_ptr<IdentityCredential> credential = - ndk::SharedRefBase::make<IdentityCredential>(hwProxy, credentialData); + ndk::SharedRefBase::make<IdentityCredential>(hwProxyFactory_, hwProxy, credentialData); auto ret = credential->initialize(); if (ret != IIdentityCredentialStore::STATUS_OK) { return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( diff --git a/identity/aidl/default/common/SecureHardwareProxy.h b/identity/aidl/default/common/SecureHardwareProxy.h index b89ad8781f..a1ed1ef03b 100644 --- a/identity/aidl/default/common/SecureHardwareProxy.h +++ b/identity/aidl/default/common/SecureHardwareProxy.h @@ -64,6 +64,9 @@ class SecureHardwareProvisioningProxy : public RefBase { virtual bool initialize(bool testCredential) = 0; + virtual bool initializeForUpdate(bool testCredential, string docType, + vector<uint8_t> encryptedCredentialKeys) = 0; + // Returns public key certificate chain with attestation. // // This must return an entire certificate chain and its implementation must @@ -164,8 +167,14 @@ class SecureHardwarePresentationProxy : public RefBase { virtual optional<vector<uint8_t>> finishRetrieval(); virtual optional<vector<uint8_t>> deleteCredential(const string& docType, + const vector<uint8_t>& challenge, + bool includeChallenge, size_t proofOfDeletionCborSize) = 0; + virtual optional<vector<uint8_t>> proveOwnership(const string& docType, bool testCredential, + const vector<uint8_t>& challenge, + size_t proofOfOwnershipCborSize) = 0; + virtual bool shutdown() = 0; }; diff --git a/identity/aidl/default/common/WritableIdentityCredential.cpp b/identity/aidl/default/common/WritableIdentityCredential.cpp index 1328f3629e..2d897c7d8b 100644 --- a/identity/aidl/default/common/WritableIdentityCredential.cpp +++ b/identity/aidl/default/common/WritableIdentityCredential.cpp @@ -40,7 +40,20 @@ using namespace ::android::hardware::identity; bool WritableIdentityCredential::initialize() { if (!hwProxy_->initialize(testCredential_)) { - LOG(ERROR) << "hwProxy->initialize failed"; + LOG(ERROR) << "hwProxy->initialize() failed"; + return false; + } + startPersonalizationCalled_ = false; + firstEntry_ = true; + + return true; +} + +// Used when updating a credential. Returns false on failure. +bool WritableIdentityCredential::initializeForUpdate( + const vector<uint8_t>& encryptedCredentialKeys) { + if (!hwProxy_->initializeForUpdate(testCredential_, docType_, encryptedCredentialKeys)) { + LOG(ERROR) << "hwProxy->initializeForUpdate() failed"; return false; } startPersonalizationCalled_ = false; diff --git a/identity/aidl/default/common/WritableIdentityCredential.h b/identity/aidl/default/common/WritableIdentityCredential.h index c6f0628cae..36ad4300d1 100644 --- a/identity/aidl/default/common/WritableIdentityCredential.h +++ b/identity/aidl/default/common/WritableIdentityCredential.h @@ -36,16 +36,22 @@ using ::std::vector; class WritableIdentityCredential : public BnWritableIdentityCredential { public: + // For a new credential, call initialize() right after construction. + // + // For an updated credential, call initializeForUpdate() right after construction. + // WritableIdentityCredential(sp<SecureHardwareProvisioningProxy> hwProxy, const string& docType, bool testCredential) : hwProxy_(hwProxy), docType_(docType), testCredential_(testCredential) {} ~WritableIdentityCredential(); - // Creates the Credential Key. Returns false on failure. Must be called - // right after construction. + // Creates the Credential Key. Returns false on failure. bool initialize(); + // Used when updating a credential. Returns false on failure. + bool initializeForUpdate(const vector<uint8_t>& encryptedCredentialKeys); + // Methods from IWritableIdentityCredential follow. ndk::ScopedAStatus getAttestationCertificate(const vector<uint8_t>& attestationApplicationId, const vector<uint8_t>& attestationChallenge, diff --git a/identity/aidl/default/identity-default.xml b/identity/aidl/default/identity-default.xml index 37d5b81c21..a074250901 100644 --- a/identity/aidl/default/identity-default.xml +++ b/identity/aidl/default/identity-default.xml @@ -1,7 +1,7 @@ <manifest version="1.0" type="device"> <hal format="aidl"> <name>android.hardware.identity</name> - <version>2</version> + <version>3</version> <interface> <name>IIdentityCredentialStore</name> <instance>default</instance> diff --git a/identity/aidl/default/libeic/EicCbor.c b/identity/aidl/default/libeic/EicCbor.c index ec049b1c0d..fe131eb8b7 100644 --- a/identity/aidl/default/libeic/EicCbor.c +++ b/identity/aidl/default/libeic/EicCbor.c @@ -17,6 +17,7 @@ #include "EicCbor.h" void eicCborInit(EicCbor* cbor, uint8_t* buffer, size_t bufferSize) { + eicMemSet(cbor, '\0', sizeof(EicCbor)); cbor->size = 0; cbor->bufferSize = bufferSize; cbor->buffer = buffer; @@ -26,6 +27,7 @@ void eicCborInit(EicCbor* cbor, uint8_t* buffer, size_t bufferSize) { void eicCborInitHmacSha256(EicCbor* cbor, uint8_t* buffer, size_t bufferSize, const uint8_t* hmacKey, size_t hmacKeySize) { + eicMemSet(cbor, '\0', sizeof(EicCbor)); cbor->size = 0; cbor->bufferSize = bufferSize; cbor->buffer = buffer; @@ -33,6 +35,10 @@ void eicCborInitHmacSha256(EicCbor* cbor, uint8_t* buffer, size_t bufferSize, eicOpsHmacSha256Init(&cbor->digester.hmacSha256, hmacKey, hmacKeySize); } +void eicCborEnableSecondaryDigesterSha256(EicCbor* cbor, EicSha256Ctx* sha256) { + cbor->secondaryDigesterSha256 = sha256; +} + void eicCborFinal(EicCbor* cbor, uint8_t digest[EIC_SHA256_DIGEST_SIZE]) { switch (cbor->digestType) { case EIC_CBOR_DIGEST_TYPE_SHA256: @@ -53,6 +59,9 @@ void eicCborAppend(EicCbor* cbor, const uint8_t* data, size_t size) { eicOpsHmacSha256Update(&cbor->digester.hmacSha256, data, size); break; } + if (cbor->secondaryDigesterSha256 != NULL) { + eicOpsSha256Update(cbor->secondaryDigesterSha256, data, size); + } if (cbor->size >= cbor->bufferSize) { cbor->size += size; diff --git a/identity/aidl/default/libeic/EicCbor.h b/identity/aidl/default/libeic/EicCbor.h index 4686b38447..9c0f531e4a 100644 --- a/identity/aidl/default/libeic/EicCbor.h +++ b/identity/aidl/default/libeic/EicCbor.h @@ -53,6 +53,9 @@ typedef struct { EicHmacSha256Ctx hmacSha256; } digester; + // The secondary digester, may be unset. + EicSha256Ctx* secondaryDigesterSha256; + // The buffer used for building up CBOR or NULL if bufferSize is 0. uint8_t* buffer; } EicCbor; @@ -70,6 +73,14 @@ void eicCborInit(EicCbor* cbor, uint8_t* buffer, size_t bufferSize); void eicCborInitHmacSha256(EicCbor* cbor, uint8_t* buffer, size_t bufferSize, const uint8_t* hmacKey, size_t hmacKeySize); +/* Enables a secondary digester. + * + * May be enabled midway through processing, this can be used to e.g. calculate + * a digest of Sig_structure (for COSE_Sign1) and a separate digest of its + * payload. + */ +void eicCborEnableSecondaryDigesterSha256(EicCbor* cbor, EicSha256Ctx* sha256); + /* Finishes building CBOR and returns the digest. */ void eicCborFinal(EicCbor* cbor, uint8_t digest[EIC_SHA256_DIGEST_SIZE]); diff --git a/identity/aidl/default/libeic/EicOps.h b/identity/aidl/default/libeic/EicOps.h index da4dabf879..d4fcf0e1bb 100644 --- a/identity/aidl/default/libeic/EicOps.h +++ b/identity/aidl/default/libeic/EicOps.h @@ -207,14 +207,17 @@ bool eicOpsCreateCredentialKey(uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE], const // Generate an X.509 certificate for the key identified by |publicKey| which // must be of the form returned by eicOpsCreateEcKey(). // +// If proofOfBinding is not NULL, it will be included as an OCTET_STRING +// X.509 extension at OID 1.3.6.1.4.1.11129.2.1.26. +// // The certificate will be signed by the key identified by |signingKey| which // must be of the form returned by eicOpsCreateEcKey(). // bool eicOpsSignEcKey(const uint8_t publicKey[EIC_P256_PUB_KEY_SIZE], const uint8_t signingKey[EIC_P256_PRIV_KEY_SIZE], unsigned int serial, const char* issuerName, const char* subjectName, time_t validityNotBefore, - time_t validityNotAfter, uint8_t* cert, - size_t* certSize); // inout + time_t validityNotAfter, const uint8_t* proofOfBinding, + size_t proofOfBindingSize, uint8_t* cert, size_t* certSize); // inout // Uses |privateKey| to create an ECDSA signature of some data (the SHA-256 must // be given by |digestOfData|). Returns the signature in |signature|. diff --git a/identity/aidl/default/libeic/EicPresentation.c b/identity/aidl/default/libeic/EicPresentation.c index d3f5556f66..5e9a280d09 100644 --- a/identity/aidl/default/libeic/EicPresentation.c +++ b/identity/aidl/default/libeic/EicPresentation.c @@ -19,13 +19,28 @@ #include <inttypes.h> bool eicPresentationInit(EicPresentation* ctx, bool testCredential, const char* docType, - const uint8_t encryptedCredentialKeys[80]) { - uint8_t credentialKeys[52]; + const uint8_t* encryptedCredentialKeys, + size_t encryptedCredentialKeysSize) { + uint8_t credentialKeys[86]; + bool expectPopSha256 = false; + + // For feature version 202009 it's 52 bytes long and for feature version 202101 it's 86 + // bytes (the additional data is the ProofOfProvisioning SHA-256). We need + // to support loading all feature versions. + // + if (encryptedCredentialKeysSize == 52 + 28) { + /* do nothing */ + } else if (encryptedCredentialKeysSize == 86 + 28) { + expectPopSha256 = true; + } else { + eicDebug("Unexpected size %zd for encryptedCredentialKeys", encryptedCredentialKeysSize); + return false; + } eicMemSet(ctx, '\0', sizeof(EicPresentation)); if (!eicOpsDecryptAes128Gcm(eicOpsGetHardwareBoundKey(testCredential), encryptedCredentialKeys, - 80, + encryptedCredentialKeysSize, // DocType is the additionalAuthenticatedData (const uint8_t*)docType, eicStrLen(docType), credentialKeys)) { eicDebug("Error decrypting CredentialKeys"); @@ -34,25 +49,42 @@ bool eicPresentationInit(EicPresentation* ctx, bool testCredential, const char* // It's supposed to look like this; // + // Feature version 202009: + // // CredentialKeys = [ // bstr, ; storageKey, a 128-bit AES key - // bstr ; credentialPrivKey, the private key for credentialKey + // bstr, ; credentialPrivKey, the private key for credentialKey // ] // - // where storageKey is 16 bytes and credentialPrivateKey is 32 bytes. + // Feature version 202101: // - // So the first two bytes will be 0x82 0x50 indicating resp. an array of two elements - // and a bstr of 16 elements. Sixteen bytes later (offset 18 and 19) there will be - // a bstr of 32 bytes. It's encoded as two bytes 0x58 and 0x20. + // CredentialKeys = [ + // bstr, ; storageKey, a 128-bit AES key + // bstr, ; credentialPrivKey, the private key for credentialKey + // bstr ; proofOfProvisioning SHA-256 + // ] // - if (credentialKeys[0] != 0x82 || credentialKeys[1] != 0x50 || credentialKeys[18] != 0x58 || - credentialKeys[19] != 0x20) { + // where storageKey is 16 bytes, credentialPrivateKey is 32 bytes, and proofOfProvisioning + // SHA-256 is 32 bytes. + // + if (credentialKeys[0] != (expectPopSha256 ? 0x83 : 0x82) || // array of two or three elements + credentialKeys[1] != 0x50 || // 16-byte bstr + credentialKeys[18] != 0x58 || credentialKeys[19] != 0x20) { // 32-byte bstr eicDebug("Invalid CBOR for CredentialKeys"); return false; } + if (expectPopSha256) { + if (credentialKeys[52] != 0x58 || credentialKeys[53] != 0x20) { // 32-byte bstr + eicDebug("Invalid CBOR for CredentialKeys"); + return false; + } + } eicMemCpy(ctx->storageKey, credentialKeys + 2, EIC_AES_128_KEY_SIZE); eicMemCpy(ctx->credentialPrivateKey, credentialKeys + 20, EIC_P256_PRIV_KEY_SIZE); ctx->testCredential = testCredential; + if (expectPopSha256) { + eicMemCpy(ctx->proofOfProvisioningSha256, credentialKeys + 54, EIC_SHA256_DIGEST_SIZE); + } return true; } @@ -61,6 +93,35 @@ bool eicPresentationGenerateSigningKeyPair(EicPresentation* ctx, const char* doc uint8_t signingKeyBlob[60]) { uint8_t signingKeyPriv[EIC_P256_PRIV_KEY_SIZE]; uint8_t signingKeyPub[EIC_P256_PUB_KEY_SIZE]; + uint8_t cborBuf[64]; + + // Generate the ProofOfBinding CBOR to include in the X.509 certificate in + // IdentityCredentialAuthenticationKeyExtension CBOR. This CBOR is defined + // by the following CDDL + // + // ProofOfBinding = [ + // "ProofOfBinding", + // bstr, // Contains the SHA-256 of ProofOfProvisioning + // ] + // + // This array may grow in the future if other information needs to be + // conveyed. + // + // The bytes of ProofOfBinding is is represented as an OCTET_STRING + // and stored at OID 1.3.6.1.4.1.11129.2.1.26. + // + + EicCbor cbor; + eicCborInit(&cbor, cborBuf, sizeof cborBuf); + eicCborAppendArray(&cbor, 2); + eicCborAppendString(&cbor, "ProofOfBinding"); + eicCborAppendByteString(&cbor, ctx->proofOfProvisioningSha256, EIC_SHA256_DIGEST_SIZE); + if (cbor.size > sizeof(cborBuf)) { + eicDebug("Exceeded buffer size"); + return false; + } + const uint8_t* proofOfBinding = cborBuf; + size_t proofOfBindingSize = cbor.size; if (!eicOpsCreateEcKey(signingKeyPriv, signingKeyPub)) { eicDebug("Error creating signing key"); @@ -73,7 +134,8 @@ bool eicPresentationGenerateSigningKeyPair(EicPresentation* ctx, const char* doc if (!eicOpsSignEcKey(signingKeyPub, ctx->credentialPrivateKey, 1, "Android Identity Credential Key", // issuer CN "Android Identity Credential Authentication Key", // subject CN - validityNotBefore, validityNotAfter, publicKeyCert, publicKeyCertSize)) { + validityNotBefore, validityNotAfter, proofOfBinding, proofOfBindingSize, + publicKeyCert, publicKeyCertSize)) { eicDebug("Error creating certificate for signing key"); return false; } @@ -674,7 +736,8 @@ bool eicPresentationFinishRetrieval(EicPresentation* ctx, uint8_t* digestToBeMac } bool eicPresentationDeleteCredential(EicPresentation* ctx, const char* docType, - size_t proofOfDeletionCborSize, + const uint8_t* challenge, size_t challengeSize, + bool includeChallenge, size_t proofOfDeletionCborSize, uint8_t signatureOfToBeSigned[EIC_ECDSA_P256_SIGNATURE_SIZE]) { EicCbor cbor; @@ -712,9 +775,12 @@ bool eicPresentationDeleteCredential(EicPresentation* ctx, const char* docType, eicCborBegin(&cbor, EIC_CBOR_MAJOR_TYPE_BYTE_STRING, proofOfDeletionCborSize); // Finally, the CBOR that we're actually signing. - eicCborAppendArray(&cbor, 3); + eicCborAppendArray(&cbor, includeChallenge ? 4 : 3); eicCborAppendString(&cbor, "ProofOfDeletion"); eicCborAppendString(&cbor, docType); + if (includeChallenge) { + eicCborAppendByteString(&cbor, challenge, challengeSize); + } eicCborAppendBool(&cbor, ctx->testCredential); uint8_t cborSha256[EIC_SHA256_DIGEST_SIZE]; @@ -726,3 +792,59 @@ bool eicPresentationDeleteCredential(EicPresentation* ctx, const char* docType, return true; } + +bool eicPresentationProveOwnership(EicPresentation* ctx, const char* docType, bool testCredential, + const uint8_t* challenge, size_t challengeSize, + size_t proofOfOwnershipCborSize, + uint8_t signatureOfToBeSigned[EIC_ECDSA_P256_SIGNATURE_SIZE]) { + EicCbor cbor; + + eicCborInit(&cbor, NULL, 0); + + // What we're going to sign is the COSE ToBeSigned structure which + // looks like the following: + // + // Sig_structure = [ + // context : "Signature" / "Signature1" / "CounterSignature", + // body_protected : empty_or_serialized_map, + // ? sign_protected : empty_or_serialized_map, + // external_aad : bstr, + // payload : bstr + // ] + // + eicCborAppendArray(&cbor, 4); + eicCborAppendString(&cbor, "Signature1"); + + // The COSE Encoded protected headers is just a single field with + // COSE_LABEL_ALG (1) -> COSE_ALG_ECSDA_256 (-7). For simplicitly we just + // hard-code the CBOR encoding: + static const uint8_t coseEncodedProtectedHeaders[] = {0xa1, 0x01, 0x26}; + eicCborAppendByteString(&cbor, coseEncodedProtectedHeaders, + sizeof(coseEncodedProtectedHeaders)); + + // We currently don't support Externally Supplied Data (RFC 8152 section 4.3) + // so external_aad is the empty bstr + static const uint8_t externalAad[0] = {}; + eicCborAppendByteString(&cbor, externalAad, sizeof(externalAad)); + + // For the payload, the _encoded_ form follows here. We handle this by simply + // opening a bstr, and then writing the CBOR. This requires us to know the + // size of said bstr, ahead of time. + eicCborBegin(&cbor, EIC_CBOR_MAJOR_TYPE_BYTE_STRING, proofOfOwnershipCborSize); + + // Finally, the CBOR that we're actually signing. + eicCborAppendArray(&cbor, 4); + eicCborAppendString(&cbor, "ProofOfOwnership"); + eicCborAppendString(&cbor, docType); + eicCborAppendByteString(&cbor, challenge, challengeSize); + eicCborAppendBool(&cbor, testCredential); + + uint8_t cborSha256[EIC_SHA256_DIGEST_SIZE]; + eicCborFinal(&cbor, cborSha256); + if (!eicOpsEcDsa(ctx->credentialPrivateKey, cborSha256, signatureOfToBeSigned)) { + eicDebug("Error signing proofOfDeletion"); + return false; + } + + return true; +} diff --git a/identity/aidl/default/libeic/EicPresentation.h b/identity/aidl/default/libeic/EicPresentation.h index d79896212e..7cad068772 100644 --- a/identity/aidl/default/libeic/EicPresentation.h +++ b/identity/aidl/default/libeic/EicPresentation.h @@ -31,6 +31,8 @@ extern "C" { #define EIC_PRESENTATION_MAX_READER_PUBLIC_KEY_SIZE 65 typedef struct { + int featureLevel; + uint8_t storageKey[EIC_AES_128_KEY_SIZE]; uint8_t credentialPrivateKey[EIC_P256_PRIV_KEY_SIZE]; @@ -79,12 +81,17 @@ typedef struct { // SHA-256 for AdditionalData, updated for each entry. uint8_t additionalDataSha256[EIC_SHA256_DIGEST_SIZE]; + // SHA-256 of ProofOfProvisioning. Set to NUL-bytes or initialized from CredentialKeys data + // if credential was created with feature version 202101 or later. + uint8_t proofOfProvisioningSha256[EIC_SHA256_DIGEST_SIZE]; + size_t expectedCborSizeAtEnd; EicCbor cbor; } EicPresentation; bool eicPresentationInit(EicPresentation* ctx, bool testCredential, const char* docType, - const uint8_t encryptedCredentialKeys[80]); + const uint8_t* encryptedCredentialKeys, + size_t encryptedCredentialKeysSize); bool eicPresentationGenerateSigningKeyPair(EicPresentation* ctx, const char* docType, time_t now, uint8_t* publicKeyCert, size_t* publicKeyCertSize, @@ -219,9 +226,19 @@ bool eicPresentationFinishRetrieval(EicPresentation* ctx, uint8_t* digestToBeMac // where content is set to the ProofOfDeletion CBOR. // bool eicPresentationDeleteCredential(EicPresentation* ctx, const char* docType, - size_t proofOfDeletionCborSize, + const uint8_t* challenge, size_t challengeSize, + bool includeChallenge, size_t proofOfDeletionCborSize, uint8_t signatureOfToBeSigned[EIC_ECDSA_P256_SIGNATURE_SIZE]); +// The data returned in |signatureOfToBeSigned| contains the ECDSA signature of +// the ToBeSigned CBOR from RFC 8051 "4.4. Signing and Verification Process" +// where content is set to the ProofOfOwnership CBOR. +// +bool eicPresentationProveOwnership(EicPresentation* ctx, const char* docType, bool testCredential, + const uint8_t* challenge, size_t challengeSize, + size_t proofOfOwnershipCborSize, + uint8_t signatureOfToBeSigned[EIC_ECDSA_P256_SIGNATURE_SIZE]); + #ifdef __cplusplus } #endif diff --git a/identity/aidl/default/libeic/EicProvisioning.c b/identity/aidl/default/libeic/EicProvisioning.c index f16605cfad..3b4148e571 100644 --- a/identity/aidl/default/libeic/EicProvisioning.c +++ b/identity/aidl/default/libeic/EicProvisioning.c @@ -26,10 +26,84 @@ bool eicProvisioningInit(EicProvisioning* ctx, bool testCredential) { return true; } +bool eicProvisioningInitForUpdate(EicProvisioning* ctx, bool testCredential, const char* docType, + const uint8_t* encryptedCredentialKeys, + size_t encryptedCredentialKeysSize) { + uint8_t credentialKeys[86]; + + // For feature version 202009 it's 52 bytes long and for feature version 202101 it's 86 + // bytes (the additional data is the ProofOfProvisioning SHA-256). We need + // to support loading all feature versions. + // + bool expectPopSha256 = false; + if (encryptedCredentialKeysSize == 52 + 28) { + /* do nothing */ + } else if (encryptedCredentialKeysSize == 86 + 28) { + expectPopSha256 = true; + } else { + eicDebug("Unexpected size %zd for encryptedCredentialKeys", encryptedCredentialKeysSize); + return false; + } + + eicMemSet(ctx, '\0', sizeof(EicProvisioning)); + ctx->testCredential = testCredential; + + if (!eicOpsDecryptAes128Gcm(eicOpsGetHardwareBoundKey(testCredential), encryptedCredentialKeys, + encryptedCredentialKeysSize, + // DocType is the additionalAuthenticatedData + (const uint8_t*)docType, eicStrLen(docType), credentialKeys)) { + eicDebug("Error decrypting CredentialKeys"); + return false; + } + + // It's supposed to look like this; + // + // Feature version 202009: + // + // CredentialKeys = [ + // bstr, ; storageKey, a 128-bit AES key + // bstr, ; credentialPrivKey, the private key for credentialKey + // ] + // + // Feature version 202101: + // + // CredentialKeys = [ + // bstr, ; storageKey, a 128-bit AES key + // bstr, ; credentialPrivKey, the private key for credentialKey + // bstr ; proofOfProvisioning SHA-256 + // ] + // + // where storageKey is 16 bytes, credentialPrivateKey is 32 bytes, and proofOfProvisioning + // SHA-256 is 32 bytes. + // + if (credentialKeys[0] != (expectPopSha256 ? 0x83 : 0x82) || // array of two or three elements + credentialKeys[1] != 0x50 || // 16-byte bstr + credentialKeys[18] != 0x58 || credentialKeys[19] != 0x20) { // 32-byte bstr + eicDebug("Invalid CBOR for CredentialKeys"); + return false; + } + if (expectPopSha256) { + if (credentialKeys[52] != 0x58 || credentialKeys[53] != 0x20) { // 32-byte bstr + eicDebug("Invalid CBOR for CredentialKeys"); + return false; + } + } + eicMemCpy(ctx->storageKey, credentialKeys + 2, EIC_AES_128_KEY_SIZE); + eicMemCpy(ctx->credentialPrivateKey, credentialKeys + 20, EIC_P256_PRIV_KEY_SIZE); + // Note: We don't care about the previous ProofOfProvisioning SHA-256 + ctx->isUpdate = true; + return true; +} + bool eicProvisioningCreateCredentialKey(EicProvisioning* ctx, const uint8_t* challenge, size_t challengeSize, const uint8_t* applicationId, size_t applicationIdSize, uint8_t* publicKeyCert, size_t* publicKeyCertSize) { + if (ctx->isUpdate) { + eicDebug("Cannot create CredentialKey on update"); + return false; + } + if (!eicOpsCreateCredentialKey(ctx->credentialPrivateKey, challenge, challengeSize, applicationId, applicationIdSize, ctx->testCredential, publicKeyCert, publicKeyCertSize)) { @@ -96,6 +170,9 @@ bool eicProvisioningStartPersonalization(EicProvisioning* ctx, int accessControl eicCborBegin(&ctx->cbor, EIC_CBOR_MAJOR_TYPE_BYTE_STRING, expectedProofOfProvisioningSize); ctx->expectedCborSizeAtEnd = expectedProofOfProvisioningSize + ctx->cbor.size; + eicOpsSha256Init(&ctx->proofOfProvisioningDigester); + eicCborEnableSecondaryDigesterSha256(&ctx->cbor, &ctx->proofOfProvisioningDigester); + eicCborAppendArray(&ctx->cbor, 5); eicCborAppendString(&ctx->cbor, "ProofOfProvisioning"); eicCborAppendString(&ctx->cbor, docType); @@ -260,14 +337,23 @@ bool eicProvisioningFinishAddingEntries( } bool eicProvisioningFinishGetCredentialData(EicProvisioning* ctx, const char* docType, - uint8_t encryptedCredentialKeys[80]) { + uint8_t* encryptedCredentialKeys, + size_t* encryptedCredentialKeysSize) { EicCbor cbor; - uint8_t cborBuf[52]; + uint8_t cborBuf[86]; + + if (*encryptedCredentialKeysSize < 86 + 28) { + eicDebug("encryptedCredentialKeysSize is %zd which is insufficient"); + return false; + } eicCborInit(&cbor, cborBuf, sizeof(cborBuf)); - eicCborAppendArray(&cbor, 2); + eicCborAppendArray(&cbor, 3); eicCborAppendByteString(&cbor, ctx->storageKey, EIC_AES_128_KEY_SIZE); eicCborAppendByteString(&cbor, ctx->credentialPrivateKey, EIC_P256_PRIV_KEY_SIZE); + uint8_t popSha256[EIC_SHA256_DIGEST_SIZE]; + eicOpsSha256Final(&ctx->proofOfProvisioningDigester, popSha256); + eicCborAppendByteString(&cbor, popSha256, EIC_SHA256_DIGEST_SIZE); if (cbor.size > sizeof(cborBuf)) { eicDebug("Exceeded buffer size"); return false; @@ -285,6 +371,7 @@ bool eicProvisioningFinishGetCredentialData(EicProvisioning* ctx, const char* do eicDebug("Error encrypting CredentialKeys"); return false; } + *encryptedCredentialKeysSize = cbor.size + 28; return true; } diff --git a/identity/aidl/default/libeic/EicProvisioning.h b/identity/aidl/default/libeic/EicProvisioning.h index 836d16e444..f064787b1b 100644 --- a/identity/aidl/default/libeic/EicProvisioning.h +++ b/identity/aidl/default/libeic/EicProvisioning.h @@ -31,7 +31,7 @@ extern "C" { #define EIC_MAX_NUM_ACCESS_CONTROL_PROFILE_IDS 32 typedef struct { - // Set by eicCreateCredentialKey. + // Set by eicCreateCredentialKey() OR eicProvisioningInitForUpdate() uint8_t credentialPrivateKey[EIC_P256_PRIV_KEY_SIZE]; int numEntryCounts; @@ -43,6 +43,7 @@ typedef struct { size_t curEntrySize; size_t curEntryNumBytesReceived; + // Set by eicProvisioningInit() OR eicProvisioningInitForUpdate() uint8_t storageKey[EIC_AES_128_KEY_SIZE]; size_t expectedCborSizeAtEnd; @@ -50,13 +51,23 @@ typedef struct { // SHA-256 for AdditionalData, updated for each entry. uint8_t additionalDataSha256[EIC_SHA256_DIGEST_SIZE]; + // Digester just for ProofOfProvisioning (without Sig_structure). + EicSha256Ctx proofOfProvisioningDigester; + EicCbor cbor; bool testCredential; + + // Set to true if this is an update. + bool isUpdate; } EicProvisioning; bool eicProvisioningInit(EicProvisioning* ctx, bool testCredential); +bool eicProvisioningInitForUpdate(EicProvisioning* ctx, bool testCredential, const char* docType, + const uint8_t* encryptedCredentialKeys, + size_t encryptedCredentialKeysSize); + bool eicProvisioningCreateCredentialKey(EicProvisioning* ctx, const uint8_t* challenge, size_t challengeSize, const uint8_t* applicationId, size_t applicationIdSize, uint8_t* publicKeyCert, @@ -107,14 +118,18 @@ bool eicProvisioningFinishAddingEntries( // CredentialKeys = [ // bstr, ; storageKey, a 128-bit AES key // bstr ; credentialPrivKey, the private key for credentialKey +// bstr ; SHA-256(ProofOfProvisioning) // ] // +// for feature version 202101. For feature version 202009 the third field was not present. +// // Since |storageKey| is 16 bytes and |credentialPrivKey| is 32 bytes, the -// encoded CBOR for CredentialKeys is 52 bytes and consequently -// |encryptedCredentialKeys| will be 52 + 28 = 80 bytes. +// encoded CBOR for CredentialKeys is 86 bytes and consequently +// |encryptedCredentialKeys| will be no longer than 86 + 28 = 114 bytes. // bool eicProvisioningFinishGetCredentialData(EicProvisioning* ctx, const char* docType, - uint8_t encryptedCredentialKeys[80]); + uint8_t* encryptedCredentialKeys, + size_t* encryptedCredentialKeysSize); #ifdef __cplusplus } diff --git a/identity/aidl/vts/Android.bp b/identity/aidl/vts/Android.bp index 03966de549..f487a64799 100644 --- a/identity/aidl/vts/Android.bp +++ b/identity/aidl/vts/Android.bp @@ -4,13 +4,21 @@ cc_test { "VtsHalTargetTestDefaults", "use_libaidlvintf_gtest_helper_static", ], + cflags: [ + "-Wno-deprecated-declarations", + ], srcs: [ - "VtsHalIdentityEndToEndTest.cpp", "VtsIWritableIdentityCredentialTests.cpp", - "VtsIdentityTestUtils.cpp", + "Util.cpp", "VtsAttestationTests.cpp", "UserAuthTests.cpp", "ReaderAuthTests.cpp", + "DeleteCredentialTests.cpp", + "ProveOwnershipTests.cpp", + "UpdateCredentialTests.cpp", + "EndToEndTests.cpp", + "TestCredentialTests.cpp", + "AuthenticationKeyTests.cpp", ], shared_libs: [ "libbinder", @@ -22,9 +30,9 @@ cc_test { "libpuresoftkeymasterdevice", "android.hardware.keymaster@4.0", "android.hardware.identity-support-lib", - "android.hardware.identity-cpp", - "android.hardware.keymaster-cpp", - "android.hardware.keymaster-ndk_platform", + "android.hardware.identity-V3-cpp", + "android.hardware.keymaster-V3-cpp", + "android.hardware.keymaster-V3-ndk_platform", "libkeymaster4support", "libkeymaster4_1support", ], diff --git a/identity/aidl/vts/AuthenticationKeyTests.cpp b/identity/aidl/vts/AuthenticationKeyTests.cpp new file mode 100644 index 0000000000..bda3e70413 --- /dev/null +++ b/identity/aidl/vts/AuthenticationKeyTests.cpp @@ -0,0 +1,194 @@ +/* + * 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 "TestCredentialTests" + +#include <aidl/Gtest.h> +#include <aidl/Vintf.h> +#include <aidl/android/hardware/keymaster/HardwareAuthToken.h> +#include <aidl/android/hardware/keymaster/VerificationToken.h> +#include <android-base/logging.h> +#include <android/hardware/identity/IIdentityCredentialStore.h> +#include <android/hardware/identity/support/IdentityCredentialSupport.h> +#include <binder/IServiceManager.h> +#include <binder/ProcessState.h> +#include <cppbor.h> +#include <cppbor_parse.h> +#include <gtest/gtest.h> +#include <future> +#include <map> +#include <utility> + +#include "Util.h" + +namespace android::hardware::identity { + +using std::endl; +using std::make_pair; +using std::map; +using std::optional; +using std::pair; +using std::string; +using std::tie; +using std::vector; + +using ::android::sp; +using ::android::String16; +using ::android::binder::Status; + +using ::android::hardware::keymaster::HardwareAuthToken; +using ::android::hardware::keymaster::VerificationToken; + +class AuthenticationKeyTests : public testing::TestWithParam<string> { + public: + virtual void SetUp() override { + string halInstanceName = GetParam(); + credentialStore_ = android::waitForDeclaredService<IIdentityCredentialStore>( + String16(halInstanceName.c_str())); + ASSERT_NE(credentialStore_, nullptr); + halApiVersion_ = credentialStore_->getInterfaceVersion(); + } + + sp<IIdentityCredentialStore> credentialStore_; + int halApiVersion_; +}; + +TEST_P(AuthenticationKeyTests, proofOfProvisionInAuthKeyCert) { + if (halApiVersion_ < 3) { + GTEST_SKIP() << "Need HAL API version 3, have " << halApiVersion_; + } + + string docType = "org.iso.18013-5.2019.mdl"; + sp<IWritableIdentityCredential> wc; + ASSERT_TRUE(credentialStore_ + ->createCredential(docType, + true, // testCredential + &wc) + .isOk()); + + vector<uint8_t> attestationApplicationId = {}; + vector<uint8_t> attestationChallenge = {1}; + vector<Certificate> certChain; + ASSERT_TRUE(wc->getAttestationCertificate(attestationApplicationId, attestationChallenge, + &certChain) + .isOk()); + + optional<vector<uint8_t>> optCredentialPubKey = + support::certificateChainGetTopMostKey(certChain[0].encodedCertificate); + ASSERT_TRUE(optCredentialPubKey); + vector<uint8_t> credentialPubKey; + credentialPubKey = optCredentialPubKey.value(); + + size_t proofOfProvisioningSize = 112; + // Not in v1 HAL, may fail + wc->setExpectedProofOfProvisioningSize(proofOfProvisioningSize); + + ASSERT_TRUE(wc->startPersonalization(1 /* numAccessControlProfiles */, + {1} /* numDataElementsPerNamespace */) + .isOk()); + + // Access control profile 0: open access - don't care about the returned SACP + SecureAccessControlProfile sacp; + ASSERT_TRUE(wc->addAccessControlProfile(1, {}, false, 0, 0, &sacp).isOk()); + + // Single entry - don't care about the returned encrypted data + vector<uint8_t> encryptedData; + vector<uint8_t> tstrLastName = cppbor::Tstr("Turing").encode(); + ASSERT_TRUE(wc->beginAddEntry({1}, "ns", "Last name", tstrLastName.size()).isOk()); + ASSERT_TRUE(wc->addEntryValue(tstrLastName, &encryptedData).isOk()); + + vector<uint8_t> proofOfProvisioningSignature; + vector<uint8_t> credentialData; + Status status = wc->finishAddingEntries(&credentialData, &proofOfProvisioningSignature); + EXPECT_TRUE(status.isOk()) << status.exceptionCode() << ": " << status.exceptionMessage(); + + optional<vector<uint8_t>> proofOfProvisioning = + support::coseSignGetPayload(proofOfProvisioningSignature); + ASSERT_TRUE(proofOfProvisioning); + string cborPretty = support::cborPrettyPrint(proofOfProvisioning.value(), 32, {}); + EXPECT_EQ( + "[\n" + " 'ProofOfProvisioning',\n" + " 'org.iso.18013-5.2019.mdl',\n" + " [\n" + " {\n" + " 'id' : 1,\n" + " },\n" + " ],\n" + " {\n" + " 'ns' : [\n" + " {\n" + " 'name' : 'Last name',\n" + " 'value' : 'Turing',\n" + " 'accessControlProfiles' : [1, ],\n" + " },\n" + " ],\n" + " },\n" + " true,\n" + "]", + cborPretty); + // Make sure it's signed by the CredentialKey in the returned cert chain. + EXPECT_TRUE(support::coseCheckEcDsaSignature(proofOfProvisioningSignature, + {}, // Additional data + credentialPubKey)); + + // Now get a credential and have it create AuthenticationKey so we can check + // the certificate. + sp<IIdentityCredential> credential; + ASSERT_TRUE(credentialStore_ + ->getCredential( + CipherSuite::CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256, + credentialData, &credential) + .isOk()); + vector<uint8_t> signingKeyBlob; + Certificate signingKeyCertificate; + ASSERT_TRUE(credential->generateSigningKeyPair(&signingKeyBlob, &signingKeyCertificate).isOk()); + optional<vector<uint8_t>> signingPubKey = + support::certificateChainGetTopMostKey(signingKeyCertificate.encodedCertificate); + EXPECT_TRUE(signingPubKey); + + // SHA-256(ProofOfProvisioning) is embedded in CBOR with the following CDDL + // + // ProofOfBinding = [ + // "ProofOfBinding", + // bstr, // Contains the SHA-256 of ProofOfProvisioning + // ] + // + // Check that. + // + optional<vector<uint8_t>> proofOfBinding = support::certificateGetExtension( + signingKeyCertificate.encodedCertificate, "1.3.6.1.4.1.11129.2.1.26"); + ASSERT_TRUE(proofOfBinding); + auto [item, _, message] = cppbor::parse(proofOfBinding.value()); + ASSERT_NE(item, nullptr) << message; + const cppbor::Array* arrayItem = item->asArray(); + ASSERT_NE(arrayItem, nullptr); + ASSERT_EQ(arrayItem->size(), 2); + const cppbor::Tstr* strItem = (*arrayItem)[0]->asTstr(); + ASSERT_NE(strItem, nullptr); + EXPECT_EQ(strItem->value(), "ProofOfBinding"); + const cppbor::Bstr* popSha256Item = (*arrayItem)[1]->asBstr(); + ASSERT_NE(popSha256Item, nullptr); + EXPECT_EQ(popSha256Item->value(), support::sha256(proofOfProvisioning.value())); +} + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AuthenticationKeyTests); +INSTANTIATE_TEST_SUITE_P( + Identity, AuthenticationKeyTests, + testing::ValuesIn(android::getAidlHalInstanceNames(IIdentityCredentialStore::descriptor)), + android::PrintInstanceNameToString); + +} // namespace android::hardware::identity diff --git a/identity/aidl/vts/DeleteCredentialTests.cpp b/identity/aidl/vts/DeleteCredentialTests.cpp new file mode 100644 index 0000000000..1d300673eb --- /dev/null +++ b/identity/aidl/vts/DeleteCredentialTests.cpp @@ -0,0 +1,169 @@ +/* + * 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 "DeleteCredentialTests" + +#include <aidl/Gtest.h> +#include <aidl/Vintf.h> +#include <aidl/android/hardware/keymaster/HardwareAuthToken.h> +#include <aidl/android/hardware/keymaster/VerificationToken.h> +#include <android-base/logging.h> +#include <android/hardware/identity/IIdentityCredentialStore.h> +#include <android/hardware/identity/support/IdentityCredentialSupport.h> +#include <binder/IServiceManager.h> +#include <binder/ProcessState.h> +#include <cppbor.h> +#include <cppbor_parse.h> +#include <gtest/gtest.h> +#include <future> +#include <map> +#include <utility> + +#include "Util.h" + +namespace android::hardware::identity { + +using std::endl; +using std::make_pair; +using std::map; +using std::optional; +using std::pair; +using std::string; +using std::tie; +using std::vector; + +using ::android::sp; +using ::android::String16; +using ::android::binder::Status; + +using ::android::hardware::keymaster::HardwareAuthToken; +using ::android::hardware::keymaster::VerificationToken; + +class DeleteCredentialTests : public testing::TestWithParam<string> { + public: + virtual void SetUp() override { + credentialStore_ = android::waitForDeclaredService<IIdentityCredentialStore>( + String16(GetParam().c_str())); + ASSERT_NE(credentialStore_, nullptr); + halApiVersion_ = credentialStore_->getInterfaceVersion(); + } + + void provisionData(); + + // Set by provisionData + vector<uint8_t> credentialData_; + vector<uint8_t> credentialPubKey_; + + sp<IIdentityCredentialStore> credentialStore_; + int halApiVersion_; +}; + +void DeleteCredentialTests::provisionData() { + string docType = "org.iso.18013-5.2019.mdl"; + bool testCredential = true; + sp<IWritableIdentityCredential> wc; + ASSERT_TRUE(credentialStore_->createCredential(docType, testCredential, &wc).isOk()); + + vector<uint8_t> attestationApplicationId = {}; + vector<uint8_t> attestationChallenge = {1}; + vector<Certificate> certChain; + ASSERT_TRUE(wc->getAttestationCertificate(attestationApplicationId, attestationChallenge, + &certChain) + .isOk()); + + optional<vector<uint8_t>> optCredentialPubKey = + support::certificateChainGetTopMostKey(certChain[0].encodedCertificate); + ASSERT_TRUE(optCredentialPubKey); + credentialPubKey_ = optCredentialPubKey.value(); + + size_t proofOfProvisioningSize = 106; + // Not in v1 HAL, may fail + wc->setExpectedProofOfProvisioningSize(proofOfProvisioningSize); + + ASSERT_TRUE(wc->startPersonalization(1 /* numAccessControlProfiles */, + {1} /* numDataElementsPerNamespace */) + .isOk()); + + // Access control profile 0: open access - don't care about the returned SACP + SecureAccessControlProfile sacp; + ASSERT_TRUE(wc->addAccessControlProfile(1, {}, false, 0, 0, &sacp).isOk()); + + // Single entry - don't care about the returned encrypted data + ASSERT_TRUE(wc->beginAddEntry({0}, "ns", "Some Data", 1).isOk()); + vector<uint8_t> encryptedData; + ASSERT_TRUE(wc->addEntryValue({9}, &encryptedData).isOk()); + + vector<uint8_t> proofOfProvisioningSignature; + Status status = wc->finishAddingEntries(&credentialData_, &proofOfProvisioningSignature); + EXPECT_TRUE(status.isOk()) << status.exceptionCode() << ": " << status.exceptionMessage(); +} + +TEST_P(DeleteCredentialTests, Delete) { + provisionData(); + + sp<IIdentityCredential> credential; + ASSERT_TRUE(credentialStore_ + ->getCredential( + CipherSuite::CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256, + credentialData_, &credential) + .isOk()); + + vector<uint8_t> proofOfDeletionSignature; + ASSERT_TRUE(credential->deleteCredential(&proofOfDeletionSignature).isOk()); + optional<vector<uint8_t>> proofOfDeletion = + support::coseSignGetPayload(proofOfDeletionSignature); + ASSERT_TRUE(proofOfDeletion); + string cborPretty = support::cborPrettyPrint(proofOfDeletion.value(), 32, {}); + EXPECT_EQ("['ProofOfDeletion', 'org.iso.18013-5.2019.mdl', true, ]", cborPretty); + EXPECT_TRUE(support::coseCheckEcDsaSignature(proofOfDeletionSignature, {}, // Additional data + credentialPubKey_)); +} + +TEST_P(DeleteCredentialTests, DeleteWithChallenge) { + if (halApiVersion_ < 3) { + GTEST_SKIP() << "Need HAL API version 3, have " << halApiVersion_; + } + + provisionData(); + + sp<IIdentityCredential> credential; + ASSERT_TRUE(credentialStore_ + ->getCredential( + CipherSuite::CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256, + credentialData_, &credential) + .isOk()); + + vector<uint8_t> challenge = {65, 66, 67}; + vector<uint8_t> proofOfDeletionSignature; + ASSERT_TRUE( + credential->deleteCredentialWithChallenge(challenge, &proofOfDeletionSignature).isOk()); + optional<vector<uint8_t>> proofOfDeletion = + support::coseSignGetPayload(proofOfDeletionSignature); + ASSERT_TRUE(proofOfDeletion); + string cborPretty = support::cborPrettyPrint(proofOfDeletion.value(), 32, {}); + EXPECT_EQ("['ProofOfDeletion', 'org.iso.18013-5.2019.mdl', {0x41, 0x42, 0x43}, true, ]", + cborPretty); + EXPECT_TRUE(support::coseCheckEcDsaSignature(proofOfDeletionSignature, {}, // Additional data + credentialPubKey_)); +} + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DeleteCredentialTests); +INSTANTIATE_TEST_SUITE_P( + Identity, DeleteCredentialTests, + testing::ValuesIn(android::getAidlHalInstanceNames(IIdentityCredentialStore::descriptor)), + android::PrintInstanceNameToString); + +} // namespace android::hardware::identity diff --git a/identity/aidl/vts/VtsHalIdentityEndToEndTest.cpp b/identity/aidl/vts/EndToEndTests.cpp index cdecb97989..5798b4c28c 100644 --- a/identity/aidl/vts/VtsHalIdentityEndToEndTest.cpp +++ b/identity/aidl/vts/EndToEndTests.cpp @@ -29,7 +29,7 @@ #include <map> #include <tuple> -#include "VtsIdentityTestUtils.h" +#include "Util.h" namespace android::hardware::identity { @@ -50,18 +50,20 @@ using ::android::hardware::keymaster::VerificationToken; using test_utils::validateAttestationCertificate; -class IdentityAidl : public testing::TestWithParam<std::string> { +class EndToEndTests : public testing::TestWithParam<std::string> { public: virtual void SetUp() override { credentialStore_ = android::waitForDeclaredService<IIdentityCredentialStore>( String16(GetParam().c_str())); ASSERT_NE(credentialStore_, nullptr); + halApiVersion_ = credentialStore_->getInterfaceVersion(); } sp<IIdentityCredentialStore> credentialStore_; + int halApiVersion_; }; -TEST_P(IdentityAidl, hardwareInformation) { +TEST_P(EndToEndTests, hardwareInformation) { HardwareInformation info; ASSERT_TRUE(credentialStore_->getHardwareInformation(&info).isOk()); ASSERT_GT(info.credentialStoreName.size(), 0); @@ -69,20 +71,21 @@ TEST_P(IdentityAidl, hardwareInformation) { ASSERT_GE(info.dataChunkSize, 256); } -tuple<bool, string, vector<uint8_t>, vector<uint8_t>> extractFromTestCredentialData( - const vector<uint8_t>& credentialData) { +tuple<bool, string, vector<uint8_t>, vector<uint8_t>, vector<uint8_t>> +extractFromTestCredentialData(const vector<uint8_t>& credentialData) { string docType; vector<uint8_t> storageKey; vector<uint8_t> credentialPrivKey; + vector<uint8_t> sha256Pop; auto [item, _, message] = cppbor::parse(credentialData); if (item == nullptr) { - return make_tuple(false, docType, storageKey, credentialPrivKey); + return make_tuple(false, docType, storageKey, credentialPrivKey, sha256Pop); } const cppbor::Array* arrayItem = item->asArray(); if (arrayItem == nullptr || arrayItem->size() != 3) { - return make_tuple(false, docType, storageKey, credentialPrivKey); + return make_tuple(false, docType, storageKey, credentialPrivKey, sha256Pop); } const cppbor::Tstr* docTypeItem = (*arrayItem)[0]->asTstr(); @@ -92,7 +95,7 @@ tuple<bool, string, vector<uint8_t>, vector<uint8_t>> extractFromTestCredentialD const cppbor::Bstr* encryptedCredentialKeysItem = (*arrayItem)[2]->asBstr(); if (docTypeItem == nullptr || testCredentialItem == nullptr || encryptedCredentialKeysItem == nullptr) { - return make_tuple(false, docType, storageKey, credentialPrivKey); + return make_tuple(false, docType, storageKey, credentialPrivKey, sha256Pop); } docType = docTypeItem->value(); @@ -103,28 +106,38 @@ tuple<bool, string, vector<uint8_t>, vector<uint8_t>> extractFromTestCredentialD optional<vector<uint8_t>> decryptedCredentialKeys = support::decryptAes128Gcm(hardwareBoundKey, encryptedCredentialKeys, docTypeVec); if (!decryptedCredentialKeys) { - return make_tuple(false, docType, storageKey, credentialPrivKey); + return make_tuple(false, docType, storageKey, credentialPrivKey, sha256Pop); } auto [dckItem, dckPos, dckMessage] = cppbor::parse(decryptedCredentialKeys.value()); if (dckItem == nullptr) { - return make_tuple(false, docType, storageKey, credentialPrivKey); + return make_tuple(false, docType, storageKey, credentialPrivKey, sha256Pop); } const cppbor::Array* dckArrayItem = dckItem->asArray(); - if (dckArrayItem == nullptr || dckArrayItem->size() != 2) { - return make_tuple(false, docType, storageKey, credentialPrivKey); + if (dckArrayItem == nullptr) { + return make_tuple(false, docType, storageKey, credentialPrivKey, sha256Pop); + } + if (dckArrayItem->size() < 2) { + return make_tuple(false, docType, storageKey, credentialPrivKey, sha256Pop); } const cppbor::Bstr* storageKeyItem = (*dckArrayItem)[0]->asBstr(); const cppbor::Bstr* credentialPrivKeyItem = (*dckArrayItem)[1]->asBstr(); if (storageKeyItem == nullptr || credentialPrivKeyItem == nullptr) { - return make_tuple(false, docType, storageKey, credentialPrivKey); + return make_tuple(false, docType, storageKey, credentialPrivKey, sha256Pop); } storageKey = storageKeyItem->value(); credentialPrivKey = credentialPrivKeyItem->value(); - return make_tuple(true, docType, storageKey, credentialPrivKey); + if (dckArrayItem->size() == 3) { + const cppbor::Bstr* sha256PopItem = (*dckArrayItem)[2]->asBstr(); + if (sha256PopItem == nullptr) { + return make_tuple(false, docType, storageKey, credentialPrivKey, sha256Pop); + } + sha256Pop = sha256PopItem->value(); + } + return make_tuple(true, docType, storageKey, credentialPrivKey, sha256Pop); } -TEST_P(IdentityAidl, createAndRetrieveCredential) { +TEST_P(EndToEndTests, createAndRetrieveCredential) { // First, generate a key-pair for the reader since its public key will be // part of the request data. vector<uint8_t> readerKey; @@ -277,8 +290,9 @@ TEST_P(IdentityAidl, createAndRetrieveCredential) { // Extract doctype, storage key, and credentialPrivKey from credentialData... this works // only because we asked for a test-credential meaning that the HBK is all zeroes. - auto [exSuccess, exDocType, exStorageKey, exCredentialPrivKey] = + auto [exSuccess, exDocType, exStorageKey, exCredentialPrivKey, exSha256Pop] = extractFromTestCredentialData(credentialData); + ASSERT_TRUE(exSuccess); ASSERT_EQ(exDocType, "org.iso.18013-5.2019.mdl"); // ... check that the public key derived from the private key matches what was @@ -291,6 +305,13 @@ TEST_P(IdentityAidl, createAndRetrieveCredential) { ASSERT_TRUE(exCredentialPubKey); ASSERT_EQ(exCredentialPubKey.value(), credentialPubKey.value()); + // Starting with API version 3 (feature version 202101) we require SHA-256(ProofOfProvisioning) + // to be in CredentialKeys (which is stored encrypted in CredentialData). Check + // that it's there with the expected value. + if (halApiVersion_ >= 3) { + ASSERT_EQ(exSha256Pop, support::sha256(proofOfProvisioning.value())); + } + // Now that the credential has been provisioned, read it back and check the // correct data is returned. sp<IIdentityCredential> credential; @@ -498,13 +519,11 @@ TEST_P(IdentityAidl, createAndRetrieveCredential) { EXPECT_EQ(mac, calculatedMac); } -GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(IdentityAidl); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EndToEndTests); INSTANTIATE_TEST_SUITE_P( - Identity, IdentityAidl, + Identity, EndToEndTests, testing::ValuesIn(android::getAidlHalInstanceNames(IIdentityCredentialStore::descriptor)), android::PrintInstanceNameToString); -// INSTANTIATE_TEST_SUITE_P(Identity, IdentityAidl, -// testing::Values("android.hardware.identity.IIdentityCredentialStore/default")); } // namespace android::hardware::identity diff --git a/identity/aidl/vts/ProveOwnershipTests.cpp b/identity/aidl/vts/ProveOwnershipTests.cpp new file mode 100644 index 0000000000..d1a3d39223 --- /dev/null +++ b/identity/aidl/vts/ProveOwnershipTests.cpp @@ -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. + */ + +#define LOG_TAG "ProveOwnershipTests" + +#include <aidl/Gtest.h> +#include <aidl/Vintf.h> +#include <aidl/android/hardware/keymaster/HardwareAuthToken.h> +#include <aidl/android/hardware/keymaster/VerificationToken.h> +#include <android-base/logging.h> +#include <android/hardware/identity/IIdentityCredentialStore.h> +#include <android/hardware/identity/support/IdentityCredentialSupport.h> +#include <binder/IServiceManager.h> +#include <binder/ProcessState.h> +#include <cppbor.h> +#include <cppbor_parse.h> +#include <gtest/gtest.h> +#include <future> +#include <map> +#include <utility> + +#include "Util.h" + +namespace android::hardware::identity { + +using std::endl; +using std::make_pair; +using std::map; +using std::optional; +using std::pair; +using std::string; +using std::tie; +using std::vector; + +using ::android::sp; +using ::android::String16; +using ::android::binder::Status; + +using ::android::hardware::keymaster::HardwareAuthToken; +using ::android::hardware::keymaster::VerificationToken; + +class ProveOwnershipTests : public testing::TestWithParam<string> { + public: + virtual void SetUp() override { + credentialStore_ = android::waitForDeclaredService<IIdentityCredentialStore>( + String16(GetParam().c_str())); + ASSERT_NE(credentialStore_, nullptr); + halApiVersion_ = credentialStore_->getInterfaceVersion(); + } + + void provisionData(); + + // Set by provisionData + vector<uint8_t> credentialData_; + vector<uint8_t> credentialPubKey_; + + sp<IIdentityCredentialStore> credentialStore_; + int halApiVersion_; +}; + +void ProveOwnershipTests::provisionData() { + string docType = "org.iso.18013-5.2019.mdl"; + bool testCredential = true; + sp<IWritableIdentityCredential> wc; + ASSERT_TRUE(credentialStore_->createCredential(docType, testCredential, &wc).isOk()); + + vector<uint8_t> attestationApplicationId = {}; + vector<uint8_t> attestationChallenge = {1}; + vector<Certificate> certChain; + ASSERT_TRUE(wc->getAttestationCertificate(attestationApplicationId, attestationChallenge, + &certChain) + .isOk()); + + optional<vector<uint8_t>> optCredentialPubKey = + support::certificateChainGetTopMostKey(certChain[0].encodedCertificate); + ASSERT_TRUE(optCredentialPubKey); + credentialPubKey_ = optCredentialPubKey.value(); + + size_t proofOfProvisioningSize = 106; + // Not in v1 HAL, may fail + wc->setExpectedProofOfProvisioningSize(proofOfProvisioningSize); + + ASSERT_TRUE(wc->startPersonalization(1 /* numAccessControlProfiles */, + {1} /* numDataElementsPerNamespace */) + .isOk()); + + // Access control profile 0: open access - don't care about the returned SACP + SecureAccessControlProfile sacp; + ASSERT_TRUE(wc->addAccessControlProfile(1, {}, false, 0, 0, &sacp).isOk()); + + // Single entry - don't care about the returned encrypted data + ASSERT_TRUE(wc->beginAddEntry({0}, "ns", "Some Data", 1).isOk()); + vector<uint8_t> encryptedData; + ASSERT_TRUE(wc->addEntryValue({9}, &encryptedData).isOk()); + + vector<uint8_t> proofOfProvisioningSignature; + Status status = wc->finishAddingEntries(&credentialData_, &proofOfProvisioningSignature); + EXPECT_TRUE(status.isOk()) << status.exceptionCode() << ": " << status.exceptionMessage(); +} + +TEST_P(ProveOwnershipTests, proveOwnership) { + if (halApiVersion_ < 3) { + GTEST_SKIP() << "Need HAL API version 3, have " << halApiVersion_; + } + + provisionData(); + + sp<IIdentityCredential> credential; + ASSERT_TRUE(credentialStore_ + ->getCredential( + CipherSuite::CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256, + credentialData_, &credential) + .isOk()); + + vector<uint8_t> challenge = {17, 18}; + vector<uint8_t> proofOfOwnershipSignature; + ASSERT_TRUE(credential->proveOwnership(challenge, &proofOfOwnershipSignature).isOk()); + optional<vector<uint8_t>> proofOfOwnership = + support::coseSignGetPayload(proofOfOwnershipSignature); + ASSERT_TRUE(proofOfOwnership); + string cborPretty = support::cborPrettyPrint(proofOfOwnership.value(), 32, {}); + EXPECT_EQ("['ProofOfOwnership', 'org.iso.18013-5.2019.mdl', {0x11, 0x12}, true, ]", cborPretty); + EXPECT_TRUE(support::coseCheckEcDsaSignature(proofOfOwnershipSignature, {}, // Additional data + credentialPubKey_)); +} + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ProveOwnershipTests); +INSTANTIATE_TEST_SUITE_P( + Identity, ProveOwnershipTests, + testing::ValuesIn(android::getAidlHalInstanceNames(IIdentityCredentialStore::descriptor)), + android::PrintInstanceNameToString); + +} // namespace android::hardware::identity diff --git a/identity/aidl/vts/ReaderAuthTests.cpp b/identity/aidl/vts/ReaderAuthTests.cpp index 0a9fdc0aa8..7656c8edfc 100644 --- a/identity/aidl/vts/ReaderAuthTests.cpp +++ b/identity/aidl/vts/ReaderAuthTests.cpp @@ -32,7 +32,7 @@ #include <map> #include <utility> -#include "VtsIdentityTestUtils.h" +#include "Util.h" namespace android::hardware::identity { @@ -123,9 +123,9 @@ vector<uint8_t> generateReaderCert(const vector<uint8_t>& publicKey, const vector<uint8_t>& signingKey) { time_t validityNotBefore = 0; time_t validityNotAfter = 0xffffffff; - optional<vector<uint8_t>> cert = - support::ecPublicKeyGenerateCertificate(publicKey, signingKey, "24601", "Issuer", - "Subject", validityNotBefore, validityNotAfter); + optional<vector<uint8_t>> cert = support::ecPublicKeyGenerateCertificate( + publicKey, signingKey, "24601", "Issuer", "Subject", validityNotBefore, + validityNotAfter, {}); return cert.value(); } diff --git a/identity/aidl/vts/TestCredentialTests.cpp b/identity/aidl/vts/TestCredentialTests.cpp new file mode 100644 index 0000000000..d53de3b073 --- /dev/null +++ b/identity/aidl/vts/TestCredentialTests.cpp @@ -0,0 +1,204 @@ +/* + * 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 "TestCredentialTests" + +#include <aidl/Gtest.h> +#include <aidl/Vintf.h> +#include <aidl/android/hardware/keymaster/HardwareAuthToken.h> +#include <aidl/android/hardware/keymaster/VerificationToken.h> +#include <android-base/logging.h> +#include <android/hardware/identity/IIdentityCredentialStore.h> +#include <android/hardware/identity/support/IdentityCredentialSupport.h> +#include <binder/IServiceManager.h> +#include <binder/ProcessState.h> +#include <cppbor.h> +#include <cppbor_parse.h> +#include <gtest/gtest.h> +#include <future> +#include <map> +#include <utility> + +#include "Util.h" + +namespace android::hardware::identity { + +using std::endl; +using std::make_pair; +using std::map; +using std::optional; +using std::pair; +using std::string; +using std::tie; +using std::vector; + +using ::android::sp; +using ::android::String16; +using ::android::binder::Status; + +using ::android::hardware::keymaster::HardwareAuthToken; +using ::android::hardware::keymaster::VerificationToken; + +class TestCredentialTests : public testing::TestWithParam<string> { + public: + virtual void SetUp() override { + string halInstanceName = GetParam(); + credentialStore_ = android::waitForDeclaredService<IIdentityCredentialStore>( + String16(halInstanceName.c_str())); + ASSERT_NE(credentialStore_, nullptr); + halApiVersion_ = credentialStore_->getInterfaceVersion(); + } + + sp<IIdentityCredentialStore> credentialStore_; + int halApiVersion_; +}; + +TEST_P(TestCredentialTests, testCredential) { + string docType = "org.iso.18013-5.2019.mdl"; + sp<IWritableIdentityCredential> wc; + ASSERT_TRUE(credentialStore_ + ->createCredential(docType, + true, // testCredential + &wc) + .isOk()); + + vector<uint8_t> attestationApplicationId = {}; + vector<uint8_t> attestationChallenge = {1}; + vector<Certificate> certChain; + ASSERT_TRUE(wc->getAttestationCertificate(attestationApplicationId, attestationChallenge, + &certChain) + .isOk()); + + optional<vector<uint8_t>> optCredentialPubKey = + support::certificateChainGetTopMostKey(certChain[0].encodedCertificate); + ASSERT_TRUE(optCredentialPubKey); + vector<uint8_t> credentialPubKey; + credentialPubKey = optCredentialPubKey.value(); + + size_t proofOfProvisioningSize = 112; + // Not in v1 HAL, may fail + wc->setExpectedProofOfProvisioningSize(proofOfProvisioningSize); + + ASSERT_TRUE(wc->startPersonalization(1 /* numAccessControlProfiles */, + {1} /* numDataElementsPerNamespace */) + .isOk()); + + // Access control profile 0: open access - don't care about the returned SACP + SecureAccessControlProfile sacp; + ASSERT_TRUE(wc->addAccessControlProfile(1, {}, false, 0, 0, &sacp).isOk()); + + // Single entry - don't care about the returned encrypted data + vector<uint8_t> encryptedData; + vector<uint8_t> tstrLastName = cppbor::Tstr("Turing").encode(); + ASSERT_TRUE(wc->beginAddEntry({1}, "ns", "Last name", tstrLastName.size()).isOk()); + ASSERT_TRUE(wc->addEntryValue(tstrLastName, &encryptedData).isOk()); + + vector<uint8_t> proofOfProvisioningSignature; + vector<uint8_t> credentialData; + Status status = wc->finishAddingEntries(&credentialData, &proofOfProvisioningSignature); + EXPECT_TRUE(status.isOk()) << status.exceptionCode() << ": " << status.exceptionMessage(); + + optional<vector<uint8_t>> proofOfProvisioning = + support::coseSignGetPayload(proofOfProvisioningSignature); + ASSERT_TRUE(proofOfProvisioning); + string cborPretty = support::cborPrettyPrint(proofOfProvisioning.value(), 32, {}); + EXPECT_EQ( + "[\n" + " 'ProofOfProvisioning',\n" + " 'org.iso.18013-5.2019.mdl',\n" + " [\n" + " {\n" + " 'id' : 1,\n" + " },\n" + " ],\n" + " {\n" + " 'ns' : [\n" + " {\n" + " 'name' : 'Last name',\n" + " 'value' : 'Turing',\n" + " 'accessControlProfiles' : [1, ],\n" + " },\n" + " ],\n" + " },\n" + " true,\n" + "]", + cborPretty); + // Make sure it's signed by the CredentialKey in the returned cert chain. + EXPECT_TRUE(support::coseCheckEcDsaSignature(proofOfProvisioningSignature, + {}, // Additional data + credentialPubKey)); + + // Now analyze credentialData.. + auto [item, _, message] = cppbor::parse(credentialData); + ASSERT_NE(item, nullptr); + const cppbor::Array* arrayItem = item->asArray(); + ASSERT_NE(arrayItem, nullptr); + ASSERT_EQ(arrayItem->size(), 3); + const cppbor::Tstr* docTypeItem = (*arrayItem)[0]->asTstr(); + const cppbor::Bool* testCredentialItem = + ((*arrayItem)[1]->asSimple() != nullptr ? ((*arrayItem)[1]->asSimple()->asBool()) + : nullptr); + EXPECT_EQ(docTypeItem->value(), docType); + EXPECT_EQ(testCredentialItem->value(), true); + + vector<uint8_t> hardwareBoundKey = support::getTestHardwareBoundKey(); + const cppbor::Bstr* encryptedCredentialKeysItem = (*arrayItem)[2]->asBstr(); + const vector<uint8_t>& encryptedCredentialKeys = encryptedCredentialKeysItem->value(); + const vector<uint8_t> docTypeVec(docType.begin(), docType.end()); + optional<vector<uint8_t>> decryptedCredentialKeys = + support::decryptAes128Gcm(hardwareBoundKey, encryptedCredentialKeys, docTypeVec); + ASSERT_TRUE(decryptedCredentialKeys); + auto [dckItem, dckPos, dckMessage] = cppbor::parse(decryptedCredentialKeys.value()); + ASSERT_NE(dckItem, nullptr) << dckMessage; + const cppbor::Array* dckArrayItem = dckItem->asArray(); + ASSERT_NE(dckArrayItem, nullptr); + // In HAL API version 1 and 2 this array has two items, in version 3 and later it has three. + if (halApiVersion_ < 3) { + ASSERT_EQ(dckArrayItem->size(), 2); + } else { + ASSERT_EQ(dckArrayItem->size(), 3); + } + const cppbor::Bstr* storageKeyItem = (*dckArrayItem)[0]->asBstr(); + const vector<uint8_t> storageKey = storageKeyItem->value(); + // const cppbor::Bstr* credentialPrivKeyItem = (*dckArrayItem)[1]->asBstr(); + // const vector<uint8_t> credentialPrivKey = credentialPrivKeyItem->value(); + + // Check storageKey can be used to decrypt |encryptedData| to |tstrLastName| + vector<uint8_t> additionalData = cppbor::Map() + .add("Namespace", "ns") + .add("Name", "Last name") + .add("AccessControlProfileIds", cppbor::Array().add(1)) + .encode(); + optional<vector<uint8_t>> decryptedDataItemValue = + support::decryptAes128Gcm(storageKey, encryptedData, additionalData); + ASSERT_TRUE(decryptedDataItemValue); + EXPECT_EQ(decryptedDataItemValue.value(), tstrLastName); + + // Check that SHA-256(ProofOfProvisioning) matches (only in HAL API version 3) + if (halApiVersion_ >= 3) { + const cppbor::Bstr* popSha256Item = (*dckArrayItem)[2]->asBstr(); + const vector<uint8_t> popSha256 = popSha256Item->value(); + ASSERT_EQ(popSha256, support::sha256(proofOfProvisioning.value())); + } +} + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TestCredentialTests); +INSTANTIATE_TEST_SUITE_P( + Identity, TestCredentialTests, + testing::ValuesIn(android::getAidlHalInstanceNames(IIdentityCredentialStore::descriptor)), + android::PrintInstanceNameToString); + +} // namespace android::hardware::identity diff --git a/identity/aidl/vts/UpdateCredentialTests.cpp b/identity/aidl/vts/UpdateCredentialTests.cpp new file mode 100644 index 0000000000..9c5ca55cf2 --- /dev/null +++ b/identity/aidl/vts/UpdateCredentialTests.cpp @@ -0,0 +1,232 @@ +/* + * 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 "UpdateCredentialTests" + +#include <aidl/Gtest.h> +#include <aidl/Vintf.h> +#include <aidl/android/hardware/keymaster/HardwareAuthToken.h> +#include <aidl/android/hardware/keymaster/VerificationToken.h> +#include <android-base/logging.h> +#include <android/hardware/identity/IIdentityCredentialStore.h> +#include <android/hardware/identity/support/IdentityCredentialSupport.h> +#include <binder/IServiceManager.h> +#include <binder/ProcessState.h> +#include <cppbor.h> +#include <cppbor_parse.h> +#include <gtest/gtest.h> +#include <future> +#include <map> +#include <utility> + +#include "Util.h" + +namespace android::hardware::identity { + +using std::endl; +using std::make_pair; +using std::map; +using std::optional; +using std::pair; +using std::string; +using std::tie; +using std::vector; + +using ::android::sp; +using ::android::String16; +using ::android::binder::Status; + +using ::android::hardware::keymaster::HardwareAuthToken; +using ::android::hardware::keymaster::VerificationToken; + +class UpdateCredentialTests : public testing::TestWithParam<string> { + public: + virtual void SetUp() override { + credentialStore_ = android::waitForDeclaredService<IIdentityCredentialStore>( + String16(GetParam().c_str())); + ASSERT_NE(credentialStore_, nullptr); + halApiVersion_ = credentialStore_->getInterfaceVersion(); + } + + void provisionData(); + + // Set by provisionData + vector<uint8_t> credentialData_; + vector<uint8_t> credentialPubKey_; + + sp<IIdentityCredentialStore> credentialStore_; + int halApiVersion_; +}; + +void UpdateCredentialTests::provisionData() { + string docType = "org.iso.18013-5.2019.mdl"; + bool testCredential = true; + sp<IWritableIdentityCredential> wc; + ASSERT_TRUE(credentialStore_->createCredential(docType, testCredential, &wc).isOk()); + + vector<uint8_t> attestationApplicationId = {}; + vector<uint8_t> attestationChallenge = {1}; + vector<Certificate> certChain; + ASSERT_TRUE(wc->getAttestationCertificate(attestationApplicationId, attestationChallenge, + &certChain) + .isOk()); + + optional<vector<uint8_t>> optCredentialPubKey = + support::certificateChainGetTopMostKey(certChain[0].encodedCertificate); + ASSERT_TRUE(optCredentialPubKey); + credentialPubKey_ = optCredentialPubKey.value(); + + size_t proofOfProvisioningSize = 112; + // Not in v1 HAL, may fail + wc->setExpectedProofOfProvisioningSize(proofOfProvisioningSize); + + ASSERT_TRUE(wc->startPersonalization(1 /* numAccessControlProfiles */, + {1} /* numDataElementsPerNamespace */) + .isOk()); + + // Access control profile 0: open access - don't care about the returned SACP + SecureAccessControlProfile sacp; + ASSERT_TRUE(wc->addAccessControlProfile(1, {}, false, 0, 0, &sacp).isOk()); + + // Single entry - don't care about the returned encrypted data + vector<uint8_t> encryptedData; + vector<uint8_t> tstrLastName = cppbor::Tstr("Prince").encode(); + ASSERT_TRUE(wc->beginAddEntry({1}, "ns", "Last name", tstrLastName.size()).isOk()); + ASSERT_TRUE(wc->addEntryValue(tstrLastName, &encryptedData).isOk()); + + vector<uint8_t> proofOfProvisioningSignature; + Status status = wc->finishAddingEntries(&credentialData_, &proofOfProvisioningSignature); + EXPECT_TRUE(status.isOk()) << status.exceptionCode() << ": " << status.exceptionMessage(); + + optional<vector<uint8_t>> proofOfProvisioning = + support::coseSignGetPayload(proofOfProvisioningSignature); + ASSERT_TRUE(proofOfProvisioning); + string cborPretty = support::cborPrettyPrint(proofOfProvisioning.value(), 32, {}); + EXPECT_EQ( + "[\n" + " 'ProofOfProvisioning',\n" + " 'org.iso.18013-5.2019.mdl',\n" + " [\n" + " {\n" + " 'id' : 1,\n" + " },\n" + " ],\n" + " {\n" + " 'ns' : [\n" + " {\n" + " 'name' : 'Last name',\n" + " 'value' : 'Prince',\n" + " 'accessControlProfiles' : [1, ],\n" + " },\n" + " ],\n" + " },\n" + " true,\n" + "]", + cborPretty); + // Make sure it's signed by the CredentialKey in the returned cert chain. + EXPECT_TRUE(support::coseCheckEcDsaSignature(proofOfProvisioningSignature, + {}, // Additional data + credentialPubKey_)); +} + +TEST_P(UpdateCredentialTests, updateCredential) { + if (halApiVersion_ < 3) { + GTEST_SKIP() << "Need HAL API version 3, have " << halApiVersion_; + } + + provisionData(); + + sp<IIdentityCredential> credential; + ASSERT_TRUE(credentialStore_ + ->getCredential( + CipherSuite::CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256, + credentialData_, &credential) + .isOk()); + + sp<IWritableIdentityCredential> wc; + ASSERT_TRUE(credential->updateCredential(&wc).isOk()); + + // Getting an attestation cert should fail (because it's an update). + vector<uint8_t> attestationApplicationId = {}; + vector<uint8_t> attestationChallenge = {1}; + vector<Certificate> certChain; + Status result = wc->getAttestationCertificate(attestationApplicationId, attestationChallenge, + &certChain); + ASSERT_FALSE(result.isOk()); + EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode()); + EXPECT_EQ(IIdentityCredentialStore::STATUS_FAILED, result.serviceSpecificErrorCode()); + + // Now provision some new data... + // + size_t proofOfProvisioningSize = 117; + // Not in v1 HAL, may fail + wc->setExpectedProofOfProvisioningSize(proofOfProvisioningSize); + + ASSERT_TRUE(wc->startPersonalization(1 /* numAccessControlProfiles */, + {1} /* numDataElementsPerNamespace */) + .isOk()); + + // Access control profile 0: open access - don't care about the returned SACP + SecureAccessControlProfile sacp; + ASSERT_TRUE(wc->addAccessControlProfile(2, {}, false, 0, 0, &sacp).isOk()); + + // Single entry - don't care about the returned encrypted data + vector<uint8_t> encryptedData; + vector<uint8_t> tstrLastName = cppbor::Tstr("T.A.F.K.A.P").encode(); + ASSERT_TRUE(wc->beginAddEntry({2}, "ns", "Last name", tstrLastName.size()).isOk()); + ASSERT_TRUE(wc->addEntryValue(tstrLastName, &encryptedData).isOk()); + + vector<uint8_t> proofOfProvisioningSignature; + Status status = wc->finishAddingEntries(&credentialData_, &proofOfProvisioningSignature); + EXPECT_TRUE(status.isOk()) << status.exceptionCode() << ": " << status.exceptionMessage(); + optional<vector<uint8_t>> proofOfProvisioning = + support::coseSignGetPayload(proofOfProvisioningSignature); + ASSERT_TRUE(proofOfProvisioning); + string cborPretty = support::cborPrettyPrint(proofOfProvisioning.value(), 32, {}); + EXPECT_EQ( + "[\n" + " 'ProofOfProvisioning',\n" + " 'org.iso.18013-5.2019.mdl',\n" + " [\n" + " {\n" + " 'id' : 2,\n" + " },\n" + " ],\n" + " {\n" + " 'ns' : [\n" + " {\n" + " 'name' : 'Last name',\n" + " 'value' : 'T.A.F.K.A.P',\n" + " 'accessControlProfiles' : [2, ],\n" + " },\n" + " ],\n" + " },\n" + " true,\n" + "]", + cborPretty); + // Make sure it's signed by the same CredentialKey we originally provisioned with. + EXPECT_TRUE(support::coseCheckEcDsaSignature(proofOfProvisioningSignature, + {}, // Additional data + credentialPubKey_)); +} + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(UpdateCredentialTests); +INSTANTIATE_TEST_SUITE_P( + Identity, UpdateCredentialTests, + testing::ValuesIn(android::getAidlHalInstanceNames(IIdentityCredentialStore::descriptor)), + android::PrintInstanceNameToString); + +} // namespace android::hardware::identity diff --git a/identity/aidl/vts/UserAuthTests.cpp b/identity/aidl/vts/UserAuthTests.cpp index 327493c9a0..ef89d1cafd 100644 --- a/identity/aidl/vts/UserAuthTests.cpp +++ b/identity/aidl/vts/UserAuthTests.cpp @@ -32,7 +32,7 @@ #include <map> #include <utility> -#include "VtsIdentityTestUtils.h" +#include "Util.h" namespace android::hardware::identity { @@ -145,7 +145,7 @@ void UserAuthTests::provisionData() { EXPECT_TRUE(status.isOk()) << status.exceptionCode() << ": " << status.exceptionMessage(); } -// From ReaderAuthTest.cpp - TODO: consolidate with VtsIdentityTestUtils.h +// From ReaderAuthTest.cpp - TODO: consolidate with Util.h pair<vector<uint8_t>, vector<uint8_t>> generateReaderKey(); vector<uint8_t> generateReaderCert(const vector<uint8_t>& publicKey, const vector<uint8_t>& signingKey); diff --git a/identity/aidl/vts/VtsIdentityTestUtils.cpp b/identity/aidl/vts/Util.cpp index 3b106514b4..1148cb0b60 100644 --- a/identity/aidl/vts/VtsIdentityTestUtils.cpp +++ b/identity/aidl/vts/Util.cpp @@ -14,15 +14,18 @@ * limitations under the License. */ -#define LOG_TAG "VtsIdentityTestUtils" +#define LOG_TAG "Util" -#include "VtsIdentityTestUtils.h" +#include "Util.h" -#include <aidl/Gtest.h> #include <android-base/logging.h> + +#include <aidl/Gtest.h> +#include <android-base/stringprintf.h> #include <keymaster/km_openssl/openssl_utils.h> #include <keymasterV4_1/attestation_record.h> #include <charconv> + #include <map> namespace android::hardware::identity::test_utils { @@ -35,6 +38,7 @@ using std::vector; using ::android::sp; using ::android::String16; +using ::android::base::StringPrintf; using ::android::binder::Status; using ::keymaster::X509_Ptr; @@ -86,7 +90,7 @@ optional<vector<uint8_t>> generateReaderCertificate(string serialDecimal, return support::ecPublicKeyGenerateCertificate(readerPublicKey.value(), readerKey.value(), serialDecimal, issuer, subject, - validityNotBefore, validityNotAfter); + validityNotBefore, validityNotAfter, {}); } optional<vector<SecureAccessControlProfile>> addAccessControlProfiles( diff --git a/identity/aidl/vts/VtsIdentityTestUtils.h b/identity/aidl/vts/Util.h index 85c24f86b5..80e52a21da 100644 --- a/identity/aidl/vts/VtsIdentityTestUtils.h +++ b/identity/aidl/vts/Util.h @@ -21,6 +21,7 @@ #include <android/hardware/identity/support/IdentityCredentialSupport.h> #include <cppbor.h> #include <cppbor_parse.h> +#include <gtest/gtest.h> namespace android::hardware::identity::test_utils { diff --git a/identity/aidl/vts/VtsAttestationTests.cpp b/identity/aidl/vts/VtsAttestationTests.cpp index 5529853009..e12fe051d5 100644 --- a/identity/aidl/vts/VtsAttestationTests.cpp +++ b/identity/aidl/vts/VtsAttestationTests.cpp @@ -29,7 +29,7 @@ #include <future> #include <map> -#include "VtsIdentityTestUtils.h" +#include "Util.h" namespace android::hardware::identity { diff --git a/identity/aidl/vts/VtsIWritableIdentityCredentialTests.cpp b/identity/aidl/vts/VtsIWritableIdentityCredentialTests.cpp index 1629a0c952..cc63c482f1 100644 --- a/identity/aidl/vts/VtsIWritableIdentityCredentialTests.cpp +++ b/identity/aidl/vts/VtsIWritableIdentityCredentialTests.cpp @@ -29,7 +29,7 @@ #include <future> #include <map> -#include "VtsIdentityTestUtils.h" +#include "Util.h" namespace android::hardware::identity { diff --git a/identity/support/include/android/hardware/identity/support/IdentityCredentialSupport.h b/identity/support/include/android/hardware/identity/support/IdentityCredentialSupport.h index 3aa5bb641e..3b91de6dcc 100644 --- a/identity/support/include/android/hardware/identity/support/IdentityCredentialSupport.h +++ b/identity/support/include/android/hardware/identity/support/IdentityCredentialSupport.h @@ -18,6 +18,7 @@ #define IDENTITY_SUPPORT_INCLUDE_IDENTITY_CREDENTIAL_UTILS_H_ #include <cstdint> +#include <map> #include <optional> #include <string> #include <tuple> @@ -29,11 +30,12 @@ namespace hardware { namespace identity { namespace support { +using ::std::map; using ::std::optional; +using ::std::pair; using ::std::string; using ::std::tuple; using ::std::vector; -using ::std::pair; // The semantic tag for a bstr which includes Encoded CBOR (RFC 7049, section 2.4) const int kSemanticTagEncodedCbor = 24; @@ -221,6 +223,11 @@ optional<pair<size_t, size_t>> certificateFindSignature(const vector<uint8_t>& x // optional<pair<time_t, time_t>> certificateGetValidity(const vector<uint8_t>& x509Certificate); +// Looks for an extension with OID in |oidStr| which must be an stored as an OCTET STRING. +// +optional<vector<uint8_t>> certificateGetExtension(const vector<uint8_t>& x509Certificate, + const string& oidStr); + // Generates a X.509 certificate for |publicKey| (which must be in the format // returned by ecKeyPairGetPublicKey()). // @@ -230,7 +237,8 @@ optional<pair<time_t, time_t>> certificateGetValidity(const vector<uint8_t>& x50 optional<vector<uint8_t>> ecPublicKeyGenerateCertificate( const vector<uint8_t>& publicKey, const vector<uint8_t>& signingKey, const string& serialDecimal, const string& issuer, const string& subject, - time_t validityNotBefore, time_t validityNotAfter); + time_t validityNotBefore, time_t validityNotAfter, + const map<string, vector<uint8_t>>& extensions); // Performs Elliptic-curve Diffie-Helman using |publicKey| (which must be in the // format returned by ecKeyPairGetPublicKey()) and |privateKey| (which must be diff --git a/identity/support/src/IdentityCredentialSupport.cpp b/identity/support/src/IdentityCredentialSupport.cpp index 093120d032..38348ac1b0 100644 --- a/identity/support/src/IdentityCredentialSupport.cpp +++ b/identity/support/src/IdentityCredentialSupport.cpp @@ -344,15 +344,22 @@ string cborPrettyPrint(const vector<uint8_t>& encodedCbor, size_t maxBStrSize, // Crypto functionality / abstraction. // --------------------------------------------------------------------------- -struct EVP_CIPHER_CTX_Deleter { - void operator()(EVP_CIPHER_CTX* ctx) const { - if (ctx != nullptr) { - EVP_CIPHER_CTX_free(ctx); - } - } -}; - -using EvpCipherCtxPtr = unique_ptr<EVP_CIPHER_CTX, EVP_CIPHER_CTX_Deleter>; +using EvpCipherCtxPtr = bssl::UniquePtr<EVP_CIPHER_CTX>; +using EC_KEY_Ptr = bssl::UniquePtr<EC_KEY>; +using EVP_PKEY_Ptr = bssl::UniquePtr<EVP_PKEY>; +using EVP_PKEY_CTX_Ptr = bssl::UniquePtr<EVP_PKEY_CTX>; +using EC_GROUP_Ptr = bssl::UniquePtr<EC_GROUP>; +using EC_POINT_Ptr = bssl::UniquePtr<EC_POINT>; +using ECDSA_SIG_Ptr = bssl::UniquePtr<ECDSA_SIG>; +using X509_Ptr = bssl::UniquePtr<X509>; +using PKCS12_Ptr = bssl::UniquePtr<PKCS12>; +using BIGNUM_Ptr = bssl::UniquePtr<BIGNUM>; +using ASN1_INTEGER_Ptr = bssl::UniquePtr<ASN1_INTEGER>; +using ASN1_TIME_Ptr = bssl::UniquePtr<ASN1_TIME>; +using ASN1_OCTET_STRING_Ptr = bssl::UniquePtr<ASN1_OCTET_STRING>; +using ASN1_OBJECT_Ptr = bssl::UniquePtr<ASN1_OBJECT>; +using X509_NAME_Ptr = bssl::UniquePtr<X509_NAME>; +using X509_EXTENSION_Ptr = bssl::UniquePtr<X509_EXTENSION>; // bool getRandom(size_t numBytes, vector<uint8_t>& output) { optional<vector<uint8_t>> getRandom(size_t numBytes) { @@ -534,115 +541,6 @@ optional<vector<uint8_t>> encryptAes128Gcm(const vector<uint8_t>& key, const vec return encryptedData; } -struct EC_KEY_Deleter { - void operator()(EC_KEY* key) const { - if (key != nullptr) { - EC_KEY_free(key); - } - } -}; -using EC_KEY_Ptr = unique_ptr<EC_KEY, EC_KEY_Deleter>; - -struct EVP_PKEY_Deleter { - void operator()(EVP_PKEY* key) const { - if (key != nullptr) { - EVP_PKEY_free(key); - } - } -}; -using EVP_PKEY_Ptr = unique_ptr<EVP_PKEY, EVP_PKEY_Deleter>; - -struct EVP_PKEY_CTX_Deleter { - void operator()(EVP_PKEY_CTX* ctx) const { - if (ctx != nullptr) { - EVP_PKEY_CTX_free(ctx); - } - } -}; -using EVP_PKEY_CTX_Ptr = unique_ptr<EVP_PKEY_CTX, EVP_PKEY_CTX_Deleter>; - -struct EC_GROUP_Deleter { - void operator()(EC_GROUP* group) const { - if (group != nullptr) { - EC_GROUP_free(group); - } - } -}; -using EC_GROUP_Ptr = unique_ptr<EC_GROUP, EC_GROUP_Deleter>; - -struct EC_POINT_Deleter { - void operator()(EC_POINT* point) const { - if (point != nullptr) { - EC_POINT_free(point); - } - } -}; - -using EC_POINT_Ptr = unique_ptr<EC_POINT, EC_POINT_Deleter>; - -struct ECDSA_SIG_Deleter { - void operator()(ECDSA_SIG* sig) const { - if (sig != nullptr) { - ECDSA_SIG_free(sig); - } - } -}; -using ECDSA_SIG_Ptr = unique_ptr<ECDSA_SIG, ECDSA_SIG_Deleter>; - -struct X509_Deleter { - void operator()(X509* x509) const { - if (x509 != nullptr) { - X509_free(x509); - } - } -}; -using X509_Ptr = unique_ptr<X509, X509_Deleter>; - -struct PKCS12_Deleter { - void operator()(PKCS12* pkcs12) const { - if (pkcs12 != nullptr) { - PKCS12_free(pkcs12); - } - } -}; -using PKCS12_Ptr = unique_ptr<PKCS12, PKCS12_Deleter>; - -struct BIGNUM_Deleter { - void operator()(BIGNUM* bignum) const { - if (bignum != nullptr) { - BN_free(bignum); - } - } -}; -using BIGNUM_Ptr = unique_ptr<BIGNUM, BIGNUM_Deleter>; - -struct ASN1_INTEGER_Deleter { - void operator()(ASN1_INTEGER* value) const { - if (value != nullptr) { - ASN1_INTEGER_free(value); - } - } -}; -using ASN1_INTEGER_Ptr = unique_ptr<ASN1_INTEGER, ASN1_INTEGER_Deleter>; - -struct ASN1_TIME_Deleter { - void operator()(ASN1_TIME* value) const { - if (value != nullptr) { - ASN1_TIME_free(value); - } - } -}; -using ASN1_TIME_Ptr = unique_ptr<ASN1_TIME, ASN1_TIME_Deleter>; - -struct X509_NAME_Deleter { - void operator()(X509_NAME* value) const { - if (value != nullptr) { - X509_NAME_free(value); - } - } -}; -using X509_NAME_Ptr = unique_ptr<X509_NAME, X509_NAME_Deleter>; - vector<uint8_t> certificateChainJoin(const vector<vector<uint8_t>>& certificateChain) { vector<uint8_t> ret; for (const vector<uint8_t>& certificate : certificateChain) { @@ -1221,8 +1119,19 @@ optional<vector<uint8_t>> ecKeyPairGetPrivateKey(const vector<uint8_t>& keyPair) return {}; } vector<uint8_t> privateKey; - privateKey.resize(BN_num_bytes(bignum)); - BN_bn2bin(bignum, privateKey.data()); + + // Note that this may return fewer than 32 bytes so pad with zeroes since we + // want to always return 32 bytes. + size_t numBytes = BN_num_bytes(bignum); + if (numBytes > 32) { + LOG(ERROR) << "Size is " << numBytes << ", expected this to be 32 or less"; + return {}; + } + privateKey.resize(32); + for (size_t n = 0; n < 32 - numBytes; n++) { + privateKey[n] = 0x00; + } + BN_bn2bin(bignum, privateKey.data() + 32 - numBytes); return privateKey; } @@ -1379,7 +1288,8 @@ optional<vector<uint8_t>> ecKeyPairGetPkcs12(const vector<uint8_t>& keyPair, con optional<vector<uint8_t>> ecPublicKeyGenerateCertificate( const vector<uint8_t>& publicKey, const vector<uint8_t>& signingKey, const string& serialDecimal, const string& issuer, const string& subject, - time_t validityNotBefore, time_t validityNotAfter) { + time_t validityNotBefore, time_t validityNotAfter, + const map<string, vector<uint8_t>>& extensions) { auto group = EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1)); auto point = EC_POINT_Ptr(EC_POINT_new(group.get())); if (EC_POINT_oct2point(group.get(), point.get(), publicKey.data(), publicKey.size(), nullptr) != @@ -1482,6 +1392,32 @@ optional<vector<uint8_t>> ecPublicKeyGenerateCertificate( return {}; } + for (auto const& [oidStr, blob] : extensions) { + ASN1_OBJECT_Ptr oid( + OBJ_txt2obj(oidStr.c_str(), 1)); // accept numerical dotted string form only + if (!oid.get()) { + LOG(ERROR) << "Error setting OID"; + return {}; + } + ASN1_OCTET_STRING_Ptr octetString(ASN1_OCTET_STRING_new()); + if (!ASN1_OCTET_STRING_set(octetString.get(), blob.data(), blob.size())) { + LOG(ERROR) << "Error setting octet string for extension"; + return {}; + } + + X509_EXTENSION_Ptr extension = X509_EXTENSION_Ptr(X509_EXTENSION_new()); + extension.reset(X509_EXTENSION_create_by_OBJ(nullptr, oid.get(), 0 /* not critical */, + octetString.get())); + if (!extension.get()) { + LOG(ERROR) << "Error setting extension"; + return {}; + } + if (!X509_add_ext(x509.get(), extension.get(), -1)) { + LOG(ERROR) << "Error adding extension"; + return {}; + } + } + if (X509_sign(x509.get(), privPkey.get(), EVP_sha256()) == 0) { LOG(ERROR) << "Error signing X509 certificate"; return {}; @@ -1650,6 +1586,44 @@ optional<vector<uint8_t>> certificateChainGetTopMostKey(const vector<uint8_t>& c return publicKey; } +optional<vector<uint8_t>> certificateGetExtension(const vector<uint8_t>& x509Certificate, + const string& oidStr) { + vector<X509_Ptr> certs; + if (!parseX509Certificates(x509Certificate, certs)) { + return {}; + } + if (certs.size() < 1) { + LOG(ERROR) << "No certificates in chain"; + return {}; + } + + ASN1_OBJECT_Ptr oid( + OBJ_txt2obj(oidStr.c_str(), 1)); // accept numerical dotted string form only + if (!oid.get()) { + LOG(ERROR) << "Error setting OID"; + return {}; + } + + int location = X509_get_ext_by_OBJ(certs[0].get(), oid.get(), -1 /* search from beginning */); + if (location == -1) { + return {}; + } + + X509_EXTENSION* ext = X509_get_ext(certs[0].get(), location); + if (ext == nullptr) { + return {}; + } + + ASN1_OCTET_STRING* octetString = X509_EXTENSION_get_data(ext); + if (octetString == nullptr) { + return {}; + } + vector<uint8_t> result; + result.resize(octetString->length); + memcpy(result.data(), octetString->data, octetString->length); + return result; +} + optional<pair<size_t, size_t>> certificateFindPublicKey(const vector<uint8_t>& x509Certificate) { vector<X509_Ptr> certs; if (!parseX509Certificates(x509Certificate, certs)) { diff --git a/identity/support/tests/IdentityCredentialSupportTest.cpp b/identity/support/tests/IdentityCredentialSupportTest.cpp index 266f263203..509133cbc9 100644 --- a/identity/support/tests/IdentityCredentialSupportTest.cpp +++ b/identity/support/tests/IdentityCredentialSupportTest.cpp @@ -271,7 +271,7 @@ vector<uint8_t> generateCertChain(size_t numCerts) { optional<vector<uint8_t>> pubKey = support::ecKeyPairGetPublicKey(keyPair.value()); optional<vector<uint8_t>> cert = support::ecPublicKeyGenerateCertificate( - pubKey.value(), privKey.value(), "0001", "someIssuer", "someSubject", 0, 0); + pubKey.value(), privKey.value(), "0001", "someIssuer", "someSubject", 0, 0, {}); certs.push_back(cert.value()); } return support::certificateChainJoin(certs); @@ -338,7 +338,7 @@ TEST(IdentityCredentialSupport, CertificateChain) { ASSERT_TRUE(pubKey); optional<vector<uint8_t>> cert = support::ecPublicKeyGenerateCertificate( - pubKey.value(), privKey.value(), "0001", "someIssuer", "someSubject", 0, 0); + pubKey.value(), privKey.value(), "0001", "someIssuer", "someSubject", 0, 0, {}); optional<vector<uint8_t>> extractedPubKey = support::certificateChainGetTopMostKey(cert.value()); @@ -358,7 +358,7 @@ TEST(IdentityCredentialSupport, CertificateChain) { optional<vector<uint8_t>> otherPubKey = support::ecKeyPairGetPublicKey(keyPair.value()); ASSERT_TRUE(otherPubKey); optional<vector<uint8_t>> otherCert = support::ecPublicKeyGenerateCertificate( - otherPubKey.value(), privKey.value(), "0001", "someIssuer", "someSubject", 0, 0); + otherPubKey.value(), privKey.value(), "0001", "someIssuer", "someSubject", 0, 0, {}); // Now both cert and otherCert are two distinct certificates. Let's make a // chain and check that certificateChainSplit() works as expected. diff --git a/light/aidl/default/Android.bp b/light/aidl/default/Android.bp index ae3f4630de..4e43ba9c63 100644 --- a/light/aidl/default/Android.bp +++ b/light/aidl/default/Android.bp @@ -7,7 +7,7 @@ cc_binary { shared_libs: [ "libbase", "libbinder_ndk", - "android.hardware.light-ndk_platform", + "android.hardware.light-V1-ndk_platform", ], srcs: [ "Lights.cpp", diff --git a/light/aidl/vts/functional/Android.bp b/light/aidl/vts/functional/Android.bp index aa4719b739..4c9356c9ca 100644 --- a/light/aidl/vts/functional/Android.bp +++ b/light/aidl/vts/functional/Android.bp @@ -27,7 +27,7 @@ cc_test { "libbinder", ], static_libs: [ - "android.hardware.light-cpp", + "android.hardware.light-V1-cpp", ], test_suites: [ "vts", diff --git a/light/utils/Android.bp b/light/utils/Android.bp index e901129d1f..871f983532 100644 --- a/light/utils/Android.bp +++ b/light/utils/Android.bp @@ -28,6 +28,6 @@ cc_binary { "libutils", ], static_libs: [ - "android.hardware.light-cpp", + "android.hardware.light-V1-cpp", ], } diff --git a/memtrack/aidl/default/Android.bp b/memtrack/aidl/default/Android.bp index 52f88c8097..8d97bfc703 100644 --- a/memtrack/aidl/default/Android.bp +++ b/memtrack/aidl/default/Android.bp @@ -21,7 +21,7 @@ cc_binary { shared_libs: [ "libbase", "libbinder_ndk", - "android.hardware.memtrack-ndk_platform", + "android.hardware.memtrack-V1-ndk_platform", ], srcs: [ "main.cpp", diff --git a/memtrack/aidl/default/Memtrack.cpp b/memtrack/aidl/default/Memtrack.cpp index 7361719002..000b25c030 100644 --- a/memtrack/aidl/default/Memtrack.cpp +++ b/memtrack/aidl/default/Memtrack.cpp @@ -35,6 +35,8 @@ ndk::ScopedAStatus Memtrack::getMemory(int pid, MemtrackType type, ndk::ScopedAStatus Memtrack::getGpuDeviceInfo(std::vector<DeviceInfo>* _aidl_return) { _aidl_return->clear(); + DeviceInfo dev_info = {.id = 0, .name = "virtio_gpu"}; + _aidl_return->emplace_back(dev_info); return ndk::ScopedAStatus::ok(); } diff --git a/memtrack/aidl/vts/Android.bp b/memtrack/aidl/vts/Android.bp index ea36677237..df87db843f 100644 --- a/memtrack/aidl/vts/Android.bp +++ b/memtrack/aidl/vts/Android.bp @@ -7,9 +7,10 @@ cc_test { srcs: ["VtsHalMemtrackTargetTest.cpp"], shared_libs: [ "libbinder_ndk", + "libvintf", ], static_libs: [ - "android.hardware.memtrack-unstable-ndk_platform", + "android.hardware.memtrack-V1-ndk_platform", ], test_suites: [ "vts-core", diff --git a/memtrack/aidl/vts/VtsHalMemtrackTargetTest.cpp b/memtrack/aidl/vts/VtsHalMemtrackTargetTest.cpp index 4d331014ba..d5f4612ca2 100644 --- a/memtrack/aidl/vts/VtsHalMemtrackTargetTest.cpp +++ b/memtrack/aidl/vts/VtsHalMemtrackTargetTest.cpp @@ -21,11 +21,15 @@ #include <aidl/android/hardware/memtrack/MemtrackType.h> #include <android/binder_manager.h> #include <android/binder_process.h> +#include <vintf/VintfObject.h> using aidl::android::hardware::memtrack::DeviceInfo; using aidl::android::hardware::memtrack::IMemtrack; using aidl::android::hardware::memtrack::MemtrackRecord; using aidl::android::hardware::memtrack::MemtrackType; +using android::vintf::KernelVersion; +using android::vintf::RuntimeInfo; +using android::vintf::VintfObject; class MemtrackAidlTest : public testing::TestWithParam<std::string> { public: @@ -75,7 +79,23 @@ TEST_P(MemtrackAidlTest, GetGpuDeviceInfo) { auto status = memtrack_->getGpuDeviceInfo(&device_info); + // Devices with < 5.4 kernels aren't required to provide an implementation of + // getGpuDeviceInfo(), and can return EX_UNSUPPORTED_OPERATION + if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) { + KernelVersion min_kernel_version = KernelVersion(5, 4, 0); + KernelVersion kernel_version = VintfObject::GetInstance() + ->getRuntimeInfo(RuntimeInfo::FetchFlag::CPU_VERSION) + ->kernelVersion(); + EXPECT_LT(kernel_version, min_kernel_version) + << "Devices with 5.10 or later kernels must implement getGpuDeviceInfo()"; + return; + } + EXPECT_TRUE(status.isOk()); + EXPECT_FALSE(device_info.empty()); + for (auto device : device_info) { + EXPECT_FALSE(device.name.empty()); + } } GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MemtrackAidlTest); diff --git a/neuralnetworks/1.0/vts/functional/AndroidTest.xml b/neuralnetworks/1.0/vts/functional/AndroidTest.xml index 13671f92b8..9dd85ae7f1 100644 --- a/neuralnetworks/1.0/vts/functional/AndroidTest.xml +++ b/neuralnetworks/1.0/vts/functional/AndroidTest.xml @@ -28,5 +28,6 @@ <test class="com.android.tradefed.testtype.GTest" > <option name="native-test-device-path" value="/data/local/tmp" /> <option name="module-name" value="VtsHalNeuralnetworksV1_0TargetTest" /> + <option name="native-test-timeout" value="20m" /> </test> </configuration> diff --git a/neuralnetworks/1.1/vts/functional/AndroidTest.xml b/neuralnetworks/1.1/vts/functional/AndroidTest.xml index cfde60cca4..74001f924e 100644 --- a/neuralnetworks/1.1/vts/functional/AndroidTest.xml +++ b/neuralnetworks/1.1/vts/functional/AndroidTest.xml @@ -28,5 +28,6 @@ <test class="com.android.tradefed.testtype.GTest" > <option name="native-test-device-path" value="/data/local/tmp" /> <option name="module-name" value="VtsHalNeuralnetworksV1_1TargetTest" /> + <option name="native-test-timeout" value="20m" /> </test> </configuration> diff --git a/oemlock/aidl/default/Android.bp b/oemlock/aidl/default/Android.bp index b9872d7eda..464b0a3d60 100644 --- a/oemlock/aidl/default/Android.bp +++ b/oemlock/aidl/default/Android.bp @@ -25,7 +25,7 @@ cc_binary { "OemLock.cpp", ], shared_libs: [ - "android.hardware.oemlock-ndk_platform", + "android.hardware.oemlock-V1-ndk_platform", "libbase", "libbinder_ndk", ], diff --git a/oemlock/aidl/vts/Android.bp b/oemlock/aidl/vts/Android.bp index a13dbe2cc7..18b53c2e7d 100644 --- a/oemlock/aidl/vts/Android.bp +++ b/oemlock/aidl/vts/Android.bp @@ -25,7 +25,7 @@ cc_test { "libbinder_ndk", "libbase", ], - static_libs: ["android.hardware.oemlock-ndk_platform"], + static_libs: ["android.hardware.oemlock-V1-ndk_platform"], test_suites: [ "general-tests", "vts", diff --git a/power/aidl/default/Android.bp b/power/aidl/default/Android.bp index 07cd368a54..de04bcdcfc 100644 --- a/power/aidl/default/Android.bp +++ b/power/aidl/default/Android.bp @@ -21,7 +21,7 @@ cc_binary { shared_libs: [ "libbase", "libbinder_ndk", - "android.hardware.power-ndk_platform", + "android.hardware.power-V1-ndk_platform", ], srcs: [ "main.cpp", diff --git a/power/aidl/vts/Android.bp b/power/aidl/vts/Android.bp index 28b08c7c4e..008073bdf8 100644 --- a/power/aidl/vts/Android.bp +++ b/power/aidl/vts/Android.bp @@ -23,7 +23,7 @@ cc_test { "libbinder", ], static_libs: [ - "android.hardware.power-cpp", + "android.hardware.power-V1-cpp", ], test_suites: [ "vts", diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/Channel.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/Channel.aidl new file mode 100644 index 0000000000..e0c372b308 --- /dev/null +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/Channel.aidl @@ -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. + *//////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m <name>-update-api`. +// +// You must not make a backward incompatible change to any AIDL file 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.power.stats; +@VintfStability +parcelable Channel { + int id; + @utf8InCpp String name; + @utf8InCpp String subsystem; +} diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/ChannelInfo.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/ChannelInfo.aidl deleted file mode 100644 index 209bec4aa7..0000000000 --- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/ChannelInfo.aidl +++ /dev/null @@ -1,23 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// 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.power.stats; -@VintfStability -parcelable ChannelInfo { - int channelId; - @utf8InCpp String channelName; -} diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumer.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumer.aidl new file mode 100644 index 0000000000..c8d7645ba2 --- /dev/null +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumer.aidl @@ -0,0 +1,40 @@ +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m <name>-update-api`. +// +// You must not make a backward incompatible change to any AIDL file 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.power.stats; +@VintfStability +parcelable EnergyConsumer { + int id; + int ordinal; + android.hardware.power.stats.EnergyConsumerType type; + @utf8InCpp String name; +} diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerAttribution.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerAttribution.aidl index 0a7cff7d01..2fdc1a5d6a 100644 --- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerAttribution.aidl +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerAttribution.aidl @@ -1,14 +1,29 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // 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. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m <name>-update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file 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 diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerId.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerId.aidl deleted file mode 100644 index 7ca3b15ff1..0000000000 --- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerId.aidl +++ /dev/null @@ -1,23 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// 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.power.stats; -@Backing(type="int") @VintfStability -enum EnergyConsumerId { - DISPLAY = 0, - GPS = 1, -} diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerResult.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerResult.aidl index 815316ec92..4937aef992 100644 --- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerResult.aidl +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerResult.aidl @@ -1,14 +1,29 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // 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. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m <name>-update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file 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 @@ -18,7 +33,7 @@ package android.hardware.power.stats; @VintfStability parcelable EnergyConsumerResult { - android.hardware.power.stats.EnergyConsumerId energyConsumerId; + int id; long timestampMs; long energyUWs; android.hardware.power.stats.EnergyConsumerAttribution[] attribution; diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerType.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerType.aidl new file mode 100644 index 0000000000..7b05d2f426 --- /dev/null +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerType.aidl @@ -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. + *//////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m <name>-update-api`. +// +// You must not make a backward incompatible change to any AIDL file 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.power.stats; +@VintfStability +enum EnergyConsumerType { + OTHER = 0, + CPU_CLUSTER = 1, + DISPLAY = 2, +} diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyMeasurement.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyMeasurement.aidl index 4d56ccf379..2d6ae165fd 100644 --- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyMeasurement.aidl +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyMeasurement.aidl @@ -1,14 +1,29 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // 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. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m <name>-update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file 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 @@ -18,7 +33,7 @@ package android.hardware.power.stats; @VintfStability parcelable EnergyMeasurement { - int channelId; + int id; long timestampMs; long durationMs; long energyUWs; diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/IPowerStats.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/IPowerStats.aidl index 07013b0b45..5b11695e85 100644 --- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/IPowerStats.aidl +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/IPowerStats.aidl @@ -1,14 +1,29 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // 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. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m <name>-update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file 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 @@ -18,10 +33,10 @@ package android.hardware.power.stats; @VintfStability interface IPowerStats { - android.hardware.power.stats.PowerEntityInfo[] getPowerEntityInfo(); + android.hardware.power.stats.PowerEntity[] getPowerEntityInfo(); android.hardware.power.stats.StateResidencyResult[] getStateResidency(in int[] powerEntityIds); - android.hardware.power.stats.EnergyConsumerId[] getEnergyConsumerInfo(); - android.hardware.power.stats.EnergyConsumerResult[] getEnergyConsumed(in android.hardware.power.stats.EnergyConsumerId[] energyConsumerIds); - android.hardware.power.stats.ChannelInfo[] getEnergyMeterInfo(); - android.hardware.power.stats.EnergyMeasurement[] readEnergyMeters(in int[] channelIds); + android.hardware.power.stats.EnergyConsumer[] getEnergyConsumerInfo(); + android.hardware.power.stats.EnergyConsumerResult[] getEnergyConsumed(in int[] energyConsumerIds); + android.hardware.power.stats.Channel[] getEnergyMeterInfo(); + android.hardware.power.stats.EnergyMeasurement[] readEnergyMeter(in int[] channelIds); } diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/PowerEntity.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/PowerEntity.aidl new file mode 100644 index 0000000000..38a62acf1e --- /dev/null +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/PowerEntity.aidl @@ -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. + *//////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m <name>-update-api`. +// +// You must not make a backward incompatible change to any AIDL file 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.power.stats; +@VintfStability +parcelable PowerEntity { + int id; + @utf8InCpp String name; + android.hardware.power.stats.State[] states; +} diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/PowerEntityInfo.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/PowerEntityInfo.aidl deleted file mode 100644 index 3b16362046..0000000000 --- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/PowerEntityInfo.aidl +++ /dev/null @@ -1,24 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// 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.power.stats; -@VintfStability -parcelable PowerEntityInfo { - int powerEntityId; - @utf8InCpp String powerEntityName; - android.hardware.power.stats.StateInfo[] states; -} diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/State.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/State.aidl new file mode 100644 index 0000000000..1c5d7c13e3 --- /dev/null +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/State.aidl @@ -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. + *//////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m <name>-update-api`. +// +// You must not make a backward incompatible change to any AIDL file 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.power.stats; +@VintfStability +parcelable State { + int id; + @utf8InCpp String name; +} diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateInfo.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateInfo.aidl deleted file mode 100644 index 0db9ab190d..0000000000 --- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateInfo.aidl +++ /dev/null @@ -1,23 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// 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.power.stats; -@VintfStability -parcelable StateInfo { - int stateId; - @utf8InCpp String stateName; -} diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidency.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidency.aidl index 206c974bc5..7982f02063 100644 --- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidency.aidl +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidency.aidl @@ -1,14 +1,29 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // 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. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m <name>-update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file 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 @@ -18,7 +33,7 @@ package android.hardware.power.stats; @VintfStability parcelable StateResidency { - int stateId; + int id; long totalTimeInStateMs; long totalStateEntryCount; long lastEntryTimestampMs; diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidencyResult.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidencyResult.aidl index dc41fef557..5bc548e437 100644 --- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidencyResult.aidl +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidencyResult.aidl @@ -1,14 +1,29 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // 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. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m <name>-update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file 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 @@ -18,6 +33,6 @@ package android.hardware.power.stats; @VintfStability parcelable StateResidencyResult { - int powerEntityId; + int id; android.hardware.power.stats.StateResidency[] stateResidencyData; } diff --git a/power/stats/aidl/android/hardware/power/stats/ChannelInfo.aidl b/power/stats/aidl/android/hardware/power/stats/Channel.aidl index a2ca6a63f1..5e8962e256 100644 --- a/power/stats/aidl/android/hardware/power/stats/ChannelInfo.aidl +++ b/power/stats/aidl/android/hardware/power/stats/Channel.aidl @@ -17,14 +17,19 @@ package android.hardware.power.stats; @VintfStability -parcelable ChannelInfo { +parcelable Channel { /** - * Unique ID of this ChannelInfo + * Unique ID of this Channel */ - int channelId; + int id; /** - * Unique name of the ChannelInfo. Vendor/device specific. Opaque to framework + * Unique name of this Channel. Vendor/device specific. Opaque to framework */ - @utf8InCpp String channelName; + @utf8InCpp String name; + + /** + * Name of the subsystem associated with this Channel. Opaque to framework + */ + @utf8InCpp String subsystem; } diff --git a/power/stats/aidl/android/hardware/power/stats/EnergyConsumer.aidl b/power/stats/aidl/android/hardware/power/stats/EnergyConsumer.aidl new file mode 100644 index 0000000000..2ff1279584 --- /dev/null +++ b/power/stats/aidl/android/hardware/power/stats/EnergyConsumer.aidl @@ -0,0 +1,41 @@ +/* + * 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.power.stats; + +import android.hardware.power.stats.EnergyConsumerType; + +@VintfStability +parcelable EnergyConsumer { + /** + * Unique ID of this EnergyConsumer + */ + int id; + + /** + * For a group of EnergyConsumers of the same logical type, sorting by ordinal + * gives their physical order. Ordinals must be consecutive integers starting from 0. + */ + int ordinal; + + /* Type of this EnergyConsumer */ + EnergyConsumerType type; + + /** + * Unique name of this EnergyConsumer. Vendor/device specific. Opaque to framework + */ + @utf8InCpp String name; +}
\ No newline at end of file diff --git a/power/stats/aidl/android/hardware/power/stats/EnergyConsumerAttribution.aidl b/power/stats/aidl/android/hardware/power/stats/EnergyConsumerAttribution.aidl index e07204aa33..5767de1656 100644 --- a/power/stats/aidl/android/hardware/power/stats/EnergyConsumerAttribution.aidl +++ b/power/stats/aidl/android/hardware/power/stats/EnergyConsumerAttribution.aidl @@ -19,7 +19,7 @@ package android.hardware.power.stats; @VintfStability parcelable EnergyConsumerAttribution { /** - * Android ID / Linux UID, the accumulated energy should be attributed to + * Android ID / Linux UID, the accumulated energy is attributed to */ int uid; /** diff --git a/power/stats/aidl/android/hardware/power/stats/EnergyConsumerResult.aidl b/power/stats/aidl/android/hardware/power/stats/EnergyConsumerResult.aidl index e8d3dd9f94..12d2042eb2 100644 --- a/power/stats/aidl/android/hardware/power/stats/EnergyConsumerResult.aidl +++ b/power/stats/aidl/android/hardware/power/stats/EnergyConsumerResult.aidl @@ -16,7 +16,6 @@ package android.hardware.power.stats; -import android.hardware.power.stats.EnergyConsumerId; import android.hardware.power.stats.EnergyConsumerAttribution; @VintfStability @@ -24,17 +23,18 @@ parcelable EnergyConsumerResult { /** * ID of the EnergyConsumer associated with this result */ - EnergyConsumerId energyConsumerId; + int id; /** * Time since boot in milliseconds */ long timestampMs; /** - * Accumulated energy since boot in microwatt-seconds (uWs) + * Total accumulated energy since boot in microwatt-seconds (uWs) */ long energyUWs; /** - * Optional attribution per UID for this EnergyConsumer. + * Optional attributed energy per Android ID / Linux UID for this EnergyConsumer. + * Sum total of attributed energy must be less than or equal to total accumulated energy. */ EnergyConsumerAttribution[] attribution; } diff --git a/power/stats/aidl/android/hardware/power/stats/EnergyConsumerId.aidl b/power/stats/aidl/android/hardware/power/stats/EnergyConsumerType.aidl index 4a6a67724d..7fd2348d70 100644 --- a/power/stats/aidl/android/hardware/power/stats/EnergyConsumerId.aidl +++ b/power/stats/aidl/android/hardware/power/stats/EnergyConsumerType.aidl @@ -16,9 +16,10 @@ package android.hardware.power.stats; +/* Indicates the type of an energy consumer reported by the Power Stats HAL */ @VintfStability -@Backing(type="int") -enum EnergyConsumerId { - DISPLAY = 0, - GPS = 1, +enum EnergyConsumerType { + OTHER, + CPU_CLUSTER, + DISPLAY, }
\ No newline at end of file diff --git a/power/stats/aidl/android/hardware/power/stats/EnergyMeasurement.aidl b/power/stats/aidl/android/hardware/power/stats/EnergyMeasurement.aidl index d81914d1f0..d3e8f46699 100644 --- a/power/stats/aidl/android/hardware/power/stats/EnergyMeasurement.aidl +++ b/power/stats/aidl/android/hardware/power/stats/EnergyMeasurement.aidl @@ -21,7 +21,7 @@ parcelable EnergyMeasurement { /** * ID of the Channel associated with this measurement */ - int channelId; + int id; /** * Approximate time of data capture in millseconds since boot */ diff --git a/power/stats/aidl/android/hardware/power/stats/IPowerStats.aidl b/power/stats/aidl/android/hardware/power/stats/IPowerStats.aidl index 05e2004b67..7a95f744d0 100644 --- a/power/stats/aidl/android/hardware/power/stats/IPowerStats.aidl +++ b/power/stats/aidl/android/hardware/power/stats/IPowerStats.aidl @@ -16,11 +16,11 @@ package android.hardware.power.stats; -import android.hardware.power.stats.ChannelInfo; -import android.hardware.power.stats.EnergyConsumerId; +import android.hardware.power.stats.Channel; +import android.hardware.power.stats.EnergyConsumer; import android.hardware.power.stats.EnergyConsumerResult; import android.hardware.power.stats.EnergyMeasurement; -import android.hardware.power.stats.PowerEntityInfo; +import android.hardware.power.stats.PowerEntity; import android.hardware.power.stats.StateResidencyResult; @VintfStability @@ -34,7 +34,7 @@ interface IPowerStats { * * @return List of information on each PowerEntity */ - PowerEntityInfo[] getPowerEntityInfo(); + PowerEntity[] getPowerEntityInfo(); /** * Reports the accumulated state residency for each requested PowerEntity. @@ -61,15 +61,14 @@ interface IPowerStats { StateResidencyResult[] getStateResidency(in int[] powerEntityIds); /** - * Return the list IDs for all supported EnergyConsumers for which energy consumption data is - * available. + * Return the list EnergyConsumers for which energy consumption data is available. * * An EnergyConsumer is a device subsystem or peripheral that consumes energy. Energy * consumption data may be used by framework for the purpose of power attribution. * - * @return List of EnergyConsumersIds that are available. + * @return List of EnergyConsumers that are available. */ - EnergyConsumerId[] getEnergyConsumerInfo(); + EnergyConsumer[] getEnergyConsumerInfo(); /** * Reports the energy consumed since boot by each requested EnergyConsumer. @@ -83,7 +82,7 @@ interface IPowerStats { * - STATUS_BAD_VALUE if an invalid energyConsumerId is provided * - STATUS_FAILED_TRANSACTION if any EnergyConsumerResult fails to be returned */ - EnergyConsumerResult[] getEnergyConsumed(in EnergyConsumerId[] energyConsumerIds); + EnergyConsumerResult[] getEnergyConsumed(in int[] energyConsumerIds); /** * Return information related to all channels monitored by Energy Meters. @@ -91,9 +90,9 @@ interface IPowerStats { * An Energy Meter is a device that monitors energy and may support monitoring multiple * channels simultaneously. A channel may correspond a bus, sense resistor, or power rail. * - * @return Information about channels monitored by Energy Meters. + * @return Channels monitored by Energy Meters. */ - ChannelInfo[] getEnergyMeterInfo(); + Channel[] getEnergyMeterInfo(); /** * Reports accumulated energy for each specified channel. @@ -108,5 +107,5 @@ interface IPowerStats { * - STATUS_BAD_VALUE if an invalid channelId is provided * - STATUS_FAILED_TRANSACTION if any EnergyMeasurement fails to be returned */ - EnergyMeasurement[] readEnergyMeters(in int[] channelIds); -}
\ No newline at end of file + EnergyMeasurement[] readEnergyMeter(in int[] channelIds); +} diff --git a/power/stats/aidl/android/hardware/power/stats/PowerEntityInfo.aidl b/power/stats/aidl/android/hardware/power/stats/PowerEntity.aidl index 002b34376e..6844a4cdb6 100644 --- a/power/stats/aidl/android/hardware/power/stats/PowerEntityInfo.aidl +++ b/power/stats/aidl/android/hardware/power/stats/PowerEntity.aidl @@ -16,20 +16,20 @@ package android.hardware.power.stats; -import android.hardware.power.stats.StateInfo; +import android.hardware.power.stats.State; @VintfStability -parcelable PowerEntityInfo { +parcelable PowerEntity { /** - * Unique ID of this PowerEntityInfo + * Unique ID of this PowerEntity */ - int powerEntityId; + int id; /** - * Unique name of the PowerEntity. Vendor/device specific. Opaque to framework + * Unique name of this PowerEntity. Vendor/device specific. Opaque to framework */ - @utf8InCpp String powerEntityName; + @utf8InCpp String name; /** - * List of states that the PowerEntity may reside in + * List of states that this PowerEntity may reside in */ - StateInfo[] states; + State[] states; }
\ No newline at end of file diff --git a/power/stats/aidl/android/hardware/power/stats/StateInfo.aidl b/power/stats/aidl/android/hardware/power/stats/State.aidl index 5703f1e9bd..33a9f705a5 100644 --- a/power/stats/aidl/android/hardware/power/stats/StateInfo.aidl +++ b/power/stats/aidl/android/hardware/power/stats/State.aidl @@ -17,15 +17,15 @@ package android.hardware.power.stats; @VintfStability -parcelable StateInfo { +parcelable State { /** - * Unique (for a given PowerEntityInfo) ID of this StateInfo + * Unique (for a given PowerEntity) ID of this State */ - int stateId; + int id; /** - * Unique (for a given PowerEntityInfo) name of the state. Vendor/device specific. + * Unique (for a given PowerEntity) name of the state. Vendor/device specific. * Opaque to framework */ - @utf8InCpp String stateName; + @utf8InCpp String name; } diff --git a/power/stats/aidl/android/hardware/power/stats/StateResidency.aidl b/power/stats/aidl/android/hardware/power/stats/StateResidency.aidl index a85ca33b51..41625171ad 100644 --- a/power/stats/aidl/android/hardware/power/stats/StateResidency.aidl +++ b/power/stats/aidl/android/hardware/power/stats/StateResidency.aidl @@ -24,7 +24,7 @@ parcelable StateResidency { /** * ID of the state associated with this residency */ - int stateId; + int id; /** * Total time in milliseconds that the corresponding PowerEntity resided * in this state since boot diff --git a/power/stats/aidl/android/hardware/power/stats/StateResidencyResult.aidl b/power/stats/aidl/android/hardware/power/stats/StateResidencyResult.aidl index 3356405a0a..949879c22c 100644 --- a/power/stats/aidl/android/hardware/power/stats/StateResidencyResult.aidl +++ b/power/stats/aidl/android/hardware/power/stats/StateResidencyResult.aidl @@ -23,7 +23,7 @@ parcelable StateResidencyResult { /** * ID of the PowerEntity associated with this result */ - int powerEntityId; + int id; /** * Residency for each state in the PowerEntity's state space */ diff --git a/power/stats/aidl/default/Android.bp b/power/stats/aidl/default/Android.bp index 40b9447b70..595ecd62d5 100644 --- a/power/stats/aidl/default/Android.bp +++ b/power/stats/aidl/default/Android.bp @@ -21,7 +21,7 @@ cc_binary { shared_libs: [ "libbase", "libbinder_ndk", - "android.hardware.power.stats-ndk_platform", + "android.hardware.power.stats-V1-ndk_platform", ], srcs: [ "main.cpp", diff --git a/power/stats/aidl/default/PowerStats.cpp b/power/stats/aidl/default/PowerStats.cpp index 367ee95201..0ffbd083c6 100644 --- a/power/stats/aidl/default/PowerStats.cpp +++ b/power/stats/aidl/default/PowerStats.cpp @@ -24,7 +24,7 @@ namespace hardware { namespace power { namespace stats { -ndk::ScopedAStatus PowerStats::getPowerEntityInfo(std::vector<PowerEntityInfo>* _aidl_return) { +ndk::ScopedAStatus PowerStats::getPowerEntityInfo(std::vector<PowerEntity>* _aidl_return) { (void)_aidl_return; return ndk::ScopedAStatus::ok(); } @@ -36,26 +36,25 @@ ndk::ScopedAStatus PowerStats::getStateResidency(const std::vector<int32_t>& in_ return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus PowerStats::getEnergyConsumerInfo(std::vector<EnergyConsumerId>* _aidl_return) { +ndk::ScopedAStatus PowerStats::getEnergyConsumerInfo(std::vector<EnergyConsumer>* _aidl_return) { (void)_aidl_return; return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus PowerStats::getEnergyConsumed( - const std::vector<EnergyConsumerId>& in_energyConsumerIds, - std::vector<EnergyConsumerResult>* _aidl_return) { +ndk::ScopedAStatus PowerStats::getEnergyConsumed(const std::vector<int32_t>& in_energyConsumerIds, + std::vector<EnergyConsumerResult>* _aidl_return) { (void)in_energyConsumerIds; (void)_aidl_return; return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus PowerStats::getEnergyMeterInfo(std::vector<ChannelInfo>* _aidl_return) { +ndk::ScopedAStatus PowerStats::getEnergyMeterInfo(std::vector<Channel>* _aidl_return) { (void)_aidl_return; return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus PowerStats::readEnergyMeters(const std::vector<int32_t>& in_channelIds, - std::vector<EnergyMeasurement>* _aidl_return) { +ndk::ScopedAStatus PowerStats::readEnergyMeter(const std::vector<int32_t>& in_channelIds, + std::vector<EnergyMeasurement>* _aidl_return) { (void)in_channelIds; (void)_aidl_return; return ndk::ScopedAStatus::ok(); diff --git a/power/stats/aidl/default/PowerStats.h b/power/stats/aidl/default/PowerStats.h index 76ab2cbd95..cb98e553f3 100644 --- a/power/stats/aidl/default/PowerStats.h +++ b/power/stats/aidl/default/PowerStats.h @@ -28,15 +28,15 @@ class PowerStats : public BnPowerStats { public: PowerStats() = default; // Methods from aidl::android::hardware::power::stats::IPowerStats - ndk::ScopedAStatus getPowerEntityInfo(std::vector<PowerEntityInfo>* _aidl_return) override; + ndk::ScopedAStatus getPowerEntityInfo(std::vector<PowerEntity>* _aidl_return) override; ndk::ScopedAStatus getStateResidency(const std::vector<int32_t>& in_powerEntityIds, std::vector<StateResidencyResult>* _aidl_return) override; - ndk::ScopedAStatus getEnergyConsumerInfo(std::vector<EnergyConsumerId>* _aidl_return) override; - ndk::ScopedAStatus getEnergyConsumed(const std::vector<EnergyConsumerId>& in_energyConsumerIds, + ndk::ScopedAStatus getEnergyConsumerInfo(std::vector<EnergyConsumer>* _aidl_return) override; + ndk::ScopedAStatus getEnergyConsumed(const std::vector<int32_t>& in_energyConsumerIds, std::vector<EnergyConsumerResult>* _aidl_return) override; - ndk::ScopedAStatus getEnergyMeterInfo(std::vector<ChannelInfo>* _aidl_return) override; - ndk::ScopedAStatus readEnergyMeters(const std::vector<int32_t>& in_channelIds, - std::vector<EnergyMeasurement>* _aidl_return) override; + ndk::ScopedAStatus getEnergyMeterInfo(std::vector<Channel>* _aidl_return) override; + ndk::ScopedAStatus readEnergyMeter(const std::vector<int32_t>& in_channelIds, + std::vector<EnergyMeasurement>* _aidl_return) override; }; } // namespace stats diff --git a/power/stats/aidl/vts/Android.bp b/power/stats/aidl/vts/Android.bp index 930709f160..31fb990905 100644 --- a/power/stats/aidl/vts/Android.bp +++ b/power/stats/aidl/vts/Android.bp @@ -23,7 +23,7 @@ cc_test { "libbinder_ndk", ], static_libs: [ - "android.hardware.power.stats-ndk_platform", + "android.hardware.power.stats-V1-ndk_platform", ], test_suites: [ "general-tests", diff --git a/power/stats/aidl/vts/VtsHalPowerStatsTargetTest.cpp b/power/stats/aidl/vts/VtsHalPowerStatsTargetTest.cpp index 1d3082191a..bed3fdf352 100644 --- a/power/stats/aidl/vts/VtsHalPowerStatsTargetTest.cpp +++ b/power/stats/aidl/vts/VtsHalPowerStatsTargetTest.cpp @@ -21,10 +21,21 @@ #include <android/binder_manager.h> #include <android/binder_process.h> -using aidl::android::hardware::power::stats::ChannelInfo; +#include <algorithm> +#include <iterator> +#include <random> +#include <unordered_map> + +using aidl::android::hardware::power::stats::Channel; +using aidl::android::hardware::power::stats::EnergyConsumer; +using aidl::android::hardware::power::stats::EnergyConsumerAttribution; +using aidl::android::hardware::power::stats::EnergyConsumerResult; +using aidl::android::hardware::power::stats::EnergyConsumerType; using aidl::android::hardware::power::stats::EnergyMeasurement; using aidl::android::hardware::power::stats::IPowerStats; -using aidl::android::hardware::power::stats::PowerEntityInfo; +using aidl::android::hardware::power::stats::PowerEntity; +using aidl::android::hardware::power::stats::State; +using aidl::android::hardware::power::stats::StateResidency; using aidl::android::hardware::power::stats::StateResidencyResult; using ndk::SpAIBinder; @@ -37,94 +48,367 @@ class PowerStatsAidl : public testing::TestWithParam<std::string> { ASSERT_NE(nullptr, powerstats.get()); } + template <typename T> + std::vector<T> getRandomSubset(std::vector<T> const& collection); + + void testNameValid(const std::string& name); + + template <typename T, typename S> + void testUnique(std::vector<T> const& collection, S T::*field); + + template <typename T, typename S, typename R> + void testMatching(std::vector<T> const& c1, R T::*f1, std::vector<S> const& c2, R S::*f2); + std::shared_ptr<IPowerStats> powerstats; }; -TEST_P(PowerStatsAidl, TestReadEnergyMeter) { - std::vector<EnergyMeasurement> data; - ASSERT_TRUE(powerstats->readEnergyMeters({}, &data).isOk()); +// Returns a random subset from a collection +template <typename T> +std::vector<T> PowerStatsAidl::getRandomSubset(std::vector<T> const& collection) { + if (collection.empty()) { + return {}; + } + + std::vector<T> selected; + std::sample(collection.begin(), collection.end(), std::back_inserter(selected), + rand() % collection.size() + 1, std::mt19937{std::random_device{}()}); + + return selected; +} + +// Tests whether a name is valid +void PowerStatsAidl::testNameValid(const std::string& name) { + EXPECT_NE(name, ""); +} + +// Tests whether the fields in a given collection are unique +template <typename T, typename S> +void PowerStatsAidl::testUnique(std::vector<T> const& collection, S T::*field) { + std::set<S> cSet; + for (auto const& elem : collection) { + EXPECT_TRUE(cSet.insert(elem.*field).second); + } +} + +template <typename T, typename S, typename R> +void PowerStatsAidl::testMatching(std::vector<T> const& c1, R T::*f1, std::vector<S> const& c2, + R S::*f2) { + std::set<R> c1fields, c2fields; + for (auto elem : c1) { + c1fields.insert(elem.*f1); + } + + for (auto elem : c2) { + c2fields.insert(elem.*f2); + } + + EXPECT_EQ(c1fields, c2fields); } // Each PowerEntity must have a valid name TEST_P(PowerStatsAidl, ValidatePowerEntityNames) { - std::vector<PowerEntityInfo> infos; + std::vector<PowerEntity> infos; ASSERT_TRUE(powerstats->getPowerEntityInfo(&infos).isOk()); for (auto info : infos) { - EXPECT_NE(info.powerEntityName, ""); + testNameValid(info.name); } } // Each power entity must have a unique name TEST_P(PowerStatsAidl, ValidatePowerEntityUniqueNames) { - std::vector<PowerEntityInfo> infos; - ASSERT_TRUE(powerstats->getPowerEntityInfo(&infos).isOk()); + std::vector<PowerEntity> entities; + ASSERT_TRUE(powerstats->getPowerEntityInfo(&entities).isOk()); - std::set<std::string> names; - for (auto info : infos) { - EXPECT_TRUE(names.insert(info.powerEntityName).second); - } + testUnique(entities, &PowerEntity::name); } // Each PowerEntity must have a unique ID TEST_P(PowerStatsAidl, ValidatePowerEntityIds) { - std::vector<PowerEntityInfo> infos; - ASSERT_TRUE(powerstats->getPowerEntityInfo(&infos).isOk()); + std::vector<PowerEntity> entities; + ASSERT_TRUE(powerstats->getPowerEntityInfo(&entities).isOk()); - std::set<int32_t> ids; - for (auto info : infos) { - EXPECT_TRUE(ids.insert(info.powerEntityId).second); + testUnique(entities, &PowerEntity::id); +} + +// Each power entity must have at least one state +TEST_P(PowerStatsAidl, ValidateStateSize) { + std::vector<PowerEntity> entities; + ASSERT_TRUE(powerstats->getPowerEntityInfo(&entities).isOk()); + + for (auto entity : entities) { + EXPECT_GT(entity.states.size(), 0); } } // Each state must have a valid name TEST_P(PowerStatsAidl, ValidateStateNames) { - std::vector<PowerEntityInfo> infos; - ASSERT_TRUE(powerstats->getPowerEntityInfo(&infos).isOk()); + std::vector<PowerEntity> entities; + ASSERT_TRUE(powerstats->getPowerEntityInfo(&entities).isOk()); - for (auto info : infos) { - for (auto state : info.states) { - EXPECT_NE(state.stateName, ""); + for (auto entity : entities) { + for (auto state : entity.states) { + testNameValid(state.name); } } } // Each state must have a name that is unique to the given PowerEntity TEST_P(PowerStatsAidl, ValidateStateUniqueNames) { - std::vector<PowerEntityInfo> infos; - ASSERT_TRUE(powerstats->getPowerEntityInfo(&infos).isOk()); + std::vector<PowerEntity> entities; + ASSERT_TRUE(powerstats->getPowerEntityInfo(&entities).isOk()); - for (auto info : infos) { - std::set<std::string> stateNames; - for (auto state : info.states) { - EXPECT_TRUE(stateNames.insert(state.stateName).second); - } + for (auto entity : entities) { + testUnique(entity.states, &State::name); } } // Each state must have an ID that is unique to the given PowerEntity TEST_P(PowerStatsAidl, ValidateStateUniqueIds) { - std::vector<PowerEntityInfo> infos; - ASSERT_TRUE(powerstats->getPowerEntityInfo(&infos).isOk()); + std::vector<PowerEntity> entities; + ASSERT_TRUE(powerstats->getPowerEntityInfo(&entities).isOk()); - for (auto info : infos) { - std::set<int32_t> stateIds; - for (auto state : info.states) { - EXPECT_TRUE(stateIds.insert(state.stateId).second); - } + for (auto entity : entities) { + testUnique(entity.states, &State::id); } } +// State residency must return a valid status TEST_P(PowerStatsAidl, TestGetStateResidency) { std::vector<StateResidencyResult> results; ASSERT_TRUE(powerstats->getStateResidency({}, &results).isOk()); } +// State residency must return all results +TEST_P(PowerStatsAidl, TestGetStateResidencyAllResults) { + std::vector<PowerEntity> entities; + ASSERT_TRUE(powerstats->getPowerEntityInfo(&entities).isOk()); + + std::vector<StateResidencyResult> results; + ASSERT_TRUE(powerstats->getStateResidency({}, &results).isOk()); + + testMatching(entities, &PowerEntity::id, results, &StateResidencyResult::id); +} + +// Each result must contain all state residencies +TEST_P(PowerStatsAidl, TestGetStateResidencyAllStateResidencies) { + std::vector<PowerEntity> entities; + ASSERT_TRUE(powerstats->getPowerEntityInfo(&entities).isOk()); + + std::vector<StateResidencyResult> results; + ASSERT_TRUE(powerstats->getStateResidency({}, &results).isOk()); + + for (auto entity : entities) { + auto it = std::find_if(results.begin(), results.end(), + [&entity](const auto& x) { return x.id == entity.id; }); + ASSERT_NE(it, results.end()); + + testMatching(entity.states, &State::id, it->stateResidencyData, &StateResidency::id); + } +} + +// State residency must return results for each requested power entity +TEST_P(PowerStatsAidl, TestGetStateResidencySelectedResults) { + std::vector<PowerEntity> entities; + ASSERT_TRUE(powerstats->getPowerEntityInfo(&entities).isOk()); + if (entities.empty()) { + return; + } + + std::vector<PowerEntity> selectedEntities = getRandomSubset(entities); + std::vector<int32_t> selectedIds; + for (auto const& entity : selectedEntities) { + selectedIds.push_back(entity.id); + } + + std::vector<StateResidencyResult> selectedResults; + ASSERT_TRUE(powerstats->getStateResidency(selectedIds, &selectedResults).isOk()); + + testMatching(selectedEntities, &PowerEntity::id, selectedResults, &StateResidencyResult::id); +} + +// Energy meter info must return a valid status TEST_P(PowerStatsAidl, TestGetEnergyMeterInfo) { - std::vector<ChannelInfo> info; + std::vector<Channel> info; ASSERT_TRUE(powerstats->getEnergyMeterInfo(&info).isOk()); } +// Each channel must have a valid name and subsystem +TEST_P(PowerStatsAidl, ValidateChannelNames) { + std::vector<Channel> channels; + ASSERT_TRUE(powerstats->getEnergyMeterInfo(&channels).isOk()); + for (auto channel : channels) { + testNameValid(channel.name); + testNameValid(channel.subsystem); + } +} + +// Each channel must have a unique name +TEST_P(PowerStatsAidl, ValidateChannelUniqueNames) { + std::vector<Channel> channels; + ASSERT_TRUE(powerstats->getEnergyMeterInfo(&channels).isOk()); + + testUnique(channels, &Channel::name); +} + +// Each channel must have a unique ID +TEST_P(PowerStatsAidl, ValidateChannelUniqueIds) { + std::vector<Channel> channels; + ASSERT_TRUE(powerstats->getEnergyMeterInfo(&channels).isOk()); + + testUnique(channels, &Channel::id); +} + +// Reading energy meter must return a valid status +TEST_P(PowerStatsAidl, TestReadEnergyMeter) { + std::vector<EnergyMeasurement> data; + ASSERT_TRUE(powerstats->readEnergyMeter({}, &data).isOk()); +} + +// Reading energy meter must return results for all available channels +TEST_P(PowerStatsAidl, TestGetAllEnergyMeasurements) { + std::vector<Channel> channels; + ASSERT_TRUE(powerstats->getEnergyMeterInfo(&channels).isOk()); + + std::vector<EnergyMeasurement> measurements; + ASSERT_TRUE(powerstats->readEnergyMeter({}, &measurements).isOk()); + + testMatching(channels, &Channel::id, measurements, &EnergyMeasurement::id); +} + +// Reading energy must must return results for each selected channel +TEST_P(PowerStatsAidl, TestGetSelectedEnergyMeasurements) { + std::vector<Channel> channels; + ASSERT_TRUE(powerstats->getEnergyMeterInfo(&channels).isOk()); + if (channels.empty()) { + return; + } + + std::vector<Channel> selectedChannels = getRandomSubset(channels); + std::vector<int32_t> selectedIds; + for (auto const& channel : selectedChannels) { + selectedIds.push_back(channel.id); + } + + std::vector<EnergyMeasurement> selectedMeasurements; + ASSERT_TRUE(powerstats->readEnergyMeter(selectedIds, &selectedMeasurements).isOk()); + + testMatching(selectedChannels, &Channel::id, selectedMeasurements, &EnergyMeasurement::id); +} + +// Energy consumer info must return a valid status +TEST_P(PowerStatsAidl, TestGetEnergyConsumerInfo) { + std::vector<EnergyConsumer> consumers; + ASSERT_TRUE(powerstats->getEnergyConsumerInfo(&consumers).isOk()); +} + +// Each energy consumer must have a unique id +TEST_P(PowerStatsAidl, TestGetEnergyConsumerUniqueId) { + std::vector<EnergyConsumer> consumers; + ASSERT_TRUE(powerstats->getEnergyConsumerInfo(&consumers).isOk()); + + testUnique(consumers, &EnergyConsumer::id); +} + +// Each energy consumer must have a valid name +TEST_P(PowerStatsAidl, ValidateEnergyConsumerNames) { + std::vector<EnergyConsumer> consumers; + ASSERT_TRUE(powerstats->getEnergyConsumerInfo(&consumers).isOk()); + + for (auto consumer : consumers) { + testNameValid(consumer.name); + } +} + +// Each energy consumer must have a unique name +TEST_P(PowerStatsAidl, ValidateEnergyConsumerUniqueNames) { + std::vector<EnergyConsumer> consumers; + ASSERT_TRUE(powerstats->getEnergyConsumerInfo(&consumers).isOk()); + + testUnique(consumers, &EnergyConsumer::name); +} + +// Energy consumers of the same type must have ordinals that are 0,1,2,..., N - 1 +TEST_P(PowerStatsAidl, ValidateEnergyConsumerOrdinals) { + std::vector<EnergyConsumer> consumers; + ASSERT_TRUE(powerstats->getEnergyConsumerInfo(&consumers).isOk()); + + std::unordered_map<EnergyConsumerType, std::set<int32_t>> ordinalMap; + + // Ordinals must be unique for each type + for (auto consumer : consumers) { + EXPECT_TRUE(ordinalMap[consumer.type].insert(consumer.ordinal).second); + } + + // Min ordinal must be 0, max ordinal must be N - 1 + for (const auto& [unused, ordinals] : ordinalMap) { + EXPECT_EQ(0, *std::min_element(ordinals.begin(), ordinals.end())); + EXPECT_EQ(ordinals.size() - 1, *std::max_element(ordinals.begin(), ordinals.end())); + } +} + +// Energy consumed must return a valid status +TEST_P(PowerStatsAidl, TestGetEnergyConsumed) { + std::vector<EnergyConsumerResult> results; + ASSERT_TRUE(powerstats->getEnergyConsumed({}, &results).isOk()); +} + +// Energy consumed must return data for all energy consumers +TEST_P(PowerStatsAidl, TestGetAllEnergyConsumed) { + std::vector<EnergyConsumer> consumers; + ASSERT_TRUE(powerstats->getEnergyConsumerInfo(&consumers).isOk()); + + std::vector<EnergyConsumerResult> results; + ASSERT_TRUE(powerstats->getEnergyConsumed({}, &results).isOk()); + + testMatching(consumers, &EnergyConsumer::id, results, &EnergyConsumerResult::id); +} + +// Energy consumed must return data for each selected energy consumer +TEST_P(PowerStatsAidl, TestGetSelectedEnergyConsumed) { + std::vector<EnergyConsumer> consumers; + ASSERT_TRUE(powerstats->getEnergyConsumerInfo(&consumers).isOk()); + if (consumers.empty()) { + return; + } + + std::vector<EnergyConsumer> selectedConsumers = getRandomSubset(consumers); + std::vector<int32_t> selectedIds; + for (auto const& consumer : selectedConsumers) { + selectedIds.push_back(consumer.id); + } + + std::vector<EnergyConsumerResult> selectedResults; + ASSERT_TRUE(powerstats->getEnergyConsumed(selectedIds, &selectedResults).isOk()); + + testMatching(selectedConsumers, &EnergyConsumer::id, selectedResults, + &EnergyConsumerResult::id); +} + +// Energy consumed attribution uids must be unique for a given energy consumer +TEST_P(PowerStatsAidl, ValidateEnergyConsumerAttributionUniqueUids) { + std::vector<EnergyConsumerResult> results; + ASSERT_TRUE(powerstats->getEnergyConsumed({}, &results).isOk()); + + for (auto result : results) { + testUnique(result.attribution, &EnergyConsumerAttribution::uid); + } +} + +// Energy consumed total energy >= sum total of uid-attributed energy +TEST_P(PowerStatsAidl, TestGetEnergyConsumedAttributedEnergy) { + std::vector<EnergyConsumerResult> results; + ASSERT_TRUE(powerstats->getEnergyConsumed({}, &results).isOk()); + + for (auto result : results) { + int64_t totalAttributedEnergyUWs = 0; + for (auto attribution : result.attribution) { + totalAttributedEnergyUWs += attribution.energyUWs; + } + EXPECT_TRUE(result.energyUWs >= totalAttributedEnergyUWs); + } +} + GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PowerStatsAidl); INSTANTIATE_TEST_SUITE_P( PowerStats, PowerStatsAidl, diff --git a/radio/1.6/IRadio.hal b/radio/1.6/IRadio.hal index a398e7d07f..b756ce1261 100644 --- a/radio/1.6/IRadio.hal +++ b/radio/1.6/IRadio.hal @@ -18,9 +18,12 @@ package android.hardware.radio@1.6; import @1.0::CdmaSmsMessage; +import @1.0::Dial; import @1.0::GsmSmsMessage; import @1.1::CardPowerState; import @1.2::DataRequestReason; +import @1.4::EmergencyCallRouting; +import @1.4::EmergencyServiceCategory; import @1.4::RadioAccessFamily; import @1.5::IRadio; import @1.5::AccessNetwork; @@ -120,6 +123,18 @@ interface IRadio extends @1.5::IRadio { * @param sliceInfo SliceInfo to be used for the data connection when a handover occurs from * EPDG to 5G. It is valid only when accessNetwork is AccessNetwork:NGRAN. If the slice * passed from EPDG is rejected, then the data failure cause must be DataCallFailCause:SLICE_REJECTED. + * @param trafficDescriptor TrafficDescriptor for which data connection needs to be + * established. It is used for URSP traffic matching as described in TS 24.526 + * Section 4.2.2. It includes an optional DNN which, if present, must be used for traffic + * matching -- it does not specify the end point to be used for the data call. The end + * point is specified by DataProfileInfo.apn; DataProfileInfo.apn must be used as the end + * point if one is not specified through URSP rules. + * @param matchAllRuleAllowed bool to indicate if using default match-all URSP rule for this + * request is allowed. If false, this request must not use the match-all URSP rule and if + * a non-match-all rule is not found (or if URSP rules are not available) it should return + * failure with cause DataCallFailCause:MATCH_ALL_RULE_NOT_ALLOWED. This is needed as some + * requests need to have a hard failure if the intention cannot be met, for example, a + * zero-rating slice. * * Response function is IRadioResponse.setupDataCallResponse_1_6() * @@ -128,7 +143,8 @@ interface IRadio extends @1.5::IRadio { oneway setupDataCall_1_6(int32_t serial, AccessNetwork accessNetwork, DataProfileInfo dataProfileInfo, bool roamingAllowed, DataRequestReason reason, vec<LinkAddress> addresses, vec<string> dnses, - int32_t pduSessionId, OptionalSliceInfo sliceInfo); + int32_t pduSessionId, OptionalSliceInfo sliceInfo, + OptionalTrafficDescriptor trafficDescriptor, bool matchAllRuleAllowed); /** * Send an SMS message @@ -324,30 +340,29 @@ interface IRadio extends @1.5::IRadio { /** * Requests to set the network type for searching and registering. * - * Instruct the radio to *only* accept the types of network provided. This - * is stronger than setPreferredNetworkType which is a suggestion. + * Instruct the radio to *only* accept the types of network provided. + * setPreferredNetworkType, setPreferredNetworkTypesBitmap will not be called anymore + * except for IRadio v1.5 or older devices. * * @param serial Serial number of request. * @param networkTypeBitmap a 32-bit bearer bitmap of RadioAccessFamily * - * Response callback is IRadioResponse.setNetworkTypeBitmapResponse() + * Response callback is IRadioResponse.setAllowedNetworkTypesBitmapResponse() */ - oneway setAllowedNetworkTypeBitmap( + oneway setAllowedNetworkTypesBitmap( uint32_t serial, bitfield<RadioAccessFamily> networkTypeBitmap); /** * Requests bitmap representing the currently allowed network types. * - * Requests the bitmap set by the corresponding method - * setAllowedNetworkTypeBitmap, which sets a strict set of RATs for the - * radio to use. Differs from getPreferredNetworkType and getPreferredNetworkTypeBitmap - * in that those request *preferences*. + * getPreferredNetworkType, getPreferredNetworkTypesBitmap will not be called anymore + * except for IRadio v1.5 or older devices. * * @param serial Serial number of request. * - * Response callback is IRadioResponse.getNetworkTypeBitmapResponse() + * Response callback is IRadioResponse.getAllowedNetworkTypesBitmapResponse() */ - oneway getAllowedNetworkTypeBitmap(uint32_t serial); + oneway getAllowedNetworkTypesBitmap(uint32_t serial); /** * Control data throttling at modem. @@ -375,6 +390,64 @@ interface IRadio extends @1.5::IRadio { int64_t completionDurationMillis); /** + * Initiate emergency voice call, with zero or more emergency service category(s), zero or + * more emergency Uniform Resource Names (URN), and routing information for handling the call. + * Android uses this request to make its emergency call instead of using @1.0::IRadio.dial + * if the 'address' in the 'dialInfo' field is identified as an emergency number by Android. + * + * In multi-sim scenario, if the emergency number is from a specific subscription, this radio + * request can still be sent out on the other subscription as long as routing is set to + * @1.4::EmergencyNumberRouting#EMERGENCY. This radio request will not be sent on an inactive + * (PIN/PUK locked) subscription unless both subscriptions are PIN/PUK locked. In this case, + * the request will be sent on the primary subscription. + * + * Some countries or carriers require some emergency numbers that must be handled with normal + * call routing if possible or emergency routing. 1) if the 'routing' field is specified as + * @1.4::EmergencyNumberRouting#NORMAL, the implementation must try the full radio service to + * use normal call routing to handle the call; if service cannot support normal routing, the + * implementation must use emergency routing to handle the call. 2) if 'routing' is specified + * as @1.4::EmergencyNumberRouting#EMERGENCY, the implementation must use emergency routing to + * handle the call. 3) if 'routing' is specified as @1.4::EmergencyNumberRouting#UNKNOWN, + * Android does not know how to handle the call. + * + * If the dialed emergency number does not have a specified emergency service category, the + * 'categories' field is set to @1.4::EmergencyServiceCategory#UNSPECIFIED; if the dialed + * emergency number does not have specified emergency Uniform Resource Names, the 'urns' field + * is set to an empty list. If the underlying technology used to request emergency services + * does not support the emergency service category or emergency uniform resource names, the + * field 'categories' or 'urns' may be ignored. + * + * In the scenarios that the 'address' in the 'dialInfo' field has other functions besides the + * emergency number function, if the 'hasKnownUserIntentEmergency' field is true, the user's + * intent for this dial request is emergency call, and the modem must treat this as an actual + * emergency dial; if the 'hasKnownUserIntentEmergency' field is false, Android does not know + * user's intent for this call. + * + * If 'isTesting' is true, this request is for testing purpose, and must not be sent to a real + * emergency service; otherwise it's for a real emergency call request. + * + * Reference: 3gpp 22.101, Section 10 - Emergency Calls; + * 3gpp 23.167, Section 6 - Functional description; + * 3gpp 24.503, Section 5.1.6.8.1 - General; + * RFC 5031 + * + * @param serial Serial number of request. + * @param dialInfo the same @1.0::Dial information used by @1.0::IRadio.dial. + * @param categories bitfield<@1.4::EmergencyServiceCategory> the Emergency Service Category(s) + * of the call. + * @param urns the emergency Uniform Resource Names (URN) + * @param routing @1.4::EmergencyCallRouting the emergency call routing information. + * @param hasKnownUserIntentEmergency Flag indicating if user's intent for the emergency call + * is known. + * @param isTesting Flag indicating if this request is for testing purpose. + * + * Response function is IRadioResponse.emergencyDialResponse() + */ + oneway emergencyDial_1_6(int32_t serial, Dial dialInfo, + bitfield<EmergencyServiceCategory> categories, vec<string> urns, + EmergencyCallRouting routing, bool hasKnownUserIntentEmergency, bool isTesting); + + /** * Get which bands the modem's background scan is acting on. * * @param serial Serial number of request. @@ -432,4 +505,17 @@ interface IRadio extends @1.5::IRadio { * Response function is IRadioResponse.getCurrentCallsResponse_1_6() */ oneway getCurrentCalls_1_6(int32_t serial); + + /** + * Request to get the current slicing configuration including URSP rules and + * NSSAIs (configured, allowed and rejected). + * URSP stands for UE route selection policy and is defined in 3GPP TS 24.526 + * Section 4.2. + * An NSSAI is a collection of network slices. Each network slice is identified by + * an S-NSSAI and is represented by the struct SliceInfo. NSSAI and S-NSSAI + * are defined in 3GPP TS 24.501. + * + * Response function is IRadioResponse.getSlicingConfigResponse() + */ + oneway getSlicingConfig(int32_t serial); }; diff --git a/radio/1.6/IRadioResponse.hal b/radio/1.6/IRadioResponse.hal index 6ac86c335e..6ad5cf262a 100644 --- a/radio/1.6/IRadioResponse.hal +++ b/radio/1.6/IRadioResponse.hal @@ -25,6 +25,7 @@ import @1.6::RegStateResult; import @1.6::RadioResponseInfo; import @1.6::SetupDataCallResult; import @1.6::SignalStrength; +import @1.6::SlicingConfig; /** * Interface declaring response functions to solicited radio requests. @@ -296,7 +297,7 @@ interface IRadioResponse extends @1.5::IRadioResponse { oneway cancelHandoverResponse(RadioResponseInfo info); /** - * Callback of IRadio.setAllowedNetworkTypeBitmap(int, bitfield<RadioAccessFamily>) + * Callback of IRadio.setAllowedNetworkTypesBitmap(int, bitfield<RadioAccessFamily>) * * Valid errors returned: * RadioError:NONE @@ -309,10 +310,12 @@ interface IRadioResponse extends @1.5::IRadioResponse { * RadioError:REQUEST_NOT_SUPPORTED * RadioError:NO_RESOURCES */ - oneway setAllowedNetworkTypeBitmapResponse(RadioResponseInfo info); + oneway setAllowedNetworkTypesBitmapResponse(RadioResponseInfo info); /** - * Callback of IRadio.getAllowedNetworkTypeBitmap(int, bitfield<RadioAccessFamily>) + * Callback of IRadio.getAllowedNetworkTypesBitmap(int, bitfield<RadioAccessFamily>) + * @param info Response info struct containing response type, serial no. and error + * @param networkTypeBitmap a 32-bit bitmap of RadioAccessFamily. * * Valid errors returned: * RadioError:NONE @@ -325,7 +328,7 @@ interface IRadioResponse extends @1.5::IRadioResponse { * RadioError:REQUEST_NOT_SUPPORTED * RadioError:NO_RESOURCES */ - oneway getAllowedNetworkTypeBitmapResponse( + oneway getAllowedNetworkTypesBitmapResponse( RadioResponseInfo info, bitfield<RadioAccessFamily> networkTypeBitmap); /** @@ -414,4 +417,17 @@ interface IRadioResponse extends @1.5::IRadioResponse { * RadioError:CANCELLED */ oneway getCurrentCallsResponse_1_6(RadioResponseInfo info, vec<Call> calls); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param slicingConfig Current slicing configuration + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:MODEM_ERR + */ + oneway getSlicingConfigResponse(RadioResponseInfo info, + SlicingConfig slicingConfig); }; diff --git a/radio/1.6/types.hal b/radio/1.6/types.hal index d475ed3657..6c23650dde 100644 --- a/radio/1.6/types.hal +++ b/radio/1.6/types.hal @@ -284,6 +284,9 @@ struct SetupDataCallResult { * retry back-off time in milliseconds. Negative value indicates network does not give any * suggestion. 0 indicates retry should be performed immediately. 0x7fffffffffffffff indicates * the device should not retry data setup anymore. + * + * During this time, no calls to IRadio@1.6::SetupDataCall for this APN will be made unless + * IRadioIndication@1.6::unthrottleApn is sent with the same APN. */ int64_t suggestedRetryTime; @@ -362,6 +365,13 @@ struct SetupDataCallResult { * AccessNetwork:NGRAN. */ OptionalSliceInfo sliceInfo; + + /** + * TrafficDescriptors for which this data call must be used. It only includes + * the TDs for which a data call has been requested so far; it is not an + * exhaustive list. + */ + vec<TrafficDescriptor> trafficDescriptors; }; /** @@ -734,6 +744,14 @@ struct RegStateResult { */ NrVopsInfo nrVopsInfo; } ngranInfo; + + struct GeranRegistrationInfo { + /** + * True if the dual transfer mode is supported. + * Refer to 3GPP TS 44.108 section 3.4.25.3 + */ + bool dtmSupported; + } geranInfo; } accessTechnologySpecificInfo; }; @@ -821,6 +839,16 @@ enum DataCallFailCause : @1.4::DataCallFailCause { * Data call fail due to the slice not being allowed for the data call. */ SLICE_REJECTED = 0x8CC, + + /** + * No matching rule available for the request, and match-all rule is not allowed for it. + */ + MATCH_ALL_RULE_NOT_ALLOWED = 0x8CD, + + /** + * If connection failed for all matching URSP rules + */ + ALL_MATCHING_RULES_FAILED = 0x8CE, }; struct PhysicalChannelConfig { @@ -889,3 +917,201 @@ enum NgranBands : @1.5::NgranBands { BAND_53 = 53, BAND_96 = 96, }; + +/** + * This safe_union represents an optional DNN. DNN stands for Data Network Name + * and represents an APN as defined in 3GPP TS 23.003. + */ +safe_union OptionalDNN { + Monostate noinit; + string value; +}; + +/** + * This safe_union represents an optional OSAppId. + */ +safe_union OptionalOSAppId { + Monostate noinit; + OSAppId value; +}; + +/** + * This safe_union represents an optional TrafficDescriptor. + */ +safe_union OptionalTrafficDescriptor { + Monostate noinit; + TrafficDescriptor value; +}; + +/** + * This struct represents a traffic descriptor. A valid struct must have at least + * one of the optional values present. This is based on the definition of traffic + * descriptor in TS 24.526 Section 5.2. + */ +struct TrafficDescriptor { + /** + * DNN stands for Data Network Name and represents an APN as defined in + * 3GPP TS 23.003. + */ + OptionalDNN dnn; + /** + * Indicates the OSId + OSAppId (used as category in Android). + */ + OptionalOSAppId osAppId; +}; + +/** + * This struct represents the OSId + OSAppId as defined in TS 24.526 Section 5.2 + */ +struct OSAppId { + /** + * Byte array representing OSId + OSAppId. The minimum length of the array is + * 18 and maximum length is 272 (16 bytes for OSId + 1 byte for OSAppId length + * + up to 255 bytes for OSAppId). + */ + vec<uint8_t> osAppId; +}; + +/** + * This struct represents the current slicing configuration. + */ +struct SlicingConfig { + /** + * This vector contains the current URSP rules. Empty vector represents that no + * rules are configured. + */ + vec<UrspRule> urspRules; + /** + * Struct containing all NSSAIs (list of slice info). + */ + Nssais nsaids; +}; + +/** + * This struct represents a single URSP rule as defined in 3GPP TS 24.526. + */ +struct UrspRule { + /** + * Precedence value in the range of 0 to 255. Higher value has lower + * precedence. + */ + uint8_t precedence; + /** + * Used as a matcher for network requests. + */ + vec<TrafficDescriptor> trafficDescriptors; + /** + * List of routes (connection parameters) that must be used for requests + * matching a trafficDescriptor. + */ + vec<RouteSelectionDescriptor> routeSelectionDescriptor; +}; + + +/** + * This struct represents a single route selection descriptor as defined in + * 3GPP TS 24.526. + */ +struct RouteSelectionDescriptor { + /** + * Precedence value in the range of 0 to 255. Higher value has lower + * precedence. + */ + uint8_t precedence; + /** + * Parameters defining this RouteSelectionDescriptor. The length of the vector + * must be >= 1. + */ + vec<RouteSelectionDescriptorParams> routeSelectionDescriptorParams; +}; + +/** + * This struct represents a route selection descriptor. A valid struct must have + * at least one of the vectors non-empty. + */ +struct RouteSelectionDescriptorParams { + /** + * Valid values are IP, IPV6 and IPV4V6. + */ + OptionalPdpProtocolType sessionType; + OptionalSscMode sscMode; + /** + * There can be 0 or more SliceInfo specified in a route descriptor. + */ + vec<SliceInfo> sliceInfo; + /** + * DNN stands for Data Network Name and represents an APN as defined in + * 3GPP TS 23.003. There can be 0 or more DNNs specified in a route + * descriptor. + */ + vec<string> dnn; +}; + +/** + * This safe_union represents an optional PdpProtocolType. + */ +safe_union OptionalPdpProtocolType { + Monostate noinit; + PdpProtocolType value; +}; + +/** + * This safe_union represents an optional SscMode. + */ +safe_union OptionalSscMode { + Monostate noinit; + SscMode value; +}; + +/** + * This struct contains all NSSAIs (lists of slices). + */ +struct Nssais { + /** + * These are all the slices configured by the network. This includes allowed + * and rejected slices, as well as slices that are neither allowed nor rejected + * yet. Empty vector indicates that no slices are configured, and in that case + * allowed and rejected vectors must be empty as well. + */ + vec<SliceInfo> configured; + /** + * These are all the slices that the UE is allowed to use. All these slices + * must be configured as well. Empty vector indicates that no slices are + * allowed yet. + */ + vec<SliceInfo> allowed; + /** + * These are all the slices that the UE is not allowed to use. All these slices + * must be configured as well. Empty vector indicates that no slices are + * rejected yet. + */ + vec<RejectedSliceInfo> rejected; + /** + * Default configured NSSAI + */ + vec<SliceInfo> defaultConfigured; +}; + +/** + * This struct represents a network slice rejected by the network. It contains a + * rejectionCause corresponding to a rejected network slice. + */ +struct RejectedSliceInfo { + SliceInfo sliceInfo; + SliceRejectionCause rejectionCause; +}; + +enum SliceRejectionCause : int32_t { + NOT_AVAILABLE_IN_PLMN, + NOT_AVAILABLE_IN_REG_AREA, +}; + +/** + * Enum representing session and service continuity mode as defined in + * 3GPP TS 23.501. + */ +enum SscMode : int32_t { + MODE_1 = 1, + MODE_2 = 2, + MODE_3 = 3, +}; diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp index 8b872921ec..07b8ccb035 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp +++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp @@ -59,9 +59,15 @@ TEST_P(RadioHidlTest_v1_6, setupDataCall_1_6) { ::android::hardware::radio::V1_6::OptionalSliceInfo optionalSliceInfo; memset(&optionalSliceInfo, 0, sizeof(optionalSliceInfo)); + ::android::hardware::radio::V1_6::OptionalTrafficDescriptor optionalTrafficDescriptor; + memset(&optionalTrafficDescriptor, 0, sizeof(optionalTrafficDescriptor)); + + bool matchAllRuleAllowed = true; + Return<void> res = radio_v1_6->setupDataCall_1_6(serial, accessNetwork, dataProfileInfo, roamingAllowed, - reason, addresses, dnses, -1, optionalSliceInfo); + reason, addresses, dnses, -1, optionalSliceInfo, + optionalTrafficDescriptor, matchAllRuleAllowed); ASSERT_OK(res); EXPECT_EQ(std::cv_status::no_timeout, wait()); @@ -82,6 +88,93 @@ TEST_P(RadioHidlTest_v1_6, setupDataCall_1_6) { } } +TEST_P(RadioHidlTest_v1_6, setupDataCall_1_6_osAppId) { + serial = GetRandomSerialNumber(); + + ::android::hardware::radio::V1_5::AccessNetwork accessNetwork = + ::android::hardware::radio::V1_5::AccessNetwork::EUTRAN; + + android::hardware::radio::V1_5::DataProfileInfo dataProfileInfo; + memset(&dataProfileInfo, 0, sizeof(dataProfileInfo)); + dataProfileInfo.profileId = DataProfileId::DEFAULT; + dataProfileInfo.apn = hidl_string("internet"); + dataProfileInfo.protocol = PdpProtocolType::IP; + dataProfileInfo.roamingProtocol = PdpProtocolType::IP; + dataProfileInfo.authType = ApnAuthType::NO_PAP_NO_CHAP; + dataProfileInfo.user = hidl_string("username"); + dataProfileInfo.password = hidl_string("password"); + dataProfileInfo.type = DataProfileInfoType::THREE_GPP; + dataProfileInfo.maxConnsTime = 300; + dataProfileInfo.maxConns = 20; + dataProfileInfo.waitTime = 0; + dataProfileInfo.enabled = true; + dataProfileInfo.supportedApnTypesBitmap = 320; + dataProfileInfo.bearerBitmap = 161543; + dataProfileInfo.mtuV4 = 0; + dataProfileInfo.mtuV6 = 0; + dataProfileInfo.preferred = true; + dataProfileInfo.persistent = false; + + bool roamingAllowed = false; + + std::vector<::android::hardware::radio::V1_5::LinkAddress> addresses = {}; + std::vector<hidl_string> dnses = {}; + + ::android::hardware::radio::V1_2::DataRequestReason reason = + ::android::hardware::radio::V1_2::DataRequestReason::NORMAL; + + ::android::hardware::radio::V1_6::OptionalSliceInfo optionalSliceInfo; + memset(&optionalSliceInfo, 0, sizeof(optionalSliceInfo)); + + ::android::hardware::radio::V1_6::OptionalTrafficDescriptor optionalTrafficDescriptor; + memset(&optionalTrafficDescriptor, 0, sizeof(optionalTrafficDescriptor)); + + ::android::hardware::radio::V1_6::TrafficDescriptor trafficDescriptor; + ::android::hardware::radio::V1_6::OSAppId osAppId; + osAppId.osAppId = 1; + trafficDescriptor.osAppId.value(osAppId); + optionalTrafficDescriptor.value(trafficDescriptor); + + bool matchAllRuleAllowed = true; + + Return<void> res = + radio_v1_6->setupDataCall_1_6(serial, accessNetwork, dataProfileInfo, roamingAllowed, + reason, addresses, dnses, -1, optionalSliceInfo, + optionalTrafficDescriptor, matchAllRuleAllowed); + ASSERT_OK(res); + + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type); + EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial); + if (cardStatus.base.base.base.cardState == CardState::ABSENT) { + ASSERT_TRUE(CheckAnyOfErrors( + radioRsp_v1_6->rspInfo.error, + {::android::hardware::radio::V1_6::RadioError::SIM_ABSENT, + ::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE, + ::android::hardware::radio::V1_6::RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW})); + } else if (cardStatus.base.base.base.cardState == CardState::PRESENT) { + ASSERT_TRUE(CheckAnyOfErrors( + radioRsp_v1_6->rspInfo.error, + {::android::hardware::radio::V1_6::RadioError::NONE, + ::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE, + ::android::hardware::radio::V1_6::RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW})); + EXPECT_EQ(optionalTrafficDescriptor.value().osAppId.value().osAppId, + radioRsp_v1_6->setupDataCallResult.trafficDescriptors[0].osAppId.value().osAppId); + } +} + +/* + * Test IRadio.getSlicingConfig() for the response returned. + */ +TEST_P(RadioHidlTest_v1_6, getSlicingConfig) { + serial = GetRandomSerialNumber(); + radio_v1_6->getSlicingConfig(serial); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type); + EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial); + EXPECT_EQ(::android::hardware::radio::V1_6::RadioError::NONE, radioRsp_v1_6->rspInfo.error); +} + /* * Test IRadio_1_6.sendSms() for the response returned. */ @@ -412,6 +505,167 @@ TEST_P(RadioHidlTest_v1_6, setSimCardPower_1_6) { } /* + * Test IRadio.emergencyDial() for the response returned. + */ +TEST_P(RadioHidlTest_v1_6, emergencyDial_1_6) { + if (!deviceSupportsFeature(FEATURE_VOICE_CALL)) { + ALOGI("Skipping emergencyDial because voice call is not supported in device"); + return; + } else { + ALOGI("Running emergencyDial because voice call is supported in device"); + } + + serial = GetRandomSerialNumber(); + + ::android::hardware::radio::V1_0::Dial dialInfo; + dialInfo.address = hidl_string("911"); + int categories = static_cast<int>( + ::android::hardware::radio::V1_4::EmergencyServiceCategory::UNSPECIFIED); + std::vector<hidl_string> urns = {""}; + ::android::hardware::radio::V1_4::EmergencyCallRouting routing = + ::android::hardware::radio::V1_4::EmergencyCallRouting::UNKNOWN; + + Return<void> res = + radio_v1_6->emergencyDial_1_6(serial, dialInfo, categories, urns, routing, true, true); + ASSERT_OK(res); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo_v1_0.type); + EXPECT_EQ(serial, radioRsp_v1_6->rspInfo_v1_0.serial); + + ALOGI("emergencyDial, rspInfo_v1_0.error = %s\n", + toString(radioRsp_v1_6->rspInfo_v1_0.error).c_str()); + + ::android::hardware::radio::V1_0::RadioError rspEmergencyDial = + radioRsp_v1_6->rspInfo_v1_0.error; + // In DSDS or TSTS, we only check the result if the current slot is IN_SERVICE + // or Emergency_Only. + if (isDsDsEnabled() || isTsTsEnabled()) { + serial = GetRandomSerialNumber(); + radio_v1_6->getVoiceRegistrationState(serial); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + if (isVoiceEmergencyOnly(radioRsp_v1_6->voiceRegResp.regState) || + isVoiceInService(radioRsp_v1_6->voiceRegResp.regState)) { + EXPECT_EQ(::android::hardware::radio::V1_0::RadioError::NONE, rspEmergencyDial); + } + } else { + EXPECT_EQ(::android::hardware::radio::V1_0::RadioError::NONE, rspEmergencyDial); + } + + // Give some time for modem to establish the emergency call channel. + sleep(MODEM_EMERGENCY_CALL_ESTABLISH_TIME); + + // Disconnect all the potential established calls to prevent them affecting other tests. + clearPotentialEstablishedCalls(); +} + +/* + * Test IRadio.emergencyDial() with specified service and its response returned. + */ +TEST_P(RadioHidlTest_v1_6, emergencyDial_1_6_withServices) { + if (!deviceSupportsFeature(FEATURE_VOICE_CALL)) { + ALOGI("Skipping emergencyDial because voice call is not supported in device"); + return; + } else { + ALOGI("Running emergencyDial because voice call is supported in device"); + } + + serial = GetRandomSerialNumber(); + + ::android::hardware::radio::V1_0::Dial dialInfo; + dialInfo.address = hidl_string("911"); + int categories = + static_cast<int>(::android::hardware::radio::V1_4::EmergencyServiceCategory::AMBULANCE); + std::vector<hidl_string> urns = {"urn:service:sos.ambulance"}; + ::android::hardware::radio::V1_4::EmergencyCallRouting routing = + ::android::hardware::radio::V1_4::EmergencyCallRouting::UNKNOWN; + + Return<void> res = + radio_v1_6->emergencyDial_1_6(serial, dialInfo, categories, urns, routing, true, true); + ASSERT_OK(res); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo_v1_0.type); + EXPECT_EQ(serial, radioRsp_v1_6->rspInfo_v1_0.serial); + + ALOGI("emergencyDial_withServices, rspInfo_v1_0.error = %s\n", + toString(radioRsp_v1_6->rspInfo_v1_0.error).c_str()); + ::android::hardware::radio::V1_0::RadioError rspEmergencyDial = + radioRsp_v1_6->rspInfo_v1_0.error; + + // In DSDS or TSTS, we only check the result if the current slot is IN_SERVICE + // or Emergency_Only. + if (isDsDsEnabled() || isTsTsEnabled()) { + serial = GetRandomSerialNumber(); + radio_v1_6->getVoiceRegistrationState(serial); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + if (isVoiceEmergencyOnly(radioRsp_v1_6->voiceRegResp.regState) || + isVoiceInService(radioRsp_v1_6->voiceRegResp.regState)) { + EXPECT_EQ(::android::hardware::radio::V1_0::RadioError::NONE, rspEmergencyDial); + } + } else { + EXPECT_EQ(::android::hardware::radio::V1_0::RadioError::NONE, rspEmergencyDial); + } + // Give some time for modem to establish the emergency call channel. + sleep(MODEM_EMERGENCY_CALL_ESTABLISH_TIME); + + // Disconnect all the potential established calls to prevent them affecting other tests. + clearPotentialEstablishedCalls(); +} + +/* + * Test IRadio.emergencyDial() with known emergency call routing and its response returned. + */ +TEST_P(RadioHidlTest_v1_6, emergencyDial_1_6_withEmergencyRouting) { + if (!deviceSupportsFeature(FEATURE_VOICE_CALL)) { + ALOGI("Skipping emergencyDial because voice call is not supported in device"); + return; + } else { + ALOGI("Running emergencyDial because voice call is supported in device"); + } + + serial = GetRandomSerialNumber(); + + ::android::hardware::radio::V1_0::Dial dialInfo; + dialInfo.address = hidl_string("911"); + int categories = static_cast<int>( + ::android::hardware::radio::V1_4::EmergencyServiceCategory::UNSPECIFIED); + std::vector<hidl_string> urns = {""}; + ::android::hardware::radio::V1_4::EmergencyCallRouting routing = + ::android::hardware::radio::V1_4::EmergencyCallRouting::EMERGENCY; + + Return<void> res = + radio_v1_6->emergencyDial_1_6(serial, dialInfo, categories, urns, routing, true, true); + ASSERT_OK(res); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo_v1_0.type); + EXPECT_EQ(serial, radioRsp_v1_6->rspInfo_v1_0.serial); + + ALOGI("emergencyDial_withEmergencyRouting, rspInfo_v1_0.error = %s\n", + toString(radioRsp_v1_6->rspInfo_v1_0.error).c_str()); + ::android::hardware::radio::V1_0::RadioError rspEmergencyDial = + radioRsp_v1_6->rspInfo_v1_0.error; + + // In DSDS or TSTS, we only check the result if the current slot is IN_SERVICE + // or Emergency_Only. + if (isDsDsEnabled() || isTsTsEnabled()) { + serial = GetRandomSerialNumber(); + radio_v1_6->getVoiceRegistrationState(serial); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + if (isVoiceEmergencyOnly(radioRsp_v1_6->voiceRegResp.regState) || + isVoiceInService(radioRsp_v1_6->voiceRegResp.regState)) { + EXPECT_EQ(::android::hardware::radio::V1_0::RadioError::NONE, rspEmergencyDial); + } + } else { + EXPECT_EQ(::android::hardware::radio::V1_0::RadioError::NONE, rspEmergencyDial); + } + + // Give some time for modem to establish the emergency call channel. + sleep(MODEM_EMERGENCY_CALL_ESTABLISH_TIME); + + // Disconnect all the potential established calls to prevent them affecting other tests. + clearPotentialEstablishedCalls(); +} + +/* * Test IRadio.getCurrentCalls_1_6() for the response returned. */ TEST_P(RadioHidlTest_v1_6, getCurrentCalls_1_6) { diff --git a/radio/1.6/vts/functional/radio_hidl_hal_test.cpp b/radio/1.6/vts/functional/radio_hidl_hal_test.cpp index 79c3cde745..59f768201d 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_test.cpp +++ b/radio/1.6/vts/functional/radio_hidl_hal_test.cpp @@ -74,6 +74,29 @@ std::cv_status RadioHidlTest_v1_6::wait() { return status; } +void RadioHidlTest_v1_6::clearPotentialEstablishedCalls() { + // Get the current call Id to hangup the established emergency call. + serial = GetRandomSerialNumber(); + radio_v1_6->getCurrentCalls_1_6(serial); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + + // Hang up to disconnect the established call channels. + for (const ::android::hardware::radio::V1_6::Call& call : radioRsp_v1_6->currentCalls) { + serial = GetRandomSerialNumber(); + radio_v1_6->hangup(serial, call.base.base.index); + ALOGI("Hang up to disconnect the established call channel: %d", call.base.base.index); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + // Give some time for modem to disconnect the established call channel. + sleep(MODEM_EMERGENCY_CALL_DISCONNECT_TIME); + } + + // Verify there are no more current calls. + serial = GetRandomSerialNumber(); + radio_v1_6->getCurrentCalls_1_6(serial); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(0, radioRsp_v1_6->currentCalls.size()); +} + void RadioHidlTest_v1_6::updateSimCardStatus() { serial = GetRandomSerialNumber(); radio_v1_6->getIccCardStatus(serial); diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h index 5fcfa3b0bb..f32e31296d 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h +++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h @@ -70,7 +70,8 @@ class RadioResponse_v1_6 : public ::android::hardware::radio::V1_6::IRadioRespon ::android::hardware::radio::V1_6::RadioResponseInfo rspInfo; // Call - hidl_vec<::android::hardware::radio::V1_2::Call> currentCalls; + hidl_vec<::android::hardware::radio::V1_6::Call> currentCalls; + ::android::hardware::radio::V1_2::VoiceRegStateResult voiceRegResp; // Sms SendSmsResult sendSmsResult; @@ -88,6 +89,7 @@ class RadioResponse_v1_6 : public ::android::hardware::radio::V1_6::IRadioRespon // Data ::android::hardware::radio::V1_4::DataRegStateResult dataRegResp; + ::android::hardware::radio::V1_6::SetupDataCallResult setupDataCallResult; // SimLock status ::android::hardware::radio::V1_4::CarrierRestrictionsWithPriority carrierRestrictionsResp; @@ -790,10 +792,10 @@ class RadioResponse_v1_6 : public ::android::hardware::radio::V1_6::IRadioRespon Return<void> cancelHandoverResponse( const ::android::hardware::radio::V1_6::RadioResponseInfo& info); - Return<void> setAllowedNetworkTypeBitmapResponse( + Return<void> setAllowedNetworkTypesBitmapResponse( const ::android::hardware::radio::V1_6::RadioResponseInfo& info); - Return<void> getAllowedNetworkTypeBitmapResponse( + Return<void> getAllowedNetworkTypesBitmapResponse( const ::android::hardware::radio::V1_6::RadioResponseInfo& info, const ::android::hardware::hidl_bitfield< ::android::hardware::radio::V1_4::RadioAccessFamily> @@ -825,6 +827,10 @@ class RadioResponse_v1_6 : public ::android::hardware::radio::V1_6::IRadioRespon Return<void> getCurrentCallsResponse_1_6( const ::android::hardware::radio::V1_6::RadioResponseInfo& info, const ::android::hardware::hidl_vec<::android::hardware::radio::V1_6::Call>& calls); + + Return<void> getSlicingConfigResponse( + const ::android::hardware::radio::V1_6::RadioResponseInfo& info, + const ::android::hardware::radio::V1_6::SlicingConfig& slicingConfig); }; /* Callback class for radio indication */ diff --git a/radio/1.6/vts/functional/radio_response.cpp b/radio/1.6/vts/functional/radio_response.cpp index 7c5cf6df86..fad3f12e2b 100644 --- a/radio/1.6/vts/functional/radio_response.cpp +++ b/radio/1.6/vts/functional/radio_response.cpp @@ -816,8 +816,11 @@ Return<void> RadioResponse_v1_6::getCellInfoListResponse_1_2( } Return<void> RadioResponse_v1_6::getVoiceRegistrationStateResponse_1_2( - const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, - const ::android::hardware::radio::V1_2::VoiceRegStateResult& /*voiceRegResponse*/) { + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + const ::android::hardware::radio::V1_2::VoiceRegStateResult& voiceRegResponse) { + rspInfo_v1_0 = info; + voiceRegResp = voiceRegResponse; + parent_v1_6.notify(info.serial); return Void(); } @@ -1050,8 +1053,9 @@ Return<void> RadioResponse_v1_6::setRadioPowerResponse_1_6( Return<void> RadioResponse_v1_6::setupDataCallResponse_1_6( const ::android::hardware::radio::V1_6::RadioResponseInfo& info, - const android::hardware::radio::V1_6::SetupDataCallResult& /* dcResponse */) { + const android::hardware::radio::V1_6::SetupDataCallResult& dcResponse) { rspInfo = info; + setupDataCallResult = dcResponse; parent_v1_6.notify(info.serial); return Void(); } @@ -1150,14 +1154,14 @@ Return<void> RadioResponse_v1_6::cancelHandoverResponse( return Void(); } -Return<void> RadioResponse_v1_6::setAllowedNetworkTypeBitmapResponse( +Return<void> RadioResponse_v1_6::setAllowedNetworkTypesBitmapResponse( const ::android::hardware::radio::V1_6::RadioResponseInfo& info) { rspInfo = info; parent_v1_6.notify(info.serial); return Void(); } -Return<void> RadioResponse_v1_6::getAllowedNetworkTypeBitmapResponse( +Return<void> RadioResponse_v1_6::getAllowedNetworkTypesBitmapResponse( const ::android::hardware::radio::V1_6::RadioResponseInfo& /*info*/, const ::android::hardware::hidl_bitfield< ::android::hardware::radio::V1_4::RadioAccessFamily> @@ -1210,7 +1214,16 @@ Return<void> RadioResponse_v1_6::getDataRegistrationStateResponse_1_6( Return<void> RadioResponse_v1_6::getCurrentCallsResponse_1_6( const ::android::hardware::radio::V1_6::RadioResponseInfo& info, - const ::android::hardware::hidl_vec<::android::hardware::radio::V1_6::Call>& /*calls*/) { + const ::android::hardware::hidl_vec<::android::hardware::radio::V1_6::Call>& calls) { + rspInfo = info; + currentCalls = calls; + parent_v1_6.notify(info.serial); + return Void(); +} + +Return<void> RadioResponse_v1_6::getSlicingConfigResponse( + const ::android::hardware::radio::V1_6::RadioResponseInfo& info, + const ::android::hardware::radio::V1_6::SlicingConfig& /*slicingConfig*/) { rspInfo = info; parent_v1_6.notify(info.serial); return Void(); diff --git a/rebootescrow/aidl/default/Android.bp b/rebootescrow/aidl/default/Android.bp index b77272f6d8..e6a4e7ab4f 100644 --- a/rebootescrow/aidl/default/Android.bp +++ b/rebootescrow/aidl/default/Android.bp @@ -20,7 +20,7 @@ cc_library_static { shared_libs: [ "libbase", "libbinder_ndk", - "android.hardware.rebootescrow-ndk_platform", + "android.hardware.rebootescrow-V1-ndk_platform", ], export_include_dirs: ["include"], srcs: [ @@ -47,7 +47,7 @@ cc_binary { shared_libs: [ "libbase", "libbinder_ndk", - "android.hardware.rebootescrow-ndk_platform", + "android.hardware.rebootescrow-V1-ndk_platform", ], static_libs: [ "libhadamardutils", diff --git a/rebootescrow/aidl/vts/functional/Android.bp b/rebootescrow/aidl/vts/functional/Android.bp index 2cc00685d6..abd4937f62 100644 --- a/rebootescrow/aidl/vts/functional/Android.bp +++ b/rebootescrow/aidl/vts/functional/Android.bp @@ -25,7 +25,7 @@ cc_test { "libbinder", ], static_libs: [ - "android.hardware.rebootescrow-cpp", + "android.hardware.rebootescrow-V1-cpp", ], test_suites: [ "vts", diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Algorithm.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Algorithm.aidl index a6c3e65a3b..29ff8f812e 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Algorithm.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Algorithm.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/BeginResult.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/BeginResult.aidl index 84395afec8..442161951c 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/BeginResult.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/BeginResult.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/BlockMode.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/BlockMode.aidl index e914823007..e9652c35db 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/BlockMode.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/BlockMode.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ByteArray.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ByteArray.aidl index cef8eca8a9..34f2749db9 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ByteArray.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ByteArray.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Certificate.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Certificate.aidl index 2277831c73..5d1cc688f4 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Certificate.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Certificate.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Digest.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Digest.aidl index 2e583ce104..5055d7544c 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Digest.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Digest.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/EcCurve.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/EcCurve.aidl index b37282242a..1a7e9b5256 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/EcCurve.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/EcCurve.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ErrorCode.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ErrorCode.aidl index aa8c071bf4..594844a736 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ErrorCode.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ErrorCode.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/HardwareAuthToken.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/HardwareAuthToken.aidl index ad5bf39b33..bd304f18e2 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/HardwareAuthToken.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/HardwareAuthToken.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// @@ -17,7 +31,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.security.keymint; -@VintfStability +@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability parcelable HardwareAuthToken { long challenge; long userId; diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/HardwareAuthenticatorType.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/HardwareAuthenticatorType.aidl index 9ab00c100f..ae64110f69 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/HardwareAuthenticatorType.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/HardwareAuthenticatorType.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintDevice.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintDevice.aidl index c95145d993..132135bf06 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintDevice.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintDevice.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintOperation.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintOperation.aidl index e6ab4c8940..a9b9a05a09 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintOperation.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintOperation.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyCharacteristics.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyCharacteristics.aidl index 49ea8af911..b430da95aa 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyCharacteristics.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyCharacteristics.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyCreationResult.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyCreationResult.aidl index 4b9ac79711..41394364ed 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyCreationResult.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyCreationResult.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyFormat.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyFormat.aidl index 4eb5a7829f..1ad7c51a0c 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyFormat.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyFormat.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyMintHardwareInfo.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyMintHardwareInfo.aidl index 0390ec9fa4..93966ea2b0 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyMintHardwareInfo.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyMintHardwareInfo.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// @@ -17,7 +31,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.security.keymint; -@VintfStability +@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability parcelable KeyMintHardwareInfo { int versionNumber; android.hardware.security.keymint.SecurityLevel securityLevel; diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyOrigin.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyOrigin.aidl index e84cf74b1a..acaf60d3b6 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyOrigin.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyOrigin.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameter.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameter.aidl index 6829a2b0f6..f534952e62 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameter.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameter.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameterArray.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameterArray.aidl index 882ca89c2e..2706623768 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameterArray.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameterArray.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameterValue.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameterValue.aidl index 6c11a924e7..c79614a5b8 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameterValue.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameterValue.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyPurpose.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyPurpose.aidl index ff8d85a31a..c1e92af3a7 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyPurpose.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyPurpose.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// @@ -24,4 +38,5 @@ enum KeyPurpose { SIGN = 2, VERIFY = 3, WRAP_KEY = 5, + AGREE_KEY = 6, } diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/PaddingMode.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/PaddingMode.aidl index 6c61312314..96b63e1bcc 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/PaddingMode.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/PaddingMode.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/SecurityLevel.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/SecurityLevel.aidl index c4812ed67a..c720d6d345 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/SecurityLevel.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/SecurityLevel.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// @@ -22,4 +36,5 @@ enum SecurityLevel { SOFTWARE = 0, TRUSTED_ENVIRONMENT = 1, STRONGBOX = 2, + KEYSTORE = 100, } diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Tag.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Tag.aidl index ce12fed082..b924a13266 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Tag.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Tag.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// @@ -42,6 +56,7 @@ enum Tag { USAGE_EXPIRE_DATETIME = 1610613138, MIN_SECONDS_BETWEEN_OPS = 805306771, MAX_USES_PER_BOOT = 805306772, + USAGE_COUNT_LIMIT = 805306773, USER_ID = 805306869, USER_SECURE_ID = -1610612234, NO_AUTH_REQUIRED = 1879048695, diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/TagType.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/TagType.aidl index 41c8832a0b..75a19a3440 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/TagType.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/TagType.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/security/keymint/aidl/android/hardware/security/keymint/HardwareAuthToken.aidl b/security/keymint/aidl/android/hardware/security/keymint/HardwareAuthToken.aidl index 1067540d9c..417a0b1dbe 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/HardwareAuthToken.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/HardwareAuthToken.aidl @@ -29,6 +29,7 @@ import android.hardware.security.keymint.HardwareAuthenticatorType; * appropriate for a given key operation. */ @VintfStability +@RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true) parcelable HardwareAuthToken { /** * challenge is a value that's used to enable authentication tokens to authorize specific diff --git a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl index d5f7a1ff33..0120a30dd5 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl @@ -26,7 +26,6 @@ import android.hardware.security.keymint.KeyParameter; import android.hardware.security.keymint.KeyMintHardwareInfo; import android.hardware.security.keymint.KeyPurpose; import android.hardware.security.keymint.SecurityLevel; -import android.hardware.security.secureclock.TimeStampToken; /** * KeyMint device definition. @@ -682,9 +681,9 @@ interface IKeyMintDevice { * values less than the key's minimum length, begin() must return ErrorCode::INVALID_MAC_LENGTH. * * @param inPurpose The purpose of the operation, one of KeyPurpose::ENCRYPT, - * KeyPurpose::DECRYPT, KeyPurpose::SIGN or KeyPurpose::VERIFY. Note that for AEAD - * modes, encryption and decryption imply signing and verification, respectively, but - * must be specified as KeyPurpose::ENCRYPT and KeyPurpose::DECRYPT. + * KeyPurpose::DECRYPT, KeyPurpose::SIGN, KeyPurpose::VERIFY, or KeyPurpose::AGREE_KEY. + * Note that for AEAD modes, encryption and decryption imply signing and verification, + * respectively, but must be specified as KeyPurpose::ENCRYPT and KeyPurpose::DECRYPT. * * @param inKeyBlob The opaque key descriptor returned by generateKey() or importKey(). The key * must have a purpose compatible with purpose and all of its usage requirements must be diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl index b149ac9975..69bec2d79f 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl @@ -36,7 +36,6 @@ parcelable KeyCreationResult { * deciding whether a given tag from `keyParams` argument to the generation/import method should * be returned in `keyCharacteristics` are: * - * - If the IKeyMintDevice cannot fully enforce the semantics of the tag, it should be omitted. * - If the semantics of the tag are fully enforced by the IKeyMintDevice, without any * assistance from components running at other security levels, it should be included in an * entry with the SecurityLevel of the IKeyMintDevice. @@ -45,6 +44,9 @@ parcelable KeyCreationResult { * SecurityLevel of the involved components. For example if a StrongBox IKeyMintDevice relies * on a TEE to validate biometric authentication, biometric authentication tags go in an entry * with SecurityLevel::TRUSTED_ENVIRONMENT. + * - If the semantics are not enforced by KeyMint at all, SecurityLevel::KEYSTORE is used to + * indicate that Keystore should enforce. Note that in Keymaster (predecessor to KeyMint), + * these tags would have been in SecurityLevel::SOFTWARE. */ KeyCharacteristics[] keyCharacteristics; diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyMintHardwareInfo.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyMintHardwareInfo.aidl index d3d7368add..1a107ba728 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/KeyMintHardwareInfo.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/KeyMintHardwareInfo.aidl @@ -22,6 +22,7 @@ import android.hardware.security.keymint.SecurityLevel; * KeyMintHardwareInfo is the hardware information returned by calling KeyMint getHardwareInfo() */ @VintfStability +@RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true) parcelable KeyMintHardwareInfo { /** * Implementation version of the keymint hardware. The version number is implementation diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyPurpose.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyPurpose.aidl index cb4682ea56..68c1740791 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/KeyPurpose.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/KeyPurpose.aidl @@ -39,5 +39,8 @@ enum KeyPurpose { /* Usable with wrapping keys. */ WRAP_KEY = 5, - /* TODO(seleneh) add AGREE_KEY and ATTEST_KEY and their corresponding codes and tests later*/ + /* Key Agreement, usable with EC keys. */ + AGREE_KEY = 6, + + /* TODO(seleneh) add ATTEST_KEY and their corresponding codes and tests later*/ } diff --git a/security/keymint/aidl/android/hardware/security/keymint/SecurityLevel.aidl b/security/keymint/aidl/android/hardware/security/keymint/SecurityLevel.aidl index 10363e9bb0..c63859c782 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/SecurityLevel.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/SecurityLevel.aidl @@ -17,16 +17,59 @@ package android.hardware.security.keymint; /** - * Device security levels. + * Device security levels. These enum values are used in two ways: + * + * 1. Returned from IKeyMintDevice::getHardwareInfo to identify the security level of the + * IKeyMintDevice. This characterizes the sort of environment in which the KeyMint + * implementation runs, and therefore the security of its operations. + * + * 2. Associated with individual KeyMint authorization Tags in KeyCharacteristics or in attestation + * certificates. This specifies the security level of the weakest environment involved in + * enforcing that particular tag, i.e. the sort of security environment an attacker would have + * to subvert in order to break the enforcement of that tag. */ @VintfStability @Backing(type="int") enum SecurityLevel { + /** + * The SOFTWARE security level represents a KeyMint implementation that runs in an Android + * process, or a tag enforced by such an implementation. An attacker who can compromise that + * process, or obtain root, or subvert the kernel on the device can defeat it. + * + * Note that the distinction between SOFTWARE and KEYSTORE is only relevant on-device. For + * attestation purposes, these categories are combined into the software-enforced authorization + * list. + */ SOFTWARE = 0, + + /** + * The TRUSTED_ENVIRONMENT security level represents a KeyMint implementation that runs in an + * Android process, or a tag enforced by such an implementation. An attacker who completely + * compromises Android, including the Linux kernel, does not have the ability to subvert it. At + * attacker who can find an exploit that gains them control of the trusted environment, or who + * has access to the physical device and can mount a sophisticated hardware attack, may be able + * to defeat it. + */ TRUSTED_ENVIRONMENT = 1, /** - * STRONGBOX specifies that the secure hardware satisfies the requirements specified in CDD - * 9.11.2. + * The STRONGBOX security level represents a KeyMint implementation that runs in security + * hardware that satisfies the requirements specified in CDD 9.11.2. Roughly speaking, these + * are discrete, security-focus computing environments that are hardened against physical and + * side channel attack, and have had their security formally validated by a competent + * penetration testing lab. */ STRONGBOX = 2, + + /** + * KeyMint implementations must never return the KEYSTORE security level from getHardwareInfo. + * It is used to specify tags that are not enforced by the IKeyMintDevice, but are instead + * to be enforced by Keystore. An attacker who can subvert the keystore process or gain root or + * subvert the kernel can prevent proper enforcement of these tags. + * + * + * Note that the distinction between SOFTWARE and KEYSTORE is only relevant on-device. When + * KeyMint generates an attestation certificate, these categories are combined into the + * software-enforced authorization list. + */ + KEYSTORE = 100 } diff --git a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl index f92bf008ed..f52e32b96a 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl @@ -27,7 +27,7 @@ import android.hardware.security.keymint.TagType; * data are stored in KeyParameter. */ @VintfStability -@Backing(type = "int") +@Backing(type="int") enum Tag { /** * Tag::INVALID should never be set. It means you hit an error. @@ -82,7 +82,6 @@ enum Tag { */ BLOCK_MODE = (2 << 28) /* TagType:ENUM_REP */ | 4, - /** * Tag::DIGEST specifies the digest algorithms that may be used with the key to perform signing * and verification operations. This tag is relevant to RSA, ECDSA and HMAC keys. Possible @@ -187,21 +186,21 @@ enum Tag { */ INCLUDE_UNIQUE_ID = (7 << 28) /* TagType:BOOL */ | 202, - /** - * Tag::RSA_OAEP_MGF_DIGEST specifies the MGF1 digest algorithms that may be used with - * RSA encryption/decryption with OAEP padding. If the key characteristics supports OAEP - * and this tag is absent then SHA1 digest is selected by default for MGF1. - * - * This tag is repeatable for key generation/import. If this tag is present in the key - * characteristics with one or more values from @4.0::Digest, then for RSA cipher - * operations with OAEP Padding, the caller must specify a digest in the additionalParams - * argument of begin operation. If this tag is missing or the specified digest is not in - * the digests associated with the key then begin operation must fail with - * ErrorCode::INCOMPATIBLE_MGF_DIGEST. - * - * Must be hardware-enforced. - */ - RSA_OAEP_MGF_DIGEST = (2 << 28) /* TagType:ENUM_REP */ | 203, + /** + * Tag::RSA_OAEP_MGF_DIGEST specifies the MGF1 digest algorithms that may be used with + * RSA encryption/decryption with OAEP padding. If the key characteristics supports OAEP + * and this tag is absent then SHA1 digest is selected by default for MGF1. + * + * This tag is repeatable for key generation/import. If this tag is present in the key + * characteristics with one or more values from @4.0::Digest, then for RSA cipher + * operations with OAEP Padding, the caller must specify a digest in the additionalParams + * argument of begin operation. If this tag is missing or the specified digest is not in + * the digests associated with the key then begin operation must fail with + * ErrorCode::INCOMPATIBLE_MGF_DIGEST. + * + * Must be hardware-enforced. + */ + RSA_OAEP_MGF_DIGEST = (2 << 28) /* TagType:ENUM_REP */ | 203, /** * TODO(seleneh) this tag needs to be deleted from all codes. @@ -333,6 +332,35 @@ enum Tag { MAX_USES_PER_BOOT = (3 << 28) /* TagType:UINT */ | 404, /** + * Tag::USAGE_COUNT_LIMIT specifies the number of times that a key may be used. This can be + * used to limit the use of a key. + * + * The value is a 32-bit integer representing the current number of attempts left. + * + * When initializing a limited use key, the value of this tag represents the maximum usage + * limit for that key. After the key usage is exhausted, the key blob should be invalidated by + * finish() call. Any subsequent attempts to use the key must result in a failure with + * ErrorCode::INVALID_KEY_BLOB returned by IKeyMintDevice. + * + * At this point, if the caller specifies count > 1, it is not expected that any TEE will be + * able to enforce this feature in the hardware due to limited resources of secure + * storage. In this case, the tag with the value of maximum usage must be added to the key + * characteristics with SecurityLevel::KEYSTORE by the IKeyMintDevice. + * + * On the other hand, if the caller specifies count = 1, some TEEs may have the ability + * to enforce this feature in the hardware with its secure storage. If the IKeyMintDevice + * implementation can enforce this feature, the tag with value = 1 must be added to the key + * characteristics with the SecurityLevel of the IKeyMintDevice. If the IKeyMintDevice can't + * enforce this feature even when the count = 1, the tag must be added to the key + * characteristics with the SecurityLevel::KEYSTORE. + * + * When the key is attested, this tag with the same value must also be added to the attestation + * record. This tag must have the same SecurityLevel as the tag that is added to the key + * characteristics. + */ + USAGE_COUNT_LIMIT = (3 << 28) | 405, /* TagType:UINT */ + + /** * Tag::USER_ID specifies the ID of the Android user that is permitted to use the key. * * Must not be hardware-enforced. @@ -468,7 +496,8 @@ enum Tag { */ TRUSTED_USER_PRESENCE_REQUIRED = (7 << 28) /* TagType:BOOL */ | 507, - /** Tag::TRUSTED_CONFIRMATION_REQUIRED is only applicable to keys with KeyPurpose SIGN, and + /** + * Tag::TRUSTED_CONFIRMATION_REQUIRED is only applicable to keys with KeyPurpose SIGN, and * specifies that this key must not be usable unless the user provides confirmation of the data * to be signed. Confirmation is proven to keyMint via an approval token. See * CONFIRMATION_TOKEN, as well as the ConfirmatinUI HAL. diff --git a/security/keymint/aidl/default/Android.bp b/security/keymint/aidl/default/Android.bp index 79697c4e9e..b2758adcb1 100644 --- a/security/keymint/aidl/default/Android.bp +++ b/security/keymint/aidl/default/Android.bp @@ -9,7 +9,7 @@ cc_binary { "-Wextra", ], shared_libs: [ - "android.hardware.security.keymint-unstable-ndk_platform", + "android.hardware.security.keymint-V1-ndk_platform", "libbase", "libbinder_ndk", "libcppbor", diff --git a/security/keymint/aidl/vts/functional/Android.bp b/security/keymint/aidl/vts/functional/Android.bp index 17a461366c..f4ba9e7362 100644 --- a/security/keymint/aidl/vts/functional/Android.bp +++ b/security/keymint/aidl/vts/functional/Android.bp @@ -30,8 +30,8 @@ cc_test { "libkeymint_support", ], static_libs: [ - "android.hardware.security.keymint-unstable-ndk_platform", - "android.hardware.security.secureclock-unstable-ndk_platform", + "android.hardware.security.keymint-V1-ndk_platform", + "android.hardware.security.secureclock-V1-ndk_platform", "libcppbor_external", "libkeymint_vts_test_utils", ], @@ -60,8 +60,8 @@ cc_test_library { "libkeymint_support", ], static_libs: [ - "android.hardware.security.keymint-unstable-ndk_platform", - "android.hardware.security.secureclock-unstable-ndk_platform", + "android.hardware.security.keymint-V1-ndk_platform", + "android.hardware.security.secureclock-V1-ndk_platform", "libcppbor", ], } diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp index 766c02dea9..6555157e5c 100644 --- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp @@ -55,6 +55,9 @@ bool KeyCharacteristicsBasicallyValid(SecurityLevel secLevel, for (auto& entry : key_characteristics) { if (entry.authorizations.empty()) return false; + // Just ignore the SecurityLevel::KEYSTORE as the KM won't do any enforcement on this. + if (entry.securityLevel == SecurityLevel::KEYSTORE) continue; + if (levels_seen.find(entry.securityLevel) != levels_seen.end()) return false; levels_seen.insert(entry.securityLevel); @@ -824,22 +827,36 @@ const vector<KeyParameter>& KeyMintAidlTestBase::SecLevelAuthorizations( return (found == key_characteristics.end()) ? kEmptyAuthList : found->authorizations; } -const vector<KeyParameter>& KeyMintAidlTestBase::HwEnforcedAuthorizations( - const vector<KeyCharacteristics>& key_characteristics) { - auto found = - std::find_if(key_characteristics.begin(), key_characteristics.end(), [](auto& entry) { - return entry.securityLevel == SecurityLevel::STRONGBOX || - entry.securityLevel == SecurityLevel::TRUSTED_ENVIRONMENT; - }); +const vector<KeyParameter>& KeyMintAidlTestBase::SecLevelAuthorizations( + const vector<KeyCharacteristics>& key_characteristics, SecurityLevel securityLevel) { + auto found = std::find_if( + key_characteristics.begin(), key_characteristics.end(), + [securityLevel](auto& entry) { return entry.securityLevel == securityLevel; }); return (found == key_characteristics.end()) ? kEmptyAuthList : found->authorizations; } -const vector<KeyParameter>& KeyMintAidlTestBase::SwEnforcedAuthorizations( +AuthorizationSet KeyMintAidlTestBase::HwEnforcedAuthorizations( const vector<KeyCharacteristics>& key_characteristics) { - auto found = std::find_if( - key_characteristics.begin(), key_characteristics.end(), - [](auto& entry) { return entry.securityLevel == SecurityLevel::SOFTWARE; }); - return (found == key_characteristics.end()) ? kEmptyAuthList : found->authorizations; + AuthorizationSet authList; + for (auto& entry : key_characteristics) { + if (entry.securityLevel == SecurityLevel::STRONGBOX || + entry.securityLevel == SecurityLevel::TRUSTED_ENVIRONMENT) { + authList.push_back(AuthorizationSet(entry.authorizations)); + } + } + return authList; +} + +AuthorizationSet KeyMintAidlTestBase::SwEnforcedAuthorizations( + const vector<KeyCharacteristics>& key_characteristics) { + AuthorizationSet authList; + for (auto& entry : key_characteristics) { + if (entry.securityLevel == SecurityLevel::SOFTWARE || + entry.securityLevel == SecurityLevel::KEYSTORE) { + authList.push_back(AuthorizationSet(entry.authorizations)); + } + } + return authList; } } // namespace test diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h index c1a1dd9034..780971dc8c 100644 --- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h +++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h @@ -175,9 +175,12 @@ class KeyMintAidlTestBase : public ::testing::TestWithParam<string> { inline const vector<KeyParameter>& SecLevelAuthorizations() { return SecLevelAuthorizations(key_characteristics_); } - const vector<KeyParameter>& HwEnforcedAuthorizations( + const vector<KeyParameter>& SecLevelAuthorizations( + const vector<KeyCharacteristics>& key_characteristics, SecurityLevel securityLevel); + + AuthorizationSet HwEnforcedAuthorizations( const vector<KeyCharacteristics>& key_characteristics); - const vector<KeyParameter>& SwEnforcedAuthorizations( + AuthorizationSet SwEnforcedAuthorizations( const vector<KeyCharacteristics>& key_characteristics); private: diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp index e7c94f37a0..c849bade2e 100644 --- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp @@ -20,9 +20,11 @@ #include <signal.h> #include <iostream> +#include <openssl/ec.h> #include <openssl/evp.h> #include <openssl/mem.h> #include <openssl/x509.h> +#include <openssl/x509v3.h> #include <cutils/properties.h> @@ -560,7 +562,7 @@ TEST_P(NewKeyGenerationTest, Rsa) { } /* - * NewKeyGenerationTest.Rsa + * NewKeyGenerationTest.RsaWithAttestation * * Verifies that keymint can generate all required RSA key sizes, and that the resulting keys * have correct characteristics. @@ -605,6 +607,100 @@ TEST_P(NewKeyGenerationTest, RsaWithAttestation) { } /* + * NewKeyGenerationTest.LimitedUsageRsa + * + * Verifies that KeyMint can generate all required RSA key sizes with limited usage, and that the + * resulting keys have correct characteristics. + */ +TEST_P(NewKeyGenerationTest, LimitedUsageRsa) { + for (auto key_size : ValidKeySizes(Algorithm::RSA)) { + vector<uint8_t> key_blob; + vector<KeyCharacteristics> key_characteristics; + ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() + .RsaSigningKey(key_size, 65537) + .Digest(Digest::NONE) + .Padding(PaddingMode::NONE) + .Authorization(TAG_USAGE_COUNT_LIMIT, 1), + &key_blob, &key_characteristics)); + + ASSERT_GT(key_blob.size(), 0U); + CheckBaseParams(key_characteristics); + + AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics); + + EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::RSA)); + EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size)) + << "Key size " << key_size << "missing"; + EXPECT_TRUE(crypto_params.Contains(TAG_RSA_PUBLIC_EXPONENT, 65537U)); + + // Check the usage count limit tag appears in the authorizations. + AuthorizationSet auths; + for (auto& entry : key_characteristics) { + auths.push_back(AuthorizationSet(entry.authorizations)); + } + EXPECT_TRUE(auths.Contains(TAG_USAGE_COUNT_LIMIT, 1U)) + << "key usage count limit " << 1U << " missing"; + + CheckedDeleteKey(&key_blob); + } +} + +/* + * NewKeyGenerationTest.LimitedUsageRsaWithAttestation + * + * Verifies that KeyMint can generate all required RSA key sizes with limited usage, and that the + * resulting keys have correct characteristics and attestation. + */ +TEST_P(NewKeyGenerationTest, LimitedUsageRsaWithAttestation) { + for (auto key_size : ValidKeySizes(Algorithm::RSA)) { + auto challenge = "hello"; + auto app_id = "foo"; + + vector<uint8_t> key_blob; + vector<KeyCharacteristics> key_characteristics; + ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() + .RsaSigningKey(key_size, 65537) + .Digest(Digest::NONE) + .Padding(PaddingMode::NONE) + .AttestationChallenge(challenge) + .AttestationApplicationId(app_id) + .Authorization(TAG_NO_AUTH_REQUIRED) + .Authorization(TAG_USAGE_COUNT_LIMIT, 1), + &key_blob, &key_characteristics)); + + ASSERT_GT(key_blob.size(), 0U); + CheckBaseParams(key_characteristics); + + AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics); + + EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::RSA)); + EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size)) + << "Key size " << key_size << "missing"; + EXPECT_TRUE(crypto_params.Contains(TAG_RSA_PUBLIC_EXPONENT, 65537U)); + + // Check the usage count limit tag appears in the authorizations. + AuthorizationSet auths; + for (auto& entry : key_characteristics) { + auths.push_back(AuthorizationSet(entry.authorizations)); + } + EXPECT_TRUE(auths.Contains(TAG_USAGE_COUNT_LIMIT, 1U)) + << "key usage count limit " << 1U << " missing"; + + // Check the usage count limit tag also appears in the attestation. + EXPECT_TRUE(verify_chain(cert_chain_)); + ASSERT_GT(cert_chain_.size(), 0); + + AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics); + AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics); + EXPECT_TRUE(verify_attestation_record(challenge, app_id, // + sw_enforced, hw_enforced, SecLevel(), + cert_chain_[0].encodedCertificate)); + + CheckedDeleteKey(&key_blob); + } +} + +/* * NewKeyGenerationTest.NoInvalidRsaSizes * * Verifies that keymint cannot generate any RSA key sizes that are designated as invalid. @@ -664,6 +760,43 @@ TEST_P(NewKeyGenerationTest, Ecdsa) { } /* + * NewKeyGenerationTest.LimitedUsageEcdsa + * + * Verifies that KeyMint can generate all required EC key sizes with limited usage, and that the + * resulting keys have correct characteristics. + */ +TEST_P(NewKeyGenerationTest, LimitedUsageEcdsa) { + for (auto key_size : ValidKeySizes(Algorithm::EC)) { + vector<uint8_t> key_blob; + vector<KeyCharacteristics> key_characteristics; + ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() + .EcdsaSigningKey(key_size) + .Digest(Digest::NONE) + .Authorization(TAG_USAGE_COUNT_LIMIT, 1), + &key_blob, &key_characteristics)); + + ASSERT_GT(key_blob.size(), 0U); + CheckBaseParams(key_characteristics); + + AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics); + + EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::EC)); + EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size)) + << "Key size " << key_size << "missing"; + + // Check the usage count limit tag appears in the authorizations. + AuthorizationSet auths; + for (auto& entry : key_characteristics) { + auths.push_back(AuthorizationSet(entry.authorizations)); + } + EXPECT_TRUE(auths.Contains(TAG_USAGE_COUNT_LIMIT, 1U)) + << "key usage count limit " << 1U << " missing"; + + CheckedDeleteKey(&key_blob); + } +} + +/* * NewKeyGenerationTest.EcdsaDefaultSize * * Verifies that failing to specify a key size for EC key generation returns @@ -778,6 +911,44 @@ TEST_P(NewKeyGenerationTest, Hmac) { } /* + * NewKeyGenerationTest.LimitedUsageHmac + * + * Verifies that KeyMint supports all required digests with limited usage Hmac, and that the + * resulting keys have correct characteristics. + */ +TEST_P(NewKeyGenerationTest, LimitedUsageHmac) { + for (auto digest : ValidDigests(false /* withNone */, true /* withMD5 */)) { + vector<uint8_t> key_blob; + vector<KeyCharacteristics> key_characteristics; + constexpr size_t key_size = 128; + ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() + .HmacKey(key_size) + .Digest(digest) + .Authorization(TAG_MIN_MAC_LENGTH, 128) + .Authorization(TAG_USAGE_COUNT_LIMIT, 1), + &key_blob, &key_characteristics)); + + ASSERT_GT(key_blob.size(), 0U); + CheckBaseParams(key_characteristics); + + AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics); + EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::HMAC)); + EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size)) + << "Key size " << key_size << "missing"; + + // Check the usage count limit tag appears in the authorizations. + AuthorizationSet auths; + for (auto& entry : key_characteristics) { + auths.push_back(AuthorizationSet(entry.authorizations)); + } + EXPECT_TRUE(auths.Contains(TAG_USAGE_COUNT_LIMIT, 1U)) + << "key usage count limit " << 1U << " missing"; + + CheckedDeleteKey(&key_blob); + } +} + +/* * NewKeyGenerationTest.HmacCheckKeySizes * * Verifies that keymint supports all key sizes, and rejects all invalid key sizes. @@ -4151,7 +4322,7 @@ TEST_P(MaxOperationsTest, TestLimitAes) { } /* - * MaxOperationsTest.TestLimitAes + * MaxOperationsTest.TestLimitRsa * * Verifies that the max uses per boot tag works correctly with RSA keys. */ @@ -4178,6 +4349,186 @@ TEST_P(MaxOperationsTest, TestLimitRsa) { INSTANTIATE_KEYMINT_AIDL_TEST(MaxOperationsTest); +typedef KeyMintAidlTestBase UsageCountLimitTest; + +/* + * UsageCountLimitTest.TestSingleUseAes + * + * Verifies that the usage count limit tag = 1 works correctly with AES keys. + */ +TEST_P(UsageCountLimitTest, TestSingleUseAes) { + if (SecLevel() == SecurityLevel::STRONGBOX) return; + + ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() + .Authorization(TAG_NO_AUTH_REQUIRED) + .AesEncryptionKey(128) + .EcbMode() + .Padding(PaddingMode::NONE) + .Authorization(TAG_USAGE_COUNT_LIMIT, 1))); + + // Check the usage count limit tag appears in the authorizations. + AuthorizationSet auths; + for (auto& entry : key_characteristics_) { + auths.push_back(AuthorizationSet(entry.authorizations)); + } + EXPECT_TRUE(auths.Contains(TAG_USAGE_COUNT_LIMIT, 1U)) + << "key usage count limit " << 1U << " missing"; + + string message = "1234567890123456"; + auto params = AuthorizationSetBuilder().EcbMode().Padding(PaddingMode::NONE); + + AuthorizationSet hardware_auths = HwEnforcedAuthorizations(key_characteristics_); + AuthorizationSet keystore_auths = + SecLevelAuthorizations(key_characteristics_, SecurityLevel::KEYSTORE); + + // First usage of AES key should work. + EncryptMessage(message, params); + + if (hardware_auths.Contains(TAG_USAGE_COUNT_LIMIT, 1U)) { + // Usage count limit tag is enforced by hardware. After using the key, the key blob + // must be invalidated from secure storage (such as RPMB partition). + EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB, Begin(KeyPurpose::ENCRYPT, params)); + } else { + // Usage count limit tag is enforced by keystore, keymint does nothing. + EXPECT_TRUE(keystore_auths.Contains(TAG_USAGE_COUNT_LIMIT, 1U)); + EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params)); + } +} + +/* + * UsageCountLimitTest.TestLimitedUseAes + * + * Verifies that the usage count limit tag > 1 works correctly with AES keys. + */ +TEST_P(UsageCountLimitTest, TestLimitedUseAes) { + if (SecLevel() == SecurityLevel::STRONGBOX) return; + + ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() + .Authorization(TAG_NO_AUTH_REQUIRED) + .AesEncryptionKey(128) + .EcbMode() + .Padding(PaddingMode::NONE) + .Authorization(TAG_USAGE_COUNT_LIMIT, 3))); + + // Check the usage count limit tag appears in the authorizations. + AuthorizationSet auths; + for (auto& entry : key_characteristics_) { + auths.push_back(AuthorizationSet(entry.authorizations)); + } + EXPECT_TRUE(auths.Contains(TAG_USAGE_COUNT_LIMIT, 3U)) + << "key usage count limit " << 3U << " missing"; + + string message = "1234567890123456"; + auto params = AuthorizationSetBuilder().EcbMode().Padding(PaddingMode::NONE); + + AuthorizationSet hardware_auths = HwEnforcedAuthorizations(key_characteristics_); + AuthorizationSet keystore_auths = + SecLevelAuthorizations(key_characteristics_, SecurityLevel::KEYSTORE); + + EncryptMessage(message, params); + EncryptMessage(message, params); + EncryptMessage(message, params); + + if (hardware_auths.Contains(TAG_USAGE_COUNT_LIMIT, 3U)) { + // Usage count limit tag is enforced by hardware. After using the key, the key blob + // must be invalidated from secure storage (such as RPMB partition). + EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB, Begin(KeyPurpose::ENCRYPT, params)); + } else { + // Usage count limit tag is enforced by keystore, keymint does nothing. + EXPECT_TRUE(keystore_auths.Contains(TAG_USAGE_COUNT_LIMIT, 3U)); + EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params)); + } +} + +/* + * UsageCountLimitTest.TestSingleUseRsa + * + * Verifies that the usage count limit tag = 1 works correctly with RSA keys. + */ +TEST_P(UsageCountLimitTest, TestSingleUseRsa) { + if (SecLevel() == SecurityLevel::STRONGBOX) return; + + ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() + .Authorization(TAG_NO_AUTH_REQUIRED) + .RsaSigningKey(1024, 65537) + .NoDigestOrPadding() + .Authorization(TAG_USAGE_COUNT_LIMIT, 1))); + + // Check the usage count limit tag appears in the authorizations. + AuthorizationSet auths; + for (auto& entry : key_characteristics_) { + auths.push_back(AuthorizationSet(entry.authorizations)); + } + EXPECT_TRUE(auths.Contains(TAG_USAGE_COUNT_LIMIT, 1U)) + << "key usage count limit " << 1U << " missing"; + + string message = "1234567890123456"; + auto params = AuthorizationSetBuilder().NoDigestOrPadding(); + + AuthorizationSet hardware_auths = HwEnforcedAuthorizations(key_characteristics_); + AuthorizationSet keystore_auths = + SecLevelAuthorizations(key_characteristics_, SecurityLevel::KEYSTORE); + + // First usage of RSA key should work. + SignMessage(message, params); + + if (hardware_auths.Contains(TAG_USAGE_COUNT_LIMIT, 1U)) { + // Usage count limit tag is enforced by hardware. After using the key, the key blob + // must be invalidated from secure storage (such as RPMB partition). + EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB, Begin(KeyPurpose::SIGN, params)); + } else { + // Usage count limit tag is enforced by keystore, keymint does nothing. + EXPECT_TRUE(keystore_auths.Contains(TAG_USAGE_COUNT_LIMIT, 1U)); + EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::SIGN, params)); + } +} + +/* + * UsageCountLimitTest.TestLimitUseRsa + * + * Verifies that the usage count limit tag > 1 works correctly with RSA keys. + */ +TEST_P(UsageCountLimitTest, TestLimitUseRsa) { + if (SecLevel() == SecurityLevel::STRONGBOX) return; + + ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() + .Authorization(TAG_NO_AUTH_REQUIRED) + .RsaSigningKey(1024, 65537) + .NoDigestOrPadding() + .Authorization(TAG_USAGE_COUNT_LIMIT, 3))); + + // Check the usage count limit tag appears in the authorizations. + AuthorizationSet auths; + for (auto& entry : key_characteristics_) { + auths.push_back(AuthorizationSet(entry.authorizations)); + } + EXPECT_TRUE(auths.Contains(TAG_USAGE_COUNT_LIMIT, 3U)) + << "key usage count limit " << 3U << " missing"; + + string message = "1234567890123456"; + auto params = AuthorizationSetBuilder().NoDigestOrPadding(); + + AuthorizationSet hardware_auths = HwEnforcedAuthorizations(key_characteristics_); + AuthorizationSet keystore_auths = + SecLevelAuthorizations(key_characteristics_, SecurityLevel::KEYSTORE); + + SignMessage(message, params); + SignMessage(message, params); + SignMessage(message, params); + + if (hardware_auths.Contains(TAG_USAGE_COUNT_LIMIT, 3U)) { + // Usage count limit tag is enforced by hardware. After using the key, the key blob + // must be invalidated from secure storage (such as RPMB partition). + EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB, Begin(KeyPurpose::SIGN, params)); + } else { + // Usage count limit tag is enforced by keystore, keymint does nothing. + EXPECT_TRUE(keystore_auths.Contains(TAG_USAGE_COUNT_LIMIT, 3U)); + EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::SIGN, params)); + } +} + +INSTANTIATE_KEYMINT_AIDL_TEST(UsageCountLimitTest); + typedef KeyMintAidlTestBase AddEntropyTest; /* @@ -4424,6 +4775,121 @@ TEST_P(TransportLimitTest, LargeFinishInput) { INSTANTIATE_KEYMINT_AIDL_TEST(TransportLimitTest); +typedef KeyMintAidlTestBase KeyAgreementTest; + +int CurveToOpenSslCurveName(EcCurve curve) { + switch (curve) { + case EcCurve::P_224: + return NID_secp224r1; + case EcCurve::P_256: + return NID_X9_62_prime256v1; + case EcCurve::P_384: + return NID_secp384r1; + case EcCurve::P_521: + return NID_secp521r1; + } +} + +/* + * KeyAgreementTest.Ecdh + * + * Verifies that ECDH works for all curves + */ +TEST_P(KeyAgreementTest, Ecdh) { + // Because it's possible to use this API with keys on different curves, we + // check all N^2 combinations where N is the number of supported + // curves. + // + // This is not a big deal as N is 4 so we only do 16 runs. If we end up with a + // lot more curves we can be smart about things and just pick |otherCurve| so + // it's not |curve| and that way we end up with only 2*N runs + // + for (auto curve : ValidCurves()) { + for (auto localCurve : ValidCurves()) { + // Generate EC key locally (with access to private key material) + auto ecKey = EC_KEY_Ptr(EC_KEY_new()); + int curveName = CurveToOpenSslCurveName(localCurve); + auto group = EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(curveName)); + ASSERT_NE(group, nullptr); + ASSERT_EQ(EC_KEY_set_group(ecKey.get(), group.get()), 1); + ASSERT_EQ(EC_KEY_generate_key(ecKey.get()), 1); + auto pkey = EVP_PKEY_Ptr(EVP_PKEY_new()); + ASSERT_EQ(EVP_PKEY_set1_EC_KEY(pkey.get(), ecKey.get()), 1); + + // Get encoded form of the public part of the locally generated key... + unsigned char* p = nullptr; + int encodedPublicKeySize = i2d_PUBKEY(pkey.get(), &p); + ASSERT_GT(encodedPublicKeySize, 0); + vector<uint8_t> encodedPublicKey( + reinterpret_cast<const uint8_t*>(p), + reinterpret_cast<const uint8_t*>(p + encodedPublicKeySize)); + OPENSSL_free(p); + + // Generate EC key in KeyMint (only access to public key material) + vector<uint8_t> challenge = {0x41, 0x42}; + EXPECT_EQ( + ErrorCode::OK, + GenerateKey(AuthorizationSetBuilder() + .Authorization(TAG_NO_AUTH_REQUIRED) + .Authorization(TAG_EC_CURVE, curve) + .Authorization(TAG_PURPOSE, KeyPurpose::AGREE_KEY) + .Authorization(TAG_ALGORITHM, Algorithm::EC) + .Authorization(TAG_ATTESTATION_APPLICATION_ID, {0x61, 0x62}) + .Authorization(TAG_ATTESTATION_CHALLENGE, challenge))) + << "Failed to generate key"; + ASSERT_GT(cert_chain_.size(), 0); + X509_Ptr kmKeyCert(parse_cert_blob(cert_chain_[0].encodedCertificate)); + ASSERT_NE(kmKeyCert, nullptr); + // Check that keyAgreement (bit 4) is set in KeyUsage + EXPECT_TRUE((X509_get_key_usage(kmKeyCert.get()) & X509v3_KU_KEY_AGREEMENT) != 0); + auto kmPkey = EVP_PKEY_Ptr(X509_get_pubkey(kmKeyCert.get())); + ASSERT_NE(kmPkey, nullptr); + if (dump_Attestations) { + for (size_t n = 0; n < cert_chain_.size(); n++) { + std::cout << bin2hex(cert_chain_[n].encodedCertificate) << std::endl; + } + } + + // Now that we have the two keys, we ask KeyMint to perform ECDH... + if (curve != localCurve) { + // If the keys are using different curves KeyMint should fail with + // ErrorCode:INVALID_ARGUMENT. Check that. + EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::AGREE_KEY, AuthorizationSetBuilder())); + string ZabFromKeyMintStr; + EXPECT_EQ(ErrorCode::INVALID_ARGUMENT, + Finish(string(encodedPublicKey.begin(), encodedPublicKey.end()), + &ZabFromKeyMintStr)); + + } else { + // Otherwise if the keys are using the same curve, it should work. + EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::AGREE_KEY, AuthorizationSetBuilder())); + string ZabFromKeyMintStr; + EXPECT_EQ(ErrorCode::OK, + Finish(string(encodedPublicKey.begin(), encodedPublicKey.end()), + &ZabFromKeyMintStr)); + vector<uint8_t> ZabFromKeyMint(ZabFromKeyMintStr.begin(), ZabFromKeyMintStr.end()); + + // Perform local ECDH between the two keys so we can check if we get the same Zab.. + auto ctx = EVP_PKEY_CTX_Ptr(EVP_PKEY_CTX_new(pkey.get(), nullptr)); + ASSERT_NE(ctx, nullptr); + ASSERT_EQ(EVP_PKEY_derive_init(ctx.get()), 1); + ASSERT_EQ(EVP_PKEY_derive_set_peer(ctx.get(), kmPkey.get()), 1); + size_t ZabFromTestLen = 0; + ASSERT_EQ(EVP_PKEY_derive(ctx.get(), nullptr, &ZabFromTestLen), 1); + vector<uint8_t> ZabFromTest; + ZabFromTest.resize(ZabFromTestLen); + ASSERT_EQ(EVP_PKEY_derive(ctx.get(), ZabFromTest.data(), &ZabFromTestLen), 1); + + EXPECT_EQ(ZabFromKeyMint, ZabFromTest); + } + + CheckedDeleteKey(); + } + } +} + +INSTANTIATE_KEYMINT_AIDL_TEST(KeyAgreementTest); + } // namespace aidl::android::hardware::security::keymint::test int main(int argc, char** argv) { diff --git a/security/keymint/support/Android.bp b/security/keymint/support/Android.bp index 0cfa798344..fde6b57683 100644 --- a/security/keymint/support/Android.bp +++ b/security/keymint/support/Android.bp @@ -31,7 +31,7 @@ cc_library { "include", ], shared_libs: [ - "android.hardware.security.keymint-unstable-ndk_platform", + "android.hardware.security.keymint-V1-ndk_platform", "libbase", "libcrypto", "libutils", diff --git a/security/keymint/support/attestation_record.cpp b/security/keymint/support/attestation_record.cpp index 596b097bed..a48f770700 100644 --- a/security/keymint/support/attestation_record.cpp +++ b/security/keymint/support/attestation_record.cpp @@ -97,6 +97,7 @@ typedef struct km_auth_list { ASN1_NULL* device_unique_attestation; ASN1_NULL* storage_key; ASN1_NULL* identity_credential; + ASN1_INTEGER* usage_count_limit; } KM_AUTH_LIST; ASN1_SEQUENCE(KM_AUTH_LIST) = { @@ -143,7 +144,8 @@ ASN1_SEQUENCE(KM_AUTH_LIST) = { ASN1_EXP_OPT(KM_AUTH_LIST, storage_key, ASN1_NULL, TAG_STORAGE_KEY.maskedTag()), ASN1_EXP_OPT(KM_AUTH_LIST, identity_credential, ASN1_NULL, TAG_IDENTITY_CREDENTIAL_KEY.maskedTag()), - + ASN1_EXP_OPT(KM_AUTH_LIST, usage_count_limit, ASN1_INTEGER, + TAG_USAGE_COUNT_LIMIT.maskedTag()), } ASN1_SEQUENCE_END(KM_AUTH_LIST); IMPLEMENT_ASN1_FUNCTIONS(KM_AUTH_LIST); @@ -285,6 +287,7 @@ static ErrorCode extract_auth_list(const KM_AUTH_LIST* record, AuthorizationSet* copyAuthTag(record->device_unique_attestation, TAG_DEVICE_UNIQUE_ATTESTATION, auth_list); copyAuthTag(record->storage_key, TAG_STORAGE_KEY, auth_list); copyAuthTag(record->identity_credential, TAG_IDENTITY_CREDENTIAL_KEY, auth_list); + copyAuthTag(record->usage_count_limit, TAG_USAGE_COUNT_LIMIT, auth_list); return ErrorCode::OK; } diff --git a/security/keymint/support/include/keymint_support/keymint_tags.h b/security/keymint/support/include/keymint_support/keymint_tags.h index 76aecb71b5..43cfb63a2f 100644 --- a/security/keymint/support/include/keymint_support/keymint_tags.h +++ b/security/keymint/support/include/keymint_support/keymint_tags.h @@ -119,6 +119,7 @@ DECLARE_TYPED_TAG(TRUSTED_CONFIRMATION_REQUIRED); DECLARE_TYPED_TAG(TRUSTED_USER_PRESENCE_REQUIRED); DECLARE_TYPED_TAG(UNIQUE_ID); DECLARE_TYPED_TAG(UNLOCKED_DEVICE_REQUIRED); +DECLARE_TYPED_TAG(USAGE_COUNT_LIMIT); DECLARE_TYPED_TAG(USAGE_EXPIRE_DATETIME); DECLARE_TYPED_TAG(USER_AUTH_TYPE); DECLARE_TYPED_TAG(USER_ID); @@ -135,15 +136,15 @@ using all_tags_t = MetaList< TAG_INVALID_t, TAG_KEY_SIZE_t, TAG_MAC_LENGTH_t, TAG_CALLER_NONCE_t, TAG_MIN_MAC_LENGTH_t, TAG_RSA_PUBLIC_EXPONENT_t, TAG_INCLUDE_UNIQUE_ID_t, TAG_ACTIVE_DATETIME_t, TAG_ORIGINATION_EXPIRE_DATETIME_t, TAG_USAGE_EXPIRE_DATETIME_t, - TAG_MIN_SECONDS_BETWEEN_OPS_t, TAG_MAX_USES_PER_BOOT_t, TAG_USER_ID_t, TAG_USER_SECURE_ID_t, - TAG_NO_AUTH_REQUIRED_t, TAG_AUTH_TIMEOUT_t, TAG_ALLOW_WHILE_ON_BODY_t, - TAG_UNLOCKED_DEVICE_REQUIRED_t, TAG_APPLICATION_ID_t, TAG_APPLICATION_DATA_t, - TAG_CREATION_DATETIME_t, TAG_ROLLBACK_RESISTANCE_t, TAG_HARDWARE_TYPE_t, - TAG_ROOT_OF_TRUST_t, TAG_ASSOCIATED_DATA_t, TAG_NONCE_t, TAG_BOOTLOADER_ONLY_t, - TAG_OS_VERSION_t, TAG_OS_PATCHLEVEL_t, TAG_UNIQUE_ID_t, TAG_ATTESTATION_CHALLENGE_t, - TAG_ATTESTATION_APPLICATION_ID_t, TAG_ATTESTATION_ID_BRAND_t, TAG_ATTESTATION_ID_DEVICE_t, - TAG_ATTESTATION_ID_PRODUCT_t, TAG_ATTESTATION_ID_MANUFACTURER_t, TAG_ATTESTATION_ID_MODEL_t, - TAG_ATTESTATION_ID_SERIAL_t, TAG_ATTESTATION_ID_IMEI_t, TAG_ATTESTATION_ID_MEID_t, + TAG_MIN_SECONDS_BETWEEN_OPS_t, TAG_MAX_USES_PER_BOOT_t, TAG_USAGE_COUNT_LIMIT_t, + TAG_USER_ID_t, TAG_USER_SECURE_ID_t, TAG_NO_AUTH_REQUIRED_t, TAG_AUTH_TIMEOUT_t, + TAG_ALLOW_WHILE_ON_BODY_t, TAG_UNLOCKED_DEVICE_REQUIRED_t, TAG_APPLICATION_ID_t, + TAG_APPLICATION_DATA_t, TAG_CREATION_DATETIME_t, TAG_ROLLBACK_RESISTANCE_t, + TAG_HARDWARE_TYPE_t, TAG_ROOT_OF_TRUST_t, TAG_ASSOCIATED_DATA_t, TAG_NONCE_t, + TAG_BOOTLOADER_ONLY_t, TAG_OS_VERSION_t, TAG_OS_PATCHLEVEL_t, TAG_UNIQUE_ID_t, + TAG_ATTESTATION_CHALLENGE_t, TAG_ATTESTATION_APPLICATION_ID_t, TAG_ATTESTATION_ID_BRAND_t, + TAG_ATTESTATION_ID_DEVICE_t, TAG_ATTESTATION_ID_PRODUCT_t, + TAG_ATTESTATION_ID_MANUFACTURER_t, TAG_ATTESTATION_ID_MODEL_t, TAG_RESET_SINCE_ID_ROTATION_t, TAG_PURPOSE_t, TAG_ALGORITHM_t, TAG_BLOCK_MODE_t, TAG_DIGEST_t, TAG_PADDING_t, TAG_ORIGIN_t, TAG_USER_AUTH_TYPE_t, TAG_EC_CURVE_t, TAG_BOOT_PATCHLEVEL_t, TAG_VENDOR_PATCHLEVEL_t, TAG_TRUSTED_CONFIRMATION_REQUIRED_t, @@ -325,7 +326,9 @@ template <TagType tag_type, Tag tag> inline std::optional< std::reference_wrapper<const typename TypedTag2ValueType<TypedTag<tag_type, tag>>::type>> authorizationValue(TypedTag<tag_type, tag> ttag, const KeyParameter& param) { - if (TypedTag2ValueType<TypedTag<tag_type, tag>>::unionTag != param.value.getTag()) return {}; + // We only check if the parameter has the correct tag here; accessTagValue checks if the correct + // union field was initialized. + if (tag != param.tag) return {}; return accessTagValue(ttag, param); } diff --git a/security/keymint/support/include/keymint_support/openssl_utils.h b/security/keymint/support/include/keymint_support/openssl_utils.h index 9ae7e52383..c3bc60b051 100644 --- a/security/keymint/support/include/keymint_support/openssl_utils.h +++ b/security/keymint/support/include/keymint_support/openssl_utils.h @@ -34,7 +34,10 @@ typedef UniquePtrDeleter<EVP_PKEY, EVP_PKEY_free> EVP_PKEY_Delete; typedef std::unique_ptr<type, UniquePtrDeleter<type, type##_free>> type##_Ptr; MAKE_OPENSSL_PTR_TYPE(ASN1_OBJECT) +MAKE_OPENSSL_PTR_TYPE(EC_KEY) +MAKE_OPENSSL_PTR_TYPE(EC_GROUP) MAKE_OPENSSL_PTR_TYPE(EVP_PKEY) +MAKE_OPENSSL_PTR_TYPE(EVP_PKEY_CTX) MAKE_OPENSSL_PTR_TYPE(RSA) MAKE_OPENSSL_PTR_TYPE(X509) MAKE_OPENSSL_PTR_TYPE(BN_CTX) diff --git a/security/secureclock/aidl/OWNERS b/security/secureclock/aidl/OWNERS new file mode 100644 index 0000000000..a93b171b00 --- /dev/null +++ b/security/secureclock/aidl/OWNERS @@ -0,0 +1,4 @@ +jbires@google.com +jdanis@google.com +seleneh@google.com +swillden@google.com diff --git a/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/TimeStampToken.aidl b/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/TimeStampToken.aidl index 51b1824da1..21eeb74519 100644 --- a/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/TimeStampToken.aidl +++ b/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/TimeStampToken.aidl @@ -17,7 +17,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.security.secureclock; -@VintfStability +@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability parcelable TimeStampToken { long challenge; android.hardware.security.secureclock.Timestamp timestamp; diff --git a/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/Timestamp.aidl b/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/Timestamp.aidl index 50b8b9ff13..f01fdc74c0 100644 --- a/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/Timestamp.aidl +++ b/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/Timestamp.aidl @@ -17,7 +17,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.security.secureclock; -@VintfStability +@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability parcelable Timestamp { long milliSeconds; } diff --git a/security/secureclock/aidl/android/hardware/security/secureclock/TimeStampToken.aidl b/security/secureclock/aidl/android/hardware/security/secureclock/TimeStampToken.aidl index b24d3355e5..3fb586078a 100644 --- a/security/secureclock/aidl/android/hardware/security/secureclock/TimeStampToken.aidl +++ b/security/secureclock/aidl/android/hardware/security/secureclock/TimeStampToken.aidl @@ -23,6 +23,7 @@ import android.hardware.security.secureclock.Timestamp; */ @VintfStability +@RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true) parcelable TimeStampToken { /** * The challenge that was provided as argument to ISecureClock.generateTimeStamp by the client. diff --git a/security/secureclock/aidl/android/hardware/security/secureclock/Timestamp.aidl b/security/secureclock/aidl/android/hardware/security/secureclock/Timestamp.aidl index 7bd1f9eab1..27758e1d25 100644 --- a/security/secureclock/aidl/android/hardware/security/secureclock/Timestamp.aidl +++ b/security/secureclock/aidl/android/hardware/security/secureclock/Timestamp.aidl @@ -23,6 +23,7 @@ package android.hardware.security.secureclock; * by setting the clock to zero during each boot, and then counting time accurately). */ @VintfStability +@RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true) parcelable Timestamp { long milliSeconds; } diff --git a/security/sharedsecret/aidl/OWNERS b/security/sharedsecret/aidl/OWNERS new file mode 100644 index 0000000000..a93b171b00 --- /dev/null +++ b/security/sharedsecret/aidl/OWNERS @@ -0,0 +1,4 @@ +jbires@google.com +jdanis@google.com +seleneh@google.com +swillden@google.com diff --git a/sensors/common/default/2.X/Sensor.cpp b/sensors/common/default/2.X/Sensor.cpp index 642fc89145..1a7c62853f 100644 --- a/sensors/common/default/2.X/Sensor.cpp +++ b/sensors/common/default/2.X/Sensor.cpp @@ -313,7 +313,7 @@ GyroSensor::GyroSensor(int32_t sensorHandle, ISensorsEventCallback* callback) : mSensorInfo.maxRange = 1000.0f * M_PI / 180.0f; mSensorInfo.resolution = 1000.0f * M_PI / (180.0f * 32768.0f); mSensorInfo.power = 0.001f; - mSensorInfo.minDelay = 2.5f * 1000; // microseconds + mSensorInfo.minDelay = 10 * 1000; // microseconds mSensorInfo.maxDelay = kDefaultMaxDelayUs; mSensorInfo.fifoReservedEventCount = 0; mSensorInfo.fifoMaxEventCount = 0; diff --git a/tests/extension/vibrator/aidl/client/Android.bp b/tests/extension/vibrator/aidl/client/Android.bp index b0d82382fa..108d000970 100644 --- a/tests/extension/vibrator/aidl/client/Android.bp +++ b/tests/extension/vibrator/aidl/client/Android.bp @@ -14,11 +14,11 @@ cc_test { shared_libs: [ "libbinder", "libutils", - "android.hardware.vibrator-cpp", - "android.hardware.tests.extension.vibrator-cpp", + "android.hardware.vibrator-V1-cpp", + "android.hardware.tests.extension.vibrator-V1-cpp", "libbinder_ndk", - "android.hardware.vibrator-ndk_platform", - "android.hardware.tests.extension.vibrator-ndk_platform", + "android.hardware.vibrator-V1-ndk_platform", + "android.hardware.tests.extension.vibrator-V1-ndk_platform", ], } diff --git a/tests/extension/vibrator/aidl/default/Android.bp b/tests/extension/vibrator/aidl/default/Android.bp index 80f7727646..2486588225 100644 --- a/tests/extension/vibrator/aidl/default/Android.bp +++ b/tests/extension/vibrator/aidl/default/Android.bp @@ -19,7 +19,7 @@ cc_binary { shared_libs: [ "libbase", "libbinder_ndk", - "android.hardware.vibrator-unstable-ndk_platform", - "android.hardware.tests.extension.vibrator-unstable-ndk_platform", + "android.hardware.vibrator-V2-ndk_platform", + "android.hardware.tests.extension.vibrator-V2-ndk_platform", ], } diff --git a/tests/lazy/1.1/ILazy.hal b/tests/lazy/1.1/ILazy.hal index b0a6a2aa09..eb48fd336a 100644 --- a/tests/lazy/1.1/ILazy.hal +++ b/tests/lazy/1.1/ILazy.hal @@ -20,10 +20,10 @@ import android.hardware.tests.lazy@1.0; interface ILazy extends @1.0::ILazy { /** - * Ask the process hosting the service to install a callback that notifies - * it when the number of active (i.e. with clients) services changes. + * Ask the process hosting the service to install a callback that notifies if there are + * services with clients. * For testing purposes, this callback exercises the code to unregister/re-register * the services and eventually shuts down the process. */ - setCustomActiveServicesCountCallback(); + setCustomActiveServicesCallback(); }; diff --git a/tests/msgq/1.0/ITestMsgQ.hal b/tests/msgq/1.0/ITestMsgQ.hal index bd10237c90..0cf9c7c71e 100644 --- a/tests/msgq/1.0/ITestMsgQ.hal +++ b/tests/msgq/1.0/ITestMsgQ.hal @@ -41,12 +41,15 @@ interface ITestMsgQ { * * @param configureFmq The server sets up a new unsynchronized FMQ if * this parameter is true. + * @param userFd True to initialize the message queue with a user supplied + * file descriptor for the ring buffer. + * False to let the message queue use a single FD for everything. * * @return ret True if successful. * @return mqDesc This structure describes the unsynchronized FMQ that was * set up by the service. Client can use it to set up the FMQ at its end. */ - getFmqUnsyncWrite(bool configureFmq) generates(bool ret, fmq_unsync<int32_t> mqDesc); + getFmqUnsyncWrite(bool configureFmq, bool userFd) generates(bool ret, fmq_unsync<int32_t> mqDesc); /** * This method request the service to write into the synchronized read/write diff --git a/tests/msgq/1.0/default/Android.bp b/tests/msgq/1.0/default/Android.bp index 6e7cd4478b..a0d6f31fd9 100644 --- a/tests/msgq/1.0/default/Android.bp +++ b/tests/msgq/1.0/default/Android.bp @@ -91,9 +91,10 @@ cc_test { // These are static libs only for testing purposes and portability. Shared // libs should be used on device. static_libs: [ + "android.hardware.common-V2-ndk_platform", + "android.hardware.common.fmq-V1-ndk_platform", "android.hardware.tests.msgq@1.0", "android.fmq.test-ndk_platform", - "android.hardware.common.fmq-unstable-ndk_platform", ], whole_static_libs: [ "android.hardware.tests.msgq@1.0-impl", diff --git a/tests/msgq/1.0/default/TestMsgQ.cpp b/tests/msgq/1.0/default/TestMsgQ.cpp index 44737378b3..4726ffe5e9 100644 --- a/tests/msgq/1.0/default/TestMsgQ.cpp +++ b/tests/msgq/1.0/default/TestMsgQ.cpp @@ -41,10 +41,19 @@ Return<bool> TestMsgQ::configureFmqSyncReadWrite( return true; } -Return<void> TestMsgQ::getFmqUnsyncWrite(bool configureFmq, getFmqUnsyncWrite_cb _hidl_cb) { +Return<void> TestMsgQ::getFmqUnsyncWrite(bool configureFmq, bool userFd, + getFmqUnsyncWrite_cb _hidl_cb) { if (configureFmq) { static constexpr size_t kNumElementsInQueue = 1024; - mFmqUnsynchronized.reset(new (std::nothrow) MessageQueueUnsync(kNumElementsInQueue)); + static constexpr size_t kElementSizeBytes = sizeof(int32_t); + android::base::unique_fd ringbufferFd; + if (userFd) { + ringbufferFd.reset( + ::ashmem_create_region("UnsyncWrite", kNumElementsInQueue * kElementSizeBytes)); + } + mFmqUnsynchronized.reset(new (std::nothrow) MessageQueueUnsync( + kNumElementsInQueue, false, std::move(ringbufferFd), + kNumElementsInQueue * kElementSizeBytes)); } if ((mFmqUnsynchronized == nullptr) || (mFmqUnsynchronized->isValid() == false)) { diff --git a/tests/msgq/1.0/default/TestMsgQ.h b/tests/msgq/1.0/default/TestMsgQ.h index 8a204b725d..49675fe306 100644 --- a/tests/msgq/1.0/default/TestMsgQ.h +++ b/tests/msgq/1.0/default/TestMsgQ.h @@ -56,7 +56,8 @@ struct TestMsgQ : public ITestMsgQ { // Methods from ::android::hardware::tests::msgq::V1_0::ITestMsgQ follow. Return<bool> configureFmqSyncReadWrite(const MQDescriptorSync<int32_t>& mqDesc) override; - Return<void> getFmqUnsyncWrite(bool configureFmq, getFmqUnsyncWrite_cb _hidl_cb) override; + Return<void> getFmqUnsyncWrite(bool configureFmq, bool userFd, + getFmqUnsyncWrite_cb _hidl_cb) override; Return<bool> requestWriteFmqSync(int32_t count) override; Return<bool> requestReadFmqSync(int32_t count) override; Return<bool> requestWriteFmqUnsync(int32_t count) override; diff --git a/tetheroffload/control/1.0/vts/functional/Android.bp b/tetheroffload/control/1.0/vts/functional/Android.bp index c397df4fa8..ddf382626f 100644 --- a/tetheroffload/control/1.0/vts/functional/Android.bp +++ b/tetheroffload/control/1.0/vts/functional/Android.bp @@ -30,3 +30,17 @@ cc_test { "vts", ], } + +cc_test_library { + name: "VtsHalTetheroffloadControlV1_0TargetTest-lib", + defaults: ["VtsHalTargetTestDefaults"], + export_include_dirs: ["include"], + static_libs: [ + "android.hardware.tetheroffload.config@1.0", + "android.hardware.tetheroffload.control@1.0", + ], + srcs: [ + "OffloadControlTestBase.cpp", + "OffloadControlTestUtils.cpp", + ], +} diff --git a/tetheroffload/control/1.0/vts/functional/OffloadControlTestBase.cpp b/tetheroffload/control/1.0/vts/functional/OffloadControlTestBase.cpp index bd0dad7a64..e392e9604f 100644 --- a/tetheroffload/control/1.0/vts/functional/OffloadControlTestBase.cpp +++ b/tetheroffload/control/1.0/vts/functional/OffloadControlTestBase.cpp @@ -53,29 +53,6 @@ void OffloadControlTestBase::setupConfigHal() { ASSERT_TRUE(ret.isOk()); } -void OffloadControlTestBase::prepareControlHal() { - control = createControl(std::get<1>(GetParam())); - ASSERT_NE(nullptr, control.get()) << "Could not get HIDL instance"; - - control_cb = new TetheringOffloadCallback(); - ASSERT_NE(nullptr, control_cb.get()) << "Could not get get offload callback"; -} - -void OffloadControlTestBase::initOffload(const bool expected_result) { - auto init_cb = [&](bool success, std::string errMsg) { - std::string msg = StringPrintf("Unexpectedly %s to init offload: %s", - success ? "succeeded" : "failed", errMsg.c_str()); - ASSERT_EQ(expected_result, success) << msg; - }; - const Return<void> ret = control->initOffload(control_cb, init_cb); - ASSERT_TRUE(ret.isOk()); -} - -void OffloadControlTestBase::setupControlHal() { - prepareControlHal(); - initOffload(true); -} - void OffloadControlTestBase::stopOffload(const ExpectBoolean value) { auto cb = [&](bool success, const hidl_string& errMsg) { switch (value) { diff --git a/tetheroffload/control/1.0/vts/functional/include/OffloadControlTestBase.h b/tetheroffload/control/1.0/vts/functional/include/OffloadControlTestBase.h index 004019a8e6..994c808930 100644 --- a/tetheroffload/control/1.0/vts/functional/include/OffloadControlTestBase.h +++ b/tetheroffload/control/1.0/vts/functional/include/OffloadControlTestBase.h @@ -36,7 +36,6 @@ using android::hardware::hidl_vec; using android::hardware::Return; using android::hardware::Void; using android::hardware::tetheroffload::config::V1_0::IOffloadConfig; -using android::hardware::tetheroffload::control::V1_0::IOffloadControl; using android::hardware::tetheroffload::control::V1_0::ITetheringOffloadCallback; using android::hardware::tetheroffload::control::V1_0::NatTimeoutUpdate; using android::hardware::tetheroffload::control::V1_0::OffloadCallbackEvent; @@ -64,17 +63,21 @@ class OffloadControlTestBase : public testing::TestWithParam<std::tuple<std::str // Called once in setup stage to retrieve correct version of // IOffloadControl object. - virtual sp<IOffloadControl> createControl(const std::string& serviceName) = 0; + virtual sp<android::hardware::tetheroffload::control::V1_0::IOffloadControl> createControl( + const std::string& serviceName) = 0; // The IOffloadConfig HAL is tested more thoroughly elsewhere. Here the // class just setup everything correctly and verify basic readiness. void setupConfigHal(); - void prepareControlHal(); + virtual void prepareControlHal() = 0; - void initOffload(const bool expected_result); + virtual void initOffload(const bool expected_result) = 0; - void setupControlHal(); + void setupControlHal() { + prepareControlHal(); + initOffload(true); + }; void stopOffload(const ExpectBoolean value); @@ -100,6 +103,6 @@ class OffloadControlTestBase : public testing::TestWithParam<std::tuple<std::str }; sp<IOffloadConfig> config; - sp<IOffloadControl> control; + sp<android::hardware::tetheroffload::control::V1_0::IOffloadControl> control; sp<TetheringOffloadCallback> control_cb; };
\ No newline at end of file diff --git a/tetheroffload/control/1.0/vts/functional/include/OffloadControlTestV1_0.h b/tetheroffload/control/1.0/vts/functional/include/OffloadControlTestV1_0.h index 7492f8af01..9189d713f9 100644 --- a/tetheroffload/control/1.0/vts/functional/include/OffloadControlTestV1_0.h +++ b/tetheroffload/control/1.0/vts/functional/include/OffloadControlTestV1_0.h @@ -26,8 +26,28 @@ class OffloadControlTestV1_0_HalNotStarted : public OffloadControlTestBase { prepareControlHal(); } - virtual sp<IOffloadControl> createControl(const std::string& serviceName) override { - return IOffloadControl::getService(serviceName); + virtual sp<android::hardware::tetheroffload::control::V1_0::IOffloadControl> createControl( + const std::string& serviceName) override { + return android::hardware::tetheroffload::control::V1_0::IOffloadControl::getService( + serviceName); + } + + virtual void prepareControlHal() override { + control = createControl(std::get<1>(GetParam())); + ASSERT_NE(nullptr, control.get()) << "Could not get HIDL instance"; + + control_cb = new TetheringOffloadCallback(); + ASSERT_NE(nullptr, control_cb.get()) << "Could not get get offload callback"; + } + + virtual void initOffload(const bool expected_result) override { + auto init_cb = [&](bool success, std::string errMsg) { + std::string msg = StringPrintf("Unexpectedly %s to init offload: %s", + success ? "succeeded" : "failed", errMsg.c_str()); + ASSERT_EQ(expected_result, success) << msg; + }; + const Return<void> ret = control->initOffload(control_cb, init_cb); + ASSERT_TRUE(ret.isOk()); } }; diff --git a/tv/cec/2.0/Android.bp b/tetheroffload/control/1.1/Android.bp index 5463b6da61..18c8ea97d1 100644 --- a/tv/cec/2.0/Android.bp +++ b/tetheroffload/control/1.1/Android.bp @@ -1,16 +1,16 @@ // This file is autogenerated by hidl-gen -Landroidbp. hidl_interface { - name: "android.hardware.tv.cec@2.0", + name: "android.hardware.tetheroffload.control@1.1", root: "android.hardware", srcs: [ "types.hal", - "IHdmiCec.hal", - "IHdmiCecCallback.hal", + "IOffloadControl.hal", + "ITetheringOffloadCallback.hal", ], interfaces: [ + "android.hardware.tetheroffload.control@1.0", "android.hidl.base@1.0", - "android.hidl.safe_union@1.0", ], gen_java: true, } diff --git a/tetheroffload/control/1.1/IOffloadControl.hal b/tetheroffload/control/1.1/IOffloadControl.hal new file mode 100644 index 0000000000..2eb54c81c8 --- /dev/null +++ b/tetheroffload/control/1.1/IOffloadControl.hal @@ -0,0 +1,80 @@ +/* + * 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.tetheroffload.control@1.1; + +import @1.0::IOffloadControl; + +/** + * Interface used to control the lifecycle of tethering offload. Note that callbacks of 1.1 HAL + * can be registered with the existing callback registration methods from 1.0 HAL. + */ +interface IOffloadControl extends @1.0::IOffloadControl { + /** + * Instruct hardware to send callbacks after certain number of bytes have been transferred in + * either direction on this upstream interface. + * + * The specified quota bytes must be applied to all traffic on the given upstream interface. + * This includes hardware forwarded traffic, software forwarded traffic, and AP-originated + * traffic. IPv4 and IPv6 traffic both count towards the same quota. IP headers are included + * in the byte count quota, but, link-layer headers are not. + * + * This API may only be called while offload is occurring on this upstream. The hardware + * management process MUST NOT store the values when offload is not started and applies once + * offload is started. This is because the quota values would likely become stale over + * time and would not reflect any new traffic that has occurred. + * + * This API replaces {@link @1.0::IOffloadControl::setDataLimit}, the framework will always + * call setDataWarningAndLimit on 1.1 implementations, and setDataLimit on 1.0 implementations. + * Thus, no interaction between the two APIs need to be addressed. + * + * The specified quota bytes MUST replace any previous quotas set by + * {@code setDataWarningAndLimit} specified on the same interface. It may be interpreted as + * "tell me when either <warningBytes> or <limitBytes> bytes have been transferred + * (in either direction), and stop offload when <limitBytes> bytes have been transferred, + * starting now and counting from zero on <upstream>." + * + * Once the {@code warningBytes} is reached, the callback registered in initOffload must be + * called with {@code OFFLOAD_WARNING_REACHED} to indicate this event. Once the event fires + * for this upstream, no further {@code OFFLOAD_WARNING_REACHED} event will be fired for this + * upstream unless this method is called again with the same interface. Note that there is + * no need to call initOffload again to resume offload if stopOffload was not called by the + * client. + * + * Similarly, Once the {@code limitBytes} is reached, the callback registered in initOffload + * must be called with {@code OFFLOAD_STOPPED_LIMIT_REACHED} to indicate this event. Once + * the event fires for this upstream, no further {@code OFFLOAD_STOPPED_LIMIT_REACHED} + * event will be fired for this upstream unless this method is called again with the same + * interface. However, unlike {@code warningBytes}, when {@code limitBytes} is reached, + * all offload must be stopped. If offload is desired again, the hardware management + * process must be completely reprogrammed by calling setUpstreamParameters and + * addDownstream again. + * + * Note that when one of the quota bytes is reached, the other one is still considered valid + * unless this method is called again with the same interface. + * + * @param upstream Upstream interface name that quota must apply to. + * @param warningBytes The quota of warning, defined as the number of bytes, starting from + * zero and counting from now. + * @param limitBytes The quota of limit, defined as the number of bytes, starting from zero + * and counting from now. + * + * @return success true if quota is applied, false otherwise + * @return errMsg a human readable string if error has occurred. + */ + setDataWarningAndLimit(string upstream, uint64_t warningBytes, uint64_t limitBytes) + generates (bool success, string errMsg); +}; diff --git a/tetheroffload/control/1.1/ITetheringOffloadCallback.hal b/tetheroffload/control/1.1/ITetheringOffloadCallback.hal new file mode 100644 index 0000000000..7a7d56d9d3 --- /dev/null +++ b/tetheroffload/control/1.1/ITetheringOffloadCallback.hal @@ -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.tetheroffload.control@1.1; + +import @1.0::ITetheringOffloadCallback; +import OffloadCallbackEvent; + +/** + * Callback providing information about status of hardware management process + * as well as providing a way to keep offloaded connections from timing out. + */ +interface ITetheringOffloadCallback extends @1.0::ITetheringOffloadCallback { + /** + * Called when an asynchronous event is generated by the hardware + * management process. Events which are common for 1.0 and 1.1 HAL + * MUST be fired on both 1.0 and 1.1 callback. + */ + oneway onEvent_1_1(OffloadCallbackEvent event); +}; diff --git a/gnss/3.0/IGnss.hal b/tetheroffload/control/1.1/types.hal index 18e5a9dee3..30e6af3e2a 100644 --- a/gnss/3.0/IGnss.hal +++ b/tetheroffload/control/1.1/types.hal @@ -14,19 +14,15 @@ * limitations under the License. */ -package android.hardware.gnss@3.0; +package android.hardware.tetheroffload.control@1.1; -import @2.1::IGnss; -import IGnssPsds; +import @1.0::OffloadCallbackEvent; -/** - * Represents the standard GNSS (Global Navigation Satellite System) interface. - */ -interface IGnss extends @2.1::IGnss { +enum OffloadCallbackEvent : @1.0::OffloadCallbackEvent { /** - * This method returns the IGnssPsds interface. - * - * @return psdsIface Handle to the IGnssPsds interface. + * This event is fired when the quota, applied in setDataWarning, has expired. It is + * recommended that the client query for statistics immediately after receiving this event. + * Note that hardware acceleration must not be stopped upon receiving this event. */ - getExtensionPsds() generates (IGnssPsds psdsIface); + OFFLOAD_WARNING_REACHED = 6, }; diff --git a/gnss/3.0/vts/functional/Android.bp b/tetheroffload/control/1.1/vts/functional/Android.bp index 584424ccc4..ab29350805 100644 --- a/gnss/3.0/vts/functional/Android.bp +++ b/tetheroffload/control/1.1/vts/functional/Android.bp @@ -1,4 +1,3 @@ -// // Copyright (C) 2020 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -12,25 +11,17 @@ // 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: "VtsHalGnssV3_0TargetTest", + name: "VtsHalTetheroffloadControlV1_1TargetTest", defaults: ["VtsHalTargetTestDefaults"], - srcs: [ - "gnss_hal_test_cases.cpp", - "VtsHalGnssV3_0TargetTest.cpp", - ], + srcs: ["VtsHalTetheroffloadControlV1_1TargetTest.cpp"], + local_include_dirs: ["include"], static_libs: [ - "android.hardware.gnss.measurement_corrections@1.0", - "android.hardware.gnss.measurement_corrections@1.1", - "android.hardware.gnss.visibility_control@1.0", - "android.hardware.gnss@1.0", - "android.hardware.gnss@1.1", - "android.hardware.gnss@2.0", - "android.hardware.gnss@2.1", - "android.hardware.gnss@3.0", - "android.hardware.gnss@common-vts-lib", + "android.hardware.tetheroffload.config@1.0", + "android.hardware.tetheroffload.control@1.0", + "android.hardware.tetheroffload.control@1.1", + "VtsHalTetheroffloadControlV1_0TargetTest-lib", ], test_suites: [ "general-tests", diff --git a/tetheroffload/control/1.1/vts/functional/VtsHalTetheroffloadControlV1_1TargetTest.cpp b/tetheroffload/control/1.1/vts/functional/VtsHalTetheroffloadControlV1_1TargetTest.cpp new file mode 100644 index 0000000000..b8c9e53121 --- /dev/null +++ b/tetheroffload/control/1.1/vts/functional/VtsHalTetheroffloadControlV1_1TargetTest.cpp @@ -0,0 +1,78 @@ +/* + * 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 <OffloadControlTestV1_1.h> +#include <gtest/gtest.h> +#include <hidl/GtestPrinter.h> +#include <hidl/ServiceManagement.h> + +using android::hardware::tetheroffload::control::V1_1::IOffloadControl; + +const hidl_string TEST_IFACE("rmnet_data0"); + +// Check that calling setDataWarningAndLimit() without first having called initOffload() returns +// false. +TEST_P(OffloadControlTestV1_1_HalNotStarted, SetDataWarningAndLimitWithoutInitReturnsFalse) { + const Return<void> ret = getControlV1_1()->setDataWarningAndLimit(TEST_IFACE, 5000ULL, 5000ULL, + ASSERT_FALSE_CALLBACK); + EXPECT_TRUE(ret.isOk()); +} + +/* + * Tests for IOffloadControl::setDataWarningAndLimit(). + */ + +// Test that setDataWarningAndLimit() for an empty interface name fails. +TEST_P(OffloadControlTestV1_1_HalStarted, SetDataWarningAndLimitEmptyUpstreamIfaceFails) { + const Return<void> ret = getControlV1_1()->setDataWarningAndLimit( + hidl_string(""), 12345ULL, 67890ULL, ASSERT_FALSE_CALLBACK); + EXPECT_TRUE(ret.isOk()); +} + +// TEST_IFACE is presumed to exist on the device and be up. No packets +// are ever actually caused to be forwarded. +TEST_P(OffloadControlTestV1_1_HalStarted, SetDataWarningAndLimitNonZeroOk) { + const Return<void> ret = getControlV1_1()->setDataWarningAndLimit(TEST_IFACE, 4000ULL, 5000ULL, + ASSERT_TRUE_CALLBACK); + EXPECT_TRUE(ret.isOk()); +} + +// TEST_IFACE is presumed to exist on the device and be up. No packets +// are ever actually caused to be forwarded. +TEST_P(OffloadControlTestV1_1_HalStarted, SetDataWarningAndLimitZeroOk) { + const Return<void> ret = + getControlV1_1()->setDataWarningAndLimit(TEST_IFACE, 0ULL, 0ULL, ASSERT_TRUE_CALLBACK); + EXPECT_TRUE(ret.isOk()); +} + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(OffloadControlTestV1_1_HalNotStarted); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(OffloadControlTestV1_1_HalStarted); + +INSTANTIATE_TEST_CASE_P( + PerInstance, OffloadControlTestV1_1_HalNotStarted, + testing::Combine(testing::ValuesIn(android::hardware::getAllHalInstanceNames( + IOffloadConfig::descriptor)), + testing::ValuesIn(android::hardware::getAllHalInstanceNames( + IOffloadControl::descriptor))), + android::hardware::PrintInstanceTupleNameToString<>); + +INSTANTIATE_TEST_CASE_P( + PerInstance, OffloadControlTestV1_1_HalStarted, + testing::Combine(testing::ValuesIn(android::hardware::getAllHalInstanceNames( + IOffloadConfig::descriptor)), + testing::ValuesIn(android::hardware::getAllHalInstanceNames( + IOffloadControl::descriptor))), + android::hardware::PrintInstanceTupleNameToString<>); diff --git a/tetheroffload/control/1.1/vts/functional/include/OffloadControlTestV1_1.h b/tetheroffload/control/1.1/vts/functional/include/OffloadControlTestV1_1.h new file mode 100644 index 0000000000..a3bc1b41c5 --- /dev/null +++ b/tetheroffload/control/1.1/vts/functional/include/OffloadControlTestV1_1.h @@ -0,0 +1,99 @@ +/* + * 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 <OffloadControlTestV1_0.h> +#include <android/hardware/tetheroffload/control/1.1/IOffloadControl.h> +#include <android/hardware/tetheroffload/control/1.1/ITetheringOffloadCallback.h> +#include <gtest/gtest.h> + +constexpr char kCallbackOnEvent_1_1[] = "onEvent_1_1"; + +class TetheringOffloadCallbackArgsV1_1 { + public: + android::hardware::tetheroffload::control::V1_1::OffloadCallbackEvent last_event; +}; + +class OffloadControlTestV1_1_HalNotStarted : public OffloadControlTestV1_0_HalNotStarted { + public: + virtual sp<android::hardware::tetheroffload::control::V1_0::IOffloadControl> createControl( + const std::string& serviceName) override { + return android::hardware::tetheroffload::control::V1_1::IOffloadControl::getService( + serviceName); + }; + + void prepareControlHal() override { + control = createControl(std::get<1>(GetParam())); + ASSERT_NE(nullptr, control.get()) << "Could not get HIDL instance"; + + control_cb_1_1 = new TetheringOffloadCallbackV1_1(); + ASSERT_NE(nullptr, control_cb_1_1.get()) << "Could not get offload callback"; + }; + + void initOffload(const bool expected_result) override { + auto init_cb = [&](bool success, std::string errMsg) { + std::string msg = StringPrintf("Unexpectedly %s to init offload: %s", + success ? "succeeded" : "failed", errMsg.c_str()); + ASSERT_EQ(expected_result, success) << msg; + }; + auto control = getControlV1_1(); + ASSERT_NE(control, nullptr); + const Return<void> ret = control->initOffload(control_cb_1_1, init_cb); + ASSERT_TRUE(ret.isOk()); + }; + + sp<android::hardware::tetheroffload::control::V1_1::IOffloadControl> getControlV1_1() { + // The cast is safe since only devices with V1.1+ HAL will be enumerated and pass in to the + // test. + return android::hardware::tetheroffload::control::V1_1::IOffloadControl::castFrom(control) + .withDefault(nullptr); + }; + + // Callback class for both new events. + class TetheringOffloadCallbackV1_1 + : public testing::VtsHalHidlTargetCallbackBase<TetheringOffloadCallbackArgsV1_1>, + public android::hardware::tetheroffload::control::V1_1::ITetheringOffloadCallback { + public: + Return<void> onEvent_1_1( + android::hardware::tetheroffload::control::V1_1::OffloadCallbackEvent event) + override { + const TetheringOffloadCallbackArgsV1_1 args{.last_event = event}; + NotifyFromCallback(kCallbackOnEvent_1_1, args); + return Void(); + }; + + Return<void> onEvent([[maybe_unused]] OffloadCallbackEvent event) override { + // Tested only in IOffloadControl 1.0. + return Void(); + }; + + Return<void> updateTimeout([[maybe_unused]] const NatTimeoutUpdate& params) override { + // Tested only in IOffloadControl 1.0. + return Void(); + }; + }; + + sp<TetheringOffloadCallbackV1_1> control_cb_1_1; +}; + +class OffloadControlTestV1_1_HalStarted : public OffloadControlTestV1_1_HalNotStarted { + public: + virtual void SetUp() override { + setupConfigHal(); + setupControlHal(); + } +};
\ No newline at end of file diff --git a/tv/cec/2.0/IHdmiCec.hal b/tv/cec/2.0/IHdmiCec.hal deleted file mode 100644 index 0723bad8c6..0000000000 --- a/tv/cec/2.0/IHdmiCec.hal +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Copyright (C) 2019 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.cec@2.0; - -import IHdmiCecCallback; - -/** - * HDMI-CEC HAL interface definition. - */ -interface IHdmiCec { - /** - * Passes Primary Device Type that must be used in this system. - * - * HAL must use it to allocate logical address as specified in CEC section - * 11.3.2 of the CEC spec 2.0b. Then CEC commands addressed the given - * logical address can be filtered in. - * This method shall be able to be called up to twice to support two Primary - * Device Type as specified in CEC Table 11-8 of the CEC spec 2.0b. - * - * @param deviceType that must be used in this system. It must be a valid - * value in CecDeviceType for the call to succeed. - * @return result Result status of the operation. SUCCESS if successful, - * FAILURE_INVALID_ARGS if the given device type is invalid, - * FAILURE_BUSY if device or resource is busy - */ - @callflow(next={"*"}) - addDeviceType(CecDeviceType deviceType) generates (Result result); - - /** - * Clears all Primary Device Types. - * - * It is used when the system plan to reconfigure Primary Device Type, - * hence to tell HAL to release all logical address associated to them, - * and change the state back to the beginning. - */ - @callflow(next="addDeviceType") - @exit - clearDeviceTypes(); - - /** - * Set All Device Types for a Primary Device Type. - * - * This value must be used in REPORT_FEATURES message to response - * GIVE_FEATURES message in HAL. - * - * @param allDeviceTypes device all device types for a Primary Device Type. - */ - @callflow(next="addDeviceType") - setAllDeviceTypes(CecAllDeviceTypes allDeviceTypes); - - /** - * Set Device Features for a Primary Device Type. - * - * This value must be used in REPORT_FEATURES message to response - * GIVE_FEATURES message in HAL. - * - * @param deviceType The device Primary Device Type. - * @param deviceFeatures device features for a Primary Device Type. - */ - @callflow(next="addDeviceType") - setDeviceFeatures(CecDeviceType deviceType, - CecDeviceFeatures deviceFeatures); - - /** - * Set Remote Control Profile for a Primary Device Type. - * - * This value must be used in REPORT_FEATURES message to response - * GIVE_FEATURES message in HAL. - * - * @param deviceType The device Primary Device Type. - * @param rcProliles remote control profiles for a Primary Device Type. - */ - @callflow(next="addDeviceType") - setRcProfile(CecDeviceType deviceType, CecRcProfile rcProfile); - - /** - * Retrieve CEC device information. - * - * CEC section 11.3 of the CEC spec 2.0b specify that a device should not - * ask for static information that another device has already supplied. - * Therefore, CEC 2.0 software stack need a map to store all cec - * devices’ information of current CEC network. - * The device information is broadcasted by a device after it allocates a - * logical address. Messages used to send out these information are - * REPORT_FEATURES, REPORT_PHYSICAL_ADDRESS, DEVICE_VENDOR_ID. - * The spec also requires less than 1 second between REPORT_FEATURES and - * REPORT_PHYSICAL_ADDRESS message, and less than 2 second between - * REPORT_PHYSICAL_ADDRESS and DEVICE_VENDOR_ID. An Implementation of - * device information map in hal can help to meet the timing constraints. - * Logical addressing is part of the process to build this map, so the - * implementation shall include allocating logical address too. - * Whenever a device plug/unplug, the topology of CEC network changes. - * The hal implementation shall update devices’ information map, and - * send out onTopologyEvent to Android system. Then Android system - * will use readDeviceInfo to retreive latest devices’ information of CEC - * network. - * If SYSTEM_CEC_CONTROL is false, the hal implementation need continue to - * maintain and update device information map, and send out pending - * onTopologyEvent to Android system when SYSTEM_CEC_CONTROL is - * changed to true. - * - * @param logicalAddress logical address of CEC device. - * @param physicalAddress physical address of CEC device. - * @return CecDeviceInfo from device information map. - * @return result Result status of the operation. SUCCESS if successful, - * FAILURE_INVALID_ARGS if logical or physical address is invalid. - * FAILURE_INVALID_STATE if device information isn't available yet. - */ - @callflow(next="onTopologyChangeEvent") - readDeviceInfo(CecLogicalAddress logicalAddress, - CecPhysicalAddress physicalAddress) - generates (Result result, CecDeviceInfo deviceInfo); - - /** - * Transmits HDMI-CEC message to other HDMI device. - * - * The method must be designed to return in a certain amount of time and not - * hanging forever. This method MUST complete with in 1 second. - * - * It must try retransmission at least once as specified in the section '7.1 - * Frame Re-transmissions' of the CEC Spec 1.4b. - * - * @param message CEC message to be sent to other HDMI device. - * @return result Result status of the operation. SUCCESS if successful, - * NACK if the sent message is not acknowledged, - * BUSY if the CEC bus is busy. - */ - @callflow(next="*") - sendMessage(CecMessage message) generates (SendMessageResult result); - - /** - * Set the callback - * - * It is used by the framework to receive CecMessages, HDMI hotplug event - * and topology update event. Only one callback client is supported. - * - * @param callback Callback object to pass hdmi events to the system. The - * previously registered callback must be replaced with this one. - */ - @callflow(next={"*"}) - @entry - setCallback(IHdmiCecCallback callback); - - /** - * Gets the hdmi port information of underlying hardware. - * - * @return infos The list of HDMI port information - */ - @callflow(next={"*"}) - getPortInfo() generates (vec<HdmiPortInfo> infos); - - /** - * Sets flags controlling the way HDMI-CEC service works down to HAL - * implementation. Those flags must be used in case the feature needs update - * in HAL itself, firmware or microcontroller. - * - * @param key The key of the option to be updated with a new value. - * @param value Value to be set. - */ - @callflow(next="*") - setOption(OptionKey key, bool value); - - /** - * Passes the updated language information of Android system. Contains - * three-letter code as defined in ISO/FDIS 639-2. Must be used for HAL to - * respond to <Get Menu Language> while in standby mode. - * - * @param language Three-letter code defined in ISO/FDIS 639-2. Must be - * lowercase letters. (e.g., eng for English) - */ - @callflow(next="*") - setLanguage(string language); - - /** - * Configures ARC circuit in the hardware logic to start or stop the - * feature. - * - * @param portId Port id to be configured. - * @param enable Flag must be either true to start the feature or false to - * stop it. - */ - @callflow(next="*") - enableAudioReturnChannel(HdmiPortId portId, bool enable); - - /** - * Gets the connection status of the specified port. - * - * It's specified in CEC section 10.8 of the CEC spec 2.0b - * - * @param portId Port id to be inspected for the connection status. - * @return status True if a device is connected, otherwise false. - */ - @callflow(next="*") - isConnected(HdmiPortId portId) generates (bool connected); -}; diff --git a/tv/cec/2.0/IHdmiCecCallback.hal b/tv/cec/2.0/IHdmiCecCallback.hal deleted file mode 100644 index 1a8a4895cd..0000000000 --- a/tv/cec/2.0/IHdmiCecCallback.hal +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2019 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.cec@2.0; - -interface IHdmiCecCallback { - /** - * The callback function that must be called by HAL implementation to notify - * the system of new CEC message arrival. - */ - oneway onCecMessage(CecMessage message); - - /** - * The callback function that must be called by HAL implementation to notify - * the system of new hotplug event. - */ - oneway onHotplugEvent(HotplugEvent event); - - /** - * The callback function must be called by HAL implementation to notify the - * system whenever CEC device information of CEC network change. - * HAL shall be ready for readDeviceInfo call before invoke this callback. - * This event is triggered by topology change of whole CEC network. It's - * different from HotplugEvent which is triggered between devices which are - * connected directly through HDMI cable. - */ - oneway onTopologyEvent(CecTopologyEvent event); -}; diff --git a/tv/cec/2.0/default/Android.bp b/tv/cec/2.0/default/Android.bp deleted file mode 100644 index d3d53425a4..0000000000 --- a/tv/cec/2.0/default/Android.bp +++ /dev/null @@ -1,40 +0,0 @@ -cc_library_shared { - name: "android.hardware.tv.cec@2.0-impl", - defaults: ["hidl_defaults"], - vendor: true, - relative_install_path: "hw", - srcs: ["HdmiCec.cpp"], - - shared_libs: [ - "libhidlbase", - "liblog", - "libbase", - "libutils", - "libhardware", - "android.hardware.tv.cec@2.0", - ], - -} - -cc_binary { - name: "android.hardware.tv.cec@2.0-service", - vintf_fragments: ["android.hardware.tv.cec@2.0-service.xml"], - defaults: ["hidl_defaults"], - relative_install_path: "hw", - vendor: true, - init_rc: ["android.hardware.tv.cec@2.0-service.rc"], - srcs: ["service.cpp"], - - shared_libs: [ - "liblog", - "libcutils", - "libdl", - "libbase", - "libutils", - "libhardware_legacy", - "libhardware", - "libhidlbase", - "android.hardware.tv.cec@2.0", - ], - -} diff --git a/tv/cec/2.0/default/HdmiCec.cpp b/tv/cec/2.0/default/HdmiCec.cpp deleted file mode 100644 index f45171955b..0000000000 --- a/tv/cec/2.0/default/HdmiCec.cpp +++ /dev/null @@ -1,421 +0,0 @@ -/* - * Copyright (C) 2019 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.tv.cec@2.0-impl" -#include <android-base/logging.h> - -#include <hardware/hardware.h> -#include <hardware/hdmi_cec.h> -#include "HdmiCec.h" - -namespace android { -namespace hardware { -namespace tv { -namespace cec { -namespace V2_0 { -namespace implementation { - -static_assert(CEC_DEVICE_INACTIVE == static_cast<int>(CecDeviceType::INACTIVE), - "CecDeviceType::INACTIVE must match legacy value."); -static_assert(CEC_DEVICE_TV == static_cast<int>(CecDeviceType::TV), - "CecDeviceType::TV must match legacy value."); -static_assert(CEC_DEVICE_RECORDER == static_cast<int>(CecDeviceType::RECORDER), - "CecDeviceType::RECORDER must match legacy value."); -static_assert(CEC_DEVICE_TUNER == static_cast<int>(CecDeviceType::TUNER), - "CecDeviceType::TUNER must match legacy value."); -static_assert(CEC_DEVICE_PLAYBACK == static_cast<int>(CecDeviceType::PLAYBACK), - "CecDeviceType::PLAYBACK must match legacy value."); -static_assert(CEC_DEVICE_AUDIO_SYSTEM == static_cast<int>(CecDeviceType::AUDIO_SYSTEM), - "CecDeviceType::AUDIO_SYSTEM must match legacy value."); -/* TODO: Adjust for cec@2.0 -static_assert(CEC_DEVICE_MAX == static_cast<int>(CecDeviceType::MAX), - "CecDeviceType::MAX must match legacy value."); -*/ -static_assert(CEC_ADDR_TV == static_cast<int>(CecLogicalAddress::TV), - "CecLogicalAddress::TV must match legacy value."); -static_assert(CEC_ADDR_RECORDER_1 == static_cast<int>(CecLogicalAddress::RECORDER_1), - "CecLogicalAddress::RECORDER_1 must match legacy value."); -static_assert(CEC_ADDR_RECORDER_2 == static_cast<int>(CecLogicalAddress::RECORDER_2), - "CecLogicalAddress::RECORDER_2 must match legacy value."); -static_assert(CEC_ADDR_TUNER_1 == static_cast<int>(CecLogicalAddress::TUNER_1), - "CecLogicalAddress::TUNER_1 must match legacy value."); -static_assert(CEC_ADDR_PLAYBACK_1 == static_cast<int>(CecLogicalAddress::PLAYBACK_1), - "CecLogicalAddress::PLAYBACK_1 must match legacy value."); -static_assert(CEC_ADDR_AUDIO_SYSTEM == static_cast<int>(CecLogicalAddress::AUDIO_SYSTEM), - "CecLogicalAddress::AUDIO_SYSTEM must match legacy value."); -static_assert(CEC_ADDR_TUNER_2 == static_cast<int>(CecLogicalAddress::TUNER_2), - "CecLogicalAddress::TUNER_2 must match legacy value."); -static_assert(CEC_ADDR_TUNER_3 == static_cast<int>(CecLogicalAddress::TUNER_3), - "CecLogicalAddress::TUNER_3 must match legacy value."); -static_assert(CEC_ADDR_PLAYBACK_2 == static_cast<int>(CecLogicalAddress::PLAYBACK_2), - "CecLogicalAddress::PLAYBACK_2 must match legacy value."); -static_assert(CEC_ADDR_RECORDER_3 == static_cast<int>(CecLogicalAddress::RECORDER_3), - "CecLogicalAddress::RECORDER_3 must match legacy value."); -static_assert(CEC_ADDR_TUNER_4 == static_cast<int>(CecLogicalAddress::TUNER_4), - "CecLogicalAddress::TUNER_4 must match legacy value."); -static_assert(CEC_ADDR_PLAYBACK_3 == static_cast<int>(CecLogicalAddress::PLAYBACK_3), - "CecLogicalAddress::PLAYBACK_3 must match legacy value."); -/* TODO: Adjust for cec@2.0 -static_assert(CEC_ADDR_FREE_USE == static_cast<int>(CecLogicalAddress::FREE_USE), - "CecLogicalAddress::FREE_USE must match legacy value."); -*/ -static_assert(CEC_ADDR_UNREGISTERED == static_cast<int>(CecLogicalAddress::UNREGISTERED), - "CecLogicalAddress::UNREGISTERED must match legacy value."); -static_assert(CEC_ADDR_BROADCAST == static_cast<int>(CecLogicalAddress::BROADCAST), - "CecLogicalAddress::BROADCAST must match legacy value."); - -static_assert(CEC_MESSAGE_FEATURE_ABORT == static_cast<int>(CecMessageType::FEATURE_ABORT), - "CecMessageType::FEATURE_ABORT must match legacy value."); -static_assert(CEC_MESSAGE_IMAGE_VIEW_ON == static_cast<int>(CecMessageType::IMAGE_VIEW_ON), - "CecMessageType::IMAGE_VIEW_ON must match legacy value."); -static_assert(CEC_MESSAGE_TUNER_STEP_INCREMENT == - static_cast<int>(CecMessageType::TUNER_STEP_INCREMENT), - "CecMessageType::TUNER_STEP_INCREMENT must match legacy value."); -static_assert(CEC_MESSAGE_TUNER_STEP_DECREMENT == - static_cast<int>(CecMessageType::TUNER_STEP_DECREMENT), - "CecMessageType::TUNER_STEP_DECREMENT must match legacy value."); -static_assert(CEC_MESSAGE_TUNER_DEVICE_STATUS == - static_cast<int>(CecMessageType::TUNER_DEVICE_STATUS), - "CecMessageType::TUNER_DEVICE_STATUS must match legacy value."); -static_assert(CEC_MESSAGE_GIVE_TUNER_DEVICE_STATUS == - static_cast<int>(CecMessageType::GIVE_TUNER_DEVICE_STATUS), - "CecMessageType::GIVE_TUNER_DEVICE_STATUS must match legacy value."); -static_assert(CEC_MESSAGE_RECORD_ON == static_cast<int>(CecMessageType::RECORD_ON), - "CecMessageType::RECORD_ON must match legacy value."); -static_assert(CEC_MESSAGE_RECORD_STATUS == static_cast<int>(CecMessageType::RECORD_STATUS), - "CecMessageType::RECORD_STATUS must match legacy value."); -static_assert(CEC_MESSAGE_RECORD_OFF == static_cast<int>(CecMessageType::RECORD_OFF), - "CecMessageType::RECORD_OFF must match legacy value."); -static_assert(CEC_MESSAGE_TEXT_VIEW_ON == static_cast<int>(CecMessageType::TEXT_VIEW_ON), - "CecMessageType::TEXT_VIEW_ON must match legacy value."); -static_assert(CEC_MESSAGE_RECORD_TV_SCREEN == static_cast<int>(CecMessageType::RECORD_TV_SCREEN), - "CecMessageType::RECORD_TV_SCREEN must match legacy value."); -static_assert(CEC_MESSAGE_GIVE_DECK_STATUS == static_cast<int>(CecMessageType::GIVE_DECK_STATUS), - "CecMessageType::GIVE_DECK_STATUS must match legacy value."); -static_assert(CEC_MESSAGE_STANDBY == static_cast<int>(CecMessageType::STANDBY), - "CecMessageType::STANDBY must match legacy value."); -static_assert(CEC_MESSAGE_PLAY == static_cast<int>(CecMessageType::PLAY), - "CecMessageType::PLAY must match legacy value."); -static_assert(CEC_MESSAGE_DECK_CONTROL == static_cast<int>(CecMessageType::DECK_CONTROL), - "CecMessageType::DECK_CONTROL must match legacy value."); -static_assert(CEC_MESSAGE_TIMER_CLEARED_STATUS == - static_cast<int>(CecMessageType::TIMER_CLEARED_STATUS), - "CecMessageType::TIMER_CLEARED_STATUS must match legacy value."); -static_assert(CEC_MESSAGE_USER_CONTROL_PRESSED == - static_cast<int>(CecMessageType::USER_CONTROL_PRESSED), - "CecMessageType::USER_CONTROL_PRESSED must match legacy value."); -static_assert(CEC_MESSAGE_USER_CONTROL_RELEASED == - static_cast<int>(CecMessageType::USER_CONTROL_RELEASED), - "CecMessageType::USER_CONTROL_RELEASED must match legacy value."); -static_assert(CEC_MESSAGE_GIVE_OSD_NAME == static_cast<int>(CecMessageType::GIVE_OSD_NAME), - "CecMessageType::GIVE_OSD_NAME must match legacy value."); -static_assert(CEC_MESSAGE_SET_OSD_NAME == static_cast<int>(CecMessageType::SET_OSD_NAME), - "CecMessageType::SET_OSD_NAME must match legacy value."); -static_assert(CEC_MESSAGE_SYSTEM_AUDIO_MODE_REQUEST == - static_cast<int>(CecMessageType::SYSTEM_AUDIO_MODE_REQUEST), - "CecMessageType::SYSTEM_AUDIO_MODE_REQUEST must match legacy value."); -static_assert(CEC_MESSAGE_GIVE_AUDIO_STATUS == static_cast<int>(CecMessageType::GIVE_AUDIO_STATUS), - "CecMessageType::GIVE_AUDIO_STATUS must match legacy value."); -static_assert(CEC_MESSAGE_SET_SYSTEM_AUDIO_MODE == - static_cast<int>(CecMessageType::SET_SYSTEM_AUDIO_MODE), - "CecMessageType::SET_SYSTEM_AUDIO_MODE must match legacy value."); -static_assert(CEC_MESSAGE_REPORT_AUDIO_STATUS == - static_cast<int>(CecMessageType::REPORT_AUDIO_STATUS), - "CecMessageType::REPORT_AUDIO_STATUS must match legacy value."); -static_assert(CEC_MESSAGE_GIVE_SYSTEM_AUDIO_MODE_STATUS == - static_cast<int>(CecMessageType::GIVE_SYSTEM_AUDIO_MODE_STATUS), - "CecMessageType::GIVE_SYSTEM_AUDIO_MODE_STATUS must match legacy value."); -static_assert(CEC_MESSAGE_SYSTEM_AUDIO_MODE_STATUS == - static_cast<int>(CecMessageType::SYSTEM_AUDIO_MODE_STATUS), - "CecMessageType::SYSTEM_AUDIO_MODE_STATUS must match legacy value."); -static_assert(CEC_MESSAGE_ROUTING_CHANGE == static_cast<int>(CecMessageType::ROUTING_CHANGE), - "CecMessageType::ROUTING_CHANGE must match legacy value."); -static_assert(CEC_MESSAGE_ROUTING_INFORMATION == - static_cast<int>(CecMessageType::ROUTING_INFORMATION), - "CecMessageType::ROUTING_INFORMATION must match legacy value."); -static_assert(CEC_MESSAGE_ACTIVE_SOURCE == static_cast<int>(CecMessageType::ACTIVE_SOURCE), - "CecMessageType::ACTIVE_SOURCE must match legacy value."); -static_assert(CEC_MESSAGE_GIVE_PHYSICAL_ADDRESS == - static_cast<int>(CecMessageType::GIVE_PHYSICAL_ADDRESS), - "CecMessageType::GIVE_PHYSICAL_ADDRESS must match legacy value."); -static_assert(CEC_MESSAGE_REPORT_PHYSICAL_ADDRESS == - static_cast<int>(CecMessageType::REPORT_PHYSICAL_ADDRESS), - "CecMessageType::REPORT_PHYSICAL_ADDRESS must match legacy value."); -static_assert(CEC_MESSAGE_REQUEST_ACTIVE_SOURCE == - static_cast<int>(CecMessageType::REQUEST_ACTIVE_SOURCE), - "CecMessageType::REQUEST_ACTIVE_SOURCE must match legacy value."); -static_assert(CEC_MESSAGE_SET_STREAM_PATH == static_cast<int>(CecMessageType::SET_STREAM_PATH), - "CecMessageType::SET_STREAM_PATH must match legacy value."); -static_assert(CEC_MESSAGE_DEVICE_VENDOR_ID == static_cast<int>(CecMessageType::DEVICE_VENDOR_ID), - "CecMessageType::DEVICE_VENDOR_ID must match legacy value."); -static_assert(CEC_MESSAGE_VENDOR_COMMAND == static_cast<int>(CecMessageType::VENDOR_COMMAND), - "CecMessageType::VENDOR_COMMAND must match legacy value."); -static_assert(CEC_MESSAGE_VENDOR_REMOTE_BUTTON_DOWN == - static_cast<int>(CecMessageType::VENDOR_REMOTE_BUTTON_DOWN), - "CecMessageType::VENDOR_REMOTE_BUTTON_DOWN must match legacy value."); -static_assert(CEC_MESSAGE_VENDOR_REMOTE_BUTTON_UP == - static_cast<int>(CecMessageType::VENDOR_REMOTE_BUTTON_UP), - "CecMessageType::VENDOR_REMOTE_BUTTON_UP must match legacy value."); -static_assert(CEC_MESSAGE_GIVE_DEVICE_VENDOR_ID == - static_cast<int>(CecMessageType::GIVE_DEVICE_VENDOR_ID), - "CecMessageType::GIVE_DEVICE_VENDOR_ID must match legacy value."); -static_assert(CEC_MESSAGE_MENU_REQUEST == static_cast<int>(CecMessageType::MENU_REQUEST), - "CecMessageType::MENU_REQUEST must match legacy value."); -static_assert(CEC_MESSAGE_MENU_STATUS == static_cast<int>(CecMessageType::MENU_STATUS), - "CecMessageType::MENU_STATUS must match legacy value."); -static_assert(CEC_MESSAGE_GIVE_DEVICE_POWER_STATUS == - static_cast<int>(CecMessageType::GIVE_DEVICE_POWER_STATUS), - "CecMessageType::GIVE_DEVICE_POWER_STATUS must match legacy value."); -static_assert(CEC_MESSAGE_REPORT_POWER_STATUS == - static_cast<int>(CecMessageType::REPORT_POWER_STATUS), - "CecMessageType::REPORT_POWER_STATUS must match legacy value."); -static_assert(CEC_MESSAGE_GET_MENU_LANGUAGE == static_cast<int>(CecMessageType::GET_MENU_LANGUAGE), - "CecMessageType::GET_MENU_LANGUAGE must match legacy value."); -static_assert(CEC_MESSAGE_SELECT_ANALOG_SERVICE == - static_cast<int>(CecMessageType::SELECT_ANALOG_SERVICE), - "CecMessageType::SELECT_ANALOG_SERVICE must match legacy value."); -static_assert(CEC_MESSAGE_SELECT_DIGITAL_SERVICE == - static_cast<int>(CecMessageType::SELECT_DIGITAL_SERVICE), - "CecMessageType::SELECT_DIGITAL_SERVICE must match legacy value."); -static_assert(CEC_MESSAGE_SET_DIGITAL_TIMER == static_cast<int>(CecMessageType::SET_DIGITAL_TIMER), - "CecMessageType::SET_DIGITAL_TIMER must match legacy value."); -static_assert(CEC_MESSAGE_CLEAR_DIGITAL_TIMER == - static_cast<int>(CecMessageType::CLEAR_DIGITAL_TIMER), - "CecMessageType::CLEAR_DIGITAL_TIMER must match legacy value."); -static_assert(CEC_MESSAGE_SET_AUDIO_RATE == static_cast<int>(CecMessageType::SET_AUDIO_RATE), - "CecMessageType::SET_AUDIO_RATE must match legacy value."); -static_assert(CEC_MESSAGE_INACTIVE_SOURCE == static_cast<int>(CecMessageType::INACTIVE_SOURCE), - "CecMessageType::INACTIVE_SOURCE must match legacy value."); -static_assert(CEC_MESSAGE_CEC_VERSION == static_cast<int>(CecMessageType::CEC_VERSION), - "CecMessageType::CEC_VERSION must match legacy value."); -static_assert(CEC_MESSAGE_GET_CEC_VERSION == static_cast<int>(CecMessageType::GET_CEC_VERSION), - "CecMessageType::GET_CEC_VERSION must match legacy value."); -static_assert(CEC_MESSAGE_VENDOR_COMMAND_WITH_ID == - static_cast<int>(CecMessageType::VENDOR_COMMAND_WITH_ID), - "CecMessageType::VENDOR_COMMAND_WITH_ID must match legacy value."); -static_assert(CEC_MESSAGE_CLEAR_EXTERNAL_TIMER == - static_cast<int>(CecMessageType::CLEAR_EXTERNAL_TIMER), - "CecMessageType::CLEAR_EXTERNAL_TIMER must match legacy value."); -static_assert(CEC_MESSAGE_SET_EXTERNAL_TIMER == - static_cast<int>(CecMessageType::SET_EXTERNAL_TIMER), - "CecMessageType::SET_EXTERNAL_TIMER must match legacy value."); -static_assert(CEC_MESSAGE_INITIATE_ARC == static_cast<int>(CecMessageType::INITIATE_ARC), - "CecMessageType::INITIATE_ARC must match legacy value."); -static_assert(CEC_MESSAGE_REPORT_ARC_INITIATED == - static_cast<int>(CecMessageType::REPORT_ARC_INITIATED), - "CecMessageType::REPORT_ARC_INITIATED must match legacy value."); -static_assert(CEC_MESSAGE_REPORT_ARC_TERMINATED == - static_cast<int>(CecMessageType::REPORT_ARC_TERMINATED), - "CecMessageType::REPORT_ARC_TERMINATED must match legacy value."); -static_assert(CEC_MESSAGE_REQUEST_ARC_INITIATION == - static_cast<int>(CecMessageType::REQUEST_ARC_INITIATION), - "CecMessageType::REQUEST_ARC_INITIATION must match legacy value."); -static_assert(CEC_MESSAGE_REQUEST_ARC_TERMINATION == - static_cast<int>(CecMessageType::REQUEST_ARC_TERMINATION), - "CecMessageType::REQUEST_ARC_TERMINATION must match legacy value."); -static_assert(CEC_MESSAGE_TERMINATE_ARC == static_cast<int>(CecMessageType::TERMINATE_ARC), - "CecMessageType::TERMINATE_ARC must match legacy value."); -static_assert(CEC_MESSAGE_ABORT == static_cast<int>(CecMessageType::ABORT), - "CecMessageType::ABORT must match legacy value."); - -static_assert(ABORT_UNRECOGNIZED_MODE == static_cast<int>(AbortReason::UNRECOGNIZED_MODE), - "AbortReason::UNRECOGNIZED_MODE must match legacy value."); -static_assert(ABORT_NOT_IN_CORRECT_MODE == static_cast<int>(AbortReason::NOT_IN_CORRECT_MODE), - "AbortReason::NOT_IN_CORRECT_MODE must match legacy value."); -static_assert(ABORT_CANNOT_PROVIDE_SOURCE == static_cast<int>(AbortReason::CANNOT_PROVIDE_SOURCE), - "AbortReason::CANNOT_PROVIDE_SOURCE must match legacy value."); -static_assert(ABORT_INVALID_OPERAND == static_cast<int>(AbortReason::INVALID_OPERAND), - "AbortReason::INVALID_OPERAND must match legacy value."); -static_assert(ABORT_REFUSED == static_cast<int>(AbortReason::REFUSED), - "AbortReason::REFUSED must match legacy value."); -static_assert(ABORT_UNABLE_TO_DETERMINE == static_cast<int>(AbortReason::UNABLE_TO_DETERMINE), - "AbortReason::UNABLE_TO_DETERMINE must match legacy value."); - -static_assert(HDMI_RESULT_SUCCESS == static_cast<int>(SendMessageResult::SUCCESS), - "SendMessageResult::SUCCESS must match legacy value."); -static_assert(HDMI_RESULT_NACK == static_cast<int>(SendMessageResult::NACK), - "SendMessageResult::NACK must match legacy value."); -static_assert(HDMI_RESULT_BUSY == static_cast<int>(SendMessageResult::BUSY), - "SendMessageResult::BUSY must match legacy value."); -static_assert(HDMI_RESULT_FAIL == static_cast<int>(SendMessageResult::FAIL), - "SendMessageResult::FAIL must match legacy value."); - -static_assert(HDMI_INPUT == static_cast<int>(HdmiPortType::INPUT), - "HdmiPortType::INPUT must match legacy value."); -static_assert(HDMI_OUTPUT == static_cast<int>(HdmiPortType::OUTPUT), - "HdmiPortType::OUTPUT must match legacy value."); - -static_assert(HDMI_OPTION_WAKEUP == static_cast<int>(OptionKey::WAKEUP), - "OptionKey::WAKEUP must match legacy value."); -static_assert(HDMI_OPTION_ENABLE_CEC == static_cast<int>(OptionKey::ENABLE_CEC), - "OptionKey::ENABLE_CEC must match legacy value."); -static_assert(HDMI_OPTION_SYSTEM_CEC_CONTROL == static_cast<int>(OptionKey::SYSTEM_CEC_CONTROL), - "OptionKey::SYSTEM_CEC_CONTROL must match legacy value."); - -sp<IHdmiCecCallback> HdmiCec::mCallback = nullptr; - -HdmiCec::HdmiCec(hdmi_cec_device_t* device) : mDevice(device) {} - -// Methods from ::android::hardware::tv::cec::V2_0::IHdmiCec follow. -Return<Result> HdmiCec::addDeviceType(CecDeviceType deviceType) { - // TODO implement - if (deviceType <= CecDeviceType::MAX) { - return Result::SUCCESS; - } else { - return Result::FAILURE_INVALID_ARGS; - } -} - -Return<void> HdmiCec::clearDeviceTypes() { - // TODO implement - return Void(); -} - -Return<void> HdmiCec::setAllDeviceTypes(CecAllDeviceTypes allDeviceTypes) { - // TODO implement - if (allDeviceTypes == 1) { - } - return Void(); -} - -Return<void> HdmiCec::setDeviceFeatures(CecDeviceType deviceType, - CecDeviceFeatures /* deviceFeatures */) { - // TODO implement - if (deviceType != CecDeviceType::MAX) { - } - return Void(); -} - -Return<void> HdmiCec::setRcProfile(CecDeviceType deviceType, const CecRcProfile& /* rcProfile */) { - // TODO implement - if (deviceType != CecDeviceType::MAX) { - } - return Void(); -} - -Return<void> HdmiCec::readDeviceInfo(CecLogicalAddress logicalAddress, - CecPhysicalAddress physicalAddress, - const readDeviceInfo_cb _hidl_cb) { - // TODO implement - CecDeviceInfo deviceInfo; - - if (logicalAddress == CecLogicalAddress::TV) { - _hidl_cb(Result::SUCCESS, deviceInfo); - if (physicalAddress) { - } - } - return Void(); -} - -Return<SendMessageResult> HdmiCec::sendMessage(const CecMessage& message) { - cec_message_t legacyMessage{ - .initiator = static_cast<cec_logical_address_t>(message.initiator), - .destination = static_cast<cec_logical_address_t>(message.destination), - .length = message.body.size(), - }; - for (size_t i = 0; i < message.body.size(); ++i) { - legacyMessage.body[i] = static_cast<unsigned char>(message.body[i]); - } - return static_cast<SendMessageResult>(mDevice->send_message(mDevice, &legacyMessage)); -} - -Return<void> HdmiCec::setCallback(const sp<IHdmiCecCallback>& callback) { - if (mCallback != nullptr) { - mCallback->unlinkToDeath(this); - mCallback = nullptr; - } - - if (callback != nullptr) { - mCallback = callback; - mCallback->linkToDeath(this, 0 /*cookie*/); - mDevice->register_event_callback(mDevice, eventCallback, nullptr); - } - return Void(); -} - -Return<void> HdmiCec::getPortInfo(getPortInfo_cb _hidl_cb) { - struct hdmi_port_info* legacyPorts; - int numPorts; - hidl_vec<HdmiPortInfo> portInfos; - mDevice->get_port_info(mDevice, &legacyPorts, &numPorts); - portInfos.resize(numPorts); - for (int i = 0; i < numPorts; ++i) { - portInfos[i] = {.type = static_cast<HdmiPortType>(legacyPorts[i].type), - .portId = static_cast<HdmiPortId>(legacyPorts[i].port_id), - .cecSupported = legacyPorts[i].cec_supported != 0, - .arcSupported = legacyPorts[i].arc_supported != 0, - .physicalAddress = legacyPorts[i].physical_address}; - } - _hidl_cb(portInfos); - return Void(); -} - -Return<void> HdmiCec::setOption(OptionKey key, bool value) { - mDevice->set_option(mDevice, static_cast<int>(key), value ? 1 : 0); - return Void(); -} - -Return<void> HdmiCec::setLanguage(const hidl_string& language) { - if (language.size() != 3) { - LOG(ERROR) << "Wrong language code: expected 3 letters, but it was " << language.size() - << "."; - return Void(); - } - const char* languageStr = language.c_str(); - int convertedLanguage = ((languageStr[0] & 0xFF) << 16) | ((languageStr[1] & 0xFF) << 8) | - (languageStr[2] & 0xFF); - mDevice->set_option(mDevice, HDMI_OPTION_SET_LANG, convertedLanguage); - return Void(); -} - -Return<void> HdmiCec::enableAudioReturnChannel(HdmiPortId portId, bool enable) { - mDevice->set_audio_return_channel(mDevice, portId, enable ? 1 : 0); - return Void(); -} - -Return<bool> HdmiCec::isConnected(HdmiPortId portId) { - return mDevice->is_connected(mDevice, portId) > 0; -} - -IHdmiCec* HIDL_FETCH_IHdmiCec(const char* hal) { - hdmi_cec_device_t* hdmi_cec_device; - int ret = 0; - const hw_module_t* hw_module = nullptr; - - ret = hw_get_module(HDMI_CEC_HARDWARE_MODULE_ID, &hw_module); - if (ret == 0) { - ret = hdmi_cec_open(hw_module, &hdmi_cec_device); - if (ret != 0) { - LOG(ERROR) << "hdmi_cec_open " << hal << " failed: " << ret; - } - } else { - LOG(ERROR) << "hw_get_module " << hal << " failed: " << ret; - } - - if (ret == 0) { - return new HdmiCec(hdmi_cec_device); - } else { - LOG(ERROR) << "Passthrough failed to load legacy HAL."; - return nullptr; - } -} - -} // namespace implementation -} // namespace V2_0 -} // namespace cec -} // namespace tv -} // namespace hardware -} // namespace android diff --git a/tv/cec/2.0/default/HdmiCec.h b/tv/cec/2.0/default/HdmiCec.h deleted file mode 100644 index ab5477089f..0000000000 --- a/tv/cec/2.0/default/HdmiCec.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_HARDWARE_TV_CEC_V2_0_HDMICEC_H -#define ANDROID_HARDWARE_TV_CEC_V2_0_HDMICEC_H - -#include <algorithm> - -#include <android/hardware/tv/cec/2.0/IHdmiCec.h> -#include <hardware/hardware.h> -#include <hardware/hdmi_cec.h> -#include <hidl/Status.h> - -#include <hidl/MQDescriptor.h> -namespace android { -namespace hardware { -namespace tv { -namespace cec { -namespace V2_0 { -namespace implementation { - -using ::android::sp; -using ::android::hardware::hidl_string; -using ::android::hardware::hidl_vec; -using ::android::hardware::Return; -using ::android::hardware::Void; -using ::android::hardware::tv::cec::V2_0::CecLogicalAddress; -using ::android::hardware::tv::cec::V2_0::CecMessage; -using ::android::hardware::tv::cec::V2_0::CecPhysicalAddress; -using ::android::hardware::tv::cec::V2_0::HdmiPortId; -using ::android::hardware::tv::cec::V2_0::HdmiPortInfo; -using ::android::hardware::tv::cec::V2_0::IHdmiCec; -using ::android::hardware::tv::cec::V2_0::IHdmiCecCallback; -using ::android::hardware::tv::cec::V2_0::MaxLength; -using ::android::hardware::tv::cec::V2_0::OptionKey; -using ::android::hardware::tv::cec::V2_0::Result; -using ::android::hardware::tv::cec::V2_0::SendMessageResult; - -struct HdmiCec : public IHdmiCec, public hidl_death_recipient { - HdmiCec(hdmi_cec_device_t* device); - // Methods from ::android::hardware::tv::cec::V2_0::IHdmiCec follow. - Return<Result> addDeviceType(CecDeviceType deviceType) override; - Return<void> clearDeviceTypes() override; - Return<void> setAllDeviceTypes(CecAllDeviceTypes allDeviceTypes) override; - Return<void> setDeviceFeatures(CecDeviceType deviceType, - CecDeviceFeatures /* deviceFeatures */) override; - Return<void> setRcProfile(CecDeviceType deviceType, - const CecRcProfile& /* rcProfile */) override; - Return<void> readDeviceInfo(CecLogicalAddress logicalAddress, - CecPhysicalAddress physicalAddress, - const readDeviceInfo_cb _hidl_cb) override; - Return<SendMessageResult> sendMessage(const CecMessage& message) override; - Return<void> setCallback(const sp<IHdmiCecCallback>& callback) override; - Return<void> getPortInfo(getPortInfo_cb _hidl_cb) override; - Return<void> setOption(OptionKey key, bool value) override; - Return<void> setLanguage(const hidl_string& language) override; - Return<void> enableAudioReturnChannel(HdmiPortId portId, bool enable) override; - Return<bool> isConnected(HdmiPortId portId) override; - - static void eventCallback(const hdmi_event_t* event, void* /* arg */) { - if (mCallback != nullptr && event != nullptr) { - if (event->type == HDMI_EVENT_CEC_MESSAGE) { - size_t length = - std::min(event->cec.length, static_cast<size_t>(MaxLength::MESSAGE_BODY)); - CecMessage cecMessage{ - .initiator = static_cast<CecLogicalAddress>(event->cec.initiator), - .destination = static_cast<CecLogicalAddress>(event->cec.destination), - }; - cecMessage.body.resize(length); - for (size_t i = 0; i < length; ++i) { - cecMessage.body[i] = static_cast<uint8_t>(event->cec.body[i]); - } - mCallback->onCecMessage(cecMessage); - } else if (event->type == HDMI_EVENT_HOT_PLUG) { - HotplugEvent hotplugEvent{ - .connected = event->hotplug.connected > 0, - .portId = static_cast<HdmiPortId>(event->hotplug.port_id)}; - mCallback->onHotplugEvent(hotplugEvent); - } - } - } - - virtual void serviceDied(uint64_t /*cookie*/, - const wp<::android::hidl::base::V1_0::IBase>& /*who*/) { - setCallback(nullptr); - } - - private: - static sp<IHdmiCecCallback> mCallback; - const hdmi_cec_device_t* mDevice; -}; - -extern "C" IHdmiCec* HIDL_FETCH_IHdmiCec(const char* name); - -} // namespace implementation -} // namespace V2_0 -} // namespace cec -} // namespace tv -} // namespace hardware -} // namespace android - -#endif // ANDROID_HARDWARE_TV_CEC_V2_0_HDMICEC_H diff --git a/tv/cec/2.0/default/OWNERS b/tv/cec/2.0/default/OWNERS deleted file mode 100644 index 1b3d095f9c..0000000000 --- a/tv/cec/2.0/default/OWNERS +++ /dev/null @@ -1,4 +0,0 @@ -nchalko@google.com -amyjojo@google.com -shubang@google.com -quxiangfang@google.com diff --git a/tv/cec/2.0/default/android.hardware.tv.cec@2.0-service.rc b/tv/cec/2.0/default/android.hardware.tv.cec@2.0-service.rc deleted file mode 100644 index 1e8cd8052c..0000000000 --- a/tv/cec/2.0/default/android.hardware.tv.cec@2.0-service.rc +++ /dev/null @@ -1,4 +0,0 @@ -service vendor.cec-hal-2-0 /vendor/bin/hw/android.hardware.tv.cec@2.0-service - class hal - user system - group system diff --git a/tv/cec/2.0/default/android.hardware.tv.cec@2.0-service.xml b/tv/cec/2.0/default/android.hardware.tv.cec@2.0-service.xml deleted file mode 100644 index 61fb1bbf9b..0000000000 --- a/tv/cec/2.0/default/android.hardware.tv.cec@2.0-service.xml +++ /dev/null @@ -1,11 +0,0 @@ -<manifest version="1.0" type="device"> - <hal format="hidl"> - <name>android.hardware.tv.cec</name> - <transport>hwbinder</transport> - <version>2.0</version> - <interface> - <name>IHdmiCec</name> - <instance>default</instance> - </interface> - </hal> -</manifest> diff --git a/tv/cec/2.0/default/service.cpp b/tv/cec/2.0/default/service.cpp deleted file mode 100644 index dacc38cc9d..0000000000 --- a/tv/cec/2.0/default/service.cpp +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2019 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.tv.cec@2.0-service" - -#include <android/hardware/tv/cec/2.0/IHdmiCec.h> -#include <hidl/LegacySupport.h> - -using android::hardware::defaultPassthroughServiceImplementation; -using android::hardware::tv::cec::V2_0::IHdmiCec; - -int main() { - return defaultPassthroughServiceImplementation<IHdmiCec>(); -} diff --git a/tv/cec/2.0/types.hal b/tv/cec/2.0/types.hal deleted file mode 100644 index cad6c396e9..0000000000 --- a/tv/cec/2.0/types.hal +++ /dev/null @@ -1,548 +0,0 @@ -/* - * Copyright (C) 2019 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.cec@2.0; - -import android.hidl.safe_union@1.0; - -/** - * CEC device type as specified in CEC Table 11-7 of the CEC spec 2.0b. - */ -enum CecDeviceType : int32_t { - INACTIVE = -1, - TV = 0, - RECORDER = 1, - TUNER = 3, - PLAYBACK = 4, - AUDIO_SYSTEM = 5, - PURE_CEC_SWITCH = 6, - PROCESSOR = 7, - MAX = PROCESSOR, -}; - -/** - * CEC logical address as specified in CEC Table 11-9 of the CEC spec 2.0b. - */ -enum CecLogicalAddress : int32_t { - TV = 0, - RECORDER_1 = 1, - RECORDER_2 = 2, - TUNER_1 = 3, - PLAYBACK_1 = 4, - AUDIO_SYSTEM = 5, - TUNER_2 = 6, - TUNER_3 = 7, - PLAYBACK_2 = 8, - RECORDER_3 = 9, - TUNER_4 = 10, - PLAYBACK_3 = 11, - BACKUP_1 = 12, // backup1 for Playback/Recording/Tuner/Processor device - BACKUP_2 = 13, // backup2 for Playback/Recording/Tuner/Processor device - SPECIFIC_USE = 14, - UNREGISTERED = 15, // as Initiator address - BROADCAST = 15, // as Destination address -}; - -/** - * HDMI CEC message types. - * - * The assigned values represent opcode used in CEC frame as specified in - * Section 11.10 of the CEC spec 2.0b on top of Section CEC 15 of the CEC - * Spec 1.4b. - */ -enum CecMessageType : int32_t { - FEATURE_ABORT = 0x00, - IMAGE_VIEW_ON = 0x04, - TUNER_STEP_INCREMENT = 0x05, - TUNER_STEP_DECREMENT = 0x06, - TUNER_DEVICE_STATUS = 0x07, - GIVE_TUNER_DEVICE_STATUS = 0x08, - RECORD_ON = 0x09, - RECORD_STATUS = 0x0A, - RECORD_OFF = 0x0B, - TEXT_VIEW_ON = 0x0D, - RECORD_TV_SCREEN = 0x0F, - GIVE_DECK_STATUS = 0x1A, - DECK_STATUS = 0x1B, - SET_MENU_LANGUAGE = 0x32, - CLEAR_ANALOG_TIMER = 0x33, - SET_ANALOG_TIMER = 0x34, - TIMER_STATUS = 0x35, - STANDBY = 0x36, - PLAY = 0x41, - DECK_CONTROL = 0x42, - TIMER_CLEARED_STATUS = 0x43, - USER_CONTROL_PRESSED = 0x44, - USER_CONTROL_RELEASED = 0x45, - GIVE_OSD_NAME = 0x46, - SET_OSD_NAME = 0x47, - SET_OSD_STRING = 0x64, - SET_TIMER_PROGRAM_TITLE = 0x67, - SYSTEM_AUDIO_MODE_REQUEST = 0x70, - GIVE_AUDIO_STATUS = 0x71, - SET_SYSTEM_AUDIO_MODE = 0x72, - REPORT_AUDIO_STATUS = 0x7A, - GIVE_SYSTEM_AUDIO_MODE_STATUS = 0x7D, - SYSTEM_AUDIO_MODE_STATUS = 0x7E, - ROUTING_CHANGE = 0x80, - ROUTING_INFORMATION = 0x81, - ACTIVE_SOURCE = 0x82, - GIVE_PHYSICAL_ADDRESS = 0x83, - REPORT_PHYSICAL_ADDRESS = 0x84, - REQUEST_ACTIVE_SOURCE = 0x85, - SET_STREAM_PATH = 0x86, - DEVICE_VENDOR_ID = 0x87, - VENDOR_COMMAND = 0x89, - VENDOR_REMOTE_BUTTON_DOWN = 0x8A, - VENDOR_REMOTE_BUTTON_UP = 0x8B, - GIVE_DEVICE_VENDOR_ID = 0x8C, - MENU_REQUEST = 0x8D, - MENU_STATUS = 0x8E, - GIVE_DEVICE_POWER_STATUS = 0x8F, - REPORT_POWER_STATUS = 0x90, - GET_MENU_LANGUAGE = 0x91, - SELECT_ANALOG_SERVICE = 0x92, - SELECT_DIGITAL_SERVICE = 0x93, - SET_DIGITAL_TIMER = 0x97, - CLEAR_DIGITAL_TIMER = 0x99, - SET_AUDIO_RATE = 0x9A, - INACTIVE_SOURCE = 0x9D, - CEC_VERSION = 0x9E, - GET_CEC_VERSION = 0x9F, - VENDOR_COMMAND_WITH_ID = 0xA0, - CLEAR_EXTERNAL_TIMER = 0xA1, - SET_EXTERNAL_TIMER = 0xA2, - REPORT_SHORT_AUDIO_DESCRIPTOR = 0xA3, - REQUEST_SHORT_AUDIO_DESCRIPTOR = 0xA4, - GIVE_FEATURES = 0XA5, - REPORT_FEATURES = 0xA6, - REQUEST_CURRENT_LATENCY = 0xA7, - REPORT_CURRENT_LATENCY = 0xA8, - INITIATE_ARC = 0xC0, - REPORT_ARC_INITIATED = 0xC1, - REPORT_ARC_TERMINATED = 0xC2, - REQUEST_ARC_INITIATION = 0xC3, - REQUEST_ARC_TERMINATION = 0xC4, - TERMINATE_ARC = 0xC5, - ABORT = 0xFF, - POLLING_MESSAGE = 0xFFFFFF00, // used for cec polling message -}; - -/** - * Abort Reason as specified in CEC Table 29 of the CEC spec 1.4b. - */ -enum AbortReason : int32_t { - UNRECOGNIZED_MODE = 0, - NOT_IN_CORRECT_MODE = 1, - CANNOT_PROVIDE_SOURCE = 2, - INVALID_OPERAND = 3, - REFUSED = 4, - UNABLE_TO_DETERMINE = 5, -}; - -enum MaxLength : int32_t { - MESSAGE_BODY = 14, -}; - -struct CecMessage { - /** logical address of sender */ - CecLogicalAddress initiator; - - /** logical address of receiver */ - CecLogicalAddress destination; - - /** cec message type */ - CecMessageType cecMessageType; - - /** - * The maximum size of body is 14 (MaxLength::MESSAGE_BODY) as specified in - * the section 6 of the CEC Spec 1.4b. Overflowed data must be ignored. - */ - vec<uint8_t> body; -}; - -/** - * error code used for send_message. - */ -enum SendMessageResult : int32_t { - SUCCESS = 0, - NACK = 1, // not acknowledged - BUSY = 2, // bus is busy - FAIL = 3, -}; - -/** - * CEC All Device Type Value as specified in Table 11-30 of the CEC spec 2.0b. - */ -enum CecAllDeviceTypeValue : uint8_t { - RESERVED_DEVICE_2 = 1 << 0, - RESERVED_DEVICE_1 = 1 << 1, - CEC_SWITCH_DEVICE = 1 << 2, - AUDIO_DEVICE = 1 << 3, - PLAYBACK_DEVICE = 1 << 4, - TUNER_DEVICE = 1 << 5, - RECORDING_DEVICE = 1 << 6, - TV_DEVICE = 1 << 7, -}; - -/** - * CEC All Device Types - * - * It is a combination of all supported type from CecAllDeviceTypeValue. - * For example a record with tuner functionalitye, - * cecAllDeviceTypes = ((CecAllDeviceTypeValue::RECORDING_DEVICE) - * |(CecAllDeviceTypeValue::TUNER_DEVICE)) - */ -typedef bitfield<CecAllDeviceTypeValue> CecAllDeviceTypes; - -/** - * CEC Versions as specified in CEC Table 11-30 of the CEC spec 2.0b. - */ -enum CecVersion : int32_t { - V_1_3_A = 0x04, - V_1_4 = 0x05, // indicate CEC 1.4, 1.4a or 1.4b - V_2_0 = 0x06, -}; - -/** - * Device Feature - * - * It is specified in CEC Table 11-30 of the CEC spec 2.0b. As a uint32 there - * is room for future extensions aka DeviceFeature2 through DeviceFeature4. - */ -enum CecDeviceFeature : uint32_t { - RESERVED = 1 << 0, - SOURCE_SUPPORT_ARC_RX = 1 << 1, - SINK_SUPPORT_ARC_TX = 1 << 2, - SOURCE_SUPPORT_SET_AUDIO_RATE = 1 << 3, - SUPPORT_CONTROLLED_BY_DECK = 1 << 4, - TV_SUPPORT_SET_OSD_STRINGS = 1 << 5, - TV_SUPPORT_RECORD_TV_SCREEN = 1 << 6, -}; - -/** - * CEC Device Features - * - * It is a combination of all supported features from CecDeviceFeature. - * For example a TV with OSD and ARC capabilities, - * CecDeviceFeatures = ((CecDeviceFeature::TV_SUPPORT_SET_OSD_STRINGS) - * |(CecDeviceFeature::SINK_SUPPORT_ARC_TX)) - */ -typedef bitfield<CecDeviceFeature> CecDeviceFeatures; - -/** - * Remote Control Profile - * - * It is specified in CEC Table 11-30 of the CEC spec 2.0b. - */ -enum CecRcProfileId : uint8_t { - NONE = 0, // TV doesn’t support any of these profiles - RC_PROFILE_1 = 0x02, // minimalistic zapper (low button count) - RC_PROFILE_2 = 0x06, // intermediate between profile 1 and profile 3 - RC_PROFILE_3 = 0x0A, // typical TV remote - RC_PROFILE_4 = 0x0E, // extended form of profile 3 -}; - -/** - * Remote Control Profile Source - * - * It is specified in CEC Table 11-30 of the CEC spec 2.0b. - */ -enum CecRcProfileSource : uint8_t { - MEDIA_CONTEXT_SENSITIVE = 1 << 0, // source can handle UI command 0x11 - MEDIA_TO = 1 << 1, // source can handle UI command 0x10 - CONTENTS = 1 << 2, // source can handle UI command 0x0B - DEVICE_SETUP = 1 << 3, // source can handle UI command 0x0A - DEVICE_ROOT = 1 << 4, // source can handle UI command 0x09 - SOURCE_FLAG = 1 << 6, // Indicate the profile is for source -}; - -/** - * Remote Control Profile for either TV or Source. - */ -safe_union CecRcProfile1 { - /** CEC remote control profile for TV. */ - CecRcProfileId profileId; - - /* CEC remote control profile for source - * - * It is a combination of all supported profiles from CecRcProfileSource. - * For example a playback device support root menu and setup menu, - * profileSource = ((CecRcProfileSource::DEVICE_ROOT) - * |(CecRcProfileSource::DEVICE_SETUP) - * |(CecRcProfileSource::SOURCE_FLAG)) - */ - bitfield<CecRcProfileSource> profileSource; -}; - -/** - * CEC Remote Control Profiles - * - * CEC 2.0 only use one byte to represent Remote Control Profile. - */ -struct CecRcProfile { - CecRcProfile1 rcProfile1; -}; - -/** - * CEC device power states as specified in CEC Table 11-10 of the CEC spec 2.0b - */ -enum CecPowerState : int8_t { - ON = 0, - STANDBY = 1, - ON_TO_STANDBY = 2, - STANDBY_TO_ON = 4, - UNKNOWN = 0xFF, // some devices may not report power status -}; - -/** CEC physical address of device */ -typedef uint16_t CecPhysicalAddress; - -/** - * CEC device information - * - * It is initially built during addressing specified in CEC section 11.3 of - * the CEC spec 2.0b. It may be updated with cec devices's status changed. - */ -struct CecDeviceInfo { - /** CEC version which device supports */ - CecVersion version; - - /** CEC device primary type */ - CecDeviceType devceType; - - /** CEC all device types */ - CecAllDeviceTypes allDeviceTypes; - - /** CEC device features */ - CecDeviceFeatures deviceFeatures; - - /** CEC Device Remote Control Profile */ - CecRcProfile rcProfile; - - /** CEC Device Vendor ID */ - uint32_t vendorId; - - /** logical address of device */ - CecLogicalAddress logicalAddress; - - /** physical of device */ - CecPhysicalAddress physicalAddress; - - /** power status of device */ - CecPowerState powerState; -}; - -/** - * Topology Event Type. - */ -enum CecTopologyEventType : int32_t { - DEVICE_ADDED, - DEVICE_REMOVED, - DEVICE_UPDATED, -}; - -/** - * Topology Event. - */ -struct CecTopologyEvent { - CecTopologyEventType eventType; - CecLogicalAddress logicalAddress; - CecPhysicalAddress physicalAddress; - - /** true if the event is about the device which the system run on */ - bool isHostDevice; -}; - - -/** - * CEC UI Command Codes as specified in CEC Table 11-31 of the CEC spec 2.0b - */ -enum CecUICommandCodes : int32_t { - SELECT_OK = 0x00, - UP = 0x01, - DOWN = 0x02, - LEFT = 0x03, - RIGHT = 0x04, - RIGHT_UP = 0x05, - RIGHT_DOWN = 0x06, - LEFT_UP = 0x07, - LEFT_DOWN = 0x08, - DEVICE_ROOT_MENU = 0x09, - DEVICE_SETUP_MENU = 0x0A, - CONTENTS_MENU = 0x0B, - FAVORITE_MENU = 0x0C, - BACK = 0x0D, - MEDIA_TOP_MENU = 0x10, - MEDIA_CONTEXT_SENSITIVE_MENU = 0x11, - NUMBER_ENTRY_MODE = 0x1D, - NUMBER_11 = 0x1E, - NUMBER_12 = 0x1F, - NUMBER_0 = 0x20, // or NUMBER 10 - NUMBER_1 = 0x21, - NUMBER_2 = 0x22, - NUMBER_3 = 0x23, - NUMBER_4 = 0x24, - NUMBER_5 = 0x25, - NUMBER_6 = 0x26, - NUMBER_7 = 0x27, - NUMBER_8 = 0x28, - NUMBER_9 = 0x29, - DOT = 0x2A, - ENTER = 0x2B, - CLEAR = 0x2C, - NEXT_FAVORITE = 0x2F, - CHANNEL_UP = 0x30, - CHANNEL_DOWN = 0x31, - PREVIOUS_CHANNEL = 0x32, - SOUND_SELECT = 0x33, - INPUT_SELECT = 0x34, - DISPLAY_INFORMATION = 0x35, - HELP = 0x36, - PAGE_UP = 0x37, - PAGE_DOWN = 0x38, - POWER = 0x40, - VOLUME_UP = 0x41, - VOLUME_DOWN = 0x42, - MUTE = 0x43, - PLAY = 0x44, - STOP = 0x45, - PAUSE = 0x46, - RECORD = 0x47, - REWIND = 0x48, - FAST_FORWARD = 0x49, - EJECT = 0x4A, - SKIP_FORWARD = 0x4B, - SKIP_BACKWARD = 0x4C, - STOP_RECORD = 0x4D, - PAUSE_RECORD = 0x4E, - ANGLE = 0x50, - SUB_PICTURE = 0x51, - VIDEO_ON_DEMAND = 0x52, - ELECTRONIC_PROGRAM_GUIDE = 0x53, - TIMER_PROGRAMMING = 0x54, - INITIAL_CONFIGURATION = 0x55, - SELECT_BROADCAST_TYPE = 0x56, - SELECT_SOUND_PRESENTATION = 0x57, - AUDIO_DESCRIPTION = 0x58, - INTERNET = 0x59, - THREE_DIMENSIONAL_MODE = 0x5A, - PLAY_FUNCTION = 0x60, - PAUSE_PLAY_FUNCTION = 0x61, - RECORD_FUNCTION = 0x62, - PAUSE_RECORD_FUNCTION = 0x63, - STOP_FUNCTION = 0x64, - MUTE_FUNCTION = 0x65, - RESTORE_VOLUME_FUNCTION = 0x66, - TUNE_FUNCTION = 0x67, - SELECT_MEDIA_FUNCTION = 0x68, - SELECT_AV_INPUT_FUNCTION = 0x69, - SELECT_AUDIO_INPUT_FUNCTION = 0x6A, - POWER_TOGGLE_FUNCTION = 0x6B, - POWER_OFF_FUNCTION = 0x6C, - POWER_ON_FUNCTION = 0x6D, - F1 = 0x71, // BLUE - F2 = 0x72, // RED - F3 = 0x73, // GREEN - F4 = 0x74, // YELLOW - F5 = 0x75, - DATA = 0x76, -}; - -/** - * HDMI port type. - */ -enum HdmiPortType : int32_t { - INPUT = 0, - OUTPUT = 1, -}; - -/** - * Options used for IHdmiCec.setOption() - */ -enum OptionKey : int32_t { - /** - * When set to false, HAL does not wake up the system upon receiving <Image - * View On> or <Text View On>. Used when user changes the TV settings to - * disable the auto TV on functionality. - * Deprecated since <Image View On> and <Text View On> become mandatory - * featrues for CEC device. Use ENABLE_CEC OptionKey to disable CEC - * functionality instead. - * True by Default - */ - WAKEUP = 1, - - /** - * When set to false, all the CEC commands are discarded. if logical address - * is ever used, it shall be released. Used when user changes the TV - * settings to disable CEC functionality. - * True by default. - * - */ - ENABLE_CEC = 2, - - /** - * Setting this flag to false means Android system must stop handling CEC - * service and yield the control over to the microprocessor that is powered - * on through the standby mode.The microprocessor shall keep current logical - * and physical address. It shall response POLLING_MESSAGE, GIVE_FEATURES, - * GIVE_DEVICE_POWER_STATUS,GIVE_DEVICE_VENDOR_ID and GIVE_PHYSICAL_ADDRESS - * to allow other CEC devices to build CEC devices map specified in CEC - * section 11.3 of the CEC spec 2.0b. - * When set to true, the system must gain the control over, hence telling - * the microprocessor to start forwarding CEC messages to Android system. - * For example, this may be called when system goes in and out of - * standby mode to notify the microprocessor that it should start/stop - * handling CEC commands on behalf of the system. - * True by default. - */ - SYSTEM_CEC_CONTROL = 3, - - /* Option 4 not used */ -}; - -/** - * Hdmi port ID. - * - * It shall start from 1 which corresponds to HDMI "port 1". - */ -typedef uint32_t HdmiPortId; - -/** Hdmi hotplug event */ -struct HotplugEvent { - bool connected; - HdmiPortId portId; -}; - -/** - * HDMI port descriptor - */ -struct HdmiPortInfo { - HdmiPortType type; - HdmiPortId portId; - bool cecSupported; - bool arcSupported; - CecPhysicalAddress physicalAddress; -}; - -enum Result : int32_t { - SUCCESS = 0, - FAILURE_UNKNOWN = 1, - FAILURE_INVALID_ARGS = 2, - FAILURE_INVALID_STATE = 3, - FAILURE_NOT_SUPPORTED = 4, - FAILURE_BUSY = 5, -}; diff --git a/vibrator/aidl/default/Android.bp b/vibrator/aidl/default/Android.bp index f9d45bb001..b44f11dc94 100644 --- a/vibrator/aidl/default/Android.bp +++ b/vibrator/aidl/default/Android.bp @@ -4,7 +4,7 @@ cc_library_static { shared_libs: [ "libbase", "libbinder_ndk", - "android.hardware.vibrator-unstable-ndk_platform", + "android.hardware.vibrator-V2-ndk_platform", ], export_include_dirs: ["include"], srcs: [ @@ -26,7 +26,7 @@ cc_binary { shared_libs: [ "libbase", "libbinder_ndk", - "android.hardware.vibrator-unstable-ndk_platform", + "android.hardware.vibrator-V2-ndk_platform", ], static_libs: [ "libvibratorexampleimpl", diff --git a/vibrator/aidl/vts/Android.bp b/vibrator/aidl/vts/Android.bp index d06b50efe3..b50b3f70be 100644 --- a/vibrator/aidl/vts/Android.bp +++ b/vibrator/aidl/vts/Android.bp @@ -9,7 +9,7 @@ cc_test { "libbinder", ], static_libs: [ - "android.hardware.vibrator-unstable-cpp", + "android.hardware.vibrator-V2-cpp", ], test_suites: [ "general-tests", @@ -28,7 +28,7 @@ cc_test { "libbinder", ], static_libs: [ - "android.hardware.vibrator-unstable-cpp", + "android.hardware.vibrator-V2-cpp", ], test_suites: [ "general-tests", diff --git a/vibrator/bench/Android.bp b/vibrator/bench/Android.bp index c7f824d75f..3d7bdc5084 100644 --- a/vibrator/bench/Android.bp +++ b/vibrator/bench/Android.bp @@ -20,7 +20,7 @@ cc_benchmark { "benchmark.cpp", ], shared_libs: [ - "android.hardware.vibrator-cpp", + "android.hardware.vibrator-V1-cpp", "android.hardware.vibrator@1.0", "android.hardware.vibrator@1.1", "android.hardware.vibrator@1.2", diff --git a/weaver/aidl/Android.bp b/weaver/aidl/Android.bp new file mode 100644 index 0000000000..5637e0a248 --- /dev/null +++ b/weaver/aidl/Android.bp @@ -0,0 +1,16 @@ +aidl_interface { + name: "android.hardware.weaver", + vendor_available: true, + srcs: ["android/hardware/weaver/*.aidl"], + stability: "vintf", + backend: { + java: { + platform_apis: true, + }, + ndk: { + vndk: { + enabled: true, + }, + }, + }, +} diff --git a/weaver/aidl/aidl_api/android.hardware.weaver/current/android/hardware/weaver/IWeaver.aidl b/weaver/aidl/aidl_api/android.hardware.weaver/current/android/hardware/weaver/IWeaver.aidl new file mode 100644 index 0000000000..29bd9a9213 --- /dev/null +++ b/weaver/aidl/aidl_api/android.hardware.weaver/current/android/hardware/weaver/IWeaver.aidl @@ -0,0 +1,42 @@ +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m <name>-update-api`. +// +// You must not make a backward incompatible change to any AIDL file 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.weaver; +@VintfStability +interface IWeaver { + android.hardware.weaver.WeaverConfig getConfig(); + android.hardware.weaver.WeaverReadResponse read(in int slotId, in byte[] key); + void write(in int slotId, in byte[] key, in byte[] value); + const int STATUS_FAILED = 1; + const int INCORRECT_KEY = 2; + const int THROTTLE = 3; +} diff --git a/weaver/aidl/aidl_api/android.hardware.weaver/current/android/hardware/weaver/WeaverConfig.aidl b/weaver/aidl/aidl_api/android.hardware.weaver/current/android/hardware/weaver/WeaverConfig.aidl new file mode 100644 index 0000000000..239cdac00b --- /dev/null +++ b/weaver/aidl/aidl_api/android.hardware.weaver/current/android/hardware/weaver/WeaverConfig.aidl @@ -0,0 +1,39 @@ +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m <name>-update-api`. +// +// You must not make a backward incompatible change to any AIDL file 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.weaver; +@VintfStability +parcelable WeaverConfig { + long slots; + long keySize; + long valueSize; +} diff --git a/weaver/aidl/aidl_api/android.hardware.weaver/current/android/hardware/weaver/WeaverReadResponse.aidl b/weaver/aidl/aidl_api/android.hardware.weaver/current/android/hardware/weaver/WeaverReadResponse.aidl new file mode 100644 index 0000000000..7e5db59f9a --- /dev/null +++ b/weaver/aidl/aidl_api/android.hardware.weaver/current/android/hardware/weaver/WeaverReadResponse.aidl @@ -0,0 +1,38 @@ +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m <name>-update-api`. +// +// You must not make a backward incompatible change to any AIDL file 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.weaver; +@VintfStability +parcelable WeaverReadResponse { + long timeout; + byte[] value; +} diff --git a/weaver/aidl/android/hardware/weaver/IWeaver.aidl b/weaver/aidl/android/hardware/weaver/IWeaver.aidl new file mode 100644 index 0000000000..ebbfabe62a --- /dev/null +++ b/weaver/aidl/android/hardware/weaver/IWeaver.aidl @@ -0,0 +1,94 @@ +/* + * 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.weaver; + +import android.hardware.weaver.WeaverConfig; +import android.hardware.weaver.WeaverReadResponse; + +/** + * Weaver provides secure storage of secret values that may only be read if the + * corresponding key has been presented. + * + * The storage must be secure as the device's user authentication and encryption + * relies on the security of these values. The cardinality of the domains of the + * key and value must be suitably large such that they cannot be easily guessed. + * + * Weaver is structured as an array of slots, each containing a key-value pair. + * Slots are uniquely identified by an ID in the range [0, `getConfig().slots`). + */ +@VintfStability +interface IWeaver { + /** + * Retrieves the config information for this implementation of Weaver. + * + * The config is static i.e. every invocation returns the same information. + * + * @return config data for this implementation of Weaver if status is OK, + * otherwise undefined. + */ + WeaverConfig getConfig(); + + /** + * Read binder calls may return a ServiceSpecificException with the following error codes. + */ + const int STATUS_FAILED = 1; + const int INCORRECT_KEY = 2; + const int THROTTLE = 3; + + /** + * Attempts to retrieve the value stored in the identified slot. + * + * The value is only returned if the provided key matches the key stored in + * the slot. The value is never returned if the wrong key is provided. + * + * Throttling must be used to limit the frequency of failed read attempts. + * The value is only returned when throttling is not active, even if the + * correct key is provided. If called when throttling is active, the time + * until the next attempt can be made is returned. + * + * Service status return: + * + * OK if the value was successfully read from slot. + * INCORRECT_KEY if the key does not match the key in the slot. + * THROTTLE if throttling is active. + * STATUS_FAILED if the read was unsuccessful for another reason. + * + * @param slotId of the slot to read from, this must be positive to be valid. + * @param key that is stored in the slot. + * @return The WeaverReadResponse for this read request. If the status is OK, + * value is set to the value in the slot and timeout is 0. Otherwise, value is + * empty and timeout is set accordingly. + */ + WeaverReadResponse read(in int slotId, in byte[] key); + + /** + * Overwrites the identified slot with the provided key and value. + * + * The new values are written regardless of the current state of the slot in + * order to remain idempotent. + * + * Service status return: + * + * OK if the write was successfully completed. + * FAILED if the write was unsuccessful. + * + * @param slotId of the slot to write to. + * @param key to write to the slot. + * @param value to write to slot. + */ + void write(in int slotId, in byte[] key, in byte[] value); +} diff --git a/weaver/aidl/android/hardware/weaver/WeaverConfig.aidl b/weaver/aidl/android/hardware/weaver/WeaverConfig.aidl new file mode 100644 index 0000000000..75d961e851 --- /dev/null +++ b/weaver/aidl/android/hardware/weaver/WeaverConfig.aidl @@ -0,0 +1,34 @@ +/* + * 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.weaver; + +@VintfStability +parcelable WeaverConfig { + /** + * The number of slots available. + */ + long slots; + /** + * The number of bytes used for a key. + */ + long keySize; + /** + * The number of bytes used for a value. + */ + long valueSize; +} + diff --git a/gnss/3.0/vts/functional/gnss_hal_test.h b/weaver/aidl/android/hardware/weaver/WeaverReadResponse.aidl index be6d38cfac..ec006e8c45 100644 --- a/gnss/3.0/vts/functional/gnss_hal_test.h +++ b/weaver/aidl/android/hardware/weaver/WeaverReadResponse.aidl @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 The Android Open Source Project + * 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. @@ -14,11 +14,17 @@ * limitations under the License. */ -#pragma once +package android.hardware.weaver; -#include <android/hardware/gnss/3.0/IGnss.h> -#include "v2_1/gnss_hal_test_template.h" +@VintfStability +parcelable WeaverReadResponse { + /** + * The time to wait, in milliseconds, before making the next request. + */ + long timeout; + /** + * The value read from the slot or empty if the value was not read. + */ + byte[] value; +} -// The main test class for GNSS HAL. -class GnssHalTest : public android::hardware::gnss::common::GnssHalTestTemplate< - android::hardware::gnss::V3_0::IGnss> {};
\ No newline at end of file diff --git a/weaver/aidl/default/Android.bp b/weaver/aidl/default/Android.bp new file mode 100644 index 0000000000..8440670c27 --- /dev/null +++ b/weaver/aidl/default/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. +// + +cc_binary { + name: "android.hardware.weaver-service.example", + relative_install_path: "hw", + init_rc: ["android.hardware.weaver-service.example.rc"], + vintf_fragments: ["android.hardware.weaver-service.example.xml"], + vendor: true, + srcs: [ + "service.cpp", + "Weaver.cpp", + ], + shared_libs: [ + "android.hardware.weaver-V1-ndk_platform", + "libbase", + "libbinder_ndk", + ], +} diff --git a/weaver/aidl/default/Weaver.cpp b/weaver/aidl/default/Weaver.cpp new file mode 100644 index 0000000000..56d9c4da8b --- /dev/null +++ b/weaver/aidl/default/Weaver.cpp @@ -0,0 +1,48 @@ +/* + * 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 "Weaver.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace weaver { + +// Methods from ::android::hardware::weaver::IWeaver follow. + +::ndk::ScopedAStatus Weaver::getConfig(WeaverConfig* out_config) { + (void)out_config; + return ::ndk::ScopedAStatus::ok(); +} + +::ndk::ScopedAStatus Weaver::read(int32_t in_slotId, const std::vector<uint8_t>& in_key, WeaverReadResponse* out_response) { + (void)in_slotId; + (void)in_key; + (void)out_response; + return ::ndk::ScopedAStatus::ok(); +} + +::ndk::ScopedAStatus Weaver::write(int32_t in_slotId, const std::vector<uint8_t>& in_key, const std::vector<uint8_t>& in_value) { + (void)in_slotId; + (void)in_key; + (void)in_value; + return ::ndk::ScopedAStatus::ok(); +} + +} //namespace weaver +} //namespace hardware +} //namespace android +} //namespace aidl diff --git a/weaver/aidl/default/Weaver.h b/weaver/aidl/default/Weaver.h new file mode 100644 index 0000000000..b50018e94a --- /dev/null +++ b/weaver/aidl/default/Weaver.h @@ -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. + */ + +#pragma once + +#include <aidl/android/hardware/weaver/BnWeaver.h> + +namespace aidl { +namespace android { +namespace hardware { +namespace weaver { + +using ::aidl::android::hardware::weaver::WeaverConfig; +using ::aidl::android::hardware::weaver::WeaverReadResponse; + +struct Weaver : public BnWeaver { +public: + Weaver() = default; + + // Methods from ::android::hardware::weaver::IWeaver follow. + ::ndk::ScopedAStatus getConfig(WeaverConfig* _aidl_return) override; + ::ndk::ScopedAStatus read(int32_t in_slotId, const std::vector<uint8_t>& in_key, WeaverReadResponse* _aidl_return) override; + ::ndk::ScopedAStatus write(int32_t in_slotId, const std::vector<uint8_t>& in_key, const std::vector<uint8_t>& in_value) override; +}; + +} // namespace weaver +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/weaver/aidl/default/android.hardware.weaver-service.example.rc b/weaver/aidl/default/android.hardware.weaver-service.example.rc new file mode 100644 index 0000000000..ec777748b2 --- /dev/null +++ b/weaver/aidl/default/android.hardware.weaver-service.example.rc @@ -0,0 +1,4 @@ +service vendor.weaver_default /vendor/bin/hw/android.hardware.weaver-service.example + class hal + user hsm + group hsm diff --git a/weaver/aidl/default/android.hardware.weaver-service.example.xml b/weaver/aidl/default/android.hardware.weaver-service.example.xml new file mode 100644 index 0000000000..ed291cdf60 --- /dev/null +++ b/weaver/aidl/default/android.hardware.weaver-service.example.xml @@ -0,0 +1,10 @@ +<manifest version="1.0" type="device"> + <hal format="aidl"> + <name>android.hardware.weaver</name> + <version>1</version> + <interface> + <name>IWeaver</name> + <instance>default</instance> + </interface> + </hal> +</manifest> diff --git a/gnss/3.0/default/Gnss.cpp b/weaver/aidl/default/service.cpp index 5f2ca4f522..1495bc9201 100644 --- a/gnss/3.0/default/Gnss.cpp +++ b/weaver/aidl/default/service.cpp @@ -14,19 +14,22 @@ * limitations under the License. */ -#define LOG_TAG "Gnss" +#include <android-base/logging.h> +#include <android/binder_manager.h> +#include <android/binder_process.h> -#include "Gnss.h" -#include <log/log.h> -#include "GnssPsds.h" -#include "Utils.h" +#include "Weaver.h" -namespace android::hardware::gnss::V3_0::implementation { +using ::aidl::android::hardware::weaver::Weaver; -// Methods from V3_0::IGnss follow. -Return<sp<V3_0::IGnssPsds>> Gnss::getExtensionPsds() { - ALOGD("Gnss::getExtensionPsds"); - return new GnssPsds(); -} +int main() { + ABinderProcess_setThreadPoolMaxThreadCount(0); + std::shared_ptr<Weaver> weaver = ndk::SharedRefBase::make<Weaver>(); + + const std::string instance = std::string() + Weaver::descriptor + "/default"; + binder_status_t status = AServiceManager_addService(weaver->asBinder().get(), instance.c_str()); + CHECK(status == STATUS_OK); -} // namespace android::hardware::gnss::V3_0::implementation + ABinderProcess_joinThreadPool(); + return -1; // Should never be reached +} diff --git a/weaver/aidl/vts/Android.bp b/weaver/aidl/vts/Android.bp new file mode 100644 index 0000000000..7daad8d833 --- /dev/null +++ b/weaver/aidl/vts/Android.bp @@ -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. +// + +cc_test { + name: "VtsHalWeaverTargetTest", + defaults: [ + "VtsHalTargetTestDefaults", + "use_libaidlvintf_gtest_helper_static", + ], + srcs: ["VtsHalWeaverTargetTest.cpp"], + shared_libs: [ + "libbinder_ndk", + "libbase", + ], + static_libs: ["android.hardware.weaver-V1-ndk_platform"], + test_suites: [ + "general-tests", + "vts", + ], +} diff --git a/weaver/aidl/vts/OWNERS b/weaver/aidl/vts/OWNERS new file mode 100644 index 0000000000..40d95e4bf0 --- /dev/null +++ b/weaver/aidl/vts/OWNERS @@ -0,0 +1,2 @@ +chengyouho@google.com +frankwoo@google.com diff --git a/weaver/aidl/vts/VtsHalWeaverTargetTest.cpp b/weaver/aidl/vts/VtsHalWeaverTargetTest.cpp new file mode 100644 index 0000000000..7d8daa2464 --- /dev/null +++ b/weaver/aidl/vts/VtsHalWeaverTargetTest.cpp @@ -0,0 +1,277 @@ +/* + * 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 <aidl/android/hardware/weaver/IWeaver.h> +#include <android/binder_manager.h> +#include <android/binder_process.h> + +#include <limits> + +using ::aidl::android::hardware::weaver::IWeaver; +using ::aidl::android::hardware::weaver::WeaverConfig; +using ::aidl::android::hardware::weaver::WeaverReadResponse; + +using ::ndk::SpAIBinder; + +const std::vector<uint8_t> KEY{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; +const std::vector<uint8_t> WRONG_KEY{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +const std::vector<uint8_t> VALUE{16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; +const std::vector<uint8_t> OTHER_VALUE{0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 255, 255}; + +struct WeaverAidlTest : public ::testing::TestWithParam<std::string> { + virtual void SetUp() override { + weaver = IWeaver::fromBinder( + SpAIBinder(AServiceManager_waitForService(GetParam().c_str()))); + ASSERT_NE(weaver, nullptr); + } + + virtual void TearDown() override {} + + std::shared_ptr<IWeaver> weaver; +}; + +/* + * Checks config values are suitably large + */ +TEST_P(WeaverAidlTest, GetConfig) { + WeaverConfig config; + + auto ret = weaver->getConfig(&config); + + ASSERT_TRUE(ret.isOk()); + + EXPECT_GE(config.slots, 16u); + EXPECT_GE(config.keySize, 16u); + EXPECT_GE(config.valueSize, 16u); +} + +/* + * Gets the config twice and checks they are the same + */ +TEST_P(WeaverAidlTest, GettingConfigMultipleTimesGivesSameResult) { + WeaverConfig config1; + WeaverConfig config2; + + auto ret = weaver->getConfig(&config1); + ASSERT_TRUE(ret.isOk()); + + ret = weaver->getConfig(&config2); + ASSERT_TRUE(ret.isOk()); + + EXPECT_EQ(config1, config2); +} + +/* + * Gets the number of slots from the config and writes a key and value to the last one + */ +TEST_P(WeaverAidlTest, WriteToLastSlot) { + WeaverConfig config; + const auto configRet = weaver->getConfig(&config); + + ASSERT_TRUE(configRet.isOk()); + + const uint32_t lastSlot = config.slots - 1; + const auto writeRet = weaver->write(lastSlot, KEY, VALUE); + ASSERT_TRUE(writeRet.isOk()); +} + +/* + * Writes a key and value to a slot + * Reads the slot with the same key and receives the value that was previously written + */ +TEST_P(WeaverAidlTest, WriteFollowedByReadGivesTheSameValue) { + constexpr uint32_t slotId = 0; + const auto ret = weaver->write(slotId, KEY, VALUE); + ASSERT_TRUE(ret.isOk()); + + WeaverReadResponse response; + std::vector<uint8_t> readValue; + uint32_t timeout; + const auto readRet = weaver->read(slotId, KEY, &response); + + readValue = response.value; + timeout = response.timeout; + + ASSERT_TRUE(readRet.isOk()); + EXPECT_EQ(readValue, VALUE); + EXPECT_EQ(timeout, 0u); +} + +/* + * Writes a key and value to a slot + * Overwrites the slot with a new key and value + * Reads the slot with the new key and receives the new value + */ +TEST_P(WeaverAidlTest, OverwritingSlotUpdatesTheValue) { + constexpr uint32_t slotId = 0; + const auto initialWriteRet = weaver->write(slotId, WRONG_KEY, VALUE); + ASSERT_TRUE(initialWriteRet.isOk()); + + const auto overwriteRet = weaver->write(slotId, KEY, OTHER_VALUE); + ASSERT_TRUE(overwriteRet.isOk()); + + WeaverReadResponse response; + std::vector<uint8_t> readValue; + uint32_t timeout; + const auto readRet = weaver->read(slotId, KEY, &response); + + readValue = response.value; + timeout = response.timeout; + + ASSERT_TRUE(readRet.isOk()); + EXPECT_EQ(readValue, OTHER_VALUE); + EXPECT_EQ(timeout, 0u); +} + +/* + * Writes a key and value to a slot + * Reads the slot with a different key so does not receive the value + */ +TEST_P(WeaverAidlTest, WriteFollowedByReadWithWrongKeyDoesNotGiveTheValue) { + constexpr uint32_t slotId = 0; + const auto ret = weaver->write(slotId, KEY, VALUE); + ASSERT_TRUE(ret.isOk()); + + WeaverReadResponse response; + std::vector<uint8_t> readValue; + const auto readRet = + weaver->read(slotId, WRONG_KEY, &response); + + readValue = response.value; + + ASSERT_FALSE(readRet.isOk()); + ASSERT_EQ(EX_SERVICE_SPECIFIC, readRet.getExceptionCode()); + ASSERT_EQ(IWeaver::INCORRECT_KEY, readRet.getServiceSpecificError()); + EXPECT_TRUE(readValue.empty()); +} + +/* + * Writing to an invalid slot fails + */ +TEST_P(WeaverAidlTest, WritingToInvalidSlotFails) { + WeaverConfig config; + const auto configRet = weaver->getConfig(&config); + ASSERT_TRUE(configRet.isOk()); + + if (config.slots == std::numeric_limits<uint32_t>::max()) { + // If there are no invalid slots then pass + return; + } + + const auto writeRet = weaver->write(config.slots, KEY, VALUE); + ASSERT_FALSE(writeRet.isOk()); +} + +/* + * Reading from an invalid slot fails rather than incorrect key + */ +TEST_P(WeaverAidlTest, ReadingFromInvalidSlotFails) { + WeaverConfig config; + const auto configRet = weaver->getConfig(&config); + ASSERT_TRUE(configRet.isOk()); + + if (config.slots == std::numeric_limits<uint32_t>::max()) { + // If there are no invalid slots then pass + return; + } + + WeaverReadResponse response; + std::vector<uint8_t> readValue; + uint32_t timeout; + const auto readRet = + weaver->read(config.slots, KEY, &response); + + readValue = response.value; + timeout = response.timeout; + + ASSERT_FALSE(readRet.isOk()); + ASSERT_EQ(EX_SERVICE_SPECIFIC, readRet.getExceptionCode()); + ASSERT_EQ(IWeaver::STATUS_FAILED, readRet.getServiceSpecificError()); + EXPECT_TRUE(readValue.empty()); + EXPECT_EQ(timeout, 0u); +} + +/* + * Writing a key that is too large fails + */ +TEST_P(WeaverAidlTest, WriteWithTooLargeKeyFails) { + WeaverConfig config; + const auto configRet = weaver->getConfig(&config); + ASSERT_TRUE(configRet.isOk()); + + std::vector<uint8_t> bigKey(config.keySize + 1); + + constexpr uint32_t slotId = 0; + const auto writeRet = weaver->write(slotId, bigKey, VALUE); + ASSERT_FALSE(writeRet.isOk()); +} + +/* + * Writing a value that is too large fails + */ +TEST_P(WeaverAidlTest, WriteWithTooLargeValueFails) { + WeaverConfig config; + const auto configRet = weaver->getConfig(&config); + ASSERT_TRUE(configRet.isOk()); + + std::vector<uint8_t> bigValue(config.valueSize + 1); + + constexpr uint32_t slotId = 0; + const auto writeRet = weaver->write(slotId, KEY, bigValue); + ASSERT_FALSE(writeRet.isOk()); +} + +/* + * Reading with a key that is loo large fails + */ +TEST_P(WeaverAidlTest, ReadWithTooLargeKeyFails) { + WeaverConfig config; + const auto configRet = weaver->getConfig(&config); + ASSERT_TRUE(configRet.isOk()); + + std::vector<uint8_t> bigKey(config.keySize + 1); + + constexpr uint32_t slotId = 0; + WeaverReadResponse response; + std::vector<uint8_t> readValue; + uint32_t timeout; + const auto readRet = + weaver->read(slotId, bigKey, &response); + + readValue = response.value; + timeout = response.timeout; + + ASSERT_FALSE(readRet.isOk()); + ASSERT_EQ(EX_SERVICE_SPECIFIC, readRet.getExceptionCode()); + ASSERT_EQ(IWeaver::STATUS_FAILED, readRet.getServiceSpecificError()); + EXPECT_TRUE(readValue.empty()); + EXPECT_EQ(timeout, 0u); +} + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WeaverAidlTest); +INSTANTIATE_TEST_SUITE_P( + PerInstance, WeaverAidlTest, + testing::ValuesIn(android::getAidlHalInstanceNames(IWeaver::descriptor)), + android::PrintInstanceNameToString); + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + ABinderProcess_setThreadPoolMaxThreadCount(1); + ABinderProcess_startThreadPool(); + return RUN_ALL_TESTS(); +} diff --git a/wifi/1.5/IWifiApIface.hal b/wifi/1.5/IWifiApIface.hal index 9625a6b712..c638f1d570 100644 --- a/wifi/1.5/IWifiApIface.hal +++ b/wifi/1.5/IWifiApIface.hal @@ -37,4 +37,18 @@ interface IWifiApIface extends @1.4::IWifiApIface { * |WifiStatusCode.ERROR_UNKNOWN| */ resetToFactoryMacAddress() generates (WifiStatus status); + + /** + * Get the names of the bridged AP instances. + * + * @return status WifiStatus of the operation + * Possible status codes: + * |WifiStatusCode.SUCCESS|, + * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|, + * |WifiStatusCode.ERROR_UNKNOWN| + * + * @return instances A vector which contains the names of the bridged AP + * instances. Note: Returns an empty vector for a non-bridged AP. + */ + getBridgedInstances() generates (WifiStatus status, vec<string> instances); }; diff --git a/wifi/1.5/IWifiChip.hal b/wifi/1.5/IWifiChip.hal index b2960cfa7a..209190a759 100644 --- a/wifi/1.5/IWifiChip.hal +++ b/wifi/1.5/IWifiChip.hal @@ -234,4 +234,33 @@ interface IWifiChip extends @1.4::IWifiChip { * |WifiStatusCode.FAILURE_IFACE_INVALID| */ setCountryCode(int8_t[2] code) generates (WifiStatus status); + + /** + * Retrieve list of usable Wifi channels for the specified band & + * operational modes. + * + * The list of usable Wifi channels in a given band depends on factors + * like current country code, operational mode (e.g. STA, SAP, CLI, GO, + * TDLS, NAN) and any hard restrictons due to DFS, LTE Coex and + * MCC(multi channel-concurrency). + * + * @param band |WifiBand| for which list of usable channels is requested. + * @param ifaceModeMask Bitmask of the modes represented by |WifiIfaceMode| + * Bitmask respresents all the modes that the caller is interested + * in (e.g. STA, SAP, CLI, GO, TDLS, NAN). + * Note: Bitmask does not represent concurrency matrix. + * @return status WifiStatus of the operation. + * Possible status codes: + * |WifiStatusCode.SUCCESS|, + * |WifiStatusCode.ERROR_NOT_SUPPORTED|, + * |WifiStatusCode.ERROR_INVALID_ARGS|, + * |WifiStatusCode.FAILURE_UNKNOWN| + * @return channels List of channels represented by |WifiUsableChannel| + * Each entry represents a channel frequency, bandwidth and + * bitmask of operational modes (e.g. STA, SAP, CLI, GO, TDLS, NAN) + * allowed on that channel. + * Note: Bitmask does not represent concurrency matrix. + */ + getUsableChannels(WifiBand band, bitfield<WifiIfaceMode> ifaceModeMask) + generates (WifiStatus status, vec<WifiUsableChannel> channels); }; diff --git a/wifi/1.5/IWifiStaIface.hal b/wifi/1.5/IWifiStaIface.hal index e9d411e00b..daf545eb9c 100644 --- a/wifi/1.5/IWifiStaIface.hal +++ b/wifi/1.5/IWifiStaIface.hal @@ -41,4 +41,17 @@ interface IWifiStaIface extends @1.3::IWifiStaIface { * @return stats Instance of |LinkLayerStats|. */ getLinkLayerStats_1_5() generates (WifiStatus status, StaLinkLayerStats stats); + + /** + * Turn on/off scan only mode for the interface. + * + * @param enable Indicate if scan only mode is to be turned on/off. + * @return status Status of the operation. + * Possible status codes: + * |WifiStatusCode.SUCCESS|, + * |WifiStatusCode.ERROR_NOT_SUPPORTED|, + * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|, + * |WifiStatusCode.FAILURE_UNKNOWN| + */ + setScanMode(bool enable) generates (WifiStatus status); }; diff --git a/wifi/1.5/default/hidl_struct_util.cpp b/wifi/1.5/default/hidl_struct_util.cpp index 29500799a4..d44b7b34d2 100644 --- a/wifi/1.5/default/hidl_struct_util.cpp +++ b/wifi/1.5/default/hidl_struct_util.cpp @@ -354,6 +354,129 @@ bool convertLegacyWifiMacInfoToHidl( return true; } +uint32_t convertHidlWifiBandToLegacyMacBand(V1_5::WifiBand hidl_band) { + switch (hidl_band) { + case V1_5::WifiBand::BAND_24GHZ: + return legacy_hal::WLAN_MAC_2_4_BAND; + case V1_5::WifiBand::BAND_5GHZ: + case V1_5::WifiBand::BAND_5GHZ_DFS: + case V1_5::WifiBand::BAND_5GHZ_WITH_DFS: + return legacy_hal::WLAN_MAC_5_0_BAND; + case V1_5::WifiBand::BAND_24GHZ_5GHZ: + case V1_5::WifiBand::BAND_24GHZ_5GHZ_WITH_DFS: + return (legacy_hal::WLAN_MAC_2_4_BAND | + legacy_hal::WLAN_MAC_5_0_BAND); + case V1_5::WifiBand::BAND_6GHZ: + return legacy_hal::WLAN_MAC_6_0_BAND; + case V1_5::WifiBand::BAND_5GHZ_6GHZ: + return (legacy_hal::WLAN_MAC_5_0_BAND | + legacy_hal::WLAN_MAC_6_0_BAND); + case V1_5::WifiBand::BAND_24GHZ_5GHZ_6GHZ: + case V1_5::WifiBand::BAND_24GHZ_5GHZ_WITH_DFS_6GHZ: + return (legacy_hal::WLAN_MAC_2_4_BAND | + legacy_hal::WLAN_MAC_5_0_BAND | + legacy_hal::WLAN_MAC_6_0_BAND); + case V1_5::WifiBand::BAND_60GHZ: + return legacy_hal::WLAN_MAC_60_0_BAND; + default: + return ( + legacy_hal::WLAN_MAC_2_4_BAND | legacy_hal::WLAN_MAC_5_0_BAND | + legacy_hal::WLAN_MAC_6_0_BAND | legacy_hal::WLAN_MAC_60_0_BAND); + } +} + +uint32_t convertHidlWifiIfaceModeToLegacy(uint32_t hidl_iface_mask) { + uint32_t legacy_iface_mask = 0; + if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_STA) { + legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_STA); + } + if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_SOFTAP) { + legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_SOFTAP); + } + if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_P2P_CLIENT) { + legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_P2P_CLIENT); + } + if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_P2P_GO) { + legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_P2P_GO); + } + if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_NAN) { + legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_NAN); + } + if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_TDLS) { + legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_TDLS); + } + if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_MESH) { + legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_MESH); + } + if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_IBSS) { + legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_IBSS); + } + return legacy_iface_mask; +} + +uint32_t convertLegacyWifiInterfaceModeToHidl(uint32_t legacy_iface_mask) { + uint32_t hidl_iface_mask = 0; + if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_STA)) { + hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_STA; + } + if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_SOFTAP)) { + hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_SOFTAP; + } + if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_P2P_CLIENT)) { + hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_P2P_CLIENT; + } + if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_P2P_GO)) { + hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_P2P_GO; + } + if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_NAN)) { + hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_NAN; + } + if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_TDLS)) { + hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_TDLS; + } + if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_MESH)) { + hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_MESH; + } + if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_IBSS)) { + hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_IBSS; + } + return hidl_iface_mask; +} + +bool convertLegacyWifiUsableChannelToHidl( + const legacy_hal::wifi_usable_channel& legacy_usable_channel, + V1_5::WifiUsableChannel* hidl_usable_channel) { + if (!hidl_usable_channel) { + return false; + } + *hidl_usable_channel = {}; + hidl_usable_channel->channel = legacy_usable_channel.freq; + hidl_usable_channel->channelBandwidth = + convertLegacyWifiChannelWidthToHidl(legacy_usable_channel.width); + hidl_usable_channel->ifaceModeMask = convertLegacyWifiInterfaceModeToHidl( + legacy_usable_channel.iface_mode_mask); + + return true; +} + +bool convertLegacyWifiUsableChannelsToHidl( + const std::vector<legacy_hal::wifi_usable_channel>& legacy_usable_channels, + std::vector<V1_5::WifiUsableChannel>* hidl_usable_channels) { + if (!hidl_usable_channels) { + return false; + } + *hidl_usable_channels = {}; + for (const auto& legacy_usable_channel : legacy_usable_channels) { + V1_5::WifiUsableChannel hidl_usable_channel; + if (!convertLegacyWifiUsableChannelToHidl(legacy_usable_channel, + &hidl_usable_channel)) { + return false; + } + hidl_usable_channels->push_back(hidl_usable_channel); + } + return true; +} + bool convertLegacyWifiMacInfosToHidl( const std::vector<legacy_hal::WifiMacInfo>& legacy_mac_infos, std::vector<V1_4::IWifiChipEventCallback::RadioModeInfo>* diff --git a/wifi/1.5/default/hidl_struct_util.h b/wifi/1.5/default/hidl_struct_util.h index feb47ef7ab..c0d7bf8f0c 100644 --- a/wifi/1.5/default/hidl_struct_util.h +++ b/wifi/1.5/default/hidl_struct_util.h @@ -206,6 +206,11 @@ bool convertLegacyRttCapabilitiesToHidl( bool convertLegacyVectorOfRttResultToHidl( const std::vector<const legacy_hal::wifi_rtt_result*>& legacy_results, std::vector<V1_4::RttResult>* hidl_results); +uint32_t convertHidlWifiBandToLegacyMacBand(V1_5::WifiBand band); +uint32_t convertHidlWifiIfaceModeToLegacy(uint32_t hidl_iface_mask); +bool convertLegacyWifiUsableChannelsToHidl( + const std::vector<legacy_hal::wifi_usable_channel>& legacy_usable_channels, + std::vector<V1_5::WifiUsableChannel>* hidl_usable_channels); } // namespace hidl_struct_util } // namespace implementation } // namespace V1_5 diff --git a/wifi/1.5/default/wifi_ap_iface.cpp b/wifi/1.5/default/wifi_ap_iface.cpp index d98aa4579a..b438a4a832 100644 --- a/wifi/1.5/default/wifi_ap_iface.cpp +++ b/wifi/1.5/default/wifi_ap_iface.cpp @@ -47,6 +47,12 @@ bool WifiApIface::isValid() { return is_valid_; } std::string WifiApIface::getName() { return ifname_; } +void WifiApIface::removeInstance(std::string instance) { + instances_.erase( + std::remove(instances_.begin(), instances_.end(), instance), + instances_.end()); +} + Return<void> WifiApIface::getName(getName_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, &WifiApIface::getNameInternal, hidl_status_cb); @@ -93,6 +99,13 @@ Return<void> WifiApIface::resetToFactoryMacAddress( hidl_status_cb); } +Return<void> WifiApIface::getBridgedInstances( + getBridgedInstances_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiApIface::getBridgedInstancesInternal, + hidl_status_cb); +} + std::pair<WifiStatus, std::string> WifiApIface::getNameInternal() { return {createWifiStatus(WifiStatusCode::SUCCESS), ifname_}; } @@ -178,6 +191,15 @@ WifiStatus WifiApIface::resetToFactoryMacAddressInternal() { } return createWifiStatus(WifiStatusCode::SUCCESS); } + +std::pair<WifiStatus, std::vector<hidl_string>> +WifiApIface::getBridgedInstancesInternal() { + std::vector<hidl_string> instances; + for (const auto& instance_name : instances_) { + instances.push_back(instance_name); + } + return {createWifiStatus(WifiStatusCode::SUCCESS), instances}; +} } // namespace implementation } // namespace V1_5 } // namespace wifi diff --git a/wifi/1.5/default/wifi_ap_iface.h b/wifi/1.5/default/wifi_ap_iface.h index 02fb2d8edc..8f8387deae 100644 --- a/wifi/1.5/default/wifi_ap_iface.h +++ b/wifi/1.5/default/wifi_ap_iface.h @@ -43,6 +43,7 @@ class WifiApIface : public V1_5::IWifiApIface { void invalidate(); bool isValid(); std::string getName(); + void removeInstance(std::string instance); // HIDL methods exposed. Return<void> getName(getName_cb hidl_status_cb) override; @@ -59,6 +60,9 @@ class WifiApIface : public V1_5::IWifiApIface { Return<void> resetToFactoryMacAddress( resetToFactoryMacAddress_cb hidl_status_cb) override; + Return<void> getBridgedInstances( + getBridgedInstances_cb hidl_status_cb) override; + private: // Corresponding worker functions for the HIDL methods. std::pair<WifiStatus, std::string> getNameInternal(); @@ -70,6 +74,8 @@ class WifiApIface : public V1_5::IWifiApIface { std::pair<WifiStatus, std::array<uint8_t, 6>> getFactoryMacAddressInternal( const std::string& ifaceName); WifiStatus resetToFactoryMacAddressInternal(); + std::pair<WifiStatus, std::vector<hidl_string>> + getBridgedInstancesInternal(); std::string ifname_; std::vector<std::string> instances_; diff --git a/wifi/1.5/default/wifi_chip.cpp b/wifi/1.5/default/wifi_chip.cpp index f3d20c8f19..f7c21639f6 100644 --- a/wifi/1.5/default/wifi_chip.cpp +++ b/wifi/1.5/default/wifi_chip.cpp @@ -739,6 +739,14 @@ Return<void> WifiChip::setCountryCode(const hidl_array<int8_t, 2>& code, code); } +Return<void> WifiChip::getUsableChannels( + WifiBand band, hidl_bitfield<WifiIfaceMode> ifaceModeMask, + getUsableChannels_cb _hidl_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::getUsableChannelsInternal, _hidl_cb, band, + ifaceModeMask); +} + void WifiChip::QcRemoveAndClearDynamicIfaces() { for (const auto& iface : created_ap_ifaces_) { std::string ifname = iface->getName(); @@ -1075,7 +1083,6 @@ WifiStatus WifiChip::removeApIfaceInternal(const std::string& ifname) { WifiStatus WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal( const std::string& ifname, const std::string& ifInstanceName) { - legacy_hal::wifi_error legacy_status; const auto iface = findUsingName(ap_ifaces_, ifname); if (!iface.get() || ifInstanceName.empty()) { return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); @@ -1087,13 +1094,13 @@ WifiStatus WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal( if (iface == ifInstanceName) { if (!iface_util_.lock()->removeIfaceFromBridge(it.first, iface)) { - LOG(ERROR) << "Failed to remove interface: " << iface - << " from " << ifname << ", error: " - << legacyErrorToString(legacy_status); + LOG(ERROR) + << "Failed to remove interface: " << ifInstanceName + << " from " << ifname; return createWifiStatus( WifiStatusCode::ERROR_NOT_AVAILABLE); } - legacy_status = + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->deleteVirtualInterface(iface); if (legacy_status != legacy_hal::WIFI_SUCCESS) { LOG(ERROR) << "Failed to del interface: " << iface @@ -1106,6 +1113,7 @@ WifiStatus WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal( } } br_ifaces_ap_instances_.erase(ifInstanceName); + iface->removeInstance(ifInstanceName); return createWifiStatus(WifiStatusCode::SUCCESS); } @@ -1538,6 +1546,25 @@ WifiStatus WifiChip::setCountryCodeInternal(const std::array<int8_t, 2>& code) { return createWifiStatusFromLegacyError(legacy_status); } +std::pair<WifiStatus, std::vector<WifiUsableChannel>> +WifiChip::getUsableChannelsInternal(WifiBand band, uint32_t ifaceModeMask) { + legacy_hal::wifi_error legacy_status; + std::vector<legacy_hal::wifi_usable_channel> legacy_usable_channels; + std::tie(legacy_status, legacy_usable_channels) = + legacy_hal_.lock()->getUsableChannels( + hidl_struct_util::convertHidlWifiBandToLegacyMacBand(band), + hidl_struct_util::convertHidlWifiIfaceModeToLegacy(ifaceModeMask)); + if (legacy_status != legacy_hal::WIFI_SUCCESS) { + return {createWifiStatusFromLegacyError(legacy_status), {}}; + } + std::vector<WifiUsableChannel> hidl_usable_channels; + if (!hidl_struct_util::convertLegacyWifiUsableChannelsToHidl( + legacy_usable_channels, &hidl_usable_channels)) { + return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; + } + return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_usable_channels}; +} + WifiStatus WifiChip::handleChipConfiguration( /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock, ChipModeId mode_id) { diff --git a/wifi/1.5/default/wifi_chip.h b/wifi/1.5/default/wifi_chip.h index 546b27697f..3248222bd7 100644 --- a/wifi/1.5/default/wifi_chip.h +++ b/wifi/1.5/default/wifi_chip.h @@ -180,6 +180,9 @@ class WifiChip : public V1_5::IWifiChip { setCoexUnsafeChannels_cb hidl_status_cb) override; Return<void> setCountryCode(const hidl_array<int8_t, 2>& code, setCountryCode_cb _hidl_cb) override; + Return<void> getUsableChannels(WifiBand band, + hidl_bitfield<WifiIfaceMode> ifaceModeMask, + getUsableChannels_cb _hidl_cb) override; private: void invalidateAndRemoveAllIfaces(); @@ -261,6 +264,8 @@ class WifiChip : public V1_5::IWifiChip { WifiStatus setCoexUnsafeChannelsInternal( std::vector<CoexUnsafeChannel> unsafe_channels, uint32_t restrictions); WifiStatus setCountryCodeInternal(const std::array<int8_t, 2>& code); + std::pair<WifiStatus, std::vector<WifiUsableChannel>> + getUsableChannelsInternal(WifiBand band, uint32_t ifaceModeMask); WifiStatus handleChipConfiguration( std::unique_lock<std::recursive_mutex>* lock, ChipModeId mode_id); WifiStatus registerDebugRingBufferCallback(); diff --git a/wifi/1.5/default/wifi_legacy_hal.cpp b/wifi/1.5/default/wifi_legacy_hal.cpp index 3e65ee0f25..94603b3053 100644 --- a/wifi/1.5/default/wifi_legacy_hal.cpp +++ b/wifi/1.5/default/wifi_legacy_hal.cpp @@ -36,6 +36,7 @@ static constexpr uint32_t kMaxGscanFrequenciesForBand = 64; static constexpr uint32_t kLinkLayerStatsDataMpduSizeThreshold = 128; static constexpr uint32_t kMaxWakeReasonStatsArraySize = 32; static constexpr uint32_t kMaxRingBuffers = 10; +static constexpr uint32_t kMaxWifiUsableChannels = 256; // need a long timeout (1000ms) for chips that unload their driver. static constexpr uint32_t kMaxStopCompleteWaitMs = 1000; static constexpr char kDriverPropName[] = "wlan.driver.status"; @@ -1636,6 +1637,19 @@ wifi_error WifiLegacyHal::setDtimConfig(const std::string& iface_name, multiplier); } +std::pair<wifi_error, std::vector<wifi_usable_channel>> +WifiLegacyHal::getUsableChannels(uint32_t band_mask, uint32_t iface_mode_mask) { + std::vector<wifi_usable_channel> channels; + channels.resize(kMaxWifiUsableChannels); + uint32_t size = 0; + wifi_error status = global_func_table_.wifi_get_usable_channels( + global_handle_, band_mask, iface_mode_mask, channels.size(), &size, + reinterpret_cast<wifi_usable_channel*>(channels.data())); + CHECK(size >= 0 && size <= kMaxWifiUsableChannels); + channels.resize(size); + return {status, std::move(channels)}; +} + void WifiLegacyHal::invalidate() { global_handle_ = nullptr; iface_name_to_handle_.clear(); diff --git a/wifi/1.5/default/wifi_legacy_hal.h b/wifi/1.5/default/wifi_legacy_hal.h index 0cc1cff8cf..dc641aef28 100644 --- a/wifi/1.5/default/wifi_legacy_hal.h +++ b/wifi/1.5/default/wifi_legacy_hal.h @@ -36,9 +36,13 @@ namespace implementation { namespace legacy_hal { // Import all the types defined inside the legacy HAL header files into this // namespace. +using ::frame_info; +using ::frame_type; using ::FRAME_TYPE_80211_MGMT; using ::FRAME_TYPE_ETHERNET_II; using ::FRAME_TYPE_UNKNOWN; +using ::fw_roaming_state_t; +using ::mac_addr; using ::NAN_CHANNEL_24G_BAND; using ::NAN_CHANNEL_5G_BAND_HIGH; using ::NAN_CHANNEL_5G_BAND_LOW; @@ -80,8 +84,6 @@ using ::NAN_RESPONSE_SUBSCRIBE_CANCEL; using ::NAN_RESPONSE_TCA; using ::NAN_RESPONSE_TRANSMIT_FOLLOWUP; using ::NAN_SECURITY_KEY_INPUT_PASSPHRASE; -using ::NAN_SECURITY_KEY_INPUT_PASSPHRASE; -using ::NAN_SECURITY_KEY_INPUT_PMK; using ::NAN_SECURITY_KEY_INPUT_PMK; using ::NAN_SERVICE_ACCEPT_POLICY_ALL; using ::NAN_SERVICE_ACCEPT_POLICY_NONE; @@ -154,19 +156,20 @@ using ::RTT_PEER_NAN; using ::RTT_PEER_P2P_CLIENT; using ::RTT_PEER_P2P_GO; using ::RTT_PEER_STA; +using ::rtt_peer_type; using ::RTT_STATUS_ABORTED; -using ::RTT_STATUS_FAILURE; using ::RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL; using ::RTT_STATUS_FAIL_BUSY_TRY_LATER; using ::RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE; using ::RTT_STATUS_FAIL_INVALID_TS; -using ::RTT_STATUS_FAIL_NOT_SCHEDULED_YET; using ::RTT_STATUS_FAIL_NO_CAPABILITY; using ::RTT_STATUS_FAIL_NO_RSP; +using ::RTT_STATUS_FAIL_NOT_SCHEDULED_YET; using ::RTT_STATUS_FAIL_PROTOCOL; using ::RTT_STATUS_FAIL_REJECTED; using ::RTT_STATUS_FAIL_SCHEDULE; using ::RTT_STATUS_FAIL_TM_TIMEOUT; +using ::RTT_STATUS_FAILURE; using ::RTT_STATUS_INVALID_REQ; using ::RTT_STATUS_NAN_RANGING_CONCURRENCY_NOT_SUPPORTED; using ::RTT_STATUS_NAN_RANGING_PROTOCOL_FAILURE; @@ -185,6 +188,8 @@ using ::RX_PKT_FATE_FW_DROP_NOBUFS; using ::RX_PKT_FATE_FW_DROP_OTHER; using ::RX_PKT_FATE_FW_QUEUED; using ::RX_PKT_FATE_SUCCESS; +using ::ssid_t; +using ::transaction_id; using ::TX_PKT_FATE_ACKED; using ::TX_PKT_FATE_DRV_DROP_INVALID; using ::TX_PKT_FATE_DRV_DROP_NOBUFS; @@ -199,24 +204,31 @@ using ::WIFI_AC_BE; using ::WIFI_AC_BK; using ::WIFI_AC_VI; using ::WIFI_AC_VO; +using ::wifi_band; using ::WIFI_BAND_A; -using ::WIFI_BAND_ABG; -using ::WIFI_BAND_ABG_WITH_DFS; using ::WIFI_BAND_A_DFS; using ::WIFI_BAND_A_WITH_DFS; +using ::WIFI_BAND_ABG; +using ::WIFI_BAND_ABG_WITH_DFS; using ::WIFI_BAND_BG; using ::WIFI_BAND_UNSPECIFIED; +using ::wifi_cached_scan_results; using ::WIFI_CHAN_WIDTH_10; using ::WIFI_CHAN_WIDTH_160; using ::WIFI_CHAN_WIDTH_20; using ::WIFI_CHAN_WIDTH_40; using ::WIFI_CHAN_WIDTH_5; -using ::WIFI_CHAN_WIDTH_5; using ::WIFI_CHAN_WIDTH_80; using ::WIFI_CHAN_WIDTH_80P80; using ::WIFI_CHAN_WIDTH_INVALID; +using ::wifi_channel_info; +using ::wifi_channel_stat; +using ::wifi_channel_width; +using ::wifi_coex_restriction; +using ::wifi_coex_unsafe_channel; using ::WIFI_DUAL_STA_NON_TRANSIENT_UNBIASED; using ::WIFI_DUAL_STA_TRANSIENT_PREFER_PRIMARY; +using ::wifi_error; using ::WIFI_ERROR_BUSY; using ::WIFI_ERROR_INVALID_ARGS; using ::WIFI_ERROR_INVALID_REQUEST_ID; @@ -228,12 +240,29 @@ using ::WIFI_ERROR_TIMED_OUT; using ::WIFI_ERROR_TOO_MANY_REQUESTS; using ::WIFI_ERROR_UNINITIALIZED; using ::WIFI_ERROR_UNKNOWN; +using ::wifi_gscan_capabilities; +using ::wifi_hal_fn; +using ::wifi_information_element; +using ::WIFI_INTERFACE_IBSS; +using ::WIFI_INTERFACE_MESH; +using ::wifi_interface_mode; +using ::WIFI_INTERFACE_NAN; +using ::WIFI_INTERFACE_P2P_CLIENT; +using ::WIFI_INTERFACE_P2P_GO; +using ::WIFI_INTERFACE_SOFTAP; +using ::WIFI_INTERFACE_STA; +using ::WIFI_INTERFACE_TDLS; +using ::wifi_interface_type; using ::WIFI_INTERFACE_TYPE_AP; using ::WIFI_INTERFACE_TYPE_NAN; using ::WIFI_INTERFACE_TYPE_P2P; using ::WIFI_INTERFACE_TYPE_STA; +using ::WIFI_INTERFACE_UNKNOWN; +using ::wifi_latency_mode; using ::WIFI_LATENCY_MODE_LOW; using ::WIFI_LATENCY_MODE_NORMAL; +using ::wifi_lci_information; +using ::wifi_lcr_information; using ::WIFI_LOGGER_CONNECT_EVENT_SUPPORTED; using ::WIFI_LOGGER_DRIVER_DUMP_SUPPORTED; using ::WIFI_LOGGER_MEMORY_DUMP_SUPPORTED; @@ -242,61 +271,34 @@ using ::WIFI_LOGGER_POWER_EVENT_SUPPORTED; using ::WIFI_LOGGER_WAKE_LOCK_SUPPORTED; using ::WIFI_MOTION_EXPECTED; using ::WIFI_MOTION_NOT_EXPECTED; +using ::wifi_motion_pattern; using ::WIFI_MOTION_UNKNOWN; +using ::wifi_multi_sta_use_case; +using ::wifi_power_scenario; using ::WIFI_POWER_SCENARIO_ON_BODY_CELL_OFF; using ::WIFI_POWER_SCENARIO_ON_BODY_CELL_ON; using ::WIFI_POWER_SCENARIO_ON_HEAD_CELL_OFF; using ::WIFI_POWER_SCENARIO_ON_HEAD_CELL_ON; using ::WIFI_POWER_SCENARIO_VOICE_CALL; +using ::wifi_rate; +using ::wifi_request_id; +using ::wifi_ring_buffer_status; +using ::wifi_roaming_capabilities; +using ::wifi_roaming_config; +using ::wifi_rtt_bw; using ::WIFI_RTT_BW_10; using ::WIFI_RTT_BW_160; using ::WIFI_RTT_BW_20; using ::WIFI_RTT_BW_40; using ::WIFI_RTT_BW_5; using ::WIFI_RTT_BW_80; +using ::wifi_rtt_capabilities; +using ::wifi_rtt_config; +using ::wifi_rtt_preamble; using ::WIFI_RTT_PREAMBLE_HE; using ::WIFI_RTT_PREAMBLE_HT; using ::WIFI_RTT_PREAMBLE_LEGACY; using ::WIFI_RTT_PREAMBLE_VHT; -using ::WIFI_SCAN_FLAG_INTERRUPTED; -using ::WIFI_SUCCESS; -using ::WLAN_MAC_2_4_BAND; -using ::WLAN_MAC_5_0_BAND; -using ::WLAN_MAC_6_0_BAND; -using ::frame_info; -using ::frame_type; -using ::fw_roaming_state_t; -using ::mac_addr; -using ::rtt_peer_type; -using ::ssid_t; -using ::transaction_id; -using ::wifi_band; -using ::wifi_cached_scan_results; -using ::wifi_channel_info; -using ::wifi_channel_stat; -using ::wifi_channel_width; -using ::wifi_coex_restriction; -using ::wifi_coex_unsafe_channel; -using ::wifi_error; -using ::wifi_gscan_capabilities; -using ::wifi_hal_fn; -using ::wifi_information_element; -using ::wifi_interface_type; -using ::wifi_latency_mode; -using ::wifi_lci_information; -using ::wifi_lcr_information; -using ::wifi_motion_pattern; -using ::wifi_multi_sta_use_case; -using ::wifi_power_scenario; -using ::wifi_rate; -using ::wifi_request_id; -using ::wifi_ring_buffer_status; -using ::wifi_roaming_capabilities; -using ::wifi_roaming_config; -using ::wifi_rtt_bw; -using ::wifi_rtt_capabilities; -using ::wifi_rtt_config; -using ::wifi_rtt_preamble; using ::wifi_rtt_responder; using ::wifi_rtt_result; using ::wifi_rtt_status; @@ -305,9 +307,16 @@ using ::wifi_rx_packet_fate; using ::wifi_rx_report; using ::wifi_scan_bucket_spec; using ::wifi_scan_cmd_params; +using ::WIFI_SCAN_FLAG_INTERRUPTED; using ::wifi_scan_result; +using ::WIFI_SUCCESS; using ::wifi_tx_packet_fate; using ::wifi_tx_report; +using ::wifi_usable_channel; +using ::WLAN_MAC_2_4_BAND; +using ::WLAN_MAC_5_0_BAND; +using ::WLAN_MAC_60_0_BAND; +using ::WLAN_MAC_6_0_BAND; // APF capabilities supported by the iface. struct PacketFilterCapabilities { @@ -693,6 +702,11 @@ class WifiLegacyHal { wifi_error setDtimConfig(const std::string& iface_name, uint32_t multiplier); + // Retrieve the list of usable channels in the requested bands + // for the requested modes + std::pair<wifi_error, std::vector<wifi_usable_channel>> getUsableChannels( + uint32_t band_mask, uint32_t iface_mode_mask); + private: // Retrieve interface handles for all the available interfaces. wifi_error retrieveIfaceHandles(); diff --git a/wifi/1.5/default/wifi_legacy_hal_stubs.cpp b/wifi/1.5/default/wifi_legacy_hal_stubs.cpp index 7ba5d9b804..6212960d7a 100644 --- a/wifi/1.5/default/wifi_legacy_hal_stubs.cpp +++ b/wifi/1.5/default/wifi_legacy_hal_stubs.cpp @@ -159,6 +159,7 @@ bool initHalFuncTableWithStubs(wifi_hal_fn* hal_fn) { populateStubFor(&hal_fn->wifi_twt_get_stats); populateStubFor(&hal_fn->wifi_twt_clear_stats); populateStubFor(&hal_fn->wifi_set_dtim_config); + populateStubFor(&hal_fn->wifi_get_usable_channels); return true; } } // namespace legacy_hal diff --git a/wifi/1.5/default/wifi_sta_iface.cpp b/wifi/1.5/default/wifi_sta_iface.cpp index 82bfcf15bb..92c9fe4392 100644 --- a/wifi/1.5/default/wifi_sta_iface.cpp +++ b/wifi/1.5/default/wifi_sta_iface.cpp @@ -273,6 +273,13 @@ Return<void> WifiStaIface::getFactoryMacAddress( hidl_status_cb); } +Return<void> WifiStaIface::setScanMode(bool enable, + setScanMode_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiStaIface::setScanModeInternal, hidl_status_cb, + enable); +} + std::pair<WifiStatus, std::string> WifiStaIface::getNameInternal() { return {createWifiStatus(WifiStatusCode::SUCCESS), ifname_}; } @@ -655,6 +662,12 @@ WifiStaIface::getFactoryMacAddressInternal() { return {createWifiStatus(WifiStatusCode::SUCCESS), mac}; } +WifiStatus WifiStaIface::setScanModeInternal(bool enable) { + // OEM's need to implement this on their devices if needed. + LOG(WARNING) << "setScanModeInternal(" << enable << ") not supported"; + return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); +} + } // namespace implementation } // namespace V1_5 } // namespace wifi diff --git a/wifi/1.5/default/wifi_sta_iface.h b/wifi/1.5/default/wifi_sta_iface.h index 94873c9494..f9058b8af1 100644 --- a/wifi/1.5/default/wifi_sta_iface.h +++ b/wifi/1.5/default/wifi_sta_iface.h @@ -114,6 +114,8 @@ class WifiStaIface : public V1_5::IWifiStaIface { setMacAddress_cb hidl_status_cb) override; Return<void> getFactoryMacAddress( getFactoryMacAddress_cb hidl_status_cb) override; + Return<void> setScanMode(bool enable, + setScanMode_cb hidl_status_cb) override; private: // Corresponding worker functions for the HIDL methods. @@ -164,6 +166,7 @@ class WifiStaIface : public V1_5::IWifiStaIface { WifiStatus setMacAddressInternal(const std::array<uint8_t, 6>& mac); std::pair<WifiStatus, std::array<uint8_t, 6>> getFactoryMacAddressInternal(); + WifiStatus setScanModeInternal(bool enable); std::string ifname_; std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_; diff --git a/wifi/1.5/types.hal b/wifi/1.5/types.hal index 9fa5c800c0..4dff77443e 100644 --- a/wifi/1.5/types.hal +++ b/wifi/1.5/types.hal @@ -24,6 +24,8 @@ import @1.0::NanCipherSuiteType; import @1.0::NanCapabilities; import @1.2::NanConfigRequestSupplemental; import @1.3::StaLinkLayerRadioStats; +import @1.0::WifiChannelInMhz; +import @1.0::WifiChannelWidthInMhz; /** * Wifi bands defined in 80211 spec. @@ -44,6 +46,64 @@ enum WifiBand : @1.4::WifiBand { }; /** + * Interface operating modes. + */ +enum WifiIfaceMode : uint32_t { + /** + * Interface operation mode is client. + */ + IFACE_MODE_STA = 1 << 0, + /** + * Interface operation mode is Hotspot. + */ + IFACE_MODE_SOFTAP = 1 << 1, + /** + * Interface operation mode is Ad-Hoc network. + */ + IFACE_MODE_IBSS = 1 << 2, + /** + * Interface operation mode is Wifi Direct Client. + */ + IFACE_MODE_P2P_CLIENT = 1 << 3, + /** + * Interface operation mode is Wifi Direct Group Owner. + */ + IFACE_MODE_P2P_GO = 1 << 4, + /** + * Interface operation mode is Aware. + */ + IFACE_MODE_NAN = 1 << 5, + /** + * Interface operation mode is Mesh network. + */ + IFACE_MODE_MESH = 1 << 6, + /** + * Interface operation mode is Tunneled Direct Link Setup. + */ + IFACE_MODE_TDLS = 1 << 7, +}; + +/** + * Wifi usable channel information. + */ +struct WifiUsableChannel { + /** + * Wifi channel freqeuncy in MHz. + */ + WifiChannelInMhz channel; + + /** + * Wifi channel bandwidth in MHz. + */ + WifiChannelWidthInMhz channelBandwidth; + + /** + * Iface modes feasible on this channel. + */ + bitfield<WifiIfaceMode> ifaceModeMask; +}; + +/** * NAN configuration request parameters added in the 1.2 HAL. These are supplemental to previous * versions. */ diff --git a/wifi/1.5/vts/functional/wifi_ap_iface_hidl_test.cpp b/wifi/1.5/vts/functional/wifi_ap_iface_hidl_test.cpp index e47b14df1e..424f9345f8 100644 --- a/wifi/1.5/vts/functional/wifi_ap_iface_hidl_test.cpp +++ b/wifi/1.5/vts/functional/wifi_ap_iface_hidl_test.cpp @@ -67,8 +67,8 @@ class WifiApIfaceHidlTest : public ::testing::TestWithParam<std::string> { std::string GetInstanceName() { return GetParam(); } }; -/* - * resetToFactoryMacAddress +/** + * resetToFactoryMacAddress in bridged AP mode. */ TEST_P(WifiApIfaceHidlTest, resetToFactoryMacAddressInBridgedModeTest) { if (!isBridgedSupport_) GTEST_SKIP() << "Missing Bridged AP support"; @@ -79,8 +79,8 @@ TEST_P(WifiApIfaceHidlTest, resetToFactoryMacAddressInBridgedModeTest) { EXPECT_EQ(WifiStatusCode::SUCCESS, status.code); } -/* - * resetToFactoryMacAddress +/** + * resetToFactoryMacAddress in non-bridged mode */ TEST_P(WifiApIfaceHidlTest, resetToFactoryMacAddressTest) { sp<IWifiApIface> wifi_ap_iface = getWifiApIface_1_5(GetInstanceName()); @@ -89,6 +89,34 @@ TEST_P(WifiApIfaceHidlTest, resetToFactoryMacAddressTest) { EXPECT_EQ(WifiStatusCode::SUCCESS, status.code); } +/** + * getBridgedInstances in non-bridged mode + */ +TEST_P(WifiApIfaceHidlTest, getBridgedInstancesTest) { + sp<IWifiApIface> wifi_ap_iface = getWifiApIface_1_5(GetInstanceName()); + ASSERT_NE(nullptr, wifi_ap_iface.get()); + const auto& status_and_instances = + HIDL_INVOKE(wifi_ap_iface, getBridgedInstances); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_instances.first.code); + const auto& instances = status_and_instances.second; + EXPECT_EQ(0, instances.size()); +} + +/** + * getBridgedInstances in bridged AP mode. + */ +TEST_P(WifiApIfaceHidlTest, getBridgedInstancesInBridgedModeTest) { + if (!isBridgedSupport_) GTEST_SKIP() << "Missing Bridged AP support"; + sp<IWifiApIface> wifi_ap_iface = + getBridgedWifiApIface_1_5(GetInstanceName()); + ASSERT_NE(nullptr, wifi_ap_iface.get()); + const auto& status_and_instances = + HIDL_INVOKE(wifi_ap_iface, getBridgedInstances); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_instances.first.code); + const auto& instances = status_and_instances.second; + EXPECT_EQ(2, instances.size()); +} + GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiApIfaceHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, WifiApIfaceHidlTest, diff --git a/wifi/1.5/vts/functional/wifi_chip_hidl_ap_test.cpp b/wifi/1.5/vts/functional/wifi_chip_hidl_ap_test.cpp index 922c9a767a..d6a040852e 100644 --- a/wifi/1.5/vts/functional/wifi_chip_hidl_ap_test.cpp +++ b/wifi/1.5/vts/functional/wifi_chip_hidl_ap_test.cpp @@ -101,14 +101,23 @@ TEST_P(WifiChipHidlTest, ASSERT_NE(nullptr, wifi_ap_iface.get()); const auto& status_and_name = HIDL_INVOKE(wifi_ap_iface, getName); EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_name.first.code); - // TODO: b/173999527, add API to get instance name to replace it. - std::string br_name = status_and_name.second; // ap_br_ is the pre-fix - std::string instance_name = - br_name.substr(6, br_name.length()); // remove the pre-fex + std::string br_name = status_and_name.second; + const auto& status_and_instances = + HIDL_INVOKE(wifi_ap_iface, getBridgedInstances); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_instances.first.code); + const auto& instances = status_and_instances.second; + EXPECT_EQ(2, instances.size()); const auto& status_code = HIDL_INVOKE(wifi_chip_, removeIfaceInstanceFromBridgedApIface, br_name, - instance_name); + instances[0]); EXPECT_EQ(WifiStatusCode::SUCCESS, status_code.code); + const auto& status_and_instances_after_remove = + HIDL_INVOKE(wifi_ap_iface, getBridgedInstances); + EXPECT_EQ(WifiStatusCode::SUCCESS, + status_and_instances_after_remove.first.code); + const auto& instances_after_remove = + status_and_instances_after_remove.second; + EXPECT_EQ(1, instances_after_remove.size()); } GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiChipHidlTest); diff --git a/wifi/1.5/vts/functional/wifi_chip_hidl_test.cpp b/wifi/1.5/vts/functional/wifi_chip_hidl_test.cpp index 36a8448d04..509f1bddc7 100644 --- a/wifi/1.5/vts/functional/wifi_chip_hidl_test.cpp +++ b/wifi/1.5/vts/functional/wifi_chip_hidl_test.cpp @@ -45,6 +45,7 @@ using ::android::hardware::wifi::V1_0::WifiStatusCode; using ::android::hardware::wifi::V1_4::IWifiChipEventCallback; using ::android::hardware::wifi::V1_5::IWifiChip; using ::android::hardware::wifi::V1_5::WifiBand; +using ::android::hardware::wifi::V1_5::WifiIfaceMode; /** * Fixture to use for all Wifi chip HIDL interface tests. @@ -187,6 +188,23 @@ TEST_P(WifiChipHidlTest, setCountryCode) { HIDL_INVOKE(wifi_chip_, setCountryCode, kCountryCode).code); } +/* getUsableChannels: + * Ensure that a call to getUsableChannels will return with a success + * status for valid inputs. + */ +TEST_P(WifiChipHidlTest, getUsableChannels) { + uint32_t ifaceModeMask = + WifiIfaceMode::IFACE_MODE_P2P_CLIENT | WifiIfaceMode::IFACE_MODE_P2P_GO; + configureChipForIfaceType(IfaceType::STA, true); + WifiBand band = WifiBand::BAND_24GHZ_5GHZ_6GHZ; + const auto& statusNonEmpty = + HIDL_INVOKE(wifi_chip_, getUsableChannels, band, ifaceModeMask); + if (statusNonEmpty.first.code != WifiStatusCode::SUCCESS) { + EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, + statusNonEmpty.first.code); + } +} + GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiChipHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, WifiChipHidlTest, diff --git a/wifi/1.5/vts/functional/wifi_sta_iface_hidl_test.cpp b/wifi/1.5/vts/functional/wifi_sta_iface_hidl_test.cpp index 8cc3300324..399307ecdc 100644 --- a/wifi/1.5/vts/functional/wifi_sta_iface_hidl_test.cpp +++ b/wifi/1.5/vts/functional/wifi_sta_iface_hidl_test.cpp @@ -108,6 +108,19 @@ TEST_P(WifiStaIfaceHidlTest, GetLinkLayerStats_1_5) { WifiStatusCode::SUCCESS, HIDL_INVOKE(wifi_sta_iface_, disableLinkLayerStatsCollection).code); } +/** + * SetScanMode + */ +TEST_P(WifiStaIfaceHidlTest, SetScanMode) { + auto statusCode = + HIDL_INVOKE(wifi_sta_iface_, setScanMode, true).code; + EXPECT_TRUE(statusCode == WifiStatusCode::SUCCESS || + statusCode == WifiStatusCode::ERROR_NOT_SUPPORTED); + + statusCode = HIDL_INVOKE(wifi_sta_iface_, setScanMode, false).code; + EXPECT_TRUE(statusCode == WifiStatusCode::SUCCESS || + statusCode == WifiStatusCode::ERROR_NOT_SUPPORTED); +} GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiStaIfaceHidlTest); INSTANTIATE_TEST_SUITE_P( diff --git a/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp b/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp index 4e63c56d2c..fe9a183d56 100644 --- a/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp +++ b/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp @@ -81,10 +81,9 @@ class HostapdHidlTest virtual void TearDown() override { HIDL_INVOKE_VOID_WITHOUT_ARGUMENTS(hostapd_, terminate); - stopHostapd(wifi_instance_name_); - // Wait 3 seconds to allow driver processing load/unload between two - // test cases. + // Wait 3 seconds to allow terminate processing before kill hostapd. sleep(3); + stopHostapd(wifi_instance_name_); } protected: @@ -106,16 +105,6 @@ class HostapdHidlTest return status_and_name.second; } - // TODO: b/177483254, remove it after fix wlan1 failure case. - 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(std::string iface_name) { ::android::hardware::wifi::hostapd::V1_0::IHostapd::IfaceParams iface_params; @@ -334,9 +323,7 @@ class HostapdHidlTest */ TEST_P(HostapdHidlTest, AddPskAccessPointWithAcs) { if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support"; - // TODO: Use setupApIfaceAndGetName after fixing b/177483254 - // std::string ifname = setupApIfaceAndGetName(false); - std::string ifname = getPrimaryWlanIfaceName(); + std::string ifname = setupApIfaceAndGetName(false); auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithAcs(ifname), getPskNwParams()); EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); @@ -348,9 +335,7 @@ TEST_P(HostapdHidlTest, AddPskAccessPointWithAcs) { */ TEST_P(HostapdHidlTest, AddPskAccessPointWithAcsAndFreqRange) { if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support"; - // TODO: Use setupApIfaceAndGetName after fixing b/177483254 - // std::string ifname = setupApIfaceAndGetName(false); - std::string ifname = getPrimaryWlanIfaceName(); + std::string ifname = setupApIfaceAndGetName(false); auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithAcsAndFreqRange(ifname), getPskNwParams()); @@ -363,9 +348,7 @@ TEST_P(HostapdHidlTest, AddPskAccessPointWithAcsAndFreqRange) { */ TEST_P(HostapdHidlTest, AddPskAccessPointWithAcsAndInvalidFreqRange) { if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support"; - // TODO: Use setupApIfaceAndGetName after fixing b/177483254 - // std::string ifname = setupApIfaceAndGetName(false); - std::string ifname = getPrimaryWlanIfaceName(); + std::string ifname = setupApIfaceAndGetName(false); auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithAcsAndInvalidFreqRange(ifname), getPskNwParams()); @@ -378,9 +361,7 @@ TEST_P(HostapdHidlTest, AddPskAccessPointWithAcsAndInvalidFreqRange) { */ TEST_P(HostapdHidlTest, AddOpenAccessPointWithAcs) { if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support"; - // TODO: Use setupApIfaceAndGetName after fixing b/177483254 - // std::string ifname = setupApIfaceAndGetName(false); - std::string ifname = getPrimaryWlanIfaceName(); + std::string ifname = setupApIfaceAndGetName(false); auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithAcs(ifname), getOpenNwParams()); EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); @@ -391,9 +372,7 @@ TEST_P(HostapdHidlTest, AddOpenAccessPointWithAcs) { * Access point creation should pass. */ TEST_P(HostapdHidlTest, AddPskAccessPointWithoutAcs) { - // TODO: Use setupApIfaceAndGetName after fixing b/177483254 - // std::string ifname = setupApIfaceAndGetName(false); - std::string ifname = getPrimaryWlanIfaceName(); + std::string ifname = setupApIfaceAndGetName(false); auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(ifname), getPskNwParams()); @@ -405,9 +384,7 @@ TEST_P(HostapdHidlTest, AddPskAccessPointWithoutAcs) { * Access point creation should pass. */ TEST_P(HostapdHidlTest, AddPskAccessPointWithoutAcsAndNonMetered) { - // TODO: Use setupApIfaceAndGetName after fixing b/177483254 - // std::string ifname = setupApIfaceAndGetName(false); - std::string ifname = getPrimaryWlanIfaceName(); + std::string ifname = setupApIfaceAndGetName(false); auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(ifname), getPskNwParamsWithNonMetered()); @@ -419,9 +396,7 @@ TEST_P(HostapdHidlTest, AddPskAccessPointWithoutAcsAndNonMetered) { * Access point creation should pass. */ TEST_P(HostapdHidlTest, AddOpenAccessPointWithoutAcs) { - // TODO: Use setupApIfaceAndGetName after fixing b/177483254 - // std::string ifname = setupApIfaceAndGetName(false); - std::string ifname = getPrimaryWlanIfaceName(); + std::string ifname = setupApIfaceAndGetName(false); auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(ifname), getOpenNwParams()); @@ -434,9 +409,7 @@ TEST_P(HostapdHidlTest, AddOpenAccessPointWithoutAcs) { */ TEST_P(HostapdHidlTest, AddSaeTransitionAccessPointWithoutAcs) { if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support"; - // TODO: Use setupApIfaceAndGetName after fixing b/177483254 - // std::string ifname = setupApIfaceAndGetName(false); - std::string ifname = getPrimaryWlanIfaceName(); + std::string ifname = setupApIfaceAndGetName(false); auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(ifname), getSaeTransitionNwParams()); @@ -449,9 +422,7 @@ TEST_P(HostapdHidlTest, AddSaeTransitionAccessPointWithoutAcs) { */ TEST_P(HostapdHidlTest, AddSAEAccessPointWithoutAcs) { if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support"; - // TODO: Use setupApIfaceAndGetName after fixing b/177483254 - // std::string ifname = setupApIfaceAndGetName(false); - std::string ifname = getPrimaryWlanIfaceName(); + std::string ifname = setupApIfaceAndGetName(false); auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(ifname), getSaeNwParams()); @@ -464,9 +435,7 @@ TEST_P(HostapdHidlTest, AddSAEAccessPointWithoutAcs) { */ TEST_P(HostapdHidlTest, RemoveAccessPointWithAcs) { if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support"; - // TODO: Use setupApIfaceAndGetName after fixing b/177483254 - // std::string ifname = setupApIfaceAndGetName(false); - std::string ifname = getPrimaryWlanIfaceName(); + std::string ifname = setupApIfaceAndGetName(false); auto status_1_2 = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithAcs(ifname), getPskNwParams()); @@ -482,9 +451,7 @@ TEST_P(HostapdHidlTest, RemoveAccessPointWithAcs) { * Access point creation & removal should pass. */ TEST_P(HostapdHidlTest, RemoveAccessPointWithoutAcs) { - // TODO: Use setupApIfaceAndGetName after fixing b/177483254 - // std::string ifname = setupApIfaceAndGetName(false); - std::string ifname = getPrimaryWlanIfaceName(); + std::string ifname = setupApIfaceAndGetName(false); auto status_1_2 = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(ifname), getPskNwParams()); @@ -500,9 +467,7 @@ TEST_P(HostapdHidlTest, RemoveAccessPointWithoutAcs) { * Access point creation should fail. */ TEST_P(HostapdHidlTest, AddPskAccessPointWithInvalidChannel) { - // TODO: Use setupApIfaceAndGetName after fixing b/177483254 - // std::string ifname = setupApIfaceAndGetName(false); - std::string ifname = getPrimaryWlanIfaceName(); + std::string ifname = setupApIfaceAndGetName(false); auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithInvalidChannel(ifname), getPskNwParams()); @@ -514,9 +479,7 @@ TEST_P(HostapdHidlTest, AddPskAccessPointWithInvalidChannel) { * Access point creation should fail. */ TEST_P(HostapdHidlTest, AddInvalidPskAccessPointWithoutAcs) { - // TODO: Use setupApIfaceAndGetName after fixing b/177483254 - // std::string ifname = setupApIfaceAndGetName(false); - std::string ifname = getPrimaryWlanIfaceName(); + std::string ifname = setupApIfaceAndGetName(false); auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(ifname), getInvalidPskNwParams()); @@ -529,9 +492,7 @@ TEST_P(HostapdHidlTest, AddInvalidPskAccessPointWithoutAcs) { */ TEST_P(HostapdHidlTest, AddInvalidSaeTransitionAccessPointWithoutAcs) { if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support"; - // TODO: Use setupApIfaceAndGetName after fixing b/177483254 - // std::string ifname = setupApIfaceAndGetName(false); - std::string ifname = getPrimaryWlanIfaceName(); + std::string ifname = setupApIfaceAndGetName(false); auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(ifname), getInvalidSaeTransitionNwParams()); @@ -544,9 +505,7 @@ TEST_P(HostapdHidlTest, AddInvalidSaeTransitionAccessPointWithoutAcs) { */ TEST_P(HostapdHidlTest, AddInvalidSaeAccessPointWithoutAcs) { if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support"; - // TODO: Use setupApIfaceAndGetName after fixing b/177483254 - // std::string ifname = setupApIfaceAndGetName(false); - std::string ifname = getPrimaryWlanIfaceName(); + std::string ifname = setupApIfaceAndGetName(false); auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(ifname), getInvalidSaeNwParams()); @@ -558,9 +517,7 @@ TEST_P(HostapdHidlTest, AddInvalidSaeAccessPointWithoutAcs) { * when hotspot interface available. */ TEST_P(HostapdHidlTest, DisconnectClientWhenIfacAvailable) { - // TODO: Use setupApIfaceAndGetName after fixing b/177483254 - // std::string ifname = setupApIfaceAndGetName(false); - std::string ifname = getPrimaryWlanIfaceName(); + std::string ifname = setupApIfaceAndGetName(false); auto status_1_2 = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(ifname), getOpenNwParams()); diff --git a/wifi/supplicant/1.4/ISupplicantStaIfaceCallback.hal b/wifi/supplicant/1.4/ISupplicantStaIfaceCallback.hal index c6f05fb953..3b0a4d4ca0 100644 --- a/wifi/supplicant/1.4/ISupplicantStaIfaceCallback.hal +++ b/wifi/supplicant/1.4/ISupplicantStaIfaceCallback.hal @@ -168,4 +168,13 @@ interface ISupplicantStaIfaceCallback extends @1.3::ISupplicantStaIfaceCallback * @param assocRejectData Association Rejection related information. */ oneway onAssociationRejected_1_4(AssociationRejectionData assocRejectData); + + /** + * Used to indicate that the supplicant failed to find a network in scan result + * which matches with the network capabilities requested by upper layer + * for connection. + * + * @param ssid network name supplicant tried to connect. + */ + oneway onNetworkNotFound(Ssid ssid); }; diff --git a/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp index 1794a39530..86d6737fa9 100644 --- a/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp +++ b/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp @@ -237,6 +237,10 @@ class IfaceCallback : public ISupplicantStaIfaceCallback { override { return Void(); } + Return<void> onNetworkNotFound( + const hidl_vec<uint8_t>& /* ssid */) override { + return Void(); + } }; /* |