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