• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <memory>
18 
19 #include "system_ability_definition.h"
20 
21 #include "dfs_error.h"
22 #include "dfsu_access_token_helper.h"
23 #include "ipc/cloud_sync_callback_manager.h"
24 #include "meta_file.h"
25 #include "sync_rule/battery_status.h"
26 #include "sync_rule/cloud_status.h"
27 #include "sync_rule/net_conn_callback_observer.h"
28 #include "sync_rule/network_status.h"
29 #include "utils_log.h"
30 #include "directory_ex.h"
31 #include "sdk_helper.h"
32 
33 namespace OHOS::FileManagement::CloudSync {
34 using namespace std;
35 using namespace OHOS;
36 
37 const string GALLERY_BUNDLE_NAME = "com.ohos.photos";
38 
39 REGISTER_SYSTEM_ABILITY_BY_ID(CloudSyncService, FILEMANAGEMENT_CLOUD_SYNC_SERVICE_SA_ID, false);
40 
CloudSyncService(int32_t saID,bool runOnCreate)41 CloudSyncService::CloudSyncService(int32_t saID, bool runOnCreate) : SystemAbility(saID, runOnCreate)
42 {
43     dataSyncManager_ = make_shared<DataSyncManager>();
44     batteryStatusListener_ = make_shared<BatteryStatusListener>(dataSyncManager_);
45 }
46 
PublishSA()47 void CloudSyncService::PublishSA()
48 {
49     LOGI("Begin to init");
50     if (!SystemAbility::Publish(this)) {
51         throw runtime_error(" Failed to publish the daemon");
52     }
53     LOGI("Init finished successfully");
54 }
55 
Init()56 void CloudSyncService::Init()
57 {
58     NetworkStatus::InitNetwork(dataSyncManager_);
59     /* Get Init Charging status */
60     BatteryStatus::GetInitChargingStatus();
61 }
62 
GetHmdfsPath(const std::string & uri,int32_t userId)63 std::string CloudSyncService::GetHmdfsPath(const std::string &uri, int32_t userId)
64 {
65     const std::string HMDFS_DIR = "/mnt/hmdfs/";
66     const std::string DATA_DIR = "/account/device_view/local/data/";
67     const std::string FILE_DIR = "data/storage/el2/distributedfiles/";
68     const std::string URI_PREFIX = "://";
69     if (uri.empty()) {
70         return "";
71     }
72 
73     std::string bundleName;
74     size_t uriPrefixPos = uri.find(URI_PREFIX);
75     if (uriPrefixPos == std::string::npos) {
76         return "";
77     }
78     uriPrefixPos += URI_PREFIX.length();
79     size_t bundleNameEndPos = uri.find('/', uriPrefixPos);
80     if (bundleNameEndPos == std::string::npos) {
81         return "";
82     }
83     bundleName = uri.substr(uriPrefixPos, bundleNameEndPos - uriPrefixPos);
84 
85     std::string relativePath;
86     size_t fileDirPos = uri.find(FILE_DIR);
87     if (fileDirPos == std::string::npos) {
88         return "";
89     }
90     fileDirPos += FILE_DIR.length();
91     relativePath = uri.substr(fileDirPos);
92 
93     std::string outputPath = HMDFS_DIR + std::to_string(userId) + DATA_DIR + bundleName + "/" + relativePath;
94     std::string dir = outputPath.substr(0, outputPath.find_last_of('/'));
95 
96     ForceCreateDirectory(dir);
97     return outputPath;
98 }
99 
OnStart()100 void CloudSyncService::OnStart()
101 {
102     Init();
103     LOGI("Begin to start service");
104     try {
105         PublishSA();
106         AddSystemAbilityListener(COMMON_EVENT_SERVICE_ID);
107     } catch (const exception &e) {
108         LOGE("%{public}s", e.what());
109     }
110     LOGI("Start service successfully");
111 }
112 
OnStop()113 void CloudSyncService::OnStop()
114 {
115     LOGI("Stop finished successfully");
116 }
117 
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)118 void CloudSyncService::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
119 {
120     LOGI("OnAddSystemAbility systemAbilityId:%{public}d added!", systemAbilityId);
121     batteryStatusListener_->Start();
122 }
123 
UnRegisterCallbackInner()124 int32_t CloudSyncService::UnRegisterCallbackInner()
125 {
126     string bundleName;
127     if (DfsuAccessTokenHelper::GetCallerBundleName(bundleName)) {
128         return E_INVAL_ARG;
129     }
130 
131     CloudSyncCallbackManager::GetInstance().RemoveCallback(bundleName);
132     return E_OK;
133 }
134 
RegisterCallbackInner(const sptr<IRemoteObject> & remoteObject)135 int32_t CloudSyncService::RegisterCallbackInner(const sptr<IRemoteObject> &remoteObject)
136 {
137     if (remoteObject == nullptr) {
138         LOGE("remoteObject is nullptr");
139         return E_INVAL_ARG;
140     }
141 
142     string bundleName;
143     if (DfsuAccessTokenHelper::GetCallerBundleName(bundleName)) {
144         return E_INVAL_ARG;
145     }
146 
147     auto callback = iface_cast<ICloudSyncCallback>(remoteObject);
148     auto callerUserId = DfsuAccessTokenHelper::GetUserId();
149     CloudSyncCallbackManager::GetInstance().AddCallback(bundleName, callerUserId, callback);
150     dataSyncManager_->RegisterCloudSyncCallback(GALLERY_BUNDLE_NAME, callerUserId);
151     return E_OK;
152 }
153 
StartSyncInner(bool forceFlag)154 int32_t CloudSyncService::StartSyncInner(bool forceFlag)
155 {
156     auto callerUserId = DfsuAccessTokenHelper::GetUserId();
157     return dataSyncManager_->TriggerStartSync(GALLERY_BUNDLE_NAME, callerUserId, forceFlag,
158         SyncTriggerType::APP_TRIGGER);
159 }
160 
StopSyncInner()161 int32_t CloudSyncService::StopSyncInner()
162 {
163     auto callerUserId = DfsuAccessTokenHelper::GetUserId();
164     return dataSyncManager_->TriggerStopSync(GALLERY_BUNDLE_NAME, callerUserId, SyncTriggerType::APP_TRIGGER);
165 }
166 
ChangeAppSwitch(const std::string & accoutId,const std::string & bundleName,bool status)167 int32_t CloudSyncService::ChangeAppSwitch(const std::string &accoutId, const std::string &bundleName, bool status)
168 {
169     auto callerUserId = DfsuAccessTokenHelper::GetUserId();
170 
171     /* update app switch status */
172     auto ret = CloudStatus::ChangeAppSwitch(bundleName, callerUserId, status);
173     if (ret != E_OK) {
174         return ret;
175     }
176 
177     if (status) {
178         return dataSyncManager_->TriggerStartSync(bundleName, callerUserId, false, SyncTriggerType::CLOUD_TRIGGER);
179     }
180     return dataSyncManager_->TriggerStopSync(bundleName, callerUserId, SyncTriggerType::CLOUD_TRIGGER);
181 }
182 
NotifyDataChange(const std::string & accoutId,const std::string & bundleName)183 int32_t CloudSyncService::NotifyDataChange(const std::string &accoutId, const std::string &bundleName)
184 {
185     auto callerUserId = DfsuAccessTokenHelper::GetUserId();
186     return dataSyncManager_->TriggerStartSync(bundleName, callerUserId, false, SyncTriggerType::CLOUD_TRIGGER);
187 }
188 
DisableCloud(const std::string & accoutId)189 int32_t CloudSyncService::DisableCloud(const std::string &accoutId)
190 {
191     return E_OK;
192 }
193 
EnableCloud(const std::string & accoutId,const SwitchDataObj & switchData)194 int32_t CloudSyncService::EnableCloud(const std::string &accoutId, const SwitchDataObj &switchData)
195 {
196     return E_OK;
197 }
198 
Clean(const std::string & accountId,const CleanOptions & cleanOptions)199 int32_t CloudSyncService::Clean(const std::string &accountId, const CleanOptions &cleanOptions)
200 {
201     LOGD("Clean accountId is: %{public}s", accountId.c_str());
202     for (auto &iter : cleanOptions.appActionsData) {
203         LOGD("Clean key is: %s, value is: %d", iter.first.c_str(), iter.second);
204     }
205 
206     MetaFileMgr::GetInstance().ClearAll();
207     auto callerUserId = DfsuAccessTokenHelper::GetUserId();
208     LOGD("Clean callerUserId is: %{public}d", callerUserId);
209     for (auto iter = cleanOptions.appActionsData.begin(); iter != cleanOptions.appActionsData.end(); ++iter) {
210         dataSyncManager_->CleanCloudFile(callerUserId, iter->first, iter->second);
211     }
212 
213     return E_OK;
214 }
215 
216 constexpr int TEST_MAIN_USR_ID = 100;
StartDownloadFile(const std::string & path)217 int32_t CloudSyncService::StartDownloadFile(const std::string &path)
218 {
219     auto callerUserId = DfsuAccessTokenHelper::GetUserId();
220     LOGI("start StartDownloadFile");
221     if (callerUserId == 0) {
222         callerUserId = TEST_MAIN_USR_ID; // for root user change id to main user for test
223     }
224     return dataSyncManager_->StartDownloadFile(GALLERY_BUNDLE_NAME, callerUserId, path);
225 }
226 
StopDownloadFile(const std::string & path)227 int32_t CloudSyncService::StopDownloadFile(const std::string &path)
228 {
229     auto callerUserId = DfsuAccessTokenHelper::GetUserId();
230     LOGI("start StopDownloadFile");
231     if (callerUserId == 0) {
232         callerUserId = TEST_MAIN_USR_ID; // for root user change id to main user for test
233     }
234     return dataSyncManager_->StopDownloadFile(GALLERY_BUNDLE_NAME, callerUserId, path);
235 }
236 
RegisterDownloadFileCallback(const sptr<IRemoteObject> & downloadCallback)237 int32_t CloudSyncService::RegisterDownloadFileCallback(const sptr<IRemoteObject> &downloadCallback)
238 {
239     auto callerUserId = DfsuAccessTokenHelper::GetUserId();
240     auto downloadCb = iface_cast<ICloudDownloadCallback>(downloadCallback);
241     LOGI("start RegisterDownloadFileCallback");
242     if (callerUserId == 0) {
243         callerUserId = TEST_MAIN_USR_ID; // for root user change id to main user for test
244     }
245     return dataSyncManager_->RegisterDownloadFileCallback(GALLERY_BUNDLE_NAME, callerUserId, downloadCb);
246 }
247 
UnregisterDownloadFileCallback()248 int32_t CloudSyncService::UnregisterDownloadFileCallback()
249 {
250     auto callerUserId = DfsuAccessTokenHelper::GetUserId();
251     LOGI("start UnregisterDownloadFileCallback");
252     if (callerUserId == 0) {
253         callerUserId = TEST_MAIN_USR_ID; // for root user change id to main user for test
254     }
255     return dataSyncManager_->UnregisterDownloadFileCallback(GALLERY_BUNDLE_NAME, callerUserId);
256 }
257 
UploadAsset(const int32_t userId,const std::string & request,std::string & result)258 int32_t CloudSyncService::UploadAsset(const int32_t userId, const std::string &request, std::string &result)
259 {
260     auto driveKit = DriveKit::DriveKitNative::GetInstance(userId);
261     if (driveKit == nullptr) {
262         LOGE("uploadAsset get drive kit instance err");
263         return E_CLOUD_SDK;
264     }
265     return driveKit->OnUploadAsset(request, result);
266 }
267 
DownloadFile(const int32_t userId,const std::string & bundleName,AssetInfoObj & assetInfoObj)268 int32_t CloudSyncService::DownloadFile(const int32_t userId, const std::string &bundleName, AssetInfoObj &assetInfoObj)
269 {
270     auto sdkHelper = std::make_shared<SdkHelper>();
271     auto ret = sdkHelper->Init(userId, bundleName);
272     if (ret != E_OK) {
273         LOGE("get sdk helper err %{public}d", ret);
274         return ret;
275     }
276 
277     DriveKit::DKAsset asset;
278     asset.assetName = assetInfoObj.assetName;
279 
280     asset.uri = GetHmdfsPath(assetInfoObj.uri, userId);
281     if (asset.uri.empty()) {
282         LOGE("fail to get download path from %{public}s", assetInfoObj.uri.c_str());
283         return E_INVAL_ARG;
284     }
285 
286     // Not to pass the assetinfo.fieldkey
287     DriveKit::DKDownloadAsset assetsToDownload{assetInfoObj.recordType, assetInfoObj.recordId, {}, asset, {}};
288     return sdkHelper->DownloadAssets(assetsToDownload);
289 }
290 } // namespace OHOS::FileManagement::CloudSync
291