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