• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-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 #include "photo_post_processor.h"
17 
18 #include "auxiliary_picture.h"
19 #include "dp_log.h"
20 #include "dp_utils.h"
21 #include "dps_event_report.h"
22 #include "events_monitor.h"
23 #include "iproxy_broker.h"
24 #include "iservmgr_hdi.h"
25 #include "picture_proxy.h"
26 #include "securec.h"
27 #include "v1_3/iimage_process_service.h"
28 #include "v1_3/iimage_process_callback.h"
29 #include "v1_3/types.h"
30 
31 namespace OHOS {
32 namespace CameraStandard {
33 namespace DeferredProcessing {
34 namespace {
35     const std::string PHOTO_SERVICE_NAME = "camera_image_process_service";
36 }
37 
38 class PhotoPostProcessor::PhotoServiceListener : public HDI::ServiceManager::V1_0::ServStatListenerStub {
39 public:
40     using StatusCallback = std::function<void(const HDI::ServiceManager::V1_0::ServiceStatus&)>;
PhotoServiceListener(const std::weak_ptr<PhotoPostProcessor> & processor)41     explicit PhotoServiceListener(const std::weak_ptr<PhotoPostProcessor>& processor) : processor_(processor)
42     {
43         DP_DEBUG_LOG("entered.");
44     }
45 
OnReceive(const HDI::ServiceManager::V1_0::ServiceStatus & status)46     void OnReceive(const HDI::ServiceManager::V1_0::ServiceStatus& status)
47     {
48         if (auto process = processor_.lock()) {
49             process->OnServiceChange(status);
50         }
51     }
52 
53 private:
54     std::weak_ptr<PhotoPostProcessor> processor_;
55 };
56 
57 class PhotoPostProcessor::SessionDeathRecipient : public IRemoteObject::DeathRecipient {
58 public:
SessionDeathRecipient(const std::weak_ptr<PhotoProcessResult> & processResult)59     explicit SessionDeathRecipient(const std::weak_ptr<PhotoProcessResult>& processResult)
60         : processResult_(processResult)
61     {
62         DP_DEBUG_LOG("entered.");
63     }
64 
OnRemoteDied(const wptr<IRemoteObject> & remote)65     void OnRemoteDied(const wptr<IRemoteObject> &remote) override
66     {
67         if (auto processResult = processResult_.lock()) {
68             processResult->OnPhotoSessionDied();
69         }
70     }
71 
72 private:
73     std::weak_ptr<PhotoProcessResult> processResult_;
74 };
75 
76 class PhotoPostProcessor::PhotoProcessListener : public OHOS::HDI::Camera::V1_3::IImageProcessCallback {
77 public:
PhotoProcessListener(const std::weak_ptr<PhotoProcessResult> & processResult)78     explicit PhotoProcessListener(const std::weak_ptr<PhotoProcessResult>& processResult)
79         : processResult_(processResult)
80     {
81         DP_DEBUG_LOG("entered.");
82     }
83 
OnProcessDone(const std::string & imageId,const OHOS::HDI::Camera::V1_2::ImageBufferInfo & buffer)84     int32_t OnProcessDone(const std::string& imageId, const OHOS::HDI::Camera::V1_2::ImageBufferInfo& buffer) override
85     {
86         DP_INFO_LOG("DPS_PHOTO: imageId: %{public}s", imageId.c_str());
87         auto processResult = processResult_.lock();
88         DP_CHECK_ERROR_RETURN_RET_LOG(processResult == nullptr, DP_OK, "PhotoProcessResult is nullptr.");
89         auto ret = processResult->ProcessBufferInfo(imageId, buffer);
90         if (ret != DP_OK) {
91             DP_ERR_LOG("Process done failed imageId: %{public}s.", imageId.c_str());
92             processResult->OnError(imageId, DPS_ERROR_IMAGE_PROC_FAILED);
93         }
94         return DP_OK;
95     }
96 
OnProcessDoneExt(const std::string & imageId,const OHOS::HDI::Camera::V1_3::ImageBufferInfoExt & buffer)97     int32_t OnProcessDoneExt(const std::string& imageId,
98         const OHOS::HDI::Camera::V1_3::ImageBufferInfoExt& buffer) override
99     {
100         DP_INFO_LOG("DPS_PHOTO: imageId: %{public}s", imageId.c_str());
101         auto processResult = processResult_.lock();
102         DP_CHECK_ERROR_RETURN_RET_LOG(processResult == nullptr, DP_OK, "PhotoProcessResult is nullptr.");
103 
104         auto ret = processResult->ProcessPictureInfoV1_3(imageId, buffer);
105         if (ret != DP_OK) {
106             DP_ERR_LOG("Process yuv done failed imageId: %{public}s.", imageId.c_str());
107             processResult->OnError(imageId, DPS_ERROR_IMAGE_PROC_FAILED);
108         }
109         return DP_OK;
110     }
111 
OnError(const std::string & imageId,OHOS::HDI::Camera::V1_2::ErrorCode errorCode)112     int32_t OnError(const std::string& imageId,  OHOS::HDI::Camera::V1_2::ErrorCode errorCode) override
113     {
114         DP_ERR_LOG("DPS_PHOTO: imageId: %{public}s, ive error: %{public}d", imageId.c_str(), errorCode);
115         auto processResult = processResult_.lock();
116         DP_CHECK_ERROR_RETURN_RET_LOG(processResult == nullptr, DP_OK, "PhotoProcessResult is nullptr.");
117 
118         processResult->OnError(imageId, MapHdiError(errorCode));
119         return DP_OK;
120     }
121 
OnStatusChanged(OHOS::HDI::Camera::V1_2::SessionStatus status)122     int32_t OnStatusChanged(OHOS::HDI::Camera::V1_2::SessionStatus status) override
123     {
124         DP_INFO_LOG("DPS_PHOTO: IVEState: %{public}d", status);
125         auto processResult = processResult_.lock();
126         DP_CHECK_ERROR_RETURN_RET_LOG(processResult == nullptr, DP_OK, "PhotoProcessResult is nullptr.");
127 
128         processResult->OnStateChanged(MapHdiStatus(status));
129         return DP_OK;
130     }
131 
132 private:
133     std::weak_ptr<PhotoProcessResult> processResult_;
134 };
135 
PhotoPostProcessor(const int32_t userId)136 PhotoPostProcessor::PhotoPostProcessor(const int32_t userId)
137     : userId_(userId), serviceListener_(nullptr), processListener_(nullptr), sessionDeathRecipient_(nullptr)
138 {
139     DP_DEBUG_LOG("entered");
140 }
141 
~PhotoPostProcessor()142 PhotoPostProcessor::~PhotoPostProcessor()
143 {
144     DP_INFO_LOG("entered");
145     DisconnectService();
146     SetPhotoSession(nullptr);
147     removeNeededList_.clear();
148     runningId_.clear();
149 }
150 
Initialize()151 int32_t PhotoPostProcessor::Initialize()
152 {
153     DP_DEBUG_LOG("entered");
154     processResult_ = std::make_shared<PhotoProcessResult>(userId_);
155     sessionDeathRecipient_ = sptr<SessionDeathRecipient>::MakeSptr(processResult_);
156     processListener_ = sptr<PhotoProcessListener>::MakeSptr(processResult_);
157     ConnectService();
158     return DP_OK;
159 }
160 
GetConcurrency(ExecutionMode mode)161 int32_t PhotoPostProcessor::GetConcurrency(ExecutionMode mode)
162 {
163     int32_t count = 1;
164     auto session = GetPhotoSession();
165     DP_CHECK_ERROR_RETURN_RET_LOG(session == nullptr, count, "photo session is nullptr, count: %{public}d", count);
166 
167     int32_t ret = session->GetCoucurrency(OHOS::HDI::Camera::V1_2::ExecutionMode::BALANCED, count);
168     DP_INFO_LOG("DPS_PHOTO: GetCoucurrency to ive, ret: %{public}d", ret);
169     return count;
170 }
171 
GetPendingImages(std::vector<std::string> & pendingImages)172 bool PhotoPostProcessor::GetPendingImages(std::vector<std::string>& pendingImages)
173 {
174     auto session = GetPhotoSession();
175     DP_CHECK_ERROR_RETURN_RET_LOG(session == nullptr, false, "photo session is nullptr.");
176 
177     int32_t ret = session->GetPendingImages(pendingImages);
178     DP_INFO_LOG("DPS_PHOTO: GetPendingImages to ive, ret: %{public}d", ret);
179     return ret == DP_OK;
180 }
181 
SetExecutionMode(ExecutionMode executionMode)182 void PhotoPostProcessor::SetExecutionMode(ExecutionMode executionMode)
183 {
184     auto session = GetPhotoSession();
185     DP_CHECK_ERROR_RETURN_LOG(session == nullptr, "photo session is nullptr.");
186 
187     int32_t ret = session->SetExecutionMode(MapToHdiExecutionMode(executionMode));
188     DP_INFO_LOG("DPS_PHOTO: SetExecutionMode to ive, ret: %{public}d", ret);
189 }
190 
SetDefaultExecutionMode()191 void PhotoPostProcessor::SetDefaultExecutionMode()
192 {
193     // 采用直接新增方法,不适配1_2 和 1_3 模式的差异点
194     auto session = GetPhotoSession();
195     DP_CHECK_ERROR_RETURN_LOG(session == nullptr, "photo session is nullptr.");
196 
197     int32_t ret = session->SetExecutionMode(
198         static_cast<OHOS::HDI::Camera::V1_2::ExecutionMode>(OHOS::HDI::Camera::V1_3::ExecutionMode::DEFAULT));
199     DP_INFO_LOG("DPS_PHOTO: SetDefaultExecutionMode to ive, ret: %{public}d", ret);
200 }
201 
ProcessImage(const std::string & imageId)202 void PhotoPostProcessor::ProcessImage(const std::string& imageId)
203 {
204     auto session = GetPhotoSession();
205     if (session == nullptr) {
206         DP_ERR_LOG("Failed to process imageId: %{public}s, photo session is nullptr", imageId.c_str());
207         DP_CHECK_EXECUTE(processResult_, processResult_->OnError(imageId, DPS_ERROR_SESSION_NOT_READY_TEMPORARILY));
208         return;
209     }
210 
211     int32_t ret = session->ProcessImage(imageId);
212     DP_INFO_LOG("DPS_PHOTO: Process photo to ive, imageId: %{public}s, ret: %{public}d", imageId.c_str(), ret);
213     runningId_.emplace(imageId);
214 }
215 
RemoveImage(const std::string & imageId)216 void PhotoPostProcessor::RemoveImage(const std::string& imageId)
217 {
218     runningId_.erase(imageId);
219     auto session = GetPhotoSession();
220     if (session == nullptr) {
221         DP_ERR_LOG("photo session is nullptr.");
222         std::lock_guard<std::mutex> lock(removeMutex_);
223         removeNeededList_.emplace_back(imageId);
224         return;
225     }
226 
227     int32_t ret = session->RemoveImage(imageId);
228     DP_INFO_LOG("DPS_PHOTO: Remove photo to ive, imageId: %{public}s, ret: %{public}d", imageId.c_str(), ret);
229     DPSEventReport::GetInstance().UpdateRemoveTime(imageId, userId_);
230 }
231 
Interrupt()232 void PhotoPostProcessor::Interrupt()
233 {
234     auto session = GetPhotoSession();
235     DP_CHECK_ERROR_RETURN_LOG(session == nullptr, "photo session is nullptr.");
236 
237     int32_t ret = session->Interrupt();
238     DP_INFO_LOG("DPS_PHOTO: Interrupt photo to ive, ret: %{public}d", ret);
239 }
240 
Reset()241 void PhotoPostProcessor::Reset()
242 {
243     auto session = GetPhotoSession();
244     DP_CHECK_ERROR_RETURN_LOG(session == nullptr, "photo session is nullptr.");
245 
246     int32_t ret = session->Reset();
247     DP_INFO_LOG("DPS_PHOTO: Reset to ive, ret: %{public}d", ret);
248 }
249 
NotifyHalStateChanged(HdiStatus hdiStatus)250 void PhotoPostProcessor::NotifyHalStateChanged(HdiStatus hdiStatus)
251 {
252     EventsMonitor::GetInstance().NotifyImageEnhanceStatus(hdiStatus);
253 }
254 
OnSessionDied()255 void PhotoPostProcessor::OnSessionDied()
256 {
257     SetPhotoSession(nullptr);
258     for (auto id : runningId_) {
259         DP_CHECK_EXECUTE(processResult_, processResult_->OnError(id, DPS_ERROR_SESSION_NOT_READY_TEMPORARILY));
260     }
261     NotifyHalStateChanged(HdiStatus::HDI_DISCONNECTED);
262 }
263 
ConnectService()264 void PhotoPostProcessor::ConnectService()
265 {
266     auto svcMgr = HDI::ServiceManager::V1_0::IServiceManager::Get();
267     DP_CHECK_ERROR_RETURN_LOG(svcMgr == nullptr, "IServiceManager init failed.");
268     serviceListener_ = sptr<PhotoServiceListener>::MakeSptr(weak_from_this());
269     auto ret  = svcMgr->RegisterServiceStatusListener(serviceListener_, DEVICE_CLASS_DEFAULT);
270     DP_CHECK_ERROR_RETURN_LOG(ret != 0, "Register Photo ServiceStatusListener failed.");
271 }
272 
DisconnectService()273 void PhotoPostProcessor::DisconnectService()
274 {
275     auto session = GetPhotoSession();
276     DP_CHECK_ERROR_RETURN_LOG(session == nullptr, "PhotoSession is nullptr.");
277 
278     const sptr<IRemoteObject> &remote = OHOS::HDI::hdi_objcast<IImageProcessSession>(session);
279     bool result = remote->RemoveDeathRecipient(sessionDeathRecipient_);
280     DP_CHECK_ERROR_RETURN_LOG(!result, "Remove DeathRecipient for PhotoProcessSession failed.");
281     auto svcMgr = HDI::ServiceManager::V1_0::IServiceManager::Get();
282     DP_CHECK_ERROR_RETURN_LOG(svcMgr == nullptr, "IServiceManager init failed.");
283 
284     auto ret  = svcMgr->UnregisterServiceStatusListener(serviceListener_);
285     DP_CHECK_ERROR_RETURN_LOG(ret != 0, "Unregister Photo ServiceStatusListener failed.");
286 }
287 
OnServiceChange(const HDI::ServiceManager::V1_0::ServiceStatus & status)288 void PhotoPostProcessor::OnServiceChange(const HDI::ServiceManager::V1_0::ServiceStatus& status)
289 {
290     DP_CHECK_RETURN(status.serviceName != PHOTO_SERVICE_NAME);
291     DP_CHECK_RETURN_LOG(status.status != HDI::ServiceManager::V1_0::SERVIE_STATUS_START,
292         "photo service state: %{public}d", status.status);
293     DP_CHECK_RETURN(GetPhotoSession() != nullptr);
294 
295     sptr<OHOS::HDI::Camera::V1_2::IImageProcessService> proxyV1_2 =
296         OHOS::HDI::Camera::V1_2::IImageProcessService::Get(status.serviceName);
297     DP_CHECK_ERROR_RETURN_LOG(proxyV1_2 == nullptr, "get ImageProcessService failed.");
298 
299     uint32_t majorVer = 0;
300     uint32_t minorVer = 0;
301     proxyV1_2->GetVersion(majorVer, minorVer);
302     int32_t versionId = GetVersionId(majorVer, minorVer);
303     sptr<IImageProcessSession> session;
304     sptr<OHOS::HDI::Camera::V1_3::IImageProcessService> proxyV1_3;
305     // LCOV_EXCL_START
306     if (versionId >= HDI_VERSION_ID_1_3) {
307         proxyV1_3 = OHOS::HDI::Camera::V1_3::IImageProcessService::CastFrom(proxyV1_2);
308     }
309     if (proxyV1_3 != nullptr) {
310         DP_INFO_LOG("CreateImageProcessSessionExt version=%{public}d_%{public}d", majorVer, minorVer);
311         proxyV1_3->CreateImageProcessSessionExt(userId_, processListener_, session);
312     } else {
313         DP_INFO_LOG("CreateImageProcessSession version=%{public}d_%{public}d", majorVer, minorVer);
314         proxyV1_2->CreateImageProcessSession(userId_, processListener_, session);
315     }
316     // LCOV_EXCL_STOP
317     DP_CHECK_ERROR_RETURN_LOG(session == nullptr, "get ImageProcessSession failed.");
318 
319     const sptr<IRemoteObject>& remote = OHOS::HDI::hdi_objcast<IImageProcessSession>(session);
320     bool result = remote->AddDeathRecipient(sessionDeathRecipient_);
321     DP_CHECK_ERROR_RETURN_LOG(!result, "add DeathRecipient for ImageProcessSession failed.");
322 
323     RemoveNeedJbo(session);
324     SetPhotoSession(session);
325     NotifyHalStateChanged(HdiStatus::HDI_READY);
326 }
327 
RemoveNeedJbo(const sptr<IImageProcessSession> & session)328 void PhotoPostProcessor::RemoveNeedJbo(const sptr<IImageProcessSession>& session)
329 {
330     std::lock_guard<std::mutex> lock(removeMutex_);
331     for (const auto& imageId : removeNeededList_) {
332         int32_t ret = session->RemoveImage(imageId);
333         DP_INFO_LOG("DPS_PHOTO: RemoveImage imageId: %{public}s, ret: %{public}d", imageId.c_str(), ret);
334     }
335     removeNeededList_.clear();
336 }
337 } // namespace DeferredProcessing
338 } // namespace CameraStandard
339 } // namespace OHOS