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