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