Clamp NNAPI HAL Version to runtime version -- hal

The NNAPI is a Mainline Module, and its runtime version is determined by
an Android Feature Flag to remotely rollout and rollback Feature Levels
as needed. This change propagates the maximum feature level version
allowed by the runtime to the HAL utility code, and clamps the utility
code's version to the version allowed by the runtime.

Bug: N/A
Test: mma
Test: CtsNNAPITestCases
Test: NeuralNetworksTest_static
Test: logged driver version, set current_feature_level, and verified the
      driver version was clamped by current_feature_level
Change-Id: Ibaa895f8e35d36b2ddf9432b3ef9468e5886075f
This commit is contained in:
Michael Butler 2022-02-11 16:48:37 -08:00
parent 4673d5ab25
commit 6f497d1833
4 changed files with 27 additions and 10 deletions

View file

@ -25,7 +25,8 @@
namespace aidl::android::hardware::neuralnetworks::utils { namespace aidl::android::hardware::neuralnetworks::utils {
::android::nn::GeneralResult<::android::nn::SharedDevice> getDevice(const std::string& name); ::android::nn::GeneralResult<::android::nn::SharedDevice> getDevice(
const std::string& name, ::android::nn::Version::Level maxFeatureLevelAllowed);
} // namespace aidl::android::hardware::neuralnetworks::utils } // namespace aidl::android::hardware::neuralnetworks::utils

View file

@ -55,11 +55,12 @@ nn::GeneralResult<nn::Version> getAidlServiceFeatureLevel(IDevice* service) {
} // namespace } // namespace
nn::GeneralResult<nn::SharedDevice> getDevice(const std::string& instanceName) { nn::GeneralResult<nn::SharedDevice> getDevice(
const std::string& instanceName, ::android::nn::Version::Level maxFeatureLevelAllowed) {
auto fullName = std::string(IDevice::descriptor) + "/" + instanceName; auto fullName = std::string(IDevice::descriptor) + "/" + instanceName;
hal::utils::ResilientDevice::Factory makeDevice = hal::utils::ResilientDevice::Factory makeDevice =
[instanceName, [instanceName, name = std::move(fullName),
name = std::move(fullName)](bool blocking) -> nn::GeneralResult<nn::SharedDevice> { maxFeatureLevelAllowed](bool blocking) -> nn::GeneralResult<nn::SharedDevice> {
std::add_pointer_t<AIBinder*(const char*)> getService; std::add_pointer_t<AIBinder*(const char*)> getService;
if (blocking) { if (blocking) {
if (__builtin_available(android __NNAPI_AIDL_MIN_ANDROID_API__, *)) { if (__builtin_available(android __NNAPI_AIDL_MIN_ANDROID_API__, *)) {
@ -79,7 +80,8 @@ nn::GeneralResult<nn::SharedDevice> getDevice(const std::string& instanceName) {
<< " returned nullptr"; << " returned nullptr";
} }
ABinderProcess_startThreadPool(); ABinderProcess_startThreadPool();
const auto featureLevel = NN_TRY(getAidlServiceFeatureLevel(service.get())); auto featureLevel = NN_TRY(getAidlServiceFeatureLevel(service.get()));
featureLevel.level = std::min(featureLevel.level, maxFeatureLevelAllowed);
return Device::create(instanceName, std::move(service), featureLevel); return Device::create(instanceName, std::move(service), featureLevel);
}; };

View file

@ -29,7 +29,18 @@ struct SharedDeviceAndUpdatability {
bool isDeviceUpdatable = false; bool isDeviceUpdatable = false;
}; };
std::vector<SharedDeviceAndUpdatability> getDevices(bool includeUpdatableDrivers); /**
* @brief Get the NNAPI sAIDL and HIDL services declared in the VINTF.
*
* @pre maxFeatureLevelAllowed >= Version::Level::FEATURE_LEVEL_5
*
* @param includeUpdatableDrivers Allow updatable drivers to be used.
* @param maxFeatureLevelAllowed Maximum version of driver allowed to be used. Any driver version
* exceeding this must be clamped to `maxFeatureLevelAllowed`.
* @return A list of devices and whether each device is updatable or not.
*/
std::vector<SharedDeviceAndUpdatability> getDevices(bool includeUpdatableDrivers,
nn::Version::Level maxFeatureLevelAllowed);
} // namespace android::hardware::neuralnetworks::service } // namespace android::hardware::neuralnetworks::service

View file

@ -74,7 +74,7 @@ void getHidlDevicesForVersion(const std::string& descriptor, getDeviceFn getDevi
void getAidlDevices(std::vector<SharedDeviceAndUpdatability>* devices, void getAidlDevices(std::vector<SharedDeviceAndUpdatability>* devices,
std::unordered_set<std::string>* registeredDevices, std::unordered_set<std::string>* registeredDevices,
bool includeUpdatableDrivers) { bool includeUpdatableDrivers, nn::Version::Level maxFeatureLevelAllowed) {
CHECK(devices != nullptr); CHECK(devices != nullptr);
CHECK(registeredDevices != nullptr); CHECK(registeredDevices != nullptr);
@ -100,7 +100,7 @@ void getAidlDevices(std::vector<SharedDeviceAndUpdatability>* devices,
continue; continue;
} }
if (const auto [it, unregistered] = registeredDevices->insert(name); unregistered) { if (const auto [it, unregistered] = registeredDevices->insert(name); unregistered) {
auto maybeDevice = aidl_hal::utils::getDevice(name); auto maybeDevice = aidl_hal::utils::getDevice(name, maxFeatureLevelAllowed);
if (maybeDevice.has_value()) { if (maybeDevice.has_value()) {
auto device = std::move(maybeDevice).value(); auto device = std::move(maybeDevice).value();
CHECK(device != nullptr); CHECK(device != nullptr);
@ -116,11 +116,14 @@ void getAidlDevices(std::vector<SharedDeviceAndUpdatability>* devices,
} // namespace } // namespace
std::vector<SharedDeviceAndUpdatability> getDevices(bool includeUpdatableDrivers) { std::vector<SharedDeviceAndUpdatability> getDevices(bool includeUpdatableDrivers,
nn::Version::Level maxFeatureLevelAllowed) {
std::vector<SharedDeviceAndUpdatability> devices; std::vector<SharedDeviceAndUpdatability> devices;
std::unordered_set<std::string> registeredDevices; std::unordered_set<std::string> registeredDevices;
getAidlDevices(&devices, &registeredDevices, includeUpdatableDrivers); CHECK_GE(maxFeatureLevelAllowed, nn::Version::Level::FEATURE_LEVEL_5);
getAidlDevices(&devices, &registeredDevices, includeUpdatableDrivers, maxFeatureLevelAllowed);
getHidlDevicesForVersion(V1_3::IDevice::descriptor, &V1_3::utils::getDevice, &devices, getHidlDevicesForVersion(V1_3::IDevice::descriptor, &V1_3::utils::getDevice, &devices,
&registeredDevices); &registeredDevices);