• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #define MLOG_TAG "Media_Cloud_Dao"
17 
18 #include "cloud_media_download_dao.h"
19 
20 #include <string>
21 #include <utime.h>
22 #include <vector>
23 
24 #include "medialibrary_unistore_manager.h"
25 #include "result_set_reader.h"
26 #include "photos_po_writer.h"
27 #include "media_column.h"
28 #include "cloud_media_operation_code.h"
29 #include "cloud_media_dao_utils.h"
30 #include "cloud_media_sync_utils.h"
31 #include "moving_photo_file_utils.h"
32 #include "accurate_common_data.h"
33 #include "asset_accurate_refresh.h"
34 #include "album_accurate_refresh.h"
35 
36 namespace OHOS::Media::CloudSync {
GetDownloadThmsConditions(const int32_t type)37 NativeRdb::AbsRdbPredicates CloudMediaDownloadDao::GetDownloadThmsConditions(const int32_t type)
38 {
39     NativeRdb::AbsRdbPredicates predicates = NativeRdb::AbsRdbPredicates(PhotoColumn::PHOTOS_TABLE);
40     predicates.EqualTo(PhotoColumn::PHOTO_SYNC_STATUS, static_cast<int32_t>(SyncStatusType::TYPE_VISIBLE));
41     predicates.EqualTo(PhotoColumn::PHOTO_CLEAN_FLAG, static_cast<int32_t>(CleanType::TYPE_NOT_CLEAN));
42     predicates.NotEqualTo(PhotoColumn::PHOTO_POSITION, static_cast<int32_t>(CloudFilePosition::POSITION_LOCAL))
43         ->And()
44         ->BeginWrap();
45     ThmLcdState state;
46     if (type != static_cast<int32_t>(ThmLcdState::THM) && type != static_cast<int32_t>(ThmLcdState::THMLCD) &&
47         type != static_cast<int32_t>(ThmLcdState::LCD)) {
48         state = ThmLcdState::THMLCD;
49     } else {
50         state = static_cast<ThmLcdState>(type);
51     }
52     predicates.EqualTo(PhotoColumn::PHOTO_THUMB_STATUS, static_cast<int32_t>(ThumbState::TO_DOWNLOAD));
53     predicates.Or()->EqualTo(PhotoColumn::PHOTO_THUMB_STATUS, static_cast<int32_t>(ThumbState::THM_TO_DOWNLOAD));
54     if (state == ThmLcdState::LCD || state == ThmLcdState::THMLCD) {
55         predicates.Or()->EqualTo(PhotoColumn::PHOTO_THUMB_STATUS, static_cast<int32_t>(ThumbState::LCD_TO_DOWNLOAD));
56     }
57     predicates.EndWrap();
58     return predicates;
59 }
60 
GetDownloadThmNum(const int32_t type,int32_t & totalNum)61 int32_t CloudMediaDownloadDao::GetDownloadThmNum(const int32_t type, int32_t &totalNum)
62 {
63     MEDIA_INFO_LOG("GetDownloadThmNum begin %{public}d", type);
64     auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
65     CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, E_RDB_STORE_NULL, "Query Thumbs to Download Failed to get rdbStore.");
66     NativeRdb::AbsRdbPredicates predicates = this->GetDownloadThmsConditions(type);
67     std::shared_ptr<NativeRdb::ResultSet> resultSet = rdbStore->Query(predicates, {"COUNT(1) AS count"});
68     if (resultSet == nullptr || resultSet->GoToFirstRow() != NativeRdb::E_OK) {
69         MEDIA_ERR_LOG("get nullptr Query Thumbs to Download");
70         return E_RDB;
71     }
72     totalNum = GetInt32Val("count", resultSet);
73     resultSet->Close();
74     MEDIA_INFO_LOG("QueryThumbsToDownload end %{public}d", totalNum);
75     return E_OK;
76 }
77 
GetDownloadThms(const DownloadThumbnailQueryDto & queryDto,std::vector<PhotosPo> & photos)78 int32_t CloudMediaDownloadDao::GetDownloadThms(const DownloadThumbnailQueryDto &queryDto, std::vector<PhotosPo> &photos)
79 {
80     MEDIA_INFO_LOG("QueryThumbsToDownload begin %{public}s", queryDto.ToString().c_str());
81     auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
82     CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, E_HAS_DB_ERROR, "Query Thumbs to Download Failed to get rdbStore.");
83     NativeRdb::AbsRdbPredicates predicates = this->GetDownloadThmsConditions(queryDto.type);
84     if (queryDto.isDownloadDisplayFirst) {
85         predicates.EqualTo(MediaColumn::MEDIA_DATE_TRASHED, 0);       // NOT_IN_TRASH
86         predicates.EqualTo(MediaColumn::MEDIA_TIME_PENDING, 0);       // NOT_IN_PENDING
87         predicates.EqualTo(MediaColumn::MEDIA_HIDDEN, 0);             // NOT_HIDDEN
88         predicates.EqualTo(PhotoColumn::PHOTO_IS_TEMP, 0);            // NOT_TEMP_FILE
89         predicates.EqualTo(PhotoColumn::PHOTO_BURST_COVER_LEVEL, 1);  // IS_BURST_COVER
90     }
91     predicates.Limit(queryDto.offset, queryDto.size);
92     predicates.OrderByDesc(PhotoColumn::MEDIA_DATE_TAKEN);
93 
94     std::shared_ptr<NativeRdb::ResultSet> resultSet = rdbStore->Query(predicates, this->DOWNLOAD_THUMBNAIL_COLUMNS);
95     int32_t ret = ResultSetReader<PhotosPoWriter, PhotosPo>(resultSet).ReadRecords(photos);
96     CHECK_AND_RETURN_RET_LOG(ret == E_OK, ret, "Query Thumbs to Download Failed to read records, ret: %{public}d", ret);
97     MEDIA_INFO_LOG("GetDownloadThms, photos size: %{public}zu", photos.size());
98     return E_OK;
99 }
100 
GetDownloadAsset(const std::vector<int32_t> & fileIds,std::vector<PhotosPo> & photos)101 int32_t CloudMediaDownloadDao::GetDownloadAsset(const std::vector<int32_t> &fileIds, std::vector<PhotosPo> &photos)
102 {
103     MEDIA_INFO_LOG("enter GetDownloadAsset");
104     auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
105     CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, E_HAS_DB_ERROR, "GetDownloadAsset Failed to get rdbStore.");
106     NativeRdb::AbsRdbPredicates queryPredicates = NativeRdb::AbsRdbPredicates(PhotoColumn::PHOTOS_TABLE);
107     queryPredicates.In(PhotoColumn::MEDIA_ID, CloudMediaDaoUtils::GetStringVector(fileIds))
108         ->And()
109         ->EqualTo(PhotoColumn::PHOTO_SYNC_STATUS, static_cast<int32_t>(SyncStatusType::TYPE_VISIBLE))
110         ->And()
111         ->EqualTo(PhotoColumn::PHOTO_CLEAN_FLAG, static_cast<int32_t>(CleanType::TYPE_NOT_CLEAN));
112     auto resultSet = rdbStore->Query(queryPredicates, this->COLUMNS_DOWNLOAD_ASSET_QUERY_BY_FILE_ID);
113     int32_t ret = ResultSetReader<PhotosPoWriter, PhotosPo>(resultSet).ReadRecords(photos);
114     CHECK_AND_RETURN_RET_LOG(ret == E_OK, ret, "GetDownloadAsset Failed to query, ret: %{public}d", ret);
115     return ret;
116 }
117 
UpdateDownloadThm(const std::vector<std::string> & cloudIds)118 int32_t CloudMediaDownloadDao::UpdateDownloadThm(const std::vector<std::string> &cloudIds)
119 {
120     MEDIA_INFO_LOG("enter UpdateDownloadThm");
121     CHECK_AND_RETURN_RET_LOG(!cloudIds.empty(), E_OK, "UpdateDownloadThm cloudIds is empty.");
122     auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
123     CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, E_RDB_STORE_NULL, "Failed to get rdbStore.");
124     CHECK_AND_PRINT_LOG(cloudIds.size() <= BATCH_LIMIT_SIZE,
125         "UpdateDownloadThm cloudIds size: %{public}zu, limit: %{public}d",
126         cloudIds.size(),
127         BATCH_LIMIT_SIZE);
128     std::string sql = "\
129         UPDATE Photos \
130             SET sync_status = 0, \
131                 thumb_status = thumb_status & ? \
132         WHERE cloud_id IN ({0});";
133     std::vector<std::string> params = {CloudMediaDaoUtils::ToStringWithCommaAndQuote(cloudIds)};
134     std::string execSql = CloudMediaDaoUtils::FillParams(sql, params);
135     std::vector<NativeRdb::ValueObject> bindArgs = {static_cast<int32_t>(~THM_TO_DOWNLOAD_MASK)};
136     int32_t ret = rdbStore->ExecuteSql(execSql, bindArgs);
137     CHECK_AND_RETURN_RET_LOG(ret == E_OK, E_ERR, "Failed to UpdateDownloadThm.");
138     return ret;
139 }
140 
UpdateDownloadLcd(const std::vector<std::string> & cloudIds)141 int32_t CloudMediaDownloadDao::UpdateDownloadLcd(const std::vector<std::string> &cloudIds)
142 {
143     MEDIA_INFO_LOG("enter UpdateDownloadLcd");
144     CHECK_AND_RETURN_RET_LOG(!cloudIds.empty(), E_OK, "UpdateDownloadLcd cloudIds is empty.");
145     auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
146     CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, E_RDB_STORE_NULL, "Failed to get rdbStore.");
147     CHECK_AND_PRINT_LOG(cloudIds.size() <= BATCH_LIMIT_SIZE,
148         "UpdateDownloadLcd cloudIds size: %{public}zu, limit: %{public}d",
149         cloudIds.size(),
150         BATCH_LIMIT_SIZE);
151     std::string sql = "\
152         UPDATE Photos \
153             SET thumb_status = thumb_status & ? \
154         WHERE cloud_id IN ({0});";
155     std::vector<std::string> params = {CloudMediaDaoUtils::ToStringWithCommaAndQuote(cloudIds)};
156     std::string execSql = CloudMediaDaoUtils::FillParams(sql, params);
157     std::vector<NativeRdb::ValueObject> bindArgs = {static_cast<int32_t>(~LCD_TO_DOWNLOAD_MASK)};
158     int32_t ret = rdbStore->ExecuteSql(execSql, bindArgs);
159     CHECK_AND_RETURN_RET_LOG(ret == E_OK, E_ERR, "Failed to UpdateDownloadLcd.");
160     return ret;
161 }
162 
UpdateDownloadThmAndLcd(const std::vector<std::string> & cloudIds)163 int32_t CloudMediaDownloadDao::UpdateDownloadThmAndLcd(const std::vector<std::string> &cloudIds)
164 {
165     MEDIA_INFO_LOG("enter UpdateDownloadThmAndLcd");
166     CHECK_AND_RETURN_RET_LOG(!cloudIds.empty(), E_OK, "UpdateDownloadThmAndLcd cloudIds is empty.");
167     auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
168     CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, E_RDB_STORE_NULL, "Failed to get rdbStore.");
169     NativeRdb::AbsRdbPredicates predicates = NativeRdb::AbsRdbPredicates(PhotoColumn::PHOTOS_TABLE);
170     predicates.In(PhotoColumn::PHOTO_CLOUD_ID, cloudIds);
171     NativeRdb::ValuesBucket values;
172     values.PutInt(PhotoColumn::PHOTO_SYNC_STATUS, static_cast<int32_t>(SyncStatusType::TYPE_VISIBLE));
173     values.PutInt(PhotoColumn::PHOTO_THUMB_STATUS, static_cast<int32_t>(ThumbState::DOWNLOADED));
174     int32_t changedRows = DEFAULT_VALUE;
175     int32_t ret = rdbStore->Update(changedRows, values, predicates);
176     CHECK_AND_RETURN_RET_LOG(ret == E_OK, E_ERR, "Failed to UpdateDownloadThmAndLcd.");
177     CHECK_AND_PRINT_LOG(changedRows > 0, "Check updateRows: %{public}d.", changedRows);
178     MEDIA_INFO_LOG("UpdateDownloadThmAndLcd, changedRows: %{public}d.", changedRows);
179     return ret;
180 }
181 
GetFileIdFromCloudId(const std::vector<std::string> & cloudIds,std::vector<std::string> & fileIds)182 int32_t CloudMediaDownloadDao::GetFileIdFromCloudId(
183     const std::vector<std::string> &cloudIds, std::vector<std::string> &fileIds)
184 {
185     MEDIA_INFO_LOG("enter GetFileIdFromCloudId, cloudIds size: %{public}zu", cloudIds.size());
186     CHECK_AND_RETURN_RET_LOG(cloudIds.size() > 0, E_OK, "GetFileIdFromCloudId cloudIds is empty.");
187     auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
188     CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, E_RDB_STORE_NULL, "Failed to get rdbStore.");
189     NativeRdb::AbsRdbPredicates predicates = NativeRdb::AbsRdbPredicates(PhotoColumn::PHOTOS_TABLE);
190     predicates.In(PhotoColumn::PHOTO_CLOUD_ID, cloudIds);
191     std::vector<std::string> columns = {MediaColumn::MEDIA_ID};
192     auto resultSet = rdbStore->Query(predicates, columns);
193     std::vector<PhotosPo> photos;
194     int32_t ret = ResultSetReader<PhotosPoWriter, PhotosPo>(resultSet).ReadRecords(photos);
195     CHECK_AND_RETURN_RET_LOG(ret == E_OK, ret, "GetFileIdFromCloudId Failed to query, ret: %{public}d", ret);
196     for (auto photo : photos) {
197         if (!photo.fileId.has_value()) {
198             continue;
199         }
200         fileIds.emplace_back(std::to_string(photo.fileId.value_or(0)));
201     }
202     return ret;
203 }
204 
QueryDownloadAssetByCloudIds(const std::vector<std::string> & cloudIds,std::vector<PhotosPo> & result)205 int32_t CloudMediaDownloadDao::QueryDownloadAssetByCloudIds(
206     const std::vector<std::string> &cloudIds, std::vector<PhotosPo> &result)
207 {
208     auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
209     CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, E_RDB_STORE_NULL, "Failed to get rdbStore.");
210     NativeRdb::AbsRdbPredicates predicates = NativeRdb::AbsRdbPredicates(PhotoColumn::PHOTOS_TABLE);
211     predicates.In(PhotoColumn::PHOTO_CLOUD_ID, cloudIds);
212     predicates.NotEqualTo(PhotoColumn::PHOTO_DIRTY, static_cast<int32_t>(DirtyType::TYPE_DELETED));
213     auto resultSet = rdbStore->Query(predicates, this->COLUMNS_DOWNLOAD_ASSET_QUERY_BY_CLOUD_ID);
214     int32_t ret = ResultSetReader<PhotosPoWriter, PhotosPo>(resultSet).ReadRecords(result);
215     CHECK_AND_RETURN_RET_LOG(ret == E_OK, ret, "Failed to query, ret: %{public}d", ret);
216     MEDIA_INFO_LOG("QueryDownloadAssetByCloudId, rowCount: %{public}d", static_cast<int32_t>(result.size()));
217     return E_OK;
218 }
219 
UpdateDownloadAsset(const bool fixFileType,const std::string & path,const CloudMediaScanService::ScanResult & scanResult)220 int32_t CloudMediaDownloadDao::UpdateDownloadAsset(const bool fixFileType, const std::string &path,
221     const CloudMediaScanService::ScanResult& scanResult)
222 {
223     MEDIA_INFO_LOG("enter UpdateDownloadAsset %{public}d, %{public}s",
224         fixFileType, path.c_str());
225     std::shared_ptr<AccurateRefresh::AssetAccurateRefresh> photoRefresh =
226         std::make_shared<AccurateRefresh::AssetAccurateRefresh>();
227     CHECK_AND_RETURN_RET_LOG(photoRefresh != nullptr, E_RDB_STORE_NULL, "UpdateDownloadAsset Failed to get rdbStore.");
228     NativeRdb::AbsRdbPredicates predicates = NativeRdb::AbsRdbPredicates(PhotoColumn::PHOTOS_TABLE);
229     predicates.EqualTo(MediaColumn::MEDIA_FILE_PATH, path);
230     NativeRdb::ValuesBucket values;
231     values.PutInt(PhotoColumn::PHOTO_POSITION, static_cast<int32_t>(PhotoPositionType::LOCAL_AND_CLOUD));
232     if (fixFileType) {
233         MEDIA_INFO_LOG("UpdateDownloadAsset file is not real moving photo, need fix subtype");
234         values.PutInt(PhotoColumn::PHOTO_SUBTYPE, static_cast<int32_t>(PhotoSubType::DEFAULT));
235     }
236     if (scanResult.scanSuccess) {
237         values.PutString(PhotoColumn::PHOTO_SHOOTING_MODE, scanResult.shootingMode);
238         values.PutString(PhotoColumn::PHOTO_SHOOTING_MODE_TAG, scanResult.shootingModeTag);
239         values.PutString(PhotoColumn::PHOTO_FRONT_CAMERA, scanResult.frontCamera);
240     }
241     int32_t changedRows = -1;
242     int32_t ret = photoRefresh->Update(changedRows, values, predicates);
243     CHECK_AND_RETURN_RET_LOG(ret == AccurateRefresh::ACCURATE_REFRESH_RET_OK,
244         E_ERR,
245         "UpdateDownloadAsset Failed to Update, ret: %{public}d.",
246         ret);
247     CHECK_AND_PRINT_LOG(changedRows > 0, "UpdateDownloadAsset changedRows: %{public}d.", changedRows);
248     photoRefresh->RefreshAlbumNoDateModified(static_cast<NotifyAlbumType>(NotifyAlbumType::SYS_ALBUM |
249         NotifyAlbumType::USER_ALBUM | NotifyAlbumType::SOURCE_ALBUM));
250     photoRefresh->Notify();
251     return ret;
252 }
253 
UpdateDownloadAssetExifRotateFix(const int32_t fileId,const int32_t exifRotate,const DirtyTypes dirtyType,bool needRegenerateThumbnail)254 int32_t CloudMediaDownloadDao::UpdateDownloadAssetExifRotateFix(const int32_t fileId,
255     const int32_t exifRotate, const DirtyTypes dirtyType, bool needRegenerateThumbnail)
256 {
257     CHECK_AND_RETURN_RET_LOG(dirtyType == DirtyTypes::TYPE_MDIRTY || dirtyType == DirtyTypes::TYPE_FDIRTY,
258         E_ERR, "Not support update this dirtype:%{public}d", dirtyType);
259     std::shared_ptr<AccurateRefresh::AssetAccurateRefresh> photoRefresh =
260         std::make_shared<AccurateRefresh::AssetAccurateRefresh>();
261     CHECK_AND_RETURN_RET_LOG(photoRefresh != nullptr, E_RDB_STORE_NULL,
262         "UpdateDownloadAssetExifRotateFix Failed to get rdbStore.");
263 
264     std::vector<NativeRdb::ValueObject> bindArgs = {
265         exifRotate, std::to_string(static_cast<int32_t>(dirtyType)), fileId,
266     };
267     int32_t ret = 0;
268     if (needRegenerateThumbnail) {
269         ret = photoRefresh->ExecuteSql(this->SQL_FIX_EXIF_ROTATE_WITH_REGENERATE_THUMBNAIL,
270             bindArgs, AccurateRefresh::RdbOperation::RDB_OPERATION_UPDATE);
271     } else {
272         ret = photoRefresh->ExecuteSql(this->SQL_FIX_EXIF_ROTATE_WITHOUT_REGENERATE_THUMBNAIL,
273             bindArgs, AccurateRefresh::RdbOperation::RDB_OPERATION_UPDATE);
274     }
275 
276     CHECK_AND_RETURN_RET_LOG(ret == AccurateRefresh::ACCURATE_REFRESH_RET_OK,
277         E_ERR,
278         "UpdateDownloadAssetExifRotateFix Failed to Update, ret: %{public}d.",
279         ret);
280     photoRefresh->Notify();
281     return E_OK;
282 }
283 }  // namespace OHOS::Media::CloudSync