1 /*
2 * Copyright (c) 2021-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 "ipc/daemon.h"
17
18 #include <exception>
19 #include <regex>
20 #include <stdexcept>
21 #include <string>
22 #include <sys/stat.h>
23 #include <unistd.h>
24 #include <unordered_set>
25
26 #include "accesstoken_kit.h"
27 #include "all_connect/all_connect_manager.h"
28 #include "asset_callback_manager.h"
29 #include "common_event_manager.h"
30 #include "common_event_support.h"
31 #include "connection_detector.h"
32 #include "device/device_manager_agent.h"
33 #include "dfs_daemon_event_dfx.h"
34 #include "dfs_error.h"
35 #include "dfsu_access_token_helper.h"
36 #include "i_file_dfs_listener.h"
37 #include "ipc_skeleton.h"
38 #include "iremote_object.h"
39 #include "iservice_registry.h"
40 #include "mountpoint/mount_manager.h"
41 #include "network/softbus/softbus_handler_asset.h"
42 #include "network/softbus/softbus_handler.h"
43 #include "network/softbus/softbus_session_dispatcher.h"
44 #include "network/softbus/softbus_session_listener.h"
45 #include "network/softbus/softbus_session_pool.h"
46 #include "sandbox_helper.h"
47 #include "system_ability_definition.h"
48 #include "trans_mananger.h"
49 #include "utils_directory.h"
50 #include "utils_log.h"
51
52 namespace OHOS {
53 namespace Storage {
54 namespace DistributedFile {
55 using namespace std;
56 using namespace OHOS::AppFileService;
57 using namespace OHOS::FileManagement;
58 using namespace OHOS::Storage::DistributedFile;
59 using HapTokenInfo = OHOS::Security::AccessToken::HapTokenInfo;
60 using AccessTokenKit = OHOS::Security::AccessToken::AccessTokenKit;
61
62 namespace {
63 const string FILE_MANAGER_AUTHORITY = "docs";
64 const string MEDIA_AUTHORITY = "media";
65 const int32_t E_PERMISSION_DENIED_NAPI = 201;
66 const int32_t E_INVAL_ARG_NAPI = 401;
67 const int32_t E_CONNECTION_FAILED = 13900045;
68 const int32_t E_UNMOUNT = 13600004;
69 constexpr int32_t CHECK_SESSION_DELAY_TIME_TWICE = 5000000;
70 constexpr mode_t DEFAULT_UMASK = 0002;
71 constexpr int32_t BLOCK_INTERVAL_SEND_FILE = 8 * 1000;
72 }
73
74 REGISTER_SYSTEM_ABILITY_BY_ID(Daemon, FILEMANAGEMENT_DISTRIBUTED_FILE_DAEMON_SA_ID, true);
75
PublishSA()76 void Daemon::PublishSA()
77 {
78 LOGI("Begin to init");
79 if (!registerToService_) {
80 bool ret = SystemAbility::Publish(this);
81 if (!ret) {
82 throw runtime_error("Failed to publish the daemon");
83 }
84 registerToService_ = true;
85 }
86 LOGI("Init finished successfully");
87 }
88
RegisterOsAccount()89 void Daemon::RegisterOsAccount()
90 {
91 EventFwk::MatchingSkills matchingSkills;
92 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USER_SWITCHED);
93 EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills);
94 subScriber_ = std::make_shared<OsAccountObserver>(subscribeInfo);
95 bool subRet = EventFwk::CommonEventManager::SubscribeCommonEvent(subScriber_);
96 if (!subRet) {
97 LOGE("Subscribe common event failed");
98 }
99 }
100
OnStart()101 void Daemon::OnStart()
102 {
103 LOGI("Begin to start service");
104 if (state_ == ServiceRunningState::STATE_RUNNING) {
105 LOGD("Daemon has already started");
106 return;
107 }
108
109 try {
110 PublishSA();
111 StartEventHandler();
112 AddSystemAbilityListener(COMMON_EVENT_SERVICE_ID);
113 AddSystemAbilityListener(SOFTBUS_SERVER_SA_ID);
114 umask(DEFAULT_UMASK);
115 AllConnectManager::GetInstance().InitAllConnectManager();
116 } catch (const exception &e) {
117 LOGE("%{public}s", e.what());
118 }
119
120 state_ = ServiceRunningState::STATE_RUNNING;
121 LOGI("Start service successfully");
122 }
123
OnStop()124 void Daemon::OnStop()
125 {
126 LOGI("Begin to stop");
127 state_ = ServiceRunningState::STATE_NOT_START;
128 registerToService_ = false;
129 bool subRet = EventFwk::CommonEventManager::UnSubscribeCommonEvent(subScriber_);
130 if (!subRet) {
131 LOGE("UnSubscribe common event failed");
132 }
133 subScriber_ = nullptr;
134 daemonExecute_ = nullptr;
135 eventHandler_ = nullptr;
136 SoftBusHandlerAsset::GetInstance().DeleteAssetLocalSessionServer();
137 AllConnectManager::GetInstance().UnInitAllConnectManager();
138 LOGI("Stop finished successfully");
139 }
140
OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId)141 void Daemon::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
142 {
143 if (systemAbilityId == COMMON_EVENT_SERVICE_ID) {
144 (void)systemAbilityId;
145 (void)deviceId;
146 RegisterOsAccount();
147 } else if (systemAbilityId == SOFTBUS_SERVER_SA_ID) {
148 SoftBusHandlerAsset::GetInstance().CreateAssetLocalSessionServer();
149 }
150 }
151
OnRemoveSystemAbility(int32_t systemAbilityId, const std::string &deviceId)152 void Daemon::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
153 {
154 (void)deviceId;
155 if (systemAbilityId == COMMON_EVENT_SERVICE_ID) {
156 if (subScriber_ == nullptr) {
157 LOGE("Daemon::OnRemoveSystemAbility subscriberPtr is nullptr");
158 return;
159 }
160
161 bool subscribeResult = EventFwk::CommonEventManager::UnSubscribeCommonEvent(subScriber_);
162 LOGI("Daemon::OnRemoveSystemAbility subscribeResult = %{public}d", subscribeResult);
163 subScriber_ = nullptr;
164 } else if (systemAbilityId == SOFTBUS_SERVER_SA_ID) {
165 SoftBusHandlerAsset::GetInstance().DeleteAssetLocalSessionServer();
166 }
167 }
168
OpenP2PConnection(const DistributedHardware::DmDeviceInfo &deviceInfo)169 int32_t Daemon::OpenP2PConnection(const DistributedHardware::DmDeviceInfo &deviceInfo)
170 {
171 LOGI("OpenP2PConnection networkId %{public}s", Utils::GetAnonyString(deviceInfo.networkId).c_str());
172 RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_BUILD__LINK, RadarReporter::DFX_SUCCESS,
173 RadarReporter::BIZ_STATE, RadarReporter::DFX_BEGIN);
174 auto path = ConnectionDetector::ParseHmdfsPath();
175 stringstream ss;
176 ss << ConnectionDetector::MocklispHash(path);
177 auto targetDir = ss.str();
178 auto networkId = std::string(deviceInfo.networkId);
179 int32_t ret = 0;
180 if (!ConnectionDetector::GetConnectionStatus(targetDir, networkId)) {
181 DeviceManagerAgent::GetInstance()->ClearCount(deviceInfo);
182 LOGI("Get connection status not ok, try again.");
183 ret = DeviceManagerAgent::GetInstance()->OnDeviceP2POnline(deviceInfo);
184 if (ret != NO_ERROR) {
185 LOGE("OpenP2PConnection failed, ret = %{public}d", ret);
186 } else {
187 ret = ConnectionDetector::RepeatGetConnectionStatus(targetDir, networkId);
188 LOGI("RepeatGetConnectionStatus end, ret = %{public}d", ret);
189 }
190 }
191 if (ret == FileManagement::ERR_BAD_VALUE) {
192 LOGI("OpenP2PConnection check connection status failed, start to clean up");
193 CloseP2PConnection(deviceInfo);
194 }
195 RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_BUILD__LINK, RadarReporter::DFX_SUCCESS,
196 RadarReporter::BIZ_STATE, RadarReporter::DFX_END);
197 return ret;
198 }
199
CloseP2PConnection(const DistributedHardware::DmDeviceInfo &deviceInfo)200 int32_t Daemon::CloseP2PConnection(const DistributedHardware::DmDeviceInfo &deviceInfo)
201 {
202 LOGI("Close P2P Connection networkId %{public}s", Utils::GetAnonyString(deviceInfo.networkId).c_str());
203 std::thread([=]() {
204 int32_t ret = DeviceManagerAgent::GetInstance()->OnDeviceP2POffline(deviceInfo);
205 LOGI("Close P2P Connection result %d", ret);
206 return ret;
207 }).detach();
208 return 0;
209 }
210
ConnectionCount(const DistributedHardware::DmDeviceInfo &deviceInfo)211 int32_t Daemon::ConnectionCount(const DistributedHardware::DmDeviceInfo &deviceInfo)
212 {
213 auto path = ConnectionDetector::ParseHmdfsPath();
214 stringstream ss;
215 ss << ConnectionDetector::MocklispHash(path);
216 auto targetDir = ss.str();
217 auto networkId = std::string(deviceInfo.networkId);
218 int32_t ret = 0;
219 ret = DeviceManagerAgent::GetInstance()->OnDeviceP2POnline(deviceInfo);
220 if (ret != NO_ERROR) {
221 LOGE("OpenP2PConnection failed, ret = %{public}d", ret);
222 } else {
223 ret = ConnectionDetector::RepeatGetConnectionStatus(targetDir, networkId);
224 LOGI("RepeatGetConnectionStatus first time, ret = %{public}d", ret);
225 }
226 ret = ConnectionDetector::RepeatGetConnectionStatus(targetDir, networkId);
227 if (ret != NO_ERROR) {
228 LOGI("RepeatGetConnectionStatus third times, ret = %{public}d", ret);
229 usleep(CHECK_SESSION_DELAY_TIME_TWICE);
230 ret = ConnectionDetector::RepeatGetConnectionStatus(targetDir, networkId);
231 }
232 return ret;
233 }
234
CleanUp(const DistributedHardware::DmDeviceInfo &deviceInfo, const std::string &networkId, uint32_t callingTokenId)235 int32_t Daemon::CleanUp(const DistributedHardware::DmDeviceInfo &deviceInfo,
236 const std::string &networkId, uint32_t callingTokenId)
237 {
238 LOGI("CleanUp start");
239 auto deviceManager = DeviceManagerAgent::GetInstance();
240 if (deviceManager->RemoveRemoteReverseObj(false, callingTokenId) != E_OK) {
241 LOGE("fail to RemoveRemoteReverseObj");
242 }
243 deviceManager->RemoveNetworkIdByOne(callingTokenId, networkId);
244 int32_t ret = CloseP2PConnection(deviceInfo);
245 if (ret != NO_ERROR) {
246 LOGE("Daemon::CleanUp CloseP2PConnection failed");
247 return E_CONNECTION_FAILED;
248 }
249 return 0;
250 }
251
ConnectionAndMount(const DistributedHardware::DmDeviceInfo &deviceInfo, const std::string &networkId, uint32_t callingTokenId)252 int32_t Daemon::ConnectionAndMount(const DistributedHardware::DmDeviceInfo &deviceInfo,
253 const std::string &networkId, uint32_t callingTokenId)
254 {
255 LOGI("ConnectionAndMount start");
256 int32_t ret = NO_ERROR;
257 ret = ConnectionCount(deviceInfo);
258 if (ret != NO_ERROR) {
259 LOGE("connection failed");
260 return ret;
261 }
262 auto deviceManager = DeviceManagerAgent::GetInstance();
263 deviceManager->AddNetworkId(callingTokenId, networkId);
264 if (!DfsuAccessTokenHelper::CheckCallerPermission(FILE_ACCESS_MANAGER_PERMISSION)) {
265 LOGW("permission denied: FILE_ACCESS_MANAGER_PERMISSION");
266 return ret;
267 }
268 std::string deviceId = deviceManager->GetDeviceIdByNetworkId(networkId);
269 ret = deviceManager->MountDfsDocs(networkId, deviceId);
270 if (ret != NO_ERROR) {
271 LOGE("[MountDfsDocs] failed");
272 }
273 return ret;
274 }
275
OpenP2PConnectionEx(const std::string &networkId, sptr<IFileDfsListener> remoteReverseObj)276 int32_t Daemon::OpenP2PConnectionEx(const std::string &networkId, sptr<IFileDfsListener> remoteReverseObj)
277 {
278 LOGI("Daemon::OpenP2PConnectionEx start, networkId %{public}s", Utils::GetAnonyString(networkId).c_str());
279 if (!DfsuAccessTokenHelper::CheckCallerPermission(PERM_DISTRIBUTED_DATASYNC)) {
280 LOGE("[OpenP2PConnectionEx] DATASYNC permission denied");
281 return E_PERMISSION_DENIED_NAPI;
282 }
283 if (dfsListenerDeathRecipient_ == nullptr) {
284 LOGE("Daemon::OpenP2PConnectionEx, new death recipient");
285 dfsListenerDeathRecipient_ = new (std::nothrow) DfsListenerDeathRecipient();
286 }
287 if (remoteReverseObj == nullptr) {
288 LOGE("Daemon::OpenP2PConnectionEx remoteReverseObj is nullptr");
289 return E_INVAL_ARG_NAPI;
290 }
291 remoteReverseObj->AsObject()->AddDeathRecipient(dfsListenerDeathRecipient_);
292 auto deviceManager = DeviceManagerAgent::GetInstance();
293 if (networkId.empty()) {
294 LOGE("Daemon::OpenP2PConnectionEx networkId is null");
295 return E_INVAL_ARG_NAPI;
296 }
297 DistributedHardware::DmDeviceInfo deviceInfo{};
298 auto res = strcpy_s(deviceInfo.networkId, networkId.size() + 1, networkId.c_str());
299 if (res != NO_ERROR) {
300 LOGE("OpenP2PConnectionEx strcpy failed, res = %{public}d", res);
301 return E_INVAL_ARG_NAPI;
302 }
303 auto callingTokenId = IPCSkeleton::GetCallingTokenID();
304 if (deviceManager->AddRemoteReverseObj(callingTokenId, remoteReverseObj) != E_OK) {
305 LOGE("Daemon::OpenP2PConnectionEx::fail to AddRemoteReverseObj");
306 }
307 int32_t ret = ConnectionAndMount(deviceInfo, networkId, callingTokenId);
308 if (ret != NO_ERROR) {
309 CleanUp(deviceInfo, networkId, callingTokenId);
310 return E_CONNECTION_FAILED;
311 }
312 LOGI("Daemon::OpenP2PConnectionEx end");
313 return ret;
314 }
315
CloseP2PConnectionEx(const std::string &networkId)316 int32_t Daemon::CloseP2PConnectionEx(const std::string &networkId)
317 {
318 LOGI("Daemon::CloseP2PConnectionEx start, networkId: %{public}s", Utils::GetAnonyString(networkId).c_str());
319 if (!DfsuAccessTokenHelper::CheckCallerPermission(PERM_DISTRIBUTED_DATASYNC)) {
320 LOGE("[CloseP2PConnectionEx] DATASYNC permission denied");
321 return E_PERMISSION_DENIED_NAPI;
322 }
323 auto deviceManager = DeviceManagerAgent::GetInstance();
324 auto callingTokenId = IPCSkeleton::GetCallingTokenID();
325 if (networkId.empty()) {
326 LOGE("[OpenP2PConnectionEx] networkId is null");
327 return E_INVAL_ARG_NAPI;
328 }
329 std::string deviceId = deviceManager->GetDeviceIdByNetworkId(networkId);
330 if (deviceId.empty()) {
331 LOGE("fail to get deviceId");
332 return E_CONNECTION_FAILED;
333 }
334 if (DfsuAccessTokenHelper::CheckCallerPermission(FILE_ACCESS_MANAGER_PERMISSION)) {
335 LOGE("[UMountDfsDocs] permission ok: FILE_ACCESS_MANAGER_PERMISSION");
336 int32_t ret_umount = deviceManager->UMountDfsDocs(networkId, deviceId, false);
337 if (ret_umount != E_OK) {
338 LOGE("[UMountDfsDocs] failed");
339 return E_UNMOUNT;
340 }
341 }
342 DistributedHardware::DmDeviceInfo deviceInfo{};
343 auto res = strcpy_s(deviceInfo.networkId, networkId.size() + 1, networkId.c_str());
344 if (res != NO_ERROR) {
345 LOGE("strcpy failed, res = %{public}d", res);
346 return E_INVAL_ARG_NAPI;
347 }
348 int32_t ret = CleanUp(deviceInfo, networkId, callingTokenId);
349 if (ret != NO_ERROR) {
350 LOGE("Daemon::CloseP2PConnectionEx disconnection failed");
351 return E_CONNECTION_FAILED;
352 }
353 LOGI("Daemon::CloseP2PConnectionEx end");
354 return 0;
355 }
356
RequestSendFile(const std::string &srcUri, const std::string &dstPath, const std::string &dstDeviceId, const std::string &sessionName)357 int32_t Daemon::RequestSendFile(const std::string &srcUri,
358 const std::string &dstPath,
359 const std::string &dstDeviceId,
360 const std::string &sessionName)
361 {
362 LOGI("RequestSendFile begin dstDeviceId: %{public}s", Utils::GetAnonyString(dstDeviceId).c_str());
363
364 auto requestSendFileBlock = std::make_shared<BlockObject<int32_t>>(BLOCK_INTERVAL_SEND_FILE, ERR_BAD_VALUE);
365 auto requestSendFileData = std::make_shared<RequestSendFileData>(
366 srcUri, dstPath, dstDeviceId, sessionName, requestSendFileBlock);
367 auto msgEvent = AppExecFwk::InnerEvent::Get(DEAMON_EXECUTE_REQUEST_SEND_FILE, requestSendFileData, 0);
368 {
369 std::lock_guard<std::mutex> lock(eventHandlerMutex_);
370 if (eventHandler_ == nullptr) {
371 LOGE("eventHandler has not find");
372 return E_EVENT_HANDLER;
373 }
374 bool isSucc = eventHandler_->SendEvent(msgEvent, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE);
375 if (!isSucc) {
376 LOGE("Daemon event handler post push asset event fail.");
377 return E_EVENT_HANDLER;
378 }
379 }
380
381 auto ret = requestSendFileBlock->GetValue();
382 LOGI("RequestSendFile end, ret is %{public}d", ret);
383 return ret;
384 }
385
PrepareSession(const std::string &srcUri, const std::string &dstUri, const std::string &srcDeviceId, const sptr<IRemoteObject> &listener, HmdfsInfo &info)386 int32_t Daemon::PrepareSession(const std::string &srcUri,
387 const std::string &dstUri,
388 const std::string &srcDeviceId,
389 const sptr<IRemoteObject> &listener,
390 HmdfsInfo &info)
391 {
392 LOGI("PrepareSession begin srcDeviceId: %{public}s", Utils::GetAnonyString(srcDeviceId).c_str());
393 AllConnectManager::GetInstance().PublishServiceState(srcDeviceId,
394 ServiceCollaborationManagerBussinessStatus::SCM_IDLE);
395
396 auto listenerCallback = iface_cast<IFileTransListener>(listener);
397 if (listenerCallback == nullptr) {
398 LOGE("ListenerCallback is nullptr");
399 return E_NULLPTR;
400 }
401
402 auto daemon = GetRemoteSA(srcDeviceId);
403 if (daemon == nullptr) {
404 LOGE("Daemon is nullptr");
405 return E_SA_LOAD_FAILED;
406 }
407
408 std::string physicalPath;
409 auto ret = GetRealPath(srcUri, dstUri, physicalPath, info, daemon);
410 if (ret != E_OK) {
411 LOGE("GetRealPath failed, ret = %{public}d", ret);
412 return ret;
413 }
414
415 SoftBusSessionPool::SessionInfo sessionInfo{.dstPath = physicalPath, .uid = IPCSkeleton::GetCallingUid()};
416 auto sessionName = SoftBusSessionPool::GetInstance().GenerateSessionName(sessionInfo);
417 if (sessionName.empty()) {
418 LOGE("SessionServer exceed max");
419 return E_SOFTBUS_SESSION_FAILED;
420 }
421 info.sessionName = sessionName;
422 StoreSessionAndListener(physicalPath, sessionName, listenerCallback);
423 auto socketId = SoftBusHandler::GetInstance().CreateSessionServer(IDaemon::SERVICE_NAME, sessionName,
424 DFS_CHANNLE_ROLE_SINK, physicalPath);
425 if (socketId <= 0) {
426 LOGE("CreateSessionServer failed, ret = %{public}d", ret);
427 DeleteSessionAndListener(sessionName, socketId);
428 return E_SOFTBUS_SESSION_FAILED;
429 }
430 physicalPath.clear();
431 if (info.authority == FILE_MANAGER_AUTHORITY || info.authority == MEDIA_AUTHORITY) {
432 LOGI("authority is media or docs");
433 physicalPath = "??" + info.dstPhysicalPath;
434 }
435 ret = Copy(srcUri, physicalPath, daemon, sessionName);
436 if (ret != E_OK) {
437 LOGE("Remote copy failed,ret = %{public}d", ret);
438 DeleteSessionAndListener(sessionName, socketId);
439 return ret;
440 }
441 return ret;
442 }
443
StoreSessionAndListener(const std::string &physicalPath, const std::string &sessionName, const sptr<IFileTransListener> &listener)444 void Daemon::StoreSessionAndListener(const std::string &physicalPath,
445 const std::string &sessionName,
446 const sptr<IFileTransListener> &listener)
447 {
448 TransManager::GetInstance().AddTransTask(sessionName, listener);
449 }
450
GetRealPath(const std::string &srcUri, const std::string &dstUri, std::string &physicalPath, HmdfsInfo &info, const sptr<IDaemon> &daemon)451 int32_t Daemon::GetRealPath(const std::string &srcUri,
452 const std::string &dstUri,
453 std::string &physicalPath,
454 HmdfsInfo &info,
455 const sptr<IDaemon> &daemon)
456 {
457 auto start = std::chrono::high_resolution_clock::now();
458 bool isSrcFile = false;
459 bool isSrcDir = false;
460 if (daemon == nullptr) {
461 LOGE("Daemon::GetRealPath daemon is nullptr");
462 return E_INVAL_ARG_NAPI;
463 }
464 auto ret = daemon->GetRemoteCopyInfo(srcUri, isSrcFile, isSrcDir);
465 if (ret != E_OK) {
466 LOGE("GetRemoteCopyInfo failed, ret = %{public}d", ret);
467 RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_FAILED,
468 RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::ERROR_CODE,
469 RadarReporter::GET_REMOTE_COPY_INFO_ERROR);
470 return E_SOFTBUS_SESSION_FAILED;
471 }
472
473 HapTokenInfo hapTokenInfo;
474 int result = AccessTokenKit::GetHapTokenInfo(IPCSkeleton::GetCallingTokenID(), hapTokenInfo);
475 if (result != Security::AccessToken::AccessTokenKitRet::RET_SUCCESS) {
476 LOGE("GetHapTokenInfo failed, errCode = %{public}d", result);
477 RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_FAILED,
478 RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::ERROR_CODE,
479 RadarReporter::GET_HAP_TOKEN_INFO_ERROR, RadarReporter::PACKAGE_NAME,
480 RadarReporter::accessTokenKit + to_string(result));
481 return E_GET_USER_ID;
482 }
483 ret = SandboxHelper::GetPhysicalPath(dstUri, std::to_string(hapTokenInfo.userID), physicalPath);
484 if (ret != E_OK) {
485 LOGE("invalid uri, ret = %{public}d", ret);
486 return E_GET_PHYSICAL_PATH_FAILED;
487 }
488
489 LOGI("physicalPath %{public}s, userId %{public}s", GetAnonyString(physicalPath).c_str(),
490 std::to_string(hapTokenInfo.userID).c_str());
491 info.dstPhysicalPath = physicalPath;
492 ret = CheckCopyRule(physicalPath, dstUri, hapTokenInfo, isSrcFile, info);
493 if (ret != E_OK) {
494 LOGE("CheckCopyRule failed, ret = %{public}d", ret);
495 return E_GET_PHYSICAL_PATH_FAILED;
496 }
497 auto end = std::chrono::high_resolution_clock::now();
498 auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
499 Utils::SysEventFileParse(duration.count());
500 return E_OK;
501 }
502
CheckCopyRule(std::string &physicalPath, const std::string &dstUri, HapTokenInfo &hapTokenInfo, const bool &isSrcFile, HmdfsInfo &info)503 int32_t Daemon::CheckCopyRule(std::string &physicalPath,
504 const std::string &dstUri,
505 HapTokenInfo &hapTokenInfo,
506 const bool &isSrcFile,
507 HmdfsInfo &info)
508 {
509 auto checkPath = physicalPath;
510 if (isSrcFile && !Utils::IsFolder(physicalPath)) {
511 auto pos = physicalPath.rfind('/');
512 if (pos == std::string::npos) {
513 LOGE("invalid file path");
514 return E_GET_PHYSICAL_PATH_FAILED;
515 }
516 physicalPath = physicalPath.substr(0, pos);
517 }
518
519 std::error_code errCode;
520 if (!std::filesystem::exists(physicalPath, errCode) && info.dirExistFlag) {
521 LOGI("Not CheckValidPath, physicalPath %{public}s", GetAnonyString(physicalPath).c_str());
522 } else {
523 auto pos = checkPath.rfind('/');
524 if (pos == std::string::npos) {
525 LOGE("invalid file path");
526 return E_GET_PHYSICAL_PATH_FAILED;
527 }
528 checkPath = checkPath.substr(0, pos);
529 if (!SandboxHelper::CheckValidPath(checkPath)) {
530 LOGE("invalid path.");
531 return E_GET_PHYSICAL_PATH_FAILED;
532 }
533 }
534
535 Uri uri(dstUri);
536 auto authority = uri.GetAuthority();
537 info.authority = authority;
538 if (authority != FILE_MANAGER_AUTHORITY && authority != MEDIA_AUTHORITY) {
539 auto bundleName = SoftBusSessionListener::GetBundleName(dstUri);
540 physicalPath = "/data/service/el2/" + to_string(hapTokenInfo.userID) + "/hmdfs/account/data/" + bundleName +
541 "/" + info.copyPath;
542 if (!SandboxHelper::CheckValidPath(physicalPath)) {
543 LOGE("invalid path.");
544 return E_GET_PHYSICAL_PATH_FAILED;
545 }
546 } else {
547 std::regex pathRegex("^[a-zA-Z0-9_\\-/\\\\]*$");
548 if (!std::filesystem::exists(physicalPath, errCode) && std::regex_match(physicalPath.c_str(), pathRegex)) {
549 std::filesystem::create_directory(physicalPath, errCode);
550 if (errCode.value() != 0) {
551 LOGE("Create directory failed, physicalPath %{public}s", GetAnonyString(physicalPath).c_str());
552 return E_GET_PHYSICAL_PATH_FAILED;
553 }
554 }
555 }
556 return E_OK;
557 }
558
GetRemoteCopyInfo(const std::string &srcUri, bool &isSrcFile, bool &srcIsDir)559 int32_t Daemon::GetRemoteCopyInfo(const std::string &srcUri, bool &isSrcFile, bool &srcIsDir)
560 {
561 LOGI("GetRemoteCopyInfo begin.");
562 auto physicalPath = SoftBusSessionListener::GetRealPath(srcUri);
563 if (physicalPath.empty()) {
564 LOGE("GetRemoteCopyInfo GetRealPath failed.");
565 return E_SOFTBUS_SESSION_FAILED;
566 }
567 isSrcFile = Utils::IsFile(physicalPath);
568 srcIsDir = Utils::IsFolder(physicalPath);
569 return E_OK;
570 }
571
GetRemoteSA(const std::string &remoteDeviceId)572 sptr<IDaemon> Daemon::GetRemoteSA(const std::string &remoteDeviceId)
573 {
574 LOGI("GetRemoteSA begin, DeviceId: %{public}s", Utils::GetAnonyString(remoteDeviceId).c_str());
575 auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
576 if (sam == nullptr) {
577 LOGE("Sam is nullptr");
578 return nullptr;
579 }
580
581 auto object = sam->GetSystemAbility(FILEMANAGEMENT_DISTRIBUTED_FILE_DAEMON_SA_ID, remoteDeviceId);
582 if (object == nullptr) {
583 LOGE("GetSystemAbility failed");
584 RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_FAILED,
585 RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::ERROR_CODE,
586 RadarReporter::GET_SYSTEM_ABILITY_ERROR, RadarReporter::PACKAGE_NAME, RadarReporter::saMgr);
587 return nullptr;
588 }
589 auto daemon = iface_cast<IDaemon>(object);
590 if (daemon == nullptr) {
591 LOGE("Connect service nullptr");
592 return nullptr;
593 }
594 LOGI("GetRemoteSA success, DeviceId: %{public}s", Utils::GetAnonyString(remoteDeviceId).c_str());
595 return daemon;
596 }
597
Copy(const std::string &srcUri, const std::string &dstPath, const sptr<IDaemon> &daemon, const std::string &sessionName)598 int32_t Daemon::Copy(const std::string &srcUri,
599 const std::string &dstPath,
600 const sptr<IDaemon> &daemon,
601 const std::string &sessionName)
602 {
603 auto &deviceManager = DistributedHardware::DeviceManager::GetInstance();
604 DistributedHardware::DmDeviceInfo localDeviceInfo{};
605 int errCode = deviceManager.GetLocalDeviceInfo(IDaemon::SERVICE_NAME, localDeviceInfo);
606 if (errCode != E_OK) {
607 LOGE("GetLocalDeviceInfo failed, errCode = %{public}d", errCode);
608 return E_GET_DEVICE_ID;
609 }
610 if (daemon == nullptr) {
611 LOGE("Daemon::Copy daemon is nullptr");
612 return E_INVAL_ARG_NAPI;
613 }
614 LOGI("Copy localDeviceInfo.networkId: %{public}s", Utils::GetAnonyString(localDeviceInfo.networkId).c_str());
615 auto ret = daemon->RequestSendFile(srcUri, dstPath, localDeviceInfo.networkId, sessionName);
616 if (ret != E_OK) {
617 LOGE("RequestSendFile failed, ret = %{public}d", ret);
618 RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_FAILED,
619 RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::ERROR_CODE,
620 RadarReporter::REQUEST_SEND_FILE_ERROR, RadarReporter::PACKAGE_NAME, ret);
621 return E_SA_LOAD_FAILED;
622 }
623 return E_OK;
624 }
625
CancelCopyTask(const std::string &sessionName)626 int32_t Daemon::CancelCopyTask(const std::string &sessionName)
627 {
628 LOGI("Cancel copy task in. sessionName = %{public}s", sessionName.c_str());
629 SoftBusSessionPool::SessionInfo sessionInfo{};
630 bool isExist = SoftBusSessionPool::GetInstance().GetSessionInfo(sessionName, sessionInfo);
631 if (!isExist) {
632 LOGE("CancelCopyTask failed, cannot get session info for input session name=%{public}s.", sessionName.c_str());
633 return E_INVAL_ARG;
634 }
635 auto callingUid = IPCSkeleton::GetCallingUid();
636 if (callingUid != sessionInfo.uid) {
637 LOGE("CancelCopyTask failed, calling uid=%{public}d has no permission to cancel copy for uid=%{public}d.",
638 callingUid, sessionInfo.uid);
639 return E_PERMISSION_DENIED;
640 }
641 SoftBusHandler::GetInstance().CloseSessionWithSessionName(sessionName);
642 return E_OK;
643 }
644
DeleteSessionAndListener(const std::string &sessionName, const int32_t socketId)645 void Daemon::DeleteSessionAndListener(const std::string &sessionName, const int32_t socketId)
646 {
647 SoftBusSessionPool::GetInstance().DeleteSessionInfo(sessionName);
648 TransManager::GetInstance().DeleteTransTask(sessionName);
649 SoftBusHandler::GetInstance().CloseSession(socketId, sessionName);
650 }
651
OnRemoteDied(const wptr<IRemoteObject> &remote)652 void Daemon::DfsListenerDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
653 {
654 sptr<IRemoteObject> diedRemote = remote.promote();
655 if (diedRemote == nullptr) {
656 LOGE("Daemon::DfsListenerDeathRecipient OnremoteDied received died notify nullptr");
657 return;
658 }
659 auto deviceManager = DeviceManagerAgent::GetInstance();
660 uint32_t callingTokenId = 0;
661 sptr<IFileDfsListener> listener = nullptr;
662 deviceManager->FindListenerByObject(remote, callingTokenId, listener);
663 if (callingTokenId==0 || listener == nullptr) {
664 LOGE("fail to FindListenerByObject");
665 return;
666 }
667 if (deviceManager->RemoveRemoteReverseObj(false, callingTokenId) != E_OK) {
668 LOGE("fail to RemoveRemoteReverseObj");
669 }
670 auto networkIdSet = deviceManager->GetNetworkIds(callingTokenId);
671 if (networkIdSet.empty()) {
672 LOGE("fail to get networkIdSet");
673 return;
674 }
675 for (auto it = networkIdSet.begin(); it != networkIdSet.end(); ++it) {
676 if (it->empty()) {
677 LOGE("[DfsListenerDeathRecipient] networkId is null");
678 continue;
679 }
680 std::string deviceId = deviceManager->GetDeviceIdByNetworkId(*it);
681 if (deviceId.empty()) {
682 LOGE("fail to get deviceId, networkId: %{public}s", Utils::GetAnonyString(*it).c_str());
683 continue;
684 }
685 deviceManager->UMountDfsDocs(*it, deviceId, false);
686 DistributedHardware::DmDeviceInfo deviceInfo{};
687 auto res = strcpy_s(deviceInfo.networkId, it->size() + 1, it->c_str());
688 if (res != 0) {
689 LOGE("strcpy failed, res = %{public}d", res);
690 return;
691 }
692 std::thread([=]() {
693 int32_t ret = deviceManager->OnDeviceP2POffline(deviceInfo);
694 LOGI("Close P2P Connection result %d", ret);
695 }).detach();
696 }
697 deviceManager->RemoveNetworkId(callingTokenId);
698 LOGI("Daemon::DfsListenerDeathRecipient OnremoteDied end");
699 return;
700 }
701
PushAsset(int32_t userId, const sptr<AssetObj> &assetObj, const sptr<IAssetSendCallback> &sendCallback)702 int32_t Daemon::PushAsset(int32_t userId,
703 const sptr<AssetObj> &assetObj,
704 const sptr<IAssetSendCallback> &sendCallback)
705 {
706 LOGI("Daemon::PushAsset begin.");
707 if (assetObj == nullptr || sendCallback == nullptr) {
708 LOGE("param is nullptr.");
709 return E_NULLPTR;
710 }
711 auto taskId = assetObj->srcBundleName_ + assetObj->sessionId_;
712 if (taskId.empty()) {
713 LOGE("assetObj info is null.");
714 return E_NULLPTR;
715 }
716 AssetCallbackManager::GetInstance().AddSendCallback(taskId, sendCallback);
717 auto pushData = std::make_shared<PushAssetData>(userId, assetObj);
718 auto msgEvent = AppExecFwk::InnerEvent::Get(DEAMON_EXECUTE_PUSH_ASSET, pushData, 0);
719
720 std::lock_guard<std::mutex> lock(eventHandlerMutex_);
721 if (eventHandler_ == nullptr) {
722 LOGE("eventHandler has not find");
723 AssetCallbackManager::GetInstance().RemoveSendCallback(taskId);
724 return E_EVENT_HANDLER;
725 }
726 bool isSucc = eventHandler_->SendEvent(msgEvent, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE);
727 if (!isSucc) {
728 LOGE("Daemon event handler post push asset event fail.");
729 AssetCallbackManager::GetInstance().RemoveSendCallback(taskId);
730 return E_EVENT_HANDLER;
731 }
732 return E_OK;
733 }
734
RegisterAssetCallback(const sptr<IAssetRecvCallback> &recvCallback)735 int32_t Daemon::RegisterAssetCallback(const sptr<IAssetRecvCallback> &recvCallback)
736 {
737 LOGI("Daemon::RegisterAssetCallback begin.");
738 if (recvCallback == nullptr) {
739 LOGE("recvCallback is nullptr.");
740 return E_NULLPTR;
741 }
742 AssetCallbackManager::GetInstance().AddRecvCallback(recvCallback);
743 return E_OK;
744 }
745
UnRegisterAssetCallback(const sptr<IAssetRecvCallback> &recvCallback)746 int32_t Daemon::UnRegisterAssetCallback(const sptr<IAssetRecvCallback> &recvCallback)
747 {
748 LOGI("Daemon::UnRegisterAssetCallback begin.");
749 if (recvCallback == nullptr) {
750 LOGE("recvCallback is nullptr.");
751 return E_NULLPTR;
752 }
753 AssetCallbackManager::GetInstance().RemoveRecvCallback(recvCallback);
754 return E_OK;
755 }
756
StartEventHandler()757 void Daemon::StartEventHandler()
758 {
759 LOGI("StartEventHandler begin");
760 if (daemonExecute_ == nullptr) {
761 daemonExecute_ = std::make_shared<DaemonExecute>();
762 }
763
764 std::lock_guard<std::mutex> lock(eventHandlerMutex_);
765 auto runer = AppExecFwk::EventRunner::Create(IDaemon::SERVICE_NAME.c_str());
766 eventHandler_ = std::make_shared<DaemonEventHandler>(runer, daemonExecute_);
767 }
768 } // namespace DistributedFile
769 } // namespace Storage
770 } // namespace OHOS