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