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 "EnhancementManager"
17 
18 #include "enhancement_manager.h"
19 
20 #include "enhancement_task_manager.h"
21 #include "medialibrary_bundle_manager.h"
22 #include "medialibrary_command.h"
23 #include "medialibrary_errno.h"
24 #include "medialibrary_type_const.h"
25 #include "medialibrary_tracer.h"
26 #include "media_log.h"
27 #include "request_policy.h"
28 #include "result_set_utils.h"
29 #include "media_file_utils.h"
30 #include "media_file_uri.h"
31 #include "medialibrary_unistore_manager.h"
32 #include "medialibrary_rdb_transaction.h"
33 #include "medialibrary_notify.h"
34 #include "userfilemgr_uri.h"
35 #include "medialibrary_async_worker.h"
36 
37 using namespace std;
38 using namespace OHOS::DataShare;
39 using namespace OHOS::NativeRdb;
40 using namespace OHOS::RdbDataShareAdapter;
41 #ifdef ABILITY_CLOUD_ENHANCEMENT_SUPPORT
42 using namespace OHOS::MediaEnhance;
43 #endif
44 namespace OHOS {
45 namespace Media {
46 using json = nlohmann::json;
47 static const string FILE_TPYE = "fileType";
48 static const string IS_HDR_VIVID = "isHdrVivid";
49 static const string HAS_WATER_MARK_INFO = "hasCloudWaterMark";
50 static const string CLOUD_WATER_MARK_INFO = "cloudWaterMarkInfo";
51 static const int32_t NO = 0;
52 static const int32_t YES = 1;
53 static const string JPEG_STR = "image/jpeg";
54 static const string HEIF_STR = "image/heic";
55 static const string JPEG_TYPE = "JPEG";
56 static const string HEIF_TYPE = "HEIF";
57 static const unordered_map<string, string> CLOUD_ENHANCEMENT_MIME_TYPE_MAP = {
58     { JPEG_STR, JPEG_TYPE },
59     { HEIF_STR, HEIF_TYPE },
60 };
61 mutex EnhancementManager::mutex_;
62 
EnhancementManager()63 EnhancementManager::EnhancementManager()
64 {
65     threadManager_ = make_shared<EnhancementThreadManager>();
66 }
67 
~EnhancementManager()68 EnhancementManager::~EnhancementManager() {}
69 
GetInstance()70 EnhancementManager& EnhancementManager::GetInstance()
71 {
72     static EnhancementManager instance;
73     return instance;
74 }
75 
76 
LoadService()77 bool EnhancementManager::LoadService()
78 {
79 #ifdef ABILITY_CLOUD_ENHANCEMENT_SUPPORT
80     if (enhancementService_ == nullptr) {
81         unique_lock<mutex> lock(mutex_);
82         if (enhancementService_ == nullptr) {
83             enhancementService_ = make_shared<EnhancementServiceAdapter>();
84         }
85     }
86     if (enhancementService_ == nullptr) {
87         return false;
88     }
89     return true;
90 #else
91     return false;
92 #endif
93 }
94 
CheckResultSet(shared_ptr<NativeRdb::ResultSet> & resultSet)95 static int32_t CheckResultSet(shared_ptr<NativeRdb::ResultSet> &resultSet)
96 {
97     if (resultSet == nullptr) {
98         MEDIA_ERR_LOG("resultset is nullptr");
99         return E_FAIL;
100     }
101     int32_t count = 0;
102     auto ret = resultSet->GetRowCount(count);
103     if (ret != E_OK) {
104         MEDIA_ERR_LOG("Failed to get resultset row count, ret: %{public}d", ret);
105         return ret;
106     }
107     if (count <= 0) {
108         MEDIA_INFO_LOG("Failed to get count, count: %{public}d", count);
109         return E_FAIL;
110     }
111     return E_OK;
112 }
113 
114 #ifdef ABILITY_CLOUD_ENHANCEMENT_SUPPORT
FillBundleWithWaterMarkInfo(MediaEnhanceBundleHandle * mediaEnhanceBundle,const string & mimeType,int32_t dynamicRangeType,const bool hasCloudWaterMark)115 static void FillBundleWithWaterMarkInfo(MediaEnhanceBundleHandle* mediaEnhanceBundle,
116     const string &mimeType, int32_t dynamicRangeType, const bool hasCloudWaterMark)
117 {
118     string filePath = CLOUD_ENHANCEMENT_WATER_MARK_DIR + "/" + "cloud_watermark_param.json";
119     string metaDataStr;
120     if (!MediaFileUtils::ReadStrFromFile(filePath, metaDataStr)) {
121         MEDIA_ERR_LOG("Failed to read meta data from: %{public}s", filePath.c_str());
122         return;
123     }
124     if (!json::accept(metaDataStr)) {
125         MEDIA_WARN_LOG("Failed to verify the meataData format, metaData is: %{private}s",
126             metaDataStr.c_str());
127         return;
128     }
129     json metaData;
130     json jsonObject = json::parse(metaDataStr);
131     if (CLOUD_ENHANCEMENT_MIME_TYPE_MAP.count(mimeType) == 0) {
132         MEDIA_WARN_LOG("Failed to verify the mimeType, mimeType is: %{public}s",
133             mimeType.c_str());
134         return;
135     }
136     metaData[FILE_TPYE] = CLOUD_ENHANCEMENT_MIME_TYPE_MAP.at(mimeType);
137     metaData[IS_HDR_VIVID] = to_string(dynamicRangeType);
138     metaData[HAS_WATER_MARK_INFO] = hasCloudWaterMark ? to_string(YES) : to_string(NO);
139     for (auto& item : jsonObject[CLOUD_WATER_MARK_INFO].items()) {
140         item.value() = to_string(item.value().get<int>());
141     }
142     metaData[CLOUD_WATER_MARK_INFO] = jsonObject[CLOUD_WATER_MARK_INFO];
143     string metaDataJson = metaData.dump();
144     MEDIA_INFO_LOG("meta data json: %{public}s", metaDataJson.c_str());
145     EnhancementManager::GetInstance().enhancementService_->PutString(mediaEnhanceBundle,
146         MediaEnhance_Bundle_Key::METADATA, metaDataJson.c_str());  // meta data
147 }
148 #endif
149 
InitCloudEnhancementAsync(AsyncTaskData * data)150 static void InitCloudEnhancementAsync(AsyncTaskData *data)
151 {
152     EnhancementManager::GetInstance().Init();
153 }
154 
InitAsync()155 bool EnhancementManager::InitAsync()
156 {
157     shared_ptr<MediaLibraryAsyncWorker> asyncWorker = MediaLibraryAsyncWorker::GetInstance();
158     if (asyncWorker == nullptr) {
159         MEDIA_INFO_LOG("can not get async worker");
160         return false;
161     }
162 
163     shared_ptr<MediaLibraryAsyncTask> asyncTask = make_shared<MediaLibraryAsyncTask>(InitCloudEnhancementAsync,
164         nullptr);
165     if (asyncTask == nullptr) {
166         MEDIA_ERR_LOG("InitCloudEnhancementAsync create task fail");
167         return false;
168     }
169     MEDIA_INFO_LOG("InitCloudEnhancementAsync add task success");
170     asyncWorker->AddTask(asyncTask, false);
171     return true;
172 }
173 
Init()174 bool EnhancementManager::Init()
175 {
176 #ifdef ABILITY_CLOUD_ENHANCEMENT_SUPPORT
177     // restart
178     if (!LoadService()) {
179         MEDIA_ERR_LOG("load enhancement service error");
180         return false;
181     }
182     RdbPredicates servicePredicates(PhotoColumn::PHOTOS_TABLE);
183     vector<string> columns = {
184         MediaColumn::MEDIA_ID, MediaColumn::MEDIA_MIME_TYPE, PhotoColumn::PHOTO_ID,
185         PhotoColumn::PHOTO_DYNAMIC_RANGE_TYPE, PhotoColumn::PHOTO_HAS_CLOUD_WATERMARK,
186     };
187     servicePredicates.EqualTo(PhotoColumn::PHOTO_CE_AVAILABLE,
188         static_cast<int32_t>(CloudEnhancementAvailableType::PROCESSING));
189     auto resultSet = MediaLibraryRdbStore::QueryWithFilter(servicePredicates, columns);
190     if (CheckResultSet(resultSet) != E_OK) {
191         MEDIA_INFO_LOG("Init query no processing task");
192         return false;
193     }
194     while (resultSet->GoToNextRow() == E_OK) {
195         int32_t fileId = GetInt32Val(MediaColumn::MEDIA_ID, resultSet);
196         string photoId = GetStringVal(PhotoColumn::PHOTO_ID, resultSet);
197         string mimeType = GetStringVal(MediaColumn::MEDIA_MIME_TYPE, resultSet);
198         int32_t dynamicRangeType = GetInt32Val(PhotoColumn::PHOTO_DYNAMIC_RANGE_TYPE, resultSet);
199         int32_t hasCloudWatermark = GetInt32Val(PhotoColumn::PHOTO_HAS_CLOUD_WATERMARK, resultSet);
200         MEDIA_INFO_LOG("restart and submit: fileId: %{public}d, photoId: %{public}s", fileId, photoId.c_str());
201         MediaEnhanceBundleHandle* mediaEnhanceBundle = enhancementService_->CreateBundle();
202         if (mediaEnhanceBundle == nullptr) {
203             continue;
204         }
205         enhancementService_->PutInt(mediaEnhanceBundle, MediaEnhance_Bundle_Key::TRIGGER_TYPE,
206             MediaEnhance_Trigger_Type::TRIGGER_HIGH_LEVEL);
207         FillBundleWithWaterMarkInfo(mediaEnhanceBundle, mimeType, dynamicRangeType,
208             hasCloudWatermark == YES ? true : false);
209         if (enhancementService_->AddTask(photoId, mediaEnhanceBundle) != E_OK) {
210             MEDIA_ERR_LOG("enhancment service error, photo_id: %{public}s", photoId.c_str());
211             enhancementService_->DestroyBundle(mediaEnhanceBundle);
212             continue;
213         }
214         enhancementService_->DestroyBundle(mediaEnhanceBundle);
215         EnhancementTaskManager::AddEnhancementTask(fileId, photoId);
216     }
217 #else
218     MEDIA_ERR_LOG("not supply cloud enhancement service");
219 #endif
220     return true;
221 }
222 
CancelTasksInternal(const vector<string> & fileIds,vector<string> & photoIds,CloudEnhancementAvailableType type)223 void EnhancementManager::CancelTasksInternal(const vector<string> &fileIds, vector<string> &photoIds,
224     CloudEnhancementAvailableType type)
225 {
226 #ifdef ABILITY_CLOUD_ENHANCEMENT_SUPPORT
227     for (const string& id : fileIds) {
228         int32_t fileId = stoi(id);
229         string photoId = EnhancementTaskManager::QueryPhotoIdByFileId(fileId);
230         if (photoId.empty()) {
231             MEDIA_INFO_LOG("task in cache not processing, file_id: %{public}d", fileId);
232             continue;
233         }
234         if (!LoadService() || enhancementService_->CancelTask(photoId) != E_OK) {
235             MEDIA_ERR_LOG("enhancment service error, photo_id: %{public}s", photoId.c_str());
236             continue;
237         }
238         EnhancementTaskManager::RemoveEnhancementTask(photoId);
239         photoIds.emplace_back(photoId);
240         MEDIA_INFO_LOG("cancel task successful, photo_id: %{public}s", photoId.c_str());
241     }
242     RdbPredicates updatePredicates(PhotoColumn::PHOTOS_TABLE);
243     updatePredicates.In(MediaColumn::MEDIA_ID, fileIds);
244     updatePredicates.And();
245     updatePredicates.BeginWrap();
246     updatePredicates.EqualTo(PhotoColumn::PHOTO_CE_AVAILABLE,
247         static_cast<int32_t>(CloudEnhancementAvailableType::PROCESSING));
248     updatePredicates.Or();
249     updatePredicates.EqualTo(PhotoColumn::PHOTO_CE_AVAILABLE,
250         static_cast<int32_t>(CloudEnhancementAvailableType::SUPPORT));
251     updatePredicates.Or();
252     updatePredicates.EqualTo(PhotoColumn::PHOTO_CE_AVAILABLE,
253         static_cast<int32_t>(CloudEnhancementAvailableType::FAILED_RETRY));
254     updatePredicates.EndWrap();
255     ValuesBucket rdbValues;
256     rdbValues.PutInt(PhotoColumn::PHOTO_CE_AVAILABLE, static_cast<int32_t>(type));
257     int32_t ret = EnhancementDatabaseOperations::Update(rdbValues, updatePredicates);
258     if (ret != E_OK) {
259         MEDIA_ERR_LOG("update ce_available failed, type: %{public}d, failed count: %{public}zu",
260             static_cast<int32_t>(type), photoIds.size());
261         return;
262     }
263     MEDIA_INFO_LOG("cancel tasks successful, type: %{public}d, success count: %{public}zu",
264         static_cast<int32_t>(type), photoIds.size());
265 #else
266     MEDIA_ERR_LOG("not supply cloud enhancement service");
267 #endif
268 }
269 
RemoveTasksInternal(const vector<string> & fileIds,vector<string> & photoIds)270 void EnhancementManager::RemoveTasksInternal(const vector<string> &fileIds, vector<string> &photoIds)
271 {
272 #ifdef ABILITY_CLOUD_ENHANCEMENT_SUPPORT
273     RdbPredicates queryPredicates(PhotoColumn::PHOTOS_TABLE);
274     vector<string> columns = { PhotoColumn::PHOTO_ID };
275     queryPredicates.In(MediaColumn::MEDIA_ID, fileIds);
276     queryPredicates.EqualTo(PhotoColumn::PHOTO_CE_AVAILABLE,
277         static_cast<int32_t>(CloudEnhancementAvailableType::TRASH));
278     shared_ptr<ResultSet> resultSet = MediaLibraryRdbStore::QueryWithFilter(queryPredicates, columns);
279     CHECK_AND_RETURN_LOG(CheckResultSet(resultSet) == E_OK, "result set is invalid");
280     while (resultSet->GoToNextRow() == E_OK) {
281         string photoId = GetStringVal(PhotoColumn::PHOTO_ID, resultSet);
282         if (!LoadService() || enhancementService_->RemoveTask(photoId) != E_OK) {
283             MEDIA_ERR_LOG("enhancment service error, photo_id: %{public}s", photoId.c_str());
284             continue;
285         }
286         photoIds.emplace_back(photoId);
287         MEDIA_INFO_LOG("remove task successful, photo_id: %{public}s", photoId.c_str());
288     }
289 #else
290     MEDIA_ERR_LOG("not supply cloud enhancement service");
291 #endif
292 }
293 
RevertEditUpdateInternal(int32_t fileId)294 bool EnhancementManager::RevertEditUpdateInternal(int32_t fileId)
295 {
296 #ifdef ABILITY_CLOUD_ENHANCEMENT_SUPPORT
297     RdbPredicates updatePredicates(PhotoColumn::PHOTOS_TABLE);
298     updatePredicates.EqualTo(MediaColumn::MEDIA_ID, fileId);
299     updatePredicates.EqualTo(PhotoColumn::PHOTO_CE_AVAILABLE,
300         static_cast<int32_t>(CloudEnhancementAvailableType::EDIT));
301     ValuesBucket rdbValues;
302     rdbValues.PutInt(PhotoColumn::PHOTO_CE_AVAILABLE,
303         static_cast<int32_t>(CloudEnhancementAvailableType::SUPPORT));
304     int32_t ret = EnhancementDatabaseOperations::Update(rdbValues, updatePredicates);
305     if (ret != E_OK) {
306         MEDIA_ERR_LOG("update ce_available error, file_id: %{public}d", fileId);
307         return false;
308     }
309     MEDIA_INFO_LOG("revert edit update successful, file_id: %{public}d", fileId);
310 #else
311     MEDIA_ERR_LOG("not supply cloud enhancement service");
312 #endif
313     return true;
314 }
315 
RecoverTrashUpdateInternal(const vector<string> & fildIds)316 bool EnhancementManager::RecoverTrashUpdateInternal(const vector<string> &fildIds)
317 {
318 #ifdef ABILITY_CLOUD_ENHANCEMENT_SUPPORT
319     RdbPredicates updatePredicates(PhotoColumn::PHOTOS_TABLE);
320     updatePredicates.In(MediaColumn::MEDIA_ID, fildIds);
321     updatePredicates.EqualTo(PhotoColumn::PHOTO_CE_AVAILABLE,
322         static_cast<int32_t>(CloudEnhancementAvailableType::TRASH));
323     ValuesBucket rdbValues;
324     rdbValues.PutInt(PhotoColumn::PHOTO_CE_AVAILABLE,
325         static_cast<int32_t>(CloudEnhancementAvailableType::SUPPORT));
326     int32_t ret = EnhancementDatabaseOperations::Update(rdbValues, updatePredicates);
327     if (ret != E_OK) {
328         MEDIA_ERR_LOG("update ce_available error");
329         return false;
330     }
331     MEDIA_INFO_LOG("revocer trash update successful");
332 #else
333     MEDIA_ERR_LOG("not supply cloud enhancement service");
334 #endif
335     return true;
336 }
337 
HandleEnhancementUpdateOperation(MediaLibraryCommand & cmd)338 int32_t EnhancementManager::HandleEnhancementUpdateOperation(MediaLibraryCommand &cmd)
339 {
340     switch (cmd.GetOprnType()) {
341         case OperationType::ENHANCEMENT_ADD: {
342 #ifdef ABILITY_CLOUD_ENHANCEMENT_SUPPORT
343             string hasCloudWatermark = cmd.GetQuerySetParam(MEDIA_OPERN_KEYWORD);
344             if (hasCloudWatermark.compare(to_string(YES)) == 0) {
345                 return HandleAddOperation(cmd, true);
346             } else {
347                 return HandleAddOperation(cmd, false);
348             }
349 #else
350             return E_ERR;
351 #endif
352         }
353         case OperationType::ENHANCEMENT_PRIORITIZE: {
354             return HandlePrioritizeOperation(cmd);
355         }
356         case OperationType::ENHANCEMENT_CANCEL: {
357             return HandleCancelOperation(cmd);
358         }
359         case OperationType::ENHANCEMENT_CANCEL_ALL: {
360             return HandleCancelAllOperation();
361         }
362         case OperationType::ENHANCEMENT_SYNC: {
363             return HandleSyncOperation();
364         }
365         default:
366             MEDIA_ERR_LOG("Unknown OprnType");
367             return E_ERR;
368     }
369     return E_OK;
370 }
371 
HandleEnhancementQueryOperation(MediaLibraryCommand & cmd,const vector<string> & columns)372 shared_ptr<NativeRdb::ResultSet> EnhancementManager::HandleEnhancementQueryOperation(MediaLibraryCommand &cmd,
373     const vector<string> &columns)
374 {
375     switch (cmd.GetOprnType()) {
376         case OperationType::ENHANCEMENT_QUERY:
377             // query database
378             return HandleQueryOperation(cmd, columns);
379         case OperationType::ENHANCEMENT_GET_PAIR:
380             return HandleGetPairOperation(cmd);
381         default:
382             break;
383     }
384     return nullptr;
385 }
386 
387 #ifdef ABILITY_CLOUD_ENHANCEMENT_SUPPORT
AddServiceTask(MediaEnhanceBundleHandle * mediaEnhanceBundle,int32_t fileId,const string & photoId,const bool hasCloudWatermark)388 int32_t EnhancementManager::AddServiceTask(MediaEnhanceBundleHandle* mediaEnhanceBundle, int32_t fileId,
389     const string &photoId, const bool hasCloudWatermark)
390 {
391     EnhancementTaskManager::AddEnhancementTask(fileId, photoId);
392     RdbPredicates servicePredicates(PhotoColumn::PHOTOS_TABLE);
393     servicePredicates.EqualTo(MediaColumn::MEDIA_ID, fileId);
394     servicePredicates.And();
395     servicePredicates.BeginWrap();
396     servicePredicates.EqualTo(PhotoColumn::PHOTO_CE_AVAILABLE,
397         static_cast<int32_t>(CloudEnhancementAvailableType::SUPPORT));
398     servicePredicates.Or();
399     servicePredicates.EqualTo(PhotoColumn::PHOTO_CE_AVAILABLE,
400         static_cast<int32_t>(CloudEnhancementAvailableType::FAILED_RETRY));
401     servicePredicates.EndWrap();
402     ValuesBucket rdbValues;
403     rdbValues.PutInt(PhotoColumn::PHOTO_CE_AVAILABLE,
404         static_cast<int32_t>(CloudEnhancementAvailableType::PROCESSING));
405     if (hasCloudWatermark) {
406         rdbValues.PutInt(PhotoColumn::PHOTO_HAS_CLOUD_WATERMARK, YES);
407     } else {
408         rdbValues.PutInt(PhotoColumn::PHOTO_HAS_CLOUD_WATERMARK, NO);
409     }
410     int32_t errCode = EnhancementDatabaseOperations::Update(rdbValues, servicePredicates);
411     if (errCode != E_OK) {
412         EnhancementTaskManager::RemoveEnhancementTask(photoId);
413         return E_ERR;
414     }
415     if (enhancementService_->AddTask(photoId, mediaEnhanceBundle) != E_OK) {
416         MEDIA_ERR_LOG("enhancment service error, photoId: %{public}s", photoId.c_str());
417         enhancementService_->DestroyBundle(mediaEnhanceBundle);
418         RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
419         predicates.EqualTo(MediaColumn::MEDIA_ID, fileId);
420         predicates.EqualTo(PhotoColumn::PHOTO_CE_AVAILABLE,
421             static_cast<int32_t>(CloudEnhancementAvailableType::PROCESSING));
422         ValuesBucket values;
423         values.PutInt(PhotoColumn::PHOTO_CE_AVAILABLE,
424             static_cast<int32_t>(CloudEnhancementAvailableType::SUPPORT));
425         EnhancementDatabaseOperations::Update(values, predicates);
426         EnhancementTaskManager::RemoveEnhancementTask(photoId);
427         return E_ERR;
428     }
429     enhancementService_->DestroyBundle(mediaEnhanceBundle);
430     return E_OK;
431 }
432 
HandleAddOperation(MediaLibraryCommand & cmd,const bool hasCloudWatermark)433 int32_t EnhancementManager::HandleAddOperation(MediaLibraryCommand &cmd, const bool hasCloudWatermark)
434 {
435     unordered_map<int32_t, string> fileId2Uri;
436     vector<string> columns = { MediaColumn::MEDIA_ID, MediaColumn::MEDIA_MIME_TYPE,
437         PhotoColumn::PHOTO_DYNAMIC_RANGE_TYPE, PhotoColumn::PHOTO_ID, PhotoColumn::PHOTO_CE_AVAILABLE
438     };
439     auto resultSet = EnhancementDatabaseOperations::BatchQuery(cmd, columns, fileId2Uri);
440     CHECK_AND_RETURN_RET_LOG(CheckResultSet(resultSet) == E_OK, E_ERR, "result set invalid");
441     int32_t errCode = E_OK;
442     while (resultSet->GoToNextRow() == E_OK) {
443         int32_t fileId = GetInt32Val(MediaColumn::MEDIA_ID, resultSet);
444         string mimeType = GetStringVal(MediaColumn::MEDIA_MIME_TYPE, resultSet);
445         int32_t dynamicRangeType = GetInt32Val(PhotoColumn::PHOTO_DYNAMIC_RANGE_TYPE, resultSet);
446         string photoId = GetStringVal(PhotoColumn::PHOTO_ID, resultSet);
447         int32_t ceAvailable = GetInt32Val(PhotoColumn::PHOTO_CE_AVAILABLE, resultSet);
448         MEDIA_INFO_LOG("HandleAddOperation fileId: %{public}d, photoId: %{public}s, ceAvailable: %{public}d",
449             fileId, photoId.c_str(), ceAvailable);
450         if (ceAvailable != static_cast<int32_t>(CloudEnhancementAvailableType::SUPPORT) &&
451             ceAvailable != static_cast<int32_t>(CloudEnhancementAvailableType::FAILED_RETRY)) {
452             MEDIA_INFO_LOG("cloud enhancement task in db not support, photoId: %{public}s",
453                 photoId.c_str());
454             errCode = E_ERR;
455             continue;
456         }
457         if (EnhancementTaskManager::InProcessingTask(photoId)) {
458             MEDIA_INFO_LOG("cloud enhancement task in cache is processing, photoId: %{public}s", photoId.c_str());
459             errCode = E_ERR;
460             continue;
461         }
462         if (!LoadService()) {
463             continue;
464         }
465         MediaEnhanceBundleHandle* mediaEnhanceBundle = enhancementService_->CreateBundle();
466         enhancementService_->PutInt(mediaEnhanceBundle, MediaEnhance_Bundle_Key::TRIGGER_TYPE,
467             MediaEnhance_Trigger_Type::TRIGGER_HIGH_LEVEL);
468         FillBundleWithWaterMarkInfo(mediaEnhanceBundle, mimeType, dynamicRangeType, hasCloudWatermark);
469         errCode = AddServiceTask(mediaEnhanceBundle, fileId, photoId, hasCloudWatermark);
470         if (errCode != E_OK) {
471             continue;
472         }
473         auto watch = MediaLibraryNotify::GetInstance();
474         watch->Notify(fileId2Uri[fileId], NotifyType::NOTIFY_UPDATE);
475     }
476     return errCode;
477 }
478 #endif
479 
HandlePrioritizeOperation(MediaLibraryCommand & cmd)480 int32_t EnhancementManager::HandlePrioritizeOperation(MediaLibraryCommand &cmd)
481 {
482 #ifdef ABILITY_CLOUD_ENHANCEMENT_SUPPORT
483     RdbPredicates servicePredicates(PhotoColumn::PHOTOS_TABLE);
484     vector<string> columns = {
485         MediaColumn::MEDIA_ID,
486         PhotoColumn::PHOTO_ID,
487         PhotoColumn::PHOTO_CE_AVAILABLE
488     };
489     auto resultSet = EnhancementDatabaseOperations::Query(cmd, servicePredicates, columns);
490     CHECK_AND_RETURN_RET_LOG(CheckResultSet(resultSet) == E_OK, E_ERR, "result set invalid");
491     resultSet->GoToNextRow();
492     int32_t fileId = GetInt32Val(MediaColumn::MEDIA_ID, resultSet);
493     string photoId = GetStringVal(PhotoColumn::PHOTO_ID, resultSet);
494     int32_t ceAvailable = GetInt32Val(PhotoColumn::PHOTO_CE_AVAILABLE, resultSet);
495     resultSet->Close();
496     MEDIA_INFO_LOG("HandlePrioritizeOperation fileId: %{public}d, photoId: %{public}s, ceAvailable: %{public}d",
497         fileId, photoId.c_str(), ceAvailable);
498     if (ceAvailable != static_cast<int32_t>(CloudEnhancementAvailableType::PROCESSING)) {
499         MEDIA_INFO_LOG("cloud enhancement task in db not processing, photoId: %{public}s",
500             photoId.c_str());
501         return E_ERR;
502     }
503     if (!EnhancementTaskManager::InProcessingTask(photoId) ||
504         EnhancementTaskManager::GetTaskRequestCount(photoId) != 0) {
505         MEDIA_INFO_LOG("cloud enhancement task in cache not processing, photoId: %{public}s",
506             photoId.c_str());
507         return E_ERR;
508     }
509     if (!LoadService()) {
510         MEDIA_ERR_LOG("load enhancement service error");
511         return E_ERR;
512     }
513     MediaEnhanceBundleHandle* mediaEnhanceBundle = enhancementService_->CreateBundle();
514     if (mediaEnhanceBundle == nullptr) {
515         return E_ERR;
516     }
517     enhancementService_->PutInt(mediaEnhanceBundle, MediaEnhance_Bundle_Key::TRIGGER_TYPE,
518         MediaEnhance_Trigger_Type::TRIGGER_HIGH_LEVEL);
519     int32_t ret = enhancementService_->AddTask(photoId, mediaEnhanceBundle);
520     enhancementService_->DestroyBundle(mediaEnhanceBundle);
521     CHECK_AND_RETURN_RET_LOG(ret == E_OK, ret, "enhancment service error, photoId: %{public}s", photoId.c_str());
522     return ret;
523 #else
524     MEDIA_ERR_LOG("not supply cloud enhancement service");
525     return E_ERR;
526 #endif
527 }
528 
HandleCancelOperation(MediaLibraryCommand & cmd)529 int32_t EnhancementManager::HandleCancelOperation(MediaLibraryCommand &cmd)
530 {
531 #ifdef ABILITY_CLOUD_ENHANCEMENT_SUPPORT
532     unordered_map<int32_t, string> fileId2Uri;
533     vector<string> columns = { MediaColumn::MEDIA_ID, PhotoColumn::PHOTO_ID, PhotoColumn::PHOTO_CE_AVAILABLE };
534     auto resultSet = EnhancementDatabaseOperations::BatchQuery(cmd, columns, fileId2Uri);
535     CHECK_AND_RETURN_RET_LOG(CheckResultSet(resultSet) == E_OK, E_ERR, "result set invalid");
536     while (resultSet->GoToNextRow() == E_OK) {
537         int32_t fileId = GetInt32Val(MediaColumn::MEDIA_ID, resultSet);
538         string photoId = GetStringVal(PhotoColumn::PHOTO_ID, resultSet);
539         int32_t ceAvailable = GetInt32Val(PhotoColumn::PHOTO_CE_AVAILABLE, resultSet);
540         MEDIA_INFO_LOG("HandleCancelOperation fileId: %{public}d, photoId: %{public}s, ceAvailable: %{public}d",
541             fileId, photoId.c_str(), ceAvailable);
542         if (ceAvailable != static_cast<int32_t>(CloudEnhancementAvailableType::PROCESSING)) {
543             MEDIA_INFO_LOG("cloud enhancement task in db not processing, photoId: %{public}s",
544                 photoId.c_str());
545             continue;
546         }
547         if (!EnhancementTaskManager::InProcessingTask(photoId)) {
548             MEDIA_INFO_LOG("cloud enhancement task in cache not processing, photoId: %{public}s",
549                 photoId.c_str());
550             continue;
551         }
552         if (!LoadService() || enhancementService_->CancelTask(photoId) != E_OK) {
553             MEDIA_ERR_LOG("enhancment service error, photoId: %{public}s", photoId.c_str());
554             continue;
555         }
556         EnhancementTaskManager::RemoveEnhancementTask(photoId);
557         RdbPredicates servicePredicates(PhotoColumn::PHOTOS_TABLE);
558         servicePredicates.EqualTo(MediaColumn::MEDIA_ID, fileId);
559         servicePredicates.EqualTo(PhotoColumn::PHOTO_CE_AVAILABLE,
560             static_cast<int32_t>(CloudEnhancementAvailableType::PROCESSING));
561         ValuesBucket rdbValues;
562         rdbValues.PutInt(PhotoColumn::PHOTO_CE_AVAILABLE, static_cast<int32_t>(CloudEnhancementAvailableType::SUPPORT));
563         int32_t ret = EnhancementDatabaseOperations::Update(rdbValues, servicePredicates);
564         if (ret != E_OK) {
565             MEDIA_ERR_LOG("update ce_available error, photoId: %{public}s", photoId.c_str());
566             continue;
567         }
568         CloudEnhancementGetCount::GetInstance().RemoveStartTime(photoId);
569         auto watch = MediaLibraryNotify::GetInstance();
570         watch->Notify(fileId2Uri[fileId], NotifyType::NOTIFY_UPDATE);
571     }
572     return E_OK;
573 #else
574     return E_ERR;
575 #endif
576 }
577 
HandleCancelAllOperation()578 int32_t EnhancementManager::HandleCancelAllOperation()
579 {
580 #ifdef ABILITY_CLOUD_ENHANCEMENT_SUPPORT
581     CHECK_AND_RETURN_RET_LOG(LoadService(), E_ERR, "Load Service Error");
582     int32_t ret = enhancementService_->CancelAllTasks();
583     CHECK_AND_RETURN_RET_LOG(ret == E_OK, ret, "cancel all tasks failed: enhancment service error");
584     vector<string> taskIds;
585     EnhancementTaskManager::RemoveAllEnhancementTask(taskIds);
586     CHECK_AND_RETURN_RET_LOG(!taskIds.empty(), E_OK, "cloud enhancement tasks in cache are not processing");
587     RdbPredicates queryPredicates(PhotoColumn::PHOTOS_TABLE);
588     queryPredicates.In(PhotoColumn::PHOTO_ID, taskIds);
589     vector<string> columns = { MediaColumn::MEDIA_ID, MediaColumn::MEDIA_FILE_PATH,
590         MediaColumn::MEDIA_NAME, PhotoColumn::PHOTO_ID, PhotoColumn::PHOTO_CE_AVAILABLE
591     };
592     auto resultSet = MediaLibraryRdbStore::QueryWithFilter(queryPredicates, columns);
593     CHECK_AND_RETURN_RET_LOG(CheckResultSet(resultSet) == E_OK, E_ERR, "result set invalid");
594     while (resultSet->GoToNextRow() == E_OK) {
595         int32_t fileId = GetInt32Val(MediaColumn::MEDIA_ID, resultSet);
596         string filePath = GetStringVal(MediaColumn::MEDIA_FILE_PATH, resultSet);
597         string displayName = GetStringVal(MediaColumn::MEDIA_NAME, resultSet);
598         string photoId = GetStringVal(PhotoColumn::PHOTO_ID, resultSet);
599         int32_t ceAvailable = GetInt32Val(PhotoColumn::PHOTO_CE_AVAILABLE, resultSet);
600         if (ceAvailable != static_cast<int32_t>(CloudEnhancementAvailableType::PROCESSING)) {
601             MEDIA_INFO_LOG("cloud enhancement task in db not processing, photoId: %{public}s",
602                 photoId.c_str());
603             continue;
604         }
605         string uri = MediaFileUtils::GetUriByExtrConditions(PhotoColumn::PHOTO_URI_PREFIX, to_string(fileId),
606             MediaFileUtils::GetExtraUri(displayName, filePath));
607         RdbPredicates updatePredicates(PhotoColumn::PHOTOS_TABLE);
608         updatePredicates.EqualTo(MediaColumn::MEDIA_ID, fileId);
609         updatePredicates.EqualTo(PhotoColumn::PHOTO_CE_AVAILABLE,
610             static_cast<int32_t>(CloudEnhancementAvailableType::PROCESSING));
611         ValuesBucket rdbValues;
612         rdbValues.PutInt(PhotoColumn::PHOTO_CE_AVAILABLE, static_cast<int32_t>(CloudEnhancementAvailableType::SUPPORT));
613         int32_t ret = EnhancementDatabaseOperations::Update(rdbValues, updatePredicates);
614         if (ret != E_OK) {
615             MEDIA_ERR_LOG("update ce_available error, photoId: %{public}s", photoId.c_str());
616             continue;
617         }
618         CloudEnhancementGetCount::GetInstance().RemoveStartTime(photoId);
619         auto watch = MediaLibraryNotify::GetInstance();
620         watch->Notify(uri, NotifyType::NOTIFY_UPDATE);
621     }
622     return E_OK;
623 #else
624     MEDIA_ERR_LOG("not supply cloud enhancement service");
625     return E_ERR;
626 #endif
627 }
628 
HandleSyncOperation()629 int32_t EnhancementManager::HandleSyncOperation()
630 {
631 #ifdef ABILITY_CLOUD_ENHANCEMENT_SUPPORT
632     MEDIA_INFO_LOG("photos start, begin to sync photos cloud enhancement available");
633     vector<string> taskIdList;
634     if (!LoadService() || enhancementService_->GetPendingTasks(taskIdList) != E_OK) {
635         MEDIA_ERR_LOG("sync tasks failed: enhancment service error");
636         return E_ERR;
637     }
638     if (taskIdList.empty()) {
639         MEDIA_INFO_LOG("no pending tasks from cloud enhancement service");
640         return E_OK;
641     }
642     MEDIA_INFO_LOG("enhancement pending tasks count from cloud enhancement: %{public}zu",
643         taskIdList.size());
644     vector<string> columns = {
645         MediaColumn::MEDIA_ID
646     };
647 
648     RdbPredicates updateNotSupportPredicates(PhotoColumn::PHOTOS_TABLE);
649     updateNotSupportPredicates.EqualTo(PhotoColumn::PHOTO_CE_AVAILABLE,
650         static_cast<int32_t>(CloudEnhancementAvailableType::NOT_SUPPORT));
651     updateNotSupportPredicates.In(PhotoColumn::PHOTO_ID, taskIdList);
652     ValuesBucket updateNotSupportBucket;
653     updateNotSupportBucket.PutInt(PhotoColumn::PHOTO_CE_AVAILABLE,
654         static_cast<int32_t>(CloudEnhancementAvailableType::SUPPORT));
655     EnhancementDatabaseOperations::Update(updateNotSupportBucket, updateNotSupportPredicates);
656 
657     RdbPredicates updateSupportPredicates(PhotoColumn::PHOTOS_TABLE);
658     updateSupportPredicates.EqualTo(PhotoColumn::PHOTO_CE_AVAILABLE,
659         static_cast<int32_t>(CloudEnhancementAvailableType::SUPPORT));
660     updateSupportPredicates.NotIn(PhotoColumn::PHOTO_ID, taskIdList);
661     ValuesBucket updateSupportBucket;
662     updateSupportBucket.PutInt(PhotoColumn::PHOTO_CE_AVAILABLE,
663         static_cast<int32_t>(CloudEnhancementAvailableType::NOT_SUPPORT));
664     EnhancementDatabaseOperations::Update(updateSupportBucket, updateSupportPredicates);
665     MEDIA_INFO_LOG("sync photos cloud enhancement available done");
666     return E_OK;
667 #else
668     MEDIA_ERR_LOG("not supply cloud enhancement service");
669     return E_ERR;
670 #endif
671 }
672 
HandleQueryOperation(MediaLibraryCommand & cmd,const vector<string> & columns)673 shared_ptr<NativeRdb::ResultSet> EnhancementManager::HandleQueryOperation(MediaLibraryCommand &cmd,
674     const vector<string> &columns)
675 {
676 #ifdef ABILITY_CLOUD_ENHANCEMENT_SUPPORT
677     RdbPredicates servicePredicates(PhotoColumn::PHOTOS_TABLE);
678     auto resultSet = EnhancementDatabaseOperations::Query(cmd, servicePredicates, columns);
679     if (CheckResultSet(resultSet) != E_OK) {
680         return nullptr;
681     }
682     resultSet->GoToNextRow();
683     string photoId = GetStringVal(PhotoColumn::PHOTO_ID, resultSet);
684     if (!EnhancementTaskManager::InProcessingTask(photoId)) {
685         MEDIA_INFO_LOG("cloud enhancement task in cache not processing, photoId: %{public}s", photoId.c_str());
686     }
687 
688     return resultSet;
689 #else
690     MEDIA_ERR_LOG("not supply cloud enhancement service");
691     return nullptr;
692 #endif
693 }
694 
HandleGetPairOperation(MediaLibraryCommand & cmd)695 shared_ptr<NativeRdb::ResultSet> EnhancementManager::HandleGetPairOperation(MediaLibraryCommand &cmd)
696 {
697 #ifdef ABILITY_CLOUD_ENHANCEMENT_SUPPORT
698     MEDIA_INFO_LOG("HandleGetPairOperation success");
699     auto resultSet = EnhancementDatabaseOperations::GetPair(cmd);
700     if (CheckResultSet(resultSet) != E_OK) {
701         MEDIA_INFO_LOG("Failed to get resultSet from HandleGetPairOperation");
702         return nullptr;
703     }
704     return resultSet;
705 #else
706     MEDIA_ERR_LOG("not supply cloud enhancement service");
707     return nullptr;
708 #endif
709 }
710 } // namespace Media
711 } // namespace OHOS