• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 #include "medialibrary_thumbnail.h"
17 
18 #include <fcntl.h>
19 
20 #include "bytrace.h"
21 #include "distributed_kv_data_manager.h"
22 #include "image_packer.h"
23 #include "media_data_ability_const.h"
24 #include "media_lib_service_const.h"
25 #include "media_log.h"
26 #include "medialibrary_sync_table.h"
27 #include "medialibrary_sync_table.h"
28 #include "openssl/sha.h"
29 #include "rdb_errno.h"
30 #include "rdb_predicates.h"
31 #include "uri_helper.h"
32 using namespace std;
33 using namespace OHOS::DistributedKv;
34 using namespace OHOS::NativeRdb;
35 
36 namespace OHOS {
37 namespace Media {
38 const string THUMBNAIL_END_SUFFIX = "_THU";
39 const string THUMBNAIL_LCD_END_SUFFIX = "_LCD";
40 const string FILE_URI_PREX = "file://";
41 
42 const string THUMBNAIL_FORMAT = "image/jpeg";
43 static constexpr uint8_t THUMBNAIL_QUALITY = 80;
44 static constexpr uint32_t THUMBNAIL_QUERY_MAX = 1000;
45 static constexpr int64_t AV_FRAME_TIME = 0;
46 
47 static constexpr uint8_t NUM_0 = 0;
48 static constexpr uint8_t NUM_1 = 1;
49 static constexpr uint8_t NUM_2 = 2;
50 static constexpr uint8_t NUM_3 = 3;
51 static constexpr uint8_t NUM_4 = 4;
52 
ThumbnailDataCopy(ThumbnailData & data,ThumbnailRdbData & rdbData)53 void ThumbnailDataCopy(ThumbnailData &data, ThumbnailRdbData &rdbData)
54 {
55     data.id = rdbData.id;
56     data.path = rdbData.path;
57     data.thumbnailKey = rdbData.thumbnailKey;
58     data.lcdKey = rdbData.lcdKey;
59     data.mediaType = rdbData.mediaType;
60 }
61 
MediaLibraryThumbnail()62 MediaLibraryThumbnail::MediaLibraryThumbnail()
63 {
64     InitKvStore();
65 }
66 
ParseStringResult(shared_ptr<ResultSet> resultSet,int index,string & data,int & errorCode)67 void ParseStringResult(shared_ptr<ResultSet> resultSet,
68                        int index, string &data, int &errorCode)
69 {
70     bool isNull = true;
71     errorCode = resultSet->IsColumnNull(index, isNull);
72     if (errorCode != E_OK) {
73         MEDIA_ERR_LOG("Failed to check column %{public}d null %{public}d", index, errorCode);
74     }
75 
76     if (!isNull) {
77         errorCode = resultSet->GetString(index, data);
78         if (errorCode != E_OK) {
79             MEDIA_ERR_LOG("Failed to get column %{public}d string %{public}d", index, errorCode);
80         }
81     } else {
82         MEDIA_INFO_LOG("Get column %{public}d null", index);
83     }
84 }
85 
ParseQueryResult(shared_ptr<ResultSet> resultSet,ThumbnailRdbData & data,int & errorCode)86 void ParseQueryResult(shared_ptr<ResultSet> resultSet,
87                       ThumbnailRdbData &data, int &errorCode)
88 {
89     ParseStringResult(resultSet, NUM_0, data.id, errorCode);
90     ParseStringResult(resultSet, NUM_1, data.path, errorCode);
91     ParseStringResult(resultSet, NUM_2, data.thumbnailKey, errorCode);
92     ParseStringResult(resultSet, NUM_3, data.lcdKey, errorCode);
93     data.mediaType = MediaType::MEDIA_TYPE_DEFAULT;
94     errorCode = resultSet->GetInt(NUM_4, data.mediaType);
95 }
96 
CreateThumbnail(ThumbRdbOpt & opts,ThumbnailData & data,std::string & key)97 bool MediaLibraryThumbnail::CreateThumbnail(ThumbRdbOpt &opts,
98                                             ThumbnailData &data,
99                                             std::string &key)
100 {
101     MEDIA_INFO_LOG("MediaLibraryThumbnail::CreateThumbnail3 IN");
102     int errorCode;
103 
104     if (!data.thumbnailKey.empty() &&
105         IsImageExist(data.thumbnailKey)) {
106         MEDIA_INFO_LOG("MediaLibraryThumbnail::CreateThumbnail image has exist in kvStore");
107         return true;
108     }
109 
110     if (!LoadSourceImage(data)) {
111         return false;
112     }
113 
114     if (!GenThumbnailKey(data)) {
115         return false;
116     }
117 
118     if (data.thumbnailKey.empty()) {
119         MEDIA_ERR_LOG("MediaLibraryThumbnail::Gen Thumbnail Key is empty");
120         return false;
121     }
122 
123     if (IsImageExist(data.thumbnailKey)) {
124         MEDIA_INFO_LOG("MediaLibraryThumbnail::CreateThumbnail Get thumbnail in kvStore");
125     } else {
126         if (!CreateThumbnailData(data)) {
127             return false;
128         }
129 
130         if (!SaveThumbnailData(data)) {
131             return false;
132         }
133     }
134 
135     data.lcdKey.clear();
136 
137     if (!UpdateThumbnailInfo(opts, data, errorCode)) {
138         return false;
139     }
140     key = data.thumbnailKey;
141 
142     MEDIA_INFO_LOG("MediaLibraryThumbnail::CreateThumbnail3 OUT");
143     return true;
144 }
145 
CreateThumbnail(ThumbRdbOpt & opts,string & key)146 bool MediaLibraryThumbnail::CreateThumbnail(ThumbRdbOpt &opts, string &key)
147 {
148     StartTrace(BYTRACE_TAG_OHOS, "CreateThumbnail");
149     MEDIA_INFO_LOG("MediaLibraryThumbnail::CreateThumbnail IN");
150 
151     ThumbnailData thumbnailData;
152     int errorCode;
153     if (!QueryThumbnailInfo(opts, thumbnailData, errorCode)) {
154         return false;
155     }
156 
157     bool ret = CreateThumbnail(opts, thumbnailData, key);
158 
159     MEDIA_INFO_LOG("MediaLibraryThumbnail::CreateThumbnail OUT");
160     FinishTrace(BYTRACE_TAG_OHOS);
161 
162     return ret;
163 }
164 
CreateLcd(ThumbRdbOpt & opts,string & key)165 bool MediaLibraryThumbnail::CreateLcd(ThumbRdbOpt &opts, string &key)
166 {
167     StartTrace(BYTRACE_TAG_OHOS, "CreateLcd");
168     MEDIA_INFO_LOG("MediaLibraryThumbnail::CreateLcd IN");
169 
170     ThumbnailData thumbnailData;
171     int errorCode;
172     if (!QueryThumbnailInfo(opts, thumbnailData, errorCode)) {
173         return false;
174     }
175 
176     if (!thumbnailData.lcdKey.empty() &&
177         IsImageExist(thumbnailData.lcdKey)) {
178         MEDIA_INFO_LOG("MediaLibraryThumbnail::CreateLcd image has exist in kvStore");
179         return true;
180     }
181 
182     if (!LoadSourceImage(thumbnailData)) {
183         return false;
184     }
185 
186     StartTrace(BYTRACE_TAG_OHOS, "CreateLcd GenLcdKey");
187     if (!GenLcdKey(thumbnailData)) {
188         return false;
189     }
190     FinishTrace(BYTRACE_TAG_OHOS);
191 
192     if (thumbnailData.lcdKey.empty()) {
193         MEDIA_ERR_LOG("MediaLibraryThumbnail::Gen lcd Key is empty");
194         return false;
195     }
196 
197     if (IsImageExist(thumbnailData.lcdKey)) {
198         MEDIA_INFO_LOG("MediaLibraryThumbnail::CreateThumbnail Get lcd in kvStore");
199     } else {
200         if (!CreateLcdData(thumbnailData)) {
201             return false;
202         }
203 
204         if (!SaveLcdData(thumbnailData)) {
205             return false;
206         }
207     }
208 
209     if (thumbnailData.thumbnailKey.empty()) {
210         CreateThumbnail(opts, thumbnailData, key);
211     }
212 
213     thumbnailData.thumbnail.clear();
214 
215     StartTrace(BYTRACE_TAG_OHOS, "CreateLcd UpdateThumbnailInfo");
216     if (!UpdateThumbnailInfo(opts, thumbnailData, errorCode)) {
217         return false;
218     }
219     FinishTrace(BYTRACE_TAG_OHOS);
220 
221     key = thumbnailData.lcdKey;
222 
223     MEDIA_INFO_LOG("MediaLibraryThumbnail::CreateLcd OUT");
224     FinishTrace(BYTRACE_TAG_OHOS);
225 
226     return true;
227 }
228 
GetThumbnailKey(ThumbRdbOpt & opts,Size & size)229 shared_ptr<AbsSharedResultSet> MediaLibraryThumbnail::GetThumbnailKey(ThumbRdbOpt &opts, Size &size)
230 {
231     shared_ptr<AbsSharedResultSet> queryResultSet;
232     MEDIA_INFO_LOG("MediaLibraryThumbnail::GetThumbnailKey IN");
233     if (singleKvStorePtr_ == nullptr) {
234         MEDIA_ERR_LOG("KvStore is not init");
235         return nullptr;
236     }
237 
238     ThumbnailData thumbnailData;
239     int errorCode;
240     queryResultSet = QueryThumbnailInfo(opts, thumbnailData, errorCode);
241     if (queryResultSet == nullptr) {
242         return queryResultSet;
243     }
244 
245     // Distribute data
246     if (MEDIALIBRARY_TABLE.compare(opts.table) != 0) {
247         return queryResultSet;
248     }
249 
250     bool isFromLcd = isThumbnailFromLcd(size);
251     if (isFromLcd) {
252         if (thumbnailData.lcdKey.empty()) {
253             CreateLcd(opts, thumbnailData.lcdKey);
254         } else {
255             return queryResultSet;
256         }
257     } else {
258         if (thumbnailData.thumbnailKey.empty()) {
259             CreateThumbnail(opts, thumbnailData.thumbnailKey);
260         } else {
261             return queryResultSet;
262         }
263     }
264 
265     queryResultSet = QueryThumbnailSet(opts);
266     return queryResultSet;
267 }
268 
GetThumbnailByRdb(ThumbRdbOpt & opts,Size & size,const std::string & uri)269 unique_ptr<PixelMap> MediaLibraryThumbnail::GetThumbnailByRdb(ThumbRdbOpt &opts,
270                                                               Size &size, const std::string &uri)
271 {
272     int errorCode;
273     shared_ptr<AbsSharedResultSet> resultSet = GetThumbnailKey(opts, size);
274     ThumbnailRdbData rdbData;
275     ParseQueryResult(resultSet, rdbData, errorCode);
276 
277     if (errorCode != E_OK) {
278         MEDIA_ERR_LOG("Failed GetThumbnailKey errorCode : %{public}d", errorCode);
279         return nullptr;
280     }
281 
282     string key = rdbData.thumbnailKey;
283     if (isThumbnailFromLcd(size)) {
284         key = rdbData.lcdKey;
285     }
286     if (key.empty()) {
287         return nullptr;
288     }
289     return GetThumbnail(key, size, uri);
290 }
291 
CreateThumbnails(ThumbRdbOpt & opts)292 void MediaLibraryThumbnail::CreateThumbnails(ThumbRdbOpt &opts)
293 {
294     MEDIA_INFO_LOG("MediaLibraryThumbnail::CreateThumbnails IN");
295     vector<ThumbnailRdbData> infos;
296     int errorCode = -1;
297     if (!QueryThumbnailInfos(opts, infos, errorCode)) {
298         MEDIA_ERR_LOG("Failed to QueryThumbnailInfos %{public}d", errorCode);
299         return;
300     }
301 
302     if (infos.empty()) {
303         MEDIA_ERR_LOG("Infos is empty");
304         return;
305     }
306 
307     for (uint32_t i = 0; i < infos.size(); i++) {
308         string key;
309         ThumbnailData data;
310         opts.row = infos[i].id;
311         ThumbnailDataCopy(data, infos[i]);
312         CreateThumbnail(opts, data, key);
313     }
314 
315     MEDIA_INFO_LOG("MediaLibraryThumbnail::CreateThumbnails OUT");
316 }
317 
LoadAudioFile(string & path,shared_ptr<PixelMap> & pixelMap)318 bool MediaLibraryThumbnail::LoadAudioFile(string &path,
319                                           shared_ptr<PixelMap> &pixelMap)
320 {
321     MEDIA_INFO_LOG("MediaLibraryThumbnail::LoadAudioFile IN");
322 #ifdef OLD_MEDIA_STD_API
323     MEDIA_ERR_LOG("Audio FetchArtPicture API is not ready!");
324     return false;
325 #else
326     std::shared_ptr<AVMetadataHelper> avMetadataHelper = AVMetadataHelperFactory::CreateAVMetadataHelper();
327     int32_t errorCode = SetSource(avMetadataHelper, path);
328     if (errorCode != 0) {
329         MEDIA_ERR_LOG("Av meta data helper set source failed %{public}d", errorCode);
330         return false;
331     }
332 
333     auto audioPicMemory = avMetadataHelper->FetchArtPicture();
334     if (audioPicMemory == nullptr) {
335         MEDIA_ERR_LOG("FetchArtPicture failed!");
336         return false;
337     }
338 
339     SourceOptions opts;
340     uint32_t error = SUCCESS;
341     unique_ptr<ImageSource> audioImageSource = ImageSource::CreateImageSource(audioPicMemory->GetBase(),
342                                                                               audioPicMemory->GetSize(),
343                                                                               opts, error);
344     if (audioImageSource == nullptr) {
345         MEDIA_ERR_LOG("Failed to create image source! %{public}d", error);
346         return false;
347     }
348 
349     error = SUCCESS;
350     DecodeOptions decOpts;
351     pixelMap = audioImageSource->CreatePixelMap(decOpts, error);
352     if (pixelMap == nullptr) {
353         MEDIA_ERR_LOG("Av meta data helper fetch frame at time failed");
354         return false;
355     }
356     if (pixelMap->GetAlphaType() == AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN) {
357         pixelMap->SetAlphaType(AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL);
358     }
359 #endif
360     MEDIA_INFO_LOG("MediaLibraryThumbnail::LoadAudioFile OUT");
361     return true;
362 }
LoadVideoFile(string & path,shared_ptr<PixelMap> & pixelMap)363 bool MediaLibraryThumbnail::LoadVideoFile(string &path,
364                                           shared_ptr<PixelMap> &pixelMap)
365 {
366     MEDIA_INFO_LOG("MediaLibraryThumbnail::LoadVideoFile IN");
367     std::shared_ptr<AVMetadataHelper> avMetadataHelper = AVMetadataHelperFactory::CreateAVMetadataHelper();
368     int32_t errorCode = SetSource(avMetadataHelper, path);
369     if (errorCode != 0) {
370         MEDIA_ERR_LOG("Av meta data helper set source failed %{public}d", errorCode);
371         return false;
372     }
373     PixelMapParams param;
374     param.colorFormat = PixelFormat::RGBA_8888;
375     pixelMap = avMetadataHelper->FetchFrameAtTime(AV_FRAME_TIME,
376                                                   AVMetadataQueryOption::AV_META_QUERY_NEXT_SYNC,
377                                                   param);
378     if (pixelMap == nullptr) {
379         MEDIA_ERR_LOG("Av meta data helper fetch frame at time failed");
380         return false;
381     }
382     if (pixelMap->GetAlphaType() == AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN) {
383         pixelMap->SetAlphaType(AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL);
384     }
385     MEDIA_INFO_LOG("MediaLibraryThumbnail::LoadVideoFile OUT");
386     return true;
387 }
LoadImageFile(string & path,shared_ptr<PixelMap> & pixelMap)388 bool MediaLibraryThumbnail::LoadImageFile(string &path,
389                                           shared_ptr<PixelMap> &pixelMap)
390 {
391     MEDIA_INFO_LOG("MediaLibraryThumbnail::LoadImageFile IN");
392     uint32_t errorCode = 0;
393     SourceOptions opts;
394 
395     StartTrace(BYTRACE_TAG_OHOS, "ImageSource::CreateImageSource");
396     unique_ptr<ImageSource> imageSource = ImageSource::CreateImageSource(path,
397                                                                          opts,
398                                                                          errorCode);
399     if (errorCode != Media::SUCCESS) {
400         MEDIA_ERR_LOG("Failed to create image source path %{public}s err %{public}d",
401                       path.c_str(), errorCode);
402         return false;
403     }
404     FinishTrace(BYTRACE_TAG_OHOS);
405 
406     StartTrace(BYTRACE_TAG_OHOS, "imageSource->CreatePixelMap");
407     DecodeOptions decodeOpts;
408     pixelMap = imageSource->CreatePixelMap(decodeOpts, errorCode);
409     if (errorCode != Media::SUCCESS) {
410         MEDIA_ERR_LOG("Failed to create pixelmap path %{public}s err %{public}d",
411                       path.c_str(), errorCode);
412         return false;
413     }
414     FinishTrace(BYTRACE_TAG_OHOS);
415 
416     MEDIA_INFO_LOG("MediaLibraryThumbnail::LoadImageFile OUT");
417     return true;
418 }
419 
GenKey(vector<uint8_t> & data,string & key)420 bool MediaLibraryThumbnail::GenKey(vector<uint8_t> &data, string &key)
421 {
422     MEDIA_INFO_LOG("MediaLibraryThumbnail::GenKey IN");
423     if (data.size() <= 0) {
424         MEDIA_ERR_LOG("Empty data");
425         return false;
426     }
427     unsigned char hash[SHA256_DIGEST_LENGTH] = "";
428     SHA256_CTX ctx;
429     SHA256_Init(&ctx);
430     SHA256_Update(&ctx, data.data(), data.size());
431     SHA256_Final(hash, &ctx);
432     // here we translate sha256 hash to hexadecimal. each 8-bit char will be presented by two characters([0-9a-f])
433     constexpr int CHAR_WIDTH = 8;
434     constexpr int HEX_WIDTH = 4;
435     constexpr unsigned char HEX_MASK = 0xf;
436     constexpr int HEX_A = 10;
437     key.reserve(SHA256_DIGEST_LENGTH * (CHAR_WIDTH / HEX_WIDTH));
438     for (unsigned char i : hash) {
439         unsigned char hex = i >> HEX_WIDTH;
440         if (hex < HEX_A) {
441             key.push_back('0' + hex);
442         } else {
443             key.push_back('a' + hex - HEX_A);
444         }
445         hex = i & HEX_MASK;
446         if (hex < HEX_A) {
447             key.push_back('0' + hex);
448         } else {
449             key.push_back('a' + hex - HEX_A);
450         }
451     }
452     MEDIA_INFO_LOG("MediaLibraryThumbnail::GenKey OUT [%{public}s]", key.c_str());
453     return true;
454 }
455 
CompressImage(std::shared_ptr<PixelMap> & pixelMap,Size & size,std::vector<uint8_t> & data)456 bool MediaLibraryThumbnail::CompressImage(std::shared_ptr<PixelMap> &pixelMap,
457                                           Size &size,
458                                           std::vector<uint8_t> &data)
459 {
460     StartTrace(BYTRACE_TAG_OHOS, "CompressImage");
461 
462     MEDIA_INFO_LOG("MediaLibraryThumbnail::CompressImage IN");
463     InitializationOptions opts = {
464         .size = size,
465         .pixelFormat = PixelFormat::BGRA_8888,
466         .alphaType = AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL
467     };
468 
469     StartTrace(BYTRACE_TAG_OHOS, "PixelMap::Create");
470     unique_ptr<PixelMap> compressImage = PixelMap::Create(*pixelMap, opts);
471     FinishTrace(BYTRACE_TAG_OHOS);
472 
473     PackOption option = {
474         .format = THUMBNAIL_FORMAT,
475         .quality = THUMBNAIL_QUALITY,
476         .numberHint = NUM_1
477     };
478 
479     data.resize(compressImage->GetByteCount());
480 
481     StartTrace(BYTRACE_TAG_OHOS, "imagePacker.StartPacking");
482     ImagePacker imagePacker;
483     int errorCode = imagePacker.StartPacking(data.data(), data.size(), option);
484     if (errorCode != Media::SUCCESS) {
485         MEDIA_ERR_LOG("Failed to StartPacking %{public}d", errorCode);
486         return false;
487     }
488     FinishTrace(BYTRACE_TAG_OHOS);
489 
490     StartTrace(BYTRACE_TAG_OHOS, "imagePacker.AddImage");
491     errorCode = imagePacker.AddImage(*compressImage);
492     if (errorCode != Media::SUCCESS) {
493         MEDIA_ERR_LOG("Failed to StartPacking %{public}d", errorCode);
494         return false;
495     }
496     FinishTrace(BYTRACE_TAG_OHOS);
497 
498     StartTrace(BYTRACE_TAG_OHOS, "imagePacker.FinalizePacking");
499     int64_t packedSize = 0;
500     errorCode = imagePacker.FinalizePacking(packedSize);
501     if (errorCode != Media::SUCCESS) {
502         MEDIA_ERR_LOG("Failed to StartPacking %{public}d", errorCode);
503         return false;
504     }
505     FinishTrace(BYTRACE_TAG_OHOS);
506 
507     MEDIA_INFO_LOG("packedSize=%{public}lld.", static_cast<long long>(packedSize));
508     data.resize(packedSize);
509 
510     MEDIA_INFO_LOG("MediaLibraryThumbnail::CompressImage OUT");
511     FinishTrace(BYTRACE_TAG_OHOS);
512 
513     return true;
514 }
515 
SaveImage(string & key,vector<uint8_t> & image)516 bool MediaLibraryThumbnail::SaveImage(string &key, vector<uint8_t> &image)
517 {
518     MEDIA_INFO_LOG("MediaLibraryThumbnail::SaveImage IN");
519 
520     if (singleKvStorePtr_ == nullptr) {
521         MEDIA_ERR_LOG("KvStore is not init");
522         return false;
523     }
524 
525     StartTrace(BYTRACE_TAG_OHOS, "SaveImage singleKvStorePtr_->Put");
526     Value val(image);
527     singleKvStorePtr_->Put(key, val);
528     FinishTrace(BYTRACE_TAG_OHOS);
529 
530     MEDIA_INFO_LOG("MediaLibraryThumbnail::SaveImage OUT");
531     return true;
532 }
533 
QueryThumbnailSet(ThumbRdbOpt & opts)534 shared_ptr<AbsSharedResultSet> MediaLibraryThumbnail::QueryThumbnailSet(ThumbRdbOpt &opts)
535 {
536     MEDIA_INFO_LOG("MediaLibraryThumbnail::QueryThumbnailSet IN row [%{public}s]",
537                    opts.row.c_str());
538     vector<string> column = {
539         MEDIA_DATA_DB_ID,
540         MEDIA_DATA_DB_FILE_PATH,
541         MEDIA_DATA_DB_THUMBNAIL,
542         MEDIA_DATA_DB_LCD,
543         MEDIA_DATA_DB_MEDIA_TYPE
544     };
545 
546     vector<string> selectionArgs;
547     string strQueryCondition = MEDIA_DATA_DB_ID + "=" + opts.row;
548 
549     RdbPredicates rdbPredicates(opts.table);
550     rdbPredicates.SetWhereClause(strQueryCondition);
551     rdbPredicates.SetWhereArgs(selectionArgs);
552 
553     shared_ptr<AbsSharedResultSet> resultSet = opts.store->Query(rdbPredicates, column);
554     MEDIA_INFO_LOG("MediaLibraryThumbnail::QueryThumbnailSet OUT");
555     return resultSet;
556 }
557 
QueryThumbnailInfo(ThumbRdbOpt & opts,ThumbnailData & data,int & errorCode)558 shared_ptr<AbsSharedResultSet> MediaLibraryThumbnail::QueryThumbnailInfo(ThumbRdbOpt &opts,
559                                                                          ThumbnailData &data, int &errorCode)
560 {
561     StartTrace(BYTRACE_TAG_OHOS, "QueryThumbnailInfo");
562 
563     MEDIA_INFO_LOG("MediaLibraryThumbnail::QueryThumbnailInfo IN row [%{public}s]", opts.row.c_str());
564     vector<string> column = {
565         MEDIA_DATA_DB_ID,
566         MEDIA_DATA_DB_FILE_PATH,
567         MEDIA_DATA_DB_THUMBNAIL,
568         MEDIA_DATA_DB_LCD,
569         MEDIA_DATA_DB_MEDIA_TYPE
570     };
571 
572     vector<string> selectionArgs;
573     string strQueryCondition = MEDIA_DATA_DB_ID + "=" + opts.row;
574 
575     RdbPredicates rdbPredicates(opts.table);
576     rdbPredicates.SetWhereClause(strQueryCondition);
577     rdbPredicates.SetWhereArgs(selectionArgs);
578 
579     StartTrace(BYTRACE_TAG_OHOS, "opts.store->Query");
580     shared_ptr<AbsSharedResultSet> resultSet = opts.store->Query(rdbPredicates, column);
581     int rowCount = 0;
582     errorCode = resultSet->GetRowCount(rowCount);
583     if (errorCode != E_OK) {
584         MEDIA_ERR_LOG("Failed to get row count %{public}d", errorCode);
585         return nullptr;
586     }
587     FinishTrace(BYTRACE_TAG_OHOS);
588 
589     if (rowCount <= 0) {
590         MEDIA_ERR_LOG("No match! %{public}s", rdbPredicates.ToString().c_str());
591         errorCode = E_EMPTY_VALUES_BUCKET;
592         return nullptr;
593     }
594 
595     errorCode = resultSet->GoToFirstRow();
596     if (errorCode != E_OK) {
597         MEDIA_ERR_LOG("Failed GoToFirstRow %{public}d", errorCode);
598         return nullptr;
599     }
600 
601     int columnCount = 0;
602     errorCode = resultSet->GetColumnCount(columnCount);
603     if (errorCode != E_OK) {
604         MEDIA_ERR_LOG("Failed to get column count %{public}d", errorCode);
605         return nullptr;
606     }
607 
608     if (columnCount <= 0) {
609         MEDIA_ERR_LOG("No column!");
610         errorCode = E_EMPTY_VALUES_BUCKET;
611         return nullptr;
612     }
613 
614     ThumbnailRdbData rdbData;
615     ParseQueryResult(resultSet, rdbData, errorCode);
616     ThumbnailDataCopy(data, rdbData);
617 
618     MEDIA_INFO_LOG("MediaLibraryThumbnail::QueryThumbnailInfo OUT");
619     FinishTrace(BYTRACE_TAG_OHOS);
620 
621     return resultSet;
622 }
623 
QueryThumbnailInfos(ThumbRdbOpt & opts,vector<ThumbnailRdbData> & infos,int & errorCode)624 bool MediaLibraryThumbnail::QueryThumbnailInfos(ThumbRdbOpt &opts,
625                                                 vector<ThumbnailRdbData> &infos,
626                                                 int &errorCode)
627 {
628     MEDIA_INFO_LOG("MediaLibraryThumbnail::QueryThumbnailInfos IN");
629     vector<string> column = {
630         MEDIA_DATA_DB_ID,
631         MEDIA_DATA_DB_FILE_PATH,
632         MEDIA_DATA_DB_THUMBNAIL,
633         MEDIA_DATA_DB_LCD,
634         MEDIA_DATA_DB_MEDIA_TYPE
635     };
636     RdbPredicates rdbPredicates(opts.table);
637     rdbPredicates.IsNull(MEDIA_DATA_DB_THUMBNAIL);
638     rdbPredicates.Limit(THUMBNAIL_QUERY_MAX);
639 
640     shared_ptr<ResultSet> resultSet = opts.store->Query(rdbPredicates, column);
641     int rowCount = 0;
642     errorCode = resultSet->GetRowCount(rowCount);
643     if (errorCode != E_OK) {
644         MEDIA_ERR_LOG("Failed to get row count %{public}d", errorCode);
645         return false;
646     }
647 
648     if (rowCount <= 0) {
649         MEDIA_ERR_LOG("No match! %{public}s", rdbPredicates.ToString().c_str());
650         errorCode = E_EMPTY_VALUES_BUCKET;
651         return false;
652     }
653 
654     errorCode = resultSet->GoToFirstRow();
655     if (errorCode != E_OK) {
656         MEDIA_ERR_LOG("Failed GoToFirstRow %{public}d", errorCode);
657         return false;
658     }
659 
660     int columnCount = 0;
661     errorCode = resultSet->GetColumnCount(columnCount);
662     if (errorCode != E_OK) {
663         MEDIA_ERR_LOG("Failed to get column count %{public}d", errorCode);
664         return false;
665     }
666 
667     if (columnCount <= 0) {
668         MEDIA_ERR_LOG("No column!");
669         errorCode = E_EMPTY_VALUES_BUCKET;
670         return false;
671     }
672 
673     do {
674         ThumbnailRdbData data;
675         ParseQueryResult(resultSet, data, errorCode);
676         if (!data.path.empty()) {
677             infos.push_back(data);
678         }
679     } while (resultSet->GoToNextRow() == E_OK);
680 
681     resultSet.reset();
682 
683     MEDIA_INFO_LOG("MediaLibraryThumbnail::QueryThumbnailInfos OUT");
684     return true;
685 }
686 
UpdateThumbnailInfo(ThumbRdbOpt & opts,ThumbnailData & data,int & errorCode)687 bool MediaLibraryThumbnail::UpdateThumbnailInfo(ThumbRdbOpt &opts,
688                                                 ThumbnailData &data,
689                                                 int &errorCode)
690 {
691     MEDIA_DEBUG_LOG("MediaLibraryThumbnail::UpdateThumbnailInfo IN");
692     ValuesBucket values;
693     int changedRows;
694     if (data.thumbnailKey.empty() && data.lcdKey.empty()) {
695         MEDIA_ERR_LOG("No key to update!");
696         return false;
697     }
698 
699     if (data.thumbnailKey.length() > 0) {
700         values.PutString(MEDIA_DATA_DB_THUMBNAIL, data.thumbnailKey);
701     }
702 
703     if (data.lcdKey.length() > 0) {
704         values.PutString(MEDIA_DATA_DB_LCD, data.lcdKey);
705     }
706 
707     StartTrace(BYTRACE_TAG_OHOS, "UpdateThumbnailInfo opts.store->Update");
708     errorCode = opts.store->Update(changedRows, opts.table, values, MEDIA_DATA_DB_ID+" = ?",
709         vector<string> { opts.row });
710     if (errorCode != NativeRdb::E_OK) {
711         MEDIA_ERR_LOG("RdbStore Update failed! %{public}d", errorCode);
712         return false;
713     }
714     FinishTrace(BYTRACE_TAG_OHOS);
715 
716     std::vector<std::string> devices = std::vector<std::string>();
717     MediaLibrarySyncTable syncTable;
718     syncTable.SyncPushTable(opts.store, BUNDLE_NAME, MEDIALIBRARY_TABLE, devices);
719 
720     return true;
721 }
722 
LoadSourceImage(ThumbnailData & data)723 bool MediaLibraryThumbnail::LoadSourceImage(ThumbnailData &data)
724 {
725     StartTrace(BYTRACE_TAG_OHOS, "LoadSourceImage");
726     MEDIA_INFO_LOG("MediaLibraryThumbnail::LoadSourceImage IN");
727 
728     bool ret = false;
729     if (data.mediaType == MEDIA_TYPE_VIDEO) {
730         ret = LoadVideoFile(data.path, data.source);
731     } else if (data.mediaType == MEDIA_TYPE_AUDIO) {
732         ret = LoadAudioFile(data.path, data.source);
733     } else {
734         ret = LoadImageFile(data.path, data.source);
735     }
736 
737     MEDIA_INFO_LOG("MediaLibraryThumbnail::LoadSourceImage OUT");
738     FinishTrace(BYTRACE_TAG_OHOS);
739 
740     return ret;
741 }
GenThumbnailKey(ThumbnailData & data)742 bool MediaLibraryThumbnail::GenThumbnailKey(ThumbnailData &data)
743 {
744     StartTrace(BYTRACE_TAG_OHOS, "GenThumbnailKey");
745     MEDIA_INFO_LOG("MediaLibraryThumbnail::GenThumbnailKey IN");
746     vector<uint8_t> source(data.source->GetPixels(),
747         data.source->GetPixels() + data.source->GetByteCount());
748 
749     bool ret = GenKey(source, data.thumbnailKey);
750     if (ret) {
751         data.thumbnailKey += THUMBNAIL_END_SUFFIX;
752     }
753 
754     MEDIA_INFO_LOG("MediaLibraryThumbnail::GenThumbnailKey OUT [%{public}s]",
755                    data.thumbnailKey.c_str());
756     FinishTrace(BYTRACE_TAG_OHOS);
757 
758     return ret;
759 }
GenLcdKey(ThumbnailData & data)760 bool MediaLibraryThumbnail::GenLcdKey(ThumbnailData &data)
761 {
762     MEDIA_INFO_LOG("MediaLibraryThumbnail::GenLcdKey IN");
763     vector<uint8_t> source(data.source->GetPixels(),
764         data.source->GetPixels() + data.source->GetByteCount());
765 
766     bool ret = GenKey(source, data.lcdKey);
767     if (ret) {
768         data.lcdKey += THUMBNAIL_LCD_END_SUFFIX;
769     }
770     MEDIA_INFO_LOG("MediaLibraryThumbnail::GenLcdKey OUT");
771     return ret;
772 }
CreateThumbnailData(ThumbnailData & data)773 bool MediaLibraryThumbnail::CreateThumbnailData(ThumbnailData &data)
774 {
775     MEDIA_INFO_LOG("MediaLibraryThumbnail::CreateThumbnailData IN");
776 
777     Size size = {
778         .width = DEFAULT_THUMBNAIL_SIZE.width,
779         .height = DEFAULT_THUMBNAIL_SIZE.height
780     };
781 
782     bool ret = CompressImage(data.source, size, data.thumbnail);
783 
784     MEDIA_INFO_LOG("MediaLibraryThumbnail::CreateThumbnailData OUT");
785     return ret;
786 }
787 
CreateLcdData(ThumbnailData & data)788 bool MediaLibraryThumbnail::CreateLcdData(ThumbnailData &data)
789 {
790     MEDIA_INFO_LOG("MediaLibraryThumbnail::CreateLcdData IN");
791 
792     Size size = DEFAULT_LCD_SIZE;
793     double widthF = data.source->GetWidth();
794     widthF = widthF*size.height/data.source->GetHeight();
795     size.width = static_cast<int32_t>(widthF);
796 
797     bool ret = CompressImage(data.source, size, data.lcd);
798 
799     MEDIA_INFO_LOG("MediaLibraryThumbnail::CreateLcdData OUT");
800     return ret;
801 }
802 
SaveThumbnailData(ThumbnailData & data)803 bool MediaLibraryThumbnail::SaveThumbnailData(ThumbnailData &data)
804 {
805     MEDIA_INFO_LOG("MediaLibraryThumbnail::SaveThumbnailData IN");
806 
807     bool ret = SaveImage(data.thumbnailKey, data.thumbnail);
808 
809     MEDIA_INFO_LOG("MediaLibraryThumbnail::SaveThumbnailData OUT");
810     return ret;
811 }
SaveLcdData(ThumbnailData & data)812 bool MediaLibraryThumbnail::SaveLcdData(ThumbnailData &data)
813 {
814     MEDIA_INFO_LOG("MediaLibraryThumbnail::SaveLcdData IN");
815 
816     bool ret = SaveImage(data.lcdKey, data.lcd);
817 
818     MEDIA_INFO_LOG("MediaLibraryThumbnail::SaveLcdData OUT");
819     return ret;
820 }
GetThumbnailFromKvStore(ThumbnailData & data)821 bool MediaLibraryThumbnail::GetThumbnailFromKvStore(ThumbnailData &data)
822 {
823     MEDIA_INFO_LOG("MediaLibraryThumbnail::GetThumbnailFromKvStore IN");
824 
825     bool ret = GetImage(data.thumbnailKey, data.thumbnail);
826 
827     MEDIA_INFO_LOG("MediaLibraryThumbnail::GetThumbnailFromKvStore OUT");
828     return ret;
829 }
GetLcdFromKvStore(ThumbnailData & data)830 bool MediaLibraryThumbnail::GetLcdFromKvStore(ThumbnailData &data)
831 {
832     MEDIA_INFO_LOG("MediaLibraryThumbnail::GetLcdFromKvStore IN");
833 
834     bool ret = GetImage(data.lcdKey, data.lcd);
835 
836     MEDIA_INFO_LOG("MediaLibraryThumbnail::GetLcdFromKvStore OUT");
837     return ret;
838 }
839 
ResizeThumbnailToTarget(ThumbnailData & data,Size & size,unique_ptr<PixelMap> & pixelMap)840 bool MediaLibraryThumbnail::ResizeThumbnailToTarget(ThumbnailData &data,
841                                                     Size &size,
842                                                     unique_ptr<PixelMap> &pixelMap)
843 {
844     MEDIA_INFO_LOG("MediaLibraryThumbnail::ResizeThumbnailToTarget IN");
845 
846     bool ret = ResizeImage(data.thumbnail, size, pixelMap);
847 
848     MEDIA_INFO_LOG("MediaLibraryThumbnail::ResizeThumbnailToTarget OUT");
849     return ret;
850 }
851 
ResizeLcdToTarget(ThumbnailData & data,Size & size,unique_ptr<PixelMap> & pixelMap)852 bool MediaLibraryThumbnail::ResizeLcdToTarget(ThumbnailData &data,
853                                               Size &size,
854                                               unique_ptr<PixelMap> &pixelMap)
855 {
856     MEDIA_INFO_LOG("MediaLibraryThumbnail::ResizeLcdToTarget IN");
857 
858     bool ret = ResizeImage(data.lcd, size, pixelMap);
859 
860     MEDIA_INFO_LOG("MediaLibraryThumbnail::ResizeLcdToTarget OUT");
861     return ret;
862 }
SetSource(std::shared_ptr<AVMetadataHelper> avMetadataHelper,const std::string & path)863 int32_t MediaLibraryThumbnail::SetSource(std::shared_ptr<AVMetadataHelper> avMetadataHelper, const std::string &path)
864 {
865     MEDIA_INFO_LOG("MediaLibraryThumbnail::SetSource IN");
866     if (avMetadataHelper == nullptr) {
867         MEDIA_INFO_LOG("MediaLibraryThumbnail::SetSource avMetadataHelper == nullptr");
868         return -1;
869     }
870     MEDIA_INFO_LOG("MediaLibraryThumbnail::SetSource path = %{public}s", path.c_str());
871     UriHelper uriHelper(path);
872     if (uriHelper.UriType() != UriHelper::URI_TYPE_FILE && !uriHelper.AccessCheck(UriHelper::URI_READ)) {
873         std::cout << "Invalid file Path" << std::endl;
874         return -1;
875     }
876     std::string rawFile = uriHelper.FormattedUri();
877     rawFile = rawFile.substr(strlen("file://"));
878     MEDIA_INFO_LOG("MediaLibraryThumbnail::SetSource rawFile = %{public}s", rawFile.c_str());
879     int32_t fd = open(rawFile.c_str(), O_RDONLY);
880     MEDIA_INFO_LOG("MediaLibraryThumbnail::SetSource fd = %{public}d", fd);
881     if (fd <= 0) {
882         MEDIA_INFO_LOG("MediaLibraryThumbnail::SetSource Open file failed");
883         return -1;
884     }
885 
886     struct stat64 st;
887     if (fstat64(fd, &st) != 0) {
888         MEDIA_INFO_LOG("MediaLibraryThumbnail::SetSource Get file state failed");
889         (void)close(fd);
890         return -1;
891     }
892     int64_t length = static_cast<int64_t>(st.st_size);
893     MEDIA_INFO_LOG("MediaLibraryThumbnail::SetSource length = %{public}lld", length);
894     int32_t ret = avMetadataHelper->SetSource(fd, 0, length, 1);
895     if (ret != 0) {
896         MEDIA_INFO_LOG("MediaLibraryThumbnail::SetSource fail");
897         (void)close(fd);
898         return -1;
899     }
900     (void)close(fd);
901     MEDIA_INFO_LOG("MediaLibraryThumbnail::SetSource OUT");
902     return 0;
903 }
904 } // namespace Media
905 } // namespace OHOS
906