f4b60bd9创建于 2021年4月17日历史提交
/*
 * Copyright (c) 2021 Huawei Device Co., Ltd.
 * 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 "communication_adapter/include/adapter_wrapper.h"

#include <cstring>
#include <map>

#include "communication_adapter/include/sa_async_handler.h"
#include "communication_adapter/include/sa_server_adapter.h"
#include "protocol/retcode_inner/aie_retcode_inner.h"
#include "utils/aie_macros.h"
#include "utils/constants/constants.h"
#include "utils/log/aie_log.h"

using namespace OHOS::AI;
namespace {
constexpr int STARTING_CLIENT_ID = 1;
constexpr int MAX_NUM_CLIENTS = 1024;
using ServerAdapters = std::map<int, SaServerAdapter*>;
ServerAdapters g_saServerAdapters;
std::atomic<int> g_clientIdAtomic(0);
std::mutex g_serverAdapterMutex;
std::mutex g_connectMutex;

int FindValidClientId()
{
    if (g_saServerAdapters.size() > MAX_NUM_CLIENTS) {
        HILOGE("[AdapterWrapper]Num of valid clients reaches max.");
        return INVALID_CLIENT_ID;
    }

    do {
        ++g_clientIdAtomic;
        if (g_clientIdAtomic < STARTING_CLIENT_ID) {
            HILOGI("[AdapterWrapper]Client id reaches max, reset to starting value [%d].", STARTING_CLIENT_ID);
            g_clientIdAtomic = STARTING_CLIENT_ID;
        }
    } while (g_saServerAdapters.find(g_clientIdAtomic) != g_saServerAdapters.end());

    return g_clientIdAtomic;
}

int AllocateClientAdapter()
{
    SaServerAdapter *adapter = nullptr;
    AIE_NEW(adapter, SaServerAdapter(g_clientIdAtomic));
    if (adapter == nullptr) {
        HILOGE("[AdapterWrapper]Failed to new adapter.");
        return INVALID_CLIENT_ID;
    }

    int clientId = adapter->GetAdapterId();

    std::lock_guard<std::mutex> guard(g_serverAdapterMutex);
    g_saServerAdapters[clientId] = adapter;
    return clientId;
}
}

class AdapterWrapper {
public:
    explicit AdapterWrapper(SaServerAdapter *adapter) : adapter_(adapter)
    {
        if (adapter_) {
            adapter_->IncRef();
        }
    }

    ~AdapterWrapper()
    {
        if (adapter_) {
            adapter_->DecRef();
            adapter_ = nullptr;
        }
    }

private:
    SaServerAdapter *adapter_ = nullptr;
};

SaServerAdapter* FindAdapter(const int clientId)
{
    std::lock_guard<std::mutex> guard(g_serverAdapterMutex);
    ServerAdapters::iterator iter = g_saServerAdapters.find(clientId);
    if (iter != g_saServerAdapters.end()) {
        return iter->second;
    }
    return nullptr;
}

int GenerateClient()
{
    HILOGI("[AdapterWrapper]Begin to call GenerateClient.");
    std::lock_guard<std::mutex> guard(g_connectMutex);

    if (FindValidClientId() == INVALID_CLIENT_ID) {
        return INVALID_CLIENT_ID;
    }

    return AllocateClientAdapter();
}

int SyncExecAlgoWrapper(const ClientInfo *clientInfo, const AlgorithmInfo *algoInfo, const DataInfo *inputInfo,
    DataInfo *outputInfo)
{
    HILOGI("[AdapterWrapper]Begin to call SyncExecAlgoWrapper.");
    if (clientInfo == nullptr || algoInfo == nullptr) {
        HILOGE("[AdapterWrapper]The clientInfo or algoInfo is nullptr");
        return RETCODE_NULL_PARAM;
    }

    if (algoInfo->isAsync) {
        HILOGW("[AdapterWrapper]SyncExecute but the algoInfo is AsyncExecute");
        return RETCODE_WRONG_INFER_MODE;
    }

    SaServerAdapter *adapter = FindAdapter(clientInfo->clientId);
    if (adapter == nullptr) {
        HILOGE("[AdapterWrapper]No adapter found for client[%d].", clientInfo->clientId);
        return RETCODE_NO_CLIENT_FOUND;
    }

    AdapterWrapper adapterGuard(adapter);
    return adapter->SyncExecute(*clientInfo, *algoInfo, *inputInfo, *outputInfo);
}

int AsyncExecAlgoWrapper(const ClientInfo *clientInfo, const AlgorithmInfo *algoInfo, const DataInfo *inputInfo)
{
    HILOGI("[AdapterWrapper]Begin to call AsyncExecAlgoWrapper.");
    if (clientInfo == nullptr || algoInfo == nullptr) {
        HILOGE("[AdapterWrapper]The clientInfo or algoInfo is nullptr.");
        return RETCODE_NULL_PARAM;
    }

    if (!algoInfo->isAsync) {
        HILOGW("[AdapterWrapper]AsyncExecute but the algoInfo is SyncExecute.");
        return RETCODE_WRONG_INFER_MODE;
    }

    SaServerAdapter *adapter = FindAdapter(clientInfo->clientId);
    if (adapter == nullptr) {
        HILOGE("[AdapterWrapper]No adapter found for client[%d].", clientInfo->clientId);
        return RETCODE_NO_CLIENT_FOUND;
    }
    AdapterWrapper adapterGuard(adapter);

    return adapter->AsyncExecute(*clientInfo, *algoInfo, *inputInfo);
}

int LoadAlgoWrapper(const ClientInfo *clientInfo, const AlgorithmInfo *algoInfo, const DataInfo *inputInfo,
    DataInfo *outputInfo)
{
    HILOGI("[AdapterWrapper]Begin to call LoadAlgoWrapper.");
    if (clientInfo == nullptr || algoInfo == nullptr) {
        HILOGE("[AdapterWrapper]The clientInfo or algoInfo is null");
        return RETCODE_NULL_PARAM;
    }

    SaServerAdapter *adapter = FindAdapter(clientInfo->clientId);
    if (adapter == nullptr) {
        HILOGE("[AdapterWrapper]No adapter found for client[%d].", clientInfo->clientId);
        return RETCODE_NO_CLIENT_FOUND;
    }

    AdapterWrapper adapterGuard(adapter);
    long long transactionId = adapter->GetTransactionId(clientInfo->sessionId);
    int retCode = adapter->LoadAlgorithm(transactionId, *algoInfo, *inputInfo, *outputInfo);
    if (retCode != RETCODE_SUCCESS) {
        HILOGE("[AdapterWrapper][transactionId:%lld]Failed to load algorithm, retCode[%d], aid[%d].",
            transactionId, retCode, algoInfo->algorithmType);
        return retCode;
    }

    if (algoInfo->isAsync) {
        SaAsyncHandler *saAsyncHandler = SaAsyncHandler::GetInstance();
        CHK_RET(saAsyncHandler == nullptr, RETCODE_NULL_PARAM);
        retCode = saAsyncHandler->StartAsyncTransaction(transactionId, clientInfo->clientId);
        HILOGI("[AdapterWrapper]StartAsyncTransaction retCode is [%d].", retCode);
    }
    return retCode;
}

int UnloadAlgoWrapper(const ClientInfo *clientInfo, const AlgorithmInfo *algoInfo, const DataInfo *inputInfo)
{
    HILOGI("[AdapterWrapper]Begin to call UnloadAlgoWrapper.");
    SaServerAdapter *adapter = FindAdapter(clientInfo->clientId);
    if (adapter == nullptr) {
        HILOGE("[AdapterWrapper]No adapter found for client[%d].", clientInfo->clientId);
        return RETCODE_NO_CLIENT_FOUND;
    }

    AdapterWrapper adapterGuard(adapter);
    long long transactionId = adapter->GetTransactionId(clientInfo->sessionId);
    if (algoInfo == nullptr) {
        HILOGE("[AdapterWrapper]AlgoInfo is nullptr.");
        return RETCODE_NULL_PARAM;
    }
    if (algoInfo->isAsync) {
        SaAsyncHandler *saAsyncHandler = SaAsyncHandler::GetInstance();
        if (saAsyncHandler != nullptr) {
            saAsyncHandler->StopAsyncTransaction(transactionId);
        }
    }

    return adapter->UnloadAlgorithm(transactionId, *inputInfo);
}

int RemoveAdapterWrapper(const ClientInfo *clientInfo)
{
    HILOGI("[AdapterWrapper]Begin to call RemoveAdapterWrapper.");
    std::lock_guard<std::mutex> guard(g_serverAdapterMutex);
    ServerAdapters::iterator iter = g_saServerAdapters.find(clientInfo->clientId);
    if (iter == g_saServerAdapters.end()) {
        HILOGE("[AdapterWrapper]Failed to find serverAdapter for client[%d].", clientInfo->clientId);
        return RETCODE_FAILURE;
    }

    AIE_DELETE(iter->second);
    g_saServerAdapters.erase(iter);
    return RETCODE_SUCCESS;
}

int SetOptionWrapper(const ClientInfo *clientInfo, int optionType, const DataInfo *inputInfo)
{
    HILOGI("[AdapterWrapper]Begin to call SetOptionWrapper.");
    SaServerAdapter *adapter = FindAdapter(clientInfo->clientId);
    if (adapter == nullptr) {
        HILOGE("[AdapterWrapper]No adapter found for client[%d].", clientInfo->clientId);
        return RETCODE_NO_CLIENT_FOUND;
    }

    AdapterWrapper adapterGuard(adapter);
    long long transactionId = adapter->GetTransactionId(clientInfo->sessionId);
    return adapter->SetOption(transactionId, optionType, *inputInfo);
}

int GetOptionWrapper(const ClientInfo *clientInfo, int optionType, const DataInfo *inputInfo, DataInfo *outputInfo)
{
    HILOGI("[AdapterWrapper]Begin to call GetOptionWrapper.");
    if (clientInfo == nullptr) {
        HILOGE("[AdapterWrapper]ClientInfo is nullptr.");
        return RETCODE_NULL_PARAM;
    }
    SaServerAdapter *adapter = FindAdapter(clientInfo->clientId);
    if (adapter == nullptr) {
        HILOGE("[AdapterWrapper]No adapter found for client[%d].", clientInfo->clientId);
        return RETCODE_NO_CLIENT_FOUND;
    }

    AdapterWrapper adapterGuard(adapter);
    long long transactionId = adapter->GetTransactionId(clientInfo->sessionId);
    return adapter->GetOption(transactionId, optionType, *inputInfo, *outputInfo);
}

int RegisterCallbackWrapper(const ClientInfo *clientInfo, SvcIdentity *sid)
{
    HILOGI("[AdapterWrapper]Begin to call RegisterCallbackWrapper.");
    SaServerAdapter *adapter = FindAdapter(clientInfo->clientId);
    if (adapter == nullptr) {
        HILOGE("[AdapterWrapper]No adapter found for client[%d].", clientInfo->clientId);
        return RETCODE_NO_CLIENT_FOUND;
    }
    AdapterWrapper adapterGuard(adapter);

    adapter->SaveEngineListener(sid);

    SaAsyncHandler *saAsyncHandler = SaAsyncHandler::GetInstance();
    CHK_RET(saAsyncHandler == nullptr, RETCODE_NULL_PARAM);
    int retCode = saAsyncHandler->RegisterAsyncHandler(clientInfo->clientId);
    if (retCode != RETCODE_SUCCESS) {
        HILOGE("[AdapterWrapper]Client[%d] session[%d] RegisterAsyncHandler result is [%d].", clientInfo->clientId,
            clientInfo->sessionId, retCode);
        return retCode;
    }

    return saAsyncHandler->StartAsyncProcess(clientInfo->clientId, adapter);
}

int UnregisterCallbackWrapper(const ClientInfo *clientInfo)
{
    HILOGI("[AdapterWrapper]Begin to call UnregisterCallbackWrapper.");
    SaServerAdapter *adapter = FindAdapter(clientInfo->clientId);
    if (adapter == nullptr) {
        HILOGE("[AdapterWrapper]No adapter found for client[%d].", clientInfo->clientId);
        return RETCODE_NO_CLIENT_FOUND;
    }

    AdapterWrapper adapterGuard(adapter);
    SaAsyncHandler *saAsyncHandler = SaAsyncHandler::GetInstance();
    CHK_RET(saAsyncHandler == nullptr, RETCODE_NULL_PARAM);
    saAsyncHandler->StopAsyncProcess(clientInfo->clientId);
    adapter->ClearEngineListener();
    return RETCODE_SUCCESS;
}