1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "communication_adapter/include/sa_server_adapter.h"
17 
18 #include "ipc_skeleton.h"
19 #include "securec.h"
20 
21 #include "protocol/retcode_inner/aie_retcode_inner.h"
22 #include "server_executor/include/i_async_task_manager.h"
23 #include "server_executor/include/i_engine_manager.h"
24 #include "server_executor/include/i_sync_task_manager.h"
25 #include "utils/aie_guard.h"
26 #include "utils/log/aie_log.h"
27 
28 namespace OHOS {
29 namespace AI {
30 namespace {
31 const unsigned int ADAPT_ID_BIT = 32U;
32 const int INPUT_LENGTH_NULL = 0;
33 }
34 
SaServerAdapter(int adapterId)35 SaServerAdapter::SaServerAdapter(int adapterId) : adapterId_(adapterId), refCount_(0)
36 {
37 }
38 
~SaServerAdapter()39 SaServerAdapter::~SaServerAdapter()
40 {
41     Uninitialize();
42 }
43 
GetSessionId(long long transactionId) const44 int SaServerAdapter::GetSessionId(long long transactionId) const
45 {
46     return static_cast<int>(static_cast<unsigned long long>(transactionId) & TRANS_ID_MASK);
47 }
48 
GetAdapterId() const49 int SaServerAdapter::GetAdapterId() const
50 {
51     return adapterId_;
52 }
53 
IncRef()54 void SaServerAdapter::IncRef()
55 {
56     ++refCount_;
57 }
58 
DecRef()59 void SaServerAdapter::DecRef()
60 {
61     refCount_--;
62 }
63 
GetRefCount() const64 int SaServerAdapter::GetRefCount() const
65 {
66     return refCount_;
67 }
68 
Uninitialize()69 void SaServerAdapter::Uninitialize()
70 {
71     std::lock_guard<std::mutex> guard(mutex_);
72     IEngineManager* engineManager = GetEngineManager();
73     if (engineManager == nullptr) {
74         HILOGE("[SaServerAdapter]Failed to get engine manager.");
75         return;
76     }
77 
78     DataInfo inputInfo = {
79         .data = nullptr,
80         .length = INPUT_LENGTH_NULL,
81     };
82 
83     for (auto &item: transactionIds_) {
84         engineManager->StopEngine(item, inputInfo);
85     }
86     transactionIds_.clear();
87 }
88 
SaveEngineListener(SvcIdentity * svcIdentity)89 void SaServerAdapter::SaveEngineListener(SvcIdentity *svcIdentity)
90 {
91     svcIdentity_ = *svcIdentity;
92 }
93 
ClearEngineListener()94 void SaServerAdapter::ClearEngineListener()
95 {
96     ReleaseSvc(svcIdentity_);
97 }
98 
GetEngineListener()99 SvcIdentity *SaServerAdapter::GetEngineListener()
100 {
101     return &svcIdentity_;
102 }
103 
GetTransactionId(int sessionId) const104 long long SaServerAdapter::GetTransactionId(int sessionId) const
105 {
106     return static_cast<long long>(static_cast<unsigned long long>(adapterId_) << ADAPT_ID_BIT) + sessionId;
107 }
108 
AsyncExecute(const ClientInfo & clientInfo,const AlgorithmInfo & algoInfo,const DataInfo & inputInfo)109 int SaServerAdapter::AsyncExecute(const ClientInfo &clientInfo, const AlgorithmInfo &algoInfo,
110     const DataInfo &inputInfo)
111 {
112     IRequest *request = nullptr;
113     ConvertToRequest(clientInfo, algoInfo, inputInfo, request);
114     ResGuard<IRequest> guardReq(request);
115 
116     IAsyncTaskManager *asyncTaskManager = GetAsyncTaskManager();
117     if (asyncTaskManager == nullptr) {
118         HILOGE("[SaServerAdapter]Get async task manager fail, ret: %d, clientId: %d, sessionId: %d, algoType: %d.",
119             RETCODE_OUT_OF_MEMORY, clientInfo.clientId, clientInfo.sessionId, algoInfo.algorithmType);
120         return RETCODE_OUT_OF_MEMORY;
121     }
122 
123     int ret = asyncTaskManager->AsyncExecute(request);
124     if (ret != RETCODE_SUCCESS) {
125         HILOGE("[SaServerAdapter]Fail to get async execute request, ret is %d.", ret);
126         return ret;
127     }
128 
129     guardReq.Detach();
130     return RETCODE_SUCCESS;
131 }
132 
ConvertToRequest(const ClientInfo & clientInfo,const AlgorithmInfo & algoInfo,const DataInfo & inputInfo,IRequest * & request)133 void SaServerAdapter::ConvertToRequest(const ClientInfo &clientInfo, const AlgorithmInfo &algoInfo,
134     const DataInfo &inputInfo, IRequest *&request)
135 {
136     request = IRequest::Create();
137     if (request == nullptr) {
138         HILOGE("[SaServerAdapter]Fail to create request.");
139         return;
140     }
141     request->SetRequestId(algoInfo.requestId);
142     request->SetOperationId(algoInfo.operateId);
143     request->SetTransactionId(GetTransactionId(clientInfo.sessionId));
144     request->SetAlgoPluginType(algoInfo.algorithmType);
145     request->SetMsg(inputInfo);
146     request->SetClientUid(clientInfo.clientUid);
147 }
148 
LoadAlgorithm(long long transactionId,const AlgorithmInfo & algoInfo,const DataInfo & inputInfo,DataInfo & outputInfo)149 int SaServerAdapter::LoadAlgorithm(long long transactionId, const AlgorithmInfo &algoInfo,
150     const DataInfo &inputInfo, DataInfo &outputInfo)
151 {
152     IEngineManager *engineManager = GetEngineManager();
153     if (engineManager == nullptr) {
154         HILOGE("[SaServerAdapter][transactionId:%lld]Failed to get engine manager.", transactionId);
155         return RETCODE_OUT_OF_MEMORY;
156     }
157     int retCode = engineManager->StartEngine(transactionId, algoInfo, inputInfo, outputInfo);
158     if (retCode != RETCODE_SUCCESS) {
159         HILOGE("[SaServerAdapter][transactionId:%lld]Failed to load algorithm.", transactionId);
160         return retCode;
161     }
162 
163     SaveTransaction(transactionId);
164     return RETCODE_SUCCESS;
165 }
166 
SetOption(long long transactionId,int optionType,const DataInfo & dataInfo)167 int SaServerAdapter::SetOption(long long transactionId, int optionType, const DataInfo &dataInfo)
168 {
169     IEngineManager *engineManager = GetEngineManager();
170     if (engineManager == nullptr) {
171         HILOGE("[SaServerAdapter][transactionId:0x%llx]Failed to get engine manager.", transactionId);
172         return RETCODE_OUT_OF_MEMORY;
173     }
174 
175     return engineManager->SetOption(transactionId, optionType, dataInfo);
176 }
177 
GetOption(long long transactionId,int optionType,const DataInfo & dataInfo,DataInfo & outputInfo)178 int SaServerAdapter::GetOption(long long transactionId, int optionType, const DataInfo &dataInfo,
179     DataInfo &outputInfo)
180 {
181     IEngineManager *engineManager = GetEngineManager();
182     if (engineManager == nullptr) {
183         HILOGE("[SaServerAdapter][transactionId:0x%llx]Failed to get engine manager.", transactionId);
184         return RETCODE_OUT_OF_MEMORY;
185     }
186 
187     return engineManager->GetOption(transactionId, optionType, dataInfo, outputInfo);
188 }
189 
SaveTransaction(long long transactionId)190 void SaServerAdapter::SaveTransaction(long long transactionId)
191 {
192     std::lock_guard<std::mutex> guard(mutex_);
193     transactionIds_.insert(transactionId);
194 }
195 
UnloadAlgorithm(long long transactionId,const DataInfo & inputInfo)196 int SaServerAdapter::UnloadAlgorithm(long long transactionId, const DataInfo &inputInfo)
197 {
198     IEngineManager* engineInstance = GetEngineManager();
199     if (engineInstance == nullptr) {
200         HILOGE("[SaServerAdapter][transactionId:%lld]Failed to get engine manager.", transactionId);
201         return RETCODE_OUT_OF_MEMORY;
202     }
203     int retCode = engineInstance->StopEngine(transactionId, inputInfo);
204     if (retCode != RETCODE_SUCCESS) {
205         HILOGE("[SaServerAdapter][transactionId:%lld]Failed to unload algorithm.", transactionId);
206         return retCode;
207     }
208     RemoveTransaction(transactionId);
209     return RETCODE_SUCCESS;
210 }
211 
RemoveTransaction(long long transactionId)212 void SaServerAdapter::RemoveTransaction(long long transactionId)
213 {
214     std::lock_guard<std::mutex> guard(mutex_);
215     transactionIds_.erase(transactionId);
216 }
217 
SyncExecute(const ClientInfo & clientInfo,const AlgorithmInfo & algoInfo,const DataInfo & inputInfo,DataInfo & outputInfo)218 int SaServerAdapter::SyncExecute(const ClientInfo &clientInfo, const AlgorithmInfo &algoInfo,
219     const DataInfo &inputInfo, DataInfo &outputInfo)
220 {
221     IRequest *request = nullptr;
222     outputInfo.data = nullptr;
223     outputInfo.length = 0;
224     ConvertToRequest(clientInfo, algoInfo, inputInfo, request);
225     if (request == nullptr) {
226         HILOGE("[SaServer]Fail to ConvertToRequest.");
227         return RETCODE_OUT_OF_MEMORY;
228     }
229     ResGuard<IRequest> guardReq(request);
230     ISyncTaskManager *taskMgr = GetSyncTaskManager();
231     if (taskMgr == nullptr) {
232         HILOGE("[SaServerAdapter]Get task manager failed, ret is %d", RETCODE_OUT_OF_MEMORY);
233         return RETCODE_OUT_OF_MEMORY;
234     }
235     IResponse *response = nullptr;
236     int retCode = taskMgr->SyncExecute(request, response);
237     ResGuard<IResponse> guardRes(response);
238     if ((retCode != RETCODE_SUCCESS) || (response == nullptr)) {
239         HILOGE("[SaServerAdapter]Execute request failed, ret is %d", retCode);
240         return retCode;
241     }
242     outputInfo = response->GetResult();
243     response->Detach();
244 
245     return RETCODE_SUCCESS;
246 }
247 } // namespace AI
248 } // namespace OHOS
249