/* * Copyright (C) 2021 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 "SampleDriverUtils.h" #include #include #include #include #include #include #include #include #include #include #include #include "SampleDriver.h" namespace android { namespace nn { namespace sample_driver { void notify(const std::shared_ptr& callback, const aidl_hal::ErrorStatus& status, const std::shared_ptr& preparedModel) { const auto ret = callback->notify(status, preparedModel); if (!ret.isOk()) { LOG(ERROR) << "Error when calling IPreparedModelCallback::notify: " << ret.getDescription() << " " << ret.getMessage(); } } ndk::ScopedAStatus toAStatus(aidl_hal::ErrorStatus errorStatus) { if (errorStatus == aidl_hal::ErrorStatus::NONE) { return ndk::ScopedAStatus::ok(); } return ndk::ScopedAStatus::fromServiceSpecificError(static_cast(errorStatus)); } ndk::ScopedAStatus toAStatus(aidl_hal::ErrorStatus errorStatus, const std::string& errorMessage) { if (errorStatus == aidl_hal::ErrorStatus::NONE) { return ndk::ScopedAStatus::ok(); } return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage( static_cast(errorStatus), errorMessage.c_str()); } ndk::ScopedAStatus prepareModelBase( aidl_hal::Model&& model, const SampleDriver* driver, aidl_hal::ExecutionPreference preference, aidl_hal::Priority priority, int64_t halDeadline, const std::shared_ptr& callback, bool isFullModelSupported) { const uid_t userId = AIBinder_getCallingUid(); if (callback.get() == nullptr) { LOG(ERROR) << "invalid callback passed to prepareModelBase"; return toAStatus(aidl_hal::ErrorStatus::INVALID_ARGUMENT, "invalid callback passed to prepareModelBase"); } const auto canonicalModel = convert(model); if (!canonicalModel.has_value()) { VLOG(DRIVER) << "invalid model passed to prepareModelBase"; notify(callback, aidl_hal::ErrorStatus::INVALID_ARGUMENT, nullptr); return toAStatus(aidl_hal::ErrorStatus::INVALID_ARGUMENT, "invalid model passed to prepareModelBase"); } if (VLOG_IS_ON(DRIVER)) { VLOG(DRIVER) << "prepareModelBase"; logModelToInfo(canonicalModel.value()); } if (!aidl_hal::utils::valid(preference)) { const std::string log_message = "invalid execution preference passed to prepareModelBase: " + toString(preference); VLOG(DRIVER) << log_message; notify(callback, aidl_hal::ErrorStatus::INVALID_ARGUMENT, nullptr); return toAStatus(aidl_hal::ErrorStatus::INVALID_ARGUMENT, log_message); } if (!aidl_hal::utils::valid(priority)) { const std::string log_message = "invalid priority passed to prepareModelBase: " + toString(priority); VLOG(DRIVER) << log_message; notify(callback, aidl_hal::ErrorStatus::INVALID_ARGUMENT, nullptr); return toAStatus(aidl_hal::ErrorStatus::INVALID_ARGUMENT, log_message); } if (!isFullModelSupported) { VLOG(DRIVER) << "model is not fully supported"; notify(callback, aidl_hal::ErrorStatus::INVALID_ARGUMENT, nullptr); return ndk::ScopedAStatus::ok(); } if (halDeadline < -1) { notify(callback, aidl_hal::ErrorStatus::INVALID_ARGUMENT, nullptr); return toAStatus(aidl_hal::ErrorStatus::INVALID_ARGUMENT, "Invalid deadline: " + toString(halDeadline)); } const auto deadline = makeDeadline(halDeadline); if (hasDeadlinePassed(deadline)) { notify(callback, aidl_hal::ErrorStatus::MISSED_DEADLINE_PERSISTENT, nullptr); return ndk::ScopedAStatus::ok(); } // asynchronously prepare the model from a new, detached thread std::thread( [driver, preference, userId, priority, callback](aidl_hal::Model&& model) { std::shared_ptr preparedModel = ndk::SharedRefBase::make(std::move(model), driver, preference, userId, priority); if (!preparedModel->initialize()) { notify(callback, aidl_hal::ErrorStatus::INVALID_ARGUMENT, nullptr); return; } notify(callback, aidl_hal::ErrorStatus::NONE, preparedModel); }, std::move(model)) .detach(); return ndk::ScopedAStatus::ok(); } } // namespace sample_driver } // namespace nn } // namespace android