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 "gallery_data_syncer.h"
17
18 #include "data_syncer.h"
19 #include "dfs_error.h"
20 #include "dfsu_timer.h"
21 #include "medialibrary_rdb_utils.h"
22 #include "sync_rule/network_status.h"
23 #include "sync_rule/screen_status.h"
24 #include "task_state_manager.h"
25 #include "utils_log.h"
26
27 namespace OHOS {
28 namespace FileManagement {
29 namespace CloudSync {
30 using namespace std;
31
CloudSyncTriggerFunc(const std::vector<std::string> & args)32 const std::string CloudSyncTriggerFunc(const std::vector<std::string> &args)
33 {
34 return "";
35 }
36
IsCallerSelfFunc(const std::vector<std::string> & args)37 const std::string IsCallerSelfFunc(const std::vector<std::string> &args)
38 {
39 return "false";
40 }
41
GalleryDataSyncer(const std::string bundleName,const int32_t userId)42 GalleryDataSyncer::GalleryDataSyncer(const std::string bundleName, const int32_t userId)
43 : DataSyncer(bundleName, userId)
44 {
45 }
46
Init(const std::string bundleName,const int32_t userId)47 int32_t GalleryDataSyncer::Init(const std::string bundleName, const int32_t userId)
48 {
49 auto rdb = RdbInit(bundleName_, userId_);
50 if (!rdb) {
51 return E_RDB;
52 }
53 /* init handler */
54 fileHandler_ = make_shared<FileDataHandler>(userId_, bundleName_, rdb, stopFlag_);
55 albumHandler_ = make_shared<AlbumDataHandler>(userId_, bundleName_, rdb, stopFlag_);
56 return E_OK;
57 }
58
RdbInit(const std::string & bundleName,const int32_t userId)59 std::shared_ptr<NativeRdb::RdbStore> GalleryDataSyncer::RdbInit(const std::string &bundleName, const int32_t userId)
60 {
61 /* rdb config */
62 NativeRdb::RdbStoreConfig config(DATABASE_NAME);
63 config.SetPath(DATA_APP_EL2 + to_string(userId) + DATABASE_DIR + DATABASE_NAME);
64 config.SetBundleName(BUNDLE_NAME);
65 config.SetReadConSize(CONNECT_SIZE);
66 config.SetSecurityLevel(NativeRdb::SecurityLevel::S3);
67 config.SetScalarFunction("cloud_sync_func", 0, CloudSyncTriggerFunc);
68 config.SetScalarFunction("is_caller_self_func", 0, IsCallerSelfFunc);
69
70 /*
71 * Just pass in any value but zero for parameter @version in GetRdbStore,
72 * since RdbCallback always return 0 in its callbacks.
73 */
74 int32_t err;
75 RdbCallback cb;
76 auto rdb = NativeRdb::RdbHelper::GetRdbStore(config, Media::MEDIA_RDB_VERSION, cb, err);
77 if (rdb == nullptr) {
78 LOGE("gallyer data syncer init rdb fail");
79 }
80
81 return rdb;
82 }
83
Clean(const int action)84 int32_t GalleryDataSyncer::Clean(const int action)
85 {
86 LOGI("gallery data sycner Clean");
87 /* start clean */
88 BeginClean();
89 /* file */
90 int32_t ret = CancelDownload(fileHandler_);
91 if (ret != E_OK) {
92 LOGE("gallery data syncer file cancel download err %{public}d", ret);
93 }
94 ret = CleanInner(albumHandler_, CleanAction::RETAIN_DATA);
95 if (ret != E_OK) {
96 LOGE("gallery data syncer album clean err %{public}d", ret);
97 }
98 fileHandler_->ClearCursor();
99 ret = fileHandler_->MarkClean(action);
100 CompleteClean();
101 return ret;
102 }
103
DisableCloud()104 int32_t GalleryDataSyncer::DisableCloud()
105 {
106 LOGI("gallery data sycner disable");
107 /* start clean */
108 BeginDisableCloud();
109 int32_t ret = CleanInner(fileHandler_, CleanAction::RETAIN_DATA);
110 if (ret != E_OK) {
111 LOGE("gallery data syncer file disable cloud err %{public}d", ret);
112 }
113 CompleteDisableCloud();
114 return ret;
115 }
116
StartDownloadFile(const std::string path,const int32_t userId)117 int32_t GalleryDataSyncer::StartDownloadFile(const std::string path, const int32_t userId)
118 {
119 return DownloadInner(fileHandler_, path, userId);
120 }
121
Schedule()122 void GalleryDataSyncer::Schedule()
123 {
124 LOGI("schedule to stage %{public}d", ++stage_);
125
126 int32_t ret = E_OK;
127 switch (stage_) {
128 case PREPARE: {
129 ret = Prepare();
130 break;
131 }
132 case DOWNLOADALBUM: {
133 ret = DownloadAlbum();
134 break;
135 }
136 case DOWNLOADFILE: {
137 ret = DownloadFile();
138 break;
139 }
140 case COMPLETEPULL: {
141 ret = CompletePull();
142 break;
143 }
144 case UPLOADALBUM: {
145 ret = UploadAlbum();
146 break;
147 }
148 case UPLOADFILE: {
149 ret = UploadFile();
150 break;
151 }
152 case COMPLETEPUSH: {
153 ret = CompletePush();
154 break;
155 }
156 case END: {
157 ret = Complete();
158 break;
159 }
160 default: {
161 ret = E_SCHEDULE;
162 LOGE("schedule fail %{public}d", ret);
163 break;
164 }
165 }
166
167 /* if error takes place while schedule, just abort it */
168 if (ret != E_OK) {
169 Abort();
170 }
171 }
172
ScheduleByType(SyncTriggerType syncTriggerType)173 void GalleryDataSyncer::ScheduleByType(SyncTriggerType syncTriggerType)
174 {
175 LOGI("schedule to stage %{public}d", ++stage_);
176 /* call putHandler in the Reset function when sync is completed */
177 if (syncTriggerType == SyncTriggerType::TASK_TRIGGER) {
178 fileHandler_->SetChecking();
179 }
180 Schedule();
181 }
182
Reset()183 void GalleryDataSyncer::Reset()
184 {
185 if (fileHandler_ != nullptr) {
186 fileHandler_->Reset();
187 }
188 if (albumHandler_ != nullptr) {
189 albumHandler_->Reset();
190 }
191 /* reset stage in case of stop or restart */
192 stage_ = BEGIN;
193 }
194
Prepare()195 int32_t GalleryDataSyncer::Prepare()
196 {
197 /* schedule to next stage */
198 Schedule();
199 return E_OK;
200 }
201
DownloadAlbum()202 int32_t GalleryDataSyncer::DownloadAlbum()
203 {
204 SyncStateChangedNotify(CloudSyncState::DOWNLOADING, ErrorType::NO_ERROR);
205
206 LOGI("gallery data sycner download album");
207 int32_t ret = Pull(albumHandler_);
208 if (ret != E_OK) {
209 LOGE("gallery data syncer pull album err %{public}d", ret);
210 }
211 return ret;
212 }
213
DownloadFile()214 int32_t GalleryDataSyncer::DownloadFile()
215 {
216 LOGI("gallery data sycner download file");
217 int ret = Pull(fileHandler_);
218 if (ret != E_OK) {
219 LOGE("gallery data syncer pull file err %{public}d", ret);
220 }
221 if (timeId_ == 0) {
222 fileHandler_->PeriodicUpdataFiles(timeId_);
223 }
224 return ret;
225 }
226
UploadAlbum()227 int32_t GalleryDataSyncer::UploadAlbum()
228 {
229 int32_t ret = Lock();
230 if (ret != E_OK) {
231 LOGE("gallery data syncer lock err %{public}d", ret);
232 return E_CLOUD_SDK;
233 }
234
235 SyncStateChangedNotify(CloudSyncState::UPLOADING, ErrorType::NO_ERROR);
236
237 LOGI("gallery data sycner upload album");
238 ret = Push(albumHandler_);
239 if (ret != E_OK) {
240 LOGE("gallery data syncer push album err %{public}d", ret);
241 }
242
243 return ret;
244 }
245
UploadFile()246 int32_t GalleryDataSyncer::UploadFile()
247 {
248 LOGI("gallery data sycner upload file");
249 int32_t ret = Push(fileHandler_);
250 if (ret != E_OK) {
251 LOGE("gallery data syncer push file err %{public}d", ret);
252 }
253 return ret;
254 }
255
Complete(bool isNeedNotify)256 int32_t GalleryDataSyncer::Complete(bool isNeedNotify)
257 {
258 LOGI("gallery data syncer complete all");
259 Unlock();
260 if (!TaskStateManager::GetInstance().HasTask(bundleName_, TaskType::DOWNLOAD_THUMB_TASK)) {
261 fileHandler_->StopUpdataFiles(timeId_);
262 }
263 int32_t ret = fileHandler_->CleanRemainRecord();
264 if (ret != E_OK) {
265 LOGW("clean remain record failed");
266 return ret;
267 }
268 DataSyncer::CompleteAll(isNeedNotify);
269 return E_OK;
270 }
271
OptimizeStorage(const int32_t agingDays)272 int32_t GalleryDataSyncer::OptimizeStorage(const int32_t agingDays)
273 {
274 LOGI("gallery data sycner FileAging");
275
276 return fileHandler_->OptimizeStorage(agingDays);
277 }
278
Lock()279 int32_t GalleryDataSyncer::Lock()
280 {
281 lock_guard<mutex> lock(lock_.mtx);
282 if (lock_.count > 0) {
283 lock_.count++;
284 return E_OK;
285 }
286
287 /* lock: device-reentrant */
288 int32_t ret = sdkHelper_->GetLock(lock_.lock);
289 if (ret != E_OK) {
290 LOGE("sdk helper get lock err %{public}d", ret);
291 lock_.lock = {0};
292 if (ret == E_SYNC_FAILED_NETWORK_NOT_AVAILABLE) {
293 SetErrorCodeMask(ErrorType::NETWORK_UNAVAILABLE);
294 }
295 return ret;
296 }
297
298 auto timerCallback = [this]() {
299 lock_guard<mutex> lock(lock_.mtx);
300 if (lock_.lock.lockSessionId.empty()) {
301 LOGE("session is unlocked, please lock first");
302 return;
303 }
304 auto ret = sdkHelper_->GetLock(lock_.lock);
305 if (ret != E_OK) {
306 LOGE("sdk helper get lock err %{public}d", ret);
307 return;
308 }
309 LOGD("timer trigger, lockSessionId:%{public}s", lock_.lock.lockSessionId.c_str());
310 };
311
312 const uint32_t KEEP_ALIVE_PERIOD_COEF = 3;
313 uint32_t period = (uint32_t)(lock_.lock.lockInterval) * (uint32_t)(SECOND_TO_MILLISECOND) / KEEP_ALIVE_PERIOD_COEF;
314 LOGD("period %{public}d", period);
315 DfsuTimer::GetInstance().Register(timerCallback, lock_.timerId, period);
316
317 lock_.count++;
318
319 return ret;
320 }
321
Unlock()322 void GalleryDataSyncer::Unlock()
323 {
324 lock_guard<mutex> lock(lock_.mtx);
325 lock_.count--;
326 if (lock_.count > 0) {
327 return;
328 }
329
330 DfsuTimer::GetInstance().Unregister(lock_.timerId);
331 /* sdk unlock */
332 sdkHelper_->DeleteLock(lock_.lock);
333 /* reset sdk lock */
334 lock_.lock = { 0 };
335 lock_.timerId = 0;
336 }
337
ForceUnlock()338 void GalleryDataSyncer::ForceUnlock()
339 {
340 lock_guard<mutex> lock(lock_.mtx);
341 if (lock_.count == 0) {
342 return;
343 }
344 DfsuTimer::GetInstance().Unregister(lock_.timerId);
345 sdkHelper_->DeleteLock(lock_.lock);
346 lock_.lock = { 0 };
347 lock_.count = 0;
348 lock_.timerId = 0;
349 }
350
DownloadThumb(int32_t type)351 int32_t GalleryDataSyncer::DownloadThumb(int32_t type)
352 {
353 LOGI("Begin download thumbnails");
354 if (TaskStateManager::GetInstance().HasTask(bundleName_, TaskType::DOWNLOAD_THUMB_TASK)) {
355 LOGI("it's already downloading thumb");
356 return E_STOP;
357 }
358 if (type == DataHandler::DownloadThmType::SCREENOFF_TRIGGER) {
359 if (!CheckScreenAndWifi()) {
360 LOGI("download thumb condition is not met");
361 return E_STOP;
362 }
363 }
364 if (timeId_ == 0) {
365 fileHandler_->PeriodicUpdataFiles(timeId_);
366 }
367 TaskStateManager::GetInstance().StartTask(bundleName_, TaskType::DOWNLOAD_THUMB_TASK);
368 fileHandler_->SetDownloadType(type);
369 int32_t ret = DataSyncer::DownloadThumbInner(fileHandler_);
370 if (ret == E_STOP) {
371 StopDownloadThumb();
372 }
373 return ret;
374 }
375
StopDownloadThumb()376 void GalleryDataSyncer::StopDownloadThumb()
377 {
378 TaskStateManager::GetInstance().CompleteTask(bundleName_, TaskType::DOWNLOAD_THUMB_TASK);
379 if (!TaskStateManager::GetInstance().HasTask(bundleName_, TaskType::SYNC_TASK)) {
380 fileHandler_->StopUpdataFiles(timeId_);
381 }
382 }
383
InitSysEventData()384 int32_t GalleryDataSyncer::InitSysEventData()
385 {
386 /* bind sync data to handler */
387 syncStat_ = make_shared<GalleryIncSyncStat>();
388 fileHandler_->SetSyncStat(syncStat_);
389 albumHandler_->SetSyncStat(syncStat_);
390
391 return E_OK;
392 }
393
FreeSysEventData()394 void GalleryDataSyncer::FreeSysEventData()
395 {
396 if (syncStat_ != nullptr) {
397 /* dec ref to sync data */
398 fileHandler_->PutSyncStat();
399 albumHandler_->PutSyncStat();
400 syncStat_ = nullptr;
401 }
402
403 if (checkStat_ != nullptr) {
404 fileHandler_->PutCheckStat();
405 checkStat_ = nullptr;
406 }
407 }
408
SetFullSyncSysEvent()409 void GalleryDataSyncer::SetFullSyncSysEvent()
410 {
411 if (syncStat_ != nullptr) {
412 syncStat_->SetFullSync();
413 }
414 }
415
SetCheckSysEvent()416 void GalleryDataSyncer::SetCheckSysEvent()
417 {
418 if (checkStat_ == nullptr) {
419 /* bind check data to handler */
420 checkStat_ = make_shared<GalleryCheckSatat>();
421 fileHandler_->SetCheckStat(checkStat_);
422 }
423 }
424
CompletePull()425 int32_t GalleryDataSyncer::CompletePull()
426 {
427 Media::MediaLibraryRdbUtils::UpdateSystemAlbumCountInternal(fileHandler_->GetRaw());
428 Media::MediaLibraryRdbUtils::UpdateUserAlbumCountInternal(fileHandler_->GetRaw());
429 return DataSyncer::CompletePull();
430 }
431
ReportSysEvent(uint32_t code)432 void GalleryDataSyncer::ReportSysEvent(uint32_t code)
433 {
434 if (syncStat_ != nullptr) {
435 if (syncStat_->IsFullSync()) {
436 UpdateBasicEventStat(code);
437 syncStat_->Report();
438 } else {
439 /* inc sync report */
440 }
441 }
442
443 if (checkStat_ != nullptr) {
444 checkStat_->Report();
445 }
446 }
447
UpdateBasicEventStat(uint32_t code)448 void GalleryDataSyncer::UpdateBasicEventStat(uint32_t code)
449 {
450 syncStat_->SetSyncReason(static_cast<uint32_t>(triggerType_));
451 syncStat_->SetStopReason(code);
452 syncStat_->SetStartTime(startTime_);
453 syncStat_->SetDuration(GetCurrentTimeStamp());
454 }
455 } // namespace CloudSync
456 } // namespace FileManagement
457 } // namespace OHOS
458