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_client.h"
17
18 #include "ipc_skeleton.h"
19
20 #include "communication_adapter/include/sa_client_proxy.h"
21 #include "platform/os_wrapper/ipc/include/aie_ipc.h"
22 #include "protocol/ipc_interface/ai_service.h"
23 #include "protocol/retcode_inner/aie_retcode_inner.h"
24 #include "utils/aie_macros.h"
25 #include "utils/constants/constants.h"
26 #include "utils/log/aie_log.h"
27
28 namespace OHOS {
29 namespace AI {
30 namespace {
AsyncCallback(uint32_t code,IpcIo * data,IpcIo * reply,MessageOption option)31 int32_t AsyncCallback(uint32_t code, IpcIo *data, IpcIo *reply, MessageOption option)
32 {
33 int asyncCallbackRet;
34 ReadInt32(data, &asyncCallbackRet);
35 int requestId;
36 ReadInt32(data, &requestId);
37 int sessionId;
38 ReadInt32(data, &sessionId);
39 DataInfo outputInfo = {
40 .data = nullptr,
41 .length = 0,
42 };
43 int ipcUnParcelRet = UnParcelDataInfo(data, &outputInfo);
44 SaClient *client = SaClient::GetInstance();
45 if (client == nullptr) {
46 HILOGE("[SaClient]The client is nullptr, maybe out of memory.");
47 FreeDataInfo(&outputInfo);
48 return RETCODE_FAILURE;
49 }
50 CallbackHandle callback = client->GetSaClientResultCb();
51 if (callback == nullptr) {
52 HILOGE("[SaClient]SA client callback is nullptr, maybe Release interface is called or the callback is deleted");
53 FreeDataInfo(&outputInfo);
54 return RETCODE_FAILURE;
55 }
56 // The asynchronous callback retCode is used only when the IPC is normal.
57 int retCode = asyncCallbackRet;
58 if (ipcUnParcelRet != RETCODE_SUCCESS) {
59 HILOGE("[SaClient]AsyncCallback failed, UnParcelDataInfo retCode[%d].", ipcUnParcelRet);
60 // The IPC is abnormal.
61 retCode = RETCODE_FAILURE;
62 }
63 callback(sessionId, outputInfo, retCode, requestId);
64 FreeDataInfo(&outputInfo);
65 return retCode;
66 }
67
OnAiDead(void * arg)68 void OnAiDead(void *arg)
69 {
70 SaClient *client = SaClient::GetInstance();
71 if (client == nullptr) {
72 HILOGE("[SaClient]callback is null.");
73 return;
74 }
75 DeathCallbackHandle onDead = client->GetSaDeathResultCb();
76 if (onDead == nullptr) {
77 HILOGE("[SaClient]Dead callback is null.");
78 return;
79 }
80 int clientId = *(reinterpret_cast<int *>(arg));
81 HILOGW("[SaClient]OnAiDead for [clientId:%d].", clientId);
82 onDead();
83 }
84 } // anonymous namespaces
85
86 std::mutex SaClient::instance_mutex_;
87 SaClient *SaClient::instance_ = nullptr;
88
89 SaClient::SaClient() = default;
90
91 SaClient::~SaClient() = default;
92
GetInstance()93 SaClient *SaClient::GetInstance()
94 {
95 CHK_RET(instance_ != nullptr, instance_);
96
97 std::lock_guard<std::mutex> lock(instance_mutex_);
98 CHK_RET(instance_ != nullptr, instance_);
99
100 SaClient *tempInstance = nullptr;
101 AIE_NEW(tempInstance, SaClient);
102 CHK_RET(tempInstance == nullptr, nullptr);
103
104 instance_ = tempInstance;
105 return instance_;
106 }
107
ReleaseInstance()108 void SaClient::ReleaseInstance()
109 {
110 std::lock_guard<std::mutex> lock(instance_mutex_);
111 AIE_DELETE(instance_);
112 }
113
Init(const ConfigInfo & configInfo,ClientInfo & clientInfo)114 int SaClient::Init(const ConfigInfo &configInfo, ClientInfo &clientInfo)
115 {
116 HosInit();
117 proxy_ = GetRemoteIUnknown();
118 if (proxy_ == nullptr) {
119 HILOGE("[SaClient]Fail to get server proxy, server exception.");
120 return RETCODE_SA_SERVICE_EXCEPTION;
121 }
122
123 int retCode = InitSaEngine(*proxy_, configInfo, clientInfo);
124 if (retCode != RETCODE_SUCCESS || clientInfo.clientId == INVALID_CLIENT_ID) {
125 HILOGE("[SaClient]InitServer result failed, clientId: %d, errorCode: [%d]", clientInfo.clientId, retCode);
126 ReleaseIUnknown(*((IUnknown *)proxy_));
127 proxy_ = nullptr;
128 return RETCODE_FAILURE;
129 }
130
131 // Register SA Death Callback
132 svc_ = SAMGR_GetRemoteIdentity(AI_SERVICE, nullptr);
133 int32_t resultCode = AddDeathRecipient(svc_, OnAiDead, &clientInfo.clientId, &deadId_);
134 if (resultCode != 0) {
135 HILOGE("[SaClient]Register SA Death Callback failed, errorCode[%d]", resultCode);
136 return RETCODE_FAILURE;
137 }
138 return RETCODE_SUCCESS;
139 }
140
LoadAlgorithm(const ClientInfo & clientInfo,const AlgorithmInfo & algorithmInfo,const DataInfo & inputInfo,DataInfo & outputInfo)141 int SaClient::LoadAlgorithm(const ClientInfo &clientInfo, const AlgorithmInfo &algorithmInfo,
142 const DataInfo &inputInfo, DataInfo &outputInfo)
143 {
144 if (proxy_ == nullptr) {
145 HILOGE("[SaClient]Service is nullptr, need reconnect server");
146 return RETCODE_SA_SERVICE_EXCEPTION;
147 }
148 return LoadAlgorithmProxy(*proxy_, clientInfo, algorithmInfo, inputInfo, outputInfo);
149 }
150
SyncExecuteAlgorithm(const ClientInfo & clientInfo,const AlgorithmInfo & algorithmInfo,const DataInfo & inputInfo,DataInfo & outputInfo)151 int SaClient::SyncExecuteAlgorithm(const ClientInfo &clientInfo, const AlgorithmInfo &algorithmInfo,
152 const DataInfo &inputInfo, DataInfo &outputInfo)
153 {
154 if (proxy_ == nullptr) {
155 HILOGE("[SaClient]Service is nullptr, need reconnect server.");
156 return RETCODE_SA_SERVICE_EXCEPTION;
157 }
158 return SyncExecAlgorithmProxy(*proxy_, clientInfo, algorithmInfo, inputInfo, outputInfo);
159 }
160
AsyncExecuteAlgorithm(const ClientInfo & clientInfo,const AlgorithmInfo & algorithmInfo,const DataInfo & inputInfo)161 int SaClient::AsyncExecuteAlgorithm(const ClientInfo &clientInfo, const AlgorithmInfo &algorithmInfo,
162 const DataInfo &inputInfo)
163 {
164 if (proxy_ == nullptr) {
165 HILOGE("[SaClient]Fail to get server proxy, retry to prepare.");
166 return RETCODE_SA_SERVICE_EXCEPTION;
167 }
168
169 return AsyncExecuteAlgorithmProxy(*proxy_, clientInfo, algorithmInfo, inputInfo);
170 }
171
UnloadAlgorithm(const ClientInfo & clientInfo,const AlgorithmInfo & algorithmInfo,const DataInfo & inputInfo)172 int SaClient::UnloadAlgorithm(const ClientInfo &clientInfo, const AlgorithmInfo &algorithmInfo,
173 const DataInfo &inputInfo)
174 {
175 if (proxy_ == nullptr) {
176 HILOGE("[SaClient]Service is nullptr, need reconnect server.");
177 return RETCODE_SA_SERVICE_EXCEPTION;
178 }
179
180 return UnloadAlgorithmProxy(*proxy_, clientInfo, algorithmInfo, inputInfo);
181 }
182
Destroy(const ClientInfo & clientInfo)183 int SaClient::Destroy(const ClientInfo &clientInfo)
184 {
185 if (proxy_ == nullptr) {
186 HILOGE("[SaClient]The proxy_ is nullptr. No need to destroy.");
187 return RETCODE_SA_SERVICE_EXCEPTION;
188 }
189
190 int retCode = DestroyEngineProxy(*proxy_, clientInfo);
191 (void)RemoveDeathRecipient(svc_, deadId_);
192 ReleaseIUnknown(*((IUnknown *)proxy_));
193 proxy_ = nullptr;
194 return retCode;
195 }
196
SetOption(const ClientInfo & clientInfo,int optionType,const DataInfo & inputInfo)197 int SaClient::SetOption(const ClientInfo &clientInfo, int optionType, const DataInfo &inputInfo)
198 {
199 if (proxy_ == nullptr) {
200 HILOGE("[SaClient]Service is nullptr. need reconnect server.");
201 return RETCODE_SA_SERVICE_EXCEPTION;
202 }
203 return SetOptionProxy(*proxy_, clientInfo, optionType, inputInfo);
204 }
205
GetOption(const ClientInfo & clientInfo,int optionType,const DataInfo & inputInfo,DataInfo & outputInfo)206 int SaClient::GetOption(const ClientInfo &clientInfo, int optionType, const DataInfo &inputInfo,
207 DataInfo &outputInfo)
208 {
209 if (proxy_ == nullptr) {
210 HILOGE("[SaClient]Service is nullptr. need reconnect server.");
211 return RETCODE_SA_SERVICE_EXCEPTION;
212 }
213 return GetOptionProxy(*proxy_, clientInfo, optionType, inputInfo, outputInfo);
214 }
215
RegisterCallback(const ClientInfo & clientInfo)216 int SaClient::RegisterCallback(const ClientInfo &clientInfo)
217 {
218 if (proxy_ == nullptr) {
219 HILOGE("[SaClient]The proxy_ is nullptr.");
220 return RETCODE_SA_SERVICE_EXCEPTION;
221 }
222
223 return RegisterCallbackProxy(*proxy_, clientInfo, AsyncCallback);
224 }
225
UnregisterCallback(const ClientInfo & clientInfo)226 int SaClient::UnregisterCallback(const ClientInfo &clientInfo)
227 {
228 if (proxy_ == nullptr) {
229 HILOGE("[SaClient]Service is nullptr, need reconnect server.");
230 return RETCODE_SA_SERVICE_EXCEPTION;
231 }
232
233 return UnregisterCallbackProxy(*proxy_, clientInfo);
234 }
235
RegisterSaClientCb(CallbackHandle resultCb)236 void SaClient::RegisterSaClientCb(CallbackHandle resultCb)
237 {
238 ResultCb_ = resultCb;
239 }
240
UnRegisterSaClientCb()241 void SaClient::UnRegisterSaClientCb()
242 {
243 ResultCb_ = nullptr;
244 }
245
GetSaClientResultCb()246 CallbackHandle SaClient::GetSaClientResultCb()
247 {
248 return ResultCb_;
249 }
250
RegisterSaDeathCb(DeathCallbackHandle deathCb)251 void SaClient::RegisterSaDeathCb(DeathCallbackHandle deathCb)
252 {
253 deathCb_ = deathCb;
254 }
255
UnRegisterSaDeathCb()256 void SaClient::UnRegisterSaDeathCb()
257 {
258 deathCb_ = nullptr;
259 }
260
GetSaDeathResultCb()261 DeathCallbackHandle SaClient::GetSaDeathResultCb()
262 {
263 return deathCb_;
264 }
265 } // namespace AI
266 } // namespace OHOS
267