Merge "Change AP_POWER_STATE_REPORT's access property."
diff --git a/confirmationui/1.0/vts/functional/Android.bp b/confirmationui/1.0/vts/functional/Android.bp
index d19d702..fd088cd 100644
--- a/confirmationui/1.0/vts/functional/Android.bp
+++ b/confirmationui/1.0/vts/functional/Android.bp
@@ -23,7 +23,7 @@
static_libs: [
"android.hardware.confirmationui@1.0",
"android.hardware.keymaster@4.0",
- "libcrypto",
+ "libcrypto_static",
"libcn-cbor",
"android.hardware.confirmationui-support-lib",
],
diff --git a/current.txt b/current.txt
index 3fabd7c..6f9f4d4 100644
--- a/current.txt
+++ b/current.txt
@@ -576,5 +576,6 @@
eb2fa0c883c2185d514be0b84c179b283753ef0c1b77b45b4f359bd23bba8b75 android.hardware.neuralnetworks@1.0::IPreparedModel
fb382e986c10b8fbb797a8546e8f9ea6d1107bfe6f3fb7e57f6bbbf1f807a906 android.hardware.neuralnetworks@1.2::IDevice
40e71cd693de5b832325c5d8f081f2ff20a7ba2b89d401cee5b4b3eb0e241681 android.hardware.neuralnetworks@1.2::IPreparedModel
+a785a57447a81e9c130eef6904c3a5c256076c6a04588c40620ebd6fa2660d77 android.hardware.radio@1.2::types
1a6e2bd289f22931c526b21916910f1d4c436b7acb9556e4243de4ce8e6cc2e4 android.hardware.soundtrigger@2.0::ISoundTriggerHwCallback
fd65298e1e09e0e3c781ab18305920d757dbe55a3b459ce17814ec5cf6dfee99 android.hardware.wifi@1.0::IWifiP2pIface
diff --git a/drm/1.0/vts/functional/Android.bp b/drm/1.0/vts/functional/Android.bp
index d6ebfdd..61d4d58 100644
--- a/drm/1.0/vts/functional/Android.bp
+++ b/drm/1.0/vts/functional/Android.bp
@@ -30,7 +30,7 @@
"libhidlmemory",
"libnativehelper",
"libssl",
- "libcrypto",
+ "libcrypto_static",
],
test_suites: ["general-tests"],
}
diff --git a/drm/1.2/vts/functional/Android.bp b/drm/1.2/vts/functional/Android.bp
index 6b4a4c0..95883bf 100644
--- a/drm/1.2/vts/functional/Android.bp
+++ b/drm/1.2/vts/functional/Android.bp
@@ -34,7 +34,7 @@
"libhidlmemory",
"libnativehelper",
"libssl",
- "libcrypto",
+ "libcrypto_static",
],
test_suites: ["general-tests"],
}
diff --git a/graphics/mapper/2.0/utils/passthrough/include/mapper-passthrough/2.0/Gralloc1Hal.h b/graphics/mapper/2.0/utils/passthrough/include/mapper-passthrough/2.0/Gralloc1Hal.h
index d9beb4f..db7e67d 100644
--- a/graphics/mapper/2.0/utils/passthrough/include/mapper-passthrough/2.0/Gralloc1Hal.h
+++ b/graphics/mapper/2.0/utils/passthrough/include/mapper-passthrough/2.0/Gralloc1Hal.h
@@ -282,14 +282,16 @@
}
if (flex.planes[0].component != FLEX_COMPONENT_Y ||
- flex.planes[1].component != FLEX_COMPONENT_Cb ||
- flex.planes[2].component != FLEX_COMPONENT_Cr) {
+ ((flex.planes[1].component != FLEX_COMPONENT_Cb || flex.planes[2].component != FLEX_COMPONENT_Cr) &&
+ (flex.planes[2].component != FLEX_COMPONENT_Cb || flex.planes[1].component != FLEX_COMPONENT_Cr))) {
return false;
}
const auto& y = flex.planes[0];
- const auto& cb = flex.planes[1];
- const auto& cr = flex.planes[2];
+ const auto& cb = (flex.planes[1].component == FLEX_COMPONENT_Cb)?
+ flex.planes[1] : flex.planes[2];
+ const auto& cr = (flex.planes[2].component == FLEX_COMPONENT_Cr)?
+ flex.planes[2] : flex.planes[1];
if (cb.h_increment != cr.h_increment || cb.v_increment != cr.v_increment) {
return false;
diff --git a/keymaster/3.0/vts/functional/Android.bp b/keymaster/3.0/vts/functional/Android.bp
index b0371c7..69aa56d 100644
--- a/keymaster/3.0/vts/functional/Android.bp
+++ b/keymaster/3.0/vts/functional/Android.bp
@@ -26,7 +26,7 @@
],
static_libs: [
"android.hardware.keymaster@3.0",
- "libcrypto",
+ "libcrypto_static",
"libsoftkeymasterdevice",
],
test_suites: ["general-tests"],
diff --git a/keymaster/4.0/vts/functional/Android.bp b/keymaster/4.0/vts/functional/Android.bp
index 333e408..0401362 100644
--- a/keymaster/4.0/vts/functional/Android.bp
+++ b/keymaster/4.0/vts/functional/Android.bp
@@ -25,7 +25,7 @@
],
static_libs: [
"android.hardware.keymaster@4.0",
- "libcrypto",
+ "libcrypto_static",
"libkeymaster4support",
"libsoftkeymasterdevice",
],
diff --git a/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp b/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp
index 3af1df3..4838e7e 100644
--- a/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp
+++ b/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp
@@ -48,10 +48,11 @@
SecurityLevel KeymasterHidlTest::securityLevel_;
hidl_string KeymasterHidlTest::name_;
hidl_string KeymasterHidlTest::author_;
+string KeymasterHidlTest::service_name_;
-void KeymasterHidlTest::SetUpTestCase() {
- string service_name = KeymasterHidlEnvironment::Instance()->getServiceName<IKeymasterDevice>();
- keymaster_ = ::testing::VtsHalHidlTargetTestBase::getService<IKeymasterDevice>(service_name);
+void KeymasterHidlTest::InitializeKeymaster() {
+ service_name_ = KeymasterHidlEnvironment::Instance()->getServiceName<IKeymasterDevice>();
+ keymaster_ = ::testing::VtsHalHidlTargetTestBase::getService<IKeymasterDevice>(service_name_);
ASSERT_NE(keymaster_, nullptr);
ASSERT_TRUE(keymaster_
@@ -62,18 +63,22 @@
author_ = author;
})
.isOk());
+}
+
+void KeymasterHidlTest::SetUpTestCase() {
+
+ InitializeKeymaster();
os_version_ = ::keymaster::GetOsVersion();
os_patch_level_ = ::keymaster::GetOsPatchlevel();
auto service_manager = android::hidl::manager::V1_0::IServiceManager::getService();
ASSERT_NE(nullptr, service_manager.get());
-
all_keymasters_.push_back(keymaster_);
service_manager->listByInterface(
IKeymasterDevice::descriptor, [&](const hidl_vec<hidl_string>& names) {
for (auto& name : names) {
- if (name == service_name) continue;
+ if (name == service_name_) continue;
auto keymaster =
::testing::VtsHalHidlTargetTestBase::getService<IKeymasterDevice>(name);
ASSERT_NE(keymaster, nullptr);
@@ -269,6 +274,13 @@
return GetCharacteristics(key_blob, client_id, app_data, key_characteristics);
}
+ErrorCode KeymasterHidlTest::GetDebugInfo(DebugInfo* debug_info) {
+ EXPECT_TRUE(keymaster_->getDebugInfo([&](const DebugInfo& hidl_debug_info) {
+ *debug_info = hidl_debug_info;
+ }).isOk());
+ return ErrorCode::OK;
+}
+
ErrorCode KeymasterHidlTest::Begin(KeyPurpose purpose, const HidlBuf& key_blob,
const AuthorizationSet& in_params, AuthorizationSet* out_params,
OperationHandle* op_handle) {
@@ -611,6 +623,20 @@
return ciphertext;
}
+string KeymasterHidlTest::EncryptMessage(const string& message, BlockMode block_mode,
+ PaddingMode padding, uint8_t mac_length_bits,
+ const HidlBuf& iv_in) {
+ SCOPED_TRACE("EncryptMessage");
+ auto params = AuthorizationSetBuilder()
+ .BlockMode(block_mode)
+ .Padding(padding)
+ .Authorization(TAG_MAC_LENGTH, mac_length_bits)
+ .Authorization(TAG_NONCE, iv_in);
+ AuthorizationSet out_params;
+ string ciphertext = EncryptMessage(message, params, &out_params);
+ return ciphertext;
+}
+
string KeymasterHidlTest::DecryptMessage(const HidlBuf& key_blob, const string& ciphertext,
const AuthorizationSet& params) {
SCOPED_TRACE("DecryptMessage");
diff --git a/keymaster/4.0/vts/functional/KeymasterHidlTest.h b/keymaster/4.0/vts/functional/KeymasterHidlTest.h
index 015fc43..b09da45 100644
--- a/keymaster/4.0/vts/functional/KeymasterHidlTest.h
+++ b/keymaster/4.0/vts/functional/KeymasterHidlTest.h
@@ -37,6 +37,7 @@
using ::android::sp;
using ::std::string;
+using hidl::base::V1_0::DebugInfo;
class HidlBuf : public hidl_vec<uint8_t> {
typedef hidl_vec<uint8_t> super;
@@ -95,6 +96,7 @@
// SetUpTestCase runs only once per test case, not once per test.
static void SetUpTestCase();
+ static void InitializeKeymaster();
static void TearDownTestCase() {
keymaster_.clear();
all_keymasters_.clear();
@@ -140,6 +142,8 @@
const HidlBuf& app_data, KeyCharacteristics* key_characteristics);
ErrorCode GetCharacteristics(const HidlBuf& key_blob, KeyCharacteristics* key_characteristics);
+ ErrorCode GetDebugInfo(DebugInfo* debug_info);
+
ErrorCode Begin(KeyPurpose purpose, const HidlBuf& key_blob, const AuthorizationSet& in_params,
AuthorizationSet* out_params, OperationHandle* op_handle);
ErrorCode Begin(KeyPurpose purpose, const AuthorizationSet& in_params,
@@ -201,6 +205,8 @@
HidlBuf* iv_out);
string EncryptMessage(const string& message, BlockMode block_mode, PaddingMode padding,
const HidlBuf& iv_in);
+ string EncryptMessage(const string& message, BlockMode block_mode, PaddingMode padding,
+ uint8_t mac_length_bits, const HidlBuf& iv_in);
string DecryptMessage(const HidlBuf& key_blob, const string& ciphertext,
const AuthorizationSet& params);
@@ -235,6 +241,7 @@
static SecurityLevel securityLevel_;
static hidl_string name_;
static hidl_string author_;
+ static string service_name_;
};
} // namespace test
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 9e6cce7..0ac7e48 100644
--- a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
+++ b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
@@ -18,6 +18,7 @@
#include <cutils/log.h>
#include <iostream>
+#include <signal.h>
#include <openssl/evp.h>
#include <openssl/mem.h>
@@ -2706,6 +2707,40 @@
}
/*
+ * EncryptionOperationsTest.AesWrongPurpose
+ *
+ * Verifies that AES encryption fails in the correct way when an unauthorized purpose is specified.
+ */
+TEST_F(EncryptionOperationsTest, AesWrongPurpose) {
+ auto err = GenerateKey(AuthorizationSetBuilder()
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .AesKey(128)
+ .Authorization(TAG_PURPOSE, KeyPurpose::ENCRYPT)
+ .Authorization(TAG_BLOCK_MODE, BlockMode::GCM)
+ .Authorization(TAG_MIN_MAC_LENGTH, 128)
+ .Padding(PaddingMode::NONE));
+ ASSERT_EQ(ErrorCode::OK, err) << "Got " << err;
+
+ err = Begin(KeyPurpose::DECRYPT,
+ AuthorizationSetBuilder().BlockMode(BlockMode::GCM).Padding(PaddingMode::NONE));
+ EXPECT_EQ(ErrorCode::INCOMPATIBLE_PURPOSE, err) << "Got " << err;
+
+ CheckedDeleteKey();
+
+ ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .AesKey(128)
+ .Authorization(TAG_PURPOSE, KeyPurpose::DECRYPT)
+ .Authorization(TAG_BLOCK_MODE, BlockMode::GCM)
+ .Authorization(TAG_MIN_MAC_LENGTH, 128)
+ .Padding(PaddingMode::NONE)));
+
+ err = Begin(KeyPurpose::ENCRYPT,
+ AuthorizationSetBuilder().BlockMode(BlockMode::GCM).Padding(PaddingMode::NONE));
+ EXPECT_EQ(ErrorCode::INCOMPATIBLE_PURPOSE, err) << "Got " << err;
+}
+
+/*
* EncryptionOperationsTest.AesEcbNoPaddingWrongInputSize
*
* Verifies that AES encryption fails in the correct way when provided an input that is not a
@@ -3225,6 +3260,92 @@
}
/*
+ * EncryptionOperationsTest.AesGcmRoundTripWithDelaySuccess
+ *
+ * Verifies that AES GCM mode works, even when there's a long delay
+ * between operations.
+ */
+TEST_F(EncryptionOperationsTest, AesGcmRoundTripWithDelaySuccess) {
+ ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .AesEncryptionKey(128)
+ .Authorization(TAG_BLOCK_MODE, BlockMode::GCM)
+ .Padding(PaddingMode::NONE)
+ .Authorization(TAG_MIN_MAC_LENGTH, 128)));
+
+ string aad = "foobar";
+ string message = "123456789012345678901234567890123456";
+
+ auto begin_params = AuthorizationSetBuilder()
+ .BlockMode(BlockMode::GCM)
+ .Padding(PaddingMode::NONE)
+ .Authorization(TAG_MAC_LENGTH, 128);
+
+ auto update_params =
+ AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA, aad.data(), aad.size());
+
+ // Encrypt
+ AuthorizationSet begin_out_params;
+ ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &begin_out_params))
+ << "Begin encrypt";
+ string ciphertext;
+ AuthorizationSet update_out_params;
+ sleep(5);
+ ASSERT_EQ(ErrorCode::OK,
+ Finish(op_handle_, update_params, message, "", &update_out_params, &ciphertext));
+
+ ASSERT_EQ(ciphertext.length(), message.length() + 16);
+
+ // Grab nonce
+ begin_params.push_back(begin_out_params);
+
+ // Decrypt.
+ ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params)) << "Begin decrypt";
+ string plaintext;
+ size_t input_consumed;
+ sleep(5);
+ ASSERT_EQ(ErrorCode::OK, Update(op_handle_, update_params, ciphertext, &update_out_params,
+ &plaintext, &input_consumed));
+ EXPECT_EQ(ciphertext.size(), input_consumed);
+ sleep(5);
+ EXPECT_EQ(ErrorCode::OK, Finish("", &plaintext));
+ EXPECT_EQ(message.length(), plaintext.length());
+ EXPECT_EQ(message, plaintext);
+}
+
+/*
+ * EncryptionOperationsTest.AesGcmDifferentNonces
+ *
+ * Verifies that encrypting the same data with different nonces produces different outputs.
+ */
+TEST_F(EncryptionOperationsTest, AesGcmDifferentNonces) {
+ ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .AesEncryptionKey(128)
+ .Authorization(TAG_BLOCK_MODE, BlockMode::GCM)
+ .Padding(PaddingMode::NONE)
+ .Authorization(TAG_MIN_MAC_LENGTH, 128)
+ .Authorization(TAG_CALLER_NONCE)));
+
+ string aad = "foobar";
+ string message = "123456789012345678901234567890123456";
+ string nonce1 = "000000000000";
+ string nonce2 = "111111111111";
+ string nonce3 = "222222222222";
+
+ string ciphertext1 =
+ EncryptMessage(message, BlockMode::GCM, PaddingMode::NONE, 128, HidlBuf(nonce1));
+ string ciphertext2 =
+ EncryptMessage(message, BlockMode::GCM, PaddingMode::NONE, 128, HidlBuf(nonce2));
+ string ciphertext3 =
+ EncryptMessage(message, BlockMode::GCM, PaddingMode::NONE, 128, HidlBuf(nonce3));
+
+ ASSERT_NE(ciphertext1, ciphertext2);
+ ASSERT_NE(ciphertext1, ciphertext3);
+ ASSERT_NE(ciphertext2, ciphertext3);
+}
+
+/*
* EncryptionOperationsTest.AesGcmTooShortTag
*
* Verifies that AES GCM mode fails correctly when a too-short tag length is specified.
@@ -4456,6 +4577,84 @@
EXPECT_EQ(result, std::make_pair(ErrorCode::OK, HidlBuf()));
}
+
+using ClearOperationsTest = KeymasterHidlTest;
+
+/*
+ * ClearSlotsTest.TooManyOperations
+ *
+ * Verifies that TOO_MANY_OPERATIONS is returned after the max number of
+ * operations are started without being finished or aborted. Also verifies
+ * that aborting the operations clears the operations.
+ *
+ */
+TEST_F(ClearOperationsTest, TooManyOperations) {
+ ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .RsaEncryptionKey(2048, 65537)
+ .Padding(PaddingMode::NONE)));
+
+ auto params = AuthorizationSetBuilder().Padding(PaddingMode::NONE);
+ int max_operations = SecLevel() == SecurityLevel::STRONGBOX ? 4 : 16;
+ OperationHandle op_handles[max_operations];
+ AuthorizationSet out_params;
+ for(int i=0; i<max_operations; i++) {
+ EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, key_blob_, params, &out_params, &(op_handles[i])));
+ }
+ EXPECT_EQ(ErrorCode::TOO_MANY_OPERATIONS,
+ Begin(KeyPurpose::ENCRYPT, key_blob_, params, &out_params, &op_handle_));
+ // Try again just in case there's a weird overflow bug
+ EXPECT_EQ(ErrorCode::TOO_MANY_OPERATIONS,
+ Begin(KeyPurpose::ENCRYPT, key_blob_, params, &out_params, &op_handle_));
+ for(int i=0; i<max_operations; i++) {
+ EXPECT_EQ(ErrorCode::OK, Abort(op_handles[i]));
+ }
+ EXPECT_EQ(ErrorCode::OK,
+ Begin(KeyPurpose::ENCRYPT, key_blob_, params, &out_params, &op_handle_));
+ AbortIfNeeded();
+}
+
+/*
+ * ClearSlotsTest.ServiceDeath
+ *
+ * Verifies that the service is restarted after death and the ongoing
+ * operations are cleared.
+ */
+TEST_F(ClearOperationsTest, ServiceDeath) {
+
+ ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .RsaEncryptionKey(2048, 65537)
+ .Padding(PaddingMode::NONE)));
+
+ auto params = AuthorizationSetBuilder().Padding(PaddingMode::NONE);
+ int max_operations = SecLevel() == SecurityLevel::STRONGBOX ? 4 : 16;
+ OperationHandle op_handles[max_operations];
+ AuthorizationSet out_params;
+ for(int i=0; i<max_operations; i++) {
+ EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, key_blob_, params, &out_params, &(op_handles[i])));
+ }
+ EXPECT_EQ(ErrorCode::TOO_MANY_OPERATIONS,
+ Begin(KeyPurpose::ENCRYPT, key_blob_, params, &out_params, &op_handle_));
+
+ DebugInfo debug_info;
+ GetDebugInfo(&debug_info);
+ kill(debug_info.pid, SIGKILL);
+ // wait 1 second for keymaster to restart
+ sleep(1);
+ InitializeKeymaster();
+
+ for(int i=0; i<max_operations; i++) {
+ EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, key_blob_, params, &out_params, &(op_handles[i])));
+ }
+ EXPECT_EQ(ErrorCode::TOO_MANY_OPERATIONS,
+ Begin(KeyPurpose::ENCRYPT, key_blob_, params, &out_params, &op_handle_));
+ for(int i=0; i<max_operations; i++) {
+ EXPECT_EQ(ErrorCode::OK, Abort(op_handles[i]));
+ }
+}
+
+
} // namespace test
} // namespace V4_0
} // namespace keymaster
diff --git a/neuralnetworks/1.0/vts/functional/Android.bp b/neuralnetworks/1.0/vts/functional/Android.bp
index 0af7f79..3e9d5f7 100644
--- a/neuralnetworks/1.0/vts/functional/Android.bp
+++ b/neuralnetworks/1.0/vts/functional/Android.bp
@@ -40,10 +40,11 @@
],
}
-cc_defaults {
- name: "VtsHalNeuralNetworksV1_0TargetTestDefaults",
+cc_test {
+ name: "VtsHalNeuralnetworksV1_0TargetTest",
defaults: ["VtsHalTargetTestDefaults"],
srcs: [
+ "BasicTests.cpp",
"TestAssertions.cpp",
"ValidateModel.cpp",
"ValidateRequest.cpp",
@@ -64,33 +65,11 @@
"libneuralnetworks_utils",
"VtsHalNeuralNetworksV1_0_utils",
],
+ whole_static_libs: [
+ "neuralnetworks_generated_V1_0_example",
+ ],
header_libs: [
"libneuralnetworks_headers",
],
test_suites: ["general-tests"],
}
-
-cc_test {
- name: "VtsHalNeuralnetworksV1_0TargetTest",
- defaults: ["VtsHalNeuralNetworksV1_0TargetTestDefaults"],
- srcs: [
- "BasicTests.cpp",
- ],
- whole_static_libs: [
- "neuralnetworks_generated_V1_0_example",
- ],
-}
-
-cc_test {
- name: "PresubmitHalNeuralnetworksV1_0TargetTest",
- defaults: ["VtsHalNeuralNetworksV1_0TargetTestDefaults"],
- srcs: [
- "BasicTests.cpp",
- ],
- whole_static_libs: [
- "neuralnetworks_generated_V1_0_example",
- ],
- cflags: [
- "-DPRESUBMIT_NOT_VTS",
- ],
-}
diff --git a/neuralnetworks/1.0/vts/functional/BasicTests.cpp b/neuralnetworks/1.0/vts/functional/BasicTests.cpp
index 551ea67..cc44c9e 100644
--- a/neuralnetworks/1.0/vts/functional/BasicTests.cpp
+++ b/neuralnetworks/1.0/vts/functional/BasicTests.cpp
@@ -21,17 +21,17 @@
namespace android::hardware::neuralnetworks::V1_0::vts::functional {
// create device test
-TEST_F(NeuralnetworksHidlTest, CreateDevice) {}
+TEST_P(NeuralnetworksHidlTest, CreateDevice) {}
// status test
-TEST_F(NeuralnetworksHidlTest, StatusTest) {
+TEST_P(NeuralnetworksHidlTest, StatusTest) {
Return<DeviceStatus> status = kDevice->getStatus();
ASSERT_TRUE(status.isOk());
EXPECT_EQ(DeviceStatus::AVAILABLE, static_cast<DeviceStatus>(status));
}
// initialization
-TEST_F(NeuralnetworksHidlTest, GetCapabilitiesTest) {
+TEST_P(NeuralnetworksHidlTest, GetCapabilitiesTest) {
Return<void> ret =
kDevice->getCapabilities([](ErrorStatus status, const Capabilities& capabilities) {
EXPECT_EQ(ErrorStatus::NONE, status);
diff --git a/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
index 1948c05..595ad85 100644
--- a/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
+++ b/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
@@ -148,6 +148,20 @@
checkResults(testModel, outputs);
}
+void GeneratedTestBase::SetUp() {
+ testing::TestWithParam<GeneratedTestParam>::SetUp();
+ ASSERT_NE(kDevice, nullptr);
+}
+
+std::vector<NamedModel> getNamedModels(const FilterFn& filter) {
+ return TestModelManager::get().getTestModels(filter);
+}
+
+std::string printGeneratedTest(const testing::TestParamInfo<GeneratedTestParam>& info) {
+ const auto& [namedDevice, namedModel] = info.param;
+ return gtestCompliantName(getName(namedDevice) + "_" + getName(namedModel));
+}
+
// Tag for the generated tests
class GeneratedTest : public GeneratedTestBase {};
diff --git a/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.h b/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.h
index 10e46b7..f230a02 100644
--- a/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.h
+++ b/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.h
@@ -18,29 +18,38 @@
#define ANDROID_HARDWARE_NEURALNETWORKS_V1_0_GENERATED_TEST_HARNESS_H
#include <android/hardware/neuralnetworks/1.0/IDevice.h>
+#include <functional>
#include "TestHarness.h"
#include "VtsHalNeuralnetworks.h"
namespace android::hardware::neuralnetworks::V1_0::vts::functional {
-class GeneratedTestBase
- : public NeuralnetworksHidlTest,
- public testing::WithParamInterface<test_helper::TestModelManager::TestParam> {
+using NamedModel = Named<const test_helper::TestModel*>;
+using GeneratedTestParam = std::tuple<NamedDevice, NamedModel>;
+
+class GeneratedTestBase : public testing::TestWithParam<GeneratedTestParam> {
protected:
- const test_helper::TestModel& kTestModel = *GetParam().second;
+ void SetUp() override;
+ const sp<IDevice> kDevice = getData(std::get<NamedDevice>(GetParam()));
+ const test_helper::TestModel& kTestModel = *getData(std::get<NamedModel>(GetParam()));
};
-#define INSTANTIATE_GENERATED_TEST(TestSuite, filter) \
- INSTANTIATE_TEST_SUITE_P( \
- TestGenerated, TestSuite, \
- testing::ValuesIn(::test_helper::TestModelManager::get().getTestModels(filter)), \
- [](const auto& info) { return info.param.first; })
+using FilterFn = std::function<bool(const test_helper::TestModel&)>;
+std::vector<NamedModel> getNamedModels(const FilterFn& filter);
+
+std::string printGeneratedTest(const testing::TestParamInfo<GeneratedTestParam>& info);
+
+#define INSTANTIATE_GENERATED_TEST(TestSuite, filter) \
+ INSTANTIATE_TEST_SUITE_P(TestGenerated, TestSuite, \
+ testing::Combine(testing::ValuesIn(getNamedDevices()), \
+ testing::ValuesIn(getNamedModels(filter))), \
+ printGeneratedTest)
// Tag for the validation tests, instantiated in VtsHalNeuralnetworks.cpp.
// TODO: Clean up the hierarchy for ValidationTest.
class ValidationTest : public GeneratedTestBase {};
-Model createModel(const ::test_helper::TestModel& testModel);
+Model createModel(const test_helper::TestModel& testModel);
} // namespace android::hardware::neuralnetworks::V1_0::vts::functional
diff --git a/neuralnetworks/1.0/vts/functional/Utils.cpp b/neuralnetworks/1.0/vts/functional/Utils.cpp
index 307003c..5b630fd 100644
--- a/neuralnetworks/1.0/vts/functional/Utils.cpp
+++ b/neuralnetworks/1.0/vts/functional/Utils.cpp
@@ -117,6 +117,13 @@
return outputBuffers;
}
+std::string gtestCompliantName(std::string name) {
+ // gtest test names must only contain alphanumeric characters
+ std::replace_if(
+ name.begin(), name.end(), [](char c) { return !std::isalnum(c); }, '_');
+ return name;
+}
+
} // namespace android::hardware::neuralnetworks
namespace android::hardware::neuralnetworks::V1_0 {
diff --git a/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworks.cpp b/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworks.cpp
index 20b4565..cb22250 100644
--- a/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworks.cpp
+++ b/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworks.cpp
@@ -18,11 +18,13 @@
#include "VtsHalNeuralnetworks.h"
#include "1.0/Callbacks.h"
-#include "1.0/Utils.h"
#include "GeneratedTestHarness.h"
#include "TestHarness.h"
#include <android-base/logging.h>
+#include <hidl/ServiceManagement.h>
+#include <string>
+#include <utility>
namespace android::hardware::neuralnetworks::V1_0::vts::functional {
@@ -76,34 +78,39 @@
ASSERT_NE(nullptr, preparedModel->get());
}
-// A class for test environment setup
-NeuralnetworksHidlEnvironment* NeuralnetworksHidlEnvironment::getInstance() {
- // This has to return a "new" object because it is freed inside
- // testing::AddGlobalTestEnvironment when the gtest is being torn down
- static NeuralnetworksHidlEnvironment* instance = new NeuralnetworksHidlEnvironment();
- return instance;
-}
-
-void NeuralnetworksHidlEnvironment::registerTestServices() {
- registerTestService<IDevice>();
-}
-
-// The main test class for NEURALNETWORK HIDL HAL.
void NeuralnetworksHidlTest::SetUp() {
- testing::VtsHalHidlTargetTestBase::SetUp();
-
-#ifdef PRESUBMIT_NOT_VTS
- const std::string name =
- NeuralnetworksHidlEnvironment::getInstance()->getServiceName<IDevice>();
- const std::string sampleDriver = "sample-";
- if (kDevice == nullptr && name.substr(0, sampleDriver.size()) == sampleDriver) {
- GTEST_SKIP();
- }
-#endif // PRESUBMIT_NOT_VTS
-
- ASSERT_NE(nullptr, kDevice.get());
+ testing::TestWithParam<NeuralnetworksHidlTestParam>::SetUp();
+ ASSERT_NE(kDevice, nullptr);
}
+static NamedDevice makeNamedDevice(const std::string& name) {
+ return {name, IDevice::getService(name)};
+}
+
+static std::vector<NamedDevice> getNamedDevicesImpl() {
+ // Retrieves the name of all service instances that implement IDevice,
+ // including any Lazy HAL instances.
+ const std::vector<std::string> names = hardware::getAllHalInstanceNames(IDevice::descriptor);
+
+ // Get a handle to each device and pair it with its name.
+ std::vector<NamedDevice> namedDevices;
+ namedDevices.reserve(names.size());
+ std::transform(names.begin(), names.end(), std::back_inserter(namedDevices), makeNamedDevice);
+ return namedDevices;
+}
+
+const std::vector<NamedDevice>& getNamedDevices() {
+ const static std::vector<NamedDevice> devices = getNamedDevicesImpl();
+ return devices;
+}
+
+std::string printNeuralnetworksHidlTest(
+ const testing::TestParamInfo<NeuralnetworksHidlTestParam>& info) {
+ return gtestCompliantName(getName(info.param));
+}
+
+INSTANTIATE_DEVICE_TEST(NeuralnetworksHidlTest);
+
// Forward declaration from ValidateModel.cpp
void validateModel(const sp<IDevice>& device, const Model& model);
// Forward declaration from ValidateRequest.cpp
@@ -130,14 +137,3 @@
INSTANTIATE_GENERATED_TEST(ValidationTest, [](const test_helper::TestModel&) { return true; });
} // namespace android::hardware::neuralnetworks::V1_0::vts::functional
-
-using android::hardware::neuralnetworks::V1_0::vts::functional::NeuralnetworksHidlEnvironment;
-
-int main(int argc, char** argv) {
- testing::AddGlobalTestEnvironment(NeuralnetworksHidlEnvironment::getInstance());
- testing::InitGoogleTest(&argc, argv);
- NeuralnetworksHidlEnvironment::getInstance()->init(&argc, argv);
-
- int status = RUN_ALL_TESTS();
- return status;
-}
diff --git a/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworks.h b/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworks.h
index 48dc237..17f4613 100644
--- a/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworks.h
+++ b/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworks.h
@@ -17,40 +17,34 @@
#ifndef ANDROID_HARDWARE_NEURALNETWORKS_V1_0_VTS_HAL_NEURALNETWORKS_H
#define ANDROID_HARDWARE_NEURALNETWORKS_V1_0_VTS_HAL_NEURALNETWORKS_H
+#include "1.0/Utils.h"
+
#include <android/hardware/neuralnetworks/1.0/IDevice.h>
#include <android/hardware/neuralnetworks/1.0/types.h>
-
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
-
-#include <android-base/macros.h>
#include <gtest/gtest.h>
+#include <vector>
+
namespace android::hardware::neuralnetworks::V1_0::vts::functional {
-// A class for test environment setup
-class NeuralnetworksHidlEnvironment : public testing::VtsHalHidlTargetTestEnvBase {
- DISALLOW_COPY_AND_ASSIGN(NeuralnetworksHidlEnvironment);
- NeuralnetworksHidlEnvironment() = default;
+using NamedDevice = Named<sp<IDevice>>;
+using NeuralnetworksHidlTestParam = NamedDevice;
- public:
- static NeuralnetworksHidlEnvironment* getInstance();
- void registerTestServices() override;
-};
-
-// The main test class for NEURALNETWORKS HIDL HAL.
-class NeuralnetworksHidlTest : public testing::VtsHalHidlTargetTestBase {
- DISALLOW_COPY_AND_ASSIGN(NeuralnetworksHidlTest);
-
- public:
- NeuralnetworksHidlTest() = default;
- void SetUp() override;
-
+class NeuralnetworksHidlTest : public testing::TestWithParam<NeuralnetworksHidlTestParam> {
protected:
- const sp<IDevice> kDevice = testing::VtsHalHidlTargetTestBase::getService<IDevice>(
- NeuralnetworksHidlEnvironment::getInstance());
+ void SetUp() override;
+ const sp<IDevice> kDevice = getData(GetParam());
};
+const std::vector<NamedDevice>& getNamedDevices();
+
+std::string printNeuralnetworksHidlTest(
+ const testing::TestParamInfo<NeuralnetworksHidlTestParam>& info);
+
+#define INSTANTIATE_DEVICE_TEST(TestSuite) \
+ INSTANTIATE_TEST_SUITE_P(PerInstance, TestSuite, testing::ValuesIn(getNamedDevices()), \
+ printNeuralnetworksHidlTest)
+
// Create an IPreparedModel object. If the model cannot be prepared,
// "preparedModel" will be nullptr instead.
void createPreparedModel(const sp<IDevice>& device, const Model& model,
diff --git a/neuralnetworks/1.0/vts/functional/include/1.0/Utils.h b/neuralnetworks/1.0/vts/functional/include/1.0/Utils.h
index 1ce751c..6d4534c 100644
--- a/neuralnetworks/1.0/vts/functional/include/1.0/Utils.h
+++ b/neuralnetworks/1.0/vts/functional/include/1.0/Utils.h
@@ -21,13 +21,15 @@
#include <android/hardware/neuralnetworks/1.0/types.h>
#include <algorithm>
#include <iosfwd>
+#include <string>
+#include <utility>
#include <vector>
#include "TestHarness.h"
namespace android::hardware::neuralnetworks {
// Create HIDL Request from the TestModel struct.
-V1_0::Request createRequest(const ::test_helper::TestModel& testModel);
+V1_0::Request createRequest(const test_helper::TestModel& testModel);
// After execution, copy out output results from the output memory pool.
std::vector<::test_helper::TestBuffer> getOutputBuffers(const V1_0::Request& request);
@@ -51,6 +53,21 @@
return index;
}
+template <typename Type>
+using Named = std::pair<std::string, Type>;
+
+template <typename Type>
+const std::string& getName(const Named<Type>& namedData) {
+ return namedData.first;
+}
+
+template <typename Type>
+const Type& getData(const Named<Type>& namedData) {
+ return namedData.second;
+}
+
+std::string gtestCompliantName(std::string name);
+
} // namespace android::hardware::neuralnetworks
namespace android::hardware::neuralnetworks::V1_0 {
diff --git a/neuralnetworks/1.1/vts/functional/Android.bp b/neuralnetworks/1.1/vts/functional/Android.bp
index c197e6d..4e85355 100644
--- a/neuralnetworks/1.1/vts/functional/Android.bp
+++ b/neuralnetworks/1.1/vts/functional/Android.bp
@@ -14,10 +14,11 @@
// limitations under the License.
//
-cc_defaults {
- name: "VtsHalNeuralNetworksV1_1TargetTestDefaults",
+cc_test {
+ name: "VtsHalNeuralnetworksV1_1TargetTest",
defaults: ["VtsHalTargetTestDefaults"],
srcs: [
+ "BasicTests.cpp",
"TestAssertions.cpp",
"ValidateModel.cpp",
"ValidateRequest.cpp",
@@ -39,35 +40,12 @@
"libneuralnetworks_utils",
"VtsHalNeuralNetworksV1_0_utils",
],
+ whole_static_libs: [
+ "neuralnetworks_generated_V1_0_example",
+ "neuralnetworks_generated_V1_1_example",
+ ],
header_libs: [
"libneuralnetworks_headers",
],
test_suites: ["general-tests"],
}
-
-cc_test {
- name: "VtsHalNeuralnetworksV1_1TargetTest",
- defaults: ["VtsHalNeuralNetworksV1_1TargetTestDefaults"],
- srcs: [
- "BasicTests.cpp",
- ],
- whole_static_libs: [
- "neuralnetworks_generated_V1_0_example",
- "neuralnetworks_generated_V1_1_example",
- ],
-}
-
-cc_test {
- name: "PresubmitHalNeuralnetworksV1_1TargetTest",
- defaults: ["VtsHalNeuralNetworksV1_1TargetTestDefaults"],
- srcs: [
- "BasicTests.cpp",
- ],
- whole_static_libs: [
- "neuralnetworks_generated_V1_0_example",
- "neuralnetworks_generated_V1_1_example",
- ],
- cflags: [
- "-DPRESUBMIT_NOT_VTS",
- ],
-}
diff --git a/neuralnetworks/1.1/vts/functional/BasicTests.cpp b/neuralnetworks/1.1/vts/functional/BasicTests.cpp
index 2791e80..44836f0 100644
--- a/neuralnetworks/1.1/vts/functional/BasicTests.cpp
+++ b/neuralnetworks/1.1/vts/functional/BasicTests.cpp
@@ -24,17 +24,17 @@
using V1_0::ErrorStatus;
// create device test
-TEST_F(NeuralnetworksHidlTest, CreateDevice) {}
+TEST_P(NeuralnetworksHidlTest, CreateDevice) {}
// status test
-TEST_F(NeuralnetworksHidlTest, StatusTest) {
+TEST_P(NeuralnetworksHidlTest, StatusTest) {
Return<DeviceStatus> status = kDevice->getStatus();
ASSERT_TRUE(status.isOk());
EXPECT_EQ(DeviceStatus::AVAILABLE, static_cast<DeviceStatus>(status));
}
// initialization
-TEST_F(NeuralnetworksHidlTest, GetCapabilitiesTest) {
+TEST_P(NeuralnetworksHidlTest, GetCapabilitiesTest) {
Return<void> ret =
kDevice->getCapabilities_1_1([](ErrorStatus status, const Capabilities& capabilities) {
EXPECT_EQ(ErrorStatus::NONE, status);
diff --git a/neuralnetworks/1.1/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/1.1/vts/functional/GeneratedTestHarness.cpp
index fddfc2b..7a929d6 100644
--- a/neuralnetworks/1.1/vts/functional/GeneratedTestHarness.cpp
+++ b/neuralnetworks/1.1/vts/functional/GeneratedTestHarness.cpp
@@ -156,6 +156,20 @@
checkResults(testModel, outputs);
}
+void GeneratedTestBase::SetUp() {
+ testing::TestWithParam<GeneratedTestParam>::SetUp();
+ ASSERT_NE(kDevice, nullptr);
+}
+
+std::vector<NamedModel> getNamedModels(const FilterFn& filter) {
+ return TestModelManager::get().getTestModels(filter);
+}
+
+std::string printGeneratedTest(const testing::TestParamInfo<GeneratedTestParam>& info) {
+ const auto& [namedDevice, namedModel] = info.param;
+ return gtestCompliantName(getName(namedDevice) + "_" + getName(namedModel));
+}
+
// Tag for the generated tests
class GeneratedTest : public GeneratedTestBase {};
diff --git a/neuralnetworks/1.1/vts/functional/GeneratedTestHarness.h b/neuralnetworks/1.1/vts/functional/GeneratedTestHarness.h
index 273d1ec..cf449ea 100644
--- a/neuralnetworks/1.1/vts/functional/GeneratedTestHarness.h
+++ b/neuralnetworks/1.1/vts/functional/GeneratedTestHarness.h
@@ -18,29 +18,38 @@
#define ANDROID_HARDWARE_NEURALNETWORKS_V1_1_GENERATED_TEST_HARNESS_H
#include <android/hardware/neuralnetworks/1.1/IDevice.h>
+#include "1.0/Utils.h"
#include "TestHarness.h"
#include "VtsHalNeuralnetworks.h"
namespace android::hardware::neuralnetworks::V1_1::vts::functional {
-class GeneratedTestBase
- : public NeuralnetworksHidlTest,
- public testing::WithParamInterface<test_helper::TestModelManager::TestParam> {
+using NamedModel = Named<const test_helper::TestModel*>;
+using GeneratedTestParam = std::tuple<NamedDevice, NamedModel>;
+
+class GeneratedTestBase : public testing::TestWithParam<GeneratedTestParam> {
protected:
- const test_helper::TestModel& kTestModel = *GetParam().second;
+ void SetUp() override;
+ const sp<IDevice> kDevice = getData(std::get<NamedDevice>(GetParam()));
+ const test_helper::TestModel& kTestModel = *getData(std::get<NamedModel>(GetParam()));
};
-#define INSTANTIATE_GENERATED_TEST(TestSuite, filter) \
- INSTANTIATE_TEST_SUITE_P( \
- TestGenerated, TestSuite, \
- testing::ValuesIn(::test_helper::TestModelManager::get().getTestModels(filter)), \
- [](const auto& info) { return info.param.first; })
+using FilterFn = std::function<bool(const test_helper::TestModel&)>;
+std::vector<NamedModel> getNamedModels(const FilterFn& filter);
+
+std::string printGeneratedTest(const testing::TestParamInfo<GeneratedTestParam>& info);
+
+#define INSTANTIATE_GENERATED_TEST(TestSuite, filter) \
+ INSTANTIATE_TEST_SUITE_P(TestGenerated, TestSuite, \
+ testing::Combine(testing::ValuesIn(getNamedDevices()), \
+ testing::ValuesIn(getNamedModels(filter))), \
+ printGeneratedTest)
// Tag for the validation tests, instantiated in VtsHalNeuralnetworks.cpp.
// TODO: Clean up the hierarchy for ValidationTest.
class ValidationTest : public GeneratedTestBase {};
-Model createModel(const ::test_helper::TestModel& testModel);
+Model createModel(const test_helper::TestModel& testModel);
} // namespace android::hardware::neuralnetworks::V1_1::vts::functional
diff --git a/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworks.cpp b/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworks.cpp
index d53d43e..d56d40b 100644
--- a/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworks.cpp
+++ b/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworks.cpp
@@ -17,13 +17,15 @@
#define LOG_TAG "neuralnetworks_hidl_hal_test"
#include "VtsHalNeuralnetworks.h"
+#include <android-base/logging.h>
+#include <hidl/ServiceManagement.h>
+#include <string>
+#include <utility>
#include "1.0/Callbacks.h"
#include "1.0/Utils.h"
#include "GeneratedTestHarness.h"
#include "TestHarness.h"
-#include <android-base/logging.h>
-
namespace android::hardware::neuralnetworks::V1_1::vts::functional {
using V1_0::ErrorStatus;
@@ -79,34 +81,39 @@
ASSERT_NE(nullptr, preparedModel->get());
}
-// A class for test environment setup
-NeuralnetworksHidlEnvironment* NeuralnetworksHidlEnvironment::getInstance() {
- // This has to return a "new" object because it is freed inside
- // testing::AddGlobalTestEnvironment when the gtest is being torn down
- static NeuralnetworksHidlEnvironment* instance = new NeuralnetworksHidlEnvironment();
- return instance;
-}
-
-void NeuralnetworksHidlEnvironment::registerTestServices() {
- registerTestService<IDevice>();
-}
-
-// The main test class for NEURALNETWORK HIDL HAL.
void NeuralnetworksHidlTest::SetUp() {
- testing::VtsHalHidlTargetTestBase::SetUp();
-
-#ifdef PRESUBMIT_NOT_VTS
- const std::string name =
- NeuralnetworksHidlEnvironment::getInstance()->getServiceName<IDevice>();
- const std::string sampleDriver = "sample-";
- if (kDevice == nullptr && name.substr(0, sampleDriver.size()) == sampleDriver) {
- GTEST_SKIP();
- }
-#endif // PRESUBMIT_NOT_VTS
-
- ASSERT_NE(nullptr, kDevice.get());
+ testing::TestWithParam<NeuralnetworksHidlTestParam>::SetUp();
+ ASSERT_NE(kDevice, nullptr);
}
+static NamedDevice makeNamedDevice(const std::string& name) {
+ return {name, IDevice::getService(name)};
+}
+
+static std::vector<NamedDevice> getNamedDevicesImpl() {
+ // Retrieves the name of all service instances that implement IDevice,
+ // including any Lazy HAL instances.
+ const std::vector<std::string> names = hardware::getAllHalInstanceNames(IDevice::descriptor);
+
+ // Get a handle to each device and pair it with its name.
+ std::vector<NamedDevice> namedDevices;
+ namedDevices.reserve(names.size());
+ std::transform(names.begin(), names.end(), std::back_inserter(namedDevices), makeNamedDevice);
+ return namedDevices;
+}
+
+const std::vector<NamedDevice>& getNamedDevices() {
+ const static std::vector<NamedDevice> devices = getNamedDevicesImpl();
+ return devices;
+}
+
+std::string printNeuralnetworksHidlTest(
+ const testing::TestParamInfo<NeuralnetworksHidlTestParam>& info) {
+ return gtestCompliantName(getName(info.param));
+}
+
+INSTANTIATE_DEVICE_TEST(NeuralnetworksHidlTest);
+
// Forward declaration from ValidateModel.cpp
void validateModel(const sp<IDevice>& device, const Model& model);
// Forward declaration from ValidateRequest.cpp
@@ -133,14 +140,3 @@
INSTANTIATE_GENERATED_TEST(ValidationTest, [](const test_helper::TestModel&) { return true; });
} // namespace android::hardware::neuralnetworks::V1_1::vts::functional
-
-using android::hardware::neuralnetworks::V1_1::vts::functional::NeuralnetworksHidlEnvironment;
-
-int main(int argc, char** argv) {
- testing::AddGlobalTestEnvironment(NeuralnetworksHidlEnvironment::getInstance());
- testing::InitGoogleTest(&argc, argv);
- NeuralnetworksHidlEnvironment::getInstance()->init(&argc, argv);
-
- int status = RUN_ALL_TESTS();
- return status;
-}
diff --git a/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworks.h b/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworks.h
index 9d6194a..e879d84 100644
--- a/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworks.h
+++ b/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworks.h
@@ -17,41 +17,33 @@
#ifndef ANDROID_HARDWARE_NEURALNETWORKS_V1_1_VTS_HAL_NEURALNETWORKS_H
#define ANDROID_HARDWARE_NEURALNETWORKS_V1_1_VTS_HAL_NEURALNETWORKS_H
-#include <android/hardware/neuralnetworks/1.0/types.h>
+#include <android/hardware/neuralnetworks/1.0/IPreparedModel.h>
#include <android/hardware/neuralnetworks/1.1/IDevice.h>
#include <android/hardware/neuralnetworks/1.1/types.h>
-
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
-
-#include <android-base/macros.h>
#include <gtest/gtest.h>
+#include <vector>
+#include "1.0/Utils.h"
namespace android::hardware::neuralnetworks::V1_1::vts::functional {
-// A class for test environment setup
-class NeuralnetworksHidlEnvironment : public testing::VtsHalHidlTargetTestEnvBase {
- DISALLOW_COPY_AND_ASSIGN(NeuralnetworksHidlEnvironment);
- NeuralnetworksHidlEnvironment() = default;
+using NamedDevice = Named<sp<IDevice>>;
+using NeuralnetworksHidlTestParam = NamedDevice;
- public:
- static NeuralnetworksHidlEnvironment* getInstance();
- void registerTestServices() override;
-};
-
-// The main test class for NEURALNETWORKS HIDL HAL.
-class NeuralnetworksHidlTest : public testing::VtsHalHidlTargetTestBase {
- DISALLOW_COPY_AND_ASSIGN(NeuralnetworksHidlTest);
-
- public:
- NeuralnetworksHidlTest() = default;
- void SetUp() override;
-
+class NeuralnetworksHidlTest : public testing::TestWithParam<NeuralnetworksHidlTestParam> {
protected:
- const sp<IDevice> kDevice = testing::VtsHalHidlTargetTestBase::getService<IDevice>(
- NeuralnetworksHidlEnvironment::getInstance());
+ void SetUp() override;
+ const sp<IDevice> kDevice = getData(GetParam());
};
+const std::vector<NamedDevice>& getNamedDevices();
+
+std::string printNeuralnetworksHidlTest(
+ const testing::TestParamInfo<NeuralnetworksHidlTestParam>& info);
+
+#define INSTANTIATE_DEVICE_TEST(TestSuite) \
+ INSTANTIATE_TEST_SUITE_P(PerInstance, TestSuite, testing::ValuesIn(getNamedDevices()), \
+ printNeuralnetworksHidlTest)
+
// Create an IPreparedModel object. If the model cannot be prepared,
// "preparedModel" will be nullptr instead.
void createPreparedModel(const sp<IDevice>& device, const Model& model,
diff --git a/neuralnetworks/1.2/vts/functional/Android.bp b/neuralnetworks/1.2/vts/functional/Android.bp
index 40ca809..3ba8879 100644
--- a/neuralnetworks/1.2/vts/functional/Android.bp
+++ b/neuralnetworks/1.2/vts/functional/Android.bp
@@ -14,16 +14,19 @@
// limitations under the License.
//
-cc_defaults {
- name: "VtsHalNeuralNetworksV1_2TargetTestDefaults",
+cc_test {
+ name: "VtsHalNeuralnetworksV1_2TargetTest",
defaults: ["VtsHalTargetTestDefaults"],
srcs: [
+ "BasicTests.cpp",
+ "Callbacks.cpp",
+ "CompilationCachingTests.cpp",
+ "GeneratedTestHarness.cpp",
"TestAssertions.cpp",
"ValidateModel.cpp",
"ValidateRequest.cpp",
+ "ValidateBurst.cpp",
"VtsHalNeuralnetworks.cpp",
- "Callbacks.cpp",
- "GeneratedTestHarness.cpp",
],
local_include_dirs: ["include"],
shared_libs: [
@@ -42,41 +45,13 @@
"libneuralnetworks_utils",
"VtsHalNeuralNetworksV1_0_utils",
],
+ whole_static_libs: [
+ "neuralnetworks_generated_V1_0_example",
+ "neuralnetworks_generated_V1_1_example",
+ "neuralnetworks_generated_V1_2_example",
+ ],
header_libs: [
"libneuralnetworks_headers",
],
test_suites: ["general-tests"],
}
-
-cc_test {
- name: "VtsHalNeuralnetworksV1_2TargetTest",
- defaults: ["VtsHalNeuralNetworksV1_2TargetTestDefaults"],
- srcs: [
- "BasicTests.cpp",
- "CompilationCachingTests.cpp",
- "ValidateBurst.cpp",
- ],
- whole_static_libs: [
- "neuralnetworks_generated_V1_0_example",
- "neuralnetworks_generated_V1_1_example",
- "neuralnetworks_generated_V1_2_example",
- ],
-}
-
-cc_test {
- name: "PresubmitHalNeuralnetworksV1_2TargetTest",
- defaults: ["VtsHalNeuralNetworksV1_2TargetTestDefaults"],
- srcs: [
- "BasicTests.cpp",
- "CompilationCachingTests.cpp",
- "ValidateBurst.cpp",
- ],
- whole_static_libs: [
- "neuralnetworks_generated_V1_0_example",
- "neuralnetworks_generated_V1_1_example",
- "neuralnetworks_generated_V1_2_example",
- ],
- cflags: [
- "-DPRESUBMIT_NOT_VTS",
- ],
-}
diff --git a/neuralnetworks/1.2/vts/functional/BasicTests.cpp b/neuralnetworks/1.2/vts/functional/BasicTests.cpp
index 8f95b96..8e82c53 100644
--- a/neuralnetworks/1.2/vts/functional/BasicTests.cpp
+++ b/neuralnetworks/1.2/vts/functional/BasicTests.cpp
@@ -25,17 +25,17 @@
using V1_0::PerformanceInfo;
// create device test
-TEST_F(NeuralnetworksHidlTest, CreateDevice) {}
+TEST_P(NeuralnetworksHidlTest, CreateDevice) {}
// status test
-TEST_F(NeuralnetworksHidlTest, StatusTest) {
+TEST_P(NeuralnetworksHidlTest, StatusTest) {
Return<DeviceStatus> status = kDevice->getStatus();
ASSERT_TRUE(status.isOk());
EXPECT_EQ(DeviceStatus::AVAILABLE, static_cast<DeviceStatus>(status));
}
// initialization
-TEST_F(NeuralnetworksHidlTest, GetCapabilitiesTest) {
+TEST_P(NeuralnetworksHidlTest, GetCapabilitiesTest) {
using OperandPerformance = Capabilities::OperandPerformance;
Return<void> ret = kDevice->getCapabilities_1_2([](ErrorStatus status,
const Capabilities& capabilities) {
@@ -60,7 +60,7 @@
}
// device version test
-TEST_F(NeuralnetworksHidlTest, GetDeviceVersionStringTest) {
+TEST_P(NeuralnetworksHidlTest, GetDeviceVersionStringTest) {
Return<void> ret =
kDevice->getVersionString([](ErrorStatus status, const hidl_string& version) {
EXPECT_EQ(ErrorStatus::NONE, status);
@@ -70,7 +70,7 @@
}
// device type test
-TEST_F(NeuralnetworksHidlTest, GetDeviceTypeTest) {
+TEST_P(NeuralnetworksHidlTest, GetDeviceTypeTest) {
Return<void> ret = kDevice->getType([](ErrorStatus status, DeviceType type) {
EXPECT_EQ(ErrorStatus::NONE, status);
EXPECT_TRUE(type == DeviceType::OTHER || type == DeviceType::CPU ||
@@ -80,7 +80,7 @@
}
// device supported extensions test
-TEST_F(NeuralnetworksHidlTest, GetDeviceSupportedExtensionsTest) {
+TEST_P(NeuralnetworksHidlTest, GetDeviceSupportedExtensionsTest) {
Return<void> ret = kDevice->getSupportedExtensions(
[](ErrorStatus status, const hidl_vec<Extension>& extensions) {
EXPECT_EQ(ErrorStatus::NONE, status);
@@ -101,7 +101,7 @@
}
// getNumberOfCacheFilesNeeded test
-TEST_F(NeuralnetworksHidlTest, getNumberOfCacheFilesNeeded) {
+TEST_P(NeuralnetworksHidlTest, getNumberOfCacheFilesNeeded) {
Return<void> ret = kDevice->getNumberOfCacheFilesNeeded(
[](ErrorStatus status, uint32_t numModelCache, uint32_t numDataCache) {
EXPECT_EQ(ErrorStatus::NONE, status);
diff --git a/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp b/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp
index bb46e06..2130a76 100644
--- a/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp
+++ b/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp
@@ -17,6 +17,7 @@
#define LOG_TAG "neuralnetworks_hidl_hal_test"
#include <android-base/logging.h>
+#include <fcntl.h>
#include <ftw.h>
#include <gtest/gtest.h>
#include <hidlmemory/mapping.h>
@@ -37,11 +38,11 @@
// Forward declaration of the mobilenet generated test models in
// frameworks/ml/nn/runtime/test/generated/.
namespace generated_tests::mobilenet_224_gender_basic_fixed {
-const ::test_helper::TestModel& get_test_model();
+const test_helper::TestModel& get_test_model();
} // namespace generated_tests::mobilenet_224_gender_basic_fixed
namespace generated_tests::mobilenet_quantized {
-const ::test_helper::TestModel& get_test_model();
+const test_helper::TestModel& get_test_model();
} // namespace generated_tests::mobilenet_quantized
namespace android::hardware::neuralnetworks::V1_2::vts::functional {
@@ -53,13 +54,13 @@
namespace float32_model {
-constexpr auto get_test_model = ::generated_tests::mobilenet_224_gender_basic_fixed::get_test_model;
+constexpr auto get_test_model = generated_tests::mobilenet_224_gender_basic_fixed::get_test_model;
} // namespace float32_model
namespace quant8_model {
-constexpr auto get_test_model = ::generated_tests::mobilenet_quantized::get_test_model;
+constexpr auto get_test_model = generated_tests::mobilenet_quantized::get_test_model;
} // namespace quant8_model
@@ -217,12 +218,13 @@
} // namespace
// Tag for the compilation caching tests.
-class CompilationCachingTestBase : public NeuralnetworksHidlTest {
+class CompilationCachingTestBase : public testing::Test {
protected:
- CompilationCachingTestBase(OperandType type) : kOperandType(type) {}
+ CompilationCachingTestBase(sp<IDevice> device, OperandType type)
+ : kDevice(std::move(device)), kOperandType(type) {}
void SetUp() override {
- NeuralnetworksHidlTest::SetUp();
+ testing::Test::SetUp();
ASSERT_NE(kDevice.get(), nullptr);
// Create cache directory. The cache directory and a temporary cache file is always created
@@ -274,7 +276,7 @@
};
nftw(mCacheDir.c_str(), callback, 128, FTW_DEPTH | FTW_MOUNT | FTW_PHYS);
}
- NeuralnetworksHidlTest::TearDown();
+ testing::Test::TearDown();
}
// Model and examples creators. According to kOperandType, the following methods will return
@@ -398,16 +400,21 @@
uint32_t mNumDataCache;
uint32_t mIsCachingSupported;
+ const sp<IDevice> kDevice;
// The primary data type of the testModel.
const OperandType kOperandType;
};
+using CompilationCachingTestParam = std::tuple<NamedDevice, OperandType>;
+
// A parameterized fixture of CompilationCachingTestBase. Every test will run twice, with the first
// pass running with float32 models and the second pass running with quant8 models.
class CompilationCachingTest : public CompilationCachingTestBase,
- public testing::WithParamInterface<OperandType> {
+ public testing::WithParamInterface<CompilationCachingTestParam> {
protected:
- CompilationCachingTest() : CompilationCachingTestBase(GetParam()) {}
+ CompilationCachingTest()
+ : CompilationCachingTestBase(getData(std::get<NamedDevice>(GetParam())),
+ std::get<OperandType>(GetParam())) {}
};
TEST_P(CompilationCachingTest, CacheSavingAndRetrieval) {
@@ -1192,16 +1199,30 @@
}
}
+static const auto kNamedDeviceChoices = testing::ValuesIn(getNamedDevices());
static const auto kOperandTypeChoices =
testing::Values(OperandType::TENSOR_FLOAT32, OperandType::TENSOR_QUANT8_ASYMM);
-INSTANTIATE_TEST_CASE_P(TestCompilationCaching, CompilationCachingTest, kOperandTypeChoices);
+std::string printCompilationCachingTest(
+ const testing::TestParamInfo<CompilationCachingTestParam>& info) {
+ const auto& [namedDevice, operandType] = info.param;
+ const std::string type = (operandType == OperandType::TENSOR_FLOAT32 ? "float32" : "quant8");
+ return gtestCompliantName(getName(namedDevice) + "_" + type);
+}
+
+INSTANTIATE_TEST_CASE_P(TestCompilationCaching, CompilationCachingTest,
+ testing::Combine(kNamedDeviceChoices, kOperandTypeChoices),
+ printCompilationCachingTest);
+
+using CompilationCachingSecurityTestParam = std::tuple<NamedDevice, OperandType, uint32_t>;
class CompilationCachingSecurityTest
: public CompilationCachingTestBase,
- public testing::WithParamInterface<std::tuple<OperandType, uint32_t>> {
+ public testing::WithParamInterface<CompilationCachingSecurityTestParam> {
protected:
- CompilationCachingSecurityTest() : CompilationCachingTestBase(std::get<0>(GetParam())) {}
+ CompilationCachingSecurityTest()
+ : CompilationCachingTestBase(getData(std::get<NamedDevice>(GetParam())),
+ std::get<OperandType>(GetParam())) {}
void SetUp() {
CompilationCachingTestBase::SetUp();
@@ -1291,7 +1312,7 @@
}
}
- const uint32_t kSeed = std::get<1>(GetParam());
+ const uint32_t kSeed = std::get<uint32_t>(GetParam());
std::mt19937 generator;
};
@@ -1338,7 +1359,16 @@
});
}
+std::string printCompilationCachingSecurityTest(
+ const testing::TestParamInfo<CompilationCachingSecurityTestParam>& info) {
+ const auto& [namedDevice, operandType, seed] = info.param;
+ const std::string type = (operandType == OperandType::TENSOR_FLOAT32 ? "float32" : "quant8");
+ return gtestCompliantName(getName(namedDevice) + "_" + type + "_" + std::to_string(seed));
+}
+
INSTANTIATE_TEST_CASE_P(TestCompilationCaching, CompilationCachingSecurityTest,
- testing::Combine(kOperandTypeChoices, testing::Range(0U, 10U)));
+ testing::Combine(kNamedDeviceChoices, kOperandTypeChoices,
+ testing::Range(0U, 10U)),
+ printCompilationCachingSecurityTest);
} // namespace android::hardware::neuralnetworks::V1_2::vts::functional
diff --git a/neuralnetworks/1.2/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/1.2/vts/functional/GeneratedTestHarness.cpp
index a2d3792..2beec98 100644
--- a/neuralnetworks/1.2/vts/functional/GeneratedTestHarness.cpp
+++ b/neuralnetworks/1.2/vts/functional/GeneratedTestHarness.cpp
@@ -190,7 +190,7 @@
}
static std::shared_ptr<::android::nn::ExecutionBurstController> CreateBurst(
const sp<IPreparedModel>& preparedModel) {
- return ::android::nn::ExecutionBurstController::create(preparedModel, /*blocking=*/true);
+ return android::nn::ExecutionBurstController::create(preparedModel, /*blocking=*/true);
}
enum class Executor { ASYNC, SYNC, BURST };
@@ -371,6 +371,20 @@
EvaluatePreparedModel(preparedModel, testModel, testDynamicOutputShape);
}
+void GeneratedTestBase::SetUp() {
+ testing::TestWithParam<GeneratedTestParam>::SetUp();
+ ASSERT_NE(kDevice, nullptr);
+}
+
+std::vector<NamedModel> getNamedModels(const FilterFn& filter) {
+ return TestModelManager::get().getTestModels(filter);
+}
+
+std::string printGeneratedTest(const testing::TestParamInfo<GeneratedTestParam>& info) {
+ const auto& [namedDevice, namedModel] = info.param;
+ return gtestCompliantName(getName(namedDevice) + "_" + getName(namedModel));
+}
+
// Tag for the generated tests
class GeneratedTest : public GeneratedTestBase {};
diff --git a/neuralnetworks/1.2/vts/functional/GeneratedTestHarness.h b/neuralnetworks/1.2/vts/functional/GeneratedTestHarness.h
index 0b8b917..dfc980c 100644
--- a/neuralnetworks/1.2/vts/functional/GeneratedTestHarness.h
+++ b/neuralnetworks/1.2/vts/functional/GeneratedTestHarness.h
@@ -22,34 +22,43 @@
#include <android/hardware/neuralnetworks/1.2/types.h>
#include <functional>
#include <vector>
+#include "1.0/Utils.h"
#include "TestHarness.h"
#include "VtsHalNeuralnetworks.h"
namespace android::hardware::neuralnetworks::V1_2::vts::functional {
-class GeneratedTestBase
- : public NeuralnetworksHidlTest,
- public testing::WithParamInterface<test_helper::TestModelManager::TestParam> {
+using NamedModel = Named<const test_helper::TestModel*>;
+using GeneratedTestParam = std::tuple<NamedDevice, NamedModel>;
+
+class GeneratedTestBase : public testing::TestWithParam<GeneratedTestParam> {
protected:
- const test_helper::TestModel& kTestModel = *GetParam().second;
+ void SetUp() override;
+ const sp<IDevice> kDevice = getData(std::get<NamedDevice>(GetParam()));
+ const test_helper::TestModel& kTestModel = *getData(std::get<NamedModel>(GetParam()));
};
-#define INSTANTIATE_GENERATED_TEST(TestSuite, filter) \
- INSTANTIATE_TEST_SUITE_P( \
- TestGenerated, TestSuite, \
- testing::ValuesIn(::test_helper::TestModelManager::get().getTestModels(filter)), \
- [](const auto& info) { return info.param.first; })
+using FilterFn = std::function<bool(const test_helper::TestModel&)>;
+std::vector<NamedModel> getNamedModels(const FilterFn& filter);
+
+std::string printGeneratedTest(const testing::TestParamInfo<GeneratedTestParam>& info);
+
+#define INSTANTIATE_GENERATED_TEST(TestSuite, filter) \
+ INSTANTIATE_TEST_SUITE_P(TestGenerated, TestSuite, \
+ testing::Combine(testing::ValuesIn(getNamedDevices()), \
+ testing::ValuesIn(getNamedModels(filter))), \
+ printGeneratedTest)
// Tag for the validation tests, instantiated in VtsHalNeuralnetworks.cpp.
// TODO: Clean up the hierarchy for ValidationTest.
class ValidationTest : public GeneratedTestBase {};
-Model createModel(const ::test_helper::TestModel& testModel);
+Model createModel(const test_helper::TestModel& testModel);
void PrepareModel(const sp<IDevice>& device, const Model& model, sp<IPreparedModel>* preparedModel);
void EvaluatePreparedModel(const sp<IPreparedModel>& preparedModel,
- const ::test_helper::TestModel& testModel, bool testDynamicOutputShape);
+ const test_helper::TestModel& testModel, bool testDynamicOutputShape);
} // namespace android::hardware::neuralnetworks::V1_2::vts::functional
diff --git a/neuralnetworks/1.2/vts/functional/ValidateBurst.cpp b/neuralnetworks/1.2/vts/functional/ValidateBurst.cpp
index c02d020..1d4493d 100644
--- a/neuralnetworks/1.2/vts/functional/ValidateBurst.cpp
+++ b/neuralnetworks/1.2/vts/functional/ValidateBurst.cpp
@@ -262,7 +262,7 @@
}));
// serialize the request
- const auto serialized = ::android::nn::serialize(request, MeasureTiming::YES, slots);
+ const auto serialized = android::nn::serialize(request, MeasureTiming::YES, slots);
// validations
removeDatumTest(sender.get(), receiver.get(), serialized);
@@ -299,7 +299,7 @@
// skip test if regular burst output isn't useful for testing a failure
// caused by having too small of a length for the result FMQ
const std::vector<FmqResultDatum> serialized =
- ::android::nn::serialize(statusRegular, outputShapesRegular, timingRegular);
+ android::nn::serialize(statusRegular, outputShapesRegular, timingRegular);
if (statusRegular != ErrorStatus::NONE ||
serialized.size() <= kExecutionBurstChannelSmallLength) {
return;
diff --git a/neuralnetworks/1.2/vts/functional/ValidateRequest.cpp b/neuralnetworks/1.2/vts/functional/ValidateRequest.cpp
index 5c52de5..f25ee62 100644
--- a/neuralnetworks/1.2/vts/functional/ValidateRequest.cpp
+++ b/neuralnetworks/1.2/vts/functional/ValidateRequest.cpp
@@ -94,7 +94,7 @@
// create burst
std::shared_ptr<::android::nn::ExecutionBurstController> burst =
- ::android::nn::ExecutionBurstController::create(preparedModel, /*blocking=*/true);
+ android::nn::ExecutionBurstController::create(preparedModel, /*blocking=*/true);
ASSERT_NE(nullptr, burst.get());
// create memory keys
diff --git a/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.cpp b/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.cpp
index aa4f1f2..4fbd0e2 100644
--- a/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.cpp
+++ b/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.cpp
@@ -17,13 +17,15 @@
#define LOG_TAG "neuralnetworks_hidl_hal_test"
#include "VtsHalNeuralnetworks.h"
+#include <android-base/logging.h>
+#include <hidl/ServiceManagement.h>
+#include <string>
+#include <utility>
#include "1.0/Callbacks.h"
#include "1.0/Utils.h"
#include "GeneratedTestHarness.h"
#include "TestHarness.h"
-#include <android-base/logging.h>
-
namespace android::hardware::neuralnetworks::V1_2::vts::functional {
using implementation::PreparedModelCallback;
@@ -82,34 +84,39 @@
ASSERT_NE(nullptr, preparedModel->get());
}
-// A class for test environment setup
-NeuralnetworksHidlEnvironment* NeuralnetworksHidlEnvironment::getInstance() {
- // This has to return a "new" object because it is freed inside
- // testing::AddGlobalTestEnvironment when the gtest is being torn down
- static NeuralnetworksHidlEnvironment* instance = new NeuralnetworksHidlEnvironment();
- return instance;
-}
-
-void NeuralnetworksHidlEnvironment::registerTestServices() {
- registerTestService<IDevice>();
-}
-
-// The main test class for NEURALNETWORK HIDL HAL.
void NeuralnetworksHidlTest::SetUp() {
- testing::VtsHalHidlTargetTestBase::SetUp();
-
-#ifdef PRESUBMIT_NOT_VTS
- const std::string name =
- NeuralnetworksHidlEnvironment::getInstance()->getServiceName<IDevice>();
- const std::string sampleDriver = "sample-";
- if (kDevice == nullptr && name.substr(0, sampleDriver.size()) == sampleDriver) {
- GTEST_SKIP();
- }
-#endif // PRESUBMIT_NOT_VTS
-
- ASSERT_NE(nullptr, kDevice.get());
+ testing::TestWithParam<NeuralnetworksHidlTestParam>::SetUp();
+ ASSERT_NE(kDevice, nullptr);
}
+static NamedDevice makeNamedDevice(const std::string& name) {
+ return {name, IDevice::getService(name)};
+}
+
+static std::vector<NamedDevice> getNamedDevicesImpl() {
+ // Retrieves the name of all service instances that implement IDevice,
+ // including any Lazy HAL instances.
+ const std::vector<std::string> names = hardware::getAllHalInstanceNames(IDevice::descriptor);
+
+ // Get a handle to each device and pair it with its name.
+ std::vector<NamedDevice> namedDevices;
+ namedDevices.reserve(names.size());
+ std::transform(names.begin(), names.end(), std::back_inserter(namedDevices), makeNamedDevice);
+ return namedDevices;
+}
+
+const std::vector<NamedDevice>& getNamedDevices() {
+ const static std::vector<NamedDevice> devices = getNamedDevicesImpl();
+ return devices;
+}
+
+std::string printNeuralnetworksHidlTest(
+ const testing::TestParamInfo<NeuralnetworksHidlTestParam>& info) {
+ return gtestCompliantName(getName(info.param));
+}
+
+INSTANTIATE_DEVICE_TEST(NeuralnetworksHidlTest);
+
// Forward declaration from ValidateModel.cpp
void validateModel(const sp<IDevice>& device, const Model& model);
// Forward declaration from ValidateRequest.cpp
@@ -162,14 +169,3 @@
}
} // namespace android::hardware::neuralnetworks::V1_2::vts::functional
-
-using android::hardware::neuralnetworks::V1_2::vts::functional::NeuralnetworksHidlEnvironment;
-
-int main(int argc, char** argv) {
- testing::AddGlobalTestEnvironment(NeuralnetworksHidlEnvironment::getInstance());
- testing::InitGoogleTest(&argc, argv);
- NeuralnetworksHidlEnvironment::getInstance()->init(&argc, argv);
-
- int status = RUN_ALL_TESTS();
- return status;
-}
diff --git a/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.h b/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.h
index 9981696..d01336e 100644
--- a/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.h
+++ b/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.h
@@ -17,42 +17,33 @@
#ifndef ANDROID_HARDWARE_NEURALNETWORKS_V1_2_VTS_HAL_NEURALNETWORKS_H
#define ANDROID_HARDWARE_NEURALNETWORKS_V1_2_VTS_HAL_NEURALNETWORKS_H
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
-#include <android-base/macros.h>
-#include <android/hardware/neuralnetworks/1.0/types.h>
-#include <android/hardware/neuralnetworks/1.1/types.h>
#include <android/hardware/neuralnetworks/1.2/IDevice.h>
+#include <android/hardware/neuralnetworks/1.2/IPreparedModel.h>
#include <android/hardware/neuralnetworks/1.2/types.h>
#include <gtest/gtest.h>
-
+#include "1.0/Utils.h"
#include "1.2/Callbacks.h"
namespace android::hardware::neuralnetworks::V1_2::vts::functional {
-// A class for test environment setup
-class NeuralnetworksHidlEnvironment : public testing::VtsHalHidlTargetTestEnvBase {
- DISALLOW_COPY_AND_ASSIGN(NeuralnetworksHidlEnvironment);
- NeuralnetworksHidlEnvironment() = default;
+using NamedDevice = Named<sp<IDevice>>;
+using NeuralnetworksHidlTestParam = NamedDevice;
- public:
- static NeuralnetworksHidlEnvironment* getInstance();
- void registerTestServices() override;
-};
-
-// The main test class for NEURALNETWORKS HIDL HAL.
-class NeuralnetworksHidlTest : public testing::VtsHalHidlTargetTestBase {
- DISALLOW_COPY_AND_ASSIGN(NeuralnetworksHidlTest);
-
- public:
- NeuralnetworksHidlTest() = default;
- void SetUp() override;
-
+class NeuralnetworksHidlTest : public testing::TestWithParam<NeuralnetworksHidlTestParam> {
protected:
- const sp<IDevice> kDevice = testing::VtsHalHidlTargetTestBase::getService<IDevice>(
- NeuralnetworksHidlEnvironment::getInstance());
+ void SetUp() override;
+ const sp<IDevice> kDevice = getData(GetParam());
};
+const std::vector<NamedDevice>& getNamedDevices();
+
+std::string printNeuralnetworksHidlTest(
+ const testing::TestParamInfo<NeuralnetworksHidlTestParam>& info);
+
+#define INSTANTIATE_DEVICE_TEST(TestSuite) \
+ INSTANTIATE_TEST_SUITE_P(PerInstance, TestSuite, testing::ValuesIn(getNamedDevices()), \
+ printNeuralnetworksHidlTest)
+
// Create an IPreparedModel object. If the model cannot be prepared,
// "preparedModel" will be nullptr instead.
void createPreparedModel(const sp<IDevice>& device, const Model& model,
diff --git a/neuralnetworks/TEST_MAPPING b/neuralnetworks/TEST_MAPPING
index 50b6c19..421922a 100644
--- a/neuralnetworks/TEST_MAPPING
+++ b/neuralnetworks/TEST_MAPPING
@@ -1,26 +1,35 @@
{
"presubmit": [
{
- "name": "PresubmitHalNeuralnetworksV1_0TargetTest",
+ "name": "VtsHalNeuralnetworksV1_0TargetTest",
"options": [
{
- "native-test-flag": "--hal_service_instance=android.hardware.neuralnetworks@1.0::IDevice/sample-all"
+ // Just use sample-all driver for presubmit tests for faster results.
+ // The other sample drivers (fast-float, quant, etc.) are subsets of
+ // sample-all.
+ "native-test-flag": "--gtest_filter=*sample_all*"
}
]
},
{
- "name": "PresubmitHalNeuralnetworksV1_1TargetTest",
+ "name": "VtsHalNeuralnetworksV1_1TargetTest",
"options": [
{
- "native-test-flag": "--hal_service_instance=android.hardware.neuralnetworks@1.1::IDevice/sample-all"
+ // Just use sample-all driver for presubmit tests for faster results.
+ // The other sample drivers (fast-float, quant, etc.) are subsets of
+ // sample-all.
+ "native-test-flag": "--gtest_filter=*sample_all*"
}
]
},
{
- "name": "PresubmitHalNeuralnetworksV1_2TargetTest",
+ "name": "VtsHalNeuralnetworksV1_2TargetTest",
"options": [
{
- "native-test-flag": "--hal_service_instance=android.hardware.neuralnetworks@1.2::IDevice/sample-all"
+ // Just use sample-all driver for presubmit tests for faster results.
+ // The other sample drivers (fast-float, quant, etc.) are subsets of
+ // sample-all.
+ "native-test-flag": "--gtest_filter=*sample_all*"
}
]
}
diff --git a/radio/1.2/types.hal b/radio/1.2/types.hal
index dffebd3..f10d753 100644
--- a/radio/1.2/types.hal
+++ b/radio/1.2/types.hal
@@ -161,7 +161,8 @@
ScanType type;
/**
- * Time interval in seconds between periodic scans, only valid when type = PERIODIC
+ * Time interval in seconds between the completion of one scan and the start of a subsequent scan.
+ * This field is only valid when 'type' is 'PERIODIC'.
* Range: ScanIntervalRange:MIN to ScanIntervalRange:MAX
*/
int32_t interval;
diff --git a/tv/tuner/1.0/Android.bp b/tv/tuner/1.0/Android.bp
index 986518b..09265f7 100644
--- a/tv/tuner/1.0/Android.bp
+++ b/tv/tuner/1.0/Android.bp
@@ -13,6 +13,7 @@
"IDescrambler.hal",
"IFrontend.hal",
"IFrontendCallback.hal",
+ "ILnb.hal",
"ITuner.hal",
],
interfaces: [
diff --git a/tv/tuner/1.0/IFrontend.hal b/tv/tuner/1.0/IFrontend.hal
index 05cee91..f9f78ef 100644
--- a/tv/tuner/1.0/IFrontend.hal
+++ b/tv/tuner/1.0/IFrontend.hal
@@ -16,6 +16,7 @@
package android.hardware.tv.tuner@1.0;
import IFrontendCallback;
+import ILnb;
/**
* A Tuner Frontend is used to tune to a frequency and lock signal. It provide
@@ -79,4 +80,98 @@
* UNKNOWN_ERROR if failed for other reasons.
*/
close() generates (Result result);
+
+ /**
+ * Scan the frontend to use the settings given.
+ *
+ * This uses the frontend to start a scan from signal delivery information.
+ * If previous scan isn't completed, this call MUST stop previous scan,
+ * and start a new scan.
+ * Scan is an async call, with FrontendScanMessage sent via callback.
+ *
+ * @param settings Signal delivery information which the frontend uses to
+ * scan the signal.
+ * @param type the type which the frontend uses to scan the signal.
+ *
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_STATE if tuning can't be applied at current stage,
+ * UNKNOWN_ERROR if tuning failed for other reasons.
+ */
+ scan(FrontendSettings settings, FrontendScanType type) generates (Result result);
+
+ /**
+ * Stops a previous scanning.
+ *
+ * If the method completes successfully, the frontend stop previous
+ * scanning.
+ *
+ * @return result Result status of the operation.
+ * SUCCESS if successfully stop tuning.
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ stopScan() generates (Result result);
+
+ /**
+ * Gets the statuses of the frontend.
+ *
+ * This retrieve the statuses of the frontend for given status types.
+ *
+ * @param statusTypes an array of status type which the caller request.
+ *
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_STATE if tuning can't be applied at current stage,
+ * UNKNOWN_ERROR if tuning failed for other reasons.
+ * @return statuses an array of statuses which response the caller's
+ * request.
+ */
+ getStatus(vec<FrontendStatusType> statusTypes) generates (Result result, vec<FrontendStatus> statuses);
+
+ /**
+ * Sets Low-Noise Block downconverter (LNB) for satellite frontend.
+ *
+ * This assigns a hardware LNB resource to the satellite frontend. It can be
+ * called multiple times to update LNB assignment. The LNB resource must be
+ * released when the frontend is closed.
+ *
+ * @param lnbId the Id of assigned LNB resource.
+ *
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_STATE if the frontend can't be set with a LNB, such as
+ * cable frontend.
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ setLnb(ILnb lnb) generates (Result result);
+
+ /**
+ * Enble or Disable Low Noise Amplifier (LNA).
+ *
+ * @param bEnable true if activate LNA module; false if deactivate LNA
+ *
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_STATE if the frontend doesn't support LNA.
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ setLna(bool bEnable) generates (Result result);
+
+ /**
+ * Sends DiSEqC (Digital Satellite Equipment Control) message.
+ *
+ * Client sends DiSeqc message to DiSEqc compatible device through the
+ * frontend. The response message from the device comes back to the client
+ * through frontend's callback onDiseqcMessage.
+ *
+ * @param diseqcMessage a byte array of data for DiSEqC message which is
+ * specified by EUTELSAT Bus Functional Specification Version 4.2.
+ *
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_STATE if the frontend can't send DiSEqc Message, such as
+ * cable frontend.
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ sendDiseqcMessage(vec<uint8_t> diseqcMessage) generates (Result result);
};
diff --git a/tv/tuner/1.0/IFrontendCallback.hal b/tv/tuner/1.0/IFrontendCallback.hal
index e907049..8896a09 100644
--- a/tv/tuner/1.0/IFrontendCallback.hal
+++ b/tv/tuner/1.0/IFrontendCallback.hal
@@ -33,5 +33,13 @@
* Specification Version 4.2.
*/
oneway onDiseqcMessage(vec<uint8_t> diseqcMessage);
-};
+ /**
+ * The callback function that must be called by HAL implementation to notify
+ * the client of scan messages.
+ *
+ * @param type the type of scan message.
+ * @param message the scan message sent by HAL to the client.
+ */
+ oneway onScanMessage(FrontendScanMessageType type, FrontendScanMessage message);
+};
diff --git a/tv/tuner/1.0/ILnb.hal b/tv/tuner/1.0/ILnb.hal
new file mode 100644
index 0000000..49fc3b4
--- /dev/null
+++ b/tv/tuner/1.0/ILnb.hal
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.tv.tuner@1.0;
+
+/**
+ * A Tuner LNB (low-noise block downconverter) is used by satellite frontend
+ * to receive the microwave signal from the satellite, amplify it, and
+ * downconvert the frequency to a lower frequency.
+ */
+interface ILnb {
+ /**
+ * Set the lnb's power voltage.
+ *
+ * @param voltage the power's voltage the Lnb to use.
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_ARGUMENT if the selected voltage isn't allowed,
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ setVoltage(FrontendLnbVoltage voltage) generates (Result result);
+
+ /**
+ * Set the lnb's tone mode.
+ *
+ * @param tone the tone mode the Lnb to use.
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_ARGUMENT if the selected tone mode isn't allowed,
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ setTone(FrontendLnbTone tone) generates (Result result);
+
+ /**
+ * Select the lnb's position.
+ *
+ * @param position the position the Lnb to use.
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_ARGUMENT if the selected position isn't allowed,
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ setSatellitePosition(FrontendLnbPosition position) generates (Result result);
+
+ /**
+ * Releases the LNB instance
+ *
+ * Associated resources are released. close may be called more than once.
+ * Calls to any other method after this will return an error
+ *
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ close() generates (Result result);
+};
diff --git a/tv/tuner/1.0/ITuner.hal b/tv/tuner/1.0/ITuner.hal
index a0f3e8e..f1a8617 100644
--- a/tv/tuner/1.0/ITuner.hal
+++ b/tv/tuner/1.0/ITuner.hal
@@ -19,6 +19,7 @@
import IDemux;
import IDescrambler;
import IFrontend;
+import ILnb;
/**
* Top level interface to manage Frontend, Demux and Decrambler hardware
@@ -45,6 +46,7 @@
* @param frontendId the id of the frontend to be opened.
* @return result Result status of the operation.
* SUCCESS if successful,
+ * UNAVAILABLE if no resource.
* UNKNOWN_ERROR if creation failed for other reasons.
* @return frontend the newly created frontend interface.
*/
@@ -62,7 +64,7 @@
* @return demuxId newly created demux id.
* @return demux the newly created demux interface.
*/
- openDemux()
+ openDemux()
generates (Result result, DemuxId demuxId, IDemux demux);
/**
@@ -75,6 +77,48 @@
* UNKNOWN_ERROR if creation failed for other reasons.
* @return descrambler the newly created descrambler interface.
*/
- openDescrambler()
+ openDescrambler()
generates (Result result, IDescrambler descrambler);
+
+ /**
+ * Create a new instance of Descrambler.
+ *
+ * It is used by the client to create a Descrambler instance.
+ *
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * UNKNOWN_ERROR if creation failed for other reasons.
+ * @return descrambler the newly created descrambler interface.
+ */
+ getFrontendInfo(FrontendId frontendId)
+ generates (Result result, FrontendInfo info);
+
+ /**
+ * Get low-noise block downconverter (LNB) IDs.
+ *
+ * It is used by the client to get all available LNBs' IDs.
+ *
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * UNKNOWN_ERROR if tuning failed for other reasons.
+ * @return frontendIds an array of LnbId for the available LNBs.
+ */
+ getLnbIds() generates (Result result, vec<LnbId> lnbIds);
+
+ /**
+ * Create a new instance of Lnb given a lnbId.
+ *
+ * It is used by the client to create a Lnb instance for satellite Frontend.
+ *
+ * @param lnbId the id of the LNB to be opened.
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * UNAVAILABLE if no resource.
+ * UNKNOWN_ERROR if creation failed for other reasons.
+ * @return lnb the newly created Lnb interface.
+ */
+ openLnbById(LnbId lnbId)
+ generates (Result result, ILnb lnb);
+
};
+
diff --git a/tv/tuner/1.0/default/Android.bp b/tv/tuner/1.0/default/Android.bp
index b211dd2..0ae8bcd 100644
--- a/tv/tuner/1.0/default/Android.bp
+++ b/tv/tuner/1.0/default/Android.bp
@@ -8,6 +8,7 @@
"Descrambler.cpp",
"Demux.cpp",
"Tuner.cpp",
+ "Lnb.cpp",
"service.cpp",
],
diff --git a/tv/tuner/1.0/default/Frontend.cpp b/tv/tuner/1.0/default/Frontend.cpp
index 3dcc2b1..0609d05 100644
--- a/tv/tuner/1.0/default/Frontend.cpp
+++ b/tv/tuner/1.0/default/Frontend.cpp
@@ -77,6 +77,46 @@
return Result::SUCCESS;
}
+Return<Result> Frontend::scan(const FrontendSettings& /* settings */, FrontendScanType /* type */) {
+ ALOGV("%s", __FUNCTION__);
+
+ return Result::SUCCESS;
+}
+
+Return<Result> Frontend::stopScan() {
+ ALOGV("%s", __FUNCTION__);
+
+ return Result::SUCCESS;
+}
+
+Return<void> Frontend::getStatus(const hidl_vec<FrontendStatusType>& /* statusTypes */,
+ getStatus_cb _hidl_cb) {
+ ALOGV("%s", __FUNCTION__);
+
+ vector<FrontendStatus> statuses;
+ _hidl_cb(Result::SUCCESS, statuses);
+
+ return Void();
+}
+
+Return<Result> Frontend::setLna(bool /* bEnable */) {
+ ALOGV("%s", __FUNCTION__);
+
+ return Result::SUCCESS;
+}
+
+Return<Result> Frontend::setLnb(const sp<ILnb>& /* lnb */) {
+ ALOGV("%s", __FUNCTION__);
+
+ return Result::SUCCESS;
+}
+
+Return<Result> Frontend::sendDiseqcMessage(const hidl_vec<uint8_t>& /* diseqcMessage */) {
+ ALOGV("%s", __FUNCTION__);
+
+ return Result::SUCCESS;
+}
+
FrontendType Frontend::getFrontendType() {
return mType;
}
diff --git a/tv/tuner/1.0/default/Frontend.h b/tv/tuner/1.0/default/Frontend.h
index f77a0d8..fc586b5 100644
--- a/tv/tuner/1.0/default/Frontend.h
+++ b/tv/tuner/1.0/default/Frontend.h
@@ -38,6 +38,7 @@
class Frontend : public IFrontend {
public:
Frontend();
+
Frontend(FrontendType type, FrontendId id);
virtual Return<Result> close() override;
@@ -48,6 +49,19 @@
virtual Return<Result> stopTune() override;
+ virtual Return<Result> scan(const FrontendSettings& settings, FrontendScanType type) override;
+
+ virtual Return<Result> stopScan() override;
+
+ virtual Return<void> getStatus(const hidl_vec<FrontendStatusType>& statusTypes,
+ getStatus_cb _hidl_cb) override;
+
+ virtual Return<Result> sendDiseqcMessage(const hidl_vec<uint8_t>& diseqcMessage) override;
+
+ virtual Return<Result> setLna(bool bEnable) override;
+
+ virtual Return<Result> setLnb(const sp<ILnb>& lnb) override;
+
FrontendType getFrontendType();
FrontendId getFrontendId();
diff --git a/tv/tuner/1.0/default/Lnb.cpp b/tv/tuner/1.0/default/Lnb.cpp
new file mode 100644
index 0000000..b81bb15
--- /dev/null
+++ b/tv/tuner/1.0/default/Lnb.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "android.hardware.tv.tuner@1.0-Lnb"
+
+#include "Lnb.h"
+#include <utils/Log.h>
+
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+namespace V1_0 {
+namespace implementation {
+
+Lnb::Lnb() {}
+
+Lnb::~Lnb() {}
+
+Return<Result> Lnb::setVoltage(FrontendLnbVoltage /* voltage */) {
+ ALOGV("%s", __FUNCTION__);
+
+ return Result::SUCCESS;
+}
+
+Return<Result> Lnb::setTone(FrontendLnbTone /* tone */) {
+ ALOGV("%s", __FUNCTION__);
+
+ return Result::SUCCESS;
+}
+
+Return<Result> Lnb::setSatellitePosition(FrontendLnbPosition /* position */) {
+ ALOGV("%s", __FUNCTION__);
+
+ return Result::SUCCESS;
+}
+
+Return<Result> Lnb::close() {
+ ALOGV("%s", __FUNCTION__);
+
+ return Result::SUCCESS;
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace tuner
+} // namespace tv
+} // namespace hardware
+} // namespace android
\ No newline at end of file
diff --git a/tv/tuner/1.0/default/Lnb.h b/tv/tuner/1.0/default/Lnb.h
new file mode 100644
index 0000000..df7e0fe
--- /dev/null
+++ b/tv/tuner/1.0/default/Lnb.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_TV_TUNER_V1_0_LNB_H_
+#define ANDROID_HARDWARE_TV_TUNER_V1_0_LNB_H_
+
+#include <android/hardware/tv/tuner/1.0/ILnb.h>
+#include <android/hardware/tv/tuner/1.0/ITuner.h>
+
+using namespace std;
+
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::tv::tuner::V1_0::FrontendLnbPosition;
+using ::android::hardware::tv::tuner::V1_0::FrontendLnbTone;
+using ::android::hardware::tv::tuner::V1_0::FrontendLnbVoltage;
+using ::android::hardware::tv::tuner::V1_0::Result;
+
+class Lnb : public ILnb {
+ public:
+ Lnb();
+
+ virtual Return<Result> setVoltage(FrontendLnbVoltage voltage);
+
+ virtual Return<Result> setTone(FrontendLnbTone tone) override;
+
+ virtual Return<Result> setSatellitePosition(FrontendLnbPosition position) override;
+
+ virtual Return<Result> close() override;
+
+ private:
+ virtual ~Lnb();
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace tuner
+} // namespace tv
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_TV_TUNER_V1_0_LNB_H_
\ No newline at end of file
diff --git a/tv/tuner/1.0/default/Tuner.cpp b/tv/tuner/1.0/default/Tuner.cpp
index 68b3436..00831ae 100644
--- a/tv/tuner/1.0/default/Tuner.cpp
+++ b/tv/tuner/1.0/default/Tuner.cpp
@@ -22,6 +22,7 @@
#include "Demux.h"
#include "Descrambler.h"
#include "Frontend.h"
+#include "Lnb.h"
namespace android {
namespace hardware {
@@ -95,6 +96,33 @@
return Void();
}
+Return<void> Tuner::getFrontendInfo(FrontendId /* frontendId */, getFrontendInfo_cb _hidl_cb) {
+ ALOGV("%s", __FUNCTION__);
+
+ FrontendInfo info;
+
+ _hidl_cb(Result::SUCCESS, info);
+ return Void();
+}
+
+Return<void> Tuner::getLnbIds(getLnbIds_cb _hidl_cb) {
+ ALOGV("%s", __FUNCTION__);
+
+ vector<LnbId> lnbIds;
+
+ _hidl_cb(Result::SUCCESS, lnbIds);
+ return Void();
+}
+
+Return<void> Tuner::openLnbById(LnbId /* lnbId */, openLnbById_cb _hidl_cb) {
+ ALOGV("%s", __FUNCTION__);
+
+ sp<ILnb> lnb = new Lnb();
+
+ _hidl_cb(Result::SUCCESS, lnb);
+ return Void();
+}
+
} // namespace implementation
} // namespace V1_0
} // namespace tuner
diff --git a/tv/tuner/1.0/default/Tuner.h b/tv/tuner/1.0/default/Tuner.h
index 12e9594..62227ee 100644
--- a/tv/tuner/1.0/default/Tuner.h
+++ b/tv/tuner/1.0/default/Tuner.h
@@ -41,6 +41,13 @@
virtual Return<void> openDescrambler(openDescrambler_cb _hidl_cb) override;
+ virtual Return<void> getFrontendInfo(FrontendId frontendId,
+ getFrontendInfo_cb _hidl_cb) override;
+
+ virtual Return<void> getLnbIds(getLnbIds_cb _hidl_cb) override;
+
+ virtual Return<void> openLnbById(LnbId lnbId, openLnbById_cb _hidl_cb) override;
+
private:
virtual ~Tuner();
// Static mFrontends array to maintain local frontends information
diff --git a/tv/tuner/1.0/types.hal b/tv/tuner/1.0/types.hal
index aa2a95c..a1153e9 100644
--- a/tv/tuner/1.0/types.hal
+++ b/tv/tuner/1.0/types.hal
@@ -41,42 +41,121 @@
enum FrontendType : uint32_t {
UNDEFINED = 0,
ANALOG,
+ /* Advanced Television Systems Committee (ATSC) Standard A/72. */
ATSC,
+ /* Advanced Television Systems Committee (ATSC 3.0) Standard A/330. */
+ ATSC3,
+ /**
+ * Digital Video Broadcasting - Cable
+ * DVB Cable Frontend Standard ETSI EN 300 468 V1.15.1.
+ */
DVBC,
+ /**
+ * Digital Video Broadcasting - Satellite
+ * DVB Satellite Frontend Standard ETSI EN 300 468 V1.15.1 and
+ * ETSI EN 302 307-2 V1.1.1.
+ */
DVBS,
+ /**
+ * Digital Video Broadcasting - Terrestrial
+ * DVB Terresttrial Frontend Standard ETSI EN 300 468 V1.15.1 and
+ * ETSI EN 302 755 V1.4.1.
+ */
DVBT,
+ /* Integrated Services Digital Broadcasting-Satellite (ISDB-S)
+ * ARIB SDT-B20 is technical document of ISDB-S.
+ */
+ ISDBS,
+ /* Integrated Services Digital Broadcasting-Satellite (ISDB-S)
+ * ARIB TR-B15 is technical document of ISDB-S3.
+ */
+ ISDBS3,
+ /* Integrated Services Digital Broadcasting-Terrestrial (ISDB-T or SBTVD)
+ * ABNT NBR 15603 is technical document of ISDB-T.
+ */
ISDBT,
};
/**
* Inner Forward Error Correction type as specified in ETSI EN 300 468 V1.15.1
- * It's a 4-bit field specifying the inner FEC scheme used according to the
- * table 35 in the spec.
+ * and ETSI EN 302 307-2 V1.1.1.
*/
@export
-enum FrontendInnerFec : uint32_t {
+enum FrontendInnerFec : uint64_t {
/* Not defined */
FEC_UNDEFINED = 0,
- /* 1/2 conv. code rate */
- FEC_1_2 = 1 << 0,
- /* 2/3 conv. code rate */
- FEC_2_3 = 1 << 1,
- /* 3/4 conv. code rate */
- FEC_3_4 = 1 << 2,
- /* 5/6 conv. code rate */
- FEC_5_6 = 1 << 3,
- /* 7/8 conv. code rate */
- FEC_7_8 = 1 << 4,
- /* 8/9 conv. code rate */
- FEC_8_9 = 1 << 5,
- /* 3/5 conv. code rate */
- FEC_3_5 = 1 << 6,
- /* 4/5 conv. code rate */
- FEC_4_5 = 1 << 7,
- /* 9/10 conv. code rate */
- FEC_9_10 = 1 << 8,
/* hardware is able to detect and set FEC automatically */
- FEC_AUTO = 1 << 9,
+ AUTO = 1 << 0,
+ /* 1/2 conv. code rate */
+ FEC_1_2 = 1 << 1,
+ /* 1/3 conv. code rate */
+ FEC_1_3 = 1 << 2,
+ /* 1/4 conv. code rate */
+ FEC_1_4 = 1 << 3,
+ /* 1/5 conv. code rate */
+ FEC_1_5 = 1 << 4,
+ /* 2/3 conv. code rate */
+ FEC_2_3 = 1 << 5,
+ /* 2/5 conv. code rate */
+ FEC_2_5 = 1 << 6,
+ /* 2/9 conv. code rate */
+ FEC_2_9 = 1 << 7,
+ /* 3/4 conv. code rate */
+ FEC_3_4 = 1 << 8,
+ /* 3/5 conv. code rate */
+ FEC_3_5 = 1 << 9,
+ /* 4/5 conv. code rate */
+ FEC_4_5 = 1 << 10,
+ /* 4/15 conv. code rate */
+ FEC_4_15 = 1 << 11,
+ /* 5/6 conv. code rate */
+ FEC_5_6 = 1 << 12,
+ /* 5/9 conv. code rate */
+ FEC_5_9 = 1 << 13,
+ /* 6/7 conv. code rate */
+ FEC_6_7 = 1 << 14,
+ /* 7/8 conv. code rate */
+ FEC_7_8 = 1 << 15,
+ /* 7/9 conv. code rate */
+ FEC_7_9 = 1 << 16,
+ /* 7/15 conv. code rate */
+ FEC_7_15 = 1 << 17,
+ /* 8/9 conv. code rate */
+ FEC_8_9 = 1 << 18,
+ /* 8/15 conv. code rate */
+ FEC_8_15 = 1 << 19,
+ /* 9/10 conv. code rate */
+ FEC_9_10 = 1 << 20,
+ /* 9/20 conv. code rate */
+ FEC_9_20 = 1 << 21,
+ /* 11/15 conv. code rate */
+ FEC_11_15 = 1 << 22,
+ /* 11/20 conv. code rate */
+ FEC_11_20 = 1 << 23,
+ /* 11/45 conv. code rate */
+ FEC_11_45 = 1 << 24,
+ /* 13/18 conv. code rate */
+ FEC_13_18 = 1 << 25,
+ /* 13/45 conv. code rate */
+ FEC_13_45 = 1 << 26,
+ /* 14/45 conv. code rate */
+ FEC_14_45 = 1 << 27,
+ /* 23/36 conv. code rate */
+ FEC_23_36 = 1 << 28,
+ /* 25/36 conv. code rate */
+ FEC_25_36 = 1 << 29,
+ /* 26/45 conv. code rate */
+ FEC_26_45 = 1 << 30,
+ /* 28/45 conv. code rate */
+ FEC_28_45 = 1 << 31,
+ /* 29/45 conv. code rate */
+ FEC_29_45 = 1 << 32,
+ /* 31/45 conv. code rate */
+ FEC_31_45 = 1 << 33,
+ /* 32/45 conv. code rate */
+ FEC_32_45 = 1 << 34,
+ /* 77/90 conv. code rate */
+ FEC_77_90 = 1 << 35,
};
/**
@@ -99,21 +178,760 @@
};
/**
+ * Capabilities for ATSC Frontend.
+ */
+struct FrontendAtscCapabilities {
+ /** Modulation capability */
+ bitfield<FrontendAtscModulation> modulationCap;
+};
+
+/**
+ * Modulation Type for ATSC3.
+ */
+@export
+enum FrontendAtsc3Modulation : uint32_t {
+ UNDEFINED = 0,
+ MOD_QPSK = 1 << 0,
+ MOD_16QAM = 1 << 1,
+ MOD_64QAM = 1 << 2,
+ MOD_256QAM = 1 << 3,
+ MOD_1024QAM = 1 << 4,
+ MOD_4096QAM = 1 << 5,
+};
+
+/**
+ * Bandwidth for ATSC3.
+ */
+@export
+enum FrontendAtsc3Bandwidth : uint32_t {
+ UNDEFINED = 0,
+ BANDWIDTH_8MHZ = 1 << 0,
+ BANDWIDTH_7MHZ = 1 << 1,
+ BANDWIDTH_6MHZ = 1 << 2,
+};
+
+/**
+ * Time Interleave Mode for ATSC3.
+ */
+@export
+enum FrontendAtsc3TimeInterleaveMode : uint32_t {
+ UNDEFINED,
+ CTI,
+ HTI,
+};
+
+/**
+ * Code Rate for ATSC3.
+ */
+@export
+enum FrontendAtsc3CodeRate : uint32_t {
+ UNDEFINED = 0,
+ /** hardware is able to detect and set Coderate automatically */
+ AUTO = 1 << 0,
+ CODERATE_2_15 = 1 << 1,
+ CODERATE_3_15 = 1 << 2,
+ CODERATE_4_15 = 1 << 3,
+ CODERATE_5_15 = 1 << 4,
+ CODERATE_6_15 = 1 << 5,
+ CODERATE_7_15 = 1 << 6,
+ CODERATE_8_15 = 1 << 7,
+ CODERATE_9_15 = 1 << 8,
+ CODERATE_10_15 = 1 << 9,
+ CODERATE_11_15 = 1 << 10,
+ CODERATE_12_15 = 1 << 11,
+ CODERATE_13_15 = 1 << 12,
+};
+
+/**
+ * Forward Error Correction (FEC) for ATSC3.
+ */
+@export
+enum FrontendAtsc3Fec : uint32_t {
+ UNDEFINED,
+ BCH_LDPC_16K,
+ BCH_LDPC_64K,
+ CRC_LDPC_16K,
+ CRC_LDPC_64K,
+ LDPC_16K,
+ LDPC_64K,
+};
+
+/**
+ * Signal Settings for an ATSC3 Frontend.
+ */
+struct FrontendAtsc3Settings {
+ /** Signal frequency in Hertz */
+ uint32_t frequency;
+ FrontendAtsc3Bandwidth bandwidth;
+ FrontendAtsc3TimeInterleaveMode interleaveMode;
+ FrontendAtsc3CodeRate codeRate;
+ FrontendAtsc3Fec fec;
+ vec<uint8_t> plpIdList;
+};
+
+/**
+ * Capabilities for ATSC3 Frontend.
+ */
+struct FrontendAtsc3Capabilities {
+ /** Modulation capability */
+ bitfield<FrontendAtsc3Modulation> modulationCap;
+ /** Bandwidth capability */
+ bitfield<FrontendAtsc3Bandwidth> bandwidthCap;
+};
+
+/**
+ * Modulation Type for DVBS.
+ */
+@export
+enum FrontendDvbsModulation : int32_t {
+ UNDEFINED = 0,
+ /** hardware is able to detect and set Modulation automatically */
+ AUTO = 1 << 0,
+ MOD_QPSK = 1 << 1,
+ MOD_8PSK = 1 << 2,
+ MOD_16QAM = 1 << 3,
+ MOD_16PSK = 1 << 4,
+ MOD_32PSK = 1 << 5,
+ MOD_ACM = 1 << 6,
+ MOD_8APSK = 1 << 7,
+ MOD_16APSK = 1 << 8,
+ MOD_32APSK = 1 << 9,
+ MOD_64APSK = 1 << 10,
+ MOD_128APSK = 1 << 11,
+ MOD_256APSK = 1 << 12,
+ /** Reserved for Proprietary modulation */
+ MOD_RESERVED = 1 << 13,
+};
+
+/**
+ * Roll Off value for DVBS.
+ */
+@export
+enum FrontendDvbsRolloff : uint32_t {
+ UNDEFINED,
+ ROLLOFF_0_35,
+ ROLLOFF_0_25,
+ ROLLOFF_0_20,
+ ROLLOFF_0_15,
+ ROLLOFF_0_10,
+ ROLLOFF_0_5,
+};
+
+/**
+ * Pilot mode for DVBS.
+ */
+@export
+enum FrontendDvbsPilot : uint32_t {
+ UNDEFINED,
+ ON,
+ OFF,
+ AUTO,
+};
+
+/**
+ * Code Rate for DVBS.
+ */
+struct FrontendDvbsCodeRate {
+ FrontendInnerFec fec;
+ bool isLinear;
+ /* true if enable short frame */
+ bool isShortFrames;
+ /* bits number in 1000 symbol. 0 if use the default. */
+ uint32_t bitsPer1000Symbol;
+};
+
+/**
+ * Sub standards in DVBS.
+ */
+@export
+enum FrontendDvbsStandard : uint8_t {
+ AUTO = 1 << 0,
+ S = 1 << 1,
+ S2 = 1 << 2,
+ S2X = 1 << 3,
+};
+
+/**
+ * Signal Settings for an DVBS Frontend.
+ */
+struct FrontendDvbsSettings {
+ /** Signal frequency in Hertz */
+ uint32_t frequency;
+ FrontendDvbsModulation modulation;
+ FrontendDvbsCodeRate coderate;
+ /** Symbols per second */
+ uint32_t symbolRate;
+ FrontendDvbsRolloff rolloff;
+ FrontendDvbsPilot pilot;
+ uint32_t inputStreamId;
+ FrontendDvbsStandard standard;
+};
+
+/**
+ * Capabilities for DVBS Frontend.
+ */
+struct FrontendDvbsCapabilities {
+ bitfield<FrontendDvbsModulation> modulationCap;
+ bitfield<FrontendInnerFec> innerfecCap;
+ bitfield<FrontendDvbsStandard> standard;
+};
+
+/**
+ * Modulation Type for DVBC.
+ */
+@export
+enum FrontendDvbcModulation : uint32_t {
+ UNDEFINED = 0,
+ /** hardware is able to detect and set Modulation automatically */
+ AUTO = 1 << 0,
+ MOD_16QAM = 1 << 1,
+ MOD_32QAM = 1 << 2,
+ MOD_64QAM = 1 << 3,
+ MOD_128QAM = 1 << 4,
+ MOD_256QAM = 1 << 5,
+};
+
+/**
+ * Outer Forward Error Correction (FEC) Type for DVBC.
+ */
+@export
+enum FrontendDvbcOuterFec : uint32_t {
+ UNDEFINED = 0,
+ OUTER_FEC_NONE,
+ OUTER_FEC_RS,
+};
+
+/**
+ * Annex Type for DVBC.
+ */
+@export
+enum FrontendDvbcAnnex : uint8_t {
+ UNDEFINED = 0,
+ A = 1 << 0,
+ B = 1 << 1,
+ C = 1 << 2,
+};
+
+/**
+ * Spectral Inversion Type for DVBC.
+ */
+@export
+enum FrontendDvbcSpectralInversion : uint32_t {
+ UNDEFINED,
+ NORMAL,
+ INVERTED,
+};
+
+/**
+ * Signal Settings for an DVBC Frontend.
+ */
+struct FrontendDvbcSettings {
+ /** Signal frequency in Hertz */
+ uint32_t frequency;
+ FrontendDvbcModulation modulation;
+ FrontendInnerFec fec;
+ /** Symbols per second */
+ uint32_t symbolRate;
+ FrontendDvbcOuterFec outerFec;
+ FrontendDvbcAnnex annex;
+ FrontendDvbcSpectralInversion spectralInversion;
+};
+
+/**
+ * Capabilities for DVBC Frontend.
+ */
+struct FrontendDvbcCapabilities {
+ bitfield<FrontendDvbcModulation> modulationCap;
+ bitfield<FrontendInnerFec> fecCap;
+ bitfield<FrontendDvbcAnnex> annexCap;
+};
+
+/**
+ * Bandwidth Type for DVBT.
+ */
+@export
+enum FrontendDvbtBandwidth : uint32_t {
+ UNDEFINED = 0,
+ /** hardware is able to detect and set Bandwidth automatically */
+ AUTO = 1 << 0,
+ BANDWIDTH_8MHZ = 1 << 1,
+ BANDWIDTH_7MHZ = 1 << 2,
+ BANDWIDTH_6MHZ = 1 << 3,
+ BANDWIDTH_5MHZ = 1 << 4,
+ BANDWIDTH_1_7MHZ = 1 << 5,
+ BANDWIDTH_10MHZ = 1 << 6,
+};
+
+/**
+ * Constellation Type for DVBT.
+ */
+@export
+enum FrontendDvbtConstellation : uint32_t {
+ UNDEFINED = 0,
+ /** hardware is able to detect and set Constellation automatically */
+ AUTO = 1 << 0,
+ CONSTELLATION_QPSK = 1 << 1,
+ CONSTELLATION_16QAM = 1 << 2,
+ CONSTELLATION_64QAM = 1 << 3,
+ CONSTELLATION_256QAM = 1 << 4,
+};
+
+/**
+ * Hierarchy Type for DVBT.
+ */
+@export
+enum FrontendDvbtHierarchy : uint32_t {
+ UNDEFINED = 0,
+ /** hardware is able to detect and set Hierarchy automatically */
+ AUTO = 1 << 0,
+ HIERARCHY_NON_NATIVE = 1 << 1,
+ HIERARCHY_1_NATIVE = 1 << 2,
+ HIERARCHY_2_NATIVE = 1 << 3,
+ HIERARCHY_4_NATIVE = 1 << 4,
+ HIERARCHY_NON_INDEPTH = 1 << 5,
+ HIERARCHY_1_INDEPTH = 1 << 6,
+ HIERARCHY_2_INDEPTH = 1 << 7,
+ HIERARCHY_4_INDEPTH = 1 << 8,
+};
+
+/**
+ * Hierarchy Type for DVBT.
+ */
+@export
+enum FrontendDvbtCoderate : uint32_t {
+ UNDEFINED = 0,
+ /** hardware is able to detect and set Hierarchy automatically */
+ AUTO = 1 << 0,
+ CODERATE_1_2 = 1 << 1,
+ CODERATE_2_3 = 1 << 2,
+ CODERATE_3_4 = 1 << 3,
+ CODERATE_5_6 = 1 << 4,
+ CODERATE_7_8 = 1 << 5,
+ CODERATE_3_5 = 1 << 6,
+ CODERATE_4_5 = 1 << 7,
+ CODERATE_6_7 = 1 << 8,
+ CODERATE_8_9 = 1 << 9,
+};
+
+/**
+ * Guard Interval Type for DVBT.
+ */
+@export
+enum FrontendDvbtGuardInterval : uint32_t {
+ UNDEFINED = 0,
+ /** hardware is able to detect and set Guard Interval automatically */
+ AUTO = 1 << 0,
+ INTERVAL_1_32 = 1 << 1,
+ INTERVAL_1_16 = 1 << 2,
+ INTERVAL_1_8 = 1 << 3,
+ INTERVAL_1_4 = 1 << 4,
+ INTERVAL_1_128 = 1 << 5,
+ INTERVAL_19_128 = 1 << 6,
+ INTERVAL_19_256 = 1 << 7,
+};
+
+/**
+ * Transmission Mode for DVBT.
+ */
+@export
+enum FrontendDvbtTransmissionMode : uint32_t {
+ UNDEFINED = 0,
+ /** hardware is able to detect and set Transmission Mode automatically */
+ AUTO = 1 << 0,
+ MODE_2K = 1 << 1,
+ MODE_8K = 1 << 2,
+ MODE_4K = 1 << 3,
+ MODE_1K = 1 << 4,
+ MODE_16K = 1 << 5,
+ MODE_32K = 1 << 6,
+};
+
+/**
+ * Physical Layer Pipe (PLP) Mode for DVBT.
+ */
+enum FrontendDvbtPlpMode : uint32_t {
+ UNDEFINED,
+ AUTO,
+ MANUAL,
+};
+
+/**
+ * Sub standards in DVBT.
+ */
+@export
+enum FrontendDvbtStandard : uint8_t {
+ AUTO = 1 << 0,
+ T = 1 << 1,
+ T2 = 1 << 2,
+};
+
+/**
* Signal Setting for DVBT Frontend.
*/
struct FrontendDvbtSettings {
/** Signal frequencey in Herhz */
uint32_t frequency;
- FrontendAtscModulation modulation;
- FrontendInnerFec fec;
+ FrontendDvbtTransmissionMode transmissionMode;
+ FrontendDvbtBandwidth bandwidth;
+ FrontendDvbtConstellation constellation;
+ FrontendDvbtHierarchy hierarchy;
+ /** Code Rate for High Priority level */
+ FrontendDvbtCoderate hpCoderate;
+ /** Code Rate for Low Priority level */
+ FrontendDvbtCoderate lpCoderate;
+ FrontendDvbtGuardInterval guardInterval;
+ bool isHighPriority;
+ FrontendDvbtStandard standard;
+ bool isMiso;
+ FrontendDvbtPlpMode plpMode;
+ /** Physical Layer Pipe (PLP) Id */
+ uint8_t plpId;
+ /** Group Id for Physical Layer Pipe (PLP) */
+ uint8_t plpGroupId;
};
/**
- * Modulation Type for ATSC.
+ * Capabilities for DVBT Frontend.
+ */
+struct FrontendDvbtCapabilities {
+ bitfield<FrontendDvbtTransmissionMode> transmissionModeCap;
+ bitfield<FrontendDvbtBandwidth> bandwidthCap;
+ bitfield<FrontendDvbtConstellation> constellationCap;
+ bitfield<FrontendDvbtCoderate> coderateCap;
+ bitfield<FrontendDvbtHierarchy> hierarchyCap;
+ bitfield<FrontendDvbtGuardInterval> guardIntervalCap;
+ bool isT2Supported;
+ bool isMisoSupported;
+};
+
+/**
+ * Roll Off Type for ISDBS.
+ */
+@export
+enum FrontendIsdbsRolloff : uint32_t {
+ UNDEFINED,
+ ROLLOFF_0_35,
+};
+
+/**
+ * Modulaltion Type for ISDBS.
+ */
+@export
+enum FrontendIsdbsModulation : uint32_t {
+ UNDEFINED = 0,
+ /** hardware is able to detect and set Modulation automatically */
+ AUTO = 1 << 0,
+ MOD_BPSK = 1 << 1,
+ MOD_QPSK = 1 << 2,
+ MOD_TC8PSK = 1 << 3,
+};
+
+/**
+ * Code Rate Type for ISDBS.
+ */
+@export
+enum FrontendIsdbsCoderate : uint32_t {
+ UNDEFINED = 0,
+ /** hardware is able to detect and set Code Rate automatically */
+ AUTO = 1 << 0,
+ CODERATE_1_2 = 1 << 1,
+ CODERATE_2_3 = 1 << 2,
+ CODERATE_3_4 = 1 << 3,
+ CODERATE_5_6 = 1 << 4,
+ CODERATE_7_8 = 1 << 5,
+};
+
+/**
+ * Stream Id Type for ISDBS.
+ */
+@export
+enum FrontendIsdbsStreamIdType : uint32_t {
+ STREAM_ID,
+ RELATIVE_STREAM_ID,
+};
+
+/**
+ * Signal Setting for ISDBS Frontend.
+ */
+struct FrontendIsdbsSettings {
+ /** Signal frequency in Hertz */
+ uint32_t frequency;
+ uint16_t streamId;
+ FrontendIsdbsStreamIdType streamIdType;
+ FrontendIsdbsModulation modulation;
+ FrontendIsdbsCoderate coderate;
+ /** Symbols per second */
+ uint32_t symbolRate;
+ FrontendIsdbsRolloff rolloff;
+};
+
+/**
+ * Capabilities for ISDBS Frontend.
+ */
+struct FrontendIsdbsCapabilities {
+ bitfield<FrontendIsdbsModulation> modulationCap;
+ bitfield<FrontendIsdbsCoderate> coderateCap;
+};
+
+/**
+ * Roll of Type for ISDBS3.
+ */
+@export
+enum FrontendIsdbs3Rolloff : uint32_t {
+ UNDEFINED,
+ ROLLOFF_0_03,
+};
+
+/**
+ * Modulaltion Type for ISDBS3.
+ */
+@export
+enum FrontendIsdbs3Modulation : uint32_t {
+ UNDEFINED = 0,
+ /** hardware is able to detect and set Modulation automatically */
+ AUTO = 1 << 5,
+ MOD_BPSK = 1 << 1,
+ MOD_QPSK = 1 << 2,
+ MOD_8PSK = 1 << 3,
+ MOD_16APSK = 1 << 4,
+ MOD_32APSK = 1 << 5,
+};
+
+/**
+ * Code Rate Type for ISDBS3.
+ */
+@export
+enum FrontendIsdbs3Coderate : uint32_t {
+ UNDEFINED = 0,
+ /** hardware is able to detect and set Code Rate automatically */
+ AUTO = 1 << 0,
+ CODERATE_1_3 = 1 << 1,
+ CODERATE_2_5 = 1 << 2,
+ CODERATE_1_2 = 1 << 3,
+ CODERATE_3_5 = 1 << 4,
+ CODERATE_2_3 = 1 << 5,
+ CODERATE_3_4 = 1 << 6,
+ CODERATE_7_9 = 1 << 7,
+ CODERATE_4_5 = 1 << 8,
+ CODERATE_5_6 = 1 << 9,
+ CODERATE_7_8 = 1 << 10,
+ CODERATE_9_10 = 1 << 11,
+};
+
+/**
+ * Signal Setting for ISDBS3 Frontend.
+ */
+struct FrontendIsdbs3Settings {
+ /** Signal frequency in Hertz */
+ uint32_t frequency;
+ uint16_t streamId;
+ FrontendIsdbsStreamIdType streamIdType;
+ FrontendIsdbs3Modulation modulation;
+ FrontendIsdbs3Coderate coderate;
+ /** Symbols per second */
+ uint32_t symbolRate;
+ FrontendIsdbs3Rolloff rolloff;
+};
+
+/**
+ * Capabilities for ISDBS3 Frontend.
+ */
+struct FrontendIsdbs3Capabilities {
+ bitfield<FrontendIsdbs3Modulation> modulationCap;
+ bitfield<FrontendIsdbs3Coderate> coderateCap;
+};
+
+/**
+ * Mode for ISDBT.
+ */
+@export
+enum FrontendIsdbtMode : uint32_t {
+ UNDEFINED = 0,
+ /** hardware is able to detect and set Mode automatically */
+ AUTO = 1 << 0,
+ MODE_1 = 1 << 1,
+ MODE_2 = 1 << 2,
+ MODE_3 = 1 << 3,
+};
+
+/**
+ * Bandwidth for ISDBT.
+ */
+@export
+enum FrontendIsdbtBandwidth : uint32_t {
+ UNDEFINED = 0,
+ /** hardware is able to detect and set Bandwidth automatically */
+ AUTO = 1 << 0,
+ BANDWIDTH_8MHZ = 1 << 1,
+ BANDWIDTH_7MHZ = 1 << 2,
+ BANDWIDTH_6MHZ = 1 << 3,
+};
+
+/**
+ * Modulation for ISDBT.
+ */
+@export
+enum FrontendIsdbtModulation : uint32_t {
+ UNDEFINED = 0,
+ /** hardware is able to detect and set Modulation automatically */
+ AUTO = 1 << 0,
+ MOD_DQPSK = 1 << 1,
+ MOD_QPSK = 1 << 2,
+ MOD_16QAM = 1 << 3,
+ MOD_64QAM = 1 << 4,
+};
+
+/** Code Rate for ISDBT. */
+typedef FrontendDvbtCoderate FrontendIsdbtCoderate;
+
+/** Guard Interval for ISDBT. */
+typedef FrontendDvbtGuardInterval FrontendIsdbtGuardInterval;
+
+/**
+ * Signal Setting for ISDBT Frontend.
+ */
+struct FrontendIsdbtSettings {
+ /** Signal frequency in Hertz */
+ uint32_t frequency;
+ FrontendIsdbtModulation modulation;
+ FrontendIsdbtBandwidth bandwidth;
+ FrontendIsdbtMode mode;
+ FrontendIsdbtCoderate coderate;
+ FrontendIsdbtGuardInterval guardInterval;
+ uint32_t serviceAreaId;
+};
+
+/**
+ * Capabilities for ISDBT Frontend.
+ */
+struct FrontendIsdbtCapabilities {
+ bitfield<FrontendIsdbtMode> modeCap;
+ bitfield<FrontendIsdbtBandwidth> bandwidthCap;
+ bitfield<FrontendIsdbtModulation> constellationCap;
+ bitfield<FrontendIsdbtCoderate> coderateCap;
+ bitfield<FrontendIsdbtGuardInterval> guardIntervalCap;
+};
+
+/**
+ * Signal Type for Analog Frontend.
+ */
+@export
+enum FrontendAnalogType : uint32_t {
+ UNDEFINED = 0,
+ PAL = 1 << 0,
+ SECAM = 1 << 1,
+ NTSC = 1 << 2,
+};
+
+/**
+ * Standard Interchange Format (SIF) for Analog Frontend.
+ */
+@export
+enum FrontendAnalogSifStandard : uint32_t {
+ UNDEFINED = 0,
+ BG = 1 << 0,
+ BG_A2 = 1 << 1,
+ BG_NICAM = 1 << 2,
+ I = 1 << 3,
+ DK = 1 << 4,
+ DK1 = 1 << 5,
+ DK2 = 1 << 6,
+ DK3 = 1 << 7,
+ DK_NICAM = 1 << 8,
+ L = 1 << 9,
+ M = 1 << 10,
+ M_BTSC = 1 << 11,
+ M_A2 = 1 << 12,
+ M_EIA_J = 1 << 13,
+ I_NICAM = 1 << 14,
+ L_NICAM = 1 << 15,
+};
+
+/**
+ * Signal Setting for Analog Frontend.
+ */
+struct FrontendAnalogSettings {
+ /** Signal frequency in Hertz */
+ uint32_t frequency;
+ FrontendAnalogType type;
+ FrontendAnalogSifStandard sifStandard;
+};
+
+/**
+ * Capabilities for Analog Frontend.
+ */
+struct FrontendAnalogCapabilities {
+ bitfield<FrontendAnalogType> typeCap;
+ bitfield<FrontendAnalogSifStandard> sifStandardCap;
+};
+
+/**
+ * Signal Setting for Frontend.
*/
safe_union FrontendSettings {
+ FrontendAnalogSettings analog;
FrontendAtscSettings atsc;
+ FrontendAtsc3Settings atsc3;
+ FrontendDvbsSettings dvbs;
+ FrontendDvbcSettings dvbc;
FrontendDvbtSettings dvbt;
+ FrontendIsdbsSettings isdbs;
+ FrontendIsdbs3Settings isdbs3;
+ FrontendIsdbtSettings isdbt;
+};
+
+/**
+ * Scan type for Frontend.
+ */
+enum FrontendScanType : uint32_t {
+ SCAN_UNDEFINED = 0,
+ SCAN_AUTO = 1 << 0,
+ SCAN_BLIND = 1 << 1,
+};
+
+/**
+ * Scan Message Type for Frontend.
+ */
+enum FrontendScanMessageType : uint32_t {
+ /** Scan locked the signal. */
+ LOCKED,
+ /** Scan stopped. */
+ END,
+ /** Scan progress report. */
+ PROGRESS_PERCENT,
+ /** Locked frequency report. */
+ FREQUENCY,
+ /** Locked symbol rate. */
+ SYMBOL_RATE,
+ /** Locked Plp Ids for DVBT2 frontend. */
+ PLP_IDS,
+ /** Locked group Ids for DVBT2 frontend. */
+ GROUP_IDS,
+ /** Locked the number of the Plps. */
+ INPUT_STREAM_IDS,
+ /** Locked signal stardard. */
+ STANDARD,
+};
+
+/**
+ * Scan Message for Frontend.
+ */
+safe_union FrontendScanMessage {
+ bool islocked;
+ bool isEnd;
+ /** scan progress percent (0..100) */
+ uint8_t progressPercent;
+ /** Signal frequency in Hertz */
+ uint32_t frequency;
+ /** Symbols per second */
+ uint32_t symbolRate;
+ vec<uint8_t> plpIds;
+ vec<uint8_t> groupIds;
+ vec<uint8_t> inputStreamIds;
+ safe_union standard {
+ FrontendDvbsStandard sStd;
+ FrontendDvbtStandard tStd;
+ } std;
};
/**
@@ -136,8 +954,174 @@
* event.
*/
LOST_LOCK,
+ /**
+ * If frontend detect that incoming Diseqc message is overflow.
+ */
+ DISEQC_RX_OVERFLOW,
+ /**
+ * If frontend detect that outgoing Diseqc message isn't delivered on time.
+ */
+ DISEQC_RX_TIMEOUT,
+ /**
+ * If frontend detect that the incoming Diseqc message has parity error.
+ */
+ DISEQC_RX_PARITY_ERROR,
+ /**
+ * If frontend detect that the LNB is overload.
+ */
+ LNB_OVERLOAD,
};
+/**
+ * Frontend Status Type.
+ */
+@export
+enum FrontendStatusType : uint32_t {
+ /** Lock status for RF or Demod. */
+ LOCK,
+ /** Signal to Noise Ratio. */
+ SNR,
+ /** Bit Error Ratio. */
+ BER,
+ /** Packages Error Ratio. */
+ PER,
+ /** Bit Error Ratio befor FEC. */
+ PRE_BER,
+ /*
+ * Signal Quality (0..100). Good data over total data in percent can be
+ * used as a way to present Signal Quality.
+ */
+ SIGNAL_QUALITY,
+ /** Signal Strength. */
+ SIGGAL_STRENGTH,
+ /** Symbol Rate. */
+ SYMBOL_RATE,
+ /** Forward Error Correction Type. */
+ FEC,
+ /** Modulation Type. */
+ MODULATION,
+ /** Spectral Inversion Type. */
+ SPECTRAL,
+ /** LNB Voltage. */
+ LNB_VOLTAGE,
+ /** Physical Layer Pipe ID. */
+ PLP_ID,
+ /** Status for Emergency Warning Broadcasting System. */
+ EWBS,
+};
+
+/**
+ * Modulation Type for Frontend's status.
+ */
+safe_union FrontendModulationStatus {
+ FrontendDvbsModulation dvbs;
+ FrontendAtsc3Modulation atsc3;
+};
+
+/**
+ * The status for Frontend.
+ */
+safe_union FrontendStatus {
+ bool isLocked;
+ /** SNR value measured by 0.001 dB. */
+ int32_t snr;
+ /** The number of error bit per 1 billion bits. */
+ uint32_t ber;
+ /** The number of error package per 1 billion packages. */
+ uint32_t per;
+ /** The number of error bit per 1 billion bits before FEC. */
+ uint32_t preBer;
+ /** Signal Quality in percent. */
+ uint32_t signalQuality;
+ /** Signal Strength measured by 0.001 dBm. */
+ int32_t signalStrength;
+ /** Symbols per second */
+ uint32_t symbolRate;
+ FrontendInnerFec innerFec;
+ FrontendModulationStatus modulation;
+ FrontendDvbcSpectralInversion inversion;
+ FrontendLnbVoltage lnbVoltage;
+ uint8_t plpId;
+ bool isEWBS;
+};
+
+/**
+ * Information for the Frontend.
+ */
+struct FrontendInfo {
+ FrontendType type;
+ /** Frequency in Hertz */
+ uint32_t minFrequency;
+ /** Frequency in Hertz */
+ uint32_t maxFrequency;
+ /** Minimum symbols per second */
+ uint32_t minSymbolRate;
+ /** Maximum symbols per second */
+ uint32_t maxSymbolRate;
+ /** Range in Hertz */
+ uint32_t acquireRange;
+ /*
+ * Frontends are assigned with the same exclusiveGroupId if they can't
+ * function at same time. For instance, they share same hardware module.
+ */
+ uint32_t exclusiveGroupId;
+ /** A list of supported status types which client can inquiry */
+ vec<FrontendStatusType> statusCaps;
+ safe_union FrontendCapabilities {
+ FrontendAnalogCapabilities analogCaps;
+ FrontendAtscCapabilities atscCaps;
+ FrontendAtsc3Capabilities atsc3Caps;
+ FrontendDvbsCapabilities dvbsCaps;
+ FrontendDvbcCapabilities dvbcCaps;
+ FrontendDvbtCapabilities dvbtCaps;
+ FrontendIsdbsCapabilities isdbsCaps;
+ FrontendIsdbs3Capabilities isdbs3Caps;
+ FrontendIsdbtCapabilities isdbtCaps;
+ } frontendCaps;
+};
+
+/*
+ * Low-Noise Block downconverter (LNB) ID is used to associate with a hardware
+ * LNB module.
+ */
+typedef uint32_t LnbId;
+
+/**
+ * Power Voltage Type for LNB.
+ */
+@export
+enum FrontendLnbVoltage : uint32_t {
+ NONE,
+ VOLTAGE_5V,
+ VOLTAGE_11V,
+ VOLTAGE_12V,
+ VOLTAGE_13V,
+ VOLTAGE_14V,
+ VOLTAGE_15V,
+ VOLTAGE_18V,
+ VOLTAGE_19V,
+};
+
+/**
+ * Tone Type for LNB.
+ */
+@export
+enum FrontendLnbTone : int32_t {
+ NONE,
+ CONTINUOUS,
+};
+
+/**
+ * The Position of LNB.
+ */
+@export
+enum FrontendLnbPosition : int32_t {
+ UNDEFINED,
+ POSITION_A,
+ POSITION_B,
+};
+
+
/* Demux ID is used to associate with a hardware demux resource. */
typedef uint32_t DemuxId;
@@ -248,7 +1232,7 @@
/* Version number for Section Filter */
uint16_t version;
/* true if the filter checks CRC and discards data with wrong CRC */
- bool checkCrc;
+ bool isCheckCrc;
/* true if the filter repeats the data with the same version */
bool isRepeat;
/* true if the filter output raw data */
@@ -265,7 +1249,7 @@
DemuxTpid tpid;
DemuxStreamId streamId;
/* true if the filter output raw data */
- bool bIsRaw;
+ bool isRaw;
};
/**
@@ -283,7 +1267,7 @@
/**
* true if the filter output goes to decoder directly in pass through mode.
*/
- bool bPassthrough;
+ bool isPassthrough;
};
/**
@@ -294,7 +1278,7 @@
/**
* true if the filter output goes to decoder directly in pass through mode.
*/
- bool bPassthrough;
+ bool isPassthrough;
};
/**
diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
index d272d71..7256cc4 100644
--- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
+++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
@@ -36,6 +36,7 @@
#include <utils/Mutex.h>
#include <fstream>
#include <iostream>
+#include <map>
#define WAIT_TIMEOUT 3000000000
@@ -72,6 +73,8 @@
using android::hardware::tv::tuner::V1_0::FrontendEventType;
using android::hardware::tv::tuner::V1_0::FrontendId;
using android::hardware::tv::tuner::V1_0::FrontendInnerFec;
+using android::hardware::tv::tuner::V1_0::FrontendScanMessage;
+using android::hardware::tv::tuner::V1_0::FrontendScanMessageType;
using android::hardware::tv::tuner::V1_0::FrontendSettings;
using android::hardware::tv::tuner::V1_0::IDemux;
using android::hardware::tv::tuner::V1_0::IDemuxCallback;
@@ -159,12 +162,21 @@
return Void();
}
+ virtual Return<void> onScanMessage(FrontendScanMessageType /* type */,
+ const FrontendScanMessage& /* message */) override {
+ android::Mutex::Autolock autoLock(mMsgLock);
+ mScanMessageReceived = true;
+ mMsgCondition.signal();
+ return Void();
+ };
+
void testOnEvent(sp<IFrontend>& frontend, FrontendSettings settings);
void testOnDiseqcMessage(sp<IFrontend>& frontend, FrontendSettings settings);
private:
bool mEventReceived = false;
bool mDiseqcMessageReceived = false;
+ bool mScanMessageReceived = false;
FrontendEventType mEventType;
hidl_vec<uint8_t> mEventMessage;
android::Mutex mMsgLock;
@@ -205,8 +217,8 @@
ALOGW("[VTS] FILTER EVENT %d", filterEvent.filterId);
android::Mutex::Autolock autoLock(mMsgLock);
mFilterEventReceived = true;
- // maybe assemble here??
- mFilterEvent = filterEvent;
+ mFilterIdToEvent[filterEvent.filterId] = filterEvent;
+ startFilterEventThread(filterEvent);
mMsgCondition.signal();
return Void();
}
@@ -236,11 +248,19 @@
void testOnFilterEvent(uint32_t filterId);
void testOnSectionFilterEvent(sp<IDemux>& demux, uint32_t filterId, MQDesc& filterMQDescriptor,
MQDesc& inputMQDescriptor);
- void startPlaybackInputThread(InputConf inputConf, MQDesc& inputMQDescriptor);
- bool readAndCompareSectionEventData();
+ void testFilterDataOutput();
+ // Legacy
+ bool readAndCompareSectionEventData(uint32_t filterId);
+ void startPlaybackInputThread(InputConf inputConf, MQDesc& inputMQDescriptor);
+ void startFilterEventThread(DemuxFilterEvent event);
static void* __threadLoopInput(void* threadArgs);
+ static void* __threadLoopFilter(void* threadArgs);
void inputThreadLoop(InputConf inputConf, bool* keepWritingInputFMQ, MQDesc& inputMQDescriptor);
+ void filterThreadLoop(DemuxFilterEvent& event);
+
+ void updateFilterMQ(uint32_t filterId, MQDesc& filterMQDescriptor);
+ void updateGoldenOutputMap(uint32_t filterId, string goldenOutputFile);
private:
struct InputThreadArgs {
@@ -249,22 +269,34 @@
bool* keepWritingInputFMQ;
MQDesc& inputMQDesc;
};
- bool mFilterEventReceived = false;
- std::vector<uint8_t> mDataOutputBuffer;
- std::unique_ptr<FilterMQ> mFilterMQ;
- std::unique_ptr<FilterMQ> mInputMQ;
+ struct FilterThreadArgs {
+ DemuxCallback* user;
+ DemuxFilterEvent& event;
+ };
uint16_t mDataLength = 0;
- DemuxFilterEvent mFilterEvent;
- android::Mutex mMsgLock;
- android::Mutex mReadLock;
- android::Condition mMsgCondition;
- EventFlag* mFilterMQEventFlag;
+ std::vector<uint8_t> mDataOutputBuffer;
+
+ bool mFilterEventReceived;
+ std::map<uint32_t, string> mFilterIdToGoldenOutput;
+ std::map<uint32_t, DemuxFilterEvent> mFilterIdToEvent;
+
+ std::map<uint32_t, std::unique_ptr<FilterMQ>> mFilterIdToMQ;
+ std::unique_ptr<FilterMQ> mInputMQ;
+ std::map<uint32_t, EventFlag*> mFilterIdToMQEventFlag;
EventFlag* mInputMQEventFlag;
+
+ android::Mutex mMsgLock;
+ android::Mutex mFilterOutputLock;
+ android::Condition mMsgCondition;
+ android::Condition mFilterOutputCondition;
+
bool mKeepWritingInputFMQ;
bool mInputThreadRunning;
pthread_t mInputThread;
+ pthread_t mFilterThread;
};
+// Legacy
void DemuxCallback::testOnFilterEvent(uint32_t filterId) {
android::Mutex::Autolock autoLock(mMsgLock);
while (!mFilterEventReceived) {
@@ -276,7 +308,7 @@
// Reset the filter event recieved flag
mFilterEventReceived = false;
// Check if filter id match
- EXPECT_TRUE(filterId == mFilterEvent.filterId) << "filter id match";
+ EXPECT_TRUE(filterId == mFilterIdToEvent[filterId].filterId) << "filter id match";
}
void DemuxCallback::startPlaybackInputThread(InputConf inputConf, MQDesc& inputMQDescriptor) {
@@ -291,28 +323,42 @@
pthread_setname_np(mInputThread, "test_playback_input_loop");
}
-/*void DemuxCallback::testPlaybackDataFlow(bool* keepWritingInputFMQ) {
- // timeout logic here
+void DemuxCallback::startFilterEventThread(DemuxFilterEvent event) {
+ struct FilterThreadArgs* threadArgs =
+ (struct FilterThreadArgs*)malloc(sizeof(struct FilterThreadArgs));
+ threadArgs->user = this;
+ threadArgs->event = event;
- // assemble logic here
+ pthread_create(&mFilterThread, NULL, __threadLoopFilter, (void*)threadArgs);
+ pthread_setname_np(mFilterThread, "test_playback_input_loop");
+}
+void DemuxCallback::testFilterDataOutput() {
+ android::Mutex::Autolock autoLock(mFilterOutputLock);
+ while (!mFilterIdToMQ.empty()) {
+ if (-ETIMEDOUT == mFilterOutputCondition.waitRelative(mFilterOutputLock, WAIT_TIMEOUT)) {
+ EXPECT_TRUE(false) << "filter output does not match golden output within timeout";
+ return;
+ }
+ }
+}
-}*/
-
+// Legacy
void DemuxCallback::testOnSectionFilterEvent(sp<IDemux>& demux, uint32_t filterId,
MQDesc& filterMQDescriptor,
MQDesc& inputMQDescriptor) {
Result status;
// Create MQ to read the output into the local buffer
- mFilterMQ = std::make_unique<FilterMQ>(filterMQDescriptor, true /* resetPointers */);
- EXPECT_TRUE(mFilterMQ);
+ mFilterIdToMQ[filterId] =
+ std::make_unique<FilterMQ>(filterMQDescriptor, true /* resetPointers */);
+ EXPECT_TRUE(mFilterIdToMQ[filterId]);
// Get the MQ to write the input to the HAL
mInputMQ = std::make_unique<FilterMQ>(inputMQDescriptor, true /* resetPointers */);
EXPECT_TRUE(mInputMQ);
// Create the EventFlag that is used to signal the HAL impl that data have been
// read the Filter FMQ
- EXPECT_TRUE(EventFlag::createEventFlag(mFilterMQ->getEventFlagWord(), &mFilterMQEventFlag) ==
- android::OK);
+ EXPECT_TRUE(EventFlag::createEventFlag(mFilterIdToMQ[filterId]->getEventFlagWord(),
+ &mFilterIdToMQEventFlag[filterId]) == android::OK);
// Create the EventFlag that is used to signal the HAL impl that data have been
// written into the Input FMQ
EXPECT_TRUE(EventFlag::createEventFlag(mInputMQ->getEventFlagWord(), &mInputMQEventFlag) ==
@@ -329,21 +375,24 @@
mInputMQEventFlag->wake(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_READY));
testOnFilterEvent(filterId);
// checksum of mDataOutputBuffer and Input golden input
- if (readAndCompareSectionEventData() && i < SECTION_READ_COUNT - 1) {
- mFilterMQEventFlag->wake(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_CONSUMED));
+ if (readAndCompareSectionEventData(filterId) && i < SECTION_READ_COUNT - 1) {
+ mFilterIdToMQEventFlag[filterId]->wake(
+ static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_CONSUMED));
}
}
}
-bool DemuxCallback::readAndCompareSectionEventData() {
+// Legacy
+bool DemuxCallback::readAndCompareSectionEventData(uint32_t filterId) {
bool result = false;
- for (int i = 0; i < mFilterEvent.events.size(); i++) {
- DemuxFilterSectionEvent event = mFilterEvent.events[i].section();
+ DemuxFilterEvent filterEvent = mFilterIdToEvent[filterId];
+ for (int i = 0; i < filterEvent.events.size(); i++) {
+ DemuxFilterSectionEvent event = filterEvent.events[i].section();
mDataLength = event.dataLength;
EXPECT_TRUE(mDataLength == goldenDataOutputBuffer.size()) << "buffer size does not match";
mDataOutputBuffer.resize(mDataLength);
- result = mFilterMQ->read(mDataOutputBuffer.data(), mDataLength);
+ result = mFilterIdToMQ[filterId]->read(mDataOutputBuffer.data(), mDataLength);
EXPECT_TRUE(result) << "can't read from Filter MQ";
for (int i = 0; i < mDataLength; i++) {
@@ -353,6 +402,18 @@
return result;
}
+void DemuxCallback::updateFilterMQ(uint32_t filterId, MQDesc& filterMQDescriptor) {
+ mFilterIdToMQ[filterId] =
+ std::make_unique<FilterMQ>(filterMQDescriptor, true /* resetPointers */);
+ EXPECT_TRUE(mFilterIdToMQ[filterId]);
+ EXPECT_TRUE(EventFlag::createEventFlag(mFilterIdToMQ[filterId]->getEventFlagWord(),
+ &mFilterIdToMQEventFlag[filterId]) == android::OK);
+}
+
+void DemuxCallback::updateGoldenOutputMap(uint32_t filterId, string goldenOutputFile) {
+ mFilterIdToGoldenOutput[filterId] = goldenOutputFile;
+}
+
void* DemuxCallback::__threadLoopInput(void* threadArgs) {
DemuxCallback* const self =
static_cast<DemuxCallback*>(((struct InputThreadArgs*)threadArgs)->user);
@@ -413,6 +474,26 @@
inputData.close();
}
+void* DemuxCallback::__threadLoopFilter(void* threadArgs) {
+ DemuxCallback* const self =
+ static_cast<DemuxCallback*>(((struct FilterThreadArgs*)threadArgs)->user);
+ self->filterThreadLoop(((struct FilterThreadArgs*)threadArgs)->event);
+ return 0;
+}
+
+void DemuxCallback::filterThreadLoop(DemuxFilterEvent& /*event*/) {
+ android::Mutex::Autolock autoLock(mFilterOutputLock);
+ // Read from MQ[event.filterId] per event and filter type
+
+ // Assemble to filterOutput[filterId]
+
+ // check if filterOutput[filterId] matches goldenOutput[filterId]
+
+ // If match, remove filterId entry from MQ map
+
+ // end thread
+}
+
// Test environment for Tuner HIDL HAL.
class TunerHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
public:
@@ -462,16 +543,19 @@
::testing::AssertionResult createDemuxWithFrontend(int32_t frontendId);
::testing::AssertionResult getInputMQDescriptor();
::testing::AssertionResult addInputToDemux(DemuxInputSettings setting);
- ::testing::AssertionResult addSectionFilterToDemux();
::testing::AssertionResult addFilterToDemux(DemuxFilterType type, DemuxFilterSettings setting);
::testing::AssertionResult getFilterMQDescriptor(const uint32_t filterId);
::testing::AssertionResult closeDemux();
::testing::AssertionResult createDescrambler();
::testing::AssertionResult closeDescrambler();
- ::testing::AssertionResult readSectionFilterDataOutput();
::testing::AssertionResult playbackDataFlowTest(vector<FilterConf> filterConf,
- InputConf inputConf, string goldenOutput);
+ InputConf inputConf,
+ vector<string> goldenOutputFiles);
+
+ // Legacy
+ ::testing::AssertionResult addSectionFilterToDemux();
+ ::testing::AssertionResult readSectionFilterDataOutput();
};
::testing::AssertionResult TunerHidlTest::createFrontend(int32_t frontendId) {
@@ -507,8 +591,6 @@
FrontendDvbtSettings frontendDvbtSettings{
.frequency = 0,
- .modulation = FrontendAtscModulation::UNDEFINED,
- .fec = FrontendInnerFec::FEC_UNDEFINED,
};
frontendSettings.dvbt(frontendDvbtSettings);
mFrontendCallback->testOnEvent(mFrontend, frontendSettings);
@@ -650,6 +732,7 @@
return ::testing::AssertionResult(status == Result::SUCCESS);
}
+// Legacy
::testing::AssertionResult TunerHidlTest::addSectionFilterToDemux() {
Result status;
@@ -717,6 +800,7 @@
return ::testing::AssertionResult(status == Result::SUCCESS);
}
+// Legacy
::testing::AssertionResult TunerHidlTest::readSectionFilterDataOutput() {
// Filter Configuration Module
DemuxInputSettings setting{
@@ -744,7 +828,7 @@
::testing::AssertionResult TunerHidlTest::playbackDataFlowTest(vector<FilterConf> filterConf,
InputConf inputConf,
- string /*goldenOutput*/) {
+ vector<string> goldenOutputFiles) {
Result status;
// Filter Configuration Module
for (int i = 0; i < filterConf.size(); i++) {
@@ -754,6 +838,12 @@
getFilterMQDescriptor(mFilterId) == ::testing::AssertionFailure()) {
return ::testing::AssertionFailure();
}
+ mDemuxCallback->updateFilterMQ(mFilterId, mFilterMQDescriptor);
+ mDemuxCallback->updateGoldenOutputMap(mFilterId, goldenOutputFiles[i]);
+ status = mDemux->startFilter(mFilterId);
+ if (status != Result::SUCCESS) {
+ return ::testing::AssertionFailure();
+ }
}
// Playback Input Module
@@ -769,12 +859,9 @@
}
// Data Verify Module
- // golden output, created FMQ to read and EventFlags to DATA_CONSUMED
- // Maintain each filter's real output (and how to assemble?????)
- // mDemuxCallback->testPlaybackDataFlow();
+ mDemuxCallback->testFilterDataOutput();
// Clean Up Module
- // TODO what about remove input, remove filters
return closeDemux();
}