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 "cloud_sync_helper.h"
20 #include "display_manager.h"
21 #include "dfx_utils.h"
22 #include "ipc_skeleton.h"
23 #include "ithumbnail_helper.h"
24 #include "media_column.h"
25 #include "media_file_utils.h"
26 #include "medialibrary_async_worker.h"
27 #include "medialibrary_db_const.h"
28 #include "medialibrary_errno.h"
29 #include "medialibrary_kvstore_manager.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_generation_post_process.h"
39 #include "thumbnail_image_framework_utils.h"
40 #include "thumbnail_source_loading.h"
41 #include "thumbnail_uri_utils.h"
42 #include "post_event_utils.h"
43 #ifdef HAS_THERMAL_MANAGER_PART
44 #include "thermal_mgr_client.h"
45 #endif
46
47 using namespace std;
48 using namespace OHOS::NativeRdb;
49 using namespace OHOS::AbilityRuntime;
50
51 namespace OHOS {
52 namespace Media {
53 std::shared_ptr<ThumbnailService> ThumbnailService::thumbnailServiceInstance_{nullptr};
54 std::mutex ThumbnailService::instanceLock_;
ThumbnailService(void)55 ThumbnailService::ThumbnailService(void)
56 {
57 rdbStorePtr_ = nullptr;
58 rdbPredicatePtr_ = nullptr;
59 }
60
GetInstance()61 shared_ptr<ThumbnailService> ThumbnailService::GetInstance()
62 {
63 if (thumbnailServiceInstance_ == nullptr) {
64 std::lock_guard<std::mutex> lockGuard(instanceLock_);
65 if (thumbnailServiceInstance_ != nullptr) {
66 return thumbnailServiceInstance_;
67 }
68 thumbnailServiceInstance_ = shared_ptr<ThumbnailService>(new ThumbnailService());
69 }
70
71 return thumbnailServiceInstance_;
72 }
73
GetDefaultWindowSize(Size & size)74 static bool GetDefaultWindowSize(Size &size)
75 {
76 auto &displayMgr = OHOS::Rosen::DisplayManager::GetInstance();
77 auto display = displayMgr.GetDefaultDisplay();
78 if (display == nullptr) {
79 MEDIA_ERR_LOG("Get display window size failed");
80 return false;
81 }
82 size.width = display->GetWidth();
83 size.height = display->GetHeight();
84 if (size.width <= 0) {
85 MEDIA_WARN_LOG("Get Default display width is invalid %{public}d", size.width);
86 size.width = DEFAULT_LCD_SIZE;
87 }
88 if (size.height <= 0) {
89 MEDIA_WARN_LOG("Get Default display height is invalid %{public}d", size.height);
90 size.height = DEFAULT_LCD_SIZE;
91 }
92 MEDIA_INFO_LOG("display window size::w %{public}d, h %{public}d", size.width, size.height);
93
94 return true;
95 }
96
CheckSizeValid()97 bool ThumbnailService::CheckSizeValid()
98 {
99 if (!isScreenSizeInit_) {
100 if (!GetDefaultWindowSize(screenSize_)) {
101 return false;
102 }
103 isScreenSizeInit_ = true;
104 }
105 return true;
106 }
107
Init(const shared_ptr<MediaLibraryRdbStore> rdbStore,const shared_ptr<Context> & context)108 void ThumbnailService::Init(const shared_ptr<MediaLibraryRdbStore> rdbStore,
109 const shared_ptr<Context> &context)
110 {
111 rdbStorePtr_ = rdbStore;
112 context_ = context;
113
114 if (!GetDefaultWindowSize(screenSize_)) {
115 MEDIA_ERR_LOG("GetDefaultWindowSize failed");
116 } else {
117 isScreenSizeInit_ = true;
118 }
119 }
120
ReleaseService()121 void ThumbnailService::ReleaseService()
122 {
123 StopAllWorker();
124 rdbStorePtr_ = nullptr;
125 context_ = nullptr;
126 thumbnailServiceInstance_ = nullptr;
127 }
128
129 #ifdef MEDIALIBRARY_COMPATIBILITY
GetPathFromDb(const shared_ptr<MediaLibraryRdbStore> rdbStorePtr,const string & fileId,const string & table,string & path)130 static int32_t GetPathFromDb(const shared_ptr<MediaLibraryRdbStore> rdbStorePtr, const string &fileId,
131 const string &table, string &path)
132 {
133 if (rdbStorePtr == nullptr) {
134 VariantMap map = {{KEY_ERR_FILE, __FILE__}, {KEY_ERR_LINE, __LINE__}, {KEY_ERR_CODE, E_HAS_DB_ERROR},
135 {KEY_OPT_TYPE, OptType::THUMB}};
136 PostEventUtils::GetInstance().PostErrorProcess(ErrType::DB_OPT_ERR, map);
137 return E_HAS_DB_ERROR;
138 }
139 if (!all_of(fileId.begin(), fileId.end(), ::isdigit)) {
140 return E_INVALID_FILEID;
141 }
142 string querySql = "SELECT " + MediaColumn::MEDIA_FILE_PATH + " FROM " + table +
143 " WHERE " + MediaColumn::MEDIA_ID + "=?";
144 vector<string> selectionArgs = { fileId };
145 auto resultSet = rdbStorePtr->QuerySql(querySql, selectionArgs);
146 if (resultSet == nullptr || resultSet->GoToFirstRow() != NativeRdb::E_OK) {
147 VariantMap map = {{KEY_ERR_FILE, __FILE__}, {KEY_ERR_LINE, __LINE__}, {KEY_ERR_CODE, E_HAS_DB_ERROR},
148 {KEY_OPT_TYPE, OptType::THUMB}};
149 PostEventUtils::GetInstance().PostErrorProcess(ErrType::DB_OPT_ERR, map);
150 return E_HAS_DB_ERROR;
151 }
152 path = GetStringVal(MediaColumn::MEDIA_FILE_PATH, resultSet);
153 if (path.empty()) {
154 return E_INVALID_PATH;
155 }
156 return E_OK;
157 }
158 #endif
159
GetThumbFd(const string & path,const string & table,const string & id,const string & uri,const Size & size,bool isAstc)160 int ThumbnailService::GetThumbFd(const string &path, const string &table, const string &id, const string &uri,
161 const Size &size, bool isAstc)
162 {
163 ThumbRdbOpt opts = {
164 .store = rdbStorePtr_,
165 .path = path,
166 .table = table,
167 .row = id,
168 .uri = uri,
169 };
170 ThumbnailType thumbType = GetThumbType(size.width, size.height, isAstc);
171 if (thumbType != ThumbnailType::THUMB && thumbType != ThumbnailType::THUMB_ASTC) {
172 opts.screenSize = screenSize_;
173 }
174 ThumbnailData data;
175 int fd = ThumbnailGenerateHelper::GetThumbnailPixelMap(data, opts, thumbType);
176 CHECK_AND_PRINT_LOG(fd >= 0, "GetThumbnailPixelMap failed : %{public}d", fd);
177 int32_t err = ThumbnailGenerationPostProcess::PostProcess(data, opts);
178 CHECK_AND_PRINT_LOG(err == E_OK, "PostProcess failed! err %{public}d", err);
179 return fd;
180 }
181
GetKeyFrameThumbFd(const string & path,const string & table,const string & id,const string & uri,int32_t & beginStamp,int32_t & type)182 int ThumbnailService::GetKeyFrameThumbFd(const string &path, const string &table, const string &id, const string &uri,
183 int32_t &beginStamp, int32_t &type)
184 {
185 ThumbRdbOpt opts = {
186 .store = rdbStorePtr_,
187 .path = path,
188 .table = table,
189 .row = id,
190 .uri = uri,
191 };
192
193 int fd = ThumbnailGenerateHelper::GetKeyFrameThumbnailPixelMap(opts, beginStamp, type);
194 if (fd < 0) {
195 MEDIA_ERR_LOG("GetKeyFrameThumbnailPixelMap failed : %{public}d", fd);
196 }
197 return fd;
198 }
199
GetThumbnailFd(const string & uri,bool isAstc)200 int ThumbnailService::GetThumbnailFd(const string &uri, bool isAstc)
201 {
202 if (!CheckSizeValid()) {
203 MEDIA_ERR_LOG("GetThumbnailFd failed for invaild size, uri: %{public}s", uri.c_str());
204 return E_THUMBNAIL_INVALID_SIZE;
205 }
206 string id;
207 string path;
208 string table;
209 Size size;
210 if (!ThumbnailUriUtils::ParseThumbnailInfo(uri, id, size, path, table)) {
211 VariantMap map = {{KEY_ERR_FILE, __FILE__}, {KEY_ERR_LINE, __LINE__}, {KEY_ERR_CODE, E_FAIL},
212 {KEY_OPT_FILE, uri}, {KEY_OPT_TYPE, OptType::THUMB}};
213 PostEventUtils::GetInstance().PostErrorProcess(ErrType::FILE_OPT_ERR, map);
214 return E_FAIL;
215 }
216 #ifdef MEDIALIBRARY_COMPATIBILITY
217 if (path.empty()) {
218 int32_t errCode = GetPathFromDb(rdbStorePtr_, id, table, path);
219 if (errCode != E_OK) {
220 VariantMap map = {{KEY_ERR_FILE, __FILE__}, {KEY_ERR_LINE, __LINE__}, {KEY_ERR_CODE, errCode},
221 {KEY_OPT_TYPE, OptType::THUMB}};
222 PostEventUtils::GetInstance().PostErrorProcess(ErrType::DB_OPT_ERR, map);
223 MEDIA_ERR_LOG("GetPathFromDb failed, errCode = %{public}d", errCode);
224 return errCode;
225 }
226 }
227 #endif
228 return GetThumbFd(path, table, id, uri, size, isAstc);
229 }
230
GetKeyFrameThumbnailFd(const string & uri,bool isAstc)231 int ThumbnailService::GetKeyFrameThumbnailFd(const string &uri, bool isAstc)
232 {
233 if (!CheckSizeValid()) {
234 MEDIA_ERR_LOG("GetKeyFrameThumbnailFd failed for invaild size, uri: %{public}s", uri.c_str());
235 return E_THUMBNAIL_INVALID_SIZE;
236 }
237 string id;
238 string path;
239 int32_t beginStamp;
240 int32_t type;
241 if (!ThumbnailUriUtils::ParseKeyFrameThumbnailInfo(uri, id, beginStamp, type, path)) {
242 MEDIA_ERR_LOG("failed to parse keyFrame thumbnail info");
243 return E_FAIL;
244 }
245 string table = PhotoColumn::HIGHLIGHT_TABLE;
246 #ifdef MEDIALIBRARY_COMPATIBILITY
247 if (path.empty()) {
248 int32_t errCode = GetPathFromDb(rdbStorePtr_, id, table, path);
249 if (errCode != E_OK) {
250 MEDIA_ERR_LOG("GetPathFromDb failed, errCode = %{public}d", errCode);
251 return errCode;
252 }
253 }
254 #endif
255 return GetKeyFrameThumbFd(path, table, id, uri, beginStamp, type);
256 }
257
ParseThumbnailParam(const std::string & uri,string & fileId,string & networkId,string & tableName)258 int32_t ThumbnailService::ParseThumbnailParam(const std::string &uri, string &fileId, string &networkId,
259 string &tableName)
260 {
261 if (!CheckSizeValid()) {
262 VariantMap map = {{KEY_ERR_FILE, __FILE__}, {KEY_ERR_LINE, __LINE__}, {KEY_ERR_CODE, E_THUMBNAIL_INVALID_SIZE},
263 {KEY_OPT_FILE, uri}, {KEY_OPT_TYPE, OptType::THUMB}};
264 PostEventUtils::GetInstance().PostErrorProcess(ErrType::FILE_OPT_ERR, map);
265 return E_THUMBNAIL_INVALID_SIZE;
266 }
267 if (!ThumbnailUriUtils::ParseFileUri(uri, fileId, networkId, tableName)) {
268 VariantMap map = {{KEY_ERR_FILE, __FILE__}, {KEY_ERR_LINE, __LINE__}, {KEY_ERR_CODE, E_ERR},
269 {KEY_OPT_FILE, uri}, {KEY_OPT_TYPE, OptType::THUMB}};
270 PostEventUtils::GetInstance().PostErrorProcess(ErrType::FILE_OPT_ERR, map);
271 MEDIA_ERR_LOG("ParseThumbnailInfo faild");
272 return E_ERR;
273 }
274 return E_OK;
275 }
276
CreateThumbnailPastDirtyDataFix(const std::string & fileId)277 int32_t ThumbnailService::CreateThumbnailPastDirtyDataFix(const std::string &fileId)
278 {
279 ThumbRdbOpt opts = {
280 .store = rdbStorePtr_,
281 .table = PhotoColumn::PHOTOS_TABLE,
282 .row = fileId
283 };
284 int err = 0;
285 ThumbnailData data;
286
287 ThumbnailUtils::QueryThumbnailDataFromFileId(opts, fileId, data, err);
288 CHECK_AND_RETURN_RET_LOG(err == E_OK, err, "QueryThumbnailDataFromFileId failed, path: %{public}s",
289 DfxUtils::GetSafePath(data.path).c_str());
290 data.loaderOpts.loadingStates = SourceLoader::LOCAL_SOURCE_LOADING_STATES;
291 data.isLocalFile = true;
292 IThumbnailHelper::AddThumbnailGenerateTask(
293 IThumbnailHelper::CreateThumbnail, opts, data, ThumbnailTaskType::FOREGROUND, ThumbnailTaskPriority::LOW);
294 return E_OK;
295 }
296
CreateLcdPastDirtyDataFix(const std::string & fileId)297 int32_t ThumbnailService::CreateLcdPastDirtyDataFix(const std::string &fileId)
298 {
299 ThumbRdbOpt opts = {
300 .store = rdbStorePtr_,
301 .table = PhotoColumn::PHOTOS_TABLE,
302 .row = fileId
303 };
304 int err = 0;
305 ThumbnailData data;
306 data.createLowQulityLcd = true;
307
308 ThumbnailUtils::QueryThumbnailDataFromFileId(opts, fileId, data, err);
309 CHECK_AND_RETURN_RET_LOG(err == E_OK, err, "QueryThumbnailDataFromFileId failed, path: %{public}s",
310 DfxUtils::GetSafePath(data.path).c_str());
311 data.loaderOpts.loadingStates = SourceLoader::LOCAL_SOURCE_LOADING_STATES;
312 data.isLocalFile = true;
313 IThumbnailHelper::AddThumbnailGenerateTask(
314 IThumbnailHelper::CreateLcd, opts, data, ThumbnailTaskType::FOREGROUND, ThumbnailTaskPriority::LOW);
315 return E_OK;
316 }
317
CreateThumbnailFileScaned(const std::string & uri,const string & path,bool isSync)318 int32_t ThumbnailService::CreateThumbnailFileScaned(const std::string &uri, const string &path, bool isSync)
319 {
320 string fileId;
321 string networkId;
322 string tableName;
323
324 int err = ParseThumbnailParam(uri, fileId, networkId, tableName);
325 if (err != E_OK) {
326 VariantMap map = {{KEY_ERR_FILE, __FILE__}, {KEY_ERR_LINE, __LINE__}, {KEY_ERR_CODE, E_ERR},
327 {KEY_OPT_FILE, uri}, {KEY_OPT_TYPE, OptType::THUMB}};
328 PostEventUtils::GetInstance().PostErrorProcess(ErrType::FILE_OPT_ERR, map);
329 return err;
330 }
331
332 std::string dateTaken = ThumbnailUriUtils::GetDateTakenFromUri(uri);
333 std::string dateModified = ThumbnailUriUtils::GetDateModifiedFromUri(uri);
334 std::string fileUri = ThumbnailUriUtils::GetFileUriFromUri(uri);
335 ThumbRdbOpt opts = {
336 .store = rdbStorePtr_,
337 .path = path,
338 .table = tableName,
339 .row = fileId,
340 .dateTaken = dateTaken,
341 .dateModified = dateModified,
342 .fileUri = fileUri,
343 .screenSize = screenSize_
344 };
345
346 err = ThumbnailGenerateHelper::CreateThumbnailFileScaned(opts, isSync);
347 if (err != E_OK) {
348 MEDIA_ERR_LOG("CreateThumbnailFileScaned failed : %{public}d", err);
349 VariantMap map = {{KEY_ERR_FILE, __FILE__}, {KEY_ERR_LINE, __LINE__}, {KEY_ERR_CODE, err},
350 {KEY_OPT_FILE, uri}, {KEY_OPT_TYPE, OptType::THUMB}};
351 PostEventUtils::GetInstance().PostErrorProcess(ErrType::FILE_OPT_ERR, map);
352 return err;
353 }
354 return E_OK;
355 }
356
CreateThumbnailFileScanedWithPicture(const std::string & uri,const string & path,std::shared_ptr<Picture> originalPhotoPicture,bool isSync)357 int32_t ThumbnailService::CreateThumbnailFileScanedWithPicture(const std::string &uri, const string &path,
358 std::shared_ptr<Picture> originalPhotoPicture, bool isSync)
359 {
360 CHECK_AND_RETURN_RET_LOG(!uri.empty(), E_ERR, "Uri is empty");
361 string fileId;
362 string networkId;
363 string tableName;
364
365 int err = ParseThumbnailParam(uri, fileId, networkId, tableName);
366 CHECK_AND_RETURN_RET_LOG(err == E_OK, err, "ParseThumbnailParam failed, err:%{public}d", err);
367
368 std::string dateTaken = ThumbnailUriUtils::GetDateTakenFromUri(uri);
369 std::string dateModified = ThumbnailUriUtils::GetDateModifiedFromUri(uri);
370 std::string fileUri = ThumbnailUriUtils::GetFileUriFromUri(uri);
371 ThumbRdbOpt opts = {
372 .store = rdbStorePtr_,
373 .path = path,
374 .table = tableName,
375 .row = fileId,
376 .dateTaken = dateTaken,
377 .dateModified = dateModified,
378 .fileUri = fileUri,
379 .screenSize = screenSize_
380 };
381
382 err = ThumbnailGenerateHelper::CreateThumbnailFileScanedWithPicture(opts, originalPhotoPicture, isSync);
383 CHECK_AND_RETURN_RET_LOG(err == E_OK, err, "CreateThumbnailFileScaned failed:%{public}d", err);
384 return E_OK;
385 }
386
InterruptBgworker()387 void ThumbnailService::InterruptBgworker()
388 {
389 std::shared_ptr<ThumbnailGenerateWorker> thumbnailWorker =
390 ThumbnailGenerateWorkerManager::GetInstance().GetThumbnailWorker(ThumbnailTaskType::BACKGROUND);
391 if (thumbnailWorker == nullptr) {
392 MEDIA_ERR_LOG("thumbnailWorker is null");
393 return;
394 }
395 thumbnailWorker->ReleaseTaskQueue(ThumbnailTaskPriority::LOW);
396 }
397
StopAllWorker()398 void ThumbnailService::StopAllWorker()
399 {
400 shared_ptr<MediaLibraryAsyncWorker> asyncWorker = MediaLibraryAsyncWorker::GetInstance();
401 if (asyncWorker != nullptr) {
402 asyncWorker->Stop();
403 }
404
405 ThumbnailGenerateWorkerManager::GetInstance().ClearAllTask();
406 }
407
GenerateThumbnailBackground()408 int32_t ThumbnailService::GenerateThumbnailBackground()
409 {
410 if (!CheckSizeValid()) {
411 return E_THUMBNAIL_INVALID_SIZE;
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 .table = tableName
423 };
424
425 if ((tableName == PhotoColumn::PHOTOS_TABLE) && ThumbnailImageFrameWorkUtils::IsSupportGenAstc()) {
426 // CreateAstcBackground contains thumbnails created.
427 err = ThumbnailGenerateHelper::CreateAstcBackground(opts);
428 if (err != E_OK) {
429 MEDIA_ERR_LOG("CreateAstcBackground failed : %{public}d", err);
430 }
431 } else {
432 err = ThumbnailGenerateHelper::CreateThumbnailBackground(opts);
433 if (err != E_OK) {
434 MEDIA_ERR_LOG("CreateThumbnailBackground failed : %{public}d", err);
435 }
436 }
437
438 if (tableName == PhotoColumn::PHOTOS_TABLE) {
439 err = ThumbnailGenerateHelper::CreateLcdBackground(opts);
440 if (err != E_OK) {
441 MEDIA_ERR_LOG("CreateLcdBackground failed : %{public}d", err);
442 }
443 }
444 }
445
446 return err;
447 }
448
UpgradeThumbnailBackground(bool isWifiConnected)449 int32_t ThumbnailService::UpgradeThumbnailBackground(bool isWifiConnected)
450 {
451 ThumbRdbOpt opts = {
452 .store = rdbStorePtr_,
453 .table = PhotoColumn::PHOTOS_TABLE
454 };
455 int32_t err = ThumbnailGenerateHelper::UpgradeThumbnailBackground(opts, isWifiConnected);
456 if (err != E_OK) {
457 MEDIA_ERR_LOG("UpgradeThumbnailBackground failed : %{public}d", err);
458 }
459 return err;
460 }
461
GenerateHighlightThumbnailBackground()462 int32_t ThumbnailService::GenerateHighlightThumbnailBackground()
463 {
464 ThumbRdbOpt opts = {
465 .store = rdbStorePtr_,
466 .table = PhotoColumn::HIGHLIGHT_TABLE
467 };
468 int32_t err = ThumbnailGenerateHelper::GenerateHighlightThumbnailBackground(opts);
469 if (err != E_OK) {
470 MEDIA_ERR_LOG("GenerateHighlightThumbnailBackground failed : %{public}d", err);
471 }
472 return err;
473 }
474
TriggerHighlightThumbnail(std::string & id,std::string & tracks,std::string & trigger,std::string & genType)475 int32_t ThumbnailService::TriggerHighlightThumbnail(std::string &id, std::string &tracks, std::string &trigger,
476 std::string &genType)
477 {
478 ThumbRdbOpt opts = {
479 .store = rdbStorePtr_,
480 .table = PhotoColumn::HIGHLIGHT_TABLE
481 };
482 int32_t err = ThumbnailGenerateHelper::TriggerHighlightThumbnail(opts, id, tracks, trigger, genType);
483 if (err != E_OK) {
484 MEDIA_ERR_LOG("TriggerHighlightThumbnail failed : %{public}d", err);
485 }
486 return err;
487 }
488
RestoreThumbnailDualFrame(const int32_t & restoreAstcCount)489 int32_t ThumbnailService::RestoreThumbnailDualFrame(const int32_t &restoreAstcCount)
490 {
491 ThumbRdbOpt opts = {
492 .store = rdbStorePtr_,
493 .table = PhotoColumn::PHOTOS_TABLE
494 };
495 return ThumbnailGenerateHelper::RestoreAstcDualFrame(opts, restoreAstcCount);
496 }
497
LcdAging()498 int32_t ThumbnailService::LcdAging()
499 {
500 int32_t err = 0;
501 vector<string> tableList;
502 tableList.emplace_back(PhotoColumn::PHOTOS_TABLE);
503 tableList.emplace_back(AudioColumn::AUDIOS_TABLE);
504 tableList.emplace_back(MEDIALIBRARY_TABLE);
505
506 for (const auto &tableName : tableList) {
507 ThumbRdbOpt opts = {
508 .store = rdbStorePtr_,
509 .table = tableName,
510 };
511 err = ThumbnailAgingHelper::AgingLcdBatch(opts);
512 if (err != E_OK) {
513 MEDIA_ERR_LOG("AgingLcdBatch failed : %{public}d", err);
514 }
515 }
516
517 return E_OK;
518 }
519
HasInvalidateThumbnail(const std::string & id,const std::string & tableName,const std::string & path,const std::string & dateTaken)520 bool ThumbnailService::HasInvalidateThumbnail(const std::string &id,
521 const std::string &tableName, const std::string &path, const std::string &dateTaken)
522 {
523 ThumbRdbOpt opts = {
524 .store = rdbStorePtr_,
525 .table = tableName,
526 .row = id,
527 };
528 ThumbnailData data;
529 data.path = path;
530 data.id = id;
531 data.dateTaken = dateTaken;
532 if (!ThumbnailUtils::DeleteAllThumbFilesAndAstc(opts, data)) {
533 MEDIA_ERR_LOG("Failed to delete thumbnail");
534 return false;
535 }
536 return true;
537 }
538
DeleteThumbnailDirAndAstc(const std::string & id,const std::string & tableName,const std::string & path,const std::string & dateTaken)539 bool ThumbnailService::DeleteThumbnailDirAndAstc(const std::string &id,
540 const std::string &tableName, const std::string &path, const std::string &dateTaken)
541 {
542 ThumbRdbOpt opts = {
543 .store = rdbStorePtr_,
544 .table = tableName,
545 .row = id,
546 };
547 ThumbnailData data;
548 data.path = path;
549 data.id = id;
550 data.dateTaken = dateTaken;
551 CHECK_AND_RETURN_RET_LOG(ThumbnailUtils::DeleteThumbnailDirAndAstc(opts, data), false,
552 "Failed to delete thumbnail");
553 return true;
554 }
555
BatchDeleteThumbnailDirAndAstc(const std::string & tableName,const std::vector<std::string> & ids,const std::vector<std::string> & paths,const std::vector<std::string> & dateTakens)556 bool ThumbnailService::BatchDeleteThumbnailDirAndAstc(const std::string &tableName,
557 const std::vector<std::string> &ids, const std::vector<std::string> &paths,
558 const std::vector<std::string> &dateTakens)
559 {
560 ThumbRdbOpt opts = {
561 .store = rdbStorePtr_,
562 .table = tableName,
563 };
564 ThumbnailDataBatch dataBatch;
565 dataBatch.ids = ids;
566 dataBatch.paths = paths;
567 dataBatch.dateTakens = dateTakens;
568 CHECK_AND_RETURN_RET_LOG(ThumbnailUtils::BatchDeleteThumbnailDirAndAstc(opts, dataBatch), false,
569 "Failed to batch delete thumbnail");
570 return true;
571 }
572
GetAgingDataSize(const int64_t & time,int & count)573 int32_t ThumbnailService::GetAgingDataSize(const int64_t &time, int &count)
574 {
575 int32_t err = 0;
576 vector<string> tableList;
577 tableList.emplace_back(PhotoColumn::PHOTOS_TABLE);
578 tableList.emplace_back(AudioColumn::AUDIOS_TABLE);
579 tableList.emplace_back(MEDIALIBRARY_TABLE);
580
581 for (const auto &tableName : tableList) {
582 ThumbRdbOpt opts = {
583 .store = rdbStorePtr_,
584 .table = tableName,
585 };
586 int tempCount = 0;
587 err = ThumbnailAgingHelper::GetAgingDataCount(time, true, opts, tempCount);
588 if (err != E_OK) {
589 MEDIA_ERR_LOG("AgingLcdBatch failed : %{public}d", err);
590 return err;
591 }
592 count += tempCount;
593 }
594
595 return err;
596 }
597
QueryNewThumbnailCount(const int64_t & time,int32_t & count)598 int32_t ThumbnailService::QueryNewThumbnailCount(const int64_t &time, int32_t &count)
599 {
600 int32_t err = 0;
601 vector<string> tableList;
602 tableList.emplace_back(PhotoColumn::PHOTOS_TABLE);
603 tableList.emplace_back(AudioColumn::AUDIOS_TABLE);
604 tableList.emplace_back(MEDIALIBRARY_TABLE);
605
606 for (const auto &tableName : tableList) {
607 ThumbRdbOpt opts = {
608 .store = rdbStorePtr_,
609 .table = tableName
610 };
611 int32_t tempCount = 0;
612 err = ThumbnailGenerateHelper::GetNewThumbnailCount(opts, time, tempCount);
613 if (err != E_OK) {
614 MEDIA_ERR_LOG("GetNewThumbnailCount failed : %{public}d", err);
615 return err;
616 }
617 count += tempCount;
618 }
619 return E_OK;
620 }
621
LocalThumbnailGeneration()622 int32_t ThumbnailService::LocalThumbnailGeneration()
623 {
624 if (!CloudSyncHelper::GetInstance()->isThumbnailGenerationCompleted_) {
625 MEDIA_INFO_LOG("active local thumb genetaion exists");
626 return E_OK;
627 }
628 CloudSyncHelper::GetInstance()->isThumbnailGenerationCompleted_ = false;
629 ThumbRdbOpt opts = {
630 .store = rdbStorePtr_,
631 .table = PhotoColumn::PHOTOS_TABLE,
632 };
633 int err = ThumbnailGenerateHelper::CreateLocalThumbnail(opts);
634 if (err != E_OK) {
635 MEDIA_ERR_LOG("LocalThumbnailGeneration failed : %{public}d", err);
636 return err;
637 }
638 return E_OK;
639 }
640
CreateAstcCloudDownload(const string & id,bool isCloudInsertTaskPriorityHigh)641 int32_t ThumbnailService::CreateAstcCloudDownload(const string &id, bool isCloudInsertTaskPriorityHigh)
642 {
643 if (!isCloudInsertTaskPriorityHigh && !currentStatusForTask_) {
644 return E_CLOUD_NOT_SUITABLE_FOR_TASK;
645 }
646 ThumbRdbOpt opts = {
647 .store = rdbStorePtr_,
648 .table = PhotoColumn::PHOTOS_TABLE,
649 .fileId = id,
650 };
651
652 int err = ThumbnailGenerateHelper::CreateAstcCloudDownload(opts, isCloudInsertTaskPriorityHigh);
653 if (err != E_OK) {
654 MEDIA_ERR_LOG("CreateAstcCloudDownload failed : %{public}d", err);
655 return err;
656 }
657 return err;
658 }
659
CreateAstcMthAndYear(const std::string & id)660 bool ThumbnailService::CreateAstcMthAndYear(const std::string &id)
661 {
662 ThumbRdbOpt opts = {
663 .store = rdbStorePtr_,
664 .table = PhotoColumn::PHOTOS_TABLE,
665 .fileId = id,
666 };
667 int err = ThumbnailGenerateHelper::CreateAstcMthAndYear(opts);
668 if (err != E_OK) {
669 MEDIA_ERR_LOG("CreateAstcMthAndYear failed, err: %{public}d", err);
670 return false;
671 }
672 return true;
673 }
674
RegenerateThumbnailFromCloud(const string & id)675 bool ThumbnailService::RegenerateThumbnailFromCloud(const string &id)
676 {
677 ThumbRdbOpt opts = {
678 .store = rdbStorePtr_,
679 .table = PhotoColumn::PHOTOS_TABLE,
680 .fileId = id,
681 };
682 int err = ThumbnailGenerateHelper::RegenerateThumbnailFromCloud(opts);
683 if (err != E_OK) {
684 MEDIA_ERR_LOG("RegenerateThumbnailFromCloud failed, err: %{public}d", err);
685 return false;
686 }
687 return true;
688 }
689
DeleteAstcWithFileIdAndDateTaken(const std::string & fileId,const std::string & dateTaken)690 void ThumbnailService::DeleteAstcWithFileIdAndDateTaken(const std::string &fileId, const std::string &dateTaken)
691 {
692 ThumbnailData data;
693 data.id = fileId;
694 data.dateTaken = dateTaken;
695 ThumbRdbOpt opts;
696
697 IThumbnailHelper::AddThumbnailGenerateTask(IThumbnailHelper::DeleteMonthAndYearAstc,
698 opts, data, ThumbnailTaskType::BACKGROUND, ThumbnailTaskPriority::HIGH);
699 }
700
CreateAstcBatchOnDemand(NativeRdb::RdbPredicates & rdbPredicate,int32_t requestId)701 int32_t ThumbnailService::CreateAstcBatchOnDemand(NativeRdb::RdbPredicates &rdbPredicate, int32_t requestId)
702 {
703 if (requestId <= 0) {
704 MEDIA_ERR_LOG("create astc batch failed, invalid request id:%{public}d", requestId);
705 return E_INVALID_VALUES;
706 }
707 CancelAstcBatchTask(requestId - 1);
708 if (GetCurrentTemperatureLevel() >= READY_TEMPERATURE_LEVEL) {
709 isTemperatureHighForReady_ = true;
710 currentRequestId_ = requestId;
711 rdbPredicatePtr_ = make_shared<NativeRdb::RdbPredicates>(rdbPredicate);
712 MEDIA_INFO_LOG("temperature is too high, the operation is suspended");
713 return E_OK;
714 }
715 ThumbRdbOpt opts = {
716 .store = rdbStorePtr_,
717 .table = PhotoColumn::PHOTOS_TABLE
718 };
719 return ThumbnailGenerateHelper::CreateAstcBatchOnDemand(opts, rdbPredicate, requestId);
720 }
721
CancelAstcBatchTask(int32_t requestId)722 void ThumbnailService::CancelAstcBatchTask(int32_t requestId)
723 {
724 if (requestId <= 0) {
725 MEDIA_ERR_LOG("cancel astc batch failed, invalid request id:%{public}d", requestId);
726 return;
727 }
728
729 if (isTemperatureHighForReady_) {
730 currentRequestId_ = 0;
731 }
732 MEDIA_INFO_LOG("CancelAstcBatchTask requestId: %{public}d", requestId);
733 std::shared_ptr<ThumbnailGenerateWorker> thumbnailWorker =
734 ThumbnailGenerateWorkerManager::GetInstance().GetThumbnailWorker(ThumbnailTaskType::FOREGROUND);
735 if (thumbnailWorker == nullptr) {
736 MEDIA_ERR_LOG("thumbnailWorker is null");
737 return;
738 }
739 thumbnailWorker->IgnoreTaskByRequestId(requestId);
740 }
741
UpdateAstcWithNewDateTaken(const std::string & fileId,const std::string & newDateTaken,const std::string & formerDateTaken)742 void ThumbnailService::UpdateAstcWithNewDateTaken(const std::string &fileId, const std::string &newDateTaken,
743 const std::string &formerDateTaken)
744 {
745 ThumbnailData data;
746 data.dateTaken = newDateTaken;
747 ThumbRdbOpt opts = {
748 .store = rdbStorePtr_,
749 .table = PhotoColumn::PHOTOS_TABLE,
750 .row = fileId,
751 .dateTaken = formerDateTaken
752 };
753
754 IThumbnailHelper::AddThumbnailGenerateTask(IThumbnailHelper::UpdateAstcDateTaken,
755 opts, data, ThumbnailTaskType::BACKGROUND, ThumbnailTaskPriority::HIGH);
756 }
757
CheckCloudThumbnailDownloadFinish()758 int32_t ThumbnailService::CheckCloudThumbnailDownloadFinish()
759 {
760 if (!ThumbnailUtils::CheckCloudThumbnailDownloadFinish(rdbStorePtr_)) {
761 return E_CLOUD_THUMBNAIL_NOT_DOWNLOAD_FINISH;
762 }
763 return E_OK;
764 }
765
UpdateThumbnailReadyToFailed(ThumbRdbOpt & opts,std::string id)766 static void UpdateThumbnailReadyToFailed(ThumbRdbOpt &opts, std::string id)
767 {
768 if (opts.store == nullptr || id.empty()) {
769 return;
770 }
771
772 ValuesBucket values;
773 int changedRows;
774 values.PutLong(PhotoColumn::PHOTO_THUMBNAIL_READY, THUMBNAIL_READY_FAILED);
775 int32_t err = opts.store->Update(changedRows, opts.table, values, MEDIA_DATA_DB_ID + " = ?", vector<string> { id });
776 if (err != NativeRdb::E_OK) {
777 MEDIA_ERR_LOG("RdbStore Update failed! %{public}d", err);
778 }
779 }
780
IsAstcChangeOldKeyToNewKeySuccess(std::shared_ptr<MediaLibraryKvStore> & monthKvStore,std::shared_ptr<MediaLibraryKvStore> & yearKvStore,const std::string & oldKey,const std::string & newKey)781 static bool IsAstcChangeOldKeyToNewKeySuccess(std::shared_ptr<MediaLibraryKvStore> &monthKvStore,
782 std::shared_ptr<MediaLibraryKvStore> &yearKvStore, const std::string &oldKey, const std::string &newKey)
783 {
784 if (oldKey.compare(newKey) == 0) {
785 MEDIA_INFO_LOG("OldKey: %{public}s is same to newKey", oldKey.c_str());
786 return true;
787 }
788 std::vector<uint8_t> monthValue;
789 std::vector<uint8_t> yearValue;
790 if (yearKvStore->Query(newKey, yearValue) == E_OK) {
791 MEDIA_INFO_LOG("NewKey Astc exists, fileID %{public}s", newKey.c_str());
792 monthKvStore->Delete(oldKey);
793 yearKvStore->Delete(oldKey);
794 return true;
795 }
796 bool isChangeKeySuccess = true;
797 if (monthKvStore->Query(oldKey, monthValue) != E_OK || monthKvStore->Insert(newKey, monthValue) != E_OK ||
798 monthKvStore->Delete(oldKey) != E_OK) {
799 MEDIA_ERR_LOG("MonthValue update failed, fileID %{public}s", newKey.c_str());
800 isChangeKeySuccess = false;
801 }
802 if (yearKvStore->Query(oldKey, yearValue) != E_OK || yearKvStore->Insert(newKey, yearValue) != E_OK ||
803 yearKvStore->Delete(oldKey) != E_OK) {
804 MEDIA_ERR_LOG("YearValue update failed, fileID %{public}s", newKey.c_str());
805 isChangeKeySuccess = false;
806 }
807 return isChangeKeySuccess;
808 }
809
AstcChangeKeyFromDateAddedToDateTaken()810 void ThumbnailService::AstcChangeKeyFromDateAddedToDateTaken()
811 {
812 if (rdbStorePtr_ == nullptr) {
813 MEDIA_ERR_LOG("RdbStorePtr is null");
814 return;
815 }
816 vector<ThumbnailData> infos;
817 if (!ThumbnailUtils::QueryOldKeyAstcInfos(rdbStorePtr_, PhotoColumn::PHOTOS_TABLE, infos)) {
818 return;
819 }
820 MEDIA_INFO_LOG("Old key astc data size: %{public}d", static_cast<int>(infos.size()));
821 if (infos.empty()) {
822 return;
823 }
824 ThumbRdbOpt opts = {
825 .store = rdbStorePtr_,
826 .table = PhotoColumn::PHOTOS_TABLE,
827 };
828
829 auto monthKvStore = MediaLibraryKvStoreManager::GetInstance()
830 .GetKvStore(KvStoreRoleType::OWNER, KvStoreValueType::MONTH_ASTC);
831 if (monthKvStore == nullptr) {
832 MEDIA_ERR_LOG("Init month kvStore failed");
833 return;
834 }
835 auto yearKvStore = MediaLibraryKvStoreManager::GetInstance()
836 .GetKvStore(KvStoreRoleType::OWNER, KvStoreValueType::YEAR_ASTC);
837 if (yearKvStore == nullptr) {
838 MEDIA_ERR_LOG("Init year kvStore failed");
839 return;
840 }
841 for (size_t i = 0; i < infos.size(); i++) {
842 std::string oldKey;
843 std::string newKey;
844 if (!MediaFileUtils::GenerateKvStoreKey(infos[i].id, infos[i].dateAdded, oldKey) ||
845 !MediaFileUtils::GenerateKvStoreKey(infos[i].id, infos[i].dateTaken, newKey)) {
846 continue;
847 }
848 if (!IsAstcChangeOldKeyToNewKeySuccess(monthKvStore, yearKvStore, oldKey, newKey)) {
849 monthKvStore->Delete(oldKey);
850 yearKvStore->Delete(oldKey);
851 UpdateThumbnailReadyToFailed(opts, infos[i].id);
852 }
853 }
854 MEDIA_INFO_LOG("PerformKvStoreChangeKeyTask End");
855 }
856
UpdateCurrentStatusForTask(const bool & currentStatusForTask)857 void ThumbnailService::UpdateCurrentStatusForTask(const bool ¤tStatusForTask)
858 {
859 currentStatusForTask_ = currentStatusForTask;
860 }
861
GetCurrentStatusForTask()862 bool ThumbnailService::GetCurrentStatusForTask()
863 {
864 return currentStatusForTask_;
865 }
866
NotifyTempStatusForReady(const int32_t & currentTemperatureLevel)867 void ThumbnailService::NotifyTempStatusForReady(const int32_t ¤tTemperatureLevel)
868 {
869 currentTemperatureLevel_ = currentTemperatureLevel;
870 if (isTemperatureHighForReady_ && currentTemperatureLevel_ < READY_TEMPERATURE_LEVEL) {
871 MEDIA_INFO_LOG("temperature is normal, the opreation is resumed");
872 isTemperatureHighForReady_ = false;
873 if (rdbPredicatePtr_ != nullptr && currentRequestId_ > 0) {
874 CreateAstcBatchOnDemand(*rdbPredicatePtr_, currentRequestId_);
875 }
876 }
877 }
878
GetCurrentTemperatureLevel()879 int32_t ThumbnailService::GetCurrentTemperatureLevel()
880 {
881 return currentTemperatureLevel_;
882 }
883
CheckLcdSizeAndUpdateStatus()884 void ThumbnailService::CheckLcdSizeAndUpdateStatus()
885 {
886 ThumbRdbOpt opts = {
887 .store = rdbStorePtr_,
888 .table = PhotoColumn::PHOTOS_TABLE
889 };
890 int32_t err = ThumbnailGenerateHelper::CheckLcdSizeAndUpdateStatus(opts);
891 if (err != E_OK) {
892 MEDIA_ERR_LOG("CheckLcdSizeAndUpdateStatus failed: %{public}d", err);
893 }
894 }
895
RepairExifRotateBackground()896 int32_t ThumbnailService::RepairExifRotateBackground()
897 {
898 ThumbRdbOpt opts = {
899 .store = rdbStorePtr_,
900 .table = PhotoColumn::PHOTOS_TABLE
901 };
902 int32_t err = ThumbnailGenerateHelper::RepairExifRotateBackground(opts);
903 CHECK_AND_RETURN_RET_LOG(err == E_OK, err, "RepairNoExifRotateBackground failed : %{public}d", err);
904 return E_OK;
905 }
906
FixThumbnailExifRotateAfterDownloadAsset(const std::string & fileId)907 int32_t ThumbnailService::FixThumbnailExifRotateAfterDownloadAsset(const std::string &fileId)
908 {
909 ThumbRdbOpt opts = {
910 .store = rdbStorePtr_,
911 .table = PhotoColumn::PHOTOS_TABLE,
912 .fileId = fileId,
913 };
914 int err = ThumbnailGenerateHelper::FixThumbnailExifRotateAfterDownloadAsset(opts);
915 CHECK_AND_RETURN_RET_LOG(err == E_OK, err, "FixThumbnailExifRotateAfterDownloadAsset failed, err: %{public}d", err);
916 return E_OK;
917 }
918 } // namespace Media
919 } // namespace OHOS
920