1 /*
2 * Copyright (C) 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 #include <sys/stat.h>
17 #include "dfx_database_utils.h"
18
19 #include "dfx_utils.h"
20 #include "dfx_reporter.h"
21 #include "medialibrary_rdbstore.h"
22 #include "medialibrary_tracer.h"
23 #include "medialibrary_unistore_manager.h"
24 #include "media_log.h"
25 #include "media_column.h"
26 #include "media_file_utils.h"
27 #include "medialibrary_errno.h"
28 #include "moving_photo_file_utils.h"
29 #include "result_set_utils.h"
30 #include "photo_album_column.h"
31 #include "photo_file_utils.h"
32 #include "preferences.h"
33 #include "preferences_helper.h"
34 #include "power_efficiency_manager.h"
35 #include "userfile_manager_types.h"
36
37 namespace OHOS {
38 namespace Media {
39 const std::string RECORD_COUNT = "recordCount";
40 const std::string ABNORMAL_VALUE = "-1";
41 const std::string DFX_OPT_TYPE = "opt_type";
42 const std::string OPT_ADD_VALUE = "1";
43 const std::string OPT_DEL_VALUE = "2";
44 const std::string OPT_UPDATE_VALUE = "3";
45 const int32_t BATCH_QUERY_PHOTO_NUMBER = 2000;
46 const int32_t FILE_HEIGHT_AND_WIDTH_240 = 240;
47 const int32_t FILE_HEIGHT_AND_WIDTH_360 = 360;
48 const int32_t FILE_HEIGHT_AND_WIDTH_480 = 480;
49 const int32_t FILE_HEIGHT_AND_WIDTH_720 = 720;
50 const int32_t FILE_HEIGHT_AND_WIDTH_1080 = 1080;
51 const int32_t FILE_HEIGHT_AND_WIDTH_1440 = 1440;
52 const int32_t FILE_HEIGHT_AND_WIDTH_2000 = 2000;
53 const int32_t FILE_HEIGHT_AND_WIDTH_4000 = 4000;
54 const int64_t PHOTO_FILE_SIZE = 1024;
55 static const std::vector<std::pair<int64_t, std::string>> sizeRanges = {
56 {100, "size100K"},
57 {250, "size250K"},
58 {500, "size500K"},
59 {1 * 1024, "size1M"},
60 {2 * 1024, "size2M"},
61 {3 * 1024, "size3M"},
62 {4 * 1024, "size4M"},
63 {5 * 1024, "size5M"},
64 {7 * 1024, "size7M"},
65 {10 * 1024, "size10M"},
66 {15 * 1024, "size15M"},
67 {20 * 1024, "size20M"},
68 {30 * 1024, "size30M"},
69 {50 * 1024, "size50M"},
70 {100 * 1024, "size100M"},
71 {500 * 1024, "size500M"},
72 {1 * 1024 * 1024, "size1G"},
73 {2 * 1024 * 1024, "size2G"},
74 {5 * 1024 * 1024, "size5G"}
75 };
76
77 static const std::unordered_map<std::string, int32_t> DEFAULT_PHOTO_SIZE_MAP = {
78 {"size100K", 0},
79 {"size250K", 0},
80 {"size500K", 0},
81 {"size1M", 0},
82 {"size2M", 0},
83 {"size3M", 0},
84 {"size4M", 0},
85 {"size5M", 0},
86 {"size7M", 0},
87 {"size10M", 0},
88 {"size15M", 0},
89 {"size20M", 0},
90 {"size30M", 0},
91 {"size50M", 0},
92 {"size100M", 0},
93 {"size500M", 0},
94 {"size1G", 0},
95 {"size2G", 0},
96 {"size5G", 0},
97 {"sizeOther", 0}
98 };
99
100 static const std::unordered_map<std::string, int32_t> DEFAULT_PHOTO_RESOLUTION_MAP = {
101 {"resolutionLess240P", 0},
102 {"resolution240P", 0},
103 {"resolution360P", 0},
104 {"resolution480P", 0},
105 {"resolution720P", 0},
106 {"resolution1080P", 0},
107 {"resolution2K", 0},
108 {"resolution4K", 0}
109 };
110
111 static const std::unordered_map<std::string, int32_t> DEFAULT_VIDEO_RESOLUTION_MAP = {
112 {"resolutionLess720P", 0},
113 {"resolution720P", 0},
114 {"resolution1080P", 0},
115 {"resolution2K", 0},
116 {"resolution4K", 0}
117 };
118
119 struct SizeAndResolutionInfoMap {
120 unordered_map<std::string, int32_t> localImageSizeMap = DEFAULT_PHOTO_SIZE_MAP;
121 unordered_map<std::string, int32_t> localVideoSizeMap = DEFAULT_PHOTO_SIZE_MAP;
122 unordered_map<std::string, int32_t> cloudImageSizeMap = DEFAULT_PHOTO_SIZE_MAP;
123 unordered_map<std::string, int32_t> cloudVideoSizeMap = DEFAULT_PHOTO_SIZE_MAP;
124 unordered_map<std::string, int32_t> localImageResolutionMap = DEFAULT_PHOTO_RESOLUTION_MAP;
125 unordered_map<std::string, int32_t> localVideoResolutionMap = DEFAULT_VIDEO_RESOLUTION_MAP;
126 unordered_map<std::string, int32_t> cloudImageResolutionMap = DEFAULT_PHOTO_RESOLUTION_MAP;
127 unordered_map<std::string, int32_t> cloudVideoResolutionMap = DEFAULT_VIDEO_RESOLUTION_MAP;
128 };
129
QueryFromPhotos(int32_t mediaType,int32_t position)130 int32_t DfxDatabaseUtils::QueryFromPhotos(int32_t mediaType, int32_t position)
131 {
132 NativeRdb::RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
133 predicates.EqualTo(MediaColumn::MEDIA_TYPE, mediaType);
134 predicates.EqualTo(PhotoColumn::PHOTO_POSITION, position);
135
136 std::vector<std::string> columns = { "count(1) AS count" };
137 std::string queryColumn = "count";
138
139 int32_t count;
140 int32_t errCode = QueryInt(predicates, columns, queryColumn, count);
141 if (errCode != E_OK) {
142 MEDIA_ERR_LOG("query photos fail: %{public}d mediaType: %{public}d position: %{public}d",
143 errCode, mediaType, position);
144 }
145
146 return count;
147 }
148
QueryAlbumInfoBySubtype(int32_t albumSubtype)149 AlbumInfo DfxDatabaseUtils::QueryAlbumInfoBySubtype(int32_t albumSubtype)
150 {
151 AlbumInfo albumInfo;
152 NativeRdb::RdbPredicates predicates(PhotoAlbumColumns::TABLE);
153 predicates.EqualTo(PhotoAlbumColumns::ALBUM_SUBTYPE, albumSubtype);
154 std::vector<std::string> columns = { PhotoAlbumColumns::ALBUM_COUNT, PhotoAlbumColumns::ALBUM_IMAGE_COUNT,
155 PhotoAlbumColumns::ALBUM_VIDEO_COUNT, PhotoAlbumColumns::ALBUM_CLOUD_ID };
156 auto resultSet = MediaLibraryRdbStore::QueryWithFilter(predicates, columns);
157 if (resultSet == nullptr || resultSet->GoToFirstRow() != NativeRdb::E_OK) {
158 MEDIA_ERR_LOG("query album fail");
159 return albumInfo;
160 }
161 albumInfo.count = GetInt32Val(PhotoAlbumColumns::ALBUM_COUNT, resultSet);
162 albumInfo.imageCount = GetInt32Val(PhotoAlbumColumns::ALBUM_IMAGE_COUNT, resultSet);
163 albumInfo.videoCount = GetInt32Val(PhotoAlbumColumns::ALBUM_VIDEO_COUNT, resultSet);
164 albumInfo.isLocal = GetStringVal(PhotoAlbumColumns::ALBUM_CLOUD_ID, resultSet) == "" ? true : false;
165 return albumInfo;
166 }
167
QueryDirtyCloudPhoto()168 std::vector<PhotoInfo> DfxDatabaseUtils::QueryDirtyCloudPhoto()
169 {
170 vector<PhotoInfo> photoInfoList;
171 NativeRdb::RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
172 predicates.NotEqualTo(PhotoColumn::PHOTO_POSITION, 1);
173 predicates.NotEqualTo(PhotoColumn::PHOTO_DIRTY, static_cast<int32_t> (DirtyType::TYPE_SYNCED));
174 predicates.Limit(DIRTY_PHOTO_COUNT);
175 std::vector<std::string> columns = { MediaColumn::MEDIA_FILE_PATH, PhotoColumn::PHOTO_DIRTY,
176 PhotoColumn::PHOTO_CLOUD_ID };
177 auto resultSet = MediaLibraryRdbStore::QueryWithFilter(predicates, columns);
178 if (resultSet == nullptr) {
179 MEDIA_ERR_LOG("resultSet is null");
180 return photoInfoList;
181 }
182 while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
183 PhotoInfo photoInfo;
184 photoInfo.data = DfxUtils::GetSafePath(GetStringVal(MediaColumn::MEDIA_FILE_PATH, resultSet));
185 photoInfo.dirty = GetInt32Val(PhotoColumn::PHOTO_DIRTY, resultSet);
186 photoInfo.cloudVersion = GetInt32Val(PhotoColumn::PHOTO_CLOUD_ID, resultSet);
187 photoInfoList.push_back(photoInfo);
188 }
189 return photoInfoList;
190 }
191
ParseResultSet(const string & querySql,int32_t mediaTypePara,int32_t & photoInfoCount)192 static bool ParseResultSet(const string &querySql, int32_t mediaTypePara, int32_t &photoInfoCount)
193 {
194 auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
195 if (rdbStore == nullptr) {
196 MEDIA_ERR_LOG("rdbStore is nullptr!");
197 return false;
198 }
199 auto resultSet = rdbStore->QuerySql(querySql);
200 if (resultSet == nullptr) {
201 MEDIA_ERR_LOG("resultSet is null");
202 return false;
203 }
204 while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
205 if (mediaTypePara > 0) {
206 int32_t mediaType = GetInt32Val(MediaColumn::MEDIA_TYPE, resultSet);
207 if (mediaType == mediaTypePara) {
208 photoInfoCount = GetInt32Val(RECORD_COUNT, resultSet);
209 }
210 } else {
211 photoInfoCount = GetInt32Val(RECORD_COUNT, resultSet);
212 }
213 }
214 return true;
215 }
216
QueryOperationResultSet(const string & querySql,int32_t & operationQueryInfoCount)217 static bool QueryOperationResultSet(const string &querySql, int32_t &operationQueryInfoCount)
218 {
219 auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
220 if (rdbStore == nullptr) {
221 MEDIA_ERR_LOG("rdbStore is nullptr");
222 return E_HAS_DB_ERROR;
223 }
224 int32_t rowCount = 0;
225 auto resultSet = rdbStore->QuerySql(querySql);
226 if (resultSet == nullptr || resultSet->GoToFirstRow() != NativeRdb::E_OK) {
227 MEDIA_ERR_LOG("query not match data failed");
228 return E_DB_FAIL;
229 }
230 if (resultSet->GetInt(0, rowCount) != NativeRdb::E_OK) {
231 MEDIA_ERR_LOG("rdb failed");
232 return E_DB_FAIL;
233 }
234 operationQueryInfoCount = rowCount;
235 return true;
236 }
237
GetDuplicateLpathCountQuerrySql()238 static string GetDuplicateLpathCountQuerrySql()
239 {
240 return "SELECT COUNT(*) AS " + RECORD_COUNT + " FROM " +
241 PhotoAlbumColumns::TABLE + " WHERE COALESCE(lpath, '') IN (SELECT lpath FROM " +
242 PhotoAlbumColumns::TABLE + " WHERE " + PhotoAlbumColumns::ALBUM_TYPE + " IN (0, 2048) AND " +
243 "COALESCE(lpath, '') <> '' AND " + PhotoAlbumColumns::ALBUM_DIRTY +
244 " <> 4 GROUP BY lpath HAVING COUNT(1) > 1) AND COALESCE(PhotoAlbum.dirty, 1) <> 4";
245 }
246
GetAbnormalLpathCountQuerySql()247 static string GetAbnormalLpathCountQuerySql()
248 {
249 return "SELECT COUNT(*) AS " + RECORD_COUNT + " FROM " +
250 PhotoAlbumColumns::TABLE + " WHERE COALESCE(lpath, '') = '' AND " +
251 PhotoAlbumColumns::ALBUM_TYPE + " != " + std::to_string(PhotoAlbumType::SYSTEM) + " AND " +
252 PhotoAlbumColumns::ALBUM_DIRTY + " != 4";
253 }
254
BuildDbInfo(PhotoRecordInfo & photoRecordInfo)255 static void BuildDbInfo(PhotoRecordInfo &photoRecordInfo)
256 {
257 string databaseDir = MEDIA_DB_DIR + "/rdb";
258 if (access(databaseDir.c_str(), E_OK) != 0) {
259 MEDIA_WARN_LOG("can not get rdb through sandbox");
260 return;
261 }
262 string dbPath = databaseDir.append("/").append(MEDIA_DATA_ABILITY_DB_NAME);
263
264 struct stat statInfo {};
265 if (stat(dbPath.c_str(), &statInfo) != 0) {
266 MEDIA_ERR_LOG("stat syscall err");
267 return;
268 }
269 photoRecordInfo.dbFileSize = statInfo.st_size;
270
271 struct stat slaveStatInfo {};
272 if (stat(MEDIA_DB_FILE_SLAVE.c_str(), &slaveStatInfo) == 0) {
273 photoRecordInfo.slaveDbFileSize = slaveStatInfo.st_size;
274 }
275 }
276
QueryPhotoRecordInfo(PhotoRecordInfo & photoRecordInfo)277 int32_t DfxDatabaseUtils::QueryPhotoRecordInfo(PhotoRecordInfo &photoRecordInfo)
278 {
279 const string filterCondition = MediaColumn::MEDIA_TIME_PENDING + " = 0 AND " +
280 PhotoColumn::PHOTO_SYNC_STATUS + " = " +
281 to_string(static_cast<int32_t>(SyncStatusType::TYPE_VISIBLE)) + " AND " +
282 PhotoColumn::PHOTO_CLEAN_FLAG + " = " +
283 to_string(static_cast<int32_t>(CleanType::TYPE_NOT_CLEAN));
284
285 const string imageAndVideoCountQuerySql = "SELECT " + MediaColumn::MEDIA_TYPE + ", COUNT(*) AS " + RECORD_COUNT +
286 " FROM " + PhotoColumn::PHOTOS_TABLE + " WHERE " + filterCondition + " GROUP BY " + MediaColumn::MEDIA_TYPE;
287
288 const string abnormalSizeCountQuerySql = "SELECT COUNT(*) AS " + RECORD_COUNT + " FROM " +
289 PhotoColumn::PHOTOS_TABLE + " WHERE " + MediaColumn::MEDIA_SIZE + " = " + ABNORMAL_VALUE +
290 " AND " + filterCondition;
291
292 const string abnormalWidthHeightQuerySql = "SELECT COUNT(*) AS " + RECORD_COUNT + " FROM " +
293 PhotoColumn::PHOTOS_TABLE + " WHERE (" + PhotoColumn::PHOTO_WIDTH + " = " + ABNORMAL_VALUE +
294 " OR " + PhotoColumn::PHOTO_HEIGHT + " = " + ABNORMAL_VALUE + ") AND " + filterCondition;
295
296 const string abnormalVideoDurationQuerySql = "SELECT COUNT(*) AS " + RECORD_COUNT + " FROM " +
297 PhotoColumn::PHOTOS_TABLE + " WHERE " + MediaColumn::MEDIA_DURATION + " = " + ABNORMAL_VALUE +
298 " AND " + MediaColumn::MEDIA_TYPE + " = " + std::to_string(MEDIA_TYPE_VIDEO) + " AND " + filterCondition;
299
300 const string totalAbnormalRecordSql = "SELECT COUNT(*) AS " + RECORD_COUNT + " FROM " +
301 PhotoColumn::PHOTOS_TABLE + " WHERE (" + MediaColumn::MEDIA_SIZE + " = 0 OR " +
302 MediaColumn::MEDIA_SIZE + " IS NULL OR " + MediaColumn::MEDIA_MIME_TYPE + " IS NULL OR " +
303 MediaColumn::MEDIA_MIME_TYPE + " = '' OR " + PhotoColumn::PHOTO_HEIGHT + " = 0 OR " +
304 PhotoColumn::PHOTO_HEIGHT + " IS NULL OR " + PhotoColumn::PHOTO_WIDTH + " = 0 OR " +
305 PhotoColumn::PHOTO_WIDTH + " IS NULL OR ((" + MediaColumn::MEDIA_DURATION + " IS NULL OR " +
306 MediaColumn::MEDIA_DURATION + " = 0 ) AND " + MediaColumn::MEDIA_TYPE + " = " +
307 std::to_string(MEDIA_TYPE_VIDEO) + " )) AND " + filterCondition;
308
309 const string duplicateLpathCountQuerySql = GetDuplicateLpathCountQuerrySql();
310 const string abnormalLpathCountQuerySql = GetAbnormalLpathCountQuerySql();
311
312 int32_t ret = ParseResultSet(imageAndVideoCountQuerySql, MEDIA_TYPE_VIDEO, photoRecordInfo.videoCount);
313 ret = ParseResultSet(imageAndVideoCountQuerySql, MEDIA_TYPE_IMAGE, photoRecordInfo.imageCount) && ret;
314 ret = ParseResultSet(abnormalSizeCountQuerySql, 0, photoRecordInfo.abnormalSizeCount) && ret;
315 ret = ParseResultSet(abnormalWidthHeightQuerySql, 0, photoRecordInfo.abnormalWidthOrHeightCount) && ret;
316 ret = ParseResultSet(abnormalVideoDurationQuerySql, 0, photoRecordInfo.abnormalVideoDurationCount) && ret;
317 ret = ParseResultSet(totalAbnormalRecordSql, 0, photoRecordInfo.toBeUpdatedRecordCount) && ret;
318 ret = ParseResultSet(duplicateLpathCountQuerySql, 0, photoRecordInfo.duplicateLpathCount) && ret;
319 ret = ParseResultSet(abnormalLpathCountQuerySql, 0, photoRecordInfo.abnormalLpathCount) && ret;
320
321 BuildDbInfo(photoRecordInfo);
322 return ret;
323 }
324
QueryOperationRecordInfo(OperationRecordInfo & operationRecordInfo)325 int32_t DfxDatabaseUtils::QueryOperationRecordInfo(OperationRecordInfo &operationRecordInfo)
326 {
327 const string addTotalCountQuerySql = "SELECT COUNT(*) FROM " + PhotoColumn::TAB_ASSET_AND_ALBUM_OPERATION_TABLE +
328 " WHERE " + DFX_OPT_TYPE + " = " + OPT_ADD_VALUE;
329 const string delTotalCountQuerySql = "SELECT COUNT(*) FROM " + PhotoColumn::TAB_ASSET_AND_ALBUM_OPERATION_TABLE +
330 " WHERE " + DFX_OPT_TYPE + " = " + OPT_DEL_VALUE;
331 const string updateTotalCountQuerySql = "SELECT COUNT(*) FROM " + PhotoColumn::TAB_ASSET_AND_ALBUM_OPERATION_TABLE +
332 " WHERE " + DFX_OPT_TYPE + " = " + OPT_UPDATE_VALUE;
333
334 bool ret = QueryOperationResultSet(addTotalCountQuerySql, operationRecordInfo.addTotalCount);
335 ret = QueryOperationResultSet(delTotalCountQuerySql, operationRecordInfo.delTotalCount) && ret;
336 ret = QueryOperationResultSet(updateTotalCountQuerySql, operationRecordInfo.updateTotalCount) && ret;
337 operationRecordInfo.totalCount = operationRecordInfo.addTotalCount + operationRecordInfo.delTotalCount +
338 operationRecordInfo.updateTotalCount;
339 return ret ? E_OK : E_FAIL;
340 }
341
QueryAnalysisVersion(const std::string & table,const std::string & column)342 int32_t DfxDatabaseUtils::QueryAnalysisVersion(const std::string &table, const std::string &column)
343 {
344 NativeRdb::RdbPredicates predicates(table);
345 string whereClause = "max(" + column + ") AS version";
346 std::vector<std::string> columns = { whereClause };
347 string version = "version";
348 double count;
349 int32_t errCode = QueryDouble(predicates, columns, version, count);
350 if (errCode != E_OK) {
351 MEDIA_ERR_LOG("query analysis version fail: %{public}d", errCode);
352 }
353 return static_cast<int32_t> (count);
354 }
355
QueryDbVersion()356 int32_t DfxDatabaseUtils::QueryDbVersion()
357 {
358 int64_t dbVersion = 0;
359 MediaLibraryRdbStore::QueryPragma("user_version", dbVersion);
360 return static_cast<int32_t> (dbVersion);
361 }
362
QueryInt(const NativeRdb::AbsRdbPredicates & predicates,const std::vector<std::string> & columns,const std::string & queryColumn,int32_t & value)363 int32_t DfxDatabaseUtils::QueryInt(const NativeRdb::AbsRdbPredicates &predicates,
364 const std::vector<std::string> &columns, const std::string &queryColumn, int32_t &value)
365 {
366 auto resultSet = MediaLibraryRdbStore::QueryWithFilter(predicates, columns);
367 if (resultSet == nullptr || resultSet->GoToFirstRow() != NativeRdb::E_OK) {
368 return E_DB_FAIL;
369 }
370 value = GetInt32Val(queryColumn, resultSet);
371 return E_OK;
372 }
373
QueryDouble(const NativeRdb::AbsRdbPredicates & predicates,const std::vector<std::string> & columns,const std::string & queryColumn,double & value)374 int32_t DfxDatabaseUtils::QueryDouble(const NativeRdb::AbsRdbPredicates &predicates,
375 const std::vector<std::string> &columns, const std::string &queryColumn, double &value)
376 {
377 auto resultSet = MediaLibraryRdbStore::QueryWithFilter(predicates, columns);
378 if (resultSet == nullptr || resultSet->GoToFirstRow() != NativeRdb::E_OK) {
379 return E_DB_FAIL;
380 }
381 value = GetDoubleVal(queryColumn, resultSet);
382 return E_OK;
383 }
384
QueryDownloadedAndGeneratedThumb(int32_t & downloadedThumb,int32_t & generatedThumb)385 int32_t DfxDatabaseUtils::QueryDownloadedAndGeneratedThumb(int32_t& downloadedThumb, int32_t& generatedThumb)
386 {
387 // cloud image that are all generated
388 NativeRdb::RdbPredicates generatePredicates(PhotoColumn::PHOTOS_TABLE);
389 std::vector<std::string> columns = { "count(1) AS count" };
390 std::string queryColumn = "count";
391 int32_t cloudImage = 2;
392 int32_t thumbGeneratedFinished = 2;
393 generatePredicates.GreaterThanOrEqualTo(PhotoColumn::PHOTO_POSITION, cloudImage)->And()
394 ->GreaterThanOrEqualTo(PhotoColumn::PHOTO_THUMBNAIL_READY, thumbGeneratedFinished);
395 int32_t errCode = QueryInt(generatePredicates, columns, queryColumn, generatedThumb);
396 if (errCode != E_OK) {
397 MEDIA_ERR_LOG("query generated image fail: %{public}d", errCode);
398 return errCode;
399 }
400
401 // cloud image that are downloaded
402 NativeRdb::RdbPredicates downloadPredicates(PhotoColumn::PHOTOS_TABLE);
403 downloadPredicates.GreaterThanOrEqualTo(PhotoColumn::PHOTO_POSITION, cloudImage)->And()
404 ->EqualTo(PhotoColumn::PHOTO_THUMB_STATUS, 0);
405 errCode = QueryInt(downloadPredicates, columns, queryColumn, downloadedThumb);
406 if (errCode != E_OK) {
407 MEDIA_ERR_LOG("query downloaded image fail: %{public}d", errCode);
408 return errCode;
409 }
410 return E_OK;
411 }
412
QueryASTCThumb(bool isLocal)413 int32_t DfxDatabaseUtils::QueryASTCThumb(bool isLocal)
414 {
415 NativeRdb::RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
416
417 int32_t localImage = 1;
418 int32_t cloudImage = 2;
419 int32_t localAndCloudImage = 3;
420 int32_t thumbnail_ready = 3;
421 if (isLocal) {
422 predicates.BeginWrap();
423 predicates.EqualTo(PhotoColumn::PHOTO_POSITION, localImage);
424 predicates.Or()->EqualTo(PhotoColumn::PHOTO_POSITION, localAndCloudImage);
425 predicates.EndWrap();
426 } else {
427 predicates.EqualTo(PhotoColumn::PHOTO_POSITION, cloudImage);
428 }
429
430 predicates.And()
431 ->GreaterThanOrEqualTo(PhotoColumn::PHOTO_THUMBNAIL_READY, thumbnail_ready);
432
433 std::vector<std::string> columns = { "count(1) AS count" };
434 std::string queryColumn = "count";
435 int32_t count = 0;
436 int32_t errCode = QueryInt(predicates, columns, queryColumn, count);
437 if (errCode != E_OK) {
438 MEDIA_ERR_LOG("query astc thumb fail: %{public}d", errCode);
439 }
440
441 return count;
442 }
443
QueryLCDThumb(bool isLocal)444 int32_t DfxDatabaseUtils::QueryLCDThumb(bool isLocal)
445 {
446 NativeRdb::RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
447
448 int32_t lcd_visit_time = 2;
449 int32_t localImage = 1;
450 int32_t cloudImage = 2;
451 int32_t localAndCloudImage = 3;
452 int32_t localThumb = 0;
453 int32_t cloudThumb = 2;
454 if (isLocal) {
455 predicates.BeginWrap();
456 predicates.EqualTo(PhotoColumn::PHOTO_POSITION, localImage);
457 predicates.And()->EqualTo(PhotoColumn::PHOTO_LCD_VISIT_TIME, lcd_visit_time);
458 predicates.EndWrap();
459 predicates.Or()->BeginWrap();
460 predicates.BeginWrap();
461 predicates.EqualTo(PhotoColumn::PHOTO_LCD_VISIT_TIME, lcd_visit_time);
462 predicates.Or()->EqualTo(PhotoColumn::PHOTO_THUMB_STATUS, localThumb);
463 predicates.Or()->EqualTo(PhotoColumn::PHOTO_THUMB_STATUS, cloudThumb);
464 predicates.EndWrap();
465 predicates.And()->EqualTo(PhotoColumn::PHOTO_POSITION, localAndCloudImage);
466 predicates.EndWrap();
467 } else {
468 predicates.BeginWrap();
469 predicates.EqualTo(PhotoColumn::PHOTO_THUMB_STATUS, localThumb);
470 predicates.Or()->EqualTo(PhotoColumn::PHOTO_THUMB_STATUS, cloudThumb);
471 predicates.EndWrap();
472 predicates.And()->EqualTo(PhotoColumn::PHOTO_POSITION, cloudImage);
473 }
474
475 std::vector<std::string> columns = { "count(1) AS count" };
476 std::string queryColumn = "count";
477
478 int32_t count = 0;
479 int32_t errCode = QueryInt(predicates, columns, queryColumn, count);
480 if (errCode != E_OK) {
481 MEDIA_ERR_LOG("query lcd thumb fail: %{public}d", errCode);
482 }
483
484 return count;
485 }
486
QueryPhotoFilePath(const shared_ptr<MediaLibraryRdbStore> rdbStore,int offset)487 static shared_ptr<NativeRdb::ResultSet> QueryPhotoFilePath(
488 const shared_ptr<MediaLibraryRdbStore> rdbStore, int offset)
489 {
490 string querySql = "SELECT " + MediaColumn::MEDIA_FILE_PATH + " FROM " + PhotoColumn::PHOTOS_TABLE +
491 " WHERE " + PhotoColumn::PHOTO_POSITION + " = 1" +
492 " LIMIT " + std::to_string(offset) + ", " + std::to_string(BATCH_QUERY_PHOTO_NUMBER);
493 return rdbStore->QuerySql(querySql);
494 }
495
CheckChargingAndScreenOff(bool isReported)496 bool DfxDatabaseUtils::CheckChargingAndScreenOff(bool isReported)
497 {
498 bool bFlag = PowerEfficiencyManager::IsChargingAndScreenOff();
499 if (bFlag) {
500 return bFlag;
501 }
502 int32_t errCode;
503 shared_ptr<NativePreferences::Preferences> prefs =
504 NativePreferences::PreferencesHelper::GetPreferences(DFX_COMMON_XML, errCode);
505 if (!prefs) {
506 MEDIA_ERR_LOG("get preferences error: %{public}d", errCode);
507 return bFlag;
508 }
509 if (isReported) {
510 int64_t time = MediaFileUtils::UTCTimeSeconds() - TWO_DAY;
511 MEDIA_INFO_LOG("change to last two day time");
512 prefs->PutLong(LAST_TWO_DAY_REPORT_TIME, time);
513 } else {
514 int64_t time = MediaFileUtils::UTCTimeSeconds() - ONE_WEEK;
515 MEDIA_INFO_LOG("change to last week day time");
516 prefs->PutLong(LAST_WEEK_REPORT_TIME, time);
517 }
518 prefs->FlushSync();
519 return bFlag;
520 }
521
QueryPhotoErrorCount()522 int32_t DfxDatabaseUtils::QueryPhotoErrorCount()
523 {
524 MEDIA_DEBUG_LOG("QueryPhotoErrorCount start");
525 MediaLibraryTracer tracer;
526 tracer.Start("QueryPhotoErrorCount");
527 auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
528 CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, E_OK, "rdbStore is nullptr");
529 std::string querySql = "SELECT count(1) as count FROM " + PhotoColumn::PHOTOS_TABLE + " WHERE " +
530 PhotoColumn::PHOTO_POSITION + " = 1";
531 shared_ptr<NativeRdb::ResultSet> resultCount = rdbStore->QuerySql(querySql);
532 CHECK_AND_RETURN_RET_LOG(resultCount != nullptr, E_OK, "Failed to query resultCount");
533 int32_t count = 0;
534 if (resultCount->GoToNextRow() == NativeRdb::E_OK) {
535 count = GetInt32Val("count", resultCount);
536 MEDIA_INFO_LOG("position == one ,count: %{public}d", count);
537 }
538 resultCount->Close();
539 CHECK_AND_RETURN_RET_LOG(count > 0, E_OK, "Failed to get count");
540 int32_t photoCount = 0;
541 for (int32_t offset = 0; offset < count; offset += BATCH_QUERY_PHOTO_NUMBER) {
542 if (!CheckChargingAndScreenOff(true)) {
543 MEDIA_ERR_LOG("Charging and screen off");
544 return E_OK;
545 }
546 auto resultSet = QueryPhotoFilePath(rdbStore, offset);
547 CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, E_OK, "Failed to query resultSet");
548 while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
549 string filePath = GetStringVal(MediaColumn::MEDIA_FILE_PATH, resultSet);
550 if (!PhotoFileUtils::IsThumbnailExists(filePath)) {
551 MEDIA_ERR_LOG("Invali date thumbnail, file path: %{private}s", filePath.c_str());
552 continue;
553 }
554 if (!MediaFileUtils::IsFileExists(filePath)) {
555 MEDIA_ERR_LOG("File not exists, file path: %{private}s", filePath.c_str());
556 photoCount++;
557 }
558 }
559 resultSet->Close();
560 }
561 return photoCount;
562 }
563
QueryTotalCloudThumb(int32_t & totalDownload)564 int32_t DfxDatabaseUtils::QueryTotalCloudThumb(int32_t& totalDownload)
565 {
566 int32_t cloudImage = 2;
567 NativeRdb::RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
568 predicates.GreaterThanOrEqualTo(PhotoColumn::PHOTO_POSITION, cloudImage);
569 std::vector<std::string> columns = { "count(1) AS count" };
570 std::string queryColumn = "count";
571 int32_t errCode = QueryInt(predicates, columns, queryColumn, totalDownload);
572 if (errCode != E_OK) {
573 MEDIA_ERR_LOG("query total download image fail: %{public}d", errCode);
574 return errCode;
575 }
576 return E_OK;
577 }
578
UpdatePhotoSizeMap(const int64_t size,std::unordered_map<std::string,int32_t> & photoSizeMap)579 static void UpdatePhotoSizeMap(const int64_t size, std::unordered_map<std::string, int32_t> &photoSizeMap)
580 {
581 if (size <= 0) {
582 MEDIA_ERR_LOG("is wrong size");
583 return;
584 }
585 int64_t fileSize = size / PHOTO_FILE_SIZE;
586 for (const auto &range : sizeRanges) {
587 if (fileSize <= range.first) {
588 photoSizeMap[range.second]++;
589 return;
590 }
591 }
592 photoSizeMap["sizeOther"]++;
593 }
594
UpdatePhotoResolutionMap(const int32_t height,const int32_t width,std::unordered_map<std::string,int32_t> & resolutionMap)595 static void UpdatePhotoResolutionMap(const int32_t height, const int32_t width,
596 std::unordered_map<std::string, int32_t> &resolutionMap)
597 {
598 int32_t min = std::min(height, width);
599 int32_t max = std::max(height, width);
600 if (max < FILE_HEIGHT_AND_WIDTH_2000) {
601 if (min < FILE_HEIGHT_AND_WIDTH_240) {
602 resolutionMap["resolutionLess240P"]++;
603 } else if (min >= FILE_HEIGHT_AND_WIDTH_240 && min < FILE_HEIGHT_AND_WIDTH_360) {
604 resolutionMap["resolution240P"]++;
605 } else if (min >= FILE_HEIGHT_AND_WIDTH_360 && min < FILE_HEIGHT_AND_WIDTH_480) {
606 resolutionMap["resolution360P"]++;
607 } else if (min >= FILE_HEIGHT_AND_WIDTH_480 && min < FILE_HEIGHT_AND_WIDTH_720) {
608 resolutionMap["resolution480P"]++;
609 } else if (min >= FILE_HEIGHT_AND_WIDTH_720 && min < FILE_HEIGHT_AND_WIDTH_1080) {
610 resolutionMap["resolution720P"]++;
611 } else if (min >= FILE_HEIGHT_AND_WIDTH_1080 && min < FILE_HEIGHT_AND_WIDTH_1440) {
612 resolutionMap["resolution1080P"]++;
613 } else {
614 MEDIA_ERR_LOG("is wrong resolution");
615 }
616 } else {
617 if (min >= FILE_HEIGHT_AND_WIDTH_1440 && max < FILE_HEIGHT_AND_WIDTH_4000) {
618 resolutionMap["resolution2K"]++;
619 } else if (min >= FILE_HEIGHT_AND_WIDTH_1440 && max >= FILE_HEIGHT_AND_WIDTH_4000) {
620 resolutionMap["resolution4K"]++;
621 } else {
622 MEDIA_ERR_LOG("is wrong resolution");
623 }
624 }
625 }
626
UpdateVideoResolutionMap(const int32_t height,const int32_t width,std::unordered_map<std::string,int32_t> & resolutionMap)627 static void UpdateVideoResolutionMap(const int32_t height, const int32_t width,
628 std::unordered_map<std::string, int32_t> &resolutionMap)
629 {
630 int32_t min = std::min(height, width);
631 int32_t max = std::max(height, width);
632 if (min < FILE_HEIGHT_AND_WIDTH_720 && max < FILE_HEIGHT_AND_WIDTH_2000) {
633 resolutionMap["resolutionLess720P"]++;
634 } else if (min >= FILE_HEIGHT_AND_WIDTH_720 && min < FILE_HEIGHT_AND_WIDTH_1080 &&
635 max < FILE_HEIGHT_AND_WIDTH_2000) {
636 resolutionMap["resolution720P"]++;
637 } else if (min >= FILE_HEIGHT_AND_WIDTH_1080 && min < FILE_HEIGHT_AND_WIDTH_1440 &&
638 max < FILE_HEIGHT_AND_WIDTH_2000) {
639 resolutionMap["resolution1080P"]++;
640 } else if (min >= FILE_HEIGHT_AND_WIDTH_1440 && max < FILE_HEIGHT_AND_WIDTH_4000 &&
641 max >= FILE_HEIGHT_AND_WIDTH_2000) {
642 resolutionMap["resolution2K"]++;
643 } else if (min >= FILE_HEIGHT_AND_WIDTH_1440 && max >= FILE_HEIGHT_AND_WIDTH_4000) {
644 resolutionMap["resolution4K"]++;
645 } else {
646 MEDIA_ERR_LOG("is wrong resolution");
647 }
648 }
649
GetPhotoMimeType(std::string & photoMimeType)650 void DfxDatabaseUtils::GetPhotoMimeType(std::string &photoMimeType)
651 {
652 auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
653 CHECK_AND_RETURN_LOG(rdbStore != nullptr, "rdbStore is nullptr");
654 std::string querySql = "SELECT " + MediaColumn::MEDIA_MIME_TYPE + ", COUNT(*) AS count FROM " +
655 PhotoColumn::PHOTOS_TABLE + " WHERE " + PhotoColumn::PHOTO_IS_TEMP + " = 0 AND " +
656 PhotoColumn::MEDIA_DATE_TRASHED + " = 0 AND " + PhotoColumn::PHOTO_BURST_COVER_LEVEL +
657 " = 1 GROUP BY " + MediaColumn::MEDIA_MIME_TYPE;
658 shared_ptr<NativeRdb::ResultSet> resultSet = rdbStore->QuerySql(querySql);
659 CHECK_AND_RETURN_LOG(resultSet != nullptr, "Failed to query resultCount");
660 while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
661 string mediaType = GetStringVal(MediaColumn::MEDIA_MIME_TYPE, resultSet);
662 int32_t count = GetInt32Val("count", resultSet);
663 photoMimeType += mediaType + ":" + std::to_string(count) + ", ";
664 }
665 resultSet->Close();
666 }
667
StatisticsSizeAndResolution(shared_ptr<NativeRdb::ResultSet> & resultSet,SizeAndResolutionInfoMap & infoMap)668 static void StatisticsSizeAndResolution(shared_ptr<NativeRdb::ResultSet> &resultSet,
669 SizeAndResolutionInfoMap &infoMap)
670 {
671 CHECK_AND_RETURN_LOG(resultSet != nullptr, "Failed to statistics");
672 int32_t position = GetInt64Val(PhotoColumn::PHOTO_POSITION, resultSet);
673 int32_t mediaType = GetInt64Val(MediaColumn::MEDIA_TYPE, resultSet);
674 int32_t height = GetInt64Val(PhotoColumn::PHOTO_HEIGHT, resultSet);
675 int32_t width = GetInt64Val(PhotoColumn::PHOTO_WIDTH, resultSet);
676 int64_t size = GetInt64Val(MediaColumn::MEDIA_SIZE, resultSet);
677 if (mediaType == MEDIA_TYPE_IMAGE) {
678 if (position == static_cast<int32_t>(PhotoPositionType::LOCAL)) {
679 UpdatePhotoSizeMap(size, infoMap.localImageSizeMap);
680 UpdatePhotoResolutionMap(height, width, infoMap.localImageResolutionMap);
681 } else {
682 UpdatePhotoSizeMap(size, infoMap.cloudImageSizeMap);
683 UpdatePhotoResolutionMap(height, width, infoMap.cloudImageResolutionMap);
684 }
685 } else if (mediaType == MEDIA_TYPE_VIDEO) {
686 if (position == static_cast<int32_t>(PhotoPositionType::LOCAL)) {
687 UpdatePhotoSizeMap(size, infoMap.localVideoSizeMap);
688 UpdateVideoResolutionMap(height, width, infoMap.localVideoResolutionMap);
689 } else {
690 UpdatePhotoSizeMap(size, infoMap.cloudVideoSizeMap);
691 UpdateVideoResolutionMap(height, width, infoMap.cloudVideoResolutionMap);
692 }
693 } else {
694 MEDIA_ERR_LOG("is wrong mediaType");
695 }
696 }
697
GetInfoToString(const unordered_map<string,int32_t> & defaultMap)698 static string GetInfoToString(const unordered_map<string, int32_t>& defaultMap)
699 {
700 std::string result;
701 for (const auto& pair : defaultMap) {
702 if (pair.second > 0) {
703 result += pair.first + ":" + std::to_string(pair.second) + "; ";
704 }
705 }
706 return result;
707 }
708
GetSizeAndResolutionInfo(QuerySizeAndResolution & queryInfo)709 bool DfxDatabaseUtils::GetSizeAndResolutionInfo(QuerySizeAndResolution &queryInfo)
710 {
711 auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
712 CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, false, "rdbStore is nullptr");
713 std::string querySql = "SELECT count(1) as count FROM " + PhotoColumn::PHOTOS_TABLE + " WHERE " +
714 PhotoColumn::PHOTO_IS_TEMP + " = 0 AND " + PhotoColumn::MEDIA_DATE_TRASHED + " = 0 AND " +
715 PhotoColumn::PHOTO_BURST_COVER_LEVEL + " = 1 ";
716 shared_ptr<NativeRdb::ResultSet> resultCount = rdbStore->QuerySql(querySql);
717 CHECK_AND_RETURN_RET_LOG(resultCount != nullptr, false, "Failed to query resultCount");
718 int32_t count = 0;
719 if (resultCount->GoToNextRow() == NativeRdb::E_OK) {
720 count = GetInt32Val("count", resultCount);
721 }
722 resultCount->Close();
723 CHECK_AND_RETURN_RET_LOG(count > 0, false, "Failed to get count");
724 SizeAndResolutionInfoMap infoMap;
725 for (int32_t offset = 0; offset < count; offset += BATCH_QUERY_PHOTO_NUMBER) {
726 if (!CheckChargingAndScreenOff(false)) {
727 MEDIA_ERR_LOG("Charging and screen off");
728 return false;
729 }
730 std::string querySql = "SELECT " + PhotoColumn::PHOTO_POSITION + ", " + MediaColumn::MEDIA_TYPE +
731 " , " + MediaColumn::MEDIA_SIZE + ", " + PhotoColumn::PHOTO_HEIGHT + ", " + PhotoColumn::PHOTO_WIDTH +
732 " FROM " + PhotoColumn::PHOTOS_TABLE + " WHERE " +
733 PhotoColumn::PHOTO_IS_TEMP + " = 0 AND " + PhotoColumn::MEDIA_DATE_TRASHED + " = 0 AND " +
734 PhotoColumn::PHOTO_BURST_COVER_LEVEL + " = 1 " +
735 " LIMIT " + std::to_string(offset) + ", " + std::to_string(BATCH_QUERY_PHOTO_NUMBER);
736
737 shared_ptr<NativeRdb::ResultSet> resultSet = rdbStore->QuerySql(querySql);
738 CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, false, "Failed to query resultCount");
739 while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
740 StatisticsSizeAndResolution(resultSet, infoMap);
741 }
742 resultSet->Close();
743 }
744 queryInfo.localImageSize = GetInfoToString(infoMap.localImageSizeMap);
745 queryInfo.localVideoSize = GetInfoToString(infoMap.localVideoSizeMap);
746 queryInfo.cloudImageSize = GetInfoToString(infoMap.cloudImageSizeMap);
747 queryInfo.cloudVideoSize = GetInfoToString(infoMap.cloudVideoSizeMap);
748 queryInfo.localImageResolution = GetInfoToString(infoMap.localImageResolutionMap);
749 queryInfo.localVideoResolution = GetInfoToString(infoMap.localVideoResolutionMap);
750 queryInfo.cloudImageResolution = GetInfoToString(infoMap.cloudImageResolutionMap);
751 queryInfo.cloudVideoResolution = GetInfoToString(infoMap.cloudVideoResolutionMap);
752 return true;
753 }
754 } // namespace Media
755 } // namespace OHOS