• 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 "camera_error_code.h"
28 #include "camera_log.h"
29 #include "camera_manager.h"
30 #include "camera_napi_const.h"
31 #include "camera_napi_object_types.h"
32 #include "camera_napi_param_parser.h"
33 #include "camera_napi_security_utils.h"
34 #include "camera_napi_template_utils.h"
35 #include "camera_napi_utils.h"
36 #include "camera_napi_worker_queue_keeper.h"
37 #include "camera_output_capability.h"
38 #include "image_napi.h"
39 #include "image_receiver.h"
40 #include "js_native_api.h"
41 #include "js_native_api_types.h"
42 #include "listener_base.h"
43 #include "media_library_comm_napi.h"
44 #include "output/photo_napi.h"
45 #include "photo_output.h"
46 #include "pixel_map_napi.h"
47 #include "refbase.h"
48 #include "native_common_napi.h"
49 #include "camera_dynamic_loader.h"
50 #include "napi/native_node_api.h"
51 
52 namespace OHOS {
53 namespace CameraStandard {
54 using namespace std;
55 namespace {
56 
AsyncCompleteCallback(napi_env env,napi_status status,void * data)57 void AsyncCompleteCallback(napi_env env, napi_status status, void* data)
58 {
59     auto photoOutputAsyncContext = static_cast<PhotoOutputAsyncContext*>(data);
60     CHECK_RETURN_ELOG(photoOutputAsyncContext == nullptr,
61         "CameraInputNapi AsyncCompleteCallback context is null");
62     MEDIA_INFO_LOG("CameraInputNapi AsyncCompleteCallback %{public}s, status = %{public}d",
63         photoOutputAsyncContext->funcName.c_str(), photoOutputAsyncContext->status);
64     std::unique_ptr<JSAsyncContextOutput> jsContext = std::make_unique<JSAsyncContextOutput>();
65     jsContext->status = photoOutputAsyncContext->status;
66 
67     if (!photoOutputAsyncContext->status) {
68         CameraNapiUtils::CreateNapiErrorObject(env, photoOutputAsyncContext->errorCode,
69             photoOutputAsyncContext->errorMsg.c_str(), jsContext);
70     } else {
71         napi_get_undefined(env, &jsContext->data);
72     }
73     if (!photoOutputAsyncContext->funcName.empty() && photoOutputAsyncContext->taskId > 0) {
74         // Finish async trace
75         CAMERA_FINISH_ASYNC_TRACE(photoOutputAsyncContext->funcName, photoOutputAsyncContext->taskId);
76         jsContext->funcName = photoOutputAsyncContext->funcName;
77     }
78     CHECK_EXECUTE(photoOutputAsyncContext->work != nullptr,
79         CameraNapiUtils::InvokeJSAsyncMethod(env, photoOutputAsyncContext->deferred,
80             photoOutputAsyncContext->callbackRef, photoOutputAsyncContext->work, *jsContext));
81     photoOutputAsyncContext->FreeHeldNapiValue(env);
82     delete photoOutputAsyncContext;
83 }
84 
ProcessCapture(PhotoOutputAsyncContext * context,bool isBurst)85 void ProcessCapture(PhotoOutputAsyncContext* context, bool isBurst)
86 {
87     context->status = true;
88     sptr<PhotoOutput> photoOutput = context->objectInfo->GetPhotoOutput();
89     MEDIA_INFO_LOG("PhotoOutputAsyncContext objectInfo GetEnableMirror is %{public}d",
90         context->objectInfo->GetEnableMirror());
91     if (context->hasPhotoSettings) {
92         std::shared_ptr<PhotoCaptureSetting> capSettings = make_shared<PhotoCaptureSetting>();
93         CHECK_EXECUTE(context->quality != -1,
94             capSettings->SetQuality(static_cast<PhotoCaptureSetting::QualityLevel>(context->quality)));
95         CHECK_EXECUTE(context->rotation != -1,
96             capSettings->SetRotation(static_cast<PhotoCaptureSetting::RotationConfig>(context->rotation)));
97         if (!context->isMirrorSettedByUser) {
98             capSettings->SetMirror(context->objectInfo->GetEnableMirror());
99         } else {
100             capSettings->SetMirror(context->isMirror);
101         }
102         CHECK_EXECUTE(context->location != nullptr, capSettings->SetLocation(context->location));
103         if (isBurst) {
104             MEDIA_ERR_LOG("ProcessContext BurstCapture");
105             uint8_t burstState = 1; // 0:end 1:start
106             capSettings->SetBurstCaptureState(burstState);
107         }
108         context->errorCode = photoOutput->Capture(capSettings);
109     } else {
110         std::shared_ptr<PhotoCaptureSetting> capSettings = make_shared<PhotoCaptureSetting>();
111         capSettings->SetMirror(context->objectInfo->GetEnableMirror());
112         context->errorCode = photoOutput->Capture(capSettings);
113     }
114     context->status = context->errorCode == 0;
115 }
116 
ValidQualityLevelFromJs(int32_t jsQuality)117 bool ValidQualityLevelFromJs(int32_t jsQuality)
118 {
119     MEDIA_INFO_LOG("PhotoOutputNapi::ValidQualityLevelFromJs quality level = %{public}d", jsQuality);
120     switch (jsQuality) {
121         case QUALITY_LEVEL_HIGH:
122         // Fallthrough
123         case QUALITY_LEVEL_MEDIUM:
124         // Fallthrough
125         case QUALITY_LEVEL_LOW:
126             return true;
127         default:
128             MEDIA_ERR_LOG("Invalid quality value received from application");
129             return false;
130     }
131     return false;
132 }
133 
ValidImageRotationFromJs(int32_t jsRotation)134 bool ValidImageRotationFromJs(int32_t jsRotation)
135 {
136     MEDIA_INFO_LOG("js rotation = %{public}d", jsRotation);
137     switch (jsRotation) {
138         case ROTATION_0:
139             // Fallthrough
140         case ROTATION_90:
141             // Fallthrough
142         case ROTATION_180:
143             // Fallthrough
144         case ROTATION_270:
145             return true;
146         default:
147             MEDIA_ERR_LOG("Invalid rotation value received from application");
148             return false;
149     }
150     return false;
151 }
152 } // namespace
153 
154 thread_local napi_ref PhotoOutputNapi::sConstructor_ = nullptr;
155 thread_local sptr<PhotoOutput> PhotoOutputNapi::sPhotoOutput_ = nullptr;
156 thread_local uint32_t PhotoOutputNapi::photoOutputTaskId = CAMERA_PHOTO_OUTPUT_TASKID;
157 thread_local napi_ref PhotoOutputNapi::rawCallback_ = nullptr;
158 static uv_sem_t g_captureStartSem;
159 static bool g_isSemInited;
160 static std::mutex g_photoImageMutex;
161 static std::mutex g_assembleImageMutex;
162 static int32_t g_captureId;
163 
FillNapiObjectWithCaptureId(napi_env env,int32_t captureId,napi_value & photoAsset)164 void FillNapiObjectWithCaptureId(napi_env env, int32_t captureId, napi_value &photoAsset)
165 {
166     napi_value propertyName;
167     napi_value propertyValue;
168     napi_create_string_utf8(env, "captureId", NAPI_AUTO_LENGTH, &propertyName);
169     napi_create_int32(env, captureId, &propertyValue);
170     napi_set_property(env, photoAsset, propertyName, propertyValue);
171     MEDIA_INFO_LOG("FillNapiObjectWithCaptureId captureId %{public}d", captureId);
172 }
173 
LoggingSurfaceBufferInfo(sptr<SurfaceBuffer> buffer,std::string bufName)174 inline void LoggingSurfaceBufferInfo(sptr<SurfaceBuffer> buffer, std::string bufName)
175 {
176     if (buffer) {
177         MEDIA_INFO_LOG("AssembleAuxiliaryPhoto %{public}s w=%{public}d, h=%{public}d, f=%{public}d", bufName.c_str(),
178             buffer->GetWidth(), buffer->GetHeight(), buffer->GetFormat());
179     }
180 };
181 
GetLocationBySettings(std::shared_ptr<PhotoCaptureSetting> settings)182 std::shared_ptr<Location> GetLocationBySettings(std::shared_ptr<PhotoCaptureSetting> settings)
183 {
184     auto location = make_shared<Location>();
185     if (settings) {
186         settings->GetLocation(location);
187         MEDIA_INFO_LOG("GetLocationBySettings latitude:%{private}f, longitude:%{private}f",
188             location->latitude, location->longitude);
189     } else {
190         MEDIA_ERR_LOG("GetLocationBySettings failed!");
191     }
192     return location;
193 }
194 
GetBurstSeqId(int32_t captureId)195 int32_t GetBurstSeqId(int32_t captureId)
196 {
197     const uint32_t burstSeqIdMask = 0xFFFF;
198     return captureId > 0 ? (static_cast<uint32_t>(captureId) & burstSeqIdMask) : captureId;
199 }
200 
CleanAfterTransPicture(sptr<PhotoOutput> photoOutput,int32_t captureId)201 void CleanAfterTransPicture(sptr<PhotoOutput> photoOutput, int32_t captureId)
202 {
203     CHECK_RETURN_ELOG(!photoOutput, "CleanAfterTransPicture photoOutput is nullptr");
204     photoOutput->photoProxyMap_[captureId] = nullptr;
205     photoOutput->photoProxyMap_.erase(captureId);
206     photoOutput->captureIdPictureMap_.erase(captureId);
207     photoOutput->captureIdGainmapMap_.erase(captureId);
208     photoOutput->captureIdDepthMap_.Erase(captureId);
209     photoOutput->captureIdExifMap_.erase(captureId);
210     photoOutput->captureIdDebugMap_.erase(captureId);
211     photoOutput->captureIdAuxiliaryCountMap_.erase(captureId);
212     photoOutput->captureIdCountMap_.erase(captureId);
213     photoOutput->captureIdHandleMap_.erase(captureId);
214 }
215 
FillPixelMapWithCaptureIdAndTimestamp(napi_env env,int32_t captureId,int64_t timestamp,napi_value pixelMapNapi)216 void FillPixelMapWithCaptureIdAndTimestamp(napi_env env, int32_t captureId, int64_t timestamp, napi_value pixelMapNapi)
217 {
218     napi_valuetype valueType = napi_undefined;
219     if (napi_typeof(env, pixelMapNapi, &valueType) != napi_ok || valueType == napi_undefined) {
220         MEDIA_ERR_LOG("FillPixelMapWithCaptureIdAndTimestamp err, pixelMapNapi is undefined = %{public}d",
221             valueType == napi_undefined);
222         return;
223     }
224     napi_value propertyName;
225     napi_value propertyValue;
226     napi_get_undefined(env, &propertyName);
227     napi_get_undefined(env, &propertyValue);
228     napi_create_string_utf8(env, "captureId", NAPI_AUTO_LENGTH, &propertyName);
229     napi_create_int32(env, captureId, &propertyValue);
230     napi_set_property(env, pixelMapNapi, propertyName, propertyValue);
231     MEDIA_INFO_LOG("FillPixelMapWithCaptureIdAndTimestamp captureId %{public}d", captureId);
232 
233     napi_create_string_utf8(env, "timestamp", NAPI_AUTO_LENGTH, &propertyName);
234     napi_create_int64(env, timestamp, &propertyValue);
235     napi_set_property(env, pixelMapNapi, propertyName, propertyValue);
236 }
237 
PhotoOutputCallback(napi_env env)238 PhotoOutputCallback::PhotoOutputCallback(napi_env env) : ListenerBase(env) {}
239 
UpdateJSExecute(uv_work_t * work)240 void UpdateJSExecute(uv_work_t* work)
241 {
242     PhotoOutputCallbackInfo* callbackInfo = reinterpret_cast<PhotoOutputCallbackInfo*>(work->data);
243     if (callbackInfo) {
244         if (callbackInfo->eventType_ == PhotoOutputEventType::CAPTURE_START ||
245             callbackInfo->eventType_ == PhotoOutputEventType::CAPTURE_START_WITH_INFO) {
246             g_captureId = callbackInfo->info_.captureID;
247             MEDIA_DEBUG_LOG("UpdateJSExecute CAPTURE_START g_captureId:%{public}d", g_captureId);
248         }
249         CHECK_EXECUTE(callbackInfo->eventType_ == PhotoOutputEventType::CAPTURE_FRAME_SHUTTER &&
250             g_captureId != callbackInfo->info_.captureID, uv_sem_wait(&g_captureStartSem));
251     }
252 }
253 
UpdateJSCallbackAsync(PhotoOutputEventType eventType,const CallbackInfo & info) const254 void PhotoOutputCallback::UpdateJSCallbackAsync(PhotoOutputEventType eventType, const CallbackInfo &info) const
255 {
256     MEDIA_DEBUG_LOG("UpdateJSCallbackAsync is called");
257     if (!g_isSemInited) {
258         uv_sem_init(&g_captureStartSem, 0);
259         g_isSemInited = true;
260     }
261     std::unique_ptr<PhotoOutputCallbackInfo> callbackInfo =
262         std::make_unique<PhotoOutputCallbackInfo>(eventType, info, shared_from_this());
263     PhotoOutputCallbackInfo *event = callbackInfo.get();
264     auto task = [event]() {
265         PhotoOutputCallbackInfo* callbackInfo = reinterpret_cast<PhotoOutputCallbackInfo *>(event);
266         if (callbackInfo) {
267             auto listener = callbackInfo->listener_.lock();
268             if (listener) {
269                 listener->UpdateJSCallback(callbackInfo->eventType_, callbackInfo->info_);
270                 if (callbackInfo->eventType_ == PhotoOutputEventType::CAPTURE_START ||
271                     callbackInfo->eventType_ == PhotoOutputEventType::CAPTURE_START_WITH_INFO) {
272                     MEDIA_DEBUG_LOG("PhotoOutputEventType::CAPTURE_START work done execute!");
273                     uv_sem_post(&g_captureStartSem);
274                 } else if (callbackInfo->eventType_ == PhotoOutputEventType::CAPTURE_FRAME_SHUTTER) {
275                     MEDIA_DEBUG_LOG("PhotoOutputEventType::CAPTURE_FRAME_SHUTTER work done execute!");
276                     uv_sem_destroy(&g_captureStartSem);
277                     g_isSemInited = false;
278                 }
279             }
280             delete callbackInfo;
281         }
282     };
283     if (napi_ok != napi_send_event(env_, task, napi_eprio_immediate)) {
284         MEDIA_ERR_LOG("failed to execute work");
285     } else {
286         callbackInfo.release();
287     }
288 }
289 
OnCaptureStarted(const int32_t captureID) const290 void PhotoOutputCallback::OnCaptureStarted(const int32_t captureID) const
291 {
292     CAMERA_SYNC_TRACE;
293     MEDIA_DEBUG_LOG("OnCaptureStarted is called!, captureID: %{public}d", captureID);
294     CallbackInfo info;
295     info.captureID = captureID;
296     UpdateJSCallbackAsync(PhotoOutputEventType::CAPTURE_START_WITH_INFO, info);
297 }
298 
OnCaptureStarted(const int32_t captureID,uint32_t exposureTime) const299 void PhotoOutputCallback::OnCaptureStarted(const int32_t captureID, uint32_t exposureTime) const
300 {
301     CAMERA_SYNC_TRACE;
302     MEDIA_DEBUG_LOG("OnCaptureStarted is called!, captureID: %{public}d", captureID);
303     CallbackInfo info;
304     info.captureID = captureID;
305     info.timestamp = exposureTime;
306     UpdateJSCallbackAsync(PhotoOutputEventType::CAPTURE_START, info);
307 }
308 
OnCaptureEnded(const int32_t captureID,const int32_t frameCount) const309 void PhotoOutputCallback::OnCaptureEnded(const int32_t captureID, const int32_t frameCount) const
310 {
311     CAMERA_SYNC_TRACE;
312     MEDIA_INFO_LOG("OnCaptureEnded is called!, captureID: %{public}d, frameCount: %{public}d",
313         captureID, frameCount);
314     CallbackInfo info;
315     info.captureID = captureID;
316     info.frameCount = frameCount;
317     UpdateJSCallbackAsync(PhotoOutputEventType::CAPTURE_END, info);
318 }
319 
OnFrameShutter(const int32_t captureId,const uint64_t timestamp) const320 void PhotoOutputCallback::OnFrameShutter(const int32_t captureId, const uint64_t timestamp) const
321 {
322     CAMERA_SYNC_TRACE;
323     MEDIA_DEBUG_LOG(
324         "OnFrameShutter is called, captureID: %{public}d, timestamp: %{public}" PRIu64, captureId, timestamp);
325     CallbackInfo info;
326     info.captureID = captureId;
327     info.timestamp = timestamp;
328     UpdateJSCallbackAsync(PhotoOutputEventType::CAPTURE_FRAME_SHUTTER, info);
329 }
330 
OnFrameShutterEnd(const int32_t captureId,const uint64_t timestamp) const331 void PhotoOutputCallback::OnFrameShutterEnd(const int32_t captureId, const uint64_t timestamp) const
332 {
333     CAMERA_SYNC_TRACE;
334     MEDIA_DEBUG_LOG(
335         "OnFrameShutterEnd is called, captureID: %{public}d, timestamp: %{public}" PRIu64, captureId, timestamp);
336     CallbackInfo info;
337     info.captureID = captureId;
338     info.timestamp = timestamp;
339     UpdateJSCallbackAsync(PhotoOutputEventType::CAPTURE_FRAME_SHUTTER_END, info);
340 }
341 
OnCaptureReady(const int32_t captureId,const uint64_t timestamp) const342 void PhotoOutputCallback::OnCaptureReady(const int32_t captureId, const uint64_t timestamp) const
343 {
344     CAMERA_SYNC_TRACE;
345     MEDIA_INFO_LOG(
346         "OnCaptureReady is called, captureID: %{public}d, timestamp: %{public}" PRIu64, captureId, timestamp);
347     CallbackInfo info;
348     info.captureID = captureId;
349     info.timestamp = timestamp;
350     UpdateJSCallbackAsync(PhotoOutputEventType::CAPTURE_READY, info);
351 }
352 
OnCaptureError(const int32_t captureId,const int32_t errorCode) const353 void PhotoOutputCallback::OnCaptureError(const int32_t captureId, const int32_t errorCode) const
354 {
355     MEDIA_DEBUG_LOG("OnCaptureError is called!, captureID: %{public}d, errorCode: %{public}d", captureId, errorCode);
356     CallbackInfo info;
357     info.captureID = captureId;
358     info.errorCode = errorCode;
359     UpdateJSCallbackAsync(PhotoOutputEventType::CAPTURE_ERROR, info);
360 }
361 
OnEstimatedCaptureDuration(const int32_t duration) const362 void PhotoOutputCallback::OnEstimatedCaptureDuration(const int32_t duration) const
363 {
364     MEDIA_DEBUG_LOG("OnEstimatedCaptureDuration is called!, duration: %{public}d", duration);
365     CallbackInfo info;
366     info.duration = duration;
367     UpdateJSCallbackAsync(PhotoOutputEventType::CAPTURE_ESTIMATED_CAPTURE_DURATION, info);
368 }
369 
OnOfflineDeliveryFinished(const int32_t captureId) const370 void PhotoOutputCallback::OnOfflineDeliveryFinished(const int32_t captureId) const
371 {
372     CAMERA_SYNC_TRACE;
373     MEDIA_DEBUG_LOG(
374         "OnOfflineDeliveryFinished is called, captureID: %{public}d", captureId);
375     CallbackInfo info;
376     info.captureID = captureId;
377     UpdateJSCallbackAsync(PhotoOutputEventType::CAPTURE_OFFLINE_DELIVERY_FINISHED, info);
378 }
379 
OnPhotoAvailable(const std::shared_ptr<Media::NativeImage> nativeImage,bool isRaw) const380 void PhotoOutputCallback::OnPhotoAvailable(const std::shared_ptr<Media::NativeImage> nativeImage, bool isRaw) const
381 {
382     MEDIA_DEBUG_LOG("PhotoOutputCallback::OnPhotoAvailable is called!");
383     CallbackInfo info;
384     info.nativeImage = nativeImage;
385     info.isRaw = isRaw;
386     UpdateJSCallbackAsync(PhotoOutputEventType::CAPTURE_PHOTO_AVAILABLE, info);
387 }
388 
OnPhotoAssetAvailable(const int32_t captureId,const std::string & uri,int32_t cameraShotType,const std::string & burstKey) const389 void PhotoOutputCallback::OnPhotoAssetAvailable(
390     const int32_t captureId, const std::string &uri, int32_t cameraShotType, const std::string &burstKey) const
391 {
392     MEDIA_DEBUG_LOG("PhotoOutputCallback::OnPhotoAssetAvailable is called!");
393     CallbackInfo info;
394     info.captureID = captureId;
395     info.uri = uri;
396     info.cameraShotType = cameraShotType;
397     info.burstKey = burstKey;
398     UpdateJSCallbackAsync(PhotoOutputEventType::CAPTURE_PHOTO_ASSET_AVAILABLE, info);
399 }
400 
OnThumbnailAvailable(const int32_t captureId,const int64_t timestamp,unique_ptr<Media::PixelMap> pixelMap) const401 void PhotoOutputCallback::OnThumbnailAvailable(
402     const int32_t captureId, const int64_t timestamp, unique_ptr<Media::PixelMap> pixelMap) const
403 {
404     MEDIA_DEBUG_LOG("PhotoOutputCallback::OnThumbnailAvailable is called!");
405     CallbackInfo info;
406     info.captureID = captureId;
407     info.timestamp = timestamp;
408     info.pixelMap = std::move(pixelMap);
409     UpdateJSCallbackAsync(PhotoOutputEventType::CAPTURE_THUMBNAIL_AVAILABLE, info);
410 }
411 
ExecuteCaptureStartCb(const CallbackInfo & info) const412 void PhotoOutputCallback::ExecuteCaptureStartCb(const CallbackInfo& info) const
413 {
414     napi_value result[ARGS_TWO] = { nullptr, nullptr };
415     napi_value retVal;
416     napi_get_undefined(env_, &result[PARAM0]);
417     if (IsEmpty(CONST_CAPTURE_START_WITH_INFO)) {
418         napi_create_int32(env_, info.captureID, &result[PARAM1]);
419         ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO,
420             .argv = result, .result = &retVal };
421         ExecuteCallback(CONST_CAPTURE_START, callbackNapiPara);
422     } else {
423         napi_value propValue;
424         napi_create_object(env_, &result[PARAM1]);
425         napi_create_int32(env_, info.captureID, &propValue);
426         napi_set_named_property(env_, result[PARAM1], "captureId", propValue);
427         int32_t invalidExposureTime = -1;
428         napi_create_int32(env_, invalidExposureTime, &propValue);
429         napi_set_named_property(env_, result[PARAM1], "time", propValue);
430         ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO,
431             .argv = result, .result = &retVal };
432         ExecuteCallback(CONST_CAPTURE_START_WITH_INFO, callbackNapiPara);
433     }
434 }
435 
ExecuteCaptureStartWithInfoCb(const CallbackInfo & info) const436 void PhotoOutputCallback::ExecuteCaptureStartWithInfoCb(const CallbackInfo& info) const
437 {
438     napi_value result[ARGS_TWO] = { nullptr, nullptr };
439     napi_value retVal;
440     napi_value propValue;
441     napi_get_undefined(env_, &result[PARAM0]);
442     napi_create_object(env_, &result[PARAM1]);
443     napi_create_int32(env_, info.captureID, &propValue);
444     napi_set_named_property(env_, result[PARAM1], "captureId", propValue);
445     napi_create_int32(env_, info.timestamp, &propValue);
446     napi_set_named_property(env_, result[PARAM1], "time", propValue);
447     ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
448     ExecuteCallback(CONST_CAPTURE_START_WITH_INFO, callbackNapiPara);
449 }
450 
ExecuteCaptureEndCb(const CallbackInfo & info) const451 void PhotoOutputCallback::ExecuteCaptureEndCb(const CallbackInfo& info) const
452 {
453     napi_value result[ARGS_TWO] = { nullptr, nullptr };
454     napi_value retVal;
455     napi_value propValue;
456     napi_get_undefined(env_, &result[PARAM0]);
457     napi_create_object(env_, &result[PARAM1]);
458     napi_create_int32(env_, info.captureID, &propValue);
459     napi_set_named_property(env_, result[PARAM1], "captureId", propValue);
460     napi_create_int32(env_, info.frameCount, &propValue);
461     napi_set_named_property(env_, result[PARAM1], "frameCount", propValue);
462     ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
463     ExecuteCallback(CONST_CAPTURE_END, callbackNapiPara);
464 }
465 
ExecuteFrameShutterCb(const CallbackInfo & info) const466 void PhotoOutputCallback::ExecuteFrameShutterCb(const CallbackInfo& info) const
467 {
468     napi_value result[ARGS_TWO] = { nullptr, nullptr };
469     napi_value retVal;
470     napi_value propValue;
471     napi_get_undefined(env_, &result[PARAM0]);
472     napi_create_object(env_, &result[PARAM1]);
473     napi_create_int32(env_, info.captureID, &propValue);
474     napi_set_named_property(env_, result[PARAM1], "captureId", propValue);
475     napi_create_int64(env_, info.timestamp, &propValue);
476     napi_set_named_property(env_, result[PARAM1], "timestamp", propValue);
477     ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
478     ExecuteCallback(CONST_CAPTURE_FRAME_SHUTTER, callbackNapiPara);
479 }
480 
ExecuteFrameShutterEndCb(const CallbackInfo & info) const481 void PhotoOutputCallback::ExecuteFrameShutterEndCb(const CallbackInfo& info) const
482 {
483     napi_value result[ARGS_TWO] = { nullptr, nullptr };
484     napi_value retVal;
485     napi_value propValue;
486     napi_get_undefined(env_, &result[PARAM0]);
487     napi_create_object(env_, &result[PARAM1]);
488     napi_create_int32(env_, info.captureID, &propValue);
489     napi_set_named_property(env_, result[PARAM1], "captureId", propValue);
490     ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
491     ExecuteCallback(CONST_CAPTURE_FRAME_SHUTTER_END, callbackNapiPara);
492 }
493 
ExecuteCaptureReadyCb(const CallbackInfo & info) const494 void PhotoOutputCallback::ExecuteCaptureReadyCb(const CallbackInfo& info) const
495 {
496     napi_value result[ARGS_ONE] = { nullptr };
497     napi_value retVal;
498     napi_get_undefined(env_, &result[PARAM0]);
499     ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_ONE, .argv = result, .result = &retVal };
500     ExecuteCallback(CONST_CAPTURE_READY, callbackNapiPara);
501 }
502 
ExecuteCaptureErrorCb(const CallbackInfo & info) const503 void PhotoOutputCallback::ExecuteCaptureErrorCb(const CallbackInfo& info) const
504 {
505     napi_value errJsResult[ARGS_ONE] = { nullptr };
506     napi_value retVal;
507     napi_value propValue;
508 
509     napi_create_object(env_, &errJsResult[PARAM0]);
510     napi_create_int32(env_, info.errorCode, &propValue);
511     napi_set_named_property(env_, errJsResult[PARAM0], "code", propValue);
512     ExecuteCallbackNapiPara callbackNapiPara {
513         .recv = nullptr, .argc = ARGS_ONE, .argv = errJsResult, .result = &retVal
514     };
515     ExecuteCallback(CONST_CAPTURE_ERROR, callbackNapiPara);
516 }
517 
ExecuteEstimatedCaptureDurationCb(const CallbackInfo & info) const518 void PhotoOutputCallback::ExecuteEstimatedCaptureDurationCb(const CallbackInfo& info) const
519 {
520     napi_value result[ARGS_TWO] = { nullptr, nullptr };
521     napi_value retVal;
522     napi_get_undefined(env_, &result[PARAM0]);
523     napi_create_int32(env_, info.duration, &result[PARAM1]);
524     ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
525     ExecuteCallback(CONST_CAPTURE_ESTIMATED_CAPTURE_DURATION, callbackNapiPara);
526 }
527 
ExecuteOfflineDeliveryFinishedCb(const CallbackInfo & info) const528 void PhotoOutputCallback::ExecuteOfflineDeliveryFinishedCb(const CallbackInfo& info) const
529 {
530     napi_value result[ARGS_ONE] = { nullptr };
531     napi_value retVal;
532     napi_get_undefined(env_, &result[PARAM0]);
533     ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_ONE, .argv = result, .result = &retVal };
534     ExecuteCallback(CONST_CAPTURE_OFFLINE_DELIVERY_FINISHED, callbackNapiPara);
535 }
536 
ExecutePhotoAvailableCb(const CallbackInfo & info) const537 void PhotoOutputCallback::ExecutePhotoAvailableCb(const CallbackInfo& info) const
538 {
539     MEDIA_INFO_LOG("ExecutePhotoAvailableCb");
540     napi_value result[ARGS_TWO] = {nullptr, nullptr};
541     napi_value retVal;
542     napi_value mainImage = nullptr;
543     napi_get_undefined(env_, &result[PARAM0]);
544     napi_get_undefined(env_, &result[PARAM1]);
545     mainImage = Media::ImageNapi::Create(env_, info.nativeImage);
546     if (mainImage == nullptr) {
547         MEDIA_ERR_LOG("ImageNapi Create failed");
548         napi_get_undefined(env_, &mainImage);
549     }
550     sptr<SurfaceBuffer> imageBuffer;
551     if (info.nativeImage) {
552         // bind imageBuffer life cycle with photoNapiObj
553         imageBuffer = info.nativeImage->GetBuffer();
554     }
555     result[PARAM1] = PhotoNapi::CreatePhoto(env_, mainImage, info.isRaw, imageBuffer);
556     ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
557     ExecuteCallback(CONST_CAPTURE_PHOTO_AVAILABLE, callbackNapiPara);
558 }
559 
ExecutePhotoAssetAvailableCb(const CallbackInfo & info) const560 void PhotoOutputCallback::ExecutePhotoAssetAvailableCb(const CallbackInfo& info) const
561 {
562     MEDIA_INFO_LOG("ExecutePhotoAssetAvailableCb");
563     napi_value result[ARGS_TWO] = {nullptr, nullptr};
564     napi_value retVal;
565     napi_value photoAsset = nullptr;
566     napi_get_undefined(env_, &result[PARAM0]);
567     napi_get_undefined(env_, &result[PARAM1]);
568     photoAsset = Media::MediaLibraryCommNapi::CreatePhotoAssetNapi(env_, info.uri, info.cameraShotType, info.burstKey);
569     if (photoAsset == nullptr) {
570         napi_get_undefined(env_, &photoAsset);
571     }
572     FillNapiObjectWithCaptureId(env_, info.captureID, photoAsset);
573     result[PARAM1] = photoAsset;
574     ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
575     ExecuteCallback(CONST_CAPTURE_PHOTO_ASSET_AVAILABLE, callbackNapiPara);
576 }
577 
ExecuteThumbnailAvailableCb(const CallbackInfo & info) const578 void PhotoOutputCallback::ExecuteThumbnailAvailableCb(const CallbackInfo& info) const
579 {
580     MEDIA_INFO_LOG("ExecuteThumbnailAvailableCb E");
581     napi_value result[ARGS_TWO] = { 0 };
582     napi_get_undefined(env_, &result[0]);
583     napi_get_undefined(env_, &result[1]);
584     napi_value retVal;
585     MEDIA_INFO_LOG("enter ImageNapi::Create start");
586     napi_value valueParam = Media::PixelMapNapi::CreatePixelMap(env_, info.pixelMap);
587     if (valueParam == nullptr) {
588         MEDIA_ERR_LOG("ImageNapi Create failed");
589         napi_get_undefined(env_, &valueParam);
590     }
591     FillPixelMapWithCaptureIdAndTimestamp(env_, info.captureID, info.timestamp, valueParam);
592     MEDIA_INFO_LOG("enter ImageNapi::Create end");
593     result[1] = valueParam;
594     ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
595     ExecuteCallback(CONST_CAPTURE_QUICK_THUMBNAIL, callbackNapiPara);
596     MEDIA_INFO_LOG("ExecuteThumbnailAvailableCb X");
597 }
598 
UpdateJSCallback(PhotoOutputEventType eventType,const CallbackInfo & info) const599 void PhotoOutputCallback::UpdateJSCallback(PhotoOutputEventType eventType, const CallbackInfo& info) const
600 {
601     MEDIA_DEBUG_LOG("UpdateJSCallback is called");
602     switch (eventType) {
603         case PhotoOutputEventType::CAPTURE_START:
604             ExecuteCaptureStartCb(info);
605             break;
606         case PhotoOutputEventType::CAPTURE_END:
607             ExecuteCaptureEndCb(info);
608             break;
609         case PhotoOutputEventType::CAPTURE_FRAME_SHUTTER:
610             ExecuteFrameShutterCb(info);
611             break;
612         case PhotoOutputEventType::CAPTURE_ERROR:
613             ExecuteCaptureErrorCb(info);
614             break;
615         case PhotoOutputEventType::CAPTURE_FRAME_SHUTTER_END:
616             ExecuteFrameShutterEndCb(info);
617             break;
618         case PhotoOutputEventType::CAPTURE_READY:
619             ExecuteCaptureReadyCb(info);
620             break;
621         case PhotoOutputEventType::CAPTURE_ESTIMATED_CAPTURE_DURATION:
622             ExecuteEstimatedCaptureDurationCb(info);
623             break;
624         case PhotoOutputEventType::CAPTURE_START_WITH_INFO:
625             ExecuteCaptureStartWithInfoCb(info);
626             break;
627         case PhotoOutputEventType::CAPTURE_OFFLINE_DELIVERY_FINISHED:
628             ExecuteOfflineDeliveryFinishedCb(info);
629             break;
630         case PhotoOutputEventType::CAPTURE_PHOTO_AVAILABLE:
631             ExecutePhotoAvailableCb(info);
632             break;
633         case PhotoOutputEventType::CAPTURE_PHOTO_ASSET_AVAILABLE:
634             ExecutePhotoAssetAvailableCb(info);
635             break;
636         case PhotoOutputEventType::CAPTURE_THUMBNAIL_AVAILABLE:
637             ExecuteThumbnailAvailableCb(info);
638             break;
639         default:
640             MEDIA_ERR_LOG("Incorrect photo callback event type received from JS");
641     }
642 }
643 
PhotoOutputNapi()644 PhotoOutputNapi::PhotoOutputNapi() {}
645 
~PhotoOutputNapi()646 PhotoOutputNapi::~PhotoOutputNapi()
647 {
648     MEDIA_DEBUG_LOG("~PhotoOutputNapi is called");
649 }
650 
PhotoOutputNapiDestructor(napi_env env,void * nativeObject,void * finalize_hint)651 void PhotoOutputNapi::PhotoOutputNapiDestructor(napi_env env, void* nativeObject, void* finalize_hint)
652 {
653     MEDIA_DEBUG_LOG("PhotoOutputNapiDestructor is called");
654     PhotoOutputNapi* photoOutput = reinterpret_cast<PhotoOutputNapi*>(nativeObject);
655     if (photoOutput != nullptr) {
656         delete photoOutput;
657     }
658 }
659 
Init(napi_env env,napi_value exports)660 napi_value PhotoOutputNapi::Init(napi_env env, napi_value exports)
661 {
662     MEDIA_DEBUG_LOG("Init is called");
663     napi_status status;
664     napi_value ctorObj;
665 
666     napi_property_descriptor photo_output_props[] = {
667         DECLARE_NAPI_FUNCTION("isMovingPhotoSupported", IsMovingPhotoSupported),
668         DECLARE_NAPI_FUNCTION("enableMovingPhoto", EnableMovingPhoto),
669         DECLARE_NAPI_FUNCTION_WRITABLE("capture", Capture),
670         DECLARE_NAPI_FUNCTION("burstCapture", BurstCapture),
671         DECLARE_NAPI_FUNCTION("confirmCapture", ConfirmCapture),
672         DECLARE_NAPI_FUNCTION("release", Release),
673         DECLARE_NAPI_FUNCTION("isMirrorSupported", IsMirrorSupported),
674         DECLARE_NAPI_FUNCTION("enableMirror", EnableMirror),
675         DECLARE_NAPI_FUNCTION("enableQuickThumbnail", EnableQuickThumbnail),
676         DECLARE_NAPI_FUNCTION("isQuickThumbnailSupported", IsQuickThumbnailSupported),
677         DECLARE_NAPI_FUNCTION("enableRawDelivery", EnableRawDelivery),
678         DECLARE_NAPI_FUNCTION("isRawDeliverySupported", IsRawDeliverySupported),
679         DECLARE_NAPI_FUNCTION("getSupportedMovingPhotoVideoCodecTypes", GetSupportedMovingPhotoVideoCodecTypes),
680         DECLARE_NAPI_FUNCTION("setMovingPhotoVideoCodecType", SetMovingPhotoVideoCodecType),
681         DECLARE_NAPI_FUNCTION("on", On),
682         DECLARE_NAPI_FUNCTION("once", Once),
683         DECLARE_NAPI_FUNCTION("off", Off),
684         DECLARE_NAPI_FUNCTION("deferImageDelivery", DeferImageDeliveryFor),
685         DECLARE_NAPI_FUNCTION("deferImageDeliveryFor", DeferImageDeliveryFor),
686         DECLARE_NAPI_FUNCTION("isDeferredImageDeliverySupported", IsDeferredImageDeliverySupported),
687         DECLARE_NAPI_FUNCTION("isDeferredImageDeliveryEnabled", IsDeferredImageDeliveryEnabled),
688         DECLARE_NAPI_FUNCTION("isAutoHighQualityPhotoSupported", IsAutoHighQualityPhotoSupported),
689         DECLARE_NAPI_FUNCTION("enableAutoHighQualityPhoto", EnableAutoHighQualityPhoto),
690         DECLARE_NAPI_FUNCTION("getActiveProfile", GetActiveProfile),
691         DECLARE_NAPI_FUNCTION("getPhotoRotation", GetPhotoRotation),
692         DECLARE_NAPI_FUNCTION("isAutoCloudImageEnhancementSupported", IsAutoCloudImageEnhancementSupported),
693         DECLARE_NAPI_FUNCTION("enableAutoCloudImageEnhancement", EnableAutoCloudImageEnhancement),
694         DECLARE_NAPI_FUNCTION("isDepthDataDeliverySupported", IsDepthDataDeliverySupported),
695         DECLARE_NAPI_FUNCTION("enableDepthDataDelivery", EnableDepthDataDelivery),
696         DECLARE_NAPI_FUNCTION("isAutoAigcPhotoSupported", IsAutoAigcPhotoSupported),
697         DECLARE_NAPI_FUNCTION("enableAutoAigcPhoto", EnableAutoAigcPhoto),
698         DECLARE_NAPI_FUNCTION("isOfflineSupported", IsOfflineSupported),
699         DECLARE_NAPI_FUNCTION("enableOffline", EnableOfflinePhoto)
700     };
701 
702     status = napi_define_class(env, CAMERA_PHOTO_OUTPUT_NAPI_CLASS_NAME, NAPI_AUTO_LENGTH, PhotoOutputNapiConstructor,
703         nullptr, sizeof(photo_output_props) / sizeof(photo_output_props[PARAM0]), photo_output_props, &ctorObj);
704     if (status == napi_ok) {
705         status = NapiRefManager::CreateMemSafetyRef(env, ctorObj, &sConstructor_);
706         if (status == napi_ok) {
707             status = napi_set_named_property(env, exports, CAMERA_PHOTO_OUTPUT_NAPI_CLASS_NAME, ctorObj);
708             CHECK_RETURN_RET(status == napi_ok, exports);
709         }
710     }
711     MEDIA_ERR_LOG("Init call Failed!");
712     return nullptr;
713 }
714 
715 // Constructor callback
PhotoOutputNapiConstructor(napi_env env,napi_callback_info info)716 napi_value PhotoOutputNapi::PhotoOutputNapiConstructor(napi_env env, napi_callback_info info)
717 {
718     MEDIA_DEBUG_LOG("PhotoOutputNapiConstructor is called");
719     napi_status status;
720     napi_value result = nullptr;
721     napi_value thisVar = nullptr;
722 
723     napi_get_undefined(env, &result);
724     CAMERA_NAPI_GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
725 
726     if (status == napi_ok && thisVar != nullptr) {
727         std::unique_ptr<PhotoOutputNapi> obj = std::make_unique<PhotoOutputNapi>();
728         obj->photoOutput_ = sPhotoOutput_;
729         obj->profile_ = sPhotoOutput_->GetPhotoProfile();
730         status = napi_wrap(env, thisVar, reinterpret_cast<void*>(obj.get()),
731 		    PhotoOutputNapi::PhotoOutputNapiDestructor, nullptr, nullptr);
732         if (status == napi_ok) {
733             obj.release();
734             return thisVar;
735         } else {
736             MEDIA_ERR_LOG("Failure wrapping js to native napi");
737         }
738     }
739     MEDIA_ERR_LOG("PhotoOutputNapiConstructor call Failed!");
740     return result;
741 }
742 
GetPhotoOutput()743 sptr<PhotoOutput> PhotoOutputNapi::GetPhotoOutput()
744 {
745     return photoOutput_;
746 }
747 
GetEnableMirror()748 bool PhotoOutputNapi::GetEnableMirror()
749 {
750     return isMirrorEnabled_;
751 }
752 
IsPhotoOutput(napi_env env,napi_value obj)753 bool PhotoOutputNapi::IsPhotoOutput(napi_env env, napi_value obj)
754 {
755     MEDIA_DEBUG_LOG("IsPhotoOutput is called");
756     bool result = false;
757     napi_status status;
758     napi_value constructor = nullptr;
759 
760     status = napi_get_reference_value(env, sConstructor_, &constructor);
761     if (status == napi_ok) {
762         status = napi_instanceof(env, obj, constructor, &result);
763         if (status != napi_ok) {
764             MEDIA_DEBUG_LOG("PhotoOutputNapi::IsPhotoOutput is failed");
765             result = false;
766         }
767     }
768     return result;
769 }
770 
CreatePhotoOutput(napi_env env,Profile & profile,std::string surfaceId)771 napi_value PhotoOutputNapi::CreatePhotoOutput(napi_env env, Profile& profile, std::string surfaceId)
772 {
773     MEDIA_DEBUG_LOG("CreatePhotoOutput is called, profile CameraFormat= %{public}d", profile.GetCameraFormat());
774     CAMERA_SYNC_TRACE;
775     napi_value result = nullptr;
776     napi_get_undefined(env, &result);
777     napi_value constructor;
778     napi_status status = napi_get_reference_value(env, sConstructor_, &constructor);
779     if (status == napi_ok) {
780         MEDIA_INFO_LOG("CreatePhotoOutput surfaceId: %{public}s", surfaceId.c_str());
781         int retCode = SUCCESS;
782         if (surfaceId == "") {
783             MEDIA_INFO_LOG("create surface on camera service");
784             retCode = CameraManager::GetInstance()->CreatePhotoOutput(profile, &sPhotoOutput_);
785         } else {
786             MEDIA_INFO_LOG("get surface by surfaceId");
787             sptr<Surface> photoSurface;
788             photoSurface = Media::ImageReceiver::getSurfaceById(surfaceId);
789             CHECK_RETURN_RET_ELOG(photoSurface == nullptr, result, "failed to get photoSurface");
790             photoSurface->SetUserData(CameraManager::surfaceFormat, std::to_string(profile.GetCameraFormat()));
791             sptr<IBufferProducer> producer = photoSurface->GetProducer();
792             CHECK_RETURN_RET_ELOG(producer == nullptr, result, "failed to create GetProducer");
793             MEDIA_INFO_LOG("profile width: %{public}d, height: %{public}d, format = %{public}d, "
794                            "surface width: %{public}d, height: %{public}d",
795                 profile.GetSize().width,
796                 profile.GetSize().height,
797                 static_cast<int32_t>(profile.GetCameraFormat()),
798                 photoSurface->GetDefaultWidth(),
799                 photoSurface->GetDefaultHeight());
800             retCode =
801                 CameraManager::GetInstance()->CreatePhotoOutput(profile, producer, &sPhotoOutput_, photoSurface);
802         }
803         CHECK_RETURN_RET_ELOG(!CameraNapiUtils::CheckError(env, retCode) || sPhotoOutput_ == nullptr,
804             result, "failed to create CreatePhotoOutput");
805         CHECK_EXECUTE(surfaceId == "", sPhotoOutput_->SetNativeSurface(true));
806         status = napi_new_instance(env, constructor, 0, nullptr, &result);
807         sPhotoOutput_ = nullptr;
808         if (status == napi_ok && result != nullptr) {
809             MEDIA_INFO_LOG("Success to create photo output instance");
810             return result;
811         }
812     }
813     MEDIA_ERR_LOG("CreatePhotoOutput call Failed!");
814     return result;
815 }
816 
CreatePhotoOutput(napi_env env,std::string surfaceId)817 napi_value PhotoOutputNapi::CreatePhotoOutput(napi_env env, std::string surfaceId)
818 {
819     MEDIA_INFO_LOG("CreatePhotoOutput with only surfaceId is called");
820     CAMERA_SYNC_TRACE;
821     napi_status status;
822     napi_value result = nullptr;
823     napi_value constructor;
824     napi_get_undefined(env, &result);
825     status = napi_get_reference_value(env, sConstructor_, &constructor);
826     if (status == napi_ok) {
827         MEDIA_INFO_LOG("CreatePhotoOutput surfaceId: %{public}s", surfaceId.c_str());
828         int retCode = SUCCESS;
829         if (surfaceId == "") {
830             MEDIA_INFO_LOG("create surface on camera service");
831             retCode = CameraManager::GetInstance()->CreatePhotoOutputWithoutProfile(&sPhotoOutput_);
832         } else {
833             MEDIA_INFO_LOG("get surface by surfaceId");
834             sptr<Surface> photoSurface = Media::ImageReceiver::getSurfaceById(surfaceId);
835             CHECK_RETURN_RET_ELOG(photoSurface == nullptr, result, "failed to get photoSurface");
836             sptr<IBufferProducer> producer = photoSurface->GetProducer();
837             CHECK_RETURN_RET_ELOG(producer == nullptr, result, "failed to create GetProducer");
838             MEDIA_INFO_LOG("surface width: %{public}d, height: %{public}d",
839                            photoSurface->GetDefaultWidth(), photoSurface->GetDefaultHeight());
840             retCode = CameraManager::GetInstance()->CreatePhotoOutputWithoutProfile(
841                 producer, &sPhotoOutput_, photoSurface);
842         }
843         CHECK_RETURN_RET_ELOG(!CameraNapiUtils::CheckError(env, retCode) || sPhotoOutput_ == nullptr,
844             result, "failed to create CreatePhotoOutput");
845         CHECK_EXECUTE(surfaceId == "", sPhotoOutput_->SetNativeSurface(true));
846         status = napi_new_instance(env, constructor, 0, nullptr, &result);
847         sPhotoOutput_ = nullptr;
848         if (status == napi_ok && result != nullptr) {
849             MEDIA_DEBUG_LOG("Success to create photo output instance");
850             return result;
851         }
852     }
853     MEDIA_ERR_LOG("CreatePhotoOutput call Failed!");
854     return result;
855 }
856 
ParseCaptureSettings(napi_env env,napi_callback_info info,PhotoOutputAsyncContext * asyncContext,std::shared_ptr<CameraNapiAsyncFunction> & asyncFunction,bool isSettingOptional)857 bool ParseCaptureSettings(napi_env env, napi_callback_info info, PhotoOutputAsyncContext* asyncContext,
858     std::shared_ptr<CameraNapiAsyncFunction>& asyncFunction, bool isSettingOptional)
859 {
860     Location settingsLocation;
861     CameraNapiObject settingsLocationNapiOjbect { {
862         { "latitude", &settingsLocation.latitude },
863         { "longitude", &settingsLocation.longitude },
864         { "altitude", &settingsLocation.altitude },
865     } };
866     CameraNapiObject settingsNapiOjbect { {
867         { "quality", &asyncContext->quality },
868         { "rotation", &asyncContext->rotation },
869         { "location", &settingsLocationNapiOjbect },
870         { "mirror", &asyncContext->isMirror },
871     } };
872     unordered_set<std::string> optionalKeys = { "quality", "rotation", "location", "mirror" };
873     settingsNapiOjbect.SetOptionalKeys(optionalKeys);
874 
875     asyncFunction =
876         std::make_shared<CameraNapiAsyncFunction>(env, "Capture", asyncContext->callbackRef, asyncContext->deferred);
877     CameraNapiParamParser jsParamParser(env, info, asyncContext->objectInfo, asyncFunction, settingsNapiOjbect);
878     if (jsParamParser.IsStatusOk()) {
879         if (settingsNapiOjbect.IsKeySetted("quality") && !ValidQualityLevelFromJs(asyncContext->quality)) {
880             CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "quality field not legal");
881             return false;
882         }
883         if (settingsNapiOjbect.IsKeySetted("rotation") && !ValidImageRotationFromJs(asyncContext->rotation)) {
884             CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "rotation field not legal");
885             return false;
886         }
887         if (settingsNapiOjbect.IsKeySetted("mirror") && asyncContext->isMirror) {
888             MEDIA_INFO_LOG("GetMirrorStatus is ok!");
889             asyncContext->isMirrorSettedByUser = true;
890         }
891         MEDIA_INFO_LOG("ParseCaptureSettings with capture settings pass");
892         asyncContext->hasPhotoSettings = true;
893         if (settingsNapiOjbect.IsKeySetted("location")) {
894             asyncContext->location = std::make_shared<Location>(settingsLocation);
895         }
896     } else if (isSettingOptional) {
897         MEDIA_WARNING_LOG("ParseCaptureSettings check capture settings fail, try capture without settings");
898         jsParamParser = CameraNapiParamParser(env, info, asyncContext->objectInfo, asyncFunction);
899     } else {
900         // Do nothing.
901     }
902     CHECK_RETURN_RET_ELOG(!jsParamParser.AssertStatus(INVALID_ARGUMENT, "invalid argument"), false,
903         "ParseCaptureSettings invalid argument");
904     asyncContext->HoldNapiValue(env, jsParamParser.GetThisVar());
905     return true;
906 }
907 
Capture(napi_env env,napi_callback_info info)908 napi_value PhotoOutputNapi::Capture(napi_env env, napi_callback_info info)
909 {
910     MEDIA_INFO_LOG("Capture is called");
911     std::unique_ptr<PhotoOutputAsyncContext> asyncContext = std::make_unique<PhotoOutputAsyncContext>(
912         "PhotoOutputNapi::Capture", CameraNapiUtils::IncrementAndGet(photoOutputTaskId));
913     std::shared_ptr<CameraNapiAsyncFunction> asyncFunction;
914     CHECK_RETURN_RET_ELOG(!ParseCaptureSettings(env, info, asyncContext.get(), asyncFunction, true), nullptr,
915         "PhotoOutputNapi::Capture parse parameters fail.");
916     napi_status status = napi_create_async_work(
917         env, nullptr, asyncFunction->GetResourceName(),
918         [](napi_env env, void* data) {
919             MEDIA_INFO_LOG("PhotoOutputNapi::Capture running on worker");
920             auto context = static_cast<PhotoOutputAsyncContext*>(data);
921             CHECK_RETURN_ELOG(context->objectInfo == nullptr, "PhotoOutputNapi::Capture async info is nullptr");
922             CAMERA_START_ASYNC_TRACE(context->funcName, context->taskId);
923             CameraNapiWorkerQueueKeeper::GetInstance()->ConsumeWorkerQueueTask(
924                 context->queueTask, [&context]() { ProcessCapture(context, false); });
925         },
926         AsyncCompleteCallback, static_cast<void*>(asyncContext.get()), &asyncContext->work);
927     if (status != napi_ok) {
928         MEDIA_ERR_LOG("Failed to create napi_create_async_work for PhotoOutputNapi::Capture");
929         asyncFunction->Reset();
930     } else {
931         asyncContext->queueTask =
932             CameraNapiWorkerQueueKeeper::GetInstance()->AcquireWorkerQueueTask("PhotoOutputNapi::Capture");
933         napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
934         asyncContext.release();
935     }
936     CHECK_RETURN_RET(asyncFunction->GetAsyncFunctionType() == ASYNC_FUN_TYPE_PROMISE,
937         asyncFunction->GetPromise());
938     return CameraNapiUtils::GetUndefinedValue(env);
939 }
940 
BurstCapture(napi_env env,napi_callback_info info)941 napi_value PhotoOutputNapi::BurstCapture(napi_env env, napi_callback_info info)
942 {
943     MEDIA_INFO_LOG("BurstCapture is called");
944     CHECK_RETURN_RET_ELOG(!CameraNapiSecurity::CheckSystemApp(env), nullptr,
945         "SystemApi EnableAutoHighQualityPhoto is called!");
946     std::unique_ptr<PhotoOutputAsyncContext> asyncContext = std::make_unique<PhotoOutputAsyncContext>(
947         "PhotoOutputNapi::BurstCapture", CameraNapiUtils::IncrementAndGet(photoOutputTaskId));
948     std::shared_ptr<CameraNapiAsyncFunction> asyncFunction;
949     CHECK_RETURN_RET_ELOG(!ParseCaptureSettings(env, info, asyncContext.get(), asyncFunction, false),
950         nullptr, "PhotoOutputNapi::BurstCapture parse parameters fail.");
951     napi_status status = napi_create_async_work(
952         env, nullptr, asyncFunction->GetResourceName(),
953         [](napi_env env, void* data) {
954             MEDIA_INFO_LOG("PhotoOutputNapi::BurstCapture running on worker");
955             auto context = static_cast<PhotoOutputAsyncContext*>(data);
956             CHECK_RETURN_ELOG(
957                 context->objectInfo == nullptr, "PhotoOutputNapi::BurstCapture async info is nullptr");
958             CAMERA_START_ASYNC_TRACE(context->funcName, context->taskId);
959             CameraNapiWorkerQueueKeeper::GetInstance()->ConsumeWorkerQueueTask(
960                 context->queueTask, [&context]() { ProcessCapture(context, true); });
961         },
962         AsyncCompleteCallback, static_cast<void*>(asyncContext.get()), &asyncContext->work);
963     if (status != napi_ok) {
964         MEDIA_ERR_LOG("Failed to create napi_create_async_work for PhotoOutputNapi::BurstCapture");
965         asyncFunction->Reset();
966     } else {
967         asyncContext->queueTask =
968             CameraNapiWorkerQueueKeeper::GetInstance()->AcquireWorkerQueueTask("PhotoOutputNapi::BurstCapture");
969         napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
970         asyncContext.release();
971     }
972     CHECK_RETURN_RET(asyncFunction->GetAsyncFunctionType() == ASYNC_FUN_TYPE_PROMISE,
973         asyncFunction->GetPromise());
974     return CameraNapiUtils::GetUndefinedValue(env);
975 }
976 
ConfirmCapture(napi_env env,napi_callback_info info)977 napi_value PhotoOutputNapi::ConfirmCapture(napi_env env, napi_callback_info info)
978 {
979     MEDIA_INFO_LOG("ConfirmCapture is called");
980     napi_status status;
981     napi_value result = nullptr;
982     size_t argc = ARGS_ZERO;
983     napi_value argv[ARGS_ZERO] = {};
984     napi_value thisVar = nullptr;
985 
986     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
987 
988     napi_get_undefined(env, &result);
989     PhotoOutputNapi* photoOutputNapi = nullptr;
990     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
991     if (status == napi_ok && photoOutputNapi != nullptr) {
992         int32_t retCode = photoOutputNapi->photoOutput_->ConfirmCapture();
993         CHECK_RETURN_RET(!CameraNapiUtils::CheckError(env, retCode), result);
994     }
995     return result;
996 }
997 
Release(napi_env env,napi_callback_info info)998 napi_value PhotoOutputNapi::Release(napi_env env, napi_callback_info info)
999 {
1000     MEDIA_INFO_LOG("Release is called");
1001     std::unique_ptr<PhotoOutputAsyncContext> asyncContext = std::make_unique<PhotoOutputAsyncContext>(
1002         "PhotoOutputNapi::Release", CameraNapiUtils::IncrementAndGet(photoOutputTaskId));
1003     auto asyncFunc =
1004         std::make_shared<CameraNapiAsyncFunction>(env, "Release", asyncContext->callbackRef, asyncContext->deferred);
1005     CameraNapiParamParser jsParamParser(env, info, asyncContext->objectInfo, asyncFunc);
1006     CHECK_RETURN_RET_ELOG(!jsParamParser.AssertStatus(INVALID_ARGUMENT, "invalid argument"), nullptr,
1007         "PhotoOutputNapi::Release invalid argument");
1008     asyncContext->HoldNapiValue(env, jsParamParser.GetThisVar());
1009     napi_status status = napi_create_async_work(
1010         env, nullptr, asyncFunc->GetResourceName(),
1011         [](napi_env env, void* data) {
1012             MEDIA_INFO_LOG("PhotoOutputNapi::Release running on worker");
1013             auto context = static_cast<PhotoOutputAsyncContext*>(data);
1014             CHECK_RETURN_ELOG(context->objectInfo == nullptr, "PhotoOutputNapi::Release async info is nullptr");
1015             CAMERA_START_ASYNC_TRACE(context->funcName, context->taskId);
1016             CameraNapiWorkerQueueKeeper::GetInstance()->ConsumeWorkerQueueTask(context->queueTask, [&context]() {
1017                 context->errorCode = context->objectInfo->photoOutput_->Release();
1018                 context->status = context->errorCode == CameraErrorCode::SUCCESS;
1019             });
1020         },
1021         AsyncCompleteCallback, static_cast<void*>(asyncContext.get()), &asyncContext->work);
1022     if (status != napi_ok) {
1023         MEDIA_ERR_LOG("Failed to create napi_create_async_work for PhotoOutputNapi::Release");
1024         asyncFunc->Reset();
1025     } else {
1026         asyncContext->queueTask =
1027             CameraNapiWorkerQueueKeeper::GetInstance()->AcquireWorkerQueueTask("PhotoOutputNapi::Release");
1028         napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
1029         asyncContext.release();
1030     }
1031     CHECK_RETURN_RET(asyncFunc->GetAsyncFunctionType() == ASYNC_FUN_TYPE_PROMISE,
1032         asyncFunc->GetPromise());
1033     return CameraNapiUtils::GetUndefinedValue(env);
1034 }
1035 
IsMirrorSupported(napi_env env,napi_callback_info info)1036 napi_value PhotoOutputNapi::IsMirrorSupported(napi_env env, napi_callback_info info)
1037 {
1038     MEDIA_INFO_LOG("IsMirrorSupported is called");
1039     napi_status status;
1040     napi_value result = nullptr;
1041     size_t argc = ARGS_ZERO;
1042     napi_value argv[ARGS_ZERO];
1043     napi_value thisVar = nullptr;
1044 
1045     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
1046 
1047     napi_get_undefined(env, &result);
1048     PhotoOutputNapi* photoOutputNapi = nullptr;
1049     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
1050     if (status == napi_ok && photoOutputNapi != nullptr) {
1051         bool isSupported = photoOutputNapi->photoOutput_->IsMirrorSupported();
1052         napi_get_boolean(env, isSupported, &result);
1053     } else {
1054         MEDIA_ERR_LOG("IsMirrorSupported call Failed!");
1055     }
1056     return result;
1057 }
1058 
EnableMirror(napi_env env,napi_callback_info info)1059 napi_value PhotoOutputNapi::EnableMirror(napi_env env, napi_callback_info info)
1060 {
1061     auto result = CameraNapiUtils::GetUndefinedValue(env);
1062     MEDIA_DEBUG_LOG("PhotoOutputNapi::EnableMirror is called");
1063     bool isMirror = false;
1064     PhotoOutputNapi* photoOutputNapi = nullptr;
1065     CameraNapiParamParser jsParamParser(env, info, photoOutputNapi, isMirror);
1066     if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "invalid argument")) {
1067         MEDIA_ERR_LOG("PhotoOutputNapi::EnableMirror invalid argument");
1068         return nullptr;
1069     }
1070     auto session = photoOutputNapi->GetPhotoOutput()->GetSession();
1071     if (session != nullptr) {
1072         photoOutputNapi->isMirrorEnabled_ = isMirror;
1073         int32_t retCode = photoOutputNapi->photoOutput_->EnableMirror(isMirror);
1074         if (!CameraNapiUtils::CheckError(env, retCode)) {
1075             return result;
1076         }
1077     }
1078     return result;
1079 }
1080 
IsQuickThumbnailSupported(napi_env env,napi_callback_info info)1081 napi_value PhotoOutputNapi::IsQuickThumbnailSupported(napi_env env, napi_callback_info info)
1082 {
1083     if (!CameraNapiSecurity::CheckSystemApp(env)) {
1084         MEDIA_ERR_LOG("SystemApi IsQuickThumbnailSupported is called!");
1085         return nullptr;
1086     }
1087     napi_status status;
1088     napi_value result = nullptr;
1089     size_t argc = ARGS_ZERO;
1090     napi_value argv[ARGS_ZERO];
1091     napi_value thisVar = nullptr;
1092 
1093     MEDIA_DEBUG_LOG("PhotoOutputNapi::IsQuickThumbnailSupported get js args");
1094     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
1095 
1096     napi_get_undefined(env, &result);
1097     PhotoOutputNapi* photoOutputNapi = nullptr;
1098     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
1099     if (status == napi_ok && photoOutputNapi != nullptr) {
1100         int32_t retCode = photoOutputNapi->photoOutput_->IsQuickThumbnailSupported();
1101         bool isSupported = (retCode == 0);
1102         CHECK_RETURN_RET(retCode > 0 && !CameraNapiUtils::CheckError(env, retCode), result);
1103         napi_get_boolean(env, isSupported, &result);
1104     }
1105     return result;
1106 }
1107 
DeferImageDeliveryFor(napi_env env,napi_callback_info info)1108 napi_value PhotoOutputNapi::DeferImageDeliveryFor(napi_env env, napi_callback_info info)
1109 {
1110     CHECK_RETURN_RET_ELOG(!CameraNapiSecurity::CheckSystemApp(env), nullptr,
1111         "SystemApi DeferImageDeliveryFor is called!");
1112     napi_status status;
1113     napi_value result = nullptr;
1114     size_t argc = ARGS_ONE;
1115     napi_value argv[ARGS_ONE] = {0};
1116     napi_value thisVar = nullptr;
1117     MEDIA_DEBUG_LOG("PhotoOutputNapi::DeferImageDeliveryFor get js args");
1118     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
1119     NAPI_ASSERT(env, argc == ARGS_ONE, "requires one parameter");
1120     napi_get_undefined(env, &result);
1121     PhotoOutputNapi* photoOutputNapi = nullptr;
1122     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
1123     if (status == napi_ok && photoOutputNapi != nullptr) {
1124         int32_t deliveryType;
1125         napi_get_value_int32(env, argv[PARAM0], &deliveryType);
1126         photoOutputNapi->photoOutput_->DeferImageDeliveryFor(static_cast<DeferredDeliveryImageType>(deliveryType));
1127         photoOutputNapi->isDeferredPhotoEnabled_ = deliveryType == DELIVERY_PHOTO;
1128     }
1129     return result;
1130 }
1131 
IsDeferredImageDeliverySupported(napi_env env,napi_callback_info info)1132 napi_value PhotoOutputNapi::IsDeferredImageDeliverySupported(napi_env env, napi_callback_info info)
1133 {
1134     CHECK_RETURN_RET_ELOG(!CameraNapiSecurity::CheckSystemApp(env), nullptr,
1135         "SystemApi IsDeferredImageDeliverySupported is called!");
1136     napi_status status;
1137     napi_value result = nullptr;
1138     size_t argc = ARGS_ONE;
1139     napi_value argv[ARGS_ONE] = {0};
1140     napi_value thisVar = nullptr;
1141     MEDIA_DEBUG_LOG("PhotoOutputNapi::IsDeferredImageDeliverySupported get js args");
1142     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
1143     NAPI_ASSERT(env, argc == ARGS_ONE, "requires one parameter");
1144     napi_get_undefined(env, &result);
1145     PhotoOutputNapi* photoOutputNapi = nullptr;
1146     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
1147     if (status == napi_ok && photoOutputNapi != nullptr) {
1148         int32_t deliveryType;
1149         napi_get_value_int32(env, argv[PARAM0], &deliveryType);
1150         int32_t retCode = photoOutputNapi->photoOutput_->IsDeferredImageDeliverySupported(
1151             static_cast<DeferredDeliveryImageType>(deliveryType));
1152         bool isSupported = (retCode == 0);
1153         CHECK_RETURN_RET(retCode > 0 && !CameraNapiUtils::CheckError(env, retCode), result);
1154         napi_get_boolean(env, isSupported, &result);
1155     }
1156     return result;
1157 }
1158 
IsDeferredImageDeliveryEnabled(napi_env env,napi_callback_info info)1159 napi_value PhotoOutputNapi::IsDeferredImageDeliveryEnabled(napi_env env, napi_callback_info info)
1160 {
1161     CHECK_RETURN_RET_ELOG(!CameraNapiSecurity::CheckSystemApp(env), nullptr,
1162         "SystemApi IsDeferredImageDeliveryEnabled is called!");
1163     napi_status status;
1164     napi_value result = nullptr;
1165     size_t argc = ARGS_ONE;
1166     napi_value argv[ARGS_ONE] = {0};
1167     napi_value thisVar = nullptr;
1168     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
1169     NAPI_ASSERT(env, argc == ARGS_ONE, "requires one parameter");
1170     napi_get_undefined(env, &result);
1171     PhotoOutputNapi* photoOutputNapi = nullptr;
1172     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
1173     if (status == napi_ok && photoOutputNapi != nullptr) {
1174         int32_t deliveryType;
1175         napi_get_value_int32(env, argv[PARAM0], &deliveryType);
1176         int32_t retCode = photoOutputNapi->photoOutput_->IsDeferredImageDeliveryEnabled(
1177             static_cast<DeferredDeliveryImageType>(deliveryType));
1178         bool isSupported = (retCode == 0);
1179         CHECK_RETURN_RET(retCode > 0 && !CameraNapiUtils::CheckError(env, retCode), result);
1180         napi_get_boolean(env, isSupported, &result);
1181     }
1182     return result;
1183 }
1184 
GetPhotoRotation(napi_env env,napi_callback_info info)1185 napi_value PhotoOutputNapi::GetPhotoRotation(napi_env env, napi_callback_info info)
1186 {
1187     MEDIA_DEBUG_LOG("GetPhotoRotation is called!");
1188     napi_status status;
1189     napi_value result = nullptr;
1190     size_t argc = ARGS_ONE;
1191     napi_value argv[ARGS_ONE] = {0};
1192     napi_value thisVar = nullptr;
1193     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
1194 
1195     napi_get_undefined(env, &result);
1196     PhotoOutputNapi* photoOutputNapi = nullptr;
1197     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
1198     if (status == napi_ok && photoOutputNapi != nullptr) {
1199         int32_t value;
1200         napi_status ret = napi_get_value_int32(env, argv[PARAM0], &value);
1201         if (ret != napi_ok) {
1202             CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT,
1203                 "GetPhotoRotation parameter missing or parameter type incorrect.");
1204             return result;
1205         }
1206         int32_t retCode = photoOutputNapi->photoOutput_->GetPhotoRotation(value);
1207         if (retCode == SERVICE_FATL_ERROR) {
1208             CameraNapiUtils::ThrowError(env, SERVICE_FATL_ERROR,
1209                 "GetPhotoRotation Camera service fatal error.");
1210             return result;
1211         }
1212         napi_create_int32(env, retCode, &result);
1213         MEDIA_INFO_LOG("PhotoOutputNapi GetPhotoRotation! %{public}d", retCode);
1214     } else {
1215         MEDIA_ERR_LOG("PhotoOutputNapi GetPhotoRotation! called failed!");
1216     }
1217     return result;
1218 }
1219 
IsMovingPhotoSupported(napi_env env,napi_callback_info info)1220 napi_value PhotoOutputNapi::IsMovingPhotoSupported(napi_env env, napi_callback_info info)
1221 {
1222     MEDIA_DEBUG_LOG("PhotoOutputNapi::IsMovingPhotoSupported is called");
1223     napi_status status;
1224     napi_value result = nullptr;
1225     size_t argc = ARGS_ZERO;
1226     napi_value argv[ARGS_ZERO];
1227     napi_value thisVar = nullptr;
1228 
1229     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
1230 
1231     napi_get_undefined(env, &result);
1232     PhotoOutputNapi* photoOutputNapi = nullptr;
1233     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
1234     CHECK_RETURN_RET_ELOG(status != napi_ok || photoOutputNapi == nullptr, result,
1235         "PhotoOutputNapi::IsMovingPhotoSupported photoOutputNapi is null!");
1236     auto session = photoOutputNapi->GetPhotoOutput()->GetSession();
1237     if (session != nullptr) {
1238         bool isSupported = session->IsMovingPhotoSupported();
1239         napi_get_boolean(env, isSupported, &result);
1240     } else {
1241         napi_get_boolean(env, false, &result);
1242         MEDIA_ERR_LOG("PhotoOutputNapi::IsMovingPhotoSupported call Failed!");
1243     }
1244     return result;
1245 }
1246 
EnableMovingPhoto(napi_env env,napi_callback_info info)1247 napi_value PhotoOutputNapi::EnableMovingPhoto(napi_env env, napi_callback_info info)
1248 {
1249     MEDIA_DEBUG_LOG("PhotoOutputNapi::enableMovingPhoto is called");
1250     napi_status status;
1251     napi_value result = nullptr;
1252     size_t argc = ARGS_ONE;
1253     napi_value argv[ARGS_ONE] = { 0 };
1254     napi_value thisVar = nullptr;
1255     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
1256     NAPI_ASSERT(env, argc == ARGS_ONE, "requires one parameter");
1257     napi_valuetype valueType = napi_undefined;
1258     napi_typeof(env, argv[0], &valueType);
1259     CHECK_RETURN_RET(valueType != napi_boolean && !CameraNapiUtils::CheckError(env, INVALID_ARGUMENT), result);
1260     napi_get_undefined(env, &result);
1261     PhotoOutputNapi* photoOutputNapi = nullptr;
1262     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
1263     CHECK_RETURN_RET_ELOG(status != napi_ok || photoOutputNapi == nullptr, result,
1264         "PhotoOutputNapi::EnableMovingPhoto photoOutputNapi is null!");
1265     auto session = photoOutputNapi->GetPhotoOutput()->GetSession();
1266     if (session != nullptr) {
1267         bool isEnableMovingPhoto;
1268         napi_get_value_bool(env, argv[PARAM0], &isEnableMovingPhoto);
1269         if (photoOutputNapi->GetPhotoOutput()) {
1270             photoOutputNapi->GetPhotoOutput()->EnableMovingPhoto(isEnableMovingPhoto);
1271         }
1272         session->LockForControl();
1273         int32_t retCode = session->EnableMovingPhoto(isEnableMovingPhoto);
1274         session->UnlockForControl();
1275         CHECK_RETURN_RET(retCode != 0 && !CameraNapiUtils::CheckError(env, retCode), result);
1276     }
1277     return result;
1278 }
1279 
1280 enum VideoCodecType : int32_t {
1281     VIDEO_ENCODE_TYPE_AVC = 0,
1282     VIDEO_ENCODE_TYPE_HEVC,
1283 };
1284 
GetSupportedMovingPhotoVideoCodecTypes(napi_env env,napi_callback_info info)1285 napi_value PhotoOutputNapi::GetSupportedMovingPhotoVideoCodecTypes(napi_env env, napi_callback_info info)
1286 {
1287     MEDIA_DEBUG_LOG("PhotoOutputNapi::GetSupportedMovingPhotoVideoCodecTypes is called");
1288     napi_status status;
1289     napi_value result = nullptr;
1290     size_t argc = ARGS_ZERO;
1291     napi_value argv[ARGS_ZERO];
1292     napi_value thisVar = nullptr;
1293 
1294     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
1295 
1296     napi_get_undefined(env, &result);
1297     PhotoOutputNapi* photoOutputNapi = nullptr;
1298     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
1299     CHECK_RETURN_RET_ELOG(status != napi_ok || photoOutputNapi == nullptr, result,
1300         "PhotoOutputNapi::GetSupportedMovingPhotoVideoCodecTypes photoOutputNapi is null!");
1301     vector<int32_t> videoCodecTypes = {VideoCodecType::VIDEO_ENCODE_TYPE_AVC, VideoCodecType::VIDEO_ENCODE_TYPE_HEVC};
1302     result = CameraNapiUtils::CreateJSArray(env, status, videoCodecTypes);
1303     if (status != napi_ok) {
1304         result = CameraNapiUtils::CreateJSArray(env, status, {});
1305     }
1306     return result;
1307 }
1308 
SetMovingPhotoVideoCodecType(napi_env env,napi_callback_info info)1309 napi_value PhotoOutputNapi::SetMovingPhotoVideoCodecType(napi_env env, napi_callback_info info)
1310 {
1311     MEDIA_DEBUG_LOG("PhotoOutputNapi::SetMovingPhotoVideoCodecType is called");
1312     napi_status status;
1313     napi_value result = nullptr;
1314     size_t argc = ARGS_ONE;
1315     napi_value argv[ARGS_ONE] = { 0 };
1316     napi_value thisVar = nullptr;
1317     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
1318     NAPI_ASSERT(env, argc == ARGS_ONE, "requires one parameter");
1319     napi_valuetype valueType = napi_undefined;
1320     napi_typeof(env, argv[0], &valueType);
1321     CHECK_RETURN_RET(valueType != napi_number && !CameraNapiUtils::CheckError(env, INVALID_ARGUMENT), result);
1322     napi_get_undefined(env, &result);
1323     PhotoOutputNapi* photoOutputNapi = nullptr;
1324     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
1325     CHECK_RETURN_RET_ELOG(status != napi_ok || photoOutputNapi == nullptr, result,
1326         "PhotoOutputNapi::SetMovingPhotoVideoCodecType photoOutputNapi is null!");
1327     if (photoOutputNapi->GetPhotoOutput() != nullptr) {
1328         int32_t codecType;
1329         napi_get_value_int32(env, argv[PARAM0], &codecType);
1330         int32_t retCode = photoOutputNapi->GetPhotoOutput()->SetMovingPhotoVideoCodecType(codecType);
1331         CHECK_RETURN_RET(retCode != 0 && !CameraNapiUtils::CheckError(env, retCode), result);
1332     }
1333     return result;
1334 }
1335 
EnableQuickThumbnail(napi_env env,napi_callback_info info)1336 napi_value PhotoOutputNapi::EnableQuickThumbnail(napi_env env, napi_callback_info info)
1337 {
1338     CHECK_RETURN_RET_ELOG(!CameraNapiSecurity::CheckSystemApp(env), nullptr,
1339         "SystemApi PhotoOutputNapi::EnableQuickThumbnail is called!");
1340     napi_status status;
1341     napi_value result = nullptr;
1342     size_t argc = ARGS_ONE;
1343     napi_value argv[ARGS_ONE] = { 0 };
1344     napi_value thisVar = nullptr;
1345     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
1346     NAPI_ASSERT(env, argc == ARGS_ONE, "requires one parameter");
1347     napi_valuetype valueType = napi_undefined;
1348     napi_typeof(env, argv[0], &valueType);
1349     CHECK_RETURN_RET(valueType != napi_boolean && !CameraNapiUtils::CheckError(env, INVALID_ARGUMENT), result);
1350     napi_get_undefined(env, &result);
1351     PhotoOutputNapi* photoOutputNapi = nullptr;
1352     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
1353     bool thumbnailSwitch;
1354     if (status == napi_ok && photoOutputNapi != nullptr) {
1355         napi_get_value_bool(env, argv[PARAM0], &thumbnailSwitch);
1356         photoOutputNapi->isQuickThumbnailEnabled_ = thumbnailSwitch;
1357         int32_t retCode = photoOutputNapi->photoOutput_->SetThumbnail(thumbnailSwitch);
1358         CHECK_RETURN_RET(retCode != 0 && !CameraNapiUtils::CheckError(env, retCode), result);
1359     }
1360     return result;
1361 }
1362 
IsRawDeliverySupported(napi_env env,napi_callback_info info)1363 napi_value PhotoOutputNapi::IsRawDeliverySupported(napi_env env, napi_callback_info info)
1364 {
1365     CHECK_RETURN_RET_ELOG(!CameraNapiSecurity::CheckSystemApp(env), nullptr,
1366         "SystemApi IsRawDeliverySupported is called!");
1367     napi_status status;
1368     napi_value result = nullptr;
1369     size_t argc = ARGS_ZERO;
1370     napi_value argv[ARGS_ZERO];
1371     napi_value thisVar = nullptr;
1372 
1373     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
1374 
1375     napi_get_undefined(env, &result);
1376     bool isSupported = false;
1377     PhotoOutputNapi* photoOutputNapi = nullptr;
1378     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
1379     if (status == napi_ok && photoOutputNapi != nullptr) {
1380         int32_t retCode = photoOutputNapi->photoOutput_->IsRawDeliverySupported(isSupported);
1381         CHECK_RETURN_RET(!CameraNapiUtils::CheckError(env, retCode), nullptr);
1382     }
1383     napi_get_boolean(env, isSupported, &result);
1384     return result;
1385 }
1386 
EnableRawDelivery(napi_env env,napi_callback_info info)1387 napi_value PhotoOutputNapi::EnableRawDelivery(napi_env env, napi_callback_info info)
1388 {
1389     CHECK_RETURN_RET_ELOG(!CameraNapiSecurity::CheckSystemApp(env), nullptr,
1390         "SystemApi PhotoOutputNapi::EnableRawDelivery is called!");
1391     napi_status status;
1392     napi_value result = nullptr;
1393     size_t argc = ARGS_ONE;
1394     napi_value argv[ARGS_ONE] = { 0 };
1395     napi_value thisVar = nullptr;
1396     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
1397     NAPI_ASSERT(env, argc == ARGS_ONE, "requires one parameter");
1398     napi_valuetype valueType = napi_undefined;
1399     napi_typeof(env, argv[0], &valueType);
1400     CHECK_RETURN_RET(valueType != napi_boolean && !CameraNapiUtils::CheckError(env, INVALID_ARGUMENT), result);
1401     napi_get_undefined(env, &result);
1402     PhotoOutputNapi* photoOutputNapi = nullptr;
1403     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
1404     bool rawDeliverySwitch;
1405     if (status == napi_ok && photoOutputNapi != nullptr) {
1406         napi_get_value_bool(env, argv[PARAM0], &rawDeliverySwitch);
1407         int32_t retCode = photoOutputNapi->photoOutput_->EnableRawDelivery(rawDeliverySwitch);
1408         CHECK_RETURN_RET(retCode != 0 && !CameraNapiUtils::CheckError(env, retCode), result);
1409     }
1410     return result;
1411 }
1412 
GetActiveProfile(napi_env env,napi_callback_info info)1413 napi_value PhotoOutputNapi::GetActiveProfile(napi_env env, napi_callback_info info)
1414 {
1415     MEDIA_DEBUG_LOG("PhotoOutputNapi::GetActiveProfile is called");
1416     PhotoOutputNapi* photoOutputNapi = nullptr;
1417     CameraNapiParamParser jsParamParser(env, info, photoOutputNapi);
1418     CHECK_RETURN_RET_ELOG(!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error"),
1419         nullptr, "PhotoOutputNapi::GetActiveProfile parse parameter occur error");
1420     auto profile = photoOutputNapi->photoOutput_->GetPhotoProfile();
1421     CHECK_RETURN_RET(profile == nullptr, CameraNapiUtils::GetUndefinedValue(env));
1422     return CameraNapiObjProfile(*profile).GenerateNapiValue(env);
1423 }
1424 
RegisterQuickThumbnailCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)1425 void PhotoOutputNapi::RegisterQuickThumbnailCallbackListener(
1426     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
1427 {
1428     CHECK_RETURN_ELOG(!CameraNapiSecurity::CheckSystemApp(env), "SystemApi!");
1429     MEDIA_INFO_LOG("PhotoOutputNapi RegisterQuickThumbnailCallbackListener!");
1430     if (!isQuickThumbnailEnabled_) {
1431         MEDIA_ERR_LOG("quickThumbnail is not enabled!");
1432         napi_throw_error(env, std::to_string(SESSION_NOT_RUNNING).c_str(), "");
1433         return;
1434     }
1435     CHECK_RETURN_ELOG(photoOutput_ == nullptr, "PhotoOutput is null!");
1436     if (photoOutputCallback_ == nullptr) {
1437         photoOutputCallback_ = std::make_shared<PhotoOutputCallback>(env);
1438         photoOutput_->SetCallback(photoOutputCallback_);
1439     }
1440     photoOutput_->SetThumbnailCallback(photoOutputCallback_);
1441     photoOutputCallback_->SaveCallbackReference(CONST_CAPTURE_QUICK_THUMBNAIL, callback, isOnce);
1442 }
1443 
UnregisterQuickThumbnailCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)1444 void PhotoOutputNapi::UnregisterQuickThumbnailCallbackListener(
1445     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
1446 {
1447     CHECK_RETURN_ELOG(!CameraNapiSecurity::CheckSystemApp(env), "SystemApi!");
1448     if (!isQuickThumbnailEnabled_) {
1449         MEDIA_ERR_LOG("quickThumbnail is not enabled!");
1450         napi_throw_error(env, std::to_string(SESSION_NOT_RUNNING).c_str(), "");
1451         return;
1452     }
1453 
1454     CHECK_RETURN_ELOG(photoOutput_ == nullptr, "PhotoOutput is null!");
1455     CHECK_RETURN_ELOG(photoOutputCallback_ == nullptr, "photoOutputCallback is null!");
1456     photoOutput_->UnSetThumbnailAvailableCallback();
1457     photoOutputCallback_->RemoveCallbackRef(CONST_CAPTURE_QUICK_THUMBNAIL, callback);
1458 }
1459 
RegisterPhotoAvailableCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)1460 void PhotoOutputNapi::RegisterPhotoAvailableCallbackListener(
1461     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
1462 {
1463     MEDIA_INFO_LOG("PhotoOutputNapi RegisterPhotoAvailableCallbackListener!");
1464     CHECK_RETURN_ELOG(photoOutput_ == nullptr, "PhotoOutput is null!");
1465     if (photoOutputCallback_ == nullptr) {
1466         photoOutputCallback_ = std::make_shared<PhotoOutputCallback>(env);
1467         photoOutput_->SetCallback(photoOutputCallback_);
1468     }
1469     photoOutput_->SetPhotoAvailableCallback(photoOutputCallback_);
1470     photoOutputCallback_->SaveCallbackReference(CONST_CAPTURE_PHOTO_AVAILABLE, callback, isOnce);
1471     callbackFlag_ |= CAPTURE_PHOTO;
1472     photoOutput_->SetCallbackFlag(callbackFlag_);
1473 }
1474 
UnregisterPhotoAvailableCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)1475 void PhotoOutputNapi::UnregisterPhotoAvailableCallbackListener(
1476     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
1477 {
1478     CHECK_RETURN_ELOG(photoOutput_ == nullptr, "PhotoOutput is null!");
1479     CHECK_RETURN_ELOG(photoOutputCallback_ == nullptr, "photoOutputCallback is null!");
1480     photoOutput_->UnSetPhotoAvailableCallback();
1481     callbackFlag_ &= ~CAPTURE_PHOTO;
1482     photoOutput_->SetCallbackFlag(callbackFlag_);
1483     photoOutputCallback_->RemoveCallbackRef(CONST_CAPTURE_PHOTO_AVAILABLE, callback);
1484 }
1485 
RegisterDeferredPhotoProxyAvailableCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)1486 void PhotoOutputNapi::RegisterDeferredPhotoProxyAvailableCallbackListener(
1487     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
1488 {
1489     MEDIA_INFO_LOG("PhotoOutputNapi RegisterDeferredPhotoProxyAvailableCallbackListener!");
1490     CHECK_RETURN_ELOG(photoOutput_ == nullptr, "PhotoOutput is null!");
1491 }
1492 
UnregisterDeferredPhotoProxyAvailableCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)1493 void PhotoOutputNapi::UnregisterDeferredPhotoProxyAvailableCallbackListener(
1494     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
1495 {
1496     MEDIA_INFO_LOG("PhotoOutputNapi UnregisterDeferredPhotoProxyAvailableCallbackListener!");
1497 }
1498 
RegisterPhotoAssetAvailableCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)1499 void PhotoOutputNapi::RegisterPhotoAssetAvailableCallbackListener(
1500     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
1501 {
1502     MEDIA_INFO_LOG("PhotoOutputNapi RegisterPhotoAssetAvailableCallbackListener!");
1503     CHECK_RETURN_ELOG(photoOutput_ == nullptr, "PhotoOutput is null!");
1504     if (photoOutputCallback_ == nullptr) {
1505         photoOutputCallback_ = std::make_shared<PhotoOutputCallback>(env);
1506         photoOutput_->SetCallback(photoOutputCallback_);
1507     }
1508     photoOutput_->SetPhotoAssetAvailableCallback(photoOutputCallback_);
1509     photoOutputCallback_->SaveCallbackReference(CONST_CAPTURE_PHOTO_ASSET_AVAILABLE, callback, isOnce);
1510     callbackFlag_ |= CAPTURE_PHOTO_ASSET;
1511     photoOutput_->SetCallbackFlag(callbackFlag_);
1512 }
1513 
UnregisterPhotoAssetAvailableCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)1514 void PhotoOutputNapi::UnregisterPhotoAssetAvailableCallbackListener(
1515     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
1516 {
1517     CHECK_RETURN_ELOG(photoOutput_ == nullptr, "PhotoOutput is null!");
1518     CHECK_RETURN_ELOG(photoOutputCallback_ == nullptr, "photoOutputCallback is null!");
1519     photoOutput_->UnSetPhotoAssetAvailableCallback();
1520     callbackFlag_ &= ~CAPTURE_PHOTO_ASSET;
1521     photoOutput_->SetCallbackFlag(callbackFlag_);
1522     photoOutput_->DeferImageDeliveryFor(DeferredDeliveryImageType::DELIVERY_NONE);
1523     photoOutputCallback_->RemoveCallbackRef(CONST_CAPTURE_PHOTO_ASSET_AVAILABLE, callback);
1524 }
1525 
RegisterCaptureStartCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)1526 void PhotoOutputNapi::RegisterCaptureStartCallbackListener(
1527     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
1528 {
1529     if (photoOutputCallback_ == nullptr) {
1530         photoOutputCallback_ = std::make_shared<PhotoOutputCallback>(env);
1531         photoOutput_->SetCallback(photoOutputCallback_);
1532     }
1533     photoOutputCallback_->SaveCallbackReference(CONST_CAPTURE_START, callback, isOnce);
1534 }
1535 
UnregisterCaptureStartCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)1536 void PhotoOutputNapi::UnregisterCaptureStartCallbackListener(
1537     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
1538 {
1539     CHECK_RETURN_ELOG(photoOutputCallback_ == nullptr, "photoOutputCallback is null");
1540     photoOutputCallback_->RemoveCallbackRef(CONST_CAPTURE_START, callback);
1541 }
1542 
RegisterCaptureStartWithInfoCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)1543 void PhotoOutputNapi::RegisterCaptureStartWithInfoCallbackListener(
1544     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
1545 {
1546     if (photoOutputCallback_ == nullptr) {
1547         photoOutputCallback_ = std::make_shared<PhotoOutputCallback>(env);
1548         photoOutput_->SetCallback(photoOutputCallback_);
1549     }
1550     photoOutputCallback_->SaveCallbackReference(CONST_CAPTURE_START_WITH_INFO, callback, isOnce);
1551 }
1552 
UnregisterCaptureStartWithInfoCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)1553 void PhotoOutputNapi::UnregisterCaptureStartWithInfoCallbackListener(
1554     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
1555 {
1556     CHECK_RETURN_ELOG(photoOutputCallback_ == nullptr, "photoOutputCallback is null");
1557     photoOutputCallback_->RemoveCallbackRef(CONST_CAPTURE_START_WITH_INFO, callback);
1558 }
1559 
RegisterCaptureEndCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)1560 void PhotoOutputNapi::RegisterCaptureEndCallbackListener(
1561     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
1562 {
1563     if (photoOutputCallback_ == nullptr) {
1564         photoOutputCallback_ = std::make_shared<PhotoOutputCallback>(env);
1565         photoOutput_->SetCallback(photoOutputCallback_);
1566     }
1567     photoOutputCallback_->SaveCallbackReference(CONST_CAPTURE_END, callback, isOnce);
1568 }
1569 
UnregisterCaptureEndCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)1570 void PhotoOutputNapi::UnregisterCaptureEndCallbackListener(
1571     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
1572 {
1573     CHECK_RETURN_ELOG(photoOutputCallback_ == nullptr, "photoOutputCallback is null");
1574     photoOutputCallback_->RemoveCallbackRef(CONST_CAPTURE_END, callback);
1575 }
1576 
RegisterFrameShutterCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)1577 void PhotoOutputNapi::RegisterFrameShutterCallbackListener(
1578     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
1579 {
1580     if (photoOutputCallback_ == nullptr) {
1581         photoOutputCallback_ = std::make_shared<PhotoOutputCallback>(env);
1582         photoOutput_->SetCallback(photoOutputCallback_);
1583     }
1584     photoOutputCallback_->SaveCallbackReference(CONST_CAPTURE_FRAME_SHUTTER, callback, isOnce);
1585 }
1586 
UnregisterFrameShutterCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)1587 void PhotoOutputNapi::UnregisterFrameShutterCallbackListener(
1588     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
1589 {
1590     CHECK_RETURN_ELOG(photoOutputCallback_ == nullptr, "photoOutputCallback is null");
1591     photoOutputCallback_->RemoveCallbackRef(CONST_CAPTURE_FRAME_SHUTTER, callback);
1592 }
1593 
RegisterErrorCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)1594 void PhotoOutputNapi::RegisterErrorCallbackListener(
1595     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
1596 {
1597     if (photoOutputCallback_ == nullptr) {
1598         photoOutputCallback_ = std::make_shared<PhotoOutputCallback>(env);
1599         photoOutput_->SetCallback(photoOutputCallback_);
1600     }
1601     photoOutputCallback_->SaveCallbackReference(CONST_CAPTURE_ERROR, callback, isOnce);
1602 }
1603 
UnregisterErrorCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)1604 void PhotoOutputNapi::UnregisterErrorCallbackListener(
1605     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
1606 {
1607     CHECK_RETURN_ELOG(photoOutputCallback_ == nullptr, "photoOutputCallback is null");
1608     photoOutputCallback_->RemoveCallbackRef(CONST_CAPTURE_ERROR, callback);
1609 }
1610 
RegisterFrameShutterEndCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)1611 void PhotoOutputNapi::RegisterFrameShutterEndCallbackListener(
1612     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
1613 {
1614     if (photoOutputCallback_ == nullptr) {
1615         photoOutputCallback_ = std::make_shared<PhotoOutputCallback>(env);
1616         photoOutput_->SetCallback(photoOutputCallback_);
1617     }
1618     photoOutputCallback_->SaveCallbackReference(CONST_CAPTURE_FRAME_SHUTTER_END, callback, isOnce);
1619 }
1620 
UnregisterFrameShutterEndCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)1621 void PhotoOutputNapi::UnregisterFrameShutterEndCallbackListener(
1622     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
1623 {
1624     CHECK_RETURN_ELOG(photoOutputCallback_ == nullptr, "photoOutputCallback is null");
1625     photoOutputCallback_->RemoveCallbackRef(CONST_CAPTURE_FRAME_SHUTTER_END, callback);
1626 }
1627 
RegisterReadyCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)1628 void PhotoOutputNapi::RegisterReadyCallbackListener(
1629     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
1630 {
1631     if (photoOutputCallback_ == nullptr) {
1632         photoOutputCallback_ = std::make_shared<PhotoOutputCallback>(env);
1633         photoOutput_->SetCallback(photoOutputCallback_);
1634     }
1635     photoOutputCallback_->SaveCallbackReference(CONST_CAPTURE_READY, callback, isOnce);
1636 }
1637 
UnregisterReadyCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)1638 void PhotoOutputNapi::UnregisterReadyCallbackListener(
1639     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
1640 {
1641     CHECK_RETURN_ELOG(photoOutputCallback_ == nullptr, "photoOutputCallback is null");
1642     photoOutputCallback_->RemoveCallbackRef(CONST_CAPTURE_READY, callback);
1643 }
1644 
RegisterEstimatedCaptureDurationCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)1645 void PhotoOutputNapi::RegisterEstimatedCaptureDurationCallbackListener(
1646     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
1647 {
1648     if (photoOutputCallback_ == nullptr) {
1649         photoOutputCallback_ = std::make_shared<PhotoOutputCallback>(env);
1650         photoOutput_->SetCallback(photoOutputCallback_);
1651     }
1652     photoOutputCallback_->SaveCallbackReference(CONST_CAPTURE_ESTIMATED_CAPTURE_DURATION, callback, isOnce);
1653 }
1654 
UnregisterEstimatedCaptureDurationCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)1655 void PhotoOutputNapi::UnregisterEstimatedCaptureDurationCallbackListener(
1656     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
1657 {
1658     CHECK_RETURN_ELOG(photoOutputCallback_ == nullptr, "photoOutputCallback is null");
1659     photoOutputCallback_->RemoveCallbackRef(CONST_CAPTURE_ESTIMATED_CAPTURE_DURATION, callback);
1660 }
1661 
GetEmitterFunctions()1662 const PhotoOutputNapi::EmitterFunctions& PhotoOutputNapi::GetEmitterFunctions()
1663 {
1664     static const EmitterFunctions funMap = {
1665         { CONST_CAPTURE_QUICK_THUMBNAIL, {
1666             &PhotoOutputNapi::RegisterQuickThumbnailCallbackListener,
1667             &PhotoOutputNapi::UnregisterQuickThumbnailCallbackListener } },
1668         { CONST_CAPTURE_PHOTO_AVAILABLE, {
1669             &PhotoOutputNapi::RegisterPhotoAvailableCallbackListener,
1670             &PhotoOutputNapi::UnregisterPhotoAvailableCallbackListener } },
1671         { CONST_CAPTURE_DEFERRED_PHOTO_AVAILABLE, {
1672             &PhotoOutputNapi::RegisterDeferredPhotoProxyAvailableCallbackListener,
1673             &PhotoOutputNapi::UnregisterDeferredPhotoProxyAvailableCallbackListener } },
1674         { CONST_CAPTURE_PHOTO_ASSET_AVAILABLE, {
1675             &PhotoOutputNapi::RegisterPhotoAssetAvailableCallbackListener,
1676             &PhotoOutputNapi::UnregisterPhotoAssetAvailableCallbackListener } },
1677         { CONST_CAPTURE_START, {
1678             &PhotoOutputNapi::RegisterCaptureStartCallbackListener,
1679             &PhotoOutputNapi::UnregisterCaptureStartCallbackListener } },
1680         { CONST_CAPTURE_END, {
1681             &PhotoOutputNapi::RegisterCaptureEndCallbackListener,
1682             &PhotoOutputNapi::UnregisterCaptureEndCallbackListener } },
1683         { CONST_CAPTURE_FRAME_SHUTTER, {
1684             &PhotoOutputNapi::RegisterFrameShutterCallbackListener,
1685             &PhotoOutputNapi::UnregisterFrameShutterCallbackListener } },
1686         { CONST_CAPTURE_ERROR, {
1687             &PhotoOutputNapi::RegisterErrorCallbackListener,
1688             &PhotoOutputNapi::UnregisterErrorCallbackListener } },
1689         { CONST_CAPTURE_FRAME_SHUTTER_END, {
1690             &PhotoOutputNapi::RegisterFrameShutterEndCallbackListener,
1691             &PhotoOutputNapi::UnregisterFrameShutterEndCallbackListener } },
1692         { CONST_CAPTURE_READY, {
1693             &PhotoOutputNapi::RegisterReadyCallbackListener,
1694             &PhotoOutputNapi::UnregisterReadyCallbackListener } },
1695         { CONST_CAPTURE_ESTIMATED_CAPTURE_DURATION, {
1696             &PhotoOutputNapi::RegisterEstimatedCaptureDurationCallbackListener,
1697             &PhotoOutputNapi::UnregisterEstimatedCaptureDurationCallbackListener } },
1698         { CONST_CAPTURE_START_WITH_INFO, {
1699             &PhotoOutputNapi::RegisterCaptureStartWithInfoCallbackListener,
1700             &PhotoOutputNapi::UnregisterCaptureStartWithInfoCallbackListener } },
1701         { CONST_CAPTURE_OFFLINE_DELIVERY_FINISHED, {
1702             &PhotoOutputNapi::RegisterOfflineDeliveryFinishedCallbackListener,
1703             &PhotoOutputNapi::UnregisterOfflineDeliveryFinishedCallbackListener } } };
1704     return funMap;
1705 }
1706 
On(napi_env env,napi_callback_info info)1707 napi_value PhotoOutputNapi::On(napi_env env, napi_callback_info info)
1708 {
1709     return ListenerTemplate<PhotoOutputNapi>::On(env, info);
1710 }
1711 
Once(napi_env env,napi_callback_info info)1712 napi_value PhotoOutputNapi::Once(napi_env env, napi_callback_info info)
1713 {
1714     return ListenerTemplate<PhotoOutputNapi>::Once(env, info);
1715 }
1716 
Off(napi_env env,napi_callback_info info)1717 napi_value PhotoOutputNapi::Off(napi_env env, napi_callback_info info)
1718 {
1719     return ListenerTemplate<PhotoOutputNapi>::Off(env, info);
1720 }
1721 
IsAutoHighQualityPhotoSupported(napi_env env,napi_callback_info info)1722 napi_value PhotoOutputNapi::IsAutoHighQualityPhotoSupported(napi_env env, napi_callback_info info)
1723 {
1724     auto result = CameraNapiUtils::GetUndefinedValue(env);
1725     CHECK_RETURN_RET_ELOG(!CameraNapiSecurity::CheckSystemApp(env), result,
1726         "SystemApi IsAutoHighQualityPhotoSupported is called!");
1727     MEDIA_DEBUG_LOG("PhotoOutputNapi::IsAutoHighQualityPhotoSupported is called");
1728     PhotoOutputNapi* photoOutputNapi = nullptr;
1729     CameraNapiParamParser jsParamParser(env, info, photoOutputNapi);
1730     CHECK_RETURN_RET_ELOG(!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error"),
1731         result, "PhotoOutputNapi::IsAutoHighQualityPhotoSupported parse parameter occur error");
1732     if (photoOutputNapi->photoOutput_ == nullptr) {
1733         MEDIA_ERR_LOG("PhotoOutputNapi::IsAutoHighQualityPhotoSupported get native object fail");
1734         CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "get native object fail");
1735         return result;
1736     }
1737 
1738     int32_t isAutoHighQualityPhotoSupported;
1739     int32_t retCode = photoOutputNapi->photoOutput_->IsAutoHighQualityPhotoSupported(isAutoHighQualityPhotoSupported);
1740     if (retCode == 0 && isAutoHighQualityPhotoSupported != -1) {
1741         napi_get_boolean(env, true, &result);
1742         return result;
1743     }
1744     MEDIA_ERR_LOG("PhotoOutputNapi::IsAutoHighQualityPhotoSupported is not supported");
1745     napi_get_boolean(env, false, &result);
1746     return result;
1747 }
1748 
EnableAutoHighQualityPhoto(napi_env env,napi_callback_info info)1749 napi_value PhotoOutputNapi::EnableAutoHighQualityPhoto(napi_env env, napi_callback_info info)
1750 {
1751     auto result = CameraNapiUtils::GetUndefinedValue(env);
1752     CHECK_RETURN_RET_ELOG(!CameraNapiSecurity::CheckSystemApp(env), result,
1753         "SystemApi EnableAutoHighQualityPhoto is called!");
1754     MEDIA_DEBUG_LOG("PhotoOutputNapi::EnableAutoHighQualityPhoto is called");
1755     PhotoOutputNapi* photoOutputNapi = nullptr;
1756     bool isEnable;
1757     CameraNapiParamParser jsParamParser(env, info, photoOutputNapi, isEnable);
1758     CHECK_RETURN_RET_ELOG(!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error"),
1759         result, "PhotoOutputNapi::EnableAutoHighQualityPhoto parse parameter occur error");
1760     if (photoOutputNapi->photoOutput_ == nullptr) {
1761         MEDIA_ERR_LOG("PhotoOutputNapi::EnableAutoHighQualityPhoto get native object fail");
1762         CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "get native object fail");
1763         return result;
1764     }
1765 
1766     int32_t retCode = photoOutputNapi->photoOutput_->EnableAutoHighQualityPhoto(isEnable);
1767     CHECK_PRINT_ELOG(!CameraNapiUtils::CheckError(env, retCode),
1768         "PhotoOutputNapi::EnableAutoHighQualityPhoto fail %{public}d", retCode);
1769     return result;
1770 }
1771 
IsAutoCloudImageEnhancementSupported(napi_env env,napi_callback_info info)1772 napi_value PhotoOutputNapi::IsAutoCloudImageEnhancementSupported(napi_env env, napi_callback_info info)
1773 {
1774     auto result = CameraNapiUtils::GetUndefinedValue(env);
1775     CHECK_RETURN_RET_ELOG(!CameraNapiSecurity::CheckSystemApp(env), result,
1776         "SystemApi IsAutoCloudImageEnhancementSupported is called!");
1777     MEDIA_DEBUG_LOG("PhotoOutputNapi::IsAutoCloudImageEnhancementSupported is called");
1778     PhotoOutputNapi* photoOutputNapi = nullptr;
1779     CameraNapiParamParser jsParamParser(env, info, photoOutputNapi);
1780     CHECK_RETURN_RET_ELOG(!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error"),
1781         result, "PhotoOutputNapi::IsAutoCloudImageEnhancementSupported parse parameter occur error");
1782     if (photoOutputNapi->photoOutput_ == nullptr) {
1783         MEDIA_ERR_LOG("PhotoOutputNapi::IsAutoCloudImageEnhancementSupported get native object fail");
1784         CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "get native object fail");
1785         return result;
1786     }
1787 
1788     bool isAutoCloudImageEnhancementSupported = false;
1789     int32_t retCode =
1790         photoOutputNapi->photoOutput_->IsAutoCloudImageEnhancementSupported(
1791             isAutoCloudImageEnhancementSupported);
1792     CHECK_RETURN_RET(!CameraNapiUtils::CheckError(env, retCode), nullptr);
1793     napi_get_boolean(env, isAutoCloudImageEnhancementSupported, &result);
1794     MEDIA_DEBUG_LOG("PhotoOutputNapi::IsAutoCloudImageEnhancementSupported is %{public}d",
1795         isAutoCloudImageEnhancementSupported);
1796     return result;
1797 }
1798 
EnableAutoCloudImageEnhancement(napi_env env,napi_callback_info info)1799 napi_value PhotoOutputNapi::EnableAutoCloudImageEnhancement(napi_env env, napi_callback_info info)
1800 {
1801     auto result = CameraNapiUtils::GetUndefinedValue(env);
1802     CHECK_RETURN_RET_ELOG(!CameraNapiSecurity::CheckSystemApp(env), result,
1803         "SystemApi EnableAutoCloudImageEnhancement is called!");
1804     MEDIA_DEBUG_LOG("PhotoOutputNapi::EnableAutoCloudImageEnhancement is called");
1805     PhotoOutputNapi* photoOutputNapi = nullptr;
1806     bool isEnable;
1807     CameraNapiParamParser jsParamParser(env, info, photoOutputNapi, isEnable);
1808     CHECK_RETURN_RET_ELOG(!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error"),
1809         result, "PhotoOutputNapi::EnableAutoCloudImageEnhancement parse parameter occur error");
1810     if (photoOutputNapi->photoOutput_ == nullptr) {
1811         MEDIA_ERR_LOG("PhotoOutputNapi::EnableAutoCloudImageEnhancement get native object fail");
1812         CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "get native object fail");
1813         return result;
1814     }
1815 
1816     int32_t retCode = photoOutputNapi->photoOutput_->EnableAutoCloudImageEnhancement(isEnable);
1817     CHECK_RETURN_RET_ELOG(!CameraNapiUtils::CheckError(env, retCode), result,
1818         "PhotoOutputNapi::EnableAutoCloudImageEnhancement fail %{public}d", retCode);
1819     MEDIA_DEBUG_LOG("PhotoOutputNapi::EnableAutoCloudImageEnhancement success");
1820     return result;
1821 }
1822 
IsDepthDataDeliverySupported(napi_env env,napi_callback_info info)1823 napi_value PhotoOutputNapi::IsDepthDataDeliverySupported(napi_env env, napi_callback_info info)
1824 {
1825     CHECK_RETURN_RET_ELOG(!CameraNapiSecurity::CheckSystemApp(env), nullptr,
1826         "SystemApi IsDepthDataDeliverySupported is called!");
1827     MEDIA_DEBUG_LOG("PhotoOutputNapi::IsDepthDataDeliverySupported is called");
1828     PhotoOutputNapi* photoOutputNapi = nullptr;
1829     CameraNapiParamParser jsParamParser(env, info, photoOutputNapi);
1830     CHECK_RETURN_RET_ELOG(!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error"),
1831         nullptr, "PhotoOutputNapi::IsDepthDataDeliverySupported parse parameter occur error");
1832     if (photoOutputNapi->photoOutput_ == nullptr) {
1833         MEDIA_ERR_LOG("PhotoOutputNapi::IsDepthDataDeliverySupported get native object fail");
1834         CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "get native object fail");
1835         return nullptr;
1836     }
1837     napi_value result = nullptr;
1838     int32_t retCode = photoOutputNapi->photoOutput_->IsDepthDataDeliverySupported();
1839     if (retCode == 0) {
1840         napi_get_boolean(env, true, &result);
1841         return result;
1842     }
1843     MEDIA_ERR_LOG("PhotoOutputNapi::IsDepthDataDeliverySupported is not supported");
1844     napi_get_boolean(env, false, &result);
1845     return result;
1846 }
1847 
EnableDepthDataDelivery(napi_env env,napi_callback_info info)1848 napi_value PhotoOutputNapi::EnableDepthDataDelivery(napi_env env, napi_callback_info info)
1849 {
1850     CHECK_RETURN_RET_ELOG(!CameraNapiSecurity::CheckSystemApp(env), nullptr,
1851         "SystemApi EnableDepthDataDelivery is called!");
1852     MEDIA_DEBUG_LOG("PhotoOutputNapi::EnableDepthDataDelivery is called");
1853     PhotoOutputNapi* photoOutputNapi = nullptr;
1854     bool isEnable;
1855     CameraNapiParamParser jsParamParser(env, info, photoOutputNapi, isEnable);
1856     CHECK_RETURN_RET_ELOG(!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error"), nullptr,
1857         "PhotoOutputNapi::EnableDepthDataDelivery parse parameter occur error");
1858     if (photoOutputNapi->photoOutput_ == nullptr) {
1859         MEDIA_ERR_LOG("PhotoOutputNapi::EnableDepthDataDelivery get native object fail");
1860         CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "get native object fail");
1861         return nullptr;
1862     }
1863 
1864     int32_t retCode = photoOutputNapi->photoOutput_->EnableDepthDataDelivery(isEnable);
1865     CHECK_PRINT_ELOG(!CameraNapiUtils::CheckError(env, retCode),
1866         "PhotoOutputNapi::EnableDepthDataDelivery fail %{public}d", retCode);
1867     return CameraNapiUtils::GetUndefinedValue(env);
1868 }
1869 
IsAutoAigcPhotoSupported(napi_env env,napi_callback_info info)1870 napi_value PhotoOutputNapi::IsAutoAigcPhotoSupported(napi_env env, napi_callback_info info)
1871 {
1872     auto result = CameraNapiUtils::GetUndefinedValue(env);
1873     if (!CameraNapiSecurity::CheckSystemApp(env)) {
1874         MEDIA_ERR_LOG("SystemApi IsAutoAigcPhotoSupported is called!");
1875         return result;
1876     }
1877     MEDIA_INFO_LOG("PhotoOutputNapi::IsAutoAigcPhotoSupported is called");
1878     PhotoOutputNapi* photoOutputNapi = nullptr;
1879     CameraNapiParamParser jsParamParser(env, info, photoOutputNapi);
1880     if (!jsParamParser.AssertStatus(PARAMETER_ERROR, "parse parameter occur error")) {
1881         MEDIA_ERR_LOG("PhotoOutputNapi::IsAutoAigcPhotoSupported parse parameter occur error");
1882         return result;
1883     }
1884     if (photoOutputNapi->photoOutput_ == nullptr) {
1885         MEDIA_ERR_LOG("PhotoOutputNapi::IsAutoAigcPhotoSupported get native object fail");
1886         CameraNapiUtils::ThrowError(env, PARAMETER_ERROR, "get native object fail");
1887         return result;
1888     }
1889     bool isAutoAigcPhotoSupported = false;
1890     int32_t retCode =
1891         photoOutputNapi->photoOutput_->IsAutoAigcPhotoSupported(
1892             isAutoAigcPhotoSupported);
1893     if (!CameraNapiUtils::CheckError(env, retCode)) {
1894         return nullptr;
1895     }
1896     napi_get_boolean(env, isAutoAigcPhotoSupported, &result);
1897     MEDIA_INFO_LOG("PhotoOutputNapi::IsAutoAigcPhotoSupported is %{public}d",
1898         isAutoAigcPhotoSupported);
1899     return result;
1900 }
1901 
EnableAutoAigcPhoto(napi_env env,napi_callback_info info)1902 napi_value PhotoOutputNapi::EnableAutoAigcPhoto(napi_env env, napi_callback_info info)
1903 {
1904     auto result = CameraNapiUtils::GetUndefinedValue(env);
1905     if (!CameraNapiSecurity::CheckSystemApp(env)) {
1906         MEDIA_ERR_LOG("SystemApi EnableAutoAigcPhoto is called!");
1907         return result;
1908     }
1909     MEDIA_DEBUG_LOG("PhotoOutputNapi::EnableAutoAigcPhoto is called");
1910     PhotoOutputNapi* photoOutputNapi = nullptr;
1911     bool isEnable;
1912     CameraNapiParamParser jsParamParser(env, info, photoOutputNapi, isEnable);
1913     if (!jsParamParser.AssertStatus(PARAMETER_ERROR, "parse parameter occur error")) {
1914         MEDIA_ERR_LOG("PhotoOutputNapi::EnableAutoAigcPhoto parse parameter occur error");
1915         return result;
1916     }
1917     if (photoOutputNapi->photoOutput_ == nullptr) {
1918         MEDIA_ERR_LOG("PhotoOutputNapi::EnableAutoAigcPhoto get native object fail");
1919         CameraNapiUtils::ThrowError(env, PARAMETER_ERROR, "get native object fail");
1920         return result;
1921     }
1922 
1923     int32_t retCode = photoOutputNapi->photoOutput_->EnableAutoAigcPhoto(isEnable);
1924     if (!CameraNapiUtils::CheckError(env, retCode)) {
1925         MEDIA_ERR_LOG("PhotoOutputNapi::EnableAutoAigcPhoto fail %{public}d", retCode);
1926         return result;
1927     }
1928     MEDIA_DEBUG_LOG("PhotoOutputNapi::EnableAutoAigcPhoto success");
1929     return result;
1930 }
1931 
RegisterOfflineDeliveryFinishedCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)1932 void PhotoOutputNapi::RegisterOfflineDeliveryFinishedCallbackListener(
1933     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
1934 {
1935     MEDIA_INFO_LOG("PhotoOutputNapi::RegisterOfflineDeliveryFinishedCallbackListener is called");
1936     CHECK_RETURN_ELOG(!CameraNapiSecurity::CheckSystemApp(env),
1937         "PhotoOutputNapi::RegisterOfflineDeliveryFinishedCallbackListener:SystemApi is called");
1938     if (photoOutputCallback_ == nullptr) {
1939         photoOutputCallback_ = std::make_shared<PhotoOutputCallback>(env);
1940         photoOutput_->SetCallback(photoOutputCallback_);
1941     }
1942     photoOutputCallback_->SaveCallbackReference(CONST_CAPTURE_OFFLINE_DELIVERY_FINISHED, callback, isOnce);
1943 }
1944 
UnregisterOfflineDeliveryFinishedCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)1945 void PhotoOutputNapi::UnregisterOfflineDeliveryFinishedCallbackListener(
1946     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
1947 {
1948     MEDIA_INFO_LOG("PhotoOutputNapi::UnregisterOfflineDeliveryFinishedCallbackListener is called");
1949     CHECK_RETURN_ELOG(!CameraNapiSecurity::CheckSystemApp(env),
1950         "PhotoOutputNapi::UnregisterOfflineDeliveryFinishedCallbackListener:SystemApi is called");
1951     if (photoOutputCallback_ == nullptr) {
1952         MEDIA_ERR_LOG("photoOutputCallback is null");
1953         return;
1954     }
1955     photoOutputCallback_->RemoveCallbackRef(CONST_CAPTURE_OFFLINE_DELIVERY_FINISHED, callback);
1956 }
1957 
IsOfflineSupported(napi_env env,napi_callback_info info)1958 napi_value PhotoOutputNapi::IsOfflineSupported(napi_env env, napi_callback_info info)
1959 {
1960     if (!CameraNapiSecurity::CheckSystemApp(env)) {
1961         MEDIA_ERR_LOG("SystemApi IsOfflineSupported is called!");
1962         return nullptr;
1963     }
1964     MEDIA_INFO_LOG("PhotoOutputNapi::IsOfflineSupported is called");
1965     PhotoOutputNapi* photoOutputNapi = nullptr;
1966     CameraNapiParamParser jsParamParser(env, info, photoOutputNapi);
1967     if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error")) {
1968         MEDIA_ERR_LOG("PhotoOutputNapi::IsOfflineSupported parse parameter occur error");
1969         return nullptr;
1970     }
1971     if (photoOutputNapi->photoOutput_ == nullptr) {
1972         MEDIA_ERR_LOG("PhotoOutputNapi::IsOfflineSupported get native object fail");
1973         CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "get native object fail");
1974         return nullptr;
1975     }
1976     napi_value result = nullptr;
1977     bool isSupported = photoOutputNapi->photoOutput_->IsOfflineSupported();
1978     napi_get_boolean(env, isSupported, &result);
1979     MEDIA_ERR_LOG("PhotoOutputNapi::IsOfflineSupported is support %{public}d", isSupported);
1980     return result;
1981 }
1982 
EnableOfflinePhoto(napi_env env,napi_callback_info info)1983 napi_value PhotoOutputNapi::EnableOfflinePhoto(napi_env env, napi_callback_info info)
1984 {
1985     if (!CameraNapiSecurity::CheckSystemApp(env)) {
1986         MEDIA_ERR_LOG("SystemApi IsOfflineSupported is called!");
1987         return nullptr;
1988     }
1989     MEDIA_INFO_LOG("EnableOfflinePhoto is called");
1990     napi_status status;
1991     napi_value result = nullptr;
1992     size_t argc = ARGS_ONE;
1993     napi_value argv[ARGS_ONE] = { 0 };
1994     napi_value thisVar = nullptr;
1995     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
1996     napi_get_undefined(env, &result);
1997     PhotoOutputNapi* photoOutputNapi = nullptr;
1998     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&photoOutputNapi));
1999     if (status != napi_ok || photoOutputNapi == nullptr) {
2000         MEDIA_ERR_LOG("EnableOfflinePhoto photoOutputNapi is null!");
2001         return result;
2002     }
2003     auto session = photoOutputNapi->GetPhotoOutput()->GetSession();
2004     if (session != nullptr && photoOutputNapi->GetPhotoOutput()) {
2005         photoOutputNapi->GetPhotoOutput()->EnableOfflinePhoto();
2006     }
2007     return result;
2008 }
2009 } // namespace CameraStandard
2010 } // namespace OHOS