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