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