• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 #define MLOG_TAG "BackgroundCloudFileProcessor"
17 
18 #include "background_cloud_file_processor.h"
19 
20 #include <sys/statvfs.h>
21 
22 #include "abs_rdb_predicates.h"
23 #include "cloud_sync_manager.h"
24 #include "common_timer_errors.h"
25 #include "media_column.h"
26 #include "media_file_utils.h"
27 #include "media_log.h"
28 #include "medialibrary_errno.h"
29 #include "medialibrary_db_const.h"
30 #include "medialibrary_rdb_utils.h"
31 #include "medialibrary_rdbstore.h"
32 #include "medialibrary_unistore_manager.h"
33 #include "metadata_extractor.h"
34 #include "mimetype_utils.h"
35 #include "rdb_store.h"
36 #include "rdb_utils.h"
37 #include "result_set_utils.h"
38 #include "values_bucket.h"
39 
40 namespace OHOS {
41 namespace Media {
42 using namespace FileManagement::CloudSync;
43 
44 static constexpr int32_t DOWNLOAD_BATCH_SIZE = 2;
45 static constexpr int32_t UPDATE_BATCH_SIZE = 1;
46 static constexpr int32_t MAX_RETRY_COUNT = 2;
47 
48 // The task can be performed only when the ratio of available storage capacity reaches this value
49 static constexpr double PROPER_DEVICE_STORAGE_CAPACITY_RATIO = 0.55;
50 
51 int32_t BackgroundCloudFileProcessor::processInterval_ = PROCESS_INTERVAL;  // 5 minute
52 int32_t BackgroundCloudFileProcessor::downloadDuration_ = DOWNLOAD_DURATION; // 10 seconds
53 recursive_mutex BackgroundCloudFileProcessor::mutex_;
54 Utils::Timer BackgroundCloudFileProcessor::timer_("background_cloud_file_processor");
55 uint32_t BackgroundCloudFileProcessor::startTimerId_ = 0;
56 uint32_t BackgroundCloudFileProcessor::stopTimerId_ = 0;
57 std::vector<std::string> BackgroundCloudFileProcessor::curDownloadPaths_;
58 bool BackgroundCloudFileProcessor::isUpdating_ = true;
59 int32_t BackgroundCloudFileProcessor::currentUpdateOffset_ = 0;
60 int32_t BackgroundCloudFileProcessor::currentRetryCount_ = 0;
61 bool BackgroundCloudFileProcessor::isDownload_ = false;
62 
DownloadCloudFiles()63 void BackgroundCloudFileProcessor::DownloadCloudFiles()
64 {
65     if (!isDownload_) {
66         MEDIA_DEBUG_LOG("download task is closed");
67         return;
68     }
69     MEDIA_DEBUG_LOG("Start downloading cloud files task");
70     if (IsStorageInsufficient()) {
71         MEDIA_WARN_LOG("Insufficient storage space, stop downloading cloud files");
72         return;
73     }
74 
75     auto resultSet = QueryCloudFiles();
76     if (resultSet == nullptr) {
77         MEDIA_ERR_LOG("Failed to query cloud files!");
78         return;
79     }
80 
81     DownloadFiles downloadFiles;
82     ParseDownloadFiles(resultSet, downloadFiles);
83     if (downloadFiles.paths.empty()) {
84         MEDIA_DEBUG_LOG("No cloud files need to be downloaded");
85         return;
86     }
87 
88     int32_t ret = AddDownloadTask(downloadFiles);
89     if (ret != E_OK) {
90         MEDIA_ERR_LOG("Failed to add download task! err: %{public}d", ret);
91     }
92 }
93 
UpdateCloudData()94 void BackgroundCloudFileProcessor::UpdateCloudData()
95 {
96     MEDIA_DEBUG_LOG("Start update cloud data task");
97     auto resultSet = QueryUpdateData();
98     if (resultSet == nullptr) {
99         MEDIA_ERR_LOG("Failed to query update data!");
100         return;
101     }
102 
103     UpdateData updateData;
104     ParseUpdateData(resultSet, updateData);
105     if (updateData.abnormalData.empty()) {
106         MEDIA_DEBUG_LOG("No cloud data need to update");
107         return;
108     }
109 
110     int32_t ret = AddUpdateDataTask(updateData);
111     if (ret != E_OK) {
112         MEDIA_ERR_LOG("Failed to add update task! err: %{public}d", ret);
113     }
114 }
115 
ProcessCloudData()116 void BackgroundCloudFileProcessor::ProcessCloudData()
117 {
118     UpdateCloudData();
119     DownloadCloudFiles();
120 }
121 
IsStorageInsufficient()122 bool BackgroundCloudFileProcessor::IsStorageInsufficient()
123 {
124     struct statvfs diskInfo;
125     int ret = statvfs("/data", &diskInfo);
126     if (ret != 0) {
127         MEDIA_ERR_LOG("Get file system status information failed, err: %{public}d", ret);
128         return true;
129     }
130 
131     double totalSize = static_cast<double>(diskInfo.f_bsize) * static_cast<double>(diskInfo.f_blocks);
132     if (totalSize < 1e-9) {
133         MEDIA_ERR_LOG("Get file system total size failed, totalSize=%{public}f", totalSize);
134         return true;
135     }
136 
137     double freeSize = static_cast<double>(diskInfo.f_bsize) * static_cast<double>(diskInfo.f_bfree);
138     double freeRatio = freeSize / totalSize;
139 
140     return freeRatio < PROPER_DEVICE_STORAGE_CAPACITY_RATIO;
141 }
142 
QueryCloudFiles()143 std::shared_ptr<NativeRdb::ResultSet> BackgroundCloudFileProcessor::QueryCloudFiles()
144 {
145     auto uniStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
146     if (uniStore == nullptr) {
147         MEDIA_ERR_LOG("uniStore is nullptr!");
148         return nullptr;
149     }
150 
151     const string sql = "SELECT " + PhotoColumn::MEDIA_FILE_PATH + ", " + PhotoColumn::MEDIA_TYPE +
152         " FROM(SELECT COUNT(*) AS count, " + PhotoColumn::MEDIA_FILE_PATH + ", " + PhotoColumn::MEDIA_TYPE + ", " +
153         MediaColumn::MEDIA_DATE_MODIFIED + " FROM " + PhotoColumn::PHOTOS_TABLE + " WHERE " +
154         PhotoColumn::PHOTO_CLEAN_FLAG + " = " + std::to_string(static_cast<int32_t>(CleanType::TYPE_NOT_CLEAN)) +
155         " AND " + PhotoColumn::PHOTO_POSITION + " = " + std::to_string(POSITION_CLOUD) + " AND " +
156         PhotoColumn::MEDIA_FILE_PATH + " IS NOT NULL AND " + PhotoColumn::MEDIA_FILE_PATH + " != '' AND " +
157         MediaColumn::MEDIA_SIZE + " > 0 AND(" + PhotoColumn::MEDIA_TYPE + " = " + std::to_string(MEDIA_TYPE_IMAGE) +
158         " OR " + PhotoColumn::MEDIA_TYPE + " = " + std::to_string(MEDIA_TYPE_VIDEO) + ") GROUP BY " +
159         PhotoColumn::MEDIA_FILE_PATH + " HAVING count = 1) ORDER BY " + PhotoColumn::MEDIA_TYPE + " DESC, " +
160         MediaColumn::MEDIA_DATE_MODIFIED + " DESC LIMIT " + std::to_string(DOWNLOAD_BATCH_SIZE);
161 
162     return uniStore->QuerySql(sql);
163 }
164 
ParseDownloadFiles(std::shared_ptr<NativeRdb::ResultSet> & resultSet,DownloadFiles & downloadFiles)165 void BackgroundCloudFileProcessor::ParseDownloadFiles(std::shared_ptr<NativeRdb::ResultSet> &resultSet,
166     DownloadFiles &downloadFiles)
167 {
168     while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
169         std::string path =
170             get<std::string>(ResultSetUtils::GetValFromColumn(PhotoColumn::MEDIA_FILE_PATH, resultSet, TYPE_STRING));
171         if (path.empty()) {
172             MEDIA_WARN_LOG("Failed to get cloud file uri!");
173             continue;
174         }
175         int32_t mediaType =
176             get<int32_t>(ResultSetUtils::GetValFromColumn(PhotoColumn::MEDIA_TYPE, resultSet, TYPE_INT32));
177         if (mediaType == static_cast<int32_t>(MEDIA_TYPE_VIDEO)) {
178             downloadFiles.paths.clear();
179             downloadFiles.paths.push_back(path);
180             downloadFiles.mediaType = MEDIA_TYPE_VIDEO;
181             return;
182         }
183         downloadFiles.paths.push_back(path);
184     }
185     downloadFiles.mediaType = MEDIA_TYPE_IMAGE;
186 }
187 
AddDownloadTask(const DownloadFiles & downloadFiles)188 int32_t BackgroundCloudFileProcessor::AddDownloadTask(const DownloadFiles &downloadFiles)
189 {
190     auto asyncWorker = MediaLibraryAsyncWorker::GetInstance();
191     if (asyncWorker == nullptr) {
192         MEDIA_ERR_LOG("Failed to get async worker instance!");
193         return E_FAIL;
194     }
195 
196     auto *taskData = new (std::nothrow) DownloadCloudFilesData(downloadFiles);
197     if (taskData == nullptr) {
198         MEDIA_ERR_LOG("Failed to alloc async data for downloading cloud files!");
199         return E_NO_MEMORY;
200     }
201 
202     auto asyncTask = std::make_shared<MediaLibraryAsyncTask>(DownloadCloudFilesExecutor, taskData);
203     asyncWorker->AddTask(asyncTask, false);
204     return E_OK;
205 }
206 
DownloadCloudFilesExecutor(AsyncTaskData * data)207 void BackgroundCloudFileProcessor::DownloadCloudFilesExecutor(AsyncTaskData *data)
208 {
209     auto *taskData = static_cast<DownloadCloudFilesData *>(data);
210     auto downloadFiles = taskData->downloadFiles_;
211 
212     MEDIA_DEBUG_LOG("Try to download %{public}zu cloud files.", downloadFiles.paths.size());
213     for (const auto &path : downloadFiles.paths) {
214         int32_t ret = CloudSyncManager::GetInstance().StartDownloadFile(path);
215         if (ret != E_OK) {
216             MEDIA_ERR_LOG("Failed to download cloud file, err: %{public}d, path: %{public}s", ret, path.c_str());
217         }
218     }
219 
220     lock_guard<recursive_mutex> lock(mutex_);
221     curDownloadPaths_ = downloadFiles.paths;
222     if (downloadFiles.mediaType == MEDIA_TYPE_VIDEO) {
223         if (stopTimerId_ > 0) {
224             timer_.Unregister(stopTimerId_);
225         }
226         stopTimerId_ = timer_.Register(StopDownloadFiles, downloadDuration_, true);
227     }
228 }
229 
StopDownloadFiles()230 void BackgroundCloudFileProcessor::StopDownloadFiles()
231 {
232     for (const auto &path : curDownloadPaths_) {
233         MEDIA_INFO_LOG("Try to Stop downloading cloud file, the path is %{public}s", path.c_str());
234         int32_t ret = CloudSyncManager::GetInstance().StopDownloadFile(path);
235         if (ret != E_OK) {
236             MEDIA_ERR_LOG("Stop downloading cloud file failed, err: %{public}d, path: %{public}s", ret, path.c_str());
237         }
238     }
239     curDownloadPaths_.clear();
240 }
241 
QueryUpdateData()242 std::shared_ptr<NativeRdb::ResultSet> BackgroundCloudFileProcessor::QueryUpdateData()
243 {
244     const std::vector<std::string> columns = { MediaColumn::MEDIA_ID, MediaColumn::MEDIA_FILE_PATH,
245         MediaColumn::MEDIA_TYPE, MediaColumn::MEDIA_SIZE,
246         PhotoColumn::PHOTO_WIDTH, PhotoColumn::PHOTO_HEIGHT,
247         MediaColumn::MEDIA_MIME_TYPE, MediaColumn::MEDIA_DURATION };
248 
249     NativeRdb::RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
250     predicates.BeginWrap()
251         ->EqualTo(MediaColumn::MEDIA_SIZE, 0)
252         ->Or()
253         ->IsNull(MediaColumn::MEDIA_SIZE)
254         ->Or()
255         ->EqualTo(PhotoColumn::PHOTO_WIDTH, 0)
256         ->Or()
257         ->IsNull(PhotoColumn::PHOTO_WIDTH)
258         ->Or()
259         ->EqualTo(PhotoColumn::PHOTO_HEIGHT, 0)
260         ->Or()
261         ->IsNull(PhotoColumn::PHOTO_HEIGHT)
262         ->Or()
263         ->EqualTo(MediaColumn::MEDIA_MIME_TYPE, "")
264         ->Or()
265         ->IsNull(MediaColumn::MEDIA_MIME_TYPE)
266         ->Or()
267         ->BeginWrap()
268         ->EqualTo(MediaColumn::MEDIA_TYPE, static_cast<int32_t>(MEDIA_TYPE_VIDEO))
269         ->And()
270         ->BeginWrap()
271         ->EqualTo(MediaColumn::MEDIA_DURATION, 0)
272         ->Or()
273         ->IsNull(MediaColumn::MEDIA_DURATION)
274         ->EndWrap()
275         ->EndWrap()
276         ->EndWrap()
277         ->And()
278         ->EqualTo(MediaColumn::MEDIA_TIME_PENDING, 0)
279         ->And()
280         ->EqualTo(PhotoColumn::PHOTO_SYNC_STATUS, static_cast<int32_t>(SyncStatusType::TYPE_VISIBLE))
281         ->And()
282         ->EqualTo(PhotoColumn::PHOTO_CLEAN_FLAG, static_cast<int32_t>(CleanType::TYPE_NOT_CLEAN))
283         ->OrderByAsc(MediaColumn::MEDIA_ID)
284         ->Limit(currentUpdateOffset_, UPDATE_BATCH_SIZE);
285 
286     return MediaLibraryRdbStore::Query(predicates, columns);
287 }
288 
ParseUpdateData(std::shared_ptr<NativeRdb::ResultSet> & resultSet,UpdateData & updateData)289 void BackgroundCloudFileProcessor::ParseUpdateData(std::shared_ptr<NativeRdb::ResultSet> &resultSet,
290     UpdateData &updateData)
291 {
292     while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
293         int32_t fileId =
294             get<int32_t>(ResultSetUtils::GetValFromColumn(MediaColumn::MEDIA_ID, resultSet, TYPE_INT32));
295         int64_t size =
296             get<int64_t>(ResultSetUtils::GetValFromColumn(MediaColumn::MEDIA_SIZE, resultSet, TYPE_INT64));
297         int32_t width =
298             get<int32_t>(ResultSetUtils::GetValFromColumn(PhotoColumn::PHOTO_WIDTH, resultSet, TYPE_INT32));
299         int32_t height =
300             get<int32_t>(ResultSetUtils::GetValFromColumn(PhotoColumn::PHOTO_HEIGHT, resultSet, TYPE_INT32));
301         int32_t duration =
302             get<int32_t>(ResultSetUtils::GetValFromColumn(MediaColumn::MEDIA_DURATION, resultSet, TYPE_INT32));
303         std::string path =
304             get<std::string>(ResultSetUtils::GetValFromColumn(MediaColumn::MEDIA_FILE_PATH, resultSet, TYPE_STRING));
305         if (path.empty()) {
306             MEDIA_WARN_LOG("Failed to get data path");
307             continue;
308         }
309         std::string mimeType =
310             get<std::string>(ResultSetUtils::GetValFromColumn(MediaColumn::MEDIA_MIME_TYPE, resultSet, TYPE_STRING));
311         int32_t mediaType =
312             get<int32_t>(ResultSetUtils::GetValFromColumn(MediaColumn::MEDIA_TYPE, resultSet, TYPE_INT32));
313 
314         AbnormalData abnormalData;
315         abnormalData.fileId = fileId;
316         abnormalData.path = path;
317         abnormalData.size = size;
318         abnormalData.width = width;
319         abnormalData.height = height;
320         abnormalData.duration = duration;
321         abnormalData.mimeType = mimeType;
322 
323         if (mediaType == static_cast<int32_t>(MEDIA_TYPE_VIDEO)) {
324             updateData.abnormalData.clear();
325             updateData.abnormalData.push_back(abnormalData);
326             updateData.mediaType = MEDIA_TYPE_VIDEO;
327             return;
328         }
329         updateData.abnormalData.push_back(abnormalData);
330     }
331     updateData.mediaType = MEDIA_TYPE_IMAGE;
332 }
333 
AddUpdateDataTask(const UpdateData & updateData)334 int32_t BackgroundCloudFileProcessor::AddUpdateDataTask(const UpdateData &updateData)
335 {
336     auto asyncWorker = MediaLibraryAsyncWorker::GetInstance();
337     if (asyncWorker == nullptr) {
338         MEDIA_ERR_LOG("Failed to get async worker instance!");
339         return E_FAIL;
340     }
341 
342     auto *taskData = new (std::nothrow) UpdateAbnormalData(updateData);
343     if (taskData == nullptr) {
344         MEDIA_ERR_LOG("Failed to alloc async data for update cloud data!");
345         return E_NO_MEMORY;
346     }
347 
348     auto asyncTask = std::make_shared<MediaLibraryAsyncTask>(UpdateCloudDataExecutor, taskData);
349     asyncWorker->AddTask(asyncTask, false);
350     return E_OK;
351 }
352 
UpdateCurrentOffset()353 void BackgroundCloudFileProcessor::UpdateCurrentOffset()
354 {
355     if (currentRetryCount_ >= MAX_RETRY_COUNT) {
356         currentUpdateOffset_ += 1;
357         currentRetryCount_ = 0;
358     } else {
359         currentRetryCount_ += 1;
360     }
361     MEDIA_INFO_LOG("currentUpdateOffset_ is %{public}d, currentRetryCount_ is %{public}d",
362         currentUpdateOffset_, currentRetryCount_);
363 }
364 
UpdateCloudDataExecutor(AsyncTaskData * data)365 void BackgroundCloudFileProcessor::UpdateCloudDataExecutor(AsyncTaskData *data)
366 {
367     auto *taskData = static_cast<UpdateAbnormalData *>(data);
368     auto updateData = taskData->updateData_;
369 
370     MEDIA_INFO_LOG("start update %{public}zu cloud files.", updateData.abnormalData.size());
371     for (const auto &abnormalData : updateData.abnormalData) {
372         if (!isUpdating_) {
373             MEDIA_INFO_LOG("stop update data, isUpdating_ is %{public}d.", isUpdating_);
374             return;
375         }
376         std::unique_ptr<Metadata> metadata = make_unique<Metadata>();
377         metadata->SetFilePath(abnormalData.path);
378         metadata->SetFileMediaType(updateData.mediaType);
379         metadata->SetFileId(abnormalData.fileId);
380         metadata->SetFileDuration(abnormalData.duration);
381         metadata->SetFileHeight(abnormalData.height);
382         metadata->SetFileWidth(abnormalData.width);
383         metadata->SetFileSize(abnormalData.size);
384         metadata->SetFileMimeType(abnormalData.mimeType);
385         GetSizeAndMimeType(metadata);
386         if (abnormalData.size == 0 || abnormalData.mimeType.empty()) {
387             int64_t fileSize = metadata->GetFileSize();
388             string mimeType =  metadata->GetFileMimeType();
389             metadata->SetFileSize(fileSize == 0 ? -1: fileSize);
390             metadata->SetFileMimeType(mimeType.empty() ? DEFAULT_IMAGE_MIME_TYPE : mimeType);
391         }
392         if (abnormalData.width == 0 || abnormalData.height == 0
393             || (abnormalData.duration == 0 && updateData.mediaType == MEDIA_TYPE_VIDEO)) {
394             int32_t ret = GetExtractMetadata(metadata);
395             if (ret != E_OK && MediaFileUtils::IsFileExists(abnormalData.path)) {
396                 UpdateCurrentOffset();
397                 MEDIA_ERR_LOG("failed to get extract metadata! err: %{public}d.", ret);
398                 continue;
399             }
400             int32_t width = metadata->GetFileWidth();
401             int32_t height = metadata->GetFileHeight();
402             int32_t duration = metadata->GetFileDuration();
403             metadata->SetFileWidth(width == 0 ? -1: width);
404             metadata->SetFileHeight(height == 0 ? -1: height);
405             metadata->SetFileDuration((duration == 0 && updateData.mediaType == MEDIA_TYPE_VIDEO) ? -1: duration);
406         }
407         UpdateAbnormaldata(metadata, PhotoColumn::PHOTOS_TABLE);
408         currentRetryCount_ = 0;
409     }
410 }
411 
SetAbnormalValuesFromMetaData(std::unique_ptr<Metadata> & metadata,NativeRdb::ValuesBucket & values)412 static void SetAbnormalValuesFromMetaData(std::unique_ptr<Metadata> &metadata, NativeRdb::ValuesBucket &values)
413 {
414     values.PutLong(MediaColumn::MEDIA_SIZE, metadata->GetFileSize());
415     values.PutInt(MediaColumn::MEDIA_DURATION, metadata->GetFileDuration());
416     values.PutInt(PhotoColumn::PHOTO_HEIGHT, metadata->GetFileHeight());
417     values.PutInt(PhotoColumn::PHOTO_WIDTH, metadata->GetFileWidth());
418     values.PutString(MediaColumn::MEDIA_MIME_TYPE, metadata->GetFileMimeType());
419 }
420 
UpdateAbnormaldata(std::unique_ptr<Metadata> & metadata,const std::string & tableName)421 void BackgroundCloudFileProcessor::UpdateAbnormaldata(std::unique_ptr<Metadata> &metadata, const std::string &tableName)
422 {
423     int32_t updateCount(0);
424     NativeRdb::ValuesBucket values;
425     string whereClause = MediaColumn::MEDIA_ID + " = ?";
426     vector<string> whereArgs = { to_string(metadata->GetFileId()) };
427     SetAbnormalValuesFromMetaData(metadata, values);
428     auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
429     if (rdbStore == nullptr) {
430         MEDIA_ERR_LOG("Update operation failed. rdbStore is null");
431         return ;
432     }
433     if (!isUpdating_) {
434         MEDIA_INFO_LOG("stop update data,isUpdating_ is %{public}d.", isUpdating_);
435         return;
436     }
437     int32_t result = rdbStore->Update(updateCount, tableName, values, whereClause, whereArgs);
438     if (result != NativeRdb::E_OK || updateCount <= 0) {
439         MEDIA_ERR_LOG("Update operation failed. Result %{public}d. Updated %{public}d", result, updateCount);
440         return ;
441     }
442     MEDIA_INFO_LOG("id:%{public}d, duration:%{public}d, height:%{public}d, width:%{public}d, size:%{public}" PRId64,
443         metadata->GetFileId(), metadata->GetFileDuration(), metadata->GetFileHeight(), metadata->GetFileWidth(),
444         metadata->GetFileSize());
445 }
446 
GetSizeAndMimeType(std::unique_ptr<Metadata> & metadata)447 void BackgroundCloudFileProcessor::GetSizeAndMimeType(std::unique_ptr<Metadata> &metadata)
448 {
449     std::string path = metadata->GetFilePath();
450     struct stat statInfo {};
451     if (stat(path.c_str(), &statInfo) != 0) {
452         MEDIA_ERR_LOG("stat syscall err %{public}d", errno);
453         metadata->SetFileSize(static_cast<int64_t>(0));
454     } else {
455         metadata->SetFileSize(statInfo.st_size);
456     }
457     string extension = ScannerUtils::GetFileExtension(path);
458     string mimeType = MimeTypeUtils::GetMimeTypeFromExtension(extension);
459     metadata->SetFileExtension(extension);
460     metadata->SetFileMimeType(mimeType);
461 }
462 
GetExtractMetadata(std::unique_ptr<Metadata> & metadata)463 int32_t BackgroundCloudFileProcessor::GetExtractMetadata(std::unique_ptr<Metadata> &metadata)
464 {
465     int32_t err = 0;
466     if (metadata->GetFileMediaType() == MEDIA_TYPE_IMAGE) {
467         err = MetadataExtractor::ExtractImageMetadata(metadata);
468     } else {
469         err = MetadataExtractor::ExtractAVMetadata(metadata);
470     }
471     if (err != E_OK) {
472         MEDIA_ERR_LOG("failed to extract data");
473         return err;
474     }
475     return E_OK;
476 }
477 
StopUpdateData()478 void BackgroundCloudFileProcessor::StopUpdateData()
479 {
480     isUpdating_ = false;
481 }
482 
StartTimer()483 void BackgroundCloudFileProcessor::StartTimer()
484 {
485     lock_guard<recursive_mutex> lock(mutex_);
486     MEDIA_INFO_LOG("Turn on the background download cloud file timer");
487 
488     if (startTimerId_ > 0) {
489         timer_.Unregister(startTimerId_);
490     }
491     uint32_t ret = timer_.Setup();
492     if (ret != Utils::TIMER_ERR_OK) {
493         MEDIA_ERR_LOG("Failed to start background download cloud files timer, err: %{public}d", ret);
494     }
495     isUpdating_ = true;
496     startTimerId_ = timer_.Register(ProcessCloudData, processInterval_);
497 }
498 
StopTimer()499 void BackgroundCloudFileProcessor::StopTimer()
500 {
501     lock_guard<recursive_mutex> lock(mutex_);
502     MEDIA_INFO_LOG("Turn off the background download cloud file timer");
503 
504     timer_.Unregister(startTimerId_);
505     timer_.Unregister(stopTimerId_);
506     timer_.Shutdown();
507     startTimerId_ = 0;
508     stopTimerId_ = 0;
509     StopUpdateData();
510     StopDownloadFiles();
511 }
512 } // namespace Media
513 } // namespace OHOS
514