• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "medialibrary_ptp_operations.h"
16 
17 #include <fcntl.h>
18 
19 #include "dfx_utils.h"
20 #include "file_asset.h"
21 #include "media_file_utils.h"
22 #include "media_log.h"
23 #include "medialibrary_errno.h"
24 #include "medialibrary_notify.h"
25 #include "medialibrary_rdbstore.h"
26 #include "medialibrary_unistore_manager.h"
27 #include "photo_album_column.h"
28 #include "result_set_utils.h"
29 #include "userfile_manager_types.h"
30 #include "album_accurate_refresh.h"
31 #include "refresh_business_name.h"
32 using namespace std;
33 namespace OHOS::Media {
34 constexpr int64_t INVALID_SIZE = 0;
35 // LCOV_EXCL_START
FetchOneFileAssetFromResultSet(const shared_ptr<NativeRdb::ResultSet> & resultSet,const vector<string> & columns)36 shared_ptr<FileAsset> MediaLibraryPtpOperations::FetchOneFileAssetFromResultSet(
37     const shared_ptr<NativeRdb::ResultSet> &resultSet, const vector<string> &columns)
38 {
39     int32_t currentRowIndex = 0;
40     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, nullptr, "resultSet is nullptr");
41     CHECK_AND_RETURN_RET_LOG(
42         resultSet->GetRowIndex(currentRowIndex) == NativeRdb::E_OK, nullptr, "Cannot get row index of resultset");
43     CHECK_AND_RETURN_RET_LOG(currentRowIndex >= 0, nullptr, "Invalid row index");
44 
45     auto fileAsset = make_shared<FileAsset>();
46     auto &map = fileAsset->GetMemberMap();
47     for (const auto &column : columns) {
48         int32_t columnIndex = 0;
49         CHECK_AND_RETURN_RET_LOG(resultSet->GetColumnIndex(column, columnIndex) == NativeRdb::E_OK,
50             nullptr, "Can not get column %{private}s index", column.c_str());
51         CHECK_AND_RETURN_RET_LOG(FILEASSET_MEMBER_MAP.find(column) != FILEASSET_MEMBER_MAP.end(), nullptr,
52             "Can not find column %{private}s from member map", column.c_str());
53         switch (FILEASSET_MEMBER_MAP.at(column)) {
54             case MEMBER_TYPE_INT32: {
55                 int32_t value = 0;
56                 CHECK_AND_RETURN_RET_LOG(resultSet->GetInt(columnIndex, value) == NativeRdb::E_OK, nullptr,
57                     "Can not get int value from column %{private}s", column.c_str());
58                 map[column] = value;
59                 break;
60             }
61             case MEMBER_TYPE_INT64: {
62                 int64_t value = 0;
63                 CHECK_AND_RETURN_RET_LOG(resultSet->GetLong(columnIndex, value) == NativeRdb::E_OK, nullptr,
64                     "Can not get long value from column %{private}s", column.c_str());
65                 map[column] = value;
66                 break;
67             }
68             case MEMBER_TYPE_STRING: {
69                 string value;
70                 CHECK_AND_RETURN_RET_LOG(resultSet->GetString(columnIndex, value) == NativeRdb::E_OK, nullptr,
71                     "Can not get string value from column %{private}s", column.c_str());
72                 map[column] = value;
73                 break;
74             }
75             case MEMBER_TYPE_DOUBLE: {
76                 double value;
77                 CHECK_AND_RETURN_RET_LOG(resultSet->GetDouble(columnIndex, value) == NativeRdb::E_OK, nullptr,
78                     "Can not get double value from column %{private}s", column.c_str());
79                 map[column] = value;
80                 break;
81             }
82             default:
83                 break;
84         }
85     }
86     return fileAsset;
87 }
88 
GetAssetFromResultSet(const shared_ptr<NativeRdb::ResultSet> & resultSet,const vector<string> & columns)89 shared_ptr<FileAsset> MediaLibraryPtpOperations::GetAssetFromResultSet(
90     const shared_ptr<NativeRdb::ResultSet> &resultSet, const vector<string> &columns)
91 {
92     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, nullptr, "resultSet is nullptr");
93     int32_t count = 0;
94     CHECK_AND_RETURN_RET_LOG(resultSet->GetRowCount(count) == NativeRdb::E_OK, nullptr,
95         "Cannot get row count of resultset");
96     CHECK_AND_RETURN_RET_LOG(count == 1, nullptr, "ResultSet count is %{public}d, not 1", count);
97     CHECK_AND_RETURN_RET_LOG(resultSet->GoToFirstRow() == NativeRdb::E_OK, nullptr, "Cannot go to first row");
98     return FetchOneFileAssetFromResultSet(resultSet, columns);
99 }
100 
PushMovingPhotoExternalPath(const std::string & path,const std::string & logTarget,std::vector<std::string> & attachment)101 void MediaLibraryPtpOperations::PushMovingPhotoExternalPath(const std::string &path, const std::string &logTarget,
102     std::vector<std::string> &attachment)
103 {
104     if (path.empty()) {
105         MEDIA_WARN_LOG("%{private}s is invalid.", logTarget.c_str());
106         return;
107     }
108     attachment.push_back(path);
109 }
110 
GetAssetSize(const std::string & extraPath)111 int64_t MediaLibraryPtpOperations::GetAssetSize(const std::string &extraPath)
112 {
113     string absExtraPath;
114     CHECK_AND_RETURN_RET_LOG(PathToRealPath(extraPath, absExtraPath), static_cast<int64_t>(E_ERR),
115         "file is not real path: %{private}s", extraPath.c_str());
116 
117     UniqueFd fd(open(absExtraPath.c_str(), O_RDONLY));
118     CHECK_AND_RETURN_RET_LOG(fd.Get() != E_ERR, static_cast<int64_t>(E_ERR),
119         "failed to open extra file");
120 
121     struct stat st;
122     CHECK_AND_RETURN_RET_LOG(fstat(fd.Get(), &st) == E_OK, static_cast<int64_t>(E_ERR),
123         "failed to get file size");
124     off_t fileSize = st.st_size;
125     return static_cast<int64_t>(fileSize);
126 }
127 
GetMovingPhotoExternalInfo(ExternalInfo & exInfo,std::vector<std::string> & attachment)128 void MediaLibraryPtpOperations::GetMovingPhotoExternalInfo(ExternalInfo &exInfo, std::vector<std::string> &attachment)
129 {
130     if (!MovingPhotoFileUtils::IsMovingPhoto(exInfo.subType, exInfo.effectMode, exInfo.originalSubType)) {
131         return;
132     }
133     exInfo.videoPath = MovingPhotoFileUtils::GetMovingPhotoVideoPath(exInfo.path);
134     exInfo.extraPath = MovingPhotoFileUtils::GetMovingPhotoExtraDataPath(exInfo.path);
135     exInfo.photoImagePath = MovingPhotoFileUtils::GetSourceMovingPhotoImagePath(exInfo.path);
136     exInfo.photoVideoPath = MovingPhotoFileUtils::GetSourceMovingPhotoVideoPath(exInfo.path);
137     exInfo.cachePath = MovingPhotoFileUtils::GetLivePhotoCachePath(exInfo.path);
138     PushMovingPhotoExternalPath(exInfo.videoPath, "videoPath", attachment);
139     PushMovingPhotoExternalPath(exInfo.extraPath, "extraPath", attachment);
140     PushMovingPhotoExternalPath(exInfo.photoImagePath, "photoImagePath", attachment);
141     PushMovingPhotoExternalPath(exInfo.photoVideoPath, "photoVideoPath", attachment);
142     PushMovingPhotoExternalPath(exInfo.cachePath, "cachePath", attachment);
143     MEDIA_INFO_LOG("videoPath is %{private}s, extraPath is %{private}s, photoImagePath is %{private}s, \
144         photoVideoPath is %{private}s, cachePath is %{private}s.", DfxUtils::GetSafePath(exInfo.videoPath).c_str(),
145         DfxUtils::GetSafePath(exInfo.extraPath).c_str(), DfxUtils::GetSafePath(exInfo.photoImagePath).c_str(),
146         DfxUtils::GetSafePath(exInfo.photoVideoPath).c_str(), DfxUtils::GetSafePath(exInfo.cachePath).c_str());
147     exInfo.sizeMp4 = GetAssetSize(exInfo.videoPath);
148     exInfo.sizeExtra = GetAssetSize(exInfo.extraPath);
149     if (exInfo.sizeMp4 <= INVALID_SIZE) {
150         MEDIA_WARN_LOG("failed to get mp4 size.");
151     } else {
152         exInfo.size += exInfo.sizeMp4;
153     }
154     if (exInfo.sizeExtra <= INVALID_SIZE) {
155         MEDIA_WARN_LOG("failed to get extra size.");
156     } else {
157         exInfo.size += exInfo.sizeExtra;
158     }
159     MEDIA_DEBUG_LOG("MovingPhoto size is %{public}" PRId64, exInfo.size);
160 }
161 
GetEditPhotoExternalInfo(ExternalInfo & exInfo,vector<string> & attachment)162 void MediaLibraryPtpOperations::GetEditPhotoExternalInfo(ExternalInfo &exInfo, vector<string> &attachment)
163 {
164     CHECK_AND_RETURN_LOG(exInfo.editTime != 0, "editTime is zero");
165     exInfo.editDataPath = PhotoFileUtils::GetEditDataPath(exInfo.path);
166     exInfo.editDataCameraPath = PhotoFileUtils::GetEditDataCameraPath(exInfo.path);
167     exInfo.editDataSourcePath = PhotoFileUtils::GetEditDataSourcePath(exInfo.path);
168     PushMovingPhotoExternalPath(exInfo.editDataPath, "editDataPath", attachment);
169     PushMovingPhotoExternalPath(exInfo.editDataCameraPath, "editDataCameraPath", attachment);
170     PushMovingPhotoExternalPath(exInfo.editDataSourcePath, "editDataSourcePath", attachment);
171     MEDIA_DEBUG_LOG("editDataPath is %{private}s, editDataCameraPath is %{private}s, editDataSourcePath is %{private}s",
172         DfxUtils::GetSafePath(exInfo.editDataPath).c_str(), DfxUtils::GetSafePath(exInfo.editDataCameraPath).c_str(),
173         DfxUtils::GetSafePath(exInfo.editDataSourcePath).c_str());
174 }
175 
GetCleanFileInfo(shared_ptr<FileAsset> & fileAssetPtr)176 FileManagement::CloudSync::CleanFileInfo MediaLibraryPtpOperations::GetCleanFileInfo(shared_ptr<FileAsset>&
177     fileAssetPtr)
178 {
179     CHECK_AND_RETURN_RET_LOG(fileAssetPtr != nullptr, {}, "GetCleanFileInfo fileAssetPtr is nullptr.");
180     FileManagement::CloudSync::CleanFileInfo cleanFileInfo;
181     ExternalInfo externalInfo;
182     externalInfo.size = fileAssetPtr->GetSize();
183     externalInfo.path = fileAssetPtr->GetPath();
184     if (externalInfo.size == INVALID_SIZE) {
185         externalInfo.size = GetAssetSize(externalInfo.path);
186         CHECK_AND_RETURN_RET_LOG(externalInfo.size > INVALID_SIZE, {}, "failed to get asset size.");
187     }
188     externalInfo.cloudId = fileAssetPtr->GetCloudId();
189     externalInfo.subType = fileAssetPtr->GetPhotoSubType();
190     externalInfo.effectMode = fileAssetPtr->GetMovingPhotoEffectMode();
191     externalInfo.originalSubType = fileAssetPtr->GetOriginalSubType();
192     GetMovingPhotoExternalInfo(externalInfo, cleanFileInfo.attachment);
193     externalInfo.dateModified = fileAssetPtr->GetDateModified();
194     externalInfo.displayName = fileAssetPtr->GetDisplayName();
195     externalInfo.editTime = fileAssetPtr->GetPhotoEditTime();
196     GetEditPhotoExternalInfo(externalInfo, cleanFileInfo.attachment);
197     cleanFileInfo.cloudId = externalInfo.cloudId;
198     cleanFileInfo.size = externalInfo.size;
199     cleanFileInfo.modifiedTime = externalInfo.dateModified;
200     cleanFileInfo.path = externalInfo.path;
201     cleanFileInfo.fileName = MediaFileUtils::GetFileName(externalInfo.path);
202     return cleanFileInfo;
203 }
204 
BatchDeleteLocalAndCloud(const vector<FileManagement::CloudSync::CleanFileInfo> & fileInfos)205 bool MediaLibraryPtpOperations::BatchDeleteLocalAndCloud(const vector<FileManagement::CloudSync::CleanFileInfo>&
206     fileInfos)
207 {
208     CHECK_AND_RETURN_RET_LOG(!fileInfos.empty(), false, "Batch delete local and cloud fileInfo is empty.");
209     vector<string> failCloudId;
210     auto ret = FileManagement::CloudSync::CloudSyncManager::GetInstance().BatchCleanFile(fileInfos,
211         failCloudId);
212     if (ret != 0) {
213         MEDIA_ERR_LOG("Failed to delete local and cloud photos permanently.");
214         return false;
215     }
216     if (failCloudId.empty()) {
217         MEDIA_DEBUG_LOG("Delete local and cloud photos permanently success");
218         return true;
219     }
220     for (const auto& element : failCloudId) {
221         MEDIA_ERR_LOG("Failed to delete, cloudId is %{public}s.", element.c_str());
222     }
223     return false;
224 }
225 
DeleteLocalAndCloudPhotos(vector<shared_ptr<FileAsset>> & subFileAsset)226 int32_t MediaLibraryPtpOperations::DeleteLocalAndCloudPhotos(vector<shared_ptr<FileAsset>> &subFileAsset)
227 {
228     MEDIA_INFO_LOG("DeleteLocalAndCloudPhotos start.");
229     vector<FileManagement::CloudSync::CleanFileInfo> fileInfos;
230     if (subFileAsset.empty()) {
231         MEDIA_INFO_LOG("DeleteLocalAndCloudPhotos subFileAsset is empty.");
232         return E_OK;
233     }
234     for (auto& fileAssetPtr : subFileAsset) {
235         if (fileAssetPtr == nullptr) {
236             continue;
237         }
238         fileInfos.push_back(GetCleanFileInfo(fileAssetPtr));
239     }
240     if (!BatchDeleteLocalAndCloud(fileInfos)) {
241         MEDIA_ERR_LOG("BatchDeleteLocalAndCloud delete media assert fail.");
242         return E_HAS_DB_ERROR;
243     }
244     return E_OK;
245 }
246 
GetBurstPhotosInfo(const std::string & burstKey,bool & isLastBurstPhoto,vector<int32_t> & burstFileIds)247 int32_t MediaLibraryPtpOperations::GetBurstPhotosInfo(const std::string &burstKey, bool &isLastBurstPhoto,
248     vector<int32_t> &burstFileIds)
249 {
250     burstFileIds.clear();
251     NativeRdb::RdbPredicates queryPredicates(PhotoColumn::PHOTOS_TABLE);
252     vector<string> columns = { MediaColumn::MEDIA_ID };
253     queryPredicates.EqualTo(PhotoColumn::PHOTO_BURST_COVER_LEVEL, static_cast<int32_t>(BurstCoverLevelType::MEMBER));
254     queryPredicates.EqualTo(PhotoColumn::PHOTO_BURST_KEY, burstKey);
255     auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
256     CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, false, "rdbStore is null");
257     auto resultSet = rdbStore->Query(queryPredicates, columns);
258     int32_t count = 0;
259     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, E_HAS_DB_ERROR, "resultSet is nullptr");
260     CHECK_AND_RETURN_RET_LOG(
261         resultSet->GetRowCount(count) == NativeRdb::E_OK, E_HAS_DB_ERROR, "Cannot get row count of resultset");
262     isLastBurstPhoto = count == 1;
263     CHECK_AND_RETURN_RET_LOG(resultSet->GoToFirstRow() == NativeRdb::E_OK, E_HAS_DB_ERROR, "have no photo asset");
264     do {
265         burstFileIds.push_back(GetInt32Val(MediaColumn::MEDIA_ID, resultSet));
266     } while (resultSet->GoToNextRow() == NativeRdb::E_OK);
267     resultSet->Close();
268     return NativeRdb::E_OK;
269 }
270 
DeletePtpPhoto(NativeRdb::RdbPredicates & rdbPredicate)271 int32_t MediaLibraryPtpOperations::DeletePtpPhoto(NativeRdb::RdbPredicates &rdbPredicate)
272 {
273     int32_t ret = 0;
274     std::vector<std::shared_ptr<FileAsset>> fileAssetVector;
275     std::shared_ptr<FileAsset> fileAsset = QueryPhotoInfo(rdbPredicate);
276     CHECK_AND_RETURN_RET_LOG(fileAsset != nullptr, E_HAS_DB_ERROR, "fileAsset is nullptr");
277     int32_t position = fileAsset->GetPosition();
278     if (position == static_cast<int32_t>(PhotoPositionType::CLOUD) ||
279         position == static_cast<int32_t>(PhotoPositionType::LOCAL_AND_CLOUD)) {
280         fileAssetVector.push_back(fileAsset);
281         return DeleteLocalAndCloudPhotos(fileAssetVector);
282     }
283     int32_t subType = fileAsset->GetPhotoSubType();
284     int32_t burstCoverLevel = fileAsset->GetBurstCoverLevel();
285     string burstKey = fileAsset->GetBurstKey();
286     bool isBurstCover = false;
287     bool isLastBurstPhoto = false;
288     vector<int32_t> burstFileIds;
289     auto assetRefresh = std::make_shared<AccurateRefresh::AssetAccurateRefresh>(
290         AccurateRefresh::DELETE_PERMANENTLY_BUSSINESS_NAME);
291     if (subType == static_cast<int32_t>(PhotoSubType::BURST)) {
292         isBurstCover = burstCoverLevel == static_cast<int32_t>(BurstCoverLevelType::COVER);
293         ret = GetBurstPhotosInfo(burstKey, isLastBurstPhoto, burstFileIds);
294         CHECK_AND_RETURN_RET_LOG(ret == NativeRdb::E_OK, E_HAS_DB_ERROR, "GetBurstPhotosInfo fail.");
295         bool needClearBurst = isLastBurstPhoto || isBurstCover;
296         ret = UpdateBurstPhotoInfo(burstKey, needClearBurst, rdbPredicate, assetRefresh);
297         CHECK_AND_RETURN_RET_LOG(ret == NativeRdb::E_OK, E_HAS_DB_ERROR, "UpdateBurstPhotoInfo fail.");
298     }
299     if (isBurstCover) {
300         auto watch = MediaLibraryNotify::GetInstance();
301         CHECK_AND_RETURN_RET_LOG(watch != nullptr, E_ERR, "Can not get MediaLibraryNotify Instance");
302         for (const auto &fileId : burstFileIds) {
303             watch->Notify(PhotoColumn::PHOTO_URI_PREFIX + to_string(fileId), NotifyType::NOTIFY_ADD);
304             watch->Notify(PhotoColumn::PHOTO_URI_PREFIX + to_string(fileId), NotifyType::NOTIFY_THUMB_ADD);
305         }
306     }
307     return MediaLibraryAssetOperations::DeletePermanently(rdbPredicate, true, assetRefresh);
308 }
309 
QueryPhotoInfo(NativeRdb::RdbPredicates & rdbPredicate)310 std::shared_ptr<FileAsset> MediaLibraryPtpOperations::QueryPhotoInfo(NativeRdb::RdbPredicates &rdbPredicate)
311 {
312     vector<string> columns = {
313         PhotoColumn::PHOTO_CLOUD_ID,
314         MediaColumn::MEDIA_SIZE,
315         MediaColumn::MEDIA_DATE_MODIFIED,
316         MediaColumn::MEDIA_FILE_PATH,
317         MediaColumn::MEDIA_NAME,
318         MediaColumn::MEDIA_ID,
319         PhotoColumn::PHOTO_POSITION,
320         PhotoColumn::PHOTO_BURST_KEY,
321         MediaColumn::MEDIA_TYPE,
322         PhotoColumn::PHOTO_SUBTYPE,
323         PhotoColumn::MOVING_PHOTO_EFFECT_MODE,
324         PhotoColumn::PHOTO_ORIGINAL_SUBTYPE,
325         PhotoColumn::PHOTO_EDIT_TIME,
326         PhotoColumn::PHOTO_OWNER_ALBUM_ID,
327         PhotoColumn::PHOTO_BURST_COVER_LEVEL,
328     };
329     auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
330     CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, nullptr, "rdbStore is null");
331     auto resultSet = rdbStore->Query(rdbPredicate, columns);
332     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, nullptr, "QueryPhotoInfo fail");
333     CHECK_AND_RETURN_RET_LOG(resultSet->GoToFirstRow() == NativeRdb::E_OK, nullptr, "have no photos");
334     return GetAssetFromResultSet(resultSet, columns);
335 }
336 
UpdateBurstPhotoInfo(const std::string & burstKey,const bool isCover,NativeRdb::RdbPredicates & rdbPredicate,std::shared_ptr<AccurateRefresh::AssetAccurateRefresh> assetRefresh)337 int32_t MediaLibraryPtpOperations::UpdateBurstPhotoInfo(const std::string &burstKey, const bool isCover,
338     NativeRdb::RdbPredicates &rdbPredicate, std::shared_ptr<AccurateRefresh::AssetAccurateRefresh> assetRefresh)
339 {
340     CHECK_AND_RETURN_RET_LOG(assetRefresh != nullptr, E_HAS_DB_ERROR, "assetRefresh is null");
341     vector<string> whereArgs;
342     string whereClause;
343     int32_t changeRows;
344     int32_t updateCount = 0;
345     NativeRdb::ValuesBucket values;
346     values.PutInt(PhotoColumn::PHOTO_BURST_COVER_LEVEL, static_cast<int32_t>(BurstCoverLevelType::COVER));
347     values.PutString(PhotoColumn::PHOTO_BURST_KEY, "");
348     values.PutInt(PhotoColumn::PHOTO_SUBTYPE, static_cast<int32_t>(PhotoSubType::DEFAULT));
349     if (isCover) {
350         whereClause = PhotoColumn::PHOTO_BURST_KEY + " = ?";
351         whereArgs = {burstKey};
352         changeRows = assetRefresh->Update(updateCount, PhotoColumn::PHOTOS_TABLE, values, whereClause, whereArgs);
353     } else {
354         changeRows = assetRefresh->Update(updateCount, values, rdbPredicate);
355     }
356     MEDIA_INFO_LOG("UpdateBurstPhotoInfo end updateRows:%{public}d", updateCount);
357     CHECK_AND_RETURN_RET_LOG(changeRows == NativeRdb::E_OK && updateCount >= 0, E_HAS_DB_ERROR,
358         "Update failed. changeRows:%{public}d, updateRows:%{public}d", changeRows, updateCount);
359     return E_OK;
360 }
361 
DeletePtpAlbum(NativeRdb::RdbPredicates & predicates)362 int32_t MediaLibraryPtpOperations::DeletePtpAlbum(NativeRdb::RdbPredicates &predicates)
363 {
364     std::vector<string> queryAlbumColumns = {PhotoAlbumColumns::ALBUM_ID};
365     auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
366     CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, E_ERR, "rdbStore is nullptr");
367     auto albumResultSet = rdbStore->Query(predicates, queryAlbumColumns);
368     CHECK_AND_RETURN_RET_LOG(albumResultSet != nullptr, E_ERR, "albumResultSet is nullptr");
369     CHECK_AND_RETURN_RET_LOG(albumResultSet->GoToFirstRow() == NativeRdb::E_OK, E_ERR, "get albumResultSet failed");
370     int32_t albumId = GetInt32Val(PhotoAlbumColumns::ALBUM_ID, albumResultSet);
371     albumResultSet->Close();
372     NativeRdb::RdbPredicates queryPredicates(PhotoColumn::PHOTOS_TABLE);
373     queryPredicates.EqualTo(PhotoColumn::PHOTO_OWNER_ALBUM_ID, to_string(albumId));
374     NativeRdb::RdbPredicates deletePhotoPredicates(PhotoColumn::PHOTOS_TABLE);
375     deletePhotoPredicates.EqualTo(PhotoColumn::PHOTO_OWNER_ALBUM_ID, to_string(albumId));
376     std::vector<std::string> photosCloumns = {PhotoColumn::PHOTO_POSITION};
377     auto photosResultSet = rdbStore->Query(deletePhotoPredicates, photosCloumns);
378     CHECK_AND_RETURN_RET_LOG(photosResultSet != nullptr, E_ERR, "photosResultSet is nullptr");
379     CHECK_AND_PRINT_LOG(photosResultSet->GoToFirstRow() == NativeRdb::E_OK, "photosResultSet do not have photo asset");
380     while (photosResultSet->GoToNextRow() == NativeRdb::E_OK) {
381         int32_t position = GetInt32Val(PhotoColumn::PHOTO_POSITION, photosResultSet);
382         if (position == static_cast<int32_t>(PhotoPositionType::CLOUD) ||
383             position == static_cast<int32_t>(PhotoPositionType::LOCAL_AND_CLOUD)) {
384             MediaLibraryAssetOperations::DeletePermanently(deletePhotoPredicates, true);
385             return E_OK;
386         }
387     }
388     MediaLibraryAssetOperations::DeletePermanently(deletePhotoPredicates, true);
389     AccurateRefresh::AlbumAccurateRefresh albumRefresh(AccurateRefresh::DELETE_PTP_ALBUM_BUSSINESS_NAME);
390     int deleteRow = -1;
391     albumRefresh.LogicalDeleteReplaceByUpdate(predicates, deleteRow);
392     CHECK_AND_RETURN_RET_LOG(deleteRow > 0, E_ERR, "delete album fail");
393     albumRefresh.Notify();
394     auto watch = MediaLibraryNotify::GetInstance();
395     CHECK_AND_RETURN_RET_LOG(watch != nullptr, E_ERR, "Can not get MediaLibraryNotify Instance");
396     watch->Notify(MediaFileUtils::GetUriByExtrConditions(PhotoAlbumColumns::ALBUM_URI_PREFIX,
397         to_string(albumId)), NotifyType::NOTIFY_REMOVE);
398     return E_OK;
399 }
400 // LCOV_EXCL_STOP
401 } // namespace OHOS::Media