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