1 /*
2 * Copyright (c) 2023 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 #define MLOG_TAG "VisionOperation"
16
17 #include <ctime>
18 #include <cmath>
19 #include <thread>
20 #include "media_analysis_helper.h"
21 #include "media_file_utils.h"
22 #include "media_log.h"
23 #include "medialibrary_data_manager.h"
24 #include "medialibrary_db_const.h"
25 #include "medialibrary_errno.h"
26 #include "medialibrary_rdb_utils.h"
27 #include "medialibrary_unistore_manager.h"
28 #include "medialibrary_vision_operations.h"
29 #include "medialibrary_rdb_transaction.h"
30 #include "medialibrary_rdbstore.h"
31 #include "rdb_utils.h"
32 #include "vision_aesthetics_score_column.h"
33 #include "vision_column.h"
34 #include "vision_total_column.h"
35 #include "vision_recommendation_column.h"
36 #include "user_photography_info_column.h"
37
38 using namespace std;
39 using namespace OHOS::NativeRdb;
40 using Uri = OHOS::Uri;
41 using namespace OHOS::DataShare;
42 using namespace OHOS::RdbDataShareAdapter;
43
44 namespace OHOS {
45 namespace Media {
46 static vector<int> NEED_UPDATE_TYPE = {
47 PhotoAlbumSubType::CLASSIFY, PhotoAlbumSubType::PORTRAIT
48 };
InsertOperation(MediaLibraryCommand & cmd)49 int32_t MediaLibraryVisionOperations::InsertOperation(MediaLibraryCommand &cmd)
50 {
51 auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
52 if (rdbStore == nullptr) {
53 return E_HAS_DB_ERROR;
54 }
55 int64_t outRowId = -1;
56 int32_t errCode = rdbStore->Insert(cmd, outRowId);
57 if (errCode != NativeRdb::E_OK || outRowId < 0) {
58 MEDIA_ERR_LOG("Insert into db failed, errCode = %{public}d", errCode);
59 return E_HAS_DB_ERROR;
60 }
61 return static_cast<int32_t>(outRowId);
62 }
63
UpdateOperation(MediaLibraryCommand & cmd)64 int32_t MediaLibraryVisionOperations::UpdateOperation(MediaLibraryCommand &cmd)
65 {
66 auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
67 if (rdbStore == nullptr) {
68 return E_HAS_DB_ERROR;
69 }
70 int32_t updateRows = -1;
71 int32_t errCode = rdbStore->Update(cmd, updateRows);
72 if (errCode != NativeRdb::E_OK || updateRows < 0) {
73 MEDIA_ERR_LOG("Update db failed, errCode = %{public}d", errCode);
74 return E_HAS_DB_ERROR;
75 }
76 return static_cast<int32_t>(updateRows);
77 }
78
DeleteOperation(MediaLibraryCommand & cmd)79 int32_t MediaLibraryVisionOperations::DeleteOperation(MediaLibraryCommand &cmd)
80 {
81 auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
82 if (rdbStore == nullptr) {
83 return E_HAS_DB_ERROR;
84 }
85 int32_t deleteRows = -1;
86 int32_t errCode = rdbStore->Delete(cmd, deleteRows);
87 if (errCode != NativeRdb::E_OK || deleteRows < 0) {
88 MEDIA_ERR_LOG("Delete db failed, errCode = %{public}d", errCode);
89 return E_HAS_DB_ERROR;
90 }
91 return static_cast<int32_t>(deleteRows);
92 }
93
QueryOperation(MediaLibraryCommand & cmd,const std::vector<std::string> & columns)94 shared_ptr<NativeRdb::ResultSet> MediaLibraryVisionOperations::QueryOperation(MediaLibraryCommand &cmd,
95 const std::vector<std::string> &columns)
96 {
97 auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
98 if (rdbStore == nullptr) {
99 return nullptr;
100 }
101 return rdbStore->Query(cmd, columns);
102 }
103
UpdateAnalysisTotal(string & uriTotal,string & selection,const string & columnName)104 static int32_t UpdateAnalysisTotal(string &uriTotal, string &selection, const string &columnName)
105 {
106 Uri uri = Uri(uriTotal);
107 DataSharePredicates predicate;
108 predicate.SetWhereClause(selection);
109 MediaLibraryCommand cmdTotal(uri);
110 DataShareValuesBucket valueBucket;
111 valueBucket.Put(STATUS, 0);
112 valueBucket.Put(columnName, 0);
113 return MediaLibraryDataManager::GetInstance()->Update(cmdTotal, valueBucket, predicate);
114 }
115
DeleteFromVisionTables(string & fileId,string & selectionTotal,const string & columnTotal,const string & tableName)116 static int32_t DeleteFromVisionTables(string &fileId, string &selectionTotal,
117 const string &columnTotal, const string &tableName)
118 {
119 string uriTotal = MEDIALIBRARY_DATA_URI + "/" + PAH_ANA_TOTAL;
120 int32_t updateRows = UpdateAnalysisTotal(uriTotal, selectionTotal, columnTotal);
121 MEDIA_DEBUG_LOG("Update %{public}d rows at total for edit commit to %{public}s", updateRows, columnTotal.c_str());
122 if (updateRows <= 0) {
123 return updateRows;
124 }
125
126 string uriTable = MEDIALIBRARY_DATA_URI + "/" + tableName;
127 Uri uri = Uri(uriTable);
128 DataSharePredicates predicate;
129 predicate.EqualTo(FILE_ID, fileId);
130 MediaLibraryCommand cmdTable(uri);
131 return MediaLibraryDataManager::GetInstance()->Delete(cmdTable, predicate);
132 }
133
DeleteFromVisionTablesForVideo(string & fileId,const string & tableName)134 static int32_t DeleteFromVisionTablesForVideo(string &fileId, const string &tableName)
135 {
136 string uriTable = MEDIALIBRARY_DATA_URI + "/" + tableName;
137 Uri uri = Uri(uriTable);
138 DataSharePredicates predicate;
139 predicate.EqualTo(FILE_ID, fileId);
140 MediaLibraryCommand cmdTable(uri);
141 return MediaLibraryDataManager::GetInstance()->Delete(cmdTable, predicate);
142 }
143
UpdateVisionTableForEdit(AsyncTaskData * taskData)144 static void UpdateVisionTableForEdit(AsyncTaskData *taskData)
145 {
146 if (taskData == nullptr) {
147 MEDIA_ERR_LOG("taskData is nullptr");
148 return;
149 }
150 UpdateVisionAsyncTaskData* data = static_cast<UpdateVisionAsyncTaskData*>(taskData);
151 if (data == nullptr) {
152 MEDIA_ERR_LOG("UpdateVisionAsyncTaskData is nullptr");
153 return;
154 }
155 string fileId = to_string(data->fileId_);
156
157 string selectionTotal = FILE_ID + " = " + fileId + " AND " + LABEL + " = 1";
158 DeleteFromVisionTables(fileId, selectionTotal, LABEL, PAH_ANA_LABEL);
159 DeleteFromVisionTablesForVideo(fileId, PAH_ANA_VIDEO_LABEL);
160
161 selectionTotal = FILE_ID + " = " + fileId + " AND " + AESTHETICS_SCORE + " = 1";
162 DeleteFromVisionTables(fileId, selectionTotal, AESTHETICS_SCORE, PAH_ANA_ATTS);
163
164 selectionTotal = FILE_ID + " = " + fileId + " AND " + OCR + " = 1";
165 DeleteFromVisionTables(fileId, selectionTotal, OCR, PAH_ANA_OCR);
166
167 selectionTotal = FILE_ID + " = " + fileId + " AND " + SALIENCY + " = 1";
168 DeleteFromVisionTables(fileId, selectionTotal, SALIENCY, PAH_ANA_SALIENCY);
169
170 selectionTotal = FILE_ID + " = " + fileId + " AND " + FACE + " IN (-2, 1, 2, 3, 4)";
171 DeleteFromVisionTables(fileId, selectionTotal, FACE, PAH_ANA_FACE);
172
173 selectionTotal = FILE_ID + " = " + fileId + " AND " + OBJECT + " = 1";
174 DeleteFromVisionTables(fileId, selectionTotal, OBJECT, PAH_ANA_OBJECT);
175
176 selectionTotal = FILE_ID + " = " + fileId + " AND " + RECOMMENDATION + " = 1";
177 DeleteFromVisionTables(fileId, selectionTotal, RECOMMENDATION, PAH_ANA_RECOMMENDATION);
178
179 selectionTotal = FILE_ID + " = " + fileId + " AND " + SEGMENTATION + " = 1";
180 DeleteFromVisionTables(fileId, selectionTotal, SEGMENTATION, PAH_ANA_SEGMENTATION);
181
182 selectionTotal = FILE_ID + " = " + fileId + " AND " + HEAD + " = 1";
183 DeleteFromVisionTables(fileId, selectionTotal, HEAD, PAH_ANA_HEAD);
184
185 selectionTotal = FILE_ID + " = " + fileId + " AND " + POSE + " = 1";
186 DeleteFromVisionTables(fileId, selectionTotal, POSE, PAH_ANA_POSE);
187
188 selectionTotal = FILE_ID + " = " + fileId + " AND " + AESTHETICS_SCORE_ALL_STATUS + " = 1";
189 DeleteFromVisionTables(fileId, selectionTotal, AESTHETICS_SCORE_ALL_STATUS, PAH_ANA_ATTS);
190 }
191
EditCommitOperation(MediaLibraryCommand & cmd)192 int32_t MediaLibraryVisionOperations::EditCommitOperation(MediaLibraryCommand &cmd)
193 {
194 if (cmd.GetOprnObject() != OperationObject::FILESYSTEM_PHOTO) {
195 return E_SUCCESS;
196 }
197 const ValuesBucket &values = cmd.GetValueBucket();
198 ValueObject valueObject;
199 int32_t fileId;
200 if (values.GetObject(PhotoColumn::MEDIA_ID, valueObject)) {
201 valueObject.GetInt(fileId);
202 } else {
203 return E_HAS_DB_ERROR;
204 }
205
206 shared_ptr<MediaLibraryAsyncWorker> asyncWorker = MediaLibraryAsyncWorker::GetInstance();
207 if (asyncWorker == nullptr) {
208 MEDIA_ERR_LOG("Can not get asyncWorker");
209 return E_ERR;
210 }
211 UpdateVisionAsyncTaskData* taskData = new (std::nothrow) UpdateVisionAsyncTaskData(fileId);
212 if (taskData == nullptr) {
213 MEDIA_ERR_LOG("Failed to new taskData");
214 return E_ERR;
215 }
216 shared_ptr<MediaLibraryAsyncTask> updateAsyncTask =
217 make_shared<MediaLibraryAsyncTask>(UpdateVisionTableForEdit, taskData);
218 if (updateAsyncTask != nullptr) {
219 asyncWorker->AddTask(updateAsyncTask, true);
220 } else {
221 MEDIA_ERR_LOG("UpdateAnalysisDataForEdit fail");
222 }
223 return E_SUCCESS;
224 }
225
HandleForegroundAnalysisOperation(MediaLibraryCommand & cmd)226 std::shared_ptr<NativeRdb::ResultSet> MediaLibraryVisionOperations::HandleForegroundAnalysisOperation(
227 MediaLibraryCommand &cmd)
228 {
229 std::shared_ptr<ForegroundAnalysisMeta> cvInfo = nullptr;
230 int32_t errCode = InitForegroundAnalysisMeta(cmd, cvInfo);
231 if (errCode != NativeRdb::E_OK) {
232 return nullptr;
233 }
234 errCode = cvInfo->GenerateOpType(cmd);
235 if (errCode != NativeRdb::E_OK) {
236 return nullptr;
237 }
238 cvInfo->StartAnalysisService();
239 return ForegroundAnalysisMeta::QueryByErrorCode(NativeRdb::E_OK);
240 }
241
InitForegroundAnalysisMeta(MediaLibraryCommand & cmd,std::shared_ptr<ForegroundAnalysisMeta> & infoPtr)242 int32_t MediaLibraryVisionOperations::InitForegroundAnalysisMeta(MediaLibraryCommand &cmd,
243 std::shared_ptr<ForegroundAnalysisMeta> &infoPtr)
244 {
245 auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
246 if (rdbStore == nullptr) {
247 return E_ERR;
248 }
249 RdbPredicates predicates(USER_PHOTOGRAPHY_INFO_TABLE);
250 vector<string> column = {
251 FRONT_INDEX_LIMIT, FRONT_INDEX_MODIFIED, FRONT_INDEX_COUNT, FRONT_CV_MODIFIED, FRONT_CV_COUNT
252 };
253 auto result = rdbStore->Query(predicates, column);
254 if (result == nullptr) {
255 return E_ERR;
256 }
257 infoPtr = make_shared<ForegroundAnalysisMeta>(result);
258 result->Close();
259 return E_OK;
260 }
261
PrepareDelayFgAnalysis(const std::string & assetUri,MediaType mediaType)262 int32_t MediaLibraryVisionOperations::PrepareDelayFgAnalysis(const std::string &assetUri,
263 MediaType mediaType)
264 {
265 int errCode = E_OK;
266 if (mediaType != MEDIA_TYPE_IMAGE && mediaType != MEDIA_TYPE_VIDEO) {
267 MEDIA_INFO_LOG("ignore media type:%{public}d", mediaType);
268 return errCode;
269 }
270 std::string photoUri = assetUri;
271 std::string fileId = MediaLibraryDataManagerUtils::GetFileIdFromPhotoUri(photoUri);
272 if (!fileId.empty()) {
273 DelayBatchTrigger::GetTrigger().Push({ fileId }, AnalysisType::ANALYSIS_SEARCH_INDEX);
274 }
275 return errCode;
276 }
277 }
278 }
279