Remove NN canonical IDevice::isUpdatable -- hal

This CL alters the AIDL utility "getDevices" to return whether or not a
service is updatable. This CL additional removes IDevice::isUpdatable
because it is now redundant with the changes to "getDevices".

Bug: 170696350
Test: mma
Test: NeuralNetworksTest_static
Change-Id: I86228763937c0dd2ee5b1d9d547c367cd7504ed4
diff --git a/neuralnetworks/utils/common/include/nnapi/hal/InvalidDevice.h b/neuralnetworks/utils/common/include/nnapi/hal/InvalidDevice.h
index d843526..5e62b9a 100644
--- a/neuralnetworks/utils/common/include/nnapi/hal/InvalidDevice.h
+++ b/neuralnetworks/utils/common/include/nnapi/hal/InvalidDevice.h
@@ -32,7 +32,7 @@
 class InvalidDevice final : public nn::IDevice {
   public:
     InvalidDevice(std::string name, std::string versionString, nn::Version featureLevel,
-                  nn::DeviceType type, bool isUpdatable, std::vector<nn::Extension> extensions,
+                  nn::DeviceType type, std::vector<nn::Extension> extensions,
                   nn::Capabilities capabilities,
                   std::pair<uint32_t, uint32_t> numberOfCacheFilesNeeded);
 
@@ -40,7 +40,6 @@
     const std::string& getVersionString() const override;
     nn::Version getFeatureLevel() const override;
     nn::DeviceType getType() const override;
-    bool isUpdatable() const override;
     const std::vector<nn::Extension>& getSupportedExtensions() const override;
     const nn::Capabilities& getCapabilities() const override;
     std::pair<uint32_t, uint32_t> getNumberOfCacheFilesNeeded() const override;
@@ -71,7 +70,6 @@
     const std::string kVersionString;
     const nn::Version kFeatureLevel;
     const nn::DeviceType kType;
-    const bool kIsUpdatable;
     const std::vector<nn::Extension> kExtensions;
     const nn::Capabilities kCapabilities;
     const std::pair<uint32_t, uint32_t> kNumberOfCacheFilesNeeded;
diff --git a/neuralnetworks/utils/common/include/nnapi/hal/ResilientDevice.h b/neuralnetworks/utils/common/include/nnapi/hal/ResilientDevice.h
index 8199c52..84ae799 100644
--- a/neuralnetworks/utils/common/include/nnapi/hal/ResilientDevice.h
+++ b/neuralnetworks/utils/common/include/nnapi/hal/ResilientDevice.h
@@ -53,7 +53,6 @@
     const std::string& getVersionString() const override;
     nn::Version getFeatureLevel() const override;
     nn::DeviceType getType() const override;
-    bool isUpdatable() const override;
     const std::vector<nn::Extension>& getSupportedExtensions() const override;
     const nn::Capabilities& getCapabilities() const override;
     std::pair<uint32_t, uint32_t> getNumberOfCacheFilesNeeded() const override;
diff --git a/neuralnetworks/utils/common/src/InvalidDevice.cpp b/neuralnetworks/utils/common/src/InvalidDevice.cpp
index 81bca7f..535ccb4 100644
--- a/neuralnetworks/utils/common/src/InvalidDevice.cpp
+++ b/neuralnetworks/utils/common/src/InvalidDevice.cpp
@@ -32,14 +32,13 @@
 namespace android::hardware::neuralnetworks::utils {
 
 InvalidDevice::InvalidDevice(std::string name, std::string versionString, nn::Version featureLevel,
-                             nn::DeviceType type, bool isUpdatable,
-                             std::vector<nn::Extension> extensions, nn::Capabilities capabilities,
+                             nn::DeviceType type, std::vector<nn::Extension> extensions,
+                             nn::Capabilities capabilities,
                              std::pair<uint32_t, uint32_t> numberOfCacheFilesNeeded)
     : kName(std::move(name)),
       kVersionString(std::move(versionString)),
       kFeatureLevel(featureLevel),
       kType(type),
-      kIsUpdatable(isUpdatable),
       kExtensions(std::move(extensions)),
       kCapabilities(std::move(capabilities)),
       kNumberOfCacheFilesNeeded(numberOfCacheFilesNeeded) {}
@@ -60,10 +59,6 @@
     return kType;
 }
 
-bool InvalidDevice::isUpdatable() const {
-    return kIsUpdatable;
-}
-
 const std::vector<nn::Extension>& InvalidDevice::getSupportedExtensions() const {
     return kExtensions;
 }
diff --git a/neuralnetworks/utils/common/src/ResilientDevice.cpp b/neuralnetworks/utils/common/src/ResilientDevice.cpp
index 13965af..2023c9a 100644
--- a/neuralnetworks/utils/common/src/ResilientDevice.cpp
+++ b/neuralnetworks/utils/common/src/ResilientDevice.cpp
@@ -122,14 +122,12 @@
     };
     if (compare(&IDevice::getName) || compare(&IDevice::getVersionString) ||
         compare(&IDevice::getFeatureLevel) || compare(&IDevice::getType) ||
-        compare(&IDevice::isUpdatable) || compare(&IDevice::getSupportedExtensions) ||
-        compare(&IDevice::getCapabilities)) {
+        compare(&IDevice::getSupportedExtensions) || compare(&IDevice::getCapabilities)) {
         LOG(ERROR) << "Recovered device has different metadata than what is cached. Marking "
                       "IDevice object as invalid.";
         device = std::make_shared<const InvalidDevice>(
-                kName, kVersionString, mDevice->getFeatureLevel(), mDevice->getType(),
-                mDevice->isUpdatable(), kExtensions, kCapabilities,
-                mDevice->getNumberOfCacheFilesNeeded());
+                kName, kVersionString, mDevice->getFeatureLevel(), mDevice->getType(), kExtensions,
+                kCapabilities, mDevice->getNumberOfCacheFilesNeeded());
         mIsValid = false;
     }
 
@@ -153,10 +151,6 @@
     return getDevice()->getType();
 }
 
-bool ResilientDevice::isUpdatable() const {
-    return getDevice()->isUpdatable();
-}
-
 const std::vector<nn::Extension>& ResilientDevice::getSupportedExtensions() const {
     return kExtensions;
 }
diff --git a/neuralnetworks/utils/common/test/MockDevice.h b/neuralnetworks/utils/common/test/MockDevice.h
index b274716..a9428bc 100644
--- a/neuralnetworks/utils/common/test/MockDevice.h
+++ b/neuralnetworks/utils/common/test/MockDevice.h
@@ -29,7 +29,6 @@
     MOCK_METHOD(const std::string&, getVersionString, (), (const, override));
     MOCK_METHOD(Version, getFeatureLevel, (), (const, override));
     MOCK_METHOD(DeviceType, getType, (), (const, override));
-    MOCK_METHOD(bool, isUpdatable, (), (const, override));
     MOCK_METHOD(const std::vector<Extension>&, getSupportedExtensions, (), (const, override));
     MOCK_METHOD(const Capabilities&, getCapabilities, (), (const, override));
     MOCK_METHOD((std::pair<uint32_t, uint32_t>), getNumberOfCacheFilesNeeded, (),
diff --git a/neuralnetworks/utils/service/include/nnapi/hal/Service.h b/neuralnetworks/utils/service/include/nnapi/hal/Service.h
index e339627..2fd5237 100644
--- a/neuralnetworks/utils/service/include/nnapi/hal/Service.h
+++ b/neuralnetworks/utils/service/include/nnapi/hal/Service.h
@@ -22,10 +22,15 @@
 #include <memory>
 #include <vector>
 
-namespace android::nn::hal {
+namespace android::hardware::neuralnetworks::service {
 
-std::vector<nn::SharedDevice> getDevices();
+struct SharedDeviceAndUpdatability {
+    nn::SharedDevice device;
+    bool isDeviceUpdatable = false;
+};
 
-}  // namespace android::nn::hal
+std::vector<SharedDeviceAndUpdatability> getDevices(bool includeUpdatableDrivers);
+
+}  // namespace android::hardware::neuralnetworks::service
 
 #endif  // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_SERVICE_H
diff --git a/neuralnetworks/utils/service/src/Service.cpp b/neuralnetworks/utils/service/src/Service.cpp
index 75ab1f9..2286288 100644
--- a/neuralnetworks/utils/service/src/Service.cpp
+++ b/neuralnetworks/utils/service/src/Service.cpp
@@ -35,6 +35,7 @@
 #include <nnapi/hal/1.2/Service.h>
 #include <nnapi/hal/1.3/Service.h>
 #include <nnapi/hal/aidl/Service.h>
+#include <nnapi/hal/aidl/Utils.h>
 
 #include <functional>
 #include <memory>
@@ -50,7 +51,7 @@
 using getDeviceFn = std::add_pointer_t<nn::GeneralResult<nn::SharedDevice>(const std::string&)>;
 
 void getHidlDevicesForVersion(const std::string& descriptor, getDeviceFn getDevice,
-                              std::vector<nn::SharedDevice>* devices,
+                              std::vector<SharedDeviceAndUpdatability>* devices,
                               std::unordered_set<std::string>* registeredDevices) {
     CHECK(devices != nullptr);
     CHECK(registeredDevices != nullptr);
@@ -62,7 +63,7 @@
             if (maybeDevice.has_value()) {
                 auto device = std::move(maybeDevice).value();
                 CHECK(device != nullptr);
-                devices->push_back(std::move(device));
+                devices->push_back({.device = std::move(device)});
             } else {
                 LOG(ERROR) << "getDevice(" << name << ") failed with " << maybeDevice.error().code
                            << ": " << maybeDevice.error().message;
@@ -71,8 +72,9 @@
     }
 }
 
-void getAidlDevices(std::vector<nn::SharedDevice>* devices,
-                    std::unordered_set<std::string>* registeredDevices) {
+void getAidlDevices(std::vector<SharedDeviceAndUpdatability>* devices,
+                    std::unordered_set<std::string>* registeredDevices,
+                    bool includeUpdatableDrivers) {
     CHECK(devices != nullptr);
     CHECK(registeredDevices != nullptr);
 
@@ -89,12 +91,21 @@
     }
 
     for (const auto& name : names) {
+        bool isDeviceUpdatable = false;
+        if (__builtin_available(android __NNAPI_AIDL_MIN_ANDROID_API__, *)) {
+            const auto instance = std::string(aidl_hal::IDevice::descriptor) + '/' + name;
+            isDeviceUpdatable = AServiceManager_isUpdatableViaApex(instance.c_str());
+        }
+        if (isDeviceUpdatable && !includeUpdatableDrivers) {
+            continue;
+        }
         if (const auto [it, unregistered] = registeredDevices->insert(name); unregistered) {
             auto maybeDevice = aidl_hal::utils::getDevice(name);
             if (maybeDevice.has_value()) {
                 auto device = std::move(maybeDevice).value();
                 CHECK(device != nullptr);
-                devices->push_back(std::move(device));
+                devices->push_back(
+                        {.device = std::move(device), .isDeviceUpdatable = isDeviceUpdatable});
             } else {
                 LOG(ERROR) << "getDevice(" << name << ") failed with " << maybeDevice.error().code
                            << ": " << maybeDevice.error().message;
@@ -103,11 +114,13 @@
     }
 }
 
-std::vector<nn::SharedDevice> getDevices() {
-    std::vector<nn::SharedDevice> devices;
+}  // namespace
+
+std::vector<SharedDeviceAndUpdatability> getDevices(bool includeUpdatableDrivers) {
+    std::vector<SharedDeviceAndUpdatability> devices;
     std::unordered_set<std::string> registeredDevices;
 
-    getAidlDevices(&devices, &registeredDevices);
+    getAidlDevices(&devices, &registeredDevices, includeUpdatableDrivers);
 
     getHidlDevicesForVersion(V1_3::IDevice::descriptor, &V1_3::utils::getDevice, &devices,
                              &registeredDevices);
@@ -121,13 +134,4 @@
     return devices;
 }
 
-}  // namespace
 }  // namespace android::hardware::neuralnetworks::service
-
-namespace android::nn::hal {
-
-std::vector<nn::SharedDevice> getDevices() {
-    return hardware::neuralnetworks::service::getDevices();
-}
-
-}  // namespace android::nn::hal