• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 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 #include <string>
16 #include <vector>
17 
18 #include "photos_restore.h"
19 #include "backup_const.h"
20 #include "backup_file_utils.h"
21 #include "userfile_manager_types.h"
22 #include "rdb_store.h"
23 #include "result_set_utils.h"
24 #include "media_log.h"
25 #include "photo_album_dao.h"
26 #include "album_plugin_config.h"
27 #include "backup_file_utils.h"
28 #include "mimetype_utils.h"
29 
30 namespace OHOS::Media {
31 static const int32_t CLOUD_ENHANCEMENT_ALBUM = 1;
32 static const int32_t DUAL_ENHANCEMENT_PHOTO_QUALITY = 120;
33 static const int32_t SINGLE_CLOUD_ENHANCEMENT_PHOTO = 120;
34 
35 /**
36  * @brief Get the gallery_media to restore to Photos.
37  */
GetGalleryMedia(int32_t offset,int pageSize,bool shouldIncludeSd,bool hasLowQualityImage)38 std::shared_ptr<NativeRdb::ResultSet> PhotosRestore::GetGalleryMedia(
39     int32_t offset, int pageSize, bool shouldIncludeSd, bool hasLowQualityImage)
40 {
41     return this->galleryMediaDao_.GetGalleryMedia(offset, pageSize, shouldIncludeSd, hasLowQualityImage);
42 }
43 
44 /**
45  * @brief Get the gallery_media for cloud to restore to Photos.
46  */
GetCloudGalleryMedia(int32_t offset,int pageSize,bool shouldIncludeSd,bool hasLowQualityImage)47 std::shared_ptr<NativeRdb::ResultSet> PhotosRestore::GetCloudGalleryMedia(
48     int32_t offset, int pageSize, bool shouldIncludeSd, bool hasLowQualityImage)
49 {
50     return this->galleryMediaDao_.GetCloudGalleryMedia(offset, pageSize, shouldIncludeSd, hasLowQualityImage);
51 }
52 
53 /**
54  * @brief Get the row count of gallery_media.
55  */
GetGalleryMediaCount(bool shouldIncludeSd,bool hasLowQualityImage)56 int32_t PhotosRestore::GetGalleryMediaCount(bool shouldIncludeSd, bool hasLowQualityImage)
57 {
58     return this->galleryMediaDao_.GetGalleryMediaCount(shouldIncludeSd, hasLowQualityImage);
59 }
60 
61 /**
62  * @brief Get the row count of cloud_meta.
63  */
GetCloudMetaCount(bool shouldIncludeSd,bool hasLowQualityImage)64 int32_t PhotosRestore::GetCloudMetaCount(bool shouldIncludeSd, bool hasLowQualityImage)
65 {
66     return this->galleryMediaDao_.GetCloudMetaCount(shouldIncludeSd, hasLowQualityImage);
67 }
68 
69 /**
70  * @brief Get the PhotoAlbum basic info.
71  */
FindAlbumInfo(const FileInfo & fileInfo)72 PhotoAlbumDao::PhotoAlbumRowData PhotosRestore::FindAlbumInfo(const FileInfo &fileInfo)
73 {
74     std::string lPath = fileInfo.lPath;
75     // Scenario 2, WHEN FileInfo is in hidden album, THEN override lPath to the folder in sourcePath.
76     // Scenario 3, WHEN FileInfo is not belongs to any album, THEN override lPath to the folder in sourcePath.
77     if (fileInfo.lPath.empty() || this->ToLower(fileInfo.lPath) == this->ToLower(GALLERT_HIDDEN_ALBUM)) {
78         lPath = this->photoAlbumDao_.ParseSourcePathToLPath(fileInfo.sourcePath);
79         MEDIA_INFO_LOG("Media_Restore: fix lPath of album.fileInfo.lPath: %{public}s, "
80                        "lPathFromSourcePath: %{public}s, lowercase: %{public}s, FileInfo Object: %{public}s",
81             fileInfo.lPath.c_str(),
82             lPath.c_str(),
83             this->ToLower(lPath).c_str(),
84             this->ToString(fileInfo).c_str());
85     }
86     PhotoAlbumDao::PhotoAlbumRowData albumInfo;
87     // Scenario 1, WHEN FileInfo is in /Pictures/Screenshots and Video type, THEN redirect to /Pictures/Screenrecords
88     if (this->ToLower(lPath) == this->ToLower(AlbumPlugin::LPATH_SCREEN_SHOTS) &&
89         fileInfo.fileType == MediaType::MEDIA_TYPE_VIDEO) {
90         albumInfo = this->photoAlbumDao_.BuildAlbumInfoOfRecorders();
91         albumInfo = this->photoAlbumDao_.GetOrCreatePhotoAlbum(albumInfo);
92         MEDIA_INFO_LOG("Media_Restore: screenshots redirect to screenrecords, fileInfo.lPath: %{public}s, "
93                        "lPathForScreenshot: %{public}s, Object: %{public}s, albumInfo: %{public}s",
94             fileInfo.lPath.c_str(),
95             lPath.c_str(),
96             this->ToString(fileInfo).c_str(),
97             this->photoAlbumDao_.ToString(albumInfo).c_str());
98         return albumInfo;
99     }
100     albumInfo = this->photoAlbumDao_.BuildAlbumInfoByLPath(lPath);
101     return this->photoAlbumDao_.GetOrCreatePhotoAlbum(albumInfo);
102 }
103 
104 /**
105  * @brief Get the PhotoAlbum basic info.
106  */
FindAlbumId(const FileInfo & fileInfo)107 int32_t PhotosRestore::FindAlbumId(const FileInfo &fileInfo)
108 {
109     PhotoAlbumDao::PhotoAlbumRowData albumInfo = this->FindAlbumInfo(fileInfo);
110     CHECK_AND_PRINT_LOG(!albumInfo.lPath.empty(), "Can not find PhotoAlbum. fileInfo.lPath= %{public}s,"
111         " fileInfo.sourcePath= %{public}s", fileInfo.lPath.c_str(), fileInfo.sourcePath.c_str());
112     return albumInfo.albumId;
113 }
114 
115 /**
116  * @brief find lPath by FileInfo.
117  */
FindlPath(const FileInfo & fileInfo)118 std::string PhotosRestore::FindlPath(const FileInfo &fileInfo)
119 {
120     PhotoAlbumDao::PhotoAlbumRowData albumInfo = this->FindAlbumInfo(fileInfo);
121     CHECK_AND_PRINT_LOG(!albumInfo.lPath.empty(), "Can not find PhotoAlbum. fileInfo.lPath= %{public}s,"
122         " fileInfo.sourcePath= %{public}s", fileInfo.lPath.c_str(), fileInfo.sourcePath.c_str());
123     return albumInfo.lPath;
124 }
125 
126 /**
127  * @brief Find PackageName by FileInfo.
128  */
FindPackageName(const FileInfo & fileInfo)129 std::string PhotosRestore::FindPackageName(const FileInfo &fileInfo)
130 {
131     PhotoAlbumDao::PhotoAlbumRowData albumInfo = this->FindAlbumInfo(fileInfo);
132     CHECK_AND_PRINT_LOG(!albumInfo.lPath.empty(), "Can not find PhotoAlbum. fileInfo.lPath= %{public}s,"
133         " fileInfo.sourcePath= %{public}s", fileInfo.lPath.c_str(), fileInfo.sourcePath.c_str());
134     return albumInfo.albumName;
135 }
136 
137 /**
138  * @brief Find BundleName by FileInfo.
139  */
FindBundleName(const FileInfo & fileInfo)140 std::string PhotosRestore::FindBundleName(const FileInfo &fileInfo)
141 {
142     PhotoAlbumDao::PhotoAlbumRowData albumInfo = this->FindAlbumInfo(fileInfo);
143     CHECK_AND_PRINT_LOG(!albumInfo.lPath.empty(), "Can not find PhotoAlbum. fileInfo.lPath= %{public}s,"
144         "fileInfo.sourcePath= %{public}s", fileInfo.lPath.c_str(), fileInfo.sourcePath.c_str());
145     return albumInfo.bundleName;
146 }
147 
148 /**
149  * @brief Find BurstKey by FileInfo.
150  */
FindBurstKey(const FileInfo & fileInfo)151 std::string PhotosRestore::FindBurstKey(const FileInfo &fileInfo)
152 {
153     CHECK_AND_RETURN_RET(fileInfo.burstKey.size() <= 0, fileInfo.burstKey);
154     return "";
155 }
156 
157 /**
158  * @brief Find Dirty by FileInfo.
159  */
FindDirty(const FileInfo & fileInfo)160 int32_t PhotosRestore::FindDirty(const FileInfo &fileInfo)
161 {
162     return static_cast<int32_t>(DirtyTypes::TYPE_NEW);
163 }
164 
165 /**
166  * @brief Find burst_cover_level by FileInfo.
167  */
FindBurstCoverLevel(const FileInfo & fileInfo)168 int32_t PhotosRestore::FindBurstCoverLevel(const FileInfo &fileInfo)
169 {
170     // identify burst photo
171     bool cond = (fileInfo.isBurst == static_cast<int32_t>(BurstCoverLevelType::COVER) ||
172         fileInfo.isBurst == static_cast<int32_t>(BurstCoverLevelType::MEMBER));
173     CHECK_AND_RETURN_RET(!cond, fileInfo.isBurst);
174     return static_cast<int32_t>(BurstCoverLevelType::COVER);
175 }
176 
177 /**
178  * @brief Find subtype by FileInfo.
179  */
FindSubtype(const FileInfo & fileInfo)180 int32_t PhotosRestore::FindSubtype(const FileInfo &fileInfo)
181 {
182     CHECK_AND_RETURN_RET(fileInfo.burstKey.size() <= 0, static_cast<int32_t>(PhotoSubType::BURST));
183     CHECK_AND_RETURN_RET(!BackupFileUtils::IsLivePhoto(fileInfo), static_cast<int32_t>(PhotoSubType::MOVING_PHOTO));
184     return static_cast<int32_t>(PhotoSubType::DEFAULT);
185 }
186 
187 /**
188  * @brief Find date_trashed by FileInfo.
189  */
FindDateTrashed(const FileInfo & fileInfo)190 int64_t PhotosRestore::FindDateTrashed(const FileInfo &fileInfo)
191 {
192     // prevent Photos marked as deleted when it's in use.
193     CHECK_AND_RETURN_RET(fileInfo.recycleFlag != 0, 0);
194     // LOG INFO for analyser.
195     if (fileInfo.recycledTime != 0) {
196         string fileName = fileInfo.displayName;
197         MEDIA_WARN_LOG("the file :%{public}s is trash.", BackupFileUtils::GarbleFileName(fileName).c_str());
198     }
199     return fileInfo.recycledTime;
200 }
201 
202 /**
203  * @brief Get duplicate data in gallery db.
204  */
GetDuplicateData(int32_t duplicateDataCount)205 void PhotosRestore::GetDuplicateData(int32_t duplicateDataCount)
206 {
207     if (duplicateDataCount <= 0) {
208         return;
209     }
210     std::string querySql = this->SQL_GALLERY_MEDIA_QUERY_DUPLICATE_DATA;
211     int rowCount = 0;
212     int offset = 0;
213     int pageSize = 200;
214     do {
215         std::vector<NativeRdb::ValueObject> params = {offset, pageSize};
216         if (this->galleryRdb_ == nullptr) {
217             MEDIA_ERR_LOG("Media_Restore: galleryRdb_ is null.");
218             break;
219         }
220         auto resultSet = this->galleryRdb_->QuerySql(querySql, params);
221         if (resultSet == nullptr) {
222             MEDIA_ERR_LOG("Query resultSql is null.");
223             break;
224         }
225         while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
226             std::string data = GetStringVal(GALLERY_FILE_DATA, resultSet);
227             int32_t count = GetInt32Val(CUSTOM_COUNT, resultSet);
228             this->duplicateDataUsedCountMap_[data] = 0;
229             MEDIA_INFO_LOG("Get duplicate data: %{public}s, count: %{public}d",
230                 BackupFileUtils::GarbleFilePath(data, DEFAULT_RESTORE_ID).c_str(),
231                 count);
232         }
233         // Check if there are more rows to fetch.
234         resultSet->GetRowCount(rowCount);
235         offset += pageSize;
236     } while (rowCount > 0);
237 }
238 
239 /**
240  * @brief Check if it is duplicate data in gallery db.
241  */
IsDuplicateData(const std::string & data)242 bool PhotosRestore::IsDuplicateData(const std::string &data)
243 {
244     std::lock_guard<mutex> lock(this->duplicateDataUsedCountMutex_);
245     if (this->duplicateDataUsedCountMap_.count(data) == 0) {
246         return false;
247     }
248     this->duplicateDataUsedCountMap_[data]++;
249     return this->duplicateDataUsedCountMap_.at(data) > 1;
250 }
251 
252 /**
253  * @brief Find PhotoQuality by FileInfo.
254  */
FindPhotoQuality(const FileInfo & fileInfo)255 int32_t PhotosRestore::FindPhotoQuality(const FileInfo &fileInfo)
256 {
257     bool cond = (fileInfo.photoQuality == 1);
258     CHECK_AND_RETURN_RET(!cond, 0);
259     return fileInfo.photoQuality;
260 }
261 
262 /**
263  * @brief Find suffix of displayName. include dot, e.g. ".jpg"
264  * @return return the suffix of displayName. "" if not found.
265  */
GetSuffix(const std::string & displayName)266 std::string PhotosRestore::GetSuffix(const std::string &displayName)
267 {
268     size_t dotPos = displayName.rfind('.');
269     if (dotPos != std::string::npos) {
270         return this->ToLower(displayName.substr(dotPos + 1));  // without dot, e.g. "jpg"
271     }
272     return "";
273 }
274 
275 /**
276  * @brief Find media_type by FileInfo.
277  */
FindMediaType(const FileInfo & fileInfo)278 int32_t PhotosRestore::FindMediaType(const FileInfo &fileInfo)
279 {
280     int32_t dualMediaType = fileInfo.fileType;
281     if (dualMediaType == DUAL_MEDIA_TYPE::IMAGE_TYPE || dualMediaType == DUAL_MEDIA_TYPE::VIDEO_TYPE) {
282         return dualMediaType == DUAL_MEDIA_TYPE::VIDEO_TYPE ? MediaType::MEDIA_TYPE_VIDEO : MediaType::MEDIA_TYPE_IMAGE;
283     }
284     std::string suffix = this->GetSuffix(fileInfo.displayName);
285     MediaType mediaType = MimeTypeUtils::GetMediaTypeFromMimeType(MimeTypeUtils::GetMimeTypeFromExtension(suffix));
286     MEDIA_INFO_LOG("Media_Restore: correct mediaType from %{public}d to %{public}d, displayName: %{public}s",
287         fileInfo.fileType,
288         mediaType,
289         fileInfo.displayName.c_str());
290     return mediaType;
291 }
292 
293 /**
294  * @brief Find source_path for the target device by FileInfo.
295  */
FindSourcePath(const FileInfo & fileInfo)296 std::string PhotosRestore::FindSourcePath(const FileInfo &fileInfo)
297 {
298     if (!fileInfo.sourcePath.empty()) {
299         return fileInfo.sourcePath;
300     }
301     std::string lPath = "/Pictures/其它";
302     if (!fileInfo.lPath.empty()) {
303         lPath = fileInfo.lPath;
304     } else {
305         MEDIA_ERR_LOG("Media_Restore: fileInfo.lPath is empty. Use default lPath: %{public}s", lPath.c_str());
306     }
307     return this->SOURCE_PATH_PREFIX + lPath + "/" + fileInfo.displayName;
308 }
309 
310 /**
311  * @brief Find enhancement photo quality for the target device by FileInfo.
312  */
FindStrongAssociation(const FileInfo & fileInfo)313 int32_t PhotosRestore::FindStrongAssociation(const FileInfo &fileInfo)
314 {
315     if (fileInfo.photoQuality == DUAL_ENHANCEMENT_PHOTO_QUALITY) {
316         return CLOUD_ENHANCEMENT_ALBUM;
317     }
318     return 0;
319 }
320 
321 /**
322  * @brief Find cloud enhancement available for the target device by FileInfo.
323  */
FindCeAvailable(const FileInfo & fileInfo)324 int32_t PhotosRestore::FindCeAvailable(const FileInfo &fileInfo)
325 {
326     if (fileInfo.photoQuality == DUAL_ENHANCEMENT_PHOTO_QUALITY) {
327         return SINGLE_CLOUD_ENHANCEMENT_PHOTO;
328     }
329     return 0;
330 }
331 }  // namespace OHOS::Media