• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &currentStatusForTask)
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 &currentTemperatureLevel)
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