Cleanup NN callback error handling
This CL introduces a new templated class CallbackValue to handle HIDL
"return value" callbacks in a terser and more readable way.
This CL also introduces a new macro HANDLE_HAL_STATUS to return from the
current function when an error is present with the ability to append a
more descriptive error message.
Finally, this CL changes the behavior of synchronous executions. Prior
to this CL, IPreparedModel fell back to an asynchronous execution if the
synchronous execution was allowed and failed. This change instead
returns a failure if synchronous execution is allowed and fails.
Bug: 173084343
Test: mma
Change-Id: I62714a932e71dfc77401bbcb9eaaaf3d94fb9707
Merged-In: I62714a932e71dfc77401bbcb9eaaaf3d94fb9707
(cherry picked from commit 98ed9baf5de85599847b2b2f53585243c3b7b776)
diff --git a/neuralnetworks/1.0/utils/src/Device.cpp b/neuralnetworks/1.0/utils/src/Device.cpp
index 83e0015..93bd81a 100644
--- a/neuralnetworks/1.0/utils/src/Device.cpp
+++ b/neuralnetworks/1.0/utils/src/Device.cpp
@@ -31,6 +31,7 @@
#include <nnapi/hal/CommonUtils.h>
#include <nnapi/hal/HandleError.h>
#include <nnapi/hal/ProtectCallback.h>
+#include <nnapi/hal/TransferValue.h>
#include <functional>
#include <memory>
@@ -44,24 +45,21 @@
namespace android::hardware::neuralnetworks::V1_0::utils {
namespace {
-nn::GeneralResult<nn::Capabilities> initCapabilities(V1_0::IDevice* device) {
+nn::GeneralResult<nn::Capabilities> capabilitiesCallback(ErrorStatus status,
+ const Capabilities& capabilities) {
+ HANDLE_HAL_STATUS(status) << "getting capabilities failed with " << toString(status);
+ return nn::convert(capabilities);
+}
+
+nn::GeneralResult<nn::Capabilities> getCapabilitiesFrom(V1_0::IDevice* device) {
CHECK(device != nullptr);
- nn::GeneralResult<nn::Capabilities> result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
- << "uninitialized";
- const auto cb = [&result](ErrorStatus status, const Capabilities& capabilities) {
- if (status != ErrorStatus::NONE) {
- const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
- result = NN_ERROR(canonical) << "getCapabilities failed with " << toString(status);
- } else {
- result = nn::convert(capabilities);
- }
- };
+ auto cb = hal::utils::CallbackValue(capabilitiesCallback);
const auto ret = device->getCapabilities(cb);
HANDLE_TRANSPORT_FAILURE(ret);
- return result;
+ return cb.take();
}
} // namespace
@@ -77,7 +75,7 @@
<< "V1_0::utils::Device::create must have non-null device";
}
- auto capabilities = NN_TRY(initCapabilities(device.get()));
+ auto capabilities = NN_TRY(getCapabilitiesFrom(device.get()));
auto deathHandler = NN_TRY(hal::utils::DeathHandler::create(device));
return std::make_shared<const Device>(PrivateConstructorTag{}, std::move(name),
@@ -134,27 +132,12 @@
const auto hidlModel = NN_TRY(convert(modelInShared));
- nn::GeneralResult<std::vector<bool>> result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
- << "uninitialized";
- auto cb = [&result, &model](ErrorStatus status, const hidl_vec<bool>& supportedOperations) {
- if (status != ErrorStatus::NONE) {
- const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
- result = NN_ERROR(canonical)
- << "getSupportedOperations failed with " << toString(status);
- } else if (supportedOperations.size() != model.main.operations.size()) {
- result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
- << "getSupportedOperations returned vector of size "
- << supportedOperations.size() << " but expected "
- << model.main.operations.size();
- } else {
- result = supportedOperations;
- }
- };
+ auto cb = hal::utils::CallbackValue(supportedOperationsCallback);
const auto ret = kDevice->getSupportedOperations(hidlModel, cb);
HANDLE_TRANSPORT_FAILURE(ret);
- return result;
+ return cb.take();
}
nn::GeneralResult<nn::SharedPreparedModel> Device::prepareModel(
@@ -173,10 +156,7 @@
const auto ret = kDevice->prepareModel(hidlModel, cb);
const auto status = HANDLE_TRANSPORT_FAILURE(ret);
- if (status != ErrorStatus::NONE) {
- const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE);
- return NN_ERROR(canonical) << "prepareModel failed with " << toString(status);
- }
+ HANDLE_HAL_STATUS(status) << "model preparation failed with " << toString(status);
return cb->get();
}