• 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 "session_coordinator.h"
17 
18 #include "dp_log.h"
19 #include "buffer_info.h"
20 #include "dps_event_report.h"
21 #include "steady_clock.h"
22 #include "picture.h"
23 #include "video_session_info.h"
24 
25 namespace OHOS {
26 namespace CameraStandard {
27 namespace DeferredProcessing {
MapDpsErrorCode(DpsError errorCode)28 ErrorCode MapDpsErrorCode(DpsError errorCode)
29 {
30     ErrorCode code = ErrorCode::ERROR_IMAGE_PROC_ABNORMAL;
31     switch (errorCode) {
32         case DpsError::DPS_ERROR_SESSION_SYNC_NEEDED:
33             code = ErrorCode::ERROR_SESSION_SYNC_NEEDED;
34             break;
35         case DpsError::DPS_ERROR_SESSION_NOT_READY_TEMPORARILY:
36             code = ErrorCode::ERROR_SESSION_NOT_READY_TEMPORARILY;
37             break;
38         case DpsError::DPS_ERROR_IMAGE_PROC_INVALID_PHOTO_ID:
39             code = ErrorCode::ERROR_IMAGE_PROC_INVALID_PHOTO_ID;
40             break;
41         case DpsError::DPS_ERROR_IMAGE_PROC_FAILED:
42             code = ErrorCode::ERROR_IMAGE_PROC_FAILED;
43             break;
44         case DpsError::DPS_ERROR_IMAGE_PROC_TIMEOUT:
45             code = ErrorCode::ERROR_IMAGE_PROC_TIMEOUT;
46             break;
47         case DpsError::DPS_ERROR_IMAGE_PROC_ABNORMAL:
48             code = ErrorCode::ERROR_IMAGE_PROC_ABNORMAL;
49             break;
50         case DpsError::DPS_ERROR_IMAGE_PROC_INTERRUPTED:
51             code = ErrorCode::ERROR_IMAGE_PROC_INTERRUPTED;
52             break;
53         case DpsError::DPS_ERROR_VIDEO_PROC_INVALID_VIDEO_ID:
54             code = ErrorCode::ERROR_VIDEO_PROC_INVALID_VIDEO_ID;
55             break;
56         case DpsError::DPS_ERROR_VIDEO_PROC_FAILED:
57             code = ErrorCode::ERROR_VIDEO_PROC_FAILED;
58             break;
59         case DpsError::DPS_ERROR_VIDEO_PROC_TIMEOUT:
60             code = ErrorCode::ERROR_VIDEO_PROC_TIMEOUT;
61             break;
62         case DpsError::DPS_ERROR_VIDEO_PROC_INTERRUPTED:
63             code = ErrorCode::ERROR_VIDEO_PROC_INTERRUPTED;
64             break;
65         default:
66             DP_WARNING_LOG("unexpected error code: %{public}d.", errorCode);
67             break;
68     }
69     return code;
70 }
71 
MapDpsStatus(DpsStatus statusCode)72 StatusCode MapDpsStatus(DpsStatus statusCode)
73 {
74     StatusCode code = StatusCode::SESSION_STATE_IDLE;
75     switch (statusCode) {
76         case DpsStatus::DPS_SESSION_STATE_IDLE:
77             code = StatusCode::SESSION_STATE_IDLE;
78             break;
79         case DpsStatus::DPS_SESSION_STATE_RUNNALBE:
80             code = StatusCode::SESSION_STATE_RUNNALBE;
81             break;
82         case DpsStatus::DPS_SESSION_STATE_RUNNING:
83             code = StatusCode::SESSION_STATE_RUNNING;
84             break;
85         case DpsStatus::DPS_SESSION_STATE_SUSPENDED:
86             code = StatusCode::SESSION_STATE_SUSPENDED;
87             break;
88         default:
89             DP_WARNING_LOG("unexpected error code: %{public}d.", statusCode);
90             break;
91     }
92     return code;
93 }
94 
95 class SessionCoordinator::ImageProcCallbacks : public IImageProcessCallbacks {
96 public:
ImageProcCallbacks(SessionCoordinator * coordinator)97     explicit ImageProcCallbacks(SessionCoordinator* coordinator) : coordinator_(coordinator)
98     {
99     }
100 
~ImageProcCallbacks()101     ~ImageProcCallbacks() override
102     {
103         coordinator_ = nullptr;
104     }
105 
OnProcessDone(const int32_t userId,const std::string & imageId,std::shared_ptr<BufferInfo> bufferInfo)106     void OnProcessDone(const int32_t userId, const std::string& imageId,
107         std::shared_ptr<BufferInfo> bufferInfo) override
108     {
109         sptr<IPCFileDescriptor> ipcFd = bufferInfo->GetIPCFileDescriptor();
110         int32_t dataSize = bufferInfo->GetDataSize();
111         bool isCloudImageEnhanceSupported = bufferInfo->IsCloudImageEnhanceSupported();
112         if (coordinator_) {
113             coordinator_->OnProcessDone(userId, imageId, ipcFd, dataSize, isCloudImageEnhanceSupported);
114         }
115     }
116 
OnProcessDoneExt(int userId,const std::string & imageId,std::shared_ptr<BufferInfoExt> bufferInfo)117     void OnProcessDoneExt(int userId, const std::string& imageId,
118         std::shared_ptr<BufferInfoExt> bufferInfo) override
119     {
120         bool isCloudImageEnhanceSupported = bufferInfo->IsCloudImageEnhanceSupported();
121         if (coordinator_ && bufferInfo) {
122             coordinator_->OnProcessDoneExt(userId, imageId, bufferInfo->GetPicture(), isCloudImageEnhanceSupported);
123         }
124     }
125 
OnError(const int userId,const std::string & imageId,DpsError errorCode)126     void OnError(const int userId, const std::string& imageId, DpsError errorCode) override
127     {
128         DP_CHECK_EXECUTE(coordinator_ != nullptr, coordinator_->OnError(userId, imageId, errorCode));
129     }
130 
OnStateChanged(const int32_t userId,DpsStatus statusCode)131     void OnStateChanged(const int32_t userId, DpsStatus statusCode) override
132     {
133         DP_CHECK_EXECUTE(coordinator_ != nullptr, coordinator_->OnStateChanged(userId, statusCode));
134     }
135 
136 private:
137     SessionCoordinator* coordinator_;
138 };
139 
140 class SessionCoordinator::VideoProcCallbacks : public IVideoProcessCallbacks {
141 public:
VideoProcCallbacks(const std::weak_ptr<SessionCoordinator> & coordinator)142     explicit VideoProcCallbacks(const std::weak_ptr<SessionCoordinator>& coordinator) : coordinator_(coordinator)
143     {
144     }
145 
146     ~VideoProcCallbacks() = default;
147 
OnProcessDone(const int32_t userId,const std::string & videoId,const sptr<IPCFileDescriptor> & ipcFd)148     void OnProcessDone(const int32_t userId, const std::string& videoId,
149         const sptr<IPCFileDescriptor>& ipcFd) override
150     {
151         auto video = coordinator_.lock();
152         DP_CHECK_ERROR_RETURN_LOG(video == nullptr, "SessionCoordinator is nullptr.");
153         video->OnVideoProcessDone(userId, videoId, ipcFd);
154     }
155 
OnError(const int32_t userId,const std::string & videoId,DpsError errorCode)156     void OnError(const int32_t userId, const std::string& videoId, DpsError errorCode) override
157     {
158         auto video = coordinator_.lock();
159         DP_CHECK_ERROR_RETURN_LOG(video == nullptr, "SessionCoordinator is nullptr.");
160         video->OnVideoError(userId, videoId, errorCode);
161     }
162 
OnStateChanged(const int32_t userId,DpsStatus statusCode)163     void OnStateChanged(const int32_t userId, DpsStatus statusCode) override
164     {
165         auto video = coordinator_.lock();
166         DP_CHECK_ERROR_RETURN_LOG(video == nullptr, "SessionCoordinator is nullptr.");
167         video->OnStateChanged(userId, statusCode);
168     }
169 
170 private:
171     std::weak_ptr<SessionCoordinator> coordinator_;
172 };
173 
SessionCoordinator()174 SessionCoordinator::SessionCoordinator()
175     : imageProcCallbacks_(nullptr),
176       remoteImageCallbacksMap_(),
177       pendingImageResults_(),
178       videoProcCallbacks_(nullptr),
179       remoteVideoCallbacksMap_(),
180       pendingRequestResults_()
181 {
182     DP_DEBUG_LOG("entered.");
183 }
184 
~SessionCoordinator()185 SessionCoordinator::~SessionCoordinator()
186 {
187     DP_DEBUG_LOG("entered.");
188     imageProcCallbacks_ = nullptr;
189     remoteImageCallbacksMap_.clear();
190     pendingImageResults_.clear();
191     videoProcCallbacks_ = nullptr;
192     remoteVideoCallbacksMap_.clear();
193     pendingRequestResults_.clear();
194 }
195 
Initialize()196 void SessionCoordinator::Initialize()
197 {
198     imageProcCallbacks_ = std::make_shared<ImageProcCallbacks>(this);
199     videoProcCallbacks_ = std::make_shared<VideoProcCallbacks>(weak_from_this());
200 }
201 
Start()202 void SessionCoordinator::Start()
203 {
204     //dps_log
205 }
206 
Stop()207 void SessionCoordinator::Stop()
208 {
209     //dps_log
210 }
211 
GetImageProcCallbacks()212 std::shared_ptr<IImageProcessCallbacks> SessionCoordinator::GetImageProcCallbacks()
213 {
214     return imageProcCallbacks_;
215 }
216 
GetVideoProcCallbacks()217 std::shared_ptr<IVideoProcessCallbacks> SessionCoordinator::GetVideoProcCallbacks()
218 {
219     return videoProcCallbacks_;
220 }
221 
OnProcessDone(const int32_t userId,const std::string & imageId,const sptr<IPCFileDescriptor> & ipcFd,const int32_t dataSize,bool isCloudImageEnhanceSupported)222 void SessionCoordinator::OnProcessDone(const int32_t userId, const std::string& imageId,
223     const sptr<IPCFileDescriptor>& ipcFd, const int32_t dataSize, bool isCloudImageEnhanceSupported)
224 {
225     DP_INFO_LOG("entered, userId: %{public}d, map size: %{public}d.",
226         userId, static_cast<int32_t>(remoteImageCallbacksMap_.size()));
227     auto iter = remoteImageCallbacksMap_.find(userId);
228     if (iter != remoteImageCallbacksMap_.end()) {
229         auto wpCallback = iter->second;
230         sptr<IDeferredPhotoProcessingSessionCallback> spCallback = wpCallback.promote();
231         DP_INFO_LOG("entered, imageId: %{public}s", imageId.c_str());
232         spCallback->OnProcessImageDone(imageId, ipcFd, dataSize, isCloudImageEnhanceSupported);
233     } else {
234         DP_INFO_LOG("callback is null, cache request, imageId: %{public}s.", imageId.c_str());
235         pendingImageResults_.push_back({CallbackType::ON_PROCESS_DONE, userId, imageId, ipcFd, dataSize,
236             DpsError::DPS_ERROR_SESSION_SYNC_NEEDED, DpsStatus::DPS_SESSION_STATE_IDLE,
237             isCloudImageEnhanceSupported});
238     }
239     return;
240 }
241 
OnProcessDoneExt(int userId,const std::string & imageId,std::shared_ptr<Media::Picture> picture,bool isCloudImageEnhanceSupported)242 void SessionCoordinator::OnProcessDoneExt(int userId, const std::string& imageId,
243     std::shared_ptr<Media::Picture> picture, bool isCloudImageEnhanceSupported)
244 {
245     auto iter = remoteImageCallbacksMap_.find(userId);
246     if (iter != remoteImageCallbacksMap_.end()) {
247         auto wpCallback = iter->second;
248         sptr<IDeferredPhotoProcessingSessionCallback> spCallback = wpCallback.promote();
249         DP_INFO_LOG("entered, imageId: %s", imageId.c_str());
250         spCallback->OnProcessImageDone(imageId, picture, isCloudImageEnhanceSupported);
251     } else {
252         DP_INFO_LOG("callback is null, cache request, imageId: %{public}s.", imageId.c_str());
253     }
254     return;
255 }
256 
OnError(const int userId,const std::string & imageId,DpsError errorCode)257 void SessionCoordinator::OnError(const int userId, const std::string& imageId, DpsError errorCode)
258 {
259     auto iter = remoteImageCallbacksMap_.find(userId);
260     if (iter != remoteImageCallbacksMap_.end()) {
261         auto wpCallback = iter->second;
262         sptr<IDeferredPhotoProcessingSessionCallback> spCallback = wpCallback.promote();
263         DP_INFO_LOG("entered, userId: %{public}d", userId);
264         spCallback->OnError(imageId, MapDpsErrorCode(errorCode));
265     } else {
266         DP_INFO_LOG("callback is null, cache request, imageId: %{public}s, errorCode: %{public}d.",
267             imageId.c_str(), errorCode);
268         pendingImageResults_.push_back({CallbackType::ON_ERROR, userId, imageId, nullptr, 0, errorCode});
269     }
270 }
271 
OnStateChanged(const int32_t userId,DpsStatus statusCode)272 void SessionCoordinator::OnStateChanged(const int32_t userId, DpsStatus statusCode)
273 {
274     auto iter = remoteImageCallbacksMap_.find(userId);
275     if (iter != remoteImageCallbacksMap_.end()) {
276         auto wpCallback = iter->second;
277         sptr<IDeferredPhotoProcessingSessionCallback> spCallback = wpCallback.promote();
278         DP_INFO_LOG("entered, userId: %{public}d", userId);
279         spCallback->OnStateChanged(MapDpsStatus(statusCode));
280     } else {
281         DP_INFO_LOG("cache request, statusCode: %{public}d.", statusCode);
282         pendingImageResults_.push_back({CallbackType::ON_STATE_CHANGED, userId, "", nullptr, 0,
283             DpsError::DPS_ERROR_IMAGE_PROC_ABNORMAL, statusCode});
284     }
285 }
286 
NotifySessionCreated(const int32_t userId,sptr<IDeferredPhotoProcessingSessionCallback> callback,TaskManager * taskManager)287 void SessionCoordinator::NotifySessionCreated(const int32_t userId,
288     sptr<IDeferredPhotoProcessingSessionCallback> callback, TaskManager* taskManager)
289 {
290     if (callback) {
291         remoteImageCallbacksMap_[userId] = callback;
292         taskManager->SubmitTask([this, callback]() {
293             this->ProcessPendingResults(callback);
294         });
295     }
296 }
297 
ProcessPendingResults(sptr<IDeferredPhotoProcessingSessionCallback> callback)298 void SessionCoordinator::ProcessPendingResults(sptr<IDeferredPhotoProcessingSessionCallback> callback)
299 {
300     DP_INFO_LOG("entered.");
301     while (!pendingImageResults_.empty()) {
302         auto result = pendingImageResults_.front();
303         if (result.callbackType == CallbackType::ON_PROCESS_DONE) {
304             callback->OnProcessImageDone(result.imageId, result.ipcFd, result.dataSize,
305                 result.isCloudImageEnhanceSupported);
306             uint64_t endTime = SteadyClock::GetTimestampMilli();
307             DPSEventReport::GetInstance().ReportImageProcessResult(result.imageId, result.userId, endTime);
308         }
309         if (result.callbackType == CallbackType::ON_ERROR) {
310             callback->OnError(result.imageId, MapDpsErrorCode(result.errorCode));
311         }
312         if (result.callbackType == CallbackType::ON_STATE_CHANGED) {
313             callback->OnStateChanged(MapDpsStatus(result.statusCode));
314         }
315         pendingImageResults_.pop_front();
316     }
317 }
318 
NotifyCallbackDestroyed(const int32_t userId)319 void SessionCoordinator::NotifyCallbackDestroyed(const int32_t userId)
320 {
321     if (remoteImageCallbacksMap_.count(userId) != 0) {
322         DP_INFO_LOG("session userId: %{public}d destroyed.", userId);
323         remoteImageCallbacksMap_.erase(userId);
324     }
325 }
326 
AddSession(const sptr<VideoSessionInfo> & sessionInfo)327 void SessionCoordinator::AddSession(const sptr<VideoSessionInfo>& sessionInfo)
328 {
329     int32_t userId = sessionInfo->GetUserId();
330     DP_INFO_LOG("add session userId: %{public}d", userId);
331     auto callback = sessionInfo->GetRemoteCallback();
332     if (callback != nullptr) {
333         remoteVideoCallbacksMap_[userId] = callback;
334         ProcessVideoResults(callback);
335     }
336 }
337 
DeleteSession(const int32_t userId)338 void SessionCoordinator::DeleteSession(const int32_t userId)
339 {
340     if (remoteVideoCallbacksMap_.count(userId) != 0) {
341         DP_INFO_LOG("delete session userId: %{public}d", userId);
342         remoteVideoCallbacksMap_.erase(userId);
343     }
344 }
345 
OnVideoProcessDone(const int32_t userId,const std::string & videoId,const sptr<IPCFileDescriptor> & ipcFd)346 void SessionCoordinator::OnVideoProcessDone(const int32_t userId, const std::string& videoId,
347     const sptr<IPCFileDescriptor> &ipcFd)
348 {
349     DP_INFO_LOG("userId: %{public}d, map size: %{public}d.",
350         userId, static_cast<int32_t>(remoteVideoCallbacksMap_.size()));
351     auto iter = remoteVideoCallbacksMap_.find(userId);
352     if (iter != remoteVideoCallbacksMap_.end()) {
353         auto spCallback = iter->second.promote();
354         DP_CHECK_ERROR_RETURN_LOG(spCallback == nullptr, "OnVideoProcessDone callback is nullptr.");
355         DP_INFO_LOG("videoId: %{public}s", videoId.c_str());
356         spCallback->OnProcessVideoDone(videoId, ipcFd);
357     } else {
358         DP_INFO_LOG("callback is null, videoId: %{public}s.", videoId.c_str());
359     }
360 }
361 
OnVideoError(const int32_t userId,const std::string & videoId,DpsError errorCode)362 void SessionCoordinator::OnVideoError(const int32_t userId, const std::string& videoId, DpsError errorCode)
363 {
364     DP_INFO_LOG("userId: %{public}d, map size: %{public}d.",
365         userId, static_cast<int32_t>(remoteVideoCallbacksMap_.size()));
366     auto iter = remoteVideoCallbacksMap_.find(userId);
367     if (iter != remoteVideoCallbacksMap_.end()) {
368         auto spCallback = iter->second.promote();
369         DP_CHECK_ERROR_RETURN_LOG(spCallback == nullptr, "OnVideoError callback is nullptr.");
370         auto error = MapDpsErrorCode(errorCode);
371         DP_INFO_LOG("videoId: %{public}s, error: %{public}d", videoId.c_str(), error);
372         spCallback->OnError(videoId, error);
373     } else {
374         DP_INFO_LOG("callback is null, videoId: %{public}s, errorCode: %{public}d.",
375             videoId.c_str(), errorCode);
376     }
377 }
378 
OnVideoStateChanged(const int32_t userId,DpsStatus statusCode)379 void SessionCoordinator::OnVideoStateChanged(const int32_t userId, DpsStatus statusCode)
380 {
381     DP_DEBUG_LOG("entered.");
382 }
383 
ProcessVideoResults(sptr<IDeferredVideoProcessingSessionCallback> callback)384 void SessionCoordinator::ProcessVideoResults(sptr<IDeferredVideoProcessingSessionCallback> callback)
385 {
386     DP_DEBUG_LOG("entered.");
387     while (!pendingRequestResults_.empty()) {
388         auto result = pendingRequestResults_.front();
389         if (result.callbackType == CallbackType::ON_PROCESS_DONE) {
390             callback->OnProcessVideoDone(result.requestId, result.ipcFd);
391         }
392         if (result.callbackType == CallbackType::ON_ERROR) {
393             callback->OnError(result.requestId, MapDpsErrorCode(result.errorCode));
394         }
395         if (result.callbackType == CallbackType::ON_STATE_CHANGED) {
396             callback->OnStateChanged(MapDpsStatus(result.statusCode));
397         }
398         pendingRequestResults_.pop_back();
399     }
400 }
401 } // namespace DeferredProcessing
402 } // namespace CameraStandard
403 } // namespace OHOS