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
16 #include "data_sync/data_sync_manager.h"
17
18 #include <thread>
19 #include <vector>
20 #include <regex>
21
22 #include "cloud_disk_data_syncer.h"
23 #include "data_syncer_rdb_col.h"
24 #include "data_syncer_rdb_store.h"
25 #include "data_sync_const.h"
26 #include "dfs_error.h"
27 #include "gallery_data_syncer.h"
28 #include "ipc/cloud_sync_callback_manager.h"
29 #include "sdk_helper.h"
30 #include "sync_rule/battery_status.h"
31 #include "sync_rule/cloud_status.h"
32 #include "sync_rule/network_status.h"
33 #include "utils_log.h"
34 #include "os_account_manager.h"
35 #include "rdb_sql_utils.h"
36 #include "rdb_store_config.h"
37
38 namespace OHOS::FileManagement::CloudSync {
39 using namespace std;
40
TriggerStartSync(const std::string & bundleName,const int32_t userId,bool forceFlag,SyncTriggerType triggerType)41 int32_t DataSyncManager::TriggerStartSync(const std::string &bundleName,
42 const int32_t userId,
43 bool forceFlag,
44 SyncTriggerType triggerType)
45 {
46 auto dataSyncer = GetDataSyncer(bundleName, userId);
47 if (!dataSyncer) {
48 LOGE("Get dataSyncer failed, bundleName: %{private}s", bundleName.c_str());
49 return E_INVAL_ARG;
50 }
51
52 if (NetworkStatus::GetNetConnStatus() == NetworkStatus::NetConnStatus::NO_NETWORK) {
53 LOGE("network is not available");
54 dataSyncer->UpdateErrorCode(E_SYNC_FAILED_NETWORK_NOT_AVAILABLE);
55 return E_SYNC_FAILED_NETWORK_NOT_AVAILABLE;
56 }
57
58 auto ret = InitSdk(userId, bundleName, dataSyncer);
59 if (ret != E_OK) {
60 return ret;
61 }
62 ret = IsSkipSync(bundleName, userId);
63 if (ret != E_OK) {
64 return ret;
65 }
66
67 std::thread([dataSyncer, forceFlag, triggerType]() { dataSyncer->StartSync(forceFlag, triggerType); }).detach();
68
69 return E_OK;
70 }
71
TriggerStopSync(const std::string & bundleName,const int32_t userId,SyncTriggerType triggerType)72 int32_t DataSyncManager::TriggerStopSync(const std::string &bundleName,
73 const int32_t userId,
74 SyncTriggerType triggerType)
75 {
76 auto dataSyncer = GetDataSyncer(bundleName, userId);
77 if (!dataSyncer) {
78 LOGE("Get dataSyncer failed, bundleName: %{private}s", bundleName.c_str());
79 return E_INVAL_ARG;
80 }
81
82 auto ret = InitSdk(userId, bundleName, dataSyncer);
83 if (ret != E_OK) {
84 return ret;
85 }
86 std::thread([dataSyncer, triggerType]() { dataSyncer->StopSync(triggerType); }).detach();
87 return E_OK;
88 }
89
RegisterCloudSyncCallback(const std::string & bundleName,const int32_t userId)90 void DataSyncManager::RegisterCloudSyncCallback(const std::string &bundleName, const int32_t userId)
91 {
92 auto dataSyncer = GetDataSyncer(bundleName, userId);
93 if (!dataSyncer) {
94 LOGE("Get dataSyncer failed, bundleName: %{private}s", bundleName.c_str());
95 return;
96 }
97
98 /* notify app current sync state */
99 dataSyncer->NotifyCurrentSyncState();
100 }
101
StartDownloadFile(const std::string & bundleName,const int32_t userId,const std::string path)102 int32_t DataSyncManager::StartDownloadFile(const std::string &bundleName, const int32_t userId, const std::string path)
103 {
104 auto dataSyncer = GetDataSyncer(bundleName, userId);
105 if (!dataSyncer) {
106 LOGE("Get dataSyncer failed, bundleName: %{private}s", bundleName.c_str());
107 return E_INVAL_ARG;
108 }
109 auto ret = InitSdk(userId, bundleName, dataSyncer);
110 if (ret != E_OK) {
111 return ret;
112 }
113 return dataSyncer->StartDownloadFile(path, userId);
114 }
115
StopDownloadFile(const std::string & bundleName,const int32_t userId,const std::string path)116 int32_t DataSyncManager::StopDownloadFile(const std::string &bundleName, const int32_t userId, const std::string path)
117 {
118 auto dataSyncer = GetDataSyncer(bundleName, userId);
119 if (!dataSyncer) {
120 LOGE("Get dataSyncer failed, bundleName: %{private}s", bundleName.c_str());
121 return E_INVAL_ARG;
122 }
123 auto ret = InitSdk(userId, bundleName, dataSyncer);
124 if (ret != E_OK) {
125 return ret;
126 }
127 return dataSyncer->StopDownloadFile(path, userId);
128 }
129
RegisterDownloadFileCallback(const std::string & bundleName,const int32_t userId,const sptr<ICloudDownloadCallback> & downloadCallback)130 int32_t DataSyncManager::RegisterDownloadFileCallback(const std::string &bundleName,
131 const int32_t userId,
132 const sptr<ICloudDownloadCallback>& downloadCallback)
133 {
134 auto dataSyncer = GetDataSyncer(bundleName, userId);
135 if (!dataSyncer) {
136 LOGE("Get dataSyncer failed, bundleName: %{private}s", bundleName.c_str());
137 return E_INVAL_ARG;
138 }
139 std::thread([dataSyncer, userId, downloadCallback]() {
140 dataSyncer->RegisterDownloadFileCallback(userId, downloadCallback);
141 }).detach();
142 return E_OK;
143 }
144
UnregisterDownloadFileCallback(const std::string & bundleName,const int32_t userId)145 int32_t DataSyncManager::UnregisterDownloadFileCallback(const std::string &bundleName,
146 const int32_t userId)
147 {
148 auto dataSyncer = GetDataSyncer(bundleName, userId);
149 if (!dataSyncer) {
150 LOGE("Get dataSyncer failed, bundleName: %{private}s", bundleName.c_str());
151 return E_INVAL_ARG;
152 }
153 std::thread([dataSyncer, userId]() { dataSyncer->UnregisterDownloadFileCallback(userId); }).detach();
154 return E_OK;
155 }
156
IsUserVerified(const int32_t userId)157 int32_t DataSyncManager::IsUserVerified(const int32_t userId)
158 {
159 bool isVerified = false;
160 if (AccountSA::OsAccountManager::IsOsAccountVerified(userId, isVerified) != E_OK) {
161 LOGE("check user verified failed");
162 return E_OSACCOUNT;
163 }
164 if (!isVerified) {
165 LOGE("user is locked");
166 return E_USER_LOCKED;
167 }
168 return E_OK;
169 }
170
TriggerRecoverySync(SyncTriggerType triggerType)171 int32_t DataSyncManager::TriggerRecoverySync(SyncTriggerType triggerType)
172 {
173 RETURN_ON_ERR(GetUserId(currentUserId_));
174 map<string, DataSyncerInfo> dataSyncerInfoMaps;
175 GetAllDataSyncerInfo(currentUserId_, dataSyncerInfoMaps);
176
177 if (dataSyncerInfoMaps.size() == 0) {
178 LOGI("not need to trigger sync");
179 return E_OK;
180 }
181
182 int32_t ret = E_OK;
183 for (const auto &iter : dataSyncerInfoMaps) {
184 auto &bundleName = iter.first;
185 if (triggerType == SyncTriggerType::NETWORK_AVAIL_TRIGGER) {
186 auto &dataSyncerInfo = iter.second;
187 auto dataSyncer = GetDataSyncer(bundleName, currentUserId_);
188 if (!dataSyncer) {
189 LOGE(" Clean Get dataSyncer failed, bundleName: %{private}s", bundleName.c_str());
190 continue;
191 }
192 if ((dataSyncerInfo.syncState != SyncState::SYNC_FAILED) &&
193 (dataSyncer->GetErrorType() != ErrorType::NETWORK_UNAVAILABLE)) {
194 LOGI("last sync is ok, no need trigger sync, bundleName:%{public}s, syncState:%{public}d",
195 bundleName.c_str(), static_cast<int32_t>(dataSyncerInfo.syncState));
196 continue;
197 }
198 }
199 ret = TriggerStartSync(bundleName, currentUserId_, false, triggerType);
200 if (ret) {
201 LOGE("trigger sync failed, ret = %{public}d, bundleName = %{public}s", ret, bundleName.c_str());
202 }
203 }
204 return ret;
205 }
206
GetDataSyncer(const std::string & bundle,const int32_t userId)207 std::shared_ptr<DataSyncer> DataSyncManager::GetDataSyncer(const std::string &bundle, const int32_t userId)
208 {
209 std::lock_guard<std::mutex> lck(dataSyncMutex_);
210 currentUserId_ = userId;
211 string bundleName;
212 Convert2BundleName(bundle, bundleName);
213 string key = bundleName + to_string(userId);
214 std::shared_ptr<DataSyncer> dataSyncer;
215 if (dataSyncersMap_.Find(key, dataSyncer)) {
216 return dataSyncer;
217 }
218
219 if (bundleName == GALLERY_BUNDLE_NAME) {
220 dataSyncer = std::make_shared<GalleryDataSyncer>(GALLERY_BUNDLE_NAME, userId);
221 } else {
222 dataSyncer = std::make_shared<CloudDiskDataSyncer>(bundleName, userId);
223 }
224 int32_t ret = dataSyncer->Init(bundleName, userId);
225 if (ret != E_OK) {
226 return nullptr;
227 }
228 dataSyncersMap_.EnsureInsert(key, dataSyncer);
229 DataSyncerRdbStore::GetInstance().Insert(userId, bundleName);
230 return dataSyncer;
231 }
232
IsSkipSync(const std::string & bundle,const int32_t userId)233 int32_t DataSyncManager::IsSkipSync(const std::string &bundle, const int32_t userId)
234 {
235 string bundleName;
236 Convert2BundleName(bundle, bundleName);
237 if (!CloudStatus::IsCloudStatusOkay(bundleName, userId)) {
238 LOGE("cloud status is not OK");
239 return E_CLOUD_SDK;
240 }
241 if (!BatteryStatus::IsBatteryCapcityOkay()) {
242 return E_SYNC_FAILED_BATTERY_TOO_LOW;
243 }
244 return E_OK;
245 }
246
CleanCloudFile(const int32_t userId,const std::string & bundleName,const int action)247 int32_t DataSyncManager::CleanCloudFile(const int32_t userId, const std::string &bundleName, const int action)
248 {
249 LOGI("Enter function CleanCloudFile");
250 auto dataSyncer = GetDataSyncer(bundleName, userId);
251 if (!dataSyncer) {
252 LOGE(" Clean Get dataSyncer failed, bundleName: %{private}s", bundleName.c_str());
253 return E_INVAL_ARG;
254 }
255 auto ret = InitSdk(userId, bundleName, dataSyncer);
256 if (ret != E_OK) {
257 LOGW("sdk init fail");
258 }
259 LOGI("bundleName:%{private}s, userId:%{private}d", dataSyncer->GetBundleName().c_str(), dataSyncer->GetUserId());
260 return dataSyncer->Clean(action);
261 }
262
OptimizeStorage(const std::string & bundleName,const int32_t userId,const int32_t agingDays)263 int32_t DataSyncManager::OptimizeStorage(const std::string &bundleName, const int32_t userId, const int32_t agingDays)
264 {
265 auto dataSyncer = GetDataSyncer(bundleName, userId);
266 if (!dataSyncer) {
267 LOGE("Get dataSyncer failed, bundleName: %{private}s", bundleName.c_str());
268 return E_INVAL_ARG;
269 }
270
271 return dataSyncer->OptimizeStorage(agingDays);
272 }
273
InitSdk(const int32_t userId,const string & bundle,std::shared_ptr<DataSyncer> dataSyncer)274 int32_t DataSyncManager::InitSdk(const int32_t userId, const string &bundle, std::shared_ptr<DataSyncer> dataSyncer)
275 {
276 std::lock_guard<std::mutex> lck(sdkHelperMutex_);
277 if (dataSyncer->HasSdkHelper()) {
278 return E_OK;
279 }
280 /* get sdk helper */
281 auto sdkHelper = std::make_shared<SdkHelper>();
282 string bundleName;
283 Convert2BundleName(bundle, bundleName);
284 auto ret = sdkHelper->Init(userId, bundleName);
285 if (ret != E_OK) {
286 LOGE("get sdk helper err %{public}d", ret);
287 return ret;
288 }
289 dataSyncer->SetSdkHelper(sdkHelper);
290 return E_OK;
291 }
292
Convert2BundleName(const string & bundle,string & bundleName)293 void DataSyncManager::Convert2BundleName(const string &bundle, string &bundleName)
294 {
295 string photo = ".photos";
296 bundleName = bundle;
297 if (bundleName == MEDIALIBRARY_BUNDLE_NAME || (bundle.size() > photo.size() &&
298 (bundle.substr(bundle.size() - photo.size()) == photo))) {
299 bundleName = GALLERY_BUNDLE_NAME;
300 }
301 }
302
DownloadThumb()303 int32_t DataSyncManager::DownloadThumb()
304 {
305 RETURN_ON_ERR(GetUserId(currentUserId_));
306 auto dataSyncer = GetDataSyncer(GALLERY_BUNDLE_NAME, currentUserId_);
307 if (!dataSyncer) {
308 LOGE("Get dataSyncer failed, bundleName: %{private}s", GALLERY_BUNDLE_NAME.c_str());
309 return E_INVAL_ARG;
310 }
311
312 auto ret = InitSdk(currentUserId_, GALLERY_BUNDLE_NAME, dataSyncer);
313 if (ret != E_OK) {
314 return ret;
315 }
316 return dataSyncer->DownloadThumb(DataHandler::DownloadThmType::SCREENOFF_TRIGGER);
317 }
318
GetUserId(int32_t & userId)319 int32_t DataSyncManager::GetUserId(int32_t &userId)
320 {
321 vector<int32_t> activeUsers;
322 if (AccountSA::OsAccountManager::QueryActiveOsAccountIds(activeUsers) != E_OK || activeUsers.empty()) {
323 LOGE("query active user failed");
324 return E_OSACCOUNT;
325 }
326 userId = activeUsers.front();
327 RETURN_ON_ERR(IsUserVerified(userId));
328 return E_OK;
329 }
330
CleanCache(const string & bundleName,const int32_t userId,const string & uri)331 int32_t DataSyncManager::CleanCache(const string &bundleName, const int32_t userId, const string &uri)
332 {
333 auto dataSyncer = GetDataSyncer(bundleName, userId);
334 if (!dataSyncer) {
335 LOGE("Get dataSyncer failed, bundleName: %{private}s", GALLERY_BUNDLE_NAME.c_str());
336 return E_INVAL_ARG;
337 }
338
339 return dataSyncer->CleanCache(uri);
340 }
341
GetAllDataSyncerInfo(const int32_t userId,map<string,DataSyncerInfo> & dataSyncerInfoMaps)342 int32_t DataSyncManager::GetAllDataSyncerInfo(const int32_t userId, map<string, DataSyncerInfo> &dataSyncerInfoMaps)
343 {
344 std::shared_ptr<NativeRdb::ResultSet> resultSet = nullptr;
345 RETURN_ON_ERR(DataSyncerRdbStore::GetInstance().QueryDataSyncer(userId, resultSet));
346
347 while (resultSet->GoToNextRow() == E_OK) {
348 string bundleName;
349 int32_t ret = DataConvertor::GetString(BUNDLE_NAME, bundleName, *resultSet);
350 if (ret != E_OK) {
351 LOGE("get bundle name failed");
352 continue;
353 }
354 int32_t state;
355 ret = DataConvertor::GetInt(SYNC_STATE, state, *resultSet);
356 if (ret != E_OK) {
357 LOGE("get sync state failed");
358 continue;
359 }
360
361 DataSyncerInfo dataSyncerInfo = {
362 .syncState = static_cast<SyncState>(state),
363 };
364 dataSyncerInfoMaps.insert({bundleName, dataSyncerInfo});
365 }
366 return E_OK;
367 }
368
DisableCloud(const int32_t userId)369 int32_t DataSyncManager::DisableCloud(const int32_t userId)
370 {
371 map<string, DataSyncerInfo> dataSyncerInfoMaps;
372 GetAllDataSyncerInfo(userId, dataSyncerInfoMaps);
373 if (dataSyncerInfoMaps.size() == 0) {
374 LOGI("not need to clean");
375 return E_OK;
376 }
377
378 for (const auto &iter : dataSyncerInfoMaps) {
379 auto &bundle = iter.first;
380 auto dataSyncer = GetDataSyncer(bundle, userId);
381 if (!dataSyncer) {
382 LOGE("Get dataSyncer failed, bundleName: %{private}s", bundle.c_str());
383 return E_INVAL_ARG;
384 }
385
386 dataSyncer->DisableCloud();
387 }
388 return E_OK;
389 }
390 } // namespace OHOS::FileManagement::CloudSync
391