1 /*
2 * Copyright (c) 2024-2025 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 #include "anonymous_string.h"
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,const std::string & dhId,DCameraCollaborationBussinessStatus state)91 int32_t DCameraAllConnectManager::PublishServiceState(const std::string &peerNetworkId,
92 const std::string &dhId, DCameraCollaborationBussinessStatus state)
93 {
94 DHLOGI("DCamera allconnect PublishServiceState begin");
95 std::lock_guard<std::mutex> lock(allConnectLock_);
96 dhIdStateMap_[dhId] = state;
97 DHLOGI("DCamera allconnect PublishServiceState dhId:%{public}s, state:%{public}d",
98 dhId.c_str(), state);
99 DCameraCollaborationBussinessStatus maxState = SCM_IDLE;
100 std::string dhIdOfmaxState;
101 for (const auto& statePair : dhIdStateMap_) {
102 if (statePair.second > maxState) {
103 maxState = statePair.second;
104 dhIdOfmaxState = statePair.first;
105 }
106 }
107 if (dllHandle_ == nullptr) {
108 DHLOGE("DCamera allconnect dllHandle_ is nullptr, all connect not support.");
109 return DistributedCameraErrno::DCAMERA_OK;
110 }
111 if (allConnect_.dCameraCollaborationPublishServiceState == nullptr) {
112 DHLOGE("DCamera allconnect PublishServiceState is nullptr, all connect function not load.");
113 return DistributedCameraErrno::DCAMERA_ERR_DLOPEN;
114 }
115
116 DHLOGI("DCamera allconnect PublishDhId:%{public}s, pulishState:%{public}d",
117 dhIdOfmaxState.c_str(), maxState);
118 int32_t ret = allConnect_.dCameraCollaborationPublishServiceState(peerNetworkId.c_str(),
119 SERVICE_NAME.c_str(),
120 "", maxState);
121 if (ret != DistributedCameraErrno::DCAMERA_OK) {
122 DHLOGE("DCamera allconnect PublishServiceState %{public}d fail, ret %{public}d", state, ret);
123 return DistributedCameraErrno::DCAMERA_ERR_PUBLISH_STATE;
124 }
125 return DistributedCameraErrno::DCAMERA_OK;
126 }
127
ApplyAdvancedResource(const std::string & peerNetworkId,DCameraCollaborationResourceRequestInfoSets * resourceRequest)128 int32_t DCameraAllConnectManager::ApplyAdvancedResource(const std::string &peerNetworkId,
129 DCameraCollaborationResourceRequestInfoSets *resourceRequest)
130 {
131 DHLOGI("DCamera allconnect ApplyAdvancedResource begin");
132 std::lock_guard<std::mutex> lock(allConnectLock_);
133 if (dllHandle_ == nullptr) {
134 DHLOGE("DCamera allconnect dllHandle_ is nullptr, all connect not support.");
135 return DistributedCameraErrno::DCAMERA_OK;
136 }
137 if (allConnect_.dCameraCollaborationApplyAdvancedResource == nullptr) {
138 DHLOGE("DCamera allconnect PublishServiceState is nullptr, all connect function not load.");
139 return DistributedCameraErrno::DCAMERA_ERR_DLOPEN;
140 }
141
142 if (applyResultBlock_ == nullptr) {
143 applyResultBlock_ = std::make_shared<DCameraBlockObject<bool>>(BLOCK_INTERVAL_ALLCONNECT, false);
144 }
145
146 int32_t ret = allConnect_.dCameraCollaborationApplyAdvancedResource(peerNetworkId.c_str(),
147 SERVICE_NAME.c_str(),
148 resourceRequest,
149 &allConnectCallback_);
150 if (ret != DistributedCameraErrno::DCAMERA_OK) {
151 DHLOGE("DCamera allconnect ApplyAdvancedResource fail, ret %{public}d", ret);
152 return DistributedCameraErrno::DCAMERA_ERR_APPLY_RESULT;
153 }
154 auto success = applyResultBlock_->GetValue();
155 if (!success) {
156 DHLOGE("DCamera allconnect applyResult is reject");
157 return DistributedCameraErrno::DCAMERA_ERR_APPLY_RESULT;
158 }
159 return DistributedCameraErrno::DCAMERA_OK;
160 }
161
GetAllConnectSoLoad()162 int32_t DCameraAllConnectManager::GetAllConnectSoLoad()
163 {
164 DHLOGI("DCamera allconnect GetAllConnectSoLoad begin");
165 std::lock_guard<std::mutex> lock(allConnectLock_);
166 char path[PATH_MAX + 1] = {0x00};
167 std::string soPathName = std::string(ALL_CONNECT_SO_PATH) + std::string(ALL_CONNECT_SO_NAME);
168 if (soPathName.empty() || (soPathName.length() > PATH_MAX) || (realpath(soPathName.c_str(), path) == nullptr)) {
169 DHLOGE("DCamera allconnect all connect so load failed, soPath=%{public}s not exist.", soPathName.c_str());
170 return DistributedCameraErrno::DCAMERA_ERR_DLOPEN;
171 }
172
173 int32_t (*allConnectProxy)(DCameraCollaborationApi *exportapi) = nullptr;
174
175 dllHandle_ = dlopen(path, RTLD_LAZY);
176 if (dllHandle_ == nullptr) {
177 DHLOGE("DCamera allconnect dlopen fail");
178 return DistributedCameraErrno::DCAMERA_ERR_DLOPEN;
179 }
180
181 allConnectProxy = reinterpret_cast<int32_t (*)(DCameraCollaborationApi *exportapi)>(
182 dlsym(dllHandle_, "ServiceCollaborationManager_Export"));
183 if (allConnectProxy == nullptr) {
184 dlclose(dllHandle_);
185 dllHandle_ = nullptr;
186 DHLOGE("DCamera allconnect dlsym allConnectProxy fail");
187 return DistributedCameraErrno::DCAMERA_ERR_DLOPEN;
188 }
189
190 int32_t ret = allConnectProxy(&allConnect_);
191 if (ret != DistributedCameraErrno::DCAMERA_OK) {
192 dlclose(dllHandle_);
193 dllHandle_ = nullptr;
194 DHLOGE("DCamera allconnect get function struct fail, ret %{public}d", ret);
195 return DistributedCameraErrno::DCAMERA_ERR_DLOPEN;
196 }
197 DHLOGI("DCamera allconnect so load success");
198 return DistributedCameraErrno::DCAMERA_OK;
199 }
200
RegisterLifecycleCallback()201 int32_t DCameraAllConnectManager::RegisterLifecycleCallback()
202 {
203 DHLOGI("DCamera allconnect RegisterLifecycleCallback begin");
204 std::lock_guard<std::mutex> lock(allConnectLock_);
205 if (dllHandle_ == nullptr) {
206 DHLOGE("DCamera allconnect dllHandle_ is nullptr, all connect so has not been loaded.");
207 return DistributedCameraErrno::DCAMERA_ERR_DLOPEN;
208 }
209 if (allConnect_.dCameraCollaborationRegisterLifecycleCallback == nullptr) {
210 DHLOGE("DCamera allconnect RegisterLifecycleCallback is nullptr, all connect function not load.");
211 return DistributedCameraErrno::DCAMERA_ERR_DLOPEN;
212 }
213
214 int32_t ret = allConnect_.dCameraCollaborationRegisterLifecycleCallback(SERVICE_NAME.c_str(),
215 &allConnectCallback_);
216 if (ret != DistributedCameraErrno::DCAMERA_OK) {
217 DHLOGE("DCamera allconnect RegisterLifecycleCallback fail, ret %{public}d", ret);
218 return DistributedCameraErrno::DCAMERA_ERR_ALLCONNECT;
219 }
220 return DistributedCameraErrno::DCAMERA_OK;
221 }
222
UnRegisterLifecycleCallback()223 int32_t DCameraAllConnectManager::UnRegisterLifecycleCallback()
224 {
225 DHLOGI("DCamera allconnect UnRegisterLifecycleCallback begin");
226 std::lock_guard<std::mutex> lock(allConnectLock_);
227 if (dllHandle_ == nullptr) {
228 DHLOGE("DCamera allconnect dllHandle_ is nullptr, all connect so has not been loaded.");
229 return DistributedCameraErrno::DCAMERA_ERR_DLOPEN;
230 }
231 if (allConnect_.dCameraCollaborationUnRegisterLifecycleCallback == nullptr) {
232 DHLOGE("DCamera allconnect RegisterLifecycleCallback is nullptr, all connect function not load.");
233 return DistributedCameraErrno::DCAMERA_ERR_DLOPEN;
234 }
235
236 int32_t ret = allConnect_.dCameraCollaborationUnRegisterLifecycleCallback(SERVICE_NAME.c_str());
237 if (ret != DistributedCameraErrno::DCAMERA_OK) {
238 DHLOGE("DCamera allconnect UnRegisterLifecycleCallback fail, ret %{public}d", ret);
239 return DistributedCameraErrno::DCAMERA_ERR_ALLCONNECT;
240 }
241 return DistributedCameraErrno::DCAMERA_OK;
242 }
243
ApplyResult(int32_t errorcode,int32_t result,const char * reason)244 int32_t DCameraAllConnectManager::ApplyResult(int32_t errorcode, int32_t result, const char *reason)
245 {
246 CHECK_AND_RETURN_RET_LOG(applyResultBlock_ == nullptr, DistributedCameraErrno::DCAMERA_ERR_APPLY_RESULT,
247 "DCamera allconnect ApplyResult applyResultBlock_ is nullptr");
248 DHLOGI("DCamera allconnect ApplyResult begin");
249 if (result != PASS) {
250 DHLOGE("DCamera allconnect Apply Result is Reject, errorcode is %{public}d, reason is %{public}s",
251 errorcode, reason);
252 applyResultBlock_->SetValue(false);
253 return DistributedCameraErrno::DCAMERA_ERR_APPLY_RESULT;
254 }
255 applyResultBlock_->SetValue(true);
256 return DistributedCameraErrno::DCAMERA_OK;
257 }
258
OnStop(const char * peerNetworkId)259 int32_t DCameraAllConnectManager::OnStop(const char *peerNetworkId)
260 {
261 DHLOGI("DCamera allconnect OnStop begin peerNetworkId:%{public}s", GetAnonyString(peerNetworkId).c_str());
262 DCameraSoftbusAdapter::GetInstance().CloseSessionWithNetWorkId(peerNetworkId);
263
264 return DistributedCameraErrno::DCAMERA_OK;
265 }
266
BuildResourceRequest()267 std::shared_ptr<DCameraCollaborationResourceRequestInfoSets> DCameraAllConnectManager::BuildResourceRequest()
268 {
269 auto resourceRequest = std::make_shared<DCameraCollaborationResourceRequestInfoSets>();
270
271 if (remoteHardwareList_ == nullptr) {
272 remoteHardwareList_ = std::make_shared<DCameraCollaboration_HardwareRequestInfo>();
273 remoteHardwareList_->hardWareType = DCameraCollaborationHardwareType::SCM_CAMERA;
274 remoteHardwareList_->canShare = true;
275 }
276 resourceRequest->remoteHardwareListSize = 1;
277 resourceRequest->remoteHardwareList = remoteHardwareList_.get();
278
279 if (localHardwareList_ == nullptr) {
280 localHardwareList_ = std::make_shared<DCameraCollaboration_HardwareRequestInfo>();
281 localHardwareList_->hardWareType = DCameraCollaborationHardwareType::SCM_CAMERA;
282 localHardwareList_->canShare = true;
283 }
284 resourceRequest->localHardwareListSize = 1;
285 resourceRequest->localHardwareList = localHardwareList_.get();
286
287 if (communicationRequest_ == nullptr) {
288 communicationRequest_ = std::make_shared<DCameraCollaborationCommunicationRequestInfo>();
289 communicationRequest_->minBandwidth = DCAMERA_QOS_TYPE_MIN_BW;
290 communicationRequest_->maxLatency = DCAMERA_QOS_TYPE_MAX_LATENCY;
291 communicationRequest_->minLatency = DCAMERA_QOS_TYPE_MIN_LATENCY;
292 communicationRequest_->maxWaitTime = 0;
293 communicationRequest_->dataType = "DATA_TYPE_VIDEO_STREAM";
294 }
295 resourceRequest->communicationRequest = communicationRequest_.get();
296
297 return resourceRequest;
298 }
299
RemoveSinkNetworkId(int32_t sessionId)300 void DCameraAllConnectManager::RemoveSinkNetworkId(int32_t sessionId)
301 {
302 std::lock_guard<std::mutex> lock(netwkIdSinkSessionIdMapLock_);
303 for (auto it: netwkIdSinkSessionIdMap_) {
304 if (it.second == sessionId) {
305 netwkIdSinkSessionIdMap_.erase(it.first);
306 break;
307 }
308 }
309 }
310
RemoveSourceNetworkId(int32_t sessionId)311 void DCameraAllConnectManager::RemoveSourceNetworkId(int32_t sessionId)
312 {
313 std::lock_guard<std::mutex> lock(netwkIdSourceSessionIdMapLock_);
314 for (auto it: netwkIdSourceSessionIdMap_) {
315 if (it.second == sessionId) {
316 netwkIdSourceSessionIdMap_.erase(it.first);
317 break;
318 }
319 }
320 }
321
SetSourceNetworkId(const std::string & networkId,int32_t socket)322 void DCameraAllConnectManager::SetSourceNetworkId(const std::string &networkId, int32_t socket)
323 {
324 if (networkId.empty()) {
325 return ;
326 }
327 if (socket < 0) {
328 return ;
329 }
330 std::lock_guard<std::mutex> lock(netwkIdSourceSessionIdMapLock_);
331 netwkIdSourceSessionIdMap_[networkId] = socket;
332 }
333
SetSinkNetWorkId(const std::string & networkId,int32_t socket)334 void DCameraAllConnectManager::SetSinkNetWorkId(const std::string &networkId, int32_t socket)
335 {
336 if (networkId.empty()) {
337 return ;
338 }
339 if (socket < 0) {
340 return ;
341 }
342 std::lock_guard<std::mutex> lock(netwkIdSinkSessionIdMapLock_);
343 netwkIdSinkSessionIdMap_[networkId] = socket;
344 }
345
GetSinkDevIdBySocket(int32_t socket)346 std::string DCameraAllConnectManager::GetSinkDevIdBySocket(int32_t socket)
347 {
348 std::lock_guard<std::mutex> lock(netwkIdSinkSessionIdMapLock_);
349 for (auto it: netwkIdSinkSessionIdMap_) {
350 if (it.second == socket) {
351 return it.first;
352 }
353 }
354 return "";
355 }
356
GetSinkSocketByNetWorkId(const std::string & networkId)357 int32_t DCameraAllConnectManager::GetSinkSocketByNetWorkId(const std::string &networkId)
358 {
359 int32_t sessionId = -1;
360 std::lock_guard<std::mutex> lock(netwkIdSinkSessionIdMapLock_);
361 auto it = netwkIdSinkSessionIdMap_.find(networkId);
362 if (it != netwkIdSinkSessionIdMap_.end()) {
363 sessionId = it->second;
364 }
365 return sessionId;
366 }
367
GetSourceSocketByNetworkId(const std::string & networkId)368 int32_t DCameraAllConnectManager::GetSourceSocketByNetworkId(const std::string &networkId)
369 {
370 int32_t sessionId = -1;
371 std::lock_guard<std::mutex> lock(netwkIdSourceSessionIdMapLock_);
372 auto it = netwkIdSourceSessionIdMap_.find(networkId);
373 if (it != netwkIdSourceSessionIdMap_.end()) {
374 sessionId = it->second;
375 }
376 return sessionId;
377 }
378 } // namespace DistributedHardware
379 } // namespace OHOS