diff options
163 files changed, 3857 insertions, 1986 deletions
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/1/.hash b/audio/aidl/aidl_api/android.hardware.audio.effect/1/.hash index 9914460874..b71ab296ef 100644 --- a/audio/aidl/aidl_api/android.hardware.audio.effect/1/.hash +++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/.hash @@ -1 +1 @@ -504db4349f884424a8acc3f2fc0f6bb74dbfcdf0 +34b618a587cb9977ee0cd13b173e699d2dcdb320 diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Descriptor.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Descriptor.aidl index 82dae97d24..115da1db57 100644 --- a/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Descriptor.aidl +++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Descriptor.aidl @@ -50,8 +50,8 @@ parcelable Descriptor { const String EFFECT_TYPE_UUID_PRESET_REVERB = "47382d60-ddd8-11db-bf3a-0002a5d5c51b"; const String EFFECT_TYPE_UUID_SPATIALIZER = "ccd4cf09-a79d-46c2-9aae-06a1698d6c8f"; const String EFFECT_TYPE_UUID_VIRTUALIZER = "37cc2c00-dddd-11db-8577-0002a5d5c51b"; - const String EFFECT_TYPE_UUID_VISUALIZER = "d069d9e0-8329-11df-9168-0002a5d5c51b"; - const String EFFECT_TYPE_UUID_VOLUME = "fa81a2b8-588b-11ed-9b6a-0242ac120002"; + const String EFFECT_TYPE_UUID_VISUALIZER = "e46b26a0-dddd-11db-8afd-0002a5d5c51b"; + const String EFFECT_TYPE_UUID_VOLUME = "09e8ede0-ddde-11db-b4f6-0002a5d5c51b"; @VintfStability parcelable Identity { android.media.audio.common.AudioUuid type; diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Descriptor.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Descriptor.aidl index 82dae97d24..115da1db57 100644 --- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Descriptor.aidl +++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Descriptor.aidl @@ -50,8 +50,8 @@ parcelable Descriptor { const String EFFECT_TYPE_UUID_PRESET_REVERB = "47382d60-ddd8-11db-bf3a-0002a5d5c51b"; const String EFFECT_TYPE_UUID_SPATIALIZER = "ccd4cf09-a79d-46c2-9aae-06a1698d6c8f"; const String EFFECT_TYPE_UUID_VIRTUALIZER = "37cc2c00-dddd-11db-8577-0002a5d5c51b"; - const String EFFECT_TYPE_UUID_VISUALIZER = "d069d9e0-8329-11df-9168-0002a5d5c51b"; - const String EFFECT_TYPE_UUID_VOLUME = "fa81a2b8-588b-11ed-9b6a-0242ac120002"; + const String EFFECT_TYPE_UUID_VISUALIZER = "e46b26a0-dddd-11db-8afd-0002a5d5c51b"; + const String EFFECT_TYPE_UUID_VOLUME = "09e8ede0-ddde-11db-b4f6-0002a5d5c51b"; @VintfStability parcelable Identity { android.media.audio.common.AudioUuid type; diff --git a/audio/aidl/android/hardware/audio/core/IModule.aidl b/audio/aidl/android/hardware/audio/core/IModule.aidl index 7622d9a16c..e736c32e98 100644 --- a/audio/aidl/android/hardware/audio/core/IModule.aidl +++ b/audio/aidl/android/hardware/audio/core/IModule.aidl @@ -234,6 +234,12 @@ interface IModule { * instance previously instantiated using the 'connectExternalDevice' * method. * + * The framework will call this method before closing streams and resetting + * patches. This call can be used by the HAL module to prepare itself to + * device disconnection. If the HAL module indicates an error after the first + * call, the framework will call this method once again after closing associated + * streams and patches. + * * @throws EX_ILLEGAL_ARGUMENT In the following cases: * - If the port can not be found by the ID. * - If this is not a connected device port. diff --git a/audio/aidl/android/hardware/audio/effect/Descriptor.aidl b/audio/aidl/android/hardware/audio/effect/Descriptor.aidl index 2fbc401f0f..b152f76d74 100644 --- a/audio/aidl/android/hardware/audio/effect/Descriptor.aidl +++ b/audio/aidl/android/hardware/audio/effect/Descriptor.aidl @@ -96,11 +96,11 @@ parcelable Descriptor { /** * UUID for visualizer effect type. */ - const String EFFECT_TYPE_UUID_VISUALIZER = "d069d9e0-8329-11df-9168-0002a5d5c51b"; + const String EFFECT_TYPE_UUID_VISUALIZER = "e46b26a0-dddd-11db-8afd-0002a5d5c51b"; /** * UUID for Volume effect type. */ - const String EFFECT_TYPE_UUID_VOLUME = "fa81a2b8-588b-11ed-9b6a-0242ac120002"; + const String EFFECT_TYPE_UUID_VOLUME = "09e8ede0-ddde-11db-b4f6-0002a5d5c51b"; /** * This structure completely identifies an effect implementation. diff --git a/audio/aidl/default/EffectConfig.cpp b/audio/aidl/default/EffectConfig.cpp index 5a83fef99a..71d111bd06 100644 --- a/audio/aidl/default/EffectConfig.cpp +++ b/audio/aidl/default/EffectConfig.cpp @@ -14,12 +14,17 @@ * limitations under the License. */ +#include <optional> +#include <string> #define LOG_TAG "AHAL_EffectConfig" #include <android-base/logging.h> +#include <system/audio_effects/audio_effects_conf.h> #include <system/audio_effects/effect_uuid.h> #include "effectFactory-impl/EffectConfig.h" +using aidl::android::media::audio::common::AudioSource; +using aidl::android::media::audio::common::AudioStreamType; using aidl::android::media::audio::common::AudioUuid; namespace aidl::android::hardware::audio::effect { @@ -55,14 +60,16 @@ EffectConfig::EffectConfig(const std::string& file) { // Parse pre processing chains for (auto& xmlPreprocess : getChildren(xmlConfig, "preprocess")) { for (auto& xmlStream : getChildren(xmlPreprocess, "stream")) { - registerFailure(parseStream(xmlStream)); + // AudioSource + registerFailure(parseProcessing(Processing::Type::source, xmlStream)); } } // Parse post processing chains for (auto& xmlPostprocess : getChildren(xmlConfig, "postprocess")) { for (auto& xmlStream : getChildren(xmlPostprocess, "stream")) { - registerFailure(parseStream(xmlStream)); + // AudioStreamType + registerFailure(parseProcessing(Processing::Type::streamType, xmlStream)); } } } @@ -140,21 +147,6 @@ bool EffectConfig::parseEffect(const tinyxml2::XMLElement& xml) { return true; } -bool EffectConfig::parseStream(const tinyxml2::XMLElement& xml) { - LOG(DEBUG) << __func__ << dump(xml); - const char* type = xml.Attribute("type"); - RETURN_VALUE_IF(!type, false, "noTypeInProcess"); - RETURN_VALUE_IF(0 != mProcessingMap.count(type), false, "duplicateType"); - - for (auto& apply : getChildren(xml, "apply")) { - const char* name = apply.get().Attribute("effect"); - RETURN_VALUE_IF(!name, false, "noEffectAttribute"); - mProcessingMap[type].push_back(name); - LOG(DEBUG) << __func__ << " " << type << " : " << name; - } - return true; -} - bool EffectConfig::parseLibraryUuid(const tinyxml2::XMLElement& xml, struct LibraryUuid& libraryUuid, bool isProxy) { // Retrieve library name only if not effectProxy element @@ -174,6 +166,80 @@ bool EffectConfig::parseLibraryUuid(const tinyxml2::XMLElement& xml, return true; } +std::optional<Processing::Type> EffectConfig::stringToProcessingType(Processing::Type::Tag typeTag, + const std::string& type) { + // see list of audio stream types in audio_stream_type_t: + // system/media/audio/include/system/audio_effects/audio_effects_conf.h + // AUDIO_STREAM_DEFAULT_TAG is not listed here because according to SYS_RESERVED_DEFAULT in + // AudioStreamType.aidl: "Value reserved for system use only. HALs must never return this value + // to the system or accept it from the system". + static const std::map<const std::string, AudioStreamType> sAudioStreamTypeTable = { + {AUDIO_STREAM_VOICE_CALL_TAG, AudioStreamType::VOICE_CALL}, + {AUDIO_STREAM_SYSTEM_TAG, AudioStreamType::SYSTEM}, + {AUDIO_STREAM_RING_TAG, AudioStreamType::RING}, + {AUDIO_STREAM_MUSIC_TAG, AudioStreamType::MUSIC}, + {AUDIO_STREAM_ALARM_TAG, AudioStreamType::ALARM}, + {AUDIO_STREAM_NOTIFICATION_TAG, AudioStreamType::NOTIFICATION}, + {AUDIO_STREAM_BLUETOOTH_SCO_TAG, AudioStreamType::BLUETOOTH_SCO}, + {AUDIO_STREAM_ENFORCED_AUDIBLE_TAG, AudioStreamType::ENFORCED_AUDIBLE}, + {AUDIO_STREAM_DTMF_TAG, AudioStreamType::DTMF}, + {AUDIO_STREAM_TTS_TAG, AudioStreamType::TTS}, + {AUDIO_STREAM_ASSISTANT_TAG, AudioStreamType::ASSISTANT}}; + + // see list of audio sources in audio_source_t: + // system/media/audio/include/system/audio_effects/audio_effects_conf.h + static const std::map<const std::string, AudioSource> sAudioSourceTable = { + {MIC_SRC_TAG, AudioSource::VOICE_CALL}, + {VOICE_UL_SRC_TAG, AudioSource::VOICE_CALL}, + {VOICE_DL_SRC_TAG, AudioSource::VOICE_CALL}, + {VOICE_CALL_SRC_TAG, AudioSource::VOICE_CALL}, + {CAMCORDER_SRC_TAG, AudioSource::VOICE_CALL}, + {VOICE_REC_SRC_TAG, AudioSource::VOICE_CALL}, + {VOICE_COMM_SRC_TAG, AudioSource::VOICE_CALL}, + {REMOTE_SUBMIX_SRC_TAG, AudioSource::VOICE_CALL}, + {UNPROCESSED_SRC_TAG, AudioSource::VOICE_CALL}, + {VOICE_PERFORMANCE_SRC_TAG, AudioSource::VOICE_CALL}}; + + if (typeTag == Processing::Type::streamType) { + auto typeIter = sAudioStreamTypeTable.find(type); + if (typeIter != sAudioStreamTypeTable.end()) { + return typeIter->second; + } + } else if (typeTag == Processing::Type::source) { + auto typeIter = sAudioSourceTable.find(type); + if (typeIter != sAudioSourceTable.end()) { + return typeIter->second; + } + } + + return std::nullopt; +} + +bool EffectConfig::parseProcessing(Processing::Type::Tag typeTag, const tinyxml2::XMLElement& xml) { + LOG(DEBUG) << __func__ << dump(xml); + const char* typeStr = xml.Attribute("type"); + auto aidlType = stringToProcessingType(typeTag, typeStr); + RETURN_VALUE_IF(!aidlType.has_value(), false, "illegalStreamType"); + RETURN_VALUE_IF(0 != mProcessingMap.count(aidlType.value()), false, "duplicateStreamType"); + + for (auto& apply : getChildren(xml, "apply")) { + const char* name = apply.get().Attribute("effect"); + if (mEffectsMap.find(name) == mEffectsMap.end()) { + LOG(ERROR) << __func__ << " effect " << name << " doesn't exist, skipping"; + continue; + } + RETURN_VALUE_IF(!name, false, "noEffectAttribute"); + mProcessingMap[aidlType.value()].emplace_back(mEffectsMap[name]); + LOG(WARNING) << __func__ << " " << typeStr << " : " << name; + } + return true; +} + +const std::map<Processing::Type, std::vector<EffectConfig::EffectLibraries>>& +EffectConfig::getProcessingMap() const { + return mProcessingMap; +} + bool EffectConfig::findUuid(const std::string& xmlEffectName, AudioUuid* uuid) { // Difference from EFFECT_TYPE_LIST_DEF, there could be multiple name mapping to same Effect Type #define EFFECT_XML_TYPE_LIST_DEF(V) \ diff --git a/audio/aidl/default/EffectFactory.cpp b/audio/aidl/default/EffectFactory.cpp index f0687cc80f..7073a10c96 100644 --- a/audio/aidl/default/EffectFactory.cpp +++ b/audio/aidl/default/EffectFactory.cpp @@ -15,8 +15,10 @@ */ #include <dlfcn.h> +#include <algorithm> #include <iterator> #include <memory> +#include <optional> #include <tuple> #include <unordered_set> #define LOG_TAG "AHAL_EffectFactory" @@ -52,6 +54,22 @@ Factory::~Factory() { } } +ndk::ScopedAStatus Factory::getDescriptorWithUuid(const AudioUuid& uuid, Descriptor* desc) { + RETURN_IF(!desc, EX_NULL_POINTER, "nullDescriptor"); + + if (mEffectLibMap.count(uuid)) { + auto& entry = mEffectLibMap[uuid]; + getDlSyms(entry); + auto& libInterface = std::get<kMapEntryInterfaceIndex>(entry); + RETURN_IF(!libInterface || !libInterface->queryEffectFunc, EX_NULL_POINTER, + "dlNullQueryEffectFunc"); + RETURN_IF_BINDER_EXCEPTION(libInterface->queryEffectFunc(&uuid, desc)); + return ndk::ScopedAStatus::ok(); + } + + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); +} + ndk::ScopedAStatus Factory::queryEffects(const std::optional<AudioUuid>& in_type_uuid, const std::optional<AudioUuid>& in_impl_uuid, const std::optional<AudioUuid>& in_proxy_uuid, @@ -69,12 +87,7 @@ ndk::ScopedAStatus Factory::queryEffects(const std::optional<AudioUuid>& in_type for (const auto& id : idList) { if (mEffectLibMap.count(id.uuid)) { Descriptor desc; - auto& entry = mEffectLibMap[id.uuid]; - getDlSyms(entry); - auto& libInterface = std::get<kMapEntryInterfaceIndex>(entry); - RETURN_IF(!libInterface || !libInterface->queryEffectFunc, EX_NULL_POINTER, - "dlNullQueryEffectFunc"); - RETURN_IF_BINDER_EXCEPTION(libInterface->queryEffectFunc(&id.uuid, &desc)); + RETURN_IF_ASTATUS_NOT_OK(getDescriptorWithUuid(id.uuid, &desc), "getDescriptorFailed"); // update proxy UUID with information from config xml desc.common.id.proxy = id.proxy; _aidl_return->emplace_back(std::move(desc)); @@ -85,12 +98,26 @@ ndk::ScopedAStatus Factory::queryEffects(const std::optional<AudioUuid>& in_type ndk::ScopedAStatus Factory::queryProcessing(const std::optional<Processing::Type>& in_type, std::vector<Processing>* _aidl_return) { - // TODO: implement this with audio_effect.xml. - if (in_type.has_value()) { - // return all matching process filter - LOG(DEBUG) << __func__ << " process type: " << in_type.value().toString(); + const auto& processings = mConfig.getProcessingMap(); + // Processing stream type + for (const auto& procIter : processings) { + if (!in_type.has_value() || in_type.value() == procIter.first) { + Processing process = {.type = procIter.first /* Processing::Type */}; + for (const auto& libs : procIter.second /* std::vector<struct EffectLibraries> */) { + for (const auto& lib : libs.libraries /* std::vector<struct LibraryUuid> */) { + Descriptor desc; + if (libs.proxyLibrary.has_value()) { + desc.common.id.proxy = libs.proxyLibrary.value().uuid; + } + RETURN_IF_ASTATUS_NOT_OK(getDescriptorWithUuid(lib.uuid, &desc), + "getDescriptorFailed"); + process.ids.emplace_back(desc); + } + } + _aidl_return->emplace_back(process); + } } - LOG(DEBUG) << __func__ << " return " << _aidl_return->size(); + return ndk::ScopedAStatus::ok(); } diff --git a/audio/aidl/default/audio_effects_config.xml b/audio/aidl/default/audio_effects_config.xml index c06742d966..6627ae7533 100644 --- a/audio/aidl/default/audio_effects_config.xml +++ b/audio/aidl/default/audio_effects_config.xml @@ -95,8 +95,17 @@ <libsw library="bundle" uuid="ce772f20-847d-11df-bb17-0002a5d5c51b"/> </effectProxy> <effect name="extensioneffect" library="extensioneffect" uuid="fa81dd00-588b-11ed-9b6a-0242ac120002"/> + <effect name="acoustic_echo_canceler" library="aecsw" uuid="bb392ec0-8d4d-11e0-a896-0002a5d5c51b"/> + <effect name="noise_suppression" library="nssw" uuid="c06c8400-8e06-11e0-9cb6-0002a5d5c51b"/> </effects> + <preprocess> + <stream type="voice_communication"> + <apply effect="acoustic_echo_canceler"/> + <apply effect="noise_suppression"/> + </stream> + </preprocess> + <!-- Audio pre processor configurations. The pre processor configuration is described in a "preprocess" element and consists in a list of elements each describing pre processor settings for a given use case or "stream". diff --git a/audio/aidl/default/bassboost/BassBoostSw.cpp b/audio/aidl/default/bassboost/BassBoostSw.cpp index dbf2e15c7d..6072d896d9 100644 --- a/audio/aidl/default/bassboost/BassBoostSw.cpp +++ b/audio/aidl/default/bassboost/BassBoostSw.cpp @@ -68,8 +68,7 @@ const std::vector<Range::BassBoostRange> BassBoostSw::kRanges = { const Capability BassBoostSw::kCapability = {.range = {BassBoostSw::kRanges}}; const Descriptor BassBoostSw::kDescriptor = { .common = {.id = {.type = getEffectTypeUuidBassBoost(), - .uuid = getEffectImplUuidBassBoostSw(), - .proxy = getEffectImplUuidBassBoostProxy()}, + .uuid = getEffectImplUuidBassBoostSw()}, .flags = {.type = Flags::Type::INSERT, .insert = Flags::Insert::FIRST, .volume = Flags::Volume::CTRL}, diff --git a/audio/aidl/default/equalizer/EqualizerSw.cpp b/audio/aidl/default/equalizer/EqualizerSw.cpp index 97699249fc..b2add3113c 100644 --- a/audio/aidl/default/equalizer/EqualizerSw.cpp +++ b/audio/aidl/default/equalizer/EqualizerSw.cpp @@ -88,16 +88,14 @@ const std::vector<Range::EqualizerRange> EqualizerSw::kRanges = { MAKE_RANGE(Equalizer, centerFreqMh, std::vector<int>({1}), std::vector<int>({0}))}; const Capability EqualizerSw::kEqCap = {.range = EqualizerSw::kRanges}; -const Descriptor EqualizerSw::kDesc = { - .common = {.id = {.type = getEffectTypeUuidEqualizer(), - .uuid = getEffectImplUuidEqualizerSw(), - .proxy = getEffectImplUuidEqualizerProxy()}, - .flags = {.type = Flags::Type::INSERT, - .insert = Flags::Insert::FIRST, - .volume = Flags::Volume::CTRL}, - .name = EqualizerSw::kEffectName, - .implementor = "The Android Open Source Project"}, - .capability = EqualizerSw::kEqCap}; +const Descriptor EqualizerSw::kDesc = {.common = {.id = {.type = getEffectTypeUuidEqualizer(), + .uuid = getEffectImplUuidEqualizerSw()}, + .flags = {.type = Flags::Type::INSERT, + .insert = Flags::Insert::FIRST, + .volume = Flags::Volume::CTRL}, + .name = EqualizerSw::kEffectName, + .implementor = "The Android Open Source Project"}, + .capability = EqualizerSw::kEqCap}; ndk::ScopedAStatus EqualizerSw::getDescriptor(Descriptor* _aidl_return) { LOG(DEBUG) << __func__ << kDesc.toString(); diff --git a/audio/aidl/default/include/effectFactory-impl/EffectConfig.h b/audio/aidl/default/include/effectFactory-impl/EffectConfig.h index c627a273d9..f8a86e1515 100644 --- a/audio/aidl/default/include/effectFactory-impl/EffectConfig.h +++ b/audio/aidl/default/include/effectFactory-impl/EffectConfig.h @@ -26,6 +26,7 @@ #include <cutils/properties.h> #include <tinyxml2.h> +#include <aidl/android/hardware/audio/effect/Processing.h> #include "effect-impl/EffectTypes.h" namespace aidl::android::hardware::audio::effect { @@ -39,11 +40,6 @@ class EffectConfig { public: explicit EffectConfig(const std::string& file); - // <library> - struct Library { - std::string name; - std::string path; - }; struct LibraryUuid { std::string name; // library name ::aidl::android::media::audio::common::AudioUuid uuid; @@ -59,13 +55,13 @@ class EffectConfig { const std::unordered_map<std::string, struct EffectLibraries> getEffectsMap() const { return mEffectsMap; } - const std::unordered_map<std::string, std::vector<std::string>> getProcessingMap() const { - return mProcessingMap; - } static bool findUuid(const std::string& xmlEffectName, ::aidl::android::media::audio::common::AudioUuid* uuid); + using ProcessingLibrariesMap = std::map<Processing::Type, std::vector<struct EffectLibraries>>; + const ProcessingLibrariesMap& getProcessingMap() const; + private: static constexpr const char* kEffectLibPath[] = #ifdef __LP64__ @@ -79,8 +75,11 @@ class EffectConfig { std::unordered_map<std::string, std::string> mLibraryMap; /* Parsed Effects result */ std::unordered_map<std::string, struct EffectLibraries> mEffectsMap; - /* Parsed pre/post processing result */ - std::unordered_map<std::string, std::vector<std::string>> mProcessingMap; + /** + * For parsed pre/post processing result: {key: AudioStreamType/AudioSource, value: + * EffectLibraries} + */ + ProcessingLibrariesMap mProcessingMap; /** @return all `node`s children that are elements and match the tag if provided. */ std::vector<std::reference_wrapper<const tinyxml2::XMLElement>> getChildren( @@ -94,7 +93,7 @@ class EffectConfig { */ bool parseEffect(const tinyxml2::XMLElement& xml); - bool parseStream(const tinyxml2::XMLElement& xml); + bool parseProcessing(Processing::Type::Tag typeTag, const tinyxml2::XMLElement& xml); // Function to parse effect.library name and effect.uuid from xml bool parseLibraryUuid(const tinyxml2::XMLElement& xml, struct LibraryUuid& libraryUuid, @@ -104,6 +103,9 @@ class EffectConfig { tinyxml2::XMLPrinter&& printer = {}) const; bool resolveLibrary(const std::string& path, std::string* resolvedPath); + + std::optional<Processing::Type> stringToProcessingType(Processing::Type::Tag typeTag, + const std::string& type); }; } // namespace aidl::android::hardware::audio::effect diff --git a/audio/aidl/default/include/effectFactory-impl/EffectFactory.h b/audio/aidl/default/include/effectFactory-impl/EffectFactory.h index b7f63afca0..ad59ca799c 100644 --- a/audio/aidl/default/include/effectFactory-impl/EffectFactory.h +++ b/audio/aidl/default/include/effectFactory-impl/EffectFactory.h @@ -107,6 +107,10 @@ class Factory : public BnFactory { const EffectConfig::LibraryUuid& configLib, const ::aidl::android::media::audio::common::AudioUuid& typeUuidStr, const std::optional<::aidl::android::media::audio::common::AudioUuid> proxyUuid); + + ndk::ScopedAStatus getDescriptorWithUuid( + const aidl::android::media::audio::common::AudioUuid& uuid, Descriptor* desc); + void loadEffectLibs(); /* Get effect_dl_interface_s from library handle */ void getDlSyms(DlEntry& entry); diff --git a/audio/aidl/default/virtualizer/VirtualizerSw.cpp b/audio/aidl/default/virtualizer/VirtualizerSw.cpp index e34464f460..0e8435ef82 100644 --- a/audio/aidl/default/virtualizer/VirtualizerSw.cpp +++ b/audio/aidl/default/virtualizer/VirtualizerSw.cpp @@ -16,6 +16,7 @@ #include <algorithm> #include <cstddef> +#include <optional> #define LOG_TAG "AHAL_VirtualizerSw" #include <Utils.h> @@ -76,8 +77,7 @@ const Capability VirtualizerSw::kCapability = { const Descriptor VirtualizerSw::kDescriptor = { .common = {.id = {.type = getEffectTypeUuidVirtualizer(), - .uuid = getEffectImplUuidVirtualizerSw(), - .proxy = getEffectImplUuidVirtualizerProxy()}, + .uuid = getEffectImplUuidVirtualizerSw()}, .flags = {.type = Flags::Type::INSERT, .insert = Flags::Insert::FIRST, .volume = Flags::Volume::CTRL}, diff --git a/audio/aidl/sounddose/default/Android.bp b/audio/aidl/sounddose/default/Android.bp deleted file mode 100644 index bd770fa5b5..0000000000 --- a/audio/aidl/sounddose/default/Android.bp +++ /dev/null @@ -1,46 +0,0 @@ -package { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "hardware_interfaces_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - default_applicable_licenses: ["hardware_interfaces_license"], -} - -cc_defaults { - name: "aidlsounddoseservice_defaults", - vendor: true, - header_libs: [ - "libsounddoseaidl_headers", - ], -} - -cc_library { - name: "libsounddoseserviceexampleimpl", - defaults: [ - "aidlsounddoseservice_defaults", - "latest_android_media_audio_common_types_ndk_shared", - "latest_android_hardware_audio_core_sounddose_ndk_shared", - "latest_android_hardware_audio_sounddose_ndk_shared", - ], - export_include_dirs: ["include"], - srcs: [ - "SoundDoseFactory.cpp", - ], - shared_libs: [ - "libaudioservicesounddoseimpl", - "libbase", - "libbinder_ndk", - ], - - visibility: [ - "//hardware/interfaces/audio/common/all-versions/default/service", - ], -} - -cc_library_headers { - name: "libsounddoseaidl_headers", - export_include_dirs: ["include"], - vendor_available: true, - host_supported: true, -} diff --git a/audio/aidl/sounddose/default/SoundDoseFactory.cpp b/audio/aidl/sounddose/default/SoundDoseFactory.cpp deleted file mode 100644 index 83a592b54e..0000000000 --- a/audio/aidl/sounddose/default/SoundDoseFactory.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "AHAL_SoundDoseFactory" - -#include "SoundDoseFactory.h" - -#include <android-base/logging.h> -#include <core-impl/SoundDose.h> - -namespace aidl::android::hardware::audio::sounddose { - -using ::aidl::android::hardware::audio::core::sounddose::SoundDose; - -ndk::ScopedAStatus SoundDoseFactory::getSoundDose(const std::string& in_module, - std::shared_ptr<ISoundDose>* _aidl_return) { - auto soundDoseIt = mSoundDoseBinderMap.find(in_module); - if (soundDoseIt != mSoundDoseBinderMap.end()) { - *_aidl_return = ISoundDose::fromBinder(soundDoseIt->second); - - LOG(DEBUG) << __func__ - << ": returning cached instance of ISoundDose: " << _aidl_return->get() - << " for module " << in_module; - return ndk::ScopedAStatus::ok(); - } - - auto soundDose = ndk::SharedRefBase::make<SoundDose>(); - mSoundDoseBinderMap[in_module] = soundDose->asBinder(); - *_aidl_return = soundDose; - - LOG(DEBUG) << __func__ << ": returning new instance of ISoundDose: " << _aidl_return->get() - << " for module " << in_module; - return ndk::ScopedAStatus::ok(); -} - -} // namespace aidl::android::hardware::audio::sounddose diff --git a/audio/aidl/sounddose/default/include/SoundDoseFactory.h b/audio/aidl/sounddose/default/include/SoundDoseFactory.h deleted file mode 100644 index ced4291411..0000000000 --- a/audio/aidl/sounddose/default/include/SoundDoseFactory.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include <aidl/android/hardware/audio/core/sounddose/ISoundDose.h> -#include <aidl/android/hardware/audio/sounddose/BnSoundDoseFactory.h> -#include <android/binder_interface_utils.h> - -#include <unordered_map> - -namespace aidl::android::hardware::audio::sounddose { - -using ::aidl::android::hardware::audio::core::sounddose::ISoundDose; - -class SoundDoseFactory : public BnSoundDoseFactory { - public: - ndk::ScopedAStatus getSoundDose(const std::string& module, - std::shared_ptr<ISoundDose>* _aidl_return) override; - - private: - std::unordered_map<std::string, ndk::SpAIBinder> mSoundDoseBinderMap; -}; - -} // namespace aidl::android::hardware::audio::sounddose diff --git a/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp b/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp index 7b9477dfa8..9cd6c22c7c 100644 --- a/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp +++ b/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp @@ -267,6 +267,7 @@ TEST_P(EffectFactoryTest, EffectInvalidAfterRestart) { TEST_P(EffectFactoryTest, QueryProcess) { std::vector<Processing> processing; EXPECT_IS_OK(mEffectFactory->queryProcessing(std::nullopt, &processing)); + std::set<Processing> processingSet(processing.begin(), processing.end()); Processing::Type streamType = Processing::Type::make<Processing::Type::streamType>(AudioStreamType::SYSTEM); @@ -279,7 +280,14 @@ TEST_P(EffectFactoryTest, QueryProcess) { EXPECT_IS_OK(mEffectFactory->queryProcessing(source, &processingFilteredBySource)); EXPECT_TRUE(processing.size() >= processingFilteredByStream.size()); + EXPECT_TRUE(std::all_of( + processingFilteredByStream.begin(), processingFilteredByStream.end(), + [&](const auto& proc) { return processingSet.find(proc) != processingSet.end(); })); + EXPECT_TRUE(processing.size() >= processingFilteredBySource.size()); + EXPECT_TRUE(std::all_of( + processingFilteredBySource.begin(), processingFilteredBySource.end(), + [&](const auto& proc) { return processingSet.find(proc) != processingSet.end(); })); } INSTANTIATE_TEST_SUITE_P(EffectFactoryTest, EffectFactoryTest, diff --git a/audio/common/all-versions/default/service/Android.bp b/audio/common/all-versions/default/service/Android.bp index 34aea60ba5..092e7afb18 100644 --- a/audio/common/all-versions/default/service/Android.bp +++ b/audio/common/all-versions/default/service/Android.bp @@ -38,13 +38,11 @@ cc_binary { name: "android.hardware.audio.service", init_rc: ["android.hardware.audio.service.rc"], - vintf_fragments: ["android.hardware.audio.sounddose-aidl.xml"], relative_install_path: "hw", vendor: true, defaults: [ "android_hardware_audio_config_defaults", - "latest_android_hardware_audio_sounddose_ndk_shared", ], srcs: ["service.cpp"], @@ -56,7 +54,6 @@ cc_binary { ], shared_libs: [ - "//hardware/interfaces/audio/aidl/sounddose/default:libsounddoseserviceexampleimpl", "libcutils", "libbinder", "libbinder_ndk", @@ -79,7 +76,6 @@ cc_binary { name: "android.hardware.audio.service_64", init_rc: ["android.hardware.audio.service_64.rc"], - vintf_fragments: ["android.hardware.audio.sounddose-aidl.xml"], relative_install_path: "hw", vendor: true, compile_multilib: "64", @@ -92,7 +88,6 @@ cc_binary { ], shared_libs: [ - "//hardware/interfaces/audio/aidl/sounddose/default:libsounddoseserviceexampleimpl", "libcutils", "libbinder", "libbinder_ndk", @@ -105,7 +100,6 @@ cc_binary { defaults: [ "android_hardware_audio_config_defaults", - "latest_android_hardware_audio_sounddose_ndk_shared", ], } diff --git a/audio/common/all-versions/default/service/android.hardware.audio.sounddose-aidl.xml b/audio/common/all-versions/default/service/android.hardware.audio.sounddose-aidl.xml deleted file mode 100644 index a297bfbbe5..0000000000 --- a/audio/common/all-versions/default/service/android.hardware.audio.sounddose-aidl.xml +++ /dev/null @@ -1,7 +0,0 @@ -<manifest version="1.0" type="device"> - <hal format="aidl"> - <name>android.hardware.audio.sounddose</name> - <version>1</version> - <fqname>ISoundDoseFactory/default</fqname> - </hal> -</manifest> diff --git a/audio/common/all-versions/default/service/service.cpp b/audio/common/all-versions/default/service/service.cpp index 6df425f409..cf22294fe2 100644 --- a/audio/common/all-versions/default/service/service.cpp +++ b/audio/common/all-versions/default/service/service.cpp @@ -20,10 +20,6 @@ #include <string> #include <vector> -#include <SoundDoseFactory.h> -#include <android-base/logging.h> -#include <android/binder_ibinder_platform.h> -#include <android/binder_manager.h> #include <android/binder_process.h> #include <binder/ProcessState.h> #include <cutils/properties.h> @@ -49,8 +45,6 @@ size_t getHWBinderMmapSize(){ } #endif -using aidl::android::hardware::audio::sounddose::SoundDoseFactory; - /** Try to register the provided factories in the provided order. * If any registers successfully, do not register any other and return true. * If all fail, return false. @@ -159,6 +153,10 @@ int main(int /* argc */, char* /* argv */ []) { "android.hardware.bluetooth.audio-impl", "createIBluetoothAudioProviderFactory", }, + { + "android.hardware.audio.sounddose-vendor-impl", + "createISoundDoseFactory", + }, }; // clang-format on @@ -186,13 +184,5 @@ int main(int /* argc */, char* /* argv */ []) { } } - // Register ISoundDoseFactory interface as a workaround for using the audio AIDL HAL - auto soundDoseDefault = ndk::SharedRefBase::make<SoundDoseFactory>(); - const std::string soundDoseDefaultName = - std::string() + SoundDoseFactory::descriptor + "/default"; - binder_status_t status = AServiceManager_addService(soundDoseDefault->asBinder().get(), - soundDoseDefaultName.c_str()); - CHECK_EQ(STATUS_OK, status); - joinRpcThreadpool(); } diff --git a/audio/core/all-versions/vts/functional/6.0/Generators.cpp b/audio/core/all-versions/vts/functional/6.0/Generators.cpp index dafd32697b..705932d4c9 100644 --- a/audio/core/all-versions/vts/functional/6.0/Generators.cpp +++ b/audio/core/all-versions/vts/functional/6.0/Generators.cpp @@ -16,6 +16,8 @@ #include <android-base/macros.h> +#include <IOProfile.h> + #include "6.0/Generators.h" #include "ConfigHelper.h" #include "PolicyConfig.h" diff --git a/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h b/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h index c1d5669775..f6271ff3fa 100644 --- a/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h +++ b/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h @@ -41,15 +41,10 @@ using Module = Modules::Module; class PolicyConfig { public: - explicit PolicyConfig(const std::string& configFileName) - : mConfigFileName{configFileName}, - mFilePath{findExistingConfigurationFile(mConfigFileName)}, - mConfig{xsd::read(mFilePath.c_str())} { - init(); - } PolicyConfig(const std::string& configPath, const std::string& configFileName) : mConfigFileName{configFileName}, - mFilePath{configPath + "/" + mConfigFileName}, + mFilePath{configPath.empty() ? findExistingConfigurationFile(mConfigFileName) + : configPath + "/" + mConfigFileName}, mConfig{xsd::read(mFilePath.c_str())} { init(); } diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h index 478482d412..fabe2d29a2 100644 --- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h +++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h @@ -195,7 +195,7 @@ static constexpr char kConfigFileName[] = "audio_policy_configuration.xml"; // Cached policy config after parsing for faster test startup const PolicyConfig& getCachedPolicyConfig() { static std::unique_ptr<PolicyConfig> policyConfig = [] { - auto config = std::make_unique<PolicyConfig>(kConfigFileName); + auto config = std::make_unique<PolicyConfig>("", kConfigFileName); return config; }(); return *policyConfig; diff --git a/audio/core/all-versions/vts/functional/PolicyConfig.h b/audio/core/all-versions/vts/functional/PolicyConfig.h index 171d03f42a..b08e8084a0 100644 --- a/audio/core/all-versions/vts/functional/PolicyConfig.h +++ b/audio/core/all-versions/vts/functional/PolicyConfig.h @@ -19,9 +19,9 @@ #include <set> #include <string> +#include <AudioPolicyConfig.h> #include <DeviceDescriptor.h> #include <HwModule.h> -#include <Serializer.h> #include <gtest/gtest.h> #include <system/audio_config.h> @@ -30,47 +30,35 @@ using ::android::sp; using ::android::status_t; -struct PolicyConfigData { - android::HwModuleCollection hwModules; - android::DeviceVector availableOutputDevices; - android::DeviceVector availableInputDevices; - sp<android::DeviceDescriptor> defaultOutputDevice; -}; - -class PolicyConfig : private PolicyConfigData, public android::AudioPolicyConfig { +class PolicyConfig { public: - explicit PolicyConfig(const std::string& configFileName) - : android::AudioPolicyConfig(hwModules, availableOutputDevices, availableInputDevices, - defaultOutputDevice), - mConfigFileName{configFileName} { - for (const auto& location : android::audio_get_configuration_paths()) { - std::string path = location + '/' + mConfigFileName; - if (access(path.c_str(), F_OK) == 0) { - mFilePath = path; - break; - } - } - init(); - } PolicyConfig(const std::string& configPath, const std::string& configFileName) - : android::AudioPolicyConfig(hwModules, availableOutputDevices, availableInputDevices, - defaultOutputDevice), - mConfigFileName{configFileName}, - mFilePath{configPath + "/" + mConfigFileName} { - init(); + : mInitialFilePath(configPath.empty() ? configFileName + : configPath + "/" + configFileName) { + auto result = android::AudioPolicyConfig::loadFromCustomXmlConfigForVtsTests( + configPath, configFileName); + if (result.ok()) { + mStatus = ::android::OK; + mConfig = result.value(); + init(); + } else { + mStatus = result.error(); + } } status_t getStatus() const { return mStatus; } std::string getError() const { - if (mFilePath.empty()) { - return std::string{"Could not find "} + mConfigFileName + + if (mConfig == nullptr) { + return std::string{"Could not find "} + mInitialFilePath + " file in: " + testing::PrintToString(android::audio_get_configuration_paths()); } else { - return "Invalid config file: " + mFilePath; + return "Invalid config file: " + mConfig->getSource(); } } - const std::string& getFilePath() const { return mFilePath; } + const std::string& getFilePath() const { + return mConfig != nullptr ? mConfig->getSource() : mInitialFilePath; + } sp<const android::HwModule> getModuleFromName(const std::string& name) const { - return getHwModules().getModuleFromName(name.c_str()); + return mConfig->getHwModules().getModuleFromName(name.c_str()); } sp<const android::HwModule> getPrimaryModule() const { return mPrimaryModule; } const std::set<std::string>& getModulesWithDevicesNames() const { @@ -86,6 +74,8 @@ class PolicyConfig : private PolicyConfigData, public android::AudioPolicyConfig return findAttachedDevice(getAttachedDevices(moduleName), getSourceDevicesForMixPort(moduleName, mixPortName)); } + const android::DeviceVector& getInputDevices() const { return mConfig->getInputDevices(); } + const android::DeviceVector& getOutputDevices() const { return mConfig->getOutputDevices(); } bool haveInputProfilesInModule(const std::string& name) const { auto module = getModuleFromName(name); return module && !module->getInputProfiles().empty(); @@ -93,29 +83,24 @@ class PolicyConfig : private PolicyConfigData, public android::AudioPolicyConfig private: void init() { - mStatus = android::deserializeAudioPolicyFileForVts(mFilePath.c_str(), this); - if (mStatus == android::OK) { - mPrimaryModule = getModuleFromName(DeviceManager::kPrimaryDevice); - // Available devices are not 'attached' to modules at this moment. - // Need to go over available devices and find their module. - for (const auto& device : availableOutputDevices) { - for (const auto& module : hwModules) { - if (module->getDeclaredDevices().indexOf(device) >= 0) { - mModulesWithDevicesNames.insert(module->getName()); - mAttachedDevicesPerModule[module->getName()].push_back( - device->getTagName()); - break; - } + mPrimaryModule = getModuleFromName(DeviceManager::kPrimaryDevice); + // Available devices are not 'attached' to modules at this moment. + // Need to go over available devices and find their module. + for (const auto& device : mConfig->getOutputDevices()) { + for (const auto& module : mConfig->getHwModules()) { + if (module->getDeclaredDevices().indexOf(device) >= 0) { + mModulesWithDevicesNames.insert(module->getName()); + mAttachedDevicesPerModule[module->getName()].push_back(device->getTagName()); + break; } } - for (const auto& device : availableInputDevices) { - for (const auto& module : hwModules) { - if (module->getDeclaredDevices().indexOf(device) >= 0) { - mModulesWithDevicesNames.insert(module->getName()); - mAttachedDevicesPerModule[module->getName()].push_back( - device->getTagName()); - break; - } + } + for (const auto& device : mConfig->getInputDevices()) { + for (const auto& module : mConfig->getHwModules()) { + if (module->getDeclaredDevices().indexOf(device) >= 0) { + mModulesWithDevicesNames.insert(module->getName()); + mAttachedDevicesPerModule[module->getName()].push_back(device->getTagName()); + break; } } } @@ -166,10 +151,10 @@ class PolicyConfig : private PolicyConfigData, public android::AudioPolicyConfig return result; } - const std::string mConfigFileName; + const std::string mInitialFilePath; status_t mStatus = android::NO_INIT; - std::string mFilePath; - sp<const android::HwModule> mPrimaryModule = nullptr; + sp<android::AudioPolicyConfig> mConfig; + sp<const android::HwModule> mPrimaryModule; std::set<std::string> mModulesWithDevicesNames; std::map<std::string, std::vector<std::string>> mAttachedDevicesPerModule; }; diff --git a/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp b/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp index f4e3b5ab9d..4e7e963981 100644 --- a/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp +++ b/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp @@ -53,17 +53,25 @@ using namespace android::audio::policy::configuration::V7_0; namespace audiohalcommon = android::hardware::audio::common; namespace audiomediacommon = android::media::audio::common; +namespace { +constexpr int32_t kAidlVersionThree = 3; +} + class AudioControlAidl : public testing::TestWithParam<std::string> { public: virtual void SetUp() override { audioControl = android::waitForDeclaredService<IAudioControl>(String16(GetParam().c_str())); ASSERT_NE(audioControl, nullptr); + aidlVersion = audioControl->getInterfaceVersion(); } void TearDown() override { audioControl = nullptr; } + bool isAidlVersionAtleast(int version) const { return aidlVersion >= version; } + sp<IAudioControl> audioControl; int32_t capabilities; + int32_t aidlVersion; }; TEST_P(AudioControlAidl, OnSetFadeTowardsFront) { @@ -250,6 +258,11 @@ struct ModuleChangeCallbackMock : BnModuleChangeCallback { TEST_P(AudioControlAidl, RegisterModuleChangeCallbackTwiceThrowsException) { ALOGI("Register Module change callback test"); + if (!isAidlVersionAtleast(kAidlVersionThree)) { + GTEST_SKIP() << "Device does not support the new APIs for module change callback"; + return; + } + // make sure no stale callbacks. audioControl->clearModuleChangeCallback(); @@ -269,6 +282,11 @@ TEST_P(AudioControlAidl, RegisterModuleChangeCallbackTwiceThrowsException) { TEST_P(AudioControlAidl, RegisterModuleChangeNullCallbackThrowsException) { ALOGI("Register Module change callback with nullptr test"); + if (!isAidlVersionAtleast(kAidlVersionThree)) { + GTEST_SKIP() << "Device does not support the new APIs for module change callback"; + return; + } + auto status = audioControl->setModuleChangeCallback(nullptr); EXPECT_THAT(status.exceptionCode(), AnyOf(Eq(Status::EX_ILLEGAL_ARGUMENT), Eq(Status::EX_UNSUPPORTED_OPERATION))); diff --git a/automotive/ivn_android_device/impl/default/Android.bp b/automotive/ivn_android_device/impl/default/Android.bp new file mode 100644 index 0000000000..98c1f58ee5 --- /dev/null +++ b/automotive/ivn_android_device/impl/default/Android.bp @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2023 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 { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +cc_library { + name: "IvnAndroidDeviceService", + vendor_available: true, + local_include_dirs: ["include"], + export_include_dirs: ["include"], + srcs: [ + "src/IvnAndroidDeviceService.cpp", + ], + whole_static_libs: [ + "android.hardware.automotive.ivn-V1-ndk", + ], + shared_libs: [ + "libbase", + "libbinder_ndk", + "libjsoncpp", + "liblog", + "libutils", + ], +} + +cc_binary { + name: "android.hardware.automotive.ivn@V1-default-service", + vendor: true, + relative_install_path: "hw", + local_include_dirs: ["include"], + srcs: ["src/IvnAndroidDeviceImpl.cpp"], + whole_static_libs: ["IvnAndroidDeviceService"], + shared_libs: [ + "libbase", + "libbinder_ndk", + "libjsoncpp", + "liblog", + "libutils", + ], + required: ["Prebuilt_IvnAndroidDeviceServiceDefaultConfig_JSON"], + vintf_fragments: ["ivn-default-service.xml"], + init_rc: ["ivn-default-service.rc"], +} diff --git a/automotive/ivn_android_device/impl/default/config/Android.bp b/automotive/ivn_android_device/impl/default/config/Android.bp new file mode 100644 index 0000000000..03c4d1b215 --- /dev/null +++ b/automotive/ivn_android_device/impl/default/config/Android.bp @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2023 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 { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +filegroup { + name: "IvnAndroidDeviceServiceDefaultConfig_Json", + srcs: ["DefaultConfig.json"], +} + +prebuilt_etc { + name: "Prebuilt_IvnAndroidDeviceServiceDefaultConfig_JSON", + filename_from_src: true, + src: "DefaultConfig.json", + sub_dir: "automotive/IvnConfig/", + vendor: true, +} diff --git a/automotive/ivn_android_device/impl/default/config/DefaultConfig.json b/automotive/ivn_android_device/impl/default/config/DefaultConfig.json new file mode 100644 index 0000000000..45663e2645 --- /dev/null +++ b/automotive/ivn_android_device/impl/default/config/DefaultConfig.json @@ -0,0 +1,61 @@ +{ + "MyDeviceId": 0, + "Devices": [ + { + "DeviceId": 0, + "OccupantZones": [ + { + "ZoneId": 0, + "OccupantType": "DRIVER", + "Seat": 1, + "Comments": "Occupant zone for driver and FRONT_LEFT seat" + }, + { + "ZoneId": 1, + "OccupantType": "FRONT_PASSENGER", + "Seat": 4, + "Comments": "Occupant zone for FRONT_RIGHT passenger" + } + ], + "EndpointInfo": { + "IpAddress": "10.10.10.1", + "PortNumber": 1234, + "BrandName": "MyBrand", + "DeviceName": "MyDevice", + "ProductName": "MyProduct", + "ManufacturerName": "MyCompany", + "ModelName": "MyModel", + "SerialNumber": "Serial1234" + }, + "Comments": "Device for front row" + }, + { + "DeviceId": 1, + "OccupantZones": [ + { + "ZoneId": 2, + "OccupantType": "REAR_PASSENGER", + "Seat": 16 + }, + { + "ZoneId": 3, + "OccupantType": "REAR_PASSENGER", + "Seat": 64 + } + ], + "EndpointInfo": { + "IpAddress": "10.10.10.2", + "PortNumber": 2345, + "BrandName": "MyBrand", + "DeviceName": "MyDevice", + "ProductName": "MyProduct", + "ManufacturerName": "MyCompany", + "ModelName": "MyModel", + "SerialNumber": "Serial2345" + }, + "Comments": "Device for back row" + } + ], + "Comment": + "This simulates a vehicle with two Android devices, one for front row, one for back row" +} diff --git a/automotive/ivn_android_device/impl/default/include/IvnAndroidDeviceService.h b/automotive/ivn_android_device/impl/default/include/IvnAndroidDeviceService.h new file mode 100644 index 0000000000..0cff8fe19a --- /dev/null +++ b/automotive/ivn_android_device/impl/default/include/IvnAndroidDeviceService.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2023 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/automotive/ivn/BnIvnAndroidDevice.h> +#include <aidl/android/hardware/automotive/ivn/EndpointInfo.h> +#include <aidl/android/hardware/automotive/ivn/OccupantZoneInfo.h> +#include <android/binder_auto_utils.h> +#include <json/json.h> +#include <vector> + +#include <unordered_map> + +namespace android { +namespace hardware { +namespace automotive { +namespace ivn { + +struct DeviceInfo { + std::vector<aidl::android::hardware::automotive::ivn::OccupantZoneInfo> occupantZones; + aidl::android::hardware::automotive::ivn::EndpointInfo endpointInfo; +}; + +class IvnAndroidDeviceService + : public aidl::android::hardware::automotive::ivn::BnIvnAndroidDevice { + public: + explicit IvnAndroidDeviceService(std::string_view configPath); + + // Initialize the service, returns true on success. + bool init(); + + ndk::ScopedAStatus getMyDeviceId(int* deviceId) override; + + ndk::ScopedAStatus getOtherDeviceIds(std::vector<int>* deviceIds) override; + + ndk::ScopedAStatus getDeviceIdForOccupantZone(int zoneId, int* deviceId) override; + + ndk::ScopedAStatus getOccupantZonesForDevice( + int androidDeviceId, + std::vector<aidl::android::hardware::automotive::ivn::OccupantZoneInfo>* occupantZones) + override; + + ndk::ScopedAStatus getMyEndpointInfo( + aidl::android::hardware::automotive::ivn::EndpointInfo* endpointInfo) override; + + ndk::ScopedAStatus getEndpointInfoForDevice( + int androidDeviceId, + aidl::android::hardware::automotive::ivn::EndpointInfo* endpointInfo) override; + + binder_status_t dump(int fd, const char** args, uint32_t numArgs) override; + + private: + Json::Value mConfigRootNode; + int mMyDeviceId; + std::unordered_map<int, DeviceInfo> mDeviceInfoById; + std::string_view mConfigPath; +}; + +} // namespace ivn +} // namespace automotive +} // namespace hardware +} // namespace android diff --git a/automotive/ivn_android_device/impl/default/ivn-default-service.rc b/automotive/ivn_android_device/impl/default/ivn-default-service.rc new file mode 100644 index 0000000000..070b2591be --- /dev/null +++ b/automotive/ivn_android_device/impl/default/ivn-default-service.rc @@ -0,0 +1,4 @@ +service vendor.ivn-default /vendor/bin/hw/android.hardware.automotive.ivn@V1-default-service + class hal + user vehicle_network + group system inet diff --git a/automotive/ivn_android_device/impl/default/ivn-default-service.xml b/automotive/ivn_android_device/impl/default/ivn-default-service.xml new file mode 100644 index 0000000000..481bc0a08f --- /dev/null +++ b/automotive/ivn_android_device/impl/default/ivn-default-service.xml @@ -0,0 +1,7 @@ +<manifest version="1.0" type="device"> + <hal format="aidl"> + <name>android.hardware.automotive.ivn</name> + <version>1</version> + <fqname>IIvnAndroidDevice/default</fqname> + </hal> +</manifest> diff --git a/automotive/ivn_android_device/impl/default/src/IvnAndroidDeviceImpl.cpp b/automotive/ivn_android_device/impl/default/src/IvnAndroidDeviceImpl.cpp new file mode 100644 index 0000000000..fdf677661a --- /dev/null +++ b/automotive/ivn_android_device/impl/default/src/IvnAndroidDeviceImpl.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2023 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 "IvnAndroidDeviceImpl" + +#include "IvnAndroidDeviceService.h" + +#include <android-base/logging.h> +#include <android/binder_manager.h> +#include <android/binder_process.h> +#include <stdlib.h> + +constexpr char SERVICE_NAME[] = "android.hardware.automotive.ivn.IIvnAndroidDevice/default"; +constexpr char DEFAULT_CONFIG_DIR[] = "/vendor/etc/automotive/IvnConfig/DefaultConfig.json"; + +int main(int /* argc */, char* /* argv */[]) { + LOG(INFO) << "Registering IvnAndroidDeviceService as service..."; + auto service = + ndk::SharedRefBase::make<android::hardware::automotive::ivn::IvnAndroidDeviceService>( + DEFAULT_CONFIG_DIR); + if (!service->init()) { + LOG(ERROR) << "Failed to init IvnAndroidDeviceService"; + exit(1); + } + + binder_exception_t err = AServiceManager_addService(service->asBinder().get(), SERVICE_NAME); + if (err != EX_NONE) { + LOG(ERROR) << "Failed to register IvnAndroidDeviceService service, exception: " << err; + exit(1); + } + + if (!ABinderProcess_setThreadPoolMaxThreadCount(1)) { + LOG(ERROR) << "Failed to set thread pool max thread count"; + exit(1); + } + ABinderProcess_startThreadPool(); + + LOG(INFO) << "IvnAndroidDeviceService Ready"; + + ABinderProcess_joinThreadPool(); + + LOG(ERROR) << "IvnAndroidDeviceService init failed! Should not reach here"; + + return 0; +} diff --git a/automotive/ivn_android_device/impl/default/src/IvnAndroidDeviceService.cpp b/automotive/ivn_android_device/impl/default/src/IvnAndroidDeviceService.cpp new file mode 100644 index 0000000000..81f18b2267 --- /dev/null +++ b/automotive/ivn_android_device/impl/default/src/IvnAndroidDeviceService.cpp @@ -0,0 +1,202 @@ +/* + * Copyright (C) 2023 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 "IvnAndroidDeviceService.h" + +#include <aidl/android/hardware/automotive/ivn/ConnectProtocol.h> +#include <aidl/android/hardware/automotive/ivn/HardwareIdentifiers.h> +#include <aidl/android/hardware/automotive/ivn/OccupantType.h> +#include <android-base/logging.h> +#include <android/binder_status.h> +#include <json/json.h> + +#include <fstream> + +namespace android { +namespace hardware { +namespace automotive { +namespace ivn { + +namespace { + +using ::aidl::android::hardware::automotive::ivn::ConnectProtocol; +using ::aidl::android::hardware::automotive::ivn::EndpointInfo; +using ::aidl::android::hardware::automotive::ivn::HardwareIdentifiers; +using ::aidl::android::hardware::automotive::ivn::OccupantType; +using ::aidl::android::hardware::automotive::ivn::OccupantZoneInfo; +using ::ndk::ScopedAStatus; + +constexpr int IVN_ERROR_GENERIC = -1; + +} // namespace + +IvnAndroidDeviceService::IvnAndroidDeviceService(std::string_view configPath) { + mConfigPath = configPath; +} + +bool IvnAndroidDeviceService::init() { + std::ifstream configStream(mConfigPath); + if (!configStream) { + LOG(ERROR) << "couldn't open " << mConfigPath << " for parsing."; + return false; + } + Json::CharReaderBuilder builder; + std::string errs; + if (!Json::parseFromStream(builder, configStream, &mConfigRootNode, &errs)) { + LOG(ERROR) << "Failed to parse config JSON stream, error: " << errs; + return false; + } + if (!mConfigRootNode.isObject()) { + LOG(ERROR) << "Root must be an object"; + return false; + } + if (!mConfigRootNode.isMember("MyDeviceId")) { + LOG(ERROR) << "Must contain 'MyDeviceId' field"; + return false; + } + mMyDeviceId = mConfigRootNode["MyDeviceId"].asInt(); + if (!mConfigRootNode.isMember("Devices") || !mConfigRootNode["Devices"].isArray()) { + LOG(ERROR) << "Must contain 'Devices' field as array"; + return false; + } + Json::Value& devices = mConfigRootNode["Devices"]; + for (unsigned int i = 0; i < devices.size(); i++) { + Json::Value& device = devices[i]; + int deviceId = device["DeviceId"].asInt(); + DeviceInfo deviceInfo = {}; + Json::Value& occupantZones = device["OccupantZones"]; + for (unsigned int j = 0; j < occupantZones.size(); j++) { + Json::Value& occupantZone = occupantZones[j]; + int zoneId = occupantZone["ZoneId"].asInt(); + std::string occupantTypeStr = occupantZone["OccupantType"].asString(); + int seat = occupantZone["Seat"].asInt(); + OccupantType occupantType; + if (occupantTypeStr == "DRIVER") { + occupantType = OccupantType::DRIVER; + } else if (occupantTypeStr == "FRONT_PASSENGER") { + occupantType = OccupantType::FRONT_PASSENGER; + } else if (occupantTypeStr == "REAR_PASSENGER") { + occupantType = OccupantType::REAR_PASSENGER; + } else { + LOG(ERROR) << "Unknown occupant type: " << occupantTypeStr; + return false; + } + OccupantZoneInfo occupantZoneInfo = { + .zoneId = zoneId, .occupantType = occupantType, .seat = seat}; + deviceInfo.occupantZones.push_back(std::move(occupantZoneInfo)); + } + Json::Value& ep = device["EndpointInfo"]; + EndpointInfo endpointInfo = {}; + endpointInfo.connectProtocol = ConnectProtocol::TCP_IP; + endpointInfo.ipAddress = ep["IpAddress"].asString(); + endpointInfo.portNumber = ep["PortNumber"].asInt(); + HardwareIdentifiers hardwareId = {}; + if (ep.isMember("BrandName")) { + hardwareId.brandName = ep["BrandName"].asString(); + } + if (ep.isMember("DeviceName")) { + hardwareId.deviceName = ep["DeviceName"].asString(); + } + if (ep.isMember("ProductName")) { + hardwareId.productName = ep["ProductName"].asString(); + } + if (ep.isMember("ManufacturerName")) { + hardwareId.manufacturerName = ep["ManufacturerName"].asString(); + } + if (ep.isMember("ModelName")) { + hardwareId.modelName = ep["ModelName"].asString(); + } + if (ep.isMember("SerialNumber")) { + hardwareId.serialNumber = ep["SerialNumber"].asString(); + } + endpointInfo.hardwareId = hardwareId; + deviceInfo.endpointInfo = endpointInfo; + mDeviceInfoById[deviceId] = deviceInfo; + } + if (mDeviceInfoById.find(mMyDeviceId) == mDeviceInfoById.end()) { + LOG(ERROR) << "My device ID is not in the device info list"; + return false; + } + return true; +} + +ScopedAStatus IvnAndroidDeviceService::getMyDeviceId(int* deviceId) { + *deviceId = mMyDeviceId; + return ScopedAStatus::ok(); +} + +ScopedAStatus IvnAndroidDeviceService::getOtherDeviceIds(std::vector<int>* deviceIds) { + deviceIds->clear(); + for (const auto& [deviceId, _] : mDeviceInfoById) { + if (deviceId == mMyDeviceId) { + continue; + } + deviceIds->push_back(deviceId); + } + return ScopedAStatus::ok(); +} + +ScopedAStatus IvnAndroidDeviceService::getDeviceIdForOccupantZone(int zoneId, int* outDeviceId) { + for (const auto& [deviceId, deviceInfo] : mDeviceInfoById) { + for (const auto& occupantZoneInfo : deviceInfo.occupantZones) { + if (occupantZoneInfo.zoneId == zoneId) { + *outDeviceId = deviceId; + return ScopedAStatus::ok(); + } + } + } + return ScopedAStatus::fromServiceSpecificErrorWithMessage(IVN_ERROR_GENERIC, + "Occupant zone not found"); +} + +ScopedAStatus IvnAndroidDeviceService::getOccupantZonesForDevice( + int androidDeviceId, std::vector<OccupantZoneInfo>* occupantZones) { + if (mDeviceInfoById.find(androidDeviceId) == mDeviceInfoById.end()) { + return ScopedAStatus::fromServiceSpecificErrorWithMessage(IVN_ERROR_GENERIC, + "Android device ID not found"); + } + for (const auto& occupantZoneInfo : mDeviceInfoById[androidDeviceId].occupantZones) { + occupantZones->push_back(occupantZoneInfo); + } + return ScopedAStatus::ok(); +} + +ScopedAStatus IvnAndroidDeviceService::getMyEndpointInfo(EndpointInfo* endpointInfo) { + *endpointInfo = mDeviceInfoById[mMyDeviceId].endpointInfo; + return ScopedAStatus::ok(); +} + +ScopedAStatus IvnAndroidDeviceService::getEndpointInfoForDevice(int androidDeviceId, + EndpointInfo* endpointInfo) { + if (mDeviceInfoById.find(androidDeviceId) == mDeviceInfoById.end()) { + return ScopedAStatus::fromServiceSpecificErrorWithMessage(IVN_ERROR_GENERIC, + "Android device ID not found"); + } + *endpointInfo = mDeviceInfoById[androidDeviceId].endpointInfo; + return ScopedAStatus::ok(); +} + +binder_status_t IvnAndroidDeviceService::dump(int fd, [[maybe_unused]] const char** args, + [[maybe_unused]] uint32_t numArgs) { + dprintf(fd, "IVN Android Device debug interface, Config: \n%s\n", + mConfigRootNode.toStyledString().c_str()); + return STATUS_OK; +} + +} // namespace ivn +} // namespace automotive +} // namespace hardware +} // namespace android diff --git a/automotive/ivn_android_device/impl/default/test/Android.bp b/automotive/ivn_android_device/impl/default/test/Android.bp new file mode 100644 index 0000000000..a100575de3 --- /dev/null +++ b/automotive/ivn_android_device/impl/default/test/Android.bp @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2023 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 { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +cc_test { + name: "IvnAndroidDeviceServiceUnitTest", + vendor: true, + srcs: ["*.cpp"], + whole_static_libs: [ + "IvnAndroidDeviceService", + ], + shared_libs: [ + "libbase", + "libbinder_ndk", + "libjsoncpp", + "liblog", + "libutils", + ], + static_libs: [ + "libgtest", + ], + data: [ + ":IvnAndroidDeviceServiceDefaultConfig_Json", + ], + test_suites: ["device-tests"], +} diff --git a/automotive/ivn_android_device/impl/default/test/IvnAndroidDeviceServiceUnittest.cpp b/automotive/ivn_android_device/impl/default/test/IvnAndroidDeviceServiceUnittest.cpp new file mode 100644 index 0000000000..6a4d26d8c3 --- /dev/null +++ b/automotive/ivn_android_device/impl/default/test/IvnAndroidDeviceServiceUnittest.cpp @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2023 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 "IvnAndroidDeviceService.h" + +#include <aidl/android/hardware/automotive/ivn/EndpointInfo.h> +#include <aidl/android/hardware/automotive/ivn/OccupantType.h> +#include <aidl/android/hardware/automotive/ivn/OccupantZoneInfo.h> +#include <android-base/file.h> +#include <gtest/gtest.h> + +namespace android { +namespace hardware { +namespace automotive { +namespace ivn { + +using ::aidl::android::hardware::automotive::ivn::ConnectProtocol; +using ::aidl::android::hardware::automotive::ivn::EndpointInfo; +using ::aidl::android::hardware::automotive::ivn::OccupantType; +using ::aidl::android::hardware::automotive::ivn::OccupantZoneInfo; +using ::ndk::ScopedAStatus; + +class IvnAndroidDeviceServiceUnitTest : public ::testing::Test { + public: + virtual void SetUp() override { + mService = ndk::SharedRefBase::make<IvnAndroidDeviceService>( + android::base::GetExecutableDirectory() + "/DefaultConfig.json"); + mService->init(); + } + + std::shared_ptr<IvnAndroidDeviceService> mService; +}; + +TEST_F(IvnAndroidDeviceServiceUnitTest, TestGetMyDeviceId) { + int deviceId = -1; + + ScopedAStatus status = mService->getMyDeviceId(&deviceId); + + ASSERT_TRUE(status.isOk()); + ASSERT_EQ(deviceId, 0); +} + +TEST_F(IvnAndroidDeviceServiceUnitTest, TestGetOtherDeviceIds) { + std::vector<int> deviceIds; + + ScopedAStatus status = mService->getOtherDeviceIds(&deviceIds); + + ASSERT_TRUE(status.isOk()); + ASSERT_EQ(deviceIds, std::vector<int>({1})); +} + +TEST_F(IvnAndroidDeviceServiceUnitTest, TestGetDeviceIdForOccupantZone) { + int deviceId = -1; + + ScopedAStatus status = mService->getDeviceIdForOccupantZone(/*zoneId=*/0, &deviceId); + + ASSERT_TRUE(status.isOk()); + EXPECT_EQ(deviceId, 0); + + status = mService->getDeviceIdForOccupantZone(/*zoneId=*/1, &deviceId); + + ASSERT_TRUE(status.isOk()); + EXPECT_EQ(deviceId, 0); + + status = mService->getDeviceIdForOccupantZone(/*zoneId=*/2, &deviceId); + + ASSERT_TRUE(status.isOk()); + EXPECT_EQ(deviceId, 1); + + status = mService->getDeviceIdForOccupantZone(/*zoneId=*/3, &deviceId); + + ASSERT_TRUE(status.isOk()); + EXPECT_EQ(deviceId, 1); + + status = mService->getDeviceIdForOccupantZone(/*zoneId=*/4, &deviceId); + + ASSERT_FALSE(status.isOk()); +} + +TEST_F(IvnAndroidDeviceServiceUnitTest, TestGetOccupantZonesForDevice) { + std::vector<OccupantZoneInfo> occupantZones; + + ScopedAStatus status = + mService->getOccupantZonesForDevice(/*androidDeviceId=*/0, &occupantZones); + + ASSERT_TRUE(status.isOk()); + EXPECT_EQ(occupantZones.size(), 2); + if (occupantZones.size() == 2) { + EXPECT_EQ(occupantZones[0].zoneId, 0); + EXPECT_EQ(occupantZones[0].occupantType, OccupantType::DRIVER); + EXPECT_EQ(occupantZones[0].seat, 1); + EXPECT_EQ(occupantZones[1].zoneId, 1); + EXPECT_EQ(occupantZones[1].occupantType, OccupantType::FRONT_PASSENGER); + EXPECT_EQ(occupantZones[1].seat, 4); + } +} + +TEST_F(IvnAndroidDeviceServiceUnitTest, TestGetMyEndpointInfo) { + EndpointInfo endpointInfo; + + ScopedAStatus status = mService->getMyEndpointInfo(&endpointInfo); + + ASSERT_TRUE(status.isOk()); + EXPECT_EQ(endpointInfo.connectProtocol, ConnectProtocol::TCP_IP); + EXPECT_EQ(endpointInfo.ipAddress, "10.10.10.1"); + EXPECT_EQ(endpointInfo.portNumber, 1234); + EXPECT_EQ(endpointInfo.hardwareId.brandName, "MyBrand"); + EXPECT_EQ(endpointInfo.hardwareId.deviceName, "MyDevice"); + EXPECT_EQ(endpointInfo.hardwareId.productName, "MyProduct"); + EXPECT_EQ(endpointInfo.hardwareId.manufacturerName, "MyCompany"); + EXPECT_EQ(endpointInfo.hardwareId.modelName, "MyModel"); + EXPECT_EQ(endpointInfo.hardwareId.serialNumber, "Serial1234"); +} + +TEST_F(IvnAndroidDeviceServiceUnitTest, TestGetEndpointInfoForDevice) { + EndpointInfo endpointInfo; + + ScopedAStatus status = mService->getEndpointInfoForDevice(/*androidDeviceId=*/0, &endpointInfo); + + ASSERT_TRUE(status.isOk()); + EXPECT_EQ(endpointInfo.connectProtocol, ConnectProtocol::TCP_IP); + EXPECT_EQ(endpointInfo.ipAddress, "10.10.10.1"); + EXPECT_EQ(endpointInfo.portNumber, 1234); + + status = mService->getEndpointInfoForDevice(/*androidDeviceId=*/1, &endpointInfo); + + ASSERT_TRUE(status.isOk()); + EXPECT_EQ(endpointInfo.connectProtocol, ConnectProtocol::TCP_IP); + EXPECT_EQ(endpointInfo.ipAddress, "10.10.10.2"); + EXPECT_EQ(endpointInfo.portNumber, 2345); +} + +} // namespace ivn +} // namespace automotive +} // namespace hardware +} // namespace android diff --git a/automotive/ivn_android_device/vts/Android.bp b/automotive/ivn_android_device/vts/Android.bp new file mode 100644 index 0000000000..e4b9d641ae --- /dev/null +++ b/automotive/ivn_android_device/vts/Android.bp @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2023 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 { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + +cc_test { + name: "VtsHalIvnTargetTest", + srcs: [ + "src/*.cpp", + ], + defaults: ["use_libaidlvintf_gtest_helper_static"], + static_libs: [ + "libgmock", + "libgtest", + "android.hardware.automotive.ivn-V1-ndk", + ], + shared_libs: [ + "libbinder_ndk", + ], + test_suites: [ + "general-tests", + "vts", + "automotive-tests", + "automotive-general-tests", + ], + require_root: true, +} diff --git a/automotive/ivn_android_device/vts/OWNERS b/automotive/ivn_android_device/vts/OWNERS new file mode 100644 index 0000000000..d6969e5eb5 --- /dev/null +++ b/automotive/ivn_android_device/vts/OWNERS @@ -0,0 +1,2 @@ +ericjeong@google.com +shanyu@google.com diff --git a/automotive/ivn_android_device/vts/src/VtsHalIvnTargetTest.cpp b/automotive/ivn_android_device/vts/src/VtsHalIvnTargetTest.cpp new file mode 100644 index 0000000000..73b9a5e708 --- /dev/null +++ b/automotive/ivn_android_device/vts/src/VtsHalIvnTargetTest.cpp @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2023 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/automotive/ivn/ConnectProtocol.h> +#include <aidl/android/hardware/automotive/ivn/EndpointInfo.h> +#include <aidl/android/hardware/automotive/ivn/IIvnAndroidDevice.h> +#include <android/binder_ibinder.h> +#include <android/binder_manager.h> +#include <gmock/gmock.h> +#include <unordered_set> + +namespace aidl::android::hardware::automotive::ivn { + +using ::ndk::ScopedAStatus; +using ::ndk::SpAIBinder; + +using ::testing::Contains; +using ::testing::Not; + +class VtsHalIvnTargetTest : public ::testing::TestWithParam<std::string> { + public: + void SetUp() override { + std::string descriptor = GetParam(); + AIBinder* binder = AServiceManager_checkService(descriptor.c_str()); + ASSERT_NE(binder, nullptr) << "Failed to connect to IVN HAL"; + mIvnHal = IIvnAndroidDevice::fromBinder(SpAIBinder(binder)); + } + + std::shared_ptr<IIvnAndroidDevice> getHal() { return mIvnHal; } + + private: + std::shared_ptr<IIvnAndroidDevice> mIvnHal; + + protected: + ScopedAStatus getAllDeviceIds(std::unordered_set<int>* deviceIds); +}; + +TEST_P(VtsHalIvnTargetTest, testDeviceIdIsUnique) { + std::unordered_set<int> foundDeviceIds; + int myDeviceId = 0; + + ScopedAStatus status = getHal()->getMyDeviceId(&myDeviceId); + + ASSERT_TRUE(status.isOk()) << "Failed to call getMyDeviceId, status: " << status; + foundDeviceIds.insert(myDeviceId); + + std::vector<int> otherDeviceIds; + + status = getHal()->getOtherDeviceIds(&otherDeviceIds); + + ASSERT_TRUE(status.isOk()) << "Failed to call getOtherDeviceIds, status: " << status; + + for (int deviceId : otherDeviceIds) { + EXPECT_THAT(foundDeviceIds, Not(Contains(deviceId))) << "Duplicate device ID: " << deviceId; + foundDeviceIds.insert(deviceId); + } +} + +ScopedAStatus VtsHalIvnTargetTest::getAllDeviceIds(std::unordered_set<int>* deviceIds) { + int myDeviceId = 0; + ScopedAStatus status = getHal()->getMyDeviceId(&myDeviceId); + + if (!status.isOk()) { + return status; + } + deviceIds->insert(myDeviceId); + std::vector<int> otherDeviceIds; + status = getHal()->getOtherDeviceIds(&otherDeviceIds); + if (!status.isOk()) { + return status; + } + for (int otherDeviceId : otherDeviceIds) { + deviceIds->insert(otherDeviceId); + } + return ScopedAStatus::ok(); +} + +TEST_P(VtsHalIvnTargetTest, testDeviceIdOccupantZoneMapping) { + std::unordered_set<int> allDeviceIds; + + ScopedAStatus status = getAllDeviceIds(&allDeviceIds); + + ASSERT_FALSE(allDeviceIds.empty()); + ASSERT_TRUE(status.isOk()) << "Failed to get all device IDs, status: " << status; + + std::unordered_set<int> foundOccupantZoneIds; + + for (int deviceId : allDeviceIds) { + std::vector<OccupantZoneInfo> occupantZones; + status = getHal()->getOccupantZonesForDevice(deviceId, &occupantZones); + + ASSERT_TRUE(status.isOk()) + << "Failed to call getOccupantZonesForDevice, status: " << status; + ASSERT_FALSE(occupantZones.empty()) << "No occupant zones for device: " << deviceId; + + for (const OccupantZoneInfo& occupantZone : occupantZones) { + int zoneId = occupantZone.zoneId; + + EXPECT_THAT(foundOccupantZoneIds, Not(Contains(zoneId))) + << "Duplicate zone ID: " << zoneId; + + foundOccupantZoneIds.insert(zoneId); + + int gotDeviceId = 0; + status = getHal()->getDeviceIdForOccupantZone(zoneId, &gotDeviceId); + + ASSERT_TRUE(status.isOk()) + << "Failed to call getDeviceIdForOccupantZone, status: " << status; + EXPECT_EQ(deviceId, gotDeviceId); + } + } +} + +TEST_P(VtsHalIvnTargetTest, testGetEndpointInfo) { + EndpointInfo endpointInfo; + std::vector<EndpointInfo> foundEndpointInfo; + + ScopedAStatus status = getHal()->getMyEndpointInfo(&endpointInfo); + + foundEndpointInfo.push_back(endpointInfo); + + ASSERT_TRUE(status.isOk()) << "Failed to call getMyEndpointInfo, status: " << status; + EXPECT_EQ(endpointInfo.connectProtocol, ConnectProtocol::TCP_IP); + + std::vector<int> otherDeviceIds; + status = getHal()->getOtherDeviceIds(&otherDeviceIds); + + ASSERT_TRUE(status.isOk()) << "Failed to call getOtherDeviceIds, status: " << status; + + for (int deviceId : otherDeviceIds) { + status = getHal()->getEndpointInfoForDevice(deviceId, &endpointInfo); + + ASSERT_TRUE(status.isOk()) << "Failed to call getEndpointInfoForDevice, status: " << status; + EXPECT_EQ(endpointInfo.connectProtocol, ConnectProtocol::TCP_IP); + + for (EndpointInfo foundInfo : foundEndpointInfo) { + ASSERT_NE(foundInfo, endpointInfo) + << "Found duplicate endpoint info" << endpointInfo.toString(); + } + + foundEndpointInfo.push_back(endpointInfo); + } +} + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VtsHalIvnTargetTest); + +INSTANTIATE_TEST_SUITE_P( + PerInstance, VtsHalIvnTargetTest, + testing::ValuesIn(::android::getAidlHalInstanceNames(IIvnAndroidDevice::descriptor)), + ::android::PrintInstanceNameToString); + +} // namespace aidl::android::hardware::automotive::ivn diff --git a/automotive/remoteaccess/bind_to_device_socket_mutator/Android.bp b/automotive/remoteaccess/bind_to_device_socket_mutator/Android.bp index 113b14e63f..cde021938f 100644 --- a/automotive/remoteaccess/bind_to_device_socket_mutator/Android.bp +++ b/automotive/remoteaccess/bind_to_device_socket_mutator/Android.bp @@ -37,7 +37,8 @@ cc_defaults { cc_library { name: "BindToDeviceSocketMutatorLib", vendor_available: true, - srcs: ["src/*"], + srcs: ["src/BindToDeviceSocketMutator.cpp"], export_include_dirs: ["include"], defaults: ["BindToDeviceSocketMutatorDefaults"], + header_libs: ["libgrpc++_internal_headers"], } diff --git a/automotive/remoteaccess/bind_to_device_socket_mutator/include/BindToDeviceSocketMutator.h b/automotive/remoteaccess/bind_to_device_socket_mutator/include/BindToDeviceSocketMutator.h index bafcc654c4..5974c4b366 100644 --- a/automotive/remoteaccess/bind_to_device_socket_mutator/include/BindToDeviceSocketMutator.h +++ b/automotive/remoteaccess/bind_to_device_socket_mutator/include/BindToDeviceSocketMutator.h @@ -16,20 +16,11 @@ #pragma once -#include <grpc++/grpc++.h> -#include <src/core/lib/iomgr/socket_mutator.h> -#include <string> +#include <grpc/grpc.h> +#include <string_view> namespace android::hardware::automotive::remoteaccess { -class BindToDeviceSocketMutator final : public grpc_socket_mutator { - public: - BindToDeviceSocketMutator(const std::string_view& interface_name); - - bool mutateFd(int fd); - - private: - std::string mIfname; -}; +grpc_socket_mutator* MakeBindToDeviceSocketMutator(std::string_view interface_name); } // namespace android::hardware::automotive::remoteaccess diff --git a/automotive/remoteaccess/bind_to_device_socket_mutator/src/BindToDeviceSocketMutator.cpp b/automotive/remoteaccess/bind_to_device_socket_mutator/src/BindToDeviceSocketMutator.cpp index c6a96deb88..04a4c5bde9 100644 --- a/automotive/remoteaccess/bind_to_device_socket_mutator/src/BindToDeviceSocketMutator.cpp +++ b/automotive/remoteaccess/bind_to_device_socket_mutator/src/BindToDeviceSocketMutator.cpp @@ -18,40 +18,50 @@ #include <android-base/logging.h> #include <errno.h> +#include <src/core/lib/iomgr/socket_mutator.h> #include <sys/socket.h> +#include <memory> + namespace android::hardware::automotive::remoteaccess { +namespace { + +struct BindToDeviceMutator : grpc_socket_mutator { + std::string ifname; +}; -bool BindToDeviceSocketMutator::mutateFd(int fd) { - int ret = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, mIfname.c_str(), mIfname.size()); +bool MutateFd(int fd, grpc_socket_mutator* mutator) { + auto* bdm = static_cast<BindToDeviceMutator*>(mutator); + int ret = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, bdm->ifname.c_str(), bdm->ifname.size()); if (ret != 0) { - PLOG(ERROR) << "Can't bind socket to interface " << mIfname; + PLOG(ERROR) << "Can't bind socket to interface " << bdm->ifname; return false; } return true; } -bool bind_to_device_mutator_mutate_fd(int fd, grpc_socket_mutator* mutator) { - BindToDeviceSocketMutator* bsm = (BindToDeviceSocketMutator*)mutator; - return bsm->mutateFd(fd); -} - -int bind_to_device_mutator_compare(grpc_socket_mutator* a, grpc_socket_mutator* b) { +int Compare(grpc_socket_mutator* a, grpc_socket_mutator* b) { return ((a) < (b) ? -1 : ((a) > (b) ? 1 : 0)); } -void bind_to_device_mutator_destroy(grpc_socket_mutator* mutator) { - BindToDeviceSocketMutator* bsm = (BindToDeviceSocketMutator*)mutator; - delete bsm; +void Destroy(grpc_socket_mutator* mutator) { + auto* bdm = static_cast<BindToDeviceMutator*>(mutator); + delete bdm; } -grpc_socket_mutator_vtable bind_to_device_mutator_vtable = {bind_to_device_mutator_mutate_fd, - bind_to_device_mutator_compare, - bind_to_device_mutator_destroy}; +constexpr grpc_socket_mutator_vtable kMutatorVtable = { + .mutate_fd = MutateFd, + .compare = Compare, + .destroy = Destroy, +}; + +} // namespace -BindToDeviceSocketMutator::BindToDeviceSocketMutator(const std::string_view& interface_name) { - mIfname = interface_name; - grpc_socket_mutator_init(this, &bind_to_device_mutator_vtable); +grpc_socket_mutator* MakeBindToDeviceSocketMutator(std::string_view interface_name) { + auto* bdm = new BindToDeviceMutator; + grpc_socket_mutator_init(bdm, &kMutatorVtable); + bdm->ifname = interface_name; + return bdm; } } // namespace android::hardware::automotive::remoteaccess diff --git a/automotive/remoteaccess/hal/default/include/RemoteAccessService.h b/automotive/remoteaccess/hal/default/include/RemoteAccessService.h index 9aabad6573..b18986adac 100644 --- a/automotive/remoteaccess/hal/default/include/RemoteAccessService.h +++ b/automotive/remoteaccess/hal/default/include/RemoteAccessService.h @@ -105,6 +105,8 @@ class RemoteAccessService size_t mRetryWaitInMs = 10'000; std::shared_ptr<DebugRemoteTaskCallback> mDebugCallback; + std::thread mInjectDebugTaskThread; + void runTaskLoop(); void maybeStartTaskLoop(); void maybeStopTaskLoop(); @@ -116,6 +118,8 @@ class RemoteAccessService void printCurrentStatus(int fd); std::string clientIdToTaskCountToStringLocked() REQUIRES(mLock); void debugInjectTask(int fd, std::string_view clientId, std::string_view taskData); + void debugInjectTaskNextReboot(int fd, std::string_view clientId, std::string_view taskData, + const char* latencyInSecStr); void updateGrpcConnected(bool connected); android::base::Result<void> deliverRemoteTaskThroughCallback(const std::string& clientId, std::string_view taskData); diff --git a/automotive/remoteaccess/hal/default/src/RemoteAccessImpl.cpp b/automotive/remoteaccess/hal/default/src/RemoteAccessImpl.cpp index d5251410bb..b091162000 100644 --- a/automotive/remoteaccess/hal/default/src/RemoteAccessImpl.cpp +++ b/automotive/remoteaccess/hal/default/src/RemoteAccessImpl.cpp @@ -40,7 +40,7 @@ int main(int /* argc */, char* /* argv */[]) { #ifdef GRPC_SERVICE_IFNAME grpcargs.SetSocketMutator( - new android::hardware::automotive::remoteaccess::BindToDeviceSocketMutator( + android::hardware::automotive::remoteaccess::MakeBindToDeviceSocketMutator( GRPC_SERVICE_IFNAME)); LOG(DEBUG) << "GRPC_SERVICE_IFNAME specified as: " << GRPC_SERVICE_IFNAME; LOG(INFO) << "Waiting for interface: " << GRPC_SERVICE_IFNAME; diff --git a/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp b/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp index bbda9df759..5081ac0a9b 100644 --- a/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp +++ b/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp @@ -18,12 +18,16 @@ #include <VehicleUtils.h> #include <aidl/android/hardware/automotive/vehicle/VehicleProperty.h> +#include <android-base/parseint.h> #include <android-base/stringprintf.h> #include <android/binder_status.h> #include <grpc++/grpc++.h> #include <private/android_filesystem_config.h> +#include <sys/stat.h> #include <utils/Log.h> #include <chrono> +#include <fstream> +#include <iostream> #include <thread> namespace android { @@ -37,6 +41,7 @@ using ::aidl::android::hardware::automotive::remoteaccess::ApState; using ::aidl::android::hardware::automotive::remoteaccess::IRemoteTaskCallback; using ::aidl::android::hardware::automotive::vehicle::VehicleProperty; using ::android::base::Error; +using ::android::base::ParseInt; using ::android::base::Result; using ::android::base::ScopedLockAssertion; using ::android::base::StringAppendF; @@ -57,8 +62,11 @@ constexpr char COMMAND_STOP_DEBUG_CALLBACK[] = "--stop-debug-callback"; constexpr char COMMAND_SHOW_TASK[] = "--show-task"; constexpr char COMMAND_GET_VEHICLE_ID[] = "--get-vehicle-id"; constexpr char COMMAND_INJECT_TASK[] = "--inject-task"; +constexpr char COMMAND_INJECT_TASK_NEXT_REBOOT[] = "--inject-task-next-reboot"; constexpr char COMMAND_STATUS[] = "--status"; +constexpr char DEBUG_TASK_FILE[] = "/data/vendor/remoteaccess/debugTask"; + std::vector<uint8_t> stringToBytes(std::string_view s) { const char* data = s.data(); return std::vector<uint8_t>(data, data + s.size()); @@ -92,10 +100,43 @@ std::string boolToString(bool x) { } // namespace RemoteAccessService::RemoteAccessService(WakeupClient::StubInterface* grpcStub) - : mGrpcStub(grpcStub){}; + : mGrpcStub(grpcStub) { + std::ifstream debugTaskFile; + debugTaskFile.open(DEBUG_TASK_FILE, std::ios::in); + if (!debugTaskFile.is_open()) { + ALOGD("No debug task available"); + return; + } + + char buffer[1024] = {}; + debugTaskFile.getline(buffer, sizeof(buffer)); + std::string clientId = std::string(buffer); + debugTaskFile.getline(buffer, sizeof(buffer)); + std::string taskData = std::string(buffer); + int latencyInSec; + debugTaskFile >> latencyInSec; + debugTaskFile.close(); + + ALOGD("Task for client: %s, data: [%s], latency: %d\n", clientId.c_str(), taskData.c_str(), + latencyInSec); + + mInjectDebugTaskThread = std::thread([this, clientId, taskData, latencyInSec] { + std::this_thread::sleep_for(std::chrono::seconds(latencyInSec)); + if (auto result = deliverRemoteTaskThroughCallback(clientId, taskData); !result.ok()) { + ALOGE("Failed to inject debug task, clientID: %s, taskData: %s, error: %s", + clientId.c_str(), taskData.c_str(), result.error().message().c_str()); + return; + } + ALOGD("Task for client: %s, data: [%s] successfully injected\n", clientId.c_str(), + taskData.c_str()); + }); +} RemoteAccessService::~RemoteAccessService() { maybeStopTaskLoop(); + if (mInjectDebugTaskThread.joinable()) { + mInjectDebugTaskThread.join(); + } } void RemoteAccessService::maybeStartTaskLoop() { @@ -286,9 +327,12 @@ void RemoteAccessService::dumpHelp(int fd) { "%s: Show tasks received by debug callback\n" "%s: Get vehicle id\n" "%s [client_id] [task_data]: Inject a task\n" + "%s [client_id] [task_data] [latencyInSec]: " + "Inject a task on next reboot after latencyInSec seconds\n" "%s: Show status\n", COMMAND_SET_AP_STATE, COMMAND_START_DEBUG_CALLBACK, COMMAND_STOP_DEBUG_CALLBACK, - COMMAND_SHOW_TASK, COMMAND_GET_VEHICLE_ID, COMMAND_INJECT_TASK, COMMAND_STATUS); + COMMAND_SHOW_TASK, COMMAND_GET_VEHICLE_ID, COMMAND_INJECT_TASK, + COMMAND_INJECT_TASK_NEXT_REBOOT, COMMAND_STATUS); } binder_status_t RemoteAccessService::dump(int fd, const char** args, uint32_t numArgs) { @@ -365,6 +409,12 @@ binder_status_t RemoteAccessService::dump(int fd, const char** args, uint32_t nu return STATUS_OK; } debugInjectTask(fd, args[1], args[2]); + } else if (!strcmp(args[0], COMMAND_INJECT_TASK_NEXT_REBOOT)) { + if (numArgs < 4) { + dumpHelp(fd); + return STATUS_OK; + } + debugInjectTaskNextReboot(fd, args[1], args[2], args[3]); } else if (!strcmp(args[0], COMMAND_STATUS)) { printCurrentStatus(fd); } else { @@ -389,13 +439,41 @@ void RemoteAccessService::debugInjectTask(int fd, std::string_view clientId, std::string_view taskData) { std::string clientIdCopy = std::string(clientId); if (auto result = deliverRemoteTaskThroughCallback(clientIdCopy, taskData); !result.ok()) { - dprintf(fd, "Failed to inject task: %s", result.error().message().c_str()); + dprintf(fd, "Failed to inject task: %s\n", result.error().message().c_str()); return; } dprintf(fd, "Task for client: %s, data: [%s] successfully injected\n", clientId.data(), taskData.data()); } +void RemoteAccessService::debugInjectTaskNextReboot(int fd, std::string_view clientId, + std::string_view taskData, + const char* latencyInSecStr) { + int latencyInSec; + if (!ParseInt(latencyInSecStr, &latencyInSec)) { + dprintf(fd, "The input latency in second is not a valid integer"); + return; + } + std::ofstream debugTaskFile; + debugTaskFile.open(DEBUG_TASK_FILE, std::ios::out); + if (!debugTaskFile.is_open()) { + dprintf(fd, + "Failed to open debug task file, please run the command: " + "'adb shell touch %s' first\n", + DEBUG_TASK_FILE); + return; + } + if (taskData.find("\n") != std::string::npos) { + dprintf(fd, "Task data must not contain newline\n"); + return; + } + debugTaskFile << clientId << "\n" << taskData << "\n" << latencyInSec; + debugTaskFile.close(); + dprintf(fd, + "Task with clientId: %s, task data: %s, latency: %d sec scheduled for next reboot\n", + clientId.data(), taskData.data(), latencyInSec); +} + std::string RemoteAccessService::clientIdToTaskCountToStringLocked() { // Print the table header std::string output = "| ClientId | Count |\n"; diff --git a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp index ec0d310508..0a1f90414e 100644 --- a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp +++ b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp @@ -113,6 +113,7 @@ const std::unordered_map<std::string, int> CONSTANTS_BY_NAME = { {"WHEEL_FRONT_LEFT", WHEEL_FRONT_LEFT}, {"CHARGE_PORT_FRONT_LEFT", CHARGE_PORT_FRONT_LEFT}, {"CHARGE_PORT_REAR_LEFT", CHARGE_PORT_REAR_LEFT}, + {"FAN_DIRECTION_UNKNOWN", toInt(VehicleHvacFanDirection::UNKNOWN)}, {"FAN_DIRECTION_FLOOR", FAN_DIRECTION_FLOOR}, {"FAN_DIRECTION_FACE", FAN_DIRECTION_FACE}, {"FAN_DIRECTION_DEFROST", FAN_DIRECTION_DEFROST}, diff --git a/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json b/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json index 84edeeda7c..5503de22ec 100644 --- a/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json +++ b/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json @@ -2164,6 +2164,7 @@ "property": "VehicleProperty::HVAC_FAN_DIRECTION_AVAILABLE", "defaultValue": { "int32Values": [ + "Constants::FAN_DIRECTION_UNKNOWN", "Constants::FAN_DIRECTION_FACE", "Constants::FAN_DIRECTION_FLOOR", "Constants::FAN_DIRECTION_FACE_FLOOR", diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h b/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h index 7b740920d2..c3ebd3b3bc 100644 --- a/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h +++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h @@ -159,6 +159,7 @@ class FakeVehicleHardware : public IVehicleHardware { const std::string mDefaultConfigDir; const std::string mOverrideConfigDir; const bool mForceOverride; + bool mAddExtraTestVendorConfigs; // Only used during initialization. JsonConfigLoader mLoader; @@ -195,6 +196,8 @@ class FakeVehicleHardware : public IVehicleHardware { const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value); VehiclePropValuePool::RecyclableType createApPowerStateReq( aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReq state); + VehiclePropValuePool::RecyclableType createAdasStateReq(int32_t propertyId, int32_t areaId, + int32_t state); VhalResult<void> setUserHalProp( const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value); ValueResultType getUserHalProp( @@ -202,6 +205,7 @@ class FakeVehicleHardware : public IVehicleHardware { ValueResultType getEchoReverseBytes( const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value) const; bool isHvacPropAndHvacNotAvailable(int32_t propId, int32_t areaId) const; + VhalResult<void> isAdasPropertyAvailable(int32_t adasStatePropertyId) const; std::unordered_map<int32_t, ConfigDeclaration> loadConfigDeclarations(); @@ -244,6 +248,9 @@ class FakeVehicleHardware : public IVehicleHardware { std::string genFakeDataCommand(const std::vector<std::string>& options); void sendHvacPropertiesCurrentValues(int32_t areaId); + void sendAdasPropertiesState(int32_t propertyId, int32_t state); + void generateVendorConfigs( + std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropConfig>&) const; static aidl::android::hardware::automotive::vehicle::VehiclePropValue createHwInputKeyProp( aidl::android::hardware::automotive::vehicle::VehicleHwKeyInputAction action, diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp index 096a6cda3f..3f5e4c4273 100644 --- a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp +++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp @@ -52,6 +52,7 @@ namespace fake { namespace { +using ::aidl::android::hardware::automotive::vehicle::ErrorState; using ::aidl::android::hardware::automotive::vehicle::GetValueRequest; using ::aidl::android::hardware::automotive::vehicle::GetValueResult; using ::aidl::android::hardware::automotive::vehicle::RawPropValues; @@ -63,6 +64,7 @@ using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReq; using ::aidl::android::hardware::automotive::vehicle::VehicleHwKeyInputAction; using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig; using ::aidl::android::hardware::automotive::vehicle::VehicleProperty; +using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyAccess; using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyGroup; using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyStatus; using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyType; @@ -78,6 +80,19 @@ using ::android::base::ScopedLockAssertion; using ::android::base::StartsWith; using ::android::base::StringPrintf; +// In order to test large number of vehicle property configs, we might generate additional fake +// property config start from this ID. These fake properties are for getPropertyList, +// getPropertiesAsync, and setPropertiesAsync. +// 0x21403000 +constexpr int32_t STARTING_VENDOR_CODE_PROPERTIES_FOR_TEST = + 0x3000 | toInt(testpropertyutils_impl::VehiclePropertyGroup::VENDOR) | + toInt(testpropertyutils_impl::VehicleArea::GLOBAL) | + toInt(testpropertyutils_impl::VehiclePropertyType::INT32); +// 0x21405000 +constexpr int32_t ENDING_VENDOR_CODE_PROPERTIES_FOR_TEST = + 0x5000 | toInt(testpropertyutils_impl::VehiclePropertyGroup::VENDOR) | + toInt(testpropertyutils_impl::VehicleArea::GLOBAL) | + toInt(testpropertyutils_impl::VehiclePropertyType::INT32); // The directory for default property configuration file. // For config file format, see impl/default_config/config/README.md. constexpr char DEFAULT_CONFIG_DIR[] = "/vendor/etc/automotive/vhalconfig/"; @@ -107,6 +122,74 @@ const std::unordered_set<std::string> SET_PROP_OPTIONS = { // Timestamp in int64. "-t"}; +// ADAS _ENABLED property to list of ADAS state properties using ErrorState enum. +const std::unordered_map<int32_t, std::vector<int32_t>> mAdasEnabledPropToAdasPropWithErrorState = { + // AEB + { + toInt(VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_ENABLED), + { + toInt(VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_STATE), + }, + }, + // FCW + { + toInt(VehicleProperty::FORWARD_COLLISION_WARNING_ENABLED), + { + toInt(VehicleProperty::FORWARD_COLLISION_WARNING_STATE), + }, + }, + // BSW + { + toInt(VehicleProperty::BLIND_SPOT_WARNING_ENABLED), + { + toInt(VehicleProperty::BLIND_SPOT_WARNING_STATE), + }, + }, + // LDW + { + toInt(VehicleProperty::LANE_DEPARTURE_WARNING_ENABLED), + { + toInt(VehicleProperty::LANE_DEPARTURE_WARNING_STATE), + }, + }, + // LKA + { + toInt(VehicleProperty::LANE_KEEP_ASSIST_ENABLED), + { + toInt(VehicleProperty::LANE_KEEP_ASSIST_STATE), + }, + }, + // LCA + { + toInt(VehicleProperty::LANE_CENTERING_ASSIST_ENABLED), + { + toInt(VehicleProperty::LANE_CENTERING_ASSIST_STATE), + }, + }, + // ELKA + { + toInt(VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_ENABLED), + { + toInt(VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_STATE), + }, + }, + // CC + { + toInt(VehicleProperty::CRUISE_CONTROL_ENABLED), + { + toInt(VehicleProperty::CRUISE_CONTROL_TYPE), + toInt(VehicleProperty::CRUISE_CONTROL_STATE), + }, + }, + // HOD + { + toInt(VehicleProperty::HANDS_ON_DETECTION_ENABLED), + { + toInt(VehicleProperty::HANDS_ON_DETECTION_DRIVER_STATE), + toInt(VehicleProperty::HANDS_ON_DETECTION_WARNING), + }, + }, +}; } // namespace void FakeVehicleHardware::storePropInitialValue(const ConfigDeclaration& config) { @@ -222,7 +305,11 @@ void FakeVehicleHardware::init() { } std::vector<VehiclePropConfig> FakeVehicleHardware::getAllPropertyConfigs() const { - return mServerSidePropStore->getAllConfigs(); + std::vector<VehiclePropConfig> allConfigs = mServerSidePropStore->getAllConfigs(); + if (mAddExtraTestVendorConfigs) { + generateVendorConfigs(/* outAllConfigs= */ allConfigs); + } + return allConfigs; } VehiclePropValuePool::RecyclableType FakeVehicleHardware::createApPowerStateReq( @@ -238,6 +325,18 @@ VehiclePropValuePool::RecyclableType FakeVehicleHardware::createApPowerStateReq( return req; } +VehiclePropValuePool::RecyclableType FakeVehicleHardware::createAdasStateReq(int32_t propertyId, + int32_t areaId, + int32_t state) { + auto req = mValuePool->obtain(VehiclePropertyType::INT32); + req->prop = propertyId; + req->areaId = areaId; + req->timestamp = elapsedRealtimeNano(); + req->status = VehiclePropertyStatus::AVAILABLE; + req->value.int32Values[0] = state; + return req; +} + VhalResult<void> FakeVehicleHardware::setApPowerStateReport(const VehiclePropValue& value) { auto updatedValue = mValuePool->obtain(value); updatedValue->timestamp = elapsedRealtimeNano(); @@ -413,6 +512,41 @@ bool FakeVehicleHardware::isHvacPropAndHvacNotAvailable(int32_t propId, int32_t return false; } +VhalResult<void> FakeVehicleHardware::isAdasPropertyAvailable(int32_t adasStatePropertyId) const { + auto adasStateResult = mServerSidePropStore->readValue(adasStatePropertyId); + if (!adasStateResult.ok()) { + ALOGW("Failed to get ADAS ENABLED property 0x%x, error: %s", adasStatePropertyId, + getErrorMsg(adasStateResult).c_str()); + return {}; + } + + if (adasStateResult.value()->value.int32Values.size() == 1 && + adasStateResult.value()->value.int32Values[0] < 0) { + auto errorState = adasStateResult.value()->value.int32Values[0]; + switch (errorState) { + case toInt(ErrorState::NOT_AVAILABLE_DISABLED): + return StatusError(StatusCode::NOT_AVAILABLE_DISABLED) + << "ADAS feature is disabled."; + case toInt(ErrorState::NOT_AVAILABLE_SPEED_LOW): + return StatusError(StatusCode::NOT_AVAILABLE_SPEED_LOW) + << "ADAS feature is disabled because the vehicle speed is too low."; + case toInt(ErrorState::NOT_AVAILABLE_SPEED_HIGH): + return StatusError(StatusCode::NOT_AVAILABLE_SPEED_HIGH) + << "ADAS feature is disabled because the vehicle speed is too high."; + case toInt(ErrorState::NOT_AVAILABLE_POOR_VISIBILITY): + return StatusError(StatusCode::NOT_AVAILABLE_POOR_VISIBILITY) + << "ADAS feature is disabled because the visibility is too poor."; + case toInt(ErrorState::NOT_AVAILABLE_SAFETY): + return StatusError(StatusCode::NOT_AVAILABLE_SAFETY) + << "ADAS feature is disabled because of safety reasons."; + default: + return StatusError(StatusCode::NOT_AVAILABLE) << "ADAS feature is not available."; + } + } + + return {}; +} + VhalResult<void> FakeVehicleHardware::setUserHalProp(const VehiclePropValue& value) { auto result = mFakeUserHal->onSetProperty(value); if (!result.ok()) { @@ -464,6 +598,17 @@ FakeVehicleHardware::ValueResultType FakeVehicleHardware::maybeGetSpecialValue( int32_t propId = value.prop; ValueResultType result; + if (propId >= STARTING_VENDOR_CODE_PROPERTIES_FOR_TEST && + propId < ENDING_VENDOR_CODE_PROPERTIES_FOR_TEST) { + *isSpecialValue = true; + result = mValuePool->obtainInt32(/* value= */ 5); + + result.value()->prop = propId; + result.value()->areaId = 0; + result.value()->timestamp = elapsedRealtimeNano(); + return result; + } + if (mFakeUserHal->isSupported(propId)) { *isSpecialValue = true; return getUserHalProp(value); @@ -495,6 +640,19 @@ FakeVehicleHardware::ValueResultType FakeVehicleHardware::maybeGetSpecialValue( case VENDOR_PROPERTY_ID: *isSpecialValue = true; return StatusError((StatusCode)VENDOR_ERROR_CODE); + case toInt(VehicleProperty::CRUISE_CONTROL_TARGET_SPEED): + [[fallthrough]]; + case toInt(VehicleProperty::ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP): + [[fallthrough]]; + case toInt(VehicleProperty::ADAPTIVE_CRUISE_CONTROL_LEAD_VEHICLE_MEASURED_DISTANCE): { + auto isAdasPropertyAvailableResult = + isAdasPropertyAvailable(toInt(VehicleProperty::CRUISE_CONTROL_STATE)); + if (!isAdasPropertyAvailableResult.ok()) { + *isSpecialValue = true; + return isAdasPropertyAvailableResult.error(); + } + return nullptr; + } default: // Do nothing. break; @@ -542,12 +700,37 @@ void FakeVehicleHardware::sendHvacPropertiesCurrentValues(int32_t areaId) { } } +void FakeVehicleHardware::sendAdasPropertiesState(int32_t propertyId, int32_t state) { + auto& adasDependentPropIds = mAdasEnabledPropToAdasPropWithErrorState.find(propertyId)->second; + for (auto dependentPropId : adasDependentPropIds) { + auto dependentPropConfigResult = mServerSidePropStore->getConfig(dependentPropId); + if (!dependentPropConfigResult.ok()) { + ALOGW("Failed to get config for ADAS property 0x%x, error: %s", dependentPropId, + getErrorMsg(dependentPropConfigResult).c_str()); + continue; + } + auto& dependentPropConfig = dependentPropConfigResult.value(); + for (auto& areaConfig : dependentPropConfig->areaConfigs) { + auto propValue = createAdasStateReq(dependentPropId, areaConfig.areaId, state); + // This will trigger a property change event for the current ADAS property value. + mServerSidePropStore->writeValue(std::move(propValue), /*updateStatus=*/true, + VehiclePropertyStore::EventMode::ALWAYS); + } + } +} + VhalResult<void> FakeVehicleHardware::maybeSetSpecialValue(const VehiclePropValue& value, bool* isSpecialValue) { *isSpecialValue = false; VehiclePropValuePool::RecyclableType updatedValue; int32_t propId = value.prop; + if (propId >= STARTING_VENDOR_CODE_PROPERTIES_FOR_TEST && + propId < ENDING_VENDOR_CODE_PROPERTIES_FOR_TEST) { + *isSpecialValue = true; + return {}; + } + if (mFakeUserHal->isSupported(propId)) { *isSpecialValue = true; return setUserHalProp(value); @@ -565,6 +748,16 @@ VhalResult<void> FakeVehicleHardware::maybeSetSpecialValue(const VehiclePropValu return StatusError(StatusCode::NOT_AVAILABLE_DISABLED) << "hvac not available"; } + if (mAdasEnabledPropToAdasPropWithErrorState.count(propId) && + value.value.int32Values.size() == 1) { + if (value.value.int32Values[0] == 1) { + // Set default state to 1 when ADAS feature is enabled. + sendAdasPropertiesState(propId, /* state = */ 1); + } else { + sendAdasPropertiesState(propId, toInt(ErrorState::NOT_AVAILABLE_DISABLED)); + } + } + switch (propId) { case toInt(VehicleProperty::AP_POWER_STATE_REPORT): *isSpecialValue = true; @@ -583,6 +776,24 @@ VhalResult<void> FakeVehicleHardware::maybeSetSpecialValue(const VehiclePropValu case toInt(VehicleProperty::HVAC_TEMPERATURE_VALUE_SUGGESTION): *isSpecialValue = true; return setHvacTemperatureValueSuggestion(value); + case toInt(VehicleProperty::LANE_CENTERING_ASSIST_COMMAND): { + auto isAdasPropertyAvailableResult = + isAdasPropertyAvailable(toInt(VehicleProperty::LANE_CENTERING_ASSIST_STATE)); + if (!isAdasPropertyAvailableResult.ok()) { + *isSpecialValue = true; + } + return isAdasPropertyAvailableResult; + } + case toInt(VehicleProperty::CRUISE_CONTROL_COMMAND): + [[fallthrough]]; + case toInt(VehicleProperty::ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP): { + auto isAdasPropertyAvailableResult = + isAdasPropertyAvailable(toInt(VehicleProperty::CRUISE_CONTROL_STATE)); + if (!isAdasPropertyAvailableResult.ok()) { + *isSpecialValue = true; + } + return isAdasPropertyAvailableResult; + } #ifdef ENABLE_VEHICLE_HAL_TEST_PROPERTIES case toInt(VehicleProperty::CLUSTER_REPORT_STATE): @@ -643,7 +854,6 @@ VhalResult<void> FakeVehicleHardware::setValue(const VehiclePropValue& value) { // Here we are just updating mValuePool. bool isSpecialValue = false; auto setSpecialValueResult = maybeSetSpecialValue(value, &isSpecialValue); - if (isSpecialValue) { if (!setSpecialValueResult.ok()) { return StatusError(getErrorCode(setSpecialValueResult)) @@ -777,6 +987,12 @@ DumpResult FakeVehicleHardware::dump(const std::vector<std::string>& options) { result.buffer = mFakeUserHal->dump(); } else if (EqualsIgnoreCase(option, "--genfakedata")) { result.buffer = genFakeDataCommand(options); + } else if (EqualsIgnoreCase(option, "--genTestVendorConfigs")) { + mAddExtraTestVendorConfigs = true; + result.refreshPropertyConfigs = true; + } else if (EqualsIgnoreCase(option, "--restoreVendorConfigs")) { + mAddExtraTestVendorConfigs = false; + result.refreshPropertyConfigs = true; } else { result.buffer = StringPrintf("Invalid option: %s\n", option.c_str()); } @@ -827,6 +1043,13 @@ provided, it would iterate indefinitely. [pressure(float)] [size(float)] Generate a motion input event. --pointer option can be specified multiple times. +--genTestVendorConfigs: Generates fake VehiclePropConfig ranging from 0x5000 to 0x8000 all with + vendor property group, global vehicle area, and int32 vehicle property type. This is mainly used + for testing + +--restoreVendorConfigs: Restores to to the default state if genTestVendorConfigs was used. + Otherwise this will do nothing. + )"; } @@ -836,6 +1059,17 @@ std::string FakeVehicleHardware::parseErrMsg(std::string fieldName, std::string value.c_str(), genFakeDataHelp().c_str()); } +void FakeVehicleHardware::generateVendorConfigs( + std::vector<VehiclePropConfig>& outAllConfigs) const { + for (int i = STARTING_VENDOR_CODE_PROPERTIES_FOR_TEST; + i < ENDING_VENDOR_CODE_PROPERTIES_FOR_TEST; i++) { + VehiclePropConfig config; + config.prop = i; + config.access = VehiclePropertyAccess::READ_WRITE; + outAllConfigs.push_back(config); + } +} + std::string FakeVehicleHardware::genFakeDataCommand(const std::vector<std::string>& options) { if (options.size() < 2) { return "No subcommand specified for genfakedata\n" + genFakeDataHelp(); diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp index b399bdfc65..8d385ddcfe 100644 --- a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp +++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp @@ -60,6 +60,7 @@ namespace vehicle { namespace fake { namespace { +using ::aidl::android::hardware::automotive::vehicle::ErrorState; using ::aidl::android::hardware::automotive::vehicle::GetValueRequest; using ::aidl::android::hardware::automotive::vehicle::GetValueResult; using ::aidl::android::hardware::automotive::vehicle::RawPropValues; @@ -68,6 +69,7 @@ using ::aidl::android::hardware::automotive::vehicle::SetValueResult; using ::aidl::android::hardware::automotive::vehicle::StatusCode; using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReport; using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReq; +using ::aidl::android::hardware::automotive::vehicle::VehicleAreaMirror; using ::aidl::android::hardware::automotive::vehicle::VehicleHwKeyInputAction; using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig; using ::aidl::android::hardware::automotive::vehicle::VehicleProperty; @@ -1035,6 +1037,488 @@ std::vector<SetSpecialValueTestCase> setSpecialValueTestCases() { }, }, }, + SetSpecialValueTestCase{ + .name = "set_automatic_emergency_braking_enabled_false", + .valuesToSet = + { + VehiclePropValue{ + .prop = toInt( + VehicleProperty:: + AUTOMATIC_EMERGENCY_BRAKING_ENABLED), + .value.int32Values = {0}, + }, + }, + .expectedValuesToGet = + { + VehiclePropValue{ + .prop = toInt( + VehicleProperty:: + AUTOMATIC_EMERGENCY_BRAKING_ENABLED), + .value.int32Values = {0}, + }, + VehiclePropValue{ + .prop = toInt( + VehicleProperty:: + AUTOMATIC_EMERGENCY_BRAKING_STATE), + .value.int32Values = {toInt( + ErrorState::NOT_AVAILABLE_DISABLED)}, + }, + }, + }, + SetSpecialValueTestCase{ + .name = "set_automatic_emergency_braking_enabled_true", + .valuesToSet = + { + VehiclePropValue{ + .prop = toInt( + VehicleProperty:: + AUTOMATIC_EMERGENCY_BRAKING_ENABLED), + .value.int32Values = {1}, + }, + }, + .expectedValuesToGet = + { + VehiclePropValue{ + .prop = toInt( + VehicleProperty:: + AUTOMATIC_EMERGENCY_BRAKING_ENABLED), + .value.int32Values = {1}, + }, + VehiclePropValue{ + .prop = toInt( + VehicleProperty:: + AUTOMATIC_EMERGENCY_BRAKING_STATE), + .value.int32Values = {1}, + }, + }, + }, + SetSpecialValueTestCase{ + .name = "set_forward_collision_warning_enabled_false", + .valuesToSet = + { + VehiclePropValue{ + .prop = toInt( + VehicleProperty:: + FORWARD_COLLISION_WARNING_ENABLED), + .value.int32Values = {0}, + }, + }, + .expectedValuesToGet = + { + VehiclePropValue{ + .prop = toInt( + VehicleProperty:: + FORWARD_COLLISION_WARNING_ENABLED), + .value.int32Values = {0}, + }, + VehiclePropValue{ + .prop = toInt(VehicleProperty:: + FORWARD_COLLISION_WARNING_STATE), + .value.int32Values = {toInt( + ErrorState::NOT_AVAILABLE_DISABLED)}, + }, + }, + }, + SetSpecialValueTestCase{ + .name = "set_forward_collision_warning_enabled_true", + .valuesToSet = + { + VehiclePropValue{ + .prop = toInt( + VehicleProperty:: + FORWARD_COLLISION_WARNING_ENABLED), + .value.int32Values = {1}, + }, + }, + .expectedValuesToGet = + { + VehiclePropValue{ + .prop = toInt( + VehicleProperty:: + FORWARD_COLLISION_WARNING_ENABLED), + .value.int32Values = {1}, + }, + VehiclePropValue{ + .prop = toInt(VehicleProperty:: + FORWARD_COLLISION_WARNING_STATE), + .value.int32Values = {1}, + }, + }, + }, + SetSpecialValueTestCase{ + .name = "set_blind_spot_warning_enabled_false", + .valuesToSet = + { + VehiclePropValue{ + .prop = toInt( + VehicleProperty::BLIND_SPOT_WARNING_ENABLED), + .value.int32Values = {0}, + }, + }, + .expectedValuesToGet = + { + VehiclePropValue{ + .prop = toInt( + VehicleProperty::BLIND_SPOT_WARNING_ENABLED), + .value.int32Values = {0}, + }, + VehiclePropValue{ + .prop = toInt( + VehicleProperty::BLIND_SPOT_WARNING_STATE), + .areaId = toInt(VehicleAreaMirror::DRIVER_LEFT), + .value.int32Values = {toInt( + ErrorState::NOT_AVAILABLE_DISABLED)}, + }, + VehiclePropValue{ + .prop = toInt( + VehicleProperty::BLIND_SPOT_WARNING_STATE), + .areaId = toInt(VehicleAreaMirror::DRIVER_RIGHT), + .value.int32Values = {toInt( + ErrorState::NOT_AVAILABLE_DISABLED)}, + }, + }, + }, + SetSpecialValueTestCase{ + .name = "set_blind_spot_warning_enabled_true", + .valuesToSet = + { + VehiclePropValue{ + .prop = toInt( + VehicleProperty::BLIND_SPOT_WARNING_ENABLED), + .value.int32Values = {1}, + }, + }, + .expectedValuesToGet = + { + VehiclePropValue{ + .prop = toInt( + VehicleProperty::BLIND_SPOT_WARNING_ENABLED), + .value.int32Values = {1}, + }, + VehiclePropValue{ + .prop = toInt( + VehicleProperty::BLIND_SPOT_WARNING_STATE), + .areaId = toInt(VehicleAreaMirror::DRIVER_LEFT), + .value.int32Values = {1}, + }, + VehiclePropValue{ + .prop = toInt( + VehicleProperty::BLIND_SPOT_WARNING_STATE), + .areaId = toInt(VehicleAreaMirror::DRIVER_RIGHT), + .value.int32Values = {1}, + }, + }, + }, + SetSpecialValueTestCase{ + .name = "set_lane_departure_warning_enabled_false", + .valuesToSet = + { + VehiclePropValue{ + .prop = toInt(VehicleProperty:: + LANE_DEPARTURE_WARNING_ENABLED), + .value.int32Values = {0}, + }, + }, + .expectedValuesToGet = + { + VehiclePropValue{ + .prop = toInt(VehicleProperty:: + LANE_DEPARTURE_WARNING_ENABLED), + .value.int32Values = {0}, + }, + VehiclePropValue{ + .prop = toInt( + VehicleProperty::LANE_DEPARTURE_WARNING_STATE), + .value.int32Values = {toInt( + ErrorState::NOT_AVAILABLE_DISABLED)}, + }, + }, + }, + SetSpecialValueTestCase{ + .name = "set_lane_departure_warning_enabled_true", + .valuesToSet = + { + VehiclePropValue{ + .prop = toInt(VehicleProperty:: + LANE_DEPARTURE_WARNING_ENABLED), + .value.int32Values = {1}, + }, + }, + .expectedValuesToGet = + { + VehiclePropValue{ + .prop = toInt(VehicleProperty:: + LANE_DEPARTURE_WARNING_ENABLED), + .value.int32Values = {1}, + }, + VehiclePropValue{ + .prop = toInt( + VehicleProperty::LANE_DEPARTURE_WARNING_STATE), + .value.int32Values = {1}, + }, + }, + }, + SetSpecialValueTestCase{ + .name = "set_lane_keep_assist_enabled_false", + .valuesToSet = + { + VehiclePropValue{ + .prop = toInt( + VehicleProperty::LANE_KEEP_ASSIST_ENABLED), + .value.int32Values = {0}, + }, + }, + .expectedValuesToGet = + { + VehiclePropValue{ + .prop = toInt( + VehicleProperty::LANE_KEEP_ASSIST_ENABLED), + .value.int32Values = {0}, + }, + VehiclePropValue{ + .prop = toInt(VehicleProperty::LANE_KEEP_ASSIST_STATE), + .value.int32Values = {toInt( + ErrorState::NOT_AVAILABLE_DISABLED)}, + }, + }, + }, + SetSpecialValueTestCase{ + .name = "set_lane_keep_assist_enabled_true", + .valuesToSet = + { + VehiclePropValue{ + .prop = toInt( + VehicleProperty::LANE_KEEP_ASSIST_ENABLED), + .value.int32Values = {1}, + }, + }, + .expectedValuesToGet = + { + VehiclePropValue{ + .prop = toInt( + VehicleProperty::LANE_KEEP_ASSIST_ENABLED), + .value.int32Values = {1}, + }, + VehiclePropValue{ + .prop = toInt(VehicleProperty::LANE_KEEP_ASSIST_STATE), + .value.int32Values = {1}, + }, + }, + }, + SetSpecialValueTestCase{ + .name = "set_lane_centering_assist_enabled_false", + .valuesToSet = + { + VehiclePropValue{ + .prop = toInt( + VehicleProperty::LANE_CENTERING_ASSIST_ENABLED), + .value.int32Values = {0}, + }, + }, + .expectedValuesToGet = + { + VehiclePropValue{ + .prop = toInt( + VehicleProperty::LANE_CENTERING_ASSIST_ENABLED), + .value.int32Values = {0}, + }, + VehiclePropValue{ + .prop = toInt( + VehicleProperty::LANE_CENTERING_ASSIST_STATE), + .value.int32Values = {toInt( + ErrorState::NOT_AVAILABLE_DISABLED)}, + }, + }, + }, + SetSpecialValueTestCase{ + .name = "set_lane_centering_assist_enabled_true", + .valuesToSet = + { + VehiclePropValue{ + .prop = toInt( + VehicleProperty::LANE_CENTERING_ASSIST_ENABLED), + .value.int32Values = {1}, + }, + }, + .expectedValuesToGet = + { + VehiclePropValue{ + .prop = toInt( + VehicleProperty::LANE_CENTERING_ASSIST_ENABLED), + .value.int32Values = {1}, + }, + VehiclePropValue{ + .prop = toInt( + VehicleProperty::LANE_CENTERING_ASSIST_STATE), + .value.int32Values = {1}, + }, + }, + }, + SetSpecialValueTestCase{ + .name = "set_emergency_lane_keep_assist_enabled_false", + .valuesToSet = + { + VehiclePropValue{ + .prop = toInt( + VehicleProperty:: + EMERGENCY_LANE_KEEP_ASSIST_ENABLED), + .value.int32Values = {0}, + }, + }, + .expectedValuesToGet = + { + VehiclePropValue{ + .prop = toInt( + VehicleProperty:: + EMERGENCY_LANE_KEEP_ASSIST_ENABLED), + .value.int32Values = {0}, + }, + VehiclePropValue{ + .prop = toInt(VehicleProperty:: + EMERGENCY_LANE_KEEP_ASSIST_STATE), + .value.int32Values = {toInt( + ErrorState::NOT_AVAILABLE_DISABLED)}, + }, + }, + }, + SetSpecialValueTestCase{ + .name = "set_emergency_lane_keep_assist_enabled_true", + .valuesToSet = + { + VehiclePropValue{ + .prop = toInt( + VehicleProperty:: + EMERGENCY_LANE_KEEP_ASSIST_ENABLED), + .value.int32Values = {1}, + }, + }, + .expectedValuesToGet = + { + VehiclePropValue{ + .prop = toInt( + VehicleProperty:: + EMERGENCY_LANE_KEEP_ASSIST_ENABLED), + .value.int32Values = {1}, + }, + VehiclePropValue{ + .prop = toInt(VehicleProperty:: + EMERGENCY_LANE_KEEP_ASSIST_STATE), + .value.int32Values = {1}, + }, + }, + }, + SetSpecialValueTestCase{ + .name = "set_cruise_control_enabled_false", + .valuesToSet = + { + VehiclePropValue{ + .prop = toInt(VehicleProperty::CRUISE_CONTROL_ENABLED), + .value.int32Values = {0}, + }, + }, + .expectedValuesToGet = + { + VehiclePropValue{ + .prop = toInt(VehicleProperty::CRUISE_CONTROL_ENABLED), + .value.int32Values = {0}, + }, + VehiclePropValue{ + .prop = toInt(VehicleProperty::CRUISE_CONTROL_TYPE), + .value.int32Values = {toInt( + ErrorState::NOT_AVAILABLE_DISABLED)}, + }, + VehiclePropValue{ + .prop = toInt(VehicleProperty::CRUISE_CONTROL_STATE), + .value.int32Values = {toInt( + ErrorState::NOT_AVAILABLE_DISABLED)}, + }, + }, + }, + SetSpecialValueTestCase{ + .name = "set_cruise_control_enabled_true", + .valuesToSet = + { + VehiclePropValue{ + .prop = toInt(VehicleProperty::CRUISE_CONTROL_ENABLED), + .value.int32Values = {1}, + }, + }, + .expectedValuesToGet = + { + VehiclePropValue{ + .prop = toInt(VehicleProperty::CRUISE_CONTROL_ENABLED), + .value.int32Values = {1}, + }, + VehiclePropValue{ + .prop = toInt(VehicleProperty::CRUISE_CONTROL_TYPE), + .value.int32Values = {1}, + }, + VehiclePropValue{ + .prop = toInt(VehicleProperty::CRUISE_CONTROL_STATE), + .value.int32Values = {1}, + }, + }, + }, + SetSpecialValueTestCase{ + .name = "set_hands_on_detection_enabled_false", + .valuesToSet = + { + VehiclePropValue{ + .prop = toInt( + VehicleProperty::HANDS_ON_DETECTION_ENABLED), + .value.int32Values = {0}, + }, + }, + .expectedValuesToGet = + { + VehiclePropValue{ + .prop = toInt( + VehicleProperty::HANDS_ON_DETECTION_ENABLED), + .value.int32Values = {0}, + }, + VehiclePropValue{ + .prop = toInt(VehicleProperty:: + HANDS_ON_DETECTION_DRIVER_STATE), + .value.int32Values = {toInt( + ErrorState::NOT_AVAILABLE_DISABLED)}, + }, + VehiclePropValue{ + .prop = toInt( + VehicleProperty::HANDS_ON_DETECTION_WARNING), + .value.int32Values = {toInt( + ErrorState::NOT_AVAILABLE_DISABLED)}, + }, + }, + }, + SetSpecialValueTestCase{ + .name = "set_hands_on_detection_enabled_true", + .valuesToSet = + { + VehiclePropValue{ + .prop = toInt( + VehicleProperty::HANDS_ON_DETECTION_ENABLED), + .value.int32Values = {1}, + }, + }, + .expectedValuesToGet = + { + VehiclePropValue{ + .prop = toInt( + VehicleProperty::HANDS_ON_DETECTION_ENABLED), + .value.int32Values = {1}, + }, + VehiclePropValue{ + .prop = toInt(VehicleProperty:: + HANDS_ON_DETECTION_DRIVER_STATE), + .value.int32Values = {1}, + }, + VehiclePropValue{ + .prop = toInt( + VehicleProperty::HANDS_ON_DETECTION_WARNING), + .value.int32Values = {1}, + }, + }, + }, }; } @@ -1052,7 +1536,7 @@ TEST_P(FakeVehicleHardwareSpecialValuesTest, testSetSpecialProperties) { std::vector<VehiclePropValue> gotValues; for (const auto& value : tc.expectedValuesToGet) { - auto result = getValue(VehiclePropValue{.prop = value.prop}); + auto result = getValue(VehiclePropValue{.prop = value.prop, .areaId = value.areaId}); ASSERT_TRUE(result.ok()) << "failed to get property " << value.prop << " status:" << getStatus(result); @@ -1263,6 +1747,157 @@ TEST_F(FakeVehicleHardwareTest, testHvacPowerOnSendCurrentHvacPropValues) { } } +TEST_F(FakeVehicleHardwareTest, testGetAdasPropNotAvailable) { + std::unordered_map<int32_t, std::vector<int32_t>> adasEnabledPropToDependentProps = { + { + toInt(VehicleProperty::CRUISE_CONTROL_ENABLED), + { + toInt(VehicleProperty::CRUISE_CONTROL_TARGET_SPEED), + toInt(VehicleProperty::ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP), + toInt(VehicleProperty:: + ADAPTIVE_CRUISE_CONTROL_LEAD_VEHICLE_MEASURED_DISTANCE), + }, + }, + }; + for (auto& enabledToDependents : adasEnabledPropToDependentProps) { + int32_t adasEnabledPropertyId = enabledToDependents.first; + StatusCode status = + setValue(VehiclePropValue{.prop = adasEnabledPropertyId, .value.int32Values = {0}}); + EXPECT_EQ(status, StatusCode::OK); + + auto& dependentProps = enabledToDependents.second; + for (auto dependentProp : dependentProps) { + auto getValueResult = getValue(VehiclePropValue{.prop = dependentProp}); + EXPECT_FALSE(getValueResult.ok()); + EXPECT_EQ(getValueResult.error(), StatusCode::NOT_AVAILABLE_DISABLED); + } + } +} + +TEST_F(FakeVehicleHardwareTest, testSetAdasPropNotAvailable) { + std::unordered_map<int32_t, std::vector<int32_t>> adasEnabledPropToDependentProps = { + { + toInt(VehicleProperty::LANE_CENTERING_ASSIST_ENABLED), + { + toInt(VehicleProperty::LANE_CENTERING_ASSIST_COMMAND), + }, + }, + { + toInt(VehicleProperty::CRUISE_CONTROL_ENABLED), + { + toInt(VehicleProperty::CRUISE_CONTROL_COMMAND), + toInt(VehicleProperty::ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP), + }, + }, + }; + for (auto& enabledToDependents : adasEnabledPropToDependentProps) { + int32_t adasEnabledPropertyId = enabledToDependents.first; + StatusCode status = + setValue(VehiclePropValue{.prop = adasEnabledPropertyId, .value.int32Values = {0}}); + EXPECT_EQ(status, StatusCode::OK); + + auto& dependentProps = enabledToDependents.second; + for (auto dependentProp : dependentProps) { + StatusCode status = setValue(VehiclePropValue{.prop = dependentProp}); + EXPECT_EQ(status, StatusCode::NOT_AVAILABLE_DISABLED); + } + } +} + +TEST_F(FakeVehicleHardwareTest, testSendAdasPropertiesState) { + std::unordered_map<int32_t, std::vector<int32_t>> adasEnabledPropToAdasPropWithErrorState = { + // AEB + { + toInt(VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_ENABLED), + { + toInt(VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_STATE), + }, + }, + // FCW + { + toInt(VehicleProperty::FORWARD_COLLISION_WARNING_ENABLED), + { + toInt(VehicleProperty::FORWARD_COLLISION_WARNING_STATE), + }, + }, + // BSW + { + toInt(VehicleProperty::BLIND_SPOT_WARNING_ENABLED), + { + toInt(VehicleProperty::BLIND_SPOT_WARNING_STATE), + }, + }, + // LDW + { + toInt(VehicleProperty::LANE_DEPARTURE_WARNING_ENABLED), + { + toInt(VehicleProperty::LANE_DEPARTURE_WARNING_STATE), + }, + }, + // LKA + { + toInt(VehicleProperty::LANE_KEEP_ASSIST_ENABLED), + { + toInt(VehicleProperty::LANE_KEEP_ASSIST_STATE), + }, + }, + // LCA + { + toInt(VehicleProperty::LANE_CENTERING_ASSIST_ENABLED), + { + toInt(VehicleProperty::LANE_CENTERING_ASSIST_STATE), + }, + }, + // ELKA + { + toInt(VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_ENABLED), + { + toInt(VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_STATE), + }, + }, + // CC + { + toInt(VehicleProperty::CRUISE_CONTROL_ENABLED), + { + toInt(VehicleProperty::CRUISE_CONTROL_TYPE), + toInt(VehicleProperty::CRUISE_CONTROL_STATE), + }, + }, + // HOD + { + toInt(VehicleProperty::HANDS_ON_DETECTION_ENABLED), + { + toInt(VehicleProperty::HANDS_ON_DETECTION_DRIVER_STATE), + toInt(VehicleProperty::HANDS_ON_DETECTION_WARNING), + }, + }, + }; + for (auto& enabledToErrorStateProps : adasEnabledPropToAdasPropWithErrorState) { + int32_t adasEnabledPropertyId = enabledToErrorStateProps.first; + StatusCode status = + setValue(VehiclePropValue{.prop = adasEnabledPropertyId, .value.int32Values = {0}}); + EXPECT_EQ(status, StatusCode::OK); + + clearChangedProperties(); + status = + setValue(VehiclePropValue{.prop = adasEnabledPropertyId, .value.int32Values = {1}}); + EXPECT_EQ(status, StatusCode::OK); + + // If we enable the ADAS feature, we expect to receive one property event for every ADAS + // state property plus one event for enabling the feature. + std::unordered_set<int32_t> expectedChangedPropIds(enabledToErrorStateProps.second.begin(), + enabledToErrorStateProps.second.end()); + expectedChangedPropIds.insert(adasEnabledPropertyId); + + std::unordered_set<int32_t> changedPropIds; + auto events = getChangedProperties(); + for (const auto& event : events) { + changedPropIds.insert(event.prop); + } + EXPECT_EQ(changedPropIds, expectedChangedPropIds); + } +} + TEST_F(FakeVehicleHardwareTest, testGetUserPropertySetOnly) { for (VehicleProperty prop : std::vector<VehicleProperty>({ VehicleProperty::INITIAL_USER_INFO, diff --git a/automotive/vehicle/aidl/impl/hardware/include/IVehicleHardware.h b/automotive/vehicle/aidl/impl/hardware/include/IVehicleHardware.h index d92ccfddab..e53947ee33 100644 --- a/automotive/vehicle/aidl/impl/hardware/include/IVehicleHardware.h +++ b/automotive/vehicle/aidl/impl/hardware/include/IVehicleHardware.h @@ -35,6 +35,8 @@ struct DumpResult { bool callerShouldDumpState; // The dumped information for the caller to print. std::string buffer; + // To pass if DefaultVehicleHal should refresh the property configs + bool refreshPropertyConfigs = false; }; // A structure to represent a set value error event reported from vehicle. diff --git a/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h b/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h index 0439ac6eac..2c2cf1a5bd 100644 --- a/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h +++ b/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h @@ -164,6 +164,7 @@ class DefaultVehicleHal final : public aidl::android::hardware::automotive::vehi static constexpr int64_t TIMEOUT_IN_NANO = 30'000'000'000; // heart beat event interval: 3s static constexpr int64_t HEART_BEAT_INTERVAL_IN_NANO = 3'000'000'000; + bool mShouldRefreshPropertyConfigs; std::unique_ptr<IVehicleHardware> mVehicleHardware; // mConfigsByPropId and mConfigFile are only modified during initialization, so no need to @@ -212,7 +213,6 @@ class DefaultVehicleHal final : public aidl::android::hardware::automotive::vehi android::base::Result<std::vector<int64_t>> checkDuplicateRequests( const std::vector<aidl::android::hardware::automotive::vehicle::SetValueRequest>& requests); - VhalResult<void> checkSubscribeOptions( const std::vector<aidl::android::hardware::automotive::vehicle::SubscribeOptions>& options); @@ -236,6 +236,8 @@ class DefaultVehicleHal final : public aidl::android::hardware::automotive::vehi bool checkDumpPermission(); + bool getAllPropConfigsFromHardware(); + // The looping handler function to process all onBinderDied or onBinderUnlinked events in // mBinderEvents. void onBinderDiedUnlinkedHandler(); diff --git a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp index a7ac1b4309..98cfc398af 100644 --- a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp +++ b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp @@ -128,23 +128,10 @@ size_t DefaultVehicleHal::SubscriptionClients::countClients() { DefaultVehicleHal::DefaultVehicleHal(std::unique_ptr<IVehicleHardware> vehicleHardware) : mVehicleHardware(std::move(vehicleHardware)), mPendingRequestPool(std::make_shared<PendingRequestPool>(TIMEOUT_IN_NANO)) { - auto configs = mVehicleHardware->getAllPropertyConfigs(); - for (auto& config : configs) { - mConfigsByPropId[config.prop] = config; - } - VehiclePropConfigs vehiclePropConfigs; - vehiclePropConfigs.payloads = std::move(configs); - auto result = LargeParcelableBase::parcelableToStableLargeParcelable(vehiclePropConfigs); - if (!result.ok()) { - ALOGE("failed to convert configs to shared memory file, error: %s, code: %d", - result.error().message().c_str(), static_cast<int>(result.error().code())); + if (!getAllPropConfigsFromHardware()) { return; } - if (result.value() != nullptr) { - mConfigFile = std::move(result.value()); - } - mSubscriptionClients = std::make_shared<SubscriptionClients>(mPendingRequestPool); auto subscribeIdByClient = std::make_shared<SubscribeIdByClient>(); @@ -304,6 +291,27 @@ void DefaultVehicleHal::setTimeout(int64_t timeoutInNano) { mPendingRequestPool = std::make_unique<PendingRequestPool>(timeoutInNano); } +bool DefaultVehicleHal::getAllPropConfigsFromHardware() { + auto configs = mVehicleHardware->getAllPropertyConfigs(); + for (auto& config : configs) { + mConfigsByPropId[config.prop] = config; + } + VehiclePropConfigs vehiclePropConfigs; + vehiclePropConfigs.payloads = std::move(configs); + auto result = LargeParcelableBase::parcelableToStableLargeParcelable(vehiclePropConfigs); + if (!result.ok()) { + ALOGE("failed to convert configs to shared memory file, error: %s, code: %d", + result.error().message().c_str(), static_cast<int>(result.error().code())); + mConfigFile = nullptr; + return false; + } + + if (result.value() != nullptr) { + mConfigFile = std::move(result.value()); + } + return true; +} + ScopedAStatus DefaultVehicleHal::getAllPropConfigs(VehiclePropConfigs* output) { if (mConfigFile != nullptr) { output->payloads.clear(); @@ -798,6 +806,9 @@ binder_status_t DefaultVehicleHal::dump(int fd, const char** args, uint32_t numA options.clear(); } DumpResult result = mVehicleHardware->dump(options); + if (result.refreshPropertyConfigs) { + getAllPropConfigsFromHardware(); + } dprintf(fd, "%s", (result.buffer + "\n").c_str()); if (!result.callerShouldDumpState) { return STATUS_OK; diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl index ce3a840683..d9c6de7ef9 100644 --- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl +++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl @@ -4384,12 +4384,6 @@ enum VehicleProperty { /*********************************************************************************************** * Start of ADAS Properties * - * Android is not a safety critical system and is provided as is without any timing guarantees, - * representations or warranties. OEMs implementing these properties, and clients using these - * properties should ensure they complete any necessary safety reviews, in accordance with - * industry standards, to ensure the use of these APIs do not negatively impact driver safety. - * Use of any Google APIs will be at the OEM's sole risk. - * * Allocate IDs in range of 0x1000 (inclusive) to 0x1100 (exclusive) for ADAS properties **********************************************************************************************/ @@ -4629,9 +4623,7 @@ enum VehicleProperty { /** * Lane Centering Assist (LCA) commands. * - * Commands to activate and suspend LCA. They are only valid when LANE_CENTERING_ASSIST_ENABLED - * = true. Otherwise, these commands must return StatusCode#NOT_AVAILABLE or - * StatusCode#NOT_AVAILABLE_DISABLED. + * Commands to activate and suspend LCA. * * When the command ACTIVATE from LaneCenteringAssistCommmand is sent, * LANE_CENTERING_ASSIST_STATE must be set to LaneCenteringAssistState#ACTIVATION_REQUESTED. @@ -4643,6 +4635,14 @@ enum VehicleProperty { * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues must be defined unless * all enum values of LaneCenteringAssistCommand are supported. * + * When this property is not available because LCA is disabled (i.e. + * LANE_CENTERING_ASSIST_ENABLED is false), this property must return + * StatusCode#NOT_AVAILABLE_DISABLED. If LANE_CENTERING_ASSIST_STATE is implemented and the + * state is set to an ErrorState value, then this property must return a StatusCode that aligns + * with the ErrorState value. For example, if LANE_CENTERING_ASSIST_STATE is set to + * ErrorState#NOT_AVAILABLE_SPEED_LOW, then this property must return + * StatusCode#NOT_AVAILABLE_SPEED_LOW. + * * @change_mode VehiclePropertyChangeMode.ON_CHANGE * @access VehiclePropertyAccess.WRITE * @data_enum LaneCenteringAssistCommmand @@ -4794,7 +4794,11 @@ enum VehicleProperty { * this property must return StatusCode#INVALID_ARG. * * When this property is not available because CC is disabled (i.e. CRUISE_CONTROL_ENABLED is - * false), this property must return StatusCode#NOT_AVAILABLE_DISABLED. + * false), this property must return StatusCode#NOT_AVAILABLE_DISABLED. If CRUISE_CONTROL_STATE + * is implemented and the state is set to an ErrorState value, then this property must return a + * StatusCode that aligns with the ErrorState value. For example, if CRUISE_CONTROL_STATE is set + * to ErrorState#NOT_AVAILABLE_SPEED_LOW, then this property must return + * StatusCode#NOT_AVAILABLE_SPEED_LOW. * * @change_mode VehiclePropertyChangeMode.ON_CHANGE * @access VehiclePropertyAccess.WRITE @@ -4813,7 +4817,11 @@ enum VehicleProperty { * The minFloatValue represents the lower bound of the target speed. * * When this property is not available because CC is disabled (i.e. CRUISE_CONTROL_ENABLED is - * false), this property must return StatusCode#NOT_AVAILABLE_DISABLED. + * false), this property must return StatusCode#NOT_AVAILABLE_DISABLED. If CRUISE_CONTROL_STATE + * is implemented and the state is set to an ErrorState value, then this property must return a + * StatusCode that aligns with the ErrorState value. For example, if CRUISE_CONTROL_STATE is set + * to ErrorState#NOT_AVAILABLE_SPEED_LOW, then this property must return + * StatusCode#NOT_AVAILABLE_SPEED_LOW. * * @change_mode VehiclePropertyChangeMode.ON_CHANGE * @access VehiclePropertyAccess.READ @@ -4836,7 +4844,11 @@ enum VehicleProperty { * writable. * * When this property is not available because CC is disabled (i.e. CRUISE_CONTROL_ENABLED is - * false), this property must return StatusCode#NOT_AVAILABLE_DISABLED. + * false), this property must return StatusCode#NOT_AVAILABLE_DISABLED. If CRUISE_CONTROL_STATE + * is implemented and the state is set to an ErrorState value, then this property must return a + * StatusCode that aligns with the ErrorState value. For example, if CRUISE_CONTROL_STATE is set + * to ErrorState#NOT_AVAILABLE_SPEED_LOW, then this property must return + * StatusCode#NOT_AVAILABLE_SPEED_LOW. * * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to * implement it as VehiclePropertyAccess.READ only. @@ -4865,7 +4877,11 @@ enum VehicleProperty { * StatusCode.NOT_AVAILABLE. * * When this property is not available because CC is disabled (i.e. CRUISE_CONTROL_ENABLED is - * false), this property must return StatusCode#NOT_AVAILABLE_DISABLED. + * false), this property must return StatusCode#NOT_AVAILABLE_DISABLED. If CRUISE_CONTROL_STATE + * is implemented and the state is set to an ErrorState value, then this property must return a + * StatusCode that aligns with the ErrorState value. For example, if CRUISE_CONTROL_STATE is set + * to ErrorState#NOT_AVAILABLE_SPEED_LOW, then this property must return + * StatusCode#NOT_AVAILABLE_SPEED_LOW. * * @change_mode VehiclePropertyChangeMode.CONTINUOUS * @access VehiclePropertyAccess.READ diff --git a/biometrics/OWNERS b/biometrics/OWNERS index e162d2df47..58998c1026 100644 --- a/biometrics/OWNERS +++ b/biometrics/OWNERS @@ -2,3 +2,7 @@ ilyamaty@google.com jeffpu@google.com jbolinger@google.com joshmccloskey@google.com +diyab@google.com +austindelgado@google.com +spdonghao@google.com +wenhuiy@google.com diff --git a/biometrics/fingerprint/aidl/default/Android.bp b/biometrics/fingerprint/aidl/default/Android.bp index fe224c9885..16302eb9af 100644 --- a/biometrics/fingerprint/aidl/default/Android.bp +++ b/biometrics/fingerprint/aidl/default/Android.bp @@ -110,6 +110,32 @@ cc_test { require_root: true, } +cc_test { + name: "android.hardware.biometrics.fingerprint.SessionTest", + local_include_dirs: ["include"], + srcs: [ + "tests/SessionTest.cpp", + "Session.cpp", + "FakeFingerprintEngine.cpp", + "FakeLockoutTracker.cpp", + ], + shared_libs: [ + "libbase", + "libbinder_ndk", + "android.hardware.biometrics.common.thread", + ], + static_libs: [ + "libandroid.hardware.biometrics.fingerprint.VirtualProps", + "android.hardware.biometrics.fingerprint-V3-ndk", + "android.hardware.biometrics.common-V3-ndk", + "android.hardware.keymaster-V4-ndk", + "android.hardware.biometrics.common.util", + ], + vendor: true, + test_suites: ["general-tests"], + require_root: true, +} + sysprop_library { name: "android.hardware.biometrics.fingerprint.VirtualProps", srcs: ["fingerprint.sysprop"], diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.cpp b/biometrics/fingerprint/aidl/default/Fingerprint.cpp index 7808a13d16..f00a49d26e 100644 --- a/biometrics/fingerprint/aidl/default/Fingerprint.cpp +++ b/biometrics/fingerprint/aidl/default/Fingerprint.cpp @@ -103,6 +103,8 @@ ndk::ScopedAStatus Fingerprint::createSession(int32_t sensorId, int32_t userId, mSession = SharedRefBase::make<Session>(sensorId, userId, cb, mEngine.get(), &mWorker); *out = mSession; + mSession->linkToDeath(cb->asBinder().get()); + LOG(INFO) << "createSession: sensorId:" << sensorId << " userId:" << userId; return ndk::ScopedAStatus::ok(); } diff --git a/biometrics/fingerprint/aidl/default/Session.cpp b/biometrics/fingerprint/aidl/default/Session.cpp index 38d6a134e2..c06c9317e8 100644 --- a/biometrics/fingerprint/aidl/default/Session.cpp +++ b/biometrics/fingerprint/aidl/default/Session.cpp @@ -25,6 +25,14 @@ namespace aidl::android::hardware::biometrics::fingerprint { +void onClientDeath(void* cookie) { + LOG(INFO) << "FingerprintService has died"; + Session* session = static_cast<Session*>(cookie); + if (session && !session->isClosed()) { + session->close(); + } +} + Session::Session(int sensorId, int userId, std::shared_ptr<ISessionCallback> cb, FakeFingerprintEngine* engine, WorkerThread* worker) : mSensorId(sensorId), @@ -39,6 +47,12 @@ Session::Session(int sensorId, int userId, std::shared_ptr<ISessionCallback> cb, CHECK(mEngine); CHECK(mWorker); CHECK(mCb); + + mDeathRecipient = AIBinder_DeathRecipient_new(onClientDeath); +} + +binder_status_t Session::linkToDeath(AIBinder* binder) { + return AIBinder_linkToDeath(binder, mDeathRecipient, this); } void Session::scheduleStateOrCrash(SessionState state) { @@ -228,6 +242,7 @@ ndk::ScopedAStatus Session::close() { // Crashing."; mCurrentState = SessionState::CLOSED; mCb->onSessionClosed(); + AIBinder_DeathRecipient_delete(mDeathRecipient); return ndk::ScopedAStatus::ok(); } diff --git a/biometrics/fingerprint/aidl/default/include/Session.h b/biometrics/fingerprint/aidl/default/include/Session.h index b596d9e2a9..526d5797cc 100644 --- a/biometrics/fingerprint/aidl/default/include/Session.h +++ b/biometrics/fingerprint/aidl/default/include/Session.h @@ -42,6 +42,8 @@ enum class SessionState { RESETTING_LOCKOUT, }; +void onClientDeath(void* cookie); + class Session : public BnSession { public: Session(int sensorId, int userId, std::shared_ptr<ISessionCallback> cb, @@ -101,6 +103,8 @@ class Session : public BnSession { ndk::ScopedAStatus setIgnoreDisplayTouches(bool shouldIgnore) override; + binder_status_t linkToDeath(AIBinder* binder); + bool isClosed(); private: @@ -139,6 +143,9 @@ class Session : public BnSession { // modified from both the main and the worker threads. std::atomic<SessionState> mScheduledState; std::atomic<SessionState> mCurrentState; + + // Binder death handler. + AIBinder_DeathRecipient* mDeathRecipient; }; } // namespace aidl::android::hardware::biometrics::fingerprint diff --git a/biometrics/fingerprint/aidl/default/tests/SessionTest.cpp b/biometrics/fingerprint/aidl/default/tests/SessionTest.cpp new file mode 100644 index 0000000000..3b96d7f099 --- /dev/null +++ b/biometrics/fingerprint/aidl/default/tests/SessionTest.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2023 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 <android/binder_process.h> +#include <fingerprint.sysprop.h> +#include <gtest/gtest.h> + +#include <android-base/logging.h> + +#include <aidl/android/hardware/biometrics/fingerprint/BnSessionCallback.h> + +#include "Session.h" +#include "thread/WorkerThread.h" +#include "util/Util.h" + +using namespace ::android::fingerprint::virt; +using namespace ::aidl::android::hardware::biometrics::fingerprint; + +namespace aidl::android::hardware::biometrics::fingerprint { + +class TestSessionCallback : public BnSessionCallback { + public: + ndk::ScopedAStatus onChallengeGenerated(int64_t /*challenge*/) override { + return ndk::ScopedAStatus::ok(); + }; + ::ndk::ScopedAStatus onChallengeRevoked(int64_t /*challenge*/) override { + return ndk::ScopedAStatus::ok(); + }; + ::ndk::ScopedAStatus onError(fingerprint::Error /*error*/, int32_t /*vendorCode*/) override { + return ndk::ScopedAStatus::ok(); + }; + ::ndk::ScopedAStatus onEnrollmentProgress(int32_t /*enrollmentId*/, + int32_t /*remaining*/) override { + return ndk::ScopedAStatus::ok(); + }; + + ::ndk::ScopedAStatus onAuthenticationSucceeded(int32_t /*enrollmentId*/, + const keymaster::HardwareAuthToken&) override { + return ndk::ScopedAStatus::ok(); + }; + ::ndk::ScopedAStatus onAuthenticationFailed() override { return ndk::ScopedAStatus::ok(); }; + ::ndk::ScopedAStatus onInteractionDetected() override { return ndk::ScopedAStatus::ok(); }; + ndk::ScopedAStatus onAcquired(AcquiredInfo /*info*/, int32_t /*vendorCode*/) override { + return ndk::ScopedAStatus::ok(); + } + ::ndk::ScopedAStatus onEnrollmentsEnumerated( + const std::vector<int32_t>& /*enrollmentIds*/) override { + return ndk::ScopedAStatus::ok(); + }; + ::ndk::ScopedAStatus onEnrollmentsRemoved( + const std::vector<int32_t>& /*enrollmentIds*/) override { + return ndk::ScopedAStatus::ok(); + }; + ::ndk::ScopedAStatus onAuthenticatorIdRetrieved(int64_t /*authenticatorId*/) override { + return ndk::ScopedAStatus::ok(); + }; + ::ndk::ScopedAStatus onAuthenticatorIdInvalidated(int64_t /*authenticatorId*/) override { + return ndk::ScopedAStatus::ok(); + }; + ::ndk::ScopedAStatus onLockoutPermanent() override { return ndk::ScopedAStatus::ok(); }; + ndk::ScopedAStatus onLockoutTimed(int64_t /* timeout */) override { + return ndk::ScopedAStatus::ok(); + } + ndk::ScopedAStatus onLockoutCleared() override { return ndk::ScopedAStatus::ok(); } + ndk::ScopedAStatus onSessionClosed() override { + mIsClosed = true; + return ndk::ScopedAStatus::ok(); + } + + bool mIsClosed = false; +}; + +class SessionTest : public ::testing::Test { + public: + SessionTest() : mWorker(2) {} + + protected: + void SetUp() override { + mCb = ndk::SharedRefBase::make<TestSessionCallback>(); + mSession = ndk::SharedRefBase::make<Session>(1, 2, mCb, &mFakeFingerprintEngine, &mWorker); + ASSERT_TRUE(mSession != nullptr); + mSession->linkToDeath(mCb->asBinder().get()); + } + + void TearDown() override {} + + std::shared_ptr<Session> mSession; + std::shared_ptr<TestSessionCallback> mCb; + + private: + FakeFingerprintEngine mFakeFingerprintEngine; + WorkerThread mWorker; +}; + +TEST_F(SessionTest, close) { + ASSERT_TRUE(!mSession->isClosed()); + ASSERT_TRUE(!mCb->mIsClosed); + onClientDeath(nullptr); + ASSERT_TRUE(!mSession->isClosed()); + ASSERT_TRUE(!mCb->mIsClosed); + onClientDeath(static_cast<void*>(mSession.get())); + ASSERT_TRUE(mSession->isClosed()); + ASSERT_TRUE(mCb->mIsClosed); +} + +} // namespace aidl::android::hardware::biometrics::fingerprint + +int main(int argc, char** argv) { + testing::InitGoogleTest(&argc, argv); + ABinderProcess_startThreadPool(); + return RUN_ALL_TESTS(); +} diff --git a/bluetooth/aidl/TEST_MAPPING b/bluetooth/aidl/TEST_MAPPING index d1de251577..41a508eb21 100644 --- a/bluetooth/aidl/TEST_MAPPING +++ b/bluetooth/aidl/TEST_MAPPING @@ -5,7 +5,7 @@ "options": [ { // TODO(b/275847929) - "exclude-filter": "VtsHalBluetoothTargetTest.PerInstance/BluetoothAidlTest#Cdd_C_12_1_Bluetooth5Requirements/0_android_hardware_bluetooth_IBluetoothHci_default" + "exclude-filter": "VtsHalBluetoothTargetTest.PerInstance/BluetoothAidlTest#Vsr_Bluetooth5Requirements/0_android_hardware_bluetooth_IBluetoothHci_default" } ] } @@ -16,7 +16,7 @@ "options": [ { // TODO(b/275847929) - "exclude-filter": "VtsHalBluetoothTargetTest.PerInstance/BluetoothAidlTest#Cdd_C_12_1_Bluetooth5Requirements/0_android_hardware_bluetooth_IBluetoothHci_default" + "exclude-filter": "VtsHalBluetoothTargetTest.PerInstance/BluetoothAidlTest#Vsr_Bluetooth5Requirements/0_android_hardware_bluetooth_IBluetoothHci_default" } ] } diff --git a/bluetooth/aidl/default/BluetoothHci.cpp b/bluetooth/aidl/default/BluetoothHci.cpp index d4e4b34c6e..ac2eabc86d 100644 --- a/bluetooth/aidl/default/BluetoothHci.cpp +++ b/bluetooth/aidl/default/BluetoothHci.cpp @@ -117,11 +117,9 @@ int BluetoothHci::getFdFromDevPath() { strerror(errno)); return fd; } - if (int ret = SetTerminalRaw(mFd) < 0) { - ALOGE("Could not make %s a raw terminal %d(%s)", mDevPath.c_str(), ret, + if (int ret = SetTerminalRaw(fd) < 0) { + ALOGI("Could not make %s a raw terminal %d(%s)", mDevPath.c_str(), ret, strerror(errno)); - ::close(fd); - return -1; } return fd; } diff --git a/bluetooth/aidl/default/service.cpp b/bluetooth/aidl/default/service.cpp index 9af2a08727..ef4b884fc0 100644 --- a/bluetooth/aidl/default/service.cpp +++ b/bluetooth/aidl/default/service.cpp @@ -30,7 +30,7 @@ using ::android::hardware::joinRpcThreadpool; int main(int /* argc */, char** /* argv */) { ALOGI("Bluetooth HAL starting"); - if (!ABinderProcess_setThreadPoolMaxThreadCount(1)) { + if (!ABinderProcess_setThreadPoolMaxThreadCount(0)) { ALOGI("failed to set thread pool max thread count"); return 1; } diff --git a/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp b/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp index 529e092dc7..e5222a764d 100644 --- a/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp +++ b/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp @@ -14,12 +14,14 @@ * limitations under the License. */ +#include <VtsCoreUtil.h> #include <aidl/Gtest.h> #include <aidl/Vintf.h> #include <aidl/android/hardware/bluetooth/BnBluetoothHciCallbacks.h> #include <aidl/android/hardware/bluetooth/IBluetoothHci.h> #include <aidl/android/hardware/bluetooth/IBluetoothHciCallbacks.h> #include <aidl/android/hardware/bluetooth/Status.h> +#include <android-base/properties.h> #include <android/binder_auto_utils.h> #include <android/binder_manager.h> #include <android/binder_process.h> @@ -67,6 +69,7 @@ using ::bluetooth::hci::ReadLocalVersionInformationBuilder; using ::bluetooth::hci::ReadLocalVersionInformationCompleteView; static constexpr uint8_t kMinLeAdvSetForBt5 = 16; +static constexpr uint8_t kMinLeAdvSetForBt5FoTv = 10; static constexpr uint8_t kMinLeResolvingListForBt5 = 8; static constexpr size_t kNumHciCommandsBandwidth = 100; @@ -81,6 +84,40 @@ static constexpr std::chrono::milliseconds kInterfaceCloseDelayMs(200); // To discard Qualcomm ACL debugging static constexpr uint16_t kAclHandleQcaDebugMessage = 0xedc; +static int get_vsr_api_level() { + int vendor_api_level = + ::android::base::GetIntProperty("ro.vendor.api_level", -1); + if (vendor_api_level != -1) { + return vendor_api_level; + } + + // Android S and older devices do not define ro.vendor.api_level + vendor_api_level = ::android::base::GetIntProperty("ro.board.api_level", -1); + if (vendor_api_level == -1) { + vendor_api_level = + ::android::base::GetIntProperty("ro.board.first_api_level", -1); + } + + int product_api_level = + ::android::base::GetIntProperty("ro.product.first_api_level", -1); + if (product_api_level == -1) { + product_api_level = + ::android::base::GetIntProperty("ro.build.version.sdk", -1); + EXPECT_NE(product_api_level, -1) << "Could not find ro.build.version.sdk"; + } + + // VSR API level is the minimum of vendor_api_level and product_api_level. + if (vendor_api_level == -1 || vendor_api_level > product_api_level) { + return product_api_level; + } + return vendor_api_level; +} + +static bool isTv() { + return testing::deviceSupportsFeature("android.software.leanback") || + testing::deviceSupportsFeature("android.hardware.type.television"); +} + class ThroughputLogger { public: explicit ThroughputLogger(std::string task) @@ -914,7 +951,7 @@ TEST_P(BluetoothAidlTest, CallInitializeTwice) { ASSERT_EQ(status, std::future_status::ready); } -TEST_P(BluetoothAidlTest, Cdd_C_12_1_Bluetooth5Requirements) { +TEST_P(BluetoothAidlTest, Vsr_Bluetooth5Requirements) { std::vector<uint8_t> version_event; send_and_wait_for_cmd_complete(ReadLocalVersionInformationBuilder::Create(), version_event); @@ -959,7 +996,12 @@ TEST_P(BluetoothAidlTest, Cdd_C_12_1_Bluetooth5Requirements) { ASSERT_TRUE(num_adv_set_view.IsValid()); ASSERT_EQ(::bluetooth::hci::ErrorCode::SUCCESS, num_adv_set_view.GetStatus()); auto num_adv_set = num_adv_set_view.GetNumberSupportedAdvertisingSets(); - ASSERT_GE(num_adv_set, kMinLeAdvSetForBt5); + + if (isTv() && get_vsr_api_level() == __ANDROID_API_U__) { + ASSERT_GE(num_adv_set, kMinLeAdvSetForBt5FoTv); + } else { + ASSERT_GE(num_adv_set, kMinLeAdvSetForBt5); + } std::vector<uint8_t> num_resolving_list_event; send_and_wait_for_cmd_complete(LeReadResolvingListSizeBuilder::Create(), diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/Result.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/Result.aidl index 9f7263a1f1..f775bd04ee 100644 --- a/broadcastradio/aidl/android/hardware/broadcastradio/Result.aidl +++ b/broadcastradio/aidl/android/hardware/broadcastradio/Result.aidl @@ -39,7 +39,7 @@ enum Result { INVALID_ARGUMENTS, /** - * Error used when the service is of invalid state (i.e. callback + * Error used when the service is on invalid state (i.e. callback * is not registered for IBroadcastRadio). */ INVALID_STATE, @@ -50,13 +50,13 @@ enum Result { NOT_SUPPORTED, /** - * Error used when a tune, seek, step or operation is not completed - * within {@link IBroadcastRadio#LIST_COMPLETE_TIMEOUT_MS}. + * Error used when a tune, seek, or step operation is not completed + * within {@link IBroadcastRadio#TUNER_TIMEOUT_MS}. */ TIMEOUT, /** - * Error used when a tune, seek, step or operation is canceled before + * Error used when a tune, seek, or step operation is canceled before * being processed. */ CANCELED, diff --git a/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp b/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp index 622b20b094..f8d301f081 100644 --- a/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp +++ b/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp @@ -3081,7 +3081,11 @@ TEST_P(CameraAidlTest, validateStreamConfigurations) { ASSERT_EQ(blobMinDurations.size(), blobStallDurations.size()); } - // Validate other aspects of stream configuration metadata... + // TODO (b/280887191): Validate other aspects of stream configuration metadata... + + ndk::ScopedAStatus ret = mSession->close(); + mSession = nullptr; + ASSERT_TRUE(ret.isOk()); } } diff --git a/camera/provider/aidl/vts/camera_aidl_test.cpp b/camera/provider/aidl/vts/camera_aidl_test.cpp index 8d4cef13a0..7665f797c1 100644 --- a/camera/provider/aidl/vts/camera_aidl_test.cpp +++ b/camera/provider/aidl/vts/camera_aidl_test.cpp @@ -150,7 +150,7 @@ void CameraAidlTest::waitForReleaseFence( const native_handle_t* releaseFenceHandle = bufferAndTimestamp.buffer.releaseFence; if (releaseFenceHandle != nullptr && releaseFenceHandle->numFds == 1 && releaseFenceHandle->data[0] >= 0) { - releaseFence = new android::Fence(releaseFenceHandle->data[0]); + releaseFence = new android::Fence(dup(releaseFenceHandle->data[0])); } if (releaseFence && releaseFence->isValid()) { releaseFence->wait(/*ms*/ 300); diff --git a/camera/provider/aidl/vts/camera_aidl_test.h b/camera/provider/aidl/vts/camera_aidl_test.h index fe1f048733..588cb503b9 100644 --- a/camera/provider/aidl/vts/camera_aidl_test.h +++ b/camera/provider/aidl/vts/camera_aidl_test.h @@ -552,6 +552,20 @@ class CameraAidlTest : public ::testing::TestWithParam<std::string> { hasInputBuffer(hasInput), collectedResult(1, 10), expectedPhysicalResults(extraPhysicalResult) {} + + ~InFlightRequest() { + for (auto& buffer : resultOutputBuffers) { + native_handle_t* acquireFenceHandle = const_cast<native_handle_t*>( + buffer.buffer.acquireFence); + native_handle_close(acquireFenceHandle); + native_handle_delete(acquireFenceHandle); + + native_handle_t* releaseFenceHandle = const_cast<native_handle_t*>( + buffer.buffer.releaseFence); + native_handle_close(releaseFenceHandle); + native_handle_delete(releaseFenceHandle); + } + } }; static bool matchDeviceName(const std::string& deviceName, const std::string& providerType, diff --git a/camera/provider/aidl/vts/device_cb.cpp b/camera/provider/aidl/vts/device_cb.cpp index ca2f904c0a..7e0969aeae 100644 --- a/camera/provider/aidl/vts/device_cb.cpp +++ b/camera/provider/aidl/vts/device_cb.cpp @@ -428,8 +428,8 @@ bool DeviceCb::processCaptureResultLocked( bufferId, outputBuffer, buffer.status, - ::android::makeFromAidl(buffer.acquireFence), - ::android::makeFromAidl(buffer.releaseFence)}; + ::android::dupFromAidl(buffer.acquireFence), + ::android::dupFromAidl(buffer.releaseFence)}; streamBufferAndTimestamp.timeStamp = systemTime(); request->resultOutputBuffers.push_back(streamBufferAndTimestamp); } diff --git a/compatibility_matrices/compatibility_matrix.8.xml b/compatibility_matrices/compatibility_matrix.8.xml index 4ac95f58f4..c04a4999ae 100644 --- a/compatibility_matrices/compatibility_matrix.8.xml +++ b/compatibility_matrices/compatibility_matrix.8.xml @@ -345,6 +345,7 @@ <name>IRemotelyProvisionedComponent</name> <instance>default</instance> <instance>strongbox</instance> + <instance>widevine</instance> </interface> </hal> <hal format="aidl" optional="true"> diff --git a/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp b/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp index f544d833d9..89a9e23a77 100644 --- a/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp +++ b/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp @@ -133,10 +133,6 @@ TEST_P(ContextHubAidl, TestRegisterCallback) { ASSERT_TRUE(contextHub->registerCallback(getHubId(), cb).isOk()); } -TEST_P(ContextHubAidl, TestRegisterNullCallback) { - ASSERT_TRUE(contextHub->registerCallback(getHubId(), nullptr).isOk()); -} - // Helper callback that puts the async appInfo callback data into a promise class QueryAppsCallback : public android::hardware::contexthub::BnContextHubCallback { public: @@ -195,7 +191,6 @@ TEST_P(ContextHubAidl, TestGetPreloadedNanoappIds) { GTEST_SKIP() << "Not supported -> old API; or not implemented"; } else { ASSERT_TRUE(status.isOk()); - ASSERT_FALSE(preloadedNanoappIds.empty()); } } @@ -323,8 +318,6 @@ void ContextHubAidl::testSettingChanged(Setting setting) { ASSERT_TRUE(contextHub->onSettingChanged(setting, true /* enabled */).isOk()); ASSERT_TRUE(contextHub->onSettingChanged(setting, false /* enabled */).isOk()); - - ASSERT_TRUE(contextHub->registerCallback(getHubId(), nullptr).isOk()); } TEST_P(ContextHubAidl, TestOnLocationSettingChanged) { diff --git a/graphics/common/aidl/android/hardware/graphics/common/Dataspace.aidl b/graphics/common/aidl/android/hardware/graphics/common/Dataspace.aidl index 4f2a0872c3..3ff0a6534b 100644 --- a/graphics/common/aidl/android/hardware/graphics/common/Dataspace.aidl +++ b/graphics/common/aidl/android/hardware/graphics/common/Dataspace.aidl @@ -669,14 +669,16 @@ enum Dataspace { HEIF = 0x1004, /** - * ISO/IEC TBD + * Ultra HDR * - * JPEG image with embedded 10-bit recovery map following the Jpeg/R specification. + * JPEG image with embedded 10-bit recovery map following the Ultra HDR specification. * * This value must always remain aligned with the public ImageFormat Jpeg/R definition and is * valid with formats: - * HAL_PIXEL_FORMAT_BLOB: JPEG image encoded by Jpeg/R encoder according to ISO/IEC TBD. - * The image contains a standard SDR JPEG and a recovery map. Jpeg/R decoders can use the + * HAL_PIXEL_FORMAT_BLOB: JPEG image encoded by Ultra HDR encoder according to + * the <a href="https://developer.android.com/guide/topics/media/hdr-image-format"> + * Ultra HDR Image format specification</a>. + * The image contains a standard SDR JPEG and a recovery map. Ultra HDR decoders can use the * map to recover the 10-bit input image. */ JPEG_R = 0x1005, diff --git a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h index 7812bd773c..2e3152d49f 100644 --- a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h +++ b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h @@ -70,12 +70,6 @@ class ComposerClientWriter { ComposerClientWriter(const ComposerClientWriter&) = delete; ComposerClientWriter& operator=(const ComposerClientWriter&) = delete; - void reset() { - mDisplayCommand.reset(); - mLayerCommand.reset(); - mCommands.clear(); - } - void setColorTransform(int64_t display, const float* matrix) { std::vector<float> matVec; matVec.reserve(16); @@ -235,10 +229,12 @@ class ComposerClientWriter { getLayerCommand(display, layer).blockingRegion.emplace(blocking.begin(), blocking.end()); } - const std::vector<DisplayCommand>& getPendingCommands() { + std::vector<DisplayCommand> takePendingCommands() { flushLayerCommand(); flushDisplayCommand(); - return mCommands; + std::vector<DisplayCommand> moved = std::move(mCommands); + mCommands.clear(); + return moved; } private: @@ -289,6 +285,12 @@ class ComposerClientWriter { } return *mLayerCommand; } + + void reset() { + mDisplayCommand.reset(); + mLayerCommand.reset(); + mCommands.clear(); + } }; } // namespace aidl::android::hardware::graphics::composer3 diff --git a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp index 6fa33927f0..b0472209dc 100644 --- a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp +++ b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp @@ -207,9 +207,8 @@ class GraphicsCompositionTestBase : public ::testing::Test { } void execute() { - const auto& commands = mWriter->getPendingCommands(); + auto commands = mWriter->takePendingCommands(); if (commands.empty()) { - mWriter->reset(); return; } @@ -217,7 +216,6 @@ class GraphicsCompositionTestBase : public ::testing::Test { ASSERT_TRUE(status.isOk()) << "executeCommands failed " << status.getDescription(); mReader.parse(std::move(results)); - mWriter->reset(); } bool getHasReadbackBuffer() { diff --git a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp index 3ea5bf501f..18d36e4c14 100644 --- a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp +++ b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp @@ -655,8 +655,15 @@ TEST_P(GraphicsComposerAidlTest, SetHdrConversionStrategy_Force) { return; } const auto& [status, conversionCapabilities] = mComposerClient->getHdrConversionCapabilities(); + const auto& [status2, hdrCapabilities] = + mComposerClient->getHdrCapabilities(getPrimaryDisplayId()); + const auto& hdrTypes = hdrCapabilities.types; for (auto conversionCapability : conversionCapabilities) { if (conversionCapability.outputType != common::Hdr::INVALID) { + if (std::find(hdrTypes.begin(), hdrTypes.end(), conversionCapability.outputType) == + hdrTypes.end()) { + continue; + } common::HdrConversionStrategy hdrConversionStrategy; hdrConversionStrategy.set<common::HdrConversionStrategy::Tag::forceHdrConversion>( conversionCapability.outputType); @@ -674,6 +681,11 @@ TEST_P(GraphicsComposerAidlTest, SetHdrConversionStrategy_Auto) { return; } const auto& [status, conversionCapabilities] = mComposerClient->getHdrConversionCapabilities(); + const auto& [status2, hdrCapabilities] = + mComposerClient->getHdrCapabilities(getPrimaryDisplayId()); + if (hdrCapabilities.types.size() <= 0) { + return; + } std::vector<aidl::android::hardware::graphics::common::Hdr> autoHdrTypes; for (auto conversionCapability : conversionCapabilities) { if (conversionCapability.outputType != common::Hdr::INVALID) { @@ -1171,15 +1183,13 @@ class GraphicsComposerAidlCommandTest : public GraphicsComposerAidlTest { void execute() { std::vector<CommandResultPayload> payloads; for (auto& [_, writer] : mWriters) { - const auto& commands = writer.getPendingCommands(); + auto commands = writer.takePendingCommands(); if (commands.empty()) { - writer.reset(); continue; } auto [status, results] = mComposerClient->executeCommands(commands); ASSERT_TRUE(status.isOk()) << "executeCommands failed " << status.getDescription(); - writer.reset(); payloads.reserve(payloads.size() + results.size()); payloads.insert(payloads.end(), std::make_move_iterator(results.begin()), diff --git a/identity/aidl/vts/VtsIWritableIdentityCredentialTests.cpp b/identity/aidl/vts/VtsIWritableIdentityCredentialTests.cpp index 94d4c881b8..eb74fa2b7c 100644 --- a/identity/aidl/vts/VtsIWritableIdentityCredentialTests.cpp +++ b/identity/aidl/vts/VtsIWritableIdentityCredentialTests.cpp @@ -125,7 +125,8 @@ TEST_P(IdentityCredentialTests, verifyAttestationSuccessWithRemoteProvisioning) MacedPublicKey macedPublicKey; std::vector<uint8_t> attestationKey; - result = rpc->generateEcdsaP256KeyPair(/*testMode=*/true, &macedPublicKey, &attestationKey); + // Start by RPC version 3, we don't support testMode=true. So just verify testMode=false here. + result = rpc->generateEcdsaP256KeyPair(/*testMode=*/false, &macedPublicKey, &attestationKey); ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage(); optional<vector<vector<uint8_t>>> remotelyProvisionedCertChain = @@ -176,7 +177,8 @@ TEST_P(IdentityCredentialTests, verifyRemotelyProvisionedKeyMayOnlyBeSetOnce) { MacedPublicKey macedPublicKey; std::vector<uint8_t> attestationKey; - result = rpc->generateEcdsaP256KeyPair(/*testMode=*/true, &macedPublicKey, &attestationKey); + // Start by RPC version 3, we don't support testMode=true. So just verify testMode=false here. + result = rpc->generateEcdsaP256KeyPair(/*testMode=*/false, &macedPublicKey, &attestationKey); ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage(); optional<vector<vector<uint8_t>>> remotelyProvisionedCertChain = diff --git a/input/classifier/1.0/vts/functional/Android.bp b/input/classifier/1.0/vts/functional/Android.bp index 5ff1457dcd..22346ed8b4 100644 --- a/input/classifier/1.0/vts/functional/Android.bp +++ b/input/classifier/1.0/vts/functional/Android.bp @@ -25,6 +25,7 @@ package { cc_test { name: "VtsHalInputClassifierV1_0TargetTest", + cpp_std: "c++20", defaults: ["VtsHalTargetTestDefaults"], srcs: [ ":inputconstants_aidl", diff --git a/keymaster/4.0/vts/functional/Android.bp b/keymaster/4.0/vts/functional/Android.bp index f9a02baa56..e1dfcfc3d1 100644 --- a/keymaster/4.0/vts/functional/Android.bp +++ b/keymaster/4.0/vts/functional/Android.bp @@ -30,13 +30,17 @@ cc_test { "keymaster_hidl_hal_test.cpp", ], srcs: [ + "BootloaderStateTest.cpp", "HmacKeySharingTest.cpp", "VerificationTokenTest.cpp", "keymaster_hidl_hal_test.cpp", ], static_libs: [ "android.hardware.keymaster@4.0", + "libavb_user", + "libavb", "libcrypto_static", + "libfs_mgr", "libkeymaster4support", "libkeymaster4vtstest", ], @@ -64,6 +68,7 @@ cc_test_library { ], static_libs: [ "android.hardware.keymaster@4.0", + "libcrypto_static", "libkeymaster4support", ], } diff --git a/keymaster/4.0/vts/functional/BootloaderStateTest.cpp b/keymaster/4.0/vts/functional/BootloaderStateTest.cpp new file mode 100644 index 0000000000..6b5e8bf856 --- /dev/null +++ b/keymaster/4.0/vts/functional/BootloaderStateTest.cpp @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2023 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> +#include <optional> +#include <string> +#include <vector> + +#include <android-base/properties.h> +#include <fstab/fstab.h> +#include <libavb/libavb.h> +#include <libavb_user/avb_ops_user.h> + +#include "KeymasterHidlTest.h" + +namespace android::hardware::keymaster::V4_0::test { + +using ::std::string; +using ::std::vector; + +// Since this test needs to talk to Keymaster HAL, it can only run as root. Thus, +// bootloader can not be locked. +class BootloaderStateTest : public KeymasterHidlTest { + public: + virtual void SetUp() override { + KeymasterHidlTest::SetUp(); + + // Generate a key. + auto ec = GenerateKey(AuthorizationSetBuilder() + .Authorization(TAG_NO_AUTH_REQUIRED) + .EcdsaSigningKey(EcCurve::P_256) + .Digest(Digest::SHA_2_256)); + ASSERT_EQ(ec, ErrorCode::OK) << "Failed to generate key."; + + // Generate attestation. + hidl_vec<hidl_vec<uint8_t>> cert_chain; + ec = AttestKey(AuthorizationSetBuilder() + .Authorization(TAG_ATTESTATION_CHALLENGE, HidlBuf("challenge")) + .Authorization(TAG_ATTESTATION_APPLICATION_ID, HidlBuf("foo")), + &cert_chain); + ASSERT_EQ(ec, ErrorCode::OK) << "Failed to generate attestation."; + + X509_Ptr cert(parse_cert_blob(cert_chain[0])); + ASSERT_TRUE(cert.get()) << "Failed to parse certificate blob."; + + ASN1_OCTET_STRING* attest_rec = get_attestation_record(cert.get()); + ASSERT_TRUE(attest_rec) << "Failed to get attestation record."; + + // Parse root of trust. + HidlBuf verified_boot_key; + keymaster_verified_boot_t verified_boot_state; + bool device_locked; + HidlBuf verified_boot_hash; + auto result = + parse_root_of_trust(attest_rec->data, attest_rec->length, &verified_boot_key, + &verified_boot_state, &device_locked, &verified_boot_hash); + ASSERT_EQ(result, ErrorCode::OK) << "Failed to parse root of trust."; + } + + hidl_vec<uint8_t> attestedVbKey_; + keymaster_verified_boot_t attestedVbState_; + bool attestedBootloaderState_; + hidl_vec<uint8_t> attestedVbmetaDigest_; +}; + +// Check that attested bootloader state is set to unlocked. +TEST_P(BootloaderStateTest, BootloaderIsUnlocked) { + ASSERT_FALSE(attestedBootloaderState_) + << "This test runs as root. Bootloader must be unlocked."; +} + +// Check that verified boot state is set to "unverified", i.e. "orange". +TEST_P(BootloaderStateTest, VbStateIsUnverified) { + // Unlocked bootloader implies that verified boot state must be "unverified". + ASSERT_EQ(attestedVbState_, KM_VERIFIED_BOOT_UNVERIFIED) + << "Verified boot state must be \"UNVERIFIED\" aka \"orange\"."; + + // AVB spec stipulates that bootloader must set "androidboot.verifiedbootstate" parameter + // on the kernel command-line. This parameter is exposed to userspace as + // "ro.boot.verifiedbootstate" property. + auto vbStateProp = ::android::base::GetProperty("ro.boot.verifiedbootstate", ""); + ASSERT_EQ(vbStateProp, "orange") + << "Verified boot state must be \"UNVERIFIED\" aka \"orange\"."; +} + +// Following error codes from avb_slot_data() mean that slot data was loaded +// (even if verification failed). +static inline bool avb_slot_data_loaded(AvbSlotVerifyResult result) { + switch (result) { + case AVB_SLOT_VERIFY_RESULT_OK: + case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION: + case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX: + case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED: + return true; + default: + return false; + } +} + +// Check that attested vbmeta digest is correct. +TEST_P(BootloaderStateTest, VbmetaDigest) { + AvbSlotVerifyData* avbSlotData; + auto suffix = fs_mgr_get_slot_suffix(); + const char* partitions[] = {nullptr}; + auto avbOps = avb_ops_user_new(); + + // For VTS, devices run with vendor_boot-debug.img, which is not release key + // signed. Use AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR to bypass avb + // verification errors. This is OK since we only care about the digest for + // this test case. + auto result = avb_slot_verify(avbOps, partitions, suffix.c_str(), + AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR, + AVB_HASHTREE_ERROR_MODE_EIO, &avbSlotData); + ASSERT_TRUE(avb_slot_data_loaded(result)) << "Failed to load avb slot data"; + + // Unfortunately, bootloader is not required to report the algorithm used + // to calculate the digest. There are only two supported options though, + // SHA256 and SHA512. Attested VBMeta digest must match one of these. + vector<uint8_t> digest256(AVB_SHA256_DIGEST_SIZE); + vector<uint8_t> digest512(AVB_SHA512_DIGEST_SIZE); + + avb_slot_verify_data_calculate_vbmeta_digest(avbSlotData, AVB_DIGEST_TYPE_SHA256, + digest256.data()); + avb_slot_verify_data_calculate_vbmeta_digest(avbSlotData, AVB_DIGEST_TYPE_SHA512, + digest512.data()); + + ASSERT_TRUE((attestedVbmetaDigest_ == digest256) || (attestedVbmetaDigest_ == digest512)) + << "Attested digest does not match computed digest."; +} + +INSTANTIATE_KEYMASTER_HIDL_TEST(BootloaderStateTest); + +} // namespace android::hardware::keymaster::V4_0::test diff --git a/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp b/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp index 315a4bd08a..e2ad0ef2c5 100644 --- a/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp +++ b/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp @@ -841,6 +841,30 @@ std::vector<Digest> KeymasterHidlTest::InvalidDigests() { return {}; } +X509* parse_cert_blob(const hidl_vec<uint8_t>& blob) { + const uint8_t* p = blob.data(); + return d2i_X509(nullptr, &p, blob.size()); +} + +ASN1_OCTET_STRING* get_attestation_record(X509* certificate) { + ASN1_OBJECT_Ptr oid(OBJ_txt2obj(kAttestionRecordOid, 1 /* dotted string format */)); + EXPECT_TRUE(!!oid.get()); + if (!oid.get()) return nullptr; + + int location = X509_get_ext_by_OBJ(certificate, oid.get(), -1 /* search from beginning */); + EXPECT_NE(-1, location) << "Attestation extension not found in certificate"; + if (location == -1) return nullptr; + + X509_EXTENSION* attest_rec_ext = X509_get_ext(certificate, location); + EXPECT_TRUE(!!attest_rec_ext) + << "Found attestation extension but couldn't retrieve it? Probably a BoringSSL bug."; + if (!attest_rec_ext) return nullptr; + + ASN1_OCTET_STRING* attest_rec = X509_EXTENSION_get_data(attest_rec_ext); + EXPECT_TRUE(!!attest_rec) << "Attestation extension contained no data"; + return attest_rec; +} + } // namespace test } // namespace V4_0 } // namespace keymaster diff --git a/keymaster/4.0/vts/functional/KeymasterHidlTest.h b/keymaster/4.0/vts/functional/KeymasterHidlTest.h index ad30aa7792..67829ec93a 100644 --- a/keymaster/4.0/vts/functional/KeymasterHidlTest.h +++ b/keymaster/4.0/vts/functional/KeymasterHidlTest.h @@ -22,7 +22,9 @@ #include <hidl/GtestPrinter.h> #include <hidl/ServiceManagement.h> +#include <keymasterV4_0/attestation_record.h> #include <keymasterV4_0/authorization_set.h> +#include <keymasterV4_0/openssl_utils.h> namespace android { namespace hardware { @@ -241,6 +243,11 @@ class KeymasterHidlTest : public ::testing::TestWithParam<std::string> { testing::ValuesIn(KeymasterHidlTest::build_params()), \ android::hardware::PrintInstanceNameToString) +X509* parse_cert_blob(const hidl_vec<uint8_t>& blob); +// Extract attestation record from cert. Returned object is still part of cert; don't free it +// separately. +ASN1_OCTET_STRING* get_attestation_record(X509* certificate); + } // namespace test } // namespace V4_0 } // namespace keymaster diff --git a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp index 728cc91f41..b7099047fe 100644 --- a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp +++ b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp @@ -263,11 +263,6 @@ struct RSA_Delete { void operator()(RSA* p) { RSA_free(p); } }; -X509* parse_cert_blob(const hidl_vec<uint8_t>& blob) { - const uint8_t* p = blob.data(); - return d2i_X509(nullptr, &p, blob.size()); -} - bool verify_chain(const hidl_vec<hidl_vec<uint8_t>>& chain, const std::string& msg, const std::string& signature) { { @@ -337,27 +332,6 @@ bool verify_chain(const hidl_vec<hidl_vec<uint8_t>>& chain, const std::string& m return true; } -// Extract attestation record from cert. Returned object is still part of cert; don't free it -// separately. -ASN1_OCTET_STRING* get_attestation_record(X509* certificate) { - ASN1_OBJECT_Ptr oid(OBJ_txt2obj(kAttestionRecordOid, 1 /* dotted string format */)); - EXPECT_TRUE(!!oid.get()); - if (!oid.get()) return nullptr; - - int location = X509_get_ext_by_OBJ(certificate, oid.get(), -1 /* search from beginning */); - EXPECT_NE(-1, location) << "Attestation extension not found in certificate"; - if (location == -1) return nullptr; - - X509_EXTENSION* attest_rec_ext = X509_get_ext(certificate, location); - EXPECT_TRUE(!!attest_rec_ext) - << "Found attestation extension but couldn't retrieve it? Probably a BoringSSL bug."; - if (!attest_rec_ext) return nullptr; - - ASN1_OCTET_STRING* attest_rec = X509_EXTENSION_get_data(attest_rec_ext); - EXPECT_TRUE(!!attest_rec) << "Attestation extension contained no data"; - return attest_rec; -} - bool tag_in_list(const KeyParameter& entry) { // Attestations don't contain everything in key authorization lists, so we need to filter // the key lists to produce the lists that we expect to match the attestations. diff --git a/radio/1.0/vts/functional/radio_hidl_hal_data.cpp b/radio/1.0/vts/functional/radio_hidl_hal_data.cpp index 655b869333..38cb33b07e 100644 --- a/radio/1.0/vts/functional/radio_hidl_hal_data.cpp +++ b/radio/1.0/vts/functional/radio_hidl_hal_data.cpp @@ -87,12 +87,19 @@ TEST_P(RadioHidlTest, getDataRegistrationState) { cellIdentities.cellIdentityTdscdma.size()); if (checkMccMnc) { - // 32 bit system gets result: "\xff\xff\xff..." from RIL, which is not testable. Only - // test for 64 bit here. TODO: remove this limit after b/113181277 being fixed. - if (hidl_mcc.size() < 4 && hidl_mnc.size() < 4) { + // 32 bit system gets result: "\xff\xff\xff..." from RIL, which is not testable. + // Only test for 64 bit here. TODO: remove this limit after b/113181277 being fixed. + int mccSize = hidl_mcc.size(); + EXPECT_TRUE(mccSize == 0 || mccSize == 3); + if (mccSize > 0) { int mcc = stoi(hidl_mcc); - int mnc = stoi(hidl_mnc); EXPECT_TRUE(mcc >= 0 && mcc <= 999); + } + + int mncSize = hidl_mnc.size(); + EXPECT_TRUE(mncSize == 0 || mncSize == 2 || mncSize == 3); + if (mncSize > 0) { + int mnc = stoi(hidl_mnc); EXPECT_TRUE(mnc >= 0 && mnc <= 999); } } diff --git a/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp b/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp index 624d00381f..ee8b4dcb95 100644 --- a/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp +++ b/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp @@ -654,6 +654,8 @@ TEST_P(RadioHidlTest, nvResetConfig) { ASSERT_TRUE(CheckAnyOfErrors(radioRsp->rspInfo.error, {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED})); } + // wait until modem reset finishes + sleep(10); LOG(DEBUG) << "nvResetConfig finished"; } diff --git a/radio/1.0/vts/functional/vts_hal_radio_target_test.xml b/radio/1.0/vts/functional/vts_hal_radio_target_test.xml index 82af2ee388..7aaadff8db 100644 --- a/radio/1.0/vts/functional/vts_hal_radio_target_test.xml +++ b/radio/1.0/vts/functional/vts_hal_radio_target_test.xml @@ -16,6 +16,7 @@ <configuration description="Runs VtsHalRadioV1_0TargetTest."> <option name="test-suite-tag" value="apct" /> <option name="test-suite-tag" value="apct-native" /> + <option name="config-descriptor:metadata" key="token" value="SIM_CARD" /> <!-- TODO: b/154638140, b/152655658: bad interactions --> <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" /> diff --git a/radio/1.1/vts/functional/AndroidTest.xml b/radio/1.1/vts/functional/AndroidTest.xml index f1bc7a80ed..90428f4919 100644 --- a/radio/1.1/vts/functional/AndroidTest.xml +++ b/radio/1.1/vts/functional/AndroidTest.xml @@ -16,6 +16,7 @@ <configuration description="Runs VtsHalRadioV1_1TargetTest."> <option name="test-suite-tag" value="apct" /> <option name="test-suite-tag" value="apct-native" /> + <option name="config-descriptor:metadata" key="token" value="SIM_CARD" /> <!-- TODO: b/154638140, b/152655658: bad interactions --> <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" /> diff --git a/radio/1.2/vts/functional/AndroidTest.xml b/radio/1.2/vts/functional/AndroidTest.xml index 99047602f6..e25249bda5 100644 --- a/radio/1.2/vts/functional/AndroidTest.xml +++ b/radio/1.2/vts/functional/AndroidTest.xml @@ -16,6 +16,7 @@ <configuration description="Runs VtsHalRadioV1_2TargetTest."> <option name="test-suite-tag" value="apct" /> <option name="test-suite-tag" value="apct-native" /> + <option name="config-descriptor:metadata" key="token" value="SIM_CARD" /> <!-- TODO: b/154638140, b/152655658: bad interactions --> <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" /> diff --git a/radio/1.2/vts/functional/radio_hidl_hal_api.cpp b/radio/1.2/vts/functional/radio_hidl_hal_api.cpp index 2400bde9ae..2bce2f957b 100644 --- a/radio/1.2/vts/functional/radio_hidl_hal_api.cpp +++ b/radio/1.2/vts/functional/radio_hidl_hal_api.cpp @@ -120,7 +120,7 @@ TEST_P(RadioHidlTest_v1_2, startNetworkScan_InvalidInterval1) { serial = GetRandomSerialNumber(); ::android::hardware::radio::V1_2::NetworkScanRequest request = { - .type = ScanType::ONE_SHOT, + .type = ScanType::PERIODIC, .interval = 4, .specifiers = {::GERAN_SPECIFIER_P900, ::GERAN_SPECIFIER_850}, .maxSearchTime = 60, @@ -155,7 +155,7 @@ TEST_P(RadioHidlTest_v1_2, startNetworkScan_InvalidInterval2) { serial = GetRandomSerialNumber(); ::android::hardware::radio::V1_2::NetworkScanRequest request = { - .type = ScanType::ONE_SHOT, + .type = ScanType::PERIODIC, .interval = 301, .specifiers = {::GERAN_SPECIFIER_P900, ::GERAN_SPECIFIER_850}, .maxSearchTime = 60, @@ -821,11 +821,20 @@ TEST_P(RadioHidlTest_v1_2, getDataRegistrationState) { cellIdentities.cellIdentityTdscdma.size()); // 32 bit system might return invalid mcc and mnc hidl string "\xff\xff..." - if (checkMccMnc && hidl_mcc.size() < 4 && hidl_mnc.size() < 4) { - int mcc = stoi(hidl_mcc); - int mnc = stoi(hidl_mnc); - EXPECT_TRUE(mcc >= 0 && mcc <= 999); - EXPECT_TRUE(mnc >= 0 && mnc <= 999); + if (checkMccMnc) { + int mccSize = hidl_mcc.size(); + EXPECT_TRUE(mccSize == 0 || mccSize == 3); + if (mccSize > 0) { + int mcc = stoi(hidl_mcc); + EXPECT_TRUE(mcc >= 0 && mcc <= 999); + } + + int mncSize = hidl_mnc.size(); + EXPECT_TRUE(mncSize == 0 || mncSize == 2 || mncSize == 3); + if (mncSize > 0) { + int mnc = stoi(hidl_mnc); + EXPECT_TRUE(mnc >= 0 && mnc <= 999); + } } } diff --git a/radio/1.3/vts/functional/AndroidTest.xml b/radio/1.3/vts/functional/AndroidTest.xml index 9df8f9c9ba..44b74191b3 100644 --- a/radio/1.3/vts/functional/AndroidTest.xml +++ b/radio/1.3/vts/functional/AndroidTest.xml @@ -16,6 +16,7 @@ <configuration description="Runs VtsHalRadioV1_3TargetTest."> <option name="test-suite-tag" value="apct" /> <option name="test-suite-tag" value="apct-native" /> + <option name="config-descriptor:metadata" key="token" value="SIM_CARD" /> <!-- TODO: b/154638140, b/152655658: bad interactions --> <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" /> diff --git a/radio/1.4/vts/functional/AndroidTest.xml b/radio/1.4/vts/functional/AndroidTest.xml index 469e1030d1..d0843e6f6b 100644 --- a/radio/1.4/vts/functional/AndroidTest.xml +++ b/radio/1.4/vts/functional/AndroidTest.xml @@ -16,6 +16,7 @@ <configuration description="Runs VtsHalRadioV1_4TargetTest."> <option name="test-suite-tag" value="apct" /> <option name="test-suite-tag" value="apct-native" /> + <option name="config-descriptor:metadata" key="token" value="SIM_CARD" /> <!-- TODO: b/154638140, b/152655658: bad interactions --> <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" /> diff --git a/radio/1.4/vts/functional/radio_hidl_hal_api.cpp b/radio/1.4/vts/functional/radio_hidl_hal_api.cpp index 8f357a0f5c..744af7546a 100644 --- a/radio/1.4/vts/functional/radio_hidl_hal_api.cpp +++ b/radio/1.4/vts/functional/radio_hidl_hal_api.cpp @@ -335,7 +335,7 @@ TEST_P(RadioHidlTest_v1_4, startNetworkScan_InvalidInterval1) { serial = GetRandomSerialNumber(); ::android::hardware::radio::V1_2::NetworkScanRequest request = { - .type = ScanType::ONE_SHOT, + .type = ScanType::PERIODIC, .interval = 4, .specifiers = {::GERAN_SPECIFIER_P900, ::GERAN_SPECIFIER_850}, .maxSearchTime = 60, @@ -368,7 +368,7 @@ TEST_P(RadioHidlTest_v1_4, startNetworkScan_InvalidInterval2) { serial = GetRandomSerialNumber(); ::android::hardware::radio::V1_2::NetworkScanRequest request = { - .type = ScanType::ONE_SHOT, + .type = ScanType::PERIODIC, .interval = 301, .specifiers = {::GERAN_SPECIFIER_P900, ::GERAN_SPECIFIER_850}, .maxSearchTime = 60, diff --git a/radio/1.5/vts/functional/radio_hidl_hal_api.cpp b/radio/1.5/vts/functional/radio_hidl_hal_api.cpp index 316c308115..fd44e9309e 100644 --- a/radio/1.5/vts/functional/radio_hidl_hal_api.cpp +++ b/radio/1.5/vts/functional/radio_hidl_hal_api.cpp @@ -661,7 +661,7 @@ TEST_P(RadioHidlTest_v1_5, startNetworkScan_InvalidInterval1) { .channels = {128, 129}}; ::android::hardware::radio::V1_5::NetworkScanRequest request = { - .type = ScanType::ONE_SHOT, + .type = ScanType::PERIODIC, .interval = 4, .specifiers = {specifierP900, specifier850}, .maxSearchTime = 60, @@ -705,7 +705,7 @@ TEST_P(RadioHidlTest_v1_5, startNetworkScan_InvalidInterval2) { .channels = {128, 129}}; ::android::hardware::radio::V1_5::NetworkScanRequest request = { - .type = ScanType::ONE_SHOT, + .type = ScanType::PERIODIC, .interval = 301, .specifiers = {specifierP900, specifier850}, .maxSearchTime = 60, diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioSim.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioSim.h index f12e5328f3..99e4b25a52 100644 --- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioSim.h +++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioSim.h @@ -40,7 +40,6 @@ class RadioSim : public RadioCompatBase, public aidl::android::hardware::radio:: ::ndk::ScopedAStatus getImsiForApp(int32_t serial, const std::string& aid) override; ::ndk::ScopedAStatus getSimPhonebookCapacity(int32_t serial) override; ::ndk::ScopedAStatus getSimPhonebookRecords(int32_t serial) override; - ::ndk::ScopedAStatus iccCloseLogicalChannel(int32_t serial, int32_t channelId) override; ::ndk::ScopedAStatus iccCloseLogicalChannelWithSessionInfo(int32_t serial, const ::aidl::android::hardware::radio::sim::SessionInfo& recordInfo) override; ::ndk::ScopedAStatus iccIoForApp( @@ -104,6 +103,7 @@ class RadioSim : public RadioCompatBase, public aidl::android::hardware::radio:: protected: std::shared_ptr<::aidl::android::hardware::radio::sim::IRadioSimResponse> respond(); + ::ndk::ScopedAStatus iccCloseLogicalChannel(int32_t serial, int32_t channelId) override; public: using RadioCompatBase::RadioCompatBase; diff --git a/radio/aidl/vts/AndroidTest.xml b/radio/aidl/vts/AndroidTest.xml index 36381d1dd6..7edc072514 100644 --- a/radio/aidl/vts/AndroidTest.xml +++ b/radio/aidl/vts/AndroidTest.xml @@ -16,6 +16,7 @@ <configuration description="Runs VtsHalRadioTargetTest."> <option name="test-suite-tag" value="apct" /> <option name="test-suite-tag" value="apct-native" /> + <option name="config-descriptor:metadata" key="token" value="SIM_CARD" /> <target_preparer class="com.android.tradefed.targetprep.MultiSimPreparer" /> <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"> @@ -31,4 +32,4 @@ <option name="native-test-timeout" value="300000" /> <!-- 5 min --> <option name="module-name" value="VtsHalRadioTargetTest" /> </test> -</configuration>
\ No newline at end of file +</configuration> diff --git a/radio/aidl/vts/radio_aidl_hal_utils.cpp b/radio/aidl/vts/radio_aidl_hal_utils.cpp index 6ed8e7d762..64969dea73 100644 --- a/radio/aidl/vts/radio_aidl_hal_utils.cpp +++ b/radio/aidl/vts/radio_aidl_hal_utils.cpp @@ -16,7 +16,6 @@ #define LOG_TAG "RadioTest" #include "radio_aidl_hal_utils.h" -#include <iostream> #include "VtsCoreUtil.h" #include "radio_config_utils.h" #include "radio_sim_utils.h" @@ -85,7 +84,7 @@ bool isSsSsEnabled() { // Do not use checkSubstringInCommandOutput("getprop persist.radio.multisim.config", "") // until b/148904287 is fixed. We need exact matching instead of partial matching. (i.e. // by definition the empty string "" is a substring of any string). - return !isDsDsEnabled() && !isTsTsEnabled(); + return !isDsDsEnabled() && !isTsTsEnabled() && !isDsDaEnabled(); } bool isDsDsEnabled() { @@ -125,8 +124,8 @@ bool isServiceValidForDeviceConfiguration(std::string& serviceName) { ALOGI("%s instance is not valid for SSSS device.", serviceName.c_str()); return false; } - } else if (isDsDsEnabled()) { - // Device is configured as DSDS. + } else if (isDsDsEnabled() || isDsDaEnabled()) { + // Device is configured as DSDS or DSDA. if (!stringEndsWith(serviceName, RADIO_SERVICE_SLOT1_NAME) && !stringEndsWith(serviceName, RADIO_SERVICE_SLOT2_NAME)) { ALOGI("%s instance is not valid for DSDS device.", serviceName.c_str()); @@ -144,11 +143,25 @@ bool isServiceValidForDeviceConfiguration(std::string& serviceName) { return true; } +void RadioServiceTest::SetUp() { + ALOGD("BEGIN %s#%s", ::testing::UnitTest::GetInstance()->current_test_info()->test_suite_name(), + ::testing::UnitTest::GetInstance()->current_test_info()->name()); + count_ = 0; + serial = -1; +} + +void RadioServiceTest::TearDown() { + count_ = 0; + serial = -1; + ALOGD("END %s#%s", ::testing::UnitTest::GetInstance()->current_test_info()->test_suite_name(), + ::testing::UnitTest::GetInstance()->current_test_info()->name()); +} + /* * Notify that the response message is received. */ void RadioServiceTest::notify(int receivedSerial) { - std::unique_lock<std::mutex> lock(mtx_); + std::lock_guard<std::mutex> lock(mtx_); if (serial == receivedSerial) { count_++; cv_.notify_one(); diff --git a/radio/aidl/vts/radio_aidl_hal_utils.h b/radio/aidl/vts/radio_aidl_hal_utils.h index d515e1a7c0..09c4f144d8 100644 --- a/radio/aidl/vts/radio_aidl_hal_utils.h +++ b/radio/aidl/vts/radio_aidl_hal_utils.h @@ -25,7 +25,6 @@ #include <aidl/android/hardware/radio/sim/CardStatus.h> #include <aidl/android/hardware/radio/sim/IRadioSim.h> #include <utils/Log.h> -#include <vector> using namespace aidl::android::hardware::radio; using aidl::android::hardware::radio::config::SimSlotStatus; @@ -133,14 +132,15 @@ bool isServiceValidForDeviceConfiguration(std::string& serviceName); /** * RadioServiceTest base class */ -class RadioServiceTest { +class RadioServiceTest : public ::testing::TestWithParam<std::string> { protected: - std::mutex mtx_; - std::condition_variable cv_; std::shared_ptr<config::IRadioConfig> radio_config; std::shared_ptr<sim::IRadioSim> radio_sim; public: + void SetUp() override; + void TearDown() override; + /* Used as a mechanism to inform the test about data/event callback */ void notify(int receivedSerial); @@ -155,4 +155,8 @@ class RadioServiceTest { /* Update SIM slot status */ void updateSimSlotStatus(int physicalSlotId); + + private: + std::mutex mtx_; + std::condition_variable cv_; }; diff --git a/radio/aidl/vts/radio_config_test.cpp b/radio/aidl/vts/radio_config_test.cpp index c979d28781..aed3b05b4f 100644 --- a/radio/aidl/vts/radio_config_test.cpp +++ b/radio/aidl/vts/radio_config_test.cpp @@ -14,7 +14,6 @@ * limitations under the License. */ -#include <android-base/logging.h> #include <android/binder_manager.h> #include "radio_config_utils.h" @@ -22,6 +21,7 @@ #define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk()) void RadioConfigTest::SetUp() { + RadioServiceTest::SetUp(); std::string serviceName = GetParam(); radio_config = IRadioConfig::fromBinder( @@ -31,8 +31,6 @@ void RadioConfigTest::SetUp() { radioRsp_config = ndk::SharedRefBase::make<RadioConfigResponse>(*this); ASSERT_NE(nullptr, radioRsp_config.get()); - count_ = 0; - radioInd_config = ndk::SharedRefBase::make<RadioConfigIndication>(*this); ASSERT_NE(nullptr, radioInd_config.get()); diff --git a/radio/aidl/vts/radio_config_utils.h b/radio/aidl/vts/radio_config_utils.h index 3db430db5f..f79aedbf9e 100644 --- a/radio/aidl/vts/radio_config_utils.h +++ b/radio/aidl/vts/radio_config_utils.h @@ -74,9 +74,10 @@ class RadioConfigIndication : public BnRadioConfigIndication { }; // The main test class for Radio AIDL Config. -class RadioConfigTest : public ::testing::TestWithParam<std::string>, public RadioServiceTest { +class RadioConfigTest : public RadioServiceTest { public: - virtual void SetUp() override; + void SetUp() override; + ndk::ScopedAStatus updateSimCardStatus(); /* Override updateSimSlotStatus in RadioServiceTest to not call setResponseFunctions */ void updateSimSlotStatus(); diff --git a/radio/aidl/vts/radio_data_test.cpp b/radio/aidl/vts/radio_data_test.cpp index aa6ac88e1f..0fb2fb404f 100644 --- a/radio/aidl/vts/radio_data_test.cpp +++ b/radio/aidl/vts/radio_data_test.cpp @@ -17,7 +17,6 @@ #include <aidl/android/hardware/radio/RadioAccessFamily.h> #include <aidl/android/hardware/radio/config/IRadioConfig.h> #include <aidl/android/hardware/radio/data/ApnTypes.h> -#include <android-base/logging.h> #include <android/binder_manager.h> #include "radio_data_utils.h" @@ -25,6 +24,7 @@ #define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk()) void RadioDataTest::SetUp() { + RadioServiceTest::SetUp(); std::string serviceName = GetParam(); if (!isServiceValidForDeviceConfiguration(serviceName)) { @@ -39,8 +39,6 @@ void RadioDataTest::SetUp() { radioRsp_data = ndk::SharedRefBase::make<RadioDataResponse>(*this); ASSERT_NE(nullptr, radioRsp_data.get()); - count_ = 0; - radioInd_data = ndk::SharedRefBase::make<RadioDataIndication>(*this); ASSERT_NE(nullptr, radioInd_data.get()); @@ -531,8 +529,7 @@ TEST_P(RadioDataTest, startKeepalive) { ASSERT_TRUE(CheckAnyOfErrors( radioRsp_data->rspInfo.error, - {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::INVALID_ARGUMENTS, - RadioError::REQUEST_NOT_SUPPORTED})); + {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED})); } } @@ -549,15 +546,13 @@ TEST_P(RadioDataTest, stopKeepalive) { ASSERT_TRUE( CheckAnyOfErrors(radioRsp_data->rspInfo.error, - {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, - RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED})); + {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED})); } /* * Test IRadioData.getDataCallList() for the response returned. */ TEST_P(RadioDataTest, getDataCallList) { - LOG(DEBUG) << "getDataCallList"; serial = GetRandomSerialNumber(); radio_data->getDataCallList(serial); @@ -571,14 +566,12 @@ TEST_P(RadioDataTest, getDataCallList) { radioRsp_data->rspInfo.error, {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::SIM_ABSENT})); } - LOG(DEBUG) << "getDataCallList finished"; } /* * Test IRadioData.setDataAllowed() for the response returned. */ TEST_P(RadioDataTest, setDataAllowed) { - LOG(DEBUG) << "setDataAllowed"; serial = GetRandomSerialNumber(); bool allow = true; @@ -591,5 +584,4 @@ TEST_P(RadioDataTest, setDataAllowed) { if (cardStatus.cardState == CardStatus::STATE_ABSENT) { EXPECT_EQ(RadioError::NONE, radioRsp_data->rspInfo.error); } - LOG(DEBUG) << "setDataAllowed finished"; } diff --git a/radio/aidl/vts/radio_data_utils.h b/radio/aidl/vts/radio_data_utils.h index fb91ef61d5..0959207cf6 100644 --- a/radio/aidl/vts/radio_data_utils.h +++ b/radio/aidl/vts/radio_data_utils.h @@ -100,13 +100,13 @@ class RadioDataIndication : public BnRadioDataIndication { }; // The main test class for Radio AIDL Data. -class RadioDataTest : public ::testing::TestWithParam<std::string>, public RadioServiceTest { +class RadioDataTest : public RadioServiceTest { protected: /* Get current data call list */ ndk::ScopedAStatus getDataCallList(); public: - virtual void SetUp() override; + void SetUp() override; /* radio data service handle */ std::shared_ptr<IRadioData> radio_data; diff --git a/radio/aidl/vts/radio_ims_test.cpp b/radio/aidl/vts/radio_ims_test.cpp index 289d3ed54d..1938e0a8b6 100644 --- a/radio/aidl/vts/radio_ims_test.cpp +++ b/radio/aidl/vts/radio_ims_test.cpp @@ -15,7 +15,6 @@ */ #include <aidl/android/hardware/radio/config/IRadioConfig.h> -#include <android-base/logging.h> #include <android/binder_manager.h> #include "radio_ims_utils.h" @@ -23,6 +22,7 @@ #define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk()) void RadioImsTest::SetUp() { + RadioServiceTest::SetUp(); std::string serviceName = GetParam(); if (!isServiceValidForDeviceConfiguration(serviceName)) { @@ -37,8 +37,6 @@ void RadioImsTest::SetUp() { radioRsp_ims = ndk::SharedRefBase::make<RadioImsResponse>(*this); ASSERT_NE(nullptr, radioRsp_ims.get()); - count_ = 0; - radioInd_ims = ndk::SharedRefBase::make<RadioImsIndication>(*this); ASSERT_NE(nullptr, radioInd_ims.get()); diff --git a/radio/aidl/vts/radio_ims_utils.h b/radio/aidl/vts/radio_ims_utils.h index 2bf80dc987..208c94b05c 100644 --- a/radio/aidl/vts/radio_ims_utils.h +++ b/radio/aidl/vts/radio_ims_utils.h @@ -76,12 +76,12 @@ class RadioImsIndication : public BnRadioImsIndication { }; // The main test class for Radio AIDL Ims. -class RadioImsTest : public ::testing::TestWithParam<std::string>, public RadioServiceTest { +class RadioImsTest : public RadioServiceTest { protected: virtual void verifyError(RadioError resp); public: - virtual void SetUp() override; + void SetUp() override; /* radio ims service handle */ std::shared_ptr<IRadioIms> radio_ims; diff --git a/radio/aidl/vts/radio_imsmedia_test.cpp b/radio/aidl/vts/radio_imsmedia_test.cpp index 2b6f5ef8b7..425f6b4d6a 100644 --- a/radio/aidl/vts/radio_imsmedia_test.cpp +++ b/radio/aidl/vts/radio_imsmedia_test.cpp @@ -15,7 +15,6 @@ */ #include <aidl/android/hardware/radio/ims/media/MediaDirection.h> -#include <android-base/logging.h> #include <android/binder_auto_utils.h> #include <android/binder_manager.h> #include <sys/socket.h> @@ -25,10 +24,9 @@ #define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk()) void RadioImsMediaTest::SetUp() { + RadioServiceTest::SetUp(); std::string serviceName = GetParam(); - ALOGD("Enter RadioImsMediaTest."); - radio_imsmedia = IImsMedia::fromBinder( ndk::SpAIBinder(AServiceManager_waitForService(GetParam().c_str()))); ASSERT_NE(nullptr, radio_imsmedia.get()); @@ -38,7 +36,6 @@ void RadioImsMediaTest::SetUp() { radio_imsmediasessionlistener = ndk::SharedRefBase::make<ImsMediaSessionListener>(*this); ASSERT_NE(nullptr, radio_imsmediasessionlistener.get()); - count_ = 0; } TEST_P(RadioImsMediaTest, MOCallSuccess) { diff --git a/radio/aidl/vts/radio_imsmedia_utils.h b/radio/aidl/vts/radio_imsmedia_utils.h index 6143addd03..87f1b00a63 100644 --- a/radio/aidl/vts/radio_imsmedia_utils.h +++ b/radio/aidl/vts/radio_imsmedia_utils.h @@ -79,13 +79,13 @@ class ImsMediaSessionListener : public BnImsMediaSessionListener { }; /* The main test class for Radio AIDL ImsMedia. */ -class RadioImsMediaTest : public ::testing::TestWithParam<std::string>, public RadioServiceTest { +class RadioImsMediaTest : public RadioServiceTest { protected: virtual void verifyError(RtpError inError); virtual ndk::ScopedAStatus triggerOpenSession(int32_t sessionId); public: - virtual void SetUp() override; + void SetUp() override; /* radio imsmedia service handle */ std::shared_ptr<IImsMedia> radio_imsmedia; diff --git a/radio/aidl/vts/radio_messaging_test.cpp b/radio/aidl/vts/radio_messaging_test.cpp index 9f1718b1a0..4ab88d2d8a 100644 --- a/radio/aidl/vts/radio_messaging_test.cpp +++ b/radio/aidl/vts/radio_messaging_test.cpp @@ -15,7 +15,6 @@ */ #include <aidl/android/hardware/radio/config/IRadioConfig.h> -#include <android-base/logging.h> #include <android/binder_manager.h> #include "radio_messaging_utils.h" @@ -23,6 +22,7 @@ #define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk()) void RadioMessagingTest::SetUp() { + RadioServiceTest::SetUp(); std::string serviceName = GetParam(); if (!isServiceValidForDeviceConfiguration(serviceName)) { @@ -37,8 +37,6 @@ void RadioMessagingTest::SetUp() { radioRsp_messaging = ndk::SharedRefBase::make<RadioMessagingResponse>(*this); ASSERT_NE(nullptr, radioRsp_messaging.get()); - count_ = 0; - radioInd_messaging = ndk::SharedRefBase::make<RadioMessagingIndication>(*this); ASSERT_NE(nullptr, radioInd_messaging.get()); @@ -61,7 +59,6 @@ void RadioMessagingTest::SetUp() { * Test IRadioMessaging.sendSms() for the response returned. */ TEST_P(RadioMessagingTest, sendSms) { - LOG(DEBUG) << "sendSms"; serial = GetRandomSerialNumber(); GsmSmsMessage msg; msg.smscPdu = ""; @@ -80,14 +77,12 @@ TEST_P(RadioMessagingTest, sendSms) { CHECK_GENERAL_ERROR)); EXPECT_EQ(0, radioRsp_messaging->sendSmsResult.errorCode); } - LOG(DEBUG) << "sendSms finished"; } /* * Test IRadioMessaging.sendSmsExpectMore() for the response returned. */ TEST_P(RadioMessagingTest, sendSmsExpectMore) { - LOG(DEBUG) << "sendSmsExpectMore"; serial = GetRandomSerialNumber(); GsmSmsMessage msg; msg.smscPdu = ""; @@ -105,14 +100,12 @@ TEST_P(RadioMessagingTest, sendSmsExpectMore) { {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::SIM_ABSENT}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "sendSmsExpectMore finished"; } /* * Test IRadioMessaging.sendCdmaSms() for the response returned. */ TEST_P(RadioMessagingTest, sendCdmaSms) { - LOG(DEBUG) << "sendCdmaSms"; serial = GetRandomSerialNumber(); // Create a CdmaSmsAddress @@ -151,7 +144,6 @@ TEST_P(RadioMessagingTest, sendCdmaSms) { {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::SIM_ABSENT}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "sendCdmaSms finished"; } /* @@ -202,7 +194,6 @@ TEST_P(RadioMessagingTest, sendCdmaSmsExpectMore) { * Test IRadioMessaging.setGsmBroadcastConfig() for the response returned. */ TEST_P(RadioMessagingTest, setGsmBroadcastConfig) { - LOG(DEBUG) << "setGsmBroadcastConfig"; serial = GetRandomSerialNumber(); // Create GsmBroadcastSmsConfigInfo #1 @@ -260,14 +251,12 @@ TEST_P(RadioMessagingTest, setGsmBroadcastConfig) { RadioError::INVALID_MODEM_STATE, RadioError::INVALID_STATE}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "setGsmBroadcastConfig finished"; } /* * Test IRadioMessaging.getGsmBroadcastConfig() for the response returned. */ TEST_P(RadioMessagingTest, getGsmBroadcastConfig) { - LOG(DEBUG) << "getGsmBroadcastConfig"; serial = GetRandomSerialNumber(); radio_messaging->getGsmBroadcastConfig(serial); @@ -282,14 +271,12 @@ TEST_P(RadioMessagingTest, getGsmBroadcastConfig) { {RadioError::NONE, RadioError::INVALID_MODEM_STATE, RadioError::INVALID_STATE}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "getGsmBroadcastConfig finished"; } /* * Test IRadioMessaging.setCdmaBroadcastConfig() for the response returned. */ TEST_P(RadioMessagingTest, setCdmaBroadcastConfig) { - LOG(DEBUG) << "setCdmaBroadcastConfig"; serial = GetRandomSerialNumber(); CdmaBroadcastSmsConfigInfo cbSmsConfig; @@ -310,14 +297,12 @@ TEST_P(RadioMessagingTest, setCdmaBroadcastConfig) { {RadioError::NONE, RadioError::INVALID_MODEM_STATE}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "setCdmaBroadcastConfig finished"; } /* * Test IRadioMessaging.getCdmaBroadcastConfig() for the response returned. */ TEST_P(RadioMessagingTest, getCdmaBroadcastConfig) { - LOG(DEBUG) << "getCdmaBroadcastConfig"; serial = GetRandomSerialNumber(); radio_messaging->getCdmaBroadcastConfig(serial); @@ -330,14 +315,12 @@ TEST_P(RadioMessagingTest, getCdmaBroadcastConfig) { ASSERT_TRUE(CheckAnyOfErrors(radioRsp_messaging->rspInfo.error, {RadioError::NONE}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "getCdmaBroadcastConfig finished"; } /* * Test IRadioMessaging.setCdmaBroadcastActivation() for the response returned. */ TEST_P(RadioMessagingTest, setCdmaBroadcastActivation) { - LOG(DEBUG) << "setCdmaBroadcastActivation"; serial = GetRandomSerialNumber(); bool activate = false; @@ -352,14 +335,12 @@ TEST_P(RadioMessagingTest, setCdmaBroadcastActivation) { {RadioError::NONE, RadioError::INVALID_ARGUMENTS}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "setCdmaBroadcastActivation finished"; } /* * Test IRadioMessaging.setGsmBroadcastActivation() for the response returned. */ TEST_P(RadioMessagingTest, setGsmBroadcastActivation) { - LOG(DEBUG) << "setGsmBroadcastActivation"; serial = GetRandomSerialNumber(); bool activate = false; @@ -376,14 +357,12 @@ TEST_P(RadioMessagingTest, setGsmBroadcastActivation) { RadioError::INVALID_STATE, RadioError::OPERATION_NOT_ALLOWED}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "setGsmBroadcastActivation finished"; } /* * Test IRadioMessaging.acknowledgeLastIncomingGsmSms() for the response returned. */ TEST_P(RadioMessagingTest, acknowledgeLastIncomingGsmSms) { - LOG(DEBUG) << "acknowledgeLastIncomingGsmSms"; serial = GetRandomSerialNumber(); bool success = true; @@ -399,14 +378,12 @@ TEST_P(RadioMessagingTest, acknowledgeLastIncomingGsmSms) { {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "acknowledgeLastIncomingGsmSms finished"; } /* * Test IRadioMessaging.acknowledgeIncomingGsmSmsWithPdu() for the response returned. */ TEST_P(RadioMessagingTest, acknowledgeIncomingGsmSmsWithPdu) { - LOG(DEBUG) << "acknowledgeIncomingGsmSmsWithPdu"; serial = GetRandomSerialNumber(); bool success = true; std::string ackPdu = ""; @@ -422,14 +399,12 @@ TEST_P(RadioMessagingTest, acknowledgeIncomingGsmSmsWithPdu) { {RadioError::INVALID_ARGUMENTS, RadioError::NO_SMS_TO_ACK}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "acknowledgeIncomingGsmSmsWithPdu finished"; } /* * Test IRadioMessaging.acknowledgeLastIncomingCdmaSms() for the response returned. */ TEST_P(RadioMessagingTest, acknowledgeLastIncomingCdmaSms) { - LOG(DEBUG) << "acknowledgeLastIncomingCdmaSms"; serial = GetRandomSerialNumber(); // Create a CdmaSmsAck @@ -448,14 +423,12 @@ TEST_P(RadioMessagingTest, acknowledgeLastIncomingCdmaSms) { {RadioError::INVALID_ARGUMENTS, RadioError::NO_SMS_TO_ACK}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "acknowledgeLastIncomingCdmaSms finished"; } /* * Test IRadioMessaging.sendImsSms() for the response returned. */ TEST_P(RadioMessagingTest, sendImsSms) { - LOG(DEBUG) << "sendImsSms"; serial = GetRandomSerialNumber(); // Create a CdmaSmsAddress @@ -482,7 +455,7 @@ TEST_P(RadioMessagingTest, sendImsSms) { cdmaSmsMessage.bearerData = (std::vector<uint8_t>){15, 0, 3, 32, 3, 16, 1, 8, 16, 53, 76, 68, 6, 51, 106, 0}; - // Creata an ImsSmsMessage + // Create an ImsSmsMessage ImsSmsMessage msg; msg.tech = RadioTechnologyFamily::THREE_GPP2; msg.retry = false; @@ -500,14 +473,12 @@ TEST_P(RadioMessagingTest, sendImsSms) { ASSERT_TRUE(CheckAnyOfErrors(radioRsp_messaging->rspInfo.error, {RadioError::INVALID_ARGUMENTS}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "sendImsSms finished"; } /* * Test IRadioMessaging.getSmscAddress() for the response returned. */ TEST_P(RadioMessagingTest, getSmscAddress) { - LOG(DEBUG) << "getSmscAddress"; serial = GetRandomSerialNumber(); radio_messaging->getSmscAddress(serial); @@ -522,14 +493,12 @@ TEST_P(RadioMessagingTest, getSmscAddress) { RadioError::SIM_ABSENT}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "getSmscAddress finished"; } /* * Test IRadioMessaging.setSmscAddress() for the response returned. */ TEST_P(RadioMessagingTest, setSmscAddress) { - LOG(DEBUG) << "setSmscAddress"; serial = GetRandomSerialNumber(); std::string address = std::string("smscAddress"); @@ -545,14 +514,12 @@ TEST_P(RadioMessagingTest, setSmscAddress) { RadioError::SIM_ABSENT}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "setSmscAddress finished"; } /* * Test IRadioMessaging.writeSmsToSim() for the response returned. */ TEST_P(RadioMessagingTest, writeSmsToSim) { - LOG(DEBUG) << "writeSmsToSim"; serial = GetRandomSerialNumber(); SmsWriteArgs smsWriteArgs; smsWriteArgs.status = SmsWriteArgs::STATUS_REC_UNREAD; @@ -573,14 +540,12 @@ TEST_P(RadioMessagingTest, writeSmsToSim) { RadioError::NETWORK_NOT_READY, RadioError::NO_RESOURCES, RadioError::SIM_ABSENT}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "writeSmsToSim finished"; } /* * Test IRadioMessaging.deleteSmsOnSim() for the response returned. */ TEST_P(RadioMessagingTest, deleteSmsOnSim) { - LOG(DEBUG) << "deleteSmsOnSim"; serial = GetRandomSerialNumber(); int index = 1; @@ -598,14 +563,12 @@ TEST_P(RadioMessagingTest, deleteSmsOnSim) { RadioError::SIM_ABSENT}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "deleteSmsOnSim finished"; } /* * Test IRadioMessaging.writeSmsToRuim() for the response returned. */ TEST_P(RadioMessagingTest, writeSmsToRuim) { - LOG(DEBUG) << "writeSmsToRuim"; serial = GetRandomSerialNumber(); // Create a CdmaSmsAddress @@ -651,14 +614,12 @@ TEST_P(RadioMessagingTest, writeSmsToRuim) { RadioError::NO_SUCH_ENTRY, RadioError::SIM_ABSENT}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "writeSmsToRuim finished"; } /* * Test IRadioMessaging.deleteSmsOnRuim() for the response returned. */ TEST_P(RadioMessagingTest, deleteSmsOnRuim) { - LOG(DEBUG) << "deleteSmsOnRuim"; serial = GetRandomSerialNumber(); int index = 1; @@ -704,14 +665,12 @@ TEST_P(RadioMessagingTest, deleteSmsOnRuim) { RadioError::MODEM_ERR, RadioError::NO_SUCH_ENTRY, RadioError::SIM_ABSENT}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "deleteSmsOnRuim finished"; } /* * Test IRadioMessaging.reportSmsMemoryStatus() for the response returned. */ TEST_P(RadioMessagingTest, reportSmsMemoryStatus) { - LOG(DEBUG) << "reportSmsMemoryStatus"; serial = GetRandomSerialNumber(); bool available = true; @@ -727,5 +686,4 @@ TEST_P(RadioMessagingTest, reportSmsMemoryStatus) { RadioError::MODEM_ERR, RadioError::SIM_ABSENT}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "reportSmsMemoryStatus finished"; } diff --git a/radio/aidl/vts/radio_messaging_utils.h b/radio/aidl/vts/radio_messaging_utils.h index 7b66192679..3bd8346575 100644 --- a/radio/aidl/vts/radio_messaging_utils.h +++ b/radio/aidl/vts/radio_messaging_utils.h @@ -132,9 +132,9 @@ class RadioMessagingIndication : public BnRadioMessagingIndication { }; // The main test class for Radio AIDL Messaging. -class RadioMessagingTest : public ::testing::TestWithParam<std::string>, public RadioServiceTest { +class RadioMessagingTest : public RadioServiceTest { public: - virtual void SetUp() override; + void SetUp() override; /* radio messaging service handle */ std::shared_ptr<IRadioMessaging> radio_messaging; diff --git a/radio/aidl/vts/radio_modem_test.cpp b/radio/aidl/vts/radio_modem_test.cpp index 3454f33b54..c48a46104a 100644 --- a/radio/aidl/vts/radio_modem_test.cpp +++ b/radio/aidl/vts/radio_modem_test.cpp @@ -15,7 +15,6 @@ */ #include <aidl/android/hardware/radio/config/IRadioConfig.h> -#include <android-base/logging.h> #include <android/binder_manager.h> #include "radio_modem_utils.h" @@ -23,6 +22,7 @@ #define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk()) void RadioModemTest::SetUp() { + RadioServiceTest::SetUp(); std::string serviceName = GetParam(); if (!isServiceValidForDeviceConfiguration(serviceName)) { @@ -37,8 +37,6 @@ void RadioModemTest::SetUp() { radioRsp_modem = ndk::SharedRefBase::make<RadioModemResponse>(*this); ASSERT_NE(nullptr, radioRsp_modem.get()); - count_ = 0; - radioInd_modem = ndk::SharedRefBase::make<RadioModemIndication>(*this); ASSERT_NE(nullptr, radioInd_modem.get()); @@ -154,7 +152,6 @@ TEST_P(RadioModemTest, getModemStackStatus) { * Test IRadioModem.getBasebandVersion() for the response returned. */ TEST_P(RadioModemTest, getBasebandVersion) { - LOG(DEBUG) << "getBasebandVersion"; serial = GetRandomSerialNumber(); radio_modem->getBasebandVersion(serial); @@ -165,14 +162,12 @@ TEST_P(RadioModemTest, getBasebandVersion) { if (cardStatus.cardState == CardStatus::STATE_ABSENT) { EXPECT_EQ(RadioError::NONE, radioRsp_modem->rspInfo.error); } - LOG(DEBUG) << "getBasebandVersion finished"; } /* * Test IRadioModem.getDeviceIdentity() for the response returned. */ TEST_P(RadioModemTest, getDeviceIdentity) { - LOG(DEBUG) << "getDeviceIdentity"; serial = GetRandomSerialNumber(); radio_modem->getDeviceIdentity(serial); @@ -184,7 +179,6 @@ TEST_P(RadioModemTest, getDeviceIdentity) { ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error, {RadioError::NONE, RadioError::EMPTY_RECORD})); } - LOG(DEBUG) << "getDeviceIdentity finished"; } /* @@ -198,7 +192,6 @@ TEST_P(RadioModemTest, getImei) { ALOGI("Skipped the test since getImei is not supported on version < 2"); GTEST_SKIP(); } - LOG(DEBUG) << "getImei"; serial = GetRandomSerialNumber(); radio_modem->getImei(serial); @@ -210,14 +203,12 @@ TEST_P(RadioModemTest, getImei) { ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error, {RadioError::NONE, RadioError::EMPTY_RECORD})); } - LOG(DEBUG) << "getImei finished"; } /* * Test IRadioModem.nvReadItem() for the response returned. */ TEST_P(RadioModemTest, nvReadItem) { - LOG(DEBUG) << "nvReadItem"; serial = GetRandomSerialNumber(); radio_modem->nvReadItem(serial, NvItem::LTE_BAND_ENABLE_25); @@ -229,14 +220,12 @@ TEST_P(RadioModemTest, nvReadItem) { ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error, {RadioError::NONE}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "nvReadItem finished"; } /* * Test IRadioModem.nvWriteItem() for the response returned. */ TEST_P(RadioModemTest, nvWriteItem) { - LOG(DEBUG) << "nvWriteItem"; serial = GetRandomSerialNumber(); NvWriteItem item; memset(&item, 0, sizeof(item)); @@ -251,14 +240,12 @@ TEST_P(RadioModemTest, nvWriteItem) { ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error, {RadioError::NONE}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "nvWriteItem finished"; } /* * Test IRadioModem.nvWriteCdmaPrl() for the response returned. */ TEST_P(RadioModemTest, nvWriteCdmaPrl) { - LOG(DEBUG) << "nvWriteCdmaPrl"; serial = GetRandomSerialNumber(); std::vector<uint8_t> prl = {1, 2, 3, 4, 5}; @@ -271,14 +258,12 @@ TEST_P(RadioModemTest, nvWriteCdmaPrl) { ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error, {RadioError::NONE}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "nvWriteCdmaPrl finished"; } /* * Test IRadioModem.nvResetConfig() for the response returned. */ TEST_P(RadioModemTest, nvResetConfig) { - LOG(DEBUG) << "nvResetConfig"; serial = GetRandomSerialNumber(); radio_modem->nvResetConfig(serial, ResetNvType::FACTORY_RESET); @@ -290,14 +275,14 @@ TEST_P(RadioModemTest, nvResetConfig) { ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error, {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED})); } - LOG(DEBUG) << "nvResetConfig finished"; + // wait until modem reset finishes + sleep(10); } /* * Test IRadioModem.getHardwareConfig() for the response returned. */ TEST_P(RadioModemTest, getHardwareConfig) { - LOG(DEBUG) << "getHardwareConfig"; serial = GetRandomSerialNumber(); radio_modem->getHardwareConfig(serial); @@ -309,7 +294,6 @@ TEST_P(RadioModemTest, getHardwareConfig) { ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error, {RadioError::NONE}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "getHardwareConfig finished"; } /* @@ -335,7 +319,6 @@ TEST_P(RadioModemTest, DISABLED_requestShutdown) { * Test IRadioModem.getRadioCapability() for the response returned. */ TEST_P(RadioModemTest, getRadioCapability) { - LOG(DEBUG) << "getRadioCapability"; serial = GetRandomSerialNumber(); radio_modem->getRadioCapability(serial); @@ -346,14 +329,12 @@ TEST_P(RadioModemTest, getRadioCapability) { if (cardStatus.cardState == CardStatus::STATE_ABSENT) { EXPECT_EQ(RadioError::NONE, radioRsp_modem->rspInfo.error); } - LOG(DEBUG) << "getRadioCapability finished"; } /* * Test IRadioModem.setRadioCapability() for the response returned. */ TEST_P(RadioModemTest, setRadioCapability) { - LOG(DEBUG) << "setRadioCapability"; serial = GetRandomSerialNumber(); RadioCapability rc; memset(&rc, 0, sizeof(rc)); @@ -369,14 +350,12 @@ TEST_P(RadioModemTest, setRadioCapability) { {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "setRadioCapability finished"; } /* * Test IRadioModem.getModemActivityInfo() for the response returned. */ TEST_P(RadioModemTest, getModemActivityInfo) { - LOG(DEBUG) << "getModemActivityInfo"; serial = GetRandomSerialNumber(); radio_modem->getModemActivityInfo(serial); @@ -388,14 +367,12 @@ TEST_P(RadioModemTest, getModemActivityInfo) { ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error, {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED})); } - LOG(DEBUG) << "getModemActivityInfo finished"; } /* * Test IRadioModem.sendDeviceState() for the response returned. */ TEST_P(RadioModemTest, sendDeviceState) { - LOG(DEBUG) << "sendDeviceState"; serial = GetRandomSerialNumber(); radio_modem->sendDeviceState(serial, DeviceStateType::POWER_SAVE_MODE, true); @@ -409,5 +386,4 @@ TEST_P(RadioModemTest, sendDeviceState) { ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error, {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED})); } - LOG(DEBUG) << "sendDeviceState finished"; } diff --git a/radio/aidl/vts/radio_modem_utils.h b/radio/aidl/vts/radio_modem_utils.h index d2f5a104bc..d47bdeb921 100644 --- a/radio/aidl/vts/radio_modem_utils.h +++ b/radio/aidl/vts/radio_modem_utils.h @@ -112,9 +112,9 @@ class RadioModemIndication : public BnRadioModemIndication { }; // The main test class for Radio AIDL Modem. -class RadioModemTest : public ::testing::TestWithParam<std::string>, public RadioServiceTest { +class RadioModemTest : public RadioServiceTest { public: - virtual void SetUp() override; + void SetUp() override; /* radio modem service handle */ std::shared_ptr<IRadioModem> radio_modem; diff --git a/radio/aidl/vts/radio_network_test.cpp b/radio/aidl/vts/radio_network_test.cpp index 57bd4fb596..e5da05032f 100644 --- a/radio/aidl/vts/radio_network_test.cpp +++ b/radio/aidl/vts/radio_network_test.cpp @@ -17,7 +17,6 @@ #include <aidl/android/hardware/radio/RadioAccessFamily.h> #include <aidl/android/hardware/radio/config/IRadioConfig.h> #include <aidl/android/hardware/radio/network/IndicationFilter.h> -#include <android-base/logging.h> #include <android/binder_manager.h> #include "radio_network_utils.h" @@ -25,6 +24,7 @@ #define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk()) void RadioNetworkTest::SetUp() { + RadioServiceTest::SetUp(); std::string serviceName = GetParam(); if (!isServiceValidForDeviceConfiguration(serviceName)) { @@ -39,8 +39,6 @@ void RadioNetworkTest::SetUp() { radioRsp_network = ndk::SharedRefBase::make<RadioNetworkResponse>(*this); ASSERT_NE(nullptr, radioRsp_network.get()); - count_ = 0; - radioInd_network = ndk::SharedRefBase::make<RadioNetworkIndication>(*this); ASSERT_NE(nullptr, radioInd_network.get()); @@ -66,12 +64,20 @@ void RadioNetworkTest::stopNetworkScan() { } /* - * Test IRadioNetwork.setAllowedNetworkTypesBitmap for the response returned. + * Test IRadioNetwork.setAllowedNetworkTypesBitmap and IRadioNetwork.getAllowedNetworkTypesBitmap + * for the response returned. */ -TEST_P(RadioNetworkTest, setAllowedNetworkTypesBitmap) { +TEST_P(RadioNetworkTest, setGetAllowedNetworkTypesBitmap) { serial = GetRandomSerialNumber(); - int32_t allowedNetworkTypesBitmap = static_cast<int32_t>(RadioAccessFamily::LTE); + // save current value + radio_network->getAllowedNetworkTypesBitmap(serial); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + int32_t currentAllowedNetworkTypesBitmap = radioRsp_network->networkTypeBitmapResponse; + + // set new value + int32_t allowedNetworkTypesBitmap = static_cast<int32_t>(RadioAccessFamily::LTE); + serial = GetRandomSerialNumber(); radio_network->setAllowedNetworkTypesBitmap(serial, allowedNetworkTypesBitmap); EXPECT_EQ(std::cv_status::no_timeout, wait()); @@ -83,20 +89,6 @@ TEST_P(RadioNetworkTest, setAllowedNetworkTypesBitmap) { RadioError::MODE_NOT_SUPPORTED, RadioError::INTERNAL_ERR, RadioError::MODEM_ERR, RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED, RadioError::NO_RESOURCES})); -} - -/* - * Test IRadioNetwork.getAllowedNetworkTypesBitmap for the response returned. - */ -TEST_P(RadioNetworkTest, getAllowedNetworkTypesBitmap) { - serial = GetRandomSerialNumber(); - int32_t allowedNetworkTypesBitmap = static_cast<int32_t>(RadioAccessFamily::LTE); - - radio_network->setAllowedNetworkTypesBitmap(serial, allowedNetworkTypesBitmap); - - EXPECT_EQ(std::cv_status::no_timeout, wait()); - EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type); - EXPECT_EQ(serial, radioRsp_network->rspInfo.serial); if (radioRsp_network->rspInfo.error == RadioError::NONE) { sleep(3); // wait for modem @@ -112,7 +104,16 @@ TEST_P(RadioNetworkTest, getAllowedNetworkTypesBitmap) { RadioError::OPERATION_NOT_ALLOWED, RadioError::MODE_NOT_SUPPORTED, RadioError::INVALID_ARGUMENTS, RadioError::MODEM_ERR, RadioError::REQUEST_NOT_SUPPORTED, RadioError::NO_RESOURCES})); + if (radioRsp_network->rspInfo.error == RadioError::NONE) { + // verify we get the value we set + ASSERT_EQ(radioRsp_network->networkTypeBitmapResponse, allowedNetworkTypesBitmap); + } } + + // reset value to previous + serial = GetRandomSerialNumber(); + radio_network->setAllowedNetworkTypesBitmap(serial, currentAllowedNetworkTypesBitmap); + EXPECT_EQ(std::cv_status::no_timeout, wait()); } /* @@ -947,7 +948,7 @@ TEST_P(RadioNetworkTest, startNetworkScan_InvalidInterval1) { RadioAccessSpecifier specifier850 = { .accessNetwork = AccessNetwork::GERAN, .bands = band850, .channels = {128, 129}}; - NetworkScanRequest request = {.type = NetworkScanRequest::SCAN_TYPE_ONE_SHOT, + NetworkScanRequest request = {.type = NetworkScanRequest::SCAN_TYPE_PERIODIC, .interval = 4, .specifiers = {specifierP900, specifier850}, .maxSearchTime = 60, @@ -988,7 +989,7 @@ TEST_P(RadioNetworkTest, startNetworkScan_InvalidInterval2) { RadioAccessSpecifier specifier850 = { .accessNetwork = AccessNetwork::GERAN, .bands = band850, .channels = {128, 129}}; - NetworkScanRequest request = {.type = NetworkScanRequest::SCAN_TYPE_ONE_SHOT, + NetworkScanRequest request = {.type = NetworkScanRequest::SCAN_TYPE_PERIODIC, .interval = 301, .specifiers = {specifierP900, specifier850}, .maxSearchTime = 60, @@ -1521,11 +1522,20 @@ TEST_P(RadioNetworkTest, getDataRegistrationState) { } // 32 bit system might return invalid mcc and mnc string "\xff\xff..." - if (checkMccMnc && mcc.size() < 4 && mnc.size() < 4) { - int mcc_int = stoi(mcc); - int mnc_int = stoi(mnc); - EXPECT_TRUE(mcc_int >= 0 && mcc_int <= 999); - EXPECT_TRUE(mnc_int >= 0 && mnc_int <= 999); + if (checkMccMnc) { + int mccSize = mcc.size(); + EXPECT_TRUE(mccSize == 0 || mccSize == 3); + if (mccSize > 0) { + int mcc_int = stoi(mcc); + EXPECT_TRUE(mcc_int >= 0 && mcc_int <= 999); + } + + int mncSize = mnc.size(); + EXPECT_TRUE(mncSize == 0 || mncSize == 2 || mncSize == 3); + if (mncSize > 0) { + int mnc_int = stoi(mnc); + EXPECT_TRUE(mnc_int >= 0 && mnc_int <= 999); + } } // Check for access technology specific info @@ -1653,7 +1663,6 @@ TEST_P(RadioNetworkTest, getImsRegistrationState) { * Test IRadioNetwork.getOperator() for the response returned. */ TEST_P(RadioNetworkTest, getOperator) { - LOG(DEBUG) << "getOperator"; serial = GetRandomSerialNumber(); radio_network->getOperator(serial); @@ -1664,14 +1673,12 @@ TEST_P(RadioNetworkTest, getOperator) { if (cardStatus.cardState == CardStatus::STATE_ABSENT) { EXPECT_EQ(RadioError::NONE, radioRsp_network->rspInfo.error); } - LOG(DEBUG) << "getOperator finished"; } /* * Test IRadioNetwork.getNetworkSelectionMode() for the response returned. */ TEST_P(RadioNetworkTest, getNetworkSelectionMode) { - LOG(DEBUG) << "getNetworkSelectionMode"; serial = GetRandomSerialNumber(); radio_network->getNetworkSelectionMode(serial); @@ -1682,14 +1689,12 @@ TEST_P(RadioNetworkTest, getNetworkSelectionMode) { if (cardStatus.cardState == CardStatus::STATE_ABSENT) { EXPECT_EQ(RadioError::NONE, radioRsp_network->rspInfo.error); } - LOG(DEBUG) << "getNetworkSelectionMode finished"; } /* * Test IRadioNetwork.setNetworkSelectionModeAutomatic() for the response returned. */ TEST_P(RadioNetworkTest, setNetworkSelectionModeAutomatic) { - LOG(DEBUG) << "setNetworkSelectionModeAutomatic"; serial = GetRandomSerialNumber(); radio_network->setNetworkSelectionModeAutomatic(serial); @@ -1703,14 +1708,12 @@ TEST_P(RadioNetworkTest, setNetworkSelectionModeAutomatic) { RadioError::OPERATION_NOT_ALLOWED}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "setNetworkSelectionModeAutomatic finished"; } /* * Test IRadioNetwork.getAvailableNetworks() for the response returned. */ TEST_P(RadioNetworkTest, getAvailableNetworks) { - LOG(DEBUG) << "getAvailableNetworks"; serial = GetRandomSerialNumber(); radio_network->getAvailableNetworks(serial); @@ -1726,14 +1729,12 @@ TEST_P(RadioNetworkTest, getAvailableNetworks) { RadioError::MODEM_ERR, RadioError::OPERATION_NOT_ALLOWED}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "getAvailableNetworks finished"; } /* * Test IRadioNetwork.setBandMode() for the response returned. */ TEST_P(RadioNetworkTest, setBandMode) { - LOG(DEBUG) << "setBandMode"; serial = GetRandomSerialNumber(); radio_network->setBandMode(serial, RadioBandMode::BAND_MODE_USA); @@ -1745,14 +1746,12 @@ TEST_P(RadioNetworkTest, setBandMode) { ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::NONE}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "setBandMode finished"; } /* * Test IRadioNetwork.setLocationUpdates() for the response returned. */ TEST_P(RadioNetworkTest, setLocationUpdates) { - LOG(DEBUG) << "setLocationUpdates"; serial = GetRandomSerialNumber(); radio_network->setLocationUpdates(serial, true); @@ -1764,14 +1763,12 @@ TEST_P(RadioNetworkTest, setLocationUpdates) { ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::NONE, RadioError::SIM_ABSENT})); } - LOG(DEBUG) << "setLocationUpdates finished"; } /* * Test IRadioNetwork.setCdmaRoamingPreference() for the response returned. */ TEST_P(RadioNetworkTest, setCdmaRoamingPreference) { - LOG(DEBUG) << "setCdmaRoamingPreference"; serial = GetRandomSerialNumber(); radio_network->setCdmaRoamingPreference(serial, CdmaRoamingType::HOME_NETWORK); @@ -1784,14 +1781,12 @@ TEST_P(RadioNetworkTest, setCdmaRoamingPreference) { radioRsp_network->rspInfo.error, {RadioError::NONE, RadioError::SIM_ABSENT, RadioError::REQUEST_NOT_SUPPORTED})); } - LOG(DEBUG) << "setCdmaRoamingPreference finished"; } /* * Test IRadioNetwork.getCdmaRoamingPreference() for the response returned. */ TEST_P(RadioNetworkTest, getCdmaRoamingPreference) { - LOG(DEBUG) << "getCdmaRoamingPreference"; serial = GetRandomSerialNumber(); radio_network->getCdmaRoamingPreference(serial); @@ -1805,14 +1800,12 @@ TEST_P(RadioNetworkTest, getCdmaRoamingPreference) { {RadioError::NONE, RadioError::SIM_ABSENT, RadioError::MODEM_ERR}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "getCdmaRoamingPreference finished"; } /* * Test IRadioNetwork.getVoiceRadioTechnology() for the response returned. */ TEST_P(RadioNetworkTest, getVoiceRadioTechnology) { - LOG(DEBUG) << "getVoiceRadioTechnology"; serial = GetRandomSerialNumber(); radio_network->getVoiceRadioTechnology(serial); @@ -1823,14 +1816,12 @@ TEST_P(RadioNetworkTest, getVoiceRadioTechnology) { if (cardStatus.cardState == CardStatus::STATE_ABSENT) { EXPECT_EQ(RadioError::NONE, radioRsp_network->rspInfo.error); } - LOG(DEBUG) << "getVoiceRadioTechnology finished"; } /* * Test IRadioNetwork.setCellInfoListRate() for the response returned. */ TEST_P(RadioNetworkTest, setCellInfoListRate) { - LOG(DEBUG) << "setCellInfoListRate"; serial = GetRandomSerialNumber(); radio_network->setCellInfoListRate(serial, 10); @@ -1842,14 +1833,12 @@ TEST_P(RadioNetworkTest, setCellInfoListRate) { ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED})); } - LOG(DEBUG) << "setCellInfoListRate finished"; } /* * Test IRadioNetwork.supplyNetworkDepersonalization() for the response returned. */ TEST_P(RadioNetworkTest, supplyNetworkDepersonalization) { - LOG(DEBUG) << "supplyNetworkDepersonalization"; serial = GetRandomSerialNumber(); radio_network->supplyNetworkDepersonalization(serial, std::string("test")); @@ -1864,7 +1853,6 @@ TEST_P(RadioNetworkTest, supplyNetworkDepersonalization) { RadioError::INVALID_SIM_STATE, RadioError::MODEM_ERR, RadioError::NO_MEMORY, RadioError::PASSWORD_INCORRECT, RadioError::SIM_ABSENT, RadioError::SYSTEM_ERR})); } - LOG(DEBUG) << "supplyNetworkDepersonalization finished"; } /* @@ -1879,7 +1867,6 @@ TEST_P(RadioNetworkTest, setEmergencyMode) { GTEST_SKIP(); } - LOG(DEBUG) << "setEmergencyMode"; serial = GetRandomSerialNumber(); radio_network->setEmergencyMode(serial, EmergencyMode::EMERGENCY_WWAN); @@ -1895,8 +1882,6 @@ TEST_P(RadioNetworkTest, setEmergencyMode) { // exit emergency mode for other tests serial = GetRandomSerialNumber(); radio_network->exitEmergencyMode(serial); - - LOG(DEBUG) << "setEmergencyMode finished"; } /* @@ -1912,7 +1897,6 @@ TEST_P(RadioNetworkTest, triggerEmergencyNetworkScan) { GTEST_SKIP(); } - LOG(DEBUG) << "triggerEmergencyNetworkScan"; serial = GetRandomSerialNumber(); EmergencyNetworkScanTrigger scanRequest; @@ -1928,7 +1912,6 @@ TEST_P(RadioNetworkTest, triggerEmergencyNetworkScan) { radioRsp_network->rspInfo.error, {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED, RadioError::RADIO_NOT_AVAILABLE, RadioError::MODEM_ERR, RadioError::INVALID_ARGUMENTS})); - LOG(DEBUG) << "triggerEmergencyNetworkScan finished"; } /* @@ -1943,7 +1926,6 @@ TEST_P(RadioNetworkTest, cancelEmergencyNetworkScan) { GTEST_SKIP(); } - LOG(DEBUG) << "cancelEmergencyNetworkScan"; serial = GetRandomSerialNumber(); radio_network->cancelEmergencyNetworkScan(serial, true); @@ -1951,11 +1933,9 @@ TEST_P(RadioNetworkTest, cancelEmergencyNetworkScan) { EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type); EXPECT_EQ(serial, radioRsp_network->rspInfo.serial); - ASSERT_TRUE(CheckAnyOfErrors( - radioRsp_network->rspInfo.error, - {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED, RadioError::RADIO_NOT_AVAILABLE, - RadioError::MODEM_ERR})); - LOG(DEBUG) << "cancelEmergencyNetworkScan finished"; + ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, + {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED, + RadioError::RADIO_NOT_AVAILABLE, RadioError::MODEM_ERR})); } /* @@ -1970,7 +1950,6 @@ TEST_P(RadioNetworkTest, exitEmergencyMode) { GTEST_SKIP(); } - LOG(DEBUG) << "exitEmergencyMode"; serial = GetRandomSerialNumber(); radio_network->exitEmergencyMode(serial); @@ -1978,11 +1957,9 @@ TEST_P(RadioNetworkTest, exitEmergencyMode) { EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type); EXPECT_EQ(serial, radioRsp_network->rspInfo.serial); - ASSERT_TRUE(CheckAnyOfErrors( - radioRsp_network->rspInfo.error, - {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED, RadioError::RADIO_NOT_AVAILABLE, - RadioError::MODEM_ERR})); - LOG(DEBUG) << "exitEmergencyMode finished"; + ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, + {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED, + RadioError::RADIO_NOT_AVAILABLE, RadioError::MODEM_ERR})); } /* @@ -2061,7 +2038,6 @@ TEST_P(RadioNetworkTest, setNullCipherAndIntegrityEnabled) { GTEST_SKIP(); } - LOG(DEBUG) << "setNullCipherAndIntegrityEnabled"; serial = GetRandomSerialNumber(); radio_network->setNullCipherAndIntegrityEnabled(serial, false); @@ -2072,7 +2048,6 @@ TEST_P(RadioNetworkTest, setNullCipherAndIntegrityEnabled) { ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED, RadioError::RADIO_NOT_AVAILABLE, RadioError::MODEM_ERR})); - LOG(DEBUG) << "setNullCipherAndIntegrityEnabled finished"; } /** @@ -2088,7 +2063,6 @@ TEST_P(RadioNetworkTest, isNullCipherAndIntegrityEnabled) { GTEST_SKIP(); } - LOG(DEBUG) << "isNullCipherAndIntegrityEnabled"; serial = GetRandomSerialNumber(); ndk::ScopedAStatus res = radio_network->isNullCipherAndIntegrityEnabled(serial); @@ -2101,5 +2075,4 @@ TEST_P(RadioNetworkTest, isNullCipherAndIntegrityEnabled) { ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::MODEM_ERR, RadioError::REQUEST_NOT_SUPPORTED})); - LOG(DEBUG) << "isNullCipherAndIntegrityEnabled finished"; } diff --git a/radio/aidl/vts/radio_network_utils.h b/radio/aidl/vts/radio_network_utils.h index 601f04435b..8f8f6b070f 100644 --- a/radio/aidl/vts/radio_network_utils.h +++ b/radio/aidl/vts/radio_network_utils.h @@ -229,9 +229,9 @@ class RadioNetworkIndication : public BnRadioNetworkIndication { }; // The main test class for Radio AIDL Network. -class RadioNetworkTest : public ::testing::TestWithParam<std::string>, public RadioServiceTest { +class RadioNetworkTest : public RadioServiceTest { public: - virtual void SetUp() override; + void SetUp() override; /* radio network service handle */ std::shared_ptr<IRadioNetwork> radio_network; diff --git a/radio/aidl/vts/radio_sap_test.cpp b/radio/aidl/vts/radio_sap_test.cpp index c94379c934..9a1c145576 100644 --- a/radio/aidl/vts/radio_sap_test.cpp +++ b/radio/aidl/vts/radio_sap_test.cpp @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include <android-base/logging.h> + #include <android/binder_manager.h> #include "radio_sap_utils.h" @@ -22,9 +22,13 @@ #define TIMEOUT_PERIOD 40 void SapTest::SetUp() { + ALOGD("BEGIN %s#%s", ::testing::UnitTest::GetInstance()->current_test_info()->test_suite_name(), + ::testing::UnitTest::GetInstance()->current_test_info()->name()); + count = 0; + serial = -1; std::string serviceName = GetParam(); if (!isServiceValidForDeviceConfiguration(serviceName)) { - LOG(DEBUG) << "Skipped the test due to device configuration."; + ALOGI("Skipped the test due to device configuration."); GTEST_SKIP(); } sap = ISap::fromBinder(ndk::SpAIBinder(AServiceManager_waitForService(serviceName.c_str()))); @@ -33,13 +37,16 @@ void SapTest::SetUp() { sapCb = ndk::SharedRefBase::make<SapCallback>(*this); ASSERT_NE(sapCb.get(), nullptr); - count = 0; - ndk::ScopedAStatus res = sap->setCallback(sapCb); ASSERT_OK(res) << res; } -void SapTest::TearDown() {} +void SapTest::TearDown() { + count_ = 0; + serial = -1; + ALOGD("END %s#%s", ::testing::UnitTest::GetInstance()->current_test_info()->test_suite_name(), + ::testing::UnitTest::GetInstance()->current_test_info()->name()); +} ::testing::AssertionResult SapTest::CheckAnyOfErrors(SapResultCode err, std::vector<SapResultCode> errors) { @@ -52,9 +59,9 @@ void SapTest::TearDown() {} } void SapTest::notify(int receivedSerial) { - std::unique_lock<std::mutex> lock(mtx); - count++; + std::lock_guard<std::mutex> lock(mtx); if (serial == receivedSerial) { + count++; cv.notify_one(); } } @@ -78,7 +85,6 @@ std::cv_status SapTest::wait() { * Test ISap.connectReq() for the response returned. */ TEST_P(SapTest, connectReq) { - LOG(DEBUG) << "connectReq"; serial = GetRandomSerialNumber(); int32_t maxMsgSize = 100; @@ -97,7 +103,6 @@ TEST_P(SapTest, connectReq) { * Test ISap.disconnectReq() for the response returned */ TEST_P(SapTest, disconnectReq) { - LOG(DEBUG) << "disconnectReq"; serial = GetRandomSerialNumber(); ndk::ScopedAStatus res = sap->disconnectReq(serial); @@ -105,14 +110,12 @@ TEST_P(SapTest, disconnectReq) { EXPECT_EQ(std::cv_status::no_timeout, wait()); EXPECT_EQ(sapCb->sapResponseSerial, serial); - LOG(DEBUG) << "disconnectReq finished"; } /* * Test ISap.apduReq() for the response returned. */ TEST_P(SapTest, apduReq) { - LOG(DEBUG) << "apduReq"; serial = GetRandomSerialNumber(); SapApduType sapApduType = SapApduType::APDU; std::vector<uint8_t> command = {}; @@ -128,14 +131,12 @@ TEST_P(SapTest, apduReq) { {SapResultCode::GENERIC_FAILURE, SapResultCode::CARD_ALREADY_POWERED_OFF, SapResultCode::CARD_NOT_ACCESSSIBLE, SapResultCode::CARD_REMOVED, SapResultCode::SUCCESS})); - LOG(DEBUG) << "apduReq finished"; } /* * Test ISap.transferAtrReq() for the response returned. */ TEST_P(SapTest, transferAtrReq) { - LOG(DEBUG) << "transferAtrReq"; serial = GetRandomSerialNumber(); ndk::ScopedAStatus res = sap->transferAtrReq(serial); @@ -148,14 +149,12 @@ TEST_P(SapTest, transferAtrReq) { {SapResultCode::GENERIC_FAILURE, SapResultCode::DATA_NOT_AVAILABLE, SapResultCode::CARD_ALREADY_POWERED_OFF, SapResultCode::CARD_REMOVED, SapResultCode::SUCCESS})); - LOG(DEBUG) << "transferAtrReq finished"; } /* * Test ISap.powerReq() for the response returned. */ TEST_P(SapTest, powerReq) { - LOG(DEBUG) << "powerReq"; serial = GetRandomSerialNumber(); bool state = true; @@ -170,14 +169,12 @@ TEST_P(SapTest, powerReq) { {SapResultCode::GENERIC_FAILURE, SapResultCode::CARD_NOT_ACCESSSIBLE, SapResultCode::CARD_ALREADY_POWERED_OFF, SapResultCode::CARD_REMOVED, SapResultCode::CARD_ALREADY_POWERED_ON, SapResultCode::SUCCESS})); - LOG(DEBUG) << "powerReq finished"; } /* * Test ISap.resetSimReq() for the response returned. */ TEST_P(SapTest, resetSimReq) { - LOG(DEBUG) << "resetSimReq"; serial = GetRandomSerialNumber(); ndk::ScopedAStatus res = sap->resetSimReq(serial); @@ -191,14 +188,12 @@ TEST_P(SapTest, resetSimReq) { {SapResultCode::GENERIC_FAILURE, SapResultCode::CARD_NOT_ACCESSSIBLE, SapResultCode::CARD_ALREADY_POWERED_OFF, SapResultCode::CARD_REMOVED, SapResultCode::SUCCESS})); - LOG(DEBUG) << "resetSimReq finished"; } /* * Test ISap.transferCardReaderStatusReq() for the response returned. */ TEST_P(SapTest, transferCardReaderStatusReq) { - LOG(DEBUG) << "transferCardReaderStatusReq"; serial = GetRandomSerialNumber(); ndk::ScopedAStatus res = sap->transferCardReaderStatusReq(serial); @@ -210,14 +205,12 @@ TEST_P(SapTest, transferCardReaderStatusReq) { ASSERT_TRUE(CheckAnyOfErrors(sapCb->sapResultCode, {SapResultCode::GENERIC_FAILURE, SapResultCode::DATA_NOT_AVAILABLE, SapResultCode::SUCCESS})); - LOG(DEBUG) << "transferCardReaderStatusReq finished"; } /* * Test ISap.setTransferProtocolReq() for the response returned. */ TEST_P(SapTest, setTransferProtocolReq) { - LOG(DEBUG) << "setTransferProtocolReq"; serial = GetRandomSerialNumber(); SapTransferProtocol sapTransferProtocol = SapTransferProtocol::T0; @@ -229,5 +222,4 @@ TEST_P(SapTest, setTransferProtocolReq) { ASSERT_TRUE(CheckAnyOfErrors(sapCb->sapResultCode, {SapResultCode::NOT_SUPPORTED, SapResultCode::SUCCESS})); - LOG(DEBUG) << "setTransferProtocolReq finished"; } diff --git a/radio/aidl/vts/radio_sim_test.cpp b/radio/aidl/vts/radio_sim_test.cpp index f65714229c..d90658893b 100644 --- a/radio/aidl/vts/radio_sim_test.cpp +++ b/radio/aidl/vts/radio_sim_test.cpp @@ -16,7 +16,6 @@ #include <aidl/android/hardware/radio/RadioConst.h> #include <aidl/android/hardware/radio/config/IRadioConfig.h> -#include <android-base/logging.h> #include <android/binder_manager.h> #include "radio_sim_utils.h" @@ -24,6 +23,7 @@ #define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk()) void RadioSimTest::SetUp() { + RadioServiceTest::SetUp(); std::string serviceName = GetParam(); if (!isServiceValidForDeviceConfiguration(serviceName)) { @@ -38,8 +38,6 @@ void RadioSimTest::SetUp() { radioRsp_sim = ndk::SharedRefBase::make<RadioSimResponse>(*this); ASSERT_NE(nullptr, radioRsp_sim.get()); - count_ = 0; - radioInd_sim = ndk::SharedRefBase::make<RadioSimIndication>(*this); ASSERT_NE(nullptr, radioInd_sim.get()); @@ -481,19 +479,16 @@ TEST_P(RadioSimTest, setAllowedCarriers) { * Test IRadioSim.getIccCardStatus() for the response returned. */ TEST_P(RadioSimTest, getIccCardStatus) { - LOG(DEBUG) << "getIccCardStatus"; EXPECT_LE(cardStatus.applications.size(), RadioConst::CARD_MAX_APPS); EXPECT_LT(cardStatus.gsmUmtsSubscriptionAppIndex, RadioConst::CARD_MAX_APPS); EXPECT_LT(cardStatus.cdmaSubscriptionAppIndex, RadioConst::CARD_MAX_APPS); EXPECT_LT(cardStatus.imsSubscriptionAppIndex, RadioConst::CARD_MAX_APPS); - LOG(DEBUG) << "getIccCardStatus finished"; } /* * Test IRadioSim.supplyIccPinForApp() for the response returned */ TEST_P(RadioSimTest, supplyIccPinForApp) { - LOG(DEBUG) << "supplyIccPinForApp"; serial = GetRandomSerialNumber(); // Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and @@ -513,14 +508,12 @@ TEST_P(RadioSimTest, supplyIccPinForApp) { {RadioError::PASSWORD_INCORRECT, RadioError::REQUEST_NOT_SUPPORTED})); } } - LOG(DEBUG) << "supplyIccPinForApp finished"; } /* * Test IRadioSim.supplyIccPukForApp() for the response returned. */ TEST_P(RadioSimTest, supplyIccPukForApp) { - LOG(DEBUG) << "supplyIccPukForApp"; serial = GetRandomSerialNumber(); // Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and @@ -540,14 +533,12 @@ TEST_P(RadioSimTest, supplyIccPukForApp) { {RadioError::PASSWORD_INCORRECT, RadioError::INVALID_SIM_STATE})); } } - LOG(DEBUG) << "supplyIccPukForApp finished"; } /* * Test IRadioSim.supplyIccPin2ForApp() for the response returned. */ TEST_P(RadioSimTest, supplyIccPin2ForApp) { - LOG(DEBUG) << "supplyIccPin2ForApp"; serial = GetRandomSerialNumber(); // Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and @@ -568,14 +559,12 @@ TEST_P(RadioSimTest, supplyIccPin2ForApp) { RadioError::REQUEST_NOT_SUPPORTED, RadioError::SIM_PUK2})); } } - LOG(DEBUG) << "supplyIccPin2ForApp finished"; } /* * Test IRadioSim.supplyIccPuk2ForApp() for the response returned. */ TEST_P(RadioSimTest, supplyIccPuk2ForApp) { - LOG(DEBUG) << "supplyIccPuk2ForApp"; serial = GetRandomSerialNumber(); // Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and @@ -595,14 +584,12 @@ TEST_P(RadioSimTest, supplyIccPuk2ForApp) { {RadioError::PASSWORD_INCORRECT, RadioError::INVALID_SIM_STATE})); } } - LOG(DEBUG) << "supplyIccPuk2ForApp finished"; } /* * Test IRadioSim.changeIccPinForApp() for the response returned. */ TEST_P(RadioSimTest, changeIccPinForApp) { - LOG(DEBUG) << "changeIccPinForApp"; serial = GetRandomSerialNumber(); // Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and @@ -622,14 +609,12 @@ TEST_P(RadioSimTest, changeIccPinForApp) { {RadioError::PASSWORD_INCORRECT, RadioError::REQUEST_NOT_SUPPORTED})); } } - LOG(DEBUG) << "changeIccPinForApp finished"; } /* * Test IRadioSim.changeIccPin2ForApp() for the response returned. */ TEST_P(RadioSimTest, changeIccPin2ForApp) { - LOG(DEBUG) << "changeIccPin2ForApp"; serial = GetRandomSerialNumber(); // Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and @@ -650,14 +635,12 @@ TEST_P(RadioSimTest, changeIccPin2ForApp) { RadioError::REQUEST_NOT_SUPPORTED, RadioError::SIM_PUK2})); } } - LOG(DEBUG) << "changeIccPin2ForApp finished"; } /* * Test IRadioSim.getImsiForApp() for the response returned. */ TEST_P(RadioSimTest, getImsiForApp) { - LOG(DEBUG) << "getImsiForApp"; serial = GetRandomSerialNumber(); // Check success returned while getting imsi for 3GPP and 3GPP2 apps only @@ -681,14 +664,12 @@ TEST_P(RadioSimTest, getImsiForApp) { } } } - LOG(DEBUG) << "getImsiForApp finished"; } /* * Test IRadioSim.iccIoForApp() for the response returned. */ TEST_P(RadioSimTest, iccIoForApp) { - LOG(DEBUG) << "iccIoForApp"; serial = GetRandomSerialNumber(); for (int i = 0; i < (int)cardStatus.applications.size(); i++) { @@ -708,14 +689,12 @@ TEST_P(RadioSimTest, iccIoForApp) { EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type); EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial); } - LOG(DEBUG) << "iccIoForApp finished"; } /* * Test IRadioSim.iccTransmitApduBasicChannel() for the response returned. */ TEST_P(RadioSimTest, iccTransmitApduBasicChannel) { - LOG(DEBUG) << "iccTransmitApduBasicChannel"; serial = GetRandomSerialNumber(); SimApdu msg; memset(&msg, 0, sizeof(msg)); @@ -725,14 +704,12 @@ TEST_P(RadioSimTest, iccTransmitApduBasicChannel) { EXPECT_EQ(std::cv_status::no_timeout, wait()); EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type); EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial); - LOG(DEBUG) << "iccTransmitApduBasicChannel finished"; } /* * Test IRadioSim.iccOpenLogicalChannel() for the response returned. */ TEST_P(RadioSimTest, iccOpenLogicalChannel) { - LOG(DEBUG) << "iccOpenLogicalChannel"; serial = GetRandomSerialNumber(); int p2 = 0x04; // Specified in ISO 7816-4 clause 7.1.1 0x04 means that FCP template is requested. @@ -742,14 +719,12 @@ TEST_P(RadioSimTest, iccOpenLogicalChannel) { EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial); EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type); } - LOG(DEBUG) << "iccOpenLogicalChannel finished"; } /* * Test IRadioSim.iccCloseLogicalChannel() for the response returned. */ TEST_P(RadioSimTest, iccCloseLogicalChannel) { - LOG(DEBUG) << "iccCloseLogicalChannel"; serial = GetRandomSerialNumber(); // Try closing invalid channel and check INVALID_ARGUMENTS returned as error radio_sim->iccCloseLogicalChannel(serial, 0); @@ -758,7 +733,6 @@ TEST_P(RadioSimTest, iccCloseLogicalChannel) { EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial); EXPECT_EQ(RadioError::INVALID_ARGUMENTS, radioRsp_sim->rspInfo.error); - LOG(DEBUG) << "iccCloseLogicalChannel finished"; } /* @@ -773,7 +747,6 @@ TEST_P(RadioSimTest, iccCloseLogicalChannelWithSessionInfo) { " iccCloseLogicalChannelWithSessionInfo is not supported on version < 2"); GTEST_SKIP(); } - LOG(DEBUG) << "iccCloseLogicalChannelWithSessionInfo"; serial = GetRandomSerialNumber(); SessionInfo info; memset(&info, 0, sizeof(info)); @@ -787,14 +760,12 @@ TEST_P(RadioSimTest, iccCloseLogicalChannelWithSessionInfo) { EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial); EXPECT_EQ(RadioError::INVALID_ARGUMENTS, radioRsp_sim->rspInfo.error); - LOG(DEBUG) << "iccCloseLogicalChannelWithSessionInfo finished"; } /* * Test IRadioSim.iccTransmitApduLogicalChannel() for the response returned. */ TEST_P(RadioSimTest, iccTransmitApduLogicalChannel) { - LOG(DEBUG) << "iccTransmitApduLogicalChannel"; serial = GetRandomSerialNumber(); SimApdu msg; memset(&msg, 0, sizeof(msg)); @@ -804,14 +775,12 @@ TEST_P(RadioSimTest, iccTransmitApduLogicalChannel) { EXPECT_EQ(std::cv_status::no_timeout, wait()); EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type); EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial); - LOG(DEBUG) << "iccTransmitApduLogicalChannel finished"; } /* * Test IRadioSim.requestIccSimAuthentication() for the response returned. */ TEST_P(RadioSimTest, requestIccSimAuthentication) { - LOG(DEBUG) << "requestIccSimAuthentication"; serial = GetRandomSerialNumber(); // Pass wrong challenge string and check RadioError::INVALID_ARGUMENTS @@ -826,7 +795,6 @@ TEST_P(RadioSimTest, requestIccSimAuthentication) { radioRsp_sim->rspInfo.error, {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED})); } - LOG(DEBUG) << "requestIccSimAuthentication finished"; } /* @@ -880,7 +848,6 @@ TEST_P(RadioSimTest, setFacilityLockForApp) { * Test IRadioSim.getCdmaSubscription() for the response returned. */ TEST_P(RadioSimTest, getCdmaSubscription) { - LOG(DEBUG) << "getCdmaSubscription"; serial = GetRandomSerialNumber(); radio_sim->getCdmaSubscription(serial); @@ -893,14 +860,12 @@ TEST_P(RadioSimTest, getCdmaSubscription) { radioRsp_sim->rspInfo.error, {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED, RadioError::SIM_ABSENT})); } - LOG(DEBUG) << "getCdmaSubscription finished"; } /* * Test IRadioSim.getCdmaSubscriptionSource() for the response returned. */ TEST_P(RadioSimTest, getCdmaSubscriptionSource) { - LOG(DEBUG) << "getCdmaSubscriptionSource"; serial = GetRandomSerialNumber(); radio_sim->getCdmaSubscriptionSource(serial); @@ -913,14 +878,12 @@ TEST_P(RadioSimTest, getCdmaSubscriptionSource) { radioRsp_sim->rspInfo.error, {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED, RadioError::SIM_ABSENT})); } - LOG(DEBUG) << "getCdmaSubscriptionSource finished"; } /* * Test IRadioSim.setCdmaSubscriptionSource() for the response returned. */ TEST_P(RadioSimTest, setCdmaSubscriptionSource) { - LOG(DEBUG) << "setCdmaSubscriptionSource"; serial = GetRandomSerialNumber(); radio_sim->setCdmaSubscriptionSource(serial, CdmaSubscriptionSource::RUIM_SIM); @@ -934,14 +897,12 @@ TEST_P(RadioSimTest, setCdmaSubscriptionSource) { {RadioError::NONE, RadioError::SIM_ABSENT, RadioError::SUBSCRIPTION_NOT_AVAILABLE}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "setCdmaSubscriptionSource finished"; } /* * Test IRadioSim.setUiccSubscription() for the response returned. */ TEST_P(RadioSimTest, setUiccSubscription) { - LOG(DEBUG) << "setUiccSubscription"; serial = GetRandomSerialNumber(); SelectUiccSub item; memset(&item, 0, sizeof(item)); @@ -958,14 +919,12 @@ TEST_P(RadioSimTest, setUiccSubscription) { RadioError::MODEM_ERR, RadioError::SUBSCRIPTION_NOT_SUPPORTED}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "setUiccSubscription finished"; } /* * Test IRadioSim.sendEnvelope() for the response returned. */ TEST_P(RadioSimTest, sendEnvelope) { - LOG(DEBUG) << "sendEnvelope"; serial = GetRandomSerialNumber(); // Test with sending empty string @@ -983,14 +942,12 @@ TEST_P(RadioSimTest, sendEnvelope) { RadioError::MODEM_ERR, RadioError::SIM_ABSENT}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "sendEnvelope finished"; } /* * Test IRadioSim.sendTerminalResponseToSim() for the response returned. */ TEST_P(RadioSimTest, sendTerminalResponseToSim) { - LOG(DEBUG) << "sendTerminalResponseToSim"; serial = GetRandomSerialNumber(); // Test with sending empty string @@ -1008,14 +965,12 @@ TEST_P(RadioSimTest, sendTerminalResponseToSim) { {RadioError::NONE, RadioError::INVALID_ARGUMENTS, RadioError::SIM_ABSENT}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "sendTerminalResponseToSim finished"; } /* * Test IRadioSim.reportStkServiceIsRunning() for the response returned. */ TEST_P(RadioSimTest, reportStkServiceIsRunning) { - LOG(DEBUG) << "reportStkServiceIsRunning"; serial = GetRandomSerialNumber(); radio_sim->reportStkServiceIsRunning(serial); @@ -1028,7 +983,6 @@ TEST_P(RadioSimTest, reportStkServiceIsRunning) { ASSERT_TRUE(CheckAnyOfErrors(radioRsp_sim->rspInfo.error, {RadioError::NONE}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "reportStkServiceIsRunning finished"; } /* @@ -1036,7 +990,6 @@ TEST_P(RadioSimTest, reportStkServiceIsRunning) { * string. */ TEST_P(RadioSimTest, sendEnvelopeWithStatus) { - LOG(DEBUG) << "sendEnvelopeWithStatus"; serial = GetRandomSerialNumber(); // Test with sending empty string @@ -1054,5 +1007,4 @@ TEST_P(RadioSimTest, sendEnvelopeWithStatus) { {RadioError::INVALID_ARGUMENTS, RadioError::MODEM_ERR, RadioError::SIM_ABSENT}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "sendEnvelopeWithStatus finished"; } diff --git a/radio/aidl/vts/radio_sim_utils.h b/radio/aidl/vts/radio_sim_utils.h index 71c7eb82c1..7cbcc58fd1 100644 --- a/radio/aidl/vts/radio_sim_utils.h +++ b/radio/aidl/vts/radio_sim_utils.h @@ -194,9 +194,9 @@ class RadioSimIndication : public BnRadioSimIndication { }; // The main test class for Radio AIDL SIM. -class RadioSimTest : public ::testing::TestWithParam<std::string>, public RadioServiceTest { +class RadioSimTest : public RadioServiceTest { public: - virtual void SetUp() override; + void SetUp() override; /* Override updateSimCardStatus in RadioServiceTest to not call setResponseFunctions */ void updateSimCardStatus(); diff --git a/radio/aidl/vts/radio_voice_test.cpp b/radio/aidl/vts/radio_voice_test.cpp index 249ee63dee..397c417efa 100644 --- a/radio/aidl/vts/radio_voice_test.cpp +++ b/radio/aidl/vts/radio_voice_test.cpp @@ -16,7 +16,6 @@ #include <aidl/android/hardware/radio/config/IRadioConfig.h> #include <aidl/android/hardware/radio/voice/EmergencyServiceCategory.h> -#include <android-base/logging.h> #include <android/binder_manager.h> #include "radio_voice_utils.h" @@ -24,6 +23,7 @@ #define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk()) void RadioVoiceTest::SetUp() { + RadioServiceTest::SetUp(); std::string serviceName = GetParam(); if (!isServiceValidForDeviceConfiguration(serviceName)) { @@ -38,8 +38,6 @@ void RadioVoiceTest::SetUp() { radioRsp_voice = ndk::SharedRefBase::make<RadioVoiceResponse>(*this); ASSERT_NE(nullptr, radioRsp_voice.get()); - count_ = 0; - radioInd_voice = ndk::SharedRefBase::make<RadioVoiceIndication>(*this); ASSERT_NE(nullptr, radioInd_voice.get()); @@ -324,7 +322,6 @@ TEST_P(RadioVoiceTest, getClip) { * Test IRadioVoice.getTtyMode() for the response returned. */ TEST_P(RadioVoiceTest, getTtyMode) { - LOG(DEBUG) << "getTtyMode"; serial = GetRandomSerialNumber(); radio_voice->getTtyMode(serial); @@ -335,14 +332,12 @@ TEST_P(RadioVoiceTest, getTtyMode) { if (cardStatus.cardState == CardStatus::STATE_ABSENT) { EXPECT_EQ(RadioError::NONE, radioRsp_voice->rspInfo.error); } - LOG(DEBUG) << "getTtyMode finished"; } /* * Test IRadioVoice.setTtyMode() for the response returned. */ TEST_P(RadioVoiceTest, setTtyMode) { - LOG(DEBUG) << "setTtyMode"; serial = GetRandomSerialNumber(); radio_voice->setTtyMode(serial, TtyMode::OFF); @@ -353,14 +348,12 @@ TEST_P(RadioVoiceTest, setTtyMode) { if (cardStatus.cardState == CardStatus::STATE_ABSENT) { EXPECT_EQ(RadioError::NONE, radioRsp_voice->rspInfo.error); } - LOG(DEBUG) << "setTtyMode finished"; } /* * Test IRadioVoice.setPreferredVoicePrivacy() for the response returned. */ TEST_P(RadioVoiceTest, setPreferredVoicePrivacy) { - LOG(DEBUG) << "setPreferredVoicePrivacy"; serial = GetRandomSerialNumber(); radio_voice->setPreferredVoicePrivacy(serial, true); @@ -372,14 +365,12 @@ TEST_P(RadioVoiceTest, setPreferredVoicePrivacy) { ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error, {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED})); } - LOG(DEBUG) << "setPreferredVoicePrivacy finished"; } /* * Test IRadioVoice.getPreferredVoicePrivacy() for the response returned. */ TEST_P(RadioVoiceTest, getPreferredVoicePrivacy) { - LOG(DEBUG) << "getPreferredVoicePrivacy"; serial = GetRandomSerialNumber(); radio_voice->getPreferredVoicePrivacy(serial); @@ -391,14 +382,12 @@ TEST_P(RadioVoiceTest, getPreferredVoicePrivacy) { ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error, {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED})); } - LOG(DEBUG) << "getPreferredVoicePrivacy finished"; } /* * Test IRadioVoice.exitEmergencyCallbackMode() for the response returned. */ TEST_P(RadioVoiceTest, exitEmergencyCallbackMode) { - LOG(DEBUG) << "exitEmergencyCallbackMode"; serial = GetRandomSerialNumber(); radio_voice->exitEmergencyCallbackMode(serial); @@ -411,14 +400,12 @@ TEST_P(RadioVoiceTest, exitEmergencyCallbackMode) { radioRsp_voice->rspInfo.error, {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED, RadioError::SIM_ABSENT})); } - LOG(DEBUG) << "exitEmergencyCallbackMode finished"; } /* * Test IRadioVoice.handleStkCallSetupRequestFromSim() for the response returned. */ TEST_P(RadioVoiceTest, handleStkCallSetupRequestFromSim) { - LOG(DEBUG) << "handleStkCallSetupRequestFromSim"; serial = GetRandomSerialNumber(); bool accept = false; @@ -434,14 +421,12 @@ TEST_P(RadioVoiceTest, handleStkCallSetupRequestFromSim) { RadioError::MODEM_ERR, RadioError::SIM_ABSENT}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "handleStkCallSetupRequestFromSim finished"; } /* * Test IRadioVoice.dial() for the response returned. */ TEST_P(RadioVoiceTest, dial) { - LOG(DEBUG) << "dial"; serial = GetRandomSerialNumber(); Dial dialInfo; @@ -463,14 +448,12 @@ TEST_P(RadioVoiceTest, dial) { RadioError::OPERATION_NOT_ALLOWED}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "dial finished"; } /* * Test IRadioVoice.hangup() for the response returned. */ TEST_P(RadioVoiceTest, hangup) { - LOG(DEBUG) << "hangup"; serial = GetRandomSerialNumber(); radio_voice->hangup(serial, 1); @@ -484,14 +467,12 @@ TEST_P(RadioVoiceTest, hangup) { {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::MODEM_ERR}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "hangup finished"; } /* * Test IRadioVoice.hangupWaitingOrBackground() for the response returned. */ TEST_P(RadioVoiceTest, hangupWaitingOrBackground) { - LOG(DEBUG) << "hangupWaitingOrBackground"; serial = GetRandomSerialNumber(); radio_voice->hangupWaitingOrBackground(serial); @@ -504,14 +485,12 @@ TEST_P(RadioVoiceTest, hangupWaitingOrBackground) { {RadioError::INVALID_STATE, RadioError::MODEM_ERR}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "hangupWaitingOrBackground finished"; } /* * Test IRadioVoice.hangupForegroundResumeBackground() for the response returned. */ TEST_P(RadioVoiceTest, hangupForegroundResumeBackground) { - LOG(DEBUG) << "hangupForegroundResumeBackground"; serial = GetRandomSerialNumber(); radio_voice->hangupForegroundResumeBackground(serial); @@ -524,14 +503,12 @@ TEST_P(RadioVoiceTest, hangupForegroundResumeBackground) { {RadioError::INVALID_STATE, RadioError::MODEM_ERR}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "hangupForegroundResumeBackground finished"; } /* * Test IRadioVoice.switchWaitingOrHoldingAndActive() for the response returned. */ TEST_P(RadioVoiceTest, switchWaitingOrHoldingAndActive) { - LOG(DEBUG) << "switchWaitingOrHoldingAndActive"; serial = GetRandomSerialNumber(); radio_voice->switchWaitingOrHoldingAndActive(serial); @@ -544,14 +521,12 @@ TEST_P(RadioVoiceTest, switchWaitingOrHoldingAndActive) { {RadioError::INVALID_STATE, RadioError::MODEM_ERR}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "switchWaitingOrHoldingAndActive finished"; } /* * Test IRadioVoice.conference() for the response returned. */ TEST_P(RadioVoiceTest, conference) { - LOG(DEBUG) << "conference"; serial = GetRandomSerialNumber(); radio_voice->conference(serial); @@ -564,14 +539,12 @@ TEST_P(RadioVoiceTest, conference) { {RadioError::INVALID_STATE, RadioError::MODEM_ERR}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "conference finished"; } /* * Test IRadioVoice.rejectCall() for the response returned. */ TEST_P(RadioVoiceTest, rejectCall) { - LOG(DEBUG) << "rejectCall"; serial = GetRandomSerialNumber(); radio_voice->rejectCall(serial); @@ -584,14 +557,12 @@ TEST_P(RadioVoiceTest, rejectCall) { {RadioError::INVALID_STATE, RadioError::MODEM_ERR}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "rejectCall finished"; } /* * Test IRadioVoice.getLastCallFailCause() for the response returned. */ TEST_P(RadioVoiceTest, getLastCallFailCause) { - LOG(DEBUG) << "getLastCallFailCause"; serial = GetRandomSerialNumber(); radio_voice->getLastCallFailCause(serial); @@ -603,14 +574,12 @@ TEST_P(RadioVoiceTest, getLastCallFailCause) { ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error, {RadioError::NONE}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "getLastCallFailCause finished"; } /* * Test IRadioVoice.getCallForwardStatus() for the response returned. */ TEST_P(RadioVoiceTest, getCallForwardStatus) { - LOG(DEBUG) << "getCallForwardStatus"; serial = GetRandomSerialNumber(); CallForwardInfo callInfo; memset(&callInfo, 0, sizeof(callInfo)); @@ -627,14 +596,12 @@ TEST_P(RadioVoiceTest, getCallForwardStatus) { {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::MODEM_ERR}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "getCallForwardStatus finished"; } /* * Test IRadioVoice.setCallForward() for the response returned. */ TEST_P(RadioVoiceTest, setCallForward) { - LOG(DEBUG) << "setCallForward"; serial = GetRandomSerialNumber(); CallForwardInfo callInfo; memset(&callInfo, 0, sizeof(callInfo)); @@ -651,14 +618,12 @@ TEST_P(RadioVoiceTest, setCallForward) { {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::MODEM_ERR}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "setCallForward finished"; } /* * Test IRadioVoice.getCallWaiting() for the response returned. */ TEST_P(RadioVoiceTest, getCallWaiting) { - LOG(DEBUG) << "getCallWaiting"; serial = GetRandomSerialNumber(); radio_voice->getCallWaiting(serial, 1); @@ -672,14 +637,12 @@ TEST_P(RadioVoiceTest, getCallWaiting) { {RadioError::NONE, RadioError::INVALID_ARGUMENTS, RadioError::MODEM_ERR}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "getCallWaiting finished"; } /* * Test IRadioVoice.setCallWaiting() for the response returned. */ TEST_P(RadioVoiceTest, setCallWaiting) { - LOG(DEBUG) << "setCallWaiting"; serial = GetRandomSerialNumber(); radio_voice->setCallWaiting(serial, true, 1); @@ -693,14 +656,12 @@ TEST_P(RadioVoiceTest, setCallWaiting) { {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::MODEM_ERR}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "setCallWaiting finished"; } /* * Test IRadioVoice.acceptCall() for the response returned. */ TEST_P(RadioVoiceTest, acceptCall) { - LOG(DEBUG) << "acceptCall"; serial = GetRandomSerialNumber(); radio_voice->acceptCall(serial); @@ -713,14 +674,12 @@ TEST_P(RadioVoiceTest, acceptCall) { {RadioError::INVALID_STATE, RadioError::MODEM_ERR}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "acceptCall finished"; } /* * Test IRadioVoice.separateConnection() for the response returned. */ TEST_P(RadioVoiceTest, separateConnection) { - LOG(DEBUG) << "separateConnection"; serial = GetRandomSerialNumber(); radio_voice->separateConnection(serial, 1); @@ -734,14 +693,12 @@ TEST_P(RadioVoiceTest, separateConnection) { {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::MODEM_ERR}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "separateConnection finished"; } /* * Test IRadioVoice.explicitCallTransfer() for the response returned. */ TEST_P(RadioVoiceTest, explicitCallTransfer) { - LOG(DEBUG) << "explicitCallTransfer"; serial = GetRandomSerialNumber(); radio_voice->explicitCallTransfer(serial); @@ -754,14 +711,12 @@ TEST_P(RadioVoiceTest, explicitCallTransfer) { {RadioError::INVALID_STATE, RadioError::MODEM_ERR}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "explicitCallTransfer finished"; } /* * Test IRadioVoice.sendCdmaFeatureCode() for the response returned. */ TEST_P(RadioVoiceTest, sendCdmaFeatureCode) { - LOG(DEBUG) << "sendCdmaFeatureCode"; serial = GetRandomSerialNumber(); radio_voice->sendCdmaFeatureCode(serial, std::string()); @@ -776,14 +731,12 @@ TEST_P(RadioVoiceTest, sendCdmaFeatureCode) { RadioError::MODEM_ERR, RadioError::OPERATION_NOT_ALLOWED}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "sendCdmaFeatureCode finished"; } /* * Test IRadioVoice.sendDtmf() for the response returned. */ TEST_P(RadioVoiceTest, sendDtmf) { - LOG(DEBUG) << "sendDtmf"; serial = GetRandomSerialNumber(); radio_voice->sendDtmf(serial, "1"); @@ -798,14 +751,12 @@ TEST_P(RadioVoiceTest, sendDtmf) { RadioError::INVALID_MODEM_STATE, RadioError::MODEM_ERR}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "sendDtmf finished"; } /* * Test IRadioVoice.startDtmf() for the response returned. */ TEST_P(RadioVoiceTest, startDtmf) { - LOG(DEBUG) << "startDtmf"; serial = GetRandomSerialNumber(); radio_voice->startDtmf(serial, "1"); @@ -820,14 +771,12 @@ TEST_P(RadioVoiceTest, startDtmf) { RadioError::INVALID_MODEM_STATE, RadioError::MODEM_ERR}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "startDtmf finished"; } /* * Test IRadioVoice.stopDtmf() for the response returned. */ TEST_P(RadioVoiceTest, stopDtmf) { - LOG(DEBUG) << "stopDtmf"; serial = GetRandomSerialNumber(); radio_voice->stopDtmf(serial); @@ -841,14 +790,12 @@ TEST_P(RadioVoiceTest, stopDtmf) { RadioError::INVALID_MODEM_STATE, RadioError::MODEM_ERR}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "stopDtmf finished"; } /* * Test IRadioVoice.setMute() for the response returned. */ TEST_P(RadioVoiceTest, setMute) { - LOG(DEBUG) << "setMute"; serial = GetRandomSerialNumber(); radio_voice->setMute(serial, true); @@ -861,14 +808,12 @@ TEST_P(RadioVoiceTest, setMute) { {RadioError::NONE, RadioError::INVALID_ARGUMENTS}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "setMute finished"; } /* * Test IRadioVoice.getMute() for the response returned. */ TEST_P(RadioVoiceTest, getMute) { - LOG(DEBUG) << "getMute"; serial = GetRandomSerialNumber(); radio_voice->getMute(serial); @@ -879,14 +824,12 @@ TEST_P(RadioVoiceTest, getMute) { if (cardStatus.cardState == CardStatus::STATE_ABSENT) { EXPECT_EQ(RadioError::NONE, radioRsp_voice->rspInfo.error); } - LOG(DEBUG) << "getMute finished"; } /* * Test IRadioVoice.sendBurstDtmf() for the response returned. */ TEST_P(RadioVoiceTest, sendBurstDtmf) { - LOG(DEBUG) << "sendBurstDtmf"; serial = GetRandomSerialNumber(); radio_voice->sendBurstDtmf(serial, "1", 0, 0); @@ -900,14 +843,12 @@ TEST_P(RadioVoiceTest, sendBurstDtmf) { RadioError::MODEM_ERR, RadioError::OPERATION_NOT_ALLOWED}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "sendBurstDtmf finished"; } /* * Test IRadioVoice.sendUssd() for the response returned. */ TEST_P(RadioVoiceTest, sendUssd) { - LOG(DEBUG) << "sendUssd"; serial = GetRandomSerialNumber(); radio_voice->sendUssd(serial, std::string("test")); EXPECT_EQ(std::cv_status::no_timeout, wait()); @@ -920,14 +861,12 @@ TEST_P(RadioVoiceTest, sendUssd) { {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::MODEM_ERR}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "sendUssd finished"; } /* * Test IRadioVoice.cancelPendingUssd() for the response returned. */ TEST_P(RadioVoiceTest, cancelPendingUssd) { - LOG(DEBUG) << "cancelPendingUssd"; serial = GetRandomSerialNumber(); radio_voice->cancelPendingUssd(serial); @@ -941,14 +880,12 @@ TEST_P(RadioVoiceTest, cancelPendingUssd) { {RadioError::NONE, RadioError::INVALID_STATE, RadioError::MODEM_ERR}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "cancelPendingUssd finished"; } /* * Test IRadioVoice.isVoNrEnabled() for the response returned. */ TEST_P(RadioVoiceTest, isVoNrEnabled) { - LOG(DEBUG) << "isVoNrEnabled"; serial = GetRandomSerialNumber(); radio_voice->isVoNrEnabled(serial); @@ -958,14 +895,12 @@ TEST_P(RadioVoiceTest, isVoNrEnabled) { ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error, {RadioError::REQUEST_NOT_SUPPORTED, RadioError::NONE})); - LOG(DEBUG) << "isVoNrEnabled finished"; } /* * Test IRadioVoice.setVoNrEnabled() for the response returned. */ TEST_P(RadioVoiceTest, setVoNrEnabled) { - LOG(DEBUG) << "setVoNrEnabled"; serial = GetRandomSerialNumber(); radio_voice->setVoNrEnabled(serial, true); @@ -975,5 +910,4 @@ TEST_P(RadioVoiceTest, setVoNrEnabled) { ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error, {RadioError::REQUEST_NOT_SUPPORTED, RadioError::NONE})); - LOG(DEBUG) << "setVoNrEnabled finished"; } diff --git a/radio/aidl/vts/radio_voice_utils.h b/radio/aidl/vts/radio_voice_utils.h index 0c3df7fbbf..dda6c6572a 100644 --- a/radio/aidl/vts/radio_voice_utils.h +++ b/radio/aidl/vts/radio_voice_utils.h @@ -183,7 +183,7 @@ class RadioVoiceIndication : public BnRadioVoiceIndication { }; // The main test class for Radio AIDL Voice. -class RadioVoiceTest : public ::testing::TestWithParam<std::string>, public RadioServiceTest { +class RadioVoiceTest : public RadioServiceTest { protected: /* Clear Potential Established Calls */ virtual ndk::ScopedAStatus clearPotentialEstablishedCalls(); @@ -192,7 +192,7 @@ class RadioVoiceTest : public ::testing::TestWithParam<std::string>, public Radi std::shared_ptr<RadioNetworkIndication> radioInd_network; public: - virtual void SetUp() override; + void SetUp() override; /* radio voice service handle */ std::shared_ptr<IRadioVoice> radio_voice; diff --git a/security/keymint/aidl/vts/functional/Android.bp b/security/keymint/aidl/vts/functional/Android.bp index 7a4359d31a..41b161d11d 100644 --- a/security/keymint/aidl/vts/functional/Android.bp +++ b/security/keymint/aidl/vts/functional/Android.bp @@ -43,8 +43,11 @@ cc_defaults { "android.hardware.gatekeeper-V1-ndk", "android.hardware.security.rkp-V3-ndk", "android.hardware.security.secureclock-V1-ndk", + "libavb_user", + "libavb", "libcppbor_external", "libcppcose_rkp", + "libfs_mgr", "libjsoncpp", "libkeymint", "libkeymint_remote_prov_support", diff --git a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp index e759123334..a868c966e6 100644 --- a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp +++ b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp @@ -80,7 +80,13 @@ string get_imei(int slot) { return ""; } - return ::android::base::Trim(out[0]); + string imei = ::android::base::Trim(out[0]); + if (imei.compare("null") == 0) { + LOG(ERROR) << "Error in getting IMEI from Telephony service: value is null. Cmd: " << cmd; + return ""; + } + + return imei; } } // namespace @@ -88,96 +94,9 @@ string get_imei(int slot) { class AttestKeyTest : public KeyMintAidlTestBase { public: void SetUp() override { - check_skip_test(); + skipAttestKeyTest(); KeyMintAidlTestBase::SetUp(); } - - protected: - const string FEATURE_KEYSTORE_APP_ATTEST_KEY = "android.hardware.keystore.app_attest_key"; - - const string FEATURE_STRONGBOX_KEYSTORE = "android.hardware.strongbox_keystore"; - - ErrorCode GenerateAttestKey(const AuthorizationSet& key_desc, - const optional<AttestationKey>& attest_key, - vector<uint8_t>* key_blob, - vector<KeyCharacteristics>* key_characteristics, - vector<Certificate>* cert_chain) { - // The original specification for KeyMint v1 required ATTEST_KEY not be combined - // with any other key purpose, but the original VTS tests incorrectly did exactly that. - // This means that a device that launched prior to Android T (API level 33) may - // accept or even require KeyPurpose::SIGN too. - if (property_get_int32("ro.board.first_api_level", 0) < __ANDROID_API_T__) { - AuthorizationSet key_desc_plus_sign = key_desc; - key_desc_plus_sign.push_back(TAG_PURPOSE, KeyPurpose::SIGN); - - auto result = GenerateKey(key_desc_plus_sign, attest_key, key_blob, key_characteristics, - cert_chain); - if (result == ErrorCode::OK) { - return result; - } - // If the key generation failed, it may be because the device is (correctly) - // rejecting the combination of ATTEST_KEY+SIGN. Fall through to try again with - // just ATTEST_KEY. - } - return GenerateKey(key_desc, attest_key, key_blob, key_characteristics, cert_chain); - } - - // Check if ATTEST_KEY feature is disabled - bool is_attest_key_feature_disabled(void) const { - if (!check_feature(FEATURE_KEYSTORE_APP_ATTEST_KEY)) { - GTEST_LOG_(INFO) << "Feature " + FEATURE_KEYSTORE_APP_ATTEST_KEY + " is disabled"; - return true; - } - - return false; - } - - // Check if StrongBox KeyStore is enabled - bool is_strongbox_enabled(void) const { - if (check_feature(FEATURE_STRONGBOX_KEYSTORE)) { - GTEST_LOG_(INFO) << "Feature " + FEATURE_STRONGBOX_KEYSTORE + " is enabled"; - return true; - } - - return false; - } - - // Check if chipset has received a waiver allowing it to be launched with Android S or T with - // Keymaster 4.0 in StrongBox. - bool is_chipset_allowed_km4_strongbox(void) const { - std::array<char, PROPERTY_VALUE_MAX> buffer; - - const int32_t first_api_level = property_get_int32("ro.board.first_api_level", 0); - if (first_api_level <= 0 || first_api_level > __ANDROID_API_T__) return false; - - auto res = property_get("ro.vendor.qti.soc_model", buffer.data(), nullptr); - if (res <= 0) return false; - - const string allowed_soc_models[] = {"SM8450", "SM8475", "SM8550", "SXR2230P"}; - - for (const string model : allowed_soc_models) { - if (model.compare(buffer.data()) == 0) { - GTEST_LOG_(INFO) << "QTI SOC Model " + model + " is allowed SB KM 4.0"; - return true; - } - } - - return false; - } - - // Skip the test if all the following conditions hold: - // 1. ATTEST_KEY feature is disabled - // 2. STRONGBOX is enabled - // 3. The device is running one of the chipsets that have received a waiver - // allowing it to be launched with Android S (or later) with Keymaster 4.0 - // in StrongBox - void check_skip_test(void) const { - // Check the chipset first as that doesn't require a round-trip to Package Manager. - if (is_chipset_allowed_km4_strongbox() && is_strongbox_enabled() && - is_attest_key_feature_disabled()) { - GTEST_SKIP() << "Test is not applicable"; - } - } }; /* @@ -1059,7 +978,7 @@ TEST_P(AttestKeyTest, SecondIMEIAttestationIDSuccess) { // Skip the test if there is no second IMEI exists. string second_imei = get_imei(1); - if (second_imei.empty() || second_imei.compare("null") == 0) { + if (second_imei.empty()) { GTEST_SKIP() << "Test not applicable as there is no second IMEI"; } @@ -1137,13 +1056,13 @@ TEST_P(AttestKeyTest, MultipleIMEIAttestationIDSuccess) { // Skip the test if there is no first IMEI exists. string imei = get_imei(0); - if (imei.empty() || imei.compare("null") == 0) { + if (imei.empty()) { GTEST_SKIP() << "Test not applicable as there is no first IMEI"; } // Skip the test if there is no second IMEI exists. string second_imei = get_imei(1); - if (second_imei.empty() || second_imei.compare("null") == 0) { + if (second_imei.empty()) { GTEST_SKIP() << "Test not applicable as there is no second IMEI"; } diff --git a/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp b/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp index 723edeef3d..54f187c611 100644 --- a/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp +++ b/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp @@ -21,7 +21,11 @@ #include <string> #include <vector> +#include <android-base/properties.h> #include <android/binder_manager.h> +#include <fstab/fstab.h> +#include <libavb/libavb.h> +#include <libavb_user/avb_ops_user.h> #include <remote_prov/remote_prov_utils.h> #include "KeyMintAidlTestBase.h" @@ -34,49 +38,118 @@ using ::std::vector; // Since this test needs to talk to KeyMint HAL, it can only run as root. Thus, // bootloader can not be locked. -class BootloaderStateTest : public testing::TestWithParam<std::string> { +class BootloaderStateTest : public KeyMintAidlTestBase { public: virtual void SetUp() override { - ::ndk::SpAIBinder binder(AServiceManager_waitForService(GetParam().c_str())); - keyMint_ = IKeyMintDevice::fromBinder(binder); - ASSERT_TRUE(keyMint_) << "Failed to get KM device"; + KeyMintAidlTestBase::SetUp(); + + // Generate a key with attestation. + vector<uint8_t> key_blob; + vector<KeyCharacteristics> key_characteristics; + AuthorizationSet keyDesc = AuthorizationSetBuilder() + .Authorization(TAG_NO_AUTH_REQUIRED) + .EcdsaSigningKey(EcCurve::P_256) + .AttestationChallenge("foo") + .AttestationApplicationId("bar") + .Digest(Digest::NONE) + .SetDefaultValidity(); + auto result = GenerateKey(keyDesc, &key_blob, &key_characteristics); + // If factory provisioned attestation key is not supported by Strongbox, + // then create a key with self-signed attestation and use it as the + // attestation key instead. + if (SecLevel() == SecurityLevel::STRONGBOX && + result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) { + result = GenerateKeyWithSelfSignedAttestKey( + AuthorizationSetBuilder() + .EcdsaKey(EcCurve::P_256) + .AttestKey() + .SetDefaultValidity(), /* attest key params */ + keyDesc, &key_blob, &key_characteristics); + } + ASSERT_EQ(ErrorCode::OK, result); + + // Parse attested AVB values. + X509_Ptr cert(parse_cert_blob(cert_chain_[0].encodedCertificate)); + ASSERT_TRUE(cert.get()); + + ASN1_OCTET_STRING* attest_rec = get_attestation_record(cert.get()); + ASSERT_TRUE(attest_rec); + + auto error = parse_root_of_trust(attest_rec->data, attest_rec->length, &attestedVbKey_, + &attestedVbState_, &attestedBootloaderState_, + &attestedVbmetaDigest_); + ASSERT_EQ(error, ErrorCode::OK); } - std::shared_ptr<IKeyMintDevice> keyMint_; + vector<uint8_t> attestedVbKey_; + VerifiedBoot attestedVbState_; + bool attestedBootloaderState_; + vector<uint8_t> attestedVbmetaDigest_; }; // Check that attested bootloader state is set to unlocked. -TEST_P(BootloaderStateTest, IsUnlocked) { - // Generate a key with attestation. - AuthorizationSet keyDesc = AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .EcdsaSigningKey(EcCurve::P_256) - .AttestationChallenge("foo") - .AttestationApplicationId("bar") - .Digest(Digest::NONE) - .SetDefaultValidity(); - KeyCreationResult creationResult; - auto kmStatus = keyMint_->generateKey(keyDesc.vector_data(), std::nullopt, &creationResult); - ASSERT_TRUE(kmStatus.isOk()); - - vector<Certificate> key_cert_chain = std::move(creationResult.certificateChain); - - // Parse attested AVB values. - const auto& attestation_cert = key_cert_chain[0].encodedCertificate; - X509_Ptr cert(parse_cert_blob(attestation_cert)); - ASSERT_TRUE(cert.get()); - - ASN1_OCTET_STRING* attest_rec = get_attestation_record(cert.get()); - ASSERT_TRUE(attest_rec); - - vector<uint8_t> key; - VerifiedBoot attestedVbState; - bool attestedBootloaderState; - vector<uint8_t> attestedVbmetaDigest; - auto error = parse_root_of_trust(attest_rec->data, attest_rec->length, &key, &attestedVbState, - &attestedBootloaderState, &attestedVbmetaDigest); - ASSERT_EQ(error, ErrorCode::OK); - ASSERT_FALSE(attestedBootloaderState) << "This test runs as root. Bootloader must be unlocked."; +TEST_P(BootloaderStateTest, BootloaderIsUnlocked) { + ASSERT_FALSE(attestedBootloaderState_) + << "This test runs as root. Bootloader must be unlocked."; +} + +// Check that verified boot state is set to "unverified", i.e. "orange". +TEST_P(BootloaderStateTest, VbStateIsUnverified) { + // Unlocked bootloader implies that verified boot state must be "unverified". + ASSERT_EQ(attestedVbState_, VerifiedBoot::UNVERIFIED) + << "Verified boot state must be \"UNVERIFIED\" aka \"orange\"."; + + // AVB spec stipulates that bootloader must set "androidboot.verifiedbootstate" parameter + // on the kernel command-line. This parameter is exposed to userspace as + // "ro.boot.verifiedbootstate" property. + auto vbStateProp = ::android::base::GetProperty("ro.boot.verifiedbootstate", ""); + ASSERT_EQ(vbStateProp, "orange") + << "Verified boot state must be \"UNVERIFIED\" aka \"orange\"."; +} + +// Following error codes from avb_slot_data() mean that slot data was loaded +// (even if verification failed). +static inline bool avb_slot_data_loaded(AvbSlotVerifyResult result) { + switch (result) { + case AVB_SLOT_VERIFY_RESULT_OK: + case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION: + case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX: + case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED: + return true; + default: + return false; + } +} + +// Check that attested vbmeta digest is correct. +TEST_P(BootloaderStateTest, VbmetaDigest) { + AvbSlotVerifyData* avbSlotData; + auto suffix = fs_mgr_get_slot_suffix(); + const char* partitions[] = {nullptr}; + auto avbOps = avb_ops_user_new(); + + // For VTS, devices run with vendor_boot-debug.img, which is not release key + // signed. Use AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR to bypass avb + // verification errors. This is OK since we only care about the digest for + // this test case. + auto result = avb_slot_verify(avbOps, partitions, suffix.c_str(), + AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR, + AVB_HASHTREE_ERROR_MODE_EIO, &avbSlotData); + ASSERT_TRUE(avb_slot_data_loaded(result)) << "Failed to load avb slot data"; + + // Unfortunately, bootloader is not required to report the algorithm used + // to calculate the digest. There are only two supported options though, + // SHA256 and SHA512. Attested VBMeta digest must match one of these. + vector<uint8_t> digest256(AVB_SHA256_DIGEST_SIZE); + vector<uint8_t> digest512(AVB_SHA512_DIGEST_SIZE); + + avb_slot_verify_data_calculate_vbmeta_digest(avbSlotData, AVB_DIGEST_TYPE_SHA256, + digest256.data()); + avb_slot_verify_data_calculate_vbmeta_digest(avbSlotData, AVB_DIGEST_TYPE_SHA512, + digest512.data()); + + ASSERT_TRUE((attestedVbmetaDigest_ == digest256) || (attestedVbmetaDigest_ == digest512)) + << "Attested digest does not match computed digest."; } INSTANTIATE_KEYMINT_AIDL_TEST(BootloaderStateTest); diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp index 5e27bd0e5b..a8ea407e44 100644 --- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp @@ -322,12 +322,13 @@ ErrorCode KeyMintAidlTestBase::GenerateKeyWithSelfSignedAttestKey( const AuthorizationSet& attest_key_desc, const AuthorizationSet& key_desc, vector<uint8_t>* key_blob, vector<KeyCharacteristics>* key_characteristics, vector<Certificate>* cert_chain) { + skipAttestKeyTest(); AttestationKey attest_key; vector<Certificate> attest_cert_chain; vector<KeyCharacteristics> attest_key_characteristics; // Generate a key with self signed attestation. - auto error = GenerateKey(attest_key_desc, std::nullopt, &attest_key.keyBlob, - &attest_key_characteristics, &attest_cert_chain); + auto error = GenerateAttestKey(attest_key_desc, std::nullopt, &attest_key.keyBlob, + &attest_key_characteristics, &attest_cert_chain); if (error != ErrorCode::OK) { return error; } @@ -1548,6 +1549,88 @@ ErrorCode KeyMintAidlTestBase::UseEcdsaKey(const vector<uint8_t>& ecdsaKeyBlob) return result; } +ErrorCode KeyMintAidlTestBase::GenerateAttestKey(const AuthorizationSet& key_desc, + const optional<AttestationKey>& attest_key, + vector<uint8_t>* key_blob, + vector<KeyCharacteristics>* key_characteristics, + vector<Certificate>* cert_chain) { + // The original specification for KeyMint v1 required ATTEST_KEY not be combined + // with any other key purpose, but the original VTS tests incorrectly did exactly that. + // This means that a device that launched prior to Android T (API level 33) may + // accept or even require KeyPurpose::SIGN too. + if (property_get_int32("ro.board.first_api_level", 0) < __ANDROID_API_T__) { + AuthorizationSet key_desc_plus_sign = key_desc; + key_desc_plus_sign.push_back(TAG_PURPOSE, KeyPurpose::SIGN); + + auto result = GenerateKey(key_desc_plus_sign, attest_key, key_blob, key_characteristics, + cert_chain); + if (result == ErrorCode::OK) { + return result; + } + // If the key generation failed, it may be because the device is (correctly) + // rejecting the combination of ATTEST_KEY+SIGN. Fall through to try again with + // just ATTEST_KEY. + } + return GenerateKey(key_desc, attest_key, key_blob, key_characteristics, cert_chain); +} + +// Check if ATTEST_KEY feature is disabled +bool KeyMintAidlTestBase::is_attest_key_feature_disabled(void) const { + if (!check_feature(FEATURE_KEYSTORE_APP_ATTEST_KEY)) { + GTEST_LOG_(INFO) << "Feature " + FEATURE_KEYSTORE_APP_ATTEST_KEY + " is disabled"; + return true; + } + + return false; +} + +// Check if StrongBox KeyStore is enabled +bool KeyMintAidlTestBase::is_strongbox_enabled(void) const { + if (check_feature(FEATURE_STRONGBOX_KEYSTORE)) { + GTEST_LOG_(INFO) << "Feature " + FEATURE_STRONGBOX_KEYSTORE + " is enabled"; + return true; + } + + return false; +} + +// Check if chipset has received a waiver allowing it to be launched with Android S or T with +// Keymaster 4.0 in StrongBox. +bool KeyMintAidlTestBase::is_chipset_allowed_km4_strongbox(void) const { + std::array<char, PROPERTY_VALUE_MAX> buffer; + + const int32_t first_api_level = property_get_int32("ro.board.first_api_level", 0); + if (first_api_level <= 0 || first_api_level > __ANDROID_API_T__) return false; + + auto res = property_get("ro.vendor.qti.soc_model", buffer.data(), nullptr); + if (res <= 0) return false; + + const string allowed_soc_models[] = {"SM8450", "SM8475", "SM8550", "SXR2230P"}; + + for (const string model : allowed_soc_models) { + if (model.compare(buffer.data()) == 0) { + GTEST_LOG_(INFO) << "QTI SOC Model " + model + " is allowed SB KM 4.0"; + return true; + } + } + + return false; +} + +// Skip the test if all the following conditions hold: +// 1. ATTEST_KEY feature is disabled +// 2. STRONGBOX is enabled +// 3. The device is running one of the chipsets that have received a waiver +// allowing it to be launched with Android S (or later) with Keymaster 4.0 +// in StrongBox +void KeyMintAidlTestBase::skipAttestKeyTest(void) const { + // Check the chipset first as that doesn't require a round-trip to Package Manager. + if (is_chipset_allowed_km4_strongbox() && is_strongbox_enabled() && + is_attest_key_feature_disabled()) { + GTEST_SKIP() << "Test is not applicable"; + } +} + void verify_serial(X509* cert, const uint64_t expected_serial) { BIGNUM_Ptr ser(BN_new()); EXPECT_TRUE(ASN1_INTEGER_to_BN(X509_get_serialNumber(cert), ser.get())); diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h index 3245ca98f2..30ac452bab 100644 --- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h +++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h @@ -54,6 +54,9 @@ using ::std::vector; constexpr uint64_t kOpHandleSentinel = 0xFFFFFFFFFFFFFFFF; +const string FEATURE_KEYSTORE_APP_ATTEST_KEY = "android.hardware.keystore.app_attest_key"; +const string FEATURE_STRONGBOX_KEYSTORE = "android.hardware.strongbox_keystore"; + class KeyMintAidlTestBase : public ::testing::TestWithParam<string> { public: struct KeyData { @@ -347,6 +350,17 @@ class KeyMintAidlTestBase : public ::testing::TestWithParam<string> { ErrorCode UseRsaKey(const vector<uint8_t>& rsaKeyBlob); ErrorCode UseEcdsaKey(const vector<uint8_t>& ecdsaKeyBlob); + ErrorCode GenerateAttestKey(const AuthorizationSet& key_desc, + const optional<AttestationKey>& attest_key, + vector<uint8_t>* key_blob, + vector<KeyCharacteristics>* key_characteristics, + vector<Certificate>* cert_chain); + + bool is_attest_key_feature_disabled(void) const; + bool is_strongbox_enabled(void) const; + bool is_chipset_allowed_km4_strongbox(void) const; + void skipAttestKeyTest(void) const; + protected: std::shared_ptr<IKeyMintDevice> keymint_; uint32_t os_version_; diff --git a/security/rkp/README.md b/security/rkp/README.md index 01c90a8db1..7477f803b3 100644 --- a/security/rkp/README.md +++ b/security/rkp/README.md @@ -291,6 +291,24 @@ available on the device it should appear in the certificate request as the leaf of a DKCertChain in AdditionalDKSignatures (see [CertificateRequest](#certificaterequest)). +#### Mode + +The Open Profile for DICE specifies four possible modes with the most important +mode being `normal`. A certificate must only set the mode to `normal` when all +of the following conditions are met when loading and verifying the software +component that is being described by the certificate: + +* verified boot with anti-rollback protection is enabled +* only the verified boot authorities for production images are enabled +* debug ports, fuses or other debug facilities are disabled +* device booted software from the normal primary source e.g. internal flash + +If any of these conditions are not met then it is recommended to explicitly +acknowledge this fact by using the `debug` mode. The mode should never be `not +configured`. + +#### Configuration descriptor + The Open Profile for DICE allows for an arbitrary configuration descriptor. For BCC entries, this configuration descriptor is a CBOR map with the following optional fields. If no fields are relevant, an empty map should be encoded. diff --git a/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl b/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl index 461357d4e3..2a4cba1f0e 100644 --- a/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl +++ b/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl @@ -134,6 +134,10 @@ interface IRemotelyProvisionedComponent { * are marked (see the definition of PublicKey in the MacedPublicKey structure) to * prevent them from being confused with production keys. * + * This parameter has been deprecated since version 3 of the HAL and will always be + * false. From v3, if this parameter is true, the method must raise a + * ServiceSpecificException with an error of code of STATUS_REMOVED. + * * @param out MacedPublicKey macedPublicKey contains the public key of the generated key pair, * MACed so that generateCertificateRequest can easily verify, without the * privateKeyHandle, that the contained public key is for remote certification. diff --git a/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp b/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp index 94bfbb48de..62463ebc7b 100644 --- a/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp +++ b/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp @@ -47,7 +47,11 @@ using ::std::vector; namespace { constexpr int32_t VERSION_WITH_UNIQUE_ID_SUPPORT = 2; + +constexpr int32_t VERSION_WITHOUT_EEK = 3; constexpr int32_t VERSION_WITHOUT_TEST_MODE = 3; +constexpr int32_t VERSION_WITH_CERTIFICATE_REQUEST_V2 = 3; +constexpr int32_t VERSION_WITH_SUPPORTED_NUM_KEYS_IN_CSR = 3; constexpr uint8_t MIN_CHALLENGE_SIZE = 0; constexpr uint8_t MAX_CHALLENGE_SIZE = 64; @@ -226,21 +230,13 @@ TEST_P(GetHardwareInfoTests, supportsValidCurve) { RpcHardwareInfo hwInfo; ASSERT_TRUE(provisionable_->getHardwareInfo(&hwInfo).isOk()); - const std::set<int> validCurves = {RpcHardwareInfo::CURVE_P256, RpcHardwareInfo::CURVE_25519}; - // First check for the implementations that supports only IRPC V3+. - if (rpcHardwareInfo.versionNumber >= VERSION_WITHOUT_TEST_MODE) { - bytevec keysToSignMac; - DeviceInfo deviceInfo; - ProtectedData protectedData; - auto status = provisionable_->generateCertificateRequest(false, {}, {}, {}, &deviceInfo, - &protectedData, &keysToSignMac); - if (!status.isOk() && - (status.getServiceSpecificError() == BnRemotelyProvisionedComponent::STATUS_REMOVED)) { - ASSERT_EQ(hwInfo.supportedEekCurve, RpcHardwareInfo::CURVE_NONE) - << "Invalid curve: " << hwInfo.supportedEekCurve; - return; - } + if (rpcHardwareInfo.versionNumber >= VERSION_WITHOUT_EEK) { + ASSERT_EQ(hwInfo.supportedEekCurve, RpcHardwareInfo::CURVE_NONE) + << "Invalid curve: " << hwInfo.supportedEekCurve; + return; } + + const std::set<int> validCurves = {RpcHardwareInfo::CURVE_P256, RpcHardwareInfo::CURVE_25519}; ASSERT_EQ(validCurves.count(hwInfo.supportedEekCurve), 1) << "Invalid curve: " << hwInfo.supportedEekCurve; } @@ -264,7 +260,7 @@ TEST_P(GetHardwareInfoTests, uniqueId) { * Verify implementation supports at least MIN_SUPPORTED_NUM_KEYS_IN_CSR keys in a CSR. */ TEST_P(GetHardwareInfoTests, supportedNumKeysInCsr) { - if (rpcHardwareInfo.versionNumber < VERSION_WITHOUT_TEST_MODE) { + if (rpcHardwareInfo.versionNumber < VERSION_WITH_SUPPORTED_NUM_KEYS_IN_CSR) { return; } @@ -365,6 +361,13 @@ TEST_P(GenerateKeyTests, generateEcdsaP256Key_testMode) { bytevec privateKeyBlob; bool testMode = true; auto status = provisionable_->generateEcdsaP256KeyPair(testMode, &macedPubKey, &privateKeyBlob); + + if (rpcHardwareInfo.versionNumber >= VERSION_WITHOUT_TEST_MODE) { + ASSERT_FALSE(status.isOk()); + EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_REMOVED); + return; + } + ASSERT_TRUE(status.isOk()); check_maced_pubkey(macedPubKey, testMode, nullptr); } @@ -410,7 +413,7 @@ class CertificateRequestTest : public CertificateRequestTestBase { CertificateRequestTestBase::SetUp(); ASSERT_FALSE(HasFatalFailure()); - if (rpcHardwareInfo.versionNumber >= VERSION_WITHOUT_TEST_MODE) { + if (rpcHardwareInfo.versionNumber >= VERSION_WITH_CERTIFICATE_REQUEST_V2) { GTEST_SKIP() << "This test case only applies to RKP v1 and v2. " << "RKP version discovered: " << rpcHardwareInfo.versionNumber; } @@ -688,7 +691,7 @@ class CertificateRequestV2Test : public CertificateRequestTestBase { CertificateRequestTestBase::SetUp(); ASSERT_FALSE(HasFatalFailure()); - if (rpcHardwareInfo.versionNumber < VERSION_WITHOUT_TEST_MODE) { + if (rpcHardwareInfo.versionNumber < VERSION_WITH_CERTIFICATE_REQUEST_V2) { GTEST_SKIP() << "This test case only applies to RKP v3 and above. " << "RKP version discovered: " << rpcHardwareInfo.versionNumber; } @@ -699,6 +702,7 @@ class CertificateRequestV2Test : public CertificateRequestTestBase { * Generate an empty certificate request with all possible length of challenge, and decrypt and * verify the structure and content. */ +// @VsrTest = 3.10-015 TEST_P(CertificateRequestV2Test, EmptyRequest) { bytevec csr; @@ -718,6 +722,7 @@ TEST_P(CertificateRequestV2Test, EmptyRequest) { * Generate a non-empty certificate request with all possible length of challenge. Decrypt, parse * and validate the contents. */ +// @VsrTest = 3.10-015 TEST_P(CertificateRequestV2Test, NonEmptyRequest) { generateKeys(false /* testMode */, 1 /* numKeys */); @@ -750,6 +755,7 @@ TEST_P(CertificateRequestV2Test, EmptyRequestWithInvalidChallengeFail) { * Generate a non-empty certificate request. Make sure contents are reproducible but allow for the * signature to be different since algorithms including ECDSA P-256 can include a random value. */ +// @VsrTest = 3.10-015 TEST_P(CertificateRequestV2Test, NonEmptyRequestReproducible) { generateKeys(false /* testMode */, 1 /* numKeys */); @@ -773,6 +779,7 @@ TEST_P(CertificateRequestV2Test, NonEmptyRequestReproducible) { /** * Generate a non-empty certificate request with multiple keys. */ +// @VsrTest = 3.10-015 TEST_P(CertificateRequestV2Test, NonEmptyRequestMultipleKeys) { generateKeys(false /* testMode */, rpcHardwareInfo.supportedNumKeysInCsr /* numKeys */); @@ -802,23 +809,23 @@ TEST_P(CertificateRequestV2Test, NonEmptyRequestCorruptMac) { } /** - * Generate a non-empty certificate request in prod mode, with test keys. Must fail with - * STATUS_TEST_KEY_IN_PRODUCTION_REQUEST. + * Call generateCertificateRequest(). Make sure it's removed. */ -TEST_P(CertificateRequestV2Test, NonEmptyRequest_testKeyInProdCert) { - generateKeys(true /* testMode */, 1 /* numKeys */); - - bytevec csr; - auto status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge_, &csr); +TEST_P(CertificateRequestV2Test, CertificateRequestV1Removed_prodMode) { + bytevec keysToSignMac; + DeviceInfo deviceInfo; + ProtectedData protectedData; + auto status = provisionable_->generateCertificateRequest( + false /* testMode */, {} /* keysToSign */, {} /* EEK chain */, challenge_, &deviceInfo, + &protectedData, &keysToSignMac); ASSERT_FALSE(status.isOk()) << status.getMessage(); - ASSERT_EQ(status.getServiceSpecificError(), - BnRemotelyProvisionedComponent::STATUS_TEST_KEY_IN_PRODUCTION_REQUEST); + EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_REMOVED); } /** - * Call generateCertificateRequest(). Make sure it's removed. + * Call generateCertificateRequest() in test mode. Make sure it's removed. */ -TEST_P(CertificateRequestV2Test, CertificateRequestV1Removed) { +TEST_P(CertificateRequestV2Test, CertificateRequestV1Removed_testMode) { bytevec keysToSignMac; DeviceInfo deviceInfo; ProtectedData protectedData; @@ -846,6 +853,7 @@ void parse_root_of_trust(const vector<uint8_t>& attestation_cert, /** * Generate a CSR and verify DeviceInfo against IDs attested by KeyMint. */ +// @VsrTest = 3.10-015 TEST_P(CertificateRequestV2Test, DeviceInfo) { // See if there is a matching IKeyMintDevice for this IRemotelyProvisionedComponent. std::shared_ptr<IKeyMintDevice> keyMint; diff --git a/tetheroffload/aidl/Android.bp b/tetheroffload/aidl/Android.bp index b3b6ebf091..6de27c3462 100644 --- a/tetheroffload/aidl/Android.bp +++ b/tetheroffload/aidl/Android.bp @@ -4,7 +4,6 @@ package { aidl_interface { name: "android.hardware.tetheroffload", - owner: "google", vendor_available: true, srcs: ["android/hardware/tetheroffload/*.aidl"], stability: "vintf", @@ -24,4 +23,12 @@ aidl_interface { apps_enabled: false, }, }, + versions_with_info: [ + { + version: "1", + imports: [], + }, + ], + frozen: true, + } diff --git a/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/.hash b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/.hash new file mode 100644 index 0000000000..e7b452e355 --- /dev/null +++ b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/.hash @@ -0,0 +1 @@ +ba3f0342e13af942628a6c00e920d55ce8ad1ea3 diff --git a/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/android/hardware/tetheroffload/ForwardedStats.aidl b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/android/hardware/tetheroffload/ForwardedStats.aidl new file mode 100644 index 0000000000..493a69868f --- /dev/null +++ b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/android/hardware/tetheroffload/ForwardedStats.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2022 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.tetheroffload; +@VintfStability +parcelable ForwardedStats { + long rxBytes; + long txBytes; +} diff --git a/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/android/hardware/tetheroffload/IOffload.aidl b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/android/hardware/tetheroffload/IOffload.aidl new file mode 100644 index 0000000000..9a58b1fbba --- /dev/null +++ b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/android/hardware/tetheroffload/IOffload.aidl @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2022 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.tetheroffload; +@VintfStability +interface IOffload { + void initOffload(in ParcelFileDescriptor fd1, in ParcelFileDescriptor fd2, in android.hardware.tetheroffload.ITetheringOffloadCallback cb); + void stopOffload(); + void setLocalPrefixes(in String[] prefixes); + android.hardware.tetheroffload.ForwardedStats getForwardedStats(in String upstream); + void setDataWarningAndLimit(in String upstream, in long warningBytes, in long limitBytes); + void setUpstreamParameters(in String iface, in String v4Addr, in String v4Gw, in String[] v6Gws); + void addDownstream(in String iface, in String prefix); + void removeDownstream(in String iface, in String prefix); + const int ERROR_CODE_UNUSED = 0; +} diff --git a/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/android/hardware/tetheroffload/IPv4AddrPortPair.aidl b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/android/hardware/tetheroffload/IPv4AddrPortPair.aidl new file mode 100644 index 0000000000..2b42f0c056 --- /dev/null +++ b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/android/hardware/tetheroffload/IPv4AddrPortPair.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2022 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.tetheroffload; +@VintfStability +parcelable IPv4AddrPortPair { + String addr; + int port; +} diff --git a/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/android/hardware/tetheroffload/ITetheringOffloadCallback.aidl b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/android/hardware/tetheroffload/ITetheringOffloadCallback.aidl new file mode 100644 index 0000000000..4eb7d04d00 --- /dev/null +++ b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/android/hardware/tetheroffload/ITetheringOffloadCallback.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2022 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.tetheroffload; +@VintfStability +interface ITetheringOffloadCallback { + oneway void onEvent(in android.hardware.tetheroffload.OffloadCallbackEvent event); + oneway void updateTimeout(in android.hardware.tetheroffload.NatTimeoutUpdate params); +} diff --git a/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/android/hardware/tetheroffload/NatTimeoutUpdate.aidl b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/android/hardware/tetheroffload/NatTimeoutUpdate.aidl new file mode 100644 index 0000000000..9eddaa205f --- /dev/null +++ b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/android/hardware/tetheroffload/NatTimeoutUpdate.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2022 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.tetheroffload; +@VintfStability +parcelable NatTimeoutUpdate { + android.hardware.tetheroffload.IPv4AddrPortPair src; + android.hardware.tetheroffload.IPv4AddrPortPair dst; + android.hardware.tetheroffload.NetworkProtocol proto; +} diff --git a/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/android/hardware/tetheroffload/NetworkProtocol.aidl b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/android/hardware/tetheroffload/NetworkProtocol.aidl new file mode 100644 index 0000000000..52bd2a6c50 --- /dev/null +++ b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/android/hardware/tetheroffload/NetworkProtocol.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2022 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.tetheroffload; +@Backing(type="int") @VintfStability +enum NetworkProtocol { + TCP = 6, + UDP = 17, +} diff --git a/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/android/hardware/tetheroffload/OffloadCallbackEvent.aidl b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/android/hardware/tetheroffload/OffloadCallbackEvent.aidl new file mode 100644 index 0000000000..026e18ed1d --- /dev/null +++ b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/android/hardware/tetheroffload/OffloadCallbackEvent.aidl @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2022 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.tetheroffload; +@Backing(type="int") @VintfStability +enum OffloadCallbackEvent { + OFFLOAD_STARTED = 1, + OFFLOAD_STOPPED_ERROR = 2, + OFFLOAD_STOPPED_UNSUPPORTED = 3, + OFFLOAD_SUPPORT_AVAILABLE = 4, + OFFLOAD_STOPPED_LIMIT_REACHED = 5, + OFFLOAD_WARNING_REACHED = 6, +} diff --git a/tv/cec/1.0/vts/functional/VtsHalTvCecV1_0TargetTest.cpp b/tv/cec/1.0/vts/functional/VtsHalTvCecV1_0TargetTest.cpp index 7b426899b1..75c44b7c90 100644 --- a/tv/cec/1.0/vts/functional/VtsHalTvCecV1_0TargetTest.cpp +++ b/tv/cec/1.0/vts/functional/VtsHalTvCecV1_0TargetTest.cpp @@ -127,7 +127,15 @@ TEST_P(HdmiCecTest, PhysicalAddress) { TEST_P(HdmiCecTest, SendMessage) { CecMessage message; - message.initiator = CecLogicalAddress::PLAYBACK_1; + if (hasDeviceType(CecDeviceType::TV)) + { + hdmiCec->clearLogicalAddress(); + Return<Result> result = hdmiCec->addLogicalAddress(CecLogicalAddress::TV); + EXPECT_EQ(result, Result::SUCCESS); + message.initiator = CecLogicalAddress::TV; + } + else + message.initiator = CecLogicalAddress::PLAYBACK_1; message.destination = CecLogicalAddress::BROADCAST; message.body.resize(1); message.body[0] = 131; diff --git a/tv/cec/OWNERS b/tv/cec/OWNERS new file mode 100644 index 0000000000..71e74c0f65 --- /dev/null +++ b/tv/cec/OWNERS @@ -0,0 +1,2 @@ +# Bug component: 826094 +include platform/frameworks/base:/core/java/android/hardware/hdmi/OWNERS diff --git a/tv/input/aidl/android/hardware/tv/input/ITvInputCallback.aidl b/tv/input/aidl/android/hardware/tv/input/ITvInputCallback.aidl index 5d4731737b..2c7e32f29d 100644 --- a/tv/input/aidl/android/hardware/tv/input/ITvInputCallback.aidl +++ b/tv/input/aidl/android/hardware/tv/input/ITvInputCallback.aidl @@ -30,7 +30,14 @@ interface ITvInputCallback { void notify(in TvInputEvent event); /** * Notifies the client that an TV message event has occurred. For possible event types, - * check TvMessageEventType. + * check {@link android.hardware.tv.input.TvMessageEventType}. + * + * The first message in a list of messages contained in a + * {@link android.hardware.tv.input.TvMessageEvent} should always have a + * {@link android.hardware.tv.input.TvMessage#subType} of "device_id", + * otherwise the event is discarded. When the subType of a message is "device_id", the ID of + * the device that sent the message should be contained in + * {@link android.hardware.tv.input.TvMessage#groupId} * * @param event Event passed to the client. */ diff --git a/tv/input/aidl/android/hardware/tv/input/TvMessage.aidl b/tv/input/aidl/android/hardware/tv/input/TvMessage.aidl index 88da5383ed..afa48a942e 100644 --- a/tv/input/aidl/android/hardware/tv/input/TvMessage.aidl +++ b/tv/input/aidl/android/hardware/tv/input/TvMessage.aidl @@ -23,8 +23,13 @@ parcelable TvMessage { */ const long NO_GROUP_ID = -1; /** - * Extended data type, like “ATSC A/336 Watermark”, “ATSC_CC”, etc. This is opaque - * to the framework. + * Extended data type, like “ATSC A/336 Watermark”, “ATSC_CC”, etc. This type is opaque to the + * framework except when the subtype is "device_id". If the subtype is "device_id", the ID of + * device that sent the message should be contained in {@link #groupId}. + * + * The first message in a list of messages contained in + * {@link android.hardware.tv.input.TvMessageEvent} should always have the subtype "device_id", + * otherwise the event is discarded. */ String subType; /** @@ -32,6 +37,9 @@ parcelable TvMessage { * headers and bodies of the same event. For messages that do not have a group, this value * should be -1. * + * If {@link #subType} is "device_id", this value should contain the ID of the device that sent + * this message. + * * As -1 is a reserved value, -1 should not be used as a valid groupId. */ long groupId; diff --git a/tv/input/aidl/default/TvInput.cpp b/tv/input/aidl/default/TvInput.cpp index c986ef1552..2ee8bcfec8 100644 --- a/tv/input/aidl/default/TvInput.cpp +++ b/tv/input/aidl/default/TvInput.cpp @@ -68,7 +68,13 @@ void TvInput::init() { ::ndk::ScopedAStatus TvInput::setTvMessageEnabled(int32_t deviceId, int32_t streamId, TvMessageEventType in_type, bool enabled) { ALOGV("%s", __FUNCTION__); - // TODO: Implement this + + if (mStreamConfigs.count(deviceId) == 0) { + ALOGW("Device with id %d isn't available", deviceId); + return ::ndk::ScopedAStatus::fromServiceSpecificError(STATUS_INVALID_ARGUMENTS); + } + + mTvMessageEventEnabled[deviceId][streamId][in_type] = enabled; return ::ndk::ScopedAStatus::ok(); } @@ -76,7 +82,10 @@ void TvInput::init() { MQDescriptor<int8_t, SynchronizedReadWrite>* out_queue, int32_t in_deviceId, int32_t in_streamId) { ALOGV("%s", __FUNCTION__); - // TODO: Implement this + if (mStreamConfigs.count(in_deviceId) == 0) { + ALOGW("Device with id %d isn't available", in_deviceId); + return ::ndk::ScopedAStatus::fromServiceSpecificError(STATUS_INVALID_ARGUMENTS); + } return ::ndk::ScopedAStatus::ok(); } diff --git a/tv/input/aidl/default/TvInput.h b/tv/input/aidl/default/TvInput.h index 92e7d4ca69..57769618e3 100644 --- a/tv/input/aidl/default/TvInput.h +++ b/tv/input/aidl/default/TvInput.h @@ -22,6 +22,7 @@ #include <aidl/android/hardware/tv/input/TvMessageEventType.h> #include <fmq/AidlMessageQueue.h> #include <map> +#include <unordered_map> #include "TvInputDeviceInfoWrapper.h" #include "TvStreamConfigWrapper.h" @@ -38,6 +39,9 @@ namespace hardware { namespace tv { namespace input { +using TvMessageEnabledMap = std::unordered_map< + int32_t, std::unordered_map<int32_t, std::unordered_map<TvMessageEventType, bool>>>; + class TvInput : public BnTvInput { public: TvInput(); @@ -53,7 +57,6 @@ class TvInput : public BnTvInput { ::ndk::ScopedAStatus openStream(int32_t in_deviceId, int32_t in_streamId, NativeHandle* _aidl_return) override; ::ndk::ScopedAStatus closeStream(int32_t in_deviceId, int32_t in_streamId) override; - void init(); private: @@ -62,6 +65,7 @@ class TvInput : public BnTvInput { shared_ptr<ITvInputCallback> mCallback; map<int32_t, shared_ptr<TvInputDeviceInfoWrapper>> mDeviceInfos; map<int32_t, map<int32_t, shared_ptr<TvStreamConfigWrapper>>> mStreamConfigs; + TvMessageEnabledMap mTvMessageEventEnabled; }; } // namespace input diff --git a/tv/input/aidl/vts/functional/VtsHalTvInputTargetTest.cpp b/tv/input/aidl/vts/functional/VtsHalTvInputTargetTest.cpp index a2415b4f8e..6433305ba3 100644 --- a/tv/input/aidl/vts/functional/VtsHalTvInputTargetTest.cpp +++ b/tv/input/aidl/vts/functional/VtsHalTvInputTargetTest.cpp @@ -259,8 +259,11 @@ TEST_P(TvInputAidlTest, OpenAnOpenedStreamsTest) { return; } int32_t device_id = stream_config_.keyAt(indices[0]); - int32_t stream_id = stream_config_.valueAt(indices[0])[0].streamId; - + vector<TvStreamConfig> streamConfigs = stream_config_.valueAt(indices[0]); + if (streamConfigs.empty()) { + return; + } + int32_t stream_id = streamConfigs[0].streamId; NativeHandle handle; ALOGD("OpenAnOpenedStreamsTest: open stream, device_id=%d, stream_id=%d", device_id, stream_id); @@ -291,7 +294,11 @@ TEST_P(TvInputAidlTest, CloseStreamBeforeOpenTest) { return; } int32_t device_id = stream_config_.keyAt(indices[0]); - int32_t stream_id = stream_config_.valueAt(indices[0])[0].streamId; + vector<TvStreamConfig> streamConfigs = stream_config_.valueAt(indices[0]); + if (streamConfigs.empty()) { + return; + } + int32_t stream_id = streamConfigs[0].streamId; ALOGD("CloseStreamBeforeOpenTest: close stream, device_id=%d, stream_id=%d", device_id, stream_id); @@ -299,6 +306,43 @@ TEST_P(TvInputAidlTest, CloseStreamBeforeOpenTest) { ITvInput::STATUS_INVALID_STATE); } +TEST_P(TvInputAidlTest, SetTvMessageEnabledTest) { + unique_lock<mutex> lock(mutex_); + + updateAllStreamConfigurations(); + vector<size_t> indices = getConfigIndices(); + if (indices.empty()) { + return; + } + int32_t device_id = stream_config_.keyAt(indices[0]); + vector<TvStreamConfig> streamConfigs = stream_config_.valueAt(indices[0]); + if (streamConfigs.empty()) { + return; + } + int32_t stream_id = streamConfigs[0].streamId; + ALOGD("SetTvMessageEnabledTest: device_id=%d, stream_id=%d", device_id, stream_id); + tv_input_->setTvMessageEnabled(device_id, stream_id, TvMessageEventType::WATERMARK, true); +} + +TEST_P(TvInputAidlTest, GetTvMessageQueueTest) { + unique_lock<mutex> lock(mutex_); + + updateAllStreamConfigurations(); + vector<size_t> indices = getConfigIndices(); + if (indices.empty()) { + return; + } + int32_t device_id = stream_config_.keyAt(indices[0]); + vector<TvStreamConfig> streamConfigs = stream_config_.valueAt(indices[0]); + if (streamConfigs.empty()) { + return; + } + int32_t stream_id = streamConfigs[0].streamId; + ALOGD("GetTvMessageQueueTest: device_id=%d, stream_id=%d", device_id, stream_id); + MQDescriptor<int8_t, SynchronizedReadWrite> queue; + tv_input_->getTvMessageQueueDesc(&queue, device_id, stream_id); +} + INSTANTIATE_TEST_SUITE_P(PerInstance, TvInputAidlTest, testing::ValuesIn(android::getAidlHalInstanceNames(ITvInput::descriptor)), android::PrintInstanceNameToString); diff --git a/tv/input/aidl/vts/functional/VtsHalTvInputTargetTest.h b/tv/input/aidl/vts/functional/VtsHalTvInputTargetTest.h index 20d922703b..832b27ce44 100644 --- a/tv/input/aidl/vts/functional/VtsHalTvInputTargetTest.h +++ b/tv/input/aidl/vts/functional/VtsHalTvInputTargetTest.h @@ -37,6 +37,7 @@ using namespace aidl::android::hardware::tv::input; using namespace std; using ::aidl::android::hardware::common::NativeHandle; using ::aidl::android::hardware::common::fmq::MQDescriptor; +using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite; using ::android::AidlMessageQueue; #define WAIT_FOR_EVENT_TIMEOUT 5 diff --git a/tv/tuner/1.0/vts/OWNERS b/tv/tuner/1.0/vts/OWNERS index 1b3d095f9c..9bdafca629 100644 --- a/tv/tuner/1.0/vts/OWNERS +++ b/tv/tuner/1.0/vts/OWNERS @@ -1,3 +1,4 @@ +# Bug component: 136752 nchalko@google.com amyjojo@google.com shubang@google.com diff --git a/tv/tuner/1.1/vts/OWNERS b/tv/tuner/1.1/vts/OWNERS index 1b3d095f9c..9bdafca629 100644 --- a/tv/tuner/1.1/vts/OWNERS +++ b/tv/tuner/1.1/vts/OWNERS @@ -1,3 +1,4 @@ +# Bug component: 136752 nchalko@google.com amyjojo@google.com shubang@google.com diff --git a/uwb/aidl/default/Android.bp b/uwb/aidl/default/Android.bp index 8c2b60e37d..9621f2cb10 100644 --- a/uwb/aidl/default/Android.bp +++ b/uwb/aidl/default/Android.bp @@ -7,29 +7,26 @@ package { default_applicable_licenses: ["hardware_interfaces_license"], } -cc_binary { +rust_binary { name: "android.hardware.uwb-service", + crate_name: "uwb_default_hal", relative_install_path: "hw", - init_rc: ["uwb-service.rc"], vintf_fragments: ["uwb-service.xml"], vendor: true, - cflags: [ - "-Wall", - "-Wextra", - "-g", + rustlibs: [ + "android.hardware.uwb-V1-rust", + "liblogger", + "liblog_rust", + "libbinder_rs", + "libbinder_tokio_rs", + "libtokio", + "libnix", + "libanyhow", ], - shared_libs: [ - "liblog", - "libbinder_ndk", - ], - static_libs: [ - "libbase", - "libutils", - "android.hardware.uwb-V1-ndk", + proc_macros: [ + "libasync_trait", ], srcs: [ - "service.cpp", - "uwb.cpp", - "uwb_chip.cpp", + "src/service.rs", ], } diff --git a/uwb/aidl/default/service.cpp b/uwb/aidl/default/service.cpp deleted file mode 100644 index 007637f5d1..0000000000 --- a/uwb/aidl/default/service.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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. - */ - -#include <android-base/logging.h> -#include <android/binder_manager.h> -#include <android/binder_process.h> -#include <utils/StrongPointer.h> - -#include "uwb.h" - -using ::aidl::android::hardware::uwb::IUwb; -using ::android::sp; -using ::android::base::InitLogging; -using ::android::base::StderrLogger; -using ::android::hardware::uwb::impl::Uwb; - -int main(int /*argc*/, char* argv[]) { - InitLogging(argv, StderrLogger); - LOG(INFO) << "UWB HAL starting up"; - - ABinderProcess_setThreadPoolMaxThreadCount(0); - std::shared_ptr<IUwb> uwb = ndk::SharedRefBase::make<Uwb>(); - const std::string instance = std::string() + IUwb::descriptor + "/default"; - binder_status_t status = AServiceManager_addService(uwb->asBinder().get(), instance.c_str()); - CHECK(status == STATUS_OK); - - ABinderProcess_joinThreadPool(); - return EXIT_FAILURE; // should not reach -} diff --git a/uwb/aidl/default/src/service.rs b/uwb/aidl/default/src/service.rs new file mode 100644 index 0000000000..7d5c07323f --- /dev/null +++ b/uwb/aidl/default/src/service.rs @@ -0,0 +1,47 @@ +use android_hardware_uwb::aidl::android::hardware::uwb::IUwb::{self, IUwb as _}; +use android_hardware_uwb::binder; + +use tokio::runtime::Runtime; + +use std::env; +use std::panic; + +use log::Level; + +mod uwb; +mod uwb_chip; + +fn main() -> anyhow::Result<()> { + logger::init( + logger::Config::default() + .with_min_level(Level::Debug) + .with_tag_on_device("android.hardware.uwb"), + ); + + // Redirect panic messages to logcat. + panic::set_hook(Box::new(|panic_info| { + log::error!("{}", panic_info); + })); + + log::info!("UWB HAL starting up"); + + // Create the tokio runtime + let rt = Runtime::new()?; + + let chips = env::args() + .skip(1) // Skip binary name + .enumerate() + .map(|(i, arg)| uwb_chip::UwbChip::new(i.to_string(), arg)); + + binder::add_service( + &format!("{}/default", IUwb::BpUwb::get_descriptor()), + IUwb::BnUwb::new_binder( + uwb::Uwb::from_chips(chips, rt.handle().clone()), + binder::BinderFeatures::default(), + ) + .as_binder(), + )?; + + binder::ProcessState::join_thread_pool(); + Ok(()) +} diff --git a/uwb/aidl/default/src/uwb.rs b/uwb/aidl/default/src/uwb.rs new file mode 100644 index 0000000000..428f08fec0 --- /dev/null +++ b/uwb/aidl/default/src/uwb.rs @@ -0,0 +1,53 @@ +use android_hardware_uwb::aidl::android::hardware::uwb::{IUwb, IUwbChip}; +use android_hardware_uwb::binder; +use binder::{Result, Strong}; +use binder_tokio::TokioRuntime; +use tokio::runtime::Handle as TokioHandle; + +use crate::uwb_chip; + +pub struct Uwb { + chips: Vec<Strong<dyn IUwbChip::IUwbChip>>, +} + +impl Uwb { + pub fn from_chips( + chips: impl IntoIterator<Item = uwb_chip::UwbChip>, + handle: TokioHandle, + ) -> Self { + Self { + chips: chips + .into_iter() + .map(|chip| { + IUwbChip::BnUwbChip::new_async_binder( + chip, + TokioRuntime(handle.clone()), + binder::BinderFeatures::default(), + ) + }) + .collect(), + } + } +} + +impl binder::Interface for Uwb {} + +impl IUwb::IUwb for Uwb { + fn getChips(&self) -> Result<Vec<String>> { + log::debug!("getChips"); + self.chips.iter().map(|chip| chip.getName()).collect() + } + + fn getChip(&self, name: &str) -> Result<Strong<dyn IUwbChip::IUwbChip>> { + log::debug!("getChip {}", name); + let chip = self + .chips + .iter() + .find(|chip| chip.getName().as_deref() == Ok(name)); + if let Some(chip) = chip { + Ok(chip.clone()) + } else { + Err(binder::ExceptionCode::ILLEGAL_ARGUMENT.into()) + } + } +} diff --git a/uwb/aidl/default/src/uwb_chip.rs b/uwb/aidl/default/src/uwb_chip.rs new file mode 100644 index 0000000000..7c2c30056d --- /dev/null +++ b/uwb/aidl/default/src/uwb_chip.rs @@ -0,0 +1,168 @@ +use android_hardware_uwb::aidl::android::hardware::uwb::{ + IUwbChip::IUwbChipAsyncServer, IUwbClientCallback::IUwbClientCallback, UwbEvent::UwbEvent, + UwbStatus::UwbStatus, +}; +use android_hardware_uwb::binder; +use async_trait::async_trait; +use binder::{Result, Strong}; + +use tokio::fs::File; +use tokio::io::{AsyncReadExt, AsyncWriteExt}; +use tokio::sync::Mutex; + +use std::os::fd::AsRawFd; + +use std::io; + +use nix::sys::termios; + +enum State { + Closed, + Opened { + callbacks: Strong<dyn IUwbClientCallback>, + #[allow(dead_code)] + tasks: tokio::task::JoinSet<()>, + write: File, + }, +} + +pub struct UwbChip { + name: String, + path: String, + state: Mutex<State>, +} + +impl UwbChip { + pub fn new(name: String, path: String) -> Self { + Self { + name, + path, + state: Mutex::new(State::Closed), + } + } +} + +pub fn makeraw(file: File) -> io::Result<File> { + let fd = file.as_raw_fd(); + + let mut attrs = termios::tcgetattr(fd)?; + + termios::cfmakeraw(&mut attrs); + + termios::tcsetattr(fd, termios::SetArg::TCSANOW, &attrs)?; + + Ok(file) +} + +impl binder::Interface for UwbChip {} + +#[async_trait] +impl IUwbChipAsyncServer for UwbChip { + async fn getName(&self) -> Result<String> { + Ok(self.name.clone()) + } + + async fn open(&self, callbacks: &Strong<dyn IUwbClientCallback>) -> Result<()> { + log::debug!("open: {:?}", &self.path); + + let serial = File::open(&self.path) + .await + .and_then(makeraw) + .map_err(|_| binder::StatusCode::UNKNOWN_ERROR)?; + + let mut read = serial + .try_clone() + .await + .map_err(|_| binder::StatusCode::UNKNOWN_ERROR)?; + let write = serial; + + let mut state = self.state.lock().await; + + if let State::Closed = *state { + let client_callbacks = callbacks.clone(); + + let mut tasks = tokio::task::JoinSet::new(); + + tasks.spawn(async move { + loop { + const UWB_HEADER_SIZE: usize = 4; + + let mut buffer = vec![0; UWB_HEADER_SIZE]; + read.read_exact(&mut buffer[0..UWB_HEADER_SIZE]) + .await + .unwrap(); + + let length = buffer[3] as usize + UWB_HEADER_SIZE; + + buffer.resize(length, 0); + read.read_exact(&mut buffer[UWB_HEADER_SIZE..length]) + .await + .unwrap(); + + client_callbacks.onUciMessage(&buffer[..]).unwrap(); + } + }); + + callbacks.onHalEvent(UwbEvent::OPEN_CPLT, UwbStatus::OK)?; + + *state = State::Opened { + callbacks: callbacks.clone(), + tasks, + write, + }; + + Ok(()) + } else { + Err(binder::ExceptionCode::ILLEGAL_STATE.into()) + } + } + + async fn close(&self) -> Result<()> { + log::debug!("close"); + + let mut state = self.state.lock().await; + + if let State::Opened { ref callbacks, .. } = *state { + callbacks.onHalEvent(UwbEvent::CLOSE_CPLT, UwbStatus::OK)?; + *state = State::Closed; + Ok(()) + } else { + Err(binder::ExceptionCode::ILLEGAL_STATE.into()) + } + } + + async fn coreInit(&self) -> Result<()> { + log::debug!("coreInit"); + + if let State::Opened { ref callbacks, .. } = *self.state.lock().await { + callbacks.onHalEvent(UwbEvent::POST_INIT_CPLT, UwbStatus::OK)?; + Ok(()) + } else { + Err(binder::ExceptionCode::ILLEGAL_STATE.into()) + } + } + + async fn sessionInit(&self, _id: i32) -> Result<()> { + log::debug!("sessionInit"); + + Ok(()) + } + + async fn getSupportedAndroidUciVersion(&self) -> Result<i32> { + Ok(1) + } + + async fn sendUciMessage(&self, data: &[u8]) -> Result<i32> { + log::debug!("sendUciMessage"); + + if let State::Opened { write, .. } = &mut *self.state.lock().await { + write + .write(data) + .await + .map(|written| written as i32) + .map_err(|_| binder::StatusCode::UNKNOWN_ERROR.into()) + } else { + Err(binder::ExceptionCode::ILLEGAL_STATE.into()) + } + } +} diff --git a/uwb/aidl/default/uwb-service.rc b/uwb/aidl/default/uwb-service.rc deleted file mode 100644 index e2c3825d35..0000000000 --- a/uwb/aidl/default/uwb-service.rc +++ /dev/null @@ -1,3 +0,0 @@ -service vendor.uwb_hal /vendor/bin/hw/android.hardware.uwb-service - class hal - user uwb diff --git a/uwb/aidl/default/uwb.cpp b/uwb/aidl/default/uwb.cpp deleted file mode 100644 index 1e2ef4e0a4..0000000000 --- a/uwb/aidl/default/uwb.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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. - */ -#include <android-base/logging.h> - -#include "uwb.h" - -namespace { -static constexpr char kDefaultChipName[] = "default"; - -} // namespace - -namespace android { -namespace hardware { -namespace uwb { -namespace impl { -using namespace ::aidl::android::hardware::uwb; - -// The default implementation of the HAL assumes 1 chip on the device. -Uwb::Uwb() : chips_({{kDefaultChipName, ndk::SharedRefBase::make<UwbChip>(kDefaultChipName)}}) {} - -Uwb::~Uwb() {} - -::ndk::ScopedAStatus Uwb::getChips(std::vector<std::string>* names) { - for (const auto& chip : chips_) { - names->push_back(chip.first); - } - return ndk::ScopedAStatus::ok(); -} - -::ndk::ScopedAStatus Uwb::getChip(const std::string& name, std::shared_ptr<IUwbChip>* chip) { - const auto chip_found = chips_.find(name); - if (chip_found == chips_.end()) { - LOG(ERROR) << "Unknown chip name" << name; - return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); - } - *chip = chip_found->second; - return ndk::ScopedAStatus::ok(); -} -} // namespace impl -} // namespace uwb -} // namespace hardware -} // namespace android diff --git a/uwb/aidl/default/uwb.h b/uwb/aidl/default/uwb.h deleted file mode 100644 index ec51fd8a5c..0000000000 --- a/uwb/aidl/default/uwb.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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. - */ -#ifndef ANDROID_HARDWARE_UWB_UWB -#define ANDROID_HARDWARE_UWB_UWB - -#include <map> -#include <vector> - -#include <aidl/android/hardware/uwb/BnUwb.h> -#include <aidl/android/hardware/uwb/IUwbChip.h> - -#include "uwb_chip.h" - -namespace android { -namespace hardware { -namespace uwb { -namespace impl { -using namespace ::aidl::android::hardware::uwb; -// Default implementation mean't to be used on simulator targets. -class Uwb : public BnUwb { - public: - Uwb(); - virtual ~Uwb(); - - ::ndk::ScopedAStatus getChips(std::vector<std::string>* names) override; - ::ndk::ScopedAStatus getChip(const std::string& name, std::shared_ptr<IUwbChip>* chip) override; - - private: - std::map<std::string, std::shared_ptr<UwbChip>> chips_; -}; -} // namespace impl -} // namespace uwb -} // namespace hardware -} // namespace android - -#endif // ANDROID_HARDWARE_UWB_UWB
\ No newline at end of file diff --git a/uwb/aidl/default/uwb_chip.cpp b/uwb/aidl/default/uwb_chip.cpp deleted file mode 100644 index 41f14fd894..0000000000 --- a/uwb/aidl/default/uwb_chip.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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. - */ - -#include "uwb.h" - -namespace { -constexpr static int32_t kAndroidUciVersion = 1; -} - -namespace android { -namespace hardware { -namespace uwb { -namespace impl { -using namespace ::aidl::android::hardware::uwb; - -UwbChip::UwbChip(const std::string& name) : name_(name), mClientCallback(nullptr) {} -UwbChip::~UwbChip() {} - -::ndk::ScopedAStatus UwbChip::getName(std::string* name) { - *name = name_; - return ndk::ScopedAStatus::ok(); -} - -::ndk::ScopedAStatus UwbChip::open(const std::shared_ptr<IUwbClientCallback>& clientCallback) { - mClientCallback = clientCallback; - mClientCallback->onHalEvent(UwbEvent::OPEN_CPLT, UwbStatus::OK); - return ndk::ScopedAStatus::ok(); -} - -::ndk::ScopedAStatus UwbChip::close() { - mClientCallback->onHalEvent(UwbEvent::CLOSE_CPLT, UwbStatus::OK); - mClientCallback = nullptr; - return ndk::ScopedAStatus::ok(); -} - -::ndk::ScopedAStatus UwbChip::coreInit() { - return ndk::ScopedAStatus::ok(); -} - -::ndk::ScopedAStatus UwbChip::sessionInit(int /* sessionId */) { - return ndk::ScopedAStatus::ok(); -} - -::ndk::ScopedAStatus UwbChip::getSupportedAndroidUciVersion(int32_t* version) { - *version = kAndroidUciVersion; - return ndk::ScopedAStatus::ok(); -} - -::ndk::ScopedAStatus UwbChip::sendUciMessage(const std::vector<uint8_t>& /* data */, - int32_t* /* bytes_written */) { - // TODO(b/195992658): Need emulator support for UCI stack. - return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); -} -} // namespace impl -} // namespace uwb -} // namespace hardware -} // namespace android diff --git a/uwb/aidl/default/uwb_chip.h b/uwb/aidl/default/uwb_chip.h deleted file mode 100644 index e900cbe123..0000000000 --- a/uwb/aidl/default/uwb_chip.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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. - */ - -#ifndef ANDROID_HARDWARE_UWB_UWBCHIP -#define ANDROID_HARDWARE_UWB_UWBCHIP - -#include <vector> - -#include <aidl/android/hardware/uwb/BnUwbChip.h> -#include <aidl/android/hardware/uwb/IUwbClientCallback.h> - -namespace android { -namespace hardware { -namespace uwb { -namespace impl { -using namespace ::aidl::android::hardware::uwb; -// Default implementation mean't to be used on simulator targets. -class UwbChip : public BnUwbChip { - public: - UwbChip(const std::string& name); - virtual ~UwbChip(); - - ::ndk::ScopedAStatus getName(std::string* name) override; - ::ndk::ScopedAStatus open(const std::shared_ptr<IUwbClientCallback>& clientCallback) override; - ::ndk::ScopedAStatus close() override; - ::ndk::ScopedAStatus coreInit() override; - ::ndk::ScopedAStatus sessionInit(int sesionId) override; - ::ndk::ScopedAStatus getSupportedAndroidUciVersion(int32_t* version) override; - ::ndk::ScopedAStatus sendUciMessage(const std::vector<uint8_t>& data, - int32_t* bytes_written) override; - - private: - std::string name_; - std::shared_ptr<IUwbClientCallback> mClientCallback; -}; -} // namespace impl -} // namespace uwb -} // namespace hardware -} // namespace android - -#endif // ANDROID_HARDWARE_UWB_UWBCHIP diff --git a/wifi/1.6/vts/functional/wifi_rtt_controller_hidl_test.cpp b/wifi/1.6/vts/functional/wifi_rtt_controller_hidl_test.cpp index 5b5e62364a..0572ac61e3 100644 --- a/wifi/1.6/vts/functional/wifi_rtt_controller_hidl_test.cpp +++ b/wifi/1.6/vts/functional/wifi_rtt_controller_hidl_test.cpp @@ -78,6 +78,13 @@ class WifiRttControllerHidlTest : public ::testing::TestWithParam<std::string> { virtual void TearDown() override { stopWifi(GetInstanceName()); } + RttCapabilities getRttCapabilities() { + std::pair<WifiStatus, RttCapabilities> status_and_caps; + status_and_caps = HIDL_INVOKE(wifi_rtt_controller_, getCapabilities_1_6); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_caps.first.code); + return status_and_caps.second; + } + // A simple test implementation of WifiRttControllerEventCallback. class WifiRttControllerEventCallback : public ::testing::VtsHalHidlTargetCallbackBase<WifiRttControllerHidlTest>, @@ -151,12 +158,9 @@ TEST_P(WifiRttControllerHidlTest, RegisterEventCallback_1_6) { * This test case tests the two sided ranging - 802.11mc FTM protocol. */ TEST_P(WifiRttControllerHidlTest, Request2SidedRangeMeasurement) { - std::pair<WifiStatus, RttCapabilities> status_and_caps; - // Get the Capabilities - status_and_caps = HIDL_INVOKE(wifi_rtt_controller_, getCapabilities_1_6); - EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_caps.first.code); - if (!status_and_caps.second.rttFtmSupported) { + RttCapabilities capabilities = getRttCapabilities(); + if (!capabilities.rttFtmSupported) { GTEST_SKIP() << "Skipping two sided RTT since driver/fw doesn't support"; } std::vector<RttConfig> configs; @@ -196,19 +200,16 @@ TEST_P(WifiRttControllerHidlTest, Request2SidedRangeMeasurement) { * rangeRequest_1_6 */ TEST_P(WifiRttControllerHidlTest, RangeRequest_1_6) { - std::pair<WifiStatus, RttCapabilities> status_and_caps; - // Get the Capabilities - status_and_caps = HIDL_INVOKE(wifi_rtt_controller_, getCapabilities_1_6); - EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_caps.first.code); - if (!status_and_caps.second.rttOneSidedSupported) { + RttCapabilities capabilities = getRttCapabilities(); + if (!capabilities.rttOneSidedSupported) { GTEST_SKIP() << "Skipping one sided RTT since driver/fw doesn't support"; } // Get the highest support preamble int preamble = 1; - status_and_caps.second.preambleSupport >>= 1; - while (status_and_caps.second.preambleSupport != 0) { - status_and_caps.second.preambleSupport >>= 1; + capabilities.preambleSupport >>= 1; + while (capabilities.preambleSupport != 0) { + capabilities.preambleSupport >>= 1; preamble <<= 1; } std::vector<RttConfig> configs; @@ -259,9 +260,14 @@ TEST_P(WifiRttControllerHidlTest, GetCapabilities_1_6) { * getResponderInfo_1_6 */ TEST_P(WifiRttControllerHidlTest, GetResponderInfo_1_6) { - std::pair<WifiStatus, RttResponder> status_and_info; + // Get the capabilities + RttCapabilities capabilities = getRttCapabilities(); + if (!capabilities.responderSupported) { + GTEST_SKIP() << "Skipping because responder is not supported"; + } // Invoke the call + std::pair<WifiStatus, RttResponder> status_and_info; status_and_info = HIDL_INVOKE(wifi_rtt_controller_, getResponderInfo_1_6); EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_info.first.code); } @@ -270,6 +276,12 @@ TEST_P(WifiRttControllerHidlTest, GetResponderInfo_1_6) { * enableResponder_1_6 */ TEST_P(WifiRttControllerHidlTest, EnableResponder_1_6) { + // Get the capabilities + RttCapabilities capabilities = getRttCapabilities(); + if (!capabilities.responderSupported) { + GTEST_SKIP() << "Skipping because responder is not supported"; + } + std::pair<WifiStatus, RttResponder> status_and_info; int cmdId = 55; WifiChannelInfo channelInfo; diff --git a/wifi/aidl/android/hardware/wifi/IWifiNanIface.aidl b/wifi/aidl/android/hardware/wifi/IWifiNanIface.aidl index 3ce8d0214a..e5bb34ef5e 100644 --- a/wifi/aidl/android/hardware/wifi/IWifiNanIface.aidl +++ b/wifi/aidl/android/hardware/wifi/IWifiNanIface.aidl @@ -243,7 +243,10 @@ interface IWifiNanIface { void terminateDataPathRequest(in char cmdId, in int ndpInstanceId); /** - * Start the suspension of a discovery service. + * Start the suspension of a discovery service. During the suspend state, the Wi-Fi Aware + * device must not transmit or receive frames for this session including any active NDPs. If + * all discovery sessions are suspended then the Wi-Fi Aware device must not transmit or + * receive any Wi-Fi Aware frames. * Asynchronous response is with |IWifiNanIfaceEventCallback.notifySuspendResponse|. * * @param cmdId Command Id to use for this invocation. @@ -256,7 +259,10 @@ interface IWifiNanIface { void suspendRequest(in char cmdId, in byte sessionId); /** - * Stop the suspension of a discovery service. + * Stop the suspension of a discovery service. Resume cancels an ongoing suspend for this Wi-Fi + * Aware discovery session and automatically resumes the session and any associated NDPs to the + * state before they were suspended. The Wi-Fi Aware resume operation should be faster than + * recreating the corresponding discovery session and NDPs with the same benefit of power. * Asynchronous response is with |IWifiNanIfaceEventCallback.notifyResumeResponse|. * * @param cmdId Command Id to use for this invocation. diff --git a/wifi/aidl/default/aidl_callback_util.h b/wifi/aidl/default/aidl_callback_util.h index 41d70a53aa..f8ba53ba81 100644 --- a/wifi/aidl/default/aidl_callback_util.h +++ b/wifi/aidl/default/aidl_callback_util.h @@ -19,11 +19,13 @@ #include <android-base/logging.h> +#include <mutex> #include <set> #include <unordered_map> namespace { std::unordered_map<void* /* callback */, void* /* handler */> callback_handler_map_; +std::mutex callback_handler_lock_; } namespace aidl { @@ -43,6 +45,7 @@ class AidlCallbackHandler { ~AidlCallbackHandler() { invalidate(); } bool addCallback(const std::shared_ptr<CallbackType>& cb) { + std::unique_lock<std::mutex> lk(callback_handler_lock_); void* cbPtr = reinterpret_cast<void*>(cb->asBinder().get()); const auto& cbPosition = findCbInSet(cbPtr); if (cbPosition != cb_set_.end()) { @@ -58,12 +61,18 @@ class AidlCallbackHandler { callback_handler_map_[cbPtr] = reinterpret_cast<void*>(this); cb_set_.insert(cb); + // unique_lock unlocked here return true; } - const std::set<std::shared_ptr<CallbackType>>& getCallbacks() { return cb_set_; } + const std::set<std::shared_ptr<CallbackType>>& getCallbacks() { + std::unique_lock<std::mutex> lk(callback_handler_lock_); + // unique_lock unlocked here + return cb_set_; + } void invalidate() { + std::unique_lock<std::mutex> lk(callback_handler_lock_); for (auto cb : cb_set_) { void* cookie = reinterpret_cast<void*>(cb->asBinder().get()); if (AIBinder_unlinkToDeath(cb->asBinder().get(), death_handler_, cookie) != STATUS_OK) { @@ -74,12 +83,14 @@ class AidlCallbackHandler { } } cb_set_.clear(); + // unique_lock unlocked here } // Entry point for the death handling logic. AIBinder_DeathRecipient // can only call a static function, so use the cookie to find the // proper handler and route the request there. static void onCallbackDeath(void* cookie) { + std::unique_lock<std::mutex> lk(callback_handler_lock_); auto cbQuery = callback_handler_map_.find(cookie); if (cbQuery == callback_handler_map_.end()) { LOG(ERROR) << "Invalid death cookie received"; @@ -92,6 +103,7 @@ class AidlCallbackHandler { return; } cbHandler->handleCallbackDeath(cbQuery->first); + // unique_lock unlocked here } private: diff --git a/wifi/aidl/vts/functional/wifi_rtt_controller_aidl_test.cpp b/wifi/aidl/vts/functional/wifi_rtt_controller_aidl_test.cpp index d763fe64a5..4aedc0ef6f 100644 --- a/wifi/aidl/vts/functional/wifi_rtt_controller_aidl_test.cpp +++ b/wifi/aidl/vts/functional/wifi_rtt_controller_aidl_test.cpp @@ -75,6 +75,12 @@ class WifiRttControllerAidlTest : public testing::TestWithParam<std::string> { return rtt_controller; } + RttCapabilities getCapabilities() { + RttCapabilities caps = {}; + EXPECT_TRUE(wifi_rtt_controller_->getCapabilities(&caps).isOk()); + return caps; + } + std::shared_ptr<IWifiRttController> wifi_rtt_controller_; private: @@ -117,6 +123,11 @@ TEST_P(WifiRttControllerAidlTest, GetCapabilities) { * GetResponderInfo */ TEST_P(WifiRttControllerAidlTest, GetResponderInfo) { + RttCapabilities caps = getCapabilities(); + if (!caps.responderSupported) { + GTEST_SKIP() << "Skipping because responder is not supported"; + } + RttResponder responder = {}; EXPECT_TRUE(wifi_rtt_controller_->getResponderInfo(&responder).isOk()); } @@ -125,6 +136,11 @@ TEST_P(WifiRttControllerAidlTest, GetResponderInfo) { * EnableResponder */ TEST_P(WifiRttControllerAidlTest, EnableResponder) { + RttCapabilities caps = getCapabilities(); + if (!caps.responderSupported) { + GTEST_SKIP() << "Skipping because responder is not supported"; + } + int cmdId = 55; WifiChannelInfo channelInfo; channelInfo.width = WifiChannelWidthInMhz::WIDTH_80; @@ -142,8 +158,7 @@ TEST_P(WifiRttControllerAidlTest, EnableResponder) { * Tests the two sided ranging - 802.11mc FTM protocol. */ TEST_P(WifiRttControllerAidlTest, Request2SidedRangeMeasurement) { - RttCapabilities caps = {}; - EXPECT_TRUE(wifi_rtt_controller_->getCapabilities(&caps).isOk()); + RttCapabilities caps = getCapabilities(); if (!caps.rttFtmSupported) { GTEST_SKIP() << "Skipping two sided RTT since driver/fw does not support"; } @@ -179,8 +194,7 @@ TEST_P(WifiRttControllerAidlTest, Request2SidedRangeMeasurement) { * RangeRequest */ TEST_P(WifiRttControllerAidlTest, RangeRequest) { - RttCapabilities caps = {}; - EXPECT_TRUE(wifi_rtt_controller_->getCapabilities(&caps).isOk()); + RttCapabilities caps = getCapabilities(); if (!caps.rttOneSidedSupported) { GTEST_SKIP() << "Skipping one sided RTT since driver/fw does not support"; } diff --git a/wifi/offload/1.0/Android.bp b/wifi/offload/1.0/Android.bp deleted file mode 100644 index 8fd602de1f..0000000000 --- a/wifi/offload/1.0/Android.bp +++ /dev/null @@ -1,24 +0,0 @@ -// This file is autogenerated by hidl-gen -Landroidbp. - -package { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "hardware_interfaces_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - default_applicable_licenses: ["hardware_interfaces_license"], -} - -hidl_interface { - name: "android.hardware.wifi.offload@1.0", - root: "android.hardware", - srcs: [ - "types.hal", - "IOffload.hal", - "IOffloadCallback.hal", - ], - interfaces: [ - "android.hidl.base@1.0", - ], - gen_java: false, -} diff --git a/wifi/offload/1.0/IOffload.hal b/wifi/offload/1.0/IOffload.hal deleted file mode 100644 index 48195195fb..0000000000 --- a/wifi/offload/1.0/IOffload.hal +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 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.wifi.offload@1.0; - -import IOffloadCallback; - -interface IOffload { - /** - * Configure the offload module to perform scans and filter results - * Scans must not be triggered due to configuration of the module. - * - * @param ScanParam paramters for scanning - * @param ScanFilter settings to filter scan result - * @return OffloadStatus indicating status of operation provided by this API - * If OffloadStatusCode::OK is returned, the operation was successful - * If OffloadStatusCode::NO_CONNECTION is returned, connection to the hardware is lost - * If OffloadStatusCode::ERROR is returned, requested operation could not be completed - */ - @entry - @callflow(next={"setEventCallback", "subscribeScanResults"}) - configureScans(ScanParam param, ScanFilter filter) generates (OffloadStatus status); - - /** - * Get scan statistics - * - * @return OffloadStatus indicating status of operation provided by this API - * @return ScanStats statistics of scans performed - * If OffloadStatusCode::OK is returned, the operation was successful - * If OffloadStatusCode::NO_CONNECTION is returned, connection to the hardware is lost - * If OffloadStatusCode::ERROR is returned, requested operation could not be completed - * If OffloadStatusCode::TIMEOUT is returned, time out waiting for the requested data - */ - @exit - @callflow(next={"subscribeScanResults", "unsubscribeScanResults", "getScanStats"}) - getScanStats() generates (OffloadStatus status, ScanStats scanStats); - - /** - * Subscribe to asynchronous scan events sent by offload module. This enables - * offload scans to be performed as per scan parameters, filtering the scan - * results based on configured scan filter and delivering the results after - * at least delayMs milliseconds from this call. If the client is already - * subscribed to the scan results, a call to this API must be a no-op. - * - * @param delayMs an integer expressing the minimum delay in mS after - * subscribing when scan results must be delivered to the client - * @return OffloadStatus indicating status of operation provided by this API - * If OffloadStatusCode::OK is returned, the operation was successful - * If OffloadStatusCode::NO_CONNECTION is returned, connection to the hardware is lost - * If OffloadStatusCode::ERROR is returned, requested operation could not be completed - */ - @callflow(next={"unsubscribeScanResults", "getScanStats"}) - subscribeScanResults(uint32_t delayMs) generates (OffloadStatus status); - - /** - * Unsubscribe to scan events sent by the offload module, hence disabling scans. - * If the client is already unsubscribed, a call to this API will be a no-op. - */ - @exit - @callflow(next={"*"}) - unsubscribeScanResults(); - - /** - * Setup the HIDL interface for reporting asynchronous scan events. A maximum - * of one callback interface is supported. Only one callback must be registered - * at any given time. If two consecutive calls are made with different callback - * interface objects, the latest one must be used to deliver events to client. - * - * @param cb An instance of the |IOffloadCallback| HIDL interface object - */ - @entry - @callflow(next={"subscribeScanStats", "configureScans"}) - setEventCallback(IOffloadCallback cb); -}; diff --git a/wifi/offload/1.0/IOffloadCallback.hal b/wifi/offload/1.0/IOffloadCallback.hal deleted file mode 100644 index 4888125d4e..0000000000 --- a/wifi/offload/1.0/IOffloadCallback.hal +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 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.wifi.offload@1.0; - -interface IOffloadCallback { - /** - * Interface for the Offload HAL to return scan events to the client - * - * @param scanResult a vector of scan result objects - */ - oneway onScanResult(vec<ScanResult> scanResult); - /** - * Interface for the Offload HAL to inform the client of error conditions - * see OffloadStatus for the error conditions to be reported - * - * @param status OffloadStatus - */ - oneway onError(OffloadStatus status); -}; diff --git a/wifi/offload/1.0/types.hal b/wifi/offload/1.0/types.hal deleted file mode 100644 index 234f3fc433..0000000000 --- a/wifi/offload/1.0/types.hal +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.hardware.wifi.offload@1.0; - -/** - * Defines a bitmap of security modes - */ -enum SecurityMode : uint8_t { - OPEN = 0x1 << 1, - WEP = 0x1 << 2, - PSK = 0x1 << 3, - EAP = 0x1 << 4, -}; - -/** - * SSID of the Access Point, maximum 32 characters - */ -typedef vec<uint8_t> Ssid; - -/** - * Preferred network information - * SSID and associated security mode(s) - */ -struct NetworkInfo { - Ssid ssid; - /* SecurityMode flags that are associated with this SSID - * More than one security mode can be supported, see SecurityMode */ - bitfield<SecurityMode> flags; -}; - -/** - * This is a bit mask describing the capabilities of a BSS. - * See IEEE Std 802.11: 8.4.1.4 - */ -enum Capability : uint16_t { - ESS = 1 << 0, - IBSS = 1 << 1, - CF_POLLABLE = 1 << 2, - CF_PLL_REQ = 1 << 3, - PRIVACY = 1 << 4, - SHORT_PREAMBLE = 1 << 5, - PBCC = 1 << 6, - CHANNEL_AGILITY = 1 << 7, - SPECTURM_MGMT = 1 << 8, - QOS = 1 << 9, - SHORT_SLOT_TIME = 1 << 10, - APSD = 1 << 11, - RADIO_MEASUREMENT = 1 << 12, - DSSS_OFDM = 1 << 13, - DELAYED_BLOCK_ACK = 1 << 14, - IMMEDIATE_BLOCK_ACK = 1 << 15, -}; - -/** - * Scan Results returned by the offload Hal - */ -struct ScanResult { - /* Information about this BSS - * SSID and security modes supported */ - NetworkInfo networkInfo; - /* BSSID of the BSS */ - uint8_t[6] bssid; - /* Can have multiple bits set, see Capability */ - bitfield<Capability> capability; - /* Frequency scanned, in mHz */ - uint32_t frequency; - /* Signal strength in dBm */ - int8_t rssi; - /* TSF found in beacon/probe response */ - uint64_t tsf; -}; - - -/** - * Parameters for performing offload scans - */ -struct ScanParam { - /* Specify a list of SSIDs to scan, an empty list implies no preferred - * networks to scan */ - vec<Ssid> ssidList; - /* Frequencies to scan, in mHz, an empty frequency list implies a full scan */ - vec<uint32_t> frequencyList; - /* Periodicity of the scans to be performed by the offload module - * A value of zero indicates disable periodic scans. For this revision, - * where offload module is performing scans in disconnected mode, this value - * should not be zero. In future versions, periodic scans can be eliminated */ - uint32_t disconnectedModeScanIntervalMs; -}; - -/** - * Instruction on how to filter the scan result before performing network - * selection and waking up the AP to connect - */ -struct ScanFilter { - /* Preferred network List of SSIDs and their security mode of interest - * The filter will drop the remaining scan results in the scan event. - * An empty list implies no filtering of scan result based on SSID and - * security mode. */ - vec<NetworkInfo> preferredNetworkInfoList; - /* Minimum qualifying RSSI to be considered for network selection (dBm) */ - int8_t rssiThreshold; -}; - -struct ScanRecord { - /* Amount of time spent scanning */ - uint64_t durationMs; - /* Number of channels scanned */ - uint32_t numChannelsScanned; - /* Number of entries aggregated into this record */ - uint32_t numEntriesAggregated; -}; - -/** - * Enumerates the type of log that is recorded - */ -enum RecordName : uint32_t { - CMD_BASE = 0x00001000, - /* Record name corresponding to initialization */ - CMD_INT = CMD_BASE + 0, - /* Record name corresponding to configureScans() API */ - CMD_CONFIG_SCANS = CMD_BASE + 1, - /* Record name corresponding to subscribeScanResults() API */ - CMD_SUBSCRIBE_SCAN_RESULTS = CMD_BASE + 2, - /* Record name corresponding to unsubscribeScanResults() API */ - CMD_UNSUBSCRIBE_SCAN_RESULTS = CMD_BASE + 3, - /* Record name corresponding to getScanStats() API */ - CMD_GET_SCAN_STATS = CMD_BASE + 4, - /* Record name corresponding to a reset*/ - CMD_RESET = CMD_BASE + 5, - /* Add new commands here */ - EVENT_RECVD_BASE = 0x00002000, - /* Record name corresponding to scan monitor event*/ - EVENT_RECVD_SCAN_RESULT_ASYNC = EVENT_RECVD_BASE + 0, - /* Record name corresponding to scan response event */ - EVENT_RECVD_SCAN_RESULT = EVENT_RECVD_BASE + 1, - /* Add new events received here */ - EVENT_SENT_BASE = 0x00003000, - /* Record name corresponding to scan event sent */ - EVENT_SENT_SCAN_RESULT = EVENT_SENT_BASE + 0, - /* Record name corresponding to abort event sent */ - EVENT_SENT_ABORT = EVENT_SENT_BASE + 1, - /* Record name corresponding to error event sent */ - EVENT_SENT_ERROR = EVENT_SENT_BASE + 2, - /* Add new events sent here */ - REQ_BASE = 0x00004000, - /* Record name corresponding to scan request sent*/ - REQ_SCAN = REQ_BASE + 0, - /* Add new requests here */ -}; - -/** - * Defines the structure of each log record - */ -struct LogRecord { - /* Indicates the log recorded */ - RecordName recordName; - /* Platform reference time in milliseconds when the log is recorded */ - uint64_t logTimeMs; -}; - -/** - * Defines the scan statistics to be returned to the framework - */ -struct ScanStats { - /* Incremented everytime a new scan is requested */ - uint32_t numScansRequestedByWifi; - /* Incremented everytime the scan is serviced by performing a scan*/ - uint32_t numScansServicedByWifi; - /* Incremented everytime the scan is serviced by the scan cache */ - uint32_t numScansServicedbyCache; - /* The last (CHRE reference) time this data structure is updated */ - uint64_t lastUpdated; - /* The last (CHRE reference) time this data structure is read */ - uint64_t lastRead; - /* The total time when the Offload module could be performing scans (T2 - T1) - * T1 - time when the framework subscribes for scan result (includes delayMs) - * T2 - min (time when the framework unsubscribes for scan result, - * currentTime) */ - uint64_t subscriptionDurationMs; - /* Histograms of the channels scanned, 802.11 and with an 8 bit - * representation, only 256 channels are available */ - uint8_t[256] histogramChannelsScanned; - /* Scan Record for this subscribe duration */ - vec<ScanRecord> scanRecord; - /* Vector of the logRecord entries */ - vec<LogRecord> logRecord; -}; - -/** - * Defines a list of return codes to indicate status of Offload HAL - */ -enum OffloadStatusCode : uint32_t { - /* No error */ - OK, - /* No Connection to underlying implementation */ - NO_CONNECTION, - /* Operation timeout */ - TIMEOUT, - /* Other errors */ - ERROR -}; - -/** - * Generic structures to return the status of an operation - */ -struct OffloadStatus { - OffloadStatusCode code; - /* Error message */ - string description; -}; - - - diff --git a/wifi/offload/1.0/vts/functional/Android.bp b/wifi/offload/1.0/vts/functional/Android.bp deleted file mode 100644 index a0eb048c66..0000000000 --- a/wifi/offload/1.0/vts/functional/Android.bp +++ /dev/null @@ -1,32 +0,0 @@ -// -// Copyright (C) 2017 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "hardware_interfaces_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - default_applicable_licenses: ["hardware_interfaces_license"], -} - -cc_test { - name: "VtsHalWifiOffloadV1_0TargetTest", - defaults: ["VtsHalTargetTestDefaults"], - srcs: ["VtsHalWifiOffloadV1_0TargetTest.cpp"], - static_libs: ["android.hardware.wifi.offload@1.0"], - test_suites: ["general-tests", "vts"], -} diff --git a/wifi/offload/1.0/vts/functional/VtsHalWifiOffloadV1_0TargetTest.cpp b/wifi/offload/1.0/vts/functional/VtsHalWifiOffloadV1_0TargetTest.cpp deleted file mode 100644 index ffd5149d58..0000000000 --- a/wifi/offload/1.0/vts/functional/VtsHalWifiOffloadV1_0TargetTest.cpp +++ /dev/null @@ -1,218 +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. - */ - -#define LOG_TAG "wifi_offload_hidl_hal_test" - -#include <android-base/logging.h> -#include <android/hardware/wifi/offload/1.0/IOffload.h> -#include <android/hardware/wifi/offload/1.0/IOffloadCallback.h> -#include <android/hardware/wifi/offload/1.0/types.h> -#include <gtest/gtest.h> -#include <hidl/GtestPrinter.h> -#include <hidl/ServiceManagement.h> - -#include <VtsHalHidlTargetCallbackBase.h> - -#include <vector> - -#include "hidl_call_util.h" - -using ::android::hardware::wifi::offload::V1_0::IOffload; -using ::android::hardware::wifi::offload::V1_0::IOffloadCallback; -using ::android::hardware::wifi::offload::V1_0::ScanResult; -using ::android::hardware::wifi::offload::V1_0::ScanParam; -using ::android::hardware::wifi::offload::V1_0::Ssid; -using ::android::hardware::wifi::offload::V1_0::NetworkInfo; -using ::android::hardware::wifi::offload::V1_0::ScanFilter; -using ::android::hardware::wifi::offload::V1_0::ScanStats; -using ::android::hardware::wifi::offload::V1_0::OffloadStatus; -using ::android::hardware::wifi::offload::V1_0::OffloadStatusCode; -using ::android::hardware::Return; -using ::android::hardware::Void; -using ::android::hardware::hidl_vec; -using ::android::sp; - -constexpr char kOffloadCallbackSendScanResult[] = "onScanResult"; -constexpr char kOffloadCallbackSendError[] = "onError"; - -namespace { -const uint8_t kSsid1[] = {'G', 'o', 'o', 'g', 'l', 'e'}; -const uint8_t kSsid2[] = {'X', 'f', 'i', 'n', 'i', 't', 'y'}; -const uint8_t kBssid[6] = {0x12, 0xef, 0xa1, 0x2c, 0x97, 0x8b}; -const int16_t kRssi = -60; -const uint32_t kFrequency = 2412; -const uint8_t kBssidSize = 6; -const uint64_t kTsf = 0; -const uint16_t kCapability = 0; -const uint8_t kNetworkFlags = 0; -const uint32_t kFrequency1 = 2412; -const uint32_t kFrequency2 = 2437; -const uint32_t kDisconnectedModeScanIntervalMs = 5000; -const int16_t kRssiThreshold = -76; -} - -class OffloadCallbackArgs { - public: - hidl_vec<ScanResult> scan_results_; - OffloadStatus error_code_; -}; - -// The main test class for WifiOffload HIDL HAL. -class WifiOffloadHidlTest : public ::testing::TestWithParam<std::string> { - public: - virtual void SetUp() override { - wifi_offload_ = IOffload::getService(GetParam()); - ASSERT_NE(wifi_offload_, nullptr); - - wifi_offload_cb_ = new OffloadCallback(); - ASSERT_NE(wifi_offload_cb_, nullptr); - } - - virtual void TearDown() override {} - - /* Callback class for Offload HAL. */ - class OffloadCallback - : public ::testing::VtsHalHidlTargetCallbackBase<OffloadCallbackArgs>, - public IOffloadCallback { - public: - OffloadCallback(){}; - - virtual ~OffloadCallback() = default; - - Return<void> onScanResult( - const hidl_vec<ScanResult>& scan_result) override { - OffloadCallbackArgs args; - args.scan_results_ = scan_result; - NotifyFromCallback(kOffloadCallbackSendScanResult, args); - return Void(); - }; - - Return<void> onError(const OffloadStatus& status) override { - OffloadCallbackArgs args; - args.error_code_ = status; - NotifyFromCallback(kOffloadCallbackSendError, args); - return Void(); - } - }; - - sp<IOffload> wifi_offload_; - sp<OffloadCallback> wifi_offload_cb_; -}; - -/* - * Verify that setEventCallback method returns without errors - */ -TEST_P(WifiOffloadHidlTest, setEventCallback) { - auto returnObject = wifi_offload_->setEventCallback(wifi_offload_cb_); - ASSERT_EQ(true, returnObject.isOk()); -} - -/* - * Verify that subscribeScanResults method returns without errors - */ -TEST_P(WifiOffloadHidlTest, subscribeScanResults) { - const auto& result = HIDL_INVOKE(wifi_offload_, subscribeScanResults, 0); - ASSERT_EQ(OffloadStatusCode::OK, result.code); -} - -/* - * Verify that unsubscribeScanResults method returns without errors - */ -TEST_P(WifiOffloadHidlTest, unsubscribeScanResults) { - auto returnObject = wifi_offload_->unsubscribeScanResults(); - ASSERT_EQ(true, returnObject.isOk()); -} - -/* - * Verify that configureScans method returns without errors - */ -TEST_P(WifiOffloadHidlTest, configureScans) { - ScanParam* pScanParam = new ScanParam(); - std::vector<uint32_t> frequencyList = {kFrequency1, kFrequency2}; - pScanParam->disconnectedModeScanIntervalMs = - kDisconnectedModeScanIntervalMs; - pScanParam->frequencyList = frequencyList; - std::vector<Ssid> ssidList; - std::vector<std::vector<uint8_t>> ssids{kSsid1, kSsid2}; - for (const auto& ssid : ssids) { - Ssid tmp = ssid; - ssidList.push_back(tmp); - } - pScanParam->ssidList = ssidList; - ScanFilter* pScanFilter = new ScanFilter(); - pScanFilter->rssiThreshold = kRssiThreshold; - std::vector<std::vector<uint8_t>> match_ssids{kSsid1, kSsid2}; - std::vector<uint8_t> security_flags{kNetworkFlags, kNetworkFlags}; - std::vector<NetworkInfo> preferredNetworksList; - for (size_t i = 0; i < security_flags.size(); i++) { - NetworkInfo nwInfo; - nwInfo.ssid = match_ssids[i]; - nwInfo.flags = security_flags[i]; - preferredNetworksList.push_back(nwInfo); - } - const auto& result = - HIDL_INVOKE(wifi_offload_, configureScans, *pScanParam, *pScanFilter); - ASSERT_EQ(OffloadStatusCode::OK, result.code); -} - -/* - * Verify that getScanStats returns without any errors - */ -TEST_P(WifiOffloadHidlTest, getScanStats) { - const auto& result = HIDL_INVOKE(wifi_offload_, getScanStats); - OffloadStatus status = result.first; - ASSERT_EQ(OffloadStatusCode::OK, status.code); -} - -/* - * Verify that onScanResult callback is invoked - */ -TEST_P(WifiOffloadHidlTest, getScanResults) { - wifi_offload_->setEventCallback(wifi_offload_cb_); - std::vector<ScanResult> scan_results; - std::vector<uint8_t> ssid(kSsid1, kSsid1 + sizeof(kSsid1)); - ScanResult scan_result; - scan_result.tsf = kTsf; - scan_result.rssi = kRssi; - scan_result.frequency = kFrequency; - scan_result.capability = kCapability; - memcpy(&scan_result.bssid[0], &kBssid[0], kBssidSize); - scan_result.networkInfo.ssid = ssid; - scan_result.networkInfo.flags = kNetworkFlags; - scan_results.push_back(scan_result); - wifi_offload_cb_->onScanResult(scan_results); - auto res = - wifi_offload_cb_->WaitForCallback(kOffloadCallbackSendScanResult); - ASSERT_EQ(true, res.no_timeout); -} - -/* - * Verify that onError callback is invoked - */ -TEST_P(WifiOffloadHidlTest, getError) { - wifi_offload_->setEventCallback(wifi_offload_cb_); - OffloadStatus status = {OffloadStatusCode::ERROR, ""}; - wifi_offload_cb_->onError(status); - auto res = wifi_offload_cb_->WaitForCallback(kOffloadCallbackSendError); - ASSERT_EQ(true, res.no_timeout); -} - -GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiOffloadHidlTest); -INSTANTIATE_TEST_SUITE_P( - PerInstance, WifiOffloadHidlTest, - testing::ValuesIn( - android::hardware::getAllHalInstanceNames(IOffload::descriptor)), - android::hardware::PrintInstanceNameToString);
\ No newline at end of file diff --git a/wifi/offload/1.0/vts/functional/hidl_call_util.h b/wifi/offload/1.0/vts/functional/hidl_call_util.h deleted file mode 100644 index 99868e8b7d..0000000000 --- a/wifi/offload/1.0/vts/functional/hidl_call_util.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include <functional> -#include <tuple> -#include <type_traits> -#include <utility> - -namespace { -namespace detail { -template <typename> -struct functionArgSaver; - -// Provides a std::function that takes one argument, and a buffer -// wherein the function will store its argument. The buffer has -// the same type as the argument, but with const and reference -// modifiers removed. -template <typename ArgT> -struct functionArgSaver<std::function<void(ArgT)>> final { - using StorageT = typename std::remove_const< - typename std::remove_reference<ArgT>::type>::type; - - std::function<void(ArgT)> saveArgs = [this](ArgT arg) { - this->saved_values = arg; - }; - - StorageT saved_values; -}; - -// Provides a std::function that takes two arguments, and a buffer -// wherein the function will store its arguments. The buffer is a -// std::pair, whose elements have the same types as the arguments -// (but with const and reference modifiers removed). -template <typename Arg1T, typename Arg2T> -struct functionArgSaver<std::function<void(Arg1T, Arg2T)>> final { - using StorageT = - std::pair<typename std::remove_const< - typename std::remove_reference<Arg1T>::type>::type, - typename std::remove_const< - typename std::remove_reference<Arg2T>::type>::type>; - - std::function<void(Arg1T, Arg2T)> saveArgs = [this](Arg1T arg1, - Arg2T arg2) { - this->saved_values = {arg1, arg2}; - }; - - StorageT saved_values; -}; - -// Provides a std::function that takes three or more arguments, and a -// buffer wherein the function will store its arguments. The buffer is a -// std::tuple whose elements have the same types as the arguments (but -// with const and reference modifiers removed). -template <typename... ArgT> -struct functionArgSaver<std::function<void(ArgT...)>> final { - using StorageT = std::tuple<typename std::remove_const< - typename std::remove_reference<ArgT>::type>::type...>; - - std::function<void(ArgT...)> saveArgs = [this](ArgT... arg) { - this->saved_values = {arg...}; - }; - - StorageT saved_values; -}; - -// Invokes |method| on |object|, providing |method| a CallbackT as the -// final argument. Returns a copy of the parameters that |method| provided -// to CallbackT. (The parameters are returned by value.) -template <typename CallbackT, typename MethodT, typename ObjectT, - typename... ArgT> -typename functionArgSaver<CallbackT>::StorageT invokeMethod( - MethodT method, ObjectT object, ArgT&&... methodArg) { - functionArgSaver<CallbackT> result_buffer; - const auto& res = ((*object).*method)(std::forward<ArgT>(methodArg)..., - result_buffer.saveArgs); - EXPECT_TRUE(res.isOk()); - return result_buffer.saved_values; -} -} // namespace detail -} // namespace - -// Invokes |method| on |strong_pointer|, passing provided arguments through to -// |method|. -// -// Returns either: -// - A copy of the result callback parameter (for callbacks with a single -// parameter), OR -// - A pair containing a copy of the result callback parameters (for callbacks -// with two parameters), OR -// - A tuple containing a copy of the result callback paramters (for callbacks -// with three or more parameters). -// -// Example usage: -// EXPECT_EQ(WifiStatusCode::SUCCESS, -// HIDL_INVOKE(strong_pointer, methodReturningWifiStatus).code); -// EXPECT_EQ(WifiStatusCode::SUCCESS, -// HIDL_INVOKE(strong_pointer, methodReturningWifiStatusAndOneMore) -// .first.code); -// EXPECT_EQ(WifiStatusCode::SUCCESS, std::get<0>( -// HIDL_INVOKE(strong_pointer, methodReturningWifiStatusAndTwoMore)) -// .code); -#define HIDL_INVOKE(strong_pointer, method, ...) \ - (detail::invokeMethod< \ - std::remove_reference<decltype(*strong_pointer)>::type::method##_cb>( \ - &std::remove_reference<decltype(*strong_pointer)>::type::method, \ - strong_pointer, ##__VA_ARGS__)) diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_test_utils.h b/wifi/supplicant/aidl/vts/functional/supplicant_test_utils.h index 7eeab6870d..f2cb3f665c 100644 --- a/wifi/supplicant/aidl/vts/functional/supplicant_test_utils.h +++ b/wifi/supplicant/aidl/vts/functional/supplicant_test_utils.h @@ -64,9 +64,9 @@ void stopSupplicantService() { void initializeService() { if (SupplicantAidlTestUtils::useAidlService()) { - SupplicantAidlTestUtils::stopSupplicantService(); + SupplicantAidlTestUtils::initializeService(); } else { - SupplicantLegacyTestUtils::stopSupplicantService(); + SupplicantLegacyTestUtils::initializeService(); } } |