• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023-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 #define MLOG_TAG "MediaLibraryUpgradeRestore"
17 
18 #include "upgrade_restore.h"
19 
20 #include "backup_const_column.h"
21 #include "backup_const_map.h"
22 #include "backup_database_utils.h"
23 #include "backup_file_utils.h"
24 #include "backup_log_utils.h"
25 #include "database_report.h"
26 #include "ffrt.h"
27 #include "ffrt_inner.h"
28 #include "gallery_db_upgrade.h"
29 #include "media_column.h"
30 #include "media_file_utils.h"
31 #include "media_log.h"
32 #include "medialibrary_data_manager.h"
33 #include "medialibrary_errno.h"
34 #include "medialibrary_rdb_transaction.h"
35 #include "photo_album_restore.h"
36 #include "photos_dao.h"
37 #include "photos_restore.h"
38 #include "result_set_utils.h"
39 #include "upgrade_restore_task_report.h"
40 #include "userfile_manager_types.h"
41 #include "vision_album_column.h"
42 #include "vision_column.h"
43 #include "vision_face_tag_column.h"
44 #include "vision_image_face_column.h"
45 #include "vision_photo_map_column.h"
46 
47 #ifdef CLOUD_SYNC_MANAGER
48 #include "cloud_sync_manager.h"
49 #endif
50 
51 namespace OHOS {
52 namespace Media {
53 constexpr int32_t PHOTOS_TABLE_ALBUM_ID = -1;
54 constexpr int32_t BASE_TEN_NUMBER = 10;
55 constexpr int32_t SEVEN_NUMBER = 7;
56 constexpr int32_t SD_PREFIX_LEVEL = 3;
57 const std::string DB_INTEGRITY_CHECK = "ok";
58 
UpgradeRestore(const std::string & galleryAppName,const std::string & mediaAppName,int32_t sceneCode)59 UpgradeRestore::UpgradeRestore(const std::string &galleryAppName, const std::string &mediaAppName, int32_t sceneCode)
60 {
61     galleryAppName_ = galleryAppName;
62     mediaAppName_ = mediaAppName;
63     sceneCode_ = sceneCode;
64     audioAppName_ = "Audio";
65     MEDIA_INFO_LOG("Use ffrt without escape");
66 }
67 
UpgradeRestore(const std::string & galleryAppName,const std::string & mediaAppName,int32_t sceneCode,const std::string & dualDirName)68 UpgradeRestore::UpgradeRestore(const std::string &galleryAppName, const std::string &mediaAppName, int32_t sceneCode,
69     const std::string &dualDirName)
70 {
71     galleryAppName_ = galleryAppName;
72     mediaAppName_ = mediaAppName;
73     sceneCode_ = sceneCode;
74     dualDirName_ = dualDirName;
75     MEDIA_INFO_LOG("Use ffrt without escape");
76 }
77 
Init(const std::string & backupRetoreDir,const std::string & upgradeFilePath,bool isUpgrade)78 int32_t UpgradeRestore::Init(const std::string &backupRetoreDir, const std::string &upgradeFilePath, bool isUpgrade)
79 {
80     appDataPath_ = backupRetoreDir;
81     string photosPreferencesPath;
82     if (sceneCode_ == DUAL_FRAME_CLONE_RESTORE_ID) {
83         filePath_ = backupRetoreDir;
84         galleryDbPath_ = backupRetoreDir + "/" + GALLERY_DB_NAME;
85         audioDbPath_ = backupRetoreDir + INTERNAL_PREFIX + "/0/" + AUDIO_DB_NAME;
86         photosPreferencesPath = backupRetoreDir + "/" + galleryAppName_ + "_preferences.xml";
87         // gallery db may include both internal & external, set flag to differentiate, default false
88         shouldIncludeSd_ = BackupFileUtils::ShouldIncludeSd(filePath_);
89         backupDatabaseHelper_.Init(sceneCode_, shouldIncludeSd_, filePath_);
90         SetParameterForClone();
91 #ifdef CLOUD_SYNC_MANAGER
92         FileManagement::CloudSync::CloudSyncManager::GetInstance().StopSync("com.ohos.medialibrary.medialibrarydata");
93 #endif
94     } else {
95         filePath_ = upgradeFilePath;
96         galleryDbPath_ = backupRetoreDir + "/" + galleryAppName_ + "/ce/databases/gallery.db";
97         externalDbPath_ = backupRetoreDir + "/" + mediaAppName_ + "/ce/databases/external.db";
98         photosPreferencesPath =
99             backupRetoreDir + "/" + galleryAppName_ + "/ce/shared_prefs/" + galleryAppName_ + "_preferences.xml";
100         shouldIncludeSd_ = false;
101         if (!MediaFileUtils::IsFileExists(externalDbPath_)) {
102             MEDIA_ERR_LOG("External db is not exist.");
103             return EXTERNAL_DB_NOT_EXIST;
104         }
105         int32_t externalErr = BackupDatabaseUtils::InitDb(externalRdb_, EXTERNAL_DB_NAME, externalDbPath_,
106             mediaAppName_, false);
107         if (externalRdb_ == nullptr) {
108             MEDIA_ERR_LOG("External init rdb fail, err = %{public}d", externalErr);
109             return E_FAIL;
110         }
111         backupDatabaseHelper_.AddDb(BackupDatabaseHelper::DbType::EXTERNAL, externalRdb_);
112         if (sceneCode_ == UPGRADE_RESTORE_ID) {
113             MediaLibraryDataManager::GetInstance()->ReCreateMediaDir();
114         }
115     }
116     MEDIA_INFO_LOG("Shoud include Sd: %{public}d", static_cast<int32_t>(shouldIncludeSd_));
117     return InitDbAndXml(photosPreferencesPath, isUpgrade);
118 }
119 
InitDbAndXml(std::string xmlPath,bool isUpgrade)120 int32_t UpgradeRestore::InitDbAndXml(std::string xmlPath, bool isUpgrade)
121 {
122     if (isUpgrade && BaseRestore::Init() != E_OK) {
123         return E_FAIL;
124     }
125     if (!MediaFileUtils::IsFileExists(galleryDbPath_)) {
126         MEDIA_ERR_LOG("Gallery media db is not exist.");
127     } else {
128         int32_t galleryErr = BackupDatabaseUtils::InitDb(galleryRdb_, GALLERY_DB_NAME, galleryDbPath_,
129             galleryAppName_, false);
130         if (galleryRdb_ == nullptr) {
131             MEDIA_ERR_LOG("Gallery init rdb fail, err = %{public}d", galleryErr);
132             return E_FAIL;
133         }
134     }
135 
136     if (!MediaFileUtils::IsFileExists(audioDbPath_)) {
137         MEDIA_ERR_LOG("audio mediaInfo db is not exist.");
138     } else {
139         int32_t audioErr = BackupDatabaseUtils::InitDb(audioRdb_, AUDIO_DB_NAME, audioDbPath_,
140             audioAppName_, false);
141         if (audioRdb_ == nullptr) {
142             MEDIA_ERR_LOG("audio init rdb fail, err = %{public}d", audioErr);
143             return E_FAIL;
144         }
145     }
146     ParseXml(xmlPath);
147     this->photoAlbumRestore_.OnStart(this->mediaLibraryRdb_, this->galleryRdb_);
148     this->photosRestore_.OnStart(this->mediaLibraryRdb_, this->galleryRdb_);
149     MEDIA_INFO_LOG("Init db succ.");
150     return E_OK;
151 }
152 
HasLowQualityImage()153 bool UpgradeRestore::HasLowQualityImage()
154 {
155     std::string sql = "SELECT count(1) AS count FROM gallery_media WHERE (local_media_id != -1) AND \
156         (storage_id IN (0, 65537)) AND relative_bucket_id NOT IN (SELECT DISTINCT relative_bucket_id FROM \
157         garbage_album WHERE type = 1) AND _size = 0 AND photo_quality = 0";
158     int count = BackupDatabaseUtils::QueryInt(galleryRdb_, sql, CUSTOM_COUNT);
159     MEDIA_INFO_LOG("HasLowQualityImage count:%{public}d", count);
160     hasLowQualityImage_ = (count > 0);
161     return hasLowQualityImage_;
162 }
163 
StringToInt(const std::string & str)164 int UpgradeRestore::StringToInt(const std::string& str)
165 {
166     if (str.empty()) {
167         return 0;
168     }
169     int base = 0;
170     size_t num = 0;
171     int sign = 1; // positive one
172     size_t len = str.length();
173     while (num < len && str[num] == ' ') {
174         num++;
175     }
176     if (num < len && (str[num] == '-' || str[num] == '+')) {
177         sign = (str[num++] == '-') ? -1 : 1;
178     }
179     while (num < len && std::isdigit(str[num])) {
180         if (base > INT_MAX / BASE_TEN_NUMBER || (base == INT_MAX / BASE_TEN_NUMBER && str[num] - '0' > SEVEN_NUMBER)) {
181             MEDIA_INFO_LOG("The number is INT_MAX");
182             return 0;
183         }
184         base = BASE_TEN_NUMBER * base + (str[num++] - '0');
185     }
186     if (num < len && !std::isdigit(str[num])) {
187         MEDIA_INFO_LOG("Not digit");
188         return 0;
189     }
190     return base * sign;
191 }
192 
HandleXmlNode(xmlNodePtr cur)193 int32_t UpgradeRestore::HandleXmlNode(xmlNodePtr cur)
194 {
195     if (cur->type == XML_ELEMENT_NODE) {
196         xmlChar* name = xmlGetProp(cur, BAD_CAST"name");
197         if (name != nullptr && xmlStrcmp(name, BAD_CAST"filter_selected_size") == 0) {
198             xmlChar* value = xmlGetProp(cur, BAD_CAST"value");
199             if (value != nullptr) {
200                 fileMinSize_ = StringToInt((const char *)(value));
201                 xmlFree(value);
202                 return E_SUCCESS;
203             }
204             xmlFree(name);
205             return E_ERR;
206         }
207         xmlFree(name);
208     }
209     return E_ERR;
210 }
211 
ParseXml(const std::string & path)212 int32_t UpgradeRestore::ParseXml(const std::string &path)
213 {
214     std::unique_ptr<xmlDoc, decltype(&xmlFreeDoc)> docPtr(
215         xmlReadFile(path.c_str(), nullptr, XML_PARSE_NOBLANKS), xmlFreeDoc);
216     if (docPtr == nullptr) {
217         MEDIA_ERR_LOG("failed to read xml file");
218         return E_ERR;
219     }
220     auto root = xmlDocGetRootElement(docPtr.get());
221     if (root == nullptr) {
222         MEDIA_ERR_LOG("failed to read root node");
223         return E_ERR;
224     }
225     for (xmlNodePtr cur = root->children; cur != NULL; cur = cur->next) {
226         if (HandleXmlNode(cur) == E_SUCCESS) {
227             return E_SUCCESS;
228         }
229     }
230     return E_ERR;
231 }
232 
RestoreAudio(void)233 void UpgradeRestore::RestoreAudio(void)
234 {
235     if (sceneCode_ == DUAL_FRAME_CLONE_RESTORE_ID) {
236         if (!MediaFileUtils::IsFileExists(RESTORE_MUSIC_LOCAL_DIR)) {
237             MEDIA_INFO_LOG("music dir is not exists!!!");
238             MediaFileUtils::CreateDirectory(RESTORE_MUSIC_LOCAL_DIR);
239         }
240         RestoreAudioFromFile();
241     }
242     (void)NativeRdb::RdbHelper::DeleteRdbStore(externalDbPath_);
243     (void)NativeRdb::RdbHelper::DeleteRdbStore(audioDbPath_);
244 }
245 
RestoreAudioFromFile()246 void UpgradeRestore::RestoreAudioFromFile()
247 {
248     MEDIA_INFO_LOG("start restore audio from audio_MediaInfo0");
249     int32_t totalNumber = BackupDatabaseUtils::QueryInt(audioRdb_, QUERY_DUAL_CLONE_AUDIO_COUNT, CUSTOM_COUNT);
250     MEDIA_INFO_LOG("totalNumber = %{public}d", totalNumber);
251     audioTotalNumber_ += static_cast<uint64_t>(totalNumber);
252     MEDIA_INFO_LOG("onProcess Update audioTotalNumber_: %{public}lld", (long long)audioTotalNumber_);
253     for (int32_t offset = 0; offset < totalNumber; offset += QUERY_COUNT) {
254         ffrt::submit([this, offset]() { RestoreAudioBatch(offset); }, { &offset }, {},
255             ffrt::task_attr().qos(static_cast<int32_t>(ffrt::qos_utility)));
256     }
257     ffrt::wait();
258 }
259 
RestoreAudioBatch(int32_t offset)260 void UpgradeRestore::RestoreAudioBatch(int32_t offset)
261 {
262     MEDIA_INFO_LOG("start restore audio from external, offset: %{public}d", offset);
263     std::vector<FileInfo> infos = QueryAudioFileInfosFromAudio(offset);
264     InsertAudio(sceneCode_, infos);
265 }
266 
QueryAudioFileInfosFromAudio(int32_t offset)267 std::vector<FileInfo> UpgradeRestore::QueryAudioFileInfosFromAudio(int32_t offset)
268 {
269     std::vector<FileInfo> result;
270     result.reserve(QUERY_COUNT);
271     if (audioRdb_ == nullptr) {
272         MEDIA_ERR_LOG("audioRdb_ is nullptr, Maybe init failed.");
273         return result;
274     }
275     std::string queryAllAudioByCount = QUERY_ALL_AUDIOS_FROM_AUDIODB + " limit " + std::to_string(offset) + ", " +
276         std::to_string(QUERY_COUNT);
277     auto resultSet = audioRdb_->QuerySql(queryAllAudioByCount);
278     if (resultSet == nullptr) {
279         MEDIA_ERR_LOG("Query resultSql is null.");
280         return result;
281     }
282     while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
283         FileInfo tmpInfo;
284         if (ParseResultSetFromAudioDb(resultSet, tmpInfo)) {
285             result.emplace_back(tmpInfo);
286         }
287     }
288     return result;
289 }
290 
ParseResultSetFromAudioDb(const std::shared_ptr<NativeRdb::ResultSet> & resultSet,FileInfo & info)291 bool UpgradeRestore::ParseResultSetFromAudioDb(const std::shared_ptr<NativeRdb::ResultSet> &resultSet, FileInfo &info)
292 {
293     info.fileType = MediaType::MEDIA_TYPE_AUDIO;
294     info.oldPath = GetStringVal(AUDIO_DATA, resultSet);
295     if (!ConvertPathToRealPath(info.oldPath, filePath_, info.filePath, info.relativePath)) {
296         MEDIA_ERR_LOG("Invalid path: %{public}s.",
297             BackupFileUtils::GarbleFilePath(info.oldPath, DEFAULT_RESTORE_ID).c_str());
298         return false;
299     }
300     info.showDateToken = GetInt64Val(EXTERNAL_DATE_MODIFIED, resultSet);
301     info.dateModified = GetInt64Val(EXTERNAL_DATE_MODIFIED, resultSet) * MSEC_TO_SEC;
302     info.displayName = BackupFileUtils::GetFileNameFromPath(info.filePath);
303     info.title = BackupFileUtils::GetFileTitle(info.displayName);
304     info.packageName = BackupFileUtils::GetFileFolderFromPath(info.relativePath, false);
305     info.isFavorite = 0;
306     info.recycledTime = 0;
307     return true;
308 }
309 
RestorePhoto()310 void UpgradeRestore::RestorePhoto()
311 {
312     AnalyzeSource();
313 
314     std::string dbIntegrityCheck = CheckGalleryDbIntegrity();
315     if (dbIntegrityCheck == DB_INTEGRITY_CHECK) {
316         // upgrade gallery.db
317         DataTransfer::GalleryDbUpgrade().OnUpgrade(this->galleryRdb_);
318         AnalyzeGallerySource();
319         InitGarbageAlbum();
320         // restore PhotoAlbum
321         this->photoAlbumRestore_.Restore();
322         RestoreFromGalleryPortraitAlbum();
323         // restore Photos
324         RestoreFromGallery();
325     } else {
326         maxId_ = 0;
327         SetErrorCode(RestoreError::GALLERY_DATABASE_CORRUPTION);
328         ErrorInfo errorInfo(RestoreError::GALLERY_DATABASE_CORRUPTION, 0, "", dbIntegrityCheck);
329         UpgradeRestoreTaskReport().SetSceneCode(this->sceneCode_).SetTaskId(this->taskId_).ReportError(errorInfo);
330     }
331     StopParameterForClone(sceneCode_);
332     MEDIA_INFO_LOG("migrate from gallery number: %{public}lld, file number: %{public}lld",
333         (long long) migrateDatabaseNumber_, (long long) migrateFileNumber_);
334     if (sceneCode_ == UPGRADE_RESTORE_ID) {
335         RestoreFromExternal(true);
336         MEDIA_INFO_LOG("migrate from camera number: %{public}lld, file number: %{public}lld",
337             (long long) migrateDatabaseNumber_, (long long) migrateFileNumber_);
338         RestoreFromExternal(false);
339         MEDIA_INFO_LOG("migrate from others number: %{public}lld, file number: %{public}lld",
340             (long long) migrateDatabaseNumber_, (long long) migrateFileNumber_);
341     }
342 
343     if (sceneCode_ == UPGRADE_RESTORE_ID) {
344         UpdateFaceAnalysisStatus();
345     } else {
346         UpdateDualCloneFaceAnalysisStatus();
347     }
348 
349     ReportPortraitStat(sceneCode_);
350     (void)NativeRdb::RdbHelper::DeleteRdbStore(galleryDbPath_);
351 }
352 
AnalyzeSource()353 void UpgradeRestore::AnalyzeSource()
354 {
355     MEDIA_INFO_LOG("start AnalyzeSource.");
356     DatabaseReport()
357         .SetSceneCode(this->sceneCode_)
358         .SetTaskId(this->taskId_)
359         .ReportExternal(this->externalRdb_,  this->galleryRdb_)
360         .ReportMedia(this->mediaLibraryRdb_, DatabaseReport::PERIOD_BEFORE);
361     MEDIA_INFO_LOG("end AnalyzeSource.");
362 }
363 
AnalyzeGalleryErrorSource()364 void UpgradeRestore::AnalyzeGalleryErrorSource()
365 {
366     if (galleryRdb_ == nullptr) {
367         MEDIA_ERR_LOG("galleryRdb_ is nullptr, Maybe init failed.");
368         return;
369     }
370     AnalyzeGalleryDuplicateData();
371 }
372 
AnalyzeGalleryDuplicateData()373 void UpgradeRestore::AnalyzeGalleryDuplicateData()
374 {
375     int32_t count = 0;
376     int32_t total = 0;
377     BackupDatabaseUtils::QueryGalleryDuplicateDataCount(galleryRdb_, count, total);
378     MEDIA_INFO_LOG("Duplicate data count: %{public}d, total: %{public}d", count, total);
379     this->photosRestore_.GetDuplicateData(count);
380 }
381 
AnalyzeGallerySource()382 void UpgradeRestore::AnalyzeGallerySource()
383 {
384     MEDIA_INFO_LOG("start AnalyzeGallerySource.");
385     AnalyzeGalleryErrorSource();
386     DatabaseReport()
387         .SetSceneCode(this->sceneCode_)
388         .SetTaskId(this->taskId_)
389         .ReportGallery(this->galleryRdb_, this->shouldIncludeSd_);
390     MEDIA_INFO_LOG("end AnalyzeGallerySource.");
391 }
392 
InitGarbageAlbum()393 void UpgradeRestore::InitGarbageAlbum()
394 {
395     BackupDatabaseUtils::InitGarbageAlbum(galleryRdb_, cacheSet_, nickMap_);
396 }
397 
RestoreFromGallery()398 void UpgradeRestore::RestoreFromGallery()
399 {
400     this->photosRestore_.LoadPhotoAlbums();
401     HasLowQualityImage();
402     int32_t totalNumber = this->photosRestore_.GetGalleryMediaCount(this->shouldIncludeSd_, this->hasLowQualityImage_);
403     MEDIA_INFO_LOG("totalNumber = %{public}d", totalNumber);
404     totalNumber_ += static_cast<uint64_t>(totalNumber);
405     MEDIA_INFO_LOG("onProcess Update totalNumber_: %{public}lld", (long long)totalNumber_);
406     ffrt_set_cpu_worker_max_num(ffrt::qos_utility, MAX_THREAD_NUM);
407     needReportFailed_ = false;
408     for (int32_t offset = 0; offset < totalNumber; offset += QUERY_COUNT) {
409         ffrt::submit([this, offset]() { RestoreBatch(offset); }, { &offset }, {},
410             ffrt::task_attr().qos(static_cast<int32_t>(ffrt::qos_utility)));
411     }
412     ffrt::wait();
413     size_t vectorLen = galleryFailedOffsets.size();
414     needReportFailed_ = true;
415     for (size_t offset = 0; offset < vectorLen; offset++) {
416         RestoreBatch(galleryFailedOffsets[offset]);
417     }
418 }
419 
RestoreBatch(int32_t offset)420 void UpgradeRestore::RestoreBatch(int32_t offset)
421 {
422     MEDIA_INFO_LOG("start restore from gallery, offset: %{public}d", offset);
423     std::vector<FileInfo> infos = QueryFileInfos(offset);
424     if (InsertPhoto(sceneCode_, infos, SourceType::GALLERY) != E_OK) {
425         galleryFailedOffsets.push_back(offset);
426     }
427     auto fileIdPairs = BackupDatabaseUtils::CollectFileIdPairs(infos);
428     BackupDatabaseUtils::UpdateAnalysisTotalTblStatus(mediaLibraryRdb_, fileIdPairs);
429 }
430 
RestoreFromExternal(bool isCamera)431 void UpgradeRestore::RestoreFromExternal(bool isCamera)
432 {
433     MEDIA_INFO_LOG("start restore from %{public}s", (isCamera ? "camera" : "others"));
434     int32_t maxId = BackupDatabaseUtils::QueryInt(galleryRdb_, isCamera ?
435         QUERY_MAX_ID_CAMERA_SCREENSHOT : QUERY_MAX_ID_OTHERS, CUSTOM_MAX_ID);
436     maxId = (maxId_ == -1) ? maxId : maxId_;
437     int32_t type = isCamera ? SourceType::EXTERNAL_CAMERA : SourceType::EXTERNAL_OTHERS;
438     int32_t totalNumber = QueryNotSyncTotalNumber(maxId, isCamera);
439     MEDIA_INFO_LOG("totalNumber = %{public}d, maxId = %{public}d", totalNumber, maxId);
440     totalNumber_ += static_cast<uint64_t>(totalNumber);
441     MEDIA_INFO_LOG("onProcess Update totalNumber_: %{public}lld", (long long)totalNumber_);
442     ffrt_set_cpu_worker_max_num(ffrt::qos_utility, MAX_THREAD_NUM);
443     needReportFailed_ = false;
444     for (int32_t offset = 0; offset < totalNumber; offset += QUERY_COUNT) {
445         ffrt::submit([this, offset, maxId, isCamera, type]() {
446                 RestoreExternalBatch(offset, maxId, isCamera, type);
447             }, { &offset }, {}, ffrt::task_attr().qos(static_cast<int32_t>(ffrt::qos_utility)));
448     }
449     ffrt::wait();
450     size_t vectorLen = externalFailedOffsets.size();
451     needReportFailed_ = true;
452     for (size_t offset = 0; offset < vectorLen; offset++) {
453         RestoreExternalBatch(externalFailedOffsets[offset], maxId, isCamera, type);
454     }
455 }
456 
RestoreExternalBatch(int32_t offset,int32_t maxId,bool isCamera,int32_t type)457 void UpgradeRestore::RestoreExternalBatch(int32_t offset, int32_t maxId, bool isCamera, int32_t type)
458 {
459     MEDIA_INFO_LOG("start restore from external, offset: %{public}d", offset);
460     std::vector<FileInfo> infos = QueryFileInfosFromExternal(offset, maxId, isCamera);
461     if (InsertPhoto(sceneCode_, infos, type) != E_OK) {
462         externalFailedOffsets.push_back(offset);
463     }
464 }
465 
QueryNotSyncTotalNumber(int32_t maxId,bool isCamera)466 int32_t UpgradeRestore::QueryNotSyncTotalNumber(int32_t maxId, bool isCamera)
467 {
468     std::string queryCamera = isCamera ? IN_CAMERA : NOT_IN_CAMERA;
469     std::string queryNotSyncByCount = QUERY_COUNT_FROM_FILES + queryCamera + " AND " +
470         COMPARE_ID + std::to_string(maxId) + " AND " + QUERY_NOT_SYNC;
471     return BackupDatabaseUtils::QueryInt(externalRdb_, queryNotSyncByCount, CUSTOM_COUNT);
472 }
473 
HandleRestData(void)474 void UpgradeRestore::HandleRestData(void)
475 {
476     MEDIA_INFO_LOG("Start to handle rest data in native.");
477     RestoreThumbnail();
478 
479     std::string photoData = appDataPath_ + "/" + galleryAppName_;
480     std::string mediaData = appDataPath_ + "/" + mediaAppName_;
481     if (MediaFileUtils::IsFileExists(photoData)) {
482         MEDIA_DEBUG_LOG("Start to delete photo data.");
483         MediaFileUtils::DeleteDir(photoData);
484     }
485     if (MediaFileUtils::IsFileExists(mediaData)) {
486         MEDIA_DEBUG_LOG("Start to delete media data.");
487         MediaFileUtils::DeleteDir(mediaData);
488     }
489     BackupFileUtils::DeleteSdDatabase(filePath_);
490 }
491 
QueryFileInfos(int32_t offset)492 std::vector<FileInfo> UpgradeRestore::QueryFileInfos(int32_t offset)
493 {
494     std::vector<FileInfo> result;
495     result.reserve(QUERY_COUNT);
496     if (galleryRdb_ == nullptr) {
497         MEDIA_ERR_LOG("galleryRdb_ is nullptr, Maybe init failed.");
498         return result;
499     }
500     auto resultSet = this->photosRestore_.GetGalleryMedia(
501         offset, QUERY_COUNT, this->shouldIncludeSd_, this->hasLowQualityImage_);
502     if (resultSet == nullptr) {
503         MEDIA_ERR_LOG("Query resultSql is null.");
504         return result;
505     }
506     while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
507         FileInfo tmpInfo;
508         if (ParseResultSetFromGallery(resultSet, tmpInfo)) {
509             result.emplace_back(tmpInfo);
510         }
511     }
512     return result;
513 }
514 
ParseResultSetForAudio(const std::shared_ptr<NativeRdb::ResultSet> & resultSet,FileInfo & info)515 bool UpgradeRestore::ParseResultSetForAudio(const std::shared_ptr<NativeRdb::ResultSet> &resultSet, FileInfo &info)
516 {
517     info.oldPath = GetStringVal(EXTERNAL_FILE_DATA, resultSet);
518     int32_t mediaType = GetInt32Val(EXTERNAL_MEDIA_TYPE, resultSet);
519     if (mediaType != DUAL_MEDIA_TYPE::AUDIO_TYPE) {
520         MEDIA_ERR_LOG("Invalid media type: %{public}d, path: %{public}s", mediaType,
521             BackupFileUtils::GarbleFilePath(info.oldPath, DEFAULT_RESTORE_ID).c_str());
522         return false;
523     }
524     info.fileType = MediaType::MEDIA_TYPE_AUDIO;
525     if (!BaseRestore::ConvertPathToRealPath(info.oldPath, filePath_, info.filePath, info.relativePath)) {
526         MEDIA_ERR_LOG("Invalid path: %{public}s.",
527             BackupFileUtils::GarbleFilePath(info.oldPath, DEFAULT_RESTORE_ID).c_str());
528         return false;
529     }
530     info.displayName = GetStringVal(EXTERNAL_DISPLAY_NAME, resultSet);
531     info.title = GetStringVal(EXTERNAL_TITLE, resultSet);
532     info.fileSize = GetInt64Val(EXTERNAL_FILE_SIZE, resultSet);
533     if (info.fileSize < GARBAGE_PHOTO_SIZE) {
534         MEDIA_WARN_LOG("maybe garbage path = %{public}s.",
535             BackupFileUtils::GarbleFilePath(info.oldPath, DEFAULT_RESTORE_ID).c_str());
536     }
537     info.duration = GetInt64Val(GALLERY_DURATION, resultSet);
538     info.isFavorite = GetInt32Val(EXTERNAL_IS_FAVORITE, resultSet);
539     info.dateModified = GetInt64Val(EXTERNAL_DATE_MODIFIED, resultSet) * MSEC_TO_SEC;
540     return true;
541 }
542 
QueryFileInfosFromExternal(int32_t offset,int32_t maxId,bool isCamera)543 std::vector<FileInfo> UpgradeRestore::QueryFileInfosFromExternal(int32_t offset, int32_t maxId, bool isCamera)
544 {
545     std::vector<FileInfo> result;
546     result.reserve(QUERY_COUNT);
547     if (externalRdb_ == nullptr) {
548         MEDIA_ERR_LOG("Pointer rdb_ is nullptr, Maybe init failed.");
549         return result;
550     }
551     std::string queryCamera = isCamera ? IN_CAMERA : NOT_IN_CAMERA;
552     std::string queryFilesByCount = QUERY_FILE_COLUMN + queryCamera + " AND " +
553         COMPARE_ID + std::to_string(maxId) + " AND " + QUERY_NOT_SYNC + " limit " + std::to_string(offset) + ", " +
554         std::to_string(QUERY_COUNT);
555     auto resultSet = externalRdb_->QuerySql(queryFilesByCount);
556     if (resultSet == nullptr) {
557         MEDIA_ERR_LOG("Query resultSql is null.");
558         return result;
559     }
560     while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
561         FileInfo tmpInfo;
562         if (ParseResultSetFromExternal(resultSet, tmpInfo)) {
563             std::string findPath = tmpInfo.relativePath;
564             bool isValid = IsValidDir(findPath);
565             if (isValid) {
566                 result.emplace_back(tmpInfo);
567             }
568         }
569     }
570     return result;
571 }
572 
IsValidDir(const string & path)573 bool UpgradeRestore::IsValidDir(const string &path)
574 {
575     bool isValid = true;
576     for (auto &cacheDir : cacheSet_) {
577         if (path.find(cacheDir) == 0) {
578             isValid = false;
579             break;
580         }
581     }
582     return isValid;
583 }
ParseResultSet(const std::shared_ptr<NativeRdb::ResultSet> & resultSet,FileInfo & info,string dbName)584 bool UpgradeRestore::ParseResultSet(const std::shared_ptr<NativeRdb::ResultSet> &resultSet, FileInfo &info,
585     string dbName)
586 {
587     // only parse image and video
588     if (!IsBasicInfoValid(resultSet, info, dbName)) {
589         return false;
590     }
591     info.title = GetStringVal(GALLERY_TITLE, resultSet);
592     info.userComment = GetStringVal(GALLERY_DESCRIPTION, resultSet);
593     info.duration = GetInt64Val(GALLERY_DURATION, resultSet);
594     info.isFavorite = GetInt32Val(GALLERY_IS_FAVORITE, resultSet);
595     info.specialFileType = GetInt32Val(GALLERY_SPECIAL_FILE_TYPE, resultSet);
596     if (BackupFileUtils::IsLivePhoto(info) && !BackupFileUtils::ConvertToMovingPhoto(info)) {
597         ErrorInfo errorInfo(RestoreError::MOVING_PHOTO_CONVERT_FAILED, 1, "",
598             BackupLogUtils::FileInfoToString(sceneCode_, info));
599         UpgradeRestoreTaskReport().SetSceneCode(this->sceneCode_).SetTaskId(this->taskId_).ReportError(errorInfo);
600         return false;
601     }
602     info.height = GetInt64Val(GALLERY_HEIGHT, resultSet);
603     info.width = GetInt64Val(GALLERY_WIDTH, resultSet);
604     info.orientation = GetInt64Val(GALLERY_ORIENTATION, resultSet);
605     info.dateModified = GetInt64Val(EXTERNAL_DATE_MODIFIED, resultSet) * MSEC_TO_SEC;
606     info.firstUpdateTime = GetInt64Val(GALLERY_FIRST_UPDATE_TIME, resultSet);
607     info.dateTaken = GetInt64Val(GALLERY_DATE_TAKEN, resultSet);
608     info.detailTime = GetStringVal(GALLERY_DETAIL_TIME, resultSet);
609     info.userId = BackupFileUtils::GetUserId(info.oldPath);
610     return true;
611 }
612 
ParseResultSetFromGallery(const std::shared_ptr<NativeRdb::ResultSet> & resultSet,FileInfo & info)613 bool UpgradeRestore::ParseResultSetFromGallery(const std::shared_ptr<NativeRdb::ResultSet> &resultSet, FileInfo &info)
614 {
615     info.localMediaId = GetInt32Val(GALLERY_LOCAL_MEDIA_ID, resultSet);
616     info.hidden = (info.localMediaId == GALLERY_HIDDEN_ID) ? 1 : 0;
617     info.recycledTime = GetInt64Val(GALLERY_RECYCLED_TIME, resultSet);
618     info.showDateToken = GetInt64Val(GALLERY_SHOW_DATE_TOKEN, resultSet);
619     // fetch relative_bucket_id, recycleFlag, is_hw_burst, hash field to generate burst_key
620     info.relativeBucketId = GetStringVal(GALLERY_MEDIA_BUCKET_ID, resultSet);
621     info.recycleFlag = GetInt32Val(GALLERY_RECYCLE_FLAG, resultSet);
622     info.isBurst = GetInt32Val(GALLERY_IS_BURST, resultSet);
623     info.hashCode = GetStringVal(GALLERY_HASH, resultSet);
624     info.fileIdOld = GetInt32Val(GALLERY_ID, resultSet);
625     info.photoQuality = GetInt32Val(PhotoColumn::PHOTO_QUALITY, resultSet);
626 
627     bool isSuccess = ParseResultSet(resultSet, info, GALLERY_DB_NAME);
628     if (!isSuccess) {
629         MEDIA_ERR_LOG("ParseResultSetFromGallery fail");
630         return isSuccess;
631     }
632     info.burstKey = burstKeyGenerator_.FindBurstKey(info);
633     // Pre-Fetch: sourcePath, lPath
634     info.sourcePath = GetStringVal(GALLERY_MEDIA_SOURCE_PATH, resultSet);
635     info.lPath = GetStringVal(GALLERY_ALBUM_IPATH, resultSet);
636     // Find lPath, bundleName, packageName by sourcePath, lPath
637     info.lPath = this->photosRestore_.FindlPath(info);
638     info.bundleName = this->photosRestore_.FindBundleName(info);
639     info.packageName = this->photosRestore_.FindPackageName(info);
640     info.photoQuality = this->photosRestore_.FindPhotoQuality(info);
641     return isSuccess;
642 }
643 
ParseResultSetFromExternal(const std::shared_ptr<NativeRdb::ResultSet> & resultSet,FileInfo & info,int mediaType)644 bool UpgradeRestore::ParseResultSetFromExternal(const std::shared_ptr<NativeRdb::ResultSet> &resultSet, FileInfo &info,
645     int mediaType)
646 {
647     bool isSuccess;
648     if (mediaType == DUAL_MEDIA_TYPE::AUDIO_TYPE) {
649         isSuccess = ParseResultSetForAudio(resultSet, info);
650     } else {
651         isSuccess = ParseResultSet(resultSet, info, EXTERNAL_DB_NAME);
652     }
653     if (!isSuccess) {
654         MEDIA_ERR_LOG("ParseResultSetFromExternal fail");
655         return isSuccess;
656     }
657     info.showDateToken = GetInt64Val(EXTERNAL_DATE_TAKEN, resultSet);
658     info.dateTaken = GetInt64Val(EXTERNAL_DATE_TAKEN, resultSet);
659     info.sourcePath = GetStringVal(EXTERNAL_FILE_DATA, resultSet);
660     return isSuccess;
661 }
662 
GetInsertValue(const FileInfo & fileInfo,const std::string & newPath,int32_t sourceType)663 NativeRdb::ValuesBucket UpgradeRestore::GetInsertValue(const FileInfo &fileInfo, const std::string &newPath,
664     int32_t sourceType)
665 {
666     NativeRdb::ValuesBucket values;
667     values.PutString(MediaColumn::MEDIA_FILE_PATH, newPath);
668     values.PutString(MediaColumn::MEDIA_TITLE, fileInfo.title);
669     values.PutString(MediaColumn::MEDIA_NAME, fileInfo.displayName);
670     values.PutInt(MediaColumn::MEDIA_TYPE, fileInfo.fileType);
671     if (fileInfo.firstUpdateTime != 0) {
672         values.PutLong(MediaColumn::MEDIA_DATE_ADDED, fileInfo.firstUpdateTime);
673     } else if (fileInfo.dateTaken != 0) {
674         values.PutLong(MediaColumn::MEDIA_DATE_ADDED, fileInfo.dateTaken);
675     }
676     if (fileInfo.dateTaken != 0) {
677         values.PutLong(MediaColumn::MEDIA_DATE_TAKEN, fileInfo.dateTaken);
678     }
679     values.PutString(PhotoColumn::PHOTO_DETAIL_TIME, fileInfo.detailTime);
680     values.PutLong(MediaColumn::MEDIA_DURATION, fileInfo.duration);
681     values.PutInt(MediaColumn::MEDIA_IS_FAV, fileInfo.isFavorite);
682     if (fileInfo.isFavorite != 0) {
683         string fileName = fileInfo.displayName;
684         MEDIA_WARN_LOG("the file :%{public}s is favorite.", BackupFileUtils::GarbleFileName(fileName).c_str());
685     }
686     values.PutLong(MediaColumn::MEDIA_DATE_TRASHED, this->photosRestore_.FindDateTrashed(fileInfo));
687     values.PutInt(MediaColumn::MEDIA_HIDDEN, fileInfo.hidden);
688     if (fileInfo.hidden != 0) {
689         string fileName = fileInfo.displayName;
690         MEDIA_WARN_LOG("the file :%{public}s is hidden.", BackupFileUtils::GarbleFileName(fileName).c_str());
691     }
692     values.PutInt(PhotoColumn::PHOTO_HEIGHT, fileInfo.height);
693     values.PutInt(PhotoColumn::PHOTO_WIDTH, fileInfo.width);
694     values.PutString(PhotoColumn::PHOTO_USER_COMMENT, fileInfo.userComment);
695     values.PutInt(PhotoColumn::PHOTO_ORIENTATION, fileInfo.orientation);
696     std::string package_name = fileInfo.packageName;
697     if (package_name != "") {
698         values.PutString(PhotoColumn::MEDIA_PACKAGE_NAME, package_name);
699     }
700     values.PutInt(PhotoColumn::PHOTO_QUALITY, fileInfo.photoQuality);
701     values.PutInt(PhotoColumn::PHOTO_SUBTYPE, this->photosRestore_.FindSubtype(fileInfo));
702     values.PutInt(PhotoColumn::PHOTO_DIRTY, this->photosRestore_.FindDirty(fileInfo));
703     values.PutInt(PhotoColumn::PHOTO_BURST_COVER_LEVEL, this->photosRestore_.FindBurstCoverLevel(fileInfo));
704     values.PutString(PhotoColumn::PHOTO_BURST_KEY, this->photosRestore_.FindBurstKey(fileInfo));
705     // find album_id by lPath.
706     values.PutInt(PhotoColumn::PHOTO_OWNER_ALBUM_ID, this->photosRestore_.FindAlbumId(fileInfo));
707     // fill the source_path at last.
708     values.PutString(PhotoColumn::PHOTO_SOURCE_PATH, this->photosRestore_.FindSourcePath(fileInfo));
709     values.PutInt(PhotoColumn::PHOTO_STRONG_ASSOCIATION, this->photosRestore_.FindStrongAssociation(fileInfo));
710     values.PutInt(PhotoColumn::PHOTO_CE_AVAILABLE, this->photosRestore_.FindCeAvailable(fileInfo));
711     return values;
712 }
713 
ConvertPathToRealPath(const std::string & srcPath,const std::string & prefix,std::string & newPath,std::string & relativePath)714 bool UpgradeRestore::ConvertPathToRealPath(const std::string &srcPath, const std::string &prefix,
715     std::string &newPath, std::string &relativePath)
716 {
717     size_t pos = 0;
718     if (!BackupFileUtils::GetPathPosByPrefixLevel(sceneCode_, srcPath, INTERNAL_PREFIX_LEVEL, pos)) {
719         return false;
720     }
721     newPath = prefix + srcPath;
722     relativePath = srcPath.substr(pos);
723     return true;
724 }
725 
ConvertPathToRealPath(const std::string & srcPath,const std::string & prefix,std::string & newPath,std::string & relativePath,FileInfo & fileInfo)726 bool UpgradeRestore::ConvertPathToRealPath(const std::string &srcPath, const std::string &prefix,
727     std::string &newPath, std::string &relativePath, FileInfo &fileInfo)
728 {
729     if (MediaFileUtils::StartsWith(srcPath, INTERNAL_PREFIX)) {
730         return ConvertPathToRealPath(srcPath, prefix, newPath, relativePath);
731     }
732     size_t pos = 0;
733     if (!BackupFileUtils::GetPathPosByPrefixLevel(sceneCode_, srcPath, SD_PREFIX_LEVEL, pos)) {
734         return false;
735     }
736     relativePath = srcPath.substr(pos);
737     if (fileInfo.fileSize < TAR_FILE_LIMIT || fileInfo.localMediaId == GALLERY_HIDDEN_ID ||
738         fileInfo.localMediaId == GALLERY_TRASHED_ID) {
739         newPath = prefix + srcPath; // packed as tar, hidden or trashed, use path in DB
740     } else {
741         newPath = prefix + relativePath; // others, remove sd prefix, use relative path
742     }
743     fileInfo.isInternal = false;
744     return true;
745 }
746 
747 /**
748  * @brief Update the FileInfo if it has a copy in system.
749  */
HasSameFileForDualClone(FileInfo & fileInfo)750 bool UpgradeRestore::HasSameFileForDualClone(FileInfo &fileInfo)
751 {
752     PhotosDao::PhotosRowData rowData = this->photosRestore_.FindSameFile(fileInfo);
753     int32_t fileId = rowData.fileId;
754     std::string cloudPath = rowData.data;
755     if (fileId <= 0 || cloudPath.empty()) {
756         return false;
757     }
758     fileInfo.isNew = false;
759     fileInfo.fileIdNew = fileId;
760     fileInfo.cloudPath = cloudPath;
761     bool isInCloud = rowData.cleanFlag == 1 && rowData.position == static_cast<int32_t>(PhotoPositionType::CLOUD);
762     // If the file was in cloud previously, only require update flags.
763     if (fileId > 0 && isInCloud) {
764         fileInfo.updateMap["clean_flag"] = "0";
765         fileInfo.updateMap["position"] = to_string(static_cast<int32_t>(PhotoPositionType::LOCAL_AND_CLOUD));
766         return false;
767     }
768     fileInfo.needMove = false;
769     return true;
770 }
771 
RestoreFromGalleryPortraitAlbum()772 void UpgradeRestore::RestoreFromGalleryPortraitAlbum()
773 {
774     int64_t start = MediaFileUtils::UTCTimeMilliSeconds();
775     int32_t totalNumber = QueryPortraitAlbumTotalNumber();
776     MEDIA_INFO_LOG("QueryPortraitAlbumTotalNumber, totalNumber = %{public}d", totalNumber);
777 
778     for (int32_t offset = 0; offset < totalNumber; offset += QUERY_COUNT) {
779         std::vector<std::string> tagNameToDeleteSelection;
780         std::vector<std::string> tagIds;
781         vector<PortraitAlbumInfo> portraitAlbumInfos = QueryPortraitAlbumInfos(offset,
782             tagNameToDeleteSelection);
783         if (!BackupDatabaseUtils::DeleteDuplicatePortraitAlbum(tagNameToDeleteSelection, tagIds, mediaLibraryRdb_)) {
784             MEDIA_ERR_LOG("Batch delete duplicate portrait album failed.");
785             return;
786         }
787         InsertPortraitAlbum(portraitAlbumInfos);
788     }
789 
790     int64_t end = MediaFileUtils::UTCTimeMilliSeconds();
791     migratePortraitTotalTimeCost_ += end - start;
792 }
793 
QueryPortraitAlbumTotalNumber()794 int32_t UpgradeRestore::QueryPortraitAlbumTotalNumber()
795 {
796     return BackupDatabaseUtils::QueryInt(galleryRdb_, QUERY_GALLERY_PORTRAIT_ALBUM_COUNT, CUSTOM_COUNT);
797 }
798 
QueryPortraitAlbumInfos(int32_t offset,std::vector<std::string> & tagNameToDeleteSelection)799 vector<PortraitAlbumInfo> UpgradeRestore::QueryPortraitAlbumInfos(int32_t offset,
800     std::vector<std::string>& tagNameToDeleteSelection)
801 {
802     vector<PortraitAlbumInfo> result;
803     result.reserve(QUERY_COUNT);
804     std::string querySql = "SELECT " + GALLERY_MERGE_TAG_TAG_ID + ", " + GALLERY_GROUP_TAG + ", " +
805         GALLERY_TAG_NAME + ", " + GALLERY_USER_OPERATION + ", " + GALLERY_RENAME_OPERATION +
806         " FROM " + GALLERY_PORTRAIT_ALBUM_TABLE;
807     querySql += " LIMIT " + std::to_string(offset) + ", " + std::to_string(QUERY_COUNT);
808     auto resultSet = BackupDatabaseUtils::GetQueryResultSet(galleryRdb_, querySql);
809     if (resultSet == nullptr) {
810         MEDIA_ERR_LOG("Query resultSql is null.");
811         return result;
812     }
813     while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
814         PortraitAlbumInfo portraitAlbumInfo;
815         if (!ParsePortraitAlbumResultSet(resultSet, portraitAlbumInfo)) {
816             MEDIA_ERR_LOG("Parse portrait album result set failed, exclude %{public}s",
817                 portraitAlbumInfo.tagName.c_str());
818             continue;
819         }
820         if (!SetAttributes(portraitAlbumInfo)) {
821             MEDIA_ERR_LOG("Set attributes failed, exclude %{public}s", portraitAlbumInfo.tagName.c_str());
822             continue;
823         }
824         if (!portraitAlbumInfo.tagName.empty()) {
825             tagNameToDeleteSelection.emplace_back(portraitAlbumInfo.tagName);
826         }
827 
828         result.emplace_back(portraitAlbumInfo);
829     }
830     return result;
831 }
832 
ParsePortraitAlbumResultSet(const std::shared_ptr<NativeRdb::ResultSet> & resultSet,PortraitAlbumInfo & portraitAlbumInfo)833 bool UpgradeRestore::ParsePortraitAlbumResultSet(const std::shared_ptr<NativeRdb::ResultSet> &resultSet,
834     PortraitAlbumInfo &portraitAlbumInfo)
835 {
836     portraitAlbumInfo.tagIdOld = GetStringVal(GALLERY_MERGE_TAG_TAG_ID, resultSet);
837     portraitAlbumInfo.groupTagOld = GetStringVal(GALLERY_GROUP_TAG, resultSet);
838     portraitAlbumInfo.tagName = GetStringVal(GALLERY_TAG_NAME, resultSet);
839     portraitAlbumInfo.userOperation = GetInt32Val(GALLERY_USER_OPERATION, resultSet);
840     portraitAlbumInfo.renameOperation = GetInt32Val(GALLERY_RENAME_OPERATION, resultSet);
841     return true;
842 }
843 
SetAttributes(PortraitAlbumInfo & portraitAlbumInfo)844 bool UpgradeRestore::SetAttributes(PortraitAlbumInfo &portraitAlbumInfo)
845 {
846     return BackupDatabaseUtils::SetTagIdNew(portraitAlbumInfo, tagIdMap_);
847 }
848 
InsertPortraitAlbum(std::vector<PortraitAlbumInfo> & portraitAlbumInfos)849 void UpgradeRestore::InsertPortraitAlbum(std::vector<PortraitAlbumInfo> &portraitAlbumInfos)
850 {
851     if (mediaLibraryRdb_ == nullptr) {
852         MEDIA_ERR_LOG("mediaLibraryRdb_ is null");
853         return;
854     }
855     if (portraitAlbumInfos.empty()) {
856         MEDIA_ERR_LOG("portraitAlbumInfos are empty");
857         return;
858     }
859 
860     int64_t startInsertAlbum = MediaFileUtils::UTCTimeMilliSeconds();
861     int32_t albumRowNum = InsertPortraitAlbumByTable(portraitAlbumInfos, true);
862     if (albumRowNum <= 0) {
863         BackupDatabaseUtils::PrintErrorLog("Insert portrait album failed", startInsertAlbum);
864         return;
865     }
866 
867     int64_t startInsertTag = MediaFileUtils::UTCTimeMilliSeconds();
868     int32_t tagRowNum = InsertPortraitAlbumByTable(portraitAlbumInfos, false);
869     if (tagRowNum <= 0) {
870         BackupDatabaseUtils::PrintErrorLog("Insert face tag failed", startInsertTag);
871         return;
872     }
873 
874     int64_t startQuery = MediaFileUtils::UTCTimeMilliSeconds();
875     BatchQueryAlbum(portraitAlbumInfos);
876     int64_t end = MediaFileUtils::UTCTimeMilliSeconds();
877     MEDIA_INFO_LOG("insert %{public}ld albums cost %{public}ld, %{public}ld tags cost %{public}ld, query cost "
878         "%{public}ld.", (long)albumRowNum, (long)(startInsertTag - startInsertAlbum), (long)tagRowNum,
879         (long)(startQuery - startInsertTag), (long)(end - startQuery));
880 }
881 
InsertPortraitAlbumByTable(std::vector<PortraitAlbumInfo> & portraitAlbumInfos,bool isAlbum)882 int32_t UpgradeRestore::InsertPortraitAlbumByTable(std::vector<PortraitAlbumInfo> &portraitAlbumInfos,
883     bool isAlbum)
884 {
885     std::vector<NativeRdb::ValuesBucket> values = GetInsertValues(portraitAlbumInfos, isAlbum);
886     int64_t rowNum = 0;
887     std::string tableName = isAlbum ? ANALYSIS_ALBUM_TABLE : VISION_FACE_TAG_TABLE;
888     int32_t errCode = BatchInsertWithRetry(tableName, values, rowNum);
889     if (errCode != E_OK) {
890         return 0;
891     }
892     return rowNum;
893 }
894 
GetInsertValues(std::vector<PortraitAlbumInfo> & portraitAlbumInfos,bool isAlbum)895 std::vector<NativeRdb::ValuesBucket> UpgradeRestore::GetInsertValues(std::vector<PortraitAlbumInfo> &portraitAlbumInfos,
896     bool isAlbum)
897 {
898     std::vector<NativeRdb::ValuesBucket> values;
899     for (auto &portraitAlbumInfo : portraitAlbumInfos) {
900         NativeRdb::ValuesBucket value = GetInsertValue(portraitAlbumInfo, isAlbum);
901         values.emplace_back(value);
902     }
903     return values;
904 }
905 
GetInsertValue(const PortraitAlbumInfo & portraitAlbumInfo,bool isAlbum)906 NativeRdb::ValuesBucket UpgradeRestore::GetInsertValue(const PortraitAlbumInfo &portraitAlbumInfo, bool isAlbum)
907 {
908     NativeRdb::ValuesBucket values;
909     values.PutString(TAG_ID, portraitAlbumInfo.tagIdNew);
910     values.PutInt(COUNT, 0);
911     if (isAlbum) {
912         values.PutString(ALBUM_NAME, portraitAlbumInfo.tagName);
913         values.PutString(GROUP_TAG, portraitAlbumInfo.groupTagOld);
914         values.PutInt(USER_OPERATION, portraitAlbumInfo.userOperation);
915         values.PutInt(RENAME_OPERATION, RENAME_OPERATION_RENAMED);
916         values.PutInt(ALBUM_TYPE, PhotoAlbumType::SMART);
917         values.PutInt(ALBUM_SUBTYPE, PhotoAlbumSubType::PORTRAIT);
918         values.PutInt(USER_DISPLAY_LEVEL, PortraitPages::FIRST_PAGE);
919         values.PutInt(IS_LOCAL, IS_LOCAL_TRUE);
920     } else {
921         values.PutString(TAG_VERSION, E_VERSION); // updated by analysis service
922     }
923     return values;
924 }
925 
BatchQueryAlbum(std::vector<PortraitAlbumInfo> & portraitAlbumInfos)926 void UpgradeRestore::BatchQueryAlbum(std::vector<PortraitAlbumInfo> &portraitAlbumInfos)
927 {
928     std::string tagIdSelection;
929     for (auto &portraitAlbumInfo : portraitAlbumInfos) {
930         BackupDatabaseUtils::UpdateSelection(tagIdSelection, portraitAlbumInfo.tagIdNew, true);
931     }
932     std::string querySql = "SELECT " + ALBUM_ID + ", " + TAG_ID + " FROM " + ANALYSIS_ALBUM_TABLE + " WHERE " +
933         TAG_ID + " IN (" + tagIdSelection + ")";
934     auto resultSet = BackupDatabaseUtils::GetQueryResultSet(mediaLibraryRdb_, querySql);
935     if (resultSet == nullptr) {
936         return;
937     }
938     while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
939         int32_t albumId = GetInt32Val(ALBUM_ID, resultSet);
940         std::string tagId = GetStringVal(TAG_ID, resultSet);
941         if (albumId <= 0 || tagId.empty()) {
942             continue;
943         }
944         portraitAlbumIdMap_[tagId] = albumId;
945     }
946 }
947 
NeedBatchQueryPhotoForPortrait(const std::vector<FileInfo> & fileInfos,NeedQueryMap & needQueryMap)948 bool UpgradeRestore::NeedBatchQueryPhotoForPortrait(const std::vector<FileInfo> &fileInfos, NeedQueryMap &needQueryMap)
949 {
950     if (portraitAlbumIdMap_.empty()) {
951         return false;
952     }
953     std::string selection;
954     for (const auto &fileInfo : fileInfos) {
955         BackupDatabaseUtils::UpdateSelection(selection, std::to_string(fileInfo.fileIdOld), false);
956     }
957     std::unordered_set<std::string> needQuerySet;
958     std::string querySql = "SELECT DISTINCT " + GALLERY_MERGE_FACE_HASH + " FROM " + GALLERY_FACE_TABLE_JOIN_TAG +
959         " HAVING " + GALLERY_MEDIA_ID + " IN (" + selection + ") AND " + GALLERY_TAG_NAME_NOT_NULL_OR_EMPTY;
960     auto resultSet = BackupDatabaseUtils::GetQueryResultSet(galleryRdb_, querySql);
961     if (resultSet == nullptr) {
962         MEDIA_ERR_LOG("Query resultSql is null.");
963         return false;
964     }
965     while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
966         std::string hash = GetStringVal(GALLERY_MERGE_FACE_HASH, resultSet);
967         if (hash.empty()) {
968             continue;
969         }
970         needQuerySet.insert(hash);
971     }
972     if (needQuerySet.empty()) {
973         return false;
974     }
975     needQueryMap[PhotoRelatedType::PORTRAIT] = needQuerySet;
976     return true;
977 }
978 
InsertFaceAnalysisData(const std::vector<FileInfo> & fileInfos,const NeedQueryMap & needQueryMap,int64_t & faceRowNum,int64_t & mapRowNum,int64_t & photoNum)979 void UpgradeRestore::InsertFaceAnalysisData(const std::vector<FileInfo> &fileInfos, const NeedQueryMap &needQueryMap,
980     int64_t &faceRowNum, int64_t &mapRowNum, int64_t &photoNum)
981 {
982     int64_t start = MediaFileUtils::UTCTimeMilliSeconds();
983     if (needQueryMap.count(PhotoRelatedType::PORTRAIT) == 0) {
984         return;
985     }
986     if (mediaLibraryRdb_ == nullptr || fileInfos.empty()) {
987         MEDIA_ERR_LOG("mediaLibraryRdb_ is null or fileInfos empty");
988         return;
989     }
990 
991     std::string hashSelection;
992     std::unordered_map<std::string, FileInfo> fileInfoMap;
993     SetHashReference(fileInfos, needQueryMap, hashSelection, fileInfoMap);
994 
995     int32_t totalNumber = QueryFaceTotalNumber(hashSelection);
996     MEDIA_INFO_LOG("Current %{public}zu / %{public}zu have %{public}d faces", fileInfoMap.size(), fileInfos.size(),
997         totalNumber);
998     std::unordered_set<std::string> excludedFiles;
999     std::unordered_set<std::string> filesWithFace;
1000     auto uniqueFileIdPairs = BackupDatabaseUtils::CollectFileIdPairs(fileInfos);
1001     BackupDatabaseUtils::DeleteExistingImageFaceData(mediaLibraryRdb_, uniqueFileIdPairs);
1002 
1003     for (int32_t offset = 0; offset < totalNumber; offset += QUERY_COUNT) {
1004         std::vector<FaceInfo> faceInfos = QueryFaceInfos(hashSelection, fileInfoMap, offset, excludedFiles);
1005         int64_t startInsertFace = MediaFileUtils::UTCTimeMilliSeconds();
1006         faceRowNum += InsertFaceAnalysisDataByTable(faceInfos, false, excludedFiles);
1007         if (faceRowNum <= 0) {
1008             BackupDatabaseUtils::PrintErrorLog("Insert face failed", startInsertFace);
1009             continue;
1010         }
1011         int64_t startInsertMap = MediaFileUtils::UTCTimeMilliSeconds();
1012         mapRowNum += InsertFaceAnalysisDataByTable(faceInfos, true, excludedFiles);
1013         if (mapRowNum <= 0) {
1014             BackupDatabaseUtils::PrintErrorLog("Insert map failed", startInsertMap);
1015             continue;
1016         }
1017         UpdateFilesWithFace(filesWithFace, faceInfos);
1018         int64_t endInsert = MediaFileUtils::UTCTimeMilliSeconds();
1019         MEDIA_INFO_LOG("insert %{public}ld faces cost %{public}ld, %{public}ld maps cost %{public}ld", (long)faceRowNum,
1020             (long)(startInsertMap - startInsertFace), (long)mapRowNum, (long)(endInsert - startInsertMap));
1021     }
1022     int64_t end = MediaFileUtils::UTCTimeMilliSeconds();
1023     photoNum = static_cast<int64_t>(filesWithFace.size());
1024     migratePortraitFaceNumber_ += faceRowNum;
1025     migratePortraitPhotoNumber_ += photoNum;
1026     migratePortraitTotalTimeCost_ += end - start;
1027 }
1028 
SetHashReference(const std::vector<FileInfo> & fileInfos,const NeedQueryMap & needQueryMap,std::string & hashSelection,std::unordered_map<std::string,FileInfo> & fileInfoMap)1029 void UpgradeRestore::SetHashReference(const std::vector<FileInfo> &fileInfos, const NeedQueryMap &needQueryMap,
1030     std::string &hashSelection, std::unordered_map<std::string, FileInfo> &fileInfoMap)
1031 {
1032     auto needQuerySet = needQueryMap.at(PhotoRelatedType::PORTRAIT);
1033     for (const auto &fileInfo : fileInfos) {
1034         if (needQuerySet.count(fileInfo.hashCode) == 0 || fileInfo.fileIdNew <= 0) {
1035             continue;
1036         }
1037         if (fileInfoMap.count(fileInfo.hashCode) > 0) {
1038             continue; // select the first one to build map
1039         }
1040         BackupDatabaseUtils::UpdateSelection(hashSelection, fileInfo.hashCode, true);
1041         fileInfoMap[fileInfo.hashCode] = fileInfo;
1042     }
1043 }
1044 
QueryFaceTotalNumber(const std::string & hashSelection)1045 int32_t UpgradeRestore::QueryFaceTotalNumber(const std::string &hashSelection)
1046 {
1047     std::string querySql = "SELECT count(1) as count FROM " + GALLERY_FACE_TABLE_FULL + " AND " +
1048         GALLERY_MERGE_FACE_HASH + " IN (" + hashSelection + ")";
1049     return BackupDatabaseUtils::QueryInt(galleryRdb_, querySql, CUSTOM_COUNT);
1050 }
1051 
QueryFaceInfos(const std::string & hashSelection,const std::unordered_map<std::string,FileInfo> & fileInfoMap,int32_t offset,std::unordered_set<std::string> & excludedFiles)1052 std::vector<FaceInfo> UpgradeRestore::QueryFaceInfos(const std::string &hashSelection,
1053     const std::unordered_map<std::string, FileInfo> &fileInfoMap, int32_t offset,
1054     std::unordered_set<std::string> &excludedFiles)
1055 {
1056     vector<FaceInfo> result;
1057     result.reserve(QUERY_COUNT);
1058     std::string querySql = "SELECT " + GALLERY_SCALE_X + ", " + GALLERY_SCALE_Y + ", " + GALLERY_SCALE_WIDTH + ", " +
1059         GALLERY_SCALE_HEIGHT + ", " + GALLERY_PITCH + ", " + GALLERY_YAW + ", " + GALLERY_ROLL + ", " +
1060         GALLERY_PROB + ", " + GALLERY_TOTAL_FACE + ", " + GALLERY_MERGE_FACE_HASH + ", " + GALLERY_MERGE_FACE_FACE_ID +
1061         ", " + GALLERY_MERGE_FACE_TAG_ID + ", " + GALLERY_LANDMARKS + " FROM " + GALLERY_FACE_TABLE_FULL + " AND " +
1062         GALLERY_MERGE_FACE_HASH + " IN (" + hashSelection + ") ORDER BY " + GALLERY_MERGE_FACE_HASH + ", " +
1063         GALLERY_MERGE_FACE_FACE_ID;
1064     querySql += " LIMIT " + std::to_string(offset) + ", " + std::to_string(QUERY_COUNT);
1065     auto resultSet = BackupDatabaseUtils::GetQueryResultSet(galleryRdb_, querySql);
1066     if (resultSet == nullptr) {
1067         MEDIA_ERR_LOG("Query resultSql is null.");
1068         return result;
1069     }
1070     while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
1071         FaceInfo faceInfo;
1072         if (!ParseFaceResultSet(resultSet, faceInfo)) {
1073             MEDIA_ERR_LOG("Parse face result set failed, exclude %{public}s", faceInfo.hash.c_str());
1074             excludedFiles.insert(faceInfo.hash);
1075             continue;
1076         }
1077         if (!SetAttributes(faceInfo, fileInfoMap)) {
1078             MEDIA_ERR_LOG("Set attributes failed, exclude %{public}s", faceInfo.hash.c_str());
1079             excludedFiles.insert(faceInfo.hash);
1080             continue;
1081         }
1082         result.emplace_back(faceInfo);
1083     }
1084     return result;
1085 }
1086 
ParseFaceResultSet(const std::shared_ptr<NativeRdb::ResultSet> & resultSet,FaceInfo & faceInfo)1087 bool UpgradeRestore::ParseFaceResultSet(const std::shared_ptr<NativeRdb::ResultSet> &resultSet, FaceInfo &faceInfo)
1088 {
1089     faceInfo.scaleX = GetDoubleVal(GALLERY_SCALE_X, resultSet);
1090     faceInfo.scaleY = GetDoubleVal(GALLERY_SCALE_Y, resultSet);
1091     faceInfo.scaleWidth = GetDoubleVal(GALLERY_SCALE_WIDTH, resultSet);
1092     faceInfo.scaleHeight = GetDoubleVal(GALLERY_SCALE_HEIGHT, resultSet);
1093     faceInfo.pitch = GetDoubleVal(GALLERY_PITCH, resultSet);
1094     faceInfo.yaw = GetDoubleVal(GALLERY_YAW, resultSet);
1095     faceInfo.roll = GetDoubleVal(GALLERY_ROLL, resultSet);
1096     faceInfo.prob = GetDoubleVal(GALLERY_PROB, resultSet);
1097     faceInfo.totalFaces = GetInt32Val(GALLERY_TOTAL_FACE, resultSet);
1098     faceInfo.hash = GetStringVal(GALLERY_MERGE_FACE_HASH, resultSet);
1099     faceInfo.faceId = GetStringVal(GALLERY_MERGE_FACE_FACE_ID, resultSet);
1100     faceInfo.tagIdOld = GetStringVal(GALLERY_MERGE_FACE_TAG_ID, resultSet);
1101     faceInfo.landmarks = BackupDatabaseUtils::GetLandmarksStr(GALLERY_LANDMARKS, resultSet);
1102     if (faceInfo.landmarks.empty()) {
1103         MEDIA_ERR_LOG("Get invalid landmarks for face %{public}s", faceInfo.faceId.c_str());
1104         return false;
1105     }
1106     return true;
1107 }
1108 
SetAttributes(FaceInfo & faceInfo,const std::unordered_map<std::string,FileInfo> & fileInfoMap)1109 bool UpgradeRestore::SetAttributes(FaceInfo &faceInfo, const std::unordered_map<std::string, FileInfo> &fileInfoMap)
1110 {
1111     return BackupDatabaseUtils::SetLandmarks(faceInfo, fileInfoMap) &&
1112         BackupDatabaseUtils::SetFileIdNew(faceInfo, fileInfoMap) &&
1113         BackupDatabaseUtils::SetTagIdNew(faceInfo, tagIdMap_) &&
1114         BackupDatabaseUtils::SetAlbumIdNew(faceInfo, portraitAlbumIdMap_);
1115 }
1116 
InsertFaceAnalysisDataByTable(const std::vector<FaceInfo> & faceInfos,bool isMap,const std::unordered_set<std::string> & excludedFiles)1117 int32_t UpgradeRestore::InsertFaceAnalysisDataByTable(const std::vector<FaceInfo> &faceInfos, bool isMap,
1118     const std::unordered_set<std::string> &excludedFiles)
1119 {
1120     std::vector<NativeRdb::ValuesBucket> values = GetInsertValues(faceInfos, isMap, excludedFiles);
1121     int64_t rowNum = 0;
1122     std::string tableName = isMap ? ANALYSIS_PHOTO_MAP_TABLE : VISION_IMAGE_FACE_TABLE;
1123     int32_t errCode = BatchInsertWithRetry(tableName, values, rowNum);
1124     if (errCode != E_OK) {
1125         return 0;
1126     }
1127     return rowNum;
1128 }
1129 
GetInsertValues(const std::vector<FaceInfo> & faceInfos,bool isMap,const std::unordered_set<std::string> & excludedFiles)1130 std::vector<NativeRdb::ValuesBucket> UpgradeRestore::GetInsertValues(const std::vector<FaceInfo> &faceInfos, bool isMap,
1131     const std::unordered_set<std::string> &excludedFiles)
1132 {
1133     std::vector<NativeRdb::ValuesBucket> values;
1134     for (auto &faceInfo : faceInfos) {
1135         if (excludedFiles.count(faceInfo.hash) > 0) {
1136             continue;
1137         }
1138         if (isMap && faceInfo.tagIdNew == TAG_ID_UNPROCESSED) {
1139             continue;
1140         }
1141         NativeRdb::ValuesBucket value = GetInsertValue(faceInfo, isMap);
1142         values.emplace_back(value);
1143     }
1144     return values;
1145 }
1146 
GetInsertValue(const FaceInfo & faceInfo,bool isMap)1147 NativeRdb::ValuesBucket UpgradeRestore::GetInsertValue(const FaceInfo &faceInfo, bool isMap)
1148 {
1149     NativeRdb::ValuesBucket values;
1150     if (isMap) {
1151         values.PutInt(MAP_ALBUM, faceInfo.albumIdNew);
1152         values.PutInt(MAP_ASSET, faceInfo.fileIdNew);
1153     } else {
1154         values.PutDouble(SCALE_X, faceInfo.scaleX);
1155         values.PutDouble(SCALE_Y, faceInfo.scaleY);
1156         values.PutDouble(SCALE_WIDTH, faceInfo.scaleWidth);
1157         values.PutDouble(SCALE_HEIGHT, faceInfo.scaleHeight);
1158         values.PutDouble(PITCH, faceInfo.pitch);
1159         values.PutDouble(YAW, faceInfo.yaw);
1160         values.PutDouble(ROLL, faceInfo.roll);
1161         values.PutDouble(PROB, faceInfo.prob);
1162         values.PutInt(TOTAL_FACES, faceInfo.totalFaces);
1163         values.PutInt(FILE_ID, faceInfo.fileIdNew);
1164         values.PutString(FACE_ID, faceInfo.faceId);
1165         values.PutString(TAG_ID, faceInfo.tagIdNew);
1166         values.PutString(LANDMARKS, faceInfo.landmarks);
1167         values.PutString(IMAGE_FACE_VERSION, DEFAULT_BACKUP_VERSION); // replaced by the latest
1168         values.PutString(IMAGE_FEATURES_VERSION, E_VERSION); // updated by analysis service
1169     }
1170     return values;
1171 }
1172 
UpdateFilesWithFace(std::unordered_set<std::string> & filesWithFace,const std::vector<FaceInfo> & faceInfos)1173 void UpgradeRestore::UpdateFilesWithFace(std::unordered_set<std::string> &filesWithFace,
1174     const std::vector<FaceInfo> &faceInfos)
1175 {
1176     for (const auto &faceInfo : faceInfos) {
1177         if (faceInfo.hash.empty()) {
1178             continue;
1179         }
1180         filesWithFace.insert(faceInfo.hash);
1181     }
1182 }
1183 
UpdateFaceAnalysisStatus()1184 void UpgradeRestore::UpdateFaceAnalysisStatus()
1185 {
1186     if (portraitAlbumIdMap_.empty()) {
1187         MEDIA_INFO_LOG("There is no need to update face analysis status");
1188         return;
1189     }
1190     int64_t startUpdateGroupTag = MediaFileUtils::UTCTimeMilliSeconds();
1191     BackupDatabaseUtils::UpdateFaceGroupTagOfDualFrame(mediaLibraryRdb_);
1192     int64_t startUpdateTotal = MediaFileUtils::UTCTimeMilliSeconds();
1193     BackupDatabaseUtils::UpdateAnalysisTotalStatus(mediaLibraryRdb_);
1194     int64_t startUpdateFaceTag = MediaFileUtils::UTCTimeMilliSeconds();
1195     BackupDatabaseUtils::UpdateAnalysisFaceTagStatus(mediaLibraryRdb_);
1196     int64_t end = MediaFileUtils::UTCTimeMilliSeconds();
1197     MEDIA_INFO_LOG("Update group tag cost %{public}lld, update total table cost %{public}lld, update face tag table "
1198         "cost %{public}lld", (long long)(startUpdateTotal - startUpdateGroupTag),
1199         (long long)(startUpdateFaceTag - startUpdateTotal), (long long)(end - startUpdateFaceTag));
1200     migratePortraitTotalTimeCost_ += end - startUpdateGroupTag;
1201 }
1202 
UpdateDualCloneFaceAnalysisStatus()1203 void UpgradeRestore::UpdateDualCloneFaceAnalysisStatus()
1204 {
1205     if (portraitAlbumIdMap_.empty()) {
1206         MEDIA_INFO_LOG("There is no need to update face analysis status");
1207         return;
1208     }
1209 
1210     BackupDatabaseUtils::UpdateFaceGroupTagOfDualFrame(mediaLibraryRdb_);
1211     BackupDatabaseUtils::UpdateAnalysisPhotoMapStatus(mediaLibraryRdb_);
1212     BackupDatabaseUtils::UpdateFaceAnalysisTblStatus(mediaLibraryRdb_);
1213 }
1214 
CheckInvalidFile(const FileInfo & fileInfo,int32_t errCode)1215 std::string UpgradeRestore::CheckInvalidFile(const FileInfo &fileInfo, int32_t errCode)
1216 {
1217     if (errCode != E_NO_SUCH_FILE) {
1218         return "";
1219     }
1220     int32_t dbType = BackupDatabaseHelper::DbType::DEFAULT;
1221     int32_t dbStatus = E_OK;
1222     int32_t fileStatus = E_OK;
1223     backupDatabaseHelper_.IsFileExist(sceneCode_, fileInfo, dbType, dbStatus, fileStatus);
1224     MEDIA_INFO_LOG("Check status type: %{public}d, db: %{public}d, file: %{public}d", dbType, dbStatus, fileStatus);
1225     return BackupLogUtils::FileDbCheckInfoToString(FileDbCheckInfo(dbType, dbStatus, fileStatus));
1226 }
1227 
GetNoNeedMigrateCount()1228 int32_t UpgradeRestore::GetNoNeedMigrateCount()
1229 {
1230     return GalleryMediaDao(this->galleryRdb_).GetNoNeedMigrateCount(this->shouldIncludeSd_);
1231 }
1232 
IsBasicInfoValid(const std::shared_ptr<NativeRdb::ResultSet> & resultSet,FileInfo & info,const std::string & dbName)1233 bool UpgradeRestore::IsBasicInfoValid(const std::shared_ptr<NativeRdb::ResultSet> &resultSet, FileInfo &info,
1234     const std::string &dbName)
1235 {
1236     info.displayName = GetStringVal(GALLERY_DISPLAY_NAME, resultSet);
1237     info.oldPath = GetStringVal(GALLERY_FILE_DATA, resultSet);
1238     info.fileType = GetInt32Val(GALLERY_MEDIA_TYPE, resultSet);
1239     info.fileSize = GetInt64Val(GALLERY_FILE_SIZE, resultSet); // read basic info from db first
1240     if (this->photosRestore_.IsDuplicateData(info.oldPath)) {
1241         ErrorInfo errorInfo(RestoreError::DUPLICATE_DATA, 1, "",
1242                             BackupLogUtils::FileInfoToString(sceneCode_, info));
1243         UpgradeRestoreTaskReport().SetSceneCode(this->sceneCode_).SetTaskId(this->taskId_).ReportError(errorInfo);
1244         return false;
1245     }
1246     if (sceneCode_ == UPGRADE_RESTORE_ID ?
1247         !BaseRestore::ConvertPathToRealPath(info.oldPath, filePath_, info.filePath, info.relativePath) :
1248         !ConvertPathToRealPath(info.oldPath, filePath_, info.filePath, info.relativePath, info)) {
1249         ErrorInfo errorInfo(RestoreError::PATH_INVALID, 1, "",
1250                             BackupLogUtils::FileInfoToString(sceneCode_, info));
1251         UpgradeRestoreTaskReport().SetSceneCode(this->sceneCode_).SetTaskId(this->taskId_).ReportError(errorInfo);
1252         return false;
1253     }
1254     info.fileType = this->photosRestore_.FindMediaType(info);
1255     if (info.fileType != MediaType::MEDIA_TYPE_IMAGE && info.fileType != MediaType::MEDIA_TYPE_VIDEO) {
1256         ErrorInfo errorInfo(RestoreError::MEDIA_TYPE_INVALID, 1, std::to_string(info.fileType),
1257                             BackupLogUtils::FileInfoToString(sceneCode_, info));
1258         UpgradeRestoreTaskReport().SetSceneCode(this->sceneCode_).SetTaskId(this->taskId_).ReportError(errorInfo);
1259         return false;
1260     }
1261     if (info.fileSize < fileMinSize_ && dbName == EXTERNAL_DB_NAME) {
1262         MEDIA_WARN_LOG("maybe garbage path = %{public}s, minSize:%{public}d.",
1263             BackupFileUtils::GarbleFilePath(info.oldPath, DEFAULT_RESTORE_ID).c_str(), fileMinSize_);
1264         ErrorInfo errorInfo(RestoreError::SIZE_INVALID, 1, "Db size < " + std::to_string(fileMinSize_),
1265                             BackupLogUtils::FileInfoToString(sceneCode_, info));
1266         UpgradeRestoreTaskReport().SetSceneCode(this->sceneCode_).SetTaskId(this->taskId_).ReportError(errorInfo);
1267         return false;
1268     }
1269     return true;
1270 }
1271 
CheckGalleryDbIntegrity()1272 std::string UpgradeRestore::CheckGalleryDbIntegrity()
1273 {
1274     MEDIA_INFO_LOG("start handle gallery integrity check.");
1275     std::string dbIntegrityCheck = DB_INTEGRITY_CHECK;
1276     std::string dbSize = "";
1277     struct stat statInfo {};
1278     if (stat(galleryDbPath_.c_str(), &statInfo) == 0) {
1279         dbSize = std::to_string(statInfo.st_size);
1280     }
1281     int64_t dbIntegrityCheckTime = MediaFileUtils::UTCTimeMilliSeconds();
1282     dbIntegrityCheck = BackupDatabaseUtils::CheckDbIntegrity(galleryRdb_, sceneCode_, "GALLERY_DB_CORRUPTION");
1283     dbIntegrityCheckTime = MediaFileUtils::UTCTimeMilliSeconds() - dbIntegrityCheckTime;
1284     UpgradeRestoreTaskReport()
1285         .SetSceneCode(this->sceneCode_)
1286         .SetTaskId(this->taskId_)
1287         .ReportProgress("GalleryDbCheck", dbSize + ";" + std::to_string(dbIntegrityCheckTime));
1288     MEDIA_INFO_LOG("end handle gallery integrity check, cost %{public}lld, size %{public}s.", \
1289         (long long)(dbIntegrityCheckTime), dbSize.c_str());
1290     return dbIntegrityCheck;
1291 }
1292 } // namespace Media
1293 } // namespace OHOS