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 <thread>
18 #include "media_analysis_helper.h"
19 #include "media_log.h"
20 #include "medialibrary_data_manager.h"
21 #include "medialibrary_db_const.h"
22 #include "medialibrary_errno.h"
23 #include "medialibrary_rdb_utils.h"
24 #include "medialibrary_unistore_manager.h"
25 #include "medialibrary_vision_operations.h"
26 #include "medialibrary_rdb_transaction.h"
27 #include "medialibrary_rdbstore.h"
28 #include "rdb_utils.h"
29 #include "vision_aesthetics_score_column.h"
30 #include "vision_column.h"
31 #include "vision_total_column.h"
32 #include "vision_recommendation_column.h"
33
34 using namespace std;
35 using namespace OHOS::NativeRdb;
36 using Uri = OHOS::Uri;
37 using namespace OHOS::DataShare;
38 using namespace OHOS::RdbDataShareAdapter;
39
40 namespace OHOS {
41 namespace Media {
42 static vector<int> NEED_UPDATE_TYPE = {
43 PhotoAlbumSubType::CLASSIFY, PhotoAlbumSubType::PORTRAIT
44 };
InsertOperation(MediaLibraryCommand & cmd)45 int32_t MediaLibraryVisionOperations::InsertOperation(MediaLibraryCommand &cmd)
46 {
47 auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
48 if (rdbStore == nullptr) {
49 return E_HAS_DB_ERROR;
50 }
51 int64_t outRowId = -1;
52 int32_t errCode = rdbStore->Insert(cmd, outRowId);
53 if (errCode != NativeRdb::E_OK || outRowId < 0) {
54 MEDIA_ERR_LOG("Insert into db failed, errCode = %{public}d", errCode);
55 return E_HAS_DB_ERROR;
56 }
57 return static_cast<int32_t>(outRowId);
58 }
59
UpdateOperation(MediaLibraryCommand & cmd)60 int32_t MediaLibraryVisionOperations::UpdateOperation(MediaLibraryCommand &cmd)
61 {
62 auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
63 if (rdbStore == nullptr) {
64 return E_HAS_DB_ERROR;
65 }
66 int32_t updateRows = -1;
67 int32_t errCode = rdbStore->Update(cmd, updateRows);
68 if (errCode != NativeRdb::E_OK || updateRows < 0) {
69 MEDIA_ERR_LOG("Update db failed, errCode = %{public}d", errCode);
70 return E_HAS_DB_ERROR;
71 }
72 return static_cast<int32_t>(updateRows);
73 }
74
DeleteOperation(MediaLibraryCommand & cmd)75 int32_t MediaLibraryVisionOperations::DeleteOperation(MediaLibraryCommand &cmd)
76 {
77 auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
78 if (rdbStore == nullptr) {
79 return E_HAS_DB_ERROR;
80 }
81 int32_t deleteRows = -1;
82 int32_t errCode = rdbStore->Delete(cmd, deleteRows);
83 if (errCode != NativeRdb::E_OK || deleteRows < 0) {
84 MEDIA_ERR_LOG("Delete db failed, errCode = %{public}d", errCode);
85 return E_HAS_DB_ERROR;
86 }
87 return static_cast<int32_t>(deleteRows);
88 }
89
QueryOperation(MediaLibraryCommand & cmd,const std::vector<std::string> & columns)90 shared_ptr<NativeRdb::ResultSet> MediaLibraryVisionOperations::QueryOperation(MediaLibraryCommand &cmd,
91 const std::vector<std::string> &columns)
92 {
93 auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
94 if (rdbStore == nullptr) {
95 return nullptr;
96 }
97 return rdbStore->Query(cmd, columns);
98 }
99
UpdateAnalysisTotal(string & uriTotal,string & selection,const string & columnName)100 static int32_t UpdateAnalysisTotal(string &uriTotal, string &selection, const string &columnName)
101 {
102 Uri uri = Uri(uriTotal);
103 DataSharePredicates predicate;
104 predicate.SetWhereClause(selection);
105 MediaLibraryCommand cmdTotal(uri);
106 DataShareValuesBucket valueBucket;
107 valueBucket.Put(STATUS, 0);
108 valueBucket.Put(columnName, 0);
109 return MediaLibraryDataManager::GetInstance()->Update(cmdTotal, valueBucket, predicate);
110 }
111
DeleteFromVisionTables(string & fileId,string & selectionTotal,const string & columnTotal,const string & tableName)112 static int32_t DeleteFromVisionTables(string &fileId, string &selectionTotal,
113 const string &columnTotal, const string &tableName)
114 {
115 string uriTotal = MEDIALIBRARY_DATA_URI + "/" + PAH_ANA_TOTAL;
116 int32_t updateRows = UpdateAnalysisTotal(uriTotal, selectionTotal, columnTotal);
117 MEDIA_DEBUG_LOG("Update %{public}d rows at total for edit commit to %{public}s", updateRows, columnTotal.c_str());
118 if (updateRows <= 0) {
119 return updateRows;
120 }
121
122 string uriTable = MEDIALIBRARY_DATA_URI + "/" + tableName;
123 Uri uri = Uri(uriTable);
124 DataSharePredicates predicate;
125 predicate.EqualTo(FILE_ID, fileId);
126 MediaLibraryCommand cmdTable(uri);
127 return MediaLibraryDataManager::GetInstance()->Delete(cmdTable, predicate);
128 }
129
DeleteFromVisionTablesForVideo(string & fileId,const string & tableName)130 static int32_t DeleteFromVisionTablesForVideo(string &fileId, const string &tableName)
131 {
132 string uriTable = MEDIALIBRARY_DATA_URI + "/" + tableName;
133 Uri uri = Uri(uriTable);
134 DataSharePredicates predicate;
135 predicate.EqualTo(FILE_ID, fileId);
136 MediaLibraryCommand cmdTable(uri);
137 return MediaLibraryDataManager::GetInstance()->Delete(cmdTable, predicate);
138 }
139
UpdateVisionTableForEdit(AsyncTaskData * taskData)140 static void UpdateVisionTableForEdit(AsyncTaskData *taskData)
141 {
142 if (taskData == nullptr) {
143 MEDIA_ERR_LOG("taskData is nullptr");
144 return;
145 }
146 UpdateVisionAsyncTaskData* data = static_cast<UpdateVisionAsyncTaskData*>(taskData);
147 if (data == nullptr) {
148 MEDIA_ERR_LOG("UpdateVisionAsyncTaskData is nullptr");
149 return;
150 }
151 string fileId = to_string(data->fileId_);
152
153 string selectionTotal = FILE_ID + " = " + fileId + " AND " + LABEL + " = 1";
154 DeleteFromVisionTables(fileId, selectionTotal, LABEL, PAH_ANA_LABEL);
155 DeleteFromVisionTablesForVideo(fileId, PAH_ANA_VIDEO_LABEL);
156
157 selectionTotal = FILE_ID + " = " + fileId + " AND " + AESTHETICS_SCORE + " = 1";
158 DeleteFromVisionTables(fileId, selectionTotal, AESTHETICS_SCORE, PAH_ANA_ATTS);
159
160 selectionTotal = FILE_ID + " = " + fileId + " AND " + OCR + " = 1";
161 DeleteFromVisionTables(fileId, selectionTotal, OCR, PAH_ANA_OCR);
162
163 selectionTotal = FILE_ID + " = " + fileId + " AND " + SALIENCY + " = 1";
164 DeleteFromVisionTables(fileId, selectionTotal, SALIENCY, PAH_ANA_SALIENCY);
165
166 selectionTotal = FILE_ID + " = " + fileId + " AND " + FACE + " IN (-2, 1, 2, 3, 4)";
167 DeleteFromVisionTables(fileId, selectionTotal, FACE, PAH_ANA_FACE);
168
169 selectionTotal = FILE_ID + " = " + fileId + " AND " + OBJECT + " = 1";
170 DeleteFromVisionTables(fileId, selectionTotal, OBJECT, PAH_ANA_OBJECT);
171
172 selectionTotal = FILE_ID + " = " + fileId + " AND " + RECOMMENDATION + " = 1";
173 DeleteFromVisionTables(fileId, selectionTotal, RECOMMENDATION, PAH_ANA_RECOMMENDATION);
174
175 selectionTotal = FILE_ID + " = " + fileId + " AND " + SEGMENTATION + " = 1";
176 DeleteFromVisionTables(fileId, selectionTotal, SEGMENTATION, PAH_ANA_SEGMENTATION);
177
178 selectionTotal = FILE_ID + " = " + fileId + " AND " + HEAD + " = 1";
179 DeleteFromVisionTables(fileId, selectionTotal, HEAD, PAH_ANA_HEAD);
180
181 selectionTotal = FILE_ID + " = " + fileId + " AND " + POSE + " = 1";
182 DeleteFromVisionTables(fileId, selectionTotal, POSE, PAH_ANA_POSE);
183
184 auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
185 if (rdbStore == nullptr) {
186 MEDIA_ERR_LOG("Can not get rdbstore");
187 return;
188 }
189 MediaLibraryRdbUtils::UpdateAnalysisAlbumByFile(rdbStore, {fileId}, NEED_UPDATE_TYPE);
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 }
226 }
227