/*
 * 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.
 */

#define LOG_TAG "ShimDevice"

#include "ShimDevice.h"

#include <NeuralNetworks.h>
#include <aidl/android/hardware/neuralnetworks/DataLocation.h>
#include <aidl/android/hardware/neuralnetworks/ErrorStatus.h>
#include <aidl/android/hardware/neuralnetworks/Extension.h>
#include <aidl/android/hardware/neuralnetworks/ExtensionOperandTypeInformation.h>
#include <aidl/android/hardware/neuralnetworks/Memory.h>
#include <aidl/android/hardware/neuralnetworks/NumberOfCacheFiles.h>
#include <aidl/android/hardware/neuralnetworks/OperandLifeTime.h>
#include <aidl/android/hardware/neuralnetworks/OperandPerformance.h>
#include <android-base/logging.h>
#include <android-base/scopeguard.h>
#include <android/binder_auto_utils.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
#include <nnapi/TypeUtils.h>
#include <nnapi/hal/aidl/Conversions.h>

#include <algorithm>
#include <limits>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>

#include "ShimConverter.h"
#include "ShimPreparedModel.h"
#include "ShimUtils.h"
#include "SupportLibrary.h"

using namespace ::android::nn::sl_wrapper;

namespace aidl::android::hardware::neuralnetworks {

namespace {

constexpr std::optional<::android::nn::wrapper::ExecutePriority> convertToNDKPriority(
        Priority priority) {
    switch (priority) {
        case Priority::LOW:
            return ::android::nn::wrapper::ExecutePriority::LOW;
        case Priority::MEDIUM:
            return ::android::nn::wrapper::ExecutePriority::MEDIUM;
        case Priority::HIGH:
            return ::android::nn::wrapper::ExecutePriority::HIGH;
    }
    LOG(ERROR) << "unrecognized priority: " << static_cast<int32_t>(priority);
    return std::nullopt;
}

constexpr std::optional<::android::nn::wrapper::ExecutePreference> convertToNDKPreference(
        ExecutionPreference preference) {
    switch (preference) {
        case ExecutionPreference::LOW_POWER:
            return ::android::nn::wrapper::ExecutePreference::PREFER_LOW_POWER;
        case ExecutionPreference::FAST_SINGLE_ANSWER:
            return ::android::nn::wrapper::ExecutePreference::PREFER_FAST_SINGLE_ANSWER;
        case ExecutionPreference::SUSTAINED_SPEED:
            return ::android::nn::wrapper::ExecutePreference::PREFER_SUSTAINED_SPEED;
    }
    LOG(ERROR) << "unrecognized preference: " << static_cast<int32_t>(preference);
    return std::nullopt;
}

// Safely downcast an IPreparedModel object to ShimPreparedModel.
// This function will return nullptr if the IPreparedModel object is not originated from the
// shim process.
const ShimPreparedModel* castToShimPreparedModel(IPreparedModel* preparedModel) {
    if (preparedModel->isRemote()) {
        return nullptr;
    }
    // This static_cast is safe because ShimPreparedModel is the only class that implements
    // the IPreparedModel interface in the sample driver process.
    return static_cast<const ShimPreparedModel*>(preparedModel);
}

static PerformanceInfo convertPerformanceInfo(const SL_ANeuralNetworksPerformanceInfo& info) {
    return {.execTime = info.execTime, .powerUsage = info.powerUsage};
}

Capabilities getCapabilities(const NnApiSupportLibrary* nnapi, ANeuralNetworksDevice* device) {
    Capabilities capabilities;
    SL_ANeuralNetworksPerformanceInfo performanceInfo;

    nnapi->SL_ANeuralNetworksDevice_getPerformanceInfo(
            device, SL_ANEURALNETWORKS_CAPABILITIES_PERFORMANCE_RELAXED_SCALAR, &performanceInfo);
    capabilities.relaxedFloat32toFloat16PerformanceScalar = convertPerformanceInfo(performanceInfo);

    nnapi->SL_ANeuralNetworksDevice_getPerformanceInfo(
            device, SL_ANEURALNETWORKS_CAPABILITIES_PERFORMANCE_RELAXED_TENSOR, &performanceInfo);
    capabilities.relaxedFloat32toFloat16PerformanceTensor = convertPerformanceInfo(performanceInfo);

    nnapi->SL_ANeuralNetworksDevice_getPerformanceInfo(
            device, SL_ANEURALNETWORKS_CAPABILITIES_PERFORMANCE_IF, &performanceInfo);
    capabilities.ifPerformance = convertPerformanceInfo(performanceInfo);

    nnapi->SL_ANeuralNetworksDevice_getPerformanceInfo(
            device, SL_ANEURALNETWORKS_CAPABILITIES_PERFORMANCE_WHILE, &performanceInfo);
    capabilities.whilePerformance = convertPerformanceInfo(performanceInfo);

    constexpr auto fn = [](SL_ANeuralNetworksOperandPerformanceInfo info, void* context) {
        auto* out = static_cast<std::vector<OperandPerformance>*>(context);
        out->push_back(OperandPerformance{
                .type = static_cast<OperandType>(info.operandType),
                .info = convertPerformanceInfo(info.performanceInfo),
        });
    };

    nnapi->SL_ANeuralNetworksDevice_forEachOperandPerformanceInfo(
            device, static_cast<void*>(&capabilities.operandPerformance), fn);

    return capabilities;
}

NumberOfCacheFiles getNumberOfCacheFilesNeeded(const NnApiSupportLibrary* nnapi,
                                               ANeuralNetworksDevice* device) {
    uint32_t numModelCacheFiles;
    uint32_t numDataCacheFiles;
    nnapi->SL_ANeuralNetworksDevice_getNumberOfCacheFilesNeeded(device, &numModelCacheFiles,
                                                                &numDataCacheFiles);
    return {
            .numModelCache = static_cast<int32_t>(numModelCacheFiles),
            .numDataCache = static_cast<int32_t>(numDataCacheFiles),
    };
}

std::vector<Extension> getVendorExtensions(const NnApiSupportLibrary* nnapi,
                                           ANeuralNetworksDevice* device) {
    uint32_t vendorExtensionCount;
    nnapi->SL_ANeuralNetworksDevice_getVendorExtensionCount(device, &vendorExtensionCount);

    std::vector<Extension> extensions(vendorExtensionCount);

    for (uint32_t vendorExtensionIndex = 0; vendorExtensionIndex < vendorExtensionCount;
         ++vendorExtensionIndex) {
        auto& extension = extensions[vendorExtensionIndex];

        const char* extensionName;
        nnapi->SL_ANeuralNetworksDevice_getVendorExtensionName(device, vendorExtensionIndex,
                                                               &extensionName);
        extension.name = extensionName;

        constexpr auto fn = [](SL_ANeuralNetworksExtensionOperandTypeInformation info,
                               void* context) {
            auto* out = static_cast<std::vector<ExtensionOperandTypeInformation>*>(context);
            out->push_back(ExtensionOperandTypeInformation{
                    .type = info.type,
                    .isTensor = info.isTensor,
                    .byteSize = static_cast<int32_t>(info.byteSize),
            });
        };
        nnapi->SL_ANeuralNetworksDevice_forEachVendorExtensionOperandTypeInformation(
                device, vendorExtensionIndex, static_cast<void*>(&extension.operandTypes), fn);
    }

    return extensions;
}

}  // namespace

ShimDevice::ShimDevice(std::shared_ptr<const NnApiSupportLibrary> nnapi,
                       ANeuralNetworksDevice* device, std::string serviceName)
    : mNnapi(std::move(nnapi)),
      mBufferTracker(ShimBufferTracker::create()),
      mServiceName(std::move(serviceName)),
      mDevice(device),
      mCapabilities(neuralnetworks::getCapabilities(mNnapi.get(), mDevice)),
      mNumberOfCacheFiles(neuralnetworks::getNumberOfCacheFilesNeeded(mNnapi.get(), mDevice)),
      mExtensions(neuralnetworks::getVendorExtensions(mNnapi.get(), mDevice)) {}

// Manages the data buffer for an operand.
class ShimBuffer : public BnBuffer {
   public:
    ShimBuffer(const NnApiSupportLibrary* nnApi, const ::android::nn::Dimensions initialDimensions,
               const ::android::nn::OperandType type,
               std::shared_ptr<::android::nn::sl_wrapper::Memory> memory,
               std::unique_ptr<ShimBufferTracker::Token> token)
        : kInitialDimensions(initialDimensions),
          kType(type),
          mNnApi(nnApi),
          mMemory(std::move(memory)),
          kToken(std::move(token)) {}

    bool tensorHasUnspecifiedDimensions(::android::nn::OperandType type,
                                        const ::android::nn::Dimensions& dimensions) {
        if (!::android::nn::isExtension(type)) {
            if (isNonExtensionScalar(type)) {
                return false;
            }
        }
        return dimensions.size() == 0 || std::any_of(dimensions.begin(), dimensions.end(),
                                                     [](int32_t dim) { return dim == 0; });
    }

    bool validateDimensions(const ::android::nn::Dimensions& dimensions) {
        if (isNonExtensionScalar(kType)) {
            if (!dimensions.empty()) {
                LOG(ERROR) << "ShimBuffer::validateDimensions -- invalid dimensions for scalar "
                              "operand";
                return false;
            }
            return true;
        }

        if (dimensions.empty()) {
            if (tensorHasUnspecifiedDimensions(kType, kInitialDimensions)) {
                LOG(ERROR) << "ShimBuffer::validateDimensions -- the initial dimensions are not "
                              "fully specified and no dimension update is provided: ";

                return false;
            }
        } else {
            if (tensorHasUnspecifiedDimensions(kType, dimensions)) {
                LOG(ERROR) << "ShimBuffer::validateDimensions -- the updated dimensions are not "
                              "fully specified: ";

                return false;
            }
        }

        const auto combined = ::android::nn::combineDimensions(kInitialDimensions, dimensions);
        if (!combined.has_value()) {
            LOG(ERROR) << "ShimBuffer::validateDimensions -- incompatible dimensions";
            return false;
        }
        return true;
    }

    ndk::ScopedAStatus copyFrom(const aidl::android::hardware::neuralnetworks::Memory& src,
                                const std::vector<int32_t>& dimensions) override {
        auto memory = convertFromHAL(mNnApi, src);

        if (!memory) {
            LOG(ERROR) << "Failed to convert HAL Memory to SL memory";
            return toAStatus(ErrorStatus::INVALID_ARGUMENT);
        }
        const auto unsignedDimensions = ::android::nn::toUnsigned(dimensions);
        if (!unsignedDimensions.has_value()) {
            return toAStatus(aidl_hal::ErrorStatus::INVALID_ARGUMENT,
                             unsignedDimensions.error().message);
        }

        if (!validateDimensions(unsignedDimensions.value())) {
            LOG(ERROR) << "Invalid dimensions";
            return toAStatus(ErrorStatus::INVALID_ARGUMENT);
        }
        Result result = memory->copyTo(*mMemory.get());

        // Special case expected error status for uninitialized source memory
        if (result == Result::BAD_DATA) {
            // NNAPI Runtime reports both uninitialized memory
            // and incompatible dimensions as BAD_DATA, but
            // VTS expects to see INVALID_ARGUMENT for bad dimensions,
            // and GENERAL_FAILURE for uninitialized memory.
            if (memory->getSize() != mMemory->getSize()) {
                return toAStatus(ErrorStatus::INVALID_ARGUMENT, "Incompatible sizes");
            }

            return toAStatus(ErrorStatus::GENERAL_FAILURE);
        }
        SLW2SAS_RETURN_IF_ERROR(result);
        return ndk::ScopedAStatus::ok();
    }

    ndk::ScopedAStatus copyTo(const Memory& dst) override {
        auto memory = convertFromHAL(mNnApi, dst);

        if (!memory) {
            LOG(ERROR) << "Failed to convert HAL Memory to SL memory";
            return toAStatus(ErrorStatus::INVALID_ARGUMENT);
        }

        Result result = mMemory->copyTo(*memory);
        // Special case expected error status for uninitialized source memory
        if (result == Result::BAD_DATA) {
            // NNAPI Runtime reports both uninitialized memory
            // and incompatible dimensions as BAD_DATA, but
            // VTS expects to see INVALID_ARGUMENT for bad dimensions,
            // and GENERAL_FAILURE for uninitialized memory.
            if (memory->getSize() != mMemory->getSize()) {
                return toAStatus(ErrorStatus::INVALID_ARGUMENT, "Incompatible sizes");
            }
            return toAStatus(ErrorStatus::GENERAL_FAILURE);
        }
        SLW2SAS_RETURN_IF_ERROR(result);
        return ndk::ScopedAStatus::ok();
    }

   private:
    const ::android::nn::Dimensions kInitialDimensions;
    const ::android::nn::OperandType kType;

    const NnApiSupportLibrary* mNnApi;
    std::shared_ptr<::android::nn::sl_wrapper::Memory> mMemory;
    const std::unique_ptr<ShimBufferTracker::Token> kToken;
};

::ndk::ScopedAStatus ShimDevice::allocate(const BufferDesc& desc,
                                          const std::vector<IPreparedModelParcel>& preparedModels,
                                          const std::vector<BufferRole>& inputRoles,
                                          const std::vector<BufferRole>& outputRoles,
                                          DeviceBuffer* buffer) {
    if (!isValidDimension(desc.dimensions)) {
        LOG(ERROR) << "ShimDriver::allocate -- passed invalid dimension values.";
        return toAStatus(ErrorStatus::INVALID_ARGUMENT,
                         "ShimDriver::allocate -- passed invalid dimension values");
    }
    ANeuralNetworksMemoryDesc* slDesc = nullptr;
    mNnapi->ANeuralNetworksMemoryDesc_create(&slDesc);
    const auto slDescGuard = ::android::base::make_scope_guard(
            [this, slDesc] { mNnapi->ANeuralNetworksMemoryDesc_free(slDesc); });

    auto unsignedDimensions = ::android::nn::toUnsigned(desc.dimensions).value();
    if (mNnapi->ANeuralNetworksMemoryDesc_setDimensions(slDesc, desc.dimensions.size(),
                                                        unsignedDimensions.data()) !=
        ANEURALNETWORKS_NO_ERROR) {
        LOG(ERROR) << "ShimDriver::allocate -- ANeuralNetworksMemoryDesc_setDimensions fail.";
        return toAStatus(ErrorStatus::INVALID_ARGUMENT,
                         "ShimDriver::allocate -- ANeuralNetworksMemoryDesc_setDimensions fail");
    }

    constexpr auto getCompilation = [](IPreparedModel* preparedModel) -> const ShimPreparedModel* {
        const auto* samplePreparedModel = castToShimPreparedModel(preparedModel);
        if (samplePreparedModel == nullptr) {
            LOG(ERROR) << "ShimDriver::allocate -- unknown remote IPreparedModel.";
            return nullptr;
        }
        return samplePreparedModel;
    };

    std::optional<::android::nn::OperandType> type;
    std::vector<uint32_t> dimensions = ::android::nn::toUnsigned(desc.dimensions).value();

    for (const auto& role : inputRoles) {
        if (role.modelIndex < 0 || role.modelIndex >= preparedModels.size()) {
            LOG(ERROR) << "Invalid modelIndex value " << role.modelIndex;
            return toAStatus(ErrorStatus::INVALID_ARGUMENT,
                             "ShimDriver::allocate -- Input role modeIndex with invalid value");
        }
        auto preparedModel = preparedModels[role.modelIndex];
        if (preparedModel.preparedModel == nullptr) {
            return toAStatus(ErrorStatus::INVALID_ARGUMENT,
                             "ShimDriver::allocate -- nullptr model");
        }

        auto pmodel = getCompilation(preparedModel.preparedModel.get());
        if (pmodel == nullptr) {
            return toAStatus(ErrorStatus::INVALID_ARGUMENT,
                             "ShimDriver::allocate -- nullptr model");
        }

        auto result = mNnapi->ANeuralNetworksMemoryDesc_addInputRole(
                slDesc, pmodel->getCompilation().getHandle(), role.ioIndex, role.probability);

        if (result != ANEURALNETWORKS_NO_ERROR) {
            LOG(ERROR) << "SampleDriver::allocate -- ANeuralNetworksMemoryDesc_addInputRole fail.";
            return toAStatus(ErrorStatus::INVALID_ARGUMENT,
                             "ShimDriver::allocate -- ANeuralNetworksMemoryDesc_addInputRole fail");
        }

        const auto& model = pmodel->getMainModel();
        const auto& op = model.getOperands()[model.getInputs()[role.ioIndex]];
        auto operandType = static_cast<::android::nn::OperandType>(op.operandType.type);
        if (!type) {
            type = operandType;
        }
        if (dimensions.empty()) {
            dimensions = op.dimensions;
        }
    }

    for (const auto& role : outputRoles) {
        if (role.modelIndex < 0 || role.modelIndex >= preparedModels.size()) {
            LOG(ERROR) << "Invalid modelIndex value " << role.modelIndex;
            return toAStatus(ErrorStatus::INVALID_ARGUMENT,
                             "ShimDriver::allocate -- Ou0tput role modeIndex with invalid value");
        }
        auto preparedModel = preparedModels[role.modelIndex];
        if (preparedModel.preparedModel == nullptr) {
            return toAStatus(ErrorStatus::INVALID_ARGUMENT,
                             "ShimDriver::allocate -- nullptr model");
        }

        auto pmodel = getCompilation(preparedModel.preparedModel.get());
        if (pmodel == nullptr) {
            return toAStatus(ErrorStatus::INVALID_ARGUMENT,
                             "ShimDriver::allocate -- nullptr model");
        }

        auto result = mNnapi->ANeuralNetworksMemoryDesc_addOutputRole(
                slDesc, pmodel->getCompilation().getHandle(), role.ioIndex, role.probability);

        if (result != ANEURALNETWORKS_NO_ERROR) {
            LOG(ERROR) << "SampleDriver::allocate -- ANeuralNetworksMemoryDesc_addInputRole fail.";
            return toAStatus(ErrorStatus::INVALID_ARGUMENT,
                             "ShimDriver::allocate -- ANeuralNetworksMemoryDesc_addInputRole fail");
        }
        const auto& model = pmodel->getMainModel();
        const auto& op = model.getOperands()[model.getOutputs()[role.ioIndex]];
        auto operandType = static_cast<::android::nn::OperandType>(op.operandType.type);
        if (!type) {
            type = operandType;
        }
        if (dimensions.empty()) {
            dimensions = op.dimensions;
        }
    }

    auto typeSize = ::android::nn::getNonExtensionSize(*type, dimensions);
    if (!typeSize.has_value()) {
        return toAStatus(ErrorStatus::INVALID_ARGUMENT,
                         "ShimDriver::allocate -- failed to get underlying type size, "
                         "possibly an extension type");
    }

    mNnapi->ANeuralNetworksMemoryDesc_finish(slDesc);
    auto memory =
            std::make_shared<::android::nn::sl_wrapper::Memory>(mNnapi.get(), slDesc, *typeSize);

    if (!memory->isValid()) {
        LOG(ERROR) << "ShimDriver::allocate -- ANeuralNetworksMemory_createFromDesc failed.";
        return toAStatus(ErrorStatus::GENERAL_FAILURE,
                         "ShimDriver::allocate -- ANeuralNetworksMemory_createFromDesc failed");
    }

    auto token = mBufferTracker->add(memory);
    if (token == nullptr) {
        LOG(ERROR) << "ShimDriver::allocate -- ShimBufferTracker returned invalid token.";
        return toAStatus(ErrorStatus::GENERAL_FAILURE,
                         "ShimDriver::allocate -- ShimBufferTracker returned invalid token.");
    }
    const uint32_t tokenValue = token->get();
    auto shimbuffer = ndk::SharedRefBase::make<ShimBuffer>(mNnapi.get(), dimensions, *type,
                                                           std::move(memory), std::move(token));
    buffer->buffer = std::move(shimbuffer);
    buffer->token = tokenValue;

    return ndk::ScopedAStatus::ok();
}

ndk::ScopedAStatus ShimDevice::getCapabilities(Capabilities* capabilities) {
    *capabilities = mCapabilities;
    return ndk::ScopedAStatus::ok();
}

ndk::ScopedAStatus ShimDevice::getNumberOfCacheFilesNeeded(NumberOfCacheFiles* numberOfCacheFiles) {
    *numberOfCacheFiles = mNumberOfCacheFiles;
    return ndk::ScopedAStatus::ok();
}

ndk::ScopedAStatus ShimDevice::getSupportedExtensions(std::vector<Extension>* extensions) {
    *extensions = mExtensions;
    return ndk::ScopedAStatus::ok();
}

ndk::ScopedAStatus ShimDevice::getSupportedOperations(const Model& model,
                                                      std::vector<bool>* supportedOperations) {
    const auto numOperations = model.main.operations.size();
    supportedOperations->resize(numOperations);

    ErrorStatus convertErrorStatus = ErrorStatus::NONE;
    std::vector<uint8_t> copiedOperandValues;
    auto modelAndMemory =
            convertFromHAL(mNnapi.get(), model, &copiedOperandValues, &convertErrorStatus);
    if (!modelAndMemory || modelAndMemory->models.empty()) {
        LOG(ERROR) << "Failed to convert HAL model to SL model";
        return toAStatus(convertErrorStatus);
    }

    auto annModel = modelAndMemory->models[0].getHandle();
    auto supportedOps = std::make_unique<bool[]>(numOperations);

    auto result = mNnapi->ANeuralNetworksModel_getSupportedOperationsForDevices(
            annModel, &mDevice, /*numDevices=*/1, supportedOps.get());
    SLW2SAS_RETURN_IF_ERROR(result);

    std::copy(supportedOps.get(), supportedOps.get() + numOperations, supportedOperations->begin());
    return ndk::ScopedAStatus::ok();
}

ndk::ScopedAStatus ShimDevice::getType(DeviceType* type) {
    int32_t deviceType;
    auto result = mNnapi->ANeuralNetworksDevice_getType(mDevice, &deviceType);
    SLW2SAS_RETURN_IF_ERROR(result);
    *type = static_cast<DeviceType>(deviceType);
    return ndk::ScopedAStatus::ok();
}

ndk::ScopedAStatus ShimDevice::getVersionString(std::string* versionString) {
    const char* buffer;
    auto result = mNnapi->ANeuralNetworksDevice_getVersion(mDevice, &buffer);
    SLW2SAS_RETURN_IF_ERROR(result);

    *versionString = std::string(buffer);
    return ndk::ScopedAStatus::ok();
}

static std::vector<int> getIntFds(const std::vector<::ndk::ScopedFileDescriptor>& scopedFds) {
    std::vector<int> fds;
    fds.reserve(scopedFds.size());
    for (const auto& scopedFd : scopedFds) {
        fds.push_back(scopedFd.get());
    }
    return fds;
}

ndk::ScopedAStatus ShimDevice::prepareModel(
        const Model& model, ExecutionPreference preference, Priority priority, int64_t deadlineNs,
        const std::vector<::ndk::ScopedFileDescriptor>& modelCache,
        const std::vector<::ndk::ScopedFileDescriptor>& dataCache,
        const std::vector<uint8_t>& token,
        const std::shared_ptr<IPreparedModelCallback>& callback) {
    // TODO(183398748): Run model preparation in detached thread.
    if (callback == nullptr) {
        return toAStatus(ErrorStatus::INVALID_ARGUMENT);
    }

    auto ndkPreference = convertToNDKPreference(preference);
    if (!ndkPreference) {
        callback->notify(ErrorStatus::INVALID_ARGUMENT, nullptr);
        return toAStatus(ErrorStatus::INVALID_ARGUMENT);
    }
    auto ndkPriority = convertToNDKPriority(priority);
    if (!ndkPriority) {
        callback->notify(ErrorStatus::INVALID_ARGUMENT, nullptr);
        return toAStatus(ErrorStatus::INVALID_ARGUMENT);
    }

    ErrorStatus convertErrorStatus = ErrorStatus::NONE;
    std::vector<uint8_t> copiedOperandValues;
    auto modelAndMemory =
            convertFromHAL(mNnapi.get(), model, &copiedOperandValues, &convertErrorStatus);

    if (!modelAndMemory || modelAndMemory->models.empty()) {
        callback->notify(ErrorStatus::INVALID_ARGUMENT, nullptr);
        return toAStatus(convertErrorStatus);
    }

    // b/185976051, past this point we pretend that compilation is asynchronous, and in
    /// case of error we return OK status, but communicate the error through the callback.
    auto compilation = ::android::nn::sl_wrapper::Compilation::createForDevice(
            mNnapi.get(), &modelAndMemory->models[0], mDevice);

    SLW2SAS_OK_RETURN_AND_ERROR_CALLBACK_IF_ERROR(compilation.first, callback);
    SLW2SAS_OK_RETURN_AND_ERROR_CALLBACK_IF_ERROR(compilation.second.setPreference(*ndkPreference),
                                                  callback);
    SLW2SAS_OK_RETURN_AND_ERROR_CALLBACK_IF_ERROR(compilation.second.setPriority(*ndkPriority),
                                                  callback);
    if (deadlineNs > -1) {
        std::chrono::time_point<::android::base::boot_clock> deadlinePoint(
                std::chrono::nanoseconds{deadlineNs});
        const auto currentTime = ::android::base::boot_clock::now();
        const auto timeoutDuration = std::chrono::nanoseconds(deadlinePoint - currentTime);
        if (timeoutDuration <= std::chrono::nanoseconds::zero()) {
            callback->notify(ErrorStatus::MISSED_DEADLINE_TRANSIENT, nullptr);
            return ndk::ScopedAStatus::ok();
        }
        SLW2SAS_OK_RETURN_AND_ERROR_CALLBACK_IF_ERROR(
                compilation.second.setTimeout(std::max<uint64_t>(1, timeoutDuration.count())),
                callback);
    }
    if (!modelCache.empty() || !dataCache.empty()) {
        SLW2SAS_OK_RETURN_AND_ERROR_CALLBACK_IF_ERROR(
                compilation.second.setCachingFromFds(getIntFds(modelCache), getIntFds(dataCache),
                                                     token),
                callback);
    }
    SLW2SAS_OK_RETURN_AND_ERROR_CALLBACK_IF_ERROR(compilation.second.finish(), callback);

    const std::shared_ptr<ShimPreparedModel> preparedModel =
            ndk::SharedRefBase::make<ShimPreparedModel>(
                    mNnapi, mBufferTracker, std::move(compilation.second),
                    std::move(modelAndMemory->models), std::move(modelAndMemory->memory),
                    std::move(copiedOperandValues));

    callback->notify(ErrorStatus::NONE, preparedModel);
    return ndk::ScopedAStatus::ok();
}

ndk::ScopedAStatus ShimDevice::prepareModelFromCache(
        int64_t /*deadlineNs*/, const std::vector<::ndk::ScopedFileDescriptor>& /*modelCache*/,
        const std::vector<::ndk::ScopedFileDescriptor>& /*dataCache*/,
        const std::vector<uint8_t>& /*token*/,
        const std::shared_ptr<IPreparedModelCallback>& callback) {
    // The NNAPI runtime will attempt to call this before falling back to
    // ShimDevice::prepareModel(). This is not a LOG(ERROR) to avoid producing
    // misleading logcat messages on every compilation request because there is
    // technically nothing wrong.
    LOG(DEBUG) << "ShimDevice::prepareModelFromCache() is not supported. Use "
                  "ShimDevice::prepareModel() instead.";
    const auto ret = callback->notify(ErrorStatus::GENERAL_FAILURE, nullptr);
    return toAStatus(ErrorStatus::GENERAL_FAILURE);
}

}  // namespace aidl::android::hardware::neuralnetworks
