From 2d7195fd3286c534fd4604cb18d1d346585691ee Mon Sep 17 00:00:00 2001 From: Lev Proleev Date: Tue, 16 Feb 2021 12:58:16 +0000 Subject: [PATCH] NNAPI: Add AIDL drivers registration Bug: 179015258 Test: adb shell setprop debug.nn.partition 2 && \ Test: NeuralNetworksTest_static Change-Id: I2c8c9a49ff917b243348043df1158a8d98f131ce Merged-In: I2c8c9a49ff917b243348043df1158a8d98f131ce (cherry picked from commit 5f732ff683211e14bcb489839e46b99ee4c39106) --- .../utils/include/nnapi/hal/aidl/Service.h | 3 +- neuralnetworks/aidl/utils/src/Service.cpp | 17 +++--- neuralnetworks/utils/service/Android.bp | 3 + neuralnetworks/utils/service/src/Service.cpp | 60 +++++++++++++++---- 4 files changed, 63 insertions(+), 20 deletions(-) diff --git a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Service.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Service.h index b4587acbf7..cb6ff4b1cd 100644 --- a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Service.h +++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Service.h @@ -20,13 +20,12 @@ #include #include #include -#include #include namespace aidl::android::hardware::neuralnetworks::utils { -nn::GeneralResult getDevice(const std::string& name); +::android::nn::GeneralResult<::android::nn::SharedDevice> getDevice(const std::string& name); } // namespace aidl::android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/aidl/utils/src/Service.cpp b/neuralnetworks/aidl/utils/src/Service.cpp index 5ec6ded5e5..511de559a6 100644 --- a/neuralnetworks/aidl/utils/src/Service.cpp +++ b/neuralnetworks/aidl/utils/src/Service.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -29,19 +30,21 @@ namespace aidl::android::hardware::neuralnetworks::utils { -nn::GeneralResult getDevice(const std::string& name) { +nn::GeneralResult getDevice(const std::string& instanceName) { + auto fullName = std::string(IDevice::descriptor) + "/" + instanceName; hal::utils::ResilientDevice::Factory makeDevice = - [name](bool blocking) -> nn::GeneralResult { - 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 { + 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)); diff --git a/neuralnetworks/utils/service/Android.bp b/neuralnetworks/utils/service/Android.bp index 9f8b9bbbfd..5f36dff2cd 100644 --- a/neuralnetworks/utils/service/Android.bp +++ b/neuralnetworks/utils/service/Android.bp @@ -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", ], } diff --git a/neuralnetworks/utils/service/src/Service.cpp b/neuralnetworks/utils/service/src/Service.cpp index a59549dbf9..c83bcc916c 100644 --- a/neuralnetworks/utils/service/src/Service.cpp +++ b/neuralnetworks/utils/service/src/Service.cpp @@ -16,7 +16,9 @@ #include "Service.h" +#include #include +#include #include #include #include @@ -31,6 +33,7 @@ #include #include #include +#include #include #include @@ -42,11 +45,12 @@ namespace android::hardware::neuralnetworks::service { namespace { +namespace aidl_hal = ::aidl::android::hardware::neuralnetworks; using getDeviceFn = std::add_pointer_t(const std::string&)>; -void getDevicesForVersion(const std::string& descriptor, getDeviceFn getDevice, - std::vector* devices, - std::unordered_set* registeredDevices) { +void getHidlDevicesForVersion(const std::string& descriptor, getDeviceFn getDevice, + std::vector* devices, + std::unordered_set* registeredDevices) { CHECK(devices != nullptr); CHECK(registeredDevices != nullptr); @@ -66,18 +70,52 @@ void getDevicesForVersion(const std::string& descriptor, getDeviceFn getDevice, } } +void getAidlDevices(std::vector* devices, + std::unordered_set* registeredDevices) { + CHECK(devices != nullptr); + CHECK(registeredDevices != nullptr); + + std::vector names; + constexpr auto callback = [](const char* serviceName, void* names) { + static_cast*>(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(&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 getDevices() { std::vector devices; std::unordered_set registeredDevices; - getDevicesForVersion(V1_3::IDevice::descriptor, &V1_3::utils::getDevice, &devices, - ®isteredDevices); - getDevicesForVersion(V1_2::IDevice::descriptor, &V1_2::utils::getDevice, &devices, - ®isteredDevices); - getDevicesForVersion(V1_1::IDevice::descriptor, &V1_1::utils::getDevice, &devices, - ®isteredDevices); - getDevicesForVersion(V1_0::IDevice::descriptor, &V1_0::utils::getDevice, &devices, - ®isteredDevices); + getAidlDevices(&devices, ®isteredDevices); + + getHidlDevicesForVersion(V1_3::IDevice::descriptor, &V1_3::utils::getDevice, &devices, + ®isteredDevices); + getHidlDevicesForVersion(V1_2::IDevice::descriptor, &V1_2::utils::getDevice, &devices, + ®isteredDevices); + getHidlDevicesForVersion(V1_1::IDevice::descriptor, &V1_1::utils::getDevice, &devices, + ®isteredDevices); + getHidlDevicesForVersion(V1_0::IDevice::descriptor, &V1_0::utils::getDevice, &devices, + ®isteredDevices); return devices; }