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 5f732ff683)
This commit is contained in:
Lev Proleev 2021-02-16 12:58:16 +00:00 committed by Slava Shklyaev
parent 593f0ecaf4
commit 2d7195fd32
4 changed files with 63 additions and 20 deletions

View file

@ -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

View file

@ -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));

View file

@ -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",
],
}

View file

@ -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,11 +45,12 @@
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,
std::vector<nn::SharedDevice>* devices,
std::unordered_set<std::string>* registeredDevices) {
void getHidlDevicesForVersion(const std::string& descriptor, getDeviceFn getDevice,
std::vector<nn::SharedDevice>* devices,
std::unordered_set<std::string>* registeredDevices) {
CHECK(devices != nullptr);
CHECK(registeredDevices != nullptr);
@ -66,18 +70,52 @@ 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,
&registeredDevices);
getDevicesForVersion(V1_2::IDevice::descriptor, &V1_2::utils::getDevice, &devices,
&registeredDevices);
getDevicesForVersion(V1_1::IDevice::descriptor, &V1_1::utils::getDevice, &devices,
&registeredDevices);
getDevicesForVersion(V1_0::IDevice::descriptor, &V1_0::utils::getDevice, &devices,
&registeredDevices);
getAidlDevices(&devices, &registeredDevices);
getHidlDevicesForVersion(V1_3::IDevice::descriptor, &V1_3::utils::getDevice, &devices,
&registeredDevices);
getHidlDevicesForVersion(V1_2::IDevice::descriptor, &V1_2::utils::getDevice, &devices,
&registeredDevices);
getHidlDevicesForVersion(V1_1::IDevice::descriptor, &V1_1::utils::getDevice, &devices,
&registeredDevices);
getHidlDevicesForVersion(V1_0::IDevice::descriptor, &V1_0::utils::getDevice, &devices,
&registeredDevices);
return devices;
}