Merge "Update TV Input HAL documentation for device IDs" into udc-dev
diff --git a/audio/aidl/default/EffectConfig.cpp b/audio/aidl/default/EffectConfig.cpp
index 5a83fef..71d111b 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 @@
// 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 @@
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 @@
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 f0687cc..7073a10 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 @@
}
}
+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 @@
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::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 c06742d..6627ae7 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/include/effectFactory-impl/EffectConfig.h b/audio/aidl/default/include/effectFactory-impl/EffectConfig.h
index c627a27..f8a86e1 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 @@
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 @@
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 @@
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 @@
*/
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 @@
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 b7f63af..ad59ca7 100644
--- a/audio/aidl/default/include/effectFactory-impl/EffectFactory.h
+++ b/audio/aidl/default/include/effectFactory-impl/EffectFactory.h
@@ -107,6 +107,10 @@
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/vts/VtsHalAudioEffectFactoryTargetTest.cpp b/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp
index 7b9477d..9cd6c22 100644
--- a/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp
@@ -267,6 +267,7 @@
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 @@
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/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp b/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp
index dbe8150..5081ac0 100644
--- a/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp
+++ b/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp
@@ -65,8 +65,7 @@
constexpr char COMMAND_INJECT_TASK_NEXT_REBOOT[] = "--inject-task-next-reboot";
constexpr char COMMAND_STATUS[] = "--status";
-constexpr char DEBUG_TASK_FOLDER[] = "/data/local/tests";
-constexpr char DEBUG_TASK_FILE[] = "/data/local/tests/debugTask";
+constexpr char DEBUG_TASK_FILE[] = "/data/vendor/remoteaccess/debugTask";
std::vector<uint8_t> stringToBytes(std::string_view s) {
const char* data = s.data();
diff --git a/bluetooth/aidl/TEST_MAPPING b/bluetooth/aidl/TEST_MAPPING
index d1de251..41a508e 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/vts/VtsHalBluetoothTargetTest.cpp b/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp
index 529e092..e5222a7 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::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 @@
// 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 @@
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 @@
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/keymaster/4.0/vts/functional/Android.bp b/keymaster/4.0/vts/functional/Android.bp
index f9a02ba..e1dfcfc 100644
--- a/keymaster/4.0/vts/functional/Android.bp
+++ b/keymaster/4.0/vts/functional/Android.bp
@@ -30,13 +30,17 @@
"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 @@
],
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 0000000..6b5e8bf
--- /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 315a4bd..e2ad0ef 100644
--- a/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp
+++ b/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp
@@ -841,6 +841,30 @@
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 ad30aa7..67829ec 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 @@
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 728cc91..b709904 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 @@
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 @@
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/security/keymint/aidl/vts/functional/Android.bp b/security/keymint/aidl/vts/functional/Android.bp
index 7a4359d..41b161d 100644
--- a/security/keymint/aidl/vts/functional/Android.bp
+++ b/security/keymint/aidl/vts/functional/Android.bp
@@ -43,8 +43,11 @@
"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 e759123..c035f19 100644
--- a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
+++ b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
@@ -88,96 +88,9 @@
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";
- }
- }
};
/*
diff --git a/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp b/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp
index 723edee..54f187c 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 @@
// 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());
+TEST_P(BootloaderStateTest, BootloaderIsUnlocked) {
+ ASSERT_FALSE(attestedBootloaderState_)
+ << "This test runs as root. Bootloader must be unlocked.";
+}
- vector<Certificate> key_cert_chain = std::move(creationResult.certificateChain);
+// 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\".";
- // 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());
+ // 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\".";
+}
- ASN1_OCTET_STRING* attest_rec = get_attestation_record(cert.get());
- ASSERT_TRUE(attest_rec);
+// 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;
+ }
+}
- 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.";
+// 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 5e27bd0..a8ea407 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -322,12 +322,13 @@
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 @@
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 3245ca9..30ac452 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
@@ -54,6 +54,9 @@
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 @@
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/wifi/offload/1.0/Android.bp b/wifi/offload/1.0/Android.bp
deleted file mode 100644
index 8fd602d..0000000
--- 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 4819519..0000000
--- 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 4888125..0000000
--- 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 234f3fc..0000000
--- 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 a0eb048..0000000
--- 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 ffd5149..0000000
--- 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 99868e8..0000000
--- 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__))