Merge "Clamp NNAPI HAL Version to runtime version -- hal" am: b66f1308ac

Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/1985406

Change-Id: Ifebccd1297cef08bdc1974eebea11bc7712a7061
diff --git a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Service.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Service.h
index cb6ff4b..f229165 100644
--- a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Service.h
+++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Service.h
@@ -25,7 +25,8 @@
 
 namespace aidl::android::hardware::neuralnetworks::utils {
 
-::android::nn::GeneralResult<::android::nn::SharedDevice> getDevice(const std::string& name);
+::android::nn::GeneralResult<::android::nn::SharedDevice> getDevice(
+        const std::string& name, ::android::nn::Version::Level maxFeatureLevelAllowed);
 
 }  // namespace aidl::android::hardware::neuralnetworks::utils
 
diff --git a/neuralnetworks/aidl/utils/src/Service.cpp b/neuralnetworks/aidl/utils/src/Service.cpp
index e48593c..24fbb53 100644
--- a/neuralnetworks/aidl/utils/src/Service.cpp
+++ b/neuralnetworks/aidl/utils/src/Service.cpp
@@ -55,11 +55,12 @@
 
 }  // namespace
 
-nn::GeneralResult<nn::SharedDevice> getDevice(const std::string& instanceName) {
+nn::GeneralResult<nn::SharedDevice> getDevice(
+        const std::string& instanceName, ::android::nn::Version::Level maxFeatureLevelAllowed) {
     auto fullName = std::string(IDevice::descriptor) + "/" + instanceName;
     hal::utils::ResilientDevice::Factory makeDevice =
-            [instanceName,
-             name = std::move(fullName)](bool blocking) -> nn::GeneralResult<nn::SharedDevice> {
+            [instanceName, name = std::move(fullName),
+             maxFeatureLevelAllowed](bool blocking) -> nn::GeneralResult<nn::SharedDevice> {
         std::add_pointer_t<AIBinder*(const char*)> getService;
         if (blocking) {
             if (__builtin_available(android __NNAPI_AIDL_MIN_ANDROID_API__, *)) {
@@ -79,7 +80,8 @@
                    << " returned nullptr";
         }
         ABinderProcess_startThreadPool();
-        const auto featureLevel = NN_TRY(getAidlServiceFeatureLevel(service.get()));
+        auto featureLevel = NN_TRY(getAidlServiceFeatureLevel(service.get()));
+        featureLevel.level = std::min(featureLevel.level, maxFeatureLevelAllowed);
         return Device::create(instanceName, std::move(service), featureLevel);
     };
 
diff --git a/neuralnetworks/utils/service/include/nnapi/hal/Service.h b/neuralnetworks/utils/service/include/nnapi/hal/Service.h
index 2fd5237..e8b9c10 100644
--- a/neuralnetworks/utils/service/include/nnapi/hal/Service.h
+++ b/neuralnetworks/utils/service/include/nnapi/hal/Service.h
@@ -29,7 +29,18 @@
     bool isDeviceUpdatable = false;
 };
 
-std::vector<SharedDeviceAndUpdatability> getDevices(bool includeUpdatableDrivers);
+/**
+ * @brief Get the NNAPI sAIDL and HIDL services declared in the VINTF.
+ *
+ * @pre maxFeatureLevelAllowed >= Version::Level::FEATURE_LEVEL_5
+ *
+ * @param includeUpdatableDrivers Allow updatable drivers to be used.
+ * @param maxFeatureLevelAllowed Maximum version of driver allowed to be used. Any driver version
+ *     exceeding this must be clamped to `maxFeatureLevelAllowed`.
+ * @return A list of devices and whether each device is updatable or not.
+ */
+std::vector<SharedDeviceAndUpdatability> getDevices(bool includeUpdatableDrivers,
+                                                    nn::Version::Level maxFeatureLevelAllowed);
 
 }  // namespace android::hardware::neuralnetworks::service
 
diff --git a/neuralnetworks/utils/service/src/Service.cpp b/neuralnetworks/utils/service/src/Service.cpp
index 2286288..e0d5f82 100644
--- a/neuralnetworks/utils/service/src/Service.cpp
+++ b/neuralnetworks/utils/service/src/Service.cpp
@@ -74,7 +74,7 @@
 
 void getAidlDevices(std::vector<SharedDeviceAndUpdatability>* devices,
                     std::unordered_set<std::string>* registeredDevices,
-                    bool includeUpdatableDrivers) {
+                    bool includeUpdatableDrivers, nn::Version::Level maxFeatureLevelAllowed) {
     CHECK(devices != nullptr);
     CHECK(registeredDevices != nullptr);
 
@@ -100,7 +100,7 @@
             continue;
         }
         if (const auto [it, unregistered] = registeredDevices->insert(name); unregistered) {
-            auto maybeDevice = aidl_hal::utils::getDevice(name);
+            auto maybeDevice = aidl_hal::utils::getDevice(name, maxFeatureLevelAllowed);
             if (maybeDevice.has_value()) {
                 auto device = std::move(maybeDevice).value();
                 CHECK(device != nullptr);
@@ -116,11 +116,14 @@
 
 }  // namespace
 
-std::vector<SharedDeviceAndUpdatability> getDevices(bool includeUpdatableDrivers) {
+std::vector<SharedDeviceAndUpdatability> getDevices(bool includeUpdatableDrivers,
+                                                    nn::Version::Level maxFeatureLevelAllowed) {
     std::vector<SharedDeviceAndUpdatability> devices;
     std::unordered_set<std::string> registeredDevices;
 
-    getAidlDevices(&devices, &registeredDevices, includeUpdatableDrivers);
+    CHECK_GE(maxFeatureLevelAllowed, nn::Version::Level::FEATURE_LEVEL_5);
+
+    getAidlDevices(&devices, &registeredDevices, includeUpdatableDrivers, maxFeatureLevelAllowed);
 
     getHidlDevicesForVersion(V1_3::IDevice::descriptor, &V1_3::utils::getDevice, &devices,
                              &registeredDevices);