• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 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 #ifndef CLONE_RESTORE_HIGHLIGHT_H
17 #define CLONE_RESTORE_HIGHLIGHT_H
18 
19 #include <sstream>
20 #include <string>
21 
22 #include "backup_const.h"
23 #include "backup_database_utils.h"
24 #include "media_log.h"
25 #include "nlohmann/json.hpp"
26 #include "rdb_store.h"
27 #include "safe_map.h"
28 
29 namespace OHOS::Media {
30 class CloneRestoreHighlight {
31 public:
32     struct InitInfo {
33         int32_t sceneCode{-1};
34         std::string taskId;
35         std::shared_ptr<NativeRdb::RdbStore> mediaLibraryRdb;
36         std::shared_ptr<NativeRdb::RdbStore> mediaRdb;
37         std::string backupRestoreDir;
38         std::unordered_map<int32_t, PhotoInfo> photoInfoMap;
39     };
40 
41     void Init(const InitInfo &info);
42     void Restore();
43     void ReportCloneRestoreHighlightTask();
44     int32_t GetNewHighlightAlbumId(int32_t oldId);
45     int32_t GetNewHighlightPhotoId(int32_t oldId);
46     std::string GetNewHighlightPhotoUri(int32_t oldId);
47     bool IsCloneHighlight();
48     std::string GetDefaultPlayInfo();
49     void UpdateHighlightStatus(const std::vector<int32_t> &highlightIds);
50     void UpdateRestoreTimeCost(int64_t timeCost);
51 
52     template<typename T>
53     static void PutIfPresent(NativeRdb::ValuesBucket &values, const std::string &columnName,
54         const std::optional<T> &optionalValue);
55 
56     template<typename T>
57     static void PutIfInIntersection(NativeRdb::ValuesBucket &values, const std::string &columnName,
58         const std::optional<T> &optionalValue, const std::unordered_set<std::string> &intersection);
59 
60     template<typename T>
61     static void GetIfInIntersection(const std::string &columnName, std::optional<T> &optionalValue,
62         const std::unordered_set<std::string> &intersection, std::shared_ptr<NativeRdb::ResultSet> resultSet);
63 
64 private:
65     struct AnalysisAlbumInfo {
66         std::optional<int32_t> albumIdOld;
67         std::optional<int32_t> albumIdNew;
68         std::optional<int32_t> albumType;
69         std::optional<int32_t> albumSubtype;
70         std::optional<std::string> albumName;
71         std::optional<std::string> oldCoverUri;
72         std::string coverUri = "";
73         std::optional<int64_t> dateModified;
74 
75         std::optional<int32_t> rank;
76         std::optional<std::string> tagId;
77         std::optional<int32_t> userOperation;
78         std::optional<std::string> groupTag;
79         std::optional<int32_t> userDisplayLevel;
80         std::optional<int32_t> isMe;
81         std::optional<int32_t> isRemoved;
82         std::optional<int32_t> renameOperation;
83         std::optional<int32_t> isLocal;
84         std::optional<int32_t> isCoverSatisfied;
85         std::optional<std::string> relationship;
86 
87         std::optional<int32_t> highlightIdOld;
88         std::optional<int32_t> highlightIdNew;
89 
ToStringAnalysisAlbumInfo90         std::string ToString() const
91         {
92             std::stringstream outputStr;
93             outputStr << "HighlightAlbumInfo[" << "albumIdOld: ";
94             if (albumIdOld.has_value()) { outputStr << albumIdOld.value(); }
95             outputStr << ", albumIdNew: ";
96             if (albumIdNew.has_value()) { outputStr << albumIdNew.value(); }
97             outputStr << ", albumName: ";
98             if (albumName.has_value()) { outputStr << albumName.value(); }
99             outputStr << ", oldCoverUri: ";
100             if (oldCoverUri.has_value()) { outputStr << oldCoverUri.value(); }
101             outputStr << ", highlightIdNew: ";
102             if (highlightIdNew.has_value()) { outputStr << highlightIdNew.value(); }
103             outputStr << ", coverUri: " << coverUri << "]";
104             return outputStr.str();
105         }
106     };
107 
108     struct HighlightAlbumInfo {
109         std::optional<int32_t> highlightIdOld;
110         std::optional<int32_t> highlightIdNew;
111         std::optional<int32_t> albumIdOld;
112         std::optional<int32_t> aiAlbumIdOld;
113         std::optional<int32_t> albumIdNew;
114         std::optional<int32_t> aiAlbumIdNew;
115         std::optional<std::string> subTitle;
116         std::optional<std::string> clusterType;
117         std::optional<std::string> clusterSubType;
118         std::optional<std::string> clusterCondition;
119         std::optional<int64_t> minDateAdded;
120         std::optional<int64_t> maxDateAdded;
121         std::optional<int64_t> generateTime;
122         std::optional<int32_t> highlightVersion;
123         std::optional<std::string> remarks;
124         std::optional<int32_t> highlightStatus;
125 
126         std::optional<int32_t> insertPicCount;
127         std::optional<int32_t> removePicCount;
128         std::optional<int32_t> shareScreenshotCount;
129         std::optional<int32_t> shareCoverCount;
130         std::optional<int32_t> renameCount;
131         std::optional<int32_t> changeCoverCount;
132         std::optional<int32_t> renderViewedTimes;
133         std::optional<int64_t> renderViewedDuration;
134         std::optional<int32_t> artLayoutViewedTimes;
135         std::optional<int64_t> artLayoutViewedDuration;
136         std::optional<int32_t> musicEditCount;
137         std::optional<int32_t> filterEditCount;
138         std::optional<int32_t> isMuted;
139         std::optional<int32_t> isFavorite;
140         std::optional<std::string> theme;
141         std::optional<int64_t> pinTime;
142         std::optional<int32_t> useSubtitle;
143         std::optional<std::string> highlightLocation;
144 
ToStringHighlightAlbumInfo145         std::string ToString() const
146         {
147             std::stringstream outputStr;
148             outputStr << "HighlightAlbumInfo[" << "albumIdNew: ";
149             if (albumIdNew.has_value()) { outputStr << albumIdNew.value(); }
150             outputStr << ", aiAlbumIdNew: ";
151             if (aiAlbumIdNew.has_value()) { outputStr << aiAlbumIdNew.value(); }
152             outputStr << ", subTitle: ";
153             if (subTitle.has_value()) { outputStr << subTitle.value(); }
154             outputStr << ", clusterType: ";
155             if (clusterType.has_value()) { outputStr << clusterType.value(); }
156             outputStr << ", clusterSubType: ";
157             if (clusterSubType.has_value()) { outputStr << clusterSubType.value(); }
158             outputStr << ", clusterCondition: ";
159             if (clusterCondition.has_value()) { outputStr << clusterCondition.value(); }
160             outputStr << ", highlightStatus: ";
161             if (highlightStatus.has_value()) { outputStr << highlightStatus.value(); }
162             outputStr << "]";
163             return outputStr.str();
164         }
165     };
166 
167     struct HighlightCoverInfo {
168         std::optional<int32_t> highlightIdNew;
169         std::optional<std::string> ratio;
170         std::optional<std::string> background;
171         std::optional<std::string> foreground;
172         std::optional<std::string> wordart;
173         std::optional<int32_t> isCovered;
174         std::optional<std::string> color;
175         std::optional<int32_t> radius;
176         std::optional<double> saturation;
177         std::optional<double> brightness;
178         std::optional<int32_t> backgroundColorType;
179         std::optional<int32_t> shadowLevel;
180         std::optional<double> scaleX;
181         std::optional<double> scaleY;
182         std::optional<double> rectWidth;
183         std::optional<double> rectHeight;
184         std::optional<double> bgrScaleX;
185         std::optional<double> bgrScaleY;
186         std::optional<double> bgrRectWidth;
187         std::optional<double> bgrRectHeight;
188         std::optional<int32_t> layoutIndex;
189         std::optional<int32_t> coverAlgoVer;
190         std::optional<int32_t> coverServiceVer;
191 
192         std::optional<int32_t> status;
193 
ToStringHighlightCoverInfo194         std::string ToString() const
195         {
196             std::stringstream outputStr;
197             outputStr << "HighlightCoverInfo[" << "highlightIdNew: ";
198             if (highlightIdNew.has_value()) { outputStr << highlightIdNew.value(); }
199             outputStr << ", ratio: ";
200             if (ratio.has_value()) { outputStr << ratio.value(); }
201             outputStr << "]";
202             return outputStr.str();
203         }
204     };
205 
206     struct HighlightPlayInfo {
207         std::optional<int32_t> highlightIdNew;
208         std::optional<int32_t> playId;
209         std::optional<std::string> music;
210         std::optional<int32_t> filter;
211         std::optional<std::string> pInfo;
212         std::optional<int32_t> isChosen;
213         std::optional<int32_t> pInfoVer;
214         std::optional<std::string> hAlgoVer;
215         std::optional<std::string> cameraAlgoVer;
216         std::optional<std::string> transAlgoVer;
217         std::optional<std::string> playServiceVer;
218         std::optional<int32_t> status;
219 
ToStringHighlightPlayInfo220         std::string ToString() const
221         {
222             std::stringstream outputStr;
223             outputStr << "HighlightPlayInfo[" << "highlightIdNew: ";
224             if (highlightIdNew.has_value()) { outputStr << highlightIdNew.value(); }
225             outputStr << ", playId: ";
226             if (playId.has_value()) { outputStr << playId.value(); }
227             outputStr << "]";
228             return outputStr.str();
229         }
230     };
231 
232     void Preprocess();
233     void RestoreAlbums();
234     void RestoreMaps();
235     int32_t GetTotalNumberOfMaps();
236     void RestoreMapsBatch();
237     void UpdateAlbums();
238 
239     void GetAnalysisAlbumInfos();
240     void GetAnalysisRowInfo(AnalysisAlbumInfo &info, std::shared_ptr<NativeRdb::ResultSet> resultSet);
241     void UpdateAlbumCoverUri(AnalysisAlbumInfo &info);
242     void InsertIntoAnalysisAlbum();
243     void GetAnalysisInsertValue(NativeRdb::ValuesBucket &value, const AnalysisAlbumInfo &info);
244     void UpdateHighlightStatusMap(int32_t highlightStatus, int32_t highlightId,
245         std::unordered_map<int32_t, std::vector<NativeRdb::ValueObject>> &highlightStatusMap);
246     void UpdateHighlightStatusInDatabase(
247         const std::unordered_map<int32_t, std::vector<NativeRdb::ValueObject>> &highlightStatusMap);
248     int32_t GetMaxAlbumId(const std::string &tableName, const std::string &idName);
249     void UpdateMapInsertValues(std::vector<NativeRdb::ValuesBucket> &values);
250     void UpdateMapInsertValuesByAlbumId(std::vector<NativeRdb::ValuesBucket> &values,
251         std::shared_ptr<NativeRdb::ResultSet> resultSet);
252     void InsertAnalysisPhotoMap(std::vector<NativeRdb::ValuesBucket> &values);
253     int32_t BatchInsertWithRetry(const std::string &tableName, const std::vector<NativeRdb::ValuesBucket> &values,
254         int64_t &rowNum);
255     NativeRdb::ValuesBucket GetMapInsertValue(int32_t albumId, int32_t fileId, std::optional<int32_t> &order);
256     void GetHighlightAlbumInfos();
257     void GetHighlightNewAlbumId(HighlightAlbumInfo &info);
258     void GetHighlightRowInfo(HighlightAlbumInfo &info, std::shared_ptr<NativeRdb::ResultSet> resultSet);
259     void InsertIntoHighlightAlbum();
260     void GetHighlightInsertValue(NativeRdb::ValuesBucket &value, const HighlightAlbumInfo &info);
261     void PutTempHighlightStatus(NativeRdb::ValuesBucket &value, const HighlightAlbumInfo &info);
262     void MoveHighlightCovers();
263     void MoveHighlightWordart(const AnalysisAlbumInfo &info, const std::string &srcDir);
264     void MoveHighlightGround(const AnalysisAlbumInfo &info, const std::string &srcDir);
265     int32_t MoveHighlightMusic(const std::string &srcDir, const std::string &dstDir);
266     void GetHighlightCoverInfos();
267     void GetCoverRowInfo(HighlightCoverInfo &info, std::shared_ptr<NativeRdb::ResultSet> resultSet);
268     void GetCoverGroundSourceInfo(HighlightCoverInfo &info, std::shared_ptr<NativeRdb::ResultSet> resultSet);
269     void InsertIntoHighlightCoverInfo();
270     void GetCoverInsertValue(NativeRdb::ValuesBucket &value, const HighlightCoverInfo &info);
271     void GetHighlightPlayInfos();
272     void GetPlayRowInfo(HighlightPlayInfo &info, std::shared_ptr<NativeRdb::ResultSet> resultSet);
273     void InsertIntoHighlightPlayInfo();
274     void GetPlayInsertValue(NativeRdb::ValuesBucket &value, const HighlightPlayInfo &info);
275     std::unordered_set<std::string> GetCommonColumns(const std::string &tableName);
276     void ReportRestoreTaskOfTotal();
277     void ReportRestoreTaskOfAlbumStats();
278     void ReportRestoreTaskOfAlbumInfo();
279     bool IsMapColumnOrderExist();
280     void HighlightDeduplicate(const HighlightAlbumInfo &info);
281     std::vector<NativeRdb::ValueObject> GetHighlightDuplicateIds(const HighlightAlbumInfo &info,
282         std::string &duplicateAlbumName, std::unordered_set<int32_t> &duplicateAnalysisAlbumIdSet);
283     void UpdateHighlightDuplicateRows(const std::vector<NativeRdb::ValueObject> &changeIds,
284         const std::string &duplicateAlbumName);
285     void DeleteAnalysisDuplicateRows(const std::unordered_set<int32_t> &duplicateAnalysisAlbumIdSet,
286         const std::string &duplicateAlbumName);
287 
288 private:
289     int32_t sceneCode_{-1};
290     std::string taskId_;
291     std::string coverPath_;
292     std::string musicDir_;
293     std::string garblePath_;
294     // old media_liabrary.db
295     std::shared_ptr<NativeRdb::RdbStore> mediaRdb_;
296     // new media_liabrary.db
297     std::shared_ptr<NativeRdb::RdbStore> mediaLibraryRdb_;
298     std::unordered_map<int32_t, PhotoInfo> photoInfoMap_;
299     std::unordered_map<std::string, std::unordered_set<std::string>> intersectionMap_;
300 
301     std::vector<AnalysisAlbumInfo> analysisInfos_;
302     std::vector<HighlightAlbumInfo> highlightInfos_;
303     std::vector<HighlightCoverInfo> coverInfos_;
304     std::vector<HighlightPlayInfo> playInfos_;
305 
306     std::mutex counterMutex_;
307     std::unordered_map<std::string, int32_t> albumPhotoCounter_;
308     bool isMapOrder_{false};
309     bool isCloneHighlight_{false};
310     bool isHighlightDirExist_{false};
311     int32_t maxIdOfAlbum_{0};
312     int32_t maxIdOfHighlight_{0};
313     int32_t lastIdOfMap_{0};
314     int64_t albumSuccessCnt_{0};
315     int64_t albumDuplicateCnt_{0};
316     int64_t albumFailedCnt_{0};
317     int64_t highlightSuccessCnt_{0};
318     int64_t highlightDuplicateCnt_{0};
319     int64_t highlightFailedCnt_{0};
320     int64_t mapSuccessCnt_{0};
321     int64_t mapFailedCnt_{0};
322     int64_t coverInfoSuccessCnt_{0};
323     int64_t coverInfoFailedCnt_{0};
324     int64_t playInfoSuccessCnt_{0};
325     int64_t playInfoFailedCnt_{0};
326     int64_t restoreTimeCost_{0};
327 };
328 
329 template<typename T>
PutIfPresent(NativeRdb::ValuesBucket & values,const std::string & columnName,const std::optional<T> & optionalValue)330 void CloneRestoreHighlight::PutIfPresent(NativeRdb::ValuesBucket& values, const std::string& columnName,
331     const std::optional<T>& optionalValue)
332 {
333     if (optionalValue.has_value()) {
334         if constexpr (std::is_same_v<std::decay_t<T>, int32_t>) {
335             values.PutInt(columnName, optionalValue.value());
336         } else if constexpr (std::is_same_v<std::decay_t<T>, int64_t>) {
337             values.PutLong(columnName, optionalValue.value());
338         } else if constexpr (std::is_same_v<std::decay_t<T>, std::string>) {
339             values.PutString(columnName, optionalValue.value());
340         } else if constexpr (std::is_same_v<std::decay_t<T>, double>) {
341             values.PutDouble(columnName, optionalValue.value());
342         }
343     }
344 }
345 
346 template<typename T>
PutIfInIntersection(NativeRdb::ValuesBucket & values,const std::string & columnName,const std::optional<T> & optionalValue,const std::unordered_set<std::string> & intersection)347 void CloneRestoreHighlight::PutIfInIntersection(NativeRdb::ValuesBucket& values, const std::string& columnName,
348     const std::optional<T>& optionalValue, const std::unordered_set<std::string> &intersection)
349 {
350     if (intersection.count(columnName) > 0) {
351         PutIfPresent<T>(values, columnName, optionalValue);
352         return;
353     }
354 }
355 
356 template<typename T>
GetIfInIntersection(const std::string & columnName,std::optional<T> & optionalValue,const std::unordered_set<std::string> & intersection,std::shared_ptr<NativeRdb::ResultSet> resultSet)357 void CloneRestoreHighlight::GetIfInIntersection(const std::string &columnName, std::optional<T> &optionalValue,
358     const std::unordered_set<std::string> &intersection, std::shared_ptr<NativeRdb::ResultSet> resultSet)
359 {
360     if (intersection.count(columnName) > 0) {
361         optionalValue = BackupDatabaseUtils::GetOptionalValue<T>(resultSet, columnName);
362         return;
363     }
364 }
365 } // namespace OHOS::Media
366 #endif // CLONE_RESTORE_HIGHLIGHT_H