1 /*
2 * Copyright (c) 2024 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 "distributed_camera_allconnect_manager.h"
17
18 #include <cstdio>
19 #include <cstdlib>
20 #include <dlfcn.h>
21 #include <thread>
22
23 #include "dcamera_protocol.h"
24 #include "dcamera_softbus_adapter.h"
25 #include "distributed_hardware_log.h"
26 #include "distributed_camera_constants.h"
27 #include "distributed_camera_errno.h"
28
29 namespace OHOS {
30 namespace DistributedHardware {
31 #ifdef __LP64__
32 constexpr const char *ALL_CONNECT_SO_PATH = "/system/lib64/";
33 #else
34 constexpr const char *ALL_CONNECT_SO_PATH = "/system/lib/";
35 #endif
36 constexpr const char *ALL_CONNECT_SO_NAME = "libcfwk_allconnect_client.z.so";
37 std::shared_ptr<DCameraBlockObject<bool>> DCameraAllConnectManager::applyResultBlock_;
DCameraAllConnectManager()38 DCameraAllConnectManager::DCameraAllConnectManager()
39 {
40 allConnectCallback_.onStop = &DCameraAllConnectManager::OnStop;
41 allConnectCallback_.applyResult = &DCameraAllConnectManager::ApplyResult;
42 }
43
GetInstance()44 DCameraAllConnectManager &DCameraAllConnectManager::GetInstance()
45 {
46 static DCameraAllConnectManager instance;
47 return instance;
48 }
49
50 std::mutex DCameraAllConnectManager::netwkIdSourceSessionIdMapLock_;
51 std::map<std::string, int> DCameraAllConnectManager::netwkIdSourceSessionIdMap_;
52 std::mutex DCameraAllConnectManager::netwkIdSinkSessionIdMapLock_;
53 std::map<std::string, int> DCameraAllConnectManager::netwkIdSinkSessionIdMap_;
54 bool DCameraAllConnectManager::bInited_ = false;
55 std::mutex DCameraAllConnectManager::bInitedLock_;
56
InitDCameraAllConnectManager()57 int32_t DCameraAllConnectManager::InitDCameraAllConnectManager()
58 {
59 DHLOGI("DCamera allconnect InitDCameraAllConnectManager begin");
60 std::lock_guard<std::mutex> lock(bInitedLock_);
61 int32_t ret = GetAllConnectSoLoad();
62 if (ret != DistributedCameraErrno::DCAMERA_OK) {
63 DHLOGE("DCamera allconnect InitDCameraAllConnectManager failed, so not exist or load so error, ret %{public}d",
64 ret);
65 return ret;
66 }
67
68 DHLOGI("DCamera allconnect InitDCameraAllConnectManager success");
69 bInited_ = true;
70 return DistributedCameraErrno::DCAMERA_OK;
71 }
72
UnInitDCameraAllConnectManager()73 int32_t DCameraAllConnectManager::UnInitDCameraAllConnectManager()
74 {
75 DHLOGI("DCamera allconnect UnInitDCameraAllConnectManager begin");
76 std::lock_guard<std::mutex> lock(bInitedLock_);
77 if (dllHandle_ != nullptr) {
78 dlclose(dllHandle_);
79 }
80 dllHandle_ = nullptr;
81 bInited_ = false;
82 return DistributedCameraErrno::DCAMERA_OK;
83 }
84
IsInited()85 bool DCameraAllConnectManager::IsInited()
86 {
87 std::lock_guard<std::mutex> lock(bInitedLock_);
88 return bInited_;
89 }
90
PublishServiceState(const std::string & peerNetworkId,DCameraCollaborationBussinessStatus state)91 int32_t DCameraAllConnectManager::PublishServiceState(const std::string &peerNetworkId,
92 DCameraCollaborationBussinessStatus state)
93 {
94 DHLOGI("DCamera allconnect PublishServiceState begin");
95 std::lock_guard<std::mutex> lock(allConnectLock_);
96 if (dllHandle_ == nullptr) {
97 DHLOGE("DCamera allconnect dllHandle_ is nullptr, all connect not support.");
98 return DistributedCameraErrno::DCAMERA_OK;
99 }
100 if (allConnect_.dCameraCollaborationPublishServiceState == nullptr) {
101 DHLOGE("DCamera allconnect PublishServiceState is nullptr, all connect function not load.");
102 return DistributedCameraErrno::DCAMERA_ERR_DLOPEN;
103 }
104
105 int32_t ret = allConnect_.dCameraCollaborationPublishServiceState(peerNetworkId.c_str(),
106 SERVICE_NAME.c_str(),
107 "", state);
108 if (ret != DistributedCameraErrno::DCAMERA_OK) {
109 DHLOGE("DCamera allconnect PublishServiceState %{public}d fail, ret %{public}d", state, ret);
110 return DistributedCameraErrno::DCAMERA_ERR_PUBLISH_STATE;
111 }
112 return DistributedCameraErrno::DCAMERA_OK;
113 }
114
ApplyAdvancedResource(const std::string & peerNetworkId,DCameraCollaborationResourceRequestInfoSets * resourceRequest)115 int32_t DCameraAllConnectManager::ApplyAdvancedResource(const std::string &peerNetworkId,
116 DCameraCollaborationResourceRequestInfoSets *resourceRequest)
117 {
118 DHLOGI("DCamera allconnect ApplyAdvancedResource begin");
119 std::lock_guard<std::mutex> lock(allConnectLock_);
120 if (dllHandle_ == nullptr) {
121 DHLOGE("DCamera allconnect dllHandle_ is nullptr, all connect not support.");
122 return DistributedCameraErrno::DCAMERA_OK;
123 }
124 if (allConnect_.dCameraCollaborationApplyAdvancedResource == nullptr) {
125 DHLOGE("DCamera allconnect PublishServiceState is nullptr, all connect function not load.");
126 return DistributedCameraErrno::DCAMERA_ERR_DLOPEN;
127 }
128
129 if (applyResultBlock_ == nullptr) {
130 applyResultBlock_ = std::make_shared<DCameraBlockObject<bool>>(BLOCK_INTERVAL_ALLCONNECT, false);
131 }
132
133 int32_t ret = allConnect_.dCameraCollaborationApplyAdvancedResource(peerNetworkId.c_str(),
134 SERVICE_NAME.c_str(),
135 resourceRequest,
136 &allConnectCallback_);
137 if (ret != DistributedCameraErrno::DCAMERA_OK) {
138 DHLOGE("DCamera allconnect ApplyAdvancedResource fail, ret %{public}d", ret);
139 return DistributedCameraErrno::DCAMERA_ERR_APPLY_RESULT;
140 }
141 auto success = applyResultBlock_->GetValue();
142 if (!success) {
143 DHLOGE("DCamera allconnect applyResult is reject");
144 return DistributedCameraErrno::DCAMERA_ERR_APPLY_RESULT;
145 }
146 return DistributedCameraErrno::DCAMERA_OK;
147 }
148
GetAllConnectSoLoad()149 int32_t DCameraAllConnectManager::GetAllConnectSoLoad()
150 {
151 DHLOGI("DCamera allconnect GetAllConnectSoLoad begin");
152 std::lock_guard<std::mutex> lock(allConnectLock_);
153 char path[PATH_MAX + 1] = {0x00};
154 std::string soPathName = std::string(ALL_CONNECT_SO_PATH) + std::string(ALL_CONNECT_SO_NAME);
155 if (soPathName.empty() || (soPathName.length() > PATH_MAX) || (realpath(soPathName.c_str(), path) == nullptr)) {
156 DHLOGE("DCamera allconnect all connect so load failed, soPath=%{public}s not exist.", soPathName.c_str());
157 return DistributedCameraErrno::DCAMERA_ERR_DLOPEN;
158 }
159
160 int32_t (*allConnectProxy)(DCameraCollaborationApi *exportapi) = nullptr;
161
162 dllHandle_ = dlopen(path, RTLD_LAZY);
163 if (dllHandle_ == nullptr) {
164 DHLOGE("DCamera allconnect dlopen fail");
165 return DistributedCameraErrno::DCAMERA_ERR_DLOPEN;
166 }
167
168 allConnectProxy = reinterpret_cast<int32_t (*)(DCameraCollaborationApi *exportapi)>(
169 dlsym(dllHandle_, "ServiceCollaborationManager_Export"));
170 if (allConnectProxy == nullptr) {
171 dlclose(dllHandle_);
172 dllHandle_ = nullptr;
173 DHLOGE("DCamera allconnect dlsym allConnectProxy fail");
174 return DistributedCameraErrno::DCAMERA_ERR_DLOPEN;
175 }
176
177 int32_t ret = allConnectProxy(&allConnect_);
178 if (ret != DistributedCameraErrno::DCAMERA_OK) {
179 dlclose(dllHandle_);
180 dllHandle_ = nullptr;
181 DHLOGE("DCamera allconnect get function struct fail, ret %{public}d", ret);
182 return DistributedCameraErrno::DCAMERA_ERR_DLOPEN;
183 }
184 DHLOGI("DCamera allconnect so load success");
185 return DistributedCameraErrno::DCAMERA_OK;
186 }
187
RegisterLifecycleCallback()188 int32_t DCameraAllConnectManager::RegisterLifecycleCallback()
189 {
190 DHLOGI("DCamera allconnect RegisterLifecycleCallback begin");
191 std::lock_guard<std::mutex> lock(allConnectLock_);
192 if (dllHandle_ == nullptr) {
193 DHLOGE("DCamera allconnect dllHandle_ is nullptr, all connect so has not been loaded.");
194 return DistributedCameraErrno::DCAMERA_ERR_DLOPEN;
195 }
196 if (allConnect_.dCameraCollaborationRegisterLifecycleCallback == nullptr) {
197 DHLOGE("DCamera allconnect RegisterLifecycleCallback is nullptr, all connect function not load.");
198 return DistributedCameraErrno::DCAMERA_ERR_DLOPEN;
199 }
200
201 int32_t ret = allConnect_.dCameraCollaborationRegisterLifecycleCallback(SERVICE_NAME.c_str(),
202 &allConnectCallback_);
203 if (ret != DistributedCameraErrno::DCAMERA_OK) {
204 DHLOGE("DCamera allconnect RegisterLifecycleCallback fail, ret %{public}d", ret);
205 return DistributedCameraErrno::DCAMERA_ERR_ALLCONNECT;
206 }
207 return DistributedCameraErrno::DCAMERA_OK;
208 }
209
UnRegisterLifecycleCallback()210 int32_t DCameraAllConnectManager::UnRegisterLifecycleCallback()
211 {
212 DHLOGI("DCamera allconnect UnRegisterLifecycleCallback begin");
213 std::lock_guard<std::mutex> lock(allConnectLock_);
214 if (dllHandle_ == nullptr) {
215 DHLOGE("DCamera allconnect dllHandle_ is nullptr, all connect so has not been loaded.");
216 return DistributedCameraErrno::DCAMERA_ERR_DLOPEN;
217 }
218 if (allConnect_.dCameraCollaborationUnRegisterLifecycleCallback == nullptr) {
219 DHLOGE("DCamera allconnect RegisterLifecycleCallback is nullptr, all connect function not load.");
220 return DistributedCameraErrno::DCAMERA_ERR_DLOPEN;
221 }
222
223 int32_t ret = allConnect_.dCameraCollaborationUnRegisterLifecycleCallback(SERVICE_NAME.c_str());
224 if (ret != DistributedCameraErrno::DCAMERA_OK) {
225 DHLOGE("DCamera allconnect UnRegisterLifecycleCallback fail, ret %{public}d", ret);
226 return DistributedCameraErrno::DCAMERA_ERR_ALLCONNECT;
227 }
228 return DistributedCameraErrno::DCAMERA_OK;
229 }
230
ApplyResult(int32_t errorcode,int32_t result,const char * reason)231 int32_t DCameraAllConnectManager::ApplyResult(int32_t errorcode, int32_t result, const char *reason)
232 {
233 DHLOGI("DCamera allconnect ApplyResult begin");
234 if (result != PASS) {
235 DHLOGE("DCamera allconnect Apply Result is Reject, errorcode is %{}d, reason is %{public}s", errorcode, reason);
236 applyResultBlock_->SetValue(false);
237 return DistributedCameraErrno::DCAMERA_ERR_APPLY_RESULT;
238 }
239 applyResultBlock_->SetValue(true);
240 return DistributedCameraErrno::DCAMERA_OK;
241 }
242
OnStop(const char * peerNetworkId)243 int32_t DCameraAllConnectManager::OnStop(const char *peerNetworkId)
244 {
245 DHLOGI("DCamera allconnect OnStop begin peerNetworkId:%{public}s", peerNetworkId);
246 DCameraSoftbusAdapter::GetInstance().CloseSessionWithNetWorkId(peerNetworkId);
247
248 return DistributedCameraErrno::DCAMERA_OK;
249 }
250
BuildResourceRequest()251 std::shared_ptr<DCameraCollaborationResourceRequestInfoSets> DCameraAllConnectManager::BuildResourceRequest()
252 {
253 auto resourceRequest = std::make_shared<DCameraCollaborationResourceRequestInfoSets>();
254
255 if (remoteHardwareList_ == nullptr) {
256 remoteHardwareList_ = std::make_shared<DCameraCollaboration_HardwareRequestInfo>();
257 remoteHardwareList_->hardWareType = DCameraCollaborationHardwareType::SCM_CAMERA;
258 remoteHardwareList_->canShare = true;
259 }
260 resourceRequest->remoteHardwareListSize = 1;
261 resourceRequest->remoteHardwareList = remoteHardwareList_.get();
262
263 if (localHardwareList_ == nullptr) {
264 localHardwareList_ = std::make_shared<DCameraCollaboration_HardwareRequestInfo>();
265 localHardwareList_->hardWareType = DCameraCollaborationHardwareType::SCM_CAMERA;
266 localHardwareList_->canShare = true;
267 }
268 resourceRequest->localHardwareListSize = 1;
269 resourceRequest->localHardwareList = localHardwareList_.get();
270
271 if (communicationRequest_ == nullptr) {
272 communicationRequest_ = std::make_shared<DCameraCollaborationCommunicationRequestInfo>();
273 communicationRequest_->minBandwidth = DCAMERA_QOS_TYPE_MIN_BW;
274 communicationRequest_->maxLatency = DCAMERA_QOS_TYPE_MAX_LATENCY;
275 communicationRequest_->minLatency = DCAMERA_QOS_TYPE_MIN_LATENCY;
276 communicationRequest_->maxWaitTime = 0;
277 communicationRequest_->dataType = "DATA_TYPE_VIDEO_STREAM";
278 }
279 resourceRequest->communicationRequest = communicationRequest_.get();
280
281 return resourceRequest;
282 }
283
RemoveSinkNetworkId(int32_t sessionId)284 void DCameraAllConnectManager::RemoveSinkNetworkId(int32_t sessionId)
285 {
286 std::lock_guard<std::mutex> lock(netwkIdSinkSessionIdMapLock_);
287 for (auto it: netwkIdSinkSessionIdMap_) {
288 if (it.second == sessionId) {
289 netwkIdSinkSessionIdMap_.erase(it.first);
290 break;
291 }
292 }
293 }
294
RemoveSourceNetworkId(int32_t sessionId)295 void DCameraAllConnectManager::RemoveSourceNetworkId(int32_t sessionId)
296 {
297 std::lock_guard<std::mutex> lock(netwkIdSourceSessionIdMapLock_);
298 for (auto it: netwkIdSourceSessionIdMap_) {
299 if (it.second == sessionId) {
300 netwkIdSourceSessionIdMap_.erase(it.first);
301 break;
302 }
303 }
304 }
305
SetSourceNetworkId(const std::string & networkId,int32_t socket)306 void DCameraAllConnectManager::SetSourceNetworkId(const std::string &networkId, int32_t socket)
307 {
308 if (networkId.empty()) {
309 return ;
310 }
311 if (socket < 0) {
312 return ;
313 }
314 std::lock_guard<std::mutex> lock(netwkIdSourceSessionIdMapLock_);
315 netwkIdSourceSessionIdMap_[networkId] = socket;
316 }
317
SetSinkNetWorkId(const std::string & networkId,int32_t socket)318 void DCameraAllConnectManager::SetSinkNetWorkId(const std::string &networkId, int32_t socket)
319 {
320 if (networkId.empty()) {
321 return ;
322 }
323 if (socket < 0) {
324 return ;
325 }
326 std::lock_guard<std::mutex> lock(netwkIdSinkSessionIdMapLock_);
327 netwkIdSinkSessionIdMap_[networkId] = socket;
328 }
329
GetSinkDevIdBySocket(int32_t socket)330 std::string DCameraAllConnectManager::GetSinkDevIdBySocket(int32_t socket)
331 {
332 std::lock_guard<std::mutex> lock(netwkIdSinkSessionIdMapLock_);
333 for (auto it: netwkIdSinkSessionIdMap_) {
334 if (it.second == socket) {
335 return it.first;
336 }
337 }
338 return "";
339 }
340
GetSinkSocketByNetWorkId(const std::string & networkId)341 int32_t DCameraAllConnectManager::GetSinkSocketByNetWorkId(const std::string &networkId)
342 {
343 int32_t sessionId = -1;
344 std::lock_guard<std::mutex> lock(netwkIdSinkSessionIdMapLock_);
345 auto it = netwkIdSinkSessionIdMap_.find(networkId);
346 if (it != netwkIdSinkSessionIdMap_.end()) {
347 sessionId = it->second;
348 }
349 return sessionId;
350 }
351
GetSourceSocketByNetworkId(const std::string & networkId)352 int32_t DCameraAllConnectManager::GetSourceSocketByNetworkId(const std::string &networkId)
353 {
354 int32_t sessionId = -1;
355 std::lock_guard<std::mutex> lock(netwkIdSourceSessionIdMapLock_);
356 auto it = netwkIdSourceSessionIdMap_.find(networkId);
357 if (it != netwkIdSourceSessionIdMap_.end()) {
358 sessionId = it->second;
359 }
360 return sessionId;
361 }
362 } // namespace DistributedHardware
363 } // namespace OHOS