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