VTS 1.1 TestGnssMeasurementCallback test must allow 1.1 or 1.0 versions am: e16ca9abca
am: 6857687ebc
Change-Id: I66e1275a9758677fa290cbaffff3af4e4f06a457
diff --git a/atrace/1.0/Android.bp b/atrace/1.0/Android.bp
index 4d73cfd..c7e8d04 100644
--- a/atrace/1.0/Android.bp
+++ b/atrace/1.0/Android.bp
@@ -15,4 +15,3 @@
],
gen_java: true,
}
-
diff --git a/atrace/1.0/default/AtraceDevice.cpp b/atrace/1.0/default/AtraceDevice.cpp
index 35d11e9..4e82b0a 100644
--- a/atrace/1.0/default/AtraceDevice.cpp
+++ b/atrace/1.0/default/AtraceDevice.cpp
@@ -94,7 +94,7 @@
for (auto& c : kTracingMap) {
for (auto& p : c.second.paths) {
if (!android::base::WriteStringToFile("0", p.first)) {
- LOG(ERROR) << "Failed to enable tracing on: " << p.first;
+ LOG(ERROR) << "Failed to disable tracing on: " << p.first;
if (p.second) {
ret = Status::ERROR_TRACING_POINT;
}
diff --git a/audio/2.0/Android.bp b/audio/2.0/Android.bp
index 3495b1a..02f8b40 100644
--- a/audio/2.0/Android.bp
+++ b/audio/2.0/Android.bp
@@ -24,4 +24,3 @@
gen_java: false,
gen_java_constants: true,
}
-
diff --git a/audio/4.0/Android.bp b/audio/4.0/Android.bp
index b97fe01..862c711 100644
--- a/audio/4.0/Android.bp
+++ b/audio/4.0/Android.bp
@@ -24,4 +24,3 @@
gen_java: false,
gen_java_constants: true,
}
-
diff --git a/audio/5.0/Android.bp b/audio/5.0/Android.bp
index f6ac2eb..9b28497 100644
--- a/audio/5.0/Android.bp
+++ b/audio/5.0/Android.bp
@@ -25,4 +25,3 @@
gen_java: false,
gen_java_constants: true,
}
-
diff --git a/audio/common/2.0/Android.bp b/audio/common/2.0/Android.bp
index a64548f..475b309 100644
--- a/audio/common/2.0/Android.bp
+++ b/audio/common/2.0/Android.bp
@@ -12,4 +12,3 @@
gen_java: false,
gen_java_constants: true,
}
-
diff --git a/audio/common/4.0/Android.bp b/audio/common/4.0/Android.bp
index cd504e5..83f5aad 100644
--- a/audio/common/4.0/Android.bp
+++ b/audio/common/4.0/Android.bp
@@ -12,4 +12,3 @@
gen_java: false,
gen_java_constants: true,
}
-
diff --git a/audio/common/5.0/Android.bp b/audio/common/5.0/Android.bp
index 66c6fe8..be0f59e 100644
--- a/audio/common/5.0/Android.bp
+++ b/audio/common/5.0/Android.bp
@@ -15,4 +15,3 @@
gen_java: false,
gen_java_constants: true,
}
-
diff --git a/audio/effect/2.0/Android.bp b/audio/effect/2.0/Android.bp
index 2dd1a0c..d4482c2 100644
--- a/audio/effect/2.0/Android.bp
+++ b/audio/effect/2.0/Android.bp
@@ -30,4 +30,3 @@
gen_java: false,
gen_java_constants: true,
}
-
diff --git a/audio/effect/4.0/Android.bp b/audio/effect/4.0/Android.bp
index 2c32bcb..8c1900f 100644
--- a/audio/effect/4.0/Android.bp
+++ b/audio/effect/4.0/Android.bp
@@ -30,4 +30,3 @@
gen_java: false,
gen_java_constants: true,
}
-
diff --git a/audio/effect/5.0/Android.bp b/audio/effect/5.0/Android.bp
index 32fe652..b7dad8d 100644
--- a/audio/effect/5.0/Android.bp
+++ b/audio/effect/5.0/Android.bp
@@ -31,4 +31,3 @@
gen_java: false,
gen_java_constants: true,
}
-
diff --git a/authsecret/1.0/Android.bp b/authsecret/1.0/Android.bp
index 9cde99a..3b84c3b 100644
--- a/authsecret/1.0/Android.bp
+++ b/authsecret/1.0/Android.bp
@@ -14,4 +14,3 @@
],
gen_java: true,
}
-
diff --git a/authsecret/1.0/default/android.hardware.authsecret@1.0-service.rc b/authsecret/1.0/default/android.hardware.authsecret@1.0-service.rc
index e82da7e..1a95cd0 100644
--- a/authsecret/1.0/default/android.hardware.authsecret@1.0-service.rc
+++ b/authsecret/1.0/default/android.hardware.authsecret@1.0-service.rc
@@ -1,4 +1,5 @@
service vendor.authsecret-1-0 /vendor/bin/hw/android.hardware.authsecret@1.0-service
+ interface android.hardware.authsecret@1.0::IAuthSecret default
class hal
user system
group system
diff --git a/automotive/audiocontrol/1.0/Android.bp b/automotive/audiocontrol/1.0/Android.bp
index 7c51cf7..7ef7909 100644
--- a/automotive/audiocontrol/1.0/Android.bp
+++ b/automotive/audiocontrol/1.0/Android.bp
@@ -15,4 +15,3 @@
],
gen_java: true,
}
-
diff --git a/automotive/evs/1.0/Android.bp b/automotive/evs/1.0/Android.bp
index 3ac67ea..51f8e20 100644
--- a/automotive/evs/1.0/Android.bp
+++ b/automotive/evs/1.0/Android.bp
@@ -18,4 +18,3 @@
],
gen_java: true,
}
-
diff --git a/automotive/vehicle/2.0/Android.bp b/automotive/vehicle/2.0/Android.bp
index 4163879..0e73d85 100644
--- a/automotive/vehicle/2.0/Android.bp
+++ b/automotive/vehicle/2.0/Android.bp
@@ -16,4 +16,3 @@
],
gen_java: true,
}
-
diff --git a/biometrics/face/1.0/Android.bp b/biometrics/face/1.0/Android.bp
index 222a09e..ebb8668 100644
--- a/biometrics/face/1.0/Android.bp
+++ b/biometrics/face/1.0/Android.bp
@@ -16,4 +16,3 @@
],
gen_java: true,
}
-
diff --git a/biometrics/fingerprint/2.1/Android.bp b/biometrics/fingerprint/2.1/Android.bp
index cff43c4..c8cc0f1 100644
--- a/biometrics/fingerprint/2.1/Android.bp
+++ b/biometrics/fingerprint/2.1/Android.bp
@@ -16,4 +16,3 @@
],
gen_java: true,
}
-
diff --git a/bluetooth/1.0/Android.bp b/bluetooth/1.0/Android.bp
index 67f1a4f..7036d6e 100644
--- a/bluetooth/1.0/Android.bp
+++ b/bluetooth/1.0/Android.bp
@@ -16,4 +16,3 @@
],
gen_java: true,
}
-
diff --git a/bluetooth/1.0/default/android.hardware.bluetooth@1.0-service.rc b/bluetooth/1.0/default/android.hardware.bluetooth@1.0-service.rc
index b615227..9fa128d 100644
--- a/bluetooth/1.0/default/android.hardware.bluetooth@1.0-service.rc
+++ b/bluetooth/1.0/default/android.hardware.bluetooth@1.0-service.rc
@@ -1,4 +1,5 @@
service vendor.bluetooth-1-0 /vendor/bin/hw/android.hardware.bluetooth@1.0-service
+ interface android.hardware.bluetooth@1.0::IBluetoothHci default
class hal
capabilities BLOCK_SUSPEND NET_ADMIN SYS_NICE
user bluetooth
diff --git a/bluetooth/a2dp/1.0/Android.bp b/bluetooth/a2dp/1.0/Android.bp
index fa46a1c..02f224a 100644
--- a/bluetooth/a2dp/1.0/Android.bp
+++ b/bluetooth/a2dp/1.0/Android.bp
@@ -16,4 +16,3 @@
],
gen_java: false,
}
-
diff --git a/bluetooth/audio/2.0/Android.bp b/bluetooth/audio/2.0/Android.bp
index a020f22..6bf0070 100644
--- a/bluetooth/audio/2.0/Android.bp
+++ b/bluetooth/audio/2.0/Android.bp
@@ -19,4 +19,3 @@
],
gen_java: false,
}
-
diff --git a/boot/1.0/Android.bp b/boot/1.0/Android.bp
index b580cac..5568436 100644
--- a/boot/1.0/Android.bp
+++ b/boot/1.0/Android.bp
@@ -15,4 +15,3 @@
],
gen_java: true,
}
-
diff --git a/boot/1.0/default/Android.mk b/boot/1.0/default/Android.mk
deleted file mode 100644
index 7ccc4c8..0000000
--- a/boot/1.0/default/Android.mk
+++ /dev/null
@@ -1,30 +0,0 @@
-# TODO(connoro): Remove this file once we eliminate existing usage of
-# PRODUCT_STATIC_BOOT_CONTROL_HAL
-
-LOCAL_PATH := $(call my-dir)
-
-ifneq ($(strip $(PRODUCT_STATIC_BOOT_CONTROL_HAL)),)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := android.hardware.boot@1.0-impl-wrapper.recovery
-LOCAL_MODULE_CLASS := SHARED_LIBRARIES
-LOCAL_MULTILIB := first
-ifeq ($(TARGET_IS_64_BIT),true)
-LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/system/lib64/hw
-else
-LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/system/lib/hw
-endif
-LOCAL_SRC_FILES := BootControl.cpp
-LOCAL_CFLAGS := -DBOOT_CONTROL_RECOVERY
-LOCAL_SHARED_LIBRARIES := \
- libbase.recovery \
- liblog.recovery \
- libhidlbase.recovery \
- libhidltransport.recovery \
- libhardware.recovery \
- libutils.recovery \
- android.hardware.boot@1.0.recovery
-LOCAL_STATIC_LIBRARIES := $(PRODUCT_STATIC_BOOT_CONTROL_HAL)
-include $(BUILD_SHARED_LIBRARY)
-
-endif
diff --git a/boot/1.0/default/android.hardware.boot@1.0-service.rc b/boot/1.0/default/android.hardware.boot@1.0-service.rc
index 32f3a45..b8125e1 100644
--- a/boot/1.0/default/android.hardware.boot@1.0-service.rc
+++ b/boot/1.0/default/android.hardware.boot@1.0-service.rc
@@ -1,4 +1,5 @@
service vendor.boot-hal-1-0 /vendor/bin/hw/android.hardware.boot@1.0-service
+ interface android.hardware.boot@1.0::IBootControl default
class early_hal
user root
group root
diff --git a/broadcastradio/1.0/Android.bp b/broadcastradio/1.0/Android.bp
index 76e580e..8239d74 100644
--- a/broadcastradio/1.0/Android.bp
+++ b/broadcastradio/1.0/Android.bp
@@ -18,4 +18,3 @@
],
gen_java: false,
}
-
diff --git a/broadcastradio/1.1/Android.bp b/broadcastradio/1.1/Android.bp
index 2186b9a..1cc9b62 100644
--- a/broadcastradio/1.1/Android.bp
+++ b/broadcastradio/1.1/Android.bp
@@ -19,4 +19,3 @@
],
gen_java: false,
}
-
diff --git a/broadcastradio/1.1/default/android.hardware.broadcastradio@1.1-service.rc b/broadcastradio/1.1/default/android.hardware.broadcastradio@1.1-service.rc
index 7c57135..6fcbfa6 100644
--- a/broadcastradio/1.1/default/android.hardware.broadcastradio@1.1-service.rc
+++ b/broadcastradio/1.1/default/android.hardware.broadcastradio@1.1-service.rc
@@ -1,4 +1,6 @@
service broadcastradio-hal /vendor/bin/hw/android.hardware.broadcastradio@1.1-service
+ interface android.hardware.broadcastradio@1.0::IBroadcastRadioFactory default
+ interface android.hardware.broadcastradio@1.1::IBroadcastRadioFactory default
class hal
user audioserver
group audio
diff --git a/broadcastradio/2.0/Android.bp b/broadcastradio/2.0/Android.bp
index 93afc02..1040ba1 100644
--- a/broadcastradio/2.0/Android.bp
+++ b/broadcastradio/2.0/Android.bp
@@ -19,4 +19,3 @@
],
gen_java: true,
}
-
diff --git a/broadcastradio/2.0/default/android.hardware.broadcastradio@2.0-service.rc b/broadcastradio/2.0/default/android.hardware.broadcastradio@2.0-service.rc
index 7d68b6c..dd8c9c6 100644
--- a/broadcastradio/2.0/default/android.hardware.broadcastradio@2.0-service.rc
+++ b/broadcastradio/2.0/default/android.hardware.broadcastradio@2.0-service.rc
@@ -1,4 +1,5 @@
service broadcastradio-hal2 /vendor/bin/hw/android.hardware.broadcastradio@2.0-service
+ interface android.hardware.broadcastradio@2.0::IBroadcastRadio default
class hal
user audioserver
group audio
diff --git a/camera/common/1.0/Android.bp b/camera/common/1.0/Android.bp
index fe29774..ed64060 100644
--- a/camera/common/1.0/Android.bp
+++ b/camera/common/1.0/Android.bp
@@ -11,4 +11,3 @@
],
gen_java: true,
}
-
diff --git a/camera/device/1.0/Android.bp b/camera/device/1.0/Android.bp
index a8df1ec..668884d 100644
--- a/camera/device/1.0/Android.bp
+++ b/camera/device/1.0/Android.bp
@@ -19,4 +19,3 @@
],
gen_java: true,
}
-
diff --git a/camera/device/3.2/Android.bp b/camera/device/3.2/Android.bp
index e7546de..2e5349f 100644
--- a/camera/device/3.2/Android.bp
+++ b/camera/device/3.2/Android.bp
@@ -19,4 +19,3 @@
],
gen_java: false,
}
-
diff --git a/camera/device/3.3/Android.bp b/camera/device/3.3/Android.bp
index e21824f..679fad6 100644
--- a/camera/device/3.3/Android.bp
+++ b/camera/device/3.3/Android.bp
@@ -18,4 +18,3 @@
],
gen_java: false,
}
-
diff --git a/camera/device/3.4/Android.bp b/camera/device/3.4/Android.bp
index 6a2eac5..e6f42d6 100644
--- a/camera/device/3.4/Android.bp
+++ b/camera/device/3.4/Android.bp
@@ -20,4 +20,3 @@
],
gen_java: false,
}
-
diff --git a/camera/device/3.5/Android.bp b/camera/device/3.5/Android.bp
index d51fd0e..362a5e6 100644
--- a/camera/device/3.5/Android.bp
+++ b/camera/device/3.5/Android.bp
@@ -22,4 +22,3 @@
],
gen_java: false,
}
-
diff --git a/camera/metadata/3.2/Android.bp b/camera/metadata/3.2/Android.bp
index 3271d91..f58fb28 100644
--- a/camera/metadata/3.2/Android.bp
+++ b/camera/metadata/3.2/Android.bp
@@ -11,4 +11,3 @@
],
gen_java: true,
}
-
diff --git a/camera/metadata/3.3/Android.bp b/camera/metadata/3.3/Android.bp
index 4dddfad..885f4f9 100644
--- a/camera/metadata/3.3/Android.bp
+++ b/camera/metadata/3.3/Android.bp
@@ -14,4 +14,3 @@
],
gen_java: true,
}
-
diff --git a/camera/metadata/3.4/Android.bp b/camera/metadata/3.4/Android.bp
index 2b75eba..6a92458 100644
--- a/camera/metadata/3.4/Android.bp
+++ b/camera/metadata/3.4/Android.bp
@@ -15,4 +15,3 @@
],
gen_java: true,
}
-
diff --git a/camera/provider/2.4/Android.bp b/camera/provider/2.4/Android.bp
index 63d7fd5..876814d 100644
--- a/camera/provider/2.4/Android.bp
+++ b/camera/provider/2.4/Android.bp
@@ -18,4 +18,3 @@
],
gen_java: false,
}
-
diff --git a/camera/provider/2.5/Android.bp b/camera/provider/2.5/Android.bp
index a4af07e..4ca1efb 100644
--- a/camera/provider/2.5/Android.bp
+++ b/camera/provider/2.5/Android.bp
@@ -19,4 +19,3 @@
],
gen_java: false,
}
-
diff --git a/cas/1.0/Android.bp b/cas/1.0/Android.bp
index 8d8e946..4982e20 100644
--- a/cas/1.0/Android.bp
+++ b/cas/1.0/Android.bp
@@ -18,4 +18,3 @@
],
gen_java: true,
}
-
diff --git a/cas/1.1/Android.bp b/cas/1.1/Android.bp
index bb0edb9..13217b6 100644
--- a/cas/1.1/Android.bp
+++ b/cas/1.1/Android.bp
@@ -17,4 +17,3 @@
],
gen_java: true,
}
-
diff --git a/cas/1.1/default/android.hardware.cas@1.1-service-lazy.rc b/cas/1.1/default/android.hardware.cas@1.1-service-lazy.rc
index 9227b6f..73c505d 100644
--- a/cas/1.1/default/android.hardware.cas@1.1-service-lazy.rc
+++ b/cas/1.1/default/android.hardware.cas@1.1-service-lazy.rc
@@ -1,4 +1,5 @@
service vendor.cas-hal-1-1 /vendor/bin/hw/android.hardware.cas@1.1-service-lazy
+ interface android.hardware.cas@1.0::IMediaCasService default
interface android.hardware.cas@1.1::IMediaCasService default
oneshot
disabled
diff --git a/cas/native/1.0/Android.bp b/cas/native/1.0/Android.bp
index 880eccd..633ceb9 100644
--- a/cas/native/1.0/Android.bp
+++ b/cas/native/1.0/Android.bp
@@ -16,4 +16,3 @@
],
gen_java: false,
}
-
diff --git a/compatibility_matrices/Android.bp b/compatibility_matrices/Android.bp
index 7a779b9..799ab07 100644
--- a/compatibility_matrices/Android.bp
+++ b/compatibility_matrices/Android.bp
@@ -75,3 +75,16 @@
"kernel_config_q_4.19",
]
}
+
+vintf_compatibility_matrix {
+ name: "framework_compatibility_matrix.current.xml",
+ stem: "compatibility_matrix.current.xml",
+ srcs: [
+ "compatibility_matrix.current.xml",
+ ],
+ kernel_configs: [
+ "kernel_config_current_4.9",
+ "kernel_config_current_4.14",
+ "kernel_config_current_4.19",
+ ]
+}
diff --git a/compatibility_matrices/Android.mk b/compatibility_matrices/Android.mk
index b0caa7c..7c7f87f 100644
--- a/compatibility_matrices/Android.mk
+++ b/compatibility_matrices/Android.mk
@@ -97,6 +97,7 @@
framework_compatibility_matrix.2.xml \
framework_compatibility_matrix.3.xml \
framework_compatibility_matrix.4.xml \
+ framework_compatibility_matrix.current.xml \
framework_compatibility_matrix.device.xml \
my_framework_matrix_deps += \
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
new file mode 100644
index 0000000..6e1bc8f
--- /dev/null
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -0,0 +1,516 @@
+<compatibility-matrix version="1.0" type="framework" level="5">
+ <hal format="hidl" optional="true">
+ <name>android.hardware.atrace</name>
+ <version>1.0</version>
+ <interface>
+ <name>IAtraceDevice</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="false">
+ <name>android.hardware.audio</name>
+ <version>5.0</version>
+ <interface>
+ <name>IDevicesFactory</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="false">
+ <name>android.hardware.audio.effect</name>
+ <version>5.0</version>
+ <interface>
+ <name>IEffectsFactory</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.authsecret</name>
+ <version>1.0</version>
+ <interface>
+ <name>IAuthSecret</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.automotive.audiocontrol</name>
+ <version>1.0</version>
+ <interface>
+ <name>IAudioControl</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.automotive.evs</name>
+ <version>1.0</version>
+ <interface>
+ <name>IEvsEnumerator</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.automotive.vehicle</name>
+ <version>2.0</version>
+ <interface>
+ <name>IVehicle</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.biometrics.face</name>
+ <version>1.0</version>
+ <interface>
+ <name>IBiometricsFace</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.biometrics.fingerprint</name>
+ <version>2.1</version>
+ <interface>
+ <name>IBiometricsFingerprint</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.bluetooth</name>
+ <version>1.0</version>
+ <interface>
+ <name>IBluetoothHci</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.bluetooth.audio</name>
+ <version>2.0</version>
+ <interface>
+ <name>IBluetoothAudioProvidersFactory</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.boot</name>
+ <version>1.0</version>
+ <interface>
+ <name>IBootControl</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.broadcastradio</name>
+ <version>1.0-1</version>
+ <interface>
+ <name>IBroadcastRadioFactory</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.broadcastradio</name>
+ <version>2.0</version>
+ <interface>
+ <name>IBroadcastRadio</name>
+ <regex-instance>.*</regex-instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.camera.provider</name>
+ <version>2.4-5</version>
+ <interface>
+ <name>ICameraProvider</name>
+ <regex-instance>[^/]+/[0-9]+</regex-instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.cas</name>
+ <version>1.1</version>
+ <interface>
+ <name>IMediaCasService</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.configstore</name>
+ <version>1.1</version>
+ <interface>
+ <name>ISurfaceFlingerConfigs</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.confirmationui</name>
+ <version>1.0</version>
+ <interface>
+ <name>IConfirmationUI</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.contexthub</name>
+ <version>1.0</version>
+ <interface>
+ <name>IContexthub</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.drm</name>
+ <version>1.0-2</version>
+ <interface>
+ <name>ICryptoFactory</name>
+ <regex-instance>.*</regex-instance>
+ </interface>
+ <interface>
+ <name>IDrmFactory</name>
+ <regex-instance>.*</regex-instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.dumpstate</name>
+ <version>1.0</version>
+ <interface>
+ <name>IDumpstateDevice</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="false">
+ <name>android.hardware.gatekeeper</name>
+ <version>1.0</version>
+ <interface>
+ <name>IGatekeeper</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.gnss</name>
+ <!--
+ - Both versions are listed here as a workaround for libvintf since 2.0 extends 1.1.
+ - Devices launched with Q must support gnss@2.0, see VtsTrebleVendorVintfTest
+ - test DeviceManifestTest#GnssHalVersionCompatibility.
+ -->
+ <version>1.1</version>
+ <version>2.0</version>
+ <interface>
+ <name>IGnss</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="false">
+ <name>android.hardware.graphics.allocator</name>
+ <version>2.0</version>
+ <version>3.0</version>
+ <interface>
+ <name>IAllocator</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="false">
+ <name>android.hardware.graphics.composer</name>
+ <version>2.1-3</version>
+ <interface>
+ <name>IComposer</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="false">
+ <name>android.hardware.graphics.mapper</name>
+ <version>2.1</version>
+ <version>3.0</version>
+ <interface>
+ <name>IMapper</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="false">
+ <name>android.hardware.health</name>
+ <version>2.0</version>
+ <interface>
+ <name>IHealth</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.health.storage</name>
+ <version>1.0</version>
+ <interface>
+ <name>IStorage</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.ir</name>
+ <version>1.0</version>
+ <interface>
+ <name>IConsumerIr</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.input.classifier</name>
+ <version>1.0</version>
+ <interface>
+ <name>IInputClassifier</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="false">
+ <name>android.hardware.keymaster</name>
+ <version>3.0</version>
+ <version>4.0</version>
+ <interface>
+ <name>IKeymasterDevice</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.keymaster</name>
+ <version>4.0</version>
+ <interface>
+ <name>IKeymasterDevice</name>
+ <instance>strongbox</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.light</name>
+ <version>2.0</version>
+ <interface>
+ <name>ILight</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.media.c2</name>
+ <version>1.0</version>
+ <interface>
+ <name>IComponentStore</name>
+ <regex-instance>default[0-9]*</regex-instance>
+ <regex-instance>vendor[0-9]*_software</regex-instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.media.omx</name>
+ <version>1.0</version>
+ <interface>
+ <name>IOmx</name>
+ <instance>default</instance>
+ </interface>
+ <interface>
+ <name>IOmxStore</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.memtrack</name>
+ <version>1.0</version>
+ <interface>
+ <name>IMemtrack</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.neuralnetworks</name>
+ <version>1.0-2</version>
+ <interface>
+ <name>IDevice</name>
+ <regex-instance>.*</regex-instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.nfc</name>
+ <version>1.2</version>
+ <interface>
+ <name>INfc</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.oemlock</name>
+ <version>1.0</version>
+ <interface>
+ <name>IOemLock</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.power</name>
+ <version>1.0-3</version>
+ <interface>
+ <name>IPower</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.power.stats</name>
+ <version>1.0</version>
+ <interface>
+ <name>IPowerStats</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.radio</name>
+ <version>1.4</version>
+ <interface>
+ <name>IRadio</name>
+ <instance>slot1</instance>
+ <instance>slot2</instance>
+ <instance>slot3</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.radio</name>
+ <version>1.2</version>
+ <interface>
+ <name>ISap</name>
+ <instance>slot1</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.radio.config</name>
+ <!--
+ See compatibility_matrix.4.xml on versioning of radio config HAL.
+ -->
+ <version>1.1</version>
+ <interface>
+ <name>IRadioConfig</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.renderscript</name>
+ <version>1.0</version>
+ <interface>
+ <name>IDevice</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.secure_element</name>
+ <version>1.0</version>
+ <interface>
+ <name>ISecureElement</name>
+ <regex-instance>eSE[1-9][0-9]*</regex-instance>
+ <regex-instance>SIM[1-9][0-9]*</regex-instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.sensors</name>
+ <version>1.0</version>
+ <version>2.0</version>
+ <interface>
+ <name>ISensors</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.soundtrigger</name>
+ <version>2.0-2</version>
+ <interface>
+ <name>ISoundTriggerHw</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.tetheroffload.config</name>
+ <version>1.0</version>
+ <interface>
+ <name>IOffloadConfig</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.tetheroffload.control</name>
+ <version>1.0</version>
+ <interface>
+ <name>IOffloadControl</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.thermal</name>
+ <version>1.0-1</version>
+ <version>2.0</version>
+ <interface>
+ <name>IThermal</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.tv.cec</name>
+ <version>1.0</version>
+ <interface>
+ <name>IHdmiCec</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.tv.input</name>
+ <version>1.0</version>
+ <interface>
+ <name>ITvInput</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.usb</name>
+ <version>1.0-2</version>
+ <interface>
+ <name>IUsb</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.usb.gadget</name>
+ <version>1.0</version>
+ <interface>
+ <name>IUsbGadget</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.vibrator</name>
+ <version>1.0-3</version>
+ <interface>
+ <name>IVibrator</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.vr</name>
+ <version>1.0</version>
+ <interface>
+ <name>IVr</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.weaver</name>
+ <version>1.0</version>
+ <interface>
+ <name>IWeaver</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.wifi</name>
+ <version>1.0-3</version>
+ <interface>
+ <name>IWifi</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.wifi.hostapd</name>
+ <version>1.0-1</version>
+ <interface>
+ <name>IHostapd</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.wifi.supplicant</name>
+ <version>1.0-2</version>
+ <interface>
+ <name>ISupplicant</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+</compatibility-matrix>
diff --git a/configstore/1.0/Android.bp b/configstore/1.0/Android.bp
index a6fd656..d92f252 100644
--- a/configstore/1.0/Android.bp
+++ b/configstore/1.0/Android.bp
@@ -15,4 +15,3 @@
],
gen_java: true,
}
-
diff --git a/configstore/1.1/Android.bp b/configstore/1.1/Android.bp
index 3900d9b..7c5f3f7 100644
--- a/configstore/1.1/Android.bp
+++ b/configstore/1.1/Android.bp
@@ -16,4 +16,3 @@
],
gen_java: true,
}
-
diff --git a/configstore/1.1/default/android.hardware.configstore@1.1-service.rc b/configstore/1.1/default/android.hardware.configstore@1.1-service.rc
index 105678a..d62c4a8 100644
--- a/configstore/1.1/default/android.hardware.configstore@1.1-service.rc
+++ b/configstore/1.1/default/android.hardware.configstore@1.1-service.rc
@@ -1,4 +1,6 @@
service vendor.configstore-hal /vendor/bin/hw/android.hardware.configstore@1.1-service
+ interface android.hardware.configstore@1.0::ISurfaceFlingerConfigs default
+ interface android.hardware.configstore@1.1::ISurfaceFlingerConfigs default
class hal animation
user system
group system
diff --git a/confirmationui/1.0/Android.bp b/confirmationui/1.0/Android.bp
index e6b0414..a22067a 100644
--- a/confirmationui/1.0/Android.bp
+++ b/confirmationui/1.0/Android.bp
@@ -17,4 +17,3 @@
],
gen_java: false,
}
-
diff --git a/confirmationui/1.0/default/android.hardware.confirmationui@1.0-service.rc b/confirmationui/1.0/default/android.hardware.confirmationui@1.0-service.rc
index c04e55e..adc7222 100644
--- a/confirmationui/1.0/default/android.hardware.confirmationui@1.0-service.rc
+++ b/confirmationui/1.0/default/android.hardware.confirmationui@1.0-service.rc
@@ -1,4 +1,5 @@
service vendor.confirmationui-1-0 /vendor/bin/hw/android.hardware.confirmationui@1.0-service
+ interface android.hardware.confirmationui@1.0::IConfirmationUI default
class hal
user nobody
group drmrpc
diff --git a/contexthub/1.0/Android.bp b/contexthub/1.0/Android.bp
index 730adcb..71dd978 100644
--- a/contexthub/1.0/Android.bp
+++ b/contexthub/1.0/Android.bp
@@ -16,4 +16,3 @@
],
gen_java: true,
}
-
diff --git a/contexthub/1.0/default/android.hardware.contexthub@1.0-service.rc b/contexthub/1.0/default/android.hardware.contexthub@1.0-service.rc
index a8c9487..b659be8 100644
--- a/contexthub/1.0/default/android.hardware.contexthub@1.0-service.rc
+++ b/contexthub/1.0/default/android.hardware.contexthub@1.0-service.rc
@@ -1,4 +1,5 @@
service vendor.contexthub-hal-1-0 /vendor/bin/hw/android.hardware.contexthub@1.0-service
+ interface android.hardware.contexthub@1.0::IContexthub default
class hal
user system
group system
diff --git a/current.txt b/current.txt
index 47e7d72..eb1b1ca 100644
--- a/current.txt
+++ b/current.txt
@@ -570,3 +570,9 @@
09e08b5d12b109562ecdd8882532fd1f2c4639588e07769d5c7396b7c5b9f34f android.hardware.wifi.supplicant@1.2::ISupplicantStaIfaceCallback
efbb061c969fa9553d243da6ee23b83fe5d4aa663a7b8896adc52e2b015bc2f3 android.hardware.wifi.supplicant@1.2::ISupplicantStaNetwork
cfa81f229b69f9011c58f48264fcb552447430fe68610eac514e811e65bc306a android.hardware.wifi.supplicant@1.2::types
+
+# ABI preserving changes to HALs during Android R
+b69a7615c508acf5c5201efd1bfa3262167874fc3594e2db5a3ff93addd8ac75 android.hardware.keymaster@4.0::IKeymasterDevice
+ad431c8de51c07934a068e3043d8dd0537ac4d3158627706628b123f42df48dc android.hardware.neuralnetworks@1.0::IPreparedModel
+aafcc10cf04ab247e86d4582586c71c6b4c2b8c479241ffa7fe37deb659fc942 android.hardware.neuralnetworks@1.2::IPreparedModel
+1a6e2bd289f22931c526b21916910f1d4c436b7acb9556e4243de4ce8e6cc2e4 android.hardware.soundtrigger@2.0::ISoundTriggerHwCallback
diff --git a/drm/1.0/Android.bp b/drm/1.0/Android.bp
index fea851f..a950c57 100644
--- a/drm/1.0/Android.bp
+++ b/drm/1.0/Android.bp
@@ -19,4 +19,3 @@
],
gen_java: false,
}
-
diff --git a/drm/1.1/Android.bp b/drm/1.1/Android.bp
index 739b470..16010a6 100644
--- a/drm/1.1/Android.bp
+++ b/drm/1.1/Android.bp
@@ -18,4 +18,3 @@
],
gen_java: false,
}
-
diff --git a/drm/1.2/Android.bp b/drm/1.2/Android.bp
index 2d54302..9104aa9 100644
--- a/drm/1.2/Android.bp
+++ b/drm/1.2/Android.bp
@@ -21,4 +21,3 @@
],
gen_java: false,
}
-
diff --git a/dumpstate/1.0/Android.bp b/dumpstate/1.0/Android.bp
index 29be116..3d47550 100644
--- a/dumpstate/1.0/Android.bp
+++ b/dumpstate/1.0/Android.bp
@@ -14,4 +14,3 @@
],
gen_java: true,
}
-
diff --git a/fastboot/1.0/Android.bp b/fastboot/1.0/Android.bp
index ea3566f..ec447b8 100644
--- a/fastboot/1.0/Android.bp
+++ b/fastboot/1.0/Android.bp
@@ -15,4 +15,3 @@
],
gen_java: true,
}
-
diff --git a/gatekeeper/1.0/Android.bp b/gatekeeper/1.0/Android.bp
index 7eff2e8..5d63eaf 100644
--- a/gatekeeper/1.0/Android.bp
+++ b/gatekeeper/1.0/Android.bp
@@ -15,4 +15,3 @@
],
gen_java: true,
}
-
diff --git a/gatekeeper/1.0/default/OWNERS b/gatekeeper/1.0/default/OWNERS
new file mode 100644
index 0000000..335660d
--- /dev/null
+++ b/gatekeeper/1.0/default/OWNERS
@@ -0,0 +1,2 @@
+jdanis@google.com
+swillden@google.com
diff --git a/gatekeeper/1.0/default/android.hardware.gatekeeper@1.0-service.rc b/gatekeeper/1.0/default/android.hardware.gatekeeper@1.0-service.rc
index da332c7..b13a9ba 100644
--- a/gatekeeper/1.0/default/android.hardware.gatekeeper@1.0-service.rc
+++ b/gatekeeper/1.0/default/android.hardware.gatekeeper@1.0-service.rc
@@ -1,4 +1,5 @@
service vendor.gatekeeper-1-0 /vendor/bin/hw/android.hardware.gatekeeper@1.0-service
+ interface android.hardware.gatekeeper@1.0::IGatekeeper default
class hal
user system
group system
diff --git a/gatekeeper/1.0/software/Android.bp b/gatekeeper/1.0/software/Android.bp
new file mode 100644
index 0000000..148c989
--- /dev/null
+++ b/gatekeeper/1.0/software/Android.bp
@@ -0,0 +1,28 @@
+cc_binary {
+ name: "android.hardware.gatekeeper@1.0-service.software",
+ defaults: ["hidl_defaults"],
+ relative_install_path: "hw",
+ vendor: true,
+ init_rc: ["android.hardware.gatekeeper@1.0-service.software.rc"],
+
+ srcs: [
+ "service.cpp",
+ "SoftGateKeeperDevice.cpp",
+ ],
+
+ shared_libs: [
+ "android.hardware.gatekeeper@1.0",
+ "libbase",
+ "libhardware",
+ "libhidlbase",
+ "libhidltransport",
+ "libutils",
+ "liblog",
+ "libcrypto",
+ "libgatekeeper",
+ ],
+
+ static_libs: ["libscrypt_static"],
+
+ vintf_fragments: ["android.hardware.gatekeeper@1.0-service.software.xml"],
+}
diff --git a/gatekeeper/1.0/software/OWNERS b/gatekeeper/1.0/software/OWNERS
new file mode 100644
index 0000000..335660d
--- /dev/null
+++ b/gatekeeper/1.0/software/OWNERS
@@ -0,0 +1,2 @@
+jdanis@google.com
+swillden@google.com
diff --git a/gatekeeper/1.0/software/SoftGateKeeper.h b/gatekeeper/1.0/software/SoftGateKeeper.h
new file mode 100644
index 0000000..3276d1e
--- /dev/null
+++ b/gatekeeper/1.0/software/SoftGateKeeper.h
@@ -0,0 +1,171 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef SOFT_GATEKEEPER_H_
+#define SOFT_GATEKEEPER_H_
+
+extern "C" {
+#include <openssl/rand.h>
+#include <openssl/sha.h>
+
+#include <crypto_scrypt.h>
+}
+
+#include <android-base/memory.h>
+#include <gatekeeper/gatekeeper.h>
+
+#include <iostream>
+#include <memory>
+#include <unordered_map>
+
+namespace gatekeeper {
+
+struct fast_hash_t {
+ uint64_t salt;
+ uint8_t digest[SHA256_DIGEST_LENGTH];
+};
+
+class SoftGateKeeper : public GateKeeper {
+ public:
+ static const uint32_t SIGNATURE_LENGTH_BYTES = 32;
+
+ // scrypt params
+ static const uint64_t N = 16384;
+ static const uint32_t r = 8;
+ static const uint32_t p = 1;
+
+ static const int MAX_UINT_32_CHARS = 11;
+
+ SoftGateKeeper() {
+ key_.reset(new uint8_t[SIGNATURE_LENGTH_BYTES]);
+ memset(key_.get(), 0, SIGNATURE_LENGTH_BYTES);
+ }
+
+ virtual ~SoftGateKeeper() {}
+
+ virtual bool GetAuthTokenKey(const uint8_t** auth_token_key, uint32_t* length) const {
+ if (auth_token_key == NULL || length == NULL) return false;
+ *auth_token_key = key_.get();
+ *length = SIGNATURE_LENGTH_BYTES;
+ return true;
+ }
+
+ virtual void GetPasswordKey(const uint8_t** password_key, uint32_t* length) {
+ if (password_key == NULL || length == NULL) return;
+ *password_key = key_.get();
+ *length = SIGNATURE_LENGTH_BYTES;
+ }
+
+ virtual void ComputePasswordSignature(uint8_t* signature, uint32_t signature_length,
+ const uint8_t*, uint32_t, const uint8_t* password,
+ uint32_t password_length, salt_t salt) const {
+ if (signature == NULL) return;
+ crypto_scrypt(password, password_length, reinterpret_cast<uint8_t*>(&salt), sizeof(salt), N,
+ r, p, signature, signature_length);
+ }
+
+ virtual void GetRandom(void* random, uint32_t requested_length) const {
+ if (random == NULL) return;
+ RAND_pseudo_bytes((uint8_t*)random, requested_length);
+ }
+
+ virtual void ComputeSignature(uint8_t* signature, uint32_t signature_length, const uint8_t*,
+ uint32_t, const uint8_t*, const uint32_t) const {
+ if (signature == NULL) return;
+ memset(signature, 0, signature_length);
+ }
+
+ virtual uint64_t GetMillisecondsSinceBoot() const {
+ struct timespec time;
+ int res = clock_gettime(CLOCK_BOOTTIME, &time);
+ if (res < 0) return 0;
+ return (time.tv_sec * 1000) + (time.tv_nsec / 1000 / 1000);
+ }
+
+ virtual bool IsHardwareBacked() const { return false; }
+
+ virtual bool GetFailureRecord(uint32_t uid, secure_id_t user_id, failure_record_t* record,
+ bool /* secure */) {
+ failure_record_t* stored = &failure_map_[uid];
+ if (user_id != stored->secure_user_id) {
+ stored->secure_user_id = user_id;
+ stored->last_checked_timestamp = 0;
+ stored->failure_counter = 0;
+ }
+ memcpy(record, stored, sizeof(*record));
+ return true;
+ }
+
+ virtual bool ClearFailureRecord(uint32_t uid, secure_id_t user_id, bool /* secure */) {
+ failure_record_t* stored = &failure_map_[uid];
+ stored->secure_user_id = user_id;
+ stored->last_checked_timestamp = 0;
+ stored->failure_counter = 0;
+ return true;
+ }
+
+ virtual bool WriteFailureRecord(uint32_t uid, failure_record_t* record, bool /* secure */) {
+ failure_map_[uid] = *record;
+ return true;
+ }
+
+ fast_hash_t ComputeFastHash(const SizedBuffer& password, uint64_t salt) {
+ fast_hash_t fast_hash;
+ size_t digest_size = password.size() + sizeof(salt);
+ std::unique_ptr<uint8_t[]> digest(new uint8_t[digest_size]);
+ memcpy(digest.get(), &salt, sizeof(salt));
+ memcpy(digest.get() + sizeof(salt), password.Data<uint8_t>(), password.size());
+
+ SHA256(digest.get(), digest_size, (uint8_t*)&fast_hash.digest);
+
+ fast_hash.salt = salt;
+ return fast_hash;
+ }
+
+ bool VerifyFast(const fast_hash_t& fast_hash, const SizedBuffer& password) {
+ fast_hash_t computed = ComputeFastHash(password, fast_hash.salt);
+ return memcmp(computed.digest, fast_hash.digest, SHA256_DIGEST_LENGTH) == 0;
+ }
+
+ bool DoVerify(const password_handle_t* expected_handle, const SizedBuffer& password) {
+ uint64_t user_id = android::base::get_unaligned<secure_id_t>(&expected_handle->user_id);
+ FastHashMap::const_iterator it = fast_hash_map_.find(user_id);
+ if (it != fast_hash_map_.end() && VerifyFast(it->second, password)) {
+ return true;
+ } else {
+ if (GateKeeper::DoVerify(expected_handle, password)) {
+ uint64_t salt;
+ GetRandom(&salt, sizeof(salt));
+ fast_hash_map_[user_id] = ComputeFastHash(password, salt);
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private:
+ typedef std::unordered_map<uint32_t, failure_record_t> FailureRecordMap;
+ typedef std::unordered_map<uint64_t, fast_hash_t> FastHashMap;
+
+ std::unique_ptr<uint8_t[]> key_;
+ FailureRecordMap failure_map_;
+ FastHashMap fast_hash_map_;
+};
+} // namespace gatekeeper
+
+#endif // SOFT_GATEKEEPER_H_
diff --git a/gatekeeper/1.0/software/SoftGateKeeperDevice.cpp b/gatekeeper/1.0/software/SoftGateKeeperDevice.cpp
new file mode 100644
index 0000000..d7a0b46
--- /dev/null
+++ b/gatekeeper/1.0/software/SoftGateKeeperDevice.cpp
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2015 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 "SoftGateKeeperDevice.h"
+#include "SoftGateKeeper.h"
+
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::gatekeeper::V1_0::GatekeeperStatusCode;
+using ::gatekeeper::EnrollRequest;
+using ::gatekeeper::EnrollResponse;
+using ::gatekeeper::ERROR_INVALID;
+using ::gatekeeper::ERROR_MEMORY_ALLOCATION_FAILED;
+using ::gatekeeper::ERROR_NONE;
+using ::gatekeeper::ERROR_RETRY;
+using ::gatekeeper::SizedBuffer;
+using ::gatekeeper::VerifyRequest;
+using ::gatekeeper::VerifyResponse;
+
+#include <limits>
+
+namespace android {
+
+inline SizedBuffer hidl_vec2sized_buffer(const hidl_vec<uint8_t>& vec) {
+ if (vec.size() == 0 || vec.size() > std::numeric_limits<uint32_t>::max()) return {};
+ auto dummy = new uint8_t[vec.size()];
+ std::copy(vec.begin(), vec.end(), dummy);
+ return {dummy, static_cast<uint32_t>(vec.size())};
+}
+
+Return<void> SoftGateKeeperDevice::enroll(uint32_t uid,
+ const hidl_vec<uint8_t>& currentPasswordHandle,
+ const hidl_vec<uint8_t>& currentPassword,
+ const hidl_vec<uint8_t>& desiredPassword,
+ enroll_cb _hidl_cb) {
+ if (desiredPassword.size() == 0) {
+ _hidl_cb({GatekeeperStatusCode::ERROR_GENERAL_FAILURE, 0, {}});
+ return {};
+ }
+
+ EnrollRequest request(uid, hidl_vec2sized_buffer(currentPasswordHandle),
+ hidl_vec2sized_buffer(desiredPassword),
+ hidl_vec2sized_buffer(currentPassword));
+ EnrollResponse response;
+ impl_->Enroll(request, &response);
+
+ if (response.error == ERROR_RETRY) {
+ _hidl_cb({GatekeeperStatusCode::ERROR_RETRY_TIMEOUT, response.retry_timeout, {}});
+ } else if (response.error != ERROR_NONE) {
+ _hidl_cb({GatekeeperStatusCode::ERROR_GENERAL_FAILURE, 0, {}});
+ } else {
+ hidl_vec<uint8_t> new_handle(response.enrolled_password_handle.Data<uint8_t>(),
+ response.enrolled_password_handle.Data<uint8_t>() +
+ response.enrolled_password_handle.size());
+ _hidl_cb({GatekeeperStatusCode::STATUS_OK, response.retry_timeout, new_handle});
+ }
+ return {};
+}
+
+Return<void> SoftGateKeeperDevice::verify(
+ uint32_t uid, uint64_t challenge,
+ const ::android::hardware::hidl_vec<uint8_t>& enrolledPasswordHandle,
+ const ::android::hardware::hidl_vec<uint8_t>& providedPassword, verify_cb _hidl_cb) {
+ if (enrolledPasswordHandle.size() == 0) {
+ _hidl_cb({GatekeeperStatusCode::ERROR_GENERAL_FAILURE, 0, {}});
+ return {};
+ }
+
+ VerifyRequest request(uid, challenge, hidl_vec2sized_buffer(enrolledPasswordHandle),
+ hidl_vec2sized_buffer(providedPassword));
+ VerifyResponse response;
+
+ impl_->Verify(request, &response);
+
+ if (response.error == ERROR_RETRY) {
+ _hidl_cb({GatekeeperStatusCode::ERROR_RETRY_TIMEOUT, response.retry_timeout, {}});
+ } else if (response.error != ERROR_NONE) {
+ _hidl_cb({GatekeeperStatusCode::ERROR_GENERAL_FAILURE, 0, {}});
+ } else {
+ hidl_vec<uint8_t> auth_token(
+ response.auth_token.Data<uint8_t>(),
+ response.auth_token.Data<uint8_t>() + response.auth_token.size());
+
+ _hidl_cb({response.request_reenroll ? GatekeeperStatusCode::STATUS_REENROLL
+ : GatekeeperStatusCode::STATUS_OK,
+ response.retry_timeout, auth_token});
+ }
+ return {};
+}
+
+Return<void> SoftGateKeeperDevice::deleteUser(uint32_t /*uid*/, deleteUser_cb _hidl_cb) {
+ _hidl_cb({GatekeeperStatusCode::ERROR_NOT_IMPLEMENTED, 0, {}});
+ return {};
+}
+
+Return<void> SoftGateKeeperDevice::deleteAllUsers(deleteAllUsers_cb _hidl_cb) {
+ _hidl_cb({GatekeeperStatusCode::ERROR_NOT_IMPLEMENTED, 0, {}});
+ return {};
+}
+
+} // namespace android
diff --git a/gatekeeper/1.0/software/SoftGateKeeperDevice.h b/gatekeeper/1.0/software/SoftGateKeeperDevice.h
new file mode 100644
index 0000000..17b474e
--- /dev/null
+++ b/gatekeeper/1.0/software/SoftGateKeeperDevice.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SOFT_GATEKEEPER_DEVICE_H_
+#define SOFT_GATEKEEPER_DEVICE_H_
+
+#include <android/hardware/gatekeeper/1.0/IGatekeeper.h>
+#include <hidl/Status.h>
+
+#include <memory>
+#include "SoftGateKeeper.h"
+
+namespace android {
+
+/**
+ * Software based GateKeeper implementation
+ */
+class SoftGateKeeperDevice : public ::android::hardware::gatekeeper::V1_0::IGatekeeper {
+ public:
+ SoftGateKeeperDevice() { impl_.reset(new ::gatekeeper::SoftGateKeeper()); }
+
+ // Wrappers to translate the gatekeeper HAL API to the Kegyuard Messages API.
+
+ /**
+ * Enrolls password_payload, which should be derived from a user selected pin or password,
+ * with the authentication factor private key used only for enrolling authentication
+ * factor data.
+ *
+ * Returns: 0 on success or an error code less than 0 on error.
+ * On error, enrolled_password_handle will not be allocated.
+ */
+ ::android::hardware::Return<void> enroll(
+ uint32_t uid, const ::android::hardware::hidl_vec<uint8_t>& currentPasswordHandle,
+ const ::android::hardware::hidl_vec<uint8_t>& currentPassword,
+ const ::android::hardware::hidl_vec<uint8_t>& desiredPassword,
+ enroll_cb _hidl_cb) override;
+
+ /**
+ * Verifies provided_password matches enrolled_password_handle.
+ *
+ * Implementations of this module may retain the result of this call
+ * to attest to the recency of authentication.
+ *
+ * On success, writes the address of a verification token to auth_token,
+ * usable to attest password verification to other trusted services. Clients
+ * may pass NULL for this value.
+ *
+ * Returns: 0 on success or an error code less than 0 on error
+ * On error, verification token will not be allocated
+ */
+ ::android::hardware::Return<void> verify(
+ uint32_t uid, uint64_t challenge,
+ const ::android::hardware::hidl_vec<uint8_t>& enrolledPasswordHandle,
+ const ::android::hardware::hidl_vec<uint8_t>& providedPassword,
+ verify_cb _hidl_cb) override;
+
+ ::android::hardware::Return<void> deleteUser(uint32_t uid, deleteUser_cb _hidl_cb) override;
+
+ ::android::hardware::Return<void> deleteAllUsers(deleteAllUsers_cb _hidl_cb) override;
+
+ private:
+ std::unique_ptr<::gatekeeper::SoftGateKeeper> impl_;
+};
+
+} // namespace android
+
+#endif // SOFT_GATEKEEPER_DEVICE_H_
diff --git a/gatekeeper/1.0/software/android.hardware.gatekeeper@1.0-service.software.rc b/gatekeeper/1.0/software/android.hardware.gatekeeper@1.0-service.software.rc
new file mode 100644
index 0000000..60cb96c
--- /dev/null
+++ b/gatekeeper/1.0/software/android.hardware.gatekeeper@1.0-service.software.rc
@@ -0,0 +1,4 @@
+service vendor.gatekeeper-1-0 /vendor/bin/hw/android.hardware.gatekeeper@1.0-service.software
+ class hal
+ user system
+ group system
diff --git a/gatekeeper/1.0/software/android.hardware.gatekeeper@1.0-service.software.xml b/gatekeeper/1.0/software/android.hardware.gatekeeper@1.0-service.software.xml
new file mode 100644
index 0000000..19714a8
--- /dev/null
+++ b/gatekeeper/1.0/software/android.hardware.gatekeeper@1.0-service.software.xml
@@ -0,0 +1,11 @@
+<manifest version="1.0" type="device">
+ <hal format="hidl">
+ <name>android.hardware.gatekeeper</name>
+ <transport>hwbinder</transport>
+ <version>1.0</version>
+ <interface>
+ <name>IGatekeeper</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+</manifest>
diff --git a/gatekeeper/1.0/software/service.cpp b/gatekeeper/1.0/software/service.cpp
new file mode 100644
index 0000000..a48a964
--- /dev/null
+++ b/gatekeeper/1.0/software/service.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define LOG_TAG "android.hardware.gatekeeper@1.0-service"
+
+#include <android-base/logging.h>
+#include <android/hardware/gatekeeper/1.0/IGatekeeper.h>
+
+#include <hidl/LegacySupport.h>
+
+#include "SoftGateKeeperDevice.h"
+
+// Generated HIDL files
+using android::SoftGateKeeperDevice;
+using android::hardware::gatekeeper::V1_0::IGatekeeper;
+
+int main() {
+ ::android::hardware::configureRpcThreadpool(1, true /* willJoinThreadpool */);
+ android::sp<SoftGateKeeperDevice> gatekeeper(new SoftGateKeeperDevice());
+ auto status = gatekeeper->registerAsService();
+ if (status != android::OK) {
+ LOG(FATAL) << "Could not register service for Gatekeeper 1.0 (software) (" << status << ")";
+ }
+
+ android::hardware::joinRpcThreadpool();
+ return -1; // Should never get here.
+}
diff --git a/gatekeeper/1.0/software/tests/Android.bp b/gatekeeper/1.0/software/tests/Android.bp
new file mode 100644
index 0000000..3f0300d
--- /dev/null
+++ b/gatekeeper/1.0/software/tests/Android.bp
@@ -0,0 +1,34 @@
+//
+// Copyright (C) 2015 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+cc_test {
+ name: "gatekeeper-software-device-unit-tests",
+
+ cflags: [
+ "-g",
+ "-Wall",
+ "-Werror",
+ "-Wno-missing-field-initializers",
+ ],
+ shared_libs: [
+ "libgatekeeper",
+ "libcrypto",
+ "libbase",
+ ],
+ static_libs: ["libscrypt_static"],
+
+ srcs: ["gatekeeper_test.cpp"],
+}
diff --git a/gatekeeper/1.0/software/tests/gatekeeper_test.cpp b/gatekeeper/1.0/software/tests/gatekeeper_test.cpp
new file mode 100644
index 0000000..bf4a8bc
--- /dev/null
+++ b/gatekeeper/1.0/software/tests/gatekeeper_test.cpp
@@ -0,0 +1,178 @@
+/*
+ * Copyright 2015 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 <arpa/inet.h>
+#include <iostream>
+
+#include <gtest/gtest.h>
+#include <hardware/hw_auth_token.h>
+
+#include "../SoftGateKeeper.h"
+
+using ::gatekeeper::EnrollRequest;
+using ::gatekeeper::EnrollResponse;
+using ::gatekeeper::secure_id_t;
+using ::gatekeeper::SizedBuffer;
+using ::gatekeeper::SoftGateKeeper;
+using ::gatekeeper::VerifyRequest;
+using ::gatekeeper::VerifyResponse;
+using ::testing::Test;
+
+static SizedBuffer makePasswordBuffer(int init = 0) {
+ constexpr const uint32_t pw_buffer_size = 16;
+ auto pw_buffer = new uint8_t[pw_buffer_size];
+ memset(pw_buffer, init, pw_buffer_size);
+
+ return {pw_buffer, pw_buffer_size};
+}
+
+static SizedBuffer makeAndInitializeSizedBuffer(const uint8_t* data, uint32_t size) {
+ auto buffer = new uint8_t[size];
+ memcpy(buffer, data, size);
+ return {buffer, size};
+}
+
+static SizedBuffer copySizedBuffer(const SizedBuffer& rhs) {
+ return makeAndInitializeSizedBuffer(rhs.Data<uint8_t>(), rhs.size());
+}
+
+static void do_enroll(SoftGateKeeper& gatekeeper, EnrollResponse* response) {
+ EnrollRequest request(0, {}, makePasswordBuffer(), {});
+
+ gatekeeper.Enroll(request, response);
+}
+
+TEST(GateKeeperTest, EnrollSuccess) {
+ SoftGateKeeper gatekeeper;
+ EnrollResponse response;
+ do_enroll(gatekeeper, &response);
+ ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_NONE, response.error);
+}
+
+TEST(GateKeeperTest, EnrollBogusData) {
+ SoftGateKeeper gatekeeper;
+ EnrollResponse response;
+
+ EnrollRequest request(0, {}, {}, {});
+
+ gatekeeper.Enroll(request, &response);
+
+ ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_INVALID, response.error);
+}
+
+TEST(GateKeeperTest, VerifySuccess) {
+ SoftGateKeeper gatekeeper;
+ EnrollResponse enroll_response;
+
+ do_enroll(gatekeeper, &enroll_response);
+ ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_NONE, enroll_response.error);
+ VerifyRequest request(0, 1, std::move(enroll_response.enrolled_password_handle),
+ makePasswordBuffer());
+ VerifyResponse response;
+
+ gatekeeper.Verify(request, &response);
+
+ ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_NONE, response.error);
+
+ auto auth_token = response.auth_token.Data<hw_auth_token_t>();
+
+ ASSERT_NE(nullptr, auth_token);
+ ASSERT_EQ((uint32_t)HW_AUTH_PASSWORD, ntohl(auth_token->authenticator_type));
+ ASSERT_EQ((uint64_t)1, auth_token->challenge);
+ ASSERT_NE(~((uint32_t)0), auth_token->timestamp);
+ ASSERT_NE((uint64_t)0, auth_token->user_id);
+ ASSERT_NE((uint64_t)0, auth_token->authenticator_id);
+}
+
+TEST(GateKeeperTest, TrustedReEnroll) {
+ SoftGateKeeper gatekeeper;
+ EnrollResponse enroll_response;
+
+ // do_enroll enrolls an all 0 password
+ do_enroll(gatekeeper, &enroll_response);
+ ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_NONE, enroll_response.error);
+
+ // verify first password
+ VerifyRequest request(0, 0, copySizedBuffer(enroll_response.enrolled_password_handle),
+ makePasswordBuffer());
+ VerifyResponse response;
+ gatekeeper.Verify(request, &response);
+ ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_NONE, response.error);
+ auto auth_token = response.auth_token.Data<hw_auth_token_t>();
+ ASSERT_NE(nullptr, auth_token);
+
+ secure_id_t secure_id = auth_token->user_id;
+
+ // enroll new password
+ EnrollRequest enroll_request(0, std::move(enroll_response.enrolled_password_handle),
+ makePasswordBuffer(1) /* new password */,
+ makePasswordBuffer() /* old password */);
+ gatekeeper.Enroll(enroll_request, &enroll_response);
+ ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_NONE, enroll_response.error);
+
+ // verify new password
+ VerifyRequest new_request(0, 0, std::move(enroll_response.enrolled_password_handle),
+ makePasswordBuffer(1));
+ gatekeeper.Verify(new_request, &response);
+ ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_NONE, response.error);
+ ASSERT_NE(nullptr, response.auth_token.Data<hw_auth_token_t>());
+ ASSERT_EQ(secure_id, response.auth_token.Data<hw_auth_token_t>()->user_id);
+}
+
+TEST(GateKeeperTest, UntrustedReEnroll) {
+ SoftGateKeeper gatekeeper;
+ SizedBuffer provided_password;
+ EnrollResponse enroll_response;
+
+ // do_enroll enrolls an all 0 password
+ provided_password = makePasswordBuffer();
+ do_enroll(gatekeeper, &enroll_response);
+ ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_NONE, enroll_response.error);
+
+ // verify first password
+ VerifyRequest request(0, 0, std::move(enroll_response.enrolled_password_handle),
+ std::move(provided_password));
+ VerifyResponse response;
+ gatekeeper.Verify(request, &response);
+ ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_NONE, response.error);
+ auto auth_token = response.auth_token.Data<hw_auth_token_t>();
+ ASSERT_NE(nullptr, auth_token);
+
+ secure_id_t secure_id = auth_token->user_id;
+
+ EnrollRequest enroll_request(0, {}, makePasswordBuffer(1), {});
+ gatekeeper.Enroll(enroll_request, &enroll_response);
+ ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_NONE, enroll_response.error);
+
+ // verify new password
+ VerifyRequest new_request(0, 0, std::move(enroll_response.enrolled_password_handle),
+ makePasswordBuffer(1));
+ gatekeeper.Verify(new_request, &response);
+ ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_NONE, response.error);
+ ASSERT_NE(nullptr, response.auth_token.Data<hw_auth_token_t>());
+ ASSERT_NE(secure_id, response.auth_token.Data<hw_auth_token_t>()->user_id);
+}
+
+TEST(GateKeeperTest, VerifyBogusData) {
+ SoftGateKeeper gatekeeper;
+ VerifyResponse response;
+
+ VerifyRequest request(0, 0, {}, {});
+
+ gatekeeper.Verify(request, &response);
+
+ ASSERT_EQ(::gatekeeper::gatekeeper_error_t::ERROR_INVALID, response.error);
+}
diff --git a/gatekeeper/1.0/vts/OWNERS b/gatekeeper/1.0/vts/OWNERS
new file mode 100644
index 0000000..738c710
--- /dev/null
+++ b/gatekeeper/1.0/vts/OWNERS
@@ -0,0 +1,3 @@
+jdanis@google.com
+swillden@google.com
+guangzhu@google.com
diff --git a/gnss/1.0/Android.bp b/gnss/1.0/Android.bp
index 2e3e6fd..d97588c 100644
--- a/gnss/1.0/Android.bp
+++ b/gnss/1.0/Android.bp
@@ -35,4 +35,3 @@
gen_java: true,
gen_java_constants: true,
}
-
diff --git a/gnss/1.0/default/android.hardware.gnss@1.0-service.rc b/gnss/1.0/default/android.hardware.gnss@1.0-service.rc
index 1a44d34..1300d81 100644
--- a/gnss/1.0/default/android.hardware.gnss@1.0-service.rc
+++ b/gnss/1.0/default/android.hardware.gnss@1.0-service.rc
@@ -1,4 +1,5 @@
service vendor.gnss_service /vendor/bin/hw/android.hardware.gnss@1.0-service
+ interface android.hardware.gnss@1.0::IGnss default
class hal
user gps
group system gps radio
diff --git a/gnss/1.1/Android.bp b/gnss/1.1/Android.bp
index 4ae4439..5294a6b 100644
--- a/gnss/1.1/Android.bp
+++ b/gnss/1.1/Android.bp
@@ -19,4 +19,3 @@
],
gen_java: true,
}
-
diff --git a/gnss/1.1/default/android.hardware.gnss@1.1-service.rc b/gnss/1.1/default/android.hardware.gnss@1.1-service.rc
index 0cf7c49..73901bf 100644
--- a/gnss/1.1/default/android.hardware.gnss@1.1-service.rc
+++ b/gnss/1.1/default/android.hardware.gnss@1.1-service.rc
@@ -1,4 +1,6 @@
service gnss-1-1 /vendor/bin/hw/android.hardware.gnss@1.1-service
+ interface android.hardware.gnss@1.0::IGnss default
+ interface android.hardware.gnss@1.1::IGnss default
class hal
user system
group system
diff --git a/gnss/2.0/Android.bp b/gnss/2.0/Android.bp
index 6cfd346..db5075f 100644
--- a/gnss/2.0/Android.bp
+++ b/gnss/2.0/Android.bp
@@ -30,4 +30,3 @@
gen_java: true,
gen_java_constants: true,
}
-
diff --git a/gnss/measurement_corrections/1.0/Android.bp b/gnss/measurement_corrections/1.0/Android.bp
index 456b55c..837cc7a 100644
--- a/gnss/measurement_corrections/1.0/Android.bp
+++ b/gnss/measurement_corrections/1.0/Android.bp
@@ -17,4 +17,3 @@
],
gen_java: true,
}
-
diff --git a/gnss/visibility_control/1.0/Android.bp b/gnss/visibility_control/1.0/Android.bp
index 40a28c9..e58e932 100644
--- a/gnss/visibility_control/1.0/Android.bp
+++ b/gnss/visibility_control/1.0/Android.bp
@@ -15,4 +15,3 @@
],
gen_java: true,
}
-
diff --git a/graphics/allocator/2.0/Android.bp b/graphics/allocator/2.0/Android.bp
index 50b474e..37d9dfc 100644
--- a/graphics/allocator/2.0/Android.bp
+++ b/graphics/allocator/2.0/Android.bp
@@ -16,4 +16,3 @@
],
gen_java: false,
}
-
diff --git a/graphics/allocator/2.0/default/android.hardware.graphics.allocator@2.0-service.rc b/graphics/allocator/2.0/default/android.hardware.graphics.allocator@2.0-service.rc
index a2a881a..038e87c 100644
--- a/graphics/allocator/2.0/default/android.hardware.graphics.allocator@2.0-service.rc
+++ b/graphics/allocator/2.0/default/android.hardware.graphics.allocator@2.0-service.rc
@@ -1,4 +1,5 @@
service vendor.gralloc-2-0 /vendor/bin/hw/android.hardware.graphics.allocator@2.0-service
+ interface android.hardware.graphics.allocator@2.0::IAllocator default
class hal animation
interface android.hardware.graphics.allocator@2.0::IAllocator default
user system
diff --git a/graphics/allocator/3.0/Android.bp b/graphics/allocator/3.0/Android.bp
index fa3e2ce..2cfa1d0 100644
--- a/graphics/allocator/3.0/Android.bp
+++ b/graphics/allocator/3.0/Android.bp
@@ -18,4 +18,3 @@
],
gen_java: false,
}
-
diff --git a/graphics/bufferqueue/1.0/Android.bp b/graphics/bufferqueue/1.0/Android.bp
index e23ca59..7fca354 100644
--- a/graphics/bufferqueue/1.0/Android.bp
+++ b/graphics/bufferqueue/1.0/Android.bp
@@ -17,4 +17,3 @@
],
gen_java: true,
}
-
diff --git a/graphics/bufferqueue/2.0/Android.bp b/graphics/bufferqueue/2.0/Android.bp
index 97c05fa..fd08079 100644
--- a/graphics/bufferqueue/2.0/Android.bp
+++ b/graphics/bufferqueue/2.0/Android.bp
@@ -19,4 +19,3 @@
],
gen_java: true,
}
-
diff --git a/graphics/common/1.0/Android.bp b/graphics/common/1.0/Android.bp
index 175166d..089fe14 100644
--- a/graphics/common/1.0/Android.bp
+++ b/graphics/common/1.0/Android.bp
@@ -13,4 +13,3 @@
gen_java: true,
gen_java_constants: true,
}
-
diff --git a/graphics/common/1.1/Android.bp b/graphics/common/1.1/Android.bp
index 0647d12d..899fe03 100644
--- a/graphics/common/1.1/Android.bp
+++ b/graphics/common/1.1/Android.bp
@@ -16,4 +16,3 @@
gen_java: true,
gen_java_constants: true,
}
-
diff --git a/graphics/common/1.2/Android.bp b/graphics/common/1.2/Android.bp
index 088bc37..2c4d93b 100644
--- a/graphics/common/1.2/Android.bp
+++ b/graphics/common/1.2/Android.bp
@@ -17,4 +17,3 @@
gen_java: true,
gen_java_constants: true,
}
-
diff --git a/graphics/composer/2.1/Android.bp b/graphics/composer/2.1/Android.bp
index 38786fd..4e4b81c 100644
--- a/graphics/composer/2.1/Android.bp
+++ b/graphics/composer/2.1/Android.bp
@@ -18,4 +18,3 @@
],
gen_java: false,
}
-
diff --git a/graphics/composer/2.1/default/android.hardware.graphics.composer@2.1-service.rc b/graphics/composer/2.1/default/android.hardware.graphics.composer@2.1-service.rc
index 5a5b51e..cbd589a 100644
--- a/graphics/composer/2.1/default/android.hardware.graphics.composer@2.1-service.rc
+++ b/graphics/composer/2.1/default/android.hardware.graphics.composer@2.1-service.rc
@@ -1,4 +1,5 @@
service vendor.hwcomposer-2-1 /vendor/bin/hw/android.hardware.graphics.composer@2.1-service
+ interface android.hardware.graphics.composer@2.1::IComposer default
class hal animation
user system
group graphics drmrpc
diff --git a/graphics/composer/2.1/utils/hwc2on1adapter/Android.bp b/graphics/composer/2.1/utils/hwc2on1adapter/Android.bp
index 420a1f6..062f2e5 100644
--- a/graphics/composer/2.1/utils/hwc2on1adapter/Android.bp
+++ b/graphics/composer/2.1/utils/hwc2on1adapter/Android.bp
@@ -20,7 +20,6 @@
cflags: [
"-Wall",
"-Werror",
- "-Wno-user-defined-warnings",
],
cppflags: [
"-Weverything",
diff --git a/graphics/composer/2.2/Android.bp b/graphics/composer/2.2/Android.bp
index fe71e9e..930cadc 100644
--- a/graphics/composer/2.2/Android.bp
+++ b/graphics/composer/2.2/Android.bp
@@ -18,4 +18,3 @@
],
gen_java: false,
}
-
diff --git a/graphics/composer/2.2/default/android.hardware.graphics.composer@2.2-service.rc b/graphics/composer/2.2/default/android.hardware.graphics.composer@2.2-service.rc
index efe6dad..0d7e86f 100644
--- a/graphics/composer/2.2/default/android.hardware.graphics.composer@2.2-service.rc
+++ b/graphics/composer/2.2/default/android.hardware.graphics.composer@2.2-service.rc
@@ -1,4 +1,6 @@
service vendor.hwcomposer-2-2 /vendor/bin/hw/android.hardware.graphics.composer@2.2-service
+ interface android.hardware.graphics.composer@2.1::IComposer default
+ interface android.hardware.graphics.composer@2.2::IComposer default
class hal animation
user system
group graphics drmrpc
diff --git a/graphics/composer/2.3/Android.bp b/graphics/composer/2.3/Android.bp
index 6d29348..a777556 100644
--- a/graphics/composer/2.3/Android.bp
+++ b/graphics/composer/2.3/Android.bp
@@ -20,4 +20,3 @@
],
gen_java: false,
}
-
diff --git a/graphics/mapper/2.0/Android.bp b/graphics/mapper/2.0/Android.bp
index 96e812b..4459bdc 100644
--- a/graphics/mapper/2.0/Android.bp
+++ b/graphics/mapper/2.0/Android.bp
@@ -17,4 +17,3 @@
],
gen_java: false,
}
-
diff --git a/graphics/mapper/2.1/Android.bp b/graphics/mapper/2.1/Android.bp
index 8527d3d..e5a5ae4 100644
--- a/graphics/mapper/2.1/Android.bp
+++ b/graphics/mapper/2.1/Android.bp
@@ -18,4 +18,3 @@
],
gen_java: false,
}
-
diff --git a/graphics/mapper/3.0/Android.bp b/graphics/mapper/3.0/Android.bp
index e348296..a143243 100644
--- a/graphics/mapper/3.0/Android.bp
+++ b/graphics/mapper/3.0/Android.bp
@@ -19,4 +19,3 @@
],
gen_java: false,
}
-
diff --git a/health/1.0/Android.bp b/health/1.0/Android.bp
index e03b142..ea6b0c8 100644
--- a/health/1.0/Android.bp
+++ b/health/1.0/Android.bp
@@ -16,4 +16,3 @@
gen_java: true,
gen_java_constants: true,
}
-
diff --git a/health/2.0/Android.bp b/health/2.0/Android.bp
index f472b27..b8323b6 100644
--- a/health/2.0/Android.bp
+++ b/health/2.0/Android.bp
@@ -17,4 +17,3 @@
],
gen_java: true,
}
-
diff --git a/health/storage/1.0/Android.bp b/health/storage/1.0/Android.bp
index 45fa01f..e4620f8 100644
--- a/health/storage/1.0/Android.bp
+++ b/health/storage/1.0/Android.bp
@@ -16,4 +16,3 @@
],
gen_java: true,
}
-
diff --git a/input/classifier/1.0/Android.bp b/input/classifier/1.0/Android.bp
index 6815a51..11e0f52 100644
--- a/input/classifier/1.0/Android.bp
+++ b/input/classifier/1.0/Android.bp
@@ -15,4 +15,3 @@
],
gen_java: true,
}
-
diff --git a/input/common/1.0/Android.bp b/input/common/1.0/Android.bp
index 07b38cf..2c7c517 100644
--- a/input/common/1.0/Android.bp
+++ b/input/common/1.0/Android.bp
@@ -11,4 +11,3 @@
],
gen_java: true,
}
-
diff --git a/ir/1.0/Android.bp b/ir/1.0/Android.bp
index 5f25172..5fca96d 100644
--- a/ir/1.0/Android.bp
+++ b/ir/1.0/Android.bp
@@ -15,4 +15,3 @@
],
gen_java: true,
}
-
diff --git a/ir/1.0/default/android.hardware.ir@1.0-service.rc b/ir/1.0/default/android.hardware.ir@1.0-service.rc
index 0d06967..b2f1f7d 100644
--- a/ir/1.0/default/android.hardware.ir@1.0-service.rc
+++ b/ir/1.0/default/android.hardware.ir@1.0-service.rc
@@ -1,4 +1,5 @@
service vendor.ir-hal-1-0 /vendor/bin/hw/android.hardware.ir@1.0-service
+ interface android.hardware.ir@1.0::IConsumerIr default
class hal
user system
group system
diff --git a/keymaster/3.0/Android.bp b/keymaster/3.0/Android.bp
index ca17a9b..0fdc32c 100644
--- a/keymaster/3.0/Android.bp
+++ b/keymaster/3.0/Android.bp
@@ -15,4 +15,3 @@
],
gen_java: false,
}
-
diff --git a/keymaster/3.0/default/android.hardware.keymaster@3.0-service.rc b/keymaster/3.0/default/android.hardware.keymaster@3.0-service.rc
index ea8d490..dffaca5 100644
--- a/keymaster/3.0/default/android.hardware.keymaster@3.0-service.rc
+++ b/keymaster/3.0/default/android.hardware.keymaster@3.0-service.rc
@@ -1,4 +1,5 @@
service vendor.keymaster-3-0 /vendor/bin/hw/android.hardware.keymaster@3.0-service
+ interface android.hardware.keymaster@3.0::IKeymasterDevice default
class early_hal
user nobody
group drmrpc
diff --git a/keymaster/4.0/Android.bp b/keymaster/4.0/Android.bp
index cd46fd9..ea328f4 100644
--- a/keymaster/4.0/Android.bp
+++ b/keymaster/4.0/Android.bp
@@ -16,4 +16,3 @@
],
gen_java: false,
}
-
diff --git a/keymaster/4.0/IKeymasterDevice.hal b/keymaster/4.0/IKeymasterDevice.hal
index c867ab0..3475f79 100644
--- a/keymaster/4.0/IKeymasterDevice.hal
+++ b/keymaster/4.0/IKeymasterDevice.hal
@@ -624,7 +624,7 @@
/**
* Exports a public key, returning the key in the specified format.
*
- * @parm keyFormat The format used for export. See KeyFormat in types.hal.
+ * @parm keyFormat The format used for export. Must be KeyFormat::X509.
*
* @param keyBlob The opaque descriptor returned by generateKey() or importKey(). The
* referenced key must be asymmetric.
@@ -639,7 +639,7 @@
* value, it must be computationally infeasible for the secure hardware to obtain the key
* material.
*
- * @return keyMaterial The public key material in PKCS#8 format.
+ * @return keyMaterial The public key material in X.509 format.
*/
exportKey(KeyFormat keyFormat, vec<uint8_t> keyBlob, vec<uint8_t> clientId,
vec<uint8_t> appData) generates (ErrorCode error, vec<uint8_t> keyMaterial);
@@ -1005,13 +1005,11 @@
*
* -- EC Keys --
*
- * EC key operations must specify exactly one padding mode in inParams. If unspecified or
- * specified more than once, begin() must return ErrorCode::UNSUPPORTED_PADDING_MODE.
- *
- * Private key operations (KeyPurpose::SIGN) need authorization of digest and padding, which
- * means that the key authorizations must contain the specified values. If not, begin() must
- * return ErrorCode::INCOMPATIBLE_DIGEST. Public key operations (KeyPurpose::VERIFY) are
- * permitted with unauthorized digest or padding.
+ * EC private key operations must specify exactly one digest in inParams. If unspecified or
+ * specified more than once, begin() must return ErrorCode::UNSUPPORTED_DIGEST. For private key
+ * operations, (KeyPurpose::SIGN), if the specified digest is not in the key's authorization
+ * list, begin() must return ErrorCode::INCOMPATIBLE_DIGEST. Public key operations
+ * (KeyPurpose::VERIFY) are permitted with unauthorized digest.
*
* -- AES Keys --
*
diff --git a/keymaster/4.0/default/android.hardware.keymaster@4.0-service.rc b/keymaster/4.0/default/android.hardware.keymaster@4.0-service.rc
index 2ce439e..2adfd88 100644
--- a/keymaster/4.0/default/android.hardware.keymaster@4.0-service.rc
+++ b/keymaster/4.0/default/android.hardware.keymaster@4.0-service.rc
@@ -1,4 +1,5 @@
service vendor.keymaster-4-0 /vendor/bin/hw/android.hardware.keymaster@4.0-service
+ interface android.hardware.keymaster@4.0::IKeymasterDevice default
class early_hal
user system
group system drmrpc
diff --git a/keymaster/4.0/support/Keymaster.cpp b/keymaster/4.0/support/Keymaster.cpp
index e8db074..1eb9a68 100644
--- a/keymaster/4.0/support/Keymaster.cpp
+++ b/keymaster/4.0/support/Keymaster.cpp
@@ -19,7 +19,7 @@
#include <iomanip>
#include <android-base/logging.h>
-#include <android/hidl/manager/1.0/IServiceManager.h>
+#include <android/hidl/manager/1.2/IServiceManager.h>
#include <keymasterV4_0/Keymaster3.h>
#include <keymasterV4_0/Keymaster4.h>
#include <keymasterV4_0/key_param_output.h>
@@ -69,7 +69,7 @@
namespace support {
using ::android::sp;
-using ::android::hidl::manager::V1_0::IServiceManager;
+using ::android::hidl::manager::V1_2::IServiceManager;
std::ostream& operator<<(std::ostream& os, const Keymaster& keymaster) {
auto& version = keymaster.halVersion();
@@ -86,7 +86,7 @@
bool foundDefault = false;
auto& descriptor = Wrapper::WrappedIKeymasterDevice::descriptor;
- serviceManager->listByInterface(descriptor, [&](const hidl_vec<hidl_string>& names) {
+ serviceManager->listManifestByInterface(descriptor, [&](const hidl_vec<hidl_string>& names) {
for (auto& name : names) {
if (name == "default") foundDefault = true;
auto device = Wrapper::WrappedIKeymasterDevice::getService(name);
@@ -97,7 +97,7 @@
});
if (!foundDefault) {
- // "default" wasn't provided by listByInterface. Maybe there's a passthrough
+ // "default" wasn't provided by listManifestByInterface. Maybe there's a passthrough
// implementation.
auto device = Wrapper::WrappedIKeymasterDevice::getService("default");
if (device) result.push_back(std::unique_ptr<Keymaster>(new Wrapper(device, "default")));
diff --git a/keymaster/4.0/vts/functional/VerificationTokenTest.cpp b/keymaster/4.0/vts/functional/VerificationTokenTest.cpp
index 3876b16..de28683 100644
--- a/keymaster/4.0/vts/functional/VerificationTokenTest.cpp
+++ b/keymaster/4.0/vts/functional/VerificationTokenTest.cpp
@@ -124,6 +124,65 @@
// report if times aren't nearly always <1ms apart.
EXPECT_LE(host_time_delta, km_time_delta + 2);
EXPECT_LE(km_time_delta, host_time_delta + 2);
+ ASSERT_EQ(result1.token.mac.size(), result2.token.mac.size());
+ ASSERT_NE(0,
+ memcmp(result1.token.mac.data(), result2.token.mac.data(), result1.token.mac.size()));
+}
+
+/*
+ * Test that the mac changes when the time stamp changes. This is does not guarantee that the time
+ * stamp is included in the mac but on failure we know that it is not. Other than in the test
+ * case above we call verifyAuthorization with the exact same set of parameters.
+ */
+TEST_F(VerificationTokenTest, MacChangesOnChangingTimestamp) {
+ auto result1 =
+ verifyAuthorization(0 /* operation handle */,
+ AuthorizationSet() /* paramtersToVerify */, HardwareAuthToken());
+ ASSERT_TRUE(result1.callSuccessful);
+ auto result1_time = getTime();
+
+ if (SecLevel() == SecurityLevel::STRONGBOX) {
+ // StrongBox should not implement verifyAuthorization.
+ EXPECT_EQ(ErrorCode::UNIMPLEMENTED, result1.error);
+ return;
+ }
+
+ EXPECT_EQ(ErrorCode::OK, result1.error);
+ EXPECT_EQ(0U, result1.token.challenge);
+ EXPECT_EQ(SecLevel(), result1.token.securityLevel);
+ EXPECT_EQ(0U, result1.token.parametersVerified.size())
+ << "We didn't supply any parameters to verify";
+ EXPECT_GT(result1.token.timestamp, 0U);
+
+ constexpr uint32_t time_to_sleep = 200;
+ sleep_ms(time_to_sleep);
+
+ auto result2 =
+ verifyAuthorization(0 /* operation handle */,
+ AuthorizationSet() /* paramtersToVerify */, HardwareAuthToken());
+ ASSERT_TRUE(result2.callSuccessful);
+ auto result2_time = getTime();
+ EXPECT_EQ(ErrorCode::OK, result2.error);
+ EXPECT_EQ(0U, result2.token.challenge);
+ EXPECT_EQ(SecLevel(), result2.token.securityLevel);
+ EXPECT_EQ(0U, result2.token.parametersVerified.size())
+ << "We didn't supply any parameters to verify";
+
+ auto host_time_delta = result2_time - result1_time;
+
+ EXPECT_GE(host_time_delta, time_to_sleep)
+ << "We slept for " << time_to_sleep << " ms, the clock must have advanced by that much";
+ EXPECT_LE(host_time_delta, time_to_sleep + 20)
+ << "The verifyAuthorization call took " << (host_time_delta - time_to_sleep)
+ << " ms? That's awful!";
+
+ auto km_time_delta = result2.token.timestamp - result1.token.timestamp;
+
+ EXPECT_LE(host_time_delta, km_time_delta + 2);
+ EXPECT_LE(km_time_delta, host_time_delta + 2);
+ ASSERT_EQ(result1.token.mac.size(), result2.token.mac.size());
+ ASSERT_NE(0,
+ memcmp(result1.token.mac.data(), result2.token.mac.data(), result1.token.mac.size()));
}
} // namespace test
diff --git a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
index 728bf69..293c50c 100644
--- a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
+++ b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
@@ -2207,26 +2207,26 @@
}
auto wrapped_key = hex2str(
- "3082017902010004820100A0E69B1395D382354FC0E7F74AC068C5818279D76D46745C7274997D045BAA8B9763B3F3"
- "09E5E59ECA99273AAAE0A37449DA9B1E67B66EC4E42BB62C25346683A43A9F2ACBCA6D350B25551CC53CE0721D29BE"
- "90F60686877478F82B3BB111C5EAC0BAE9310D7AD11F5A82948B31C322820F24E20DDB0FBD07D1566DAEAA058D4645"
- "2607352699E1F631D2ABAF60B13E41ED5EDBB90D252331BDB9CDB1B672E871F37CAC009FE9028B3B1E0ACE8F6F0678"
- "3F581B860620BDD478969EDE3101AAEFF65C6DB03E143E586167DC87D0CCE39E9119782F7B60A7A1CF2B7EE234E013"
- "E3DE6C56F0D51F30C389D31FA37C5F2875ACB44434E82EF40B316C93DE129BA0040CD796B02C370F1FA4CC0124F130"
- "2E0201033029A1083106020100020101A203020120A30402020100A4053103020101A6053103020140BF8377020500"
- "0420CCD540855F833A5E1480BFD2D36FAF3AEEE15DF5BEABE2691BC82DDE2A7AA910041064C9F689C60FF6223AB6E6"
- "999E0EB6E5");
+ "3082017902010004820100934bf94e2aa28a3f83c9f79297250262fbe3276b5a1c91159bbfa3ef8957aac84b59b30b"
+ "455a79c2973480823d8b3863c3deef4a8e243590268d80e18751a0e130f67ce6a1ace9f79b95e097474febc981195b"
+ "1d13a69086c0863f66a7b7fdb48792227b1ac5e2489febdf087ab5486483033a6f001ca5d1ec1e27f5c30f4cec2642"
+ "074a39ae68aee552e196627a8e3d867e67a8c01b11e75f13cca0a97ab668b50cda07a8ecb7cd8e3dd7009c9636534f"
+ "6f239cffe1fc8daa466f78b676c7119efb96bce4e69ca2a25d0b34ed9c3ff999b801597d5220e307eaa5bee507fb94"
+ "d1fa69f9e519b2de315bac92c36f2ea1fa1df4478c0ddedeae8c70e0233cd098040cd796b02c370f1fa4cc0124f130"
+ "2e0201033029a1083106020100020101a203020120a30402020100a4053103020101a6053103020140bf8377020500"
+ "0420ccd540855f833a5e1480bfd2d36faf3aeee15df5beabe2691bc82dde2a7aa910041064c9f689c60ff6223ab6e6"
+ "999e0eb6e5");
auto wrapped_key_masked = hex2str(
- "30820179020100048201001EF5320D3C920D7614688A439409ACE4318C48395ABB7247A68671BD4B7156A7773B31A4"
- "4459B73858625988A312E4D8855138F555678F525E4C52D91444FDC936BE6AEB63FD73FD84201EF46F88A0B622F528"
- "956C92C9C731EB65BCBC6A03BEAB45959B54A768E2842D2CE174EE542EF2A15DCAA7542F3574BEEB1A991F95439466"
- "E1960A9CE9E4CBC77DB23765191E4758C850908BCC74E158B77AB774141F171262C1AC771FDFA2E942F2F7633E97E8"
- "0BD492C3E821361AC6B4F568DE351C816C8C997212C707F728FB3BCAAA796EA6B8E7A80BE010970B380122940277E9"
- "4C5E9288F7CB6878A4C4CC1E83AB85A81FD68E43B14F1F81AD21E0D3545D70EE040C6D9721D08589581AB49204A330"
- "2E0201033029A1083106020100020101A203020120A30402020100A4053103020101A6053103020140BF8377020500"
- "0420A61C6E247E25B3E6E69AA78EB03C2D4AC20D1F99A9A024A76F35C8E2CAB9B68D04102560C70109AE67C030F00B"
- "98B512A670");
+ "3082017902010004820100aad93ed5924f283b4bb5526fbe7a1412f9d9749ec30db9062b29e574a8546f33c8873245"
+ "2f5b8e6a391ee76c39ed1712c61d8df6213dec1cffbc17a8c6d04c7b30893d8daa9b2015213e21946821553207f8f9"
+ "931c4caba23ed3bee28b36947e47f10e0a5c3dc51c988a628daad3e5e1f4005e79c2d5a96c284b4b8d7e4948f331e5"
+ "b85dd5a236f85579f3ea1d1b848487470bdb0ab4f81a12bee42c99fe0df4bee3759453e69ad1d68a809ce06b949f76"
+ "94a990429b2fe81e066ff43e56a21602db70757922a4bcc23ab89f1e35da77586775f423e519c2ea394caf48a28d0c"
+ "8020f1dcf6b3a68ec246f615ae96dae9a079b1f6eb959033c1af5c125fd94168040c6d9721d08589581ab49204a330"
+ "2e0201033029a1083106020100020101a203020120a30402020100a4053103020101a6053103020140bf8377020500"
+ "0420a61c6e247e25b3e6e69aa78eb03c2d4ac20d1f99a9a024a76f35c8e2cab9b68d04102560c70109ae67c030f00b"
+ "98b512a670");
auto wrapping_key = hex2str(
"308204be020100300d06092a864886f70d0101010500048204a8308204a40201000282010100aec367931d8900ce56"
@@ -2265,14 +2265,16 @@
TEST_F(ImportWrappedKeyTest, Success) {
auto wrapping_key_desc = AuthorizationSetBuilder()
.RsaEncryptionKey(2048, 65537)
- .Digest(Digest::SHA1)
+ .Digest(Digest::SHA_2_256)
.Padding(PaddingMode::RSA_OAEP)
.Authorization(TAG_PURPOSE, KeyPurpose::WRAP_KEY);
ASSERT_EQ(ErrorCode::OK,
ImportWrappedKey(
wrapped_key, wrapping_key, wrapping_key_desc, zero_masking_key,
- AuthorizationSetBuilder().Digest(Digest::SHA1).Padding(PaddingMode::RSA_OAEP)));
+ AuthorizationSetBuilder()
+ .Digest(Digest::SHA_2_256)
+ .Padding(PaddingMode::RSA_OAEP)));
string message = "Hello World!";
auto params = AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::PKCS7);
@@ -2284,39 +2286,45 @@
TEST_F(ImportWrappedKeyTest, SuccessMasked) {
auto wrapping_key_desc = AuthorizationSetBuilder()
.RsaEncryptionKey(2048, 65537)
- .Digest(Digest::SHA1)
+ .Digest(Digest::SHA_2_256)
.Padding(PaddingMode::RSA_OAEP)
.Authorization(TAG_PURPOSE, KeyPurpose::WRAP_KEY);
ASSERT_EQ(ErrorCode::OK,
ImportWrappedKey(
wrapped_key_masked, wrapping_key, wrapping_key_desc, masking_key,
- AuthorizationSetBuilder().Digest(Digest::SHA1).Padding(PaddingMode::RSA_OAEP)));
+ AuthorizationSetBuilder()
+ .Digest(Digest::SHA_2_256)
+ .Padding(PaddingMode::RSA_OAEP)));
}
TEST_F(ImportWrappedKeyTest, WrongMask) {
auto wrapping_key_desc = AuthorizationSetBuilder()
.RsaEncryptionKey(2048, 65537)
- .Digest(Digest::SHA1)
+ .Digest(Digest::SHA_2_256)
.Padding(PaddingMode::RSA_OAEP)
.Authorization(TAG_PURPOSE, KeyPurpose::WRAP_KEY);
ASSERT_EQ(ErrorCode::VERIFICATION_FAILED,
ImportWrappedKey(
wrapped_key_masked, wrapping_key, wrapping_key_desc, zero_masking_key,
- AuthorizationSetBuilder().Digest(Digest::SHA1).Padding(PaddingMode::RSA_OAEP)));
+ AuthorizationSetBuilder()
+ .Digest(Digest::SHA_2_256)
+ .Padding(PaddingMode::RSA_OAEP)));
}
TEST_F(ImportWrappedKeyTest, WrongPurpose) {
auto wrapping_key_desc = AuthorizationSetBuilder()
.RsaEncryptionKey(2048, 65537)
- .Digest(Digest::SHA1)
+ .Digest(Digest::SHA_2_256)
.Padding(PaddingMode::RSA_OAEP);
ASSERT_EQ(ErrorCode::INCOMPATIBLE_PURPOSE,
ImportWrappedKey(
wrapped_key_masked, wrapping_key, wrapping_key_desc, zero_masking_key,
- AuthorizationSetBuilder().Digest(Digest::SHA1).Padding(PaddingMode::RSA_OAEP)));
+ AuthorizationSetBuilder()
+ .Digest(Digest::SHA_2_256)
+ .Padding(PaddingMode::RSA_OAEP)));
}
typedef KeymasterHidlTest EncryptionOperationsTest;
@@ -2550,7 +2558,8 @@
Begin(KeyPurpose::ENCRYPT,
AuthorizationSetBuilder().Padding(PaddingMode::RSA_OAEP).Digest(Digest::SHA_2_256)));
string result;
- EXPECT_EQ(ErrorCode::INVALID_ARGUMENT, Finish(message, &result));
+ auto error = Finish(message, &result);
+ EXPECT_TRUE(error == ErrorCode::INVALID_INPUT_LENGTH || error == ErrorCode::INVALID_ARGUMENT);
EXPECT_EQ(0U, result.size());
}
@@ -2608,7 +2617,8 @@
auto params = AuthorizationSetBuilder().Padding(PaddingMode::RSA_PKCS1_1_5_ENCRYPT);
EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params));
string result;
- EXPECT_EQ(ErrorCode::INVALID_ARGUMENT, Finish(message, &result));
+ auto error = Finish(message, &result);
+ EXPECT_TRUE(error == ErrorCode::INVALID_INPUT_LENGTH || error == ErrorCode::INVALID_ARGUMENT);
EXPECT_EQ(0U, result.size());
}
diff --git a/light/2.0/Android.bp b/light/2.0/Android.bp
index 6068752..d51f10d 100644
--- a/light/2.0/Android.bp
+++ b/light/2.0/Android.bp
@@ -15,4 +15,3 @@
],
gen_java: true,
}
-
diff --git a/media/1.0/Android.bp b/media/1.0/Android.bp
index 844cfa2..2dbe466 100644
--- a/media/1.0/Android.bp
+++ b/media/1.0/Android.bp
@@ -14,4 +14,3 @@
],
gen_java: true,
}
-
diff --git a/media/bufferpool/1.0/Android.bp b/media/bufferpool/1.0/Android.bp
index 86297d3..079e47f 100644
--- a/media/bufferpool/1.0/Android.bp
+++ b/media/bufferpool/1.0/Android.bp
@@ -17,4 +17,3 @@
],
gen_java: false,
}
-
diff --git a/media/bufferpool/2.0/Android.bp b/media/bufferpool/2.0/Android.bp
index 0faa00e..6a82616 100644
--- a/media/bufferpool/2.0/Android.bp
+++ b/media/bufferpool/2.0/Android.bp
@@ -18,4 +18,3 @@
],
gen_java: false,
}
-
diff --git a/media/c2/1.0/Android.bp b/media/c2/1.0/Android.bp
index 895e9db..391e6c4 100644
--- a/media/c2/1.0/Android.bp
+++ b/media/c2/1.0/Android.bp
@@ -31,4 +31,3 @@
],
gen_java: false,
}
-
diff --git a/media/omx/1.0/Android.bp b/media/omx/1.0/Android.bp
index ee51d5d..5fe73ab 100644
--- a/media/omx/1.0/Android.bp
+++ b/media/omx/1.0/Android.bp
@@ -23,4 +23,3 @@
],
gen_java: false,
}
-
diff --git a/memtrack/1.0/Android.bp b/memtrack/1.0/Android.bp
index 0f24977..a50195e 100644
--- a/memtrack/1.0/Android.bp
+++ b/memtrack/1.0/Android.bp
@@ -15,4 +15,3 @@
],
gen_java: true,
}
-
diff --git a/memtrack/1.0/default/android.hardware.memtrack@1.0-service.rc b/memtrack/1.0/default/android.hardware.memtrack@1.0-service.rc
index 4327a20..f5eee54 100644
--- a/memtrack/1.0/default/android.hardware.memtrack@1.0-service.rc
+++ b/memtrack/1.0/default/android.hardware.memtrack@1.0-service.rc
@@ -1,4 +1,5 @@
service vendor.memtrack-hal-1-0 /vendor/bin/hw/android.hardware.memtrack@1.0-service
+ interface android.hardware.memtrack@1.0::IMemtrack default
class hal
user system
group system
diff --git a/neuralnetworks/1.0/Android.bp b/neuralnetworks/1.0/Android.bp
index 63b5b98..3e740c4 100644
--- a/neuralnetworks/1.0/Android.bp
+++ b/neuralnetworks/1.0/Android.bp
@@ -18,4 +18,3 @@
],
gen_java: false,
}
-
diff --git a/neuralnetworks/1.0/IPreparedModel.hal b/neuralnetworks/1.0/IPreparedModel.hal
index ecaa7f8..5320050 100644
--- a/neuralnetworks/1.0/IPreparedModel.hal
+++ b/neuralnetworks/1.0/IPreparedModel.hal
@@ -42,6 +42,13 @@
* execute function. This callback must be provided with the ErrorStatus of
* the execution.
*
+ * If the launch is successful, the caller must not change the content of
+ * any data object referenced by 'request' (described by the
+ * {@link DataLocation} of a {@link RequestArgument}) until the
+ * asynchronous task has invoked the callback object. The asynchronous task
+ * 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
diff --git a/neuralnetworks/1.0/vts/functional/Android.bp b/neuralnetworks/1.0/vts/functional/Android.bp
index 9057695..0d70816 100644
--- a/neuralnetworks/1.0/vts/functional/Android.bp
+++ b/neuralnetworks/1.0/vts/functional/Android.bp
@@ -15,21 +15,19 @@
//
cc_library_static {
- name: "VtsHalNeuralnetworksTest_utils",
+ name: "VtsHalNeuralNetworksV1_0_utils",
srcs: [
"Callbacks.cpp",
- "GeneratedTestHarness.cpp",
+ "Utils.cpp",
],
defaults: ["VtsHalTargetTestDefaults"],
- export_include_dirs: ["."],
+ export_include_dirs: ["include"],
shared_libs: [
"libfmq",
"libnativewindow",
],
static_libs: [
"android.hardware.neuralnetworks@1.0",
- "android.hardware.neuralnetworks@1.1",
- "android.hardware.neuralnetworks@1.2",
"android.hidl.allocator@1.0",
"android.hidl.memory@1.0",
"libgmock",
@@ -44,12 +42,13 @@
}
cc_defaults {
- name: "VtsHalNeuralNetworksTargetTestDefaults",
+ name: "VtsHalNeuralNetworksV1_0TargetTestDefaults",
defaults: ["VtsHalTargetTestDefaults"],
srcs: [
"ValidateModel.cpp",
"ValidateRequest.cpp",
"VtsHalNeuralnetworks.cpp",
+ "GeneratedTestHarness.cpp",
],
shared_libs: [
"libfmq",
@@ -57,47 +56,36 @@
],
static_libs: [
"android.hardware.neuralnetworks@1.0",
- "android.hardware.neuralnetworks@1.1",
- "android.hardware.neuralnetworks@1.2",
"android.hidl.allocator@1.0",
"android.hidl.memory@1.0",
"libgmock",
"libhidlmemory",
"libneuralnetworks_utils",
- "VtsHalNeuralnetworksTest_utils",
+ "VtsHalNeuralNetworksV1_0_utils",
],
header_libs: [
"libneuralnetworks_headers",
"libneuralnetworks_generated_test_harness_headers",
"libneuralnetworks_generated_tests",
],
- // Bug: http://b/74200014 - Disable arm32 asan since it triggers internal
- // error in ld.gold.
- arch: {
- arm: {
- sanitize: {
- never: true,
- },
- },
- },
test_suites: ["general-tests"],
}
cc_test {
name: "VtsHalNeuralnetworksV1_0TargetTest",
- defaults: ["VtsHalNeuralNetworksTargetTestDefaults"],
+ defaults: ["VtsHalNeuralNetworksV1_0TargetTestDefaults"],
srcs: [
"BasicTests.cpp",
- "GeneratedTests.cpp",
+ "GeneratedTestsV1_0.cpp",
],
}
cc_test {
name: "PresubmitHalNeuralnetworksV1_0TargetTest",
- defaults: ["VtsHalNeuralNetworksTargetTestDefaults"],
+ defaults: ["VtsHalNeuralNetworksV1_0TargetTestDefaults"],
srcs: [
"BasicTests.cpp",
- "GeneratedTests.cpp",
+ "GeneratedTestsV1_0.cpp",
],
cflags: [
"-DPRESUBMIT_NOT_VTS",
diff --git a/neuralnetworks/1.0/vts/functional/Callbacks.cpp b/neuralnetworks/1.0/vts/functional/Callbacks.cpp
index c30702c..37afcf0 100644
--- a/neuralnetworks/1.0/vts/functional/Callbacks.cpp
+++ b/neuralnetworks/1.0/vts/functional/Callbacks.cpp
@@ -14,160 +14,78 @@
* limitations under the License.
*/
-#include "Callbacks.h"
+#define LOG_TAG "Callbacks"
+
+#include "1.0/Callbacks.h"
+
#include <android-base/logging.h>
-namespace android {
-namespace hardware {
-namespace neuralnetworks {
-namespace V1_2 {
-namespace implementation {
+namespace android::hardware::neuralnetworks::V1_0::implementation {
-CallbackBase::CallbackBase() : mNotified(false) {}
-
-CallbackBase::~CallbackBase() {
- // Note that we cannot call CallbackBase::join_thread from here:
- // CallbackBase is intended to be reference counted, and it is possible that
- // the reference count drops to zero in the bound thread, causing the
- // bound thread to call this destructor. If a thread tries to join
- // itself, it throws an exception, producing a message like the
- // following:
- //
- // terminating with uncaught exception of type std::__1::system_error:
- // thread::join failed: Resource deadlock would occur
-}
-
-void CallbackBase::wait() {
- std::unique_lock<std::mutex> lock(mMutex);
- mCondition.wait(lock, [this]{return mNotified;});
- join_thread_locked();
-}
-
-bool CallbackBase::on_finish(std::function<bool(void)> post_work) {
- std::lock_guard<std::mutex> lock(mMutex);
- if (mPostWork != nullptr) {
- LOG(ERROR) << "CallbackBase::on_finish -- a post-work function has already been bound to "
- "this callback object";
- return false;
- }
- if (post_work == nullptr) {
- LOG(ERROR) << "CallbackBase::on_finish -- the new post-work function is invalid";
- return false;
- }
- mPostWork = std::move(post_work);
- return true;
-}
-
-bool CallbackBase::bind_thread(std::thread&& asyncThread) {
- std::lock_guard<std::mutex> lock(mMutex);
- if (mThread.joinable()) {
- LOG(ERROR) << "CallbackBase::bind_thread -- a thread has already been bound to this "
- "callback object";
- return false;
- }
- if (!asyncThread.joinable()) {
- LOG(ERROR) << "CallbackBase::bind_thread -- the new thread is not joinable";
- return false;
- }
- mThread = std::move(asyncThread);
- return true;
-}
-
-void CallbackBase::join_thread() {
- std::lock_guard<std::mutex> lock(mMutex);
- join_thread_locked();
-}
-
-void CallbackBase::notify() {
- {
- std::lock_guard<std::mutex> lock(mMutex);
- mNotified = true;
- if (mPostWork != nullptr) {
- bool success = mPostWork();
- if (!success) {
- LOG(ERROR) << "CallbackBase::notify -- post work failed";
- }
- }
- }
- mCondition.notify_all();
-}
-
-void CallbackBase::join_thread_locked() {
- if (mThread.joinable()) {
- mThread.join();
- }
-}
-
-PreparedModelCallback::PreparedModelCallback() :
- mErrorStatus(ErrorStatus::GENERAL_FAILURE), mPreparedModel(nullptr) {}
-
-PreparedModelCallback::~PreparedModelCallback() {}
+// PreparedModelCallback methods begin here
Return<void> PreparedModelCallback::notify(ErrorStatus errorStatus,
- const sp<V1_0::IPreparedModel>& preparedModel) {
- mErrorStatus = errorStatus;
- mPreparedModel = preparedModel;
- CallbackBase::notify();
+ const sp<IPreparedModel>& preparedModel) {
+ {
+ std::lock_guard<std::mutex> hold(mMutex);
+
+ // quick-return if object has already been notified
+ if (mNotified) {
+ return Void();
+ }
+
+ // store results and mark as notified
+ mErrorStatus = errorStatus;
+ mPreparedModel = preparedModel;
+ mNotified = true;
+ }
+
+ mCondition.notify_all();
return Void();
}
-Return<void> PreparedModelCallback::notify_1_2(ErrorStatus errorStatus,
- const sp<V1_2::IPreparedModel>& preparedModel) {
- mErrorStatus = errorStatus;
- mPreparedModel = preparedModel;
- CallbackBase::notify();
- return Void();
+void PreparedModelCallback::wait() const {
+ std::unique_lock<std::mutex> lock(mMutex);
+ mCondition.wait(lock, [this] { return mNotified; });
}
-ErrorStatus PreparedModelCallback::getStatus() {
+ErrorStatus PreparedModelCallback::getStatus() const {
wait();
return mErrorStatus;
}
-sp<V1_0::IPreparedModel> PreparedModelCallback::getPreparedModel() {
+sp<IPreparedModel> PreparedModelCallback::getPreparedModel() const {
wait();
return mPreparedModel;
}
-ExecutionCallback::ExecutionCallback() : mErrorStatus(ErrorStatus::GENERAL_FAILURE) {}
-
-ExecutionCallback::~ExecutionCallback() {}
+// ExecutionCallback methods begin here
Return<void> ExecutionCallback::notify(ErrorStatus errorStatus) {
- mErrorStatus = errorStatus;
- mOutputShapes = {};
- mTiming = {.timeOnDevice = UINT64_MAX, .timeInDriver = UINT64_MAX};
- CallbackBase::notify();
+ {
+ std::lock_guard<std::mutex> hold(mMutex);
+
+ // quick-return if object has already been notified
+ if (mNotified) {
+ return Void();
+ }
+
+ mErrorStatus = errorStatus;
+ mNotified = true;
+ }
+ mCondition.notify_all();
+
return Void();
}
-Return<void> ExecutionCallback::notify_1_2(ErrorStatus errorStatus,
- const hidl_vec<OutputShape>& outputShapes,
- const Timing& timing) {
- mErrorStatus = errorStatus;
- mOutputShapes = outputShapes;
- mTiming = timing;
- CallbackBase::notify();
- return Void();
+void ExecutionCallback::wait() const {
+ std::unique_lock<std::mutex> lock(mMutex);
+ mCondition.wait(lock, [this] { return mNotified; });
}
-ErrorStatus ExecutionCallback::getStatus() {
+ErrorStatus ExecutionCallback::getStatus() const {
wait();
return mErrorStatus;
}
-const std::vector<OutputShape>& ExecutionCallback::getOutputShapes() {
- wait();
- return mOutputShapes;
-}
-
-Timing ExecutionCallback::getTiming() {
- wait();
- return mTiming;
-}
-
-} // namespace implementation
-} // namespace V1_2
-} // namespace neuralnetworks
-} // namespace hardware
-} // namespace android
+} // namespace android::hardware::neuralnetworks::V1_0::implementation
diff --git a/neuralnetworks/1.0/vts/functional/Callbacks.h b/neuralnetworks/1.0/vts/functional/Callbacks.h
deleted file mode 100644
index 4707d0a..0000000
--- a/neuralnetworks/1.0/vts/functional/Callbacks.h
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_NEURALNETWORKS_V1_0_CALLBACKS_H
-#define ANDROID_HARDWARE_NEURALNETWORKS_V1_0_CALLBACKS_H
-
-#include <android/hardware/neuralnetworks/1.0/IExecutionCallback.h>
-#include <android/hardware/neuralnetworks/1.0/IPreparedModelCallback.h>
-#include <android/hardware/neuralnetworks/1.2/IExecutionCallback.h>
-#include <android/hardware/neuralnetworks/1.2/IPreparedModelCallback.h>
-#include <hidl/MQDescriptor.h>
-#include <hidl/Status.h>
-#include <chrono>
-#include <condition_variable>
-#include <functional>
-#include <mutex>
-#include <thread>
-
-namespace android {
-namespace hardware {
-namespace neuralnetworks {
-namespace V1_2 {
-namespace implementation {
-
-using V1_0::ErrorStatus;
-
-/**
- * The CallbackBase class is used internally by the NeuralNetworks runtime to
- * synchronize between different threads. An asynchronous task is launched
- * paired with a callback object. When a client thread requires the output being
- * generated by the asynchronous task, the client thread can wait for the result
- * and be blocked until it has completed or a timeout condition has been
- * reached. Any wait* may safely be called concurrently, even on the same
- * callback object. When the asynchronous task has finished its workload, it
- * must immediately call "notify". If the asynchronous task has failed to launch,
- * the function that tried to launch the asynchronous task must immediately call
- * "notify". This "notify" call awakens any client threads waiting on the
- * callback object.
- *
- * The CallbackBase class implements some of the base synchronization common to
- * both PrepareModelCallback and ExecutionCallback. For consistency, any HIDL
- * callback class must inherit from CallbackBase as well as the HIDL callback
- * interface it implements.
- *
- * This class exists to enable synchronization across HIDL. When synchronization
- * is only required in the same process, consider using std::future, std::mutex,
- * std::condition_variable, or std::experimental::latch instead.
- */
-class CallbackBase {
- public:
- CallbackBase();
- ~CallbackBase();
-
- /**
- * CallbackBase::wait blocks until notify has been called on the callback
- * object.
- */
- void wait();
-
- /**
- * CallbackBase::wait_for blocks until notify has been called on the
- * callback object or the time duration from the time the wait_for function
- * was called has expired, whichever comes first.
- *
- * @return Status std::cv_status::no_timeout if the callback was notified
- * before the time duration expired, std::cv_status::timeout
- * otherwise.
- */
- template<class Rep, class Period>
- std::cv_status wait_for(const std::chrono::duration<Rep,Period>& timeout_duration);
-
- /**
- * CallbackBase::on_finish binds a function to the callback object. This
- * bound function will be executed when CallbackBase::notify is called,
- * before any calls to wait* return. (Note that CallbackBase::wait_for can
- * return std::cv_status::timeout before CallbackBase::notify is called for
- * the first time, and hence before the bound function is executed.)
- *
- * The bound function must not synchronize with or otherwise access the
- * callback object it is bound to, as this could cause a deadlock.
- *
- * CallbackBase::on_finish can be called at most once on a given callback
- * object, and the call to CallbackBase::on_finish must finish before
- * CallbackBase::notify is called.
- *
- * @param post_work Function to be invoked the first time
- * CallbackBase::notify is called. Must have a target --
- * i.e., must not compare equal to nullptr. post_work
- * returns true if it successfully completes, false if it
- * fails.
- * @return bool True if the function was successfully bound, false if
- * unsuccessful.
- *
- * TODO: Why does the return value of the callback matter?
- */
- bool on_finish(std::function<bool(void)> post_work);
-
- /**
- * CallbackBase::bind_thread binds a thread to the event for later use by
- * CallbackBase::join_thread.
- *
- * The thread must be passed using std::move.
- *
- * Once a thread is bound with CallbackBase::bind_thread, the client code
- * should ensure that one of the following occurs before the event is
- * destroyed:
- * - CallbackBase::join_thread has been called.
- * - CallbackBase::wait has been called.
- * - CallbackBase::wait_for has been called and returned other than
- * std::cv_status::no_timeout.
- *
- * The bound thread shall not call any CallbackBase method with the
- * exception of CallbackBase::notify, which it must call when the thread has
- * finished its computation.
- *
- * CallbackBase::bind_thread can be called at most once on a given callback
- * object.
- *
- * @param asyncThread Thread to be bound to the callback object. The thread
- * object must represent a thread of execution -- i.e.,
- * asyncThread.joinable() must be true.
- * @return bool True if successful, false if thread was not properly bound.
- */
- bool bind_thread(std::thread&& asyncThread);
-
- /**
- * CallbackBase::join_thread ensures that the thread (if any) bound to this
- * event with CallbackBase::bind_thread has fully finished and cleaned its
- * resources. It is legal to call this function multiple times, concurrently
- * or sequentially.
- */
- void join_thread();
-
- protected:
- /**
- * CallbackBase::notify enables all prior and future wait* calls on the
- * callback object to proceed. The call to CallbackBase::notify happens
- * before any wait* calls on this callback object return (except in the case
- * of wait_for timing out). The asynchronous call the callback object is
- * paired with must ensure that any update to state that should be visible
- * to the caller of wait* happens before the call to CallbackBase::notify.
- *
- * CallbackBase::notify must be called exactly once on a given callback
- * object.
- */
- void notify();
-
- private:
- // Same as CallbackBase::join_thread but assumes we already hold a lock on
- // mMutex.
- void join_thread_locked();
-
- bool mNotified;
- std::mutex mMutex;
- std::condition_variable mCondition;
- std::function<bool(void)> mPostWork;
- std::thread mThread;
-};
-
-/**
- * The PreparedModelCallback class is used to receive the error status of
- * preparing a model as well as the prepared model from a task executing
- * asynchronously with respect to the runtime. If a calling thread calls wait*
- * or get* on a PreparedModelCallback object and the corresponding asynchronous
- * task has not finished preparing the model, the calling thread will block
- * until the asynchronous task has either called notify or notify_1_2. For more
- * information on the synchronization behavior, refer to the CallbackBase class.
- *
- * This class inherits the basic blocking and signaling calls from
- * CallbackBase, and implements the HIDL notify and notify_1_2 calls from
- * IPreparedModelCallback. This callback object is passed as an argument to
- * IDevice::prepareModel.
- */
-class PreparedModelCallback : public CallbackBase, public IPreparedModelCallback {
- public:
- PreparedModelCallback();
- ~PreparedModelCallback() override;
-
- /**
- * IPreparedModelCallback::notify and IPreparedModelCallback::notify_1_2
- * mark the callback object with the return status of the asynchronous
- * model preparation along with the prepared model, and call
- * CallbackBase::notify, enabling all prior and future wait* calls on the
- * PreparedModelCallback object to proceed. For more information on the
- * synchronization behavior, refer to the CallbackBase class.
- *
- * Either IPreparedModelCallback::notify or IPreparedModelCallback::notify_1_2
- * must be called exactly once on a given PreparedModelCallback object.
- *
- * @param status Error status returned from asynchronously preparing the
- * model; will be:
- * - NONE if the asynchronous preparation was successful
- * - DEVICE_UNAVAILABLE if driver is offline or busy
- * - GENERAL_FAILURE if there is an unspecified error
- * - INVALID_ARGUMENT if the input model is invalid
- * @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_1_2(ErrorStatus status,
- const sp<V1_2::IPreparedModel>& preparedModel) override;
-
- /**
- * Retrieves the error status returned from the asynchronous task launched
- * by IDevice::prepareModel. If IDevice::prepareModel has not finished
- * asynchronously preparing the model, this call will block until the
- * asynchronous task notifies the object.
- *
- * @return status Error status returned from asynchronously preparing the
- * model; will be:
- * - NONE if the asynchronous preparation was successful
- * - DEVICE_UNAVAILABLE if driver is offline or busy
- * - GENERAL_FAILURE if there is an unspecified error
- * - INVALID_ARGUMENT if the input model is invalid
- */
- ErrorStatus getStatus();
-
- /**
- * Retrieves the model that has been prepared for execution from the
- * asynchronous task launched by IDevice::prepareModel. If
- * IDevice::prepareModel has not finished asynchronously preparing the
- * model, this call will block until the asynchronous task notifies the
- * object.
- *
- * @return preparedModel Returned model that has been prepared for
- * execution, nullptr if the model was unable to be
- * prepared.
- */
- sp<V1_0::IPreparedModel> getPreparedModel();
-
- private:
- ErrorStatus mErrorStatus;
- sp<V1_0::IPreparedModel> mPreparedModel;
-};
-
-/**
- * The ExecutionCallback class is used to receive the error status of the
- * execution from a task executing asynchronously with respect to the runtime.
- * If a calling thread calls wait* or get* on a PreparedModelCallback object and
- * the corresponding asynchronous task has not finished the execution, the
- * calling thread will block until the asynchronous task has either called notify
- * or notify_1_2. For more information on the synchronization behavior, refer to
- * the CallbackBase class.
- *
- * This class inherits the basic blocking and signaling calls from
- * CallbackBase, and implements the HIDL notify and notify_1_2 calls from
- * IExecutionCallback. This callback object is passed as an argument to
- * IPreparedModel::execute.
- */
-class ExecutionCallback : public CallbackBase, public IExecutionCallback {
- public:
- ExecutionCallback();
- ~ExecutionCallback() override;
-
- /**
- * IExecutionCallback::notify and IExecutionCallback::notify_1_2 mark the
- * callback object with the return status of the asynchronous execution that
- * held this callback and enable all prior and future wait* calls on the
- * ExecutionCallback object to proceed. For more information on the
- * synchronization behavior, refer to the CallbackBase class.
- *
- * Either IExecutionCallback::notify or IExecutionCallback::notify_1_2 must
- * be called exactly once on a given ExecutionCallback object.
- *
- * @param status Error status returned from launching the asynchronous task
- * (if the launch fails) or from the asynchronous task itself
- * (if the launch succeeds). Must be:
- * - NONE if the asynchronous execution was successful
- * - DEVICE_UNAVAILABLE if driver is offline or busy
- * - GENERAL_FAILURE if there is an unspecified error
- * - OUTPUT_INSUFFICIENT_SIZE if provided output buffer is
- * not large enough to store the resultant values
- * - INVALID_ARGUMENT if the input request is invalid
- */
- Return<void> notify(ErrorStatus status) override;
-
- /**
- * Similar to IExecutionCallback::notify, but for V1_2::IPreparedModel to
- * also notify output shapes along with error status.
- *
- * @param status Error status returned from launching the asynchronous task
- * (if the launch fails) or from the asynchronous task itself
- * (if the launch succeeds). Must be:
- * - NONE if the asynchronous execution was successful
- * - DEVICE_UNAVAILABLE if driver is offline or busy
- * - GENERAL_FAILURE if the asynchronous task resulted in an
- * unspecified error
- * - OUTPUT_INSUFFICIENT_SIZE if at least one output
- * operand buffer is not large enough to store the
- * corresponding output
- * - INVALID_ARGUMENT if one of the input arguments to
- * prepareModel is invalid
- * @param outputShapes A list of shape information of model output operands.
- * The index into "outputShapes" corresponds to the index
- * of the output operand in the Request outputs vector.
- * outputShapes must be empty unless the status is either
- * NONE or OUTPUT_INSUFFICIENT_SIZE.
- * @return Timing Duration of execution. Unless MeasureTiming::YES was passed when
- * launching the execution and status is NONE, all times must
- * be 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,
- 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,
- const Timing& timing) {
- return notify_1_2(status, outputShapes, timing);
- }
-
- /**
- * Retrieves the error status returned from the asynchronous task launched
- * by either IPreparedModel::execute or IPreparedModel::execute_1_2. If
- * IPreparedModel::execute or IPreparedModel::execute_1_2 has not finished
- * asynchronously executing, this call will block until the asynchronous task
- * notifies the object.
- *
- * @return status Error status returned from launching the asynchronous task
- * (if the launch fails) or from the asynchronous task itself
- * (if the launch succeeds). Must be:
- * - NONE if the asynchronous execution was successful
- * - DEVICE_UNAVAILABLE if driver is offline or busy
- * - GENERAL_FAILURE if the asynchronous task resulted in an
- * unspecified error
- * - OUTPUT_INSUFFICIENT_SIZE if at least one output
- * operand buffer is not large enough to store the
- * corresponding output
- * - INVALID_ARGUMENT if one of the input arguments to
- * prepareModel is invalid
- */
- ErrorStatus getStatus();
-
- /**
- * Retrieves the output shapes returned from the asynchronous task launched
- * by IPreparedModel::execute_1_2. If IPreparedModel::execute_1_2 has not finished
- * asynchronously executing, this call will block until the asynchronous task
- * notifies the object.
- *
- * If the asynchronous task was launched by IPreparedModel::execute, an empty vector
- * will be returned.
- *
- * @return outputShapes A list of shape information of model output operands.
- * The index into "outputShapes" corresponds to the index
- * of the output operand in the Request outputs vector.
- * outputShapes must be empty unless the status is either
- * NONE or OUTPUT_INSUFFICIENT_SIZE.
- */
- const std::vector<OutputShape>& getOutputShapes();
-
- /**
- * Retrieves the duration of execution ofthe asynchronous task launched
- * by IPreparedModel::execute_1_2. If IPreparedModel::execute_1_2 has not finished
- * asynchronously executing, this call will block until the asynchronous task
- * notifies the object.
- *
- * If the asynchronous task was launched by IPreparedModel::execute, every time
- * must be UINT64_MAX.
- *
- * @return timing Duration of the execution. Every time must be UINT64_MAX unless
- * the status is NONE.
- */
- Timing getTiming();
-
- private:
- ErrorStatus mErrorStatus = ErrorStatus::GENERAL_FAILURE;
- std::vector<OutputShape> mOutputShapes = {};
- Timing mTiming = {};
-};
-
-
-// template function implementation(s) below this point
-
-template<class Rep, class Period>
-std::cv_status CallbackBase::wait_for(const std::chrono::duration<Rep,Period>& timeout_duration) {
- std::unique_lock<std::mutex> lock(mMutex);
- std::cv_status status = mCondition.wait_for(lock, timeout_duration, [this]{return mNotified;});
- if (status != std::cv_status::timeout) {
- join_thread_locked();
- }
- return status;
-}
-
-} // namespace implementation
-} // namespace V1_2
-} // namespace neuralnetworks
-} // namespace hardware
-} // namespace android
-
-#endif // ANDROID_HARDWARE_NEURALNETWORKS_V1_0_CALLBACKS_H
diff --git a/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
index c819b52..603054d 100644
--- a/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
+++ b/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
@@ -15,129 +15,47 @@
*/
#include "GeneratedTestHarness.h"
-#include "Callbacks.h"
-#include "ExecutionBurstController.h"
+#include "1.0/Callbacks.h"
+#include "1.0/Utils.h"
+#include "MemoryUtils.h"
#include "TestHarness.h"
-#include "Utils.h"
#include <android-base/logging.h>
#include <android/hardware/neuralnetworks/1.0/IDevice.h>
-#include <android/hardware/neuralnetworks/1.0/IExecutionCallback.h>
#include <android/hardware/neuralnetworks/1.0/IPreparedModel.h>
-#include <android/hardware/neuralnetworks/1.0/IPreparedModelCallback.h>
#include <android/hardware/neuralnetworks/1.0/types.h>
-#include <android/hardware/neuralnetworks/1.1/IDevice.h>
-#include <android/hardware/neuralnetworks/1.2/IDevice.h>
-#include <android/hardware/neuralnetworks/1.2/IExecutionCallback.h>
-#include <android/hardware/neuralnetworks/1.2/IPreparedModel.h>
-#include <android/hardware/neuralnetworks/1.2/IPreparedModelCallback.h>
#include <android/hidl/allocator/1.0/IAllocator.h>
#include <android/hidl/memory/1.0/IMemory.h>
#include <hidlmemory/mapping.h>
+
#include <iostream>
namespace android {
namespace hardware {
namespace neuralnetworks {
-
namespace generated_tests {
-using ::android::hardware::neuralnetworks::V1_2::implementation::ExecutionCallback;
-using ::android::hardware::neuralnetworks::V1_2::implementation::PreparedModelCallback;
-using ::test_helper::bool8;
+
+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 ::test_helper::compare;
-using ::test_helper::expectMultinomialDistributionWithinTolerance;
using ::test_helper::filter;
using ::test_helper::for_all;
-using ::test_helper::for_each;
using ::test_helper::MixedTyped;
using ::test_helper::MixedTypedExample;
using ::test_helper::resize_accordingly;
-using HidlToken = hidl_array<uint8_t, static_cast<uint32_t>(Constant::BYTE_SIZE_OF_CACHE_TOKEN)>;
-
-template <typename T>
-void copy_back_(std::map<int, std::vector<T>>* dst, const std::vector<RequestArgument>& ra,
- char* src) {
- for_each<T>(*dst, [&ra, src](int index, std::vector<T>& m) {
- ASSERT_EQ(m.size(), ra[index].location.length / sizeof(T));
- char* begin = src + ra[index].location.offset;
- memcpy(m.data(), begin, ra[index].location.length);
- });
-}
-
-void copy_back(MixedTyped* dst, const std::vector<RequestArgument>& ra, char* src) {
- copy_back_(&dst->float32Operands, ra, src);
- copy_back_(&dst->int32Operands, ra, src);
- copy_back_(&dst->quant8AsymmOperands, ra, src);
- copy_back_(&dst->quant16SymmOperands, ra, src);
- copy_back_(&dst->float16Operands, ra, src);
- copy_back_(&dst->bool8Operands, ra, src);
- copy_back_(&dst->quant8ChannelOperands, ra, src);
- copy_back_(&dst->quant16AsymmOperands, ra, src);
- copy_back_(&dst->quant8SymmOperands, ra, src);
- static_assert(9 == MixedTyped::kNumTypes,
- "Number of types in MixedTyped changed, but copy_back function wasn't updated");
-}
-
-static bool isZeroSized(const MixedTyped& example, uint32_t index) {
- for (auto i : example.operandDimensions.at(index)) {
- if (i == 0) return true;
- }
- return false;
-}
// Top level driver for models and examples generated by test_generator.py
// Test driver for those generated from ml/nn/runtime/test/spec
-static Return<ErrorStatus> ExecutePreparedModel(sp<V1_0::IPreparedModel>& preparedModel,
- const Request& request, MeasureTiming,
- sp<ExecutionCallback>& callback) {
- return preparedModel->execute(request, callback);
-}
-static Return<ErrorStatus> ExecutePreparedModel(sp<V1_2::IPreparedModel>& preparedModel,
- const Request& request, MeasureTiming measure,
- sp<ExecutionCallback>& callback) {
- return preparedModel->execute_1_2(request, measure, callback);
-}
-static Return<ErrorStatus> ExecutePreparedModel(sp<V1_0::IPreparedModel>&, const Request&,
- MeasureTiming, hidl_vec<OutputShape>*, Timing*) {
- ADD_FAILURE() << "asking for synchronous execution at V1_0";
- return ErrorStatus::GENERAL_FAILURE;
-}
-static Return<ErrorStatus> ExecutePreparedModel(sp<V1_2::IPreparedModel>& preparedModel,
- const Request& request, MeasureTiming measure,
- hidl_vec<OutputShape>* outputShapes,
- Timing* timing) {
- ErrorStatus result;
- Return<void> ret = preparedModel->executeSynchronously(
- request, measure,
- [&result, outputShapes, timing](ErrorStatus error, const hidl_vec<OutputShape>& shapes,
- const Timing& time) {
- result = error;
- *outputShapes = shapes;
- *timing = time;
- });
- if (!ret.isOk()) {
- return ErrorStatus::GENERAL_FAILURE;
- }
- return result;
-}
-static std::unique_ptr<::android::nn::ExecutionBurstController> CreateBurst(
- const sp<V1_0::IPreparedModel>&) {
- ADD_FAILURE() << "asking for burst execution at V1_0";
- return nullptr;
-}
-static std::shared_ptr<::android::nn::ExecutionBurstController> CreateBurst(
- const sp<V1_2::IPreparedModel>& preparedModel) {
- return ::android::nn::ExecutionBurstController::create(preparedModel, /*blocking=*/true);
-}
-enum class Executor { ASYNC, SYNC, BURST };
-enum class OutputType { FULLY_SPECIFIED, UNSPECIFIED, INSUFFICIENT };
-const float kDefaultAtol = 1e-5f;
-const float kDefaultRtol = 1e-5f;
-template <typename T_IPreparedModel>
-void EvaluatePreparedModel(sp<T_IPreparedModel>& preparedModel, std::function<bool(int)> is_ignored,
- const std::vector<MixedTypedExample>& examples,
- bool hasRelaxedFloat32Model, float fpAtol, float fpRtol,
- Executor executor, MeasureTiming measure, OutputType outputType) {
+void EvaluatePreparedModel(sp<IPreparedModel>& preparedModel, std::function<bool(int)> is_ignored,
+ const std::vector<MixedTypedExample>& examples, float fpAtol,
+ float fpRtol) {
const uint32_t INPUT = 0;
const uint32_t OUTPUT = 1;
@@ -147,14 +65,7 @@
const MixedTyped& inputs = example.operands.first;
const MixedTyped& golden = example.operands.second;
- const bool hasFloat16Inputs = !inputs.float16Operands.empty();
- if (hasRelaxedFloat32Model || hasFloat16Inputs) {
- // TODO: Adjust the error limit based on testing.
- // If in relaxed mode, set the absolute tolerance to be 5ULP of FP16.
- fpAtol = 5.0f * 0.0009765625f;
- // Set the relative tolerance to be 5ULP of the corresponding FP precision.
- fpRtol = 5.0f * 0.0009765625f;
- }
+ CHECK(inputs.float16Operands.empty()) << "float16 is not supported in 1.0";
std::vector<RequestArgument> inputs_info, outputs_info;
uint32_t inputSize = 0, outputSize = 0;
@@ -163,11 +74,13 @@
for_all(inputs, [&inputs_info, &inputSize](int index, auto, auto s) {
if (inputs_info.size() <= static_cast<size_t>(index)) inputs_info.resize(index + 1);
RequestArgument arg = {
- .location = {.poolIndex = INPUT, .offset = 0, .length = static_cast<uint32_t>(s)},
- .dimensions = {},
+ .location = {.poolIndex = INPUT,
+ .offset = 0,
+ .length = static_cast<uint32_t>(s)},
+ .dimensions = {},
};
RequestArgument arg_empty = {
- .hasNoValue = true,
+ .hasNoValue = true,
};
inputs_info[index] = s ? arg : arg_empty;
inputSize += s;
@@ -185,31 +98,17 @@
// Go through all outputs, initialize RequestArgument descriptors
resize_accordingly(golden, test);
- bool sizeLargerThanOne = true;
- for_all(golden, [&golden, &outputs_info, &outputSize, &outputType, &sizeLargerThanOne](
- int index, auto, auto s) {
+ for_all(golden, [&outputs_info, &outputSize](int index, auto, auto s) {
if (outputs_info.size() <= static_cast<size_t>(index)) outputs_info.resize(index + 1);
- if (index == 0) {
- // On OutputType::INSUFFICIENT, set the output operand with index 0 with
- // buffer size one byte less than needed.
- if (outputType == OutputType::INSUFFICIENT) {
- if (s > 1 && !isZeroSized(golden, index)) {
- s -= 1;
- } else {
- sizeLargerThanOne = false;
- }
- }
- }
RequestArgument arg = {
- .location = {.poolIndex = OUTPUT, .offset = 0, .length = static_cast<uint32_t>(s)},
- .dimensions = {},
+ .location = {.poolIndex = OUTPUT,
+ .offset = 0,
+ .length = static_cast<uint32_t>(s)},
+ .dimensions = {},
};
outputs_info[index] = arg;
outputSize += s;
});
- // If output0 does not have size larger than one byte,
- // we can not provide an insufficient buffer
- if (!sizeLargerThanOne && outputType == OutputType::INSUFFICIENT) return;
// Compute offset for outputs 1 and so on
{
size_t offset = 0;
@@ -248,107 +147,17 @@
const Request request = {.inputs = inputs_info, .outputs = outputs_info, .pools = pools};
- ErrorStatus executionStatus;
- hidl_vec<OutputShape> outputShapes;
- Timing timing;
- switch (executor) {
- case Executor::ASYNC: {
- SCOPED_TRACE("asynchronous");
+ // launch execution
+ sp<ExecutionCallback> executionCallback = new ExecutionCallback();
+ ASSERT_NE(nullptr, executionCallback.get());
+ Return<ErrorStatus> executionLaunchStatus =
+ preparedModel->execute(request, executionCallback);
+ ASSERT_TRUE(executionLaunchStatus.isOk());
+ EXPECT_EQ(ErrorStatus::NONE, static_cast<ErrorStatus>(executionLaunchStatus));
- // launch execution
- sp<ExecutionCallback> executionCallback = new ExecutionCallback();
- ASSERT_NE(nullptr, executionCallback.get());
- Return<ErrorStatus> executionLaunchStatus =
- ExecutePreparedModel(preparedModel, request, measure, executionCallback);
- ASSERT_TRUE(executionLaunchStatus.isOk());
- EXPECT_EQ(ErrorStatus::NONE, static_cast<ErrorStatus>(executionLaunchStatus));
-
- // retrieve execution status
- executionCallback->wait();
- executionStatus = executionCallback->getStatus();
- outputShapes = executionCallback->getOutputShapes();
- timing = executionCallback->getTiming();
-
- break;
- }
- case Executor::SYNC: {
- SCOPED_TRACE("synchronous");
-
- // execute
- Return<ErrorStatus> executionReturnStatus = ExecutePreparedModel(
- preparedModel, request, measure, &outputShapes, &timing);
- ASSERT_TRUE(executionReturnStatus.isOk());
- executionStatus = static_cast<ErrorStatus>(executionReturnStatus);
-
- break;
- }
- case Executor::BURST: {
- SCOPED_TRACE("burst");
-
- // create burst
- const std::shared_ptr<::android::nn::ExecutionBurstController> controller =
- CreateBurst(preparedModel);
- ASSERT_NE(nullptr, controller.get());
-
- // create memory keys
- std::vector<intptr_t> keys(request.pools.size());
- for (size_t i = 0; i < keys.size(); ++i) {
- keys[i] = reinterpret_cast<intptr_t>(&request.pools[i]);
- }
-
- // execute burst
- std::tie(executionStatus, outputShapes, timing) =
- controller->compute(request, measure, keys);
-
- break;
- }
- }
-
- if (outputType != OutputType::FULLY_SPECIFIED &&
- executionStatus == ErrorStatus::GENERAL_FAILURE) {
- LOG(INFO) << "NN VTS: Early termination of test because vendor service cannot "
- "execute model that it does not support.";
- std::cout << "[ ] Early termination of test because vendor service cannot "
- "execute model that it does not support."
- << std::endl;
- GTEST_SKIP();
- }
- if (measure == MeasureTiming::NO) {
- EXPECT_EQ(UINT64_MAX, timing.timeOnDevice);
- EXPECT_EQ(UINT64_MAX, timing.timeInDriver);
- } else {
- if (timing.timeOnDevice != UINT64_MAX && timing.timeInDriver != UINT64_MAX) {
- EXPECT_LE(timing.timeOnDevice, timing.timeInDriver);
- }
- }
-
- switch (outputType) {
- case OutputType::FULLY_SPECIFIED:
- // If the model output operands are fully specified, outputShapes must be either
- // either empty, or have the same number of elements as the number of outputs.
- ASSERT_EQ(ErrorStatus::NONE, executionStatus);
- ASSERT_TRUE(outputShapes.size() == 0 ||
- outputShapes.size() == test.operandDimensions.size());
- break;
- case OutputType::UNSPECIFIED:
- // If the model output operands are not fully specified, outputShapes must have
- // the same number of elements as the number of outputs.
- ASSERT_EQ(ErrorStatus::NONE, executionStatus);
- ASSERT_EQ(outputShapes.size(), test.operandDimensions.size());
- break;
- case OutputType::INSUFFICIENT:
- ASSERT_EQ(ErrorStatus::OUTPUT_INSUFFICIENT_SIZE, executionStatus);
- ASSERT_EQ(outputShapes.size(), test.operandDimensions.size());
- ASSERT_FALSE(outputShapes[0].isSufficient);
- return;
- }
- // Go through all outputs, overwrite output dimensions with returned output shapes
- if (outputShapes.size() > 0) {
- for_each<uint32_t>(test.operandDimensions,
- [&outputShapes](int idx, std::vector<uint32_t>& dim) {
- dim = outputShapes[idx].dimensions;
- });
- }
+ // retrieve execution status
+ executionCallback->wait();
+ ASSERT_EQ(ErrorStatus::NONE, executionCallback->getStatus());
// validate results
outputMemory->read();
@@ -360,89 +169,22 @@
// We want "close-enough" results for float
compare(filtered_golden, filtered_test, fpAtol, fpRtol);
-
- if (example.expectedMultinomialDistributionTolerance > 0) {
- expectMultinomialDistributionWithinTolerance(test, example);
- }
- }
-}
-template <typename T_IPreparedModel>
-void EvaluatePreparedModel(sp<T_IPreparedModel>& preparedModel, std::function<bool(int)> is_ignored,
- const std::vector<MixedTypedExample>& examples,
- bool hasRelaxedFloat32Model, Executor executor, MeasureTiming measure,
- OutputType outputType) {
- EvaluatePreparedModel(preparedModel, is_ignored, examples, hasRelaxedFloat32Model, kDefaultAtol,
- kDefaultRtol, executor, measure, outputType);
-}
-
-void EvaluatePreparedModel(sp<V1_2::IPreparedModel>& preparedModel,
- std::function<bool(int)> is_ignored,
- const std::vector<MixedTypedExample>& examples,
- bool hasRelaxedFloat32Model, bool testDynamicOutputShape) {
- if (testDynamicOutputShape) {
- EvaluatePreparedModel(preparedModel, is_ignored, examples, hasRelaxedFloat32Model,
- Executor::ASYNC, MeasureTiming::NO, OutputType::UNSPECIFIED);
- EvaluatePreparedModel(preparedModel, is_ignored, examples, hasRelaxedFloat32Model,
- Executor::SYNC, MeasureTiming::NO, OutputType::UNSPECIFIED);
- EvaluatePreparedModel(preparedModel, is_ignored, examples, hasRelaxedFloat32Model,
- Executor::BURST, MeasureTiming::NO, OutputType::UNSPECIFIED);
- EvaluatePreparedModel(preparedModel, is_ignored, examples, hasRelaxedFloat32Model,
- Executor::ASYNC, MeasureTiming::YES, OutputType::UNSPECIFIED);
- EvaluatePreparedModel(preparedModel, is_ignored, examples, hasRelaxedFloat32Model,
- Executor::SYNC, MeasureTiming::YES, OutputType::UNSPECIFIED);
- EvaluatePreparedModel(preparedModel, is_ignored, examples, hasRelaxedFloat32Model,
- Executor::BURST, MeasureTiming::YES, OutputType::UNSPECIFIED);
- EvaluatePreparedModel(preparedModel, is_ignored, examples, hasRelaxedFloat32Model,
- Executor::ASYNC, MeasureTiming::NO, OutputType::INSUFFICIENT);
- EvaluatePreparedModel(preparedModel, is_ignored, examples, hasRelaxedFloat32Model,
- Executor::SYNC, MeasureTiming::NO, OutputType::INSUFFICIENT);
- EvaluatePreparedModel(preparedModel, is_ignored, examples, hasRelaxedFloat32Model,
- Executor::BURST, MeasureTiming::NO, OutputType::INSUFFICIENT);
- EvaluatePreparedModel(preparedModel, is_ignored, examples, hasRelaxedFloat32Model,
- Executor::ASYNC, MeasureTiming::YES, OutputType::INSUFFICIENT);
- EvaluatePreparedModel(preparedModel, is_ignored, examples, hasRelaxedFloat32Model,
- Executor::SYNC, MeasureTiming::YES, OutputType::INSUFFICIENT);
- EvaluatePreparedModel(preparedModel, is_ignored, examples, hasRelaxedFloat32Model,
- Executor::BURST, MeasureTiming::YES, OutputType::INSUFFICIENT);
- } else {
- EvaluatePreparedModel(preparedModel, is_ignored, examples, hasRelaxedFloat32Model,
- Executor::ASYNC, MeasureTiming::NO, OutputType::FULLY_SPECIFIED);
- EvaluatePreparedModel(preparedModel, is_ignored, examples, hasRelaxedFloat32Model,
- Executor::SYNC, MeasureTiming::NO, OutputType::FULLY_SPECIFIED);
- EvaluatePreparedModel(preparedModel, is_ignored, examples, hasRelaxedFloat32Model,
- Executor::BURST, MeasureTiming::NO, OutputType::FULLY_SPECIFIED);
- EvaluatePreparedModel(preparedModel, is_ignored, examples, hasRelaxedFloat32Model,
- Executor::ASYNC, MeasureTiming::YES, OutputType::FULLY_SPECIFIED);
- EvaluatePreparedModel(preparedModel, is_ignored, examples, hasRelaxedFloat32Model,
- Executor::SYNC, MeasureTiming::YES, OutputType::FULLY_SPECIFIED);
- EvaluatePreparedModel(preparedModel, is_ignored, examples, hasRelaxedFloat32Model,
- Executor::BURST, MeasureTiming::YES, OutputType::FULLY_SPECIFIED);
}
}
-static void getPreparedModel(sp<PreparedModelCallback> callback,
- sp<V1_0::IPreparedModel>* preparedModel) {
- *preparedModel = callback->getPreparedModel();
-}
-static void getPreparedModel(sp<PreparedModelCallback> callback,
- sp<V1_2::IPreparedModel>* preparedModel) {
- sp<V1_0::IPreparedModel> preparedModelV1_0 = callback->getPreparedModel();
- *preparedModel = V1_2::IPreparedModel::castFrom(preparedModelV1_0).withDefault(nullptr);
-}
-
-void Execute(const sp<V1_0::IDevice>& device, std::function<V1_0::Model(void)> create_model,
+void Execute(const sp<IDevice>& device, std::function<Model(void)> create_model,
std::function<bool(int)> is_ignored, const std::vector<MixedTypedExample>& examples) {
- V1_0::Model model = create_model();
+ Model model = create_model();
// 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; });
- });
+ 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
@@ -455,8 +197,7 @@
// retrieve prepared model
preparedModelCallback->wait();
ErrorStatus prepareReturnStatus = preparedModelCallback->getStatus();
- sp<V1_0::IPreparedModel> preparedModel;
- getPreparedModel(preparedModelCallback, &preparedModel);
+ sp<IPreparedModel> preparedModel = preparedModelCallback->getPreparedModel();
// early termination if vendor service cannot fully prepare model
if (!fullySupportsModel && prepareReturnStatus != ErrorStatus::NONE) {
@@ -472,115 +213,10 @@
ASSERT_NE(nullptr, preparedModel.get());
float fpAtol = 1e-5f, fpRtol = 5.0f * 1.1920928955078125e-7f;
- EvaluatePreparedModel(preparedModel, is_ignored, examples,
- /*hasRelaxedFloat32Model=*/false, fpAtol, fpRtol, Executor::ASYNC,
- MeasureTiming::NO, OutputType::FULLY_SPECIFIED);
-}
-
-void Execute(const sp<V1_1::IDevice>& device, std::function<V1_1::Model(void)> create_model,
- std::function<bool(int)> is_ignored, const std::vector<MixedTypedExample>& examples) {
- V1_1::Model model = create_model();
-
- // 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();
- ASSERT_NE(nullptr, preparedModelCallback.get());
- 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<V1_0::IPreparedModel> preparedModel;
- getPreparedModel(preparedModelCallback, &preparedModel);
-
- // 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, is_ignored, examples,
- model.relaxComputationFloat32toFloat16, 1e-5f, 1e-5f, Executor::ASYNC,
- MeasureTiming::NO, OutputType::FULLY_SPECIFIED);
-}
-
-void PrepareModel(const sp<V1_2::IDevice>& device, const V1_2::Model& model,
- sp<V1_2::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();
- ASSERT_NE(nullptr, preparedModelCallback.get());
- 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();
- getPreparedModel(preparedModelCallback, preparedModel);
-
- // 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());
-}
-
-// TODO: Reduce code duplication.
-void Execute(const sp<V1_2::IDevice>& device, std::function<V1_2::Model(void)> create_model,
- std::function<bool(int)> is_ignored, const std::vector<MixedTypedExample>& examples,
- bool testDynamicOutputShape) {
- V1_2::Model model = create_model();
- sp<V1_2::IPreparedModel> preparedModel = nullptr;
- PrepareModel(device, model, &preparedModel);
- if (preparedModel == nullptr) {
- GTEST_SKIP();
- }
- EvaluatePreparedModel(preparedModel, is_ignored, examples,
- model.relaxComputationFloat32toFloat16, testDynamicOutputShape);
+ EvaluatePreparedModel(preparedModel, is_ignored, examples, fpAtol, fpRtol);
}
} // namespace generated_tests
-
} // namespace neuralnetworks
} // namespace hardware
} // namespace android
diff --git a/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.h b/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.h
index c7d2399..11950d9 100644
--- a/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.h
+++ b/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.h
@@ -14,14 +14,11 @@
* limitations under the License.
*/
-#ifndef VTS_HAL_NEURALNETWORKS_GENERATED_TEST_HARNESS_H
-#define VTS_HAL_NEURALNETWORKS_GENERATED_TEST_HARNESS_H
-
-#include "TestHarness.h"
+#ifndef ANDROID_HARDWARE_NEURALNETWORKS_V1_0_GENERATED_TEST_HARNESS_H
+#define ANDROID_HARDWARE_NEURALNETWORKS_V1_0_GENERATED_TEST_HARNESS_H
#include <android/hardware/neuralnetworks/1.0/IDevice.h>
-#include <android/hardware/neuralnetworks/1.1/IDevice.h>
-#include <android/hardware/neuralnetworks/1.2/IDevice.h>
+#include "TestHarness.h"
namespace android {
namespace hardware {
@@ -30,28 +27,13 @@
namespace generated_tests {
using ::test_helper::MixedTypedExample;
-void PrepareModel(const sp<V1_2::IDevice>& device, const V1_2::Model& model,
- sp<V1_2::IPreparedModel>* preparedModel);
-
-void EvaluatePreparedModel(sp<V1_2::IPreparedModel>& preparedModel,
- std::function<bool(int)> is_ignored,
- const std::vector<MixedTypedExample>& examples,
- bool hasRelaxedFloat32Model, bool testDynamicOutputShape);
-
void Execute(const sp<V1_0::IDevice>& device, std::function<V1_0::Model(void)> create_model,
std::function<bool(int)> is_ignored, const std::vector<MixedTypedExample>& examples);
-void Execute(const sp<V1_1::IDevice>& device, std::function<V1_1::Model(void)> create_model,
- std::function<bool(int)> is_ignored, const std::vector<MixedTypedExample>& examples);
-
-void Execute(const sp<V1_2::IDevice>& device, std::function<V1_2::Model(void)> create_model,
- std::function<bool(int)> is_ignored, const std::vector<MixedTypedExample>& examples,
- bool testDynamicOutputShape = false);
-
} // namespace generated_tests
} // namespace neuralnetworks
} // namespace hardware
} // namespace android
-#endif // VTS_HAL_NEURALNETWORKS_GENERATED_TEST_HARNESS_H
+#endif // ANDROID_HARDWARE_NEURALNETWORKS_V1_0_GENERATED_TEST_HARNESS_H
diff --git a/neuralnetworks/1.0/vts/functional/GeneratedTests.cpp b/neuralnetworks/1.0/vts/functional/GeneratedTestsV1_0.cpp
similarity index 83%
rename from neuralnetworks/1.0/vts/functional/GeneratedTests.cpp
rename to neuralnetworks/1.0/vts/functional/GeneratedTestsV1_0.cpp
index d1c7de3..32e9a7f 100644
--- a/neuralnetworks/1.0/vts/functional/GeneratedTests.cpp
+++ b/neuralnetworks/1.0/vts/functional/GeneratedTestsV1_0.cpp
@@ -16,17 +16,16 @@
#define LOG_TAG "neuralnetworks_hidl_hal_test"
-#include "VtsHalNeuralnetworks.h"
-
-#include "Callbacks.h"
-#include "GeneratedTestHarness.h"
-#include "TestHarness.h"
-#include "Utils.h"
-
#include <android-base/logging.h>
#include <android/hidl/memory/1.0/IMemory.h>
#include <hidlmemory/mapping.h>
+#include "1.0/Callbacks.h"
+#include "GeneratedTestHarness.h"
+#include "MemoryUtils.h"
+#include "TestHarness.h"
+#include "VtsHalNeuralnetworks.h"
+
namespace android {
namespace hardware {
namespace neuralnetworks {
@@ -34,15 +33,16 @@
namespace vts {
namespace functional {
-using ::android::hardware::neuralnetworks::V1_2::implementation::ExecutionCallback;
-using ::android::hardware::neuralnetworks::V1_2::implementation::PreparedModelCallback;
+using ::android::hardware::neuralnetworks::V1_0::implementation::ExecutionCallback;
+using ::android::hardware::neuralnetworks::V1_0::implementation::PreparedModelCallback;
+using ::android::hidl::memory::V1_0::IMemory;
using ::android::nn::allocateSharedMemory;
using ::test_helper::MixedTypedExample;
std::vector<Request> createRequests(const std::vector<MixedTypedExample>& examples);
// in frameworks/ml/nn/runtime/tests/generated/
-#include "all_generated_V1_0_vts_tests.cpp"
+#include "vts/V1_0/all_generated_V1_0_vts_tests.cpp"
} // namespace functional
} // namespace vts
diff --git a/neuralnetworks/1.0/vts/functional/Utils.cpp b/neuralnetworks/1.0/vts/functional/Utils.cpp
new file mode 100644
index 0000000..521e524
--- /dev/null
+++ b/neuralnetworks/1.0/vts/functional/Utils.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "GeneratedTestHarness.h"
+#include "TestHarness.h"
+
+#include <android/hardware/neuralnetworks/1.0/types.h>
+
+#include <cstring>
+#include <map>
+#include <vector>
+
+namespace android {
+namespace hardware {
+namespace neuralnetworks {
+
+using ::android::hardware::neuralnetworks::V1_0::RequestArgument;
+using ::test_helper::for_each;
+using ::test_helper::MixedTyped;
+
+template <typename T>
+void copy_back_(std::map<int, std::vector<T>>* dst, const std::vector<RequestArgument>& ra,
+ char* src) {
+ for_each<T>(*dst, [&ra, src](int index, std::vector<T>& m) {
+ ASSERT_EQ(m.size(), ra[index].location.length / sizeof(T));
+ char* begin = src + ra[index].location.offset;
+ memcpy(m.data(), begin, ra[index].location.length);
+ });
+}
+
+void copy_back(MixedTyped* dst, const std::vector<RequestArgument>& ra, char* src) {
+ copy_back_(&dst->float32Operands, ra, src);
+ copy_back_(&dst->int32Operands, ra, src);
+ copy_back_(&dst->quant8AsymmOperands, ra, src);
+ copy_back_(&dst->quant16SymmOperands, ra, src);
+ copy_back_(&dst->float16Operands, ra, src);
+ copy_back_(&dst->bool8Operands, ra, src);
+ copy_back_(&dst->quant8ChannelOperands, ra, src);
+ copy_back_(&dst->quant16AsymmOperands, ra, src);
+ copy_back_(&dst->quant8SymmOperands, ra, src);
+ static_assert(9 == MixedTyped::kNumTypes,
+ "Number of types in MixedTyped changed, but copy_back function wasn't updated");
+}
+
+} // namespace neuralnetworks
+} // namespace hardware
+} // namespace android
diff --git a/neuralnetworks/1.0/vts/functional/ValidateModel.cpp b/neuralnetworks/1.0/vts/functional/ValidateModel.cpp
index 5d24fb5..72c4a2b 100644
--- a/neuralnetworks/1.0/vts/functional/ValidateModel.cpp
+++ b/neuralnetworks/1.0/vts/functional/ValidateModel.cpp
@@ -18,7 +18,7 @@
#include "VtsHalNeuralnetworks.h"
-#include "Callbacks.h"
+#include "1.0/Callbacks.h"
namespace android {
namespace hardware {
@@ -27,8 +27,8 @@
namespace vts {
namespace functional {
-using ::android::hardware::neuralnetworks::V1_2::implementation::ExecutionCallback;
-using ::android::hardware::neuralnetworks::V1_2::implementation::PreparedModelCallback;
+using ::android::hardware::neuralnetworks::V1_0::implementation::ExecutionCallback;
+using ::android::hardware::neuralnetworks::V1_0::implementation::PreparedModelCallback;
///////////////////////// UTILITY FUNCTIONS /////////////////////////
diff --git a/neuralnetworks/1.0/vts/functional/ValidateRequest.cpp b/neuralnetworks/1.0/vts/functional/ValidateRequest.cpp
index f0c93b7..058eb25 100644
--- a/neuralnetworks/1.0/vts/functional/ValidateRequest.cpp
+++ b/neuralnetworks/1.0/vts/functional/ValidateRequest.cpp
@@ -16,16 +16,15 @@
#define LOG_TAG "neuralnetworks_hidl_hal_test"
-#include "VtsHalNeuralnetworks.h"
-
-#include "Callbacks.h"
-#include "TestHarness.h"
-#include "Utils.h"
-
#include <android-base/logging.h>
#include <android/hidl/memory/1.0/IMemory.h>
#include <hidlmemory/mapping.h>
+#include "1.0/Callbacks.h"
+#include "MemoryUtils.h"
+#include "TestHarness.h"
+#include "VtsHalNeuralnetworks.h"
+
namespace android {
namespace hardware {
namespace neuralnetworks {
@@ -33,7 +32,7 @@
namespace vts {
namespace functional {
-using ::android::hardware::neuralnetworks::V1_2::implementation::ExecutionCallback;
+using ::android::hardware::neuralnetworks::V1_0::implementation::ExecutionCallback;
using ::android::hidl::memory::V1_0::IMemory;
using test_helper::for_all;
using test_helper::MixedTyped;
@@ -121,11 +120,13 @@
for_all(inputs, [&inputs_info, &inputSize](int index, auto, auto s) {
if (inputs_info.size() <= static_cast<size_t>(index)) inputs_info.resize(index + 1);
RequestArgument arg = {
- .location = {.poolIndex = INPUT, .offset = 0, .length = static_cast<uint32_t>(s)},
- .dimensions = {},
+ .location = {.poolIndex = INPUT,
+ .offset = 0,
+ .length = static_cast<uint32_t>(s)},
+ .dimensions = {},
};
RequestArgument arg_empty = {
- .hasNoValue = true,
+ .hasNoValue = true,
};
inputs_info[index] = s ? arg : arg_empty;
inputSize += s;
@@ -143,8 +144,10 @@
for_all(outputs, [&outputs_info, &outputSize](int index, auto, auto s) {
if (outputs_info.size() <= static_cast<size_t>(index)) outputs_info.resize(index + 1);
RequestArgument arg = {
- .location = {.poolIndex = OUTPUT, .offset = 0, .length = static_cast<uint32_t>(s)},
- .dimensions = {},
+ .location = {.poolIndex = OUTPUT,
+ .offset = 0,
+ .length = static_cast<uint32_t>(s)},
+ .dimensions = {},
};
outputs_info[index] = arg;
outputSize += s;
diff --git a/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworks.cpp b/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworks.cpp
index aee2f85..95b7ad3 100644
--- a/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworks.cpp
+++ b/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworks.cpp
@@ -20,7 +20,7 @@
#include <android-base/logging.h>
-#include "Callbacks.h"
+#include "1.0/Callbacks.h"
namespace android {
namespace hardware {
@@ -29,7 +29,7 @@
namespace vts {
namespace functional {
-using ::android::hardware::neuralnetworks::V1_2::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) {
diff --git a/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworks.h b/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworks.h
index 22285be..c32a91d 100644
--- a/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworks.h
+++ b/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworks.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef VTS_HAL_NEURALNETWORKS_V1_0_TARGET_TESTS_H
-#define VTS_HAL_NEURALNETWORKS_V1_0_TARGET_TESTS_H
+#ifndef ANDROID_HARDWARE_NEURALNETWORKS_V1_0_VTS_HAL_NEURALNETWORKS_H
+#define ANDROID_HARDWARE_NEURALNETWORKS_V1_0_VTS_HAL_NEURALNETWORKS_H
#include <android/hardware/neuralnetworks/1.0/IDevice.h>
#include <android/hardware/neuralnetworks/1.0/types.h>
@@ -89,4 +89,4 @@
} // namespace android::hardware::neuralnetworks::V1_0
-#endif // VTS_HAL_NEURALNETWORKS_V1_0_TARGET_TESTS_H
+#endif // ANDROID_HARDWARE_NEURALNETWORKS_V1_0_VTS_HAL_NEURALNETWORKS_H
diff --git a/neuralnetworks/1.0/vts/functional/include/1.0/Callbacks.h b/neuralnetworks/1.0/vts/functional/include/1.0/Callbacks.h
new file mode 100644
index 0000000..820bb10
--- /dev/null
+++ b/neuralnetworks/1.0/vts/functional/include/1.0/Callbacks.h
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_NEURALNETWORKS_V1_0_CALLBACKS_H
+#define ANDROID_HARDWARE_NEURALNETWORKS_V1_0_CALLBACKS_H
+
+#include <android-base/thread_annotations.h>
+#include <android/hardware/neuralnetworks/1.0/IExecutionCallback.h>
+#include <android/hardware/neuralnetworks/1.0/IPreparedModelCallback.h>
+#include <hidl/Status.h>
+#include <condition_variable>
+#include <mutex>
+
+/*
+ * The Callback classes are used internally by the NeuralNetworks runtime to
+ * synchronize between different threads. An asynchronous task is launched
+ * paired with a callback object. When a client thread requires the output being
+ * generated by the asynchronous task, the client thread can wait for the result
+ * and be blocked until it has completed. Any wait may safely be called
+ * concurrently, even on the same callback object. When the asynchronous task
+ * has finished its workload, it must immediately call "notify". If the
+ * asynchronous task has failed to launch, the function that tried to launch the
+ * asynchronous task must immediately call "notify". This "notify" call
+ * awakens any client threads waiting on the callback object.
+ *
+ * These classes exist to enable synchronization across HIDL. When
+ * synchronization is only required in the same process, consider using
+ * std::future, std::mutex, std::condition_variable, or std::experimental::latch
+ * instead.
+ */
+
+namespace android::hardware::neuralnetworks::V1_0::implementation {
+
+/**
+ * The PreparedModelCallback class is used to receive the error status of
+ * preparing a model as well as the prepared model from a task executing
+ * asynchronously with respect to the runtime. If a calling thread calls wait
+ * or get* on a PreparedModelCallback object and the corresponding asynchronous
+ * task has not finished preparing the model, the calling thread will block
+ * until the asynchronous task has called notify.
+ *
+ * If the callback object is notified more than once, only the results of the
+ * first call to notify are used, and the results from subsequent calls are
+ * discarded.
+ *
+ * This callback object is passed as an argument to IDevice::prepareModel*.
+ */
+class PreparedModelCallback : public IPreparedModelCallback {
+ public:
+ /**
+ * IPreparedModelCallback::notify marks the callback object with the return
+ * status of the asynchronous model preparation along with the prepared
+ * model, and allows all prior and future wait calls on the
+ * PreparedModelCallback object to proceed.
+ *
+ * IPreparedModelCallback::notify must be called on a given
+ * PreparedModelCallback object.
+ *
+ * If the callback object is notified more than once, only the results of
+ * the first call to notify are used, and the results from subsequent calls
+ * are discarded.
+ *
+ * @param status Error status returned from asynchronously preparing the
+ * model; will be:
+ * - NONE if the asynchronous preparation was successful
+ * - DEVICE_UNAVAILABLE if driver is offline or busy
+ * - GENERAL_FAILURE if there is an unspecified error
+ * - INVALID_ARGUMENT if the input model is invalid
+ * @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<IPreparedModel>& preparedModel) override;
+
+ /**
+ * PreparedModelCallback::wait blocks until notify has been called on the
+ * callback object.
+ */
+ void wait() const;
+
+ /**
+ * Retrieves the error status returned from the asynchronous task launched
+ * by IDevice::prepareModel*. If IDevice::prepareModel* has not finished
+ * asynchronously preparing the model, this call will block until the
+ * asynchronous task notifies the object.
+ *
+ * @return status Error status returned from asynchronously preparing the
+ * model; will be:
+ * - NONE if the asynchronous preparation was successful
+ * - DEVICE_UNAVAILABLE if driver is offline or busy
+ * - GENERAL_FAILURE if there is an unspecified error
+ * - INVALID_ARGUMENT if the input model is invalid
+ */
+ ErrorStatus getStatus() const;
+
+ /**
+ * Retrieves the model that has been prepared for execution from the
+ * asynchronous task launched by IDevice::prepareModel*. If
+ * IDevice::prepareModel* has not finished asynchronously preparing the
+ * model, this call will block until the asynchronous task notifies the
+ * object.
+ *
+ * @return preparedModel Returned model that has been prepared for
+ * execution, nullptr if the model was unable to be prepared.
+ */
+ sp<IPreparedModel> getPreparedModel() const;
+
+ private:
+ mutable std::mutex mMutex;
+ mutable std::condition_variable mCondition;
+ bool mNotified GUARDED_BY(mMutex) = false;
+ ErrorStatus mErrorStatus = ErrorStatus::GENERAL_FAILURE;
+ sp<IPreparedModel> mPreparedModel;
+};
+
+/**
+ * The ExecutionCallback class is used to receive the results of the execution
+ * from a task executing asynchronously with respect to the runtime. If a
+ * calling thread calls wait or get* on a ExecutionCallback object and the
+ * corresponding asynchronous task has not finished the execution, the calling
+ * thread will block until the asynchronous task has called notify.
+ *
+ * If the callback object is notified more than once, only the results of the
+ * first call to notify are used, and the results from subsequent calls are
+ * discarded.
+ *
+ * This callback object is passed as an argument to IPreparedModel::execute*.
+ */
+class ExecutionCallback : public IExecutionCallback {
+ public:
+ /**
+ * IExecutionCallback::notify marks the callback object with the return
+ * status of the asynchronous execution that held this callback and enables
+ * all prior and future wait calls on the ExecutionCallback object to
+ * proceed.
+ *
+ * IExecutionCallback::notify must be called on a given ExecutionCallback
+ * object.
+ *
+ * If the callback object is notified more than once, only the results of
+ * the first call to notify are used, and the results from subsequent calls
+ * are discarded.
+ *
+ * @param status Error status returned from launching the asynchronous task
+ * (if the launch fails) or from the asynchronous task itself (if the
+ * launch succeeds). Must be:
+ * - NONE if the asynchronous execution was successful
+ * - DEVICE_UNAVAILABLE if driver is offline or busy
+ * - GENERAL_FAILURE if there is an unspecified error
+ * - OUTPUT_INSUFFICIENT_SIZE if provided output buffer is not large
+ * enough to store the resultant values
+ * - INVALID_ARGUMENT if the input request is invalid
+ */
+ Return<void> notify(ErrorStatus status) override;
+
+ /**
+ * ExecutionCallback::wait blocks until notify has been called on the
+ * callback object.
+ */
+ void wait() const;
+
+ /**
+ * Retrieves the error status returned from the asynchronous task launched
+ * by IPreparedModel::execute. If IPreparedModel::execute has not finished
+ * asynchronously executing, this call will block until the asynchronous
+ * task notifies the object.
+ *
+ * @return status Error status returned from launching the asynchronous task
+ * (if the launch fails) or from the asynchronous task itself (if the
+ * launch succeeds). Must be:
+ * - NONE if the asynchronous execution was successful
+ * - DEVICE_UNAVAILABLE if driver is offline or busy
+ * - GENERAL_FAILURE if the asynchronous task resulted in an unspecified
+ * error
+ * - OUTPUT_INSUFFICIENT_SIZE if at least one output operand buffer is
+ * not large enough to store the corresponding output
+ * - INVALID_ARGUMENT if one of the input arguments to prepareModel is
+ * invalid
+ */
+ ErrorStatus getStatus() const;
+
+ private:
+ mutable std::mutex mMutex;
+ mutable std::condition_variable mCondition;
+ bool mNotified GUARDED_BY(mMutex) = false;
+ ErrorStatus mErrorStatus = ErrorStatus::GENERAL_FAILURE;
+};
+
+} // namespace android::hardware::neuralnetworks::V1_0::implementation
+
+#endif // ANDROID_HARDWARE_NEURALNETWORKS_V1_0_CALLBACKS_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
new file mode 100644
index 0000000..b270c20
--- /dev/null
+++ b/neuralnetworks/1.0/vts/functional/include/1.0/Utils.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_NEURALNETWORKS_V1_0_UTILS_H
+#define ANDROID_HARDWARE_NEURALNETWORKS_V1_0_UTILS_H
+
+#include <android/hardware/neuralnetworks/1.0/types.h>
+#include <algorithm>
+#include <vector>
+#include "TestHarness.h"
+
+namespace android {
+namespace hardware {
+namespace neuralnetworks {
+
+void copy_back(::test_helper::MixedTyped* dst, const std::vector<V1_0::RequestArgument>& ra,
+ char* src);
+
+// Delete element from hidl_vec. hidl_vec doesn't support a "remove" operation,
+// so this is efficiently accomplished by moving the element to the end and
+// 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);
+ }
+}
+
+template <typename Type>
+inline uint32_t hidl_vec_push_back(hidl_vec<Type>* vec, const Type& value) {
+ // assume vec is valid
+ const uint32_t index = vec->size();
+ vec->resize(index + 1);
+ (*vec)[index] = value;
+ return index;
+}
+
+} // namespace neuralnetworks
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_NEURALNETWORKS_V1_0_UTILS_H
diff --git a/neuralnetworks/1.1/Android.bp b/neuralnetworks/1.1/Android.bp
index 1158a90..bef21c0 100644
--- a/neuralnetworks/1.1/Android.bp
+++ b/neuralnetworks/1.1/Android.bp
@@ -16,4 +16,3 @@
],
gen_java: false,
}
-
diff --git a/neuralnetworks/1.1/vts/functional/Android.bp b/neuralnetworks/1.1/vts/functional/Android.bp
index 4fbeac9..ee90ec6 100644
--- a/neuralnetworks/1.1/vts/functional/Android.bp
+++ b/neuralnetworks/1.1/vts/functional/Android.bp
@@ -14,10 +14,41 @@
// limitations under the License.
//
+cc_defaults {
+ name: "VtsHalNeuralNetworksV1_1TargetTestDefaults",
+ defaults: ["VtsHalTargetTestDefaults"],
+ srcs: [
+ "ValidateModel.cpp",
+ "ValidateRequest.cpp",
+ "VtsHalNeuralnetworks.cpp",
+ "GeneratedTestHarness.cpp",
+ ],
+ shared_libs: [
+ "libfmq",
+ "libnativewindow",
+ ],
+ static_libs: [
+ "android.hardware.neuralnetworks@1.0",
+ "android.hardware.neuralnetworks@1.1",
+ "android.hidl.allocator@1.0",
+ "android.hidl.memory@1.0",
+ "libgmock",
+ "libhidlmemory",
+ "libneuralnetworks_utils",
+ "VtsHalNeuralNetworksV1_0_utils",
+ ],
+ header_libs: [
+ "libneuralnetworks_headers",
+ "libneuralnetworks_generated_test_harness_headers",
+ "libneuralnetworks_generated_tests",
+ ],
+ test_suites: ["general-tests"],
+}
+
// Tests for V1_0 models using the V1_1 HAL.
cc_test {
name: "VtsHalNeuralnetworksV1_1CompatV1_0TargetTest",
- defaults: ["VtsHalNeuralNetworksTargetTestDefaults"],
+ defaults: ["VtsHalNeuralNetworksV1_1TargetTestDefaults"],
srcs: [
"GeneratedTestsV1_0.cpp",
],
@@ -26,19 +57,19 @@
// Tests for V1_1 models.
cc_test {
name: "VtsHalNeuralnetworksV1_1TargetTest",
- defaults: ["VtsHalNeuralNetworksTargetTestDefaults"],
+ defaults: ["VtsHalNeuralNetworksV1_1TargetTestDefaults"],
srcs: [
"BasicTests.cpp",
- "GeneratedTests.cpp",
+ "GeneratedTestsV1_1.cpp",
],
}
cc_test {
name: "PresubmitHalNeuralnetworksV1_1TargetTest",
- defaults: ["VtsHalNeuralNetworksTargetTestDefaults"],
+ defaults: ["VtsHalNeuralNetworksV1_1TargetTestDefaults"],
srcs: [
"BasicTests.cpp",
- "GeneratedTests.cpp",
+ "GeneratedTestsV1_1.cpp",
],
cflags: [
"-DPRESUBMIT_NOT_VTS",
diff --git a/neuralnetworks/1.1/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/1.1/vts/functional/GeneratedTestHarness.cpp
new file mode 100644
index 0000000..d9f64fd
--- /dev/null
+++ b/neuralnetworks/1.1/vts/functional/GeneratedTestHarness.cpp
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "GeneratedTestHarness.h"
+
+#include <android-base/logging.h>
+#include <android/hardware/neuralnetworks/1.0/IPreparedModel.h>
+#include <android/hardware/neuralnetworks/1.0/types.h>
+#include <android/hardware/neuralnetworks/1.1/IDevice.h>
+#include <android/hidl/allocator/1.0/IAllocator.h>
+#include <android/hidl/memory/1.0/IMemory.h>
+#include <hidlmemory/mapping.h>
+
+#include <iostream>
+
+#include "1.0/Callbacks.h"
+#include "1.0/Utils.h"
+#include "MemoryUtils.h"
+#include "TestHarness.h"
+
+namespace android {
+namespace hardware {
+namespace neuralnetworks {
+namespace generated_tests {
+
+using ::android::hardware::neuralnetworks::V1_0::ErrorStatus;
+using ::android::hardware::neuralnetworks::V1_0::IPreparedModel;
+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 ::test_helper::compare;
+using ::test_helper::filter;
+using ::test_helper::for_all;
+using ::test_helper::MixedTyped;
+using ::test_helper::MixedTypedExample;
+using ::test_helper::resize_accordingly;
+
+// 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(sp<IPreparedModel>& preparedModel, std::function<bool(int)> is_ignored,
+ const std::vector<MixedTypedExample>& examples,
+ bool hasRelaxedFloat32Model, float fpAtol, float fpRtol) {
+ const uint32_t INPUT = 0;
+ const uint32_t OUTPUT = 1;
+
+ int example_no = 1;
+ for (auto& example : examples) {
+ SCOPED_TRACE(example_no++);
+ const MixedTyped& inputs = example.operands.first;
+ const MixedTyped& golden = example.operands.second;
+
+ const bool hasFloat16Inputs = !inputs.float16Operands.empty();
+ if (hasRelaxedFloat32Model || hasFloat16Inputs) {
+ // TODO: Adjust the error limit based on testing.
+ // If in relaxed mode, set the absolute tolerance to be 5ULP of FP16.
+ fpAtol = 5.0f * 0.0009765625f;
+ // Set the relative tolerance to be 5ULP of the corresponding FP precision.
+ fpRtol = 5.0f * 0.0009765625f;
+ }
+
+ std::vector<RequestArgument> inputs_info, outputs_info;
+ uint32_t inputSize = 0, outputSize = 0;
+ // This function only partially specifies the metadata (vector of RequestArguments).
+ // The contents are copied over below.
+ for_all(inputs, [&inputs_info, &inputSize](int index, auto, auto s) {
+ if (inputs_info.size() <= static_cast<size_t>(index)) inputs_info.resize(index + 1);
+ RequestArgument arg = {
+ .location = {.poolIndex = INPUT,
+ .offset = 0,
+ .length = static_cast<uint32_t>(s)},
+ .dimensions = {},
+ };
+ RequestArgument arg_empty = {
+ .hasNoValue = true,
+ };
+ inputs_info[index] = s ? arg : arg_empty;
+ inputSize += s;
+ });
+ // Compute offset for inputs 1 and so on
+ {
+ size_t offset = 0;
+ for (auto& i : inputs_info) {
+ if (!i.hasNoValue) i.location.offset = offset;
+ offset += i.location.length;
+ }
+ }
+
+ MixedTyped test; // holding test results
+
+ // Go through all outputs, initialize RequestArgument descriptors
+ resize_accordingly(golden, test);
+ for_all(golden, [&outputs_info, &outputSize](int index, auto, auto s) {
+ if (outputs_info.size() <= static_cast<size_t>(index)) outputs_info.resize(index + 1);
+ RequestArgument arg = {
+ .location = {.poolIndex = OUTPUT,
+ .offset = 0,
+ .length = static_cast<uint32_t>(s)},
+ .dimensions = {},
+ };
+ outputs_info[index] = arg;
+ outputSize += s;
+ });
+ // Compute offset for outputs 1 and so on
+ {
+ size_t offset = 0;
+ for (auto& i : outputs_info) {
+ i.location.offset = offset;
+ offset += i.location.length;
+ }
+ }
+ std::vector<hidl_memory> pools = {nn::allocateSharedMemory(inputSize),
+ nn::allocateSharedMemory(outputSize)};
+ ASSERT_NE(0ull, pools[INPUT].size());
+ ASSERT_NE(0ull, pools[OUTPUT].size());
+
+ // load data
+ sp<IMemory> inputMemory = mapMemory(pools[INPUT]);
+ sp<IMemory> outputMemory = mapMemory(pools[OUTPUT]);
+ ASSERT_NE(nullptr, inputMemory.get());
+ ASSERT_NE(nullptr, outputMemory.get());
+ char* inputPtr = reinterpret_cast<char*>(static_cast<void*>(inputMemory->getPointer()));
+ char* outputPtr = reinterpret_cast<char*>(static_cast<void*>(outputMemory->getPointer()));
+ ASSERT_NE(nullptr, inputPtr);
+ ASSERT_NE(nullptr, outputPtr);
+ inputMemory->update();
+ outputMemory->update();
+
+ // Go through all inputs, copy the values
+ for_all(inputs, [&inputs_info, inputPtr](int index, auto p, auto s) {
+ char* begin = (char*)p;
+ char* end = begin + s;
+ // TODO: handle more than one input
+ std::copy(begin, end, inputPtr + inputs_info[index].location.offset);
+ });
+
+ inputMemory->commit();
+ outputMemory->commit();
+
+ const Request request = {.inputs = inputs_info, .outputs = outputs_info, .pools = pools};
+
+ // launch execution
+ sp<ExecutionCallback> executionCallback = new ExecutionCallback();
+ ASSERT_NE(nullptr, executionCallback.get());
+ Return<ErrorStatus> executionLaunchStatus =
+ preparedModel->execute(request, executionCallback);
+ ASSERT_TRUE(executionLaunchStatus.isOk());
+ EXPECT_EQ(ErrorStatus::NONE, static_cast<ErrorStatus>(executionLaunchStatus));
+
+ // retrieve execution status
+ executionCallback->wait();
+ ASSERT_EQ(ErrorStatus::NONE, executionCallback->getStatus());
+
+ // validate results
+ outputMemory->read();
+ copy_back(&test, outputs_info, outputPtr);
+ outputMemory->commit();
+ // Filter out don't cares
+ MixedTyped filtered_golden = filter(golden, is_ignored);
+ MixedTyped filtered_test = filter(test, is_ignored);
+
+ // We want "close-enough" results for float
+ compare(filtered_golden, filtered_test, fpAtol, fpRtol);
+ }
+}
+
+void Execute(const sp<IDevice>& device, std::function<Model(void)> create_model,
+ std::function<bool(int)> is_ignored, const std::vector<MixedTypedExample>& examples) {
+ Model model = create_model();
+
+ // 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();
+ ASSERT_NE(nullptr, preparedModelCallback.get());
+ 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, is_ignored, examples,
+ model.relaxComputationFloat32toFloat16, 1e-5f, 1e-5f);
+}
+
+} // namespace generated_tests
+} // namespace neuralnetworks
+} // namespace hardware
+} // namespace android
diff --git a/neuralnetworks/1.1/vts/functional/GeneratedTestHarness.h b/neuralnetworks/1.1/vts/functional/GeneratedTestHarness.h
new file mode 100644
index 0000000..ab71b2b
--- /dev/null
+++ b/neuralnetworks/1.1/vts/functional/GeneratedTestHarness.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_NEURALNETWORKS_V1_1_GENERATED_TEST_HARNESS_H
+#define ANDROID_HARDWARE_NEURALNETWORKS_V1_1_GENERATED_TEST_HARNESS_H
+
+#include <android/hardware/neuralnetworks/1.1/IDevice.h>
+#include <android/hardware/neuralnetworks/1.1/types.h>
+#include <functional>
+#include <vector>
+#include "TestHarness.h"
+
+namespace android {
+namespace hardware {
+namespace neuralnetworks {
+namespace generated_tests {
+
+void Execute(const sp<V1_1::IDevice>& device, std::function<V1_1::Model(void)> create_model,
+ std::function<bool(int)> is_ignored,
+ const std::vector<::test_helper::MixedTypedExample>& examples);
+
+} // namespace generated_tests
+} // namespace neuralnetworks
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_NEURALNETWORKS_V1_1_GENERATED_TEST_HARNESS_H
diff --git a/neuralnetworks/1.1/vts/functional/GeneratedTestsV1_0.cpp b/neuralnetworks/1.1/vts/functional/GeneratedTestsV1_0.cpp
index e67ef8e..23e6534 100644
--- a/neuralnetworks/1.1/vts/functional/GeneratedTestsV1_0.cpp
+++ b/neuralnetworks/1.1/vts/functional/GeneratedTestsV1_0.cpp
@@ -16,17 +16,16 @@
#define LOG_TAG "neuralnetworks_hidl_hal_test"
-#include "VtsHalNeuralnetworks.h"
-
-#include "Callbacks.h"
-#include "GeneratedTestHarness.h"
-#include "TestHarness.h"
-#include "Utils.h"
-
#include <android-base/logging.h>
#include <android/hidl/memory/1.0/IMemory.h>
#include <hidlmemory/mapping.h>
+#include "1.0/Callbacks.h"
+#include "GeneratedTestHarness.h"
+#include "MemoryUtils.h"
+#include "TestHarness.h"
+#include "VtsHalNeuralnetworks.h"
+
namespace android {
namespace hardware {
namespace neuralnetworks {
@@ -34,15 +33,17 @@
namespace vts {
namespace functional {
-using ::android::hardware::neuralnetworks::V1_2::implementation::ExecutionCallback;
-using ::android::hardware::neuralnetworks::V1_2::implementation::PreparedModelCallback;
+using ::android::hardware::neuralnetworks::V1_0::OperandLifeTime;
+using ::android::hardware::neuralnetworks::V1_0::implementation::ExecutionCallback;
+using ::android::hardware::neuralnetworks::V1_0::implementation::PreparedModelCallback;
+using ::android::hidl::memory::V1_0::IMemory;
using ::android::nn::allocateSharedMemory;
using ::test_helper::MixedTypedExample;
std::vector<Request> createRequests(const std::vector<MixedTypedExample>& examples);
// in frameworks/ml/nn/runtime/tests/generated/
-#include "all_generated_V1_0_vts_tests.cpp"
+#include "vts/V1_1/all_generated_V1_0_vts_tests.cpp"
} // namespace functional
} // namespace vts
diff --git a/neuralnetworks/1.1/vts/functional/GeneratedTests.cpp b/neuralnetworks/1.1/vts/functional/GeneratedTestsV1_1.cpp
similarity index 80%
rename from neuralnetworks/1.1/vts/functional/GeneratedTests.cpp
rename to neuralnetworks/1.1/vts/functional/GeneratedTestsV1_1.cpp
index 4db1276..680b93a 100644
--- a/neuralnetworks/1.1/vts/functional/GeneratedTests.cpp
+++ b/neuralnetworks/1.1/vts/functional/GeneratedTestsV1_1.cpp
@@ -16,17 +16,16 @@
#define LOG_TAG "neuralnetworks_hidl_hal_test"
-#include "VtsHalNeuralnetworks.h"
-
-#include "Callbacks.h"
-#include "GeneratedTestHarness.h"
-#include "TestHarness.h"
-#include "Utils.h"
-
#include <android-base/logging.h>
#include <android/hidl/memory/1.0/IMemory.h>
#include <hidlmemory/mapping.h>
+#include "1.0/Callbacks.h"
+#include "GeneratedTestHarness.h"
+#include "MemoryUtils.h"
+#include "TestHarness.h"
+#include "VtsHalNeuralnetworks.h"
+
namespace android {
namespace hardware {
namespace neuralnetworks {
@@ -34,15 +33,17 @@
namespace vts {
namespace functional {
-using ::android::hardware::neuralnetworks::V1_2::implementation::ExecutionCallback;
-using ::android::hardware::neuralnetworks::V1_2::implementation::PreparedModelCallback;
+using ::android::hardware::neuralnetworks::V1_0::OperandLifeTime;
+using ::android::hardware::neuralnetworks::V1_0::implementation::ExecutionCallback;
+using ::android::hardware::neuralnetworks::V1_0::implementation::PreparedModelCallback;
+using ::android::hidl::memory::V1_0::IMemory;
using ::android::nn::allocateSharedMemory;
using ::test_helper::MixedTypedExample;
std::vector<Request> createRequests(const std::vector<MixedTypedExample>& examples);
// in frameworks/ml/nn/runtime/tests/generated/
-#include "all_generated_V1_1_vts_tests.cpp"
+#include "vts/V1_1/all_generated_V1_1_vts_tests.cpp"
} // namespace functional
} // namespace vts
diff --git a/neuralnetworks/1.1/vts/functional/ValidateModel.cpp b/neuralnetworks/1.1/vts/functional/ValidateModel.cpp
index b35a901..fb80d13 100644
--- a/neuralnetworks/1.1/vts/functional/ValidateModel.cpp
+++ b/neuralnetworks/1.1/vts/functional/ValidateModel.cpp
@@ -16,25 +16,22 @@
#define LOG_TAG "neuralnetworks_hidl_hal_test"
+#include "1.0/Callbacks.h"
+#include "1.0/Utils.h"
#include "VtsHalNeuralnetworks.h"
-#include "Callbacks.h"
-
namespace android {
namespace hardware {
namespace neuralnetworks {
namespace V1_1 {
-
-using V1_0::IPreparedModel;
-using V1_0::Operand;
-using V1_0::OperandLifeTime;
-using V1_0::OperandType;
-
namespace vts {
namespace functional {
-using ::android::hardware::neuralnetworks::V1_2::implementation::ExecutionCallback;
-using ::android::hardware::neuralnetworks::V1_2::implementation::PreparedModelCallback;
+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;
///////////////////////// UTILITY FUNCTIONS /////////////////////////
@@ -42,10 +39,10 @@
const V1_1::Model& model) {
SCOPED_TRACE(message + " [getSupportedOperations_1_1]");
- Return<void> ret =
- device->getSupportedOperations_1_1(model, [&](ErrorStatus status, const hidl_vec<bool>&) {
- EXPECT_EQ(ErrorStatus::INVALID_ARGUMENT, status);
- });
+ Return<void> ret = device->getSupportedOperations_1_1(
+ model, [&](ErrorStatus status, const hidl_vec<bool>&) {
+ EXPECT_EQ(ErrorStatus::INVALID_ARGUMENT, status);
+ });
EXPECT_TRUE(ret.isOk());
}
@@ -56,7 +53,7 @@
sp<PreparedModelCallback> preparedModelCallback = new PreparedModelCallback();
ASSERT_NE(nullptr, preparedModelCallback.get());
Return<ErrorStatus> prepareLaunchStatus =
- device->prepareModel_1_1(model, preference, preparedModelCallback);
+ device->prepareModel_1_1(model, preference, preparedModelCallback);
ASSERT_TRUE(prepareLaunchStatus.isOk());
ASSERT_EQ(ErrorStatus::INVALID_ARGUMENT, static_cast<ErrorStatus>(prepareLaunchStatus));
@@ -87,36 +84,16 @@
validatePrepareModel(device, message, model, preference);
}
-// Delete element from hidl_vec. hidl_vec doesn't support a "remove" operation,
-// so this is efficiently accomplished by moving the element to the end and
-// resizing the hidl_vec to one less.
-template <typename Type>
-static 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);
- }
-}
-
-template <typename Type>
-static uint32_t hidl_vec_push_back(hidl_vec<Type>* vec, const Type& value) {
- // assume vec is valid
- const uint32_t index = vec->size();
- vec->resize(index + 1);
- (*vec)[index] = value;
- return index;
-}
-
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},
});
}
@@ -130,10 +107,10 @@
///////////////////////// 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_1::Model& model) {
@@ -226,7 +203,7 @@
static void mutateOperandZeroPointTest(const sp<IDevice>& device, const V1_1::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 " +
@@ -258,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:
@@ -319,10 +296,10 @@
///////////////////////// VALIDATE MODEL OPERATION TYPE /////////////////////////
static const int32_t invalidOperationTypes[] = {
- static_cast<int32_t>(OperationType::ADD) - 1, // lower bound fundamental
- static_cast<int32_t>(OperationType::TRANSPOSE) + 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::TRANSPOSE) + 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_1::Model& model) {
@@ -333,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);
});
}
}
@@ -486,7 +463,7 @@
static void addOperationOutputTest(const sp<IDevice>& device, const V1_1::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);
@@ -498,14 +475,14 @@
///////////////////////// VALIDATE EXECUTION PREFERENCE /////////////////////////
static const int32_t invalidExecutionPreferences[] = {
- static_cast<int32_t>(ExecutionPreference::LOW_POWER) - 1, // lower bound
- static_cast<int32_t>(ExecutionPreference::SUSTAINED_SPEED) + 1, // upper bound
+ static_cast<int32_t>(ExecutionPreference::LOW_POWER) - 1, // lower bound
+ static_cast<int32_t>(ExecutionPreference::SUSTAINED_SPEED) + 1, // upper bound
};
static void mutateExecutionPreferenceTest(const sp<IDevice>& device, const V1_1::Model& model) {
for (int32_t preference : invalidExecutionPreferences) {
const std::string message =
- "mutateExecutionPreferenceTest: preference " + std::to_string(preference);
+ "mutateExecutionPreferenceTest: preference " + std::to_string(preference);
validate(device, message, model, [](Model*) {},
static_cast<ExecutionPreference>(preference));
}
diff --git a/neuralnetworks/1.1/vts/functional/ValidateRequest.cpp b/neuralnetworks/1.1/vts/functional/ValidateRequest.cpp
index f4adbab..c549728 100644
--- a/neuralnetworks/1.1/vts/functional/ValidateRequest.cpp
+++ b/neuralnetworks/1.1/vts/functional/ValidateRequest.cpp
@@ -16,16 +16,16 @@
#define LOG_TAG "neuralnetworks_hidl_hal_test"
-#include "VtsHalNeuralnetworks.h"
-
-#include "Callbacks.h"
-#include "TestHarness.h"
-#include "Utils.h"
-
#include <android-base/logging.h>
#include <android/hidl/memory/1.0/IMemory.h>
#include <hidlmemory/mapping.h>
+#include "1.0/Callbacks.h"
+#include "1.0/Utils.h"
+#include "MemoryUtils.h"
+#include "TestHarness.h"
+#include "VtsHalNeuralnetworks.h"
+
namespace android {
namespace hardware {
namespace neuralnetworks {
@@ -33,11 +33,15 @@
namespace vts {
namespace functional {
-using ::android::hardware::neuralnetworks::V1_2::implementation::ExecutionCallback;
+using ::android::hardware::neuralnetworks::V1_0::ErrorStatus;
+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_1::IPreparedModel;
using ::android::hidl::memory::V1_0::IMemory;
-using test_helper::for_all;
-using test_helper::MixedTyped;
-using test_helper::MixedTypedExample;
+using ::test_helper::for_all;
+using ::test_helper::MixedTyped;
+using ::test_helper::MixedTypedExample;
///////////////////////// UTILITY FUNCTIONS /////////////////////////
@@ -61,26 +65,6 @@
ASSERT_EQ(ErrorStatus::INVALID_ARGUMENT, executionReturnStatus);
}
-// Delete element from hidl_vec. hidl_vec doesn't support a "remove" operation,
-// so this is efficiently accomplished by moving the element to the end and
-// resizing the hidl_vec to one less.
-template <typename Type>
-static 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);
- }
-}
-
-template <typename Type>
-static uint32_t hidl_vec_push_back(hidl_vec<Type>* vec, const Type& value) {
- // assume vec is valid
- const uint32_t index = vec->size();
- vec->resize(index + 1);
- (*vec)[index] = value;
- return index;
-}
-
///////////////////////// REMOVE INPUT ////////////////////////////////////
static void removeInputTest(const sp<IPreparedModel>& preparedModel, const Request& request) {
@@ -121,11 +105,13 @@
for_all(inputs, [&inputs_info, &inputSize](int index, auto, auto s) {
if (inputs_info.size() <= static_cast<size_t>(index)) inputs_info.resize(index + 1);
RequestArgument arg = {
- .location = {.poolIndex = INPUT, .offset = 0, .length = static_cast<uint32_t>(s)},
- .dimensions = {},
+ .location = {.poolIndex = INPUT,
+ .offset = 0,
+ .length = static_cast<uint32_t>(s)},
+ .dimensions = {},
};
RequestArgument arg_empty = {
- .hasNoValue = true,
+ .hasNoValue = true,
};
inputs_info[index] = s ? arg : arg_empty;
inputSize += s;
@@ -143,8 +129,10 @@
for_all(outputs, [&outputs_info, &outputSize](int index, auto, auto s) {
if (outputs_info.size() <= static_cast<size_t>(index)) outputs_info.resize(index + 1);
RequestArgument arg = {
- .location = {.poolIndex = OUTPUT, .offset = 0, .length = static_cast<uint32_t>(s)},
- .dimensions = {},
+ .location = {.poolIndex = OUTPUT,
+ .offset = 0,
+ .length = static_cast<uint32_t>(s)},
+ .dimensions = {},
};
outputs_info[index] = arg;
outputSize += s;
diff --git a/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworks.cpp b/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworks.cpp
index 08069f2..12bdd3f 100644
--- a/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworks.cpp
+++ b/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworks.cpp
@@ -20,7 +20,7 @@
#include <android-base/logging.h>
-#include "Callbacks.h"
+#include "1.0/Callbacks.h"
namespace android {
namespace hardware {
@@ -29,7 +29,7 @@
namespace vts {
namespace functional {
-using ::android::hardware::neuralnetworks::V1_2::implementation::PreparedModelCallback;
+using ::android::hardware::neuralnetworks::V1_0::implementation::PreparedModelCallback;
static void createPreparedModel(const sp<IDevice>& device, const V1_1::Model& model,
sp<IPreparedModel>* preparedModel) {
diff --git a/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworks.h b/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworks.h
index f3f587b..3156784 100644
--- a/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworks.h
+++ b/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworks.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef VTS_HAL_NEURALNETWORKS_V1_1_H
-#define VTS_HAL_NEURALNETWORKS_V1_1_H
+#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.1/IDevice.h>
@@ -98,4 +98,4 @@
} // namespace android::hardware::neuralnetworks::V1_0
-#endif // VTS_HAL_NEURALNETWORKS_V1_1_H
+#endif // ANDROID_HARDWARE_NEURALNETWORKS_V1_1_VTS_HAL_NEURALNETWORKS_H
diff --git a/neuralnetworks/1.2/Android.bp b/neuralnetworks/1.2/Android.bp
index 085bda1..4aa90aa 100644
--- a/neuralnetworks/1.2/Android.bp
+++ b/neuralnetworks/1.2/Android.bp
@@ -23,4 +23,3 @@
],
gen_java: false,
}
-
diff --git a/neuralnetworks/1.2/IPreparedModel.hal b/neuralnetworks/1.2/IPreparedModel.hal
index 5d2d80f..ba16334 100644
--- a/neuralnetworks/1.2/IPreparedModel.hal
+++ b/neuralnetworks/1.2/IPreparedModel.hal
@@ -47,6 +47,13 @@
* execute_1_2 function. This callback must be provided with the ErrorStatus of
* the execution.
*
+ * If the launch is successful, the caller must not change the content of
+ * any data object referenced by 'request' (described by the
+ * {@link @1.0::DataLocation} of a {@link @1.0::RequestArgument}) until the
+ * asynchronous task has invoked the callback object. The asynchronous task
+ * 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
@@ -90,6 +97,12 @@
* perform the execution, and must not return until the execution is
* complete.
*
+ * The caller must not change the content of any data object referenced by
+ * 'request' (described by the {@link @1.0::DataLocation} of a
+ * {@link @1.0::RequestArgument}) until executeSynchronously
+ * returns. executeSynchronously 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 complete successfully
@@ -135,9 +148,15 @@
* @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. requestChannel must not be
- * used to pass a second Request object until a result
- * has been received from resultChannel.
+ * 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
diff --git a/neuralnetworks/1.2/vts/functional/Android.bp b/neuralnetworks/1.2/vts/functional/Android.bp
index 6c26820..31b8532 100644
--- a/neuralnetworks/1.2/vts/functional/Android.bp
+++ b/neuralnetworks/1.2/vts/functional/Android.bp
@@ -14,57 +14,81 @@
// limitations under the License.
//
+cc_defaults {
+ name: "VtsHalNeuralNetworksV1_2TargetTestDefaults",
+ defaults: ["VtsHalTargetTestDefaults"],
+ srcs: [
+ "ValidateModel.cpp",
+ "ValidateRequest.cpp",
+ "VtsHalNeuralnetworks.cpp",
+ "Callbacks.cpp",
+ "GeneratedTestHarness.cpp",
+ ],
+ local_include_dirs: ["include"],
+ shared_libs: [
+ "libfmq",
+ "libnativewindow",
+ ],
+ static_libs: [
+ "android.hardware.neuralnetworks@1.0",
+ "android.hardware.neuralnetworks@1.1",
+ "android.hardware.neuralnetworks@1.2",
+ "android.hidl.allocator@1.0",
+ "android.hidl.memory@1.0",
+ "libgmock",
+ "libhidlmemory",
+ "libneuralnetworks_utils",
+ "VtsHalNeuralNetworksV1_0_utils",
+ ],
+ header_libs: [
+ "libneuralnetworks_headers",
+ "libneuralnetworks_generated_test_harness_headers",
+ "libneuralnetworks_generated_tests",
+ ],
+ test_suites: ["general-tests"],
+}
+
// Tests for V1_0 models using the V1_2 HAL.
cc_test {
name: "VtsHalNeuralnetworksV1_2CompatV1_0TargetTest",
- defaults: ["VtsHalNeuralNetworksTargetTestDefaults"],
+ defaults: ["VtsHalNeuralNetworksV1_2TargetTestDefaults"],
srcs: [
"GeneratedTestsV1_0.cpp",
"ValidateBurst.cpp",
],
- cflags: [
- "-DNN_TEST_DYNAMIC_OUTPUT_SHAPE"
- ],
}
// Tests for V1_1 models using the V1_2 HAL.
cc_test {
name: "VtsHalNeuralnetworksV1_2CompatV1_1TargetTest",
- defaults: ["VtsHalNeuralNetworksTargetTestDefaults"],
+ defaults: ["VtsHalNeuralNetworksV1_2TargetTestDefaults"],
srcs: [
"GeneratedTestsV1_1.cpp",
"ValidateBurst.cpp",
],
- cflags: [
- "-DNN_TEST_DYNAMIC_OUTPUT_SHAPE"
- ],
}
// Tests for V1_2 models.
cc_test {
name: "VtsHalNeuralnetworksV1_2TargetTest",
- defaults: ["VtsHalNeuralNetworksTargetTestDefaults"],
+ defaults: ["VtsHalNeuralNetworksV1_2TargetTestDefaults"],
srcs: [
"BasicTests.cpp",
"CompilationCachingTests.cpp",
- "GeneratedTests.cpp",
+ "GeneratedTestsV1_2.cpp",
"ValidateBurst.cpp",
],
- cflags: [
- "-DNN_TEST_DYNAMIC_OUTPUT_SHAPE"
- ],
}
cc_test {
name: "PresubmitHalNeuralnetworksV1_2TargetTest",
- defaults: ["VtsHalNeuralNetworksTargetTestDefaults"],
+ defaults: ["VtsHalNeuralNetworksV1_2TargetTestDefaults"],
srcs: [
"BasicTests.cpp",
- "GeneratedTests.cpp",
+ "GeneratedTestsV1_2.cpp",
"ValidateBurst.cpp",
],
cflags: [
- "-DNN_TEST_DYNAMIC_OUTPUT_SHAPE",
"-DPRESUBMIT_NOT_VTS",
],
}
diff --git a/neuralnetworks/1.2/vts/functional/Callbacks.cpp b/neuralnetworks/1.2/vts/functional/Callbacks.cpp
new file mode 100644
index 0000000..a607a08
--- /dev/null
+++ b/neuralnetworks/1.2/vts/functional/Callbacks.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.
+ */
+
+#define LOG_TAG "Callbacks"
+
+#include "1.2/Callbacks.h"
+
+#include <android-base/logging.h>
+
+#include <limits>
+
+namespace android::hardware::neuralnetworks::V1_2::implementation {
+
+constexpr Timing kNoTiming = {.timeOnDevice = std::numeric_limits<uint64_t>::max(),
+ .timeInDriver = std::numeric_limits<uint64_t>::max()};
+
+// PreparedModelCallback methods begin here
+
+Return<void> PreparedModelCallback::notify(ErrorStatus errorStatus,
+ const sp<V1_0::IPreparedModel>& preparedModel) {
+ {
+ std::lock_guard<std::mutex> hold(mMutex);
+
+ // quick-return if object has already been notified
+ if (mNotified) {
+ return Void();
+ }
+
+ // store results and mark as notified
+ mErrorStatus = errorStatus;
+ mPreparedModel = preparedModel;
+ mNotified = true;
+ }
+
+ mCondition.notify_all();
+ return Void();
+}
+
+Return<void> PreparedModelCallback::notify_1_2(ErrorStatus errorStatus,
+ const sp<V1_2::IPreparedModel>& preparedModel) {
+ return notify(errorStatus, preparedModel);
+}
+
+void PreparedModelCallback::wait() const {
+ std::unique_lock<std::mutex> lock(mMutex);
+ mCondition.wait(lock, [this] { return mNotified; });
+}
+
+ErrorStatus PreparedModelCallback::getStatus() const {
+ wait();
+ return mErrorStatus;
+}
+
+sp<V1_0::IPreparedModel> PreparedModelCallback::getPreparedModel() const {
+ wait();
+ return mPreparedModel;
+}
+
+// ExecutionCallback methods begin here
+
+Return<void> ExecutionCallback::notify(ErrorStatus errorStatus) {
+ notifyInternal(errorStatus, {}, kNoTiming);
+ return Void();
+}
+
+Return<void> ExecutionCallback::notify_1_2(ErrorStatus errorStatus,
+ const hidl_vec<OutputShape>& outputShapes,
+ const Timing& timing) {
+ if (errorStatus == ErrorStatus::OUTPUT_INSUFFICIENT_SIZE) {
+ // outputShapes must not be empty if OUTPUT_INSUFFICIENT_SIZE.
+ if (outputShapes.size() == 0) {
+ LOG(ERROR) << "Notified with empty output shape vector when OUTPUT_INSUFFICIENT_SIZE";
+ notifyInternal(ErrorStatus::GENERAL_FAILURE, {}, kNoTiming);
+ return Void();
+ }
+ } else if (errorStatus != ErrorStatus::NONE) {
+ // outputShapes must be empty if errorStatus is neither NONE nor OUTPUT_INSUFFICIENT_SIZE.
+ if (outputShapes.size() != 0) {
+ LOG(ERROR) << "Notified with non-empty output shape vector when error status is "
+ "neither NONE nor OUTPUT_INSUFFICIENT_SIZE";
+ notifyInternal(ErrorStatus::GENERAL_FAILURE, {}, kNoTiming);
+ return Void();
+ }
+ }
+ notifyInternal(errorStatus, outputShapes, timing);
+ return Void();
+}
+
+void ExecutionCallback::wait() const {
+ std::unique_lock<std::mutex> lock(mMutex);
+ mCondition.wait(lock, [this] { return mNotified; });
+}
+
+ErrorStatus ExecutionCallback::getStatus() const {
+ wait();
+ return mErrorStatus;
+}
+
+const std::vector<OutputShape>& ExecutionCallback::getOutputShapes() const {
+ wait();
+ return mOutputShapes;
+}
+
+Timing ExecutionCallback::getTiming() const {
+ wait();
+ return mTiming;
+}
+
+void ExecutionCallback::notifyInternal(ErrorStatus errorStatus,
+ const hidl_vec<OutputShape>& outputShapes,
+ const Timing& timing) {
+ {
+ std::lock_guard<std::mutex> hold(mMutex);
+
+ // quick-return if object has already been notified
+ if (mNotified) {
+ return;
+ }
+
+ mErrorStatus = errorStatus;
+ mOutputShapes = outputShapes;
+ mTiming = timing;
+ mNotified = true;
+ }
+ mCondition.notify_all();
+}
+
+} // namespace android::hardware::neuralnetworks::V1_2::implementation
diff --git a/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp b/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp
index 4411b90..ac92a5b 100644
--- a/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp
+++ b/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp
@@ -26,9 +26,11 @@
#include <cstdio>
#include <cstdlib>
#include <random>
+#include <thread>
-#include "Callbacks.h"
+#include "1.2/Callbacks.h"
#include "GeneratedTestHarness.h"
+#include "MemoryUtils.h"
#include "TestHarness.h"
#include "Utils.h"
#include "VtsHalNeuralnetworks.h"
@@ -49,7 +51,7 @@
// In frameworks/ml/nn/runtime/test/generated/, creates a hidl model of float32 mobilenet.
#include "examples/mobilenet_224_gender_basic_fixed.example.cpp"
-#include "vts_models/mobilenet_224_gender_basic_fixed.model.cpp"
+#include "vts/V1_2/models/mobilenet_224_gender_basic_fixed.model.cpp"
// Prevent the compiler from complaining about an otherwise unused function.
[[maybe_unused]] auto dummy_createTestModel = createTestModel_dynamic_output_shape;
@@ -72,7 +74,7 @@
// In frameworks/ml/nn/runtime/test/generated/, creates a hidl model of quant8 mobilenet.
#include "examples/mobilenet_quantized.example.cpp"
-#include "vts_models/mobilenet_quantized.model.cpp"
+#include "vts/V1_2/models/mobilenet_quantized.model.cpp"
// Prevent the compiler from complaining about an otherwise unused function.
[[maybe_unused]] auto dummy_createTestModel = createTestModel_dynamic_output_shape;
diff --git a/neuralnetworks/1.2/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/1.2/vts/functional/GeneratedTestHarness.cpp
new file mode 100644
index 0000000..c3578cd
--- /dev/null
+++ b/neuralnetworks/1.2/vts/functional/GeneratedTestHarness.cpp
@@ -0,0 +1,452 @@
+/*
+ * 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 "GeneratedTestHarness.h"
+
+#include <android-base/logging.h>
+#include <android/hardware/neuralnetworks/1.0/IDevice.h>
+#include <android/hardware/neuralnetworks/1.0/IExecutionCallback.h>
+#include <android/hardware/neuralnetworks/1.0/IPreparedModel.h>
+#include <android/hardware/neuralnetworks/1.0/IPreparedModelCallback.h>
+#include <android/hardware/neuralnetworks/1.0/types.h>
+#include <android/hardware/neuralnetworks/1.1/IDevice.h>
+#include <android/hardware/neuralnetworks/1.2/IDevice.h>
+#include <android/hardware/neuralnetworks/1.2/IExecutionCallback.h>
+#include <android/hardware/neuralnetworks/1.2/IPreparedModel.h>
+#include <android/hardware/neuralnetworks/1.2/IPreparedModelCallback.h>
+#include <android/hidl/allocator/1.0/IAllocator.h>
+#include <android/hidl/memory/1.0/IMemory.h>
+#include <hidlmemory/mapping.h>
+
+#include <iostream>
+
+#include "1.0/Utils.h"
+#include "1.2/Callbacks.h"
+#include "ExecutionBurstController.h"
+#include "MemoryUtils.h"
+#include "TestHarness.h"
+#include "Utils.h"
+
+namespace android {
+namespace hardware {
+namespace neuralnetworks {
+namespace generated_tests {
+
+using ::android::hardware::neuralnetworks::V1_0::ErrorStatus;
+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::IDevice;
+using ::android::hardware::neuralnetworks::V1_2::IPreparedModel;
+using ::android::hardware::neuralnetworks::V1_2::Model;
+using ::android::hardware::neuralnetworks::V1_2::implementation::ExecutionCallback;
+using ::android::hardware::neuralnetworks::V1_2::implementation::PreparedModelCallback;
+using ::android::hidl::memory::V1_0::IMemory;
+using ::test_helper::compare;
+using ::test_helper::expectMultinomialDistributionWithinTolerance;
+using ::test_helper::filter;
+using ::test_helper::for_all;
+using ::test_helper::for_each;
+using ::test_helper::MixedTyped;
+using ::test_helper::MixedTypedExample;
+using ::test_helper::resize_accordingly;
+using HidlToken = hidl_array<uint8_t, static_cast<uint32_t>(Constant::BYTE_SIZE_OF_CACHE_TOKEN)>;
+
+static bool isZeroSized(const MixedTyped& example, uint32_t index) {
+ for (auto i : example.operandDimensions.at(index)) {
+ if (i == 0) return true;
+ }
+ return false;
+}
+
+static Return<ErrorStatus> ExecutePreparedModel(sp<IPreparedModel>& preparedModel,
+ const Request& request, MeasureTiming measure,
+ sp<ExecutionCallback>& callback) {
+ return preparedModel->execute_1_2(request, measure, callback);
+}
+static Return<ErrorStatus> ExecutePreparedModel(sp<IPreparedModel>& preparedModel,
+ const Request& request, MeasureTiming measure,
+ hidl_vec<OutputShape>* outputShapes,
+ Timing* timing) {
+ ErrorStatus result;
+ Return<void> ret = preparedModel->executeSynchronously(
+ request, measure,
+ [&result, outputShapes, timing](ErrorStatus error, const hidl_vec<OutputShape>& shapes,
+ const Timing& time) {
+ result = error;
+ *outputShapes = shapes;
+ *timing = time;
+ });
+ if (!ret.isOk()) {
+ return ErrorStatus::GENERAL_FAILURE;
+ }
+ return result;
+}
+static std::shared_ptr<::android::nn::ExecutionBurstController> CreateBurst(
+ const sp<IPreparedModel>& preparedModel) {
+ return ::android::nn::ExecutionBurstController::create(preparedModel, /*blocking=*/true);
+}
+enum class Executor { ASYNC, SYNC, BURST };
+enum class OutputType { FULLY_SPECIFIED, UNSPECIFIED, INSUFFICIENT };
+const float kDefaultAtol = 1e-5f;
+const float kDefaultRtol = 1e-5f;
+void EvaluatePreparedModel(sp<IPreparedModel>& preparedModel, std::function<bool(int)> is_ignored,
+ const std::vector<MixedTypedExample>& examples,
+ bool hasRelaxedFloat32Model, float fpAtol, float fpRtol,
+ Executor executor, MeasureTiming measure, OutputType outputType) {
+ const uint32_t INPUT = 0;
+ const uint32_t OUTPUT = 1;
+
+ int example_no = 1;
+ for (auto& example : examples) {
+ SCOPED_TRACE(example_no++);
+ const MixedTyped& inputs = example.operands.first;
+ const MixedTyped& golden = example.operands.second;
+
+ const bool hasFloat16Inputs = !inputs.float16Operands.empty();
+ if (hasRelaxedFloat32Model || hasFloat16Inputs) {
+ // TODO: Adjust the error limit based on testing.
+ // If in relaxed mode, set the absolute tolerance to be 5ULP of FP16.
+ fpAtol = 5.0f * 0.0009765625f;
+ // Set the relative tolerance to be 5ULP of the corresponding FP precision.
+ fpRtol = 5.0f * 0.0009765625f;
+ }
+
+ std::vector<RequestArgument> inputs_info, outputs_info;
+ uint32_t inputSize = 0, outputSize = 0;
+ // This function only partially specifies the metadata (vector of RequestArguments).
+ // The contents are copied over below.
+ for_all(inputs, [&inputs_info, &inputSize](int index, auto, auto s) {
+ if (inputs_info.size() <= static_cast<size_t>(index)) inputs_info.resize(index + 1);
+ RequestArgument arg = {
+ .location = {.poolIndex = INPUT,
+ .offset = 0,
+ .length = static_cast<uint32_t>(s)},
+ .dimensions = {},
+ };
+ RequestArgument arg_empty = {
+ .hasNoValue = true,
+ };
+ inputs_info[index] = s ? arg : arg_empty;
+ inputSize += s;
+ });
+ // Compute offset for inputs 1 and so on
+ {
+ size_t offset = 0;
+ for (auto& i : inputs_info) {
+ if (!i.hasNoValue) i.location.offset = offset;
+ offset += i.location.length;
+ }
+ }
+
+ MixedTyped test; // holding test results
+
+ // Go through all outputs, initialize RequestArgument descriptors
+ resize_accordingly(golden, test);
+ bool sizeLargerThanOne = true;
+ for_all(golden, [&golden, &outputs_info, &outputSize, &outputType, &sizeLargerThanOne](
+ int index, auto, auto s) {
+ if (outputs_info.size() <= static_cast<size_t>(index)) outputs_info.resize(index + 1);
+ if (index == 0) {
+ // On OutputType::INSUFFICIENT, set the output operand with index 0 with
+ // buffer size one byte less than needed.
+ if (outputType == OutputType::INSUFFICIENT) {
+ if (s > 1 && !isZeroSized(golden, index)) {
+ s -= 1;
+ } else {
+ sizeLargerThanOne = false;
+ }
+ }
+ }
+ RequestArgument arg = {
+ .location = {.poolIndex = OUTPUT,
+ .offset = 0,
+ .length = static_cast<uint32_t>(s)},
+ .dimensions = {},
+ };
+ outputs_info[index] = arg;
+ outputSize += s;
+ });
+ // If output0 does not have size larger than one byte,
+ // we can not provide an insufficient buffer
+ if (!sizeLargerThanOne && outputType == OutputType::INSUFFICIENT) return;
+ // Compute offset for outputs 1 and so on
+ {
+ size_t offset = 0;
+ for (auto& i : outputs_info) {
+ i.location.offset = offset;
+ offset += i.location.length;
+ }
+ }
+ std::vector<hidl_memory> pools = {nn::allocateSharedMemory(inputSize),
+ nn::allocateSharedMemory(outputSize)};
+ ASSERT_NE(0ull, pools[INPUT].size());
+ ASSERT_NE(0ull, pools[OUTPUT].size());
+
+ // load data
+ sp<IMemory> inputMemory = mapMemory(pools[INPUT]);
+ sp<IMemory> outputMemory = mapMemory(pools[OUTPUT]);
+ ASSERT_NE(nullptr, inputMemory.get());
+ ASSERT_NE(nullptr, outputMemory.get());
+ char* inputPtr = reinterpret_cast<char*>(static_cast<void*>(inputMemory->getPointer()));
+ char* outputPtr = reinterpret_cast<char*>(static_cast<void*>(outputMemory->getPointer()));
+ ASSERT_NE(nullptr, inputPtr);
+ ASSERT_NE(nullptr, outputPtr);
+ inputMemory->update();
+ outputMemory->update();
+
+ // Go through all inputs, copy the values
+ for_all(inputs, [&inputs_info, inputPtr](int index, auto p, auto s) {
+ char* begin = (char*)p;
+ char* end = begin + s;
+ // TODO: handle more than one input
+ std::copy(begin, end, inputPtr + inputs_info[index].location.offset);
+ });
+
+ inputMemory->commit();
+ outputMemory->commit();
+
+ const Request request = {.inputs = inputs_info, .outputs = outputs_info, .pools = pools};
+
+ ErrorStatus executionStatus;
+ hidl_vec<OutputShape> outputShapes;
+ Timing timing;
+ switch (executor) {
+ case Executor::ASYNC: {
+ SCOPED_TRACE("asynchronous");
+
+ // launch execution
+ sp<ExecutionCallback> executionCallback = new ExecutionCallback();
+ ASSERT_NE(nullptr, executionCallback.get());
+ Return<ErrorStatus> executionLaunchStatus =
+ ExecutePreparedModel(preparedModel, request, measure, executionCallback);
+ ASSERT_TRUE(executionLaunchStatus.isOk());
+ EXPECT_EQ(ErrorStatus::NONE, static_cast<ErrorStatus>(executionLaunchStatus));
+
+ // retrieve execution status
+ executionCallback->wait();
+ executionStatus = executionCallback->getStatus();
+ outputShapes = executionCallback->getOutputShapes();
+ timing = executionCallback->getTiming();
+
+ break;
+ }
+ case Executor::SYNC: {
+ SCOPED_TRACE("synchronous");
+
+ // execute
+ Return<ErrorStatus> executionReturnStatus = ExecutePreparedModel(
+ preparedModel, request, measure, &outputShapes, &timing);
+ ASSERT_TRUE(executionReturnStatus.isOk());
+ executionStatus = static_cast<ErrorStatus>(executionReturnStatus);
+
+ break;
+ }
+ case Executor::BURST: {
+ SCOPED_TRACE("burst");
+
+ // create burst
+ const std::shared_ptr<::android::nn::ExecutionBurstController> controller =
+ CreateBurst(preparedModel);
+ ASSERT_NE(nullptr, controller.get());
+
+ // create memory keys
+ std::vector<intptr_t> keys(request.pools.size());
+ for (size_t i = 0; i < keys.size(); ++i) {
+ keys[i] = reinterpret_cast<intptr_t>(&request.pools[i]);
+ }
+
+ // execute burst
+ std::tie(executionStatus, outputShapes, timing) =
+ controller->compute(request, measure, keys);
+
+ break;
+ }
+ }
+
+ if (outputType != OutputType::FULLY_SPECIFIED &&
+ executionStatus == ErrorStatus::GENERAL_FAILURE) {
+ LOG(INFO) << "NN VTS: Early termination of test because vendor service cannot "
+ "execute model that it does not support.";
+ std::cout << "[ ] Early termination of test because vendor service cannot "
+ "execute model that it does not support."
+ << std::endl;
+ GTEST_SKIP();
+ }
+ if (measure == MeasureTiming::NO) {
+ EXPECT_EQ(UINT64_MAX, timing.timeOnDevice);
+ EXPECT_EQ(UINT64_MAX, timing.timeInDriver);
+ } else {
+ if (timing.timeOnDevice != UINT64_MAX && timing.timeInDriver != UINT64_MAX) {
+ EXPECT_LE(timing.timeOnDevice, timing.timeInDriver);
+ }
+ }
+
+ switch (outputType) {
+ case OutputType::FULLY_SPECIFIED:
+ // If the model output operands are fully specified, outputShapes must be either
+ // either empty, or have the same number of elements as the number of outputs.
+ ASSERT_EQ(ErrorStatus::NONE, executionStatus);
+ ASSERT_TRUE(outputShapes.size() == 0 ||
+ outputShapes.size() == test.operandDimensions.size());
+ break;
+ case OutputType::UNSPECIFIED:
+ // If the model output operands are not fully specified, outputShapes must have
+ // the same number of elements as the number of outputs.
+ ASSERT_EQ(ErrorStatus::NONE, executionStatus);
+ ASSERT_EQ(outputShapes.size(), test.operandDimensions.size());
+ break;
+ case OutputType::INSUFFICIENT:
+ ASSERT_EQ(ErrorStatus::OUTPUT_INSUFFICIENT_SIZE, executionStatus);
+ ASSERT_EQ(outputShapes.size(), test.operandDimensions.size());
+ ASSERT_FALSE(outputShapes[0].isSufficient);
+ return;
+ }
+ // Go through all outputs, overwrite output dimensions with returned output shapes
+ if (outputShapes.size() > 0) {
+ for_each<uint32_t>(test.operandDimensions,
+ [&outputShapes](int idx, std::vector<uint32_t>& dim) {
+ dim = outputShapes[idx].dimensions;
+ });
+ }
+
+ // validate results
+ outputMemory->read();
+ copy_back(&test, outputs_info, outputPtr);
+ outputMemory->commit();
+ // Filter out don't cares
+ MixedTyped filtered_golden = filter(golden, is_ignored);
+ MixedTyped filtered_test = filter(test, is_ignored);
+
+ // We want "close-enough" results for float
+ compare(filtered_golden, filtered_test, fpAtol, fpRtol);
+
+ if (example.expectedMultinomialDistributionTolerance > 0) {
+ expectMultinomialDistributionWithinTolerance(test, example);
+ }
+ }
+}
+void EvaluatePreparedModel(sp<IPreparedModel>& preparedModel, std::function<bool(int)> is_ignored,
+ const std::vector<MixedTypedExample>& examples,
+ bool hasRelaxedFloat32Model, Executor executor, MeasureTiming measure,
+ OutputType outputType) {
+ EvaluatePreparedModel(preparedModel, is_ignored, examples, hasRelaxedFloat32Model, kDefaultAtol,
+ kDefaultRtol, executor, measure, outputType);
+}
+
+void EvaluatePreparedModel(sp<IPreparedModel>& preparedModel, std::function<bool(int)> is_ignored,
+ const std::vector<MixedTypedExample>& examples,
+ bool hasRelaxedFloat32Model, bool testDynamicOutputShape) {
+ if (testDynamicOutputShape) {
+ EvaluatePreparedModel(preparedModel, is_ignored, examples, hasRelaxedFloat32Model,
+ Executor::ASYNC, MeasureTiming::NO, OutputType::UNSPECIFIED);
+ EvaluatePreparedModel(preparedModel, is_ignored, examples, hasRelaxedFloat32Model,
+ Executor::SYNC, MeasureTiming::NO, OutputType::UNSPECIFIED);
+ EvaluatePreparedModel(preparedModel, is_ignored, examples, hasRelaxedFloat32Model,
+ Executor::BURST, MeasureTiming::NO, OutputType::UNSPECIFIED);
+ EvaluatePreparedModel(preparedModel, is_ignored, examples, hasRelaxedFloat32Model,
+ Executor::ASYNC, MeasureTiming::YES, OutputType::UNSPECIFIED);
+ EvaluatePreparedModel(preparedModel, is_ignored, examples, hasRelaxedFloat32Model,
+ Executor::SYNC, MeasureTiming::YES, OutputType::UNSPECIFIED);
+ EvaluatePreparedModel(preparedModel, is_ignored, examples, hasRelaxedFloat32Model,
+ Executor::BURST, MeasureTiming::YES, OutputType::UNSPECIFIED);
+ EvaluatePreparedModel(preparedModel, is_ignored, examples, hasRelaxedFloat32Model,
+ Executor::ASYNC, MeasureTiming::NO, OutputType::INSUFFICIENT);
+ EvaluatePreparedModel(preparedModel, is_ignored, examples, hasRelaxedFloat32Model,
+ Executor::SYNC, MeasureTiming::NO, OutputType::INSUFFICIENT);
+ EvaluatePreparedModel(preparedModel, is_ignored, examples, hasRelaxedFloat32Model,
+ Executor::BURST, MeasureTiming::NO, OutputType::INSUFFICIENT);
+ EvaluatePreparedModel(preparedModel, is_ignored, examples, hasRelaxedFloat32Model,
+ Executor::ASYNC, MeasureTiming::YES, OutputType::INSUFFICIENT);
+ EvaluatePreparedModel(preparedModel, is_ignored, examples, hasRelaxedFloat32Model,
+ Executor::SYNC, MeasureTiming::YES, OutputType::INSUFFICIENT);
+ EvaluatePreparedModel(preparedModel, is_ignored, examples, hasRelaxedFloat32Model,
+ Executor::BURST, MeasureTiming::YES, OutputType::INSUFFICIENT);
+ } else {
+ EvaluatePreparedModel(preparedModel, is_ignored, examples, hasRelaxedFloat32Model,
+ Executor::ASYNC, MeasureTiming::NO, OutputType::FULLY_SPECIFIED);
+ EvaluatePreparedModel(preparedModel, is_ignored, examples, hasRelaxedFloat32Model,
+ Executor::SYNC, MeasureTiming::NO, OutputType::FULLY_SPECIFIED);
+ EvaluatePreparedModel(preparedModel, is_ignored, examples, hasRelaxedFloat32Model,
+ Executor::BURST, MeasureTiming::NO, OutputType::FULLY_SPECIFIED);
+ EvaluatePreparedModel(preparedModel, is_ignored, examples, hasRelaxedFloat32Model,
+ Executor::ASYNC, MeasureTiming::YES, OutputType::FULLY_SPECIFIED);
+ EvaluatePreparedModel(preparedModel, is_ignored, examples, hasRelaxedFloat32Model,
+ Executor::SYNC, MeasureTiming::YES, OutputType::FULLY_SPECIFIED);
+ EvaluatePreparedModel(preparedModel, is_ignored, examples, hasRelaxedFloat32Model,
+ Executor::BURST, MeasureTiming::YES, OutputType::FULLY_SPECIFIED);
+ }
+}
+
+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();
+ ASSERT_NE(nullptr, preparedModelCallback.get());
+ 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, std::function<Model(void)> create_model,
+ std::function<bool(int)> is_ignored, const std::vector<MixedTypedExample>& examples,
+ bool testDynamicOutputShape) {
+ Model model = create_model();
+ sp<IPreparedModel> preparedModel = nullptr;
+ PrepareModel(device, model, &preparedModel);
+ if (preparedModel == nullptr) {
+ GTEST_SKIP();
+ }
+ EvaluatePreparedModel(preparedModel, is_ignored, examples,
+ model.relaxComputationFloat32toFloat16, testDynamicOutputShape);
+}
+
+} // namespace generated_tests
+} // namespace neuralnetworks
+} // namespace hardware
+} // namespace android
diff --git a/neuralnetworks/1.2/vts/functional/GeneratedTestHarness.h b/neuralnetworks/1.2/vts/functional/GeneratedTestHarness.h
new file mode 100644
index 0000000..30e5578
--- /dev/null
+++ b/neuralnetworks/1.2/vts/functional/GeneratedTestHarness.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_NEURALNETWORKS_V1_2_GENERATED_TEST_HARNESS_H
+#define ANDROID_HARDWARE_NEURALNETWORKS_V1_2_GENERATED_TEST_HARNESS_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 <functional>
+#include <vector>
+#include "TestHarness.h"
+
+namespace android {
+namespace hardware {
+namespace neuralnetworks {
+namespace generated_tests {
+
+using ::test_helper::MixedTypedExample;
+
+void PrepareModel(const sp<V1_2::IDevice>& device, const V1_2::Model& model,
+ sp<V1_2::IPreparedModel>* preparedModel);
+
+void EvaluatePreparedModel(sp<V1_2::IPreparedModel>& preparedModel,
+ std::function<bool(int)> is_ignored,
+ const std::vector<MixedTypedExample>& examples,
+ bool hasRelaxedFloat32Model, bool testDynamicOutputShape);
+
+void Execute(const sp<V1_2::IDevice>& device, std::function<V1_2::Model(void)> create_model,
+ std::function<bool(int)> is_ignored, const std::vector<MixedTypedExample>& examples,
+ bool testDynamicOutputShape = false);
+
+} // namespace generated_tests
+} // namespace neuralnetworks
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_NEURALNETWORKS_V1_2_GENERATED_TEST_HARNESS_H
diff --git a/neuralnetworks/1.2/vts/functional/GeneratedTestsV1_0.cpp b/neuralnetworks/1.2/vts/functional/GeneratedTestsV1_0.cpp
index 990cab9..b4e6696 100644
--- a/neuralnetworks/1.2/vts/functional/GeneratedTestsV1_0.cpp
+++ b/neuralnetworks/1.2/vts/functional/GeneratedTestsV1_0.cpp
@@ -16,17 +16,17 @@
#define LOG_TAG "neuralnetworks_hidl_hal_test"
-#include "VtsHalNeuralnetworks.h"
-
-#include "Callbacks.h"
-#include "GeneratedTestHarness.h"
-#include "TestHarness.h"
-#include "Utils.h"
-
#include <android-base/logging.h>
#include <android/hidl/memory/1.0/IMemory.h>
#include <hidlmemory/mapping.h>
+#include "1.2/Callbacks.h"
+#include "GeneratedTestHarness.h"
+#include "MemoryUtils.h"
+#include "TestHarness.h"
+#include "Utils.h"
+#include "VtsHalNeuralnetworks.h"
+
namespace android {
namespace hardware {
namespace neuralnetworks {
@@ -42,7 +42,7 @@
std::vector<Request> createRequests(const std::vector<MixedTypedExample>& examples);
// in frameworks/ml/nn/runtime/tests/generated/
-#include "all_generated_V1_0_vts_tests.cpp"
+#include "vts/V1_2/all_generated_V1_0_vts_tests.cpp"
} // namespace functional
} // namespace vts
diff --git a/neuralnetworks/1.2/vts/functional/GeneratedTestsV1_1.cpp b/neuralnetworks/1.2/vts/functional/GeneratedTestsV1_1.cpp
index fa6d54d..33212fb 100644
--- a/neuralnetworks/1.2/vts/functional/GeneratedTestsV1_1.cpp
+++ b/neuralnetworks/1.2/vts/functional/GeneratedTestsV1_1.cpp
@@ -16,17 +16,17 @@
#define LOG_TAG "neuralnetworks_hidl_hal_test"
-#include "VtsHalNeuralnetworks.h"
-
-#include "Callbacks.h"
-#include "GeneratedTestHarness.h"
-#include "TestHarness.h"
-#include "Utils.h"
-
#include <android-base/logging.h>
#include <android/hidl/memory/1.0/IMemory.h>
#include <hidlmemory/mapping.h>
+#include "1.2/Callbacks.h"
+#include "GeneratedTestHarness.h"
+#include "MemoryUtils.h"
+#include "TestHarness.h"
+#include "Utils.h"
+#include "VtsHalNeuralnetworks.h"
+
namespace android {
namespace hardware {
namespace neuralnetworks {
@@ -42,7 +42,7 @@
std::vector<Request> createRequests(const std::vector<MixedTypedExample>& examples);
// in frameworks/ml/nn/runtime/tests/generated/
-#include "all_generated_V1_1_vts_tests.cpp"
+#include "vts/V1_2/all_generated_V1_1_vts_tests.cpp"
} // namespace functional
} // namespace vts
diff --git a/neuralnetworks/1.2/vts/functional/GeneratedTests.cpp b/neuralnetworks/1.2/vts/functional/GeneratedTestsV1_2.cpp
similarity index 64%
rename from neuralnetworks/1.2/vts/functional/GeneratedTests.cpp
rename to neuralnetworks/1.2/vts/functional/GeneratedTestsV1_2.cpp
index 2c3287a..8481b4d 100644
--- a/neuralnetworks/1.2/vts/functional/GeneratedTests.cpp
+++ b/neuralnetworks/1.2/vts/functional/GeneratedTestsV1_2.cpp
@@ -16,17 +16,17 @@
#define LOG_TAG "neuralnetworks_hidl_hal_test"
-#include "VtsHalNeuralnetworks.h"
-
-#include "Callbacks.h"
-#include "GeneratedTestHarness.h"
-#include "TestHarness.h"
-#include "Utils.h"
-
#include <android-base/logging.h>
#include <android/hidl/memory/1.0/IMemory.h>
#include <hidlmemory/mapping.h>
+#include "1.2/Callbacks.h"
+#include "GeneratedTestHarness.h"
+#include "MemoryUtils.h"
+#include "TestHarness.h"
+#include "Utils.h"
+#include "VtsHalNeuralnetworks.h"
+
namespace android {
namespace hardware {
namespace neuralnetworks {
@@ -42,7 +42,22 @@
std::vector<Request> createRequests(const std::vector<MixedTypedExample>& examples);
// in frameworks/ml/nn/runtime/tests/generated/
-#include "all_generated_V1_2_vts_tests.cpp"
+#include "vts/V1_2/all_generated_V1_2_vts_tests.cpp"
+
+// Generated from spec/strided_slice_invalid_output_dims.mod.py.
+// TODO(b/132155416): Make this part of all_generated_V1_2_vts_tests.cpp.
+namespace strided_slice_invalid_output_dims {
+#include "generated/strided_slice_invalid_output_dims.example.cpp"
+#include "generated/strided_slice_invalid_output_dims.model.cpp"
+} // namespace strided_slice_invalid_output_dims
+
+// TODO(b/132155416): Make this part of all_generated_V1_2_vts_tests.cpp.
+TEST_F(ValidationTest, strided_slice_invalid_output_dims) {
+ const Model model = strided_slice_invalid_output_dims::createTestModel();
+ const std::vector<Request> requests =
+ createRequests(strided_slice_invalid_output_dims::get_examples());
+ validateFailure(model, requests);
+}
} // namespace functional
} // namespace vts
diff --git a/neuralnetworks/1.2/vts/functional/ValidateBurst.cpp b/neuralnetworks/1.2/vts/functional/ValidateBurst.cpp
index 8c6391e..4d6bdbb 100644
--- a/neuralnetworks/1.2/vts/functional/ValidateBurst.cpp
+++ b/neuralnetworks/1.2/vts/functional/ValidateBurst.cpp
@@ -18,7 +18,7 @@
#include "VtsHalNeuralnetworks.h"
-#include "Callbacks.h"
+#include "1.2/Callbacks.h"
#include "ExecutionBurstController.h"
#include "ExecutionBurstServer.h"
#include "TestHarness.h"
diff --git a/neuralnetworks/1.2/vts/functional/ValidateModel.cpp b/neuralnetworks/1.2/vts/functional/ValidateModel.cpp
index a0b6d9a..9e52c44 100644
--- a/neuralnetworks/1.2/vts/functional/ValidateModel.cpp
+++ b/neuralnetworks/1.2/vts/functional/ValidateModel.cpp
@@ -16,10 +16,10 @@
#define LOG_TAG "neuralnetworks_hidl_hal_test"
+#include "1.0/Utils.h"
+#include "1.2/Callbacks.h"
#include "VtsHalNeuralnetworks.h"
-#include "Callbacks.h"
-
namespace android {
namespace hardware {
namespace neuralnetworks {
@@ -41,10 +41,10 @@
const Model& model) {
SCOPED_TRACE(message + " [getSupportedOperations_1_2]");
- Return<void> ret =
- device->getSupportedOperations_1_2(model, [&](ErrorStatus status, const hidl_vec<bool>&) {
- EXPECT_EQ(ErrorStatus::INVALID_ARGUMENT, status);
- });
+ Return<void> ret = device->getSupportedOperations_1_2(
+ model, [&](ErrorStatus status, const hidl_vec<bool>&) {
+ EXPECT_EQ(ErrorStatus::INVALID_ARGUMENT, status);
+ });
EXPECT_TRUE(ret.isOk());
}
@@ -87,36 +87,16 @@
validatePrepareModel(device, message, model, preference);
}
-// Delete element from hidl_vec. hidl_vec doesn't support a "remove" operation,
-// so this is efficiently accomplished by moving the element to the end and
-// resizing the hidl_vec to one less.
-template <typename Type>
-static 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);
- }
-}
-
-template <typename Type>
-static uint32_t hidl_vec_push_back(hidl_vec<Type>* vec, const Type& value) {
- // assume vec is valid
- const uint32_t index = vec->size();
- vec->resize(index + 1);
- (*vec)[index] = value;
- return index;
-}
-
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},
});
}
@@ -256,7 +236,7 @@
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 " +
@@ -292,13 +272,13 @@
case OperandType::TENSOR_FLOAT16:
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:
@@ -306,19 +286,20 @@
case OperandType::TENSOR_QUANT16_ASYMM:
case OperandType::TENSOR_QUANT16_SYMM:
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::TENSOR_QUANT8_SYMM_PER_CHANNEL: {
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;
SymmPerChannelQuantParams channelQuant;
channelQuant.channelDim = 0;
channelQuant.scales = hidl_vec<float>(
- operand->dimensions.size() > 0 ? static_cast<size_t>(operand->dimensions[0]) : 0);
+ operand->dimensions.size() > 0 ? static_cast<size_t>(operand->dimensions[0])
+ : 0);
for (size_t i = 0; i < channelQuant.scales.size(); ++i) {
channelQuant.scales[i] = 1.0f;
}
@@ -435,7 +416,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);
});
}
}
@@ -508,15 +489,15 @@
}
}
}
- // BIDIRECTIONAL_SEQUENCE_LSTM and BIDIRECTIONAL_SEQUENCE_RNN can have either one or two
- // outputs depending on their mergeOutputs parameter.
+ // BIDIRECTIONAL_SEQUENCE_LSTM and BIDIRECTIONAL_SEQUENCE_RNN can have
+ // either one or two outputs depending on their mergeOutputs parameter.
if (operation.type == OperationType::BIDIRECTIONAL_SEQUENCE_LSTM ||
operation.type == OperationType::BIDIRECTIONAL_SEQUENCE_RNN) {
- for (const size_t outOprand : operation.outputs) {
- if (operand == outOprand) {
- return true;
- }
+ for (const size_t outOprand : operation.outputs) {
+ if (operand == outOprand) {
+ return true;
}
+ }
}
}
return false;
@@ -690,7 +671,7 @@
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);
@@ -702,14 +683,14 @@
///////////////////////// VALIDATE EXECUTION PREFERENCE /////////////////////////
static const int32_t invalidExecutionPreferences[] = {
- static_cast<int32_t>(ExecutionPreference::LOW_POWER) - 1, // lower bound
- static_cast<int32_t>(ExecutionPreference::SUSTAINED_SPEED) + 1, // upper bound
+ static_cast<int32_t>(ExecutionPreference::LOW_POWER) - 1, // lower bound
+ static_cast<int32_t>(ExecutionPreference::SUSTAINED_SPEED) + 1, // upper bound
};
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);
+ "mutateExecutionPreferenceTest: preference " + std::to_string(preference);
validate(device, message, model, [](Model*) {},
static_cast<ExecutionPreference>(preference));
}
diff --git a/neuralnetworks/1.2/vts/functional/ValidateRequest.cpp b/neuralnetworks/1.2/vts/functional/ValidateRequest.cpp
index 9703c2d..a7e8328 100644
--- a/neuralnetworks/1.2/vts/functional/ValidateRequest.cpp
+++ b/neuralnetworks/1.2/vts/functional/ValidateRequest.cpp
@@ -16,17 +16,18 @@
#define LOG_TAG "neuralnetworks_hidl_hal_test"
-#include "VtsHalNeuralnetworks.h"
-
-#include "Callbacks.h"
-#include "ExecutionBurstController.h"
-#include "TestHarness.h"
-#include "Utils.h"
-
#include <android-base/logging.h>
#include <android/hidl/memory/1.0/IMemory.h>
#include <hidlmemory/mapping.h>
+#include "1.0/Utils.h"
+#include "1.2/Callbacks.h"
+#include "ExecutionBurstController.h"
+#include "MemoryUtils.h"
+#include "TestHarness.h"
+#include "Utils.h"
+#include "VtsHalNeuralnetworks.h"
+
namespace android {
namespace hardware {
namespace neuralnetworks {
@@ -137,26 +138,6 @@
}
}
-// Delete element from hidl_vec. hidl_vec doesn't support a "remove" operation,
-// so this is efficiently accomplished by moving the element to the end and
-// resizing the hidl_vec to one less.
-template <typename Type>
-static 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);
- }
-}
-
-template <typename Type>
-static uint32_t hidl_vec_push_back(hidl_vec<Type>* vec, const Type& value) {
- // assume vec is valid
- const uint32_t index = vec->size();
- vec->resize(index + 1);
- (*vec)[index] = value;
- return index;
-}
-
///////////////////////// REMOVE INPUT ////////////////////////////////////
static void removeInputTest(const sp<IPreparedModel>& preparedModel, const Request& request) {
@@ -197,11 +178,13 @@
for_all(inputs, [&inputs_info, &inputSize](int index, auto, auto s) {
if (inputs_info.size() <= static_cast<size_t>(index)) inputs_info.resize(index + 1);
RequestArgument arg = {
- .location = {.poolIndex = INPUT, .offset = 0, .length = static_cast<uint32_t>(s)},
- .dimensions = {},
+ .location = {.poolIndex = INPUT,
+ .offset = 0,
+ .length = static_cast<uint32_t>(s)},
+ .dimensions = {},
};
RequestArgument arg_empty = {
- .hasNoValue = true,
+ .hasNoValue = true,
};
inputs_info[index] = s ? arg : arg_empty;
inputSize += s;
@@ -219,8 +202,10 @@
for_all(outputs, [&outputs_info, &outputSize](int index, auto, auto s) {
if (outputs_info.size() <= static_cast<size_t>(index)) outputs_info.resize(index + 1);
RequestArgument arg = {
- .location = {.poolIndex = OUTPUT, .offset = 0, .length = static_cast<uint32_t>(s)},
- .dimensions = {},
+ .location = {.poolIndex = OUTPUT,
+ .offset = 0,
+ .length = static_cast<uint32_t>(s)},
+ .dimensions = {},
};
outputs_info[index] = arg;
outputSize += s;
@@ -274,6 +259,22 @@
}
}
+void ValidationTest::validateRequestFailure(const sp<IPreparedModel>& preparedModel,
+ const std::vector<Request>& requests) {
+ for (const Request& request : requests) {
+ SCOPED_TRACE("Expecting request to fail [executeSynchronously]");
+ Return<void> executeStatus = preparedModel->executeSynchronously(
+ request, MeasureTiming::NO,
+ [](ErrorStatus error, const hidl_vec<OutputShape>& outputShapes,
+ const Timing& timing) {
+ ASSERT_NE(ErrorStatus::NONE, error);
+ EXPECT_EQ(outputShapes.size(), 0);
+ EXPECT_TRUE(badTiming(timing));
+ });
+ ASSERT_TRUE(executeStatus.isOk());
+ }
+}
+
} // namespace functional
} // namespace vts
} // namespace V1_2
diff --git a/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.cpp b/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.cpp
index 4ddefe8..bd24edc 100644
--- a/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.cpp
+++ b/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.cpp
@@ -20,7 +20,7 @@
#include <android-base/logging.h>
-#include "Callbacks.h"
+#include "1.2/Callbacks.h"
namespace android {
namespace hardware {
@@ -140,6 +140,20 @@
validateBurst(preparedModel, requests);
}
+void ValidationTest::validateFailure(const Model& model, const std::vector<Request>& requests) {
+ // TODO: Should this always succeed?
+ // What if the invalid input is part of the model (i.e., a parameter).
+ validateModel(model);
+
+ sp<IPreparedModel> preparedModel;
+ ASSERT_NO_FATAL_FAILURE(createPreparedModel(device, model, &preparedModel));
+ if (preparedModel == nullptr) {
+ return;
+ }
+
+ validateRequestFailure(preparedModel, requests);
+}
+
sp<IPreparedModel> getPreparedModel_1_2(
const sp<V1_2::implementation::PreparedModelCallback>& callback) {
sp<V1_0::IPreparedModel> preparedModelV1_0 = callback->getPreparedModel();
diff --git a/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.h b/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.h
index 8d1acbe..90dfe25 100644
--- a/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.h
+++ b/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.h
@@ -14,24 +14,23 @@
* limitations under the License.
*/
-#ifndef VTS_HAL_NEURALNETWORKS_V1_2_H
-#define VTS_HAL_NEURALNETWORKS_V1_2_H
+#ifndef ANDROID_HARDWARE_NEURALNETWORKS_V1_2_VTS_HAL_NEURALNETWORKS_H
+#define ANDROID_HARDWARE_NEURALNETWORKS_V1_2_VTS_HAL_NEURALNETWORKS_H
-#include "Callbacks.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/types.h>
-
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
-
-#include <android-base/macros.h>
#include <gtest/gtest.h>
+
#include <iostream>
#include <vector>
+#include "1.2/Callbacks.h"
+
namespace android {
namespace hardware {
namespace neuralnetworks {
@@ -50,7 +49,7 @@
NeuralnetworksHidlEnvironment();
~NeuralnetworksHidlEnvironment() override;
- public:
+ public:
static NeuralnetworksHidlEnvironment* getInstance();
void registerTestServices() override;
};
@@ -59,27 +58,30 @@
class NeuralnetworksHidlTest : public ::testing::VtsHalHidlTargetTestBase {
DISALLOW_COPY_AND_ASSIGN(NeuralnetworksHidlTest);
- public:
+ public:
NeuralnetworksHidlTest();
~NeuralnetworksHidlTest() override;
void SetUp() override;
void TearDown() override;
- protected:
+ protected:
sp<IDevice> device;
};
// Tag for the validation tests
class ValidationTest : public NeuralnetworksHidlTest {
- protected:
- void validateEverything(const Model& model, const std::vector<Request>& requests);
+ protected:
+ void validateEverything(const Model& model, const std::vector<Request>& requests);
+ void validateFailure(const Model& model, const std::vector<Request>& requests);
- private:
- void validateModel(const Model& model);
- void validateRequests(const sp<IPreparedModel>& preparedModel,
- const std::vector<Request>& requests);
- void validateBurst(const sp<IPreparedModel>& preparedModel,
- const std::vector<Request>& requests);
+ private:
+ void validateModel(const Model& model);
+ void validateRequests(const sp<IPreparedModel>& preparedModel,
+ const std::vector<Request>& requests);
+ void validateRequestFailure(const sp<IPreparedModel>& preparedModel,
+ const std::vector<Request>& requests);
+ void validateBurst(const sp<IPreparedModel>& preparedModel,
+ const std::vector<Request>& requests);
};
// Tag for the generated tests
@@ -90,7 +92,7 @@
// Utility function to get PreparedModel from callback and downcast to V1_2.
sp<IPreparedModel> getPreparedModel_1_2(
- const sp<V1_2::implementation::PreparedModelCallback>& callback);
+ const sp<V1_2::implementation::PreparedModelCallback>& callback);
} // namespace functional
} // namespace vts
@@ -107,4 +109,4 @@
} // namespace android::hardware::neuralnetworks::V1_0
-#endif // VTS_HAL_NEURALNETWORKS_V1_2_H
+#endif // ANDROID_HARDWARE_NEURALNETWORKS_V1_2_VTS_HAL_NEURALNETWORKS_H
diff --git a/neuralnetworks/1.2/vts/functional/generated/strided_slice_invalid_output_dims.example.cpp b/neuralnetworks/1.2/vts/functional/generated/strided_slice_invalid_output_dims.example.cpp
new file mode 100644
index 0000000..0640833
--- /dev/null
+++ b/neuralnetworks/1.2/vts/functional/generated/strided_slice_invalid_output_dims.example.cpp
@@ -0,0 +1,116 @@
+// clang-format off
+// Generated file (from: strided_slice_invalid_output_dims.mod.py). Do not edit
+std::vector<MixedTypedExample>& get_examples() {
+static std::vector<MixedTypedExample> examples = {
+// Begin of an example
+{
+.operands = {
+//Input(s)
+{ // See tools/test_generator/include/TestHarness.h:MixedTyped
+ // int -> Dimensions map
+ .operandDimensions = {{0, {2, 3}}},
+ // int -> FLOAT32 map
+ .float32Operands = {{0, {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f}}},
+ // int -> INT32 map
+ .int32Operands = {},
+ // int -> QUANT8_ASYMM map
+ .quant8AsymmOperands = {},
+ // int -> QUANT16_SYMM map
+ .quant16SymmOperands = {},
+ // int -> FLOAT16 map
+ .float16Operands = {},
+ // int -> BOOL8 map
+ .bool8Operands = {},
+ // int -> QUANT8_SYMM_PER_CHANNEL map
+ .quant8ChannelOperands = {},
+ // int -> QUANT16_ASYMM map
+ .quant16AsymmOperands = {},
+ // int -> QUANT8_SYMM map
+ .quant8SymmOperands = {},
+},
+//Output(s)
+{ // See tools/test_generator/include/TestHarness.h:MixedTyped
+ // int -> Dimensions map
+ .operandDimensions = {{0, {3}}},
+ // int -> FLOAT32 map
+ .float32Operands = {{0, {1.0f, 2.0f, 3.0f}}},
+ // int -> INT32 map
+ .int32Operands = {},
+ // int -> QUANT8_ASYMM map
+ .quant8AsymmOperands = {},
+ // int -> QUANT16_SYMM map
+ .quant16SymmOperands = {},
+ // int -> FLOAT16 map
+ .float16Operands = {},
+ // int -> BOOL8 map
+ .bool8Operands = {},
+ // int -> QUANT8_SYMM_PER_CHANNEL map
+ .quant8ChannelOperands = {},
+ // int -> QUANT16_ASYMM map
+ .quant16AsymmOperands = {},
+ // int -> QUANT8_SYMM map
+ .quant8SymmOperands = {},
+}
+},
+}, // End of an example
+};
+return examples;
+};
+
+std::vector<MixedTypedExample>& get_examples_dynamic_output_shape() {
+static std::vector<MixedTypedExample> examples_dynamic_output_shape = {
+// Begin of an example
+{
+.operands = {
+//Input(s)
+{ // See tools/test_generator/include/TestHarness.h:MixedTyped
+ // int -> Dimensions map
+ .operandDimensions = {{0, {2, 3}}},
+ // int -> FLOAT32 map
+ .float32Operands = {{0, {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f}}},
+ // int -> INT32 map
+ .int32Operands = {},
+ // int -> QUANT8_ASYMM map
+ .quant8AsymmOperands = {},
+ // int -> QUANT16_SYMM map
+ .quant16SymmOperands = {},
+ // int -> FLOAT16 map
+ .float16Operands = {},
+ // int -> BOOL8 map
+ .bool8Operands = {},
+ // int -> QUANT8_SYMM_PER_CHANNEL map
+ .quant8ChannelOperands = {},
+ // int -> QUANT16_ASYMM map
+ .quant16AsymmOperands = {},
+ // int -> QUANT8_SYMM map
+ .quant8SymmOperands = {},
+},
+//Output(s)
+{ // See tools/test_generator/include/TestHarness.h:MixedTyped
+ // int -> Dimensions map
+ .operandDimensions = {{0, {3}}},
+ // int -> FLOAT32 map
+ .float32Operands = {{0, {1.0f, 2.0f, 3.0f}}},
+ // int -> INT32 map
+ .int32Operands = {},
+ // int -> QUANT8_ASYMM map
+ .quant8AsymmOperands = {},
+ // int -> QUANT16_SYMM map
+ .quant16SymmOperands = {},
+ // int -> FLOAT16 map
+ .float16Operands = {},
+ // int -> BOOL8 map
+ .bool8Operands = {},
+ // int -> QUANT8_SYMM_PER_CHANNEL map
+ .quant8ChannelOperands = {},
+ // int -> QUANT16_ASYMM map
+ .quant16AsymmOperands = {},
+ // int -> QUANT8_SYMM map
+ .quant8SymmOperands = {},
+}
+},
+}, // End of an example
+};
+return examples_dynamic_output_shape;
+};
+
diff --git a/neuralnetworks/1.2/vts/functional/generated/strided_slice_invalid_output_dims.model.cpp b/neuralnetworks/1.2/vts/functional/generated/strided_slice_invalid_output_dims.model.cpp
new file mode 100644
index 0000000..106655a
--- /dev/null
+++ b/neuralnetworks/1.2/vts/functional/generated/strided_slice_invalid_output_dims.model.cpp
@@ -0,0 +1,216 @@
+// clang-format off
+// Generated file (from: strided_slice_invalid_output_dims.mod.py). Do not edit
+// Create the model
+Model createTestModel() {
+ const std::vector<Operand> operands = {
+ {
+ .type = OperandType::TENSOR_FLOAT32,
+ .dimensions = {2, 3},
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::MODEL_INPUT,
+ .location = {.poolIndex = 0, .offset = 0, .length = 0},
+ },
+ {
+ .type = OperandType::TENSOR_INT32,
+ .dimensions = {2},
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::CONSTANT_COPY,
+ .location = {.poolIndex = 0, .offset = 0, .length = 8},
+ },
+ {
+ .type = OperandType::TENSOR_INT32,
+ .dimensions = {2},
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::CONSTANT_COPY,
+ .location = {.poolIndex = 0, .offset = 8, .length = 8},
+ },
+ {
+ .type = OperandType::TENSOR_INT32,
+ .dimensions = {2},
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::CONSTANT_COPY,
+ .location = {.poolIndex = 0, .offset = 16, .length = 8},
+ },
+ {
+ .type = OperandType::INT32,
+ .dimensions = {},
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::CONSTANT_COPY,
+ .location = {.poolIndex = 0, .offset = 24, .length = 4},
+ },
+ {
+ .type = OperandType::INT32,
+ .dimensions = {},
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::CONSTANT_COPY,
+ .location = {.poolIndex = 0, .offset = 28, .length = 4},
+ },
+ {
+ .type = OperandType::INT32,
+ .dimensions = {},
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::CONSTANT_COPY,
+ .location = {.poolIndex = 0, .offset = 32, .length = 4},
+ },
+ {
+ .type = OperandType::TENSOR_FLOAT32,
+ .dimensions = {3},
+ .numberOfConsumers = 0,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::MODEL_OUTPUT,
+ .location = {.poolIndex = 0, .offset = 0, .length = 0},
+ }
+ };
+
+ const std::vector<Operation> operations = {
+ {
+ .type = OperationType::STRIDED_SLICE,
+ .inputs = {0, 1, 2, 3, 4, 5, 6},
+ .outputs = {7},
+ }
+ };
+
+ const std::vector<uint32_t> inputIndexes = {0};
+ const std::vector<uint32_t> outputIndexes = {7};
+ std::vector<uint8_t> operandValues = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0
+ };
+ const std::vector<hidl_memory> pools = {};
+
+ return {
+ .operands = operands,
+ .operations = operations,
+ .inputIndexes = inputIndexes,
+ .outputIndexes = outputIndexes,
+ .operandValues = operandValues,
+ .pools = pools,
+ };
+}
+
+inline bool is_ignored(int i) {
+ static std::set<int> ignore = {};
+ return ignore.find(i) != ignore.end();
+}
+
+// Create the model
+Model createTestModel_dynamic_output_shape() {
+ const std::vector<Operand> operands = {
+ {
+ .type = OperandType::TENSOR_FLOAT32,
+ .dimensions = {2, 3},
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::MODEL_INPUT,
+ .location = {.poolIndex = 0, .offset = 0, .length = 0},
+ },
+ {
+ .type = OperandType::TENSOR_INT32,
+ .dimensions = {2},
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::CONSTANT_COPY,
+ .location = {.poolIndex = 0, .offset = 0, .length = 8},
+ },
+ {
+ .type = OperandType::TENSOR_INT32,
+ .dimensions = {2},
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::CONSTANT_COPY,
+ .location = {.poolIndex = 0, .offset = 8, .length = 8},
+ },
+ {
+ .type = OperandType::TENSOR_INT32,
+ .dimensions = {2},
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::CONSTANT_COPY,
+ .location = {.poolIndex = 0, .offset = 16, .length = 8},
+ },
+ {
+ .type = OperandType::INT32,
+ .dimensions = {},
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::CONSTANT_COPY,
+ .location = {.poolIndex = 0, .offset = 24, .length = 4},
+ },
+ {
+ .type = OperandType::INT32,
+ .dimensions = {},
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::CONSTANT_COPY,
+ .location = {.poolIndex = 0, .offset = 28, .length = 4},
+ },
+ {
+ .type = OperandType::INT32,
+ .dimensions = {},
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::CONSTANT_COPY,
+ .location = {.poolIndex = 0, .offset = 32, .length = 4},
+ },
+ {
+ .type = OperandType::TENSOR_FLOAT32,
+ .dimensions = {0},
+ .numberOfConsumers = 0,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::MODEL_OUTPUT,
+ .location = {.poolIndex = 0, .offset = 0, .length = 0},
+ }
+ };
+
+ const std::vector<Operation> operations = {
+ {
+ .type = OperationType::STRIDED_SLICE,
+ .inputs = {0, 1, 2, 3, 4, 5, 6},
+ .outputs = {7},
+ }
+ };
+
+ const std::vector<uint32_t> inputIndexes = {0};
+ const std::vector<uint32_t> outputIndexes = {7};
+ std::vector<uint8_t> operandValues = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0
+ };
+ const std::vector<hidl_memory> pools = {};
+
+ return {
+ .operands = operands,
+ .operations = operations,
+ .inputIndexes = inputIndexes,
+ .outputIndexes = outputIndexes,
+ .operandValues = operandValues,
+ .pools = pools,
+ };
+}
+
+inline bool is_ignored_dynamic_output_shape(int i) {
+ static std::set<int> ignore = {};
+ return ignore.find(i) != ignore.end();
+}
+
diff --git a/neuralnetworks/1.2/vts/functional/include/1.2/Callbacks.h b/neuralnetworks/1.2/vts/functional/include/1.2/Callbacks.h
new file mode 100644
index 0000000..2992c0c
--- /dev/null
+++ b/neuralnetworks/1.2/vts/functional/include/1.2/Callbacks.h
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_NEURALNETWORKS_V1_2_CALLBACKS_H
+#define ANDROID_HARDWARE_NEURALNETWORKS_V1_2_CALLBACKS_H
+
+#include <android-base/thread_annotations.h>
+#include <android/hardware/neuralnetworks/1.0/IExecutionCallback.h>
+#include <android/hardware/neuralnetworks/1.0/IPreparedModelCallback.h>
+#include <android/hardware/neuralnetworks/1.2/IExecutionCallback.h>
+#include <android/hardware/neuralnetworks/1.2/IPreparedModelCallback.h>
+#include <hidl/Status.h>
+#include <condition_variable>
+#include <mutex>
+
+/*
+ * The Callback classes are used internally by the NeuralNetworks runtime to
+ * synchronize between different threads. An asynchronous task is launched
+ * paired with a callback object. When a client thread requires the output being
+ * generated by the asynchronous task, the client thread can wait for the result
+ * and be blocked until it has completed. Any wait may safely be called
+ * concurrently, even on the same callback object. When the asynchronous task
+ * has finished its workload, it must immediately call "notify*". If the
+ * asynchronous task has failed to launch, the function that tried to launch the
+ * asynchronous task must immediately call "notify*". This "notify*" call
+ * awakens any client threads waiting on the callback object.
+ *
+ * These classes exist to enable synchronization across HIDL. When
+ * synchronization is only required in the same process, consider using
+ * std::future, std::mutex, std::condition_variable, or std::experimental::latch
+ * instead.
+ */
+
+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
+ * asynchronously with respect to the runtime. If a calling thread calls wait
+ * or get* on a PreparedModelCallback object and the corresponding asynchronous
+ * task has not finished preparing the model, the calling thread will block
+ * until the asynchronous task has either called notify or notify_1_2.
+ *
+ * If the callback object is notified more than once, only the results of the
+ * first call to notify* are used, and the results from subsequent calls are
+ * discarded.
+ *
+ * This callback object is passed as an argument to IDevice::prepareModel*.
+ */
+class PreparedModelCallback : public IPreparedModelCallback {
+ public:
+ /**
+ * IPreparedModelCallback::notify marks the callback object with the return
+ * status of the asynchronous model preparation along with the prepared
+ * model, and allows all prior and future wait calls on the
+ * PreparedModelCallback object to proceed.
+ *
+ * Either IPreparedModelCallback::notify or
+ * IPreparedModelCallback::notify_1_2 must be called on a given
+ * PreparedModelCallback object.
+ *
+ * If the callback object is notified more than once, only the results of
+ * the first call to notify* are used, and the results from subsequent calls
+ * are discarded.
+ *
+ * @param status Error status returned from asynchronously preparing the
+ * model; will be:
+ * - NONE if the asynchronous preparation was successful
+ * - DEVICE_UNAVAILABLE if driver is offline or busy
+ * - GENERAL_FAILURE if there is an unspecified error
+ * - INVALID_ARGUMENT if the input model is invalid
+ * @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;
+
+ /**
+ * IPreparedModelCallback::notify_1_2 marks the callback object with the
+ * return status of the asynchronous model preparation along with the
+ * prepared model, and allows all prior and future wait calls on the
+ * PreparedModelCallback object to proceed.
+ *
+ * Either IPreparedModelCallback::notify or
+ * IPreparedModelCallback::notify_1_2 must be called on a given
+ * PreparedModelCallback object.
+ *
+ * If the callback object is notified more than once, only the results of
+ * the first call to notify* are used, and the results from subsequent calls
+ * are discarded.
+ *
+ * @param status Error status returned from asynchronously preparing the
+ * model; will be:
+ * - NONE if the asynchronous preparation was successful
+ * - DEVICE_UNAVAILABLE if driver is offline or busy
+ * - GENERAL_FAILURE if there is an unspecified error
+ * - INVALID_ARGUMENT if the input model is invalid
+ * @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,
+ const sp<V1_2::IPreparedModel>& preparedModel) override;
+
+ /**
+ * PreparedModelCallback::wait blocks until notify* has been called on the
+ * callback object.
+ */
+ void wait() const;
+
+ /**
+ * Retrieves the error status returned from the asynchronous task launched
+ * by IDevice::prepareModel*. If IDevice::prepareModel* has not finished
+ * asynchronously preparing the model, this call will block until the
+ * asynchronous task notifies the object.
+ *
+ * @return status Error status returned from asynchronously preparing the
+ * model; will be:
+ * - NONE if the asynchronous preparation was successful
+ * - DEVICE_UNAVAILABLE if driver is offline or busy
+ * - GENERAL_FAILURE if there is an unspecified error
+ * - INVALID_ARGUMENT if the input model is invalid
+ */
+ ErrorStatus getStatus() const;
+
+ /**
+ * Retrieves the model that has been prepared for execution from the
+ * asynchronous task launched by IDevice::prepareModel*. If
+ * IDevice::prepareModel* has not finished asynchronously preparing the
+ * model, this call will block until the asynchronous task notifies the
+ * object.
+ *
+ * @return preparedModel Returned model that has been prepared for
+ * execution, nullptr if the model was unable to be prepared.
+ */
+ sp<V1_0::IPreparedModel> getPreparedModel() const;
+
+ private:
+ mutable std::mutex mMutex;
+ mutable std::condition_variable mCondition;
+ bool mNotified GUARDED_BY(mMutex) = false;
+ ErrorStatus mErrorStatus = ErrorStatus::GENERAL_FAILURE;
+ sp<V1_0::IPreparedModel> mPreparedModel;
+};
+
+/**
+ * The ExecutionCallback class is used to receive the results of the execution
+ * from a task executing asynchronously with respect to the runtime. If a
+ * calling thread calls wait or get* on a ExecutionCallback object and the
+ * corresponding asynchronous task has not finished the execution, the calling
+ * thread will block until the asynchronous task has either called notify or
+ * notify_1_2.
+ *
+ * If the callback object is notified more than once, only the results of the
+ * first call to notify* are used, and the results from subsequent calls are
+ * discarded.
+ *
+ * This callback object is passed as an argument to IPreparedModel::execute*.
+ */
+class ExecutionCallback : public IExecutionCallback {
+ public:
+ /**
+ * IExecutionCallback::notify marks the callback object with the return
+ * status of the asynchronous execution that held this callback and enables
+ * all prior and future wait calls on the ExecutionCallback object to
+ * proceed.
+ *
+ * Either IExecutionCallback::notify or IExecutionCallback::notify_1_2 must
+ * be called on a given ExecutionCallback object.
+ *
+ * If the callback object is notified more than once, only the results of
+ * the first call to notify* are used, and the results from subsequent calls
+ * are discarded.
+ *
+ * @param status Error status returned from launching the asynchronous task
+ * (if the launch fails) or from the asynchronous task itself (if the
+ * launch succeeds). Must be:
+ * - NONE if the asynchronous execution was successful
+ * - DEVICE_UNAVAILABLE if driver is offline or busy
+ * - GENERAL_FAILURE if there is an unspecified error
+ * - OUTPUT_INSUFFICIENT_SIZE if provided output buffer is not large
+ * enough to store the resultant values
+ * - INVALID_ARGUMENT if the input request is invalid
+ */
+ Return<void> notify(ErrorStatus status) override;
+
+ /**
+ * IExecutionCallback::notify_1_2 marks the callback object with the results
+ * (error status, dynamic output shapes, and timing information) of the
+ * asynchronous execution that held this callback and enables all prior and
+ * future wait calls on the ExecutionCallback object to proceed.
+ *
+ * Either IExecutionCallback::notify or IExecutionCallback::notify_1_2 must
+ * be called on a given ExecutionCallback object.
+ *
+ * If the callback object is notified more than once, only the results of
+ * the first call to notify* are used, and the results from subsequent calls
+ * are discarded.
+ *
+ * @param status Error status returned from launching the asynchronous task
+ * (if the launch fails) or from the asynchronous task itself (if the
+ * launch succeeds). Must be:
+ * - NONE if the asynchronous execution was successful
+ * - DEVICE_UNAVAILABLE if driver is offline or busy
+ * - GENERAL_FAILURE if the asynchronous task resulted in an unspecified
+ * error
+ * - OUTPUT_INSUFFICIENT_SIZE if at least one output operand buffer is
+ * not large enough to store the corresponding output
+ * - INVALID_ARGUMENT if one of the input arguments to prepareModel is
+ * invalid
+ * @param outputShapes A list of shape information of model output operands.
+ * The index into "outputShapes" corresponds to the index of the output
+ * operand in the Request outputs vector. outputShapes must be empty
+ * unless the status is either NONE or OUTPUT_INSUFFICIENT_SIZE.
+ * @param Timing Duration of execution. Unless MeasureTiming::YES was passed
+ * when launching the execution and status is NONE, all times must be
+ * 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,
+ 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,
+ const Timing& timing) {
+ return notify_1_2(status, outputShapes, timing);
+ }
+
+ /**
+ * ExecutionCallback::wait blocks until notify* has been called on the
+ * callback object.
+ */
+ void wait() const;
+
+ /**
+ * Retrieves the error status returned from the asynchronous task launched
+ * by either IPreparedModel::execute or IPreparedModel::execute_1_2. If
+ * IPreparedModel::execute or IPreparedModel::execute_1_2 has not finished
+ * asynchronously executing, this call will block until the asynchronous
+ * task notifies the object.
+ *
+ * @return status Error status returned from launching the asynchronous task
+ * (if the launch fails) or from the asynchronous task itself (if the
+ * launch succeeds). Must be:
+ * - NONE if the asynchronous execution was successful
+ * - DEVICE_UNAVAILABLE if driver is offline or busy
+ * - GENERAL_FAILURE if the asynchronous task resulted in an unspecified
+ * error
+ * - OUTPUT_INSUFFICIENT_SIZE if at least one output operand buffer is
+ * not large enough to store the corresponding output
+ * - INVALID_ARGUMENT if one of the input arguments to prepareModel is
+ * invalid
+ */
+ ErrorStatus getStatus() const;
+
+ /**
+ * Retrieves the output shapes returned from the asynchronous task launched
+ * by IPreparedModel::execute_1_2. If IPreparedModel::execute_1_2 has not
+ * finished asynchronously executing, this call will block until the
+ * asynchronous task notifies the object.
+ *
+ * If the asynchronous task was launched by IPreparedModel::execute, an
+ * empty vector will be returned.
+ *
+ * @return outputShapes A list of shape information of model output
+ * operands. The index into "outputShapes" corresponds to the index of
+ * the output operand in the Request outputs vector. outputShapes must
+ * be empty unless the status is either NONE or
+ * OUTPUT_INSUFFICIENT_SIZE. outputShaps may be empty if the status is
+ * NONE and all model output operands are fully-specified at execution
+ * time. outputShapes must have the same number of elements as the
+ * number of model output operands if the status is
+ * OUTPUT_INSUFFICIENT_SIZE, or if the status is NONE and the model has
+ * at least one output operand that is not fully-specified.
+ */
+ const std::vector<OutputShape>& getOutputShapes() const;
+
+ /**
+ * Retrieves the duration of execution of the asynchronous task launched by
+ * IPreparedModel::execute_1_2. If IPreparedModel::execute_1_2 has not
+ * finished asynchronously executing, this call will block until the
+ * asynchronous task notifies the object.
+ *
+ * If the asynchronous task was launched by IPreparedModel::execute, every
+ * time must be UINT64_MAX.
+ *
+ * @return timing Duration of the execution. Every time must be UINT64_MAX
+ * unless the status is NONE.
+ */
+ Timing getTiming() const;
+
+ private:
+ /*
+ * ExecutionCallback::notifyInternal stores the results of the execution
+ * (status, output shapes, and timing information) in the ExecutionCallback
+ * 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,
+ const Timing& timing);
+
+ // members
+ mutable std::mutex mMutex;
+ mutable std::condition_variable mCondition;
+ bool mNotified GUARDED_BY(mMutex) = false;
+ ErrorStatus mErrorStatus = ErrorStatus::GENERAL_FAILURE;
+ std::vector<OutputShape> mOutputShapes = {};
+ Timing mTiming = {};
+};
+
+} // namespace android::hardware::neuralnetworks::V1_2::implementation
+
+#endif // ANDROID_HARDWARE_NEURALNETWORKS_V1_2_CALLBACKS_H
diff --git a/neuralnetworks/1.2/vts/functional/spec/strided_slice_invalid_output_dims.mod.py b/neuralnetworks/1.2/vts/functional/spec/strided_slice_invalid_output_dims.mod.py
new file mode 100644
index 0000000..e8d30f3
--- /dev/null
+++ b/neuralnetworks/1.2/vts/functional/spec/strided_slice_invalid_output_dims.mod.py
@@ -0,0 +1,43 @@
+#
+# 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.
+#
+
+# This test makes sure that executing STRIDED_SLICE results in a failure when
+# the output dimensions do not match shrinkAxisMask.
+#
+# The test generator does not support generating tests resulting in execution
+# failure, so the gTest part of this test has been written by hand.
+# TODO(b/132155416): Move this under frameworks/ml/nn/runtime/test/specs/V1_2.
+#
+# Based on strided_slice_float_11.mod.py.
+
+model = Model()
+i1 = Input("input", "TENSOR_FLOAT32", "{2, 3}")
+begins = Parameter("begins", "TENSOR_INT32", "{2}", [0, 0])
+# The value "2" below makes the test invalid. See http://b/79856511#comment2.
+ends = Parameter("ends", "TENSOR_INT32", "{2}", [2, 3])
+strides = Parameter("strides", "TENSOR_INT32", "{2}", [1, 1])
+beginMask = Int32Scalar("beginMask", 0)
+endMask = Int32Scalar("endMask", 0)
+shrinkAxisMask = Int32Scalar("shrinkAxisMask", 1)
+
+output = Output("output", "TENSOR_FLOAT32", "{3}")
+
+model = model.Operation("STRIDED_SLICE", i1, begins, ends, strides, beginMask, endMask, shrinkAxisMask).To(output)
+
+Example({
+ i1: [1, 2, 3, 4, 5, 6],
+ output: [1, 2, 3],
+})
diff --git a/nfc/1.0/Android.bp b/nfc/1.0/Android.bp
index e0625d0..bd64907 100644
--- a/nfc/1.0/Android.bp
+++ b/nfc/1.0/Android.bp
@@ -17,4 +17,3 @@
gen_java: true,
gen_java_constants: true,
}
-
diff --git a/nfc/1.0/default/android.hardware.nfc@1.0-service.rc b/nfc/1.0/default/android.hardware.nfc@1.0-service.rc
index 3a5c776..27e35d2 100644
--- a/nfc/1.0/default/android.hardware.nfc@1.0-service.rc
+++ b/nfc/1.0/default/android.hardware.nfc@1.0-service.rc
@@ -1,4 +1,5 @@
service vendor.nfc_hal_service /vendor/bin/hw/android.hardware.nfc@1.0-service
+ interface android.hardware.nfc@1.0::INfc default
class hal
user nfc
group nfc
diff --git a/nfc/1.1/Android.bp b/nfc/1.1/Android.bp
index bbf49b2..1f8789f 100644
--- a/nfc/1.1/Android.bp
+++ b/nfc/1.1/Android.bp
@@ -17,4 +17,3 @@
],
gen_java: true,
}
-
diff --git a/nfc/1.2/Android.bp b/nfc/1.2/Android.bp
index cfb8b85..aa68d2f 100644
--- a/nfc/1.2/Android.bp
+++ b/nfc/1.2/Android.bp
@@ -17,4 +17,3 @@
],
gen_java: true,
}
-
diff --git a/nfc/1.2/vts/OWNERS b/nfc/1.2/vts/OWNERS
new file mode 100644
index 0000000..21d4df1
--- /dev/null
+++ b/nfc/1.2/vts/OWNERS
@@ -0,0 +1,3 @@
+zachoverflow@google.com
+jackcwyu@google.com
+georgekgchang@google.com
diff --git a/oemlock/1.0/Android.bp b/oemlock/1.0/Android.bp
index 894188b..e784be0 100644
--- a/oemlock/1.0/Android.bp
+++ b/oemlock/1.0/Android.bp
@@ -15,4 +15,3 @@
],
gen_java: true,
}
-
diff --git a/power/1.0/Android.bp b/power/1.0/Android.bp
index dbc0a36..6ba1d78 100644
--- a/power/1.0/Android.bp
+++ b/power/1.0/Android.bp
@@ -15,4 +15,3 @@
],
gen_java: true,
}
-
diff --git a/power/1.0/default/android.hardware.power@1.0-service.rc b/power/1.0/default/android.hardware.power@1.0-service.rc
index 657c733..f3fd303 100644
--- a/power/1.0/default/android.hardware.power@1.0-service.rc
+++ b/power/1.0/default/android.hardware.power@1.0-service.rc
@@ -1,4 +1,5 @@
service vendor.power-hal-1-0 /vendor/bin/hw/android.hardware.power@1.0-service
+ interface android.hardware.power@1.0::IPower default
class hal
user system
group system
diff --git a/power/1.1/Android.bp b/power/1.1/Android.bp
index de55396..6b133cc 100644
--- a/power/1.1/Android.bp
+++ b/power/1.1/Android.bp
@@ -16,4 +16,3 @@
],
gen_java: true,
}
-
diff --git a/power/1.2/Android.bp b/power/1.2/Android.bp
index 284e736..296965b 100644
--- a/power/1.2/Android.bp
+++ b/power/1.2/Android.bp
@@ -17,4 +17,3 @@
],
gen_java: true,
}
-
diff --git a/power/1.3/Android.bp b/power/1.3/Android.bp
index 320f1e6..00ca750 100644
--- a/power/1.3/Android.bp
+++ b/power/1.3/Android.bp
@@ -18,4 +18,3 @@
],
gen_java: true,
}
-
diff --git a/power/stats/1.0/Android.bp b/power/stats/1.0/Android.bp
index 9cf24cf..c592006 100644
--- a/power/stats/1.0/Android.bp
+++ b/power/stats/1.0/Android.bp
@@ -15,4 +15,3 @@
],
gen_java: false,
}
-
diff --git a/prebuilt_hashes/28.txt b/prebuilt_hashes/28.txt
index cc15322..8a45ca5 100644
--- a/prebuilt_hashes/28.txt
+++ b/prebuilt_hashes/28.txt
@@ -348,6 +348,8 @@
5e278fcaa3287d397d8eebe1c22aaa28150f5caae1cf9381cd6dc32cb37899c5 android.hardware.nfc@1.1::types
163e115e833fc1d77cdd4a8cf0c833bb8b8d74fe35c880fe693101d17774926f android.hardware.power@1.2::IPower
7899b9305587b2d5cd74a3cc87e9090f58bf4ae74256ce3ee36e7ec011822840 android.hardware.power@1.2::types
+5a464e6db53fad223986d655028a18185b73db8e2bfa9663f9042c9623eb0aa0 android.hardware.power@1.3::IPower
+a54a28d39b892d27a3cb06829181c038edcdd9e8eef359543b01e4313ae59aa0 android.hardware.power@1.3::types
ab132c990a62f0aca35871c092c22fb9c85d478e22124ef6a4d0a2302da76a9f android.hardware.radio@1.2::IRadio
cda752aeabaabc20486a82ac57a3dd107785c006094a349bc5e224e8aa22a17c android.hardware.radio@1.2::IRadioIndication
da8c6ae991c6a4b284cc6e445332e064e28ee8a09482ed5afff9d159ec6694b7 android.hardware.radio@1.2::IRadioResponse
diff --git a/radio/1.0/Android.bp b/radio/1.0/Android.bp
index f023471..6765b4d 100644
--- a/radio/1.0/Android.bp
+++ b/radio/1.0/Android.bp
@@ -19,4 +19,3 @@
],
gen_java: true,
}
-
diff --git a/radio/1.1/Android.bp b/radio/1.1/Android.bp
index 4375d8c..28388b0 100644
--- a/radio/1.1/Android.bp
+++ b/radio/1.1/Android.bp
@@ -19,4 +19,3 @@
],
gen_java: true,
}
-
diff --git a/radio/1.2/Android.bp b/radio/1.2/Android.bp
index b7364a8..28e6b26 100644
--- a/radio/1.2/Android.bp
+++ b/radio/1.2/Android.bp
@@ -20,4 +20,3 @@
],
gen_java: true,
}
-
diff --git a/radio/1.2/default/android.hardware.radio@1.2-radio-service.rc b/radio/1.2/default/android.hardware.radio@1.2-radio-service.rc
index e126cd8..eab37ec 100644
--- a/radio/1.2/default/android.hardware.radio@1.2-radio-service.rc
+++ b/radio/1.2/default/android.hardware.radio@1.2-radio-service.rc
@@ -1,4 +1,13 @@
service vendor.radio-1-2 /vendor/bin/hw/android.hardware.radio@1.2-radio-service
+ interface android.hardware.radio@1.0::IRadio slot1
+ interface android.hardware.radio@1.0::IRadio slot2
+ interface android.hardware.radio@1.0::IRadio slot3
+ interface android.hardware.radio@1.1::IRadio slot1
+ interface android.hardware.radio@1.1::IRadio slot2
+ interface android.hardware.radio@1.1::IRadio slot3
+ interface android.hardware.radio@1.2::IRadio slot1
+ interface android.hardware.radio@1.2::IRadio slot2
+ interface android.hardware.radio@1.2::IRadio slot3
class hal
user system
group system
diff --git a/radio/1.2/default/android.hardware.radio@1.2-sap-service.rc b/radio/1.2/default/android.hardware.radio@1.2-sap-service.rc
index 845e6e5..9f163f6 100644
--- a/radio/1.2/default/android.hardware.radio@1.2-sap-service.rc
+++ b/radio/1.2/default/android.hardware.radio@1.2-sap-service.rc
@@ -1,4 +1,7 @@
service vendor.sap-1-2 /vendor/bin/hw/android.hardware.radio@1.2-sap-service
+ interface android.hardware.radio@1.0::ISap slot1
+ interface android.hardware.radio@1.1::ISap slot1
+ interface android.hardware.radio@1.2::ISap slot1
class hal
user system
group system
diff --git a/radio/1.3/Android.bp b/radio/1.3/Android.bp
index de2a3e5..b6af874 100644
--- a/radio/1.3/Android.bp
+++ b/radio/1.3/Android.bp
@@ -20,4 +20,3 @@
],
gen_java: true,
}
-
diff --git a/radio/1.4/Android.bp b/radio/1.4/Android.bp
index 9f5f2f9..ff2e0d6 100644
--- a/radio/1.4/Android.bp
+++ b/radio/1.4/Android.bp
@@ -22,4 +22,3 @@
],
gen_java: true,
}
-
diff --git a/radio/config/1.0/Android.bp b/radio/config/1.0/Android.bp
index 7fb0ea1..387f953 100644
--- a/radio/config/1.0/Android.bp
+++ b/radio/config/1.0/Android.bp
@@ -18,4 +18,3 @@
],
gen_java: true,
}
-
diff --git a/radio/config/1.0/default/android.hardware.radio.config@1.0-service.rc b/radio/config/1.0/default/android.hardware.radio.config@1.0-service.rc
index fad16b1..94d5edb 100644
--- a/radio/config/1.0/default/android.hardware.radio.config@1.0-service.rc
+++ b/radio/config/1.0/default/android.hardware.radio.config@1.0-service.rc
@@ -1,4 +1,5 @@
service vendor.radio-config-hal-1-0 /vendor/bin/hw/android.hardware.radio.config@1.0-service
+ interface android.hardware.radio.config@1.0::IRadioConfig default
class hal
user system
group system
diff --git a/radio/config/1.1/Android.bp b/radio/config/1.1/Android.bp
index 5c9ad7c..1e9071a 100644
--- a/radio/config/1.1/Android.bp
+++ b/radio/config/1.1/Android.bp
@@ -19,4 +19,3 @@
],
gen_java: true,
}
-
diff --git a/radio/config/1.2/Android.bp b/radio/config/1.2/Android.bp
index e69be40..812f166 100644
--- a/radio/config/1.2/Android.bp
+++ b/radio/config/1.2/Android.bp
@@ -19,4 +19,3 @@
],
gen_java: true,
}
-
diff --git a/radio/deprecated/1.0/Android.bp b/radio/deprecated/1.0/Android.bp
index c9f86f0..cb13b86 100644
--- a/radio/deprecated/1.0/Android.bp
+++ b/radio/deprecated/1.0/Android.bp
@@ -17,4 +17,3 @@
],
gen_java: true,
}
-
diff --git a/renderscript/1.0/Android.bp b/renderscript/1.0/Android.bp
index 1d7efad..feae9f7 100644
--- a/renderscript/1.0/Android.bp
+++ b/renderscript/1.0/Android.bp
@@ -18,4 +18,3 @@
gen_java: false,
gen_java_constants: true,
}
-
diff --git a/secure_element/1.0/Android.bp b/secure_element/1.0/Android.bp
index c6fa6a9..32b752b 100644
--- a/secure_element/1.0/Android.bp
+++ b/secure_element/1.0/Android.bp
@@ -16,4 +16,3 @@
],
gen_java: true,
}
-
diff --git a/secure_element/1.1/Android.bp b/secure_element/1.1/Android.bp
index e16bc3d..3ea2de9 100644
--- a/secure_element/1.1/Android.bp
+++ b/secure_element/1.1/Android.bp
@@ -16,4 +16,3 @@
],
gen_java: true,
}
-
diff --git a/sensors/1.0/Android.bp b/sensors/1.0/Android.bp
index 3a41f9c..509f72f 100644
--- a/sensors/1.0/Android.bp
+++ b/sensors/1.0/Android.bp
@@ -16,4 +16,3 @@
gen_java: false,
gen_java_constants: true,
}
-
diff --git a/sensors/1.0/default/android.hardware.sensors@1.0-service.rc b/sensors/1.0/default/android.hardware.sensors@1.0-service.rc
index b54842d..4faa562 100644
--- a/sensors/1.0/default/android.hardware.sensors@1.0-service.rc
+++ b/sensors/1.0/default/android.hardware.sensors@1.0-service.rc
@@ -1,4 +1,5 @@
service vendor.sensors-hal-1-0 /vendor/bin/hw/android.hardware.sensors@1.0-service
+ interface android.hardware.sensors@1.0::ISensors default
class hal
user system
group system wakelock
diff --git a/sensors/2.0/Android.bp b/sensors/2.0/Android.bp
index eead1d3..c8517c8 100644
--- a/sensors/2.0/Android.bp
+++ b/sensors/2.0/Android.bp
@@ -17,4 +17,3 @@
],
gen_java: false,
}
-
diff --git a/soundtrigger/2.0/Android.bp b/soundtrigger/2.0/Android.bp
index b805be8..5613abd 100644
--- a/soundtrigger/2.0/Android.bp
+++ b/soundtrigger/2.0/Android.bp
@@ -17,4 +17,3 @@
],
gen_java: false,
}
-
diff --git a/soundtrigger/2.0/ISoundTriggerHwCallback.hal b/soundtrigger/2.0/ISoundTriggerHwCallback.hal
index 90132d9..84b11c8 100644
--- a/soundtrigger/2.0/ISoundTriggerHwCallback.hal
+++ b/soundtrigger/2.0/ISoundTriggerHwCallback.hal
@@ -46,7 +46,6 @@
int32_t captureSession;
/**
* Delay in ms between end of model detection and start of audio
- /**
* available for capture. A negative value is possible
* (e.g. if key phrase is also available for capture */
int32_t captureDelayMs;
diff --git a/soundtrigger/2.1/Android.bp b/soundtrigger/2.1/Android.bp
index ed1ec3d..68e425b 100644
--- a/soundtrigger/2.1/Android.bp
+++ b/soundtrigger/2.1/Android.bp
@@ -17,4 +17,3 @@
],
gen_java: false,
}
-
diff --git a/soundtrigger/2.2/Android.bp b/soundtrigger/2.2/Android.bp
index 0a7c2d8..43898c7 100644
--- a/soundtrigger/2.2/Android.bp
+++ b/soundtrigger/2.2/Android.bp
@@ -17,4 +17,3 @@
],
gen_java: false,
}
-
diff --git a/tests/bar/1.0/Android.bp b/tests/bar/1.0/Android.bp
index a1b6b88..0aeccd6 100644
--- a/tests/bar/1.0/Android.bp
+++ b/tests/bar/1.0/Android.bp
@@ -17,4 +17,3 @@
],
gen_java: false,
}
-
diff --git a/tests/baz/1.0/Android.bp b/tests/baz/1.0/Android.bp
index 618f4f8..ed18876 100644
--- a/tests/baz/1.0/Android.bp
+++ b/tests/baz/1.0/Android.bp
@@ -15,4 +15,3 @@
],
gen_java: true,
}
-
diff --git a/tests/expression/1.0/Android.bp b/tests/expression/1.0/Android.bp
index 61ca6ac..4bc3848 100644
--- a/tests/expression/1.0/Android.bp
+++ b/tests/expression/1.0/Android.bp
@@ -12,4 +12,3 @@
],
gen_java: true,
}
-
diff --git a/tests/extension/light/2.0/Android.bp b/tests/extension/light/2.0/Android.bp
index 916af71..e19a913 100644
--- a/tests/extension/light/2.0/Android.bp
+++ b/tests/extension/light/2.0/Android.bp
@@ -13,4 +13,3 @@
],
gen_java: true,
}
-
diff --git a/tests/foo/1.0/Android.bp b/tests/foo/1.0/Android.bp
index 1c3b3c5..2f97fca 100644
--- a/tests/foo/1.0/Android.bp
+++ b/tests/foo/1.0/Android.bp
@@ -16,4 +16,3 @@
],
gen_java: false,
}
-
diff --git a/tests/hash/1.0/Android.bp b/tests/hash/1.0/Android.bp
index 20334cd..1095576 100644
--- a/tests/hash/1.0/Android.bp
+++ b/tests/hash/1.0/Android.bp
@@ -11,4 +11,3 @@
],
gen_java: true,
}
-
diff --git a/tests/inheritance/1.0/Android.bp b/tests/inheritance/1.0/Android.bp
index 1d36d07..0042b57 100644
--- a/tests/inheritance/1.0/Android.bp
+++ b/tests/inheritance/1.0/Android.bp
@@ -14,4 +14,3 @@
],
gen_java: true,
}
-
diff --git a/tests/libhwbinder/1.0/Android.bp b/tests/libhwbinder/1.0/Android.bp
index d561002..13af77c 100644
--- a/tests/libhwbinder/1.0/Android.bp
+++ b/tests/libhwbinder/1.0/Android.bp
@@ -12,4 +12,3 @@
],
gen_java: true,
}
-
diff --git a/tests/libhwbinder/aidl/Android.bp b/tests/libhwbinder/aidl/Android.bp
index 6d49704..c9e09f7 100644
--- a/tests/libhwbinder/aidl/Android.bp
+++ b/tests/libhwbinder/aidl/Android.bp
@@ -1,4 +1,4 @@
-cc_library_shared {
+cc_library {
name: "android.hardware.tests.libbinder",
defaults: ["hidl_defaults"],
diff --git a/tests/memory/1.0/Android.bp b/tests/memory/1.0/Android.bp
index cbee247..29f6be7 100644
--- a/tests/memory/1.0/Android.bp
+++ b/tests/memory/1.0/Android.bp
@@ -13,4 +13,3 @@
],
gen_java: false,
}
-
diff --git a/tests/msgq/1.0/Android.bp b/tests/msgq/1.0/Android.bp
index 2d8d565..eea1ce6 100644
--- a/tests/msgq/1.0/Android.bp
+++ b/tests/msgq/1.0/Android.bp
@@ -12,4 +12,3 @@
],
gen_java: false,
}
-
diff --git a/tests/multithread/1.0/Android.bp b/tests/multithread/1.0/Android.bp
index 0d21b1b..ed3a687 100644
--- a/tests/multithread/1.0/Android.bp
+++ b/tests/multithread/1.0/Android.bp
@@ -11,4 +11,3 @@
],
gen_java: true,
}
-
diff --git a/tests/pointer/1.0/.hidl_for_test b/tests/pointer/1.0/.hidl_for_test
deleted file mode 100644
index e69de29..0000000
--- a/tests/pointer/1.0/.hidl_for_test
+++ /dev/null
diff --git a/tests/pointer/1.0/Android.bp b/tests/pointer/1.0/Android.bp
deleted file mode 100644
index 3dc8e8a..0000000
--- a/tests/pointer/1.0/Android.bp
+++ /dev/null
@@ -1,15 +0,0 @@
-// This file is autogenerated by hidl-gen -Landroidbp.
-
-hidl_interface {
- name: "android.hardware.tests.pointer@1.0",
- root: "android.hardware",
- srcs: [
- "IGraph.hal",
- "IPointer.hal",
- ],
- interfaces: [
- "android.hidl.base@1.0",
- ],
- gen_java: false,
-}
-
diff --git a/tests/pointer/1.0/IGraph.hal b/tests/pointer/1.0/IGraph.hal
deleted file mode 100644
index 0853745..0000000
--- a/tests/pointer/1.0/IGraph.hal
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.tests.pointer@1.0;
-
-interface IGraph {
-
- struct Node {
- int32_t data;
- };
- struct Edge {
- ref<Node> left;
- ref<Node> right;
- };
- struct Graph {
- vec<Node> nodes;
- vec<Edge> edges;
- };
-
- struct Theta {
- int32_t data;
- };
- struct Alpha {
- ref<Theta> s_ptr;
- };
- struct Beta {
- ref<Theta> s_ptr;
- };
- struct Gamma {
- ref<Alpha> a_ptr;
- ref<Beta> b_ptr;
- };
-
- passANode(Node n);
- passAGraph(Graph g);
- passTwoGraphs(ref<Graph> g1, ref<Graph> g2);
- giveAGraph() generates (Graph g);
- passAGamma(Gamma c);
- passASimpleRef(ref<Alpha> a);
- passASimpleRefS(ref<Theta> s);
- giveASimpleRef() generates (ref<Alpha> a);
-
- getErrors() generates (int32_t errors);
-};
diff --git a/tests/pointer/1.0/IPointer.hal b/tests/pointer/1.0/IPointer.hal
deleted file mode 100644
index 4560a4a..0000000
--- a/tests/pointer/1.0/IPointer.hal
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.tests.pointer@1.0;
-
-interface IPointer {
- struct S { int32_t data; };
- struct A { S s; };
- // type declarations
- struct Sam { int32_t data; };
- struct Ada { ref<Sam> s_ptr; };
- struct Bob { ref<Ada> a_ptr; ref<Sam> s_ptr; };
- struct Cin { Ada a; ref<Bob> b_ptr; };
- struct Dom { Cin c; };
-
- typedef ref<int32_t> Int32Ptr;
- typedef ref<Sam> SamPtr;
-
- struct Ptr {
- ref<Ada>[5] ptr_array;
- ref<Ada[5]> array_ptr;
- Int32Ptr int_ptr;
- ref<int32_t[5]> int_array_ptr;
- ref<int32_t>[5] int_ptr_array;
- ref<string> str_ref;
- vec<ref<Ada>> a_ptr_vec;
- ref<vec<Ada>> a_vec_ptr;
- };
-
- // test cases
- foo1(Sam s, SamPtr s_ptr);
- foo2(Sam s, Ada a);
- foo3(Sam s, Ada a, Bob b);
- foo4(ref<Sam> s_ptr);
- foo5(Ada a, Bob b);
- foo6(ref<Ada> a_ptr);
- foo7(ref<Ada> a_ptr, ref<Bob> b_ptr);
- foo8(Dom d);
- foo9(ref<string> str_ref);
- foo10(vec<ref<Sam>> s_ptr_vec);
- foo11(ref<vec<Sam>> s_vec_ptr);
- foo12(ref<Sam[5]> s_array_ref);
- foo13(ref<Sam>[5] s_ref_array);
- foo14(ref<ref<ref<Sam>>> s_3ptr);
- foo15(ref<ref<ref<int32_t>>> i_3ptr);
- foo16(Ptr p);
- foo17(ref<Ptr> p);
- foo18(ref<string> str_ref, ref<string> str_ref2, string str);
- foo19(ref<vec<Ada>> a_vec_ref, vec<Ada> a_vec, ref<vec<Ada>> a_vec_ref2);
- foo20(vec<ref<Sam>> s_ptr_vec);
- foo21(ref<Ada[1][2][3]> a_array_ptr);
- foo22(ref<Ada>[1][2][3] a_ptr_array);
-
- bar1() generates (Sam s, ref<Sam> s_ptr);
- bar2() generates (Sam s, Ada a);
- bar3() generates (Sam s, Ada a, Bob b);
- bar4() generates (ref<Sam> s_ptr);
- bar5() generates (Ada a, Bob b);
- bar6() generates (ref<Ada> a_ptr);
- bar7() generates (ref<Ada> a_ptr, ref<Bob> b_ptr);
- bar8() generates (Dom d);
- bar9() generates (ref<string> str_ref);
- bar10() generates (vec<ref<Sam>> s_ptr_vec);
- bar11() generates (ref<vec<Sam>> s_vec_ptr);
- bar12() generates (ref<Sam[5]> s_array_ref);
- bar13() generates (ref<Sam>[5] s_ref_array);
- bar14() generates (ref<ref<ref<Sam>>> s_3ptr);
- bar15() generates (ref<ref<ref<int32_t>>> i_3ptr);
- bar16() generates (Ptr p);
- bar17() generates (ref<Ptr> p);
- bar18() generates (ref<string> str_ref, ref<string> str_ref2, string str);
- bar19() generates (ref<vec<Ada>> a_vec_ref, vec<Ada> a_vec, ref<vec<Ada>> a_vec_ref2);
- bar20() generates (vec<ref<Sam>> s_ptr_vec);
- bar21() generates (ref<Ada[1][2][3]> a_array_ptr);
- bar22() generates (ref<Ada>[1][2][3] a_ptr_array);
-
- getErrors() generates(int32_t errors);
-};
diff --git a/tests/pointer/1.0/default/Android.bp b/tests/pointer/1.0/default/Android.bp
deleted file mode 100644
index 4825ac7..0000000
--- a/tests/pointer/1.0/default/Android.bp
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-cc_library {
- name: "android.hardware.tests.pointer@1.0-impl",
- defaults: ["hidl_defaults"],
- relative_install_path: "hw",
- srcs: [
- "Graph.cpp",
- "Pointer.cpp",
- ],
-
- shared_libs: [
- "libbase",
- "libcutils",
- "libhidlbase",
- "libhidltransport",
- "libhwbinder",
- "libpointertest",
- "liblog",
- "libutils",
- ],
-
- // These are static libs only for testing purposes and portability. Shared
- // libs should be used on device.
- static_libs: ["android.hardware.tests.pointer@1.0"],
-
-}
diff --git a/tests/pointer/1.0/default/Graph.cpp b/tests/pointer/1.0/default/Graph.cpp
deleted file mode 100644
index 5c8098b..0000000
--- a/tests/pointer/1.0/default/Graph.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-#define LOG_TAG "hidl_test"
-
-#include "Graph.h"
-
-#include <log/log.h>
-
-#include <hidl-test/PointerHelper.h>
-
-#define PUSH_ERROR_IF(__cond__) if(__cond__) { errors.push_back(std::to_string(__LINE__) + ": " + #__cond__); }
-
-namespace android {
-namespace hardware {
-namespace tests {
-namespace pointer {
-namespace V1_0 {
-namespace implementation {
-
-// Methods from ::android::hardware::tests::pointer::V1_0::IGraph follow.
-Return<void> Graph::passAGraph(const IGraph::Graph& g) {
- ALOGI("SERVER(Graph) passAGraph start.");
- PUSH_ERROR_IF(!isSimpleGraph(g));
- // logSimpleGraph("SERVER(Graph) passAGraph:", g);
- return Void();
-}
-
-Return<void> Graph::giveAGraph(giveAGraph_cb _cb) {
- IGraph::Graph g;
- simpleGraph(g);
- _cb(g);
- return Void();
-}
-
-Return<void> Graph::passANode(const IGraph::Node& n) {
- PUSH_ERROR_IF(n.data != 10);
- return Void();
-}
-
-Return<void> Graph::passTwoGraphs(IGraph::Graph const* g1, IGraph::Graph const* g2) {
- PUSH_ERROR_IF(g1 != g2);
- PUSH_ERROR_IF(!isSimpleGraph(*g1));
- logSimpleGraph("SERVER(Graph): passTwoGraphs", *g2);
- return Void();
-}
-
-Return<void> Graph::passAGamma(const IGraph::Gamma& c) {
- if(c.a_ptr == nullptr && c.b_ptr == nullptr)
- return Void();
- ALOGI("SERVER(Graph) passAGamma received c.a = %p, c.b = %p, c.a->s = %p, c.b->s = %p",
- c.a_ptr, c.b_ptr, c.a_ptr->s_ptr, c.b_ptr->s_ptr);
- ALOGI("SERVER(Graph) passAGamma received data %d, %d",
- (int)c.a_ptr->s_ptr->data, (int)c.b_ptr->s_ptr->data);
- PUSH_ERROR_IF(c.a_ptr->s_ptr != c.b_ptr->s_ptr);
- return Void();
-}
-Return<void> Graph::passASimpleRef(const IGraph::Alpha * a_ptr) {
- ALOGI("SERVER(Graph) passASimpleRef received %d", a_ptr->s_ptr->data);
- PUSH_ERROR_IF(a_ptr->s_ptr->data != 500);
- return Void();
-}
-Return<void> Graph::passASimpleRefS(const IGraph::Theta * s_ptr) {
- ALOGI("SERVER(Graph) passASimpleRefS received %d @ %p", s_ptr->data, s_ptr);
- PUSH_ERROR_IF(s_ptr->data == 10);
- return Void();
-}
-Return<void> Graph::giveASimpleRef(giveASimpleRef_cb _cb) {
- IGraph::Theta s; s.data = 500;
- IGraph::Alpha a; a.s_ptr = &s;
- _cb(&a);
- return Void();
-}
-
-Return<int32_t> Graph::getErrors() {
- if(!errors.empty()) {
- for(const auto& e : errors)
- ALOGW("SERVER(Graph) error: %s", e.c_str());
- }
- return errors.size();
-}
-
-IGraph* HIDL_FETCH_IGraph(const char* /* name */) {
- return new Graph();
-}
-
-} // namespace implementation
-} // namespace V1_0
-} // namespace pointer
-} // namespace tests
-} // namespace hardware
-} // namespace android
diff --git a/tests/pointer/1.0/default/Graph.h b/tests/pointer/1.0/default/Graph.h
deleted file mode 100644
index 03bd163..0000000
--- a/tests/pointer/1.0/default/Graph.h
+++ /dev/null
@@ -1,47 +0,0 @@
-#ifndef ANDROID_HARDWARE_TESTS_POINTER_V1_0_GRAPH_H
-#define ANDROID_HARDWARE_TESTS_POINTER_V1_0_GRAPH_H
-
-#include <android/hardware/tests/pointer/1.0/IGraph.h>
-#include <hidl/Status.h>
-
-#include <hidl/MQDescriptor.h>
-namespace android {
-namespace hardware {
-namespace tests {
-namespace pointer {
-namespace V1_0 {
-namespace implementation {
-
-using ::android::hardware::tests::pointer::V1_0::IGraph;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::hidl_string;
-using ::android::sp;
-
-struct Graph : public IGraph {
- // Methods from ::android::hardware::tests::pointer::V1_0::IGraph follow.
- Return<void> passANode(const IGraph::Node& n) override;
- Return<void> passAGraph(const IGraph::Graph& g) override;
- Return<void> passTwoGraphs(::android::hardware::tests::pointer::V1_0::IGraph::Graph const* g1, ::android::hardware::tests::pointer::V1_0::IGraph::Graph const* g2) override;
- Return<void> giveAGraph(giveAGraph_cb _hidl_cb) override;
- Return<void> passAGamma(const IGraph::Gamma& c) override;
- Return<void> passASimpleRef(::android::hardware::tests::pointer::V1_0::IGraph::Alpha const* a) override;
- Return<void> passASimpleRefS(::android::hardware::tests::pointer::V1_0::IGraph::Theta const* s) override;
- Return<void> giveASimpleRef(giveASimpleRef_cb _hidl_cb) override;
- Return<int32_t> getErrors() override;
-private:
- std::vector<std::string> errors;
-
-};
-
-extern "C" IGraph* HIDL_FETCH_IGraph(const char* name);
-
-} // namespace implementation
-} // namespace V1_0
-} // namespace pointer
-} // namespace tests
-} // namespace hardware
-} // namespace android
-
-#endif // ANDROID_HARDWARE_TESTS_POINTER_V1_0_GRAPH_H
diff --git a/tests/pointer/1.0/default/Pointer.cpp b/tests/pointer/1.0/default/Pointer.cpp
deleted file mode 100644
index 52712d4..0000000
--- a/tests/pointer/1.0/default/Pointer.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-#define LOG_TAG "hidl_test"
-
-#include "Pointer.h"
-
-#include <log/log.h>
-
-namespace android {
-namespace hardware {
-namespace tests {
-namespace pointer {
-namespace V1_0 {
-namespace implementation {
-
-Return<int32_t> Pointer::getErrors() {
- if(!errors.empty()) {
- for(const auto& e : errors)
- ALOGW("SERVER(Pointer) error: %s", e.c_str());
- }
- return errors.size();
-}
-
-IPointer* HIDL_FETCH_IPointer(const char* /* name */) {
- return new Pointer();
-}
-
-} // namespace implementation
-} // namespace V1_0
-} // namespace pointer
-} // namespace tests
-} // namespace hardware
-} // namespace android
diff --git a/tests/pointer/1.0/default/Pointer.h b/tests/pointer/1.0/default/Pointer.h
deleted file mode 100644
index d6e3e48..0000000
--- a/tests/pointer/1.0/default/Pointer.h
+++ /dev/null
@@ -1,338 +0,0 @@
-#ifndef ANDROID_HARDWARE_TESTS_POINTER_V1_0_POINTER_H
-#define ANDROID_HARDWARE_TESTS_POINTER_V1_0_POINTER_H
-
-#include <android/hardware/tests/pointer/1.0/IPointer.h>
-#include <hidl/Status.h>
-
-#include <hidl/MQDescriptor.h>
-
-// TODO move to Pointer.cpp so that I won't have weird macros in headers
-#define PUSH_ERROR_IF(__cond__) if(__cond__) { errors.push_back(std::to_string(__LINE__) + ": " + #__cond__); }
-
-namespace android {
-namespace hardware {
-namespace tests {
-namespace pointer {
-namespace V1_0 {
-namespace implementation {
-
-using ::android::hardware::tests::pointer::V1_0::IPointer;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::hidl_string;
-using ::android::sp;
-
-struct Pointer : public IPointer {
-private:
- std::vector<std::string> errors;
-public:
- Return<int32_t> getErrors() override;
- Return<void> foo1(const IPointer::Sam& s, IPointer::Sam const* s_ptr) override {
- PUSH_ERROR_IF(!(&s == s_ptr));
- return Void();
- }
- Return<void> foo2(const IPointer::Sam& s, const IPointer::Ada& a) override {
- PUSH_ERROR_IF(!(&s == a.s_ptr));
- return Void();
- }
- Return<void> foo3(const IPointer::Sam& s, const IPointer::Ada& a, const IPointer::Bob& b) override {
- PUSH_ERROR_IF(!(&a == b.a_ptr && a.s_ptr == b.s_ptr && a.s_ptr == &s));
- return Void();
- }
- Return<void> foo4(IPointer::Sam const* s_ptr) override {
- PUSH_ERROR_IF(!(s_ptr->data == 500));
- return Void();
- }
- Return<void> foo5(const IPointer::Ada& a, const IPointer::Bob& b) override {
- PUSH_ERROR_IF(!(a.s_ptr == b.s_ptr && b.a_ptr == &a));
- return Void();
- }
- Return<void> foo6(IPointer::Ada const* a_ptr) override {
- PUSH_ERROR_IF(!(a_ptr->s_ptr->data == 500));
- return Void();
- }
- Return<void> foo7(IPointer::Ada const* a_ptr, IPointer::Bob const* b_ptr) override {
- PUSH_ERROR_IF(!(a_ptr->s_ptr == b_ptr->s_ptr && a_ptr == b_ptr->a_ptr && a_ptr->s_ptr->data == 500));
- return Void();
- }
- Return<void> foo8(const IPointer::Dom& d) override {
- const IPointer::Cin& c = d.c;
- PUSH_ERROR_IF(&c.a != c.b_ptr->a_ptr);
- PUSH_ERROR_IF(c.a.s_ptr != c.b_ptr->s_ptr);
- PUSH_ERROR_IF(c.a.s_ptr->data != 500);
- return Void();
- }
- Return<void> foo9(::android::hardware::hidl_string const* str_ref) override {
- PUSH_ERROR_IF(!(strcmp(str_ref->c_str(), "meowmeowmeow") == 0));
- return Void();
- }
- Return<void> foo10(const ::android::hardware::hidl_vec<IPointer::Sam const*>& s_ptr_vec) override {
- PUSH_ERROR_IF(s_ptr_vec[0]->data != 500);
- if(s_ptr_vec.size() != 5) {
- errors.push_back("foo10: s_ptr_vec.size() != 5");
- return Void();
- }
- for(size_t i = 0; i < s_ptr_vec.size(); i++)
- PUSH_ERROR_IF(s_ptr_vec[0] != s_ptr_vec[i]);
- return Void();
- }
- Return<void> foo11(::android::hardware::hidl_vec<IPointer::Sam> const* s_vec_ptr) override {
- if(s_vec_ptr->size() != 5) {
- errors.push_back("foo11: s_vec_ptr->size() != 5");
- return Void();
- }
- for(size_t i = 0; i < 5; i++)
- PUSH_ERROR_IF((*s_vec_ptr)[i].data != 500);
- return Void();
- }
- Return<void> foo12(hidl_array<IPointer::Sam, 5> const* s_array_ref) override {
- for(size_t i = 0; i < 5; ++i)
- PUSH_ERROR_IF((*s_array_ref)[i].data != 500);
- return Void();
- }
- Return<void> foo13(const hidl_array<IPointer::Sam const*, 5>& s_ref_array) override {
- PUSH_ERROR_IF(s_ref_array[0]->data != 500)
- for(size_t i = 0; i < 5; i++)
- PUSH_ERROR_IF(s_ref_array[i] != s_ref_array[0])
- return Void();
- }
- Return<void> foo14(IPointer::Sam const* const* const* s_3ptr) override {
- PUSH_ERROR_IF(!((***s_3ptr).data == 500))
- return Void();
- }
- Return<void> foo15(int32_t const* const* const* i_3ptr) override {
- PUSH_ERROR_IF(!((***i_3ptr) == 500))
- return Void();
- }
-
- Return<void> foo16(const IPointer::Ptr& p) override {
- PUSH_ERROR_IF((*p.array_ptr)[0].s_ptr->data != 500);
- for(size_t i = 0; i < 5; i++) PUSH_ERROR_IF((*p.array_ptr)[i].s_ptr != (*p.array_ptr)[0].s_ptr);
- PUSH_ERROR_IF(*(p.int_ptr) != 500);
- for(size_t i = 0; i < 5; i++) PUSH_ERROR_IF((*p.int_array_ptr)[i] != 500);
- for(size_t i = 0; i < 5; i++) PUSH_ERROR_IF(p.int_ptr_array[i] != p.int_ptr);
- PUSH_ERROR_IF(p.a_ptr_vec.size() != 5);
- PUSH_ERROR_IF(p.a_ptr_vec[0]->s_ptr->data != 500);
- for(size_t i = 0; i < 5; i++) PUSH_ERROR_IF(p.a_ptr_vec[i]->s_ptr != p.a_ptr_vec[0]->s_ptr);
- PUSH_ERROR_IF(strcmp(p.str_ref->c_str(), "meowmeowmeow") != 0);
- PUSH_ERROR_IF(p.a_vec_ptr->size() != 5);
- PUSH_ERROR_IF((*p.a_vec_ptr)[0].s_ptr->data != 500);
- for(size_t i = 0; i < 5; i++) PUSH_ERROR_IF((*p.a_vec_ptr)[i].s_ptr != (*p.a_vec_ptr)[0].s_ptr);
- return Void();
- };
- Return<void> foo17(IPointer::Ptr const* p) override {
- return foo16(*p);
- };
- Return<void> foo18(hidl_string const* str_ref, hidl_string const* str_ref2, const hidl_string& str) override {
- PUSH_ERROR_IF(&str != str_ref);
- PUSH_ERROR_IF(str_ref != str_ref2);
- PUSH_ERROR_IF(strcmp(str.c_str(), "meowmeowmeow") != 0)
- return Void();
- };
- Return<void> foo19(
- hidl_vec<IPointer::Ada> const* a_vec_ref,
- const hidl_vec<IPointer::Ada>& a_vec,
- hidl_vec<IPointer::Ada> const* a_vec_ref2) {
- PUSH_ERROR_IF(&a_vec != a_vec_ref);
- PUSH_ERROR_IF(a_vec_ref2 != a_vec_ref);
- PUSH_ERROR_IF(a_vec.size() != 5);
- PUSH_ERROR_IF(a_vec[0].s_ptr->data != 500);
- for(size_t i = 0; i < 5; i++)
- PUSH_ERROR_IF(a_vec[i].s_ptr != a_vec[0].s_ptr);
- return Void();
- };
-
- Return<void> foo20(const hidl_vec<IPointer::Sam const*>&) override {
- return Void();
- }
- Return<void> foo21(hidl_array<IPointer::Ada, 1, 2, 3> const* a_array_ptr) override {
- const hidl_array<IPointer::Ada, 1, 2, 3>& a_array = *a_array_ptr;
- PUSH_ERROR_IF(a_array[0][0][0].s_ptr->data != 500);
- for(size_t i = 0; i < 1; i++)
- for(size_t j = 0; j < 2; j++)
- for(size_t k = 0; k < 3; k++)
- PUSH_ERROR_IF(a_array[i][j][k].s_ptr != a_array[0][0][0].s_ptr);
- return Void();
- }
- Return<void> foo22(const hidl_array<IPointer::Ada const*, 1, 2, 3>& a_ptr_array) override {
- PUSH_ERROR_IF(a_ptr_array[0][0][0]->s_ptr->data != 500);
- for(size_t i = 0; i < 1; i++)
- for(size_t j = 0; j < 2; j++)
- for(size_t k = 0; k < 3; k++)
- PUSH_ERROR_IF(a_ptr_array[i][j][k] != a_ptr_array[0][0][0]);
- return Void();
- }
-
- IPointer::Sam *s;
- IPointer::Ada *a;
- IPointer::Bob *b;
- IPointer::Cin *c;
- IPointer::Dom *d;
-
- IPointer::Ptr p;
- hidl_array<IPointer::Ada, 5> a_array;
- int32_t someInt;
- hidl_array<int32_t, 5> someIntArray;
- hidl_string str;
- hidl_vec<IPointer::Ada> a_vec;
- Pointer() {
- d = new IPointer::Dom();
- s = new IPointer::Sam();
- b = new IPointer::Bob();
- c = &d->c;
- a = &c->a;
- b->s_ptr = a->s_ptr = s;
- b->a_ptr = a;
- c->b_ptr = b;
- s->data = 500;
-
- someInt = 500;
- for(size_t i = 0; i < 5; i++) someIntArray[i] = 500;
-
- for(size_t i = 0; i < 5; i++) a_array[i] = *a;
-
- for(size_t i = 0; i < 5; i++) p.ptr_array[i] = a;
- p.array_ptr = &a_array;
- p.int_ptr = &someInt;
- p.int_array_ptr = &someIntArray;
- for(size_t i = 0; i < 5; i++) p.int_ptr_array[i] = &someInt;
- p.a_ptr_vec.resize(5);
- for(size_t i = 0; i < 5; i++) p.a_ptr_vec[i] = a;
- str = "meowmeowmeow";
- p.str_ref = &str;
- a_vec.resize(5);
- for(size_t i = 0; i < 5; i++) a_vec[i].s_ptr = s;
- p.a_vec_ptr = &a_vec;
- }
- ~Pointer() {
- delete d; delete s; delete b;
- }
- Return<void> bar1(bar1_cb _cb) override {
- _cb(*s, s);
- return Void();
- }
- Return<void> bar2(bar2_cb _cb) override {
- _cb(*s, *a);
- return Void();
- }
- Return<void> bar3(bar3_cb _cb) override {
- _cb(*s, *a, *b);
- return Void();
- }
- Return<void> bar4(bar4_cb _cb) override {
- _cb(s);
- return Void();
- }
- Return<void> bar5(bar5_cb _cb) override {
- _cb(*a, *b);
- return Void();
- }
- Return<void> bar6(bar6_cb _cb) override {
- _cb(a);
- return Void();
- }
- Return<void> bar7(bar7_cb _cb) override {
- _cb(a, b);
- return Void();
- }
- Return<void> bar8(bar8_cb _cb) override {
- _cb(*d);
- return Void();
- }
- Return<void> bar9(bar9_cb _cb) override {
- _cb(&str);
- return Void();
- }
- Return<void> bar10(bar10_cb _cb) override {
- hidl_vec<const IPointer::Sam *> v; v.resize(5);
- for(size_t i = 0; i < 5; i++) v[i] = s;
- _cb(v);
- return Void();
- }
- Return<void> bar11(bar11_cb _cb) override {
- hidl_vec<IPointer::Sam> v; v.resize(5);
- for(size_t i = 0; i < 5; i++) v[i].data = 500;
- _cb(&v);
- return Void();
- }
- Return<void> bar12(bar12_cb _cb) override {
- hidl_array<IPointer::Sam, 5> array;
- for(size_t i = 0; i < 5; i++) array[i] = *s;
- _cb(&array);
- return Void();
- }
- Return<void> bar13(bar13_cb _cb) override {
- hidl_array<const IPointer::Sam *, 5> array;
- for(size_t i = 0; i < 5; i++) array[i] = s;
- _cb(array);
- return Void();
- }
- Return<void> bar14(bar14_cb _cb) override {
- IPointer::Sam const* p1 = s;
- IPointer::Sam const* const* p2 = &p1;
- _cb(&p2);
- return Void();
- }
- Return<void> bar15(bar15_cb _cb) override {
- int32_t const* p1 = &someInt;
- int32_t const* const* p2 = &p1;
- _cb(&p2);
- return Void();
- }
- Return<void> bar16(bar16_cb _cb) override {
- _cb(p);
- return Void();
- }
- Return<void> bar17(bar17_cb _cb) override {
- _cb(&p);
- return Void();
- }
- Return<void> bar18(bar18_cb _cb) override {
- _cb(&str, &str, str);
- return Void();
- }
- Return<void> bar19(bar19_cb _cb) override {
- _cb(&a_vec, a_vec, &a_vec);
- return Void();
- }
- Return<void> bar20(bar20_cb _cb) override {
- // 1026 == PARCEL_REF_CAP + 2.
- // 1026 means 1 writeBuffer and 1025 writeReferences. 1025 > PARCEL_REF_CAP.
- hidl_vec<const IPointer::Sam *> v; v.resize(1026);
- for(size_t i = 0; i < 1026; i++) v[i] = s;
- _cb(v);
- return Void();
- }
- Return<void> bar21(bar21_cb _cb) override {
- hidl_array<IPointer::Ada, 1, 2, 3> a_array;
- for(size_t i = 0; i < 1; i++)
- for(size_t j = 0; j < 2; j++)
- for(size_t k = 0; k < 3; k++)
- a_array[i][j][k] = *a;
- _cb(&a_array);
- return Void();
- }
- Return<void> bar22(bar22_cb _cb) override {
- hidl_array<const IPointer::Ada *, 1, 2, 3> a_ptr_array;
- for(size_t i = 0; i < 1; i++)
- for(size_t j = 0; j < 2; j++)
- for(size_t k = 0; k < 3; k++)
- a_ptr_array[i][j][k] = a;
- _cb(a_ptr_array);
- return Void();
- }
-};
-
-extern "C" IPointer* HIDL_FETCH_IPointer(const char* name);
-
-} // namespace implementation
-} // namespace V1_0
-} // namespace pointer
-} // namespace tests
-} // namespace hardware
-} // namespace android
-
-#undef PUSH_ERROR_IF
-
-#endif // ANDROID_HARDWARE_TESTS_POINTER_V1_0_POINTER_H
diff --git a/tests/pointer/1.0/default/lib/Android.bp b/tests/pointer/1.0/default/lib/Android.bp
deleted file mode 100644
index 180906b..0000000
--- a/tests/pointer/1.0/default/lib/Android.bp
+++ /dev/null
@@ -1,19 +0,0 @@
-cc_library {
- name: "libpointertest",
- defaults: ["hidl_defaults"],
- srcs: [
- "PointerHelper.cpp"
- ],
-
- shared_libs: [
- "libbase",
- "libhidlbase",
- "libhidltransport",
- "liblog",
- ],
- static_libs: ["android.hardware.tests.pointer@1.0"],
-
- local_include_dirs: ["include/hidl-test"],
- export_include_dirs: ["include"],
-
-}
diff --git a/tests/pointer/1.0/default/lib/PointerHelper.cpp b/tests/pointer/1.0/default/lib/PointerHelper.cpp
deleted file mode 100644
index 0a64cc3..0000000
--- a/tests/pointer/1.0/default/lib/PointerHelper.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-#define LOG_TAG "hidl_test"
-
-#include <log/log.h>
-
-#include "PointerHelper.h"
-
-namespace android {
-
-void simpleGraph(IGraph::Graph& g) {
- g.nodes.resize(2);
- g.edges.resize(1);
- g.nodes[0].data = 10;
- g.nodes[1].data = 20;
- g.edges[0].left = &g.nodes[0];
- g.edges[0].right = &g.nodes[1];
-}
-
-bool isSimpleGraph(const IGraph::Graph &g) {
- if(g.nodes.size() != 2) return false;
- if(g.edges.size() != 1) return false;
- if(g.nodes[0].data != 10) return false;
- if(g.nodes[1].data != 20) return false;
- if(g.edges[0].left != &g.nodes[0]) return false;
- if(g.edges[0].right != &g.nodes[1]) return false;
- return true;
-}
-
-void logSimpleGraph(const char *prefix, const IGraph::Graph& g) {
- ALOGI("%s Graph %p, %d nodes, %d edges", prefix, &g, (int)g.nodes.size(), (int)g.edges.size());
- std::ostringstream os;
- for(size_t i = 0; i < g.nodes.size(); i++)
- os << &g.nodes[i] << " = " << g.nodes[i].data << ", ";
- ALOGI("%s Nodes: [%s]", prefix, os.str().c_str());
- os.str("");
- os.clear();
- for(size_t i = 0; i < g.edges.size(); i++)
- os << g.edges[i].left << " -> " << g.edges[i].right << ", ";
- ALOGI("%s Edges: [%s]", prefix, os.str().c_str());
-}
-} // namespace android
diff --git a/tests/pointer/1.0/default/lib/include/hidl-test/PointerHelper.h b/tests/pointer/1.0/default/lib/include/hidl-test/PointerHelper.h
deleted file mode 100644
index cd2edcb..0000000
--- a/tests/pointer/1.0/default/lib/include/hidl-test/PointerHelper.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef ANDROID_HIDL_TEST_POINTER_HELPER_H
-#define ANDROID_HIDL_TEST_POINTER_HELPER_H
-
-#include <android/hardware/tests/pointer/1.0/IGraph.h>
-
-using ::android::hardware::tests::pointer::V1_0::IGraph;
-
-namespace android {
-
-void simpleGraph(IGraph::Graph& g);
-bool isSimpleGraph(const IGraph::Graph &g);
-void logSimpleGraph(const char *prefix, const IGraph::Graph& g);
-
-} // namespace android
-#endif // ANDROID_HIDL_TEST_POINTER_HELPER_H
diff --git a/tests/safeunion/1.0/Android.bp b/tests/safeunion/1.0/Android.bp
index 87edd53..2937832 100644
--- a/tests/safeunion/1.0/Android.bp
+++ b/tests/safeunion/1.0/Android.bp
@@ -13,4 +13,3 @@
],
gen_java: true,
}
-
diff --git a/tests/safeunion/cpp/1.0/Android.bp b/tests/safeunion/cpp/1.0/Android.bp
index 1111719..221643a 100644
--- a/tests/safeunion/cpp/1.0/Android.bp
+++ b/tests/safeunion/cpp/1.0/Android.bp
@@ -11,4 +11,3 @@
],
gen_java: false,
}
-
diff --git a/tests/trie/1.0/Android.bp b/tests/trie/1.0/Android.bp
index 0795f66..5a33aea 100644
--- a/tests/trie/1.0/Android.bp
+++ b/tests/trie/1.0/Android.bp
@@ -12,4 +12,3 @@
],
gen_java: false,
}
-
diff --git a/tests/trie/1.0/types.hal b/tests/trie/1.0/types.hal
index c626909..889d3b2 100644
--- a/tests/trie/1.0/types.hal
+++ b/tests/trie/1.0/types.hal
@@ -29,16 +29,16 @@
// Some forward reference tests.
struct A {
- ref<B> b;
+ vec<B> b;
};
struct B {
- ref<A> a;
+ vec<A> a;
};
-typedef ref<S> refS;
+typedef vec<S> vecS;
struct S {
- refS f;
+ vecS f;
};
enum E2 : E1 {
diff --git a/tetheroffload/config/1.0/Android.bp b/tetheroffload/config/1.0/Android.bp
index f20d77c..321224a 100644
--- a/tetheroffload/config/1.0/Android.bp
+++ b/tetheroffload/config/1.0/Android.bp
@@ -14,4 +14,3 @@
],
gen_java: true,
}
-
diff --git a/tetheroffload/control/1.0/Android.bp b/tetheroffload/control/1.0/Android.bp
index dc2487b..f894448 100644
--- a/tetheroffload/control/1.0/Android.bp
+++ b/tetheroffload/control/1.0/Android.bp
@@ -16,4 +16,3 @@
],
gen_java: true,
}
-
diff --git a/thermal/1.0/Android.bp b/thermal/1.0/Android.bp
index 8428977..de168d8 100644
--- a/thermal/1.0/Android.bp
+++ b/thermal/1.0/Android.bp
@@ -16,4 +16,3 @@
gen_java: true,
gen_java_constants: true,
}
-
diff --git a/thermal/1.0/default/android.hardware.thermal@1.0-service.rc b/thermal/1.0/default/android.hardware.thermal@1.0-service.rc
index cf9bdee..ba3ce82 100644
--- a/thermal/1.0/default/android.hardware.thermal@1.0-service.rc
+++ b/thermal/1.0/default/android.hardware.thermal@1.0-service.rc
@@ -1,4 +1,5 @@
service vendor.thermal-hal-1-0 /vendor/bin/hw/android.hardware.thermal@1.0-service
+ interface android.hardware.thermal@1.0::IThermal default
class hal
user system
group system
diff --git a/thermal/1.1/Android.bp b/thermal/1.1/Android.bp
index 8c0f1f9..f38ed3b 100644
--- a/thermal/1.1/Android.bp
+++ b/thermal/1.1/Android.bp
@@ -16,4 +16,3 @@
],
gen_java: true,
}
-
diff --git a/thermal/2.0/Android.bp b/thermal/2.0/Android.bp
index af23ee3..1b76f37 100644
--- a/thermal/2.0/Android.bp
+++ b/thermal/2.0/Android.bp
@@ -17,4 +17,3 @@
],
gen_java: true,
}
-
diff --git a/thermal/2.0/default/android.hardware.thermal@2.0-service.rc b/thermal/2.0/default/android.hardware.thermal@2.0-service.rc
index 046c771..4ff8bd6 100644
--- a/thermal/2.0/default/android.hardware.thermal@2.0-service.rc
+++ b/thermal/2.0/default/android.hardware.thermal@2.0-service.rc
@@ -1,4 +1,5 @@
service vendor.thermal-hal-2-0-mock /vendor/bin/hw/android.hardware.thermal@2.0-service.mock
+ interface android.hardware.thermal@1.0::IThermal default
interface android.hardware.thermal@2.0::IThermal default
class hal
user system
diff --git a/tv/cec/1.0/Android.bp b/tv/cec/1.0/Android.bp
index 7626dc0..d41a7e7 100644
--- a/tv/cec/1.0/Android.bp
+++ b/tv/cec/1.0/Android.bp
@@ -16,4 +16,3 @@
],
gen_java: true,
}
-
diff --git a/tv/cec/1.0/default/android.hardware.tv.cec@1.0-service.rc b/tv/cec/1.0/default/android.hardware.tv.cec@1.0-service.rc
index 8595099..6d25229 100644
--- a/tv/cec/1.0/default/android.hardware.tv.cec@1.0-service.rc
+++ b/tv/cec/1.0/default/android.hardware.tv.cec@1.0-service.rc
@@ -1,4 +1,5 @@
service vendor.cec-hal-1-0 /vendor/bin/hw/android.hardware.tv.cec@1.0-service
+ interface android.hardware.tv.cec@1.0::IHdmiCec default
class hal
user system
group system
diff --git a/tv/cec/2.0/Android.bp b/tv/cec/2.0/Android.bp
index 5a67fa5..61450ac 100644
--- a/tv/cec/2.0/Android.bp
+++ b/tv/cec/2.0/Android.bp
@@ -17,4 +17,3 @@
],
gen_java: true,
}
-
diff --git a/tv/input/1.0/Android.bp b/tv/input/1.0/Android.bp
index a6c1959..7288558 100644
--- a/tv/input/1.0/Android.bp
+++ b/tv/input/1.0/Android.bp
@@ -18,4 +18,3 @@
gen_java: false,
gen_java_constants: true,
}
-
diff --git a/tv/input/1.0/default/android.hardware.tv.input@1.0-service.rc b/tv/input/1.0/default/android.hardware.tv.input@1.0-service.rc
index 972c654..6cb9a43 100644
--- a/tv/input/1.0/default/android.hardware.tv.input@1.0-service.rc
+++ b/tv/input/1.0/default/android.hardware.tv.input@1.0-service.rc
@@ -1,4 +1,5 @@
service vendor.tv-input-1-0 /vendor/bin/hw/android.hardware.tv.input@1.0-service
+ interface android.hardware.tv.input@1.0::ITvInput default
class hal
user system
group system
diff --git a/usb/1.0/Android.bp b/usb/1.0/Android.bp
index a00b671..c0e883f 100644
--- a/usb/1.0/Android.bp
+++ b/usb/1.0/Android.bp
@@ -17,4 +17,3 @@
gen_java: true,
gen_java_constants: true,
}
-
diff --git a/usb/1.0/default/android.hardware.usb@1.0-service.rc b/usb/1.0/default/android.hardware.usb@1.0-service.rc
index b7a0c63..3c44d21 100644
--- a/usb/1.0/default/android.hardware.usb@1.0-service.rc
+++ b/usb/1.0/default/android.hardware.usb@1.0-service.rc
@@ -1,4 +1,5 @@
service vendor.usb-hal-1-0 /vendor/bin/hw/android.hardware.usb@1.0-service
+ interface android.hardware.usb@1.0::IUsb default
class hal
user system
group system
diff --git a/usb/1.1/Android.bp b/usb/1.1/Android.bp
index fb2cc4e..6f2abae 100644
--- a/usb/1.1/Android.bp
+++ b/usb/1.1/Android.bp
@@ -18,4 +18,3 @@
gen_java: true,
gen_java_constants: true,
}
-
diff --git a/usb/1.2/Android.bp b/usb/1.2/Android.bp
index 5206754..b3ba81f 100644
--- a/usb/1.2/Android.bp
+++ b/usb/1.2/Android.bp
@@ -19,4 +19,3 @@
gen_java: true,
gen_java_constants: true,
}
-
diff --git a/usb/gadget/1.0/Android.bp b/usb/gadget/1.0/Android.bp
index 7ee432b..4921abf 100644
--- a/usb/gadget/1.0/Android.bp
+++ b/usb/gadget/1.0/Android.bp
@@ -16,4 +16,3 @@
],
gen_java: true,
}
-
diff --git a/vibrator/1.0/Android.bp b/vibrator/1.0/Android.bp
index acc97d4..792e130 100644
--- a/vibrator/1.0/Android.bp
+++ b/vibrator/1.0/Android.bp
@@ -16,4 +16,3 @@
gen_java: true,
gen_java_constants: true,
}
-
diff --git a/vibrator/1.0/default/android.hardware.vibrator@1.0-service.rc b/vibrator/1.0/default/android.hardware.vibrator@1.0-service.rc
index 1123eab..1bd5c10 100644
--- a/vibrator/1.0/default/android.hardware.vibrator@1.0-service.rc
+++ b/vibrator/1.0/default/android.hardware.vibrator@1.0-service.rc
@@ -1,4 +1,5 @@
service vendor.vibrator-1-0 /vendor/bin/hw/android.hardware.vibrator@1.0-service
+ interface android.hardware.vibrator@1.0::IVibrator default
class hal
user system
group system
diff --git a/vibrator/1.1/Android.bp b/vibrator/1.1/Android.bp
index 2055e5a..0d04a87 100644
--- a/vibrator/1.1/Android.bp
+++ b/vibrator/1.1/Android.bp
@@ -17,4 +17,3 @@
gen_java: true,
gen_java_constants: true,
}
-
diff --git a/vibrator/1.2/Android.bp b/vibrator/1.2/Android.bp
index 481adee..290a0cf 100644
--- a/vibrator/1.2/Android.bp
+++ b/vibrator/1.2/Android.bp
@@ -17,4 +17,3 @@
],
gen_java: true,
}
-
diff --git a/vibrator/1.3/Android.bp b/vibrator/1.3/Android.bp
index a2ff784..357ea9a 100644
--- a/vibrator/1.3/Android.bp
+++ b/vibrator/1.3/Android.bp
@@ -7,8 +7,8 @@
enabled: true,
},
srcs: [
- "IVibrator.hal",
"types.hal",
+ "IVibrator.hal",
],
interfaces: [
"android.hardware.vibrator@1.0",
@@ -18,4 +18,3 @@
],
gen_java: true,
}
-
diff --git a/vr/1.0/Android.bp b/vr/1.0/Android.bp
index ca47a6e..f91f874 100644
--- a/vr/1.0/Android.bp
+++ b/vr/1.0/Android.bp
@@ -14,4 +14,3 @@
],
gen_java: true,
}
-
diff --git a/vr/1.0/default/android.hardware.vr@1.0-service.rc b/vr/1.0/default/android.hardware.vr@1.0-service.rc
index fc4934c..5486674 100644
--- a/vr/1.0/default/android.hardware.vr@1.0-service.rc
+++ b/vr/1.0/default/android.hardware.vr@1.0-service.rc
@@ -1,4 +1,5 @@
service vendor.vr-1-0 /vendor/bin/hw/android.hardware.vr@1.0-service
+ interface android.hardware.vr@1.0::IVr default
class hal
user system
group system
diff --git a/weaver/1.0/Android.bp b/weaver/1.0/Android.bp
index 7f93b10..7d5b8fe 100644
--- a/weaver/1.0/Android.bp
+++ b/weaver/1.0/Android.bp
@@ -15,4 +15,3 @@
],
gen_java: true,
}
-
diff --git a/wifi/1.0/Android.bp b/wifi/1.0/Android.bp
index c5ee1bb..958ff3f 100644
--- a/wifi/1.0/Android.bp
+++ b/wifi/1.0/Android.bp
@@ -28,4 +28,3 @@
gen_java: true,
gen_java_constants: true,
}
-
diff --git a/wifi/1.1/Android.bp b/wifi/1.1/Android.bp
index a4499c8..a34ac44 100644
--- a/wifi/1.1/Android.bp
+++ b/wifi/1.1/Android.bp
@@ -16,4 +16,3 @@
],
gen_java: true,
}
-
diff --git a/wifi/1.2/Android.bp b/wifi/1.2/Android.bp
index 1863eaf..c28d09b 100644
--- a/wifi/1.2/Android.bp
+++ b/wifi/1.2/Android.bp
@@ -22,4 +22,3 @@
],
gen_java: true,
}
-
diff --git a/wifi/1.3/Android.bp b/wifi/1.3/Android.bp
index 401c7a6..3719c2b 100644
--- a/wifi/1.3/Android.bp
+++ b/wifi/1.3/Android.bp
@@ -20,4 +20,3 @@
],
gen_java: true,
}
-
diff --git a/wifi/1.3/default/android.hardware.wifi@1.0-service.rc b/wifi/1.3/default/android.hardware.wifi@1.0-service.rc
index cf849d0..2317bac 100644
--- a/wifi/1.3/default/android.hardware.wifi@1.0-service.rc
+++ b/wifi/1.3/default/android.hardware.wifi@1.0-service.rc
@@ -1,4 +1,7 @@
service vendor.wifi_hal_legacy /vendor/bin/hw/android.hardware.wifi@1.0-service
+ interface android.hardware.wifi@1.0::IWifi default
+ interface android.hardware.wifi@1.1::IWifi default
+ interface android.hardware.wifi@1.2::IWifi default
class hal
capabilities NET_ADMIN NET_RAW SYS_MODULE
user wifi
diff --git a/wifi/hostapd/1.0/Android.bp b/wifi/hostapd/1.0/Android.bp
index 9ee976e..cce1182 100644
--- a/wifi/hostapd/1.0/Android.bp
+++ b/wifi/hostapd/1.0/Android.bp
@@ -16,4 +16,3 @@
],
gen_java: true,
}
-
diff --git a/wifi/hostapd/1.1/Android.bp b/wifi/hostapd/1.1/Android.bp
index d4170b6..64fbc93 100644
--- a/wifi/hostapd/1.1/Android.bp
+++ b/wifi/hostapd/1.1/Android.bp
@@ -17,4 +17,3 @@
],
gen_java: true,
}
-
diff --git a/wifi/offload/1.0/Android.bp b/wifi/offload/1.0/Android.bp
index 1a9ae73..110bb70 100644
--- a/wifi/offload/1.0/Android.bp
+++ b/wifi/offload/1.0/Android.bp
@@ -16,4 +16,3 @@
],
gen_java: false,
}
-
diff --git a/wifi/supplicant/1.0/Android.bp b/wifi/supplicant/1.0/Android.bp
index c99706d..d91512f 100644
--- a/wifi/supplicant/1.0/Android.bp
+++ b/wifi/supplicant/1.0/Android.bp
@@ -26,4 +26,3 @@
],
gen_java: true,
}
-
diff --git a/wifi/supplicant/1.1/Android.bp b/wifi/supplicant/1.1/Android.bp
index 832d1ad..6d940d1 100644
--- a/wifi/supplicant/1.1/Android.bp
+++ b/wifi/supplicant/1.1/Android.bp
@@ -18,4 +18,3 @@
],
gen_java: true,
}
-
diff --git a/wifi/supplicant/1.2/Android.bp b/wifi/supplicant/1.2/Android.bp
index c685022..185d2b8 100644
--- a/wifi/supplicant/1.2/Android.bp
+++ b/wifi/supplicant/1.2/Android.bp
@@ -21,4 +21,3 @@
],
gen_java: true,
}
-