• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 "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 "connect_count/connect_count.h"
33 #include "device/device_manager_agent.h"
34 #include "dfs_daemon_event_dfx.h"
35 #include "dfs_error.h"
36 #include "dfsu_access_token_helper.h"
37 #include "i_file_dfs_listener.h"
38 #include "ipc_skeleton.h"
39 #include "iremote_object.h"
40 #include "iservice_registry.h"
41 #include "mountpoint/mount_manager.h"
42 #include "network/softbus/softbus_handler_asset.h"
43 #include "network/softbus/softbus_handler.h"
44 #include "network/softbus/softbus_session_dispatcher.h"
45 #include "network/softbus/softbus_session_pool.h"
46 #include "network/softbus/softbus_session_listener.h"
47 #include "sandbox_helper.h"
48 #include "system_ability_definition.h"
49 #include "trans_mananger.h"
50 #include "utils_directory.h"
51 #include "utils_log.h"
52 
53 namespace OHOS {
54 namespace Storage {
55 namespace DistributedFile {
56 using namespace std;
57 using namespace OHOS::AppFileService;
58 using namespace OHOS::FileManagement;
59 using namespace OHOS::Storage::DistributedFile;
60 using HapTokenInfo = OHOS::Security::AccessToken::HapTokenInfo;
61 using AccessTokenKit = OHOS::Security::AccessToken::AccessTokenKit;
62 
63 namespace {
64 const string FILE_MANAGER_AUTHORITY = "docs";
65 const string MEDIA_AUTHORITY = "media";
66 const int32_t E_PERMISSION_DENIED_NAPI = 201;
67 const int32_t E_INVAL_ARG_NAPI = 401;
68 const int32_t E_CONNECTION_FAILED = 13900045;
69 const int32_t E_UNMOUNT = 13600004;
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     std::lock_guard<std::mutex> lock(connectMutex_);
172     LOGI("OpenP2PConnection networkId %{public}s", Utils::GetAnonyString(deviceInfo.networkId).c_str());
173     RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_BUILD__LINK, RadarReporter::DFX_SUCCESS,
174                  RadarReporter::BIZ_STATE, RadarReporter::DFX_BEGIN);
175     auto callingTokenId = IPCSkeleton::GetCallingTokenID();
176     sptr<IFileDfsListener> listener = nullptr;
177     auto ret = ConnectionCount(deviceInfo);
178     if (ret == E_OK) {
179         ConnectCount::GetInstance()->AddConnect(callingTokenId, deviceInfo.networkId, listener);
180     } else {
181         CleanUp(deviceInfo);
182     }
183     return ret;
184 }
185 
CloseP2PConnection(const DistributedHardware::DmDeviceInfo & deviceInfo)186 int32_t Daemon::CloseP2PConnection(const DistributedHardware::DmDeviceInfo &deviceInfo)
187 {
188     std::lock_guard<std::mutex> lock(connectMutex_);
189     LOGI("Close P2P Connection networkId %{public}s", Utils::GetAnonyString(deviceInfo.networkId).c_str());
190     auto callingTokenId = IPCSkeleton::GetCallingTokenID();
191     auto networkId = std::string(deviceInfo.networkId);
192     ConnectCount::GetInstance()->RemoveConnect(callingTokenId, networkId);
193     CleanUp(deviceInfo);
194     return 0;
195 }
196 
ConnectionCount(const DistributedHardware::DmDeviceInfo & deviceInfo)197 int32_t Daemon::ConnectionCount(const DistributedHardware::DmDeviceInfo &deviceInfo)
198 {
199     auto path = ConnectionDetector::ParseHmdfsPath();
200     stringstream ss;
201     auto st_dev = ConnectionDetector::MocklispHash(path);
202     if (st_dev == static_cast<uint64_t>(FileManagement::ERR_BAD_VALUE)) {
203         return st_dev;
204     }
205     ss << st_dev;
206     auto targetDir = ss.str();
207     auto networkId = std::string(deviceInfo.networkId);
208     int32_t ret = 0;
209     if (!ConnectCount::GetInstance()->CheckCount(networkId)) {
210         ret = DeviceManagerAgent::GetInstance()->OnDeviceP2POnline(deviceInfo);
211         if (ret == NO_ERROR) {
212             ret = ConnectionDetector::RepeatGetConnectionStatus(targetDir, networkId);
213         }
214     }
215     if (ret == E_OK) {
216         RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_BUILD__LINK, RadarReporter::DFX_SUCCESS,
217                      RadarReporter::BIZ_STATE, RadarReporter::DFX_BEGIN);
218         LOGI("RepeatGetConnectionStatus end, ret = %{public}d", ret);
219     } else {
220         RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_BUILD__LINK, RadarReporter::DFX_FAILED,
221                      RadarReporter::BIZ_STATE, RadarReporter::DFX_BEGIN);
222         LOGE("OpenP2PConnection failed, ret = %{public}d", ret);
223     }
224     return ret;
225 }
226 
CleanUp(const DistributedHardware::DmDeviceInfo & deviceInfo)227 int32_t Daemon::CleanUp(const DistributedHardware::DmDeviceInfo &deviceInfo)
228 {
229     LOGI("CleanUp start");
230     auto networkId = std::string(deviceInfo.networkId);
231     if (!ConnectCount::GetInstance()->CheckCount(networkId)) {
232         int32_t ret = DeviceManagerAgent::GetInstance()->OnDeviceP2POffline(deviceInfo);
233         LOGI("Close P2P Connection result %{public}d", ret);
234         return ret;
235     }
236     return E_OK;
237 }
238 
ConnectionAndMount(const DistributedHardware::DmDeviceInfo & deviceInfo,const std::string & networkId,uint32_t callingTokenId,sptr<IFileDfsListener> remoteReverseObj)239 int32_t Daemon::ConnectionAndMount(const DistributedHardware::DmDeviceInfo &deviceInfo,
240     const std::string &networkId, uint32_t callingTokenId, sptr<IFileDfsListener> remoteReverseObj)
241 {
242     LOGI("ConnectionAndMount start");
243     int32_t ret = NO_ERROR;
244     ret = ConnectionCount(deviceInfo);
245     if (ret != NO_ERROR) {
246         LOGE("connection failed");
247         return ret;
248     }
249     ConnectCount::GetInstance()->AddConnect(callingTokenId, networkId, remoteReverseObj);
250 
251     if (!DfsuAccessTokenHelper::CheckCallerPermission(FILE_ACCESS_MANAGER_PERMISSION)) {
252         LOGW("permission denied: FILE_ACCESS_MANAGER_PERMISSION");
253         return ret;
254     }
255     auto deviceManager = DeviceManagerAgent::GetInstance();
256     std::string deviceId = deviceManager->GetDeviceIdByNetworkId(networkId);
257     ret = deviceManager->MountDfsDocs(networkId, deviceId);
258     if (ret != NO_ERROR) {
259         ConnectCount::GetInstance()->RemoveConnect(callingTokenId, networkId);
260         LOGE("[MountDfsDocs] failed");
261     }
262     return ret;
263 }
264 
OpenP2PConnectionEx(const std::string & networkId,sptr<IFileDfsListener> remoteReverseObj)265 int32_t Daemon::OpenP2PConnectionEx(const std::string &networkId, sptr<IFileDfsListener> remoteReverseObj)
266 {
267     std::lock_guard<std::mutex> lock(connectMutex_);
268     LOGI("Daemon::OpenP2PConnectionEx start, networkId %{public}s", Utils::GetAnonyString(networkId).c_str());
269     if (!DfsuAccessTokenHelper::CheckCallerPermission(PERM_DISTRIBUTED_DATASYNC)) {
270         LOGE("[OpenP2PConnectionEx] DATASYNC permission denied");
271         return E_PERMISSION_DENIED_NAPI;
272     }
273     if (dfsListenerDeathRecipient_ == nullptr) {
274         LOGE("Daemon::OpenP2PConnectionEx, new death recipient");
275         dfsListenerDeathRecipient_ = new (std::nothrow) DfsListenerDeathRecipient();
276     }
277     if (remoteReverseObj == nullptr) {
278         LOGE("Daemon::OpenP2PConnectionEx remoteReverseObj is nullptr");
279         return E_INVAL_ARG_NAPI;
280     }
281     remoteReverseObj->AsObject()->AddDeathRecipient(dfsListenerDeathRecipient_);
282     auto deviceManager = DeviceManagerAgent::GetInstance();
283     if (networkId.empty() || networkId.length() >= DM_MAX_DEVICE_ID_LEN) {
284         LOGE("Daemon::OpenP2PConnectionEx networkId length is invalid.");
285         return E_INVAL_ARG_NAPI;
286     }
287     DistributedHardware::DmDeviceInfo deviceInfo{};
288     auto res = strcpy_s(deviceInfo.networkId, DM_MAX_DEVICE_ID_LEN, networkId.c_str());
289     if (res != NO_ERROR) {
290         LOGE("OpenP2PConnectionEx strcpy failed, res = %{public}d", res);
291         return E_INVAL_ARG_NAPI;
292     }
293     auto callingTokenId = IPCSkeleton::GetCallingTokenID();
294     int32_t ret = ConnectionAndMount(deviceInfo, networkId, callingTokenId, remoteReverseObj);
295     if (ret != NO_ERROR) {
296         CleanUp(deviceInfo);
297         return E_CONNECTION_FAILED;
298     }
299     LOGI("Daemon::OpenP2PConnectionEx end");
300     return ret;
301 }
302 
CloseP2PConnectionEx(const std::string & networkId)303 int32_t Daemon::CloseP2PConnectionEx(const std::string &networkId)
304 {
305     std::lock_guard<std::mutex> lock(connectMutex_);
306     LOGI("Daemon::CloseP2PConnectionEx start, networkId: %{public}s", Utils::GetAnonyString(networkId).c_str());
307     if (!DfsuAccessTokenHelper::CheckCallerPermission(PERM_DISTRIBUTED_DATASYNC)) {
308         LOGE("[CloseP2PConnectionEx] DATASYNC permission denied");
309         return E_PERMISSION_DENIED_NAPI;
310     }
311     auto deviceManager = DeviceManagerAgent::GetInstance();
312     auto callingTokenId = IPCSkeleton::GetCallingTokenID();
313     if (networkId.empty() || networkId.length() >= DM_MAX_DEVICE_ID_LEN) {
314         LOGE("Daemon::CloseP2PConnectionEx networkId length is invalid.");
315         return E_INVAL_ARG_NAPI;
316     }
317     std::string deviceId = deviceManager->GetDeviceIdByNetworkId(networkId);
318     if (deviceId.empty()) {
319         LOGE("fail to get deviceId");
320         return E_CONNECTION_FAILED;
321     }
322     if (DfsuAccessTokenHelper::CheckCallerPermission(FILE_ACCESS_MANAGER_PERMISSION)) {
323         LOGE("[UMountDfsDocs] permission ok: FILE_ACCESS_MANAGER_PERMISSION");
324         int32_t ret_umount = deviceManager->UMountDfsDocs(networkId, deviceId, false);
325         if (ret_umount != E_OK) {
326             LOGE("[UMountDfsDocs] failed");
327             return E_UNMOUNT;
328         }
329     }
330     DistributedHardware::DmDeviceInfo deviceInfo{};
331     auto res = strcpy_s(deviceInfo.networkId, DM_MAX_DEVICE_ID_LEN, networkId.c_str());
332     if (res != NO_ERROR) {
333         LOGE("strcpy failed, res = %{public}d", res);
334         return E_INVAL_ARG_NAPI;
335     }
336     ConnectCount::GetInstance()->RemoveConnect(callingTokenId, networkId);
337     int32_t ret = CleanUp(deviceInfo);
338     if (ret != NO_ERROR) {
339         LOGE("Daemon::CloseP2PConnectionEx disconnection failed");
340         return E_CONNECTION_FAILED;
341     }
342     LOGI("Daemon::CloseP2PConnectionEx end");
343     return 0;
344 }
345 
RequestSendFile(const std::string & srcUri,const std::string & dstPath,const std::string & dstDeviceId,const std::string & sessionName)346 int32_t Daemon::RequestSendFile(const std::string &srcUri,
347                                 const std::string &dstPath,
348                                 const std::string &dstDeviceId,
349                                 const std::string &sessionName)
350 {
351     LOGI("RequestSendFile begin dstDeviceId: %{public}s", Utils::GetAnonyString(dstDeviceId).c_str());
352     auto requestSendFileBlock = std::make_shared<BlockObject<int32_t>>(BLOCK_INTERVAL_SEND_FILE, ERR_BAD_VALUE);
353     auto requestSendFileData = std::make_shared<RequestSendFileData>(
354         srcUri, dstPath, dstDeviceId, sessionName, requestSendFileBlock);
355     auto msgEvent = AppExecFwk::InnerEvent::Get(DEAMON_EXECUTE_REQUEST_SEND_FILE, requestSendFileData, 0);
356     {
357         std::lock_guard<std::mutex> lock(eventHandlerMutex_);
358         if (eventHandler_ == nullptr) {
359             LOGE("eventHandler has not find");
360             return E_EVENT_HANDLER;
361         }
362         bool isSucc = eventHandler_->SendEvent(msgEvent, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE);
363         if (!isSucc) {
364             LOGE("Daemon event handler post push asset event fail.");
365             return E_EVENT_HANDLER;
366         }
367     }
368 
369     auto ret = requestSendFileBlock->GetValue();
370     LOGI("RequestSendFile end, ret is %{public}d", ret);
371     return ret;
372 }
373 
PrepareSession(const std::string & srcUri,const std::string & dstUri,const std::string & srcDeviceId,const sptr<IRemoteObject> & listener,HmdfsInfo & info)374 int32_t Daemon::PrepareSession(const std::string &srcUri,
375                                const std::string &dstUri,
376                                const std::string &srcDeviceId,
377                                const sptr<IRemoteObject> &listener,
378                                HmdfsInfo &info)
379 {
380     LOGI("PrepareSession begin srcDeviceId: %{public}s", Utils::GetAnonyString(srcDeviceId).c_str());
381     auto listenerCallback = iface_cast<IFileTransListener>(listener);
382     if (listenerCallback == nullptr) {
383         LOGE("ListenerCallback is nullptr");
384         return E_NULLPTR;
385     }
386 
387     auto daemon = GetRemoteSA(srcDeviceId);
388     if (daemon == nullptr) {
389         LOGE("Daemon is nullptr");
390         return E_SA_LOAD_FAILED;
391     }
392 
393     std::string physicalPath;
394     auto ret = GetRealPath(srcUri, dstUri, physicalPath, info, daemon);
395     if (ret != E_OK) {
396         LOGE("GetRealPath failed, ret = %{public}d", ret);
397         return ret;
398     }
399 
400     SoftBusSessionPool::SessionInfo sessionInfo{.dstPath = physicalPath, .uid = IPCSkeleton::GetCallingUid()};
401     auto sessionName = SoftBusSessionPool::GetInstance().GenerateSessionName(sessionInfo);
402     if (sessionName.empty()) {
403         LOGE("SessionServer exceed max");
404         return E_SOFTBUS_SESSION_FAILED;
405     }
406     info.sessionName = sessionName;
407     StoreSessionAndListener(physicalPath, sessionName, listenerCallback);
408 
409     auto prepareSessionBlock = std::make_shared<BlockObject<int32_t>>(BLOCK_INTERVAL_SEND_FILE, ERR_BAD_VALUE);
410     auto prepareSessionData = std::make_shared<PrepareSessionData>(
411         srcUri, physicalPath, sessionName, daemon, info, prepareSessionBlock);
412     auto msgEvent = AppExecFwk::InnerEvent::Get(DEAMON_EXECUTE_PREPARE_SESSION, prepareSessionData, 0);
413     {
414         std::lock_guard<std::mutex> lock(eventHandlerMutex_);
415         if (eventHandler_ == nullptr) {
416             LOGE("eventHandler has not find");
417             return E_EVENT_HANDLER;
418         }
419         bool isSucc = eventHandler_->SendEvent(msgEvent, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE);
420         if (!isSucc) {
421             LOGE("Daemon event handler post Prepare Session event fail.");
422             return E_EVENT_HANDLER;
423         }
424     }
425 
426     ret = prepareSessionBlock->GetValue();
427     LOGI("PrepareSession end, ret is %{public}d", ret);
428     return ret;
429 }
430 
StoreSessionAndListener(const std::string & physicalPath,const std::string & sessionName,const sptr<IFileTransListener> & listener)431 void Daemon::StoreSessionAndListener(const std::string &physicalPath,
432                                      const std::string &sessionName,
433                                      const sptr<IFileTransListener> &listener)
434 {
435     TransManager::GetInstance().AddTransTask(sessionName, listener);
436 }
437 
GetRealPath(const std::string & srcUri,const std::string & dstUri,std::string & physicalPath,HmdfsInfo & info,const sptr<IDaemon> & daemon)438 int32_t Daemon::GetRealPath(const std::string &srcUri,
439                             const std::string &dstUri,
440                             std::string &physicalPath,
441                             HmdfsInfo &info,
442                             const sptr<IDaemon> &daemon)
443 {
444     auto start = std::chrono::high_resolution_clock::now();
445     bool isSrcFile = false;
446     bool isSrcDir = false;
447     if (daemon == nullptr) {
448         LOGE("Daemon::GetRealPath daemon is nullptr");
449         return E_INVAL_ARG_NAPI;
450     }
451     auto ret = daemon->GetRemoteCopyInfo(srcUri, isSrcFile, isSrcDir);
452     if (ret != E_OK) {
453         LOGE("GetRemoteCopyInfo failed, ret = %{public}d", ret);
454         RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_FAILED,
455             RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::ERROR_CODE,
456             RadarReporter::GET_REMOTE_COPY_INFO_ERROR);
457         return E_SOFTBUS_SESSION_FAILED;
458     }
459 
460     HapTokenInfo hapTokenInfo;
461     int result = AccessTokenKit::GetHapTokenInfo(IPCSkeleton::GetCallingTokenID(), hapTokenInfo);
462     if (result != Security::AccessToken::AccessTokenKitRet::RET_SUCCESS) {
463         LOGE("GetHapTokenInfo failed, errCode = %{public}d", result);
464         RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_FAILED,
465             RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::ERROR_CODE,
466             RadarReporter::GET_HAP_TOKEN_INFO_ERROR, RadarReporter::PACKAGE_NAME,
467             RadarReporter::accessTokenKit + to_string(result));
468         return E_GET_USER_ID;
469     }
470     ret = SandboxHelper::GetPhysicalPath(dstUri, std::to_string(hapTokenInfo.userID), physicalPath);
471     if (ret != E_OK) {
472         LOGE("invalid uri, ret = %{public}d", ret);
473         return E_GET_PHYSICAL_PATH_FAILED;
474     }
475 
476     LOGI("physicalPath %{public}s, userId %{public}s", GetAnonyString(physicalPath).c_str(),
477          std::to_string(hapTokenInfo.userID).c_str());
478     info.dstPhysicalPath = physicalPath;
479     ret = CheckCopyRule(physicalPath, dstUri, hapTokenInfo, isSrcFile, info);
480     if (ret != E_OK) {
481         LOGE("CheckCopyRule failed, ret = %{public}d", ret);
482         return E_GET_PHYSICAL_PATH_FAILED;
483     }
484     auto end = std::chrono::high_resolution_clock::now();
485     auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
486     Utils::SysEventFileParse(duration.count());
487     return E_OK;
488 }
489 
CheckCopyRule(std::string & physicalPath,const std::string & dstUri,HapTokenInfo & hapTokenInfo,const bool & isSrcFile,HmdfsInfo & info)490 int32_t Daemon::CheckCopyRule(std::string &physicalPath,
491                               const std::string &dstUri,
492                               HapTokenInfo &hapTokenInfo,
493                               const bool &isSrcFile,
494                               HmdfsInfo &info)
495 {
496     auto checkPath = physicalPath;
497     if (isSrcFile && !Utils::IsFolder(physicalPath)) {
498         auto pos = physicalPath.rfind('/');
499         if (pos == std::string::npos) {
500             LOGE("invalid file path");
501             return E_GET_PHYSICAL_PATH_FAILED;
502         }
503         physicalPath = physicalPath.substr(0, pos);
504     }
505 
506     std::error_code errCode;
507     if (!std::filesystem::exists(physicalPath, errCode) && info.dirExistFlag) {
508         LOGI("Not CheckValidPath, physicalPath %{public}s", GetAnonyString(physicalPath).c_str());
509     } else {
510         auto pos = checkPath.rfind('/');
511         if (pos == std::string::npos) {
512             LOGE("invalid file path");
513             return E_GET_PHYSICAL_PATH_FAILED;
514         }
515         checkPath = checkPath.substr(0, pos);
516         if (!SandboxHelper::CheckValidPath(checkPath)) {
517             LOGE("invalid path.");
518             return E_GET_PHYSICAL_PATH_FAILED;
519         }
520     }
521 
522     Uri uri(dstUri);
523     auto authority = uri.GetAuthority();
524     info.authority = authority;
525     if (authority != FILE_MANAGER_AUTHORITY && authority != MEDIA_AUTHORITY) {
526         auto bundleName = SoftBusSessionListener::GetBundleName(dstUri);
527         physicalPath = "/data/service/el2/" + to_string(hapTokenInfo.userID) + "/hmdfs/account/data/" + bundleName +
528                        "/" + info.copyPath;
529         if (!SandboxHelper::CheckValidPath(physicalPath)) {
530             LOGE("invalid path.");
531             return E_GET_PHYSICAL_PATH_FAILED;
532         }
533     } else {
534         std::regex pathRegex("^[a-zA-Z0-9_\\-/\\\\]*$");
535         if (!std::filesystem::exists(physicalPath, errCode) && std::regex_match(physicalPath.c_str(), pathRegex)) {
536             std::filesystem::create_directory(physicalPath, errCode);
537             if (errCode.value() != 0) {
538                 LOGE("Create directory failed, physicalPath %{public}s", GetAnonyString(physicalPath).c_str());
539                 return E_GET_PHYSICAL_PATH_FAILED;
540             }
541         }
542     }
543     return E_OK;
544 }
545 
GetRemoteCopyInfo(const std::string & srcUri,bool & isSrcFile,bool & srcIsDir)546 int32_t Daemon::GetRemoteCopyInfo(const std::string &srcUri, bool &isSrcFile, bool &srcIsDir)
547 {
548     LOGI("GetRemoteCopyInfo begin.");
549     auto physicalPath = SoftBusSessionListener::GetRealPath(srcUri);
550     if (physicalPath.empty()) {
551         LOGE("GetRemoteCopyInfo GetRealPath failed.");
552         return E_SOFTBUS_SESSION_FAILED;
553     }
554     isSrcFile = Utils::IsFile(physicalPath);
555     srcIsDir = Utils::IsFolder(physicalPath);
556     return E_OK;
557 }
558 
GetRemoteSA(const std::string & remoteDeviceId)559 sptr<IDaemon> Daemon::GetRemoteSA(const std::string &remoteDeviceId)
560 {
561     LOGI("GetRemoteSA begin, DeviceId: %{public}s", Utils::GetAnonyString(remoteDeviceId).c_str());
562     auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
563     if (sam == nullptr) {
564         LOGE("Sam is nullptr");
565         return nullptr;
566     }
567 
568     auto object = sam->GetSystemAbility(FILEMANAGEMENT_DISTRIBUTED_FILE_DAEMON_SA_ID, remoteDeviceId);
569     if (object == nullptr) {
570         LOGE("GetSystemAbility failed");
571         RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_FAILED,
572             RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::ERROR_CODE,
573             RadarReporter::GET_SYSTEM_ABILITY_ERROR, RadarReporter::PACKAGE_NAME, RadarReporter::saMgr);
574         return nullptr;
575     }
576     auto daemon = iface_cast<IDaemon>(object);
577     if (daemon == nullptr) {
578         LOGE("Connect service nullptr");
579         return nullptr;
580     }
581     LOGI("GetRemoteSA success, DeviceId: %{public}s", Utils::GetAnonyString(remoteDeviceId).c_str());
582     return daemon;
583 }
584 
Copy(const std::string & srcUri,const std::string & dstPath,const sptr<IDaemon> & daemon,const std::string & sessionName)585 int32_t Daemon::Copy(const std::string &srcUri,
586                      const std::string &dstPath,
587                      const sptr<IDaemon> &daemon,
588                      const std::string &sessionName)
589 {
590     auto &deviceManager = DistributedHardware::DeviceManager::GetInstance();
591     DistributedHardware::DmDeviceInfo localDeviceInfo{};
592     int errCode = deviceManager.GetLocalDeviceInfo(IDaemon::SERVICE_NAME, localDeviceInfo);
593     if (errCode != E_OK) {
594         LOGE("GetLocalDeviceInfo failed, errCode = %{public}d", errCode);
595         return E_GET_DEVICE_ID;
596     }
597     if (daemon == nullptr) {
598         LOGE("Daemon::Copy daemon is nullptr");
599         return E_INVAL_ARG_NAPI;
600     }
601     LOGI("Copy localDeviceInfo.networkId: %{public}s", Utils::GetAnonyString(localDeviceInfo.networkId).c_str());
602     auto ret = daemon->RequestSendFile(srcUri, dstPath, localDeviceInfo.networkId, sessionName);
603     if (ret != E_OK) {
604         LOGE("RequestSendFile failed, ret = %{public}d", ret);
605         RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_FAILED,
606             RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::ERROR_CODE,
607             RadarReporter::REQUEST_SEND_FILE_ERROR, RadarReporter::PACKAGE_NAME, ret);
608         return E_SA_LOAD_FAILED;
609     }
610     return E_OK;
611 }
612 
CancelCopyTask(const std::string & sessionName)613 int32_t Daemon::CancelCopyTask(const std::string &sessionName)
614 {
615     LOGI("Cancel copy task in. sessionName = %{public}s", sessionName.c_str());
616     SoftBusSessionPool::SessionInfo sessionInfo{};
617     bool isExist = SoftBusSessionPool::GetInstance().GetSessionInfo(sessionName, sessionInfo);
618     if (!isExist) {
619         LOGE("CancelCopyTask failed, cannot get session info for input session name=%{public}s.", sessionName.c_str());
620         return E_INVAL_ARG;
621     }
622     auto callingUid = IPCSkeleton::GetCallingUid();
623     if (callingUid != sessionInfo.uid) {
624         LOGE("CancelCopyTask failed, calling uid=%{public}d has no permission to cancel copy for uid=%{public}d.",
625              callingUid, sessionInfo.uid);
626         return E_PERMISSION_DENIED;
627     }
628     SoftBusHandler::GetInstance().CloseSessionWithSessionName(sessionName);
629     return E_OK;
630 }
631 
DeleteSessionAndListener(const std::string & sessionName,const int32_t socketId)632 void Daemon::DeleteSessionAndListener(const std::string &sessionName, const int32_t socketId)
633 {
634     SoftBusSessionPool::GetInstance().DeleteSessionInfo(sessionName);
635     TransManager::GetInstance().DeleteTransTask(sessionName);
636     SoftBusHandler::GetInstance().CloseSession(socketId, sessionName);
637 }
638 
OnRemoteDied(const wptr<IRemoteObject> & remote)639 void Daemon::DfsListenerDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
640 {
641     sptr<IRemoteObject> diedRemote = remote.promote();
642     if (diedRemote == nullptr) {
643         LOGE("Daemon::DfsListenerDeathRecipient OnremoteDied received died notify nullptr");
644         return;
645     }
646 
647     uint32_t callingTokenId;
648     auto ret = ConnectCount::GetInstance()->FindCallingTokenIdForListerner(diedRemote, callingTokenId);
649     if (ret != E_OK) {
650         LOGE("fail to FindCallingTokenIdForListerner");
651         return;
652     }
653     auto networkIds = ConnectCount::GetInstance()->RemoveConnect(callingTokenId);
654     if (networkIds.empty()) {
655         LOGE("fail to get networkIdSet");
656         return;
657     }
658     auto deviceManager = DeviceManagerAgent::GetInstance();
659     for (auto it = networkIds.begin(); it != networkIds.end(); ++it) {
660         if (it->empty()) {
661             LOGE("[DfsListenerDeathRecipient] networkId is null");
662             continue;
663         }
664         std::string deviceId = deviceManager->GetDeviceIdByNetworkId(*it);
665         if (deviceId.empty()) {
666             LOGE("fail to get deviceId, networkId: %{public}s", Utils::GetAnonyString(*it).c_str());
667             continue;
668         }
669         deviceManager->UMountDfsDocs(*it, deviceId, false);
670         DistributedHardware::DmDeviceInfo deviceInfo{};
671         auto res = strcpy_s(deviceInfo.networkId, DM_MAX_DEVICE_ID_LEN, it->c_str());
672         if (res != 0) {
673             LOGE("strcpy failed, res = %{public}d", res);
674             return;
675         }
676         if (!ConnectCount::GetInstance()->CheckCount(*it)) {
677             DeviceManagerAgent::GetInstance()->OnDeviceP2POffline(deviceInfo);
678         }
679     }
680     LOGI("Daemon::DfsListenerDeathRecipient OnremoteDied end");
681     return;
682 }
683 
PushAsset(int32_t userId,const sptr<AssetObj> & assetObj,const sptr<IAssetSendCallback> & sendCallback)684 int32_t Daemon::PushAsset(int32_t userId,
685                           const sptr<AssetObj> &assetObj,
686                           const sptr<IAssetSendCallback> &sendCallback)
687 {
688     LOGI("Daemon::PushAsset begin.");
689     if (assetObj == nullptr || sendCallback == nullptr) {
690         LOGE("param is nullptr.");
691         return E_NULLPTR;
692     }
693     auto taskId = assetObj->srcBundleName_ + assetObj->sessionId_;
694     if (taskId.empty()) {
695         LOGE("assetObj info is null.");
696         return E_NULLPTR;
697     }
698     AssetCallbackManager::GetInstance().AddSendCallback(taskId, sendCallback);
699     auto pushData = std::make_shared<PushAssetData>(userId, assetObj);
700     auto msgEvent = AppExecFwk::InnerEvent::Get(DEAMON_EXECUTE_PUSH_ASSET, pushData, 0);
701 
702     std::lock_guard<std::mutex> lock(eventHandlerMutex_);
703     if (eventHandler_ == nullptr) {
704         LOGE("eventHandler has not find");
705         AssetCallbackManager::GetInstance().RemoveSendCallback(taskId);
706         return E_EVENT_HANDLER;
707     }
708     bool isSucc = eventHandler_->SendEvent(msgEvent, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE);
709     if (!isSucc) {
710         LOGE("Daemon event handler post push asset event fail.");
711         AssetCallbackManager::GetInstance().RemoveSendCallback(taskId);
712         return E_EVENT_HANDLER;
713     }
714     return E_OK;
715 }
716 
RegisterAssetCallback(const sptr<IAssetRecvCallback> & recvCallback)717 int32_t Daemon::RegisterAssetCallback(const sptr<IAssetRecvCallback> &recvCallback)
718 {
719     LOGI("Daemon::RegisterAssetCallback begin.");
720     if (recvCallback == nullptr) {
721         LOGE("recvCallback is nullptr.");
722         return E_NULLPTR;
723     }
724     AssetCallbackManager::GetInstance().AddRecvCallback(recvCallback);
725     return E_OK;
726 }
727 
UnRegisterAssetCallback(const sptr<IAssetRecvCallback> & recvCallback)728 int32_t Daemon::UnRegisterAssetCallback(const sptr<IAssetRecvCallback> &recvCallback)
729 {
730     LOGI("Daemon::UnRegisterAssetCallback begin.");
731     if (recvCallback == nullptr) {
732         LOGE("recvCallback is nullptr.");
733         return E_NULLPTR;
734     }
735     AssetCallbackManager::GetInstance().RemoveRecvCallback(recvCallback);
736     return E_OK;
737 }
738 
StartEventHandler()739 void Daemon::StartEventHandler()
740 {
741     LOGI("StartEventHandler begin");
742     if (daemonExecute_ == nullptr) {
743         daemonExecute_ = std::make_shared<DaemonExecute>();
744     }
745 
746     std::lock_guard<std::mutex> lock(eventHandlerMutex_);
747     auto runer = AppExecFwk::EventRunner::Create(IDaemon::SERVICE_NAME.c_str());
748     eventHandler_ = std::make_shared<DaemonEventHandler>(runer, daemonExecute_);
749 }
750 } // namespace DistributedFile
751 } // namespace Storage
752 } // namespace OHOS