1 /*
2  * Copyright (c) 2021-2024 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 "output/photo_output_napi.h"
17 
18 #include <cstddef>
19 #include <cstdint>
20 #include <memory>
21 #include <mutex>
22 #include <string>
23 #include <unistd.h>
24 #include <unordered_set>
25 #include <uv.h>
26 
27 #include "buffer_extra_data_impl.h"
28 #include "camera_buffer_handle_utils.h"
29 #include "camera_error_code.h"
30 #include "camera_log.h"
31 #include "camera_manager.h"
32 #include "camera_napi_const.h"
33 #include "camera_napi_object_types.h"
34 #include "camera_napi_param_parser.h"
35 #include "camera_napi_security_utils.h"
36 #include "camera_napi_template_utils.h"
37 #include "camera_napi_utils.h"
38 #include "camera_napi_worker_queue_keeper.h"
39 #include "camera_output_capability.h"
40 #include "camera_photo_proxy.h"
41 #include "camera_util.h"
42 #include "dp_utils.h"
43 #include "image_napi.h"
44 #include "image_packer.h"
45 #include "image_receiver.h"
46 #include "ipc_skeleton.h"
47 #include "js_native_api.h"
48 #include "js_native_api_types.h"
49 #include "listener_base.h"
50 #include "media_library_comm_napi.h"
51 #include "media_library_manager.h"
52 #include "output/deferred_photo_proxy_napi.h"
53 #include "output/photo_napi.h"
54 #include "output/photo_output_napi.h"
55 #include "photo_output.h"
56 #include "pixel_map_napi.h"
57 #include "picture.h"
58 #include "refbase.h"
59 #include "securec.h"
60 #include "task_manager.h"
61 #include "video_key_info.h"
62 #include "camera_dynamic_loader.h"
63 
64 namespace OHOS {
65 namespace CameraStandard {
66 using namespace std;
67 namespace {
AsyncCompleteCallback(napi_env env,napi_status status,void * data)68 void AsyncCompleteCallback(napi_env env, napi_status status, void* data)
69 {
70     auto context = static_cast<PhotoOutputAsyncContext*>(data);
71     CHECK_ERROR_RETURN_LOG(context == nullptr, "CameraInputNapi AsyncCompleteCallback context is null");
72     MEDIA_INFO_LOG("CameraInputNapi AsyncCompleteCallback %{public}s, status = %{public}d", context->funcName.c_str(),
73         context->status);
74     std::unique_ptr<JSAsyncContextOutput> jsContext = std::make_unique<JSAsyncContextOutput>();
75     jsContext->status = context->status;
76 
77     if (!context->status) {
78         CameraNapiUtils::CreateNapiErrorObject(env, context->errorCode, context->errorMsg.c_str(), jsContext);
79     } else {
80         napi_get_undefined(env, &jsContext->data);
81     }
82     if (!context->funcName.empty() && context->taskId > 0) {
83         // Finish async trace
84         CAMERA_FINISH_ASYNC_TRACE(context->funcName, context->taskId);
85         jsContext->funcName = context->funcName;
86     }
87     if (context->work != nullptr) {
88         CameraNapiUtils::InvokeJSAsyncMethod(env, context->deferred, context->callbackRef, context->work, *jsContext);
89     }
90     context->FreeHeldNapiValue(env);
91     delete context;
92 }
93 
ProcessCapture(PhotoOutputAsyncContext * context,bool isBurst)94 void ProcessCapture(PhotoOutputAsyncContext* context, bool isBurst)
95 {
96     context->status = true;
97     sptr<PhotoOutput> photoOutput = context->objectInfo->GetPhotoOutput();
98     MEDIA_INFO_LOG("PhotoOutputAsyncContext objectInfo GetEnableMirror is %{public}d",
99         context->objectInfo->GetEnableMirror());
100     if (context->hasPhotoSettings) {
101         std::shared_ptr<PhotoCaptureSetting> capSettings = make_shared<PhotoCaptureSetting>();
102         if (context->quality != -1) {
103             capSettings->SetQuality(static_cast<PhotoCaptureSetting::QualityLevel>(context->quality));
104         }
105         if (context->rotation != -1) {
106             capSettings->SetRotation(static_cast<PhotoCaptureSetting::RotationConfig>(context->rotation));
107         }
108         if (!context->isMirrorSettedByUser) {
109             capSettings->SetMirror(context->objectInfo->GetEnableMirror());
110         } else {
111             capSettings->SetMirror(context->isMirror);
112         }
113         if (context->location != nullptr) {
114             capSettings->SetLocation(context->location);
115         }
116         if (isBurst) {
117             MEDIA_ERR_LOG("ProcessContext BurstCapture");
118             uint8_t burstState = 1; // 0:end 1:start
119             capSettings->SetBurstCaptureState(burstState);
120         }
121         context->errorCode = photoOutput->Capture(capSettings);
122     } else {
123         std::shared_ptr<PhotoCaptureSetting> capSettings = make_shared<PhotoCaptureSetting>();
124         capSettings->SetMirror(context->objectInfo->GetEnableMirror());
125         context->errorCode = photoOutput->Capture(capSettings);
126     }
127     context->status = context->errorCode == 0;
128 }
129 
ValidQualityLevelFromJs(int32_t jsQuality)130 bool ValidQualityLevelFromJs(int32_t jsQuality)
131 {
132     MEDIA_INFO_LOG("PhotoOutputNapi::ValidQualityLevelFromJs quality level = %{public}d", jsQuality);
133     switch (jsQuality) {
134         case QUALITY_LEVEL_HIGH:
135         // Fallthrough
136         case QUALITY_LEVEL_MEDIUM:
137         // Fallthrough
138         case QUALITY_LEVEL_LOW:
139             return true;
140         default:
141             MEDIA_ERR_LOG("Invalid quality value received from application");
142             return false;
143     }
144     return false;
145 }
146 
ValidImageRotationFromJs(int32_t jsRotation)147 bool ValidImageRotationFromJs(int32_t jsRotation)
148 {
149     MEDIA_INFO_LOG("js rotation = %{public}d", jsRotation);
150     switch (jsRotation) {
151         case ROTATION_0:
152             // Fallthrough
153         case ROTATION_90:
154             // Fallthrough
155         case ROTATION_180:
156             // Fallthrough
157         case ROTATION_270:
158             return true;
159         default:
160             MEDIA_ERR_LOG("Invalid rotation value received from application");
161             return false;
162     }
163     return false;
164 }
165 } // namespace
166 
167 thread_local napi_ref PhotoOutputNapi::sConstructor_ = nullptr;
168 thread_local sptr<PhotoOutput> PhotoOutputNapi::sPhotoOutput_ = nullptr;
169 thread_local sptr<Surface> PhotoOutputNapi::sPhotoSurface_ = nullptr;
170 thread_local uint32_t PhotoOutputNapi::photoOutputTaskId = CAMERA_PHOTO_OUTPUT_TASKID;
171 thread_local napi_ref PhotoOutputNapi::rawCallback_ = nullptr;
172 static uv_sem_t g_captureStartSem;
173 static bool g_isSemInited;
174 static std::mutex g_photoImageMutex;
175 static std::mutex g_assembleImageMutex;
176 static int32_t g_captureId;
177 
PhotoListener(napi_env env,const sptr<Surface> photoSurface,wptr<PhotoOutput> photoOutput)178 PhotoListener::PhotoListener(napi_env env, const sptr<Surface> photoSurface, wptr<PhotoOutput> photoOutput)
179     : ListenerBase(env), photoSurface_(photoSurface), photoOutput_(photoOutput)
180 {
181     if (bufferProcessor_ == nullptr && photoSurface != nullptr) {
182         bufferProcessor_ = std::make_shared<PhotoBufferProcessor>(photoSurface);
183     }
184     if (taskManager_ == nullptr) {
185         constexpr int32_t numThreads = 1;
186         taskManager_ = std::make_shared<DeferredProcessing::TaskManager>("PhotoListener",
187             numThreads, false);
188     }
189 }
~PhotoListener()190 PhotoListener::~PhotoListener()
191 {
192     if (taskManager_) {
193         taskManager_->CancelAllTasks();
194         taskManager_.reset();
195         taskManager_ = nullptr;
196     }
197 }
RawPhotoListener(napi_env env,const sptr<Surface> rawPhotoSurface)198 RawPhotoListener::RawPhotoListener(napi_env env, const sptr<Surface> rawPhotoSurface)
199     : ListenerBase(env), rawPhotoSurface_(rawPhotoSurface)
200 {
201     if (bufferProcessor_ == nullptr && rawPhotoSurface != nullptr) {
202         bufferProcessor_ = std::make_shared<PhotoBufferProcessor>(rawPhotoSurface);
203     }
204 }
205 
AuxiliaryPhotoListener(const std::string surfaceName,const sptr<Surface> surface,wptr<PhotoOutput> photoOutput)206 AuxiliaryPhotoListener::AuxiliaryPhotoListener(const std::string surfaceName, const sptr<Surface> surface,
207     wptr<PhotoOutput> photoOutput) : surfaceName_(surfaceName), surface_(surface), photoOutput_(photoOutput)
208 {
209     if (bufferProcessor_ == nullptr && surface != nullptr) {
210         bufferProcessor_ = std::make_shared<PhotoBufferProcessor>(surface);
211     }
212 }
213 
GetCaptureId(sptr<SurfaceBuffer> surfaceBuffer)214 int32_t GetCaptureId(sptr<SurfaceBuffer> surfaceBuffer)
215 {
216     int32_t captureId;
217     int32_t burstSeqId = -1;
218     int32_t maskBurstSeqId = 0;
219     int32_t invalidSeqenceId = -1;
220     int32_t captureIdMask = 0x0000FFFF;
221     int32_t captureIdShit = 16;
222     surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::burstSequenceId, burstSeqId);
223     surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::captureId, captureId);
224     if (burstSeqId != invalidSeqenceId && captureId >= 0) {
225         maskBurstSeqId = ((captureId & captureIdMask) << captureIdShit) | burstSeqId;
226         MEDIA_INFO_LOG("PhotoListener captureId:%{public}d, burstSeqId:%{public}d, maskBurstSeqId = %{public}d",
227             captureId, burstSeqId, maskBurstSeqId);
228         return maskBurstSeqId;
229     }
230     MEDIA_INFO_LOG("PhotoListener captureId:%{public}d, burstSeqId:%{public}d", captureId, burstSeqId);
231     return captureId;
232 }
233 
InitPictureListeners(napi_env env,wptr<PhotoOutput> photoOutput)234 void PictureListener::InitPictureListeners(napi_env env, wptr<PhotoOutput> photoOutput)
235 {
236     if (photoOutput == nullptr) {
237         MEDIA_ERR_LOG("photoOutput is null");
238         return;
239     }
240     SurfaceError ret;
241     string retStr = "";
242     std::string surfaceName = "";
243     if (photoOutput->gainmapSurface_ != nullptr) {
244         surfaceName = CONST_GAINMAP_SURFACE;
245         gainmapImageListener = new (std::nothrow) AuxiliaryPhotoListener(surfaceName, photoOutput->gainmapSurface_,
246             photoOutput);
247         ret = photoOutput->gainmapSurface_->RegisterConsumerListener(
248             (sptr<IBufferConsumerListener>&)gainmapImageListener);
249         retStr = ret != SURFACE_ERROR_OK ? retStr + "[gainmap]" : retStr;
250     }
251     if (photoOutput->deepSurface_ != nullptr) {
252         surfaceName = CONST_DEEP_SURFACE;
253         deepImageListener = new (std::nothrow) AuxiliaryPhotoListener(surfaceName, photoOutput->deepSurface_,
254             photoOutput);
255         ret = photoOutput->deepSurface_->RegisterConsumerListener(
256             (sptr<IBufferConsumerListener>&)deepImageListener);
257         retStr = ret != SURFACE_ERROR_OK ? retStr + "[deep]" : retStr;
258     }
259     if (photoOutput->exifSurface_ != nullptr) {
260         surfaceName = CONST_EXIF_SURFACE;
261         exifImageListener = new (std::nothrow) AuxiliaryPhotoListener(surfaceName, photoOutput->exifSurface_,
262             photoOutput);
263         ret = photoOutput->exifSurface_->RegisterConsumerListener(
264             (sptr<IBufferConsumerListener>&)exifImageListener);
265         retStr = ret != SURFACE_ERROR_OK ? retStr + "[exif]" : retStr;
266     }
267     if (photoOutput->debugSurface_ != nullptr) {
268         surfaceName = CONST_DEBUG_SURFACE;
269         debugImageListener = new (std::nothrow) AuxiliaryPhotoListener(surfaceName, photoOutput->debugSurface_,
270             photoOutput);
271         ret = photoOutput->debugSurface_->RegisterConsumerListener(
272             (sptr<IBufferConsumerListener>&)debugImageListener);
273         retStr = ret != SURFACE_ERROR_OK ? retStr + "[debug]" : retStr;
274     }
275     if (retStr != "") {
276         MEDIA_ERR_LOG("register surface consumer listener failed! type = %{public}s", retStr.c_str());
277     }
278 }
279 
DeepCopyBuffer(sptr<SurfaceBuffer> newSurfaceBuffer,sptr<SurfaceBuffer> surfaceBuffer,int32_t captureId) const280 void AuxiliaryPhotoListener::DeepCopyBuffer(
281     sptr<SurfaceBuffer> newSurfaceBuffer, sptr<SurfaceBuffer> surfaceBuffer, int32_t  captureId) const
282 {
283     MEDIA_DEBUG_LOG("AuxiliaryPhotoListener::DeepCopyBuffer w=%{public}d, h=%{public}d, f=%{public}d "
284         "surfaceName=%{public}s captureId = %{public}d", surfaceBuffer->GetWidth(), surfaceBuffer->GetHeight(),
285         surfaceBuffer->GetFormat(), surfaceName_.c_str(), captureId);
286     BufferRequestConfig requestConfig = {
287         .width = surfaceBuffer->GetWidth(),
288         .height = surfaceBuffer->GetHeight(),
289         .strideAlignment = 0x8, // default stride is 8 Bytes.
290         .format = surfaceBuffer->GetFormat(),
291         .usage = surfaceBuffer->GetUsage(),
292         .timeout = 0,
293         .colorGamut = surfaceBuffer->GetSurfaceBufferColorGamut(),
294         .transform = surfaceBuffer->GetSurfaceBufferTransform(),
295     };
296     auto allocErrorCode = newSurfaceBuffer->Alloc(requestConfig);
297     MEDIA_DEBUG_LOG("AuxiliaryPhotoListener::DeepCopyBuffer SurfaceBuffer alloc ret: %{public}d surfaceName=%{public}s "
298         "captureId = %{public}d", allocErrorCode, surfaceName_.c_str(), captureId);
299     if (memcpy_s(newSurfaceBuffer->GetVirAddr(), newSurfaceBuffer->GetSize(),
300         surfaceBuffer->GetVirAddr(), surfaceBuffer->GetSize()) != EOK) {
301         MEDIA_ERR_LOG("PhotoListener memcpy_s failed");
302     }
303     MEDIA_DEBUG_LOG("AuxiliaryPhotoListener::DeepCopyBuffer memcpy end surfaceName=%{public}s captureId = %{public}d",
304         surfaceName_.c_str(), captureId);
305 }
306 
ExecuteDeepCopySurfaceBuffer()307 void AuxiliaryPhotoListener::ExecuteDeepCopySurfaceBuffer() __attribute__((no_sanitize("cfi")))
308 {
309     MEDIA_INFO_LOG("AssembleAuxiliaryPhoto ExecuteDeepCopySurfaceBuffer surfaceName = %{public}s",
310         surfaceName_.c_str());
311     sptr<SurfaceBuffer> surfaceBuffer = nullptr;
312     int32_t fence = -1;
313     int64_t timestamp;
314     OHOS::Rect damage;
315     MEDIA_INFO_LOG("AssembleAuxiliaryPhoto surfaceName = %{public}s AcquireBuffer before", surfaceName_.c_str());
316     SurfaceError surfaceRet = surface_->AcquireBuffer(surfaceBuffer, fence, timestamp, damage);
317     MEDIA_INFO_LOG("AssembleAuxiliaryPhoto surfaceName = %{public}s AcquireBuffer end", surfaceName_.c_str());
318     if (surfaceRet != SURFACE_ERROR_OK) {
319         MEDIA_ERR_LOG("AuxiliaryPhotoListener Failed to acquire surface buffer");
320         return;
321     }
322     int32_t captureId = GetCaptureId(surfaceBuffer);
323     int32_t dataSize = 0;
324     surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::dataSize, dataSize);
325     // deep copy buffer
326     sptr<SurfaceBuffer> newSurfaceBuffer = SurfaceBuffer::Create();
327     DeepCopyBuffer(newSurfaceBuffer, surfaceBuffer, captureId);
328     MEDIA_INFO_LOG("AuxiliaryPhotoListener surfaceName_ = %{public}s w=%{public}d, h=%{public}d, f=%{public}d"
329                    "captureId=%{public}d", surfaceName_.c_str(), newSurfaceBuffer->GetWidth(),
330                    newSurfaceBuffer->GetHeight(), newSurfaceBuffer->GetFormat(), captureId);
331     MEDIA_INFO_LOG("AssembleAuxiliaryPhoto surfaceName = %{public}s ReleaseBuffer captureId=%{public}d, before",
332         surfaceName_.c_str(), captureId);
333     surface_->ReleaseBuffer(surfaceBuffer, -1);
334     MEDIA_INFO_LOG("AssembleAuxiliaryPhoto surfaceName = %{public}s ReleaseBuffer captureId=%{public}d, end",
335         surfaceName_.c_str(), captureId);
336 
337     BufferHandle* bufferHandle = newSurfaceBuffer->GetBufferHandle();
338     if (bufferHandle == nullptr) {
339         MEDIA_ERR_LOG("invalid bufferHandle");
340         return;
341     }
342     MEDIA_INFO_LOG("AssembleAuxiliaryPhoto surfaceName = %{public}s Map captureId=%{public}d, before",
343         surfaceName_.c_str(), captureId);
344     newSurfaceBuffer->Map();
345     MEDIA_INFO_LOG("AssembleAuxiliaryPhoto surfaceName = %{public}s Map captureId=%{public}d, end",
346         surfaceName_.c_str(), captureId);
347     if (surfaceName_ == CONST_EXIF_SURFACE) {
348         sptr<BufferExtraData> extraData = new BufferExtraDataImpl();
349         extraData->ExtraSet("exifDataSize", dataSize);
350         newSurfaceBuffer->SetExtraData(extraData);
351         MEDIA_INFO_LOG("AuxiliaryPhotoListener exifDataSize = %{public}d", dataSize);
352     }
353     {
354         std::lock_guard<std::mutex> lock(g_photoImageMutex);
355         auto photoOutput = photoOutput_.promote();
356         if (photoOutput == nullptr) {
357             MEDIA_ERR_LOG("AuxiliaryPhotoListener ExecuteDeepCopySurfaceBuffer photoOutput is nullptr");
358             return;
359         }
360         if (photoOutput->captureIdAuxiliaryCountMap_.count(captureId)) {
361             int32_t auxiliaryCount = photoOutput->captureIdAuxiliaryCountMap_[captureId];
362             int32_t expectCount = photoOutput->captureIdCountMap_[captureId];
363             if (auxiliaryCount == -1 || (expectCount != 0 && auxiliaryCount == expectCount)) {
364                 MEDIA_INFO_LOG("AuxiliaryPhotoListener ReleaseBuffer, captureId=%{public}d", captureId);
365                 return;
366             }
367         }
368         photoOutput->captureIdAuxiliaryCountMap_[captureId]++;
369         switch (SurfaceTypeHelper.ToEnum(surfaceName_)) {
370             case SurfaceType::GAINMAP_SURFACE: {
371                     photoOutput->captureIdGainmapMap_[captureId] = newSurfaceBuffer;
372                     MEDIA_INFO_LOG("AuxiliaryPhotoListener gainmapSurfaceBuffer_, captureId=%{public}d", captureId);
373                 } break;
374             case SurfaceType::DEEP_SURFACE: {
375                     photoOutput->captureIdDepthMap_[captureId] = newSurfaceBuffer;
376                     MEDIA_INFO_LOG("AuxiliaryPhotoListener deepSurfaceBuffer_, captureId=%{public}d", captureId);
377                 } break;
378             case SurfaceType::EXIF_SURFACE: {
379                     photoOutput->captureIdExifMap_[captureId] = newSurfaceBuffer;
380                     MEDIA_INFO_LOG("AuxiliaryPhotoListener exifSurfaceBuffer_, captureId=%{public}d", captureId);
381                 } break;
382             case SurfaceType::DEBUG_SURFACE: {
383                     photoOutput->captureIdDebugMap_[captureId] = newSurfaceBuffer;
384                     MEDIA_INFO_LOG("AuxiliaryPhotoListener debugSurfaceBuffer_, captureId=%{public}d", captureId);
385                 } break;
386             default:
387                 break;
388         }
389         MEDIA_INFO_LOG("AuxiliaryPhotoListener auxiliaryPhotoCount = %{public}d, captureCount = %{public}d, "
390                        "surfaceName=%{public}s, captureId=%{public}d",
391             photoOutput->captureIdAuxiliaryCountMap_[captureId], photoOutput->captureIdCountMap_[captureId],
392             surfaceName_.c_str(), captureId);
393         if (photoOutput->captureIdCountMap_[captureId] != 0 &&
394             photoOutput->captureIdAuxiliaryCountMap_[captureId] == photoOutput->captureIdCountMap_[captureId]) {
395             uint32_t handle = photoOutput->captureIdHandleMap_[captureId];
396             MEDIA_INFO_LOG("AuxiliaryPhotoListener StopMonitor, surfaceName=%{public}s, handle = %{public}d, "
397                            "captureId = %{public}d",
398                 surfaceName_.c_str(), handle, captureId);
399             DeferredProcessing::GetGlobalWatchdog().DoTimeout(handle);
400             DeferredProcessing::GetGlobalWatchdog().StopMonitor(handle);
401             photoOutput->captureIdAuxiliaryCountMap_[captureId] = -1;
402             MEDIA_INFO_LOG("AuxiliaryPhotoListener captureIdAuxiliaryCountMap_ = -1");
403         }
404         MEDIA_INFO_LOG("AuxiliaryPhotoListener auxiliaryPhotoCount = %{public}d, captureCount = %{public}d, "
405                        "surfaceName=%{public}s, captureId=%{public}d",
406             photoOutput->captureIdAuxiliaryCountMap_[captureId], photoOutput->captureIdCountMap_[captureId],
407             surfaceName_.c_str(), captureId);
408     }
409 }
410 
OnBufferAvailable()411 void AuxiliaryPhotoListener::OnBufferAvailable()
412 {
413     CAMERA_SYNC_TRACE;
414     MEDIA_INFO_LOG("AuxiliaryPhotoListener::OnBufferAvailable is called, surfaceName=%{public}s", surfaceName_.c_str());
415     if (!surface_) {
416         MEDIA_ERR_LOG("AuxiliaryPhotoListener napi photoSurface_ is null");
417         return;
418     }
419     auto photoOutput = photoOutput_.promote();
420     if (photoOutput && photoOutput->taskManager_) {
421         wptr<AuxiliaryPhotoListener> thisPtr(this);
422         photoOutput->taskManager_->SubmitTask([thisPtr]() {
423             auto listener = thisPtr.promote();
424             if (listener) {
425                 listener->ExecuteDeepCopySurfaceBuffer();
426             }
427         });
428     }
429     MEDIA_INFO_LOG("AuxiliaryPhotoListener::OnBufferAvailable is end, surfaceName=%{public}s", surfaceName_.c_str());
430 }
431 
GetAuxiliaryPhotoCount(sptr<SurfaceBuffer> surfaceBuffer)432 int32_t PhotoListener::GetAuxiliaryPhotoCount(sptr<SurfaceBuffer> surfaceBuffer)
433 {
434     int32_t auxiliaryCount;
435     surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::imageCount, auxiliaryCount);
436     MEDIA_INFO_LOG("PhotoListener auxiliaryCount:%{public}d", auxiliaryCount);
437     return auxiliaryCount;
438 }
439 
CreateCameraPhotoProxy(sptr<SurfaceBuffer> surfaceBuffer)440 sptr<CameraPhotoProxy> PhotoListener::CreateCameraPhotoProxy(sptr<SurfaceBuffer> surfaceBuffer)
441 {
442     int32_t isDegradedImage;
443     surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::isDegradedImage, isDegradedImage);
444     MEDIA_INFO_LOG("PhotoListener CreateCameraPhotoProxy isDegradedImage:%{public}d", isDegradedImage);
445     int64_t imageId = 0;
446     int32_t deferredProcessingType;
447     int32_t captureId;
448     int32_t burstSeqId = -1;
449     surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::imageId, imageId);
450     surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::deferredProcessingType, deferredProcessingType);
451     surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::captureId, captureId);
452     // When not in burst mode, burstSequenceId is invalid (-1); otherwise,
453     // it is an incrementing serial number starting from 1
454     surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::burstSequenceId, burstSeqId);
455     MEDIA_INFO_LOG("PhotoListener CreateCameraPhotoProxy imageId:%{public}" PRId64 ", "
456         "deferredProcessingType:%{public}d, captureId = %{public}d, burstSeqId = %{public}d",
457         imageId, deferredProcessingType, captureId, burstSeqId);
458     // get buffer handle and photo info
459     int32_t photoWidth;
460     int32_t photoHeight;
461     surfaceBuffer->GetExtraData()->ExtraGet(OHOS::CameraStandard::dataWidth, photoWidth);
462     surfaceBuffer->GetExtraData()->ExtraGet(OHOS::CameraStandard::dataHeight, photoHeight);
463     uint64_t size = static_cast<uint64_t>(surfaceBuffer->GetSize());
464     int32_t extraDataSize = 0;
465     auto res = surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::dataSize, extraDataSize);
466     if (res != 0) {
467         MEDIA_INFO_LOG("ExtraGet dataSize error %{public}d", res);
468     } else if (extraDataSize <= 0) {
469         MEDIA_INFO_LOG("ExtraGet dataSize Ok, but size <= 0");
470     } else if (static_cast<uint64_t>(extraDataSize) > size) {
471         MEDIA_INFO_LOG("ExtraGet dataSize Ok,but dataSize %{public}d is bigger than bufferSize %{public}" PRIu64,
472             extraDataSize, size);
473     } else {
474         MEDIA_INFO_LOG("ExtraGet dataSize %{public}d", extraDataSize);
475         size = static_cast<uint64_t>(extraDataSize);
476     }
477     int32_t deferredImageFormat = 0;
478     res = surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::deferredImageFormat, deferredImageFormat);
479     bool isHighQuality = (isDegradedImage == 0);
480     MEDIA_INFO_LOG("PhotoListener CreateCameraPhotoProxy deferredImageFormat:%{public}d, isHighQuality = %{public}d, "
481         "size:%{public}" PRId64, deferredImageFormat, isHighQuality, size);
482     sptr<CameraPhotoProxy> photoProxy = new(std::nothrow) CameraPhotoProxy(
483         nullptr, deferredImageFormat, photoWidth, photoHeight, isHighQuality, captureId, burstSeqId);
484     std::string imageIdStr = std::to_string(imageId);
485     photoProxy->SetDeferredAttrs(imageIdStr, deferredProcessingType, size, deferredImageFormat);
486     return photoProxy;
487 }
488 
ExecuteDeepCopySurfaceBuffer()489 void PhotoListener::ExecuteDeepCopySurfaceBuffer() __attribute__((no_sanitize("cfi")))
490 {
491     sptr<SurfaceBuffer> surfaceBuffer = nullptr;
492     sptr<SurfaceBuffer> newSurfaceBuffer = nullptr;
493     sptr<CameraPhotoProxy> photoProxy = nullptr;
494     int32_t auxiliaryCount = 0;
495     int32_t captureId = -1;
496     int32_t fence = -1;
497     int64_t timestamp;
498     OHOS::Rect damage;
499     SurfaceError surfaceRet = photoSurface_->AcquireBuffer(surfaceBuffer, fence, timestamp, damage);
500     MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto 0");
501     if (surfaceRet != SURFACE_ERROR_OK) {
502         MEDIA_ERR_LOG("PhotoListener Failed to acquire surface buffer");
503         return;
504     }
505     auxiliaryCount = GetAuxiliaryPhotoCount(surfaceBuffer);
506     captureId = GetCaptureId(surfaceBuffer);
507     auto photoOutput = photoOutput_.promote();
508     if (photoOutput != nullptr) {
509         photoOutput->AcquireBufferToPrepareProxy(captureId);
510     }
511     // deep copy buffer
512     newSurfaceBuffer = SurfaceBuffer::Create();
513     MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto 1");
514     DeepCopyBuffer(newSurfaceBuffer, surfaceBuffer, captureId);
515     MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto 2");
516     photoSurface_->ReleaseBuffer(surfaceBuffer, -1);
517     {
518         std::lock_guard<std::mutex> lock(g_photoImageMutex);
519         if (!photoOutput) {
520             MEDIA_ERR_LOG("photoOutput is nullptr");
521             return;
522         }
523         MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto 3");
524         photoOutput->captureIdCountMap_[captureId] = auxiliaryCount;
525         photoOutput->captureIdAuxiliaryCountMap_[captureId]++;
526         MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto 4 captureId = %{public}d", captureId);
527         photoProxy = CreateCameraPhotoProxy(surfaceBuffer);
528         photoOutput->photoProxyMap_[captureId] = photoProxy;
529         MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto 5");
530         if (!photoProxy) {
531             MEDIA_ERR_LOG("photoProxy is nullptr");
532             return;
533         }
534         if (photoProxy->isHighQuality_ && (callbackFlag_ & CAPTURE_PHOTO) != 0) {
535             UpdateMainPictureStageOneJSCallback(surfaceBuffer, timestamp);
536             return;
537         }
538         BufferHandle* bufferHandle = newSurfaceBuffer->GetBufferHandle();
539         MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto 6");
540         if (bufferHandle == nullptr) {
541             MEDIA_ERR_LOG("invalid bufferHandle");
542             return;
543         }
544         MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto 7");
545         newSurfaceBuffer->Map();
546         MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto 8");
547         photoProxy->bufferHandle_ = bufferHandle;
548         std::unique_ptr<Media::Picture> picture = Media::Picture::Create(newSurfaceBuffer);
549         if (!picture) {
550             MEDIA_ERR_LOG("picture is nullptr");
551             return;
552         }
553         Media::ImageInfo imageInfo;
554         MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto MainSurface w=%{public}d, h=%{public}d, f=%{public}d",
555             newSurfaceBuffer->GetWidth(), newSurfaceBuffer->GetHeight(), newSurfaceBuffer->GetFormat());
556         photoOutput->captureIdPictureMap_[captureId] = std::move(picture);
557         uint32_t pictureHandle;
558         constexpr uint32_t delayMilli = 1 * 1000;
559         MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto GetGlobalWatchdog StartMonitor, captureId=%{public}d",
560             captureId);
561         DeferredProcessing::GetGlobalWatchdog().StartMonitor(pictureHandle, delayMilli,
562             [this, captureId, timestamp](uint32_t handle) {
563                 MEDIA_INFO_LOG("PhotoListener PhotoListener-Watchdog executed, handle: %{public}d, "
564                     "captureId=%{public}d", static_cast<int>(handle), captureId);
565                 AssembleAuxiliaryPhoto(timestamp, captureId);
566                 auto photoOutput = photoOutput_.promote();
567                 if (photoOutput && photoOutput->captureIdAuxiliaryCountMap_.count(captureId)) {
568                     photoOutput->captureIdAuxiliaryCountMap_[captureId] = -1;
569                     MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto captureIdAuxiliaryCountMap_ = -1, "
570                         "captureId=%{public}d", captureId);
571                 }
572         });
573         photoOutput->captureIdHandleMap_[captureId] = pictureHandle;
574         MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto, pictureHandle: %{public}d, captureId=%{public}d "
575             "captureIdCountMap = %{public}d, captureIdAuxiliaryCountMap = %{public}d",
576             pictureHandle, captureId, photoOutput->captureIdCountMap_[captureId],
577             photoOutput->captureIdAuxiliaryCountMap_[captureId]);
578         if (photoOutput->captureIdCountMap_[captureId] != 0 &&
579             photoOutput->captureIdAuxiliaryCountMap_[captureId] == photoOutput->captureIdCountMap_[captureId]) {
580             MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto auxiliaryCount is complete, StopMonitor DoTimeout "
581                 "handle = %{public}d, captureId = %{public}d", pictureHandle, captureId);
582             DeferredProcessing::GetGlobalWatchdog().DoTimeout(pictureHandle);
583             DeferredProcessing::GetGlobalWatchdog().StopMonitor(pictureHandle);
584         }
585         MEDIA_INFO_LOG("PhotoListener AssembleAuxiliaryPhoto end");
586     }
587 }
588 
OnBufferAvailable()589 void PhotoListener::OnBufferAvailable()
590 {
591     CAMERA_SYNC_TRACE;
592     MEDIA_INFO_LOG("PhotoListener::OnBufferAvailable is called");
593     auto photoOutput = photoOutput_.promote();
594     if (photoSurface_ == nullptr || photoOutput == nullptr) {
595         MEDIA_ERR_LOG("PhotoListener::OnBufferAvailable photoSurface or photoOutput is null");
596         return;
597     }
598     if (!photoOutput->IsYuvOrHeifPhoto()) {
599         UpdateJSCallbackAsync(photoSurface_);
600         MEDIA_INFO_LOG("PhotoListener::OnBufferAvailable is end");
601         return;
602     }
603     if (taskManager_ == nullptr) {
604         MEDIA_ERR_LOG("PhotoListener::OnBufferAvailable taskManager_ is null");
605         return;
606     }
607     wptr<PhotoListener> thisPtr(this);
608     taskManager_->SubmitTask([thisPtr]() {
609         auto listener = thisPtr.promote();
610         if (listener) {
611             listener->ExecuteDeepCopySurfaceBuffer();
612         }
613     });
614     MEDIA_INFO_LOG("PhotoListener::OnBufferAvailable is end");
615 }
616 
FillNapiObjectWithCaptureId(napi_env env,int32_t captureId,napi_value & photoAsset)617 void FillNapiObjectWithCaptureId(napi_env env, int32_t captureId, napi_value &photoAsset)
618 {
619     napi_valuetype valueType = napi_undefined;
620     if (napi_typeof(env, photoAsset, &valueType) != napi_ok || valueType == napi_undefined) {
621         MEDIA_ERR_LOG("FillNapiObjectWithCaptureId err, photoAsset is undefined = %{public}d",
622             valueType == napi_undefined);
623         return;
624     }
625     napi_value propertyName, propertyValue;
626     napi_get_undefined(env, &propertyName);
627     napi_get_undefined(env, &propertyValue);
628     napi_create_string_utf8(env, "captureId", NAPI_AUTO_LENGTH, &propertyName);
629     napi_create_int32(env, captureId, &propertyValue);
630     napi_set_property(env, photoAsset, propertyName, propertyValue);
631     MEDIA_INFO_LOG("FillNapiObjectWithCaptureId captureId %{public}d", captureId);
632 }
633 
UpdatePictureJSCallback(int32_t captureId,const string uri,int32_t cameraShotType,const std::string burstKey) const634 void PhotoListener::UpdatePictureJSCallback(int32_t captureId, const string uri, int32_t cameraShotType,
635     const std::string burstKey) const
636 {
637     MEDIA_INFO_LOG("PhotoListener:UpdatePictureJSCallback called");
638     uv_loop_s* loop = nullptr;
639     napi_get_uv_event_loop(env_, &loop);
640     CHECK_ERROR_RETURN_LOG(loop == nullptr, "PhotoListenerInfo UpdateJSCallbackAsync failed to get event loop");
641     uv_work_t* work = new (std::nothrow) uv_work_t;
642     CHECK_ERROR_RETURN_LOG(work == nullptr, "PhotoListenerInfo UpdateJSCallbackAsync failed to allocate work");
643     std::unique_ptr<PhotoListenerInfo> callbackInfo = std::make_unique<PhotoListenerInfo>(nullptr, this);
644     callbackInfo->captureId = captureId;
645     callbackInfo->uri = uri;
646     callbackInfo->cameraShotType = cameraShotType;
647     callbackInfo->burstKey = burstKey;
648     work->data = callbackInfo.get();
649     int ret = uv_queue_work_with_qos(
650         loop, work, [](uv_work_t* work) {},
651         [](uv_work_t* work, int status) {
652             MEDIA_INFO_LOG("UpdatePictureJSCallback enter");
653             PhotoListenerInfo* callbackInfo = reinterpret_cast<PhotoListenerInfo*>(work->data);
654             if (callbackInfo && callbackInfo->listener_) {
655                 napi_value result[ARGS_TWO] = { nullptr, nullptr };
656                 napi_value retVal;
657                 napi_get_undefined(callbackInfo->listener_->env_, &result[PARAM0]);
658                 napi_get_undefined(callbackInfo->listener_->env_, &result[PARAM1]);
659                 napi_value photoAsset = Media::MediaLibraryCommNapi::CreatePhotoAssetNapi(callbackInfo->listener_->env_,
660                     callbackInfo->uri, callbackInfo->cameraShotType, callbackInfo->burstKey);
661                 if (photoAsset == nullptr) {
662                     napi_get_undefined(callbackInfo->listener_->env_, &photoAsset);
663                 }
664                 FillNapiObjectWithCaptureId(callbackInfo->listener_->env_, callbackInfo->captureId, photoAsset);
665                 result[PARAM1] = photoAsset;
666                 MEDIA_INFO_LOG("UpdatePictureJSCallback result %{public}s, type %{public}d, burstKey %{public}s",
667                     callbackInfo->uri.c_str(), callbackInfo->cameraShotType, callbackInfo->burstKey.c_str());
668                 ExecuteCallbackNapiPara callbackPara {
669                     .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
670                 callbackInfo->listener_->ExecuteCallback(CONST_CAPTURE_PHOTO_ASSET_AVAILABLE, callbackPara);
671                 MEDIA_INFO_LOG("PhotoListener:UpdateJSCallbackAsync() complete");
672                 callbackInfo->listener_ = nullptr;
673                 delete callbackInfo;
674             }
675             delete work;
676         },
677         uv_qos_user_initiated);
678     if (ret) {
679         MEDIA_ERR_LOG("RawPhotoListener:UpdateJSCallbackAsync() failed to execute work");
680         delete work;
681     } else {
682         callbackInfo.release();
683     }
684 }
685 
UpdateMainPictureStageOneJSCallback(sptr<SurfaceBuffer> surfaceBuffer,int64_t timestamp) const686 void PhotoListener::UpdateMainPictureStageOneJSCallback(sptr<SurfaceBuffer> surfaceBuffer, int64_t timestamp) const
687 {
688     MEDIA_INFO_LOG("PhotoListener:UpdateMainPictureStageOneJSCallback called");
689     uv_loop_s* loop = nullptr;
690     napi_get_uv_event_loop(env_, &loop);
691     if (!loop) {
692         MEDIA_ERR_LOG("PhotoListenerInfo:UpdateMainPictureStageOneJSCallback() failed to get event loop");
693         return;
694     }
695     uv_work_t* work = new (std::nothrow) uv_work_t;
696     if (!work) {
697         MEDIA_ERR_LOG("PhotoListenerInfo:UpdateMainPictureStageOneJSCallback() failed to allocate work");
698         return;
699     }
700     std::unique_ptr<PhotoListenerInfo> callbackInfo = std::make_unique<PhotoListenerInfo>(nullptr, this);
701     callbackInfo->surfaceBuffer = surfaceBuffer;
702     callbackInfo->timestamp = timestamp;
703     work->data = callbackInfo.get();
704     int ret = uv_queue_work_with_qos(
705         loop, work, [](uv_work_t* work) {},
706         [](uv_work_t* work, int status) {
707             PhotoListenerInfo* callbackInfo = reinterpret_cast<PhotoListenerInfo*>(work->data);
708             if (callbackInfo && callbackInfo->listener_) {
709                 MEDIA_INFO_LOG("ExecutePhotoAsset picture");
710                 sptr<SurfaceBuffer> surfaceBuffer = callbackInfo->surfaceBuffer;
711                 int64_t timestamp = callbackInfo->timestamp;
712                 callbackInfo->listener_->ExecutePhoto(surfaceBuffer, timestamp);
713                 callbackInfo->listener_ = nullptr;
714                 delete callbackInfo;
715             }
716             delete work;
717         },
718         uv_qos_user_initiated);
719     if (ret) {
720         MEDIA_ERR_LOG("RawPhotoListener:UpdateJSCallbackAsync() failed to execute work");
721         delete work;
722     } else {
723         callbackInfo.release();
724     }
725 }
726 
LoggingSurfaceBufferInfo(sptr<SurfaceBuffer> buffer,std::string bufName)727 inline void LoggingSurfaceBufferInfo(sptr<SurfaceBuffer> buffer, std::string bufName)
728 {
729     if (buffer) {
730         MEDIA_INFO_LOG("AssembleAuxiliaryPhoto %{public}s w=%{public}d, h=%{public}d, f=%{public}d", bufName.c_str(),
731             buffer->GetWidth(), buffer->GetHeight(), buffer->GetFormat());
732     }
733 };
734 
GetLocationBySettings(std::shared_ptr<PhotoCaptureSetting> settings)735 std::shared_ptr<Location> GetLocationBySettings(std::shared_ptr<PhotoCaptureSetting> settings)
736 {
737     auto location = make_shared<Location>();
738     if (settings) {
739         settings->GetLocation(location);
740         MEDIA_INFO_LOG("GetLocationBySettings latitude:%{private}f, longitude:%{private}f",
741             location->latitude, location->longitude);
742     } else {
743         MEDIA_ERR_LOG("GetLocationBySettings failed!");
744     }
745     return location;
746 }
747 
GetBurstSeqId(int32_t captureId)748 int32_t GetBurstSeqId(int32_t captureId)
749 {
750     const uint32_t burstSeqIdMask = 0xFFFF;
751     return captureId > 0 ? (static_cast<int32_t>(static_cast<uint32_t>(captureId) & burstSeqIdMask)) : captureId;
752 }
753 
CleanAfterTransPicture(sptr<PhotoOutput> photoOutput,int32_t captureId)754 void CleanAfterTransPicture(sptr<PhotoOutput> photoOutput, int32_t captureId)
755 {
756     if (!photoOutput) {
757         MEDIA_ERR_LOG("CleanAfterTransPicture photoOutput is nullptr");
758         return;
759     }
760     photoOutput->photoProxyMap_[captureId] = nullptr;
761     photoOutput->photoProxyMap_.erase(captureId);
762     photoOutput->captureIdPictureMap_.erase(captureId);
763     photoOutput->captureIdGainmapMap_.erase(captureId);
764     photoOutput->captureIdDepthMap_.erase(captureId);
765     photoOutput->captureIdExifMap_.erase(captureId);
766     photoOutput->captureIdDebugMap_.erase(captureId);
767     photoOutput->captureIdAuxiliaryCountMap_.erase(captureId);
768     photoOutput->captureIdCountMap_.erase(captureId);
769     photoOutput->captureIdHandleMap_.erase(captureId);
770 }
771 
AssembleAuxiliaryPhoto(int64_t timestamp,int32_t captureId)772 void PhotoListener::AssembleAuxiliaryPhoto(int64_t timestamp, int32_t captureId) __attribute__((no_sanitize("cfi")))
773 {
774     MEDIA_INFO_LOG("AssembleAuxiliaryPhoto begin captureId %{public}d, burstSeqId %{public}d",
775         captureId, GetBurstSeqId(captureId));
776     std::lock_guard<std::mutex> lock(g_assembleImageMutex);
777     auto photoOutput = photoOutput_.promote();
778     if (photoOutput && photoOutput->GetSession()) {
779         auto location = GetLocationBySettings(photoOutput->GetDefaultCaptureSetting());
780         if (location && photoOutput->photoProxyMap_[captureId]) {
781             photoOutput->photoProxyMap_[captureId]->SetLocation(location->latitude, location->longitude);
782         }
783         std::unique_ptr<Media::Picture> picture = std::move(photoOutput->captureIdPictureMap_[captureId]);
784         if (photoOutput->captureIdExifMap_[captureId] && picture) {
785             auto buffer = photoOutput->captureIdExifMap_[captureId];
786             LoggingSurfaceBufferInfo(buffer, "exifSurfaceBuffer");
787             picture->SetExifMetadata(buffer);
788             photoOutput->captureIdExifMap_[captureId] = nullptr;
789         }
790         if (photoOutput->captureIdGainmapMap_[captureId] && picture) {
791             std::unique_ptr<Media::AuxiliaryPicture> uniptr = Media::AuxiliaryPicture::Create(
792                 photoOutput->captureIdGainmapMap_[captureId], Media::AuxiliaryPictureType::GAINMAP);
793             std::shared_ptr<Media::AuxiliaryPicture> picturePtr = std::move(uniptr);
794             LoggingSurfaceBufferInfo(photoOutput->captureIdGainmapMap_[captureId], "gainmapSurfaceBuffer");
795             picture->SetAuxiliaryPicture(picturePtr);
796             photoOutput->captureIdGainmapMap_[captureId] = nullptr;
797         }
798         if (photoOutput->captureIdDepthMap_[captureId] && picture) {
799             std::unique_ptr<Media::AuxiliaryPicture> uniptr = Media::AuxiliaryPicture::Create(
800                 photoOutput->captureIdDepthMap_[captureId], Media::AuxiliaryPictureType::DEPTH_MAP);
801             std::shared_ptr<Media::AuxiliaryPicture> picturePtr = std::move(uniptr);
802             LoggingSurfaceBufferInfo(photoOutput->captureIdDepthMap_[captureId], "deepSurfaceBuffer");
803             picture->SetAuxiliaryPicture(picturePtr);
804             photoOutput->captureIdDepthMap_[captureId] = nullptr;
805         }
806         if (photoOutput->captureIdDebugMap_[captureId] && picture) {
807             auto buffer = photoOutput->captureIdDebugMap_[captureId];
808             LoggingSurfaceBufferInfo(buffer, "debugSurfaceBuffer");
809             picture->SetMaintenanceData(buffer);
810             photoOutput->captureIdDebugMap_[captureId] = nullptr;
811         }
812         MEDIA_INFO_LOG("AssembleAuxiliaryPhoto end captureId %{public}d, burstSeqId %{public}d",
813             captureId, GetBurstSeqId(captureId));
814         if (picture) {
815             std::string uri;
816             int32_t cameraShotType;
817             std::string burstKey = "";
818             photoOutput->GetSession()->CreateMediaLibrary(std::move(picture), photoOutput->photoProxyMap_[captureId],
819                 uri, cameraShotType, burstKey, timestamp);
820             MEDIA_INFO_LOG("CreateMediaLibrary result %{public}s, type %{public}d", uri.c_str(), cameraShotType);
821             UpdatePictureJSCallback(captureId, uri, cameraShotType, burstKey);
822             CleanAfterTransPicture(photoOutput, captureId);
823         } else {
824             MEDIA_ERR_LOG("CreateMediaLibrary picture is nullptr");
825         }
826     }
827 }
828 
ExecutePhoto(sptr<SurfaceBuffer> surfaceBuffer,int64_t timestamp) const829 void PhotoListener::ExecutePhoto(sptr<SurfaceBuffer> surfaceBuffer, int64_t timestamp) const
830 {
831     MEDIA_INFO_LOG("ExecutePhoto");
832     napi_value result[ARGS_TWO] = {nullptr, nullptr};
833     napi_value retVal;
834     napi_value mainImage = nullptr;
835     std::shared_ptr<Media::NativeImage> image = std::make_shared<Media::NativeImage>(surfaceBuffer,
836         bufferProcessor_, timestamp);
837     napi_get_undefined(env_, &result[PARAM0]);
838     napi_get_undefined(env_, &result[PARAM1]);
839     mainImage = Media::ImageNapi::Create(env_, image);
840     if (mainImage == nullptr) {
841         MEDIA_ERR_LOG("ImageNapi Create failed");
842         napi_get_undefined(env_, &mainImage);
843     }
844     napi_value photoValue = PhotoNapi::CreatePhoto(env_, mainImage);
845     FillNapiObjectWithCaptureId(env_, GetCaptureId(surfaceBuffer), photoValue);
846     result[PARAM1] = photoValue;
847     ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
848     ExecuteCallback(CONST_CAPTURE_PHOTO_AVAILABLE, callbackNapiPara);
849     photoSurface_->ReleaseBuffer(surfaceBuffer, -1);
850 }
851 
ExecuteDeferredPhoto(sptr<SurfaceBuffer> surfaceBuffer) const852 void PhotoListener::ExecuteDeferredPhoto(sptr<SurfaceBuffer> surfaceBuffer) const
853 {
854     MEDIA_INFO_LOG("ExecuteDeferredPhoto");
855     napi_value result[ARGS_TWO] = {nullptr, nullptr};
856     napi_value retVal;
857 
858     BufferHandle* bufferHandle = surfaceBuffer->GetBufferHandle();
859     int64_t imageId;
860     int32_t deferredProcessingType;
861     surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::imageId, imageId);
862     surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::deferredProcessingType, deferredProcessingType);
863     MEDIA_INFO_LOG("PhotoListener ExecuteDeferredPhoto imageId:%{public}" PRId64 ", deferredProcessingType:%{public}d",
864         imageId, deferredProcessingType);
865 
866     // create pixelMap to encode
867     int32_t thumbnailWidth;
868     int32_t thumbnailHeight;
869     surfaceBuffer->GetExtraData()->ExtraGet(OHOS::CameraStandard::dataWidth, thumbnailWidth);
870     surfaceBuffer->GetExtraData()->ExtraGet(OHOS::CameraStandard::dataHeight, thumbnailHeight);
871     MEDIA_INFO_LOG("thumbnailWidth:%{public}d, thumbnailHeight: %{public}d", thumbnailWidth, thumbnailHeight);
872 
873     MEDIA_DEBUG_LOG("w:%{public}d, h:%{public}d, s:%{public}d, fd:%{public}d, size: %{public}d, format: %{public}d",
874         bufferHandle->width, bufferHandle->height, bufferHandle->stride, bufferHandle->fd, bufferHandle->size,
875         bufferHandle->format);
876 
877     napi_get_undefined(env_, &result[PARAM0]);
878     napi_get_undefined(env_, &result[PARAM1]);
879 
880     // deep copy buffer
881     sptr<SurfaceBuffer> newSurfaceBuffer = SurfaceBuffer::Create();
882     DeepCopyBuffer(newSurfaceBuffer, surfaceBuffer, 0);
883     BufferHandle *newBufferHandle = CameraCloneBufferHandle(newSurfaceBuffer->GetBufferHandle());
884     if (newBufferHandle == nullptr) {
885         napi_value errorCode;
886         napi_create_int32(env_, CameraErrorCode::INVALID_ARGUMENT, &errorCode);
887         result[PARAM0] = errorCode;
888         MEDIA_ERR_LOG("invalid bufferHandle");
889     }
890 
891     // call js function
892     sptr<DeferredPhotoProxy> deferredPhotoProxy;
893     std::string imageIdStr = std::to_string(imageId);
894     deferredPhotoProxy = new(std::nothrow) DeferredPhotoProxy(newBufferHandle, imageIdStr, deferredProcessingType,
895         thumbnailWidth, thumbnailHeight);
896     if (deferredPhotoProxy == nullptr) {
897         napi_value errorCode;
898         napi_create_int32(env_, CameraErrorCode::SERVICE_FATL_ERROR, &errorCode);
899         result[PARAM0] = errorCode;
900         MEDIA_ERR_LOG("failed to new deferredPhotoProxy!");
901     }
902     result[PARAM1] = DeferredPhotoProxyNapi::CreateDeferredPhotoProxy(env_, deferredPhotoProxy);
903 
904     ExecuteCallbackNapiPara callbackPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
905     ExecuteCallback(CONST_CAPTURE_DEFERRED_PHOTO_AVAILABLE, callbackPara);
906 
907     // return buffer to buffer queue
908     photoSurface_->ReleaseBuffer(surfaceBuffer, -1);
909 }
910 
DeepCopyBuffer(sptr<SurfaceBuffer> newSurfaceBuffer,sptr<SurfaceBuffer> surfaceBuffer,int32_t captureId) const911 void PhotoListener::DeepCopyBuffer(sptr<SurfaceBuffer> newSurfaceBuffer, sptr<SurfaceBuffer> surfaceBuffer,
912     int32_t captureId) const
913 {
914     MEDIA_DEBUG_LOG("PhotoListener::DeepCopyBuffer w=%{public}d, h=%{public}d, f=%{public}d surfaceName=%{public}s "
915         "captureId = %{public}d", surfaceBuffer->GetWidth(), surfaceBuffer->GetHeight(), surfaceBuffer->GetFormat(),
916         "main", captureId);
917     BufferRequestConfig requestConfig = {
918         .width = surfaceBuffer->GetWidth(),
919         .height = surfaceBuffer->GetHeight(),
920         .strideAlignment = 0x8, // default stride is 8 Bytes.
921         .format = surfaceBuffer->GetFormat(),
922         .usage = surfaceBuffer->GetUsage(),
923         .timeout = 0,
924         .colorGamut = surfaceBuffer->GetSurfaceBufferColorGamut(),
925         .transform = surfaceBuffer->GetSurfaceBufferTransform(),
926     };
927     auto allocErrorCode = newSurfaceBuffer->Alloc(requestConfig);
928     MEDIA_DEBUG_LOG("PhotoListener::DeepCopyBuffer SurfaceBuffer alloc ret: %{public}d surfaceName=%{public}s "
929         "captureId = %{public}d", allocErrorCode, "main", captureId);
930     if (memcpy_s(newSurfaceBuffer->GetVirAddr(), newSurfaceBuffer->GetSize(),
931         surfaceBuffer->GetVirAddr(), surfaceBuffer->GetSize()) != EOK) {
932         MEDIA_ERR_LOG("PhotoListener memcpy_s failed");
933     }
934     MEDIA_DEBUG_LOG("PhotoListener::DeepCopyBuffer memcpy_s end surfaceName=%{public}s captureId = %{public}d",
935         "main", captureId);
936 }
937 
ExecutePhotoAsset(sptr<SurfaceBuffer> surfaceBuffer,bool isHighQuality,int64_t timestamp) const938 void PhotoListener::ExecutePhotoAsset(sptr<SurfaceBuffer> surfaceBuffer, bool isHighQuality, int64_t timestamp) const
939 {
940     CAMERA_SYNC_TRACE;
941     MEDIA_INFO_LOG("ExecutePhotoAsset");
942     napi_value result[ARGS_TWO] = { nullptr, nullptr };
943     napi_value retVal;
944     napi_get_undefined(env_, &result[PARAM0]);
945     napi_get_undefined(env_, &result[PARAM1]);
946     // deep copy buffer
947     sptr<SurfaceBuffer> newSurfaceBuffer = SurfaceBuffer::Create();
948     DeepCopyBuffer(newSurfaceBuffer, surfaceBuffer, 0);
949     BufferHandle* bufferHandle = newSurfaceBuffer->GetBufferHandle();
950     if (bufferHandle == nullptr) {
951         napi_value errorCode;
952         napi_create_int32(env_, CameraErrorCode::INVALID_ARGUMENT, &errorCode);
953         result[PARAM0] = errorCode;
954         MEDIA_ERR_LOG("invalid bufferHandle");
955     }
956     newSurfaceBuffer->Map();
957     int32_t captureId = GetCaptureId(surfaceBuffer);
958     string uri = "";
959     int32_t cameraShotType = 0;
960     std::string burstKey = "";
961     CreateMediaLibrary(surfaceBuffer, bufferHandle, isHighQuality, uri, cameraShotType, burstKey, timestamp);
962     MEDIA_INFO_LOG("CreateMediaLibrary result uri:%{public}s cameraShotType:%{public}d burstKey:%{public}s",
963         uri.c_str(), cameraShotType, burstKey.c_str());
964     napi_value photoAssetValue = Media::MediaLibraryCommNapi::CreatePhotoAssetNapi(env_, uri, cameraShotType, burstKey);
965     if (photoAssetValue == nullptr) {
966         napi_get_undefined(env_, &photoAssetValue);
967     }
968     FillNapiObjectWithCaptureId(env_, captureId, photoAssetValue);
969     result[PARAM1] = photoAssetValue;
970     ExecuteCallbackNapiPara callbackPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
971     ExecuteCallback(CONST_CAPTURE_PHOTO_ASSET_AVAILABLE, callbackPara);
972     // return buffer to buffer queue
973     photoSurface_->ReleaseBuffer(surfaceBuffer, -1);
974 }
975 
CreateMediaLibrary(sptr<SurfaceBuffer> surfaceBuffer,BufferHandle * bufferHandle,bool isHighQuality,std::string & uri,int32_t & cameraShotType,std::string & burstKey,int64_t timestamp) const976 void PhotoListener::CreateMediaLibrary(sptr<SurfaceBuffer> surfaceBuffer, BufferHandle *bufferHandle,
977     bool isHighQuality, std::string &uri, int32_t &cameraShotType, std::string &burstKey, int64_t timestamp) const
978 {
979     CAMERA_SYNC_TRACE;
980     if (bufferHandle == nullptr) {
981         MEDIA_ERR_LOG("bufferHandle is nullptr");
982         return;
983     }
984     int32_t captureId;
985     surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::captureId, captureId);
986     int32_t burstSeqId = -1;
987     surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::burstSequenceId, burstSeqId);
988     int64_t imageId = 0;
989     surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::imageId, imageId);
990     int32_t deferredProcessingType;
991     surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::deferredProcessingType, deferredProcessingType);
992     MEDIA_INFO_LOG(
993         "PhotoListener ExecutePhotoAsset captureId:%{public}d "
994         "imageId:%{public}" PRId64 ", deferredProcessingType:%{public}d, burstSeqId:%{public}d",
995         captureId, imageId, deferredProcessingType, burstSeqId);
996     int32_t photoWidth;
997     surfaceBuffer->GetExtraData()->ExtraGet(OHOS::CameraStandard::dataWidth, photoWidth);
998     int32_t photoHeight;
999     surfaceBuffer->GetExtraData()->ExtraGet(OHOS::CameraStandard::dataHeight, photoHeight);
1000     uint64_t size = static_cast<uint64_t>(surfaceBuffer->GetSize());
1001     int32_t extraDataSize = 0;
1002     auto res = surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::dataSize, extraDataSize);
1003     if (res != 0) {
1004         MEDIA_INFO_LOG("ExtraGet dataSize error %{public}d", res);
1005     } else if (extraDataSize <= 0) {
1006         MEDIA_INFO_LOG("ExtraGet dataSize Ok, but size <= 0");
1007     } else if (static_cast<uint64_t>(extraDataSize) > size) {
1008         MEDIA_INFO_LOG("ExtraGet dataSize Ok,but dataSize %{public}d is bigger than bufferSize %{public}" PRIu64,
1009             extraDataSize, size);
1010     } else {
1011         MEDIA_INFO_LOG("ExtraGet dataSize %{public}d", extraDataSize);
1012         size = static_cast<uint64_t>(extraDataSize);
1013     }
1014     int32_t deferredImageFormat = 0;
1015     res = surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::deferredImageFormat, deferredImageFormat);
1016     MEDIA_INFO_LOG("deferredImageFormat:%{public}d, width:%{public}d, height:%{public}d, size:%{public}" PRId64,
1017         deferredImageFormat, photoWidth, photoHeight, size);
1018     int32_t format = bufferHandle->format;
1019     sptr<CameraPhotoProxy> photoProxy;
1020     std::string imageIdStr = std::to_string(imageId);
1021     photoProxy = new(std::nothrow) CameraPhotoProxy(bufferHandle, format, photoWidth, photoHeight,
1022                                                     isHighQuality, captureId, burstSeqId);
1023     if (photoProxy == nullptr) {
1024         return;
1025     }
1026     photoProxy->SetDeferredAttrs(imageIdStr, deferredProcessingType, size, deferredImageFormat);
1027     auto photoOutput = photoOutput_.promote();
1028     if (photoOutput && photoOutput->GetSession()) {
1029         auto settings = photoOutput->GetDefaultCaptureSetting();
1030         if (settings) {
1031             auto location = make_shared<Location>();
1032             settings->GetLocation(location);
1033             photoProxy->SetLocation(location->latitude, location->longitude);
1034         }
1035         photoOutput->GetSession()->CreateMediaLibrary(photoProxy, uri, cameraShotType, burstKey, timestamp);
1036     }
1037 }
1038 
UpdateJSCallback(sptr<Surface> photoSurface) const1039 void PhotoListener::UpdateJSCallback(sptr<Surface> photoSurface) const
1040 {
1041     MEDIA_DEBUG_LOG("PhotoListener UpdateJSCallback enter");
1042     sptr<SurfaceBuffer> surfaceBuffer = nullptr;
1043     int32_t fence = -1;
1044     int64_t timestamp;
1045     OHOS::Rect damage;
1046     SurfaceError surfaceRet = photoSurface->AcquireBuffer(surfaceBuffer, fence, timestamp, damage);
1047     if (surfaceRet != SURFACE_ERROR_OK) {
1048         MEDIA_ERR_LOG("PhotoListener Failed to acquire surface buffer");
1049         return;
1050     }
1051     MEDIA_INFO_LOG("PhotoListener::UpdateJSCallback ts is:%{public}" PRId64, timestamp);
1052     int32_t isDegradedImage;
1053     surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::isDegradedImage, isDegradedImage);
1054     MEDIA_INFO_LOG("PhotoListener UpdateJSCallback isDegradedImage:%{public}d", isDegradedImage);
1055     if ((callbackFlag_ & CAPTURE_PHOTO_ASSET) != 0) {
1056         auto photoOutput = photoOutput_.promote();
1057         if (photoOutput != nullptr) {
1058             int32_t currentCaptureId = GetCaptureId(surfaceBuffer);
1059             photoOutput->AcquireBufferToPrepareProxy(currentCaptureId);
1060         }
1061         ExecutePhotoAsset(surfaceBuffer, isDegradedImage == 0, timestamp);
1062     } else if (isDegradedImage == 0 && (callbackFlag_ & CAPTURE_PHOTO) != 0) {
1063         ExecutePhoto(surfaceBuffer, timestamp);
1064     } else if (isDegradedImage != 0 && (callbackFlag_ & CAPTURE_DEFERRED_PHOTO) != 0) {
1065         ExecuteDeferredPhoto(surfaceBuffer);
1066     } else {
1067         MEDIA_INFO_LOG("PhotoListener on error callback");
1068     }
1069 }
1070 
UpdateJSCallbackAsync(sptr<Surface> photoSurface) const1071 void PhotoListener::UpdateJSCallbackAsync(sptr<Surface> photoSurface) const
1072 {
1073     MEDIA_DEBUG_LOG("PhotoListener UpdateJSCallbackAsync enter");
1074     uv_loop_s* loop = nullptr;
1075     napi_get_uv_event_loop(env_, &loop);
1076     MEDIA_INFO_LOG("PhotoListener UpdateJSCallbackAsync get loop");
1077     if (!loop) {
1078         MEDIA_ERR_LOG("PhotoListener:UpdateJSCallbackAsync() failed to get event loop");
1079         return;
1080     }
1081     uv_work_t* work = new (std::nothrow) uv_work_t;
1082     if (!work) {
1083         MEDIA_ERR_LOG("PhotoListener:UpdateJSCallbackAsync() failed to allocate work");
1084         return;
1085     }
1086     std::unique_ptr<PhotoListenerInfo> callbackInfo = std::make_unique<PhotoListenerInfo>(photoSurface, this);
1087     work->data = callbackInfo.get();
1088     MEDIA_DEBUG_LOG("PhotoListener UpdateJSCallbackAsync uv_queue_work_with_qos start");
1089     int ret = uv_queue_work_with_qos(
1090         loop, work, [](uv_work_t* work) {},
1091         [](uv_work_t* work, int status) {
1092             PhotoListenerInfo* callbackInfo = reinterpret_cast<PhotoListenerInfo*>(work->data);
1093             if (callbackInfo) {
1094                 callbackInfo->listener_->UpdateJSCallback(callbackInfo->photoSurface_);
1095                 MEDIA_INFO_LOG("PhotoListener:UpdateJSCallbackAsync() complete");
1096                 callbackInfo->photoSurface_ = nullptr;
1097                 callbackInfo->listener_ = nullptr;
1098                 delete callbackInfo;
1099             }
1100             delete work;
1101         },
1102         uv_qos_user_initiated);
1103     if (ret) {
1104         MEDIA_ERR_LOG("PhotoListener:UpdateJSCallbackAsync() failed to execute work");
1105         delete work;
1106     } else {
1107         callbackInfo.release();
1108     }
1109 }
1110 
SaveCallback(const std::string eventName,napi_value callback)1111 void PhotoListener::SaveCallback(const std::string eventName, napi_value callback)
1112 {
1113     MEDIA_INFO_LOG("PhotoListener::SaveCallback is called eventName:%{public}s", eventName.c_str());
1114     auto eventTypeEnum = PhotoOutputEventTypeHelper.ToEnum(eventName);
1115     switch (eventTypeEnum) {
1116         case PhotoOutputEventType::CAPTURE_PHOTO_AVAILABLE:
1117             callbackFlag_ |= CAPTURE_PHOTO;
1118             break;
1119         case PhotoOutputEventType::CAPTURE_DEFERRED_PHOTO_AVAILABLE:
1120             callbackFlag_ |= CAPTURE_DEFERRED_PHOTO;
1121             break;
1122         case PhotoOutputEventType::CAPTURE_PHOTO_ASSET_AVAILABLE:
1123             callbackFlag_ |= CAPTURE_PHOTO_ASSET;
1124             break;
1125         default:
1126             MEDIA_ERR_LOG("Incorrect photo callback event type received from JS");
1127             return;
1128     }
1129     auto photoOutput = photoOutput_.promote();
1130     if (photoOutput) {
1131         photoOutput->SetCallbackFlag(callbackFlag_);
1132     } else {
1133         MEDIA_ERR_LOG("cannot get photoOutput");
1134     }
1135     SaveCallbackReference(eventName, callback, false);
1136 }
1137 
RemoveCallback(const std::string eventName,napi_value callback)1138 void PhotoListener::RemoveCallback(const std::string eventName, napi_value callback)
1139 {
1140     MEDIA_INFO_LOG("PhotoListener::RemoveCallback is called eventName:%{public}s", eventName.c_str());
1141     if (eventName == CONST_CAPTURE_PHOTO_AVAILABLE) {
1142         callbackFlag_ &= ~CAPTURE_PHOTO;
1143     } else if (eventName == CONST_CAPTURE_DEFERRED_PHOTO_AVAILABLE) {
1144         callbackFlag_ &= ~CAPTURE_DEFERRED_PHOTO;
1145     } else if (eventName == CONST_CAPTURE_PHOTO_ASSET_AVAILABLE) {
1146         auto photoOutput = photoOutput_.promote();
1147         if (photoOutput != nullptr) {
1148             photoOutput->DeferImageDeliveryFor(DeferredDeliveryImageType::DELIVERY_NONE);
1149         }
1150         callbackFlag_ &= ~CAPTURE_PHOTO_ASSET;
1151     }
1152     RemoveCallbackRef(eventName, callback);
1153 }
1154 
OnBufferAvailable()1155 void RawPhotoListener::OnBufferAvailable()
1156 {
1157     std::lock_guard<std::mutex> lock(g_photoImageMutex);
1158     CAMERA_SYNC_TRACE;
1159     MEDIA_INFO_LOG("RawPhotoListener::OnBufferAvailable is called");
1160     if (!rawPhotoSurface_) {
1161         MEDIA_ERR_LOG("RawPhotoListener napi rawPhotoSurface_ is null");
1162         return;
1163     }
1164     UpdateJSCallbackAsync(rawPhotoSurface_);
1165 }
1166 
ExecuteRawPhoto(sptr<SurfaceBuffer> surfaceBuffer) const1167 void RawPhotoListener::ExecuteRawPhoto(sptr<SurfaceBuffer> surfaceBuffer) const
1168 {
1169     MEDIA_INFO_LOG("ExecuteRawPhoto");
1170     napi_value result[ARGS_TWO] = { nullptr, nullptr };
1171     napi_value retVal;
1172     napi_value rawImage = nullptr;
1173     std::shared_ptr<Media::NativeImage> image = std::make_shared<Media::NativeImage>(surfaceBuffer, bufferProcessor_);
1174     napi_get_undefined(env_, &result[PARAM0]);
1175     napi_get_undefined(env_, &result[PARAM1]);
1176     rawImage = Media::ImageNapi::Create(env_, image);
1177     if (rawImage == nullptr) {
1178         MEDIA_ERR_LOG("ImageNapi Create failed");
1179         napi_get_undefined(env_, &rawImage);
1180     }
1181     result[PARAM1] = PhotoNapi::CreateRawPhoto(env_, rawImage);
1182     ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
1183     ExecuteCallback(CONST_CAPTURE_PHOTO_AVAILABLE, callbackNapiPara);
1184     rawPhotoSurface_->ReleaseBuffer(surfaceBuffer, -1);
1185 }
1186 
UpdateJSCallback(sptr<Surface> rawPhotoSurface) const1187 void RawPhotoListener::UpdateJSCallback(sptr<Surface> rawPhotoSurface) const
1188 {
1189     sptr<SurfaceBuffer> surfaceBuffer = nullptr;
1190     int32_t fence = -1;
1191     int64_t timestamp;
1192     OHOS::Rect damage;
1193     SurfaceError surfaceRet = rawPhotoSurface->AcquireBuffer(surfaceBuffer, fence, timestamp, damage);
1194     if (surfaceRet != SURFACE_ERROR_OK) {
1195         MEDIA_ERR_LOG("RawPhotoListener Failed to acquire surface buffer");
1196         return;
1197     }
1198 
1199     int32_t isDegradedImage;
1200     surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::isDegradedImage, isDegradedImage);
1201     MEDIA_INFO_LOG("RawPhotoListener UpdateJSCallback isDegradedImage:%{public}d", isDegradedImage);
1202 
1203     if (isDegradedImage == 0) {
1204         ExecuteRawPhoto(surfaceBuffer);
1205     } else {
1206         MEDIA_ERR_LOG("RawPhoto not support deferred photo");
1207     }
1208 }
1209 
UpdateJSCallbackAsync(sptr<Surface> rawPhotoSurface) const1210 void RawPhotoListener::UpdateJSCallbackAsync(sptr<Surface> rawPhotoSurface) const
1211 {
1212     uv_loop_s* loop = nullptr;
1213     napi_get_uv_event_loop(env_, &loop);
1214     if (!loop) {
1215         MEDIA_ERR_LOG("RawPhotoListener:UpdateJSCallbackAsync() failed to get event loop");
1216         return;
1217     }
1218     uv_work_t* work = new (std::nothrow) uv_work_t;
1219     if (!work) {
1220         MEDIA_ERR_LOG("RawPhotoListener:UpdateJSCallbackAsync() failed to allocate work");
1221         return;
1222     }
1223     std::unique_ptr<RawPhotoListenerInfo> callbackInfo = std::make_unique<RawPhotoListenerInfo>(rawPhotoSurface, this);
1224     work->data = callbackInfo.get();
1225     int ret = uv_queue_work_with_qos(
1226         loop, work, [](uv_work_t* work) {},
1227         [](uv_work_t* work, int status) {
1228             RawPhotoListenerInfo* callbackInfo = reinterpret_cast<RawPhotoListenerInfo*>(work->data);
1229             if (callbackInfo) {
1230                 callbackInfo->listener_->UpdateJSCallback(callbackInfo->rawPhotoSurface_);
1231                 MEDIA_INFO_LOG("RawPhotoListener:UpdateJSCallbackAsync() complete");
1232                 callbackInfo->rawPhotoSurface_ = nullptr;
1233                 callbackInfo->listener_ = nullptr;
1234                 delete callbackInfo;
1235             }
1236             delete work;
1237         },
1238         uv_qos_user_initiated);
1239     if (ret) {
1240         MEDIA_ERR_LOG("RawPhotoListener:UpdateJSCallbackAsync() failed to execute work");
1241         delete work;
1242     } else {
1243         callbackInfo.release();
1244     }
1245 }
1246 
PhotoOutputCallback(napi_env env)1247 PhotoOutputCallback::PhotoOutputCallback(napi_env env) : ListenerBase(env) {}
1248 
UpdateJSExecute(uv_work_t * work)1249 void UpdateJSExecute(uv_work_t* work)
1250 {
1251     PhotoOutputCallbackInfo* callbackInfo = reinterpret_cast<PhotoOutputCallbackInfo*>(work->data);
1252     if (callbackInfo) {
1253         if (callbackInfo->eventType_ == PhotoOutputEventType::CAPTURE_START ||
1254             callbackInfo->eventType_ == PhotoOutputEventType::CAPTURE_START_WITH_INFO) {
1255             g_captureId = callbackInfo->info_.captureID;
1256             MEDIA_DEBUG_LOG("UpdateJSExecute CAPTURE_START g_captureId:%{public}d", g_captureId);
1257         }
1258         if (callbackInfo->eventType_ == PhotoOutputEventType::CAPTURE_FRAME_SHUTTER &&
1259             g_captureId != callbackInfo->info_.captureID) {
1260             uv_sem_wait(&g_captureStartSem);
1261         }
1262     }
1263 }
1264 
UpdateJSCallbackAsync(PhotoOutputEventType eventType,const CallbackInfo & info) const1265 void PhotoOutputCallback::UpdateJSCallbackAsync(PhotoOutputEventType eventType, const CallbackInfo &info) const
1266 {
1267     MEDIA_DEBUG_LOG("UpdateJSCallbackAsync is called");
1268     uv_loop_s* loop = nullptr;
1269     napi_get_uv_event_loop(env_, &loop);
1270     if (loop == nullptr) {
1271         MEDIA_ERR_LOG("failed to get event loop or failed to allocate work");
1272         return;
1273     }
1274     uv_work_t* work = new(std::nothrow) uv_work_t;
1275     if (work == nullptr) {
1276         MEDIA_ERR_LOG("UpdateJSCallbackAsync work is null");
1277         return;
1278     }
1279     if (!g_isSemInited) {
1280         uv_sem_init(&g_captureStartSem, 0);
1281         g_isSemInited = true;
1282     }
1283     std::unique_ptr<PhotoOutputCallbackInfo> callbackInfo =
1284         std::make_unique<PhotoOutputCallbackInfo>(eventType, info, shared_from_this());
1285     work->data = callbackInfo.get();
1286     int ret = uv_queue_work_with_qos(loop, work, UpdateJSExecute, [] (uv_work_t* work, int status) {
1287         PhotoOutputCallbackInfo* callbackInfo = reinterpret_cast<PhotoOutputCallbackInfo *>(work->data);
1288         if (callbackInfo) {
1289             auto listener = callbackInfo->listener_.lock();
1290             if (listener) {
1291                 listener->UpdateJSCallback(callbackInfo->eventType_, callbackInfo->info_);
1292                 if (callbackInfo->eventType_ == PhotoOutputEventType::CAPTURE_START ||
1293                     callbackInfo->eventType_ == PhotoOutputEventType::CAPTURE_START_WITH_INFO) {
1294                     MEDIA_DEBUG_LOG("PhotoOutputEventType::CAPTURE_START work done execute!");
1295                     uv_sem_post(&g_captureStartSem);
1296                 } else if (callbackInfo->eventType_ == PhotoOutputEventType::CAPTURE_FRAME_SHUTTER) {
1297                     MEDIA_DEBUG_LOG("PhotoOutputEventType::CAPTURE_FRAME_SHUTTER work done execute!");
1298                     uv_sem_destroy(&g_captureStartSem);
1299                     g_isSemInited = false;
1300                 }
1301             }
1302             delete callbackInfo;
1303         }
1304         delete work;
1305     }, uv_qos_user_initiated);
1306     if (ret) {
1307         MEDIA_ERR_LOG("failed to execute work");
1308         delete work;
1309     } else {
1310         callbackInfo.release();
1311     }
1312 }
1313 
OnCaptureStarted(const int32_t captureID) const1314 void PhotoOutputCallback::OnCaptureStarted(const int32_t captureID) const
1315 {
1316     CAMERA_SYNC_TRACE;
1317     MEDIA_DEBUG_LOG("OnCaptureStarted is called!, captureID: %{public}d", captureID);
1318     CallbackInfo info;
1319     info.captureID = captureID;
1320     UpdateJSCallbackAsync(PhotoOutputEventType::CAPTURE_START, info);
1321 }
1322 
OnCaptureStarted(const int32_t captureID,uint32_t exposureTime) const1323 void PhotoOutputCallback::OnCaptureStarted(const int32_t captureID, uint32_t exposureTime) const
1324 {
1325     CAMERA_SYNC_TRACE;
1326     MEDIA_DEBUG_LOG("OnCaptureStarted is called!, captureID: %{public}d", captureID);
1327     CallbackInfo info;
1328     info.captureID = captureID;
1329     info.timestamp = exposureTime;
1330     UpdateJSCallbackAsync(PhotoOutputEventType::CAPTURE_START_WITH_INFO, info);
1331 }
1332 
OnCaptureEnded(const int32_t captureID,const int32_t frameCount) const1333 void PhotoOutputCallback::OnCaptureEnded(const int32_t captureID, const int32_t frameCount) const
1334 {
1335     CAMERA_SYNC_TRACE;
1336     MEDIA_INFO_LOG("OnCaptureEnded is called!, captureID: %{public}d, frameCount: %{public}d",
1337         captureID, frameCount);
1338     CallbackInfo info;
1339     info.captureID = captureID;
1340     info.frameCount = frameCount;
1341     UpdateJSCallbackAsync(PhotoOutputEventType::CAPTURE_END, info);
1342 }
1343 
OnFrameShutter(const int32_t captureId,const uint64_t timestamp) const1344 void PhotoOutputCallback::OnFrameShutter(const int32_t captureId, const uint64_t timestamp) const
1345 {
1346     CAMERA_SYNC_TRACE;
1347     MEDIA_DEBUG_LOG(
1348         "OnFrameShutter is called, captureID: %{public}d, timestamp: %{public}" PRIu64, captureId, timestamp);
1349     CallbackInfo info;
1350     info.captureID = captureId;
1351     info.timestamp = timestamp;
1352     UpdateJSCallbackAsync(PhotoOutputEventType::CAPTURE_FRAME_SHUTTER, info);
1353 }
1354 
OnFrameShutterEnd(const int32_t captureId,const uint64_t timestamp) const1355 void PhotoOutputCallback::OnFrameShutterEnd(const int32_t captureId, const uint64_t timestamp) const
1356 {
1357     CAMERA_SYNC_TRACE;
1358     MEDIA_DEBUG_LOG(
1359         "OnFrameShutterEnd is called, captureID: %{public}d, timestamp: %{public}" PRIu64, captureId, timestamp);
1360     CallbackInfo info;
1361     info.captureID = captureId;
1362     info.timestamp = timestamp;
1363     UpdateJSCallbackAsync(PhotoOutputEventType::CAPTURE_FRAME_SHUTTER_END, info);
1364 }
1365 
OnCaptureReady(const int32_t captureId,const uint64_t timestamp) const1366 void PhotoOutputCallback::OnCaptureReady(const int32_t captureId, const uint64_t timestamp) const
1367 {
1368     CAMERA_SYNC_TRACE;
1369     MEDIA_DEBUG_LOG(
1370         "OnCaptureReady is called, captureID: %{public}d, timestamp: %{public}" PRIu64, captureId, timestamp);
1371     CallbackInfo info;
1372     info.captureID = captureId;
1373     info.timestamp = timestamp;
1374     UpdateJSCallbackAsync(PhotoOutputEventType::CAPTURE_READY, info);
1375 }
1376 
OnCaptureError(const int32_t captureId,const int32_t errorCode) const1377 void PhotoOutputCallback::OnCaptureError(const int32_t captureId, const int32_t errorCode) const
1378 {
1379     MEDIA_DEBUG_LOG("OnCaptureError is called!, captureID: %{public}d, errorCode: %{public}d", captureId, errorCode);
1380     CallbackInfo info;
1381     info.captureID = captureId;
1382     info.errorCode = errorCode;
1383     UpdateJSCallbackAsync(PhotoOutputEventType::CAPTURE_ERROR, info);
1384 }
1385 
OnEstimatedCaptureDuration(const int32_t duration) const1386 void PhotoOutputCallback::OnEstimatedCaptureDuration(const int32_t duration) const
1387 {
1388     MEDIA_DEBUG_LOG("OnEstimatedCaptureDuration is called!, duration: %{public}d", duration);
1389     CallbackInfo info;
1390     info.duration = duration;
1391     UpdateJSCallbackAsync(PhotoOutputEventType::CAPTURE_ESTIMATED_CAPTURE_DURATION, info);
1392 }
1393 
ExecuteCaptureStartCb(const CallbackInfo & info) const1394 void PhotoOutputCallback::ExecuteCaptureStartCb(const CallbackInfo& info) const
1395 {
1396     napi_value result[ARGS_TWO] = { nullptr, nullptr };
1397     napi_value retVal;
1398     napi_get_undefined(env_, &result[PARAM0]);
1399     if (IsEmpty(CONST_CAPTURE_START_WITH_INFO)) {
1400         napi_create_int32(env_, info.captureID, &result[PARAM1]);
1401         ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO,
1402             .argv = result, .result = &retVal };
1403         ExecuteCallback(CONST_CAPTURE_START, callbackNapiPara);
1404     } else {
1405         napi_value propValue;
1406         napi_create_object(env_, &result[PARAM1]);
1407         napi_create_int32(env_, info.captureID, &propValue);
1408         napi_set_named_property(env_, result[PARAM1], "captureId", propValue);
1409         int32_t invalidExposureTime = -1;
1410         napi_create_int32(env_, invalidExposureTime, &propValue);
1411         napi_set_named_property(env_, result[PARAM1], "time", propValue);
1412         ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO,
1413             .argv = result, .result = &retVal };
1414         ExecuteCallback(CONST_CAPTURE_START_WITH_INFO, callbackNapiPara);
1415     }
1416 }
1417 
ExecuteCaptureStartWithInfoCb(const CallbackInfo & info) const1418 void PhotoOutputCallback::ExecuteCaptureStartWithInfoCb(const CallbackInfo& info) const
1419 {
1420     napi_value result[ARGS_TWO] = { nullptr, nullptr };
1421     napi_value retVal;
1422     napi_value propValue;
1423     napi_get_undefined(env_, &result[PARAM0]);
1424     napi_create_object(env_, &result[PARAM1]);
1425     napi_create_int32(env_, info.captureID, &propValue);
1426     napi_set_named_property(env_, result[PARAM1], "captureId", propValue);
1427     napi_create_int32(env_, info.timestamp, &propValue);
1428     napi_set_named_property(env_, result[PARAM1], "time", propValue);
1429     ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
1430     ExecuteCallback(CONST_CAPTURE_START_WITH_INFO, callbackNapiPara);
1431 }
1432 
ExecuteCaptureEndCb(const CallbackInfo & info) const1433 void PhotoOutputCallback::ExecuteCaptureEndCb(const CallbackInfo& info) const
1434 {
1435     napi_value result[ARGS_TWO] = { nullptr, nullptr };
1436     napi_value retVal;
1437     napi_value propValue;
1438     napi_get_undefined(env_, &result[PARAM0]);
1439     napi_create_object(env_, &result[PARAM1]);
1440     napi_create_int32(env_, info.captureID, &propValue);
1441     napi_set_named_property(env_, result[PARAM1], "captureId", propValue);
1442     napi_create_int32(env_, info.frameCount, &propValue);
1443     napi_set_named_property(env_, result[PARAM1], "frameCount", propValue);
1444     ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
1445     ExecuteCallback(CONST_CAPTURE_END, callbackNapiPara);
1446 }
1447 
ExecuteFrameShutterCb(const CallbackInfo & info) const1448 void PhotoOutputCallback::ExecuteFrameShutterCb(const CallbackInfo& info) const
1449 {
1450     napi_value result[ARGS_TWO] = { nullptr, nullptr };
1451     napi_value retVal;
1452     napi_value propValue;
1453     napi_get_undefined(env_, &result[PARAM0]);
1454     napi_create_object(env_, &result[PARAM1]);
1455     napi_create_int32(env_, info.captureID, &propValue);
1456     napi_set_named_property(env_, result[PARAM1], "captureId", propValue);
1457     napi_create_int64(env_, info.timestamp, &propValue);
1458     napi_set_named_property(env_, result[PARAM1], "timestamp", propValue);
1459     ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
1460     ExecuteCallback(CONST_CAPTURE_FRAME_SHUTTER, callbackNapiPara);
1461 }
1462 
ExecuteFrameShutterEndCb(const CallbackInfo & info) const1463 void PhotoOutputCallback::ExecuteFrameShutterEndCb(const CallbackInfo& info) const
1464 {
1465     napi_value result[ARGS_TWO] = { nullptr, nullptr };
1466     napi_value retVal;
1467     napi_value propValue;
1468     napi_get_undefined(env_, &result[PARAM0]);
1469     napi_create_object(env_, &result[PARAM1]);
1470     napi_create_int32(env_, info.captureID, &propValue);
1471     napi_set_named_property(env_, result[PARAM1], "captureId", propValue);
1472     ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
1473     ExecuteCallback(CONST_CAPTURE_FRAME_SHUTTER_END, callbackNapiPara);
1474 }
1475 
ExecuteCaptureReadyCb(const CallbackInfo & info) const1476 void PhotoOutputCallback::ExecuteCaptureReadyCb(const CallbackInfo& info) const
1477 {
1478     napi_value result[ARGS_ONE] = { nullptr };
1479     napi_value retVal;
1480     napi_get_undefined(env_, &result[PARAM0]);
1481     ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_ONE, .argv = result, .result = &retVal };
1482     ExecuteCallback(CONST_CAPTURE_READY, callbackNapiPara);
1483 }
1484 
ExecuteCaptureErrorCb(const CallbackInfo & info) const1485 void PhotoOutputCallback::ExecuteCaptureErrorCb(const CallbackInfo& info) const
1486 {
1487     napi_value errJsResult[ARGS_ONE] = { nullptr };
1488     napi_value retVal;
1489     napi_value propValue;
1490 
1491     napi_create_object(env_, &errJsResult[PARAM0]);
1492     napi_create_int32(env_, info.errorCode, &propValue);
1493     napi_set_named_property(env_, errJsResult[PARAM0], "code", propValue);
1494     ExecuteCallbackNapiPara callbackNapiPara {
1495         .recv = nullptr, .argc = ARGS_ONE, .argv = errJsResult, .result = &retVal
1496     };
1497     ExecuteCallback(CONST_CAPTURE_ERROR, callbackNapiPara);
1498 }
1499 
ExecuteEstimatedCaptureDurationCb(const CallbackInfo & info) const1500 void PhotoOutputCallback::ExecuteEstimatedCaptureDurationCb(const CallbackInfo& info) const
1501 {
1502     napi_value result[ARGS_TWO] = { nullptr, nullptr };
1503     napi_value retVal;
1504     napi_get_undefined(env_, &result[PARAM0]);
1505     napi_create_int32(env_, info.duration, &result[PARAM1]);
1506     ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
1507     ExecuteCallback(CONST_CAPTURE_ESTIMATED_CAPTURE_DURATION, callbackNapiPara);
1508 }
1509 
UpdateJSCallback(PhotoOutputEventType eventType,const CallbackInfo & info) const1510 void PhotoOutputCallback::UpdateJSCallback(PhotoOutputEventType eventType, const CallbackInfo& info) const
1511 {
1512     MEDIA_DEBUG_LOG("UpdateJSCallback is called");
1513     switch (eventType) {
1514         case PhotoOutputEventType::CAPTURE_START:
1515             ExecuteCaptureStartCb(info);
1516             break;
1517         case PhotoOutputEventType::CAPTURE_END:
1518             ExecuteCaptureEndCb(info);
1519             break;
1520         case PhotoOutputEventType::CAPTURE_FRAME_SHUTTER:
1521             ExecuteFrameShutterCb(info);
1522             break;
1523         case PhotoOutputEventType::CAPTURE_ERROR:
1524             ExecuteCaptureErrorCb(info);
1525             break;
1526         case PhotoOutputEventType::CAPTURE_FRAME_SHUTTER_END:
1527             ExecuteFrameShutterEndCb(info);
1528             break;
1529         case PhotoOutputEventType::CAPTURE_READY:
1530             ExecuteCaptureReadyCb(info);
1531             break;
1532         case PhotoOutputEventType::CAPTURE_ESTIMATED_CAPTURE_DURATION:
1533             ExecuteEstimatedCaptureDurationCb(info);
1534             break;
1535         case PhotoOutputEventType::CAPTURE_START_WITH_INFO:
1536             ExecuteCaptureStartWithInfoCb(info);
1537             break;
1538         default:
1539             MEDIA_ERR_LOG("Incorrect photo callback event type received from JS");
1540     }
1541 }
1542 
ThumbnailListener(napi_env env,const sptr<PhotoOutput> photoOutput)1543 ThumbnailListener::ThumbnailListener(napi_env env, const sptr<PhotoOutput> photoOutput)
1544     : ListenerBase(env), photoOutput_(photoOutput)
1545 {}
1546 
OnBufferAvailable()1547 void ThumbnailListener::OnBufferAvailable()
1548 {
1549     CAMERA_SYNC_TRACE;
1550     MEDIA_INFO_LOG("ThumbnailListener::OnBufferAvailable is called");
1551     ExecuteDeepCopySurfaceBuffer();
1552     constexpr int32_t memSize = 20 * 1024;
1553     int32_t retCode = CameraManager::GetInstance()->RequireMemorySize(memSize);
1554     CHECK_ERROR_RETURN_LOG(retCode != 0, "ThumbnailListener::OnBufferAvailable RequireMemorySize failed");
1555     MEDIA_INFO_LOG("ThumbnailListener::OnBufferAvailable is end");
1556 }
1557 
ExecuteDeepCopySurfaceBuffer()1558 void ThumbnailListener::ExecuteDeepCopySurfaceBuffer()
1559 {
1560     auto photoOutput = photoOutput_.promote();
1561     CHECK_ERROR_RETURN_LOG(photoOutput == nullptr, "ThumbnailListener photoOutput is nullptr");
1562     CHECK_ERROR_RETURN_LOG(photoOutput->thumbnailSurface_ == nullptr, "ThumbnailListener thumbnailSurface_ is nullptr");
1563     auto surface = photoOutput->thumbnailSurface_;
1564     string surfaceName = "Thumbnail";
1565     MEDIA_INFO_LOG("ThumbnailListener ExecuteDeepCopySurfaceBuffer surfaceName = %{public}s",
1566         surfaceName.c_str());
1567     sptr<SurfaceBuffer> surfaceBuffer = nullptr;
1568     int32_t fence = -1;
1569     int64_t timestamp;
1570     OHOS::Rect damage;
1571     MEDIA_INFO_LOG("ThumbnailListener surfaceName = %{public}s AcquireBuffer before", surfaceName.c_str());
1572     SurfaceError surfaceRet = surface->AcquireBuffer(surfaceBuffer, fence, timestamp, damage);
1573     MEDIA_INFO_LOG("ThumbnailListener surfaceName = %{public}s AcquireBuffer end", surfaceName.c_str());
1574     if (surfaceRet != SURFACE_ERROR_OK) {
1575         MEDIA_ERR_LOG("ThumbnailListener Failed to acquire surface buffer");
1576         return;
1577     }
1578     int32_t thumbnailWidth;
1579     int32_t thumbnailHeight;
1580     int32_t burstSeqId = -1;
1581     surfaceBuffer->GetExtraData()->ExtraGet(OHOS::CameraStandard::dataWidth, thumbnailWidth);
1582     surfaceBuffer->GetExtraData()->ExtraGet(OHOS::CameraStandard::dataHeight, thumbnailHeight);
1583     surfaceBuffer->GetExtraData()->ExtraGet(OHOS::Camera::burstSequenceId, burstSeqId);
1584     int32_t captureId = GetCaptureId(surfaceBuffer);
1585     MEDIA_INFO_LOG("ThumbnailListener thumbnailWidth:%{public}d, thumbnailheight: %{public}d, captureId: %{public}d,"
1586         "burstSeqId: %{public}d", thumbnailWidth, thumbnailHeight, captureId, burstSeqId);
1587     if (burstSeqId != -1) {
1588         surface->ReleaseBuffer(surfaceBuffer, -1);
1589         return;
1590     }
1591     Media::InitializationOptions opts {
1592         .size = { .width = thumbnailWidth, .height = thumbnailHeight },
1593         .srcPixelFormat = Media::PixelFormat::RGBA_8888,
1594         .pixelFormat = Media::PixelFormat::RGBA_8888,
1595     };
1596     const int32_t formatSize = 4;
1597     auto pixelMap = Media::PixelMap::Create(static_cast<const uint32_t*>(surfaceBuffer->GetVirAddr()),
1598         thumbnailWidth * thumbnailHeight * formatSize, 0, thumbnailWidth, opts, true);
1599     MEDIA_DEBUG_LOG("ThumbnailListener ReleaseBuffer begin");
1600     surface->ReleaseBuffer(surfaceBuffer, -1);
1601     MEDIA_DEBUG_LOG("ThumbnailListener ReleaseBuffer end");
1602     UpdateJSCallbackAsync(std::move(pixelMap));
1603     MEDIA_INFO_LOG("ThumbnailListener surfaceName = %{public}s UpdateJSCallbackAsync captureId=%{public}d, end",
1604         surfaceName.c_str(), captureId);
1605 }
1606 
UpdateJSCallbackAsync(unique_ptr<Media::PixelMap> pixelMap)1607 void ThumbnailListener::UpdateJSCallbackAsync(unique_ptr<Media::PixelMap> pixelMap)
1608 {
1609     uv_loop_s* loop = nullptr;
1610     napi_get_uv_event_loop(env_, &loop);
1611     if (!loop) {
1612         MEDIA_ERR_LOG("ThumbnailListener:UpdateJSCallbackAsync() failed to get event loop");
1613         return;
1614     }
1615     uv_work_t* work = new (std::nothrow) uv_work_t;
1616     if (!work) {
1617         MEDIA_ERR_LOG("ThumbnailListener:UpdateJSCallbackAsync() failed to allocate work");
1618         return;
1619     }
1620     std::unique_ptr<ThumbnailListenerInfo> callbackInfo =
1621         std::make_unique<ThumbnailListenerInfo>(this, std::move(pixelMap));
1622     work->data = callbackInfo.get();
1623     int ret = uv_queue_work_with_qos(
1624         loop, work, [](uv_work_t* work) {},
1625         [](uv_work_t* work, int status) {
1626             ThumbnailListenerInfo* callbackInfo = reinterpret_cast<ThumbnailListenerInfo*>(work->data);
1627             if (callbackInfo) {
1628                 auto listener = callbackInfo->listener_.promote();
1629                 if (listener != nullptr) {
1630                     listener->UpdateJSCallback(std::move(callbackInfo->pixelMap_));
1631                     MEDIA_INFO_LOG("ThumbnailListener:UpdateJSCallbackAsync() complete");
1632                 }
1633                 delete callbackInfo;
1634             }
1635             delete work;
1636         },
1637         uv_qos_user_initiated);
1638     if (ret) {
1639         MEDIA_ERR_LOG("ThumbnailListener:UpdateJSCallbackAsync() failed to execute work");
1640         delete work;
1641     } else {
1642         callbackInfo.release();
1643     }
1644 }
1645 
UpdateJSCallback(unique_ptr<Media::PixelMap> pixelMap) const1646 void ThumbnailListener::UpdateJSCallback(unique_ptr<Media::PixelMap> pixelMap) const
1647 {
1648     if (pixelMap == nullptr) {
1649         MEDIA_ERR_LOG("ThumbnailListener::UpdateJSCallback surfaceBuffer is nullptr");
1650         return;
1651     }
1652     napi_value result[ARGS_TWO] = { 0 };
1653     napi_get_undefined(env_, &result[0]);
1654     napi_get_undefined(env_, &result[1]);
1655     napi_value retVal;
1656     MEDIA_INFO_LOG("enter ImageNapi::Create start");
1657     napi_value valueParam = Media::PixelMapNapi::CreatePixelMap(env_, std::move(pixelMap));
1658     if (valueParam == nullptr) {
1659         MEDIA_ERR_LOG("ImageNapi Create failed");
1660         napi_get_undefined(env_, &valueParam);
1661     }
1662     MEDIA_INFO_LOG("enter ImageNapi::Create end");
1663     result[1] = valueParam;
1664     ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
1665     ExecuteCallback(CONST_CAPTURE_QUICK_THUMBNAIL, callbackNapiPara);
1666 }
1667 
FillPixelMapWithCaptureIdAndTimestamp(napi_env env,int32_t captureId,int64_t timestamp,napi_value pixelMapNapi)1668 void FillPixelMapWithCaptureIdAndTimestamp(napi_env env, int32_t captureId, int64_t timestamp, napi_value pixelMapNapi)
1669 {
1670     napi_valuetype valueType = napi_undefined;
1671     if (napi_typeof(env, pixelMapNapi, &valueType) != napi_ok || valueType == napi_undefined) {
1672         MEDIA_ERR_LOG("FillPixelMapWithCaptureIdAndTimestamp err, pixelMapNapi is undefined = %{public}d",
1673             valueType == napi_undefined);
1674         return;
1675     }
1676     napi_value propertyName, propertyValue;
1677     napi_get_undefined(env, &propertyName);
1678     napi_get_undefined(env, &propertyValue);
1679     napi_create_string_utf8(env, "captureId", NAPI_AUTO_LENGTH, &propertyName);
1680     napi_create_int32(env, captureId, &propertyValue);
1681     napi_set_property(env, pixelMapNapi, propertyName, propertyValue);
1682     MEDIA_INFO_LOG("FillPixelMapWithCaptureIdAndTimestamp captureId %{public}d", captureId);
1683 
1684     napi_create_string_utf8(env, "timestamp", NAPI_AUTO_LENGTH, &propertyName);
1685     napi_create_int64(env, timestamp, &propertyValue);
1686     napi_set_property(env, pixelMapNapi, propertyName, propertyValue);
1687 }
1688 
UpdateJSCallback() const1689 void ThumbnailListener::UpdateJSCallback() const
1690 {
1691     auto photoOutput = photoOutput_.promote();
1692     if (photoOutput == nullptr) {
1693         MEDIA_ERR_LOG("ThumbnailListener::UpdateJSCallback photoOutput is nullptr");
1694         return;
1695     }
1696     napi_value result[ARGS_TWO] = { 0 };
1697     napi_get_undefined(env_, &result[0]);
1698     napi_get_undefined(env_, &result[1]);
1699     napi_value retVal;
1700     MEDIA_INFO_LOG("enter ImageNapi::Create start");
1701     int32_t fence = -1;
1702     int64_t timestamp;
1703     OHOS::Rect damage;
1704     sptr<SurfaceBuffer> thumbnailBuffer = nullptr;
1705     SurfaceError surfaceRet = photoOutput->thumbnailSurface_->AcquireBuffer(thumbnailBuffer, fence, timestamp, damage);
1706     if (surfaceRet != SURFACE_ERROR_OK) {
1707         MEDIA_ERR_LOG("ThumbnailListener Failed to acquire surface buffer");
1708         return;
1709     }
1710     int32_t thumbnailWidth;
1711     int32_t thumbnailHeight;
1712     thumbnailBuffer->GetExtraData()->ExtraGet(OHOS::CameraStandard::dataWidth, thumbnailWidth);
1713     thumbnailBuffer->GetExtraData()->ExtraGet(OHOS::CameraStandard::dataHeight, thumbnailHeight);
1714     int32_t captureId = GetCaptureId(thumbnailBuffer);
1715     Media::InitializationOptions opts;
1716     opts.srcPixelFormat = Media::PixelFormat::RGBA_8888;
1717     opts.pixelFormat = Media::PixelFormat::RGBA_8888;
1718     opts.size = { .width = thumbnailWidth, .height = thumbnailHeight };
1719     MEDIA_INFO_LOG("thumbnailWidth:%{public}d, thumbnailheight: %{public}d", thumbnailWidth, thumbnailHeight);
1720     const int32_t formatSize = 4;
1721     auto pixelMap = Media::PixelMap::Create(static_cast<const uint32_t*>(thumbnailBuffer->GetVirAddr()),
1722         thumbnailWidth * thumbnailHeight * formatSize, 0, thumbnailWidth, opts, true);
1723     napi_value valueParam = Media::PixelMapNapi::CreatePixelMap(env_, std::move(pixelMap));
1724     if (valueParam == nullptr) {
1725         MEDIA_ERR_LOG("ImageNapi Create failed");
1726         napi_get_undefined(env_, &valueParam);
1727     }
1728     FillPixelMapWithCaptureIdAndTimestamp(env_, captureId, timestamp, valueParam);
1729     MEDIA_INFO_LOG("enter ImageNapi::Create end");
1730     result[1] = valueParam;
1731 
1732     ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
1733     ExecuteCallback(CONST_CAPTURE_QUICK_THUMBNAIL, callbackNapiPara);
1734     photoOutput->thumbnailSurface_->ReleaseBuffer(thumbnailBuffer, -1);
1735 }
1736 
UpdateJSCallbackAsync()1737 void ThumbnailListener::UpdateJSCallbackAsync()
1738 {
1739     uv_loop_s* loop = nullptr;
1740     napi_get_uv_event_loop(env_, &loop);
1741     CHECK_ERROR_RETURN_LOG(loop == nullptr, "ThumbnailListener UpdateJSCallbackAsync failed to get event loop");
1742     uv_work_t* work = new (std::nothrow) uv_work_t;
1743     CHECK_ERROR_RETURN_LOG(work == nullptr, "ThumbnailListener UpdateJSCallbackAsync failed to allocate work");
1744     std::unique_ptr<ThumbnailListenerInfo> callbackInfo =
1745         std::make_unique<ThumbnailListenerInfo>(this, nullptr);
1746     work->data = callbackInfo.get();
1747     int ret = uv_queue_work_with_qos(
1748         loop, work, [](uv_work_t* work) {},
1749         [](uv_work_t* work, int status) {
1750             ThumbnailListenerInfo* callbackInfo = reinterpret_cast<ThumbnailListenerInfo*>(work->data);
1751             if (callbackInfo) {
1752                 auto listener = callbackInfo->listener_.promote();
1753                 if (listener != nullptr) {
1754                     listener->UpdateJSCallback();
1755                     MEDIA_INFO_LOG("ThumbnailListener:UpdateJSCallbackAsync() complete");
1756                 }
1757                 delete callbackInfo;
1758             }
1759             delete work;
1760         },
1761         uv_qos_user_initiated);
1762     if (ret) {
1763         MEDIA_ERR_LOG("ThumbnailListener:UpdateJSCallbackAsync() failed to execute work");
1764         delete work;
1765     } else {
1766         callbackInfo.release();
1767     }
1768 }
1769 
PhotoOutputNapi()1770 PhotoOutputNapi::PhotoOutputNapi() {}
1771 
~PhotoOutputNapi()1772 PhotoOutputNapi::~PhotoOutputNapi()
1773 {
1774     if (pictureListener_) {
1775         pictureListener_->gainmapImageListener = nullptr;
1776         pictureListener_->deepImageListener = nullptr;
1777         pictureListener_->exifImageListener = nullptr;
1778         pictureListener_->debugImageListener = nullptr;
1779     }
1780     pictureListener_ = nullptr;
1781     MEDIA_DEBUG_LOG("~PhotoOutputNapi is called");
1782 }
1783 
PhotoOutputNapiDestructor(napi_env env,void * nativeObject,void * finalize_hint)1784 void PhotoOutputNapi::PhotoOutputNapiDestructor(napi_env env, void* nativeObject, void* finalize_hint)
1785 {
1786     MEDIA_DEBUG_LOG("PhotoOutputNapiDestructor is called");
1787     PhotoOutputNapi* photoOutput = reinterpret_cast<PhotoOutputNapi*>(nativeObject);
1788     if (photoOutput != nullptr) {
1789         delete photoOutput;
1790     }
1791 }
1792 
Init(napi_env env,napi_value exports)1793 napi_value PhotoOutputNapi::Init(napi_env env, napi_value exports)
1794 {
1795     MEDIA_DEBUG_LOG("Init is called");
1796     napi_status status;
1797     napi_value ctorObj;
1798     int32_t refCount = 1;
1799 
1800     napi_property_descriptor photo_output_props[] = {
1801         DECLARE_NAPI_FUNCTION("isMovingPhotoSupported", IsMovingPhotoSupported),
1802         DECLARE_NAPI_FUNCTION("enableMovingPhoto", EnableMovingPhoto),
1803         DECLARE_NAPI_FUNCTION("capture", Capture),
1804         DECLARE_NAPI_FUNCTION("burstCapture", BurstCapture),
1805         DECLARE_NAPI_FUNCTION("confirmCapture", ConfirmCapture),
1806         DECLARE_NAPI_FUNCTION("release", Release),
1807         DECLARE_NAPI_FUNCTION("isMirrorSupported", IsMirrorSupported),
1808         DECLARE_NAPI_FUNCTION("enableMirror", EnableMirror),
1809         DECLARE_NAPI_FUNCTION("enableQuickThumbnail", EnableQuickThumbnail),
1810         DECLARE_NAPI_FUNCTION("isQuickThumbnailSupported", IsQuickThumbnailSupported),
1811         DECLARE_NAPI_FUNCTION("enableRawDelivery", EnableRawDelivery),
1812         DECLARE_NAPI_FUNCTION("isRawDeliverySupported", IsRawDeliverySupported),
1813         DECLARE_NAPI_FUNCTION("getSupportedMovingPhotoVideoCodecTypes", GetSupportedMovingPhotoVideoCodecTypes),
1814         DECLARE_NAPI_FUNCTION("setMovingPhotoVideoCodecType", SetMovingPhotoVideoCodecType),
1815         DECLARE_NAPI_FUNCTION("on", On),
1816         DECLARE_NAPI_FUNCTION("once", Once),
1817         DECLARE_NAPI_FUNCTION("off", Off),
1818         DECLARE_NAPI_FUNCTION("deferImageDelivery", DeferImageDeliveryFor),
1819         DECLARE_NAPI_FUNCTION("deferImageDeliveryFor", DeferImageDeliveryFor),
1820         DECLARE_NAPI_FUNCTION("isDeferredImageDeliverySupported", IsDeferredImageDeliverySupported),
1821         DECLARE_NAPI_FUNCTION("isDeferredImageDeliveryEnabled", IsDeferredImageDeliveryEnabled),
1822         DECLARE_NAPI_FUNCTION("isAutoHighQualityPhotoSupported", IsAutoHighQualityPhotoSupported),
1823         DECLARE_NAPI_FUNCTION("enableAutoHighQualityPhoto", EnableAutoHighQualityPhoto),
1824         DECLARE_NAPI_FUNCTION("getActiveProfile", GetActiveProfile),
1825         DECLARE_NAPI_FUNCTION("getPhotoRotation", GetPhotoRotation),
1826         DECLARE_NAPI_FUNCTION("isAutoCloudImageEnhancementSupported", IsAutoCloudImageEnhancementSupported),
1827         DECLARE_NAPI_FUNCTION("enableAutoCloudImageEnhancement", EnableAutoCloudImageEnhancement),
1828         DECLARE_NAPI_FUNCTION("isDepthDataDeliverySupported", IsDepthDataDeliverySupported),
1829         DECLARE_NAPI_FUNCTION("enableDepthDataDelivery", EnableDepthDataDelivery)
1830     };
1831 
1832     status = napi_define_class(env, CAMERA_PHOTO_OUTPUT_NAPI_CLASS_NAME, NAPI_AUTO_LENGTH, PhotoOutputNapiConstructor,
1833         nullptr, sizeof(photo_output_props) / sizeof(photo_output_props[PARAM0]), photo_output_props, &ctorObj);
1834     if (status == napi_ok) {
1835         status = napi_create_reference(env, ctorObj, refCount, &sConstructor_);
1836         if (status == napi_ok) {
1837             status = napi_set_named_property(env, exports, CAMERA_PHOTO_OUTPUT_NAPI_CLASS_NAME, ctorObj);
1838             if (status == napi_ok) {
1839                 return exports;
1840             }
1841         }
1842     }
1843     MEDIA_ERR_LOG("Init call Failed!");
1844     return nullptr;
1845 }
1846 
1847 // Constructor callback
PhotoOutputNapiConstructor(napi_env env,napi_callback_info info)1848 napi_value PhotoOutputNapi::PhotoOutputNapiConstructor(napi_env env, napi_callback_info info)
1849 {
1850     MEDIA_DEBUG_LOG("PhotoOutputNapiConstructor is called");
1851     napi_status status;
1852     napi_value result = nullptr;
1853     napi_value thisVar = nullptr;
1854 
1855     napi_get_undefined(env, &result);
1856     CAMERA_NAPI_GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
1857 
1858     if (status == napi_ok && thisVar != nullptr) {
1859         std::unique_ptr<PhotoOutputNapi> obj = std::make_unique<PhotoOutputNapi>();
1860         obj->photoOutput_ = sPhotoOutput_;
1861         obj->profile_ = sPhotoOutput_->GetPhotoProfile();
1862         status = napi_wrap(env, thisVar, reinterpret_cast<void*>(obj.get()),
1863 		                   PhotoOutputNapi::PhotoOutputNapiDestructor, nullptr, nullptr);
1864         if (status == napi_ok) {
1865             obj.release();
1866             return thisVar;
1867         } else {
1868             MEDIA_ERR_LOG("Failure wrapping js to native napi");
1869         }
1870     }
1871     MEDIA_ERR_LOG("PhotoOutputNapiConstructor call Failed!");
1872     return result;
1873 }
1874 
GetPhotoOutput()1875 sptr<PhotoOutput> PhotoOutputNapi::GetPhotoOutput()
1876 {
1877     return photoOutput_;
1878 }
1879 
GetEnableMirror()1880 bool PhotoOutputNapi::GetEnableMirror()
1881 {
1882     return isMirrorEnabled_;
1883 }
1884 
IsPhotoOutput(napi_env env,napi_value obj)1885 bool PhotoOutputNapi::IsPhotoOutput(napi_env env, napi_value obj)
1886 {
1887     MEDIA_DEBUG_LOG("IsPhotoOutput is called");
1888     bool result = false;
1889     napi_status status;
1890     napi_value constructor = nullptr;
1891 
1892     status = napi_get_reference_value(env, sConstructor_, &constructor);
1893     if (status == napi_ok) {
1894         status = napi_instanceof(env, obj, constructor, &result);
1895         if (status != napi_ok) {
1896             result = false;
1897         }
1898     }
1899     return result;
1900 }
1901 
CreateMultiChannelPictureLisenter(napi_env env)1902 void PhotoOutputNapi::CreateMultiChannelPictureLisenter(napi_env env)
1903 {
1904     if (pictureListener_ == nullptr) {
1905         MEDIA_INFO_LOG("new photoListener and register surface consumer listener");
1906         sptr<PictureListener> pictureListener = new (std::nothrow) PictureListener();
1907         pictureListener->InitPictureListeners(env, photoOutput_);
1908         if (photoListener_ == nullptr) {
1909             sptr<PhotoListener> photoListener = new (std::nothrow) PhotoListener(env, sPhotoSurface_, photoOutput_);
1910             SurfaceError ret = sPhotoSurface_->RegisterConsumerListener((sptr<IBufferConsumerListener>&)photoListener);
1911             if (ret != SURFACE_ERROR_OK) {
1912                 MEDIA_ERR_LOG("register surface consumer listener failed!");
1913             }
1914             photoListener_ = photoListener;
1915             pictureListener_ = pictureListener;
1916         }
1917         if (photoOutput_->taskManager_ == nullptr) {
1918             constexpr int32_t auxiliaryPictureCount = 4;
1919             photoOutput_->taskManager_ = std::make_shared<DeferredProcessing::TaskManager>("AuxilaryPictureListener",
1920                 auxiliaryPictureCount, false);
1921         }
1922     }
1923 }
1924 
CreateSingleChannelPhotoLisenter(napi_env env)1925 void PhotoOutputNapi::CreateSingleChannelPhotoLisenter(napi_env env)
1926 {
1927     if (photoListener_ == nullptr) {
1928         MEDIA_INFO_LOG("new photoListener and register surface consumer listener");
1929         sptr<PhotoListener> photoListener = new (std::nothrow) PhotoListener(env, sPhotoSurface_, photoOutput_);
1930         SurfaceError ret = sPhotoSurface_->RegisterConsumerListener((sptr<IBufferConsumerListener>&)photoListener);
1931         if (ret != SURFACE_ERROR_OK) {
1932             MEDIA_ERR_LOG("register surface consumer listener failed!");
1933         }
1934         photoListener_ = photoListener;
1935     }
1936 }
1937 
CreatePhotoOutput(napi_env env,Profile & profile,std::string surfaceId)1938 napi_value PhotoOutputNapi::CreatePhotoOutput(napi_env env, Profile& profile, std::string surfaceId)
1939 {
1940     MEDIA_DEBUG_LOG("CreatePhotoOutput is called, profile CameraFormat= %{public}d", profile.GetCameraFormat());
1941     CAMERA_SYNC_TRACE;
1942     napi_value result = nullptr;
1943     napi_get_undefined(env, &result);
1944     napi_value constructor;
1945     napi_status status = napi_get_reference_value(env, sConstructor_, &constructor);
1946     if (status == napi_ok) {
1947         MEDIA_INFO_LOG("CreatePhotoOutput surfaceId: %{public}s", surfaceId.c_str());
1948         sptr<Surface> photoSurface;
1949         if (surfaceId == "") {
1950             MEDIA_INFO_LOG("create surface as consumer");
1951             photoSurface = Surface::CreateSurfaceAsConsumer("photoOutput");
1952             sPhotoSurface_ = photoSurface;
1953         } else {
1954             MEDIA_INFO_LOG("get surface by surfaceId");
1955             photoSurface = Media::ImageReceiver::getSurfaceById(surfaceId);
1956         }
1957         if (photoSurface == nullptr) {
1958             MEDIA_ERR_LOG("failed to get surface");
1959             return result;
1960         }
1961         photoSurface->SetUserData(CameraManager::surfaceFormat, std::to_string(profile.GetCameraFormat()));
1962         sptr<IBufferProducer> surfaceProducer = photoSurface->GetProducer();
1963         MEDIA_INFO_LOG("profile width: %{public}d, height: %{public}d, format = %{public}d, "
1964                        "surface width: %{public}d, height: %{public}d", profile.GetSize().width,
1965                        profile.GetSize().height, static_cast<int32_t>(profile.GetCameraFormat()),
1966                        photoSurface->GetDefaultWidth(), photoSurface->GetDefaultHeight());
1967         int retCode = CameraManager::GetInstance()->CreatePhotoOutput(profile, surfaceProducer, &sPhotoOutput_);
1968         if (!CameraNapiUtils::CheckError(env, retCode) || sPhotoOutput_ == nullptr) {
1969             MEDIA_ERR_LOG("failed to create CreatePhotoOutput");
1970             return result;
1971         }
1972         if (surfaceId == "") {
1973             sPhotoOutput_->SetNativeSurface(true);
1974         }
1975         if (sPhotoOutput_->IsYuvOrHeifPhoto()) {
1976             sPhotoOutput_->CreateMultiChannel();
1977         }
1978         status = napi_new_instance(env, constructor, 0, nullptr, &result);
1979         sPhotoOutput_ = nullptr;
1980         if (status == napi_ok && result != nullptr) {
1981             MEDIA_INFO_LOG("Success to create photo output instance");
1982             return result;
1983         }
1984     }
1985     MEDIA_ERR_LOG("CreatePhotoOutput call Failed!");
1986     return result;
1987 }
1988 
CreatePhotoOutput(napi_env env,std::string surfaceId)1989 napi_value PhotoOutputNapi::CreatePhotoOutput(napi_env env, std::string surfaceId)
1990 {
1991     MEDIA_INFO_LOG("CreatePhotoOutput with only surfaceId is called");
1992     CAMERA_SYNC_TRACE;
1993     napi_status status;
1994     napi_value result = nullptr;
1995     napi_value constructor;
1996     napi_get_undefined(env, &result);
1997     status = napi_get_reference_value(env, sConstructor_, &constructor);
1998     if (status == napi_ok) {
1999         MEDIA_INFO_LOG("CreatePhotoOutput surfaceId: %{public}s", surfaceId.c_str());
2000         sptr<Surface> photoSurface;
2001         if (surfaceId == "") {
2002             MEDIA_INFO_LOG("create surface as consumer");
2003             photoSurface = Surface::CreateSurfaceAsConsumer("photoOutput");
2004             sPhotoSurface_ = photoSurface;
2005         } else {
2006             MEDIA_INFO_LOG("get surface by surfaceId");
2007             photoSurface = Media::ImageReceiver::getSurfaceById(surfaceId);
2008         }
2009         if (photoSurface == nullptr) {
2010             MEDIA_ERR_LOG("failed to get surface");
2011             return result;
2012         }
2013         sptr<IBufferProducer> surfaceProducer = photoSurface->GetProducer();
2014         MEDIA_INFO_LOG("surface width: %{public}d, height: %{public}d", photoSurface->GetDefaultWidth(),
2015             photoSurface->GetDefaultHeight());
2016         int retCode = CameraManager::GetInstance()->CreatePhotoOutputWithoutProfile(surfaceProducer, &sPhotoOutput_);
2017         if (!CameraNapiUtils::CheckError(env, retCode) || sPhotoOutput_ == nullptr) {
2018             MEDIA_ERR_LOG("failed to create CreatePhotoOutput");
2019             return result;
2020         }
2021         if (surfaceId == "") {
2022             sPhotoOutput_->SetNativeSurface(true);
2023         }
2024         status = napi_new_instance(env, constructor, 0, nullptr, &result);
2025         sPhotoOutput_ = nullptr;
2026         if (status == napi_ok && result != nullptr) {
2027             MEDIA_DEBUG_LOG("Success to create photo output instance");
2028             return result;
2029         }
2030     }
2031     MEDIA_ERR_LOG("CreatePhotoOutput call Failed!");
2032     return result;
2033 }
2034 
ParseCaptureSettings(napi_env env,napi_callback_info info,PhotoOutputAsyncContext * asyncContext,std::shared_ptr<CameraNapiAsyncFunction> & asyncFunction,bool isSettingOptional)2035 bool ParseCaptureSettings(napi_env env, napi_callback_info info, PhotoOutputAsyncContext* asyncContext,
2036     std::shared_ptr<CameraNapiAsyncFunction>& asyncFunction, bool isSettingOptional)
2037 {
2038     Location settingsLocation;
2039     CameraNapiObject settingsLocationNapiOjbect { {
2040         { "latitude", &settingsLocation.latitude },
2041         { "longitude", &settingsLocation.longitude },
2042         { "altitude", &settingsLocation.altitude },
2043     } };
2044     CameraNapiObject settingsNapiOjbect { {
2045         { "quality", &asyncContext->quality },
2046         { "rotation", &asyncContext->rotation },
2047         { "location", &settingsLocationNapiOjbect },
2048         { "mirror", &asyncContext->isMirror },
2049     } };
2050     unordered_set<std::string> optionalKeys = { "quality", "rotation", "location", "mirror" };
2051     settingsNapiOjbect.SetOptionalKeys(optionalKeys);
2052 
2053     asyncFunction =
2054         std::make_shared<CameraNapiAsyncFunction>(env, "Capture", asyncContext->callbackRef, asyncContext->deferred);
2055     CameraNapiParamParser jsParamParser(env, info, asyncContext->objectInfo, asyncFunction, settingsNapiOjbect);
2056     if (jsParamParser.IsStatusOk()) {
2057         if (settingsNapiOjbect.IsKeySetted("quality") && !ValidQualityLevelFromJs(asyncContext->quality)) {
2058             CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "quality field not legal");
2059             return false;
2060         }
2061         if (settingsNapiOjbect.IsKeySetted("rotation") && !ValidImageRotationFromJs(asyncContext->rotation)) {
2062             CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "rotation field not legal");
2063             return false;
2064         }
2065         if (settingsNapiOjbect.IsKeySetted("mirror") && asyncContext->isMirror) {
2066             MEDIA_INFO_LOG("GetMirrorStatus is ok!");
2067             asyncContext->isMirrorSettedByUser = true;
2068         }
2069         MEDIA_INFO_LOG("ParseCaptureSettings with capture settings pass");
2070         asyncContext->hasPhotoSettings = true;
2071         if (settingsNapiOjbect.IsKeySetted("location")) {
2072             asyncContext->location = std::make_shared<Location>(settingsLocation);
2073         }
2074     } else if (isSettingOptional) {
2075         MEDIA_WARNING_LOG("ParseCaptureSettings check capture settings fail, try capture without settings");
2076         jsParamParser = CameraNapiParamParser(env, info, asyncContext->objectInfo, asyncFunction);
2077     } else {
2078         // Do nothing.
2079     }
2080     if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "invalid argument")) {
2081         MEDIA_ERR_LOG("ParseCaptureSettings invalid argument");
2082         return false;
2083     }
2084     asyncContext->HoldNapiValue(env, jsParamParser.GetThisVar());
2085     return true;
2086 }
2087 
Capture(napi_env env,napi_callback_info info)2088 napi_value PhotoOutputNapi::Capture(napi_env env, napi_callback_info info)
2089 {
2090     MEDIA_INFO_LOG("Capture is called");
2091     std::unique_ptr<PhotoOutputAsyncContext> asyncContext = std::make_unique<PhotoOutputAsyncContext>(
2092         "PhotoOutputNapi::Capture", CameraNapiUtils::IncrementAndGet(photoOutputTaskId));
2093     std::shared_ptr<CameraNapiAsyncFunction> asyncFunction;
2094     if (!ParseCaptureSettings(env, info, asyncContext.get(), asyncFunction, true)) {
2095         MEDIA_ERR_LOG("PhotoOutputNapi::Capture parse parameters fail.");
2096         return nullptr;
2097     }
2098     napi_status status = napi_create_async_work(
2099         env, nullptr, asyncFunction->GetResourceName(),
2100         [](napi_env env, void* data) {
2101             MEDIA_INFO_LOG("PhotoOutputNapi::Capture running on worker");
2102             auto context = static_cast<PhotoOutputAsyncContext*>(data);
2103             CHECK_ERROR_RETURN_LOG(context->objectInfo == nullptr, "PhotoOutputNapi::Capture async info is nullptr");
2104             CAMERA_START_ASYNC_TRACE(context->funcName, context->taskId);
2105             CameraNapiWorkerQueueKeeper::GetInstance()->ConsumeWorkerQueueTask(
2106                 context->queueTask, [&context]() { ProcessCapture(context, false); });
2107         },
2108         AsyncCompleteCallback, static_cast<void*>(asyncContext.get()), &asyncContext->work);
2109     if (status != napi_ok) {
2110         MEDIA_ERR_LOG("Failed to create napi_create_async_work for PhotoOutputNapi::Capture");
2111         asyncFunction->Reset();
2112     } else {
2113         asyncContext->queueTask =
2114             CameraNapiWorkerQueueKeeper::GetInstance()->AcquireWorkerQueueTask("PhotoOutputNapi::Capture");
2115         napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
2116         asyncContext.release();
2117     }
2118     if (asyncFunction->GetAsyncFunctionType() == ASYNC_FUN_TYPE_PROMISE) {
2119         return asyncFunction->GetPromise();
2120     }
2121     return CameraNapiUtils::GetUndefinedValue(env);
2122 }
2123 
BurstCapture(napi_env env,napi_callback_info info)2124 napi_value PhotoOutputNapi::BurstCapture(napi_env env, napi_callback_info info)
2125 {
2126     MEDIA_INFO_LOG("BurstCapture is called");
2127     if (!CameraNapiSecurity::CheckSystemApp(env)) {
2128         MEDIA_ERR_LOG("SystemApi EnableAutoHighQualityPhoto is called!");
2129         return nullptr;
2130     }
2131 
2132     std::unique_ptr<PhotoOutputAsyncContext> asyncContext = std::make_unique<PhotoOutputAsyncContext>(
2133         "PhotoOutputNapi::BurstCapture", CameraNapiUtils::IncrementAndGet(photoOutputTaskId));
2134     std::shared_ptr<CameraNapiAsyncFunction> asyncFunction;
2135     if (!ParseCaptureSettings(env, info, asyncContext.get(), asyncFunction, false)) {
2136         MEDIA_ERR_LOG("PhotoOutputNapi::BurstCapture parse parameters fail.");
2137         return nullptr;
2138     }
2139     napi_status status = napi_create_async_work(
2140         env, nullptr, asyncFunction->GetResourceName(),
2141         [](napi_env env, void* data) {
2142             MEDIA_INFO_LOG("PhotoOutputNapi::BurstCapture running on worker");
2143             auto context = static_cast<PhotoOutputAsyncContext*>(data);
2144             CHECK_ERROR_RETURN_LOG(
2145                 context->objectInfo == nullptr, "PhotoOutputNapi::BurstCapture async info is nullptr");
2146             CAMERA_START_ASYNC_TRACE(context->funcName, context->taskId);
2147             CameraNapiWorkerQueueKeeper::GetInstance()->ConsumeWorkerQueueTask(
2148                 context->queueTask, [&context]() { ProcessCapture(context, true); });
2149         },
2150         AsyncCompleteCallback, static_cast<void*>(asyncContext.get()), &asyncContext->work);
2151     if (status != napi_ok) {
2152         MEDIA_ERR_LOG("Failed to create napi_create_async_work for PhotoOutputNapi::BurstCapture");
2153         asyncFunction->Reset();
2154     } else {
2155         asyncContext->queueTask =
2156             CameraNapiWorkerQueueKeeper::GetInstance()->AcquireWorkerQueueTask("PhotoOutputNapi::BurstCapture");
2157         napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
2158         asyncContext.release();
2159     }
2160     if (asyncFunction->GetAsyncFunctionType() == ASYNC_FUN_TYPE_PROMISE) {
2161         return asyncFunction->GetPromise();
2162     }
2163     return CameraNapiUtils::GetUndefinedValue(env);
2164 }
2165 
ConfirmCapture(napi_env env,napi_callback_info info)2166 napi_value PhotoOutputNapi::ConfirmCapture(napi_env env, napi_callback_info info)
2167 {
2168     MEDIA_INFO_LOG("ConfirmCapture is called");
2169     napi_status status;
2170     napi_value result = nullptr;
2171     size_t argc = ARGS_ZERO;
2172     napi_value argv[ARGS_ZERO] = {};
2173     napi_value thisVar = nullptr;
2174 
2175     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
2176 
2177     napi_get_undefined(env, &result);
2178     PhotoOutputNapi* photoOutputNapi = nullptr;
2179     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
2180     if (status == napi_ok && photoOutputNapi != nullptr) {
2181         int32_t retCode = photoOutputNapi->photoOutput_->ConfirmCapture();
2182         if (!CameraNapiUtils::CheckError(env, retCode)) {
2183             return result;
2184         }
2185     }
2186     return result;
2187 }
2188 
Release(napi_env env,napi_callback_info info)2189 napi_value PhotoOutputNapi::Release(napi_env env, napi_callback_info info)
2190 {
2191     MEDIA_INFO_LOG("Release is called");
2192     std::unique_ptr<PhotoOutputAsyncContext> asyncContext = std::make_unique<PhotoOutputAsyncContext>(
2193         "PhotoOutputNapi::Release", CameraNapiUtils::IncrementAndGet(photoOutputTaskId));
2194     auto asyncFunction =
2195         std::make_shared<CameraNapiAsyncFunction>(env, "Release", asyncContext->callbackRef, asyncContext->deferred);
2196     CameraNapiParamParser jsParamParser(env, info, asyncContext->objectInfo, asyncFunction);
2197     if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "invalid argument")) {
2198         MEDIA_ERR_LOG("PhotoOutputNapi::Release invalid argument");
2199         return nullptr;
2200     }
2201     asyncContext->HoldNapiValue(env, jsParamParser.GetThisVar());
2202     napi_status status = napi_create_async_work(
2203         env, nullptr, asyncFunction->GetResourceName(),
2204         [](napi_env env, void* data) {
2205             MEDIA_INFO_LOG("PhotoOutputNapi::Release running on worker");
2206             auto context = static_cast<PhotoOutputAsyncContext*>(data);
2207             CHECK_ERROR_RETURN_LOG(context->objectInfo == nullptr, "PhotoOutputNapi::Release async info is nullptr");
2208             CAMERA_START_ASYNC_TRACE(context->funcName, context->taskId);
2209             CameraNapiWorkerQueueKeeper::GetInstance()->ConsumeWorkerQueueTask(context->queueTask, [&context]() {
2210                 context->errorCode = context->objectInfo->photoOutput_->Release();
2211                 context->status = context->errorCode == CameraErrorCode::SUCCESS;
2212             });
2213         },
2214         AsyncCompleteCallback, static_cast<void*>(asyncContext.get()), &asyncContext->work);
2215     if (status != napi_ok) {
2216         MEDIA_ERR_LOG("Failed to create napi_create_async_work for PhotoOutputNapi::Release");
2217         asyncFunction->Reset();
2218     } else {
2219         asyncContext->queueTask =
2220             CameraNapiWorkerQueueKeeper::GetInstance()->AcquireWorkerQueueTask("PhotoOutputNapi::Release");
2221         napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
2222         asyncContext.release();
2223     }
2224     if (asyncFunction->GetAsyncFunctionType() == ASYNC_FUN_TYPE_PROMISE) {
2225         return asyncFunction->GetPromise();
2226     }
2227     return CameraNapiUtils::GetUndefinedValue(env);
2228 }
2229 
IsMirrorSupported(napi_env env,napi_callback_info info)2230 napi_value PhotoOutputNapi::IsMirrorSupported(napi_env env, napi_callback_info info)
2231 {
2232     MEDIA_INFO_LOG("IsMirrorSupported is called");
2233     napi_status status;
2234     napi_value result = nullptr;
2235     size_t argc = ARGS_ZERO;
2236     napi_value argv[ARGS_ZERO];
2237     napi_value thisVar = nullptr;
2238 
2239     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
2240 
2241     napi_get_undefined(env, &result);
2242     PhotoOutputNapi* photoOutputNapi = nullptr;
2243     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
2244     if (status == napi_ok && photoOutputNapi != nullptr) {
2245         bool isSupported = photoOutputNapi->photoOutput_->IsMirrorSupported();
2246         napi_get_boolean(env, isSupported, &result);
2247     } else {
2248         MEDIA_ERR_LOG("IsMirrorSupported call Failed!");
2249     }
2250     return result;
2251 }
2252 
EnableMirror(napi_env env,napi_callback_info info)2253 napi_value PhotoOutputNapi::EnableMirror(napi_env env, napi_callback_info info)
2254 {
2255     auto result = CameraNapiUtils::GetUndefinedValue(env);
2256     MEDIA_DEBUG_LOG("PhotoOutputNapi::EnableMirror is called");
2257     PhotoOutputNapi* photoOutputNapi = nullptr;
2258     bool isMirror = false;
2259     CameraNapiParamParser jsParamParser(env, info, photoOutputNapi, isMirror);
2260     if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "invalid argument")) {
2261         MEDIA_ERR_LOG("PhotoOutputNapi::EnableMirror invalid argument");
2262         return nullptr;
2263     }
2264     auto session = photoOutputNapi->GetPhotoOutput()->GetSession();
2265     if (session != nullptr) {
2266         photoOutputNapi->isMirrorEnabled_ = isMirror;
2267         int32_t retCode = photoOutputNapi->photoOutput_->EnableMirror(isMirror);
2268         if (!CameraNapiUtils::CheckError(env, retCode)) {
2269             return result;
2270         }
2271     }
2272     return result;
2273 }
2274 
IsQuickThumbnailSupported(napi_env env,napi_callback_info info)2275 napi_value PhotoOutputNapi::IsQuickThumbnailSupported(napi_env env, napi_callback_info info)
2276 {
2277     if (!CameraNapiSecurity::CheckSystemApp(env)) {
2278         MEDIA_ERR_LOG("SystemApi IsQuickThumbnailSupported is called!");
2279         return nullptr;
2280     }
2281     napi_status status;
2282     napi_value result = nullptr;
2283     size_t argc = ARGS_ZERO;
2284     napi_value argv[ARGS_ZERO];
2285     napi_value thisVar = nullptr;
2286 
2287     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
2288 
2289     napi_get_undefined(env, &result);
2290     PhotoOutputNapi* photoOutputNapi = nullptr;
2291     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
2292     if (status == napi_ok && photoOutputNapi != nullptr) {
2293         int32_t retCode = photoOutputNapi->photoOutput_->IsQuickThumbnailSupported();
2294         bool isSupported = (retCode == 0);
2295         if (retCode > 0 && !CameraNapiUtils::CheckError(env, retCode)) {
2296             return result;
2297         }
2298         napi_get_boolean(env, isSupported, &result);
2299     }
2300     return result;
2301 }
2302 
DeferImageDeliveryFor(napi_env env,napi_callback_info info)2303 napi_value PhotoOutputNapi::DeferImageDeliveryFor(napi_env env, napi_callback_info info)
2304 {
2305     if (!CameraNapiSecurity::CheckSystemApp(env)) {
2306         MEDIA_ERR_LOG("SystemApi DeferImageDeliveryFor is called!");
2307         return nullptr;
2308     }
2309     napi_status status;
2310     napi_value result = nullptr;
2311     size_t argc = ARGS_ONE;
2312     napi_value argv[ARGS_ONE] = {0};
2313     napi_value thisVar = nullptr;
2314     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
2315     NAPI_ASSERT(env, argc == ARGS_ONE, "requires one parameter");
2316     napi_get_undefined(env, &result);
2317     PhotoOutputNapi* photoOutputNapi = nullptr;
2318     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
2319     if (status == napi_ok && photoOutputNapi != nullptr) {
2320         int32_t deliveryType;
2321         napi_get_value_int32(env, argv[PARAM0], &deliveryType);
2322         photoOutputNapi->photoOutput_->DeferImageDeliveryFor(static_cast<DeferredDeliveryImageType>(deliveryType));
2323         photoOutputNapi->isDeferredPhotoEnabled_ = deliveryType == DELIVERY_PHOTO;
2324     }
2325     return result;
2326 }
2327 
IsDeferredImageDeliverySupported(napi_env env,napi_callback_info info)2328 napi_value PhotoOutputNapi::IsDeferredImageDeliverySupported(napi_env env, napi_callback_info info)
2329 {
2330     if (!CameraNapiSecurity::CheckSystemApp(env)) {
2331         MEDIA_ERR_LOG("SystemApi IsDeferredImageDeliverySupported is called!");
2332         return nullptr;
2333     }
2334     napi_status status;
2335     napi_value result = nullptr;
2336     size_t argc = ARGS_ONE;
2337     napi_value argv[ARGS_ONE] = {0};
2338     napi_value thisVar = nullptr;
2339     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
2340     NAPI_ASSERT(env, argc == ARGS_ONE, "requires one parameter");
2341     napi_get_undefined(env, &result);
2342     PhotoOutputNapi* photoOutputNapi = nullptr;
2343     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
2344     if (status == napi_ok && photoOutputNapi != nullptr) {
2345         int32_t deliveryType;
2346         napi_get_value_int32(env, argv[PARAM0], &deliveryType);
2347         int32_t retCode = photoOutputNapi->photoOutput_->IsDeferredImageDeliverySupported(
2348             static_cast<DeferredDeliveryImageType>(deliveryType));
2349         bool isSupported = (retCode == 0);
2350         if (retCode > 0 && !CameraNapiUtils::CheckError(env, retCode)) {
2351             return result;
2352         }
2353         napi_get_boolean(env, isSupported, &result);
2354     }
2355     return result;
2356 }
2357 
GetPhotoRotation(napi_env env,napi_callback_info info)2358 napi_value PhotoOutputNapi::GetPhotoRotation(napi_env env, napi_callback_info info)
2359 {
2360     MEDIA_DEBUG_LOG("GetPhotoRotation is called!");
2361     napi_status status;
2362     napi_value result = nullptr;
2363     size_t argc = ARGS_ONE;
2364     napi_value argv[ARGS_ONE] = {0};
2365     napi_value thisVar = nullptr;
2366     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
2367 
2368     napi_get_undefined(env, &result);
2369     PhotoOutputNapi* photoOutputNapi = nullptr;
2370     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
2371     if (status == napi_ok && photoOutputNapi != nullptr) {
2372         int32_t value;
2373         napi_status ret = napi_get_value_int32(env, argv[PARAM0], &value);
2374         if (ret != napi_ok) {
2375             CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT,
2376                 "GetPhotoRotation parameter missing or parameter type incorrect.");
2377             return result;
2378         }
2379         int32_t retCode = photoOutputNapi->photoOutput_->GetPhotoRotation(value);
2380         if (retCode == SERVICE_FATL_ERROR) {
2381             CameraNapiUtils::ThrowError(env, SERVICE_FATL_ERROR,
2382                 "GetPhotoRotation Camera service fatal error.");
2383             return result;
2384         }
2385         napi_create_int32(env, retCode, &result);
2386         MEDIA_INFO_LOG("PhotoOutputNapi GetPhotoRotation! %{public}d", retCode);
2387     } else {
2388         MEDIA_ERR_LOG("PhotoOutputNapi GetPhotoRotation! called failed!");
2389     }
2390     return result;
2391 }
2392 
IsDeferredImageDeliveryEnabled(napi_env env,napi_callback_info info)2393 napi_value PhotoOutputNapi::IsDeferredImageDeliveryEnabled(napi_env env, napi_callback_info info)
2394 {
2395     if (!CameraNapiSecurity::CheckSystemApp(env)) {
2396         MEDIA_ERR_LOG("SystemApi IsDeferredImageDeliveryEnabled is called!");
2397         return nullptr;
2398     }
2399     napi_status status;
2400     napi_value result = nullptr;
2401     size_t argc = ARGS_ONE;
2402     napi_value argv[ARGS_ONE] = {0};
2403     napi_value thisVar = nullptr;
2404     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
2405     NAPI_ASSERT(env, argc == ARGS_ONE, "requires one parameter");
2406     napi_get_undefined(env, &result);
2407     PhotoOutputNapi* photoOutputNapi = nullptr;
2408     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
2409     if (status == napi_ok && photoOutputNapi != nullptr) {
2410         int32_t deliveryType;
2411         napi_get_value_int32(env, argv[PARAM0], &deliveryType);
2412         int32_t retCode = photoOutputNapi->photoOutput_->IsDeferredImageDeliveryEnabled(
2413             static_cast<DeferredDeliveryImageType>(deliveryType));
2414         bool isSupported = (retCode == 0);
2415         if (retCode > 0 && !CameraNapiUtils::CheckError(env, retCode)) {
2416             return result;
2417         }
2418         napi_get_boolean(env, isSupported, &result);
2419     }
2420     return result;
2421 }
2422 
IsMovingPhotoSupported(napi_env env,napi_callback_info info)2423 napi_value PhotoOutputNapi::IsMovingPhotoSupported(napi_env env, napi_callback_info info)
2424 {
2425     MEDIA_DEBUG_LOG("IsMotionPhotoSupported is called");
2426     napi_status status;
2427     napi_value result = nullptr;
2428     size_t argc = ARGS_ZERO;
2429     napi_value argv[ARGS_ZERO];
2430     napi_value thisVar = nullptr;
2431 
2432     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
2433 
2434     napi_get_undefined(env, &result);
2435     PhotoOutputNapi* photoOutputNapi = nullptr;
2436     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
2437     if (status != napi_ok || photoOutputNapi == nullptr) {
2438         MEDIA_ERR_LOG("IsMotionPhotoSupported photoOutputNapi is null!");
2439         return result;
2440     }
2441     auto session = photoOutputNapi->GetPhotoOutput()->GetSession();
2442     if (session != nullptr) {
2443         bool isSupported = session->IsMovingPhotoSupported();
2444         napi_get_boolean(env, isSupported, &result);
2445     } else {
2446         napi_get_boolean(env, false, &result);
2447         MEDIA_ERR_LOG("IsMotionPhotoSupported call Failed!");
2448     }
2449     return result;
2450 }
2451 
EnableMovingPhoto(napi_env env,napi_callback_info info)2452 napi_value PhotoOutputNapi::EnableMovingPhoto(napi_env env, napi_callback_info info)
2453 {
2454     MEDIA_DEBUG_LOG("enableMovingPhoto is called");
2455     napi_status status;
2456     napi_value result = nullptr;
2457     size_t argc = ARGS_ONE;
2458     napi_value argv[ARGS_ONE] = { 0 };
2459     napi_value thisVar = nullptr;
2460     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
2461     NAPI_ASSERT(env, argc == ARGS_ONE, "requires one parameter");
2462     napi_valuetype valueType = napi_undefined;
2463     napi_typeof(env, argv[0], &valueType);
2464     if (valueType != napi_boolean && !CameraNapiUtils::CheckError(env, INVALID_ARGUMENT)) {
2465         return result;
2466     }
2467     napi_get_undefined(env, &result);
2468     PhotoOutputNapi* photoOutputNapi = nullptr;
2469     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
2470     if (status != napi_ok || photoOutputNapi == nullptr) {
2471         MEDIA_ERR_LOG("EnableMovingPhoto photoOutputNapi is null!");
2472         return result;
2473     }
2474     auto session = photoOutputNapi->GetPhotoOutput()->GetSession();
2475     if (session != nullptr) {
2476         bool isEnableMovingPhoto;
2477         napi_get_value_bool(env, argv[PARAM0], &isEnableMovingPhoto);
2478         session->LockForControl();
2479         int32_t retCode = session->EnableMovingPhoto(isEnableMovingPhoto);
2480         session->UnlockForControl();
2481         if (retCode != 0 && !CameraNapiUtils::CheckError(env, retCode)) {
2482             return result;
2483         }
2484     }
2485     return result;
2486 }
2487 
GetSupportedMovingPhotoVideoCodecTypes(napi_env env,napi_callback_info info)2488 napi_value PhotoOutputNapi::GetSupportedMovingPhotoVideoCodecTypes(napi_env env, napi_callback_info info)
2489 {
2490     MEDIA_DEBUG_LOG("IsMotionPhotoSupported is called");
2491     napi_status status;
2492     napi_value result = nullptr;
2493     size_t argc = ARGS_ZERO;
2494     napi_value argv[ARGS_ZERO];
2495     napi_value thisVar = nullptr;
2496 
2497     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
2498 
2499     napi_get_undefined(env, &result);
2500     PhotoOutputNapi* photoOutputNapi = nullptr;
2501     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
2502     if (status != napi_ok || photoOutputNapi == nullptr) {
2503         MEDIA_ERR_LOG("IsMotionPhotoSupported photoOutputNapi is null!");
2504         return result;
2505     }
2506     vector<int32_t> videoCodecTypes = {VideoCodecType::VIDEO_ENCODE_TYPE_AVC, VideoCodecType::VIDEO_ENCODE_TYPE_HEVC};
2507     result = CameraNapiUtils::CreateJSArray(env, status, videoCodecTypes);
2508     if (status != napi_ok) {
2509         result = CameraNapiUtils::CreateJSArray(env, status, {});
2510     }
2511     return result;
2512 }
2513 
SetMovingPhotoVideoCodecType(napi_env env,napi_callback_info info)2514 napi_value PhotoOutputNapi::SetMovingPhotoVideoCodecType(napi_env env, napi_callback_info info)
2515 {
2516     MEDIA_DEBUG_LOG("SetMovingPhotoVideoCodecType is called");
2517     napi_status status;
2518     napi_value result = nullptr;
2519     size_t argc = ARGS_ONE;
2520     napi_value argv[ARGS_ONE] = { 0 };
2521     napi_value thisVar = nullptr;
2522     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
2523     NAPI_ASSERT(env, argc == ARGS_ONE, "requires one parameter");
2524     napi_valuetype valueType = napi_undefined;
2525     napi_typeof(env, argv[0], &valueType);
2526     if (valueType != napi_number && !CameraNapiUtils::CheckError(env, INVALID_ARGUMENT)) {
2527         return result;
2528     }
2529     napi_get_undefined(env, &result);
2530     PhotoOutputNapi* photoOutputNapi = nullptr;
2531     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
2532     if (status != napi_ok || photoOutputNapi == nullptr) {
2533         MEDIA_ERR_LOG("SetMovingPhotoVideoCodecType photoOutputNapi is null!");
2534         return result;
2535     }
2536     if (photoOutputNapi->GetPhotoOutput() != nullptr) {
2537         int32_t codecType;
2538         napi_get_value_int32(env, argv[PARAM0], &codecType);
2539         int32_t retCode = photoOutputNapi->GetPhotoOutput()->SetMovingPhotoVideoCodecType(codecType);
2540         if (retCode != 0 && !CameraNapiUtils::CheckError(env, retCode)) {
2541             return result;
2542         }
2543     }
2544     return result;
2545 }
2546 
EnableQuickThumbnail(napi_env env,napi_callback_info info)2547 napi_value PhotoOutputNapi::EnableQuickThumbnail(napi_env env, napi_callback_info info)
2548 {
2549     if (!CameraNapiSecurity::CheckSystemApp(env)) {
2550         MEDIA_ERR_LOG("SystemApi EnableQuickThumbnail is called!");
2551         return nullptr;
2552     }
2553     napi_status status;
2554     napi_value result = nullptr;
2555     size_t argc = ARGS_ONE;
2556     napi_value argv[ARGS_ONE] = { 0 };
2557     napi_value thisVar = nullptr;
2558     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
2559     NAPI_ASSERT(env, argc == ARGS_ONE, "requires one parameter");
2560     napi_valuetype valueType = napi_undefined;
2561     napi_typeof(env, argv[0], &valueType);
2562     if (valueType != napi_boolean && !CameraNapiUtils::CheckError(env, INVALID_ARGUMENT)) {
2563         return result;
2564     }
2565     napi_get_undefined(env, &result);
2566     PhotoOutputNapi* photoOutputNapi = nullptr;
2567     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
2568     bool thumbnailSwitch;
2569     if (status == napi_ok && photoOutputNapi != nullptr) {
2570         napi_get_value_bool(env, argv[PARAM0], &thumbnailSwitch);
2571         photoOutputNapi->isQuickThumbnailEnabled_ = thumbnailSwitch;
2572         int32_t retCode = photoOutputNapi->photoOutput_->SetThumbnail(thumbnailSwitch);
2573         if (retCode != 0 && !CameraNapiUtils::CheckError(env, retCode)) {
2574             return result;
2575         }
2576     }
2577     return result;
2578 }
2579 
IsRawDeliverySupported(napi_env env,napi_callback_info info)2580 napi_value PhotoOutputNapi::IsRawDeliverySupported(napi_env env, napi_callback_info info)
2581 {
2582     if (!CameraNapiSecurity::CheckSystemApp(env)) {
2583         MEDIA_ERR_LOG("SystemApi IsRawDeliverySupported is called!");
2584         return nullptr;
2585     }
2586     napi_status status;
2587     napi_value result = nullptr;
2588     size_t argc = ARGS_ZERO;
2589     napi_value argv[ARGS_ZERO];
2590     napi_value thisVar = nullptr;
2591 
2592     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
2593 
2594     napi_get_undefined(env, &result);
2595     bool isSupported = false;
2596     PhotoOutputNapi* photoOutputNapi = nullptr;
2597     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
2598     if (status == napi_ok && photoOutputNapi != nullptr) {
2599         int32_t retCode = photoOutputNapi->photoOutput_->IsRawDeliverySupported();
2600         isSupported = (retCode == 1);
2601     }
2602     napi_get_boolean(env, isSupported, &result);
2603     return result;
2604 }
2605 
EnableRawDelivery(napi_env env,napi_callback_info info)2606 napi_value PhotoOutputNapi::EnableRawDelivery(napi_env env, napi_callback_info info)
2607 {
2608     if (!CameraNapiSecurity::CheckSystemApp(env)) {
2609         MEDIA_ERR_LOG("SystemApi EnableRawDelivery is called!");
2610         return nullptr;
2611     }
2612     napi_status status;
2613     napi_value result = nullptr;
2614     size_t argc = ARGS_ONE;
2615     napi_value argv[ARGS_ONE] = { 0 };
2616     napi_value thisVar = nullptr;
2617     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
2618     NAPI_ASSERT(env, argc == ARGS_ONE, "requires one parameter");
2619     napi_valuetype valueType = napi_undefined;
2620     napi_typeof(env, argv[0], &valueType);
2621     if (valueType != napi_boolean && !CameraNapiUtils::CheckError(env, INVALID_ARGUMENT)) {
2622         return result;
2623     }
2624     napi_get_undefined(env, &result);
2625     PhotoOutputNapi* photoOutputNapi = nullptr;
2626     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
2627     bool rawDeliverySwitch;
2628     if (status == napi_ok && photoOutputNapi != nullptr) {
2629         napi_get_value_bool(env, argv[PARAM0], &rawDeliverySwitch);
2630         int32_t retCode = photoOutputNapi->photoOutput_->EnableRawDelivery(rawDeliverySwitch);
2631         if (retCode != 0 && !CameraNapiUtils::CheckError(env, retCode)) {
2632             return result;
2633         }
2634     }
2635     MEDIA_INFO_LOG("new rawPhotoListener and register surface consumer listener");
2636     CHECK_ERROR_RETURN_RET_LOG(photoOutputNapi == nullptr, result, "photoOutputNapi is null!");
2637     auto rawSurface = photoOutputNapi->photoOutput_->rawPhotoSurface_;
2638     if (rawSurface == nullptr) {
2639         MEDIA_ERR_LOG("rawPhotoSurface_ is null!");
2640         return result;
2641     }
2642     sptr<RawPhotoListener> rawPhotoListener = new (std::nothrow) RawPhotoListener(env, rawSurface);
2643     if (rawPhotoListener == nullptr) {
2644         MEDIA_ERR_LOG("failed to new rawPhotoListener");
2645         return result;
2646     }
2647     SurfaceError ret = rawSurface->RegisterConsumerListener((sptr<IBufferConsumerListener>&)rawPhotoListener);
2648     if (ret != SURFACE_ERROR_OK) {
2649         MEDIA_ERR_LOG("register surface consumer listener failed!");
2650     }
2651     photoOutputNapi->rawPhotoListener_ = rawPhotoListener;
2652     napi_value callback;
2653     napi_get_reference_value(env, rawCallback_, &callback);
2654     photoOutputNapi->rawPhotoListener_->SaveCallbackReference(CONST_CAPTURE_PHOTO_AVAILABLE, callback, false);
2655     return result;
2656 }
2657 
GetActiveProfile(napi_env env,napi_callback_info info)2658 napi_value PhotoOutputNapi::GetActiveProfile(napi_env env, napi_callback_info info)
2659 {
2660     MEDIA_DEBUG_LOG("PhotoOutputNapi::GetActiveProfile is called");
2661     PhotoOutputNapi* photoOutputNapi = nullptr;
2662     CameraNapiParamParser jsParamParser(env, info, photoOutputNapi);
2663     if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error")) {
2664         MEDIA_ERR_LOG("PhotoOutputNapi::GetActiveProfile parse parameter occur error");
2665         return nullptr;
2666     }
2667     auto profile = photoOutputNapi->photoOutput_->GetPhotoProfile();
2668     if (profile == nullptr) {
2669         return CameraNapiUtils::GetUndefinedValue(env);
2670     }
2671     return CameraNapiObjProfile(*profile).GenerateNapiValue(env);
2672 }
2673 
RegisterQuickThumbnailCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)2674 void PhotoOutputNapi::RegisterQuickThumbnailCallbackListener(
2675     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
2676 {
2677     if (!CameraNapiSecurity::CheckSystemApp(env)) {
2678         MEDIA_ERR_LOG("SystemApi quickThumbnail on is called!");
2679         return;
2680     }
2681 
2682     // Set callback for exposureStateChange
2683     if (thumbnailListener_ == nullptr) {
2684         if (!isQuickThumbnailEnabled_) {
2685             MEDIA_ERR_LOG("quickThumbnail is not enabled!");
2686             napi_throw_error(env, std::to_string(SESSION_NOT_RUNNING).c_str(), "");
2687             return;
2688         }
2689         thumbnailListener_ = new ThumbnailListener(env, photoOutput_);
2690         photoOutput_->SetThumbnailListener((sptr<IBufferConsumerListener>&)thumbnailListener_);
2691     }
2692     thumbnailListener_->SaveCallbackReference(eventName, callback, isOnce);
2693 }
2694 
UnregisterQuickThumbnailCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)2695 void PhotoOutputNapi::UnregisterQuickThumbnailCallbackListener(
2696     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
2697 {
2698     if (!CameraNapiSecurity::CheckSystemApp(env)) {
2699         MEDIA_ERR_LOG("SystemApi quickThumbnail off is called!");
2700         return;
2701     }
2702     if (!isQuickThumbnailEnabled_) {
2703         MEDIA_ERR_LOG("quickThumbnail is not enabled!");
2704         napi_throw_error(env, std::to_string(SESSION_NOT_RUNNING).c_str(), "");
2705         return;
2706     }
2707     if (thumbnailListener_ != nullptr) {
2708         thumbnailListener_->RemoveCallbackRef(eventName, callback);
2709     }
2710 }
2711 
RegisterPhotoAvailableCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)2712 void PhotoOutputNapi::RegisterPhotoAvailableCallbackListener(
2713     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
2714 {
2715     if (sPhotoSurface_ == nullptr) {
2716         MEDIA_ERR_LOG("sPhotoSurface_ is null!");
2717         return;
2718     }
2719     if (photoListener_ == nullptr) {
2720         MEDIA_INFO_LOG("new photoListener and register surface consumer listener");
2721         sptr<PhotoListener> photoListener = new (std::nothrow) PhotoListener(env, sPhotoSurface_, photoOutput_);
2722         if (photoListener == nullptr) {
2723             MEDIA_ERR_LOG("photoListener is null!");
2724             return;
2725         }
2726         SurfaceError ret = sPhotoSurface_->RegisterConsumerListener((sptr<IBufferConsumerListener>&)photoListener);
2727         if (ret != SURFACE_ERROR_OK) {
2728             MEDIA_ERR_LOG("register surface consumer listener failed!");
2729         }
2730         photoListener_ = photoListener;
2731     }
2732     photoListener_->SaveCallback(CONST_CAPTURE_PHOTO_AVAILABLE, callback);
2733 
2734     // Preconfig can't support rawPhotoListener.
2735     if (photoOutput_ != nullptr && profile_ != nullptr) {
2736         napi_ref rawCallback;
2737         napi_create_reference(env, callback, 1, &rawCallback);
2738         rawCallback_ = rawCallback;
2739         if (profile_->GetCameraFormat() == CAMERA_FORMAT_YUV_420_SP) {
2740             CreateMultiChannelPictureLisenter(env);
2741         }
2742     }
2743 }
2744 
UnregisterPhotoAvailableCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)2745 void PhotoOutputNapi::UnregisterPhotoAvailableCallbackListener(
2746     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
2747 {
2748     if (photoListener_ != nullptr) {
2749         photoListener_->RemoveCallback(CONST_CAPTURE_PHOTO_AVAILABLE, callback);
2750     }
2751     if (rawPhotoListener_ != nullptr) {
2752         rawPhotoListener_->RemoveCallbackRef(CONST_CAPTURE_PHOTO_AVAILABLE, callback);
2753     }
2754 }
2755 
RegisterDeferredPhotoProxyAvailableCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)2756 void PhotoOutputNapi::RegisterDeferredPhotoProxyAvailableCallbackListener(
2757     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
2758 {
2759     if (sPhotoSurface_ == nullptr) {
2760         MEDIA_ERR_LOG("sPhotoSurface_ is null!");
2761         return;
2762     }
2763     if (photoListener_ == nullptr) {
2764         MEDIA_INFO_LOG("new deferred photoListener and register surface consumer listener");
2765         sptr<PhotoListener> photoListener = new (std::nothrow) PhotoListener(env, sPhotoSurface_, photoOutput_);
2766         if (photoListener == nullptr) {
2767             MEDIA_ERR_LOG("failed to new photoListener!");
2768             return;
2769         }
2770         SurfaceError ret = sPhotoSurface_->RegisterConsumerListener((sptr<IBufferConsumerListener>&)photoListener);
2771         if (ret != SURFACE_ERROR_OK) {
2772             MEDIA_ERR_LOG("register surface consumer listener failed!");
2773         }
2774         photoListener_ = photoListener;
2775     }
2776     photoListener_->SaveCallback(CONST_CAPTURE_DEFERRED_PHOTO_AVAILABLE, callback);
2777 }
2778 
UnregisterDeferredPhotoProxyAvailableCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)2779 void PhotoOutputNapi::UnregisterDeferredPhotoProxyAvailableCallbackListener(
2780     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
2781 {
2782     if (photoListener_ != nullptr) {
2783         photoListener_->RemoveCallback(CONST_CAPTURE_DEFERRED_PHOTO_AVAILABLE, callback);
2784     }
2785 }
2786 
RegisterPhotoAssetAvailableCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)2787 void PhotoOutputNapi::RegisterPhotoAssetAvailableCallbackListener(
2788     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
2789 {
2790     if (sPhotoSurface_ == nullptr) {
2791         MEDIA_ERR_LOG("sPhotoSurface_ is null!");
2792         return;
2793     }
2794     if (photoOutput_ == nullptr) {
2795         MEDIA_ERR_LOG("photoOutput_ is null!");
2796         return;
2797     }
2798     if (photoOutput_->IsYuvOrHeifPhoto()) {
2799         CreateMultiChannelPictureLisenter(env);
2800     } else {
2801         CreateSingleChannelPhotoLisenter(env);
2802     }
2803     photoListener_->SaveCallback(CONST_CAPTURE_PHOTO_ASSET_AVAILABLE, callback);
2804 }
2805 
UnregisterPhotoAssetAvailableCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)2806 void PhotoOutputNapi::UnregisterPhotoAssetAvailableCallbackListener(
2807     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
2808 {
2809     if (photoListener_ != nullptr) {
2810         photoListener_->RemoveCallback(CONST_CAPTURE_PHOTO_ASSET_AVAILABLE, callback);
2811         if (photoListener_->taskManager_) {
2812             photoListener_->taskManager_->CancelAllTasks();
2813             photoListener_->taskManager_.reset();
2814             photoListener_->taskManager_ = nullptr;
2815         }
2816     }
2817     if (photoOutput_) {
2818         if (photoOutput_->taskManager_) {
2819             photoOutput_->taskManager_->CancelAllTasks();
2820             photoOutput_->taskManager_.reset();
2821             photoOutput_->taskManager_ = nullptr;
2822         }
2823     }
2824 }
2825 
RegisterCaptureStartCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)2826 void PhotoOutputNapi::RegisterCaptureStartCallbackListener(
2827     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
2828 {
2829     if (photoOutputCallback_ == nullptr) {
2830         photoOutputCallback_ = std::make_shared<PhotoOutputCallback>(env);
2831         photoOutput_->SetCallback(photoOutputCallback_);
2832     }
2833     photoOutputCallback_->SaveCallbackReference(CONST_CAPTURE_START, callback, isOnce);
2834 }
2835 
UnregisterCaptureStartCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)2836 void PhotoOutputNapi::UnregisterCaptureStartCallbackListener(
2837     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
2838 {
2839     if (photoOutputCallback_ == nullptr) {
2840         MEDIA_ERR_LOG("photoOutputCallback is null");
2841         return;
2842     }
2843     photoOutputCallback_->RemoveCallbackRef(CONST_CAPTURE_START, callback);
2844 }
2845 
RegisterCaptureStartWithInfoCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)2846 void PhotoOutputNapi::RegisterCaptureStartWithInfoCallbackListener(
2847     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
2848 {
2849     if (photoOutputCallback_ == nullptr) {
2850         photoOutputCallback_ = std::make_shared<PhotoOutputCallback>(env);
2851         photoOutput_->SetCallback(photoOutputCallback_);
2852     }
2853     photoOutputCallback_->SaveCallbackReference(CONST_CAPTURE_START_WITH_INFO, callback, isOnce);
2854 }
2855 
UnregisterCaptureStartWithInfoCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)2856 void PhotoOutputNapi::UnregisterCaptureStartWithInfoCallbackListener(
2857     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
2858 {
2859     if (photoOutputCallback_ == nullptr) {
2860         MEDIA_ERR_LOG("photoOutputCallback is null");
2861         return;
2862     }
2863     photoOutputCallback_->RemoveCallbackRef(CONST_CAPTURE_START_WITH_INFO, callback);
2864 }
2865 
RegisterCaptureEndCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)2866 void PhotoOutputNapi::RegisterCaptureEndCallbackListener(
2867     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
2868 {
2869     if (photoOutputCallback_ == nullptr) {
2870         photoOutputCallback_ = std::make_shared<PhotoOutputCallback>(env);
2871         photoOutput_->SetCallback(photoOutputCallback_);
2872     }
2873     photoOutputCallback_->SaveCallbackReference(CONST_CAPTURE_END, callback, isOnce);
2874 }
2875 
UnregisterCaptureEndCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)2876 void PhotoOutputNapi::UnregisterCaptureEndCallbackListener(
2877     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
2878 {
2879     if (photoOutputCallback_ == nullptr) {
2880         MEDIA_ERR_LOG("photoOutputCallback is null");
2881         return;
2882     }
2883     photoOutputCallback_->RemoveCallbackRef(CONST_CAPTURE_END, callback);
2884 }
2885 
RegisterFrameShutterCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)2886 void PhotoOutputNapi::RegisterFrameShutterCallbackListener(
2887     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
2888 {
2889     if (photoOutputCallback_ == nullptr) {
2890         photoOutputCallback_ = std::make_shared<PhotoOutputCallback>(env);
2891         photoOutput_->SetCallback(photoOutputCallback_);
2892     }
2893     photoOutputCallback_->SaveCallbackReference(CONST_CAPTURE_FRAME_SHUTTER, callback, isOnce);
2894 }
2895 
UnregisterFrameShutterCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)2896 void PhotoOutputNapi::UnregisterFrameShutterCallbackListener(
2897     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
2898 {
2899     if (photoOutputCallback_ == nullptr) {
2900         MEDIA_ERR_LOG("photoOutputCallback is null");
2901         return;
2902     }
2903     photoOutputCallback_->RemoveCallbackRef(CONST_CAPTURE_FRAME_SHUTTER, callback);
2904 }
2905 
RegisterErrorCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)2906 void PhotoOutputNapi::RegisterErrorCallbackListener(
2907     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
2908 {
2909     if (photoOutputCallback_ == nullptr) {
2910         photoOutputCallback_ = std::make_shared<PhotoOutputCallback>(env);
2911         photoOutput_->SetCallback(photoOutputCallback_);
2912     }
2913     photoOutputCallback_->SaveCallbackReference(CONST_CAPTURE_ERROR, callback, isOnce);
2914 }
2915 
UnregisterErrorCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)2916 void PhotoOutputNapi::UnregisterErrorCallbackListener(
2917     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
2918 {
2919     if (photoOutputCallback_ == nullptr) {
2920         MEDIA_ERR_LOG("photoOutputCallback is null");
2921         return;
2922     }
2923     photoOutputCallback_->RemoveCallbackRef(CONST_CAPTURE_ERROR, callback);
2924 }
2925 
RegisterFrameShutterEndCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)2926 void PhotoOutputNapi::RegisterFrameShutterEndCallbackListener(
2927     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
2928 {
2929     if (photoOutputCallback_ == nullptr) {
2930         photoOutputCallback_ = std::make_shared<PhotoOutputCallback>(env);
2931         photoOutput_->SetCallback(photoOutputCallback_);
2932     }
2933     photoOutputCallback_->SaveCallbackReference(CONST_CAPTURE_FRAME_SHUTTER_END, callback, isOnce);
2934 }
2935 
UnregisterFrameShutterEndCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)2936 void PhotoOutputNapi::UnregisterFrameShutterEndCallbackListener(
2937     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
2938 {
2939     if (photoOutputCallback_ == nullptr) {
2940         MEDIA_ERR_LOG("photoOutputCallback is null");
2941         return;
2942     }
2943     photoOutputCallback_->RemoveCallbackRef(CONST_CAPTURE_FRAME_SHUTTER_END, callback);
2944 }
2945 
RegisterReadyCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)2946 void PhotoOutputNapi::RegisterReadyCallbackListener(
2947     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
2948 {
2949     if (photoOutputCallback_ == nullptr) {
2950         photoOutputCallback_ = std::make_shared<PhotoOutputCallback>(env);
2951         photoOutput_->SetCallback(photoOutputCallback_);
2952     }
2953     photoOutputCallback_->SaveCallbackReference(CONST_CAPTURE_READY, callback, isOnce);
2954 }
2955 
UnregisterReadyCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)2956 void PhotoOutputNapi::UnregisterReadyCallbackListener(
2957     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
2958 {
2959     if (photoOutputCallback_ == nullptr) {
2960         MEDIA_ERR_LOG("photoOutputCallback is null");
2961         return;
2962     }
2963     photoOutputCallback_->RemoveCallbackRef(CONST_CAPTURE_READY, callback);
2964 }
2965 
RegisterEstimatedCaptureDurationCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)2966 void PhotoOutputNapi::RegisterEstimatedCaptureDurationCallbackListener(
2967     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
2968 {
2969     if (photoOutputCallback_ == nullptr) {
2970         photoOutputCallback_ = std::make_shared<PhotoOutputCallback>(env);
2971         photoOutput_->SetCallback(photoOutputCallback_);
2972     }
2973     photoOutputCallback_->SaveCallbackReference(CONST_CAPTURE_ESTIMATED_CAPTURE_DURATION, callback, isOnce);
2974 }
2975 
UnregisterEstimatedCaptureDurationCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)2976 void PhotoOutputNapi::UnregisterEstimatedCaptureDurationCallbackListener(
2977     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
2978 {
2979     if (photoOutputCallback_ == nullptr) {
2980         MEDIA_ERR_LOG("photoOutputCallback is null");
2981         return;
2982     }
2983     photoOutputCallback_->RemoveCallbackRef(CONST_CAPTURE_ESTIMATED_CAPTURE_DURATION, callback);
2984 }
2985 
GetEmitterFunctions()2986 const PhotoOutputNapi::EmitterFunctions& PhotoOutputNapi::GetEmitterFunctions()
2987 {
2988     static const EmitterFunctions funMap = {
2989         { CONST_CAPTURE_QUICK_THUMBNAIL, {
2990             &PhotoOutputNapi::RegisterQuickThumbnailCallbackListener,
2991             &PhotoOutputNapi::UnregisterQuickThumbnailCallbackListener } },
2992         { CONST_CAPTURE_PHOTO_AVAILABLE, {
2993             &PhotoOutputNapi::RegisterPhotoAvailableCallbackListener,
2994             &PhotoOutputNapi::UnregisterPhotoAvailableCallbackListener } },
2995         { CONST_CAPTURE_DEFERRED_PHOTO_AVAILABLE, {
2996             &PhotoOutputNapi::RegisterDeferredPhotoProxyAvailableCallbackListener,
2997             &PhotoOutputNapi::UnregisterDeferredPhotoProxyAvailableCallbackListener } },
2998         { CONST_CAPTURE_PHOTO_ASSET_AVAILABLE, {
2999             &PhotoOutputNapi::RegisterPhotoAssetAvailableCallbackListener,
3000             &PhotoOutputNapi::UnregisterPhotoAssetAvailableCallbackListener } },
3001         { CONST_CAPTURE_START, {
3002             &PhotoOutputNapi::RegisterCaptureStartCallbackListener,
3003             &PhotoOutputNapi::UnregisterCaptureStartCallbackListener } },
3004         { CONST_CAPTURE_END, {
3005             &PhotoOutputNapi::RegisterCaptureEndCallbackListener,
3006             &PhotoOutputNapi::UnregisterCaptureEndCallbackListener } },
3007         { CONST_CAPTURE_FRAME_SHUTTER, {
3008             &PhotoOutputNapi::RegisterFrameShutterCallbackListener,
3009             &PhotoOutputNapi::UnregisterFrameShutterCallbackListener } },
3010         { CONST_CAPTURE_ERROR, {
3011             &PhotoOutputNapi::RegisterErrorCallbackListener,
3012             &PhotoOutputNapi::UnregisterErrorCallbackListener } },
3013         { CONST_CAPTURE_FRAME_SHUTTER_END, {
3014             &PhotoOutputNapi::RegisterFrameShutterEndCallbackListener,
3015             &PhotoOutputNapi::UnregisterFrameShutterEndCallbackListener } },
3016         { CONST_CAPTURE_READY, {
3017             &PhotoOutputNapi::RegisterReadyCallbackListener,
3018             &PhotoOutputNapi::UnregisterReadyCallbackListener } },
3019         { CONST_CAPTURE_ESTIMATED_CAPTURE_DURATION, {
3020             &PhotoOutputNapi::RegisterEstimatedCaptureDurationCallbackListener,
3021             &PhotoOutputNapi::UnregisterEstimatedCaptureDurationCallbackListener } },
3022         { CONST_CAPTURE_START_WITH_INFO, {
3023             &PhotoOutputNapi::RegisterCaptureStartWithInfoCallbackListener,
3024             &PhotoOutputNapi::UnregisterCaptureStartWithInfoCallbackListener } } };
3025     return funMap;
3026 }
3027 
On(napi_env env,napi_callback_info info)3028 napi_value PhotoOutputNapi::On(napi_env env, napi_callback_info info)
3029 {
3030     return ListenerTemplate<PhotoOutputNapi>::On(env, info);
3031 }
3032 
Once(napi_env env,napi_callback_info info)3033 napi_value PhotoOutputNapi::Once(napi_env env, napi_callback_info info)
3034 {
3035     return ListenerTemplate<PhotoOutputNapi>::Once(env, info);
3036 }
3037 
Off(napi_env env,napi_callback_info info)3038 napi_value PhotoOutputNapi::Off(napi_env env, napi_callback_info info)
3039 {
3040     return ListenerTemplate<PhotoOutputNapi>::Off(env, info);
3041 }
3042 
IsAutoHighQualityPhotoSupported(napi_env env,napi_callback_info info)3043 napi_value PhotoOutputNapi::IsAutoHighQualityPhotoSupported(napi_env env, napi_callback_info info)
3044 {
3045     auto result = CameraNapiUtils::GetUndefinedValue(env);
3046     if (!CameraNapiSecurity::CheckSystemApp(env)) {
3047         MEDIA_ERR_LOG("SystemApi IsAutoHighQualityPhotoSupported is called!");
3048         return result;
3049     }
3050     MEDIA_DEBUG_LOG("PhotoOutputNapi::IsAutoHighQualityPhotoSupported is called");
3051     PhotoOutputNapi* photoOutputNapi = nullptr;
3052     CameraNapiParamParser jsParamParser(env, info, photoOutputNapi);
3053     if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error")) {
3054         MEDIA_ERR_LOG("PhotoOutputNapi::IsAutoHighQualityPhotoSupported parse parameter occur error");
3055         return result;
3056     }
3057     if (photoOutputNapi->photoOutput_ == nullptr) {
3058         MEDIA_ERR_LOG("PhotoOutputNapi::IsAutoHighQualityPhotoSupported get native object fail");
3059         CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "get native object fail");
3060         return result;
3061     }
3062 
3063     int32_t isAutoHighQualityPhotoSupported;
3064     int32_t retCode = photoOutputNapi->photoOutput_->IsAutoHighQualityPhotoSupported(isAutoHighQualityPhotoSupported);
3065     if (retCode == 0 && isAutoHighQualityPhotoSupported != -1) {
3066         napi_get_boolean(env, true, &result);
3067         return result;
3068     }
3069     MEDIA_ERR_LOG("PhotoOutputNapi::IsAutoHighQualityPhotoSupported is not supported");
3070     napi_get_boolean(env, false, &result);
3071     return result;
3072 }
3073 
IsAutoCloudImageEnhancementSupported(napi_env env,napi_callback_info info)3074 napi_value PhotoOutputNapi::IsAutoCloudImageEnhancementSupported(napi_env env, napi_callback_info info)
3075 {
3076     auto result = CameraNapiUtils::GetUndefinedValue(env);
3077     if (!CameraNapiSecurity::CheckSystemApp(env)) {
3078         MEDIA_ERR_LOG("SystemApi IsAutoCloudImageEnhancementSupported is called!");
3079         return result;
3080     }
3081     MEDIA_DEBUG_LOG("PhotoOutputNapi::IsAutoCloudImageEnhancementSupported is called");
3082     PhotoOutputNapi* photoOutputNapi = nullptr;
3083     CameraNapiParamParser jsParamParser(env, info, photoOutputNapi);
3084     if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error")) {
3085         MEDIA_ERR_LOG("PhotoOutputNapi::IsAutoCloudImageEnhancementSupported parse parameter occur error");
3086         return result;
3087     }
3088     if (photoOutputNapi->photoOutput_ == nullptr) {
3089         MEDIA_ERR_LOG("PhotoOutputNapi::IsAutoCloudImageEnhancementSupported get native object fail");
3090         CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "get native object fail");
3091         return result;
3092     }
3093     bool isAutoCloudImageEnhancementSupported = false;
3094     int32_t retCode =
3095         photoOutputNapi->photoOutput_->IsAutoCloudImageEnhancementSupported(
3096             isAutoCloudImageEnhancementSupported);
3097     if (!CameraNapiUtils::CheckError(env, retCode)) {
3098         return nullptr;
3099     }
3100     napi_get_boolean(env, isAutoCloudImageEnhancementSupported, &result);
3101     MEDIA_DEBUG_LOG("PhotoOutputNapi::IsAutoCloudImageEnhancementSupported is %{public}d",
3102         isAutoCloudImageEnhancementSupported);
3103     return result;
3104 }
3105 
EnableAutoHighQualityPhoto(napi_env env,napi_callback_info info)3106 napi_value PhotoOutputNapi::EnableAutoHighQualityPhoto(napi_env env, napi_callback_info info)
3107 {
3108     auto result = CameraNapiUtils::GetUndefinedValue(env);
3109     if (!CameraNapiSecurity::CheckSystemApp(env)) {
3110         MEDIA_ERR_LOG("SystemApi EnableAutoHighQualityPhoto is called!");
3111         return result;
3112     }
3113     MEDIA_DEBUG_LOG("PhotoOutputNapi::EnableAutoHighQualityPhoto is called");
3114     PhotoOutputNapi* photoOutputNapi = nullptr;
3115     bool isEnable;
3116     CameraNapiParamParser jsParamParser(env, info, photoOutputNapi, isEnable);
3117     if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error")) {
3118         MEDIA_ERR_LOG("PhotoOutputNapi::EnableAutoHighQualityPhoto parse parameter occur error");
3119         return result;
3120     }
3121     if (photoOutputNapi->photoOutput_ == nullptr) {
3122         MEDIA_ERR_LOG("PhotoOutputNapi::EnableAutoHighQualityPhoto get native object fail");
3123         CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "get native object fail");
3124         return result;
3125     }
3126 
3127     int32_t retCode = photoOutputNapi->photoOutput_->EnableAutoHighQualityPhoto(isEnable);
3128     if (!CameraNapiUtils::CheckError(env, retCode)) {
3129         MEDIA_ERR_LOG("PhotoOutputNapi::EnableAutoHighQualityPhoto fail %{public}d", retCode);
3130     }
3131     return result;
3132 }
3133 
EnableAutoCloudImageEnhancement(napi_env env,napi_callback_info info)3134 napi_value PhotoOutputNapi::EnableAutoCloudImageEnhancement(napi_env env, napi_callback_info info)
3135 {
3136     auto result = CameraNapiUtils::GetUndefinedValue(env);
3137     if (!CameraNapiSecurity::CheckSystemApp(env)) {
3138         MEDIA_ERR_LOG("SystemApi EnableAutoCloudImageEnhancement is called!");
3139         return result;
3140     }
3141     MEDIA_DEBUG_LOG("PhotoOutputNapi::EnableAutoCloudImageEnhancement is called");
3142     PhotoOutputNapi* photoOutputNapi = nullptr;
3143     bool isEnable;
3144     CameraNapiParamParser jsParamParser(env, info, photoOutputNapi, isEnable);
3145     if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error")) {
3146         MEDIA_ERR_LOG("PhotoOutputNapi::EnableAutoCloudImageEnhancement parse parameter occur error");
3147         return result;
3148     }
3149     if (photoOutputNapi->photoOutput_ == nullptr) {
3150         MEDIA_ERR_LOG("PhotoOutputNapi::EnableAutoCloudImageEnhancement get native object fail");
3151         CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "get native object fail");
3152         return result;
3153     }
3154 
3155     int32_t retCode = photoOutputNapi->photoOutput_->EnableAutoCloudImageEnhancement(isEnable);
3156     if (!CameraNapiUtils::CheckError(env, retCode)) {
3157         MEDIA_ERR_LOG("PhotoOutputNapi::EnableAutoCloudImageEnhancement fail %{public}d", retCode);
3158         return result;
3159     }
3160     MEDIA_DEBUG_LOG("PhotoOutputNapi::EnableAutoCloudImageEnhancement success");
3161     return result;
3162 }
3163 
IsDepthDataDeliverySupported(napi_env env,napi_callback_info info)3164 napi_value PhotoOutputNapi::IsDepthDataDeliverySupported(napi_env env, napi_callback_info info)
3165 {
3166     if (!CameraNapiSecurity::CheckSystemApp(env)) {
3167         MEDIA_ERR_LOG("SystemApi IsDepthDataDeliverySupported is called!");
3168         return nullptr;
3169     }
3170     MEDIA_DEBUG_LOG("PhotoOutputNapi::IsDepthDataDeliverySupported is called");
3171     PhotoOutputNapi* photoOutputNapi = nullptr;
3172     CameraNapiParamParser jsParamParser(env, info, photoOutputNapi);
3173     if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error")) {
3174         MEDIA_ERR_LOG("PhotoOutputNapi::IsDepthDataDeliverySupported parse parameter occur error");
3175         return nullptr;
3176     }
3177     if (photoOutputNapi->photoOutput_ == nullptr) {
3178         MEDIA_ERR_LOG("PhotoOutputNapi::IsDepthDataDeliverySupported get native object fail");
3179         CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "get native object fail");
3180         return nullptr;
3181     }
3182     napi_value result = nullptr;
3183     int32_t retCode = photoOutputNapi->photoOutput_->IsDepthDataDeliverySupported();
3184     if (retCode == 0) {
3185         napi_get_boolean(env, true, &result);
3186         return result;
3187     }
3188     MEDIA_ERR_LOG("PhotoOutputNapi::IsDepthDataDeliverySupported is not supported");
3189     napi_get_boolean(env, false, &result);
3190     return result;
3191 }
3192 
EnableDepthDataDelivery(napi_env env,napi_callback_info info)3193 napi_value PhotoOutputNapi::EnableDepthDataDelivery(napi_env env, napi_callback_info info)
3194 {
3195     if (!CameraNapiSecurity::CheckSystemApp(env)) {
3196         MEDIA_ERR_LOG("SystemApi EnableDepthDataDelivery is called!");
3197         return nullptr;
3198     }
3199     MEDIA_DEBUG_LOG("PhotoOutputNapi::EnableDepthDataDelivery is called");
3200     PhotoOutputNapi* photoOutputNapi = nullptr;
3201     bool isEnable;
3202     CameraNapiParamParser jsParamParser(env, info, photoOutputNapi, isEnable);
3203     if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error")) {
3204         MEDIA_ERR_LOG("PhotoOutputNapi::EnableDepthDataDelivery parse parameter occur error");
3205         return nullptr;
3206     }
3207     if (photoOutputNapi->photoOutput_ == nullptr) {
3208         MEDIA_ERR_LOG("PhotoOutputNapi::EnableDepthDataDelivery get native object fail");
3209         CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "get native object fail");
3210         return nullptr;
3211     }
3212 
3213     int32_t retCode = photoOutputNapi->photoOutput_->EnableDepthDataDelivery(isEnable);
3214     if (!CameraNapiUtils::CheckError(env, retCode)) {
3215         MEDIA_ERR_LOG("PhotoOutputNapi::EnableDepthDataDelivery fail %{public}d", retCode);
3216     }
3217     return CameraNapiUtils::GetUndefinedValue(env);
3218 }
3219 } // namespace CameraStandard
3220 } // namespace OHOS