• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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