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 auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
189 if (rdbStore == nullptr) {
190 MEDIA_ERR_LOG("Can not get rdbstore");
191 return;
192 }
193 MediaLibraryRdbUtils::UpdateAnalysisAlbumByFile(rdbStore, {fileId}, NEED_UPDATE_TYPE);
194 }
195
EditCommitOperation(MediaLibraryCommand & cmd)196 int32_t MediaLibraryVisionOperations::EditCommitOperation(MediaLibraryCommand &cmd)
197 {
198 if (cmd.GetOprnObject() != OperationObject::FILESYSTEM_PHOTO) {
199 return E_SUCCESS;
200 }
201 const ValuesBucket &values = cmd.GetValueBucket();
202 ValueObject valueObject;
203 int32_t fileId;
204 if (values.GetObject(PhotoColumn::MEDIA_ID, valueObject)) {
205 valueObject.GetInt(fileId);
206 } else {
207 return E_HAS_DB_ERROR;
208 }
209
210 shared_ptr<MediaLibraryAsyncWorker> asyncWorker = MediaLibraryAsyncWorker::GetInstance();
211 if (asyncWorker == nullptr) {
212 MEDIA_ERR_LOG("Can not get asyncWorker");
213 return E_ERR;
214 }
215 UpdateVisionAsyncTaskData* taskData = new (std::nothrow) UpdateVisionAsyncTaskData(fileId);
216 if (taskData == nullptr) {
217 MEDIA_ERR_LOG("Failed to new taskData");
218 return E_ERR;
219 }
220 shared_ptr<MediaLibraryAsyncTask> updateAsyncTask =
221 make_shared<MediaLibraryAsyncTask>(UpdateVisionTableForEdit, taskData);
222 if (updateAsyncTask != nullptr) {
223 asyncWorker->AddTask(updateAsyncTask, true);
224 } else {
225 MEDIA_ERR_LOG("UpdateAnalysisDataForEdit fail");
226 }
227 return E_SUCCESS;
228 }
229
HandleForegroundAnalysisOperation(MediaLibraryCommand & cmd)230 int32_t MediaLibraryVisionOperations::HandleForegroundAnalysisOperation(MediaLibraryCommand &cmd)
231 {
232 std::shared_ptr<ForegroundAnalysisMeta> cvInfo = nullptr;
233 int32_t errCode = InitForegroundAnalysisMeta(cmd, cvInfo);
234 if (errCode != NativeRdb::E_OK) {
235 return errCode;
236 }
237 errCode = cvInfo->GenerateOpType(cmd);
238 if (errCode != NativeRdb::E_OK) {
239 return errCode;
240 }
241 cvInfo->StartAnalysisService();
242 return NativeRdb::E_OK;
243 }
244
InitForegroundAnalysisMeta(MediaLibraryCommand & cmd,std::shared_ptr<ForegroundAnalysisMeta> & infoPtr)245 int32_t MediaLibraryVisionOperations::InitForegroundAnalysisMeta(MediaLibraryCommand &cmd,
246 std::shared_ptr<ForegroundAnalysisMeta> &infoPtr)
247 {
248 auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
249 if (rdbStore == nullptr) {
250 return E_ERR;
251 }
252 RdbPredicates predicates(USER_PHOTOGRAPHY_INFO_TABLE);
253 vector<string> column = {
254 FRONT_INDEX_LIMIT, FRONT_INDEX_MODIFIED, FRONT_INDEX_COUNT, FRONT_CV_MODIFIED, FRONT_CV_COUNT
255 };
256 auto result = rdbStore->Query(predicates, column);
257 if (result == nullptr) {
258 return E_ERR;
259 }
260 infoPtr = make_shared<ForegroundAnalysisMeta>(result);
261 result->Close();
262 return E_OK;
263 }
264
GenerateAndSubmitForegroundAnalysis()265 int32_t MediaLibraryVisionOperations::GenerateAndSubmitForegroundAnalysis()
266 {
267 Uri uri(PAH_UPDATE_ANA_FOREGROUND);
268 MediaLibraryCommand cmd(uri);
269 DataShare::DataSharePredicates predicates;
270 DataShareValuesBucket value;
271 value.Put(FOREGROUND_ANALYSIS_TYPE, AnalysisType::ANALYSIS_SEARCH_INDEX);
272 value.Put(FOREGROUND_ANALYSIS_TASK_ID, ForegroundAnalysisMeta::GetIncTaskId());
273 return MediaLibraryDataManager::GetInstance()->Update(cmd, value, predicates);
274 }
275 }
276 }
277