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