1 /*
2  * Copyright (c) 2023 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 #include "ipc/cloud_sync_service.h"
16 
17 #include <cstdint>
18 #include <memory>
19 
20 #include "battery_status.h"
21 #include "cloud_file_kit.h"
22 #include "cloud_status.h"
23 #include "cycle_task/cycle_task_runner.h"
24 #include "data_sync_const.h"
25 #include "data_syncer_rdb_store.h"
26 #include "dfs_error.h"
27 #include "dfsu_access_token_helper.h"
28 #include "directory_ex.h"
29 #include "ipc/download_asset_callback_manager.h"
30 #include "meta_file.h"
31 #include "net_conn_callback_observer.h"
32 #include "parameters.h"
33 #include "periodic_check_task.h"
34 #include "plugin_loader.h"
35 #include "network_status.h"
36 #include "sandbox_helper.h"
37 #include "screen_status.h"
38 #include "session_manager.h"
39 #include "system_ability_definition.h"
40 #include "system_load.h"
41 #include "task_state_manager.h"
42 #include "utils_log.h"
43 
44 namespace OHOS::FileManagement::CloudSync {
45 using namespace std;
46 using namespace OHOS;
47 using namespace CloudFile;
48 constexpr int32_t MIN_USER_ID = 100;
49 constexpr int LOAD_SA_TIMEOUT_MS = 4000;
50 
51 REGISTER_SYSTEM_ABILITY_BY_ID(CloudSyncService, FILEMANAGEMENT_CLOUD_SYNC_SERVICE_SA_ID, false);
52 
CloudSyncService(int32_t saID,bool runOnCreate)53 CloudSyncService::CloudSyncService(int32_t saID, bool runOnCreate) : SystemAbility(saID, runOnCreate)
54 {
55 }
56 
PublishSA()57 void CloudSyncService::PublishSA()
58 {
59     LOGI("Begin to init");
60     if (!SystemAbility::Publish(this)) {
61         throw runtime_error("Failed to publish the daemon");
62     }
63     LOGI("Init finished successfully");
64 }
65 
PreInit()66 void CloudSyncService::PreInit()
67 {
68     /* load cloud file ext plugin */
69     CloudFile::PluginLoader::GetInstance().LoadCloudKitPlugin(true);
70     auto instance = CloudFile::CloudFileKit::GetInstance();
71     if (instance == nullptr) {
72         LOGE("get cloud file helper instance failed");
73         dataSyncManager_ = make_shared<DataSyncManager>();
74     } else {
75         dataSyncManager_ = instance->GetDataSyncManager();
76     }
77 
78     batteryStatusListener_ = make_shared<BatteryStatusListener>(dataSyncManager_);
79     screenStatusListener_ = make_shared<ScreenStatusListener>(dataSyncManager_);
80     userStatusListener_ = make_shared<UserStatusListener>(dataSyncManager_);
81 }
82 
Init()83 void CloudSyncService::Init()
84 {
85     NetworkStatus::InitNetwork(dataSyncManager_);
86     /* Get Init Charging status */
87     BatteryStatus::GetInitChargingStatus();
88     ScreenStatus::InitScreenStatus();
89 }
90 
91 constexpr int TEST_MAIN_USR_ID = 100;
GetBundleNameUserInfo(BundleNameUserInfo & bundleNameUserInfo)92 int32_t CloudSyncService::GetBundleNameUserInfo(BundleNameUserInfo &bundleNameUserInfo)
93 {
94     string bundleName;
95     if (DfsuAccessTokenHelper::GetCallerBundleName(bundleName)) {
96         return E_INVAL_ARG;
97     }
98     bundleNameUserInfo.bundleName = bundleName;
99 
100     auto callerUserId = DfsuAccessTokenHelper::GetUserId();
101     if (callerUserId == 0) {
102         callerUserId = TEST_MAIN_USR_ID; // for root user change id to main user for test
103     }
104     bundleNameUserInfo.userId = callerUserId;
105 
106     auto callerPid = DfsuAccessTokenHelper::GetPid();
107     bundleNameUserInfo.pid = callerPid;
108 
109     return E_OK;
110 }
111 
GetBundleNameUserInfo(const std::vector<std::string> & uriVec,BundleNameUserInfo & bundleNameUserInfo)112 void CloudSyncService::GetBundleNameUserInfo(const std::vector<std::string> &uriVec,
113                                              BundleNameUserInfo &bundleNameUserInfo)
114 {
115     Uri uri(uriVec[0]);
116     string bundleName = uri.GetAuthority();
117     bundleNameUserInfo.bundleName = bundleName;
118 
119     auto callerUserId = DfsuAccessTokenHelper::GetUserId();
120     if (callerUserId == 0) {
121         callerUserId = TEST_MAIN_USR_ID; // for root user change id to main user for test
122     }
123     bundleNameUserInfo.userId = callerUserId;
124 
125     auto callerPid = DfsuAccessTokenHelper::GetPid();
126     bundleNameUserInfo.pid = callerPid;
127 }
128 
GetHmdfsPath(const std::string & uri,int32_t userId)129 std::string CloudSyncService::GetHmdfsPath(const std::string &uri, int32_t userId)
130 {
131     const std::string HMDFS_DIR = "/mnt/hmdfs/";
132     const std::string DATA_DIR = "/account/device_view/local/data/";
133     const std::string FILE_DIR = "data/storage/el2/distributedfiles/";
134     const std::string URI_PREFIX = "://";
135     if (uri.empty() || uri.find("..") != std::string::npos) {
136         return "";
137     }
138 
139     std::string bundleName;
140     size_t uriPrefixPos = uri.find(URI_PREFIX);
141     if (uriPrefixPos == std::string::npos) {
142         return "";
143     }
144     uriPrefixPos += URI_PREFIX.length();
145     size_t bundleNameEndPos = uri.find('/', uriPrefixPos);
146     if (bundleNameEndPos == std::string::npos) {
147         return "";
148     }
149     bundleName = uri.substr(uriPrefixPos, bundleNameEndPos - uriPrefixPos);
150 
151     std::string relativePath;
152     size_t fileDirPos = uri.find(FILE_DIR);
153     if (fileDirPos == std::string::npos) {
154         return "";
155     }
156     fileDirPos += FILE_DIR.length();
157     relativePath = uri.substr(fileDirPos);
158 
159     std::string outputPath = HMDFS_DIR + std::to_string(userId) + DATA_DIR + bundleName + "/" + relativePath;
160     std::string dir = outputPath.substr(0, outputPath.find_last_of('/'));
161 
162     ForceCreateDirectory(dir);
163     return outputPath;
164 }
165 
OnStart(const SystemAbilityOnDemandReason & startReason)166 void CloudSyncService::OnStart(const SystemAbilityOnDemandReason& startReason)
167 {
168     PreInit();
169     try {
170         PublishSA();
171         AddSystemAbilityListener(COMMON_EVENT_SERVICE_ID);
172         AddSystemAbilityListener(SOFTBUS_SERVER_SA_ID);
173         AddSystemAbilityListener(RES_SCHED_SYS_ABILITY_ID);
174     } catch (const exception &e) {
175         LOGE("%{public}s", e.what());
176     }
177     LOGI("Start service successfully");
178     Init();
179     LOGI("init service successfully");
180     system::SetParameter(CLOUD_FILE_SERVICE_SA_STATUS_FLAG, CLOUD_FILE_SERVICE_SA_START);
181     TaskStateManager::GetInstance().StartTask();
182     // 跟随进程生命周期
183     ffrt::submit([startReason, this]() {
184         this->HandleStartReason(startReason);
185     });
186 }
187 
OnActive(const SystemAbilityOnDemandReason & startReason)188 void CloudSyncService::OnActive(const SystemAbilityOnDemandReason& startReason)
189 {
190     LOGI("active service successfully");
191     system::SetParameter(CLOUD_FILE_SERVICE_SA_STATUS_FLAG, CLOUD_FILE_SERVICE_SA_START);
192     TaskStateManager::GetInstance().StartTask();
193     ffrt::submit([startReason, this]() {
194         this->HandleStartReason(startReason);
195     });
196 }
197 
OnStop()198 void CloudSyncService::OnStop()
199 {
200     LOGI("Stop finished successfully");
201 }
202 
HandleStartReason(const SystemAbilityOnDemandReason & startReason)203 void CloudSyncService::HandleStartReason(const SystemAbilityOnDemandReason& startReason)
204 {
205     string reason = startReason.GetName();
206     int32_t userId = 0;
207 
208     LOGI("Begin to start service reason: %{public}s", reason.c_str());
209 
210     if (reason == "usual.event.USER_UNLOCKED") {
211         return;
212     }
213 
214     if (dataSyncManager_->GetUserId(userId) != E_OK) {
215         return;
216     }
217 
218     if (reason == "usual.event.wifi.CONN_STATE") {
219         dataSyncManager_->TriggerRecoverySync(SyncTriggerType::NETWORK_AVAIL_TRIGGER);
220         dataSyncManager_->DownloadThumb();
221         dataSyncManager_->CacheVideo();
222     } else if (reason == "usual.event.BATTERY_OKAY") {
223         dataSyncManager_->TriggerRecoverySync(SyncTriggerType::BATTERY_OK_TRIGGER);
224     } else if (reason == "usual.event.SCREEN_OFF" || reason == "usual.event.POWER_CONNECTED") {
225         dataSyncManager_->DownloadThumb();
226         dataSyncManager_->CacheVideo();
227     }
228 
229     if (reason != "load") {
230         shared_ptr<CycleTaskRunner> taskRunner = make_shared<CycleTaskRunner>(dataSyncManager_);
231         taskRunner->StartTask();
232     }
233 }
234 
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)235 void CloudSyncService::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
236 {
237     LOGI("OnAddSystemAbility systemAbilityId:%{public}d added!", systemAbilityId);
238     if (systemAbilityId == COMMON_EVENT_SERVICE_ID) {
239         userStatusListener_->Start();
240         batteryStatusListener_->Start();
241         screenStatusListener_->Start();
242     } else if (systemAbilityId == SOFTBUS_SERVER_SA_ID) {
243         auto sessionManager = make_shared<SessionManager>();
244         sessionManager->Init();
245         userStatusListener_->AddObserver(sessionManager);
246         fileTransferManager_ = make_shared<FileTransferManager>(sessionManager);
247         fileTransferManager_->Init();
248     } else if (systemAbilityId == RES_SCHED_SYS_ABILITY_ID) {
249         SystemLoadStatus::InitSystemload(dataSyncManager_);
250     } else {
251         LOGE("unexpected");
252     }
253 }
254 
OnLoadSACompleteForRemote(const std::string & deviceId,int32_t systemAbilityId,const sptr<IRemoteObject> & remoteObject)255 void CloudSyncService::LoadRemoteSACallback::OnLoadSACompleteForRemote(const std::string &deviceId,
256                                                                        int32_t systemAbilityId,
257                                                                        const sptr<IRemoteObject> &remoteObject)
258 {
259     LOGI("Load CloudSync SA success,systemAbilityId:%{public}d, remoteObj result:%{public}s", systemAbilityId,
260          (remoteObject == nullptr ? "false" : "true"));
261     unique_lock<mutex> lock(loadRemoteSAMutex_);
262     if (remoteObject == nullptr) {
263         isLoadSuccess_.store(false);
264     } else {
265         isLoadSuccess_.store(true);
266         remoteObjectMap_[deviceId] = remoteObject;
267     }
268     proxyConVar_.notify_one();
269 }
270 
SetDeathRecipient(const sptr<IRemoteObject> & remoteObject)271 void CloudSyncService::SetDeathRecipient(const sptr<IRemoteObject> &remoteObject)
272 {
273     LOGD("set death recipient");
274     auto deathCallback = [this](const wptr<IRemoteObject> &obj) {
275         unique_lock<mutex> lock(loadRemoteSAMutex_);
276         for (auto it = remoteObjectMap_.begin(); it != remoteObjectMap_.end();) {
277             if (it->second.GetRefPtr() == obj.GetRefPtr()) {
278                 it = remoteObjectMap_.erase(it);
279                 LOGD("remote sa died");
280             } else {
281                 ++it;
282             }
283         }
284     };
285     deathRecipient_ = sptr(new SvcDeathRecipient(deathCallback));
286     remoteObject->AddDeathRecipient(deathRecipient_);
287 }
288 
LoadRemoteSA(const std::string & deviceId)289 int32_t CloudSyncService::LoadRemoteSA(const std::string &deviceId)
290 {
291     unique_lock<mutex> lock(loadRemoteSAMutex_);
292     auto iter = remoteObjectMap_.find(deviceId);
293     if (iter != remoteObjectMap_.end()) {
294         return E_OK;
295     }
296     auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
297     if (samgr == nullptr) {
298         LOGE("Samgr is nullptr");
299         return E_SA_LOAD_FAILED;
300     }
301     sptr<LoadRemoteSACallback> cloudSyncLoadCallback = new LoadRemoteSACallback();
302     if (cloudSyncLoadCallback == nullptr) {
303         LOGE("cloudSyncLoadCallback is nullptr");
304         return E_SA_LOAD_FAILED;
305     }
306     int32_t ret = samgr->LoadSystemAbility(FILEMANAGEMENT_CLOUD_SYNC_SERVICE_SA_ID, deviceId, cloudSyncLoadCallback);
307     if (ret != E_OK) {
308         LOGE("Failed to Load systemAbility, systemAbilityId:%{pulbic}d, ret code:%{pulbic}d",
309              FILEMANAGEMENT_CLOUD_SYNC_SERVICE_SA_ID, ret);
310         return E_SA_LOAD_FAILED;
311     }
312 
313     auto waitStatus = cloudSyncLoadCallback->proxyConVar_.wait_for(
314         lock, std::chrono::milliseconds(LOAD_SA_TIMEOUT_MS),
315         [cloudSyncLoadCallback]() { return cloudSyncLoadCallback->isLoadSuccess_.load(); });
316     if (!waitStatus) {
317         LOGE("Load CloudSynd SA timeout");
318         return E_SA_LOAD_FAILED;
319     }
320     SetDeathRecipient(remoteObjectMap_[deviceId]);
321     return E_OK;
322 }
323 
GetTargetBundleName(string & targetBundleName,string & callerBundleName)324 static int32_t GetTargetBundleName(string &targetBundleName, string &callerBundleName)
325 {
326     if (DfsuAccessTokenHelper::GetCallerBundleName(callerBundleName)) {
327         return E_INVAL_ARG;
328     }
329     if (targetBundleName == "") {
330         targetBundleName = callerBundleName;
331     }
332     if (targetBundleName != callerBundleName &&
333         !DfsuAccessTokenHelper::CheckCallerPermission(PERM_CLOUD_SYNC_MANAGER)) {
334         LOGE("permission denied: cloudfile_sync_manager");
335         return E_PERMISSION_DENIED;
336     }
337     return E_OK;
338 }
339 
UnRegisterCallbackInner(const string & bundleName)340 int32_t CloudSyncService::UnRegisterCallbackInner(const string &bundleName)
341 {
342     string targetBundleName = bundleName;
343     string callerBundleName = "";
344     int32_t ret = GetTargetBundleName(targetBundleName, callerBundleName);
345     if (ret != E_OK) {
346         LOGE("get bundle name failed: %{public}d", ret);
347         return ret;
348     }
349     dataSyncManager_->UnRegisterCloudSyncCallback(targetBundleName, callerBundleName);
350     return E_OK;
351 }
352 
RegisterCallbackInner(const sptr<IRemoteObject> & remoteObject,const string & bundleName)353 int32_t CloudSyncService::RegisterCallbackInner(const sptr<IRemoteObject> &remoteObject, const string &bundleName)
354 {
355     if (remoteObject == nullptr) {
356         LOGE("remoteObject is nullptr");
357         return E_INVAL_ARG;
358     }
359 
360     string targetBundleName = bundleName;
361     string callerBundleName = "";
362     int32_t ret = GetTargetBundleName(targetBundleName, callerBundleName);
363     if (ret != E_OK) {
364         LOGE("get bundle name failed: %{public}d", ret);
365         return ret;
366     }
367 
368     auto callback = iface_cast<ICloudSyncCallback>(remoteObject);
369     auto callerUserId = DfsuAccessTokenHelper::GetUserId();
370     dataSyncManager_->RegisterCloudSyncCallback(targetBundleName, callerBundleName, callerUserId, callback);
371     return E_OK;
372 }
373 
StartSyncInner(bool forceFlag,const string & bundleName)374 int32_t CloudSyncService::StartSyncInner(bool forceFlag, const string &bundleName)
375 {
376     string targetBundleName = bundleName;
377     string callerBundleName = "";
378     int32_t ret = GetTargetBundleName(targetBundleName, callerBundleName);
379     if (ret != E_OK) {
380         LOGE("get bundle name failed: %{public}d", ret);
381         return ret;
382     }
383     auto callerUserId = DfsuAccessTokenHelper::GetUserId();
384     return dataSyncManager_->TriggerStartSync(targetBundleName, callerUserId, forceFlag,
385         SyncTriggerType::APP_TRIGGER);
386 }
387 
TriggerSyncInner(const std::string & bundleName,const int32_t & userId)388 int32_t CloudSyncService::TriggerSyncInner(const std::string &bundleName, const int32_t &userId)
389 {
390     if (bundleName.empty() || userId < MIN_USER_ID) {
391         LOGE("Trigger sync parameter is invalid");
392         return E_INVAL_ARG;
393     }
394     return dataSyncManager_->TriggerStartSync(bundleName, userId, false,
395         SyncTriggerType::APP_TRIGGER);
396 }
397 
StopSyncInner(const string & bundleName,bool forceFlag)398 int32_t CloudSyncService::StopSyncInner(const string &bundleName, bool forceFlag)
399 {
400     string targetBundleName = bundleName;
401     string callerBundleName = "";
402     int32_t ret = GetTargetBundleName(targetBundleName, callerBundleName);
403     if (ret != E_OK) {
404         LOGE("get bundle name failed: %{public}d", ret);
405         return ret;
406     }
407     auto callerUserId = DfsuAccessTokenHelper::GetUserId();
408     return dataSyncManager_->TriggerStopSync(targetBundleName, callerUserId, forceFlag, SyncTriggerType::APP_TRIGGER);
409 }
410 
ResetCursor(const string & bundleName)411 int32_t CloudSyncService::ResetCursor(const string &bundleName)
412 {
413     string targetBundleName = bundleName;
414     string callerBundleName = "";
415     int32_t ret = GetTargetBundleName(targetBundleName, callerBundleName);
416     if (ret != E_OK) {
417         LOGE("get bundle name failed: %{public}d", ret);
418         return ret;
419     }
420     auto callerUserId = DfsuAccessTokenHelper::GetUserId();
421     return dataSyncManager_->ResetCursor(targetBundleName, callerUserId);
422 }
423 
GetSyncTimeInner(int64_t & syncTime,const string & bundleName)424 int32_t CloudSyncService::GetSyncTimeInner(int64_t &syncTime, const string &bundleName)
425 {
426     string targetBundleName = bundleName;
427     string callerBundleName = "";
428     int32_t ret = GetTargetBundleName(targetBundleName, callerBundleName);
429     if (ret != E_OK) {
430         LOGE("get bundle name failed: %{public}d", ret);
431         return ret;
432     }
433     auto callerUserId = DfsuAccessTokenHelper::GetUserId();
434     return DataSyncerRdbStore::GetInstance().GetLastSyncTime(callerUserId, targetBundleName, syncTime);
435 }
436 
CleanCacheInner(const std::string & uri)437 int32_t CloudSyncService::CleanCacheInner(const std::string &uri)
438 {
439     string bundleName;
440     if (DfsuAccessTokenHelper::GetCallerBundleName(bundleName)) {
441         return E_INVAL_ARG;
442     }
443     auto callerUserId = DfsuAccessTokenHelper::GetUserId();
444     return dataSyncManager_->CleanCache(bundleName, callerUserId, uri);
445 }
446 
ChangeAppSwitch(const std::string & accoutId,const std::string & bundleName,bool status)447 int32_t CloudSyncService::ChangeAppSwitch(const std::string &accoutId, const std::string &bundleName, bool status)
448 {
449     auto callerUserId = DfsuAccessTokenHelper::GetUserId();
450 
451     /* update app switch status */
452     auto ret = CloudStatus::ChangeAppSwitch(bundleName, callerUserId, status);
453     if (ret != E_OK) {
454         return ret;
455     }
456     if (status) {
457         return dataSyncManager_->TriggerStartSync(bundleName, callerUserId, false, SyncTriggerType::CLOUD_TRIGGER);
458     } else {
459         system::SetParameter(CLOUDSYNC_STATUS_KEY, CLOUDSYNC_STATUS_SWITCHOFF);
460         return dataSyncManager_->TriggerStopSync(bundleName, callerUserId, false, SyncTriggerType::CLOUD_TRIGGER);
461     }
462 }
463 
NotifyDataChange(const std::string & accoutId,const std::string & bundleName)464 int32_t CloudSyncService::NotifyDataChange(const std::string &accoutId, const std::string &bundleName)
465 {
466     auto callerUserId = DfsuAccessTokenHelper::GetUserId();
467     return dataSyncManager_->TriggerStartSync(bundleName, callerUserId, false, SyncTriggerType::CLOUD_TRIGGER);
468 }
469 
NotifyEventChange(int32_t userId,const std::string & eventId,const std::string & extraData)470 int32_t CloudSyncService::NotifyEventChange(int32_t userId, const std::string &eventId, const std::string &extraData)
471 {
472     auto instance = CloudFile::CloudFileKit::GetInstance();
473     if (instance == nullptr) {
474         LOGE("get cloud file helper instance failed");
475         return E_NULLPTR;
476     }
477 
478     string appBundleName;
479     string prepareTraceId;
480     auto ret = instance->ResolveNotificationEvent(userId, extraData, appBundleName, prepareTraceId);
481     if (ret != E_OK) {
482         LOGE("ResolveNotificationEvent failed, ret:%{public}d", ret);
483         return E_CLOUD_SDK;
484     }
485 
486     return dataSyncManager_->TriggerStartSync(appBundleName, userId, false,
487         SyncTriggerType::CLOUD_TRIGGER, prepareTraceId);
488 }
489 
DisableCloud(const std::string & accoutId)490 int32_t CloudSyncService::DisableCloud(const std::string &accoutId)
491 {
492     auto callerUserId = DfsuAccessTokenHelper::GetUserId();
493     system::SetParameter(CLOUDSYNC_STATUS_KEY, CLOUDSYNC_STATUS_LOGOUT);
494     return dataSyncManager_->DisableCloud(callerUserId);
495 }
496 
EnableCloud(const std::string & accoutId,const SwitchDataObj & switchData)497 int32_t CloudSyncService::EnableCloud(const std::string &accoutId, const SwitchDataObj &switchData)
498 {
499     return E_OK;
500 }
501 
Clean(const std::string & accountId,const CleanOptions & cleanOptions)502 int32_t CloudSyncService::Clean(const std::string &accountId, const CleanOptions &cleanOptions)
503 {
504     for (auto &iter : cleanOptions.appActionsData) {
505         LOGD("Clean key is: %s, value is: %d", iter.first.c_str(), iter.second);
506     }
507 
508     MetaFileMgr::GetInstance().ClearAll();
509     MetaFileMgr::GetInstance().CloudDiskClearAll();
510     auto callerUserId = DfsuAccessTokenHelper::GetUserId();
511     LOGI("Clean callerUserId is: %{public}d", callerUserId);
512     for (auto iter = cleanOptions.appActionsData.begin(); iter != cleanOptions.appActionsData.end(); ++iter) {
513         dataSyncManager_->CleanCloudFile(callerUserId, iter->first, iter->second);
514     }
515 
516     return E_OK;
517 }
StartFileCache(const std::vector<std::string> & uriVec,int64_t & downloadId,std::bitset<FIELD_KEY_MAX_SIZE> fieldkey,bool isCallbackValid,const sptr<IRemoteObject> & downloadCallback)518 int32_t CloudSyncService::StartFileCache(const std::vector<std::string> &uriVec,
519                                          int64_t &downloadId, std::bitset<FIELD_KEY_MAX_SIZE> fieldkey,
520                                          bool isCallbackValid,
521                                          const sptr<IRemoteObject> &downloadCallback)
522 {
523     BundleNameUserInfo bundleNameUserInfo;
524     int ret = GetBundleNameUserInfo(bundleNameUserInfo);
525     if (ret != E_OK) {
526         LOGE("GetBundleNameUserInfo failed.");
527         return ret;
528     }
529     LOGI("start StartFileCache");
530     auto downloadCb = iface_cast<ICloudDownloadCallback>(downloadCallback);
531     return dataSyncManager_->StartDownloadFile(bundleNameUserInfo, uriVec, downloadId, fieldkey, downloadCb);
532 }
533 
StartDownloadFile(const std::string & path)534 int32_t CloudSyncService::StartDownloadFile(const std::string &path)
535 {
536     BundleNameUserInfo bundleNameUserInfo;
537     int ret = GetBundleNameUserInfo(bundleNameUserInfo);
538     if (ret != E_OK) {
539         return ret;
540     }
541     std::vector<std::string> pathVec;
542     pathVec.push_back(path);
543     int64_t downloadId = 0;
544     LOGI("start StartDownloadFile");
545     return dataSyncManager_->StartDownloadFile(bundleNameUserInfo, pathVec, downloadId,
546                                                CloudSync::FIELDKEY_CONTENT, nullptr);
547 }
548 
StopDownloadFile(const std::string & path,bool needClean)549 int32_t CloudSyncService::StopDownloadFile(const std::string &path, bool needClean)
550 {
551     BundleNameUserInfo bundleNameUserInfo;
552     int ret = GetBundleNameUserInfo(bundleNameUserInfo);
553     if (ret != E_OK) {
554         return ret;
555     }
556     LOGI("start StopDownloadFile");
557     return dataSyncManager_->StopDownloadFile(bundleNameUserInfo, path, needClean);
558 }
559 
StopFileCache(const int64_t & downloadId,bool needClean)560 int32_t CloudSyncService::StopFileCache(const int64_t &downloadId,  bool needClean)
561 {
562     BundleNameUserInfo bundleNameUserInfo;
563     int ret = GetBundleNameUserInfo(bundleNameUserInfo);
564     if (ret != E_OK) {
565         return ret;
566     }
567     LOGI("start StopFileCache");
568     return dataSyncManager_->StopFileCache(bundleNameUserInfo, downloadId, needClean);
569 }
570 
RegisterDownloadFileCallback(const sptr<IRemoteObject> & downloadCallback)571 int32_t CloudSyncService::RegisterDownloadFileCallback(const sptr<IRemoteObject> &downloadCallback)
572 {
573     BundleNameUserInfo bundleNameUserInfo;
574     int ret = GetBundleNameUserInfo(bundleNameUserInfo);
575     if (ret != E_OK) {
576         return ret;
577     }
578     auto downloadCb = iface_cast<ICloudDownloadCallback>(downloadCallback);
579     LOGI("start RegisterDownloadFileCallback");
580     return dataSyncManager_->RegisterDownloadFileCallback(bundleNameUserInfo, downloadCb);
581 }
582 
UnregisterDownloadFileCallback()583 int32_t CloudSyncService::UnregisterDownloadFileCallback()
584 {
585     BundleNameUserInfo bundleNameUserInfo;
586     int ret = GetBundleNameUserInfo(bundleNameUserInfo);
587     if (ret != E_OK) {
588         return ret;
589     }
590     LOGI("start UnregisterDownloadFileCallback");
591     return dataSyncManager_->UnregisterDownloadFileCallback(bundleNameUserInfo);
592 }
593 
UploadAsset(const int32_t userId,const std::string & request,std::string & result)594 int32_t CloudSyncService::UploadAsset(const int32_t userId, const std::string &request, std::string &result)
595 {
596     auto instance = CloudFile::CloudFileKit::GetInstance();
597     if (instance == nullptr) {
598         LOGE("get cloud file helper instance failed");
599         return E_NULLPTR;
600     }
601 
602     string bundleName("distributeddata");
603     TaskStateManager::GetInstance().StartTask(bundleName, TaskType::UPLOAD_ASSET_TASK);
604     auto ret = instance->OnUploadAsset(userId, request, result);
605     TaskStateManager::GetInstance().CompleteTask(bundleName, TaskType::UPLOAD_ASSET_TASK);
606     return ret;
607 }
608 
DownloadFile(const int32_t userId,const std::string & bundleName,AssetInfoObj & assetInfoObj)609 int32_t CloudSyncService::DownloadFile(const int32_t userId, const std::string &bundleName, AssetInfoObj &assetInfoObj)
610 {
611     auto instance = CloudFile::CloudFileKit::GetInstance();
612     if (instance == nullptr) {
613         LOGE("get cloud file helper instance failed");
614         return E_NULLPTR;
615     }
616 
617     auto assetsDownloader = instance->GetCloudAssetsDownloader(userId, bundleName);
618     if (assetsDownloader == nullptr) {
619         LOGE("get asset downloader failed");
620         return E_NULLPTR;
621     }
622 
623     Asset asset;
624     asset.assetName = assetInfoObj.assetName;
625 
626     asset.uri = GetHmdfsPath(assetInfoObj.uri, userId);
627     if (asset.uri.empty()) {
628         LOGE("fail to get download path from %{public}s", GetAnonyString(assetInfoObj.uri).c_str());
629         return E_INVAL_ARG;
630     }
631 
632     // Not to pass the assetinfo.fieldkey
633     DownloadAssetInfo assetsToDownload{assetInfoObj.recordType, assetInfoObj.recordId, {}, asset, {}};
634     TaskStateManager::GetInstance().StartTask(bundleName, TaskType::DOWNLOAD_ASSET_TASK);
635     auto ret = assetsDownloader->DownloadAssets(assetsToDownload);
636     TaskStateManager::GetInstance().CompleteTask(bundleName, TaskType::DOWNLOAD_ASSET_TASK);
637     return ret;
638 }
639 
DownloadFiles(const int32_t userId,const std::string & bundleName,const std::vector<AssetInfoObj> & assetInfoObj,std::vector<bool> & assetResultMap)640 int32_t CloudSyncService::DownloadFiles(const int32_t userId, const std::string &bundleName,
641     const std::vector<AssetInfoObj> &assetInfoObj, std::vector<bool> &assetResultMap)
642 {
643     auto instance = CloudFile::CloudFileKit::GetInstance();
644     if (instance == nullptr) {
645         LOGE("get cloud file helper instance failed");
646         return E_NULLPTR;
647     }
648 
649     auto assetsDownloader = instance->GetCloudAssetsDownloader(userId, bundleName);
650     if (assetsDownloader == nullptr) {
651         LOGE("get asset downloader failed");
652         return E_NULLPTR;
653     }
654 
655     std::vector<DownloadAssetInfo> assetsToDownload;
656     for (const auto &obj: assetInfoObj) {
657         Asset asset;
658         asset.assetName = obj.assetName;
659         asset.uri = GetHmdfsPath(obj.uri, userId);
660         if (asset.uri.empty()) {
661             LOGE("fail to get download path from %{private}s", GetAnonyString(obj.uri).c_str());
662             return E_INVAL_ARG;
663         }
664         DownloadAssetInfo assetToDownload{obj.recordType, obj.recordId, {}, asset, {}};
665         assetsToDownload.emplace_back(assetToDownload);
666     }
667 
668     TaskStateManager::GetInstance().StartTask(bundleName, TaskType::DOWNLOAD_ASSET_TASK);
669     auto ret = assetsDownloader->DownloadAssets(assetsToDownload, assetResultMap);
670     TaskStateManager::GetInstance().CompleteTask(bundleName, TaskType::DOWNLOAD_ASSET_TASK);
671     return ret;
672 }
673 
DownloadAsset(const uint64_t taskId,const int32_t userId,const std::string & bundleName,const std::string & networkId,AssetInfoObj & assetInfoObj)674 int32_t CloudSyncService::DownloadAsset(const uint64_t taskId,
675                                         const int32_t userId,
676                                         const std::string &bundleName,
677                                         const std::string &networkId,
678                                         AssetInfoObj &assetInfoObj)
679 {
680     if (networkId == "edge2cloud") {
681         LOGE("now not support");
682         return E_INVAL_ARG;
683     }
684     // Load sa for remote device
685     if (LoadRemoteSA(networkId) != E_OK) { // maybe need to convert deviceId
686         return E_SA_LOAD_FAILED;
687     }
688 
689     string uri = assetInfoObj.uri;
690     fileTransferManager_->DownloadFileFromRemoteDevice(networkId, userId, taskId, uri);
691     return E_OK;
692 }
693 
RegisterDownloadAssetCallback(const sptr<IRemoteObject> & remoteObject)694 int32_t CloudSyncService::RegisterDownloadAssetCallback(const sptr<IRemoteObject> &remoteObject)
695 {
696     if (remoteObject == nullptr) {
697         LOGE("remoteObject is nullptr");
698         return E_INVAL_ARG;
699     }
700     auto callback = iface_cast<IDownloadAssetCallback>(remoteObject);
701     DownloadAssetCallbackManager::GetInstance().AddCallback(callback);
702     return E_OK;
703 }
704 
DeleteAsset(const int32_t userId,const std::string & uri)705 int32_t CloudSyncService::DeleteAsset(const int32_t userId, const std::string &uri)
706 {
707     std::string physicalPath = "";
708     int ret = AppFileService::SandboxHelper::GetPhysicalPath(uri, std::to_string(userId), physicalPath);
709     if (ret != 0) {
710         LOGE("Get physical path failed with %{public}d", ret);
711         return E_GET_PHYSICAL_PATH_FAILED;
712     }
713 
714     LOGD("delete assert, path %{public}s", GetAnonyString(physicalPath).c_str());
715 
716     ret = unlink(physicalPath.c_str());
717     if (ret != 0) {
718         LOGE("fail to delete asset, errno %{public}d", errno);
719         return E_DELETE_FAILED;
720     }
721     return E_OK;
722 }
723 } // namespace OHOS::FileManagement::CloudSync
724