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