• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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