1cb7eb8c9Sopenharmony_ci/* 2cb7eb8c9Sopenharmony_ci* Copyright (c) 2024 Huawei Device Co., Ltd. 3cb7eb8c9Sopenharmony_ci* Licensed under the Apache License, Version 2.0 (the "License"); 4cb7eb8c9Sopenharmony_ci* you may not use this file except in compliance with the License. 5cb7eb8c9Sopenharmony_ci* You may obtain a copy of the License at 6cb7eb8c9Sopenharmony_ci* 7cb7eb8c9Sopenharmony_ci* http://www.apache.org/licenses/LICENSE-2.0 8cb7eb8c9Sopenharmony_ci* 9cb7eb8c9Sopenharmony_ci* Unless required by applicable law or agreed to in writing, software 10cb7eb8c9Sopenharmony_ci* distributed under the License is distributed on an "AS IS" BASIS, 11cb7eb8c9Sopenharmony_ci* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12cb7eb8c9Sopenharmony_ci* See the License for the specific language governing permissions and 13cb7eb8c9Sopenharmony_ci* limitations under the License. 14cb7eb8c9Sopenharmony_ci */ 15cb7eb8c9Sopenharmony_ci 16cb7eb8c9Sopenharmony_ci#include "daemon_execute.h" 17cb7eb8c9Sopenharmony_ci 18cb7eb8c9Sopenharmony_ci#include <chrono> 19cb7eb8c9Sopenharmony_ci#include <ctime> 20cb7eb8c9Sopenharmony_ci#include <filesystem> 21cb7eb8c9Sopenharmony_ci#include <memory> 22cb7eb8c9Sopenharmony_ci#include <random> 23cb7eb8c9Sopenharmony_ci#include <regex> 24cb7eb8c9Sopenharmony_ci 25cb7eb8c9Sopenharmony_ci#include "asset_callback_manager.h" 26cb7eb8c9Sopenharmony_ci#include "dfs_error.h" 27cb7eb8c9Sopenharmony_ci#include "network/softbus/softbus_asset_send_listener.h" 28cb7eb8c9Sopenharmony_ci#include "network/softbus/softbus_handler_asset.h" 29cb7eb8c9Sopenharmony_ci#include "network/softbus/softbus_session_pool.h" 30cb7eb8c9Sopenharmony_ci#include "refbase.h" 31cb7eb8c9Sopenharmony_ci#include "sandbox_helper.h" 32cb7eb8c9Sopenharmony_ci#include "utils_directory.h" 33cb7eb8c9Sopenharmony_ci#include "utils_log.h" 34cb7eb8c9Sopenharmony_ci 35cb7eb8c9Sopenharmony_ci#include "all_connect/all_connect_manager.h" 36cb7eb8c9Sopenharmony_ci#include "network/softbus/softbus_handler.h" 37cb7eb8c9Sopenharmony_ci 38cb7eb8c9Sopenharmony_cinamespace OHOS { 39cb7eb8c9Sopenharmony_cinamespace Storage { 40cb7eb8c9Sopenharmony_cinamespace DistributedFile { 41cb7eb8c9Sopenharmony_ciusing namespace OHOS::AppFileService; 42cb7eb8c9Sopenharmony_ciusing namespace OHOS::FileManagement; 43cb7eb8c9Sopenharmony_ciDaemonExecute::DaemonExecute() 44cb7eb8c9Sopenharmony_ci{ 45cb7eb8c9Sopenharmony_ci LOGI("DaemonExecute begin."); 46cb7eb8c9Sopenharmony_ci executeFuncMap_[DEAMON_EXECUTE_PUSH_ASSET] = &DaemonExecute::ExecutePushAsset; 47cb7eb8c9Sopenharmony_ci executeFuncMap_[DEAMON_EXECUTE_REQUEST_SEND_FILE] = &DaemonExecute::ExecuteRequestSendFile; 48cb7eb8c9Sopenharmony_ci} 49cb7eb8c9Sopenharmony_ci 50cb7eb8c9Sopenharmony_civoid DaemonExecute::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event) 51cb7eb8c9Sopenharmony_ci{ 52cb7eb8c9Sopenharmony_ci if (event == nullptr) { 53cb7eb8c9Sopenharmony_ci LOGE("event is nullptr."); 54cb7eb8c9Sopenharmony_ci return; 55cb7eb8c9Sopenharmony_ci } 56cb7eb8c9Sopenharmony_ci std::lock_guard<std::mutex> lock(executeFuncMapMutex_); 57cb7eb8c9Sopenharmony_ci auto itFunc = executeFuncMap_.find(event->GetInnerEventId()); 58cb7eb8c9Sopenharmony_ci if (itFunc == executeFuncMap_.end()) { 59cb7eb8c9Sopenharmony_ci LOGE("not find execute func."); 60cb7eb8c9Sopenharmony_ci return; 61cb7eb8c9Sopenharmony_ci } 62cb7eb8c9Sopenharmony_ci 63cb7eb8c9Sopenharmony_ci auto executeFunc = itFunc->second; 64cb7eb8c9Sopenharmony_ci (this->*executeFunc)(event); 65cb7eb8c9Sopenharmony_ci} 66cb7eb8c9Sopenharmony_ci 67cb7eb8c9Sopenharmony_civoid DaemonExecute::ExecutePushAsset(const AppExecFwk::InnerEvent::Pointer &event) 68cb7eb8c9Sopenharmony_ci{ 69cb7eb8c9Sopenharmony_ci if (event == nullptr) { 70cb7eb8c9Sopenharmony_ci LOGI("eventhandler fail."); 71cb7eb8c9Sopenharmony_ci return; 72cb7eb8c9Sopenharmony_ci } 73cb7eb8c9Sopenharmony_ci auto pushData = event->GetSharedObject<PushAssetData>(); 74cb7eb8c9Sopenharmony_ci if (pushData == nullptr) { 75cb7eb8c9Sopenharmony_ci LOGE("pushData is nullptr."); 76cb7eb8c9Sopenharmony_ci return; 77cb7eb8c9Sopenharmony_ci } 78cb7eb8c9Sopenharmony_ci int32_t userId = pushData->userId_; 79cb7eb8c9Sopenharmony_ci auto assetObj = pushData->assetObj_; 80cb7eb8c9Sopenharmony_ci if (assetObj == nullptr) { 81cb7eb8c9Sopenharmony_ci LOGE("assetObj is nullptr."); 82cb7eb8c9Sopenharmony_ci return; 83cb7eb8c9Sopenharmony_ci } 84cb7eb8c9Sopenharmony_ci int32_t socketId; 85cb7eb8c9Sopenharmony_ci auto ret = SoftBusHandlerAsset::GetInstance().AssetBind(assetObj->dstNetworkId_, socketId); 86cb7eb8c9Sopenharmony_ci if (ret != E_OK) { 87cb7eb8c9Sopenharmony_ci LOGE("ExecutePushAsset AssetBind failed, ret %{public}d", ret); 88cb7eb8c9Sopenharmony_ci auto taskId = assetObj->srcBundleName_ + assetObj->sessionId_; 89cb7eb8c9Sopenharmony_ci AssetCallbackManager::GetInstance().NotifyAssetSendResult(taskId, assetObj, FileManagement::E_EVENT_HANDLER); 90cb7eb8c9Sopenharmony_ci AssetCallbackManager::GetInstance().RemoveSendCallback(taskId); 91cb7eb8c9Sopenharmony_ci return; 92cb7eb8c9Sopenharmony_ci } 93cb7eb8c9Sopenharmony_ci SoftBusHandlerAsset::GetInstance().AddAssetObj(socketId, assetObj); 94cb7eb8c9Sopenharmony_ci 95cb7eb8c9Sopenharmony_ci auto fileList = GetFileList(assetObj->uris_, userId, assetObj->srcBundleName_); 96cb7eb8c9Sopenharmony_ci if (fileList.empty()) { 97cb7eb8c9Sopenharmony_ci LOGE("get fileList is empty."); 98cb7eb8c9Sopenharmony_ci HandlePushAssetFail(socketId, assetObj); 99cb7eb8c9Sopenharmony_ci return; 100cb7eb8c9Sopenharmony_ci } 101cb7eb8c9Sopenharmony_ci 102cb7eb8c9Sopenharmony_ci std::string sendFileName; 103cb7eb8c9Sopenharmony_ci bool isSingleFile; 104cb7eb8c9Sopenharmony_ci ret = HandleZip(fileList, assetObj, sendFileName, isSingleFile); 105cb7eb8c9Sopenharmony_ci if (ret != E_OK) { 106cb7eb8c9Sopenharmony_ci LOGE("zip files fail. socketId is %{public}d", socketId); 107cb7eb8c9Sopenharmony_ci HandlePushAssetFail(socketId, assetObj); 108cb7eb8c9Sopenharmony_ci SoftBusHandlerAsset::GetInstance().RemoveFile(sendFileName, !isSingleFile); 109cb7eb8c9Sopenharmony_ci return; 110cb7eb8c9Sopenharmony_ci } 111cb7eb8c9Sopenharmony_ci 112cb7eb8c9Sopenharmony_ci ret = SoftBusHandlerAsset::GetInstance().AssetSendFile(socketId, sendFileName, isSingleFile); 113cb7eb8c9Sopenharmony_ci if (ret != E_OK) { 114cb7eb8c9Sopenharmony_ci LOGE("ExecutePushAsset send file fail, ret %{public}d", ret); 115cb7eb8c9Sopenharmony_ci HandlePushAssetFail(socketId, assetObj); 116cb7eb8c9Sopenharmony_ci SoftBusHandlerAsset::GetInstance().RemoveFile(sendFileName, !isSingleFile); 117cb7eb8c9Sopenharmony_ci return; 118cb7eb8c9Sopenharmony_ci } 119cb7eb8c9Sopenharmony_ci} 120cb7eb8c9Sopenharmony_ci 121cb7eb8c9Sopenharmony_civoid DaemonExecute::ExecuteRequestSendFile(const AppExecFwk::InnerEvent::Pointer &event) 122cb7eb8c9Sopenharmony_ci{ 123cb7eb8c9Sopenharmony_ci if (event == nullptr) { 124cb7eb8c9Sopenharmony_ci LOGI("eventhandler fail."); 125cb7eb8c9Sopenharmony_ci return; 126cb7eb8c9Sopenharmony_ci } 127cb7eb8c9Sopenharmony_ci auto requestSendFileData = event->GetSharedObject<RequestSendFileData>(); 128cb7eb8c9Sopenharmony_ci if (requestSendFileData == nullptr) { 129cb7eb8c9Sopenharmony_ci LOGE("requestSendFileData is nullptr."); 130cb7eb8c9Sopenharmony_ci return; 131cb7eb8c9Sopenharmony_ci } 132cb7eb8c9Sopenharmony_ci 133cb7eb8c9Sopenharmony_ci auto requestSendFileBlock = requestSendFileData->requestSendFileBlock_; 134cb7eb8c9Sopenharmony_ci if (requestSendFileBlock == nullptr) { 135cb7eb8c9Sopenharmony_ci LOGE("requestSendFileBlock is nullptr."); 136cb7eb8c9Sopenharmony_ci return; 137cb7eb8c9Sopenharmony_ci } 138cb7eb8c9Sopenharmony_ci std::string srcUri = requestSendFileData->srcUri_; 139cb7eb8c9Sopenharmony_ci std::string dstPath = requestSendFileData->dstPath_; 140cb7eb8c9Sopenharmony_ci std::string dstDeviceId = requestSendFileData->dstDeviceId_; 141cb7eb8c9Sopenharmony_ci std::string sessionName = requestSendFileData->sessionName_; 142cb7eb8c9Sopenharmony_ci if (srcUri.empty() || dstDeviceId.empty() || sessionName.empty()) { 143cb7eb8c9Sopenharmony_ci LOGE("params empty. %{public}s, %{public}s", sessionName.c_str(), Utils::GetAnonyString(dstDeviceId).c_str()); 144cb7eb8c9Sopenharmony_ci requestSendFileBlock->SetValue(ERR_BAD_VALUE); 145cb7eb8c9Sopenharmony_ci return; 146cb7eb8c9Sopenharmony_ci } 147cb7eb8c9Sopenharmony_ci 148cb7eb8c9Sopenharmony_ci requestSendFileBlock->SetValue(RequestSendFileInner(srcUri, dstPath, dstDeviceId, sessionName)); 149cb7eb8c9Sopenharmony_ci} 150cb7eb8c9Sopenharmony_ci 151cb7eb8c9Sopenharmony_ciint32_t DaemonExecute::RequestSendFileInner(const std::string &srcUri, 152cb7eb8c9Sopenharmony_ci const std::string &dstPath, 153cb7eb8c9Sopenharmony_ci const std::string &dstDeviceId, 154cb7eb8c9Sopenharmony_ci const std::string &sessionName) 155cb7eb8c9Sopenharmony_ci{ 156cb7eb8c9Sopenharmony_ci LOGI("RequestSendFile begin dstDeviceId: %{public}s", Utils::GetAnonyString(dstDeviceId).c_str()); 157cb7eb8c9Sopenharmony_ci auto resourceReq = AllConnectManager::GetInstance().BuildResourceRequest(); 158cb7eb8c9Sopenharmony_ci int32_t ret = AllConnectManager::GetInstance().ApplyAdvancedResource(dstDeviceId, resourceReq.get()); 159cb7eb8c9Sopenharmony_ci if (ret != E_OK) { 160cb7eb8c9Sopenharmony_ci LOGE("ApplyAdvancedResource fail, ret is %{public}d", ret); 161cb7eb8c9Sopenharmony_ci return ERR_APPLY_RESULT; 162cb7eb8c9Sopenharmony_ci } 163cb7eb8c9Sopenharmony_ci 164cb7eb8c9Sopenharmony_ci int32_t socketId; 165cb7eb8c9Sopenharmony_ci ret = SoftBusHandler::GetInstance().OpenSession(sessionName, sessionName, dstDeviceId, socketId); 166cb7eb8c9Sopenharmony_ci if (ret != E_OK) { 167cb7eb8c9Sopenharmony_ci LOGE("OpenSession failed, ret is %{public}d", ret); 168cb7eb8c9Sopenharmony_ci return ret; 169cb7eb8c9Sopenharmony_ci } 170cb7eb8c9Sopenharmony_ci AllConnectManager::GetInstance().PublishServiceState(dstDeviceId, 171cb7eb8c9Sopenharmony_ci ServiceCollaborationManagerBussinessStatus::SCM_CONNECTED); 172cb7eb8c9Sopenharmony_ci LOGI("RequestSendFile OpenSession success"); 173cb7eb8c9Sopenharmony_ci 174cb7eb8c9Sopenharmony_ci ret = SoftBusHandler::GetInstance().CopySendFile(socketId, sessionName, srcUri, dstPath); 175cb7eb8c9Sopenharmony_ci if (ret != E_OK) { 176cb7eb8c9Sopenharmony_ci LOGE("CopySendFile failed, ret is %{public}d", ret); 177cb7eb8c9Sopenharmony_ci SoftBusHandler::GetInstance().CloseSession(socketId, sessionName); 178cb7eb8c9Sopenharmony_ci return ret; 179cb7eb8c9Sopenharmony_ci } 180cb7eb8c9Sopenharmony_ci return E_OK; 181cb7eb8c9Sopenharmony_ci} 182cb7eb8c9Sopenharmony_ci 183cb7eb8c9Sopenharmony_cistd::string DaemonExecute::GetZipName(const std::string &relativePath) 184cb7eb8c9Sopenharmony_ci{ 185cb7eb8c9Sopenharmony_ci auto cppnow = std::chrono::system_clock::now(); 186cb7eb8c9Sopenharmony_ci auto cppnow_ms = std::chrono::time_point_cast<std::chrono::milliseconds>(cppnow); 187cb7eb8c9Sopenharmony_ci auto value = std::to_string(cppnow_ms.time_since_epoch().count()); 188cb7eb8c9Sopenharmony_ci 189cb7eb8c9Sopenharmony_ci std::random_device rd; 190cb7eb8c9Sopenharmony_ci std::string random = std::to_string(rd()); 191cb7eb8c9Sopenharmony_ci std::string zipName = value + "_" + random + ".zip"; 192cb7eb8c9Sopenharmony_ci 193cb7eb8c9Sopenharmony_ci while (std::filesystem::exists(relativePath + zipName)) { 194cb7eb8c9Sopenharmony_ci random = std::to_string(rd()); 195cb7eb8c9Sopenharmony_ci zipName = value + "_" + random + ".zip"; 196cb7eb8c9Sopenharmony_ci } 197cb7eb8c9Sopenharmony_ci LOGI("zipName is %{public}s", zipName.c_str()); 198cb7eb8c9Sopenharmony_ci return zipName; 199cb7eb8c9Sopenharmony_ci} 200cb7eb8c9Sopenharmony_ci 201cb7eb8c9Sopenharmony_cistd::vector<std::string> DaemonExecute::GetFileList(const std::vector<std::string> &uris, 202cb7eb8c9Sopenharmony_ci int32_t userId, 203cb7eb8c9Sopenharmony_ci const std::string &srcBundleName) 204cb7eb8c9Sopenharmony_ci{ 205cb7eb8c9Sopenharmony_ci std::vector<std::string> fileList; 206cb7eb8c9Sopenharmony_ci std::regex pattern("/mnt/hmdfs/\\d{3,}/account/device_view/local/data/.*"); 207cb7eb8c9Sopenharmony_ci for (const auto &uri : uris) { 208cb7eb8c9Sopenharmony_ci size_t pos = uri.find(srcBundleName); 209cb7eb8c9Sopenharmony_ci if (pos == std::string::npos) { 210cb7eb8c9Sopenharmony_ci LOGE("srcBundleName not find in uri."); 211cb7eb8c9Sopenharmony_ci return {}; 212cb7eb8c9Sopenharmony_ci } 213cb7eb8c9Sopenharmony_ci 214cb7eb8c9Sopenharmony_ci std::string physicalPath; 215cb7eb8c9Sopenharmony_ci int32_t ret = SandboxHelper::GetPhysicalPath(uri, std::to_string(userId), physicalPath); 216cb7eb8c9Sopenharmony_ci if (ret != E_OK) { 217cb7eb8c9Sopenharmony_ci LOGE("invalid uri, ret = %{public}d", ret); 218cb7eb8c9Sopenharmony_ci return {}; 219cb7eb8c9Sopenharmony_ci } 220cb7eb8c9Sopenharmony_ci if (!SandboxHelper::CheckValidPath(physicalPath)) { 221cb7eb8c9Sopenharmony_ci LOGE("invalid path : %{public}s", GetAnonyString(physicalPath).c_str()); 222cb7eb8c9Sopenharmony_ci return {}; 223cb7eb8c9Sopenharmony_ci } 224cb7eb8c9Sopenharmony_ci if (OHOS::Storage::DistributedFile::Utils::IsFolder(physicalPath)) { 225cb7eb8c9Sopenharmony_ci LOGE("uri is folder are not supported now."); 226cb7eb8c9Sopenharmony_ci return {}; 227cb7eb8c9Sopenharmony_ci } 228cb7eb8c9Sopenharmony_ci if (!std::regex_match(physicalPath, pattern)) { 229cb7eb8c9Sopenharmony_ci LOGE("physicalPath is not hmdfs path."); 230cb7eb8c9Sopenharmony_ci } 231cb7eb8c9Sopenharmony_ci fileList.emplace_back(physicalPath); 232cb7eb8c9Sopenharmony_ci } 233cb7eb8c9Sopenharmony_ci LOGI("GetFileList success, file num is %{public}s", std::to_string(fileList.size()).c_str()); 234cb7eb8c9Sopenharmony_ci return fileList; 235cb7eb8c9Sopenharmony_ci} 236cb7eb8c9Sopenharmony_ci 237cb7eb8c9Sopenharmony_ciint32_t DaemonExecute::HandleZip(const std::vector<std::string> &fileList, 238cb7eb8c9Sopenharmony_ci const sptr<AssetObj> &assetObj, 239cb7eb8c9Sopenharmony_ci std::string &sendFileName, 240cb7eb8c9Sopenharmony_ci bool &isSingleFile) 241cb7eb8c9Sopenharmony_ci{ 242cb7eb8c9Sopenharmony_ci if (fileList.size() > 1) { 243cb7eb8c9Sopenharmony_ci size_t pos = fileList[0].find(assetObj->srcBundleName_); 244cb7eb8c9Sopenharmony_ci if (pos == std::string::npos) { 245cb7eb8c9Sopenharmony_ci LOGE("srcBundleName not find in uri."); 246cb7eb8c9Sopenharmony_ci return E_ZIP; 247cb7eb8c9Sopenharmony_ci } 248cb7eb8c9Sopenharmony_ci std::string relativePath = fileList[0].substr(0, pos + assetObj->srcBundleName_.length()) + "/"; 249cb7eb8c9Sopenharmony_ci sendFileName = relativePath + GetZipName(relativePath); 250cb7eb8c9Sopenharmony_ci int32_t ret = SoftBusHandlerAsset::GetInstance().CompressFile(fileList, relativePath, sendFileName); 251cb7eb8c9Sopenharmony_ci if (ret != E_OK) { 252cb7eb8c9Sopenharmony_ci LOGE("zip ffiles fail."); 253cb7eb8c9Sopenharmony_ci return E_ZIP; 254cb7eb8c9Sopenharmony_ci } 255cb7eb8c9Sopenharmony_ci isSingleFile = false; 256cb7eb8c9Sopenharmony_ci SoftBusAssetSendListener::AddFileMap(assetObj->srcBundleName_ + assetObj->sessionId_, false); 257cb7eb8c9Sopenharmony_ci return E_OK; 258cb7eb8c9Sopenharmony_ci } else { 259cb7eb8c9Sopenharmony_ci sendFileName = fileList[0]; 260cb7eb8c9Sopenharmony_ci isSingleFile = true; 261cb7eb8c9Sopenharmony_ci SoftBusAssetSendListener::AddFileMap(assetObj->srcBundleName_ + assetObj->sessionId_, true); 262cb7eb8c9Sopenharmony_ci return E_OK; 263cb7eb8c9Sopenharmony_ci } 264cb7eb8c9Sopenharmony_ci} 265cb7eb8c9Sopenharmony_ci 266cb7eb8c9Sopenharmony_civoid DaemonExecute::HandlePushAssetFail(int32_t socketId, const sptr<AssetObj> &assetObj) 267cb7eb8c9Sopenharmony_ci{ 268cb7eb8c9Sopenharmony_ci auto taskId = assetObj->srcBundleName_ + assetObj->sessionId_; 269cb7eb8c9Sopenharmony_ci AssetCallbackManager::GetInstance().NotifyAssetSendResult(taskId, assetObj, FileManagement::E_EVENT_HANDLER); 270cb7eb8c9Sopenharmony_ci SoftBusHandlerAsset::GetInstance().closeAssetBind(socketId); 271cb7eb8c9Sopenharmony_ci AssetCallbackManager::GetInstance().RemoveSendCallback(taskId); 272cb7eb8c9Sopenharmony_ci SoftBusAssetSendListener::RemoveFileMap(taskId); 273cb7eb8c9Sopenharmony_ci} 274cb7eb8c9Sopenharmony_ci} // namespace DistributedFile 275cb7eb8c9Sopenharmony_ci} // namespace Storage 276cb7eb8c9Sopenharmony_ci} // namespace OHOS 277