• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_pool.h"
45 #include "network/softbus/softbus_session_listener.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 
52 namespace OHOS {
53 namespace Storage {
54 namespace DistributedFile {
55 using namespace std;
56 using namespace OHOS::AppFileService;
57 using namespace OHOS::FileManagement;
58 using namespace OHOS::Storage::DistributedFile;
59 using HapTokenInfo = OHOS::Security::AccessToken::HapTokenInfo;
60 using AccessTokenKit = OHOS::Security::AccessToken::AccessTokenKit;
61 
62 namespace {
63 const string FILE_MANAGER_AUTHORITY = "docs";
64 const string MEDIA_AUTHORITY = "media";
65 const int32_t E_PERMISSION_DENIED_NAPI = 201;
66 const int32_t E_INVAL_ARG_NAPI = 401;
67 const int32_t E_CONNECTION_FAILED = 13900045;
68 const int32_t E_UNMOUNT = 13600004;
69 constexpr int32_t CHECK_SESSION_DELAY_TIME_TWICE = 5000000;
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     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 
CloseP2PConnection(const DistributedHardware::DmDeviceInfo & deviceInfo)200 int32_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 
ConnectionCount(const DistributedHardware::DmDeviceInfo & deviceInfo)211 int32_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 
CleanUp(const DistributedHardware::DmDeviceInfo & deviceInfo,const std::string & networkId,uint32_t callingTokenId)235 int32_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 
ConnectionAndMount(const DistributedHardware::DmDeviceInfo & deviceInfo,const std::string & networkId,uint32_t callingTokenId)252 int32_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 
OpenP2PConnectionEx(const std::string & networkId,sptr<IFileDfsListener> remoteReverseObj)276 int32_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 
CloseP2PConnectionEx(const std::string & networkId)316 int32_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 
RequestSendFile(const std::string & srcUri,const std::string & dstPath,const std::string & dstDeviceId,const std::string & sessionName)357 int32_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     auto requestSendFileBlock = std::make_shared<BlockObject<int32_t>>(BLOCK_INTERVAL_SEND_FILE, ERR_BAD_VALUE);
364     auto requestSendFileData = std::make_shared<RequestSendFileData>(
365         srcUri, dstPath, dstDeviceId, sessionName, requestSendFileBlock);
366     auto msgEvent = AppExecFwk::InnerEvent::Get(DEAMON_EXECUTE_REQUEST_SEND_FILE, requestSendFileData, 0);
367     {
368         std::lock_guard<std::mutex> lock(eventHandlerMutex_);
369         if (eventHandler_ == nullptr) {
370             LOGE("eventHandler has not find");
371             return E_EVENT_HANDLER;
372         }
373         bool isSucc = eventHandler_->SendEvent(msgEvent, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE);
374         if (!isSucc) {
375             LOGE("Daemon event handler post push asset event fail.");
376             return E_EVENT_HANDLER;
377         }
378     }
379 
380     auto ret = requestSendFileBlock->GetValue();
381     LOGI("RequestSendFile end, ret is %{public}d", ret);
382     return ret;
383 }
384 
PrepareSession(const std::string & srcUri,const std::string & dstUri,const std::string & srcDeviceId,const sptr<IRemoteObject> & listener,HmdfsInfo & info)385 int32_t Daemon::PrepareSession(const std::string &srcUri,
386                                const std::string &dstUri,
387                                const std::string &srcDeviceId,
388                                const sptr<IRemoteObject> &listener,
389                                HmdfsInfo &info)
390 {
391     LOGI("PrepareSession begin srcDeviceId: %{public}s", Utils::GetAnonyString(srcDeviceId).c_str());
392     auto listenerCallback = iface_cast<IFileTransListener>(listener);
393     if (listenerCallback == nullptr) {
394         LOGE("ListenerCallback is nullptr");
395         return E_NULLPTR;
396     }
397 
398     auto daemon = GetRemoteSA(srcDeviceId);
399     if (daemon == nullptr) {
400         LOGE("Daemon is nullptr");
401         return E_SA_LOAD_FAILED;
402     }
403 
404     std::string physicalPath;
405     auto ret = GetRealPath(srcUri, dstUri, physicalPath, info, daemon);
406     if (ret != E_OK) {
407         LOGE("GetRealPath failed, ret = %{public}d", ret);
408         return ret;
409     }
410 
411     SoftBusSessionPool::SessionInfo sessionInfo{.dstPath = physicalPath, .uid = IPCSkeleton::GetCallingUid()};
412     auto sessionName = SoftBusSessionPool::GetInstance().GenerateSessionName(sessionInfo);
413     if (sessionName.empty()) {
414         LOGE("SessionServer exceed max");
415         return E_SOFTBUS_SESSION_FAILED;
416     }
417     info.sessionName = sessionName;
418     StoreSessionAndListener(physicalPath, sessionName, listenerCallback);
419 
420     auto prepareSessionBlock = std::make_shared<BlockObject<int32_t>>(BLOCK_INTERVAL_SEND_FILE, ERR_BAD_VALUE);
421     auto prepareSessionData = std::make_shared<PrepareSessionData>(
422         srcUri, physicalPath, sessionName, daemon, info, prepareSessionBlock);
423     auto msgEvent = AppExecFwk::InnerEvent::Get(DEAMON_EXECUTE_PREPARE_SESSION, prepareSessionData, 0);
424     {
425         std::lock_guard<std::mutex> lock(eventHandlerMutex_);
426         if (eventHandler_ == nullptr) {
427             LOGE("eventHandler has not find");
428             return E_EVENT_HANDLER;
429         }
430         bool isSucc = eventHandler_->SendEvent(msgEvent, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE);
431         if (!isSucc) {
432             LOGE("Daemon event handler post Prepare Session event fail.");
433             return E_EVENT_HANDLER;
434         }
435     }
436 
437     ret = prepareSessionBlock->GetValue();
438     LOGI("PrepareSession end, ret is %{public}d", ret);
439     return ret;
440 }
441 
StoreSessionAndListener(const std::string & physicalPath,const std::string & sessionName,const sptr<IFileTransListener> & listener)442 void Daemon::StoreSessionAndListener(const std::string &physicalPath,
443                                      const std::string &sessionName,
444                                      const sptr<IFileTransListener> &listener)
445 {
446     TransManager::GetInstance().AddTransTask(sessionName, listener);
447 }
448 
GetRealPath(const std::string & srcUri,const std::string & dstUri,std::string & physicalPath,HmdfsInfo & info,const sptr<IDaemon> & daemon)449 int32_t Daemon::GetRealPath(const std::string &srcUri,
450                             const std::string &dstUri,
451                             std::string &physicalPath,
452                             HmdfsInfo &info,
453                             const sptr<IDaemon> &daemon)
454 {
455     auto start = std::chrono::high_resolution_clock::now();
456     bool isSrcFile = false;
457     bool isSrcDir = false;
458     if (daemon == nullptr) {
459         LOGE("Daemon::GetRealPath daemon is nullptr");
460         return E_INVAL_ARG_NAPI;
461     }
462     auto ret = daemon->GetRemoteCopyInfo(srcUri, isSrcFile, isSrcDir);
463     if (ret != E_OK) {
464         LOGE("GetRemoteCopyInfo failed, ret = %{public}d", ret);
465         RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_FAILED,
466             RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::ERROR_CODE,
467             RadarReporter::GET_REMOTE_COPY_INFO_ERROR);
468         return E_SOFTBUS_SESSION_FAILED;
469     }
470 
471     HapTokenInfo hapTokenInfo;
472     int result = AccessTokenKit::GetHapTokenInfo(IPCSkeleton::GetCallingTokenID(), hapTokenInfo);
473     if (result != Security::AccessToken::AccessTokenKitRet::RET_SUCCESS) {
474         LOGE("GetHapTokenInfo failed, errCode = %{public}d", result);
475         RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_FAILED,
476             RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::ERROR_CODE,
477             RadarReporter::GET_HAP_TOKEN_INFO_ERROR, RadarReporter::PACKAGE_NAME,
478             RadarReporter::accessTokenKit + to_string(result));
479         return E_GET_USER_ID;
480     }
481     ret = SandboxHelper::GetPhysicalPath(dstUri, std::to_string(hapTokenInfo.userID), physicalPath);
482     if (ret != E_OK) {
483         LOGE("invalid uri, ret = %{public}d", ret);
484         return E_GET_PHYSICAL_PATH_FAILED;
485     }
486 
487     LOGI("physicalPath %{public}s, userId %{public}s", GetAnonyString(physicalPath).c_str(),
488          std::to_string(hapTokenInfo.userID).c_str());
489     info.dstPhysicalPath = physicalPath;
490     ret = CheckCopyRule(physicalPath, dstUri, hapTokenInfo, isSrcFile, info);
491     if (ret != E_OK) {
492         LOGE("CheckCopyRule failed, ret = %{public}d", ret);
493         return E_GET_PHYSICAL_PATH_FAILED;
494     }
495     auto end = std::chrono::high_resolution_clock::now();
496     auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
497     Utils::SysEventFileParse(duration.count());
498     return E_OK;
499 }
500 
CheckCopyRule(std::string & physicalPath,const std::string & dstUri,HapTokenInfo & hapTokenInfo,const bool & isSrcFile,HmdfsInfo & info)501 int32_t Daemon::CheckCopyRule(std::string &physicalPath,
502                               const std::string &dstUri,
503                               HapTokenInfo &hapTokenInfo,
504                               const bool &isSrcFile,
505                               HmdfsInfo &info)
506 {
507     auto checkPath = physicalPath;
508     if (isSrcFile && !Utils::IsFolder(physicalPath)) {
509         auto pos = physicalPath.rfind('/');
510         if (pos == std::string::npos) {
511             LOGE("invalid file path");
512             return E_GET_PHYSICAL_PATH_FAILED;
513         }
514         physicalPath = physicalPath.substr(0, pos);
515     }
516 
517     std::error_code errCode;
518     if (!std::filesystem::exists(physicalPath, errCode) && info.dirExistFlag) {
519         LOGI("Not CheckValidPath, physicalPath %{public}s", GetAnonyString(physicalPath).c_str());
520     } else {
521         auto pos = checkPath.rfind('/');
522         if (pos == std::string::npos) {
523             LOGE("invalid file path");
524             return E_GET_PHYSICAL_PATH_FAILED;
525         }
526         checkPath = checkPath.substr(0, pos);
527         if (!SandboxHelper::CheckValidPath(checkPath)) {
528             LOGE("invalid path.");
529             return E_GET_PHYSICAL_PATH_FAILED;
530         }
531     }
532 
533     Uri uri(dstUri);
534     auto authority = uri.GetAuthority();
535     info.authority = authority;
536     if (authority != FILE_MANAGER_AUTHORITY && authority != MEDIA_AUTHORITY) {
537         auto bundleName = SoftBusSessionListener::GetBundleName(dstUri);
538         physicalPath = "/data/service/el2/" + to_string(hapTokenInfo.userID) + "/hmdfs/account/data/" + bundleName +
539                        "/" + info.copyPath;
540         if (!SandboxHelper::CheckValidPath(physicalPath)) {
541             LOGE("invalid path.");
542             return E_GET_PHYSICAL_PATH_FAILED;
543         }
544     } else {
545         std::regex pathRegex("^[a-zA-Z0-9_\\-/\\\\]*$");
546         if (!std::filesystem::exists(physicalPath, errCode) && std::regex_match(physicalPath.c_str(), pathRegex)) {
547             std::filesystem::create_directory(physicalPath, errCode);
548             if (errCode.value() != 0) {
549                 LOGE("Create directory failed, physicalPath %{public}s", GetAnonyString(physicalPath).c_str());
550                 return E_GET_PHYSICAL_PATH_FAILED;
551             }
552         }
553     }
554     return E_OK;
555 }
556 
GetRemoteCopyInfo(const std::string & srcUri,bool & isSrcFile,bool & srcIsDir)557 int32_t Daemon::GetRemoteCopyInfo(const std::string &srcUri, bool &isSrcFile, bool &srcIsDir)
558 {
559     LOGI("GetRemoteCopyInfo begin.");
560     auto physicalPath = SoftBusSessionListener::GetRealPath(srcUri);
561     if (physicalPath.empty()) {
562         LOGE("GetRemoteCopyInfo GetRealPath failed.");
563         return E_SOFTBUS_SESSION_FAILED;
564     }
565     isSrcFile = Utils::IsFile(physicalPath);
566     srcIsDir = Utils::IsFolder(physicalPath);
567     return E_OK;
568 }
569 
GetRemoteSA(const std::string & remoteDeviceId)570 sptr<IDaemon> Daemon::GetRemoteSA(const std::string &remoteDeviceId)
571 {
572     LOGI("GetRemoteSA begin, DeviceId: %{public}s", Utils::GetAnonyString(remoteDeviceId).c_str());
573     auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
574     if (sam == nullptr) {
575         LOGE("Sam is nullptr");
576         return nullptr;
577     }
578 
579     auto object = sam->GetSystemAbility(FILEMANAGEMENT_DISTRIBUTED_FILE_DAEMON_SA_ID, remoteDeviceId);
580     if (object == nullptr) {
581         LOGE("GetSystemAbility failed");
582         RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_FAILED,
583             RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::ERROR_CODE,
584             RadarReporter::GET_SYSTEM_ABILITY_ERROR, RadarReporter::PACKAGE_NAME, RadarReporter::saMgr);
585         return nullptr;
586     }
587     auto daemon = iface_cast<IDaemon>(object);
588     if (daemon == nullptr) {
589         LOGE("Connect service nullptr");
590         return nullptr;
591     }
592     LOGI("GetRemoteSA success, DeviceId: %{public}s", Utils::GetAnonyString(remoteDeviceId).c_str());
593     return daemon;
594 }
595 
Copy(const std::string & srcUri,const std::string & dstPath,const sptr<IDaemon> & daemon,const std::string & sessionName)596 int32_t Daemon::Copy(const std::string &srcUri,
597                      const std::string &dstPath,
598                      const sptr<IDaemon> &daemon,
599                      const std::string &sessionName)
600 {
601     auto &deviceManager = DistributedHardware::DeviceManager::GetInstance();
602     DistributedHardware::DmDeviceInfo localDeviceInfo{};
603     int errCode = deviceManager.GetLocalDeviceInfo(IDaemon::SERVICE_NAME, localDeviceInfo);
604     if (errCode != E_OK) {
605         LOGE("GetLocalDeviceInfo failed, errCode = %{public}d", errCode);
606         return E_GET_DEVICE_ID;
607     }
608     if (daemon == nullptr) {
609         LOGE("Daemon::Copy daemon is nullptr");
610         return E_INVAL_ARG_NAPI;
611     }
612     LOGI("Copy localDeviceInfo.networkId: %{public}s", Utils::GetAnonyString(localDeviceInfo.networkId).c_str());
613     auto ret = daemon->RequestSendFile(srcUri, dstPath, localDeviceInfo.networkId, sessionName);
614     if (ret != E_OK) {
615         LOGE("RequestSendFile failed, ret = %{public}d", ret);
616         RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_FAILED,
617             RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::ERROR_CODE,
618             RadarReporter::REQUEST_SEND_FILE_ERROR, RadarReporter::PACKAGE_NAME, ret);
619         return E_SA_LOAD_FAILED;
620     }
621     return E_OK;
622 }
623 
CancelCopyTask(const std::string & sessionName)624 int32_t Daemon::CancelCopyTask(const std::string &sessionName)
625 {
626     LOGI("Cancel copy task in. sessionName = %{public}s", sessionName.c_str());
627     SoftBusSessionPool::SessionInfo sessionInfo{};
628     bool isExist = SoftBusSessionPool::GetInstance().GetSessionInfo(sessionName, sessionInfo);
629     if (!isExist) {
630         LOGE("CancelCopyTask failed, cannot get session info for input session name=%{public}s.", sessionName.c_str());
631         return E_INVAL_ARG;
632     }
633     auto callingUid = IPCSkeleton::GetCallingUid();
634     if (callingUid != sessionInfo.uid) {
635         LOGE("CancelCopyTask failed, calling uid=%{public}d has no permission to cancel copy for uid=%{public}d.",
636              callingUid, sessionInfo.uid);
637         return E_PERMISSION_DENIED;
638     }
639     SoftBusHandler::GetInstance().CloseSessionWithSessionName(sessionName);
640     return E_OK;
641 }
642 
DeleteSessionAndListener(const std::string & sessionName,const int32_t socketId)643 void Daemon::DeleteSessionAndListener(const std::string &sessionName, const int32_t socketId)
644 {
645     SoftBusSessionPool::GetInstance().DeleteSessionInfo(sessionName);
646     TransManager::GetInstance().DeleteTransTask(sessionName);
647     SoftBusHandler::GetInstance().CloseSession(socketId, sessionName);
648 }
649 
OnRemoteDied(const wptr<IRemoteObject> & remote)650 void Daemon::DfsListenerDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
651 {
652     sptr<IRemoteObject> diedRemote = remote.promote();
653     if (diedRemote == nullptr) {
654         LOGE("Daemon::DfsListenerDeathRecipient OnremoteDied received died notify nullptr");
655         return;
656     }
657     auto deviceManager = DeviceManagerAgent::GetInstance();
658     uint32_t callingTokenId = 0;
659     sptr<IFileDfsListener> listener = nullptr;
660     deviceManager->FindListenerByObject(remote, callingTokenId, listener);
661     if (callingTokenId==0 || listener == nullptr) {
662         LOGE("fail to FindListenerByObject");
663         return;
664     }
665     if (deviceManager->RemoveRemoteReverseObj(false, callingTokenId) != E_OK) {
666         LOGE("fail to RemoveRemoteReverseObj");
667     }
668     auto networkIdSet = deviceManager->GetNetworkIds(callingTokenId);
669     if (networkIdSet.empty()) {
670         LOGE("fail to get networkIdSet");
671         return;
672     }
673     for (auto it = networkIdSet.begin(); it != networkIdSet.end(); ++it) {
674         if (it->empty()) {
675             LOGE("[DfsListenerDeathRecipient] networkId is null");
676             continue;
677         }
678         std::string deviceId = deviceManager->GetDeviceIdByNetworkId(*it);
679         if (deviceId.empty()) {
680             LOGE("fail to get deviceId, networkId: %{public}s", Utils::GetAnonyString(*it).c_str());
681             continue;
682         }
683         deviceManager->UMountDfsDocs(*it, deviceId, false);
684         DistributedHardware::DmDeviceInfo deviceInfo{};
685         auto res = strcpy_s(deviceInfo.networkId, it->size() + 1, it->c_str());
686         if (res != 0) {
687             LOGE("strcpy failed, res = %{public}d", res);
688             return;
689         }
690         std::thread([=]() {
691             int32_t ret = deviceManager->OnDeviceP2POffline(deviceInfo);
692             LOGI("Close P2P Connection result %d", ret);
693             }).detach();
694     }
695     deviceManager->RemoveNetworkId(callingTokenId);
696     LOGI("Daemon::DfsListenerDeathRecipient OnremoteDied end");
697     return;
698 }
699 
PushAsset(int32_t userId,const sptr<AssetObj> & assetObj,const sptr<IAssetSendCallback> & sendCallback)700 int32_t Daemon::PushAsset(int32_t userId,
701                           const sptr<AssetObj> &assetObj,
702                           const sptr<IAssetSendCallback> &sendCallback)
703 {
704     LOGI("Daemon::PushAsset begin.");
705     if (assetObj == nullptr || sendCallback == nullptr) {
706         LOGE("param is nullptr.");
707         return E_NULLPTR;
708     }
709     auto taskId = assetObj->srcBundleName_ + assetObj->sessionId_;
710     if (taskId.empty()) {
711         LOGE("assetObj info is null.");
712         return E_NULLPTR;
713     }
714     AssetCallbackManager::GetInstance().AddSendCallback(taskId, sendCallback);
715     auto pushData = std::make_shared<PushAssetData>(userId, assetObj);
716     auto msgEvent = AppExecFwk::InnerEvent::Get(DEAMON_EXECUTE_PUSH_ASSET, pushData, 0);
717 
718     std::lock_guard<std::mutex> lock(eventHandlerMutex_);
719     if (eventHandler_ == nullptr) {
720         LOGE("eventHandler has not find");
721         AssetCallbackManager::GetInstance().RemoveSendCallback(taskId);
722         return E_EVENT_HANDLER;
723     }
724     bool isSucc = eventHandler_->SendEvent(msgEvent, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE);
725     if (!isSucc) {
726         LOGE("Daemon event handler post push asset event fail.");
727         AssetCallbackManager::GetInstance().RemoveSendCallback(taskId);
728         return E_EVENT_HANDLER;
729     }
730     return E_OK;
731 }
732 
RegisterAssetCallback(const sptr<IAssetRecvCallback> & recvCallback)733 int32_t Daemon::RegisterAssetCallback(const sptr<IAssetRecvCallback> &recvCallback)
734 {
735     LOGI("Daemon::RegisterAssetCallback begin.");
736     if (recvCallback == nullptr) {
737         LOGE("recvCallback is nullptr.");
738         return E_NULLPTR;
739     }
740     AssetCallbackManager::GetInstance().AddRecvCallback(recvCallback);
741     return E_OK;
742 }
743 
UnRegisterAssetCallback(const sptr<IAssetRecvCallback> & recvCallback)744 int32_t Daemon::UnRegisterAssetCallback(const sptr<IAssetRecvCallback> &recvCallback)
745 {
746     LOGI("Daemon::UnRegisterAssetCallback begin.");
747     if (recvCallback == nullptr) {
748         LOGE("recvCallback is nullptr.");
749         return E_NULLPTR;
750     }
751     AssetCallbackManager::GetInstance().RemoveRecvCallback(recvCallback);
752     return E_OK;
753 }
754 
StartEventHandler()755 void Daemon::StartEventHandler()
756 {
757     LOGI("StartEventHandler begin");
758     if (daemonExecute_ == nullptr) {
759         daemonExecute_ = std::make_shared<DaemonExecute>();
760     }
761 
762     std::lock_guard<std::mutex> lock(eventHandlerMutex_);
763     auto runer = AppExecFwk::EventRunner::Create(IDaemon::SERVICE_NAME.c_str());
764     eventHandler_ = std::make_shared<DaemonEventHandler>(runer, daemonExecute_);
765 }
766 } // namespace DistributedFile
767 } // namespace Storage
768 } // namespace OHOS