1 /*
2 * Copyright (C) 2022-2023 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
16 #define MLOG_TAG "Thumbnail"
17
18 #include "thumbnail_utils.h"
19
20 #include <fcntl.h>
21 #include <malloc.h>
22 #include <sys/stat.h>
23
24 #include "cloud_sync_helper.h"
25 #include "datashare_helper.h"
26 #include "datashare_abs_result_set.h"
27 #ifdef DISTRIBUTED
28 #include "device_manager.h"
29 #endif
30 #include "dfx_utils.h"
31 #include "directory_ex.h"
32 #include "distributed_kv_data_manager.h"
33 #include "hitrace_meter.h"
34 #include "image_packer.h"
35 #include "ipc_skeleton.h"
36 #include "iservice_registry.h"
37 #include "media_column.h"
38 #ifdef DISTRIBUTED
39 #include "media_device_column.h"
40 #endif
41 #include "media_exif.h"
42 #include "media_remote_thumbnail_column.h"
43 #include "medialibrary_common_utils.h"
44 #include "medialibrary_errno.h"
45 #include "medialibrary_kvstore_manager.h"
46 #include "medialibrary_sync_operation.h"
47 #include "medialibrary_tracer.h"
48 #include "media_file_utils.h"
49 #include "media_log.h"
50 #include "mimetype_utils.h"
51 #include "parameter.h"
52 #include "post_proc.h"
53 #include "rdb_errno.h"
54 #include "result_set_utils.h"
55 #include "thumbnail_const.h"
56 #include "thumbnail_source_loading.h"
57 #include "unique_fd.h"
58 #include "wifi_device.h"
59 #include "post_event_utils.h"
60 #include "dfx_manager.h"
61 #include "image_format_convert.h"
62
63 using namespace std;
64 using namespace OHOS::DistributedKv;
65 using namespace OHOS::NativeRdb;
66
67 namespace OHOS {
68 namespace Media {
69
70 static constexpr int STORAGE_MANAGER_MANAGER_ID = 5003;
71 static const std::string CLOUD_DATASHARE_URI = "datashareproxy://com.huawei.hmos.clouddrive/cloud_sp?Proxy=true";
72
73 #ifdef DISTRIBUTED
DeleteDistributeLcdData(ThumbRdbOpt & opts,ThumbnailData & thumbnailData)74 bool ThumbnailUtils::DeleteDistributeLcdData(ThumbRdbOpt &opts, ThumbnailData &thumbnailData)
75 {
76 if (thumbnailData.lcdKey.empty()) {
77 MEDIA_ERR_LOG("lcd Key is empty");
78 return false;
79 }
80
81 if (IsImageExist(thumbnailData.lcdKey, opts.networkId, opts.kvStore)) {
82 if (!RemoveDataFromKv(opts.kvStore, thumbnailData.lcdKey)) {
83 MEDIA_ERR_LOG("ThumbnailUtils::RemoveDataFromKv faild");
84 return false;
85 }
86 if (!CleanDistributeLcdInfo(opts)) {
87 return false;
88 }
89 }
90
91 return true;
92 }
93 #endif
94
GetThumbnailSuffix(ThumbnailType type)95 std::string ThumbnailUtils::GetThumbnailSuffix(ThumbnailType type)
96 {
97 string suffix;
98 switch (type) {
99 case ThumbnailType::THUMB:
100 suffix = THUMBNAIL_THUMB_SUFFIX;
101 break;
102 case ThumbnailType::THUMB_ASTC:
103 suffix = THUMBNAIL_THUMBASTC_SUFFIX;
104 break;
105 case ThumbnailType::LCD:
106 suffix = THUMBNAIL_LCD_SUFFIX;
107 break;
108 default:
109 return "";
110 }
111 return suffix;
112 }
113
DeleteThumbFile(ThumbnailData & data,ThumbnailType type)114 bool ThumbnailUtils::DeleteThumbFile(ThumbnailData &data, ThumbnailType type)
115 {
116 string fileName = GetThumbnailPath(data.path, GetThumbnailSuffix(type));
117 if (!MediaFileUtils::DeleteFile(fileName)) {
118 MEDIA_ERR_LOG("delete file faild %{public}d", errno);
119 VariantMap map = {{KEY_ERR_FILE, __FILE__}, {KEY_ERR_LINE, __LINE__}, {KEY_ERR_CODE, -errno},
120 {KEY_OPT_FILE, fileName}, {KEY_OPT_TYPE, OptType::THUMB}};
121 PostEventUtils::GetInstance().PostErrorProcess(ErrType::FILE_OPT_ERR, map);
122 return false;
123 }
124 return true;
125 }
126
DeleteThumbExDir(ThumbnailData & data)127 bool ThumbnailUtils::DeleteThumbExDir(ThumbnailData &data)
128 {
129 string fileName = GetThumbnailPath(data.path, THUMBNAIL_THUMB_EX_SUFFIX);
130 string dirName = MediaFileUtils::GetParentPath(fileName);
131 if (access(dirName.c_str(), F_OK) != 0) {
132 MEDIA_INFO_LOG("No need to delete THM_EX, directory not exists path: %{public}s, id: %{public}s",
133 DfxUtils::GetSafePath(dirName).c_str(), data.id.c_str());
134 return true;
135 }
136 if (!MediaFileUtils::DeleteDir(dirName)) {
137 MEDIA_INFO_LOG("Failed to delete THM_EX directory, path: %{public}s, id: %{public}s",
138 DfxUtils::GetSafePath(dirName).c_str(), data.id.c_str());
139 return false;
140 }
141 return true;
142 }
143
LoadAudioFileInfo(shared_ptr<AVMetadataHelper> avMetadataHelper,ThumbnailData & data,Size & desiredSize,uint32_t & errCode)144 bool ThumbnailUtils::LoadAudioFileInfo(shared_ptr<AVMetadataHelper> avMetadataHelper, ThumbnailData &data,
145 Size &desiredSize, uint32_t &errCode)
146 {
147 if (avMetadataHelper == nullptr || avMetadataHelper->FetchArtPicture() == nullptr) {
148 MEDIA_ERR_LOG("FetchArtPicture failed!");
149 return false;
150 }
151
152 auto audioPicMemory = avMetadataHelper->FetchArtPicture();
153 SourceOptions opts;
154 unique_ptr<ImageSource> audioImageSource = ImageSource::CreateImageSource(audioPicMemory->GetBase(),
155 audioPicMemory->GetSize(), opts, errCode);
156 if (audioImageSource == nullptr) {
157 MEDIA_ERR_LOG("Failed to create image source! path %{public}s errCode %{public}d",
158 DfxUtils::GetSafePath(data.path).c_str(), errCode);
159 return false;
160 }
161
162 ImageInfo imageInfo;
163 errCode = audioImageSource->GetImageInfo(0, imageInfo);
164 if (errCode != E_OK) {
165 MEDIA_ERR_LOG("Failed to get image info, path: %{public}s err: %{public}d",
166 DfxUtils::GetSafePath(data.path).c_str(), errCode);
167 return false;
168 }
169 data.stats.sourceWidth = imageInfo.size.width;
170 data.stats.sourceHeight = imageInfo.size.height;
171
172 DecodeOptions decOpts;
173 decOpts.desiredSize = ConvertDecodeSize(data, imageInfo.size, desiredSize);
174 decOpts.desiredPixelFormat = PixelFormat::RGBA_8888;
175 auto pixelMapPtr = audioImageSource->CreatePixelMap(decOpts, errCode);
176 std::shared_ptr<PixelMap> pixelMap = std::move(pixelMapPtr);
177 if ((errCode != E_OK) || (pixelMap == nullptr)) {
178 MEDIA_ERR_LOG("Av meta data helper fetch frame at time failed");
179 if (errCode != E_OK) {
180 VariantMap map = {{KEY_ERR_FILE, __FILE__}, {KEY_ERR_LINE, __LINE__},
181 {KEY_ERR_CODE, static_cast<int32_t>(errCode)}, {KEY_OPT_FILE, data.path},
182 {KEY_OPT_TYPE, OptType::THUMB}};
183 PostEventUtils::GetInstance().PostErrorProcess(ErrType::FILE_OPT_ERR, map);
184 }
185 return false;
186 }
187 data.source.SetPixelMap(pixelMap);
188 return true;
189 }
190
LoadAudioFile(ThumbnailData & data,Size & desiredSize)191 bool ThumbnailUtils::LoadAudioFile(ThumbnailData &data, Size &desiredSize)
192 {
193 shared_ptr<AVMetadataHelper> avMetadataHelper = AVMetadataHelperFactory::CreateAVMetadataHelper();
194 string path = data.path;
195 int32_t err = SetSource(avMetadataHelper, path);
196 if (err != E_OK) {
197 MEDIA_ERR_LOG("Av meta data helper set source failed %{public}d", err);
198 return false;
199 }
200 uint32_t errCode = 0;
201 if (!LoadAudioFileInfo(avMetadataHelper, data, desiredSize, errCode)) {
202 VariantMap map = {{KEY_ERR_FILE, __FILE__}, {KEY_ERR_LINE, __LINE__},
203 {KEY_ERR_CODE, static_cast<int32_t>(errCode)}, {KEY_OPT_FILE, path}, {KEY_OPT_TYPE, OptType::THUMB}};
204 PostEventUtils::GetInstance().PostErrorProcess(ErrType::FILE_OPT_ERR, map);
205 return false;
206 }
207 return true;
208 }
209
LoadVideoFile(ThumbnailData & data,Size & desiredSize)210 bool ThumbnailUtils::LoadVideoFile(ThumbnailData &data, Size &desiredSize)
211 {
212 shared_ptr<AVMetadataHelper> avMetadataHelper = AVMetadataHelperFactory::CreateAVMetadataHelper();
213 string path = data.path;
214 int32_t err = SetSource(avMetadataHelper, path);
215 if (err != 0) {
216 return false;
217 }
218 int32_t videoWidth = 0;
219 int32_t videoHeight = 0;
220 if (!ParseVideoSize(avMetadataHelper, videoWidth, videoHeight)) {
221 return false;
222 }
223 PixelMapParams param;
224 param.colorFormat = PixelFormat::RGBA_8888;
225 ConvertDecodeSize(data, {videoWidth, videoHeight}, desiredSize);
226 param.dstWidth = desiredSize.width;
227 param.dstHeight = desiredSize.height;
228 std::shared_ptr<PixelMap> pixelMap;
229 pixelMap = avMetadataHelper->FetchFrameYuv(AV_FRAME_TIME, AVMetadataQueryOption::AV_META_QUERY_NEXT_SYNC,
230 param);
231 if (pixelMap == nullptr) {
232 DfxManager::GetInstance()->HandleThumbnailError(path, DfxType::AV_FETCH_FRAME, err);
233 return false;
234 }
235 if (pixelMap->GetPixelFormat() == PixelFormat::YCBCR_P010) {
236 uint32_t ret = ImageFormatConvert::ConvertImageFormat(pixelMap, PixelFormat::RGBA_1010102);
237 if (ret != E_OK) {
238 MEDIA_ERR_LOG("PixelMapYuv10ToRGBA_1010102: source ConvertImageFormat fail");
239 return false;
240 }
241 }
242
243 data.source.SetPixelMap(pixelMap);
244 data.orientation = 0;
245 data.stats.sourceWidth = pixelMap->GetWidth();
246 data.stats.sourceHeight = pixelMap->GetHeight();
247 DfxManager::GetInstance()->HandleHighMemoryThumbnail(path, MEDIA_TYPE_VIDEO, videoWidth, videoHeight);
248 return true;
249 }
250
ParseVideoSize(std::shared_ptr<AVMetadataHelper> & avMetadataHelper,int32_t & videoWidth,int32_t & videoHeight)251 bool ThumbnailUtils::ParseVideoSize(std::shared_ptr<AVMetadataHelper> &avMetadataHelper,
252 int32_t &videoWidth, int32_t &videoHeight)
253 {
254 auto resultMap = avMetadataHelper->ResolveMetadata();
255 if (resultMap.empty()) {
256 MEDIA_ERR_LOG("map of video size is empty");
257 return false;
258 }
259 int32_t rotation = 0;
260 const std::string strOfRotation = resultMap.at(AVMetadataCode::AV_KEY_VIDEO_ORIENTATION);
261 if (strOfRotation.empty()) {
262 // The field of rotation may be empty, and if it is empty, it means rotation is zero
263 MEDIA_INFO_LOG("rotation is zero");
264 } else if (!ConvertStrToInt32(strOfRotation, rotation)) {
265 MEDIA_ERR_LOG("Parse rotation from resultmap error");
266 return false;
267 }
268
269 bool needRevolve = ((rotation + VERTICAL_ANGLE) % STRAIGHT_ANGLE != 0);
270 if (!ConvertStrToInt32(resultMap.at(AVMetadataCode::AV_KEY_VIDEO_WIDTH),
271 needRevolve ? videoWidth : videoHeight)) {
272 MEDIA_ERR_LOG("Parse width from resultmap error");
273 return false;
274 }
275 if (!ConvertStrToInt32(resultMap.at(AVMetadataCode::AV_KEY_VIDEO_HEIGHT),
276 needRevolve ? videoHeight : videoWidth)) {
277 MEDIA_ERR_LOG("Parse height from resultmap error");
278 return false;
279 }
280 return true;
281 }
282
283 // gen pixelmap from data.souce.pixelMapSource, should ensure source is not null
GenTargetPixelmap(ThumbnailData & data,const Size & desiredSize)284 bool ThumbnailUtils::GenTargetPixelmap(ThumbnailData &data, const Size &desiredSize)
285 {
286 MediaLibraryTracer tracer;
287 tracer.Start("GenTargetPixelmap");
288 auto pixelMap = data.source.GetPixelMap();
289 if (pixelMap == nullptr) {
290 return false;
291 }
292
293 if (!ScaleFastThumb(data, desiredSize)) {
294 return false;
295 }
296
297 float widthScale = (1.0f * desiredSize.width) / pixelMap->GetWidth();
298 float heightScale = (1.0f * desiredSize.height) / pixelMap->GetHeight();
299 pixelMap->scale(widthScale, heightScale);
300 return true;
301 }
302
ScaleTargetPixelMap(std::shared_ptr<PixelMap> & dataSource,const Size & targetSize,const AntiAliasingOption & option)303 bool ThumbnailUtils::ScaleTargetPixelMap(std::shared_ptr<PixelMap> &dataSource, const Size &targetSize,
304 const AntiAliasingOption &option)
305 {
306 MediaLibraryTracer tracer;
307 tracer.Start("ImageSource::ScaleTargetPixelMap");
308
309 PostProc postProc;
310 if (!postProc.ScalePixelMapEx(targetSize, *dataSource, option)) {
311 MEDIA_ERR_LOG("Fail to scale to target thumbnail, ScalePixelMapEx failed, targetSize: %{public}d * %{public}d",
312 targetSize.width, targetSize.height);
313 return false;
314 }
315 return true;
316 }
317
CenterScaleEx(std::shared_ptr<PixelMap> & dataSource,const Size & desiredSize,const std::string path)318 bool ThumbnailUtils::CenterScaleEx(std::shared_ptr<PixelMap> &dataSource, const Size &desiredSize,
319 const std::string path)
320 {
321 if (dataSource->GetHeight() * dataSource->GetWidth() == 0) {
322 MEDIA_ERR_LOG("Invalid source size, ScalePixelMapEx failed, path: %{public}s",
323 DfxUtils::GetSafePath(path).c_str());
324 return false;
325 }
326 float sourceScale = static_cast<float>(dataSource->GetHeight()) / static_cast<float>(dataSource->GetWidth());
327 float scale = 1.0f;
328 if (sourceScale <= 1.0f) {
329 scale = static_cast<float>(desiredSize.height) / static_cast<float>(dataSource->GetHeight());
330 } else {
331 scale = static_cast<float>(desiredSize.width) / static_cast<float>(dataSource->GetWidth());
332 }
333
334 MediaLibraryTracer tracer;
335 tracer.Start("CenterScaleEx");
336 if (std::abs(scale - 1.0f) > FLOAT_EPSILON) {
337 Size targetSize = {
338 static_cast<int32_t>(scale * dataSource->GetWidth()),
339 static_cast<int32_t>(scale * dataSource->GetHeight())
340 };
341 if (!ScaleTargetPixelMap(dataSource, targetSize, Media::AntiAliasingOption::GAUSS)) {
342 MEDIA_ERR_LOG("Fail in CenterScaleEx, ScalePixelMapEx failed, path: %{public}s",
343 DfxUtils::GetSafePath(path).c_str());
344 return false;
345 }
346 }
347
348 MediaLibraryTracer innerTracer;
349 innerTracer.Start("CenterScale");
350 PostProc postProc;
351 if (!postProc.CenterScale(desiredSize, *dataSource)) {
352 MEDIA_ERR_LOG("Fail in CenterScaleEx, CenterScale failed, path: %{public}s",
353 DfxUtils::GetSafePath(path).c_str());
354 return false;
355 }
356 return true;
357 }
358
LoadImageFile(ThumbnailData & data,Size & desiredSize)359 bool ThumbnailUtils::LoadImageFile(ThumbnailData &data, Size &desiredSize)
360 {
361 mallopt(M_SET_THREAD_CACHE, M_THREAD_CACHE_DISABLE);
362 mallopt(M_DELAYED_FREE, M_DELAYED_FREE_DISABLE);
363
364 SourceLoader sourceLoader(desiredSize, data);
365 return sourceLoader.RunLoading();
366 }
367
CompressImage(shared_ptr<PixelMap> & pixelMap,vector<uint8_t> & data,bool isAstc,bool forceSdr,const uint8_t quality)368 bool ThumbnailUtils::CompressImage(shared_ptr<PixelMap> &pixelMap, vector<uint8_t> &data, bool isAstc,
369 bool forceSdr, const uint8_t quality)
370 {
371 PackOption option = {
372 .format = isAstc ? THUMBASTC_FORMAT : THUMBNAIL_FORMAT,
373 .quality = isAstc ? ASTC_LOW_QUALITY : quality,
374 .numberHint = NUMBER_HINT_1,
375 .desiredDynamicRange = forceSdr ? EncodeDynamicRange::SDR :EncodeDynamicRange::AUTO
376 };
377 data.resize(max(pixelMap->GetByteCount(), MIN_COMPRESS_BUF_SIZE));
378
379 MediaLibraryTracer tracer;
380 tracer.Start("imagePacker.StartPacking");
381 ImagePacker imagePacker;
382 uint32_t err = imagePacker.StartPacking(data.data(), data.size(), option);
383 tracer.Finish();
384 if (err != E_OK) {
385 MEDIA_ERR_LOG("Failed to StartPacking %{public}d", err);
386 return false;
387 }
388
389 tracer.Start("imagePacker.AddImage");
390 err = imagePacker.AddImage(*pixelMap);
391 tracer.Finish();
392 if (err != E_OK) {
393 MEDIA_ERR_LOG("Failed to StartPacking %{public}d", err);
394 return false;
395 }
396
397 tracer.Start("imagePacker.FinalizePacking");
398 int64_t packedSize = 0;
399 err = imagePacker.FinalizePacking(packedSize);
400 if (err != E_OK) {
401 MEDIA_ERR_LOG("Failed to StartPacking %{public}d", err);
402 return false;
403 }
404
405 data.resize(packedSize);
406 return true;
407 }
408
CheckAfterPacking(const std::string & tempOutputPath,const std::string & outputPath)409 bool CheckAfterPacking(const std::string &tempOutputPath, const std::string &outputPath)
410 {
411 size_t size = -1;
412 MediaFileUtils::GetFileSize(tempOutputPath, size);
413 if (size == 0 && !MediaFileUtils::DeleteFile(tempOutputPath)) {
414 MEDIA_ERR_LOG("CompressPicture failed, failed to delete temp filters file: %{public}s",
415 DfxUtils::GetSafePath(tempOutputPath).c_str());
416 return false;
417 }
418 int ret = rename(tempOutputPath.c_str(), outputPath.c_str());
419 if (ret != E_SUCCESS) {
420 MEDIA_ERR_LOG("CompressPicture failed, failed to rename temp filters file: %{public}s",
421 DfxUtils::GetSafePath(tempOutputPath).c_str());
422 return false;
423 }
424 if (MediaFileUtils::IsFileExists(tempOutputPath)) {
425 MEDIA_INFO_LOG("file: %{public}s exists, needs to be deleted", DfxUtils::GetSafePath(tempOutputPath).c_str());
426 if (!MediaFileUtils::DeleteFile(tempOutputPath)) {
427 MEDIA_ERR_LOG("delete file: %{public}s failed", DfxUtils::GetSafePath(tempOutputPath).c_str());
428 }
429 }
430 return true;
431 }
432
CompressPicture(ThumbnailData & data,bool isSourceEx)433 bool ThumbnailUtils::CompressPicture(ThumbnailData &data, bool isSourceEx)
434 {
435 CHECK_AND_RETURN_RET_LOG(
436 THUMBNAIL_QUALITY_SET.count(data.thumbnailQuality),
437 false,
438 "compress thumbnail quality not in thumbnail quality set, quality: %{public}d",
439 data.thumbnailQuality);
440
441 MEDIA_INFO_LOG("CompressPicture %{public}s", DfxUtils::GetSafePath(data.path).c_str());
442 auto outputPath = GetThumbnailPath(data.path, THUMBNAIL_LCD_SUFFIX);
443 auto picture = isSourceEx ? data.source.GetPictureEx() : data.source.GetPicture();
444 if (picture == nullptr) {
445 MEDIA_ERR_LOG("CompressPicture failed, source is nullptr, path: %{public}s",
446 DfxUtils::GetSafePath(data.path).c_str());
447 return false;
448 }
449 Media::ImagePacker imagePacker;
450 PackOption option = {
451 .format = THUMBNAIL_FORMAT,
452 .quality = data.thumbnailQuality,
453 .numberHint = NUMBER_HINT_1,
454 .desiredDynamicRange = EncodeDynamicRange::AUTO,
455 .needsPackProperties = false
456 };
457 int ret = SaveFileCreateDir(data.path, isSourceEx ? THUMBNAIL_LCD_EX_SUFFIX : THUMBNAIL_LCD_SUFFIX, outputPath);
458 if (ret != E_OK) {
459 MEDIA_ERR_LOG("CompressPicture failed, SaveFileCreateDir failed, path: %{public}s, isSourceEx: %{public}d",
460 DfxUtils::GetSafePath(data.path).c_str(), isSourceEx);
461 return false;
462 }
463 size_t lastSlash = outputPath.rfind('/');
464 if (lastSlash == string::npos || outputPath.size() <= lastSlash + 1) {
465 MEDIA_ERR_LOG("CompressPicture failed, failed to check outputPath: %{public}s, isSourceEx: %{public}d",
466 DfxUtils::GetSafePath(data.path).c_str(), isSourceEx);
467 return false;
468 }
469 string tempOutputPath = outputPath.substr(0, lastSlash) + "/temp_" + outputPath.substr(lastSlash + 1);
470 ret = MediaFileUtils::CreateAsset(tempOutputPath);
471 if (ret != E_SUCCESS) {
472 MEDIA_ERR_LOG("CompressPicture failed, failed to create temp filter file: %{public}s, isSourceEx: %{public}d",
473 DfxUtils::GetSafePath(data.path).c_str(), isSourceEx);
474 return false;
475 }
476 imagePacker.StartPacking(tempOutputPath, option);
477 imagePacker.AddPicture(*(picture));
478 imagePacker.FinalizePacking();
479 CheckAfterPacking(tempOutputPath, outputPath);
480 return true;
481 }
482
QueryThumbnailSet(ThumbRdbOpt & opts)483 shared_ptr<ResultSet> ThumbnailUtils::QueryThumbnailSet(ThumbRdbOpt &opts)
484 {
485 vector<string> column = {
486 MEDIA_DATA_DB_ID,
487 MEDIA_DATA_DB_FILE_PATH,
488 MEDIA_DATA_DB_MEDIA_TYPE,
489 };
490
491 vector<string> selectionArgs;
492 string strQueryCondition = MEDIA_DATA_DB_ID + " = " + opts.row;
493
494 RdbPredicates rdbPredicates(opts.table);
495 rdbPredicates.SetWhereClause(strQueryCondition);
496 rdbPredicates.SetWhereArgs(selectionArgs);
497 if (opts.store == nullptr) {
498 MEDIA_ERR_LOG("opts.store is nullptr");
499 return nullptr;
500 }
501 return opts.store->QueryByStep(rdbPredicates, column);
502 }
503
QueryThumbnailInfo(ThumbRdbOpt & opts,ThumbnailData & data,int & err)504 shared_ptr<ResultSet> ThumbnailUtils::QueryThumbnailInfo(ThumbRdbOpt &opts,
505 ThumbnailData &data, int &err)
506 {
507 vector<string> column = {
508 MEDIA_DATA_DB_ID,
509 MEDIA_DATA_DB_FILE_PATH,
510 MEDIA_DATA_DB_MEDIA_TYPE,
511 };
512 MediaLibraryTracer tracer;
513 tracer.Start("QueryThumbnailInfo");
514 auto resultSet = QueryThumbnailSet(opts);
515 if (!CheckResultSetCount(resultSet, err)) {
516 return nullptr;
517 }
518
519 err = resultSet->GoToFirstRow();
520 if (err != E_OK) {
521 VariantMap map = {{KEY_ERR_FILE, __FILE__}, {KEY_ERR_LINE, __LINE__}, {KEY_ERR_CODE, err},
522 {KEY_OPT_TYPE, OptType::THUMB}};
523 PostEventUtils::GetInstance().PostErrorProcess(ErrType::DB_OPT_ERR, map);
524 return nullptr;
525 }
526
527 ParseQueryResult(resultSet, data, err, column);
528 return resultSet;
529 }
530
QueryLcdCount(ThumbRdbOpt & opts,int & outLcdCount,int & err)531 bool ThumbnailUtils::QueryLcdCount(ThumbRdbOpt &opts, int &outLcdCount, int &err)
532 {
533 vector<string> column = {
534 MEDIA_DATA_DB_ID,
535 };
536 RdbPredicates rdbPredicates(opts.table);
537 if (opts.table == PhotoColumn::PHOTOS_TABLE) {
538 rdbPredicates.EqualTo(PhotoColumn::PHOTO_LAST_VISIT_TIME, "0");
539 }
540 rdbPredicates.NotEqualTo(MEDIA_DATA_DB_MEDIA_TYPE, to_string(MEDIA_TYPE_FILE));
541 rdbPredicates.NotEqualTo(MEDIA_DATA_DB_MEDIA_TYPE, to_string(MEDIA_TYPE_ALBUM));
542 if (opts.store == nullptr) {
543 MEDIA_ERR_LOG("opts.store is nullptr");
544 return false;
545 }
546 auto resultSet = opts.store->QueryByStep(rdbPredicates, column);
547 if (resultSet == nullptr) {
548 MEDIA_ERR_LOG("ResultSet is nullptr");
549 return false;
550 }
551 int rowCount = 0;
552 err = resultSet->GetRowCount(rowCount);
553 resultSet.reset();
554 if (err != E_OK) {
555 MEDIA_ERR_LOG("Failed to get row count %{public}d", err);
556 return false;
557 }
558 MEDIA_DEBUG_LOG("rowCount is %{public}d", rowCount);
559 if (rowCount <= 0) {
560 MEDIA_INFO_LOG("No match! %{private}s", rdbPredicates.ToString().c_str());
561 rowCount = 0;
562 }
563
564 outLcdCount = rowCount;
565 return true;
566 }
567
QueryLcdCountByTime(const int64_t & time,const bool & before,ThumbRdbOpt & opts,int & outLcdCount,int & err)568 bool ThumbnailUtils::QueryLcdCountByTime(const int64_t &time, const bool &before, ThumbRdbOpt &opts, int &outLcdCount,
569 int &err)
570 {
571 vector<string> column = {
572 MEDIA_DATA_DB_ID,
573 };
574 RdbPredicates rdbPredicates(opts.table);
575 if (opts.table == PhotoColumn::PHOTOS_TABLE) {
576 if (before) {
577 rdbPredicates.LessThanOrEqualTo(PhotoColumn::PHOTO_LAST_VISIT_TIME, to_string(time));
578 } else {
579 rdbPredicates.GreaterThan(PhotoColumn::PHOTO_LAST_VISIT_TIME, to_string(time));
580 }
581 }
582 rdbPredicates.NotEqualTo(MEDIA_DATA_DB_MEDIA_TYPE, to_string(MEDIA_TYPE_FILE));
583 rdbPredicates.NotEqualTo(MEDIA_DATA_DB_MEDIA_TYPE, to_string(MEDIA_TYPE_ALBUM));
584 if (opts.store == nullptr) {
585 MEDIA_ERR_LOG("opts.store is nullptr");
586 return false;
587 }
588 auto resultSet = opts.store->QueryByStep(rdbPredicates, column);
589 if (resultSet == nullptr) {
590 MEDIA_ERR_LOG("ResultSet is nullptr");
591 return false;
592 }
593 int rowCount = 0;
594 err = resultSet->GetRowCount(rowCount);
595 resultSet.reset();
596 if (err != E_OK) {
597 MEDIA_ERR_LOG("Failed to get row count %{public}d", err);
598 return false;
599 }
600 MEDIA_DEBUG_LOG("rowCount is %{public}d", rowCount);
601 if (rowCount <= 0) {
602 MEDIA_INFO_LOG("No match! %{private}s", rdbPredicates.ToString().c_str());
603 rowCount = 0;
604 }
605
606 outLcdCount = rowCount;
607 return true;
608 }
609
QueryDistributeLcdCount(ThumbRdbOpt & opts,int & outLcdCount,int & err)610 bool ThumbnailUtils::QueryDistributeLcdCount(ThumbRdbOpt &opts, int &outLcdCount, int &err)
611 {
612 vector<string> column = {
613 REMOTE_THUMBNAIL_DB_ID,
614 };
615 RdbPredicates rdbPredicates(REMOTE_THUMBNAIL_TABLE);
616 rdbPredicates.EqualTo(REMOTE_THUMBNAIL_DB_UDID, opts.udid);
617 rdbPredicates.IsNotNull(MEDIA_DATA_DB_LCD);
618 if (opts.store == nullptr) {
619 MEDIA_ERR_LOG("opts.store is nullptr");
620 return false;
621 }
622 auto resultSet = opts.store->QueryByStep(rdbPredicates, column);
623 if (resultSet == nullptr) {
624 return false;
625 }
626 int rowCount = 0;
627 err = resultSet->GetRowCount(rowCount);
628 resultSet.reset();
629 if (err != E_OK) {
630 MEDIA_ERR_LOG("Failed to get row count %{public}d", err);
631 return false;
632 }
633 MEDIA_INFO_LOG("rowCount is %{public}d", rowCount);
634 if (rowCount <= 0) {
635 MEDIA_INFO_LOG("No match! %{private}s", rdbPredicates.ToString().c_str());
636 rowCount = 0;
637 }
638 outLcdCount = rowCount;
639 return true;
640 }
641
642 #ifdef DISTRIBUTED
QueryAgingDistributeLcdInfos(ThumbRdbOpt & opts,int LcdLimit,vector<ThumbnailData> & infos,int & err)643 bool ThumbnailUtils::QueryAgingDistributeLcdInfos(ThumbRdbOpt &opts, int LcdLimit,
644 vector<ThumbnailData> &infos, int &err)
645 {
646 vector<string> column = {
647 REMOTE_THUMBNAIL_DB_FILE_ID,
648 MEDIA_DATA_DB_LCD
649 };
650 RdbPredicates rdbPredicates(REMOTE_THUMBNAIL_TABLE);
651 rdbPredicates.IsNotNull(MEDIA_DATA_DB_LCD);
652 rdbPredicates.EqualTo(REMOTE_THUMBNAIL_DB_UDID, opts.udid);
653
654 rdbPredicates.Limit(LcdLimit);
655 if (opts.store == nullptr) {
656 MEDIA_ERR_LOG("opts.store is nullptr");
657 return false;
658 }
659 shared_ptr<ResultSet> resultSet = opts.store->QueryByStep(rdbPredicates, column);
660 if (!CheckResultSetCount(resultSet, err)) {
661 MEDIA_ERR_LOG("CheckResultSetCount failed %{public}d", err);
662 return false;
663 }
664
665 err = resultSet->GoToFirstRow();
666 if (err != E_OK) {
667 MEDIA_ERR_LOG("Failed GoToFirstRow %{public}d", err);
668 return false;
669 }
670
671 ThumbnailData data;
672 do {
673 ParseQueryResult(resultSet, data, err, column);
674 if (!data.lcdKey.empty()) {
675 infos.push_back(data);
676 }
677 } while (resultSet->GoToNextRow() == E_OK);
678 return true;
679 }
680 #endif
681
QueryAgingLcdInfos(ThumbRdbOpt & opts,int LcdLimit,vector<ThumbnailData> & infos,int & err)682 bool ThumbnailUtils::QueryAgingLcdInfos(ThumbRdbOpt &opts, int LcdLimit,
683 vector<ThumbnailData> &infos, int &err)
684 {
685 vector<string> column = {
686 MEDIA_DATA_DB_ID,
687 MEDIA_DATA_DB_FILE_PATH,
688 MEDIA_DATA_DB_MEDIA_TYPE,
689 };
690 RdbPredicates rdbPredicates(opts.table);
691 rdbPredicates.NotEqualTo(MEDIA_DATA_DB_MEDIA_TYPE, to_string(MEDIA_TYPE_FILE));
692 rdbPredicates.NotEqualTo(MEDIA_DATA_DB_MEDIA_TYPE, to_string(MEDIA_TYPE_ALBUM));
693
694 rdbPredicates.Limit(LcdLimit);
695 if (opts.table == PhotoColumn::PHOTOS_TABLE) {
696 rdbPredicates.OrderByAsc(PhotoColumn::PHOTO_LAST_VISIT_TIME);
697 }
698 if (opts.store == nullptr) {
699 MEDIA_ERR_LOG("opts.store is nullptr");
700 return false;
701 }
702 shared_ptr<ResultSet> resultSet = opts.store->QueryByStep(rdbPredicates, column);
703 if (!CheckResultSetCount(resultSet, err)) {
704 MEDIA_ERR_LOG("CheckResultSetCount failed %{public}d", err);
705 return false;
706 }
707
708 err = resultSet->GoToFirstRow();
709 if (err != E_OK) {
710 MEDIA_ERR_LOG("Failed GoToFirstRow %{public}d", err);
711 return false;
712 }
713
714 ThumbnailData data;
715 do {
716 ParseQueryResult(resultSet, data, err, column);
717 if (!data.path.empty()) {
718 infos.push_back(data);
719 }
720 } while (resultSet->GoToNextRow() == E_OK);
721 return true;
722 }
723
QueryNoLcdInfos(ThumbRdbOpt & opts,vector<ThumbnailData> & infos,int & err)724 bool ThumbnailUtils::QueryNoLcdInfos(ThumbRdbOpt &opts, vector<ThumbnailData> &infos, int &err)
725 {
726 vector<string> column = {
727 MEDIA_DATA_DB_ID,
728 MEDIA_DATA_DB_FILE_PATH,
729 MEDIA_DATA_DB_MEDIA_TYPE,
730 MEDIA_DATA_DB_POSITION,
731 MEDIA_DATA_DB_ORIENTATION,
732 };
733 RdbPredicates rdbPredicates(opts.table);
734 rdbPredicates.EqualTo(PhotoColumn::PHOTO_LCD_VISIT_TIME, "0");
735 rdbPredicates.EqualTo(PhotoColumn::PHOTO_POSITION, "1");
736 rdbPredicates.OrderByDesc(MEDIA_DATA_DB_DATE_TAKEN);
737 if (opts.store == nullptr) {
738 MEDIA_ERR_LOG("opts.store is nullptr");
739 return false;
740 }
741 shared_ptr<ResultSet> resultSet = opts.store->QueryByStep(rdbPredicates, column);
742 if (!CheckResultSetCount(resultSet, err)) {
743 MEDIA_ERR_LOG("QueryNoLcdInfos failed %{public}d", err);
744 if (err == E_EMPTY_VALUES_BUCKET) {
745 return true;
746 }
747 return false;
748 }
749
750 err = resultSet->GoToFirstRow();
751 if (err != E_OK) {
752 MEDIA_ERR_LOG("QueryNoLcdInfos failed GoToFirstRow %{public}d", err);
753 return false;
754 }
755
756 ThumbnailData data;
757 do {
758 ParseQueryResult(resultSet, data, err, column);
759 if (!data.path.empty()) {
760 infos.push_back(data);
761 }
762 } while (resultSet->GoToNextRow() == E_OK);
763 return true;
764 }
765
QueryLocalNoLcdInfos(ThumbRdbOpt & opts,vector<ThumbnailData> & infos,int & err)766 bool ThumbnailUtils::QueryLocalNoLcdInfos(ThumbRdbOpt &opts, vector<ThumbnailData> &infos, int &err)
767 {
768 if (opts.store == nullptr) {
769 MEDIA_ERR_LOG("opts.store is nullptr");
770 return false;
771 }
772 vector<string> column = {
773 MEDIA_DATA_DB_ID,
774 MEDIA_DATA_DB_FILE_PATH,
775 MEDIA_DATA_DB_MEDIA_TYPE,
776 };
777 RdbPredicates rdbPredicates(opts.table);
778 rdbPredicates.EqualTo(PhotoColumn::PHOTO_LCD_VISIT_TIME, "0");
779 rdbPredicates.EqualTo(PhotoColumn::PHOTO_DIRTY, "1");
780 rdbPredicates.Limit(MAXIMUM_LCD_CHECK_NUM);
781 rdbPredicates.OrderByDesc(MEDIA_DATA_DB_DATE_TAKEN);
782 shared_ptr<ResultSet> resultSet = opts.store->QueryByStep(rdbPredicates, column);
783 if (!CheckResultSetCount(resultSet, err)) {
784 MEDIA_ERR_LOG("QueryLocalNoLcdInfos failed %{public}d", err);
785 if (err == E_EMPTY_VALUES_BUCKET) {
786 return true;
787 }
788 return false;
789 }
790
791 err = resultSet->GoToFirstRow();
792 if (err != E_OK) {
793 MEDIA_ERR_LOG("QueryLocalNoLcdInfos failed GoToFirstRow %{public}d", err);
794 return false;
795 }
796
797 ThumbnailData data;
798 do {
799 ParseQueryResult(resultSet, data, err, column);
800 if (!data.path.empty()) {
801 infos.push_back(data);
802 }
803 } while (resultSet->GoToNextRow() == E_OK);
804 return true;
805 }
806
QueryNoThumbnailInfos(ThumbRdbOpt & opts,vector<ThumbnailData> & infos,int & err)807 bool ThumbnailUtils::QueryNoThumbnailInfos(ThumbRdbOpt &opts, vector<ThumbnailData> &infos, int &err)
808 {
809 vector<string> column = { MEDIA_DATA_DB_ID, MEDIA_DATA_DB_FILE_PATH, MEDIA_DATA_DB_MEDIA_TYPE };
810 RdbPredicates rdbPredicates(opts.table);
811 if (opts.table == PhotoColumn::PHOTOS_TABLE) {
812 rdbPredicates.EqualTo(PhotoColumn::PHOTO_LAST_VISIT_TIME, "0");
813 }
814 if ((opts.table == PhotoColumn::PHOTOS_TABLE) || (opts.table == AudioColumn::AUDIOS_TABLE)) {
815 rdbPredicates.EqualTo(MediaColumn::MEDIA_DATE_TRASHED, "0");
816 } else {
817 rdbPredicates.EqualTo(MEDIA_DATA_DB_IS_TRASH, "0");
818 }
819 rdbPredicates.EqualTo(MEDIA_DATA_DB_TIME_PENDING, "0");
820 rdbPredicates.NotEqualTo(MEDIA_DATA_DB_MEDIA_TYPE, to_string(MEDIA_TYPE_ALBUM));
821 rdbPredicates.NotEqualTo(MEDIA_DATA_DB_MEDIA_TYPE, to_string(MEDIA_TYPE_FILE));
822 if (opts.table == PhotoColumn::PHOTOS_TABLE) {
823 // Filter data that Only exists in Cloud to avoid cosuming data of downloading the original image
824 // meaning of Position: 1--only in local, 2--only in cloud, 3--both in local and cloud
825 rdbPredicates.BeginWrap()->EqualTo(PhotoColumn::PHOTO_POSITION, "1")->Or()->
826 EqualTo(PhotoColumn::PHOTO_POSITION, "3")->EndWrap();
827 }
828 rdbPredicates.Limit(THUMBNAIL_QUERY_MAX);
829 rdbPredicates.OrderByDesc(MEDIA_DATA_DB_DATE_TAKEN);
830 if (opts.store == nullptr) {
831 MEDIA_ERR_LOG("opts.store is nullptr");
832 return false;
833 }
834 shared_ptr<ResultSet> resultSet = opts.store->QueryByStep(rdbPredicates, column);
835 if (!CheckResultSetCount(resultSet, err)) {
836 MEDIA_ERR_LOG("CheckResultSetCount failed %{public}d", err);
837 if (err == E_EMPTY_VALUES_BUCKET) {
838 return true;
839 }
840 return false;
841 }
842 err = resultSet->GoToFirstRow();
843 if (err != E_OK) {
844 MEDIA_ERR_LOG("Failed GoToFirstRow %{public}d", err);
845 return false;
846 }
847 ThumbnailData data;
848 do {
849 ParseQueryResult(resultSet, data, err, column);
850 if (!data.path.empty()) {
851 infos.push_back(data);
852 }
853 } while (resultSet->GoToNextRow() == E_OK);
854 return true;
855 }
856
QueryUpgradeThumbnailInfos(ThumbRdbOpt & opts,vector<ThumbnailData> & infos,bool isWifiConnected,int & err)857 bool ThumbnailUtils::QueryUpgradeThumbnailInfos(ThumbRdbOpt &opts, vector<ThumbnailData> &infos,
858 bool isWifiConnected, int &err)
859 {
860 vector<string> column = {
861 MEDIA_DATA_DB_ID,
862 MEDIA_DATA_DB_FILE_PATH,
863 MEDIA_DATA_DB_MEDIA_TYPE,
864 MEDIA_DATA_DB_DATE_ADDED,
865 MEDIA_DATA_DB_NAME,
866 MEDIA_DATA_DB_DATE_TAKEN,
867 };
868 RdbPredicates rdbPredicates(opts.table);
869 rdbPredicates.EqualTo(PhotoColumn::PHOTO_THUMBNAIL_READY, std::to_string(
870 static_cast<int32_t>(ThumbnailReady::THUMB_UPGRADE)));
871 if (!isWifiConnected) {
872 rdbPredicates.NotEqualTo(PhotoColumn::PHOTO_POSITION, "2");
873 }
874 rdbPredicates.OrderByDesc(MEDIA_DATA_DB_DATE_TAKEN);
875 if (opts.store == nullptr) {
876 MEDIA_ERR_LOG("opts.store is nullptr");
877 return false;
878 }
879 shared_ptr<ResultSet> resultSet = opts.store->QueryByStep(rdbPredicates, column);
880 if (!CheckResultSetCount(resultSet, err)) {
881 MEDIA_ERR_LOG("CheckResultSetCount failed %{public}d", err);
882 if (err == E_EMPTY_VALUES_BUCKET) {
883 return true;
884 }
885 return false;
886 }
887
888 err = resultSet->GoToFirstRow();
889 if (err != E_OK) {
890 MEDIA_ERR_LOG("Failed GoToFirstRow %{public}d", err);
891 return false;
892 }
893
894 ThumbnailData data;
895 do {
896 ParseQueryResult(resultSet, data, err, column);
897 if (!data.path.empty()) {
898 infos.push_back(data);
899 }
900 } while (resultSet->GoToNextRow() == E_OK);
901 return true;
902 }
903
QueryNoAstcInfosRestored(ThumbRdbOpt & opts,vector<ThumbnailData> & infos,int & err)904 bool ThumbnailUtils::QueryNoAstcInfosRestored(ThumbRdbOpt &opts, vector<ThumbnailData> &infos, int &err)
905 {
906 vector<string> column = {
907 MEDIA_DATA_DB_ID,
908 MEDIA_DATA_DB_FILE_PATH,
909 MEDIA_DATA_DB_MEDIA_TYPE,
910 MEDIA_DATA_DB_DATE_ADDED,
911 MEDIA_DATA_DB_NAME,
912 MEDIA_DATA_DB_POSITION,
913 MEDIA_DATA_DB_DATE_TAKEN,
914 };
915 RdbPredicates rdbPredicates(opts.table);
916 rdbPredicates.EqualTo(PhotoColumn::PHOTO_THUMBNAIL_READY, "0");
917 rdbPredicates.BeginWrap()->EqualTo(PhotoColumn::PHOTO_POSITION, "1")->Or()->
918 EqualTo(PhotoColumn::PHOTO_POSITION, "3")->EndWrap();
919 rdbPredicates.OrderByDesc(MEDIA_DATA_DB_DATE_TAKEN);
920 rdbPredicates.Limit(ASTC_GENERATE_COUNT_AFTER_RESTORE);
921 if (opts.store == nullptr) {
922 MEDIA_ERR_LOG("opts.store is nullptr");
923 return false;
924 }
925 shared_ptr<ResultSet> resultSet = opts.store->QueryByStep(rdbPredicates, column);
926 if (!CheckResultSetCount(resultSet, err)) {
927 MEDIA_ERR_LOG("CheckResultSetCount failed %{public}d", err);
928 if (err == E_EMPTY_VALUES_BUCKET) {
929 return true;
930 }
931 return false;
932 }
933
934 err = resultSet->GoToFirstRow();
935 if (err != E_OK) {
936 MEDIA_ERR_LOG("Failed GoToFirstRow %{public}d", err);
937 return false;
938 }
939
940 ThumbnailData data;
941 do {
942 ParseQueryResult(resultSet, data, err, column);
943 if (!data.path.empty()) {
944 infos.push_back(data);
945 }
946 } while (resultSet->GoToNextRow() == E_OK);
947 return true;
948 }
949
QueryNoAstcInfos(ThumbRdbOpt & opts,vector<ThumbnailData> & infos,int & err)950 bool ThumbnailUtils::QueryNoAstcInfos(ThumbRdbOpt &opts, vector<ThumbnailData> &infos, int &err)
951 {
952 vector<string> column = {
953 MEDIA_DATA_DB_ID, MEDIA_DATA_DB_FILE_PATH, MEDIA_DATA_DB_MEDIA_TYPE, MEDIA_DATA_DB_DATE_TAKEN,
954 MEDIA_DATA_DB_NAME, MEDIA_DATA_DB_POSITION, MEDIA_DATA_DB_ORIENTATION,
955 };
956 RdbPredicates rdbPredicates(opts.table);
957 rdbPredicates.BeginWrap()
958 ->EqualTo(PhotoColumn::PHOTO_THUMBNAIL_READY, "0")
959 ->Or()->EqualTo(PhotoColumn::PHOTO_THUMBNAIL_READY, "2")
960 ->Or()->EqualTo(PhotoColumn::PHOTO_THUMBNAIL_READY, "7")
961 ->EndWrap();
962 rdbPredicates.BeginWrap()
963 ->BeginWrap()
964 ->EqualTo(PhotoColumn::PHOTO_POSITION, "1")->Or()->EqualTo(PhotoColumn::PHOTO_POSITION, "3")
965 ->EndWrap()->Or()->BeginWrap()
966 ->EqualTo(PhotoColumn::PHOTO_POSITION, "2")->And()->EqualTo(PhotoColumn::PHOTO_THUMB_STATUS, "0")
967 ->EndWrap()->EndWrap();
968 rdbPredicates.OrderByDesc(MEDIA_DATA_DB_DATE_TAKEN);
969 if (opts.store == nullptr) {
970 MEDIA_ERR_LOG("opts.store is nullptr");
971 return false;
972 }
973 shared_ptr<ResultSet> resultSet = opts.store->QueryByStep(rdbPredicates, column);
974 if (!CheckResultSetCount(resultSet, err)) {
975 MEDIA_ERR_LOG("CheckResultSetCount failed %{public}d", err);
976 if (err == E_EMPTY_VALUES_BUCKET) {
977 return true;
978 }
979 return false;
980 }
981
982 err = resultSet->GoToFirstRow();
983 if (err != E_OK) {
984 MEDIA_ERR_LOG("Failed GoToFirstRow %{public}d", err);
985 return false;
986 }
987
988 ThumbnailData data;
989 do {
990 ParseQueryResult(resultSet, data, err, column);
991 if (!data.path.empty()) {
992 infos.push_back(data);
993 }
994 } while (resultSet->GoToNextRow() == E_OK);
995 return true;
996 }
997
QueryNewThumbnailCount(ThumbRdbOpt & opts,const int64_t & time,int & count,int & err)998 bool ThumbnailUtils::QueryNewThumbnailCount(ThumbRdbOpt &opts, const int64_t &time, int &count,
999 int &err)
1000 {
1001 vector<string> column = {
1002 MEDIA_DATA_DB_ID,
1003 };
1004 RdbPredicates rdbPredicates(opts.table);
1005 if (opts.table == PhotoColumn::PHOTOS_TABLE) {
1006 rdbPredicates.GreaterThan(PhotoColumn::PHOTO_LAST_VISIT_TIME, to_string(time));
1007 }
1008 if (opts.table == MEDIALIBRARY_TABLE) {
1009 rdbPredicates.EqualTo(MEDIA_DATA_DB_IS_TRASH, "0");
1010 } else {
1011 rdbPredicates.EqualTo(MEDIA_DATA_DB_DATE_TRASHED, "0");
1012 }
1013 rdbPredicates.EqualTo(MEDIA_DATA_DB_TIME_PENDING, "0");
1014 rdbPredicates.NotEqualTo(MEDIA_DATA_DB_MEDIA_TYPE, to_string(MEDIA_TYPE_ALBUM));
1015 rdbPredicates.NotEqualTo(MEDIA_DATA_DB_MEDIA_TYPE, to_string(MEDIA_TYPE_FILE));
1016
1017 rdbPredicates.OrderByDesc(MEDIA_DATA_DB_DATE_TAKEN);
1018 if (opts.store == nullptr) {
1019 MEDIA_ERR_LOG("opts.store is nullptr");
1020 return false;
1021 }
1022 shared_ptr<ResultSet> resultSet = opts.store->QueryByStep(rdbPredicates, column);
1023 if (resultSet == nullptr) {
1024 MEDIA_ERR_LOG("ResultSet is nullptr");
1025 return false;
1026 }
1027 int rowCount = 0;
1028 err = resultSet->GetRowCount(rowCount);
1029 resultSet.reset();
1030 if (err != E_OK) {
1031 MEDIA_ERR_LOG("Failed to get row count %{public}d", err);
1032 return false;
1033 }
1034 MEDIA_DEBUG_LOG("rowCount is %{public}d", rowCount);
1035 if (rowCount <= 0) {
1036 MEDIA_INFO_LOG("No match! %{public}s", rdbPredicates.ToString().c_str());
1037 rowCount = 0;
1038 }
1039
1040 count = rowCount;
1041 return true;
1042 }
1043
UpdateLcdInfo(ThumbRdbOpt & opts,ThumbnailData & data,int & err)1044 bool ThumbnailUtils::UpdateLcdInfo(ThumbRdbOpt &opts, ThumbnailData &data, int &err)
1045 {
1046 ValuesBucket values;
1047 int changedRows;
1048
1049 MediaLibraryTracer tracer;
1050 tracer.Start("UpdateLcdInfo opts.store->Update");
1051 values.PutLong(PhotoColumn::PHOTO_LAST_VISIT_TIME, MediaFileUtils::UTCTimeMilliSeconds());
1052 values.PutLong(PhotoColumn::PHOTO_LCD_VISIT_TIME, static_cast<int64_t>(LcdReady::GENERATE_LCD_COMPLETED));
1053
1054 Size lcdSize;
1055 if (GetLocalThumbSize(data, ThumbnailType::LCD, lcdSize)) {
1056 SetThumbnailSizeValue(values, lcdSize, PhotoColumn::PHOTO_LCD_SIZE);
1057 }
1058 if (opts.store == nullptr) {
1059 MEDIA_ERR_LOG("opts.store is nullptr");
1060 return false;
1061 }
1062 err = opts.store->Update(changedRows, opts.table, values, MEDIA_DATA_DB_ID + " = ?",
1063 vector<string> { opts.row });
1064 if (err != NativeRdb::E_OK) {
1065 MEDIA_ERR_LOG("RdbStore Update failed! %{public}d", err);
1066 return false;
1067 }
1068 return true;
1069 }
1070
UpdateVisitTime(ThumbRdbOpt & opts,ThumbnailData & data,int & err)1071 bool ThumbnailUtils::UpdateVisitTime(ThumbRdbOpt &opts, ThumbnailData &data, int &err)
1072 {
1073 #ifdef DISTRIBUTED
1074 if (!opts.networkId.empty()) {
1075 return DoUpdateRemoteThumbnail(opts, data, err);
1076 }
1077 #endif
1078
1079 ValuesBucket values;
1080 int changedRows;
1081 int64_t timeNow = UTCTimeMilliSeconds();
1082 values.PutLong(PhotoColumn::PHOTO_LAST_VISIT_TIME, timeNow);
1083 if (opts.store == nullptr) {
1084 MEDIA_ERR_LOG("opts.store is nullptr");
1085 return false;
1086 }
1087 err = opts.store->Update(changedRows, opts.table, values, MEDIA_DATA_DB_ID + " = ?",
1088 vector<string> { opts.row });
1089 if (err != NativeRdb::E_OK) {
1090 MEDIA_ERR_LOG("UpdateVisitTime rdbStore Update failed! %{public}d", err);
1091 return false;
1092 }
1093 return true;
1094 }
1095
UpdateLcdReadyStatus(ThumbRdbOpt & opts,ThumbnailData & data,int & err,LcdReady status)1096 bool ThumbnailUtils::UpdateLcdReadyStatus(ThumbRdbOpt &opts, ThumbnailData &data, int &err, LcdReady status)
1097 {
1098 ValuesBucket values;
1099 int changedRows;
1100 values.PutLong(PhotoColumn::PHOTO_LCD_VISIT_TIME, static_cast<int64_t>(status));
1101 if (opts.store == nullptr) {
1102 MEDIA_ERR_LOG("opts.store is nullptr");
1103 return false;
1104 }
1105 err = opts.store->Update(changedRows, opts.table, values, MEDIA_DATA_DB_ID + " = ?",
1106 vector<string> { opts.row });
1107 if (err != NativeRdb::E_OK) {
1108 MEDIA_ERR_LOG("UpdateLcdReadyStatus rdbStore Update failed! %{public}d", err);
1109 return false;
1110 }
1111 return true;
1112 }
1113
1114 #ifdef DISTRIBUTED
QueryDeviceThumbnailRecords(ThumbRdbOpt & opts,vector<ThumbnailData> & infos,int & err)1115 bool ThumbnailUtils::QueryDeviceThumbnailRecords(ThumbRdbOpt &opts, vector<ThumbnailData> &infos,
1116 int &err)
1117 {
1118 vector<string> column = {
1119 REMOTE_THUMBNAIL_DB_FILE_ID,
1120 MEDIA_DATA_DB_THUMBNAIL,
1121 MEDIA_DATA_DB_LCD
1122 };
1123 RdbPredicates rdbPredicates(REMOTE_THUMBNAIL_TABLE);
1124 rdbPredicates.EqualTo(REMOTE_THUMBNAIL_DB_UDID, opts.udid);
1125 if (opts.store == nullptr) {
1126 MEDIA_ERR_LOG("opts.store is nullptr");
1127 return false;
1128 }
1129 shared_ptr<ResultSet> resultSet = opts.store->QueryByStep(rdbPredicates, column);
1130 if (!CheckResultSetCount(resultSet, err)) {
1131 MEDIA_ERR_LOG("CheckResultSetCount failed %{public}d", err);
1132 return false;
1133 }
1134
1135 err = resultSet->GoToFirstRow();
1136 if (err != E_OK) {
1137 MEDIA_ERR_LOG("Failed GoToFirstRow %{public}d", err);
1138 return false;
1139 }
1140
1141 ThumbnailData data;
1142 do {
1143 ParseQueryResult(resultSet, data, err, column);
1144 infos.push_back(data);
1145 } while (resultSet->GoToNextRow() == E_OK);
1146 return true;
1147 }
1148
GetUdidByNetworkId(ThumbRdbOpt & opts,const string & networkId,string & outUdid,int & err)1149 bool ThumbnailUtils::GetUdidByNetworkId(ThumbRdbOpt &opts, const string &networkId,
1150 string &outUdid, int &err)
1151 {
1152 vector<string> column = {
1153 DEVICE_DB_ID,
1154 DEVICE_DB_UDID
1155 };
1156 RdbPredicates rdbPredicates(DEVICE_TABLE);
1157 rdbPredicates.EqualTo(DEVICE_DB_NETWORK_ID, networkId);
1158 if (opts.store == nullptr) {
1159 MEDIA_ERR_LOG("opts.store is nullptr");
1160 return false;
1161 }
1162 shared_ptr<ResultSet> resultSet = opts.store->QueryByStep(rdbPredicates, column);
1163 if (!CheckResultSetCount(resultSet, err)) {
1164 MEDIA_ERR_LOG("CheckResultSetCount failed %{public}d", err);
1165 return false;
1166 }
1167
1168 err = resultSet->GoToFirstRow();
1169 if (err != E_OK) {
1170 MEDIA_ERR_LOG("Failed GoToFirstRow %{public}d", err);
1171 return false;
1172 }
1173 int index;
1174 err = resultSet->GetColumnIndex(DEVICE_DB_UDID, index);
1175 if (err == NativeRdb::E_OK) {
1176 ParseStringResult(resultSet, index, outUdid, err);
1177 } else {
1178 MEDIA_ERR_LOG("Get column index error %{public}d", err);
1179 }
1180 return true;
1181 }
1182
QueryRemoteThumbnail(ThumbRdbOpt & opts,ThumbnailData & data,int & err)1183 bool ThumbnailUtils::QueryRemoteThumbnail(ThumbRdbOpt &opts, ThumbnailData &data, int &err)
1184 {
1185 if (data.udid.empty() && !GetUdidByNetworkId(opts, opts.networkId, data.udid, err)) {
1186 MEDIA_ERR_LOG("GetUdidByNetworkId failed! %{public}d", err);
1187 return false;
1188 }
1189
1190 vector<string> column = {
1191 REMOTE_THUMBNAIL_DB_ID,
1192 MEDIA_DATA_DB_THUMBNAIL,
1193 MEDIA_DATA_DB_LCD
1194 };
1195 RdbPredicates rdbPredicates(REMOTE_THUMBNAIL_TABLE);
1196 rdbPredicates.EqualTo(REMOTE_THUMBNAIL_DB_FILE_ID, data.id);
1197 rdbPredicates.EqualTo(REMOTE_THUMBNAIL_DB_UDID, data.udid);
1198 if (opts.store == nullptr) {
1199 MEDIA_ERR_LOG("opts.store is nullptr");
1200 return false;
1201 }
1202 shared_ptr<ResultSet> resultSet = opts.store->QueryByStep(rdbPredicates, column);
1203 if (!CheckResultSetCount(resultSet, err)) {
1204 MEDIA_ERR_LOG("CheckResultSetCount failed %{public}d", err);
1205 return false;
1206 }
1207
1208 err = resultSet->GoToFirstRow();
1209 if (err != E_OK) {
1210 MEDIA_ERR_LOG("Failed GoToFirstRow %{public}d", err);
1211 return false;
1212 }
1213
1214 int index;
1215 err = resultSet->GetColumnIndex(MEDIA_DATA_DB_LCD, index);
1216 if (err == NativeRdb::E_OK) {
1217 ParseStringResult(resultSet, index, data.lcdKey, err);
1218 }
1219
1220 err = resultSet->GetColumnIndex(MEDIA_DATA_DB_THUMBNAIL, index);
1221 if (err == NativeRdb::E_OK) {
1222 ParseStringResult(resultSet, index, data.thumbnailKey, err);
1223 }
1224 return true;
1225 }
1226
IsKeyNotSame(const string & newKey,const string & oldKey)1227 static inline bool IsKeyNotSame(const string &newKey, const string &oldKey)
1228 {
1229 return !newKey.empty() && !oldKey.empty() && (newKey != oldKey);
1230 }
1231
DoUpdateRemoteThumbnail(ThumbRdbOpt & opts,ThumbnailData & data,int & err)1232 bool ThumbnailUtils::DoUpdateRemoteThumbnail(ThumbRdbOpt &opts, ThumbnailData &data, int &err)
1233 {
1234 if (opts.networkId.empty()) {
1235 return false;
1236 }
1237 if (data.thumbnailKey.empty() && data.lcdKey.empty()) {
1238 return false;
1239 }
1240 ThumbnailData tmpData = data;
1241 auto isGot = ThumbnailUtils::QueryRemoteThumbnail(opts, tmpData, err);
1242 if (isGot) {
1243 if (IsKeyNotSame(data.thumbnailKey, tmpData.thumbnailKey)) {
1244 if (!RemoveDataFromKv(opts.kvStore, tmpData.thumbnailKey)) {
1245 return false;
1246 }
1247 }
1248 if (IsKeyNotSame(data.lcdKey, tmpData.lcdKey)) {
1249 if (!RemoveDataFromKv(opts.kvStore, tmpData.lcdKey)) {
1250 return false;
1251 }
1252 }
1253 }
1254
1255 data.udid = tmpData.udid;
1256 if (isGot) {
1257 return UpdateRemoteThumbnailInfo(opts, data, err);
1258 } else {
1259 return InsertRemoteThumbnailInfo(opts, data, err);
1260 }
1261 }
1262
UpdateRemoteThumbnailInfo(ThumbRdbOpt & opts,ThumbnailData & data,int & err)1263 bool ThumbnailUtils::UpdateRemoteThumbnailInfo(ThumbRdbOpt &opts, ThumbnailData &data, int &err)
1264 {
1265 RdbPredicates rdbPredicates(REMOTE_THUMBNAIL_TABLE);
1266 rdbPredicates.EqualTo(REMOTE_THUMBNAIL_DB_FILE_ID, data.id);
1267 rdbPredicates.EqualTo(REMOTE_THUMBNAIL_DB_UDID, data.udid);
1268
1269 ValuesBucket values;
1270 if (!data.thumbnailKey.empty()) {
1271 values.PutString(MEDIA_DATA_DB_THUMBNAIL, data.thumbnailKey);
1272 }
1273
1274 if (!data.lcdKey.empty()) {
1275 values.PutString(MEDIA_DATA_DB_LCD, data.lcdKey);
1276 }
1277
1278 int changedRows;
1279 if (opts.store == nullptr) {
1280 MEDIA_ERR_LOG("opts.store is nullptr");
1281 return false;
1282 }
1283 err = opts.store->Update(changedRows, values, rdbPredicates);
1284 if (err != NativeRdb::E_OK) {
1285 MEDIA_ERR_LOG("RdbStore Update failed! %{public}d", err);
1286 return false;
1287 }
1288
1289 return true;
1290 }
1291
InsertRemoteThumbnailInfo(ThumbRdbOpt & opts,ThumbnailData & data,int & err)1292 bool ThumbnailUtils::InsertRemoteThumbnailInfo(ThumbRdbOpt &opts, ThumbnailData &data, int &err)
1293 {
1294 ValuesBucket values;
1295 values.PutInt(REMOTE_THUMBNAIL_DB_FILE_ID, stoi(data.id));
1296 values.PutString(REMOTE_THUMBNAIL_DB_UDID, data.udid);
1297 if (!data.thumbnailKey.empty()) {
1298 values.PutString(MEDIA_DATA_DB_THUMBNAIL, data.thumbnailKey);
1299 }
1300
1301 if (!data.lcdKey.empty()) {
1302 values.PutString(MEDIA_DATA_DB_LCD, data.lcdKey);
1303 }
1304
1305 int64_t outRowId = -1;
1306 if (opts.store == nullptr) {
1307 MEDIA_ERR_LOG("opts.store is nullptr");
1308 return false;
1309 }
1310 err = opts.store->Insert(outRowId, REMOTE_THUMBNAIL_TABLE, values);
1311 if (err != NativeRdb::E_OK) {
1312 MEDIA_ERR_LOG("RdbStore Update failed! %{public}d", err);
1313 return false;
1314 }
1315 return true;
1316 }
1317 #endif
1318
CleanThumbnailInfo(ThumbRdbOpt & opts,bool withThumb,bool withLcd)1319 bool ThumbnailUtils::CleanThumbnailInfo(ThumbRdbOpt &opts, bool withThumb, bool withLcd)
1320 {
1321 ValuesBucket values;
1322 if (withThumb) {
1323 values.PutNull(MEDIA_DATA_DB_THUMBNAIL);
1324 }
1325 if (withLcd) {
1326 values.PutInt(MEDIA_DATA_DB_DIRTY, static_cast<int32_t>(DirtyType::TYPE_SYNCED));
1327 if (opts.table == MEDIALIBRARY_TABLE) {
1328 values.PutNull(MEDIA_DATA_DB_LCD);
1329 }
1330 if (opts.table == PhotoColumn::PHOTOS_TABLE) {
1331 values.PutLong(PhotoColumn::PHOTO_LAST_VISIT_TIME, 0);
1332 }
1333 }
1334 int changedRows;
1335 if (opts.store == nullptr) {
1336 MEDIA_ERR_LOG("opts.store is nullptr");
1337 return false;
1338 }
1339 auto err = opts.store->Update(changedRows, opts.table, values, MEDIA_DATA_DB_ID + " = ?",
1340 vector<string> { opts.row });
1341 if (err != NativeRdb::E_OK) {
1342 MEDIA_ERR_LOG("RdbStore Update failed! %{public}d", err);
1343 return false;
1344 }
1345 return true;
1346 }
1347
1348 #ifdef DISTRIBUTED
CleanDistributeLcdInfo(ThumbRdbOpt & opts)1349 bool ThumbnailUtils::CleanDistributeLcdInfo(ThumbRdbOpt &opts)
1350 {
1351 string udid;
1352 int err;
1353 if (!GetUdidByNetworkId(opts, opts.networkId, udid, err)) {
1354 MEDIA_ERR_LOG("GetUdidByNetworkId failed! %{public}d", err);
1355 return false;
1356 }
1357
1358 ValuesBucket values;
1359 values.PutNull(MEDIA_DATA_DB_LCD);
1360 int changedRows;
1361 vector<string> whereArgs = { udid, opts.row };
1362 string deleteCondition = REMOTE_THUMBNAIL_DB_UDID + " = ? AND " +
1363 REMOTE_THUMBNAIL_DB_FILE_ID + " = ?";
1364 if (opts.store == nullptr) {
1365 MEDIA_ERR_LOG("opts.store is nullptr");
1366 return false;
1367 }
1368 auto ret = opts.store->Update(changedRows, REMOTE_THUMBNAIL_TABLE, values, deleteCondition, whereArgs);
1369 if (ret != NativeRdb::E_OK) {
1370 MEDIA_ERR_LOG("RdbStore Delete failed! %{public}d", ret);
1371 return false;
1372 }
1373 return true;
1374 }
1375
DeleteDistributeThumbnailInfo(ThumbRdbOpt & opts)1376 bool ThumbnailUtils::DeleteDistributeThumbnailInfo(ThumbRdbOpt &opts)
1377 {
1378 int changedRows;
1379 vector<string> whereArgs = { opts.udid, opts.row };
1380 string deleteCondition = REMOTE_THUMBNAIL_DB_UDID + " = ? AND " +
1381 REMOTE_THUMBNAIL_DB_FILE_ID + " = ?";
1382 if (opts.store == nullptr) {
1383 MEDIA_ERR_LOG("opts.store is nullptr");
1384 return false;
1385 }
1386 auto err = opts.store->Delete(changedRows, REMOTE_THUMBNAIL_TABLE, deleteCondition, whereArgs);
1387 if (err != NativeRdb::E_OK) {
1388 MEDIA_ERR_LOG("RdbStore Delete failed! %{public}d", err);
1389 return false;
1390 }
1391 return true;
1392 }
1393 #endif
1394
PostProcPixelMapSource(ThumbnailData & data)1395 void PostProcPixelMapSource(ThumbnailData &data)
1396 {
1397 auto pixelMap = data.source.GetPixelMap();
1398 if (pixelMap == nullptr) {
1399 return;
1400 }
1401 pixelMap->SetAlphaType(AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL);
1402 if (data.orientation != 0) {
1403 if (data.isLocalFile) {
1404 Media::InitializationOptions opts;
1405 auto copySourcePtr = PixelMap::Create(*pixelMap, opts);
1406 std::shared_ptr<PixelMap> copySource = std::move(copySourcePtr);
1407 data.source.SetPixelMapEx(copySource);
1408 }
1409 pixelMap->rotate(static_cast<float>(data.orientation));
1410 }
1411
1412 // PixelMap has been rotated, fix the exif orientation to zero degree.
1413 pixelMap->ModifyImageProperty(PHOTO_DATA_IMAGE_ORIENTATION, DEFAULT_EXIF_ORIENTATION);
1414 }
1415
CopyPictureSource(std::shared_ptr<Picture> & picture,std::shared_ptr<Picture> & copySource)1416 bool ThumbnailUtils::CopyPictureSource(std::shared_ptr<Picture> &picture, std::shared_ptr<Picture> ©Source)
1417 {
1418 auto pixelMap = picture->GetMainPixel();
1419 auto gainMap = picture->GetGainmapPixelMap();
1420 if (pixelMap == nullptr || gainMap == nullptr) {
1421 return false;
1422 }
1423 Media::InitializationOptions pixelMapOpts = {
1424 .size = {pixelMap->GetWidth(), pixelMap->GetHeight()},
1425 .pixelFormat = pixelMap->GetPixelFormat(),
1426 .alphaType = pixelMap->GetAlphaType()
1427 };
1428 auto copyPixelMapPtr = PixelMap::Create(*pixelMap, pixelMapOpts);
1429 std::shared_ptr<PixelMap> copyPixelMap = std::move(copyPixelMapPtr);
1430 if (copyPixelMap == nullptr) {
1431 return false;
1432 }
1433
1434 Media::InitializationOptions gainMapOpts = {
1435 .size = {gainMap->GetWidth(), gainMap->GetHeight()},
1436 .pixelFormat = gainMap->GetPixelFormat(),
1437 .alphaType = gainMap->GetAlphaType()
1438 };
1439 auto copyGainMapPtr = PixelMap::Create(*gainMap, gainMapOpts);
1440 std::shared_ptr<PixelMap> copyGainMap = std::move(copyGainMapPtr);
1441 if (copyGainMap == nullptr) {
1442 return false;
1443 }
1444 Size copyGainMapSize = {copyGainMap->GetWidth(), copyGainMap->GetHeight()};
1445 auto auxiliaryPicturePtr = AuxiliaryPicture::Create(copyGainMap, AuxiliaryPictureType::GAINMAP, copyGainMapSize);
1446 std::shared_ptr<AuxiliaryPicture> auxiliaryPicture = std::move(auxiliaryPicturePtr);
1447 if (auxiliaryPicture == nullptr) {
1448 return false;
1449 }
1450 auto copySourcePtr = Picture::Create(copyPixelMap);
1451 copySource = std::move(copySourcePtr);
1452 copySource->SetAuxiliaryPicture(auxiliaryPicture);
1453 return true;
1454 }
1455
PostProcPictureSource(ThumbnailData & data)1456 void PostProcPictureSource(ThumbnailData &data)
1457 {
1458 auto picture = data.source.GetPicture();
1459 if (picture == nullptr) {
1460 return;
1461 }
1462 auto pixelMap = picture->GetMainPixel();
1463 auto gainMap = picture->GetGainmapPixelMap();
1464 if (pixelMap == nullptr || gainMap == nullptr) {
1465 return;
1466 }
1467 if (data.orientation != 0) {
1468 if (data.isLocalFile) {
1469 std::shared_ptr<Picture> copySource;
1470 ThumbnailUtils::CopyPictureSource(picture, copySource);
1471 data.source.SetPictureEx(copySource);
1472 }
1473 pixelMap->rotate(static_cast<float>(data.orientation));
1474 gainMap->rotate(static_cast<float>(data.orientation));
1475 }
1476 }
1477
LoadSourceImage(ThumbnailData & data)1478 bool ThumbnailUtils::LoadSourceImage(ThumbnailData &data)
1479 {
1480 if (!data.source.IsEmptySource()) {
1481 return true;
1482 }
1483 MediaLibraryTracer tracer;
1484 tracer.Start("LoadSourceImage");
1485 if (data.mediaType == -1) {
1486 auto extension = MediaFileUtils::GetExtensionFromPath(data.path);
1487 auto mimeType = MimeTypeUtils::GetMimeTypeFromExtension(extension);
1488 data.mediaType = MimeTypeUtils::GetMediaTypeFromMimeType(mimeType);
1489 }
1490
1491 bool ret = false;
1492 Size desiredSize;
1493 if (data.mediaType == MEDIA_TYPE_AUDIO) {
1494 ret = LoadAudioFile(data, desiredSize);
1495 } else {
1496 ret = LoadImageFile(data, desiredSize);
1497 }
1498 if (!ret || (data.source.IsEmptySource())) {
1499 return false;
1500 }
1501 tracer.Finish();
1502
1503 auto pixelMap = data.source.GetPixelMap();
1504 if (data.loaderOpts.decodeInThumbSize && !CenterScaleEx(pixelMap, desiredSize, data.path)) {
1505 MEDIA_ERR_LOG("thumbnail center crop failed [%{private}s]", data.id.c_str());
1506 return false;
1507 }
1508
1509 if (data.source.HasPictureSource()) {
1510 PostProcPictureSource(data);
1511 } else {
1512 PostProcPixelMapSource(data);
1513 }
1514 return true;
1515 }
1516
ScaleFastThumb(ThumbnailData & data,const Size & size)1517 bool ThumbnailUtils::ScaleFastThumb(ThumbnailData &data, const Size &size)
1518 {
1519 MediaLibraryTracer tracer;
1520 tracer.Start("ScaleFastThumb");
1521
1522 auto pixelMap = data.source.GetPixelMap();
1523 if (!CenterScaleEx(pixelMap, size, data.path)) {
1524 MEDIA_ERR_LOG("Fast thumb center crop failed [%{private}s]", data.id.c_str());
1525 return false;
1526 }
1527 return true;
1528 }
1529
SaveFile(const string & fileName,uint8_t * output,int writeSize)1530 static int SaveFile(const string &fileName, uint8_t *output, int writeSize)
1531 {
1532 string tempFileName = fileName + ".tmp";
1533 const mode_t fileMode = 0644;
1534 mode_t mask = umask(0);
1535 UniqueFd fd(open(tempFileName.c_str(), O_WRONLY | O_CREAT | O_TRUNC, fileMode));
1536 umask(mask);
1537 if (fd.Get() < 0) {
1538 if (errno == EEXIST) {
1539 UniqueFd fd(open(tempFileName.c_str(), O_WRONLY | O_TRUNC, fileMode));
1540 }
1541 if (fd.Get() < 0) {
1542 int err = errno;
1543 std::string fileParentPath = MediaFileUtils::GetParentPath(tempFileName);
1544 MEDIA_ERR_LOG("save failed! status %{public}d, filePath: %{public}s exists: %{public}d, parent path "
1545 "exists: %{public}d", err, DfxUtils::GetSafePath(tempFileName).c_str(), MediaFileUtils::IsFileExists(
1546 tempFileName), MediaFileUtils::IsFileExists(fileParentPath));
1547 if (err == EACCES) {
1548 MediaFileUtils::PrintStatInformation(fileParentPath);
1549 }
1550 return -err;
1551 }
1552 }
1553 int ret = write(fd.Get(), output, writeSize);
1554 if (ret < 0) {
1555 MEDIA_ERR_LOG("write failed errno %{public}d", errno);
1556 return -errno;
1557 }
1558 int32_t errCode = fsync(fd.Get());
1559 if (errCode < 0) {
1560 MEDIA_ERR_LOG("fsync failed errno %{public}d", errno);
1561 return -errno;
1562 }
1563 close(fd.Release());
1564
1565 if (MediaFileUtils::IsFileExists(fileName)) {
1566 MEDIA_INFO_LOG("file: %{public}s exists and needs to be deleted", DfxUtils::GetSafePath(fileName).c_str());
1567 if (!MediaFileUtils::DeleteFile(fileName)) {
1568 MEDIA_ERR_LOG("delete file: %{public}s failed", DfxUtils::GetSafePath(fileName).c_str());
1569 return -errno;
1570 }
1571 }
1572 errCode = MediaFileUtils::ModifyAsset(tempFileName, fileName);
1573 if (errCode != E_OK) {
1574 int32_t lastErrno = errno;
1575 if (!MediaFileUtils::DeleteFile(tempFileName)) {
1576 MEDIA_WARN_LOG("Delete tmp thumb error: %{public}d, name: %{public}s",
1577 errno, DfxUtils::GetSafePath(tempFileName).c_str());
1578 }
1579 if (errCode == E_FILE_EXIST || (errCode == E_FILE_OPER_FAIL && lastErrno == EEXIST)) {
1580 return E_OK;
1581 }
1582 return errCode;
1583 }
1584 return ret;
1585 }
1586
SaveFileCreateDir(const string & path,const string & suffix,string & fileName)1587 int ThumbnailUtils::SaveFileCreateDir(const string &path, const string &suffix, string &fileName)
1588 {
1589 fileName = GetThumbnailPath(path, suffix);
1590 string dir = MediaFileUtils::GetParentPath(fileName);
1591 if (!MediaFileUtils::CreateDirectory(dir)) {
1592 MEDIA_ERR_LOG("Fail to create directory, fileName: %{public}s", DfxUtils::GetSafePath(fileName).c_str());
1593 return -errno;
1594 }
1595 return E_OK;
1596 }
1597
ToSaveFile(ThumbnailData & data,const string & fileName,uint8_t * output,const int & writeSize)1598 int ThumbnailUtils::ToSaveFile(ThumbnailData &data, const string &fileName, uint8_t *output, const int &writeSize)
1599 {
1600 int ret = SaveFile(fileName, output, writeSize);
1601 if (ret < 0) {
1602 MEDIA_ERR_LOG("Fail to save File, err: %{public}d", ret);
1603 return ret;
1604 } else if (ret != writeSize) {
1605 MEDIA_ERR_LOG("Fail to save File, insufficient space left.");
1606 return E_NO_SPACE;
1607 }
1608 return E_OK;
1609 }
1610
TrySaveFile(ThumbnailData & data,ThumbnailType type)1611 int ThumbnailUtils::TrySaveFile(ThumbnailData &data, ThumbnailType type)
1612 {
1613 string suffix;
1614 uint8_t *output;
1615 uint32_t writeSize;
1616 switch (type) {
1617 case ThumbnailType::THUMB:
1618 suffix = THUMBNAIL_THUMB_SUFFIX;
1619 output = data.thumbnail.data();
1620 writeSize = data.thumbnail.size();
1621 break;
1622 case ThumbnailType::THUMB_ASTC:
1623 suffix = THUMBNAIL_THUMBASTC_SUFFIX;
1624 output = data.thumbAstc.data();
1625 writeSize = data.thumbAstc.size();
1626 break;
1627 case ThumbnailType::LCD:
1628 suffix = THUMBNAIL_LCD_SUFFIX;
1629 output = data.lcd.data();
1630 writeSize = data.lcd.size();
1631 break;
1632 case ThumbnailType::MTH_ASTC:
1633 output = data.monthAstc.data();
1634 writeSize = data.monthAstc.size();
1635 break;
1636 case ThumbnailType::YEAR_ASTC:
1637 output = data.yearAstc.data();
1638 writeSize = data.yearAstc.size();
1639 break;
1640 case ThumbnailType::LCD_EX:
1641 suffix = THUMBNAIL_LCD_EX_SUFFIX;
1642 output = data.lcd.data();
1643 writeSize = data.lcd.size();
1644 break;
1645 case ThumbnailType::THUMB_EX:
1646 suffix = THUMBNAIL_THUMB_EX_SUFFIX;
1647 output = data.thumbnail.data();
1648 writeSize = data.thumbnail.size();
1649 break;
1650 default:
1651 return E_INVALID_ARGUMENTS;
1652 }
1653 if (writeSize <= 0) {
1654 return E_THUMBNAIL_LOCAL_CREATE_FAIL;
1655 }
1656 if (type == ThumbnailType::MTH_ASTC || type == ThumbnailType::YEAR_ASTC) {
1657 return SaveAstcDataToKvStore(data, type);
1658 }
1659 return SaveThumbDataToLocalDir(data, suffix, output, writeSize);
1660 }
1661
SaveThumbDataToLocalDir(ThumbnailData & data,const std::string & suffix,uint8_t * output,const int writeSize)1662 int ThumbnailUtils::SaveThumbDataToLocalDir(ThumbnailData &data, const std::string &suffix,
1663 uint8_t *output, const int writeSize)
1664 {
1665 string fileName;
1666 int ret = SaveFileCreateDir(data.path, suffix, fileName);
1667 if (ret != E_OK) {
1668 MEDIA_ERR_LOG("SaveThumbDataToLocalDir create dir path %{public}s err %{public}d",
1669 DfxUtils::GetSafePath(data.path).c_str(), ret);
1670 return ret;
1671 }
1672 ret = ToSaveFile(data, fileName, output, writeSize);
1673 if (ret < 0) {
1674 MEDIA_ERR_LOG("SaveThumbDataToLocalDir ToSaveFile path %{public}s err %{public}d",
1675 DfxUtils::GetSafePath(data.path).c_str(), ret);
1676 return ret;
1677 }
1678 return E_OK;
1679 }
1680
SetSource(shared_ptr<AVMetadataHelper> avMetadataHelper,const string & path)1681 int32_t ThumbnailUtils::SetSource(shared_ptr<AVMetadataHelper> avMetadataHelper, const string &path)
1682 {
1683 if (avMetadataHelper == nullptr) {
1684 MEDIA_ERR_LOG("avMetadataHelper == nullptr");
1685 return E_ERR;
1686 }
1687 MEDIA_DEBUG_LOG("path = %{public}s", DfxUtils::GetSafePath(path).c_str());
1688
1689 string absFilePath;
1690 if (!PathToRealPath(path, absFilePath)) {
1691 MEDIA_ERR_LOG("Failed to open a nullptr path, errno=%{public}d, path:%{public}s",
1692 errno, DfxUtils::GetSafePath(path).c_str());
1693 return E_ERR;
1694 }
1695
1696 int32_t fd = open(absFilePath.c_str(), O_RDONLY);
1697 if (fd < 0) {
1698 MEDIA_ERR_LOG("Open file failed, err %{public}d, file: %{public}s exists: %{public}d",
1699 errno, DfxUtils::GetSafePath(absFilePath).c_str(), MediaFileUtils::IsFileExists(absFilePath));
1700 return E_ERR;
1701 }
1702 struct stat64 st;
1703 if (fstat64(fd, &st) != 0) {
1704 MEDIA_ERR_LOG("Get file state failed, err %{public}d", errno);
1705 (void)close(fd);
1706 return E_ERR;
1707 }
1708 int64_t length = static_cast<int64_t>(st.st_size);
1709 int32_t ret = avMetadataHelper->SetSource(fd, 0, length, AV_META_USAGE_PIXEL_MAP);
1710 if (ret != 0) {
1711 DfxManager::GetInstance()->HandleThumbnailError(absFilePath, DfxType::AV_SET_SOURCE, ret);
1712 (void)close(fd);
1713 return E_ERR;
1714 }
1715 (void)close(fd);
1716 return E_SUCCESS;
1717 }
1718
ResizeImage(const vector<uint8_t> & data,const Size & size,unique_ptr<PixelMap> & pixelMap)1719 bool ThumbnailUtils::ResizeImage(const vector<uint8_t> &data, const Size &size, unique_ptr<PixelMap> &pixelMap)
1720 {
1721 MediaLibraryTracer tracer;
1722 tracer.Start("ResizeImage");
1723 if (data.size() == 0) {
1724 MEDIA_ERR_LOG("Data is empty");
1725 return false;
1726 }
1727
1728 tracer.Start("ImageSource::CreateImageSource");
1729 uint32_t err = E_OK;
1730 SourceOptions opts;
1731 unique_ptr<ImageSource> imageSource = ImageSource::CreateImageSource(data.data(),
1732 data.size(), opts, err);
1733 if (imageSource == nullptr) {
1734 MEDIA_ERR_LOG("imageSource is nullptr");
1735 return false;
1736 }
1737 if (err != E_OK) {
1738 MEDIA_ERR_LOG("Failed to create image source %{public}d", err);
1739 return false;
1740 }
1741 tracer.Finish();
1742
1743 tracer.Start("imageSource->CreatePixelMap");
1744 DecodeOptions decodeOpts;
1745 decodeOpts.desiredSize.width = size.width;
1746 decodeOpts.desiredSize.height = size.height;
1747 pixelMap = imageSource->CreatePixelMap(decodeOpts, err);
1748 if (err != E_SUCCESS) {
1749 MEDIA_ERR_LOG("Failed to create pixelmap %{public}d", err);
1750 return false;
1751 }
1752
1753 return true;
1754 }
1755
1756 // notice: return value is whether thumb/lcd is deleted
DeleteOriginImage(ThumbRdbOpt & opts)1757 bool ThumbnailUtils::DeleteOriginImage(ThumbRdbOpt &opts)
1758 {
1759 ThumbnailData tmpData;
1760 tmpData.path = opts.path;
1761 bool isDelete = false;
1762 if (opts.path.empty()) {
1763 int err = 0;
1764 auto rdbSet = QueryThumbnailInfo(opts, tmpData, err);
1765 if (rdbSet == nullptr) {
1766 MEDIA_ERR_LOG("QueryThumbnailInfo Faild [ %{public}d ]", err);
1767 return isDelete;
1768 }
1769 }
1770 ValuesBucket values;
1771 int changedRows;
1772 values.PutLong(PhotoColumn::PHOTO_THUMBNAIL_READY, 0);
1773 values.PutLong(PhotoColumn::PHOTO_LCD_VISIT_TIME, 0);
1774 int32_t err = opts.store->Update(changedRows, opts.table, values, MEDIA_DATA_DB_ID + " = ?",
1775 vector<string> { opts.row });
1776 if (err != NativeRdb::E_OK) {
1777 MEDIA_ERR_LOG("RdbStore Update Failed Before Delete Thumbnail! %{public}d", err);
1778 }
1779 MEDIA_INFO_LOG("Start DeleteOriginImage, id: %{public}s, path: %{public}s",
1780 opts.row.c_str(), DfxUtils::GetSafePath(tmpData.path).c_str());
1781 if (!opts.dateTaken.empty() && DeleteAstcDataFromKvStore(opts, ThumbnailType::MTH_ASTC)) {
1782 isDelete = true;
1783 }
1784 if (!opts.dateTaken.empty() && DeleteAstcDataFromKvStore(opts, ThumbnailType::YEAR_ASTC)) {
1785 isDelete = true;
1786 }
1787 if (DeleteThumbFile(tmpData, ThumbnailType::THUMB)) {
1788 isDelete = true;
1789 }
1790 if (ThumbnailUtils::IsSupportGenAstc() && DeleteThumbFile(tmpData, ThumbnailType::THUMB_ASTC)) {
1791 isDelete = true;
1792 }
1793 if (DeleteThumbFile(tmpData, ThumbnailType::LCD)) {
1794 isDelete = true;
1795 }
1796 if (DeleteThumbExDir(tmpData)) {
1797 isDelete = true;
1798 }
1799 string fileName = GetThumbnailPath(tmpData.path, "");
1800 return isDelete;
1801 }
1802
DoDeleteMonthAndYearAstc(ThumbRdbOpt & opts)1803 bool ThumbnailUtils::DoDeleteMonthAndYearAstc(ThumbRdbOpt &opts)
1804 {
1805 MEDIA_INFO_LOG("Start DoDeleteMonthAndYearAstc, id: %{public}s", opts.row.c_str());
1806 bool isDeleteAstcSuccess = true;
1807 if (!DeleteAstcDataFromKvStore(opts, ThumbnailType::MTH_ASTC)) {
1808 isDeleteAstcSuccess = false;
1809 }
1810 if (!DeleteAstcDataFromKvStore(opts, ThumbnailType::YEAR_ASTC)) {
1811 isDeleteAstcSuccess = false;
1812 }
1813 return isDeleteAstcSuccess;
1814 }
1815
DoUpdateAstcDateTaken(ThumbRdbOpt & opts,ThumbnailData & data)1816 bool ThumbnailUtils::DoUpdateAstcDateTaken(ThumbRdbOpt &opts, ThumbnailData &data)
1817 {
1818 MEDIA_INFO_LOG("Start DoUpdateAstcDateTaken, id: %{public}s", opts.row.c_str());
1819 return UpdateAstcDateTakenFromKvStore(opts, data);
1820 }
1821
1822 #ifdef DISTRIBUTED
IsImageExist(const string & key,const string & networkId,const shared_ptr<SingleKvStore> & kvStore)1823 bool ThumbnailUtils::IsImageExist(const string &key, const string &networkId, const shared_ptr<SingleKvStore> &kvStore)
1824 {
1825 if (key.empty()) {
1826 return false;
1827 }
1828
1829 if (kvStore == nullptr) {
1830 MEDIA_ERR_LOG("KvStore is not init");
1831 return false;
1832 }
1833
1834 bool ret = false;
1835 DataQuery query;
1836 query.InKeys({key});
1837 int count = 0;
1838 auto status = kvStore->GetCount(query, count);
1839 if (status == Status::SUCCESS && count > 0) {
1840 ret = true;
1841 }
1842
1843 if (!ret) {
1844 if (!networkId.empty()) {
1845 MediaLibraryTracer tracer;
1846 tracer.Start("SyncPullKvstore");
1847 vector<string> keys = { key };
1848 auto syncStatus = MediaLibrarySyncOperation::SyncPullKvstore(kvStore, keys, networkId);
1849 if (syncStatus == DistributedKv::Status::SUCCESS) {
1850 MEDIA_DEBUG_LOG("SyncPullKvstore SUCCESS");
1851 return true;
1852 } else {
1853 MEDIA_ERR_LOG("SyncPullKvstore failed! ret %{public}d", syncStatus);
1854 return false;
1855 }
1856 }
1857 }
1858 return ret;
1859 }
1860 #endif
1861
UTCTimeMilliSeconds()1862 int64_t ThumbnailUtils::UTCTimeMilliSeconds()
1863 {
1864 struct timespec t;
1865 constexpr int64_t SEC_TO_MSEC = 1e3;
1866 constexpr int64_t MSEC_TO_NSEC = 1e6;
1867 clock_gettime(CLOCK_REALTIME, &t);
1868 return t.tv_sec * SEC_TO_MSEC + t.tv_nsec / MSEC_TO_NSEC;
1869 }
1870
CheckResultSetCount(const shared_ptr<ResultSet> & resultSet,int & err)1871 bool ThumbnailUtils::CheckResultSetCount(const shared_ptr<ResultSet> &resultSet, int &err)
1872 {
1873 if (resultSet == nullptr) {
1874 MEDIA_ERR_LOG("resultSet is nullptr!");
1875 return false;
1876 }
1877 int rowCount = 0;
1878 err = resultSet->GetRowCount(rowCount);
1879 if (err != E_OK || rowCount < 0) {
1880 MEDIA_ERR_LOG("Failed to get row count %{public}d", err);
1881 return false;
1882 } else if (rowCount == 0) {
1883 MEDIA_ERR_LOG("CheckCount No match!");
1884 err = E_EMPTY_VALUES_BUCKET;
1885 return false;
1886 }
1887 return true;
1888 }
1889
ParseStringResult(const shared_ptr<ResultSet> & resultSet,int index,string & data,int & err)1890 void ThumbnailUtils::ParseStringResult(const shared_ptr<ResultSet> &resultSet, int index, string &data, int &err)
1891 {
1892 bool isNull = true;
1893 err = resultSet->IsColumnNull(index, isNull);
1894 if (err != E_OK) {
1895 MEDIA_ERR_LOG("Failed to check column %{public}d null %{public}d", index, err);
1896 }
1897
1898 if (!isNull) {
1899 err = resultSet->GetString(index, data);
1900 if (err != E_OK) {
1901 MEDIA_ERR_LOG("Failed to get column %{public}d string %{public}d", index, err);
1902 }
1903 }
1904 }
1905
ParseQueryResult(const shared_ptr<ResultSet> & resultSet,ThumbnailData & data,int & err,const std::vector<std::string> & column)1906 void ThumbnailUtils::ParseQueryResult(const shared_ptr<ResultSet> &resultSet, ThumbnailData &data,
1907 int &err, const std::vector<std::string> &column)
1908 {
1909 int index;
1910 for (auto &columnValue : column) {
1911 err = resultSet->GetColumnIndex(columnValue, index);
1912 if (err != NativeRdb::E_OK) {
1913 continue;
1914 }
1915 if (columnValue == MEDIA_DATA_DB_ID) {
1916 ParseStringResult(resultSet, index, data.id, err);
1917 } else if (columnValue == MEDIA_DATA_DB_FILE_PATH) {
1918 ParseStringResult(resultSet, index, data.path, err);
1919 } else if (columnValue == MEDIA_DATA_DB_DATE_ADDED) {
1920 ParseStringResult(resultSet, index, data.dateAdded, err);
1921 } else if (columnValue == MEDIA_DATA_DB_NAME) {
1922 ParseStringResult(resultSet, index, data.displayName, err);
1923 } else if (columnValue == MEDIA_DATA_DB_MEDIA_TYPE) {
1924 data.mediaType = MediaType::MEDIA_TYPE_ALL;
1925 err = resultSet->GetInt(index, data.mediaType);
1926 } else if (columnValue == MEDIA_DATA_DB_ORIENTATION) {
1927 err = resultSet->GetInt(index, data.orientation);
1928 } else if (columnValue == MEDIA_DATA_DB_POSITION) {
1929 int position = 0;
1930 err = resultSet->GetInt(index, position);
1931 data.isLocalFile = (position == 1);
1932 } else if (columnValue == MEDIA_DATA_DB_HEIGHT) {
1933 err = resultSet->GetInt(index, data.photoHeight);
1934 } else if (columnValue == MEDIA_DATA_DB_WIDTH) {
1935 err = resultSet->GetInt(index, data.photoWidth);
1936 }
1937 }
1938
1939 err = resultSet->GetColumnIndex(MEDIA_DATA_DB_DATE_TAKEN, index);
1940 if (err == NativeRdb::E_OK) {
1941 ParseStringResult(resultSet, index, data.dateTaken, err);
1942 }
1943 }
1944
ResizeThumb(int & width,int & height)1945 bool ThumbnailUtils::ResizeThumb(int &width, int &height)
1946 {
1947 int maxLen = max(width, height);
1948 int minLen = min(width, height);
1949 if (minLen == 0) {
1950 MEDIA_ERR_LOG("Divisor minLen is 0");
1951 return false;
1952 }
1953 double ratio = static_cast<double>(maxLen) / minLen;
1954 if (minLen > SHORT_SIDE_THRESHOLD) {
1955 minLen = SHORT_SIDE_THRESHOLD;
1956 maxLen = static_cast<int>(SHORT_SIDE_THRESHOLD * ratio);
1957 if (maxLen > MAXIMUM_SHORT_SIDE_THRESHOLD) {
1958 maxLen = MAXIMUM_SHORT_SIDE_THRESHOLD;
1959 }
1960 if (height > width) {
1961 width = minLen;
1962 height = maxLen;
1963 } else {
1964 width = maxLen;
1965 height = minLen;
1966 }
1967 }
1968 if (minLen <= SHORT_SIDE_THRESHOLD && maxLen > SHORT_SIDE_THRESHOLD && ratio > ASPECT_RATIO_THRESHOLD) {
1969 int newMaxLen = static_cast<int>(minLen * ASPECT_RATIO_THRESHOLD);
1970 if (height > width) {
1971 width = minLen;
1972 height = newMaxLen;
1973 } else {
1974 width = newMaxLen;
1975 height = minLen;
1976 }
1977 }
1978 return true;
1979 }
1980
ResizeLcd(int & width,int & height)1981 bool ThumbnailUtils::ResizeLcd(int &width, int &height)
1982 {
1983 int maxLen = max(width, height);
1984 int minLen = min(width, height);
1985 if (minLen == 0) {
1986 MEDIA_ERR_LOG("Divisor minLen is 0");
1987 return false;
1988 }
1989 double ratio = static_cast<double>(maxLen) / minLen;
1990 if (std::abs(ratio) < EPSILON) {
1991 MEDIA_ERR_LOG("ratio is 0");
1992 return false;
1993 }
1994 int newMaxLen = maxLen;
1995 int newMinLen = minLen;
1996 if (maxLen > LCD_LONG_SIDE_THRESHOLD) {
1997 newMaxLen = LCD_LONG_SIDE_THRESHOLD;
1998 newMinLen = static_cast<int>(newMaxLen / ratio);
1999 }
2000 int lastMinLen = newMinLen;
2001 int lastMaxLen = newMaxLen;
2002 if (newMinLen < LCD_SHORT_SIDE_THRESHOLD && minLen >= LCD_SHORT_SIDE_THRESHOLD) {
2003 lastMinLen = LCD_SHORT_SIDE_THRESHOLD;
2004 lastMaxLen = static_cast<int>(lastMinLen * ratio);
2005 if (lastMaxLen > MAXIMUM_LCD_LONG_SIDE) {
2006 lastMaxLen = MAXIMUM_LCD_LONG_SIDE;
2007 lastMinLen = static_cast<int>(lastMaxLen / ratio);
2008 }
2009 }
2010
2011 // When LCD size has changed after resize, check if width or height is odd number
2012 // Add one to the odd side to make sure LCD would be compressed through hardware encode
2013 if (max(width, height) != lastMaxLen) {
2014 lastMaxLen += lastMaxLen % EVEN_BASE_NUMBER;
2015 lastMinLen += lastMinLen % EVEN_BASE_NUMBER;
2016 }
2017 if (height > width) {
2018 width = lastMinLen;
2019 height = lastMaxLen;
2020 } else {
2021 width = lastMaxLen;
2022 height = lastMinLen;
2023 }
2024 return true;
2025 }
2026
IsSupportGenAstc()2027 bool ThumbnailUtils::IsSupportGenAstc()
2028 {
2029 return ImageSource::IsSupportGenAstc();
2030 }
2031
SaveAstcDataToKvStore(ThumbnailData & data,const ThumbnailType & type)2032 int ThumbnailUtils::SaveAstcDataToKvStore(ThumbnailData &data, const ThumbnailType &type)
2033 {
2034 string key;
2035 if (!MediaFileUtils::GenerateKvStoreKey(data.id, data.dateTaken, key)) {
2036 MEDIA_ERR_LOG("GenerateKvStoreKey failed");
2037 return E_ERR;
2038 }
2039
2040 std::shared_ptr<MediaLibraryKvStore> kvStore;
2041 if (type == ThumbnailType::MTH_ASTC) {
2042 kvStore = MediaLibraryKvStoreManager::GetInstance()
2043 .GetKvStore(KvStoreRoleType::OWNER, KvStoreValueType::MONTH_ASTC);
2044 } else if (type == ThumbnailType::YEAR_ASTC) {
2045 kvStore = MediaLibraryKvStoreManager::GetInstance()
2046 .GetKvStore(KvStoreRoleType::OWNER, KvStoreValueType::YEAR_ASTC);
2047 } else {
2048 MEDIA_ERR_LOG("invalid thumbnailType");
2049 return E_ERR;
2050 }
2051 if (kvStore == nullptr) {
2052 MEDIA_ERR_LOG("kvStore is nullptr");
2053 return E_ERR;
2054 }
2055 int32_t count = 0;
2056 kvStore->GetCount(key, count);
2057 data.isThumbExisted = count > 0;
2058 int status = kvStore->Insert(key, type == ThumbnailType::MTH_ASTC ? data.monthAstc : data.yearAstc);
2059 if (status != E_OK) {
2060 MEDIA_ERR_LOG("Insert failed, type:%{public}d, field_id:%{public}s, status:%{public}d",
2061 type, key.c_str(), status);
2062 return E_ERR;
2063 }
2064 MEDIA_INFO_LOG("type:%{public}d, field_id:%{public}s, status:%{public}d", type, key.c_str(), status);
2065 return status;
2066 }
2067
CheckDateTaken(ThumbRdbOpt & opts,ThumbnailData & data)2068 bool ThumbnailUtils::CheckDateTaken(ThumbRdbOpt &opts, ThumbnailData &data)
2069 {
2070 if (!data.dateTaken.empty()) {
2071 return true;
2072 }
2073
2074 vector<string> column = {
2075 MEDIA_DATA_DB_DATE_TAKEN,
2076 };
2077 vector<string> selectionArgs;
2078 string strQueryCondition = MEDIA_DATA_DB_ID + " = " + data.id;
2079 RdbPredicates rdbPredicates(opts.table);
2080 rdbPredicates.SetWhereClause(strQueryCondition);
2081 rdbPredicates.SetWhereArgs(selectionArgs);
2082 if (opts.store == nullptr) {
2083 MEDIA_ERR_LOG("opts.store is nullptr");
2084 return false;
2085 }
2086 shared_ptr<ResultSet> resultSet = opts.store->QueryByStep(rdbPredicates, column);
2087
2088 int err;
2089 if (!CheckResultSetCount(resultSet, err)) {
2090 MEDIA_ERR_LOG("CheckResultSetCount failed, err: %{public}d", err);
2091 return false;
2092 }
2093 err = resultSet->GoToFirstRow();
2094 if (err != E_OK) {
2095 MEDIA_ERR_LOG("GoToFirstRow failed, err: %{public}d", err);
2096 return false;
2097 }
2098
2099 int index;
2100 err = resultSet->GetColumnIndex(MEDIA_DATA_DB_DATE_TAKEN, index);
2101 if (err == NativeRdb::E_OK) {
2102 ParseStringResult(resultSet, index, data.dateTaken, err);
2103 } else {
2104 MEDIA_ERR_LOG("GetColumnIndex failed, err: %{public}d", err);
2105 resultSet->Close();
2106 return false;
2107 }
2108 resultSet->Close();
2109 return true;
2110 }
2111
QueryThumbnailDataFromFileId(ThumbRdbOpt & opts,const std::string & id,ThumbnailData & data,int & err)2112 void ThumbnailUtils::QueryThumbnailDataFromFileId(ThumbRdbOpt &opts, const std::string &id,
2113 ThumbnailData &data, int &err)
2114 {
2115 if (opts.table.empty()) {
2116 MEDIA_ERR_LOG("Table is empty");
2117 return;
2118 }
2119 RdbPredicates predicates(opts.table);
2120 predicates.EqualTo(MediaColumn::MEDIA_ID, id);
2121 vector<string> columns = {
2122 MEDIA_DATA_DB_ID,
2123 MEDIA_DATA_DB_FILE_PATH,
2124 MEDIA_DATA_DB_HEIGHT,
2125 MEDIA_DATA_DB_WIDTH,
2126 MEDIA_DATA_DB_MEDIA_TYPE,
2127 MEDIA_DATA_DB_DATE_ADDED,
2128 MEDIA_DATA_DB_ORIENTATION,
2129 MEDIA_DATA_DB_POSITION,
2130 MEDIA_DATA_DB_DATE_TAKEN,
2131 };
2132 if (opts.store == nullptr) {
2133 MEDIA_ERR_LOG("opts.store is nullptr");
2134 return;
2135 }
2136 auto resultSet = opts.store->QueryByStep(predicates, columns);
2137 if (resultSet == nullptr) {
2138 MEDIA_ERR_LOG("ResultSet is nullptr");
2139 return;
2140 }
2141 err = resultSet->GoToFirstRow();
2142 if (err != NativeRdb::E_OK) {
2143 MEDIA_ERR_LOG("Fail to GoToFirstRow");
2144 resultSet->Close();
2145 return;
2146 }
2147
2148 ParseQueryResult(resultSet, data, err, columns);
2149 if (err != NativeRdb::E_OK || data.path.empty()) {
2150 MEDIA_ERR_LOG("Fail to query thumbnail data using id: %{public}s, err: %{public}d", id.c_str(), err);
2151 resultSet->Close();
2152 return;
2153 }
2154 resultSet->Close();
2155 data.stats.uri = data.path;
2156 }
2157
DeleteAstcDataFromKvStore(ThumbRdbOpt & opts,const ThumbnailType & type)2158 bool ThumbnailUtils::DeleteAstcDataFromKvStore(ThumbRdbOpt &opts, const ThumbnailType &type)
2159 {
2160 string key;
2161 if (!MediaFileUtils::GenerateKvStoreKey(opts.row, opts.dateTaken, key)) {
2162 MEDIA_ERR_LOG("GenerateKvStoreKey failed");
2163 return false;
2164 }
2165
2166 std::shared_ptr<MediaLibraryKvStore> kvStore;
2167 if (type == ThumbnailType::MTH_ASTC) {
2168 kvStore = MediaLibraryKvStoreManager::GetInstance()
2169 .GetKvStore(KvStoreRoleType::OWNER, KvStoreValueType::MONTH_ASTC);
2170 } else if (type == ThumbnailType::YEAR_ASTC) {
2171 kvStore = MediaLibraryKvStoreManager::GetInstance()
2172 .GetKvStore(KvStoreRoleType::OWNER, KvStoreValueType::YEAR_ASTC);
2173 } else {
2174 MEDIA_ERR_LOG("invalid thumbnailType");
2175 return false;
2176 }
2177 if (kvStore == nullptr) {
2178 MEDIA_ERR_LOG("kvStore is nullptr");
2179 return false;
2180 }
2181
2182 int status = kvStore->Delete(key);
2183 return status == E_OK;
2184 }
2185
UpdateAstcDateTakenFromKvStore(ThumbRdbOpt & opts,const ThumbnailData & data)2186 bool ThumbnailUtils::UpdateAstcDateTakenFromKvStore(ThumbRdbOpt &opts, const ThumbnailData &data)
2187 {
2188 std::string formerKey;
2189 std::string newKey;
2190 if (!MediaFileUtils::GenerateKvStoreKey(opts.row, opts.dateTaken, formerKey) ||
2191 !MediaFileUtils::GenerateKvStoreKey(opts.row, data.dateTaken, newKey)) {
2192 MEDIA_ERR_LOG("UpdateAstcDateTakenFromKvStore GenerateKvStoreKey failed");
2193 return false;
2194 }
2195
2196 std::shared_ptr<MediaLibraryKvStore> monthKvStore;
2197 std::shared_ptr<MediaLibraryKvStore> yearKvStore;
2198 monthKvStore = MediaLibraryKvStoreManager::GetInstance()
2199 .GetKvStore(KvStoreRoleType::OWNER, KvStoreValueType::MONTH_ASTC);
2200 yearKvStore = MediaLibraryKvStoreManager::GetInstance()
2201 .GetKvStore(KvStoreRoleType::OWNER, KvStoreValueType::YEAR_ASTC);
2202 if (monthKvStore == nullptr || yearKvStore == nullptr) {
2203 MEDIA_ERR_LOG("kvStore is nullptr");
2204 return false;
2205 }
2206
2207 std::vector<uint8_t> monthValue;
2208 if (monthKvStore->Query(formerKey, monthValue) != E_OK || monthKvStore->Insert(newKey, monthValue) != E_OK) {
2209 MEDIA_ERR_LOG("MonthValue update failed, fileId %{public}s", opts.row.c_str());
2210 return false;
2211 }
2212 std::vector<uint8_t> yearValue;
2213 if (yearKvStore->Query(formerKey, yearValue) != E_OK || yearKvStore->Insert(newKey, yearValue) != E_OK) {
2214 MEDIA_ERR_LOG("YearValue update failed, fileId %{public}s", opts.row.c_str());
2215 return false;
2216 }
2217
2218 int status = monthKvStore->Delete(formerKey) && yearKvStore->Delete(formerKey);
2219 if (status != E_OK) {
2220 MEDIA_ERR_LOG("Former kv delete failed, fileId %{public}s", opts.row.c_str());
2221 return false;
2222 }
2223 return true;
2224 }
2225
GetThumbnailInfo(ThumbRdbOpt & opts,ThumbnailData & outData)2226 void ThumbnailUtils::GetThumbnailInfo(ThumbRdbOpt &opts, ThumbnailData &outData)
2227 {
2228 if (opts.store == nullptr) {
2229 return;
2230 }
2231 if (!opts.path.empty()) {
2232 outData.path = opts.path;
2233 outData.id = opts.row;
2234 outData.dateTaken = opts.dateTaken;
2235 outData.fileUri = opts.fileUri;
2236 outData.stats.uri = outData.fileUri;
2237 return;
2238 }
2239 string filesTableName = opts.table;
2240 int errCode = E_ERR;
2241 if (!opts.networkId.empty()) {
2242 filesTableName = opts.store->ObtainDistributedTableName(opts.networkId, opts.table, errCode);
2243 }
2244 if (filesTableName.empty()) {
2245 return;
2246 }
2247 opts.table = filesTableName;
2248 int err;
2249 ThumbnailUtils::QueryThumbnailInfo(opts, outData, err);
2250 if (err != E_OK) {
2251 MEDIA_ERR_LOG("query fail [%{public}d]", err);
2252 }
2253 }
2254
ScaleThumbnailFromSource(ThumbnailData & data,bool isSourceEx)2255 bool ThumbnailUtils::ScaleThumbnailFromSource(ThumbnailData &data, bool isSourceEx)
2256 {
2257 std::shared_ptr<PixelMap> dataSource = isSourceEx ? data.source.GetPixelMapEx() : data.source.GetPixelMap();
2258 if (dataSource == nullptr) {
2259 MEDIA_ERR_LOG("Fail to scale thumbnail, data source is empty, isSourceEx: %{public}d.", isSourceEx);
2260 return false;
2261 }
2262 if (dataSource != nullptr && dataSource->IsHdr()) {
2263 uint32_t ret = dataSource->ToSdr();
2264 if (ret != E_OK) {
2265 MEDIA_ERR_LOG("Fail to transform to sdr, isSourceEx: %{public}d.", isSourceEx);
2266 return false;
2267 }
2268 }
2269 ImageInfo imageInfo;
2270 dataSource->GetImageInfo(imageInfo);
2271 if (imageInfo.pixelFormat != PixelFormat::RGBA_8888) {
2272 uint32_t ret = ImageFormatConvert::ConvertImageFormat(dataSource, PixelFormat::RGBA_8888);
2273 if (ret != E_OK) {
2274 MEDIA_ERR_LOG("Fail to scale convert image format, isSourceEx: %{public}d, format: %{public}d.",
2275 isSourceEx, imageInfo.pixelFormat);
2276 return false;
2277 }
2278 }
2279 if (isSourceEx) {
2280 data.source.SetPixelMapEx(dataSource);
2281 } else {
2282 data.source.SetPixelMap(dataSource);
2283 }
2284 Size desiredSize;
2285 Size targetSize = ConvertDecodeSize(data, {dataSource->GetWidth(), dataSource->GetHeight()}, desiredSize);
2286 if (!ScaleTargetPixelMap(dataSource, targetSize, Media::AntiAliasingOption::HIGH)) {
2287 MEDIA_ERR_LOG("Fail to scale to targetSize");
2288 return false;
2289 }
2290 if (!CenterScaleEx(dataSource, desiredSize, data.path)) {
2291 MEDIA_ERR_LOG("ScaleThumbnailFromSource center crop failed, path: %{public}s, isSourceEx: %{public}d.",
2292 DfxUtils::GetSafePath(data.path).c_str(), isSourceEx);
2293 return false;
2294 }
2295 return true;
2296 }
2297
RecordStartGenerateStats(ThumbnailData::GenerateStats & stats,GenerateScene scene,LoadSourceType sourceType)2298 void ThumbnailUtils::RecordStartGenerateStats(ThumbnailData::GenerateStats &stats,
2299 GenerateScene scene, LoadSourceType sourceType)
2300 {
2301 stats.startTime = MediaFileUtils::UTCTimeMilliSeconds();
2302 stats.scene = scene;
2303 stats.sourceType = sourceType;
2304 }
2305
RecordCostTimeAndReport(ThumbnailData::GenerateStats & stats)2306 void ThumbnailUtils::RecordCostTimeAndReport(ThumbnailData::GenerateStats &stats)
2307 {
2308 stats.totalCost = static_cast<int32_t>(MediaFileUtils::UTCTimeMilliSeconds() - stats.startTime);
2309 DfxManager::GetInstance()->HandleThumbnailGeneration(stats);
2310 }
2311
GetLocalThumbSize(const ThumbnailData & data,const ThumbnailType & type,Size & size)2312 bool ThumbnailUtils::GetLocalThumbSize(const ThumbnailData &data, const ThumbnailType& type, Size& size)
2313 {
2314 if (type != ThumbnailType::THUMB && type != ThumbnailType::LCD && type != ThumbnailType::THUMB_ASTC) {
2315 MEDIA_ERR_LOG("can not get size for such type: %{public}d", type);
2316 return false;
2317 }
2318 std::string tmpPath = "";
2319 switch (type) {
2320 case ThumbnailType::THUMB:
2321 case ThumbnailType::THUMB_ASTC:
2322 tmpPath = GetLocalThumbnailPath(data.path, THUMBNAIL_THUMB_SUFFIX);
2323 break;
2324 case ThumbnailType::LCD:
2325 tmpPath = GetLocalThumbnailPath(data.path, THUMBNAIL_LCD_SUFFIX);
2326 break;
2327 default:
2328 break;
2329 }
2330 uint32_t err = 0;
2331 SourceOptions opts;
2332 unique_ptr<ImageSource> imageSource = ImageSource::CreateImageSource(tmpPath, opts, err);
2333 if (err != E_OK || imageSource == nullptr) {
2334 MEDIA_ERR_LOG("Failed to LoadImageSource for path:%{public}s", DfxUtils::GetSafePath(tmpPath).c_str());
2335 return false;
2336 }
2337 ImageInfo imageInfo;
2338 err = imageSource->GetImageInfo(0, imageInfo);
2339 if (err != E_OK) {
2340 MEDIA_ERR_LOG("Failed to Get ImageInfo, path:%{public}s", DfxUtils::GetSafePath(tmpPath).c_str());
2341 return false;
2342 }
2343 size.height = imageInfo.size.height;
2344 size.width = imageInfo.size.width;
2345 return true;
2346 }
2347
SetThumbnailSizeValue(NativeRdb::ValuesBucket & values,Size & size,const std::string & column)2348 void ThumbnailUtils::SetThumbnailSizeValue(NativeRdb::ValuesBucket& values, Size& size, const std::string& column)
2349 {
2350 if (size.height == 0 || size.width == 0) {
2351 return;
2352 }
2353 std::string tmpSize = std::to_string(size.width) + ":" + std::to_string(size.height);
2354 values.PutString(column, tmpSize);
2355 }
2356
IsMobileNetworkEnabled()2357 static bool IsMobileNetworkEnabled()
2358 {
2359 bool isWifiConnected = false;
2360 auto wifiDevicePtr = Wifi::WifiDevice::GetInstance(WIFI_DEVICE_ABILITY_ID);
2361 if (wifiDevicePtr == nullptr) {
2362 MEDIA_ERR_LOG("wifiDevicePtr is null");
2363 } else {
2364 int32_t ret = wifiDevicePtr->IsConnected(isWifiConnected);
2365 if (ret != Wifi::WIFI_OPT_SUCCESS) {
2366 MEDIA_ERR_LOG("Get Is Connnected Fail: %{public}d", ret);
2367 }
2368 }
2369 if (isWifiConnected) {
2370 return true;
2371 }
2372 auto saMgr = OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
2373 if (saMgr == nullptr) {
2374 MEDIA_ERR_LOG("Failed to get SystemAbilityManagerClient");
2375 return false;
2376 }
2377 OHOS::sptr<OHOS::IRemoteObject> remoteObject = saMgr->CheckSystemAbility(STORAGE_MANAGER_MANAGER_ID);
2378 if (remoteObject == nullptr) {
2379 MEDIA_ERR_LOG("Token is null.");
2380 return false;
2381 }
2382 std::shared_ptr<DataShare::DataShareHelper> cloudHelper =
2383 DataShare::DataShareHelper::Creator(remoteObject, CLOUD_DATASHARE_URI);
2384 if (cloudHelper == nullptr) {
2385 MEDIA_INFO_LOG("cloudHelper is null");
2386 return false;
2387 }
2388 DataShare::DataSharePredicates predicates;
2389 predicates.EqualTo("key", "useMobileNetworkData");
2390 Uri cloudUri(CLOUD_DATASHARE_URI + "&key=useMobileNetworkData");
2391 vector<string> columns = {"value"};
2392 shared_ptr<DataShare::DataShareResultSet> resultSet =
2393 cloudHelper->Query(cloudUri, predicates, columns);
2394
2395 //default mobile network is off
2396 string switchOn = "0";
2397 if (resultSet != nullptr && resultSet->GoToNextRow()==0) {
2398 resultSet->GetString(0, switchOn);
2399 }
2400 if (resultSet != nullptr) {
2401 resultSet->Close();
2402 }
2403 cloudHelper->Release();
2404 return switchOn == "1";
2405 }
2406
QueryNoAstcInfosOnDemand(ThumbRdbOpt & opts,std::vector<ThumbnailData> & infos,NativeRdb::RdbPredicates & rdbPredicate,int & err)2407 bool ThumbnailUtils::QueryNoAstcInfosOnDemand(ThumbRdbOpt &opts,
2408 std::vector<ThumbnailData> &infos, NativeRdb::RdbPredicates &rdbPredicate, int &err)
2409 {
2410 vector<string> column = {
2411 MEDIA_DATA_DB_ID, MEDIA_DATA_DB_FILE_PATH, MEDIA_DATA_DB_HEIGHT, MEDIA_DATA_DB_WIDTH,
2412 MEDIA_DATA_DB_POSITION, MEDIA_DATA_DB_MEDIA_TYPE, MEDIA_DATA_DB_DATE_ADDED, MEDIA_DATA_DB_NAME,
2413 MEDIA_DATA_DB_ORIENTATION,
2414 MEDIA_DATA_DB_DATE_TAKEN,
2415 };
2416 rdbPredicate.EqualTo(PhotoColumn::PHOTO_THUMBNAIL_READY, "0");
2417 if (!IsMobileNetworkEnabled()) {
2418 rdbPredicate.BeginWrap();
2419 rdbPredicate.EqualTo(PhotoColumn::PHOTO_POSITION, "1");
2420 rdbPredicate.Or();
2421 rdbPredicate.EqualTo(PhotoColumn::PHOTO_POSITION, "3");
2422 rdbPredicate.EndWrap();
2423 }
2424 rdbPredicate.EqualTo(MEDIA_DATA_DB_TIME_PENDING, "0");
2425 rdbPredicate.EqualTo(PhotoColumn::PHOTO_CLEAN_FLAG, "0");
2426 rdbPredicate.EqualTo(MEDIA_DATA_DB_DATE_TRASHED, "0");
2427 rdbPredicate.EqualTo(COMPAT_HIDDEN, "0");
2428 rdbPredicate.Limit(THUMBNAIL_GENERATE_BATCH_COUNT);
2429 if (opts.store == nullptr) {
2430 MEDIA_ERR_LOG("opts.store is nullptr");
2431 return false;
2432 }
2433 shared_ptr<ResultSet> resultSet = opts.store->QueryByStep(rdbPredicate, column);
2434 if (!CheckResultSetCount(resultSet, err)) {
2435 MEDIA_ERR_LOG("CheckResultSetCount failed %{public}d", err);
2436 if (err == E_EMPTY_VALUES_BUCKET) {
2437 return true;
2438 }
2439 return false;
2440 }
2441 err = resultSet->GoToFirstRow();
2442 if (err != E_OK) {
2443 MEDIA_ERR_LOG("Failed GoToFirstRow %{public}d", err);
2444 return false;
2445 }
2446
2447 ThumbnailData data;
2448 do {
2449 ParseQueryResult(resultSet, data, err, column);
2450 if (!data.path.empty()) {
2451 infos.push_back(data);
2452 }
2453 } while (resultSet->GoToNextRow() == E_OK);
2454 return true;
2455 }
2456
ConvertStrToInt32(const std::string & str,int32_t & ret)2457 bool ThumbnailUtils::ConvertStrToInt32(const std::string &str, int32_t &ret)
2458 {
2459 if (str.empty() || str.length() > INT32_MAX_VALUE_LENGTH) {
2460 MEDIA_ERR_LOG("convert failed, str = %{public}s", str.c_str());
2461 return false;
2462 }
2463 if (!IsNumericStr(str)) {
2464 MEDIA_ERR_LOG("convert failed, input is not number, str = %{public}s", str.c_str());
2465 return false;
2466 }
2467 int64_t numberValue = std::stoll(str);
2468 if (numberValue < INT32_MIN || numberValue > INT32_MAX) {
2469 MEDIA_ERR_LOG("convert failed, Input is out of range, str = %{public}s", str.c_str());
2470 return false;
2471 }
2472 ret = static_cast<int32_t>(numberValue);
2473 return true;
2474 }
2475
CheckCloudThumbnailDownloadFinish(const std::shared_ptr<MediaLibraryRdbStore> rdbStorePtr)2476 bool ThumbnailUtils::CheckCloudThumbnailDownloadFinish(const std::shared_ptr<MediaLibraryRdbStore> rdbStorePtr)
2477 {
2478 if (rdbStorePtr == nullptr) {
2479 MEDIA_ERR_LOG("RdbStorePtr is nullptr!");
2480 return false;
2481 }
2482
2483 RdbPredicates rdbPredicates(PhotoColumn::PHOTOS_TABLE);
2484 vector<string> column = { "count(1) AS count" };
2485 rdbPredicates.BeginWrap()
2486 ->GreaterThanOrEqualTo(PhotoColumn::PHOTO_POSITION, CLOUD_PHOTO_POSITION)
2487 ->And()
2488 ->NotEqualTo(PhotoColumn::PHOTO_THUMB_STATUS, CLOUD_THUMB_STATUS_DOWNLOAD)
2489 ->EndWrap();
2490 shared_ptr<ResultSet> resultSet = rdbStorePtr->Query(rdbPredicates, column);
2491 if (resultSet == nullptr || resultSet->GoToFirstRow() != NativeRdb::E_OK) {
2492 MEDIA_ERR_LOG("ResultSet is null!");
2493 return false;
2494 }
2495
2496 int32_t count = GetInt32Val(RDB_QUERY_COUNT, resultSet);
2497 MEDIA_INFO_LOG("Number of undownloaded cloud images: %{public}d", count);
2498 if (count > CLOUD_THUMBNAIL_DOWNLOAD_FINISH_NUMBER) {
2499 return false;
2500 }
2501 return true;
2502 }
2503
QueryOldKeyAstcInfos(const std::shared_ptr<MediaLibraryRdbStore> rdbStorePtr,const std::string & table,std::vector<ThumbnailData> & infos)2504 bool ThumbnailUtils::QueryOldKeyAstcInfos(const std::shared_ptr<MediaLibraryRdbStore> rdbStorePtr,
2505 const std::string &table, std::vector<ThumbnailData> &infos)
2506 {
2507 vector<string> column = {
2508 MEDIA_DATA_DB_ID,
2509 MEDIA_DATA_DB_DATE_ADDED,
2510 MEDIA_DATA_DB_DATE_TAKEN,
2511 };
2512 RdbPredicates rdbPredicates(table);
2513 rdbPredicates.GreaterThanOrEqualTo(PhotoColumn::PHOTO_THUMBNAIL_READY, "3");
2514 rdbPredicates.OrderByDesc(MEDIA_DATA_DB_DATE_TAKEN);
2515 shared_ptr<ResultSet> resultSet = rdbStorePtr->QueryByStep(rdbPredicates, column);
2516 int err = 0;
2517 if (!CheckResultSetCount(resultSet, err)) {
2518 MEDIA_ERR_LOG("CheckResultSetCount failed %{public}d", err);
2519 if (err == E_EMPTY_VALUES_BUCKET) {
2520 return true;
2521 }
2522 return false;
2523 }
2524 err = resultSet->GoToFirstRow();
2525 if (err != E_OK) {
2526 MEDIA_ERR_LOG("Failed GoToFirstRow %{public}d", err);
2527 return false;
2528 }
2529
2530 ThumbnailData data;
2531 do {
2532 ParseQueryResult(resultSet, data, err, column);
2533 infos.push_back(data);
2534 } while (resultSet->GoToNextRow() == E_OK);
2535 return true;
2536 }
2537
CheckRemainSpaceMeetCondition(const int32_t & freeSizePercentLimit)2538 bool ThumbnailUtils::CheckRemainSpaceMeetCondition(const int32_t &freeSizePercentLimit)
2539 {
2540 static int64_t totalSize = MediaFileUtils::GetTotalSize();
2541 if (totalSize <= 0) {
2542 totalSize = MediaFileUtils::GetTotalSize();
2543 }
2544 CHECK_AND_RETURN_RET_LOG(totalSize > 0, false, "Get total size failed, totalSize:%{public}" PRId64, totalSize);
2545 int64_t freeSize = MediaFileUtils::GetFreeSize();
2546 CHECK_AND_RETURN_RET_LOG(freeSize > 0, false, "Get free size failed, freeSize:%{public}" PRId64, freeSize);
2547 int32_t freeSizePercent = static_cast<int32_t>(freeSize * 100 / totalSize);
2548 CHECK_AND_RETURN_RET_LOG(freeSizePercent > freeSizePercentLimit, false,
2549 "Check free size failed, totalSize:%{public}" PRId64 ", freeSize:%{public}" PRId64 ", "
2550 "freeSizePercentLimit:%{public}d", totalSize, freeSize, freeSizePercentLimit);
2551 return true;
2552 }
2553 } // namespace Media
2554 } // namespace OHOS
2555