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