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 ¤tStatusForTask)
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 ¤tTemperatureLevel)
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