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