1 /*
2 * Copyright (c) 2023-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
16 #include "deferred_photo_processor.h"
17
18 #include "dp_log.h"
19 #include "dp_utils.h"
20 #include "dps_event_report.h"
21
22 namespace OHOS {
23 namespace CameraStandard {
24 namespace DeferredProcessing {
DeferredPhotoProcessor(const int32_t userId,const std::shared_ptr<PhotoJobRepository> & repository,const std::shared_ptr<PhotoPostProcessor> & postProcessor,const std::weak_ptr<IImageProcessCallbacks> & callback)25 DeferredPhotoProcessor::DeferredPhotoProcessor(const int32_t userId,
26 const std::shared_ptr<PhotoJobRepository>& repository, const std::shared_ptr<PhotoPostProcessor>& postProcessor,
27 const std::weak_ptr<IImageProcessCallbacks>& callback)
28 : userId_(userId), repository_(repository), postProcessor_(postProcessor), callback_(callback)
29 {
30 DP_DEBUG_LOG("entered.");
31 }
32
~DeferredPhotoProcessor()33 DeferredPhotoProcessor::~DeferredPhotoProcessor()
34 {
35 DP_DEBUG_LOG("entered.");
36 }
37
Initialize()38 void DeferredPhotoProcessor::Initialize()
39 {
40 DP_DEBUG_LOG("entered.");
41 postProcessor_->Initialize();
42 postProcessor_->SetCallback(weak_from_this());
43 }
44
AddImage(const std::string & imageId,bool discardable,DpsMetadata & metadata)45 void DeferredPhotoProcessor::AddImage(const std::string& imageId, bool discardable, DpsMetadata& metadata)
46 {
47 DP_DEBUG_LOG("entered.");
48 repository_->AddDeferredJob(imageId, discardable, metadata);
49 }
50
RemoveImage(const std::string & imageId,bool restorable)51 void DeferredPhotoProcessor::RemoveImage(const std::string& imageId, bool restorable)
52 {
53 DP_DEBUG_LOG("entered.");
54 auto item = requestedImages_.find(imageId);
55 if (item != requestedImages_.end()) {
56 requestedImages_.erase(item);
57 }
58 DP_CHECK_ERROR_RETURN_LOG(repository_ == nullptr, "repository_ is nullptr");
59
60 if (restorable == false) {
61 if (repository_->GetJobStatus(imageId) == PhotoJobStatus::RUNNING) {
62 DP_CHECK_ERROR_RETURN_LOG(postProcessor_ == nullptr, "postProcessor_ is nullptr, RemoveImage failed.");
63 postProcessor_->Interrupt();
64 }
65 DP_CHECK_ERROR_RETURN_LOG(postProcessor_ == nullptr, "postProcessor_ is nullptr, RemoveImage failed.");
66 postProcessor_->RemoveImage(imageId);
67 }
68 repository_->RemoveDeferredJob(imageId, restorable);
69 }
70
RestoreImage(const std::string & imageId)71 void DeferredPhotoProcessor::RestoreImage(const std::string& imageId)
72 {
73 DP_DEBUG_LOG("entered.");
74 repository_->RestoreJob(imageId);
75 }
76
ProcessImage(const std::string & appName,const std::string & imageId)77 void DeferredPhotoProcessor::ProcessImage(const std::string& appName, const std::string& imageId)
78 {
79 DP_DEBUG_LOG("entered.");
80 if (!repository_->IsOfflineJob(imageId)) {
81 DP_INFO_LOG("DPS_PHOTO: imageId is not offlineJob %{public}s", imageId.c_str());
82 return;
83 }
84 requestedImages_.insert(imageId);
85 bool isImageIdValid = repository_->RequestJob(imageId);
86 if (!isImageIdValid) {
87 if (auto callback = callback_.lock()) {
88 callback->OnError(userId_, imageId, DpsError::DPS_ERROR_IMAGE_PROC_INVALID_PHOTO_ID);
89 }
90 } else {
91 if (repository_->GetJobPriority(postedImageId_) != PhotoJobPriority::HIGH) {
92 Interrupt();
93 }
94 }
95 }
96
CancelProcessImage(const std::string & imageId)97 void DeferredPhotoProcessor::CancelProcessImage(const std::string& imageId)
98 {
99 DP_DEBUG_LOG("entered.");
100 requestedImages_.erase(imageId);
101 repository_->CancelJob(imageId);
102 }
103
OnProcessDone(const int32_t userId,const std::string & imageId,const std::shared_ptr<BufferInfo> & bufferInfo)104 void DeferredPhotoProcessor::OnProcessDone(const int32_t userId, const std::string& imageId,
105 const std::shared_ptr<BufferInfo>& bufferInfo)
106 {
107 DP_INFO_LOG("DPS_PHOTO: userId: %{public}d, imageId: %{public}s.", userId, imageId.c_str());
108 //如果已经非高优先级,且任务结果不是全质量的图,那么不用返回给上层了,等下次出全质量图再返回
109 if (!(bufferInfo->IsHighQuality())) {
110 DP_INFO_LOG("not high quality photo");
111 if ((repository_->GetJobPriority(imageId) != PhotoJobPriority::HIGH)) {
112 DP_INFO_LOG("not high quality and not high priority, need retry");
113 repository_->SetJobPending(imageId);
114 return;
115 } else {
116 DP_INFO_LOG("not high quality, but high priority, and process as normal job before, need retry");
117 if (repository_->GetJobRunningPriority(imageId) != PhotoJobPriority::HIGH) {
118 repository_->SetJobPending(imageId);
119 return;
120 }
121 }
122 }
123 if (auto callback = callback_.lock()) {
124 callback->OnProcessDone(userId, imageId, bufferInfo);
125 repository_->SetJobCompleted(imageId);
126 }
127 }
128
OnProcessDoneExt(const int32_t userId,const std::string & imageId,const std::shared_ptr<BufferInfoExt> & bufferInfo)129 void DeferredPhotoProcessor::OnProcessDoneExt(const int32_t userId, const std::string& imageId,
130 const std::shared_ptr<BufferInfoExt>& bufferInfo)
131 {
132 DP_INFO_LOG("DPS_PHOTO: userId: %{public}d, imageId: %{public}s.", userId, imageId.c_str());
133 //如果已经非高优先级,且任务结果不是全质量的图,那么不用返回给上层了,等下次出全质量图再返回
134 if (!(bufferInfo->IsHighQuality())) {
135 DP_INFO_LOG("not high quality photo");
136 if ((repository_->GetJobPriority(imageId) != PhotoJobPriority::HIGH)) {
137 DP_INFO_LOG("not high quality and not high priority, need retry");
138 repository_->SetJobPending(imageId);
139 return;
140 } else {
141 DP_INFO_LOG("not high quality, but high priority, and process as normal job before, need retry");
142 if (repository_->GetJobRunningPriority(imageId) != PhotoJobPriority::HIGH) {
143 repository_->SetJobPending(imageId);
144 return;
145 }
146 }
147 }
148 if (auto callback = callback_.lock()) {
149 callback->OnProcessDoneExt(userId, imageId, bufferInfo);
150 repository_->SetJobCompleted(imageId);
151 }
152 }
153
OnError(const int32_t userId,const std::string & imageId,DpsError errorCode)154 void DeferredPhotoProcessor::OnError(const int32_t userId, const std::string& imageId, DpsError errorCode)
155 {
156 DP_INFO_LOG("DPS_PHOTO: userId: %{public}d, imageId: %{public}s, error: %{public}d.",
157 userId, imageId.c_str(), errorCode);
158 if (errorCode == DpsError::DPS_ERROR_IMAGE_PROC_INTERRUPTED &&
159 repository_->GetJobPriority(imageId) == PhotoJobPriority::HIGH &&
160 requestedImages_.count(imageId) != 0) {
161 repository_->SetJobPending(imageId);
162 return;
163 }
164
165 if (!IsFatalError(errorCode)) {
166 if (repository_->GetJobPriority(imageId) == PhotoJobPriority::HIGH) {
167 if (repository_->GetJobRunningPriority(imageId) != PhotoJobPriority::HIGH) {
168 repository_->SetJobPending(imageId);
169 return;
170 }
171 } else {
172 repository_->SetJobFailed(imageId);
173 return;
174 }
175 }
176 if (auto callback = callback_.lock()) {
177 callback->OnError(userId, imageId, errorCode);
178 repository_->SetJobFailed(imageId);
179 }
180 }
181
OnStateChanged(const int32_t userId,DpsStatus statusCode)182 void DeferredPhotoProcessor::OnStateChanged(const int32_t userId, DpsStatus statusCode)
183 {
184 DP_DEBUG_LOG("DPS_PHOTO: userId: %{public}d, statusCode: %{public}d.", userId, statusCode);
185 }
186
NotifyScheduleState(DpsStatus status)187 void DeferredPhotoProcessor::NotifyScheduleState(DpsStatus status)
188 {
189 if (auto callback = callback_.lock()) {
190 callback->OnStateChanged(userId_, status);
191 }
192 }
193
PostProcess(const DeferredPhotoWorkPtr & work)194 void DeferredPhotoProcessor::PostProcess(const DeferredPhotoWorkPtr& work)
195 {
196 auto executionMode = work->GetExecutionMode();
197 postedImageId_ = work->GetDeferredPhotoJob()->GetImageId();
198 DP_INFO_LOG("DPS_PHOTO: imageId: %{public}s, executionMode: %{public}d", postedImageId_.c_str(), executionMode);
199 auto item = requestedImages_.find(postedImageId_);
200 if (item != requestedImages_.end()) {
201 requestedImages_.erase(item);
202 }
203 repository_->SetJobRunning(postedImageId_);
204 postProcessor_->SetExecutionMode(executionMode);
205 postProcessor_->ProcessImage(postedImageId_);
206 DPSEventReport::GetInstance().UpdateExecutionMode(postedImageId_, userId_, executionMode);
207 DPSEventReport::GetInstance().ReportImageModeChange(executionMode);
208 }
209
SetDefaultExecutionMode()210 void DeferredPhotoProcessor::SetDefaultExecutionMode()
211 {
212 DP_DEBUG_LOG("entered.");
213 postProcessor_->SetDefaultExecutionMode();
214 }
215
Interrupt()216 void DeferredPhotoProcessor::Interrupt()
217 {
218 DP_DEBUG_LOG("entered.");
219 postProcessor_->Interrupt();
220 }
221
GetConcurrency(ExecutionMode mode)222 int32_t DeferredPhotoProcessor::GetConcurrency(ExecutionMode mode)
223 {
224 DP_DEBUG_LOG("entered.");
225 return postProcessor_->GetConcurrency(mode);
226 }
227
GetPendingImages(std::vector<std::string> & pendingImages)228 bool DeferredPhotoProcessor::GetPendingImages(std::vector<std::string>& pendingImages)
229 {
230 DP_DEBUG_LOG("entered.");
231 bool isSuccess = postProcessor_->GetPendingImages(pendingImages);
232 if (isSuccess) {
233 return true;
234 }
235 return false;
236 }
237
IsFatalError(DpsError errorCode)238 bool DeferredPhotoProcessor::IsFatalError(DpsError errorCode)
239 {
240 DP_DEBUG_LOG("entered, code: %{public}d", errorCode);
241 if (errorCode == DpsError::DPS_ERROR_IMAGE_PROC_FAILED ||
242 errorCode == DpsError::DPS_ERROR_IMAGE_PROC_INVALID_PHOTO_ID ||
243 errorCode == DpsError::DPS_ERROR_IMAGE_PROC_HIGH_TEMPERATURE) {
244 return true;
245 } else {
246 return false;
247 }
248 }
249 } // namespace DeferredProcessing
250 } // namespace CameraStandard
251 } // namespace OHOS