Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5f732ff6 authored by Lev Proleev's avatar Lev Proleev
Browse files

NNAPI: Add AIDL drivers registration

Bug: 179015258
Test: adb shell setprop debug.nn.partition 2 && \
Test: NeuralNetworksTest_static
Change-Id: I2c8c9a49ff917b243348043df1158a8d98f131ce
parent 9837322a
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -20,13 +20,12 @@
#include <nnapi/IDevice.h>
#include <nnapi/Result.h>
#include <nnapi/Types.h>
#include <nnapi/hal/CommonUtils.h>

#include <string>

namespace aidl::android::hardware::neuralnetworks::utils {

nn::GeneralResult<nn::SharedDevice> getDevice(const std::string& name);
::android::nn::GeneralResult<::android::nn::SharedDevice> getDevice(const std::string& name);

}  // namespace aidl::android::hardware::neuralnetworks::utils

+10 −7
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@

#include <android/binder_auto_utils.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>

#include <nnapi/IDevice.h>
#include <nnapi/Result.h>
@@ -29,19 +30,21 @@

namespace aidl::android::hardware::neuralnetworks::utils {

nn::GeneralResult<nn::SharedDevice> getDevice(const std::string& name) {
nn::GeneralResult<nn::SharedDevice> getDevice(const std::string& instanceName) {
    auto fullName = std::string(IDevice::descriptor) + "/" + instanceName;
    hal::utils::ResilientDevice::Factory makeDevice =
            [name](bool blocking) -> nn::GeneralResult<nn::SharedDevice> {
        auto service = blocking ? IDevice::fromBinder(
                                          ndk::SpAIBinder(AServiceManager_getService(name.c_str())))
                                : IDevice::fromBinder(ndk::SpAIBinder(
                                          AServiceManager_checkService(name.c_str())));
            [instanceName,
             name = std::move(fullName)](bool blocking) -> nn::GeneralResult<nn::SharedDevice> {
        const auto& getService =
                blocking ? AServiceManager_getService : AServiceManager_checkService;
        auto service = IDevice::fromBinder(ndk::SpAIBinder(getService(name.c_str())));
        if (service == nullptr) {
            return NN_ERROR() << (blocking ? "AServiceManager_getService"
                                           : "AServiceManager_checkService")
                              << " returned nullptr";
        }
        return Device::create(name, std::move(service));
        ABinderProcess_startThreadPool();
        return Device::create(instanceName, std::move(service));
    };

    return hal::utils::ResilientDevice::create(std::move(makeDevice));
+3 −0
Original line number Diff line number Diff line
@@ -35,12 +35,15 @@ cc_library_static {
        "neuralnetworks_utils_hal_1_1",
        "neuralnetworks_utils_hal_1_2",
        "neuralnetworks_utils_hal_1_3",
        "neuralnetworks_utils_hal_aidl",
        "neuralnetworks_utils_hal_common",
    ],
    shared_libs: [
        "android.hardware.neuralnetworks-V1-ndk_platform",
        "android.hardware.neuralnetworks@1.0",
        "android.hardware.neuralnetworks@1.1",
        "android.hardware.neuralnetworks@1.2",
        "android.hardware.neuralnetworks@1.3",
        "libbinder_ndk",
    ],
}
+49 −11
Original line number Diff line number Diff line
@@ -16,7 +16,9 @@

#include "Service.h"

#include <aidl/android/hardware/neuralnetworks/IDevice.h>
#include <android-base/logging.h>
#include <android/binder_manager.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>
@@ -31,6 +33,7 @@
#include <nnapi/hal/1.1/Service.h>
#include <nnapi/hal/1.2/Service.h>
#include <nnapi/hal/1.3/Service.h>
#include <nnapi/hal/aidl/Service.h>

#include <functional>
#include <memory>
@@ -42,9 +45,10 @@
namespace android::hardware::neuralnetworks::service {
namespace {

namespace aidl_hal = ::aidl::android::hardware::neuralnetworks;
using getDeviceFn = std::add_pointer_t<nn::GeneralResult<nn::SharedDevice>(const std::string&)>;

void getDevicesForVersion(const std::string& descriptor, getDeviceFn getDevice,
void getHidlDevicesForVersion(const std::string& descriptor, getDeviceFn getDevice,
                              std::vector<nn::SharedDevice>* devices,
                              std::unordered_set<std::string>* registeredDevices) {
    CHECK(devices != nullptr);
@@ -66,17 +70,51 @@ void getDevicesForVersion(const std::string& descriptor, getDeviceFn getDevice,
    }
}

void getAidlDevices(std::vector<nn::SharedDevice>* devices,
                    std::unordered_set<std::string>* registeredDevices) {
    CHECK(devices != nullptr);
    CHECK(registeredDevices != nullptr);

    std::vector<std::string> names;
    constexpr auto callback = [](const char* serviceName, void* names) {
        static_cast<std::vector<std::string>*>(names)->emplace_back(serviceName);
    };

    // Devices with SDK level lower than 31 (Android S) don't have any AIDL drivers available, so
    // there is no need for a workaround supported on lower levels.
    if (__builtin_available(android __ANDROID_API_S__, *)) {
        AServiceManager_forEachDeclaredInstance(aidl_hal::IDevice::descriptor,
                                                static_cast<void*>(&names), callback);
    }

    for (const auto& name : names) {
        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));
            } else {
                LOG(ERROR) << "getDevice(" << name << ") failed with " << maybeDevice.error().code
                           << ": " << maybeDevice.error().message;
            }
        }
    }
}

std::vector<nn::SharedDevice> getDevices() {
    std::vector<nn::SharedDevice> devices;
    std::unordered_set<std::string> registeredDevices;

    getDevicesForVersion(V1_3::IDevice::descriptor, &V1_3::utils::getDevice, &devices,
    getAidlDevices(&devices, &registeredDevices);

    getHidlDevicesForVersion(V1_3::IDevice::descriptor, &V1_3::utils::getDevice, &devices,
                             &registeredDevices);
    getDevicesForVersion(V1_2::IDevice::descriptor, &V1_2::utils::getDevice, &devices,
    getHidlDevicesForVersion(V1_2::IDevice::descriptor, &V1_2::utils::getDevice, &devices,
                             &registeredDevices);
    getDevicesForVersion(V1_1::IDevice::descriptor, &V1_1::utils::getDevice, &devices,
    getHidlDevicesForVersion(V1_1::IDevice::descriptor, &V1_1::utils::getDevice, &devices,
                             &registeredDevices);
    getDevicesForVersion(V1_0::IDevice::descriptor, &V1_0::utils::getDevice, &devices,
    getHidlDevicesForVersion(V1_0::IDevice::descriptor, &V1_0::utils::getDevice, &devices,
                             &registeredDevices);

    return devices;