• 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 "channel_manager.h"
30 #include "common_event_manager.h"
31 #include "common_event_support.h"
32 #include "connect_count/connect_count.h"
33 #include "connection_detector.h"
34 #include "control_cmd_parser.h"
35 #include "copy/file_size_utils.h"
36 #include "copy/remote_file_copy_manager.h"
37 #include "device/device_manager_agent.h"
38 #include "device/device_profile_adapter.h"
39 #include "dfs_daemon_event_dfx.h"
40 #include "dfs_error.h"
41 #include "dfsu_access_token_helper.h"
42 #include "i_file_dfs_listener.h"
43 #include "ipc_skeleton.h"
44 #include "iremote_object.h"
45 #include "iservice_registry.h"
46 #include "mountpoint/mount_manager.h"
47 #include "network/softbus/softbus_handler.h"
48 #include "network/softbus/softbus_handler_asset.h"
49 #include "network/softbus/softbus_permission_check.h"
50 #include "network/softbus/softbus_session_dispatcher.h"
51 #include "network/softbus/softbus_session_listener.h"
52 #include "network/softbus/softbus_session_pool.h"
53 #include "network/devsl_dispatcher.h"
54 #include "remote_file_share.h"
55 #include "sandbox_helper.h"
56 #include "system_ability_definition.h"
57 #include "system_notifier.h"
58 #include "trans_mananger.h"
59 #include "utils_directory.h"
60 #include "utils_log.h"
61 
62 namespace OHOS {
63 namespace Storage {
64 namespace DistributedFile {
65 using namespace std;
66 using namespace OHOS::AppFileService;
67 using namespace OHOS::FileManagement;
68 using namespace OHOS::Storage::DistributedFile;
69 using FileManagement::ERR_OK;
70 
71 using HapTokenInfo = OHOS::Security::AccessToken::HapTokenInfo;
72 using AccessTokenKit = OHOS::Security::AccessToken::AccessTokenKit;
73 
74 namespace {
75 const string FILE_MANAGER_AUTHORITY = "docs";
76 const string MEDIA_AUTHORITY = "media";
77 const int32_t E_PERMISSION_DENIED_NAPI = 201;
78 const int32_t E_INVAL_ARG_NAPI = 401;
79 const int32_t E_CONNECTION_FAILED = 13900045;
80 const int32_t E_UNMOUNT = 13600004;
81 const int32_t PASTEBOARDUSERID = 3816;
82 const int32_t UDMFUSERID = 3012;
83 constexpr mode_t DEFAULT_UMASK = 0002;
84 constexpr int32_t BLOCK_INTERVAL_SEND_FILE = 10 * 1000;
85 constexpr int32_t DEFAULT_USER_ID = 100;
86 constexpr int32_t VALID_MOUNT_NETWORKID_LEN = 16;
87 constexpr uint64_t INNER_COPY_LIMIT = 1024 * 1024 * 1024;
88 } // namespace
89 
90 REGISTER_SYSTEM_ABILITY_BY_ID(Daemon, FILEMANAGEMENT_DISTRIBUTED_FILE_DAEMON_SA_ID, true);
91 
QueryActiveUserId()92 static int32_t QueryActiveUserId()
93 {
94     std::vector<int32_t> ids;
95     ErrCode errCode = AccountSA::OsAccountManager::QueryActiveOsAccountIds(ids);
96     if (errCode != NO_ERROR || ids.empty()) {
97         LOGE("Query active userid failed, errCode: %{public}d, ", errCode);
98         return DEFAULT_USER_ID;
99     }
100     return ids[0];
101 }
102 
PublishSA()103 void Daemon::PublishSA()
104 {
105     LOGI("Begin to init");
106     if (!registerToService_) {
107         bool ret = SystemAbility::Publish(this);
108         if (!ret) {
109             throw runtime_error("Failed to publish the daemon");
110         }
111         registerToService_ = true;
112     }
113     LOGI("Init finished successfully");
114 }
115 
RegisterOsAccount()116 void Daemon::RegisterOsAccount()
117 {
118     EventFwk::MatchingSkills matchingSkills;
119     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USER_SWITCHED);
120     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USER_UNLOCKED);
121     EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills);
122     subScriber_ = std::make_shared<OsAccountObserver>(subscribeInfo);
123     bool subRet = EventFwk::CommonEventManager::SubscribeCommonEvent(subScriber_);
124     if (!subRet) {
125         LOGE("Subscribe common event failed");
126     }
127 }
128 
OnStart()129 void Daemon::OnStart()
130 {
131     LOGI("Begin to start service");
132     if (state_ == ServiceRunningState::STATE_RUNNING) {
133         LOGD("Daemon has already started");
134         return;
135     }
136 
137     try {
138         PublishSA();
139         StartEventHandler();
140         AddSystemAbilityListener(COMMON_EVENT_SERVICE_ID);
141         AddSystemAbilityListener(SOFTBUS_SERVER_SA_ID);
142         umask(DEFAULT_UMASK);
143         AllConnectManager::GetInstance().InitAllConnectManager();
144     } catch (const exception &e) {
145         LOGE("%{public}s", e.what());
146     }
147 
148     state_ = ServiceRunningState::STATE_RUNNING;
149     LOGI("Start service successfully");
150 }
151 
OnStop()152 void Daemon::OnStop()
153 {
154     LOGI("Begin to stop");
155     state_ = ServiceRunningState::STATE_NOT_START;
156     registerToService_ = false;
157     bool subRet = EventFwk::CommonEventManager::UnSubscribeCommonEvent(subScriber_);
158     if (!subRet) {
159         LOGE("UnSubscribe common event failed");
160     }
161     subScriber_ = nullptr;
162     daemonExecute_ = nullptr;
163     eventHandler_ = nullptr;
164     SoftBusHandlerAsset::GetInstance().DeleteAssetLocalSessionServer();
165     AllConnectManager::GetInstance().UnInitAllConnectManager();
166     LOGI("Stop finished successfully");
167 }
168 
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)169 void Daemon::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
170 {
171     if (systemAbilityId == COMMON_EVENT_SERVICE_ID) {
172         LOGI("Daemon::OnAddSystemAbility common event service online");
173         if (subScriber_ == nullptr) {
174             RegisterOsAccount();
175         }
176     } else if (systemAbilityId == SOFTBUS_SERVER_SA_ID) {
177         SoftBusHandlerAsset::GetInstance().CreateAssetLocalSessionServer();
178     }
179 }
180 
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)181 void Daemon::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
182 {
183     (void)deviceId;
184     if (systemAbilityId == COMMON_EVENT_SERVICE_ID) {
185         if (subScriber_ == nullptr) {
186             LOGE("Daemon::OnRemoveSystemAbility subscriberPtr is nullptr");
187             return;
188         }
189         LOGI("OnRemoveSystemAbility common event service offline");
190     } else if (systemAbilityId == SOFTBUS_SERVER_SA_ID) {
191         SoftBusHandlerAsset::GetInstance().DeleteAssetLocalSessionServer();
192     }
193 }
194 
OpenP2PConnection(const DistributedHardware::DmDeviceInfo & deviceInfo)195 int32_t Daemon::OpenP2PConnection(const DistributedHardware::DmDeviceInfo &deviceInfo)
196 {
197     std::lock_guard<std::mutex> lock(connectMutex_);
198     LOGI("OpenP2PConnection networkId %{public}s", Utils::GetAnonyString(deviceInfo.networkId).c_str());
199     RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_BUILD__LINK, RadarReporter::DFX_SUCCESS,
200                  RadarReporter::BIZ_STATE, RadarReporter::DFX_BEGIN);
201     RemoveDfsDelayTask(deviceInfo.networkId);
202     auto callingTokenId = IPCSkeleton::GetCallingTokenID();
203     sptr<IFileDfsListener> listener = nullptr;
204     auto ret = ConnectionCount(deviceInfo);
205     if (ret == E_OK) {
206         ConnectCount::GetInstance()->AddConnect(callingTokenId, deviceInfo.networkId, listener);
207     } else {
208         if (ret == ERR_CHECKOUT_COUNT) {
209             ConnectCount::GetInstance()->RemoveConnect(callingTokenId, deviceInfo.networkId);
210         }
211         CleanUp(deviceInfo);
212     }
213     return ret;
214 }
215 
CloseP2PConnection(const DistributedHardware::DmDeviceInfo & deviceInfo)216 int32_t Daemon::CloseP2PConnection(const DistributedHardware::DmDeviceInfo &deviceInfo)
217 {
218     std::lock_guard<std::mutex> lock(connectMutex_);
219     LOGI("Close P2P Connection networkId %{public}s", Utils::GetAnonyString(deviceInfo.networkId).c_str());
220     auto callingTokenId = IPCSkeleton::GetCallingTokenID();
221     auto networkId = std::string(deviceInfo.networkId);
222     ConnectCount::GetInstance()->RemoveConnect(callingTokenId, networkId);
223     CleanUp(deviceInfo);
224     return 0;
225 }
226 
ConnectionCount(const DistributedHardware::DmDeviceInfo & deviceInfo)227 int32_t Daemon::ConnectionCount(const DistributedHardware::DmDeviceInfo &deviceInfo)
228 {
229     auto path = ConnectionDetector::ParseHmdfsPath();
230     stringstream ss;
231     auto st_dev = ConnectionDetector::MocklispHash(path);
232     if (st_dev == static_cast<uint64_t>(FileManagement::ERR_BAD_VALUE)) {
233         return st_dev;
234     }
235     ss << st_dev;
236     auto targetDir = ss.str();
237     auto networkId = std::string(deviceInfo.networkId);
238     int32_t ret = 0;
239     if (!ConnectCount::GetInstance()->CheckCount(networkId)) {
240         ret = DeviceManagerAgent::GetInstance()->OnDeviceP2POnline(deviceInfo);
241         DevslDispatcher::GetDeviceDevsl(networkId);
242         if (ret == NO_ERROR) {
243             ret = ConnectionDetector::RepeatGetConnectionStatus(targetDir, networkId);
244         }
245     } else {
246         if (ConnectionDetector::RepeatGetConnectionStatus(targetDir, networkId) != E_OK) {
247             ret = ERR_CHECKOUT_COUNT;
248         }
249     }
250     if (ret == E_OK) {
251         RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_BUILD__LINK, RadarReporter::DFX_SUCCESS,
252                      RadarReporter::BIZ_STATE, RadarReporter::DFX_BEGIN);
253         LOGI("RepeatGetConnectionStatus end, ret = %{public}d", ret);
254     } else {
255         RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_BUILD__LINK, RadarReporter::DFX_FAILED,
256                      RadarReporter::BIZ_STATE, RadarReporter::DFX_BEGIN);
257         LOGE("OpenP2PConnection failed, ret = %{public}d", ret);
258     }
259     return ret;
260 }
261 
CleanUp(const DistributedHardware::DmDeviceInfo & deviceInfo)262 int32_t Daemon::CleanUp(const DistributedHardware::DmDeviceInfo &deviceInfo)
263 {
264     LOGI("CleanUp start");
265     auto networkId = std::string(deviceInfo.networkId);
266     if (!ConnectCount::GetInstance()->CheckCount(networkId)) {
267         auto ret = SendDfsDelayTask(networkId);
268         LOGI("Close P2P Connection");
269         return ret;
270     }
271     return E_OK;
272 }
273 
ConnectionAndMount(const DistributedHardware::DmDeviceInfo & deviceInfo,const std::string & networkId,uint32_t callingTokenId,sptr<IFileDfsListener> remoteReverseObj)274 int32_t Daemon::ConnectionAndMount(const DistributedHardware::DmDeviceInfo &deviceInfo,
275     const std::string &networkId, uint32_t callingTokenId, sptr<IFileDfsListener> remoteReverseObj)
276 {
277     LOGI("ConnectionAndMount start");
278     int32_t ret = NO_ERROR;
279     ret = ConnectionCount(deviceInfo);
280     if (ret != NO_ERROR) {
281         LOGE("connection failed");
282         if (ret == ERR_CHECKOUT_COUNT) {
283             ConnectCount::GetInstance()->RemoveConnect(callingTokenId, networkId);
284         }
285         return ret;
286     }
287     ConnectCount::GetInstance()->AddConnect(callingTokenId, networkId, remoteReverseObj);
288 
289     if (!DfsuAccessTokenHelper::CheckCallerPermission(FILE_ACCESS_MANAGER_PERMISSION)) {
290         LOGW("permission denied: FILE_ACCESS_MANAGER_PERMISSION");
291         return ret;
292     }
293     auto deviceManager = DeviceManagerAgent::GetInstance();
294     std::string deviceId = deviceManager->GetDeviceIdByNetworkId(networkId);
295     ret = deviceManager->MountDfsDocs(networkId, deviceId);
296     if (ret != NO_ERROR) {
297         ConnectCount::GetInstance()->RemoveConnect(callingTokenId, networkId);
298         LOGE("[MountDfsDocs] failed");
299     }
300     return ret;
301 }
302 
OpenP2PConnectionEx(const std::string & networkId,sptr<IFileDfsListener> remoteReverseObj)303 int32_t Daemon::OpenP2PConnectionEx(const std::string &networkId, sptr<IFileDfsListener> remoteReverseObj)
304 {
305     std::lock_guard<std::mutex> lock(connectMutex_);
306     LOGI("Daemon::OpenP2PConnectionEx start, networkId %{public}s", Utils::GetAnonyString(networkId).c_str());
307     if (!DfsuAccessTokenHelper::CheckCallerPermission(PERM_DISTRIBUTED_DATASYNC)) {
308         LOGE("[OpenP2PConnectionEx] DATASYNC permission denied");
309         return E_PERMISSION_DENIED_NAPI;
310     }
311     if (dfsListenerDeathRecipient_ == nullptr) {
312         LOGE("Daemon::OpenP2PConnectionEx, new death recipient");
313         dfsListenerDeathRecipient_ = sptr(new (std::nothrow) DfsListenerDeathRecipient());
314     }
315     if (dfsListenerDeathRecipient_ == nullptr) {
316         LOGE("Daemon::OpenP2PConnectionEx, dfsListenerDeathRecipient is nullptr");
317         return E_INVAL_ARG_NAPI;
318     }
319     if (remoteReverseObj == nullptr) {
320         LOGE("Daemon::OpenP2PConnectionEx remoteReverseObj is nullptr");
321         return E_INVAL_ARG_NAPI;
322     }
323     remoteReverseObj->AsObject()->AddDeathRecipient(dfsListenerDeathRecipient_);
324     auto deviceManager = DeviceManagerAgent::GetInstance();
325     if (networkId.empty() || networkId.length() >= DM_MAX_DEVICE_ID_LEN) {
326         LOGE("Daemon::OpenP2PConnectionEx networkId length is invalid.");
327         return E_INVAL_ARG_NAPI;
328     }
329     DistributedHardware::DmDeviceInfo deviceInfo{};
330     auto res = strcpy_s(deviceInfo.networkId, DM_MAX_DEVICE_ID_LEN, networkId.c_str());
331     if (res != NO_ERROR) {
332         LOGE("OpenP2PConnectionEx strcpy failed, res = %{public}d", res);
333         return E_INVAL_ARG_NAPI;
334     }
335     auto callingTokenId = IPCSkeleton::GetCallingTokenID();
336     RemoveDfsDelayTask(networkId);
337     int32_t ret = ConnectionAndMount(deviceInfo, networkId, callingTokenId, remoteReverseObj);
338     if (ret != NO_ERROR) {
339         CleanUp(deviceInfo);
340         return E_CONNECTION_FAILED;
341     }
342     LOGI("Daemon::OpenP2PConnectionEx end");
343     return ret;
344 }
345 
CloseP2PConnectionEx(const std::string & networkId)346 int32_t Daemon::CloseP2PConnectionEx(const std::string &networkId)
347 {
348     std::lock_guard<std::mutex> lock(connectMutex_);
349     LOGI("Daemon::CloseP2PConnectionEx start, networkId: %{public}s", Utils::GetAnonyString(networkId).c_str());
350     if (!DfsuAccessTokenHelper::CheckCallerPermission(PERM_DISTRIBUTED_DATASYNC)) {
351         LOGE("[CloseP2PConnectionEx] DATASYNC permission denied");
352         return E_PERMISSION_DENIED_NAPI;
353     }
354     auto deviceManager = DeviceManagerAgent::GetInstance();
355     auto callingTokenId = IPCSkeleton::GetCallingTokenID();
356     if (networkId.empty() || networkId.length() >= DM_MAX_DEVICE_ID_LEN) {
357         LOGE("Daemon::CloseP2PConnectionEx networkId length is invalid. len: %{public}zu",  networkId.length());
358         return E_INVAL_ARG_NAPI;
359     }
360     std::string deviceId = deviceManager->GetDeviceIdByNetworkId(networkId);
361     if (deviceId.empty()) {
362         LOGE("fail to get deviceId");
363         return E_CONNECTION_FAILED;
364     }
365     if (DfsuAccessTokenHelper::CheckCallerPermission(FILE_ACCESS_MANAGER_PERMISSION)) {
366         LOGE("[UMountDfsDocs] permission ok: FILE_ACCESS_MANAGER_PERMISSION");
367         int32_t ret_umount = deviceManager->UMountDfsDocs(networkId, deviceId, false);
368         if (ret_umount != NO_ERROR) {
369             LOGE("[UMountDfsDocs] failed");
370             return E_UNMOUNT;
371         }
372     }
373     DistributedHardware::DmDeviceInfo deviceInfo{};
374     auto res = strcpy_s(deviceInfo.networkId, DM_MAX_DEVICE_ID_LEN, networkId.c_str());
375     if (res != NO_ERROR) {
376         LOGE("strcpy failed, res = %{public}d", res);
377         return E_INVAL_ARG_NAPI;
378     }
379     ConnectCount::GetInstance()->RemoveConnect(callingTokenId, networkId);
380     int32_t ret = CleanUp(deviceInfo);
381     if (ret != NO_ERROR) {
382         LOGE("Daemon::CloseP2PConnectionEx disconnection failed");
383         return E_CONNECTION_FAILED;
384     }
385     LOGI("Daemon::CloseP2PConnectionEx end");
386     return 0;
387 }
388 
IsCallingDeviceTrusted()389 bool Daemon::IsCallingDeviceTrusted()
390 {
391     std::string callingNetworkId = IPCSkeleton::GetCallingDeviceID();
392     LOGI("Daemon::IsCallingDeviceTrusted called, callingNetworkId=%{public}.5s", callingNetworkId.c_str());
393     if (callingNetworkId.empty()) {
394         LOGE("Get callingNetworkId failed");
395         return false;
396     }
397     if (!SoftBusPermissionCheck::IsSameAccount(callingNetworkId)) {
398         LOGE("The calling device is not trusted");
399         return false;
400     }
401     LOGI("Daemon::IsCallingDeviceTrusted end");
402     return true;
403 }
404 
RequestSendFile(const std::string & srcUri,const std::string & dstPath,const std::string & dstDeviceId,const std::string & sessionName)405 int32_t Daemon::RequestSendFile(const std::string &srcUri,
406                                 const std::string &dstPath,
407                                 const std::string &dstDeviceId,
408                                 const std::string &sessionName)
409 {
410     LOGI("RequestSendFile begin dstDeviceId: %{public}s", Utils::GetAnonyString(dstDeviceId).c_str());
411 #ifdef SUPPORT_SAME_ACCOUNT
412     if (!IsCallingDeviceTrusted()) {
413         LOGE("Check calling device permission failed");
414         return FileManagement::E_PERMISSION_DENIED;
415     }
416 #endif
417     if (!FileSizeUtils::IsFilePathValid(FileSizeUtils::GetRealUri(srcUri)) ||
418         !FileSizeUtils::IsFilePathValid(FileSizeUtils::GetRealUri(dstPath))) {
419         LOGE("Path is forbidden");
420         return OHOS::FileManagement::E_ILLEGAL_URI;
421     }
422     auto requestSendFileBlock = std::make_shared<BlockObject<int32_t>>(BLOCK_INTERVAL_SEND_FILE, ERR_BAD_VALUE);
423     auto requestSendFileData = std::make_shared<RequestSendFileData>(
424         srcUri, dstPath, dstDeviceId, sessionName, requestSendFileBlock);
425     auto msgEvent = AppExecFwk::InnerEvent::Get(DEAMON_EXECUTE_REQUEST_SEND_FILE, requestSendFileData, 0);
426     {
427         std::lock_guard<std::mutex> lock(eventHandlerMutex_);
428         if (eventHandler_ == nullptr) {
429             LOGE("eventHandler has not find");
430             return E_EVENT_HANDLER;
431         }
432         bool isSucc = eventHandler_->SendEvent(msgEvent, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE);
433         if (!isSucc) {
434             LOGE("Daemon event handler post push asset event fail.");
435             return E_EVENT_HANDLER;
436         }
437     }
438 
439     auto ret = requestSendFileBlock->GetValue();
440     LOGI("RequestSendFile end, ret is %{public}d", ret);
441     return ret;
442 }
443 
InnerCopy(const std::string & srcUri,const std::string & dstUri,const std::string & srcDeviceId,const sptr<IFileTransListener> & listener,HmdfsInfo & info)444 int32_t Daemon::InnerCopy(const std::string &srcUri, const std::string &dstUri,
445     const std::string &srcDeviceId, const sptr<IFileTransListener> &listener, HmdfsInfo &info)
446 {
447     if (!FileSizeUtils::IsFilePathValid(FileSizeUtils::GetRealUri(srcUri)) ||
448         !FileSizeUtils::IsFilePathValid(FileSizeUtils::GetRealUri(dstUri))) {
449         LOGE("Path is forbidden");
450         return ERR_BAD_VALUE;
451     }
452     DistributedHardware::DmDeviceInfo deviceInfo;
453     auto res = strcpy_s(deviceInfo.networkId, DM_MAX_DEVICE_ID_LEN, srcDeviceId.c_str());
454     if (res != 0) {
455         LOGE("strcpy failed, res = %{public}d", res);
456         return ERR_BAD_VALUE;
457     }
458     OpenP2PConnection(deviceInfo);
459     auto ret = Storage::DistributedFile::RemoteFileCopyManager::GetInstance()->RemoteCopy(srcUri, dstUri,
460         listener, QueryActiveUserId(), info.copyPath);
461     CloseP2PConnection(deviceInfo);
462     LOGI("InnerCopy end, ret = %{public}d", ret);
463     return ret;
464 }
465 
PrepareSession(const std::string & srcUri,const std::string & dstUri,const std::string & srcDeviceId,const sptr<IRemoteObject> & listener,HmdfsInfo & info)466 int32_t Daemon::PrepareSession(const std::string &srcUri,
467                                const std::string &dstUri,
468                                const std::string &srcDeviceId,
469                                const sptr<IRemoteObject> &listener,
470                                HmdfsInfo &info)
471 {
472     auto listenerCallback = iface_cast<IFileTransListener>(listener);
473     if (listenerCallback == nullptr) {
474         LOGE("ListenerCallback is nullptr");
475         return E_NULLPTR;
476     }
477 
478     std::string srcPhysicalPath;
479     if (SandboxHelper::GetPhysicalPath(srcUri, std::to_string(QueryActiveUserId()), srcPhysicalPath) != E_OK) {
480         LOGE("Get src path failed, invalid uri");
481         return EINVAL;
482     }
483 
484     uint64_t fileSize = 0;
485     struct stat fileStat;
486     if (stat(srcPhysicalPath.c_str(), &fileStat) == 0) {
487         fileSize = fileStat.st_size;
488     } else {
489         LOGE("Stat srcPhysicalPath failed.");
490     }
491 
492     DfsVersion remoteDfsVersion;
493     auto ret = DeviceProfileAdapter::GetInstance().GetDfsVersionFromNetworkId(srcDeviceId, remoteDfsVersion);
494     LOGI("GetRemoteVersion: ret:%{public}d, version:%{public}s", ret, remoteDfsVersion.dump().c_str());
495 
496     if ((ret == FileManagement::ERR_OK) && (remoteDfsVersion.majorVersionNum != 0) && fileSize < INNER_COPY_LIMIT) {
497         return InnerCopy(srcUri, dstUri, srcDeviceId, listenerCallback, info);
498     }
499 
500     return CopyBaseOnRPC(srcUri, dstUri, srcDeviceId, listenerCallback, info);
501 }
502 
CopyBaseOnRPC(const std::string & srcUri,const std::string & dstUri,const std::string & srcDeviceId,const sptr<IFileTransListener> & listenerCallback,HmdfsInfo & info)503 int32_t Daemon::CopyBaseOnRPC(const std::string &srcUri,
504                               const std::string &dstUri,
505                               const std::string &srcDeviceId,
506                               const sptr<IFileTransListener> &listenerCallback,
507                               HmdfsInfo &info)
508 {
509     auto daemon = GetRemoteSA(srcDeviceId);
510     if (daemon == nullptr) {
511         LOGE("Daemon is nullptr");
512         return E_SA_LOAD_FAILED;
513     }
514 
515     std::string physicalPath;
516     auto ret = GetRealPath(srcUri, dstUri, physicalPath, info, daemon);
517     if (ret != E_OK) {
518         LOGE("GetRealPath failed, ret = %{public}d", ret);
519         return ret;
520     }
521     if (StoreSessionAndListener(physicalPath, info.sessionName, listenerCallback) != E_OK) {
522         LOGE("SessionServer exceed max");
523         return E_SOFTBUS_SESSION_FAILED;
524     }
525 
526     auto prepareSessionBlock = std::make_shared<BlockObject<int32_t>>(BLOCK_INTERVAL_SEND_FILE, ERR_BAD_VALUE);
527     auto prepareSessionData =
528         std::make_shared<PrepareSessionData>(srcUri, physicalPath, info.sessionName, daemon, info, prepareSessionBlock);
529     auto msgEvent = AppExecFwk::InnerEvent::Get(DEAMON_EXECUTE_PREPARE_SESSION, prepareSessionData, 0);
530     {
531         std::lock_guard<std::mutex> lock(eventHandlerMutex_);
532         if (eventHandler_ == nullptr) {
533             LOGE("eventHandler has not find");
534             return E_EVENT_HANDLER;
535         }
536         bool isSucc = eventHandler_->SendEvent(msgEvent, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE);
537         if (!isSucc) {
538             LOGE("Daemon event handler post Prepare Session event fail.");
539             return E_EVENT_HANDLER;
540         }
541     }
542 
543     ret = prepareSessionBlock->GetValue();
544     if (ret != E_OK) {
545         DeleteSessionAndListener(info.sessionName);
546     }
547     LOGI("PrepareSession end, ret is %{public}d", ret);
548     return ret;
549 }
550 
StoreSessionAndListener(const std::string & physicalPath,std::string & sessionName,const sptr<IFileTransListener> & listener)551 int32_t Daemon::StoreSessionAndListener(const std::string &physicalPath,
552                                         std::string &sessionName,
553                                         const sptr<IFileTransListener> &listener)
554 {
555     SoftBusSessionPool::SessionInfo sessionInfo{.dstPath = physicalPath, .uid = IPCSkeleton::GetCallingUid()};
556     sessionName = SoftBusSessionPool::GetInstance().GenerateSessionName(sessionInfo);
557     if (sessionName.empty()) {
558         LOGE("SessionServer exceed max");
559         return E_SOFTBUS_SESSION_FAILED;
560     }
561     TransManager::GetInstance().AddTransTask(sessionName, listener);
562     return E_OK;
563 }
564 
GetRealPath(const std::string & srcUri,const std::string & dstUri,std::string & physicalPath,HmdfsInfo & info,const sptr<IDaemon> & daemon)565 int32_t Daemon::GetRealPath(const std::string &srcUri,
566                             const std::string &dstUri,
567                             std::string &physicalPath,
568                             HmdfsInfo &info,
569                             const sptr<IDaemon> &daemon)
570 {
571     bool isSrcFile = false;
572     bool isSrcDir = false;
573     if (daemon == nullptr) {
574         LOGE("Daemon::GetRealPath daemon is nullptr");
575         return E_INVAL_ARG_NAPI;
576     }
577     if (!FileSizeUtils::IsFilePathValid(FileSizeUtils::GetRealUri(srcUri)) ||
578         !FileSizeUtils::IsFilePathValid(FileSizeUtils::GetRealUri(dstUri))) {
579         LOGE("Path is forbidden");
580         return OHOS::FileManagement::E_ILLEGAL_URI;
581     }
582     auto ret = daemon->GetRemoteCopyInfo(srcUri, isSrcFile, isSrcDir);
583     if (ret != E_OK) {
584         LOGE("GetRemoteCopyInfo failed, ret = %{public}d", ret);
585         RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_FAILED,
586             RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::ERROR_CODE,
587             RadarReporter::GET_REMOTE_COPY_INFO_ERROR);
588         return E_SOFTBUS_SESSION_FAILED;
589     }
590 
591     HapTokenInfo hapTokenInfo;
592     int result = AccessTokenKit::GetHapTokenInfo(IPCSkeleton::GetCallingTokenID(), hapTokenInfo);
593     if (result != Security::AccessToken::AccessTokenKitRet::RET_SUCCESS) {
594         LOGE("GetHapTokenInfo failed, errCode = %{public}d", result);
595         RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_FAILED,
596             RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::ERROR_CODE,
597             RadarReporter::GET_HAP_TOKEN_INFO_ERROR, RadarReporter::PACKAGE_NAME,
598             RadarReporter::accessTokenKit + to_string(result));
599         return E_GET_USER_ID;
600     }
601     ret = SandboxHelper::GetPhysicalPath(dstUri, std::to_string(hapTokenInfo.userID), physicalPath);
602     if (ret != E_OK) {
603         LOGE("invalid uri, ret = %{public}d", ret);
604         return E_GET_PHYSICAL_PATH_FAILED;
605     }
606 
607     LOGI("GetRealPath userId %{public}s", std::to_string(hapTokenInfo.userID).c_str());
608     info.dstPhysicalPath = physicalPath;
609     ret = CheckCopyRule(physicalPath, dstUri, hapTokenInfo, isSrcFile, info);
610     if (ret != E_OK) {
611         LOGE("CheckCopyRule failed, ret = %{public}d", ret);
612         return E_GET_PHYSICAL_PATH_FAILED;
613     }
614     return E_OK;
615 }
616 
CheckCopyRule(std::string & physicalPath,const std::string & dstUri,HapTokenInfo & hapTokenInfo,const bool & isSrcFile,HmdfsInfo & info)617 int32_t Daemon::CheckCopyRule(std::string &physicalPath,
618                               const std::string &dstUri,
619                               HapTokenInfo &hapTokenInfo,
620                               const bool &isSrcFile,
621                               HmdfsInfo &info)
622 {
623     auto checkPath = physicalPath;
624     if (isSrcFile && !Utils::IsFolder(physicalPath)) {
625         auto pos = physicalPath.rfind('/');
626         if (pos == std::string::npos) {
627             LOGE("invalid file path");
628             return E_GET_PHYSICAL_PATH_FAILED;
629         }
630         physicalPath = physicalPath.substr(0, pos);
631     }
632 
633     std::error_code errCode;
634     if (!std::filesystem::exists(physicalPath, errCode) && info.dirExistFlag) {
635         LOGI("Not CheckValidPath");
636     } else {
637         auto pos = checkPath.rfind('/');
638         if (pos == std::string::npos) {
639             LOGE("invalid file path");
640             return E_GET_PHYSICAL_PATH_FAILED;
641         }
642         checkPath = checkPath.substr(0, pos);
643         if (!SandboxHelper::CheckValidPath(checkPath)) {
644             LOGE("invalid path.");
645             return E_GET_PHYSICAL_PATH_FAILED;
646         }
647     }
648 
649     Uri uri(dstUri);
650     auto authority = uri.GetAuthority();
651     info.authority = authority;
652     if (authority != FILE_MANAGER_AUTHORITY && authority != MEDIA_AUTHORITY) {
653         auto bundleName = SoftBusSessionListener::GetBundleName(dstUri);
654         physicalPath = "/data/service/el2/" + to_string(hapTokenInfo.userID) + "/hmdfs/account/data/" + bundleName +
655                        "/" + info.copyPath;
656         if (!SandboxHelper::CheckValidPath(physicalPath)) {
657             LOGE("invalid path.");
658             return E_GET_PHYSICAL_PATH_FAILED;
659         }
660     } else {
661         std::regex pathRegex("^[a-zA-Z0-9_\\-/\\\\\u4E00-\u9FA5]*$");
662         if (!std::filesystem::exists(physicalPath, errCode) && std::regex_match(physicalPath.c_str(), pathRegex)) {
663             std::filesystem::create_directory(physicalPath, errCode);
664             if (errCode.value() != 0) {
665                 LOGE("Create directory failed, errCode %{public}d", errCode.value());
666                 return E_GET_PHYSICAL_PATH_FAILED;
667             }
668         }
669     }
670     return E_OK;
671 }
672 
GetRemoteCopyInfo(const std::string & srcUri,bool & isSrcFile,bool & srcIsDir)673 int32_t Daemon::GetRemoteCopyInfo(const std::string &srcUri, bool &isSrcFile, bool &srcIsDir)
674 {
675     LOGI("GetRemoteCopyInfo begin.");
676 #ifdef SUPPORT_SAME_ACCOUNT
677     if (!IsCallingDeviceTrusted()) {
678         LOGE("Check calling device permission failed");
679         return FileManagement::E_PERMISSION_DENIED;
680     }
681 #endif
682     auto physicalPath = SoftBusSessionListener::GetRealPath(srcUri);
683     if (physicalPath.empty()) {
684         LOGE("GetRemoteCopyInfo GetRealPath failed.");
685         return E_SOFTBUS_SESSION_FAILED;
686     }
687     isSrcFile = Utils::IsFile(physicalPath);
688     srcIsDir = Utils::IsFolder(physicalPath);
689     return E_OK;
690 }
691 
GetRemoteSA(const std::string & remoteDeviceId)692 sptr<IDaemon> Daemon::GetRemoteSA(const std::string &remoteDeviceId)
693 {
694     LOGI("GetRemoteSA begin, DeviceId: %{public}s", Utils::GetAnonyString(remoteDeviceId).c_str());
695     auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
696     if (sam == nullptr) {
697         LOGE("Sam is nullptr");
698         return nullptr;
699     }
700 
701     auto object = sam->GetSystemAbility(FILEMANAGEMENT_DISTRIBUTED_FILE_DAEMON_SA_ID, remoteDeviceId);
702     if (object == nullptr) {
703         LOGE("GetSystemAbility failed");
704         RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_FAILED,
705             RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::ERROR_CODE,
706             RadarReporter::GET_SYSTEM_ABILITY_ERROR, RadarReporter::PACKAGE_NAME, RadarReporter::saMgr);
707         return nullptr;
708     }
709     auto daemon = iface_cast<IDaemon>(object);
710     if (daemon == nullptr) {
711         LOGE("Connect service nullptr");
712         return nullptr;
713     }
714     LOGI("GetRemoteSA success, DeviceId: %{public}s", Utils::GetAnonyString(remoteDeviceId).c_str());
715     return daemon;
716 }
717 
Copy(const std::string & srcUri,const std::string & dstPath,const sptr<IDaemon> & daemon,const std::string & sessionName)718 int32_t Daemon::Copy(const std::string &srcUri,
719                      const std::string &dstPath,
720                      const sptr<IDaemon> &daemon,
721                      const std::string &sessionName)
722 {
723     if (!FileSizeUtils::IsFilePathValid(FileSizeUtils::GetRealUri(srcUri)) ||
724         !FileSizeUtils::IsFilePathValid(FileSizeUtils::GetRealUri(dstPath))) {
725         LOGE("Path is forbidden");
726         return E_INVAL_ARG;
727     }
728     auto &deviceManager = DistributedHardware::DeviceManager::GetInstance();
729     DistributedHardware::DmDeviceInfo localDeviceInfo{};
730     int errCode = deviceManager.GetLocalDeviceInfo(IDaemon::SERVICE_NAME, localDeviceInfo);
731     if (errCode != E_OK) {
732         LOGE("GetLocalDeviceInfo failed, errCode = %{public}d", errCode);
733         return E_GET_DEVICE_ID;
734     }
735     if (daemon == nullptr) {
736         LOGE("Daemon::Copy daemon is nullptr");
737         return E_INVAL_ARG_NAPI;
738     }
739     LOGI("Copy localDeviceInfo.networkId: %{public}s", Utils::GetAnonyString(localDeviceInfo.networkId).c_str());
740     auto ret = daemon->RequestSendFile(srcUri, dstPath, localDeviceInfo.networkId, sessionName);
741     if (ret != E_OK) {
742         LOGE("RequestSendFile failed, ret = %{public}d", ret);
743         RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_FAILED,
744             RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::ERROR_CODE,
745             RadarReporter::REQUEST_SEND_FILE_ERROR, RadarReporter::PACKAGE_NAME, ret);
746         return E_SA_LOAD_FAILED;
747     }
748     return E_OK;
749 }
750 
CancelCopyTask(const std::string & sessionName)751 int32_t Daemon::CancelCopyTask(const std::string &sessionName)
752 {
753     LOGI("Cancel copy task in. sessionName = %{public}s", sessionName.c_str());
754     SoftBusSessionPool::SessionInfo sessionInfo{};
755     bool isExist = SoftBusSessionPool::GetInstance().GetSessionInfo(sessionName, sessionInfo);
756     if (!isExist) {
757         LOGE("CancelCopyTask failed, cannot get session info for input session name=%{public}s.", sessionName.c_str());
758         return E_INVAL_ARG;
759     }
760     auto callingUid = IPCSkeleton::GetCallingUid();
761     if (callingUid != sessionInfo.uid) {
762         LOGE("CancelCopyTask failed, calling uid=%{public}d has no permission to cancel copy for uid=%{public}d.",
763              callingUid, sessionInfo.uid);
764         return E_PERMISSION_DENIED;
765     }
766     SoftBusHandler::GetInstance().CloseSessionWithSessionName(sessionName);
767     return E_OK;
768 }
769 
CancelCopyTask(const std::string & srcUri,const std::string & dstUri)770 int32_t Daemon::CancelCopyTask(const std::string &srcUri, const std::string &dstUri)
771 {
772     Storage::DistributedFile::RemoteFileCopyManager::GetInstance()->RemoteCancel(srcUri, dstUri);
773     return E_OK;
774 }
775 
DeleteSessionAndListener(const std::string & sessionName)776 void Daemon::DeleteSessionAndListener(const std::string &sessionName)
777 {
778     SoftBusSessionPool::GetInstance().DeleteSessionInfo(sessionName);
779     TransManager::GetInstance().DeleteTransTask(sessionName);
780 }
781 
OnRemoteDied(const wptr<IRemoteObject> & remote)782 void Daemon::DfsListenerDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
783 {
784     sptr<IRemoteObject> diedRemote = remote.promote();
785     if (diedRemote == nullptr) {
786         LOGE("Daemon::DfsListenerDeathRecipient OnremoteDied received died notify nullptr");
787         return;
788     }
789 
790     uint32_t callingTokenId;
791     auto ret = ConnectCount::GetInstance()->FindCallingTokenIdForListerner(diedRemote, callingTokenId);
792     if (ret != E_OK) {
793         LOGE("fail to FindCallingTokenIdForListerner");
794         return;
795     }
796     auto networkIds = ConnectCount::GetInstance()->RemoveConnect(callingTokenId);
797     if (networkIds.empty()) {
798         LOGE("fail to get networkIdSet");
799         return;
800     }
801     auto deviceManager = DeviceManagerAgent::GetInstance();
802     for (auto it = networkIds.begin(); it != networkIds.end(); ++it) {
803         if (it->empty()) {
804             LOGE("[DfsListenerDeathRecipient] networkId is null");
805             continue;
806         }
807         std::string deviceId = deviceManager->GetDeviceIdByNetworkId(*it);
808         if (deviceId.empty()) {
809             LOGE("fail to get deviceId, networkId: %{public}s", Utils::GetAnonyString(*it).c_str());
810             continue;
811         }
812         deviceManager->UMountDfsDocs(*it, deviceId, false);
813         DistributedHardware::DmDeviceInfo deviceInfo{};
814         auto res = strcpy_s(deviceInfo.networkId, DM_MAX_DEVICE_ID_LEN, it->c_str());
815         if (res != 0) {
816             LOGE("strcpy failed, res = %{public}d", res);
817             return;
818         }
819         if (!ConnectCount::GetInstance()->CheckCount(*it)) {
820             DeviceManagerAgent::GetInstance()->OnDeviceP2POffline(deviceInfo);
821         }
822     }
823     LOGI("Daemon::DfsListenerDeathRecipient OnremoteDied end");
824     return;
825 }
826 
PushAsset(int32_t userId,const sptr<AssetObj> & assetObj,const sptr<IAssetSendCallback> & sendCallback)827 int32_t Daemon::PushAsset(int32_t userId,
828                           const sptr<AssetObj> &assetObj,
829                           const sptr<IAssetSendCallback> &sendCallback)
830 {
831     LOGI("Daemon::PushAsset begin.");
832     if (assetObj == nullptr || sendCallback == nullptr) {
833         LOGE("param is nullptr.");
834         return E_NULLPTR;
835     }
836     const auto &uriVec = assetObj->uris_;
837     for (const auto &uri : uriVec) {
838         if (!FileSizeUtils::IsFilePathValid(FileSizeUtils::GetRealUri(uri))) {
839             LOGE("Path is forbidden");
840             return OHOS::FileManagement::E_ILLEGAL_URI;
841         }
842     }
843     auto taskId = assetObj->srcBundleName_ + assetObj->sessionId_;
844     if (taskId.empty()) {
845         LOGE("assetObj info is null.");
846         return E_NULLPTR;
847     }
848     AssetCallbackManager::GetInstance().AddSendCallback(taskId, sendCallback);
849     auto pushData = std::make_shared<PushAssetData>(userId, assetObj);
850     auto msgEvent = AppExecFwk::InnerEvent::Get(DEAMON_EXECUTE_PUSH_ASSET, pushData, 0);
851 
852     std::lock_guard<std::mutex> lock(eventHandlerMutex_);
853     if (eventHandler_ == nullptr) {
854         LOGE("eventHandler has not find");
855         AssetCallbackManager::GetInstance().RemoveSendCallback(taskId);
856         return E_EVENT_HANDLER;
857     }
858     bool isSucc = eventHandler_->SendEvent(msgEvent, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE);
859     if (!isSucc) {
860         LOGE("Daemon event handler post push asset event fail.");
861         AssetCallbackManager::GetInstance().RemoveSendCallback(taskId);
862         return E_EVENT_HANDLER;
863     }
864     return E_OK;
865 }
866 
RegisterAssetCallback(const sptr<IAssetRecvCallback> & recvCallback)867 int32_t Daemon::RegisterAssetCallback(const sptr<IAssetRecvCallback> &recvCallback)
868 {
869     LOGI("Daemon::RegisterAssetCallback begin.");
870     if (recvCallback == nullptr) {
871         LOGE("recvCallback is nullptr.");
872         return E_NULLPTR;
873     }
874     AssetCallbackManager::GetInstance().AddRecvCallback(recvCallback);
875     return E_OK;
876 }
877 
UnRegisterAssetCallback(const sptr<IAssetRecvCallback> & recvCallback)878 int32_t Daemon::UnRegisterAssetCallback(const sptr<IAssetRecvCallback> &recvCallback)
879 {
880     LOGI("Daemon::UnRegisterAssetCallback begin.");
881     if (recvCallback == nullptr) {
882         LOGE("recvCallback is nullptr.");
883         return E_NULLPTR;
884     }
885     AssetCallbackManager::GetInstance().RemoveRecvCallback(recvCallback);
886     return E_OK;
887 }
888 
StartEventHandler()889 void Daemon::StartEventHandler()
890 {
891     LOGI("StartEventHandler begin");
892     if (daemonExecute_ == nullptr) {
893         daemonExecute_ = std::make_shared<DaemonExecute>();
894     }
895 
896     std::lock_guard<std::mutex> lock(eventHandlerMutex_);
897     auto runer = AppExecFwk::EventRunner::Create(IDaemon::SERVICE_NAME.c_str());
898     eventHandler_ = std::make_shared<DaemonEventHandler>(runer, daemonExecute_);
899 }
900 
SendDfsDelayTask(const std::string & networkId)901 int32_t Daemon::SendDfsDelayTask(const std::string &networkId)
902 {
903     LOGI("Daemon::SendDfsDelayTask enter.");
904     constexpr int32_t DEFAULT_DELAY_INTERVAL = 1 * 1000;
905     if (networkId.empty()) {
906         LOGE("networkId is empty.");
907         return E_NULLPTR;
908     }
909     LOGI("SendDfsDelayTask NetworkId:%{public}.5s", networkId.c_str());
910     std::lock_guard<std::mutex> lock(eventHandlerMutex_);
911     if (eventHandler_ == nullptr) {
912         LOGE("eventHandler has not find.");
913         return E_EVENT_HANDLER;
914     }
915 
916     auto executeFunc = [this, networkId] { DisconnectDevice(networkId); };
917     bool isSucc = eventHandler_->PostTask(executeFunc, networkId, DEFAULT_DELAY_INTERVAL,
918         AppExecFwk::EventHandler::Priority::IMMEDIATE);
919     if (!isSucc) {
920         LOGE("Daemon event handler post delay disconnect device event fail.");
921         return E_EVENT_HANDLER;
922     }
923     return E_OK;
924 }
925 
RemoveDfsDelayTask(const std::string & networkId)926 void Daemon::RemoveDfsDelayTask(const std::string &networkId)
927 {
928     LOGI("Daemon::RemoveDfsDelayTask enter.");
929     std::lock_guard<std::mutex> lock(eventHandlerMutex_);
930     if (eventHandler_ == nullptr) {
931         LOGE("eventHandler has not find.");
932         return;
933     }
934     LOGI("RemoveDfsDelayTask NetworkId:%{public}.5s", networkId.c_str());
935     eventHandler_->RemoveTask(networkId);
936 }
937 
DisconnectDevice(const std::string networkId)938 void Daemon::DisconnectDevice(const std::string networkId)
939 {
940     LOGI("Daemon::DisconnectDevice enter.");
941     DistributedHardware::DmDeviceInfo deviceInfo;
942     auto ret = strcpy_s(deviceInfo.networkId, DM_MAX_DEVICE_ID_LEN, networkId.c_str());
943     if (ret != 0) {
944         LOGE("strcpy for network id failed, ret is %{public}d", ret);
945         return;
946     }
947     LOGI("DisconnectDevice NetworkId:%{public}.5s", networkId.c_str());
948     ret = DeviceManagerAgent::GetInstance()->OnDeviceP2POffline(deviceInfo);
949     LOGI("Daemon::DisconnectDevice result %{public}d", ret);
950 }
951 
GetDfsUrisDirFromLocal(const std::vector<std::string> & uriList,const int32_t userId,std::unordered_map<std::string,AppFileService::ModuleRemoteFileShare::HmdfsUriInfo> & uriToDfsUriMaps)952 int32_t Daemon::GetDfsUrisDirFromLocal(const std::vector<std::string> &uriList,
953                                        const int32_t userId,
954                                        std::unordered_map<std::string,
955                                        AppFileService::ModuleRemoteFileShare::HmdfsUriInfo> &uriToDfsUriMaps)
956 {
957     LOGI("Daemon::GetDfsUrisDirFromLocal start");
958     auto callingUid = IPCSkeleton::GetCallingUid();
959     if (callingUid != PASTEBOARDUSERID && callingUid != UDMFUSERID) {
960         LOGE("Permission denied, caller is not pasterboard or udmf");
961         return E_PERMISSION_DENIED;
962     }
963     for (const auto &uri : uriList) {
964         if (!FileSizeUtils::IsFilePathValid(FileSizeUtils::GetRealUri(uri))) {
965             LOGE("path: %{public}s is forbidden", Utils::GetAnonyString(uri).c_str());
966             return OHOS::FileManagement::E_ILLEGAL_URI;
967         }
968     }
969     auto ret = AppFileService::ModuleRemoteFileShare::RemoteFileShare::GetDfsUrisDirFromLocal(uriList, userId,
970                                                                                               uriToDfsUriMaps);
971     if (ret != FileManagement::E_OK) {
972         LOGE("GetDfsUrisDirFromLocal Failed, ret = %{public}d", ret);
973         return ret;
974     }
975     return FileManagement::E_OK;
976 }
977 
GetDfsSwitchStatus(const std::string & networkId,int32_t & switchStatus)978 int32_t Daemon::GetDfsSwitchStatus(const std::string &networkId, int32_t &switchStatus)
979 {
980     LOGI("GetDfsSwitchStatus enter. networkId: %{public}s", Utils::GetAnonyString(networkId).c_str());
981     LOGI("GetDfsSwitchStatus end, switchStatus %{public}d", switchStatus);
982     return E_OK;
983 }
984 
UpdateDfsSwitchStatus(int32_t switchStatus)985 int32_t Daemon::UpdateDfsSwitchStatus(int32_t switchStatus)
986 {
987     LOGI("UpdateDfsSwitchStatus enter, switch status: %{public}d", switchStatus);
988     return E_OK;
989 }
990 
GetConnectedDeviceList(std::vector<DfsDeviceInfo> & deviceList)991 int32_t Daemon::GetConnectedDeviceList(std::vector<DfsDeviceInfo> &deviceList)
992 {
993     LOGI("GetConnectedDeviceList enter.");
994     (void)deviceList;
995     return E_OK;
996 }
997 
DisconnectByRemote(const string & networkId)998 void Daemon::DisconnectByRemote(const string &networkId)
999 {
1000     LOGI("start DisconnectByRemote");
1001     if (networkId.empty() || networkId.length() >= DM_MAX_DEVICE_ID_LEN) {
1002         LOGE("Daemon::DisconnectByRemote networkId length is invalid. len: %{public}zu", networkId.length());
1003         return;
1004     }
1005     string subnetworkId = networkId.substr(0, VALID_MOUNT_NETWORKID_LEN);
1006     int32_t res = DeviceManagerAgent::GetInstance()->UMountDfsDocs(networkId, subnetworkId, true);
1007     if (res != NO_ERROR) {
1008         LOGE("[UMountDfsDocs] failed");
1009         return;
1010     }
1011     DistributedHardware::DmDeviceInfo deviceInfo{};
1012     res = strcpy_s(deviceInfo.networkId, DM_MAX_DEVICE_ID_LEN, networkId.c_str());
1013     if (res != NO_ERROR) {
1014         LOGE("strcpy failed, res = %{public}d", res);
1015         return;
1016     }
1017     ConnectCount::GetInstance()->RemoveConnect(IPCSkeleton::GetCallingTokenID(), networkId);
1018     int32_t ret = CleanUp(deviceInfo);
1019     if (ret != NO_ERROR) {
1020         LOGE("DisconnectByRemote disconnection failed.");
1021         return;
1022     }
1023 }
1024 
CreatControlLink(const std::string & networkId)1025 int32_t Daemon::CreatControlLink(const std::string &networkId)
1026 {
1027     LOGI("start CreatControlLink");
1028     if (ChannelManager::GetInstance().HasExistChannel(networkId)) {
1029         LOGI("exist channel, networkId: %{public}.6s", networkId.c_str());
1030         return ERR_OK;
1031     }
1032 
1033     DfsVersion remoteDfsVersion;
1034     auto ret = DeviceProfileAdapter::GetInstance().GetDfsVersionFromNetworkId(networkId, remoteDfsVersion);
1035     LOGI("GetRemoteVersion: ret:%{public}d, version:%{public}s", ret, remoteDfsVersion.dump().c_str());
1036     if ((ret == ERR_OK) && (remoteDfsVersion.majorVersionNum == 0)) {
1037         LOGW("old version, not need CreatControlLink");
1038         return ERR_OK;
1039     }
1040 
1041     if (ChannelManager::GetInstance().CreateClientChannel(networkId) != ERR_OK) {
1042         LOGE("create channel failed, networkId: %{public}.6s", networkId.c_str());
1043         return FileManagement::ERR_BAD_VALUE;
1044     }
1045     return ERR_OK;
1046 }
1047 
CancelControlLink(const std::string & networkId)1048 int32_t Daemon::CancelControlLink(const std::string &networkId)
1049 {
1050     if (!ChannelManager::GetInstance().HasExistChannel(networkId)) {
1051         LOGI("not exist channel, networkId: %{public}.6s", networkId.c_str());
1052         return ERR_OK;
1053     }
1054     if (ChannelManager::GetInstance().DestroyClientChannel(networkId) != ERR_OK) {
1055         LOGE("create channel failed, networkId: %{public}.6s", networkId.c_str());
1056         return FileManagement::ERR_BAD_VALUE;
1057     }
1058     return ERR_OK;
1059 }
1060 
CheckRemoteAllowConnect(const std::string & networkId)1061 int32_t Daemon::CheckRemoteAllowConnect(const std::string &networkId)
1062 {
1063     LOGI("start CheckRemoteAllowConnect");
1064     int32_t ret = CreatControlLink(networkId);
1065     if (ret != ERR_OK) {
1066         LOGE("CheckRemoteAllowConnect ret = %{public}d", ret);
1067         return ret;
1068     }
1069     ControlCmd request;
1070     request.msgType = ControlCmdType::CMD_CHECK_ALLOW_CONNECT;
1071 
1072     ControlCmd response;
1073     ret = ChannelManager::GetInstance().SendRequest(networkId, request, response, true);
1074     if (ret != ERR_OK) {
1075         LOGE("SendRequest ret = %{public}d", ret);
1076         return ret;
1077     }
1078 
1079     return response.msgBody == "true" ? FileManagement::ERR_BAD_VALUE : FileManagement::E_OK;
1080 }
1081 
NotifyRemotePublishNotification(const std::string & networkId)1082 int32_t Daemon::NotifyRemotePublishNotification(const std::string &networkId)
1083 {
1084     LOGI("start NotifyRemotePublishNotification");
1085     int32_t ret = CreatControlLink(networkId);
1086     if (ret != ERR_OK) {
1087         LOGE("NotifyRemotePublishNotification ret = %{public}d", ret);
1088         return ret;
1089     }
1090     ControlCmd request;
1091     request.msgType = ControlCmdType::CMD_PUBLISH_NOTIFICATION;
1092 
1093     std::string srcNetId;
1094     ret = DistributedHardware::DeviceManager::GetInstance().GetLocalDeviceNetWorkId(IDaemon::SERVICE_NAME, srcNetId);
1095     if (ret != ERR_OK) {
1096         LOGE("DeviceManager GetLocalDeviceNetWorkId failed. ret is %{public}d", ret);
1097         return ret;
1098     }
1099     request.networkId = srcNetId;
1100 
1101     ControlCmd response;
1102     ret = ChannelManager::GetInstance().SendRequest(networkId, request, response);
1103     if (ret != ERR_OK) {
1104         LOGE("SendRequest ret = %{public}d", ret);
1105         return ret;
1106     }
1107     return ret;
1108 }
1109 
NotifyRemoteCancelNotification(const std::string & networkId)1110 int32_t Daemon::NotifyRemoteCancelNotification(const std::string &networkId)
1111 {
1112     LOGI("start NotifyRemoteCancelNotification");
1113     int32_t ret = CreatControlLink(networkId);
1114     if (ret != ERR_OK) {
1115         LOGE("NotifyRemoteCancelNotification ret = %{public}d", ret);
1116         return ret;
1117     }
1118     ControlCmd request;
1119     request.msgType = ControlCmdType::CMD_CANCEL_NOTIFICATION;
1120 
1121     std::string srcNetId;
1122     ret = DistributedHardware::DeviceManager::GetInstance().GetLocalDeviceNetWorkId(IDaemon::SERVICE_NAME, srcNetId);
1123     if (ret != ERR_OK) {
1124         LOGE("DeviceManager GetLocalDeviceNetWorkId failed. ret is %{public}d", ret);
1125         return ret;
1126     }
1127     request.networkId = srcNetId;
1128 
1129     ControlCmd response;
1130     ret = ChannelManager::GetInstance().SendRequest(networkId, request, response);
1131     if (ret != ERR_OK) {
1132         LOGE("SendRequest ret = %{public}d", ret);
1133         return ret;
1134     }
1135     return ret;
1136 }
1137 
1138 } // namespace DistributedFile
1139 } // namespace Storage
1140 } // namespace OHOS
1141