• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 #define MLOG_TAG "Thumbnail"
16 
17 #include "thumbnail_service.h"
18 
19 #include "cloud_sync_helper.h"
20 #include "display_manager.h"
21 #include "dfx_utils.h"
22 #include "ipc_skeleton.h"
23 #include "ithumbnail_helper.h"
24 #include "media_column.h"
25 #include "media_file_utils.h"
26 #include "medialibrary_async_worker.h"
27 #include "medialibrary_db_const.h"
28 #include "medialibrary_errno.h"
29 #include "medialibrary_kvstore_manager.h"
30 #include "medialibrary_type_const.h"
31 #include "medialibrary_unistore_manager.h"
32 #include "media_log.h"
33 #include "result_set_utils.h"
34 #include "thumbnail_aging_helper.h"
35 #include "thumbnail_const.h"
36 #include "thumbnail_generate_helper.h"
37 #include "thumbnail_generate_worker_manager.h"
38 #include "thumbnail_generation_post_process.h"
39 #include "thumbnail_image_framework_utils.h"
40 #include "thumbnail_source_loading.h"
41 #include "thumbnail_uri_utils.h"
42 #include "post_event_utils.h"
43 #ifdef HAS_THERMAL_MANAGER_PART
44 #include "thermal_mgr_client.h"
45 #endif
46 
47 using namespace std;
48 using namespace OHOS::NativeRdb;
49 using namespace OHOS::AbilityRuntime;
50 
51 namespace OHOS {
52 namespace Media {
53 std::shared_ptr<ThumbnailService> ThumbnailService::thumbnailServiceInstance_{nullptr};
54 std::mutex ThumbnailService::instanceLock_;
ThumbnailService(void)55 ThumbnailService::ThumbnailService(void)
56 {
57     rdbStorePtr_ = nullptr;
58     rdbPredicatePtr_ = nullptr;
59 }
60 
GetInstance()61 shared_ptr<ThumbnailService> ThumbnailService::GetInstance()
62 {
63     if (thumbnailServiceInstance_ == nullptr) {
64         std::lock_guard<std::mutex> lockGuard(instanceLock_);
65         if (thumbnailServiceInstance_ != nullptr) {
66             return thumbnailServiceInstance_;
67         }
68         thumbnailServiceInstance_ = shared_ptr<ThumbnailService>(new ThumbnailService());
69     }
70 
71     return thumbnailServiceInstance_;
72 }
73 
GetDefaultWindowSize(Size & size)74 static bool GetDefaultWindowSize(Size &size)
75 {
76     auto &displayMgr = OHOS::Rosen::DisplayManager::GetInstance();
77     auto display = displayMgr.GetDefaultDisplay();
78     if (display == nullptr) {
79         MEDIA_ERR_LOG("Get display window size failed");
80         return false;
81     }
82     size.width = display->GetWidth();
83     size.height = display->GetHeight();
84     if (size.width <= 0) {
85         MEDIA_WARN_LOG("Get Default display width is invalid %{public}d", size.width);
86         size.width = DEFAULT_LCD_SIZE;
87     }
88     if (size.height <= 0) {
89         MEDIA_WARN_LOG("Get Default display height is invalid %{public}d", size.height);
90         size.height = DEFAULT_LCD_SIZE;
91     }
92     MEDIA_INFO_LOG("display window size::w %{public}d, h %{public}d", size.width, size.height);
93 
94     return true;
95 }
96 
CheckSizeValid()97 bool ThumbnailService::CheckSizeValid()
98 {
99     if (!isScreenSizeInit_) {
100         if (!GetDefaultWindowSize(screenSize_)) {
101             return false;
102         }
103         isScreenSizeInit_ = true;
104     }
105     return true;
106 }
107 
Init(const shared_ptr<MediaLibraryRdbStore> rdbStore,const shared_ptr<Context> & context)108 void ThumbnailService::Init(const shared_ptr<MediaLibraryRdbStore> rdbStore,
109     const shared_ptr<Context> &context)
110 {
111     rdbStorePtr_ = rdbStore;
112     context_ = context;
113 
114     if (!GetDefaultWindowSize(screenSize_)) {
115         MEDIA_ERR_LOG("GetDefaultWindowSize failed");
116     } else {
117         isScreenSizeInit_ = true;
118     }
119 }
120 
ReleaseService()121 void ThumbnailService::ReleaseService()
122 {
123     StopAllWorker();
124     rdbStorePtr_ = nullptr;
125     context_ = nullptr;
126     thumbnailServiceInstance_ = nullptr;
127 }
128 
129 #ifdef MEDIALIBRARY_COMPATIBILITY
GetPathFromDb(const shared_ptr<MediaLibraryRdbStore> rdbStorePtr,const string & fileId,const string & table,string & path)130 static int32_t GetPathFromDb(const shared_ptr<MediaLibraryRdbStore> rdbStorePtr, const string &fileId,
131     const string &table, string &path)
132 {
133     if (rdbStorePtr == nullptr) {
134         VariantMap map = {{KEY_ERR_FILE, __FILE__}, {KEY_ERR_LINE, __LINE__}, {KEY_ERR_CODE, E_HAS_DB_ERROR},
135             {KEY_OPT_TYPE, OptType::THUMB}};
136         PostEventUtils::GetInstance().PostErrorProcess(ErrType::DB_OPT_ERR, map);
137         return E_HAS_DB_ERROR;
138     }
139     if (!all_of(fileId.begin(), fileId.end(), ::isdigit)) {
140         return E_INVALID_FILEID;
141     }
142     string querySql = "SELECT " + MediaColumn::MEDIA_FILE_PATH + " FROM " + table +
143         " WHERE " + MediaColumn::MEDIA_ID + "=?";
144     vector<string> selectionArgs = { fileId };
145     auto resultSet = rdbStorePtr->QuerySql(querySql, selectionArgs);
146     if (resultSet == nullptr || resultSet->GoToFirstRow() != NativeRdb::E_OK) {
147         VariantMap map = {{KEY_ERR_FILE, __FILE__}, {KEY_ERR_LINE, __LINE__}, {KEY_ERR_CODE, E_HAS_DB_ERROR},
148             {KEY_OPT_TYPE, OptType::THUMB}};
149         PostEventUtils::GetInstance().PostErrorProcess(ErrType::DB_OPT_ERR, map);
150         return E_HAS_DB_ERROR;
151     }
152     path = GetStringVal(MediaColumn::MEDIA_FILE_PATH, resultSet);
153     if (path.empty()) {
154         return E_INVALID_PATH;
155     }
156     return E_OK;
157 }
158 #endif
159 
GetThumbFd(const string & path,const string & table,const string & id,const string & uri,const Size & size,bool isAstc)160 int ThumbnailService::GetThumbFd(const string &path, const string &table, const string &id, const string &uri,
161     const Size &size, bool isAstc)
162 {
163     ThumbRdbOpt opts = {
164         .store = rdbStorePtr_,
165         .path = path,
166         .table = table,
167         .row = id,
168         .uri = uri,
169     };
170     ThumbnailType thumbType = GetThumbType(size.width, size.height, isAstc);
171     if (thumbType != ThumbnailType::THUMB && thumbType != ThumbnailType::THUMB_ASTC) {
172         opts.screenSize = screenSize_;
173     }
174     ThumbnailData data;
175     int fd = ThumbnailGenerateHelper::GetThumbnailPixelMap(data, opts, thumbType);
176     CHECK_AND_PRINT_LOG(fd >= 0, "GetThumbnailPixelMap failed : %{public}d", fd);
177     int32_t err = ThumbnailGenerationPostProcess::PostProcess(data, opts);
178     CHECK_AND_PRINT_LOG(err == E_OK, "PostProcess failed! err %{public}d", err);
179     return fd;
180 }
181 
GetKeyFrameThumbFd(const string & path,const string & table,const string & id,const string & uri,int32_t & beginStamp,int32_t & type)182 int ThumbnailService::GetKeyFrameThumbFd(const string &path, const string &table, const string &id, const string &uri,
183     int32_t &beginStamp, int32_t &type)
184 {
185     ThumbRdbOpt opts = {
186         .store = rdbStorePtr_,
187         .path = path,
188         .table = table,
189         .row = id,
190         .uri = uri,
191     };
192 
193     int fd = ThumbnailGenerateHelper::GetKeyFrameThumbnailPixelMap(opts, beginStamp, type);
194     if (fd < 0) {
195         MEDIA_ERR_LOG("GetKeyFrameThumbnailPixelMap failed : %{public}d", fd);
196     }
197     return fd;
198 }
199 
GetThumbnailFd(const string & uri,bool isAstc)200 int ThumbnailService::GetThumbnailFd(const string &uri, bool isAstc)
201 {
202     if (!CheckSizeValid()) {
203         MEDIA_ERR_LOG("GetThumbnailFd failed for invaild size, uri: %{public}s", uri.c_str());
204         return E_THUMBNAIL_INVALID_SIZE;
205     }
206     string id;
207     string path;
208     string table;
209     Size size;
210     if (!ThumbnailUriUtils::ParseThumbnailInfo(uri, id, size, path, table)) {
211         VariantMap map = {{KEY_ERR_FILE, __FILE__}, {KEY_ERR_LINE, __LINE__}, {KEY_ERR_CODE, E_FAIL},
212             {KEY_OPT_FILE, uri}, {KEY_OPT_TYPE, OptType::THUMB}};
213         PostEventUtils::GetInstance().PostErrorProcess(ErrType::FILE_OPT_ERR, map);
214         return E_FAIL;
215     }
216 #ifdef MEDIALIBRARY_COMPATIBILITY
217     if (path.empty()) {
218         int32_t errCode = GetPathFromDb(rdbStorePtr_, id, table, path);
219         if (errCode != E_OK) {
220             VariantMap map = {{KEY_ERR_FILE, __FILE__}, {KEY_ERR_LINE, __LINE__}, {KEY_ERR_CODE, errCode},
221                 {KEY_OPT_TYPE, OptType::THUMB}};
222             PostEventUtils::GetInstance().PostErrorProcess(ErrType::DB_OPT_ERR, map);
223             MEDIA_ERR_LOG("GetPathFromDb failed, errCode = %{public}d", errCode);
224             return errCode;
225         }
226     }
227 #endif
228     return GetThumbFd(path, table, id, uri, size, isAstc);
229 }
230 
GetKeyFrameThumbnailFd(const string & uri,bool isAstc)231 int ThumbnailService::GetKeyFrameThumbnailFd(const string &uri, bool isAstc)
232 {
233     if (!CheckSizeValid()) {
234         MEDIA_ERR_LOG("GetKeyFrameThumbnailFd failed for invaild size, uri: %{public}s", uri.c_str());
235         return E_THUMBNAIL_INVALID_SIZE;
236     }
237     string id;
238     string path;
239     int32_t beginStamp;
240     int32_t type;
241     if (!ThumbnailUriUtils::ParseKeyFrameThumbnailInfo(uri, id, beginStamp, type, path)) {
242         MEDIA_ERR_LOG("failed to parse keyFrame thumbnail info");
243         return E_FAIL;
244     }
245     string table = PhotoColumn::HIGHLIGHT_TABLE;
246 #ifdef MEDIALIBRARY_COMPATIBILITY
247     if (path.empty()) {
248         int32_t errCode = GetPathFromDb(rdbStorePtr_, id, table, path);
249         if (errCode != E_OK) {
250             MEDIA_ERR_LOG("GetPathFromDb failed, errCode = %{public}d", errCode);
251             return errCode;
252         }
253     }
254 #endif
255     return GetKeyFrameThumbFd(path, table, id, uri, beginStamp, type);
256 }
257 
ParseThumbnailParam(const std::string & uri,string & fileId,string & networkId,string & tableName)258 int32_t ThumbnailService::ParseThumbnailParam(const std::string &uri, string &fileId, string &networkId,
259     string &tableName)
260 {
261     if (!CheckSizeValid()) {
262         VariantMap map = {{KEY_ERR_FILE, __FILE__}, {KEY_ERR_LINE, __LINE__}, {KEY_ERR_CODE, E_THUMBNAIL_INVALID_SIZE},
263             {KEY_OPT_FILE, uri}, {KEY_OPT_TYPE, OptType::THUMB}};
264         PostEventUtils::GetInstance().PostErrorProcess(ErrType::FILE_OPT_ERR, map);
265         return E_THUMBNAIL_INVALID_SIZE;
266     }
267     if (!ThumbnailUriUtils::ParseFileUri(uri, fileId, networkId, tableName)) {
268         VariantMap map = {{KEY_ERR_FILE, __FILE__}, {KEY_ERR_LINE, __LINE__}, {KEY_ERR_CODE, E_ERR},
269             {KEY_OPT_FILE, uri}, {KEY_OPT_TYPE, OptType::THUMB}};
270         PostEventUtils::GetInstance().PostErrorProcess(ErrType::FILE_OPT_ERR, map);
271         MEDIA_ERR_LOG("ParseThumbnailInfo faild");
272         return E_ERR;
273     }
274     return E_OK;
275 }
276 
CreateThumbnailPastDirtyDataFix(const std::string & fileId)277 int32_t ThumbnailService::CreateThumbnailPastDirtyDataFix(const std::string &fileId)
278 {
279     ThumbRdbOpt opts = {
280         .store = rdbStorePtr_,
281         .table = PhotoColumn::PHOTOS_TABLE,
282         .row = fileId
283     };
284     int err = 0;
285     ThumbnailData data;
286 
287     ThumbnailUtils::QueryThumbnailDataFromFileId(opts, fileId, data, err);
288     CHECK_AND_RETURN_RET_LOG(err == E_OK, err, "QueryThumbnailDataFromFileId failed, path: %{public}s",
289         DfxUtils::GetSafePath(data.path).c_str());
290     data.loaderOpts.loadingStates = SourceLoader::LOCAL_SOURCE_LOADING_STATES;
291     data.isLocalFile = true;
292     IThumbnailHelper::AddThumbnailGenerateTask(
293         IThumbnailHelper::CreateThumbnail, opts, data, ThumbnailTaskType::FOREGROUND, ThumbnailTaskPriority::LOW);
294     return E_OK;
295 }
296 
CreateLcdPastDirtyDataFix(const std::string & fileId)297 int32_t ThumbnailService::CreateLcdPastDirtyDataFix(const std::string &fileId)
298 {
299     ThumbRdbOpt opts = {
300         .store = rdbStorePtr_,
301         .table = PhotoColumn::PHOTOS_TABLE,
302         .row = fileId
303     };
304     int err = 0;
305     ThumbnailData data;
306     data.createLowQulityLcd = true;
307 
308     ThumbnailUtils::QueryThumbnailDataFromFileId(opts, fileId, data, err);
309     CHECK_AND_RETURN_RET_LOG(err == E_OK, err, "QueryThumbnailDataFromFileId failed, path: %{public}s",
310         DfxUtils::GetSafePath(data.path).c_str());
311     data.loaderOpts.loadingStates = SourceLoader::LOCAL_SOURCE_LOADING_STATES;
312     data.isLocalFile = true;
313     IThumbnailHelper::AddThumbnailGenerateTask(
314         IThumbnailHelper::CreateLcd, opts, data, ThumbnailTaskType::FOREGROUND, ThumbnailTaskPriority::LOW);
315     return E_OK;
316 }
317 
CreateThumbnailFileScaned(const std::string & uri,const string & path,bool isSync)318 int32_t ThumbnailService::CreateThumbnailFileScaned(const std::string &uri, const string &path, bool isSync)
319 {
320     string fileId;
321     string networkId;
322     string tableName;
323 
324     int err = ParseThumbnailParam(uri, fileId, networkId, tableName);
325     if (err != E_OK) {
326         VariantMap map = {{KEY_ERR_FILE, __FILE__}, {KEY_ERR_LINE, __LINE__}, {KEY_ERR_CODE, E_ERR},
327             {KEY_OPT_FILE, uri}, {KEY_OPT_TYPE, OptType::THUMB}};
328         PostEventUtils::GetInstance().PostErrorProcess(ErrType::FILE_OPT_ERR, map);
329         return err;
330     }
331 
332     std::string dateTaken = ThumbnailUriUtils::GetDateTakenFromUri(uri);
333     std::string dateModified = ThumbnailUriUtils::GetDateModifiedFromUri(uri);
334     std::string fileUri = ThumbnailUriUtils::GetFileUriFromUri(uri);
335     ThumbRdbOpt opts = {
336         .store = rdbStorePtr_,
337         .path = path,
338         .table = tableName,
339         .row = fileId,
340         .dateTaken = dateTaken,
341         .dateModified = dateModified,
342         .fileUri = fileUri,
343         .screenSize = screenSize_
344     };
345 
346     err = ThumbnailGenerateHelper::CreateThumbnailFileScaned(opts, isSync);
347     if (err != E_OK) {
348         MEDIA_ERR_LOG("CreateThumbnailFileScaned failed : %{public}d", err);
349         VariantMap map = {{KEY_ERR_FILE, __FILE__}, {KEY_ERR_LINE, __LINE__}, {KEY_ERR_CODE, err},
350             {KEY_OPT_FILE, uri}, {KEY_OPT_TYPE, OptType::THUMB}};
351         PostEventUtils::GetInstance().PostErrorProcess(ErrType::FILE_OPT_ERR, map);
352         return err;
353     }
354     return E_OK;
355 }
356 
CreateThumbnailFileScanedWithPicture(const std::string & uri,const string & path,std::shared_ptr<Picture> originalPhotoPicture,bool isSync)357 int32_t ThumbnailService::CreateThumbnailFileScanedWithPicture(const std::string &uri, const string &path,
358     std::shared_ptr<Picture> originalPhotoPicture, bool isSync)
359 {
360     CHECK_AND_RETURN_RET_LOG(!uri.empty(), E_ERR, "Uri is empty");
361     string fileId;
362     string networkId;
363     string tableName;
364 
365     int err = ParseThumbnailParam(uri, fileId, networkId, tableName);
366     CHECK_AND_RETURN_RET_LOG(err == E_OK, err, "ParseThumbnailParam failed, err:%{public}d", err);
367 
368     std::string dateTaken = ThumbnailUriUtils::GetDateTakenFromUri(uri);
369     std::string dateModified = ThumbnailUriUtils::GetDateModifiedFromUri(uri);
370     std::string fileUri = ThumbnailUriUtils::GetFileUriFromUri(uri);
371     ThumbRdbOpt opts = {
372         .store = rdbStorePtr_,
373         .path = path,
374         .table = tableName,
375         .row = fileId,
376         .dateTaken = dateTaken,
377         .dateModified = dateModified,
378         .fileUri = fileUri,
379         .screenSize = screenSize_
380     };
381 
382     err = ThumbnailGenerateHelper::CreateThumbnailFileScanedWithPicture(opts, originalPhotoPicture, isSync);
383     CHECK_AND_RETURN_RET_LOG(err == E_OK, err, "CreateThumbnailFileScaned failed:%{public}d", err);
384     return E_OK;
385 }
386 
InterruptBgworker()387 void ThumbnailService::InterruptBgworker()
388 {
389     std::shared_ptr<ThumbnailGenerateWorker> thumbnailWorker =
390         ThumbnailGenerateWorkerManager::GetInstance().GetThumbnailWorker(ThumbnailTaskType::BACKGROUND);
391     if (thumbnailWorker == nullptr) {
392         MEDIA_ERR_LOG("thumbnailWorker is null");
393         return;
394     }
395     thumbnailWorker->ReleaseTaskQueue(ThumbnailTaskPriority::LOW);
396 }
397 
StopAllWorker()398 void ThumbnailService::StopAllWorker()
399 {
400     shared_ptr<MediaLibraryAsyncWorker> asyncWorker = MediaLibraryAsyncWorker::GetInstance();
401     if (asyncWorker != nullptr) {
402         asyncWorker->Stop();
403     }
404 
405     ThumbnailGenerateWorkerManager::GetInstance().ClearAllTask();
406 }
407 
GenerateThumbnailBackground()408 int32_t ThumbnailService::GenerateThumbnailBackground()
409 {
410     if (!CheckSizeValid()) {
411         return E_THUMBNAIL_INVALID_SIZE;
412     }
413     int32_t err = 0;
414     vector<string> tableList;
415     tableList.emplace_back(PhotoColumn::PHOTOS_TABLE);
416     tableList.emplace_back(AudioColumn::AUDIOS_TABLE);
417     tableList.emplace_back(MEDIALIBRARY_TABLE);
418 
419     for (const auto &tableName : tableList) {
420         ThumbRdbOpt opts = {
421             .store = rdbStorePtr_,
422             .table = tableName
423         };
424 
425         if ((tableName == PhotoColumn::PHOTOS_TABLE) && ThumbnailImageFrameWorkUtils::IsSupportGenAstc()) {
426             // CreateAstcBackground contains thumbnails created.
427             err = ThumbnailGenerateHelper::CreateAstcBackground(opts);
428             if (err != E_OK) {
429                 MEDIA_ERR_LOG("CreateAstcBackground failed : %{public}d", err);
430             }
431         } else {
432             err = ThumbnailGenerateHelper::CreateThumbnailBackground(opts);
433             if (err != E_OK) {
434                 MEDIA_ERR_LOG("CreateThumbnailBackground failed : %{public}d", err);
435             }
436         }
437 
438         if (tableName == PhotoColumn::PHOTOS_TABLE) {
439             err = ThumbnailGenerateHelper::CreateLcdBackground(opts);
440             if (err != E_OK) {
441                 MEDIA_ERR_LOG("CreateLcdBackground failed : %{public}d", err);
442             }
443         }
444     }
445 
446     return err;
447 }
448 
UpgradeThumbnailBackground(bool isWifiConnected)449 int32_t ThumbnailService::UpgradeThumbnailBackground(bool isWifiConnected)
450 {
451     ThumbRdbOpt opts = {
452         .store = rdbStorePtr_,
453         .table = PhotoColumn::PHOTOS_TABLE
454     };
455     int32_t err = ThumbnailGenerateHelper::UpgradeThumbnailBackground(opts, isWifiConnected);
456     if (err != E_OK) {
457         MEDIA_ERR_LOG("UpgradeThumbnailBackground failed : %{public}d", err);
458     }
459     return err;
460 }
461 
GenerateHighlightThumbnailBackground()462 int32_t ThumbnailService::GenerateHighlightThumbnailBackground()
463 {
464     ThumbRdbOpt opts = {
465         .store = rdbStorePtr_,
466         .table = PhotoColumn::HIGHLIGHT_TABLE
467     };
468     int32_t err = ThumbnailGenerateHelper::GenerateHighlightThumbnailBackground(opts);
469     if (err != E_OK) {
470         MEDIA_ERR_LOG("GenerateHighlightThumbnailBackground failed : %{public}d", err);
471     }
472     return err;
473 }
474 
TriggerHighlightThumbnail(std::string & id,std::string & tracks,std::string & trigger,std::string & genType)475 int32_t ThumbnailService::TriggerHighlightThumbnail(std::string &id, std::string &tracks, std::string &trigger,
476     std::string &genType)
477 {
478     ThumbRdbOpt opts = {
479         .store = rdbStorePtr_,
480         .table = PhotoColumn::HIGHLIGHT_TABLE
481     };
482     int32_t err = ThumbnailGenerateHelper::TriggerHighlightThumbnail(opts, id, tracks, trigger, genType);
483     if (err != E_OK) {
484         MEDIA_ERR_LOG("TriggerHighlightThumbnail failed : %{public}d", err);
485     }
486     return err;
487 }
488 
RestoreThumbnailDualFrame(const int32_t & restoreAstcCount)489 int32_t ThumbnailService::RestoreThumbnailDualFrame(const int32_t &restoreAstcCount)
490 {
491     ThumbRdbOpt opts = {
492         .store = rdbStorePtr_,
493         .table = PhotoColumn::PHOTOS_TABLE
494     };
495     return ThumbnailGenerateHelper::RestoreAstcDualFrame(opts, restoreAstcCount);
496 }
497 
LcdAging()498 int32_t ThumbnailService::LcdAging()
499 {
500     int32_t err = 0;
501     vector<string> tableList;
502     tableList.emplace_back(PhotoColumn::PHOTOS_TABLE);
503     tableList.emplace_back(AudioColumn::AUDIOS_TABLE);
504     tableList.emplace_back(MEDIALIBRARY_TABLE);
505 
506     for (const auto &tableName : tableList) {
507         ThumbRdbOpt opts = {
508             .store = rdbStorePtr_,
509             .table = tableName,
510         };
511         err = ThumbnailAgingHelper::AgingLcdBatch(opts);
512         if (err != E_OK) {
513             MEDIA_ERR_LOG("AgingLcdBatch failed : %{public}d", err);
514         }
515     }
516 
517     return E_OK;
518 }
519 
HasInvalidateThumbnail(const std::string & id,const std::string & tableName,const std::string & path,const std::string & dateTaken)520 bool ThumbnailService::HasInvalidateThumbnail(const std::string &id,
521     const std::string &tableName, const std::string &path, const std::string &dateTaken)
522 {
523     ThumbRdbOpt opts = {
524         .store = rdbStorePtr_,
525         .table = tableName,
526         .row = id,
527     };
528     ThumbnailData data;
529     data.path = path;
530     data.id = id;
531     data.dateTaken = dateTaken;
532     if (!ThumbnailUtils::DeleteAllThumbFilesAndAstc(opts, data)) {
533         MEDIA_ERR_LOG("Failed to delete thumbnail");
534         return false;
535     }
536     return true;
537 }
538 
DeleteThumbnailDirAndAstc(const std::string & id,const std::string & tableName,const std::string & path,const std::string & dateTaken)539 bool ThumbnailService::DeleteThumbnailDirAndAstc(const std::string &id,
540     const std::string &tableName, const std::string &path, const std::string &dateTaken)
541 {
542     ThumbRdbOpt opts = {
543         .store = rdbStorePtr_,
544         .table = tableName,
545         .row = id,
546     };
547     ThumbnailData data;
548     data.path = path;
549     data.id = id;
550     data.dateTaken = dateTaken;
551     CHECK_AND_RETURN_RET_LOG(ThumbnailUtils::DeleteThumbnailDirAndAstc(opts, data), false,
552         "Failed to delete thumbnail");
553     return true;
554 }
555 
BatchDeleteThumbnailDirAndAstc(const std::string & tableName,const std::vector<std::string> & ids,const std::vector<std::string> & paths,const std::vector<std::string> & dateTakens)556 bool ThumbnailService::BatchDeleteThumbnailDirAndAstc(const std::string &tableName,
557     const std::vector<std::string> &ids, const std::vector<std::string> &paths,
558     const std::vector<std::string> &dateTakens)
559 {
560     ThumbRdbOpt opts = {
561         .store = rdbStorePtr_,
562         .table = tableName,
563     };
564     ThumbnailDataBatch dataBatch;
565     dataBatch.ids = ids;
566     dataBatch.paths = paths;
567     dataBatch.dateTakens = dateTakens;
568     CHECK_AND_RETURN_RET_LOG(ThumbnailUtils::BatchDeleteThumbnailDirAndAstc(opts, dataBatch), false,
569         "Failed to batch delete thumbnail");
570     return true;
571 }
572 
GetAgingDataSize(const int64_t & time,int & count)573 int32_t ThumbnailService::GetAgingDataSize(const int64_t &time, int &count)
574 {
575     int32_t err = 0;
576     vector<string> tableList;
577     tableList.emplace_back(PhotoColumn::PHOTOS_TABLE);
578     tableList.emplace_back(AudioColumn::AUDIOS_TABLE);
579     tableList.emplace_back(MEDIALIBRARY_TABLE);
580 
581     for (const auto &tableName : tableList) {
582         ThumbRdbOpt opts = {
583             .store = rdbStorePtr_,
584             .table = tableName,
585         };
586         int tempCount = 0;
587         err = ThumbnailAgingHelper::GetAgingDataCount(time, true, opts, tempCount);
588         if (err != E_OK) {
589             MEDIA_ERR_LOG("AgingLcdBatch failed : %{public}d", err);
590             return err;
591         }
592         count += tempCount;
593     }
594 
595     return err;
596 }
597 
QueryNewThumbnailCount(const int64_t & time,int32_t & count)598 int32_t ThumbnailService::QueryNewThumbnailCount(const int64_t &time, int32_t &count)
599 {
600     int32_t err = 0;
601     vector<string> tableList;
602     tableList.emplace_back(PhotoColumn::PHOTOS_TABLE);
603     tableList.emplace_back(AudioColumn::AUDIOS_TABLE);
604     tableList.emplace_back(MEDIALIBRARY_TABLE);
605 
606     for (const auto &tableName : tableList) {
607         ThumbRdbOpt opts = {
608             .store = rdbStorePtr_,
609             .table = tableName
610         };
611         int32_t tempCount = 0;
612         err = ThumbnailGenerateHelper::GetNewThumbnailCount(opts, time, tempCount);
613         if (err != E_OK) {
614             MEDIA_ERR_LOG("GetNewThumbnailCount failed : %{public}d", err);
615             return err;
616         }
617         count += tempCount;
618     }
619     return E_OK;
620 }
621 
LocalThumbnailGeneration()622 int32_t ThumbnailService::LocalThumbnailGeneration()
623 {
624     if (!CloudSyncHelper::GetInstance()->isThumbnailGenerationCompleted_) {
625         MEDIA_INFO_LOG("active local thumb genetaion exists");
626         return E_OK;
627     }
628     CloudSyncHelper::GetInstance()->isThumbnailGenerationCompleted_ = false;
629     ThumbRdbOpt opts = {
630         .store = rdbStorePtr_,
631         .table = PhotoColumn::PHOTOS_TABLE,
632     };
633     int err = ThumbnailGenerateHelper::CreateLocalThumbnail(opts);
634     if (err != E_OK) {
635         MEDIA_ERR_LOG("LocalThumbnailGeneration failed : %{public}d", err);
636         return err;
637     }
638     return E_OK;
639 }
640 
CreateAstcCloudDownload(const string & id,bool isCloudInsertTaskPriorityHigh)641 int32_t ThumbnailService::CreateAstcCloudDownload(const string &id, bool isCloudInsertTaskPriorityHigh)
642 {
643     if (!isCloudInsertTaskPriorityHigh && !currentStatusForTask_) {
644         return E_CLOUD_NOT_SUITABLE_FOR_TASK;
645     }
646     ThumbRdbOpt opts = {
647         .store = rdbStorePtr_,
648         .table = PhotoColumn::PHOTOS_TABLE,
649         .fileId = id,
650     };
651 
652     int err = ThumbnailGenerateHelper::CreateAstcCloudDownload(opts, isCloudInsertTaskPriorityHigh);
653     if (err != E_OK) {
654         MEDIA_ERR_LOG("CreateAstcCloudDownload failed : %{public}d", err);
655         return err;
656     }
657     return err;
658 }
659 
CreateAstcMthAndYear(const std::string & id)660 bool ThumbnailService::CreateAstcMthAndYear(const std::string &id)
661 {
662     ThumbRdbOpt opts = {
663         .store = rdbStorePtr_,
664         .table = PhotoColumn::PHOTOS_TABLE,
665         .fileId = id,
666     };
667     int err = ThumbnailGenerateHelper::CreateAstcMthAndYear(opts);
668     if (err != E_OK) {
669         MEDIA_ERR_LOG("CreateAstcMthAndYear failed, err: %{public}d", err);
670         return false;
671     }
672     return true;
673 }
674 
RegenerateThumbnailFromCloud(const string & id)675 bool ThumbnailService::RegenerateThumbnailFromCloud(const string &id)
676 {
677     ThumbRdbOpt opts = {
678         .store = rdbStorePtr_,
679         .table = PhotoColumn::PHOTOS_TABLE,
680         .fileId = id,
681     };
682     int err = ThumbnailGenerateHelper::RegenerateThumbnailFromCloud(opts);
683     if (err != E_OK) {
684         MEDIA_ERR_LOG("RegenerateThumbnailFromCloud failed, err: %{public}d", err);
685         return false;
686     }
687     return true;
688 }
689 
DeleteAstcWithFileIdAndDateTaken(const std::string & fileId,const std::string & dateTaken)690 void ThumbnailService::DeleteAstcWithFileIdAndDateTaken(const std::string &fileId, const std::string &dateTaken)
691 {
692     ThumbnailData data;
693     data.id = fileId;
694     data.dateTaken = dateTaken;
695     ThumbRdbOpt opts;
696 
697     IThumbnailHelper::AddThumbnailGenerateTask(IThumbnailHelper::DeleteMonthAndYearAstc,
698         opts, data, ThumbnailTaskType::BACKGROUND, ThumbnailTaskPriority::HIGH);
699 }
700 
CreateAstcBatchOnDemand(NativeRdb::RdbPredicates & rdbPredicate,int32_t requestId)701 int32_t ThumbnailService::CreateAstcBatchOnDemand(NativeRdb::RdbPredicates &rdbPredicate, int32_t requestId)
702 {
703     if (requestId <= 0) {
704         MEDIA_ERR_LOG("create astc batch failed, invalid request id:%{public}d", requestId);
705         return E_INVALID_VALUES;
706     }
707     CancelAstcBatchTask(requestId - 1);
708     if (GetCurrentTemperatureLevel() >= READY_TEMPERATURE_LEVEL) {
709         isTemperatureHighForReady_ = true;
710         currentRequestId_ = requestId;
711         rdbPredicatePtr_ = make_shared<NativeRdb::RdbPredicates>(rdbPredicate);
712         MEDIA_INFO_LOG("temperature is too high, the operation is suspended");
713         return E_OK;
714     }
715     ThumbRdbOpt opts = {
716         .store = rdbStorePtr_,
717         .table = PhotoColumn::PHOTOS_TABLE
718     };
719     return ThumbnailGenerateHelper::CreateAstcBatchOnDemand(opts, rdbPredicate, requestId);
720 }
721 
CancelAstcBatchTask(int32_t requestId)722 void ThumbnailService::CancelAstcBatchTask(int32_t requestId)
723 {
724     if (requestId <= 0) {
725         MEDIA_ERR_LOG("cancel astc batch failed, invalid request id:%{public}d", requestId);
726         return;
727     }
728 
729     if (isTemperatureHighForReady_) {
730         currentRequestId_ = 0;
731     }
732     MEDIA_INFO_LOG("CancelAstcBatchTask requestId: %{public}d", requestId);
733     std::shared_ptr<ThumbnailGenerateWorker> thumbnailWorker =
734         ThumbnailGenerateWorkerManager::GetInstance().GetThumbnailWorker(ThumbnailTaskType::FOREGROUND);
735     if (thumbnailWorker == nullptr) {
736         MEDIA_ERR_LOG("thumbnailWorker is null");
737         return;
738     }
739     thumbnailWorker->IgnoreTaskByRequestId(requestId);
740 }
741 
UpdateAstcWithNewDateTaken(const std::string & fileId,const std::string & newDateTaken,const std::string & formerDateTaken)742 void ThumbnailService::UpdateAstcWithNewDateTaken(const std::string &fileId, const std::string &newDateTaken,
743     const std::string &formerDateTaken)
744 {
745     ThumbnailData data;
746     data.dateTaken = newDateTaken;
747     ThumbRdbOpt opts = {
748         .store = rdbStorePtr_,
749         .table = PhotoColumn::PHOTOS_TABLE,
750         .row = fileId,
751         .dateTaken = formerDateTaken
752     };
753 
754     IThumbnailHelper::AddThumbnailGenerateTask(IThumbnailHelper::UpdateAstcDateTaken,
755         opts, data, ThumbnailTaskType::BACKGROUND, ThumbnailTaskPriority::HIGH);
756 }
757 
CheckCloudThumbnailDownloadFinish()758 int32_t ThumbnailService::CheckCloudThumbnailDownloadFinish()
759 {
760     if (!ThumbnailUtils::CheckCloudThumbnailDownloadFinish(rdbStorePtr_)) {
761         return E_CLOUD_THUMBNAIL_NOT_DOWNLOAD_FINISH;
762     }
763     return E_OK;
764 }
765 
UpdateThumbnailReadyToFailed(ThumbRdbOpt & opts,std::string id)766 static void UpdateThumbnailReadyToFailed(ThumbRdbOpt &opts, std::string id)
767 {
768     if (opts.store == nullptr || id.empty()) {
769         return;
770     }
771 
772     ValuesBucket values;
773     int changedRows;
774     values.PutLong(PhotoColumn::PHOTO_THUMBNAIL_READY, THUMBNAIL_READY_FAILED);
775     int32_t err = opts.store->Update(changedRows, opts.table, values, MEDIA_DATA_DB_ID + " = ?", vector<string> { id });
776     if (err != NativeRdb::E_OK) {
777         MEDIA_ERR_LOG("RdbStore Update failed! %{public}d", err);
778     }
779 }
780 
IsAstcChangeOldKeyToNewKeySuccess(std::shared_ptr<MediaLibraryKvStore> & monthKvStore,std::shared_ptr<MediaLibraryKvStore> & yearKvStore,const std::string & oldKey,const std::string & newKey)781 static bool IsAstcChangeOldKeyToNewKeySuccess(std::shared_ptr<MediaLibraryKvStore> &monthKvStore,
782     std::shared_ptr<MediaLibraryKvStore> &yearKvStore, const std::string &oldKey, const std::string &newKey)
783 {
784     if (oldKey.compare(newKey) == 0) {
785         MEDIA_INFO_LOG("OldKey: %{public}s is same to newKey", oldKey.c_str());
786         return true;
787     }
788     std::vector<uint8_t> monthValue;
789     std::vector<uint8_t> yearValue;
790     if (yearKvStore->Query(newKey, yearValue) == E_OK) {
791         MEDIA_INFO_LOG("NewKey Astc exists, fileID %{public}s", newKey.c_str());
792         monthKvStore->Delete(oldKey);
793         yearKvStore->Delete(oldKey);
794         return true;
795     }
796     bool isChangeKeySuccess = true;
797     if (monthKvStore->Query(oldKey, monthValue) != E_OK || monthKvStore->Insert(newKey, monthValue) != E_OK ||
798         monthKvStore->Delete(oldKey) != E_OK) {
799         MEDIA_ERR_LOG("MonthValue update failed, fileID %{public}s", newKey.c_str());
800         isChangeKeySuccess = false;
801     }
802     if (yearKvStore->Query(oldKey, yearValue) != E_OK || yearKvStore->Insert(newKey, yearValue) != E_OK ||
803         yearKvStore->Delete(oldKey) != E_OK) {
804         MEDIA_ERR_LOG("YearValue update failed, fileID %{public}s", newKey.c_str());
805         isChangeKeySuccess = false;
806     }
807     return isChangeKeySuccess;
808 }
809 
AstcChangeKeyFromDateAddedToDateTaken()810 void ThumbnailService::AstcChangeKeyFromDateAddedToDateTaken()
811 {
812     if (rdbStorePtr_ == nullptr) {
813         MEDIA_ERR_LOG("RdbStorePtr is null");
814         return;
815     }
816     vector<ThumbnailData> infos;
817     if (!ThumbnailUtils::QueryOldKeyAstcInfos(rdbStorePtr_, PhotoColumn::PHOTOS_TABLE, infos)) {
818         return;
819     }
820     MEDIA_INFO_LOG("Old key astc data size: %{public}d", static_cast<int>(infos.size()));
821     if (infos.empty()) {
822         return;
823     }
824     ThumbRdbOpt opts = {
825         .store = rdbStorePtr_,
826         .table = PhotoColumn::PHOTOS_TABLE,
827     };
828 
829     auto monthKvStore = MediaLibraryKvStoreManager::GetInstance()
830         .GetKvStore(KvStoreRoleType::OWNER, KvStoreValueType::MONTH_ASTC);
831     if (monthKvStore == nullptr) {
832         MEDIA_ERR_LOG("Init month kvStore failed");
833         return;
834     }
835     auto yearKvStore = MediaLibraryKvStoreManager::GetInstance()
836         .GetKvStore(KvStoreRoleType::OWNER, KvStoreValueType::YEAR_ASTC);
837     if (yearKvStore == nullptr) {
838         MEDIA_ERR_LOG("Init year kvStore failed");
839         return;
840     }
841     for (size_t i = 0; i < infos.size(); i++) {
842         std::string oldKey;
843         std::string newKey;
844         if (!MediaFileUtils::GenerateKvStoreKey(infos[i].id, infos[i].dateAdded, oldKey) ||
845             !MediaFileUtils::GenerateKvStoreKey(infos[i].id, infos[i].dateTaken, newKey)) {
846             continue;
847         }
848         if (!IsAstcChangeOldKeyToNewKeySuccess(monthKvStore, yearKvStore, oldKey, newKey)) {
849             monthKvStore->Delete(oldKey);
850             yearKvStore->Delete(oldKey);
851             UpdateThumbnailReadyToFailed(opts, infos[i].id);
852         }
853     }
854     MEDIA_INFO_LOG("PerformKvStoreChangeKeyTask End");
855 }
856 
UpdateCurrentStatusForTask(const bool & currentStatusForTask)857 void ThumbnailService::UpdateCurrentStatusForTask(const bool &currentStatusForTask)
858 {
859     currentStatusForTask_ = currentStatusForTask;
860 }
861 
GetCurrentStatusForTask()862 bool ThumbnailService::GetCurrentStatusForTask()
863 {
864     return currentStatusForTask_;
865 }
866 
NotifyTempStatusForReady(const int32_t & currentTemperatureLevel)867 void ThumbnailService::NotifyTempStatusForReady(const int32_t &currentTemperatureLevel)
868 {
869     currentTemperatureLevel_ = currentTemperatureLevel;
870     if (isTemperatureHighForReady_ && currentTemperatureLevel_ < READY_TEMPERATURE_LEVEL) {
871         MEDIA_INFO_LOG("temperature is normal, the opreation is resumed");
872         isTemperatureHighForReady_ = false;
873         if (rdbPredicatePtr_ != nullptr && currentRequestId_ > 0) {
874             CreateAstcBatchOnDemand(*rdbPredicatePtr_, currentRequestId_);
875         }
876     }
877 }
878 
GetCurrentTemperatureLevel()879 int32_t ThumbnailService::GetCurrentTemperatureLevel()
880 {
881     return currentTemperatureLevel_;
882 }
883 
CheckLcdSizeAndUpdateStatus()884 void ThumbnailService::CheckLcdSizeAndUpdateStatus()
885 {
886     ThumbRdbOpt opts = {
887         .store = rdbStorePtr_,
888         .table = PhotoColumn::PHOTOS_TABLE
889     };
890     int32_t err = ThumbnailGenerateHelper::CheckLcdSizeAndUpdateStatus(opts);
891     if (err != E_OK) {
892         MEDIA_ERR_LOG("CheckLcdSizeAndUpdateStatus failed: %{public}d", err);
893     }
894 }
895 
RepairExifRotateBackground()896 int32_t ThumbnailService::RepairExifRotateBackground()
897 {
898     ThumbRdbOpt opts = {
899         .store = rdbStorePtr_,
900         .table = PhotoColumn::PHOTOS_TABLE
901     };
902     int32_t err = ThumbnailGenerateHelper::RepairExifRotateBackground(opts);
903     CHECK_AND_RETURN_RET_LOG(err == E_OK, err, "RepairNoExifRotateBackground failed : %{public}d", err);
904     return E_OK;
905 }
906 
FixThumbnailExifRotateAfterDownloadAsset(const std::string & fileId)907 int32_t ThumbnailService::FixThumbnailExifRotateAfterDownloadAsset(const std::string &fileId)
908 {
909     ThumbRdbOpt opts = {
910         .store = rdbStorePtr_,
911         .table = PhotoColumn::PHOTOS_TABLE,
912         .fileId = fileId,
913     };
914     int err = ThumbnailGenerateHelper::FixThumbnailExifRotateAfterDownloadAsset(opts);
915     CHECK_AND_RETURN_RET_LOG(err == E_OK, err, "FixThumbnailExifRotateAfterDownloadAsset failed, err: %{public}d", err);
916     return E_OK;
917 }
918 } // namespace Media
919 } // namespace OHOS
920