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 <sys/mman.h>
17 #include "deferred_proc_session/deferred_photo_proc_session.h"
18 #include "picture_proxy.h"
19 #include "iservice_registry.h"
20 #include "camera_log.h"
21 #include "camera_util.h"
22 #include "system_ability_definition.h"
23 #include "picture_interface.h"
24
25 namespace OHOS {
26 namespace CameraStandard {
27
OnProcessImageDone(const std::string & imageId,const sptr<IPCFileDescriptor> & ipcFileDescriptor,int64_t bytes,uint32_t cloudImageEnhanceFlag)28 int32_t DeferredPhotoProcessingSessionCallback::OnProcessImageDone(const std::string &imageId,
29 const sptr<IPCFileDescriptor>& ipcFileDescriptor, int64_t bytes, uint32_t cloudImageEnhanceFlag)
30 {
31 // LCOV_EXCL_START
32 MEDIA_INFO_LOG("DeferredPhotoProcessingSessionCallback::OnProcessImageDone() is called!"
33 "cloudImageEnhanceFlag: %{public}u", cloudImageEnhanceFlag);
34 CHECK_RETURN_RET(ipcFileDescriptor == nullptr, CAMERA_INVALID_ARG);
35 int fd = ipcFileDescriptor->GetFd();
36 void* addr = mmap(nullptr, bytes, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
37 if (deferredPhotoProcSession_ != nullptr && deferredPhotoProcSession_->GetCallback() != nullptr) {
38 if (addr == MAP_FAILED) {
39 MEDIA_ERR_LOG("DeferredPhotoProcessingSessionCallback::OnProcessImageDone() mmap failed");
40 deferredPhotoProcSession_->GetCallback()->OnError(imageId, DpsErrorCode::ERROR_IMAGE_PROC_FAILED);
41 return 0;
42 } else {
43 deferredPhotoProcSession_->GetCallback()->OnProcessImageDone(imageId, static_cast<uint8_t*>(addr), bytes,
44 cloudImageEnhanceFlag);
45 }
46 } else {
47 MEDIA_INFO_LOG("DeferredPhotoProcessingSessionCallback::OnProcessImageDone not set!, Discarding callback");
48 }
49 munmap(addr, bytes);
50 return 0;
51 // LCOV_EXCL_STOP
52 }
53
OnError(const std::string & imageId,DeferredProcessing::ErrorCode errorCode)54 int32_t DeferredPhotoProcessingSessionCallback::OnError(const std::string &imageId,
55 DeferredProcessing::ErrorCode errorCode)
56 {
57 // LCOV_EXCL_START
58 MEDIA_INFO_LOG("DeferredPhotoProcessingSessionCallback::OnError() is called, errorCode: %{public}d", errorCode);
59 if (deferredPhotoProcSession_ != nullptr && deferredPhotoProcSession_->GetCallback() != nullptr) {
60 deferredPhotoProcSession_->GetCallback()->OnError(imageId, DpsErrorCode(errorCode));
61 } else {
62 MEDIA_INFO_LOG("DeferredPhotoProcessingSessionCallback::OnError not set!, Discarding callback");
63 }
64 return 0;
65 // LCOV_EXCL_STOP
66 }
67
OnStateChanged(DeferredProcessing::StatusCode status)68 int32_t DeferredPhotoProcessingSessionCallback::OnStateChanged(DeferredProcessing::StatusCode status)
69 {
70 // LCOV_EXCL_START
71 MEDIA_INFO_LOG("DeferredPhotoProcessingSessionCallback::OnStateChanged() is called, status:%{public}d", status);
72 if (deferredPhotoProcSession_ != nullptr && deferredPhotoProcSession_->GetCallback() != nullptr) {
73 deferredPhotoProcSession_->GetCallback()->OnStateChanged(DpsStatusCode(status));
74 } else {
75 MEDIA_INFO_LOG("DeferredPhotoProcessingSessionCallback::OnStateChanged not set!, Discarding callback");
76 }
77 return 0;
78 // LCOV_EXCL_STOP
79 }
80
OnProcessImageDone(const std::string & imageId,const std::shared_ptr<PictureIntf> & pictureIntf,uint32_t cloudImageEnhanceFlag)81 int32_t DeferredPhotoProcessingSessionCallback::OnProcessImageDone(const std::string &imageId,
82 const std::shared_ptr<PictureIntf>& pictureIntf, uint32_t cloudImageEnhanceFlag)
83 {
84 // LCOV_EXCL_START
85 MEDIA_INFO_LOG("DeferredPhotoProcessingSessionCallback::OnProcessImageDone() is"
86 "called, status:%{public}s, cloudImageEnhanceFlag: %{public}u", imageId.c_str(), cloudImageEnhanceFlag);
87 if (pictureIntf != nullptr) {
88 MEDIA_INFO_LOG("picture is not null");
89 }
90 if (deferredPhotoProcSession_ != nullptr && deferredPhotoProcSession_->GetCallback() != nullptr) {
91 deferredPhotoProcSession_->GetCallback()->OnProcessImageDone(imageId, pictureIntf, cloudImageEnhanceFlag);
92 } else {
93 MEDIA_INFO_LOG("DeferredPhotoProcessingSessionCallback::OnProcessImageDone not set!, Discarding callback");
94 }
95 return 0;
96 // LCOV_EXCL_STOP
97 }
98
OnDeliveryLowQualityImage(const std::string & imageId,const std::shared_ptr<PictureIntf> & pictureIntf)99 int32_t DeferredPhotoProcessingSessionCallback::OnDeliveryLowQualityImage(const std::string &imageId,
100 const std::shared_ptr<PictureIntf>& pictureIntf)
101 {
102 // LCOV_EXCL_START
103 MEDIA_INFO_LOG("DeferredPhotoProcessingSessionCallback::OnDeliveryLowQualityImage() is"
104 "called, status:%{public}s", imageId.c_str());
105 auto callback = deferredPhotoProcSession_->GetCallback();
106 if (pictureIntf != nullptr && callback != nullptr) {
107 MEDIA_INFO_LOG("pictureIntf is not null");
108 callback->OnDeliveryLowQualityImage(imageId, pictureIntf);
109 }
110 return 0;
111 // LCOV_EXCL_STOP
112 }
113
CallbackParcel(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)114 int32_t DeferredPhotoProcessingSessionCallback::CallbackParcel([[maybe_unused]] uint32_t code,
115 [[maybe_unused]] MessageParcel& data, [[maybe_unused]] MessageParcel& reply, [[maybe_unused]] MessageOption& option)
116 {
117 // LCOV_EXCL_START
118 MEDIA_DEBUG_LOG("start, code:%{public}u", code);
119 if ((static_cast<DeferredProcessing::IDeferredPhotoProcessingSessionCallbackIpcCode>(code)
120 != DeferredProcessing::IDeferredPhotoProcessingSessionCallbackIpcCode::COMMAND_ON_DELIVERY_LOW_QUALITY_IMAGE)
121 && (static_cast<DeferredProcessing::IDeferredPhotoProcessingSessionCallbackIpcCode>(code)
122 != DeferredProcessing::IDeferredPhotoProcessingSessionCallbackIpcCode::
123 COMMAND_ON_PROCESS_IMAGE_DONE_IN_STRING_IN_SHARED_PTR_PICTUREINTF_IN_UNSIGNED_INT)) {
124 return ERR_NONE;
125 }
126 CHECK_RETURN_RET(data.ReadInterfaceToken() != GetDescriptor(), ERR_TRANSACTION_FAILED);
127
128 switch (static_cast<DeferredProcessing::IDeferredPhotoProcessingSessionCallbackIpcCode>(code)) {
129 case DeferredProcessing::IDeferredPhotoProcessingSessionCallbackIpcCode::
130 COMMAND_ON_DELIVERY_LOW_QUALITY_IMAGE: {
131 MEDIA_INFO_LOG("HandleProcessLowQualityImage enter");
132 std::string imageId = Str16ToStr8(data.ReadString16());
133 int32_t size = data.ReadInt32();
134 CHECK_RETURN_RET_ELOG(size == 0, ERR_INVALID_DATA, "Not an parcelable oject");
135 std::shared_ptr<PictureProxy> picturePtr = PictureProxy::CreatePictureProxy();
136 CHECK_RETURN_RET_ELOG(picturePtr == nullptr, ERR_INVALID_DATA, "picturePtr is nullptr");
137 MEDIA_DEBUG_LOG("HandleProcessLowQualityImage Picture::Unmarshalling E");
138 picturePtr->UnmarshallingPicture(data);
139 MEDIA_DEBUG_LOG("HandleProcessLowQualityImage Picture::Unmarshalling X");
140 ErrCode errCode = OnDeliveryLowQualityImage(imageId, picturePtr->GetPictureIntf());
141 MEDIA_INFO_LOG("HandleProcessLowQualityImage result: %{public}d", errCode);
142 CHECK_RETURN_RET_ELOG(!reply.WriteInt32(errCode), ERR_INVALID_VALUE,
143 "OnDeliveryLowQualityImage faild");
144 break;
145 }
146 case DeferredProcessing::IDeferredPhotoProcessingSessionCallbackIpcCode::
147 COMMAND_ON_PROCESS_IMAGE_DONE_IN_STRING_IN_SHARED_PTR_PICTUREINTF_IN_UNSIGNED_INT: {
148 MEDIA_INFO_LOG("HandleOnProcessPictureDone enter");
149 std::string imageId = Str16ToStr8(data.ReadString16());
150 int32_t size = data.ReadInt32();
151 CHECK_RETURN_RET_ELOG(size == 0, ERR_INVALID_DATA, "Not an parcelable oject");
152 std::shared_ptr<PictureProxy> picturePtr = PictureProxy::CreatePictureProxy();
153 CHECK_RETURN_RET_ELOG(picturePtr == nullptr, IPC_STUB_INVALID_DATA_ERR, "picturePtr is nullptr");
154 MEDIA_DEBUG_LOG("HandleOnProcessPictureDone Picture::Unmarshalling E");
155 picturePtr->UnmarshallingPicture(data);
156 MEDIA_DEBUG_LOG("HandleOnProcessPictureDone Picture::Unmarshalling X");
157 uint32_t cloudImageEnhanceFlag = data.ReadUint32();
158 ErrCode errCode = OnProcessImageDone(imageId, picturePtr->GetPictureIntf(), cloudImageEnhanceFlag);
159 MEDIA_INFO_LOG("HandleOnProcessPictureDone result: %{public}d, cloudImageEnhanceFlag: %{public}u",
160 errCode, cloudImageEnhanceFlag);
161 CHECK_RETURN_RET_ELOG(!reply.WriteInt32(errCode), ERR_INVALID_VALUE, "OnProcessImageDone faild");
162 break;
163 }
164 default:
165 break;
166 }
167 return -1;
168 // LCOV_EXCL_STOP
169 }
170
DeferredPhotoProcSession(int userId,std::shared_ptr<IDeferredPhotoProcSessionCallback> callback)171 DeferredPhotoProcSession::DeferredPhotoProcSession(int userId,
172 std::shared_ptr<IDeferredPhotoProcSessionCallback> callback)
173 {
174 MEDIA_INFO_LOG("enter.");
175 userId_ = userId;
176 callback_ = callback;
177 }
178
~DeferredPhotoProcSession()179 DeferredPhotoProcSession::~DeferredPhotoProcSession()
180 {
181 MEDIA_INFO_LOG("DeferredPhotoProcSession::DeferredPhotoProcSession Destructor!");
182 CHECK_RETURN(remoteSession_ == nullptr);
183 (void)remoteSession_->AsObject()->RemoveDeathRecipient(deathRecipient_);
184 remoteSession_ = nullptr;
185 }
186
BeginSynchronize()187 void DeferredPhotoProcSession::BeginSynchronize()
188 {
189 // LCOV_EXCL_START
190 CHECK_RETURN_ELOG(
191 remoteSession_ == nullptr, "DeferredPhotoProcSession::BeginSynchronize failed due to binder died.");
192
193 MEDIA_INFO_LOG("DeferredPhotoProcSession:BeginSynchronize() enter.");
194 remoteSession_->BeginSynchronize();
195 // LCOV_EXCL_STOP
196 }
197
EndSynchronize()198 void DeferredPhotoProcSession::EndSynchronize()
199 {
200 // LCOV_EXCL_START
201 CHECK_RETURN_ELOG(
202 remoteSession_ == nullptr, "DeferredPhotoProcSession::EndSynchronize failed due to binder died.");
203 MEDIA_INFO_LOG("DeferredPhotoProcSession::EndSynchronize() enter.");
204 remoteSession_->EndSynchronize();
205 // LCOV_EXCL_STOP
206 }
207
AddImage(const std::string & imageId,DpsMetadata & metadata,const bool discardable)208 void DeferredPhotoProcSession::AddImage(const std::string& imageId, DpsMetadata& metadata, const bool discardable)
209 {
210 // LCOV_EXCL_START
211 CHECK_RETURN_ELOG(remoteSession_ == nullptr, "DeferredPhotoProcSession::AddImage failed due to binder died.");
212 MEDIA_INFO_LOG("DeferredPhotoProcSession::AddImage() enter.");
213 remoteSession_->AddImage(imageId, metadata, discardable);
214 // LCOV_EXCL_STOP
215 }
216
RemoveImage(const std::string & imageId,const bool restorable)217 void DeferredPhotoProcSession::RemoveImage(const std::string& imageId, const bool restorable)
218 {
219 // LCOV_EXCL_START
220 CHECK_RETURN_ELOG(
221 remoteSession_ == nullptr, "DeferredPhotoProcSession::RemoveImage failed due to binder died.");
222 MEDIA_INFO_LOG("DeferredPhotoProcSession RemoveImage() enter.");
223 remoteSession_->RemoveImage(imageId, restorable);
224 // LCOV_EXCL_STOP
225 }
226
RestoreImage(const std::string & imageId)227 void DeferredPhotoProcSession::RestoreImage(const std::string& imageId)
228 {
229 // LCOV_EXCL_START
230 CHECK_RETURN_ELOG(
231 remoteSession_ == nullptr, "DeferredPhotoProcSession::RestoreImage failed due to binder died.");
232 MEDIA_INFO_LOG("DeferredPhotoProcSession RestoreImage() enter.");
233 remoteSession_->RestoreImage(imageId);
234 // LCOV_EXCL_STOP
235 }
236
ProcessImage(const std::string & appName,const std::string & imageId)237 void DeferredPhotoProcSession::ProcessImage(const std::string& appName, const std::string& imageId)
238 {
239 // LCOV_EXCL_START
240 CHECK_RETURN_ELOG(
241 remoteSession_ == nullptr, "DeferredPhotoProcSession::ProcessImage failed due to binder died.");
242 MEDIA_INFO_LOG("DeferredPhotoProcSession::ProcessImage() enter.");
243 remoteSession_->ProcessImage(appName, imageId);
244 // LCOV_EXCL_STOP
245 }
246
CancelProcessImage(const std::string & imageId)247 bool DeferredPhotoProcSession::CancelProcessImage(const std::string& imageId)
248 {
249 // LCOV_EXCL_START
250 CHECK_RETURN_RET_ELOG(
251 remoteSession_ == nullptr, false, "DeferredPhotoProcSession::CancelProcessImage failed due to binder died.");
252 MEDIA_INFO_LOG("DeferredPhotoProcSession:CancelProcessImage() enter.");
253 remoteSession_->CancelProcessImage(imageId);
254 return true;
255 // LCOV_EXCL_STOP
256 }
257
SetDeferredPhotoSession(sptr<DeferredProcessing::IDeferredPhotoProcessingSession> & session)258 int32_t DeferredPhotoProcSession::SetDeferredPhotoSession(
259 sptr<DeferredProcessing::IDeferredPhotoProcessingSession>& session)
260 {
261 // LCOV_EXCL_START
262 remoteSession_ = session;
263 sptr<IRemoteObject> object = remoteSession_->AsObject();
264 pid_t pid = 0;
265 deathRecipient_ = new(std::nothrow) CameraDeathRecipient(pid);
266 CHECK_RETURN_RET_ELOG(deathRecipient_ == nullptr, CAMERA_ALLOC_ERROR, "failed to new CameraDeathRecipient.");
267
268 deathRecipient_->SetNotifyCb([this](pid_t pid) { CameraServerDied(pid); });
269 bool result = object->AddDeathRecipient(deathRecipient_);
270 CHECK_RETURN_RET_ELOG(!result, -1, "failed to add deathRecipient");
271 return 0;
272 // LCOV_EXCL_STOP
273 }
274
CameraServerDied(pid_t pid)275 void DeferredPhotoProcSession::CameraServerDied(pid_t pid)
276 {
277 // LCOV_EXCL_START
278 MEDIA_ERR_LOG("camera server has died, pid:%{public}d!", pid);
279 if (remoteSession_ != nullptr) {
280 (void)remoteSession_->AsObject()->RemoveDeathRecipient(deathRecipient_);
281 remoteSession_ = nullptr;
282 }
283 deathRecipient_ = nullptr;
284 ReconnectDeferredProcessingSession();
285 if (callback_ != nullptr) {
286 MEDIA_INFO_LOG("DeferredPhotoProcSession Reconnect session successful, send sync requestion.");
287 callback_->OnError("", DpsErrorCode::ERROR_SESSION_SYNC_NEEDED);
288 }
289 return;
290 // LCOV_EXCL_STOP
291 }
292
ReconnectDeferredProcessingSession()293 void DeferredPhotoProcSession::ReconnectDeferredProcessingSession()
294 {
295 // LCOV_EXCL_START
296 MEDIA_INFO_LOG("DeferredPhotoProcSession::ReconnectDeferredProcessingSession, enter.");
297 ConnectDeferredProcessingSession();
298 if (remoteSession_ == nullptr) {
299 MEDIA_INFO_LOG("Reconnecting deferred processing session failed.");
300 ReconnectDeferredProcessingSession();
301 }
302 return;
303 // LCOV_EXCL_STOP
304 }
305
ConnectDeferredProcessingSession()306 void DeferredPhotoProcSession::ConnectDeferredProcessingSession()
307 {
308 // LCOV_EXCL_START
309 MEDIA_INFO_LOG("DeferredPhotoProcSession::ConnectDeferredProcessingSession, enter.");
310 CHECK_RETURN_ELOG(remoteSession_ != nullptr, "remoteSession_ is not null");
311 sptr<IRemoteObject> object = nullptr;
312 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
313 CHECK_RETURN_ELOG(samgr == nullptr, "Failed to get System ability manager");
314 object = samgr->GetSystemAbility(CAMERA_SERVICE_ID);
315 CHECK_RETURN_ELOG(object == nullptr, "object is null");
316 serviceProxy_ = iface_cast<ICameraService>(object);
317 CHECK_RETURN_ELOG(serviceProxy_ == nullptr, "serviceProxy_ is null");
318 sptr<DeferredProcessing::IDeferredPhotoProcessingSession> session = nullptr;
319 sptr<DeferredProcessing::IDeferredPhotoProcessingSessionCallback> remoteCallback = nullptr;
320 sptr<DeferredPhotoProcSession> deferredPhotoProcSession = nullptr;
321 deferredPhotoProcSession = new(std::nothrow) DeferredPhotoProcSession(userId_, callback_);
322 CHECK_RETURN(deferredPhotoProcSession == nullptr);
323 remoteCallback = new(std::nothrow) DeferredPhotoProcessingSessionCallback(deferredPhotoProcSession);
324 CHECK_RETURN(remoteCallback == nullptr);
325 serviceProxy_->CreateDeferredPhotoProcessingSession(userId_, remoteCallback, session);
326 CHECK_EXECUTE(session, SetDeferredPhotoSession(session));
327 return;
328 // LCOV_EXCL_STOP
329 }
330
GetCallback()331 std::shared_ptr<IDeferredPhotoProcSessionCallback> DeferredPhotoProcSession::GetCallback()
332 {
333 return callback_;
334 }
335
336 } // namespace CameraStandard
337 } // namespace OHOS