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 #define MLOG_TAG "MediaLibraryCloudUploadChecker"
17
18 #include "cloud_upload_checker.h"
19
20 #include "media_file_utils.h"
21 #include "media_file_uri.h"
22 #include "medialibrary_unistore_manager.h"
23 #include "photo_album_column.h"
24 #include "thumbnail_const.h"
25 #include "media_column.h"
26 #include "preferences.h"
27 #include "preferences_helper.h"
28 #include "result_set_utils.h"
29 #include "thumbnail_const.h"
30 #include "medialibrary_object_utils.h"
31 #include "medialibrary_photo_operations.h"
32
33 namespace OHOS {
34 namespace Media {
35 using namespace std;
36 using namespace NativeRdb;
37 const std::string BATCH_SIZE = "500";
38 const std::string TASK_PROGRESS_XML = "/data/storage/el2/base/preferences/task_progress.xml";
39 const std::string NO_ORIGIN_PHOTO_NUMBER = "no_origin_photo_number";
40
41 static const int32_t NO_ORIGIN_BUT_LCD = 100;
42 static const int32_t NO_ORIGIN_NO_LCD = 101;
43
HandleNoOriginPhoto()44 void CloudUploadChecker::HandleNoOriginPhoto()
45 {
46 MEDIA_INFO_LOG("start handle no origin photo!");
47 int32_t errCode;
48 shared_ptr<NativePreferences::Preferences> prefs =
49 NativePreferences::PreferencesHelper::GetPreferences(TASK_PROGRESS_XML, errCode);
50 if (!prefs) {
51 MEDIA_ERR_LOG("get preferences error: %{public}d", errCode);
52 return;
53 }
54 int32_t curFileId = prefs->GetInt(NO_ORIGIN_PHOTO_NUMBER, 0);
55 MEDIA_INFO_LOG("start file id: %{public}d", curFileId);
56 while (GetPhotoCount(curFileId) > 0) {
57 MEDIA_INFO_LOG("start handle origin photo start: %{public}d", curFileId);
58 int32_t nextFileId = curFileId;
59 std::vector<CheckedPhotoInfo> photoInfos = QueryPhotoInfo(curFileId, nextFileId);
60 HandlePhotoInfos(photoInfos);
61 curFileId = nextFileId + 1;
62 prefs->PutInt(NO_ORIGIN_PHOTO_NUMBER, curFileId);
63 prefs->FlushSync();
64 }
65 MEDIA_INFO_LOG("end handle no origin photo!");
66 return;
67 }
68
HandlePhotoInfos(std::vector<CheckedPhotoInfo> photoInfos)69 void CloudUploadChecker::HandlePhotoInfos(std::vector<CheckedPhotoInfo> photoInfos)
70 {
71 std::vector<std::string> lcdList;
72 std::vector<std::string> noLcdList;
73 for (CheckedPhotoInfo photoInfo: photoInfos) {
74 if (MediaFileUtils::IsFileExists(photoInfo.path)) {
75 continue;
76 }
77 string lcdPath = GetThumbnailPath(photoInfo.path, THUMBNAIL_LCD_SUFFIX);
78 if (MediaFileUtils::IsFileExists(lcdPath)) {
79 lcdList.push_back(to_string(photoInfo.fileId));
80 } else {
81 noLcdList.push_back(to_string(photoInfo.fileId));
82 }
83 }
84 if (!lcdList.empty()) {
85 UpdateDirty(lcdList, NO_ORIGIN_BUT_LCD);
86 }
87 if (!noLcdList.empty()) {
88 UpdateDirty(noLcdList, NO_ORIGIN_NO_LCD);
89 }
90 }
91
UpdateDirty(std::vector<std::string> idList,int32_t dirtyType)92 void CloudUploadChecker::UpdateDirty(std::vector<std::string> idList, int32_t dirtyType)
93 {
94 auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
95 if (rdbStore == nullptr) {
96 MEDIA_ERR_LOG("Failed to get rdbstore!");
97 return;
98 }
99 RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
100 predicates.In(MediaColumn::MEDIA_ID, idList);
101 ValuesBucket values;
102 values.PutInt(PhotoColumn::PHOTO_DIRTY, dirtyType);
103 int32_t updateCount = 0;
104 int32_t err = rdbStore->Update(updateCount, values, predicates);
105 MEDIA_INFO_LOG("dirty: %{public}d, idList size: %{public}d, update size: %{public}d, err: %{public}d", dirtyType,
106 static_cast<int32_t>(idList.size()), updateCount, err);
107 }
108
GetPhotoCount(int32_t startFileId)109 int32_t CloudUploadChecker::GetPhotoCount(int32_t startFileId)
110 {
111 auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
112 if (rdbStore == nullptr) {
113 MEDIA_ERR_LOG("Failed to get rdbstore!");
114 return 0;
115 }
116 std::string queryCount = " COUNT(*) AS Count";
117 std::string sql = GetQuerySql(startFileId, queryCount);
118 std::shared_ptr<NativeRdb::ResultSet> resultSet = rdbStore->QuerySql(sql);
119 if (resultSet == nullptr || resultSet->GoToFirstRow() != NativeRdb::E_OK) {
120 MEDIA_ERR_LOG("resultSet is null or count is 0");
121 return 0;
122 }
123 int32_t count = get<int32_t>(ResultSetUtils::GetValFromColumn("Count", resultSet, TYPE_INT32));
124 return count;
125 }
126
GetQuerySql(int32_t startFileId,std::string mediaColumns)127 std::string CloudUploadChecker::GetQuerySql(int32_t startFileId, std::string mediaColumns)
128 {
129 const std::string sql = "SELECT " + mediaColumns + " FROM Photos WHERE dirty = 1 AND thumbnail_ready >= 3 AND " +
130 "lcd_visit_time >= 2 AND date_trashed = 0 AND file_id > " + to_string(startFileId) + " LIMIT " + BATCH_SIZE;
131 return sql;
132 }
133
QueryPhotoInfo(int32_t startFileId,int32_t & outFileId)134 std::vector<CheckedPhotoInfo> CloudUploadChecker::QueryPhotoInfo(int32_t startFileId, int32_t &outFileId)
135 {
136 std::vector<CheckedPhotoInfo> photoInfos;
137 auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
138 if (rdbStore == nullptr) {
139 MEDIA_ERR_LOG("Failed to get rdbstore!");
140 return photoInfos;
141 }
142 const std::string mediaColumns = Media::PhotoColumn::MEDIA_ID + ", " + Media::PhotoColumn::MEDIA_FILE_PATH;
143 std::string sql = GetQuerySql(startFileId, mediaColumns);
144 std::shared_ptr<NativeRdb::ResultSet> resultSet = rdbStore->QuerySql(sql);
145 if (resultSet == nullptr || resultSet->GoToFirstRow() != NativeRdb::E_OK) {
146 MEDIA_ERR_LOG("resultSet is null or count is 0");
147 return photoInfos;
148 }
149 int32_t fileId = startFileId;
150 while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
151 CheckedPhotoInfo photoInfo;
152 std::string path =
153 get<std::string>(ResultSetUtils::GetValFromColumn(MediaColumn::MEDIA_FILE_PATH, resultSet, TYPE_STRING));
154 if (path.empty()) {
155 MEDIA_WARN_LOG("Failed to get data path");
156 continue;
157 }
158 fileId = get<int32_t>(ResultSetUtils::GetValFromColumn(MediaColumn::MEDIA_ID, resultSet, TYPE_INT32));
159 photoInfo.fileId = fileId;
160 photoInfo.path = path;
161 photoInfos.push_back(photoInfo);
162 }
163 outFileId = fileId;
164 return photoInfos;
165 }
166 } // namespace Media
167 } // namespace OHOS