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