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