Make VtsHalNeuralnetworksTargetTest run on the host

This change adds a host build of VtsHalNeuralnetworksTargetTest. In the
existing device build of VtsHalNeuralnetworksTargetTest, the drivers run
out-of-process. In the host build of VtsHalNeuralnetworkaTargetTest, the
driver runs in-process.

The in-process driver that runs on the host is the canonical sample
driver (which is just the CPU "driver", located in
packages/modules/NeuralNetworks/driver/sample) adapted to an AIDL
interface (by the adapter code in
hardware/interfaces/neuralnetworks/utils/adapter/aidl).

Bug: N/A
Test: mma
Test: VtsHalNeuralnetworksTargetTest on host
Change-Id: Ia30dd3a7db8e0592b9f13d69c9831f8ffe10c371
diff --git a/neuralnetworks/aidl/vts/functional/Android.bp b/neuralnetworks/aidl/vts/functional/Android.bp
index 1ed15b8..356cdb0 100644
--- a/neuralnetworks/aidl/vts/functional/Android.bp
+++ b/neuralnetworks/aidl/vts/functional/Android.bp
@@ -30,6 +30,7 @@
         "neuralnetworks_vts_functional_defaults",
         "use_libaidlvintf_gtest_helper_static",
     ],
+    host_supported: true,
     srcs: [
         "BasicTests.cpp",
         "Callbacks.cpp",
@@ -46,18 +47,11 @@
     ],
     shared_libs: [
         "libbinder_ndk",
-        "libnativewindow",
-        "libvndksupport",
     ],
     static_libs: [
-        "android.hidl.allocator@1.0",
-        "android.hidl.memory@1.0",
         "libaidlcommonsupport",
-        "libgmock",
-        "libhidlmemory",
         "libneuralnetworks_common",
         "libneuralnetworks_generated_test_harness",
-        "libsync",
     ],
     whole_static_libs: [
         "neuralnetworks_generated_AIDL_V3_example",
@@ -73,6 +67,34 @@
     ],
     test_suites: [
         "general-tests",
-        "vts",
     ],
+    target: {
+        android: {
+            shared_libs: [
+                "libnativewindow",
+                "libvndksupport",
+            ],
+            static_libs: [
+                "libsync",
+            ],
+            test_suites: [
+                "vts",
+            ],
+            test_config: "AndroidTestDevice.xml",
+        },
+        host: {
+            shared_libs: [
+                "libtextclassifier_hash",
+            ],
+            static_libs: [
+                "neuralnetworks_canonical_sample_driver",
+                "neuralnetworks_utils_hal_adapter_aidl",
+            ],
+            exclude_static_libs: [
+                "VtsHalHidlTestUtils",
+                "libaidlvintf_gtest_helper",
+            ],
+            test_config: "AndroidTestHost.xml",
+        },
+    },
 }
diff --git a/neuralnetworks/aidl/vts/functional/AndroidTest.xml b/neuralnetworks/aidl/vts/functional/AndroidTestDevice.xml
similarity index 100%
rename from neuralnetworks/aidl/vts/functional/AndroidTest.xml
rename to neuralnetworks/aidl/vts/functional/AndroidTestDevice.xml
diff --git a/neuralnetworks/aidl/vts/functional/AndroidTestHost.xml b/neuralnetworks/aidl/vts/functional/AndroidTestHost.xml
new file mode 100644
index 0000000..7372a31
--- /dev/null
+++ b/neuralnetworks/aidl/vts/functional/AndroidTestHost.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2022 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Runs VtsHalNeuralnetworksTargetTest.">
+    <test class="com.android.tradefed.testtype.HostGTest" >
+        <option name="module-name" value="VtsHalNeuralnetworksTargetTest" />
+        <option name="native-test-timeout" value="15m" />
+    </test>
+</configuration>
+
diff --git a/neuralnetworks/aidl/vts/functional/CompilationCachingTests.cpp b/neuralnetworks/aidl/vts/functional/CompilationCachingTests.cpp
index 77208aa..7451f7e 100644
--- a/neuralnetworks/aidl/vts/functional/CompilationCachingTests.cpp
+++ b/neuralnetworks/aidl/vts/functional/CompilationCachingTests.cpp
@@ -23,7 +23,6 @@
 #include <fcntl.h>
 #include <ftw.h>
 #include <gtest/gtest.h>
-#include <hidlmemory/mapping.h>
 #include <unistd.h>
 
 #include <cstdio>
@@ -34,7 +33,6 @@
 
 #include "Callbacks.h"
 #include "GeneratedTestHarness.h"
-#include "MemoryUtils.h"
 #include "TestHarness.h"
 #include "Utils.h"
 #include "VtsHalNeuralnetworks.h"
@@ -229,7 +227,11 @@
 
         // Create cache directory. The cache directory and a temporary cache file is always created
         // to test the behavior of prepareModelFromCache, even when caching is not supported.
+#ifdef __ANDROID__
         char cacheDirTemp[] = "/data/local/tmp/TestCompilationCachingXXXXXX";
+#else   // __ANDROID__
+        char cacheDirTemp[] = "/tmp/TestCompilationCachingXXXXXX";
+#endif  // __ANDROID__
         char* cacheDir = mkdtemp(cacheDirTemp);
         ASSERT_NE(cacheDir, nullptr);
         mCacheDir = cacheDir;
diff --git a/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp
index 8c8a87a..40f6cd1 100644
--- a/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp
+++ b/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp
@@ -20,7 +20,6 @@
 #include <aidl/android/hardware/neuralnetworks/RequestMemoryPool.h>
 #include <android-base/logging.h>
 #include <android/binder_auto_utils.h>
-#include <android/sync.h>
 #include <gtest/gtest.h>
 
 #include <algorithm>
@@ -30,7 +29,6 @@
 #include <numeric>
 #include <vector>
 
-#include <MemoryUtils.h>
 #include <android/binder_status.h>
 #include <nnapi/Result.h>
 #include <nnapi/SharedMemory.h>
@@ -43,6 +41,10 @@
 #include "Utils.h"
 #include "VtsHalNeuralnetworks.h"
 
+#ifdef __ANDROID__
+#include <android/sync.h>
+#endif  // __ANDROID__
+
 namespace aidl::android::hardware::neuralnetworks::vts::functional {
 
 namespace nn = ::android::nn;
@@ -281,10 +283,14 @@
 }  // namespace
 
 void waitForSyncFence(int syncFd) {
-    constexpr int kInfiniteTimeout = -1;
     ASSERT_GT(syncFd, 0);
+#ifdef __ANDROID__
+    constexpr int kInfiniteTimeout = -1;
     int r = sync_wait(syncFd, kInfiniteTimeout);
     ASSERT_GE(r, 0);
+#else   // __ANDROID__
+    LOG(FATAL) << "waitForSyncFence not supported on host";
+#endif  // __ANDROID__
 }
 
 Model createModel(const TestModel& testModel) {
@@ -895,7 +901,11 @@
             outputTypesList = {OutputType::FULLY_SPECIFIED};
             measureTimingList = {false};
             executorList = {Executor::SYNC, Executor::BURST, Executor::FENCED};
+#ifdef __ANDROID__
             memoryTypeList = {MemoryType::BLOB_AHWB, MemoryType::DEVICE};
+#else   // __ANDROID__
+            memoryTypeList = {MemoryType::DEVICE};  // BLOB_AHWB is not supported on the host.
+#endif  // __ANDROID__
         } break;
         case TestKind::FENCED_COMPUTE: {
             outputTypesList = {OutputType::FULLY_SPECIFIED};
diff --git a/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp b/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp
index 97760ae..f8341b1 100644
--- a/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp
+++ b/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "neuralnetworks_aidl_hal_test"
 
 #include <aidl/android/hardware/graphics/common/PixelFormat.h>
+#include <aidl/android/hardware/neuralnetworks/IPreparedModel.h>
 #include <android-base/logging.h>
 #include <android/binder_auto_utils.h>
 #include <android/binder_interface_utils.h>
@@ -33,7 +34,6 @@
 
 #include "Callbacks.h"
 #include "GeneratedTestHarness.h"
-#include "MemoryUtils.h"
 #include "Utils.h"
 #include "VtsHalNeuralnetworks.h"
 
@@ -191,7 +191,7 @@
 }
 
 // A placeholder invalid IPreparedModel class for MemoryDomainAllocateTest.InvalidPreparedModel
-class InvalidPreparedModel : public BnPreparedModel {
+class InvalidPreparedModel final : public IPreparedModel {
   public:
     ndk::ScopedAStatus executeSynchronously(const Request&, bool, int64_t, int64_t,
                                             ExecutionResult*) override {
@@ -225,6 +225,16 @@
         return ndk::ScopedAStatus::fromServiceSpecificError(
                 static_cast<int32_t>(ErrorStatus::GENERAL_FAILURE));
     }
+    ndk::ScopedAStatus getInterfaceVersion(int32_t* /*interfaceVersion*/) {
+        return ndk::ScopedAStatus::fromServiceSpecificError(
+                static_cast<int32_t>(ErrorStatus::GENERAL_FAILURE));
+    }
+    ndk::ScopedAStatus getInterfaceHash(std::string* /*interfaceHash*/) {
+        return ndk::ScopedAStatus::fromServiceSpecificError(
+                static_cast<int32_t>(ErrorStatus::GENERAL_FAILURE));
+    }
+    ndk::SpAIBinder asBinder() override { return ::ndk::SpAIBinder{}; }
+    bool isRemote() override { return true; }
 };
 
 template <typename... Args>
diff --git a/neuralnetworks/aidl/vts/functional/Utils.cpp b/neuralnetworks/aidl/vts/functional/Utils.cpp
index efd5bca..1bc76f2 100644
--- a/neuralnetworks/aidl/vts/functional/Utils.cpp
+++ b/neuralnetworks/aidl/vts/functional/Utils.cpp
@@ -21,18 +21,20 @@
 #include <aidl/android/hardware/neuralnetworks/OperandType.h>
 #include <android-base/logging.h>
 #include <android/binder_status.h>
-#include <android/hardware_buffer.h>
 
 #include <sys/mman.h>
 #include <iostream>
 #include <limits>
 #include <numeric>
 
-#include <MemoryUtils.h>
 #include <nnapi/SharedMemory.h>
 #include <nnapi/hal/aidl/Conversions.h>
 #include <nnapi/hal/aidl/Utils.h>
 
+#ifdef __ANDROID__
+#include <android/hardware_buffer.h>
+#endif  // __ANDROID__
+
 namespace aidl::android::hardware::neuralnetworks {
 
 using test_helper::TestBuffer;
@@ -140,7 +142,8 @@
     return ahwb->mIsValid ? std::move(ahwb) : nullptr;
 }
 
-void TestBlobAHWB::initialize(uint32_t size) {
+void TestBlobAHWB::initialize([[maybe_unused]] uint32_t size) {
+#ifdef __ANDROID__
     mIsValid = false;
     ASSERT_GT(size, 0);
     const auto usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN;
@@ -164,6 +167,9 @@
     mAidlMemory = utils::convert(mMemory).value();
 
     mIsValid = true;
+#else   // __ANDROID__
+    LOG(FATAL) << "TestBlobAHWB::initialize not supported on host";
+#endif  // __ANDROID__
 }
 
 std::string gtestCompliantName(std::string name) {
diff --git a/neuralnetworks/aidl/vts/functional/Utils.h b/neuralnetworks/aidl/vts/functional/Utils.h
index 0db3f8c..4e0a4aa 100644
--- a/neuralnetworks/aidl/vts/functional/Utils.h
+++ b/neuralnetworks/aidl/vts/functional/Utils.h
@@ -18,7 +18,6 @@
 #define ANDROID_HARDWARE_NEURALNETWORKS_AIDL_UTILS_H
 
 #include <android-base/logging.h>
-#include <android/hardware_buffer.h>
 #include <gtest/gtest.h>
 
 #include <algorithm>
diff --git a/neuralnetworks/aidl/vts/functional/VtsHalNeuralnetworks.cpp b/neuralnetworks/aidl/vts/functional/VtsHalNeuralnetworks.cpp
index ad93e6d..51b4805 100644
--- a/neuralnetworks/aidl/vts/functional/VtsHalNeuralnetworks.cpp
+++ b/neuralnetworks/aidl/vts/functional/VtsHalNeuralnetworks.cpp
@@ -15,6 +15,7 @@
  */
 
 #define LOG_TAG "neuralnetworks_aidl_hal_test"
+
 #include "VtsHalNeuralnetworks.h"
 
 #include <android-base/logging.h>
@@ -28,13 +29,19 @@
 #include <utility>
 
 #include <TestHarness.h>
-#include <aidl/Vintf.h>
 #include <nnapi/hal/aidl/Conversions.h>
 
 #include "Callbacks.h"
 #include "GeneratedTestHarness.h"
 #include "Utils.h"
 
+#ifdef __ANDROID__
+#include <aidl/Vintf.h>
+#else  // __ANDROID__
+#include <CanonicalDevice.h>
+#include <nnapi/hal/aidl/Adapter.h>
+#endif  // __ANDROID__
+
 namespace aidl::android::hardware::neuralnetworks::vts::functional {
 
 using implementation::PreparedModelCallback;
@@ -111,6 +118,7 @@
     ASSERT_TRUE(deviceIsResponsive);
 }
 
+#ifdef __ANDROID__
 static NamedDevice makeNamedDevice(const std::string& name) {
     ndk::SpAIBinder binder(AServiceManager_waitForService(name.c_str()));
     return {name, IDevice::fromBinder(binder)};
@@ -127,6 +135,14 @@
     std::transform(names.begin(), names.end(), std::back_inserter(namedDevices), makeNamedDevice);
     return namedDevices;
 }
+#else   // __ANDROID__
+static std::vector<NamedDevice> getNamedDevicesImpl() {
+    const std::string name = "nnapi-sample";
+    auto device = std::make_shared<const ::android::nn::sample::Device>(name);
+    auto aidlDevice = adapter::adapt(device);
+    return {{name, aidlDevice}};
+}
+#endif  // __ANDROID__
 
 const std::vector<NamedDevice>& getNamedDevices() {
     const static std::vector<NamedDevice> devices = getNamedDevicesImpl();