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