• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #define MLOG_TAG "MediaLibraryBaseRestore"
17 
18 #include "base_restore.h"
19 
20 #include <sstream>
21 
22 #include "application_context.h"
23 #include "backup_database_utils.h"
24 #include "backup_dfx_utils.h"
25 #include "backup_file_utils.h"
26 #include "backup_log_utils.h"
27 #include "directory_ex.h"
28 #include "extension_context.h"
29 #include "media_column.h"
30 #include "media_log.h"
31 #include "media_file_utils.h"
32 #include "media_scanner_manager.h"
33 #include "medialibrary_asset_operations.h"
34 #include "medialibrary_data_manager.h"
35 #include "medialibrary_object_utils.h"
36 #include "medialibrary_rdb_utils.h"
37 #include "medialibrary_type_const.h"
38 #include "medialibrary_errno.h"
39 #include "metadata.h"
40 #include "moving_photo_file_utils.h"
41 #include "parameters.h"
42 #include "photo_album_column.h"
43 #include "result_set_utils.h"
44 #include "userfilemgr_uri.h"
45 #include "medialibrary_notify.h"
46 #include "upgrade_restore_task_report.h"
47 #include "medialibrary_rdb_transaction.h"
48 #include "database_report.h"
49 
50 namespace OHOS {
51 namespace Media {
52 const std::string DATABASE_PATH = "/data/storage/el2/database/rdb/media_library.db";
53 const std::string SINGLE_DIR_NAME = "A";
54 const std::string CLONE_FLAG = "multimedia.medialibrary.cloneFlag";
55 
StartRestore(const std::string & backupRetoreDir,const std::string & upgradePath)56 void BaseRestore::StartRestore(const std::string &backupRetoreDir, const std::string &upgradePath)
57 {
58     backupRestoreDir_ = backupRetoreDir;
59     int32_t errorCode = Init(backupRetoreDir, upgradePath, true);
60     if (errorCode == E_OK) {
61         RestorePhoto();
62         RestoreAudio();
63         MEDIA_INFO_LOG("migrate database number: %{public}lld, file number: %{public}lld (%{public}lld + "
64             "%{public}lld), duplicate number: %{public}lld + %{public}lld, audio database number:%{public}lld, "
65             "audio file number:%{public}lld, duplicate audio number: %{public}lld, map number: %{public}lld",
66             (long long)migrateDatabaseNumber_, (long long)migrateFileNumber_,
67             (long long)(migrateFileNumber_ - migrateVideoFileNumber_), (long long)migrateVideoFileNumber_,
68             (long long)migratePhotoDuplicateNumber_, (long long)migrateVideoDuplicateNumber_,
69             (long long)migrateAudioDatabaseNumber_, (long long)migrateAudioFileNumber_,
70             (long long)migrateAudioDuplicateNumber_, (long long) migrateDatabaseMapNumber_);
71         UpdateDatabase();
72     } else {
73         if (errorCode != EXTERNAL_DB_NOT_EXIST) {
74             SetErrorCode(RestoreError::INIT_FAILED);
75         }
76         ErrorInfo errorInfo(RestoreError::INIT_FAILED, 0, errorCode);
77         UpgradeRestoreTaskReport().SetSceneCode(this->sceneCode_).SetTaskId(this->taskId_).ReportError(errorInfo);
78     }
79     HandleRestData();
80 }
81 
Init(void)82 int32_t BaseRestore::Init(void)
83 {
84     if (mediaLibraryRdb_ != nullptr) {
85         return E_OK;
86     }
87     auto context = AbilityRuntime::Context::GetApplicationContext();
88     if (context == nullptr) {
89         MEDIA_ERR_LOG("Failed to get context");
90         return E_FAIL;
91     }
92     int32_t err = BackupDatabaseUtils::InitDb(mediaLibraryRdb_, MEDIA_DATA_ABILITY_DB_NAME, DATABASE_PATH, BUNDLE_NAME,
93         true, context->GetArea());
94     if (err != E_OK) {
95         MEDIA_ERR_LOG("medialibrary rdb fail, err = %{public}d", err);
96         return E_FAIL;
97     }
98     int32_t sceneCode = 0;
99     int32_t errCode = MediaLibraryDataManager::GetInstance()->InitMediaLibraryMgr(context, nullptr, sceneCode);
100     if (errCode != E_OK) {
101         MEDIA_ERR_LOG("When restore, InitMediaLibraryMgr fail, errcode = %{public}d", errCode);
102         return errCode;
103     }
104     migrateDatabaseNumber_ = 0;
105     migrateFileNumber_ = 0;
106     migrateVideoFileNumber_ = 0;
107     migrateAudioDatabaseNumber_ = 0;
108     migrateAudioFileNumber_ = 0;
109     imageNumber_ = BackupDatabaseUtils::QueryUniqueNumber(mediaLibraryRdb_, IMAGE_ASSET_TYPE);
110     videoNumber_ = BackupDatabaseUtils::QueryUniqueNumber(mediaLibraryRdb_, VIDEO_ASSET_TYPE);
111     audioNumber_ = BackupDatabaseUtils::QueryUniqueNumber(mediaLibraryRdb_, AUDIO_ASSET_TYPE);
112     MEDIA_INFO_LOG("imageNumber: %{public}d", (int)imageNumber_);
113     MEDIA_INFO_LOG("videoNumber: %{public}d", (int)videoNumber_);
114     MEDIA_INFO_LOG("audioNumber: %{public}d", (int)audioNumber_);
115     return E_OK;
116 }
117 
ConvertPathToRealPath(const std::string & srcPath,const std::string & prefix,std::string & newPath,std::string & relativePath)118 bool BaseRestore::ConvertPathToRealPath(const std::string &srcPath, const std::string &prefix,
119     std::string &newPath, std::string &relativePath)
120 {
121     size_t pos = 0;
122     int32_t count = 0;
123     constexpr int32_t prefixLevel = 4;
124     for (size_t i = 0; i < srcPath.length(); i++) {
125         if (srcPath[i] == '/') {
126             count++;
127             if (count == prefixLevel) {
128                 pos = i;
129                 break;
130             }
131         }
132     }
133     if (count < prefixLevel) {
134         return false;
135     }
136     relativePath = srcPath.substr(pos);
137     if (!dualDirName_.empty() && relativePath.find(dualDirName_) != string::npos) {
138         std::size_t posStart = relativePath.find_first_of("/");
139         std::size_t posEnd = relativePath.find_first_of("/", posStart + 1);
140         if (posEnd != string::npos) {
141             string temp = relativePath.substr(posStart + 1, posEnd - posStart -1);
142             if (temp == dualDirName_) {
143                 relativePath.replace(relativePath.find(dualDirName_), dualDirName_.length(), SINGLE_DIR_NAME);
144             }
145         }
146     }
147     std::string extraPrefix = BackupFileUtils::GetExtraPrefixForRealPath(sceneCode_, srcPath);
148     newPath = prefix + extraPrefix + relativePath;
149     return true;
150 }
151 
QuerySql(const string & sql,const vector<string> & selectionArgs) const152 shared_ptr<NativeRdb::ResultSet> BaseRestore::QuerySql(const string &sql, const vector<string> &selectionArgs) const
153 {
154     if (mediaLibraryRdb_ == nullptr) {
155         MEDIA_ERR_LOG("Pointer rdb_ is nullptr. Maybe it didn't init successfully.");
156         return nullptr;
157     }
158 
159     return mediaLibraryRdb_->QuerySql(sql, selectionArgs);
160 }
161 
MoveFile(const std::string & srcFile,const std::string & dstFile) const162 int32_t BaseRestore::MoveFile(const std::string &srcFile, const std::string &dstFile) const
163 {
164     int32_t errCode = BackupFileUtils::MoveFile(srcFile, dstFile, sceneCode_);
165     if (errCode == E_SUCCESS) {
166         return E_OK;
167     }
168     if (this->CopyFile(srcFile, dstFile) != E_OK) {
169         return E_FAIL;
170     }
171     (void)MediaFileUtils::DeleteFile(srcFile);
172     return E_OK;
173 }
174 
CopyFile(const std::string & srcFile,const std::string & dstFile) const175 int32_t BaseRestore::CopyFile(const std::string &srcFile, const std::string &dstFile) const
176 {
177     if (!MediaFileUtils::CopyFileUtil(srcFile, dstFile)) {
178         MEDIA_ERR_LOG("CopyFile failed, src: %{public}s, dst: %{public}s, errMsg: %{public}s",
179             BackupFileUtils::GarbleFilePath(srcFile, sceneCode_).c_str(),
180             BackupFileUtils::GarbleFilePath(srcFile, DEFAULT_RESTORE_ID).c_str(), strerror(errno));
181         return E_FAIL;
182     }
183     return E_OK;
184 }
185 
IsFileValid(FileInfo & fileInfo,const int32_t sceneCode)186 int32_t BaseRestore::IsFileValid(FileInfo &fileInfo, const int32_t sceneCode)
187 {
188     int32_t errCode = BackupFileUtils::IsFileValid(fileInfo.filePath, DUAL_FRAME_CLONE_RESTORE_ID,
189         fileInfo.relativePath, hasLowQualityImage_);
190     if (errCode != E_OK) {
191         MEDIA_ERR_LOG("File is not valid: %{public}s, errno=%{public}d.",
192             BackupFileUtils::GarbleFilePath(fileInfo.filePath, sceneCode).c_str(), errno);
193         return errCode;
194     }
195 
196     if (BackupFileUtils::IsLivePhoto(fileInfo)) {
197         if (!MediaFileUtils::IsFileValid(fileInfo.movingPhotoVideoPath)) {
198             MEDIA_ERR_LOG("Moving photo video is not valid: %{public}s, errno=%{public}d.",
199                 BackupFileUtils::GarbleFilePath(fileInfo.movingPhotoVideoPath, sceneCode).c_str(), errno);
200             return E_FAIL;
201         }
202 
203         if (!MediaFileUtils::IsFileValid(fileInfo.extraDataPath)) {
204             MEDIA_WARN_LOG("Media extra data is not valid: %{public}s, errno=%{public}d.",
205                 BackupFileUtils::GarbleFilePath(fileInfo.extraDataPath, sceneCode).c_str(), errno);
206             return E_FAIL;
207         }
208     }
209     return E_OK;
210 }
211 
RemoveDuplicateDualCloneFiles(const FileInfo & fileInfo)212 static void RemoveDuplicateDualCloneFiles(const FileInfo &fileInfo)
213 {
214     (void)MediaFileUtils::DeleteFile(fileInfo.filePath);
215     if (BackupFileUtils::IsLivePhoto(fileInfo)) {
216         (void)MediaFileUtils::DeleteFile(fileInfo.movingPhotoVideoPath);
217         (void)MediaFileUtils::DeleteFile(fileInfo.extraDataPath);
218     }
219 }
220 
GetInsertValues(const int32_t sceneCode,std::vector<FileInfo> & fileInfos,int32_t sourceType)221 vector<NativeRdb::ValuesBucket> BaseRestore::GetInsertValues(const int32_t sceneCode, std::vector<FileInfo> &fileInfos,
222     int32_t sourceType)
223 {
224     vector<NativeRdb::ValuesBucket> values;
225     for (size_t i = 0; i < fileInfos.size(); i++) {
226         int32_t errCode = IsFileValid(fileInfos[i], sceneCode);
227         if (errCode != E_OK) {
228             fileInfos[i].needMove = false;
229             std::string fileDbCheckInfo = CheckInvalidFile(fileInfos[i], errCode);
230             ErrorInfo errorInfo(RestoreError::FILE_INVALID, 1, std::to_string(errCode),
231                 BackupLogUtils::FileInfoToString(sceneCode, fileInfos[i], { fileDbCheckInfo }));
232             UpgradeRestoreTaskReport().SetSceneCode(this->sceneCode_).SetTaskId(this->taskId_).ReportError(errorInfo);
233             continue;
234         }
235         std::string cloudPath;
236         int32_t uniqueId = GetUniqueId(fileInfos[i].fileType);
237         errCode = BackupFileUtils::CreateAssetPathById(uniqueId, fileInfos[i].fileType,
238             MediaFileUtils::GetExtensionFromPath(fileInfos[i].displayName), cloudPath);
239         if (errCode != E_OK) {
240             fileInfos[i].needMove = false;
241             ErrorInfo errorInfo(RestoreError::CREATE_PATH_FAILED, 1, std::to_string(errCode),
242                 BackupLogUtils::FileInfoToString(sceneCode, fileInfos[i]));
243             UpgradeRestoreTaskReport().SetSceneCode(this->sceneCode_).SetTaskId(this->taskId_).ReportError(errorInfo);
244             continue;
245         }
246         fileInfos[i].cloudPath = cloudPath;
247         NativeRdb::ValuesBucket value = GetInsertValue(fileInfos[i], cloudPath, sourceType);
248         SetValueFromMetaData(fileInfos[i], value);
249         if ((sceneCode == DUAL_FRAME_CLONE_RESTORE_ID || sceneCode == OTHERS_PHONE_CLONE_RESTORE ||
250             sceneCode == LITE_PHONE_CLONE_RESTORE || sceneCode == I_PHONE_CLONE_RESTORE) &&
251             this->HasSameFileForDualClone(fileInfos[i])) {
252             fileInfos[i].needMove = false;
253             RemoveDuplicateDualCloneFiles(fileInfos[i]);
254             MEDIA_WARN_LOG("File %{public}s already exists.",
255                 BackupFileUtils::GarbleFilePath(fileInfos[i].filePath, sceneCode).c_str());
256             UpdateDuplicateNumber(fileInfos[i].fileType);
257             continue;
258         }
259         if (fileInfos[i].isNew) {
260             values.emplace_back(value);
261         }
262     }
263     return values;
264 }
265 
InsertDateTaken(std::unique_ptr<Metadata> & metadata,FileInfo & fileInfo,NativeRdb::ValuesBucket & value)266 static void InsertDateTaken(std::unique_ptr<Metadata> &metadata, FileInfo &fileInfo, NativeRdb::ValuesBucket &value)
267 {
268     int64_t dateTaken = metadata->GetDateTaken();
269     if (dateTaken != 0) {
270         value.PutLong(MediaColumn::MEDIA_DATE_TAKEN, dateTaken);
271         fileInfo.dateTaken = dateTaken;
272         return;
273     }
274 
275     int64_t dateAdded = metadata->GetFileDateAdded();
276     if (dateAdded == 0) {
277         int64_t dateModified = metadata->GetFileDateModified();
278         if (dateModified == 0) {
279             dateTaken = MediaFileUtils::UTCTimeMilliSeconds();
280         } else {
281             dateTaken = dateModified;
282         }
283     } else {
284         dateTaken = dateAdded;
285     }
286     value.PutLong(MediaColumn::MEDIA_DATE_TAKEN, dateTaken);
287     fileInfo.dateTaken = dateTaken;
288 }
289 
InsertDateAdded(std::unique_ptr<Metadata> & metadata,NativeRdb::ValuesBucket & value)290 static void InsertDateAdded(std::unique_ptr<Metadata> &metadata, NativeRdb::ValuesBucket &value)
291 {
292     int64_t dateAdded = metadata->GetFileDateAdded();
293     if (dateAdded != 0) {
294         value.PutLong(MediaColumn::MEDIA_DATE_ADDED, dateAdded);
295         return;
296     }
297 
298     int64_t dateTaken = metadata->GetDateTaken();
299     if (dateTaken == 0) {
300         int64_t dateModified = metadata->GetFileDateModified();
301         if (dateModified == 0) {
302             dateAdded = MediaFileUtils::UTCTimeMilliSeconds();
303         } else {
304             dateAdded = dateModified;
305         }
306     } else {
307         dateAdded = dateTaken;
308     }
309     value.PutLong(MediaColumn::MEDIA_DATE_ADDED, dateAdded);
310 }
311 
InsertOrientation(std::unique_ptr<Metadata> & metadata,NativeRdb::ValuesBucket & value,FileInfo & fileInfo,int32_t sceneCode)312 static void InsertOrientation(std::unique_ptr<Metadata> &metadata, NativeRdb::ValuesBucket &value,
313     FileInfo &fileInfo, int32_t sceneCode)
314 {
315     bool hasOrientation = value.HasColumn(PhotoColumn::PHOTO_ORIENTATION);
316     if (hasOrientation && fileInfo.fileType != MEDIA_TYPE_VIDEO) {
317         return; // image use orientation in rdb
318     }
319     if (hasOrientation) {
320         value.Delete(PhotoColumn::PHOTO_ORIENTATION);
321     }
322     value.PutInt(PhotoColumn::PHOTO_ORIENTATION, metadata->GetOrientation()); // video use orientation in metadata
323     if (sceneCode == OTHERS_PHONE_CLONE_RESTORE || sceneCode == I_PHONE_CLONE_RESTORE ||
324         sceneCode == LITE_PHONE_CLONE_RESTORE) {
325         fileInfo.orientation = metadata->GetOrientation();
326     }
327 }
328 
SetCoverPosition(const FileInfo & fileInfo,const unique_ptr<Metadata> & imageMetaData,NativeRdb::ValuesBucket & value)329 static void SetCoverPosition(const FileInfo &fileInfo,
330     const unique_ptr<Metadata> &imageMetaData, NativeRdb::ValuesBucket &value)
331 {
332     uint64_t coverPosition = 0;
333     if (BackupFileUtils::IsLivePhoto(fileInfo)) {
334         uint32_t version = 0;
335         uint32_t frameIndex = 0;
336         bool hasCinemagraphInfo = false;
337         string absExtraDataPath;
338         if (!PathToRealPath(fileInfo.extraDataPath, absExtraDataPath)) {
339             MEDIA_ERR_LOG("file is not real path: %{private}s, errno: %{public}d",
340                 fileInfo.extraDataPath.c_str(), errno);
341             value.PutLong(PhotoColumn::PHOTO_COVER_POSITION, static_cast<int64_t>(coverPosition));
342             return;
343         }
344         UniqueFd extraDataFd(open(absExtraDataPath.c_str(), O_RDONLY));
345         (void)MovingPhotoFileUtils::GetVersionAndFrameNum(extraDataFd.Get(), version, frameIndex, hasCinemagraphInfo);
346         (void)MovingPhotoFileUtils::GetCoverPosition(fileInfo.movingPhotoVideoPath,
347             frameIndex, coverPosition, Scene::AV_META_SCENE_CLONE);
348     }
349     value.PutLong(PhotoColumn::PHOTO_COVER_POSITION, static_cast<int64_t>(coverPosition));
350 }
351 
SetValueFromMetaData(FileInfo & fileInfo,NativeRdb::ValuesBucket & value)352 void BaseRestore::SetValueFromMetaData(FileInfo &fileInfo, NativeRdb::ValuesBucket &value)
353 {
354     std::unique_ptr<Metadata> data = make_unique<Metadata>();
355     data->SetFilePath(fileInfo.filePath);
356     data->SetFileMediaType(fileInfo.fileType);
357     data->SetFileDateModified(fileInfo.dateModified);
358     data->SetFileName(fileInfo.displayName);
359     BackupFileUtils::FillMetadata(data);
360     MediaType mediaType = data->GetFileMediaType();
361 
362     value.PutString(MediaColumn::MEDIA_FILE_PATH, data->GetFilePath());
363     value.PutString(MediaColumn::MEDIA_MIME_TYPE, data->GetFileMimeType());
364     value.PutInt(MediaColumn::MEDIA_TYPE, mediaType);
365     value.PutString(MediaColumn::MEDIA_TITLE, data->GetFileTitle());
366     if (fileInfo.fileSize != 0) {
367         value.PutLong(MediaColumn::MEDIA_SIZE, fileInfo.fileSize);
368     } else {
369         MEDIA_WARN_LOG("DB file size is zero!");
370         value.PutLong(MediaColumn::MEDIA_SIZE, data->GetFileSize());
371         fileInfo.fileSize = data->GetFileSize();
372     }
373     value.PutLong(MediaColumn::MEDIA_DATE_MODIFIED, data->GetFileDateModified());
374     value.PutInt(MediaColumn::MEDIA_DURATION, data->GetFileDuration());
375     InsertDateTaken(data, fileInfo, value);
376     value.PutLong(MediaColumn::MEDIA_TIME_PENDING, 0);
377     value.PutInt(PhotoColumn::PHOTO_HEIGHT, data->GetFileHeight());
378     value.PutInt(PhotoColumn::PHOTO_WIDTH, data->GetFileWidth());
379     value.PutDouble(PhotoColumn::PHOTO_LONGITUDE, data->GetLongitude());
380     value.PutDouble(PhotoColumn::PHOTO_LATITUDE, data->GetLatitude());
381     value.PutString(PhotoColumn::PHOTO_ALL_EXIF, data->GetAllExif());
382     value.PutString(PhotoColumn::PHOTO_SHOOTING_MODE, data->GetShootingMode());
383     value.PutString(PhotoColumn::PHOTO_SHOOTING_MODE_TAG, data->GetShootingModeTag());
384     value.PutLong(PhotoColumn::PHOTO_LAST_VISIT_TIME, data->GetLastVisitTime());
385     value.PutString(PhotoColumn::PHOTO_FRONT_CAMERA, data->GetFrontCamera());
386     value.PutInt(PhotoColumn::PHOTO_DYNAMIC_RANGE_TYPE, data->GetDynamicRangeType());
387     InsertDateAdded(data, value);
388     InsertOrientation(data, value, fileInfo, sceneCode_);
389     int64_t dateAdded = 0;
390     NativeRdb::ValueObject valueObject;
391     if (value.GetObject(MediaColumn::MEDIA_DATE_ADDED, valueObject)) {
392         valueObject.GetLong(dateAdded);
393     }
394     fileInfo.dateAdded = dateAdded;
395     value.PutString(PhotoColumn::PHOTO_DATE_YEAR,
396         MediaFileUtils::StrCreateTimeByMilliseconds(PhotoColumn::PHOTO_DATE_YEAR_FORMAT, fileInfo.dateTaken));
397     value.PutString(PhotoColumn::PHOTO_DATE_MONTH,
398         MediaFileUtils::StrCreateTimeByMilliseconds(PhotoColumn::PHOTO_DATE_MONTH_FORMAT, fileInfo.dateTaken));
399     value.PutString(PhotoColumn::PHOTO_DATE_DAY,
400         MediaFileUtils::StrCreateTimeByMilliseconds(PhotoColumn::PHOTO_DATE_DAY_FORMAT, fileInfo.dateTaken));
401     SetCoverPosition(fileInfo, data, value);
402 }
403 
CreateDir(std::string & dir)404 void BaseRestore::CreateDir(std::string &dir)
405 {
406     if (!MediaFileUtils::IsFileExists(dir)) {
407         MediaFileUtils::CreateDirectory(dir);
408     }
409 }
410 
RecursiveCreateDir(std::string & relativePath,std::string & suffix)411 void BaseRestore::RecursiveCreateDir(std::string &relativePath, std::string &suffix)
412 {
413     CreateDir(relativePath);
414     size_t pos = suffix.find('/');
415     if (pos == std::string::npos) {
416         return;
417     }
418     std::string prefix = suffix.substr(0, pos + 1);
419     std::string suffixTmp = suffix.erase(0, prefix.length());
420     prefix = relativePath + prefix;
421     RecursiveCreateDir(prefix, suffixTmp);
422 }
423 
InsertAudio(int32_t sceneCode,std::vector<FileInfo> & fileInfos)424 void BaseRestore::InsertAudio(int32_t sceneCode, std::vector<FileInfo> &fileInfos)
425 {
426     if (fileInfos.empty()) {
427         MEDIA_ERR_LOG("fileInfos are empty");
428         return;
429     }
430     int64_t startMove = MediaFileUtils::UTCTimeMilliSeconds();
431     int32_t fileMoveCount = 0;
432     for (size_t i = 0; i < fileInfos.size(); i++) {
433         if (!MediaFileUtils::IsFileExists(fileInfos[i].filePath)) {
434             MEDIA_ERR_LOG("File is not exist: filePath: %{public}s, size: %{public}lld",
435                 BackupFileUtils::GarbleFilePath(fileInfos[i].filePath, sceneCode).c_str(),
436                 (long long)fileInfos[i].fileSize);
437             continue;
438         }
439         string relativePath0 = RESTORE_MUSIC_LOCAL_DIR;
440         string relativePath1 = fileInfos[i].relativePath;
441         if (relativePath1[0] == '/') {
442             relativePath1.erase(0, 1);
443         }
444         string dstPath = RESTORE_MUSIC_LOCAL_DIR + relativePath1;
445         RecursiveCreateDir(relativePath0, relativePath1);
446         if (MediaFileUtils::IsFileExists(dstPath)) {
447             MEDIA_INFO_LOG("dstPath %{public}s already exists.",
448                 BackupFileUtils::GarbleFilePath(fileInfos[i].filePath, sceneCode).c_str());
449             UpdateDuplicateNumber(fileInfos[i].fileType);
450             continue;
451         }
452         int32_t moveErrCode = BackupFileUtils::MoveFile(fileInfos[i].filePath, dstPath, sceneCode);
453         if (moveErrCode != E_SUCCESS) {
454             MEDIA_ERR_LOG("MoveFile failed, filePath: %{public}s, errCode: %{public}d, errno: %{public}d",
455                 BackupFileUtils::GarbleFilePath(fileInfos[i].filePath, sceneCode).c_str(), moveErrCode, errno);
456             UpdateFailedFiles(fileInfos[i].fileType, fileInfos[i], RestoreError::MOVE_FAILED);
457             continue;
458         }
459         BackupFileUtils::ModifyFile(dstPath, fileInfos[i].dateModified / MSEC_TO_SEC);
460         fileMoveCount++;
461     }
462     migrateAudioFileNumber_ += fileMoveCount;
463     int64_t end = MediaFileUtils::UTCTimeMilliSeconds();
464     MEDIA_INFO_LOG("move %{public}ld file cost %{public}ld.", (long)fileMoveCount, (long)(end - startMove));
465 }
466 
MoveExtraData(const FileInfo & fileInfo,int32_t sceneCode)467 static bool MoveExtraData(const FileInfo &fileInfo, int32_t sceneCode)
468 {
469     string localExtraDataDir = BackupFileUtils::GetReplacedPathByPrefixType(
470         PrefixType::CLOUD, PrefixType::LOCAL, MovingPhotoFileUtils::GetMovingPhotoExtraDataDir(fileInfo.cloudPath));
471     if (localExtraDataDir.empty()) {
472         MEDIA_WARN_LOG("Failed to get local extra data dir");
473         return false;
474     }
475     if (!MediaFileUtils::IsFileExists(localExtraDataDir) && !MediaFileUtils::CreateDirectory(localExtraDataDir)) {
476         MEDIA_WARN_LOG("Failed to create local extra data dir, errno:%{public}d", errno);
477         return false;
478     }
479 
480     string localExtraDataPath = BackupFileUtils::GetReplacedPathByPrefixType(
481         PrefixType::CLOUD, PrefixType::LOCAL, MovingPhotoFileUtils::GetMovingPhotoExtraDataPath(fileInfo.cloudPath));
482     if (localExtraDataPath.empty()) {
483         MEDIA_WARN_LOG("Failed to get local extra data path");
484         return false;
485     }
486     int32_t errCode = BackupFileUtils::MoveFile(fileInfo.extraDataPath, localExtraDataPath, sceneCode);
487     if (errCode != E_OK) {
488         MEDIA_WARN_LOG("MoveFile failed, src:%{public}s, dest:%{public}s, err:%{public}d, errno:%{public}d",
489             BackupFileUtils::GarbleFilePath(fileInfo.extraDataPath, sceneCode).c_str(),
490             BackupFileUtils::GarbleFilePath(localExtraDataPath, sceneCode).c_str(), errCode, errno);
491         return false;
492     }
493     return true;
494 }
495 
MoveAndModifyFile(const FileInfo & fileInfo,int32_t sceneCode)496 static bool MoveAndModifyFile(const FileInfo &fileInfo, int32_t sceneCode)
497 {
498     string tmpPath = fileInfo.cloudPath;
499     string localPath = tmpPath.replace(0, RESTORE_CLOUD_DIR.length(), RESTORE_LOCAL_DIR);
500     int32_t errCode = BackupFileUtils::MoveFile(fileInfo.filePath, localPath, sceneCode);
501     if (errCode != E_OK) {
502         MEDIA_ERR_LOG("MoveFile failed, src:%{public}s, dest:%{public}s, err:%{public}d, errno:%{public}d",
503             BackupFileUtils::GarbleFilePath(fileInfo.filePath, sceneCode).c_str(),
504             BackupFileUtils::GarbleFilePath(localPath, sceneCode).c_str(), errCode, errno);
505         return false;
506     }
507     BackupFileUtils::ModifyFile(localPath, fileInfo.dateModified / MSEC_TO_SEC);
508 
509     if (BackupFileUtils::IsLivePhoto(fileInfo)) {
510         string tmpVideoPath = MovingPhotoFileUtils::GetMovingPhotoVideoPath(fileInfo.cloudPath);
511         string localVideoPath = tmpVideoPath.replace(0, RESTORE_CLOUD_DIR.length(), RESTORE_LOCAL_DIR);
512         errCode = BackupFileUtils::MoveFile(fileInfo.movingPhotoVideoPath, localVideoPath, sceneCode);
513         if (errCode != E_OK) {
514             MEDIA_ERR_LOG(
515                 "MoveFile failed for mov video, src:%{public}s, dest:%{public}s, err:%{public}d, errno:%{public}d",
516                 BackupFileUtils::GarbleFilePath(fileInfo.movingPhotoVideoPath, sceneCode).c_str(),
517                 BackupFileUtils::GarbleFilePath(localVideoPath, sceneCode).c_str(), errCode, errno);
518             (void)MediaFileUtils::DeleteFile(localPath);
519             return false;
520         }
521         BackupFileUtils::ModifyFile(localVideoPath, fileInfo.dateModified / MSEC_TO_SEC);
522         return MoveExtraData(fileInfo, sceneCode);
523     }
524     return true;
525 }
526 
MoveMigrateFile(std::vector<FileInfo> & fileInfos,int32_t & fileMoveCount,int32_t & videoFileMoveCount,int32_t sceneCode)527 void BaseRestore::MoveMigrateFile(std::vector<FileInfo> &fileInfos, int32_t &fileMoveCount, int32_t &videoFileMoveCount,
528     int32_t sceneCode)
529 {
530     vector<std::string> moveFailedData;
531     for (size_t i = 0; i < fileInfos.size(); i++) {
532         if (!fileInfos[i].needMove) {
533             continue;
534         }
535         if (IsFileValid(fileInfos[i], sceneCode) != E_OK) {
536             continue;
537         }
538         if (!MoveAndModifyFile(fileInfos[i], sceneCode)) {
539             fileInfos[i].updateMap.clear();
540             UpdateFailedFiles(fileInfos[i].fileType, fileInfos[i], RestoreError::MOVE_FAILED);
541             ErrorInfo errorInfo(RestoreError::MOVE_FAILED, 1, strerror(errno),
542                 BackupLogUtils::FileInfoToString(sceneCode, fileInfos[i]));
543             UpgradeRestoreTaskReport().SetSceneCode(this->sceneCode_).SetTaskId(this->taskId_).ReportError(errorInfo);
544             moveFailedData.push_back(fileInfos[i].cloudPath);
545             continue;
546         }
547         fileMoveCount++;
548         videoFileMoveCount += fileInfos[i].fileType == MediaType::MEDIA_TYPE_VIDEO;
549     }
550     DeleteMoveFailedData(moveFailedData);
551     migrateFileNumber_ += fileMoveCount;
552     migrateVideoFileNumber_ += videoFileMoveCount;
553 }
554 
InsertPhoto(int32_t sceneCode,std::vector<FileInfo> & fileInfos,int32_t sourceType)555 int BaseRestore::InsertPhoto(int32_t sceneCode, std::vector<FileInfo> &fileInfos, int32_t sourceType)
556 {
557     MEDIA_INFO_LOG("Start insert %{public}zu photos", fileInfos.size());
558     if (mediaLibraryRdb_ == nullptr) {
559         MEDIA_ERR_LOG("mediaLibraryRdb_ is null");
560         return E_OK;
561     }
562     if (fileInfos.empty()) {
563         MEDIA_ERR_LOG("fileInfos are empty");
564         return E_OK;
565     }
566     int64_t startGenerate = MediaFileUtils::UTCTimeMilliSeconds();
567     vector<NativeRdb::ValuesBucket> values = GetInsertValues(sceneCode, fileInfos, sourceType);
568     int64_t startInsert = MediaFileUtils::UTCTimeMilliSeconds();
569     int64_t rowNum = 0;
570     int32_t errCode = BatchInsertWithRetry(PhotoColumn::PHOTOS_TABLE, values, rowNum);
571     if (errCode != E_OK) {
572         if (needReportFailed_) {
573             UpdateFailedFiles(fileInfos, RestoreError::INSERT_FAILED);
574             ErrorInfo errorInfo(RestoreError::INSERT_FAILED, static_cast<int32_t>(fileInfos.size()), errCode);
575             UpgradeRestoreTaskReport().SetSceneCode(this->sceneCode_).SetTaskId(this->taskId_).ReportError(errorInfo);
576         }
577         return errCode;
578     }
579 
580     int64_t startInsertRelated = MediaFileUtils::UTCTimeMilliSeconds();
581     InsertPhotoRelated(fileInfos, sourceType);
582 
583     int64_t startMove = MediaFileUtils::UTCTimeMilliSeconds();
584     migrateDatabaseNumber_ += rowNum;
585     int32_t fileMoveCount = 0;
586     int32_t videoFileMoveCount = 0;
587     MoveMigrateFile(fileInfos, fileMoveCount, videoFileMoveCount, sceneCode);
588     this->tabOldPhotosRestore_.Restore(this->mediaLibraryRdb_, fileInfos);
589     int64_t startUpdate = MediaFileUtils::UTCTimeMilliSeconds();
590     UpdatePhotosByFileInfoMap(mediaLibraryRdb_, fileInfos);
591     int64_t end = MediaFileUtils::UTCTimeMilliSeconds();
592     MEDIA_INFO_LOG("generate values cost %{public}ld, insert %{public}ld assets cost %{public}ld, insert photo related"
593         " cost %{public}ld, and move %{public}ld files (%{public}ld + %{public}ld) cost %{public}ld. update cost"
594         " %{public}ld.",
595         (long)(startInsert - startGenerate), (long)rowNum, (long)(startInsertRelated - startInsert),
596         (long)(startMove - startInsertRelated), (long)fileMoveCount, (long)(fileMoveCount - videoFileMoveCount),
597         (long)videoFileMoveCount, (long)(startUpdate - startMove), long(end - startUpdate));
598     return E_OK;
599 }
600 
DeleteMoveFailedData(std::vector<std::string> & moveFailedData)601 void BaseRestore::DeleteMoveFailedData(std::vector<std::string> &moveFailedData)
602 {
603     if (moveFailedData.empty()) {
604         MEDIA_INFO_LOG("No move failed");
605         return;
606     }
607     MEDIA_INFO_LOG("%{public}d file move failed", static_cast<int>(moveFailedData.size()));
608     NativeRdb::AbsRdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
609     predicates.In(MediaColumn::MEDIA_FILE_PATH, moveFailedData);
610     int32_t changedRows = 0;
611     int deleteRes = BackupDatabaseUtils::Delete(predicates, changedRows, mediaLibraryRdb_);
612     MEDIA_INFO_LOG("changeRows:%{public}d, deleteRes:%{public}d", changedRows, deleteRes);
613 }
614 
BatchInsertWithRetry(const std::string & tableName,std::vector<NativeRdb::ValuesBucket> & values,int64_t & rowNum)615 int32_t BaseRestore::BatchInsertWithRetry(const std::string &tableName, std::vector<NativeRdb::ValuesBucket> &values,
616     int64_t &rowNum)
617 {
618     if (values.empty()) {
619         return 0;
620     }
621 
622     int32_t errCode = E_ERR;
623     TransactionOperations trans{ __func__ };
624     trans.SetBackupRdbStore(mediaLibraryRdb_);
625     std::function<int(void)> func = [&]()->int {
626         errCode = trans.BatchInsert(rowNum, tableName, values);
627         if (errCode != E_OK) {
628             MEDIA_ERR_LOG("InsertSql failed, errCode: %{public}d, rowNum: %{public}ld.", errCode, (long)rowNum);
629         }
630         return errCode;
631     };
632     errCode = trans.RetryTrans(func, true);
633     if (errCode != E_OK) {
634         MEDIA_ERR_LOG("BatchInsertWithRetry: tans finish fail!, ret:%{public}d", errCode);
635     }
636     return errCode;
637 }
638 
MoveDirectory(const std::string & srcDir,const std::string & dstDir,bool deleteOriginalFile) const639 int32_t BaseRestore::MoveDirectory(const std::string &srcDir, const std::string &dstDir, bool deleteOriginalFile) const
640 {
641     if (!MediaFileUtils::CreateDirectory(dstDir)) {
642         MEDIA_ERR_LOG("Create dstDir %{public}s failed",
643             BackupFileUtils::GarbleFilePath(dstDir, DEFAULT_RESTORE_ID).c_str());
644         return E_FAIL;
645     }
646     if (!MediaFileUtils::IsFileExists(srcDir)) {
647         MEDIA_WARN_LOG("%{public}s doesn't exist, skip.", srcDir.c_str());
648         return E_OK;
649     }
650     for (const auto &dirEntry : std::filesystem::directory_iterator{ srcDir }) {
651         std::string srcFilePath = dirEntry.path();
652         std::string tmpFilePath = srcFilePath;
653         std::string dstFilePath = tmpFilePath.replace(0, srcDir.length(), dstDir);
654         int32_t opRet = E_FAIL;
655         if (deleteOriginalFile) {
656             opRet = this->MoveFile(srcFilePath, dstFilePath);
657         } else {
658             opRet = this->CopyFile(srcFilePath, dstFilePath);
659         }
660         if (opRet != E_OK) {
661             MEDIA_ERR_LOG("Move file from %{public}s to %{public}s failed, deleteOriginalFile=%{public}d",
662                 BackupFileUtils::GarbleFilePath(srcFilePath, sceneCode_).c_str(),
663                 BackupFileUtils::GarbleFilePath(dstFilePath, DEFAULT_RESTORE_ID).c_str(),
664                 deleteOriginalFile);
665             return E_FAIL;
666         }
667     }
668     return E_OK;
669 }
670 
IsSameAudioFile(const std::shared_ptr<NativeRdb::RdbStore> & rdbStore,const std::string & tableName,FileInfo & fileInfo)671 bool BaseRestore::IsSameAudioFile(const std::shared_ptr<NativeRdb::RdbStore> &rdbStore, const std::string &tableName,
672     FileInfo &fileInfo)
673 {
674     string srcPath = fileInfo.filePath;
675     string dstPath = BackupFileUtils::GetFullPathByPrefixType(PrefixType::LOCAL, fileInfo.relativePath);
676     struct stat srcStatInfo {};
677     struct stat dstStatInfo {};
678 
679     if (access(dstPath.c_str(), F_OK)) {
680         return false;
681     }
682     if (stat(srcPath.c_str(), &srcStatInfo) != 0) {
683         MEDIA_ERR_LOG("Failed to get file %{private}s StatInfo, err=%{public}d", srcPath.c_str(), errno);
684         return false;
685     }
686     if (stat(dstPath.c_str(), &dstStatInfo) != 0) {
687         MEDIA_ERR_LOG("Failed to get file %{private}s StatInfo, err=%{public}d", dstPath.c_str(), errno);
688         return false;
689     }
690     if ((srcStatInfo.st_size != dstStatInfo.st_size || srcStatInfo.st_mtime != dstStatInfo.st_mtime) &&
691         !HasSameAudioFile(rdbStore, tableName, fileInfo)) { /* file size & last modify time */
692         MEDIA_INFO_LOG("Size (%{public}lld -> %{public}lld) or mtime (%{public}lld -> %{public}lld) differs",
693             (long long)srcStatInfo.st_size, (long long)dstStatInfo.st_size, (long long)srcStatInfo.st_mtime,
694             (long long)dstStatInfo.st_mtime);
695         return false;
696     }
697     fileInfo.isNew = false;
698     return true;
699 }
700 
HasSameAudioFile(const std::shared_ptr<NativeRdb::RdbStore> & rdbStore,const std::string & tableName,FileInfo & fileInfo)701 bool BaseRestore::HasSameAudioFile(const std::shared_ptr<NativeRdb::RdbStore> &rdbStore, const std::string &tableName,
702     FileInfo &fileInfo)
703 {
704     string querySql = "SELECT " + MediaColumn::MEDIA_ID + ", " + MediaColumn::MEDIA_FILE_PATH + " FROM " +
705         tableName + " WHERE " + MediaColumn::MEDIA_NAME + " = '" + fileInfo.displayName + "' AND " +
706         MediaColumn::MEDIA_SIZE + " = " + to_string(fileInfo.fileSize) + " AND " +
707         MediaColumn::MEDIA_DATE_MODIFIED + " = " + to_string(fileInfo.dateModified);
708     querySql += " LIMIT 1";
709     auto resultSet = BackupDatabaseUtils::GetQueryResultSet(rdbStore, querySql);
710     if (resultSet == nullptr || resultSet->GoToFirstRow() != NativeRdb::E_OK) {
711         return false;
712     }
713     int32_t fileId = GetInt32Val(MediaColumn::MEDIA_ID, resultSet);
714     string cloudPath = GetStringVal(MediaColumn::MEDIA_FILE_PATH, resultSet);
715     if (fileId <= 0 || cloudPath.empty()) {
716         return false;
717     }
718     fileInfo.fileIdNew = fileId;
719     fileInfo.cloudPath = cloudPath;
720     return true;
721 }
722 
InsertPhotoMap(std::vector<FileInfo> & fileInfos,int64_t & mapRowNum)723 void BaseRestore::InsertPhotoMap(std::vector<FileInfo> &fileInfos, int64_t &mapRowNum)
724 {
725     BatchInsertMap(fileInfos, mapRowNum);
726     migrateDatabaseMapNumber_ += mapRowNum;
727 }
728 
BatchQueryPhoto(vector<FileInfo> & fileInfos,bool isFull,const NeedQueryMap & needQueryMap)729 void BaseRestore::BatchQueryPhoto(vector<FileInfo> &fileInfos, bool isFull, const NeedQueryMap &needQueryMap)
730 {
731     string querySql = "SELECT " + MediaColumn::MEDIA_ID + " , " + MediaColumn::MEDIA_FILE_PATH + " FROM " +
732         PhotoColumn::PHOTOS_TABLE + " WHERE ";
733     bool firstSql = false;
734     std::vector<std::string> cloudPathArgs;
735     for (auto &fileInfo : fileInfos) {
736         if (!isFull && !NeedQuery(fileInfo, needQueryMap)) {
737             continue;
738         }
739         if (firstSql) {
740             querySql += " OR ";
741         } else {
742             firstSql = true;
743         }
744         querySql += MediaColumn::MEDIA_FILE_PATH + " = ? ";
745         cloudPathArgs.push_back(fileInfo.cloudPath);
746     }
747     auto result = BackupDatabaseUtils::GetQueryResultSet(mediaLibraryRdb_, querySql, cloudPathArgs);
748     if (result == nullptr) {
749         MEDIA_ERR_LOG("Query resultSql is null.");
750         return;
751     }
752     while (result->GoToNextRow() == NativeRdb::E_OK) {
753         int32_t fileId = GetInt32Val(MediaColumn::MEDIA_ID, result);
754         std::string path = GetStringVal(MediaColumn::MEDIA_FILE_PATH, result);
755         auto pathMatch = [path {path}](const auto &fileInfo) {
756             return fileInfo.cloudPath == path;
757         };
758         auto it = std::find_if(fileInfos.begin(), fileInfos.end(), pathMatch);
759         if (it != fileInfos.end() && fileId > 0) {
760             it->fileIdNew = fileId;
761         }
762     }
763 }
764 
BatchInsertMap(const vector<FileInfo> & fileInfos,int64_t & totalRowNum)765 void BaseRestore::BatchInsertMap(const vector<FileInfo> &fileInfos, int64_t &totalRowNum)
766 {
767     vector<NativeRdb::ValuesBucket> values;
768     for (const auto &fileInfo : fileInfos) {
769         if (!fileInfo.packageName.empty()) {
770             // add for trigger insert_photo_insert_source_album
771             continue;
772         }
773         if (fileInfo.cloudPath.empty() || fileInfo.mediaAlbumId <= 0 || fileInfo.fileIdNew <= 0) {
774             MEDIA_ERR_LOG("AlbumMap error file name = %{public}s.", fileInfo.displayName.c_str());
775             continue;
776         }
777         NativeRdb::ValuesBucket value;
778         value.PutInt(PhotoMap::ASSET_ID, fileInfo.fileIdNew);
779         value.PutInt(PhotoMap::ALBUM_ID, fileInfo.mediaAlbumId);
780         values.emplace_back(value);
781     }
782     int64_t rowNum = 0;
783     int32_t errCode = BatchInsertWithRetry(PhotoMap::TABLE, values, rowNum);
784     if (errCode != E_OK) {
785         MEDIA_ERR_LOG("Batch insert map failed, errCode: %{public}d", errCode);
786     }
787     totalRowNum += rowNum;
788 }
789 
StartRestoreEx(const std::string & backupRetoreDir,const std::string & upgradePath,std::string & restoreExInfo)790 void BaseRestore::StartRestoreEx(const std::string &backupRetoreDir, const std::string &upgradePath,
791                                  std::string &restoreExInfo)
792 {
793     UpgradeRestoreTaskReport()
794         .SetSceneCode(this->sceneCode_)
795         .SetTaskId(this->taskId_)
796         .ReportProgress("start", std::to_string(MediaFileUtils::UTCTimeSeconds()));
797     StartRestore(backupRetoreDir, upgradePath);
798     DatabaseReport()
799         .SetSceneCode(this->sceneCode_)
800         .SetTaskId(this->taskId_)
801         .ReportMedia(this->mediaLibraryRdb_, DatabaseReport::PERIOD_AFTER);
802     restoreExInfo = GetRestoreExInfo();
803     UpgradeRestoreTaskReport()
804         .SetSceneCode(this->sceneCode_)
805         .SetTaskId(this->taskId_)
806         .ReportTask(restoreExInfo)
807         .ReportTotal(std::to_string(errorCode_), GetRestoreTotalInfo())
808         .ReportTimeCost()
809         .ReportProgress("end", std::to_string(MediaFileUtils::UTCTimeSeconds()));
810 }
811 
GetRestoreExInfo()812 std::string BaseRestore::GetRestoreExInfo()
813 {
814     nlohmann::json restoreExInfoJson;
815     restoreExInfoJson[STAT_KEY_RESULT_INFO] = { GetErrorInfoJson(), GetCountInfoJson(STAT_TYPES) };
816     return restoreExInfoJson.dump();
817 }
818 
GetErrorInfoJson()819 nlohmann::json BaseRestore::GetErrorInfoJson()
820 {
821     int32_t errorCode = errorCode_ == RestoreError::SUCCESS ? STAT_DEFAULT_ERROR_CODE_SUCCESS :
822         STAT_DEFAULT_ERROR_CODE_FAILED;
823     nlohmann::json errorInfoJson = {
824         { STAT_KEY_TYPE, STAT_VALUE_ERROR_INFO },
825         { STAT_KEY_ERROR_CODE, std::to_string(errorCode) },
826         { STAT_KEY_ERROR_INFO, errorInfo_ }
827     };
828     return errorInfoJson;
829 }
830 
GetCountInfoJson(const std::vector<std::string> & countInfoTypes)831 nlohmann::json BaseRestore::GetCountInfoJson(const std::vector<std::string> &countInfoTypes)
832 {
833     nlohmann::json countInfoJson;
834     countInfoJson[STAT_KEY_TYPE] = STAT_VALUE_COUNT_INFO;
835     size_t limit = MAX_FAILED_FILES_LIMIT;
836     for (const auto &type : countInfoTypes) {
837         SubCountInfo subCountInfo = GetSubCountInfo(type);
838         MEDIA_INFO_LOG("SubCountInfo %{public}s success: %{public}lld, duplicate: %{public}lld, failed: %{public}zu",
839             type.c_str(), (long long)subCountInfo.successCount, (long long)subCountInfo.duplicateCount,
840             subCountInfo.failedFiles.size());
841         countInfoJson[STAT_KEY_INFOS].push_back(GetSubCountInfoJson(type, subCountInfo, limit));
842     }
843     return countInfoJson;
844 }
845 
GetSubCountInfo(const std::string & type)846 SubCountInfo BaseRestore::GetSubCountInfo(const std::string &type)
847 {
848     std::unordered_map<std::string, FailedFileInfo> failedFiles = GetFailedFiles(type);
849     if (type == STAT_TYPE_PHOTO) {
850         return SubCountInfo(migrateFileNumber_ - migrateVideoFileNumber_, migratePhotoDuplicateNumber_, failedFiles);
851     }
852     if (type == STAT_TYPE_VIDEO) {
853         return SubCountInfo(migrateVideoFileNumber_, migrateVideoDuplicateNumber_, failedFiles);
854     }
855     return SubCountInfo(migrateAudioFileNumber_, migrateAudioDuplicateNumber_, failedFiles);
856 }
857 
GetFailedFiles(const std::string & type)858 std::unordered_map<std::string, FailedFileInfo> BaseRestore::GetFailedFiles(const std::string &type)
859 {
860     std::lock_guard<mutex> lock(failedFilesMutex_);
861     std::unordered_map<std::string, FailedFileInfo> failedFiles;
862     auto iter = failedFilesMap_.find(type);
863     if (iter != failedFilesMap_.end()) {
864         return iter->second;
865     }
866     return failedFiles;
867 }
868 
GetSubCountInfoJson(const std::string & type,const SubCountInfo & subCountInfo,size_t & limit)869 nlohmann::json BaseRestore::GetSubCountInfoJson(const std::string &type, const SubCountInfo &subCountInfo,
870     size_t &limit)
871 {
872     nlohmann::json subCountInfoJson;
873     subCountInfoJson[STAT_KEY_BACKUP_INFO] = type;
874     subCountInfoJson[STAT_KEY_SUCCESS_COUNT] = subCountInfo.successCount;
875     subCountInfoJson[STAT_KEY_DUPLICATE_COUNT] = subCountInfo.duplicateCount;
876     subCountInfoJson[STAT_KEY_FAILED_COUNT] = subCountInfo.failedFiles.size();
877     // update currentLimit = min(limit, failedFiles.size())
878     size_t currentLimit = limit <= subCountInfo.failedFiles.size() ? limit : subCountInfo.failedFiles.size();
879     std::string detailsPath;
880     std::vector<std::string> failedFilesList;
881     if (sceneCode_ == UPGRADE_RESTORE_ID) {
882         detailsPath = BackupFileUtils::GetDetailsPath(DEFAULT_RESTORE_ID, type, subCountInfo.failedFiles, currentLimit);
883         subCountInfoJson[STAT_KEY_DETAILS] = detailsPath;
884     } else {
885         failedFilesList = BackupFileUtils::GetFailedFilesList(DEFAULT_RESTORE_ID, subCountInfo.failedFiles,
886             currentLimit);
887         subCountInfoJson[STAT_KEY_DETAILS] = failedFilesList;
888     }
889     MEDIA_INFO_LOG("Get %{public}s details size: %{public}zu", type.c_str(), currentLimit);
890     limit -= currentLimit; // update total limit
891     return subCountInfoJson;
892 }
893 
GetBackupInfo()894 std::string BaseRestore::GetBackupInfo()
895 {
896     return "";
897 }
898 
SetErrorCode(int32_t errorCode)899 void BaseRestore::SetErrorCode(int32_t errorCode)
900 {
901     errorCode_ = errorCode;
902     errorInfo_ = BackupLogUtils::RestoreErrorToString(errorCode);
903 }
904 
UpdateFailedFileByFileType(int32_t fileType,const FileInfo & fileInfo,int32_t errorCode)905 void BaseRestore::UpdateFailedFileByFileType(int32_t fileType, const FileInfo &fileInfo, int32_t errorCode)
906 {
907     std::lock_guard<mutex> lock(failedFilesMutex_);
908     FailedFileInfo failedFileInfo(sceneCode_, fileInfo, errorCode);
909     if (fileType == static_cast<int32_t>(MediaType::MEDIA_TYPE_IMAGE)) {
910         failedFilesMap_[STAT_TYPE_PHOTO].emplace(fileInfo.oldPath, failedFileInfo);
911         return;
912     }
913     if (fileType == static_cast<int32_t>(MediaType::MEDIA_TYPE_VIDEO)) {
914         failedFilesMap_[STAT_TYPE_VIDEO].emplace(fileInfo.oldPath, failedFileInfo);
915         return;
916     }
917     if (fileType == static_cast<int32_t>(MediaType::MEDIA_TYPE_AUDIO)) {
918         failedFilesMap_[STAT_TYPE_AUDIO].emplace(fileInfo.oldPath, failedFileInfo);
919         return;
920     }
921     MEDIA_ERR_LOG("Unsupported file type: %{public}d", fileType);
922 }
923 
UpdateFailedFiles(int32_t fileType,const FileInfo & fileInfo,int32_t errorCode)924 void BaseRestore::UpdateFailedFiles(int32_t fileType, const FileInfo &fileInfo, int32_t errorCode)
925 {
926     SetErrorCode(errorCode);
927     UpdateFailedFileByFileType(fileType, fileInfo, errorCode);
928 }
929 
UpdateFailedFiles(const std::vector<FileInfo> & fileInfos,int32_t errorCode)930 void BaseRestore::UpdateFailedFiles(const std::vector<FileInfo> &fileInfos, int32_t errorCode)
931 {
932     SetErrorCode(errorCode);
933     for (const auto &fileInfo : fileInfos) {
934         UpdateFailedFileByFileType(fileInfo.fileType, fileInfo, errorCode);
935     }
936 }
937 
UpdateDuplicateNumber(int32_t fileType)938 void BaseRestore::UpdateDuplicateNumber(int32_t fileType)
939 {
940     if (fileType == static_cast<int32_t>(MediaType::MEDIA_TYPE_IMAGE)) {
941         migratePhotoDuplicateNumber_++;
942         return;
943     }
944     if (fileType == static_cast<int32_t>(MediaType::MEDIA_TYPE_VIDEO)) {
945         migrateVideoDuplicateNumber_++;
946         return;
947     }
948     if (fileType == static_cast<int32_t>(MediaType::MEDIA_TYPE_AUDIO)) {
949         migrateAudioDuplicateNumber_++;
950         return;
951     }
952     MEDIA_ERR_LOG("Unsupported file type: %{public}d", fileType);
953 }
954 
SetParameterForClone()955 void BaseRestore::SetParameterForClone()
956 {
957     auto currentTime = to_string(MediaFileUtils::UTCTimeSeconds());
958     MEDIA_INFO_LOG("SetParameterForClone currentTime:%{public}s", currentTime.c_str());
959     bool retFlag = system::SetParameter(CLONE_FLAG, currentTime);
960     if (!retFlag) {
961         MEDIA_ERR_LOG("Failed to set parameter cloneFlag, retFlag:%{public}d", retFlag);
962     }
963 }
964 
StopParameterForClone(int32_t sceneCode)965 void BaseRestore::StopParameterForClone(int32_t sceneCode)
966 {
967     bool retFlag = system::SetParameter(CLONE_FLAG, "0");
968     if (!retFlag) {
969         MEDIA_ERR_LOG("Failed to set parameter cloneFlag, retFlag:%{public}d", retFlag);
970     }
971 }
972 
InsertPhotoRelated(std::vector<FileInfo> & fileInfos,int32_t sourceType)973 void BaseRestore::InsertPhotoRelated(std::vector<FileInfo> &fileInfos, int32_t sourceType)
974 {
975     if (sourceType != SourceType::GALLERY) {
976         return;
977     }
978     NeedQueryMap needQueryMap;
979     if (!NeedBatchQueryPhoto(fileInfos, needQueryMap)) {
980         MEDIA_INFO_LOG("There is no need to batch query photo");
981         return;
982     }
983     int64_t startQuery = MediaFileUtils::UTCTimeMilliSeconds();
984     BatchQueryPhoto(fileInfos, false, needQueryMap);
985     int64_t startInsertMap = MediaFileUtils::UTCTimeMilliSeconds();
986     int64_t mapRowNum = 0;
987     InsertPhotoMap(fileInfos, mapRowNum);
988     int64_t startInsertPortrait = MediaFileUtils::UTCTimeMilliSeconds();
989     int64_t faceRowNum = 0;
990     int64_t portraitMapRowNum = 0;
991     int64_t portraitPhotoNum = 0;
992     InsertFaceAnalysisData(fileInfos, needQueryMap, faceRowNum, portraitMapRowNum, portraitPhotoNum);
993     int64_t end = MediaFileUtils::UTCTimeMilliSeconds();
994     MEDIA_INFO_LOG("query cost %{public}ld, insert %{public}ld maps cost %{public}ld, insert face analysis data of "
995         "%{public}ld photos (%{public}ld faces + %{public}ld maps) cost %{public}ld",
996         (long)(startInsertMap - startQuery), (long)mapRowNum, (long)(startInsertPortrait - startInsertMap),
997         (long)portraitPhotoNum, (long)faceRowNum, (long)portraitMapRowNum, (long)(end - startInsertPortrait));
998 }
999 
NeedBatchQueryPhoto(const std::vector<FileInfo> & fileInfos,NeedQueryMap & needQueryMap)1000 bool BaseRestore::NeedBatchQueryPhoto(const std::vector<FileInfo> &fileInfos, NeedQueryMap &needQueryMap)
1001 {
1002     return NeedBatchQueryPhotoForPhotoMap(fileInfos, needQueryMap) ||
1003         NeedBatchQueryPhotoForPortrait(fileInfos, needQueryMap);
1004 }
1005 
NeedBatchQueryPhotoForPhotoMap(const std::vector<FileInfo> & fileInfos,NeedQueryMap & needQueryMap)1006 bool BaseRestore::NeedBatchQueryPhotoForPhotoMap(const std::vector<FileInfo> &fileInfos, NeedQueryMap &needQueryMap)
1007 {
1008     std::unordered_set<std::string> needQuerySet;
1009     for (const auto &fileInfo : fileInfos) {
1010         if (!fileInfo.packageName.empty()) {
1011             continue;
1012         }
1013         if (fileInfo.cloudPath.empty() || fileInfo.mediaAlbumId <= 0) {
1014             MEDIA_ERR_LOG("Album error file name = %{public}s.", fileInfo.displayName.c_str());
1015             continue;
1016         }
1017         needQuerySet.insert(fileInfo.cloudPath);
1018     }
1019     if (needQuerySet.empty()) {
1020         return false;
1021     }
1022     needQueryMap[PhotoRelatedType::PHOTO_MAP] = needQuerySet;
1023     return true;
1024 }
1025 
NeedBatchQueryPhotoForPortrait(const std::vector<FileInfo> & fileInfos,NeedQueryMap & needQueryMap)1026 bool BaseRestore::NeedBatchQueryPhotoForPortrait(const std::vector<FileInfo> &fileInfos, NeedQueryMap &needQueryMap)
1027 {
1028     return false;
1029 }
1030 
NeedQuery(const FileInfo & fileInfo,const NeedQueryMap & needQueryMap)1031 bool BaseRestore::NeedQuery(const FileInfo &fileInfo, const NeedQueryMap &needQueryMap)
1032 {
1033     for (auto iter = needQueryMap.begin(); iter != needQueryMap.end(); ++iter) {
1034         if (NeedQueryByPhotoRelatedType(fileInfo, iter->first, iter->second)) {
1035             return true;
1036         }
1037     }
1038     return false;
1039 }
1040 
NeedQueryByPhotoRelatedType(const FileInfo & fileInfo,PhotoRelatedType photoRelatedType,const std::unordered_set<std::string> & needQuerySet)1041 bool BaseRestore::NeedQueryByPhotoRelatedType(const FileInfo &fileInfo, PhotoRelatedType photoRelatedType,
1042     const std::unordered_set<std::string> &needQuerySet)
1043 {
1044     std::string searchPath;
1045     switch (photoRelatedType) {
1046         case PhotoRelatedType::PHOTO_MAP: {
1047             searchPath = fileInfo.cloudPath;
1048             break;
1049         }
1050         case PhotoRelatedType::PORTRAIT: {
1051             searchPath = fileInfo.hashCode;
1052             break;
1053         }
1054         default:
1055             MEDIA_ERR_LOG("Unsupported photo related type: %{public}d", static_cast<int32_t>(photoRelatedType));
1056     }
1057     return !searchPath.empty() && needQuerySet.count(searchPath) > 0;
1058 }
1059 
InsertFaceAnalysisData(const std::vector<FileInfo> & fileInfos,const NeedQueryMap & needQueryMap,int64_t & faceRowNum,int64_t & mapRowNum,int64_t & photoNum)1060 void BaseRestore::InsertFaceAnalysisData(const std::vector<FileInfo> &fileInfos, const NeedQueryMap &needQueryMap,
1061     int64_t &faceRowNum, int64_t &mapRowNum, int64_t &photoNum)
1062 {
1063     return;
1064 }
1065 
ReportPortraitStat(int32_t sceneCode)1066 void BaseRestore::ReportPortraitStat(int32_t sceneCode)
1067 {
1068     MEDIA_INFO_LOG("PortraitStat: album %{public}zu, photo %{public}lld, face %{public}lld, cost %{public}lld",
1069         portraitAlbumIdMap_.size(), (long long)migratePortraitPhotoNumber_, (long long)migratePortraitFaceNumber_,
1070         (long long)migratePortraitTotalTimeCost_);
1071     BackupDfxUtils::PostPortraitStat(static_cast<uint32_t>(portraitAlbumIdMap_.size()), migratePortraitPhotoNumber_,
1072         migratePortraitFaceNumber_, migratePortraitTotalTimeCost_);
1073 }
1074 
GetUniqueId(int32_t fileType)1075 int32_t BaseRestore::GetUniqueId(int32_t fileType)
1076 {
1077     int32_t uniqueId = -1;
1078     switch (fileType) {
1079         case MediaType::MEDIA_TYPE_IMAGE: {
1080             lock_guard<mutex> lock(imageMutex_);
1081             uniqueId = static_cast<int32_t>(imageNumber_);
1082             imageNumber_++;
1083             break;
1084         }
1085         case MediaType::MEDIA_TYPE_VIDEO: {
1086             lock_guard<mutex> lock(videoMutex_);
1087             uniqueId = static_cast<int32_t>(videoNumber_);
1088             videoNumber_++;
1089             break;
1090         }
1091         case MediaType::MEDIA_TYPE_AUDIO: {
1092             lock_guard<mutex> lock(audioMutex_);
1093             uniqueId = static_cast<int32_t>(audioNumber_);
1094             audioNumber_++;
1095             break;
1096         }
1097         default:
1098             MEDIA_ERR_LOG("Unsupported file type: %{public}d", fileType);
1099     }
1100     return uniqueId;
1101 }
1102 
GetProgressInfo()1103 std::string BaseRestore::GetProgressInfo()
1104 {
1105     nlohmann::json progressInfoJson;
1106     for (const auto &type : STAT_PROGRESS_TYPES) {
1107         SubProcessInfo subProcessInfo = GetSubProcessInfo(type);
1108         progressInfoJson[STAT_KEY_PROGRESS_INFO].push_back(GetSubProcessInfoJson(type, subProcessInfo));
1109     }
1110     std::string progressInfo = progressInfoJson.dump();
1111     UpgradeRestoreTaskReport()
1112         .SetSceneCode(this->sceneCode_)
1113         .SetTaskId(this->taskId_)
1114         .ReportProgress("onProcess", progressInfo, ongoingTotalNumber_.load())
1115         .ReportTimeout(ongoingTotalNumber_.load());
1116     return progressInfo;
1117 }
1118 
GetSubProcessInfo(const std::string & type)1119 SubProcessInfo BaseRestore::GetSubProcessInfo(const std::string &type)
1120 {
1121     uint64_t success = 0;
1122     uint64_t duplicate = 0;
1123     uint64_t failed = 0;
1124     uint64_t total = 0;
1125     if (type == STAT_TYPE_PHOTO_VIDEO) {
1126         success = migrateFileNumber_;
1127         duplicate = migratePhotoDuplicateNumber_ + migrateVideoDuplicateNumber_;
1128         failed = static_cast<uint64_t>(GetFailedFiles(STAT_TYPE_PHOTO).size() + GetFailedFiles(STAT_TYPE_VIDEO).size());
1129         total = totalNumber_;
1130     } else if (type == STAT_TYPE_AUDIO) {
1131         success = migrateAudioFileNumber_;
1132         duplicate = migrateAudioDuplicateNumber_;
1133         failed = static_cast<uint64_t>(GetFailedFiles(type).size());
1134         total = audioTotalNumber_;
1135     } else if (type == STAT_TYPE_UPDATE) {
1136         UpdateProcessedNumber(updateProcessStatus_, updateProcessedNumber_, updateTotalNumber_);
1137         success = updateProcessedNumber_;
1138         total = updateTotalNumber_;
1139     } else if (type == STAT_TYPE_OTHER) {
1140         UpdateProcessedNumber(otherProcessStatus_, otherProcessedNumber_, otherTotalNumber_);
1141         success = otherProcessedNumber_;
1142         total = otherTotalNumber_;
1143     } else {
1144         ongoingTotalNumber_++;
1145         success = ongoingTotalNumber_;
1146         total = ongoingTotalNumber_; // make sure progressInfo changes as process goes on
1147     }
1148     uint64_t processed = success + duplicate + failed;
1149     return SubProcessInfo(processed, total);
1150 }
1151 
UpdateProcessedNumber(const std::atomic<int32_t> & processStatus,std::atomic<uint64_t> & processedNumber,const std::atomic<uint64_t> & totalNumber)1152 void BaseRestore::UpdateProcessedNumber(const std::atomic<int32_t> &processStatus,
1153     std::atomic<uint64_t> &processedNumber, const std::atomic<uint64_t> &totalNumber)
1154 {
1155     if (processStatus == ProcessStatus::STOP) {
1156         processedNumber = totalNumber.load();
1157         return;
1158     }
1159     processedNumber += processedNumber < totalNumber ? 1 : 0;
1160 }
1161 
GetSubProcessInfoJson(const std::string & type,const SubProcessInfo & subProcessInfo)1162 nlohmann::json BaseRestore::GetSubProcessInfoJson(const std::string &type, const SubProcessInfo &subProcessInfo)
1163 {
1164     nlohmann::json subProcessInfoJson;
1165     subProcessInfoJson[STAT_KEY_NAME] = type;
1166     subProcessInfoJson[STAT_KEY_PROCESSED] = subProcessInfo.processed;
1167     subProcessInfoJson[STAT_KEY_TOTAL] = subProcessInfo.total;
1168     subProcessInfoJson[STAT_KEY_IS_PERCENTAGE] = false;
1169     return subProcessInfoJson;
1170 }
1171 
UpdateDatabase()1172 void BaseRestore::UpdateDatabase()
1173 {
1174     updateProcessStatus_ = ProcessStatus::START;
1175     GetUpdateTotalCount();
1176     MEDIA_INFO_LOG("Start update all albums");
1177     auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
1178     MediaLibraryRdbUtils::UpdateAllAlbums(rdbStore);
1179     MEDIA_INFO_LOG("Start update unique number");
1180     BackupDatabaseUtils::UpdateUniqueNumber(mediaLibraryRdb_, imageNumber_, IMAGE_ASSET_TYPE);
1181     BackupDatabaseUtils::UpdateUniqueNumber(mediaLibraryRdb_, videoNumber_, VIDEO_ASSET_TYPE);
1182     BackupDatabaseUtils::UpdateUniqueNumber(mediaLibraryRdb_, audioNumber_, AUDIO_ASSET_TYPE);
1183     MEDIA_INFO_LOG("Start notify");
1184     NotifyAlbum();
1185     updateProcessStatus_ = ProcessStatus::STOP;
1186 }
1187 
NotifyAlbum()1188 void BaseRestore::NotifyAlbum()
1189 {
1190     auto watch = MediaLibraryNotify::GetInstance();
1191     if (watch == nullptr) {
1192         MEDIA_ERR_LOG("Can not get MediaLibraryNotify Instance");
1193         return;
1194     }
1195     watch->Notify(PhotoColumn::DEFAULT_PHOTO_URI, NotifyType::NOTIFY_ADD);
1196     watch->Notify(PhotoAlbumColumns::ALBUM_URI_PREFIX, NotifyType::NOTIFY_ADD);
1197 }
1198 
GetUpdateTotalCount()1199 void BaseRestore::GetUpdateTotalCount()
1200 {
1201     GetUpdateAllAlbumsCount();
1202     GetUpdateUniqueNumberCount();
1203 }
1204 
GetUpdateAllAlbumsCount()1205 void BaseRestore::GetUpdateAllAlbumsCount()
1206 {
1207     const std::vector<std::string> ALBUM_TABLE_LIST = { "PhotoAlbum", "AnalysisAlbum" };
1208     int32_t albumTotalCount = 0;
1209     for (const auto &tableName : ALBUM_TABLE_LIST) {
1210         std::string querySql = "SELECT count(1) as count FROM " + tableName;
1211         albumTotalCount += BackupDatabaseUtils::QueryInt(mediaLibraryRdb_, querySql, CUSTOM_COUNT);
1212     }
1213     updateTotalNumber_ += static_cast<uint64_t>(albumTotalCount);
1214     MEDIA_INFO_LOG("onProcess Update updateTotalNumber_: %{public}lld", (long long)updateTotalNumber_);
1215 }
1216 
GetUpdateUniqueNumberCount()1217 void BaseRestore::GetUpdateUniqueNumberCount()
1218 {
1219     updateTotalNumber_ += UNIQUE_NUMBER_NUM;
1220     MEDIA_INFO_LOG("onProcess Update updateTotalNumber_: %{public}lld", (long long)updateTotalNumber_);
1221 }
1222 
RestoreThumbnail()1223 void BaseRestore::RestoreThumbnail()
1224 {
1225     // restore thumbnail for date fronted 500 photos
1226     MEDIA_INFO_LOG("Start RestoreThumbnail");
1227     otherProcessStatus_ = ProcessStatus::START;
1228     otherTotalNumber_ += THUMBNAIL_NUM;
1229     MEDIA_INFO_LOG("onProcess Update otherTotalNumber_: %{public}lld", (long long)otherTotalNumber_);
1230     BackupFileUtils::GenerateThumbnailsAfterRestore();
1231     otherProcessStatus_ = ProcessStatus::STOP;
1232 }
1233 
StartBackup()1234 void BaseRestore::StartBackup()
1235 {}
1236 
CheckInvalidFile(const FileInfo & fileInfo,int32_t errCode)1237 std::string BaseRestore::CheckInvalidFile(const FileInfo &fileInfo, int32_t errCode)
1238 {
1239     return "";
1240 }
1241 
GetRestoreTotalInfo()1242 std::string BaseRestore::GetRestoreTotalInfo()
1243 {
1244     std::stringstream restoreTotalInfo;
1245     uint64_t success = migrateFileNumber_;
1246     uint64_t duplicate = migratePhotoDuplicateNumber_ + migrateVideoDuplicateNumber_;
1247     uint64_t failed = static_cast<uint64_t>(GetFailedFiles(STAT_TYPE_PHOTO).size() +
1248         GetFailedFiles(STAT_TYPE_VIDEO).size());
1249     uint64_t error = totalNumber_ - success - duplicate - failed;
1250     restoreTotalInfo << failed;
1251     restoreTotalInfo << ";" << error;
1252     restoreTotalInfo << ";" << GetNoNeedMigrateCount();
1253     return restoreTotalInfo.str();
1254 }
1255 
GetNoNeedMigrateCount()1256 int32_t BaseRestore::GetNoNeedMigrateCount()
1257 {
1258     return 0;
1259 }
1260 
UpdatePhotosByFileInfoMap(std::shared_ptr<NativeRdb::RdbStore> mediaLibraryRdb,const std::vector<FileInfo> & fileInfos)1261 void BaseRestore::UpdatePhotosByFileInfoMap(std::shared_ptr<NativeRdb::RdbStore> mediaLibraryRdb,
1262     const std::vector<FileInfo>& fileInfos)
1263 {
1264     for (const FileInfo &fileInfo : fileInfos) {
1265         auto &updateMap = fileInfo.updateMap;
1266         if (fileInfo.fileIdNew <= 0 || fileInfo.isNew || updateMap.empty()) {
1267             continue;
1268         }
1269         int32_t changeRows = 0;
1270         std::unique_ptr<NativeRdb::AbsRdbPredicates> predicates =
1271             make_unique<NativeRdb::AbsRdbPredicates>(PhotoColumn::PHOTOS_TABLE);
1272         predicates->SetWhereClause("file_id=?");
1273         predicates->SetWhereArgs({ to_string(fileInfo.fileIdNew) });
1274         NativeRdb::ValuesBucket updatePostBucket;
1275         for (auto it = updateMap.begin(); it != updateMap.end(); it++) {
1276             updatePostBucket.Put(it->first, it->second);
1277         }
1278         BackupDatabaseUtils::Update(mediaLibraryRdb, changeRows, updatePostBucket, predicates);
1279         if (changeRows <= 0) {
1280             MEDIA_ERR_LOG("update failed, fileId: %{public}d", fileInfo.fileIdNew);
1281             ErrorInfo errorInfo(RestoreError::UPDATE_PHOTOS_FAILED, 1, "",
1282                 BackupLogUtils::FileInfoToString(this->sceneCode_, fileInfo));
1283             UpgradeRestoreTaskReport().SetSceneCode(this->sceneCode_).SetTaskId(this->taskId_).ReportError(errorInfo);
1284         }
1285     }
1286 }
1287 } // namespace Media
1288 } // namespace OHOS
1289