1 /*
2 * Copyright (c) 2025 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 "Media_Cloud_Service"
17
18 #include "cloud_media_enhance_service.h"
19
20 #include <fcntl.h>
21 #include <string>
22 #include <vector>
23
24 #include "cloud_media_operation_code.h"
25 #include "media_file_utils.h"
26 #include "media_itypes_utils.h"
27 #include "media_log.h"
28 #include "medialibrary_errno.h"
29 #include "parameters.h"
30 #include "result_set_utils.h"
31 #include "multistages_photo_capture_manager.h"
32 #include "userfilemgr_uri.h"
33 #include "request_policy.h"
34
35 namespace OHOS::Media::CloudSync {
36 const int32_t SUBMIT_TIMEOUT_SECONDS = 5;
37 #ifdef ABILITY_CAMERA_SUPPORT
38 const int32_t SUBMIT_MAX = 10;
39 #endif
40 // LCOV_EXCL_START
GetCloudSyncUnPreparedData(int32_t & result)41 int32_t CloudMediaEnhanceService::GetCloudSyncUnPreparedData(int32_t &result)
42 {
43 MEDIA_INFO_LOG("GetCloudSyncUnPreparedData begin");
44 int32_t ret = this->enhanceDao_.GetCloudSyncUnPreparedDataCount(result);
45 CHECK_AND_RETURN_RET_LOG(ret == E_OK, ret, "Failed to GetCloudSyncUnPreparedData.");
46 return ret;
47 }
48
SubmitCloudSyncPreparedDataTask()49 int32_t CloudMediaEnhanceService::SubmitCloudSyncPreparedDataTask()
50 {
51 MEDIA_INFO_LOG("SubmitCloudSyncPreparedDataTask begin");
52
53 if (submitRunning_.load()) {
54 MEDIA_WARN_LOG("SubmitCloudSyncPreparedDataTask reject new task, a task is already running ");
55 return E_ERR;
56 }
57
58 #ifdef ABILITY_CAMERA_SUPPORT
59 if (nullptr == executor_) {
60 executor_ = std::make_unique<OHOS::ThreadPool>("SubmitPreparedDataTaskExecutor");
61 CHECK_AND_RETURN_RET_LOG(executor_ != nullptr, E_ERR, "Failed to Make Executor.");
62 executor_->SetMaxTaskNum(1);
63 executor_->Start(1);
64
65 MultiStagesPhotoCaptureManager::GetInstance().SetProcessImageDoneCallback(
66 [this](bool success, const std::string &photoId) {
67 if (photoId.empty() || photoId != submitPhotoId_) {
68 return;
69 }
70 callbackDone_.store(true);
71 cv_.notify_one();
72 MEDIA_INFO_LOG("ProcessImageDoneCallback photoId = %{public}s", photoId.c_str());
73 submitCount_++;
74 if (!success || submitCount_ >= SUBMIT_MAX) {
75 StopSubmit();
76 return;
77 }
78 SubmitNextCloudSyncPreparedDataTask();
79 }
80 );
81 }
82
83 submitRunning_.store(true);
84 SubmitNextCloudSyncPreparedDataTask();
85 #endif
86
87 return E_OK;
88 }
89
SubmitNextCloudSyncPreparedDataTask()90 void CloudMediaEnhanceService::SubmitNextCloudSyncPreparedDataTask()
91 {
92 executor_->AddTask([this]() {
93 auto [fileId, photoId] = this->enhanceDao_.GetNextUnPreparedData();
94 MEDIA_INFO_LOG("GetNextUnPreparedData FileId = %{public}s, PhotoId = %{public}s",
95 fileId.c_str(), photoId.c_str());
96 if (fileId.empty() || submitPhotoId_ == photoId) {
97 StopSubmit();
98 return;
99 }
100 submitPhotoId_ = photoId;
101
102 const std::string hightQualityMode = std::to_string(static_cast<int32_t>(RequestPolicy::HIGH_QUALITY_MODE));
103 vector<std::string> columns { fileId, hightQualityMode };
104 std::string uriStr = PAH_PROCESS_IMAGE;
105 MediaFileUtils::UriAppendKeyValue(uriStr, "api_version", std::to_string(MEDIA_API_VERSION_V10));
106 Uri uri(uriStr);
107 MediaLibraryCommand cmd(uri);
108 MultiStagesPhotoCaptureManager::GetInstance().HandleMultiStagesOperation(cmd, columns);
109 callbackDone_.store(false);
110
111 SubmitTaskTimeoutCheck();
112 });
113 }
114
SubmitTaskTimeoutCheck()115 void CloudMediaEnhanceService::SubmitTaskTimeoutCheck()
116 {
117 std::unique_lock<std::mutex> lock(mtx_);
118 auto timeout = std::chrono::system_clock::now() + std::chrono::seconds(SUBMIT_TIMEOUT_SECONDS);
119 while (!callbackDone_.load()) {
120 if (cv_.wait_until(lock, timeout) == std::cv_status::timeout) {
121 MEDIA_WARN_LOG("Submit task timeout !");
122 StopSubmit();
123 break;
124 }
125 }
126 MEDIA_INFO_LOG("Submit timeout check end");
127 }
128
StopSubmit()129 void CloudMediaEnhanceService::StopSubmit()
130 {
131 MEDIA_INFO_LOG("SubmitCloudSyncPreparedDataTask StopSubmit, submitCount = %{public}d", submitCount_);
132 submitCount_ = 0;
133 submitPhotoId_.clear();
134 submitRunning_.store(false);
135 }
136 // LCOV_EXCL_STOP
137 } // namespace OHOS::Media::CloudSync