• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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