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