| name | media-library-single-clone |
| description | OpenHarmony single-framework media library clone restore domain expertise. Use when working with multimedia_media_library clone/restore/backup extension code, especially services/media_backup_extension/src/clone_restore.cpp, base_restore.cpp, photos_clone.cpp, photos_dao.cpp, and related headers. Covers clone restore workflows, duplicate asset merging, cloud photo cloning, position management (LOCAL/CLOUD/LOCAL_AND_CLOUD), thumbnail handling, and SQL query patterns for Photos/PhotoAlbum/PhotoMap tables.
|
媒体库单单克隆 (Media Library Single Clone)
Core Files
| Component | Path |
|---|
| Clone restore main | services/media_backup_extension/src/clone_restore.cpp |
| Clone restore header | services/media_backup_extension/include/clone_restore.h |
| Base restore | services/media_backup_extension/src/base_restore.cpp |
| Photos DAO | services/media_backup_extension/src/restore/photos_dao.cpp |
| Photos clone | services/media_backup_extension/src/restore/photos_clone.cpp |
| Backup const | services/media_backup_extension/include/backup_const.h |
Key Workflows
1. Normal Photo Clone Flow
RestorePhoto()
├── QueryFileInfos(offset) // position IN (1,3), local photos
├── InsertPhoto(fileInfos)
│ ├── GetInsertValues() // PrepareCloudPath + GetInsertValue
│ ├── BatchInsertWithRetry() // INSERT into Photos
│ ├── InsertPhotoRelated() // BatchQueryPhoto + BatchInsertMap
│ └── MoveMigrateFile() // MoveAsset (MovePicture/Thumbnail/EditData)
└── ProcessFailedOffsets()
2. Cloud Photo Clone Flow
RestorePhotoForCloud() // only when IsCloudRestoreSatisfied()
├── QueryCloudFileInfos(offset) // position = 2, cloud photos
├── InsertCloudPhoto()
│ ├── GetCloudInsertValues() // uses GetCloudInsertValue
│ ├── BatchInsertWithRetry()
│ ├── InsertPhotoRelated()
│ └── MoveMigrateCloudFile()
└── ProcessCloudPhotosFailedOffsets()
3. Duplicate Detection & Merge Flow
PrepareCloudPath()
└── IsSameFileForClone()
├── photosClone_.FindSameFile() // SQL match by lPath/displayName/size/orientation/cloud_id
└── ExtraCheckForCloneSameFile() // sets isNew=false, fileIdNew, cloudPath
└── If dst is pure cloud (position=2):
├── IsSameAssetForCloudIdMove() // displayName/fileSize/orientation match
├── needMove = true/false
└── position -> LOCAL_AND_CLOUD (3), needUpdatePositionToLocalAndCloud = true
When duplicate detected:
fileInfo.isNew = false → skipped in GetInsertValues/GetCloudInsertValues
MoveAsset() → MergeDuplicateAsset() (imports origin if missing) + MergeDuplicateThumbnail()
UpdatePositionForMergedCloudDuplicates() → updates position to 3 for merged cloud dupes
Critical Position Values
| Value | Enum | Meaning |
|---|
| 1 | LOCAL | Local file only |
| 2 | CLOUD | Cloud-only (no local copy) |
| 3 | LOCAL_AND_CLOUD | Both local and cloud |
- Old device SQL queries use
position IN (1, 3) for normal clone, position = 2 for cloud clone
- New device
PhotosDao::FindSameFile searches among file_id <= maxFileId (pre-clone data)
Important Logic Details
- BatchQueryPhoto: After INSERT, queries
mediaLibraryRdb_ by cloudPath to get new fileIdNew
- GetCloudInsertValue: Sets
position, cloud_id, sync_status=TYPE_BACKUP, dirty=0, thumbnail_ready=0
- MovePicture: For non-Lake files, copies/moves from backup path to local path (cloud→local prefix replace)
- Lake files:
fileSourceType = MEDIA_HO_LAKE, use storagePath instead of cloudPath, skip file move
- ShouldDeleteDuplicateLakeFile: Keeps source only when target is pure-cloud and local origin exists
Common Bug Patterns
- SQL column missing in FindSameFile:
SQL_PHOTOS_FIND_SAME_FILE_IN_ALBUM / WITHOUT_ALBUM / BY_SOURCE_PATH must select display_name, size, orientation in outer SELECT. Missing these causes IsSameAssetForCloudIdMove to always return false, blocking position update and origin asset move.
- Need visible flag:
UpdatePositionForMergedCloudDuplicates skips when !needVisible. needVisible is set false when file move fails or file not found.
- Inner vs outer SELECT consistency: When adding columns to outer SELECT of subquery SQLs, ensure inner SELECT also includes them.
References