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