• 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 
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