2020-08-06 23:22:35 -07:00
|
|
|
/*
|
|
|
|
|
* Copyright (C) 2020 The Android Open Source Project
|
|
|
|
|
*
|
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
|
*
|
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
*
|
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
|
* limitations under the License.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "Service.h"
|
|
|
|
|
|
2021-04-07 14:10:55 +01:00
|
|
|
#include <AndroidVersionUtil.h>
|
2021-02-16 12:58:16 +00:00
|
|
|
#include <aidl/android/hardware/neuralnetworks/IDevice.h>
|
2020-08-06 23:22:35 -07:00
|
|
|
#include <android-base/logging.h>
|
2021-02-16 12:58:16 +00:00
|
|
|
#include <android/binder_manager.h>
|
2020-08-06 23:22:35 -07:00
|
|
|
#include <android/hardware/neuralnetworks/1.0/IDevice.h>
|
|
|
|
|
#include <android/hardware/neuralnetworks/1.1/IDevice.h>
|
|
|
|
|
#include <android/hardware/neuralnetworks/1.2/IDevice.h>
|
|
|
|
|
#include <android/hardware/neuralnetworks/1.3/IDevice.h>
|
|
|
|
|
#include <android/hidl/manager/1.2/IServiceManager.h>
|
|
|
|
|
#include <hidl/ServiceManagement.h>
|
|
|
|
|
#include <nnapi/IDevice.h>
|
|
|
|
|
#include <nnapi/Result.h>
|
|
|
|
|
#include <nnapi/TypeUtils.h>
|
|
|
|
|
#include <nnapi/Types.h>
|
|
|
|
|
#include <nnapi/hal/1.0/Service.h>
|
|
|
|
|
#include <nnapi/hal/1.1/Service.h>
|
|
|
|
|
#include <nnapi/hal/1.2/Service.h>
|
|
|
|
|
#include <nnapi/hal/1.3/Service.h>
|
2021-02-16 12:58:16 +00:00
|
|
|
#include <nnapi/hal/aidl/Service.h>
|
2021-04-14 23:26:47 -07:00
|
|
|
#include <nnapi/hal/aidl/Utils.h>
|
2020-08-06 23:22:35 -07:00
|
|
|
|
|
|
|
|
#include <functional>
|
|
|
|
|
#include <memory>
|
|
|
|
|
#include <string>
|
|
|
|
|
#include <type_traits>
|
|
|
|
|
#include <unordered_set>
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
|
|
namespace android::hardware::neuralnetworks::service {
|
|
|
|
|
namespace {
|
|
|
|
|
|
2021-02-16 12:58:16 +00:00
|
|
|
namespace aidl_hal = ::aidl::android::hardware::neuralnetworks;
|
2020-08-06 23:22:35 -07:00
|
|
|
using getDeviceFn = std::add_pointer_t<nn::GeneralResult<nn::SharedDevice>(const std::string&)>;
|
|
|
|
|
|
2021-02-16 12:58:16 +00:00
|
|
|
void getHidlDevicesForVersion(const std::string& descriptor, getDeviceFn getDevice,
|
2022-02-11 17:53:49 -08:00
|
|
|
std::vector<nn::SharedDevice>* devices,
|
2021-02-16 12:58:16 +00:00
|
|
|
std::unordered_set<std::string>* registeredDevices) {
|
2020-08-06 23:22:35 -07:00
|
|
|
CHECK(devices != nullptr);
|
|
|
|
|
CHECK(registeredDevices != nullptr);
|
|
|
|
|
|
|
|
|
|
const auto names = getAllHalInstanceNames(descriptor);
|
|
|
|
|
for (const auto& name : names) {
|
|
|
|
|
if (const auto [it, unregistered] = registeredDevices->insert(name); unregistered) {
|
|
|
|
|
auto maybeDevice = getDevice(name);
|
|
|
|
|
if (maybeDevice.has_value()) {
|
|
|
|
|
auto device = std::move(maybeDevice).value();
|
|
|
|
|
CHECK(device != nullptr);
|
2022-02-11 17:53:49 -08:00
|
|
|
devices->push_back(std::move(device));
|
2020-08-06 23:22:35 -07:00
|
|
|
} else {
|
|
|
|
|
LOG(ERROR) << "getDevice(" << name << ") failed with " << maybeDevice.error().code
|
|
|
|
|
<< ": " << maybeDevice.error().message;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-11 17:53:49 -08:00
|
|
|
void getAidlDevices(std::vector<nn::SharedDevice>* devices,
|
2021-04-14 23:26:47 -07:00
|
|
|
std::unordered_set<std::string>* registeredDevices,
|
2022-02-11 17:53:49 -08:00
|
|
|
nn::Version::Level maxFeatureLevelAllowed) {
|
2021-02-16 12:58:16 +00:00
|
|
|
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.
|
2021-04-07 14:10:55 +01:00
|
|
|
if (__builtin_available(android __NNAPI_AIDL_MIN_ANDROID_API__, *)) {
|
2021-02-16 12:58:16 +00:00
|
|
|
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) {
|
2022-02-11 16:48:37 -08:00
|
|
|
auto maybeDevice = aidl_hal::utils::getDevice(name, maxFeatureLevelAllowed);
|
2021-02-16 12:58:16 +00:00
|
|
|
if (maybeDevice.has_value()) {
|
|
|
|
|
auto device = std::move(maybeDevice).value();
|
|
|
|
|
CHECK(device != nullptr);
|
2022-02-11 17:53:49 -08:00
|
|
|
devices->push_back(std::move(device));
|
2021-02-16 12:58:16 +00:00
|
|
|
} else {
|
|
|
|
|
LOG(ERROR) << "getDevice(" << name << ") failed with " << maybeDevice.error().code
|
|
|
|
|
<< ": " << maybeDevice.error().message;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-14 23:26:47 -07:00
|
|
|
} // namespace
|
|
|
|
|
|
2022-02-11 17:53:49 -08:00
|
|
|
std::vector<nn::SharedDevice> getDevices(nn::Version::Level maxFeatureLevelAllowed) {
|
|
|
|
|
std::vector<nn::SharedDevice> devices;
|
2020-08-06 23:22:35 -07:00
|
|
|
std::unordered_set<std::string> registeredDevices;
|
|
|
|
|
|
2022-02-11 16:48:37 -08:00
|
|
|
CHECK_GE(maxFeatureLevelAllowed, nn::Version::Level::FEATURE_LEVEL_5);
|
|
|
|
|
|
2022-02-11 17:53:49 -08:00
|
|
|
getAidlDevices(&devices, ®isteredDevices, maxFeatureLevelAllowed);
|
2021-02-16 12:58:16 +00:00
|
|
|
|
|
|
|
|
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);
|
2020-08-06 23:22:35 -07:00
|
|
|
|
|
|
|
|
return devices;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace android::hardware::neuralnetworks::service
|