1 /*
2  * Copyright (C) 2024-2024 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 "burst_key_generator.h"
17 
18 #include <uuid.h>
19 #include <algorithm>
20 #include <sstream>
21 
22 #include "media_log.h"
23 
24 namespace OHOS::Media {
25 /**
26  * @brief find prefix contains "_BURST" of fileInfo.title
27  *
28  * @param fileInfo row data from gallery.db # gallery_media
29  * @return std::string prefix of fileInfo.title
30  */
FindTitlePrefix(const FileInfo & fileInfo)31 std::string BurstKeyGenerator::FindTitlePrefix(const FileInfo &fileInfo)
32 {
33     std::string displayName = fileInfo.displayName;
34     auto pos = displayName.find(this->TITLE_KEY_WORDS_OF_BURST);
35     if (pos == std::string::npos) {
36         MEDIA_ERR_LOG("Media_Restore: cannot find _BURST. Object: %{public}s", this->ToString(fileInfo).c_str());
37         return "";
38     }
39     return displayName.substr(0, std::min<int32_t>(pos, DISPLAY_NAME_PREFIX_LENGTH) + 1);
40 }
41 
42 /**
43  * @brief find group hash based on fileInfo.relativeBucketId, fileInfo.title and groupIndex
44  *
45  * @param fileInfo row data from gallery.db # gallery_media
46  * @return std::string hash to identify a group of burst photo
47  */
FindGroupHash(const FileInfo & fileInfo)48 std::string BurstKeyGenerator::FindGroupHash(const FileInfo &fileInfo)
49 {
50     return fileInfo.relativeBucketId + "#" + FindTitlePrefix(fileInfo) + "#" + std::to_string(FindGroupIndex(fileInfo));
51 }
52 
53 /**
54  * @brief find groupIndex based on objectHash
55  *
56  * @param fileInfo row data from gallery.db # gallery_media
57  * @return int32_t groupIndex to identify which group the fileInfo belongs to
58  */
FindGroupIndex(const FileInfo & fileInfo)59 int32_t BurstKeyGenerator::FindGroupIndex(const FileInfo &fileInfo)
60 {
61     // the photo do not in recycle bin.
62     if (fileInfo.recycleFlag == 0) {
63         return 0;
64     }
65     std::string objectHash = FindObjectHash(fileInfo);
66     auto it = objectHashMap_.find(objectHash);
67     int32_t groupIndex = 1;
68     if (it != objectHashMap_.end()) {
69         groupIndex = it->second + 1;
70     }
71     objectHashMap_[objectHash] = groupIndex;
72     return groupIndex;
73 }
74 
75 /**
76  * @brief find objectHash based on fileInfo.relativeBucketId, fileInfo.title and fileInfo.hashCode
77  *
78  * @param fileInfo row data from gallery.db # gallery_media
79  * @return std::string objectHash to identify fileInfo
80  */
FindObjectHash(const FileInfo & fileInfo)81 std::string BurstKeyGenerator::FindObjectHash(const FileInfo &fileInfo)
82 {
83     return fileInfo.relativeBucketId + "#" + FindTitlePrefix(fileInfo) + "#" + fileInfo.hashCode;
84 }
85 
86 /**
87  * @brief generate a uuid without '-'
88  *
89  * @return std::string uuid with 32 characters
90  */
GenerateUuid()91 std::string BurstKeyGenerator::GenerateUuid()
92 {
93     uuid_t uuid;
94     uuid_generate(uuid);
95     char str[UUID_STR_LENGTH] = {};
96     uuid_unparse(uuid, str);
97     return str;
98 }
99 
100 /**
101  * @brief find burstKey for burst photo in Album and Recycle-Bin
102  *
103  * @param fileInfo row data from gallery.db # gallery_media
104  * @return std::string burstKey to identify burst photo group
105  */
FindBurstKey(const FileInfo & fileInfo)106 std::string BurstKeyGenerator::FindBurstKey(const FileInfo &fileInfo)
107 {
108     // isBurst, 1=burst cover photo, 2=burst photo, 0=others
109     if (fileInfo.isBurst != BURST_COVER_TYPE && fileInfo.isBurst != BURST_MEMBER_TYPE) {
110         return "";
111     }
112     std::unique_lock<std::mutex> lock(this->burstKeyLock_);
113     std::string groupHash = FindGroupHash(fileInfo);
114     auto it = groupHashMap_.find(groupHash);
115     if (it == groupHashMap_.end()) {
116         groupHashMap_[groupHash] = GenerateUuid();
117     }
118     MEDIA_DEBUG_LOG("Media_Restore: burst photo, objectHash: %{public}s, groupHash: %{public}s, burstKey: %{public}s",
119         FindObjectHash(fileInfo).c_str(),
120         groupHash.c_str(),
121         groupHashMap_[groupHash].c_str());
122     return groupHashMap_[groupHash];
123 }
124 
ToString(const FileInfo & fileInfo)125 std::string BurstKeyGenerator::ToString(const FileInfo &fileInfo)
126 {
127     std::stringstream ss;
128     ss << "FileInfo[ fileId: " << fileInfo.fileIdOld << ", displayName: " << fileInfo.displayName
129        << ", bundleName: " << fileInfo.bundleName << ", lPath: " << fileInfo.lPath << ", size: " << fileInfo.fileSize
130        << ", fileType: " << fileInfo.fileType << ", oldPath: " << fileInfo.oldPath
131        << ", sourcePath: " << fileInfo.sourcePath << " ]";
132     return ss.str();
133 }
134 }  // namespace OHOS::Media