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