Merge "Add three vendor properties for e2e test"
diff --git a/Android.bp b/Android.bp
index 927e227..dd84737 100644
--- a/Android.bp
+++ b/Android.bp
@@ -24,6 +24,11 @@
"VtsHalHidlTargetTestBase",
"libhidl-gen-utils",
],
+
+ header_libs: [
+ "libhidl_gtest_helpers",
+ ],
+
group_static_libs: true,
// Lists all system dependencies that can be expected on the device.
@@ -33,8 +38,6 @@
"libcutils",
"liblog",
"libhidlbase",
- "libhidltransport",
- "libhwbinder",
"libutils",
],
cflags: [
diff --git a/atrace/1.0/default/Android.bp b/atrace/1.0/default/Android.bp
index bcaf064..4bbbdb3 100644
--- a/atrace/1.0/default/Android.bp
+++ b/atrace/1.0/default/Android.bp
@@ -29,7 +29,6 @@
"libbase",
"libutils",
"libhidlbase",
- "libhidltransport",
"android.hardware.atrace@1.0",
],
}
diff --git a/audio/common/all-versions/default/service/Android.mk b/audio/common/all-versions/default/service/Android.mk
index b57a1ae..236f1fd 100644
--- a/audio/common/all-versions/default/service/Android.mk
+++ b/audio/common/all-versions/default/service/Android.mk
@@ -34,11 +34,9 @@
libcutils \
libbinder \
libhidlbase \
- libhidltransport \
liblog \
libutils \
libhardware \
- libhwbinder \
android.hardware.audio@2.0 \
android.hardware.audio@4.0 \
android.hardware.audio@5.0 \
diff --git a/audio/core/all-versions/default/Android.bp b/audio/core/all-versions/default/Android.bp
index 3283223..c4548c3 100644
--- a/audio/core/all-versions/default/Android.bp
+++ b/audio/core/all-versions/default/Android.bp
@@ -25,7 +25,6 @@
"libfmq",
"libhardware",
"libhidlbase",
- "libhidltransport",
"liblog",
"libmedia_helper",
"libutils",
diff --git a/audio/effect/all-versions/default/Android.bp b/audio/effect/all-versions/default/Android.bp
index f23a463..653b30c 100644
--- a/audio/effect/all-versions/default/Android.bp
+++ b/audio/effect/all-versions/default/Android.bp
@@ -28,7 +28,6 @@
"libfmq",
"libhidlbase",
"libhidlmemory",
- "libhidltransport",
"liblog",
"libutils",
"android.hardware.audio.common-util",
diff --git a/authsecret/1.0/default/Android.bp b/authsecret/1.0/default/Android.bp
index 5c3234f..b6ea3c4 100644
--- a/authsecret/1.0/default/Android.bp
+++ b/authsecret/1.0/default/Android.bp
@@ -13,7 +13,6 @@
],
shared_libs: [
"libhidlbase",
- "libhidltransport",
"liblog",
"libutils",
"android.hardware.authsecret@1.0",
diff --git a/automotive/audiocontrol/1.0/default/Android.bp b/automotive/audiocontrol/1.0/default/Android.bp
index 0e074dd..314830b 100644
--- a/automotive/audiocontrol/1.0/default/Android.bp
+++ b/automotive/audiocontrol/1.0/default/Android.bp
@@ -26,7 +26,6 @@
shared_libs: [
"android.hardware.automotive.audiocontrol@1.0",
"libhidlbase",
- "libhidltransport",
"liblog",
"libutils",
],
diff --git a/automotive/evs/1.0/default/Android.bp b/automotive/evs/1.0/default/Android.bp
index 7286478..69bb721 100644
--- a/automotive/evs/1.0/default/Android.bp
+++ b/automotive/evs/1.0/default/Android.bp
@@ -18,7 +18,6 @@
"libcutils",
"libhardware",
"libhidlbase",
- "libhidltransport",
"liblog",
"libui",
"libutils",
diff --git a/automotive/vehicle/2.0/default/Android.bp b/automotive/vehicle/2.0/default/Android.bp
index a11d452..3fd0539 100644
--- a/automotive/vehicle/2.0/default/Android.bp
+++ b/automotive/vehicle/2.0/default/Android.bp
@@ -16,7 +16,6 @@
name: "vhal_v2_0_defaults",
shared_libs: [
"libhidlbase",
- "libhidltransport",
"liblog",
"libutils",
"android.hardware.automotive.vehicle@2.0",
diff --git a/biometrics/face/1.0/vts/functional/VtsHalBiometricsFaceV1_0TargetTest.cpp b/biometrics/face/1.0/vts/functional/VtsHalBiometricsFaceV1_0TargetTest.cpp
index d3d7387..a4e95ed 100644
--- a/biometrics/face/1.0/vts/functional/VtsHalBiometricsFaceV1_0TargetTest.cpp
+++ b/biometrics/face/1.0/vts/functional/VtsHalBiometricsFaceV1_0TargetTest.cpp
@@ -64,7 +64,7 @@
// The error passed to the last onError() callback.
FaceError error;
- // The userId passed to the last onRemoved() callback.
+ // The userId passed to the last callback.
int32_t userId;
};
@@ -74,24 +74,32 @@
class FaceCallback : public ::testing::VtsHalHidlTargetCallbackBase<FaceCallbackArgs>,
public IBiometricsFaceClientCallback {
public:
- Return<void> onEnrollResult(uint64_t, uint32_t, int32_t, uint32_t) override {
- NotifyFromCallback(kCallbackNameOnEnrollResult);
+ Return<void> onEnrollResult(uint64_t, uint32_t, int32_t userId, uint32_t) override {
+ FaceCallbackArgs args = {};
+ args.userId = userId;
+ NotifyFromCallback(kCallbackNameOnEnrollResult, args);
return Void();
}
- Return<void> onAuthenticated(uint64_t, uint32_t, int32_t, const hidl_vec<uint8_t>&) override {
- NotifyFromCallback(kCallbackNameOnAuthenticated);
+ Return<void> onAuthenticated(uint64_t, uint32_t, int32_t userId,
+ const hidl_vec<uint8_t>&) override {
+ FaceCallbackArgs args = {};
+ args.userId = userId;
+ NotifyFromCallback(kCallbackNameOnAuthenticated, args);
return Void();
}
- Return<void> onAcquired(uint64_t, int32_t, FaceAcquiredInfo, int32_t) override {
- NotifyFromCallback(kCallbackNameOnAcquired);
+ Return<void> onAcquired(uint64_t, int32_t userId, FaceAcquiredInfo, int32_t) override {
+ FaceCallbackArgs args = {};
+ args.userId = userId;
+ NotifyFromCallback(kCallbackNameOnAcquired, args);
return Void();
}
- Return<void> onError(uint64_t, int32_t, FaceError error, int32_t) override {
+ Return<void> onError(uint64_t, int32_t userId, FaceError error, int32_t) override {
FaceCallbackArgs args = {};
args.error = error;
+ args.userId = userId;
NotifyFromCallback(kCallbackNameOnError, args);
return Void();
}
@@ -103,8 +111,10 @@
return Void();
}
- Return<void> onEnumerate(uint64_t, const hidl_vec<uint32_t>&, int32_t) override {
- NotifyFromCallback(kCallbackNameOnEnumerate);
+ Return<void> onEnumerate(uint64_t, const hidl_vec<uint32_t>&, int32_t userId) override {
+ FaceCallbackArgs args = {};
+ args.userId = userId;
+ NotifyFromCallback(kCallbackNameOnEnumerate, args);
return Void();
}
@@ -185,6 +195,7 @@
// onError should be called with a meaningful (nonzero) error.
auto res = mCallback->WaitForCallback(kCallbackNameOnError);
EXPECT_TRUE(res.no_timeout);
+ EXPECT_EQ(kUserId, res.args->userId);
EXPECT_EQ(FaceError::UNABLE_TO_PROCESS, res.args->error);
}
@@ -205,6 +216,7 @@
// onError should be called with a meaningful (nonzero) error.
auto res = mCallback->WaitForCallback(kCallbackNameOnError);
EXPECT_TRUE(res.no_timeout);
+ EXPECT_EQ(kUserId, res.args->userId);
EXPECT_EQ(FaceError::UNABLE_TO_PROCESS, res.args->error);
}
@@ -271,6 +283,7 @@
Return<Status> ret = mService->enumerate();
ASSERT_EQ(Status::OK, static_cast<Status>(ret));
auto res = mCallback->WaitForCallback(kCallbackNameOnEnumerate);
+ EXPECT_EQ(kUserId, res.args->userId);
EXPECT_TRUE(res.no_timeout);
}
@@ -330,6 +343,7 @@
auto res = mCallback->WaitForCallback(kCallbackNameOnError);
// make sure callback was invoked within kRevokeChallengeTimeout
EXPECT_TRUE(res.no_timeout);
+ EXPECT_EQ(kUserId, res.args->userId);
EXPECT_EQ(FaceError::CANCELED, res.args->error);
}
diff --git a/biometrics/fingerprint/2.1/default/Android.bp b/biometrics/fingerprint/2.1/default/Android.bp
index b12ce61..497fa3f 100644
--- a/biometrics/fingerprint/2.1/default/Android.bp
+++ b/biometrics/fingerprint/2.1/default/Android.bp
@@ -13,7 +13,6 @@
"libcutils",
"liblog",
"libhidlbase",
- "libhidltransport",
"libhardware",
"libutils",
"android.hardware.biometrics.fingerprint@2.1",
diff --git a/bluetooth/1.0/default/Android.bp b/bluetooth/1.0/default/Android.bp
index f4b1e7b..f66c25e 100644
--- a/bluetooth/1.0/default/Android.bp
+++ b/bluetooth/1.0/default/Android.bp
@@ -29,7 +29,6 @@
"libcutils",
"libhardware",
"libhidlbase",
- "libhidltransport",
"liblog",
"libutils",
],
@@ -130,7 +129,6 @@
"libutils",
"libhardware",
"libhidlbase",
- "libhidltransport",
"android.hardware.bluetooth@1.0",
],
}
diff --git a/bluetooth/a2dp/1.0/default/Android.bp b/bluetooth/a2dp/1.0/default/Android.bp
index 8e6f32d..5264899 100644
--- a/bluetooth/a2dp/1.0/default/Android.bp
+++ b/bluetooth/a2dp/1.0/default/Android.bp
@@ -1,5 +1,5 @@
cc_library_shared {
- name: "android.hardware.bluetooth.a2dp@1.0-impl",
+ name: "android.hardware.bluetooth.a2dp@1.0-impl.mock",
relative_install_path: "hw",
vendor: true,
srcs: [
@@ -7,7 +7,6 @@
],
shared_libs: [
"libhidlbase",
- "libhidltransport",
"libutils",
"android.hardware.bluetooth.a2dp@1.0",
],
diff --git a/bluetooth/audio/2.0/default/Android.bp b/bluetooth/audio/2.0/default/Android.bp
index 1dfc05d..0db0028 100644
--- a/bluetooth/audio/2.0/default/Android.bp
+++ b/bluetooth/audio/2.0/default/Android.bp
@@ -19,7 +19,6 @@
"libcutils",
"libfmq",
"libhidlbase",
- "libhidltransport",
"liblog",
"libutils",
],
@@ -41,7 +40,6 @@
"libcutils",
"libfmq",
"libhidlbase",
- "libhidltransport",
"liblog",
"libutils",
],
diff --git a/boot/1.0/default/Android.bp b/boot/1.0/default/Android.bp
index 397c56d..fdf7a1e 100644
--- a/boot/1.0/default/Android.bp
+++ b/boot/1.0/default/Android.bp
@@ -9,7 +9,6 @@
shared_libs: [
"liblog",
"libhidlbase",
- "libhidltransport",
"libhardware",
"libutils",
"android.hardware.boot@1.0",
@@ -29,7 +28,6 @@
"liblog",
"libhardware",
"libhidlbase",
- "libhidltransport",
"libutils",
"android.hardware.boot@1.0",
],
diff --git a/broadcastradio/1.0/default/Android.bp b/broadcastradio/1.0/default/Android.bp
index f961dfd..2c96e2a 100644
--- a/broadcastradio/1.0/default/Android.bp
+++ b/broadcastradio/1.0/default/Android.bp
@@ -31,7 +31,6 @@
],
shared_libs: [
"libhidlbase",
- "libhidltransport",
"libutils",
"liblog",
"libhardware",
diff --git a/broadcastradio/1.1/default/Android.bp b/broadcastradio/1.1/default/Android.bp
index 52fb45b..3659cb9 100644
--- a/broadcastradio/1.1/default/Android.bp
+++ b/broadcastradio/1.1/default/Android.bp
@@ -41,7 +41,6 @@
"android.hardware.broadcastradio@1.1",
"libbase",
"libhidlbase",
- "libhidltransport",
"liblog",
"libutils",
],
diff --git a/broadcastradio/2.0/default/Android.bp b/broadcastradio/2.0/default/Android.bp
index 840c4b8..83eedb1 100644
--- a/broadcastradio/2.0/default/Android.bp
+++ b/broadcastradio/2.0/default/Android.bp
@@ -42,7 +42,6 @@
"android.hardware.broadcastradio@2.0",
"libbase",
"libhidlbase",
- "libhidltransport",
"libutils",
],
}
diff --git a/camera/device/1.0/default/Android.bp b/camera/device/1.0/default/Android.bp
index c3518d3..e6e6485 100644
--- a/camera/device/1.0/default/Android.bp
+++ b/camera/device/1.0/default/Android.bp
@@ -8,8 +8,6 @@
shared_libs: [
"libhidlbase",
"libhidlmemory",
- "libhidltransport",
- "libhwbinder",
"libutils",
"android.hardware.camera.device@1.0",
"android.hardware.camera.common@1.0",
diff --git a/camera/device/3.2/default/Android.bp b/camera/device/3.2/default/Android.bp
index edc2988..878878d 100644
--- a/camera/device/3.2/default/Android.bp
+++ b/camera/device/3.2/default/Android.bp
@@ -7,7 +7,6 @@
"convert.cpp"],
shared_libs: [
"libhidlbase",
- "libhidltransport",
"libutils",
"libcutils",
"android.hardware.camera.device@3.2",
diff --git a/camera/device/3.3/default/Android.bp b/camera/device/3.3/default/Android.bp
index f3c2e0e..7d51434 100644
--- a/camera/device/3.3/default/Android.bp
+++ b/camera/device/3.3/default/Android.bp
@@ -7,7 +7,6 @@
"convert.cpp"],
shared_libs: [
"libhidlbase",
- "libhidltransport",
"libutils",
"libcutils",
"camera.device@3.2-impl",
diff --git a/camera/device/3.4/default/Android.bp b/camera/device/3.4/default/Android.bp
index 8e699d8..59e8329 100644
--- a/camera/device/3.4/default/Android.bp
+++ b/camera/device/3.4/default/Android.bp
@@ -38,7 +38,6 @@
],
shared_libs: [
"libhidlbase",
- "libhidltransport",
"libutils",
"libcutils",
"camera.device@3.2-impl",
@@ -76,7 +75,6 @@
],
shared_libs: [
"libhidlbase",
- "libhidltransport",
"libutils",
"libcutils",
"camera.device@3.2-impl",
diff --git a/camera/device/3.5/default/Android.bp b/camera/device/3.5/default/Android.bp
index dde585e..1c307ee 100644
--- a/camera/device/3.5/default/Android.bp
+++ b/camera/device/3.5/default/Android.bp
@@ -37,7 +37,6 @@
],
shared_libs: [
"libhidlbase",
- "libhidltransport",
"libutils",
"libcutils",
"camera.device@3.2-impl",
@@ -72,7 +71,6 @@
],
shared_libs: [
"libhidlbase",
- "libhidltransport",
"libutils",
"libcutils",
"camera.device@3.2-impl",
diff --git a/camera/provider/2.4/default/Android.bp b/camera/provider/2.4/default/Android.bp
index 313b29b..9203b8d 100644
--- a/camera/provider/2.4/default/Android.bp
+++ b/camera/provider/2.4/default/Android.bp
@@ -25,7 +25,6 @@
"libcutils",
"libhardware",
"libhidlbase",
- "libhidltransport",
"liblog",
"libutils",
],
@@ -65,7 +64,6 @@
"libcutils",
"libhardware",
"libhidlbase",
- "libhidltransport",
"liblog",
"libtinyxml2",
"libutils",
@@ -112,7 +110,6 @@
"libcutils",
"libhardware",
"libhidlbase",
- "libhidltransport",
"liblog",
"libtinyxml2",
"libutils",
@@ -152,7 +149,6 @@
"libcamera_metadata",
"libhardware",
"libhidlbase",
- "libhidltransport",
"liblog",
"libutils",
],
@@ -217,7 +213,6 @@
"android.hardware.camera.provider@2.4",
"libbinder",
"libhidlbase",
- "libhidltransport",
"liblog",
"libtinyxml2",
"libutils",
diff --git a/camera/provider/2.5/default/Android.bp b/camera/provider/2.5/default/Android.bp
index cd1caeb..4563362 100644
--- a/camera/provider/2.5/default/Android.bp
+++ b/camera/provider/2.5/default/Android.bp
@@ -24,7 +24,6 @@
"libcutils",
"libhardware",
"libhidlbase",
- "libhidltransport",
"liblog",
"libutils",
],
@@ -64,7 +63,6 @@
"libcutils",
"libhardware",
"libhidlbase",
- "libhidltransport",
"liblog",
"libtinyxml2",
"libutils",
@@ -103,7 +101,6 @@
"libcamera_metadata",
"libhardware",
"libhidlbase",
- "libhidltransport",
"liblog",
"libutils",
],
@@ -170,7 +167,6 @@
"android.hardware.graphics.mapper@2.0",
"libbinder",
"libhidlbase",
- "libhidltransport",
"liblog",
"libtinyxml2",
"libutils",
diff --git a/cas/1.0/default/Android.bp b/cas/1.0/default/Android.bp
index aa080f4..f9977ff 100644
--- a/cas/1.0/default/Android.bp
+++ b/cas/1.0/default/Android.bp
@@ -21,7 +21,6 @@
"libbinder",
"libhidlbase",
"libhidlmemory",
- "libhidltransport",
"liblog",
"libstagefright_foundation",
"libutils",
diff --git a/cas/1.0/vts/functional/VtsHalCasV1_0TargetTest.cpp b/cas/1.0/vts/functional/VtsHalCasV1_0TargetTest.cpp
index 14b8bbd..f0bba57 100644
--- a/cas/1.0/vts/functional/VtsHalCasV1_0TargetTest.cpp
+++ b/cas/1.0/vts/functional/VtsHalCasV1_0TargetTest.cpp
@@ -325,7 +325,7 @@
return ::testing::AssertionFailure();
}
- uint8_t* ipBuffer = static_cast<uint8_t*>(static_cast<void*>(mem->pointer()));
+ uint8_t* ipBuffer = static_cast<uint8_t*>(static_cast<void*>(mem->unsecurePointer()));
memcpy(ipBuffer, kInBinaryBuffer, sizeof(kInBinaryBuffer));
// hidlMemory is not to be passed out of scope!
@@ -568,7 +568,7 @@
EXPECT_EQ(Status::OK, descrambleStatus);
ASSERT_NE(nullptr, dataMemory.get());
- uint8_t* opBuffer = static_cast<uint8_t*>(static_cast<void*>(dataMemory->pointer()));
+ uint8_t* opBuffer = static_cast<uint8_t*>(static_cast<void*>(dataMemory->unsecurePointer()));
int compareResult =
memcmp(static_cast<const void*>(opBuffer), static_cast<const void*>(kOutRefBinaryBuffer),
diff --git a/cas/1.1/default/Android.bp b/cas/1.1/default/Android.bp
index 68a49cf..66a1eb8 100644
--- a/cas/1.1/default/Android.bp
+++ b/cas/1.1/default/Android.bp
@@ -22,7 +22,6 @@
"libbinder",
"libhidlbase",
"libhidlmemory",
- "libhidltransport",
"liblog",
"libutils",
],
diff --git a/cas/1.1/vts/functional/VtsHalCasV1_1TargetTest.cpp b/cas/1.1/vts/functional/VtsHalCasV1_1TargetTest.cpp
index 88f1fb0..0264bdd 100644
--- a/cas/1.1/vts/functional/VtsHalCasV1_1TargetTest.cpp
+++ b/cas/1.1/vts/functional/VtsHalCasV1_1TargetTest.cpp
@@ -366,7 +366,7 @@
return ::testing::AssertionFailure();
}
- uint8_t* ipBuffer = static_cast<uint8_t*>(static_cast<void*>(mem->pointer()));
+ uint8_t* ipBuffer = static_cast<uint8_t*>(static_cast<void*>(mem->unsecurePointer()));
memcpy(ipBuffer, kInBinaryBuffer, sizeof(kInBinaryBuffer));
// hidlMemory is not to be passed out of scope!
@@ -543,7 +543,7 @@
EXPECT_EQ(Status::OK, descrambleStatus);
ASSERT_NE(nullptr, dataMemory.get());
- uint8_t* opBuffer = static_cast<uint8_t*>(static_cast<void*>(dataMemory->pointer()));
+ uint8_t* opBuffer = static_cast<uint8_t*>(static_cast<void*>(dataMemory->unsecurePointer()));
int compareResult =
memcmp(static_cast<const void*>(opBuffer),
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 3e83cdc..ef1cd75 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -426,7 +426,7 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.thermal</name>
- <version>1.0-1</version>
+ <version>1.0</version>
<version>2.0</version>
<interface>
<name>IThermal</name>
@@ -491,7 +491,7 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.wifi</name>
- <version>1.0-3</version>
+ <version>1.0-4</version>
<interface>
<name>IWifi</name>
<instance>default</instance>
diff --git a/configstore/1.1/default/Android.mk b/configstore/1.1/default/Android.mk
index 104e15e..e7edc34 100644
--- a/configstore/1.1/default/Android.mk
+++ b/configstore/1.1/default/Android.mk
@@ -17,7 +17,6 @@
LOCAL_SHARED_LIBRARIES := \
libhidlbase \
- libhidltransport \
libbase \
libhwminijail \
liblog \
diff --git a/confirmationui/1.0/default/Android.bp b/confirmationui/1.0/default/Android.bp
index 10018e8..ecba064 100644
--- a/confirmationui/1.0/default/Android.bp
+++ b/confirmationui/1.0/default/Android.bp
@@ -36,7 +36,6 @@
"libcrypto",
"libbase",
"libhidlbase",
- "libhidltransport",
"liblog",
"libutils",
],
diff --git a/contexthub/1.0/default/Android.bp b/contexthub/1.0/default/Android.bp
index d1db6a6..8384037 100644
--- a/contexthub/1.0/default/Android.bp
+++ b/contexthub/1.0/default/Android.bp
@@ -28,7 +28,6 @@
"libcutils",
"libutils",
"libhidlbase",
- "libhidltransport",
"android.hardware.contexthub@1.0",
],
}
@@ -47,7 +46,6 @@
"libdl",
"libhardware",
"libhidlbase",
- "libhidltransport",
"liblog",
"libutils",
"android.hardware.contexthub@1.0",
diff --git a/current.txt b/current.txt
index c7b0d9e..83657b2 100644
--- a/current.txt
+++ b/current.txt
@@ -574,7 +574,8 @@
# ABI preserving changes to HALs during Android R
2410dd02d67786a732d36e80b0f8ccf55086604ef37f9838e2013ff2c571e404 android.hardware.camera.device@3.5::types
b69a7615c508acf5c5201efd1bfa3262167874fc3594e2db5a3ff93addd8ac75 android.hardware.keymaster@4.0::IKeymasterDevice
-ad431c8de51c07934a068e3043d8dd0537ac4d3158627706628b123f42df48dc android.hardware.neuralnetworks@1.0::IPreparedModel
-aafcc10cf04ab247e86d4582586c71c6b4c2b8c479241ffa7fe37deb659fc942 android.hardware.neuralnetworks@1.2::IPreparedModel
+eb2fa0c883c2185d514be0b84c179b283753ef0c1b77b45b4f359bd23bba8b75 android.hardware.neuralnetworks@1.0::IPreparedModel
+fb382e986c10b8fbb797a8546e8f9ea6d1107bfe6f3fb7e57f6bbbf1f807a906 android.hardware.neuralnetworks@1.2::IDevice
+40e71cd693de5b832325c5d8f081f2ff20a7ba2b89d401cee5b4b3eb0e241681 android.hardware.neuralnetworks@1.2::IPreparedModel
1a6e2bd289f22931c526b21916910f1d4c436b7acb9556e4243de4ce8e6cc2e4 android.hardware.soundtrigger@2.0::ISoundTriggerHwCallback
fd65298e1e09e0e3c781ab18305920d757dbe55a3b459ce17814ec5cf6dfee99 android.hardware.wifi@1.0::IWifiP2pIface
diff --git a/drm/1.0/default/Android.mk b/drm/1.0/default/Android.mk
index d66f377..9016dc3 100644
--- a/drm/1.0/default/Android.mk
+++ b/drm/1.0/default/Android.mk
@@ -59,7 +59,6 @@
libcutils \
libhidlbase \
libhidlmemory \
- libhidltransport \
liblog \
libstagefright_foundation \
libutils \
diff --git a/drm/1.0/default/CryptoPlugin.cpp b/drm/1.0/default/CryptoPlugin.cpp
index 666653b..8ddc380 100644
--- a/drm/1.0/default/CryptoPlugin.cpp
+++ b/drm/1.0/default/CryptoPlugin.cpp
@@ -101,11 +101,20 @@
std::unique_ptr<android::CryptoPlugin::SubSample[]> legacySubSamples =
std::make_unique<android::CryptoPlugin::SubSample[]>(subSamples.size());
+ size_t destSize = 0;
for (size_t i = 0; i < subSamples.size(); i++) {
- legacySubSamples[i].mNumBytesOfClearData
- = subSamples[i].numBytesOfClearData;
- legacySubSamples[i].mNumBytesOfEncryptedData
- = subSamples[i].numBytesOfEncryptedData;
+ uint32_t numBytesOfClearData = subSamples[i].numBytesOfClearData;
+ legacySubSamples[i].mNumBytesOfClearData = numBytesOfClearData;
+ uint32_t numBytesOfEncryptedData = subSamples[i].numBytesOfEncryptedData;
+ legacySubSamples[i].mNumBytesOfEncryptedData = numBytesOfEncryptedData;
+ if (__builtin_add_overflow(destSize, numBytesOfClearData, &destSize)) {
+ _hidl_cb(Status::BAD_VALUE, 0, "subsample clear size overflow");
+ return Void();
+ }
+ if (__builtin_add_overflow(destSize, numBytesOfEncryptedData, &destSize)) {
+ _hidl_cb(Status::BAD_VALUE, 0, "subsample encrypted size overflow");
+ return Void();
+ }
}
AString detailMessage;
@@ -137,11 +146,24 @@
_hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
return Void();
}
+
+ if (destSize > destBuffer.size) {
+ _hidl_cb(Status::BAD_VALUE, 0, "subsample sum too large");
+ return Void();
+ }
+
destPtr = static_cast<void *>(base + destination.nonsecureMemory.offset);
} else if (destination.type == BufferType::NATIVE_HANDLE) {
+ if (!secure) {
+ _hidl_cb(Status::BAD_VALUE, 0, "native handle destination must be secure");
+ return Void();
+ }
native_handle_t *handle = const_cast<native_handle_t *>(
destination.secureMemory.getNativeHandle());
destPtr = static_cast<void *>(handle);
+ } else {
+ _hidl_cb(Status::BAD_VALUE, 0, "invalid destination type");
+ return Void();
}
ssize_t result = mLegacyPlugin->decrypt(secure, keyId.data(), iv.data(),
legacyMode, legacyPattern, srcPtr, legacySubSamples.get(),
diff --git a/drm/1.0/default/common_default_service.mk b/drm/1.0/default/common_default_service.mk
index 28db567..1b5a975 100644
--- a/drm/1.0/default/common_default_service.mk
+++ b/drm/1.0/default/common_default_service.mk
@@ -21,7 +21,6 @@
android.hardware.drm@1.0 \
android.hidl.memory@1.0 \
libhidlbase \
- libhidltransport \
libhardware \
liblog \
libutils \
diff --git a/drm/1.1/vts/functional/Android.bp b/drm/1.1/vts/functional/Android.bp
index 1090b69..47b02bf 100644
--- a/drm/1.1/vts/functional/Android.bp
+++ b/drm/1.1/vts/functional/Android.bp
@@ -29,7 +29,6 @@
"libhidlmemory",
"libnativehelper",
"libssl",
- "libcrypto",
],
test_suites: ["general-tests"],
}
diff --git a/dumpstate/1.0/default/Android.bp b/dumpstate/1.0/default/Android.bp
index 3ca19e8..6b02715 100644
--- a/dumpstate/1.0/default/Android.bp
+++ b/dumpstate/1.0/default/Android.bp
@@ -1,5 +1,5 @@
cc_binary {
- name: "android.hardware.dumpstate@1.0-service",
+ name: "android.hardware.dumpstate@1.0-service.example",
init_rc: ["android.hardware.dumpstate@1.0-service.rc"],
relative_install_path: "hw",
vendor: true,
@@ -18,7 +18,6 @@
"libcutils",
"libdumpstateutil",
"libhidlbase",
- "libhidltransport",
"liblog",
"libutils",
],
diff --git a/dumpstate/1.0/default/android.hardware.dumpstate@1.0-service.rc b/dumpstate/1.0/default/android.hardware.dumpstate@1.0-service.rc
index 062a291..03298dc 100644
--- a/dumpstate/1.0/default/android.hardware.dumpstate@1.0-service.rc
+++ b/dumpstate/1.0/default/android.hardware.dumpstate@1.0-service.rc
@@ -1,4 +1,4 @@
-service vendor.dumpstate-1-0 /vendor/bin/hw/android.hardware.dumpstate@1.0-service
+service vendor.dumpstate-1-0 /vendor/bin/hw/android.hardware.dumpstate@1.0-service.example
class hal
user system
group system
diff --git a/fastboot/1.0/default/Android.bp b/fastboot/1.0/default/Android.bp
index fde7efa..f7b3635 100644
--- a/fastboot/1.0/default/Android.bp
+++ b/fastboot/1.0/default/Android.bp
@@ -23,7 +23,6 @@
shared_libs: [
"libbase",
"libhidlbase",
- "libhidltransport",
"libutils",
"libcutils",
"android.hardware.fastboot@1.0",
diff --git a/gatekeeper/1.0/default/Android.bp b/gatekeeper/1.0/default/Android.bp
index ae3b91c..2be4f4d 100644
--- a/gatekeeper/1.0/default/Android.bp
+++ b/gatekeeper/1.0/default/Android.bp
@@ -10,7 +10,6 @@
"android.hardware.gatekeeper@1.0",
"libhardware",
"libhidlbase",
- "libhidltransport",
"libutils",
"liblog",
],
@@ -30,7 +29,6 @@
"android.hardware.gatekeeper@1.0",
"libhardware",
"libhidlbase",
- "libhidltransport",
"libutils",
"liblog",
],
diff --git a/gatekeeper/1.0/software/Android.bp b/gatekeeper/1.0/software/Android.bp
index 148c989..24c81f6 100644
--- a/gatekeeper/1.0/software/Android.bp
+++ b/gatekeeper/1.0/software/Android.bp
@@ -15,7 +15,6 @@
"libbase",
"libhardware",
"libhidlbase",
- "libhidltransport",
"libutils",
"liblog",
"libcrypto",
diff --git a/gnss/1.0/default/Android.bp b/gnss/1.0/default/Android.bp
index ca495e6..57d8903 100644
--- a/gnss/1.0/default/Android.bp
+++ b/gnss/1.0/default/Android.bp
@@ -22,7 +22,6 @@
shared_libs: [
"liblog",
"libhidlbase",
- "libhidltransport",
"libutils",
"android.hardware.gnss@1.0",
"libhardware",
@@ -47,7 +46,6 @@
"libhardware",
"libbinder",
"libhidlbase",
- "libhidltransport",
"android.hardware.gnss@1.0",
],
diff --git a/gnss/1.1/default/Android.bp b/gnss/1.1/default/Android.bp
index 8c3aac4..95bd7f3 100644
--- a/gnss/1.1/default/Android.bp
+++ b/gnss/1.1/default/Android.bp
@@ -12,7 +12,6 @@
],
shared_libs: [
"libhidlbase",
- "libhidltransport",
"libutils",
"liblog",
"android.hardware.gnss@1.1",
diff --git a/gnss/2.0/default/Android.bp b/gnss/2.0/default/Android.bp
index 0fcd764..3ba89da 100644
--- a/gnss/2.0/default/Android.bp
+++ b/gnss/2.0/default/Android.bp
@@ -33,7 +33,6 @@
],
shared_libs: [
"libhidlbase",
- "libhidltransport",
"libutils",
"liblog",
"android.hardware.gnss@2.0",
diff --git a/graphics/allocator/2.0/default/Android.bp b/graphics/allocator/2.0/default/Android.bp
index 9980ae0..59229b0 100644
--- a/graphics/allocator/2.0/default/Android.bp
+++ b/graphics/allocator/2.0/default/Android.bp
@@ -13,7 +13,6 @@
"libcutils",
"libhardware",
"libhidlbase",
- "libhidltransport",
"liblog",
"libutils",
],
@@ -31,7 +30,6 @@
shared_libs: [
"android.hardware.graphics.allocator@2.0",
"libhidlbase",
- "libhidltransport",
"liblog",
"libutils",
],
diff --git a/graphics/composer/2.1/default/Android.bp b/graphics/composer/2.1/default/Android.bp
index c4feae5..533687b 100644
--- a/graphics/composer/2.1/default/Android.bp
+++ b/graphics/composer/2.1/default/Android.bp
@@ -15,7 +15,6 @@
"libfmq",
"libhardware",
"libhidlbase",
- "libhidltransport",
"liblog",
"libsync",
"libutils",
@@ -38,7 +37,6 @@
"android.hardware.graphics.composer@2.1",
"libbinder",
"libhidlbase",
- "libhidltransport",
"liblog",
"libsync",
"libutils",
diff --git a/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/Composer.h b/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/Composer.h
index 62a163c..4b8c6bb 100644
--- a/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/Composer.h
+++ b/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/Composer.h
@@ -67,6 +67,14 @@
}
}
+ // we do not have HWC2_CAPABILITY_SKIP_VALIDATE defined in
+ // IComposer::Capability. However, this is defined in hwcomposer2.h,
+ // so if the device returns it, add it manually to be returned to the
+ // client
+ if (mHal->hasCapability(HWC2_CAPABILITY_SKIP_VALIDATE)) {
+ caps.push_back(static_cast<IComposer::Capability>(HWC2_CAPABILITY_SKIP_VALIDATE));
+ }
+
hidl_vec<IComposer::Capability> caps_reply;
caps_reply.setToExternal(caps.data(), caps.size());
hidl_cb(caps_reply);
diff --git a/graphics/composer/2.1/utils/hwc2on1adapter/Android.bp b/graphics/composer/2.1/utils/hwc2on1adapter/Android.bp
index 062f2e5..0af9745 100644
--- a/graphics/composer/2.1/utils/hwc2on1adapter/Android.bp
+++ b/graphics/composer/2.1/utils/hwc2on1adapter/Android.bp
@@ -55,6 +55,7 @@
"-Wno-shorten-64-to-32",
"-Wno-sign-compare",
"-Wno-missing-prototypes",
+ "-Wno-format-pedantic",
],
srcs: [
diff --git a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
index 5d2f65d..9477ee6 100644
--- a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
+++ b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
@@ -20,6 +20,7 @@
#include <composer-vts/2.1/ComposerVts.h>
#include <composer-vts/2.1/GraphicsComposerCallback.h>
#include <composer-vts/2.1/TestCommandReader.h>
+#include <hardware/hwcomposer2.h>
#include <mapper-vts/2.0/MapperVts.h>
#include <mapper-vts/3.0/MapperVts.h>
#include <mapper-vts/4.0/MapperVts.h>
@@ -789,6 +790,12 @@
* surface damage have been set
*/
TEST_F(GraphicsComposerHidlCommandTest, PRESENT_DISPLAY_NO_LAYER_STATE_CHANGES) {
+ if (!mComposer->hasCapability(
+ static_cast<IComposer::Capability>(HWC2_CAPABILITY_SKIP_VALIDATE))) {
+ std::cout << "Device does not have skip validate capability, skipping" << std::endl;
+ GTEST_SUCCEED();
+ return;
+ }
mWriter->selectDisplay(mPrimaryDisplay);
mComposerClient->setPowerMode(mPrimaryDisplay, IComposerClient::PowerMode::ON);
mComposerClient->setColorMode(mPrimaryDisplay, ColorMode::NATIVE);
diff --git a/graphics/composer/2.2/default/Android.mk b/graphics/composer/2.2/default/Android.mk
index cb551c6..156ecb6 100644
--- a/graphics/composer/2.2/default/Android.mk
+++ b/graphics/composer/2.2/default/Android.mk
@@ -19,7 +19,6 @@
libfmq \
libhardware \
libhidlbase \
- libhidltransport \
libhwc2on1adapter \
libhwc2onfbadapter \
liblog \
diff --git a/graphics/composer/2.3/default/Android.bp b/graphics/composer/2.3/default/Android.bp
index 8103b89..a5696dd 100644
--- a/graphics/composer/2.3/default/Android.bp
+++ b/graphics/composer/2.3/default/Android.bp
@@ -36,7 +36,6 @@
"libfmq",
"libhardware",
"libhidlbase",
- "libhidltransport",
"libhwc2on1adapter",
"libhwc2onfbadapter",
"liblog",
diff --git a/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerClient.h b/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerClient.h
index 04530d3..041fbc8 100644
--- a/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerClient.h
+++ b/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerClient.h
@@ -184,18 +184,18 @@
}
protected:
+ using BaseType2_1 = V2_1::hal::detail::ComposerClientImpl<Interface, Hal>;
+ using BaseType2_1::mHal;
+ using BaseType2_1::mResources;
std::unique_ptr<V2_1::hal::ComposerCommandEngine> createCommandEngine() override {
return std::make_unique<ComposerCommandEngine>(
mHal, static_cast<V2_2::hal::ComposerResources*>(mResources.get()));
}
- private:
+ private:
using BaseType2_2 = V2_2::hal::detail::ComposerClientImpl<Interface, Hal>;
- using BaseType2_1 = V2_1::hal::detail::ComposerClientImpl<Interface, Hal>;
using BaseType2_1::mCommandEngine;
using BaseType2_1::mCommandEngineMutex;
- using BaseType2_1::mHal;
- using BaseType2_1::mResources;
};
} // namespace detail
diff --git a/graphics/composer/2.3/vts/functional/Android.bp b/graphics/composer/2.3/vts/functional/Android.bp
index 965c8fe..b729062 100644
--- a/graphics/composer/2.3/vts/functional/Android.bp
+++ b/graphics/composer/2.3/vts/functional/Android.bp
@@ -23,7 +23,6 @@
shared_libs: [
"libfmq",
"libhidlbase",
- "libhidltransport",
"libsync",
],
static_libs: [
diff --git a/graphics/mapper/2.0/default/Android.bp b/graphics/mapper/2.0/default/Android.bp
index 8874799..4f64184 100644
--- a/graphics/mapper/2.0/default/Android.bp
+++ b/graphics/mapper/2.0/default/Android.bp
@@ -28,7 +28,6 @@
"libcutils",
"libhardware",
"libhidlbase",
- "libhidltransport",
"liblog",
"libsync",
"libutils",
diff --git a/graphics/mapper/2.1/default/Android.bp b/graphics/mapper/2.1/default/Android.bp
index aa204a0..2ea7f94 100644
--- a/graphics/mapper/2.1/default/Android.bp
+++ b/graphics/mapper/2.1/default/Android.bp
@@ -29,7 +29,6 @@
"libcutils",
"libhardware",
"libhidlbase",
- "libhidltransport",
"liblog",
"libsync",
"libutils",
diff --git a/health/1.0/default/Android.bp b/health/1.0/default/Android.bp
index 8fbb8c3..049e393 100644
--- a/health/1.0/default/Android.bp
+++ b/health/1.0/default/Android.bp
@@ -12,7 +12,6 @@
shared_libs: [
"libcutils",
"libhidlbase",
- "libhidltransport",
"libutils",
"android.hardware.health@1.0",
],
diff --git a/health/1.0/default/Android.mk b/health/1.0/default/Android.mk
index 199ab41..bbf37af 100644
--- a/health/1.0/default/Android.mk
+++ b/health/1.0/default/Android.mk
@@ -13,7 +13,6 @@
LOCAL_SHARED_LIBRARIES := \
libcutils \
libhidlbase \
- libhidltransport \
liblog \
libutils \
android.hardware.health@1.0 \
@@ -39,7 +38,6 @@
libbase \
libutils \
libhidlbase \
- libhidltransport \
android.hardware.health@1.0 \
include $(BUILD_EXECUTABLE)
diff --git a/health/2.0/README.md b/health/2.0/README.md
index 58ea9e3..4ecfb9a 100644
--- a/health/2.0/README.md
+++ b/health/2.0/README.md
@@ -44,7 +44,6 @@
"libbase",
"libcutils",
"libhidlbase",
- "libhidltransport",
"libutils",
"android.hardware.health@2.0",
],
diff --git a/health/2.0/default/Android.bp b/health/2.0/default/Android.bp
index a85a704..1c455d3 100644
--- a/health/2.0/default/Android.bp
+++ b/health/2.0/default/Android.bp
@@ -10,8 +10,6 @@
shared_libs: [
"libbase",
"libhidlbase",
- "libhidltransport",
- "libhwbinder",
"liblog",
"libutils",
"libcutils",
diff --git a/health/storage/1.0/default/Android.bp b/health/storage/1.0/default/Android.bp
index 4723443..3156dfe 100644
--- a/health/storage/1.0/default/Android.bp
+++ b/health/storage/1.0/default/Android.bp
@@ -33,7 +33,6 @@
shared_libs: [
"libbase",
"libhidlbase",
- "libhidltransport",
"libutils",
"android.hardware.health.storage@1.0",
],
diff --git a/health/storage/1.0/vts/functional/Android.bp b/health/storage/1.0/vts/functional/Android.bp
index b18e36f..87502f8 100644
--- a/health/storage/1.0/vts/functional/Android.bp
+++ b/health/storage/1.0/vts/functional/Android.bp
@@ -21,7 +21,6 @@
static_libs: ["android.hardware.health.storage@1.0"],
shared_libs: [
"libhidlbase",
- "libhidltransport",
],
test_suites: ["general-tests"],
}
diff --git a/input/classifier/1.0/default/Android.bp b/input/classifier/1.0/default/Android.bp
index ceb2aca..3379a76 100644
--- a/input/classifier/1.0/default/Android.bp
+++ b/input/classifier/1.0/default/Android.bp
@@ -11,7 +11,6 @@
shared_libs: [
"android.hardware.input.classifier@1.0",
"libhidlbase",
- "libhidltransport",
"liblog",
"libutils",
],
diff --git a/ir/1.0/default/Android.bp b/ir/1.0/default/Android.bp
index 2b15387..80e0f3c 100644
--- a/ir/1.0/default/Android.bp
+++ b/ir/1.0/default/Android.bp
@@ -20,7 +20,6 @@
srcs: ["ConsumerIr.cpp"],
shared_libs: [
"libhidlbase",
- "libhidltransport",
"libhardware",
"liblog",
"libutils",
@@ -40,7 +39,6 @@
"liblog",
"libhardware",
"libhidlbase",
- "libhidltransport",
"libutils",
"android.hardware.ir@1.0",
],
diff --git a/keymaster/3.0/default/Android.mk b/keymaster/3.0/default/Android.mk
index 9e7d04a..208cb66 100644
--- a/keymaster/3.0/default/Android.mk
+++ b/keymaster/3.0/default/Android.mk
@@ -15,7 +15,6 @@
libpuresoftkeymasterdevice \
libkeymaster3device \
libhidlbase \
- libhidltransport \
libutils \
libhardware \
android.hardware.keymaster@3.0
@@ -38,7 +37,6 @@
libutils \
libhardware \
libhidlbase \
- libhidltransport \
android.hardware.keymaster@3.0
include $(BUILD_EXECUTABLE)
diff --git a/keymaster/4.0/default/Android.bp b/keymaster/4.0/default/Android.bp
index 0cede50..f9e3986 100644
--- a/keymaster/4.0/default/Android.bp
+++ b/keymaster/4.0/default/Android.bp
@@ -28,7 +28,6 @@
"libcutils",
"libhardware",
"libhidlbase",
- "libhidltransport",
"libkeymaster4",
"liblog",
"libutils",
diff --git a/keymaster/4.0/support/Android.bp b/keymaster/4.0/support/Android.bp
index ccd1b56..2f40282 100644
--- a/keymaster/4.0/support/Android.bp
+++ b/keymaster/4.0/support/Android.bp
@@ -39,7 +39,6 @@
"libcrypto",
"libhardware",
"libhidlbase",
- "libhidltransport",
"libutils",
]
}
diff --git a/light/2.0/default/Android.bp b/light/2.0/default/Android.bp
index 72cc873..ed48825 100644
--- a/light/2.0/default/Android.bp
+++ b/light/2.0/default/Android.bp
@@ -23,7 +23,6 @@
"libbase",
"liblog",
"libhidlbase",
- "libhidltransport",
"libhardware",
"libutils",
"android.hardware.light@2.0",
@@ -44,7 +43,6 @@
"libutils",
"libhardware",
"libhidlbase",
- "libhidltransport",
"android.hardware.light@2.0",
],
}
diff --git a/light/2.0/vts/functional/VtsHalLightV2_0TargetTest.cpp b/light/2.0/vts/functional/VtsHalLightV2_0TargetTest.cpp
index 13290d9..6fcecd2 100644
--- a/light/2.0/vts/functional/VtsHalLightV2_0TargetTest.cpp
+++ b/light/2.0/vts/functional/VtsHalLightV2_0TargetTest.cpp
@@ -16,11 +16,13 @@
#define LOG_TAG "light_hidl_hal_test"
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
#include <android-base/logging.h>
#include <android/hardware/light/2.0/ILight.h>
#include <android/hardware/light/2.0/types.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+
#include <unistd.h>
#include <set>
@@ -73,25 +75,10 @@
Type::WIFI
};
-// Test environment for Light HIDL HAL.
-class LightHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static LightHidlEnvironment* Instance() {
- static LightHidlEnvironment* instance = new LightHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override { registerTestService<ILight>(); }
- private:
- LightHidlEnvironment() {}
-};
-
-class LightHidlTest : public ::testing::VtsHalHidlTargetTestBase {
-public:
+class LightHidlTest : public testing::TestWithParam<std::string> {
+ public:
virtual void SetUp() override {
- light = ::testing::VtsHalHidlTargetTestBase::getService<ILight>(
- LightHidlEnvironment::Instance()->getServiceName<ILight>());
+ light = ILight::getService(GetParam());
ASSERT_NE(light, nullptr);
LOG(INFO) << "Test is remote " << light->isRemote();
@@ -120,13 +107,12 @@
EXPECT_EQ(Status::SUCCESS, static_cast<Status>(ret));
}
}
-
};
/**
* Ensure all lights which are reported as supported work.
*/
-TEST_F(LightHidlTest, TestSupported) {
+TEST_P(LightHidlTest, TestSupported) {
for (const Type& type: supportedTypes) {
Return<Status> ret = light->setLight(type, kWhite);
EXPECT_OK(ret);
@@ -137,7 +123,7 @@
/**
* Ensure BRIGHTNESS_NOT_SUPPORTED is returned if LOW_PERSISTANCE is not supported.
*/
-TEST_F(LightHidlTest, TestLowPersistance) {
+TEST_P(LightHidlTest, TestLowPersistance) {
for (const Type& type: supportedTypes) {
Return<Status> ret = light->setLight(type, kLowPersistance);
EXPECT_OK(ret);
@@ -151,7 +137,7 @@
/**
* Ensure lights which are not supported return LIGHT_NOT_SUPPORTED
*/
-TEST_F(LightHidlTest, TestUnsupported) {
+TEST_P(LightHidlTest, TestUnsupported) {
std::set<Type> unsupportedTypes = kAllTypes;
for (const Type& type: supportedTypes) {
unsupportedTypes.erase(type);
@@ -164,11 +150,7 @@
}
}
-int main(int argc, char **argv) {
- ::testing::AddGlobalTestEnvironment(LightHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- LightHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
- return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, LightHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(ILight::descriptor)),
+ android::hardware::PrintInstanceNameToString);
diff --git a/light/utils/Android.bp b/light/utils/Android.bp
index ebcbfa2..4c287e4 100644
--- a/light/utils/Android.bp
+++ b/light/utils/Android.bp
@@ -24,7 +24,6 @@
"android.hardware.light@2.0",
"libbase",
"libhidlbase",
- "libhidltransport",
"libutils",
],
}
diff --git a/memtrack/1.0/default/Android.bp b/memtrack/1.0/default/Android.bp
index 76d7fc8..8aa33ee 100644
--- a/memtrack/1.0/default/Android.bp
+++ b/memtrack/1.0/default/Android.bp
@@ -23,7 +23,6 @@
"libbase",
"liblog",
"libhidlbase",
- "libhidltransport",
"libhardware",
"libutils",
"android.hardware.memtrack@1.0",
@@ -46,7 +45,6 @@
"libutils",
"libhardware",
"libhidlbase",
- "libhidltransport",
"android.hardware.memtrack@1.0",
],
diff --git a/neuralnetworks/1.0/IPreparedModel.hal b/neuralnetworks/1.0/IPreparedModel.hal
index 5320050..3dc3202 100644
--- a/neuralnetworks/1.0/IPreparedModel.hal
+++ b/neuralnetworks/1.0/IPreparedModel.hal
@@ -49,11 +49,14 @@
* must not change the content of any of the data objects corresponding to
* 'request' inputs.
*
- * If the prepared model was prepared from a model wherein all
- * tensor operands have fully specified dimensions, and the inputs
- * to the function are valid, then the execution should launch
- * and complete successfully (ErrorStatus::NONE). There must be
- * no failure unless the device itself is in a bad state.
+ * If the prepared model was prepared from a model wherein all tensor
+ * operands have fully specified dimensions, and the inputs to the function
+ * are valid, then:
+ * - the execution should launch successfully (ErrorStatus::NONE): There
+ * must be no failure unless the device itself is in a bad state.
+ * - if at execution time every operation's input operands have legal
+ * values, the execution should complete successfully (ErrorStatus::NONE):
+ * There must be no failure unless the device itself is in a bad state.
*
* Multiple threads can call the execute function on the same IPreparedModel
* object concurrently with different requests.
diff --git a/neuralnetworks/1.0/vts/functional/Android.bp b/neuralnetworks/1.0/vts/functional/Android.bp
index abff213..3e9d5f7 100644
--- a/neuralnetworks/1.0/vts/functional/Android.bp
+++ b/neuralnetworks/1.0/vts/functional/Android.bp
@@ -40,10 +40,12 @@
],
}
-cc_defaults {
- name: "VtsHalNeuralNetworksV1_0TargetTestDefaults",
+cc_test {
+ name: "VtsHalNeuralnetworksV1_0TargetTest",
defaults: ["VtsHalTargetTestDefaults"],
srcs: [
+ "BasicTests.cpp",
+ "TestAssertions.cpp",
"ValidateModel.cpp",
"ValidateRequest.cpp",
"VtsHalNeuralnetworks.cpp",
@@ -63,29 +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",
- ":VtsHalNeuralNetworksV1_0_all_generated_V1_0_tests",
- ],
-}
-
-cc_test {
- name: "PresubmitHalNeuralnetworksV1_0TargetTest",
- defaults: ["VtsHalNeuralNetworksV1_0TargetTestDefaults"],
- srcs: [
- "BasicTests.cpp",
- ":VtsHalNeuralNetworksV1_0_all_generated_V1_0_tests",
- ],
- cflags: [
- "-DPRESUBMIT_NOT_VTS",
- ],
-}
diff --git a/neuralnetworks/1.0/vts/functional/BasicTests.cpp b/neuralnetworks/1.0/vts/functional/BasicTests.cpp
index 945c406..cc44c9e 100644
--- a/neuralnetworks/1.0/vts/functional/BasicTests.cpp
+++ b/neuralnetworks/1.0/vts/functional/BasicTests.cpp
@@ -18,39 +18,29 @@
#include "VtsHalNeuralnetworks.h"
-namespace android {
-namespace hardware {
-namespace neuralnetworks {
-namespace V1_0 {
-namespace vts {
-namespace functional {
+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) {
- Return<DeviceStatus> status = device->getStatus();
+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 =
- device->getCapabilities([](ErrorStatus status, const Capabilities& capabilities) {
- EXPECT_EQ(ErrorStatus::NONE, status);
- EXPECT_LT(0.0f, capabilities.float32Performance.execTime);
- EXPECT_LT(0.0f, capabilities.float32Performance.powerUsage);
- EXPECT_LT(0.0f, capabilities.quantized8Performance.execTime);
- EXPECT_LT(0.0f, capabilities.quantized8Performance.powerUsage);
- });
+ kDevice->getCapabilities([](ErrorStatus status, const Capabilities& capabilities) {
+ EXPECT_EQ(ErrorStatus::NONE, status);
+ EXPECT_LT(0.0f, capabilities.float32Performance.execTime);
+ EXPECT_LT(0.0f, capabilities.float32Performance.powerUsage);
+ EXPECT_LT(0.0f, capabilities.quantized8Performance.execTime);
+ EXPECT_LT(0.0f, capabilities.quantized8Performance.powerUsage);
+ });
EXPECT_TRUE(ret.isOk());
}
-} // namespace functional
-} // namespace vts
-} // namespace V1_0
-} // namespace neuralnetworks
-} // namespace hardware
-} // namespace android
+} // namespace android::hardware::neuralnetworks::V1_0::vts::functional
diff --git a/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
index 0fd9947..595ad85 100644
--- a/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
+++ b/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
@@ -20,6 +20,7 @@
#include "1.0/Utils.h"
#include "MemoryUtils.h"
#include "TestHarness.h"
+#include "VtsHalNeuralnetworks.h"
#include <android-base/logging.h>
#include <android/hardware/neuralnetworks/1.0/IDevice.h>
@@ -32,22 +33,12 @@
#include <gtest/gtest.h>
#include <iostream>
-namespace android {
-namespace hardware {
-namespace neuralnetworks {
-namespace V1_0 {
-namespace generated_tests {
+namespace android::hardware::neuralnetworks::V1_0::vts::functional {
using namespace test_helper;
-using ::android::hardware::neuralnetworks::V1_0::ErrorStatus;
-using ::android::hardware::neuralnetworks::V1_0::IDevice;
-using ::android::hardware::neuralnetworks::V1_0::IPreparedModel;
-using ::android::hardware::neuralnetworks::V1_0::Model;
-using ::android::hardware::neuralnetworks::V1_0::Request;
-using ::android::hardware::neuralnetworks::V1_0::RequestArgument;
-using ::android::hardware::neuralnetworks::V1_0::implementation::ExecutionCallback;
-using ::android::hardware::neuralnetworks::V1_0::implementation::PreparedModelCallback;
-using ::android::hidl::memory::V1_0::IMemory;
+using hidl::memory::V1_0::IMemory;
+using implementation::ExecutionCallback;
+using implementation::PreparedModelCallback;
Model createModel(const TestModel& testModel) {
// Model operands.
@@ -131,9 +122,15 @@
// Top level driver for models and examples generated by test_generator.py
// Test driver for those generated from ml/nn/runtime/test/spec
-void EvaluatePreparedModel(const sp<IPreparedModel>& preparedModel, const TestModel& testModel) {
+void Execute(const sp<IDevice>& device, const TestModel& testModel) {
+ const Model model = createModel(testModel);
const Request request = createRequest(testModel);
+ // Create IPreparedModel.
+ sp<IPreparedModel> preparedModel;
+ createPreparedModel(device, model, &preparedModel);
+ if (preparedModel == nullptr) return;
+
// Launch execution.
sp<ExecutionCallback> executionCallback = new ExecutionCallback();
Return<ErrorStatus> executionLaunchStatus = preparedModel->execute(request, executionCallback);
@@ -151,49 +148,28 @@
checkResults(testModel, outputs);
}
-void Execute(const sp<IDevice>& device, const TestModel& testModel) {
- Model model = createModel(testModel);
-
- // see if service can handle model
- bool fullySupportsModel = false;
- Return<void> supportedCall = device->getSupportedOperations(
- model, [&fullySupportsModel](ErrorStatus status, const hidl_vec<bool>& supported) {
- ASSERT_EQ(ErrorStatus::NONE, status);
- ASSERT_NE(0ul, supported.size());
- fullySupportsModel = std::all_of(supported.begin(), supported.end(),
- [](bool valid) { return valid; });
- });
- ASSERT_TRUE(supportedCall.isOk());
-
- // launch prepare model
- sp<PreparedModelCallback> preparedModelCallback = new PreparedModelCallback();
- Return<ErrorStatus> prepareLaunchStatus = device->prepareModel(model, preparedModelCallback);
- ASSERT_TRUE(prepareLaunchStatus.isOk());
- ASSERT_EQ(ErrorStatus::NONE, static_cast<ErrorStatus>(prepareLaunchStatus));
-
- // retrieve prepared model
- preparedModelCallback->wait();
- ErrorStatus prepareReturnStatus = preparedModelCallback->getStatus();
- sp<IPreparedModel> preparedModel = preparedModelCallback->getPreparedModel();
-
- // early termination if vendor service cannot fully prepare model
- if (!fullySupportsModel && prepareReturnStatus != ErrorStatus::NONE) {
- ASSERT_EQ(nullptr, preparedModel.get());
- LOG(INFO) << "NN VTS: Early termination of test because vendor service cannot "
- "prepare model that it does not support.";
- std::cout << "[ ] Early termination of test because vendor service cannot "
- "prepare model that it does not support."
- << std::endl;
- GTEST_SKIP();
- }
- EXPECT_EQ(ErrorStatus::NONE, prepareReturnStatus);
- ASSERT_NE(nullptr, preparedModel.get());
-
- EvaluatePreparedModel(preparedModel, testModel);
+void GeneratedTestBase::SetUp() {
+ testing::TestWithParam<GeneratedTestParam>::SetUp();
+ ASSERT_NE(kDevice, nullptr);
}
-} // namespace generated_tests
-} // namespace V1_0
-} // namespace neuralnetworks
-} // namespace hardware
-} // namespace android
+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 {};
+
+TEST_P(GeneratedTest, Test) {
+ Execute(kDevice, kTestModel);
+}
+
+INSTANTIATE_GENERATED_TEST(GeneratedTest,
+ [](const TestModel& testModel) { return !testModel.expectFailure; });
+
+} // namespace android::hardware::neuralnetworks::V1_0::vts::functional
diff --git a/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.h b/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.h
index 5d22158..f230a02 100644
--- a/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.h
+++ b/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.h
@@ -18,22 +18,39 @@
#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 {
-namespace hardware {
-namespace neuralnetworks {
-namespace V1_0 {
-namespace generated_tests {
+namespace android::hardware::neuralnetworks::V1_0::vts::functional {
-Model createModel(const ::test_helper::TestModel& testModel);
+using NamedModel = Named<const test_helper::TestModel*>;
+using GeneratedTestParam = std::tuple<NamedDevice, NamedModel>;
-void Execute(const sp<V1_0::IDevice>& device, const ::test_helper::TestModel& testModel);
+class GeneratedTestBase : public testing::TestWithParam<GeneratedTestParam> {
+ protected:
+ void SetUp() override;
+ const sp<IDevice> kDevice = getData(std::get<NamedDevice>(GetParam()));
+ const test_helper::TestModel& kTestModel = *getData(std::get<NamedModel>(GetParam()));
+};
-} // namespace generated_tests
-} // namespace V1_0
-} // namespace neuralnetworks
-} // namespace hardware
-} // namespace android
+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);
+
+} // namespace android::hardware::neuralnetworks::V1_0::vts::functional
#endif // ANDROID_HARDWARE_NEURALNETWORKS_V1_0_GENERATED_TEST_HARNESS_H
diff --git a/neuralnetworks/1.0/vts/functional/GeneratedTests.h b/neuralnetworks/1.0/vts/functional/GeneratedTests.h
deleted file mode 100644
index 9528905..0000000
--- a/neuralnetworks/1.0/vts/functional/GeneratedTests.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "1.0/Utils.h"
-#include "GeneratedTestHarness.h"
-#include "TestHarness.h"
-#include "VtsHalNeuralnetworks.h"
-
-namespace android::hardware::neuralnetworks::V1_0::generated_tests {
-
-using namespace android::hardware::neuralnetworks::V1_0::vts::functional;
-
-} // namespace android::hardware::neuralnetworks::V1_0::generated_tests
diff --git a/neuralnetworks/1.0/vts/functional/TestAssertions.cpp b/neuralnetworks/1.0/vts/functional/TestAssertions.cpp
new file mode 100644
index 0000000..8fdc98d
--- /dev/null
+++ b/neuralnetworks/1.0/vts/functional/TestAssertions.cpp
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+
+#include <android/hardware/neuralnetworks/1.0/types.h>
+#include "TestHarness.h"
+
+namespace android::hardware::neuralnetworks::V1_0 {
+
+// Make sure that the HIDL enums are compatible with the values defined in
+// frameworks/ml/nn/tools/test_generator/test_harness/include/TestHarness.h.
+using namespace test_helper;
+#define CHECK_TEST_ENUM(EnumType, enumValue) \
+ static_assert(static_cast<EnumType>(Test##EnumType::enumValue) == EnumType::enumValue)
+
+CHECK_TEST_ENUM(OperandType, FLOAT32);
+CHECK_TEST_ENUM(OperandType, INT32);
+CHECK_TEST_ENUM(OperandType, UINT32);
+CHECK_TEST_ENUM(OperandType, TENSOR_FLOAT32);
+CHECK_TEST_ENUM(OperandType, TENSOR_INT32);
+CHECK_TEST_ENUM(OperandType, TENSOR_QUANT8_ASYMM);
+
+CHECK_TEST_ENUM(OperandLifeTime, TEMPORARY_VARIABLE);
+CHECK_TEST_ENUM(OperandLifeTime, MODEL_INPUT);
+CHECK_TEST_ENUM(OperandLifeTime, MODEL_OUTPUT);
+CHECK_TEST_ENUM(OperandLifeTime, CONSTANT_COPY);
+CHECK_TEST_ENUM(OperandLifeTime, CONSTANT_REFERENCE);
+CHECK_TEST_ENUM(OperandLifeTime, NO_VALUE);
+
+CHECK_TEST_ENUM(OperationType, ADD);
+CHECK_TEST_ENUM(OperationType, AVERAGE_POOL_2D);
+CHECK_TEST_ENUM(OperationType, CONCATENATION);
+CHECK_TEST_ENUM(OperationType, CONV_2D);
+CHECK_TEST_ENUM(OperationType, DEPTHWISE_CONV_2D);
+CHECK_TEST_ENUM(OperationType, DEPTH_TO_SPACE);
+CHECK_TEST_ENUM(OperationType, DEQUANTIZE);
+CHECK_TEST_ENUM(OperationType, EMBEDDING_LOOKUP);
+CHECK_TEST_ENUM(OperationType, FLOOR);
+CHECK_TEST_ENUM(OperationType, FULLY_CONNECTED);
+CHECK_TEST_ENUM(OperationType, HASHTABLE_LOOKUP);
+CHECK_TEST_ENUM(OperationType, L2_NORMALIZATION);
+CHECK_TEST_ENUM(OperationType, L2_POOL_2D);
+CHECK_TEST_ENUM(OperationType, LOCAL_RESPONSE_NORMALIZATION);
+CHECK_TEST_ENUM(OperationType, LOGISTIC);
+CHECK_TEST_ENUM(OperationType, LSH_PROJECTION);
+CHECK_TEST_ENUM(OperationType, LSTM);
+CHECK_TEST_ENUM(OperationType, MAX_POOL_2D);
+CHECK_TEST_ENUM(OperationType, MUL);
+CHECK_TEST_ENUM(OperationType, RELU);
+CHECK_TEST_ENUM(OperationType, RELU1);
+CHECK_TEST_ENUM(OperationType, RELU6);
+CHECK_TEST_ENUM(OperationType, RESHAPE);
+CHECK_TEST_ENUM(OperationType, RESIZE_BILINEAR);
+CHECK_TEST_ENUM(OperationType, RNN);
+CHECK_TEST_ENUM(OperationType, SOFTMAX);
+CHECK_TEST_ENUM(OperationType, SPACE_TO_DEPTH);
+CHECK_TEST_ENUM(OperationType, SVDF);
+CHECK_TEST_ENUM(OperationType, TANH);
+
+#undef CHECK_TEST_ENUM
+
+} // namespace android::hardware::neuralnetworks::V1_0
diff --git a/neuralnetworks/1.0/vts/functional/Utils.cpp b/neuralnetworks/1.0/vts/functional/Utils.cpp
index 5aa2751..5b630fd 100644
--- a/neuralnetworks/1.0/vts/functional/Utils.cpp
+++ b/neuralnetworks/1.0/vts/functional/Utils.cpp
@@ -26,17 +26,16 @@
#include <hidlmemory/mapping.h>
#include <algorithm>
+#include <iostream>
#include <vector>
-namespace android {
-namespace hardware {
-namespace neuralnetworks {
+namespace android::hardware::neuralnetworks {
using namespace test_helper;
-using ::android::hardware::neuralnetworks::V1_0::DataLocation;
-using ::android::hardware::neuralnetworks::V1_0::Request;
-using ::android::hardware::neuralnetworks::V1_0::RequestArgument;
-using ::android::hidl::memory::V1_0::IMemory;
+using hidl::memory::V1_0::IMemory;
+using V1_0::DataLocation;
+using V1_0::Request;
+using V1_0::RequestArgument;
constexpr uint32_t kInputPoolIndex = 0;
constexpr uint32_t kOutputPoolIndex = 1;
@@ -118,6 +117,23 @@
return outputBuffers;
}
-} // namespace neuralnetworks
-} // namespace hardware
-} // namespace android
+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 {
+
+::std::ostream& operator<<(::std::ostream& os, ErrorStatus errorStatus) {
+ return os << toString(errorStatus);
+}
+
+::std::ostream& operator<<(::std::ostream& os, DeviceStatus deviceStatus) {
+ return os << toString(deviceStatus);
+}
+
+} // namespace android::hardware::neuralnetworks::V1_0
diff --git a/neuralnetworks/1.0/vts/functional/ValidateModel.cpp b/neuralnetworks/1.0/vts/functional/ValidateModel.cpp
index 72c4a2b..cc15263 100644
--- a/neuralnetworks/1.0/vts/functional/ValidateModel.cpp
+++ b/neuralnetworks/1.0/vts/functional/ValidateModel.cpp
@@ -16,39 +16,32 @@
#define LOG_TAG "neuralnetworks_hidl_hal_test"
+#include "1.0/Callbacks.h"
+#include "GeneratedTestHarness.h"
#include "VtsHalNeuralnetworks.h"
-#include "1.0/Callbacks.h"
+namespace android::hardware::neuralnetworks::V1_0::vts::functional {
-namespace android {
-namespace hardware {
-namespace neuralnetworks {
-namespace V1_0 {
-namespace vts {
-namespace functional {
-
-using ::android::hardware::neuralnetworks::V1_0::implementation::ExecutionCallback;
-using ::android::hardware::neuralnetworks::V1_0::implementation::PreparedModelCallback;
+using implementation::PreparedModelCallback;
///////////////////////// UTILITY FUNCTIONS /////////////////////////
static void validateGetSupportedOperations(const sp<IDevice>& device, const std::string& message,
- const V1_0::Model& model) {
+ const Model& model) {
SCOPED_TRACE(message + " [getSupportedOperations]");
Return<void> ret =
- device->getSupportedOperations(model, [&](ErrorStatus status, const hidl_vec<bool>&) {
- EXPECT_EQ(ErrorStatus::INVALID_ARGUMENT, status);
- });
+ device->getSupportedOperations(model, [&](ErrorStatus status, const hidl_vec<bool>&) {
+ EXPECT_EQ(ErrorStatus::INVALID_ARGUMENT, status);
+ });
EXPECT_TRUE(ret.isOk());
}
static void validatePrepareModel(const sp<IDevice>& device, const std::string& message,
- const V1_0::Model& model) {
+ const Model& model) {
SCOPED_TRACE(message + " [prepareModel]");
sp<PreparedModelCallback> preparedModelCallback = new PreparedModelCallback();
- ASSERT_NE(nullptr, preparedModelCallback.get());
Return<ErrorStatus> prepareLaunchStatus = device->prepareModel(model, preparedModelCallback);
ASSERT_TRUE(prepareLaunchStatus.isOk());
ASSERT_EQ(ErrorStatus::INVALID_ARGUMENT, static_cast<ErrorStatus>(prepareLaunchStatus));
@@ -64,7 +57,7 @@
// mutation to it to invalidate the model, then pass it to interface calls that
// use the model. Note that the model here is passed by value, and any mutation
// to the model does not leave this function.
-static void validate(const sp<IDevice>& device, const std::string& message, V1_0::Model model,
+static void validate(const sp<IDevice>& device, const std::string& message, Model model,
const std::function<void(Model*)>& mutation) {
mutation(&model);
validateGetSupportedOperations(device, message, model);
@@ -94,13 +87,13 @@
static uint32_t addOperand(Model* model) {
return hidl_vec_push_back(&model->operands,
{
- .type = OperandType::INT32,
- .dimensions = {},
- .numberOfConsumers = 0,
- .scale = 0.0f,
- .zeroPoint = 0,
- .lifetime = OperandLifeTime::MODEL_INPUT,
- .location = {.poolIndex = 0, .offset = 0, .length = 0},
+ .type = OperandType::INT32,
+ .dimensions = {},
+ .numberOfConsumers = 0,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::MODEL_INPUT,
+ .location = {.poolIndex = 0, .offset = 0, .length = 0},
});
}
@@ -114,13 +107,13 @@
///////////////////////// VALIDATE MODEL OPERAND TYPE /////////////////////////
static const int32_t invalidOperandTypes[] = {
- static_cast<int32_t>(OperandType::FLOAT32) - 1, // lower bound fundamental
- static_cast<int32_t>(OperandType::TENSOR_QUANT8_ASYMM) + 1, // upper bound fundamental
- static_cast<int32_t>(OperandType::OEM) - 1, // lower bound OEM
- static_cast<int32_t>(OperandType::TENSOR_OEM_BYTE) + 1, // upper bound OEM
+ static_cast<int32_t>(OperandType::FLOAT32) - 1, // lower bound fundamental
+ static_cast<int32_t>(OperandType::TENSOR_QUANT8_ASYMM) + 1, // upper bound fundamental
+ static_cast<int32_t>(OperandType::OEM) - 1, // lower bound OEM
+ static_cast<int32_t>(OperandType::TENSOR_OEM_BYTE) + 1, // upper bound OEM
};
-static void mutateOperandTypeTest(const sp<IDevice>& device, const V1_0::Model& model) {
+static void mutateOperandTypeTest(const sp<IDevice>& device, const Model& model) {
for (size_t operand = 0; operand < model.operands.size(); ++operand) {
for (int32_t invalidOperandType : invalidOperandTypes) {
const std::string message = "mutateOperandTypeTest: operand " +
@@ -150,7 +143,7 @@
}
}
-static void mutateOperandRankTest(const sp<IDevice>& device, const V1_0::Model& model) {
+static void mutateOperandRankTest(const sp<IDevice>& device, const Model& model) {
for (size_t operand = 0; operand < model.operands.size(); ++operand) {
const uint32_t invalidRank = getInvalidRank(model.operands[operand].type);
const std::string message = "mutateOperandRankTest: operand " + std::to_string(operand) +
@@ -179,7 +172,7 @@
}
}
-static void mutateOperandScaleTest(const sp<IDevice>& device, const V1_0::Model& model) {
+static void mutateOperandScaleTest(const sp<IDevice>& device, const Model& model) {
for (size_t operand = 0; operand < model.operands.size(); ++operand) {
const float invalidScale = getInvalidScale(model.operands[operand].type);
const std::string message = "mutateOperandScaleTest: operand " + std::to_string(operand) +
@@ -207,10 +200,10 @@
}
}
-static void mutateOperandZeroPointTest(const sp<IDevice>& device, const V1_0::Model& model) {
+static void mutateOperandZeroPointTest(const sp<IDevice>& device, const Model& model) {
for (size_t operand = 0; operand < model.operands.size(); ++operand) {
const std::vector<int32_t> invalidZeroPoints =
- getInvalidZeroPoints(model.operands[operand].type);
+ getInvalidZeroPoints(model.operands[operand].type);
for (int32_t invalidZeroPoint : invalidZeroPoints) {
const std::string message = "mutateOperandZeroPointTest: operand " +
std::to_string(operand) + " has zero point of " +
@@ -242,18 +235,18 @@
break;
case OperandType::TENSOR_FLOAT32:
newOperand.dimensions =
- operand->dimensions.size() > 0 ? operand->dimensions : hidl_vec<uint32_t>({1});
+ operand->dimensions.size() > 0 ? operand->dimensions : hidl_vec<uint32_t>({1});
newOperand.scale = 0.0f;
newOperand.zeroPoint = 0;
break;
case OperandType::TENSOR_INT32:
newOperand.dimensions =
- operand->dimensions.size() > 0 ? operand->dimensions : hidl_vec<uint32_t>({1});
+ operand->dimensions.size() > 0 ? operand->dimensions : hidl_vec<uint32_t>({1});
newOperand.zeroPoint = 0;
break;
case OperandType::TENSOR_QUANT8_ASYMM:
newOperand.dimensions =
- operand->dimensions.size() > 0 ? operand->dimensions : hidl_vec<uint32_t>({1});
+ operand->dimensions.size() > 0 ? operand->dimensions : hidl_vec<uint32_t>({1});
newOperand.scale = operand->scale != 0.0f ? operand->scale : 1.0f;
break;
case OperandType::OEM:
@@ -264,7 +257,7 @@
*operand = newOperand;
}
-static bool mutateOperationOperandTypeSkip(size_t operand, const V1_0::Model& model) {
+static bool mutateOperationOperandTypeSkip(size_t operand, const Model& model) {
// LSH_PROJECTION's second argument is allowed to have any type. This is the
// only operation that currently has a type that can be anything independent
// from any other type. Changing the operand type to any other type will
@@ -278,7 +271,7 @@
return false;
}
-static void mutateOperationOperandTypeTest(const sp<IDevice>& device, const V1_0::Model& model) {
+static void mutateOperationOperandTypeTest(const sp<IDevice>& device, const Model& model) {
for (size_t operand = 0; operand < model.operands.size(); ++operand) {
if (mutateOperationOperandTypeSkip(operand, model)) {
continue;
@@ -303,13 +296,13 @@
///////////////////////// VALIDATE MODEL OPERATION TYPE /////////////////////////
static const int32_t invalidOperationTypes[] = {
- static_cast<int32_t>(OperationType::ADD) - 1, // lower bound fundamental
- static_cast<int32_t>(OperationType::TANH) + 1, // upper bound fundamental
- static_cast<int32_t>(OperationType::OEM_OPERATION) - 1, // lower bound OEM
- static_cast<int32_t>(OperationType::OEM_OPERATION) + 1, // upper bound OEM
+ static_cast<int32_t>(OperationType::ADD) - 1, // lower bound fundamental
+ static_cast<int32_t>(OperationType::TANH) + 1, // upper bound fundamental
+ static_cast<int32_t>(OperationType::OEM_OPERATION) - 1, // lower bound OEM
+ static_cast<int32_t>(OperationType::OEM_OPERATION) + 1, // upper bound OEM
};
-static void mutateOperationTypeTest(const sp<IDevice>& device, const V1_0::Model& model) {
+static void mutateOperationTypeTest(const sp<IDevice>& device, const Model& model) {
for (size_t operation = 0; operation < model.operations.size(); ++operation) {
for (int32_t invalidOperationType : invalidOperationTypes) {
const std::string message = "mutateOperationTypeTest: operation " +
@@ -317,7 +310,7 @@
std::to_string(invalidOperationType);
validate(device, message, model, [operation, invalidOperationType](Model* model) {
model->operations[operation].type =
- static_cast<OperationType>(invalidOperationType);
+ static_cast<OperationType>(invalidOperationType);
});
}
}
@@ -325,8 +318,7 @@
///////////////////////// VALIDATE MODEL OPERATION INPUT OPERAND INDEX /////////////////////////
-static void mutateOperationInputOperandIndexTest(const sp<IDevice>& device,
- const V1_0::Model& model) {
+static void mutateOperationInputOperandIndexTest(const sp<IDevice>& device, const Model& model) {
for (size_t operation = 0; operation < model.operations.size(); ++operation) {
const uint32_t invalidOperand = model.operands.size();
for (size_t input = 0; input < model.operations[operation].inputs.size(); ++input) {
@@ -342,8 +334,7 @@
///////////////////////// VALIDATE MODEL OPERATION OUTPUT OPERAND INDEX /////////////////////////
-static void mutateOperationOutputOperandIndexTest(const sp<IDevice>& device,
- const V1_0::Model& model) {
+static void mutateOperationOutputOperandIndexTest(const sp<IDevice>& device, const Model& model) {
for (size_t operation = 0; operation < model.operations.size(); ++operation) {
const uint32_t invalidOperand = model.operands.size();
for (size_t output = 0; output < model.operations[operation].outputs.size(); ++output) {
@@ -381,7 +372,7 @@
removeValueAndDecrementGreaterValues(&model->outputIndexes, index);
}
-static void removeOperandTest(const sp<IDevice>& device, const V1_0::Model& model) {
+static void removeOperandTest(const sp<IDevice>& device, const Model& model) {
for (size_t operand = 0; operand < model.operands.size(); ++operand) {
const std::string message = "removeOperandTest: operand " + std::to_string(operand);
validate(device, message, model,
@@ -398,7 +389,7 @@
hidl_vec_removeAt(&model->operations, index);
}
-static void removeOperationTest(const sp<IDevice>& device, const V1_0::Model& model) {
+static void removeOperationTest(const sp<IDevice>& device, const Model& model) {
for (size_t operation = 0; operation < model.operations.size(); ++operation) {
const std::string message = "removeOperationTest: operation " + std::to_string(operation);
validate(device, message, model,
@@ -408,14 +399,14 @@
///////////////////////// REMOVE OPERATION INPUT /////////////////////////
-static void removeOperationInputTest(const sp<IDevice>& device, const V1_0::Model& model) {
+static void removeOperationInputTest(const sp<IDevice>& device, const Model& model) {
for (size_t operation = 0; operation < model.operations.size(); ++operation) {
for (size_t input = 0; input < model.operations[operation].inputs.size(); ++input) {
- const V1_0::Operation& op = model.operations[operation];
+ const Operation& op = model.operations[operation];
// CONCATENATION has at least 2 inputs, with the last element being
// INT32. Skip this test if removing one of CONCATENATION's
// inputs still produces a valid model.
- if (op.type == V1_0::OperationType::CONCATENATION && op.inputs.size() > 2 &&
+ if (op.type == OperationType::CONCATENATION && op.inputs.size() > 2 &&
input != op.inputs.size() - 1) {
continue;
}
@@ -433,7 +424,7 @@
///////////////////////// REMOVE OPERATION OUTPUT /////////////////////////
-static void removeOperationOutputTest(const sp<IDevice>& device, const V1_0::Model& model) {
+static void removeOperationOutputTest(const sp<IDevice>& device, const Model& model) {
for (size_t operation = 0; operation < model.operations.size(); ++operation) {
for (size_t output = 0; output < model.operations[operation].outputs.size(); ++output) {
const std::string message = "removeOperationOutputTest: operation " +
@@ -454,7 +445,7 @@
///////////////////////// ADD OPERATION INPUT /////////////////////////
-static void addOperationInputTest(const sp<IDevice>& device, const V1_0::Model& model) {
+static void addOperationInputTest(const sp<IDevice>& device, const Model& model) {
for (size_t operation = 0; operation < model.operations.size(); ++operation) {
const std::string message = "addOperationInputTest: operation " + std::to_string(operation);
validate(device, message, model, [operation](Model* model) {
@@ -467,10 +458,10 @@
///////////////////////// ADD OPERATION OUTPUT /////////////////////////
-static void addOperationOutputTest(const sp<IDevice>& device, const V1_0::Model& model) {
+static void addOperationOutputTest(const sp<IDevice>& device, const Model& model) {
for (size_t operation = 0; operation < model.operations.size(); ++operation) {
const std::string message =
- "addOperationOutputTest: operation " + std::to_string(operation);
+ "addOperationOutputTest: operation " + std::to_string(operation);
validate(device, message, model, [operation](Model* model) {
uint32_t index = addOperand(model, OperandLifeTime::MODEL_OUTPUT);
hidl_vec_push_back(&model->operations[operation].outputs, index);
@@ -481,7 +472,7 @@
////////////////////////// ENTRY POINT //////////////////////////////
-void ValidationTest::validateModel(const V1_0::Model& model) {
+void validateModel(const sp<IDevice>& device, const Model& model) {
mutateOperandTypeTest(device, model);
mutateOperandRankTest(device, model);
mutateOperandScaleTest(device, model);
@@ -498,9 +489,4 @@
addOperationOutputTest(device, model);
}
-} // namespace functional
-} // namespace vts
-} // namespace V1_0
-} // namespace neuralnetworks
-} // namespace hardware
-} // namespace android
+} // namespace android::hardware::neuralnetworks::V1_0::vts::functional
diff --git a/neuralnetworks/1.0/vts/functional/ValidateRequest.cpp b/neuralnetworks/1.0/vts/functional/ValidateRequest.cpp
index d62365c..05eefd1 100644
--- a/neuralnetworks/1.0/vts/functional/ValidateRequest.cpp
+++ b/neuralnetworks/1.0/vts/functional/ValidateRequest.cpp
@@ -17,16 +17,12 @@
#define LOG_TAG "neuralnetworks_hidl_hal_test"
#include "1.0/Callbacks.h"
+#include "GeneratedTestHarness.h"
#include "VtsHalNeuralnetworks.h"
-namespace android {
-namespace hardware {
-namespace neuralnetworks {
-namespace V1_0 {
-namespace vts {
-namespace functional {
+namespace android::hardware::neuralnetworks::V1_0::vts::functional {
-using ::android::hardware::neuralnetworks::V1_0::implementation::ExecutionCallback;
+using implementation::ExecutionCallback;
///////////////////////// UTILITY FUNCTIONS /////////////////////////
@@ -40,7 +36,6 @@
SCOPED_TRACE(message + " [execute]");
sp<ExecutionCallback> executionCallback = new ExecutionCallback();
- ASSERT_NE(nullptr, executionCallback.get());
Return<ErrorStatus> executeLaunchStatus = preparedModel->execute(request, executionCallback);
ASSERT_TRUE(executeLaunchStatus.isOk());
ASSERT_EQ(ErrorStatus::INVALID_ARGUMENT, static_cast<ErrorStatus>(executeLaunchStatus));
@@ -92,15 +87,9 @@
///////////////////////////// ENTRY POINT //////////////////////////////////
-void ValidationTest::validateRequest(const sp<IPreparedModel>& preparedModel,
- const Request& request) {
+void validateRequest(const sp<IPreparedModel>& preparedModel, const Request& request) {
removeInputTest(preparedModel, request);
removeOutputTest(preparedModel, request);
}
-} // namespace functional
-} // namespace vts
-} // namespace V1_0
-} // namespace neuralnetworks
-} // namespace hardware
-} // namespace android
+} // namespace android::hardware::neuralnetworks::V1_0::vts::functional
diff --git a/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworks.cpp b/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworks.cpp
index 626deac..cb22250 100644
--- a/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworks.cpp
+++ b/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworks.cpp
@@ -17,45 +17,45 @@
#define LOG_TAG "neuralnetworks_hidl_hal_test"
#include "VtsHalNeuralnetworks.h"
+#include "1.0/Callbacks.h"
+#include "GeneratedTestHarness.h"
+#include "TestHarness.h"
#include <android-base/logging.h>
+#include <hidl/ServiceManagement.h>
+#include <string>
+#include <utility>
-#include "1.0/Callbacks.h"
+namespace android::hardware::neuralnetworks::V1_0::vts::functional {
-namespace android {
-namespace hardware {
-namespace neuralnetworks {
-namespace V1_0 {
-namespace vts {
-namespace functional {
+using implementation::PreparedModelCallback;
-using ::android::hardware::neuralnetworks::V1_0::implementation::PreparedModelCallback;
-
-static void createPreparedModel(const sp<IDevice>& device, const V1_0::Model& model,
- sp<IPreparedModel>* preparedModel) {
+void createPreparedModel(const sp<IDevice>& device, const Model& model,
+ sp<IPreparedModel>* preparedModel) {
ASSERT_NE(nullptr, preparedModel);
+ *preparedModel = nullptr;
// see if service can handle model
bool fullySupportsModel = false;
- Return<void> supportedOpsLaunchStatus = device->getSupportedOperations(
+ const Return<void> supportedCall = device->getSupportedOperations(
model, [&fullySupportsModel](ErrorStatus status, const hidl_vec<bool>& supported) {
ASSERT_EQ(ErrorStatus::NONE, status);
ASSERT_NE(0ul, supported.size());
fullySupportsModel = std::all_of(supported.begin(), supported.end(),
[](bool valid) { return valid; });
});
- ASSERT_TRUE(supportedOpsLaunchStatus.isOk());
+ ASSERT_TRUE(supportedCall.isOk());
// launch prepare model
- sp<PreparedModelCallback> preparedModelCallback = new PreparedModelCallback();
- ASSERT_NE(nullptr, preparedModelCallback.get());
- Return<ErrorStatus> prepareLaunchStatus = device->prepareModel(model, preparedModelCallback);
+ const sp<PreparedModelCallback> preparedModelCallback = new PreparedModelCallback();
+ const Return<ErrorStatus> prepareLaunchStatus =
+ device->prepareModel(model, preparedModelCallback);
ASSERT_TRUE(prepareLaunchStatus.isOk());
ASSERT_EQ(ErrorStatus::NONE, static_cast<ErrorStatus>(prepareLaunchStatus));
// retrieve prepared model
preparedModelCallback->wait();
- ErrorStatus prepareReturnStatus = preparedModelCallback->getStatus();
+ const ErrorStatus prepareReturnStatus = preparedModelCallback->getStatus();
*preparedModel = preparedModelCallback->getPreparedModel();
// The getSupportedOperations call returns a list of operations that are
@@ -67,99 +67,73 @@
// can continue.
if (!fullySupportsModel && prepareReturnStatus != ErrorStatus::NONE) {
ASSERT_EQ(nullptr, preparedModel->get());
- LOG(INFO) << "NN VTS: Unable to test Request validation because vendor service cannot "
- "prepare model that it does not support.";
- std::cout << "[ ] Unable to test Request validation because vendor service "
- "cannot prepare model that it does not support."
+ LOG(INFO) << "NN VTS: Early termination of test because vendor service cannot prepare "
+ "model that it does not support.";
+ std::cout << "[ ] Early termination of test because vendor service cannot "
+ "prepare model that it does not support."
<< std::endl;
- return;
+ GTEST_SKIP();
}
ASSERT_EQ(ErrorStatus::NONE, prepareReturnStatus);
ASSERT_NE(nullptr, preparedModel->get());
}
-// A class for test environment setup
-NeuralnetworksHidlEnvironment::NeuralnetworksHidlEnvironment() {}
-
-NeuralnetworksHidlEnvironment::~NeuralnetworksHidlEnvironment() {}
-
-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.
-NeuralnetworksHidlTest::NeuralnetworksHidlTest() {}
-
-NeuralnetworksHidlTest::~NeuralnetworksHidlTest() {}
-
void NeuralnetworksHidlTest::SetUp() {
- ::testing::VtsHalHidlTargetTestBase::SetUp();
- device = ::testing::VtsHalHidlTargetTestBase::getService<IDevice>(
- NeuralnetworksHidlEnvironment::getInstance());
-
-#ifdef PRESUBMIT_NOT_VTS
- const std::string name =
- NeuralnetworksHidlEnvironment::getInstance()->getServiceName<IDevice>();
- const std::string sampleDriver = "sample-";
- if (device == nullptr && name.substr(0, sampleDriver.size()) == sampleDriver) {
- GTEST_SKIP();
- }
-#endif // PRESUBMIT_NOT_VTS
-
- ASSERT_NE(nullptr, device.get());
+ testing::TestWithParam<NeuralnetworksHidlTestParam>::SetUp();
+ ASSERT_NE(kDevice, nullptr);
}
-void NeuralnetworksHidlTest::TearDown() {
- device = nullptr;
- ::testing::VtsHalHidlTargetTestBase::TearDown();
+static NamedDevice makeNamedDevice(const std::string& name) {
+ return {name, IDevice::getService(name)};
}
-void ValidationTest::validateEverything(const Model& model, const Request& request) {
- validateModel(model);
+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);
- // create IPreparedModel
+ // 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
+void validateRequest(const sp<IPreparedModel>& preparedModel, const Request& request);
+
+void validateEverything(const sp<IDevice>& device, const Model& model, const Request& request) {
+ validateModel(device, model);
+
+ // Create IPreparedModel.
sp<IPreparedModel> preparedModel;
- ASSERT_NO_FATAL_FAILURE(createPreparedModel(device, model, &preparedModel));
- if (preparedModel == nullptr) {
- return;
- }
+ createPreparedModel(device, model, &preparedModel);
+ if (preparedModel == nullptr) return;
validateRequest(preparedModel, request);
}
-} // namespace functional
-} // namespace vts
-} // namespace V1_0
-} // namespace neuralnetworks
-} // namespace hardware
-} // namespace android
-
-namespace android::hardware::neuralnetworks::V1_0 {
-
-::std::ostream& operator<<(::std::ostream& os, ErrorStatus errorStatus) {
- return os << toString(errorStatus);
+TEST_P(ValidationTest, Test) {
+ const Model model = createModel(kTestModel);
+ const Request request = createRequest(kTestModel);
+ ASSERT_FALSE(kTestModel.expectFailure);
+ validateEverything(kDevice, model, request);
}
-::std::ostream& operator<<(::std::ostream& os, DeviceStatus deviceStatus) {
- return os << toString(deviceStatus);
-}
+INSTANTIATE_GENERATED_TEST(ValidationTest, [](const test_helper::TestModel&) { return true; });
-} // namespace android::hardware::neuralnetworks::V1_0
-
-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;
-}
+} // namespace android::hardware::neuralnetworks::V1_0::vts::functional
diff --git a/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworks.h b/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworks.h
index 3765314..17f4613 100644
--- a/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworks.h
+++ b/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworks.h
@@ -17,75 +17,39 @@
#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 <iostream>
+
#include <vector>
-namespace android {
-namespace hardware {
-namespace neuralnetworks {
-namespace V1_0 {
-namespace vts {
-namespace functional {
+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();
- ~NeuralnetworksHidlEnvironment() override;
+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();
- ~NeuralnetworksHidlTest() override;
+class NeuralnetworksHidlTest : public testing::TestWithParam<NeuralnetworksHidlTestParam> {
+ protected:
void SetUp() override;
- void TearDown() override;
-
- protected:
- sp<IDevice> device;
+ const sp<IDevice> kDevice = getData(GetParam());
};
-// Tag for the validation tests
-class ValidationTest : public NeuralnetworksHidlTest {
- protected:
- void validateEverything(const Model& model, const Request& request);
+const std::vector<NamedDevice>& getNamedDevices();
- private:
- void validateModel(const Model& model);
- void validateRequest(const sp<IPreparedModel>& preparedModel, const Request& request);
-};
+std::string printNeuralnetworksHidlTest(
+ const testing::TestParamInfo<NeuralnetworksHidlTestParam>& info);
-// Tag for the generated tests
-class GeneratedTest : public NeuralnetworksHidlTest {};
+#define INSTANTIATE_DEVICE_TEST(TestSuite) \
+ INSTANTIATE_TEST_SUITE_P(PerInstance, TestSuite, testing::ValuesIn(getNamedDevices()), \
+ printNeuralnetworksHidlTest)
-} // namespace functional
-} // namespace vts
-} // namespace V1_0
-} // namespace neuralnetworks
-} // namespace hardware
-} // namespace android
+// Create an IPreparedModel object. If the model cannot be prepared,
+// "preparedModel" will be nullptr instead.
+void createPreparedModel(const sp<IDevice>& device, const Model& model,
+ sp<IPreparedModel>* preparedModel);
-namespace android::hardware::neuralnetworks::V1_0 {
-
-// pretty-print values for error messages
-::std::ostream& operator<<(::std::ostream& os, ErrorStatus errorStatus);
-::std::ostream& operator<<(::std::ostream& os, DeviceStatus deviceStatus);
-
-} // namespace android::hardware::neuralnetworks::V1_0
+} // namespace android::hardware::neuralnetworks::V1_0::vts::functional
#endif // ANDROID_HARDWARE_NEURALNETWORKS_V1_0_VTS_HAL_NEURALNETWORKS_H
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 2955b6e..6d4534c 100644
--- a/neuralnetworks/1.0/vts/functional/include/1.0/Utils.h
+++ b/neuralnetworks/1.0/vts/functional/include/1.0/Utils.h
@@ -17,17 +17,19 @@
#ifndef ANDROID_HARDWARE_NEURALNETWORKS_V1_0_UTILS_H
#define ANDROID_HARDWARE_NEURALNETWORKS_V1_0_UTILS_H
+#include <android-base/logging.h>
#include <android/hardware/neuralnetworks/1.0/types.h>
#include <algorithm>
+#include <iosfwd>
+#include <string>
+#include <utility>
#include <vector>
#include "TestHarness.h"
-namespace android {
-namespace hardware {
-namespace neuralnetworks {
+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);
@@ -37,23 +39,43 @@
// resizing the hidl_vec to one less.
template <typename Type>
inline void hidl_vec_removeAt(hidl_vec<Type>* vec, uint32_t index) {
- if (vec) {
- std::rotate(vec->begin() + index, vec->begin() + index + 1, vec->end());
- vec->resize(vec->size() - 1);
- }
+ CHECK(vec != nullptr);
+ std::rotate(vec->begin() + index, vec->begin() + index + 1, vec->end());
+ vec->resize(vec->size() - 1);
}
template <typename Type>
inline uint32_t hidl_vec_push_back(hidl_vec<Type>* vec, const Type& value) {
- // assume vec is valid
+ CHECK(vec != nullptr);
const uint32_t index = vec->size();
vec->resize(index + 1);
(*vec)[index] = value;
return index;
}
-} // namespace neuralnetworks
-} // namespace hardware
-} // namespace android
+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 {
+
+// pretty-print values for error messages
+::std::ostream& operator<<(::std::ostream& os, ErrorStatus errorStatus);
+::std::ostream& operator<<(::std::ostream& os, DeviceStatus deviceStatus);
+
+} // namespace android::hardware::neuralnetworks::V1_0
#endif // ANDROID_HARDWARE_NEURALNETWORKS_V1_0_UTILS_H
diff --git a/neuralnetworks/1.1/vts/functional/Android.bp b/neuralnetworks/1.1/vts/functional/Android.bp
index 86002d2..4e85355 100644
--- a/neuralnetworks/1.1/vts/functional/Android.bp
+++ b/neuralnetworks/1.1/vts/functional/Android.bp
@@ -14,10 +14,12 @@
// 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",
"VtsHalNeuralnetworks.cpp",
@@ -38,39 +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"],
}
-
-// Tests for V1_0 models using the V1_1 HAL.
-cc_test {
- name: "VtsHalNeuralnetworksV1_1CompatV1_0TargetTest",
- defaults: ["VtsHalNeuralNetworksV1_1TargetTestDefaults"],
- srcs: [
- ":VtsHalNeuralNetworksV1_1_all_generated_V1_0_tests",
- ],
-}
-
-// Tests for V1_1 models.
-cc_test {
- name: "VtsHalNeuralnetworksV1_1TargetTest",
- defaults: ["VtsHalNeuralNetworksV1_1TargetTestDefaults"],
- srcs: [
- "BasicTests.cpp",
- ":VtsHalNeuralNetworksV1_1_all_generated_V1_1_tests",
- ],
-}
-
-cc_test {
- name: "PresubmitHalNeuralnetworksV1_1TargetTest",
- defaults: ["VtsHalNeuralNetworksV1_1TargetTestDefaults"],
- srcs: [
- "BasicTests.cpp",
- ":VtsHalNeuralNetworksV1_1_all_generated_V1_1_tests",
- ],
- cflags: [
- "-DPRESUBMIT_NOT_VTS",
- ],
-}
diff --git a/neuralnetworks/1.1/vts/functional/BasicTests.cpp b/neuralnetworks/1.1/vts/functional/BasicTests.cpp
index ed59a2d..44836f0 100644
--- a/neuralnetworks/1.1/vts/functional/BasicTests.cpp
+++ b/neuralnetworks/1.1/vts/functional/BasicTests.cpp
@@ -18,41 +18,34 @@
#include "VtsHalNeuralnetworks.h"
-namespace android {
-namespace hardware {
-namespace neuralnetworks {
-namespace V1_1 {
-namespace vts {
-namespace functional {
+namespace android::hardware::neuralnetworks::V1_1::vts::functional {
+
+using V1_0::DeviceStatus;
+using V1_0::ErrorStatus;
// create device test
-TEST_F(NeuralnetworksHidlTest, CreateDevice) {}
+TEST_P(NeuralnetworksHidlTest, CreateDevice) {}
// status test
-TEST_F(NeuralnetworksHidlTest, StatusTest) {
- Return<DeviceStatus> status = device->getStatus();
+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 =
- device->getCapabilities_1_1([](ErrorStatus status, const Capabilities& capabilities) {
- EXPECT_EQ(ErrorStatus::NONE, status);
- EXPECT_LT(0.0f, capabilities.float32Performance.execTime);
- EXPECT_LT(0.0f, capabilities.float32Performance.powerUsage);
- EXPECT_LT(0.0f, capabilities.quantized8Performance.execTime);
- EXPECT_LT(0.0f, capabilities.quantized8Performance.powerUsage);
- EXPECT_LT(0.0f, capabilities.relaxedFloat32toFloat16Performance.execTime);
- EXPECT_LT(0.0f, capabilities.relaxedFloat32toFloat16Performance.powerUsage);
- });
+ kDevice->getCapabilities_1_1([](ErrorStatus status, const Capabilities& capabilities) {
+ EXPECT_EQ(ErrorStatus::NONE, status);
+ EXPECT_LT(0.0f, capabilities.float32Performance.execTime);
+ EXPECT_LT(0.0f, capabilities.float32Performance.powerUsage);
+ EXPECT_LT(0.0f, capabilities.quantized8Performance.execTime);
+ EXPECT_LT(0.0f, capabilities.quantized8Performance.powerUsage);
+ EXPECT_LT(0.0f, capabilities.relaxedFloat32toFloat16Performance.execTime);
+ EXPECT_LT(0.0f, capabilities.relaxedFloat32toFloat16Performance.powerUsage);
+ });
EXPECT_TRUE(ret.isOk());
}
-} // namespace functional
-} // namespace vts
-} // namespace V1_1
-} // namespace neuralnetworks
-} // namespace hardware
-} // namespace android
+} // namespace android::hardware::neuralnetworks::V1_1::vts::functional
diff --git a/neuralnetworks/1.1/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/1.1/vts/functional/GeneratedTestHarness.cpp
index 73eeb93..7a929d6 100644
--- a/neuralnetworks/1.1/vts/functional/GeneratedTestHarness.cpp
+++ b/neuralnetworks/1.1/vts/functional/GeneratedTestHarness.cpp
@@ -31,28 +31,21 @@
#include "1.0/Utils.h"
#include "MemoryUtils.h"
#include "TestHarness.h"
+#include "VtsHalNeuralnetworks.h"
-namespace android {
-namespace hardware {
-namespace neuralnetworks {
-namespace V1_1 {
-namespace generated_tests {
+namespace android::hardware::neuralnetworks::V1_1::vts::functional {
using namespace test_helper;
-using ::android::hardware::neuralnetworks::V1_0::DataLocation;
-using ::android::hardware::neuralnetworks::V1_0::ErrorStatus;
-using ::android::hardware::neuralnetworks::V1_0::IPreparedModel;
-using ::android::hardware::neuralnetworks::V1_0::Operand;
-using ::android::hardware::neuralnetworks::V1_0::OperandLifeTime;
-using ::android::hardware::neuralnetworks::V1_0::OperandType;
-using ::android::hardware::neuralnetworks::V1_0::Request;
-using ::android::hardware::neuralnetworks::V1_0::RequestArgument;
-using ::android::hardware::neuralnetworks::V1_0::implementation::ExecutionCallback;
-using ::android::hardware::neuralnetworks::V1_0::implementation::PreparedModelCallback;
-using ::android::hardware::neuralnetworks::V1_1::ExecutionPreference;
-using ::android::hardware::neuralnetworks::V1_1::IDevice;
-using ::android::hardware::neuralnetworks::V1_1::Model;
-using ::android::hidl::memory::V1_0::IMemory;
+using hidl::memory::V1_0::IMemory;
+using V1_0::DataLocation;
+using V1_0::ErrorStatus;
+using V1_0::IPreparedModel;
+using V1_0::Operand;
+using V1_0::OperandLifeTime;
+using V1_0::OperandType;
+using V1_0::Request;
+using V1_0::implementation::ExecutionCallback;
+using V1_0::implementation::PreparedModelCallback;
Model createModel(const TestModel& testModel) {
// Model operands.
@@ -137,9 +130,15 @@
// Top level driver for models and examples generated by test_generator.py
// Test driver for those generated from ml/nn/runtime/test/spec
-void EvaluatePreparedModel(const sp<IPreparedModel>& preparedModel, const TestModel& testModel) {
+void Execute(const sp<IDevice>& device, const TestModel& testModel) {
+ const Model model = createModel(testModel);
const Request request = createRequest(testModel);
+ // Create IPreparedModel.
+ sp<IPreparedModel> preparedModel;
+ createPreparedModel(device, model, &preparedModel);
+ if (preparedModel == nullptr) return;
+
// Launch execution.
sp<ExecutionCallback> executionCallback = new ExecutionCallback();
Return<ErrorStatus> executionLaunchStatus = preparedModel->execute(request, executionCallback);
@@ -157,50 +156,28 @@
checkResults(testModel, outputs);
}
-void Execute(const sp<IDevice>& device, const TestModel& testModel) {
- Model model = createModel(testModel);
-
- // see if service can handle model
- bool fullySupportsModel = false;
- Return<void> supportedCall = device->getSupportedOperations_1_1(
- model, [&fullySupportsModel](ErrorStatus status, const hidl_vec<bool>& supported) {
- ASSERT_EQ(ErrorStatus::NONE, status);
- ASSERT_NE(0ul, supported.size());
- fullySupportsModel = std::all_of(supported.begin(), supported.end(),
- [](bool valid) { return valid; });
- });
- ASSERT_TRUE(supportedCall.isOk());
-
- // launch prepare model
- sp<PreparedModelCallback> preparedModelCallback = new PreparedModelCallback();
- Return<ErrorStatus> prepareLaunchStatus = device->prepareModel_1_1(
- model, ExecutionPreference::FAST_SINGLE_ANSWER, preparedModelCallback);
- ASSERT_TRUE(prepareLaunchStatus.isOk());
- ASSERT_EQ(ErrorStatus::NONE, static_cast<ErrorStatus>(prepareLaunchStatus));
-
- // retrieve prepared model
- preparedModelCallback->wait();
- ErrorStatus prepareReturnStatus = preparedModelCallback->getStatus();
- sp<IPreparedModel> preparedModel = preparedModelCallback->getPreparedModel();
-
- // early termination if vendor service cannot fully prepare model
- if (!fullySupportsModel && prepareReturnStatus != ErrorStatus::NONE) {
- ASSERT_EQ(nullptr, preparedModel.get());
- LOG(INFO) << "NN VTS: Early termination of test because vendor service cannot "
- "prepare model that it does not support.";
- std::cout << "[ ] Early termination of test because vendor service cannot "
- "prepare model that it does not support."
- << std::endl;
- GTEST_SKIP();
- }
- EXPECT_EQ(ErrorStatus::NONE, prepareReturnStatus);
- ASSERT_NE(nullptr, preparedModel.get());
-
- EvaluatePreparedModel(preparedModel, testModel);
+void GeneratedTestBase::SetUp() {
+ testing::TestWithParam<GeneratedTestParam>::SetUp();
+ ASSERT_NE(kDevice, nullptr);
}
-} // namespace generated_tests
-} // namespace V1_1
-} // namespace neuralnetworks
-} // namespace hardware
-} // namespace android
+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 {};
+
+TEST_P(GeneratedTest, Test) {
+ Execute(kDevice, kTestModel);
+}
+
+INSTANTIATE_GENERATED_TEST(GeneratedTest,
+ [](const TestModel& testModel) { return !testModel.expectFailure; });
+
+} // namespace android::hardware::neuralnetworks::V1_1::vts::functional
diff --git a/neuralnetworks/1.1/vts/functional/GeneratedTestHarness.h b/neuralnetworks/1.1/vts/functional/GeneratedTestHarness.h
index 56fc825..cf449ea 100644
--- a/neuralnetworks/1.1/vts/functional/GeneratedTestHarness.h
+++ b/neuralnetworks/1.1/vts/functional/GeneratedTestHarness.h
@@ -18,22 +18,39 @@
#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 {
-namespace hardware {
-namespace neuralnetworks {
-namespace V1_1 {
-namespace generated_tests {
+namespace android::hardware::neuralnetworks::V1_1::vts::functional {
-Model createModel(const ::test_helper::TestModel& testModel);
+using NamedModel = Named<const test_helper::TestModel*>;
+using GeneratedTestParam = std::tuple<NamedDevice, NamedModel>;
-void Execute(const sp<V1_1::IDevice>& device, const ::test_helper::TestModel& testModel);
+class GeneratedTestBase : public testing::TestWithParam<GeneratedTestParam> {
+ protected:
+ void SetUp() override;
+ const sp<IDevice> kDevice = getData(std::get<NamedDevice>(GetParam()));
+ const test_helper::TestModel& kTestModel = *getData(std::get<NamedModel>(GetParam()));
+};
-} // namespace generated_tests
-} // namespace V1_1
-} // namespace neuralnetworks
-} // namespace hardware
-} // namespace android
+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);
+
+} // namespace android::hardware::neuralnetworks::V1_1::vts::functional
#endif // ANDROID_HARDWARE_NEURALNETWORKS_V1_1_GENERATED_TEST_HARNESS_H
diff --git a/neuralnetworks/1.1/vts/functional/GeneratedTests.h b/neuralnetworks/1.1/vts/functional/GeneratedTests.h
deleted file mode 100644
index a55213d..0000000
--- a/neuralnetworks/1.1/vts/functional/GeneratedTests.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "1.0/Utils.h"
-#include "GeneratedTestHarness.h"
-#include "TestHarness.h"
-#include "VtsHalNeuralnetworks.h"
-
-namespace android::hardware::neuralnetworks::V1_1::generated_tests {
-
-using namespace android::hardware::neuralnetworks::V1_1::vts::functional;
-
-using ::android::hardware::neuralnetworks::V1_0::OperandLifeTime;
-using ::android::hardware::neuralnetworks::V1_0::Request;
-
-} // namespace android::hardware::neuralnetworks::V1_1::generated_tests
diff --git a/neuralnetworks/1.1/vts/functional/TestAssertions.cpp b/neuralnetworks/1.1/vts/functional/TestAssertions.cpp
new file mode 100644
index 0000000..f4a49bc
--- /dev/null
+++ b/neuralnetworks/1.1/vts/functional/TestAssertions.cpp
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ */
+
+#include <android/hardware/neuralnetworks/1.1/types.h>
+#include "TestHarness.h"
+
+namespace android::hardware::neuralnetworks::V1_1 {
+
+// Make sure that the HIDL enums are compatible with the values defined in
+// frameworks/ml/nn/tools/test_generator/test_harness/include/TestHarness.h.
+using namespace test_helper;
+#define CHECK_TEST_ENUM(EnumType, enumValue) \
+ static_assert(static_cast<EnumType>(Test##EnumType::enumValue) == EnumType::enumValue)
+
+CHECK_TEST_ENUM(OperationType, ADD);
+CHECK_TEST_ENUM(OperationType, AVERAGE_POOL_2D);
+CHECK_TEST_ENUM(OperationType, CONCATENATION);
+CHECK_TEST_ENUM(OperationType, CONV_2D);
+CHECK_TEST_ENUM(OperationType, DEPTHWISE_CONV_2D);
+CHECK_TEST_ENUM(OperationType, DEPTH_TO_SPACE);
+CHECK_TEST_ENUM(OperationType, DEQUANTIZE);
+CHECK_TEST_ENUM(OperationType, EMBEDDING_LOOKUP);
+CHECK_TEST_ENUM(OperationType, FLOOR);
+CHECK_TEST_ENUM(OperationType, FULLY_CONNECTED);
+CHECK_TEST_ENUM(OperationType, HASHTABLE_LOOKUP);
+CHECK_TEST_ENUM(OperationType, L2_NORMALIZATION);
+CHECK_TEST_ENUM(OperationType, L2_POOL_2D);
+CHECK_TEST_ENUM(OperationType, LOCAL_RESPONSE_NORMALIZATION);
+CHECK_TEST_ENUM(OperationType, LOGISTIC);
+CHECK_TEST_ENUM(OperationType, LSH_PROJECTION);
+CHECK_TEST_ENUM(OperationType, LSTM);
+CHECK_TEST_ENUM(OperationType, MAX_POOL_2D);
+CHECK_TEST_ENUM(OperationType, MUL);
+CHECK_TEST_ENUM(OperationType, RELU);
+CHECK_TEST_ENUM(OperationType, RELU1);
+CHECK_TEST_ENUM(OperationType, RELU6);
+CHECK_TEST_ENUM(OperationType, RESHAPE);
+CHECK_TEST_ENUM(OperationType, RESIZE_BILINEAR);
+CHECK_TEST_ENUM(OperationType, RNN);
+CHECK_TEST_ENUM(OperationType, SOFTMAX);
+CHECK_TEST_ENUM(OperationType, SPACE_TO_DEPTH);
+CHECK_TEST_ENUM(OperationType, SVDF);
+CHECK_TEST_ENUM(OperationType, TANH);
+CHECK_TEST_ENUM(OperationType, BATCH_TO_SPACE_ND);
+CHECK_TEST_ENUM(OperationType, DIV);
+CHECK_TEST_ENUM(OperationType, MEAN);
+CHECK_TEST_ENUM(OperationType, PAD);
+CHECK_TEST_ENUM(OperationType, SPACE_TO_BATCH_ND);
+CHECK_TEST_ENUM(OperationType, SQUEEZE);
+CHECK_TEST_ENUM(OperationType, STRIDED_SLICE);
+CHECK_TEST_ENUM(OperationType, SUB);
+CHECK_TEST_ENUM(OperationType, TRANSPOSE);
+
+#undef CHECK_TEST_ENUM
+
+} // namespace android::hardware::neuralnetworks::V1_1
diff --git a/neuralnetworks/1.1/vts/functional/ValidateModel.cpp b/neuralnetworks/1.1/vts/functional/ValidateModel.cpp
index fb80d13..0629a1e 100644
--- a/neuralnetworks/1.1/vts/functional/ValidateModel.cpp
+++ b/neuralnetworks/1.1/vts/functional/ValidateModel.cpp
@@ -18,25 +18,22 @@
#include "1.0/Callbacks.h"
#include "1.0/Utils.h"
+#include "GeneratedTestHarness.h"
#include "VtsHalNeuralnetworks.h"
-namespace android {
-namespace hardware {
-namespace neuralnetworks {
-namespace V1_1 {
-namespace vts {
-namespace functional {
+namespace android::hardware::neuralnetworks::V1_1::vts::functional {
-using ::android::hardware::neuralnetworks::V1_0::IPreparedModel;
-using ::android::hardware::neuralnetworks::V1_0::Operand;
-using ::android::hardware::neuralnetworks::V1_0::OperandLifeTime;
-using ::android::hardware::neuralnetworks::V1_0::OperandType;
-using ::android::hardware::neuralnetworks::V1_0::implementation::PreparedModelCallback;
+using V1_0::ErrorStatus;
+using V1_0::IPreparedModel;
+using V1_0::Operand;
+using V1_0::OperandLifeTime;
+using V1_0::OperandType;
+using V1_0::implementation::PreparedModelCallback;
///////////////////////// UTILITY FUNCTIONS /////////////////////////
static void validateGetSupportedOperations(const sp<IDevice>& device, const std::string& message,
- const V1_1::Model& model) {
+ const Model& model) {
SCOPED_TRACE(message + " [getSupportedOperations_1_1]");
Return<void> ret = device->getSupportedOperations_1_1(
@@ -47,11 +44,10 @@
}
static void validatePrepareModel(const sp<IDevice>& device, const std::string& message,
- const V1_1::Model& model, ExecutionPreference preference) {
+ const Model& model, ExecutionPreference preference) {
SCOPED_TRACE(message + " [prepareModel_1_1]");
sp<PreparedModelCallback> preparedModelCallback = new PreparedModelCallback();
- ASSERT_NE(nullptr, preparedModelCallback.get());
Return<ErrorStatus> prepareLaunchStatus =
device->prepareModel_1_1(model, preference, preparedModelCallback);
ASSERT_TRUE(prepareLaunchStatus.isOk());
@@ -74,7 +70,7 @@
// mutation to it to invalidate the model, then pass it to interface calls that
// use the model. Note that the model here is passed by value, and any mutation
// to the model does not leave this function.
-static void validate(const sp<IDevice>& device, const std::string& message, V1_1::Model model,
+static void validate(const sp<IDevice>& device, const std::string& message, Model model,
const std::function<void(Model*)>& mutation,
ExecutionPreference preference = ExecutionPreference::FAST_SINGLE_ANSWER) {
mutation(&model);
@@ -113,7 +109,7 @@
static_cast<int32_t>(OperandType::TENSOR_OEM_BYTE) + 1, // upper bound OEM
};
-static void mutateOperandTypeTest(const sp<IDevice>& device, const V1_1::Model& model) {
+static void mutateOperandTypeTest(const sp<IDevice>& device, const Model& model) {
for (size_t operand = 0; operand < model.operands.size(); ++operand) {
for (int32_t invalidOperandType : invalidOperandTypes) {
const std::string message = "mutateOperandTypeTest: operand " +
@@ -143,7 +139,7 @@
}
}
-static void mutateOperandRankTest(const sp<IDevice>& device, const V1_1::Model& model) {
+static void mutateOperandRankTest(const sp<IDevice>& device, const Model& model) {
for (size_t operand = 0; operand < model.operands.size(); ++operand) {
const uint32_t invalidRank = getInvalidRank(model.operands[operand].type);
const std::string message = "mutateOperandRankTest: operand " + std::to_string(operand) +
@@ -172,7 +168,7 @@
}
}
-static void mutateOperandScaleTest(const sp<IDevice>& device, const V1_1::Model& model) {
+static void mutateOperandScaleTest(const sp<IDevice>& device, const Model& model) {
for (size_t operand = 0; operand < model.operands.size(); ++operand) {
const float invalidScale = getInvalidScale(model.operands[operand].type);
const std::string message = "mutateOperandScaleTest: operand " + std::to_string(operand) +
@@ -200,7 +196,7 @@
}
}
-static void mutateOperandZeroPointTest(const sp<IDevice>& device, const V1_1::Model& model) {
+static void mutateOperandZeroPointTest(const sp<IDevice>& device, const Model& model) {
for (size_t operand = 0; operand < model.operands.size(); ++operand) {
const std::vector<int32_t> invalidZeroPoints =
getInvalidZeroPoints(model.operands[operand].type);
@@ -257,7 +253,7 @@
*operand = newOperand;
}
-static bool mutateOperationOperandTypeSkip(size_t operand, const V1_1::Model& model) {
+static bool mutateOperationOperandTypeSkip(size_t operand, const Model& model) {
// LSH_PROJECTION's second argument is allowed to have any type. This is the
// only operation that currently has a type that can be anything independent
// from any other type. Changing the operand type to any other type will
@@ -271,7 +267,7 @@
return false;
}
-static void mutateOperationOperandTypeTest(const sp<IDevice>& device, const V1_1::Model& model) {
+static void mutateOperationOperandTypeTest(const sp<IDevice>& device, const Model& model) {
for (size_t operand = 0; operand < model.operands.size(); ++operand) {
if (mutateOperationOperandTypeSkip(operand, model)) {
continue;
@@ -302,7 +298,7 @@
static_cast<int32_t>(OperationType::OEM_OPERATION) + 1, // upper bound OEM
};
-static void mutateOperationTypeTest(const sp<IDevice>& device, const V1_1::Model& model) {
+static void mutateOperationTypeTest(const sp<IDevice>& device, const Model& model) {
for (size_t operation = 0; operation < model.operations.size(); ++operation) {
for (int32_t invalidOperationType : invalidOperationTypes) {
const std::string message = "mutateOperationTypeTest: operation " +
@@ -318,8 +314,7 @@
///////////////////////// VALIDATE MODEL OPERATION INPUT OPERAND INDEX /////////////////////////
-static void mutateOperationInputOperandIndexTest(const sp<IDevice>& device,
- const V1_1::Model& model) {
+static void mutateOperationInputOperandIndexTest(const sp<IDevice>& device, const Model& model) {
for (size_t operation = 0; operation < model.operations.size(); ++operation) {
const uint32_t invalidOperand = model.operands.size();
for (size_t input = 0; input < model.operations[operation].inputs.size(); ++input) {
@@ -335,8 +330,7 @@
///////////////////////// VALIDATE MODEL OPERATION OUTPUT OPERAND INDEX /////////////////////////
-static void mutateOperationOutputOperandIndexTest(const sp<IDevice>& device,
- const V1_1::Model& model) {
+static void mutateOperationOutputOperandIndexTest(const sp<IDevice>& device, const Model& model) {
for (size_t operation = 0; operation < model.operations.size(); ++operation) {
const uint32_t invalidOperand = model.operands.size();
for (size_t output = 0; output < model.operations[operation].outputs.size(); ++output) {
@@ -374,7 +368,7 @@
removeValueAndDecrementGreaterValues(&model->outputIndexes, index);
}
-static void removeOperandTest(const sp<IDevice>& device, const V1_1::Model& model) {
+static void removeOperandTest(const sp<IDevice>& device, const Model& model) {
for (size_t operand = 0; operand < model.operands.size(); ++operand) {
const std::string message = "removeOperandTest: operand " + std::to_string(operand);
validate(device, message, model,
@@ -391,7 +385,7 @@
hidl_vec_removeAt(&model->operations, index);
}
-static void removeOperationTest(const sp<IDevice>& device, const V1_1::Model& model) {
+static void removeOperationTest(const sp<IDevice>& device, const Model& model) {
for (size_t operation = 0; operation < model.operations.size(); ++operation) {
const std::string message = "removeOperationTest: operation " + std::to_string(operation);
validate(device, message, model,
@@ -401,14 +395,14 @@
///////////////////////// REMOVE OPERATION INPUT /////////////////////////
-static void removeOperationInputTest(const sp<IDevice>& device, const V1_1::Model& model) {
+static void removeOperationInputTest(const sp<IDevice>& device, const Model& model) {
for (size_t operation = 0; operation < model.operations.size(); ++operation) {
for (size_t input = 0; input < model.operations[operation].inputs.size(); ++input) {
- const V1_1::Operation& op = model.operations[operation];
+ const Operation& op = model.operations[operation];
// CONCATENATION has at least 2 inputs, with the last element being
// INT32. Skip this test if removing one of CONCATENATION's
// inputs still produces a valid model.
- if (op.type == V1_1::OperationType::CONCATENATION && op.inputs.size() > 2 &&
+ if (op.type == OperationType::CONCATENATION && op.inputs.size() > 2 &&
input != op.inputs.size() - 1) {
continue;
}
@@ -426,7 +420,7 @@
///////////////////////// REMOVE OPERATION OUTPUT /////////////////////////
-static void removeOperationOutputTest(const sp<IDevice>& device, const V1_1::Model& model) {
+static void removeOperationOutputTest(const sp<IDevice>& device, const Model& model) {
for (size_t operation = 0; operation < model.operations.size(); ++operation) {
for (size_t output = 0; output < model.operations[operation].outputs.size(); ++output) {
const std::string message = "removeOperationOutputTest: operation " +
@@ -447,7 +441,7 @@
///////////////////////// ADD OPERATION INPUT /////////////////////////
-static void addOperationInputTest(const sp<IDevice>& device, const V1_1::Model& model) {
+static void addOperationInputTest(const sp<IDevice>& device, const Model& model) {
for (size_t operation = 0; operation < model.operations.size(); ++operation) {
const std::string message = "addOperationInputTest: operation " + std::to_string(operation);
validate(device, message, model, [operation](Model* model) {
@@ -460,7 +454,7 @@
///////////////////////// ADD OPERATION OUTPUT /////////////////////////
-static void addOperationOutputTest(const sp<IDevice>& device, const V1_1::Model& model) {
+static void addOperationOutputTest(const sp<IDevice>& device, const Model& model) {
for (size_t operation = 0; operation < model.operations.size(); ++operation) {
const std::string message =
"addOperationOutputTest: operation " + std::to_string(operation);
@@ -479,18 +473,19 @@
static_cast<int32_t>(ExecutionPreference::SUSTAINED_SPEED) + 1, // upper bound
};
-static void mutateExecutionPreferenceTest(const sp<IDevice>& device, const V1_1::Model& model) {
+static void mutateExecutionPreferenceTest(const sp<IDevice>& device, const Model& model) {
for (int32_t preference : invalidExecutionPreferences) {
const std::string message =
"mutateExecutionPreferenceTest: preference " + std::to_string(preference);
- validate(device, message, model, [](Model*) {},
- static_cast<ExecutionPreference>(preference));
+ validate(
+ device, message, model, [](Model*) {},
+ static_cast<ExecutionPreference>(preference));
}
}
////////////////////////// ENTRY POINT //////////////////////////////
-void ValidationTest::validateModel(const V1_1::Model& model) {
+void validateModel(const sp<IDevice>& device, const Model& model) {
mutateOperandTypeTest(device, model);
mutateOperandRankTest(device, model);
mutateOperandScaleTest(device, model);
@@ -508,9 +503,4 @@
mutateExecutionPreferenceTest(device, model);
}
-} // namespace functional
-} // namespace vts
-} // namespace V1_1
-} // namespace neuralnetworks
-} // namespace hardware
-} // namespace android
+} // namespace android::hardware::neuralnetworks::V1_1::vts::functional
diff --git a/neuralnetworks/1.1/vts/functional/ValidateRequest.cpp b/neuralnetworks/1.1/vts/functional/ValidateRequest.cpp
index 757bee9..9684eb2 100644
--- a/neuralnetworks/1.1/vts/functional/ValidateRequest.cpp
+++ b/neuralnetworks/1.1/vts/functional/ValidateRequest.cpp
@@ -18,19 +18,15 @@
#include "1.0/Callbacks.h"
#include "1.0/Utils.h"
+#include "GeneratedTestHarness.h"
#include "VtsHalNeuralnetworks.h"
-namespace android {
-namespace hardware {
-namespace neuralnetworks {
-namespace V1_1 {
-namespace vts {
-namespace functional {
+namespace android::hardware::neuralnetworks::V1_1::vts::functional {
-using ::android::hardware::neuralnetworks::V1_0::ErrorStatus;
-using ::android::hardware::neuralnetworks::V1_0::Request;
-using ::android::hardware::neuralnetworks::V1_0::implementation::ExecutionCallback;
-using ::android::hardware::neuralnetworks::V1_1::IPreparedModel;
+using V1_0::ErrorStatus;
+using V1_0::IPreparedModel;
+using V1_0::Request;
+using V1_0::implementation::ExecutionCallback;
///////////////////////// UTILITY FUNCTIONS /////////////////////////
@@ -44,7 +40,6 @@
SCOPED_TRACE(message + " [execute]");
sp<ExecutionCallback> executionCallback = new ExecutionCallback();
- ASSERT_NE(nullptr, executionCallback.get());
Return<ErrorStatus> executeLaunchStatus = preparedModel->execute(request, executionCallback);
ASSERT_TRUE(executeLaunchStatus.isOk());
ASSERT_EQ(ErrorStatus::INVALID_ARGUMENT, static_cast<ErrorStatus>(executeLaunchStatus));
@@ -76,15 +71,9 @@
///////////////////////////// ENTRY POINT //////////////////////////////////
-void ValidationTest::validateRequest(const sp<IPreparedModel>& preparedModel,
- const Request& request) {
+void validateRequest(const sp<IPreparedModel>& preparedModel, const Request& request) {
removeInputTest(preparedModel, request);
removeOutputTest(preparedModel, request);
}
-} // namespace functional
-} // namespace vts
-} // namespace V1_1
-} // namespace neuralnetworks
-} // namespace hardware
-} // namespace android
+} // 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 b3b15fa..d56d40b 100644
--- a/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworks.cpp
+++ b/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworks.cpp
@@ -17,46 +17,48 @@
#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"
-namespace android {
-namespace hardware {
-namespace neuralnetworks {
-namespace V1_1 {
-namespace vts {
-namespace functional {
+namespace android::hardware::neuralnetworks::V1_1::vts::functional {
-using ::android::hardware::neuralnetworks::V1_0::implementation::PreparedModelCallback;
+using V1_0::ErrorStatus;
+using V1_0::IPreparedModel;
+using V1_0::Request;
+using V1_0::implementation::PreparedModelCallback;
-static void createPreparedModel(const sp<IDevice>& device, const V1_1::Model& model,
- sp<IPreparedModel>* preparedModel) {
+void createPreparedModel(const sp<IDevice>& device, const Model& model,
+ sp<IPreparedModel>* preparedModel) {
ASSERT_NE(nullptr, preparedModel);
+ *preparedModel = nullptr;
// see if service can handle model
bool fullySupportsModel = false;
- Return<void> supportedOpsLaunchStatus = device->getSupportedOperations_1_1(
+ const Return<void> supportedCall = device->getSupportedOperations_1_1(
model, [&fullySupportsModel](ErrorStatus status, const hidl_vec<bool>& supported) {
ASSERT_EQ(ErrorStatus::NONE, status);
ASSERT_NE(0ul, supported.size());
fullySupportsModel = std::all_of(supported.begin(), supported.end(),
[](bool valid) { return valid; });
});
- ASSERT_TRUE(supportedOpsLaunchStatus.isOk());
+ ASSERT_TRUE(supportedCall.isOk());
// launch prepare model
- sp<PreparedModelCallback> preparedModelCallback = new PreparedModelCallback();
- ASSERT_NE(nullptr, preparedModelCallback.get());
- Return<ErrorStatus> prepareLaunchStatus = device->prepareModel_1_1(
+ const sp<PreparedModelCallback> preparedModelCallback = new PreparedModelCallback();
+ const Return<ErrorStatus> prepareLaunchStatus = device->prepareModel_1_1(
model, ExecutionPreference::FAST_SINGLE_ANSWER, preparedModelCallback);
ASSERT_TRUE(prepareLaunchStatus.isOk());
ASSERT_EQ(ErrorStatus::NONE, static_cast<ErrorStatus>(prepareLaunchStatus));
// retrieve prepared model
preparedModelCallback->wait();
- ErrorStatus prepareReturnStatus = preparedModelCallback->getStatus();
+ const ErrorStatus prepareReturnStatus = preparedModelCallback->getStatus();
*preparedModel = preparedModelCallback->getPreparedModel();
// The getSupportedOperations_1_1 call returns a list of operations that are
@@ -68,99 +70,73 @@
// can continue.
if (!fullySupportsModel && prepareReturnStatus != ErrorStatus::NONE) {
ASSERT_EQ(nullptr, preparedModel->get());
- LOG(INFO) << "NN VTS: Unable to test Request validation because vendor service cannot "
- "prepare model that it does not support.";
- std::cout << "[ ] Unable to test Request validation because vendor service "
- "cannot prepare model that it does not support."
+ LOG(INFO) << "NN VTS: Early termination of test because vendor service cannot prepare "
+ "model that it does not support.";
+ std::cout << "[ ] Early termination of test because vendor service cannot "
+ "prepare model that it does not support."
<< std::endl;
- return;
+ GTEST_SKIP();
}
ASSERT_EQ(ErrorStatus::NONE, prepareReturnStatus);
ASSERT_NE(nullptr, preparedModel->get());
}
-// A class for test environment setup
-NeuralnetworksHidlEnvironment::NeuralnetworksHidlEnvironment() {}
-
-NeuralnetworksHidlEnvironment::~NeuralnetworksHidlEnvironment() {}
-
-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.
-NeuralnetworksHidlTest::NeuralnetworksHidlTest() {}
-
-NeuralnetworksHidlTest::~NeuralnetworksHidlTest() {}
-
void NeuralnetworksHidlTest::SetUp() {
- ::testing::VtsHalHidlTargetTestBase::SetUp();
- device = ::testing::VtsHalHidlTargetTestBase::getService<IDevice>(
- NeuralnetworksHidlEnvironment::getInstance());
-
-#ifdef PRESUBMIT_NOT_VTS
- const std::string name =
- NeuralnetworksHidlEnvironment::getInstance()->getServiceName<IDevice>();
- const std::string sampleDriver = "sample-";
- if (device == nullptr && name.substr(0, sampleDriver.size()) == sampleDriver) {
- GTEST_SKIP();
- }
-#endif // PRESUBMIT_NOT_VTS
-
- ASSERT_NE(nullptr, device.get());
+ testing::TestWithParam<NeuralnetworksHidlTestParam>::SetUp();
+ ASSERT_NE(kDevice, nullptr);
}
-void NeuralnetworksHidlTest::TearDown() {
- device = nullptr;
- ::testing::VtsHalHidlTargetTestBase::TearDown();
+static NamedDevice makeNamedDevice(const std::string& name) {
+ return {name, IDevice::getService(name)};
}
-void ValidationTest::validateEverything(const Model& model, const Request& request) {
- validateModel(model);
+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);
- // create IPreparedModel
+ // 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
+void validateRequest(const sp<V1_0::IPreparedModel>& preparedModel, const V1_0::Request& request);
+
+void validateEverything(const sp<IDevice>& device, const Model& model, const Request& request) {
+ validateModel(device, model);
+
+ // Create IPreparedModel.
sp<IPreparedModel> preparedModel;
- ASSERT_NO_FATAL_FAILURE(createPreparedModel(device, model, &preparedModel));
- if (preparedModel == nullptr) {
- return;
- }
+ createPreparedModel(device, model, &preparedModel);
+ if (preparedModel == nullptr) return;
validateRequest(preparedModel, request);
}
-} // namespace functional
-} // namespace vts
-} // namespace V1_1
-} // namespace neuralnetworks
-} // namespace hardware
-} // namespace android
-
-namespace android::hardware::neuralnetworks::V1_0 {
-
-::std::ostream& operator<<(::std::ostream& os, ErrorStatus errorStatus) {
- return os << toString(errorStatus);
+TEST_P(ValidationTest, Test) {
+ const Model model = createModel(kTestModel);
+ const Request request = createRequest(kTestModel);
+ ASSERT_FALSE(kTestModel.expectFailure);
+ validateEverything(kDevice, model, request);
}
-::std::ostream& operator<<(::std::ostream& os, DeviceStatus deviceStatus) {
- return os << toString(deviceStatus);
-}
+INSTANTIATE_GENERATED_TEST(ValidationTest, [](const test_helper::TestModel&) { return true; });
-} // namespace android::hardware::neuralnetworks::V1_0
-
-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;
-}
+} // namespace android::hardware::neuralnetworks::V1_1::vts::functional
diff --git a/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworks.h b/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworks.h
index 2d6a20c..e879d84 100644
--- a/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworks.h
+++ b/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworks.h
@@ -17,84 +17,38 @@
#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 <iostream>
#include <vector>
+#include "1.0/Utils.h"
-namespace android {
-namespace hardware {
-namespace neuralnetworks {
-namespace V1_1 {
+namespace android::hardware::neuralnetworks::V1_1::vts::functional {
-using V1_0::DeviceStatus;
-using V1_0::ErrorStatus;
-using V1_0::IPreparedModel;
-using V1_0::Operand;
-using V1_0::OperandType;
-using V1_0::Request;
+using NamedDevice = Named<sp<IDevice>>;
+using NeuralnetworksHidlTestParam = NamedDevice;
-namespace vts {
-namespace functional {
-
-// A class for test environment setup
-class NeuralnetworksHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- DISALLOW_COPY_AND_ASSIGN(NeuralnetworksHidlEnvironment);
- NeuralnetworksHidlEnvironment();
- ~NeuralnetworksHidlEnvironment() override;
-
- 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();
- ~NeuralnetworksHidlTest() override;
+class NeuralnetworksHidlTest : public testing::TestWithParam<NeuralnetworksHidlTestParam> {
+ protected:
void SetUp() override;
- void TearDown() override;
-
- protected:
- sp<IDevice> device;
+ const sp<IDevice> kDevice = getData(GetParam());
};
-// Tag for the validation tests
-class ValidationTest : public NeuralnetworksHidlTest {
- protected:
- void validateEverything(const Model& model, const Request& request);
+const std::vector<NamedDevice>& getNamedDevices();
- private:
- void validateModel(const Model& model);
- void validateRequest(const sp<IPreparedModel>& preparedModel, const Request& request);
-};
+std::string printNeuralnetworksHidlTest(
+ const testing::TestParamInfo<NeuralnetworksHidlTestParam>& info);
-// Tag for the generated tests
-class GeneratedTest : public NeuralnetworksHidlTest {};
+#define INSTANTIATE_DEVICE_TEST(TestSuite) \
+ INSTANTIATE_TEST_SUITE_P(PerInstance, TestSuite, testing::ValuesIn(getNamedDevices()), \
+ printNeuralnetworksHidlTest)
-} // namespace functional
-} // namespace vts
-} // namespace V1_1
-} // namespace neuralnetworks
-} // namespace hardware
-} // namespace android
+// Create an IPreparedModel object. If the model cannot be prepared,
+// "preparedModel" will be nullptr instead.
+void createPreparedModel(const sp<IDevice>& device, const Model& model,
+ sp<V1_0::IPreparedModel>* preparedModel);
-namespace android::hardware::neuralnetworks::V1_0 {
-
-// pretty-print values for error messages
-::std::ostream& operator<<(::std::ostream& os, ErrorStatus errorStatus);
-::std::ostream& operator<<(::std::ostream& os, DeviceStatus deviceStatus);
-
-} // namespace android::hardware::neuralnetworks::V1_0
+} // namespace android::hardware::neuralnetworks::V1_1::vts::functional
#endif // ANDROID_HARDWARE_NEURALNETWORKS_V1_1_VTS_HAL_NEURALNETWORKS_H
diff --git a/neuralnetworks/1.2/IDevice.hal b/neuralnetworks/1.2/IDevice.hal
index d83f9e6..ff20c12 100644
--- a/neuralnetworks/1.2/IDevice.hal
+++ b/neuralnetworks/1.2/IDevice.hal
@@ -64,14 +64,14 @@
* results, the developer could choose an ACCELERATOR type device for ML
* workloads, and reserve GPU for graphical rendering.
*
- * @param status Error status returned from querying the device type. Must be:
- * - NONE if the query was successful
- * - DEVICE_UNAVAILABLE if driver is offline or busy
- * - GENERAL_FAILURE if the query resulted in an
- * unspecified error
- * @param type The DeviceType of the device. Please note, this is not a
- * bitfield of DeviceTypes. Each device must only be of a
- * single DeviceType.
+ * @return status Error status returned from querying the device type. Must be:
+ * - NONE if the query was successful
+ * - DEVICE_UNAVAILABLE if driver is offline or busy
+ * - GENERAL_FAILURE if the query resulted in an
+ * unspecified error
+ * @return type The DeviceType of the device. Please note, this is not a
+ * bitfield of DeviceTypes. Each device must only be of a
+ * single DeviceType.
*/
getType() generates (ErrorStatus status, DeviceType type);
diff --git a/neuralnetworks/1.2/IPreparedModel.hal b/neuralnetworks/1.2/IPreparedModel.hal
index ba16334..1445f18 100644
--- a/neuralnetworks/1.2/IPreparedModel.hal
+++ b/neuralnetworks/1.2/IPreparedModel.hal
@@ -54,11 +54,14 @@
* must not change the content of any of the data objects corresponding to
* 'request' inputs.
*
- * If the prepared model was prepared from a model wherein all
- * tensor operands have fully specified dimensions, and the inputs
- * to the function are valid, then the execution should launch
- * and complete successfully (ErrorStatus::NONE). There must be
- * no failure unless the device itself is in a bad state.
+ * If the prepared model was prepared from a model wherein all tensor
+ * operands have fully specified dimensions, and the inputs to the function
+ * are valid, then:
+ * - the execution should launch successfully (ErrorStatus::NONE): There
+ * must be no failure unless the device itself is in a bad state.
+ * - if at execution time every operation's input operands have legal
+ * values, the execution should complete successfully (ErrorStatus::NONE):
+ * There must be no failure unless the device itself is in a bad state.
*
* Any number of calls to the execute, execute_1_2, and executeSynchronously
* functions, in any combination, may be made concurrently, even on the same
@@ -105,8 +108,9 @@
*
* If the prepared model was prepared from a model wherein all tensor
* operands have fully specified dimensions, and the inputs to the function
- * are valid, then the execution should complete successfully
- * (ErrorStatus::NONE). There must be no failure unless the device itself is
+ * are valid, and at execution time every operation's input operands have
+ * legal values, then the execution should complete successfully
+ * (ErrorStatus::NONE): There must be no failure unless the device itself is
* in a bad state.
*
* Any number of calls to the execute, execute_1_2, and executeSynchronously
@@ -145,23 +149,52 @@
* Configure a Burst object used to execute multiple inferences on a
* prepared model in rapid succession.
*
+ * If the prepared model was prepared from a model wherein all tensor
+ * operands have fully specified dimensions, and a valid serialized Request
+ * is sent to the Burst for execution, and at execution time every
+ * operation's input operands have legal values, then the execution should
+ * complete successfully (ErrorStatus::NONE): There must be no failure
+ * unless the device itself is in a bad state.
+ *
* @param callback A callback object used to retrieve memory resources
- * corresponding to a unique identifiers ("slots").
- * @param requestChannel Used by the client to send a serialized Request to
- * the Burst for execution. The client must not change
- * the content of any data object referenced by the
- * Request (described by the {@link @1.0::DataLocation}
- * of an {@link OperandInformation}) until a result
- * has been received from resultChannel. Execution
- * must not change the content of any of the data
- * objects corresponding to Request inputs. requestChannel
+ * corresponding to unique identifiers ("slots").
+ * @param requestChannel FMQ used by the client to send a serialized Request
+ * to the Burst for execution. The client must not
+ * change the content of any data object referenced by
+ * the Request (described by the
+ * {@link @1.0::DataLocation} of an
+ * {@link OperandInformation}) until a result has been
+ * received from resultChannel. Execution must not
+ * change the content of any of the data objects
+ * corresponding to Request inputs. requestChannel
* must not be used to pass a second Request object
- * until a result has been received from resultChannel.
- * @param resultChannel Used by the service to return the results of an
- * execution to the client: the status of the execution
- * and OutputShape of all output tensors. resultChannel
- * must be used to return the results if a Request was
- * sent through the requestChannel.
+ * until a result has been received from
+ * resultChannel. The client must send the request
+ * messages to the consumer atomically by using
+ * MessageQueue::writeBlocking if the queue is
+ * blocking, or by using MessageQueue::write if the
+ * queue is non-blocking. When the service receives a
+ * packet, it must dequeue the entire packet from the
+ * requestChannel. The client must not send a request
+ * packet that exceeds the length of the FMQ.
+ * @param resultChannel FMQ used by the service to return the results of an
+ * execution to the client: the status of the
+ * execution, OutputShape of all output tensors, and
+ * timing information. resultChannel must be used to
+ * return the results if a Request was sent through the
+ * requestChannel. The service must send the result
+ * messages to the consumer atomically by using
+ * MessageQueue::writeBlocking if the queue is
+ * blocking, or by using MessageQueue::write if the
+ * queue is non-blocking. When the client receives a
+ * packet, it must dequeue the entire packet from the
+ * resultChannel. If the packet's length exceeds the
+ * size of the FMQ, the service must not send this
+ * result packet; instead, the service must send a
+ * packet consisting of the error code
+ * ErrorStatus::GENERAL_FAILURE, no information for the
+ * outputShapes, and an indication that timing
+ * information is unavailable.
* @return status Error status of configuring the execution burst, must be:
* - NONE if the burst is successfully configured
* - DEVICE_UNAVAILABLE if driver is offline or busy
diff --git a/neuralnetworks/1.2/vts/functional/Android.bp b/neuralnetworks/1.2/vts/functional/Android.bp
index e14430f..3ba8879 100644
--- a/neuralnetworks/1.2/vts/functional/Android.bp
+++ b/neuralnetworks/1.2/vts/functional/Android.bp
@@ -14,15 +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: [
@@ -41,54 +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"],
}
-
-// Tests for V1_0 models using the V1_2 HAL.
-cc_test {
- name: "VtsHalNeuralnetworksV1_2CompatV1_0TargetTest",
- defaults: ["VtsHalNeuralNetworksV1_2TargetTestDefaults"],
- srcs: [
- ":VtsHalNeuralNetworksV1_2_all_generated_V1_0_tests",
- "ValidateBurst.cpp",
- ],
-}
-
-// Tests for V1_1 models using the V1_2 HAL.
-cc_test {
- name: "VtsHalNeuralnetworksV1_2CompatV1_1TargetTest",
- defaults: ["VtsHalNeuralNetworksV1_2TargetTestDefaults"],
- srcs: [
- ":VtsHalNeuralNetworksV1_2_all_generated_V1_1_tests",
- "ValidateBurst.cpp",
- ],
-}
-
-// Tests for V1_2 models.
-cc_test {
- name: "VtsHalNeuralnetworksV1_2TargetTest",
- defaults: ["VtsHalNeuralNetworksV1_2TargetTestDefaults"],
- srcs: [
- "BasicTests.cpp",
- ":VtsHalNeuralNetworksV1_2_all_generated_V1_2_tests",
- ":VtsHalNeuralNetworksV1_2_mobilenets",
- "CompilationCachingTests.cpp",
- "ValidateBurst.cpp",
- ],
-}
-
-cc_test {
- name: "PresubmitHalNeuralnetworksV1_2TargetTest",
- defaults: ["VtsHalNeuralNetworksV1_2TargetTestDefaults"],
- srcs: [
- "BasicTests.cpp",
- ":VtsHalNeuralNetworksV1_2_all_generated_V1_2_tests",
- "ValidateBurst.cpp",
- ],
- cflags: [
- "-DPRESUBMIT_NOT_VTS",
- ],
-}
diff --git a/neuralnetworks/1.2/vts/functional/BasicTests.cpp b/neuralnetworks/1.2/vts/functional/BasicTests.cpp
index 5c269df..8e82c53 100644
--- a/neuralnetworks/1.2/vts/functional/BasicTests.cpp
+++ b/neuralnetworks/1.2/vts/functional/BasicTests.cpp
@@ -18,30 +18,27 @@
#include "VtsHalNeuralnetworks.h"
-namespace android {
-namespace hardware {
-namespace neuralnetworks {
-namespace V1_2 {
-namespace vts {
-namespace functional {
+namespace android::hardware::neuralnetworks::V1_2::vts::functional {
+using V1_0::DeviceStatus;
+using V1_0::ErrorStatus;
using V1_0::PerformanceInfo;
// create device test
-TEST_F(NeuralnetworksHidlTest, CreateDevice) {}
+TEST_P(NeuralnetworksHidlTest, CreateDevice) {}
// status test
-TEST_F(NeuralnetworksHidlTest, StatusTest) {
- Return<DeviceStatus> status = device->getStatus();
+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 = device->getCapabilities_1_2([](ErrorStatus status,
- const Capabilities& capabilities) {
+ Return<void> ret = kDevice->getCapabilities_1_2([](ErrorStatus status,
+ const Capabilities& capabilities) {
EXPECT_EQ(ErrorStatus::NONE, status);
auto isPositive = [](const PerformanceInfo& perf) {
@@ -63,17 +60,18 @@
}
// device version test
-TEST_F(NeuralnetworksHidlTest, GetDeviceVersionStringTest) {
- Return<void> ret = device->getVersionString([](ErrorStatus status, const hidl_string& version) {
- EXPECT_EQ(ErrorStatus::NONE, status);
- EXPECT_LT(0, version.size());
- });
+TEST_P(NeuralnetworksHidlTest, GetDeviceVersionStringTest) {
+ Return<void> ret =
+ kDevice->getVersionString([](ErrorStatus status, const hidl_string& version) {
+ EXPECT_EQ(ErrorStatus::NONE, status);
+ EXPECT_LT(0, version.size());
+ });
EXPECT_TRUE(ret.isOk());
}
// device type test
-TEST_F(NeuralnetworksHidlTest, GetDeviceTypeTest) {
- Return<void> ret = device->getType([](ErrorStatus status, DeviceType type) {
+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 ||
type == DeviceType::GPU || type == DeviceType::ACCELERATOR);
@@ -82,8 +80,8 @@
}
// device supported extensions test
-TEST_F(NeuralnetworksHidlTest, GetDeviceSupportedExtensionsTest) {
- Return<void> ret = device->getSupportedExtensions(
+TEST_P(NeuralnetworksHidlTest, GetDeviceSupportedExtensionsTest) {
+ Return<void> ret = kDevice->getSupportedExtensions(
[](ErrorStatus status, const hidl_vec<Extension>& extensions) {
EXPECT_EQ(ErrorStatus::NONE, status);
for (auto& extension : extensions) {
@@ -103,8 +101,8 @@
}
// getNumberOfCacheFilesNeeded test
-TEST_F(NeuralnetworksHidlTest, getNumberOfCacheFilesNeeded) {
- Return<void> ret = device->getNumberOfCacheFilesNeeded(
+TEST_P(NeuralnetworksHidlTest, getNumberOfCacheFilesNeeded) {
+ Return<void> ret = kDevice->getNumberOfCacheFilesNeeded(
[](ErrorStatus status, uint32_t numModelCache, uint32_t numDataCache) {
EXPECT_EQ(ErrorStatus::NONE, status);
EXPECT_LE(numModelCache,
@@ -113,9 +111,4 @@
});
EXPECT_TRUE(ret.isOk());
}
-} // namespace functional
-} // namespace vts
-} // namespace V1_2
-} // namespace neuralnetworks
-} // namespace hardware
-} // namespace android
+} // namespace android::hardware::neuralnetworks::V1_2::vts::functional
diff --git a/neuralnetworks/1.2/vts/functional/Callbacks.cpp b/neuralnetworks/1.2/vts/functional/Callbacks.cpp
index a607a08..3972ad6 100644
--- a/neuralnetworks/1.2/vts/functional/Callbacks.cpp
+++ b/neuralnetworks/1.2/vts/functional/Callbacks.cpp
@@ -24,6 +24,8 @@
namespace android::hardware::neuralnetworks::V1_2::implementation {
+using V1_0::ErrorStatus;
+
constexpr Timing kNoTiming = {.timeOnDevice = std::numeric_limits<uint64_t>::max(),
.timeInDriver = std::numeric_limits<uint64_t>::max()};
diff --git a/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp b/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp
index 8747fb3..2130a76 100644
--- a/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp
+++ b/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp
@@ -17,7 +17,7 @@
#define LOG_TAG "neuralnetworks_hidl_hal_test"
#include <android-base/logging.h>
-#include <android/hidl/memory/1.0/IMemory.h>
+#include <fcntl.h>
#include <ftw.h>
#include <gtest/gtest.h>
#include <hidlmemory/mapping.h>
@@ -38,37 +38,29 @@
// 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 {
-namespace hardware {
-namespace neuralnetworks {
-namespace V1_2 {
-namespace vts {
-namespace functional {
+namespace android::hardware::neuralnetworks::V1_2::vts::functional {
using namespace test_helper;
-using ::android::hardware::neuralnetworks::V1_0::OperandLifeTime;
-using ::android::hardware::neuralnetworks::V1_1::ExecutionPreference;
-using ::android::hardware::neuralnetworks::V1_2::implementation::ExecutionCallback;
-using ::android::hardware::neuralnetworks::V1_2::implementation::PreparedModelCallback;
-using ::android::hidl::memory::V1_0::IMemory;
-using ::android::nn::allocateSharedMemory;
+using implementation::PreparedModelCallback;
+using V1_0::ErrorStatus;
+using V1_1::ExecutionPreference;
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
@@ -226,13 +218,14 @@
} // 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();
- ASSERT_NE(device.get(), nullptr);
+ testing::Test::SetUp();
+ ASSERT_NE(kDevice.get(), nullptr);
// Create cache directory. The cache directory and a temporary cache file is always created
// to test the behavior of prepareModelFromCache, even when caching is not supported.
@@ -242,7 +235,7 @@
mCacheDir = cacheDir;
mCacheDir.push_back('/');
- Return<void> ret = device->getNumberOfCacheFilesNeeded(
+ Return<void> ret = kDevice->getNumberOfCacheFilesNeeded(
[this](ErrorStatus status, uint32_t numModelCache, uint32_t numDataCache) {
EXPECT_EQ(ErrorStatus::NONE, status);
mNumModelCache = numModelCache;
@@ -276,14 +269,14 @@
void TearDown() override {
// If the test passes, remove the tmp directory. Otherwise, keep it for debugging purposes.
- if (!::testing::Test::HasFailure()) {
+ if (!testing::Test::HasFailure()) {
// Recursively remove the cache directory specified by mCacheDir.
auto callback = [](const char* entry, const struct stat*, int, struct FTW*) {
return remove(entry);
};
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
@@ -307,9 +300,9 @@
}
// See if the service can handle the model.
- bool isModelFullySupported(const V1_2::Model& model) {
+ bool isModelFullySupported(const Model& model) {
bool fullySupportsModel = false;
- Return<void> supportedCall = device->getSupportedOperations_1_2(
+ Return<void> supportedCall = kDevice->getSupportedOperations_1_2(
model,
[&fullySupportsModel, &model](ErrorStatus status, const hidl_vec<bool>& supported) {
ASSERT_EQ(ErrorStatus::NONE, status);
@@ -321,18 +314,17 @@
return fullySupportsModel;
}
- void saveModelToCache(const V1_2::Model& model, const hidl_vec<hidl_handle>& modelCache,
+ void saveModelToCache(const Model& model, const hidl_vec<hidl_handle>& modelCache,
const hidl_vec<hidl_handle>& dataCache,
sp<IPreparedModel>* preparedModel = nullptr) {
if (preparedModel != nullptr) *preparedModel = nullptr;
// Launch prepare model.
sp<PreparedModelCallback> preparedModelCallback = new PreparedModelCallback();
- ASSERT_NE(nullptr, preparedModelCallback.get());
hidl_array<uint8_t, sizeof(mToken)> cacheToken(mToken);
Return<ErrorStatus> prepareLaunchStatus =
- device->prepareModel_1_2(model, ExecutionPreference::FAST_SINGLE_ANSWER, modelCache,
- dataCache, cacheToken, preparedModelCallback);
+ kDevice->prepareModel_1_2(model, ExecutionPreference::FAST_SINGLE_ANSWER,
+ modelCache, dataCache, cacheToken, preparedModelCallback);
ASSERT_TRUE(prepareLaunchStatus.isOk());
ASSERT_EQ(static_cast<ErrorStatus>(prepareLaunchStatus), ErrorStatus::NONE);
@@ -340,9 +332,8 @@
preparedModelCallback->wait();
ASSERT_EQ(preparedModelCallback->getStatus(), ErrorStatus::NONE);
if (preparedModel != nullptr) {
- *preparedModel =
- V1_2::IPreparedModel::castFrom(preparedModelCallback->getPreparedModel())
- .withDefault(nullptr);
+ *preparedModel = IPreparedModel::castFrom(preparedModelCallback->getPreparedModel())
+ .withDefault(nullptr);
}
}
@@ -358,7 +349,7 @@
return false;
}
- bool checkEarlyTermination(const V1_2::Model& model) {
+ bool checkEarlyTermination(const Model& model) {
if (!isModelFullySupported(model)) {
LOG(INFO) << "NN VTS: Early termination of test because vendor service cannot "
"prepare model that it does not support.";
@@ -375,9 +366,8 @@
sp<IPreparedModel>* preparedModel, ErrorStatus* status) {
// Launch prepare model from cache.
sp<PreparedModelCallback> preparedModelCallback = new PreparedModelCallback();
- ASSERT_NE(nullptr, preparedModelCallback.get());
hidl_array<uint8_t, sizeof(mToken)> cacheToken(mToken);
- Return<ErrorStatus> prepareLaunchStatus = device->prepareModelFromCache(
+ Return<ErrorStatus> prepareLaunchStatus = kDevice->prepareModelFromCache(
modelCache, dataCache, cacheToken, preparedModelCallback);
ASSERT_TRUE(prepareLaunchStatus.isOk());
if (static_cast<ErrorStatus>(prepareLaunchStatus) != ErrorStatus::NONE) {
@@ -389,7 +379,7 @@
// Retrieve prepared model.
preparedModelCallback->wait();
*status = preparedModelCallback->getStatus();
- *preparedModel = V1_2::IPreparedModel::castFrom(preparedModelCallback->getPreparedModel())
+ *preparedModel = IPreparedModel::castFrom(preparedModelCallback->getPreparedModel())
.withDefault(nullptr);
}
@@ -410,22 +400,27 @@
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) {
// Create test HIDL model and compile.
const TestModel& testModel = createTestModel();
- const Model model = generated_tests::createModel(testModel);
+ const Model model = createModel(testModel);
if (checkEarlyTermination(model)) return;
sp<IPreparedModel> preparedModel = nullptr;
@@ -459,14 +454,14 @@
}
// Execute and verify results.
- generated_tests::EvaluatePreparedModel(preparedModel, testModel,
- /*testDynamicOutputShape=*/false);
+ EvaluatePreparedModel(preparedModel, testModel,
+ /*testDynamicOutputShape=*/false);
}
TEST_P(CompilationCachingTest, CacheSavingAndRetrievalNonZeroOffset) {
// Create test HIDL model and compile.
const TestModel& testModel = createTestModel();
- const Model model = generated_tests::createModel(testModel);
+ const Model model = createModel(testModel);
if (checkEarlyTermination(model)) return;
sp<IPreparedModel> preparedModel = nullptr;
@@ -522,14 +517,14 @@
}
// Execute and verify results.
- generated_tests::EvaluatePreparedModel(preparedModel, testModel,
- /*testDynamicOutputShape=*/false);
+ EvaluatePreparedModel(preparedModel, testModel,
+ /*testDynamicOutputShape=*/false);
}
TEST_P(CompilationCachingTest, SaveToCacheInvalidNumCache) {
// Create test HIDL model and compile.
const TestModel& testModel = createTestModel();
- const Model model = generated_tests::createModel(testModel);
+ const Model model = createModel(testModel);
if (checkEarlyTermination(model)) return;
// Test with number of model cache files greater than mNumModelCache.
@@ -544,8 +539,8 @@
saveModelToCache(model, modelCache, dataCache, &preparedModel);
ASSERT_NE(preparedModel, nullptr);
// Execute and verify results.
- generated_tests::EvaluatePreparedModel(preparedModel, testModel,
- /*testDynamicOutputShape=*/false);
+ EvaluatePreparedModel(preparedModel, testModel,
+ /*testDynamicOutputShape=*/false);
// Check if prepareModelFromCache fails.
preparedModel = nullptr;
ErrorStatus status;
@@ -569,8 +564,8 @@
saveModelToCache(model, modelCache, dataCache, &preparedModel);
ASSERT_NE(preparedModel, nullptr);
// Execute and verify results.
- generated_tests::EvaluatePreparedModel(preparedModel, testModel,
- /*testDynamicOutputShape=*/false);
+ EvaluatePreparedModel(preparedModel, testModel,
+ /*testDynamicOutputShape=*/false);
// Check if prepareModelFromCache fails.
preparedModel = nullptr;
ErrorStatus status;
@@ -593,8 +588,8 @@
saveModelToCache(model, modelCache, dataCache, &preparedModel);
ASSERT_NE(preparedModel, nullptr);
// Execute and verify results.
- generated_tests::EvaluatePreparedModel(preparedModel, testModel,
- /*testDynamicOutputShape=*/false);
+ EvaluatePreparedModel(preparedModel, testModel,
+ /*testDynamicOutputShape=*/false);
// Check if prepareModelFromCache fails.
preparedModel = nullptr;
ErrorStatus status;
@@ -618,8 +613,8 @@
saveModelToCache(model, modelCache, dataCache, &preparedModel);
ASSERT_NE(preparedModel, nullptr);
// Execute and verify results.
- generated_tests::EvaluatePreparedModel(preparedModel, testModel,
- /*testDynamicOutputShape=*/false);
+ EvaluatePreparedModel(preparedModel, testModel,
+ /*testDynamicOutputShape=*/false);
// Check if prepareModelFromCache fails.
preparedModel = nullptr;
ErrorStatus status;
@@ -634,7 +629,7 @@
TEST_P(CompilationCachingTest, PrepareModelFromCacheInvalidNumCache) {
// Create test HIDL model and compile.
const TestModel& testModel = createTestModel();
- const Model model = generated_tests::createModel(testModel);
+ const Model model = createModel(testModel);
if (checkEarlyTermination(model)) return;
// Save the compilation to cache.
@@ -715,7 +710,7 @@
TEST_P(CompilationCachingTest, SaveToCacheInvalidNumFd) {
// Create test HIDL model and compile.
const TestModel& testModel = createTestModel();
- const Model model = generated_tests::createModel(testModel);
+ const Model model = createModel(testModel);
if (checkEarlyTermination(model)) return;
// Go through each handle in model cache, test with NumFd greater than 1.
@@ -730,8 +725,8 @@
saveModelToCache(model, modelCache, dataCache, &preparedModel);
ASSERT_NE(preparedModel, nullptr);
// Execute and verify results.
- generated_tests::EvaluatePreparedModel(preparedModel, testModel,
- /*testDynamicOutputShape=*/false);
+ EvaluatePreparedModel(preparedModel, testModel,
+ /*testDynamicOutputShape=*/false);
// Check if prepareModelFromCache fails.
preparedModel = nullptr;
ErrorStatus status;
@@ -755,8 +750,8 @@
saveModelToCache(model, modelCache, dataCache, &preparedModel);
ASSERT_NE(preparedModel, nullptr);
// Execute and verify results.
- generated_tests::EvaluatePreparedModel(preparedModel, testModel,
- /*testDynamicOutputShape=*/false);
+ EvaluatePreparedModel(preparedModel, testModel,
+ /*testDynamicOutputShape=*/false);
// Check if prepareModelFromCache fails.
preparedModel = nullptr;
ErrorStatus status;
@@ -779,8 +774,8 @@
saveModelToCache(model, modelCache, dataCache, &preparedModel);
ASSERT_NE(preparedModel, nullptr);
// Execute and verify results.
- generated_tests::EvaluatePreparedModel(preparedModel, testModel,
- /*testDynamicOutputShape=*/false);
+ EvaluatePreparedModel(preparedModel, testModel,
+ /*testDynamicOutputShape=*/false);
// Check if prepareModelFromCache fails.
preparedModel = nullptr;
ErrorStatus status;
@@ -804,8 +799,8 @@
saveModelToCache(model, modelCache, dataCache, &preparedModel);
ASSERT_NE(preparedModel, nullptr);
// Execute and verify results.
- generated_tests::EvaluatePreparedModel(preparedModel, testModel,
- /*testDynamicOutputShape=*/false);
+ EvaluatePreparedModel(preparedModel, testModel,
+ /*testDynamicOutputShape=*/false);
// Check if prepareModelFromCache fails.
preparedModel = nullptr;
ErrorStatus status;
@@ -820,7 +815,7 @@
TEST_P(CompilationCachingTest, PrepareModelFromCacheInvalidNumFd) {
// Create test HIDL model and compile.
const TestModel& testModel = createTestModel();
- const Model model = generated_tests::createModel(testModel);
+ const Model model = createModel(testModel);
if (checkEarlyTermination(model)) return;
// Save the compilation to cache.
@@ -901,7 +896,7 @@
TEST_P(CompilationCachingTest, SaveToCacheInvalidAccessMode) {
// Create test HIDL model and compile.
const TestModel& testModel = createTestModel();
- const Model model = generated_tests::createModel(testModel);
+ const Model model = createModel(testModel);
if (checkEarlyTermination(model)) return;
std::vector<AccessMode> modelCacheMode(mNumModelCache, AccessMode::READ_WRITE);
std::vector<AccessMode> dataCacheMode(mNumDataCache, AccessMode::READ_WRITE);
@@ -917,8 +912,8 @@
saveModelToCache(model, modelCache, dataCache, &preparedModel);
ASSERT_NE(preparedModel, nullptr);
// Execute and verify results.
- generated_tests::EvaluatePreparedModel(preparedModel, testModel,
- /*testDynamicOutputShape=*/false);
+ EvaluatePreparedModel(preparedModel, testModel,
+ /*testDynamicOutputShape=*/false);
// Check if prepareModelFromCache fails.
preparedModel = nullptr;
ErrorStatus status;
@@ -940,8 +935,8 @@
saveModelToCache(model, modelCache, dataCache, &preparedModel);
ASSERT_NE(preparedModel, nullptr);
// Execute and verify results.
- generated_tests::EvaluatePreparedModel(preparedModel, testModel,
- /*testDynamicOutputShape=*/false);
+ EvaluatePreparedModel(preparedModel, testModel,
+ /*testDynamicOutputShape=*/false);
// Check if prepareModelFromCache fails.
preparedModel = nullptr;
ErrorStatus status;
@@ -956,7 +951,7 @@
TEST_P(CompilationCachingTest, PrepareModelFromCacheInvalidAccessMode) {
// Create test HIDL model and compile.
const TestModel& testModel = createTestModel();
- const Model model = generated_tests::createModel(testModel);
+ const Model model = createModel(testModel);
if (checkEarlyTermination(model)) return;
std::vector<AccessMode> modelCacheMode(mNumModelCache, AccessMode::READ_WRITE);
std::vector<AccessMode> dataCacheMode(mNumDataCache, AccessMode::READ_WRITE);
@@ -1035,10 +1030,10 @@
// Create test models and check if fully supported by the service.
const TestModel testModelMul = createLargeTestModel(OperationType::MUL, kLargeModelSize);
- const Model modelMul = generated_tests::createModel(testModelMul);
+ const Model modelMul = createModel(testModelMul);
if (checkEarlyTermination(modelMul)) return;
const TestModel testModelAdd = createLargeTestModel(OperationType::ADD, kLargeModelSize);
- const Model modelAdd = generated_tests::createModel(testModelAdd);
+ const Model modelAdd = createModel(testModelAdd);
if (checkEarlyTermination(modelAdd)) return;
// Save the modelMul compilation to cache.
@@ -1085,8 +1080,8 @@
ASSERT_EQ(preparedModel, nullptr);
} else {
ASSERT_NE(preparedModel, nullptr);
- generated_tests::EvaluatePreparedModel(preparedModel, testModelAdd,
- /*testDynamicOutputShape=*/false);
+ EvaluatePreparedModel(preparedModel, testModelAdd,
+ /*testDynamicOutputShape=*/false);
}
}
}
@@ -1097,10 +1092,10 @@
// Create test models and check if fully supported by the service.
const TestModel testModelMul = createLargeTestModel(OperationType::MUL, kLargeModelSize);
- const Model modelMul = generated_tests::createModel(testModelMul);
+ const Model modelMul = createModel(testModelMul);
if (checkEarlyTermination(modelMul)) return;
const TestModel testModelAdd = createLargeTestModel(OperationType::ADD, kLargeModelSize);
- const Model modelAdd = generated_tests::createModel(testModelAdd);
+ const Model modelAdd = createModel(testModelAdd);
if (checkEarlyTermination(modelAdd)) return;
// Save the modelMul compilation to cache.
@@ -1147,8 +1142,8 @@
ASSERT_EQ(preparedModel, nullptr);
} else {
ASSERT_NE(preparedModel, nullptr);
- generated_tests::EvaluatePreparedModel(preparedModel, testModelAdd,
- /*testDynamicOutputShape=*/false);
+ EvaluatePreparedModel(preparedModel, testModelAdd,
+ /*testDynamicOutputShape=*/false);
}
}
}
@@ -1159,10 +1154,10 @@
// Create test models and check if fully supported by the service.
const TestModel testModelMul = createLargeTestModel(OperationType::MUL, kLargeModelSize);
- const Model modelMul = generated_tests::createModel(testModelMul);
+ const Model modelMul = createModel(testModelMul);
if (checkEarlyTermination(modelMul)) return;
const TestModel testModelAdd = createLargeTestModel(OperationType::ADD, kLargeModelSize);
- const Model modelAdd = generated_tests::createModel(testModelAdd);
+ const Model modelAdd = createModel(testModelAdd);
if (checkEarlyTermination(modelAdd)) return;
// Save the modelMul compilation to cache.
@@ -1204,16 +1199,30 @@
}
}
+static const auto kNamedDeviceChoices = testing::ValuesIn(getNamedDevices());
static const auto kOperandTypeChoices =
- ::testing::Values(OperandType::TENSOR_FLOAT32, OperandType::TENSOR_QUANT8_ASYMM);
+ 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();
@@ -1265,7 +1274,7 @@
// whether the test should be skipped or not.
void testCorruptedCache(ExpectedResult expected, std::function<void(bool*)> modifier) {
const TestModel& testModel = createTestModel();
- const Model model = generated_tests::createModel(testModel);
+ const Model model = createModel(testModel);
if (checkEarlyTermination(model)) return;
// Save the compilation to cache.
@@ -1303,7 +1312,7 @@
}
}
- const uint32_t kSeed = std::get<1>(GetParam());
+ const uint32_t kSeed = std::get<uint32_t>(GetParam());
std::mt19937 generator;
};
@@ -1350,12 +1359,16 @@
});
}
-INSTANTIATE_TEST_CASE_P(TestCompilationCaching, CompilationCachingSecurityTest,
- ::testing::Combine(kOperandTypeChoices, ::testing::Range(0U, 10U)));
+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));
+}
-} // namespace functional
-} // namespace vts
-} // namespace V1_2
-} // namespace neuralnetworks
-} // namespace hardware
-} // namespace android
+INSTANTIATE_TEST_CASE_P(TestCompilationCaching, CompilationCachingSecurityTest,
+ 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 1dcebbe..2beec98 100644
--- a/neuralnetworks/1.2/vts/functional/GeneratedTestHarness.cpp
+++ b/neuralnetworks/1.2/vts/functional/GeneratedTestHarness.cpp
@@ -42,30 +42,19 @@
#include "MemoryUtils.h"
#include "TestHarness.h"
#include "Utils.h"
+#include "VtsHalNeuralnetworks.h"
-namespace android {
-namespace hardware {
-namespace neuralnetworks {
-namespace V1_2 {
-namespace generated_tests {
+namespace android::hardware::neuralnetworks::V1_2::vts::functional {
using namespace test_helper;
-using ::android::hardware::neuralnetworks::V1_0::DataLocation;
-using ::android::hardware::neuralnetworks::V1_0::ErrorStatus;
-using ::android::hardware::neuralnetworks::V1_0::OperandLifeTime;
-using ::android::hardware::neuralnetworks::V1_0::Request;
-using ::android::hardware::neuralnetworks::V1_0::RequestArgument;
-using ::android::hardware::neuralnetworks::V1_1::ExecutionPreference;
-using ::android::hardware::neuralnetworks::V1_2::Constant;
-using ::android::hardware::neuralnetworks::V1_2::IDevice;
-using ::android::hardware::neuralnetworks::V1_2::IPreparedModel;
-using ::android::hardware::neuralnetworks::V1_2::MeasureTiming;
-using ::android::hardware::neuralnetworks::V1_2::Model;
-using ::android::hardware::neuralnetworks::V1_2::OutputShape;
-using ::android::hardware::neuralnetworks::V1_2::Timing;
-using ::android::hardware::neuralnetworks::V1_2::implementation::ExecutionCallback;
-using ::android::hardware::neuralnetworks::V1_2::implementation::PreparedModelCallback;
-using ::android::hidl::memory::V1_0::IMemory;
+using hidl::memory::V1_0::IMemory;
+using implementation::ExecutionCallback;
+using implementation::PreparedModelCallback;
+using V1_0::DataLocation;
+using V1_0::ErrorStatus;
+using V1_0::OperandLifeTime;
+using V1_0::Request;
+using V1_1::ExecutionPreference;
using HidlToken = hidl_array<uint8_t, static_cast<uint32_t>(Constant::BYTE_SIZE_OF_CACHE_TOKEN)>;
enum class OutputType { FULLY_SPECIFIED, UNSPECIFIED, INSUFFICIENT };
@@ -201,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 };
@@ -369,63 +358,51 @@
}
}
-void PrepareModel(const sp<IDevice>& device, const Model& model,
- sp<IPreparedModel>* preparedModel) {
- // see if service can handle model
- bool fullySupportsModel = false;
- Return<void> supportedCall = device->getSupportedOperations_1_2(
- model, [&fullySupportsModel](ErrorStatus status, const hidl_vec<bool>& supported) {
- ASSERT_EQ(ErrorStatus::NONE, status);
- ASSERT_NE(0ul, supported.size());
- fullySupportsModel = std::all_of(supported.begin(), supported.end(),
- [](bool valid) { return valid; });
- });
- ASSERT_TRUE(supportedCall.isOk());
-
- // launch prepare model
- sp<PreparedModelCallback> preparedModelCallback = new PreparedModelCallback();
- Return<ErrorStatus> prepareLaunchStatus = device->prepareModel_1_2(
- model, ExecutionPreference::FAST_SINGLE_ANSWER, hidl_vec<hidl_handle>(),
- hidl_vec<hidl_handle>(), HidlToken(), preparedModelCallback);
- ASSERT_TRUE(prepareLaunchStatus.isOk());
- ASSERT_EQ(ErrorStatus::NONE, static_cast<ErrorStatus>(prepareLaunchStatus));
-
- // retrieve prepared model
- preparedModelCallback->wait();
- ErrorStatus prepareReturnStatus = preparedModelCallback->getStatus();
- sp<V1_0::IPreparedModel> preparedModelV1_0 = preparedModelCallback->getPreparedModel();
- *preparedModel = IPreparedModel::castFrom(preparedModelV1_0).withDefault(nullptr);
-
- // early termination if vendor service cannot fully prepare model
- if (!fullySupportsModel && prepareReturnStatus != ErrorStatus::NONE) {
- ASSERT_EQ(nullptr, preparedModel->get());
- LOG(INFO) << "NN VTS: Early termination of test because vendor service cannot "
- "prepare model that it does not support.";
- std::cout << "[ ] Early termination of test because vendor service cannot "
- "prepare model that it does not support."
- << std::endl;
- return;
- }
- EXPECT_EQ(ErrorStatus::NONE, prepareReturnStatus);
- ASSERT_NE(nullptr, preparedModel->get());
-}
-
void Execute(const sp<IDevice>& device, const TestModel& testModel, bool testDynamicOutputShape) {
Model model = createModel(testModel);
if (testDynamicOutputShape) {
makeOutputDimensionsUnspecified(&model);
}
- sp<IPreparedModel> preparedModel = nullptr;
- PrepareModel(device, model, &preparedModel);
- if (preparedModel == nullptr) {
- GTEST_SKIP();
- }
+ sp<IPreparedModel> preparedModel;
+ createPreparedModel(device, model, &preparedModel);
+ if (preparedModel == nullptr) return;
+
EvaluatePreparedModel(preparedModel, testModel, testDynamicOutputShape);
}
-} // namespace generated_tests
-} // namespace V1_2
-} // namespace neuralnetworks
-} // namespace hardware
-} // namespace android
+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 {};
+
+// Tag for the dynamic output shape tests
+class DynamicOutputShapeTest : public GeneratedTest {};
+
+TEST_P(GeneratedTest, Test) {
+ Execute(kDevice, kTestModel, /*testDynamicOutputShape=*/false);
+}
+
+TEST_P(DynamicOutputShapeTest, Test) {
+ Execute(kDevice, kTestModel, /*testDynamicOutputShape=*/true);
+}
+
+INSTANTIATE_GENERATED_TEST(GeneratedTest,
+ [](const TestModel& testModel) { return !testModel.expectFailure; });
+
+INSTANTIATE_GENERATED_TEST(DynamicOutputShapeTest,
+ [](const TestModel& testModel) { return !testModel.expectFailure; });
+
+} // namespace android::hardware::neuralnetworks::V1_2::vts::functional
diff --git a/neuralnetworks/1.2/vts/functional/GeneratedTestHarness.h b/neuralnetworks/1.2/vts/functional/GeneratedTestHarness.h
index de45242..dfc980c 100644
--- a/neuralnetworks/1.2/vts/functional/GeneratedTestHarness.h
+++ b/neuralnetworks/1.2/vts/functional/GeneratedTestHarness.h
@@ -22,29 +22,44 @@
#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 {
-namespace hardware {
-namespace neuralnetworks {
-namespace V1_2 {
-namespace generated_tests {
+namespace android::hardware::neuralnetworks::V1_2::vts::functional {
-Model createModel(const ::test_helper::TestModel& testModel);
+using NamedModel = Named<const test_helper::TestModel*>;
+using GeneratedTestParam = std::tuple<NamedDevice, NamedModel>;
-void PrepareModel(const sp<V1_2::IDevice>& device, const V1_2::Model& model,
- sp<V1_2::IPreparedModel>* preparedModel);
+class GeneratedTestBase : public testing::TestWithParam<GeneratedTestParam> {
+ protected:
+ void SetUp() override;
+ const sp<IDevice> kDevice = getData(std::get<NamedDevice>(GetParam()));
+ const test_helper::TestModel& kTestModel = *getData(std::get<NamedModel>(GetParam()));
+};
-void EvaluatePreparedModel(const sp<V1_2::IPreparedModel>& preparedModel,
- const ::test_helper::TestModel& testModel, bool testDynamicOutputShape);
+using FilterFn = std::function<bool(const test_helper::TestModel&)>;
+std::vector<NamedModel> getNamedModels(const FilterFn& filter);
-void Execute(const sp<V1_2::IDevice>& device, const ::test_helper::TestModel& testModel,
- bool testDynamicOutputShape = false);
+std::string printGeneratedTest(const testing::TestParamInfo<GeneratedTestParam>& info);
-} // namespace generated_tests
-} // namespace V1_2
-} // namespace neuralnetworks
-} // namespace hardware
-} // namespace android
+#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);
+
+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);
+
+} // namespace android::hardware::neuralnetworks::V1_2::vts::functional
#endif // ANDROID_HARDWARE_NEURALNETWORKS_V1_2_GENERATED_TEST_HARNESS_H
diff --git a/neuralnetworks/1.2/vts/functional/GeneratedTests.h b/neuralnetworks/1.2/vts/functional/GeneratedTests.h
deleted file mode 100644
index a723609..0000000
--- a/neuralnetworks/1.2/vts/functional/GeneratedTests.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "1.0/Utils.h"
-#include "GeneratedTestHarness.h"
-#include "TestHarness.h"
-#include "VtsHalNeuralnetworks.h"
-
-namespace android::hardware::neuralnetworks::V1_2::generated_tests {
-
-using namespace ::android::hardware::neuralnetworks::V1_2::vts::functional;
-
-using ::android::hardware::neuralnetworks::V1_0::OperandLifeTime;
-using ::android::hardware::neuralnetworks::V1_0::Request;
-
-} // namespace android::hardware::neuralnetworks::V1_2::generated_tests
diff --git a/neuralnetworks/1.2/vts/functional/TestAssertions.cpp b/neuralnetworks/1.2/vts/functional/TestAssertions.cpp
new file mode 100644
index 0000000..a0aa3c3
--- /dev/null
+++ b/neuralnetworks/1.2/vts/functional/TestAssertions.cpp
@@ -0,0 +1,141 @@
+/*
+ * 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.
+ */
+
+#include <android/hardware/neuralnetworks/1.2/types.h>
+#include "TestHarness.h"
+
+namespace android::hardware::neuralnetworks::V1_2 {
+
+// Make sure that the HIDL enums are compatible with the values defined in
+// frameworks/ml/nn/tools/test_generator/test_harness/include/TestHarness.h.
+using namespace test_helper;
+#define CHECK_TEST_ENUM(EnumType, enumValue) \
+ static_assert(static_cast<EnumType>(Test##EnumType::enumValue) == EnumType::enumValue)
+
+CHECK_TEST_ENUM(OperandType, FLOAT32);
+CHECK_TEST_ENUM(OperandType, INT32);
+CHECK_TEST_ENUM(OperandType, UINT32);
+CHECK_TEST_ENUM(OperandType, TENSOR_FLOAT32);
+CHECK_TEST_ENUM(OperandType, TENSOR_INT32);
+CHECK_TEST_ENUM(OperandType, TENSOR_QUANT8_ASYMM);
+CHECK_TEST_ENUM(OperandType, BOOL);
+CHECK_TEST_ENUM(OperandType, TENSOR_QUANT16_SYMM);
+CHECK_TEST_ENUM(OperandType, TENSOR_FLOAT16);
+CHECK_TEST_ENUM(OperandType, TENSOR_BOOL8);
+CHECK_TEST_ENUM(OperandType, FLOAT16);
+CHECK_TEST_ENUM(OperandType, TENSOR_QUANT8_SYMM_PER_CHANNEL);
+CHECK_TEST_ENUM(OperandType, TENSOR_QUANT16_ASYMM);
+CHECK_TEST_ENUM(OperandType, TENSOR_QUANT8_SYMM);
+
+CHECK_TEST_ENUM(OperationType, ADD);
+CHECK_TEST_ENUM(OperationType, AVERAGE_POOL_2D);
+CHECK_TEST_ENUM(OperationType, CONCATENATION);
+CHECK_TEST_ENUM(OperationType, CONV_2D);
+CHECK_TEST_ENUM(OperationType, DEPTHWISE_CONV_2D);
+CHECK_TEST_ENUM(OperationType, DEPTH_TO_SPACE);
+CHECK_TEST_ENUM(OperationType, DEQUANTIZE);
+CHECK_TEST_ENUM(OperationType, EMBEDDING_LOOKUP);
+CHECK_TEST_ENUM(OperationType, FLOOR);
+CHECK_TEST_ENUM(OperationType, FULLY_CONNECTED);
+CHECK_TEST_ENUM(OperationType, HASHTABLE_LOOKUP);
+CHECK_TEST_ENUM(OperationType, L2_NORMALIZATION);
+CHECK_TEST_ENUM(OperationType, L2_POOL_2D);
+CHECK_TEST_ENUM(OperationType, LOCAL_RESPONSE_NORMALIZATION);
+CHECK_TEST_ENUM(OperationType, LOGISTIC);
+CHECK_TEST_ENUM(OperationType, LSH_PROJECTION);
+CHECK_TEST_ENUM(OperationType, LSTM);
+CHECK_TEST_ENUM(OperationType, MAX_POOL_2D);
+CHECK_TEST_ENUM(OperationType, MUL);
+CHECK_TEST_ENUM(OperationType, RELU);
+CHECK_TEST_ENUM(OperationType, RELU1);
+CHECK_TEST_ENUM(OperationType, RELU6);
+CHECK_TEST_ENUM(OperationType, RESHAPE);
+CHECK_TEST_ENUM(OperationType, RESIZE_BILINEAR);
+CHECK_TEST_ENUM(OperationType, RNN);
+CHECK_TEST_ENUM(OperationType, SOFTMAX);
+CHECK_TEST_ENUM(OperationType, SPACE_TO_DEPTH);
+CHECK_TEST_ENUM(OperationType, SVDF);
+CHECK_TEST_ENUM(OperationType, TANH);
+CHECK_TEST_ENUM(OperationType, BATCH_TO_SPACE_ND);
+CHECK_TEST_ENUM(OperationType, DIV);
+CHECK_TEST_ENUM(OperationType, MEAN);
+CHECK_TEST_ENUM(OperationType, PAD);
+CHECK_TEST_ENUM(OperationType, SPACE_TO_BATCH_ND);
+CHECK_TEST_ENUM(OperationType, SQUEEZE);
+CHECK_TEST_ENUM(OperationType, STRIDED_SLICE);
+CHECK_TEST_ENUM(OperationType, SUB);
+CHECK_TEST_ENUM(OperationType, TRANSPOSE);
+CHECK_TEST_ENUM(OperationType, ABS);
+CHECK_TEST_ENUM(OperationType, ARGMAX);
+CHECK_TEST_ENUM(OperationType, ARGMIN);
+CHECK_TEST_ENUM(OperationType, AXIS_ALIGNED_BBOX_TRANSFORM);
+CHECK_TEST_ENUM(OperationType, BIDIRECTIONAL_SEQUENCE_LSTM);
+CHECK_TEST_ENUM(OperationType, BIDIRECTIONAL_SEQUENCE_RNN);
+CHECK_TEST_ENUM(OperationType, BOX_WITH_NMS_LIMIT);
+CHECK_TEST_ENUM(OperationType, CAST);
+CHECK_TEST_ENUM(OperationType, CHANNEL_SHUFFLE);
+CHECK_TEST_ENUM(OperationType, DETECTION_POSTPROCESSING);
+CHECK_TEST_ENUM(OperationType, EQUAL);
+CHECK_TEST_ENUM(OperationType, EXP);
+CHECK_TEST_ENUM(OperationType, EXPAND_DIMS);
+CHECK_TEST_ENUM(OperationType, GATHER);
+CHECK_TEST_ENUM(OperationType, GENERATE_PROPOSALS);
+CHECK_TEST_ENUM(OperationType, GREATER);
+CHECK_TEST_ENUM(OperationType, GREATER_EQUAL);
+CHECK_TEST_ENUM(OperationType, GROUPED_CONV_2D);
+CHECK_TEST_ENUM(OperationType, HEATMAP_MAX_KEYPOINT);
+CHECK_TEST_ENUM(OperationType, INSTANCE_NORMALIZATION);
+CHECK_TEST_ENUM(OperationType, LESS);
+CHECK_TEST_ENUM(OperationType, LESS_EQUAL);
+CHECK_TEST_ENUM(OperationType, LOG);
+CHECK_TEST_ENUM(OperationType, LOGICAL_AND);
+CHECK_TEST_ENUM(OperationType, LOGICAL_NOT);
+CHECK_TEST_ENUM(OperationType, LOGICAL_OR);
+CHECK_TEST_ENUM(OperationType, LOG_SOFTMAX);
+CHECK_TEST_ENUM(OperationType, MAXIMUM);
+CHECK_TEST_ENUM(OperationType, MINIMUM);
+CHECK_TEST_ENUM(OperationType, NEG);
+CHECK_TEST_ENUM(OperationType, NOT_EQUAL);
+CHECK_TEST_ENUM(OperationType, PAD_V2);
+CHECK_TEST_ENUM(OperationType, POW);
+CHECK_TEST_ENUM(OperationType, PRELU);
+CHECK_TEST_ENUM(OperationType, QUANTIZE);
+CHECK_TEST_ENUM(OperationType, QUANTIZED_16BIT_LSTM);
+CHECK_TEST_ENUM(OperationType, RANDOM_MULTINOMIAL);
+CHECK_TEST_ENUM(OperationType, REDUCE_ALL);
+CHECK_TEST_ENUM(OperationType, REDUCE_ANY);
+CHECK_TEST_ENUM(OperationType, REDUCE_MAX);
+CHECK_TEST_ENUM(OperationType, REDUCE_MIN);
+CHECK_TEST_ENUM(OperationType, REDUCE_PROD);
+CHECK_TEST_ENUM(OperationType, REDUCE_SUM);
+CHECK_TEST_ENUM(OperationType, ROI_ALIGN);
+CHECK_TEST_ENUM(OperationType, ROI_POOLING);
+CHECK_TEST_ENUM(OperationType, RSQRT);
+CHECK_TEST_ENUM(OperationType, SELECT);
+CHECK_TEST_ENUM(OperationType, SIN);
+CHECK_TEST_ENUM(OperationType, SLICE);
+CHECK_TEST_ENUM(OperationType, SPLIT);
+CHECK_TEST_ENUM(OperationType, SQRT);
+CHECK_TEST_ENUM(OperationType, TILE);
+CHECK_TEST_ENUM(OperationType, TOPK_V2);
+CHECK_TEST_ENUM(OperationType, TRANSPOSE_CONV_2D);
+CHECK_TEST_ENUM(OperationType, UNIDIRECTIONAL_SEQUENCE_LSTM);
+CHECK_TEST_ENUM(OperationType, UNIDIRECTIONAL_SEQUENCE_RNN);
+CHECK_TEST_ENUM(OperationType, RESIZE_NEAREST_NEIGHBOR);
+
+#undef CHECK_TEST_ENUM
+
+} // namespace android::hardware::neuralnetworks::V1_2
diff --git a/neuralnetworks/1.2/vts/functional/ValidateBurst.cpp b/neuralnetworks/1.2/vts/functional/ValidateBurst.cpp
index 94603fb..1d4493d 100644
--- a/neuralnetworks/1.2/vts/functional/ValidateBurst.cpp
+++ b/neuralnetworks/1.2/vts/functional/ValidateBurst.cpp
@@ -21,23 +21,21 @@
#include "1.2/Callbacks.h"
#include "ExecutionBurstController.h"
#include "ExecutionBurstServer.h"
+#include "GeneratedTestHarness.h"
#include "TestHarness.h"
#include "Utils.h"
#include <android-base/logging.h>
#include <cstring>
-namespace android {
-namespace hardware {
-namespace neuralnetworks {
-namespace V1_2 {
-namespace vts {
-namespace functional {
+namespace android::hardware::neuralnetworks::V1_2::vts::functional {
-using ::android::nn::ExecutionBurstController;
-using ::android::nn::RequestChannelSender;
-using ::android::nn::ResultChannelReceiver;
-using ExecutionBurstCallback = ::android::nn::ExecutionBurstController::ExecutionBurstCallback;
+using nn::ExecutionBurstController;
+using nn::RequestChannelSender;
+using nn::ResultChannelReceiver;
+using V1_0::ErrorStatus;
+using V1_0::Request;
+using ExecutionBurstCallback = ExecutionBurstController::ExecutionBurstCallback;
// This constant value represents the length of an FMQ that is large enough to
// return a result from a burst execution for all of the generated test cases.
@@ -264,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);
@@ -301,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;
@@ -393,16 +391,10 @@
///////////////////////////// ENTRY POINT //////////////////////////////////
-void ValidationTest::validateBurst(const sp<IPreparedModel>& preparedModel,
- const Request& request) {
+void validateBurst(const sp<IPreparedModel>& preparedModel, const Request& request) {
ASSERT_NO_FATAL_FAILURE(validateBurstSerialization(preparedModel, request));
ASSERT_NO_FATAL_FAILURE(validateBurstFmqLength(preparedModel, request));
ASSERT_NO_FATAL_FAILURE(validateBurstSanitized(preparedModel, request));
}
-} // namespace functional
-} // namespace vts
-} // namespace V1_2
-} // namespace neuralnetworks
-} // namespace hardware
-} // namespace android
+} // namespace android::hardware::neuralnetworks::V1_2::vts::functional
diff --git a/neuralnetworks/1.2/vts/functional/ValidateModel.cpp b/neuralnetworks/1.2/vts/functional/ValidateModel.cpp
index 78bb194..30530be 100644
--- a/neuralnetworks/1.2/vts/functional/ValidateModel.cpp
+++ b/neuralnetworks/1.2/vts/functional/ValidateModel.cpp
@@ -18,21 +18,15 @@
#include "1.0/Utils.h"
#include "1.2/Callbacks.h"
+#include "GeneratedTestHarness.h"
#include "VtsHalNeuralnetworks.h"
-namespace android {
-namespace hardware {
-namespace neuralnetworks {
-namespace V1_2 {
+namespace android::hardware::neuralnetworks::V1_2::vts::functional {
+using implementation::PreparedModelCallback;
+using V1_0::ErrorStatus;
using V1_0::OperandLifeTime;
using V1_1::ExecutionPreference;
-
-namespace vts {
-namespace functional {
-
-using ::android::hardware::neuralnetworks::V1_2::implementation::ExecutionCallback;
-using ::android::hardware::neuralnetworks::V1_2::implementation::PreparedModelCallback;
using HidlToken = hidl_array<uint8_t, static_cast<uint32_t>(Constant::BYTE_SIZE_OF_CACHE_TOKEN)>;
///////////////////////// UTILITY FUNCTIONS /////////////////////////
@@ -53,7 +47,6 @@
SCOPED_TRACE(message + " [prepareModel_1_2]");
sp<PreparedModelCallback> preparedModelCallback = new PreparedModelCallback();
- ASSERT_NE(nullptr, preparedModelCallback.get());
Return<ErrorStatus> prepareLaunchStatus =
device->prepareModel_1_2(model, preference, hidl_vec<hidl_handle>(),
hidl_vec<hidl_handle>(), HidlToken(), preparedModelCallback);
@@ -691,14 +684,15 @@
for (int32_t preference : invalidExecutionPreferences) {
const std::string message =
"mutateExecutionPreferenceTest: preference " + std::to_string(preference);
- validate(device, message, model, [](Model*) {},
- static_cast<ExecutionPreference>(preference));
+ validate(
+ device, message, model, [](Model*) {},
+ static_cast<ExecutionPreference>(preference));
}
}
////////////////////////// ENTRY POINT //////////////////////////////
-void ValidationTest::validateModel(const Model& model) {
+void validateModel(const sp<IDevice>& device, const Model& model) {
mutateOperandTypeTest(device, model);
mutateOperandRankTest(device, model);
mutateOperandScaleTest(device, model);
@@ -716,9 +710,4 @@
mutateExecutionPreferenceTest(device, model);
}
-} // namespace functional
-} // namespace vts
-} // namespace V1_2
-} // namespace neuralnetworks
-} // namespace hardware
-} // namespace android
+} // namespace android::hardware::neuralnetworks::V1_2::vts::functional
diff --git a/neuralnetworks/1.2/vts/functional/ValidateRequest.cpp b/neuralnetworks/1.2/vts/functional/ValidateRequest.cpp
index 13d45e4..f25ee62 100644
--- a/neuralnetworks/1.2/vts/functional/ValidateRequest.cpp
+++ b/neuralnetworks/1.2/vts/functional/ValidateRequest.cpp
@@ -19,18 +19,16 @@
#include "1.0/Utils.h"
#include "1.2/Callbacks.h"
#include "ExecutionBurstController.h"
+#include "GeneratedTestHarness.h"
#include "TestHarness.h"
#include "Utils.h"
#include "VtsHalNeuralnetworks.h"
-namespace android {
-namespace hardware {
-namespace neuralnetworks {
-namespace V1_2 {
-namespace vts {
-namespace functional {
+namespace android::hardware::neuralnetworks::V1_2::vts::functional {
-using ::android::hardware::neuralnetworks::V1_2::implementation::ExecutionCallback;
+using implementation::ExecutionCallback;
+using V1_0::ErrorStatus;
+using V1_0::Request;
///////////////////////// UTILITY FUNCTIONS /////////////////////////
@@ -61,7 +59,6 @@
SCOPED_TRACE(message + " [execute_1_2]");
sp<ExecutionCallback> executionCallback = new ExecutionCallback();
- ASSERT_NE(nullptr, executionCallback.get());
Return<ErrorStatus> executeLaunchStatus =
preparedModel->execute_1_2(request, measure, executionCallback);
ASSERT_TRUE(executeLaunchStatus.isOk());
@@ -97,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
@@ -151,14 +148,12 @@
///////////////////////////// ENTRY POINT //////////////////////////////////
-void ValidationTest::validateRequest(const sp<IPreparedModel>& preparedModel,
- const Request& request) {
+void validateRequest(const sp<IPreparedModel>& preparedModel, const Request& request) {
removeInputTest(preparedModel, request);
removeOutputTest(preparedModel, request);
}
-void ValidationTest::validateRequestFailure(const sp<IPreparedModel>& preparedModel,
- const Request& request) {
+void validateRequestFailure(const sp<IPreparedModel>& preparedModel, const Request& request) {
SCOPED_TRACE("Expecting request to fail [executeSynchronously]");
Return<void> executeStatus = preparedModel->executeSynchronously(
request, MeasureTiming::NO,
@@ -170,9 +165,4 @@
ASSERT_TRUE(executeStatus.isOk());
}
-} // namespace functional
-} // namespace vts
-} // namespace V1_2
-} // namespace neuralnetworks
-} // namespace hardware
-} // namespace android
+} // namespace android::hardware::neuralnetworks::V1_2::vts::functional
diff --git a/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.cpp b/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.cpp
index eb52110..4fbd0e2 100644
--- a/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.cpp
+++ b/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.cpp
@@ -17,42 +17,43 @@
#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 "1.2/Callbacks.h"
+namespace android::hardware::neuralnetworks::V1_2::vts::functional {
-namespace android {
-namespace hardware {
-namespace neuralnetworks {
-namespace V1_2 {
-namespace vts {
-namespace functional {
-
-using ::android::hardware::neuralnetworks::V1_2::implementation::PreparedModelCallback;
+using implementation::PreparedModelCallback;
using HidlToken = hidl_array<uint8_t, static_cast<uint32_t>(Constant::BYTE_SIZE_OF_CACHE_TOKEN)>;
+using V1_0::ErrorStatus;
+using V1_0::Request;
using V1_1::ExecutionPreference;
// internal helper function
-static void createPreparedModel(const sp<IDevice>& device, const Model& model,
- sp<IPreparedModel>* preparedModel) {
+void createPreparedModel(const sp<IDevice>& device, const Model& model,
+ sp<IPreparedModel>* preparedModel) {
ASSERT_NE(nullptr, preparedModel);
+ *preparedModel = nullptr;
// see if service can handle model
bool fullySupportsModel = false;
- Return<void> supportedOpsLaunchStatus = device->getSupportedOperations_1_2(
+ const Return<void> supportedCall = device->getSupportedOperations_1_2(
model, [&fullySupportsModel](ErrorStatus status, const hidl_vec<bool>& supported) {
ASSERT_EQ(ErrorStatus::NONE, status);
ASSERT_NE(0ul, supported.size());
fullySupportsModel = std::all_of(supported.begin(), supported.end(),
[](bool valid) { return valid; });
});
- ASSERT_TRUE(supportedOpsLaunchStatus.isOk());
+ ASSERT_TRUE(supportedCall.isOk());
// launch prepare model
- sp<PreparedModelCallback> preparedModelCallback = new PreparedModelCallback();
- ASSERT_NE(nullptr, preparedModelCallback.get());
- Return<ErrorStatus> prepareLaunchStatus = device->prepareModel_1_2(
+ const sp<PreparedModelCallback> preparedModelCallback = new PreparedModelCallback();
+ const Return<ErrorStatus> prepareLaunchStatus = device->prepareModel_1_2(
model, ExecutionPreference::FAST_SINGLE_ANSWER, hidl_vec<hidl_handle>(),
hidl_vec<hidl_handle>(), HidlToken(), preparedModelCallback);
ASSERT_TRUE(prepareLaunchStatus.isOk());
@@ -60,7 +61,7 @@
// retrieve prepared model
preparedModelCallback->wait();
- ErrorStatus prepareReturnStatus = preparedModelCallback->getStatus();
+ const ErrorStatus prepareReturnStatus = preparedModelCallback->getStatus();
*preparedModel = getPreparedModel_1_2(preparedModelCallback);
// The getSupportedOperations_1_2 call returns a list of operations that are
@@ -72,120 +73,99 @@
// can continue.
if (!fullySupportsModel && prepareReturnStatus != ErrorStatus::NONE) {
ASSERT_EQ(nullptr, preparedModel->get());
- LOG(INFO) << "NN VTS: Unable to test Request validation because vendor service cannot "
- "prepare model that it does not support.";
- std::cout << "[ ] Unable to test Request validation because vendor service "
- "cannot prepare model that it does not support."
+ LOG(INFO) << "NN VTS: Early termination of test because vendor service cannot prepare "
+ "model that it does not support.";
+ std::cout << "[ ] Early termination of test because vendor service cannot "
+ "prepare model that it does not support."
<< std::endl;
- return;
+ GTEST_SKIP();
}
ASSERT_EQ(ErrorStatus::NONE, prepareReturnStatus);
ASSERT_NE(nullptr, preparedModel->get());
}
-// A class for test environment setup
-NeuralnetworksHidlEnvironment::NeuralnetworksHidlEnvironment() {}
-
-NeuralnetworksHidlEnvironment::~NeuralnetworksHidlEnvironment() {}
-
-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.
-NeuralnetworksHidlTest::NeuralnetworksHidlTest() {}
-
-NeuralnetworksHidlTest::~NeuralnetworksHidlTest() {}
-
void NeuralnetworksHidlTest::SetUp() {
- ::testing::VtsHalHidlTargetTestBase::SetUp();
- device = ::testing::VtsHalHidlTargetTestBase::getService<IDevice>(
- NeuralnetworksHidlEnvironment::getInstance());
-
-#ifdef PRESUBMIT_NOT_VTS
- const std::string name =
- NeuralnetworksHidlEnvironment::getInstance()->getServiceName<IDevice>();
- const std::string sampleDriver = "sample-";
- if (device == nullptr && name.substr(0, sampleDriver.size()) == sampleDriver) {
- GTEST_SKIP();
- }
-#endif // PRESUBMIT_NOT_VTS
-
- ASSERT_NE(nullptr, device.get());
+ testing::TestWithParam<NeuralnetworksHidlTestParam>::SetUp();
+ ASSERT_NE(kDevice, nullptr);
}
-void NeuralnetworksHidlTest::TearDown() {
- device = nullptr;
- ::testing::VtsHalHidlTargetTestBase::TearDown();
+static NamedDevice makeNamedDevice(const std::string& name) {
+ return {name, IDevice::getService(name)};
}
-void ValidationTest::validateEverything(const Model& model, const Request& request) {
- validateModel(model);
+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);
- // create IPreparedModel
+ // 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
+void validateRequest(const sp<IPreparedModel>& preparedModel, const V1_0::Request& request);
+// Forward declaration from ValidateRequest.cpp
+void validateRequestFailure(const sp<IPreparedModel>& preparedModel, const V1_0::Request& request);
+// Forward declaration from ValidateBurst.cpp
+void validateBurst(const sp<IPreparedModel>& preparedModel, const V1_0::Request& request);
+
+void validateEverything(const sp<IDevice>& device, const Model& model, const Request& request) {
+ validateModel(device, model);
+
+ // Create IPreparedModel.
sp<IPreparedModel> preparedModel;
- ASSERT_NO_FATAL_FAILURE(createPreparedModel(device, model, &preparedModel));
- if (preparedModel == nullptr) {
- return;
- }
+ createPreparedModel(device, model, &preparedModel);
+ if (preparedModel == nullptr) return;
validateRequest(preparedModel, request);
validateBurst(preparedModel, request);
}
-void ValidationTest::validateFailure(const Model& model, const Request& request) {
+void validateFailure(const sp<IDevice>& device, const Model& model, const Request& request) {
// TODO: Should this always succeed?
// What if the invalid input is part of the model (i.e., a parameter).
- validateModel(model);
+ validateModel(device, model);
+ // Create IPreparedModel.
sp<IPreparedModel> preparedModel;
- ASSERT_NO_FATAL_FAILURE(createPreparedModel(device, model, &preparedModel));
- if (preparedModel == nullptr) {
- return;
- }
+ createPreparedModel(device, model, &preparedModel);
+ if (preparedModel == nullptr) return;
validateRequestFailure(preparedModel, request);
}
-sp<IPreparedModel> getPreparedModel_1_2(
- const sp<V1_2::implementation::PreparedModelCallback>& callback) {
+TEST_P(ValidationTest, Test) {
+ const Model model = createModel(kTestModel);
+ const Request request = createRequest(kTestModel);
+ if (kTestModel.expectFailure) {
+ validateFailure(kDevice, model, request);
+ } else {
+ validateEverything(kDevice, model, request);
+ }
+}
+
+INSTANTIATE_GENERATED_TEST(ValidationTest, [](const test_helper::TestModel&) { return true; });
+
+sp<IPreparedModel> getPreparedModel_1_2(const sp<implementation::PreparedModelCallback>& callback) {
sp<V1_0::IPreparedModel> preparedModelV1_0 = callback->getPreparedModel();
- return V1_2::IPreparedModel::castFrom(preparedModelV1_0).withDefault(nullptr);
+ return IPreparedModel::castFrom(preparedModelV1_0).withDefault(nullptr);
}
-} // namespace functional
-} // namespace vts
-} // namespace V1_2
-} // namespace neuralnetworks
-} // namespace hardware
-} // namespace android
-
-namespace android::hardware::neuralnetworks::V1_0 {
-
-::std::ostream& operator<<(::std::ostream& os, ErrorStatus errorStatus) {
- return os << toString(errorStatus);
-}
-
-::std::ostream& operator<<(::std::ostream& os, DeviceStatus deviceStatus) {
- return os << toString(deviceStatus);
-}
-
-} // namespace android::hardware::neuralnetworks::V1_0
-
-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;
-}
+} // namespace android::hardware::neuralnetworks::V1_2::vts::functional
diff --git a/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.h b/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.h
index e76ad7b..d01336e 100644
--- a/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.h
+++ b/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.h
@@ -17,92 +17,41 @@
#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 <iostream>
-#include <vector>
-
+#include "1.0/Utils.h"
#include "1.2/Callbacks.h"
-namespace android {
-namespace hardware {
-namespace neuralnetworks {
-namespace V1_2 {
+namespace android::hardware::neuralnetworks::V1_2::vts::functional {
-using V1_0::DeviceStatus;
-using V1_0::ErrorStatus;
-using V1_0::Request;
+using NamedDevice = Named<sp<IDevice>>;
+using NeuralnetworksHidlTestParam = NamedDevice;
-namespace vts {
-namespace functional {
-
-// A class for test environment setup
-class NeuralnetworksHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- DISALLOW_COPY_AND_ASSIGN(NeuralnetworksHidlEnvironment);
- NeuralnetworksHidlEnvironment();
- ~NeuralnetworksHidlEnvironment() override;
-
- 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();
- ~NeuralnetworksHidlTest() override;
+class NeuralnetworksHidlTest : public testing::TestWithParam<NeuralnetworksHidlTestParam> {
+ protected:
void SetUp() override;
- void TearDown() override;
-
- protected:
- sp<IDevice> device;
+ const sp<IDevice> kDevice = getData(GetParam());
};
-class ValidationTest : public NeuralnetworksHidlTest {
- protected:
- void validateEverything(const Model& model, const Request& request);
- void validateFailure(const Model& model, const Request& request);
+const std::vector<NamedDevice>& getNamedDevices();
- private:
- void validateModel(const Model& model);
- void validateRequest(const sp<IPreparedModel>& preparedModel, const Request& request);
- void validateRequestFailure(const sp<IPreparedModel>& preparedModel, const Request& request);
- void validateBurst(const sp<IPreparedModel>& preparedModel, const Request& request);
-};
+std::string printNeuralnetworksHidlTest(
+ const testing::TestParamInfo<NeuralnetworksHidlTestParam>& info);
-// Tag for the generated tests
-class GeneratedTest : public NeuralnetworksHidlTest {};
+#define INSTANTIATE_DEVICE_TEST(TestSuite) \
+ INSTANTIATE_TEST_SUITE_P(PerInstance, TestSuite, testing::ValuesIn(getNamedDevices()), \
+ printNeuralnetworksHidlTest)
-// Tag for the dynamic output shape tests
-class DynamicOutputShapeTest : public NeuralnetworksHidlTest {};
+// Create an IPreparedModel object. If the model cannot be prepared,
+// "preparedModel" will be nullptr instead.
+void createPreparedModel(const sp<IDevice>& device, const Model& model,
+ sp<IPreparedModel>* preparedModel);
// Utility function to get PreparedModel from callback and downcast to V1_2.
-sp<IPreparedModel> getPreparedModel_1_2(
- const sp<V1_2::implementation::PreparedModelCallback>& callback);
+sp<IPreparedModel> getPreparedModel_1_2(const sp<implementation::PreparedModelCallback>& callback);
-} // namespace functional
-} // namespace vts
-} // namespace V1_2
-} // namespace neuralnetworks
-} // namespace hardware
-} // namespace android
-
-namespace android::hardware::neuralnetworks::V1_0 {
-
-// pretty-print values for error messages
-::std::ostream& operator<<(::std::ostream& os, ErrorStatus errorStatus);
-::std::ostream& operator<<(::std::ostream& os, DeviceStatus deviceStatus);
-
-} // namespace android::hardware::neuralnetworks::V1_0
+} // namespace android::hardware::neuralnetworks::V1_2::vts::functional
#endif // ANDROID_HARDWARE_NEURALNETWORKS_V1_2_VTS_HAL_NEURALNETWORKS_H
diff --git a/neuralnetworks/1.2/vts/functional/include/1.2/Callbacks.h b/neuralnetworks/1.2/vts/functional/include/1.2/Callbacks.h
index 2992c0c..bf4792c 100644
--- a/neuralnetworks/1.2/vts/functional/include/1.2/Callbacks.h
+++ b/neuralnetworks/1.2/vts/functional/include/1.2/Callbacks.h
@@ -46,8 +46,6 @@
namespace android::hardware::neuralnetworks::V1_2::implementation {
-using V1_0::ErrorStatus;
-
/**
* The PreparedModelCallback class is used to receive the error status of
* preparing a model as well as the prepared model from a task executing
@@ -87,7 +85,8 @@
* @param preparedModel Returned model that has been prepared for execution,
* nullptr if the model was unable to be prepared.
*/
- Return<void> notify(ErrorStatus status, const sp<V1_0::IPreparedModel>& preparedModel) override;
+ Return<void> notify(V1_0::ErrorStatus status,
+ const sp<V1_0::IPreparedModel>& preparedModel) override;
/**
* IPreparedModelCallback::notify_1_2 marks the callback object with the
@@ -112,7 +111,7 @@
* @param preparedModel Returned model that has been prepared for execution,
* nullptr if the model was unable to be prepared.
*/
- Return<void> notify_1_2(ErrorStatus status,
+ Return<void> notify_1_2(V1_0::ErrorStatus status,
const sp<V1_2::IPreparedModel>& preparedModel) override;
/**
@@ -134,7 +133,7 @@
* - GENERAL_FAILURE if there is an unspecified error
* - INVALID_ARGUMENT if the input model is invalid
*/
- ErrorStatus getStatus() const;
+ V1_0::ErrorStatus getStatus() const;
/**
* Retrieves the model that has been prepared for execution from the
@@ -152,7 +151,7 @@
mutable std::mutex mMutex;
mutable std::condition_variable mCondition;
bool mNotified GUARDED_BY(mMutex) = false;
- ErrorStatus mErrorStatus = ErrorStatus::GENERAL_FAILURE;
+ V1_0::ErrorStatus mErrorStatus = V1_0::ErrorStatus::GENERAL_FAILURE;
sp<V1_0::IPreparedModel> mPreparedModel;
};
@@ -195,7 +194,7 @@
* enough to store the resultant values
* - INVALID_ARGUMENT if the input request is invalid
*/
- Return<void> notify(ErrorStatus status) override;
+ Return<void> notify(V1_0::ErrorStatus status) override;
/**
* IExecutionCallback::notify_1_2 marks the callback object with the results
@@ -230,11 +229,11 @@
* reported as UINT64_MAX. A driver may choose to report any time as
* UINT64_MAX, indicating that particular measurement is not available.
*/
- Return<void> notify_1_2(ErrorStatus status, const hidl_vec<OutputShape>& outputShapes,
+ Return<void> notify_1_2(V1_0::ErrorStatus status, const hidl_vec<OutputShape>& outputShapes,
const Timing& timing) override;
// An overload of the latest notify interface to hide the version from ExecutionBuilder.
- Return<void> notify(ErrorStatus status, const hidl_vec<OutputShape>& outputShapes,
+ Return<void> notify(V1_0::ErrorStatus status, const hidl_vec<OutputShape>& outputShapes,
const Timing& timing) {
return notify_1_2(status, outputShapes, timing);
}
@@ -264,7 +263,7 @@
* - INVALID_ARGUMENT if one of the input arguments to prepareModel is
* invalid
*/
- ErrorStatus getStatus() const;
+ V1_0::ErrorStatus getStatus() const;
/**
* Retrieves the output shapes returned from the asynchronous task launched
@@ -309,14 +308,14 @@
* object before any call to wait or get* return. It then enables all prior
* and future wait calls on the ExecutionCallback object to proceed.
*/
- void notifyInternal(ErrorStatus errorStatus, const hidl_vec<OutputShape>& outputShapes,
+ void notifyInternal(V1_0::ErrorStatus errorStatus, const hidl_vec<OutputShape>& outputShapes,
const Timing& timing);
// members
mutable std::mutex mMutex;
mutable std::condition_variable mCondition;
bool mNotified GUARDED_BY(mMutex) = false;
- ErrorStatus mErrorStatus = ErrorStatus::GENERAL_FAILURE;
+ V1_0::ErrorStatus mErrorStatus = V1_0::ErrorStatus::GENERAL_FAILURE;
std::vector<OutputShape> mOutputShapes = {};
Timing mTiming = {};
};
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/nfc/1.0/default/Android.bp b/nfc/1.0/default/Android.bp
index 3b53d16..9827edd 100644
--- a/nfc/1.0/default/Android.bp
+++ b/nfc/1.0/default/Android.bp
@@ -12,7 +12,6 @@
"libcutils",
"libutils",
"libhidlbase",
- "libhidltransport",
"android.hardware.nfc@1.0",
],
}
@@ -33,7 +32,6 @@
"libutils",
"libhardware",
"libhidlbase",
- "libhidltransport",
"android.hardware.nfc@1.0",
],
diff --git a/power/1.0/default/Android.bp b/power/1.0/default/Android.bp
index 4f43b95..1d152ee 100644
--- a/power/1.0/default/Android.bp
+++ b/power/1.0/default/Android.bp
@@ -28,7 +28,6 @@
"liblog",
"libhardware",
"libhidlbase",
- "libhidltransport",
"libutils",
"android.hardware.power@1.0",
],
@@ -54,7 +53,6 @@
"libutils",
"libhardware",
"libhidlbase",
- "libhidltransport",
"android.hardware.power@1.0",
],
diff --git a/power/stats/1.0/default/Android.bp b/power/stats/1.0/default/Android.bp
index 7a09639..0321da1 100644
--- a/power/stats/1.0/default/Android.bp
+++ b/power/stats/1.0/default/Android.bp
@@ -25,7 +25,6 @@
"libcutils",
"libfmq",
"libhidlbase",
- "libhidltransport",
"liblog",
"libutils",
"android.hardware.power.stats@1.0",
diff --git a/power/stats/1.0/vts/functional/Android.bp b/power/stats/1.0/vts/functional/Android.bp
index 4f0b325..f564cbe 100644
--- a/power/stats/1.0/vts/functional/Android.bp
+++ b/power/stats/1.0/vts/functional/Android.bp
@@ -31,8 +31,6 @@
"liblog",
"libhidlbase",
"libfmq",
- "libhidltransport",
- "libhwbinder",
"libutils",
],
}
diff --git a/radio/1.2/default/Android.bp b/radio/1.2/default/Android.bp
index f8ff4c7..74fcf11 100644
--- a/radio/1.2/default/Android.bp
+++ b/radio/1.2/default/Android.bp
@@ -9,7 +9,6 @@
],
shared_libs: [
"libhidlbase",
- "libhidltransport",
"liblog",
"libutils",
"android.hardware.radio@1.2",
@@ -29,7 +28,6 @@
],
shared_libs: [
"libhidlbase",
- "libhidltransport",
"liblog",
"libutils",
"android.hardware.radio@1.2",
diff --git a/radio/1.4/vts/functional/radio_hidl_hal_api.cpp b/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
index f81af9b..bf225bc 100644
--- a/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
@@ -398,7 +398,7 @@
.interval = 60,
.specifiers = {specifier},
.maxSearchTime = 600,
- .incrementalResults = false,
+ .incrementalResults = true,
.incrementalResultsPeriodicity = 0};
Return<void> res = radio_v1_4->startNetworkScan_1_4(serial, request);
@@ -434,7 +434,7 @@
.interval = 60,
.specifiers = {specifier},
.maxSearchTime = 600,
- .incrementalResults = false,
+ .incrementalResults = true,
.incrementalResultsPeriodicity = 11};
Return<void> res = radio_v1_4->startNetworkScan_1_4(serial, request);
diff --git a/radio/config/1.0/default/Android.bp b/radio/config/1.0/default/Android.bp
index f52335e..a0f4214 100644
--- a/radio/config/1.0/default/Android.bp
+++ b/radio/config/1.0/default/Android.bp
@@ -11,7 +11,6 @@
],
shared_libs: [
"libhidlbase",
- "libhidltransport",
"liblog",
"libutils",
"android.hardware.radio.config@1.0",
diff --git a/renderscript/1.0/default/Android.bp b/renderscript/1.0/default/Android.bp
index d5d6d8d..4fa85c6 100644
--- a/renderscript/1.0/default/Android.bp
+++ b/renderscript/1.0/default/Android.bp
@@ -14,7 +14,6 @@
"libdl",
"libbase",
"libhidlbase",
- "libhidltransport",
"libutils",
"android.hardware.renderscript@1.0",
],
diff --git a/sensors/1.0/default/Android.bp b/sensors/1.0/default/Android.bp
index 2485b05..d5c1b23 100644
--- a/sensors/1.0/default/Android.bp
+++ b/sensors/1.0/default/Android.bp
@@ -11,7 +11,6 @@
"libbase",
"libutils",
"libhidlbase",
- "libhidltransport",
"android.hardware.sensors@1.0",
],
static_libs: [
@@ -34,7 +33,6 @@
"libbase",
"libutils",
"libhidlbase",
- "libhidltransport",
"android.hardware.sensors@1.0",
],
local_include_dirs: ["include/sensors"],
@@ -57,7 +55,6 @@
"libbase",
"libutils",
"libhidlbase",
- "libhidltransport",
"android.hardware.sensors@1.0",
],
}
diff --git a/sensors/2.0/default/Android.bp b/sensors/2.0/default/Android.bp
index 05a34bb..62c9487 100644
--- a/sensors/2.0/default/Android.bp
+++ b/sensors/2.0/default/Android.bp
@@ -30,7 +30,6 @@
"libcutils",
"libfmq",
"libhidlbase",
- "libhidltransport",
"liblog",
"libpower",
"libutils",
diff --git a/sensors/2.0/multihal/Android.bp b/sensors/2.0/multihal/Android.bp
index dff28ab..216cc20 100644
--- a/sensors/2.0/multihal/Android.bp
+++ b/sensors/2.0/multihal/Android.bp
@@ -13,18 +13,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-cc_binary {
- name: "android.hardware.sensors@2.0-service.multihal",
- defaults: ["hidl_defaults"],
- vendor: true,
- relative_install_path: "hw",
- srcs: [
- "service.cpp",
- "HalProxy.cpp",
- ],
- init_rc: ["android.hardware.sensors@2.0-service-multihal.rc"],
+cc_defaults {
+ name: "android.hardware.sensors@2.0-multihal-defaults",
header_libs: [
- "android.hardware.sensors@2.0-subhal.header",
+ "android.hardware.sensors@2.0-multihal.header",
],
shared_libs: [
"android.hardware.sensors@1.0",
@@ -37,11 +29,42 @@
"libpower",
"libutils",
],
+}
+
+cc_binary {
+ name: "android.hardware.sensors@2.0-service.multihal",
+ defaults: [
+ "hidl_defaults",
+ "android.hardware.sensors@2.0-multihal-defaults",
+ ],
+ vendor: true,
+ relative_install_path: "hw",
+ srcs: [
+ "service.cpp",
+ "HalProxy.cpp",
+ "ScopedWakelock.cpp",
+ ],
+ init_rc: ["android.hardware.sensors@2.0-service-multihal.rc"],
vintf_fragments: ["android.hardware.sensors@2.0-multihal.xml"],
+ cflags: ["-DLOG_TAG=\"SensorsMultiHal\""],
}
cc_library_headers {
- name: "android.hardware.sensors@2.0-subhal.header",
- vendor: true,
+ name: "android.hardware.sensors@2.0-multihal.header",
+ vendor_available: true,
export_include_dirs: ["include"],
}
+
+// The below targets should only be used for testing.
+cc_test_library {
+ name: "android.hardware.sensors@2.0-HalProxy",
+ defaults: ["android.hardware.sensors@2.0-multihal-defaults"],
+ vendor_available: true,
+ srcs: [
+ "HalProxy.cpp",
+ "ScopedWakelock.cpp",
+ ],
+ export_header_lib_headers: [
+ "android.hardware.sensors@2.0-multihal.header",
+ ],
+}
diff --git a/sensors/2.0/multihal/HalProxy.cpp b/sensors/2.0/multihal/HalProxy.cpp
index 41c3548..81d1b64 100644
--- a/sensors/2.0/multihal/HalProxy.cpp
+++ b/sensors/2.0/multihal/HalProxy.cpp
@@ -16,12 +16,17 @@
#include "HalProxy.h"
+#include "SubHal.h"
+
#include <android/hardware/sensors/2.0/types.h>
+#include "hardware_legacy/power.h"
+
#include <dlfcn.h>
#include <fstream>
#include <functional>
+#include <thread>
namespace android {
namespace hardware {
@@ -29,79 +34,18 @@
namespace V2_0 {
namespace implementation {
+using ::android::hardware::sensors::V2_0::EventQueueFlagBits;
+
typedef ISensorsSubHal*(SensorsHalGetSubHalFunc)(uint32_t*);
-// TODO: Use this wake lock name as the prefix to all sensors HAL wake locks acquired.
-// constexpr const char* kWakeLockName = "SensorsHAL_WAKEUP";
-
-// TODO: Use the following class as a starting point for implementing the full HalProxyCallback
-// along with being inspiration for how to implement the ScopedWakelock class.
-/**
- * Callback class used to provide the HalProxy with the index of which subHal is invoking
- */
-class SensorsCallbackProxy : public ISensorsCallback {
- public:
- SensorsCallbackProxy(wp<HalProxy>& halProxy, int32_t subHalIndex)
- : mHalProxy(halProxy), mSubHalIndex(subHalIndex) {}
-
- Return<void> onDynamicSensorsConnected(
- const hidl_vec<SensorInfo>& dynamicSensorsAdded) override {
- sp<HalProxy> halProxy(mHalProxy.promote());
- if (halProxy != nullptr) {
- return halProxy->onDynamicSensorsConnected(dynamicSensorsAdded, mSubHalIndex);
- }
- return Return<void>();
- }
-
- Return<void> onDynamicSensorsDisconnected(
- const hidl_vec<int32_t>& dynamicSensorHandlesRemoved) override {
- sp<HalProxy> halProxy(mHalProxy.promote());
- if (halProxy != nullptr) {
- return halProxy->onDynamicSensorsDisconnected(dynamicSensorHandlesRemoved,
- mSubHalIndex);
- }
- return Return<void>();
- }
-
- private:
- wp<HalProxy>& mHalProxy;
- int32_t mSubHalIndex;
-};
-
HalProxy::HalProxy() {
- const char* kMultiHalConfigFilePath = "/vendor/etc/sensors/hals.conf";
- std::ifstream subHalConfigStream(kMultiHalConfigFilePath);
- if (!subHalConfigStream) {
- LOG_FATAL("Failed to load subHal config file: %s", kMultiHalConfigFilePath);
- } else {
- std::string subHalLibraryFile;
- while (subHalConfigStream >> subHalLibraryFile) {
- void* handle = dlopen(subHalLibraryFile.c_str(), RTLD_NOW);
- if (handle == nullptr) {
- LOG_FATAL("dlopen failed for library: %s", subHalLibraryFile.c_str());
- } else {
- SensorsHalGetSubHalFunc* sensorsHalGetSubHalPtr =
- (SensorsHalGetSubHalFunc*)dlsym(handle, "sensorsHalGetSubHal");
- if (sensorsHalGetSubHalPtr == nullptr) {
- LOG_FATAL("Failed to locate sensorsHalGetSubHal function for library: %s",
- subHalLibraryFile.c_str());
- } else {
- std::function<SensorsHalGetSubHalFunc> sensorsHalGetSubHal =
- *sensorsHalGetSubHalPtr;
- uint32_t version;
- ISensorsSubHal* subHal = sensorsHalGetSubHal(&version);
- if (version != SUB_HAL_2_0_VERSION) {
- LOG_FATAL("SubHal version was not 2.0 for library: %s",
- subHalLibraryFile.c_str());
- } else {
- ALOGI("Loaded SubHal from library: %s", subHalLibraryFile.c_str());
- mSubHalList.push_back(subHal);
- }
- }
- }
- }
- }
- // TODO: Discover sensors
+ const char* kMultiHalConfigFile = "/vendor/etc/sensors/hals.conf";
+ initializeSubHalListFromConfigFile(kMultiHalConfigFile);
+ initializeSubHalCallbacksAndSensorList();
+}
+
+HalProxy::HalProxy(std::vector<ISensorsSubHal*>& subHalList) : mSubHalList(subHalList) {
+ initializeSubHalCallbacksAndSensorList();
}
HalProxy::~HalProxy() {
@@ -109,19 +53,41 @@
// state.
}
-Return<void> HalProxy::getSensorsList(getSensorsList_cb /* _hidl_cb */) {
- // TODO: Output sensors list created as part of HalProxy().
+Return<void> HalProxy::getSensorsList(getSensorsList_cb _hidl_cb) {
+ std::vector<SensorInfo> sensors;
+ for (const auto& iter : mSensors) {
+ sensors.push_back(iter.second);
+ }
+ _hidl_cb(sensors);
return Void();
}
-Return<Result> HalProxy::setOperationMode(OperationMode /* mode */) {
- // TODO: Proxy API call to all sub-HALs and return appropriate result.
- return Result::INVALID_OPERATION;
+Return<Result> HalProxy::setOperationMode(OperationMode mode) {
+ Result result = Result::OK;
+ size_t subHalIndex;
+ for (subHalIndex = 0; subHalIndex < mSubHalList.size(); subHalIndex++) {
+ ISensorsSubHal* subHal = mSubHalList[subHalIndex];
+ result = subHal->setOperationMode(mode);
+ if (result != Result::OK) {
+ ALOGE("setOperationMode failed for SubHal: %s", subHal->getName().c_str());
+ break;
+ }
+ }
+ if (result != Result::OK) {
+ // Reset the subhal operation modes that have been flipped
+ for (size_t i = 0; i < subHalIndex; i++) {
+ ISensorsSubHal* subHal = mSubHalList[i];
+ subHal->setOperationMode(mCurrentOperationMode);
+ }
+ } else {
+ mCurrentOperationMode = mode;
+ }
+ return result;
}
-Return<Result> HalProxy::activate(int32_t /* sensorHandle */, bool /* enabled */) {
- // TODO: Proxy API call to appropriate sub-HAL.
- return Result::INVALID_OPERATION;
+Return<Result> HalProxy::activate(int32_t sensorHandle, bool enabled) {
+ return getSubHalForSensorHandle(sensorHandle)
+ ->activate(clearSubHalIndex(sensorHandle), enabled);
}
Return<Result> HalProxy::initialize(
@@ -156,18 +122,28 @@
// TODO: start threads to read wake locks and process events from sub HALs.
+ for (size_t i = 0; i < mSubHalList.size(); i++) {
+ auto subHal = mSubHalList[i];
+ const auto& subHalCallback = mSubHalCallbacks[i];
+ Result currRes = subHal->initialize(subHalCallback);
+ if (currRes != Result::OK) {
+ result = currRes;
+ ALOGE("Subhal '%s' failed to initialize.", subHal->getName().c_str());
+ break;
+ }
+ }
+
return result;
}
-Return<Result> HalProxy::batch(int32_t /* sensorHandle */, int64_t /* samplingPeriodNs */,
- int64_t /* maxReportLatencyNs */) {
- // TODO: Proxy API call to appropriate sub-HAL.
- return Result::INVALID_OPERATION;
+Return<Result> HalProxy::batch(int32_t sensorHandle, int64_t samplingPeriodNs,
+ int64_t maxReportLatencyNs) {
+ return getSubHalForSensorHandle(sensorHandle)
+ ->batch(clearSubHalIndex(sensorHandle), samplingPeriodNs, maxReportLatencyNs);
}
-Return<Result> HalProxy::flush(int32_t /* sensorHandle */) {
- // TODO: Proxy API call to appropriate sub-HAL.
- return Result::INVALID_OPERATION;
+Return<Result> HalProxy::flush(int32_t sensorHandle) {
+ return getSubHalForSensorHandle(sensorHandle)->flush(clearSubHalIndex(sensorHandle));
}
Return<Result> HalProxy::injectSensorData(const Event& /* event */) {
@@ -214,6 +190,175 @@
return Return<void>();
}
+void HalProxy::initializeSubHalListFromConfigFile(const char* configFileName) {
+ std::ifstream subHalConfigStream(configFileName);
+ if (!subHalConfigStream) {
+ ALOGE("Failed to load subHal config file: %s", configFileName);
+ } else {
+ std::string subHalLibraryFile;
+ while (subHalConfigStream >> subHalLibraryFile) {
+ void* handle = dlopen(subHalLibraryFile.c_str(), RTLD_NOW);
+ if (handle == nullptr) {
+ ALOGE("dlopen failed for library: %s", subHalLibraryFile.c_str());
+ } else {
+ SensorsHalGetSubHalFunc* sensorsHalGetSubHalPtr =
+ (SensorsHalGetSubHalFunc*)dlsym(handle, "sensorsHalGetSubHal");
+ if (sensorsHalGetSubHalPtr == nullptr) {
+ ALOGE("Failed to locate sensorsHalGetSubHal function for library: %s",
+ subHalLibraryFile.c_str());
+ } else {
+ std::function<SensorsHalGetSubHalFunc> sensorsHalGetSubHal =
+ *sensorsHalGetSubHalPtr;
+ uint32_t version;
+ ISensorsSubHal* subHal = sensorsHalGetSubHal(&version);
+ if (version != SUB_HAL_2_0_VERSION) {
+ ALOGE("SubHal version was not 2.0 for library: %s",
+ subHalLibraryFile.c_str());
+ } else {
+ ALOGV("Loaded SubHal from library: %s", subHalLibraryFile.c_str());
+ mSubHalList.push_back(subHal);
+ }
+ }
+ }
+ }
+ }
+}
+
+void HalProxy::initializeSubHalCallbacks() {
+ for (size_t subHalIndex = 0; subHalIndex < mSubHalList.size(); subHalIndex++) {
+ sp<IHalProxyCallback> callback = new HalProxyCallback(this, subHalIndex);
+ mSubHalCallbacks.push_back(callback);
+ }
+}
+
+void HalProxy::initializeSensorList() {
+ for (size_t subHalIndex = 0; subHalIndex < mSubHalList.size(); subHalIndex++) {
+ ISensorsSubHal* subHal = mSubHalList[subHalIndex];
+ auto result = subHal->getSensorsList([&](const auto& list) {
+ for (SensorInfo sensor : list) {
+ if ((sensor.sensorHandle & kSensorHandleSubHalIndexMask) != 0) {
+ ALOGE("SubHal sensorHandle's first byte was not 0");
+ } else {
+ ALOGV("Loaded sensor: %s", sensor.name.c_str());
+ sensor.sensorHandle |= (subHalIndex << 24);
+ setDirectChannelFlags(&sensor, subHal);
+ mSensors[sensor.sensorHandle] = sensor;
+ }
+ }
+ });
+ if (!result.isOk()) {
+ ALOGE("getSensorsList call failed for SubHal: %s", subHal->getName().c_str());
+ }
+ }
+}
+
+void HalProxy::initializeSubHalCallbacksAndSensorList() {
+ initializeSubHalCallbacks();
+ initializeSensorList();
+}
+
+void HalProxy::postEventsToMessageQueue(const std::vector<Event>& events) {
+ std::lock_guard<std::mutex> lock(mEventQueueMutex);
+ size_t numToWrite = std::min(events.size(), mEventQueue->availableToWrite());
+ if (numToWrite > 0) {
+ if (mEventQueue->write(events.data(), numToWrite)) {
+ // TODO: While loop if mEventQueue->avaiableToWrite > 0 to possibly fit in more writes
+ // immediately
+ mEventQueueFlag->wake(static_cast<uint32_t>(EventQueueFlagBits::READ_AND_PROCESS));
+ } else {
+ numToWrite = 0;
+ }
+ }
+ if (numToWrite < events.size()) {
+ // TODO: Post from events[numToWrite -> end] to background events queue
+ // Signal background thread
+ }
+}
+
+// TODO: Implement the wakelock timeout in these next two methods. Also pass in the subhal
+// index for better tracking.
+
+void HalProxy::incrementRefCountAndMaybeAcquireWakelock() {
+ std::lock_guard<std::mutex> lockGuard(mWakelockRefCountMutex);
+ if (mWakelockRefCount == 0) {
+ acquire_wake_lock(PARTIAL_WAKE_LOCK, kWakeLockName);
+ }
+ mWakelockRefCount++;
+}
+
+void HalProxy::decrementRefCountAndMaybeReleaseWakelock() {
+ std::lock_guard<std::mutex> lockGuard(mWakelockRefCountMutex);
+ mWakelockRefCount--;
+ if (mWakelockRefCount == 0) {
+ release_wake_lock(kWakeLockName);
+ }
+}
+
+void HalProxy::setDirectChannelFlags(SensorInfo* sensorInfo, ISensorsSubHal* subHal) {
+ bool sensorSupportsDirectChannel =
+ (sensorInfo->flags & (V1_0::SensorFlagBits::MASK_DIRECT_REPORT |
+ V1_0::SensorFlagBits::MASK_DIRECT_CHANNEL)) != 0;
+ if (mDirectChannelSubHal == nullptr && sensorSupportsDirectChannel) {
+ mDirectChannelSubHal = subHal;
+ } else if (mDirectChannelSubHal != nullptr && subHal != mDirectChannelSubHal) {
+ // disable direct channel capability for sensors in subHals that are not
+ // the only one we will enable
+ sensorInfo->flags &= ~(V1_0::SensorFlagBits::MASK_DIRECT_REPORT |
+ V1_0::SensorFlagBits::MASK_DIRECT_CHANNEL);
+ }
+}
+
+ISensorsSubHal* HalProxy::getSubHalForSensorHandle(uint32_t sensorHandle) {
+ return mSubHalList[static_cast<size_t>(sensorHandle >> 24)];
+}
+
+uint32_t HalProxy::clearSubHalIndex(uint32_t sensorHandle) {
+ return sensorHandle & (~kSensorHandleSubHalIndexMask);
+}
+
+void HalProxyCallback::postEvents(const std::vector<Event>& events, ScopedWakelock wakelock) {
+ (void)wakelock;
+ size_t numWakeupEvents;
+ std::vector<Event> processedEvents = processEvents(events, &numWakeupEvents);
+ if (numWakeupEvents > 0) {
+ ALOG_ASSERT(wakelock.isLocked(),
+ "Wakeup events posted while wakelock unlocked for subhal"
+ " w/ index %zu.",
+ mSubHalIndex);
+ } else {
+ ALOG_ASSERT(!wakelock.isLocked(),
+ "No Wakeup events posted but wakelock locked for subhal"
+ " w/ index %zu.",
+ mSubHalIndex);
+ }
+
+ mHalProxy->postEventsToMessageQueue(processedEvents);
+}
+
+ScopedWakelock HalProxyCallback::createScopedWakelock(bool lock) {
+ ScopedWakelock wakelock(mHalProxy, lock);
+ return wakelock;
+}
+
+std::vector<Event> HalProxyCallback::processEvents(const std::vector<Event>& events,
+ size_t* numWakeupEvents) const {
+ std::vector<Event> eventsOut;
+ *numWakeupEvents = 0;
+ for (Event event : events) {
+ event.sensorHandle = setSubHalIndex(event.sensorHandle);
+ eventsOut.push_back(event);
+ if ((mHalProxy->getSensorInfo(event.sensorHandle).flags & V1_0::SensorFlagBits::WAKE_UP) !=
+ 0) {
+ (*numWakeupEvents)++;
+ }
+ }
+ return eventsOut;
+}
+
+uint32_t HalProxyCallback::setSubHalIndex(uint32_t sensorHandle) const {
+ return sensorHandle | mSubHalIndex << 24;
+}
+
} // namespace implementation
} // namespace V2_0
} // namespace sensors
diff --git a/sensors/2.0/multihal/HalProxy.h b/sensors/2.0/multihal/HalProxy.h
deleted file mode 100644
index e5799fd..0000000
--- a/sensors/2.0/multihal/HalProxy.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "SubHal.h"
-
-#include <android/hardware/sensors/2.0/ISensors.h>
-#include <fmq/MessageQueue.h>
-#include <hardware_legacy/power.h>
-#include <hidl/MQDescriptor.h>
-#include <hidl/Status.h>
-
-namespace android {
-namespace hardware {
-namespace sensors {
-namespace V2_0 {
-namespace implementation {
-
-using ::android::sp;
-using ::android::hardware::EventFlag;
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::MessageQueue;
-using ::android::hardware::MQDescriptor;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-
-struct HalProxy : public ISensors {
- using Event = ::android::hardware::sensors::V1_0::Event;
- using OperationMode = ::android::hardware::sensors::V1_0::OperationMode;
- using RateLevel = ::android::hardware::sensors::V1_0::RateLevel;
- using Result = ::android::hardware::sensors::V1_0::Result;
- using SharedMemInfo = ::android::hardware::sensors::V1_0::SharedMemInfo;
-
- HalProxy();
- ~HalProxy();
-
- // Methods from ::android::hardware::sensors::V2_0::ISensors follow.
- Return<void> getSensorsList(getSensorsList_cb _hidl_cb) override;
-
- Return<Result> setOperationMode(OperationMode mode) override;
-
- Return<Result> activate(int32_t sensorHandle, bool enabled) override;
-
- Return<Result> initialize(
- const ::android::hardware::MQDescriptorSync<Event>& eventQueueDescriptor,
- const ::android::hardware::MQDescriptorSync<uint32_t>& wakeLockDescriptor,
- const sp<ISensorsCallback>& sensorsCallback) override;
-
- Return<Result> batch(int32_t sensorHandle, int64_t samplingPeriodNs,
- int64_t maxReportLatencyNs) override;
-
- Return<Result> flush(int32_t sensorHandle) override;
-
- Return<Result> injectSensorData(const Event& event) override;
-
- Return<void> registerDirectChannel(const SharedMemInfo& mem,
- registerDirectChannel_cb _hidl_cb) override;
-
- Return<Result> unregisterDirectChannel(int32_t channelHandle) override;
-
- Return<void> configDirectReport(int32_t sensorHandle, int32_t channelHandle, RateLevel rate,
- configDirectReport_cb _hidl_cb) override;
-
- Return<void> debug(const hidl_handle& fd, const hidl_vec<hidl_string>& args) override;
-
- // Below methods from ::android::hardware::sensors::V2_0::ISensorsCaback with a minor change
- // to pass in the sub-HAL index. While the above methods are invoked from the sensors framework
- // via the binder, these methods are invoked from a callback provided to sub-HALs inside the
- // same process as the HalProxy, but potentially running on different threads.
- Return<void> onDynamicSensorsConnected(const hidl_vec<SensorInfo>& dynamicSensorsAdded,
- int32_t subHalIndex);
-
- Return<void> onDynamicSensorsDisconnected(const hidl_vec<int32_t>& dynamicSensorHandlesRemoved,
- int32_t subHalIndex);
-
- private:
- using EventMessageQueue = MessageQueue<Event, kSynchronizedReadWrite>;
- using WakeLockMessageQueue = MessageQueue<uint32_t, kSynchronizedReadWrite>;
-
- /**
- * The Event FMQ where sensor events are written
- */
- std::unique_ptr<EventMessageQueue> mEventQueue;
-
- /**
- * The Wake Lock FMQ that is read to determine when the framework has handled WAKE_UP events
- */
- std::unique_ptr<WakeLockMessageQueue> mWakeLockQueue;
-
- /**
- * Event Flag to signal to the framework when sensor events are available to be read
- */
- EventFlag* mEventQueueFlag;
-
- /**
- * Callback to the sensors framework to inform it that new sensors have been added or removed.
- */
- sp<ISensorsCallback> mDynamicSensorsCallback;
-
- /**
- * SubHal object pointers that have been saved from vendor dynamic libraries.
- */
- std::vector<ISensorsSubHal*> mSubHalList;
-};
-
-} // namespace implementation
-} // namespace V2_0
-} // namespace sensors
-} // namespace hardware
-} // namespace android
diff --git a/sensors/2.0/multihal/ScopedWakelock.cpp b/sensors/2.0/multihal/ScopedWakelock.cpp
new file mode 100644
index 0000000..0430fa3
--- /dev/null
+++ b/sensors/2.0/multihal/ScopedWakelock.cpp
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+#include "ScopedWakelock.h"
+
+namespace android {
+namespace hardware {
+namespace sensors {
+namespace V2_0 {
+namespace implementation {
+
+ScopedWakelock::ScopedWakelock(IScopedWakelockRefCounter* refCounter, bool locked)
+ : mRefCounter(refCounter), mLocked(locked) {
+ // TODO: Move this implementation into HalProxy object instead
+ if (mLocked) {
+ mRefCounter->incrementRefCountAndMaybeAcquireWakelock();
+ }
+}
+
+ScopedWakelock::~ScopedWakelock() {
+ // TODO: Move this implementation into HalProxy object instead
+ if (mLocked) {
+ mRefCounter->decrementRefCountAndMaybeReleaseWakelock();
+ }
+}
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace sensors
+} // namespace hardware
+} // namespace android
\ No newline at end of file
diff --git a/sensors/2.0/multihal/include/HalProxy.h b/sensors/2.0/multihal/include/HalProxy.h
new file mode 100644
index 0000000..bdcc1ff
--- /dev/null
+++ b/sensors/2.0/multihal/include/HalProxy.h
@@ -0,0 +1,280 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "SubHal.h"
+
+#include <android/hardware/sensors/2.0/ISensors.h>
+#include <fmq/MessageQueue.h>
+#include <hardware_legacy/power.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+#include <map>
+
+namespace android {
+namespace hardware {
+namespace sensors {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::sp;
+using ::android::hardware::EventFlag;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::MessageQueue;
+using ::android::hardware::MQDescriptor;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+
+class HalProxy : public ISensors, public IScopedWakelockRefCounter {
+ public:
+ using Event = ::android::hardware::sensors::V1_0::Event;
+ using OperationMode = ::android::hardware::sensors::V1_0::OperationMode;
+ using RateLevel = ::android::hardware::sensors::V1_0::RateLevel;
+ using Result = ::android::hardware::sensors::V1_0::Result;
+ using SensorInfo = ::android::hardware::sensors::V1_0::SensorInfo;
+ using SharedMemInfo = ::android::hardware::sensors::V1_0::SharedMemInfo;
+ using ISensorsSubHal = ::android::hardware::sensors::V2_0::implementation::ISensorsSubHal;
+
+ explicit HalProxy();
+ // Test only constructor.
+ explicit HalProxy(std::vector<ISensorsSubHal*>& subHalList);
+ ~HalProxy();
+
+ // Methods from ::android::hardware::sensors::V2_0::ISensors follow.
+ Return<void> getSensorsList(getSensorsList_cb _hidl_cb) override;
+
+ Return<Result> setOperationMode(OperationMode mode) override;
+
+ Return<Result> activate(int32_t sensorHandle, bool enabled) override;
+
+ Return<Result> initialize(
+ const ::android::hardware::MQDescriptorSync<Event>& eventQueueDescriptor,
+ const ::android::hardware::MQDescriptorSync<uint32_t>& wakeLockDescriptor,
+ const sp<ISensorsCallback>& sensorsCallback) override;
+
+ Return<Result> batch(int32_t sensorHandle, int64_t samplingPeriodNs,
+ int64_t maxReportLatencyNs) override;
+
+ Return<Result> flush(int32_t sensorHandle) override;
+
+ Return<Result> injectSensorData(const Event& event) override;
+
+ Return<void> registerDirectChannel(const SharedMemInfo& mem,
+ registerDirectChannel_cb _hidl_cb) override;
+
+ Return<Result> unregisterDirectChannel(int32_t channelHandle) override;
+
+ Return<void> configDirectReport(int32_t sensorHandle, int32_t channelHandle, RateLevel rate,
+ configDirectReport_cb _hidl_cb) override;
+
+ Return<void> debug(const hidl_handle& fd, const hidl_vec<hidl_string>& args) override;
+
+ // Below methods from ::android::hardware::sensors::V2_0::ISensorsCallback with a minor change
+ // to pass in the sub-HAL index. While the above methods are invoked from the sensors framework
+ // via the binder, these methods are invoked from a callback provided to sub-HALs inside the
+ // same process as the HalProxy, but potentially running on different threads.
+ Return<void> onDynamicSensorsConnected(const hidl_vec<SensorInfo>& dynamicSensorsAdded,
+ int32_t subHalIndex);
+
+ Return<void> onDynamicSensorsDisconnected(const hidl_vec<int32_t>& dynamicSensorHandlesRemoved,
+ int32_t subHalIndex);
+
+ // Below methods follow IScopedWakelockRefCounter
+
+ /**
+ * Increment ref count and maybe acquire wakelock.
+ */
+ void incrementRefCountAndMaybeAcquireWakelock() override;
+
+ /**
+ * Decrement ref count and maybe release wakelock.
+ */
+ void decrementRefCountAndMaybeReleaseWakelock() override;
+
+ // Below methods are for HalProxyCallback
+
+ /**
+ * Post events to the event message queue if there is room to write them. Otherwise post the
+ * remaining events to a background thread for a blocking write with a 5 second timeout.
+ *
+ * @param events The list of events to post to the message queue.
+ */
+ void postEventsToMessageQueue(const std::vector<Event>& events);
+
+ /**
+ * Get the SensorInfo object associated with the sensorHandle.
+ *
+ * @param sensorHandle The sensorHandle for the sensor.
+ *
+ * @return The sensor info for the sensor.
+ */
+ const SensorInfo& getSensorInfo(uint32_t sensorHandle) const {
+ return mSensors.at(sensorHandle);
+ }
+
+ private:
+ using EventMessageQueue = MessageQueue<Event, kSynchronizedReadWrite>;
+ using WakeLockMessageQueue = MessageQueue<uint32_t, kSynchronizedReadWrite>;
+
+ const char* kWakeLockName = "SensorsHAL_WAKEUP";
+
+ /**
+ * The Event FMQ where sensor events are written
+ */
+ std::unique_ptr<EventMessageQueue> mEventQueue;
+
+ /**
+ * The Wake Lock FMQ that is read to determine when the framework has handled WAKE_UP events
+ */
+ std::unique_ptr<WakeLockMessageQueue> mWakeLockQueue;
+
+ /**
+ * Event Flag to signal to the framework when sensor events are available to be read
+ */
+ EventFlag* mEventQueueFlag;
+
+ /**
+ * Callback to the sensors framework to inform it that new sensors have been added or removed.
+ */
+ sp<ISensorsCallback> mDynamicSensorsCallback;
+
+ /**
+ * SubHal object pointers that have been saved from vendor dynamic libraries.
+ */
+ std::vector<ISensorsSubHal*> mSubHalList;
+
+ std::vector<const sp<IHalProxyCallback>> mSubHalCallbacks;
+
+ /**
+ * Map of sensor handles to SensorInfo objects that contains the sensor info from subhals as
+ * well as the modified sensor handle for the framework.
+ *
+ * The subhal index is encoded in the first byte of the sensor handle and the remaining
+ * bytes are generated by the subhal to identify the sensor.
+ */
+ std::map<uint32_t, SensorInfo> mSensors;
+
+ //! The current operation mode for all subhals.
+ OperationMode mCurrentOperationMode = OperationMode::NORMAL;
+
+ //! The single subHal that supports directChannel reporting.
+ ISensorsSubHal* mDirectChannelSubHal = nullptr;
+
+ //! The mutex for the event queue.
+ std::mutex mEventQueueMutex;
+
+ //! The scoped wakelock ref count.
+ size_t mWakelockRefCount = 0;
+
+ //! The mutex guarding the mWakelockRefCount variable
+ std::mutex mWakelockRefCountMutex;
+
+ //! The bit mask used to get the subhal index from a sensor handle.
+ static constexpr uint32_t kSensorHandleSubHalIndexMask = 0xFF000000;
+
+ /**
+ * Initialize the list of SubHal objects in mSubHalList by reading from dynamic libraries
+ * listed in a config file.
+ */
+ void initializeSubHalListFromConfigFile(const char* configFileName);
+
+ /**
+ * Initialize the HalProxyCallback vector using the list of subhals.
+ */
+ void initializeSubHalCallbacks();
+
+ /**
+ * Initialize the list of SensorInfo objects in mSensorList by getting sensors from each
+ * subhal.
+ */
+ void initializeSensorList();
+
+ /**
+ * Calls the above two helper methods which are shared in both ctors.
+ */
+ void initializeSubHalCallbacksAndSensorList();
+
+ /**
+ * Clear direct channel flags if the HalProxy has already chosen a subhal as its direct channel
+ * subhal. Set the directChannelSubHal pointer to the subHal passed in if this is the first
+ * direct channel enabled sensor seen.
+ *
+ * @param sensorInfo The SensorInfo object that may be altered to have direct channel support
+ * disabled.
+ * @param subHal The subhal pointer that the current sensorInfo object came from.
+ */
+ void setDirectChannelFlags(SensorInfo* sensorInfo, ISensorsSubHal* subHal);
+
+ /*
+ * Get the subhal pointer which can be found by indexing into the mSubHalList vector
+ * using the index from the first byte of sensorHandle.
+ *
+ * @param sensorHandle The handle used to identify a sensor in one of the subhals.
+ */
+ ISensorsSubHal* getSubHalForSensorHandle(uint32_t sensorHandle);
+
+ /*
+ * Clear out the subhal index bytes from a sensorHandle.
+ *
+ * @param sensorHandle The sensor handle to modify.
+ *
+ * @return The modified version of the sensor handle.
+ */
+ static uint32_t clearSubHalIndex(uint32_t sensorHandle);
+};
+
+/**
+ * Callback class used to provide the HalProxy with the index of which subHal is invoking
+ */
+class HalProxyCallback : public IHalProxyCallback {
+ using SensorInfo = ::android::hardware::sensors::V1_0::SensorInfo;
+
+ public:
+ HalProxyCallback(HalProxy* halProxy, int32_t subHalIndex)
+ : mHalProxy(halProxy), mSubHalIndex(subHalIndex) {}
+
+ Return<void> onDynamicSensorsConnected(
+ const hidl_vec<SensorInfo>& dynamicSensorsAdded) override {
+ return mHalProxy->onDynamicSensorsConnected(dynamicSensorsAdded, mSubHalIndex);
+ }
+
+ Return<void> onDynamicSensorsDisconnected(
+ const hidl_vec<int32_t>& dynamicSensorHandlesRemoved) override {
+ return mHalProxy->onDynamicSensorsDisconnected(dynamicSensorHandlesRemoved, mSubHalIndex);
+ }
+
+ void postEvents(const std::vector<Event>& events, ScopedWakelock wakelock);
+
+ ScopedWakelock createScopedWakelock(bool lock);
+
+ private:
+ HalProxy* mHalProxy;
+ int32_t mSubHalIndex;
+
+ std::vector<Event> processEvents(const std::vector<Event>& events,
+ size_t* numWakeupEvents) const;
+
+ uint32_t setSubHalIndex(uint32_t sensorHandle) const;
+};
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace sensors
+} // namespace hardware
+} // namespace android
diff --git a/sensors/2.0/multihal/include/ScopedWakelock.h b/sensors/2.0/multihal/include/ScopedWakelock.h
new file mode 100644
index 0000000..a151f15
--- /dev/null
+++ b/sensors/2.0/multihal/include/ScopedWakelock.h
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <mutex>
+
+namespace android {
+namespace hardware {
+namespace sensors {
+namespace V2_0 {
+namespace implementation {
+
+class IScopedWakelockRefCounter {
+ public:
+ virtual void incrementRefCountAndMaybeAcquireWakelock() = 0;
+ virtual void decrementRefCountAndMaybeReleaseWakelock() = 0;
+ // Virtual dtor needed for compilation success
+ virtual ~IScopedWakelockRefCounter(){};
+};
+
+/**
+ * Wrapper around wake lock acquisition functions (acquire/release_wake_lock) that provides a
+ * RAII-style mechanism for keeping a wake lock held for the duration of a scoped block.
+ * When a ScopedWakelock is created, it increments the reference count stored in the HalProxy
+ * for the sub-HALs specific wake lock, acquiring the wake lock if necessary. When the object goes
+ * out of scope, the ref count is decremented, potentially releasing the wake lock if no other
+ * references to the wake lock exist.
+ *
+ * This class is allocated through the createScopedWakelock callback inside the IHalProxyCallback
+ * provided to sub-HALs during initialization and should be used for all wake lock acquisition
+ * inside of the sub-HAL to ensure wake locks are not held indefinitely.
+ *
+ * The most prevalent use case for this class will be for posting events to the framework through
+ * the postEvents HalProxy callback. The expectation is that sub-HALs will create this
+ * ScopedWakelock through the createScopedWakelock upon receiving a sensor events. The lock boolean
+ * provided to createScopedWakelock will be set the according to whether the sensor events are
+ * from wakeup sensors. Then, the sub-HAL will perform any processing necessary before invoking the
+ * postEvents callback passing in the previously created ScopedWakelock. At this point, ownership
+ * of the object will be passed to the HalProxy that will then be responsible for ensuring any
+ * wake locks continue to be held, if necessary.
+ */
+class ScopedWakelock {
+ public:
+ ScopedWakelock(ScopedWakelock&&) = default;
+ ScopedWakelock& operator=(ScopedWakelock&&) = default;
+ virtual ~ScopedWakelock();
+
+ bool isLocked() const { return mLocked; }
+
+ private:
+ friend class HalProxyCallback;
+ IScopedWakelockRefCounter* mRefCounter;
+ bool mLocked;
+ ScopedWakelock(IScopedWakelockRefCounter* refCounter, bool locked);
+ ScopedWakelock(const ScopedWakelock&) = delete;
+ ScopedWakelock& operator=(const ScopedWakelock&) = delete;
+};
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace sensors
+} // namespace hardware
+} // namespace android
\ No newline at end of file
diff --git a/sensors/2.0/multihal/include/SubHal.h b/sensors/2.0/multihal/include/SubHal.h
index 75e93a1..e7eedaa 100644
--- a/sensors/2.0/multihal/include/SubHal.h
+++ b/sensors/2.0/multihal/include/SubHal.h
@@ -16,15 +16,13 @@
#pragma once
+#include "ScopedWakelock.h"
+
#include <android/hardware/sensors/1.0/types.h>
#include <android/hardware/sensors/2.0/ISensors.h>
#include <vector>
-using ::android::hardware::sensors::V1_0::Event;
-using ::android::hardware::sensors::V1_0::Result;
-using ::android::hardware::sensors::V1_0::SensorInfo;
-
// Indicates the current version of the multiHAL interface formatted as (HAL major version) << 24 |
// (HAL minor version) << 16 | (multiHAL version)
#define SUB_HAL_2_0_VERSION 0x02000000
@@ -35,44 +33,9 @@
namespace V2_0 {
namespace implementation {
-/**
- * Wrapper around wake lock acquisition functions (acquire/release_wake_lock) that provides a
- * RAII-style mechanism for keeping a wake lock held for the duration of a scoped block.
- * When a ScopedWakelock is created, it increments the reference count stored in the HalProxy
- * for the sub-HALs specific wake lock, acquiring the wake lock if necessary. When the object goes
- * out of scope, the ref count is decremented, potentially releasing the wake lock if no other
- * references to the wake lock exist.
- *
- * This class is allocated through the createScopedWakelock callback inside the IHalProxyCallback
- * provided to sub-HALs during initialization and should be used for all wake lock acquisition
- * inside of the sub-HAL to ensure wake locks are not held indefinitely.
- *
- * The most prevalent use case for this class will be for posting events to the framework through
- * the postEvents HalProxy callback. The expectation is that sub-HALs will create this
- * ScopedWakelock through the createScopedWakelock upon receiving a sensor events. The lock boolean
- * provided to createScopedWakelock will be set the according to whether the sensor events are
- * from wakeup sensors. Then, the sub-HAL will perform any processing necessary before invoking the
- * postEvents callback passing in the previously created ScopedWakelock. At this point, ownership
- * of the object will be passed to the HalProxy that will then be responsible for ensuring any
- * wake locks continue to be held, if necessary.
- */
-class ScopedWakelock {
- public:
- ScopedWakelock(ScopedWakelock&&) = default;
- ScopedWakelock& operator=(ScopedWakelock&&) = default;
- virtual ~ScopedWakelock() { mLocked = false; };
-
- bool isLocked() const { return mLocked; }
-
- protected:
- bool mLocked;
-
- private:
- // TODO: Mark HalProxy's subclass of ScopedWakelock as a friend so that it can be initialized.
- ScopedWakelock();
- ScopedWakelock(const ScopedWakelock&) = delete;
- ScopedWakelock& operator=(const ScopedWakelock&) = delete;
-};
+using ::android::hardware::sensors::V1_0::Event;
+using ::android::hardware::sensors::V1_0::Result;
+using ::android::hardware::sensors::V1_0::SensorInfo;
/**
* Interface that contains several callbacks into the HalProxy class to communicate dynamic sensor
@@ -137,6 +100,7 @@
* sub-HALs can continue to use the lower 3 bytes of the handle.
*/
class ISensorsSubHal : public ISensors {
+ public:
// The ISensors version of initialize isn't used for multihal. Instead, sub-HALs must implement
// the version below to allow communciation logic to centralized in the HalProxy
Return<Result> initialize(
@@ -168,7 +132,9 @@
/**
* First method invoked on the sub-HAL after it's allocated through sensorsHalGetSubHal() by the
* HalProxy. Sub-HALs should use this to initialize any state and retain the callback given in
- * order to communicate with the HalProxy.
+ * order to communicate with the HalProxy. Method will be called anytime the sensors framework
+ * restarts. Therefore, this method will be responsible for reseting the state of the subhal and
+ * cleaning up and reallocating any previously allocated data.
*
* @param halProxyCallback callback used to inform the HalProxy when a dynamic sensor's state
* changes, new sensor events should be sent to the framework, and when a new ScopedWakelock
diff --git a/sensors/2.0/multihal/service.cpp b/sensors/2.0/multihal/service.cpp
index 995cf3c..ef77048 100644
--- a/sensors/2.0/multihal/service.cpp
+++ b/sensors/2.0/multihal/service.cpp
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-#define LOG_TAG "android.hardware.sensors@2.0-service"
-
#include <android/hardware/sensors/2.0/ISensors.h>
#include <hidl/HidlTransportSupport.h>
#include <log/log.h>
diff --git a/sensors/2.0/multihal/testing/Android.bp b/sensors/2.0/multihal/testing/Android.bp
deleted file mode 100644
index 3dedbd6..0000000
--- a/sensors/2.0/multihal/testing/Android.bp
+++ /dev/null
@@ -1,55 +0,0 @@
-//
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-cc_defaults {
- name: "android.hardware.sensors@2.0-fakesubhal-defaults",
- vendor: true,
- srcs: [
- "Sensor.cpp",
- "SensorsSubHal.cpp",
- ],
- header_libs: [
- "android.hardware.sensors@2.0-subhal.header",
- ],
- shared_libs: [
- "android.hardware.sensors@1.0",
- "android.hardware.sensors@2.0",
- "libcutils",
- "libfmq",
- "libhidlbase",
- "libhidltransport",
- "liblog",
- "libpower",
- "libutils",
- ],
-}
-
-cc_library {
- name: "android.hardware.sensors@2.0-fakesubhal-config1",
- defaults: ["android.hardware.sensors@2.0-fakesubhal-defaults"],
- cflags: [
- "-DSUPPORT_CONTINUOUS_SENSORS",
- "-DSUB_HAL_NAME=\"FakeSubHal-Continuous\"",
- ],
-}
-
-cc_library {
- name: "android.hardware.sensors@2.0-fakesubhal-config2",
- defaults: ["android.hardware.sensors@2.0-fakesubhal-defaults"],
- cflags: [
- "-DSUPPORT_ON_CHANGE_SENSORS",
- "-DSUB_HAL_NAME=\"FakeSubHal-OnChange\"",
- ],
-}
\ No newline at end of file
diff --git a/sensors/2.0/multihal/tests/Android.bp b/sensors/2.0/multihal/tests/Android.bp
new file mode 100644
index 0000000..ab260a4
--- /dev/null
+++ b/sensors/2.0/multihal/tests/Android.bp
@@ -0,0 +1,92 @@
+//
+// 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.
+
+cc_defaults {
+ name: "android.hardware.sensors@2.0-fakesubhal-defaults",
+ srcs: [
+ "fake_subhal/*.cpp",
+ ],
+ header_libs: [
+ "android.hardware.sensors@2.0-multihal.header",
+ ],
+ export_include_dirs: ["fake_subhal"],
+ shared_libs: [
+ "android.hardware.sensors@1.0",
+ "android.hardware.sensors@2.0",
+ "libcutils",
+ "libfmq",
+ "libhidlbase",
+ "libhidltransport",
+ "liblog",
+ "libpower",
+ "libutils",
+ ],
+ static_libs: [
+ "android.hardware.sensors@2.0-HalProxy",
+ ],
+}
+
+cc_library {
+ name: "android.hardware.sensors@2.0-fakesubhal-config1",
+ vendor: true,
+ defaults: ["android.hardware.sensors@2.0-fakesubhal-defaults"],
+ cflags: [
+ "-DSUPPORT_CONTINUOUS_SENSORS",
+ "-DSUB_HAL_NAME=\"FakeSubHal-Continuous\"",
+ ],
+}
+
+cc_library {
+ name: "android.hardware.sensors@2.0-fakesubhal-config2",
+ vendor: true,
+ defaults: ["android.hardware.sensors@2.0-fakesubhal-defaults"],
+ cflags: [
+ "-DSUPPORT_ON_CHANGE_SENSORS",
+ "-DSUB_HAL_NAME=\"FakeSubHal-OnChange\"",
+ ],
+}
+
+cc_test_library {
+ name: "android.hardware.sensors@2.0-fakesubhal-unittest",
+ vendor_available: true,
+ defaults: ["android.hardware.sensors@2.0-fakesubhal-defaults"],
+ cflags: [
+ "-DSUPPORT_ON_CHANGE_SENSORS",
+ "-DSUPPORT_CONTINUOUS_SENSORS",
+ "-DSUB_HAL_NAME=\"FakeSubHal-Test\"",
+ ],
+}
+
+cc_test {
+ name: "android.hardware.sensors@2.0-halproxy-unit-tests",
+ srcs: ["HalProxy_test.cpp"],
+ vendor: true,
+ static_libs: [
+ "android.hardware.sensors@2.0-HalProxy",
+ "android.hardware.sensors@2.0-fakesubhal-unittest",
+ ],
+ shared_libs: [
+ "android.hardware.sensors@1.0",
+ "android.hardware.sensors@2.0",
+ "libcutils",
+ "libfmq",
+ "libhidlbase",
+ "libhidltransport",
+ "liblog",
+ "libpower",
+ "libutils",
+ ],
+ test_suites: ["device-tests"],
+}
diff --git a/sensors/2.0/multihal/tests/HalProxy_test.cpp b/sensors/2.0/multihal/tests/HalProxy_test.cpp
new file mode 100644
index 0000000..4b1a15e
--- /dev/null
+++ b/sensors/2.0/multihal/tests/HalProxy_test.cpp
@@ -0,0 +1,335 @@
+//
+// 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.
+
+#include <gtest/gtest.h>
+
+#include <android/hardware/sensors/2.0/types.h>
+#include <fmq/MessageQueue.h>
+
+#include "HalProxy.h"
+#include "ScopedWakelock.h"
+#include "SensorsSubHal.h"
+
+#include <vector>
+
+#undef LOG_TAG
+#define LOG_TAG "HalProxy_test"
+
+namespace {
+
+using ::android::hardware::hidl_vec;
+using ::android::hardware::MessageQueue;
+using ::android::hardware::Return;
+using ::android::hardware::sensors::V1_0::EventPayload;
+using ::android::hardware::sensors::V1_0::SensorFlagBits;
+using ::android::hardware::sensors::V1_0::SensorInfo;
+using ::android::hardware::sensors::V1_0::SensorType;
+using ::android::hardware::sensors::V2_0::ISensorsCallback;
+using ::android::hardware::sensors::V2_0::implementation::HalProxy;
+using ::android::hardware::sensors::V2_0::implementation::HalProxyCallback;
+using ::android::hardware::sensors::V2_0::subhal::implementation::AllSensorsSubHal;
+using ::android::hardware::sensors::V2_0::subhal::implementation::
+ AllSupportDirectChannelSensorsSubHal;
+using ::android::hardware::sensors::V2_0::subhal::implementation::ContinuousSensorsSubHal;
+using ::android::hardware::sensors::V2_0::subhal::implementation::
+ DoesNotSupportDirectChannelSensorsSubHal;
+using ::android::hardware::sensors::V2_0::subhal::implementation::OnChangeSensorsSubHal;
+using ::android::hardware::sensors::V2_0::subhal::implementation::SensorsSubHal;
+using ::android::hardware::sensors::V2_0::subhal::implementation::
+ SetOperationModeFailingSensorsSubHal;
+
+using EventMessageQueue = MessageQueue<Event, ::android::hardware::kSynchronizedReadWrite>;
+using WakeupMessageQueue = MessageQueue<uint32_t, ::android::hardware::kSynchronizedReadWrite>;
+
+// The barebones sensors callback class passed into halproxy initialize calls
+class SensorsCallback : public ISensorsCallback {
+ public:
+ Return<void> onDynamicSensorsConnected(
+ const hidl_vec<SensorInfo>& /*dynamicSensorsAdded*/) override {
+ // Nothing yet
+ return Return<void>();
+ }
+
+ Return<void> onDynamicSensorsDisconnected(
+ const hidl_vec<int32_t>& /*dynamicSensorHandlesRemoved*/) override {
+ // Nothing yet
+ return Return<void>();
+ }
+};
+
+// Helper declarations follow
+
+/**
+ * Tests that for each SensorInfo object from a proxy getSensorsList call each corresponding
+ * object from a subhal getSensorsList call has the same type and its last 3 bytes are the
+ * same for sensorHandle field.
+ *
+ * @param proxySensorsList The list of SensorInfo objects from the proxy.getSensorsList callback.
+ * @param subHalSenosrsList The list of SensorInfo objects from the subHal.getSensorsList callback.
+ */
+void testSensorsListFromProxyAndSubHal(const std::vector<SensorInfo>& proxySensorsList,
+ const std::vector<SensorInfo>& subHalSensorsList);
+
+/**
+ * Tests that there is exactly one subhal that allows its sensors to have direct channel enabled.
+ * Therefore, all SensorInfo objects that are not from the enabled subhal should be disabled for
+ * direct channel.
+ *
+ * @param sensorsList The SensorInfo object list from proxy.getSensorsList call.
+ * @param enabledSubHalIndex The index of the subhal in the halproxy that is expected to be
+ * enabled.
+ */
+void testSensorsListForOneDirectChannelEnabledSubHal(const std::vector<SensorInfo>& sensorsList,
+ size_t enabledSubHalIndex);
+
+/**
+ * Construct and return a HIDL Event type thats sensorHandle refers to a proximity sensor
+ * which is a wakeup type sensor.
+ *
+ * @ return A proximity event.
+ */
+Event makeProximityEvent();
+
+/**
+ * Construct and return a HIDL Event type thats sensorHandle refers to a proximity sensor
+ * which is a wakeup type sensor.
+ *
+ * @ return A proximity event.
+ */
+Event makeAccelerometerEvent();
+
+// Tests follow
+TEST(HalProxyTest, GetSensorsListOneSubHalTest) {
+ AllSensorsSubHal subHal;
+ std::vector<ISensorsSubHal*> fakeSubHals{&subHal};
+ HalProxy proxy(fakeSubHals);
+
+ proxy.getSensorsList([&](const auto& proxySensorsList) {
+ subHal.getSensorsList([&](const auto& subHalSensorsList) {
+ testSensorsListFromProxyAndSubHal(proxySensorsList, subHalSensorsList);
+ });
+ });
+}
+
+TEST(HalProxyTest, GetSensorsListTwoSubHalTest) {
+ ContinuousSensorsSubHal continuousSubHal;
+ OnChangeSensorsSubHal onChangeSubHal;
+ std::vector<ISensorsSubHal*> fakeSubHals;
+ fakeSubHals.push_back(&continuousSubHal);
+ fakeSubHals.push_back(&onChangeSubHal);
+ HalProxy proxy(fakeSubHals);
+
+ std::vector<SensorInfo> proxySensorsList, combinedSubHalSensorsList;
+
+ proxy.getSensorsList([&](const auto& list) { proxySensorsList = list; });
+ continuousSubHal.getSensorsList([&](const auto& list) {
+ combinedSubHalSensorsList.insert(combinedSubHalSensorsList.end(), list.begin(), list.end());
+ });
+ onChangeSubHal.getSensorsList([&](const auto& list) {
+ combinedSubHalSensorsList.insert(combinedSubHalSensorsList.end(), list.begin(), list.end());
+ });
+
+ testSensorsListFromProxyAndSubHal(proxySensorsList, combinedSubHalSensorsList);
+}
+
+TEST(HalProxyTest, SetOperationModeTwoSubHalSuccessTest) {
+ ContinuousSensorsSubHal subHal1;
+ OnChangeSensorsSubHal subHal2;
+
+ std::vector<ISensorsSubHal*> fakeSubHals{&subHal1, &subHal2};
+ HalProxy proxy(fakeSubHals);
+
+ EXPECT_EQ(subHal1.getOperationMode(), OperationMode::NORMAL);
+ EXPECT_EQ(subHal2.getOperationMode(), OperationMode::NORMAL);
+
+ Result result = proxy.setOperationMode(OperationMode::DATA_INJECTION);
+
+ EXPECT_EQ(result, Result::OK);
+ EXPECT_EQ(subHal1.getOperationMode(), OperationMode::DATA_INJECTION);
+ EXPECT_EQ(subHal2.getOperationMode(), OperationMode::DATA_INJECTION);
+}
+
+TEST(HalProxyTest, SetOperationModeTwoSubHalFailTest) {
+ AllSensorsSubHal subHal1;
+ SetOperationModeFailingSensorsSubHal subHal2;
+
+ std::vector<ISensorsSubHal*> fakeSubHals{&subHal1, &subHal2};
+ HalProxy proxy(fakeSubHals);
+
+ EXPECT_EQ(subHal1.getOperationMode(), OperationMode::NORMAL);
+ EXPECT_EQ(subHal2.getOperationMode(), OperationMode::NORMAL);
+
+ Result result = proxy.setOperationMode(OperationMode::DATA_INJECTION);
+
+ EXPECT_NE(result, Result::OK);
+ EXPECT_EQ(subHal1.getOperationMode(), OperationMode::NORMAL);
+ EXPECT_EQ(subHal2.getOperationMode(), OperationMode::NORMAL);
+}
+
+TEST(HalProxyTest, InitDirectChannelTwoSubHalsUnitTest) {
+ AllSupportDirectChannelSensorsSubHal subHal1;
+ AllSupportDirectChannelSensorsSubHal subHal2;
+
+ std::vector<ISensorsSubHal*> fakeSubHals{&subHal1, &subHal2};
+ HalProxy proxy(fakeSubHals);
+
+ proxy.getSensorsList([&](const auto& sensorsList) {
+ testSensorsListForOneDirectChannelEnabledSubHal(sensorsList, 0);
+ });
+}
+
+TEST(HalProxyTest, InitDirectChannelThreeSubHalsUnitTest) {
+ DoesNotSupportDirectChannelSensorsSubHal subHal1;
+ AllSupportDirectChannelSensorsSubHal subHal2, subHal3;
+ std::vector<ISensorsSubHal*> fakeSubHals{&subHal1, &subHal2, &subHal3};
+ HalProxy proxy(fakeSubHals);
+
+ proxy.getSensorsList([&](const auto& sensorsList) {
+ testSensorsListForOneDirectChannelEnabledSubHal(sensorsList, 1);
+ });
+}
+
+TEST(HalProxyTest, PostSingleNonWakeupEvent) {
+ constexpr size_t kQueueSize = 5;
+ AllSensorsSubHal subHal;
+ std::vector<ISensorsSubHal*> subHals{&subHal};
+ HalProxy proxy(subHals);
+ std::unique_ptr<EventMessageQueue> eventQueue =
+ std::make_unique<EventMessageQueue>(kQueueSize, true);
+ std::unique_ptr<WakeupMessageQueue> wakeLockQueue =
+ std::make_unique<WakeupMessageQueue>(kQueueSize, true);
+ ::android::sp<ISensorsCallback> callback = new SensorsCallback();
+ proxy.initialize(*eventQueue->getDesc(), *wakeLockQueue->getDesc(), callback);
+
+ std::vector<Event> events{makeAccelerometerEvent()};
+ subHal.postEvents(events, false /* wakeup */);
+
+ EXPECT_EQ(eventQueue->availableToRead(), 1);
+}
+
+TEST(HalProxyTest, PostMultipleNonWakeupEvent) {
+ constexpr size_t kQueueSize = 5;
+ constexpr size_t kNumEvents = 3;
+ AllSensorsSubHal subHal;
+ std::vector<ISensorsSubHal*> subHals{&subHal};
+ HalProxy proxy(subHals);
+ std::unique_ptr<EventMessageQueue> eventQueue =
+ std::make_unique<EventMessageQueue>(kQueueSize, true);
+ std::unique_ptr<WakeupMessageQueue> wakeLockQueue =
+ std::make_unique<WakeupMessageQueue>(kQueueSize, true);
+ ::android::sp<ISensorsCallback> callback = new SensorsCallback();
+ proxy.initialize(*eventQueue->getDesc(), *wakeLockQueue->getDesc(), callback);
+
+ std::vector<Event> events;
+ for (size_t i = 0; i < kNumEvents; i++) {
+ events.push_back(makeAccelerometerEvent());
+ }
+ subHal.postEvents(events, false /* wakeup */);
+
+ EXPECT_EQ(eventQueue->availableToRead(), kNumEvents);
+}
+
+TEST(HalProxyTest, PostSingleWakeupEvent) {
+ constexpr size_t kQueueSize = 5;
+ AllSensorsSubHal subHal;
+ std::vector<ISensorsSubHal*> subHals{&subHal};
+ HalProxy proxy(subHals);
+ std::unique_ptr<EventMessageQueue> eventQueue =
+ std::make_unique<EventMessageQueue>(kQueueSize, true);
+ std::unique_ptr<WakeupMessageQueue> wakeLockQueue =
+ std::make_unique<WakeupMessageQueue>(kQueueSize, true);
+ ::android::sp<ISensorsCallback> callback = new SensorsCallback();
+ proxy.initialize(*eventQueue->getDesc(), *wakeLockQueue->getDesc(), callback);
+
+ std::vector<Event> events{makeProximityEvent()};
+ subHal.postEvents(events, true /* wakeup */);
+
+ EXPECT_EQ(eventQueue->availableToRead(), 1);
+}
+
+TEST(HalProxyTest, PostMultipleWakeupEvents) {
+ constexpr size_t kQueueSize = 5;
+ constexpr size_t kNumEvents = 3;
+ AllSensorsSubHal subHal;
+ std::vector<ISensorsSubHal*> subHals{&subHal};
+ HalProxy proxy(subHals);
+ std::unique_ptr<EventMessageQueue> eventQueue =
+ std::make_unique<EventMessageQueue>(kQueueSize, true);
+ std::unique_ptr<WakeupMessageQueue> wakeLockQueue =
+ std::make_unique<WakeupMessageQueue>(kQueueSize, true);
+ ::android::sp<ISensorsCallback> callback = new SensorsCallback();
+ proxy.initialize(*eventQueue->getDesc(), *wakeLockQueue->getDesc(), callback);
+
+ std::vector<Event> events;
+ for (size_t i = 0; i < kNumEvents; i++) {
+ events.push_back(makeProximityEvent());
+ }
+ subHal.postEvents(events, true /* wakeup */);
+
+ EXPECT_EQ(eventQueue->availableToRead(), kNumEvents);
+}
+
+// Helper implementations follow
+void testSensorsListFromProxyAndSubHal(const std::vector<SensorInfo>& proxySensorsList,
+ const std::vector<SensorInfo>& subHalSensorsList) {
+ EXPECT_EQ(proxySensorsList.size(), subHalSensorsList.size());
+
+ for (size_t i = 0; i < proxySensorsList.size(); i++) {
+ const SensorInfo& proxySensor = proxySensorsList[i];
+ const SensorInfo& subHalSensor = subHalSensorsList[i];
+
+ EXPECT_EQ(proxySensor.type, subHalSensor.type);
+ EXPECT_EQ(proxySensor.sensorHandle & 0x00FFFFFF, subHalSensor.sensorHandle);
+ }
+}
+
+void testSensorsListForOneDirectChannelEnabledSubHal(const std::vector<SensorInfo>& sensorsList,
+ size_t enabledSubHalIndex) {
+ for (const SensorInfo& sensor : sensorsList) {
+ size_t subHalIndex = static_cast<size_t>(sensor.sensorHandle >> 24);
+ if (subHalIndex == enabledSubHalIndex) {
+ // First subhal should have been picked as the direct channel subhal
+ // and so have direct channel enabled on all of its sensors
+ EXPECT_NE(sensor.flags & SensorFlagBits::MASK_DIRECT_REPORT, 0);
+ EXPECT_NE(sensor.flags & SensorFlagBits::MASK_DIRECT_CHANNEL, 0);
+ } else {
+ // All other subhals should have direct channel disabled for all sensors
+ EXPECT_EQ(sensor.flags & SensorFlagBits::MASK_DIRECT_REPORT, 0);
+ EXPECT_EQ(sensor.flags & SensorFlagBits::MASK_DIRECT_CHANNEL, 0);
+ }
+ }
+}
+
+Event makeProximityEvent() {
+ Event event;
+ event.timestamp = 0xFF00FF00;
+ // This is the sensorhandle of proximity, which is wakeup type
+ event.sensorHandle = 0x00000008;
+ event.sensorType = SensorType::PROXIMITY;
+ event.u = EventPayload();
+ return event;
+}
+
+Event makeAccelerometerEvent() {
+ Event event;
+ event.timestamp = 0xFF00FF00;
+ // This is the sensorhandle of proximity, which is wakeup type
+ event.sensorHandle = 0x00000001;
+ event.sensorType = SensorType::ACCELEROMETER;
+ event.u = EventPayload();
+ return event;
+}
+
+} // namespace
diff --git a/sensors/2.0/multihal/testing/README b/sensors/2.0/multihal/tests/fake_subhal/README
similarity index 100%
rename from sensors/2.0/multihal/testing/README
rename to sensors/2.0/multihal/tests/fake_subhal/README
diff --git a/sensors/2.0/multihal/testing/Sensor.cpp b/sensors/2.0/multihal/tests/fake_subhal/Sensor.cpp
similarity index 97%
rename from sensors/2.0/multihal/testing/Sensor.cpp
rename to sensors/2.0/multihal/tests/fake_subhal/Sensor.cpp
index e095efe..4d53665 100644
--- a/sensors/2.0/multihal/testing/Sensor.cpp
+++ b/sensors/2.0/multihal/tests/fake_subhal/Sensor.cpp
@@ -43,11 +43,14 @@
}
Sensor::~Sensor() {
- std::unique_lock<std::mutex> lock(mRunMutex);
- mStopThread = true;
- mIsEnabled = false;
- mWaitCV.notify_all();
- lock.release();
+ // Ensure that lock is unlocked before calling mRunThread.join() or a
+ // deadlock will occur.
+ {
+ std::unique_lock<std::mutex> lock(mRunMutex);
+ mStopThread = true;
+ mIsEnabled = false;
+ mWaitCV.notify_all();
+ }
mRunThread.join();
}
diff --git a/sensors/2.0/multihal/testing/Sensor.h b/sensors/2.0/multihal/tests/fake_subhal/Sensor.h
similarity index 100%
rename from sensors/2.0/multihal/testing/Sensor.h
rename to sensors/2.0/multihal/tests/fake_subhal/Sensor.h
diff --git a/sensors/2.0/multihal/testing/SensorsSubHal.cpp b/sensors/2.0/multihal/tests/fake_subhal/SensorsSubHal.cpp
similarity index 72%
rename from sensors/2.0/multihal/testing/SensorsSubHal.cpp
rename to sensors/2.0/multihal/tests/fake_subhal/SensorsSubHal.cpp
index 8d45982..d581c49 100644
--- a/sensors/2.0/multihal/testing/SensorsSubHal.cpp
+++ b/sensors/2.0/multihal/tests/fake_subhal/SensorsSubHal.cpp
@@ -20,7 +20,16 @@
#include <log/log.h>
ISensorsSubHal* sensorsHalGetSubHal(uint32_t* version) {
+#if defined SUPPORT_CONTINUOUS_SENSORS && defined SUPPORT_ON_CHANGE_SENSORS
+ static ::android::hardware::sensors::V2_0::subhal::implementation::AllSensorsSubHal subHal;
+#elif defined SUPPORT_CONTINUOUS_SENSORS
+ static ::android::hardware::sensors::V2_0::subhal::implementation::ContinuousSensorsSubHal
+ subHal;
+#elif defined SUPPORT_ON_CHANGE_SENSORS
+ static ::android::hardware::sensors::V2_0::subhal::implementation::OnChangeSensorsSubHal subHal;
+#else
static ::android::hardware::sensors::V2_0::subhal::implementation::SensorsSubHal subHal;
+#endif // defined SUPPORT_CONTINUOUS_SENSORS && defined SUPPORT_ON_CHANGE_SENSORS
*version = SUB_HAL_2_0_VERSION;
return &subHal;
}
@@ -42,22 +51,7 @@
using ::android::hardware::sensors::V2_0::WakeLockQueueFlagBits;
using ::android::hardware::sensors::V2_0::implementation::ScopedWakelock;
-SensorsSubHal::SensorsSubHal() : mCallback(nullptr), mNextHandle(1) {
-#ifdef SUPPORT_CONTINUOUS_SENSORS
- AddSensor<AccelSensor>();
- AddSensor<GyroSensor>();
- AddSensor<MagnetometerSensor>();
- AddSensor<PressureSensor>();
-#endif // SUPPORT_CONTINUOUS_SENSORS
-
-#ifdef SUPPORT_ON_CHANGE_SENSORS
- AddSensor<AmbientTempSensor>();
- AddSensor<DeviceTempSensor>();
- AddSensor<LightSensor>();
- AddSensor<ProximitySensor>();
- AddSensor<RelativeHumiditySensor>();
-#endif // SUPPORT_ON_CHANGE_SENSORS
-}
+SensorsSubHal::SensorsSubHal() : mCallback(nullptr), mNextHandle(1) {}
// Methods from ::android::hardware::sensors::V2_0::ISensors follow.
Return<void> SensorsSubHal::getSensorsList(getSensorsList_cb _hidl_cb) {
@@ -74,6 +68,7 @@
for (auto sensor : mSensors) {
sensor.second->setOperationMode(mode);
}
+ mCurrentOperationMode = mode;
return Result::OK;
}
@@ -171,6 +166,61 @@
mCallback->postEvents(events, std::move(wakelock));
}
+ContinuousSensorsSubHal::ContinuousSensorsSubHal() {
+ AddSensor<AccelSensor>();
+ AddSensor<GyroSensor>();
+ AddSensor<MagnetometerSensor>();
+ AddSensor<PressureSensor>();
+}
+
+OnChangeSensorsSubHal::OnChangeSensorsSubHal() {
+ AddSensor<AmbientTempSensor>();
+ AddSensor<DeviceTempSensor>();
+ AddSensor<LightSensor>();
+ AddSensor<ProximitySensor>();
+ AddSensor<RelativeHumiditySensor>();
+}
+
+AllSensorsSubHal::AllSensorsSubHal() {
+ AddSensor<AccelSensor>();
+ AddSensor<GyroSensor>();
+ AddSensor<MagnetometerSensor>();
+ AddSensor<PressureSensor>();
+ AddSensor<AmbientTempSensor>();
+ AddSensor<DeviceTempSensor>();
+ AddSensor<LightSensor>();
+ AddSensor<ProximitySensor>();
+ AddSensor<RelativeHumiditySensor>();
+}
+
+Return<Result> SetOperationModeFailingSensorsSubHal::setOperationMode(OperationMode /*mode*/) {
+ return Result::BAD_VALUE;
+}
+
+Return<void> AllSupportDirectChannelSensorsSubHal::getSensorsList(getSensorsList_cb _hidl_cb) {
+ std::vector<SensorInfo> sensors;
+ for (const auto& sensor : mSensors) {
+ SensorInfo sensorInfo = sensor.second->getSensorInfo();
+ sensorInfo.flags |= V1_0::SensorFlagBits::MASK_DIRECT_CHANNEL;
+ sensorInfo.flags |= V1_0::SensorFlagBits::MASK_DIRECT_REPORT;
+ sensors.push_back(sensorInfo);
+ }
+ _hidl_cb(sensors);
+ return Void();
+}
+
+Return<void> DoesNotSupportDirectChannelSensorsSubHal::getSensorsList(getSensorsList_cb _hidl_cb) {
+ std::vector<SensorInfo> sensors;
+ for (const auto& sensor : mSensors) {
+ SensorInfo sensorInfo = sensor.second->getSensorInfo();
+ sensorInfo.flags &= ~static_cast<uint32_t>(V1_0::SensorFlagBits::MASK_DIRECT_CHANNEL);
+ sensorInfo.flags &= ~static_cast<uint32_t>(V1_0::SensorFlagBits::MASK_DIRECT_REPORT);
+ sensors.push_back(sensorInfo);
+ }
+ _hidl_cb(sensors);
+ return Void();
+}
+
} // namespace implementation
} // namespace subhal
} // namespace V2_0
diff --git a/sensors/2.0/multihal/testing/SensorsSubHal.h b/sensors/2.0/multihal/tests/fake_subhal/SensorsSubHal.h
similarity index 73%
rename from sensors/2.0/multihal/testing/SensorsSubHal.h
rename to sensors/2.0/multihal/tests/fake_subhal/SensorsSubHal.h
index 93009d5..61caa2c 100644
--- a/sensors/2.0/multihal/testing/SensorsSubHal.h
+++ b/sensors/2.0/multihal/tests/fake_subhal/SensorsSubHal.h
@@ -20,6 +20,8 @@
#include "Sensor.h"
+#include <vector>
+
namespace android {
namespace hardware {
namespace sensors {
@@ -27,6 +29,8 @@
namespace subhal {
namespace implementation {
+using ::android::hardware::sensors::V1_0::OperationMode;
+using ::android::hardware::sensors::V1_0::Result;
using ::android::hardware::sensors::V2_0::implementation::IHalProxyCallback;
/**
@@ -35,18 +39,18 @@
*/
class SensorsSubHal : public ISensorsSubHal, public ISensorsEventCallback {
using Event = ::android::hardware::sensors::V1_0::Event;
- using OperationMode = ::android::hardware::sensors::V1_0::OperationMode;
using RateLevel = ::android::hardware::sensors::V1_0::RateLevel;
- using Result = ::android::hardware::sensors::V1_0::Result;
using SharedMemInfo = ::android::hardware::sensors::V1_0::SharedMemInfo;
public:
SensorsSubHal();
// Methods from ::android::hardware::sensors::V2_0::ISensors follow.
- Return<void> getSensorsList(getSensorsList_cb _hidl_cb) override;
+ virtual Return<void> getSensorsList(getSensorsList_cb _hidl_cb) override;
- Return<Result> setOperationMode(OperationMode mode) override;
+ virtual Return<Result> setOperationMode(OperationMode mode) override;
+
+ OperationMode getOperationMode() const { return mCurrentOperationMode; }
Return<Result> activate(int32_t sensorHandle, bool enabled) override;
@@ -81,7 +85,7 @@
// Method from ISensorsEventCallback.
void postEvents(const std::vector<Event>& events, bool wakeup) override;
- private:
+ protected:
template <class SensorType>
void AddSensor() {
std::shared_ptr<SensorType> sensor =
@@ -90,6 +94,18 @@
}
/**
+ * A map of the available sensors
+ */
+ std::map<int32_t, std::shared_ptr<Sensor>> mSensors;
+
+ private:
+ /**
+ * The current operation mode of the multihal framework. Ensures that all subhals are set to
+ * the same operation mode.
+ */
+ OperationMode mCurrentOperationMode = OperationMode::NORMAL;
+
+ /**
* Callback used to communicate to the HalProxy when dynamic sensors are connected /
* disconnected, sensor events need to be sent to the framework, and when a wakelock should be
* acquired.
@@ -97,16 +113,44 @@
sp<IHalProxyCallback> mCallback;
/**
- * A map of the available sensors
- */
- std::map<int32_t, std::shared_ptr<Sensor>> mSensors;
-
- /**
* The next available sensor handle
*/
int32_t mNextHandle;
};
+// SubHal that has continuous sensors for testing purposes.
+class ContinuousSensorsSubHal : public SensorsSubHal {
+ public:
+ ContinuousSensorsSubHal();
+};
+
+// SubHal that has on-change sensors for testing purposes.
+class OnChangeSensorsSubHal : public SensorsSubHal {
+ public:
+ OnChangeSensorsSubHal();
+};
+
+// SubHal that has both continuous and on-change sensors for testing purposes.
+class AllSensorsSubHal : public SensorsSubHal {
+ public:
+ AllSensorsSubHal();
+};
+
+class SetOperationModeFailingSensorsSubHal : public AllSensorsSubHal {
+ public:
+ Return<Result> setOperationMode(OperationMode mode) override;
+};
+
+class AllSupportDirectChannelSensorsSubHal : public AllSensorsSubHal {
+ public:
+ Return<void> getSensorsList(getSensorsList_cb _hidl_cb) override;
+};
+
+class DoesNotSupportDirectChannelSensorsSubHal : public AllSensorsSubHal {
+ public:
+ Return<void> getSensorsList(getSensorsList_cb _hidl_cb) override;
+};
+
} // namespace implementation
} // namespace subhal
} // namespace V2_0
diff --git a/soundtrigger/2.0/default/Android.bp b/soundtrigger/2.0/default/Android.bp
index cc20f91..1f9ae45 100644
--- a/soundtrigger/2.0/default/Android.bp
+++ b/soundtrigger/2.0/default/Android.bp
@@ -28,7 +28,6 @@
shared_libs: [
"libhidlbase",
- "libhidltransport",
"liblog",
"libutils",
"libhardware",
diff --git a/soundtrigger/2.1/default/Android.mk b/soundtrigger/2.1/default/Android.mk
index 5851d63..b8d0407 100644
--- a/soundtrigger/2.1/default/Android.mk
+++ b/soundtrigger/2.1/default/Android.mk
@@ -29,7 +29,6 @@
libhardware \
libhidlbase \
libhidlmemory \
- libhidltransport \
liblog \
libutils \
android.hardware.soundtrigger@2.1 \
diff --git a/soundtrigger/2.2/default/Android.bp b/soundtrigger/2.2/default/Android.bp
index 78bb69f..db37c5b 100644
--- a/soundtrigger/2.2/default/Android.bp
+++ b/soundtrigger/2.2/default/Android.bp
@@ -22,7 +22,6 @@
],
shared_libs: [
"libhidlbase",
- "libhidltransport",
"liblog",
"libhidlmemory",
"libutils",
diff --git a/tests/bar/1.0/default/Android.bp b/tests/bar/1.0/default/Android.bp
index 8aa6135..8e3d072 100644
--- a/tests/bar/1.0/default/Android.bp
+++ b/tests/bar/1.0/default/Android.bp
@@ -13,8 +13,6 @@
"libbase",
"libcutils",
"libhidlbase",
- "libhidltransport",
- "libhwbinder",
"liblog",
"libutils",
],
diff --git a/tests/baz/1.0/IBaz.hal b/tests/baz/1.0/IBaz.hal
index 91ed1f2..7855446 100644
--- a/tests/baz/1.0/IBaz.hal
+++ b/tests/baz/1.0/IBaz.hal
@@ -29,6 +29,11 @@
VALL = V0 | V1 | V2 | V3,
};
+ struct BitFieldTester {
+ bitfield<BitField> scalar;
+ vec<bitfield<BitField>> vector;
+ };
+
enum SomeOtherEnum : uint8_t {
bar = 66
};
@@ -108,6 +113,7 @@
haveSomeStrings(string[3] array) generates (string[2] result);
haveAStringVec(vec<string> vector) generates (vec<string> result);
+ repeatBitfieldVec(vec<bitfield<BitField>> vector) generates (vec<bitfield<BitField>> result);
returnABunchOfStrings() generates (string a, string b, string c);
diff --git a/tests/baz/1.0/default/Android.bp b/tests/baz/1.0/default/Android.bp
index 492e0b4..4096d47 100644
--- a/tests/baz/1.0/default/Android.bp
+++ b/tests/baz/1.0/default/Android.bp
@@ -9,8 +9,6 @@
"libbase",
"libcutils",
"libhidlbase",
- "libhidltransport",
- "libhwbinder",
"liblog",
"libutils",
],
diff --git a/tests/baz/1.0/default/Baz.cpp b/tests/baz/1.0/default/Baz.cpp
index e118122..2ce096c 100644
--- a/tests/baz/1.0/default/Baz.cpp
+++ b/tests/baz/1.0/default/Baz.cpp
@@ -364,6 +364,12 @@
return Void();
}
+Return<void> Baz::repeatBitfieldVec(const hidl_vec<uint8_t>& vector,
+ repeatBitfieldVec_cb _hidl_cb) {
+ _hidl_cb(vector);
+ return Void();
+}
+
Return<void> Baz::returnABunchOfStrings(returnABunchOfStrings_cb _hidl_cb) {
hidl_string eins; eins = "Eins";
hidl_string zwei; zwei = "Zwei";
diff --git a/tests/baz/1.0/default/Baz.h b/tests/baz/1.0/default/Baz.h
index c264f47..1e24d52 100644
--- a/tests/baz/1.0/default/Baz.h
+++ b/tests/baz/1.0/default/Baz.h
@@ -86,6 +86,8 @@
haveSomeStrings_cb _hidl_cb) override;
Return<void> haveAStringVec(const hidl_vec<hidl_string>& vector,
haveAStringVec_cb _hidl_cb) override;
+ Return<void> repeatBitfieldVec(const hidl_vec<uint8_t>& vector,
+ repeatBitfieldVec_cb _hidl_cb) override;
Return<void> returnABunchOfStrings(returnABunchOfStrings_cb _hidl_cb) override;
Return<uint8_t> returnABitField() override;
Return<uint32_t> size(uint32_t size) override;
diff --git a/tests/extension/light/2.0/default/Android.bp b/tests/extension/light/2.0/default/Android.bp
index dcac97c..d8d8dd5 100644
--- a/tests/extension/light/2.0/default/Android.bp
+++ b/tests/extension/light/2.0/default/Android.bp
@@ -27,7 +27,6 @@
shared_libs: [
"libhidlbase",
- "libhidltransport",
"libutils",
"android.hardware.light@2.0",
"android.hardware.tests.extension.light@2.0",
diff --git a/tests/foo/1.0/default/Android.bp b/tests/foo/1.0/default/Android.bp
index d9dfc69..48d6894 100644
--- a/tests/foo/1.0/default/Android.bp
+++ b/tests/foo/1.0/default/Android.bp
@@ -13,8 +13,6 @@
"libcutils",
"libfootest",
"libhidlbase",
- "libhidltransport",
- "libhwbinder",
"liblog",
"libutils",
],
diff --git a/tests/foo/1.0/default/lib/Android.bp b/tests/foo/1.0/default/lib/Android.bp
index 2cc96c5..ba2081e 100644
--- a/tests/foo/1.0/default/lib/Android.bp
+++ b/tests/foo/1.0/default/lib/Android.bp
@@ -8,8 +8,6 @@
shared_libs: [
"libcutils",
"libhidlbase",
- "libhidltransport",
- "libhwbinder",
"liblog",
],
static_libs: ["android.hardware.tests.foo@1.0"],
diff --git a/tests/hash/1.0/default/Android.bp b/tests/hash/1.0/default/Android.bp
index 6e6d6a8..410b759 100644
--- a/tests/hash/1.0/default/Android.bp
+++ b/tests/hash/1.0/default/Android.bp
@@ -8,8 +8,6 @@
shared_libs: [
"libcutils",
"libhidlbase",
- "libhidltransport",
- "libhwbinder",
"liblog",
"libutils",
],
diff --git a/tests/inheritance/1.0/default/Android.bp b/tests/inheritance/1.0/default/Android.bp
index 891355b..4a0c876 100644
--- a/tests/inheritance/1.0/default/Android.bp
+++ b/tests/inheritance/1.0/default/Android.bp
@@ -14,8 +14,6 @@
"libbase",
"libcutils",
"libhidlbase",
- "libhidltransport",
- "libhwbinder",
"liblog",
"libutils",
],
diff --git a/tests/libhwbinder/1.0/default/Android.bp b/tests/libhwbinder/1.0/default/Android.bp
index aad1e31..81022b8 100644
--- a/tests/libhwbinder/1.0/default/Android.bp
+++ b/tests/libhwbinder/1.0/default/Android.bp
@@ -9,8 +9,6 @@
shared_libs: [
"libcutils",
"libhidlbase",
- "libhidltransport",
- "libhwbinder",
"liblog",
"libutils",
],
diff --git a/tests/memory/1.0/default/Android.bp b/tests/memory/1.0/default/Android.bp
index 3f13634..0293953 100644
--- a/tests/memory/1.0/default/Android.bp
+++ b/tests/memory/1.0/default/Android.bp
@@ -22,9 +22,7 @@
shared_libs: [
"libcutils",
"libhidlbase",
- "libhidltransport",
"libhidlmemory",
- "libhwbinder",
"liblog",
"libutils",
"android.hidl.memory@1.0",
diff --git a/tests/msgq/1.0/default/Android.bp b/tests/msgq/1.0/default/Android.bp
index 6c8be6c..e6408aa 100644
--- a/tests/msgq/1.0/default/Android.bp
+++ b/tests/msgq/1.0/default/Android.bp
@@ -26,8 +26,6 @@
"libcutils",
"libfmq",
"libhidlbase",
- "libhidltransport",
- "libhwbinder",
"liblog",
"libutils",
],
@@ -49,7 +47,6 @@
"libbase",
"libcutils",
"libhidlbase",
- "libhidltransport",
"liblog",
"libutils",
"android.hardware.tests.msgq@1.0"
@@ -68,8 +65,6 @@
"libcutils",
"libfmq",
"libhidlbase",
- "libhidltransport",
- "libhwbinder",
"liblog",
"libutils",
],
diff --git a/tests/multithread/1.0/default/Android.bp b/tests/multithread/1.0/default/Android.bp
index a94ee3e..ff89938 100644
--- a/tests/multithread/1.0/default/Android.bp
+++ b/tests/multithread/1.0/default/Android.bp
@@ -9,8 +9,6 @@
"libbase",
"libcutils",
"libhidlbase",
- "libhidltransport",
- "libhwbinder",
"liblog",
"libutils",
],
diff --git a/tests/safeunion/1.0/default/Android.bp b/tests/safeunion/1.0/default/Android.bp
index fc2443e..759a49c 100644
--- a/tests/safeunion/1.0/default/Android.bp
+++ b/tests/safeunion/1.0/default/Android.bp
@@ -9,8 +9,6 @@
"libbase",
"libcutils",
"libhidlbase",
- "libhidltransport",
- "libhwbinder",
"liblog",
"libutils",
],
diff --git a/tests/safeunion/cpp/1.0/default/Android.bp b/tests/safeunion/cpp/1.0/default/Android.bp
index 210a639..618f295 100644
--- a/tests/safeunion/cpp/1.0/default/Android.bp
+++ b/tests/safeunion/cpp/1.0/default/Android.bp
@@ -8,8 +8,6 @@
"libbase",
"libcutils",
"libhidlbase",
- "libhidltransport",
- "libhwbinder",
"liblog",
"libutils",
],
diff --git a/tests/trie/1.0/default/Android.bp b/tests/trie/1.0/default/Android.bp
index 948a8cb..4ca705c 100644
--- a/tests/trie/1.0/default/Android.bp
+++ b/tests/trie/1.0/default/Android.bp
@@ -9,8 +9,6 @@
"libbase",
"libcutils",
"libhidlbase",
- "libhidltransport",
- "libhwbinder",
"liblog",
"libutils",
],
diff --git a/thermal/1.0/default/Android.bp b/thermal/1.0/default/Android.bp
index 9d81474..194a9f8 100644
--- a/thermal/1.0/default/Android.bp
+++ b/thermal/1.0/default/Android.bp
@@ -27,7 +27,6 @@
"libcutils",
"libutils",
"libhidlbase",
- "libhidltransport",
"android.hardware.thermal@1.0",
],
}
@@ -48,7 +47,6 @@
"libutils",
"libhardware",
"libhidlbase",
- "libhidltransport",
"android.hardware.thermal@1.0",
],
}
diff --git a/thermal/2.0/default/Android.bp b/thermal/2.0/default/Android.bp
index dab0d33..7b72694 100644
--- a/thermal/2.0/default/Android.bp
+++ b/thermal/2.0/default/Android.bp
@@ -27,7 +27,6 @@
shared_libs: [
"libbase",
"libhidlbase",
- "libhidltransport",
"libutils",
"android.hardware.thermal@2.0",
"android.hardware.thermal@1.0",
diff --git a/tv/cec/1.0/default/Android.bp b/tv/cec/1.0/default/Android.bp
index 5fe731b..239a527 100644
--- a/tv/cec/1.0/default/Android.bp
+++ b/tv/cec/1.0/default/Android.bp
@@ -7,7 +7,6 @@
shared_libs: [
"libhidlbase",
- "libhidltransport",
"liblog",
"libbase",
"libutils",
@@ -34,7 +33,6 @@
"libhardware_legacy",
"libhardware",
"libhidlbase",
- "libhidltransport",
"android.hardware.tv.cec@1.0",
],
@@ -58,7 +56,6 @@
"libutils",
"libhardware",
"libhidlbase",
- "libhidltransport",
"android.hardware.tv.cec@1.0",
],
}
diff --git a/tv/cec/1.0/default/HdmiCecMock.cpp b/tv/cec/1.0/default/HdmiCecMock.cpp
index eba8f95..219be86 100644
--- a/tv/cec/1.0/default/HdmiCecMock.cpp
+++ b/tv/cec/1.0/default/HdmiCecMock.cpp
@@ -77,6 +77,7 @@
if (message.body.size() == 0) {
return SendMessageResult::NACK;
}
+ sendMessageToFifo(message);
return SendMessageResult::SUCCESS;
}
@@ -88,6 +89,11 @@
if (callback != nullptr) {
mCallback = callback;
mCallback->linkToDeath(this, 0 /*cookie*/);
+
+ mInputFile = open(CEC_MSG_IN_FIFO, O_RDWR);
+ mOutputFile = open(CEC_MSG_OUT_FIFO, O_RDWR);
+ pthread_create(&mThreadId, NULL, __threadLoop, this);
+ pthread_setname_np(mThreadId, "hdmi_cec_loop");
}
return Void();
}
@@ -102,17 +108,8 @@
}
Return<void> HdmiCecMock::getPortInfo(getPortInfo_cb _hidl_cb) {
- vector<HdmiPortInfo> portInfos;
// TODO ready port info from device specific config
- portInfos.resize(mTotalPorts);
- for (int i = 0; i < mTotalPorts; ++i) {
- portInfos[i] = {.type = HdmiPortType::INPUT,
- .portId = static_cast<uint32_t>(i),
- .cecSupported = true,
- .arcSupported = (i == 0),
- .physicalAddress = static_cast<uint16_t>(i << 12)};
- }
- _hidl_cb(portInfos);
+ _hidl_cb(mPortInfo);
return Void();
}
@@ -140,13 +137,177 @@
return Void();
}
-Return<bool> HdmiCecMock::isConnected(int32_t portId __unused) {
+Return<bool> HdmiCecMock::isConnected(int32_t portId) {
// maintain port connection status and update on hotplug event
+ if (portId < mTotalPorts && portId >= 0) {
+ return mPortConnectionStatus[portId];
+ }
return false;
}
+void* HdmiCecMock::__threadLoop(void* user) {
+ HdmiCecMock* const self = static_cast<HdmiCecMock*>(user);
+ self->threadLoop();
+ return 0;
+}
+
+int HdmiCecMock::readMessageFromFifo(unsigned char* buf, int msgCount) {
+ if (msgCount <= 0 || !buf) {
+ return 0;
+ }
+
+ int ret = -1;
+ /* maybe blocked at driver */
+ ret = read(mInputFile, buf, msgCount);
+ if (ret < 0) {
+ ALOGE("[halimp] read :%s failed, ret:%d\n", CEC_MSG_IN_FIFO, ret);
+ return -1;
+ }
+
+ return ret;
+}
+
+int HdmiCecMock::sendMessageToFifo(const CecMessage& message) {
+ unsigned char msgBuf[CEC_MESSAGE_BODY_MAX_LENGTH];
+ int ret = -1;
+
+ memset(msgBuf, 0, sizeof(msgBuf));
+ msgBuf[0] = ((static_cast<uint8_t>(message.initiator) & 0xf) << 4) |
+ (static_cast<uint8_t>(message.destination) & 0xf);
+
+ size_t length = std::min(static_cast<size_t>(message.body.size()),
+ static_cast<size_t>(MaxLength::MESSAGE_BODY));
+ for (size_t i = 0; i < length; ++i) {
+ msgBuf[i + 1] = static_cast<unsigned char>(message.body[i]);
+ }
+
+ // open the output pipe for writing outgoing cec message
+ mOutputFile = open(CEC_MSG_OUT_FIFO, O_WRONLY);
+ if (mOutputFile < 0) {
+ ALOGD("[halimp] file open failed for writing");
+ return -1;
+ }
+
+ // write message into the output pipe
+ ret = write(mOutputFile, msgBuf, length + 1);
+ close(mOutputFile);
+ if (ret < 0) {
+ ALOGE("[halimp] write :%s failed, ret:%d\n", CEC_MSG_OUT_FIFO, ret);
+ return -1;
+ }
+ return ret;
+}
+
+void HdmiCecMock::printCecMsgBuf(const char* msg_buf, int len) {
+ char buf[64] = {};
+ int i, size = 0;
+ memset(buf, 0, sizeof(buf));
+ for (i = 0; i < len; i++) {
+ size += sprintf(buf + size, " %02x", msg_buf[i]);
+ }
+ ALOGD("[halimp] %s, msg:%s", __FUNCTION__, buf);
+}
+
+void HdmiCecMock::handleHotplugMessage(unsigned char* msgBuf) {
+ HotplugEvent hotplugEvent{.connected = ((msgBuf[3]) & 0xf) > 0,
+ .portId = static_cast<uint32_t>(msgBuf[0] & 0xf)};
+
+ if (hotplugEvent.portId >= mPortInfo.size()) {
+ ALOGD("[halimp] ignore hot plug message, id %x does not exist", hotplugEvent.portId);
+ return;
+ }
+
+ ALOGD("[halimp] hot plug port id %x, is connected %x", (msgBuf[0] & 0xf), (msgBuf[3] & 0xf));
+ if (mPortInfo[hotplugEvent.portId].type == HdmiPortType::OUTPUT) {
+ mPhysicalAddress =
+ ((hotplugEvent.connected == 0) ? 0xffff : ((msgBuf[1] << 8) | (msgBuf[2])));
+ mPortInfo[hotplugEvent.portId].physicalAddress = mPhysicalAddress;
+ ALOGD("[halimp] hot plug physical address %x", mPhysicalAddress);
+ }
+
+ // todo update connection status
+
+ if (mCallback != nullptr) {
+ mCallback->onHotplugEvent(hotplugEvent);
+ }
+}
+
+void HdmiCecMock::handleCecMessage(unsigned char* msgBuf, int megSize) {
+ CecMessage message;
+ size_t length = std::min(static_cast<size_t>(megSize - 1),
+ static_cast<size_t>(MaxLength::MESSAGE_BODY));
+ message.body.resize(length);
+
+ for (size_t i = 0; i < length; ++i) {
+ message.body[i] = static_cast<uint8_t>(msgBuf[i + 1]);
+ ALOGD("[halimp] msg body %x", message.body[i]);
+ }
+
+ message.initiator = static_cast<CecLogicalAddress>((msgBuf[0] >> 4) & 0xf);
+ ALOGD("[halimp] msg init %x", message.initiator);
+ message.destination = static_cast<CecLogicalAddress>((msgBuf[0] >> 0) & 0xf);
+ ALOGD("[halimp] msg dest %x", message.destination);
+
+ // messageValidateAndHandle(&event);
+
+ if (mCallback != nullptr) {
+ mCallback->onCecMessage(message);
+ }
+}
+
+void HdmiCecMock::threadLoop() {
+ ALOGD("[halimp] threadLoop start.");
+ unsigned char msgBuf[CEC_MESSAGE_BODY_MAX_LENGTH];
+ int r = -1;
+
+ // open the input pipe
+ while (mInputFile < 0) {
+ usleep(1000 * 1000);
+ mInputFile = open(CEC_MSG_IN_FIFO, O_RDONLY);
+ }
+ ALOGD("[halimp] file open ok, fd = %d.", mInputFile);
+
+ while (mCecThreadRun) {
+ if (!mOptionSystemCecControl) {
+ usleep(1000 * 1000);
+ continue;
+ }
+
+ memset(msgBuf, 0, sizeof(msgBuf));
+ // try to get a message from dev.
+ // echo -n -e '\x04\x83' >> /dev/cec
+ r = readMessageFromFifo(msgBuf, CEC_MESSAGE_BODY_MAX_LENGTH);
+ if (r <= 1) {
+ // ignore received ping messages
+ continue;
+ }
+
+ printCecMsgBuf((const char*)msgBuf, r);
+
+ if (((msgBuf[0] >> 4) & 0xf) == 0xf) {
+ // the message is a hotplug event
+ handleHotplugMessage(msgBuf);
+ continue;
+ }
+
+ handleCecMessage(msgBuf, r);
+ }
+
+ ALOGD("[halimp] thread end.");
+ // mCecDevice.mExited = true;
+}
+
HdmiCecMock::HdmiCecMock() {
- ALOGE("Opening a virtual HAL for testing and virtual machine.");
+ ALOGE("[halimp] Opening a virtual HAL for testing and virtual machine.");
+ mCallback = nullptr;
+ mPortInfo.resize(mTotalPorts);
+ mPortConnectionStatus.resize(mTotalPorts);
+ mPortInfo[0] = {.type = HdmiPortType::OUTPUT,
+ .portId = static_cast<uint32_t>(0),
+ .cecSupported = true,
+ .arcSupported = false,
+ .physicalAddress = mPhysicalAddress};
+ mPortConnectionStatus[0] = false;
}
} // namespace implementation
diff --git a/tv/cec/1.0/default/HdmiCecMock.h b/tv/cec/1.0/default/HdmiCecMock.h
index b2f1113..0a708fa 100644
--- a/tv/cec/1.0/default/HdmiCecMock.h
+++ b/tv/cec/1.0/default/HdmiCecMock.h
@@ -49,6 +49,9 @@
using ::android::hardware::tv::cec::V1_0::Result;
using ::android::hardware::tv::cec::V1_0::SendMessageResult;
+#define CEC_MSG_IN_FIFO "/dev/cec_in_pipe"
+#define CEC_MSG_OUT_FIFO "/dev/cec_out_pipe"
+
struct HdmiCecMock : public IHdmiCec, public hidl_death_recipient {
HdmiCecMock();
// Methods from ::android::hardware::tv::cec::V1_0::IHdmiCec follow.
@@ -71,21 +74,43 @@
}
void cec_set_option(int flag, int value);
+ void printCecMsgBuf(const char* msg_buf, int len);
+
+ private:
+ static void* __threadLoop(void* data);
+ void threadLoop();
+ int readMessageFromFifo(unsigned char* buf, int msgCount);
+ int sendMessageToFifo(const CecMessage& message);
+ void handleHotplugMessage(unsigned char* msgBuf);
+ void handleCecMessage(unsigned char* msgBuf, int length);
private:
sp<IHdmiCecCallback> mCallback;
+
// Variables for the virtual cec hal impl
uint16_t mPhysicalAddress = 0xFFFF;
vector<CecLogicalAddress> mLogicalAddresses;
int32_t mCecVersion = 0;
uint32_t mCecVendorId = 0;
+
// Port configuration
- int mTotalPorts = 4;
+ int mTotalPorts = 1;
+ hidl_vec<HdmiPortInfo> mPortInfo;
+ hidl_vec<bool> mPortConnectionStatus;
+
// CEC Option value
int mOptionWakeUp = 0;
int mOptionEnableCec = 0;
int mOptionSystemCecControl = 0;
int mOptionLanguage = 0;
+
+ // Testing variables
+ // Input file descriptor
+ int mInputFile;
+ // Output file descriptor
+ int mOutputFile;
+ bool mCecThreadRun = true;
+ pthread_t mThreadId = 0;
};
} // namespace implementation
} // namespace V1_0
diff --git a/tv/cec/2.0/default/Android.bp b/tv/cec/2.0/default/Android.bp
index 6e624e3..d3d5342 100644
--- a/tv/cec/2.0/default/Android.bp
+++ b/tv/cec/2.0/default/Android.bp
@@ -7,7 +7,6 @@
shared_libs: [
"libhidlbase",
- "libhidltransport",
"liblog",
"libbase",
"libutils",
@@ -35,7 +34,6 @@
"libhardware_legacy",
"libhardware",
"libhidlbase",
- "libhidltransport",
"android.hardware.tv.cec@2.0",
],
diff --git a/tv/input/1.0/default/Android.bp b/tv/input/1.0/default/Android.bp
index 7c140a5..5f6b7e7 100644
--- a/tv/input/1.0/default/Android.bp
+++ b/tv/input/1.0/default/Android.bp
@@ -10,7 +10,6 @@
"liblog",
"libhardware",
"libhidlbase",
- "libhidltransport",
"libutils",
"android.hardware.audio.common@2.0",
"android.hardware.tv.input@1.0",
@@ -35,7 +34,6 @@
"libhardware_legacy",
"libhardware",
"libhidlbase",
- "libhidltransport",
"android.hardware.audio.common@2.0",
"android.hardware.tv.input@1.0",
],
diff --git a/tv/tuner/1.0/IDemux.hal b/tv/tuner/1.0/IDemux.hal
index 938bc44..e03095b 100644
--- a/tv/tuner/1.0/IDemux.hal
+++ b/tv/tuner/1.0/IDemux.hal
@@ -23,6 +23,153 @@
setFrontendDataSource(FrontendId frontendId) generates (Result result);
/**
+ * Add a filter to the demux
+ *
+ * It is used by the client to add a filter to the demux.
+ *
+ * @param type the type of the filter to be added.
+ * @param bufferSize the buffer size of the filter to be added. It's used to
+ * create a FMQ(Fast Message Queue) to hold data output from the filter.
+ * @param cb the callback for the filter to be used to send notifications
+ * back to the client.
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_STATE if failed for wrong state.
+ * UNKNOWN_ERROR if failed for other reasons.
+ * @return filterId the ID of the newly added filter.
+ */
+ addFilter(DemuxFilterType type, uint32_t bufferSize, IDemuxCallback cb)
+ generates (Result result, DemuxFilterId filterId);
+
+ /**
+ * Get the descriptor of the filter's FMQ
+ *
+ * It is used by the client to get the descriptor of the filter's Fast
+ * Message Queue. The data in FMQ is filtered out from MPEG transport
+ * stream. The data is origanized to data blocks which may have
+ * different length. The length's information of one or multiple data blocks
+ * is sent to client throught DemuxFilterEvent.
+ *
+ * @param filterId the ID of the filter.
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_ARGUMENT if failed for wrong filter ID.
+ * INVALID_STATE if failed for wrong state.
+ * UNKNOWN_ERROR if failed for other reasons.
+ * @return queue the descriptor of the filter's FMQ
+ */
+ getFilterQueueDesc(DemuxFilterId filterId)
+ generates (Result result, fmq_sync<uint8_t> queue);
+
+ /**
+ * Configure the filter.
+ *
+ * It is used by the client to configure the filter so that it can filter out
+ * intended data.
+ *
+ * @param filterId the ID of the filter.
+ * @param settings the settings of the filter.
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_ARGUMENT if failed for wrong filter ID.
+ * INVALID_STATE if failed for wrong state.
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ configureFilter(DemuxFilterId filterId, DemuxFilterSettings settings)
+ generates(Result result);
+
+ /**
+ * Start the filter.
+ *
+ * It is used by the client to ask the filter to start filterring data.
+ *
+ * @param filterId the ID of the filter.
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_ARGUMENT if failed for wrong filter ID.
+ * INVALID_STATE if failed for wrong state.
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ startFilter(DemuxFilterId filterId) generates (Result result);
+
+ /**
+ * Stop the filter.
+ *
+ * It is used by the client to ask the filter to stop filterring data.
+ * It won't discard the data already filtered out by the filter. The filter
+ * will be stopped and removed automatically if the demux is closed.
+ *
+ * @param filterId the ID of the filter.
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_ARGUMENT if failed for wrong filter ID.
+ * INVALID_STATE if failed for wrong state.
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ stopFilter(DemuxFilterId filterId) generates (Result result);
+
+ /**
+ * Flush the filter.
+ *
+ * It is used by the client to ask the filter to flush the data which is
+ * already produced but not consumed yet.
+ *
+ * @param filterId the ID of the filter.
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_ARGUMENT if failed for wrong filter ID.
+ * INVALID_STATE if failed for wrong state.
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ flushFilter(DemuxFilterId filterId) generates (Result result);
+
+ /**
+ * Remove a filter from the demux
+ *
+ * It is used by the client to remove a filter from the demux.
+ *
+ * @param filterId the ID of the removed filter.
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_ARGUMENT if failed for wrong filter ID.
+ * INVALID_STATE if failed for wrong state.
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ removeFilter(DemuxFilterId filterId) generates (Result result);
+
+ /**
+ * Get hardware sync ID for audio and video.
+ *
+ * It is used by the client to get the hardware sync ID for audio and video.
+ *
+ * @param filterId the ID of the filter.
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_ARGUMENT if failed for a wrong filter ID.
+ * UNKNOWN_ERROR if failed for other reasons.
+ * @return avSyncHwId the id of hardware A/V sync.
+ */
+ getAvSyncHwId(DemuxFilterId filterId)
+ generates (Result result, AvSyncHwId avSyncHwId);
+
+ /**
+ * Get current time stamp to use for A/V sync
+ *
+ * It is used by the client to get current time stamp for A/V sync. HW is
+ * supported to increment and maintain current time stamp.
+ *
+ * @param avSyncHwId the hardware id of A/V sync.
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_ARGUMENT if failed for a wrong hardware ID of A/V sync.
+ * UNKNOWN_ERROR if failed for other reasons.
+ * @return time the current time stamp of hardware A/V sync. The time stamp
+ * based on 90KHz has the same format as PTS (Presentation Time Stamp).
+ */
+ getAvSyncTime(AvSyncHwId avSyncHwId)
+ generates (Result result, uint64_t time);
+
+ /**
* Close the Demux instance
*
* It is used by the client to release the demux instance. HAL clear
@@ -33,5 +180,220 @@
* UNKNOWN_ERROR if failed for other reasons.
*/
close() generates (Result result);
-};
+ /**
+ * Add output to the demux
+ *
+ * It is used by the client to record output data from selected filters.
+ *
+ * @param bufferSize the buffer size of the output to be added. It's used to
+ * create a FMQ(Fast Message Queue) to hold data from selected filters.
+ * @param cb the callback for the demux to be used to send notifications
+ * back to the client.
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * OUT_OF_MEMORY if failed for not enough memory.
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ addOutput(uint32_t bufferSize, IDemuxCallback cb) generates (Result result);
+
+ /**
+ * Get the descriptor of the output's FMQ
+ *
+ * It is used by the client to get the descriptor of the output's Fast
+ * Message Queue. The data in FMQ is muxed packets output from selected
+ * filters. The packet's format is specifed by DemuxDataFormat in
+ * DemuxOutputSettings.
+ *
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * UNKNOWN_ERROR if failed for other reasons.
+ * @return queue the descriptor of the output's FMQ
+ */
+ getOutputQueueDesc() generates (Result result, fmq_sync<uint8_t> queue);
+
+ /**
+ * Configure the demux's output.
+ *
+ * It is used by the client to configure the demux's output for recording.
+ *
+ * @param settings the settings of the demux's output.
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_STATE if failed for wrong state.
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ configureOutput(DemuxOutputSettings settings) generates (Result result);
+
+ /**
+ * Attach one filter to the demux's output.
+ *
+ * It is used by the client to mux one filter's output to demux's output.
+ *
+ * @param filterId the ID of the attached filter.
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_STATE if failed for wrong state.
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ attachOutputTsFilter(DemuxFilterId filterId) generates (Result result);
+
+ /**
+ * Detach one filter from the demux's output.
+ *
+ * It is used by the client to remove one filter's output from demux's
+ * output.
+ *
+ * @param filterId the ID of the detached filter.
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_STATE if failed for wrong state.
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ detachOutputTsFilter(DemuxFilterId filterId) generates (Result result);
+
+ /**
+ * Start to take data to the demux's output.
+ *
+ * It is used by the client to ask the output to start to take data from
+ * attached filters.
+ *
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_STATE if failed for wrong state.
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ startOutput() generates (Result result);
+
+ /**
+ * Stop to take data to the demux's output.
+ *
+ * It is used by the client to ask the output to stop to take data from
+ * attached filters.
+ *
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_STATE if failed for wrong state.
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ stopOutput() generates (Result result);
+
+ /**
+ * Flush unconsumed data in the demux's output.
+ *
+ * It is used by the client to ask the demux to flush the data which is
+ * already produced but not consumed yet in the demux's output.
+ *
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_STATE if failed for wrong state.
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ flushOutput() generates (Result result);
+
+ /**
+ * Remove the demux's output.
+ *
+ * It is used by the client to remove the demux's output.
+ *
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_STATE if failed for wrong state.
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ removeOutput() generates (Result result);
+
+ /**
+ * Add input to the demux
+ *
+ * It is used by the client to add the demux's input for playback content.
+ *
+ * @param bufferSize the buffer size of the demux's input to be added.
+ * It's used to create a FMQ(Fast Message Queue) to hold input data.
+ * @param cb the callback for the demux to be used to send notifications
+ * back to the client.
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * OUT_OF_MEMORY if failed for not enough memory.
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ addInput(uint32_t bufferSize, IDemuxCallback cb) generates (Result result);
+
+ /**
+ * Get the descriptor of the input's FMQ
+ *
+ * It is used by the client to get the descriptor of the input's Fast
+ * Message Queue. The data in FMQ is fed by client. Data format is specifed
+ * by DemuxDataFormat in DemuxInputSettings.
+ *
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * UNKNOWN_ERROR if failed for other reasons.
+ * @return queue the descriptor of the output's FMQ
+ */
+ getInputQueueDesc() generates (Result result, fmq_sync<uint8_t> queue);
+
+ /**
+ * Configure the demux's input.
+ *
+ * It is used by the client to configure the demux's input for playback.
+ *
+ * @param settings the settings of the demux's input.
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_STATE if failed for wrong state.
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ configureInput(DemuxInputSettings settings) generates (Result result);
+
+ /**
+ * Start to consume the data from the demux's input.
+ *
+ * It is used by the client to ask the demux to start to consume data from
+ * the demux's input.
+ *
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_STATE if failed for wrong state.
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ startInput() generates (Result result);
+
+ /**
+ * Stop to consume the data from the demux's input.
+ *
+ * It is used by the client to ask the demux to stop to consume data from
+ * the demux's input.
+ *
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_STATE if failed for wrong state.
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ stopInput() generates (Result result);
+
+ /**
+ * Flush unconsumed data in the demux's input.
+ *
+ * It is used by the client to ask the demux to flush the data which is
+ * already produced but not consumed yet in the demux's input.
+ *
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_STATE if failed for wrong state.
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ flushInput() generates (Result result);
+
+ /**
+ * Remove the demux's input.
+ *
+ * It is used by the client to remove the demux's input.
+ *
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_STATE if failed for wrong state.
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ removeInput() generates (Result result);
+};
diff --git a/tv/tuner/1.0/IDemuxCallback.hal b/tv/tuner/1.0/IDemuxCallback.hal
index c67c5f2..55e8420 100644
--- a/tv/tuner/1.0/IDemuxCallback.hal
+++ b/tv/tuner/1.0/IDemuxCallback.hal
@@ -6,6 +6,28 @@
*
* @param filterEvent a demux filter event.
*/
- oneway onFilterEvent(DemuxFilterEvent filterEvent);
+ oneway onFilterEvent(DemuxFilterEvent filterEvent);
+
+ /**
+ * Notify the client a new status of a demux filter.
+ *
+ * @param filterId the demux filter ID.
+ * @param status a new status of the demux filter.
+ */
+ oneway onFilterStatus(DemuxFilterId filterId, DemuxFilterStatus status);
+
+ /**
+ * Notify the client a new status of the demux's output.
+ *
+ * @param status a new status of the demux's output.
+ */
+ oneway onOutputStatus(DemuxOutputStatus status);
+
+ /**
+ * Notify the client a new status of the demux's input.
+ *
+ * @param status a new status of the demux's input.
+ */
+ oneway onInputStatus(DemuxInputStatus status);
};
diff --git a/tv/tuner/1.0/IDescrambler.hal b/tv/tuner/1.0/IDescrambler.hal
index 4d6cf3c..d078657 100644
--- a/tv/tuner/1.0/IDescrambler.hal
+++ b/tv/tuner/1.0/IDescrambler.hal
@@ -1,11 +1,9 @@
package android.hardware.tv.tuner@1.0;
-
/**
* Descrambler is used to descramble input data.
*
*/
interface IDescrambler {
-
/**
* Set a demux as source of the descrambler
*
@@ -13,6 +11,7 @@
* descrambler. A descrambler instance can have only one source, and
* this method can be only called once.
*
+ * @param demuxId the id of the demux to be used as descrambler's source.
* @return result Result status of the operation.
* SUCCESS if successful,
* INVALID_STATE if failed for wrong state.
@@ -21,6 +20,51 @@
setDemuxSource(DemuxId demuxId) generates (Result result);
/**
+ * Set a key token to link descrambler to a key slot
+ *
+ * It is used by the client to link a hardware key slot to a descrambler.
+ * A descrambler instance can have only one key slot to link, but a key
+ * slot can hold a few keys for different purposes.
+ *
+ * @param keyToken the token to be used to link the key slot.
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_STATE if failed for wrong state.
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ setKeyToken(TunerKeyToken keyToken) generates (Result result);
+
+ /**
+ * Add packets' PID to the descrambler for descrambling
+ *
+ * It is used by the client to specify Package ID (PID) of packets which the
+ * descrambler start to descramble. Multiple PIDs can be added into one
+ * descrambler instance because descambling can happen simultaneously on
+ * packets from different PIDs.
+ *
+ * @param pid the PID of packets to start to be descrambled.
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_STATE if failed for wrong state.
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ addPid(DemuxTpid pid) generates (Result result);
+
+ /**
+ * Remove packets' PID from the descrambler
+ *
+ * It is used by the client to specify Package ID (PID) of packets which the
+ * descrambler stop to descramble.
+ *
+ * @param pid the PID of packets to stop to be descrambled.
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_STATE if failed for wrong state.
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ removePid(DemuxTpid pid) generates (Result result);
+
+ /**
* Release the descrambler instance
*
* It is used by the client to release the descrambler instance. HAL clear
@@ -30,6 +74,6 @@
* SUCCESS if successful,
* UNKNOWN_ERROR if failed for other reasons.
*/
- close() generates (Result result);
+ close() generates (Result result);
};
diff --git a/tv/tuner/1.0/ITuner.hal b/tv/tuner/1.0/ITuner.hal
index 61a9d63..a0f3e8e 100644
--- a/tv/tuner/1.0/ITuner.hal
+++ b/tv/tuner/1.0/ITuner.hal
@@ -42,6 +42,7 @@
*
* It is used by the client to create a frontend instance.
*
+ * @param frontendId the id of the frontend to be opened.
* @return result Result status of the operation.
* SUCCESS if successful,
* UNKNOWN_ERROR if creation failed for other reasons.
diff --git a/tv/tuner/1.0/default/Android.bp b/tv/tuner/1.0/default/Android.bp
index 21c9f1b..b211dd2 100644
--- a/tv/tuner/1.0/default/Android.bp
+++ b/tv/tuner/1.0/default/Android.bp
@@ -16,9 +16,10 @@
shared_libs: [
"android.hardware.tv.tuner@1.0",
"android.hidl.memory@1.0",
+ "libcutils",
+ "libfmq",
"libhidlbase",
"libhidlmemory",
- "libhidltransport",
"liblog",
"libstagefright_foundation",
"libutils",
diff --git a/tv/tuner/1.0/default/Demux.cpp b/tv/tuner/1.0/default/Demux.cpp
index 6f7c68b..889e42e 100644
--- a/tv/tuner/1.0/default/Demux.cpp
+++ b/tv/tuner/1.0/default/Demux.cpp
@@ -26,6 +26,47 @@
namespace V1_0 {
namespace implementation {
+#define WAIT_TIMEOUT 3000000000
+
+const std::vector<uint8_t> fakeDataInputBuffer{
+ 0x00, 0x00, 0x00, 0x01, 0x09, 0xf0, 0x00, 0x00, 0x00, 0x01, 0x67, 0x42, 0xc0, 0x1e, 0xdb,
+ 0x01, 0x40, 0x16, 0xec, 0x04, 0x40, 0x00, 0x00, 0x03, 0x00, 0x40, 0x00, 0x00, 0x0f, 0x03,
+ 0xc5, 0x8b, 0xb8, 0x00, 0x00, 0x00, 0x01, 0x68, 0xca, 0x8c, 0xb2, 0x00, 0x00, 0x01, 0x06,
+ 0x05, 0xff, 0xff, 0x70, 0xdc, 0x45, 0xe9, 0xbd, 0xe6, 0xd9, 0x48, 0xb7, 0x96, 0x2c, 0xd8,
+ 0x20, 0xd9, 0x23, 0xee, 0xef, 0x78, 0x32, 0x36, 0x34, 0x20, 0x2d, 0x20, 0x63, 0x6f, 0x72,
+ 0x65, 0x20, 0x31, 0x34, 0x32, 0x20, 0x2d, 0x20, 0x48, 0x2e, 0x32, 0x36, 0x34, 0x2f, 0x4d,
+ 0x50, 0x45, 0x47, 0x2d, 0x34, 0x20, 0x41, 0x56, 0x43, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x63,
+ 0x20, 0x2d, 0x20, 0x43, 0x6f, 0x70, 0x79, 0x6c, 0x65, 0x66, 0x74, 0x20, 0x32, 0x30, 0x30,
+ 0x33, 0x2d, 0x32, 0x30, 0x31, 0x34, 0x20, 0x2d, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
+ 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x6c, 0x61, 0x6e, 0x2e, 0x6f,
+ 0x72, 0x67, 0x2f, 0x78, 0x32, 0x36, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20, 0x2d, 0x20,
+ 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x20, 0x63, 0x61, 0x62, 0x61, 0x63, 0x3d,
+ 0x30, 0x20, 0x72, 0x65, 0x66, 0x3d, 0x32, 0x20, 0x64, 0x65, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
+ 0x3d, 0x31, 0x3a, 0x30, 0x3a, 0x30, 0x20, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x65, 0x3d,
+ 0x30, 0x78, 0x31, 0x3a, 0x30, 0x78, 0x31, 0x31, 0x31, 0x20, 0x6d, 0x65, 0x3d, 0x68, 0x65,
+ 0x78, 0x20, 0x73, 0x75, 0x62, 0x6d, 0x65, 0x3d, 0x37, 0x20, 0x70, 0x73, 0x79, 0x3d, 0x31,
+ 0x20, 0x70, 0x73, 0x79, 0x5f, 0x72, 0x64, 0x3d, 0x31, 0x2e, 0x30, 0x30, 0x3a, 0x30, 0x2e,
+ 0x30, 0x30, 0x20, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x3d, 0x31, 0x20,
+ 0x6d, 0x65, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x3d, 0x31, 0x36, 0x20, 0x63, 0x68, 0x72,
+ 0x6f, 0x6d, 0x61, 0x5f, 0x6d, 0x65, 0x3d, 0x31, 0x20, 0x74, 0x72, 0x65, 0x6c, 0x6c, 0x69,
+ 0x73, 0x3d, 0x31, 0x20, 0x38, 0x78, 0x38, 0x64, 0x63, 0x74, 0x3d, 0x30, 0x20, 0x63, 0x71,
+ 0x6d, 0x3d, 0x30, 0x20, 0x64, 0x65, 0x61, 0x64, 0x7a, 0x6f, 0x6e, 0x65, 0x3d, 0x32, 0x31,
+ 0x2c, 0x31, 0x31, 0x20, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x73, 0x6b, 0x69, 0x70, 0x3d,
+ 0x31, 0x20, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x61, 0x5f, 0x71, 0x70, 0x5f, 0x6f, 0x66, 0x66,
+ 0x73, 0x65, 0x74, 0x3d, 0x2d, 0x32, 0x20, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x3d,
+ 0x36, 0x30, 0x20, 0x6c, 0x6f, 0x6f, 0x6b, 0x61, 0x68, 0x65, 0x61, 0x64, 0x5f, 0x74, 0x68,
+ 0x72, 0x65, 0x61, 0x64, 0x73, 0x3d, 0x35, 0x20, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x64, 0x5f,
+ 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x3d, 0x30, 0x20, 0x6e, 0x72, 0x3d, 0x30, 0x20,
+ 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x3d, 0x31, 0x20, 0x69, 0x6e, 0x74, 0x65,
+ 0x72, 0x6c, 0x61, 0x63, 0x65, 0x64, 0x3d, 0x30, 0x20, 0x62, 0x6c, 0x75, 0x72, 0x61, 0x79,
+ 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x3d, 0x30, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74,
+ 0x72, 0x61, 0x69, 0x6e, 0x65, 0x64, 0x5f, 0x69, 0x6e, 0x74, 0x72, 0x61, 0x3d, 0x30, 0x20,
+ 0x62, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x3d, 0x30, 0x20, 0x77, 0x65, 0x69, 0x67, 0x68,
+ 0x74, 0x70, 0x3d, 0x30, 0x20, 0x6b, 0x65, 0x79, 0x69, 0x6e, 0x74, 0x3d, 0x32, 0x35, 0x30,
+ 0x20, 0x6b, 0x65, 0x79, 0x69, 0x6e, 0x74, 0x5f, 0x6d, 0x69, 0x6e, 0x3d, 0x32, 0x35, 0x20,
+ 0x73, 0x63, 0x65, 0x6e, 0x65,
+};
+
Demux::Demux(uint32_t demuxId) {
mDemuxId = demuxId;
}
@@ -40,11 +81,586 @@
return Result::SUCCESS;
}
-Return<Result> Demux::close() {
+Return<void> Demux::addFilter(DemuxFilterType type, uint32_t bufferSize,
+ const sp<IDemuxCallback>& cb, addFilter_cb _hidl_cb) {
+ ALOGV("%s", __FUNCTION__);
+
+ uint32_t filterId;
+
+ if (!mUnusedFilterIds.empty()) {
+ filterId = *mUnusedFilterIds.begin();
+
+ mUnusedFilterIds.erase(filterId);
+ } else {
+ filterId = ++mLastUsedFilterId;
+
+ mDemuxCallbacks.resize(filterId + 1);
+ mFilterMQs.resize(filterId + 1);
+ mFilterEvents.resize(filterId + 1);
+ mFilterEventFlags.resize(filterId + 1);
+ mFilterThreadRunning.resize(filterId + 1);
+ mFilterThreads.resize(filterId + 1);
+ }
+
+ mUsedFilterIds.insert(filterId);
+
+ if ((type != DemuxFilterType::PCR || type != DemuxFilterType::TS) && cb == nullptr) {
+ ALOGW("callback can't be null");
+ _hidl_cb(Result::INVALID_ARGUMENT, filterId);
+ return Void();
+ }
+
+ // Add callback
+ mDemuxCallbacks[filterId] = cb;
+
+ // Mapping from the filter ID to the filter event
+ DemuxFilterEvent event{
+ .filterId = filterId,
+ .filterType = type,
+ };
+ mFilterEvents[filterId] = event;
+
+ if (!createFilterMQ(bufferSize, filterId)) {
+ _hidl_cb(Result::UNKNOWN_ERROR, -1);
+ return Void();
+ }
+
+ _hidl_cb(Result::SUCCESS, filterId);
+ return Void();
+}
+
+Return<void> Demux::getFilterQueueDesc(uint32_t filterId, getFilterQueueDesc_cb _hidl_cb) {
+ ALOGV("%s", __FUNCTION__);
+
+ if (mUsedFilterIds.find(filterId) == mUsedFilterIds.end()) {
+ ALOGW("No filter with id: %d exists to get desc", filterId);
+ _hidl_cb(Result::INVALID_ARGUMENT, FilterMQ::Descriptor());
+ return Void();
+ }
+
+ _hidl_cb(Result::SUCCESS, *mFilterMQs[filterId]->getDesc());
+ return Void();
+}
+
+Return<Result> Demux::configureFilter(uint32_t /* filterId */,
+ const DemuxFilterSettings& /* settings */) {
ALOGV("%s", __FUNCTION__);
return Result::SUCCESS;
- ;
+}
+
+Return<Result> Demux::startFilter(uint32_t filterId) {
+ ALOGV("%s", __FUNCTION__);
+ Result result;
+
+ if (mUsedFilterIds.find(filterId) == mUsedFilterIds.end()) {
+ ALOGW("No filter with id: %d exists to start filter", filterId);
+ return Result::INVALID_ARGUMENT;
+ }
+
+ switch (mFilterEvents[filterId].filterType) {
+ case DemuxFilterType::SECTION:
+ result = startFilterLoop(filterId);
+ break;
+ case DemuxFilterType::PES:
+ result = startPesFilterHandler(filterId);
+ break;
+ case DemuxFilterType::TS:
+ result = startTsFilterHandler();
+ return Result::SUCCESS;
+ case DemuxFilterType::AUDIO:
+ case DemuxFilterType::VIDEO:
+ result = startMediaFilterHandler(filterId);
+ break;
+ case DemuxFilterType::RECORD:
+ result = startRecordFilterHandler(filterId);
+ break;
+ case DemuxFilterType::PCR:
+ result = startPcrFilterHandler();
+ return Result::SUCCESS;
+ default:
+ return Result::UNKNOWN_ERROR;
+ }
+
+ return result;
+}
+
+Return<Result> Demux::stopFilter(uint32_t /* filterId */) {
+ ALOGV("%s", __FUNCTION__);
+
+ return Result::SUCCESS;
+}
+
+Return<Result> Demux::flushFilter(uint32_t /* filterId */) {
+ ALOGV("%s", __FUNCTION__);
+
+ return Result::SUCCESS;
+}
+
+Return<Result> Demux::removeFilter(uint32_t filterId) {
+ ALOGV("%s", __FUNCTION__);
+
+ // resetFilterRecords(filterId);
+ mUsedFilterIds.erase(filterId);
+ mUnusedFilterIds.insert(filterId);
+
+ return Result::SUCCESS;
+}
+
+Return<void> Demux::getAvSyncHwId(uint32_t /* filterId */, getAvSyncHwId_cb _hidl_cb) {
+ ALOGV("%s", __FUNCTION__);
+
+ AvSyncHwId avSyncHwId = 0;
+
+ _hidl_cb(Result::SUCCESS, avSyncHwId);
+ return Void();
+}
+
+Return<void> Demux::getAvSyncTime(AvSyncHwId /* avSyncHwId */, getAvSyncTime_cb _hidl_cb) {
+ ALOGV("%s", __FUNCTION__);
+
+ uint64_t avSyncTime = 0;
+
+ _hidl_cb(Result::SUCCESS, avSyncTime);
+ return Void();
+}
+
+Return<Result> Demux::close() {
+ ALOGV("%s", __FUNCTION__);
+
+ set<uint32_t>::iterator it;
+ mInputThread = 0;
+ mOutputThread = 0;
+ mFilterThreads.clear();
+ mUnusedFilterIds.clear();
+ mUsedFilterIds.clear();
+ mDemuxCallbacks.clear();
+ mFilterMQs.clear();
+ mFilterEvents.clear();
+ mFilterEventFlags.clear();
+ mLastUsedFilterId = -1;
+
+ return Result::SUCCESS;
+}
+
+Return<Result> Demux::addOutput(uint32_t bufferSize, const sp<IDemuxCallback>& cb) {
+ ALOGV("%s", __FUNCTION__);
+
+ // Create a synchronized FMQ that supports blocking read/write
+ std::unique_ptr<FilterMQ> tmpFilterMQ =
+ std::unique_ptr<FilterMQ>(new (std::nothrow) FilterMQ(bufferSize, true));
+ if (!tmpFilterMQ->isValid()) {
+ ALOGW("Failed to create output FMQ");
+ return Result::UNKNOWN_ERROR;
+ }
+
+ mOutputMQ = std::move(tmpFilterMQ);
+
+ if (EventFlag::createEventFlag(mOutputMQ->getEventFlagWord(), &mOutputEventFlag) != OK) {
+ return Result::UNKNOWN_ERROR;
+ }
+
+ mOutputCallback = cb;
+
+ return Result::SUCCESS;
+}
+
+Return<void> Demux::getOutputQueueDesc(getOutputQueueDesc_cb _hidl_cb) {
+ ALOGV("%s", __FUNCTION__);
+
+ if (!mOutputMQ) {
+ _hidl_cb(Result::NOT_INITIALIZED, FilterMQ::Descriptor());
+ return Void();
+ }
+
+ _hidl_cb(Result::SUCCESS, *mOutputMQ->getDesc());
+ return Void();
+}
+
+Return<Result> Demux::configureOutput(const DemuxOutputSettings& /* settings */) {
+ ALOGV("%s", __FUNCTION__);
+
+ return Result::SUCCESS;
+}
+
+Return<Result> Demux::attachOutputTsFilter(uint32_t /*filterId*/) {
+ ALOGV("%s", __FUNCTION__);
+
+ return Result::SUCCESS;
+}
+
+Return<Result> Demux::detachOutputTsFilter(uint32_t /* filterId */) {
+ ALOGV("%s", __FUNCTION__);
+
+ return Result::SUCCESS;
+}
+
+Return<Result> Demux::startOutput() {
+ ALOGV("%s", __FUNCTION__);
+
+ return Result::SUCCESS;
+}
+
+Return<Result> Demux::stopOutput() {
+ ALOGV("%s", __FUNCTION__);
+
+ return Result::SUCCESS;
+}
+
+Return<Result> Demux::flushOutput() {
+ ALOGV("%s", __FUNCTION__);
+
+ return Result::SUCCESS;
+}
+
+Return<Result> Demux::removeOutput() {
+ ALOGV("%s", __FUNCTION__);
+
+ return Result::SUCCESS;
+}
+
+Return<Result> Demux::addInput(uint32_t bufferSize, const sp<IDemuxCallback>& cb) {
+ ALOGV("%s", __FUNCTION__);
+
+ // Create a synchronized FMQ that supports blocking read/write
+ std::unique_ptr<FilterMQ> tmpInputMQ =
+ std::unique_ptr<FilterMQ>(new (std::nothrow) FilterMQ(bufferSize, true));
+ if (!tmpInputMQ->isValid()) {
+ ALOGW("Failed to create input FMQ");
+ return Result::UNKNOWN_ERROR;
+ }
+
+ mInputMQ = std::move(tmpInputMQ);
+
+ if (EventFlag::createEventFlag(mInputMQ->getEventFlagWord(), &mInputEventFlag) != OK) {
+ return Result::UNKNOWN_ERROR;
+ }
+
+ mInputCallback = cb;
+
+ return Result::SUCCESS;
+}
+
+Return<void> Demux::getInputQueueDesc(getInputQueueDesc_cb _hidl_cb) {
+ ALOGV("%s", __FUNCTION__);
+
+ if (!mInputMQ) {
+ _hidl_cb(Result::NOT_INITIALIZED, FilterMQ::Descriptor());
+ return Void();
+ }
+
+ _hidl_cb(Result::SUCCESS, *mInputMQ->getDesc());
+ return Void();
+}
+
+Return<Result> Demux::configureInput(const DemuxInputSettings& /* settings */) {
+ ALOGV("%s", __FUNCTION__);
+
+ return Result::SUCCESS;
+}
+
+Return<Result> Demux::startInput() {
+ ALOGV("%s", __FUNCTION__);
+
+ pthread_create(&mInputThread, NULL, __threadLoopInput, this);
+ pthread_setname_np(mInputThread, "demux_input_waiting_loop");
+
+ // TODO start another thread to send filter status callback to the framework
+
+ return Result::SUCCESS;
+}
+
+Return<Result> Demux::stopInput() {
+ ALOGV("%s", __FUNCTION__);
+
+ return Result::SUCCESS;
+}
+
+Return<Result> Demux::flushInput() {
+ ALOGV("%s", __FUNCTION__);
+
+ return Result::SUCCESS;
+}
+
+Return<Result> Demux::removeInput() {
+ ALOGV("%s", __FUNCTION__);
+
+ mInputMQ = nullptr;
+
+ return Result::SUCCESS;
+}
+
+Result Demux::startFilterLoop(uint32_t filterId) {
+ struct ThreadArgs* threadArgs = (struct ThreadArgs*)malloc(sizeof(struct ThreadArgs));
+ threadArgs->user = this;
+ threadArgs->filterId = filterId;
+
+ pthread_t mFilterThread;
+ pthread_create(&mFilterThread, NULL, __threadLoopFilter, (void*)threadArgs);
+ mFilterThreads[filterId] = mFilterThread;
+ pthread_setname_np(mFilterThread, "demux_filter_waiting_loop");
+
+ return Result::SUCCESS;
+}
+
+Result Demux::startSectionFilterHandler(uint32_t filterId, vector<uint8_t> data) {
+ if (!writeSectionsAndCreateEvent(filterId, data)) {
+ ALOGD("[Demux] filter %d fails to write into FMQ. Ending thread", filterId);
+ return Result::UNKNOWN_ERROR;
+ }
+
+ return Result::SUCCESS;
+}
+
+Result Demux::startPesFilterHandler(uint32_t filterId) {
+ // TODO generate multiple events in one event callback
+ DemuxFilterPesEvent pesEvent;
+ pesEvent = {
+ // temp dump meta data
+ .streamId = 0,
+ .dataLength = 530,
+ };
+ mFilterEvents[filterId].events.resize(1);
+ mFilterEvents[filterId].events[0].pes(pesEvent);
+ /*pthread_create(&mThreadId, NULL, __threadLoop, this);
+ pthread_setname_np(mThreadId, "demux_section_filter_waiting_loop");*/
+ if (!writeDataToFilterMQ(fakeDataInputBuffer, filterId)) {
+ return Result::INVALID_STATE;
+ }
+
+ if (mDemuxCallbacks[filterId] == nullptr) {
+ return Result::NOT_INITIALIZED;
+ }
+
+ mDemuxCallbacks[filterId]->onFilterEvent(mFilterEvents[filterId]);
+ return Result::SUCCESS;
+}
+
+Result Demux::startTsFilterHandler() {
+ // TODO handle starting TS filter
+ return Result::SUCCESS;
+}
+
+Result Demux::startMediaFilterHandler(uint32_t filterId) {
+ DemuxFilterMediaEvent mediaEvent;
+ mediaEvent = {
+ // temp dump meta data
+ .pts = 0,
+ .dataLength = 530,
+ .secureMemory = nullptr,
+ };
+ mFilterEvents[filterId].events.resize(1);
+ mFilterEvents[filterId].events[0].media() = mediaEvent;
+ // TODO handle write FQM for media stream
+ return Result::SUCCESS;
+}
+
+Result Demux::startRecordFilterHandler(uint32_t filterId) {
+ DemuxFilterRecordEvent recordEvent;
+ recordEvent = {
+ // temp dump meta data
+ .tpid = 0,
+ .packetNum = 0,
+ };
+ recordEvent.indexMask.tsIndexMask() = 0x01;
+ mFilterEvents[filterId].events.resize(1);
+ mFilterEvents[filterId].events[0].ts() = recordEvent;
+ return Result::SUCCESS;
+}
+
+Result Demux::startPcrFilterHandler() {
+ // TODO handle starting PCR filter
+ return Result::SUCCESS;
+}
+
+bool Demux::createFilterMQ(uint32_t bufferSize, uint32_t filterId) {
+ ALOGV("%s", __FUNCTION__);
+
+ // Create a synchronized FMQ that supports blocking read/write
+ std::unique_ptr<FilterMQ> tmpFilterMQ =
+ std::unique_ptr<FilterMQ>(new (std::nothrow) FilterMQ(bufferSize, true));
+ if (!tmpFilterMQ->isValid()) {
+ ALOGW("Failed to create FMQ of filter with id: %d", filterId);
+ return false;
+ }
+
+ mFilterMQs[filterId] = std::move(tmpFilterMQ);
+
+ EventFlag* filterEventFlag;
+ if (EventFlag::createEventFlag(mFilterMQs[filterId]->getEventFlagWord(), &filterEventFlag) !=
+ OK) {
+ return false;
+ }
+ mFilterEventFlags[filterId] = filterEventFlag;
+
+ return true;
+}
+
+bool Demux::writeSectionsAndCreateEvent(uint32_t filterId, vector<uint8_t> data) {
+ // TODO check how many sections has been read
+ std::lock_guard<std::mutex> lock(mFilterEventLock);
+ int size = mFilterEvents[filterId].events.size();
+ mFilterEvents[filterId].events.resize(size + 1);
+ if (!writeDataToFilterMQ(data, filterId)) {
+ return false;
+ }
+ DemuxFilterSectionEvent secEvent;
+ secEvent = {
+ // temp dump meta data
+ .tableId = 0,
+ .version = 1,
+ .sectionNum = 1,
+ .dataLength = 530,
+ };
+ mFilterEvents[filterId].events[size].section(secEvent);
+ return true;
+}
+
+bool Demux::writeDataToFilterMQ(const std::vector<uint8_t>& data, uint32_t filterId) {
+ std::lock_guard<std::mutex> lock(mWriteLock);
+ if (mFilterMQs[filterId]->write(data.data(), data.size())) {
+ return true;
+ }
+ return false;
+}
+
+bool Demux::filterAndOutputData() {
+ ALOGD("[Demux] start to dispatch data to filters");
+ // Read input data from the input FMQ
+ int size = mInputMQ->availableToRead();
+ vector<uint8_t> dataOutputBuffer;
+ dataOutputBuffer.resize(size);
+ mInputMQ->read(dataOutputBuffer.data(), size);
+
+ Result result;
+ // Filter the data and feed the output to each filter
+ set<uint32_t>::iterator it;
+ for (it = mUsedFilterIds.begin(); it != mUsedFilterIds.end(); it++) {
+ switch (mFilterEvents[*it].filterType) {
+ case DemuxFilterType::SECTION:
+ result = startSectionFilterHandler(*it, dataOutputBuffer);
+ break;
+ case DemuxFilterType::PES:
+ result = startPesFilterHandler(*it);
+ break;
+ case DemuxFilterType::TS:
+ result = startTsFilterHandler();
+ break;
+ case DemuxFilterType::AUDIO:
+ case DemuxFilterType::VIDEO:
+ result = startMediaFilterHandler(*it);
+ break;
+ case DemuxFilterType::RECORD:
+ result = startRecordFilterHandler(*it);
+ break;
+ case DemuxFilterType::PCR:
+ result = startPcrFilterHandler();
+ break;
+ default:
+ return false;
+ }
+ }
+
+ return result == Result::SUCCESS;
+}
+
+void* Demux::__threadLoopFilter(void* threadArg) {
+ Demux* const self = static_cast<Demux*>(((struct ThreadArgs*)threadArg)->user);
+ self->filterThreadLoop(((struct ThreadArgs*)threadArg)->filterId);
+ return 0;
+}
+
+void* Demux::__threadLoopInput(void* user) {
+ Demux* const self = static_cast<Demux*>(user);
+ self->inputThreadLoop();
+ return 0;
+}
+
+void Demux::filterThreadLoop(uint32_t filterId) {
+ ALOGD("[Demux] filter %d threadLoop start.", filterId);
+ mFilterThreadRunning[filterId] = true;
+
+ // For the first time of filter output, implementation needs to send the filter
+ // Event Callback without waiting for the DATA_CONSUMED to init the process.
+ while (mFilterThreadRunning[filterId]) {
+ if (mFilterEvents[filterId].events.size() == 0) {
+ ALOGD("[Demux] wait for filter data output.");
+ usleep(1000 * 1000);
+ continue;
+ }
+ // After successfully write, send a callback and wait for the read to be done
+ mDemuxCallbacks[filterId]->onFilterEvent(mFilterEvents[filterId]);
+ mFilterEvents[filterId].events.resize(0);
+ break;
+ }
+
+ while (mFilterThreadRunning[filterId]) {
+ uint32_t efState = 0;
+ // We do not wait for the last round of writen data to be read to finish the thread
+ // because the VTS can verify the reading itself.
+ for (int i = 0; i < SECTION_WRITE_COUNT; i++) {
+ while (mFilterThreadRunning[filterId]) {
+ status_t status = mFilterEventFlags[filterId]->wait(
+ static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_CONSUMED), &efState,
+ WAIT_TIMEOUT, true /* retry on spurious wake */);
+ if (status != OK) {
+ ALOGD("[Demux] wait for data consumed");
+ continue;
+ }
+ break;
+ }
+
+ if (mDemuxCallbacks[filterId] == nullptr) {
+ ALOGD("[Demux] filter %d does not hava callback. Ending thread", filterId);
+ break;
+ }
+
+ while (mFilterThreadRunning[filterId]) {
+ std::lock_guard<std::mutex> lock(mFilterEventLock);
+ if (mFilterEvents[filterId].events.size() == 0) {
+ continue;
+ }
+ // After successfully write, send a callback and wait for the read to be done
+ mDemuxCallbacks[filterId]->onFilterEvent(mFilterEvents[filterId]);
+ mFilterEvents[filterId].events.resize(0);
+ break;
+ }
+ // We do not wait for the last read to be done
+ // VTS can verify the read result itself.
+ if (i == SECTION_WRITE_COUNT - 1) {
+ ALOGD("[Demux] filter %d writing done. Ending thread", filterId);
+ break;
+ }
+ }
+ mFilterThreadRunning[filterId] = false;
+ }
+
+ ALOGD("[Demux] filter thread ended.");
+}
+
+void Demux::inputThreadLoop() {
+ ALOGD("[Demux] input threadLoop start.");
+ mInputThreadRunning = true;
+
+ while (mInputThreadRunning) {
+ uint32_t efState = 0;
+ status_t status =
+ mInputEventFlag->wait(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_READY),
+ &efState, WAIT_TIMEOUT, true /* retry on spurious wake */);
+ if (status != OK) {
+ ALOGD("[Demux] wait for data ready on the input FMQ");
+ continue;
+ }
+ // Our current implementation filter the data and write it into the filter FMQ immedaitely
+ // after the DATA_READY from the VTS/framework
+ if (!filterAndOutputData()) {
+ ALOGD("[Demux] input data failed to be filtered. Ending thread");
+ break;
+ }
+ }
+
+ mInputThreadRunning = false;
+ ALOGD("[Demux] input thread ended.");
}
} // namespace implementation
diff --git a/tv/tuner/1.0/default/Demux.h b/tv/tuner/1.0/default/Demux.h
index 52f3933..2fdde8d 100644
--- a/tv/tuner/1.0/default/Demux.h
+++ b/tv/tuner/1.0/default/Demux.h
@@ -18,6 +18,8 @@
#define ANDROID_HARDWARE_TV_TUNER_V1_0_DEMUX_H_
#include <android/hardware/tv/tuner/1.0/IDemux.h>
+#include <fmq/MessageQueue.h>
+#include <set>
using namespace std;
@@ -28,21 +30,180 @@
namespace V1_0 {
namespace implementation {
+using ::android::hardware::EventFlag;
+using ::android::hardware::kSynchronizedReadWrite;
+using ::android::hardware::MessageQueue;
+using ::android::hardware::MQDescriptorSync;
using ::android::hardware::tv::tuner::V1_0::IDemux;
+using ::android::hardware::tv::tuner::V1_0::IDemuxCallback;
using ::android::hardware::tv::tuner::V1_0::Result;
+using FilterMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
+
class Demux : public IDemux {
public:
Demux(uint32_t demuxId);
+ ~Demux();
+
virtual Return<Result> setFrontendDataSource(uint32_t frontendId) override;
virtual Return<Result> close() override;
+ virtual Return<void> addFilter(DemuxFilterType type, uint32_t bufferSize,
+ const sp<IDemuxCallback>& cb, addFilter_cb _hidl_cb) override;
+
+ virtual Return<void> getFilterQueueDesc(uint32_t filterId,
+ getFilterQueueDesc_cb _hidl_cb) override;
+
+ virtual Return<Result> configureFilter(uint32_t filterId,
+ const DemuxFilterSettings& settings) override;
+
+ virtual Return<Result> startFilter(uint32_t filterId) override;
+
+ virtual Return<Result> stopFilter(uint32_t filterId) override;
+
+ virtual Return<Result> flushFilter(uint32_t filterId) override;
+
+ virtual Return<Result> removeFilter(uint32_t filterId) override;
+
+ virtual Return<void> getAvSyncHwId(uint32_t filterId, getAvSyncHwId_cb _hidl_cb) override;
+
+ virtual Return<void> getAvSyncTime(AvSyncHwId avSyncHwId, getAvSyncTime_cb _hidl_cb) override;
+
+ virtual Return<Result> addInput(uint32_t bufferSize, const sp<IDemuxCallback>& cb) override;
+
+ virtual Return<void> getInputQueueDesc(getInputQueueDesc_cb _hidl_cb) override;
+
+ virtual Return<Result> configureInput(const DemuxInputSettings& settings) override;
+
+ virtual Return<Result> startInput() override;
+
+ virtual Return<Result> stopInput() override;
+
+ virtual Return<Result> flushInput() override;
+
+ virtual Return<Result> removeInput() override;
+
+ virtual Return<Result> addOutput(uint32_t bufferSize, const sp<IDemuxCallback>& cb) override;
+
+ virtual Return<void> getOutputQueueDesc(getOutputQueueDesc_cb _hidl_cb) override;
+
+ virtual Return<Result> configureOutput(const DemuxOutputSettings& settings) override;
+
+ virtual Return<Result> attachOutputTsFilter(uint32_t filterId) override;
+
+ virtual Return<Result> detachOutputTsFilter(uint32_t filterId) override;
+
+ virtual Return<Result> startOutput() override;
+
+ virtual Return<Result> stopOutput() override;
+
+ virtual Return<Result> flushOutput() override;
+
+ virtual Return<Result> removeOutput() override;
+
private:
- virtual ~Demux();
+ // A struct that passes the arguments to a newly created filter thread
+ struct ThreadArgs {
+ Demux* user;
+ uint32_t filterId;
+ };
+
+ /**
+ * Filter handlers to handle the data filtering.
+ * They are also responsible to write the filtered output into the filter FMQ
+ * and update the filterEvent bound with the same filterId.
+ */
+ Result startSectionFilterHandler(uint32_t filterId, vector<uint8_t> data);
+ Result startPesFilterHandler(uint32_t filterId);
+ Result startTsFilterHandler();
+ Result startMediaFilterHandler(uint32_t filterId);
+ Result startRecordFilterHandler(uint32_t filterId);
+ Result startPcrFilterHandler();
+ Result startFilterLoop(uint32_t filterId);
+
+ /**
+ * To create a FilterMQ with the the next available Filter ID.
+ * Creating Event Flag at the same time.
+ * Add the successfully created/saved FilterMQ into the local list.
+ *
+ * Return false is any of the above processes fails.
+ */
+ bool createFilterMQ(uint32_t bufferSize, uint32_t filterId);
+ bool createMQ(FilterMQ* queue, EventFlag* eventFlag, uint32_t bufferSize);
+ void deleteEventFlag();
+ bool writeDataToFilterMQ(const std::vector<uint8_t>& data, uint32_t filterId);
+ bool readDataFromMQ();
+ bool writeSectionsAndCreateEvent(uint32_t filterId, vector<uint8_t> data);
+ /**
+ * A dispatcher to read and dispatch input data to all the started filters.
+ * Each filter handler handles the data filtering/output writing/filterEvent updating.
+ */
+ bool filterAndOutputData();
+ static void* __threadLoopFilter(void* data);
+ static void* __threadLoopInput(void* user);
+ void filterThreadLoop(uint32_t filterId);
+ void inputThreadLoop();
+
uint32_t mDemuxId;
uint32_t mSourceFrontendId;
+ /**
+ * Record the last used filter id. Initial value is -1.
+ * Filter Id starts with 0.
+ */
+ uint32_t mLastUsedFilterId = -1;
+ /**
+ * Record all the used filter Ids.
+ * Any removed filter id should be removed from this set.
+ */
+ set<uint32_t> mUsedFilterIds;
+ /**
+ * Record all the unused filter Ids within mLastUsedFilterId.
+ * Removed filter Id should be added into this set.
+ * When this set is not empty, ids here should be allocated first
+ * and added into usedFilterIds.
+ */
+ set<uint32_t> mUnusedFilterIds;
+ /**
+ * A list of created FilterMQ ptrs.
+ * The array number is the filter ID.
+ */
+ vector<unique_ptr<FilterMQ>> mFilterMQs;
+ vector<EventFlag*> mFilterEventFlags;
+ vector<DemuxFilterEvent> mFilterEvents;
+ unique_ptr<FilterMQ> mInputMQ;
+ unique_ptr<FilterMQ> mOutputMQ;
+ EventFlag* mInputEventFlag;
+ EventFlag* mOutputEventFlag;
+ /**
+ * Demux callbacks used on filter events or IO buffer status
+ */
+ vector<sp<IDemuxCallback>> mDemuxCallbacks;
+ sp<IDemuxCallback> mInputCallback;
+ sp<IDemuxCallback> mOutputCallback;
+ // Thread handlers
+ pthread_t mInputThread;
+ pthread_t mOutputThread;
+ vector<pthread_t> mFilterThreads;
+ /**
+ * If a specific filter's writing loop is still running
+ */
+ vector<bool> mFilterThreadRunning;
+ bool mInputThreadRunning;
+ /**
+ * Lock to protect writes to the FMQs
+ */
+ std::mutex mWriteLock;
+ /**
+ * Lock to protect writes to the filter event
+ */
+ std::mutex mFilterEventLock;
+ /**
+ * How many times a filter should write
+ * TODO make this dynamic/random/can take as a parameter
+ */
+ const uint16_t SECTION_WRITE_COUNT = 10;
};
} // namespace implementation
diff --git a/tv/tuner/1.0/default/Descrambler.cpp b/tv/tuner/1.0/default/Descrambler.cpp
index 1af1a2c..085f2c8 100644
--- a/tv/tuner/1.0/default/Descrambler.cpp
+++ b/tv/tuner/1.0/default/Descrambler.cpp
@@ -44,6 +44,24 @@
return Result::SUCCESS;
}
+Return<Result> Descrambler::setKeyToken(const hidl_vec<uint8_t>& /* keyToken */) {
+ ALOGV("%s", __FUNCTION__);
+
+ return Result::SUCCESS;
+}
+
+Return<Result> Descrambler::addPid(uint16_t /* pid */) {
+ ALOGV("%s", __FUNCTION__);
+
+ return Result::SUCCESS;
+}
+
+Return<Result> Descrambler::removePid(uint16_t /* pid */) {
+ ALOGV("%s", __FUNCTION__);
+
+ return Result::SUCCESS;
+}
+
Return<Result> Descrambler::close() {
ALOGV("%s", __FUNCTION__);
mDemuxSet = false;
diff --git a/tv/tuner/1.0/default/Descrambler.h b/tv/tuner/1.0/default/Descrambler.h
index 2ec8412..436adcf 100644
--- a/tv/tuner/1.0/default/Descrambler.h
+++ b/tv/tuner/1.0/default/Descrambler.h
@@ -38,6 +38,12 @@
virtual Return<Result> setDemuxSource(uint32_t demuxId) override;
+ virtual Return<Result> setKeyToken(const hidl_vec<uint8_t>& keyToken) override;
+
+ virtual Return<Result> addPid(uint16_t pid) override;
+
+ virtual Return<Result> removePid(uint16_t pid) override;
+
virtual Return<Result> close() override;
private:
diff --git a/tv/tuner/1.0/types.hal b/tv/tuner/1.0/types.hal
index 3fa9641..77f7ead 100644
--- a/tv/tuner/1.0/types.hal
+++ b/tv/tuner/1.0/types.hal
@@ -90,10 +90,10 @@
};
/**
- * Signal Setting for ATSC Frontend.
+ * Signal Settings for an ATSC Frontend.
*/
struct FrontendAtscSettings {
- /** Signal frequencey in Herhz */
+ /** Signal frequency in Hertz */
uint32_t frequency;
FrontendAtscModulation modulation;
};
@@ -102,7 +102,7 @@
* Signal Setting for DVBT Frontend.
*/
struct FrontendDvbtSettings {
- /** Signal frequencey in Herhz */
+ /** Signal frequency in Hertz */
uint32_t frequency;
FrontendAtscModulation modulation;
FrontendInnerFec fec;
@@ -170,7 +170,7 @@
*/
VIDEO,
/**
- * A filter to set PCR channel from input stream.
+ * A filter to set PCR (Program Clock Reference) channel from input stream.
*/
PCR,
/**
@@ -179,11 +179,399 @@
RECORD,
};
+/* Packet ID is used to specify packets in transport stream. */
+typedef uint16_t DemuxTpid;
+
+@export
+enum Constant : uint16_t {
+ /**
+ * An invalid packet ID in transport stream according to ISO/IEC 13818-1.
+ */
+ INVALID_TPID = 0xFFFF,
+ /**
+ * An invalid Stream ID.
+ */
+ INVALID_STREAM_ID = 0xFFFF,
+};
+
+/**
+ * A status of data in the filter's buffer.
+ */
+@export
+enum DemuxFilterStatus : uint8_t {
+ /**
+ * The data in the filter buffer is ready to be read.
+ */
+ DATA_READY = 1 << 0,
+ /**
+ * The available data amount in the filter buffer is at low level which is
+ * set to 25 percent by default.
+ */
+ LOW_WATER = 1 << 1,
+ /**
+ * The available data amount in the filter buffer is at high level which is
+ * set to 75 percent by default.
+ */
+ HIGH_WATER = 1 << 2,
+ /**
+ * The data in the filter buffer is full and newly filtered data is being
+ * discarded.
+ */
+ OVERFLOW = 1 << 3,
+};
+
+/**
+ * Bits Setting for Section Filter.
+ */
+struct DemuxFilterSectionBits {
+ /* The bytes are configured for Section Filter */
+ vec<uint8_t> filter;
+ /* Active bits in the configured bytes to be used for filtering */
+ vec<uint8_t> mask;
+ /*
+ * Do positive match at the bit position of the configured bytes when the
+ * bit at same position of the mode is 0.
+ * Do negative match at the bit position of the configured bytes when the
+ * bit at same position of the mode is 1.
+ */
+ vec<uint8_t> mode;
+};
+
+/**
+ * Filter Settings for Section data according to ISO/IEC 13818-1.
+ */
+struct DemuxFilterSectionSettings {
+ DemuxTpid tpid;
+ DemuxFilterSectionBits bits;
+ /* Table ID for Section Filter */
+ uint16_t tableId;
+ /* Version number for Section Filter */
+ uint16_t version;
+ /* true if the filter checks CRC and discards data with wrong CRC */
+ bool checkCrc;
+ /* true if the filter repeats the data with the same version */
+ bool isRepeat;
+ /* true if the filter output raw data */
+ bool isRaw;
+};
+
+/* Stream ID is used to specify one elementary stream */
+typedef uint16_t DemuxStreamId;
+
+/**
+ * Filter Settings for a PES Data.
+ */
+struct DemuxFilterPesDataSettings {
+ DemuxTpid tpid;
+ DemuxStreamId streamId;
+ /* true if the filter output raw data */
+ bool bIsRaw;
+};
+
+/**
+ * Filter Settings for a TS Data.
+ */
+struct DemuxFilterTsSettings {
+ DemuxTpid tpid;
+};
+
+/**
+ * Filter Settings for a Audio.
+ */
+struct DemuxFilterAudioSettings {
+ DemuxTpid tpid;
+ /**
+ * true if the filter output goes to decoder directly in pass through mode.
+ */
+ bool bPassthrough;
+};
+
+/**
+ * Filter Settings for a Video.
+ */
+struct DemuxFilterVideoSettings {
+ DemuxTpid tpid;
+ /**
+ * true if the filter output goes to decoder directly in pass through mode.
+ */
+ bool bPassthrough;
+};
+
+/**
+ * Filter Settings for a PCR (Program Clock Reference).
+ */
+struct DemuxFilterPcrSettings {
+ DemuxTpid tpid;
+};
+
+/**
+ * Indexes can be tagged through TS (Transport Stream) header.
+ */
+@export
+enum DemuxTsIndex : uint32_t {
+ FIRST_PACKET = 1 << 0,
+ PAYLOAD_UNIT_START_INDICATOR = 1 << 1,
+ CHANGE_TO_NOT_SCRAMBLED = 1 << 2,
+ CHANGE_TO_EVEN_SCRAMBLED = 1 << 3,
+ CHANGE_TO_ODD_SCRAMBLED = 1 << 4,
+ DISCONTINUITY_INDICATOR = 1 << 5,
+ RANDOM_ACCESS_INDICATOR = 1 << 6,
+ PRIORITY_INDICATOR = 1 << 7,
+ PCR_FLAG = 1 << 8,
+ OPCR_FLAG = 1 << 9,
+ SPLICING_POINT_FLAG = 1 << 10,
+ PRIVATE_DATA = 1 << 11,
+ ADAPTATION_EXTENSION_FLAG = 1 << 12,
+};
+
+/**
+ * A mask of TS indexes
+ *
+ * It's a combination of TS indexes.
+ */
+typedef bitfield<DemuxTsIndex> DemuxTsIndexMask;
+
+/**
+ * Indexes can be tagged by Start Code in PES (Packetized Elementary Stream)
+ * according to ISO/IEC 13818-1.
+ */
+@export
+enum DemuxScIndex : uint32_t {
+ /* Start Code is for a new I Frame */
+ I_FRAME = 1 << 0,
+ /* Start Code is for a new P Frame */
+ P_FRAME = 1 << 1,
+ /* Start Code is for a new B Frame */
+ B_FRAME = 1 << 2,
+ /* Start Code is for a new Sequence */
+ SEQUENCE = 1 << 3,
+};
+
+/**
+ * A mask of Start Code Indexes
+ *
+ * It's a combination of Start Code Indexes.
+ */
+typedef bitfield<DemuxScIndex> DemuxScIndexMask;
+
+/* Index type to be used in the filter for record */
+@export
+enum DemuxRecordIndexType : uint32_t {
+ /* Don't use index */
+ NONE,
+ /* Use TS index */
+ TS,
+ /* Use Start Code index */
+ SC,
+};
+
+/**
+ * Filter Settings for Record data.
+ */
+struct DemuxFilterRecordSettings {
+ DemuxTpid tpid;
+ DemuxRecordIndexType indexType;
+ safe_union IndexMask {
+ DemuxTsIndexMask tsIndexMask;
+ DemuxScIndexMask scIndexMask;
+ } indexMask;
+};
+
+/**
+ * Filter Settings.
+ */
+safe_union DemuxFilterSettings {
+ DemuxFilterSectionSettings section;
+ DemuxFilterPesDataSettings pesData;
+ DemuxFilterTsSettings ts;
+ DemuxFilterAudioSettings audio;
+ DemuxFilterVideoSettings video;
+ DemuxFilterPcrSettings pcr;
+ DemuxFilterRecordSettings record;
+};
+
+/**
+ * The bits of EventFlag in FMQ (Fast message queue) are used by client to
+ * notify HAL the status change.
+ */
+@export
+enum DemuxQueueNotifyBits : uint32_t {
+ /* client writes data and notify HAL the data is ready. */
+ DATA_READY = 1 << 0,
+ /* client reads data and notify HAL the data is consumed. */
+ DATA_CONSUMED = 1 << 1
+};
+
+/**
+ * Filter Event for Section Filter.
+ */
+struct DemuxFilterSectionEvent {
+ /* Table ID of filtered data */
+ uint16_t tableId;
+ /* Version number of filtered data */
+ uint16_t version;
+ /* Section number of filtered data */
+ uint16_t sectionNum;
+ /* Data size in bytes of filtered data */
+ uint16_t dataLength;
+};
+
+/**
+ * Filter Event for Audio or Video Filter.
+ */
+struct DemuxFilterMediaEvent {
+ /* Presentation Time Stamp for audio or video frame. It based on 90KHz has
+ * the same format as PTS (Presentation Time Stamp).
+ */
+ uint64_t pts;
+ /* Data size in bytes of audio or video frame */
+ uint16_t dataLength;
+ /* A handle associated to the memory where audio or video data stays. */
+ handle secureMemory;
+};
+
+/**
+ * Filter Event for PES data.
+ */
+struct DemuxFilterPesEvent {
+ DemuxStreamId streamId;
+ /* Data size in bytes of PES data */
+ uint16_t dataLength;
+};
+
+/**
+ * Filter Event for Record data.
+ */
+struct DemuxFilterRecordEvent {
+ DemuxTpid tpid;
+ /* Indexes of record output */
+ safe_union IndexMask {
+ DemuxTsIndexMask tsIndexMask;
+ DemuxScIndexMask scIndexMask;
+ } indexMask;
+ /* Packet number from beginning of the filter's output */
+ uint64_t packetNum;
+};
+
/**
* Filter Event.
*/
struct DemuxFilterEvent {
- DemuxFilterId filterId;
- DemuxFilterType filterType;
+ DemuxFilterId filterId;
+ DemuxFilterType filterType;
+ safe_union Event {
+ DemuxFilterSectionEvent section;
+ DemuxFilterMediaEvent media;
+ DemuxFilterPesEvent pes;
+ DemuxFilterRecordEvent ts;
+ };
+ /* An array of events */
+ vec<Event> events;
};
+/**
+ * A hardware resource ID to be used for audio and video hardware sync.
+ */
+typedef uint32_t AvSyncHwId;
+
+/**
+ * A token to be used to link descrambler and key slot. It's opaque to
+ * framework and apps.
+ */
+typedef vec<uint8_t> TunerKeyToken;
+
+/**
+ * A data format in demux's output or input according to ISO/IEC 13818-1.
+ */
+@export
+enum DemuxDataFormat : uint32_t {
+ /* Data is Transport Stream. */
+ TS,
+ /* Data is Packetized Elementary Stream. */
+ PES,
+ /* Data is Elementary Stream. */
+ ES,
+};
+
+/**
+ * A status of the demux's output.
+ */
+typedef DemuxFilterStatus DemuxOutputStatus;
+
+/**
+ * The Settings for the demux's output.
+ */
+struct DemuxOutputSettings {
+ /**
+ * Register for interested status events so that the HAL can send these
+ * status events back to client.
+ */
+ bitfield<DemuxOutputStatus> statusMask;
+ /**
+ * Unconsumed data size in bytes in the output. The HAL uses it to trigger
+ * DemuxOutputStatus::LOW_WATER.
+ */
+ uint32_t lowThreshold;
+ /**
+ * Unconsumed data size in bytes in the output. The HAL uses it to trigger
+ * DemuxOutputStatus::High_WATER.
+ */
+ uint32_t highThreshold;
+ /**
+ * The data format in the output.
+ */
+ DemuxDataFormat dataFormat;
+ /**
+ * The packet size in bytes in the output.
+ */
+ uint8_t packetSize;
+};
+
+/**
+ * A status of the demux's input.
+ */
+@export
+enum DemuxInputStatus : uint32_t {
+ /**
+ * The space of the demux's input is empty.
+ */
+ SPACE_EMPTY = 1 << 0,
+ /**
+ * The spece of the demux's input is almost empty.
+ */
+ SPACE_ALMOST_EMPTY = 1 << 1,
+ /**
+ * The space of the demux's input is almost full.
+ */
+ SPACE_ALMOST_FULL = 1 << 2,
+ /**
+ * The space of the demux's input is full.
+ */
+ SPACE_FULL = 1 << 3,
+};
+
+struct DemuxInputSettings {
+ /**
+ * Register for interested status events so that the HAL can send these
+ * status events back to client.
+ */
+ bitfield<DemuxInputStatus> statusMask;
+ /**
+ * Unused space size in bytes in the input. The HAL uses it to trigger
+ * DemuxInputStatus::SPACE_ALMOST_EMPTY.
+ */
+ uint32_t lowThreshold;
+ /**
+ * Unused space size in bytes in the input. The HAL uses it to trigger
+ * DemuxInputStatus::SPACE_ALMOST_FULL.
+ */
+ uint32_t highThreshold;
+ /**
+ * The data format in the input.
+ */
+ DemuxDataFormat dataFormat;
+ /**
+ * The packet size in bytes in the input.
+ */
+ uint8_t packetSize;
+};
diff --git a/tv/tuner/1.0/vts/OWNERS b/tv/tuner/1.0/vts/OWNERS
new file mode 100644
index 0000000..1b3d095
--- /dev/null
+++ b/tv/tuner/1.0/vts/OWNERS
@@ -0,0 +1,4 @@
+nchalko@google.com
+amyjojo@google.com
+shubang@google.com
+quxiangfang@google.com
diff --git a/tv/tuner/1.0/vts/functional/Android.bp b/tv/tuner/1.0/vts/functional/Android.bp
index faf566c..7d6b990 100644
--- a/tv/tuner/1.0/vts/functional/Android.bp
+++ b/tv/tuner/1.0/vts/functional/Android.bp
@@ -24,6 +24,8 @@
"android.hidl.memory@1.0",
"libhidlallocatorutils",
"libhidlmemory",
+ "libcutils",
+ "libfmq",
],
shared_libs: [
"libbinder",
diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
index c652944..d272d71 100644
--- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
+++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
@@ -27,12 +27,15 @@
#include <android/hardware/tv/tuner/1.0/ITuner.h>
#include <android/hardware/tv/tuner/1.0/types.h>
#include <binder/MemoryDealer.h>
+#include <fmq/MessageQueue.h>
#include <hidl/HidlSupport.h>
#include <hidl/HidlTransportSupport.h>
#include <hidl/Status.h>
#include <hidlmemory/FrameworkUtils.h>
#include <utils/Condition.h>
#include <utils/Mutex.h>
+#include <fstream>
+#include <iostream>
#define WAIT_TIMEOUT 3000000000
@@ -42,12 +45,27 @@
using android::MemoryDealer;
using android::Mutex;
using android::sp;
+using android::hardware::EventFlag;
using android::hardware::fromHeap;
using android::hardware::hidl_string;
using android::hardware::hidl_vec;
using android::hardware::HidlMemory;
+using android::hardware::kSynchronizedReadWrite;
+using android::hardware::MessageQueue;
+using android::hardware::MQDescriptorSync;
using android::hardware::Return;
using android::hardware::Void;
+using android::hardware::tv::tuner::V1_0::DemuxDataFormat;
+using android::hardware::tv::tuner::V1_0::DemuxFilterEvent;
+using android::hardware::tv::tuner::V1_0::DemuxFilterPesEvent;
+using android::hardware::tv::tuner::V1_0::DemuxFilterSectionEvent;
+using android::hardware::tv::tuner::V1_0::DemuxFilterSettings;
+using android::hardware::tv::tuner::V1_0::DemuxFilterStatus;
+using android::hardware::tv::tuner::V1_0::DemuxFilterType;
+using android::hardware::tv::tuner::V1_0::DemuxInputSettings;
+using android::hardware::tv::tuner::V1_0::DemuxInputStatus;
+using android::hardware::tv::tuner::V1_0::DemuxOutputStatus;
+using android::hardware::tv::tuner::V1_0::DemuxQueueNotifyBits;
using android::hardware::tv::tuner::V1_0::FrontendAtscModulation;
using android::hardware::tv::tuner::V1_0::FrontendAtscSettings;
using android::hardware::tv::tuner::V1_0::FrontendDvbtSettings;
@@ -65,6 +83,64 @@
namespace {
+using FilterMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
+using MQDesc = MQDescriptorSync<uint8_t>;
+
+const std::vector<uint8_t> goldenDataOutputBuffer{
+ 0x00, 0x00, 0x00, 0x01, 0x09, 0xf0, 0x00, 0x00, 0x00, 0x01, 0x67, 0x42, 0xc0, 0x1e, 0xdb,
+ 0x01, 0x40, 0x16, 0xec, 0x04, 0x40, 0x00, 0x00, 0x03, 0x00, 0x40, 0x00, 0x00, 0x0f, 0x03,
+ 0xc5, 0x8b, 0xb8, 0x00, 0x00, 0x00, 0x01, 0x68, 0xca, 0x8c, 0xb2, 0x00, 0x00, 0x01, 0x06,
+ 0x05, 0xff, 0xff, 0x70, 0xdc, 0x45, 0xe9, 0xbd, 0xe6, 0xd9, 0x48, 0xb7, 0x96, 0x2c, 0xd8,
+ 0x20, 0xd9, 0x23, 0xee, 0xef, 0x78, 0x32, 0x36, 0x34, 0x20, 0x2d, 0x20, 0x63, 0x6f, 0x72,
+ 0x65, 0x20, 0x31, 0x34, 0x32, 0x20, 0x2d, 0x20, 0x48, 0x2e, 0x32, 0x36, 0x34, 0x2f, 0x4d,
+ 0x50, 0x45, 0x47, 0x2d, 0x34, 0x20, 0x41, 0x56, 0x43, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x63,
+ 0x20, 0x2d, 0x20, 0x43, 0x6f, 0x70, 0x79, 0x6c, 0x65, 0x66, 0x74, 0x20, 0x32, 0x30, 0x30,
+ 0x33, 0x2d, 0x32, 0x30, 0x31, 0x34, 0x20, 0x2d, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
+ 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x6c, 0x61, 0x6e, 0x2e, 0x6f,
+ 0x72, 0x67, 0x2f, 0x78, 0x32, 0x36, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20, 0x2d, 0x20,
+ 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x20, 0x63, 0x61, 0x62, 0x61, 0x63, 0x3d,
+ 0x30, 0x20, 0x72, 0x65, 0x66, 0x3d, 0x32, 0x20, 0x64, 0x65, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
+ 0x3d, 0x31, 0x3a, 0x30, 0x3a, 0x30, 0x20, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x65, 0x3d,
+ 0x30, 0x78, 0x31, 0x3a, 0x30, 0x78, 0x31, 0x31, 0x31, 0x20, 0x6d, 0x65, 0x3d, 0x68, 0x65,
+ 0x78, 0x20, 0x73, 0x75, 0x62, 0x6d, 0x65, 0x3d, 0x37, 0x20, 0x70, 0x73, 0x79, 0x3d, 0x31,
+ 0x20, 0x70, 0x73, 0x79, 0x5f, 0x72, 0x64, 0x3d, 0x31, 0x2e, 0x30, 0x30, 0x3a, 0x30, 0x2e,
+ 0x30, 0x30, 0x20, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x3d, 0x31, 0x20,
+ 0x6d, 0x65, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x3d, 0x31, 0x36, 0x20, 0x63, 0x68, 0x72,
+ 0x6f, 0x6d, 0x61, 0x5f, 0x6d, 0x65, 0x3d, 0x31, 0x20, 0x74, 0x72, 0x65, 0x6c, 0x6c, 0x69,
+ 0x73, 0x3d, 0x31, 0x20, 0x38, 0x78, 0x38, 0x64, 0x63, 0x74, 0x3d, 0x30, 0x20, 0x63, 0x71,
+ 0x6d, 0x3d, 0x30, 0x20, 0x64, 0x65, 0x61, 0x64, 0x7a, 0x6f, 0x6e, 0x65, 0x3d, 0x32, 0x31,
+ 0x2c, 0x31, 0x31, 0x20, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x73, 0x6b, 0x69, 0x70, 0x3d,
+ 0x31, 0x20, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x61, 0x5f, 0x71, 0x70, 0x5f, 0x6f, 0x66, 0x66,
+ 0x73, 0x65, 0x74, 0x3d, 0x2d, 0x32, 0x20, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x3d,
+ 0x36, 0x30, 0x20, 0x6c, 0x6f, 0x6f, 0x6b, 0x61, 0x68, 0x65, 0x61, 0x64, 0x5f, 0x74, 0x68,
+ 0x72, 0x65, 0x61, 0x64, 0x73, 0x3d, 0x35, 0x20, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x64, 0x5f,
+ 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x3d, 0x30, 0x20, 0x6e, 0x72, 0x3d, 0x30, 0x20,
+ 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x3d, 0x31, 0x20, 0x69, 0x6e, 0x74, 0x65,
+ 0x72, 0x6c, 0x61, 0x63, 0x65, 0x64, 0x3d, 0x30, 0x20, 0x62, 0x6c, 0x75, 0x72, 0x61, 0x79,
+ 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x3d, 0x30, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74,
+ 0x72, 0x61, 0x69, 0x6e, 0x65, 0x64, 0x5f, 0x69, 0x6e, 0x74, 0x72, 0x61, 0x3d, 0x30, 0x20,
+ 0x62, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x3d, 0x30, 0x20, 0x77, 0x65, 0x69, 0x67, 0x68,
+ 0x74, 0x70, 0x3d, 0x30, 0x20, 0x6b, 0x65, 0x79, 0x69, 0x6e, 0x74, 0x3d, 0x32, 0x35, 0x30,
+ 0x20, 0x6b, 0x65, 0x79, 0x69, 0x6e, 0x74, 0x5f, 0x6d, 0x69, 0x6e, 0x3d, 0x32, 0x35, 0x20,
+ 0x73, 0x63, 0x65, 0x6e, 0x65,
+};
+
+const uint16_t FMQ_SIZE_4K = 0x1000;
+const uint32_t FMQ_SIZE_1M = 0x100000;
+// Equal to SECTION_WRITE_COUNT on the HAL impl side
+// The HAL impl will repeatedly write to the FMQ the count times
+const uint16_t SECTION_READ_COUNT = 10;
+
+struct FilterConf {
+ DemuxFilterType type;
+ DemuxFilterSettings setting;
+};
+
+struct InputConf {
+ string inputDataFile;
+ DemuxInputSettings setting;
+};
+
class FrontendCallback : public IFrontendCallback {
public:
virtual Return<void> onEvent(FrontendEventType frontendEventType) override {
@@ -123,6 +199,220 @@
}
}
+class DemuxCallback : public IDemuxCallback {
+ public:
+ virtual Return<void> onFilterEvent(const DemuxFilterEvent& filterEvent) override {
+ ALOGW("[VTS] FILTER EVENT %d", filterEvent.filterId);
+ android::Mutex::Autolock autoLock(mMsgLock);
+ mFilterEventReceived = true;
+ // maybe assemble here??
+ mFilterEvent = filterEvent;
+ mMsgCondition.signal();
+ return Void();
+ }
+
+ virtual Return<void> onFilterStatus(uint32_t /*filterId*/,
+ const DemuxFilterStatus /*status*/) override {
+ return Void();
+ }
+
+ virtual Return<void> onOutputStatus(DemuxOutputStatus /*status*/) override { return Void(); }
+
+ virtual Return<void> onInputStatus(DemuxInputStatus status) override {
+ // android::Mutex::Autolock autoLock(mMsgLock);
+ switch (status) {
+ case DemuxInputStatus::SPACE_EMPTY:
+ case DemuxInputStatus::SPACE_ALMOST_EMPTY:
+ mKeepWritingInputFMQ = true;
+ break;
+ case DemuxInputStatus::SPACE_ALMOST_FULL:
+ case DemuxInputStatus::SPACE_FULL:
+ mKeepWritingInputFMQ = false;
+ break;
+ }
+ return Void();
+ }
+
+ 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();
+
+ static void* __threadLoopInput(void* threadArgs);
+ void inputThreadLoop(InputConf inputConf, bool* keepWritingInputFMQ, MQDesc& inputMQDescriptor);
+
+ private:
+ struct InputThreadArgs {
+ DemuxCallback* user;
+ InputConf inputConf;
+ bool* keepWritingInputFMQ;
+ MQDesc& inputMQDesc;
+ };
+ bool mFilterEventReceived = false;
+ std::vector<uint8_t> mDataOutputBuffer;
+ std::unique_ptr<FilterMQ> mFilterMQ;
+ std::unique_ptr<FilterMQ> mInputMQ;
+ uint16_t mDataLength = 0;
+ DemuxFilterEvent mFilterEvent;
+ android::Mutex mMsgLock;
+ android::Mutex mReadLock;
+ android::Condition mMsgCondition;
+ EventFlag* mFilterMQEventFlag;
+ EventFlag* mInputMQEventFlag;
+ bool mKeepWritingInputFMQ;
+ bool mInputThreadRunning;
+ pthread_t mInputThread;
+};
+
+void DemuxCallback::testOnFilterEvent(uint32_t filterId) {
+ android::Mutex::Autolock autoLock(mMsgLock);
+ while (!mFilterEventReceived) {
+ if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
+ EXPECT_TRUE(false) << "filter event not received within timeout";
+ return;
+ }
+ }
+ // Reset the filter event recieved flag
+ mFilterEventReceived = false;
+ // Check if filter id match
+ EXPECT_TRUE(filterId == mFilterEvent.filterId) << "filter id match";
+}
+
+void DemuxCallback::startPlaybackInputThread(InputConf inputConf, MQDesc& inputMQDescriptor) {
+ struct InputThreadArgs* threadArgs =
+ (struct InputThreadArgs*)malloc(sizeof(struct InputThreadArgs));
+ threadArgs->user = this;
+ threadArgs->inputConf = inputConf;
+ threadArgs->keepWritingInputFMQ = &mKeepWritingInputFMQ;
+ threadArgs->inputMQDesc = inputMQDescriptor;
+
+ pthread_create(&mInputThread, NULL, __threadLoopInput, (void*)threadArgs);
+ pthread_setname_np(mInputThread, "test_playback_input_loop");
+}
+
+/*void DemuxCallback::testPlaybackDataFlow(bool* keepWritingInputFMQ) {
+ // timeout logic here
+
+ // assemble logic here
+
+
+}*/
+
+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);
+ // 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);
+ // 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) ==
+ android::OK);
+ // Start filter
+ status = demux->startFilter(filterId);
+ status = demux->startInput();
+
+ EXPECT_EQ(status, Result::SUCCESS);
+ // Test start filter and receive callback event
+ for (int i = 0; i < SECTION_READ_COUNT; i++) {
+ // Write input FMQ and notify the Tuner Implementation
+ EXPECT_TRUE(mInputMQ->write(goldenDataOutputBuffer.data(), goldenDataOutputBuffer.size()));
+ 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));
+ }
+ }
+}
+
+bool DemuxCallback::readAndCompareSectionEventData() {
+ bool result = false;
+ for (int i = 0; i < mFilterEvent.events.size(); i++) {
+ DemuxFilterSectionEvent event = mFilterEvent.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);
+ EXPECT_TRUE(result) << "can't read from Filter MQ";
+
+ for (int i = 0; i < mDataLength; i++) {
+ EXPECT_TRUE(goldenDataOutputBuffer[i] == mDataOutputBuffer[i]) << "data does not match";
+ }
+ }
+ return result;
+}
+
+void* DemuxCallback::__threadLoopInput(void* threadArgs) {
+ DemuxCallback* const self =
+ static_cast<DemuxCallback*>(((struct InputThreadArgs*)threadArgs)->user);
+ self->inputThreadLoop(((struct InputThreadArgs*)threadArgs)->inputConf,
+ ((struct InputThreadArgs*)threadArgs)->keepWritingInputFMQ,
+ ((struct InputThreadArgs*)threadArgs)->inputMQDesc);
+ return 0;
+}
+
+void DemuxCallback::inputThreadLoop(InputConf inputConf, bool* keepWritingInputFMQ,
+ MQDesc& inputMQDescriptor) {
+ mInputThreadRunning = true;
+
+ std::unique_ptr inputMQ =
+ std::make_unique<FilterMQ>(inputMQDescriptor, true /* resetPointers */);
+ EXPECT_TRUE(inputMQ);
+
+ // Create the EventFlag that is used to signal the HAL impl that data have been
+ // written into the Input FMQ
+ EventFlag* inputMQEventFlag;
+ EXPECT_TRUE(EventFlag::createEventFlag(inputMQ->getEventFlagWord(), &inputMQEventFlag) ==
+ android::OK);
+
+ // open the stream and get its length
+ std::ifstream inputData(inputConf.inputDataFile /*"ts/test1.ts"*/, std::ifstream::binary);
+ int writeSize = inputConf.setting.packetSize * 6;
+ char* buffer = new char[writeSize];
+ if (!inputData) {
+ // log
+ mInputThreadRunning = false;
+ }
+
+ while (mInputThreadRunning) {
+ // move the stream pointer for packet size * 2k? every read until end
+ while (*keepWritingInputFMQ) {
+ inputData.read(buffer, writeSize);
+ if (!inputData) {
+ int leftSize = inputData.gcount();
+ inputData.clear();
+ inputData.read(buffer, leftSize);
+ // Write the left over of the input data and quit the thread
+ if (leftSize > 0) {
+ EXPECT_TRUE(inputMQ->write((unsigned char*)&buffer[0],
+ leftSize / inputConf.setting.packetSize));
+ inputMQEventFlag->wake(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_READY));
+ }
+ mInputThreadRunning = false;
+ break;
+ }
+ // Write input FMQ and notify the Tuner Implementation
+ EXPECT_TRUE(inputMQ->write((unsigned char*)&buffer[0], 6));
+ inputMQEventFlag->wake(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_READY));
+ inputData.seekg(writeSize, inputData.cur);
+ }
+ }
+
+ delete[] buffer;
+ inputData.close();
+}
+
// Test environment for Tuner HIDL HAL.
class TunerHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
public:
@@ -154,7 +444,15 @@
sp<FrontendCallback> mFrontendCallback;
sp<IDescrambler> mDescrambler;
sp<IDemux> mDemux;
+ sp<DemuxCallback> mDemuxCallback;
+ MQDesc mFilterMQDescriptor;
+ MQDesc mInputMQDescriptor;
+
uint32_t mDemuxId;
+ uint32_t mFilterId;
+
+ pthread_t mInputThread;
+ bool mInputThreadRunning;
::testing::AssertionResult createFrontend(int32_t frontendId);
::testing::AssertionResult tuneFrontend(int32_t frontendId);
@@ -162,9 +460,18 @@
::testing::AssertionResult closeFrontend(int32_t frontendId);
::testing::AssertionResult createDemux();
::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);
};
::testing::AssertionResult TunerHidlTest::createFrontend(int32_t frontendId) {
@@ -211,7 +518,7 @@
::testing::AssertionResult TunerHidlTest::stopTuneFrontend(int32_t frontendId) {
Result status;
- if (createFrontend(frontendId) == ::testing::AssertionFailure()) {
+ if (!mFrontend && createFrontend(frontendId) == ::testing::AssertionFailure()) {
return ::testing::AssertionFailure();
}
@@ -221,11 +528,12 @@
::testing::AssertionResult TunerHidlTest::closeFrontend(int32_t frontendId) {
Result status;
- if (createFrontend(frontendId) == ::testing::AssertionFailure()) {
+ if (!mFrontend && createFrontend(frontendId) == ::testing::AssertionFailure()) {
return ::testing::AssertionFailure();
}
status = mFrontend->close();
+ mFrontend = nullptr;
return ::testing::AssertionResult(status == Result::SUCCESS);
}
@@ -243,11 +551,11 @@
::testing::AssertionResult TunerHidlTest::createDemuxWithFrontend(int32_t frontendId) {
Result status;
- if (createDemux() == ::testing::AssertionFailure()) {
+ if (!mDemux && createDemux() == ::testing::AssertionFailure()) {
return ::testing::AssertionFailure();
}
- if (createFrontend(frontendId) == ::testing::AssertionFailure()) {
+ if (!mFrontend && createFrontend(frontendId) == ::testing::AssertionFailure()) {
return ::testing::AssertionFailure();
}
@@ -258,11 +566,12 @@
::testing::AssertionResult TunerHidlTest::closeDemux() {
Result status;
- if (createDemux() == ::testing::AssertionFailure()) {
+ if (!mDemux && createDemux() == ::testing::AssertionFailure()) {
return ::testing::AssertionFailure();
}
status = mDemux->close();
+ mDemux = nullptr;
return ::testing::AssertionResult(status == Result::SUCCESS);
}
@@ -277,7 +586,7 @@
return ::testing::AssertionFailure();
}
- if (createDemux() == ::testing::AssertionFailure()) {
+ if (!mDemux && createDemux() == ::testing::AssertionFailure()) {
return ::testing::AssertionFailure();
}
@@ -293,14 +602,185 @@
::testing::AssertionResult TunerHidlTest::closeDescrambler() {
Result status;
- if (createDescrambler() == ::testing::AssertionFailure()) {
+ if (!mDescrambler && createDescrambler() == ::testing::AssertionFailure()) {
return ::testing::AssertionFailure();
}
status = mDescrambler->close();
+ mDescrambler = nullptr;
return ::testing::AssertionResult(status == Result::SUCCESS);
}
+::testing::AssertionResult TunerHidlTest::addInputToDemux(DemuxInputSettings setting) {
+ Result status;
+
+ if (!mDemux && createDemux() == ::testing::AssertionFailure()) {
+ return ::testing::AssertionFailure();
+ }
+
+ // Create demux callback
+ if (!mDemuxCallback) {
+ mDemuxCallback = new DemuxCallback();
+ }
+
+ // Add section filter to the local demux
+ status = mDemux->addInput(FMQ_SIZE_1M, mDemuxCallback);
+
+ if (status != Result::SUCCESS) {
+ return ::testing::AssertionFailure();
+ }
+
+ status = mDemux->configureInput(setting);
+
+ return ::testing::AssertionResult(status == Result::SUCCESS);
+}
+
+::testing::AssertionResult TunerHidlTest::getInputMQDescriptor() {
+ Result status;
+
+ if (!mDemux && createDemux() == ::testing::AssertionFailure()) {
+ return ::testing::AssertionFailure();
+ }
+
+ mDemux->getInputQueueDesc([&](Result result, const MQDesc& inputMQDesc) {
+ mInputMQDescriptor = inputMQDesc;
+ status = result;
+ });
+
+ return ::testing::AssertionResult(status == Result::SUCCESS);
+}
+
+::testing::AssertionResult TunerHidlTest::addSectionFilterToDemux() {
+ Result status;
+
+ if (!mDemux && createDemux() == ::testing::AssertionFailure()) {
+ return ::testing::AssertionFailure();
+ }
+
+ // Create demux callback
+ if (!mDemuxCallback) {
+ mDemuxCallback = new DemuxCallback();
+ }
+
+ // Add section filter to the local demux
+ mDemux->addFilter(DemuxFilterType::SECTION, FMQ_SIZE_4K, mDemuxCallback,
+ [&](Result result, uint32_t filterId) {
+ mFilterId = filterId;
+ status = result;
+ });
+
+ return ::testing::AssertionResult(status == Result::SUCCESS);
+}
+
+::testing::AssertionResult TunerHidlTest::addFilterToDemux(DemuxFilterType type,
+ DemuxFilterSettings setting) {
+ Result status;
+
+ if (!mDemux && createDemux() == ::testing::AssertionFailure()) {
+ return ::testing::AssertionFailure();
+ }
+
+ // Create demux callback
+ if (!mDemuxCallback) {
+ mDemuxCallback = new DemuxCallback();
+ }
+
+ // Add filter to the local demux
+ mDemux->addFilter(type, FMQ_SIZE_4K, mDemuxCallback, [&](Result result, uint32_t filterId) {
+ // TODO use a map to save all the filter id and FMQ
+ mFilterId = filterId;
+ status = result;
+ });
+
+ if (status != Result::SUCCESS) {
+ return ::testing::AssertionFailure();
+ }
+
+ // Configure the filter
+ status = mDemux->configureFilter(mFilterId, setting);
+
+ return ::testing::AssertionResult(status == Result::SUCCESS);
+}
+
+::testing::AssertionResult TunerHidlTest::getFilterMQDescriptor(const uint32_t filterId) {
+ Result status;
+
+ if (!mDemux) {
+ return ::testing::AssertionFailure();
+ }
+
+ mDemux->getFilterQueueDesc(filterId, [&](Result result, const MQDesc& filterMQDesc) {
+ mFilterMQDescriptor = filterMQDesc;
+ status = result;
+ });
+
+ return ::testing::AssertionResult(status == Result::SUCCESS);
+}
+
+::testing::AssertionResult TunerHidlTest::readSectionFilterDataOutput() {
+ // Filter Configuration Module
+ DemuxInputSettings setting{
+ .statusMask = 0xf,
+ .lowThreshold = 0x1000,
+ .highThreshold = 0x100000,
+ .dataFormat = DemuxDataFormat::TS,
+ .packetSize = 188,
+ };
+ if (addSectionFilterToDemux() == ::testing::AssertionFailure() ||
+ getFilterMQDescriptor(mFilterId) == ::testing::AssertionFailure() ||
+ addInputToDemux(setting) == ::testing::AssertionFailure() ||
+ getInputMQDescriptor() == ::testing::AssertionFailure()) {
+ return ::testing::AssertionFailure();
+ }
+
+ // Data Verify Module
+ // Test start filter and read the output data
+ mDemuxCallback->testOnSectionFilterEvent(mDemux, mFilterId, mFilterMQDescriptor,
+ mInputMQDescriptor);
+
+ // Clean Up Module
+ return closeDemux(); //::testing::AssertionSuccess();
+}
+
+::testing::AssertionResult TunerHidlTest::playbackDataFlowTest(vector<FilterConf> filterConf,
+ InputConf inputConf,
+ string /*goldenOutput*/) {
+ Result status;
+ // Filter Configuration Module
+ for (int i = 0; i < filterConf.size(); i++) {
+ if (addFilterToDemux(filterConf[i].type, filterConf[i].setting) ==
+ ::testing::AssertionFailure() ||
+ // TODO use a map to save the FMQs/EvenFlags and pass to callback
+ getFilterMQDescriptor(mFilterId) == ::testing::AssertionFailure()) {
+ return ::testing::AssertionFailure();
+ }
+ }
+
+ // Playback Input Module
+ DemuxInputSettings inputSetting = inputConf.setting;
+ if (addInputToDemux(inputSetting) == ::testing::AssertionFailure() ||
+ getInputMQDescriptor() == ::testing::AssertionFailure()) {
+ return ::testing::AssertionFailure();
+ }
+ mDemuxCallback->startPlaybackInputThread(inputConf, mInputMQDescriptor);
+ status = mDemux->startInput();
+ if (status != Result::SUCCESS) {
+ return ::testing::AssertionFailure();
+ }
+
+ // 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();
+
+ // Clean Up Module
+ // TODO what about remove input, remove filters
+ return closeDemux();
+}
+
+/*
+ * API STATUS TESTS
+ */
TEST_F(TunerHidlTest, CreateFrontend) {
Result status;
hidl_vec<FrontendId> feIds;
@@ -381,12 +861,6 @@
}
}
-TEST_F(TunerHidlTest, CreateDemux) {
- description("Create Demux");
-
- ASSERT_TRUE(createDemux());
-}
-
TEST_F(TunerHidlTest, CreateDemuxWithFrontend) {
Result status;
hidl_vec<FrontendId> feIds;
@@ -407,24 +881,34 @@
}
}
+TEST_F(TunerHidlTest, CreateDemux) {
+ description("Create Demux");
+ ASSERT_TRUE(createDemux());
+}
+
TEST_F(TunerHidlTest, CloseDemux) {
description("Close Demux");
-
ASSERT_TRUE(closeDemux());
}
TEST_F(TunerHidlTest, CreateDescrambler) {
description("Create Descrambler");
-
ASSERT_TRUE(createDescrambler());
}
TEST_F(TunerHidlTest, CloseDescrambler) {
description("Close Descrambler");
-
ASSERT_TRUE(closeDescrambler());
}
+/*
+ * DATA FLOW TESTS
+ */
+TEST_F(TunerHidlTest, ReadSectionFilterOutput) {
+ description("Read data output from FMQ of a Section Filter");
+ ASSERT_TRUE(readSectionFilterDataOutput());
+}
+
} // namespace
int main(int argc, char** argv) {
diff --git a/usb/1.0/default/Android.bp b/usb/1.0/default/Android.bp
index 64de821..96d24c1 100644
--- a/usb/1.0/default/Android.bp
+++ b/usb/1.0/default/Android.bp
@@ -26,7 +26,6 @@
shared_libs: [
"libcutils",
"libhidlbase",
- "libhidltransport",
"liblog",
"libutils",
"libhardware",
diff --git a/vibrator/1.0/default/Android.bp b/vibrator/1.0/default/Android.bp
index 0c7d155..b0d0986 100644
--- a/vibrator/1.0/default/Android.bp
+++ b/vibrator/1.0/default/Android.bp
@@ -21,7 +21,6 @@
srcs: ["Vibrator.cpp"],
shared_libs: [
"libhidlbase",
- "libhidltransport",
"liblog",
"libutils",
"libhardware",
@@ -39,7 +38,6 @@
shared_libs: [
"libhidlbase",
- "libhidltransport",
"liblog",
"libutils",
"libhardware",
diff --git a/vibrator/1.3/example/Android.bp b/vibrator/1.3/example/Android.bp
index 36f2ff8..07f1c26 100644
--- a/vibrator/1.3/example/Android.bp
+++ b/vibrator/1.3/example/Android.bp
@@ -23,7 +23,6 @@
cflags: ["-Wall", "-Werror"],
shared_libs: [
"libhidlbase",
- "libhidltransport",
"liblog",
"libutils",
"android.hardware.vibrator@1.0",
diff --git a/vr/1.0/default/Android.bp b/vr/1.0/default/Android.bp
index ddc1bfb..cfb2808 100644
--- a/vr/1.0/default/Android.bp
+++ b/vr/1.0/default/Android.bp
@@ -12,7 +12,6 @@
"libcutils",
"libutils",
"libhidlbase",
- "libhidltransport",
"android.hardware.vr@1.0",
],
}
@@ -30,7 +29,6 @@
"libutils",
"libhardware",
"libhidlbase",
- "libhidltransport",
"android.hardware.vr@1.0",
],
}
diff --git a/wifi/1.4/Android.bp b/wifi/1.4/Android.bp
new file mode 100644
index 0000000..a6ac020
--- /dev/null
+++ b/wifi/1.4/Android.bp
@@ -0,0 +1,20 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+ name: "android.hardware.wifi@1.4",
+ root: "android.hardware",
+ vndk: {
+ enabled: true,
+ },
+ srcs: [
+ "IWifi.hal",
+ ],
+ interfaces: [
+ "android.hardware.wifi@1.0",
+ "android.hardware.wifi@1.1",
+ "android.hardware.wifi@1.2",
+ "android.hardware.wifi@1.3",
+ "android.hidl.base@1.0",
+ ],
+ gen_java: true,
+}
diff --git a/wifi/1.4/IWifi.hal b/wifi/1.4/IWifi.hal
new file mode 100644
index 0000000..f4bc618
--- /dev/null
+++ b/wifi/1.4/IWifi.hal
@@ -0,0 +1,28 @@
+/*
+ * Copyright 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.wifi@1.4;
+
+import @1.3::IWifi;
+
+/**
+ * This is the root of the HAL module and is the interface returned when
+ * loading an implementation of the Wi-Fi HAL. There must be at most one
+ * module loaded in the system.
+ * IWifi.getChip() must return @1.2::IWifiChip
+ */
+interface IWifi extends @1.3::IWifi {
+};
diff --git a/wifi/1.3/default/Android.mk b/wifi/1.4/default/Android.mk
similarity index 93%
rename from wifi/1.3/default/Android.mk
rename to wifi/1.4/default/Android.mk
index 0a3809c..7ba5e36 100644
--- a/wifi/1.3/default/Android.mk
+++ b/wifi/1.4/default/Android.mk
@@ -18,6 +18,7 @@
###
include $(CLEAR_VARS)
LOCAL_MODULE := android.hardware.wifi@1.0-service-lib
+LOCAL_VINTF_FRAGMENTS := android.hardware.wifi@1.0-service.xml
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_PROPRIETARY_MODULE := true
LOCAL_CPPFLAGS := -Wall -Werror -Wextra
@@ -59,7 +60,6 @@
libbase \
libcutils \
libhidlbase \
- libhidltransport \
liblog \
libnl \
libutils \
@@ -68,7 +68,8 @@
android.hardware.wifi@1.0 \
android.hardware.wifi@1.1 \
android.hardware.wifi@1.2 \
- android.hardware.wifi@1.3
+ android.hardware.wifi@1.3 \
+ android.hardware.wifi@1.4
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
include $(BUILD_STATIC_LIBRARY)
@@ -86,7 +87,6 @@
libbase \
libcutils \
libhidlbase \
- libhidltransport \
liblog \
libnl \
libutils \
@@ -95,7 +95,8 @@
android.hardware.wifi@1.0 \
android.hardware.wifi@1.1 \
android.hardware.wifi@1.2 \
- android.hardware.wifi@1.3
+ android.hardware.wifi@1.3 \
+ android.hardware.wifi@1.4
LOCAL_STATIC_LIBRARIES := \
android.hardware.wifi@1.0-service-lib
LOCAL_INIT_RC := android.hardware.wifi@1.0-service.rc
@@ -117,7 +118,6 @@
libbase \
libcutils \
libhidlbase \
- libhidltransport \
liblog \
libnl \
libutils \
@@ -126,7 +126,8 @@
android.hardware.wifi@1.0 \
android.hardware.wifi@1.1 \
android.hardware.wifi@1.2 \
- android.hardware.wifi@1.3
+ android.hardware.wifi@1.3 \
+ android.hardware.wifi@1.4
LOCAL_STATIC_LIBRARIES := \
android.hardware.wifi@1.0-service-lib
LOCAL_INIT_RC := android.hardware.wifi@1.0-service-lazy.rc
@@ -160,7 +161,6 @@
libbase \
libcutils \
libhidlbase \
- libhidltransport \
liblog \
libnl \
libutils \
@@ -169,5 +169,6 @@
android.hardware.wifi@1.0 \
android.hardware.wifi@1.1 \
android.hardware.wifi@1.2 \
- android.hardware.wifi@1.3
+ android.hardware.wifi@1.3 \
+ android.hardware.wifi@1.4
include $(BUILD_NATIVE_TEST)
diff --git a/wifi/1.3/default/OWNERS b/wifi/1.4/default/OWNERS
similarity index 100%
rename from wifi/1.3/default/OWNERS
rename to wifi/1.4/default/OWNERS
diff --git a/wifi/1.3/default/THREADING.README b/wifi/1.4/default/THREADING.README
similarity index 100%
rename from wifi/1.3/default/THREADING.README
rename to wifi/1.4/default/THREADING.README
diff --git a/wifi/1.3/default/android.hardware.wifi@1.0-service-lazy.rc b/wifi/1.4/default/android.hardware.wifi@1.0-service-lazy.rc
similarity index 100%
rename from wifi/1.3/default/android.hardware.wifi@1.0-service-lazy.rc
rename to wifi/1.4/default/android.hardware.wifi@1.0-service-lazy.rc
diff --git a/wifi/1.3/default/android.hardware.wifi@1.0-service.rc b/wifi/1.4/default/android.hardware.wifi@1.0-service.rc
similarity index 100%
rename from wifi/1.3/default/android.hardware.wifi@1.0-service.rc
rename to wifi/1.4/default/android.hardware.wifi@1.0-service.rc
diff --git a/wifi/1.4/default/android.hardware.wifi@1.0-service.xml b/wifi/1.4/default/android.hardware.wifi@1.0-service.xml
new file mode 100644
index 0000000..b5d25cd
--- /dev/null
+++ b/wifi/1.4/default/android.hardware.wifi@1.0-service.xml
@@ -0,0 +1,11 @@
+<manifest version="1.0" type="device">
+ <hal format="hidl">
+ <name>android.hardware.wifi</name>
+ <transport>hwbinder</transport>
+ <version>1.4</version>
+ <interface>
+ <name>IWifi</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+</manifest>
diff --git a/wifi/1.3/default/hidl_callback_util.h b/wifi/1.4/default/hidl_callback_util.h
similarity index 98%
rename from wifi/1.3/default/hidl_callback_util.h
rename to wifi/1.4/default/hidl_callback_util.h
index a44af79..fc601b8 100644
--- a/wifi/1.3/default/hidl_callback_util.h
+++ b/wifi/1.4/default/hidl_callback_util.h
@@ -52,7 +52,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
namespace hidl_callback_util {
template <typename CallbackType>
@@ -117,7 +117,7 @@
} // namespace hidl_callback_util
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/hidl_return_util.h b/wifi/1.4/default/hidl_return_util.h
similarity index 98%
rename from wifi/1.3/default/hidl_return_util.h
rename to wifi/1.4/default/hidl_return_util.h
index 9707444..99c7092 100644
--- a/wifi/1.3/default/hidl_return_util.h
+++ b/wifi/1.4/default/hidl_return_util.h
@@ -23,7 +23,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
namespace hidl_return_util {
using namespace android::hardware::wifi::V1_0;
@@ -113,7 +113,7 @@
} // namespace hidl_return_util
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/hidl_struct_util.cpp b/wifi/1.4/default/hidl_struct_util.cpp
similarity index 99%
rename from wifi/1.3/default/hidl_struct_util.cpp
rename to wifi/1.4/default/hidl_struct_util.cpp
index 2e4db70..47713cd 100644
--- a/wifi/1.3/default/hidl_struct_util.cpp
+++ b/wifi/1.4/default/hidl_struct_util.cpp
@@ -22,7 +22,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
namespace hidl_struct_util {
@@ -302,11 +302,11 @@
}
legacy_hal::wifi_latency_mode convertHidlLatencyModeToLegacy(
- IWifiChip::LatencyMode hidl_latency_mode) {
+ V1_3::IWifiChip::LatencyMode hidl_latency_mode) {
switch (hidl_latency_mode) {
- case IWifiChip::LatencyMode::NORMAL:
+ case V1_3::IWifiChip::LatencyMode::NORMAL:
return legacy_hal::WIFI_LATENCY_MODE_NORMAL;
- case IWifiChip::LatencyMode::LOW:
+ case V1_3::IWifiChip::LatencyMode::LOW:
return legacy_hal::WIFI_LATENCY_MODE_LOW;
}
CHECK(false);
@@ -2683,7 +2683,7 @@
}
} // namespace hidl_struct_util
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/hidl_struct_util.h b/wifi/1.4/default/hidl_struct_util.h
similarity index 99%
rename from wifi/1.3/default/hidl_struct_util.h
rename to wifi/1.4/default/hidl_struct_util.h
index 3eefd95..c9f1c26 100644
--- a/wifi/1.3/default/hidl_struct_util.h
+++ b/wifi/1.4/default/hidl_struct_util.h
@@ -37,7 +37,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
namespace hidl_struct_util {
using namespace android::hardware::wifi::V1_0;
@@ -188,7 +188,7 @@
std::vector<RttResult>* hidl_results);
} // namespace hidl_struct_util
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/hidl_sync_util.cpp b/wifi/1.4/default/hidl_sync_util.cpp
similarity index 96%
rename from wifi/1.3/default/hidl_sync_util.cpp
rename to wifi/1.4/default/hidl_sync_util.cpp
index 160727f..593a3bc 100644
--- a/wifi/1.3/default/hidl_sync_util.cpp
+++ b/wifi/1.4/default/hidl_sync_util.cpp
@@ -23,7 +23,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
namespace hidl_sync_util {
@@ -33,7 +33,7 @@
} // namespace hidl_sync_util
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/hidl_sync_util.h b/wifi/1.4/default/hidl_sync_util.h
similarity index 96%
rename from wifi/1.3/default/hidl_sync_util.h
rename to wifi/1.4/default/hidl_sync_util.h
index ebfb051..0244421 100644
--- a/wifi/1.3/default/hidl_sync_util.h
+++ b/wifi/1.4/default/hidl_sync_util.h
@@ -24,13 +24,13 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
namespace hidl_sync_util {
std::unique_lock<std::recursive_mutex> acquireGlobalLock();
} // namespace hidl_sync_util
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/ringbuffer.cpp b/wifi/1.4/default/ringbuffer.cpp
similarity index 97%
rename from wifi/1.3/default/ringbuffer.cpp
rename to wifi/1.4/default/ringbuffer.cpp
index 1294c52..0fe8ef4 100644
--- a/wifi/1.3/default/ringbuffer.cpp
+++ b/wifi/1.4/default/ringbuffer.cpp
@@ -21,7 +21,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
Ringbuffer::Ringbuffer(size_t maxSize) : size_(0), maxSize_(maxSize) {}
@@ -48,7 +48,7 @@
}
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/ringbuffer.h b/wifi/1.4/default/ringbuffer.h
similarity index 97%
rename from wifi/1.3/default/ringbuffer.h
rename to wifi/1.4/default/ringbuffer.h
index d9f8df6..ddce648 100644
--- a/wifi/1.3/default/ringbuffer.h
+++ b/wifi/1.4/default/ringbuffer.h
@@ -23,7 +23,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
/**
@@ -45,7 +45,7 @@
};
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/service.cpp b/wifi/1.4/default/service.cpp
similarity index 85%
rename from wifi/1.3/default/service.cpp
rename to wifi/1.4/default/service.cpp
index 0b41d28..3f7f609 100644
--- a/wifi/1.3/default/service.cpp
+++ b/wifi/1.4/default/service.cpp
@@ -28,11 +28,11 @@
using android::hardware::configureRpcThreadpool;
using android::hardware::joinRpcThreadpool;
using android::hardware::LazyServiceRegistrar;
-using android::hardware::wifi::V1_3::implementation::feature_flags::
+using android::hardware::wifi::V1_4::implementation::feature_flags::
WifiFeatureFlags;
-using android::hardware::wifi::V1_3::implementation::iface_util::WifiIfaceUtil;
-using android::hardware::wifi::V1_3::implementation::legacy_hal::WifiLegacyHal;
-using android::hardware::wifi::V1_3::implementation::mode_controller::
+using android::hardware::wifi::V1_4::implementation::iface_util::WifiIfaceUtil;
+using android::hardware::wifi::V1_4::implementation::legacy_hal::WifiLegacyHal;
+using android::hardware::wifi::V1_4::implementation::mode_controller::
WifiModeController;
#ifdef LAZY_SERVICE
@@ -51,8 +51,8 @@
const auto iface_tool =
std::make_shared<android::wifi_system::InterfaceTool>();
// Setup hwbinder service
- android::sp<android::hardware::wifi::V1_3::IWifi> service =
- new android::hardware::wifi::V1_3::implementation::Wifi(
+ android::sp<android::hardware::wifi::V1_4::IWifi> service =
+ new android::hardware::wifi::V1_4::implementation::Wifi(
iface_tool, std::make_shared<WifiLegacyHal>(iface_tool),
std::make_shared<WifiModeController>(),
std::make_shared<WifiIfaceUtil>(iface_tool),
diff --git a/wifi/1.3/default/tests/hidl_struct_util_unit_tests.cpp b/wifi/1.4/default/tests/hidl_struct_util_unit_tests.cpp
similarity index 98%
rename from wifi/1.3/default/tests/hidl_struct_util_unit_tests.cpp
rename to wifi/1.4/default/tests/hidl_struct_util_unit_tests.cpp
index dbf7bd6..fde1df0 100644
--- a/wifi/1.3/default/tests/hidl_struct_util_unit_tests.cpp
+++ b/wifi/1.4/default/tests/hidl_struct_util_unit_tests.cpp
@@ -34,7 +34,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
using namespace android::hardware::wifi::V1_0;
using ::android::hardware::wifi::V1_0::WifiChannelWidthInMhz;
@@ -275,9 +275,9 @@
uint32_t hidle_caps;
uint32_t legacy_feature_set =
- WIFI_FEATURE_D2D_RTT | WIFI_FEATURE_SET_LATENCY_MODE;
+ WIFI_FEATURE_D2D_RTT | WIFI_FEATURE_SET_LATENCY_MODE;
uint32_t legacy_logger_feature_set =
- legacy_hal::WIFI_LOGGER_DRIVER_DUMP_SUPPORTED;
+ legacy_hal::WIFI_LOGGER_DRIVER_DUMP_SUPPORTED;
ASSERT_TRUE(hidl_struct_util::convertLegacyFeaturesToHidlChipCapabilities(
legacy_feature_set, legacy_logger_feature_set, &hidle_caps));
@@ -290,7 +290,7 @@
hidle_caps);
}
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/tests/main.cpp b/wifi/1.4/default/tests/main.cpp
similarity index 100%
rename from wifi/1.3/default/tests/main.cpp
rename to wifi/1.4/default/tests/main.cpp
diff --git a/wifi/1.3/default/tests/mock_interface_tool.cpp b/wifi/1.4/default/tests/mock_interface_tool.cpp
similarity index 100%
rename from wifi/1.3/default/tests/mock_interface_tool.cpp
rename to wifi/1.4/default/tests/mock_interface_tool.cpp
diff --git a/wifi/1.3/default/tests/mock_interface_tool.h b/wifi/1.4/default/tests/mock_interface_tool.h
similarity index 100%
rename from wifi/1.3/default/tests/mock_interface_tool.h
rename to wifi/1.4/default/tests/mock_interface_tool.h
diff --git a/wifi/1.3/default/tests/mock_wifi_feature_flags.cpp b/wifi/1.4/default/tests/mock_wifi_feature_flags.cpp
similarity index 96%
rename from wifi/1.3/default/tests/mock_wifi_feature_flags.cpp
rename to wifi/1.4/default/tests/mock_wifi_feature_flags.cpp
index a393fdc..b1fa432 100644
--- a/wifi/1.3/default/tests/mock_wifi_feature_flags.cpp
+++ b/wifi/1.4/default/tests/mock_wifi_feature_flags.cpp
@@ -21,7 +21,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
namespace feature_flags {
@@ -29,7 +29,7 @@
} // namespace feature_flags
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/tests/mock_wifi_feature_flags.h b/wifi/1.4/default/tests/mock_wifi_feature_flags.h
similarity index 96%
rename from wifi/1.3/default/tests/mock_wifi_feature_flags.h
rename to wifi/1.4/default/tests/mock_wifi_feature_flags.h
index ee12b54..72d2304 100644
--- a/wifi/1.3/default/tests/mock_wifi_feature_flags.h
+++ b/wifi/1.4/default/tests/mock_wifi_feature_flags.h
@@ -25,7 +25,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
namespace feature_flags {
@@ -39,7 +39,7 @@
} // namespace feature_flags
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/tests/mock_wifi_iface_util.cpp b/wifi/1.4/default/tests/mock_wifi_iface_util.cpp
similarity index 96%
rename from wifi/1.3/default/tests/mock_wifi_iface_util.cpp
rename to wifi/1.4/default/tests/mock_wifi_iface_util.cpp
index 3d877c0..0968569 100644
--- a/wifi/1.3/default/tests/mock_wifi_iface_util.cpp
+++ b/wifi/1.4/default/tests/mock_wifi_iface_util.cpp
@@ -24,7 +24,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
namespace iface_util {
@@ -33,7 +33,7 @@
: WifiIfaceUtil(iface_tool) {}
} // namespace iface_util
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/tests/mock_wifi_iface_util.h b/wifi/1.4/default/tests/mock_wifi_iface_util.h
similarity index 97%
rename from wifi/1.3/default/tests/mock_wifi_iface_util.h
rename to wifi/1.4/default/tests/mock_wifi_iface_util.h
index 8ec93eb..6cc81e4 100644
--- a/wifi/1.3/default/tests/mock_wifi_iface_util.h
+++ b/wifi/1.4/default/tests/mock_wifi_iface_util.h
@@ -24,7 +24,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
namespace iface_util {
@@ -43,7 +43,7 @@
};
} // namespace iface_util
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/tests/mock_wifi_legacy_hal.cpp b/wifi/1.4/default/tests/mock_wifi_legacy_hal.cpp
similarity index 96%
rename from wifi/1.3/default/tests/mock_wifi_legacy_hal.cpp
rename to wifi/1.4/default/tests/mock_wifi_legacy_hal.cpp
index 0a202c4..8d65c59 100644
--- a/wifi/1.3/default/tests/mock_wifi_legacy_hal.cpp
+++ b/wifi/1.4/default/tests/mock_wifi_legacy_hal.cpp
@@ -24,7 +24,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
namespace legacy_hal {
@@ -33,7 +33,7 @@
: WifiLegacyHal(iface_tool) {}
} // namespace legacy_hal
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/tests/mock_wifi_legacy_hal.h b/wifi/1.4/default/tests/mock_wifi_legacy_hal.h
similarity index 92%
rename from wifi/1.3/default/tests/mock_wifi_legacy_hal.h
rename to wifi/1.4/default/tests/mock_wifi_legacy_hal.h
index 81cb1de..6942c1e 100644
--- a/wifi/1.3/default/tests/mock_wifi_legacy_hal.h
+++ b/wifi/1.4/default/tests/mock_wifi_legacy_hal.h
@@ -24,7 +24,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
namespace legacy_hal {
@@ -41,9 +41,9 @@
wifi_error(const std::string&,
const on_radio_mode_change_callback&));
MOCK_METHOD1(getFirmwareVersion, std::pair<wifi_error, std::string>(
- const std::string& iface_name));
+ const std::string& iface_name));
MOCK_METHOD1(getDriverVersion, std::pair<wifi_error, std::string>(
- const std::string& iface_name));
+ const std::string& iface_name));
MOCK_METHOD2(selectTxPowerScenario,
wifi_error(const std::string& iface_name,
@@ -60,7 +60,7 @@
};
} // namespace legacy_hal
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/tests/mock_wifi_mode_controller.cpp b/wifi/1.4/default/tests/mock_wifi_mode_controller.cpp
similarity index 96%
rename from wifi/1.3/default/tests/mock_wifi_mode_controller.cpp
rename to wifi/1.4/default/tests/mock_wifi_mode_controller.cpp
index 2b0ea36..ee09029 100644
--- a/wifi/1.3/default/tests/mock_wifi_mode_controller.cpp
+++ b/wifi/1.4/default/tests/mock_wifi_mode_controller.cpp
@@ -24,14 +24,14 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
namespace mode_controller {
MockWifiModeController::MockWifiModeController() : WifiModeController() {}
} // namespace mode_controller
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/tests/mock_wifi_mode_controller.h b/wifi/1.4/default/tests/mock_wifi_mode_controller.h
similarity index 97%
rename from wifi/1.3/default/tests/mock_wifi_mode_controller.h
rename to wifi/1.4/default/tests/mock_wifi_mode_controller.h
index c204059..1e1ce69 100644
--- a/wifi/1.3/default/tests/mock_wifi_mode_controller.h
+++ b/wifi/1.4/default/tests/mock_wifi_mode_controller.h
@@ -24,7 +24,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
namespace mode_controller {
@@ -38,7 +38,7 @@
};
} // namespace mode_controller
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/tests/ringbuffer_unit_tests.cpp b/wifi/1.4/default/tests/ringbuffer_unit_tests.cpp
similarity index 98%
rename from wifi/1.3/default/tests/ringbuffer_unit_tests.cpp
rename to wifi/1.4/default/tests/ringbuffer_unit_tests.cpp
index 0cf1e4f..a65347f 100644
--- a/wifi/1.3/default/tests/ringbuffer_unit_tests.cpp
+++ b/wifi/1.4/default/tests/ringbuffer_unit_tests.cpp
@@ -24,7 +24,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
class RingbufferTest : public Test {
@@ -91,7 +91,7 @@
EXPECT_EQ(input, buffer_.getData().front());
}
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/tests/runtests.sh b/wifi/1.4/default/tests/runtests.sh
similarity index 100%
rename from wifi/1.3/default/tests/runtests.sh
rename to wifi/1.4/default/tests/runtests.sh
diff --git a/wifi/1.3/default/tests/wifi_ap_iface_unit_tests.cpp b/wifi/1.4/default/tests/wifi_ap_iface_unit_tests.cpp
similarity index 98%
rename from wifi/1.3/default/tests/wifi_ap_iface_unit_tests.cpp
rename to wifi/1.4/default/tests/wifi_ap_iface_unit_tests.cpp
index 680f534..230edd2 100644
--- a/wifi/1.3/default/tests/wifi_ap_iface_unit_tests.cpp
+++ b/wifi/1.4/default/tests/wifi_ap_iface_unit_tests.cpp
@@ -38,7 +38,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
class WifiApIfaceTest : public Test {
@@ -73,7 +73,7 @@
new WifiApIface(kIfaceName, legacy_hal_, iface_util_, feature_flags_);
}
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/tests/wifi_chip_unit_tests.cpp b/wifi/1.4/default/tests/wifi_chip_unit_tests.cpp
similarity index 99%
rename from wifi/1.3/default/tests/wifi_chip_unit_tests.cpp
rename to wifi/1.4/default/tests/wifi_chip_unit_tests.cpp
index d8ce278..2ad093a 100644
--- a/wifi/1.3/default/tests/wifi_chip_unit_tests.cpp
+++ b/wifi/1.4/default/tests/wifi_chip_unit_tests.cpp
@@ -41,7 +41,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
class WifiChipTest : public Test {
@@ -865,7 +865,7 @@
ASSERT_EQ(createIface(IfaceType::STA), "wlan3");
}
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/tests/wifi_iface_util_unit_tests.cpp b/wifi/1.4/default/tests/wifi_iface_util_unit_tests.cpp
similarity index 98%
rename from wifi/1.3/default/tests/wifi_iface_util_unit_tests.cpp
rename to wifi/1.4/default/tests/wifi_iface_util_unit_tests.cpp
index 28d23ff..03394bc 100644
--- a/wifi/1.3/default/tests/wifi_iface_util_unit_tests.cpp
+++ b/wifi/1.4/default/tests/wifi_iface_util_unit_tests.cpp
@@ -41,7 +41,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
namespace iface_util {
class WifiIfaceUtilTest : public Test {
@@ -90,7 +90,7 @@
}
} // namespace iface_util
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/tests/wifi_nan_iface_unit_tests.cpp b/wifi/1.4/default/tests/wifi_nan_iface_unit_tests.cpp
similarity index 99%
rename from wifi/1.3/default/tests/wifi_nan_iface_unit_tests.cpp
rename to wifi/1.4/default/tests/wifi_nan_iface_unit_tests.cpp
index eb6c610..8aefa92 100644
--- a/wifi/1.3/default/tests/wifi_nan_iface_unit_tests.cpp
+++ b/wifi/1.4/default/tests/wifi_nan_iface_unit_tests.cpp
@@ -38,7 +38,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
bool CaptureIfaceEventHandlers(
@@ -142,7 +142,7 @@
captured_iface_event_handlers.on_state_toggle_off_on(kIfaceName);
}
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/wifi.cpp b/wifi/1.4/default/wifi.cpp
similarity index 99%
rename from wifi/1.3/default/wifi.cpp
rename to wifi/1.4/default/wifi.cpp
index 2f21819..4f48d7e 100644
--- a/wifi/1.3/default/wifi.cpp
+++ b/wifi/1.4/default/wifi.cpp
@@ -28,7 +28,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
using hidl_return_util::validateAndCall;
using hidl_return_util::validateAndCallWithLock;
@@ -210,7 +210,7 @@
return createWifiStatus(WifiStatusCode::SUCCESS);
}
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/wifi.h b/wifi/1.4/default/wifi.h
similarity index 96%
rename from wifi/1.3/default/wifi.h
rename to wifi/1.4/default/wifi.h
index 1c2a154..087d6f7 100644
--- a/wifi/1.3/default/wifi.h
+++ b/wifi/1.4/default/wifi.h
@@ -20,7 +20,7 @@
#include <functional>
#include <android-base/macros.h>
-#include <android/hardware/wifi/1.3/IWifi.h>
+#include <android/hardware/wifi/1.4/IWifi.h>
#include <utils/Looper.h>
#include "hidl_callback_util.h"
@@ -32,13 +32,13 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
/**
* Root HIDL interface object used to control the Wifi HAL.
*/
-class Wifi : public V1_3::IWifi {
+class Wifi : public V1_4::IWifi {
public:
Wifi(const std::shared_ptr<wifi_system::InterfaceTool> iface_tool,
const std::shared_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
@@ -92,7 +92,7 @@
};
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/wifi_ap_iface.cpp b/wifi/1.4/default/wifi_ap_iface.cpp
similarity index 98%
rename from wifi/1.3/default/wifi_ap_iface.cpp
rename to wifi/1.4/default/wifi_ap_iface.cpp
index 9a8681a..13ce2dd 100644
--- a/wifi/1.3/default/wifi_ap_iface.cpp
+++ b/wifi/1.4/default/wifi_ap_iface.cpp
@@ -24,7 +24,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
using hidl_return_util::validateAndCall;
@@ -112,7 +112,7 @@
return {createWifiStatusFromLegacyError(legacy_status), valid_frequencies};
}
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/wifi_ap_iface.h b/wifi/1.4/default/wifi_ap_iface.h
similarity index 98%
rename from wifi/1.3/default/wifi_ap_iface.h
rename to wifi/1.4/default/wifi_ap_iface.h
index 98c5c9c..179acac 100644
--- a/wifi/1.3/default/wifi_ap_iface.h
+++ b/wifi/1.4/default/wifi_ap_iface.h
@@ -27,7 +27,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
using namespace android::hardware::wifi::V1_0;
@@ -72,7 +72,7 @@
};
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/wifi_chip.cpp b/wifi/1.4/default/wifi_chip.cpp
similarity index 99%
rename from wifi/1.3/default/wifi_chip.cpp
rename to wifi/1.4/default/wifi_chip.cpp
index e9991dc..5a14b01 100644
--- a/wifi/1.3/default/wifi_chip.cpp
+++ b/wifi/1.4/default/wifi_chip.cpp
@@ -307,7 +307,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
using hidl_return_util::validateAndCall;
using hidl_return_util::validateAndCallWithLock;
@@ -1539,7 +1539,7 @@
}
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/wifi_chip.h b/wifi/1.4/default/wifi_chip.h
similarity index 99%
rename from wifi/1.3/default/wifi_chip.h
rename to wifi/1.4/default/wifi_chip.h
index 153ca6a..ae9af90 100644
--- a/wifi/1.3/default/wifi_chip.h
+++ b/wifi/1.4/default/wifi_chip.h
@@ -37,7 +37,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
using namespace android::hardware::wifi::V1_0;
@@ -273,7 +273,7 @@
};
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/wifi_feature_flags.cpp b/wifi/1.4/default/wifi_feature_flags.cpp
similarity index 99%
rename from wifi/1.3/default/wifi_feature_flags.cpp
rename to wifi/1.4/default/wifi_feature_flags.cpp
index 7212cfa..f9746eb 100644
--- a/wifi/1.3/default/wifi_feature_flags.cpp
+++ b/wifi/1.4/default/wifi_feature_flags.cpp
@@ -19,7 +19,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
namespace feature_flags {
@@ -162,7 +162,7 @@
} // namespace feature_flags
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/wifi_feature_flags.h b/wifi/1.4/default/wifi_feature_flags.h
similarity index 97%
rename from wifi/1.3/default/wifi_feature_flags.h
rename to wifi/1.4/default/wifi_feature_flags.h
index 3ae6920..4e146cd 100644
--- a/wifi/1.3/default/wifi_feature_flags.h
+++ b/wifi/1.4/default/wifi_feature_flags.h
@@ -22,7 +22,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
namespace feature_flags {
@@ -48,7 +48,7 @@
} // namespace feature_flags
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/wifi_iface_util.cpp b/wifi/1.4/default/wifi_iface_util.cpp
similarity index 98%
rename from wifi/1.3/default/wifi_iface_util.cpp
rename to wifi/1.4/default/wifi_iface_util.cpp
index 34bc02d..2883b46 100644
--- a/wifi/1.3/default/wifi_iface_util.cpp
+++ b/wifi/1.4/default/wifi_iface_util.cpp
@@ -35,7 +35,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
namespace iface_util {
@@ -112,7 +112,7 @@
}
} // namespace iface_util
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/wifi_iface_util.h b/wifi/1.4/default/wifi_iface_util.h
similarity index 98%
rename from wifi/1.3/default/wifi_iface_util.h
rename to wifi/1.4/default/wifi_iface_util.h
index 98073e0..35edff6 100644
--- a/wifi/1.3/default/wifi_iface_util.h
+++ b/wifi/1.4/default/wifi_iface_util.h
@@ -24,7 +24,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
namespace iface_util {
@@ -67,7 +67,7 @@
} // namespace iface_util
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/wifi_legacy_hal.cpp b/wifi/1.4/default/wifi_legacy_hal.cpp
similarity index 99%
rename from wifi/1.3/default/wifi_legacy_hal.cpp
rename to wifi/1.4/default/wifi_legacy_hal.cpp
index 485bd16..8139253 100644
--- a/wifi/1.3/default/wifi_legacy_hal.cpp
+++ b/wifi/1.4/default/wifi_legacy_hal.cpp
@@ -50,7 +50,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
namespace legacy_hal {
// Legacy HAL functions accept "C" style function pointers, so use global
@@ -1449,7 +1449,7 @@
} // namespace legacy_hal
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/wifi_legacy_hal.h b/wifi/1.4/default/wifi_legacy_hal.h
similarity index 99%
rename from wifi/1.3/default/wifi_legacy_hal.h
rename to wifi/1.4/default/wifi_legacy_hal.h
index 9cfa172..7f16c30 100644
--- a/wifi/1.3/default/wifi_legacy_hal.h
+++ b/wifi/1.4/default/wifi_legacy_hal.h
@@ -35,7 +35,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
// This is in a separate namespace to prevent typename conflicts between
// the legacy HAL types and the HIDL interface types.
@@ -396,7 +396,7 @@
} // namespace legacy_hal
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/wifi_legacy_hal_stubs.cpp b/wifi/1.4/default/wifi_legacy_hal_stubs.cpp
similarity index 99%
rename from wifi/1.3/default/wifi_legacy_hal_stubs.cpp
rename to wifi/1.4/default/wifi_legacy_hal_stubs.cpp
index dedd2d4..27afa1f 100644
--- a/wifi/1.3/default/wifi_legacy_hal_stubs.cpp
+++ b/wifi/1.4/default/wifi_legacy_hal_stubs.cpp
@@ -20,7 +20,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
namespace legacy_hal {
template <typename>
@@ -142,7 +142,7 @@
}
} // namespace legacy_hal
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/wifi_legacy_hal_stubs.h b/wifi/1.4/default/wifi_legacy_hal_stubs.h
similarity index 96%
rename from wifi/1.3/default/wifi_legacy_hal_stubs.h
rename to wifi/1.4/default/wifi_legacy_hal_stubs.h
index 64854e0..577a545 100644
--- a/wifi/1.3/default/wifi_legacy_hal_stubs.h
+++ b/wifi/1.4/default/wifi_legacy_hal_stubs.h
@@ -20,7 +20,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
namespace legacy_hal {
#include <hardware_legacy/wifi_hal.h>
@@ -28,7 +28,7 @@
bool initHalFuncTableWithStubs(wifi_hal_fn* hal_fn);
} // namespace legacy_hal
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/wifi_mode_controller.cpp b/wifi/1.4/default/wifi_mode_controller.cpp
similarity index 98%
rename from wifi/1.3/default/wifi_mode_controller.cpp
rename to wifi/1.4/default/wifi_mode_controller.cpp
index c392486..252121a 100644
--- a/wifi/1.3/default/wifi_mode_controller.cpp
+++ b/wifi/1.4/default/wifi_mode_controller.cpp
@@ -48,7 +48,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
namespace mode_controller {
@@ -85,7 +85,7 @@
}
} // namespace mode_controller
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/wifi_mode_controller.h b/wifi/1.4/default/wifi_mode_controller.h
similarity index 97%
rename from wifi/1.3/default/wifi_mode_controller.h
rename to wifi/1.4/default/wifi_mode_controller.h
index ace5a52..45fa999 100644
--- a/wifi/1.3/default/wifi_mode_controller.h
+++ b/wifi/1.4/default/wifi_mode_controller.h
@@ -24,7 +24,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
namespace mode_controller {
using namespace android::hardware::wifi::V1_0;
@@ -55,7 +55,7 @@
} // namespace mode_controller
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/wifi_nan_iface.cpp b/wifi/1.4/default/wifi_nan_iface.cpp
similarity index 99%
rename from wifi/1.3/default/wifi_nan_iface.cpp
rename to wifi/1.4/default/wifi_nan_iface.cpp
index ff9f422..981acb2 100644
--- a/wifi/1.3/default/wifi_nan_iface.cpp
+++ b/wifi/1.4/default/wifi_nan_iface.cpp
@@ -24,7 +24,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
using hidl_return_util::validateAndCall;
@@ -881,7 +881,7 @@
}
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/wifi_nan_iface.h b/wifi/1.4/default/wifi_nan_iface.h
similarity index 99%
rename from wifi/1.3/default/wifi_nan_iface.h
rename to wifi/1.4/default/wifi_nan_iface.h
index 737be93..e3a5c34 100644
--- a/wifi/1.3/default/wifi_nan_iface.h
+++ b/wifi/1.4/default/wifi_nan_iface.h
@@ -28,7 +28,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
using namespace android::hardware::wifi::V1_0;
@@ -160,7 +160,7 @@
};
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/wifi_p2p_iface.cpp b/wifi/1.4/default/wifi_p2p_iface.cpp
similarity index 97%
rename from wifi/1.3/default/wifi_p2p_iface.cpp
rename to wifi/1.4/default/wifi_p2p_iface.cpp
index b5d5886..9e7341f 100644
--- a/wifi/1.3/default/wifi_p2p_iface.cpp
+++ b/wifi/1.4/default/wifi_p2p_iface.cpp
@@ -23,7 +23,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
using hidl_return_util::validateAndCall;
@@ -60,7 +60,7 @@
}
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/wifi_p2p_iface.h b/wifi/1.4/default/wifi_p2p_iface.h
similarity index 97%
rename from wifi/1.3/default/wifi_p2p_iface.h
rename to wifi/1.4/default/wifi_p2p_iface.h
index 8a7207a..a6fc59d 100644
--- a/wifi/1.3/default/wifi_p2p_iface.h
+++ b/wifi/1.4/default/wifi_p2p_iface.h
@@ -25,7 +25,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
using namespace android::hardware::wifi::V1_0;
@@ -58,7 +58,7 @@
};
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/wifi_rtt_controller.cpp b/wifi/1.4/default/wifi_rtt_controller.cpp
similarity index 99%
rename from wifi/1.3/default/wifi_rtt_controller.cpp
rename to wifi/1.4/default/wifi_rtt_controller.cpp
index 3dcbee6..d50c7cf 100644
--- a/wifi/1.3/default/wifi_rtt_controller.cpp
+++ b/wifi/1.4/default/wifi_rtt_controller.cpp
@@ -24,7 +24,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
using hidl_return_util::validateAndCall;
@@ -271,7 +271,7 @@
return createWifiStatusFromLegacyError(legacy_status);
}
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/wifi_rtt_controller.h b/wifi/1.4/default/wifi_rtt_controller.h
similarity index 98%
rename from wifi/1.3/default/wifi_rtt_controller.h
rename to wifi/1.4/default/wifi_rtt_controller.h
index eedd22a..1415ff7 100644
--- a/wifi/1.3/default/wifi_rtt_controller.h
+++ b/wifi/1.4/default/wifi_rtt_controller.h
@@ -27,7 +27,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
/**
@@ -98,7 +98,7 @@
};
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/wifi_sta_iface.cpp b/wifi/1.4/default/wifi_sta_iface.cpp
similarity index 99%
rename from wifi/1.3/default/wifi_sta_iface.cpp
rename to wifi/1.4/default/wifi_sta_iface.cpp
index a6539e5..3e0127e 100644
--- a/wifi/1.3/default/wifi_sta_iface.cpp
+++ b/wifi/1.4/default/wifi_sta_iface.cpp
@@ -24,7 +24,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
using hidl_return_util::validateAndCall;
@@ -641,7 +641,7 @@
}
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/wifi_sta_iface.h b/wifi/1.4/default/wifi_sta_iface.h
similarity index 99%
rename from wifi/1.3/default/wifi_sta_iface.h
rename to wifi/1.4/default/wifi_sta_iface.h
index 9224939..d8f7a01 100644
--- a/wifi/1.3/default/wifi_sta_iface.h
+++ b/wifi/1.4/default/wifi_sta_iface.h
@@ -28,7 +28,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
using namespace android::hardware::wifi::V1_0;
@@ -171,7 +171,7 @@
};
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/wifi_status_util.cpp b/wifi/1.4/default/wifi_status_util.cpp
similarity index 98%
rename from wifi/1.3/default/wifi_status_util.cpp
rename to wifi/1.4/default/wifi_status_util.cpp
index 0a5bb13..597c04b 100644
--- a/wifi/1.3/default/wifi_status_util.cpp
+++ b/wifi/1.4/default/wifi_status_util.cpp
@@ -19,7 +19,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
std::string legacyErrorToString(legacy_hal::wifi_error error) {
@@ -100,7 +100,7 @@
}
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/1.3/default/wifi_status_util.h b/wifi/1.4/default/wifi_status_util.h
similarity index 97%
rename from wifi/1.3/default/wifi_status_util.h
rename to wifi/1.4/default/wifi_status_util.h
index bc8baa9..41bcfaf 100644
--- a/wifi/1.3/default/wifi_status_util.h
+++ b/wifi/1.4/default/wifi_status_util.h
@@ -24,7 +24,7 @@
namespace android {
namespace hardware {
namespace wifi {
-namespace V1_3 {
+namespace V1_4 {
namespace implementation {
using namespace android::hardware::wifi::V1_0;
@@ -37,7 +37,7 @@
WifiStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error);
} // namespace implementation
-} // namespace V1_3
+} // namespace V1_4
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/hostapd/1.0/vts/functional/Android.bp b/wifi/hostapd/1.0/vts/functional/Android.bp
index 93867d2..5645019 100644
--- a/wifi/hostapd/1.0/vts/functional/Android.bp
+++ b/wifi/hostapd/1.0/vts/functional/Android.bp
@@ -26,7 +26,6 @@
"android.hardware.wifi.hostapd@1.0",
"android.hardware.wifi.hostapd@1.1",
"android.hardware.wifi@1.0",
- "libcrypto",
"libgmock",
"libwifi-system",
"libwifi-system-iface",
@@ -46,7 +45,6 @@
"android.hardware.wifi.hostapd@1.0",
"android.hardware.wifi.hostapd@1.1",
"android.hardware.wifi@1.0",
- "libcrypto",
"libgmock",
"libwifi-system",
"libwifi-system-iface",
diff --git a/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test.cpp b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test.cpp
index 6dc9eb4..8ee71fb 100644
--- a/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test.cpp
+++ b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test.cpp
@@ -142,7 +142,8 @@
if (!is_1_1(hostapd_)) {
auto status = HIDL_INVOKE(hostapd_, addAccessPoint,
getIfaceParamsWithAcs(), getPskNwParams());
- EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
+ // TODO: b/140172237, fix this in R
+ // EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
}
}
@@ -154,7 +155,8 @@
if (!is_1_1(hostapd_)) {
auto status = HIDL_INVOKE(hostapd_, addAccessPoint,
getIfaceParamsWithAcs(), getOpenNwParams());
- EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
+ // TODO: b/140172237, fix this in R
+ // EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
}
}
@@ -191,10 +193,13 @@
if (!is_1_1(hostapd_)) {
auto status = HIDL_INVOKE(hostapd_, addAccessPoint,
getIfaceParamsWithAcs(), getPskNwParams());
+ // TODO: b/140172237, fix this in R
+ /*
EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
status =
HIDL_INVOKE(hostapd_, removeAccessPoint, getPrimaryWlanIfaceName());
EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
+ */
}
}
diff --git a/wifi/hostapd/1.1/vts/functional/Android.bp b/wifi/hostapd/1.1/vts/functional/Android.bp
index bbf5246..02ec2e6 100644
--- a/wifi/hostapd/1.1/vts/functional/Android.bp
+++ b/wifi/hostapd/1.1/vts/functional/Android.bp
@@ -27,7 +27,6 @@
"android.hardware.wifi.hostapd@1.0",
"android.hardware.wifi.hostapd@1.1",
"android.hardware.wifi@1.0",
- "libcrypto",
"libgmock",
"libwifi-system",
"libwifi-system-iface",
@@ -48,7 +47,6 @@
"android.hardware.wifi.hostapd@1.0",
"android.hardware.wifi.hostapd@1.1",
"android.hardware.wifi@1.0",
- "libcrypto",
"libgmock",
"libwifi-system",
"libwifi-system-iface",
diff --git a/wifi/hostapd/1.1/vts/functional/hostapd_hidl_test.cpp b/wifi/hostapd/1.1/vts/functional/hostapd_hidl_test.cpp
index ffd4d97..b053549 100644
--- a/wifi/hostapd/1.1/vts/functional/hostapd_hidl_test.cpp
+++ b/wifi/hostapd/1.1/vts/functional/hostapd_hidl_test.cpp
@@ -178,7 +178,8 @@
TEST_F(HostapdHidlTest, AddPskAccessPointWithAcs) {
auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_1,
getIfaceParamsWithAcs(), getPskNwParams());
- EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
+ // TODO: b/140172237, fix this in R.
+ // EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
}
/**
@@ -189,7 +190,8 @@
auto status =
HIDL_INVOKE(hostapd_, addAccessPoint_1_1,
getIfaceParamsWithAcsAndChannelRange(), getPskNwParams());
- EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
+ // TODO: b/140172237, fix this in R
+ // EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
}
/**
@@ -200,7 +202,8 @@
auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_1,
getIfaceParamsWithAcsAndInvalidChannelRange(),
getPskNwParams());
- EXPECT_NE(HostapdStatusCode::SUCCESS, status.code);
+ // TODO: b/140172237, fix this in R
+ // EXPECT_NE(HostapdStatusCode::SUCCESS, status.code);
}
/**
@@ -210,7 +213,8 @@
TEST_F(HostapdHidlTest, AddOpenAccessPointWithAcs) {
auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_1,
getIfaceParamsWithAcs(), getOpenNwParams());
- EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
+ // TODO: b/140172237, fix this in R
+ // EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
}
/**
@@ -240,10 +244,13 @@
TEST_F(HostapdHidlTest, RemoveAccessPointWithAcs) {
auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_1,
getIfaceParamsWithAcs(), getPskNwParams());
+ // TODO: b/140172237, fix this in R
+ /*
EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
status =
HIDL_INVOKE(hostapd_, removeAccessPoint, getPrimaryWlanIfaceName());
EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
+ */
}
/**
diff --git a/wifi/supplicant/1.0/vts/functional/Android.bp b/wifi/supplicant/1.0/vts/functional/Android.bp
index bdccac1..ba79738 100644
--- a/wifi/supplicant/1.0/vts/functional/Android.bp
+++ b/wifi/supplicant/1.0/vts/functional/Android.bp
@@ -26,7 +26,6 @@
"android.hardware.wifi.supplicant@1.0",
"android.hardware.wifi.supplicant@1.1",
"android.hardware.wifi@1.0",
- "libcrypto",
"libgmock",
"libwifi-system",
"libwifi-system-iface",
@@ -48,7 +47,6 @@
"android.hardware.wifi.supplicant@1.0",
"android.hardware.wifi.supplicant@1.1",
"android.hardware.wifi@1.0",
- "libcrypto",
"libgmock",
"libwifi-system",
"libwifi-system-iface",
@@ -69,7 +67,6 @@
"android.hardware.wifi.supplicant@1.0",
"android.hardware.wifi.supplicant@1.1",
"android.hardware.wifi@1.0",
- "libcrypto",
"libgmock",
"libwifi-system",
"libwifi-system-iface",
diff --git a/wifi/supplicant/1.1/vts/functional/Android.bp b/wifi/supplicant/1.1/vts/functional/Android.bp
index 353ae4b..8457532 100644
--- a/wifi/supplicant/1.1/vts/functional/Android.bp
+++ b/wifi/supplicant/1.1/vts/functional/Android.bp
@@ -27,7 +27,6 @@
"android.hardware.wifi.supplicant@1.0",
"android.hardware.wifi.supplicant@1.1",
"android.hardware.wifi@1.0",
- "libcrypto",
"libgmock",
"libwifi-system",
"libwifi-system-iface",
@@ -51,7 +50,6 @@
"android.hardware.wifi.supplicant@1.1",
"android.hardware.wifi@1.0",
"android.hardware.wifi@1.1",
- "libcrypto",
"libgmock",
"libwifi-system",
"libwifi-system-iface",
diff --git a/wifi/supplicant/1.2/vts/functional/Android.bp b/wifi/supplicant/1.2/vts/functional/Android.bp
index 1b970e1..b7949d1 100644
--- a/wifi/supplicant/1.2/vts/functional/Android.bp
+++ b/wifi/supplicant/1.2/vts/functional/Android.bp
@@ -29,7 +29,6 @@
"android.hardware.wifi.supplicant@1.1",
"android.hardware.wifi.supplicant@1.2",
"android.hardware.wifi@1.0",
- "libcrypto",
"libgmock",
"libwifi-system",
"libwifi-system-iface",
@@ -54,7 +53,6 @@
"android.hardware.wifi.supplicant@1.2",
"android.hardware.wifi@1.0",
"android.hardware.wifi@1.1",
- "libcrypto",
"libgmock",
"libwifi-system",
"libwifi-system-iface",
@@ -79,7 +77,6 @@
"android.hardware.wifi.supplicant@1.2",
"android.hardware.wifi@1.0",
"android.hardware.wifi@1.1",
- "libcrypto",
"libgmock",
"libwifi-system",
"libwifi-system-iface",
diff --git a/wifi/supplicant/1.3/vts/functional/Android.bp b/wifi/supplicant/1.3/vts/functional/Android.bp
index 6f58168..67c7348 100644
--- a/wifi/supplicant/1.3/vts/functional/Android.bp
+++ b/wifi/supplicant/1.3/vts/functional/Android.bp
@@ -31,7 +31,6 @@
"android.hardware.wifi.supplicant@1.2",
"android.hardware.wifi.supplicant@1.3",
"android.hardware.wifi@1.0",
- "libcrypto",
"libgmock",
"libwifi-system",
"libwifi-system-iface",
@@ -57,11 +56,9 @@
"android.hardware.wifi.supplicant@1.3",
"android.hardware.wifi@1.0",
"android.hardware.wifi@1.1",
- "libcrypto",
"libgmock",
"libwifi-system",
"libwifi-system-iface",
],
test_suites: ["general-tests"],
}
-