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