• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "all_connect/all_connect_manager.h"
17 
18 #include <cstdio>
19 #include <cstdlib>
20 #include <dlfcn.h>
21 #include <thread>
22 
23 #include "dfs_error.h"
24 #include "network/softbus/softbus_asset_recv_listener.h"
25 #include "network/softbus/softbus_asset_send_listener.h"
26 #include "network/softbus/softbus_handler.h"
27 #include "utils_directory.h"
28 #include "utils_log.h"
29 
30 namespace OHOS {
31 namespace Storage {
32 namespace DistributedFile {
33 #ifdef __LP64__
34 constexpr const char *ALL_CONNECT_SO_PATH = "/system/lib64/";
35 #else
36 constexpr const char *ALL_CONNECT_SO_PATH = "/system/lib/";
37 #endif
38 constexpr const char *ALL_CONNECT_SO_NAME = "libcfwk_allconnect_client.z.so";
39 std::shared_ptr<BlockObject<bool>> AllConnectManager::applyResultBlock_;
40 constexpr int32_t DFS_QOS_TYPE_MIN_BW = 90 * 1024 * 1024;
41 constexpr int32_t DFS_QOS_TYPE_MAX_LATENCY = 10000;
42 constexpr int32_t DFS_QOS_TYPE_MIN_LATENCY = 2000;
AllConnectManager()43 AllConnectManager::AllConnectManager()
44 {
45     allConnectCallback_.OnStop = &AllConnectManager::OnStop;
46     allConnectCallback_.ApplyResult = &AllConnectManager::ApplyResult;
47 }
48 
GetInstance()49 AllConnectManager &AllConnectManager::GetInstance()
50 {
51     static AllConnectManager instance;
52     return instance;
53 }
54 
InitAllConnectManager()55 int32_t AllConnectManager::InitAllConnectManager()
56 {
57     LOGI("InitAllConnectManager begin");
58     int32_t ret = GetAllConnectSoLoad();
59     if (ret != FileManagement::ERR_OK) {
60         LOGE("InitAllConnectManager failed, all connect so not exist or load so error, ret %{public}d", ret);
61         return ret;
62     }
63 
64     ret = RegisterLifecycleCallback();
65     if (ret != FileManagement::ERR_OK) {
66         LOGE("InitAllConnectManager failed, register lifecycle callback error, ret %{public}d", ret);
67         return ret;
68     }
69     LOGI("InitAllConnectManager success");
70     return FileManagement::ERR_OK;
71 }
72 
UnInitAllConnectManager()73 int32_t AllConnectManager::UnInitAllConnectManager()
74 {
75     LOGI("UnInitAllConnectManager begin");
76     int32_t ret = UnRegisterLifecycleCallback();
77     if (ret != FileManagement::ERR_OK) {
78         LOGE("UnInitAllConnectManagerfailed, unregister lifecycle callback error, ret %{public}d", ret);
79     }
80 
81     std::lock_guard<std::mutex> lock(allConnectLock_);
82     dlclose(dllHandle_);
83     dllHandle_ = nullptr;
84     return FileManagement::ERR_OK;
85 }
86 
PublishServiceState(DfsConnectCode code,const std::string & peerNetworkId,ServiceCollaborationManagerBussinessStatus state)87 int32_t AllConnectManager::PublishServiceState(DfsConnectCode code, const std::string &peerNetworkId,
88                                                ServiceCollaborationManagerBussinessStatus state)
89 {
90     LOGI("PublishServiceState NetworkId: %{public}s, %{public}d begin",
91          Utils::GetAnonyString(peerNetworkId).c_str(), state);
92     std::lock_guard<std::mutex> lock(allConnectLock_);
93     if (dllHandle_ == nullptr) {
94         LOGE("dllHandle_ is nullptr, all connect not support.");
95         return FileManagement::ERR_OK;
96     }
97     if (allConnect_.ServiceCollaborationManager_PublishServiceState == nullptr) {
98         LOGE("PublishServiceState is nullptr, all connect function not load.");
99         return FileManagement::ERR_DLOPEN;
100     }
101 
102     if (!GetPublicState(code, peerNetworkId, state)) {
103         return FileManagement::ERR_OK;
104     }
105     int32_t ret = allConnect_.ServiceCollaborationManager_PublishServiceState(peerNetworkId.c_str(),
106                                                                               SERVICE_NAME.c_str(),
107                                                                               "", state);
108     if (ret != FileManagement::ERR_OK) {
109         LOGE("PublishServiceState %{public}d fail, ret %{public}d", state, ret);
110         return FileManagement::ERR_PUBLISH_STATE;
111     }
112     return FileManagement::ERR_OK;
113 }
114 
GetPublicState(DfsConnectCode code,const std::string & peerNetworkId,ServiceCollaborationManagerBussinessStatus state)115 bool AllConnectManager::GetPublicState(DfsConnectCode code, const std::string &peerNetworkId,
116     ServiceCollaborationManagerBussinessStatus state)
117 {
118     std::lock_guard<std::mutex> lock(connectStatesMutex_);
119     auto connectStateIter = connectStates_.find(peerNetworkId);
120     if (connectStateIter == connectStates_.end()) {
121         std::map<DfsConnectCode, ServiceCollaborationManagerBussinessStatus> tmp;
122         tmp.insert(std::make_pair(code, state));
123         connectStates_.insert(std::make_pair(peerNetworkId, tmp));
124         return state == SCM_CONNECTED;
125     }
126     auto &connectState = connectStateIter->second;
127 
128     auto it = connectState.find(code);
129     if (it == connectState.end()) {
130         connectState.insert(std::make_pair(code, state));
131         return state == SCM_CONNECTED;
132     }
133     if (state == it->second) {
134         return false;
135     }
136 
137     // connect -> idle
138     if (state == SCM_IDLE && it->second == SCM_CONNECTED) {
139         connectState[code] = state;
140         for (auto iter : connectState) {
141             if (iter.second == SCM_CONNECTED) {
142                 return false;
143             }
144         }
145         return true;
146     }
147     // idle -> connect
148     connectState[code] = state;
149     return true;
150 }
151 
ApplyAdvancedResource(const std::string & peerNetworkId,ServiceCollaborationManager_ResourceRequestInfoSets * resourceRequest)152 int32_t AllConnectManager::ApplyAdvancedResource(const std::string &peerNetworkId,
153     ServiceCollaborationManager_ResourceRequestInfoSets *resourceRequest)
154 {
155     LOGI("ApplyAdvancedResource begin, peerNetworkId: %{public}s", Utils::GetAnonyString(peerNetworkId).c_str());
156     std::lock_guard<std::mutex> lock(allConnectLock_);
157     if (dllHandle_ == nullptr) {
158         LOGE("dllHandle_ is nullptr, all connect not support.");
159         return FileManagement::ERR_OK;
160     }
161     if (allConnect_.ServiceCollaborationManager_ApplyAdvancedResource == nullptr) {
162         LOGE("PublishServiceState is nullptr, all connect function not load.");
163         return FileManagement::ERR_DLOPEN;
164     }
165 
166     if (applyResultBlock_ == nullptr) {
167         applyResultBlock_ = std::make_shared<BlockObject<bool>>(BLOCK_INTERVAL_ALLCONNECT, false);
168     }
169 
170     int32_t ret = allConnect_.ServiceCollaborationManager_ApplyAdvancedResource(peerNetworkId.c_str(),
171                                                                                 SERVICE_NAME.c_str(),
172                                                                                 resourceRequest,
173                                                                                 &allConnectCallback_);
174     if (ret != FileManagement::ERR_OK) {
175         LOGE("ApplyAdvancedResource fail, ret %{public}d", ret);
176         return FileManagement::ERR_APPLY_RESULT;
177     }
178     auto success = applyResultBlock_->GetValue();
179     if (!success) {
180         LOGE("applyResult is reject, peerNetworkId: %{public}s", Utils::GetAnonyString(peerNetworkId).c_str());
181         return FileManagement::ERR_APPLY_RESULT;
182     }
183     LOGI("ApplyAdvancedResource success, peerNetworkId: %{public}s", Utils::GetAnonyString(peerNetworkId).c_str());
184     return FileManagement::ERR_OK;
185 }
186 
GetAllConnectSoLoad()187 int32_t AllConnectManager::GetAllConnectSoLoad()
188 {
189     LOGI("GetAllConnectSoLoad begin");
190     std::lock_guard<std::mutex> lock(allConnectLock_);
191     char path[PATH_MAX + 1] = {0x00};
192     std::string soPathName = std::string(ALL_CONNECT_SO_PATH) + std::string(ALL_CONNECT_SO_NAME);
193     if (soPathName.empty() || (soPathName.length() > PATH_MAX) ||
194         (realpath(soPathName.c_str(), path) == nullptr)) {
195         LOGE("all connect so load failed, soPath=%{public}s not exist.", soPathName.c_str());
196         return FileManagement::ERR_DLOPEN;
197     }
198 
199     int32_t (*allConnectProxy)(ServiceCollaborationManager_API *exportapi) = nullptr;
200 
201     dllHandle_ = dlopen(path, RTLD_LAZY);
202     if (dllHandle_ == nullptr) {
203         LOGE("dlopen fail");
204         return FileManagement::ERR_DLOPEN;
205     }
206 
207     allConnectProxy = reinterpret_cast<int32_t (*)(ServiceCollaborationManager_API *exportapi)>(
208         dlsym(dllHandle_, "ServiceCollaborationManager_Export"));
209     if (allConnectProxy == nullptr) {
210         dlclose(dllHandle_);
211         dllHandle_ = nullptr;
212         LOGE("dlsym allConnectProxy fail");
213         return FileManagement::ERR_DLOPEN;
214     }
215 
216     int32_t ret = allConnectProxy(&allConnect_);
217     if (ret != FileManagement::ERR_OK) {
218         dlclose(dllHandle_);
219         dllHandle_ = nullptr;
220         LOGE("get function struct fail, ret %{public}d", ret);
221         return FileManagement::ERR_DLOPEN;
222     }
223     LOGI("so load success");
224     return FileManagement::ERR_OK;
225 }
226 
RegisterLifecycleCallback()227 int32_t AllConnectManager::RegisterLifecycleCallback()
228 {
229     LOGI("RegisterLifecycleCallback begin");
230     std::lock_guard<std::mutex> lock(allConnectLock_);
231     if (dllHandle_ == nullptr) {
232         LOGE("dllHandle_ is nullptr, all connect so has not been loaded.");
233         return FileManagement::ERR_DLOPEN;
234     }
235     if (allConnect_.ServiceCollaborationManager_RegisterLifecycleCallback == nullptr) {
236         LOGE("RegisterLifecycleCallback is nullptr, all connect function not load.");
237         return FileManagement::ERR_DLOPEN;
238     }
239 
240     int32_t ret = allConnect_.ServiceCollaborationManager_RegisterLifecycleCallback(SERVICE_NAME.c_str(),
241                                                                                     &allConnectCallback_);
242     if (ret != FileManagement::ERR_OK) {
243         LOGE("RegisterLifecycleCallback fail, ret %{public}d", ret);
244         return FileManagement::ERR_ALLCONNECT;
245     }
246     return FileManagement::ERR_OK;
247 }
248 
UnRegisterLifecycleCallback()249 int32_t AllConnectManager::UnRegisterLifecycleCallback()
250 {
251     LOGI("UnRegisterLifecycleCallback begin");
252     std::lock_guard<std::mutex> lock(allConnectLock_);
253     if (dllHandle_ == nullptr) {
254         LOGE("dllHandle_ is nullptr, all connect so has not been loaded.");
255         return FileManagement::ERR_DLOPEN;
256     }
257     if (allConnect_.ServiceCollaborationManager_UnRegisterLifecycleCallback == nullptr) {
258         LOGE("RegisterLifecycleCallback is nullptr, all connect function not load.");
259         return FileManagement::ERR_DLOPEN;
260     }
261 
262     int32_t ret = allConnect_.ServiceCollaborationManager_UnRegisterLifecycleCallback(SERVICE_NAME.c_str());
263     if (ret != FileManagement::ERR_OK) {
264         LOGE("UnRegisterLifecycleCallback fail, ret %{public}d", ret);
265         return FileManagement::ERR_ALLCONNECT;
266     }
267     return FileManagement::ERR_OK;
268 }
269 
ApplyResult(int32_t errorcode,int32_t result,const char * reason)270 int32_t AllConnectManager::ApplyResult(int32_t errorcode, int32_t result, const char *reason)
271 {
272     (void)reason;
273     LOGI("ApplyResult begin");
274     if (result != PASS) {
275         LOGE("Apply Result is Reject, errorcode is %{public}d", errorcode);
276         applyResultBlock_->SetValue(false);
277         return FileManagement::ERR_APPLY_RESULT;
278     }
279     applyResultBlock_->SetValue(true);
280     return FileManagement::ERR_OK;
281 }
282 
OnStop(const char * peerNetworkId)283 int32_t AllConnectManager::OnStop(const char *peerNetworkId)
284 {
285     std::string pNetworkId(peerNetworkId);
286     LOGI("OnStop begin, peerNetworkId:%{public}s", Utils::GetAnonyString(pNetworkId).c_str());
287     std::thread([pNetworkId]() {
288         SoftBusHandler::GetInstance().CopyOnStop(pNetworkId);
289         SoftbusAssetRecvListener::DisConnectByAllConnect(pNetworkId);
290         SoftBusAssetSendListener::DisConnectByAllConnect(pNetworkId);
291     }).detach();
292     return FileManagement::ERR_OK;
293 }
294 
BuildResourceRequest()295 std::shared_ptr<ServiceCollaborationManager_ResourceRequestInfoSets> AllConnectManager::BuildResourceRequest()
296 {
297     auto resourceRequest = std::make_shared<ServiceCollaborationManager_ResourceRequestInfoSets>();
298 
299     if (remoteHardwareList_ == nullptr) {
300         remoteHardwareList_ = std::make_shared<ServiceCollaborationManager_HardwareRequestInfo>();
301         remoteHardwareList_->hardWareType = ServiceCollaborationManagerHardwareType::SCM_DISPLAY;
302         remoteHardwareList_->canShare = true;
303     }
304     resourceRequest->remoteHardwareListSize = 1;
305     resourceRequest->remoteHardwareList = remoteHardwareList_.get();
306 
307     if (localHardwareList_ == nullptr) {
308         localHardwareList_ = std::make_shared<ServiceCollaborationManager_HardwareRequestInfo>();
309         localHardwareList_->hardWareType = ServiceCollaborationManagerHardwareType::SCM_DISPLAY;
310         localHardwareList_->canShare = true;
311     }
312     resourceRequest->localHardwareListSize = 1;
313     resourceRequest->localHardwareList = localHardwareList_.get();
314 
315     if (communicationRequest_ == nullptr) {
316         communicationRequest_ = std::make_shared<ServiceCollaborationManager_CommunicationRequestInfo>();
317         communicationRequest_->minBandwidth = DFS_QOS_TYPE_MIN_BW;
318         communicationRequest_->maxLatency = DFS_QOS_TYPE_MAX_LATENCY;
319         communicationRequest_->minLatency = DFS_QOS_TYPE_MIN_LATENCY;
320         communicationRequest_->maxWaitTime = 0;
321         communicationRequest_->dataType = "DATA_TYPE_FILE";
322     }
323     resourceRequest->communicationRequest = communicationRequest_.get();
324 
325     return resourceRequest;
326 }
327 } // namespace DistributedFile
328 } // namespace Storage
329 } // namespace OHOS