• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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/preview_output_napi.h"
17 
18 #include <cstdint>
19 #include <memory>
20 #include <string>
21 #include <uv.h>
22 
23 #include "camera_error_code.h"
24 #include "camera_log.h"
25 #include "camera_napi_const.h"
26 #include "camera_napi_object_types.h"
27 #include "camera_napi_param_parser.h"
28 #include "camera_napi_security_utils.h"
29 #include "camera_napi_template_utils.h"
30 #include "camera_napi_utils.h"
31 #include "camera_napi_worker_queue_keeper.h"
32 #include "camera_output_capability.h"
33 #include "js_native_api.h"
34 #include "js_native_api_types.h"
35 #include "listener_base.h"
36 #include "napi/native_api.h"
37 #include "napi/native_common.h"
38 #include "napi/native_node_api.h"
39 #include "preview_output.h"
40 #include "refbase.h"
41 #include "surface_utils.h"
42 
43 namespace OHOS {
44 namespace CameraStandard {
45 using namespace std;
46 namespace {
GetSurfaceFromSurfaceId(napi_env env,std::string & surfaceId)47 sptr<Surface> GetSurfaceFromSurfaceId(napi_env env, std::string& surfaceId)
48 {
49     MEDIA_DEBUG_LOG("GetSurfaceFromSurfaceId enter");
50     char *ptr;
51     uint64_t iSurfaceId = std::strtoull(surfaceId.c_str(), &ptr, 10);
52     MEDIA_INFO_LOG("GetSurfaceFromSurfaceId surfaceId %{public}" PRIu64, iSurfaceId);
53 
54     return SurfaceUtils::GetInstance()->GetSurface(iSurfaceId);
55 }
56 
AsyncCompleteCallback(napi_env env,napi_status status,void * data)57 void AsyncCompleteCallback(napi_env env, napi_status status, void* data)
58 {
59     auto previewOutputAsyncContext = static_cast<PreviewOutputAsyncContext*>(data);
60     CHECK_RETURN_ELOG(previewOutputAsyncContext == nullptr,
61         "PreviewOutputNapi AsyncCompleteCallback context is null");
62     MEDIA_INFO_LOG("PreviewOutputNapi AsyncCompleteCallback %{public}s, status = %{public}d",
63         previewOutputAsyncContext->funcName.c_str(), previewOutputAsyncContext->status);
64     std::unique_ptr<JSAsyncContextOutput> jsContext = std::make_unique<JSAsyncContextOutput>();
65     jsContext->status = previewOutputAsyncContext->status;
66     if (!previewOutputAsyncContext->status) {
67         CameraNapiUtils::CreateNapiErrorObject(env, previewOutputAsyncContext->errorCode,
68             previewOutputAsyncContext->errorMsg.c_str(), jsContext);
69     } else {
70         napi_get_undefined(env, &jsContext->data);
71     }
72     if (!previewOutputAsyncContext->funcName.empty() && previewOutputAsyncContext->taskId > 0) {
73         // Finish async trace
74         CAMERA_FINISH_ASYNC_TRACE(previewOutputAsyncContext->funcName, previewOutputAsyncContext->taskId);
75         jsContext->funcName = previewOutputAsyncContext->funcName;
76     }
77     CHECK_EXECUTE(previewOutputAsyncContext->work != nullptr,
78         CameraNapiUtils::InvokeJSAsyncMethod(env, previewOutputAsyncContext->deferred,
79             previewOutputAsyncContext->callbackRef, previewOutputAsyncContext->work, *jsContext));
80     previewOutputAsyncContext->FreeHeldNapiValue(env);
81     delete previewOutputAsyncContext;
82 }
83 } // namespace
84 
85 thread_local napi_ref PreviewOutputNapi::sConstructor_ = nullptr;
86 thread_local sptr<PreviewOutput> PreviewOutputNapi::sPreviewOutput_ = nullptr;
87 thread_local uint32_t PreviewOutputNapi::previewOutputTaskId = CAMERA_PREVIEW_OUTPUT_TASKID;
88 
PreviewOutputCallback(napi_env env)89 PreviewOutputCallback::PreviewOutputCallback(napi_env env) : ListenerBase(env) {}
90 
UpdateJSCallbackAsync(PreviewOutputEventType eventType,const int32_t value) const91 void PreviewOutputCallback::UpdateJSCallbackAsync(PreviewOutputEventType eventType, const int32_t value) const
92 {
93     MEDIA_DEBUG_LOG("UpdateJSCallbackAsync is called");
94     std::unique_ptr<PreviewOutputCallbackInfo> callbackInfo =
95         std::make_unique<PreviewOutputCallbackInfo>(eventType, value, shared_from_this());
96     PreviewOutputCallbackInfo *event = callbackInfo.get();
97     auto task = [event]() {
98         PreviewOutputCallbackInfo* callbackInfo = reinterpret_cast<PreviewOutputCallbackInfo *>(event);
99         if (callbackInfo) {
100             auto listener = callbackInfo->listener_.lock();
101             CHECK_EXECUTE(listener, listener->UpdateJSCallback(callbackInfo->eventType_, callbackInfo->value_));
102             delete callbackInfo;
103         }
104     };
105     if (napi_ok != napi_send_event(env_, task, napi_eprio_immediate)) {
106         MEDIA_ERR_LOG("failed to execute work");
107     } else {
108         callbackInfo.release();
109     }
110 }
111 
OnFrameStarted() const112 void PreviewOutputCallback::OnFrameStarted() const
113 {
114     CAMERA_SYNC_TRACE;
115     MEDIA_INFO_LOG("OnFrameStarted is called");
116     UpdateJSCallbackAsync(PreviewOutputEventType::PREVIEW_FRAME_START, -1);
117 }
118 
OnFrameEnded(const int32_t frameCount) const119 void PreviewOutputCallback::OnFrameEnded(const int32_t frameCount) const
120 {
121     CAMERA_SYNC_TRACE;
122     MEDIA_DEBUG_LOG("OnFrameEnded is called, frameCount: %{public}d", frameCount);
123     UpdateJSCallbackAsync(PreviewOutputEventType::PREVIEW_FRAME_END, frameCount);
124 }
125 
OnError(const int32_t errorCode) const126 void PreviewOutputCallback::OnError(const int32_t errorCode) const
127 {
128     CAMERA_SYNC_TRACE;
129     MEDIA_DEBUG_LOG("OnError is called, errorCode: %{public}d", errorCode);
130     UpdateJSCallbackAsync(PreviewOutputEventType::PREVIEW_FRAME_ERROR, errorCode);
131 }
132 
OnSketchStatusDataChangedAsync(SketchStatusData statusData) const133 void PreviewOutputCallback::OnSketchStatusDataChangedAsync(SketchStatusData statusData) const
134 {
135     MEDIA_DEBUG_LOG("OnSketchStatusChangedAsync is called");
136     std::shared_ptr<SketchStatusCallbackInfo> callbackInfo =
137         std::make_shared<SketchStatusCallbackInfo>(statusData, shared_from_this(), env_);
138     auto task = [callbackInfo]() {
139         auto listener = callbackInfo->listener_.lock();
140         if (listener) {
141             listener->OnSketchStatusDataChangedCall(callbackInfo->sketchStatusData_);
142         }
143     };
144     if (napi_ok != napi_send_event(env_, task, napi_eprio_immediate)) {
145         MEDIA_ERR_LOG("PreviewOutputCallback::OnSketchStatusDataChangedAsync failed to execute work");
146     }
147 }
148 
OnSketchStatusDataChangedCall(SketchStatusData sketchStatusData) const149 void PreviewOutputCallback::OnSketchStatusDataChangedCall(SketchStatusData sketchStatusData) const
150 {
151     CAMERA_SYNC_TRACE;
152     MEDIA_DEBUG_LOG("OnSketchStatusChangedCall is called");
153     ExecuteCallbackScopeSafe(CONST_SKETCH_STATUS_CHANGED, [&]() {
154         napi_value errCode = CameraNapiUtils::GetUndefinedValue(env_);
155         napi_value callbackObj;
156 
157         CameraNapiObject sketchOffset {{
158             { "x", &sketchStatusData.offsetx },
159             { "y", &sketchStatusData.offsety },
160         }};
161 
162         CameraNapiObject sketchObj {{
163             { "status", reinterpret_cast<int32_t*>(&sketchStatusData.status) },
164             { "sketchRatio", &sketchStatusData.sketchRatio },
165             { "centerPointOffset", &sketchOffset }
166         }};
167         callbackObj = sketchObj.CreateNapiObjFromMap(env_);
168         return ExecuteCallbackData(env_, errCode, callbackObj);
169     });
170 }
171 
OnSketchStatusDataChanged(const SketchStatusData & statusData) const172 void PreviewOutputCallback::OnSketchStatusDataChanged(const SketchStatusData& statusData) const
173 {
174     CAMERA_SYNC_TRACE;
175     MEDIA_DEBUG_LOG("OnSketchStatusDataChanged is called");
176     OnSketchStatusDataChangedAsync(statusData);
177 }
178 
UpdateJSCallback(PreviewOutputEventType eventType,const int32_t value) const179 void PreviewOutputCallback::UpdateJSCallback(PreviewOutputEventType eventType, const int32_t value) const
180 {
181     MEDIA_DEBUG_LOG("UpdateJSCallback is called");
182     std::string eventName = PreviewOutputEventTypeHelper.GetKeyString(eventType);
183     if (eventName.empty()) {
184         MEDIA_WARNING_LOG(
185             "PreviewOutputCallback::UpdateJSCallback, event type is invalid %d", static_cast<int32_t>(eventType));
186         return;
187     }
188     int32_t nonConstValue = value;
189     ExecuteCallbackScopeSafe(eventName, [&]() {
190         napi_value errCode = CameraNapiUtils::GetUndefinedValue(env_);
191         napi_value callbackObj = CameraNapiUtils::GetUndefinedValue(env_);
192         if (eventType == PreviewOutputEventType::PREVIEW_FRAME_ERROR) {
193             CameraNapiObject errObj { { { "code", &nonConstValue } } };
194             errCode = errObj.CreateNapiObjFromMap(env_);
195         }
196         return ExecuteCallbackData(env_, errCode, callbackObj);
197     });
198 }
199 
PreviewOutputNapi()200 PreviewOutputNapi::PreviewOutputNapi() : env_(nullptr) {}
201 
~PreviewOutputNapi()202 PreviewOutputNapi::~PreviewOutputNapi()
203 {
204     MEDIA_DEBUG_LOG("~PreviewOutputNapi is called");
205 }
206 
PreviewOutputNapiDestructor(napi_env env,void * nativeObject,void * finalize_hint)207 void PreviewOutputNapi::PreviewOutputNapiDestructor(napi_env env, void* nativeObject, void* finalize_hint)
208 {
209     MEDIA_DEBUG_LOG("PreviewOutputNapiDestructor is called");
210     PreviewOutputNapi* cameraObj = reinterpret_cast<PreviewOutputNapi*>(nativeObject);
211     if (cameraObj != nullptr) {
212         delete cameraObj;
213     }
214 }
215 
Init(napi_env env,napi_value exports)216 napi_value PreviewOutputNapi::Init(napi_env env, napi_value exports)
217 {
218     MEDIA_DEBUG_LOG("Init is called");
219     napi_status status;
220     napi_value ctorObj;
221 
222     napi_property_descriptor preview_output_props[] = {
223         DECLARE_NAPI_FUNCTION("addDeferredSurface", AddDeferredSurface),
224         DECLARE_NAPI_FUNCTION("start", Start),
225         DECLARE_NAPI_FUNCTION("stop", Stop),
226         DECLARE_NAPI_FUNCTION("release", Release),
227         DECLARE_NAPI_FUNCTION("on", On),
228         DECLARE_NAPI_FUNCTION("once", Once),
229         DECLARE_NAPI_FUNCTION("off", Off),
230         DECLARE_NAPI_FUNCTION("isSketchSupported", IsSketchSupported),
231         DECLARE_NAPI_FUNCTION("getSketchRatio", GetSketchRatio),
232         DECLARE_NAPI_FUNCTION("enableSketch", EnableSketch),
233         DECLARE_NAPI_FUNCTION("attachSketchSurface", AttachSketchSurface),
234         DECLARE_NAPI_FUNCTION("setFrameRate", SetFrameRate),
235         DECLARE_NAPI_FUNCTION("getActiveFrameRate", GetActiveFrameRate),
236         DECLARE_NAPI_FUNCTION("getSupportedFrameRates", GetSupportedFrameRates),
237         DECLARE_NAPI_FUNCTION("getActiveProfile", GetActiveProfile),
238         DECLARE_NAPI_FUNCTION("getPreviewRotation", GetPreviewRotation),
239         DECLARE_NAPI_FUNCTION("setPreviewRotation", SetPreviewRotation)
240     };
241 
242     status = napi_define_class(env, CAMERA_PREVIEW_OUTPUT_NAPI_CLASS_NAME, NAPI_AUTO_LENGTH,
243                                PreviewOutputNapiConstructor, nullptr,
244                                sizeof(preview_output_props) / sizeof(preview_output_props[PARAM0]),
245                                preview_output_props, &ctorObj);
246     if (status == napi_ok) {
247         status = NapiRefManager::CreateMemSafetyRef(env, ctorObj, &sConstructor_);
248         if (status == napi_ok) {
249             status = napi_set_named_property(env, exports, CAMERA_PREVIEW_OUTPUT_NAPI_CLASS_NAME, ctorObj);
250             CHECK_RETURN_RET(status == napi_ok, exports);
251         }
252     }
253     MEDIA_ERR_LOG("Init call Failed!");
254     return nullptr;
255 }
256 
257 // Constructor callback
PreviewOutputNapiConstructor(napi_env env,napi_callback_info info)258 napi_value PreviewOutputNapi::PreviewOutputNapiConstructor(napi_env env, napi_callback_info info)
259 {
260     MEDIA_DEBUG_LOG("PreviewOutputNapiConstructor is called");
261     napi_status status;
262     napi_value result = nullptr;
263     napi_value thisVar = nullptr;
264 
265     napi_get_undefined(env, &result);
266     CAMERA_NAPI_GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
267 
268     if (status == napi_ok && thisVar != nullptr) {
269         std::unique_ptr<PreviewOutputNapi> obj = std::make_unique<PreviewOutputNapi>();
270         if (obj != nullptr) {
271             obj->env_ = env;
272             obj->previewOutput_ = sPreviewOutput_;
273 
274             status = napi_wrap(env, thisVar, reinterpret_cast<void*>(obj.get()),
275                 PreviewOutputNapi::PreviewOutputNapiDestructor, nullptr, nullptr);
276             if (status == napi_ok) {
277                 obj.release();
278                 return thisVar;
279             } else {
280                 MEDIA_ERR_LOG("Failure wrapping js to native napi");
281             }
282         }
283     }
284     MEDIA_ERR_LOG("PreviewOutputNapiConstructor call Failed!");
285     return result;
286 }
287 
CreateDeferredPreviewOutput(napi_env env,Profile & profile)288 napi_value PreviewOutputNapi::CreateDeferredPreviewOutput(napi_env env, Profile& profile)
289 {
290     CAMERA_SYNC_TRACE;
291     napi_status status;
292     napi_value result = nullptr;
293     napi_value constructor;
294 
295     status = napi_get_reference_value(env, sConstructor_, &constructor);
296     if (status == napi_ok) {
297         sPreviewOutput_ = CameraManager::GetInstance()->CreateDeferredPreviewOutput(profile);
298         CHECK_RETURN_RET_ELOG(sPreviewOutput_ == nullptr, result, "failed to create previewOutput");
299         status = napi_new_instance(env, constructor, 0, nullptr, &result);
300         sPreviewOutput_ = nullptr;
301 
302         if (status == napi_ok && result != nullptr) {
303             return result;
304         } else {
305             MEDIA_ERR_LOG("Failed to create preview output instance");
306         }
307     }
308 
309     napi_get_undefined(env, &result);
310     return result;
311 }
312 
CreatePreviewOutput(napi_env env,Profile & profile,std::string surfaceId)313 napi_value PreviewOutputNapi::CreatePreviewOutput(napi_env env, Profile& profile, std::string surfaceId)
314 {
315     MEDIA_INFO_LOG("PreviewOutputNapi::CreatePreviewOutput is called");
316     CAMERA_SYNC_TRACE;
317     napi_status status;
318     napi_value result = nullptr;
319     napi_value constructor;
320 
321     status = napi_get_reference_value(env, sConstructor_, &constructor);
322     if (status == napi_ok) {
323         uint64_t iSurfaceId;
324         std::istringstream iStringStream(surfaceId);
325         iStringStream >> iSurfaceId;
326         sptr<Surface> surface = SurfaceUtils::GetInstance()->GetSurface(iSurfaceId);
327         if (!surface) {
328             surface = Media::ImageReceiver::getSurfaceById(surfaceId);
329         }
330         CHECK_RETURN_RET_ELOG(surface == nullptr, result,
331             "PreviewOutputNapi::CreatePreviewOutput failed to get surface");
332 
333         surface->SetUserData(CameraManager::surfaceFormat, std::to_string(profile.GetCameraFormat()));
334         int retCode = CameraManager::GetInstance()->CreatePreviewOutput(profile, surface, &sPreviewOutput_);
335         CHECK_RETURN_RET(!CameraNapiUtils::CheckError(env, retCode), nullptr);
336         CHECK_RETURN_RET_ELOG(sPreviewOutput_ == nullptr, result,
337             "PreviewOutputNapi::CreatePreviewOutput failed to create previewOutput");
338         sPreviewOutput_->SetSurfaceId(surfaceId);
339         status = napi_new_instance(env, constructor, 0, nullptr, &result);
340         sPreviewOutput_ = nullptr;
341 
342         if (status == napi_ok && result != nullptr) {
343             return result;
344         } else {
345             MEDIA_ERR_LOG("PreviewOutputNapi::CreatePreviewOutput Failed to create preview output instance");
346         }
347     }
348     MEDIA_ERR_LOG("PreviewOutputNapi::CreatePreviewOutput call Failed!");
349     napi_get_undefined(env, &result);
350     return result;
351 }
352 
CreatePreviewOutput(napi_env env,std::string surfaceId)353 napi_value PreviewOutputNapi::CreatePreviewOutput(napi_env env, std::string surfaceId)
354 {
355     MEDIA_INFO_LOG("CreatePreviewOutput with only surfaceId is called");
356     CAMERA_SYNC_TRACE;
357     napi_status status;
358     napi_value result = nullptr;
359     napi_value constructor;
360 
361     status = napi_get_reference_value(env, sConstructor_, &constructor);
362     if (status == napi_ok) {
363         uint64_t iSurfaceId;
364         std::istringstream iss(surfaceId);
365         iss >> iSurfaceId;
366         sptr<Surface> surface = SurfaceUtils::GetInstance()->GetSurface(iSurfaceId);
367         if (!surface) {
368             surface = Media::ImageReceiver::getSurfaceById(surfaceId);
369         }
370         CHECK_RETURN_RET_ELOG(surface == nullptr, result, "failed to get surface");
371         int retCode = CameraManager::GetInstance()->CreatePreviewOutputWithoutProfile(surface, &sPreviewOutput_);
372         CHECK_RETURN_RET(!CameraNapiUtils::CheckError(env, retCode), nullptr);
373         CHECK_RETURN_RET_ELOG(sPreviewOutput_ == nullptr, result,
374             "failed to create previewOutput with only surfaceId");
375         sPreviewOutput_->SetSurfaceId(surfaceId);
376         status = napi_new_instance(env, constructor, 0, nullptr, &result);
377         sPreviewOutput_ = nullptr;
378 
379         if (status == napi_ok && result != nullptr) {
380             return result;
381         } else {
382             MEDIA_ERR_LOG("Failed to create preview output instance with only surfaceId");
383         }
384     }
385     MEDIA_ERR_LOG("CreatePreviewOutput with only surfaceId call Failed!");
386     napi_get_undefined(env, &result);
387     return result;
388 }
389 
GetPreviewOutput()390 sptr<PreviewOutput> PreviewOutputNapi::GetPreviewOutput()
391 {
392     return previewOutput_;
393 }
394 
IsPreviewOutput(napi_env env,napi_value obj)395 bool PreviewOutputNapi::IsPreviewOutput(napi_env env, napi_value obj)
396 {
397     MEDIA_DEBUG_LOG("IsPreviewOutput is called");
398     bool result = false;
399     napi_status status;
400     napi_value constructor = nullptr;
401 
402     status = napi_get_reference_value(env, sConstructor_, &constructor);
403     if (status == napi_ok) {
404         status = napi_instanceof(env, obj, constructor, &result);
405         if (status != napi_ok) {
406             MEDIA_DEBUG_LOG("PreviewOutputNapi::IsPreviewOutput is failed");
407             result = false;
408         }
409     }
410     return result;
411 }
412 
GetActiveProfile(napi_env env,napi_callback_info info)413 napi_value PreviewOutputNapi::GetActiveProfile(napi_env env, napi_callback_info info)
414 {
415     MEDIA_DEBUG_LOG("PreviewOutputNapi::GetActiveProfile is called");
416     PreviewOutputNapi* previewOutputNapi = nullptr;
417     CameraNapiParamParser jsParamParser(env, info, previewOutputNapi);
418     CHECK_RETURN_RET_ELOG(!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error"),
419         nullptr, "PreviewOutputNapi::GetActiveProfile parse parameter occur error");
420     auto profile = previewOutputNapi->previewOutput_->GetPreviewProfile();
421     CHECK_RETURN_RET(profile == nullptr, CameraNapiUtils::GetUndefinedValue(env));
422     return CameraNapiObjProfile(*profile).GenerateNapiValue(env);
423 }
424 
Release(napi_env env,napi_callback_info info)425 napi_value PreviewOutputNapi::Release(napi_env env, napi_callback_info info)
426 {
427     MEDIA_INFO_LOG("PreviewOutputNapi::Release is called");
428     std::unique_ptr<PreviewOutputAsyncContext> asyncContext = std::make_unique<PreviewOutputAsyncContext>(
429         "PreviewOutputNapi::Release", CameraNapiUtils::IncrementAndGet(previewOutputTaskId));
430     auto asyncFunction =
431         std::make_shared<CameraNapiAsyncFunction>(env, "Release", asyncContext->callbackRef, asyncContext->deferred);
432     CameraNapiParamParser jsParamParser(env, info, asyncContext->objectInfo, asyncFunction);
433     CHECK_RETURN_RET_ELOG(!jsParamParser.AssertStatus(INVALID_ARGUMENT, "invalid argument"),
434         nullptr, "PreviewOutputNapi::Release invalid argument");
435     asyncContext->HoldNapiValue(env, jsParamParser.GetThisVar());
436     napi_status status = napi_create_async_work(
437         env, nullptr, asyncFunction->GetResourceName(),
438         [](napi_env env, void* data) {
439             MEDIA_INFO_LOG("PreviewOutputNapi::Release running on worker");
440             auto context = static_cast<PreviewOutputAsyncContext*>(data);
441             CHECK_RETURN_ELOG(context->objectInfo == nullptr, "PreviewOutputNapi::Release async info is nullptr");
442             CAMERA_START_ASYNC_TRACE(context->funcName, context->taskId);
443             CameraNapiWorkerQueueKeeper::GetInstance()->ConsumeWorkerQueueTask(context->queueTask, [&context]() {
444                 context->errorCode = context->objectInfo->previewOutput_->Release();
445                 context->status = context->errorCode == CameraErrorCode::SUCCESS;
446             });
447         },
448         AsyncCompleteCallback, static_cast<void*>(asyncContext.get()), &asyncContext->work);
449     if (status != napi_ok) {
450         MEDIA_ERR_LOG("Failed to create napi_create_async_work for PreviewOutputNapi::Release");
451         asyncFunction->Reset();
452     } else {
453         asyncContext->queueTask =
454             CameraNapiWorkerQueueKeeper::GetInstance()->AcquireWorkerQueueTask("PreviewOutputNapi::Release");
455         napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
456         asyncContext.release();
457     }
458     CHECK_RETURN_RET(asyncFunction->GetAsyncFunctionType() == ASYNC_FUN_TYPE_PROMISE,
459         asyncFunction->GetPromise());
460     return CameraNapiUtils::GetUndefinedValue(env);
461 }
462 
AddDeferredSurface(napi_env env,napi_callback_info info)463 napi_value PreviewOutputNapi::AddDeferredSurface(napi_env env, napi_callback_info info)
464 {
465     MEDIA_DEBUG_LOG("AddDeferredSurface is called");
466     CHECK_RETURN_RET_ELOG(!CameraNapiSecurity::CheckSystemApp(env), nullptr,
467         "SystemApi AddDeferredSurface is called!");
468 
469     PreviewOutputNapi* previewOutputNapi;
470     std::string surfaceId;
471     CameraNapiParamParser jsParamParser(env, info, previewOutputNapi, surfaceId);
472     CHECK_RETURN_RET_ELOG(!jsParamParser.AssertStatus(INVALID_ARGUMENT, "invalid argument"), nullptr,
473         "CameraInputNapi::AddDeferredSurface invalid argument");
474 
475     uint64_t iSurfaceId;
476     std::istringstream iss(surfaceId);
477     iss >> iSurfaceId;
478     sptr<Surface> surface = SurfaceUtils::GetInstance()->GetSurface(iSurfaceId);
479     if (!surface) {
480         surface = Media::ImageReceiver::getSurfaceById(surfaceId);
481     }
482     if (surface == nullptr) {
483         MEDIA_ERR_LOG("CameraInputNapi::AddDeferredSurface failed to get surface");
484         CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "invalid argument surface get fail");
485         return nullptr;
486     }
487     auto previewProfile = previewOutputNapi->previewOutput_->GetPreviewProfile();
488     CHECK_EXECUTE(previewProfile != nullptr,
489         surface->SetUserData(CameraManager::surfaceFormat, std::to_string(previewProfile->GetCameraFormat())));
490     previewOutputNapi->previewOutput_->AddDeferredSurface(surface);
491     return CameraNapiUtils::GetUndefinedValue(env);
492 }
493 
Start(napi_env env,napi_callback_info info)494 napi_value PreviewOutputNapi::Start(napi_env env, napi_callback_info info)
495 {
496     MEDIA_INFO_LOG("Start is called");
497     std::unique_ptr<PreviewOutputAsyncContext> asyncContext = std::make_unique<PreviewOutputAsyncContext>(
498         "PreviewOutputNapi::Start", CameraNapiUtils::IncrementAndGet(previewOutputTaskId));
499     auto asyncFunction =
500         std::make_shared<CameraNapiAsyncFunction>(env, "Start", asyncContext->callbackRef, asyncContext->deferred);
501     CameraNapiParamParser jsParamParser(env, info, asyncContext->objectInfo, asyncFunction);
502     CHECK_RETURN_RET_ELOG(!jsParamParser.AssertStatus(INVALID_ARGUMENT, "invalid argument"),
503         nullptr, "PreviewOutputNapi::Start invalid argument");
504     asyncContext->HoldNapiValue(env, jsParamParser.GetThisVar());
505     napi_status status = napi_create_async_work(
506         env, nullptr, asyncFunction->GetResourceName(),
507         [](napi_env env, void* data) {
508             MEDIA_INFO_LOG("PreviewOutputNapi::Start running on worker");
509             auto context = static_cast<PreviewOutputAsyncContext*>(data);
510             CHECK_RETURN_ELOG(context->objectInfo == nullptr, "PreviewOutputNapi::Start async info is nullptr");
511             CAMERA_START_ASYNC_TRACE(context->funcName, context->taskId);
512             CameraNapiWorkerQueueKeeper::GetInstance()->ConsumeWorkerQueueTask(context->queueTask, [&context]() {
513                 context->errorCode = context->objectInfo->previewOutput_->Start();
514                 context->status = context->errorCode == CameraErrorCode::SUCCESS;
515                 MEDIA_INFO_LOG("PreviewOutputNapi::Start errorCode:%{public}d", context->errorCode);
516             });
517         },
518         AsyncCompleteCallback, static_cast<void*>(asyncContext.get()), &asyncContext->work);
519     if (status != napi_ok) {
520         MEDIA_ERR_LOG("Failed to create napi_create_async_work for PreviewOutputNapi::Start");
521         asyncFunction->Reset();
522     } else {
523         asyncContext->queueTask =
524             CameraNapiWorkerQueueKeeper::GetInstance()->AcquireWorkerQueueTask("PreviewOutputNapi::Start");
525         napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
526         asyncContext.release();
527     }
528     CHECK_RETURN_RET(asyncFunction->GetAsyncFunctionType() == ASYNC_FUN_TYPE_PROMISE,
529         asyncFunction->GetPromise());
530     return CameraNapiUtils::GetUndefinedValue(env);
531 }
532 
Stop(napi_env env,napi_callback_info info)533 napi_value PreviewOutputNapi::Stop(napi_env env, napi_callback_info info)
534 {
535     MEDIA_INFO_LOG("PreviewOutputNapi::Stop is called");
536     std::unique_ptr<PreviewOutputAsyncContext> asyncContext = std::make_unique<PreviewOutputAsyncContext>(
537         "PreviewOutputNapi::Stop", CameraNapiUtils::IncrementAndGet(previewOutputTaskId));
538     auto asyncFunction =
539         std::make_shared<CameraNapiAsyncFunction>(env, "Stop", asyncContext->callbackRef, asyncContext->deferred);
540     CameraNapiParamParser jsParamParser(env, info, asyncContext->objectInfo, asyncFunction);
541     CHECK_RETURN_RET_ELOG(!jsParamParser.AssertStatus(INVALID_ARGUMENT, "invalid argument"), nullptr,
542         "PreviewOutputNapi::Stop invalid argument");
543     asyncContext->HoldNapiValue(env, jsParamParser.GetThisVar());
544     napi_status status = napi_create_async_work(
545         env, nullptr, asyncFunction->GetResourceName(),
546         [](napi_env env, void* data) {
547             MEDIA_INFO_LOG("PreviewOutputNapi::Stop running on worker");
548             auto context = static_cast<PreviewOutputAsyncContext*>(data);
549             CHECK_RETURN_ELOG(context->objectInfo == nullptr, "PreviewOutputNapi::Stop async info is nullptr");
550             CAMERA_START_ASYNC_TRACE(context->funcName, context->taskId);
551             CameraNapiWorkerQueueKeeper::GetInstance()->ConsumeWorkerQueueTask(context->queueTask, [&context]() {
552                 context->errorCode = context->objectInfo->previewOutput_->Stop();
553                 context->status = context->errorCode == CameraErrorCode::SUCCESS;
554                 MEDIA_INFO_LOG("PreviewOutputNapi::Stop errorCode:%{public}d", context->errorCode);
555             });
556         },
557         AsyncCompleteCallback, static_cast<void*>(asyncContext.get()), &asyncContext->work);
558     if (status != napi_ok) {
559         MEDIA_ERR_LOG("Failed to create napi_create_async_work for PreviewOutputNapi::Stop");
560         asyncFunction->Reset();
561     } else {
562         asyncContext->queueTask =
563             CameraNapiWorkerQueueKeeper::GetInstance()->AcquireWorkerQueueTask("PreviewOutputNapi::Stop");
564         napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
565         asyncContext.release();
566     }
567     CHECK_RETURN_RET(asyncFunction->GetAsyncFunctionType() == ASYNC_FUN_TYPE_PROMISE,
568         asyncFunction->GetPromise());
569     return CameraNapiUtils::GetUndefinedValue(env);
570 }
571 
RegisterFrameStartCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)572 void PreviewOutputNapi::RegisterFrameStartCallbackListener(
573     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
574 {
575     auto listener = RegisterCallbackListener(eventName, env, callback, args, isOnce);
576     CHECK_RETURN_ELOG(
577         listener == nullptr, "PreviewOutputNapi::RegisterFrameStartCallbackListener listener is null");
578     previewOutput_->SetCallback(listener);
579 }
580 
RegisterFrameEndCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)581 void PreviewOutputNapi::RegisterFrameEndCallbackListener(
582     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
583 {
584     auto listener = RegisterCallbackListener(eventName, env, callback, args, isOnce);
585     CHECK_RETURN_ELOG(listener == nullptr, "PreviewOutputNapi::RegisterFrameEndCallbackListener listener is null");
586     previewOutput_->SetCallback(listener);
587 }
588 
RegisterErrorCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)589 void PreviewOutputNapi::RegisterErrorCallbackListener(
590     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
591 {
592     auto listener = RegisterCallbackListener(eventName, env, callback, args, isOnce);
593     CHECK_RETURN_ELOG(listener == nullptr, "PreviewOutputNapi::RegisterErrorCallbackListener listener is null");
594     previewOutput_->SetCallback(listener);
595 }
596 
UnregisterCommonCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)597 void PreviewOutputNapi::UnregisterCommonCallbackListener(
598     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
599 {
600     auto listener = UnregisterCallbackListener(eventName, env, callback, args);
601     CHECK_RETURN_ELOG(listener == nullptr,
602         "PreviewOutputNapi::UnregisterCommonCallbackListener %{public}s listener is null", eventName.c_str());
603     if (listener->IsEmpty(eventName)) {
604         previewOutput_->RemoveCallback(listener);
605     }
606 }
607 
RegisterSketchStatusChangedCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)608 void PreviewOutputNapi::RegisterSketchStatusChangedCallbackListener(
609     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
610 {
611     CHECK_RETURN_ELOG(!CameraNapiSecurity::CheckSystemApp(env), "SystemApi On sketchStatusChanged is called!");
612     auto listener = RegisterCallbackListener(eventName, env, callback, args, isOnce);
613     CHECK_RETURN_ELOG(
614         listener == nullptr, "PreviewOutputNapi::RegisterSketchStatusChangedCallbackListener listener is null");
615     previewOutput_->SetCallback(listener);
616     previewOutput_->OnNativeRegisterCallback(eventName);
617 }
618 
UnregisterSketchStatusChangedCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)619 void PreviewOutputNapi::UnregisterSketchStatusChangedCallbackListener(
620     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
621 {
622     if (!CameraNapiSecurity::CheckSystemApp(env)) {
623         MEDIA_ERR_LOG("SystemApi Off sketchStatusChanged is called!");
624         return;
625     }
626 
627     auto listener = UnregisterCallbackListener(eventName, env, callback, args);
628     CHECK_RETURN_ELOG(
629         listener == nullptr, "PreviewOutputNapi::UnregisterSketchStatusChangedCallbackListener listener is null");
630     previewOutput_->OnNativeUnregisterCallback(eventName);
631     if (listener->IsEmpty(eventName)) {
632         previewOutput_->RemoveCallback(listener);
633     }
634 }
635 
GetEmitterFunctions()636 const PreviewOutputNapi::EmitterFunctions& PreviewOutputNapi::GetEmitterFunctions()
637 {
638     static const EmitterFunctions funMap = {
639         { CONST_PREVIEW_FRAME_START, {
640             &PreviewOutputNapi::RegisterFrameStartCallbackListener,
641             &PreviewOutputNapi::UnregisterCommonCallbackListener } },
642         { CONST_PREVIEW_FRAME_END, {
643             &PreviewOutputNapi::RegisterFrameEndCallbackListener,
644             &PreviewOutputNapi::UnregisterCommonCallbackListener } },
645         { CONST_PREVIEW_FRAME_ERROR, {
646             &PreviewOutputNapi::RegisterErrorCallbackListener,
647             &PreviewOutputNapi::UnregisterCommonCallbackListener } },
648         { CONST_SKETCH_STATUS_CHANGED, {
649             &PreviewOutputNapi::RegisterSketchStatusChangedCallbackListener,
650             &PreviewOutputNapi::UnregisterSketchStatusChangedCallbackListener } } };
651     return funMap;
652 }
653 
IsSketchSupported(napi_env env,napi_callback_info info)654 napi_value PreviewOutputNapi::IsSketchSupported(napi_env env, napi_callback_info info)
655 {
656     CHECK_RETURN_RET_ELOG(!CameraNapiSecurity::CheckSystemApp(env), nullptr,
657         "SystemApi IsSketchSupported is called!");
658     MEDIA_INFO_LOG("PreviewOutputNapi::IsSketchSupported is called");
659     PreviewOutputNapi* previewOutputNapi = nullptr;
660     CameraNapiParamParser jsParamParser(env, info, previewOutputNapi);
661     CHECK_RETURN_RET_ELOG(!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error"),
662         nullptr, "PreviewOutputNapi::IsSketchSupported parse parameter occur error");
663 
664     bool isSupported = previewOutputNapi->previewOutput_->IsSketchSupported();
665     return CameraNapiUtils::GetBooleanValue(env, isSupported);
666 }
667 
GetSketchRatio(napi_env env,napi_callback_info info)668 napi_value PreviewOutputNapi::GetSketchRatio(napi_env env, napi_callback_info info)
669 {
670     CHECK_RETURN_RET_ELOG(!CameraNapiSecurity::CheckSystemApp(env),
671         nullptr, "SystemApi GetSketchRatio is called!");
672     MEDIA_INFO_LOG("PreviewOutputNapi::GetSketchRatio is called");
673     PreviewOutputNapi* previewOutputNapi = nullptr;
674     CameraNapiParamParser jsParamParser(env, info, previewOutputNapi);
675     CHECK_RETURN_RET_ELOG(!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error"),
676         nullptr, "PreviewOutputNapi::GetSketchRatio parse parameter occur error");
677     auto result = CameraNapiUtils::GetUndefinedValue(env);
678     float ratio = previewOutputNapi->previewOutput_->GetSketchRatio();
679     napi_create_double(env, ratio, &result);
680     return result;
681 }
682 
EnableSketch(napi_env env,napi_callback_info info)683 napi_value PreviewOutputNapi::EnableSketch(napi_env env, napi_callback_info info)
684 {
685     MEDIA_DEBUG_LOG("PreviewOutputNapi::EnableSketch enter");
686     CHECK_RETURN_RET_ELOG(!CameraNapiSecurity::CheckSystemApp(env), nullptr, "SystemApi EnableSketch is called!");
687 
688     bool isEnableSketch;
689     PreviewOutputNapi* previewOutputNapi = nullptr;
690     CameraNapiParamParser jsParamParser(env, info, previewOutputNapi, isEnableSketch);
691     CHECK_RETURN_RET_ELOG(!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error"), nullptr,
692         "PreviewOutputNapi::EnableSketch parse parameter occur error");
693 
694     int32_t retCode = previewOutputNapi->previewOutput_->EnableSketch(isEnableSketch);
695     CHECK_RETURN_RET_ELOG(!CameraNapiUtils::CheckError(env, retCode), nullptr,
696         "PreviewOutputNapi::EnableSketch fail! %{public}d", retCode);
697     MEDIA_DEBUG_LOG("PreviewOutputNapi::EnableSketch success");
698     return CameraNapiUtils::GetUndefinedValue(env);
699 }
700 
GetPreviewRotation(napi_env env,napi_callback_info info)701 napi_value PreviewOutputNapi::GetPreviewRotation(napi_env env, napi_callback_info info)
702 {
703     MEDIA_DEBUG_LOG("GetPreviewRotation is called!");
704     napi_status status;
705     napi_value result = nullptr;
706     size_t argc = ARGS_ONE;
707     napi_value argv[ARGS_ONE] = {0};
708     napi_value thisVar = nullptr;
709     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
710 
711     napi_get_undefined(env, &result);
712     PreviewOutputNapi* previewOutputNapi = nullptr;
713     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&previewOutputNapi));
714     if (status == napi_ok && previewOutputNapi != nullptr) {
715         int32_t value;
716         napi_status ret = napi_get_value_int32(env, argv[PARAM0], &value);
717         if (ret != napi_ok) {
718             CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT,
719                 "GetPreviewRotation parameter missing or parameter type incorrect.");
720             return result;
721         }
722         int32_t retCode = previewOutputNapi->previewOutput_->GetPreviewRotation(value);
723         if (retCode == SERVICE_FATL_ERROR) {
724             CameraNapiUtils::ThrowError(env, SERVICE_FATL_ERROR,
725                 "GetPreviewRotation Camera service fatal error.");
726             return result;
727         }
728         if (retCode == INVALID_ARGUMENT) {
729             CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT,
730                 "GetPreviewRotation Camera invalid argument.");
731             return result;
732         }
733         napi_create_int32(env, retCode, &result);
734         MEDIA_INFO_LOG("PreviewOutputNapi GetPreviewRotation! %{public}d", retCode);
735     } else {
736         MEDIA_ERR_LOG("PreviewOutputNapi GetPreviewRotation! called failed!");
737     }
738     return result;
739 }
740 
SetPreviewRotation(napi_env env,napi_callback_info info)741 napi_value PreviewOutputNapi::SetPreviewRotation(napi_env env, napi_callback_info info)
742 {
743     MEDIA_DEBUG_LOG("SetPreviewRotation is called!");
744     PreviewOutputNapi* previewOutputNapi = nullptr;
745     int32_t imageRotation = 0;
746     bool isDisplayLocked;
747     int32_t retCode = 0;
748     CameraNapiParamParser jsParamParser(env, info, previewOutputNapi, imageRotation, isDisplayLocked);
749     if (jsParamParser.IsStatusOk()) {
750         MEDIA_INFO_LOG("PreviewOutputNapi SetPreviewRotation! %{public}d", imageRotation);
751     } else {
752         MEDIA_WARNING_LOG("PreviewOutputNapi SetPreviewRotation without isDisplayLocked flag!");
753         jsParamParser = CameraNapiParamParser(env, info, previewOutputNapi, imageRotation);
754         isDisplayLocked = false;
755     }
756     CHECK_RETURN_RET_ELOG(!jsParamParser.AssertStatus(INVALID_ARGUMENT, "invalid argument"), nullptr,
757         "PreviewOutputNapi::SetPreviewRotation invalid argument");
758     if (previewOutputNapi->previewOutput_ == nullptr || imageRotation < 0 ||
759         imageRotation > ROTATION_270 || (imageRotation % ROTATION_90 != 0)) {
760         MEDIA_ERR_LOG("PreviewOutputNapi::SetPreviewRotation get native object fail");
761         CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "get native object fail");
762         return nullptr;
763     }
764     retCode = previewOutputNapi->previewOutput_->SetPreviewRotation(imageRotation, isDisplayLocked);
765     CHECK_RETURN_RET_ELOG(!CameraNapiUtils::CheckError(env, retCode), nullptr,
766         "PreviewOutputNapi::SetPreviewRotation! %{public}d", retCode);
767     MEDIA_DEBUG_LOG("PreviewOutputNapi::SetPreviewRotation success");
768     return CameraNapiUtils::GetUndefinedValue(env);
769 }
770 
AttachSketchSurface(napi_env env,napi_callback_info info)771 napi_value PreviewOutputNapi::AttachSketchSurface(napi_env env, napi_callback_info info)
772 {
773     MEDIA_DEBUG_LOG("PreviewOutputNapi::AttachSketchSurface enter");
774     CHECK_RETURN_RET_ELOG(!CameraNapiSecurity::CheckSystemApp(env), nullptr,
775         "SystemApi AttachSketchSurface is called!");
776 
777     std::string surfaceId;
778     PreviewOutputNapi* previewOutputNapi = nullptr;
779     CameraNapiParamParser jsParamParser(env, info, previewOutputNapi, surfaceId);
780     CHECK_RETURN_RET_ELOG(!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error"), nullptr,
781         "PreviewOutputNapi::AttachSketchSurface parse parameter occur error");
782 
783     sptr<Surface> surface = GetSurfaceFromSurfaceId(env, surfaceId);
784     if (surface == nullptr) {
785         MEDIA_ERR_LOG("PreviewOutputNapi::AttachSketchSurface get surface is null");
786         CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "input surface convert fail");
787         return nullptr;
788     }
789 
790     int32_t retCode = previewOutputNapi->previewOutput_->AttachSketchSurface(surface);
791     CHECK_RETURN_RET_ELOG(!CameraNapiUtils::CheckError(env, retCode), nullptr,
792         "PreviewOutputNapi::AttachSketchSurface! %{public}d", retCode);
793     MEDIA_DEBUG_LOG("PreviewOutputNapi::AttachSketchSurface success");
794     return CameraNapiUtils::GetUndefinedValue(env);
795 }
796 
SetFrameRate(napi_env env,napi_callback_info info)797 napi_value PreviewOutputNapi::SetFrameRate(napi_env env, napi_callback_info info)
798 {
799     MEDIA_DEBUG_LOG("SetFrameRate is called");
800     CAMERA_SYNC_TRACE;
801     napi_status status;
802     napi_value result;
803     size_t argc = ARGS_TWO;
804     napi_value argv[ARGS_TWO] = {0};
805     napi_value thisVar = nullptr;
806 
807     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
808 
809     napi_get_undefined(env, &result);
810     PreviewOutputNapi* previewOutputNapi = nullptr;
811     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&previewOutputNapi));
812     if (status == napi_ok && previewOutputNapi != nullptr) {
813         int32_t minFrameRate;
814         napi_get_value_int32(env, argv[PARAM0], &minFrameRate);
815         int32_t maxFrameRate;
816         napi_get_value_int32(env, argv[PARAM1], &maxFrameRate);
817         int32_t retCode = previewOutputNapi->previewOutput_->SetFrameRate(minFrameRate, maxFrameRate);
818         CHECK_RETURN_RET_ELOG(!CameraNapiUtils::CheckError(env, retCode), result,
819             "PreviewOutputNapi::SetFrameRate! %{public}d", retCode);
820     } else {
821         MEDIA_ERR_LOG("SetFrameRate call Failed!");
822     }
823     return result;
824 }
825 
GetActiveFrameRate(napi_env env,napi_callback_info info)826 napi_value PreviewOutputNapi::GetActiveFrameRate(napi_env env, napi_callback_info info)
827 {
828     MEDIA_DEBUG_LOG("GetActiveFrameRate is called");
829     CAMERA_SYNC_TRACE;
830     napi_status status;
831     napi_value result;
832     size_t argc = ARGS_ZERO;
833     napi_value argv[ARGS_ZERO];
834     napi_value thisVar = nullptr;
835 
836     MEDIA_DEBUG_LOG("PreviewOutputNapi::GetActiveFrameRate get js args");
837     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
838     NAPI_ASSERT(env, (argc == ARGS_ZERO), "requires no parameter.");
839 
840     napi_get_undefined(env, &result);
841     PreviewOutputNapi* previewOutputNapi = nullptr;
842     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&previewOutputNapi));
843     if (status == napi_ok && previewOutputNapi != nullptr) {
844         std::vector<int32_t> frameRateRange = previewOutputNapi->previewOutput_->GetFrameRateRange();
845         CameraNapiUtils::CreateFrameRateJSArray(env, frameRateRange, result);
846     } else {
847         MEDIA_ERR_LOG("GetActiveFrameRate call failed!");
848     }
849     return result;
850 }
851 
GetSupportedFrameRates(napi_env env,napi_callback_info info)852 napi_value PreviewOutputNapi::GetSupportedFrameRates(napi_env env, napi_callback_info info)
853 {
854     MEDIA_DEBUG_LOG("PreviewOutputNapi::GetSupportedFrameRates is called");
855 
856     CAMERA_SYNC_TRACE;
857     napi_status status;
858     napi_value result;
859     size_t argc = ARGS_ZERO;
860     napi_value argv[ARGS_ZERO];
861     napi_value thisVar = nullptr;
862 
863     MEDIA_DEBUG_LOG("PreviewOutputNapi::GetSupportedFrameRates get js args");
864     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
865     NAPI_ASSERT(env, (argc == ARGS_ZERO), "requires no parameter.");
866     napi_get_undefined(env, &result);
867     PreviewOutputNapi* previewOutputNapi = nullptr;
868     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&previewOutputNapi));
869     if (status == napi_ok && previewOutputNapi != nullptr) {
870         std::vector<std::vector<int32_t>> supportedFrameRatesRange =
871                                           previewOutputNapi->previewOutput_->GetSupportedFrameRates();
872         result = CameraNapiUtils::CreateSupportFrameRatesJSArray(env, supportedFrameRatesRange);
873     } else {
874         MEDIA_ERR_LOG("GetSupportedFrameRates call failed!");
875     }
876     return result;
877 }
878 
On(napi_env env,napi_callback_info info)879 napi_value PreviewOutputNapi::On(napi_env env, napi_callback_info info)
880 {
881     return ListenerTemplate<PreviewOutputNapi>::On(env, info);
882 }
883 
Once(napi_env env,napi_callback_info info)884 napi_value PreviewOutputNapi::Once(napi_env env, napi_callback_info info)
885 {
886     return ListenerTemplate<PreviewOutputNapi>::Once(env, info);
887 }
888 
Off(napi_env env,napi_callback_info info)889 napi_value PreviewOutputNapi::Off(napi_env env, napi_callback_info info)
890 {
891     return ListenerTemplate<PreviewOutputNapi>::Off(env, info);
892 }
893 } // namespace CameraStandard
894 } // namespace OHOS
895