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 "ipc_skeleton.h"
19 #include "iservice_registry.h"
20 #include "camera_log.h"
21 #include "camera_util.h"
22 #include "system_ability_definition.h"
23 #include "camera_error_code.h"
24 #include "picture.h"
25 
26 namespace OHOS {
27 namespace CameraStandard {
28 
OnProcessImageDone(const std::string & imageId,const sptr<IPCFileDescriptor> ipcFileDescriptor,const long bytes,bool isCloudImageEnhanceSupported)29 int32_t DeferredPhotoProcessingSessionCallback::OnProcessImageDone(const std::string &imageId,
30     const sptr<IPCFileDescriptor> ipcFileDescriptor, const long bytes, bool isCloudImageEnhanceSupported)
31 {
32     MEDIA_INFO_LOG("DeferredPhotoProcessingSessionCallback::OnProcessImageDone() is called!");
33     if (ipcFileDescriptor == nullptr) {
34         return CAMERA_INVALID_ARG;
35     }
36     int fd = ipcFileDescriptor->GetFd();
37     void* addr = mmap(nullptr, bytes, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
38     if (deferredPhotoProcSession_ != nullptr && deferredPhotoProcSession_->GetCallback() != nullptr) {
39         if (addr == MAP_FAILED) {
40             MEDIA_ERR_LOG("DeferredPhotoProcessingSessionCallback::OnProcessImageDone() mmap failed");
41             deferredPhotoProcSession_->GetCallback()->OnError(imageId, ERROR_IMAGE_PROC_FAILED);
42             return 0;
43         } else {
44             deferredPhotoProcSession_->GetCallback()->OnProcessImageDone(imageId, static_cast<uint8_t*>(addr), bytes,
45                 isCloudImageEnhanceSupported);
46         }
47     } else {
48         MEDIA_INFO_LOG("DeferredPhotoProcessingSessionCallback::OnProcessImageDone not set!, Discarding callback");
49     }
50     munmap(addr, bytes);
51     return 0;
52 }
53 
OnError(const std::string & imageId,const DeferredProcessing::ErrorCode errorCode)54 int32_t DeferredPhotoProcessingSessionCallback::OnError(const std::string &imageId,
55     const DeferredProcessing::ErrorCode errorCode)
56 {
57     MEDIA_INFO_LOG("DeferredPhotoProcessingSessionCallback::OnError() is called, errorCode: %{public}d", errorCode);
58     if (deferredPhotoProcSession_ != nullptr && deferredPhotoProcSession_->GetCallback() != nullptr) {
59         deferredPhotoProcSession_->GetCallback()->OnError(imageId, DpsErrorCode(errorCode));
60     } else {
61         MEDIA_INFO_LOG("DeferredPhotoProcessingSessionCallback::OnError not set!, Discarding callback");
62     }
63     return 0;
64 }
65 
OnStateChanged(const DeferredProcessing::StatusCode status)66 int32_t DeferredPhotoProcessingSessionCallback::OnStateChanged(const DeferredProcessing::StatusCode status)
67 {
68     MEDIA_INFO_LOG("DeferredPhotoProcessingSessionCallback::OnStateChanged() is called, status:%{public}d", status);
69     if (deferredPhotoProcSession_ != nullptr && deferredPhotoProcSession_->GetCallback() != nullptr) {
70         deferredPhotoProcSession_->GetCallback()->OnStateChanged(DpsStatusCode(status));
71     } else {
72         MEDIA_INFO_LOG("DeferredPhotoProcessingSessionCallback::OnStateChanged not set!, Discarding callback");
73     }
74     return 0;
75 }
76 
OnProcessImageDone(const std::string & imageId,std::shared_ptr<Media::Picture> picture,bool isCloudImageEnhanceSupported)77 int32_t DeferredPhotoProcessingSessionCallback::OnProcessImageDone(const std::string &imageId,
78     std::shared_ptr<Media::Picture> picture, bool isCloudImageEnhanceSupported)
79 {
80     MEDIA_INFO_LOG("DeferredPhotoProcessingSessionCallback::OnProcessImageDone() is"
81         "called, status:%{public}s", imageId.c_str());
82     if (picture != nullptr) {
83         MEDIA_INFO_LOG("picture is not null");
84     }
85     if (deferredPhotoProcSession_ != nullptr && deferredPhotoProcSession_->GetCallback() != nullptr) {
86         deferredPhotoProcSession_->GetCallback()->OnProcessImageDone(imageId, picture, isCloudImageEnhanceSupported);
87     } else {
88         MEDIA_INFO_LOG("DeferredPhotoProcessingSessionCallback::OnProcessImageDone not set!, Discarding callback");
89     }
90     return 0;
91 }
92 
OnDeliveryLowQualityImage(const std::string & imageId,std::shared_ptr<Media::Picture> picture)93 int32_t DeferredPhotoProcessingSessionCallback::OnDeliveryLowQualityImage(const std::string &imageId,
94     std::shared_ptr<Media::Picture> picture)
95 {
96     MEDIA_INFO_LOG("DeferredPhotoProcessingSessionCallback::OnDeliveryLowQualityImage() is"
97         "called, status:%{public}s", imageId.c_str());
98     if (picture != nullptr) {
99         MEDIA_INFO_LOG("picture is not null");
100         deferredPhotoProcSession_->GetCallback()->OnDeliveryLowQualityImage(imageId, picture);
101     }
102     return 0;
103 }
104 
DeferredPhotoProcSession(int userId,std::shared_ptr<IDeferredPhotoProcSessionCallback> callback)105 DeferredPhotoProcSession::DeferredPhotoProcSession(int userId,
106     std::shared_ptr<IDeferredPhotoProcSessionCallback> callback)
107 {
108     MEDIA_INFO_LOG("enter.");
109     userId_ = userId;
110     callback_ = callback;
111 }
112 
~DeferredPhotoProcSession()113 DeferredPhotoProcSession::~DeferredPhotoProcSession()
114 {
115     MEDIA_INFO_LOG("DeferredPhotoProcSession::DeferredPhotoProcSession Destructor!");
116     if (remoteSession_ != nullptr) {
117         (void)remoteSession_->AsObject()->RemoveDeathRecipient(deathRecipient_);
118         remoteSession_ = nullptr;
119     }
120 }
121 
BeginSynchronize()122 void DeferredPhotoProcSession::BeginSynchronize()
123 {
124     if (remoteSession_ == nullptr) {
125         MEDIA_ERR_LOG("DeferredPhotoProcSession::BeginSynchronize failed due to binder died.");
126     } else {
127         MEDIA_INFO_LOG("DeferredPhotoProcSession:BeginSynchronize() enter.");
128         remoteSession_->BeginSynchronize();
129     }
130     return;
131 }
132 
EndSynchronize()133 void DeferredPhotoProcSession::EndSynchronize()
134 {
135     if (remoteSession_ == nullptr) {
136         MEDIA_ERR_LOG("DeferredPhotoProcSession::EndSynchronize failed due to binder died.");
137     } else {
138         MEDIA_INFO_LOG("DeferredPhotoProcSession::EndSynchronize() enter.");
139         remoteSession_->EndSynchronize();
140     }
141     return;
142 }
143 
AddImage(const std::string & imageId,DpsMetadata & metadata,const bool discardable)144 void DeferredPhotoProcSession::AddImage(const std::string& imageId, DpsMetadata& metadata, const bool discardable)
145 {
146     if (remoteSession_ == nullptr) {
147         MEDIA_ERR_LOG("DeferredPhotoProcSession::AddImage failed due to binder died.");
148     } else {
149         MEDIA_INFO_LOG("DeferredPhotoProcSession::AddImage() enter.");
150         remoteSession_->AddImage(imageId, metadata, discardable);
151     }
152     return;
153 }
154 
RemoveImage(const std::string & imageId,const bool restorable)155 void DeferredPhotoProcSession::RemoveImage(const std::string& imageId, const bool restorable)
156 {
157     if (remoteSession_ == nullptr) {
158         MEDIA_ERR_LOG("DeferredPhotoProcSession::RemoveImage failed due to binder died.");
159     } else {
160         MEDIA_INFO_LOG("DeferredPhotoProcSession RemoveImage() enter.");
161         remoteSession_->RemoveImage(imageId, restorable);
162     }
163     return;
164 }
165 
RestoreImage(const std::string & imageId)166 void DeferredPhotoProcSession::RestoreImage(const std::string& imageId)
167 {
168     if (remoteSession_ == nullptr) {
169         MEDIA_ERR_LOG("DeferredPhotoProcSession::RestoreImage failed due to binder died.");
170     } else {
171         MEDIA_INFO_LOG("DeferredPhotoProcSession RestoreImage() enter.");
172         remoteSession_->RestoreImage(imageId);
173     }
174     return;
175 }
176 
ProcessImage(const std::string & appName,const std::string & imageId)177 void DeferredPhotoProcSession::ProcessImage(const std::string& appName, const std::string& imageId)
178 {
179     if (remoteSession_ == nullptr) {
180         MEDIA_ERR_LOG("DeferredPhotoProcSession::ProcessImage failed due to binder died.");
181     } else {
182         MEDIA_INFO_LOG("DeferredPhotoProcSession::ProcessImage() enter.");
183         remoteSession_->ProcessImage(appName, imageId);
184     }
185     return;
186 }
187 
CancelProcessImage(const std::string & imageId)188 bool DeferredPhotoProcSession::CancelProcessImage(const std::string& imageId)
189 {
190     if (remoteSession_ == nullptr) {
191         MEDIA_ERR_LOG("DeferredPhotoProcSession::CancelProcessImage failed due to binder died.");
192         return false;
193     }
194     MEDIA_INFO_LOG("DeferredPhotoProcSession:CancelProcessImage() enter.");
195     remoteSession_->CancelProcessImage(imageId);
196     return true;
197 }
198 
SetDeferredPhotoSession(sptr<DeferredProcessing::IDeferredPhotoProcessingSession> & session)199 int32_t DeferredPhotoProcSession::SetDeferredPhotoSession(
200     sptr<DeferredProcessing::IDeferredPhotoProcessingSession>& session)
201 {
202     remoteSession_ = session;
203     sptr<IRemoteObject> object = remoteSession_->AsObject();
204     pid_t pid = 0;
205     deathRecipient_ = new(std::nothrow) CameraDeathRecipient(pid);
206     CHECK_ERROR_RETURN_RET_LOG(deathRecipient_ == nullptr, CAMERA_ALLOC_ERROR, "failed to new CameraDeathRecipient.");
207 
208     deathRecipient_->SetNotifyCb([this](pid_t pid) { CameraServerDied(pid); });
209     bool result = object->AddDeathRecipient(deathRecipient_);
210     if (!result) {
211         MEDIA_ERR_LOG("failed to add deathRecipient");
212         return -1;  // return error
213     }
214     return 0;
215 }
216 
CameraServerDied(pid_t pid)217 void DeferredPhotoProcSession::CameraServerDied(pid_t pid)
218 {
219     MEDIA_ERR_LOG("camera server has died, pid:%{public}d!", pid);
220     if (remoteSession_ != nullptr) {
221         (void)remoteSession_->AsObject()->RemoveDeathRecipient(deathRecipient_);
222         remoteSession_ = nullptr;
223     }
224     deathRecipient_ = nullptr;
225     ReconnectDeferredProcessingSession();
226     if (callback_ != nullptr) {
227         MEDIA_INFO_LOG("Reconnect session successful, send sync requestion.");
228         callback_->OnError("", DpsErrorCode::ERROR_SESSION_SYNC_NEEDED);
229     }
230     return;
231 }
232 
ReconnectDeferredProcessingSession()233 void DeferredPhotoProcSession::ReconnectDeferredProcessingSession()
234 {
235     MEDIA_INFO_LOG("DeferredPhotoProcSession::ReconnectDeferredProcessingSession, enter.");
236     ConnectDeferredProcessingSession();
237     if (remoteSession_ == nullptr) {
238         MEDIA_INFO_LOG("Reconnecting deferred processing session failed.");
239         ReconnectDeferredProcessingSession();
240     }
241     return;
242 }
243 
ConnectDeferredProcessingSession()244 void DeferredPhotoProcSession::ConnectDeferredProcessingSession()
245 {
246     MEDIA_INFO_LOG("DeferredPhotoProcSession::ConnectDeferredProcessingSession, enter.");
247     CHECK_ERROR_RETURN_LOG(remoteSession_ != nullptr, "remoteSession_ is not null");
248     sptr<IRemoteObject> object = nullptr;
249     auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
250     CHECK_ERROR_RETURN_LOG(samgr == nullptr, "Failed to get System ability manager");
251     object = samgr->GetSystemAbility(CAMERA_SERVICE_ID);
252     CHECK_ERROR_RETURN_LOG(object == nullptr, "object is null");
253     serviceProxy_ = iface_cast<ICameraService>(object);
254     CHECK_ERROR_RETURN_LOG(serviceProxy_ == nullptr, "serviceProxy_ is null");
255     sptr<DeferredProcessing::IDeferredPhotoProcessingSession> session = nullptr;
256     sptr<DeferredProcessing::IDeferredPhotoProcessingSessionCallback> remoteCallback = nullptr;
257     sptr<DeferredPhotoProcSession> deferredPhotoProcSession = nullptr;
258     deferredPhotoProcSession = new(std::nothrow) DeferredPhotoProcSession(userId_, callback_);
259     CHECK_ERROR_RETURN(deferredPhotoProcSession == nullptr);
260     remoteCallback = new(std::nothrow) DeferredPhotoProcessingSessionCallback(deferredPhotoProcSession);
261     CHECK_ERROR_RETURN(remoteCallback == nullptr);
262     serviceProxy_->CreateDeferredPhotoProcessingSession(userId_, remoteCallback, session);
263     if (session) {
264         SetDeferredPhotoSession(session);
265     }
266     return;
267 }
268 
GetCallback()269 std::shared_ptr<IDeferredPhotoProcSessionCallback> DeferredPhotoProcSession::GetCallback()
270 {
271     return callback_;
272 }
273 
274 } // namespace CameraStandard
275 } // namespace OHOS