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_adapter.h"
17 
18 #include "communication_adapter/include/sa_async_handler.h"
19 #include "communication_adapter/include/sa_client.h"
20 #include "platform/time/include/time.h"
21 #include "protocol/retcode_inner/aie_retcode_inner.h"
22 #include "utils/constants/constants.h"
23 #include "utils/log/aie_log.h"
24 
25 namespace OHOS {
26 namespace AI {
27 namespace {
28     const char * const CONNECT_MANAGER_WORKER_NAME = "ConnectMgrWorker";
29     const int CLIENT_RECONNECTION_INTERVAL = 10;
30 }
31 
ConnectMgrWorker(const ConfigInfo & configInfo,ClientInfo & clientInfo)32 ConnectMgrWorker::ConnectMgrWorker(const ConfigInfo &configInfo, ClientInfo &clientInfo)
33     : configInfo_(configInfo), clientInfo_(clientInfo)
34 {
35 }
36 
GetName() const37 const char *ConnectMgrWorker::GetName() const
38 {
39     return CONNECT_MANAGER_WORKER_NAME;
40 }
41 
OneAction()42 bool ConnectMgrWorker::OneAction()
43 {
44     SaClientAdapter *clientAdapter = SaClientAdapter::GetInstance();
45     if (clientAdapter == nullptr) {
46         HILOGE("[SaClientAdapter][ThreadName:%s, ThreadId:0x%lx]Fail to SaClientAdapter::GetInstance",
47             GetName(), GetThreadId());
48         return false;
49     }
50     if (clientAdapter->GetClientId() != INVALID_CLIENT_ID) {
51         StepSleepMs(CLIENT_RECONNECTION_INTERVAL);
52         return true;
53     }
54 
55     SaClient *client = SaClient::GetInstance();
56     if (client == nullptr) {
57         HILOGE("[SaClientAdapter][ThreadName:%s, ThreadId:0x%lx]Fail to SaClient::GetInstance",
58             GetName(), GetThreadId());
59         return false;
60     }
61 
62     int retCode = client->Init(configInfo_, clientInfo_);
63     if (retCode != RETCODE_SUCCESS || clientInfo_.clientId == INVALID_CLIENT_ID) {
64         HILOGE("[SaClientAdapter][ThreadName:%s, ThreadId:0x%lx]Fail to Init to server. errorCode:%d",
65             GetName(), GetThreadId(), retCode);
66         StepSleepMs(CLIENT_RECONNECTION_INTERVAL);
67         return true;
68     }
69     clientAdapter->SetClientId(clientInfo_.clientId);
70     clientAdapter->SetServerUid(clientInfo_.serverUid);
71     return true;
72 }
73 
Initialize()74 bool ConnectMgrWorker::Initialize()
75 {
76     return true;
77 }
78 
Uninitialize()79 void ConnectMgrWorker::Uninitialize()
80 {
81     SaClient *client = SaClient::GetInstance();
82     if (client == nullptr) {
83         HILOGE("[SaClientAdapter][ThreadName:%s, ThreadId:0x%lx]UnInitialize, fail to SaClient::GetInstance.",
84             GetName(), GetThreadId());
85         return;
86     }
87 
88     SaClientAdapter *clientAdapter = SaClientAdapter::GetInstance();
89     if (clientAdapter == nullptr) {
90         HILOGE("[SaClientAdapter][ThreadName:%s, ThreadId:0x%lx]UnInitialize fail to GetInstance",
91             GetName(), GetThreadId());
92         return;
93     }
94     int retCode = client->Destroy(clientInfo_);
95     if (retCode != RETCODE_SUCCESS) {
96         HILOGE("[SaClientAdapter][ThreadName:%s, ThreadId:0x%lx]UnInitialize, fail to Destroy.",
97             GetName(), GetThreadId());
98     }
99     clientAdapter->SetClientId(INVALID_CLIENT_ID);
100 }
101 
102 std::mutex SaClientAdapter::instance_mutex_;
103 SaClientAdapter *SaClientAdapter::instance_ = nullptr;
104 
105 SaClientAdapter::SaClientAdapter() = default;
106 
107 SaClientAdapter::~SaClientAdapter() = default;
108 
GetInstance()109 SaClientAdapter *SaClientAdapter::GetInstance()
110 {
111     CHK_RET(instance_ != nullptr, instance_);
112     std::lock_guard<std::mutex> lock(instance_mutex_);
113     CHK_RET(instance_ != nullptr, instance_);
114     AIE_NEW(instance_, SaClientAdapter);
115     return instance_;
116 }
117 
ReleaseInstance()118 void SaClientAdapter::ReleaseInstance()
119 {
120     std::lock_guard<std::mutex> lock(instance_mutex_);
121     AIE_DELETE(instance_);
122 }
123 
InitAiServer(const ConfigInfo & configInfo,ClientInfo & clientInfo,const AlgorithmInfo & algorithmInfo)124 int SaClientAdapter::InitAiServer(const ConfigInfo &configInfo, ClientInfo &clientInfo,
125     const AlgorithmInfo &algorithmInfo)
126 {
127     HILOGI("[SaClientAdapter]Begin to call InitAiServer.");
128     ThreadPool *threadPool = ThreadPool::GetInstance();
129     CHK_RET(threadPool == nullptr, RETCODE_OUT_OF_MEMORY);
130 
131     connectMgrThread_ = threadPool->Pop();
132     CHK_RET(connectMgrThread_ == nullptr, RETCODE_OUT_OF_MEMORY);
133 
134     AIE_NEW(connectMgrWorker_, ConnectMgrWorker(configInfo, clientInfo));
135     if (connectMgrWorker_ == nullptr) {
136         threadPool->Push(connectMgrThread_);
137         connectMgrThread_ = nullptr;
138         return RETCODE_OUT_OF_MEMORY;
139     }
140 
141     bool startSuccess = connectMgrThread_->StartThread(connectMgrWorker_);
142     if (!startSuccess) {
143         HILOGE("[SaClientAdapter]Fail to start thread.");
144         threadPool->Push(connectMgrThread_);
145         connectMgrThread_ = nullptr;
146         AIE_DELETE(connectMgrWorker_);
147         return RETCODE_START_THREAD_FAILED;
148     }
149     return RETCODE_SUCCESS;
150 }
151 
CloseAiServer()152 int SaClientAdapter::CloseAiServer()
153 {
154     HILOGI("[SaClientAdapter]Begin to call CloseAiServer.");
155     if (connectMgrThread_ == nullptr) {
156         HILOGW("[SaClientAdapter]Server has already been stopped, there is no need to close.");
157         return RETCODE_FAILURE;
158     }
159     connectMgrThread_->StopThread();
160     ThreadPool *threadPool = ThreadPool::GetInstance();
161     CHK_RET(threadPool == nullptr, RETCODE_OUT_OF_MEMORY);
162     threadPool->Push(connectMgrThread_);
163     AIE_DELETE(connectMgrWorker_);
164     connectMgrThread_ = nullptr;
165     return RETCODE_SUCCESS;
166 }
167 
LoadAlgorithm(const ClientInfo & clientInfo,const AlgorithmInfo & algorithmInfo,const DataInfo & inputInfo,DataInfo & outputInfo)168 int SaClientAdapter::LoadAlgorithm(const ClientInfo &clientInfo, const AlgorithmInfo &algorithmInfo,
169     const DataInfo &inputInfo, DataInfo &outputInfo)
170 {
171     HILOGI("[SaClientAdapter]Begin to call LoadAlgorithm.");
172     SaClient *saClient = SaClient::GetInstance();
173     CHK_RET(saClient == nullptr, RETCODE_NULL_PARAM);
174     SaAsyncHandler *saAsyncHandler = SaAsyncHandler::GetInstance();
175     CHK_RET(saAsyncHandler == nullptr, RETCODE_OUT_OF_MEMORY);
176     if (algorithmInfo.isAsync && saAsyncHandler->GetAsyncCbSize() == 1) {
177         int retCode = saClient->RegisterCallback(clientInfo);
178         if (retCode != RETCODE_SUCCESS) {
179             HILOGE("[SaClientAdapter]Fail to RegisterServerCb. errCode:%d", retCode);
180             return RETCODE_FAILURE;
181         }
182     }
183     return saClient->LoadAlgorithm(clientInfo, algorithmInfo, inputInfo, outputInfo);
184 }
185 
UnLoadAlgorithm(const ClientInfo & clientInfo,const AlgorithmInfo & algorithmInfo,const DataInfo & inputInfo)186 int SaClientAdapter::UnLoadAlgorithm(const ClientInfo &clientInfo, const AlgorithmInfo &algorithmInfo,
187     const DataInfo &inputInfo)
188 {
189     HILOGI("[SaClientAdapter]Begin to call UnLoadAlgorithm.");
190     SaClient *client = SaClient::GetInstance();
191     CHK_RET(client == nullptr, RETCODE_NULL_PARAM);
192     SaAsyncHandler *saAsyncHandler = SaAsyncHandler::GetInstance();
193     CHK_RET(saAsyncHandler == nullptr, RETCODE_NULL_PARAM);
194     if (algorithmInfo.isAsync && saAsyncHandler->IsCallbackEmpty()) {
195         int retCode = client->UnregisterCallback(clientInfo);
196         if (retCode != RETCODE_SUCCESS) {
197             HILOGE("[SaClientAdapter]Fail to RegisterServerCb. errCode:%d", retCode);
198             return RETCODE_FAILURE;
199         }
200     }
201 
202     return client->UnloadAlgorithm(clientInfo, algorithmInfo, inputInfo);
203 }
204 
SyncExecute(const ClientInfo & clientInfo,const AlgorithmInfo & algorithmInfo,const DataInfo & inputInfo,DataInfo & outputInfo)205 int SaClientAdapter::SyncExecute(const ClientInfo &clientInfo, const AlgorithmInfo &algorithmInfo,
206     const DataInfo &inputInfo, DataInfo &outputInfo)
207 {
208     HILOGI("[SaClientAdapter]Begin to call SyncExecute.");
209     SaClient *client = SaClient::GetInstance();
210     CHK_RET(client == nullptr, RETCODE_NULL_PARAM);
211 
212     return client->SyncExecuteAlgorithm(clientInfo, algorithmInfo, inputInfo, outputInfo);
213 }
214 
AsyncExecute(const ClientInfo & clientInfo,const AlgorithmInfo & algorithmInfo,const DataInfo & inputInfo)215 int SaClientAdapter::AsyncExecute(const ClientInfo &clientInfo, const AlgorithmInfo &algorithmInfo,
216     const DataInfo &inputInfo)
217 {
218     HILOGI("[SaClientAdapter]Begin to call AsyncExecute.");
219     SaClient *saClient = SaClient::GetInstance();
220     CHK_RET(saClient == nullptr, RETCODE_NULL_PARAM);
221     return saClient->AsyncExecuteAlgorithm(clientInfo, algorithmInfo, inputInfo);
222 }
223 
SetOption(const ClientInfo & clientInfo,int optionType,const DataInfo & inputInfo)224 int SaClientAdapter::SetOption(const ClientInfo &clientInfo, int optionType, const DataInfo &inputInfo)
225 {
226     HILOGI("[SaClientAdapter]Begin to call SetOption.");
227     SaClient *saClient = SaClient::GetInstance();
228     CHK_RET(saClient == nullptr, RETCODE_NULL_PARAM);
229     return saClient->SetOption(clientInfo, optionType, inputInfo);
230 }
231 
GetOption(const ClientInfo & clientInfo,int optionType,const DataInfo & inputInfo,DataInfo & outputInfo)232 int SaClientAdapter::GetOption(const ClientInfo &clientInfo, int optionType, const DataInfo &inputInfo,
233     DataInfo &outputInfo)
234 {
235     HILOGI("[SaClientAdapter]Begin to call GetOption.");
236     SaClient *saClient = SaClient::GetInstance();
237     CHK_RET(saClient == nullptr, RETCODE_NULL_PARAM);
238     return saClient->GetOption(clientInfo, optionType, inputInfo, outputInfo);
239 }
240 
GetClient()241 ClientFactory *GetClient()
242 {
243     return SaClientAdapter::GetInstance();
244 }
245 } // namespace AI
246 } // namespace OHOS
247