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