• 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_generate_helper.h"
18 
19 #include <fcntl.h>
20 
21 #include "acl.h"
22 #include "cloud_sync_helper.h"
23 #include "dfx_const.h"
24 #include "dfx_manager.h"
25 #include "dfx_timer.h"
26 #include "dfx_utils.h"
27 #include "ffrt.h"
28 #include "ffrt_inner.h"
29 #include "directory_ex.h"
30 #include "ithumbnail_helper.h"
31 #include "medialibrary_errno.h"
32 #include "medialibrary_kvstore_manager.h"
33 #include "medialibrary_photo_operations.h"
34 #include "medialibrary_type_const.h"
35 #include "media_file_utils.h"
36 #include "media_log.h"
37 #include "thumbnail_const.h"
38 #include "thumbnail_generate_worker_manager.h"
39 #include "thumbnail_source_loading.h"
40 #include "thumbnail_utils.h"
41 
42 using namespace std;
43 using namespace OHOS::DistributedKv;
44 using namespace OHOS::NativeRdb;
45 
46 namespace OHOS {
47 namespace Media {
48 const int FFRT_MAX_RESTORE_ASTC_THREADS = 4;
49 const std::string SQL_REFRESH_THUMBNAIL_READY =
50     " Update " + PhotoColumn::PHOTOS_TABLE + " SET " + PhotoColumn::PHOTO_THUMBNAIL_READY + " = 7 " +
51     " WHERE " + PhotoColumn::PHOTO_THUMBNAIL_READY + " != 0; END;";
52 
CreateThumbnailFileScaned(ThumbRdbOpt & opts,bool isSync)53 int32_t ThumbnailGenerateHelper::CreateThumbnailFileScaned(ThumbRdbOpt &opts, bool isSync)
54 {
55     ThumbnailData thumbnailData;
56     ThumbnailUtils::GetThumbnailInfo(opts, thumbnailData);
57     thumbnailData.needResizeLcd = true;
58     thumbnailData.loaderOpts.loadingStates = SourceLoader::LOCAL_SOURCE_LOADING_STATES;
59     ThumbnailUtils::RecordStartGenerateStats(thumbnailData.stats, GenerateScene::LOCAL, LoadSourceType::LOCAL_PHOTO);
60     if (ThumbnailUtils::DeleteThumbExDir(thumbnailData)) {
61         MEDIA_ERR_LOG("Delete THM_EX directory, path: %{public}s, id: %{public}s",
62             DfxUtils::GetSafePath(thumbnailData.path).c_str(), thumbnailData.id.c_str());
63     }
64 
65     if (isSync) {
66         WaitStatus status;
67         bool isSuccess = IThumbnailHelper::DoCreateLcdAndThumbnail(opts, thumbnailData, status);
68         if (status == WaitStatus::INSERT) {
69             IThumbnailHelper::UpdateThumbnailState(opts, thumbnailData, isSuccess);
70         }
71 
72         ThumbnailUtils::RecordCostTimeAndReport(thumbnailData.stats);
73     } else {
74         IThumbnailHelper::AddThumbnailGenerateTask(IThumbnailHelper::CreateLcdAndThumbnail,
75             opts, thumbnailData, ThumbnailTaskType::FOREGROUND, ThumbnailTaskPriority::HIGH);
76     }
77     return E_OK;
78 }
79 
CreateThumbnailFileScanedWithPicture(ThumbRdbOpt & opts,std::shared_ptr<Picture> originalPhotoPicture,bool isSync)80 int32_t ThumbnailGenerateHelper::CreateThumbnailFileScanedWithPicture(ThumbRdbOpt &opts,
81     std::shared_ptr<Picture> originalPhotoPicture, bool isSync)
82 {
83     ThumbnailData thumbnailData;
84     ThumbnailUtils::GetThumbnailInfo(opts, thumbnailData);
85     thumbnailData.needResizeLcd = true;
86     thumbnailData.loaderOpts.loadingStates = SourceLoader::LOCAL_SOURCE_LOADING_STATES;
87     thumbnailData.originalPhotoPicture = originalPhotoPicture;
88     ThumbnailUtils::RecordStartGenerateStats(thumbnailData.stats, GenerateScene::LOCAL, LoadSourceType::LOCAL_PHOTO);
89 
90     MEDIA_INFO_LOG("Delete THM_EX directory successsully:%{public}d, originalPhotoPicture exists:%{public}d, "
91         "path: %{public}s, id: %{public}s", ThumbnailUtils::DeleteThumbExDir(thumbnailData),
92         originalPhotoPicture != nullptr, DfxUtils::GetSafePath(thumbnailData.path).c_str(), thumbnailData.id.c_str());
93 
94     if (isSync) {
95         WaitStatus status;
96         bool isSuccess = IThumbnailHelper::DoCreateLcdAndThumbnail(opts, thumbnailData, status);
97         if (status == WaitStatus::INSERT) {
98             IThumbnailHelper::UpdateThumbnailState(opts, thumbnailData, isSuccess);
99         }
100         ThumbnailUtils::RecordCostTimeAndReport(thumbnailData.stats);
101     } else {
102         IThumbnailHelper::AddThumbnailGenerateTask(IThumbnailHelper::CreateLcdAndThumbnail,
103             opts, thumbnailData, ThumbnailTaskType::FOREGROUND, ThumbnailTaskPriority::HIGH);
104     }
105     return E_OK;
106 }
107 
CreateThumbnailBackground(ThumbRdbOpt & opts)108 int32_t ThumbnailGenerateHelper::CreateThumbnailBackground(ThumbRdbOpt &opts)
109 {
110     if (opts.store == nullptr) {
111         MEDIA_ERR_LOG("rdbStore is not init");
112         return E_ERR;
113     }
114     CHECK_AND_RETURN_RET_LOG(ThumbnailUtils::CheckRemainSpaceMeetCondition(THUMBNAIL_FREE_SIZE_LIMIT_10),
115         E_FREE_SIZE_NOT_ENOUGH, "Free size is not enough");
116 
117     vector<ThumbnailData> infos;
118     int32_t err = GetNoThumbnailData(opts, infos);
119     if (err != E_OK) {
120         MEDIA_ERR_LOG("Failed to GetNoLThumbnailData %{private}d", err);
121         return err;
122     }
123 
124     if (infos.empty()) {
125         MEDIA_DEBUG_LOG("No need generate thumbnail.");
126         return E_OK;
127     }
128     auto createThumbnailBackgroundTask = [](std::shared_ptr<ThumbnailTaskData> &data) {
129         CHECK_AND_RETURN_LOG(data != nullptr, "Data is null");
130         auto &thumbnailData = data->thumbnailData_;
131         CHECK_AND_RETURN_LOG(ThumbnailUtils::CheckRemainSpaceMeetCondition(THUMBNAIL_FREE_SIZE_LIMIT_10),
132             "CreateThumbnailBackgroundTask free size is not enough, id:%{public}s, path:%{public}s",
133             thumbnailData.id.c_str(), DfxUtils::GetSafePath(thumbnailData.path).c_str());
134         IThumbnailHelper::CreateThumbnail(data);
135     };
136 
137     for (uint32_t i = 0; i < infos.size(); i++) {
138         opts.row = infos[i].id;
139         infos[i].loaderOpts.loadingStates = infos[i].isLocalFile ? SourceLoader::LOCAL_SOURCE_LOADING_STATES :
140             SourceLoader::CLOUD_SOURCE_LOADING_STATES;
141         IThumbnailHelper::AddThumbnailGenerateTask(createThumbnailBackgroundTask,
142             opts, infos[i], ThumbnailTaskType::BACKGROUND, ThumbnailTaskPriority::LOW);
143     }
144 
145     return E_OK;
146 }
147 
CreateAstcBackground(ThumbRdbOpt & opts)148 int32_t ThumbnailGenerateHelper::CreateAstcBackground(ThumbRdbOpt &opts)
149 {
150     if (opts.store == nullptr) {
151         MEDIA_ERR_LOG("rdbStore is not init");
152         return E_ERR;
153     }
154 
155     CheckMonthAndYearKvStoreValid(opts);
156     CHECK_AND_RETURN_RET_LOG(ThumbnailUtils::CheckRemainSpaceMeetCondition(THUMBNAIL_FREE_SIZE_LIMIT_10),
157         E_FREE_SIZE_NOT_ENOUGH, "Free size is not enough");
158     vector<ThumbnailData> infos;
159     int32_t err = GetNoAstcData(opts, infos);
160     if (err != E_OK) {
161         MEDIA_ERR_LOG("Failed to GetNoAstcData %{private}d", err);
162         return err;
163     }
164 
165     auto kvStore = MediaLibraryKvStoreManager::GetInstance()
166         .GetKvStore(KvStoreRoleType::OWNER, KvStoreValueType::MONTH_ASTC);
167     if (infos.empty() || kvStore == nullptr) {
168         MEDIA_DEBUG_LOG("No need create Astc.");
169         return E_OK;
170     }
171 
172     auto createAstcBackgroundTask = [](std::shared_ptr<ThumbnailTaskData> &data) {
173         CHECK_AND_RETURN_LOG(data != nullptr, "Data is null");
174         auto &thumbnailData = data->thumbnailData_;
175         CHECK_AND_RETURN_LOG(ThumbnailUtils::CheckRemainSpaceMeetCondition(THUMBNAIL_FREE_SIZE_LIMIT_10),
176             "CreateAstcBackgroundTask free size is not enough, id:%{public}s, path:%{public}s",
177             thumbnailData.id.c_str(), DfxUtils::GetSafePath(thumbnailData.path).c_str());
178         if (thumbnailData.isLocalFile ||
179             thumbnailData.position == static_cast<int32_t>(PhotoPositionType::LOCAL_AND_CLOUD)) {
180             thumbnailData.loaderOpts.loadingStates = SourceLoader::LOCAL_SOURCE_LOADING_STATES;
181             IThumbnailHelper::CreateThumbnail(data);
182         } else {
183             thumbnailData.loaderOpts.loadingStates = thumbnailData.orientation != 0 ?
184                 SourceLoader::CLOUD_LCD_SOURCE_LOADING_STATES : SourceLoader::CLOUD_SOURCE_LOADING_STATES;
185             thumbnailData.orientation != 0 ? IThumbnailHelper::CreateAstcEx(data) : IThumbnailHelper::CreateAstc(data);
186         }
187     };
188 
189     MEDIA_INFO_LOG("no astc data size: %{public}d", static_cast<int>(infos.size()));
190     for (uint32_t i = 0; i < infos.size(); i++) {
191         opts.row = infos[i].id;
192         ThumbnailUtils::RecordStartGenerateStats(infos[i].stats, GenerateScene::BACKGROUND,
193             LoadSourceType::LOCAL_PHOTO);
194         IThumbnailHelper::AddThumbnailGenerateTask(createAstcBackgroundTask,
195             opts, infos[i], ThumbnailTaskType::BACKGROUND, ThumbnailTaskPriority::LOW);
196     }
197     return E_OK;
198 }
199 
CreateAstcCloudDownload(ThumbRdbOpt & opts,bool isCloudInsertTaskPriorityHigh)200 int32_t ThumbnailGenerateHelper::CreateAstcCloudDownload(ThumbRdbOpt &opts, bool isCloudInsertTaskPriorityHigh)
201 {
202     ThumbnailData data;
203     ThumbnailUtils::RecordStartGenerateStats(data.stats, GenerateScene::CLOUD, LoadSourceType::LOCAL_PHOTO);
204     int err = 0;
205     ThumbnailUtils::QueryThumbnailDataFromFileId(opts, opts.fileId, data, err);
206     if (err != E_OK) {
207         MEDIA_ERR_LOG("QueryThumbnailDataFromFileId failed, path: %{public}s",
208             DfxUtils::GetSafePath(data.path).c_str());
209         return err;
210     }
211     ValuesBucket values;
212     Size lcdSize;
213     if (data.mediaType == MEDIA_TYPE_VIDEO && ThumbnailUtils::GetLocalThumbSize(data, ThumbnailType::LCD, lcdSize)) {
214         ThumbnailUtils::SetThumbnailSizeValue(values, lcdSize, PhotoColumn::PHOTO_LCD_SIZE);
215         int changedRows;
216         int32_t err = opts.store->Update(changedRows, opts.table, values, MEDIA_DATA_DB_ID + " = ?",
217         vector<string> { data.id });
218         if (err != NativeRdb::E_OK) {
219             MEDIA_ERR_LOG("RdbStore lcd size failed! %{public}d", err);
220         }
221     }
222 
223     data.loaderOpts.loadingStates = data.orientation != 0 ?
224         SourceLoader::CLOUD_LCD_SOURCE_LOADING_STATES : SourceLoader::CLOUD_SOURCE_LOADING_STATES;
225     if (isCloudInsertTaskPriorityHigh) {
226         IThumbnailHelper::AddThumbnailGenerateTask(data.orientation != 0 ?
227             IThumbnailHelper::CreateAstcEx : IThumbnailHelper::CreateAstc,
228             opts, data, ThumbnailTaskType::FOREGROUND, ThumbnailTaskPriority::MID);
229         return E_OK;
230     }
231 
232     auto lowPriorityCreateAstcCloudDownloadTask = [](std::shared_ptr<ThumbnailTaskData> &data) {
233         CHECK_AND_RETURN_LOG(data != nullptr, "Data is null");
234         auto &thumbnailData = data->thumbnailData_;
235         CHECK_AND_RETURN_LOG(ThumbnailUtils::CheckRemainSpaceMeetCondition(THUMBNAIL_FREE_SIZE_LIMIT_10),
236             "LowPriorityCreateAstcCloudDownloadTask free size is not enough, id:%{public}s, path:%{public}s",
237             thumbnailData.id.c_str(), DfxUtils::GetSafePath(thumbnailData.path).c_str());
238         thumbnailData.orientation != 0 ? IThumbnailHelper::CreateAstcEx(data) : IThumbnailHelper::CreateAstc(data);
239     };
240     IThumbnailHelper::AddThumbnailGenerateTask(lowPriorityCreateAstcCloudDownloadTask,
241         opts, data, ThumbnailTaskType::BACKGROUND, ThumbnailTaskPriority::LOW);
242     return E_OK;
243 }
244 
CreateAstcMthAndYear(ThumbRdbOpt & opts)245 int32_t ThumbnailGenerateHelper::CreateAstcMthAndYear(ThumbRdbOpt &opts)
246 {
247     ThumbnailData data;
248     int err = 0;
249     ThumbnailUtils::QueryThumbnailDataFromFileId(opts, opts.fileId, data, err);
250     if (err != E_OK) {
251         MEDIA_ERR_LOG("CreateAstcMthAndYear query data from fileId failed, id: %{public}s", opts.fileId.c_str());
252         return err;
253     }
254     data.loaderOpts.loadingStates = (data.isLocalFile ||
255         data.position == static_cast<int32_t>(PhotoPositionType::LOCAL_AND_CLOUD)) ?
256         SourceLoader::LOCAL_THUMB_SOURCE_LOADING_STATES : SourceLoader::CLOUD_SOURCE_LOADING_STATES;
257     if (!IThumbnailHelper::DoCreateAstcMthAndYear(opts, data)) {
258         return E_ERR;
259     }
260     return E_OK;
261 }
262 
CreateLocalThumbnail(ThumbRdbOpt & opts)263 int32_t ThumbnailGenerateHelper::CreateLocalThumbnail(ThumbRdbOpt &opts)
264 {
265     if (opts.store == nullptr) {
266         MEDIA_ERR_LOG("rdbStore is not init");
267         return E_ERR;
268     }
269     vector<ThumbnailData> infos;
270     int32_t err = 0;
271     if (!ThumbnailUtils::QueryLocalNoThumbnailInfos(opts, infos, err)) {
272         MEDIA_ERR_LOG("Failed to QueryNoThumbnailInfos %{private}d", err);
273         IThumbnailHelper::AddThumbnailGenerateTask(IThumbnailHelper::CloudSyncOnGenerationComplete,
274             ThumbnailTaskType::BACKGROUND, ThumbnailTaskPriority::MID);
275         return err;
276     }
277     if (infos.empty()) {
278         IThumbnailHelper::AddThumbnailGenerateTask(IThumbnailHelper::CloudSyncOnGenerationComplete,
279             ThumbnailTaskType::BACKGROUND, ThumbnailTaskPriority::MID);
280         return E_OK;
281     }
282     std::shared_ptr<ExecuteParamBuilder> param = std::make_shared<ExecuteParamBuilder>();
283     param->batteryLimit_ = LOCAL_GENERATION_BATTERY_CAPACITY;
284     param->tempLimit_ = READY_TEMPERATURE_LEVEL;
285     param->affinity_ = CpuAffinityType::CPU_IDX_6;
286     MEDIA_INFO_LOG("CreateLocalThumbnail: %{public}d", static_cast<int>(infos.size()));
287     for (uint32_t i = 0; i < infos.size(); i++) {
288         opts.row = infos[i].id;
289         infos[i].loaderOpts.loadingStates = SourceLoader::LOCAL_SOURCE_LOADING_STATES;
290         if (infos[i].thumbnailReady == 0 && infos[i].lcdVisitTime == 0) {
291             IThumbnailHelper::AddThumbnailGenerateTask(IThumbnailHelper::CreateLcdAndThumbnail,
292                 opts, infos[i], ThumbnailTaskType::BACKGROUND, ThumbnailTaskPriority::MID, param);
293         } else if (infos[i].thumbnailReady == 0) {
294             IThumbnailHelper::AddThumbnailGenerateTask(IThumbnailHelper::CreateThumbnail,
295                 opts, infos[i], ThumbnailTaskType::BACKGROUND, ThumbnailTaskPriority::MID, param);
296         } else if (infos[i].lcdVisitTime == 0) {
297             IThumbnailHelper::AddThumbnailGenerateTask(IThumbnailHelper::CreateLcd,
298                 opts, infos[i], ThumbnailTaskType::BACKGROUND, ThumbnailTaskPriority::MID, param);
299         }
300     }
301     IThumbnailHelper::AddThumbnailGenerateTask(IThumbnailHelper::CloudSyncOnGenerationComplete,
302         ThumbnailTaskType::BACKGROUND, ThumbnailTaskPriority::MID);
303     return E_OK;
304 }
305 
CreateAstcBatchOnDemand(ThumbRdbOpt & opts,NativeRdb::RdbPredicates & predicate,int32_t requestId)306 int32_t ThumbnailGenerateHelper::CreateAstcBatchOnDemand(
307     ThumbRdbOpt &opts, NativeRdb::RdbPredicates &predicate, int32_t requestId)
308 {
309     if (opts.store == nullptr) {
310         MEDIA_ERR_LOG("rdbStore is not init");
311         return E_ERR;
312     }
313 
314     vector<ThumbnailData> infos;
315     int32_t err = 0;
316     if (!ThumbnailUtils::QueryNoAstcInfosOnDemand(opts, infos, predicate, err)) {
317         MEDIA_ERR_LOG("Failed to QueryNoAstcInfos %{public}d", err);
318         return err;
319     }
320     if (infos.empty()) {
321         MEDIA_INFO_LOG("No need create Astc.");
322         return E_THUMBNAIL_ASTC_ALL_EXIST;
323     }
324 
325     MEDIA_INFO_LOG("no astc data size: %{public}d, requestId: %{public}d", static_cast<int>(infos.size()), requestId);
326     for (auto& info : infos) {
327         opts.row = info.id;
328         ThumbnailUtils::RecordStartGenerateStats(info.stats, GenerateScene::FOREGROUND, LoadSourceType::LOCAL_PHOTO);
329         if (info.isLocalFile || info.position == static_cast<int32_t>(PhotoPositionType::LOCAL_AND_CLOUD)) {
330             info.loaderOpts.loadingStates = SourceLoader::LOCAL_SOURCE_LOADING_STATES;
331             IThumbnailHelper::AddThumbnailGenBatchTask(IThumbnailHelper::CreateThumbnail, opts, info, requestId);
332         } else {
333             info.loaderOpts.loadingStates = info.mediaType == MEDIA_TYPE_VIDEO ?
334                 SourceLoader::ALL_SOURCE_LOADING_CLOUD_VIDEO_STATES : SourceLoader::ALL_SOURCE_LOADING_STATES;
335             IThumbnailHelper::AddThumbnailGenBatchTask(info.orientation == 0 ?
336                 IThumbnailHelper::CreateAstc : IThumbnailHelper::CreateAstcEx, opts, info, requestId);
337         }
338     }
339     return E_OK;
340 }
341 
NeedGenerateLocalLcd(ThumbnailData & data)342 bool NeedGenerateLocalLcd(ThumbnailData &data)
343 {
344     std::string lcdLocalPath = GetLocalThumbnailPath(data.path, THUMBNAIL_LCD_SUFFIX);
345     size_t lcdSize = -1;
346 
347     // Local LCD exist, and its size is less than upload limit
348     if (access(lcdLocalPath.c_str(), F_OK) == 0 && MediaFileUtils::GetFileSize(lcdLocalPath, lcdSize) &&
349         lcdSize < LCD_UPLOAD_LIMIT_SIZE) {
350         return false;
351     }
352     MEDIA_INFO_LOG("Local file Lcd need to be generate, size: %{public}d, path: %{public}s",
353         static_cast<int>(lcdSize), DfxUtils::GetSafePath(data.path).c_str());
354     return true;
355 }
356 
CreateLcdBackground(ThumbRdbOpt & opts)357 int32_t ThumbnailGenerateHelper::CreateLcdBackground(ThumbRdbOpt &opts)
358 {
359     if (opts.store == nullptr) {
360         return E_ERR;
361     }
362     CHECK_AND_RETURN_RET_LOG(ThumbnailUtils::CheckRemainSpaceMeetCondition(THUMBNAIL_FREE_SIZE_LIMIT_10),
363         E_FREE_SIZE_NOT_ENOUGH, "Free size is not enough");
364 
365     vector<ThumbnailData> infos;
366     int32_t err = GetNoLcdData(opts, infos);
367     if (err != E_OK) {
368         MEDIA_ERR_LOG("Failed to GetNoLcdData %{private}d", err);
369         return err;
370     }
371     if (infos.empty()) {
372         MEDIA_DEBUG_LOG("No need create Lcd.");
373         return E_THUMBNAIL_LCD_ALL_EXIST;
374     }
375     auto createLcdBackgroundTask = [](std::shared_ptr<ThumbnailTaskData> &data) {
376         CHECK_AND_RETURN_LOG(data != nullptr, "CreateLcd failed, data is null");
377         auto &thumbnailData = data->thumbnailData_;
378         CHECK_AND_RETURN_LOG(ThumbnailUtils::CheckRemainSpaceMeetCondition(THUMBNAIL_FREE_SIZE_LIMIT_10),
379             "CreateLcdBackgroundTask free size is not enough, id:%{public}s, path:%{public}s",
380             thumbnailData.id.c_str(), DfxUtils::GetSafePath(thumbnailData.path).c_str());
381         thumbnailData.loaderOpts.loadingStates = SourceLoader::LOCAL_SOURCE_LOADING_STATES;
382         IThumbnailHelper::CreateLcd(data);
383     };
384 
385     MEDIA_INFO_LOG("No lcd data size: %{public}d", static_cast<int>(infos.size()));
386     for (uint32_t i = 0; i < infos.size(); i++) {
387         opts.row = infos[i].id;
388 
389         // Check whether LCD exists or is over upload limit, if it does, just update the database
390         if (!NeedGenerateLocalLcd(infos[i])) {
391             MEDIA_INFO_LOG("Skip CreateLcdBackground, lcd exists: %{public}s",
392                 DfxUtils::GetSafePath(infos[i].path).c_str());
393             ThumbnailUtils::UpdateLcdReadyStatus(opts, infos[i], err, LcdReady::GENERATE_LCD_COMPLETED);
394             continue;
395         }
396         IThumbnailHelper::AddThumbnailGenerateTask(createLcdBackgroundTask,
397             opts, infos[i], ThumbnailTaskType::BACKGROUND, ThumbnailTaskPriority::LOW);
398     }
399     return E_OK;
400 }
401 
CheckLcdSizeAndUpdateStatus(ThumbRdbOpt & opts)402 int32_t ThumbnailGenerateHelper::CheckLcdSizeAndUpdateStatus(ThumbRdbOpt &opts)
403 {
404     if (opts.store == nullptr) {
405         return E_ERR;
406     }
407 
408     vector<ThumbnailData> infos;
409     int32_t err = GetLocalNoLcdData(opts, infos);
410     if (err != E_OK) {
411         MEDIA_ERR_LOG("Failed to CheckLcdSizeAndUpdateStatus %{public}d", err);
412         return err;
413     }
414     if (infos.empty()) {
415         MEDIA_INFO_LOG("No need CheckLcdSizeAndUpdateStatus.");
416         return E_THUMBNAIL_LCD_ALL_EXIST;
417     }
418 
419     MEDIA_INFO_LOG("CheckLcdSizeAndUpdateStatus size: %{public}d", static_cast<int>(infos.size()));
420     for (uint32_t i = 0; i < infos.size(); i++) {
421         opts.row = infos[i].id;
422 
423         // Check whether LCD exists or is over upload limit, if it does, just update the database
424         if (!NeedGenerateLocalLcd(infos[i])) {
425             MEDIA_INFO_LOG("Check lcd size succeeded, lcd exists: %{public}s",
426                 DfxUtils::GetSafePath(infos[i].path).c_str());
427             ThumbnailUtils::UpdateLcdReadyStatus(opts, infos[i], err, LcdReady::GENERATE_LCD_COMPLETED);
428         }
429     }
430     return E_OK;
431 }
432 
GetLcdCount(ThumbRdbOpt & opts,int & outLcdCount)433 int32_t ThumbnailGenerateHelper::GetLcdCount(ThumbRdbOpt &opts, int &outLcdCount)
434 {
435     int32_t err = E_ERR;
436     if (!ThumbnailUtils::QueryLcdCount(opts, outLcdCount, err)) {
437         MEDIA_ERR_LOG("Failed to QueryLcdCount %{private}d", err);
438         return err;
439     }
440     return E_OK;
441 }
442 
GetNoLcdData(ThumbRdbOpt & opts,vector<ThumbnailData> & outDatas)443 int32_t ThumbnailGenerateHelper::GetNoLcdData(ThumbRdbOpt &opts, vector<ThumbnailData> &outDatas)
444 {
445     int32_t err = E_ERR;
446     if (!ThumbnailUtils::QueryNoLcdInfos(opts, outDatas, err)) {
447         MEDIA_ERR_LOG("Failed to QueryNoLcdInfos %{private}d", err);
448         return err;
449     }
450     return E_OK;
451 }
452 
GetLocalNoLcdData(ThumbRdbOpt & opts,vector<ThumbnailData> & outDatas)453 int32_t ThumbnailGenerateHelper::GetLocalNoLcdData(ThumbRdbOpt &opts, vector<ThumbnailData> &outDatas)
454 {
455     int32_t err = E_ERR;
456     if (!ThumbnailUtils::QueryLocalNoLcdInfos(opts, outDatas, err)) {
457         MEDIA_ERR_LOG("Failed to QueryLocalNoLcdInfos %{private}d", err);
458         return err;
459     }
460     return E_OK;
461 }
462 
GetNoThumbnailData(ThumbRdbOpt & opts,vector<ThumbnailData> & outDatas)463 int32_t ThumbnailGenerateHelper::GetNoThumbnailData(ThumbRdbOpt &opts, vector<ThumbnailData> &outDatas)
464 {
465     int32_t err = E_ERR;
466     if (!ThumbnailUtils::QueryNoThumbnailInfos(opts, outDatas, err)) {
467         MEDIA_ERR_LOG("Failed to QueryNoThumbnailInfos %{private}d", err);
468         return err;
469     }
470     return E_OK;
471 }
472 
GetNoAstcData(ThumbRdbOpt & opts,vector<ThumbnailData> & outDatas)473 int32_t ThumbnailGenerateHelper::GetNoAstcData(ThumbRdbOpt &opts, vector<ThumbnailData> &outDatas)
474 {
475     int32_t err = E_ERR;
476     if (!ThumbnailUtils::QueryNoAstcInfos(opts, outDatas, err)) {
477         MEDIA_ERR_LOG("Failed to QueryNoAstcInfos %{public}d", err);
478         return err;
479     }
480     return E_OK;
481 }
482 
GetNoHighlightData(ThumbRdbOpt & opts,vector<ThumbnailData> & outDatas)483 int32_t ThumbnailGenerateHelper::GetNoHighlightData(ThumbRdbOpt &opts, vector<ThumbnailData> &outDatas)
484 {
485     int32_t err = E_ERR;
486     if (!ThumbnailUtils::QueryNoHighlightInfos(opts, outDatas, err)) {
487         MEDIA_ERR_LOG("Failed to QueryNoHighlightInfos %{public}d", err);
488         return err;
489     }
490     return E_OK;
491 }
492 
GetNewThumbnailCount(ThumbRdbOpt & opts,const int64_t & time,int & count)493 int32_t ThumbnailGenerateHelper::GetNewThumbnailCount(ThumbRdbOpt &opts, const int64_t &time, int &count)
494 {
495     int32_t err = E_ERR;
496     if (!ThumbnailUtils::QueryNewThumbnailCount(opts, time, count, err)) {
497         MEDIA_ERR_LOG("Failed to QueryNoThumbnailInfos %{private}d", err);
498         return err;
499     }
500     return E_OK;
501 }
502 
GenerateLocalThumbnail(ThumbRdbOpt & opts,ThumbnailData & data,ThumbnailType thumbType)503 bool GenerateLocalThumbnail(ThumbRdbOpt &opts, ThumbnailData &data, ThumbnailType thumbType)
504 {
505     data.loaderOpts.loadingStates = SourceLoader::LOCAL_SOURCE_LOADING_STATES;
506     WaitStatus status;
507     if (thumbType == ThumbnailType::LCD && !IThumbnailHelper::DoCreateLcd(opts, data, status)) {
508         MEDIA_ERR_LOG("Get lcd thumbnail pixelmap, doCreateLcd failed: %{public}s",
509             DfxUtils::GetSafePath(data.path).c_str());
510         return false;
511     }
512     if (thumbType != ThumbnailType::LCD) {
513         bool isSuccess = IThumbnailHelper::DoCreateThumbnail(opts, data, status);
514         if (status == WaitStatus::INSERT) {
515             IThumbnailHelper::UpdateThumbnailState(opts, data, isSuccess);
516         }
517         if (!isSuccess) {
518             MEDIA_ERR_LOG("Get default thumbnail pixelmap, doCreateThumbnail failed: %{public}s",
519                 DfxUtils::GetSafePath(data.path).c_str());
520             return false;
521         }
522     }
523     return true;
524 }
525 
GenerateKeyFrameLocalThumbnail(ThumbRdbOpt & opts,ThumbnailData & data,int32_t thumbType)526 bool GenerateKeyFrameLocalThumbnail(ThumbRdbOpt &opts, ThumbnailData &data, int32_t thumbType)
527 {
528     data.loaderOpts.loadingStates = SourceLoader::LOCAL_SOURCE_LOADING_STATES;
529     WaitStatus status;
530     if (thumbType == KEY_FRAME_LCD && !IThumbnailHelper::DoCreateLcd(opts, data, status)) {
531         MEDIA_ERR_LOG("Get key frame lcd thumbnail pixelmap, doCreateLcd failed: %{public}s",
532             DfxUtils::GetSafePath(data.path).c_str());
533         return false;
534     }
535     if (thumbType != KEY_FRAME_LCD) {
536         bool isSuccess = IThumbnailHelper::DoCreateThumbnail(opts, data, status);
537         if (!isSuccess) {
538             MEDIA_ERR_LOG("Get default key frame thumbnail pixelmap, doCreateThumbnail failed: %{public}s",
539                 DfxUtils::GetSafePath(data.path).c_str());
540             return false;
541         }
542     }
543     return true;
544 }
545 
GetAvailableFile(ThumbRdbOpt & opts,ThumbnailData & data,ThumbnailType thumbType,std::string & fileName)546 int32_t ThumbnailGenerateHelper::GetAvailableFile(ThumbRdbOpt &opts, ThumbnailData &data, ThumbnailType thumbType,
547     std::string &fileName)
548 {
549     string thumbSuffix = GetThumbSuffix(thumbType);
550     fileName = GetThumbnailPath(data.path, thumbSuffix);
551     if (thumbType == ThumbnailType::THUMB_ASTC) {
552         // Try to get jpeg thumbnail instead if there is no astc file
553         if (access(fileName.c_str(), F_OK) == 0) {
554             return E_OK;
555         } else {
556             fileName = GetThumbnailPath(data.path, GetThumbSuffix(ThumbnailType::THUMB));
557         }
558     }
559 
560     // No need to create thumbnails if corresponding file exists
561     if (access(fileName.c_str(), F_OK) == 0) {
562         MEDIA_INFO_LOG("File exists, path: %{public}s", DfxUtils::GetSafePath(fileName).c_str());
563         return E_OK;
564     }
565 
566     // Check if unrotated file exists
567     string fileParentPath = MediaFileUtils::GetParentPath(fileName);
568     string tempFileName = fileParentPath + "/THM_EX" + fileName.substr(fileParentPath.length());
569     if (access(tempFileName.c_str(), F_OK) == 0) {
570         fileName = tempFileName;
571         data.isOpeningCloudFile = true;
572         MEDIA_INFO_LOG("Unrotated file exists, path: %{public}s", DfxUtils::GetSafePath(fileName).c_str());
573         return E_OK;
574     }
575 
576     MEDIA_INFO_LOG("No available file, create thumbnail, path: %{public}s", DfxUtils::GetSafePath(fileName).c_str());
577     if (!GenerateLocalThumbnail(opts, data, thumbType)) {
578         MEDIA_ERR_LOG("GenerateLocalThumbnail failed, path: %{public}s", DfxUtils::GetSafePath(tempFileName).c_str());
579         return E_THUMBNAIL_LOCAL_CREATE_FAIL;
580     }
581     if (!opts.path.empty()) {
582         fileName = GetThumbnailPath(data.path, thumbSuffix);
583     }
584     return E_OK;
585 }
586 
GetAvailableKeyFrameFile(ThumbRdbOpt & opts,ThumbnailData & data,int32_t thumbType,std::string & fileName)587 int32_t ThumbnailGenerateHelper::GetAvailableKeyFrameFile(ThumbRdbOpt &opts, ThumbnailData &data, int32_t thumbType,
588     std::string &fileName)
589 {
590     string thumbSuffix = GetKeyFrameThumbSuffix(thumbType);
591     fileName = GetThumbnailPathHighlight(data.path, thumbSuffix, data.timeStamp);
592     // No need to create keyFrame thumbnails if corresponding file exists
593     if (access(fileName.c_str(), F_OK) == 0) {
594         MEDIA_INFO_LOG("GetAvailableKeyFrameFile: file exists, path: %{public}s",
595             DfxUtils::GetSafePath(fileName).c_str());
596         return E_OK;
597     }
598 
599     MEDIA_INFO_LOG("GetAvailableKeyFrameFile: no available file, create thumbnail, path: %{public}s",
600         DfxUtils::GetSafePath(fileName).c_str());
601     if (!GenerateKeyFrameLocalThumbnail(opts, data, thumbType)) {
602         MEDIA_ERR_LOG("GenerateKeyFrameLocalThumbnail failed");
603         return E_THUMBNAIL_LOCAL_CREATE_FAIL;
604     }
605     if (!opts.path.empty()) {
606         fileName = GetThumbnailPathHighlight(data.path, thumbSuffix, data.timeStamp);
607     }
608     return E_OK;
609 }
610 
IsLocalThumbnailAvailable(ThumbnailData & data,ThumbnailType thumbType)611 bool IsLocalThumbnailAvailable(ThumbnailData &data, ThumbnailType thumbType)
612 {
613     string tmpPath = "";
614     switch (thumbType) {
615         case ThumbnailType::THUMB:
616         case ThumbnailType::THUMB_ASTC:
617             tmpPath = GetLocalThumbnailPath(data.path, THUMBNAIL_THUMB_SUFFIX);
618             break;
619         case ThumbnailType::LCD:
620             tmpPath =  GetLocalThumbnailPath(data.path, THUMBNAIL_LCD_SUFFIX);
621             break;
622         default:
623             break;
624     }
625     return access(tmpPath.c_str(), F_OK) == 0;
626 }
627 
IsLocalKeyFrameThumbnailAvailable(ThumbnailData & data,int32_t type)628 bool IsLocalKeyFrameThumbnailAvailable(ThumbnailData &data, int32_t type)
629 {
630     string tmpPath = "";
631     switch (type) {
632         case KEY_FRAME_THM:
633         case KEY_FRAME_THM_ASTC:
634             tmpPath = GetLocalKeyFrameThumbnailPath(data.path, THUMBNAIL_THUMB_SUFFIX, data.timeStamp);
635             break;
636         case KEY_FRAME_LCD:
637             tmpPath = GetLocalKeyFrameThumbnailPath(data.path, THUMBNAIL_LCD_SUFFIX, data.timeStamp);
638             break;
639         default:
640             break;
641     }
642     return access(tmpPath.c_str(), F_OK) == 0;
643 }
644 
UpdateStreamReadThumbDbStatus(ThumbRdbOpt & opts,ThumbnailData & data,ThumbnailType thumbType)645 void UpdateStreamReadThumbDbStatus(ThumbRdbOpt& opts, ThumbnailData& data, ThumbnailType thumbType)
646 {
647     ValuesBucket values;
648     Size tmpSize;
649     if (!ThumbnailUtils::GetLocalThumbSize(data, thumbType, tmpSize)) {
650         return;
651     }
652     switch (thumbType) {
653         case ThumbnailType::LCD:
654             ThumbnailUtils::SetThumbnailSizeValue(values, tmpSize, PhotoColumn::PHOTO_LCD_SIZE);
655             values.PutLong(PhotoColumn::PHOTO_LCD_VISIT_TIME, static_cast<int64_t>(LcdReady::GENERATE_LCD_COMPLETED));
656             break;
657         case ThumbnailType::THUMB:
658         case ThumbnailType::THUMB_ASTC:
659             ThumbnailUtils::SetThumbnailSizeValue(values, tmpSize, PhotoColumn::PHOTO_THUMB_SIZE);
660             break;
661         default:
662             break;
663     }
664     int changedRows = 0;
665     int32_t err = opts.store->Update(changedRows, opts.table, values, MEDIA_DATA_DB_ID + " = ?",
666         vector<string> { data.id });
667     if (err != NativeRdb::E_OK) {
668         MEDIA_ERR_LOG("UpdateStreamReadThumbDbStatus failed! %{public}d", err);
669     }
670 }
671 
UpdateThumbStatus(ThumbRdbOpt & opts,ThumbnailType thumbType,ThumbnailData & thumbnailData,int & err,bool & isLocalThumbnailAvailable)672 void UpdateThumbStatus(ThumbRdbOpt &opts, ThumbnailType thumbType, ThumbnailData& thumbnailData, int& err,
673     bool& isLocalThumbnailAvailable)
674 {
675     if (!isLocalThumbnailAvailable) {
676         UpdateStreamReadThumbDbStatus(opts, thumbnailData, thumbType);
677     }
678     if (thumbType == ThumbnailType::LCD && opts.table == PhotoColumn::PHOTOS_TABLE) {
679         ThumbnailUtils::UpdateVisitTime(opts, thumbnailData, err);
680     }
681 }
682 
GetThumbnailPixelMap(ThumbRdbOpt & opts,ThumbnailType thumbType)683 int32_t ThumbnailGenerateHelper::GetThumbnailPixelMap(ThumbRdbOpt &opts, ThumbnailType thumbType)
684 {
685     ThumbnailWait thumbnailWait(false);
686     thumbnailWait.CheckAndWait(opts.row, thumbType == ThumbnailType::LCD);
687     ThumbnailData thumbnailData;
688     ThumbnailUtils::GetThumbnailInfo(opts, thumbnailData);
689 
690     int err;
691     ThumbnailUtils::QueryThumbnailDataFromFileId(opts, thumbnailData.id, thumbnailData, err);
692 
693     string fileName;
694     err = GetAvailableFile(opts, thumbnailData, thumbType, fileName);
695     if (err != E_OK) {
696         MEDIA_ERR_LOG("GetAvailableFile failed, path: %{public}s", DfxUtils::GetSafePath(thumbnailData.path).c_str());
697         return err;
698     }
699     bool isLocalThumbnailAvailable = IsLocalThumbnailAvailable(thumbnailData, thumbType);
700     DfxTimer dfxTimer(thumbType == ThumbnailType::LCD ? DfxType::CLOUD_LCD_OPEN : DfxType::CLOUD_DEFAULT_OPEN,
701         INVALID_DFX, thumbType == ThumbnailType::LCD ? CLOUD_LCD_TIME_OUT : CLOUD_DEFAULT_TIME_OUT, false);
702 
703     string absFilePath;
704     if (!PathToRealPath(fileName, absFilePath)) {
705         MEDIA_ERR_LOG("file is not real path, file path: %{public}s", DfxUtils::GetSafePath(fileName).c_str());
706         return E_ERR;
707     }
708 
709     auto fd = open(absFilePath.c_str(), O_RDONLY);
710     dfxTimer.End();
711     if (fd < 0) {
712         DfxManager::GetInstance()->HandleThumbnailError(absFilePath,
713             thumbType == ThumbnailType::LCD ? DfxType::CLOUD_LCD_OPEN : DfxType::CLOUD_DEFAULT_OPEN, -errno);
714         return -errno;
715     }
716     if (thumbnailData.isOpeningCloudFile && thumbnailData.orientation != 0) {
717         if (thumbnailData.mediaType == MEDIA_TYPE_VIDEO) {
718             MEDIA_INFO_LOG("No need to rotate video file, path: %{public}s",
719                 DfxUtils::GetSafePath(thumbnailData.path).c_str());
720             thumbnailData.orientation = 0;
721         }
722         IThumbnailHelper::DoRotateThumbnailEx(opts, thumbnailData, fd, thumbType);
723         fileName = GetThumbnailPath(thumbnailData.path,
724             thumbType == ThumbnailType::LCD ? THUMBNAIL_LCD_SUFFIX : THUMBNAIL_THUMB_SUFFIX);
725         if (!PathToRealPath(fileName, absFilePath)) {
726             MEDIA_ERR_LOG("file is not real path, file path: %{public}s", DfxUtils::GetSafePath(fileName).c_str());
727             return E_ERR;
728         }
729 
730         fd = open(absFilePath.c_str(), O_RDONLY);
731         if (fd < 0) {
732             MEDIA_ERR_LOG("Rotate thumb failed, path: %{public}s", DfxUtils::GetSafePath(thumbnailData.path).c_str());
733             DfxManager::GetInstance()->HandleThumbnailError(absFilePath,
734                 thumbType == ThumbnailType::LCD ? DfxType::CLOUD_LCD_OPEN : DfxType::CLOUD_DEFAULT_OPEN, -errno);
735             return -errno;
736         }
737     }
738     UpdateThumbStatus(opts, thumbType, thumbnailData, err, isLocalThumbnailAvailable);
739     return fd;
740 }
741 
GetKeyFrameThumbnailPixelMap(ThumbRdbOpt & opts,int32_t & timeStamp,int32_t & type)742 int32_t ThumbnailGenerateHelper::GetKeyFrameThumbnailPixelMap(ThumbRdbOpt &opts, int32_t &timeStamp, int32_t &type)
743 {
744     ThumbnailWait thumbnailWait(false);
745     thumbnailWait.CheckAndWait(opts.row, type == KEY_FRAME_LCD);
746     vector<int> trackInfos;
747     int32_t errTracks = E_ERR;
748     if (!ThumbnailUtils::GetHighlightTracks(opts, trackInfos, errTracks)) {
749         MEDIA_ERR_LOG("Failed to GetHighlightTracks %{public}d", errTracks);
750         return errTracks;
751     }
752     if (find(trackInfos.begin(), trackInfos.end(), timeStamp) == trackInfos.end()) {
753         timeStamp = 0;
754         MEDIA_ERR_LOG("Not the frame of the highlight tracks, return the first frame");
755     }
756 
757     ThumbnailData thumbnailData;
758     thumbnailData.path = opts.path;
759     thumbnailData.id = opts.row;
760     thumbnailData.dateTaken = opts.dateTaken;
761     thumbnailData.fileUri = opts.fileUri;
762     thumbnailData.stats.uri = thumbnailData.fileUri;
763     thumbnailData.timeStamp = std::to_string(timeStamp);
764     thumbnailData.tracks = "tracks";
765 
766     string fileName;
767     int err = GetAvailableKeyFrameFile(opts, thumbnailData, type, fileName);
768     if (err != E_OK) {
769         MEDIA_ERR_LOG("GetAvailableKeyFrameFile failed, path: %{public}s",
770             DfxUtils::GetSafePath(thumbnailData.path).c_str());
771         return err;
772     }
773 
774     string absFilePath;
775     if (!PathToRealPath(fileName, absFilePath)) {
776         MEDIA_ERR_LOG("file is not real path, file path: %{public}s",
777             DfxUtils::GetSafePath(fileName).c_str());
778         return E_ERR;
779     }
780 
781     auto fd = open(absFilePath.c_str(), O_RDONLY);
782     if (fd < 0) {
783         MEDIA_ERR_LOG("GetKeyFrameThumbnailPixelMap: open file failed path: %{public}s, errno:%{public}d",
784             DfxUtils::GetSafePath(thumbnailData.path).c_str(), errno);
785         return E_ERR;
786     }
787     return fd;
788 }
789 
GenerateHighlightThumbnailBackground(ThumbRdbOpt & opts)790 int32_t ThumbnailGenerateHelper::GenerateHighlightThumbnailBackground(ThumbRdbOpt &opts)
791 {
792     if (opts.store == nullptr) {
793         MEDIA_ERR_LOG("rdbStore is not init");
794         return E_ERR;
795     }
796 
797     vector<ThumbnailData> infos;
798     int32_t err = GetNoHighlightData(opts, infos);
799     if (err != E_OK) {
800         MEDIA_ERR_LOG("Failed to GetNoHighlightData %{public}d", err);
801         return err;
802     }
803     if (infos.empty()) {
804         MEDIA_DEBUG_LOG("No need generate highlight thumbnail.");
805         return E_OK;
806     }
807 
808     for (uint32_t i = 0; i < infos.size(); i++) {
809         opts.row = infos[i].id;
810         infos[i].loaderOpts.loadingStates = SourceLoader::LOCAL_SOURCE_LOADING_STATES;
811         IThumbnailHelper::AddThumbnailGenerateTask(IThumbnailHelper::CreateLcdAndThumbnail,
812             opts, infos[i], ThumbnailTaskType::BACKGROUND, ThumbnailTaskPriority::LOW);
813     }
814     return E_OK;
815 }
816 
TriggerHighlightThumbnail(ThumbRdbOpt & opts,std::string & id,std::string & tracks,std::string & trigger,std::string & genType)817 int32_t ThumbnailGenerateHelper::TriggerHighlightThumbnail(ThumbRdbOpt &opts, std::string &id, std::string &tracks,
818     std::string &trigger, std::string &genType)
819 {
820     ThumbnailData data;
821     data.id = id;
822     data.tracks = tracks;
823     data.trigger = trigger;
824 
825     int32_t err = E_ERR;
826     if (!ThumbnailUtils::QueryHighlightTriggerPath(opts, data, err)) {
827         MEDIA_ERR_LOG("Failed to QueryHighlightTriggerPath %{public}d", err);
828         return err;
829     }
830     if (genType == MEDIA_DATA_DB_UPDATE_TYPE && ThumbnailUtils::DeleteBeginTimestampDir(data)) {
831         MEDIA_INFO_LOG("Delete beginTimeStampDir success");
832     }
833     opts.row = data.id;
834     data.loaderOpts.loadingStates = SourceLoader::LOCAL_SOURCE_LOADING_STATES;
835     IThumbnailHelper::AddThumbnailGenerateTask(IThumbnailHelper::CreateLcdAndThumbnail,
836         opts, data, ThumbnailTaskType::BACKGROUND, ThumbnailTaskPriority::LOW);
837     return E_OK;
838 }
839 
UpgradeThumbnailBackground(ThumbRdbOpt & opts,bool isWifiConnected)840 int32_t ThumbnailGenerateHelper::UpgradeThumbnailBackground(ThumbRdbOpt &opts, bool isWifiConnected)
841 {
842     if (opts.store == nullptr) {
843         MEDIA_ERR_LOG("rdbStore is not init");
844         return E_ERR;
845     }
846     CHECK_AND_RETURN_RET_LOG(ThumbnailUtils::CheckRemainSpaceMeetCondition(THUMBNAIL_FREE_SIZE_LIMIT_10),
847         E_FREE_SIZE_NOT_ENOUGH, "Free size is not enough");
848 
849     vector<ThumbnailData> infos;
850     int32_t err = GetThumbnailDataNeedUpgrade(opts, infos, isWifiConnected);
851     if (err != E_OK) {
852         MEDIA_ERR_LOG("Failed to GetThumbnailDataNeedUpgrade %{public}d", err);
853         return err;
854     }
855     if (infos.empty()) {
856         MEDIA_DEBUG_LOG("No need upgrade thumbnail.");
857         return E_OK;
858     }
859     MEDIA_INFO_LOG("Will upgrade %{public}zu photo thumbnails, wifi: %{public}d.", infos.size(), isWifiConnected);
860     for (uint32_t i = 0; i < infos.size(); i++) {
861         opts.row = infos[i].id;
862         ThumbnailUtils::RecordStartGenerateStats(infos[i].stats, GenerateScene::UPGRADE, LoadSourceType::LOCAL_PHOTO);
863         infos[i].loaderOpts.loadingStates = (infos[i].mediaType == MEDIA_TYPE_VIDEO) ?
864             SourceLoader::UPGRADE_VIDEO_SOURCE_LOADING_STATES : SourceLoader::UPGRADE_SOURCE_LOADING_STATES;
865         IThumbnailHelper::AddThumbnailGenerateTask(IThumbnailHelper::CreateLcdAndThumbnail,
866             opts, infos[i], ThumbnailTaskType::BACKGROUND, ThumbnailTaskPriority::LOW);
867     }
868     return E_OK;
869 }
870 
RestoreAstcDualFrame(ThumbRdbOpt & opts,const int32_t & restoreAstcCount)871 int32_t ThumbnailGenerateHelper::RestoreAstcDualFrame(ThumbRdbOpt &opts, const int32_t &restoreAstcCount)
872 {
873     CHECK_AND_RETURN_RET_LOG(restoreAstcCount > 0, E_ERR, "RestoreAstcCount:%{public}d is invalid", restoreAstcCount);
874     CHECK_AND_RETURN_RET_LOG(opts.store != nullptr, E_ERR, "RdbStore is not init");
875     vector<ThumbnailData> infos;
876     int32_t err = 0;
877     if (!ThumbnailUtils::QueryNoAstcInfosRestored(opts, infos, err, restoreAstcCount)) {
878         MEDIA_ERR_LOG("Failed to QueryNoAstcInfosRestored %{public}d", err);
879         return err;
880     }
881     if (infos.empty()) {
882         MEDIA_INFO_LOG("No photos need resotre astc.");
883         return E_OK;
884     }
885 
886     MEDIA_INFO_LOG("create astc for restored dual frame photos count:%{public}zu, restoreAstcCount:%{public}d",
887         infos.size(), restoreAstcCount);
888 
889     for (auto &info : infos) {
890         opts.row = info.id;
891         info.loaderOpts.loadingStates = SourceLoader::LOCAL_SOURCE_LOADING_STATES;
892         ThumbnailUtils::RecordStartGenerateStats(info.stats, GenerateScene::RESTORE, LoadSourceType::LOCAL_PHOTO);
893         IThumbnailHelper::AddThumbnailGenerateTask(IThumbnailHelper::CreateThumbnail, opts, info,
894             ThumbnailTaskType::FOREGROUND, ThumbnailTaskPriority::MID);
895     }
896 
897     MEDIA_INFO_LOG("create astc for restored dual frame photos finished");
898     return E_OK;
899 }
900 
GetThumbnailDataNeedUpgrade(ThumbRdbOpt & opts,std::vector<ThumbnailData> & outDatas,bool isWifiConnected)901 int32_t ThumbnailGenerateHelper::GetThumbnailDataNeedUpgrade(ThumbRdbOpt &opts, std::vector<ThumbnailData> &outDatas,
902     bool isWifiConnected)
903 {
904     int32_t err = E_ERR;
905     if (!ThumbnailUtils::QueryUpgradeThumbnailInfos(opts, outDatas, isWifiConnected, err)) {
906         MEDIA_ERR_LOG("Failed to QueryUpgradeThumbnailInfos %{public}d", err);
907         return err;
908     }
909     return E_OK;
910 }
911 
CheckMonthAndYearKvStoreValid(ThumbRdbOpt & opts)912 void ThumbnailGenerateHelper::CheckMonthAndYearKvStoreValid(ThumbRdbOpt &opts)
913 {
914     bool isMonthKvStoreValid = MediaLibraryKvStoreManager::GetInstance().IsKvStoreValid(KvStoreValueType::MONTH_ASTC);
915     bool isYearKvStoreValid = MediaLibraryKvStoreManager::GetInstance().IsKvStoreValid(KvStoreValueType::YEAR_ASTC);
916     if (isMonthKvStoreValid && isYearKvStoreValid) {
917         return;
918     }
919 
920     if (opts.store == nullptr) {
921         MEDIA_ERR_LOG("rdbStore is not init");
922         return;
923     }
924 
925     MEDIA_INFO_LOG("KvStore is invalid, start update rdb");
926     if (opts.store->ExecuteSql(SQL_REFRESH_THUMBNAIL_READY) != NativeRdb::E_OK) {
927         MEDIA_ERR_LOG("Update rdb failed");
928         return;
929     }
930     MEDIA_INFO_LOG("Update rdb successfully");
931 
932     if (!isMonthKvStoreValid) {
933         MediaLibraryKvStoreManager::GetInstance().RebuildInvalidKvStore(KvStoreValueType::MONTH_ASTC);
934     }
935 
936     if (!isYearKvStoreValid) {
937         MediaLibraryKvStoreManager::GetInstance().RebuildInvalidKvStore(KvStoreValueType::YEAR_ASTC);
938     }
939 
940     Acl::AclSetDatabase();
941     MEDIA_INFO_LOG("RebuildInvalidKvStore finish, isMonthKvStoreValid: %{public}d, isYearKvStoreValid: %{public}d",
942         isMonthKvStoreValid, isYearKvStoreValid);
943 }
944 } // namespace Media
945 } // namespace OHOS
946