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